Re: Kill IN6_IFF_NODAD
On 19/08/15(Wed) 13:31, Martin Pieuchot wrote: > KAME people chose to add states to the address descriptors in order > to implement various IPv6 automagic features. But IN6_IFF_NODAD is > not a real state, it's just a hack for some spaghetti code. > > Diff belows get rids of this flag by shuffling some code around and > only using the IN6_IFF_TENTATIVE flag. Updated diff, this one contains a splsoftnet() missed in previous and kindly reported by sthen@. Index: net/if_spppsubr.c === RCS file: /cvs/src/sys/net/if_spppsubr.c,v retrieving revision 1.136 diff -u -p -r1.136 if_spppsubr.c --- net/if_spppsubr.c 18 Jul 2015 15:51:16 - 1.136 +++ net/if_spppsubr.c 22 Aug 2015 10:19:41 - @@ -4790,9 +4790,6 @@ sppp_set_ip6_addr(struct sppp *sp, const */ ifra->ifra_prefixmask.sin6_family = AF_UNSPEC; - /* DAD is redundant after an IPv6CP exchange. */ - ifra->ifra_flags |= IN6_IFF_NODAD; - task_add(systq, &sp->ipv6cp.set_addr_task); } Index: netinet6/in6.c === RCS file: /cvs/src/sys/netinet6/in6.c,v retrieving revision 1.165 diff -u -p -r1.165 in6.c --- netinet6/in6.c 19 Aug 2015 13:27:38 - 1.165 +++ netinet6/in6.c 22 Aug 2015 10:25:19 - @@ -468,11 +468,19 @@ in6_control(struct socket *so, u_long cm /* reject read-only flags */ if ((ifra->ifra_flags & IN6_IFF_DUPLICATED) != 0 || (ifra->ifra_flags & IN6_IFF_DETACHED) != 0 || - (ifra->ifra_flags & IN6_IFF_NODAD) != 0 || (ifra->ifra_flags & IN6_IFF_DEPRECATED) != 0 || (ifra->ifra_flags & IN6_IFF_AUTOCONF) != 0) { return (EINVAL); } + + /* +* Make the address tentative before joining multicast +* addresses, so that corresponding MLD responses would +* not have a tentative source address. +*/ + if ((ia6 == NULL) && in6if_do_dad(ifp)) + ifra->ifra_flags |= IN6_IFF_TENTATIVE; + /* * first, make or update the interface address structure, * and link it to the list. try to enable inet6 if there @@ -497,6 +505,11 @@ in6_control(struct socket *so, u_long cm break; } + /* Perform DAD, if needed. */ + if (ia6->ia6_flags & IN6_IFF_TENTATIVE) + nd6_dad_start(&ia6->ia_ifa); + + plen = in6_mask2len(&ifra->ifra_prefixmask.sin6_addr, NULL); if (plen == 128) { dohooks(ifp->if_addrhooks, 0); @@ -753,15 +766,6 @@ in6_update_ifa(struct ifnet *ifp, struct * configure address flags. */ ia6->ia6_flags = ifra->ifra_flags; - /* -* Make the address tentative before joining multicast addresses, -* so that corresponding MLD responses would not have a tentative -* source address. -*/ - ia6->ia6_flags &= ~IN6_IFF_DUPLICATED; /* safety */ - if (hostIsNew && in6if_do_dad(ifp) && - (ifra->ifra_flags & IN6_IFF_NODAD) == 0) - ia6->ia6_flags |= IN6_IFF_TENTATIVE; /* * We are done if we have simply modified an existing address. @@ -906,17 +910,6 @@ in6_update_ifa(struct ifnet *ifp, struct if (!imm) goto cleanup; LIST_INSERT_HEAD(&ia6->ia6_memberships, imm, i6mm_chain); - } - - /* -* Perform DAD, if needed. -* XXX It may be of use, if we can administratively -* disable DAD. -*/ - if (hostIsNew && in6if_do_dad(ifp) && - (ifra->ifra_flags & IN6_IFF_NODAD) == 0) - { - nd6_dad_start(&ia6->ia_ifa, NULL); } return (error); Index: netinet6/in6_ifattach.c === RCS file: /cvs/src/sys/netinet6/in6_ifattach.c,v retrieving revision 1.91 diff -u -p -r1.91 in6_ifattach.c --- netinet6/in6_ifattach.c 17 Aug 2015 10:57:24 - 1.91 +++ netinet6/in6_ifattach.c 22 Aug 2015 10:19:41 - @@ -292,7 +292,6 @@ success: int in6_ifattach_linklocal(struct ifnet *ifp, struct in6_addr *ifid) { - struct in6_ifaddr *ia6; struct in6_aliasreq ifra; int s, error; @@ -332,12 +331,6 @@ in6_ifattach_linklocal(struct ifnet *ifp ifra.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME; /* -* Do not let in6_update_ifa() do DAD, since we need a random delay -* before sending an NS at the first time the interface becomes up. -*/ - ifra.ifra_flags |= IN6_IFF_NODAD; - - /* * Now call in6_update_ifa() to do a bunch of procedures to configure * a link
Kill IN6_IFF_NODAD
KAME people chose to add states to the address descriptors in order to implement various IPv6 automagic features. But IN6_IFF_NODAD is not a real state, it's just a hack for some spaghetti code. Diff belows get rids of this flag by shuffling some code around and only using the IN6_IFF_TENTATIVE flag. Ok? Index: net/if_spppsubr.c === RCS file: /cvs/src/sys/net/if_spppsubr.c,v retrieving revision 1.136 diff -u -p -r1.136 if_spppsubr.c --- net/if_spppsubr.c 18 Jul 2015 15:51:16 - 1.136 +++ net/if_spppsubr.c 19 Aug 2015 11:15:01 - @@ -4790,9 +4790,6 @@ sppp_set_ip6_addr(struct sppp *sp, const */ ifra->ifra_prefixmask.sin6_family = AF_UNSPEC; - /* DAD is redundant after an IPv6CP exchange. */ - ifra->ifra_flags |= IN6_IFF_NODAD; - task_add(systq, &sp->ipv6cp.set_addr_task); } Index: netinet6/in6.c === RCS file: /cvs/src/sys/netinet6/in6.c,v retrieving revision 1.164 diff -u -p -r1.164 in6.c --- netinet6/in6.c 19 Aug 2015 11:09:24 - 1.164 +++ netinet6/in6.c 19 Aug 2015 11:15:02 - @@ -468,11 +468,19 @@ in6_control(struct socket *so, u_long cm /* reject read-only flags */ if ((ifra->ifra_flags & IN6_IFF_DUPLICATED) != 0 || (ifra->ifra_flags & IN6_IFF_DETACHED) != 0 || - (ifra->ifra_flags & IN6_IFF_NODAD) != 0 || (ifra->ifra_flags & IN6_IFF_DEPRECATED) != 0 || (ifra->ifra_flags & IN6_IFF_AUTOCONF) != 0) { return (EINVAL); } + + /* +* Make the address tentative before joining multicast +* addresses, so that corresponding MLD responses would +* not have a tentative source address. +*/ + if ((ia6 == NULL) && in6if_do_dad(ifp)) + ifra->ifra_flags |= IN6_IFF_TENTATIVE; + /* * first, make or update the interface address structure, * and link it to the list. try to enable inet6 if there @@ -497,6 +505,11 @@ in6_control(struct socket *so, u_long cm break; } + /* Perform DAD, if needed. */ + if (ia6->ia6_flags & IN6_IFF_TENTATIVE) + nd6_dad_start(&ia6->ia_ifa); + + plen = in6_mask2len(&ifra->ifra_prefixmask.sin6_addr, NULL); if (plen == 128) { dohooks(ifp->if_addrhooks, 0); @@ -753,15 +766,6 @@ in6_update_ifa(struct ifnet *ifp, struct * configure address flags. */ ia6->ia6_flags = ifra->ifra_flags; - /* -* Make the address tentative before joining multicast addresses, -* so that corresponding MLD responses would not have a tentative -* source address. -*/ - ia6->ia6_flags &= ~IN6_IFF_DUPLICATED; /* safety */ - if (hostIsNew && in6if_do_dad(ifp) && - (ifra->ifra_flags & IN6_IFF_NODAD) == 0) - ia6->ia6_flags |= IN6_IFF_TENTATIVE; /* * We are done if we have simply modified an existing address. @@ -906,17 +910,6 @@ in6_update_ifa(struct ifnet *ifp, struct if (!imm) goto cleanup; LIST_INSERT_HEAD(&ia6->ia6_memberships, imm, i6mm_chain); - } - - /* -* Perform DAD, if needed. -* XXX It may be of use, if we can administratively -* disable DAD. -*/ - if (hostIsNew && in6if_do_dad(ifp) && - (ifra->ifra_flags & IN6_IFF_NODAD) == 0) - { - nd6_dad_start(&ia6->ia_ifa, NULL); } return (error); Index: netinet6/in6_ifattach.c === RCS file: /cvs/src/sys/netinet6/in6_ifattach.c,v retrieving revision 1.91 diff -u -p -r1.91 in6_ifattach.c --- netinet6/in6_ifattach.c 17 Aug 2015 10:57:24 - 1.91 +++ netinet6/in6_ifattach.c 19 Aug 2015 11:15:02 - @@ -292,7 +292,6 @@ success: int in6_ifattach_linklocal(struct ifnet *ifp, struct in6_addr *ifid) { - struct in6_ifaddr *ia6; struct in6_aliasreq ifra; int s, error; @@ -332,12 +331,6 @@ in6_ifattach_linklocal(struct ifnet *ifp ifra.ifra_lifetime.ia6t_pltime = ND6_INFINITE_LIFETIME; /* -* Do not let in6_update_ifa() do DAD, since we need a random delay -* before sending an NS at the first time the interface becomes up. -*/ - ifra.ifra_flags |= IN6_IFF_NODAD; - - /* * Now call in6_update_ifa() to do a bunch of procedures to configure * a link-local address. In the case of CARP, we may be called after * one has already been configured, so check if it's already there @@ -363,21 +356,17