Commit f845392f authored by David S. Miller's avatar David S. Miller

Merge bk://kernel.bkbits.net/jmorris/ipv6-2.5

into nuts.ninka.net:/home/davem/src/BK/net-2.5
parents 6fee4e4e 5107a690
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
#define MAX_RTR_SOLICITATIONS 3 #define MAX_RTR_SOLICITATIONS 3
#define RTR_SOLICITATION_INTERVAL (4*HZ) #define RTR_SOLICITATION_INTERVAL (4*HZ)
#define MIN_VALID_LIFETIME (2*3600) /* 2 hours */
#define TEMP_VALID_LIFETIME (7*86400) #define TEMP_VALID_LIFETIME (7*86400)
#define TEMP_PREFERRED_LIFETIME (86400) #define TEMP_PREFERRED_LIFETIME (86400)
#define REGEN_MAX_RETRY (5) #define REGEN_MAX_RETRY (5)
......
...@@ -608,7 +608,9 @@ static void neigh_periodic_timer(unsigned long arg) ...@@ -608,7 +608,9 @@ static void neigh_periodic_timer(unsigned long arg)
static __inline__ int neigh_max_probes(struct neighbour *n) static __inline__ int neigh_max_probes(struct neighbour *n)
{ {
struct neigh_parms *p = n->parms; struct neigh_parms *p = n->parms;
return p->ucast_probes + p->app_probes + p->mcast_probes; return (n->nud_state & NUD_PROBE ?
p->ucast_probes :
p->ucast_probes + p->app_probes + p->mcast_probes);
} }
......
...@@ -1299,7 +1299,6 @@ static struct inet6_dev *addrconf_add_dev(struct net_device *dev) ...@@ -1299,7 +1299,6 @@ static struct inet6_dev *addrconf_add_dev(struct net_device *dev)
void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len)
{ {
struct prefix_info *pinfo; struct prefix_info *pinfo;
struct rt6_info *rt;
__u32 valid_lft; __u32 valid_lft;
__u32 prefered_lft; __u32 prefered_lft;
int addr_type; int addr_type;
...@@ -1355,33 +1354,33 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) ...@@ -1355,33 +1354,33 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len)
else else
rt_expires = jiffies + valid_lft * HZ; rt_expires = jiffies + valid_lft * HZ;
if (pinfo->onlink) {
struct rt6_info *rt;
rt = rt6_lookup(&pinfo->prefix, NULL, dev->ifindex, 1); rt = rt6_lookup(&pinfo->prefix, NULL, dev->ifindex, 1);
if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) { if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) {
if (rt->rt6i_flags&RTF_EXPIRES) { if (rt->rt6i_flags&RTF_EXPIRES) {
if (pinfo->onlink == 0 || valid_lft == 0) { if (valid_lft == 0) {
ip6_del_rt(rt, NULL, NULL); ip6_del_rt(rt, NULL, NULL);
rt = NULL; rt = NULL;
} else { } else {
rt->rt6i_expires = rt_expires; rt->rt6i_expires = rt_expires;
} }
} }
} else if (pinfo->onlink && valid_lft) { } else if (valid_lft) {
addrconf_prefix_route(&pinfo->prefix, pinfo->prefix_len, addrconf_prefix_route(&pinfo->prefix, pinfo->prefix_len,
dev, rt_expires, RTF_ADDRCONF|RTF_EXPIRES); dev, rt_expires, RTF_ADDRCONF|RTF_EXPIRES);
} }
if (rt) if (rt)
dst_release(&rt->u.dst); dst_release(&rt->u.dst);
}
/* Try to figure out our local address for this prefix */ /* Try to figure out our local address for this prefix */
if (pinfo->autoconf && in6_dev->cnf.autoconf) { if (pinfo->autoconf && in6_dev->cnf.autoconf) {
struct inet6_ifaddr * ifp; struct inet6_ifaddr * ifp;
struct in6_addr addr; struct in6_addr addr;
int plen; int create = 0, update_lft = 0;
int create = 0;
plen = pinfo->prefix_len >> 3;
if (pinfo->prefix_len == 64) { if (pinfo->prefix_len == 64) {
memcpy(&addr, &pinfo->prefix, 8); memcpy(&addr, &pinfo->prefix, 8);
...@@ -1415,25 +1414,45 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) ...@@ -1415,25 +1414,45 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len)
return; return;
} }
create = 1; update_lft = create = 1;
addrconf_dad_start(ifp); addrconf_dad_start(ifp);
} }
if (ifp && valid_lft == 0) {
ipv6_del_addr(ifp);
ifp = NULL;
}
if (ifp) { if (ifp) {
int flags; int flags;
unsigned long now;
#ifdef CONFIG_IPV6_PRIVACY #ifdef CONFIG_IPV6_PRIVACY
struct inet6_ifaddr *ift; struct inet6_ifaddr *ift;
#endif #endif
u32 stored_lft;
/* update lifetime (RFC2462 5.5.3 e) */
spin_lock(&ifp->lock); spin_lock(&ifp->lock);
now = jiffies;
if (ifp->valid_lft > (now - ifp->tstamp) / HZ)
stored_lft = ifp->valid_lft - (now - ifp->tstamp) / HZ;
else
stored_lft = 0;
if (!update_lft && stored_lft) {
if (valid_lft > MIN_VALID_LIFETIME ||
valid_lft > stored_lft)
update_lft = 1;
else if (stored_lft <= MIN_VALID_LIFETIME) {
/* valid_lft <= stored_lft is always true */
/* XXX: IPsec */
update_lft = 0;
} else {
valid_lft = MIN_VALID_LIFETIME;
if (valid_lft < prefered_lft)
prefered_lft = valid_lft;
update_lft = 1;
}
}
if (update_lft) {
ifp->valid_lft = valid_lft; ifp->valid_lft = valid_lft;
ifp->prefered_lft = prefered_lft; ifp->prefered_lft = prefered_lft;
ifp->tstamp = jiffies; ifp->tstamp = now;
flags = ifp->flags; flags = ifp->flags;
ifp->flags &= ~IFA_F_DEPRECATED; ifp->flags &= ~IFA_F_DEPRECATED;
spin_unlock(&ifp->lock); spin_unlock(&ifp->lock);
...@@ -1441,6 +1460,8 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) ...@@ -1441,6 +1460,8 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len)
if (!(flags&IFA_F_TENTATIVE)) if (!(flags&IFA_F_TENTATIVE))
ipv6_ifa_notify((flags&IFA_F_DEPRECATED) ? ipv6_ifa_notify((flags&IFA_F_DEPRECATED) ?
0 : RTM_NEWADDR, ifp); 0 : RTM_NEWADDR, ifp);
} else
spin_unlock(&ifp->lock);
#ifdef CONFIG_IPV6_PRIVACY #ifdef CONFIG_IPV6_PRIVACY
read_lock_bh(&in6_dev->lock); read_lock_bh(&in6_dev->lock);
......
...@@ -1239,7 +1239,6 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int offse ...@@ -1239,7 +1239,6 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int offse
memcpy(np->cork.opt, opt, opt->tot_len); memcpy(np->cork.opt, opt, opt->tot_len);
inet->cork.flags |= IPCORK_OPT; inet->cork.flags |= IPCORK_OPT;
/* need source address above miyazawa*/ /* need source address above miyazawa*/
exthdrlen += opt->opt_flen ? opt->opt_flen : 0;
} }
dst_hold(&rt->u.dst); dst_hold(&rt->u.dst);
np->cork.rt = rt; np->cork.rt = rt;
...@@ -1252,6 +1251,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int offse ...@@ -1252,6 +1251,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, int offse
length += exthdrlen; length += exthdrlen;
transhdrlen += exthdrlen; transhdrlen += exthdrlen;
} }
exthdrlen += opt ? opt->opt_flen : 0;
} else { } else {
rt = np->cork.rt; rt = np->cork.rt;
if (inet->cork.flags & IPCORK_OPT) if (inet->cork.flags & IPCORK_OPT)
......
...@@ -624,6 +624,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg ...@@ -624,6 +624,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg
if (msg->msg_controllen) { if (msg->msg_controllen) {
opt = &opt_space; opt = &opt_space;
memset(opt, 0, sizeof(struct ipv6_txoptions)); memset(opt, 0, sizeof(struct ipv6_txoptions));
opt->tot_len = sizeof(struct ipv6_txoptions);
err = datagram_send_ctl(msg, &fl, opt, &hlimit); err = datagram_send_ctl(msg, &fl, opt, &hlimit);
if (err < 0) { if (err < 0) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment