Module Name:    src
Committed By:   roy
Date:           Thu Jun  5 16:06:49 UTC 2014

Modified Files:
        src/sys/netinet6: in6.h in6_ifattach.c ip6_input.c nd6.c nd6.h
        src/usr.sbin/ndp: ndp.8 ndp.c

Log Message:
Add IPV6CTL_AUTO_LINKLOCAL and ND6_IFF_AUTO_LINKLOCAL toggles which
control the automatic creation of IPv6 link-local addresses when an
interface is brought up.

Taken from FreeBSD.


To generate a diff of this commit:
cvs rdiff -u -r1.76 -r1.77 src/sys/netinet6/in6.h
cvs rdiff -u -r1.90 -r1.91 src/sys/netinet6/in6_ifattach.c
cvs rdiff -u -r1.146 -r1.147 src/sys/netinet6/ip6_input.c
cvs rdiff -u -r1.150 -r1.151 src/sys/netinet6/nd6.c
cvs rdiff -u -r1.58 -r1.59 src/sys/netinet6/nd6.h
cvs rdiff -u -r1.26 -r1.27 src/usr.sbin/ndp/ndp.8
cvs rdiff -u -r1.42 -r1.43 src/usr.sbin/ndp/ndp.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/netinet6/in6.h
diff -u src/sys/netinet6/in6.h:1.76 src/sys/netinet6/in6.h:1.77
--- src/sys/netinet6/in6.h:1.76	Fri May 30 01:39:03 2014
+++ src/sys/netinet6/in6.h	Thu Jun  5 16:06:49 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: in6.h,v 1.76 2014/05/30 01:39:03 christos Exp $	*/
+/*	$NetBSD: in6.h,v 1.77 2014/06/05 16:06:49 roy Exp $	*/
 /*	$KAME: in6.h,v 1.83 2001/03/29 02:55:07 jinmei Exp $	*/
 
 /*
@@ -571,7 +571,9 @@ struct ip6_mtuinfo {
 #define IPV6CTL_ANONPORTMAX	29	/* maximum ephemeral port */
 #define IPV6CTL_LOWPORTMIN	30	/* minimum reserved port */
 #define IPV6CTL_LOWPORTMAX	31	/* maximum reserved port */
-/* 32 to 38: reserved */
+/* 32 to 34: reserved */
+#define IPV6CTL_AUTO_LINKLOCAL	35	/* automatic link-local addr assign */
+/* 36 to 38: reserved */
 #define IPV6CTL_USE_DEFAULTZONE	39	/* use default scope zone */
 /* 40: reserved */
 #define IPV6CTL_MAXFRAGS	41	/* max fragments */

Index: src/sys/netinet6/in6_ifattach.c
diff -u src/sys/netinet6/in6_ifattach.c:1.90 src/sys/netinet6/in6_ifattach.c:1.91
--- src/sys/netinet6/in6_ifattach.c:1.90	Sat May 17 20:44:24 2014
+++ src/sys/netinet6/in6_ifattach.c	Thu Jun  5 16:06:49 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: in6_ifattach.c,v 1.90 2014/05/17 20:44:24 rmind Exp $	*/
+/*	$NetBSD: in6_ifattach.c,v 1.91 2014/06/05 16:06:49 roy Exp $	*/
 /*	$KAME: in6_ifattach.c,v 1.124 2001/07/18 08:32:51 jinmei Exp $	*/
 
 /*
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in6_ifattach.c,v 1.90 2014/05/17 20:44:24 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in6_ifattach.c,v 1.91 2014/06/05 16:06:49 roy Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -754,6 +754,8 @@ in6_ifattach(struct ifnet *ifp, struct i
 #ifdef IFT_PFSYNC
 	case IFT_PFSYNC:
 #endif
+		ND_IFINFO(ifp)->flags &= ~ND6_IFF_AUTO_LINKLOCAL;
+		ND_IFINFO(ifp)->flags |= ND6_IFF_IFDISABLED;
 		return;
 	}
 
@@ -784,6 +786,7 @@ in6_ifattach(struct ifnet *ifp, struct i
 		 * linklocals for 6to4 interface, but there's no use and
 		 * it is rather harmful to have one.
 		 */
