<div dir="ltr"><div><div>As we have discussed offline, When ethertype attribute is not specified in the key filed but specified in the mask filed, we treat to mean a special ether type, namely the 802.2 ether type. <br><br>
</div>The incremental over V5 of the mega flow patch are attached. V6 will be sent shortly after all V5 feedback are received. <br><br></div><div>--andy<br></div><div><br><br>---<br> datapath/flow.c | 42 ++++++++++++++++++++++++++++--------------<br>
1 file changed, 28 insertions(+), 14 deletions(-)<br><br>diff --git a/datapath/flow.c b/datapath/flow.c<br>index f6674fd..2b7d9ed 100644<br>--- a/datapath/flow.c<br>+++ b/datapath/flow.c<br>@@ -135,6 +135,9 @@ static bool ovs_match_validate(const struct sw_flow_match *match,<br>
| (1ULL << OVS_KEY_ATTR_ARP)<br> | (1ULL << OVS_KEY_ATTR_ND));<br> <br>+ if (match->key->eth.type == htons(ETH_P_802_2))<br>+ mask_allowed |= (1ULL << OVS_KEY_ATTR_ETHERTYPE);<br>
+<br> /* Check key attributes. */<br> if (match->key->eth.type == htons(ETH_P_ARP)<br> || match->key->eth.type == htons(ETH_P_RARP)) {<br>@@ -1349,7 +1352,7 @@ static int ovs_key_from_nlattrs(struct sw_flow_match *match, u64 attrs,<br>
const struct ovs_key_ipv6 *ipv6_key;<br> <br> ipv6_key = nla_data(a[OVS_KEY_ATTR_IPV6]);<br>- if (ipv6_key->ipv6_frag > OVS_FRAG_TYPE_MAX)<br>+ if (!is_mask && ipv6_key->ipv6_frag > OVS_FRAG_TYPE_MAX)<br>
return -EINVAL;<br> SW_FLOW_KEY_PUT(match, ipv6.label,<br> ipv6_key->ipv6_label, is_mask);<br>@@ -1534,6 +1537,15 @@ int ovs_match_from_nlattrs(struct sw_flow_match *match,<br> ovs_sw_flow_mask_set(match->mask, &match->range, 0xff);<br>
}<br> <br>+ if (!(key_attrs & (1ULL << OVS_KEY_ATTR_ETHERTYPE))) {<br>+ if (match->mask)<br>+ if (match->mask->key.eth.type != htons(0xffff)<br>+ && (match->mask->key.eth.type != htons(0)))<br>
+ return -EINVAL;<br>+<br>+ match->key->eth.type = htons(ETH_P_802_2);<br>+ }<br>+<br> if (ovs_match_validate(match, key_attrs, mask_attrs) == false)<br> return -EINVAL;<br> <br>
@@ -1607,32 +1619,34 @@ int ovs_flow_to_nlattrs(const struct sw_flow_key *swkey,<br> nla_put_u32(skb, OVS_KEY_ATTR_SKB_MARK, output->phy.skb_mark))<br> goto nla_put_failure;<br> <br>- nla = nla_reserve(skb, OVS_KEY_ATTR_ETHERNET, sizeof(*eth_key));<br>
- if (!nla)<br>- goto nla_put_failure;<br>+ if (!is_all_zero((u8 *)&output->eth, 2 * ETH_ALEN)) {<br>+ nla = nla_reserve(skb, OVS_KEY_ATTR_ETHERNET, sizeof(*eth_key));<br>+ if (!nla)<br>
+ goto nla_put_failure;<br> <br>- eth_key = nla_data(nla);<br>- memcpy(eth_key->eth_src, output->eth.src, ETH_ALEN);<br>- memcpy(eth_key->eth_dst, output->eth.dst, ETH_ALEN);<br>+ eth_key = nla_data(nla);<br>
+ memcpy(eth_key->eth_src, output->eth.src, ETH_ALEN);<br>+ memcpy(eth_key->eth_dst, output->eth.dst, ETH_ALEN);<br>+ }<br> <br> if (swkey->eth.tci || swkey->eth.type == htons(ETH_P_8021Q)) {<br>
__be16 eth_type;<br>- eth_type = (swkey == output) ? htons(ETH_P_8021Q) : 0 ;<br>+ eth_type = (swkey == output) ? htons(ETH_P_8021Q) : htons(0xffff) ;<br> if (nla_put_be16(skb, OVS_KEY_ATTR_ETHERTYPE, eth_type) ||<br>
- nla_put_be16(skb, OVS_KEY_ATTR_VLAN, output->eth.tci))<br>+ nla_put_be16(skb, OVS_KEY_ATTR_VLAN, output->eth.tci))<br> goto nla_put_failure;<br> encap = nla_nest_start(skb, OVS_KEY_ATTR_ENCAP);<br>
if (!swkey->eth.tci)<br> goto unencap;<br>- } else {<br>+ } else<br> encap = NULL;<br>- }<br> <br>- if (swkey->eth.type == htons(ETH_P_802_2))<br>+ if ((swkey == output) && (swkey->eth.type == htons(ETH_P_802_2)))<br>
goto unencap;<br> <br>- if (nla_put_be16(skb, OVS_KEY_ATTR_ETHERTYPE, output->eth.type))<br>- goto nla_put_failure;<br>+ if (output->eth.type != 0)<br>+ if (nla_put_be16(skb, OVS_KEY_ATTR_ETHERTYPE, output->eth.type))<br>
+ goto nla_put_failure;<br> <br> if (swkey->eth.type == htons(ETH_P_IP)) {<br> struct ovs_key_ipv4 *ipv4_key;<br>-- <br>1.7.9.5<br><br><br>---<br> lib/odp-util.c | 20 +++++++++++++++-----<br> 1 file changed, 15 insertions(+), 5 deletions(-)<br>
<br>diff --git a/lib/odp-util.c b/lib/odp-util.c<br>index a126148..a243adc 100644<br>--- a/lib/odp-util.c<br>+++ b/lib/odp-util.c<br>@@ -1316,18 +1316,19 @@ odp_flow_format(const struct nlattr *key, size_t key_len,<br> if (key_len) {<br>
const struct nlattr *a;<br> unsigned int left;<br>+ bool has_ethtype_key = false;<br>+ const struct nlattr *ma = NULL;<br> <br> NL_ATTR_FOR_EACH (a, left, key, key_len) {<br>- const struct nlattr *ma = NULL;<br>
-<br> if (a != key) {<br> ds_put_char(ds, ',');<br> }<br>-<br>+ if (nl_attr_type(a) == OVS_KEY_ATTR_ETHERTYPE) {<br>+ has_ethtype_key = true;<br>+ }<br>
if (mask && mask_len) {<br> ma = nl_attr_find__(mask, mask_len, nl_attr_type(a));<br> }<br>-<br> format_odp_key_attr(a, ma, ds);<br> }<br> if (left) {<br>
@@ -1342,6 +1343,13 @@ odp_flow_format(const struct nlattr *key, size_t key_len,<br> }<br> ds_put_char(ds, ')');<br> }<br>+ if (!has_ethtype_key) {<br>+ ma = nl_attr_find__(mask, mask_len, OVS_KEY_ATTR_ETHERTYPE);<br>
+ if (ma) {<br>+ ds_put_format(ds, ",eth_type(0/0x%04"PRIx16")", <br>+ ntohs(nl_attr_get_be16(ma)));<br>+ }<br>+ }<br> } else {<br>
ds_put_cstr(ds, "<empty>");<br> }<br>@@ -1659,7 +1667,9 @@ parse_odp_key_mask_attr(const char *s, const struct simap *port_names,<br> <br> if (mask && sscanf(s, "eth_type(%i/%i)%n",<br>
&eth_type, &eth_type_mask, &n) > 0 && n > 0) {<br>- nl_msg_put_be16(key, OVS_KEY_ATTR_ETHERTYPE, htons(eth_type));<br>+ if (eth_type != 0) {<br>+ nl_msg_put_be16(key, OVS_KEY_ATTR_ETHERTYPE, htons(eth_type));<br>
+ }<br> nl_msg_put_be16(mask, OVS_KEY_ATTR_ETHERTYPE, htons(eth_type_mask));<br> return n;<br> } else if (sscanf(s, "eth_type(%i)%n", &eth_type, &n) > 0 && n > 0) {<br>
-- <br>1.7.9.5<br><br><br><br></div></div>