On FreeBSD 12 (tested and verified on 12.1-RELEASE-p2), after "ifconfig
inet6" for a tun/tap interface, there sometimes is a race condition
where the "IFDISABLED" flag shows up after a short time frame, under
a second, and never clears itself. This disables use of the configured
IPv6 address on the interface, breaking IPv6 over tun/tap operation.
This only happens if ipv6_activate_all_interfaces="YES" is not
set in /etc/rc.conf - but there might be reasons why this is not so.
As a workaround until this can be fixed on the FreeBSD side (or a
better workaround is found), sleep(1) after ifconfig, then call
"ifconfig $dev inet6 -ifdisable".
Yes, this is massively ugly but makes the problem completely go
away for my test systems.
(The same effect can be achieved with an --up script that does this,
but it's even less pretty - see trac ticket)
FreeBSD: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=248172
v2: reword text, refer to FreeBSD bug with much more details
Trac: 1226
Signed-off-by: Gert Doering <gert@greenie.muc.de>
Acked-by: Arne Schwabe <arne@rfc2549.org>
Message-Id: <20200723121949.78223-1-gert@greenie.muc.de>
URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg20553.html
Signed-off-by: Gert Doering <gert@greenie.muc.de>
(cherry picked from commit 5e19cc2c1bf22d44f10dc585ba69d48951dc7a86)
| ... | ... |
@@ -1038,6 +1038,29 @@ do_ifconfig_ipv6(struct tuntap *tt, const char *ifname, int tun_mtu, |
| 1038 | 1038 |
openvpn_execve_check(&argv, es, S_FATAL, |
| 1039 | 1039 |
"generic BSD ifconfig inet6 failed"); |
| 1040 | 1040 |
|
| 1041 |
+#if defined(TARGET_FREEBSD) && __FreeBSD_version >= 1200000 |
|
| 1042 |
+ /* On FreeBSD 12 and up, there is ipv6_activate_all_interfaces="YES" |
|
| 1043 |
+ * in rc.conf, which is not set by default. If it is *not* set, |
|
| 1044 |
+ * "all new interfaces that are not already up" are configured by |
|
| 1045 |
+ * devd + /etc/pccard_ether as "inet6 ifdisabled". |
|
| 1046 |
+ * |
|
| 1047 |
+ * The "is this interface already up?" test is a non-zero time window |
|
| 1048 |
+ * which we manage to hit with our ifconfig often enough to cause |
|
| 1049 |
+ * frequent fails in the openvpn test environment. |
|
| 1050 |
+ * |
|
| 1051 |
+ * Thus: assume that the system might interfere, wait for things to |
|
| 1052 |
+ * settle (it's a very short time window), and remove -ifdisable again. |
|
| 1053 |
+ * |
|
| 1054 |
+ * See: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=248172 |
|
| 1055 |
+ */ |
|
| 1056 |
+ sleep(1); |
|
| 1057 |
+ argv_printf(&argv, "%s %s inet6 -ifdisabled", IFCONFIG_PATH, ifname); |
|
| 1058 |
+ argv_msg(M_INFO, &argv); |
|
| 1059 |
+ |
|
| 1060 |
+ openvpn_execve_check(&argv, es, S_FATAL, |
|
| 1061 |
+ "FreeBSD BSD 'ifconfig inet6 -ifdisabled' failed"); |
|
| 1062 |
+#endif |
|
| 1063 |
+ |
|
| 1041 | 1064 |
#if defined(TARGET_OPENBSD) || defined(TARGET_NETBSD) \ |
| 1042 | 1065 |
|| defined(TARGET_DARWIN) |
| 1043 | 1066 |
/* and, hooray, we explicitly need to add a route... */ |