From: Andy Zhou Date: Thu, 1 Aug 2013 17:49:45 +0000 (-0700) Subject: datapath: Accept any in_port mask but override to be exact match X-Git-Tag: sliver-openvswitch-2.0.90-1~33^2~53 X-Git-Url: http://git.onelab.eu/?p=sliver-openvswitch.git;a=commitdiff_plain;h=202c1051a9670595a87498d6f6dbf066e3d757b8 datapath: Accept any in_port mask but override to be exact match Pre mega flow, netlink allows the in_port key attribute to be missing. Missing in_port is interpreted as DP_MAX_PORTS. For backward compatibility, mega flow implementation will always allow the mask of in_port to be specified, as if the in_port key attribute is always specified. To prevent accidental match of the DP_MAX_PORTS, which value is opaque to the user space, we will always force the mask to be exact match, regardless of the value supplied by the netline message. Missing in_port mask continue to mean wildcarded match, same as other masks. Signed-off-by: Andy Zhou Signed-off-by: Jesse Gross --- diff --git a/datapath/flow.c b/datapath/flow.c index 29d306230..4d18aad3d 100644 --- a/datapath/flow.c +++ b/datapath/flow.c @@ -135,12 +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); + /* Always allowed mask fields. */ + mask_allowed |= ((1ULL << OVS_KEY_ATTR_TUNNEL) + | (1ULL << OVS_KEY_ATTR_IN_PORT)); if (match->key->eth.type == htons(ETH_P_802_2) && match->mask && (match->mask->key.eth.type == htons(0xffff))) @@ -1315,8 +1312,11 @@ static int metadata_from_nlattrs(struct sw_flow_match *match, u64 *attrs, if (*attrs & (1ULL << OVS_KEY_ATTR_IN_PORT)) { u32 in_port = nla_get_u32(a[OVS_KEY_ATTR_IN_PORT]); - if (!is_mask && in_port >= DP_MAX_PORTS) + if (is_mask) + in_port = 0xffffffff; /* Always exact match in_port. */ + else if (in_port >= DP_MAX_PORTS) return -EINVAL; + SW_FLOW_KEY_PUT(match, phy.in_port, in_port, is_mask); *attrs &= ~(1ULL << OVS_KEY_ATTR_IN_PORT); } else if (!is_mask) {