[ovs-dev] [PATCH] tunnel: Don't wildcard TTL and TOS in some circumstances.

Justin Pettit jpettit at nicira.com
Thu Jun 13 23:53:25 UTC 2013


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 <jpettit at nicira.com>
---
 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 ca26acb..f506c28 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 df28df3..d1a6587 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 34c1133..803e2d9 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 e8458d0..3109314 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: <del>
+in_port=3,nw_tos=0,nw_ecn=1,nw_ttl=64, n_subfacets:1, used:0.0s, Datapath actions: <del>
+in_port=3,nw_tos=252,nw_ecn=1,nw_ttl=128, n_subfacets:1, used:0.0s, Datapath actions: <del>
+])
+OVS_VSWITCHD_STOP
+AT_CLEANUP
-- 
1.7.5.4




More information about the dev mailing list