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 ");