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

From: Huanle Han <hanxue...@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 <hanxue...@gmail.com>
---
 ofproto/ofproto-dpif-xlate.c | 33 ++++++++++++++++++++++++---------
 1 file changed, 24 insertions(+), 9 deletions(-)

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) {
-            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
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev
_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to