Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 1 Jun 2011 14:12:35 +0000 (UTC)
From:      Hiroki Sato <hrs@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r222563 - user/hrs/ipv6/sys/netinet6
Message-ID:  <201106011412.p51ECZFV073230@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: hrs
Date: Wed Jun  1 14:12:35 2011
New Revision: 222563
URL: http://svn.freebsd.org/changeset/base/222563

Log:
  - Make the code more proactively clear an ND6_IFF_IFDISABLED flag when
    an explicit action for INET6 configuration happens.  The changes are:
  
    1. When an ND6 flag is changed via SIOCSIFINFO_FLAGS ioctl,
       setting ND6_IFF_ACCEPT_RTADV and/or ND6_IFF_AUTO_LINKLOCAL now triggers
       an attempt to clear the ND6_IFF_IFDISABLED flag.
  
    2. When an AF_INET6 address is added successfully to an interface and
       it is marked as ND6_IFF_IFDISABLED, an attempt to clear the
       ND6_IFF_IFDISABLED happens.
  
    This simplifies ND6_IFF_IFDISABLED flag manipulation by users via ifconfig(8);
    in most cases the manual configuration is no longer needed.
  
  - When ND6_IFF_AUTO_LINKLOCAL is set and no link-local address is assigned to
    an interface, SIOCSIFINFO_FLAGS ioctl now calls in6_ifattach() to configure
    a link-local address.
  
    This change ensures link-local address configuration when "ifconfig IF inet6"
    command is invoked.  For example, "ifconfig IF inet6 auto_linklocal" now
    always try to configure an LL addr even if ND6_IFF_AUTO_LINKLOCAL is already
    set to 1 (i.e. down/up cycle is no longer needed).

Modified:
  user/hrs/ipv6/sys/netinet6/in6.c
  user/hrs/ipv6/sys/netinet6/nd6.c

Modified: user/hrs/ipv6/sys/netinet6/in6.c
==============================================================================
--- user/hrs/ipv6/sys/netinet6/in6.c	Wed Jun  1 14:02:25 2011	(r222562)
+++ user/hrs/ipv6/sys/netinet6/in6.c	Wed Jun  1 14:12:35 2011	(r222563)
@@ -652,8 +652,33 @@ in6_control(struct socket *so, u_long cm
 		 * that is, this address might make other addresses detached.
 		 */
 		pfxlist_onlink_check();
-		if (error == 0 && ia)
+		if (error == 0 && ia) {
+			if (ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) {
+				/*
+				 * Try to clear the flag when a new
+				 * IPv6 address is added onto an
+				 * IFDISABLED interface and it
+				 * succeeds.
+				 */
+				struct in6_ndireq nd;
+
+				memset(&nd, 0, sizeof(nd));
+				nd.ndi.flags = ND_IFINFO(ifp)->flags;
+				nd.ndi.flags &= ~ND6_IFF_IFDISABLED;
+				if (nd6_ioctl(SIOCSIFINFO_FLAGS,
+					      (caddr_t)&nd, ifp) < 0)
+					log(LOG_NOTICE, "SIOCAIFADDR_IN6: "
+					    "SIOCSIFINFO_FLAGS for -ifdisabled "
+					    "failed.");
+				/*
+				 * Ignore failure of clearing the flag
+				 * intentionally.  The failure means
+				 * some serious problems like address
+				 * duplication were detected.
+				 */
+			}
 			EVENTHANDLER_INVOKE(ifaddr_event, ifp);
+		}
 		break;
 	}
 

Modified: user/hrs/ipv6/sys/netinet6/nd6.c
==============================================================================
--- user/hrs/ipv6/sys/netinet6/nd6.c	Wed Jun  1 14:02:25 2011	(r222562)
+++ user/hrs/ipv6/sys/netinet6/nd6.c	Wed Jun  1 14:12:35 2011	(r222563)
@@ -1322,6 +1322,15 @@ nd6_ioctl(u_long cmd, caddr_t data, stru
 		struct ifaddr *ifa;
 		struct in6_ifaddr *ia;
 
+		/*
+		 * Try to clear ifdisabled flag when enabling
+		 * accept_rtadv or auto_linklocal.
+		 */
+		if ((ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) &&
+		    (ND.flags & (ND6_IFF_ACCEPT_RTADV |
+				 ND6_IFF_AUTO_LINKLOCAL)))
+			ND.flags &= ~ND6_IFF_IFDISABLED;
+
 		if ((ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) &&
 		    !(ND.flags & ND6_IFF_IFDISABLED)) {
 			/* ifdisabled 1->0 transision */
@@ -1379,6 +1388,25 @@ nd6_ioctl(u_long cmd, caddr_t data, stru
 			/* If no link-local address on ifp, configure */
 			ND_IFINFO(ifp)->flags |= ND6_IFF_AUTO_LINKLOCAL;
 			in6_ifattach(ifp, NULL);
+		} else if (ND_IFINFO(ifp)->flags & ND6_IFF_AUTO_LINKLOCAL) {
+			/*
+			 * When the IF already has
+			 * ND6_IFF_AUTO_LINKLOCAL and no link-local
+			 * address is assigned, try to assign one.
+			 */
+			int haslinklocal = 0;
+			
+			IF_ADDR_LOCK(ifp);
+			TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
+				if (ifa->ifa_addr->sa_family != AF_INET6)
+					continue;
+				ia = (struct in6_ifaddr *)ifa;
+				if (IN6_IS_ADDR_LINKLOCAL(&(ia->ia_addr.sin6_addr)))
+					haslinklocal = 1;
+			}
+			IF_ADDR_UNLOCK(ifp);
+			if (!haslinklocal)
+				in6_ifattach(ifp, NULL);
 		}
 	}
 		ND_IFINFO(ifp)->flags = ND.flags;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201106011412.p51ECZFV073230>