github.com/metacubex/sing-tun@v0.2.7-0.20240512075008-89e7c6208eec/tun_linux_flags.go (about) 1 //go:build linux 2 3 package tun 4 5 import ( 6 "os" 7 "syscall" 8 "unsafe" 9 10 E "github.com/sagernet/sing/common/exceptions" 11 12 "golang.org/x/sys/unix" 13 ) 14 15 func checkVNETHDREnabled(fd int, name string) (bool, error) { 16 ifr, err := unix.NewIfreq(name) 17 if err != nil { 18 return false, err 19 } 20 err = unix.IoctlIfreq(fd, unix.TUNGETIFF, ifr) 21 if err != nil { 22 return false, os.NewSyscallError("TUNGETIFF", err) 23 } 24 return ifr.Uint16()&unix.IFF_VNET_HDR != 0, nil 25 } 26 27 func setTCPOffload(fd int) error { 28 const ( 29 // TODO: support TSO with ECN bits 30 tunOffloads = unix.TUN_F_CSUM | unix.TUN_F_TSO4 | unix.TUN_F_TSO6 31 ) 32 err := unix.IoctlSetInt(fd, unix.TUNSETOFFLOAD, tunOffloads) 33 if err != nil { 34 return E.Cause(os.NewSyscallError("TUNSETOFFLOAD", err), "enable offload") 35 } 36 return nil 37 } 38 39 type ifreqData struct { 40 ifrName [unix.IFNAMSIZ]byte 41 ifrData uintptr 42 } 43 44 type ethtoolValue struct { 45 cmd uint32 46 data uint32 47 } 48 49 //go:linkname ioctlPtr golang.org/x/sys/unix.ioctlPtr 50 func ioctlPtr(fd int, req uint, arg unsafe.Pointer) (err error) 51 52 func checkChecksumOffload(name string, cmd uint32) (bool, error) { 53 fd, err := unix.Socket(unix.AF_INET, unix.SOCK_DGRAM, unix.IPPROTO_IP) 54 if err != nil { 55 return false, err 56 } 57 defer syscall.Close(fd) 58 ifr := ifreqData{} 59 copy(ifr.ifrName[:], name) 60 data := ethtoolValue{cmd: cmd} 61 ifr.ifrData = uintptr(unsafe.Pointer(&data)) 62 err = ioctlPtr(fd, unix.SIOCETHTOOL, unsafe.Pointer(&ifr)) 63 if err != nil { 64 return false, os.NewSyscallError("SIOCETHTOOL ETHTOOL_GTXCSUM", err) 65 } 66 return data.data == 0, nil 67 } 68 69 func setChecksumOffload(name string, cmd uint32) error { 70 fd, err := unix.Socket(unix.AF_INET, unix.SOCK_DGRAM, unix.IPPROTO_IP) 71 if err != nil { 72 return err 73 } 74 defer syscall.Close(fd) 75 ifr := ifreqData{} 76 copy(ifr.ifrName[:], name) 77 data := ethtoolValue{cmd: cmd, data: 0} 78 ifr.ifrData = uintptr(unsafe.Pointer(&data)) 79 err = ioctlPtr(fd, unix.SIOCETHTOOL, unsafe.Pointer(&ifr)) 80 if err != nil { 81 return os.NewSyscallError("SIOCETHTOOL ETHTOOL_STXCSUM", err) 82 } 83 return nil 84 }