Later patches rely on the DSCP and ECN masks to be properly set when the fields are read. Also, avoid reading nw_tos if tunnel's inner packet is not IP.
Signed-off-by: Jarno Rajahalme <jrajaha...@nicira.com> --- ofproto/ofproto-dpif-xlate.c | 2 +- ofproto/tunnel.c | 37 ++++++++++++++++++++----------------- 2 files changed, 21 insertions(+), 18 deletions(-) diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index c3040d7..0952037 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -1790,7 +1790,7 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port, flow_nw_tos = flow->nw_tos; if (dscp_from_skb_priority(xport, flow->skb_priority, &dscp)) { - wc->masks.nw_tos |= IP_ECN_MASK; + wc->masks.nw_tos |= IP_DSCP_MASK; flow->nw_tos &= ~IP_DSCP_MASK; flow->nw_tos |= dscp; } diff --git a/ofproto/tunnel.c b/ofproto/tunnel.c index 001045a..336b810 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)) { + wc->masks.nw_tos |= IP_ECN_MASK; + if ((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; + } } } @@ -335,7 +338,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 +395,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 +404,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) -- 1.7.10.4 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev