Signed-off-by: Matthias May <[email protected]>
---
 ofproto/ofproto-dpif-xlate.c | 53 +++++++++++++++++++++++++++++++++-----------
 ofproto/ofproto-dpif-xlate.h |  4 ++--
 2 files changed, 42 insertions(+), 15 deletions(-)

diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index ca286e372..297619a8d 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -126,6 +126,7 @@ struct xbundle {
     struct bond *bond;             /* Nonnull iff more than one port. */
     struct lacp *lacp;             /* LACP handle or null. */
 
+    ofp_port_t port_group;         /* Group of ports to forbid loopback */
     enum port_vlan_mode vlan_mode; /* VLAN mode. */
     uint16_t qinq_ethtype;         /* Ethertype of dot1q-tunnel interface
                                     * either 0x8100 or 0x88a8. */
@@ -554,6 +555,7 @@ static void xlate_xbridge_set(struct xbridge *, struct dpif 
*,
                               bool forward_bpdu, bool has_in_band,
                               const struct dpif_backer_support *);
 static void xlate_xbundle_set(struct xbundle *xbundle,
+                              ofp_port_t port_group,
                               enum port_vlan_mode vlan_mode,
                               uint16_t qinq_ethtype, int vlan,
                               unsigned long *trunks, unsigned long *cvlans,
@@ -862,6 +864,7 @@ xlate_xbridge_set(struct xbridge *xbridge,
 
 static void
 xlate_xbundle_set(struct xbundle *xbundle,
+                  ofp_port_t port_group,
                   enum port_vlan_mode vlan_mode, uint16_t qinq_ethtype,
                   int vlan, unsigned long *trunks, unsigned long *cvlans,
                   bool use_priority_tags,
@@ -870,6 +873,7 @@ xlate_xbundle_set(struct xbundle *xbundle,
 {
     ovs_assert(xbundle->xbridge);
 
+    xbundle->port_group = port_group;
     xbundle->vlan_mode = vlan_mode;
     xbundle->qinq_ethtype = qinq_ethtype;
     xbundle->vlan = vlan;
@@ -969,10 +973,11 @@ xlate_xbundle_copy(struct xbridge *xbridge, struct 
xbundle *xbundle)
     new_xbundle->name = xstrdup(xbundle->name);
     xlate_xbundle_init(new_xcfg, new_xbundle);
 
-    xlate_xbundle_set(new_xbundle, xbundle->vlan_mode, xbundle->qinq_ethtype,
-                      xbundle->vlan, xbundle->trunks, xbundle->cvlans,
-                      xbundle->use_priority_tags, xbundle->bond, xbundle->lacp,
-                      xbundle->floodable, xbundle->protected);
+    xlate_xbundle_set(new_xbundle, xbundle->port_group, xbundle->vlan_mode,
+                      xbundle->qinq_ethtype, xbundle->vlan, xbundle->trunks,
+                      xbundle->cvlans, xbundle->use_priority_tags,
+                      xbundle->bond, xbundle->lacp, xbundle->floodable,
+                      xbundle->protected);
     LIST_FOR_EACH (xport, bundle_node, &xbundle->xports) {
         xlate_xport_copy(xbridge, new_xbundle, xport);
     }
@@ -1163,8 +1168,8 @@ xlate_remove_ofproto(struct ofproto_dpif *ofproto)
 
 void
 xlate_bundle_set(struct ofproto_dpif *ofproto, struct ofbundle *ofbundle,
-                 const char *name, enum port_vlan_mode vlan_mode,
-                 uint16_t qinq_ethtype, int vlan,
+                 const char *name, ofp_port_t port_group,
+                 enum port_vlan_mode vlan_mode, uint16_t qinq_ethtype, int 
vlan,
                  unsigned long *trunks, unsigned long *cvlans,
                  bool use_priority_tags,
                  const struct bond *bond, const struct lacp *lacp,
@@ -1186,7 +1191,8 @@ xlate_bundle_set(struct ofproto_dpif *ofproto, struct 
ofbundle *ofbundle,
     free(xbundle->name);
     xbundle->name = xstrdup(name);
 
-    xlate_xbundle_set(xbundle, vlan_mode, qinq_ethtype, vlan, trunks, cvlans,
+    xlate_xbundle_set(xbundle, port_group,
+                      vlan_mode, qinq_ethtype, vlan, trunks, cvlans,
                       use_priority_tags, bond, lacp, floodable, protected);
 }
 
@@ -2495,12 +2501,16 @@ xlate_normal_mcast_send_group(struct xlate_ctx *ctx,
     xcfg = ovsrcu_get(struct xlate_cfg *, &xcfgp);
     LIST_FOR_EACH(b, bundle_node, &grp->bundle_lru) {
         mcast_xbundle = xbundle_lookup(xcfg, b->port);
-        if (mcast_xbundle && mcast_xbundle != in_xbundle) {
+        if (mcast_xbundle && mcast_xbundle != in_xbundle
+            && mcast_xbundle->port_group != in_xbundle->port_group) {
             xlate_report(ctx, OFT_DETAIL, "forwarding to mcast group port");
             output_normal(ctx, mcast_xbundle, xvlan);
         } else if (!mcast_xbundle) {
             xlate_report(ctx, OFT_WARN,
                          "mcast group port is unknown, dropping");
+        } else if (mcast_xbundle->port_group == in_xbundle->port_group) {
+            xlate_report(ctx, OFT_DETAIL,
+                         "mcast group port is in same port_group, dropping");
         } else {
             xlate_report(ctx, OFT_DETAIL,
                          "mcast group port is input port, dropping");
@@ -2524,7 +2534,8 @@ xlate_normal_mcast_send_mrouters(struct xlate_ctx *ctx,
     LIST_FOR_EACH(mrouter, mrouter_node, &ms->mrouter_lru) {
         mcast_xbundle = xbundle_lookup(xcfg, mrouter->port);
         if (mcast_xbundle && mcast_xbundle != in_xbundle
-            && mrouter->vlan == xvlan->v[0].vid) {
+            && mrouter->vlan == xvlan->v[0].vid
+            && mcast_xbundle->port_group != in_xbundle->port_group) {
             xlate_report(ctx, OFT_DETAIL, "forwarding to mcast router port");
             output_normal(ctx, mcast_xbundle, xvlan);
         } else if (!mcast_xbundle) {
@@ -2533,6 +2544,9 @@ xlate_normal_mcast_send_mrouters(struct xlate_ctx *ctx,
         } else if (mrouter->vlan != xvlan->v[0].vid) {
             xlate_report(ctx, OFT_DETAIL,
                          "mcast router is on another vlan, dropping");
+        } else if (mcast_xbundle->port_group == in_xbundle->port_group) {
+            xlate_report(ctx, OFT_DETAIL,
+                         "mcast router port is in same port_group, dropping");
         } else {
             xlate_report(ctx, OFT_DETAIL,
                          "mcast router port is input port, dropping");
@@ -2555,12 +2569,16 @@ xlate_normal_mcast_send_fports(struct xlate_ctx *ctx,
     xcfg = ovsrcu_get(struct xlate_cfg *, &xcfgp);
     LIST_FOR_EACH(fport, node, &ms->fport_list) {
         mcast_xbundle = xbundle_lookup(xcfg, fport->port);
-        if (mcast_xbundle && mcast_xbundle != in_xbundle) {
+        if (mcast_xbundle && mcast_xbundle != in_xbundle
+            && mcast_xbundle->port_group != in_xbundle->port_group) {
             xlate_report(ctx, OFT_DETAIL, "forwarding to mcast flood port");
             output_normal(ctx, mcast_xbundle, xvlan);
         } else if (!mcast_xbundle) {
             xlate_report(ctx, OFT_WARN,
                          "mcast flood port is unknown, dropping");
+        } else if (mcast_xbundle->port_group == in_xbundle->port_group) {
+            xlate_report(ctx, OFT_DETAIL,
+                         "mcast port is in same port_group, dropping");
         } else {
             xlate_report(ctx, OFT_DETAIL,
                          "mcast flood port is input port, dropping");
@@ -2583,13 +2601,17 @@ xlate_normal_mcast_send_rports(struct xlate_ctx *ctx,
     xcfg = ovsrcu_get(struct xlate_cfg *, &xcfgp);
     LIST_FOR_EACH(rport, node, &ms->rport_list) {
         mcast_xbundle = xbundle_lookup(xcfg, rport->port);
-        if (mcast_xbundle && mcast_xbundle != in_xbundle) {
+        if (mcast_xbundle && mcast_xbundle != in_xbundle
+            && mcast_xbundle->port_group != in_xbundle->port_group) {
             xlate_report(ctx, OFT_DETAIL,
                          "forwarding report to mcast flagged port");
             output_normal(ctx, mcast_xbundle, xvlan);
         } else if (!mcast_xbundle) {
             xlate_report(ctx, OFT_WARN,
                          "mcast port is unknown, dropping the report");
+        } else if (mcast_xbundle->port_group == in_xbundle->port_group) {
+            xlate_report(ctx, OFT_DETAIL,
+                         "mcast port is in same port_group, dropping");
         } else {
             xlate_report(ctx, OFT_DETAIL,
                          "mcast port is input port, dropping the Report");
@@ -2607,7 +2629,8 @@ xlate_normal_flood(struct xlate_ctx *ctx, struct xbundle 
*in_xbundle,
         if (xbundle != in_xbundle
             && xbundle_includes_vlan(xbundle, xvlan)
             && xbundle->floodable
-            && !xbundle_mirror_out(ctx->xbridge, xbundle)) {
+            && !xbundle_mirror_out(ctx->xbridge, xbundle)
+            && xbundle->port_group != in_xbundle->port_group) {
             output_normal(ctx, xbundle, xvlan);
         }
     }
@@ -2808,12 +2831,16 @@ xlate_normal(struct xlate_ctx *ctx)
         if (mac_port) {
             struct xlate_cfg *xcfg = ovsrcu_get(struct xlate_cfg *, &xcfgp);
             struct xbundle *mac_xbundle = xbundle_lookup(xcfg, mac_port);
-            if (mac_xbundle && mac_xbundle != in_xbundle) {
+            if (mac_xbundle && mac_xbundle != in_xbundle
+                && mac_xbundle->port_group != in_xbundle->port_group) {
                 xlate_report(ctx, OFT_DETAIL, "forwarding to learned port");
                 output_normal(ctx, mac_xbundle, &xvlan);
             } else if (!mac_xbundle) {
                 xlate_report(ctx, OFT_WARN,
                              "learned port is unknown, dropping");
+            } else if (mac_xbundle->port_group == in_xbundle->port_group) {
+                xlate_report(ctx, OFT_DETAIL,
+                             "learned port is in same port_group, dropping");
             } else {
                 xlate_report(ctx, OFT_DETAIL,
                              "learned port is input port, dropping");
diff --git a/ofproto/ofproto-dpif-xlate.h b/ofproto/ofproto-dpif-xlate.h
index 12abfa32b..a5c22e835 100644
--- a/ofproto/ofproto-dpif-xlate.h
+++ b/ofproto/ofproto-dpif-xlate.h
@@ -167,8 +167,8 @@ void xlate_ofproto_set(struct ofproto_dpif *, const char 
*name, struct dpif *,
 void xlate_remove_ofproto(struct ofproto_dpif *);
 
 void xlate_bundle_set(struct ofproto_dpif *, struct ofbundle *,
-                      const char *name, enum port_vlan_mode,
-                      uint16_t qinq_ethtype, int vlan,
+                      const char *name, ofp_port_t port_group,
+                      enum port_vlan_mode, uint16_t qinq_ethtype, int vlan,
                       unsigned long *trunks, unsigned long *cvlans,
                       bool use_priority_tags,
                       const struct bond *, const struct lacp *,
-- 
2.11.0

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to