long long int used; /* Last used time, in monotonic msecs. */
long long int packet_count; /* Number of packets matched. */
long long int byte_count; /* Number of bytes matched. */
- ovs_be16 tcp_ctl; /* Bitwise-OR of seen tcp_ctl values. */
+ uint8_t tcp_flags; /* Bitwise-OR of seen tcp_flags values. */
/* Actions. */
struct nlattr *actions;
return dpif_netdev_cast(dpif)->dp;
}
+static int
+dpif_netdev_enumerate(struct sset *all_dps)
+{
+ struct shash_node *node;
+
+ SHASH_FOR_EACH(node, &dp_netdevs) {
+ sset_add(all_dps, node->name);
+ }
+ return 0;
+}
+
static struct dpif *
create_dpif_netdev(struct dp_netdev *dp)
{
return 0;
}
+static const char* internal_port_type(const struct dp_netdev* dp)
+{
+ if (dp->class == &dpif_netdev_class)
+ return "tap";
+ if (dp->class == &dpif_planetlab_class)
+ return "tap_pl";
+ return "dummy";
+}
+
static int
do_add_port(struct dp_netdev *dp, const char *devname, const char *type,
uint16_t port_no)
/* XXX reject devices already in some dp_netdev. */
/* Open and validate network device. */
- open_type = (strcmp(type, "internal") ? type
- : dp->class != &dpif_netdev_class ? "dummy"
- : "tap");
+ open_type = (strcmp(type, "internal") ? type : internal_port_type(dp));
error = netdev_open(devname, open_type, &netdev);
if (error) {
return error;
struct dp_netdev *dp = get_dp_netdev(dpif);
int port_no;
- if (dpif->dpif_class != &dpif_netdev_class) {
+ if (dpif->dpif_class != &dpif_netdev_class &&
+ dpif->dpif_class != &dpif_planetlab_class)
+ {
/* If the port name contains a number, try to assign that port number.
* This can make writing unit tests easier because port numbers are
* predictable. */
stats->n_packets = flow->packet_count;
stats->n_bytes = flow->byte_count;
stats->used = flow->used;
- stats->tcp_flags = TCP_FLAGS(flow->tcp_ctl);
+ stats->tcp_flags = flow->tcp_flags;
}
static int
flow->used = 0;
flow->packet_count = 0;
flow->byte_count = 0;
- flow->tcp_ctl = 0;
+ flow->tcp_flags = 0;
}
static int
}
static int
-dpif_netdev_flow_del(struct dpif *dpif,
- const struct nlattr *nl_key, size_t nl_key_len,
- struct dpif_flow_stats *stats)
+dpif_netdev_flow_del(struct dpif *dpif, const struct dpif_flow_del *del)
{
struct dp_netdev *dp = get_dp_netdev(dpif);
struct dp_netdev_flow *flow;
struct flow key;
int error;
- error = dpif_netdev_flow_from_nlattrs(nl_key, nl_key_len, &key);
+ error = dpif_netdev_flow_from_nlattrs(del->key, del->key_len, &key);
if (error) {
return error;
}
flow = dp_netdev_lookup_flow(dp, &key);
if (flow) {
- if (stats) {
- get_dpif_flow_stats(flow, stats);
+ if (del->stats) {
+ get_dpif_flow_stats(flow, del->stats);
}
dp_netdev_free_flow(dp, flow);
return 0;
}
static int
-dpif_netdev_recv(struct dpif *dpif, struct dpif_upcall *upcall)
+dpif_netdev_recv(struct dpif *dpif, struct dpif_upcall *upcall,
+ struct ofpbuf *buf)
{
struct dp_netdev_queue *q = find_nonempty_queue(dpif);
if (q) {
*upcall = *u;
free(u);
+ ofpbuf_uninit(buf);
+ *buf = *u->packet;
+
return 0;
} else {
return EAGAIN;
flow->used = time_msec();
flow->packet_count++;
flow->byte_count += packet->size;
- if (key->dl_type == htons(ETH_TYPE_IP) &&
- key->nw_proto == IPPROTO_TCP && packet->l7) {
- struct tcp_header *th = packet->l4;
- flow->tcp_ctl |= th->tcp_ctl;
- }
+ flow->tcp_flags |= packet_get_tcp_flags(packet, key);
}
static void
}
}
+#define DPIF_NETDEV_CLASS_FUNCTIONS \
+ dpif_netdev_enumerate, \
+ dpif_netdev_open, \
+ dpif_netdev_close, \
+ dpif_netdev_destroy, \
+ dpif_netdev_run, \
+ dpif_netdev_wait, \
+ dpif_netdev_get_stats, \
+ dpif_netdev_port_add, \
+ dpif_netdev_port_del, \
+ dpif_netdev_port_query_by_number, \
+ dpif_netdev_port_query_by_name, \
+ dpif_netdev_get_max_ports, \
+ NULL, /* port_get_pid */ \
+ dpif_netdev_port_dump_start, \
+ dpif_netdev_port_dump_next, \
+ dpif_netdev_port_dump_done, \
+ dpif_netdev_port_poll, \
+ dpif_netdev_port_poll_wait, \
+ dpif_netdev_flow_get, \
+ dpif_netdev_flow_put, \
+ dpif_netdev_flow_del, \
+ dpif_netdev_flow_flush, \
+ dpif_netdev_flow_dump_start, \
+ dpif_netdev_flow_dump_next, \
+ dpif_netdev_flow_dump_done, \
+ dpif_netdev_execute, \
+ NULL, /* operate */ \
+ dpif_netdev_recv_set, \
+ dpif_netdev_queue_to_priority, \
+ dpif_netdev_recv, \
+ dpif_netdev_recv_wait, \
+ dpif_netdev_recv_purge, \
+
const struct dpif_class dpif_netdev_class = {
"netdev",
- NULL, /* enumerate */
- dpif_netdev_open,
- dpif_netdev_close,
- dpif_netdev_destroy,
- dpif_netdev_run,
- dpif_netdev_wait,
- dpif_netdev_get_stats,
- dpif_netdev_port_add,
- dpif_netdev_port_del,
- dpif_netdev_port_query_by_number,
- dpif_netdev_port_query_by_name,
- dpif_netdev_get_max_ports,
- NULL, /* port_get_pid */
- dpif_netdev_port_dump_start,
- dpif_netdev_port_dump_next,
- dpif_netdev_port_dump_done,
- dpif_netdev_port_poll,
- dpif_netdev_port_poll_wait,
- dpif_netdev_flow_get,
- dpif_netdev_flow_put,
- dpif_netdev_flow_del,
- dpif_netdev_flow_flush,
- dpif_netdev_flow_dump_start,
- dpif_netdev_flow_dump_next,
- dpif_netdev_flow_dump_done,
- dpif_netdev_execute,
- NULL, /* operate */
- dpif_netdev_recv_set,
- dpif_netdev_queue_to_priority,
- dpif_netdev_recv,
- dpif_netdev_recv_wait,
- dpif_netdev_recv_purge,
+ DPIF_NETDEV_CLASS_FUNCTIONS
+};
+
+const struct dpif_class dpif_planetlab_class = {
+ "planetlab",
+ DPIF_NETDEV_CLASS_FUNCTIONS
};
static void
dpif_dummy_register__("dummy");
}
+