- 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
This commit is contained in:
parent
4c2206b625
commit
acbda2ccc1
@ -652,8 +652,32 @@ in6_control(struct socket *so, u_long cmd, caddr_t data,
|
||||
* 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
|
||||
* address duplication was detected.
|
||||
*/
|
||||
}
|
||||
EVENTHANDLER_INVOKE(ifaddr_event, ifp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user