net/hsr: Move slave init to hsr_slave.c.
Also try to prevent some possible slave dereference race conditions. This is
finalized in the next patch, which abandons the slave array in favour of
a list_head list and list RCU.
Signed-off-by: Arvid Brodin <arvid.brodin@alten.se>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/net/hsr/hsr_main.c b/net/hsr/hsr_main.c
index 431b528..b5abe26 100644
--- a/net/hsr/hsr_main.c
+++ b/net/hsr/hsr_main.c
@@ -17,6 +17,7 @@
#include "hsr_device.h"
#include "hsr_netlink.h"
#include "hsr_framereg.h"
+#include "hsr_slave.h"
/* List of all registered virtual HSR devices */
@@ -124,22 +125,21 @@
if (dev == hsr->dev)
break;
- if (dev == hsr->slave[0])
- ether_addr_copy(hsr->dev->dev_addr,
- hsr->slave[0]->dev_addr);
+ if (dev == hsr->slave[0]) {
+ ether_addr_copy(hsr->dev->dev_addr, dev->dev_addr);
+ call_netdevice_notifiers(NETDEV_CHANGEADDR, hsr->dev);
+ }
/* Make sure we recognize frames from ourselves in hsr_rcv() */
+ other_slave = hsr->slave[1];
res = hsr_create_self_node(&hsr->self_node_db,
hsr->dev->dev_addr,
- hsr->slave[1] ?
- hsr->slave[1]->dev_addr :
+ other_slave ?
+ other_slave->dev_addr :
hsr->dev->dev_addr);
if (res)
netdev_warn(hsr->dev,
"Could not update HSR node address.\n");
-
- if (dev == hsr->slave[0])
- call_netdevice_notifiers(NETDEV_CHANGEADDR, hsr->dev);
break;
case NETDEV_CHANGEMTU:
if (dev == hsr->dev)
@@ -149,10 +149,14 @@
dev_set_mtu(hsr->dev, mtu_max);
break;
case NETDEV_UNREGISTER:
- if (dev == hsr->slave[0])
+ if (dev == hsr->slave[0]) {
hsr->slave[0] = NULL;
- if (dev == hsr->slave[1])
+ hsr_del_slave(hsr, 0);
+ }
+ if (dev == hsr->slave[1]) {
hsr->slave[1] = NULL;
+ hsr_del_slave(hsr, 1);
+ }
/* There should really be a way to set a new slave device... */