From: Jesse Gross Date: Fri, 3 Aug 2012 01:22:38 +0000 (-0700) Subject: datapath: Relax set header validation. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6e9bea4da975729edf650c94430a02cc0518e383;p=openvswitch datapath: Relax set header validation. When installing a flow with an action to set a particular field we need to validate that the packets that are part of the flow actually contain that header. With IP we use zeroed addresses and with TCP/UDP the check is for zeroed ports. This check is overly broad and can catch packets like DHCP requests that have a zero source address in a legitimate header. This changes the check to look for a zeroed protocol number for IP or for both ports be zero for TCP/UDP before considering the header to not exist. Bug #12769 Reported-by: Ethan Jackson Signed-off-by: Jesse Gross Acked-by: Pravin B Shelar --- diff --git a/datapath/datapath.c b/datapath/datapath.c index dc2cfad5..7a7dc4c1 100644 --- a/datapath/datapath.c +++ b/datapath/datapath.c @@ -561,10 +561,10 @@ static int validate_sample(const struct nlattr *attr, static int validate_tp_port(const struct sw_flow_key *flow_key) { if (flow_key->eth.type == htons(ETH_P_IP)) { - if (flow_key->ipv4.tp.src && flow_key->ipv4.tp.dst) + if (flow_key->ipv4.tp.src || flow_key->ipv4.tp.dst) return 0; } else if (flow_key->eth.type == htons(ETH_P_IPV6)) { - if (flow_key->ipv6.tp.src && flow_key->ipv6.tp.dst) + if (flow_key->ipv6.tp.src || flow_key->ipv6.tp.dst) return 0; } @@ -597,7 +597,7 @@ static int validate_set(const struct nlattr *a, if (flow_key->eth.type != htons(ETH_P_IP)) return -EINVAL; - if (!flow_key->ipv4.addr.src || !flow_key->ipv4.addr.dst) + if (!flow_key->ip.proto) return -EINVAL; ipv4_key = nla_data(ovs_key); diff --git a/lib/odp-util.c b/lib/odp-util.c index 7caab09c..901dac3b 100644 --- a/lib/odp-util.c +++ b/lib/odp-util.c @@ -1976,7 +1976,7 @@ static void commit_set_port_action(const struct flow *flow, struct flow *base, struct ofpbuf *odp_actions) { - if (!base->tp_src || !base->tp_dst) { + if (!base->tp_src && !base->tp_dst) { return; }