diff options
Diffstat (limited to 'net/bridge')
-rw-r--r-- | net/bridge/br.c | 22 | ||||
-rw-r--r-- | net/bridge/br_device.c | 3 | ||||
-rw-r--r-- | net/bridge/br_if.c | 15 | ||||
-rw-r--r-- | net/bridge/br_ioctl.c | 20 | ||||
-rw-r--r-- | net/bridge/br_netlink.c | 15 | ||||
-rw-r--r-- | net/bridge/br_notify.c | 3 | ||||
-rw-r--r-- | net/bridge/br_private.h | 6 | ||||
-rw-r--r-- | net/bridge/br_stp_bpdu.c | 3 |
8 files changed, 44 insertions, 43 deletions
diff --git a/net/bridge/br.c b/net/bridge/br.c index 573acdf6f9ff..4d2c1f1cb524 100644 --- a/net/bridge/br.c +++ b/net/bridge/br.c | |||
@@ -28,6 +28,10 @@ static const struct stp_proto br_stp_proto = { | |||
28 | .rcv = br_stp_rcv, | 28 | .rcv = br_stp_rcv, |
29 | }; | 29 | }; |
30 | 30 | ||
31 | static struct pernet_operations br_net_ops = { | ||
32 | .exit = br_net_exit, | ||
33 | }; | ||
34 | |||
31 | static int __init br_init(void) | 35 | static int __init br_init(void) |
32 | { | 36 | { |
33 | int err; | 37 | int err; |
@@ -42,18 +46,22 @@ static int __init br_init(void) | |||
42 | if (err) | 46 | if (err) |
43 | goto err_out; | 47 | goto err_out; |
44 | 48 | ||
45 | err = br_netfilter_init(); | 49 | err = register_pernet_subsys(&br_net_ops); |
46 | if (err) | 50 | if (err) |
47 | goto err_out1; | 51 | goto err_out1; |
48 | 52 | ||
49 | err = register_netdevice_notifier(&br_device_notifier); | 53 | err = br_netfilter_init(); |
50 | if (err) | 54 | if (err) |
51 | goto err_out2; | 55 | goto err_out2; |
52 | 56 | ||
53 | err = br_netlink_init(); | 57 | err = register_netdevice_notifier(&br_device_notifier); |
54 | if (err) | 58 | if (err) |
55 | goto err_out3; | 59 | goto err_out3; |
56 | 60 | ||
61 | err = br_netlink_init(); | ||
62 | if (err) | ||
63 | goto err_out4; | ||
64 | |||
57 | brioctl_set(br_ioctl_deviceless_stub); | 65 | brioctl_set(br_ioctl_deviceless_stub); |
58 | br_handle_frame_hook = br_handle_frame; | 66 | br_handle_frame_hook = br_handle_frame; |
59 | 67 | ||
@@ -61,10 +69,12 @@ static int __init br_init(void) | |||
61 | br_fdb_put_hook = br_fdb_put; | 69 | br_fdb_put_hook = br_fdb_put; |
62 | 70 | ||
63 | return 0; | 71 | return 0; |
64 | err_out3: | 72 | err_out4: |
65 | unregister_netdevice_notifier(&br_device_notifier); | 73 | unregister_netdevice_notifier(&br_device_notifier); |
66 | err_out2: | 74 | err_out3: |
67 | br_netfilter_fini(); | 75 | br_netfilter_fini(); |
76 | err_out2: | ||
77 | unregister_pernet_subsys(&br_net_ops); | ||
68 | err_out1: | 78 | err_out1: |
69 | br_fdb_fini(); | 79 | br_fdb_fini(); |
70 | err_out: | 80 | err_out: |
@@ -80,7 +90,7 @@ static void __exit br_deinit(void) | |||
80 | unregister_netdevice_notifier(&br_device_notifier); | 90 | unregister_netdevice_notifier(&br_device_notifier); |
81 | brioctl_set(NULL); | 91 | brioctl_set(NULL); |
82 | 92 | ||
83 | br_cleanup_bridges(); | 93 | unregister_pernet_subsys(&br_net_ops); |
84 | 94 | ||
85 | synchronize_net(); | 95 | synchronize_net(); |
86 | 96 | ||
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index 4f52c3d50ebe..22ba8632196f 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c | |||
@@ -178,5 +178,6 @@ void br_dev_setup(struct net_device *dev) | |||
178 | dev->priv_flags = IFF_EBRIDGE; | 178 | dev->priv_flags = IFF_EBRIDGE; |
179 | 179 | ||
180 | dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | | 180 | dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_HIGHDMA | |
181 | NETIF_F_GSO_MASK | NETIF_F_NO_CSUM | NETIF_F_LLTX; | 181 | NETIF_F_GSO_MASK | NETIF_F_NO_CSUM | NETIF_F_LLTX | |
182 | NETIF_F_NETNS_LOCAL; | ||
182 | } | 183 | } |
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index 63c18aacde8c..573e20f7dba4 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c | |||
@@ -168,7 +168,7 @@ static void del_br(struct net_bridge *br) | |||
168 | unregister_netdevice(br->dev); | 168 | unregister_netdevice(br->dev); |
169 | } | 169 | } |
170 | 170 | ||
171 | static struct net_device *new_bridge_dev(const char *name) | 171 | static struct net_device *new_bridge_dev(struct net *net, const char *name) |
172 | { | 172 | { |
173 | struct net_bridge *br; | 173 | struct net_bridge *br; |
174 | struct net_device *dev; | 174 | struct net_device *dev; |
@@ -178,6 +178,7 @@ static struct net_device *new_bridge_dev(const char *name) | |||
178 | 178 | ||
179 | if (!dev) | 179 | if (!dev) |
180 | return NULL; | 180 | return NULL; |
181 | dev_net_set(dev, net); | ||
181 | 182 | ||
182 | br = netdev_priv(dev); | 183 | br = netdev_priv(dev); |
183 | br->dev = dev; | 184 | br->dev = dev; |
@@ -262,12 +263,12 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br, | |||
262 | return p; | 263 | return p; |
263 | } | 264 | } |
264 | 265 | ||
265 | int br_add_bridge(const char *name) | 266 | int br_add_bridge(struct net *net, const char *name) |
266 | { | 267 | { |
267 | struct net_device *dev; | 268 | struct net_device *dev; |
268 | int ret; | 269 | int ret; |
269 | 270 | ||
270 | dev = new_bridge_dev(name); | 271 | dev = new_bridge_dev(net, name); |
271 | if (!dev) | 272 | if (!dev) |
272 | return -ENOMEM; | 273 | return -ENOMEM; |
273 | 274 | ||
@@ -294,13 +295,13 @@ out_free: | |||
294 | goto out; | 295 | goto out; |
295 | } | 296 | } |
296 | 297 | ||
297 | int br_del_bridge(const char *name) | 298 | int br_del_bridge(struct net *net, const char *name) |
298 | { | 299 | { |
299 | struct net_device *dev; | 300 | struct net_device *dev; |
300 | int ret = 0; | 301 | int ret = 0; |
301 | 302 | ||
302 | rtnl_lock(); | 303 | rtnl_lock(); |
303 | dev = __dev_get_by_name(&init_net, name); | 304 | dev = __dev_get_by_name(net, name); |
304 | if (dev == NULL) | 305 | if (dev == NULL) |
305 | ret = -ENXIO; /* Could not find device */ | 306 | ret = -ENXIO; /* Could not find device */ |
306 | 307 | ||
@@ -445,13 +446,13 @@ int br_del_if(struct net_bridge *br, struct net_device *dev) | |||
445 | return 0; | 446 | return 0; |
446 | } | 447 | } |
447 | 448 | ||
448 | void __exit br_cleanup_bridges(void) | 449 | void br_net_exit(struct net *net) |
449 | { | 450 | { |
450 | struct net_device *dev; | 451 | struct net_device *dev; |
451 | 452 | ||
452 | rtnl_lock(); | 453 | rtnl_lock(); |
453 | restart: | 454 | restart: |
454 | for_each_netdev(&init_net, dev) { | 455 | for_each_netdev(net, dev) { |
455 | if (dev->priv_flags & IFF_EBRIDGE) { | 456 | if (dev->priv_flags & IFF_EBRIDGE) { |
456 | del_br(dev->priv); | 457 | del_br(dev->priv); |
457 | goto restart; | 458 | goto restart; |
diff --git a/net/bridge/br_ioctl.c b/net/bridge/br_ioctl.c index 5bbf07362172..6a6433daaf27 100644 --- a/net/bridge/br_ioctl.c +++ b/net/bridge/br_ioctl.c | |||
@@ -21,12 +21,12 @@ | |||
21 | #include "br_private.h" | 21 | #include "br_private.h" |
22 | 22 | ||
23 | /* called with RTNL */ | 23 | /* called with RTNL */ |
24 | static int get_bridge_ifindices(int *indices, int num) | 24 | static int get_bridge_ifindices(struct net *net, int *indices, int num) |
25 | { | 25 | { |
26 | struct net_device *dev; | 26 | struct net_device *dev; |
27 | int i = 0; | 27 | int i = 0; |
28 | 28 | ||
29 | for_each_netdev(&init_net, dev) { | 29 | for_each_netdev(net, dev) { |
30 | if (i >= num) | 30 | if (i >= num) |
31 | break; | 31 | break; |
32 | if (dev->priv_flags & IFF_EBRIDGE) | 32 | if (dev->priv_flags & IFF_EBRIDGE) |
@@ -89,7 +89,7 @@ static int add_del_if(struct net_bridge *br, int ifindex, int isadd) | |||
89 | if (!capable(CAP_NET_ADMIN)) | 89 | if (!capable(CAP_NET_ADMIN)) |
90 | return -EPERM; | 90 | return -EPERM; |
91 | 91 | ||
92 | dev = dev_get_by_index(&init_net, ifindex); | 92 | dev = dev_get_by_index(dev_net(br->dev), ifindex); |
93 | if (dev == NULL) | 93 | if (dev == NULL) |
94 | return -EINVAL; | 94 | return -EINVAL; |
95 | 95 | ||
@@ -315,7 +315,7 @@ static int old_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) | |||
315 | return -EOPNOTSUPP; | 315 | return -EOPNOTSUPP; |
316 | } | 316 | } |
317 | 317 | ||
318 | static int old_deviceless(void __user *uarg) | 318 | static int old_deviceless(struct net *net, void __user *uarg) |
319 | { | 319 | { |
320 | unsigned long args[3]; | 320 | unsigned long args[3]; |
321 | 321 | ||
@@ -337,7 +337,7 @@ static int old_deviceless(void __user *uarg) | |||
337 | if (indices == NULL) | 337 | if (indices == NULL) |
338 | return -ENOMEM; | 338 | return -ENOMEM; |
339 | 339 | ||
340 | args[2] = get_bridge_ifindices(indices, args[2]); | 340 | args[2] = get_bridge_ifindices(net, indices, args[2]); |
341 | 341 | ||
342 | ret = copy_to_user((void __user *)args[1], indices, args[2]*sizeof(int)) | 342 | ret = copy_to_user((void __user *)args[1], indices, args[2]*sizeof(int)) |
343 | ? -EFAULT : args[2]; | 343 | ? -EFAULT : args[2]; |
@@ -360,9 +360,9 @@ static int old_deviceless(void __user *uarg) | |||
360 | buf[IFNAMSIZ-1] = 0; | 360 | buf[IFNAMSIZ-1] = 0; |
361 | 361 | ||
362 | if (args[0] == BRCTL_ADD_BRIDGE) | 362 | if (args[0] == BRCTL_ADD_BRIDGE) |
363 | return br_add_bridge(buf); | 363 | return br_add_bridge(net, buf); |
364 | 364 | ||
365 | return br_del_bridge(buf); | 365 | return br_del_bridge(net, buf); |
366 | } | 366 | } |
367 | } | 367 | } |
368 | 368 | ||
@@ -374,7 +374,7 @@ int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, void __user *uar | |||
374 | switch (cmd) { | 374 | switch (cmd) { |
375 | case SIOCGIFBR: | 375 | case SIOCGIFBR: |
376 | case SIOCSIFBR: | 376 | case SIOCSIFBR: |
377 | return old_deviceless(uarg); | 377 | return old_deviceless(net, uarg); |
378 | 378 | ||
379 | case SIOCBRADDBR: | 379 | case SIOCBRADDBR: |
380 | case SIOCBRDELBR: | 380 | case SIOCBRDELBR: |
@@ -389,9 +389,9 @@ int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, void __user *uar | |||
389 | 389 | ||
390 | buf[IFNAMSIZ-1] = 0; | 390 | buf[IFNAMSIZ-1] = 0; |
391 | if (cmd == SIOCBRADDBR) | 391 | if (cmd == SIOCBRADDBR) |
392 | return br_add_bridge(buf); | 392 | return br_add_bridge(net, buf); |
393 | 393 | ||
394 | return br_del_bridge(buf); | 394 | return br_del_bridge(net, buf); |
395 | } | 395 | } |
396 | } | 396 | } |
397 | return -EOPNOTSUPP; | 397 | return -EOPNOTSUPP; |
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index f155e6ce8a21..ba7be195803c 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c | |||
@@ -82,6 +82,7 @@ nla_put_failure: | |||
82 | */ | 82 | */ |
83 | void br_ifinfo_notify(int event, struct net_bridge_port *port) | 83 | void br_ifinfo_notify(int event, struct net_bridge_port *port) |
84 | { | 84 | { |
85 | struct net *net = dev_net(port->dev); | ||
85 | struct sk_buff *skb; | 86 | struct sk_buff *skb; |
86 | int err = -ENOBUFS; | 87 | int err = -ENOBUFS; |
87 | 88 | ||
@@ -97,10 +98,10 @@ void br_ifinfo_notify(int event, struct net_bridge_port *port) | |||
97 | kfree_skb(skb); | 98 | kfree_skb(skb); |
98 | goto errout; | 99 | goto errout; |
99 | } | 100 | } |
100 | err = rtnl_notify(skb, &init_net,0, RTNLGRP_LINK, NULL, GFP_ATOMIC); | 101 | err = rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC); |
101 | errout: | 102 | errout: |
102 | if (err < 0) | 103 | if (err < 0) |
103 | rtnl_set_sk_err(&init_net, RTNLGRP_LINK, err); | 104 | rtnl_set_sk_err(net, RTNLGRP_LINK, err); |
104 | } | 105 | } |
105 | 106 | ||
106 | /* | 107 | /* |
@@ -112,11 +113,8 @@ static int br_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) | |||
112 | struct net_device *dev; | 113 | struct net_device *dev; |
113 | int idx; | 114 | int idx; |
114 | 115 | ||
115 | if (net != &init_net) | ||
116 | return 0; | ||
117 | |||
118 | idx = 0; | 116 | idx = 0; |
119 | for_each_netdev(&init_net, dev) { | 117 | for_each_netdev(net, dev) { |
120 | /* not a bridge port */ | 118 | /* not a bridge port */ |
121 | if (dev->br_port == NULL || idx < cb->args[0]) | 119 | if (dev->br_port == NULL || idx < cb->args[0]) |
122 | goto skip; | 120 | goto skip; |
@@ -147,9 +145,6 @@ static int br_rtm_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
147 | struct net_bridge_port *p; | 145 | struct net_bridge_port *p; |
148 | u8 new_state; | 146 | u8 new_state; |
149 | 147 | ||
150 | if (net != &init_net) | ||
151 | return -EINVAL; | ||
152 | |||
153 | if (nlmsg_len(nlh) < sizeof(*ifm)) | 148 | if (nlmsg_len(nlh) < sizeof(*ifm)) |
154 | return -EINVAL; | 149 | return -EINVAL; |
155 | 150 | ||
@@ -165,7 +160,7 @@ static int br_rtm_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
165 | if (new_state > BR_STATE_BLOCKING) | 160 | if (new_state > BR_STATE_BLOCKING) |
166 | return -EINVAL; | 161 | return -EINVAL; |
167 | 162 | ||
168 | dev = __dev_get_by_index(&init_net, ifm->ifi_index); | 163 | dev = __dev_get_by_index(net, ifm->ifi_index); |
169 | if (!dev) | 164 | if (!dev) |
170 | return -ENODEV; | 165 | return -ENODEV; |
171 | 166 | ||
diff --git a/net/bridge/br_notify.c b/net/bridge/br_notify.c index 76340bdd052e..763a3ec292e5 100644 --- a/net/bridge/br_notify.c +++ b/net/bridge/br_notify.c | |||
@@ -35,9 +35,6 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v | |||
35 | struct net_bridge_port *p = dev->br_port; | 35 | struct net_bridge_port *p = dev->br_port; |
36 | struct net_bridge *br; | 36 | struct net_bridge *br; |
37 | 37 | ||
38 | if (!net_eq(dev_net(dev), &init_net)) | ||
39 | return NOTIFY_DONE; | ||
40 | |||
41 | /* not a port of a bridge */ | 38 | /* not a port of a bridge */ |
42 | if (p == NULL) | 39 | if (p == NULL) |
43 | return NOTIFY_DONE; | 40 | return NOTIFY_DONE; |
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index c3dc18ddc043..b6c3b71974dc 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h | |||
@@ -178,9 +178,9 @@ extern void br_flood_forward(struct net_bridge *br, struct sk_buff *skb); | |||
178 | 178 | ||
179 | /* br_if.c */ | 179 | /* br_if.c */ |
180 | extern void br_port_carrier_check(struct net_bridge_port *p); | 180 | extern void br_port_carrier_check(struct net_bridge_port *p); |
181 | extern int br_add_bridge(const char *name); | 181 | extern int br_add_bridge(struct net *net, const char *name); |
182 | extern int br_del_bridge(const char *name); | 182 | extern int br_del_bridge(struct net *net, const char *name); |
183 | extern void br_cleanup_bridges(void); | 183 | extern void br_net_exit(struct net *net); |
184 | extern int br_add_if(struct net_bridge *br, | 184 | extern int br_add_if(struct net_bridge *br, |
185 | struct net_device *dev); | 185 | struct net_device *dev); |
186 | extern int br_del_if(struct net_bridge *br, | 186 | extern int br_del_if(struct net_bridge *br, |
diff --git a/net/bridge/br_stp_bpdu.c b/net/bridge/br_stp_bpdu.c index 8b200f96f722..81ae40b3f655 100644 --- a/net/bridge/br_stp_bpdu.c +++ b/net/bridge/br_stp_bpdu.c | |||
@@ -140,9 +140,6 @@ void br_stp_rcv(const struct stp_proto *proto, struct sk_buff *skb, | |||
140 | struct net_bridge *br; | 140 | struct net_bridge *br; |
141 | const unsigned char *buf; | 141 | const unsigned char *buf; |
142 | 142 | ||
143 | if (!net_eq(dev_net(dev), &init_net)) | ||
144 | goto err; | ||
145 | |||
146 | if (!p) | 143 | if (!p) |
147 | goto err; | 144 | goto err; |
148 | 145 | ||