From d4f4a9b25251d8279f5287142bc84f637101ee77 Mon Sep 17 00:00:00 2001 From: Justin Pettit Date: Thu, 13 Jun 2013 16:46:33 -0700 Subject: [PATCH] tunnel: Don't wildcard TTL and TOS in some circumstances. For tunnels, we need to handle the facet's wildcards specially in a couple of cases: - Don't wildcard TTL for facets if "ttl" option is "inherit". - Never wildcard the ECN bits, since they are always inherited. - Wildcard the rest of the TOS field if the "tos" option is "inherit". Issue #17911 Signed-off-by: Justin Pettit --- ofproto/ofproto-dpif-xlate.c | 2 +- ofproto/tunnel.c | 7 ++++++- ofproto/tunnel.h | 3 ++- tests/ofproto-dpif.at | 29 +++++++++++++++++++++++++++++ 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index ca26acb14..f506c283b 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -873,7 +873,7 @@ compose_output_action__(struct xlate_ctx *ctx, uint16_t ofp_port, * matches, while explicit set actions on tunnel metadata are. */ struct flow_tnl flow_tnl = flow->tunnel; - odp_port = tnl_port_send(ofport->tnl_port, flow); + odp_port = tnl_port_send(ofport->tnl_port, flow, &ctx->xout->wc); if (odp_port == OVSP_NONE) { xlate_report(ctx, "Tunneling decided against output"); goto out; /* restore flow_nw_tos */ diff --git a/ofproto/tunnel.c b/ofproto/tunnel.c index df28df3e6..636c5492e 100644 --- a/ofproto/tunnel.c +++ b/ofproto/tunnel.c @@ -213,7 +213,8 @@ tnl_port_receive(const struct flow *flow) * port that the output should happen on. May return OVSP_NONE if the output * shouldn't occur. */ uint32_t -tnl_port_send(const struct tnl_port *tnl_port, struct flow *flow) +tnl_port_send(const struct tnl_port *tnl_port, struct flow *flow, + struct flow_wildcards *wc) { const struct netdev_tunnel_config *cfg; char *pre_flow_str = NULL; @@ -242,14 +243,18 @@ tnl_port_send(const struct tnl_port *tnl_port, struct flow *flow) } if (cfg->ttl_inherit && is_ip_any(flow)) { + wc->masks.nw_ttl = 0xff; flow->tunnel.ip_ttl = flow->nw_ttl; } else { flow->tunnel.ip_ttl = cfg->ttl; } if (cfg->tos_inherit && is_ip_any(flow)) { + wc->masks.nw_tos = 0xff; flow->tunnel.ip_tos = flow->nw_tos & IP_DSCP_MASK; } else { + /* ECN fields are always inherited. */ + wc->masks.nw_tos |= IP_ECN_MASK; flow->tunnel.ip_tos = cfg->tos; } diff --git a/ofproto/tunnel.h b/ofproto/tunnel.h index 34c113368..803e2d94d 100644 --- a/ofproto/tunnel.h +++ b/ofproto/tunnel.h @@ -38,7 +38,8 @@ struct tnl_port *tnl_port_add(const struct ofport *, uint32_t odp_port); void tnl_port_del(struct tnl_port *); const struct ofport *tnl_port_receive(const struct flow *); -uint32_t tnl_port_send(const struct tnl_port *, struct flow *); +uint32_t tnl_port_send(const struct tnl_port *, struct flow *, + struct flow_wildcards *wc); /* Returns true if 'flow' should be submitted to tnl_port_receive(). */ static inline bool diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at index e8458d0f5..3109314ff 100644 --- a/tests/ofproto-dpif.at +++ b/tests/ofproto-dpif.at @@ -2553,3 +2553,32 @@ in_port=1,vlan_tci=0x0000/0x0fff,dl_src=50:54:00:00:00:0b, n_subfacets:1, used:0 ]) OVS_VSWITCHD_STOP AT_CLEANUP + +AT_SETUP([ofproto-dpif megaflow - tunnels]) +OVS_VSWITCHD_START( + [add-port br0 p1 -- set Interface p1 type=dummy ofport_request=1 \ + ofport_request=1 -- \ + add-port br0 p2 -- set Interface p2 type=gre options:remote_ip=1.1.1.1 \ + ofport_request=2 options:key=flow -- \ + add-port br0 p3 -- set Interface p3 type=dummy ofport_request=3 \ + ofport_request=3 -- \ + add-port br0 p4 -- set Interface p4 type=gre options:remote_ip=1.1.1.2 \ + options:tos=inherit options:ttl=inherit ofport_request=4 options:key=flow]) +AT_DATA([flows.txt], [dnl +in_port=1,actions=output(2) +in_port=3,actions=output(4) +]) +AT_CHECK([ovs-ofctl add-flows br0 flows.txt]) +dnl ECN bits are always copied out, but don't use 0x3 (CE), since that +dnl will cause the packet to be dropped. +AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0xfd,ttl=128,frag=no),icmp(type=8,code=0)']) +AT_CHECK([ovs-appctl netdev-dummy/receive p1 'in_port(1),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.4,dst=10.0.0.3,proto=1,tos=0x1,ttl=64,frag=no),icmp(type=8,code=0)']) +AT_CHECK([ovs-appctl netdev-dummy/receive p3 'in_port(3),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0xfd,ttl=128,frag=no),icmp(type=8,code=0)']) +AT_CHECK([ovs-appctl netdev-dummy/receive p3 'in_port(3),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.4,dst=10.0.0.3,proto=1,tos=0x1,ttl=64,frag=no),icmp(type=8,code=0)']) +AT_CHECK([ovs-appctl dpif/dump-megaflows br0 | STRIP_XOUT], [0], [dnl +in_port=1,nw_ecn=1, n_subfacets:2, used:0.0s, Datapath actions: +in_port=3,nw_tos=0,nw_ecn=1,nw_ttl=64, n_subfacets:1, used:0.0s, Datapath actions: +in_port=3,nw_tos=252,nw_ecn=1,nw_ttl=128, n_subfacets:1, used:0.0s, Datapath actions: +]) +OVS_VSWITCHD_STOP +AT_CLEANUP -- 2.43.0