datapath/flow_netlink: Avoid wildcarding tunnel key with disabled megaflows
authorDaniele Di Proietto <ddiproietto@vmware.com>
Thu, 17 Jul 2014 06:36:05 +0000 (06:36 +0000)
committerAndy Zhou <azhou@nicira.com>
Wed, 23 Jul 2014 20:26:01 +0000 (13:26 -0700)
If the userspace wants to match on a flow with some tunnel attributesset to 0,
it simply omits them in the netlink attributes stream.
Since our wildcarding logic (when megaflows are disabled) is based on the
attributes in the netlink stream, we set our mask incorrectly.

This commit adds a check to detect if the userspace wants to match on a tunnel,
in which case we simply unwildcard the whole tun_key

Reported-by: Andy Zhou <azhou@nicira.com>
Signed-off-by: Daniele Di Proietto <ddiproietto@vmware.com>
Signed-off-by: Andy Zhou <azhou@nicira.com>
datapath/flow_netlink.c

index 445fa88..e1eadbb 100644 (file)
@@ -106,6 +106,20 @@ static void update_range__(struct sw_flow_match *match,
        SW_FLOW_KEY_MEMCPY_OFFSET(match, offsetof(struct sw_flow_key, field), \
                                  value_p, len, is_mask)
 
+#define SW_FLOW_KEY_MEMSET_FIELD(match, field, value, is_mask) \
+       do { \
+               update_range__(match, offsetof(struct sw_flow_key, field),  \
+                                    sizeof((match)->key->field), is_mask); \
+               if (is_mask) {                                              \
+                       if ((match)->mask)                                  \
+                               memset((u8 *)&(match)->mask->key.field, value,\
+                                      sizeof((match)->mask->key.field));   \
+               } else {                                                    \
+                       memset((u8 *)&(match)->key->field, value,           \
+                              sizeof((match)->key->field));                \
+               }                                                           \
+       } while (0)
+
 static bool match_validate(const struct sw_flow_match *match,
                           u64 key_attrs, u64 mask_attrs)
 {
@@ -912,6 +926,11 @@ int ovs_nla_get_match(struct sw_flow_match *match,
 
                mask_set_nlattr(newmask, 0xff);
 
+               /* The userspace does not send tunnel attributes that are 0,
+                * but we should not wildcard them nonetheless. */
+               if (match->key->tun_key.ipv4_dst)
+                       SW_FLOW_KEY_MEMSET_FIELD(match, tun_key, 0xff, true);
+
                mask = newmask;
        }