diff options
-rw-r--r-- | include/linux/netdevice.h | 7 | ||||
-rw-r--r-- | net/core/dev.c | 8 | ||||
-rw-r--r-- | net/core/rtnetlink.c | 4 |
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 | ||
5096 | out: | 5102 | out: |
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: |