2
0
mirror of https://github.com/openvswitch/ovs synced 2025-10-17 14:28:02 +00:00

vswitchd: Limit fake bridge MAC selection to ports in the same VLAN

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@googlemail.com>
Signed-off-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
Helmut Schaa
2014-02-19 11:59:33 +01:00
committed by Ben Pfaff
parent 4bc1cfdead
commit 21a955fc29

View File

@@ -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 *);
@@ -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);
}
@@ -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;
@@ -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) {
@@ -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
@@ -3477,9 +3487,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;
@@ -3487,6 +3498,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) {