[ovs-dev] [PATCH v5 12/13] datapath: Relax flow set-up time validations.

Jarno Rajahalme jrajahalme at nicira.com
Fri Sep 5 23:05:19 UTC 2014


Allow setting of fields without matching on the same fields.  Field
existence check is done on set action execution time instead, using
the extracted flow key.

Signed-off-by: Jarno Rajahalme <jrajahalme at nicira.com>
---
 datapath/actions.c      |   21 ++++++++++++++++++++-
 datapath/flow_netlink.c |   46 +++++++++++++++-------------------------------
 2 files changed, 35 insertions(+), 32 deletions(-)

diff --git a/datapath/actions.c b/datapath/actions.c
index 243b672..3b2de3f 100644
--- a/datapath/actions.c
+++ b/datapath/actions.c
@@ -470,6 +470,10 @@ static int set_ipv4(struct sk_buff *skb, const struct ovs_key_ipv4 *key,
 	__be32 new_addr;
 	int err;
 
+	/* eth.type is checked at flow install time already. */
+	if (!OVS_CB(skb)->pkt_key->ip.proto)
+		return -EINVAL;
+
 	err = make_writable(skb, skb_network_offset(skb) +
 				 sizeof(struct iphdr));
 	if (unlikely(err))
@@ -519,6 +523,10 @@ static int set_ipv6(struct sk_buff *skb, const struct ovs_key_ipv6 *key,
 	struct ipv6hdr *nh;
 	int err;
 
+	/* eth.type is checked at flow install time already. */
+	if (!OVS_CB(skb)->pkt_key->ip.proto)
+		return -EINVAL;
+
 	err = make_writable(skb, skb_network_offset(skb) +
 			    sizeof(struct ipv6hdr));
 	if (unlikely(err))
@@ -593,6 +601,10 @@ static int set_udp(struct sk_buff *skb, const struct ovs_key_udp *key,
 	__be16 src, dst;
 	int err;
 
+	/* Must have extracted ports. */
+	if (!OVS_CB(skb)->pkt_key->tp.src && !OVS_CB(skb)->pkt_key->tp.dst)
+		return -EINVAL;
+
 	err = make_writable(skb, skb_transport_offset(skb) +
 				 sizeof(struct udphdr));
 	if (unlikely(err))
@@ -634,6 +646,10 @@ static int set_tcp(struct sk_buff *skb, const struct ovs_key_tcp *key,
 	__be16 src, dst;
 	int err;
 
+	/* Must have extracted ports. */
+	if (!OVS_CB(skb)->pkt_key->tp.src && !OVS_CB(skb)->pkt_key->tp.dst)
+		return -EINVAL;
+
 	err = make_writable(skb, skb_transport_offset(skb) +
 				 sizeof(struct tcphdr));
 	if (unlikely(err))
@@ -664,6 +680,10 @@ static int set_sctp(struct sk_buff *skb, const struct ovs_key_sctp *key,
 	__le32 old_correct_csum, new_csum, old_csum;
 	int err;
 
+	/* Must have extracted ports. */
+	if (!OVS_CB(skb)->pkt_key->tp.src && !OVS_CB(skb)->pkt_key->tp.dst)
+		return -EINVAL;
+
 	err = make_writable(skb, sctphoff + sizeof(struct sctphdr));
 	if (unlikely(err))
 		return err;
@@ -821,7 +841,6 @@ static int execute_set_action(struct sk_buff *skb, const struct nlattr *a)
 	}
 
 	return -EINVAL;
-
 }
 
 /* Mask is at the midpoint of the data. */
diff --git a/datapath/flow_netlink.c b/datapath/flow_netlink.c
index ec32a00..09aaf41 100644
--- a/datapath/flow_netlink.c
+++ b/datapath/flow_netlink.c
@@ -1511,16 +1511,6 @@ static int validate_and_copy_sample(const struct nlattr *attr,
 	return 0;
 }
 
-static int validate_tp_port(const struct sw_flow_key *flow_key,
-			    __be16 eth_type)
-{
-	if ((eth_type == htons(ETH_P_IP) || eth_type == htons(ETH_P_IPV6)) &&
-	    (flow_key->tp.src || flow_key->tp.dst))
-		return 0;
-
-	return -EINVAL;
-}
-
 void ovs_match_init(struct sw_flow_match *match,
 		    struct sw_flow_key *key,
 		    struct sw_flow_mask *mask)
@@ -1666,9 +1656,6 @@ static int validate_set(const struct nlattr *a,
 		if (eth_type != htons(ETH_P_IP))
 			return -EINVAL;
 
-		if (!flow_key->ip.proto)
-			return -EINVAL;
-
 		ipv4_key = nla_data(ovs_key);
 
 		if (masked) {
@@ -1690,9 +1677,6 @@ static int validate_set(const struct nlattr *a,
 		if (eth_type != htons(ETH_P_IPV6))
 			return -EINVAL;
 
-		if (!flow_key->ip.proto)
-			return -EINVAL;
-
 		ipv6_key = nla_data(ovs_key);
 		if (masked) {
 			const struct ovs_key_ipv6 *mask = ipv6_key + 1;
@@ -1717,35 +1701,35 @@ static int validate_set(const struct nlattr *a,
 		break;
 
 	case OVS_KEY_ATTR_TCP:
-		if (flow_key->ip.proto != IPPROTO_TCP)
+		if (eth_type != htons(ETH_P_IP) &&
+		    eth_type != htons(ETH_P_IPV6))
 			return -EINVAL;
 
-		err = validate_tp_port(flow_key, eth_type);
-		if (err)
-			return err;
+		if (flow_key->ip.proto != IPPROTO_TCP)
+			return -EINVAL;
 		break;
 
 	case OVS_KEY_ATTR_UDP:
-		if (flow_key->ip.proto != IPPROTO_UDP)
+		if (eth_type != htons(ETH_P_IP) &&
+		    eth_type != htons(ETH_P_IPV6))
 			return -EINVAL;
 
-		err = validate_tp_port(flow_key, eth_type);
-		if (err)
-			return err;
-		break;
-
-	case OVS_KEY_ATTR_MPLS:
-		if (!eth_p_mpls(eth_type))
+		if (flow_key->ip.proto != IPPROTO_UDP)
 			return -EINVAL;
 		break;
 
 	case OVS_KEY_ATTR_SCTP:
+		if (eth_type != htons(ETH_P_IP) &&
+		    eth_type != htons(ETH_P_IPV6))
+			return -EINVAL;
+
 		if (flow_key->ip.proto != IPPROTO_SCTP)
 			return -EINVAL;
+		break;
 
-		err = validate_tp_port(flow_key, eth_type);
-		if (err)
-			return err;
+	case OVS_KEY_ATTR_MPLS:
+		if (!eth_p_mpls(eth_type))
+			return -EINVAL;
 		break;
 
 	default:
-- 
1.7.10.4




More information about the dev mailing list