summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniele Di Proietto <ddiproietto@vmware.com>2014-07-17 06:36:05 +0000
committerAndy Zhou <azhou@nicira.com>2014-07-23 13:26:01 -0700
commit0b496cdade43b028959f8e6bfdd56cfaf25f9abc (patch)
treea3a14996f3b44776432092aa44fca1f72ca09f4b
parent3854ab2153f943e2b2bb84520a0301424f01d4cb (diff)
downloadopenvswitch-0b496cdade43b028959f8e6bfdd56cfaf25f9abc.tar.gz
datapath/flow_netlink: Avoid wildcarding tunnel key with disabled megaflows
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>
-rw-r--r--datapath/flow_netlink.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/datapath/flow_netlink.c b/datapath/flow_netlink.c
index 445fa882a..e1eadbbb2 100644
--- a/datapath/flow_netlink.c
+++ b/datapath/flow_netlink.c
@@ -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;
}