[ovs-dev] [PATCH 56/62] ofproto-dpif-xlate: ovs-tcpdump cannot capture incomming vxlan packets

Tao YunXiang taoyunxiang at cmss.chinamobile.com
Mon Dec 28 09:25:14 UTC 2020


From: Taoyunxiang <taoyunxiang at cmss.chinamobile.com>

Code Source From: Self Code
Description:
when running ovs-tcpdump -i ethX and the port is used
as the incomming port for a vxlan port.

The callstack for the upcall:

mirror_ingress_packet
mirror_packet
output_normal
compose_output_action
compose_output_action__
terminate_native_tunnel

it will xlate the action into a tnl_pop action, not an output action to the
mirror port. So eventually the translated actions will be 'tnl_pop(x), tnl_pop(x)'.
However, the right action should be '(mirror port), tnl_pop(x)'

This patch adds a flag in xlate_ctx indicating the current output_normal
is used by mirroring. Note that we cannot use ctx->mirrors as the
indicator as in the mirror code, the ctx->mirrors will not be cleared
after mirror action finished.

Jira:  #[Optional]
市场项目编号(名称):[Optional]
---
 lib/dpif-netdev.c            | 11 ++++++++++-
 ofproto/ofproto-dpif-xlate.c | 10 ++++++++--
 2 files changed, 18 insertions(+), 3 deletions(-)

diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
index e127396..85e1fe4 100644
--- a/lib/dpif-netdev.c
+++ b/lib/dpif-netdev.c
@@ -2362,17 +2362,20 @@ mark_to_flow_disassociate(struct dp_netdev_pmd_thread *pmd,
     return ret;
 }
 
+/*
 static void
 flow_mark_flush(struct dp_netdev_pmd_thread *pmd)
 {
     struct dp_netdev_flow *flow;
 
+    VLOG_DBG("TIMO DBG: in flow_mark_flush\n");
     CMAP_FOR_EACH (flow, mark_node, &flow_mark.mark_to_flow) {
         if (flow->pmd_id == pmd->core_id) {
             queue_netdev_flow_del(pmd, flow);
         }
     }
 }
+*/
 
 static struct dp_netdev_flow *
 mark_to_flow_find(const struct dp_netdev_pmd_thread *pmd,
@@ -2466,6 +2469,8 @@ dp_netdev_flow_offload_put(struct dp_flow_offload_item *offload)
     }
 
     if (modification) {
+        VLOG_DBG("TIMO DBG: mod flow ufid:"UUID_FMT" \n",
+              UUID_ARGS((struct uuid *)&flow->ufid));
         mark = flow->mark;
         ovs_assert(mark != INVALID_FLOW_MARK);
     } else {
@@ -5032,7 +5037,11 @@ reload_affected_pmds(struct dp_netdev *dp)
 
     CMAP_FOR_EACH (pmd, node, &dp->poll_threads) {
         if (pmd->need_reload) {
-            flow_mark_flush(pmd);
+            /* For dp port add/del, don't need to 
+             * delete hw flows, only sw flow delete
+             * would trigger hw flow delete
+             * flow_mark_flush(pmd);
+             */
             dp_netdev_reload_pmd__(pmd);
         }
     }
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index 54cfbfb..5e2b676 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -269,6 +269,7 @@ struct xlate_ctx {
     bool exit;                  /* No further actions should be processed. */
     mirror_mask_t mirrors;      /* Bitmap of associated mirrors. */
     int mirror_snaplen;         /* Max size of a mirror packet in byte. */
+    bool in_mirror_output;
 
    /* Freezing Translation
     * ====================
@@ -2147,7 +2148,9 @@ mirror_packet(struct xlate_ctx *ctx, struct xbundle *xbundle,
         if (out) {
             struct xbundle *out_xbundle = xbundle_lookup(ctx->xcfg, out);
             if (out_xbundle) {
+                ctx->in_mirror_output = true;
                 output_normal(ctx, out_xbundle, &xvlan);
+                ctx->in_mirror_output = false;
             }
         } else if (xvlan.v[0].vid != out_vlan
                    && !eth_addr_is_reserved(ctx->xin->flow.dl_dst)) {
@@ -2158,7 +2161,9 @@ mirror_packet(struct xlate_ctx *ctx, struct xbundle *xbundle,
             LIST_FOR_EACH (xb, list_node, &xbridge->xbundles) {
                 if (xbundle_includes_vlan(xb, &xvlan)
                     && !xbundle_mirror_out(xbridge, xb)) {
+                    ctx->in_mirror_output = true;
                     output_normal(ctx, xb, &xvlan);
+                    ctx->in_mirror_output = false;
                 }
             }
             xvlan.v[0].vid = old_vid;
@@ -4223,8 +4228,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, flow, wc,
-                                           &odp_tnl_port)) {
+        } else if (!ctx->in_mirror_output && 
+                   terminate_native_tunnel(ctx, 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);
@@ -7462,6 +7467,7 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout)
         .exit = false,
         .error = XLATE_OK,
         .mirrors = 0,
+        .in_mirror_output = false,
 
         .freezing = false,
         .recirc_update_dp_hash = false,
-- 
1.8.3.1





More information about the dev mailing list