git.openpandora.org
/
pandora-kernel.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
ipv6: fix nl group when advertising a new link
[pandora-kernel.git]
/
net
/
ipv6
/
addrconf.c
diff --git
a/net/ipv6/addrconf.c
b/net/ipv6/addrconf.c
index
ec7a91d
..
93b7a93
100644
(file)
--- a/
net/ipv6/addrconf.c
+++ b/
net/ipv6/addrconf.c
@@
-98,7
+98,11
@@
#endif
#define INFINITY_LIFE_TIME 0xFFFFFFFF
#endif
#define INFINITY_LIFE_TIME 0xFFFFFFFF
-#define TIME_DELTA(a, b) ((unsigned long)((long)(a) - (long)(b)))
+
+static inline u32 cstamp_delta(unsigned long cstamp)
+{
+ return (cstamp - INITIAL_JIFFIES) * 100UL / HZ;
+}
#define ADDRCONF_TIMER_FUZZ_MINUS (HZ > 50 ? HZ/50 : 1)
#define ADDRCONF_TIMER_FUZZ (HZ / 4)
#define ADDRCONF_TIMER_FUZZ_MINUS (HZ > 50 ? HZ/50 : 1)
#define ADDRCONF_TIMER_FUZZ (HZ / 4)
@@
-836,7
+840,7
@@
static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *i
{
struct inet6_dev *idev = ifp->idev;
struct in6_addr addr, *tmpaddr;
{
struct inet6_dev *idev = ifp->idev;
struct in6_addr addr, *tmpaddr;
- unsigned long tmp_prefered_lft, tmp_valid_lft, tmp_cstamp, tmp_tstamp;
+ unsigned long tmp_prefered_lft, tmp_valid_lft, tmp_cstamp, tmp_tstamp
, age
;
unsigned long regen_advance;
int tmp_plen;
int ret = 0;
unsigned long regen_advance;
int tmp_plen;
int ret = 0;
@@
-886,12
+890,13
@@
retry:
goto out;
}
memcpy(&addr.s6_addr[8], idev->rndid, 8);
goto out;
}
memcpy(&addr.s6_addr[8], idev->rndid, 8);
+ age = (jiffies - ifp->tstamp) / HZ;
tmp_valid_lft = min_t(__u32,
ifp->valid_lft,
tmp_valid_lft = min_t(__u32,
ifp->valid_lft,
- idev->cnf.temp_valid_lft);
+ idev->cnf.temp_valid_lft
+ age
);
tmp_prefered_lft = min_t(__u32,
ifp->prefered_lft,
tmp_prefered_lft = min_t(__u32,
ifp->prefered_lft,
- idev->cnf.temp_prefered_lft -
+ idev->cnf.temp_prefered_lft
+ age
-
idev->cnf.max_desync_factor);
tmp_plen = ifp->prefix_len;
max_addresses = idev->cnf.max_addresses;
idev->cnf.max_desync_factor);
tmp_plen = ifp->prefix_len;
max_addresses = idev->cnf.max_addresses;
@@
-1426,8
+1431,10
@@
void addrconf_dad_failure(struct inet6_ifaddr *ifp)
{
struct inet6_dev *idev = ifp->idev;
{
struct inet6_dev *idev = ifp->idev;
- if (addrconf_dad_end(ifp))
+ if (addrconf_dad_end(ifp)) {
+ in6_ifa_put(ifp);
return;
return;
+ }
if (net_ratelimit())
printk(KERN_INFO "%s: IPv6 duplicate address %pI6c detected!\n",
if (net_ratelimit())
printk(KERN_INFO "%s: IPv6 duplicate address %pI6c detected!\n",
@@
-2021,10
+2028,11
@@
ok:
ipv6_ifa_notify(0, ift);
}
ipv6_ifa_notify(0, ift);
}
- if (
create
&& in6_dev->cnf.use_tempaddr > 0) {
+ if (
(create || list_empty(&in6_dev->tempaddr_list))
&& in6_dev->cnf.use_tempaddr > 0) {
/*
* When a new public address is created as described in [ADDRCONF],
/*
* When a new public address is created as described in [ADDRCONF],
- * also create a new temporary address.
+ * also create a new temporary address. Also create a temporary
+ * address if it's enabled but no temporary address currently exists.
*/
read_unlock_bh(&in6_dev->lock);
ipv6_create_tempaddr(ifp, NULL);
*/
read_unlock_bh(&in6_dev->lock);
ipv6_create_tempaddr(ifp, NULL);
@@
-2736,10
+2744,6
@@
static int addrconf_ifdown(struct net_device *dev, int how)
/* Flag it for later restoration when link comes up */
ifa->flags |= IFA_F_TENTATIVE;
ifa->state = INET6_IFADDR_STATE_DAD;
/* Flag it for later restoration when link comes up */
ifa->flags |= IFA_F_TENTATIVE;
ifa->state = INET6_IFADDR_STATE_DAD;
-
- write_unlock_bh(&idev->lock);
-
- in6_ifa_hold(ifa);
} else {
list_del(&ifa->if_list);
} else {
list_del(&ifa->if_list);
@@
-2754,19
+2758,15
@@
static int addrconf_ifdown(struct net_device *dev, int how)
ifa->state = INET6_IFADDR_STATE_DEAD;
spin_unlock_bh(&ifa->state_lock);
ifa->state = INET6_IFADDR_STATE_DEAD;
spin_unlock_bh(&ifa->state_lock);
- if (state == INET6_IFADDR_STATE_DEAD)
- goto put_ifa;
- }
-
- __ipv6_ifa_notify(RTM_DELADDR, ifa);
- if (ifa->state == INET6_IFADDR_STATE_DEAD)
- atomic_notifier_call_chain(&inet6addr_chain,
- NETDEV_DOWN, ifa);
-
-put_ifa:
- in6_ifa_put(ifa);
+ if (state != INET6_IFADDR_STATE_DEAD) {
+ __ipv6_ifa_notify(RTM_DELADDR, ifa);
+ atomic_notifier_call_chain(&inet6addr_chain,
+ NETDEV_DOWN, ifa);
+ }
- write_lock_bh(&idev->lock);
+ in6_ifa_put(ifa);
+ write_lock_bh(&idev->lock);
+ }
}
list_splice(&keep_list, &idev->addr_list);
}
list_splice(&keep_list, &idev->addr_list);
@@
-3448,10
+3448,8
@@
static int put_cacheinfo(struct sk_buff *skb, unsigned long cstamp,
{
struct ifa_cacheinfo ci;
{
struct ifa_cacheinfo ci;
- ci.cstamp = (u32)(TIME_DELTA(cstamp, INITIAL_JIFFIES) / HZ * 100
- + TIME_DELTA(cstamp, INITIAL_JIFFIES) % HZ * 100 / HZ);
- ci.tstamp = (u32)(TIME_DELTA(tstamp, INITIAL_JIFFIES) / HZ * 100
- + TIME_DELTA(tstamp, INITIAL_JIFFIES) % HZ * 100 / HZ);
+ ci.cstamp = cstamp_delta(cstamp);
+ ci.tstamp = cstamp_delta(tstamp);
ci.ifa_prefered = preferred;
ci.ifa_valid = valid;
ci.ifa_prefered = preferred;
ci.ifa_valid = valid;
@@
-3802,8
+3800,10
@@
static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
array[DEVCONF_AUTOCONF] = cnf->autoconf;
array[DEVCONF_DAD_TRANSMITS] = cnf->dad_transmits;
array[DEVCONF_RTR_SOLICITS] = cnf->rtr_solicits;
array[DEVCONF_AUTOCONF] = cnf->autoconf;
array[DEVCONF_DAD_TRANSMITS] = cnf->dad_transmits;
array[DEVCONF_RTR_SOLICITS] = cnf->rtr_solicits;
- array[DEVCONF_RTR_SOLICIT_INTERVAL] = cnf->rtr_solicit_interval;
- array[DEVCONF_RTR_SOLICIT_DELAY] = cnf->rtr_solicit_delay;
+ array[DEVCONF_RTR_SOLICIT_INTERVAL] =
+ jiffies_to_msecs(cnf->rtr_solicit_interval);
+ array[DEVCONF_RTR_SOLICIT_DELAY] =
+ jiffies_to_msecs(cnf->rtr_solicit_delay);
array[DEVCONF_FORCE_MLD_VERSION] = cnf->force_mld_version;
#ifdef CONFIG_IPV6_PRIVACY
array[DEVCONF_USE_TEMPADDR] = cnf->use_tempaddr;
array[DEVCONF_FORCE_MLD_VERSION] = cnf->force_mld_version;
#ifdef CONFIG_IPV6_PRIVACY
array[DEVCONF_USE_TEMPADDR] = cnf->use_tempaddr;
@@
-3817,7
+3817,8
@@
static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
array[DEVCONF_ACCEPT_RA_PINFO] = cnf->accept_ra_pinfo;
#ifdef CONFIG_IPV6_ROUTER_PREF
array[DEVCONF_ACCEPT_RA_RTR_PREF] = cnf->accept_ra_rtr_pref;
array[DEVCONF_ACCEPT_RA_PINFO] = cnf->accept_ra_pinfo;
#ifdef CONFIG_IPV6_ROUTER_PREF
array[DEVCONF_ACCEPT_RA_RTR_PREF] = cnf->accept_ra_rtr_pref;
- array[DEVCONF_RTR_PROBE_INTERVAL] = cnf->rtr_probe_interval;
+ array[DEVCONF_RTR_PROBE_INTERVAL] =
+ jiffies_to_msecs(cnf->rtr_probe_interval);
#ifdef CONFIG_IPV6_ROUTE_INFO
array[DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN] = cnf->accept_ra_rt_info_max_plen;
#endif
#ifdef CONFIG_IPV6_ROUTE_INFO
array[DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN] = cnf->accept_ra_rt_info_max_plen;
#endif
@@
-3933,10
+3934,9
@@
static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
NLA_PUT_U32(skb, IFLA_INET6_FLAGS, idev->if_flags);
ci.max_reasm_len = IPV6_MAXPLEN;
NLA_PUT_U32(skb, IFLA_INET6_FLAGS, idev->if_flags);
ci.max_reasm_len = IPV6_MAXPLEN;
- ci.tstamp = (__u32)(TIME_DELTA(idev->tstamp, INITIAL_JIFFIES) / HZ * 100
- + TIME_DELTA(idev->tstamp, INITIAL_JIFFIES) % HZ * 100 / HZ);
- ci.reachable_time = idev->nd_parms->reachable_time;
- ci.retrans_time = idev->nd_parms->retrans_time;
+ ci.tstamp = cstamp_delta(idev->tstamp);
+ ci.reachable_time = jiffies_to_msecs(idev->nd_parms->reachable_time);
+ ci.retrans_time = jiffies_to_msecs(idev->nd_parms->retrans_time);
NLA_PUT(skb, IFLA_INET6_CACHEINFO, sizeof(ci), &ci);
nla = nla_reserve(skb, IFLA_INET6_CONF, DEVCONF_MAX * sizeof(s32));
NLA_PUT(skb, IFLA_INET6_CACHEINFO, sizeof(ci), &ci);
nla = nla_reserve(skb, IFLA_INET6_CONF, DEVCONF_MAX * sizeof(s32));
@@
-4021,11
+4021,11
@@
void inet6_ifinfo_notify(int event, struct inet6_dev *idev)
kfree_skb(skb);
goto errout;
}
kfree_skb(skb);
goto errout;
}
- rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IF
ADDR
, NULL, GFP_ATOMIC);
+ rtnl_notify(skb, net, 0, RTNLGRP_IPV6_IF
INFO
, NULL, GFP_ATOMIC);
return;
errout:
if (err < 0)
return;
errout:
if (err < 0)
- rtnl_set_sk_err(net, RTNLGRP_IPV6_IF
ADDR
, err);
+ rtnl_set_sk_err(net, RTNLGRP_IPV6_IF
INFO
, err);
}
static inline size_t inet6_prefix_nlmsg_size(void)
}
static inline size_t inet6_prefix_nlmsg_size(void)