Skip to content

Commit 90ea7a0

Browse files
wwqgtxxnekohasekai
authored andcommitted
Fix udp/icmp not work on gso with mixed stack
1 parent 6ee3db8 commit 90ea7a0

2 files changed

Lines changed: 34 additions & 0 deletions

File tree

tun_linux.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ type NativeTun struct {
3939
writeAccess sync.Mutex
4040
vnetHdr bool
4141
writeBuffer []byte
42+
vnetHdrWriteBuf []byte
4243
gsoToWrite []int
4344
tcpGROTable *tcpGROTable
4445
udpGroAccess sync.Mutex

tun_linux_gvisor.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
package tun
44

55
import (
6+
"fmt"
7+
68
"github.com/sagernet/gvisor/pkg/rawfile"
79
"github.com/sagernet/gvisor/pkg/tcpip/link/fdbased"
810
"github.com/sagernet/gvisor/pkg/tcpip/stack"
@@ -18,6 +20,37 @@ var _ GVisorTun = (*NativeTun)(nil)
1820

1921
func (t *NativeTun) WritePacket(pkt *stack.PacketBuffer) (int, error) {
2022
iovecs := t.iovecsOutputDefault
23+
if t.vnetHdr {
24+
if t.vnetHdrWriteBuf == nil {
25+
t.vnetHdrWriteBuf = make([]byte, virtioNetHdrLen)
26+
}
27+
vnetHdr := virtioNetHdr{}
28+
if pkt.GSOOptions.Type != stack.GSONone {
29+
vnetHdr.hdrLen = uint16(pkt.HeaderSize())
30+
if pkt.GSOOptions.NeedsCsum {
31+
vnetHdr.flags = unix.VIRTIO_NET_HDR_F_NEEDS_CSUM
32+
vnetHdr.csumStart = pkt.GSOOptions.L3HdrLen
33+
vnetHdr.csumOffset = pkt.GSOOptions.CsumOffset
34+
}
35+
if uint16(pkt.Data().Size()) > pkt.GSOOptions.MSS {
36+
switch pkt.GSOOptions.Type {
37+
case stack.GSOTCPv4:
38+
vnetHdr.gsoType = unix.VIRTIO_NET_HDR_GSO_TCPV4
39+
case stack.GSOTCPv6:
40+
vnetHdr.gsoType = unix.VIRTIO_NET_HDR_GSO_TCPV6
41+
default:
42+
panic(fmt.Sprintf("Unknown gso type: %v", pkt.GSOOptions.Type))
43+
}
44+
vnetHdr.gsoSize = pkt.GSOOptions.MSS
45+
}
46+
}
47+
if err := vnetHdr.encode(t.vnetHdrWriteBuf); err != nil {
48+
return 0, err
49+
}
50+
iovec := unix.Iovec{Base: &t.vnetHdrWriteBuf[0]}
51+
iovec.SetLen(virtioNetHdrLen)
52+
iovecs = append(iovecs, iovec)
53+
}
2154
var dataLen int
2255
for _, packetSlice := range pkt.AsSlices() {
2356
dataLen += len(packetSlice)

0 commit comments

Comments
 (0)