X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=datapath%2Fflow.c;h=29d306230c70584880531badeea763157e400491;hb=78f1e5c7d39a27d86677bb7c301824f8a8c3a5a8;hp=2c114083fe8fd8d5af367bbca26f85432f0dd90d;hpb=16c6b9216e8ccccb392b09d2f1bc9e1a0e1d935d;p=sliver-openvswitch.git diff --git a/datapath/flow.c b/datapath/flow.c index 2c114083f..29d306230 100644 --- a/datapath/flow.c +++ b/datapath/flow.c @@ -82,8 +82,9 @@ static void update_range__(struct sw_flow_match *match, do { \ update_range__(match, offsetof(struct sw_flow_key, field), \ sizeof((match)->key->field), is_mask); \ - if (is_mask && match->mask != NULL) { \ - (match)->mask->key.field = value; \ + if (is_mask) { \ + if ((match)->mask) \ + (match)->mask->key.field = value; \ } else { \ (match)->key->field = value; \ } \ @@ -93,8 +94,9 @@ static void update_range__(struct sw_flow_match *match, do { \ update_range__(match, offsetof(struct sw_flow_key, field), \ len, is_mask); \ - if (is_mask && match->mask != NULL) { \ - memcpy(&(match)->mask->key.field, value_p, len); \ + if (is_mask) { \ + if ((match)->mask) \ + memcpy(&(match)->mask->key.field, value_p, len);\ } else { \ memcpy(&(match)->key->field, value_p, len); \ } \ @@ -133,6 +135,9 @@ static bool ovs_match_validate(const struct sw_flow_match *match, | (1ULL << OVS_KEY_ATTR_ARP) | (1ULL << OVS_KEY_ATTR_ND)); + /* Tunnel mask is always allowed. */ + mask_allowed |= (1ULL << OVS_KEY_ATTR_TUNNEL); + if (match->key->phy.in_port == DP_MAX_PORTS && match->mask && (match->mask->key.phy.in_port == 0xffff)) mask_allowed |= (1ULL << OVS_KEY_ATTR_IN_PORT); @@ -1363,15 +1368,19 @@ static int ovs_key_from_nlattrs(struct sw_flow_match *match, u64 attrs, __be16 tci; tci = nla_get_be16(a[OVS_KEY_ATTR_VLAN]); - if (!is_mask) - if (!(tci & htons(VLAN_TAG_PRESENT))) { + if (!(tci & htons(VLAN_TAG_PRESENT))) { + if (is_mask) + OVS_NLERR("VLAN TCI mask does not have exact match for VLAN_TAG_PRESENT bit.\n"); + else OVS_NLERR("VLAN TCI does not have VLAN_TAG_PRESENT bit set.\n"); - return -EINVAL; - } + + return -EINVAL; + } SW_FLOW_KEY_PUT(match, eth.tci, tci, is_mask); attrs &= ~(1ULL << OVS_KEY_ATTR_VLAN); - } + } else if (!is_mask) + SW_FLOW_KEY_PUT(match, eth.tci, htons(0xffff), true); if (attrs & (1ULL << OVS_KEY_ATTR_ETHERTYPE)) { __be16 eth_type; @@ -1688,8 +1697,7 @@ int ovs_flow_to_nlattrs(const struct sw_flow_key *swkey, struct ovs_key_ethernet *eth_key; struct nlattr *nla, *encap; - if (output->phy.priority && - nla_put_u32(skb, OVS_KEY_ATTR_PRIORITY, output->phy.priority)) + if (nla_put_u32(skb, OVS_KEY_ATTR_PRIORITY, output->phy.priority)) goto nla_put_failure; if (swkey->tun_key.ipv4_dst && @@ -1709,8 +1717,7 @@ int ovs_flow_to_nlattrs(const struct sw_flow_key *swkey, goto nla_put_failure; } - if (output->phy.skb_mark && - nla_put_u32(skb, OVS_KEY_ATTR_SKB_MARK, output->phy.skb_mark)) + if (nla_put_u32(skb, OVS_KEY_ATTR_SKB_MARK, output->phy.skb_mark)) goto nla_put_failure; nla = nla_reserve(skb, OVS_KEY_ATTR_ETHERNET, sizeof(*eth_key));