[ovs-dev] ofproto-dpif-xlate: Check mirror port before do terminate_native_tunnel
diff mbox series

Message ID 20190726121839.92497-1-wang.li@139.com
State New
Headers show
Series
  • [ovs-dev] ofproto-dpif-xlate: Check mirror port before do terminate_native_tunnel
Related show

Commit Message

Wang Li July 26, 2019, 12:18 p.m. UTC
From: Wang Li <wangli39@baidu.com>

The problem is the ovs-tcpdump can not capture the ingress vxlan traffics
when it listens on the dpdk port, and the following dump-flows described
the details:

ovs-tcpdump stopped:
recirc_id(0),in_port(2),packet_type(ns=0,id=0),eth(),eth_type(0x0800),ipv4(),
udp(dst=4789), packets:6, bytes:888, used:0.188s, actions:tnl_pop(6)

ovs-tcpdump started:
recirc_id(0),in_port(2),packet_type(ns=0,id=0),eth(),eth_type(0x0800),ipv4(),
udp(dst=4789), packets:17, bytes:2516, used:0.038s,actions:tnl_pop(6),tnl_pop(6)

There are two tnl_pop actions here, and the ovs-tcpdump app can not capture any
ingress vxlan traffics, in the meantime the side effect is the VM got duplicate
packets that looks like this:
64 bytes from 172.16.0.37: icmp_seq=1 ttl=64 time=0.132 ms
64 bytes from 172.16.0.37: icmp_seq=1 ttl=64 time=0.132 ms (DUP!)
64 bytes from 172.16.0.37: icmp_seq=2 ttl=64 time=0.115 ms
64 bytes from 172.16.0.37: icmp_seq=2 ttl=64 time=0.115 ms (DUP!)

ovs-tcpdump started with this fix:
recirc_id(0),in_port(2),packet_type(ns=0,id=0),eth(),eth_type(0x0800),ipv4(),
udp(dst=4789), packets:29, bytes:4292, used:0.330s, actions:7,tnl_pop(6)

The root cause is the duplicate tnl_pop actions, so this fix will check if the
ingress vxlan traffics are mirrored to the specified mirror port, in that case
we should deliver the origin vxlan packets to mirror port without tnl_pop.

Signed-off-by: Wang Li <wangli39@baidu.com>
---
 ofproto/ofproto-dpif-xlate.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

Patch
diff mbox series

diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index 28a7fdd84..93536df11 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -153,6 +153,7 @@  struct xbundle {
                                    /* Use 802.1p tag for frames in VLAN 0? */
     bool floodable;                /* No port has OFPUTIL_PC_NO_FLOOD set? */
     bool protected;                /* Protected port mode */
+    bool is_mirror;                /* True if it is mirror port */
 };
 
 struct xport {
@@ -184,6 +185,7 @@  struct xport {
 
     bool may_enable;                 /* May be enabled in bonds. */
     bool is_tunnel;                  /* Is a tunnel port. */
+    bool is_mirror;                  /* Is a mirror port. */
     enum netdev_pt_mode pt_mode;     /* packet_type handling. */
 
     struct cfm *cfm;                 /* CFM handle or null. */
@@ -2124,6 +2126,7 @@  mirror_packet(struct xlate_ctx *ctx, struct xbundle *xbundle,
         if (out) {
             struct xbundle *out_xbundle = xbundle_lookup(ctx->xcfg, out);
             if (out_xbundle) {
+                out_xbundle->is_mirror = true;
                 output_normal(ctx, out_xbundle, &xvlan);
             }
         } else if (xvlan.v[0].vid != out_vlan
@@ -2458,6 +2461,7 @@  output_normal(struct xlate_ctx *ctx, const struct xbundle *out_xbundle,
     memcpy(&old_vlans, &ctx->xin->flow.vlans, sizeof(old_vlans));
     xvlan_put(&ctx->xin->flow, &out_xvlan, out_xbundle->use_priority_tags);
 
+    xport->is_mirror = out_xbundle->is_mirror;
     compose_output_action(ctx, xport->ofp_port, use_recirc ? &xr : NULL,
                           false, false);
     memcpy(&ctx->xin->flow.vlans, &old_vlans, sizeof(old_vlans));
@@ -4151,8 +4155,8 @@  compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port,
             native_tunnel_output(ctx, xport, flow, odp_port, truncate);
             flow->tunnel = flow_tnl; /* Restore tunnel metadata */
 
-        } else if (terminate_native_tunnel(ctx, ofp_port, flow, wc,
-                                           &odp_tnl_port)) {
+        } else if (!xport->is_mirror && terminate_native_tunnel(ctx, ofp_port,
+                                flow, wc, &odp_tnl_port)) {
             /* Intercept packet to be received on native tunnel port. */
             nl_msg_put_odp_port(ctx->odp_actions, OVS_ACTION_ATTR_TUNNEL_POP,
                                 odp_tnl_port);