X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fdpif-netdev.c;h=14b919275d2f9d190175a5a39f533fec68b540aa;hb=454ec971d79a921e2e97516ddb9c725d0cfa607d;hp=50052708afe8b982f93de910f79ab0b5ad7cefb1;hpb=007948177581f3b3dad188221593d0e4bdca6ba0;p=openvswitch diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c index 50052708..14b91927 100644 --- a/lib/dpif-netdev.c +++ b/lib/dpif-netdev.c @@ -114,7 +114,7 @@ struct dp_netdev_flow { 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. */ - uint16_t tcp_ctl; /* Bitwise-OR of seen tcp_ctl values. */ + ovs_be16 tcp_ctl; /* Bitwise-OR of seen tcp_ctl values. */ /* Actions. */ struct nlattr *actions; @@ -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,7 +1089,7 @@ 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); } } @@ -1174,7 +1178,7 @@ dp_netdev_set_nw_addr(struct ofpbuf *packet, const struct flow *key, struct ip_header *nh = packet->l3; ovs_be32 ip = nl_attr_get_be32(a); uint16_t type = nl_attr_type(a); - uint32_t *field; + ovs_be32 *field; field = type == ODP_ACTION_ATTR_SET_NW_SRC ? &nh->ip_src : &nh->ip_dst; if (key->nw_proto == IPPROTO_TCP && packet->l7) { @@ -1185,7 +1189,7 @@ dp_netdev_set_nw_addr(struct ofpbuf *packet, const struct flow *key, if (uh->udp_csum) { uh->udp_csum = recalc_csum32(uh->udp_csum, *field, ip); if (!uh->udp_csum) { - uh->udp_csum = 0xffff; + uh->udp_csum = htons(0xffff); } } } @@ -1218,7 +1222,7 @@ dp_netdev_set_tp_port(struct ofpbuf *packet, const struct flow *key, if (is_ip(packet, key)) { uint16_t type = nl_attr_type(a); ovs_be16 port = nl_attr_get_be16(a); - uint16_t *field; + ovs_be16 *field; if (key->nw_proto == IPPROTO_TCP && packet->l7) { struct tcp_header *th = packet->l4; @@ -1249,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]; @@ -1281,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, @@ -1324,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; @@ -1358,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;