diff options
| author | stephen hemminger <shemminger@vyatta.com> | 2011-03-24 09:24:01 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2011-03-28 02:35:02 -0400 |
| commit | edf947f10074fea27fdb1730524dca59355a1c40 (patch) | |
| tree | 4141cd2fa39ae589055057e912d3235150d670c5 /net/bridge | |
| parent | 8628bd8af7c4c14f40f5183f80f5744c4e682439 (diff) | |
bridge: notify applications if address of bridge device changes
The mac address of the bridge device may be changed when a new interface
is added to the bridge. If this happens, then the bridge needs to call
the network notifiers to tickle any other systems that care. Since bridge
can be a module, this also means exporting the notifier function.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge')
| -rw-r--r-- | net/bridge/br_if.c | 6 | ||||
| -rw-r--r-- | net/bridge/br_private.h | 2 | ||||
| -rw-r--r-- | net/bridge/br_stp_if.c | 9 |
3 files changed, 12 insertions, 5 deletions
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index dce8f0009a12..718b60366dfe 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c | |||
| @@ -389,6 +389,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) | |||
| 389 | { | 389 | { |
| 390 | struct net_bridge_port *p; | 390 | struct net_bridge_port *p; |
| 391 | int err = 0; | 391 | int err = 0; |
| 392 | bool changed_addr; | ||
| 392 | 393 | ||
| 393 | /* Don't allow bridging non-ethernet like devices */ | 394 | /* Don't allow bridging non-ethernet like devices */ |
| 394 | if ((dev->flags & IFF_LOOPBACK) || | 395 | if ((dev->flags & IFF_LOOPBACK) || |
| @@ -446,7 +447,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) | |||
| 446 | list_add_rcu(&p->list, &br->port_list); | 447 | list_add_rcu(&p->list, &br->port_list); |
| 447 | 448 | ||
| 448 | spin_lock_bh(&br->lock); | 449 | spin_lock_bh(&br->lock); |
| 449 | br_stp_recalculate_bridge_id(br); | 450 | changed_addr = br_stp_recalculate_bridge_id(br); |
| 450 | br_features_recompute(br); | 451 | br_features_recompute(br); |
| 451 | 452 | ||
| 452 | if ((dev->flags & IFF_UP) && netif_carrier_ok(dev) && | 453 | if ((dev->flags & IFF_UP) && netif_carrier_ok(dev) && |
| @@ -456,6 +457,9 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) | |||
| 456 | 457 | ||
| 457 | br_ifinfo_notify(RTM_NEWLINK, p); | 458 | br_ifinfo_notify(RTM_NEWLINK, p); |
| 458 | 459 | ||
| 460 | if (changed_addr) | ||
| 461 | call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); | ||
| 462 | |||
| 459 | dev_set_mtu(br->dev, br_min_mtu(br)); | 463 | dev_set_mtu(br->dev, br_min_mtu(br)); |
| 460 | 464 | ||
| 461 | kobject_uevent(&p->kobj, KOBJ_ADD); | 465 | kobject_uevent(&p->kobj, KOBJ_ADD); |
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 19e2f46ed086..387013d33745 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h | |||
| @@ -497,7 +497,7 @@ extern void br_stp_disable_bridge(struct net_bridge *br); | |||
| 497 | extern void br_stp_set_enabled(struct net_bridge *br, unsigned long val); | 497 | extern void br_stp_set_enabled(struct net_bridge *br, unsigned long val); |
| 498 | extern void br_stp_enable_port(struct net_bridge_port *p); | 498 | extern void br_stp_enable_port(struct net_bridge_port *p); |
| 499 | extern void br_stp_disable_port(struct net_bridge_port *p); | 499 | extern void br_stp_disable_port(struct net_bridge_port *p); |
| 500 | extern void br_stp_recalculate_bridge_id(struct net_bridge *br); | 500 | extern bool br_stp_recalculate_bridge_id(struct net_bridge *br); |
| 501 | extern void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *a); | 501 | extern void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *a); |
| 502 | extern void br_stp_set_bridge_priority(struct net_bridge *br, | 502 | extern void br_stp_set_bridge_priority(struct net_bridge *br, |
| 503 | u16 newprio); | 503 | u16 newprio); |
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c index 79372d4a4055..5593f5aec942 100644 --- a/net/bridge/br_stp_if.c +++ b/net/bridge/br_stp_if.c | |||
| @@ -204,7 +204,7 @@ void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *addr) | |||
| 204 | static const unsigned short br_mac_zero_aligned[ETH_ALEN >> 1]; | 204 | static const unsigned short br_mac_zero_aligned[ETH_ALEN >> 1]; |
| 205 | 205 | ||
| 206 | /* called under bridge lock */ | 206 | /* called under bridge lock */ |
| 207 | void br_stp_recalculate_bridge_id(struct net_bridge *br) | 207 | bool br_stp_recalculate_bridge_id(struct net_bridge *br) |
| 208 | { | 208 | { |
| 209 | const unsigned char *br_mac_zero = | 209 | const unsigned char *br_mac_zero = |
| 210 | (const unsigned char *)br_mac_zero_aligned; | 210 | (const unsigned char *)br_mac_zero_aligned; |
| @@ -222,8 +222,11 @@ void br_stp_recalculate_bridge_id(struct net_bridge *br) | |||
| 222 | 222 | ||
| 223 | } | 223 | } |
| 224 | 224 | ||
| 225 | if (compare_ether_addr(br->bridge_id.addr, addr)) | 225 | if (compare_ether_addr(br->bridge_id.addr, addr) == 0) |
| 226 | br_stp_change_bridge_id(br, addr); | 226 | return false; /* no change */ |
| 227 | |||
| 228 | br_stp_change_bridge_id(br, addr); | ||
| 229 | return true; | ||
| 227 | } | 230 | } |
| 228 | 231 | ||
| 229 | /* called under bridge lock */ | 232 | /* called under bridge lock */ |
