ofproto: Resubmit Statistics.
[openvswitch] / datapath / flow.c
index 9823b9feb31ef5fadc321d1e2e91d4b2d4a745ae..fe05df324c529af3b10f771631d074f93c09ff8f 100644 (file)
@@ -34,6 +34,8 @@
 #include <net/ipv6.h>
 #include <net/ndisc.h>
 
+#include "vlan.h"
+
 static struct kmem_cache *flow_cache;
 static unsigned int hash_seed __read_mostly;
 
@@ -449,8 +451,12 @@ int flow_extract(struct sk_buff *skb, u16 in_port, struct sw_flow_key *key,
 
        /* dl_type, dl_vlan, dl_vlan_pcp. */
        __skb_pull(skb, 2 * ETH_ALEN);
-       if (eth->h_proto == htons(ETH_P_8021Q))
+
+       if (vlan_tx_tag_present(skb))
+               key->dl_tci = htons(vlan_get_tci(skb));
+       else if (eth->h_proto == htons(ETH_P_8021Q))
                parse_vlan(skb, key);
+
        key->dl_type = parse_ethertype(skb);
        skb_reset_network_header(skb);
        __skb_push(skb, skb->data - (unsigned char *)eth);
@@ -813,6 +819,11 @@ int flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb)
        struct odp_key_ethernet *eth_key;
        struct nlattr *nla;
 
+       /* This is an imperfect sanity-check that FLOW_BUFSIZE doesn't need
+        * to be updated, but will at least raise awareness when new ODP key
+        * types are added. */
+       BUILD_BUG_ON(__ODP_KEY_ATTR_MAX != 14);
+
        if (swkey->tun_id != cpu_to_be64(0))
                NLA_PUT_BE64(skb, ODP_KEY_ATTR_TUN_ID, swkey->tun_id);
 
@@ -845,6 +856,7 @@ int flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb)
                if (!nla)
                        goto nla_put_failure;
                ipv4_key = nla_data(nla);
+               memset(ipv4_key, 0, sizeof(struct odp_key_ipv4));
                ipv4_key->ipv4_src = swkey->ipv4_src;
                ipv4_key->ipv4_dst = swkey->ipv4_dst;
                ipv4_key->ipv4_proto = swkey->nw_proto;
@@ -856,6 +868,7 @@ int flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb)
                if (!nla)
                        goto nla_put_failure;
                ipv6_key = nla_data(nla);
+               memset(ipv6_key, 0, sizeof(struct odp_key_ipv6));
                memcpy(ipv6_key->ipv6_src, swkey->ipv6_src,
                                sizeof(ipv6_key->ipv6_src));
                memcpy(ipv6_key->ipv6_dst, swkey->ipv6_dst,
@@ -869,6 +882,7 @@ int flow_to_nlattrs(const struct sw_flow_key *swkey, struct sk_buff *skb)
                if (!nla)
                        goto nla_put_failure;
                arp_key = nla_data(nla);
+               memset(arp_key, 0, sizeof(struct odp_key_arp));
                arp_key->arp_sip = swkey->ipv4_src;
                arp_key->arp_tip = swkey->ipv4_dst;
                arp_key->arp_op = htons(swkey->nw_proto);