diff options
-rw-r--r-- | include/net/addrconf.h | 9 | ||||
-rw-r--r-- | net/ipv6/addrconf.c | 66 | ||||
-rw-r--r-- | net/ipv6/af_inet6.c | 6 |
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 { | |||
55 | extern int addrconf_init(void); | 55 | extern int addrconf_init(void); |
56 | extern void addrconf_cleanup(void); | 56 | extern void addrconf_cleanup(void); |
57 | 57 | ||
58 | extern int addrconf_add_ifaddr(void __user *arg); | 58 | extern int addrconf_add_ifaddr(struct net *net, |
59 | extern int addrconf_del_ifaddr(void __user *arg); | 59 | void __user *arg); |
60 | extern int addrconf_set_dstaddr(void __user *arg); | 60 | extern int addrconf_del_ifaddr(struct net *net, |
61 | void __user *arg); | ||
62 | extern int addrconf_set_dstaddr(struct net *net, | ||
63 | void __user *arg); | ||
61 | 64 | ||
62 | extern int ipv6_chk_addr(struct net *net, | 65 | extern 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 | */ |
1869 | int addrconf_set_dstaddr(void __user *arg) | 1869 | int 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 | */ |
1927 | static int inet6_addr_add(int ifindex, struct in6_addr *pfx, int plen, | 1928 | static 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 | ||
1987 | static int inet6_addr_del(int ifindex, struct in6_addr *pfx, int plen) | 1990 | static 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 | ||
2021 | int addrconf_add_ifaddr(void __user *arg) | 2026 | int 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 | ||
2039 | int addrconf_del_ifaddr(void __user *arg) | 2045 | int 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 | ||
3067 | static int inet6_addr_modify(struct inet6_ifaddr *ifp, u8 ifa_flags, | 3074 | static 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 | ||
4261 | EXPORT_SYMBOL(unregister_inet6addr_notifier); | 4269 | EXPORT_SYMBOL(unregister_inet6addr_notifier); |
4262 | 4270 | ||
4271 | |||
4272 | static int addrconf_net_init(struct net *net) | ||
4273 | { | ||
4274 | return 0; | ||
4275 | } | ||
4276 | |||
4277 | static void addrconf_net_exit(struct net *net) | ||
4278 | { | ||
4279 | ; | ||
4280 | } | ||
4281 | |||
4282 | static 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; |