+		ND_IFINFO(ifp)->flags &= ~ND6_IFF_AUTO_LINKLOCAL;
 		return;
 #endif
 	case IFT_CARP:
@@ -817,7 +820,9 @@ in6_ifattach(struct ifnet *ifp, struct i
 	/*
 	 * assign a link-local address, if there's none.
 	 */
-	if (ip6_auto_linklocal) {
+	if (!(ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) &&
+	    ND_IFINFO(ifp)->flags & ND6_IFF_AUTO_LINKLOCAL)
+	{
 		ia = in6ifa_ifpforlinklocal(ifp, 0);
 		if (ia == NULL && in6_ifattach_linklocal(ifp, altifp) != 0) {
 			printf("%s: cannot assign link-local address\n",

Index: src/sys/netinet6/ip6_input.c
diff -u src/sys/netinet6/ip6_input.c:1.146 src/sys/netinet6/ip6_input.c:1.147
--- src/sys/netinet6/ip6_input.c:1.146	Fri May 30 01:39:03 2014
+++ src/sys/netinet6/ip6_input.c	Thu Jun  5 16:06:49 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip6_input.c,v 1.146 2014/05/30 01:39:03 christos Exp $	*/
+/*	$NetBSD: ip6_input.c,v 1.147 2014/06/05 16:06:49 roy Exp $	*/
 /*	$KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $	*/
 
 /*
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.146 2014/05/30 01:39:03 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.147 2014/06/05 16:06:49 roy Exp $");
 
 #include "opt_gateway.h"
 #include "opt_inet.h"
@@ -1854,6 +1854,15 @@ sysctl_net_inet6_ip6_setup(struct sysctl
 		       IPV6CTL_V6ONLY, CTL_EOL);
 	sysctl_createv(clog, 0, NULL, NULL,
 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+		       CTLTYPE_INT, "auto_linklocal",
+		       SYSCTL_DESCR("Default value of per-interface flag for "
+		                    "adding an IPv6 link-local address to "
+				    "interfaces when attached"),
+		       NULL, 0, &ip6_auto_linklocal, 0,
+		       CTL_NET, PF_INET6, IPPROTO_IPV6,
+		       IPV6CTL_AUTO_LINKLOCAL, CTL_EOL);
+	sysctl_createv(clog, 0, NULL, NULL,
+		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 		       CTLTYPE_INT, "anonportmin",
 		       SYSCTL_DESCR("Lowest ephemeral port number to assign"),
 		       sysctl_net_inet_ip_ports, 0, &ip6_anonportmin, 0,

Index: src/sys/netinet6/nd6.c
diff -u src/sys/netinet6/nd6.c:1.150 src/sys/netinet6/nd6.c:1.151
--- src/sys/netinet6/nd6.c:1.150	Tue May 20 20:23:56 2014
+++ src/sys/netinet6/nd6.c	Thu Jun  5 16:06:49 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: nd6.c,v 1.150 2014/05/20 20:23:56 bouyer Exp $	*/
+/*	$NetBSD: nd6.c,v 1.151 2014/06/05 16:06:49 roy Exp $	*/
 /*	$KAME: nd6.c,v 1.279 2002/06/08 11:16:51 itojun Exp $	*/
 
 /*
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.150 2014/05/20 20:23:56 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.151 2014/06/05 16:06:49 roy Exp $");
 
 #include "opt_ipsec.h"
 
@@ -66,6 +66,7 @@ __KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.15
 #include <netinet6/ip6_var.h>
 #include <netinet6/scope6_var.h>
 #include <netinet6/nd6.h>
+#include <netinet6/in6_ifattach.h>
 #include <netinet/icmp6.h>
 #include <netinet6/icmp6_private.h>
 
@@ -177,13 +178,24 @@ nd6_ifattach(struct ifnet *ifp)
 	nd->basereachable = REACHABLE_TIME;
 	nd->reachable = ND_COMPUTE_RTIME(nd->basereachable);
 	nd->retrans = RETRANS_TIMER;
-	/*
-	 * Note that the default value of ip6_accept_rtadv is 0.
-	 * Because we do not set ND6_IFF_OVERRIDE_RTADV here, we won't
-	 * accept RAs by default.
-	 */
+
 	nd->flags = ND6_IFF_PERFORMNUD | ND6_IFF_ACCEPT_RTADV;
 
+	/* A loopback interface always has ND6_IFF_AUTO_LINKLOCAL.
+	 * A bridge interface should not have ND6_IFF_AUTO_LINKLOCAL
+	 * because one of it's members should. */
+	if ((ip6_auto_linklocal && ifp->if_type != IFT_BRIDGE) ||
+	    (ifp->if_flags & IFF_LOOPBACK))
+		nd->flags |= ND6_IFF_AUTO_LINKLOCAL;
+
+	/* A loopback interface does not need to accept RTADV.
+	 * A bridge interface should not accept RTADV
+	 * because one of it's members should. */
+	if (ip6_accept_rtadv &&
+	    !(ifp->if_flags & IFF_LOOPBACK) &&
+	    !(ifp->if_type != IFT_BRIDGE))
+		nd->flags |= ND6_IFF_ACCEPT_RTADV;
+
 	/* XXX: we cannot call nd6_setmtu since ifp is not fully initialized */
 	nd6_setmtu0(ifp, nd);
 
@@ -1698,8 +1710,38 @@ nd6_ioctl(u_long cmd, void *data, struct
 				ia->ia6_flags |= IN6_IFF_TENTATIVE;
 			}
 		}
-	}
 
+		if (ND.flags & ND6_IFF_AUTO_LINKLOCAL) {
+			if (!(ND_IFINFO(ifp)->flags & ND6_IFF_AUTO_LINKLOCAL)) {
+				/* auto_linklocal 0->1 transition */
+
+				ND_IFINFO(ifp)->flags |= ND6_IFF_AUTO_LINKLOCAL;
+				in6_ifattach(ifp, NULL);
+			} else if (!(ND.flags & ND6_IFF_IFDISABLED) &&
+			    ifp->if_flags & IFF_UP)
+			{
+				/*
+				 * When the IF already has
+				 * ND6_IFF_AUTO_LINKLOCAL, no link-local
+				 * address is assigned, and IFF_UP, try to
+				 * assign one.
+				 */
+				 int haslinklocal = 0;
+
+				 IFADDR_FOREACH(ifa, ifp) {
+					if (ifa->ifa_addr->sa_family !=AF_INET6)
+						continue;
+					ia = (struct in6_ifaddr *)ifa;
+					if (IN6_IS_ADDR_LINKLOCAL(IA6_IN6(ia))){
+						haslinklocal = 1;
+						break;
+					}
+				 }
+				 if (!haslinklocal)
+					in6_ifattach(ifp, NULL);
+			}
+		}
+	}
 		ND_IFINFO(ifp)->flags = ND.flags;
 		break;
 #undef ND

Index: src/sys/netinet6/nd6.h
diff -u src/sys/netinet6/nd6.h:1.58 src/sys/netinet6/nd6.h:1.59
--- src/sys/netinet6/nd6.h:1.58	Tue May 21 08:37:27 2013
+++ src/sys/netinet6/nd6.h	Thu Jun  5 16:06:49 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: nd6.h,v 1.58 2013/05/21 08:37:27 roy Exp $	*/
+/*	$NetBSD: nd6.h,v 1.59 2014/06/05 16:06:49 roy Exp $	*/
 /*	$KAME: nd6.h,v 1.95 2002/06/08 11:31:06 itojun Exp $	*/
 
 /*
@@ -93,6 +93,7 @@ struct nd_ifinfo {
 					 * DAD failure.  (XXX: not ND-specific)
 					 */
 #define	ND6_IFF_OVERRIDE_RTADV	0x10	/* See "RTADV Key", below. */
+#define	ND6_IFF_AUTO_LINKLOCAL	0x20
 
 /*
  * RTADV Key

Index: src/usr.sbin/ndp/ndp.8
diff -u src/usr.sbin/ndp/ndp.8:1.26 src/usr.sbin/ndp/ndp.8:1.27
--- src/usr.sbin/ndp/ndp.8:1.26	Thu Mar 20 13:34:35 2014
+++ src/usr.sbin/ndp/ndp.8	Thu Jun  5 16:06:49 2014
@@ -1,4 +1,4 @@
-.\"	$NetBSD: ndp.8,v 1.26 2014/03/20 13:34:35 roy Exp $
+.\"	$NetBSD: ndp.8,v 1.27 2014/06/05 16:06:49 roy Exp $
 .\"	$KAME: ndp.8,v 1.33 2005/10/19 14:57:42 suz Exp $
 .\"
 .\" Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -28,7 +28,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.Dd March 20, 2014
+.Dd June 5, 2014
 .Dt NDP 8
 .Os
 .\"
@@ -189,6 +189,12 @@ variable is non-0, or the flag
 .Ic override_rtadv
 is on.
 This flag is set to 1 by default.
+.It Ic auto_linklocal
+Specify whether or not to perform automatic link-local address configuration on
+.Ar interface .
+This flag is set by
+.Li net.inet6.ip6.auto_linklocal
+sysctl variable.
 .It Ic override_rtadv
 Specify whether or not to override the
 .Li net.inet6.ip6.accept_rtadv

Index: src/usr.sbin/ndp/ndp.c
diff -u src/usr.sbin/ndp/ndp.c:1.42 src/usr.sbin/ndp/ndp.c:1.43
--- src/usr.sbin/ndp/ndp.c:1.42	Tue Dec 17 20:26:46 2013
+++ src/usr.sbin/ndp/ndp.c	Thu Jun  5 16:06:49 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: ndp.c,v 1.42 2013/12/17 20:26:46 martin Exp $	*/
+/*	$NetBSD: ndp.c,v 1.43 2014/06/05 16:06:49 roy Exp $	*/
 /*	$KAME: ndp.c,v 1.121 2005/07/13 11:30:13 keiichi Exp $	*/
 
 /*
@@ -918,6 +918,9 @@ ifinfo(char *ifname, int argc, char **ar
 #ifdef ND6_IFF_OVERRIDE_RTADV
 		SETFLAG("override_rtadv", ND6_IFF_OVERRIDE_RTADV);
 #endif
+#ifdef ND6_IFF_AUTO_LINKLOCAL
+		SETFLAG("auto_linklocal", ND6_IFF_AUTO_LINKLOCAL);
+#endif
 #ifdef ND6_IFF_PREFER_SOURCE
 		SETFLAG("prefer_source", ND6_IFF_PREFER_SOURCE);
 #endif
@@ -996,6 +999,10 @@ ifinfo(char *ifname, int argc, char **ar
 		if ((ND.flags & ND6_IFF_OVERRIDE_RTADV))
 			(void)printf("override_rtadv ");
 #endif
+#ifdef ND6_IFF_AUTO_LINKLOCAL
+		if ((ND.flags & ND6_IFF_AUTO_LINKLOCAL))
+			(void)printf("auto_linklocal ");
+#endif
 #ifdef ND6_IFF_PREFER_SOURCE
 		if ((ND.flags & ND6_IFF_PREFER_SOURCE))
 			(void)printf("prefer_source ");

Reply via email to