33package tun
44
55import (
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
1921func (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