[ovs-dev] [PATCH 2/2] vswitchd: Limit fake bridge MAC selection to ports in the same VLAN

Helmut Schaa helmut.schaa at googlemail.com
Wed Feb 19 10:59:33 UTC 2014


Limit fake bridge MAC address selection to only consider ports
that use the same VLAN as the fake bridge itself.

This prevents OVS from selecting a MAC address that was not really
present in the VLAN of the fake bridge before.

Signed-off-by: Helmut Schaa <helmut.schaa at googlemail.com>
---

I'm running this patchset on top of the 2.0 branch right now so
I'd appreciate some review before applying.

Thanks,
Helmut

 vswitchd/bridge.c | 27 ++++++++++++++++++++-------
 1 file changed, 20 insertions(+), 7 deletions(-)

diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
index 8223b9e..f86a883 100644
--- a/vswitchd/bridge.c
+++ b/vswitchd/bridge.c
@@ -252,7 +252,7 @@ static struct iface *iface_lookup(const struct bridge *, const char *name);
 static struct iface *iface_find(const char *name);
 static struct iface *iface_from_ofp_port(const struct bridge *,
                                          ofp_port_t ofp_port);
-static void iface_set_mac(struct iface *, const uint8_t *);
+static void iface_set_mac(const struct bridge *, const struct port *, struct iface *);
 static void iface_set_ofport(const struct ovsrec_interface *, ofp_port_t ofport);
 static void iface_clear_db_record(const struct ovsrec_interface *if_cfg);
 static void iface_configure_qos(struct iface *, const struct ovsrec_qos *);
@@ -578,7 +578,7 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg)
                 iface_set_ofport(iface->cfg, iface->ofp_port);
                 iface_configure_cfm(iface);
                 iface_configure_qos(iface, port->cfg->qos);
-                iface_set_mac(iface, port->cfg->fake_bridge ? br->ea : NULL);
+                iface_set_mac(br, port, iface);
                 ofproto_port_set_bfd(br->ofproto, iface->ofp_port,
                                      &iface->cfg->bfd);
             }
@@ -1568,8 +1568,8 @@ bridge_configure_mac_table(struct bridge *br)
 }
 
 static void
-find_local_hw_addr(struct bridge *br, uint8_t ea[ETH_ADDR_LEN],
-                   struct iface **hw_addr_iface)
+find_local_hw_addr(const struct bridge *br, uint8_t ea[ETH_ADDR_LEN],
+                   const struct port *fake_br, struct iface **hw_addr_iface)
 {
     struct hmapx mirror_output_ports;
     struct port *port;
@@ -1632,6 +1632,14 @@ find_local_hw_addr(struct bridge *br, uint8_t ea[ETH_ADDR_LEN],
                 continue;
             }
 
+            /* For fake bridges we only choose from ports with the same tag */
+            if (fake_br && fake_br->cfg && fake_br->cfg->tag) {
+                if (!port->cfg->tag)
+                    continue;
+                if (*port->cfg->tag != *fake_br->cfg->tag)
+                    continue;
+            }
+
             /* Grab MAC. */
             error = netdev_get_etheraddr(iface->netdev, iface_ea);
             if (error) {
@@ -1681,7 +1689,7 @@ bridge_pick_local_hw_addr(struct bridge *br, uint8_t ea[ETH_ADDR_LEN],
     }
 
     /* Find a local hw address */
-    find_local_hw_addr(br, ea, hw_addr_iface);
+    find_local_hw_addr(br, ea, NULL, hw_addr_iface);
 }
 
 /* Choose and returns the datapath ID for bridge 'br' given that the bridge
@@ -3496,9 +3504,10 @@ iface_from_ofp_port(const struct bridge *br, ofp_port_t ofp_port)
 /* Set Ethernet address of 'iface', if one is specified in the configuration
  * file. */
 static void
-iface_set_mac(struct iface *iface, const uint8_t *mac)
+iface_set_mac(const struct bridge *br, const struct port *port, struct iface *iface)
 {
-    uint8_t ea[ETH_ADDR_LEN];
+    uint8_t ea[ETH_ADDR_LEN], *mac = NULL;
+    struct iface *hw_addr_iface;
 
     if (strcmp(iface->type, "internal")) {
         return;
@@ -3506,6 +3515,10 @@ iface_set_mac(struct iface *iface, const uint8_t *mac)
 
     if (iface->cfg->mac && eth_addr_from_string(iface->cfg->mac, ea)) {
         mac = ea;
+    } else if (port->cfg->fake_bridge) {
+        /* Fake bridge and no MAC set in the configuration. Pick a local one. */
+        find_local_hw_addr(br, ea, port, &hw_addr_iface);
+        mac = ea;
     }
 
     if (mac) {
-- 
1.8.1.4




More information about the dev mailing list