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.c52
1 files changed, 24 insertions, 28 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index e048ec62d109..23cc8e1ce8d4 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)
@@ -2740,10 +2744,6 @@ static int addrconf_ifdown(struct net_device *dev, int how)
2740 /* Flag it for later restoration when link comes up */ 2744 /* Flag it for later restoration when link comes up */
2741 ifa->flags |= IFA_F_TENTATIVE; 2745 ifa->flags |= IFA_F_TENTATIVE;
2742 ifa->state = INET6_IFADDR_STATE_DAD; 2746 ifa->state = INET6_IFADDR_STATE_DAD;
2743
2744 write_unlock_bh(&idev->lock);
2745
2746 in6_ifa_hold(ifa);
2747 } else { 2747 } else {
2748 list_del(&ifa->if_list); 2748 list_del(&ifa->if_list);
2749 2749
@@ -2758,19 +2758,15 @@ static int addrconf_ifdown(struct net_device *dev, int how)
2758 ifa->state = INET6_IFADDR_STATE_DEAD; 2758 ifa->state = INET6_IFADDR_STATE_DEAD;
2759 spin_unlock_bh(&ifa->state_lock); 2759 spin_unlock_bh(&ifa->state_lock);
2760 2760
2761 if (state == INET6_IFADDR_STATE_DEAD) 2761 if (state != INET6_IFADDR_STATE_DEAD) {
2762 goto put_ifa; 2762 __ipv6_ifa_notify(RTM_DELADDR, ifa);
2763 } 2763 atomic_notifier_call_chain(&inet6addr_chain,
2764 2764 NETDEV_DOWN, ifa);
2765 __ipv6_ifa_notify(RTM_DELADDR, ifa); 2765 }
2766 if (ifa->state == INET6_IFADDR_STATE_DEAD)
2767 atomic_notifier_call_chain(&inet6addr_chain,
2768 NETDEV_DOWN, ifa);
2769
2770put_ifa:
2771 in6_ifa_put(ifa);
2772 2766
2773 write_lock_bh(&idev->lock); 2767 in6_ifa_put(ifa);
2768 write_lock_bh(&idev->lock);
2769 }
2774 } 2770 }
2775 2771
2776 list_splice(&keep_list, &idev->addr_list); 2772 list_splice(&keep_list, &idev->addr_list);
@@ -3452,10 +3448,8 @@ static int put_cacheinfo(struct sk_buff *skb, unsigned long cstamp,
3452{ 3448{
3453 struct ifa_cacheinfo ci; 3449 struct ifa_cacheinfo ci;
3454 3450
3455 ci.cstamp = (u32)(TIME_DELTA(cstamp, INITIAL_JIFFIES) / HZ * 100 3451 ci.cstamp = cstamp_delta(cstamp);
3456 + TIME_DELTA(cstamp, INITIAL_JIFFIES) % HZ * 100 / HZ); 3452 ci.tstamp = cstamp_delta(tstamp);
3457 ci.tstamp = (u32)(TIME_DELTA(tstamp, INITIAL_JIFFIES) / HZ * 100
3458 + TIME_DELTA(tstamp, INITIAL_JIFFIES) % HZ * 100 / HZ);
3459 ci.ifa_prefered = preferred; 3453 ci.ifa_prefered = preferred;
3460 ci.ifa_valid = valid; 3454 ci.ifa_valid = valid;
3461 3455
@@ -3806,8 +3800,10 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
3806 array[DEVCONF_AUTOCONF] = cnf->autoconf; 3800 array[DEVCONF_AUTOCONF] = cnf->autoconf;
3807 array[DEVCONF_DAD_TRANSMITS] = cnf->dad_transmits; 3801 array[DEVCONF_DAD_TRANSMITS] = cnf->dad_transmits;
3808 array[DEVCONF_RTR_SOLICITS] = cnf->rtr_solicits; 3802 array[DEVCONF_RTR_SOLICITS] = cnf->rtr_solicits;
3809 array[DEVCONF_RTR_SOLICIT_INTERVAL] = cnf->rtr_solicit_interval; 3803 array[DEVCONF_RTR_SOLICIT_INTERVAL] =
3810 array[DEVCONF_RTR_SOLICIT_DELAY] = cnf->rtr_solicit_delay; 3804 jiffies_to_msecs(cnf->rtr_solicit_interval);
3805 array[DEVCONF_RTR_SOLICIT_DELAY] =
3806 jiffies_to_msecs(cnf->rtr_solicit_delay);
3811 array[DEVCONF_FORCE_MLD_VERSION] = cnf->force_mld_version; 3807 array[DEVCONF_FORCE_MLD_VERSION] = cnf->force_mld_version;
3812#ifdef CONFIG_IPV6_PRIVACY 3808#ifdef CONFIG_IPV6_PRIVACY
3813 array[DEVCONF_USE_TEMPADDR] = cnf->use_tempaddr; 3809 array[DEVCONF_USE_TEMPADDR] = cnf->use_tempaddr;
@@ -3821,7 +3817,8 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
3821 array[DEVCONF_ACCEPT_RA_PINFO] = cnf->accept_ra_pinfo; 3817 array[DEVCONF_ACCEPT_RA_PINFO] = cnf->accept_ra_pinfo;
3822#ifdef CONFIG_IPV6_ROUTER_PREF 3818#ifdef CONFIG_IPV6_ROUTER_PREF
3823 array[DEVCONF_ACCEPT_RA_RTR_PREF] = cnf->accept_ra_rtr_pref; 3819 array[DEVCONF_ACCEPT_RA_RTR_PREF] = cnf->accept_ra_rtr_pref;
3824 array[DEVCONF_RTR_PROBE_INTERVAL] = cnf->rtr_probe_interval; 3820 array[DEVCONF_RTR_PROBE_INTERVAL] =
3821 jiffies_to_msecs(cnf->rtr_probe_interval);
3825#ifdef CONFIG_IPV6_ROUTE_INFO 3822#ifdef CONFIG_IPV6_ROUTE_INFO
3826 array[DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN] = cnf->accept_ra_rt_info_max_plen; 3823 array[DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN] = cnf->accept_ra_rt_info_max_plen;
3827#endif 3824#endif
@@ -3937,10 +3934,9 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
3937 NLA_PUT_U32(skb, IFLA_INET6_FLAGS, idev->if_flags); 3934 NLA_PUT_U32(skb, IFLA_INET6_FLAGS, idev->if_flags);
3938 3935
3939 ci.max_reasm_len = IPV6_MAXPLEN; 3936 ci.max_reasm_len = IPV6_MAXPLEN;
3940 ci.tstamp = (__u32)(TIME_DELTA(idev->tstamp, INITIAL_JIFFIES) / HZ * 100 3937 ci.tstamp = cstamp_delta(idev->tstamp);
3941 + TIME_DELTA(idev->tstamp, INITIAL_JIFFIES) % HZ * 100 / HZ); 3938 ci.reachable_time = jiffies_to_msecs(idev->nd_parms->reachable_time);
3942 ci.reachable_time = idev->nd_parms->reachable_time; 3939 ci.retrans_time = jiffies_to_msecs(idev->nd_parms->retrans_time);
3943 ci.retrans_time = idev->nd_parms->retrans_time;
3944 NLA_PUT(skb, IFLA_INET6_CACHEINFO, sizeof(ci), &ci); 3940 NLA_PUT(skb, IFLA_INET6_CACHEINFO, sizeof(ci), &ci);
3945 3941
3946 nla = nla_reserve(skb, IFLA_INET6_CONF, DEVCONF_MAX * sizeof(s32)); 3942 nla = nla_reserve(skb, IFLA_INET6_CONF, DEVCONF_MAX * sizeof(s32));