Add checksum offload stub

This commit is contained in:
世界 2023-12-16 01:52:43 +08:00
parent fc86b20fba
commit 010126fc60
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
12 changed files with 220 additions and 83 deletions

2
go.mod
View file

@ -7,7 +7,7 @@ require (
github.com/go-ole/go-ole v1.3.0
github.com/sagernet/gvisor v0.0.0-20231209105102-8d27a30e436e
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97
github.com/sagernet/sing v0.2.20-0.20231211084415-35e7014b0898
github.com/sagernet/sing v0.3.0-beta.3
github.com/scjalliance/comshim v0.0.0-20230315213746-5e51f40bd3b9
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba
golang.org/x/net v0.19.0

8
go.sum
View file

@ -1,17 +1,20 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU=
github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/sagernet/gvisor v0.0.0-20231209105102-8d27a30e436e h1:DOkjByVeAR56dkszjnMZke4wr7yM/1xHaJF3G9olkEE=
github.com/sagernet/gvisor v0.0.0-20231209105102-8d27a30e436e/go.mod h1:fLxq/gtp0qzkaEwywlRRiGmjOK5ES/xUzyIKIFP2Asw=
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 h1:iL5gZI3uFp0X6EslacyapiRz7LLSJyr4RajF/BhMVyE=
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
github.com/sagernet/sing v0.2.20-0.20231211084415-35e7014b0898 h1:ZR0wpw4/0NCICOX10SIUW8jpPVV7+D98nGA6p4zWICo=
github.com/sagernet/sing v0.2.20-0.20231211084415-35e7014b0898/go.mod h1:Ce5LNojQOgOiWhiD8pPD6E9H7e2KgtOe3Zxx4Ou5u80=
github.com/sagernet/sing v0.3.0-beta.3 h1:E2xBoJUducK/FE6EwMk95Rt2bkXeht9l1BTYRui+DXs=
github.com/sagernet/sing v0.3.0-beta.3/go.mod h1:9pfuAH6mZfgnz/YjP6xu5sxx882rfyjpcrTdUpd6w3g=
github.com/scjalliance/comshim v0.0.0-20230315213746-5e51f40bd3b9 h1:rc/CcqLH3lh8n+csdOuDfP+NuykE0U6AeYSJJHKDgSg=
github.com/scjalliance/comshim v0.0.0-20230315213746-5e51f40bd3b9/go.mod h1:a/83NAfUXvEuLpmxDssAXxgUgrEy12MId3Wd7OTs76s=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 h1:gga7acRE695APm9hlsSMoOoE65U4/TcqNj90mc69Rlg=
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M=
@ -24,3 +27,4 @@ golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

View file

@ -50,6 +50,10 @@ func (p TCPPacket) SetChecksum(sum [2]byte) {
p[17] = sum[1]
}
func (p TCPPacket) OffloadChecksum() {
p.SetChecksum(zeroChecksum)
}
func (p TCPPacket) ResetChecksum(psum uint32) {
p.SetChecksum(zeroChecksum)
p.SetChecksum(Checksum(psum, p))

View file

@ -45,6 +45,10 @@ func (p UDPPacket) SetChecksum(sum [2]byte) {
p[7] = sum[1]
}
func (p UDPPacket) OffloadChecksum() {
p.SetChecksum(zeroChecksum)
}
func (p UDPPacket) ResetChecksum(psum uint32) {
p.SetChecksum(zeroChecksum)
p.SetChecksum(Checksum(psum, p))

View file

@ -91,17 +91,18 @@ func (m *Mixed) tunLoop() {
m.wintunLoop(winTun)
return
}
if batchTUN, isBatchTUN := m.tun.(BatchTUN); isBatchTUN {
batchSize := batchTUN.BatchSize()
if linuxTUN, isLinuxTUN := m.tun.(LinuxTUN); isLinuxTUN {
m.frontHeadroom = linuxTUN.FrontHeadroom()
m.txChecksumOffload = linuxTUN.TXChecksumOffload()
batchSize := linuxTUN.BatchSize()
if batchSize > 1 {
m.batchLoop(batchTUN, batchSize)
m.batchLoop(linuxTUN, batchSize)
return
}
}
frontHeadroom := m.tun.FrontHeadroom()
packetBuffer := make([]byte, m.mtu+frontHeadroom+PacketOffset)
packetBuffer := make([]byte, m.mtu+PacketOffset)
for {
n, err := m.tun.Read(packetBuffer[frontHeadroom:])
n, err := m.tun.Read(packetBuffer)
if err != nil {
if E.IsClosed(err) {
return
@ -111,8 +112,8 @@ func (m *Mixed) tunLoop() {
if n < clashtcpip.IPv4PacketMinLength {
continue
}
rawPacket := packetBuffer[:frontHeadroom+n]
packet := packetBuffer[frontHeadroom+PacketOffset : frontHeadroom+n]
rawPacket := packetBuffer[:n]
packet := packetBuffer[PacketOffset:n]
if m.processPacket(packet) {
_, err = m.tun.Write(rawPacket)
if err != nil {
@ -142,16 +143,15 @@ func (m *Mixed) wintunLoop(winTun WinTun) {
}
}
func (m *Mixed) batchLoop(linuxTUN BatchTUN, batchSize int) {
frontHeadroom := m.tun.FrontHeadroom()
func (m *Mixed) batchLoop(linuxTUN LinuxTUN, batchSize int) {
packetBuffers := make([][]byte, batchSize)
writeBuffers := make([][]byte, batchSize)
packetSizes := make([]int, batchSize)
for i := range packetBuffers {
packetBuffers[i] = make([]byte, m.mtu+frontHeadroom)
packetBuffers[i] = make([]byte, m.mtu+m.frontHeadroom)
}
for {
n, err := linuxTUN.BatchRead(packetBuffers, frontHeadroom, packetSizes)
n, err := linuxTUN.BatchRead(packetBuffers, m.frontHeadroom, packetSizes)
if err != nil {
if E.IsClosed(err) {
return
@ -167,13 +167,13 @@ func (m *Mixed) batchLoop(linuxTUN BatchTUN, batchSize int) {
continue
}
packetBuffer := packetBuffers[i]
packet := packetBuffer[frontHeadroom : frontHeadroom+packetSize]
packet := packetBuffer[m.frontHeadroom : m.frontHeadroom+packetSize]
if m.processPacket(packet) {
writeBuffers = append(writeBuffers, packetBuffer[:frontHeadroom+packetSize])
writeBuffers = append(writeBuffers, packetBuffer[:m.frontHeadroom+packetSize])
}
}
if len(writeBuffers) > 0 {
err = linuxTUN.BatchWrite(writeBuffers, frontHeadroom)
err = linuxTUN.BatchWrite(writeBuffers, m.frontHeadroom)
if err != nil {
m.logger.Trace(E.Cause(err, "batch write packet"))
}

View file

@ -41,6 +41,8 @@ type System struct {
udpNat *udpnat.Service[netip.AddrPort]
bindInterface bool
interfaceFinder control.InterfaceFinder
frontHeadroom int
txChecksumOffload bool
}
type Session struct {
@ -144,17 +146,18 @@ func (s *System) tunLoop() {
s.wintunLoop(winTun)
return
}
if batchTUN, isBatchTUN := s.tun.(BatchTUN); isBatchTUN {
batchSize := batchTUN.BatchSize()
if linuxTUN, isLinuxTUN := s.tun.(LinuxTUN); isLinuxTUN {
s.frontHeadroom = linuxTUN.FrontHeadroom()
s.txChecksumOffload = linuxTUN.TXChecksumOffload()
batchSize := linuxTUN.BatchSize()
if batchSize > 1 {
s.batchLoop(batchTUN, batchSize)
s.batchLoop(linuxTUN, batchSize)
return
}
}
frontHeadroom := s.tun.FrontHeadroom()
packetBuffer := make([]byte, s.mtu+frontHeadroom+PacketOffset)
packetBuffer := make([]byte, s.mtu+PacketOffset)
for {
n, err := s.tun.Read(packetBuffer[frontHeadroom:])
n, err := s.tun.Read(packetBuffer)
if err != nil {
if E.IsClosed(err) {
return
@ -164,8 +167,8 @@ func (s *System) tunLoop() {
if n < clashtcpip.IPv4PacketMinLength {
continue
}
rawPacket := packetBuffer[:frontHeadroom+n]
packet := packetBuffer[frontHeadroom+PacketOffset : frontHeadroom+n]
rawPacket := packetBuffer[:n]
packet := packetBuffer[PacketOffset:n]
if s.processPacket(packet) {
_, err = s.tun.Write(rawPacket)
if err != nil {
@ -195,16 +198,15 @@ func (s *System) wintunLoop(winTun WinTun) {
}
}
func (s *System) batchLoop(linuxTUN BatchTUN, batchSize int) {
frontHeadroom := s.tun.FrontHeadroom()
func (s *System) batchLoop(linuxTUN LinuxTUN, batchSize int) {
packetBuffers := make([][]byte, batchSize)
writeBuffers := make([][]byte, batchSize)
packetSizes := make([]int, batchSize)
for i := range packetBuffers {
packetBuffers[i] = make([]byte, s.mtu+frontHeadroom)
packetBuffers[i] = make([]byte, s.mtu+s.frontHeadroom)
}
for {
n, err := linuxTUN.BatchRead(packetBuffers, frontHeadroom, packetSizes)
n, err := linuxTUN.BatchRead(packetBuffers, s.frontHeadroom, packetSizes)
if err != nil {
if E.IsClosed(err) {
return
@ -220,13 +222,13 @@ func (s *System) batchLoop(linuxTUN BatchTUN, batchSize int) {
continue
}
packetBuffer := packetBuffers[i]
packet := packetBuffer[frontHeadroom : frontHeadroom+packetSize]
packet := packetBuffer[s.frontHeadroom : s.frontHeadroom+packetSize]
if s.processPacket(packet) {
writeBuffers = append(writeBuffers, packetBuffer[:frontHeadroom+packetSize])
writeBuffers = append(writeBuffers, packetBuffer[:s.frontHeadroom+packetSize])
}
}
if len(writeBuffers) > 0 {
err = linuxTUN.BatchWrite(writeBuffers, frontHeadroom)
err = linuxTUN.BatchWrite(writeBuffers, s.frontHeadroom)
if err != nil {
s.logger.Trace(E.Cause(err, "batch write packet"))
}
@ -352,8 +354,13 @@ func (s *System) processIPv4TCP(packet clashtcpip.IPv4Packet, header clashtcpip.
packet.SetDestinationIP(s.inet4ServerAddress)
header.SetDestinationPort(s.tcpPort)
}
header.ResetChecksum(packet.PseudoSum())
packet.ResetChecksum()
if !s.txChecksumOffload {
header.ResetChecksum(packet.PseudoSum())
packet.ResetChecksum()
} else {
header.OffloadChecksum()
packet.ResetChecksum()
}
return nil
}
@ -378,8 +385,11 @@ func (s *System) processIPv6TCP(packet clashtcpip.IPv6Packet, header clashtcpip.
packet.SetDestinationIP(s.inet6ServerAddress)
header.SetDestinationPort(s.tcpPort6)
}
header.ResetChecksum(packet.PseudoSum())
packet.ResetChecksum()
if !s.txChecksumOffload {
header.ResetChecksum(packet.PseudoSum())
} else {
header.OffloadChecksum()
}
return nil
}
@ -410,7 +420,13 @@ func (s *System) processIPv4UDP(packet clashtcpip.IPv4Packet, header clashtcpip.
headerLen := packet.HeaderLen() + clashtcpip.UDPHeaderSize
headerCopy := make([]byte, headerLen)
copy(headerCopy, packet[:headerLen])
return &systemUDPPacketWriter4{s.tun, s.tun.FrontHeadroom() + PacketOffset, headerCopy, source}
return &systemUDPPacketWriter4{
s.tun,
s.frontHeadroom + PacketOffset,
headerCopy,
source,
s.txChecksumOffload,
}
})
return nil
}
@ -436,7 +452,13 @@ func (s *System) processIPv6UDP(packet clashtcpip.IPv6Packet, header clashtcpip.
headerLen := len(packet) - int(header.Length()) + clashtcpip.UDPHeaderSize
headerCopy := make([]byte, headerLen)
copy(headerCopy, packet[:headerLen])
return &systemUDPPacketWriter6{s.tun, s.tun.FrontHeadroom() + PacketOffset, headerCopy, source}
return &systemUDPPacketWriter6{
s.tun,
s.frontHeadroom + PacketOffset,
headerCopy,
source,
s.txChecksumOffload,
}
})
return nil
}
@ -468,10 +490,11 @@ func (s *System) processIPv6ICMP(packet clashtcpip.IPv6Packet, header clashtcpip
}
type systemUDPPacketWriter4 struct {
tun Tun
frontHeadroom int
header []byte
source netip.AddrPort
tun Tun
frontHeadroom int
header []byte
source netip.AddrPort
txChecksumOffload bool
}
func (w *systemUDPPacketWriter4) WritePacket(buffer *buf.Buffer, destination M.Socksaddr) error {
@ -488,8 +511,13 @@ func (w *systemUDPPacketWriter4) WritePacket(buffer *buf.Buffer, destination M.S
udpHdr.SetDestinationPort(udpHdr.SourcePort())
udpHdr.SetSourcePort(destination.Port)
udpHdr.SetLength(uint16(buffer.Len() + clashtcpip.UDPHeaderSize))
udpHdr.ResetChecksum(ipHdr.PseudoSum())
ipHdr.ResetChecksum()
if !w.txChecksumOffload {
udpHdr.ResetChecksum(ipHdr.PseudoSum())
ipHdr.ResetChecksum()
} else {
udpHdr.OffloadChecksum()
ipHdr.ResetChecksum()
}
if PacketOffset > 0 {
newPacket.ExtendHeader(PacketOffset)[3] = syscall.AF_INET
} else {
@ -499,10 +527,11 @@ func (w *systemUDPPacketWriter4) WritePacket(buffer *buf.Buffer, destination M.S
}
type systemUDPPacketWriter6 struct {
tun Tun
frontHeadroom int
header []byte
source netip.AddrPort
tun Tun
frontHeadroom int
header []byte
source netip.AddrPort
txChecksumOffload bool
}
func (w *systemUDPPacketWriter6) WritePacket(buffer *buf.Buffer, destination M.Socksaddr) error {
@ -520,7 +549,11 @@ func (w *systemUDPPacketWriter6) WritePacket(buffer *buf.Buffer, destination M.S
udpHdr.SetDestinationPort(udpHdr.SourcePort())
udpHdr.SetSourcePort(destination.Port)
udpHdr.SetLength(udpLen)
udpHdr.ResetChecksum(ipHdr.PseudoSum())
if !w.txChecksumOffload {
udpHdr.ResetChecksum(ipHdr.PseudoSum())
} else {
udpHdr.OffloadChecksum()
}
if PacketOffset > 0 {
newPacket.ExtendHeader(PacketOffset)[3] = syscall.AF_INET6
} else {

8
tun.go
View file

@ -24,7 +24,6 @@ type Handler interface {
type Tun interface {
io.ReadWriter
N.VectorisedWriter
N.FrontHeadroom
Close() error
}
@ -33,11 +32,13 @@ type WinTun interface {
ReadPacket() ([]byte, func(), error)
}
type BatchTUN interface {
type LinuxTUN interface {
Tun
N.FrontHeadroom
BatchSize() int
BatchRead(buffers [][]byte, offset int, readN []int) (n int, err error)
BatchWrite(buffers [][]byte, offset int) error
TXChecksumOffload() bool
}
type Options struct {
@ -63,6 +64,9 @@ type Options struct {
TableIndex int
FileDescriptor int
Logger logger.Logger
// No work for TCP, do not use.
_TXChecksumOffload bool
}
func CalculateInterfaceName(name string) (tunName string) {

View file

@ -5,7 +5,6 @@ import (
"net"
"net/netip"
"os"
"runtime"
"syscall"
"unsafe"
@ -68,14 +67,9 @@ func New(options Options) (Tun, error) {
if !ok {
panic("create vectorised writer")
}
runtime.SetFinalizer(nativeTun.tunFile, nil)
return nativeTun, nil
}
func (t *NativeTun) FrontHeadroom() int {
return 0
}
func (t *NativeTun) Read(p []byte) (n int, err error) {
return t.tunFile.Read(p)
}

View file

@ -24,7 +24,7 @@ import (
"golang.org/x/sys/unix"
)
var _ BatchTUN = (*NativeTun)(nil)
var _ LinuxTUN = (*NativeTun)(nil)
type NativeTun struct {
tunFd int
@ -40,6 +40,7 @@ type NativeTun struct {
tcpGROAccess sync.Mutex
tcp4GROTable *tcpGROTable
tcp6GROTable *tcpGROTable
txChecksumOffload bool
}
func New(options Options) (Tun, error) {
@ -246,20 +247,17 @@ func (t *NativeTun) configure(tunLink netlink.Link) error {
}
if t.options.GSO {
vnethdrEnabled, err := checkVNETHDREnabled(uint16(t.tunFd), t.options.Name)
var vnetHdrEnabled bool
vnetHdrEnabled, err = checkVNETHDREnabled(t.tunFd, t.options.Name)
if err != nil {
return E.Cause(err, "enable offload: check IFF_VNET_HDR enabled")
}
if !vnethdrEnabled {
if !vnetHdrEnabled {
return E.Cause(err, "enable offload: IFF_VNET_HDR not enabled")
}
const (
// TODO: support TSO with ECN bits
tunOffloads = unix.TUN_F_CSUM | unix.TUN_F_TSO4 | unix.TUN_F_TSO6
)
err = unix.IoctlSetInt(t.tunFd, unix.TUNSETOFFLOAD, tunOffloads)
err = setTCPOffload(t.tunFd)
if err != nil {
return E.Cause(os.NewSyscallError("TUNSETOFFLOAD", err), "enable offload")
return err
}
t.gsoEnabled = true
t.gsoBuffer = make([]byte, virtioNetHdrLen+int(gsoMaxSize))
@ -267,6 +265,27 @@ func (t *NativeTun) configure(tunLink netlink.Link) error {
t.tcp6GROTable = newTCPGROTable()
}
var rxChecksumOffload bool
rxChecksumOffload, err = checkChecksumOffload(t.options.Name, unix.ETHTOOL_GRXCSUM)
if err == nil && !rxChecksumOffload {
_ = setChecksumOffload(t.options.Name, unix.ETHTOOL_SRXCSUM)
}
if !t.options._TXChecksumOffload {
var txChecksumOffload bool
txChecksumOffload, err = checkChecksumOffload(t.options.Name, unix.ETHTOOL_GTXCSUM)
if err != nil {
return err
}
if err == nil && !txChecksumOffload {
err = setChecksumOffload(t.options.Name, unix.ETHTOOL_STXCSUM)
if err != nil {
return err
}
}
t.txChecksumOffload = true
}
err = netlink.LinkSetUp(tunLink)
if err != nil {
return err
@ -306,18 +325,6 @@ func (t *NativeTun) configure(tunLink netlink.Link) error {
return nil
}
func checkVNETHDREnabled(fd uint16, name string) (bool, error) {
ifr, err := unix.NewIfreq(name)
if err != nil {
return false, err
}
err = unix.IoctlIfreq(int(fd), unix.TUNGETIFF, ifr)
if err != nil {
return false, os.NewSyscallError("TUNGETIFF", err)
}
return ifr.Uint16()&unix.IFF_VNET_HDR != 0, nil
}
func (t *NativeTun) Close() error {
if t.interfaceCallback != nil {
t.options.InterfaceMonitor.UnregisterCallback(t.interfaceCallback)
@ -325,6 +332,10 @@ func (t *NativeTun) Close() error {
return E.Errors(t.unsetRoute(), t.unsetRules(), common.Close(common.PtrOrNil(t.tunFile)))
}
func (t *NativeTun) TXChecksumOffload() bool {
return t.txChecksumOffload
}
func prefixToIPNet(prefix netip.Prefix) *net.IPNet {
return &net.IPNet{
IP: prefix.Addr().AsSlice(),

84
tun_linux_flags.go Normal file
View file

@ -0,0 +1,84 @@
//go:build linux
package tun
import (
"os"
"syscall"
"unsafe"
E "github.com/sagernet/sing/common/exceptions"
"golang.org/x/sys/unix"
)
func checkVNETHDREnabled(fd int, name string) (bool, error) {
ifr, err := unix.NewIfreq(name)
if err != nil {
return false, err
}
err = unix.IoctlIfreq(fd, unix.TUNGETIFF, ifr)
if err != nil {
return false, os.NewSyscallError("TUNGETIFF", err)
}
return ifr.Uint16()&unix.IFF_VNET_HDR != 0, nil
}
func setTCPOffload(fd int) error {
const (
// TODO: support TSO with ECN bits
tunOffloads = unix.TUN_F_CSUM | unix.TUN_F_TSO4 | unix.TUN_F_TSO6
)
err := unix.IoctlSetInt(fd, unix.TUNSETOFFLOAD, tunOffloads)
if err != nil {
return E.Cause(os.NewSyscallError("TUNSETOFFLOAD", err), "enable offload")
}
return nil
}
type ifreqData struct {
ifrName [unix.IFNAMSIZ]byte
ifrData uintptr
}
type ethtoolValue struct {
cmd uint32
data uint32
}
//go:linkname ioctlPtr golang.org/x/sys/unix.ioctlPtr
func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error)
func checkChecksumOffload(name string, cmd uint32) (bool, error) {
fd, err := unix.Socket(unix.AF_INET, unix.SOCK_DGRAM, unix.IPPROTO_IP)
if err != nil {
return false, err
}
defer syscall.Close(fd)
ifr := ifreqData{}
copy(ifr.ifrName[:], name)
data := ethtoolValue{cmd: cmd}
ifr.ifrData = uintptr(unsafe.Pointer(&data))
err = ioctlPtr(fd, unix.SIOCETHTOOL, unsafe.Pointer(&ifr))
if err != nil {
return false, os.NewSyscallError("SIOCETHTOOL ETHTOOL_GTXCSUM", err)
}
return data.data == 0, nil
}
func setChecksumOffload(name string, cmd uint32) error {
fd, err := unix.Socket(unix.AF_INET, unix.SOCK_DGRAM, unix.IPPROTO_IP)
if err != nil {
return err
}
defer syscall.Close(fd)
ifr := ifreqData{}
copy(ifr.ifrName[:], name)
data := ethtoolValue{cmd: cmd, data: 0}
ifr.ifrData = uintptr(unsafe.Pointer(&data))
err = ioctlPtr(fd, unix.SIOCETHTOOL, unsafe.Pointer(&ifr))
if err != nil {
return os.NewSyscallError("SIOCETHTOOL ETHTOOL_STXCSUM", err)
}
return nil
}

View file

@ -14,12 +14,15 @@ func (t *NativeTun) NewEndpoint() (stack.LinkEndpoint, error) {
return fdbased.New(&fdbased.Options{
FDs: []int{t.tunFd},
MTU: t.options.MTU,
GSOMaxSize: gsoMaxSize,
RXChecksumOffload: true,
TXChecksumOffload: t.txChecksumOffload,
})
}
return fdbased.New(&fdbased.Options{
FDs: []int{t.tunFd},
MTU: t.options.MTU,
RXChecksumOffload: true,
TXChecksumOffload: t.txChecksumOffload,
})
}

View file

@ -65,10 +65,6 @@ func New(options Options) (WinTun, error) {
return nativeTun, nil
}
func (t *NativeTun) FrontHeadroom() int {
return 0
}
func (t *NativeTun) configure() error {
luid := winipcfg.LUID(t.adapter.LUID())
if len(t.options.Inet4Address) > 0 {