aboutsummaryrefslogtreecommitdiffstats
path: root/net/bridge/br_device.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/bridge/br_device.c')
-rw-r--r--net/bridge/br_device.c28
1 files changed, 26 insertions, 2 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}