}
static void
-dp_netdev_free(struct dp_netdev *dp)
+dp_netdev_purge_queues(struct dp_netdev *dp)
{
int i;
- dp_netdev_flow_flush(dp);
- while (dp->n_ports > 0) {
- struct dp_netdev_port *port = CONTAINER_OF(
- dp->port_list.next, struct dp_netdev_port, node);
- do_del_port(dp, port->port_no);
- }
for (i = 0; i < N_QUEUES; i++) {
struct dp_netdev_queue *q = &dp->queues[i];
- unsigned int j;
- for (j = q->tail; j != q->head; j++) {
- struct dpif_upcall *upcall = q->upcalls[j & QUEUE_MASK];
+ while (q->tail != q->head) {
+ struct dpif_upcall *upcall = q->upcalls[q->tail++ & QUEUE_MASK];
ofpbuf_delete(upcall->packet);
free(upcall);
}
}
+}
+
+static void
+dp_netdev_free(struct dp_netdev *dp)
+{
+ dp_netdev_flow_flush(dp);
+ while (dp->n_ports > 0) {
+ struct dp_netdev_port *port = CONTAINER_OF(
+ dp->port_list.next, struct dp_netdev_port, node);
+ do_del_port(dp, port->port_no);
+ }
+ dp_netdev_purge_queues(dp);
hmap_destroy(&dp->flow_table);
free(dp->name);
free(dp);
{
struct dp_netdev *dp = get_dp_netdev(dpif);
memset(stats, 0, sizeof *stats);
- stats->n_flows = hmap_count(&dp->flow_table);
- stats->cur_capacity = hmap_capacity(&dp->flow_table);
- stats->max_capacity = MAX_FLOWS;
- 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;
stats->n_lost = dp->n_lost;
- stats->max_miss_queue = MAX_QUEUE_LEN;
- stats->max_action_queue = MAX_QUEUE_LEN;
return 0;
}
}
static void
-answer_port_query(const struct dp_netdev_port *port, struct odp_port *odp_port)
+answer_port_query(const struct dp_netdev_port *port,
+ struct dpif_port *dpif_port)
{
- memset(odp_port, 0, sizeof *odp_port);
- ovs_strlcpy(odp_port->devname, netdev_get_name(port->netdev),
- sizeof odp_port->devname);
- odp_port->port = port->port_no;
- strcpy(odp_port->type, port->internal ? "internal" : "system");
+ dpif_port->name = xstrdup(netdev_get_name(port->netdev));
+ dpif_port->type = xstrdup(port->internal ? "internal" : "system");
+ dpif_port->port_no = port->port_no;
}
static int
dpif_netdev_port_query_by_number(const struct dpif *dpif, uint16_t port_no,
- struct odp_port *odp_port)
+ struct dpif_port *dpif_port)
{
struct dp_netdev *dp = get_dp_netdev(dpif);
struct dp_netdev_port *port;
error = get_port_by_number(dp, port_no, &port);
if (!error) {
- answer_port_query(port, odp_port);
+ answer_port_query(port, dpif_port);
}
return error;
}
static int
dpif_netdev_port_query_by_name(const struct dpif *dpif, const char *devname,
- struct odp_port *odp_port)
+ struct dpif_port *dpif_port)
{
struct dp_netdev *dp = get_dp_netdev(dpif);
struct dp_netdev_port *port;
error = get_port_by_name(dp, devname, &port);
if (!error) {
- answer_port_query(port, odp_port);
+ answer_port_query(port, dpif_port);
}
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)
{
struct dp_netdev_port_state {
uint32_t port_no;
+ char *name;
};
static int
static int
dpif_netdev_port_dump_next(const struct dpif *dpif, void *state_,
- struct odp_port *odp_port)
+ struct dpif_port *dpif_port)
{
struct dp_netdev_port_state *state = state_;
struct dp_netdev *dp = get_dp_netdev(dpif);
for (port_no = state->port_no; port_no < MAX_PORTS; port_no++) {
struct dp_netdev_port *port = dp->ports[port_no];
if (port) {
- answer_port_query(port, odp_port);
+ free(state->name);
+ state->name = xstrdup(netdev_get_name(port->netdev));
+ dpif_port->name = state->name;
+ dpif_port->type = port->internal ? "internal" : "system";
+ dpif_port->port_no = port->port_no;
state->port_no = port_no + 1;
return 0;
}
}
static int
-dpif_netdev_port_dump_done(const struct dpif *dpif OVS_UNUSED, void *state)
+dpif_netdev_port_dump_done(const struct dpif *dpif OVS_UNUSED, void *state_)
{
+ struct dp_netdev_port_state *state = state_;
+ free(state->name);
free(state);
return 0;
}
* wake up to queue new messages, so there is nothing to do. */
}
}
+
+static void
+dpif_netdev_recv_purge(struct dpif *dpif)
+{
+ struct dpif_netdev *dpif_netdev = dpif_netdev_cast(dpif);
+ dp_netdev_purge_queues(dpif_netdev->dp);
+}
\f
static void
dp_netdev_flow_used(struct dp_netdev_flow *flow, struct flow *key,
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,
NULL, /* queue_to_priority */
dpif_netdev_recv,
dpif_netdev_recv_wait,
+ dpif_netdev_recv_purge,
};
void