net/wireguard: workaround SIOCGIFSTATUS race in FreeBSD kernel
PR: 233955
This commit is contained in:
parent
58993b6b59
commit
4ad662d0e4
Notes:
svn2git
2021-03-31 03:12:20 +00:00
svn path=/head/; revision=499755
@ -2,6 +2,7 @@
|
||||
|
||||
PORTNAME= wireguard
|
||||
PORTVERSION= 0.0.20190406
|
||||
PORTREVISION= 1
|
||||
CATEGORIES= net
|
||||
MASTER_SITES= https://git.zx2c4.com/WireGuard/snapshot/
|
||||
DISTNAME= WireGuard-${PORTVERSION}
|
||||
|
@ -0,0 +1,65 @@
|
||||
From b3e1a1b07d3631bd816f9bfc27452a89dc29fa28 Mon Sep 17 00:00:00 2001
|
||||
From: "Jason A. Donenfeld" <Jason@zx2c4.com>
|
||||
Date: Sun, 21 Apr 2019 10:11:36 +0900
|
||||
Subject: wg-quick: freebsd: workaround SIOCGIFSTATUS race in FreeBSD kernel
|
||||
|
||||
---
|
||||
src/tools/wg-quick/freebsd.bash | 31 ++++++++++++++++++++++---------
|
||||
1 file changed, 22 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/src/tools/wg-quick/freebsd.bash b/src/tools/wg-quick/freebsd.bash
|
||||
index 9d3a4026..72e0bd04 100755
|
||||
--- wg-quick/freebsd.bash
|
||||
+++ wg-quick/freebsd.bash
|
||||
@@ -137,18 +137,30 @@ del_routes() {
|
||||
done
|
||||
}
|
||||
|
||||
+if_exists() {
|
||||
+ # HACK: The goal is simply to determine whether or not the interface exists. The
|
||||
+ # straight-forward way of doing this would be `ifconfig $INTERFACE`, but this
|
||||
+ # invokes the SIOCGIFSTATUS ioctl, which races with interface shutdown inside
|
||||
+ # the tun driver, resulting in a kernel panic. So we work around it the stupid
|
||||
+ # way by using the one utility that appears to call if_nametoindex fairly early
|
||||
+ # and fails if it doesn't exist: `arp`.
|
||||
+ if arp -i "$INTERFACE" -a -n >/dev/null 2>&1; then
|
||||
+ return 0
|
||||
+ else
|
||||
+ return 1
|
||||
+ fi
|
||||
+}
|
||||
+
|
||||
del_if() {
|
||||
- local line monitor_pid
|
||||
[[ $HAVE_SET_DNS -eq 0 ]] || unset_dns
|
||||
- exec 39< <(exec route -n monitor 2>/dev/null)
|
||||
- monitor_pid=$!
|
||||
cmd rm -f "/var/run/wireguard/$INTERFACE.sock"
|
||||
- while ifconfig "$INTERFACE" >/dev/null 2>&1; do
|
||||
- while read -r line; do
|
||||
- [[ $line =~ ^RTM_IFANNOUNCE:.* ]] && break
|
||||
- done <&39
|
||||
+ while if_exists; do
|
||||
+ # HACK: it would be nice to `route monitor` here and wait for RTM_IFANNOUNCE
|
||||
+ # but it turns out that the announcement is made before the interface
|
||||
+ # disappears so we sometimes get a hang. So, we're instead left with polling
|
||||
+ # in a sleep loop like this.
|
||||
+ sleep 0.1
|
||||
done
|
||||
- kill $monitor_pid
|
||||
}
|
||||
|
||||
up_if() {
|
||||
@@ -274,7 +286,8 @@ monitor_daemon() {
|
||||
# endpoints change.
|
||||
while read -r event; do
|
||||
[[ $event == RTM_* ]] || continue
|
||||
- ifconfig "$INTERFACE" >/dev/null 2>&1 || break
|
||||
+ [[ -e /var/run/wireguard/$INTERFACE.sock ]] || break
|
||||
+ if_exists || break
|
||||
[[ $AUTO_ROUTE4 -eq 1 || $AUTO_ROUTE6 -eq 1 ]] && set_endpoint_direct_route
|
||||
# TODO: set the mtu as well, but only if up
|
||||
done < <(route -n monitor)) & disown
|
||||
--
|
||||
cgit v1.2.1-20-gc37e
|
||||
|
Loading…
Reference in New Issue
Block a user