aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/addrconf.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/addrconf.c')
-rw-r--r--net/ipv6/addrconf.c58
1 files changed, 24 insertions, 34 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index a7bda0757053..498b927f68be 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -289,19 +289,19 @@ static int snmp6_alloc_dev(struct inet6_dev *idev)
289 sizeof(struct ipstats_mib), 289 sizeof(struct ipstats_mib),
290 __alignof__(struct ipstats_mib)) < 0) 290 __alignof__(struct ipstats_mib)) < 0)
291 goto err_ip; 291 goto err_ip;
292 if (snmp_mib_init((void __percpu **)idev->stats.icmpv6, 292 idev->stats.icmpv6dev = kzalloc(sizeof(struct icmpv6_mib_device),
293 sizeof(struct icmpv6_mib), 293 GFP_KERNEL);
294 __alignof__(struct icmpv6_mib)) < 0) 294 if (!idev->stats.icmpv6dev)
295 goto err_icmp; 295 goto err_icmp;
296 if (snmp_mib_init((void __percpu **)idev->stats.icmpv6msg, 296 idev->stats.icmpv6msgdev = kzalloc(sizeof(struct icmpv6msg_mib_device),
297 sizeof(struct icmpv6msg_mib), 297 GFP_KERNEL);
298 __alignof__(struct icmpv6msg_mib)) < 0) 298 if (!idev->stats.icmpv6msgdev)
299 goto err_icmpmsg; 299 goto err_icmpmsg;
300 300
301 return 0; 301 return 0;
302 302
303err_icmpmsg: 303err_icmpmsg:
304 snmp_mib_free((void __percpu **)idev->stats.icmpv6); 304 kfree(idev->stats.icmpv6dev);
305err_icmp: 305err_icmp:
306 snmp_mib_free((void __percpu **)idev->stats.ipv6); 306 snmp_mib_free((void __percpu **)idev->stats.ipv6);
307err_ip: 307err_ip:
@@ -310,19 +310,13 @@ err_ip:
310 310
311static void snmp6_free_dev(struct inet6_dev *idev) 311static void snmp6_free_dev(struct inet6_dev *idev)
312{ 312{
313 snmp_mib_free((void __percpu **)idev->stats.icmpv6msg); 313 kfree(idev->stats.icmpv6msgdev);
314 snmp_mib_free((void __percpu **)idev->stats.icmpv6); 314 kfree(idev->stats.icmpv6dev);
315 snmp_mib_free((void __percpu **)idev->stats.ipv6); 315 snmp_mib_free((void __percpu **)idev->stats.ipv6);
316} 316}
317 317
318/* Nobody refers to this device, we may destroy it. */ 318/* Nobody refers to this device, we may destroy it. */
319 319
320static void in6_dev_finish_destroy_rcu(struct rcu_head *head)
321{
322 struct inet6_dev *idev = container_of(head, struct inet6_dev, rcu);
323 kfree(idev);
324}
325
326void in6_dev_finish_destroy(struct inet6_dev *idev) 320void in6_dev_finish_destroy(struct inet6_dev *idev)
327{ 321{
328 struct net_device *dev = idev->dev; 322 struct net_device *dev = idev->dev;
@@ -339,7 +333,7 @@ void in6_dev_finish_destroy(struct inet6_dev *idev)
339 return; 333 return;
340 } 334 }
341 snmp6_free_dev(idev); 335 snmp6_free_dev(idev);
342 call_rcu(&idev->rcu, in6_dev_finish_destroy_rcu); 336 kfree_rcu(idev, rcu);
343} 337}
344 338
345EXPORT_SYMBOL(in6_dev_finish_destroy); 339EXPORT_SYMBOL(in6_dev_finish_destroy);
@@ -535,12 +529,6 @@ static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old)
535} 529}
536#endif 530#endif
537 531
538static void inet6_ifa_finish_destroy_rcu(struct rcu_head *head)
539{
540 struct inet6_ifaddr *ifp = container_of(head, struct inet6_ifaddr, rcu);
541 kfree(ifp);
542}
543
544/* Nobody refers to this ifaddr, destroy it */ 532/* Nobody refers to this ifaddr, destroy it */
545void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp) 533void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp)
546{ 534{
@@ -561,7 +549,7 @@ void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp)
561 } 549 }
562 dst_release(&ifp->rt->dst); 550 dst_release(&ifp->rt->dst);
563 551
564 call_rcu(&ifp->rcu, inet6_ifa_finish_destroy_rcu); 552 kfree_rcu(ifp, rcu);
565} 553}
566 554
567static void 555static void
@@ -825,6 +813,8 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp)
825 dst_release(&rt->dst); 813 dst_release(&rt->dst);
826 } 814 }
827 815
816 /* clean up prefsrc entries */
817 rt6_remove_prefsrc(ifp);
828out: 818out:
829 in6_ifa_put(ifp); 819 in6_ifa_put(ifp);
830} 820}
@@ -1281,7 +1271,7 @@ static int ipv6_count_addresses(struct inet6_dev *idev)
1281 return cnt; 1271 return cnt;
1282} 1272}
1283 1273
1284int ipv6_chk_addr(struct net *net, struct in6_addr *addr, 1274int ipv6_chk_addr(struct net *net, const struct in6_addr *addr,
1285 struct net_device *dev, int strict) 1275 struct net_device *dev, int strict)
1286{ 1276{
1287 struct inet6_ifaddr *ifp; 1277 struct inet6_ifaddr *ifp;
@@ -1324,7 +1314,7 @@ static bool ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr,
1324 return false; 1314 return false;
1325} 1315}
1326 1316
1327int ipv6_chk_prefix(struct in6_addr *addr, struct net_device *dev) 1317int ipv6_chk_prefix(const struct in6_addr *addr, struct net_device *dev)
1328{ 1318{
1329 struct inet6_dev *idev; 1319 struct inet6_dev *idev;
1330 struct inet6_ifaddr *ifa; 1320 struct inet6_ifaddr *ifa;
@@ -1455,7 +1445,7 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp)
1455 1445
1456/* Join to solicited addr multicast group. */ 1446/* Join to solicited addr multicast group. */
1457 1447
1458void addrconf_join_solict(struct net_device *dev, struct in6_addr *addr) 1448void addrconf_join_solict(struct net_device *dev, const struct in6_addr *addr)
1459{ 1449{
1460 struct in6_addr maddr; 1450 struct in6_addr maddr;
1461 1451
@@ -1466,7 +1456,7 @@ void addrconf_join_solict(struct net_device *dev, struct in6_addr *addr)
1466 ipv6_dev_mc_inc(dev, &maddr); 1456 ipv6_dev_mc_inc(dev, &maddr);
1467} 1457}
1468 1458
1469void addrconf_leave_solict(struct inet6_dev *idev, struct in6_addr *addr) 1459void addrconf_leave_solict(struct inet6_dev *idev, const struct in6_addr *addr)
1470{ 1460{
1471 struct in6_addr maddr; 1461 struct in6_addr maddr;
1472 1462
@@ -2111,7 +2101,7 @@ err_exit:
2111/* 2101/*
2112 * Manual configuration of address on an interface 2102 * Manual configuration of address on an interface
2113 */ 2103 */
2114static int inet6_addr_add(struct net *net, int ifindex, struct in6_addr *pfx, 2104static int inet6_addr_add(struct net *net, int ifindex, const struct in6_addr *pfx,
2115 unsigned int plen, __u8 ifa_flags, __u32 prefered_lft, 2105 unsigned int plen, __u8 ifa_flags, __u32 prefered_lft,
2116 __u32 valid_lft) 2106 __u32 valid_lft)
2117{ 2107{
@@ -2185,7 +2175,7 @@ static int inet6_addr_add(struct net *net, int ifindex, struct in6_addr *pfx,
2185 return PTR_ERR(ifp); 2175 return PTR_ERR(ifp);
2186} 2176}
2187 2177
2188static int inet6_addr_del(struct net *net, int ifindex, struct in6_addr *pfx, 2178static int inet6_addr_del(struct net *net, int ifindex, const struct in6_addr *pfx,
2189 unsigned int plen) 2179 unsigned int plen)
2190{ 2180{
2191 struct inet6_ifaddr *ifp; 2181 struct inet6_ifaddr *ifp;
@@ -2348,7 +2338,7 @@ static void init_loopback(struct net_device *dev)
2348 add_addr(idev, &in6addr_loopback, 128, IFA_HOST); 2338 add_addr(idev, &in6addr_loopback, 128, IFA_HOST);
2349} 2339}
2350 2340
2351static void addrconf_add_linklocal(struct inet6_dev *idev, struct in6_addr *addr) 2341static void addrconf_add_linklocal(struct inet6_dev *idev, const struct in6_addr *addr)
2352{ 2342{
2353 struct inet6_ifaddr * ifp; 2343 struct inet6_ifaddr * ifp;
2354 u32 addr_flags = IFA_F_PERMANENT; 2344 u32 addr_flags = IFA_F_PERMANENT;
@@ -3119,7 +3109,7 @@ void if6_proc_exit(void)
3119 3109
3120#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) 3110#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
3121/* Check if address is a home address configured on any interface. */ 3111/* Check if address is a home address configured on any interface. */
3122int ipv6_chk_home_addr(struct net *net, struct in6_addr *addr) 3112int ipv6_chk_home_addr(struct net *net, const struct in6_addr *addr)
3123{ 3113{
3124 int ret = 0; 3114 int ret = 0;
3125 struct inet6_ifaddr *ifp = NULL; 3115 struct inet6_ifaddr *ifp = NULL;
@@ -3836,7 +3826,7 @@ static inline size_t inet6_if_nlmsg_size(void)
3836 + nla_total_size(inet6_ifla6_size()); /* IFLA_PROTINFO */ 3826 + nla_total_size(inet6_ifla6_size()); /* IFLA_PROTINFO */
3837} 3827}
3838 3828
3839static inline void __snmp6_fill_stats(u64 *stats, void __percpu **mib, 3829static inline void __snmp6_fill_statsdev(u64 *stats, atomic_long_t *mib,
3840 int items, int bytes) 3830 int items, int bytes)
3841{ 3831{
3842 int i; 3832 int i;
@@ -3846,7 +3836,7 @@ static inline void __snmp6_fill_stats(u64 *stats, void __percpu **mib,
3846 /* Use put_unaligned() because stats may not be aligned for u64. */ 3836 /* Use put_unaligned() because stats may not be aligned for u64. */
3847 put_unaligned(items, &stats[0]); 3837 put_unaligned(items, &stats[0]);
3848 for (i = 1; i < items; i++) 3838 for (i = 1; i < items; i++)
3849 put_unaligned(snmp_fold_field(mib, i), &stats[i]); 3839 put_unaligned(atomic_long_read(&mib[i]), &stats[i]);
3850 3840
3851 memset(&stats[items], 0, pad); 3841 memset(&stats[items], 0, pad);
3852} 3842}
@@ -3875,7 +3865,7 @@ static void snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype,
3875 IPSTATS_MIB_MAX, bytes, offsetof(struct ipstats_mib, syncp)); 3865 IPSTATS_MIB_MAX, bytes, offsetof(struct ipstats_mib, syncp));
3876 break; 3866 break;
3877 case IFLA_INET6_ICMP6STATS: 3867 case IFLA_INET6_ICMP6STATS:
3878 __snmp6_fill_stats(stats, (void __percpu **)idev->stats.icmpv6, ICMP6_MIB_MAX, bytes); 3868 __snmp6_fill_statsdev(stats, idev->stats.icmpv6dev->mibs, ICMP6_MIB_MAX, bytes);
3879 break; 3869 break;
3880 } 3870 }
3881} 3871}