Skip to content

Commit

Permalink
vswitchd: Limit fake bridge MAC selection to ports in the same VLAN
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Ben Pfaff <[email protected]>
  • Loading branch information
helmut-jacob authored and blp committed Feb 26, 2014
1 parent 4bc1cfd commit 21a955f
Showing 1 changed file with 22 additions and 7 deletions.
29 changes: 22 additions & 7 deletions vswitchd/bridge.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,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 *);
Expand Down Expand Up @@ -574,7 +574,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);
}
Expand Down Expand Up @@ -1548,8 +1548,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;
Expand Down Expand Up @@ -1612,6 +1612,16 @@ 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) {
Expand Down Expand Up @@ -1661,7 +1671,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
Expand Down Expand Up @@ -3477,16 +3487,21 @@ 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;
}

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) {
Expand Down

0 comments on commit 21a955f

Please sign in to comment.