Re: nd6_timer & global list of IPv6 addresses

2017-03-01 Thread Alexander Bluhm
On Wed, Mar 01, 2017 at 12:46:08PM +0100, Martin Pieuchot wrote:
> The work done in this timer should be considerably reduced when we'll
> move autoconf out of the kernel.  However we'll always need to check
> for IPv6 address life time expiration.   This use case doesn't justify
> a specific global data structure. 
> 
> So let's iterate over the global list of interfaces instead.  This also
> prepare the work to split the NET_LOCK().  Since the ioctl(2) are
> per-ifp it makes sense to serialize write operations on a per interface
> basis.
> 
> ok?

OK bluhm@

> 
> Index: netinet6/nd6.c
> ===
> RCS file: /cvs/src/sys/netinet6/nd6.c,v
> retrieving revision 1.203
> diff -u -p -r1.203 nd6.c
> --- netinet6/nd6.c9 Feb 2017 15:23:35 -   1.203
> +++ netinet6/nd6.c1 Mar 2017 11:30:52 -
> @@ -435,7 +435,7 @@ nd6_timer_work(void *null)
>  {
>   struct nd_defrouter *dr, *ndr;
>   struct nd_prefix *pr, *npr;
> - struct in6_ifaddr *ia6, *nia6;
> + struct ifnet *ifp;
>   int s;
>  
>   NET_LOCK(s);
> @@ -453,18 +453,26 @@ nd6_timer_work(void *null)
>* However, from a stricter spec-conformance standpoint, we should
>* rather separate address lifetimes and prefix lifetimes.
>*/
> - TAILQ_FOREACH_SAFE(ia6, _ifaddr, ia_list, nia6) {
> - /* check address lifetime */
> - if (IFA6_IS_INVALID(ia6)) {
> - in6_purgeaddr(>ia_ifa);
> - } else if (IFA6_IS_DEPRECATED(ia6)) {
> - ia6->ia6_flags |= IN6_IFF_DEPRECATED;
> - } else {
> - /*
> -  * A new RA might have made a deprecated address
> -  * preferred.
> -  */
> - ia6->ia6_flags &= ~IN6_IFF_DEPRECATED;
> + TAILQ_FOREACH(ifp, , if_list) {
> + struct ifaddr *ifa, *nifa;
> + struct in6_ifaddr *ia6;
> +
> + TAILQ_FOREACH_SAFE(ifa, >if_addrlist, ifa_list, nifa) {
> + if (ifa->ifa_addr->sa_family != AF_INET6)
> + continue;
> + ia6 = ifatoia6(ifa);
> + /* check address lifetime */
> + if (IFA6_IS_INVALID(ia6)) {
> + in6_purgeaddr(>ia_ifa);
> + } else if (IFA6_IS_DEPRECATED(ia6)) {
> + ia6->ia6_flags |= IN6_IFF_DEPRECATED;
> + } else {
> + /*
> +  * A new RA might have made a deprecated address
> +  * preferred.
> +  */
> + ia6->ia6_flags &= ~IN6_IFF_DEPRECATED;
> + }
>   }
>   }
>  



nd6_timer & global list of IPv6 addresses

2017-03-01 Thread Martin Pieuchot
The work done in this timer should be considerably reduced when we'll
move autoconf out of the kernel.  However we'll always need to check
for IPv6 address life time expiration.   This use case doesn't justify
a specific global data structure. 

So let's iterate over the global list of interfaces instead.  This also
prepare the work to split the NET_LOCK().  Since the ioctl(2) are
per-ifp it makes sense to serialize write operations on a per interface
basis.

ok?

Index: netinet6/nd6.c
===
RCS file: /cvs/src/sys/netinet6/nd6.c,v
retrieving revision 1.203
diff -u -p -r1.203 nd6.c
--- netinet6/nd6.c  9 Feb 2017 15:23:35 -   1.203
+++ netinet6/nd6.c  1 Mar 2017 11:30:52 -
@@ -435,7 +435,7 @@ nd6_timer_work(void *null)
 {
struct nd_defrouter *dr, *ndr;
struct nd_prefix *pr, *npr;
-   struct in6_ifaddr *ia6, *nia6;
+   struct ifnet *ifp;
int s;
 
NET_LOCK(s);
@@ -453,18 +453,26 @@ nd6_timer_work(void *null)
 * However, from a stricter spec-conformance standpoint, we should
 * rather separate address lifetimes and prefix lifetimes.
 */
-   TAILQ_FOREACH_SAFE(ia6, _ifaddr, ia_list, nia6) {
-   /* check address lifetime */
-   if (IFA6_IS_INVALID(ia6)) {
-   in6_purgeaddr(>ia_ifa);
-   } else if (IFA6_IS_DEPRECATED(ia6)) {
-   ia6->ia6_flags |= IN6_IFF_DEPRECATED;
-   } else {
-   /*
-* A new RA might have made a deprecated address
-* preferred.
-*/
-   ia6->ia6_flags &= ~IN6_IFF_DEPRECATED;
+   TAILQ_FOREACH(ifp, , if_list) {
+   struct ifaddr *ifa, *nifa;
+   struct in6_ifaddr *ia6;
+
+   TAILQ_FOREACH_SAFE(ifa, >if_addrlist, ifa_list, nifa) {
+   if (ifa->ifa_addr->sa_family != AF_INET6)
+   continue;
+   ia6 = ifatoia6(ifa);
+   /* check address lifetime */
+   if (IFA6_IS_INVALID(ia6)) {
+   in6_purgeaddr(>ia_ifa);
+   } else if (IFA6_IS_DEPRECATED(ia6)) {
+   ia6->ia6_flags |= IN6_IFF_DEPRECATED;
+   } else {
+   /*
+* A new RA might have made a deprecated address
+* preferred.
+*/
+   ia6->ia6_flags &= ~IN6_IFF_DEPRECATED;
+   }
}
}