[ovs-dev] [PATCH] datapath: Bug fix: kernel incorrectly rejects valid mega flow

Andy Zhou azhou at nicira.com
Wed Jun 26 15:38:37 UTC 2013


Fix a few bugs in kernel netlink validation code.

Bug #18233

Signed-off-by: Andy Zhou <azhou at nicira.com>
---
 datapath/flow.c |   23 ++++++++++++++++-------
 1 file changed, 16 insertions(+), 7 deletions(-)

diff --git a/datapath/flow.c b/datapath/flow.c
index fc6752e..2740898 100644
--- a/datapath/flow.c
+++ b/datapath/flow.c
@@ -1329,8 +1329,9 @@ 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 && (tci & htons(VLAN_TAG_PRESENT)))
-			return -EINVAL;
+		if (!is_mask)
+			if (!(tci & htons(VLAN_TAG_PRESENT)))
+				return -EINVAL;
 
 		SW_FLOW_KEY_PUT(match, eth.tci, tci, is_mask);
 		attrs &= ~(1ULL << OVS_KEY_ATTR_VLAN);
@@ -1528,13 +1529,15 @@ int ovs_match_from_nlattrs(struct sw_flow_match *match,
 	if (key_attrs & 1ULL << OVS_KEY_ATTR_ENCAP) {
 		encap = a[OVS_KEY_ATTR_ENCAP];
 		key_attrs &= ~(1ULL << OVS_KEY_ATTR_ENCAP);
-		if (nla_len(encap)) {
-			__be16 eth_type = 0; /* ETH_P_8021Q */
 
-			if (a[OVS_KEY_ATTR_ETHERTYPE])
-				eth_type = nla_get_be16(a[OVS_KEY_ATTR_ETHERTYPE]);
+		if ((!a[OVS_KEY_ATTR_VLAN]) || (!a[OVS_KEY_ATTR_ETHERTYPE]))
+			return -EINVAL;
+
+		if (nla_len(encap)) {
+			__be16 eth_type;
 
-			if  ((eth_type == htons(ETH_P_8021Q)) && (a[OVS_KEY_ATTR_VLAN])) {
+			eth_type = nla_get_be16(a[OVS_KEY_ATTR_ETHERTYPE]);
+			if (eth_type == htons(ETH_P_8021Q)) {
 				encap_valid = true;
 				key_attrs &= ~(1ULL << OVS_KEY_ATTR_ETHERTYPE);
 				err = parse_flow_nlattrs(encap, a, &key_attrs);
@@ -1543,6 +1546,11 @@ int ovs_match_from_nlattrs(struct sw_flow_match *match,
 
 			if (err)
 				return err;
+		} else {
+			__be16 tci;
+			tci = nla_get_be16(a[OVS_KEY_ATTR_VLAN]);
+			if (!tci)
+				return -EINVAL;
 		}
 	}
 
@@ -1558,6 +1566,7 @@ int ovs_match_from_nlattrs(struct sw_flow_match *match,
 		if ((mask_attrs & 1ULL << OVS_KEY_ATTR_ENCAP) && encap_valid) {
 			__be16 eth_type = 0;
 
+			mask_attrs &= ~(1ULL << OVS_KEY_ATTR_ENCAP);
 			if (a[OVS_KEY_ATTR_ETHERTYPE])
 				eth_type = nla_get_be16(a[OVS_KEY_ATTR_ETHERTYPE]);
 			if (eth_type == htons(0xffff)) {
-- 
1.7.9.5




More information about the dev mailing list