X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fdpif-netdev.c;h=14b919275d2f9d190175a5a39f533fec68b540aa;hb=264ecd63860eaf705669edac1bdc7292d8da0843;hp=cc898fb2fc77a38c35b6b537e8184a3e78c7c62c;hpb=d84d4b88d26e3f37ce24f1d3eebe0d70ef264f73;p=openvswitch diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index cc898fb2..14b91927 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -146,7 +146,7 @@ static int do_add_port(struct dp_netdev *, const char *devname, static int do_del_port(struct dp_netdev *, uint16_t port_no); static int dpif_netdev_open(const struct dpif_class *, const char *name, bool create, struct dpif **); -static int dp_netdev_output_control(struct dp_netdev *, const struct ofpbuf *, +static int dp_netdev_output_userspace(struct dp_netdev *, const struct ofpbuf *, int queue_no, const struct flow *, uint64_t arg); static int dp_netdev_execute_actions(struct dp_netdev *, @@ -302,6 +302,7 @@ dpif_netdev_get_stats(const struct dpif *dpif, struct odp_stats *stats) { struct dp_netdev *dp = get_dp_netdev(dpif); memset(stats, 0, sizeof *stats); + stats->n_flows = hmap_count(&dp->flow_table); stats->n_frags = dp->n_frags; stats->n_hit = dp->n_hit; stats->n_missed = dp->n_missed; @@ -707,8 +708,7 @@ dpif_netdev_validate_actions(const struct nlattr *actions, } break; - case ODP_ACTION_ATTR_CONTROLLER: - case ODP_ACTION_ATTR_DROP_SPOOFED_ARP: + case ODP_ACTION_ATTR_USERSPACE: break; case ODP_ACTION_ATTR_SET_DL_TCI: @@ -944,6 +944,7 @@ dpif_netdev_flow_dump_done(const struct dpif *dpif OVS_UNUSED, void *state_) static int dpif_netdev_execute(struct dpif *dpif, + const struct nlattr *key_attrs, size_t key_len, const struct nlattr *actions, size_t actions_len, const struct ofpbuf *packet) { @@ -975,7 +976,10 @@ dpif_netdev_execute(struct dpif *dpif, * if we don't. */ copy = *packet; } + flow_extract(©, 0, -1, &key); + dpif_netdev_flow_from_nlattrs(key_attrs, key_len, &key); + error = dp_netdev_execute_actions(dp, ©, &key, actions, actions_len); if (mutates) { ofpbuf_uninit(©); @@ -1085,57 +1089,49 @@ dp_netdev_port_input(struct dp_netdev *dp, struct dp_netdev_port *port, dp->n_hit++; } else { dp->n_missed++; - dp_netdev_output_control(dp, packet, DPIF_UC_MISS, &key, 0); + dp_netdev_output_userspace(dp, packet, DPIF_UC_MISS, &key, 0); } } static void -dp_netdev_run(void) +dpif_netdev_run(struct dpif *dpif) { - struct shash_node *node; + struct dp_netdev *dp = get_dp_netdev(dpif); + struct dp_netdev_port *port; struct ofpbuf packet; ofpbuf_init(&packet, DP_NETDEV_HEADROOM + VLAN_ETH_HEADER_LEN + max_mtu); - SHASH_FOR_EACH (node, &dp_netdevs) { - struct dp_netdev *dp = node->data; - struct dp_netdev_port *port; - LIST_FOR_EACH (port, node, &dp->port_list) { - int error; - - /* Reset packet contents. */ - ofpbuf_clear(&packet); - ofpbuf_reserve(&packet, DP_NETDEV_HEADROOM); - - error = netdev_recv(port->netdev, &packet); - if (!error) { - dp_netdev_port_input(dp, port, &packet); - } else if (error != EAGAIN && error != EOPNOTSUPP) { - static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); - VLOG_ERR_RL(&rl, "error receiving data from %s: %s", - netdev_get_name(port->netdev), strerror(error)); - } + LIST_FOR_EACH (port, node, &dp->port_list) { + int error; + + /* Reset packet contents. */ + ofpbuf_clear(&packet); + ofpbuf_reserve(&packet, DP_NETDEV_HEADROOM); + + error = netdev_recv(port->netdev, &packet); + if (!error) { + dp_netdev_port_input(dp, port, &packet); + } else if (error != EAGAIN && error != EOPNOTSUPP) { + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5); + VLOG_ERR_RL(&rl, "error receiving data from %s: %s", + netdev_get_name(port->netdev), strerror(error)); } } ofpbuf_uninit(&packet); } static void -dp_netdev_wait(void) +dpif_netdev_wait(struct dpif *dpif) { - struct shash_node *node; - - SHASH_FOR_EACH (node, &dp_netdevs) { - struct dp_netdev *dp = node->data; - struct dp_netdev_port *port; + struct dp_netdev *dp = get_dp_netdev(dpif); + struct dp_netdev_port *port; - LIST_FOR_EACH (port, node, &dp->port_list) { - netdev_recv_wait(port->netdev); - } + LIST_FOR_EACH (port, node, &dp->port_list) { + netdev_recv_wait(port->netdev); } } - static void dp_netdev_strip_vlan(struct ofpbuf *packet) { @@ -1257,7 +1253,7 @@ dp_netdev_output_port(struct dp_netdev *dp, struct ofpbuf *packet, } static int -dp_netdev_output_control(struct dp_netdev *dp, const struct ofpbuf *packet, +dp_netdev_output_userspace(struct dp_netdev *dp, const struct ofpbuf *packet, int queue_no, const struct flow *flow, uint64_t arg) { struct dp_netdev_queue *q = &dp->queues[queue_no]; @@ -1289,34 +1285,6 @@ dp_netdev_output_control(struct dp_netdev *dp, const struct ofpbuf *packet, return 0; } -/* Returns true if 'packet' is an invalid Ethernet+IPv4 ARP packet: one with - * screwy or truncated header fields or one whose inner and outer Ethernet - * address differ. */ -static bool -dp_netdev_is_spoofed_arp(struct ofpbuf *packet, const struct flow *key) -{ - struct arp_eth_header *arp; - struct eth_header *eth; - ptrdiff_t l3_size; - - if (key->dl_type != htons(ETH_TYPE_ARP)) { - return false; - } - - l3_size = (char *) ofpbuf_end(packet) - (char *) packet->l3; - if (l3_size < sizeof(struct arp_eth_header)) { - return true; - } - - eth = packet->l2; - arp = packet->l3; - return (arp->ar_hrd != htons(ARP_HRD_ETHERNET) - || arp->ar_pro != htons(ARP_PRO_IP) - || arp->ar_hln != ETH_HEADER_LEN - || arp->ar_pln != 4 - || !eth_addr_equals(arp->ar_sha, eth->eth_src)); -} - static int dp_netdev_execute_actions(struct dp_netdev *dp, struct ofpbuf *packet, struct flow *key, @@ -1332,8 +1300,8 @@ dp_netdev_execute_actions(struct dp_netdev *dp, dp_netdev_output_port(dp, packet, nl_attr_get_u32(a)); break; - case ODP_ACTION_ATTR_CONTROLLER: - dp_netdev_output_control(dp, packet, DPIF_UC_ACTION, + case ODP_ACTION_ATTR_USERSPACE: + dp_netdev_output_userspace(dp, packet, DPIF_UC_ACTION, key, nl_attr_get_u64(a)); break; @@ -1366,11 +1334,6 @@ dp_netdev_execute_actions(struct dp_netdev *dp, case ODP_ACTION_ATTR_SET_TP_DST: dp_netdev_set_tp_port(packet, key, a); break; - - case ODP_ACTION_ATTR_DROP_SPOOFED_ARP: - if (dp_netdev_is_spoofed_arp(packet, key)) { - return 0; - } } } return 0; @@ -1378,12 +1341,12 @@ dp_netdev_execute_actions(struct dp_netdev *dp, const struct dpif_class dpif_netdev_class = { "netdev", - dp_netdev_run, - dp_netdev_wait, NULL, /* enumerate */ dpif_netdev_open, dpif_netdev_close, dpif_netdev_destroy, + dpif_netdev_run, + dpif_netdev_wait, dpif_netdev_get_stats, dpif_netdev_get_drop_frags, dpif_netdev_set_drop_frags,