/* Allow setting mac address to any valid ethernet address. */ static int br_set_mac_address(struct net_device *dev, void *p) { struct net_bridge *br = netdev_priv(dev); struct sockaddr *addr = p; if (!is_valid_ether_addr(addr->sa_data)) return -EINVAL; spin_lock_bh(&br->lock); memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); br_stp_change_bridge_id(br, addr->sa_data); br->flags |= BR_SET_MAC_ADDR; spin_unlock_bh(&br->lock); return 0; }
/* called under bridge lock */ void br_stp_recalculate_bridge_id(struct net_bridge *br) { unsigned char *addr; struct net_bridge_port *p; addr = br_mac_zero; p = br->port_list; while (p != NULL) { if (addr == br_mac_zero || memcmp(p->dev->dev_addr, addr, ETH_ALEN) < 0) addr = p->dev->dev_addr; p = p->next; } if (memcmp(br->bridge_id.addr, addr, ETH_ALEN)) br_stp_change_bridge_id(br, addr); }