rcu_assign_pointer(dp->ports[parms->port_no], vport);
list_add_rcu(&vport->node, &dp->port_list);
- dp->n_ports++;
dp_ifinfo_notify(RTM_NEWLINK, vport);
}
dp_ifinfo_notify(RTM_DELLINK, p);
/* First drop references to device. */
- p->dp->n_ports--;
list_del_rcu(&p->node);
rcu_assign_pointer(p->dp->ports[p->port_no], NULL);
struct odp_stats stats;
int i;
- stats.n_ports = dp->n_ports;
- stats.max_ports = DP_MAX_PORTS;
stats.n_frags = stats.n_hit = stats.n_missed = stats.n_lost = 0;
for_each_possible_cpu(i) {
const struct dp_stats_percpu *percpu_stats;
* @waitqueue: Waitqueue, for waiting for new packets in @queues.
* @n_flows: Number of flows currently in flow table.
* @table: Current flow table.
- * @n_ports: Number of ports currently in @ports.
* @ports: Map from port number to &struct vport. %ODPP_LOCAL port
* always exists, other ports may be %NULL.
* @port_list: List of all ports in @ports in arbitrary order.
struct tbl __rcu *table;
/* Switch ports. */
- unsigned int n_ports;
struct vport __rcu *ports[DP_MAX_PORTS];
struct list_head port_list;
#define ODP_GET_SFLOW_PROBABILITY _IOW('O', 20, int)
struct odp_stats {
- /* Ports. */
- uint32_t n_ports; /* Current number of ports. */
- uint32_t max_ports; /* Maximum supported number of ports. */
-
- /* Lookups. */
uint64_t n_frags; /* Number of dropped IP fragments. */
uint64_t n_hit; /* Number of flow table matches. */
uint64_t n_missed; /* Number of flow table misses. */
return dpif_linux_port_query__(dpif, 0, devname, dpif_port);
}
+static int
+dpif_linux_get_max_ports(const struct dpif *dpif OVS_UNUSED)
+{
+ /* If the datapath increases its range of supported ports, then it should
+ * start reporting that. */
+ return 1024;
+}
+
static int
dpif_linux_flow_flush(struct dpif *dpif_)
{
dpif_linux_port_del,
dpif_linux_port_query_by_number,
dpif_linux_port_query_by_name,
+ dpif_linux_get_max_ports,
dpif_linux_port_dump_start,
dpif_linux_port_dump_next,
dpif_linux_port_dump_done,
{
struct dp_netdev *dp = get_dp_netdev(dpif);
memset(stats, 0, sizeof *stats);
- stats->n_ports = dp->n_ports;
- stats->max_ports = MAX_PORTS;
stats->n_frags = dp->n_frags;
stats->n_hit = dp->n_hit;
stats->n_missed = dp->n_missed;
return error;
}
+static int
+dpif_netdev_get_max_ports(const struct dpif *dpif OVS_UNUSED)
+{
+ return MAX_PORTS;
+}
+
static void
dp_netdev_free_flow(struct dp_netdev *dp, struct dp_netdev_flow *flow)
{
dpif_netdev_port_del,
dpif_netdev_port_query_by_number,
dpif_netdev_port_query_by_name,
+ dpif_netdev_get_max_ports,
dpif_netdev_port_dump_start,
dpif_netdev_port_dump_next,
dpif_netdev_port_dump_done,
int (*port_query_by_name)(const struct dpif *dpif, const char *devname,
struct dpif_port *port);
+ /* Returns one greater than the largest port number accepted in flow
+ * actions. */
+ int (*get_max_ports)(const struct dpif *dpif);
+
/* Attempts to begin dumping the ports in a dpif. On success, returns 0
* and initializes '*statep' with any data needed for iteration. On
* failure, returns a positive errno value. */
return error;
}
+/* Returns one greater than the maximum port number accepted in flow
+ * actions. */
+int
+dpif_get_max_ports(const struct dpif *dpif)
+{
+ return dpif->dpif_class->get_max_ports(dpif);
+}
+
/* Looks up port number 'port_no' in 'dpif'. On success, returns 0 and copies
* the port's name into the 'name_size' bytes in 'name', ensuring that the
* result is null-terminated. On failure, returns a positive errno value and
struct dpif_port *);
int dpif_port_get_name(struct dpif *, uint16_t port_no,
char *name, size_t name_size);
+int dpif_get_max_ports(const struct dpif *);
struct dpif_port_dump {
const struct dpif *dpif;
const struct ofhooks *ofhooks, void *aux,
struct ofproto **ofprotop)
{
- struct odp_stats stats;
struct ofproto *p;
struct dpif *dpif;
int error;
VLOG_ERR("failed to open datapath %s: %s", datapath, strerror(error));
return error;
}
- error = dpif_get_dp_stats(dpif, &stats);
- if (error) {
- VLOG_ERR("failed to obtain stats for datapath %s: %s",
- datapath, strerror(error));
- dpif_close(dpif);
- return error;
- }
error = dpif_recv_set_mask(dpif, ODPL_MISS | ODPL_ACTION | ODPL_SFLOW);
if (error) {
VLOG_ERR("failed to listen on datapath %s: %s",
p->netdev_monitor = netdev_monitor_create();
hmap_init(&p->ports);
shash_init(&p->port_by_name);
- p->max_ports = stats.max_ports;
+ p->max_ports = dpif_get_max_ports(dpif);
/* Initialize submodules. */
p->switch_status = switch_status_create(p);
printf("%s:\n", dpif_name(dpif));
if (!dpif_get_dp_stats(dpif, &stats)) {
- printf("\tports: cur:%"PRIu32", max:%"PRIu32"\n",
- stats.n_ports, stats.max_ports);
printf("\tlookups: frags:%llu, hit:%llu, missed:%llu, lost:%llu\n",
(unsigned long long int) stats.n_frags,
(unsigned long long int) stats.n_hit,