aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet6/nd6.c
diff options
context:
space:
mode:
authorHiroki Sato <hrs@FreeBSD.org>2011-06-06 02:37:38 +0000
committerHiroki Sato <hrs@FreeBSD.org>2011-06-06 02:37:38 +0000
commit77bc49858c4ac962f77f7fd2b991f8c286841d2a (patch)
tree3a91fc09001b4b8c1e39d012abbbcdb449105f43 /sys/netinet6/nd6.c
parente7fa8d0ada7547ca92a905aa9f683ea66c750c88 (diff)
downloadsrc-77bc49858c4ac962f77f7fd2b991f8c286841d2a.tar.gz
src-77bc49858c4ac962f77f7fd2b991f8c286841d2a.zip
- 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 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). Reviewed by: bz
Notes
Notes: svn path=/head/; revision=222730
Diffstat (limited to 'sys/netinet6/nd6.c')
-rw-r--r--sys/netinet6/nd6.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c
index b17b5dad1c03..231ce94ecbe3 100644
--- a/sys/netinet6/nd6.c
+++ b/sys/netinet6/nd6.c
@@ -1322,6 +1322,15 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
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,27 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
/* 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(IA6_IN6(ia))) {
+ haslinklocal = 1;
+ break;
+ }
+ }
+ IF_ADDR_UNLOCK(ifp);
+ if (!haslinklocal)
+ in6_ifattach(ifp, NULL);
}
}
ND_IFINFO(ifp)->flags = ND.flags;