Re: Kill IN6_IFF_NODAD

2015-08-22 Thread Martin Pieuchot
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

2015-08-19 Thread Martin Pieuchot
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