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 <[email protected]>
---
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
_______________________________________________
dev mailing list
[email protected]
http://openvswitch.org/mailman/listinfo/dev