diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2009-12-12 17:11:15 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-12-13 22:45:22 -0500 |
commit | d90a909e1f3e006a1d57fe11fd417173b6494701 (patch) | |
tree | 72893da9ed5083b44dbb8d778d648e114d351a0a /net | |
parent | 5781b2356cbecb0b73b06ec8c3897cabdfdd0928 (diff) |
net: Fix userspace RTM_NEWLINK notifications.
I received some bug reports about userspace programs having problems
because after RTM_NEWLINK was received they could not immediate access
files under /proc/sys/net/ because they had not been registered yet.
The original problem was trivially fixed by moving the userspace
notification from rtnetlink_event() to the end of
register_netdevice().
When testing that change I discovered I was still getting RTM_NEWLINK
events before I could access proc and I was also getting RTM_NEWLINK
events after I was seeing RTM_DELLINK. Things practically guaranteed
to confuse userspace.
After a little more investigation these extra notifications proved to
be from the new notifiers NETDEV_POST_INIT and NETDEV_UNREGISTER_BATCH
hitting the default case in rtnetlink_event, and triggering
unnecessary RTM_NEWLINK messages.
rtnetlink_event now explicitly handles NETDEV_UNREGISTER_BATCH and
NETDEV_POST_INIT to avoid sending the incorrect userspace
notifications.
Signed-off-by: Eric W. Biederman <ebiederm@aristanetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/core/dev.c | 11 | ||||
-rw-r--r-- | net/core/rtnetlink.c | 6 |
2 files changed, 14 insertions, 3 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 6fe7d739e59b..be9924f60ec3 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -5035,6 +5035,11 @@ int register_netdevice(struct net_device *dev) | |||
5035 | rollback_registered(dev); | 5035 | rollback_registered(dev); |
5036 | dev->reg_state = NETREG_UNREGISTERED; | 5036 | dev->reg_state = NETREG_UNREGISTERED; |
5037 | } | 5037 | } |
5038 | /* | ||
5039 | * Prevent userspace races by waiting until the network | ||
5040 | * device is fully setup before sending notifications. | ||
5041 | */ | ||
5042 | rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U); | ||
5038 | 5043 | ||
5039 | out: | 5044 | out: |
5040 | return ret; | 5045 | return ret; |
@@ -5597,6 +5602,12 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char | |||
5597 | /* Notify protocols, that a new device appeared. */ | 5602 | /* Notify protocols, that a new device appeared. */ |
5598 | call_netdevice_notifiers(NETDEV_REGISTER, dev); | 5603 | call_netdevice_notifiers(NETDEV_REGISTER, dev); |
5599 | 5604 | ||
5605 | /* | ||
5606 | * Prevent userspace races by waiting until the network | ||
5607 | * device is fully setup before sending notifications. | ||
5608 | */ | ||
5609 | rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U); | ||
5610 | |||
5600 | synchronize_net(); | 5611 | synchronize_net(); |
5601 | err = 0; | 5612 | err = 0; |
5602 | out: | 5613 | out: |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 33148a568199..794bcb897ff0 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -1364,15 +1364,15 @@ static int rtnetlink_event(struct notifier_block *this, unsigned long event, voi | |||
1364 | case NETDEV_UNREGISTER: | 1364 | case NETDEV_UNREGISTER: |
1365 | rtmsg_ifinfo(RTM_DELLINK, dev, ~0U); | 1365 | rtmsg_ifinfo(RTM_DELLINK, dev, ~0U); |
1366 | break; | 1366 | break; |
1367 | case NETDEV_REGISTER: | ||
1368 | rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U); | ||
1369 | break; | ||
1370 | case NETDEV_UP: | 1367 | case NETDEV_UP: |
1371 | case NETDEV_DOWN: | 1368 | case NETDEV_DOWN: |
1372 | rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING); | 1369 | rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING); |
1373 | break; | 1370 | break; |
1371 | case NETDEV_POST_INIT: | ||
1372 | case NETDEV_REGISTER: | ||
1374 | case NETDEV_CHANGE: | 1373 | case NETDEV_CHANGE: |
1375 | case NETDEV_GOING_DOWN: | 1374 | case NETDEV_GOING_DOWN: |
1375 | case NETDEV_UNREGISTER_BATCH: | ||
1376 | break; | 1376 | break; |
1377 | default: | 1377 | default: |
1378 | rtmsg_ifinfo(RTM_NEWLINK, dev, 0); | 1378 | rtmsg_ifinfo(RTM_NEWLINK, dev, 0); |