Skip to content

Commit 6fda735

Browse files
btherydavem330
authored andcommitted
[NETNS][IPV6] addrconf - make addrconf per namespace
All the infrastructure to propagate the network namespace information is ready. Make use of it. There is a special case here between the initial network namespace and the other namespaces: * When ipv6 is initialized at boot time (aka in the init_net), it registers to the notifier callback. So addrconf_notify will be called as many time as there are network devices setup on the system and the function will add ipv6 addresses to the network devices. But the first device which needs to have its ipv6 address setup is the loopback, unfortunatly this is not the case. So the loopback address is setup manually in the ipv6 init function. * With the network namespace, this ordering problem does not appears because notifier is already setup and active, so as soon as we register the loopback the ipv6 address is setup and it will be the first device. Signed-off-by: Benjamin Thery <benjamin.thery@bull.net> Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent af28493 commit 6fda735

File tree

1 file changed

+50
-63
lines changed

1 file changed

+50
-63
lines changed

net/ipv6/addrconf.c

Lines changed: 50 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -561,7 +561,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen,
561561
write_lock(&addrconf_hash_lock);
562562

563563
/* Ignore adding duplicate addresses on an interface */
564-
if (ipv6_chk_same_addr(&init_net, addr, idev->dev)) {
564+
if (ipv6_chk_same_addr(idev->dev->nd_net, addr, idev->dev)) {
565565
ADBG(("ipv6_add_addr: already assigned\n"));
566566
err = -EEXIST;
567567
goto out;
@@ -751,9 +751,9 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp)
751751
if ((ifp->flags & IFA_F_PERMANENT) && onlink < 1) {
752752
struct in6_addr prefix;
753753
struct rt6_info *rt;
754-
754+
struct net *net = ifp->idev->dev->nd_net;
755755
ipv6_addr_prefix(&prefix, &ifp->addr, ifp->prefix_len);
756-
rt = rt6_lookup(&init_net, &prefix, NULL, ifp->idev->dev->ifindex, 1);
756+
rt = rt6_lookup(net, &prefix, NULL, ifp->idev->dev->ifindex, 1);
757757

758758
if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) {
759759
if (onlink == 0) {
@@ -905,6 +905,7 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev,
905905
{
906906
struct ipv6_saddr_score hiscore;
907907
struct inet6_ifaddr *ifa_result = NULL;
908+
struct net *net = daddr_dev->nd_net;
908909
int daddr_type = __ipv6_addr_type(daddr);
909910
int daddr_scope = __ipv6_addr_src_scope(daddr_type);
910911
int daddr_ifindex = daddr_dev ? daddr_dev->ifindex : 0;
@@ -916,7 +917,7 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev,
916917
read_lock(&dev_base_lock);
917918
rcu_read_lock();
918919

919-
for_each_netdev(&init_net, dev) {
920+
for_each_netdev(net, dev) {
920921
struct inet6_dev *idev;
921922
struct inet6_ifaddr *ifa;
922923

@@ -1555,7 +1556,7 @@ addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev,
15551556
.fc_expires = expires,
15561557
.fc_dst_len = plen,
15571558
.fc_flags = RTF_UP | flags,
1558-
.fc_nlinfo.nl_net = &init_net,
1559+
.fc_nlinfo.nl_net = dev->nd_net,
15591560
};
15601561

15611562
ipv6_addr_copy(&cfg.fc_dst, pfx);
@@ -1582,7 +1583,7 @@ static void addrconf_add_mroute(struct net_device *dev)
15821583
.fc_ifindex = dev->ifindex,
15831584
.fc_dst_len = 8,
15841585
.fc_flags = RTF_UP,
1585-
.fc_nlinfo.nl_net = &init_net,
1586+
.fc_nlinfo.nl_net = dev->nd_net,
15861587
};
15871588

15881589
ipv6_addr_set(&cfg.fc_dst, htonl(0xFF000000), 0, 0, 0);
@@ -1599,7 +1600,7 @@ static void sit_route_add(struct net_device *dev)
15991600
.fc_ifindex = dev->ifindex,
16001601
.fc_dst_len = 96,
16011602
.fc_flags = RTF_UP | RTF_NONEXTHOP,
1602-
.fc_nlinfo.nl_net = &init_net,
1603+
.fc_nlinfo.nl_net = dev->nd_net,
16031604
};
16041605

16051606
/* prefix length - 96 bits "::d.d.d.d" */
@@ -1700,7 +1701,8 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len)
17001701

17011702
if (pinfo->onlink) {
17021703
struct rt6_info *rt;
1703-
rt = rt6_lookup(&init_net, &pinfo->prefix, NULL, dev->ifindex, 1);
1704+
rt = rt6_lookup(dev->nd_net, &pinfo->prefix, NULL,
1705+
dev->ifindex, 1);
17041706

17051707
if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) {
17061708
if (rt->rt6i_flags&RTF_EXPIRES) {
@@ -1743,7 +1745,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len)
17431745

17441746
ok:
17451747

1746-
ifp = ipv6_get_ifaddr(&init_net, &addr, dev, 1);
1748+
ifp = ipv6_get_ifaddr(dev->nd_net, &addr, dev, 1);
17471749

17481750
if (ifp == NULL && valid_lft) {
17491751
int max_addresses = in6_dev->cnf.max_addresses;
@@ -2066,6 +2068,7 @@ static void sit_add_v4_addrs(struct inet6_dev *idev)
20662068
struct inet6_ifaddr * ifp;
20672069
struct in6_addr addr;
20682070
struct net_device *dev;
2071+
struct net *net = idev->dev->nd_net;
20692072
int scope;
20702073

20712074
ASSERT_RTNL();
@@ -2092,7 +2095,7 @@ static void sit_add_v4_addrs(struct inet6_dev *idev)
20922095
return;
20932096
}
20942097

2095-
for_each_netdev(&init_net, dev) {
2098+
for_each_netdev(net, dev) {
20962099
struct in_device * in_dev = __in_dev_get_rtnl(dev);
20972100
if (in_dev && (dev->flags & IFF_UP)) {
20982101
struct in_ifaddr * ifa;
@@ -2255,15 +2258,16 @@ ipv6_inherit_linklocal(struct inet6_dev *idev, struct net_device *link_dev)
22552258
static void ip6_tnl_add_linklocal(struct inet6_dev *idev)
22562259
{
22572260
struct net_device *link_dev;
2261+
struct net *net = idev->dev->nd_net;
22582262

22592263
/* first try to inherit the link-local address from the link device */
22602264
if (idev->dev->iflink &&
2261-
(link_dev = __dev_get_by_index(&init_net, idev->dev->iflink))) {
2265+
(link_dev = __dev_get_by_index(net, idev->dev->iflink))) {
22622266
if (!ipv6_inherit_linklocal(idev, link_dev))
22632267
return;
22642268
}
22652269
/* then try to inherit it from any device */
2266-
for_each_netdev(&init_net, link_dev) {
2270+
for_each_netdev(net, link_dev) {
22672271
if (!ipv6_inherit_linklocal(idev, link_dev))
22682272
return;
22692273
}
@@ -2296,9 +2300,6 @@ static int addrconf_notify(struct notifier_block *this, unsigned long event,
22962300
int run_pending = 0;
22972301
int err;
22982302

2299-
if (dev->nd_net != &init_net)
2300-
return NOTIFY_DONE;
2301-
23022303
switch(event) {
23032304
case NETDEV_REGISTER:
23042305
if (!idev && dev->mtu >= IPV6_MIN_MTU) {
@@ -3056,9 +3057,6 @@ inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
30563057
struct in6_addr *pfx;
30573058
int err;
30583059

3059-
if (net != &init_net)
3060-
return -EINVAL;
3061-
30623060
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy);
30633061
if (err < 0)
30643062
return err;
@@ -3121,9 +3119,6 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
31213119
u8 ifa_flags;
31223120
int err;
31233121

3124-
if (net != &init_net)
3125-
return -EINVAL;
3126-
31273122
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy);
31283123
if (err < 0)
31293124
return err;
@@ -3324,12 +3319,13 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
33243319
struct inet6_ifaddr *ifa;
33253320
struct ifmcaddr6 *ifmca;
33263321
struct ifacaddr6 *ifaca;
3322+
struct net *net = skb->sk->sk_net;
33273323

33283324
s_idx = cb->args[0];
33293325
s_ip_idx = ip_idx = cb->args[1];
33303326

33313327
idx = 0;
3332-
for_each_netdev(&init_net, dev) {
3328+
for_each_netdev(net, dev) {
33333329
if (idx < s_idx)
33343330
goto cont;
33353331
if (idx > s_idx)
@@ -3396,35 +3392,23 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb,
33963392

33973393
static int inet6_dump_ifaddr(struct sk_buff *skb, struct netlink_callback *cb)
33983394
{
3399-
struct net *net = skb->sk->sk_net;
34003395
enum addr_type_t type = UNICAST_ADDR;
34013396

3402-
if (net != &init_net)
3403-
return 0;
3404-
34053397
return inet6_dump_addr(skb, cb, type);
34063398
}
34073399

34083400
static int inet6_dump_ifmcaddr(struct sk_buff *skb, struct netlink_callback *cb)
34093401
{
3410-
struct net *net = skb->sk->sk_net;
34113402
enum addr_type_t type = MULTICAST_ADDR;
34123403

3413-
if (net != &init_net)
3414-
return 0;
3415-
34163404
return inet6_dump_addr(skb, cb, type);
34173405
}
34183406

34193407

34203408
static int inet6_dump_ifacaddr(struct sk_buff *skb, struct netlink_callback *cb)
34213409
{
3422-
struct net *net = skb->sk->sk_net;
34233410
enum addr_type_t type = ANYCAST_ADDR;
34243411

3425-
if (net != &init_net)
3426-
return 0;
3427-
34283412
return inet6_dump_addr(skb, cb, type);
34293413
}
34303414

@@ -3440,9 +3424,6 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh,
34403424
struct sk_buff *skb;
34413425
int err;
34423426

3443-
if (net != &init_net)
3444-
return -EINVAL;
3445-
34463427
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy);
34473428
if (err < 0)
34483429
goto errout;
@@ -3455,7 +3436,7 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh,
34553436

34563437
ifm = nlmsg_data(nlh);
34573438
if (ifm->ifa_index)
3458-
dev = __dev_get_by_index(&init_net, ifm->ifa_index);
3439+
dev = __dev_get_by_index(net, ifm->ifa_index);
34593440

34603441
if ((ifa = ipv6_get_ifaddr(net, addr, dev, 1)) == NULL) {
34613442
err = -EADDRNOTAVAIL;
@@ -3475,7 +3456,7 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh,
34753456
kfree_skb(skb);
34763457
goto errout_ifa;
34773458
}
3478-
err = rtnl_unicast(skb, &init_net, NETLINK_CB(in_skb).pid);
3459+
err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).pid);
34793460
errout_ifa:
34803461
in6_ifa_put(ifa);
34813462
errout:
@@ -3485,6 +3466,7 @@ static int inet6_rtm_getaddr(struct sk_buff *in_skb, struct nlmsghdr* nlh,
34853466
static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa)
34863467
{
34873468
struct sk_buff *skb;
3469+
struct net *net = ifa->idev->dev->nd_net;
34883470
int err = -ENOBUFS;
34893471

34903472
skb = nlmsg_new(inet6_ifaddr_msgsize(), GFP_ATOMIC);
@@ -3498,10 +3480,10 @@ static void inet6_ifa_notify(int event, struct inet6_ifaddr *ifa)
34983480
kfree_skb(skb);
34993481
goto errout;
35003482
}
3501-
err = rtnl_notify(skb, &init_net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
3483+
err = rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
35023484
errout:
35033485
if (err < 0)
3504-
rtnl_set_sk_err(&init_net, RTNLGRP_IPV6_IFADDR, err);
3486+
rtnl_set_sk_err(net, RTNLGRP_IPV6_IFADDR, err);
35053487
}
35063488

35073489
static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
@@ -3666,12 +3648,9 @@ static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
36663648
struct net_device *dev;
36673649
struct inet6_dev *idev;
36683650

3669-
if (net != &init_net)
3670-
return 0;
3671-
36723651
read_lock(&dev_base_lock);
36733652
idx = 0;
3674-
for_each_netdev(&init_net, dev) {
3653+
for_each_netdev(net, dev) {
36753654
if (idx < s_idx)
36763655
goto cont;
36773656
if ((idev = in6_dev_get(dev)) == NULL)
@@ -3693,6 +3672,7 @@ static int inet6_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
36933672
void inet6_ifinfo_notify(int event, struct inet6_dev *idev)
36943673
{
36953674
struct sk_buff *skb;
3675+
struct net *net = idev->dev->nd_net;
36963676
int err = -ENOBUFS;
36973677

36983678
skb = nlmsg_new(inet6_if_nlmsg_size(), GFP_ATOMIC);
@@ -3706,10 +3686,10 @@ void inet6_ifinfo_notify(int event, struct inet6_dev *idev)
37063686
kfree_skb(skb);
37073687
goto errout;
37083688
}
3709-
err = rtnl_notify(skb, &init_net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
3689+
err = rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC);
37103690
errout:
37113691
if (err < 0)
3712-
rtnl_set_sk_err(&init_net, RTNLGRP_IPV6_IFADDR, err);
3692+
rtnl_set_sk_err(net, RTNLGRP_IPV6_IFADDR, err);
37133693
}
37143694

37153695
static inline size_t inet6_prefix_nlmsg_size(void)
@@ -3762,6 +3742,7 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev,
37623742
struct prefix_info *pinfo)
37633743
{
37643744
struct sk_buff *skb;
3745+
struct net *net = idev->dev->nd_net;
37653746
int err = -ENOBUFS;
37663747

37673748
skb = nlmsg_new(inet6_prefix_nlmsg_size(), GFP_ATOMIC);
@@ -3775,10 +3756,10 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev,
37753756
kfree_skb(skb);
37763757
goto errout;
37773758
}
3778-
err = rtnl_notify(skb, &init_net, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC);
3759+
err = rtnl_notify(skb, net, 0, RTNLGRP_IPV6_PREFIX, NULL, GFP_ATOMIC);
37793760
errout:
37803761
if (err < 0)
3781-
rtnl_set_sk_err(&init_net, RTNLGRP_IPV6_PREFIX, err);
3762+
rtnl_set_sk_err(net, RTNLGRP_IPV6_PREFIX, err);
37823763
}
37833764

37843765
static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
@@ -4276,7 +4257,26 @@ static int addrconf_net_init(struct net *net)
42764257

42774258
static void addrconf_net_exit(struct net *net)
42784259
{
4279-
;
4260+
struct net_device *dev;
4261+
4262+
/*
4263+
* Remove loopback references from default routing entries
4264+
*/
4265+
/* in6_dev_put(net->ipv6.ip6_null_entry->rt6i_idev); */
4266+
/* #ifdef CONFIG_IPV6_MULTIPLE_TABLES */
4267+
/* in6_dev_put(net->ipv6.ip6_prohibit_entry->rt6i_idev); */
4268+
/* in6_dev_put(net->ipv6.ip6_blk_hole_entry->rt6i_idev); */
4269+
/* #endif */
4270+
4271+
rtnl_lock();
4272+
/* clean dev list */
4273+
for_each_netdev(net, dev) {
4274+
if (__in6_dev_get(dev) == NULL)
4275+
continue;
4276+
addrconf_ifdown(dev, 1);
4277+
}
4278+
addrconf_ifdown(net->loopback_dev, 2);
4279+
rtnl_unlock();
42804280
}
42814281

42824282
static struct pernet_operations addrconf_net_ops = {
@@ -4357,7 +4357,6 @@ int __init addrconf_init(void)
43574357

43584358
void addrconf_cleanup(void)
43594359
{
4360-
struct net_device *dev;
43614360
struct inet6_ifaddr *ifa;
43624361
int i;
43634362

@@ -4368,21 +4367,9 @@ void addrconf_cleanup(void)
43684367

43694368
rtnl_lock();
43704369

4371-
/*
4372-
* clean dev list.
4373-
*/
4374-
4375-
for_each_netdev(&init_net, dev) {
4376-
if (__in6_dev_get(dev) == NULL)
4377-
continue;
4378-
addrconf_ifdown(dev, 1);
4379-
}
4380-
addrconf_ifdown(init_net.loopback_dev, 2);
4381-
43824370
/*
43834371
* Check hash table.
43844372
*/
4385-
43864373
write_lock_bh(&addrconf_hash_lock);
43874374
for (i=0; i < IN6_ADDR_HSIZE; i++) {
43884375
for (ifa=inet6_addr_lst[i]; ifa; ) {

0 commit comments

Comments
 (0)