X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=ofproto%2Ftunnel.c;h=d2e9584f1d646d55a547014e3232c02f152417c4;hb=HEAD;hp=001045a53a83d9eef0a32e679bcb9ae1bdee2302;hpb=87972a8fcd0f339c7229a014edd4c75fd9c1356c;p=sliver-openvswitch.git diff --git a/ofproto/tunnel.c b/ofproto/tunnel.c index 001045a53..d2e9584f1 100644 --- a/ofproto/tunnel.c +++ b/ofproto/tunnel.c @@ -298,17 +298,20 @@ out: } static bool -tnl_ecn_ok(const struct flow *base_flow, struct flow *flow) +tnl_ecn_ok(const struct flow *base_flow, struct flow *flow, + struct flow_wildcards *wc) { - if (is_ip_any(base_flow) - && (flow->tunnel.ip_tos & IP_ECN_MASK) == IP_ECN_CE) { - if ((base_flow->nw_tos & IP_ECN_MASK) == IP_ECN_NOT_ECT) { - VLOG_WARN_RL(&rl, "dropping tunnel packet marked ECN CE" - " but is not ECN capable"); - return false; - } else { - /* Set the ECN CE value in the tunneled packet. */ - flow->nw_tos |= IP_ECN_CE; + if (is_ip_any(base_flow)) { + if ((flow->tunnel.ip_tos & IP_ECN_MASK) == IP_ECN_CE) { + wc->masks.nw_tos |= IP_ECN_MASK; + if ((base_flow->nw_tos & IP_ECN_MASK) == IP_ECN_NOT_ECT) { + VLOG_WARN_RL(&rl, "dropping tunnel packet marked ECN CE" + " but is not ECN capable"); + return false; + } else { + /* Set the ECN CE value in the tunneled packet. */ + flow->nw_tos |= IP_ECN_CE; + } } } @@ -323,6 +326,11 @@ bool tnl_xlate_init(const struct flow *base_flow, struct flow *flow, struct flow_wildcards *wc) { + /* tnl_port_should_receive() examines the 'tunnel.ip_dst' field to + * determine the presence of the tunnel metadata. However, since tunnels' + * datapath port numbers are different from the non-tunnel ports, and we + * always unwildcard the 'in_port', we do not need to unwildcard + * the 'tunnel.ip_dst' for non-tunneled packets. */ if (tnl_port_should_receive(flow)) { wc->masks.tunnel.tun_id = OVS_BE64_MAX; wc->masks.tunnel.ip_src = OVS_BE32_MAX; @@ -335,7 +343,7 @@ tnl_xlate_init(const struct flow *base_flow, struct flow *flow, memset(&wc->masks.pkt_mark, 0xff, sizeof wc->masks.pkt_mark); - if (!tnl_ecn_ok(base_flow, flow)) { + if (!tnl_ecn_ok(base_flow, flow, wc)) { return false; } @@ -392,7 +400,7 @@ tnl_port_send(const struct ofport_dpif *ofport, struct flow *flow, } if (cfg->tos_inherit && is_ip_any(flow)) { - wc->masks.nw_tos = 0xff; + wc->masks.nw_tos = IP_DSCP_MASK; flow->tunnel.ip_tos = flow->nw_tos & IP_DSCP_MASK; } else { flow->tunnel.ip_tos = cfg->tos; @@ -401,12 +409,12 @@ tnl_port_send(const struct ofport_dpif *ofport, struct flow *flow, /* ECN fields are always inherited. */ if (is_ip_any(flow)) { wc->masks.nw_tos |= IP_ECN_MASK; - } - if ((flow->nw_tos & IP_ECN_MASK) == IP_ECN_CE) { - flow->tunnel.ip_tos |= IP_ECN_ECT_0; - } else { - flow->tunnel.ip_tos |= flow->nw_tos & IP_ECN_MASK; + if ((flow->nw_tos & IP_ECN_MASK) == IP_ECN_CE) { + flow->tunnel.ip_tos |= IP_ECN_ECT_0; + } else { + flow->tunnel.ip_tos |= flow->nw_tos & IP_ECN_MASK; + } } flow->tunnel.flags = (cfg->dont_fragment ? FLOW_TNL_F_DONT_FRAGMENT : 0)