diff mbox series

[ovs-dev] 答复: [PATCH 2/3] xlate: fix packets loopback caused by duplicate read of xcfgp.

Message ID 40280F65B1B0B44E8089ED31C01616EBA35D3C48@dggeml509-mbx.china.huawei.com
State Not Applicable
Headers show
Series [ovs-dev] 答复: [PATCH 2/3] xlate: fix packets loopback caused by duplicate read of xcfgp. | expand

Commit Message

Lilijun (Jerry, Cloud Networking) Jan. 24, 2018, 5:56 p.m. UTC
I have tested your patch and can fix my problem described in the following patch. 
https://mail.openvswitch.org/pipermail/ovs-dev/2018-January/343423.html

Thanks.

-----邮件原件-----
发件人: ovs-dev-bounces@openvswitch.org [mailto:ovs-dev-bounces@openvswitch.org] 代表 Ben Pfaff
发送时间: 2018年1月25日 1:41
收件人: dev@openvswitch.org
抄送: Ben Pfaff <blp@ovn.org>
主题: [ovs-dev] [PATCH 2/3] xlate: fix packets loopback caused by duplicate read of xcfgp.

From: Huanle Han <hanxueluo@gmail.com>


Some functions, such as xlate_normal_mcast_send_mrouters, test xbundle pointers equality to avoid sending packet back to in bundle. However, xbundle pointers port from different xcfgp for same port are inequal.
This may lead to the packet loopback.

This commit stores xcfgp on ctx at first and always uses the same xcfgp during one packet process period.

Signed-off-by: Huanle Han <hanxueluo@gmail.com>

---
 ofproto/ofproto-dpif-xlate.c | 33 ++++++++++++++++++++++++---------
 1 file changed, 24 insertions(+), 9 deletions(-)

