Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
On Wed, Feb 21, 2007 at 01:30:31AM -0800, David Miller wrote: > From: YOSHIFUJI Hideaki <[EMAIL PROTECTED]> > Date: Wed, 21 Feb 2007 17:15:45 +0900 (JST) > > > In article <[EMAIL PROTECTED]> (at Wed, 21 Feb 2007 00:02:22 -0800 (PST)), > > David Miller <[EMAIL PROTECTED]> says: > > > > > > So, I think it is ready. Here's my sign-off: > > > > > > > > Signed-off-by: YOSHIFUJI Hideaki <[EMAIL PROTECTED]> > > > > > > Neil, please keep this patch ready for the next merge window. > > > > Dave, Neil, > > > > I expect to have some changes in routing code in near future, > > I want to have Neil's change in my -dev tree, if you don't mind. > > I have no problem with this, and I am sure Neil will be OK > with it too. Absolutely, I'll keep my devel branch rebased against Daves tree until its all checked in, just in case any updates are needed. Thanks for all the help everyone! Neil - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
From: YOSHIFUJI Hideaki <[EMAIL PROTECTED]> Date: Wed, 21 Feb 2007 17:15:45 +0900 (JST) > In article <[EMAIL PROTECTED]> (at Wed, 21 Feb 2007 00:02:22 -0800 (PST)), > David Miller <[EMAIL PROTECTED]> says: > > > > So, I think it is ready. Here's my sign-off: > > > > > > Signed-off-by: YOSHIFUJI Hideaki <[EMAIL PROTECTED]> > > > > Neil, please keep this patch ready for the next merge window. > > Dave, Neil, > > I expect to have some changes in routing code in near future, > I want to have Neil's change in my -dev tree, if you don't mind. I have no problem with this, and I am sure Neil will be OK with it too. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
In article <[EMAIL PROTECTED]> (at Wed, 21 Feb 2007 00:02:22 -0800 (PST)), David Miller <[EMAIL PROTECTED]> says: > > So, I think it is ready. Here's my sign-off: > > > > Signed-off-by: YOSHIFUJI Hideaki <[EMAIL PROTECTED]> > > Neil, please keep this patch ready for the next merge window. Dave, Neil, I expect to have some changes in routing code in near future, I want to have Neil's change in my -dev tree, if you don't mind. --yoshfuji - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
From: YOSHIFUJI Hideaki <[EMAIL PROTECTED]> Date: Wed, 14 Feb 2007 06:46:49 +0900 (JST) > In article <[EMAIL PROTECTED]> (at Tue, 13 Feb 2007 15:45:15 -0500), Neil > Horman <[EMAIL PROTECTED]> says: > > > Signed-off-by: Neil Horman <[EMAIL PROTECTED]> > > I'm starting regression tests now. Thank you. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
In article <[EMAIL PROTECTED]> (at Tue, 13 Feb 2007 15:45:15 -0500), Neil Horman <[EMAIL PROTECTED]> says: > Signed-off-by: Neil Horman <[EMAIL PROTECTED]> I'm starting regression tests now. --yoshfuji - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
>I still have a question. Now, who will install the kernel route for > > the incoming packet? Can we get packet for our unicast address during > > optimistic DAD period? As per Yoshifjui's observation, the current patch doesn't currently allow for the reception of inbound packets to our optimistic address, since we don't add a route for this destination address to our table until we call ipv6_ifa_notify, which happens after the dad process completes. This updated patch corrects that by adding a route for the optimistic address in addrconf_dad_start, and only conditionally doing it in ipv6_ifa_notify if the route has not already been added. Route deltion should still be common with non-optimistic cases since the route is removed on interface deletion from ipv6_ifa_notify, which occurs in the common code path ipv6_del_addr. Thanks & Regards Neil Signed-off-by: Neil Horman <[EMAIL PROTECTED]> include/linux/if_addr.h |1 include/linux/ipv6.h|4 + include/linux/sysctl.h |1 include/net/addrconf.h |4 + net/ipv6/Kconfig| 10 net/ipv6/addrconf.c | 107 net/ipv6/ip6_output.c | 35 +++ net/ipv6/mcast.c|4 - net/ipv6/ndisc.c| 86 +++--- 9 files changed, 209 insertions(+), 43 deletions(-) diff --git a/include/linux/if_addr.h b/include/linux/if_addr.h index d557e4c..43f3bed 100644 --- a/include/linux/if_addr.h +++ b/include/linux/if_addr.h @@ -39,6 +39,7 @@ enum #define IFA_F_TEMPORARYIFA_F_SECONDARY #defineIFA_F_NODAD 0x02 +#define IFA_F_OPTIMISTIC 0x04 #defineIFA_F_HOMEADDRESS 0x10 #define IFA_F_DEPRECATED 0x20 #define IFA_F_TENTATIVE0x40 diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index f824113..bf93c1b 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -177,6 +177,9 @@ struct ipv6_devconf { #endif #endif __s32 proxy_ndp; +#ifdef CONFIG_IPV6_OPTIMISTIC_DAD + __s32 optimistic_dad; +#endif void*sysctl; }; @@ -205,6 +208,7 @@ enum { DEVCONF_RTR_PROBE_INTERVAL, DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN, DEVCONF_PROXY_NDP, + DEVCONF_OPTIMISTIC_DAD, DEVCONF_MAX }; diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 665412c..a7c0496 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -570,6 +570,7 @@ enum { NET_IPV6_RTR_PROBE_INTERVAL=21, NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=22, NET_IPV6_PROXY_NDP=23, + NET_IPV6_OPTIMISTIC_DAD=24, __NET_IPV6_MAX }; diff --git a/include/net/addrconf.h b/include/net/addrconf.h index 88df8fc..d248a19 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -73,7 +73,9 @@ extern intipv6_get_saddr(struct dst_entry *dst, extern int ipv6_dev_get_saddr(struct net_device *dev, struct in6_addr *daddr, struct in6_addr *saddr); -extern int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *); +extern int ipv6_get_lladdr(struct net_device *dev, + struct in6_addr *, + unsigned char banned_flags); extern int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2); extern voidaddrconf_join_solict(struct net_device *dev, diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig index deb4101..822d3eb 100644 --- a/net/ipv6/Kconfig +++ b/net/ipv6/Kconfig @@ -57,6 +57,16 @@ config IPV6_ROUTE_INFO If unsure, say N. +config IPV6_OPTIMISTIC_DAD + bool "IPv6: Enable RFC 4429 Optimistic DAD (EXPERIMENTAL)" + depends on IPV6 && EXPERIMENTAL + ---help--- + This is experimental support for optimistic Duplicate + Address Detection. It allows for autoconfigured addresses + to be used more quickly. + + If unsure, say N. + config INET6_AH tristate "IPv6: AH transformation" depends on IPV6 diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index ea0755b..7ea0a36 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -594,6 +594,16 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen, ifa->rt = rt; + /* +* part one of RFC 4429, section 3.3 +* We should not configure an address as +* optimistic if we do not yet know the link +* layer address of our nexhop router +*/ + + if (rt->rt6i_nexthop == NULL) + ifa->flags &= ~IFA_F_OPTIMISTIC; + ifa->idev = idev; in6_dev_hold(idev); /* Fo
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
On Tue, Feb 13, 2007 at 08:27:59AM +0900, YOSHIFUJI Hideaki / 吉藤英明 wrote: > In article <[EMAIL PROTECTED]> (at Thu, 8 Feb 2007 08:07:15 -0500), Neil > Horman <[EMAIL PROTECTED]> says: > > > > I still have a question. Now, who will install the kernel route for > > > the incoming packet? Can we get packet for our unicast address during > > > optimistic DAD period? > > > > > Not sure what you're getting at here. RFC 4429 makes no distinction between > > optimistic and non-optimistic packets for recevied frames, so routes for > > received packets will be added by the same code that does it currently > > (which I > > admittedly haven't looked into to closely). Packets received for our > > unicast > > address (even if it is optimistic) are handled just as any other packet is > > (same > > as it is for TENTATIVE addresses, as I understand it). > > I think it is clear. > > In tentative state, we do not receive any packet. > After finishind DAD process, we install kernel route for that address > in net/ipv6/addrconf.c:__ipv6_ifa_notify(), and we start receiving > packet for that address. > > On the other hand, optimistic addresses are like in deprecated state. > So, we should be able to receive frames for those addresses. > I'm sorry, you're right, it is clear now. I hadn't considered the need for a route to receive frames, and the point at which we insert it. I'm puting together a new patch for this right now and will post it as soon as I've built and started testing it. Thanks & Regards Neil > --yoshfuji > - > To unsubscribe from this list: send the line "unsubscribe netdev" in > the body of a message to [EMAIL PROTECTED] > More majordomo info at http://vger.kernel.org/majordomo-info.html - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
In article <[EMAIL PROTECTED]> (at Thu, 8 Feb 2007 08:07:15 -0500), Neil Horman <[EMAIL PROTECTED]> says: > > I still have a question. Now, who will install the kernel route for > > the incoming packet? Can we get packet for our unicast address during > > optimistic DAD period? > > > Not sure what you're getting at here. RFC 4429 makes no distinction between > optimistic and non-optimistic packets for recevied frames, so routes for > received packets will be added by the same code that does it currently (which > I > admittedly haven't looked into to closely). Packets received for our unicast > address (even if it is optimistic) are handled just as any other packet is > (same > as it is for TENTATIVE addresses, as I understand it). I think it is clear. In tentative state, we do not receive any packet. After finishind DAD process, we install kernel route for that address in net/ipv6/addrconf.c:__ipv6_ifa_notify(), and we start receiving packet for that address. On the other hand, optimistic addresses are like in deprecated state. So, we should be able to receive frames for those addresses. --yoshfuji - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
> > New patch attached with these fixes included > > Ping? Any further thoughts here? My (allbeit limited) testing seems to be going fairly well so far... Neil > Thanks & Regards > Neil > > Signed-off-by: Neil Horman <[EMAIL PROTECTED]> > > > include/linux/if_addr.h |1 > include/linux/ipv6.h|4 ++ > include/linux/sysctl.h |1 > include/net/addrconf.h |4 +- > net/ipv6/Kconfig| 10 + > net/ipv6/addrconf.c | 90 > > net/ipv6/ip6_output.c | 35 ++ > net/ipv6/mcast.c|4 +- > net/ipv6/ndisc.c| 84 > 9 files changed, 192 insertions(+), 41 deletions(-) > > > > > diff --git a/include/linux/if_addr.h b/include/linux/if_addr.h > index d557e4c..43f3bed 100644 > --- a/include/linux/if_addr.h > +++ b/include/linux/if_addr.h > @@ -39,6 +39,7 @@ enum > #define IFA_F_TEMPORARY IFA_F_SECONDARY > > #define IFA_F_NODAD 0x02 > +#define IFA_F_OPTIMISTIC 0x04 > #define IFA_F_HOMEADDRESS 0x10 > #define IFA_F_DEPRECATED 0x20 > #define IFA_F_TENTATIVE 0x40 > diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h > index f824113..bf93c1b 100644 > --- a/include/linux/ipv6.h > +++ b/include/linux/ipv6.h > @@ -177,6 +177,9 @@ struct ipv6_devconf { > #endif > #endif > __s32 proxy_ndp; > +#ifdef CONFIG_IPV6_OPTIMISTIC_DAD > + __s32 optimistic_dad; > +#endif > void*sysctl; > }; > > @@ -205,6 +208,7 @@ enum { > DEVCONF_RTR_PROBE_INTERVAL, > DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN, > DEVCONF_PROXY_NDP, > + DEVCONF_OPTIMISTIC_DAD, > DEVCONF_MAX > }; > > diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h > index 81480e6..972a33a 100644 > --- a/include/linux/sysctl.h > +++ b/include/linux/sysctl.h > @@ -570,6 +570,7 @@ enum { > NET_IPV6_RTR_PROBE_INTERVAL=21, > NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=22, > NET_IPV6_PROXY_NDP=23, > + NET_IPV6_OPTIMISTIC_DAD=24, > __NET_IPV6_MAX > }; > > diff --git a/include/net/addrconf.h b/include/net/addrconf.h > index 88df8fc..d248a19 100644 > --- a/include/net/addrconf.h > +++ b/include/net/addrconf.h > @@ -73,7 +73,9 @@ extern int ipv6_get_saddr(struct dst_entry > *dst, > extern int ipv6_dev_get_saddr(struct net_device *dev, > struct in6_addr *daddr, > struct in6_addr *saddr); > -extern int ipv6_get_lladdr(struct net_device *dev, struct > in6_addr *); > +extern int ipv6_get_lladdr(struct net_device *dev, > + struct in6_addr *, > + unsigned char banned_flags); > extern int ipv6_rcv_saddr_equal(const struct sock *sk, > const struct sock *sk2); > extern void addrconf_join_solict(struct net_device *dev, > diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig > index deb4101..822d3eb 100644 > --- a/net/ipv6/Kconfig > +++ b/net/ipv6/Kconfig > @@ -57,6 +57,16 @@ config IPV6_ROUTE_INFO > > If unsure, say N. > > +config IPV6_OPTIMISTIC_DAD > + bool "IPv6: Enable RFC 4429 Optimistic DAD (EXPERIMENTAL)" > + depends on IPV6 && EXPERIMENTAL > + ---help--- > + This is experimental support for optimistic Duplicate > + Address Detection. It allows for autoconfigured addresses > + to be used more quickly. > + > + If unsure, say N. > + > config INET6_AH > tristate "IPv6: AH transformation" > depends on IPV6 > diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c > index e385469..c884eeb 100644 > --- a/net/ipv6/addrconf.c > +++ b/net/ipv6/addrconf.c > @@ -594,6 +594,16 @@ ipv6_add_addr(struct inet6_dev *idev, const struct > in6_addr *addr, int pfxlen, > > ifa->rt = rt; > > + /* > + * part one of RFC 4429, section 3.3 > + * We should not configure an address as > + * optimistic if we do not yet know the link > + * layer address of our nexhop router > + */ > + > + if (rt->rt6i_nexthop == NULL) > + ifa->flags &= ~IFA_F_OPTIMISTIC; > + > ifa->idev = idev; > in6_dev_hold(idev); > /* For caller */ > @@ -770,6 +780,7 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, > struct inet6_ifaddr *i > int tmp_plen; > int ret = 0; > int max_addresses; > + u32 addr_flags; > > write_lock(&idev->lock); > if (ift) { > @@ -827,10 +838,17 @@ retry: > spin_unlock_bh(&ifp->lock); > > write_unlock(&idev->lock); > + > + addr_flags = IFA_F_TEMPORARY; > + /* set in addrconf_prefix_rcv() */ > + if (ifp->flags & IFA_F_OPTIMISTIC) > +
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
On Fri, Feb 09, 2007 at 02:10:37AM +0900, YOSHIFUJI Hideaki / 吉藤英明 wrote: > In article <[EMAIL PROTECTED]> (at Thu, 8 Feb 2007 11:41:52 -0500), Neil > Horman <[EMAIL PROTECTED]> says: > > > These should be placed > > > } > > here. No? > Yes, you're right. After re-reading the logic, its pretty evident that you want to do the optimistic dad checks regardless of weather the flows initial source address is the anycast address. > > > Still leaking ifp. Something like this? > > int send_sllao = dev->addr_len; > > #ifdef CONFIG_IPV6_OPTIMISTIC_DAD > if (send_sllao) { > struct inet6_ifaddr *ifp = ipv6_get_ifaddr(saddr, dev, 1); > if (ifp) { > if (ifp->flags & IFA_F_OPTIMISTIC) >send_sllao = 0; > in6_ifa_put(ifp); > } else > send_sllao = 0; > } > #endif > Yeah, definately another leak. You're fix looks good to me. New patch attached with these fixes included Thanks & Regards Neil Signed-off-by: Neil Horman <[EMAIL PROTECTED]> include/linux/if_addr.h |1 include/linux/ipv6.h|4 ++ include/linux/sysctl.h |1 include/net/addrconf.h |4 +- net/ipv6/Kconfig| 10 + net/ipv6/addrconf.c | 90 net/ipv6/ip6_output.c | 35 ++ net/ipv6/mcast.c|4 +- net/ipv6/ndisc.c| 84 9 files changed, 192 insertions(+), 41 deletions(-) diff --git a/include/linux/if_addr.h b/include/linux/if_addr.h index d557e4c..43f3bed 100644 --- a/include/linux/if_addr.h +++ b/include/linux/if_addr.h @@ -39,6 +39,7 @@ enum #define IFA_F_TEMPORARYIFA_F_SECONDARY #defineIFA_F_NODAD 0x02 +#define IFA_F_OPTIMISTIC 0x04 #defineIFA_F_HOMEADDRESS 0x10 #define IFA_F_DEPRECATED 0x20 #define IFA_F_TENTATIVE0x40 diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index f824113..bf93c1b 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -177,6 +177,9 @@ struct ipv6_devconf { #endif #endif __s32 proxy_ndp; +#ifdef CONFIG_IPV6_OPTIMISTIC_DAD + __s32 optimistic_dad; +#endif void*sysctl; }; @@ -205,6 +208,7 @@ enum { DEVCONF_RTR_PROBE_INTERVAL, DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN, DEVCONF_PROXY_NDP, + DEVCONF_OPTIMISTIC_DAD, DEVCONF_MAX }; diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 81480e6..972a33a 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -570,6 +570,7 @@ enum { NET_IPV6_RTR_PROBE_INTERVAL=21, NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=22, NET_IPV6_PROXY_NDP=23, + NET_IPV6_OPTIMISTIC_DAD=24, __NET_IPV6_MAX }; diff --git a/include/net/addrconf.h b/include/net/addrconf.h index 88df8fc..d248a19 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -73,7 +73,9 @@ extern intipv6_get_saddr(struct dst_entry *dst, extern int ipv6_dev_get_saddr(struct net_device *dev, struct in6_addr *daddr, struct in6_addr *saddr); -extern int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *); +extern int ipv6_get_lladdr(struct net_device *dev, + struct in6_addr *, + unsigned char banned_flags); extern int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2); extern voidaddrconf_join_solict(struct net_device *dev, diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig index deb4101..822d3eb 100644 --- a/net/ipv6/Kconfig +++ b/net/ipv6/Kconfig @@ -57,6 +57,16 @@ config IPV6_ROUTE_INFO If unsure, say N. +config IPV6_OPTIMISTIC_DAD + bool "IPv6: Enable RFC 4429 Optimistic DAD (EXPERIMENTAL)" + depends on IPV6 && EXPERIMENTAL + ---help--- + This is experimental support for optimistic Duplicate + Address Detection. It allows for autoconfigured addresses + to be used more quickly. + + If unsure, say N. + config INET6_AH tristate "IPv6: AH transformation" depends on IPV6 diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index e385469..c884eeb 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -594,6 +594,16 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen, ifa->rt = rt; + /* +* part one of RFC 4429, section 3.3 +* We should not configure an address as +* optimistic if we do not yet know the link +* layer address of our nexhop router +*/ + + if (rt->rt6i_nexthop == NULL) + ifa->flags &= ~I
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
In article <[EMAIL PROTECTED]> (at Thu, 8 Feb 2007 11:41:52 -0500), Neil Horman <[EMAIL PROTECTED]> says: > diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c > index 7b7bd44..07a5f4d 100644 > --- a/net/ipv6/ip6_output.c > +++ b/net/ipv6/ip6_output.c > @@ -859,6 +859,40 @@ static int ip6_dst_lookup_tail(struct sock *sk, > err = ipv6_get_saddr(*dst, &fl->fl6_dst, &fl->fl6_src); > if (err) > goto out_err_release; > +#ifdef CONFIG_IPV6_OPTIMISTIC_DAD > + /* > + * Here if the dst entry we've looked up > + * has a neighbour entry that is in the INCOMPLETE > + * state and the src address from the flow is > + * marked as OPTIMISTIC, we release the found > + * dst entry and replace it instead with the > + * dst entry of the nexthop router > + */ > + if (!((*dst)->neighbour->nud_state & NUD_VALID)) { > + struct inet6_ifaddr *ifp; > + struct flowi fl_gw; > + int redirect; > + > + ifp = ipv6_get_ifaddr(&fl->fl6_src, (*dst)->dev, 1); > + > + redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC); > + if (ifp) > + in6_ifa_put(ifp); > + > + if (redirect) { > + /* > + * We need to get the dst entry for the > + * default router instead > + */ > + dst_release(*dst); > + memcpy(&fl_gw, fl, sizeof(struct flowi)); > + memset(&fl_gw.fl6_dst, 0, sizeof(struct > in6_addr)); > + *dst = ip6_route_output(sk, &fl_gw); > + if ((err = (*dst)->error)) > + goto out_err_release; > > + } > + } > +#endif These should be placed > } here. No? > diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c > index 39bb658..9656018 100644 > --- a/net/ipv6/ndisc.c > +++ b/net/ipv6/ndisc.c > @@ -622,9 +625,29 @@ void ndisc_send_rs(struct net_device *dev, struct > in6_addr *saddr, > struct sk_buff *skb; > struct icmp6hdr *hdr; > __u8 * opt; > + struct inet6_ifaddr *ifp; > + int send_sllao = 1; > int len; > int err; > > + /* > + * Check the source address. If its OPTIMISTIC > + * and addr_len is non-zero (implying the sllao option) > + * then don't send the RS (RFC 4429, section 2.2) > + */ > + ifp = ipv6_get_ifaddr(saddr, dev, 1); > + > + /* > + * According to section 2.2 of RFC 4429, we must not > + * send router solicitations with a sllao from > + * optimistic addresses, but we may send the solicitation > + * if we don't include the sllao. So here we check > + * if our address is optimistic, and if so, we > + * supress the inclusion of the sllao. > + */ > + if (!dev->addr_len || !ifp || (ifp->flags & IFA_F_OPTIMISTIC)) > + send_sllao=0; > + > ndisc_flow_init(&fl, NDISC_ROUTER_SOLICITATION, saddr, daddr, > dev->ifindex); > Still leaking ifp. Something like this? int send_sllao = dev->addr_len; #ifdef CONFIG_IPV6_OPTIMISTIC_DAD if (send_sllao) { struct inet6_ifaddr *ifp = ipv6_get_ifaddr(saddr, dev, 1); if (ifp) { if (ifp->flags & IFA_F_OPTIMISTIC) send_sllao = 0; in6_ifa_put(ifp); } else send_sllao = 0; } #endif --yoshfuji - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
On Thu, Feb 08, 2007 at 07:26:20AM +0900, YOSHIFUJI Hideaki / 吉藤英明 wrote: > In article <[EMAIL PROTECTED]> (at Wed, 7 Feb 2007 15:55:03 -0500), Neil > Horman <[EMAIL PROTECTED]> says: > > > @@ -559,7 +562,7 @@ void ndisc_send_ns(struct net_device *dev, struct > > neighbour *neigh, > > return; > > > > len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr); > > - send_llinfo = dev->addr_len && !ipv6_addr_any(saddr); > > + send_llinfo = dev->addr_len && !ipv6_addr_any(saddr); > > if (send_llinfo) > > len += ndisc_opt_addr_space(dev); > > > > trailing space > > > @@ -637,7 +660,7 @@ void ndisc_send_rs(struct net_device *dev, struct > > in6_addr *saddr, > > return; > > > > len = sizeof(struct icmp6hdr); > > - if (dev->addr_len) > > + if (dev->addr_len && send_sllao) > > len += ndisc_opt_addr_space(dev); > > > > skb = sock_alloc_send_skb(sk, > > if (send_sllao) > > > @@ -664,7 +687,7 @@ void ndisc_send_rs(struct net_device *dev, struct > > in6_addr *saddr, > > > > opt = (u8*) (hdr + 1); > > > > - if (dev->addr_len) > > + if (dev->addr_len && send_sllao) > > ndisc_fill_addr_option(opt, ND_OPT_SOURCE_LL_ADDR, > > dev->dev_addr, > >dev->addr_len, dev->type); > > > > ditto. > > --yoshfuji Ok, new patch attached. Fixes up Yoshfuji's requested changes above, as well as Vlads observed ifaddr reference leak. Let me know what you think. Thanks & Regards Neil Signed-off-by: Neil Horman <[EMAIL PROTECTED]> include/linux/if_addr.h |1 include/linux/ipv6.h|4 ++ include/linux/sysctl.h |1 include/net/addrconf.h |4 +- net/ipv6/Kconfig| 10 + net/ipv6/addrconf.c | 90 net/ipv6/ip6_output.c | 34 ++ net/ipv6/mcast.c|4 +- net/ipv6/ndisc.c| 80 ++ 9 files changed, 187 insertions(+), 41 deletions(-) diff --git a/include/linux/if_addr.h b/include/linux/if_addr.h index d557e4c..43f3bed 100644 --- a/include/linux/if_addr.h +++ b/include/linux/if_addr.h @@ -39,6 +39,7 @@ enum #define IFA_F_TEMPORARYIFA_F_SECONDARY #defineIFA_F_NODAD 0x02 +#define IFA_F_OPTIMISTIC 0x04 #defineIFA_F_HOMEADDRESS 0x10 #define IFA_F_DEPRECATED 0x20 #define IFA_F_TENTATIVE0x40 diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index f824113..bf93c1b 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -177,6 +177,9 @@ struct ipv6_devconf { #endif #endif __s32 proxy_ndp; +#ifdef CONFIG_IPV6_OPTIMISTIC_DAD + __s32 optimistic_dad; +#endif void*sysctl; }; @@ -205,6 +208,7 @@ enum { DEVCONF_RTR_PROBE_INTERVAL, DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN, DEVCONF_PROXY_NDP, + DEVCONF_OPTIMISTIC_DAD, DEVCONF_MAX }; diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 81480e6..972a33a 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -570,6 +570,7 @@ enum { NET_IPV6_RTR_PROBE_INTERVAL=21, NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=22, NET_IPV6_PROXY_NDP=23, + NET_IPV6_OPTIMISTIC_DAD=24, __NET_IPV6_MAX }; diff --git a/include/net/addrconf.h b/include/net/addrconf.h index 88df8fc..d248a19 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -73,7 +73,9 @@ extern intipv6_get_saddr(struct dst_entry *dst, extern int ipv6_dev_get_saddr(struct net_device *dev, struct in6_addr *daddr, struct in6_addr *saddr); -extern int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *); +extern int ipv6_get_lladdr(struct net_device *dev, + struct in6_addr *, + unsigned char banned_flags); extern int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2); extern voidaddrconf_join_solict(struct net_device *dev, diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig index deb4101..822d3eb 100644 --- a/net/ipv6/Kconfig +++ b/net/ipv6/Kconfig @@ -57,6 +57,16 @@ config IPV6_ROUTE_INFO If unsure, say N. +config IPV6_OPTIMISTIC_DAD + bool "IPv6: Enable RFC 4429 Optimistic DAD (EXPERIMENTAL)" + depends on IPV6 && EXPERIMENTAL + ---help--- + This is experimental support for optimistic Duplicate + Address Detection. It allows for autoconfigured addresses + to be used more quickly. + + If unsure, say N. + config INET6_AH tristate "IPv6: AH
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
On Thu, Feb 08, 2007 at 06:52:06AM +0900, YOSHIFUJI Hideaki / 吉藤英明 wrote: > In article <[EMAIL PROTECTED]> (at Wed, 7 Feb 2007 15:55:03 -0500), Neil > Horman <[EMAIL PROTECTED]> says: > > > diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c > > index 7b7bd44..8a1ea96 100644 > > --- a/net/ipv6/ip6_output.c > > +++ b/net/ipv6/ip6_output.c > > @@ -859,6 +859,34 @@ static int ip6_dst_lookup_tail(struct sock *sk, > > err = ipv6_get_saddr(*dst, &fl->fl6_dst, &fl->fl6_src); > > if (err) > > goto out_err_release; > > +#ifdef CONFIG_IPV6_OPTIMISTIC_DAD > > + /* > > +* Here if the dst entry we've looked up > > +* has a neighbour entry that is in the INCOMPLETE > > +* state and the src address from the flow is > > +* marked as OPTIMISTIC, we release the found > > +* dst entry and replace it instead with the > > +* dst entry of the nexthop router > > +*/ > > + if (!((*dst)->neighbour->nud_state & NUD_VALID)) { > > + struct inet6_ifaddr *ifp; > > + struct flowi fl_gw; > > + ifp = ipv6_get_ifaddr(&fl->fl6_src, (*dst)->dev, 1); > > + > > + if (ifp && ifp->flags & IFA_F_OPTIMISTIC) { > > + /* > > +* We need to get the dst entry for the > > +* default router instead > > +*/ > > + dst_release(*dst); > > + memcpy(&fl_gw, fl, sizeof(struct flowi)); > > + memset(&fl_gw.fl6_dst, 0, sizeof(struct > > in6_addr)); > > + *dst = ip6_route_output(sk, &fl_gw); > > + if ((err = (*dst)->error)) > > + goto out_err_release; > > > > + } > > + } > > +#endif > > } > > > > return 0; > > Sorry, this is still not correct if the source address is already > specified. I think they should be placed just betwee laste "}" and > "return 0;", no? > I think moving it would be no more correct or incorrect, but it would be less efficient. ipv6_addr_any will only return true if the source address is the anycast address (::). That address will never be optimistic. So we could certainly move the optimistic code to where you indicate, but then we'd be checking the code for optimistic address without any need? Or is there something I'm missing? > > I still have a question. Now, who will install the kernel route for > the incoming packet? Can we get packet for our unicast address during > optimistic DAD period? > Not sure what you're getting at here. RFC 4429 makes no distinction between optimistic and non-optimistic packets for recevied frames, so routes for received packets will be added by the same code that does it currently (which I admittedly haven't looked into to closely). Packets received for our unicast address (even if it is optimistic) are handled just as any other packet is (same as it is for TENTATIVE addresses, as I understand it). Regards Neil > --yoshfuji > - > To unsubscribe from this list: send the line "unsubscribe netdev" in > the body of a message to [EMAIL PROTECTED] > More majordomo info at http://vger.kernel.org/majordomo-info.html - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
In article <[EMAIL PROTECTED]> (at Wed, 7 Feb 2007 15:55:03 -0500), Neil Horman <[EMAIL PROTECTED]> says: > @@ -559,7 +562,7 @@ void ndisc_send_ns(struct net_device *dev, struct > neighbour *neigh, > return; > > len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr); > - send_llinfo = dev->addr_len && !ipv6_addr_any(saddr); > + send_llinfo = dev->addr_len && !ipv6_addr_any(saddr); > if (send_llinfo) > len += ndisc_opt_addr_space(dev); > trailing space > @@ -637,7 +660,7 @@ void ndisc_send_rs(struct net_device *dev, struct > in6_addr *saddr, > return; > > len = sizeof(struct icmp6hdr); > - if (dev->addr_len) > + if (dev->addr_len && send_sllao) > len += ndisc_opt_addr_space(dev); > > skb = sock_alloc_send_skb(sk, if (send_sllao) > @@ -664,7 +687,7 @@ void ndisc_send_rs(struct net_device *dev, struct > in6_addr *saddr, > > opt = (u8*) (hdr + 1); > > - if (dev->addr_len) > + if (dev->addr_len && send_sllao) > ndisc_fill_addr_option(opt, ND_OPT_SOURCE_LL_ADDR, > dev->dev_addr, > dev->addr_len, dev->type); > ditto. --yoshfuji - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
In article <[EMAIL PROTECTED]> (at Wed, 7 Feb 2007 15:55:03 -0500), Neil Horman <[EMAIL PROTECTED]> says: > diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c > index 7b7bd44..8a1ea96 100644 > --- a/net/ipv6/ip6_output.c > +++ b/net/ipv6/ip6_output.c > @@ -859,6 +859,34 @@ static int ip6_dst_lookup_tail(struct sock *sk, > err = ipv6_get_saddr(*dst, &fl->fl6_dst, &fl->fl6_src); > if (err) > goto out_err_release; > +#ifdef CONFIG_IPV6_OPTIMISTIC_DAD > + /* > + * Here if the dst entry we've looked up > + * has a neighbour entry that is in the INCOMPLETE > + * state and the src address from the flow is > + * marked as OPTIMISTIC, we release the found > + * dst entry and replace it instead with the > + * dst entry of the nexthop router > + */ > + if (!((*dst)->neighbour->nud_state & NUD_VALID)) { > + struct inet6_ifaddr *ifp; > + struct flowi fl_gw; > + ifp = ipv6_get_ifaddr(&fl->fl6_src, (*dst)->dev, 1); > + > + if (ifp && ifp->flags & IFA_F_OPTIMISTIC) { > + /* > + * We need to get the dst entry for the > + * default router instead > + */ > + dst_release(*dst); > + memcpy(&fl_gw, fl, sizeof(struct flowi)); > + memset(&fl_gw.fl6_dst, 0, sizeof(struct > in6_addr)); > + *dst = ip6_route_output(sk, &fl_gw); > + if ((err = (*dst)->error)) > + goto out_err_release; > > + } > + } > +#endif > } > > return 0; Sorry, this is still not correct if the source address is already specified. I think they should be placed just betwee laste "}" and "return 0;", no? I still have a question. Now, who will install the kernel route for the incoming packet? Can we get packet for our unicast address during optimistic DAD period? --yoshfuji - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
Darn... and it was looking so good... > diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c > index 7b7bd44..8a1ea96 100644 > --- a/net/ipv6/ip6_output.c > +++ b/net/ipv6/ip6_output.c > @@ -859,6 +859,34 @@ static int ip6_dst_lookup_tail(struct sock *sk, > err = ipv6_get_saddr(*dst, &fl->fl6_dst, &fl->fl6_src); > if (err) > goto out_err_release; > +#ifdef CONFIG_IPV6_OPTIMISTIC_DAD > + /* > + * Here if the dst entry we've looked up > + * has a neighbour entry that is in the INCOMPLETE > + * state and the src address from the flow is > + * marked as OPTIMISTIC, we release the found > + * dst entry and replace it instead with the > + * dst entry of the nexthop router > + */ > + if (!((*dst)->neighbour->nud_state & NUD_VALID)) { > + struct inet6_ifaddr *ifp; > + struct flowi fl_gw; > + ifp = ipv6_get_ifaddr(&fl->fl6_src, (*dst)->dev, 1); > + > + if (ifp && ifp->flags & IFA_F_OPTIMISTIC) { > + /* > + * We need to get the dst entry for the > + * default router instead > + */ > + dst_release(*dst); > + memcpy(&fl_gw, fl, sizeof(struct flowi)); > + memset(&fl_gw.fl6_dst, 0, sizeof(struct > in6_addr)); > + *dst = ip6_route_output(sk, &fl_gw); > + if ((err = (*dst)->error)) > + goto out_err_release; > > + } > + } > +#endif You are leaking an 'ifp' ref. ipv6_get_ifaddr() does in6_ifa_hold(ifp). You need do in6_ifa_put(ifp), when you are done with the ifp. > @@ -622,9 +625,29 @@ void ndisc_send_rs(struct net_device *dev, struct > in6_addr *saddr, > struct sk_buff *skb; > struct icmp6hdr *hdr; > __u8 * opt; > + struct inet6_ifaddr *ifp; > + int send_sllao = 1; > int len; > int err; > > + /* > + * Check the source address. If its OPTIMISTIC > + * and addr_len is non-zero (implying the sllao option) > + * then don't send the RS (RFC 4429, section 2.2) > + */ > + ifp = ipv6_get_ifaddr(saddr, dev, 1); > + > + /* > + * According to section 2.2 of RFC 4429, we must not > + * send router solicitations with a sllao from > + * optimistic addresses, but we may send the solicitation > + * if we don't include the sllao. So here we check > + * if our address is optimistic, and if so, we > + * supress the inclusion of the sllao. > + */ > + if (!dev->addr_len || !ifp || (ifp->flags & IFA_F_OPTIMISTIC)) > + send_sllao=0; > + Ditto. -vlad - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
On Tue, Feb 06, 2007 at 04:13:25PM -0500, Vlad Yasevich wrote: > Hi Neil > > a few comments. sorry, just can't resist... :) > More majordomo info at http://vger.kernel.org/majordomo-info.html Its really ok :). Brian found some other minor typos as well. I've attached the latest patch which takes your comments, and Brians observations into account. The only change I left out was the space/tab conversion in ndisc_send_ns, since it appeared to be more inline with the style in the rest of the file. Everything else is incorporated into this patch, however. Thanks for all the keen eyes! Thanks & Regards Neil Signed-off-by: Neil Horman <[EMAIL PROTECTED]> include/linux/if_addr.h |1 include/linux/ipv6.h|4 ++ include/linux/sysctl.h |1 include/net/addrconf.h |4 +- net/ipv6/Kconfig| 10 + net/ipv6/addrconf.c | 90 net/ipv6/ip6_output.c | 28 ++ net/ipv6/mcast.c|4 +- net/ipv6/ndisc.c| 82 ++- 9 files changed, 182 insertions(+), 42 deletions(-) diff --git a/include/linux/if_addr.h b/include/linux/if_addr.h index d557e4c..43f3bed 100644 --- a/include/linux/if_addr.h +++ b/include/linux/if_addr.h @@ -39,6 +39,7 @@ enum #define IFA_F_TEMPORARYIFA_F_SECONDARY #defineIFA_F_NODAD 0x02 +#define IFA_F_OPTIMISTIC 0x04 #defineIFA_F_HOMEADDRESS 0x10 #define IFA_F_DEPRECATED 0x20 #define IFA_F_TENTATIVE0x40 diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index f824113..bf93c1b 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -177,6 +177,9 @@ struct ipv6_devconf { #endif #endif __s32 proxy_ndp; +#ifdef CONFIG_IPV6_OPTIMISTIC_DAD + __s32 optimistic_dad; +#endif void*sysctl; }; @@ -205,6 +208,7 @@ enum { DEVCONF_RTR_PROBE_INTERVAL, DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN, DEVCONF_PROXY_NDP, + DEVCONF_OPTIMISTIC_DAD, DEVCONF_MAX }; diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 81480e6..972a33a 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -570,6 +570,7 @@ enum { NET_IPV6_RTR_PROBE_INTERVAL=21, NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=22, NET_IPV6_PROXY_NDP=23, + NET_IPV6_OPTIMISTIC_DAD=24, __NET_IPV6_MAX }; diff --git a/include/net/addrconf.h b/include/net/addrconf.h index 88df8fc..d248a19 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -73,7 +73,9 @@ extern intipv6_get_saddr(struct dst_entry *dst, extern int ipv6_dev_get_saddr(struct net_device *dev, struct in6_addr *daddr, struct in6_addr *saddr); -extern int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *); +extern int ipv6_get_lladdr(struct net_device *dev, + struct in6_addr *, + unsigned char banned_flags); extern int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2); extern voidaddrconf_join_solict(struct net_device *dev, diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig index deb4101..822d3eb 100644 --- a/net/ipv6/Kconfig +++ b/net/ipv6/Kconfig @@ -57,6 +57,16 @@ config IPV6_ROUTE_INFO If unsure, say N. +config IPV6_OPTIMISTIC_DAD + bool "IPv6: Enable RFC 4429 Optimistic DAD (EXPERIMENTAL)" + depends on IPV6 && EXPERIMENTAL + ---help--- + This is experimental support for optimistic Duplicate + Address Detection. It allows for autoconfigured addresses + to be used more quickly. + + If unsure, say N. + config INET6_AH tristate "IPv6: AH transformation" depends on IPV6 diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index e385469..c884eeb 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -594,6 +594,16 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen, ifa->rt = rt; + /* +* part one of RFC 4429, section 3.3 +* We should not configure an address as +* optimistic if we do not yet know the link +* layer address of our nexhop router +*/ + + if (rt->rt6i_nexthop == NULL) + ifa->flags &= ~IFA_F_OPTIMISTIC; + ifa->idev = idev; in6_dev_hold(idev); /* For caller */ @@ -770,6 +780,7 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *i int tmp_plen; int ret = 0; int max_addresses; + u32 addr_flags; write_lock(&idev->
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
Hi Neil a few comments. sorry, just can't resist... :) > @@ -2627,6 +2673,9 @@ static void addrconf_dad_completed(struct inet6_ifaddr > *ifp) >* Configure the address for reception. Now it is valid. >*/ > > + if (ifp->flags & IFA_F_OPTIMISTIC) > + addrconf_leave_anycast(ifp); > + > ipv6_ifa_notify(RTM_NEWADDR, ifp); Since we are no longer doing anycast, remove the above. > diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c > index 7b7bd44..b8a5261 100644 > --- a/net/ipv6/ip6_output.c > +++ b/net/ipv6/ip6_output.c > @@ -857,6 +857,34 @@ static int ip6_dst_lookup_tail(struct sock *sk, > > if (ipv6_addr_any(&fl->fl6_src)) { > err = ipv6_get_saddr(*dst, &fl->fl6_dst, &fl->fl6_src); > +#ifdef CONFIG_IPV6_OPTIMISTIC_DAD > + /* > + * Here if the dst entry we've looked up > + * has a neighbour entry that is in the INCOMPLETE > + * state and the src address from the flow is > + * marked as OPTIMISTIC, we release the found > + * dst entry and replace it instead with the > + * dst entry of the nexthop router > + */ > + if (!((*dst)->neighbour->nud_state & NUD_VALID)) { > + struct inet6_ifaddr *ifp; > + struct flowi fl_gw; > + ifp = ipv6_get_ifaddr(&fl->fl6_src, (*dst)->dev, 1); > + > + if (ifp && ifp->flags & IFA_F_OPTIMISTIC) { > + /* > + * We need to get the dst entry for the > + * default router instead > + */ > + dst_release(*dst); > + memcpy(&fl_gw, fl, sizeof(struct flowi)); > + memset(&fl_gw.fl6_dst, 0, sizeof(struct > in6_addr)); > + *dst = ip6_route_output(sk, &fl_gw); > + if ((err = (*dst)->error)) > + goto out_err_release; > > + } > + } > +#endif > if (err) > goto out_err_release; This actually doesn't look right What if ipv6_get_saddr returned an error? I think the new code should go after the 'goto out_err_release;'... That way, we do optimistic checks if we have a valid source address. > } > diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c > index 882cde4..9c5273c 100644 > --- a/net/ipv6/mcast.c > +++ b/net/ipv6/mcast.c > @@ -1411,7 +1411,7 @@ static struct sk_buff *mld_newpack(struct net_device > *dev, int size) > > skb_reserve(skb, LL_RESERVED_SPACE(dev)); > > - if (ipv6_get_lladdr(dev, &addr_buf)) { > + if (ipv6_get_lladdr(dev, &addr_buf, IFA_F_TENTATIVE)) { > /* : >* use unspecified address as the source address >* when a valid link-local address is not available. > @@ -1789,7 +1789,7 @@ static void igmp6_send(struct in6_addr *addr, struct > net_device *dev, int type) > > skb_reserve(skb, LL_RESERVED_SPACE(dev)); > > - if (ipv6_get_lladdr(dev, &addr_buf)) { > + if (ipv6_get_lladdr(dev, &addr_buf, IFA_F_TENTATIVE)) { > /* : >* use unspecified address as the source address >* when a valid link-local address is not available. > diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c > index 39bb658..7400805 100644 > --- a/net/ipv6/ndisc.c > +++ b/net/ipv6/ndisc.c > @@ -447,6 +447,8 @@ static void ndisc_send_na(struct net_device *dev, struct > neighbour *neigh, > ifp = ipv6_get_ifaddr(solicited_addr, dev, 1); > if (ifp) { > src_addr = solicited_addr; > + if (ifp->flags & IFA_F_OPTIMISTIC) > + override = 0; > in6_ifa_put(ifp); > } else { > if (ipv6_dev_get_saddr(dev, daddr, &tmpaddr)) > @@ -500,6 +502,7 @@ static void ndisc_send_na(struct net_device *dev, struct > neighbour *neigh, > msg->icmph.icmp6_solicited = solicited; > msg->icmph.icmp6_override = override; > > + Empty line... > /* Set the target address. */ > ipv6_addr_copy(&msg->target, solicited_addr); > > @@ -542,7 +545,8 @@ void ndisc_send_ns(struct net_device *dev, struct > neighbour *neigh, > int send_llinfo; > > if (saddr == NULL) { > - if (ipv6_get_lladdr(dev, &addr_buf)) > + if (ipv6_get_lladdr(dev, &addr_buf, > +(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC))) > return; > saddr = &addr_buf; > } > @@ -559,7 +563,7 @@ void ndisc_send_ns(struct net_device *dev, struct > neighbour *neigh, > return; > > len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr); > - send_llinfo = dev->addr_len &&
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
On Tue, Feb 06, 2007 at 07:51:44AM -0500, Neil Horman wrote: > On Tue, Feb 06, 2007 at 10:24:05AM +0900, YOSHIFUJI Hideaki / 吉藤英明 wrote: > > Hello. > > > > Thank you Yoshifuji. To be honest, I've been focused on functionality rather Ok, New patch attached, taking Vlad and Yoshifujis latest comments into account. Vlad, as you mentioned, I too looked and saw that we already join the all nodes multicast address in ipv6_add_dev, so the additional anycast join is incorrect, and has been removed. Whitespace/tabs have been cleaned up, code has been consolidated/beautified as per suggestions. I'm testing now, and early results are good. Thanks & Regards Neil Signed-off-by: Neil Horman <[EMAIL PROTECTED]> include/linux/if_addr.h |1 include/linux/ipv6.h|4 ++ include/linux/sysctl.h |1 include/net/addrconf.h |4 +- net/ipv6/Kconfig| 10 + net/ipv6/addrconf.c | 93 net/ipv6/ip6_output.c | 28 ++ net/ipv6/mcast.c|4 +- net/ipv6/ndisc.c| 84 ++- 9 files changed, 187 insertions(+), 42 deletions(-) diff --git a/include/linux/if_addr.h b/include/linux/if_addr.h index d557e4c..43f3bed 100644 --- a/include/linux/if_addr.h +++ b/include/linux/if_addr.h @@ -39,6 +39,7 @@ enum #define IFA_F_TEMPORARYIFA_F_SECONDARY #defineIFA_F_NODAD 0x02 +#define IFA_F_OPTIMISTIC 0x04 #defineIFA_F_HOMEADDRESS 0x10 #define IFA_F_DEPRECATED 0x20 #define IFA_F_TENTATIVE0x40 diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index f824113..bf93c1b 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -177,6 +177,9 @@ struct ipv6_devconf { #endif #endif __s32 proxy_ndp; +#ifdef CONFIG_IPV6_OPTIMISTIC_DAD + __s32 optimistic_dad; +#endif void*sysctl; }; @@ -205,6 +208,7 @@ enum { DEVCONF_RTR_PROBE_INTERVAL, DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN, DEVCONF_PROXY_NDP, + DEVCONF_OPTIMISTIC_DAD, DEVCONF_MAX }; diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 81480e6..972a33a 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -570,6 +570,7 @@ enum { NET_IPV6_RTR_PROBE_INTERVAL=21, NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=22, NET_IPV6_PROXY_NDP=23, + NET_IPV6_OPTIMISTIC_DAD=24, __NET_IPV6_MAX }; diff --git a/include/net/addrconf.h b/include/net/addrconf.h index 88df8fc..d248a19 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -73,7 +73,9 @@ extern intipv6_get_saddr(struct dst_entry *dst, extern int ipv6_dev_get_saddr(struct net_device *dev, struct in6_addr *daddr, struct in6_addr *saddr); -extern int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *); +extern int ipv6_get_lladdr(struct net_device *dev, + struct in6_addr *, + unsigned char banned_flags); extern int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2); extern voidaddrconf_join_solict(struct net_device *dev, diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig index deb4101..822d3eb 100644 --- a/net/ipv6/Kconfig +++ b/net/ipv6/Kconfig @@ -57,6 +57,16 @@ config IPV6_ROUTE_INFO If unsure, say N. +config IPV6_OPTIMISTIC_DAD + bool "IPv6: Enable RFC 4429 Optimistic DAD (EXPERIMENTAL)" + depends on IPV6 && EXPERIMENTAL + ---help--- + This is experimental support for optimistic Duplicate + Address Detection. It allows for autoconfigured addresses + to be used more quickly. + + If unsure, say N. + config INET6_AH tristate "IPv6: AH transformation" depends on IPV6 diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index e385469..f2bf7da 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -594,6 +594,16 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen, ifa->rt = rt; + /* +* part one of RFC 4429, section 3.3 +* We should not configure an address as +* optimistic if we do not yet know the link +* layer address of out nexhop router +*/ + + if (rt->rt6i_nexthop == NULL) + ifa->flags &= ~IFA_F_OPTIMISTIC; + ifa->idev = idev; in6_dev_hold(idev); /* For caller */ @@ -770,6 +780,7 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, struct inet6_ifaddr *i int tmp_plen; int ret = 0; int max_addresses; +
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
On Tue, Feb 06, 2007 at 10:24:05AM +0900, YOSHIFUJI Hideaki / 吉藤英明 wrote: > Hello. > Thank you Yoshifuji. To be honest, I've been focused on functionality rather than pretty so far, figuring I'd clean up the tabbing from my various patch inclusions/reversions when we had agreed that the functionality looked good. I'll fix up my tabbing/spacing, as well as your other comments in my next post. Regards Neil - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
From: YOSHIFUJI Hideaki <[EMAIL PROTECTED]> Date: Tue, 06 Feb 2007 10:44:08 +0900 (JST) > Yes, I agree, but I think it is different issue, and > maybe, we should check and change other places as well, > in separate patch(es). I agree. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
In article <[EMAIL PROTECTED]> (at Mon, 05 Feb 2007 17:32:58 -0800 (PST)), David Miller <[EMAIL PROTECTED]> says: > From: YOSHIFUJI Hideaki <[EMAIL PROTECTED]> > Date: Tue, 06 Feb 2007 10:24:05 +0900 (JST) > > > > @@ -498,7 +500,8 @@ static void ndisc_send_na(struct net_device *dev, > > > struct neighbour *neigh, > > > msg->icmph.icmp6_unused = 0; > > > msg->icmph.icmp6_router= router; > > > msg->icmph.icmp6_solicited = solicited; > > > -msg->icmph.icmp6_override = override; > > > + msg->icmph.icmp6_override = override; > > > + > > > > > > /* Set the target address. */ > > > ipv6_addr_copy(&msg->target, solicited_addr); > > > > Why do you "change" this? > > He edited it, but then reverted his change but in the > process added proper tab characters :-) It is easy > to miss things like this. I know, you know. :-) > This whole file has a lot of lines lacking proper tab > characters. Yes, I agree, but I think it is different issue, and maybe, we should check and change other places as well, in separate patch(es). --yoshfuji - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
From: YOSHIFUJI Hideaki <[EMAIL PROTECTED]> Date: Tue, 06 Feb 2007 10:24:05 +0900 (JST) > > @@ -498,7 +500,8 @@ static void ndisc_send_na(struct net_device *dev, > > struct neighbour *neigh, > > msg->icmph.icmp6_unused = 0; > > msg->icmph.icmp6_router= router; > > msg->icmph.icmp6_solicited = solicited; > > -msg->icmph.icmp6_override = override; > > + msg->icmph.icmp6_override = override; > > + > > > > /* Set the target address. */ > > ipv6_addr_copy(&msg->target, solicited_addr); > > Why do you "change" this? He edited it, but then reverted his change but in the process added proper tab characters :-) It is easy to miss things like this. This whole file has a lot of lines lacking proper tab characters. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
Hello. In article <[EMAIL PROTECTED]> (at Mon, 5 Feb 2007 15:56:51 -0500), Neil Horman <[EMAIL PROTECTED]> says: > if (ifp == NULL && valid_lft) { > int max_addresses = in6_dev->cnf.max_addresses; > + u32 addr_flags = 0; > + > +#ifdef CONFIG_IPV6_OPTIMISTIC_DAD > + if (in6_dev->cnf.optimistic_dad && > + !ipv6_devconf.forwarding) > + addr_flags = IFA_F_OPTIMISTIC; > +#endif > > /* Do not allow to create too much of autoconfigured >* addresses; this would be too easy way to crash > kernel. > @@ -1742,7 +1762,8 @@ ok: > if (!max_addresses || > ipv6_count_addresses(in6_dev) < max_addresses) > ifp = ipv6_add_addr(in6_dev, &addr, > pinfo->prefix_len, > - > addr_type&IPV6_ADDR_SCOPE_MASK, 0); > + > addr_type&IPV6_ADDR_SCOPE_MASK, > + addr_flags); > > if (!ifp || IS_ERR(ifp)) { > in6_dev_put(in6_dev); > @@ -1945,7 +1966,11 @@ static int inet6_addr_add(int ifindex, struct in6_addr > *pfx, int plen, > ifp->prefered_lft = prefered_lft; > ifp->tstamp = jiffies; > spin_unlock_bh(&ifp->lock); > - > + /* > + * Note that section 3.1 of RFC 4429 indicates > + * That the Optimistic flag should not be set for > + * manually configured addresses > + */ > addrconf_dad_start(ifp, 0); > in6_ifa_put(ifp); > addrconf_verify(0); > @@ -2122,8 +2147,16 @@ static void init_loopback(struct net_device *dev) > static void addrconf_add_linklocal(struct inet6_dev *idev, struct in6_addr > *addr) > { > struct inet6_ifaddr * ifp; > + u32 addr_flags = IFA_F_PERMANENT; > + > +#ifdef CONFIG_IPV6_OPTIMISTIC_DAD > + if (idev->cnf.optimistic_dad && > + !ipv6_devconf.forwarding) > + addr_flags |= IFA_F_OPTIMISTIC; > +#endif > + > > - ifp = ipv6_add_addr(idev, addr, 64, IFA_LINK, IFA_F_PERMANENT); > + ifp = ipv6_add_addr(idev, addr, 64, IFA_LINK, addr_flags); > if (!IS_ERR(ifp)) { > addrconf_dad_start(ifp, 0); > in6_ifa_put(ifp); > @@ -2190,7 +2223,7 @@ ipv6_inherit_linklocal(struct inet6_dev *idev, struct > net_device *link_dev) > { > struct in6_addr lladdr; > > - if (!ipv6_get_lladdr(link_dev, &lladdr)) { > + if (!ipv6_get_lladdr(link_dev, &lladdr, IFA_F_TENTATIVE)) { > addrconf_add_linklocal(idev, &lladdr); > return 0; > } > @@ -2527,7 +2560,11 @@ static void addrconf_dad_kick(struct inet6_ifaddr *ifp) > unsigned long rand_num; > struct inet6_dev *idev = ifp->idev; > > - rand_num = net_random() % (idev->cnf.rtr_solicit_delay ? : 1); > + if (ifp->flags & IFA_F_OPTIMISTIC) > + rand_num = 0; > + else > + rand_num = net_random() % (idev->cnf.rtr_solicit_delay ? : 1); > + > ifp->probes = idev->cnf.dad_transmits; > addrconf_mod_timer(ifp, AC_DAD, rand_num); > } > @@ -2553,7 +2590,7 @@ static void addrconf_dad_start(struct inet6_ifaddr > *ifp, u32 flags) > if (dev->flags&(IFF_NOARP|IFF_LOOPBACK) || > !(ifp->flags&IFA_F_TENTATIVE) || > ifp->flags & IFA_F_NODAD) { > - ifp->flags &= ~IFA_F_TENTATIVE; > + ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC); > spin_unlock_bh(&ifp->lock); > read_unlock_bh(&idev->lock); > > @@ -2573,6 +2610,14 @@ static void addrconf_dad_start(struct inet6_ifaddr > *ifp, u32 flags) > addrconf_dad_stop(ifp); > return; > } > + > + /* > + * Optimistic nodes need to join the anycast address > + * right away > + */ > + if (ifp->flags & IFA_F_OPTIMISTIC) > + addrconf_join_anycast(ifp); > + > addrconf_dad_kick(ifp); > spin_unlock_bh(&ifp->lock); > out: > @@ -2597,7 +2642,7 @@ static void addrconf_dad_timer(unsigned long data) >* DAD was successful >*/ > > - ifp->flags &= ~IFA_F_TENTATIVE; > + ifp->flags &= ~(IFA_F_TENTATIVE|IFA_F_OPTIMISTIC); > spin_unlock_bh(&ifp->lock); > read_unlock_bh(&idev->lock); > > @@ -2627,6 +2672,9 @@ static void addrconf_dad_completed(struct inet6_ifaddr > *ifp) >* Configure the address for reception. Now it is valid. >*/ > > + if (ifp->flags & IFA_F_OPTIMISTIC) > + addrconf_leave_anycast(ifp); > + > ipv6_ifa_notify(RTM_NEWADDR, ifp); > > /* If added prefix is link local and forwarding is off, > @@ -3398,6 +3446,9 @@ st
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
On Mon, Feb 05, 2007 at 12:33:55PM -0500, Brian Haley wrote: > >Please, if you think you can find a way for us to do optimistic dad flags > >as > >opt-in, rather than masked out, I'm all for it. Thanks! > > This patch should apply on-top of yours, if you want I can send the > whole thing out too. I've only compile-tested it, so don't know if it > behaves the same as your original. > > -Brian > Thank you brian, I'll look over and incorporate this into my new tree as I'm fixing up the anycast hole Vlad brought up Thanks & Regards Neil > > Signed-off-by: Brian Haley <[EMAIL PROTECTED]> > diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c > index c341371..ddac8b0 100644 > --- a/net/ipv6/addrconf.c > +++ b/net/ipv6/addrconf.c > @@ -593,13 +593,8 @@ ipv6_add_addr(struct inet6_dev *idev, co > ifa->cstamp = ifa->tstamp = jiffies; > > ifa->rt = rt; > -#ifdef CONFIG_IPV6_OPTIMISTIC_DAD > - if (!idev->cnf.optimistic_dad || ipv6_devconf.forwarding || > -(ifa->rt->rt6i_nexthop == NULL)) > + if (rt->rt6i_nexthop == NULL) > ifa->flags &= ~IFA_F_OPTIMISTIC; > -#else > - ifa->flags &= ~IFA_F_OPTIMISTIC; > -#endif > ifa->idev = idev; > in6_dev_hold(idev); > /* For caller */ > @@ -776,6 +771,7 @@ static int ipv6_create_tempaddr(struct i > int tmp_plen; > int ret = 0; > int max_addresses; > + u32 addr_flags; > > write_lock(&idev->lock); > if (ift) { > @@ -833,11 +829,17 @@ retry: > spin_unlock_bh(&ifp->lock); > > write_unlock(&idev->lock); > + > + addr_flags = IFA_F_TEMPORARY; > + /* set in addrconf_prefix_rcv() */ > + if (ifp->flags & IFA_F_OPTIMISTIC) > + addr_flags |= IFA_F_OPTIMISTIC; > + > ift = !max_addresses || > ipv6_count_addresses(idev) < max_addresses ? > ipv6_add_addr(idev, &addr, tmp_plen, > ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, > - IFA_F_TEMPORARY|IFA_F_OPTIMISTIC) : NULL; > + addr_flags) : NULL; > if (!ift || IS_ERR(ift)) { > in6_ifa_put(ifp); > in6_dev_put(idev); > @@ -1746,6 +1748,13 @@ ok: > > if (ifp == NULL && valid_lft) { > int max_addresses = in6_dev->cnf.max_addresses; > + u32 addr_flags = 0; > + > +#ifdef CONFIG_IPV6_OPTIMISTIC_DAD > + if (in6_dev->cnf.optimistic_dad && > + !ipv6_devconf.forwarding) > + addr_flags = IFA_F_OPTIMISTIC; > +#endif > > /* Do not allow to create too much of autoconfigured >* addresses; this would be too easy way to crash > kernel. > @@ -1753,7 +1762,8 @@ ok: > if (!max_addresses || > ipv6_count_addresses(in6_dev) < max_addresses) > ifp = ipv6_add_addr(in6_dev, &addr, > pinfo->prefix_len, > - > addr_type&IPV6_ADDR_SCOPE_MASK, 0); > + > addr_type&IPV6_ADDR_SCOPE_MASK, > + addr_flags); > > if (!ifp || IS_ERR(ifp)) { > in6_dev_put(in6_dev); > @@ -1762,10 +1772,6 @@ ok: > > update_lft = create = 1; > ifp->cstamp = jiffies; > -#ifdef CONFIG_IPV6_OPTIMISTIC_DAD > - if (ifp->idev->cnf.optimistic_dad) > - ifp->flags |= IFA_F_OPTIMISTIC; > -#endif > addrconf_dad_start(ifp, RTF_ADDRCONF|RTF_PREFIX_RT); > } > > @@ -2141,9 +2147,16 @@ static void init_loopback(struct net_dev > static void addrconf_add_linklocal(struct inet6_dev *idev, struct in6_addr > *addr) > { > struct inet6_ifaddr * ifp; > + u32 addr_flags = IFA_F_PERMANENT; > + > +#ifdef CONFIG_IPV6_OPTIMISTIC_DAD > + if (idev->cnf.optimistic_dad && > + !ipv6_devconf.forwarding) > + addr_flags |= IFA_F_OPTIMISTIC; > +#endif > + > > - ifp = ipv6_add_addr(idev, addr, 64, IFA_LINK, > - IFA_F_PERMANENT|IFA_F_OPTIMISTIC); > + ifp = ipv6_add_addr(idev, addr, 64, IFA_LINK, addr_flags); > if (!IS_ERR(ifp)) { > addrconf_dad_start(ifp, 0); > in6_ifa_put(ifp); - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
Please, if you think you can find a way for us to do optimistic dad flags as opt-in, rather than masked out, I'm all for it. Thanks! This patch should apply on-top of yours, if you want I can send the whole thing out too. I've only compile-tested it, so don't know if it behaves the same as your original. -Brian Signed-off-by: Brian Haley <[EMAIL PROTECTED]> diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index c341371..ddac8b0 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -593,13 +593,8 @@ ipv6_add_addr(struct inet6_dev *idev, co ifa->cstamp = ifa->tstamp = jiffies; ifa->rt = rt; -#ifdef CONFIG_IPV6_OPTIMISTIC_DAD - if (!idev->cnf.optimistic_dad || ipv6_devconf.forwarding || - (ifa->rt->rt6i_nexthop == NULL)) + if (rt->rt6i_nexthop == NULL) ifa->flags &= ~IFA_F_OPTIMISTIC; -#else - ifa->flags &= ~IFA_F_OPTIMISTIC; -#endif ifa->idev = idev; in6_dev_hold(idev); /* For caller */ @@ -776,6 +771,7 @@ static int ipv6_create_tempaddr(struct i int tmp_plen; int ret = 0; int max_addresses; + u32 addr_flags; write_lock(&idev->lock); if (ift) { @@ -833,11 +829,17 @@ retry: spin_unlock_bh(&ifp->lock); write_unlock(&idev->lock); + + addr_flags = IFA_F_TEMPORARY; + /* set in addrconf_prefix_rcv() */ + if (ifp->flags & IFA_F_OPTIMISTIC) + addr_flags |= IFA_F_OPTIMISTIC; + ift = !max_addresses || ipv6_count_addresses(idev) < max_addresses ? ipv6_add_addr(idev, &addr, tmp_plen, ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, - IFA_F_TEMPORARY|IFA_F_OPTIMISTIC) : NULL; + addr_flags) : NULL; if (!ift || IS_ERR(ift)) { in6_ifa_put(ifp); in6_dev_put(idev); @@ -1746,6 +1748,13 @@ ok: if (ifp == NULL && valid_lft) { int max_addresses = in6_dev->cnf.max_addresses; + u32 addr_flags = 0; + +#ifdef CONFIG_IPV6_OPTIMISTIC_DAD + if (in6_dev->cnf.optimistic_dad && + !ipv6_devconf.forwarding) +addr_flags = IFA_F_OPTIMISTIC; +#endif /* Do not allow to create too much of autoconfigured * addresses; this would be too easy way to crash kernel. @@ -1753,7 +1762,8 @@ ok: if (!max_addresses || ipv6_count_addresses(in6_dev) < max_addresses) ifp = ipv6_add_addr(in6_dev, &addr, pinfo->prefix_len, - addr_type&IPV6_ADDR_SCOPE_MASK, 0); + addr_type&IPV6_ADDR_SCOPE_MASK, + addr_flags); if (!ifp || IS_ERR(ifp)) { in6_dev_put(in6_dev); @@ -1762,10 +1772,6 @@ ok: update_lft = create = 1; ifp->cstamp = jiffies; -#ifdef CONFIG_IPV6_OPTIMISTIC_DAD - if (ifp->idev->cnf.optimistic_dad) -ifp->flags |= IFA_F_OPTIMISTIC; -#endif addrconf_dad_start(ifp, RTF_ADDRCONF|RTF_PREFIX_RT); } @@ -2141,9 +2147,16 @@ static void init_loopback(struct net_dev static void addrconf_add_linklocal(struct inet6_dev *idev, struct in6_addr *addr) { struct inet6_ifaddr * ifp; + u32 addr_flags = IFA_F_PERMANENT; + +#ifdef CONFIG_IPV6_OPTIMISTIC_DAD + if (idev->cnf.optimistic_dad && + !ipv6_devconf.forwarding) + addr_flags |= IFA_F_OPTIMISTIC; +#endif + - ifp = ipv6_add_addr(idev, addr, 64, IFA_LINK, - IFA_F_PERMANENT|IFA_F_OPTIMISTIC); + ifp = ipv6_add_addr(idev, addr, 64, IFA_LINK, addr_flags); if (!IS_ERR(ifp)) { addrconf_dad_start(ifp, 0); in6_ifa_put(ifp);
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
On Fri, Feb 02, 2007 at 06:57:37PM -0500, Brian Haley wrote: > Hi Vlad, > > Vlad Yasevich wrote: > >Brian Haley wrote: > >>Hi Neil, > >> > >>>@@ -830,7 +836,8 @@ retry: > >>> ift = !max_addresses || > >>> ipv6_count_addresses(idev) < max_addresses ? > >>>ipv6_add_addr(idev, &addr, tmp_plen, > >>>- ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, > >>>IFA_F_TEMPORARY) : NULL; > >>>+ ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, > >>>+ IFA_F_TEMPORARY|IFA_F_OPTIMISTIC) : NULL; > > > >Hi Brian > > > >>So why are you always adding these as optimistic now? Shouldn't this be > >>triggering off idev->cnf.optimistic_dad? I know you're clearing it in > >>ipv6_add_addr(), but I liked Vlad's suggestion of not setting it > >>initially since this way seems backwards. > > > >The troubling case seems to manually configured addresses > >(inet6_addr_add()). > >If we can clearly and easily distinguish between this case of address > >and all the other ones, then we can simply set the flag in ipv6_add_addr, > >like > >we set the tentative flag. > > Right, I guess maybe I'm trying to figure out what > idev->cnf.optimistic_dad means: > > 1. Interface supports OPTIMISTIC addresses > 2. All auto-configured addresses on interface are OPTIMISTIC > 3. ??? > The flag means that the interface supports optimistic DAD for all addresses which are eligible to take advantage of RFC 4429. As Vlad mentioned manually configured addresses are excluded from that set. > All other addresses are created w/out OPTIMISTIC set. > > I think manually-configured addresses can be tagged as OPTIMISTIC just > like MIPv6 Home Addresses are if we just change this line in > inet6_rtm_newaddr(): > > < ifa_flags = ifm->ifa_flags & (IFA_F_NODAD | IFA_F_HOMEADDRESS); > -- > > ifa_flags = ifm->ifa_flags & (IFA_F_NODAD | IFA_F_HOMEADDRESS | > IFA_F_OPTIMISTIC); > > and tweak the rest of the code, but that doesn't cover the > addrconf_add_ifaddr() codepath via ioctl(SIOCSIFADDR). > > I can generate a patch based-on Neil's, but it will take me until Monday > to get it out. > Please, if you think you can find a way for us to do optimistic dad flags as opt-in, rather than masked out, I'm all for it. Thanks! Neil > -Brian - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
On Fri, Feb 02, 2007 at 05:22:31PM -0500, Vlad Yasevich wrote: > Neil Horman wrote: > > On Fri, Feb 02, 2007 at 11:46:08AM -0800, David Miller wrote: > >> From: Neil Horman <[EMAIL PROTECTED]> > >> Date: Fri, 2 Feb 2007 14:06:34 -0500 > >> > >>> Ok, I'm still testing it, but heres a new patch for review. > >>> Significant changes include the addition of a > >>> CONFIG_IPV6_OPTIMISTIC_DAD option that is dependent on the inclusion > >>> of both IPPV6 and EXPERIMENTAL options, as well as a new method for > >>> redirecting packets from optimistic sources to incomplete neighbors > >>> by instead looking up a default router in ip6_dst_lookup_tail, as I > >>> described in my previous note. > >> This looks largely fine to me, but I wonder about one bit: > >> > >> + > >> + /* > >> + * Optimistic nodes need to join the anycast address > >> + * right away > >> + */ > >> + if (ifp->flags & IFA_F_OPTIMISTIC) > >> + addrconf_join_anycast(ifp); > >> + > >> > >> If something can clear that bit during the DAD, we won't > >> call addrconf_leave_anycast() later. Can that happen? > > The only way the flag should get cleared once we've started DAD is when it > > completes or fails. In the failure case, we destroy the ifaddr structure, > > which > > I think should force a leave_anycast, while the completed condition calls > > addrconf_leave_anycast as part of the completion process before it clears > > the > > flags, so I think we should be ok. If anyone sees anything to the contrary, > > please let me know and I'll be sure to plug the hole. > > I think there is a hole: > > Looking for addrconf_leave_anycast() shows: > dev_forward_change(): 475 addrconf_leave_anycast(ifa); > __ipv6_ifa_notify(): 3613 addrconf_leave_anycast(ifp); > > Problem: __ipv6_ifa_notify only performs the 'leave' if forwarding is > enabled. > However, OPTIMISTIC, is set when forwarding is _disabled_. > > > -vlad I think you may be right. I'll fix that up monday AM. Thanks! Neil - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
On Fri, Feb 02, 2007 at 04:50:35PM -0500, Vlad Yasevich wrote: > Neil Horman wrote: > > Ok, I'm still testing it, but heres a new patch for review. Significant > > changes > > include the addition of a CONFIG_IPV6_OPTIMISTIC_DAD option that is > > dependent on > > the inclusion of both IPPV6 and EXPERIMENTAL options, as well as a new > > method > > for redirecting packets from optimistic sources to incomplete neighbors by > > instead looking up a default router in ip6_dst_lookup_tail, as I described > > in my > > previous note. > > > > Hi Neil > > Still digesting the routing changes, but I think you missed > addrconf_prefix_rcv()... ;) > I may well have, I'll take a good look on monday. Thanks for the eyes :) Neil > > -vlad - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
Hi Vlad, Vlad Yasevich wrote: Brian Haley wrote: Hi Neil, @@ -830,7 +836,8 @@ retry: ift = !max_addresses || ipv6_count_addresses(idev) < max_addresses ? ipv6_add_addr(idev, &addr, tmp_plen, - ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, IFA_F_TEMPORARY) : NULL; + ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, + IFA_F_TEMPORARY|IFA_F_OPTIMISTIC) : NULL; Hi Brian So why are you always adding these as optimistic now? Shouldn't this be triggering off idev->cnf.optimistic_dad? I know you're clearing it in ipv6_add_addr(), but I liked Vlad's suggestion of not setting it initially since this way seems backwards. The troubling case seems to manually configured addresses (inet6_addr_add()). If we can clearly and easily distinguish between this case of address and all the other ones, then we can simply set the flag in ipv6_add_addr, like we set the tentative flag. Right, I guess maybe I'm trying to figure out what idev->cnf.optimistic_dad means: 1. Interface supports OPTIMISTIC addresses 2. All auto-configured addresses on interface are OPTIMISTIC 3. ??? All other addresses are created w/out OPTIMISTIC set. I think manually-configured addresses can be tagged as OPTIMISTIC just like MIPv6 Home Addresses are if we just change this line in inet6_rtm_newaddr(): < ifa_flags = ifm->ifa_flags & (IFA_F_NODAD | IFA_F_HOMEADDRESS); -- > ifa_flags = ifm->ifa_flags & (IFA_F_NODAD | IFA_F_HOMEADDRESS | IFA_F_OPTIMISTIC); and tweak the rest of the code, but that doesn't cover the addrconf_add_ifaddr() codepath via ioctl(SIOCSIFADDR). I can generate a patch based-on Neil's, but it will take me until Monday to get it out. -Brian - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
Neil Horman wrote: > On Fri, Feb 02, 2007 at 11:46:08AM -0800, David Miller wrote: >> From: Neil Horman <[EMAIL PROTECTED]> >> Date: Fri, 2 Feb 2007 14:06:34 -0500 >> >>> Ok, I'm still testing it, but heres a new patch for review. >>> Significant changes include the addition of a >>> CONFIG_IPV6_OPTIMISTIC_DAD option that is dependent on the inclusion >>> of both IPPV6 and EXPERIMENTAL options, as well as a new method for >>> redirecting packets from optimistic sources to incomplete neighbors >>> by instead looking up a default router in ip6_dst_lookup_tail, as I >>> described in my previous note. >> This looks largely fine to me, but I wonder about one bit: >> >> + >> +/* >> + * Optimistic nodes need to join the anycast address >> + * right away >> + */ >> +if (ifp->flags & IFA_F_OPTIMISTIC) >> +addrconf_join_anycast(ifp); >> + >> >> If something can clear that bit during the DAD, we won't >> call addrconf_leave_anycast() later. Can that happen? > The only way the flag should get cleared once we've started DAD is when it > completes or fails. In the failure case, we destroy the ifaddr structure, > which > I think should force a leave_anycast, while the completed condition calls > addrconf_leave_anycast as part of the completion process before it clears the > flags, so I think we should be ok. If anyone sees anything to the contrary, > please let me know and I'll be sure to plug the hole. I think there is a hole: Looking for addrconf_leave_anycast() shows: dev_forward_change(): 475 addrconf_leave_anycast(ifa); __ipv6_ifa_notify():3613 addrconf_leave_anycast(ifp); Problem: __ipv6_ifa_notify only performs the 'leave' if forwarding is enabled. However, OPTIMISTIC, is set when forwarding is _disabled_. -vlad - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
Brian Haley wrote: > Hi Neil, > >> @@ -830,7 +836,8 @@ retry: >> ift = !max_addresses || >>ipv6_count_addresses(idev) < max_addresses ? >> ipv6_add_addr(idev, &addr, tmp_plen, >> - ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, >> IFA_F_TEMPORARY) : NULL; >> + ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, >> + IFA_F_TEMPORARY|IFA_F_OPTIMISTIC) : NULL; > Hi Brian > So why are you always adding these as optimistic now? Shouldn't this be > triggering off idev->cnf.optimistic_dad? I know you're clearing it in > ipv6_add_addr(), but I liked Vlad's suggestion of not setting it > initially since this way seems backwards. The troubling case seems to manually configured addresses (inet6_addr_add()). If we can clearly and easily distinguish between this case of address and all the other ones, then we can simply set the flag in ipv6_add_addr, like we set the tentative flag. So, we can introduce another parameter to ipv6_add_addr() or another flag that can distinguish manual config. Otherwise, we can keep the code as is, passing the optimistic flag from needed callers, and clearing it inside ipv6_add_addr(). My thought was to clear it from the 'flags' parameter before ifa->flags was set, but that doesn't really matter. -vlad - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
Neil Horman wrote: > Ok, I'm still testing it, but heres a new patch for review. Significant > changes > include the addition of a CONFIG_IPV6_OPTIMISTIC_DAD option that is dependent > on > the inclusion of both IPPV6 and EXPERIMENTAL options, as well as a new method > for redirecting packets from optimistic sources to incomplete neighbors by > instead looking up a default router in ip6_dst_lookup_tail, as I described in > my > previous note. > Hi Neil Still digesting the routing changes, but I think you missed addrconf_prefix_rcv()... ;) -vlad - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
Hi Neil, @@ -830,7 +836,8 @@ retry: ift = !max_addresses || ipv6_count_addresses(idev) < max_addresses ? ipv6_add_addr(idev, &addr, tmp_plen, - ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, IFA_F_TEMPORARY) : NULL; + ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, + IFA_F_TEMPORARY|IFA_F_OPTIMISTIC) : NULL; So why are you always adding these as optimistic now? Shouldn't this be triggering off idev->cnf.optimistic_dad? I know you're clearing it in ipv6_add_addr(), but I liked Vlad's suggestion of not setting it initially since this way seems backwards. @@ -2123,7 +2142,8 @@ static void addrconf_add_linklocal(struct inet6_dev *idev, struct in6_addr *addr { struct inet6_ifaddr * ifp; - ifp = ipv6_add_addr(idev, addr, 64, IFA_LINK, IFA_F_PERMANENT); + ifp = ipv6_add_addr(idev, addr, 64, IFA_LINK, + IFA_F_PERMANENT|IFA_F_OPTIMISTIC); Here too. -Brian - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
On Fri, Feb 02, 2007 at 11:46:08AM -0800, David Miller wrote: > From: Neil Horman <[EMAIL PROTECTED]> > Date: Fri, 2 Feb 2007 14:06:34 -0500 > > > Ok, I'm still testing it, but heres a new patch for review. > > Significant changes include the addition of a > > CONFIG_IPV6_OPTIMISTIC_DAD option that is dependent on the inclusion > > of both IPPV6 and EXPERIMENTAL options, as well as a new method for > > redirecting packets from optimistic sources to incomplete neighbors > > by instead looking up a default router in ip6_dst_lookup_tail, as I > > described in my previous note. > > This looks largely fine to me, but I wonder about one bit: > > + > + /* > + * Optimistic nodes need to join the anycast address > + * right away > + */ > + if (ifp->flags & IFA_F_OPTIMISTIC) > + addrconf_join_anycast(ifp); > + > > If something can clear that bit during the DAD, we won't > call addrconf_leave_anycast() later. Can that happen? The only way the flag should get cleared once we've started DAD is when it completes or fails. In the failure case, we destroy the ifaddr structure, which I think should force a leave_anycast, while the completed condition calls addrconf_leave_anycast as part of the completion process before it clears the flags, so I think we should be ok. If anyone sees anything to the contrary, please let me know and I'll be sure to plug the hole. Thanks & Regards Neil > - > To unsubscribe from this list: send the line "unsubscribe netdev" in > the body of a message to [EMAIL PROTECTED] > More majordomo info at http://vger.kernel.org/majordomo-info.html - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
From: Neil Horman <[EMAIL PROTECTED]> Date: Fri, 2 Feb 2007 14:06:34 -0500 > Ok, I'm still testing it, but heres a new patch for review. > Significant changes include the addition of a > CONFIG_IPV6_OPTIMISTIC_DAD option that is dependent on the inclusion > of both IPPV6 and EXPERIMENTAL options, as well as a new method for > redirecting packets from optimistic sources to incomplete neighbors > by instead looking up a default router in ip6_dst_lookup_tail, as I > described in my previous note. This looks largely fine to me, but I wonder about one bit: + + /* +* Optimistic nodes need to join the anycast address +* right away +*/ + if (ifp->flags & IFA_F_OPTIMISTIC) + addrconf_join_anycast(ifp); + If something can clear that bit during the DAD, we won't call addrconf_leave_anycast() later. Can that happen? - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
Ok, I'm still testing it, but heres a new patch for review. Significant changes include the addition of a CONFIG_IPV6_OPTIMISTIC_DAD option that is dependent on the inclusion of both IPPV6 and EXPERIMENTAL options, as well as a new method for redirecting packets from optimistic sources to incomplete neighbors by instead looking up a default router in ip6_dst_lookup_tail, as I described in my previous note. Thoughts and comments appreciated Thanks & Regards Neil Signed-off-by: Neil Horman <[EMAIL PROTECTED]> include/linux/if_addr.h |1 include/linux/ipv6.h|4 ++ include/linux/sysctl.h |1 include/net/addrconf.h |4 +- net/ipv6/Kconfig| 10 ++ net/ipv6/addrconf.c | 79 ++-- net/ipv6/ip6_output.c | 32 ++- net/ipv6/mcast.c|4 +- net/ipv6/ndisc.c| 79 +--- 9 files changed, 171 insertions(+), 43 deletions(-) diff --git a/include/linux/if_addr.h b/include/linux/if_addr.h index d557e4c..43f3bed 100644 --- a/include/linux/if_addr.h +++ b/include/linux/if_addr.h @@ -39,6 +39,7 @@ enum #define IFA_F_TEMPORARYIFA_F_SECONDARY #defineIFA_F_NODAD 0x02 +#define IFA_F_OPTIMISTIC 0x04 #defineIFA_F_HOMEADDRESS 0x10 #define IFA_F_DEPRECATED 0x20 #define IFA_F_TENTATIVE0x40 diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index f824113..bf93c1b 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -177,6 +177,9 @@ struct ipv6_devconf { #endif #endif __s32 proxy_ndp; +#ifdef CONFIG_IPV6_OPTIMISTIC_DAD + __s32 optimistic_dad; +#endif void*sysctl; }; @@ -205,6 +208,7 @@ enum { DEVCONF_RTR_PROBE_INTERVAL, DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN, DEVCONF_PROXY_NDP, + DEVCONF_OPTIMISTIC_DAD, DEVCONF_MAX }; diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 81480e6..972a33a 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -570,6 +570,7 @@ enum { NET_IPV6_RTR_PROBE_INTERVAL=21, NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=22, NET_IPV6_PROXY_NDP=23, + NET_IPV6_OPTIMISTIC_DAD=24, __NET_IPV6_MAX }; diff --git a/include/net/addrconf.h b/include/net/addrconf.h index 88df8fc..d248a19 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -73,7 +73,9 @@ extern intipv6_get_saddr(struct dst_entry *dst, extern int ipv6_dev_get_saddr(struct net_device *dev, struct in6_addr *daddr, struct in6_addr *saddr); -extern int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *); +extern int ipv6_get_lladdr(struct net_device *dev, + struct in6_addr *, + unsigned char banned_flags); extern int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2); extern voidaddrconf_join_solict(struct net_device *dev, diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig index deb4101..822d3eb 100644 --- a/net/ipv6/Kconfig +++ b/net/ipv6/Kconfig @@ -57,6 +57,16 @@ config IPV6_ROUTE_INFO If unsure, say N. +config IPV6_OPTIMISTIC_DAD + bool "IPv6: Enable RFC 4429 Optimistic DAD (EXPERIMENTAL)" + depends on IPV6 && EXPERIMENTAL + ---help--- + This is experimental support for optimistic Duplicate + Address Detection. It allows for autoconfigured addresses + to be used more quickly. + + If unsure, say N. + config INET6_AH tristate "IPv6: AH transformation" depends on IPV6 diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 2a7e461..d00e3f6 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -593,7 +593,13 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen, ifa->cstamp = ifa->tstamp = jiffies; ifa->rt = rt; - +#ifdef CONFIG_IPV6_OPTIMISTIC_DAD + if (!idev->cnf.optimistic_dad || ipv6_devconf.forwarding || + (ifa->rt->rt6i_nexthop == NULL)) + ifa->flags &= ~IFA_F_OPTIMISTIC; +#else + ifa->flags &= ~IFA_F_OPTIMISTIC; +#endif ifa->idev = idev; in6_dev_hold(idev); /* For caller */ @@ -830,7 +836,8 @@ retry: ift = !max_addresses || ipv6_count_addresses(idev) < max_addresses ? ipv6_add_addr(idev, &addr, tmp_plen, - ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, IFA_F_TEMPORARY) : NULL; + ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, +
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
On Wed, Jan 31, 2007 at 01:16:29AM +0900, YOSHIFUJI Hideaki / 吉藤英明 wrote: > In article <[EMAIL PROTECTED]> (at Tue, 30 Jan 2007 08:02:08 -0500), Neil > Horman <[EMAIL PROTECTED]> says: > > > > I do not think we should copy neighbor information from (one of) > > > default routers, but use temporary neigh entry (or neigh in new state) > > > for such datagrams in stead. We should aware that: > > > > > Not sure how that is different from what I'm proposing. a neighbor entry > > that > > maps a given host on the current subnet to the MAC of the default router, > > that > > then gets flushed when DAD completes is temporary, as far as I can see. > > > > > 1) default router's link-layer address may change. > > True, but if this changes, all our network connectivity is lost, until the > > normal neighbor solicitation process completes anyway. > > No, router may update its link-layer address by NA with Override flag set. > In that case, we must use new link-layer for subsequent packets from > our opportunistic address duing DAD. > > > > 2) we may have more than one default routers. > > True, but I would think we could select any of them and this would work. > > Granted, we wouldn't use all the default routers in the table as we would > > with > > routed frames, but I'm not sure how we avoid that. > > I mean, if the status of the selected default router has changed or > has been deleted, we should try other router, at least. > > > > 3) the default router's link-layer may be invalidated. > > > > > yes, but this would be bad for the same reason as (1) > > We MUST take this into account. > Ok, understood. In summary, we can't simply fill out the neighbor entry for a given host with the address of a default router because 1) Any changes to the router link layer address wont be reflected in that when it (the change) happens, redering the local address unable to communicate until the neighbour entries age out. 2) There may be more than one default router as selected by the routing policy, and we should be able to try those routes if the selected router becomes unavailable It sounds like what we need to do is shim into the route lookup code, and detect there if we need to redirect every packet as they are sent. I think I may have an idea for this. What if we implement the lookup in ip6_dst_lookup_tail. In there we can check if the associated neigh entry for the resolved dst_entry is in a INCOMPLETE or FAILED state, and if the ifaddr associated withe the source address passed in via the flowi struct is in an OPTIMISTIC state. If both conditions are true, we release the dst_entry that we origionally looked up, and instead conduct a second lookup with a newly constructed flowi struct with the dst addr replaced with an all zeros address (which I think should return a gateway, selected as per routing policy). Then we can return that dst entry instead. Since ip6_push_pending frames seems to bulid the ipv6 header using the addresses in the flowi struct passed into ip6_*_dst_lookup from *_sendmsg routines, and the link layer header is built based on the info gathered from the resolved dst_entry (If I'm reading the code right), I think this give us what we want, in that we redirect to a gatweway when we send from an optimistic address, and we select the gateway based on the logic in the route lookup code (ip6_route_output() specifically). I'm trying to implement this right now, and will post a new patch as soon as I have it done. In the meantime, any thoughts would be most appreciated. Regards Neil > --yoshfuji > - > To unsubscribe from this list: send the line "unsubscribe netdev" in > the body of a message to [EMAIL PROTECTED] > More majordomo info at http://vger.kernel.org/majordomo-info.html - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
In article <[EMAIL PROTECTED]> (at Tue, 30 Jan 2007 08:02:08 -0500), Neil Horman <[EMAIL PROTECTED]> says: > > I do not think we should copy neighbor information from (one of) > > default routers, but use temporary neigh entry (or neigh in new state) > > for such datagrams in stead. We should aware that: > > > Not sure how that is different from what I'm proposing. a neighbor entry that > maps a given host on the current subnet to the MAC of the default router, that > then gets flushed when DAD completes is temporary, as far as I can see. > > > 1) default router's link-layer address may change. > True, but if this changes, all our network connectivity is lost, until the > normal neighbor solicitation process completes anyway. No, router may update its link-layer address by NA with Override flag set. In that case, we must use new link-layer for subsequent packets from our opportunistic address duing DAD. > > 2) we may have more than one default routers. > True, but I would think we could select any of them and this would work. > Granted, we wouldn't use all the default routers in the table as we would with > routed frames, but I'm not sure how we avoid that. I mean, if the status of the selected default router has changed or has been deleted, we should try other router, at least. > > 3) the default router's link-layer may be invalidated. > > > yes, but this would be bad for the same reason as (1) We MUST take this into account. --yoshfuji - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
On Tue, Jan 30, 2007 at 07:25:36AM +0900, YOSHIFUJI Hideaki / 吉藤英明 wrote: > In article <[EMAIL PROTECTED]> (at Mon, 29 Jan 2007 16:30:13 -0500), Neil > Horman <[EMAIL PROTECTED]> says: > > > Quick reality check here. In thinking about how best to go about this > > redirection of frames to the default router, based on Dave M.s input, I > > think > > that the best solution would be in ndisc_send_ns. What I was thinking was > > that > > in ndisc_send_ns, we already detect if a source address is optimistic and > > squash > > the transmission of the frame there. What if in addition to that > > supression, we > : > > Well...I think it is okay if sending NS is deferred (or omit) in > ndisc_send_ns() (or in ndisc_solicit(), probably) if the source is Agreed, the code already does this, per the RFC. > optimistic address, but... I'm not sure so far if it is appropriate > from design POV. The ndisc_send_ns() nor ndisc_solicit() is not about > our current neigh state machine, at all. > Thats true, but I'm not sure how we can avoid that. > I do not think we should copy neighbor information from (one of) > default routers, but use temporary neigh entry (or neigh in new state) > for such datagrams in stead. We should aware that: > Not sure how that is different from what I'm proposing. a neighbor entry that maps a given host on the current subnet to the MAC of the default router, that then gets flushed when DAD completes is temporary, as far as I can see. > 1) default router's link-layer address may change. True, but if this changes, all our network connectivity is lost, until the normal neighbor solicitation process completes anyway. > 2) we may have more than one default routers. True, but I would think we could select any of them and this would work. Granted, we wouldn't use all the default routers in the table as we would with routed frames, but I'm not sure how we avoid that. > 3) the default router's link-layer may be invalidated. > yes, but this would be bad for the same reason as (1) > Anyway, I'm start thinking about CONFIG_IPV6_OPTIMISTIC_DAD to > make sure the new code path will not break anything else... > Agreed, I'll add in the config option with my next patch. > --yoshfuji > - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
In article <[EMAIL PROTECTED]> (at Mon, 29 Jan 2007 16:30:13 -0500), Neil Horman <[EMAIL PROTECTED]> says: > Quick reality check here. In thinking about how best to go about this > redirection of frames to the default router, based on Dave M.s input, I think > that the best solution would be in ndisc_send_ns. What I was thinking was > that > in ndisc_send_ns, we already detect if a source address is optimistic and > squash > the transmission of the frame there. What if in addition to that supression, > we : Well...I think it is okay if sending NS is deferred (or omit) in ndisc_send_ns() (or in ndisc_solicit(), probably) if the source is optimistic address, but... I'm not sure so far if it is appropriate from design POV. The ndisc_send_ns() nor ndisc_solicit() is not about our current neigh state machine, at all. I do not think we should copy neighbor information from (one of) default routers, but use temporary neigh entry (or neigh in new state) for such datagrams in stead. We should aware that: 1) default router's link-layer address may change. 2) we may have more than one default routers. 3) the default router's link-layer may be invalidated. Anyway, I'm start thinking about CONFIG_IPV6_OPTIMISTIC_DAD to make sure the new code path will not break anything else... --yoshfuji - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
Quick reality check here. In thinking about how best to go about this redirection of frames to the default router, based on Dave M.s input, I think that the best solution would be in ndisc_send_ns. What I was thinking was that in ndisc_send_ns, we already detect if a source address is optimistic and squash the transmission of the frame there. What if in addition to that supression, we also immediately update the neighbor cache entry for the requested host, to reflect the mac address of the default gateway. That way any dst cache lookups for hosts we don't know the true link layer address for will get redirected to the default gateway. Then any ICMP redirect messages from the router will fix those entires up for us. Later, when DAD completes, normal neighbour garbage collection and/or timeouts will sort out the neighbor cache entries for us. Or alternatively we could flush the cache entirely, or scan the cache for entires that match the lladdr of the default gateway and do a selective purge. I'm going to start implementing this, but I wanted to post it here to make sure I'm not missing anything really big on this idea. Thanks & Regards Neil - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
On Fri, Jan 26, 2007 at 04:42:41PM -0500, Vlad Yasevich wrote: > Neil Horman wrote: > > On Fri, Jan 26, 2007 at 03:28:40PM -0500, Vlad Yasevich wrote: > >> Hi Neil > >> > >> Neil Horman wrote: > >>> On Fri, Jan 26, 2007 at 09:13:31AM +0900, YOSHIFUJI Hideaki / 吉藤英明 wrote: > In article <[EMAIL PROTECTED]> (at Thu, 25 Jan 2007 14:45:00 -0500), > Neil Horman <[EMAIL PROTECTED]> says: > >>> > >>> New patch attached with most of your suggestions incorporated. I've a few > >>> comments mixed in for some of the suggestions that I think need further > >>> discussion > >>> > If optimistic_dad is disabled, flags should be IFA_F_TEMPORARY, > not IFA_F_TEMPORARY|IFA_F_OPTIMISTIC. > > Another idea is to use IFA_F_OPTIMISTIC not > IFA_F_OPTIMISTIC|IFA_F_TENTATIVE until the DAD has been finished. > > >>> I'm currently setting the OPTIMISTIC flag in every location that its > >>> possibly > >>> needed, and then clearing it in addrconf_dad_start if that interface is > >>> not > >>> participating in optimistic dad. I do this because the RFC in section 3.1 > >>> indicates that manually configured addresses should not set the > >>> optimistic flag. > >>> If I removed the OPTIMISTIC flag from the locations it gets set in the > >>> patch and > >>> then only set it for participating interfaces in addrconf_dad_start, I > >>> would > >>> need to have some way to tell if the address in question was manually > >>> configured > >>> (to avoid setting it in that case). At present I see no clear way to do > >>> that, > >>> but if you have a suggestion, I'll happily change this around. > >> One suggestiong/question: > >> > >> Instead of clearing the OPTIMISTIC flag in addrconf_dad_start(), wouldn't > >> it be better > >> to simply not set the flag in ipv6_add_addr()? Just mask that flag from > >> the 'flags' > >> argument passed to that function when conditions are right. > >> > > Doh! Sometimes I don't just think straight. Yes, as long as ipv6_add_addr > > is > > only for adding static addresses (which it pretty clearly is), that would > > work > > much better. I'll fix it up and repost on monday. > > > > Don't suppose you have any thoughts on how to solve the "send to default > > router" > > problem, do you? > > > > Still trying to figure how the routing side works. sorry > > -vlad I've got your flag changes made, but I'm holding off on reposting for a bit. Dave M. just gave me some advice on how best to handle the default router case. Trying to understand the routing code and integrate that before I repost. Thanks Neil - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
Neil Horman wrote: > On Fri, Jan 26, 2007 at 03:28:40PM -0500, Vlad Yasevich wrote: >> Hi Neil >> >> Neil Horman wrote: >>> On Fri, Jan 26, 2007 at 09:13:31AM +0900, YOSHIFUJI Hideaki / 吉藤英明 wrote: In article <[EMAIL PROTECTED]> (at Thu, 25 Jan 2007 14:45:00 -0500), Neil Horman <[EMAIL PROTECTED]> says: >>> >>> New patch attached with most of your suggestions incorporated. I've a few >>> comments mixed in for some of the suggestions that I think need further >>> discussion >>> If optimistic_dad is disabled, flags should be IFA_F_TEMPORARY, not IFA_F_TEMPORARY|IFA_F_OPTIMISTIC. Another idea is to use IFA_F_OPTIMISTIC not IFA_F_OPTIMISTIC|IFA_F_TENTATIVE until the DAD has been finished. >>> I'm currently setting the OPTIMISTIC flag in every location that its >>> possibly >>> needed, and then clearing it in addrconf_dad_start if that interface is not >>> participating in optimistic dad. I do this because the RFC in section 3.1 >>> indicates that manually configured addresses should not set the optimistic >>> flag. >>> If I removed the OPTIMISTIC flag from the locations it gets set in the >>> patch and >>> then only set it for participating interfaces in addrconf_dad_start, I would >>> need to have some way to tell if the address in question was manually >>> configured >>> (to avoid setting it in that case). At present I see no clear way to do >>> that, >>> but if you have a suggestion, I'll happily change this around. >> One suggestiong/question: >> >> Instead of clearing the OPTIMISTIC flag in addrconf_dad_start(), wouldn't it >> be better >> to simply not set the flag in ipv6_add_addr()? Just mask that flag from the >> 'flags' >> argument passed to that function when conditions are right. >> > Doh! Sometimes I don't just think straight. Yes, as long as ipv6_add_addr is > only for adding static addresses (which it pretty clearly is), that would work > much better. I'll fix it up and repost on monday. > > Don't suppose you have any thoughts on how to solve the "send to default > router" > problem, do you? > Still trying to figure how the routing side works. sorry -vlad - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
On Fri, Jan 26, 2007 at 03:28:40PM -0500, Vlad Yasevich wrote: > Hi Neil > > Neil Horman wrote: > > On Fri, Jan 26, 2007 at 09:13:31AM +0900, YOSHIFUJI Hideaki / 吉藤英明 wrote: > >> In article <[EMAIL PROTECTED]> (at Thu, 25 Jan 2007 14:45:00 -0500), Neil > >> Horman <[EMAIL PROTECTED]> says: > > > > > > New patch attached with most of your suggestions incorporated. I've a few > > comments mixed in for some of the suggestions that I think need further > > discussion > > > >> If optimistic_dad is disabled, flags should be IFA_F_TEMPORARY, > >> not IFA_F_TEMPORARY|IFA_F_OPTIMISTIC. > >> > >> Another idea is to use IFA_F_OPTIMISTIC not > >> IFA_F_OPTIMISTIC|IFA_F_TENTATIVE until the DAD has been finished. > >> > > > > I'm currently setting the OPTIMISTIC flag in every location that its > > possibly > > needed, and then clearing it in addrconf_dad_start if that interface is not > > participating in optimistic dad. I do this because the RFC in section 3.1 > > indicates that manually configured addresses should not set the optimistic > > flag. > > If I removed the OPTIMISTIC flag from the locations it gets set in the > > patch and > > then only set it for participating interfaces in addrconf_dad_start, I would > > need to have some way to tell if the address in question was manually > > configured > > (to avoid setting it in that case). At present I see no clear way to do > > that, > > but if you have a suggestion, I'll happily change this around. > > One suggestiong/question: > > Instead of clearing the OPTIMISTIC flag in addrconf_dad_start(), wouldn't it > be better > to simply not set the flag in ipv6_add_addr()? Just mask that flag from the > 'flags' > argument passed to that function when conditions are right. > Doh! Sometimes I don't just think straight. Yes, as long as ipv6_add_addr is only for adding static addresses (which it pretty clearly is), that would work much better. I'll fix it up and repost on monday. Don't suppose you have any thoughts on how to solve the "send to default router" problem, do you? Regards Neil - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
Hi Neil Neil Horman wrote: > On Fri, Jan 26, 2007 at 09:13:31AM +0900, YOSHIFUJI Hideaki / 吉藤英明 wrote: >> In article <[EMAIL PROTECTED]> (at Thu, 25 Jan 2007 14:45:00 -0500), Neil >> Horman <[EMAIL PROTECTED]> says: > > > New patch attached with most of your suggestions incorporated. I've a few > comments mixed in for some of the suggestions that I think need further > discussion > >> If optimistic_dad is disabled, flags should be IFA_F_TEMPORARY, >> not IFA_F_TEMPORARY|IFA_F_OPTIMISTIC. >> >> Another idea is to use IFA_F_OPTIMISTIC not >> IFA_F_OPTIMISTIC|IFA_F_TENTATIVE until the DAD has been finished. >> > > I'm currently setting the OPTIMISTIC flag in every location that its possibly > needed, and then clearing it in addrconf_dad_start if that interface is not > participating in optimistic dad. I do this because the RFC in section 3.1 > indicates that manually configured addresses should not set the optimistic > flag. > If I removed the OPTIMISTIC flag from the locations it gets set in the patch > and > then only set it for participating interfaces in addrconf_dad_start, I would > need to have some way to tell if the address in question was manually > configured > (to avoid setting it in that case). At present I see no clear way to do that, > but if you have a suggestion, I'll happily change this around. One suggestiong/question: Instead of clearing the OPTIMISTIC flag in addrconf_dad_start(), wouldn't it be better to simply not set the flag in ipv6_add_addr()? Just mask that flag from the 'flags' argument passed to that function when conditions are right. like if (!idev->cnf.optimistic_dad || ipv6_devconf.forwarding) flags &= ~IFA_F_OPTIMISTIC; The ifa->rt is also set there, so if the check for that is valid, we can do it there as well. -vlad - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
On Fri, Jan 26, 2007 at 09:13:31AM +0900, YOSHIFUJI Hideaki / 吉藤英明 wrote: > In article <[EMAIL PROTECTED]> (at Thu, 25 Jan 2007 14:45:00 -0500), Neil > Horman <[EMAIL PROTECTED]> says: New patch attached with most of your suggestions incorporated. I've a few comments mixed in for some of the suggestions that I think need further discussion > If optimistic_dad is disabled, flags should be IFA_F_TEMPORARY, > not IFA_F_TEMPORARY|IFA_F_OPTIMISTIC. > > Another idea is to use IFA_F_OPTIMISTIC not > IFA_F_OPTIMISTIC|IFA_F_TENTATIVE until the DAD has been finished. > I'm currently setting the OPTIMISTIC flag in every location that its possibly needed, and then clearing it in addrconf_dad_start if that interface is not participating in optimistic dad. I do this because the RFC in section 3.1 indicates that manually configured addresses should not set the optimistic flag. If I removed the OPTIMISTIC flag from the locations it gets set in the patch and then only set it for participating interfaces in addrconf_dad_start, I would need to have some way to tell if the address in question was manually configured (to avoid setting it in that case). At present I see no clear way to do that, but if you have a suggestion, I'll happily change this around. > > ((ifa_result->flags & > (IFA_F_DEPRECATED|IFA_F_OPTIMISTIC)) == 0) > ditto. > Done > > @@ -2123,7 +2133,8 @@ static void addrconf_add_linklocal(struct inet6_dev > > *idev, struct in6_addr *addr > > { > > struct inet6_ifaddr * ifp; > > > > - ifp = ipv6_add_addr(idev, addr, 64, IFA_LINK, IFA_F_PERMANENT); > > + ifp = ipv6_add_addr(idev, addr, 64, IFA_LINK, > > + IFA_F_PERMANENT|IFA_F_OPTIMISTIC); > > if (!IS_ERR(ifp)) { > > addrconf_dad_start(ifp, 0); > > in6_ifa_put(ifp); > > Please do not always put IFA_F_OPTIMISTIC. > Again, same reasoning as above for why I set optimistic in this way. > > > > + /* > > +* Optimistic nodes need to joing the anycast address > > +* right away > > +*/ > > + if (ifp->flags & IFA_F_OPTIMISTIC) > > + addrconf_join_anycast(ifp); > > + > > if (ifp->prefix_len != 128 && (ifp->flags&IFA_F_PERMANENT)) > > addrconf_prefix_route(&ifp->addr, ifp->prefix_len, dev, 0, > > flags); > > Should we join anycast even if the node is a host (not a router)?! > I've moved this to the spot below where we check if we are forwarding, so the new patch attached does not join anycast if we are a router. > When you add a call to "addrconf_join_anycast()", > you must consider when to leave this. > I think addrconf_dad_completed is appropriate for this. New patch leaves anycast group when we are no longer optimistic > > > @@ -2573,6 +2594,18 @@ static void addrconf_dad_start(struct inet6_ifaddr > > *ifp, u32 flags) > > addrconf_dad_stop(ifp); > > return; > > } > > + > > + /* > > +* Forwarding devices (routers) should not use > > +* optimistic addresses > > +* Nor should interfaces that don't know the > > +* Source address for their default gateway > > +* RFC 4429 Sec 3.3 > > +*/ > > + if ((ipv6_devconf.forwarding) || > > + (ifp->rt == NULL)) > > + ifp->flags &= ~IFA_F_OPTIMISTIC; > > + > > addrconf_dad_kick(ifp); > > spin_unlock_bh(&ifp->lock); > > out: > > Please test this condition when you are adding the > address. > Are you sure? There are several locations where we add an address that we start dad on. Shall I test this in all of those places? It would seem more appropriate to do it in addrconf_dad_start, as I do. Or am I missing something? > BTW, you have not implemented the later condition, > right? Sefault gatewa is not tested. > I thought I was testing it. I was under the impression from my reading of the code the ifp->rt held the rt6_info pointer for the default gateway, so if its not set, we don't know the default gateway. I may well be missing something here though. Please let me know. > > index 6a9f616..fcd22e3 100644 > > --- a/net/ipv6/ndisc.c > > +++ b/net/ipv6/ndisc.c > > @@ -498,7 +498,21 @@ static void ndisc_send_na(struct net_device *dev, > > struct neighbour *neigh, > > msg->icmph.icmp6_unused = 0; > > msg->icmph.icmp6_router= router; > > msg->icmph.icmp6_solicited = solicited; > > -msg->icmph.icmp6_override = override; > > + if (!ifp || !(ifp->flags & IFA_F_OPTIMISTIC)) > > + msg->icmph.icmp6_override = override; > > + else { > > + /* > > +* We must clear the override flag on all > > +* neighbor advertisements from source > > +* addresses that are OPTIMISTIC - RFC 4429 > > +* section 2.2 > > +*/ > > + if (override) > > + printk(KERN_WARNING > > + "Disallowing override flag for
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
On Sat, Jan 27, 2007 at 12:44:29AM +0900, YOSHIFUJI Hideaki / 吉藤英明 wrote: > In article <[EMAIL PROTECTED]> (at Fri, 26 Jan 2007 09:27:30 -0500), Neil > Horman <[EMAIL PROTECTED]> says: > > > I'm looking for it at the moment, but I too had assumed that redirecting the > > outgoing packet to the default router would happen automatically within the > > routing code as a result of not having a completed neighbor entry available. > > Since I've modified ndisc_send_ns such that we will never send Neighbor > > solicitations from an optimistic address, as per section 3.2, we'll never > > get a > > completed neightbor entry while the address is optimistic. If thats not the > > case, I'd welcome some suggestions on how to implement this (given that I'm > > not > > overly familiar with the code right now). From what I see, I think the > > routing > > code will select the default route when rti6_nexthop is null during route > > selection, which it will be if the neighbor entry doesn't get resolved. Not > > 100% sure though. Let me know what you think. > > (Now I remember that I hit similar issue before when I once > tried to implement this) > > Well... no, you cannot assume that routing code solves this issue. > This is not so trivial, and I am not aware clean solution yet... > > On reason of this issue is because the source address may not be > probided by user, and the source address selection will be done > after looking up routing table. > > One possibiliy is to solve by rt->rt6i_nexthop->output(), > but I guess we will hit some race condition. > > Hmm... > Is this perhaps something we can do in ip6_output2? We can test the interface flags there and if the interface is optimistic, we can lookup the default route (perhaps via rt6_lookup, using the unspecified address for the daddr), and then replace skb->dst with the dst_entry retrieved from the lookup, which should give us the proper mac header construction starting in ip6_output_finish. What do you think? Neil - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
In article <[EMAIL PROTECTED]> (at Fri, 26 Jan 2007 09:27:30 -0500), Neil Horman <[EMAIL PROTECTED]> says: > I'm looking for it at the moment, but I too had assumed that redirecting the > outgoing packet to the default router would happen automatically within the > routing code as a result of not having a completed neighbor entry available. > Since I've modified ndisc_send_ns such that we will never send Neighbor > solicitations from an optimistic address, as per section 3.2, we'll never get > a > completed neightbor entry while the address is optimistic. If thats not the > case, I'd welcome some suggestions on how to implement this (given that I'm > not > overly familiar with the code right now). From what I see, I think the > routing > code will select the default route when rti6_nexthop is null during route > selection, which it will be if the neighbor entry doesn't get resolved. Not > 100% sure though. Let me know what you think. (Now I remember that I hit similar issue before when I once tried to implement this) Well... no, you cannot assume that routing code solves this issue. This is not so trivial, and I am not aware clean solution yet... On reason of this issue is because the source address may not be probided by user, and the source address selection will be done after looking up routing table. One possibiliy is to solve by rt->rt6i_nexthop->output(), but I guess we will hit some race condition. Hmm... --yoshfuji - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
On Thu, Jan 25, 2007 at 05:13:57PM -0500, Vlad Yasevich wrote: > Hi Neil > > > > > I prefer to be more explicit in my order of operation, but that does seem > > more > > consistent with the prevaling style. New patch attached. > > > > Looks good to me. > > One question thought. What causes the stack to send via Default Router > instead > of sending an NS (Section 3.2). I see there is code to prevent sending NS > from > the optimistic address, but I see nothing that would send this packet to a > default > router. This might be buried somewhere in the routing code, but I just can't > see it. > > I'm looking for it at the moment, but I too had assumed that redirecting the outgoing packet to the default router would happen automatically within the routing code as a result of not having a completed neighbor entry available. Since I've modified ndisc_send_ns such that we will never send Neighbor solicitations from an optimistic address, as per section 3.2, we'll never get a completed neightbor entry while the address is optimistic. If thats not the case, I'd welcome some suggestions on how to implement this (given that I'm not overly familiar with the code right now). From what I see, I think the routing code will select the default route when rti6_nexthop is null during route selection, which it will be if the neighbor entry doesn't get resolved. Not 100% sure though. Let me know what you think. Regards Neil > Thanks > -vlad - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
YOSHIFUJI Hideaki / 吉藤英明 wrote: > In article <[EMAIL PROTECTED]> (at Thu, 25 Jan 2007 14:45:00 -0500), Neil > Horman <[EMAIL PROTECTED]> says: > >> diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c >> index 2a7e461..46f91ee 100644 >> --- a/net/ipv6/addrconf.c >> +++ b/net/ipv6/addrconf.c >> @@ -830,7 +830,8 @@ retry: >> ift = !max_addresses || >>ipv6_count_addresses(idev) < max_addresses ? >> ipv6_add_addr(idev, &addr, tmp_plen, >> - ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, >> IFA_F_TEMPORARY) : NULL; >> + ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, >> + IFA_F_TEMPORARY|IFA_F_OPTIMISTIC) : NULL; >> if (!ift || IS_ERR(ift)) { >> in6_ifa_put(ifp); >> in6_dev_put(idev); > > If optimistic_dad is disabled, flags should be IFA_F_TEMPORARY, > not IFA_F_TEMPORARY|IFA_F_OPTIMISTIC. > > Another idea is to use IFA_F_OPTIMISTIC not > IFA_F_OPTIMISTIC|IFA_F_TENTATIVE until the DAD has been finished. > >> @@ -1027,15 +1029,17 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev, > : >> +/* Rule 3: Avoid deprecated and optimistic address */ >> if (hiscore.rule < 3) { >> if (ipv6_saddr_preferred(hiscore.addr_type) || >> -!(ifa_result->flags & IFA_F_DEPRECATED)) >> +((!(ifa_result->flags & IFA_F_DEPRECATED)) >> && >> +(!(ifa_result->flags & IFA_F_OPTIMISTIC >> hiscore.attrs |= >> IPV6_SADDR_SCORE_PREFERRED; >> hiscore.rule++; > > ((ifa_result->flags & > (IFA_F_DEPRECATED|IFA_F_OPTIMISTIC)) == 0) > >> } >> if (ipv6_saddr_preferred(score.addr_type) || >> -!(ifa->flags & IFA_F_DEPRECATED)) { >> +((!(ifa->flags & IFA_F_DEPRECATED)) && >> +(!(ifa_result->flags & IFA_F_OPTIMISTIC { >> score.attrs |= IPV6_SADDR_SCORE_PREFERRED; >> if (!(hiscore.attrs & >> IPV6_SADDR_SCORE_PREFERRED)) { >> score.rule = 3; > > ditto. > >> @@ -2123,7 +2133,8 @@ static void addrconf_add_linklocal(struct inet6_dev >> *idev, struct in6_addr *addr >> { >> struct inet6_ifaddr * ifp; >> >> -ifp = ipv6_add_addr(idev, addr, 64, IFA_LINK, IFA_F_PERMANENT); >> +ifp = ipv6_add_addr(idev, addr, 64, IFA_LINK, >> +IFA_F_PERMANENT|IFA_F_OPTIMISTIC); >> if (!IS_ERR(ifp)) { >> addrconf_dad_start(ifp, 0); >> in6_ifa_put(ifp); > > Please do not always put IFA_F_OPTIMISTIC. > >> >> +/* >> + * Optimistic nodes need to joing the anycast address >> + * right away >> + */ >> +if (ifp->flags & IFA_F_OPTIMISTIC) >> +addrconf_join_anycast(ifp); >> + >> if (ifp->prefix_len != 128 && (ifp->flags&IFA_F_PERMANENT)) >> addrconf_prefix_route(&ifp->addr, ifp->prefix_len, dev, 0, >> flags); > > Should we join anycast even if the node is a host (not a router)?! "A router SHOULD NOT configure an Optimistic Address. " Section 3.3 I think this check is missing from the implementation. >> @@ -622,9 +637,20 @@ void ndisc_send_rs(struct net_device *dev, struct >> in6_addr *saddr, >> +/* >> + * Check the source address. If its OPTIMISTIC >> + * and addr_len is non-zero (implying the sllao option) >> + * then don't send the RS (RFC 4429, section 2.2) >> + */ >> +ifp = ipv6_get_ifaddr(saddr, dev, 1); >> + >> +if ((!ifp) || ((ifp->flags & IFA_F_OPTIMISTIC) && dev->addr_len)) >> +return; >> + >> ndisc_flow_init(&fl, NDISC_ROUTER_SOLICITATION, saddr, daddr, >> dev->ifindex); >> > > I disagree. Please send RS in other way. > Choose another address, or send it without SLLAO. > Agree. Sending without SLLAO is a "MAY" option in the draft and would yield better operation. -vlad - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
In article <[EMAIL PROTECTED]> (at Thu, 25 Jan 2007 14:45:00 -0500), Neil Horman <[EMAIL PROTECTED]> says: > diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c > index 2a7e461..46f91ee 100644 > --- a/net/ipv6/addrconf.c > +++ b/net/ipv6/addrconf.c > @@ -830,7 +830,8 @@ retry: > ift = !max_addresses || > ipv6_count_addresses(idev) < max_addresses ? > ipv6_add_addr(idev, &addr, tmp_plen, > - ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, > IFA_F_TEMPORARY) : NULL; > + ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, > + IFA_F_TEMPORARY|IFA_F_OPTIMISTIC) : NULL; > if (!ift || IS_ERR(ift)) { > in6_ifa_put(ifp); > in6_dev_put(idev); If optimistic_dad is disabled, flags should be IFA_F_TEMPORARY, not IFA_F_TEMPORARY|IFA_F_OPTIMISTIC. Another idea is to use IFA_F_OPTIMISTIC not IFA_F_OPTIMISTIC|IFA_F_TENTATIVE until the DAD has been finished. > @@ -1027,15 +1029,17 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev, : > + /* Rule 3: Avoid deprecated and optimistic address */ > if (hiscore.rule < 3) { > if (ipv6_saddr_preferred(hiscore.addr_type) || > - !(ifa_result->flags & IFA_F_DEPRECATED)) > + ((!(ifa_result->flags & IFA_F_DEPRECATED)) > && > + (!(ifa_result->flags & IFA_F_OPTIMISTIC > hiscore.attrs |= > IPV6_SADDR_SCORE_PREFERRED; > hiscore.rule++; ((ifa_result->flags & (IFA_F_DEPRECATED|IFA_F_OPTIMISTIC)) == 0) > } > if (ipv6_saddr_preferred(score.addr_type) || > - !(ifa->flags & IFA_F_DEPRECATED)) { > + ((!(ifa->flags & IFA_F_DEPRECATED)) && > + (!(ifa_result->flags & IFA_F_OPTIMISTIC { > score.attrs |= IPV6_SADDR_SCORE_PREFERRED; > if (!(hiscore.attrs & > IPV6_SADDR_SCORE_PREFERRED)) { > score.rule = 3; ditto. > @@ -2123,7 +2133,8 @@ static void addrconf_add_linklocal(struct inet6_dev > *idev, struct in6_addr *addr > { > struct inet6_ifaddr * ifp; > > - ifp = ipv6_add_addr(idev, addr, 64, IFA_LINK, IFA_F_PERMANENT); > + ifp = ipv6_add_addr(idev, addr, 64, IFA_LINK, > + IFA_F_PERMANENT|IFA_F_OPTIMISTIC); > if (!IS_ERR(ifp)) { > addrconf_dad_start(ifp, 0); > in6_ifa_put(ifp); Please do not always put IFA_F_OPTIMISTIC. > > + /* > + * Optimistic nodes need to joing the anycast address > + * right away > + */ > + if (ifp->flags & IFA_F_OPTIMISTIC) > + addrconf_join_anycast(ifp); > + > if (ifp->prefix_len != 128 && (ifp->flags&IFA_F_PERMANENT)) > addrconf_prefix_route(&ifp->addr, ifp->prefix_len, dev, 0, > flags); Should we join anycast even if the node is a host (not a router)?! When you add a call to "addrconf_join_anycast()", you must consider when to leave this. > @@ -2573,6 +2594,18 @@ static void addrconf_dad_start(struct inet6_ifaddr > *ifp, u32 flags) > addrconf_dad_stop(ifp); > return; > } > + > + /* > + * Forwarding devices (routers) should not use > + * optimistic addresses > + * Nor should interfaces that don't know the > + * Source address for their default gateway > + * RFC 4429 Sec 3.3 > + */ > + if ((ipv6_devconf.forwarding) || > +(ifp->rt == NULL)) > + ifp->flags &= ~IFA_F_OPTIMISTIC; > + > addrconf_dad_kick(ifp); > spin_unlock_bh(&ifp->lock); > out: Please test this condition when you are adding the address. BTW, you have not implemented the later condition, right? Sefault gatewa is not tested. > index 6a9f616..fcd22e3 100644 > --- a/net/ipv6/ndisc.c > +++ b/net/ipv6/ndisc.c > @@ -498,7 +498,21 @@ static void ndisc_send_na(struct net_device *dev, struct > neighbour *neigh, > msg->icmph.icmp6_unused = 0; > msg->icmph.icmp6_router= router; > msg->icmph.icmp6_solicited = solicited; > -msg->icmph.icmp6_override = override; > + if (!ifp || !(ifp->flags & IFA_F_OPTIMISTIC)) > + msg->icmph.icmp6_override = override; > + else { > + /* > + * We must clear the override flag on all > + * neighbor advertisements from source > + * addresses that are OPTIMISTIC - RFC 4429 > + * section 2.2 > + */ > + if (override) > + printk(KERN_WARNING > + "Disallowing override flag for OPTIMISTIC
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
Hi Neil I went through the RFC again it seems like the following is missing: Section 3.3: > * (modifies section 5.4.2) The host MUST join the all-nodes multicast >address and the solicited-node multicast address of the >Tentative address. The host SHOULD NOT delay before sending >Neighbor Solicitation messages. For this, addrconf_dad_kick() should pass 0 to addrconf_mod_timer when the address is optimistic. Otherwise, we'll delay DAD some of the purpose of optimistic addresses is lost. -vlad - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
Hi Neil > > I prefer to be more explicit in my order of operation, but that does seem more > consistent with the prevaling style. New patch attached. > Looks good to me. One question thought. What causes the stack to send via Default Router instead of sending an NS (Section 3.2). I see there is code to prevent sending NS from the optimistic address, but I see nothing that would send this packet to a default router. This might be buried somewhere in the routing code, but I just can't see it. Thanks -vlad - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
On Thu, Jan 25, 2007 at 03:18:59PM -0500, Vlad Yasevich wrote: > Hi Neil > > > @@ -1027,15 +1029,17 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev, > > } > > } > > > > - /* Rule 3: Avoid deprecated address */ > > + /* Rule 3: Avoid deprecated and optimistic address */ > > if (hiscore.rule < 3) { > > if (ipv6_saddr_preferred(hiscore.addr_type) || > > - !(ifa_result->flags & IFA_F_DEPRECATED)) > > + ((!(ifa_result->flags & IFA_F_DEPRECATED)) > > && > > + (!(ifa_result->flags & IFA_F_OPTIMISTIC > > One style comment. Looks like some extra parenthesis that I don't thing are > needed. > I think you can say > > + (!(ifa_result->flags & IFA_F_DEPRECATED)) > && > + !(ifa_result->flags & IFA_F_OPTIMISTIC > > > > hiscore.attrs |= > > IPV6_SADDR_SCORE_PREFERRED; > > hiscore.rule++; > > } > > if (ipv6_saddr_preferred(score.addr_type) || > > - !(ifa->flags & IFA_F_DEPRECATED)) { > > + ((!(ifa->flags & IFA_F_DEPRECATED)) && > > + (!(ifa_result->flags & IFA_F_OPTIMISTIC { > > same here. > > > score.attrs |= IPV6_SADDR_SCORE_PREFERRED; > > if (!(hiscore.attrs & > > IPV6_SADDR_SCORE_PREFERRED)) { > > score.rule = 3; > > -vlad I prefer to be more explicit in my order of operation, but that does seem more consistent with the prevaling style. New patch attached. Thanks & Regards Neil Signed-off-by: Neil Horman <[EMAIL PROTECTED]> include/linux/if_addr.h |1 include/linux/ipv6.h|2 + include/linux/sysctl.h |1 include/net/addrconf.h |4 +- net/ipv6/addrconf.c | 69 net/ipv6/mcast.c|4 +- net/ipv6/ndisc.c| 82 +++- 7 files changed, 125 insertions(+), 38 deletions(-) diff --git a/include/linux/if_addr.h b/include/linux/if_addr.h index d557e4c..43f3bed 100644 --- a/include/linux/if_addr.h +++ b/include/linux/if_addr.h @@ -39,6 +39,7 @@ enum #define IFA_F_TEMPORARYIFA_F_SECONDARY #defineIFA_F_NODAD 0x02 +#define IFA_F_OPTIMISTIC 0x04 #defineIFA_F_HOMEADDRESS 0x10 #define IFA_F_DEPRECATED 0x20 #define IFA_F_TENTATIVE0x40 diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index f824113..5d37abf 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -177,6 +177,7 @@ struct ipv6_devconf { #endif #endif __s32 proxy_ndp; + __s32 optimistic_dad; void*sysctl; }; @@ -205,6 +206,7 @@ enum { DEVCONF_RTR_PROBE_INTERVAL, DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN, DEVCONF_PROXY_NDP, + DEVCONF_OPTIMISTIC_DAD, DEVCONF_MAX }; diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 81480e6..972a33a 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -570,6 +570,7 @@ enum { NET_IPV6_RTR_PROBE_INTERVAL=21, NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=22, NET_IPV6_PROXY_NDP=23, + NET_IPV6_OPTIMISTIC_DAD=24, __NET_IPV6_MAX }; diff --git a/include/net/addrconf.h b/include/net/addrconf.h index 88df8fc..d248a19 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -73,7 +73,9 @@ extern intipv6_get_saddr(struct dst_entry *dst, extern int ipv6_dev_get_saddr(struct net_device *dev, struct in6_addr *daddr, struct in6_addr *saddr); -extern int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *); +extern int ipv6_get_lladdr(struct net_device *dev, + struct in6_addr *, + unsigned char banned_flags); extern int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2); extern voidaddrconf_join_solict(struct net_device *dev, diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 2a7e461..057a260 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -830,7 +830,8 @@ retry: ift = !max_addresses || ipv6_count_addresses(idev) < max_addresses ? ipv6_add_addr(idev, &addr, tmp_plen, - ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, IFA
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
Hi Neil > @@ -1027,15 +1029,17 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev, > } > } > > - /* Rule 3: Avoid deprecated address */ > + /* Rule 3: Avoid deprecated and optimistic address */ > if (hiscore.rule < 3) { > if (ipv6_saddr_preferred(hiscore.addr_type) || > - !(ifa_result->flags & IFA_F_DEPRECATED)) > + ((!(ifa_result->flags & IFA_F_DEPRECATED)) > && > + (!(ifa_result->flags & IFA_F_OPTIMISTIC One style comment. Looks like some extra parenthesis that I don't thing are needed. I think you can say + (!(ifa_result->flags & IFA_F_DEPRECATED)) && +!(ifa_result->flags & IFA_F_OPTIMISTIC > hiscore.attrs |= > IPV6_SADDR_SCORE_PREFERRED; > hiscore.rule++; > } > if (ipv6_saddr_preferred(score.addr_type) || > - !(ifa->flags & IFA_F_DEPRECATED)) { > + ((!(ifa->flags & IFA_F_DEPRECATED)) && > + (!(ifa_result->flags & IFA_F_OPTIMISTIC { same here. > score.attrs |= IPV6_SADDR_SCORE_PREFERRED; > if (!(hiscore.attrs & > IPV6_SADDR_SCORE_PREFERRED)) { > score.rule = 3; -vlad - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
On Thu, Jan 25, 2007 at 12:16:59PM -0500, Vlad Yasevich wrote: > I tend to agree with Neil here. Marking optimistic addresses as deprecated > doesn't > buy as much since the address can transition in and out of deprecated state > regardless > of DAD. > > However, there is a problem with the current implementation in that > OPTIMISTIC address > will never be chosen as source because it's always TENTATIVE and OPTIMISTIC > at the > same time. What needs to happen is for ipv6_dev_get_saddr() to not ignore > OPTIMISTIC > addresses and treat them same as DEPRECATED. > > -vlad Heres an updated patch. Same as the previous patch but it adds three modifications to ipv6_dev_get_saddr, which do the following: a) Adds logic to not remove addresses that are both tentative and optimistic from the set of considered addresses b) Treats optimistic addresses and deptrecated address in the same fashion by checking for both flags appropriately during source address selection. Thoughts welcome. Thanks & Regards Neil Signed-off-by: Neil Horman <[EMAIL PROTECTED] include/linux/if_addr.h |1 include/linux/ipv6.h|2 + include/linux/sysctl.h |1 include/net/addrconf.h |4 +- net/ipv6/addrconf.c | 69 net/ipv6/mcast.c|4 +- net/ipv6/ndisc.c| 82 +++- 7 files changed, 125 insertions(+), 38 deletions(-) diff --git a/include/linux/if_addr.h b/include/linux/if_addr.h index d557e4c..43f3bed 100644 --- a/include/linux/if_addr.h +++ b/include/linux/if_addr.h @@ -39,6 +39,7 @@ enum #define IFA_F_TEMPORARYIFA_F_SECONDARY #defineIFA_F_NODAD 0x02 +#define IFA_F_OPTIMISTIC 0x04 #defineIFA_F_HOMEADDRESS 0x10 #define IFA_F_DEPRECATED 0x20 #define IFA_F_TENTATIVE0x40 diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index f824113..5d37abf 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -177,6 +177,7 @@ struct ipv6_devconf { #endif #endif __s32 proxy_ndp; + __s32 optimistic_dad; void*sysctl; }; @@ -205,6 +206,7 @@ enum { DEVCONF_RTR_PROBE_INTERVAL, DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN, DEVCONF_PROXY_NDP, + DEVCONF_OPTIMISTIC_DAD, DEVCONF_MAX }; diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 81480e6..972a33a 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -570,6 +570,7 @@ enum { NET_IPV6_RTR_PROBE_INTERVAL=21, NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=22, NET_IPV6_PROXY_NDP=23, + NET_IPV6_OPTIMISTIC_DAD=24, __NET_IPV6_MAX }; diff --git a/include/net/addrconf.h b/include/net/addrconf.h index 88df8fc..d248a19 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -73,7 +73,9 @@ extern intipv6_get_saddr(struct dst_entry *dst, extern int ipv6_dev_get_saddr(struct net_device *dev, struct in6_addr *daddr, struct in6_addr *saddr); -extern int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *); +extern int ipv6_get_lladdr(struct net_device *dev, + struct in6_addr *, + unsigned char banned_flags); extern int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2); extern voidaddrconf_join_solict(struct net_device *dev, diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 2a7e461..46f91ee 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -830,7 +830,8 @@ retry: ift = !max_addresses || ipv6_count_addresses(idev) < max_addresses ? ipv6_add_addr(idev, &addr, tmp_plen, - ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, IFA_F_TEMPORARY) : NULL; + ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, + IFA_F_TEMPORARY|IFA_F_OPTIMISTIC) : NULL; if (!ift || IS_ERR(ift)) { in6_ifa_put(ifp); in6_dev_put(idev); @@ -962,13 +963,14 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev, * - Tentative Address (RFC2462 section 5.4) * - A tentative address is not considered *"assigned to an interface" in the traditional -*sense. +*sense, unless it is also flagged as optimistic. * - Candidate Source Address (section 4) * - In any case, anycast addresses, multicast *addre
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
Neil Horman wrote: > On Wed, Jan 24, 2007 at 05:54:47PM -0800, Sridhar Samudrala wrote: >> Sec 2.1 of RFC 4429 says >> >>Unless noted otherwise, components of the IPv6 protocol stack should >>treat addresses in the Optimistic state equivalently to those in the >>Deprecated state, indicating that the address is available for use >>but should not be used if another suitable address is available. For >>example, Default Address Selection [RFC3484] uses the address state >>to decide which source address to use for an outgoing packet. >>Implementations should treat an address in state Optimistic as if it >>were in state Deprecated. If address states are recorded as >>individual flags, this can easily be achieved by also setting >>'Deprecated' when 'Optimistic' is set. >> >> So i think DEPRECATED flag also should be set when we mark an address >> as OPTIMISTIC so that we don't use it as source address for new >> connections if another address is available until DAD is completed. >> >> Thanks >> Sridhar >> > > Oh, good catch. Thank you Sri. However, I'm worried about the next > paragraph: > > It is important to note that the address lifetime rules of [RFC2462] >still apply, and so an address may be Deprecated as well as >Optimistic. When DAD completes without incident, the address becomes >either a Preferred or a Deprecated address, as per RFC 2462 > > Given that, it seems to me that addresses which are flagged as Deprecated may > enter and exit that state independently of the DAD process, which I think > gives > rise to the possibility of a race. I.e. if an address becomes deprecated > right > before DAD completes, and then addrconf_dad_complete clears the > IFA_F_DEPRECATED > flag, that seems wrong. Instead I think it would be better if we tested for > the > OPTIMISTIC flag in ipv6_dev_get_saddr in parallel with the DEPRECATED flag. I > may be wrong about this, but I'm going to err on the side of safety. If you > can > ensure that this race is not possible. Please let me know, and I'll happily > just set the flag. I'll repost a new patch soon. I tend to agree with Neil here. Marking optimistic addresses as deprecated doesn't buy as much since the address can transition in and out of deprecated state regardless of DAD. However, there is a problem with the current implementation in that OPTIMISTIC address will never be chosen as source because it's always TENTATIVE and OPTIMISTIC at the same time. What needs to happen is for ipv6_dev_get_saddr() to not ignore OPTIMISTIC addresses and treat them same as DEPRECATED. -vlad - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
On Wed, Jan 24, 2007 at 05:54:47PM -0800, Sridhar Samudrala wrote: > Sec 2.1 of RFC 4429 says > >Unless noted otherwise, components of the IPv6 protocol stack should >treat addresses in the Optimistic state equivalently to those in the >Deprecated state, indicating that the address is available for use >but should not be used if another suitable address is available. For >example, Default Address Selection [RFC3484] uses the address state >to decide which source address to use for an outgoing packet. >Implementations should treat an address in state Optimistic as if it >were in state Deprecated. If address states are recorded as >individual flags, this can easily be achieved by also setting >'Deprecated' when 'Optimistic' is set. > > So i think DEPRECATED flag also should be set when we mark an address > as OPTIMISTIC so that we don't use it as source address for new > connections if another address is available until DAD is completed. > > Thanks > Sridhar > Oh, good catch. Thank you Sri. However, I'm worried about the next paragraph: It is important to note that the address lifetime rules of [RFC2462] still apply, and so an address may be Deprecated as well as Optimistic. When DAD completes without incident, the address becomes either a Preferred or a Deprecated address, as per RFC 2462 Given that, it seems to me that addresses which are flagged as Deprecated may enter and exit that state independently of the DAD process, which I think gives rise to the possibility of a race. I.e. if an address becomes deprecated right before DAD completes, and then addrconf_dad_complete clears the IFA_F_DEPRECATED flag, that seems wrong. Instead I think it would be better if we tested for the OPTIMISTIC flag in ipv6_dev_get_saddr in parallel with the DEPRECATED flag. I may be wrong about this, but I'm going to err on the side of safety. If you can ensure that this race is not possible. Please let me know, and I'll happily just set the flag. I'll repost a new patch soon. Thanks & Regards Neil > > On Tue, 2007-01-23 at 15:51 -0500, Neil Horman wrote: > > On Tue, Jan 23, 2007 at 09:18:20AM +0900, YOSHIFUJI Hideaki / 吉藤英明 wrote: > > > Hello. > > > > > > New patch attached, incorporating Yoshijui and Vlads latest comments. I > > didn't > > follow guidance on the ndisc_recv_ns comment, Yoshifuji, since Vlad had > > already > > suggested an alternate solution in a previous post, but from looking at them > > both, they should be equivalent. > > > > Thanks & Regards > > Neil > > > > Signed-off-by: Neil Horman <[EMAIL PROTECTED]> > > > > > > include/linux/if_addr.h |1 > > include/linux/ipv6.h|2 + > > include/linux/sysctl.h |1 > > include/net/addrconf.h |4 +- > > net/ipv6/addrconf.c | 56 > > net/ipv6/mcast.c|4 +- > > net/ipv6/ndisc.c| 82 > > +++- > > 7 files changed, 117 insertions(+), 33 deletions(-) > > > > > > diff --git a/include/linux/if_addr.h b/include/linux/if_addr.h > > index d557e4c..43f3bed 100644 > > --- a/include/linux/if_addr.h > > +++ b/include/linux/if_addr.h > > @@ -39,6 +39,7 @@ enum > > #define IFA_F_TEMPORARYIFA_F_SECONDARY > > > > #defineIFA_F_NODAD 0x02 > > +#define IFA_F_OPTIMISTIC 0x04 > > #defineIFA_F_HOMEADDRESS 0x10 > > #define IFA_F_DEPRECATED 0x20 > > #define IFA_F_TENTATIVE0x40 > > diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h > > index f824113..5d37abf 100644 > > --- a/include/linux/ipv6.h > > +++ b/include/linux/ipv6.h > > @@ -177,6 +177,7 @@ struct ipv6_devconf { > > #endif > > #endif > > __s32 proxy_ndp; > > + __s32 optimistic_dad; > > void*sysctl; > > }; > > > > @@ -205,6 +206,7 @@ enum { > > DEVCONF_RTR_PROBE_INTERVAL, > > DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN, > > DEVCONF_PROXY_NDP, > > + DEVCONF_OPTIMISTIC_DAD, > > DEVCONF_MAX > > }; > > > > diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h > > index 81480e6..972a33a 100644 > > --- a/include/linux/sysctl.h > > +++ b/include/linux/sysctl.h > > @@ -570,6 +570,7 @@ enum { > > NET_IPV6_RTR_PROBE_INTERVAL=21, > > NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=22, > > NET_IPV6_PROXY_NDP=23, > > + NET_IPV6_OPTIMISTIC_DAD=24, > > __NET_IPV6_MAX > > }; > > > > diff --git a/include/net/addrconf.h b/include/net/addrconf.h > > index 88df8fc..d248a19 100644 > > --- a/include/net/addrconf.h > > +++ b/include/net/addrconf.h > > @@ -73,7 +73,9 @@ extern intipv6_get_saddr(struct > > dst_entry *dst, > > extern int ipv6_dev_get_saddr(struct net_device *dev, > >struct in6_addr *daddr, > >struct in6_addr *saddr); > > -extern int ipv6_get_lladdr(struct net_d
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
Sec 2.1 of RFC 4429 says Unless noted otherwise, components of the IPv6 protocol stack should treat addresses in the Optimistic state equivalently to those in the Deprecated state, indicating that the address is available for use but should not be used if another suitable address is available. For example, Default Address Selection [RFC3484] uses the address state to decide which source address to use for an outgoing packet. Implementations should treat an address in state Optimistic as if it were in state Deprecated. If address states are recorded as individual flags, this can easily be achieved by also setting 'Deprecated' when 'Optimistic' is set. So i think DEPRECATED flag also should be set when we mark an address as OPTIMISTIC so that we don't use it as source address for new connections if another address is available until DAD is completed. Thanks Sridhar On Tue, 2007-01-23 at 15:51 -0500, Neil Horman wrote: > On Tue, Jan 23, 2007 at 09:18:20AM +0900, YOSHIFUJI Hideaki / 吉藤英明 wrote: > > Hello. > > > New patch attached, incorporating Yoshijui and Vlads latest comments. I > didn't > follow guidance on the ndisc_recv_ns comment, Yoshifuji, since Vlad had > already > suggested an alternate solution in a previous post, but from looking at them > both, they should be equivalent. > > Thanks & Regards > Neil > > Signed-off-by: Neil Horman <[EMAIL PROTECTED]> > > > include/linux/if_addr.h |1 > include/linux/ipv6.h|2 + > include/linux/sysctl.h |1 > include/net/addrconf.h |4 +- > net/ipv6/addrconf.c | 56 > net/ipv6/mcast.c|4 +- > net/ipv6/ndisc.c| 82 > +++- > 7 files changed, 117 insertions(+), 33 deletions(-) > > > diff --git a/include/linux/if_addr.h b/include/linux/if_addr.h > index d557e4c..43f3bed 100644 > --- a/include/linux/if_addr.h > +++ b/include/linux/if_addr.h > @@ -39,6 +39,7 @@ enum > #define IFA_F_TEMPORARY IFA_F_SECONDARY > > #define IFA_F_NODAD 0x02 > +#define IFA_F_OPTIMISTIC 0x04 > #define IFA_F_HOMEADDRESS 0x10 > #define IFA_F_DEPRECATED 0x20 > #define IFA_F_TENTATIVE 0x40 > diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h > index f824113..5d37abf 100644 > --- a/include/linux/ipv6.h > +++ b/include/linux/ipv6.h > @@ -177,6 +177,7 @@ struct ipv6_devconf { > #endif > #endif > __s32 proxy_ndp; > + __s32 optimistic_dad; > void*sysctl; > }; > > @@ -205,6 +206,7 @@ enum { > DEVCONF_RTR_PROBE_INTERVAL, > DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN, > DEVCONF_PROXY_NDP, > + DEVCONF_OPTIMISTIC_DAD, > DEVCONF_MAX > }; > > diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h > index 81480e6..972a33a 100644 > --- a/include/linux/sysctl.h > +++ b/include/linux/sysctl.h > @@ -570,6 +570,7 @@ enum { > NET_IPV6_RTR_PROBE_INTERVAL=21, > NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=22, > NET_IPV6_PROXY_NDP=23, > + NET_IPV6_OPTIMISTIC_DAD=24, > __NET_IPV6_MAX > }; > > diff --git a/include/net/addrconf.h b/include/net/addrconf.h > index 88df8fc..d248a19 100644 > --- a/include/net/addrconf.h > +++ b/include/net/addrconf.h > @@ -73,7 +73,9 @@ extern int ipv6_get_saddr(struct dst_entry > *dst, > extern int ipv6_dev_get_saddr(struct net_device *dev, > struct in6_addr *daddr, > struct in6_addr *saddr); > -extern int ipv6_get_lladdr(struct net_device *dev, struct > in6_addr *); > +extern int ipv6_get_lladdr(struct net_device *dev, > + struct in6_addr *, > + unsigned char banned_flags); > extern int ipv6_rcv_saddr_equal(const struct sock *sk, > const struct sock *sk2); > extern void addrconf_join_solict(struct net_device *dev, > diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c > index 2a7e461..d2b01ec 100644 > --- a/net/ipv6/addrconf.c > +++ b/net/ipv6/addrconf.c > @@ -830,7 +830,8 @@ retry: > ift = !max_addresses || > ipv6_count_addresses(idev) < max_addresses ? > ipv6_add_addr(idev, &addr, tmp_plen, > - ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, > IFA_F_TEMPORARY) : NULL; > + ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, > + IFA_F_TEMPORARY|IFA_F_OPTIMISTIC) : NULL; > if (!ift || IS_ERR(ift)) { > in6_ifa_put(ifp); > in6_dev_put(idev); > @@ -1174,7 +1175,8 @@ int ipv6_get_saddr(struct dst_entry *dst, > } > > > -int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *add
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
On Tue, Jan 23, 2007 at 09:18:20AM +0900, YOSHIFUJI Hideaki / 吉藤英明 wrote: > Hello. New patch attached, incorporating Yoshijui and Vlads latest comments. I didn't follow guidance on the ndisc_recv_ns comment, Yoshifuji, since Vlad had already suggested an alternate solution in a previous post, but from looking at them both, they should be equivalent. Thanks & Regards Neil Signed-off-by: Neil Horman <[EMAIL PROTECTED]> include/linux/if_addr.h |1 include/linux/ipv6.h|2 + include/linux/sysctl.h |1 include/net/addrconf.h |4 +- net/ipv6/addrconf.c | 56 net/ipv6/mcast.c|4 +- net/ipv6/ndisc.c| 82 +++- 7 files changed, 117 insertions(+), 33 deletions(-) diff --git a/include/linux/if_addr.h b/include/linux/if_addr.h index d557e4c..43f3bed 100644 --- a/include/linux/if_addr.h +++ b/include/linux/if_addr.h @@ -39,6 +39,7 @@ enum #define IFA_F_TEMPORARYIFA_F_SECONDARY #defineIFA_F_NODAD 0x02 +#define IFA_F_OPTIMISTIC 0x04 #defineIFA_F_HOMEADDRESS 0x10 #define IFA_F_DEPRECATED 0x20 #define IFA_F_TENTATIVE0x40 diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index f824113..5d37abf 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -177,6 +177,7 @@ struct ipv6_devconf { #endif #endif __s32 proxy_ndp; + __s32 optimistic_dad; void*sysctl; }; @@ -205,6 +206,7 @@ enum { DEVCONF_RTR_PROBE_INTERVAL, DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN, DEVCONF_PROXY_NDP, + DEVCONF_OPTIMISTIC_DAD, DEVCONF_MAX }; diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 81480e6..972a33a 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -570,6 +570,7 @@ enum { NET_IPV6_RTR_PROBE_INTERVAL=21, NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=22, NET_IPV6_PROXY_NDP=23, + NET_IPV6_OPTIMISTIC_DAD=24, __NET_IPV6_MAX }; diff --git a/include/net/addrconf.h b/include/net/addrconf.h index 88df8fc..d248a19 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -73,7 +73,9 @@ extern intipv6_get_saddr(struct dst_entry *dst, extern int ipv6_dev_get_saddr(struct net_device *dev, struct in6_addr *daddr, struct in6_addr *saddr); -extern int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *); +extern int ipv6_get_lladdr(struct net_device *dev, + struct in6_addr *, + unsigned char banned_flags); extern int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2); extern voidaddrconf_join_solict(struct net_device *dev, diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 2a7e461..d2b01ec 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -830,7 +830,8 @@ retry: ift = !max_addresses || ipv6_count_addresses(idev) < max_addresses ? ipv6_add_addr(idev, &addr, tmp_plen, - ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, IFA_F_TEMPORARY) : NULL; + ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, + IFA_F_TEMPORARY|IFA_F_OPTIMISTIC) : NULL; if (!ift || IS_ERR(ift)) { in6_ifa_put(ifp); in6_dev_put(idev); @@ -1174,7 +1175,8 @@ int ipv6_get_saddr(struct dst_entry *dst, } -int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr) +int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr, + unsigned char banned_flags) { struct inet6_dev *idev; int err = -EADDRNOTAVAIL; @@ -1185,7 +1187,7 @@ int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr) read_lock_bh(&idev->lock); for (ifp=idev->addr_list; ifp; ifp=ifp->if_next) { - if (ifp->scope == IFA_LINK && !(ifp->flags&IFA_F_TENTATIVE)) { + if (ifp->scope == IFA_LINK && !(ifp->flags & banned_flags)) { ipv6_addr_copy(addr, &ifp->addr); err = 0; break; @@ -1751,6 +1753,7 @@ ok: update_lft = create = 1; ifp->cstamp = jiffies; + ifp->flags |= IFA_F_OPTIMISTIC; addrconf_dad_start(ifp, RTF_ADDRCONF|RTF_PREFIX_RT); } @@ -1945,7 +1948,11 @@ static int inet6_addr_add(int ifindex, struct in6_addr *pfx, int plen,
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
Hi Neil Neil Horman wrote: > + /* > + * This is not a dad solicitation, meaning we > may > + * need to respond to it, if we are > + * an optimistic node, go ahead, otherwise > + * ignore it Nit. Can you rephrase the comment just a bit. It seems a bit of a run-on sentence... The other comment from Yoshifuji-san still apply. Thanks -vlad - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
On Mon, Jan 22, 2007 at 03:25:39PM -0500, Vlad Yasevich wrote: > Hi Neil Yeah, I think your right. I missed the implication of testing for (!dad) at the top of that clause. I think we could accomplish the same thing by moving my additions to the top of the clause, but I think your logic reads more cleanly. New patch attached Regards Neil Signed-off-by: Neil Horman <[EMAIL PROTECTED]> include/linux/if_addr.h |1 include/linux/ipv6.h|1 include/linux/sysctl.h |1 include/net/addrconf.h |4 +- net/ipv6/addrconf.c | 55 +++- net/ipv6/mcast.c|4 +- net/ipv6/ndisc.c| 82 +++- 7 files changed, 115 insertions(+), 33 deletions(-) diff --git a/include/linux/if_addr.h b/include/linux/if_addr.h index d557e4c..43f3bed 100644 --- a/include/linux/if_addr.h +++ b/include/linux/if_addr.h @@ -39,6 +39,7 @@ enum #define IFA_F_TEMPORARYIFA_F_SECONDARY #defineIFA_F_NODAD 0x02 +#define IFA_F_OPTIMISTIC 0x04 #defineIFA_F_HOMEADDRESS 0x10 #define IFA_F_DEPRECATED 0x20 #define IFA_F_TENTATIVE0x40 diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index f824113..1a8edc1 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -176,6 +176,7 @@ struct ipv6_devconf { __s32 accept_ra_rt_info_max_plen; #endif #endif + __s32 use_optimistic_dad; __s32 proxy_ndp; void*sysctl; }; diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 81480e6..972a33a 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -570,6 +570,7 @@ enum { NET_IPV6_RTR_PROBE_INTERVAL=21, NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=22, NET_IPV6_PROXY_NDP=23, + NET_IPV6_OPTIMISTIC_DAD=24, __NET_IPV6_MAX }; diff --git a/include/net/addrconf.h b/include/net/addrconf.h index 88df8fc..d248a19 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -73,7 +73,9 @@ extern intipv6_get_saddr(struct dst_entry *dst, extern int ipv6_dev_get_saddr(struct net_device *dev, struct in6_addr *daddr, struct in6_addr *saddr); -extern int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *); +extern int ipv6_get_lladdr(struct net_device *dev, + struct in6_addr *, + unsigned char banned_flags); extern int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2); extern voidaddrconf_join_solict(struct net_device *dev, diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 2a7e461..316d771 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -830,7 +830,8 @@ retry: ift = !max_addresses || ipv6_count_addresses(idev) < max_addresses ? ipv6_add_addr(idev, &addr, tmp_plen, - ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, IFA_F_TEMPORARY) : NULL; + ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, + IFA_F_TEMPORARY|IFA_F_OPTIMISTIC) : NULL; if (!ift || IS_ERR(ift)) { in6_ifa_put(ifp); in6_dev_put(idev); @@ -1174,7 +1175,8 @@ int ipv6_get_saddr(struct dst_entry *dst, } -int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr) +int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr, + unsigned char banned_flags) { struct inet6_dev *idev; int err = -EADDRNOTAVAIL; @@ -1185,7 +1187,7 @@ int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr) read_lock_bh(&idev->lock); for (ifp=idev->addr_list; ifp; ifp=ifp->if_next) { - if (ifp->scope == IFA_LINK && !(ifp->flags&IFA_F_TENTATIVE)) { + if (ifp->scope == IFA_LINK && !(ifp->flags & banned_flags)) { ipv6_addr_copy(addr, &ifp->addr); err = 0; break; @@ -1751,6 +1753,7 @@ ok: update_lft = create = 1; ifp->cstamp = jiffies; + ifp->flags |= IFA_F_OPTIMISTIC; addrconf_dad_start(ifp, RTF_ADDRCONF|RTF_PREFIX_RT); } @@ -1945,7 +1948,11 @@ static int inet6_addr_add(int ifindex, struct in6_addr *pfx, int plen, ifp->prefered_lft = prefered_lft; ifp->tstamp = jiffies; spin_unlock_bh(&ifp->lock); - + /* +* Note that se
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
Hello. In article <[EMAIL PROTECTED]> (at Mon, 22 Jan 2007 13:15:28 -0500), Neil Horman <[EMAIL PROTECTED]> says: > Reposted patch, with your suggestions/corrections incorporated. The only > thing > I left alone was your last comment regarding the checking of saddr for being a > unicast address. According to the RFC as I read it, its possible to receive > valid neighbor soliciations with a source address that is the unspecified > address, which I didn't think ipv6_addr_type flagged as being unicast. Now it > may be that such NS messages are discarded before arriving at that recieve > routine, but I was figuring better safe than sorry. If you're sufficiently > confident that we won't see non-unicast saddrs there, let me know and I'll > happily remove that as well. Okay, right, we can see unspecified source address. However, we have "dad" variable. More comments. > +++ b/include/linux/ipv6.h > @@ -176,6 +176,7 @@ struct ipv6_devconf { > __s32 accept_ra_rt_info_max_plen; > #endif > #endif > + __s32 use_optimistic_dad; > __s32 proxy_ndp; > void*sysctl; > }; Please do not insert between variables but add to the right before the "sysctl" member. > diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h > index 81480e6..972a33a 100644 > --- a/include/linux/sysctl.h > +++ b/include/linux/sysctl.h > @@ -570,6 +570,7 @@ enum { > NET_IPV6_RTR_PROBE_INTERVAL=21, > NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=22, > NET_IPV6_PROXY_NDP=23, > + NET_IPV6_OPTIMISTIC_DAD=24, > __NET_IPV6_MAX > }; > : > @@ -3918,6 +3948,15 @@ static struct addrconf_sysctl_table > .proc_handler = &proc_dointvec, > }, > { > + .ctl_name = NET_IPV6_OPTIMISTIC_DAD, > + .procname = "use_optimistic_dad", > + .data = > &ipv6_devconf.use_optimistic_dad, > + .maxlen = sizeof(int), > + .mode = 0644, > + .proc_handler = &proc_dointvec, > + > + }, > + { > .ctl_name = 0, /* sentinel */ > } > }, Please use similar names (sysctl enum, member name and sysctl name(s)); e.g. NET_IPV6_OPTIMISTIC_DAD, optimistic_dad, "optimistic_dad". You forgot adding DEVCONF_OPTIMISTIC_DAD in include/linux/ipv6.h and net/ipv6/addrconf.c:ipv6_store_devconf(). : > @@ -746,6 +772,7 @@ static void ndisc_recv_ns(struct sk_buff *skb) > int dad = ipv6_addr_any(saddr); > int inc; > int is_router; > + int type; > > if (ipv6_addr_is_multicast(&msg->target)) { > ND_PRINTK2(KERN_WARNING Here, "dad" is true if the source is unspecified address. So, > @@ -816,8 +845,20 @@ static void ndisc_recv_ns(struct sk_buff *skb) > goto out; > } > } > - addrconf_dad_failure(ifp); > - return; > + > + /* The one exception to the above rule about > +optimistic addresses is that we need to always > +respond to an NS from a unicast address if we are > +optimistic. RFC 4429 Sec 3.3. If (unicast > +and optimistic) are false then we can just fail > +dad now. > + */ > + type = ipv6_addr_type(saddr); > + if (!((ifp->flags & IFA_F_OPTIMISTIC) && > + (type & IPV6_ADDR_UNICAST))) { > + addrconf_dad_failure(ifp); > + return; > + } > } > > idev = ifp->idev; You can say, if (dad || !(ifp->flags & IFA_F_OPTIMISTIC)) { addrconf_dad_failure(ifp); return; } Regards, -- YOSHIFUJI Hideaki @ USAGI Project <[EMAIL PROTECTED]> GPG-FP : 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
Hi Neil I don't this is still right... > @@ -746,6 +772,7 @@ static void ndisc_recv_ns(struct sk_buff *skb) > int dad = ipv6_addr_any(saddr); > int inc; > int is_router; > + int type; > > if (ipv6_addr_is_multicast(&msg->target)) { > ND_PRINTK2(KERN_WARNING > @@ -796,14 +823,8 @@ static void ndisc_recv_ns(struct sk_buff *skb) > inc = ipv6_addr_is_multicast(daddr); > > if ((ifp = ipv6_get_ifaddr(&msg->target, dev, 1)) != NULL) { > - if (ifp->flags & IFA_F_TENTATIVE) { > - /* Address is tentative. If the source > -is unspecified address, it is someone > -does DAD, otherwise we ignore solicitations > -until DAD timer expires. > - */ > - if (!dad) > - goto out; > + > + if (ifp->flags & (IFA_F_TENTATIVE|IFA_F_OPTIMISTIC)) { > if (dev->type == ARPHRD_IEEE802_TR) { > unsigned char *sadr = skb->mac.raw; > if (((sadr[8] ^ dev->dev_addr[0]) & 0x7f) == 0 > && > @@ -816,8 +837,23 @@ static void ndisc_recv_ns(struct sk_buff *skb) > goto out; > } > } First, you do looped packet detection for all packets, not just DAD. > - addrconf_dad_failure(ifp); > - return; > + > + /* The one exception to the above rule about > +optimistic addresses is that we need to always > +respond to an NS from a unicast address if we are > +optimistic. RFC 4429 Sec 3.3. If (unicast > +and optimistic) are false then we can just fail > +dad now. > + */ > + if (ifp->flags & IFA_F_OPTIMISTIC) { > + type = ipv6_addr_type(saddr); > + if (!(type & IPV6_ADDR_UNICAST)) { > + addrconf_dad_failure(ifp); > + goto out; > + } > + } else > + if (!dad) > + goto out; Second, you fail dad in the OPTIMISTIC case, but not the regular case, which should also fail if this is a DAD packet. I think the following is what you want (totally untested): if (ifp->flags & (IFA_F_TENTATIVE|IFA_F_OPTIMISTIC)) { if (dad) { /* We are processing a DAD packet for a tentative address. * Make sure that this was not one of our NSs looped back * to us. */ if (dev->type== ARPHDR_IEEE802_TR) { . blah ... } /* Fail DAD since we are colliding with someout out there*/ addrconf_dad_failure(ifp); } else { /* This is not a DAD neighbor solicitation. If we * are OPTIMISTIC, we'll respond with a NA. Otherwise * we'll ignore the packet. */ if (!(ifp->flags & IFA_F_OPTIMISTIC)) goto out } } idef = ifp->idev; -vlad - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
On Mon, Jan 22, 2007 at 08:39:24PM +0200, Mika Penttilä wrote: > Neil Horman wrote: > > I think you should remove / modify the : > if (!dad) >goto out; > > which makes the rfc4429 tests not functional. > > --Mika > Yeah, I think you're right. In fact, as I look at it more closely I think that logic for NS message recives is a bit confused overall. Section 3.3 of RFC 4429 says that I should fail DAD if I'm optimistic and I get an NS from the unspecified address, but I must reply to an NS from a unicast address. The way the logic is written, I was going to fail dad if the address was just tentative (i.e. odad was disabled), which is a deviation from the nominal behavior. And of course, as you mention, the (!dad) clause kills the odad tests (although it is still required if we are not an optimistic address). This updated patch should take care of all that, as well as make that logic more clear Thanks & Regards Neil Signed-off-by: Neil Horman <[EMAIL PROTECTED]> include/linux/if_addr.h |1 include/linux/ipv6.h|1 include/linux/sysctl.h |1 include/net/addrconf.h |4 ++- net/ipv6/addrconf.c | 55 -- net/ipv6/mcast.c|4 +-- net/ipv6/ndisc.c| 62 +--- 7 files changed, 104 insertions(+), 24 deletions(-) diff --git a/include/linux/if_addr.h b/include/linux/if_addr.h index d557e4c..43f3bed 100644 --- a/include/linux/if_addr.h +++ b/include/linux/if_addr.h @@ -39,6 +39,7 @@ enum #define IFA_F_TEMPORARYIFA_F_SECONDARY #defineIFA_F_NODAD 0x02 +#define IFA_F_OPTIMISTIC 0x04 #defineIFA_F_HOMEADDRESS 0x10 #define IFA_F_DEPRECATED 0x20 #define IFA_F_TENTATIVE0x40 diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index f824113..1a8edc1 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -176,6 +176,7 @@ struct ipv6_devconf { __s32 accept_ra_rt_info_max_plen; #endif #endif + __s32 use_optimistic_dad; __s32 proxy_ndp; void*sysctl; }; diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 81480e6..972a33a 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -570,6 +570,7 @@ enum { NET_IPV6_RTR_PROBE_INTERVAL=21, NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=22, NET_IPV6_PROXY_NDP=23, + NET_IPV6_OPTIMISTIC_DAD=24, __NET_IPV6_MAX }; diff --git a/include/net/addrconf.h b/include/net/addrconf.h index 88df8fc..d248a19 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -73,7 +73,9 @@ extern intipv6_get_saddr(struct dst_entry *dst, extern int ipv6_dev_get_saddr(struct net_device *dev, struct in6_addr *daddr, struct in6_addr *saddr); -extern int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *); +extern int ipv6_get_lladdr(struct net_device *dev, + struct in6_addr *, + unsigned char banned_flags); extern int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2); extern voidaddrconf_join_solict(struct net_device *dev, diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 2a7e461..316d771 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -830,7 +830,8 @@ retry: ift = !max_addresses || ipv6_count_addresses(idev) < max_addresses ? ipv6_add_addr(idev, &addr, tmp_plen, - ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, IFA_F_TEMPORARY) : NULL; + ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, + IFA_F_TEMPORARY|IFA_F_OPTIMISTIC) : NULL; if (!ift || IS_ERR(ift)) { in6_ifa_put(ifp); in6_dev_put(idev); @@ -1174,7 +1175,8 @@ int ipv6_get_saddr(struct dst_entry *dst, } -int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr) +int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr, + unsigned char banned_flags) { struct inet6_dev *idev; int err = -EADDRNOTAVAIL; @@ -1185,7 +1187,7 @@ int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr) read_lock_bh(&idev->lock); for (ifp=idev->addr_list; ifp; ifp=ifp->if_next) { - if (ifp->scope == IFA_LINK && !(ifp->flags&IFA_F_TENTATIVE)) { + if (ifp->scope == IFA_LINK && !(ifp->flags & banned_flags)) { ipv6_addr_copy(addr, &ifp->addr);
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
Neil Horman wrote: On Sat, Jan 20, 2007 at 08:05:07AM +0900, YOSHIFUJI Hideaki / 吉藤英明 wrote: Hello. In article <[EMAIL PROTECTED]> (at Fri, 19 Jan 2007 16:23:14 -0500), Neil Horman <[EMAIL PROTECTED]> says: Patch to Implement IPv6 RFC 4429 (Optimistic Duplicate Address Detection). In Good work. We will see if this would break core and basic ipv6 code. Dave, please hold on. Some quick comments. --yoshfuji Reposted patch, with your suggestions/corrections incorporated. The only thing I left alone was your last comment regarding the checking of saddr for being a unicast address. According to the RFC as I read it, its possible to receive valid neighbor soliciations with a source address that is the unspecified address, which I didn't think ipv6_addr_type flagged as being unicast. Now it may be that such NS messages are discarded before arriving at that recieve routine, but I was figuring better safe than sorry. If you're sufficiently confident that we won't see non-unicast saddrs there, let me know and I'll happily remove that as well. Thanks & Regards Neil NTATIVE) { + + if (ifp->flags & (IFA_F_TENTATIVE|IFA_F_OPTIMISTIC)) { /* Address is tentative. If the source - is unspecified address, it is someone - does DAD, otherwise we ignore solicitations - until DAD timer expires. + is unspecified address, someone else + is doing DAD, and if its not us, then + we need to fail our own DAD + RFC 4429 Sec 3.3 */ if (!dad) goto out; @@ -816,8 +845,20 @@ static void ndisc_recv_ns(struct sk_buff *skb) goto out; } } - addrconf_dad_failure(ifp); - return; + + /* The one exception to the above rule about + optimistic addresses is that we need to always + respond to an NS from a unicast address if we are + optimistic. RFC 4429 Sec 3.3. If (unicast + and optimistic) are false then we can just fail + dad now. + */ + type = ipv6_addr_type(saddr); + if (!((ifp->flags & IFA_F_OPTIMISTIC) && + (type & IPV6_ADDR_UNICAST))) { +addrconf_dad_failure(ifp); +return; + } } I think you should remove / modify the : if (!dad) goto out; which makes the rfc4429 tests not functional. --Mika - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
On Sat, Jan 20, 2007 at 08:05:07AM +0900, YOSHIFUJI Hideaki / 吉藤英明 wrote: > Hello. > > In article <[EMAIL PROTECTED]> (at Fri, 19 Jan 2007 16:23:14 -0500), Neil > Horman <[EMAIL PROTECTED]> says: > > > Patch to Implement IPv6 RFC 4429 (Optimistic Duplicate Address Detection). > > In > > Good work. We will see if this would break core and basic ipv6 code. > Dave, please hold on. > > Some quick comments. > --yoshfuji Reposted patch, with your suggestions/corrections incorporated. The only thing I left alone was your last comment regarding the checking of saddr for being a unicast address. According to the RFC as I read it, its possible to receive valid neighbor soliciations with a source address that is the unspecified address, which I didn't think ipv6_addr_type flagged as being unicast. Now it may be that such NS messages are discarded before arriving at that recieve routine, but I was figuring better safe than sorry. If you're sufficiently confident that we won't see non-unicast saddrs there, let me know and I'll happily remove that as well. Thanks & Regards Neil Signed-off-by: Neil Horman <[EMAIL PROTECTED]> include/linux/if_addr.h |1 include/linux/ipv6.h|1 include/linux/sysctl.h |1 include/net/addrconf.h |4 ++- net/ipv6/addrconf.c | 55 ++-- net/ipv6/mcast.c|4 +-- net/ipv6/ndisc.c| 59 7 files changed, 105 insertions(+), 20 deletions(-) diff --git a/include/linux/if_addr.h b/include/linux/if_addr.h index d557e4c..43f3bed 100644 --- a/include/linux/if_addr.h +++ b/include/linux/if_addr.h @@ -39,6 +39,7 @@ enum #define IFA_F_TEMPORARYIFA_F_SECONDARY #defineIFA_F_NODAD 0x02 +#define IFA_F_OPTIMISTIC 0x04 #defineIFA_F_HOMEADDRESS 0x10 #define IFA_F_DEPRECATED 0x20 #define IFA_F_TENTATIVE0x40 diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index f824113..1a8edc1 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h @@ -176,6 +176,7 @@ struct ipv6_devconf { __s32 accept_ra_rt_info_max_plen; #endif #endif + __s32 use_optimistic_dad; __s32 proxy_ndp; void*sysctl; }; diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index 81480e6..972a33a 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -570,6 +570,7 @@ enum { NET_IPV6_RTR_PROBE_INTERVAL=21, NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=22, NET_IPV6_PROXY_NDP=23, + NET_IPV6_OPTIMISTIC_DAD=24, __NET_IPV6_MAX }; diff --git a/include/net/addrconf.h b/include/net/addrconf.h index 88df8fc..d248a19 100644 --- a/include/net/addrconf.h +++ b/include/net/addrconf.h @@ -73,7 +73,9 @@ extern intipv6_get_saddr(struct dst_entry *dst, extern int ipv6_dev_get_saddr(struct net_device *dev, struct in6_addr *daddr, struct in6_addr *saddr); -extern int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *); +extern int ipv6_get_lladdr(struct net_device *dev, + struct in6_addr *, + unsigned char banned_flags); extern int ipv6_rcv_saddr_equal(const struct sock *sk, const struct sock *sk2); extern voidaddrconf_join_solict(struct net_device *dev, diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 2a7e461..316d771 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -830,7 +830,8 @@ retry: ift = !max_addresses || ipv6_count_addresses(idev) < max_addresses ? ipv6_add_addr(idev, &addr, tmp_plen, - ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, IFA_F_TEMPORARY) : NULL; + ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, + IFA_F_TEMPORARY|IFA_F_OPTIMISTIC) : NULL; if (!ift || IS_ERR(ift)) { in6_ifa_put(ifp); in6_dev_put(idev); @@ -1174,7 +1175,8 @@ int ipv6_get_saddr(struct dst_entry *dst, } -int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr) +int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr, + unsigned char banned_flags) { struct inet6_dev *idev; int err = -EADDRNOTAVAIL; @@ -1185,7 +1187,7 @@ int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr) read_lock_bh(&idev->lock); for (ifp=idev->addr_list; ifp; ifp=ifp->if_next) { - if (ifp->scope == IFA_LINK && !(ifp->flags&IFA_F_TENTATIVE)) { + i
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
On Sat, Jan 20, 2007 at 08:05:07AM +0900, YOSHIFUJI Hideaki / 吉藤英明 wrote: > Hello. > > In article <[EMAIL PROTECTED]> (at Fri, 19 Jan 2007 16:23:14 -0500), Neil > Horman <[EMAIL PROTECTED]> says: > > > Patch to Implement IPv6 RFC 4429 (Optimistic Duplicate Address Detection). > > In > > Good work. We will see if this would break core and basic ipv6 code. > Dave, please hold on. > Thank you. I'll implement your requested changes and repost monday afternoon Regards Neil > Some quick comments. > > > --- a/include/net/ipv6.h > > +++ b/include/net/ipv6.h > > @@ -110,6 +110,7 @@ struct frag_hdr { > > /* sysctls */ > > extern int sysctl_ipv6_bindv6only; > > extern int sysctl_mld_max_msf; > > +extern int sysctl_optimistic_dad; > > > : > > diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c > > index 2a7e461..f7afb2a 100644 > > --- a/net/ipv6/addrconf.c > > +++ b/net/ipv6/addrconf.c > > @@ -206,6 +206,8 @@ static struct ipv6_devconf ipv6_devconf_dflt > > __read_mostly = { > > .proxy_ndp = 0, > > }; > > > > +int sysctl_optimistic_dad = 1; > > + > > Please put this into ipv6_devconf{} and make it per-interface variable. > And I think default should be kept off (0). > > > /* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */ > > #if 0 > > const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT; > > @@ -830,7 +832,8 @@ retry: > > ift = !max_addresses || > > ipv6_count_addresses(idev) < max_addresses ? > > ipv6_add_addr(idev, &addr, tmp_plen, > > - ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, > > IFA_F_TEMPORARY) : NULL; > > + ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, > > + IFA_F_TEMPORARY|IFA_F_OPTIMISTIC) : NULL; > > if (!ift || IS_ERR(ift)) { > > in6_ifa_put(ifp); > > in6_dev_put(idev); > > Please align ipv6_addr_type and IFA_F_TEMPORARY > > > @@ -1174,7 +1177,8 @@ int ipv6_get_saddr(struct dst_entry *dst, > > } > > > > > > -int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr) > > +int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr, > > + unsigned char banned_flags) > > { > > struct inet6_dev *idev; > > int err = -EADDRNOTAVAIL; > > Please align "struct net_device" and "unsigned char". > > > @@ -1185,7 +1189,7 @@ int ipv6_get_lladdr(struct net_device *dev, struct > > in6_addr *addr) > > > > read_lock_bh(&idev->lock); > > for (ifp=idev->addr_list; ifp; ifp=ifp->if_next) { > > - if (ifp->scope == IFA_LINK && > > !(ifp->flags&IFA_F_TENTATIVE)) { > > + if (ifp->scope == IFA_LINK && > > !(ifp->flags&banned_flags)) { > > ipv6_addr_copy(addr, &ifp->addr); > > err = 0; > > break; > > @@ -1742,7 +1746,7 @@ ok: > > It is not your fault, but please put a space around "&". > > > if (!max_addresses || > > ipv6_count_addresses(in6_dev) < max_addresses) > > ifp = ipv6_add_addr(in6_dev, &addr, > > pinfo->prefix_len, > > - > > addr_type&IPV6_ADDR_SCOPE_MASK, 0); > > + > > addr_type&IPV6_ADDR_SCOPE_MASK,0); > > > > if (!ifp || IS_ERR(ifp)) { > > in6_dev_put(in6_dev); > > Please do no kill space after ",". > > > @@ -2123,7 +2132,8 @@ static void addrconf_add_linklocal(struct inet6_dev > > *idev, struct in6_addr *addr > > { > > struct inet6_ifaddr * ifp; > > > > - ifp = ipv6_add_addr(idev, addr, 64, IFA_LINK, IFA_F_PERMANENT); > > + ifp = ipv6_add_addr(idev, addr, 64, IFA_LINK, > > + IFA_F_PERMANENT|IFA_F_OPTIMISTIC); > > if (!IS_ERR(ifp)) { > > addrconf_dad_start(ifp, 0); > > in6_ifa_put(ifp); > > Please align idev and IFA_F_PERMANENT. > > > @@ -542,7 +556,8 @@ void ndisc_send_ns(struct net_device *dev, struct > > neighbour *neigh, > > int send_llinfo; > > > > if (saddr == NULL) { > > - if (ipv6_get_lladdr(dev, &addr_buf)) > > + if (ipv6_get_lladdr(dev, &addr_buf, > > + (IFA_F_TENTATIVE|IFA_F_OPTIMISTIC))) > > return; > > saddr = &addr_buf; > > } > > ditto... ("dev" and "(") > > > + and optimistic) are false then we can just fail > > + dad now. > > + */ > > + type = ipv6_addr_type(saddr); > > + if (!((ifp->flags & IFA_F_OPTIMISTIC) && > > + (type & IPV6_ADDR_UNICAST))) { > > + addrconf_dad_failure(ifp); > > + return; > > + } > > } > > > > idev = ifp->idev;
Re: [PATCH] IPv6: Implement RFC 4429 Optimistic Duplicate Address Detection
Hello. In article <[EMAIL PROTECTED]> (at Fri, 19 Jan 2007 16:23:14 -0500), Neil Horman <[EMAIL PROTECTED]> says: > Patch to Implement IPv6 RFC 4429 (Optimistic Duplicate Address Detection). In Good work. We will see if this would break core and basic ipv6 code. Dave, please hold on. Some quick comments. > --- a/include/net/ipv6.h > +++ b/include/net/ipv6.h > @@ -110,6 +110,7 @@ struct frag_hdr { > /* sysctls */ > extern int sysctl_ipv6_bindv6only; > extern int sysctl_mld_max_msf; > +extern int sysctl_optimistic_dad; > : > diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c > index 2a7e461..f7afb2a 100644 > --- a/net/ipv6/addrconf.c > +++ b/net/ipv6/addrconf.c > @@ -206,6 +206,8 @@ static struct ipv6_devconf ipv6_devconf_dflt > __read_mostly = { > .proxy_ndp = 0, > }; > > +int sysctl_optimistic_dad = 1; > + Please put this into ipv6_devconf{} and make it per-interface variable. And I think default should be kept off (0). > /* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */ > #if 0 > const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT; > @@ -830,7 +832,8 @@ retry: > ift = !max_addresses || > ipv6_count_addresses(idev) < max_addresses ? > ipv6_add_addr(idev, &addr, tmp_plen, > - ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, > IFA_F_TEMPORARY) : NULL; > + ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, > + IFA_F_TEMPORARY|IFA_F_OPTIMISTIC) : NULL; > if (!ift || IS_ERR(ift)) { > in6_ifa_put(ifp); > in6_dev_put(idev); Please align ipv6_addr_type and IFA_F_TEMPORARY > @@ -1174,7 +1177,8 @@ int ipv6_get_saddr(struct dst_entry *dst, > } > > > -int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr) > +int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr, > + unsigned char banned_flags) > { > struct inet6_dev *idev; > int err = -EADDRNOTAVAIL; Please align "struct net_device" and "unsigned char". > @@ -1185,7 +1189,7 @@ int ipv6_get_lladdr(struct net_device *dev, struct > in6_addr *addr) > > read_lock_bh(&idev->lock); > for (ifp=idev->addr_list; ifp; ifp=ifp->if_next) { > - if (ifp->scope == IFA_LINK && > !(ifp->flags&IFA_F_TENTATIVE)) { > + if (ifp->scope == IFA_LINK && > !(ifp->flags&banned_flags)) { > ipv6_addr_copy(addr, &ifp->addr); > err = 0; > break; > @@ -1742,7 +1746,7 @@ ok: It is not your fault, but please put a space around "&". > if (!max_addresses || > ipv6_count_addresses(in6_dev) < max_addresses) > ifp = ipv6_add_addr(in6_dev, &addr, > pinfo->prefix_len, > - > addr_type&IPV6_ADDR_SCOPE_MASK, 0); > + > addr_type&IPV6_ADDR_SCOPE_MASK,0); > > if (!ifp || IS_ERR(ifp)) { > in6_dev_put(in6_dev); Please do no kill space after ",". > @@ -2123,7 +2132,8 @@ static void addrconf_add_linklocal(struct inet6_dev > *idev, struct in6_addr *addr > { > struct inet6_ifaddr * ifp; > > - ifp = ipv6_add_addr(idev, addr, 64, IFA_LINK, IFA_F_PERMANENT); > + ifp = ipv6_add_addr(idev, addr, 64, IFA_LINK, > + IFA_F_PERMANENT|IFA_F_OPTIMISTIC); > if (!IS_ERR(ifp)) { > addrconf_dad_start(ifp, 0); > in6_ifa_put(ifp); Please align idev and IFA_F_PERMANENT. > @@ -542,7 +556,8 @@ void ndisc_send_ns(struct net_device *dev, struct > neighbour *neigh, > int send_llinfo; > > if (saddr == NULL) { > - if (ipv6_get_lladdr(dev, &addr_buf)) > + if (ipv6_get_lladdr(dev, &addr_buf, > + (IFA_F_TENTATIVE|IFA_F_OPTIMISTIC))) > return; > saddr = &addr_buf; > } ditto... ("dev" and "(") > +and optimistic) are false then we can just fail > +dad now. > + */ > + type = ipv6_addr_type(saddr); > + if (!((ifp->flags & IFA_F_OPTIMISTIC) && > + (type & IPV6_ADDR_UNICAST))) { > + addrconf_dad_failure(ifp); > + return; > + } > } > > idev = ifp->idev; hmm? Here, is saddr always unicast, isn't it?! --yoshfuji - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html