]> git.proxmox.com Git - mirror_ovs.git/commitdiff
ofproto-dpif-xlate: Account mirrored packets only if the VLAN matches.
authorBen Pfaff <blp@ovn.org>
Thu, 27 Dec 2018 21:41:55 +0000 (13:41 -0800)
committerBen Pfaff <blp@ovn.org>
Fri, 18 Jan 2019 00:25:43 +0000 (16:25 -0800)
Until now, OVS has accounted packets to mirrors even if the VLAN selection
criteria did not match.  This fixes the problem.

Acked-by: Justin Pettit <jpettit@ovn.org>
Tested-by: Shweta Seth <shwseth@cisco.com>
Reported-by: Shweta Seth <shwseth@cisco.com>
Reported-at: https://mail.openvswitch.org/pipermail/ovs-discuss/2018-December/047931.html
Signed-off-by: Ben Pfaff <blp@ovn.org>
ofproto/ofproto-dpif-xlate.c

index 839fddd99fbe423175c7155dd03e0202e2c9501a..b2e986264612c6e118cb474163ca37cfb8ebbaec 100644 (file)
@@ -2058,21 +2058,10 @@ mirror_packet(struct xlate_ctx *ctx, struct xbundle *xbundle,
         return;
     }
 
-    if (ctx->xin->resubmit_stats) {
-        mirror_update_stats(xbridge->mbridge, mirrors,
-                            ctx->xin->resubmit_stats->n_packets,
-                            ctx->xin->resubmit_stats->n_bytes);
-    }
-    if (ctx->xin->xcache) {
-        struct xc_entry *entry;
-
-        entry = xlate_cache_add_entry(ctx->xin->xcache, XC_MIRROR);
-        entry->mirror.mbridge = mbridge_ref(xbridge->mbridge);
-        entry->mirror.mirrors = mirrors;
-    }
-
-    /* 'mirrors' is a bit-mask of candidates for mirroring.  Iterate as long as
-     * some candidates remain.  */
+    /* 'mirrors' is a bit-mask of candidates for mirroring.  Iterate through
+     * the candidates, adding the ones that really should be mirrored to
+     * 'used_mirrors', as long as some candidates remain.  */
+    mirror_mask_t used_mirrors = 0;
     while (mirrors) {
         const unsigned long *vlans;
         mirror_mask_t dup_mirrors;
@@ -2096,6 +2085,9 @@ mirror_packet(struct xlate_ctx *ctx, struct xbundle *xbundle,
             continue;
         }
 
+        /* We sent a packet to this mirror. */
+        used_mirrors |= rightmost_1bit(mirrors);
+
         /* Record the mirror, and the mirrors that output to the same
          * destination, so that we don't mirror to them again.  This must be
          * done now to ensure that output_normal(), below, doesn't recursively
@@ -2129,6 +2121,21 @@ mirror_packet(struct xlate_ctx *ctx, struct xbundle *xbundle,
         mirrors &= ~ctx->mirrors;
         ctx->mirror_snaplen = 0;
     }
+
+    if (used_mirrors) {
+        if (ctx->xin->resubmit_stats) {
+            mirror_update_stats(xbridge->mbridge, used_mirrors,
+                                ctx->xin->resubmit_stats->n_packets,
+                                ctx->xin->resubmit_stats->n_bytes);
+        }
+        if (ctx->xin->xcache) {
+            struct xc_entry *entry;
+
+            entry = xlate_cache_add_entry(ctx->xin->xcache, XC_MIRROR);
+            entry->mirror.mbridge = mbridge_ref(xbridge->mbridge);
+            entry->mirror.mirrors = used_mirrors;
+        }
+    }
 }
 
 static void