Skip to content

Commit

Permalink
used syscalls to disable TX csum offload
Browse files Browse the repository at this point in the history
  • Loading branch information
hellt committed Nov 5, 2020
1 parent 40ada0f commit 2e25ca3
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 16 deletions.
9 changes: 3 additions & 6 deletions clab/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"io"
"io/ioutil"
"os"
"os/exec"
"path"
"strconv"
"strings"
Expand Down Expand Up @@ -105,13 +104,11 @@ func (c *cLab) CreateBridge(ctx context.Context) (err error) {
return fmt.Errorf("failed to enable LLDP on docker bridge: %v", err)
}

log.Debug("Disable Checksum Offloading on the docker bridge")
var b []byte
b, err = exec.Command("sudo", "ethtool", "--offload", bridgeName, "rx", "off", "tx", "off").CombinedOutput()
log.Debugf("Disabling TX checksum offloading for the %s bridge interface...", bridgeName)
err = EthtoolTXOff(bridgeName)
if err != nil {
return fmt.Errorf("failed to disable Checksum Offloading on docker bridge: %v", err)
return fmt.Errorf("Failed to disable TX checksum offloading for the %s bridge interface: %v", bridgeName, err)
}
log.Debugf("%s", string(b))
return nil
}

Expand Down
62 changes: 62 additions & 0 deletions clab/ethtool.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package clab

import (
"fmt"
"syscall"
"unsafe"
)

const (
SIOCETHTOOL = 0x8946 // linux/sockios.h
ETHTOOL_GTXCSUM = 0x00000016 // linux/ethtool.h
ETHTOOL_STXCSUM = 0x00000017 // linux/ethtool.h
IFNAMSIZ = 16 // linux/if.h
)

// linux/if.h 'struct ifreq'
type IFReqData struct {
Name [IFNAMSIZ]byte
Data uintptr
}

// linux/ethtool.h 'struct ethtool_value'
type EthtoolValue struct {
Cmd uint32
Data uint32
}

func ioctlEthtool(fd int, argp uintptr) error {
_, _, errno := syscall.RawSyscall(syscall.SYS_IOCTL, uintptr(fd), uintptr(SIOCETHTOOL), argp)
if errno != 0 {
return errno
}
return nil
}

// EthtoolTXOff disables TX checksum offload on specified interface
func EthtoolTXOff(name string) error {
if len(name)+1 > IFNAMSIZ {
return fmt.Errorf("name too long")
}

socket, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, 0)
if err != nil {
return err
}
defer syscall.Close(socket)

// Request current value
value := EthtoolValue{Cmd: ETHTOOL_GTXCSUM}
request := IFReqData{Data: uintptr(unsafe.Pointer(&value))}
copy(request.Name[:], name)

if err := ioctlEthtool(socket, uintptr(unsafe.Pointer(&request))); err != nil {
return err
}
if value.Data == 0 { // if already off, don't try to change
return nil
}

value = EthtoolValue{ETHTOOL_STXCSUM, 0}
return ioctlEthtool(socket, uintptr(unsafe.Pointer(&request)))
}
17 changes: 7 additions & 10 deletions clab/netlink.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,11 @@ func (c *cLab) createAToBveth(l *Link) error {

func (c *cLab) configVeth(dummyInterface, endpointName, ns string) error {
var cmd *exec.Cmd
var err error
log.Debugf("Disabling TX checksum offloading for the %s interface...", dummyInterface)
err := EthtoolTXOff(dummyInterface)
if err != nil {
return err
}
log.Debugf("map dummy interface '%s' to container %s", dummyInterface, ns)
cmd = exec.Command("sudo", "ip", "link", "set", dummyInterface, "netns", ns)
err = runCmd(cmd)
Expand All @@ -97,12 +101,6 @@ func (c *cLab) configVeth(dummyInterface, endpointName, ns string) error {
if err != nil {
return err
}
log.Debugf("set RX, TX offload off for interface '%s' in NS %s", endpointName, ns)
cmd = exec.Command("docker", "exec", ns, "ethtool", "--offload", endpointName, "rx", "off", "tx", "off")
err = runCmd(cmd)
if err != nil {
return err
}
return nil
}

Expand Down Expand Up @@ -148,9 +146,8 @@ func (c *cLab) createvethToBridge(l *Link) error {
if err != nil {
return err
}
log.Debug("set RX, TX offload off on veth of the bridge interface")
cmd = exec.Command("sudo", "ethtool", "--offload", bridgeIfname, "rx", "off", "tx", "off")
err = runCmd(cmd)
log.Debugf("Disabling TX checksum offloading for the %s interface...", bridgeIfname)
err = EthtoolTXOff(bridgeIfname)
if err != nil {
return err
}
Expand Down

0 comments on commit 2e25ca3

Please sign in to comment.