diff options
author | Daniele Di Proietto <ddiproietto@vmware.com> | 2014-07-17 06:36:05 +0000 |
---|---|---|
committer | Andy Zhou <azhou@nicira.com> | 2014-07-23 13:26:01 -0700 |
commit | 0b496cdade43b028959f8e6bfdd56cfaf25f9abc (patch) | |
tree | a3a14996f3b44776432092aa44fca1f72ca09f4b | |
parent | 3854ab2153f943e2b2bb84520a0301424f01d4cb (diff) | |
download | openvswitch-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.c | 19 |
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; } |