[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