aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/addrconf.h9
-rw-r--r--net/ipv6/addrconf.c66
-rw-r--r--net/ipv6/af_inet6.c6
3 files changed, 57 insertions, 24 deletions
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index 89e3c53c8886..232da20e7171 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -55,9 +55,12 @@ struct prefix_info {
55extern int addrconf_init(void); 55extern int addrconf_init(void);
56extern void addrconf_cleanup(void); 56extern void addrconf_cleanup(void);
57 57
58extern int addrconf_add_ifaddr(void __user *arg); 58extern int addrconf_add_ifaddr(struct net *net,
59extern int addrconf_del_ifaddr(void __user *arg); 59 void __user *arg);
60extern int addrconf_set_dstaddr(void __user *arg); 60extern int addrconf_del_ifaddr(struct net *net,
61 void __user *arg);
62extern int addrconf_set_dstaddr(struct net *net,
63 void __user *arg);
61 64
62extern int ipv6_chk_addr(struct net *net, 65extern int ipv6_chk_addr(struct net *net,
63 struct in6_addr *addr, 66 struct in6_addr *addr,
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 17b06d220e95..127021bdd180 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1866,7 +1866,7 @@ ok:
1866 * Special case for SIT interfaces where we create a new "virtual" 1866 * Special case for SIT interfaces where we create a new "virtual"
1867 * device. 1867 * device.
1868 */ 1868 */
1869int addrconf_set_dstaddr(void __user *arg) 1869int addrconf_set_dstaddr(struct net *net, void __user *arg)
1870{ 1870{
1871 struct in6_ifreq ireq; 1871 struct in6_ifreq ireq;
1872 struct net_device *dev; 1872 struct net_device *dev;
@@ -1878,7 +1878,7 @@ int addrconf_set_dstaddr(void __user *arg)
1878 if (copy_from_user(&ireq, arg, sizeof(struct in6_ifreq))) 1878 if (copy_from_user(&ireq, arg, sizeof(struct in6_ifreq)))
1879 goto err_exit; 1879 goto err_exit;
1880 1880
1881 dev = __dev_get_by_index(&init_net, ireq.ifr6_ifindex); 1881 dev = __dev_get_by_index(net, ireq.ifr6_ifindex);
1882 1882
1883 err = -ENODEV; 1883 err = -ENODEV;
1884 if (dev == NULL) 1884 if (dev == NULL)
@@ -1909,7 +1909,8 @@ int addrconf_set_dstaddr(void __user *arg)
1909 1909
1910 if (err == 0) { 1910 if (err == 0) {
1911 err = -ENOBUFS; 1911 err = -ENOBUFS;
1912 if ((dev = __dev_get_by_name(&init_net, p.name)) == NULL) 1912 dev = __dev_get_by_name(net, p.name);
1913 if (!dev)
1913 goto err_exit; 1914 goto err_exit;
1914 err = dev_open(dev); 1915 err = dev_open(dev);
1915 } 1916 }
@@ -1924,8 +1925,9 @@ err_exit:
1924/* 1925/*
1925 * Manual configuration of address on an interface 1926 * Manual configuration of address on an interface
1926 */ 1927 */
1927static int inet6_addr_add(int ifindex, struct in6_addr *pfx, int plen, 1928static int inet6_addr_add(struct net *net, int ifindex, struct in6_addr *pfx,
1928 __u8 ifa_flags, __u32 prefered_lft, __u32 valid_lft) 1929 int plen, __u8 ifa_flags, __u32 prefered_lft,
1930 __u32 valid_lft)
1929{ 1931{
1930 struct inet6_ifaddr *ifp; 1932 struct inet6_ifaddr *ifp;
1931 struct inet6_dev *idev; 1933 struct inet6_dev *idev;
@@ -1939,7 +1941,8 @@ static int inet6_addr_add(int ifindex, struct in6_addr *pfx, int plen,
1939 if (!valid_lft || prefered_lft > valid_lft) 1941 if (!valid_lft || prefered_lft > valid_lft)
1940 return -EINVAL; 1942 return -EINVAL;
1941 1943
1942 if ((dev = __dev_get_by_index(&init_net, ifindex)) == NULL) 1944 dev = __dev_get_by_index(net, ifindex);
1945 if (!dev)
1943 return -ENODEV; 1946 return -ENODEV;
1944 1947
1945 if ((idev = addrconf_add_dev(dev)) == NULL) 1948 if ((idev = addrconf_add_dev(dev)) == NULL)
@@ -1984,13 +1987,15 @@ static int inet6_addr_add(int ifindex, struct in6_addr *pfx, int plen,
1984 return PTR_ERR(ifp); 1987 return PTR_ERR(ifp);
1985} 1988}
1986 1989
1987static int inet6_addr_del(int ifindex, struct in6_addr *pfx, int plen) 1990static int inet6_addr_del(struct net *net, int ifindex, struct in6_addr *pfx,
1991 int plen)
1988{ 1992{
1989 struct inet6_ifaddr *ifp; 1993 struct inet6_ifaddr *ifp;
1990 struct inet6_dev *idev; 1994 struct inet6_dev *idev;
1991 struct net_device *dev; 1995 struct net_device *dev;
1992 1996
1993 if ((dev = __dev_get_by_index(&init_net, ifindex)) == NULL) 1997 dev = __dev_get_by_index(net, ifindex);
1998 if (!dev)
1994 return -ENODEV; 1999 return -ENODEV;
1995 2000
1996 if ((idev = __in6_dev_get(dev)) == NULL) 2001 if ((idev = __in6_dev_get(dev)) == NULL)
@@ -2018,7 +2023,7 @@ static int inet6_addr_del(int ifindex, struct in6_addr *pfx, int plen)
2018} 2023}
2019 2024
2020 2025
2021int addrconf_add_ifaddr(void __user *arg) 2026int addrconf_add_ifaddr(struct net *net, void __user *arg)
2022{ 2027{
2023 struct in6_ifreq ireq; 2028 struct in6_ifreq ireq;
2024 int err; 2029 int err;
@@ -2030,13 +2035,14 @@ int addrconf_add_ifaddr(void __user *arg)
2030 return -EFAULT; 2035 return -EFAULT;
2031 2036
2032 rtnl_lock(); 2037 rtnl_lock();
2033 err = inet6_addr_add(ireq.ifr6_ifindex, &ireq.ifr6_addr, ireq.ifr6_prefixlen, 2038 err = inet6_addr_add(net, ireq.ifr6_ifindex, &ireq.ifr6_addr,
2034 IFA_F_PERMANENT, INFINITY_LIFE_TIME, INFINITY_LIFE_TIME); 2039 ireq.ifr6_prefixlen, IFA_F_PERMANENT,
2040 INFINITY_LIFE_TIME, INFINITY_LIFE_TIME);
2035 rtnl_unlock(); 2041 rtnl_unlock();
2036 return err; 2042 return err;
2037} 2043}
2038 2044
2039int addrconf_del_ifaddr(void __user *arg) 2045int addrconf_del_ifaddr(struct net *net, void __user *arg)
2040{ 2046{
2041 struct in6_ifreq ireq; 2047 struct in6_ifreq ireq;
2042 int err; 2048 int err;
@@ -2048,7 +2054,8 @@ int addrconf_del_ifaddr(void __user *arg)
2048 return -EFAULT; 2054 return -EFAULT;
2049 2055
2050 rtnl_lock(); 2056 rtnl_lock();
2051 err = inet6_addr_del(ireq.ifr6_ifindex, &ireq.ifr6_addr, ireq.ifr6_prefixlen); 2057 err = inet6_addr_del(net, ireq.ifr6_ifindex, &ireq.ifr6_addr,
2058 ireq.ifr6_prefixlen);
2052 rtnl_unlock(); 2059 rtnl_unlock();
2053 return err; 2060 return err;
2054} 2061}
@@ -3061,7 +3068,7 @@ inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
3061 if (pfx == NULL) 3068 if (pfx == NULL)
3062 return -EINVAL; 3069 return -EINVAL;
3063 3070
3064 return inet6_addr_del(ifm->ifa_index, pfx, ifm->ifa_prefixlen); 3071 return inet6_addr_del(net, ifm->ifa_index, pfx, ifm->ifa_prefixlen);
3065} 3072}
3066 3073
3067static int inet6_addr_modify(struct inet6_ifaddr *ifp, u8 ifa_flags, 3074static int inet6_addr_modify(struct inet6_ifaddr *ifp, u8 ifa_flags,
@@ -3137,7 +3144,7 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
3137 valid_lft = INFINITY_LIFE_TIME; 3144 valid_lft = INFINITY_LIFE_TIME;
3138 } 3145 }
3139 3146
3140 dev = __dev_get_by_index(&init_net, ifm->ifa_index); 3147 dev = __dev_get_by_index(net, ifm->ifa_index);
3141 if (dev == NULL) 3148 if (dev == NULL)
3142 return -ENODEV; 3149 return -ENODEV;
3143 3150
@@ -3150,8 +3157,9 @@ inet6_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
3150 * It would be best to check for !NLM_F_CREATE here but 3157 * It would be best to check for !NLM_F_CREATE here but
3151 * userspace alreay relies on not having to provide this. 3158 * userspace alreay relies on not having to provide this.
3152 */ 3159 */
3153 return inet6_addr_add(ifm->ifa_index, pfx, ifm->ifa_prefixlen, 3160 return inet6_addr_add(net, ifm->ifa_index, pfx,
3154 ifa_flags, preferred_lft, valid_lft); 3161 ifm->ifa_prefixlen, ifa_flags,
3162 preferred_lft, valid_lft);
3155 } 3163 }
3156 3164
3157 if (nlh->nlmsg_flags & NLM_F_EXCL || 3165 if (nlh->nlmsg_flags & NLM_F_EXCL ||
@@ -4260,6 +4268,22 @@ int unregister_inet6addr_notifier(struct notifier_block *nb)
4260 4268
4261EXPORT_SYMBOL(unregister_inet6addr_notifier); 4269EXPORT_SYMBOL(unregister_inet6addr_notifier);
4262 4270
4271
4272static int addrconf_net_init(struct net *net)
4273{
4274 return 0;
4275}
4276
4277static void addrconf_net_exit(struct net *net)
4278{
4279 ;
4280}
4281
4282static struct pernet_operations addrconf_net_ops = {
4283 .init = addrconf_net_init,
4284 .exit = addrconf_net_exit,
4285};
4286
4263/* 4287/*
4264 * Init / cleanup code 4288 * Init / cleanup code
4265 */ 4289 */
@@ -4301,6 +4325,10 @@ int __init addrconf_init(void)
4301 if (err) 4325 if (err)
4302 goto errlo; 4326 goto errlo;
4303 4327
4328 err = register_pernet_device(&addrconf_net_ops);
4329 if (err)
4330 return err;
4331
4304 register_netdevice_notifier(&ipv6_dev_notf); 4332 register_netdevice_notifier(&ipv6_dev_notf);
4305 4333
4306 addrconf_verify(0); 4334 addrconf_verify(0);
@@ -4334,6 +4362,7 @@ void addrconf_cleanup(void)
4334 int i; 4362 int i;
4335 4363
4336 unregister_netdevice_notifier(&ipv6_dev_notf); 4364 unregister_netdevice_notifier(&ipv6_dev_notf);
4365 unregister_pernet_device(&addrconf_net_ops);
4337 4366
4338 unregister_pernet_subsys(&addrconf_ops); 4367 unregister_pernet_subsys(&addrconf_ops);
4339 4368
@@ -4370,6 +4399,7 @@ void addrconf_cleanup(void)
4370 write_unlock_bh(&addrconf_hash_lock); 4399 write_unlock_bh(&addrconf_hash_lock);
4371 4400
4372 del_timer(&addr_chk_timer); 4401 del_timer(&addr_chk_timer);
4373
4374 rtnl_unlock(); 4402 rtnl_unlock();
4403
4404 unregister_pernet_subsys(&addrconf_net_ops);
4375} 4405}
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c
index 430bbd2139c1..afe9276d0420 100644
--- a/net/ipv6/af_inet6.c
+++ b/net/ipv6/af_inet6.c
@@ -454,11 +454,11 @@ int inet6_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
454 return(ipv6_route_ioctl(net, cmd, (void __user *)arg)); 454 return(ipv6_route_ioctl(net, cmd, (void __user *)arg));
455 455
456 case SIOCSIFADDR: 456 case SIOCSIFADDR:
457 return addrconf_add_ifaddr((void __user *) arg); 457 return addrconf_add_ifaddr(net, (void __user *) arg);
458 case SIOCDIFADDR: 458 case SIOCDIFADDR:
459 return addrconf_del_ifaddr((void __user *) arg); 459 return addrconf_del_ifaddr(net, (void __user *) arg);
460 case SIOCSIFDSTADDR: 460 case SIOCSIFDSTADDR:
461 return addrconf_set_dstaddr((void __user *) arg); 461 return addrconf_set_dstaddr(net, (void __user *) arg);
462 default: 462 default:
463 if (!sk->sk_prot->ioctl) 463 if (!sk->sk_prot->ioctl)
464 return -ENOIOCTLCMD; 464 return -ENOIOCTLCMD;