TUN vectorised reads/writes

This commit is contained in:
Neil Alexander 2023-11-30 21:23:29 +00:00
parent 04c0acf71b
commit 0fb5d76e30
No known key found for this signature in database
GPG key ID: A02A2019A2BB0944
9 changed files with 75 additions and 23 deletions

View file

@ -1,33 +1,48 @@
package tun
const TUN_OFFSET_BYTES = 4
import (
"net"
)
const TUN_OFFSET_BYTES = 80 // sizeof(virtio_net_hdr)
const TUN_MAX_VECTOR = 16
func (tun *TunAdapter) idealBatchSize() int {
if b := tun.iface.BatchSize(); b <= TUN_MAX_VECTOR {
return b
}
return TUN_MAX_VECTOR
}
func (tun *TunAdapter) read() {
var buf [TUN_OFFSET_BYTES + 65535]byte
vs := tun.idealBatchSize()
bufs := make(net.Buffers, vs)
sizes := make([]int, vs)
for i := range bufs {
bufs[i] = make([]byte, TUN_OFFSET_BYTES+65535)
}
for {
n, err := tun.iface.Read(buf[:], TUN_OFFSET_BYTES)
if n <= TUN_OFFSET_BYTES || err != nil {
n, err := tun.iface.Read(bufs, sizes, TUN_OFFSET_BYTES)
if err != nil {
tun.log.Errorln("Error reading TUN:", err)
ferr := tun.iface.Flush()
if ferr != nil {
tun.log.Errorln("Unable to flush packets:", ferr)
}
return
}
begin := TUN_OFFSET_BYTES
end := begin + n
bs := buf[begin:end]
if _, err := tun.rwc.Write(bs); err != nil {
tun.log.Debugln("Unable to send packet:", err)
for i, b := range bufs[:n] {
if _, err := tun.rwc.Write(b[TUN_OFFSET_BYTES : TUN_OFFSET_BYTES+sizes[i]]); err != nil {
tun.log.Debugln("Unable to send packet:", err)
}
}
}
}
func (tun *TunAdapter) write() {
var buf [TUN_OFFSET_BYTES + 65535]byte
vs := 1 // One at a time for now... eventually use tun.idealBatchSize()
bufs := make(net.Buffers, vs)
for i := range bufs {
bufs[i] = make([]byte, TUN_OFFSET_BYTES+65535)
}
for {
bs := buf[TUN_OFFSET_BYTES:]
n, err := tun.rwc.Read(bs)
n, err := tun.rwc.Read(bufs[0][TUN_OFFSET_BYTES : TUN_OFFSET_BYTES+65535])
if err != nil {
tun.log.Errorln("Exiting TUN writer due to core read error:", err)
return
@ -35,8 +50,8 @@ func (tun *TunAdapter) write() {
if !tun.isEnabled {
continue // Nothing to do, the tun isn't enabled
}
bs = buf[:TUN_OFFSET_BYTES+n]
if _, err = tun.iface.Write(bs, TUN_OFFSET_BYTES); err != nil {
bufs[0] = bufs[0][:TUN_OFFSET_BYTES+n]
if _, err = tun.iface.Write(bufs, TUN_OFFSET_BYTES); err != nil {
tun.Act(nil, func() {
if !tun.isOpen {
tun.log.Errorln("TUN iface write error:", err)