-            struct xlate_cfg *xcfg = ovsrcu_get(struct xlate_cfg *, &xcfgp);
+            struct xlate_cfg *xcfg = xlate_get_cfg(ctx);
             struct xbundle *out_xbundle = xbundle_lookup(xcfg, out);
             if (out_xbundle) {
                 output_normal(ctx, out_xbundle, &xvlan); @@ -2234,7 +2248,7 @@ output_normal(struct xlate_ctx *ctx, const struct xbundle *out_xbundle,
         xport = CONTAINER_OF(ovs_list_front(&out_xbundle->xports), struct xport,
                              bundle_node);
     } else {
-        struct xlate_cfg *xcfg = ovsrcu_get(struct xlate_cfg *, &xcfgp);
+        struct xlate_cfg *xcfg = xlate_get_cfg(ctx);
         struct flow_wildcards *wc = ctx->wc;
         struct ofport_dpif *ofport;
 
@@ -2537,7 +2551,7 @@ update_mcast_snooping_table(const struct xlate_ctx *ctx,
     /* Don't learn from flood ports */
     mcast_xbundle = NULL;
     ovs_rwlock_wrlock(&ms->rwlock);
-    xcfg = ovsrcu_get(struct xlate_cfg *, &xcfgp);
+    xcfg = xlate_get_cfg(ctx);
     LIST_FOR_EACH(fport, node, &ms->fport_list) {
         mcast_xbundle = xbundle_lookup(xcfg, fport->port);
         if (mcast_xbundle == in_xbundle) { @@ -2570,7 +2584,7 @@ xlate_normal_mcast_send_group(struct xlate_ctx *ctx,
     struct mcast_group_bundle *b;
     struct xbundle *mcast_xbundle;
 
-    xcfg = ovsrcu_get(struct xlate_cfg *, &xcfgp);
+    xcfg = xlate_get_cfg(ctx);
     LIST_FOR_EACH(b, bundle_node, &grp->bundle_lru) {
         mcast_xbundle = xbundle_lookup(xcfg, b->port);
         if (mcast_xbundle && mcast_xbundle != in_xbundle) { @@ -2598,7 +2612,7 @@ xlate_normal_mcast_send_mrouters(struct xlate_ctx *ctx,
     struct mcast_mrouter_bundle *mrouter;
     struct xbundle *mcast_xbundle;
 
-    xcfg = ovsrcu_get(struct xlate_cfg *, &xcfgp);
+    xcfg = xlate_get_cfg(ctx);
     LIST_FOR_EACH(mrouter, mrouter_node, &ms->mrouter_lru) {
         mcast_xbundle = xbundle_lookup(xcfg, mrouter->port);
         if (mcast_xbundle && mcast_xbundle != in_xbundle @@ -2630,7 +2644,7 @@ xlate_normal_mcast_send_fports(struct xlate_ctx *ctx,
     struct mcast_port_bundle *fport;
     struct xbundle *mcast_xbundle;
 
-    xcfg = ovsrcu_get(struct xlate_cfg *, &xcfgp);
+    xcfg = xlate_get_cfg(ctx);
     LIST_FOR_EACH(fport, node, &ms->fport_list) {
         mcast_xbundle = xbundle_lookup(xcfg, fport->port);
         if (mcast_xbundle && mcast_xbundle != in_xbundle) { @@ -2658,7 +2672,7 @@ xlate_normal_mcast_send_rports(struct xlate_ctx *ctx,
     struct mcast_port_bundle *rport;
     struct xbundle *mcast_xbundle;
 
-    xcfg = ovsrcu_get(struct xlate_cfg *, &xcfgp);
+    xcfg = xlate_get_cfg(ctx);
     LIST_FOR_EACH(rport, node, &ms->rport_list) {
         mcast_xbundle = xbundle_lookup(xcfg, rport->port);
         if (mcast_xbundle
@@ -2890,7 +2904,7 @@ xlate_normal(struct xlate_ctx *ctx)
         ovs_rwlock_unlock(&ctx->xbridge->ml->rwlock);
 
         if (mac_port) {
-            struct xlate_cfg *xcfg = ovsrcu_get(struct xlate_cfg *, &xcfgp);
+            struct xlate_cfg *xcfg = xlate_get_cfg(ctx);
             struct xbundle *mac_xbundle = xbundle_lookup(xcfg, mac_port);
             if (mac_xbundle
                 && mac_xbundle != in_xbundle @@ -6840,6 +6854,7 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout)
         .xout = xout,
         .base_flow = *flow,
         .orig_tunnel_ipv6_dst = flow_tnl_dst(&flow->tunnel),
+        .xcfg = xcfg,
         .xbridge = xbridge,
         .stack = OFPBUF_STUB_INITIALIZER(stack_stub),
         .rule = xin->rule,
--
2.10.2

_______________________________________________
dev mailing list
dev@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev
diff mbox series

Patch

diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index 51ddc93a0935..9d6ca94afc82 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -182,6 +182,7 @@  struct xlate_ctx {
     struct xlate_in *xin;
     struct xlate_out *xout;
 
+    struct xlate_cfg *xcfg;
     const struct xbridge *xbridge;
 
     /* Flow at the last commit. */
@@ -512,9 +513,22 @@  struct xlate_cfg {
 static OVSRCU_TYPE(struct xlate_cfg *) xcfgp = OVSRCU_INITIALIZER(NULL);  static struct xlate_cfg *new_xcfg = NULL;
 
+static struct xlate_cfg *
+xlate_get_cfg(const struct xlate_ctx *ctx) {
+    struct xlate_cfg *cfg = NULL;
+
+    if (ctx && ctx->xcfg) {
+        cfg = ctx->xcfg;
+    } else {
+        cfg = ovsrcu_get(struct xlate_cfg *, &xcfgp);
+    }
+
+    return cfg;
+}
+
 typedef void xlate_actions_handler(const struct ofpact *, size_t ofpacts_len,
                                    struct xlate_ctx *, bool);
-
 static bool may_receive(const struct xport *, struct xlate_ctx *);  static void do_xlate_actions(const struct ofpact *, size_t ofpacts_len,
                              struct xlate_ctx *, bool); @@ -1965,7 +1979,7 @@ mirror_packet(struct xlate_ctx *ctx, struct xbundle *xbundle,
 
         /* Send the packet to the mirror. */
         if (out) {