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