aboutsummaryrefslogtreecommitdiffstats
path: root/net/bridge
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@osdl.org>2005-12-21 21:51:49 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-01-03 16:11:00 -0500
commit4505a3ef720845b5db3ddb440de13cd4800fd508 (patch)
tree2de3d2fb20d160dc1a04bdb0295882561e4244bc /net/bridge
parentfbe9cc4a87030d5cad5f944ffaef6af7efd119e4 (diff)
[BRIDGE]: allow setting hardware address of bridge pseudo-dev
Some people are using bridging to hide multiple machines from an ISP that restricts by MAC address. So in that case allow the bridge mac address to be set to any of the existing interfaces. I don't want to allow any arbitrary value and confuse STP. Signed-off-by: Stephen Hemminger <shemminger@osdl.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge')
-rw-r--r--net/bridge/br_device.c28
-rw-r--r--net/bridge/br_private.h1
-rw-r--r--net/bridge/br_stp_if.c3
3 files changed, 28 insertions, 4 deletions
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c
index f564ee99782d..f7a66abf5def 100644
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -15,7 +15,8 @@
15 15
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/netdevice.h> 17#include <linux/netdevice.h>
18#include <linux/module.h> 18#include <linux/etherdevice.h>
19
19#include <asm/uaccess.h> 20#include <asm/uaccess.h>
20#include "br_private.h" 21#include "br_private.h"
21 22
@@ -82,6 +83,29 @@ static int br_change_mtu(struct net_device *dev, int new_mtu)
82 return 0; 83 return 0;
83} 84}
84 85
86/* Allow setting mac address of pseudo-bridge to be same as
87 * any of the bound interfaces
88 */
89static int br_set_mac_address(struct net_device *dev, void *p)
90{
91 struct net_bridge *br = netdev_priv(dev);
92 struct sockaddr *addr = p;
93 struct net_bridge_port *port;
94 int err = -EADDRNOTAVAIL;
95
96 spin_lock_bh(&br->lock);
97 list_for_each_entry(port, &br->port_list, list) {
98 if (!compare_ether_addr(port->dev->dev_addr, addr->sa_data)) {
99 br_stp_change_bridge_id(br, addr->sa_data);
100 err = 0;
101 break;
102 }
103 }
104 spin_unlock_bh(&br->lock);
105
106 return err;
107}
108
85void br_dev_setup(struct net_device *dev) 109void br_dev_setup(struct net_device *dev)
86{ 110{
87 memset(dev->dev_addr, 0, ETH_ALEN); 111 memset(dev->dev_addr, 0, ETH_ALEN);
@@ -98,6 +122,6 @@ void br_dev_setup(struct net_device *dev)
98 SET_MODULE_OWNER(dev); 122 SET_MODULE_OWNER(dev);
99 dev->stop = br_dev_stop; 123 dev->stop = br_dev_stop;
100 dev->tx_queue_len = 0; 124 dev->tx_queue_len = 0;
101 dev->set_mac_address = NULL; 125 dev->set_mac_address = br_set_mac_address;
102 dev->priv_flags = IFF_EBRIDGE; 126 dev->priv_flags = IFF_EBRIDGE;
103} 127}
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index bdf95a74d8cd..2c249486476f 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -201,6 +201,7 @@ extern void br_stp_disable_bridge(struct net_bridge *br);
201extern void br_stp_enable_port(struct net_bridge_port *p); 201extern void br_stp_enable_port(struct net_bridge_port *p);
202extern void br_stp_disable_port(struct net_bridge_port *p); 202extern void br_stp_disable_port(struct net_bridge_port *p);
203extern void br_stp_recalculate_bridge_id(struct net_bridge *br); 203extern void br_stp_recalculate_bridge_id(struct net_bridge *br);
204extern void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *a);
204extern void br_stp_set_bridge_priority(struct net_bridge *br, 205extern void br_stp_set_bridge_priority(struct net_bridge *br,
205 u16 newprio); 206 u16 newprio);
206extern void br_stp_set_port_priority(struct net_bridge_port *p, 207extern void br_stp_set_port_priority(struct net_bridge_port *p,
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c
index ac09b6a23523..2d2e969ae25d 100644
--- a/net/bridge/br_stp_if.c
+++ b/net/bridge/br_stp_if.c
@@ -120,8 +120,7 @@ void br_stp_disable_port(struct net_bridge_port *p)
120} 120}
121 121
122/* called under bridge lock */ 122/* called under bridge lock */
123static void br_stp_change_bridge_id(struct net_bridge *br, 123void br_stp_change_bridge_id(struct net_bridge *br, const unsigned char *addr)
124 const unsigned char *addr)
125{ 124{
126 unsigned char oldaddr[6]; 125 unsigned char oldaddr[6];
127 struct net_bridge_port *p; 126 struct net_bridge_port *p;