svn commit: r499754 - in head/net/wireguard-go: . files
Bernhard Froehlich
decke at FreeBSD.org
Tue Apr 23 12:33:46 UTC 2019
Author: decke
Date: Tue Apr 23 12:33:44 2019
New Revision: 499754
URL: https://svnweb.freebsd.org/changeset/ports/499754
Log:
net/wireguard:
work around numerous kernel panics on shutdown in tun(4)
There are numerous race conditions. But even this will crash it:
while true; do ifconfig tun0 create; ifconfig tun0 destroy; done
It seems like LLv6 is related, which we're not using anyway, so
explicitly disable it on the interface.
PR: 233955
Added:
head/net/wireguard-go/files/
head/net/wireguard-go/files/patch-bb42ec7d185ab5f5cd3867ac1258edff86b7f307 (contents, props changed)
Modified:
head/net/wireguard-go/Makefile
Modified: head/net/wireguard-go/Makefile
==============================================================================
--- head/net/wireguard-go/Makefile Tue Apr 23 12:18:10 2019 (r499753)
+++ head/net/wireguard-go/Makefile Tue Apr 23 12:33:44 2019 (r499754)
@@ -2,6 +2,7 @@
PORTNAME= wireguard-go
PORTVERSION= 0.0.20190409
+PORTREVISION= 1
CATEGORIES= net
MASTER_SITES= https://git.zx2c4.com/wireguard-go/snapshot/
DISTFILES= ${PORTNAME}-${PORTVERSION}${EXTRACT_SUFX}
Added: head/net/wireguard-go/files/patch-bb42ec7d185ab5f5cd3867ac1258edff86b7f307
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ head/net/wireguard-go/files/patch-bb42ec7d185ab5f5cd3867ac1258edff86b7f307 Tue Apr 23 12:33:44 2019 (r499754)
@@ -0,0 +1,204 @@
+From bb42ec7d185ab5f5cd3867ac1258edff86b7f307 Mon Sep 17 00:00:00 2001
+From: "Jason A. Donenfeld" <Jason at zx2c4.com>
+Date: Sat, 20 Apr 2019 11:29:07 +0900
+Subject: tun: freebsd: work around numerous kernel panics on shutdown
+
+There are numerous race conditions. But even this will crash it:
+
+while true; do ifconfig tun0 create; ifconfig tun0 destroy; done
+
+It seems like LLv6 is related, which we're not using anyway, so
+explicitly disable it on the interface.
+---
+ tun/tun_freebsd.go | 105 +++++++++++++++++++++++++++++++++++++++++------------
+ 1 file changed, 82 insertions(+), 23 deletions(-)
+
+diff --git a/tun/tun_freebsd.go b/tun/tun_freebsd.go
+index 01a4348..c9c89ef 100644
+--- tun/tun_freebsd.go
++++ tun/tun_freebsd.go
+@@ -19,9 +19,19 @@ import (
+
+ // _TUNSIFHEAD, value derived from sys/net/{if_tun,ioccom}.h
+ // const _TUNSIFHEAD = ((0x80000000) | (((4) & ((1 << 13) - 1) ) << 16) | (uint32(byte('t')) << 8) | (96))
+-const _TUNSIFHEAD = 0x80047460
+-const _TUNSIFMODE = 0x8004745e
+-const _TUNSIFPID = 0x2000745f
++const (
++ _TUNSIFHEAD = 0x80047460
++ _TUNSIFMODE = 0x8004745e
++ _TUNSIFPID = 0x2000745f
++)
++
++//TODO: move into x/sys/unix
++const (
++ SIOCGIFINFO_IN6 = 0xc048696c
++ SIOCSIFINFO_IN6 = 0xc048696d
++ ND6_IFF_AUTO_LINKLOCAL = 0x20
++ ND6_IFF_NO_DAD = 0x100
++)
+
+ // Iface status string max len
+ const _IFSTATMAX = 800
+@@ -32,7 +42,7 @@ const SIZEOF_UINTPTR = 4 << (^uintptr(0) >> 32 & 1)
+ type ifreq_ptr struct {
+ Name [unix.IFNAMSIZ]byte
+ Data uintptr
+- Pad0 [24 - SIZEOF_UINTPTR]byte
++ Pad0 [16 - SIZEOF_UINTPTR]byte
+ }
+
+ // Structure for iface mtu get/set ioctls
+@@ -48,6 +58,23 @@ type ifstat struct {
+ Ascii [_IFSTATMAX]byte
+ }
+
++// Structures for nd6 flag manipulation
++type in6_ndireq struct {
++ Name [unix.IFNAMSIZ]byte
++ Linkmtu uint32
++ Maxmtu uint32
++ Basereachable uint32
++ Reachable uint32
++ Retrans uint32
++ Flags uint32
++ Recalctm int
++ Chlim uint8
++ Initialized uint8
++ Randomseed0 [8]byte
++ Randomseed1 [8]byte
++ Randomid [8]byte
++}
++
+ type NativeTun struct {
+ name string
+ tunFile *os.File
+@@ -191,23 +218,18 @@ func tunName(fd uintptr) (string, error) {
+
+ // Destroy a named system interface
+ func tunDestroy(name string) error {
+- // open control socket
++ // Open control socket.
+ var fd int
+-
+ fd, err := unix.Socket(
+ unix.AF_INET,
+ unix.SOCK_DGRAM,
+ 0,
+ )
+-
+ if err != nil {
+ return err
+ }
+-
+ defer unix.Close(fd)
+
+- // do ioctl call
+-
+ var ifr [32]byte
+ copy(ifr[:], name)
+ _, _, errno := unix.Syscall(
+@@ -216,7 +238,6 @@ func tunDestroy(name string) error {
+ uintptr(unix.SIOCIFDESTROY),
+ uintptr(unsafe.Pointer(&ifr[0])),
+ )
+-
+ if errno != 0 {
+ return fmt.Errorf("failed to destroy interface %s: %s", name, errno.Error())
+ }
+@@ -263,33 +284,71 @@ func CreateTUN(name string, mtu int) (TUNDevice, error) {
+ })
+
+ if errno != 0 {
+- return nil, fmt.Errorf("error %s", errno.Error())
++ tunFile.Close()
++ tunDestroy(assignedName)
++ return nil, fmt.Errorf("Unable to put into IFHEAD mode: %v", errno)
+ }
+
+- // Rename tun interface
+-
+- // Open control socket
++ // Open control sockets
+ confd, err := unix.Socket(
+ unix.AF_INET,
+ unix.SOCK_DGRAM,
+ 0,
+ )
+-
+ if err != nil {
++ tunFile.Close()
++ tunDestroy(assignedName)
+ return nil, err
+ }
+-
+ defer unix.Close(confd)
++ confd6, err := unix.Socket(
++ unix.AF_INET6,
++ unix.SOCK_DGRAM,
++ 0,
++ )
++ if err != nil {
++ tunFile.Close()
++ tunDestroy(assignedName)
++ return nil, err
++ }
++ defer unix.Close(confd6)
+
+- // set up struct for iface rename
++ // Disable link-local v6, not just because WireGuard doesn't do that anyway, but
++ // also because there are serious races with attaching and detaching LLv6 addresses
++ // in relation to interface lifetime within the FreeBSD kernel.
++ var ndireq in6_ndireq
++ copy(ndireq.Name[:], assignedName)
++ _, _, errno = unix.Syscall(
++ unix.SYS_IOCTL,
++ uintptr(confd6),
++ uintptr(SIOCGIFINFO_IN6),
++ uintptr(unsafe.Pointer(&ndireq)),
++ )
++ if errno != 0 {
++ tunFile.Close()
++ tunDestroy(assignedName)
++ return nil, fmt.Errorf("Unable to get nd6 flags for %s: %v", assignedName, errno)
++ }
++ ndireq.Flags = ndireq.Flags &^ ND6_IFF_AUTO_LINKLOCAL
++ ndireq.Flags = ndireq.Flags | ND6_IFF_NO_DAD
++ _, _, errno = unix.Syscall(
++ unix.SYS_IOCTL,
++ uintptr(confd6),
++ uintptr(SIOCSIFINFO_IN6),
++ uintptr(unsafe.Pointer(&ndireq)),
++ )
++ if errno != 0 {
++ tunFile.Close()
++ tunDestroy(assignedName)
++ return nil, fmt.Errorf("Unable to set nd6 flags for %s: %v", assignedName, errno)
++ }
++
++ // Rename the interface
+ var newnp [unix.IFNAMSIZ]byte
+ copy(newnp[:], name)
+-
+ var ifr ifreq_ptr
+ copy(ifr.Name[:], assignedName)
+ ifr.Data = uintptr(unsafe.Pointer(&newnp[0]))
+-
+- //do actual ioctl to rename iface
+ _, _, errno = unix.Syscall(
+ unix.SYS_IOCTL,
+ uintptr(confd),
+@@ -298,8 +357,8 @@ func CreateTUN(name string, mtu int) (TUNDevice, error) {
+ )
+ if errno != 0 {
+ tunFile.Close()
+- tunDestroy(name)
+- return nil, fmt.Errorf("failed to rename %s to %s: %s", assignedName, name, errno.Error())
++ tunDestroy(assignedName)
++ return nil, fmt.Errorf("Failed to rename %s to %s: %v", assignedName, name, errno)
+ }
+
+ return CreateTUNFromFile(tunFile, mtu)
+--
+cgit v1.2.1-20-gc37e
+
More information about the svn-ports-all
mailing list