aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2007-09-12 07:02:17 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-10 19:49:09 -0400
commite9dc86534051b78e41e5b746cccc291b57a3a311 (patch)
tree1cd4a1dde4c51b6311749428a22cc8a8f5436825 /net/ipv4
parente730c15519d09ea528b4d2f1103681fa5937c0e6 (diff)
[NET]: Make device event notification network namespace safe
Every user of the network device notifiers is either a protocol stack or a pseudo device. If a protocol stack that does not have support for multiple network namespaces receives an event for a device that is not in the initial network namespace it quite possibly can get confused and do the wrong thing. To avoid problems until all of the protocol stacks are converted this patch modifies all netdev event handlers to ignore events on devices that are not in the initial network namespace. As the rest of the code is made network namespace aware these checks can be removed. Signed-off-by: Eric W. Biederman <ebiederm@xmission.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/arp.c3
-rw-r--r--net/ipv4/devinet.c3
-rw-r--r--net/ipv4/fib_frontend.c3
-rw-r--r--net/ipv4/ipmr.c7
-rw-r--r--net/ipv4/netfilter/ip_queue.c3
-rw-r--r--net/ipv4/netfilter/ipt_MASQUERADE.c3
6 files changed, 21 insertions, 1 deletions
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index bde129708e22..a11e7a5c1da4 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -1205,6 +1205,9 @@ static int arp_netdev_event(struct notifier_block *this, unsigned long event, vo
1205{ 1205{
1206 struct net_device *dev = ptr; 1206 struct net_device *dev = ptr;
1207 1207
1208 if (dev->nd_net != &init_net)
1209 return NOTIFY_DONE;
1210
1208 switch (event) { 1211 switch (event) {
1209 case NETDEV_CHANGEADDR: 1212 case NETDEV_CHANGEADDR:
1210 neigh_changeaddr(&arp_tbl, dev); 1213 neigh_changeaddr(&arp_tbl, dev);
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 5dbe5803b7d5..c5eb1a29a5cf 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -1051,6 +1051,9 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
1051 struct net_device *dev = ptr; 1051 struct net_device *dev = ptr;
1052 struct in_device *in_dev = __in_dev_get_rtnl(dev); 1052 struct in_device *in_dev = __in_dev_get_rtnl(dev);
1053 1053
1054 if (dev->nd_net != &init_net)
1055 return NOTIFY_DONE;
1056
1054 ASSERT_RTNL(); 1057 ASSERT_RTNL();
1055 1058
1056 if (!in_dev) { 1059 if (!in_dev) {
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index eff6bce453ee..cefb55ec3d62 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -860,6 +860,9 @@ static int fib_netdev_event(struct notifier_block *this, unsigned long event, vo
860 struct net_device *dev = ptr; 860 struct net_device *dev = ptr;
861 struct in_device *in_dev = __in_dev_get_rtnl(dev); 861 struct in_device *in_dev = __in_dev_get_rtnl(dev);
862 862
863 if (dev->nd_net != &init_net)
864 return NOTIFY_DONE;
865
863 if (event == NETDEV_UNREGISTER) { 866 if (event == NETDEV_UNREGISTER) {
864 fib_disable_ip(dev, 2); 867 fib_disable_ip(dev, 2);
865 return NOTIFY_DONE; 868 return NOTIFY_DONE;
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 35683e1a42e8..036598835c63 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -1083,13 +1083,18 @@ int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg)
1083 1083
1084static int ipmr_device_event(struct notifier_block *this, unsigned long event, void *ptr) 1084static int ipmr_device_event(struct notifier_block *this, unsigned long event, void *ptr)
1085{ 1085{
1086 struct net_device *dev = ptr;
1086 struct vif_device *v; 1087 struct vif_device *v;
1087 int ct; 1088 int ct;
1089
1090 if (dev->nd_net != &init_net)
1091 return NOTIFY_DONE;
1092
1088 if (event != NETDEV_UNREGISTER) 1093 if (event != NETDEV_UNREGISTER)
1089 return NOTIFY_DONE; 1094 return NOTIFY_DONE;
1090 v=&vif_table[0]; 1095 v=&vif_table[0];
1091 for (ct=0;ct<maxvif;ct++,v++) { 1096 for (ct=0;ct<maxvif;ct++,v++) {
1092 if (v->dev==ptr) 1097 if (v->dev==dev)
1093 vif_delete(ct); 1098 vif_delete(ct);
1094 } 1099 }
1095 return NOTIFY_DONE; 1100 return NOTIFY_DONE;
diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
index cb5e61a1d7ab..d91856097f25 100644
--- a/net/ipv4/netfilter/ip_queue.c
+++ b/net/ipv4/netfilter/ip_queue.c
@@ -557,6 +557,9 @@ ipq_rcv_dev_event(struct notifier_block *this,
557{ 557{
558 struct net_device *dev = ptr; 558 struct net_device *dev = ptr;
559 559
560 if (dev->nd_net != &init_net)
561 return NOTIFY_DONE;
562
560 /* Drop any packets associated with the downed device */ 563 /* Drop any packets associated with the downed device */
561 if (event == NETDEV_DOWN) 564 if (event == NETDEV_DOWN)
562 ipq_dev_drop(dev->ifindex); 565 ipq_dev_drop(dev->ifindex);
diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c
index 7c4e4be7c8b3..3e0b562b2db7 100644
--- a/net/ipv4/netfilter/ipt_MASQUERADE.c
+++ b/net/ipv4/netfilter/ipt_MASQUERADE.c
@@ -125,6 +125,9 @@ static int masq_device_event(struct notifier_block *this,
125{ 125{
126 const struct net_device *dev = ptr; 126 const struct net_device *dev = ptr;
127 127
128 if (dev->nd_net != &init_net)
129 return NOTIFY_DONE;
130
128 if (event == NETDEV_DOWN) { 131 if (event == NETDEV_DOWN) {
129 /* Device was downed. Search entire table for 132 /* Device was downed. Search entire table for
130 conntracks which were associated with that device, 133 conntracks which were associated with that device,