aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/addrconf.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /net/ipv6/addrconf.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'net/ipv6/addrconf.c')
-rw-r--r--net/ipv6/addrconf.c312
1 files changed, 166 insertions, 146 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 324fac3b6c16..498b927f68be 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -98,7 +98,11 @@
98#endif 98#endif
99 99
100#define INFINITY_LIFE_TIME 0xFFFFFFFF 100#define INFINITY_LIFE_TIME 0xFFFFFFFF
101#define TIME_DELTA(a, b) ((unsigned long)((long)(a) - (long)(b))) 101
102static inline u32 cstamp_delta(unsigned long cstamp)
103{
104 return (cstamp - INITIAL_JIFFIES) * 100UL / HZ;
105}
102 106
103#define ADDRCONF_TIMER_FUZZ_MINUS (HZ > 50 ? HZ/50 : 1) 107#define ADDRCONF_TIMER_FUZZ_MINUS (HZ > 50 ? HZ/50 : 1)
104#define ADDRCONF_TIMER_FUZZ (HZ / 4) 108#define ADDRCONF_TIMER_FUZZ (HZ / 4)
@@ -243,7 +247,7 @@ static inline bool addrconf_qdisc_ok(const struct net_device *dev)
243/* Check if a route is valid prefix route */ 247/* Check if a route is valid prefix route */
244static inline int addrconf_is_prefix_route(const struct rt6_info *rt) 248static inline int addrconf_is_prefix_route(const struct rt6_info *rt)
245{ 249{
246 return ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0); 250 return (rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0;
247} 251}
248 252
249static void addrconf_del_timer(struct inet6_ifaddr *ifp) 253static void addrconf_del_timer(struct inet6_ifaddr *ifp)
@@ -285,19 +289,19 @@ static int snmp6_alloc_dev(struct inet6_dev *idev)
285 sizeof(struct ipstats_mib), 289 sizeof(struct ipstats_mib),
286 __alignof__(struct ipstats_mib)) < 0) 290 __alignof__(struct ipstats_mib)) < 0)
287 goto err_ip; 291 goto err_ip;
288 if (snmp_mib_init((void __percpu **)idev->stats.icmpv6, 292 idev->stats.icmpv6dev = kzalloc(sizeof(struct icmpv6_mib_device),
289 sizeof(struct icmpv6_mib), 293 GFP_KERNEL);
290 __alignof__(struct icmpv6_mib)) < 0) 294 if (!idev->stats.icmpv6dev)
291 goto err_icmp; 295 goto err_icmp;
292 if (snmp_mib_init((void __percpu **)idev->stats.icmpv6msg, 296 idev->stats.icmpv6msgdev = kzalloc(sizeof(struct icmpv6msg_mib_device),
293 sizeof(struct icmpv6msg_mib), 297 GFP_KERNEL);
294 __alignof__(struct icmpv6msg_mib)) < 0) 298 if (!idev->stats.icmpv6msgdev)
295 goto err_icmpmsg; 299 goto err_icmpmsg;
296 300
297 return 0; 301 return 0;
298 302
299err_icmpmsg: 303err_icmpmsg:
300 snmp_mib_free((void __percpu **)idev->stats.icmpv6); 304 kfree(idev->stats.icmpv6dev);
301err_icmp: 305err_icmp:
302 snmp_mib_free((void __percpu **)idev->stats.ipv6); 306 snmp_mib_free((void __percpu **)idev->stats.ipv6);
303err_ip: 307err_ip:
@@ -306,19 +310,13 @@ err_ip:
306 310
307static void snmp6_free_dev(struct inet6_dev *idev) 311static void snmp6_free_dev(struct inet6_dev *idev)
308{ 312{
309 snmp_mib_free((void __percpu **)idev->stats.icmpv6msg); 313 kfree(idev->stats.icmpv6msgdev);
310 snmp_mib_free((void __percpu **)idev->stats.icmpv6); 314 kfree(idev->stats.icmpv6dev);
311 snmp_mib_free((void __percpu **)idev->stats.ipv6); 315 snmp_mib_free((void __percpu **)idev->stats.ipv6);
312} 316}
313 317
314/* Nobody refers to this device, we may destroy it. */ 318/* Nobody refers to this device, we may destroy it. */
315 319
316static void in6_dev_finish_destroy_rcu(struct rcu_head *head)
317{
318 struct inet6_dev *idev = container_of(head, struct inet6_dev, rcu);
319 kfree(idev);
320}
321
322void in6_dev_finish_destroy(struct inet6_dev *idev) 320void in6_dev_finish_destroy(struct inet6_dev *idev)
323{ 321{
324 struct net_device *dev = idev->dev; 322 struct net_device *dev = idev->dev;
@@ -335,7 +333,7 @@ void in6_dev_finish_destroy(struct inet6_dev *idev)
335 return; 333 return;
336 } 334 }
337 snmp6_free_dev(idev); 335 snmp6_free_dev(idev);
338 call_rcu(&idev->rcu, in6_dev_finish_destroy_rcu); 336 kfree_rcu(idev, rcu);
339} 337}
340 338
341EXPORT_SYMBOL(in6_dev_finish_destroy); 339EXPORT_SYMBOL(in6_dev_finish_destroy);
@@ -416,9 +414,6 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
416 dev->type == ARPHRD_TUNNEL6 || 414 dev->type == ARPHRD_TUNNEL6 ||
417 dev->type == ARPHRD_SIT || 415 dev->type == ARPHRD_SIT ||
418 dev->type == ARPHRD_NONE) { 416 dev->type == ARPHRD_NONE) {
419 printk(KERN_INFO
420 "%s: Disabled Privacy Extensions\n",
421 dev->name);
422 ndev->cnf.use_tempaddr = -1; 417 ndev->cnf.use_tempaddr = -1;
423 } else { 418 } else {
424 in6_dev_hold(ndev); 419 in6_dev_hold(ndev);
@@ -534,12 +529,6 @@ static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old)
534} 529}
535#endif 530#endif
536 531
537static void inet6_ifa_finish_destroy_rcu(struct rcu_head *head)
538{
539 struct inet6_ifaddr *ifp = container_of(head, struct inet6_ifaddr, rcu);
540 kfree(ifp);
541}
542
543/* Nobody refers to this ifaddr, destroy it */ 532/* Nobody refers to this ifaddr, destroy it */
544void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp) 533void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp)
545{ 534{
@@ -560,7 +549,7 @@ void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp)
560 } 549 }
561 dst_release(&ifp->rt->dst); 550 dst_release(&ifp->rt->dst);
562 551
563 call_rcu(&ifp->rcu, inet6_ifa_finish_destroy_rcu); 552 kfree_rcu(ifp, rcu);
564} 553}
565 554
566static void 555static void
@@ -717,12 +706,9 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp)
717 struct inet6_ifaddr *ifa, *ifn; 706 struct inet6_ifaddr *ifa, *ifn;
718 struct inet6_dev *idev = ifp->idev; 707 struct inet6_dev *idev = ifp->idev;
719 int state; 708 int state;
720 int hash;
721 int deleted = 0, onlink = 0; 709 int deleted = 0, onlink = 0;
722 unsigned long expires = jiffies; 710 unsigned long expires = jiffies;
723 711
724 hash = ipv6_addr_hash(&ifp->addr);
725
726 spin_lock_bh(&ifp->state_lock); 712 spin_lock_bh(&ifp->state_lock);
727 state = ifp->state; 713 state = ifp->state;
728 ifp->state = INET6_IFADDR_STATE_DEAD; 714 ifp->state = INET6_IFADDR_STATE_DEAD;
@@ -827,6 +813,8 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp)
827 dst_release(&rt->dst); 813 dst_release(&rt->dst);
828 } 814 }
829 815
816 /* clean up prefsrc entries */
817 rt6_remove_prefsrc(ifp);
830out: 818out:
831 in6_ifa_put(ifp); 819 in6_ifa_put(ifp);
832} 820}
@@ -836,7 +824,7 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *i
836{ 824{
837 struct inet6_dev *idev = ifp->idev; 825 struct inet6_dev *idev = ifp->idev;
838 struct in6_addr addr, *tmpaddr; 826 struct in6_addr addr, *tmpaddr;
839 unsigned long tmp_prefered_lft, tmp_valid_lft, tmp_cstamp, tmp_tstamp; 827 unsigned long tmp_prefered_lft, tmp_valid_lft, tmp_cstamp, tmp_tstamp, age;
840 unsigned long regen_advance; 828 unsigned long regen_advance;
841 int tmp_plen; 829 int tmp_plen;
842 int ret = 0; 830 int ret = 0;
@@ -886,12 +874,13 @@ retry:
886 goto out; 874 goto out;
887 } 875 }
888 memcpy(&addr.s6_addr[8], idev->rndid, 8); 876 memcpy(&addr.s6_addr[8], idev->rndid, 8);
877 age = (jiffies - ifp->tstamp) / HZ;
889 tmp_valid_lft = min_t(__u32, 878 tmp_valid_lft = min_t(__u32,
890 ifp->valid_lft, 879 ifp->valid_lft,
891 idev->cnf.temp_valid_lft); 880 idev->cnf.temp_valid_lft + age);
892 tmp_prefered_lft = min_t(__u32, 881 tmp_prefered_lft = min_t(__u32,
893 ifp->prefered_lft, 882 ifp->prefered_lft,
894 idev->cnf.temp_prefered_lft - 883 idev->cnf.temp_prefered_lft + age -
895 idev->cnf.max_desync_factor); 884 idev->cnf.max_desync_factor);
896 tmp_plen = ifp->prefix_len; 885 tmp_plen = ifp->prefix_len;
897 max_addresses = idev->cnf.max_addresses; 886 max_addresses = idev->cnf.max_addresses;
@@ -1085,7 +1074,7 @@ static int ipv6_get_saddr_eval(struct net *net,
1085 case IPV6_SADDR_RULE_PRIVACY: 1074 case IPV6_SADDR_RULE_PRIVACY:
1086 { 1075 {
1087 /* Rule 7: Prefer public address 1076 /* Rule 7: Prefer public address
1088 * Note: prefer temprary address if use_tempaddr >= 2 1077 * Note: prefer temporary address if use_tempaddr >= 2
1089 */ 1078 */
1090 int preftmp = dst->prefs & (IPV6_PREFER_SRC_PUBLIC|IPV6_PREFER_SRC_TMP) ? 1079 int preftmp = dst->prefs & (IPV6_PREFER_SRC_PUBLIC|IPV6_PREFER_SRC_TMP) ?
1091 !!(dst->prefs & IPV6_PREFER_SRC_TMP) : 1080 !!(dst->prefs & IPV6_PREFER_SRC_TMP) :
@@ -1282,7 +1271,7 @@ static int ipv6_count_addresses(struct inet6_dev *idev)
1282 return cnt; 1271 return cnt;
1283} 1272}
1284 1273
1285int ipv6_chk_addr(struct net *net, struct in6_addr *addr, 1274int ipv6_chk_addr(struct net *net, const struct in6_addr *addr,
1286 struct net_device *dev, int strict) 1275 struct net_device *dev, int strict)
1287{ 1276{
1288 struct inet6_ifaddr *ifp; 1277 struct inet6_ifaddr *ifp;
@@ -1325,7 +1314,7 @@ static bool ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr,
1325 return false; 1314 return false;
1326} 1315}
1327 1316
1328int ipv6_chk_prefix(struct in6_addr *addr, struct net_device *dev) 1317int ipv6_chk_prefix(const struct in6_addr *addr, struct net_device *dev)
1329{ 1318{
1330 struct inet6_dev *idev; 1319 struct inet6_dev *idev;
1331 struct inet6_ifaddr *ifa; 1320 struct inet6_ifaddr *ifa;
@@ -1426,8 +1415,10 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp)
1426{ 1415{
1427 struct inet6_dev *idev = ifp->idev; 1416 struct inet6_dev *idev = ifp->idev;
1428 1417
1429 if (addrconf_dad_end(ifp)) 1418 if (addrconf_dad_end(ifp)) {
1419 in6_ifa_put(ifp);
1430 return; 1420 return;
1421 }
1431 1422
1432 if (net_ratelimit()) 1423 if (net_ratelimit())
1433 printk(KERN_INFO "%s: IPv6 duplicate address %pI6c detected!\n", 1424 printk(KERN_INFO "%s: IPv6 duplicate address %pI6c detected!\n",
@@ -1454,7 +1445,7 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp)
1454 1445
1455/* Join to solicited addr multicast group. */ 1446/* Join to solicited addr multicast group. */
1456 1447
1457void addrconf_join_solict(struct net_device *dev, struct in6_addr *addr) 1448void addrconf_join_solict(struct net_device *dev, const struct in6_addr *addr)
1458{ 1449{
1459 struct in6_addr maddr; 1450 struct in6_addr maddr;
1460 1451
@@ -1465,7 +1456,7 @@ void addrconf_join_solict(struct net_device *dev, struct in6_addr *addr)
1465 ipv6_dev_mc_inc(dev, &maddr); 1456 ipv6_dev_mc_inc(dev, &maddr);
1466} 1457}
1467 1458
1468void addrconf_leave_solict(struct inet6_dev *idev, struct in6_addr *addr) 1459void addrconf_leave_solict(struct inet6_dev *idev, const struct in6_addr *addr)
1469{ 1460{
1470 struct in6_addr maddr; 1461 struct in6_addr maddr;
1471 1462
@@ -1544,7 +1535,7 @@ static int addrconf_ifid_infiniband(u8 *eui, struct net_device *dev)
1544 return 0; 1535 return 0;
1545} 1536}
1546 1537
1547int __ipv6_isatap_ifid(u8 *eui, __be32 addr) 1538static int __ipv6_isatap_ifid(u8 *eui, __be32 addr)
1548{ 1539{
1549 if (addr == 0) 1540 if (addr == 0)
1550 return -1; 1541 return -1;
@@ -1560,7 +1551,6 @@ int __ipv6_isatap_ifid(u8 *eui, __be32 addr)
1560 memcpy(eui + 4, &addr, 4); 1551 memcpy(eui + 4, &addr, 4);
1561 return 0; 1552 return 0;
1562} 1553}
1563EXPORT_SYMBOL(__ipv6_isatap_ifid);
1564 1554
1565static int addrconf_ifid_sit(u8 *eui, struct net_device *dev) 1555static int addrconf_ifid_sit(u8 *eui, struct net_device *dev)
1566{ 1556{
@@ -1968,7 +1958,7 @@ ok:
1968 * to the stored lifetime since we'll 1958 * to the stored lifetime since we'll
1969 * be updating the timestamp below, 1959 * be updating the timestamp below,
1970 * else we'll set it back to the 1960 * else we'll set it back to the
1971 * minumum. 1961 * minimum.
1972 */ 1962 */
1973 if (prefered_lft != ifp->prefered_lft) { 1963 if (prefered_lft != ifp->prefered_lft) {
1974 valid_lft = stored_lft; 1964 valid_lft = stored_lft;
@@ -2022,10 +2012,11 @@ ok:
2022 ipv6_ifa_notify(0, ift); 2012 ipv6_ifa_notify(0, ift);
2023 } 2013 }
2024 2014
2025 if (create && in6_dev->cnf.use_tempaddr > 0) { 2015 if ((create || list_empty(&in6_dev->tempaddr_list)) && in6_dev->cnf.use_tempaddr > 0) {
2026 /* 2016 /*
2027 * When a new public address is created as described in [ADDRCONF], 2017 * When a new public address is created as described in [ADDRCONF],
2028 * also create a new temporary address. 2018 * also create a new temporary address. Also create a temporary
2019 * address if it's enabled but no temporary address currently exists.
2029 */ 2020 */
2030 read_unlock_bh(&in6_dev->lock); 2021 read_unlock_bh(&in6_dev->lock);
2031 ipv6_create_tempaddr(ifp, NULL); 2022 ipv6_create_tempaddr(ifp, NULL);
@@ -2110,7 +2101,7 @@ err_exit:
2110/* 2101/*
2111 * Manual configuration of address on an interface 2102 * Manual configuration of address on an interface
2112 */ 2103 */
2113static 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,
2114 unsigned int plen, __u8 ifa_flags, __u32 prefered_lft, 2105 unsigned int plen, __u8 ifa_flags, __u32 prefered_lft,
2115 __u32 valid_lft) 2106 __u32 valid_lft)
2116{ 2107{
@@ -2184,7 +2175,7 @@ static int inet6_addr_add(struct net *net, int ifindex, struct in6_addr *pfx,
2184 return PTR_ERR(ifp); 2175 return PTR_ERR(ifp);
2185} 2176}
2186 2177
2187static 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,
2188 unsigned int plen) 2179 unsigned int plen)
2189{ 2180{
2190 struct inet6_ifaddr *ifp; 2181 struct inet6_ifaddr *ifp;
@@ -2347,7 +2338,7 @@ static void init_loopback(struct net_device *dev)
2347 add_addr(idev, &in6addr_loopback, 128, IFA_HOST); 2338 add_addr(idev, &in6addr_loopback, 128, IFA_HOST);
2348} 2339}
2349 2340
2350static 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)
2351{ 2342{
2352 struct inet6_ifaddr * ifp; 2343 struct inet6_ifaddr * ifp;
2353 u32 addr_flags = IFA_F_PERMANENT; 2344 u32 addr_flags = IFA_F_PERMANENT;
@@ -2657,8 +2648,7 @@ static int addrconf_ifdown(struct net_device *dev, int how)
2657 struct net *net = dev_net(dev); 2648 struct net *net = dev_net(dev);
2658 struct inet6_dev *idev; 2649 struct inet6_dev *idev;
2659 struct inet6_ifaddr *ifa; 2650 struct inet6_ifaddr *ifa;
2660 LIST_HEAD(keep_list); 2651 int state, i;
2661 int state;
2662 2652
2663 ASSERT_RTNL(); 2653 ASSERT_RTNL();
2664 2654
@@ -2684,6 +2674,23 @@ static int addrconf_ifdown(struct net_device *dev, int how)
2684 2674
2685 } 2675 }
2686 2676
2677 /* Step 2: clear hash table */
2678 for (i = 0; i < IN6_ADDR_HSIZE; i++) {
2679 struct hlist_head *h = &inet6_addr_lst[i];
2680 struct hlist_node *n;
2681
2682 spin_lock_bh(&addrconf_hash_lock);
2683 restart:
2684 hlist_for_each_entry_rcu(ifa, n, h, addr_lst) {
2685 if (ifa->idev == idev) {
2686 hlist_del_init_rcu(&ifa->addr_lst);
2687 addrconf_del_timer(ifa);
2688 goto restart;
2689 }
2690 }
2691 spin_unlock_bh(&addrconf_hash_lock);
2692 }
2693
2687 write_lock_bh(&idev->lock); 2694 write_lock_bh(&idev->lock);
2688 2695
2689 /* Step 2: clear flags for stateless addrconf */ 2696 /* Step 2: clear flags for stateless addrconf */
@@ -2717,61 +2724,24 @@ static int addrconf_ifdown(struct net_device *dev, int how)
2717 struct inet6_ifaddr, if_list); 2724 struct inet6_ifaddr, if_list);
2718 addrconf_del_timer(ifa); 2725 addrconf_del_timer(ifa);
2719 2726
2720 /* If just doing link down, and address is permanent 2727 list_del(&ifa->if_list);
2721 and not link-local, then retain it. */
2722 if (!how &&
2723 (ifa->flags&IFA_F_PERMANENT) &&
2724 !(ipv6_addr_type(&ifa->addr) & IPV6_ADDR_LINKLOCAL)) {
2725 list_move_tail(&ifa->if_list, &keep_list);
2726
2727 /* If not doing DAD on this address, just keep it. */
2728 if ((dev->flags&(IFF_NOARP|IFF_LOOPBACK)) ||
2729 idev->cnf.accept_dad <= 0 ||
2730 (ifa->flags & IFA_F_NODAD))
2731 continue;
2732
2733 /* If it was tentative already, no need to notify */
2734 if (ifa->flags & IFA_F_TENTATIVE)
2735 continue;
2736 2728
2737 /* Flag it for later restoration when link comes up */ 2729 write_unlock_bh(&idev->lock);
2738 ifa->flags |= IFA_F_TENTATIVE;
2739 ifa->state = INET6_IFADDR_STATE_DAD;
2740
2741 write_unlock_bh(&idev->lock);
2742
2743 in6_ifa_hold(ifa);
2744 } else {
2745 list_del(&ifa->if_list);
2746
2747 /* clear hash table */
2748 spin_lock_bh(&addrconf_hash_lock);
2749 hlist_del_init_rcu(&ifa->addr_lst);
2750 spin_unlock_bh(&addrconf_hash_lock);
2751 2730
2752 write_unlock_bh(&idev->lock); 2731 spin_lock_bh(&ifa->state_lock);
2753 spin_lock_bh(&ifa->state_lock); 2732 state = ifa->state;
2754 state = ifa->state; 2733 ifa->state = INET6_IFADDR_STATE_DEAD;
2755 ifa->state = INET6_IFADDR_STATE_DEAD; 2734 spin_unlock_bh(&ifa->state_lock);
2756 spin_unlock_bh(&ifa->state_lock);
2757 2735
2758 if (state == INET6_IFADDR_STATE_DEAD) 2736 if (state != INET6_IFADDR_STATE_DEAD) {
2759 goto put_ifa; 2737 __ipv6_ifa_notify(RTM_DELADDR, ifa);
2738 atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifa);
2760 } 2739 }
2761
2762 __ipv6_ifa_notify(RTM_DELADDR, ifa);
2763 if (ifa->state == INET6_IFADDR_STATE_DEAD)
2764 atomic_notifier_call_chain(&inet6addr_chain,
2765 NETDEV_DOWN, ifa);
2766
2767put_ifa:
2768 in6_ifa_put(ifa); 2740 in6_ifa_put(ifa);
2769 2741
2770 write_lock_bh(&idev->lock); 2742 write_lock_bh(&idev->lock);
2771 } 2743 }
2772 2744
2773 list_splice(&keep_list, &idev->addr_list);
2774
2775 write_unlock_bh(&idev->lock); 2745 write_unlock_bh(&idev->lock);
2776 2746
2777 /* Step 5: Discard multicast list */ 2747 /* Step 5: Discard multicast list */
@@ -2964,7 +2934,8 @@ static void addrconf_dad_completed(struct inet6_ifaddr *ifp)
2964 start sending router solicitations. 2934 start sending router solicitations.
2965 */ 2935 */
2966 2936
2967 if (ifp->idev->cnf.forwarding == 0 && 2937 if ((ifp->idev->cnf.forwarding == 0 ||
2938 ifp->idev->cnf.forwarding == 2) &&
2968 ifp->idev->cnf.rtr_solicits > 0 && 2939 ifp->idev->cnf.rtr_solicits > 0 &&
2969 (dev->flags&IFF_LOOPBACK) == 0 && 2940 (dev->flags&IFF_LOOPBACK) == 0 &&
2970 (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) { 2941 (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) {
@@ -3138,7 +3109,7 @@ void if6_proc_exit(void)
3138 3109
3139#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) 3110#if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
3140/* Check if address is a home address configured on any interface. */ 3111/* Check if address is a home address configured on any interface. */
3141int ipv6_chk_home_addr(struct net *net, struct in6_addr *addr) 3112int ipv6_chk_home_addr(struct net *net, const struct in6_addr *addr)
3142{ 3113{
3143 int ret = 0; 3114 int ret = 0;
3144 struct inet6_ifaddr *ifp = NULL; 3115 struct inet6_ifaddr *ifp = NULL;
@@ -3448,10 +3419,8 @@ static int put_cacheinfo(struct sk_buff *skb, unsigned long cstamp,
3448{ 3419{
3449 struct ifa_cacheinfo ci; 3420 struct ifa_cacheinfo ci;
3450 3421
3451 ci.cstamp = (u32)(TIME_DELTA(cstamp, INITIAL_JIFFIES) / HZ * 100 3422 ci.cstamp = cstamp_delta(cstamp);
3452 + TIME_DELTA(cstamp, INITIAL_JIFFIES) % HZ * 100 / HZ); 3423 ci.tstamp = cstamp_delta(tstamp);
3453 ci.tstamp = (u32)(TIME_DELTA(tstamp, INITIAL_JIFFIES) / HZ * 100
3454 + TIME_DELTA(tstamp, INITIAL_JIFFIES) % HZ * 100 / HZ);
3455 ci.ifa_prefered = preferred; 3424 ci.ifa_prefered = preferred;
3456 ci.ifa_valid = valid; 3425 ci.ifa_valid = valid;
3457 3426
@@ -3802,8 +3771,10 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
3802 array[DEVCONF_AUTOCONF] = cnf->autoconf; 3771 array[DEVCONF_AUTOCONF] = cnf->autoconf;
3803 array[DEVCONF_DAD_TRANSMITS] = cnf->dad_transmits; 3772 array[DEVCONF_DAD_TRANSMITS] = cnf->dad_transmits;
3804 array[DEVCONF_RTR_SOLICITS] = cnf->rtr_solicits; 3773 array[DEVCONF_RTR_SOLICITS] = cnf->rtr_solicits;
3805 array[DEVCONF_RTR_SOLICIT_INTERVAL] = cnf->rtr_solicit_interval; 3774 array[DEVCONF_RTR_SOLICIT_INTERVAL] =
3806 array[DEVCONF_RTR_SOLICIT_DELAY] = cnf->rtr_solicit_delay; 3775 jiffies_to_msecs(cnf->rtr_solicit_interval);
3776 array[DEVCONF_RTR_SOLICIT_DELAY] =
3777 jiffies_to_msecs(cnf->rtr_solicit_delay);
3807 array[DEVCONF_FORCE_MLD_VERSION] = cnf->force_mld_version; 3778 array[DEVCONF_FORCE_MLD_VERSION] = cnf->force_mld_version;
3808#ifdef CONFIG_IPV6_PRIVACY 3779#ifdef CONFIG_IPV6_PRIVACY
3809 array[DEVCONF_USE_TEMPADDR] = cnf->use_tempaddr; 3780 array[DEVCONF_USE_TEMPADDR] = cnf->use_tempaddr;
@@ -3817,7 +3788,8 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
3817 array[DEVCONF_ACCEPT_RA_PINFO] = cnf->accept_ra_pinfo; 3788 array[DEVCONF_ACCEPT_RA_PINFO] = cnf->accept_ra_pinfo;
3818#ifdef CONFIG_IPV6_ROUTER_PREF 3789#ifdef CONFIG_IPV6_ROUTER_PREF
3819 array[DEVCONF_ACCEPT_RA_RTR_PREF] = cnf->accept_ra_rtr_pref; 3790 array[DEVCONF_ACCEPT_RA_RTR_PREF] = cnf->accept_ra_rtr_pref;
3820 array[DEVCONF_RTR_PROBE_INTERVAL] = cnf->rtr_probe_interval; 3791 array[DEVCONF_RTR_PROBE_INTERVAL] =
3792 jiffies_to_msecs(cnf->rtr_probe_interval);
3821#ifdef CONFIG_IPV6_ROUTE_INFO 3793#ifdef CONFIG_IPV6_ROUTE_INFO
3822 array[DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN] = cnf->accept_ra_rt_info_max_plen; 3794 array[DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN] = cnf->accept_ra_rt_info_max_plen;
3823#endif 3795#endif
@@ -3835,6 +3807,15 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
3835 array[DEVCONF_FORCE_TLLAO] = cnf->force_tllao; 3807 array[DEVCONF_FORCE_TLLAO] = cnf->force_tllao;
3836} 3808}
3837 3809
3810static inline size_t inet6_ifla6_size(void)
3811{
3812 return nla_total_size(4) /* IFLA_INET6_FLAGS */
3813 + nla_total_size(sizeof(struct ifla_cacheinfo))
3814 + nla_total_size(DEVCONF_MAX * 4) /* IFLA_INET6_CONF */
3815 + nla_total_size(IPSTATS_MIB_MAX * 8) /* IFLA_INET6_STATS */
3816 + nla_total_size(ICMP6_MIB_MAX * 8); /* IFLA_INET6_ICMP6STATS */
3817}
3818
3838static inline size_t inet6_if_nlmsg_size(void) 3819static inline size_t inet6_if_nlmsg_size(void)
3839{ 3820{
3840 return NLMSG_ALIGN(sizeof(struct ifinfomsg)) 3821 return NLMSG_ALIGN(sizeof(struct ifinfomsg))
@@ -3842,16 +3823,10 @@ static inline size_t inet6_if_nlmsg_size(void)
3842 + nla_total_size(MAX_ADDR_LEN) /* IFLA_ADDRESS */ 3823 + nla_total_size(MAX_ADDR_LEN) /* IFLA_ADDRESS */
3843 + nla_total_size(4) /* IFLA_MTU */ 3824 + nla_total_size(4) /* IFLA_MTU */
3844 + nla_total_size(4) /* IFLA_LINK */ 3825 + nla_total_size(4) /* IFLA_LINK */
3845 + nla_total_size( /* IFLA_PROTINFO */ 3826 + nla_total_size(inet6_ifla6_size()); /* IFLA_PROTINFO */
3846 nla_total_size(4) /* IFLA_INET6_FLAGS */
3847 + nla_total_size(sizeof(struct ifla_cacheinfo))
3848 + nla_total_size(DEVCONF_MAX * 4) /* IFLA_INET6_CONF */
3849 + nla_total_size(IPSTATS_MIB_MAX * 8) /* IFLA_INET6_STATS */
3850 + nla_total_size(ICMP6_MIB_MAX * 8) /* IFLA_INET6_ICMP6STATS */
3851 );
3852} 3827}
3853 3828
3854static inline void __snmp6_fill_stats(u64 *stats, void __percpu **mib, 3829static inline void __snmp6_fill_statsdev(u64 *stats, atomic_long_t *mib,
3855 int items, int bytes) 3830 int items, int bytes)
3856{ 3831{
3857 int i; 3832 int i;
@@ -3861,7 +3836,7 @@ static inline void __snmp6_fill_stats(u64 *stats, void __percpu **mib,
3861 /* Use put_unaligned() because stats may not be aligned for u64. */ 3836 /* Use put_unaligned() because stats may not be aligned for u64. */
3862 put_unaligned(items, &stats[0]); 3837 put_unaligned(items, &stats[0]);
3863 for (i = 1; i < items; i++) 3838 for (i = 1; i < items; i++)
3864 put_unaligned(snmp_fold_field(mib, i), &stats[i]); 3839 put_unaligned(atomic_long_read(&mib[i]), &stats[i]);
3865 3840
3866 memset(&stats[items], 0, pad); 3841 memset(&stats[items], 0, pad);
3867} 3842}
@@ -3890,20 +3865,75 @@ static void snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype,
3890 IPSTATS_MIB_MAX, bytes, offsetof(struct ipstats_mib, syncp)); 3865 IPSTATS_MIB_MAX, bytes, offsetof(struct ipstats_mib, syncp));
3891 break; 3866 break;
3892 case IFLA_INET6_ICMP6STATS: 3867 case IFLA_INET6_ICMP6STATS:
3893 __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);
3894 break; 3869 break;
3895 } 3870 }
3896} 3871}
3897 3872
3873static int inet6_fill_ifla6_attrs(struct sk_buff *skb, struct inet6_dev *idev)
3874{
3875 struct nlattr *nla;
3876 struct ifla_cacheinfo ci;
3877
3878 NLA_PUT_U32(skb, IFLA_INET6_FLAGS, idev->if_flags);
3879
3880 ci.max_reasm_len = IPV6_MAXPLEN;
3881 ci.tstamp = cstamp_delta(idev->tstamp);
3882 ci.reachable_time = jiffies_to_msecs(idev->nd_parms->reachable_time);
3883 ci.retrans_time = jiffies_to_msecs(idev->nd_parms->retrans_time);
3884 NLA_PUT(skb, IFLA_INET6_CACHEINFO, sizeof(ci), &ci);
3885
3886 nla = nla_reserve(skb, IFLA_INET6_CONF, DEVCONF_MAX * sizeof(s32));
3887 if (nla == NULL)
3888 goto nla_put_failure;
3889 ipv6_store_devconf(&idev->cnf, nla_data(nla), nla_len(nla));
3890
3891 /* XXX - MC not implemented */
3892
3893 nla = nla_reserve(skb, IFLA_INET6_STATS, IPSTATS_MIB_MAX * sizeof(u64));
3894 if (nla == NULL)
3895 goto nla_put_failure;
3896 snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_STATS, nla_len(nla));
3897
3898 nla = nla_reserve(skb, IFLA_INET6_ICMP6STATS, ICMP6_MIB_MAX * sizeof(u64));
3899 if (nla == NULL)
3900 goto nla_put_failure;
3901 snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_ICMP6STATS, nla_len(nla));
3902
3903 return 0;
3904
3905nla_put_failure:
3906 return -EMSGSIZE;
3907}
3908
3909static size_t inet6_get_link_af_size(const struct net_device *dev)
3910{
3911 if (!__in6_dev_get(dev))
3912 return 0;
3913
3914 return inet6_ifla6_size();
3915}
3916
3917static int inet6_fill_link_af(struct sk_buff *skb, const struct net_device *dev)
3918{
3919 struct inet6_dev *idev = __in6_dev_get(dev);
3920
3921 if (!idev)
3922 return -ENODATA;
3923
3924 if (inet6_fill_ifla6_attrs(skb, idev) < 0)
3925 return -EMSGSIZE;
3926
3927 return 0;
3928}
3929
3898static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev, 3930static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
3899 u32 pid, u32 seq, int event, unsigned int flags) 3931 u32 pid, u32 seq, int event, unsigned int flags)
3900{ 3932{
3901 struct net_device *dev = idev->dev; 3933 struct net_device *dev = idev->dev;
3902 struct nlattr *nla;
3903 struct ifinfomsg *hdr; 3934 struct ifinfomsg *hdr;
3904 struct nlmsghdr *nlh; 3935 struct nlmsghdr *nlh;
3905 void *protoinfo; 3936 void *protoinfo;
3906 struct ifla_cacheinfo ci;
3907 3937
3908 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*hdr), flags); 3938 nlh = nlmsg_put(skb, pid, seq, event, sizeof(*hdr), flags);
3909 if (nlh == NULL) 3939 if (nlh == NULL)
@@ -3930,31 +3960,8 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
3930 if (protoinfo == NULL) 3960 if (protoinfo == NULL)
3931 goto nla_put_failure; 3961 goto nla_put_failure;
3932 3962
3933 NLA_PUT_U32(skb, IFLA_INET6_FLAGS, idev->if_flags); 3963 if (inet6_fill_ifla6_attrs(skb, idev) < 0)
3934
3935 ci.max_reasm_len = IPV6_MAXPLEN;
3936 ci.tstamp = (__u32)(TIME_DELTA(idev->tstamp, INITIAL_JIFFIES) / HZ * 100
3937 + TIME_DELTA(idev->tstamp, INITIAL_JIFFIES) % HZ * 100 / HZ);
3938 ci.reachable_time = idev->nd_parms->reachable_time;
3939 ci.retrans_time = idev->nd_parms->retrans_time;
3940 NLA_PUT(skb, IFLA_INET6_CACHEINFO, sizeof(ci), &ci);
3941
3942 nla = nla_reserve(skb, IFLA_INET6_CONF, DEVCONF_MAX * sizeof(s32));
3943 if (nla == NULL)
3944 goto nla_put_failure;
3945 ipv6_store_devconf(&idev->cnf, nla_data(nla), nla_len(nla));
3946
3947 /* XXX - MC not implemented */
3948
3949 nla = nla_reserve(skb, IFLA_INET6_STATS, IPSTATS_MIB_MAX * sizeof(u64));
3950 if (nla == NULL)
3951 goto nla_put_failure;
3952 snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_STATS, nla_len(nla));
3953
3954 nla = nla_reserve(skb, IFLA_INET6_ICMP6STATS, ICMP6_MIB_MAX * sizeof(u64));
3955 if (nla == NULL)
3956 goto nla_put_failure; 3964 goto nla_put_failure;
3957 snmp6_fill_stats(nla_data(nla), idev, IFLA_INET6_ICMP6STATS, nla_len(nla));
3958 3965
3959 nla_nest_end(skb, protoinfo); 3966 nla_nest_end(skb, protoinfo);
3960 return nlmsg_end(skb, nlh); 3967 return nlmsg_end(skb, nlh);
@@ -4021,11 +4028,11 @@ void inet6_ifinfo_notify(int event, struct inet6_dev *idev)
4021 kfree_skb(skb); 4028 kfree_skb(skb);
4022 goto errout; 4029 goto errout;
4023 } 4030 }
4024 rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFADDR, NULL, GFP_ATOMIC); 4031 rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IFINFO, NULL, GFP_ATOMIC);
4025 return; 4032 return;
4026errout: 4033errout:
4027 if (err < 0) 4034 if (err < 0)
4028 rtnl_set_sk_err(net, RTNLGRP_IPV6_IFADDR, err); 4035 rtnl_set_sk_err(net, RTNLGRP_IPV6_IFINFO, err);
4029} 4036}
4030 4037
4031static inline size_t inet6_prefix_nlmsg_size(void) 4038static inline size_t inet6_prefix_nlmsg_size(void)
@@ -4122,8 +4129,7 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
4122 addrconf_leave_solict(ifp->idev, &ifp->addr); 4129 addrconf_leave_solict(ifp->idev, &ifp->addr);
4123 dst_hold(&ifp->rt->dst); 4130 dst_hold(&ifp->rt->dst);
4124 4131
4125 if (ifp->state == INET6_IFADDR_STATE_DEAD && 4132 if (ip6_del_rt(ifp->rt))
4126 ip6_del_rt(ifp->rt))
4127 dst_free(&ifp->rt->dst); 4133 dst_free(&ifp->rt->dst);
4128 break; 4134 break;
4129 } 4135 }
@@ -4521,7 +4527,7 @@ static void __addrconf_sysctl_unregister(struct ipv6_devconf *p)
4521 4527
4522 t = p->sysctl; 4528 t = p->sysctl;
4523 p->sysctl = NULL; 4529 p->sysctl = NULL;
4524 unregister_sysctl_table(t->sysctl_header); 4530 unregister_net_sysctl_table(t->sysctl_header);
4525 kfree(t->dev_name); 4531 kfree(t->dev_name);
4526 kfree(t); 4532 kfree(t);
4527} 4533}
@@ -4625,6 +4631,12 @@ int unregister_inet6addr_notifier(struct notifier_block *nb)
4625} 4631}
4626EXPORT_SYMBOL(unregister_inet6addr_notifier); 4632EXPORT_SYMBOL(unregister_inet6addr_notifier);
4627 4633
4634static struct rtnl_af_ops inet6_ops = {
4635 .family = AF_INET6,
4636 .fill_link_af = inet6_fill_link_af,
4637 .get_link_af_size = inet6_get_link_af_size,
4638};
4639
4628/* 4640/*
4629 * Init / cleanup code 4641 * Init / cleanup code
4630 */ 4642 */
@@ -4676,6 +4688,10 @@ int __init addrconf_init(void)
4676 4688
4677 addrconf_verify(0); 4689 addrconf_verify(0);
4678 4690
4691 err = rtnl_af_register(&inet6_ops);
4692 if (err < 0)
4693 goto errout_af;
4694
4679 err = __rtnl_register(PF_INET6, RTM_GETLINK, NULL, inet6_dump_ifinfo); 4695 err = __rtnl_register(PF_INET6, RTM_GETLINK, NULL, inet6_dump_ifinfo);
4680 if (err < 0) 4696 if (err < 0)
4681 goto errout; 4697 goto errout;
@@ -4691,6 +4707,8 @@ int __init addrconf_init(void)
4691 4707
4692 return 0; 4708 return 0;
4693errout: 4709errout:
4710 rtnl_af_unregister(&inet6_ops);
4711errout_af:
4694 unregister_netdevice_notifier(&ipv6_dev_notf); 4712 unregister_netdevice_notifier(&ipv6_dev_notf);
4695errlo: 4713errlo:
4696 unregister_pernet_subsys(&addrconf_ops); 4714 unregister_pernet_subsys(&addrconf_ops);
@@ -4711,6 +4729,8 @@ void addrconf_cleanup(void)
4711 4729
4712 rtnl_lock(); 4730 rtnl_lock();
4713 4731
4732 __rtnl_af_unregister(&inet6_ops);
4733
4714 /* clean dev list */ 4734 /* clean dev list */
4715 for_each_netdev(&init_net, dev) { 4735 for_each_netdev(&init_net, dev) {
4716 if (__in6_dev_get(dev) == NULL) 4736 if (__in6_dev_get(dev) == NULL)