IPv6: set ifdisabled in the kernel rather than in rc

Enable ND6_IFF_IFDISABLED when the interface is created in the
kernel before return to user space.

This avoids a race when an interface is create by a program which
also calls ifconfig IF inet6 -ifdisabled and races with the
devd -> /etc/pccard_ether -> .. netif start IF -> ifdisabled
calls (the devd/rc framework disabling IPv6 again after the program
had enabled it already).

In case the global net.inet6.ip6.accept_rtadv was turned on,
we also default to enabling IPv6 on the interfaces, rather than
disabling them.

PR:		248172
Reported by:	Gert Doering (gert greenie.muc.de)
Reviewed by:	glebius (, phk)
MFC after:	2 weeks
Differential Revision:	https://reviews.freebsd.org/D27324
This commit is contained in:
bz 2020-11-25 20:58:01 +00:00
parent 26290e6312
commit 43e7814da7
2 changed files with 8 additions and 3 deletions

View File

@ -134,8 +134,6 @@ ifconfig_up()
if ! noafif $1 && afexists inet6; then
if checkyesno ipv6_activate_all_interfaces; then
_ipv6_opts="-ifdisabled"
elif [ "$1" != "lo0" ]; then
_ipv6_opts="ifdisabled"
fi
# backward compatibility: $ipv6_enable

View File

@ -273,6 +273,10 @@ nd6_ifattach(struct ifnet *ifp)
nd->flags = ND6_IFF_PERFORMNUD;
/* Set IPv6 disabled on all interfaces but loopback by default. */
if ((ifp->if_flags & IFF_LOOPBACK) == 0)
nd->flags |= ND6_IFF_IFDISABLED;
/* A loopback interface always has ND6_IFF_AUTO_LINKLOCAL.
* XXXHRS: Clear ND6_IFF_AUTO_LINKLOCAL on an IFT_BRIDGE interface by
* default regardless of the V_ip6_auto_linklocal configuration to
@ -290,8 +294,11 @@ nd6_ifattach(struct ifnet *ifp)
*/
if (V_ip6_accept_rtadv &&
!(ifp->if_flags & IFF_LOOPBACK) &&
(ifp->if_type != IFT_BRIDGE))
(ifp->if_type != IFT_BRIDGE)) {
nd->flags |= ND6_IFF_ACCEPT_RTADV;
/* If we globally accept rtadv, assume IPv6 on. */
nd->flags &= ~ND6_IFF_IFDISABLED;
}
if (V_ip6_no_radr && !(ifp->if_flags & IFF_LOOPBACK))
nd->flags |= ND6_IFF_NO_RADR;