aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/netdevice.h7
-rw-r--r--net/core/dev.c8
-rw-r--r--net/core/rtnetlink.c4
3 files changed, 14 insertions, 5 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 7a2aea56f195..1bfda90c2625 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -924,7 +924,12 @@ struct net_device {
924 NETREG_UNREGISTERED, /* completed unregister todo */ 924 NETREG_UNREGISTERED, /* completed unregister todo */
925 NETREG_RELEASED, /* called free_netdev */ 925 NETREG_RELEASED, /* called free_netdev */
926 NETREG_DUMMY, /* dummy device for NAPI poll */ 926 NETREG_DUMMY, /* dummy device for NAPI poll */
927 } reg_state; 927 } reg_state:16;
928
929 enum {
930 RTNL_LINK_INITIALIZED,
931 RTNL_LINK_INITIALIZING,
932 } rtnl_link_state:16;
928 933
929 /* Called from unregister, can be used to call free_netdev */ 934 /* Called from unregister, can be used to call free_netdev */
930 void (*destructor)(struct net_device *dev); 935 void (*destructor)(struct net_device *dev);
diff --git a/net/core/dev.c b/net/core/dev.c
index eb7f1a4fefc6..75332b089529 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4865,6 +4865,10 @@ static void rollback_registered_many(struct list_head *head)
4865 */ 4865 */
4866 call_netdevice_notifiers(NETDEV_UNREGISTER, dev); 4866 call_netdevice_notifiers(NETDEV_UNREGISTER, dev);
4867 4867
4868 if (!dev->rtnl_link_ops ||
4869 dev->rtnl_link_state == RTNL_LINK_INITIALIZED)
4870 rtmsg_ifinfo(RTM_DELLINK, dev, ~0U);
4871
4868 /* 4872 /*
4869 * Flush the unicast and multicast chains 4873 * Flush the unicast and multicast chains
4870 */ 4874 */
@@ -5091,7 +5095,9 @@ int register_netdevice(struct net_device *dev)
5091 * Prevent userspace races by waiting until the network 5095 * Prevent userspace races by waiting until the network
5092 * device is fully setup before sending notifications. 5096 * device is fully setup before sending notifications.
5093 */ 5097 */
5094 rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U); 5098 if (!dev->rtnl_link_ops ||
5099 dev->rtnl_link_state == RTNL_LINK_INITIALIZED)
5100 rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U);
5095 5101
5096out: 5102out:
5097 return ret; 5103 return ret;
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index b7c7dfd86507..020e43bfef5f 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1425,9 +1425,6 @@ static int rtnetlink_event(struct notifier_block *this, unsigned long event, voi
1425 struct net_device *dev = ptr; 1425 struct net_device *dev = ptr;
1426 1426
1427 switch (event) { 1427 switch (event) {
1428 case NETDEV_UNREGISTER:
1429 rtmsg_ifinfo(RTM_DELLINK, dev, ~0U);
1430 break;
1431 case NETDEV_UP: 1428 case NETDEV_UP:
1432 case NETDEV_DOWN: 1429 case NETDEV_DOWN:
1433 rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING); 1430 rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING);
@@ -1437,6 +1434,7 @@ static int rtnetlink_event(struct notifier_block *this, unsigned long event, voi
1437 case NETDEV_REGISTER: 1434 case NETDEV_REGISTER:
1438 case NETDEV_CHANGE: 1435 case NETDEV_CHANGE:
1439 case NETDEV_GOING_DOWN: 1436 case NETDEV_GOING_DOWN:
1437 case NETDEV_UNREGISTER:
1440 case NETDEV_UNREGISTER_BATCH: 1438 case NETDEV_UNREGISTER_BATCH:
1441 break; 1439 break;
1442 default: 1440 default: