From f77e84a6d13ca79532db71c295c229b34fdc60ce Mon Sep 17 00:00:00 2001 From: Luke Rindels Date: Tue, 26 Jul 2022 13:11:50 -0600 Subject: [PATCH 1/8] tun/netstack: expose stack and dispatcher Signed-off-by: Luke Rindels --- tun/netstack/tun.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tun/netstack/tun.go b/tun/netstack/tun.go index c26d8ed5e..ea378bdaa 100644 --- a/tun/netstack/tun.go +++ b/tun/netstack/tun.go @@ -207,6 +207,14 @@ func (tun *netTun) MTU() (int, error) { return tun.mtu, nil } +func (tun *netTun) Stack() *stack.Stack { + return tun.stack +} + +func (tun *netTun) Dispatcher() stack.NetworkDispatcher { + return tun.dispatcher +} + func convertToFullAddr(endpoint netip.AddrPort) (tcpip.FullAddress, tcpip.NetworkProtocolNumber) { var protoNumber tcpip.NetworkProtocolNumber if endpoint.Addr().Is4() { From 3ee0cc0ce57a97187cc2120a8259dbeaab65744a Mon Sep 17 00:00:00 2001 From: Luke Rindels Date: Tue, 26 Jul 2022 14:19:43 -0600 Subject: [PATCH 2/8] tun/netstack: expose stack and dispatcher Signed-off-by: Luke Rindels --- tun/netstack/tun.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tun/netstack/tun.go b/tun/netstack/tun.go index ea378bdaa..6b8859b44 100644 --- a/tun/netstack/tun.go +++ b/tun/netstack/tun.go @@ -207,14 +207,6 @@ func (tun *netTun) MTU() (int, error) { return tun.mtu, nil } -func (tun *netTun) Stack() *stack.Stack { - return tun.stack -} - -func (tun *netTun) Dispatcher() stack.NetworkDispatcher { - return tun.dispatcher -} - func convertToFullAddr(endpoint netip.AddrPort) (tcpip.FullAddress, tcpip.NetworkProtocolNumber) { var protoNumber tcpip.NetworkProtocolNumber if endpoint.Addr().Is4() { @@ -305,6 +297,14 @@ func (net *Net) ListenUDP(laddr *net.UDPAddr) (*gonet.UDPConn, error) { return net.DialUDP(laddr, nil) } +func (net *Net) Stack() *stack.Stack { + return net.stack +} + +func (net *Net) Dispatcher() stack.NetworkDispatcher { + return net.dispatcher +} + type PingConn struct { laddr PingAddr raddr PingAddr From 8066536716509b51143d382237a46d3f938ad535 Mon Sep 17 00:00:00 2001 From: Luke Rindels Date: Tue, 26 Jul 2022 14:42:56 -0600 Subject: [PATCH 3/8] tun/netstack: enable raw endpoint write Signed-off-by: Luke Rindels --- tun/netstack/tun.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tun/netstack/tun.go b/tun/netstack/tun.go index 6b8859b44..ad509da5e 100644 --- a/tun/netstack/tun.go +++ b/tun/netstack/tun.go @@ -31,6 +31,7 @@ import ( "gvisor.dev/gvisor/pkg/tcpip/network/ipv6" "gvisor.dev/gvisor/pkg/tcpip/stack" "gvisor.dev/gvisor/pkg/tcpip/transport/icmp" + "gvisor.dev/gvisor/pkg/tcpip/transport/raw" "gvisor.dev/gvisor/pkg/tcpip/transport/tcp" "gvisor.dev/gvisor/pkg/tcpip/transport/udp" "gvisor.dev/gvisor/pkg/waiter" @@ -103,9 +104,11 @@ func (e *endpoint) AddHeader(tcpip.LinkAddress, tcpip.LinkAddress, tcpip.Network func CreateNetTUN(localAddresses, dnsServers []netip.Addr, mtu int) (tun.Device, *Net, error) { opts := stack.Options{ - NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol, ipv6.NewProtocol}, - TransportProtocols: []stack.TransportProtocolFactory{tcp.NewProtocol, udp.NewProtocol, icmp.NewProtocol6, icmp.NewProtocol4}, - HandleLocal: true, + NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol, ipv6.NewProtocol}, + TransportProtocols: []stack.TransportProtocolFactory{tcp.NewProtocol, udp.NewProtocol, icmp.NewProtocol6, icmp.NewProtocol4}, + HandleLocal: true, + RawFactory: raw.EndpointFactory{}, + AllowPacketEndpointWrite: true, } dev := &netTun{ stack: stack.New(opts), From da3a7e2ca54804c440ccb481b8a92d49b63eb986 Mon Sep 17 00:00:00 2001 From: Luke Rindels Date: Fri, 4 Nov 2022 14:55:40 -0600 Subject: [PATCH 4/8] Expose endpoint, dispatcher is deprecated --- tun/netstack/tun.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tun/netstack/tun.go b/tun/netstack/tun.go index 0990a36e8..126098f98 100644 --- a/tun/netstack/tun.go +++ b/tun/netstack/tun.go @@ -272,8 +272,8 @@ func (net *Net) Stack() *stack.Stack { return net.stack } -func (net *Net) Dispatcher() stack.NetworkDispatcher { - return net.dispatcher +func (net *Net) Endpoint() *channel.Endpoint { + return net.ep } type PingConn struct { From 083493de03ef2b994a513ca82144d1bc88f1e280 Mon Sep 17 00:00:00 2001 From: Luke Rindels Date: Fri, 4 Nov 2022 16:33:28 -0600 Subject: [PATCH 5/8] Bump gvisor --- go.mod | 2 +- go.sum | 4 ++-- tun/netstack/tun.go | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index c180d1b49..c9f8828df 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( golang.org/x/net v0.0.0-20220225172249-27dd8689420f golang.org/x/sys v0.0.0-20220315194320-039c03cc5b86 golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 - gvisor.dev/gvisor v0.0.0-20220817001344-846276b3dbc5 + gvisor.dev/gvisor v0.0.0-20221104205919-655443bf0670 ) require ( diff --git a/go.sum b/go.sum index 5f417a7c6..f45109446 100644 --- a/go.sum +++ b/go.sum @@ -10,5 +10,5 @@ golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqG golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224 h1:Ug9qvr1myri/zFN6xL17LSCBGFDnphBBhzmILHsM5TY= golang.zx2c4.com/wintun v0.0.0-20211104114900-415007cec224/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI= -gvisor.dev/gvisor v0.0.0-20220817001344-846276b3dbc5 h1:cv/zaNV0nr1mJzaeo4S5mHIm5va1W0/9J3/5prlsuRM= -gvisor.dev/gvisor v0.0.0-20220817001344-846276b3dbc5/go.mod h1:TIvkJD0sxe8pIob3p6T8IzxXunlp6yfgktvTNp+DGNM= +gvisor.dev/gvisor v0.0.0-20221104205919-655443bf0670 h1:tbG0IU4/lPpZMxv6kerFtJhV/vSb5eqw4eiI4rtxPMQ= +gvisor.dev/gvisor v0.0.0-20221104205919-655443bf0670/go.mod h1:D0iRe6RVONyvN6uEi/rqBtONyitX5GaHMDDbeMzwgiE= diff --git a/tun/netstack/tun.go b/tun/netstack/tun.go index 126098f98..74b6a7e63 100644 --- a/tun/netstack/tun.go +++ b/tun/netstack/tun.go @@ -144,7 +144,7 @@ func (tun *netTun) Write(buf []byte, offset int) (int, error) { func (tun *netTun) WriteNotify() { pkt := tun.ep.Read() - if pkt == nil { + if pkt.IsNil() { return } From 2e22d4a23db142cb77bfc61201fcfe19b5dc3e2f Mon Sep 17 00:00:00 2001 From: Luke Rindels Date: Wed, 28 Jun 2023 09:09:00 -0600 Subject: [PATCH 6/8] Remove HandleLocal --- tun/netstack/tun.go | 1 - 1 file changed, 1 deletion(-) diff --git a/tun/netstack/tun.go b/tun/netstack/tun.go index c98094adc..ebd18b1e8 100644 --- a/tun/netstack/tun.go +++ b/tun/netstack/tun.go @@ -56,7 +56,6 @@ func CreateNetTUN(localAddresses, dnsServers []netip.Addr, mtu int) (tun.Device, opts := stack.Options{ NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol, ipv6.NewProtocol}, TransportProtocols: []stack.TransportProtocolFactory{tcp.NewProtocol, udp.NewProtocol, icmp.NewProtocol6, icmp.NewProtocol4}, - HandleLocal: true, RawFactory: raw.EndpointFactory{}, AllowPacketEndpointWrite: true, } From ff70a39ed361a454cfcdc0619bdd317389584041 Mon Sep 17 00:00:00 2001 From: Aptimex Date: Mon, 11 Aug 2025 13:23:13 -0600 Subject: [PATCH 7/8] add separate CreateRaw function --- tun/netstack/tun.go | 56 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/tun/netstack/tun.go b/tun/netstack/tun.go index 063ded87f..95e274f44 100644 --- a/tun/netstack/tun.go +++ b/tun/netstack/tun.go @@ -54,6 +54,62 @@ type netTun struct { type Net netTun func CreateNetTUN(localAddresses, dnsServers []netip.Addr, mtu int) (tun.Device, *Net, error) { + opts := stack.Options{ + NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol, ipv6.NewProtocol}, + TransportProtocols: []stack.TransportProtocolFactory{tcp.NewProtocol, udp.NewProtocol, icmp.NewProtocol6, icmp.NewProtocol4}, + HandleLocal: true, + } + dev := &netTun{ + ep: channel.New(1024, uint32(mtu), ""), + stack: stack.New(opts), + events: make(chan tun.Event, 10), + incomingPacket: make(chan *buffer.View), + dnsServers: dnsServers, + mtu: mtu, + } + sackEnabledOpt := tcpip.TCPSACKEnabled(true) // TCP SACK is disabled by default + tcpipErr := dev.stack.SetTransportProtocolOption(tcp.ProtocolNumber, &sackEnabledOpt) + if tcpipErr != nil { + return nil, nil, fmt.Errorf("could not enable TCP SACK: %v", tcpipErr) + } + dev.notifyHandle = dev.ep.AddNotify(dev) + tcpipErr = dev.stack.CreateNIC(1, dev.ep) + if tcpipErr != nil { + return nil, nil, fmt.Errorf("CreateNIC: %v", tcpipErr) + } + for _, ip := range localAddresses { + var protoNumber tcpip.NetworkProtocolNumber + if ip.Is4() { + protoNumber = ipv4.ProtocolNumber + } else if ip.Is6() { + protoNumber = ipv6.ProtocolNumber + } + protoAddr := tcpip.ProtocolAddress{ + Protocol: protoNumber, + AddressWithPrefix: tcpip.AddrFromSlice(ip.AsSlice()).WithPrefix(), + } + tcpipErr := dev.stack.AddProtocolAddress(1, protoAddr, stack.AddressProperties{}) + if tcpipErr != nil { + return nil, nil, fmt.Errorf("AddProtocolAddress(%v): %v", ip, tcpipErr) + } + if ip.Is4() { + dev.hasV4 = true + } else if ip.Is6() { + dev.hasV6 = true + } + } + if dev.hasV4 { + dev.stack.AddRoute(tcpip.Route{Destination: header.IPv4EmptySubnet, NIC: 1}) + } + if dev.hasV6 { + dev.stack.AddRoute(tcpip.Route{Destination: header.IPv6EmptySubnet, NIC: 1}) + } + + dev.events <- tun.EventUp + return dev, (*Net)(dev), nil +} + +func CreateRawNetTUN(localAddresses, dnsServers []netip.Addr, mtu int) (tun.Device, *Net, error) { opts := stack.Options{ NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol, ipv6.NewProtocol}, TransportProtocols: []stack.TransportProtocolFactory{tcp.NewProtocol, udp.NewProtocol, icmp.NewProtocol6, icmp.NewProtocol4}, From 7984dc76bc938bca1f54efa78548d24905c0838e Mon Sep 17 00:00:00 2001 From: Aptimex Date: Mon, 11 Aug 2025 16:50:24 -0600 Subject: [PATCH 8/8] more generic CreateNetTUNwithOptions --- tun/netstack/tun.go | 59 +++------------------------------------------ 1 file changed, 3 insertions(+), 56 deletions(-) diff --git a/tun/netstack/tun.go b/tun/netstack/tun.go index 95e274f44..229b3485a 100644 --- a/tun/netstack/tun.go +++ b/tun/netstack/tun.go @@ -34,7 +34,6 @@ import ( "gvisor.dev/gvisor/pkg/tcpip/network/ipv6" "gvisor.dev/gvisor/pkg/tcpip/stack" "gvisor.dev/gvisor/pkg/tcpip/transport/icmp" - "gvisor.dev/gvisor/pkg/tcpip/transport/raw" "gvisor.dev/gvisor/pkg/tcpip/transport/tcp" "gvisor.dev/gvisor/pkg/tcpip/transport/udp" "gvisor.dev/gvisor/pkg/waiter" @@ -59,63 +58,11 @@ func CreateNetTUN(localAddresses, dnsServers []netip.Addr, mtu int) (tun.Device, TransportProtocols: []stack.TransportProtocolFactory{tcp.NewProtocol, udp.NewProtocol, icmp.NewProtocol6, icmp.NewProtocol4}, HandleLocal: true, } - dev := &netTun{ - ep: channel.New(1024, uint32(mtu), ""), - stack: stack.New(opts), - events: make(chan tun.Event, 10), - incomingPacket: make(chan *buffer.View), - dnsServers: dnsServers, - mtu: mtu, - } - sackEnabledOpt := tcpip.TCPSACKEnabled(true) // TCP SACK is disabled by default - tcpipErr := dev.stack.SetTransportProtocolOption(tcp.ProtocolNumber, &sackEnabledOpt) - if tcpipErr != nil { - return nil, nil, fmt.Errorf("could not enable TCP SACK: %v", tcpipErr) - } - dev.notifyHandle = dev.ep.AddNotify(dev) - tcpipErr = dev.stack.CreateNIC(1, dev.ep) - if tcpipErr != nil { - return nil, nil, fmt.Errorf("CreateNIC: %v", tcpipErr) - } - for _, ip := range localAddresses { - var protoNumber tcpip.NetworkProtocolNumber - if ip.Is4() { - protoNumber = ipv4.ProtocolNumber - } else if ip.Is6() { - protoNumber = ipv6.ProtocolNumber - } - protoAddr := tcpip.ProtocolAddress{ - Protocol: protoNumber, - AddressWithPrefix: tcpip.AddrFromSlice(ip.AsSlice()).WithPrefix(), - } - tcpipErr := dev.stack.AddProtocolAddress(1, protoAddr, stack.AddressProperties{}) - if tcpipErr != nil { - return nil, nil, fmt.Errorf("AddProtocolAddress(%v): %v", ip, tcpipErr) - } - if ip.Is4() { - dev.hasV4 = true - } else if ip.Is6() { - dev.hasV6 = true - } - } - if dev.hasV4 { - dev.stack.AddRoute(tcpip.Route{Destination: header.IPv4EmptySubnet, NIC: 1}) - } - if dev.hasV6 { - dev.stack.AddRoute(tcpip.Route{Destination: header.IPv6EmptySubnet, NIC: 1}) - } - - dev.events <- tun.EventUp - return dev, (*Net)(dev), nil + return CreateNetTUNwithOptions(localAddresses, dnsServers, mtu, opts) } -func CreateRawNetTUN(localAddresses, dnsServers []netip.Addr, mtu int) (tun.Device, *Net, error) { - opts := stack.Options{ - NetworkProtocols: []stack.NetworkProtocolFactory{ipv4.NewProtocol, ipv6.NewProtocol}, - TransportProtocols: []stack.TransportProtocolFactory{tcp.NewProtocol, udp.NewProtocol, icmp.NewProtocol6, icmp.NewProtocol4}, - RawFactory: raw.EndpointFactory{}, - AllowPacketEndpointWrite: true, - } +func CreateNetTUNwithOptions(localAddresses, dnsServers []netip.Addr, mtu int, stackOptions stack.Options) (tun.Device, *Net, error) { + opts := stackOptions dev := &netTun{ ep: channel.New(1024, uint32(mtu), ""), stack: stack.New(opts),