datapath: Convert IPv6 TCP and UDP port netlink attributes properly.
authorJustin Pettit <jpettit@nicira.com>
Thu, 27 Jun 2013 20:42:14 +0000 (13:42 -0700)
committerJustin Pettit <jpettit@nicira.com>
Thu, 27 Jun 2013 21:10:11 +0000 (14:10 -0700)
The code that converts netlink attributes to a flow match always
stored TCP and UDP ports in the IPv4 structure.  This commit
properly puts TCP and UDP traffic into appropriate IPv4 and IPv6
structures.

Signed-off-by: Justin Pettit <jpettit@nicira.com>
Acked-by: Jesse Gross <jesse@nicira.com>
datapath/flow.c

index 39de931..fc6752e 100644 (file)
@@ -1308,6 +1308,7 @@ static int ovs_key_from_nlattrs(struct sw_flow_match *match,  u64 attrs,
                const struct nlattr **a, bool is_mask)
 {
        int err;
+       u64 orig_attrs = attrs;
 
        err = metadata_from_nlattrs(match, &attrs, a, is_mask);
        if (err)
@@ -1422,10 +1423,17 @@ static int ovs_key_from_nlattrs(struct sw_flow_match *match,  u64 attrs,
                const struct ovs_key_tcp *tcp_key;
 
                tcp_key = nla_data(a[OVS_KEY_ATTR_TCP]);
-               SW_FLOW_KEY_PUT(match, ipv4.tp.src,
-                               tcp_key->tcp_src, is_mask);
-               SW_FLOW_KEY_PUT(match, ipv4.tp.dst,
-                               tcp_key->tcp_dst, is_mask);
+               if (orig_attrs & (1ULL << OVS_KEY_ATTR_IPV4)) {
+                       SW_FLOW_KEY_PUT(match, ipv4.tp.src,
+                                       tcp_key->tcp_src, is_mask);
+                       SW_FLOW_KEY_PUT(match, ipv4.tp.dst,
+                                       tcp_key->tcp_dst, is_mask);
+               } else {
+                       SW_FLOW_KEY_PUT(match, ipv6.tp.src,
+                                       tcp_key->tcp_src, is_mask);
+                       SW_FLOW_KEY_PUT(match, ipv6.tp.dst,
+                                       tcp_key->tcp_dst, is_mask);
+               }
                attrs &= ~(1ULL << OVS_KEY_ATTR_TCP);
        }
 
@@ -1433,10 +1441,17 @@ static int ovs_key_from_nlattrs(struct sw_flow_match *match,  u64 attrs,
                const struct ovs_key_udp *udp_key;
 
                udp_key = nla_data(a[OVS_KEY_ATTR_UDP]);
-               SW_FLOW_KEY_PUT(match, ipv4.tp.src,
-                               udp_key->udp_src, is_mask);
-               SW_FLOW_KEY_PUT(match, ipv4.tp.dst,
-                               udp_key->udp_dst, is_mask);
+               if (orig_attrs & (1ULL << OVS_KEY_ATTR_IPV4)) {
+                       SW_FLOW_KEY_PUT(match, ipv4.tp.src,
+                                       udp_key->udp_src, is_mask);
+                       SW_FLOW_KEY_PUT(match, ipv4.tp.dst,
+                                       udp_key->udp_dst, is_mask);
+               } else {
+                       SW_FLOW_KEY_PUT(match, ipv6.tp.src,
+                                       udp_key->udp_src, is_mask);
+                       SW_FLOW_KEY_PUT(match, ipv6.tp.dst,
+                                       udp_key->udp_dst, is_mask);
+               }
                attrs &= ~(1ULL << OVS_KEY_ATTR_UDP);
        }