rename GSO: hardware->host and software->gVisor

API names such as flags and Makefile targets are unchanged so as not to break
users.

PiperOrigin-RevId: 458279776
This commit is contained in:
Kevin Krakauer
2022-06-30 11:58:10 -07:00
committed by gVisor bot
parent 0c3abacb1c
commit 1eb2c3659d
13 changed files with 65 additions and 62 deletions
+1 -1
View File
@@ -209,7 +209,7 @@ steps:
arch: "amd64"
os: "ubuntu"
- <<: *common
label: ":satellite: SWGSO tests"
label: ":satellite: gVisor GSO tests"
command: make swgso-tests
agents:
arch: "amd64"
+8 -8
View File
@@ -192,8 +192,8 @@ type Options struct {
// disabled.
GSOMaxSize uint32
// SoftwareGSOEnabled indicates whether software GSO is enabled or not.
SoftwareGSOEnabled bool
// GvisorGSOEnabled indicates whether Gvisor GSO is enabled or not.
GvisorGSOEnabled bool
// PacketDispatchMode specifies the type of inbound dispatcher to be
// used for this endpoint.
@@ -295,10 +295,10 @@ func New(opts *Options) (stack.LinkEndpoint, error) {
e.fds = append(e.fds, fdInfo{fd: fd, isSocket: isSocket})
if isSocket {
if opts.GSOMaxSize != 0 {
if opts.SoftwareGSOEnabled {
e.gsoKind = stack.SWGSOSupported
if opts.GvisorGSOEnabled {
e.gsoKind = stack.GvisorGSOSupported
} else {
e.gsoKind = stack.HWGSOSupported
e.gsoKind = stack.HostGSOSupported
}
e.gsoMaxSize = opts.GSOMaxSize
}
@@ -506,7 +506,7 @@ func (e *endpoint) writePacket(pkt *stack.PacketBuffer) tcpip.Error {
fdInfo := e.fds[pkt.Hash%uint32(len(e.fds))]
fd := fdInfo.fd
var vnetHdrBuf []byte
if e.gsoKind == stack.HWGSOSupported {
if e.gsoKind == stack.HostGSOSupported {
vnetHdr := virtioNetHdr{}
if pkt.GSOOptions.Type != stack.GSONone {
vnetHdr.hdrLen = uint16(pkt.HeaderSize())
@@ -577,7 +577,7 @@ func (e *endpoint) sendBatch(batchFDInfo fdInfo, pkts []*stack.PacketBuffer) (in
syscallHeaderBytes := uintptr(0)
for _, pkt := range batch {
var vnetHdrBuf []byte
if e.gsoKind == stack.HWGSOSupported {
if e.gsoKind == stack.HostGSOSupported {
vnetHdr := virtioNetHdr{}
if pkt.GSOOptions.Type != stack.GSONone {
vnetHdr.hdrLen = uint16(pkt.HeaderSize())
@@ -670,7 +670,7 @@ func (e *endpoint) sendBatch(batchFDInfo fdInfo, pkts []*stack.PacketBuffer) (in
// - pkt.NetworkProtocolNumber
func (e *endpoint) WritePackets(pkts stack.PacketBufferList) (int, tcpip.Error) {
// Preallocate to avoid repeated reallocation as we append to batch.
// batchSz is 47 because when SWGSO is in use then a single 65KB TCP
// batchSz is 47 because when GvisorGSO is in use then a single 65KB TCP
// segment can get split into 46 segments of 1420 bytes and a single 216
// byte segment.
const batchSz = 47
+2 -2
View File
@@ -184,7 +184,7 @@ func newReadVDispatcher(fd int, e *endpoint) (linkDispatcher, error) {
fd: fd,
e: e,
}
skipsVnetHdr := d.e.gsoKind == stack.HWGSOSupported
skipsVnetHdr := d.e.gsoKind == stack.HostGSOSupported
d.buf = newIovecBuffer(BufConfig, skipsVnetHdr)
return d, nil
}
@@ -269,7 +269,7 @@ func newRecvMMsgDispatcher(fd int, e *endpoint) (linkDispatcher, error) {
bufs: make([]*iovecBuffer, MaxMsgsPerRecv),
msgHdrs: make([]rawfile.MMsgHdr, MaxMsgsPerRecv),
}
skipsVnetHdr := d.e.gsoKind == stack.HWGSOSupported
skipsVnetHdr := d.e.gsoKind == stack.HostGSOSupported
for i := range d.bufs {
d.bufs[i] = newIovecBuffer(BufConfig, skipsVnetHdr)
}
+13 -11
View File
@@ -1168,9 +1168,9 @@ const (
GSOTCPv4
GSOTCPv6
// GSOSW is used for software GSO segments which have to be sent by
// GSOGvisor is used for gVisor GSO segments which have to be sent by
// endpoint.WritePackets.
GSOSW
GSOGvisor
)
// GSO contains generic segmentation offload properties.
@@ -1193,20 +1193,22 @@ type GSO struct {
MaxSize uint32
}
// SupportedGSO returns the type of segmentation offloading supported.
// SupportedGSO is the type of segmentation offloading supported.
type SupportedGSO int
const (
// GSONotSupported indicates that segmentation offloading is not supported.
GSONotSupported SupportedGSO = iota
// HWGSOSupported indicates that segmentation offloading may be performed by
// the hardware.
HWGSOSupported
// HostGSOSupported indicates that segmentation offloading may be performed
// by the host. This is typically true when netstack is attached to a host
// AF_PACKET socket, and not true when attached to a unix socket or other
// non-networking data layer.
HostGSOSupported
// SWGSOSupported indicates that segmentation offloading may be performed in
// software.
SWGSOSupported
// GvisorGSOSupported indicates that segmentation offloading may be performed
// in gVisor.
GvisorGSOSupported
)
// GSOEndpoint provides access to GSO properties.
@@ -1218,6 +1220,6 @@ type GSOEndpoint interface {
SupportedGSO() SupportedGSO
}
// SoftwareGSOMaxSize is a maximum allowed size of a software GSO segment.
// GvisorGSOMaxSize is a maximum allowed size of a software GSO segment.
// This isn't a hard limit, because it is never set into packet headers.
const SoftwareGSOMaxSize = 1 << 16
const GvisorGSOMaxSize = 1 << 16
+6 -6
View File
@@ -302,18 +302,18 @@ func (r *Route) RequiresTXTransportChecksum() bool {
return r.outgoingNIC.NetworkLinkEndpoint.Capabilities()&CapabilityTXChecksumOffload == 0
}
// HasSoftwareGSOCapability returns true if the route supports software GSO.
func (r *Route) HasSoftwareGSOCapability() bool {
// HasGvisorGSOCapability returns true if the route supports gVisor GSO.
func (r *Route) HasGvisorGSOCapability() bool {
if gso, ok := r.outgoingNIC.NetworkLinkEndpoint.(GSOEndpoint); ok {
return gso.SupportedGSO() == SWGSOSupported
return gso.SupportedGSO() == GvisorGSOSupported
}
return false
}
// HasHardwareGSOCapability returns true if the route supports hardware GSO.
func (r *Route) HasHardwareGSOCapability() bool {
// HasHostGSOCapability returns true if the route supports host GSO.
func (r *Route) HasHostGSOCapability() bool {
if gso, ok := r.outgoingNIC.NetworkLinkEndpoint.(GSOEndpoint); ok {
return gso.SupportedGSO() == HWGSOSupported
return gso.SupportedGSO() == HostGSOSupported
}
return false
}
+1 -1
View File
@@ -900,7 +900,7 @@ func sendTCP(r *stack.Route, tf tcpFields, pkt *stack.PacketBuffer, gso stack.GS
tf.rcvWnd = math.MaxUint16
}
if r.Loop()&stack.PacketLoop == 0 && gso.Type == stack.GSOSW && int(gso.MSS) < pkt.Data().Size() {
if r.Loop()&stack.PacketLoop == 0 && gso.Type == stack.GSOGvisor && int(gso.MSS) < pkt.Data().Size() {
return sendTCPBatch(r, tf, pkt, gso, owner)
}
+5 -5
View File
@@ -3088,7 +3088,7 @@ func (e *endpoint) completeStateLocked(s *stack.TCPEndpointState) {
s.Sender.SpuriousRecovery = e.snd.spuriousRecovery
}
func (e *endpoint) initHardwareGSO() {
func (e *endpoint) initHostGSO() {
switch e.route.NetProto() {
case header.IPv4ProtocolNumber:
e.gso.Type = stack.GSOTCPv4
@@ -3105,12 +3105,12 @@ func (e *endpoint) initHardwareGSO() {
}
func (e *endpoint) initGSO() {
if e.route.HasHardwareGSOCapability() {
e.initHardwareGSO()
} else if e.route.HasSoftwareGSOCapability() {
if e.route.HasHostGSOCapability() {
e.initHostGSO()
} else if e.route.HasGvisorGSOCapability() {
e.gso = stack.GSO{
MaxSize: e.route.GSOMaxSize(),
Type: stack.GSOSW,
Type: stack.GSOGvisor,
NeedsCsum: false,
}
}
@@ -1268,7 +1268,7 @@ func (c *Context) SACKEnabled() bool {
// SetGSOEnabled enables or disables generic segmentation offload.
func (c *Context) SetGSOEnabled(enable bool) {
if enable {
c.linkEP.SupportedGSOKind = stack.HWGSOSupported
c.linkEP.SupportedGSOKind = stack.HostGSOSupported
} else {
c.linkEP.SupportedGSOKind = stack.GSONotSupported
}
+12 -12
View File
@@ -86,17 +86,17 @@ type Neighbor struct {
// FDBasedLink configures an fd-based link.
type FDBasedLink struct {
Name string
MTU int
Addresses []IPWithPrefix
Routes []Route
GSOMaxSize uint32
SoftwareGSOEnabled bool
TXChecksumOffload bool
RXChecksumOffload bool
LinkAddress net.HardwareAddr
QDisc config.QueueingDiscipline
Neighbors []Neighbor
Name string
MTU int
Addresses []IPWithPrefix
Routes []Route
GSOMaxSize uint32
GvisorGSOEnabled bool
TXChecksumOffload bool
RXChecksumOffload bool
LinkAddress net.HardwareAddr
QDisc config.QueueingDiscipline
Neighbors []Neighbor
// NumChannels controls how many underlying FD's are to be used to
// create this endpoint.
@@ -221,7 +221,7 @@ func (n *Network) CreateLinksAndRoutes(args *CreateLinksAndRoutesArgs, _ *struct
Address: mac,
PacketDispatchMode: fdbased.RecvMMsg,
GSOMaxSize: link.GSOMaxSize,
SoftwareGSOEnabled: link.SoftwareGSOEnabled,
GvisorGSOEnabled: link.GvisorGSOEnabled,
TXChecksumOffload: link.TXChecksumOffload,
RXChecksumOffload: link.RXChecksumOffload,
})
+5 -4
View File
@@ -88,11 +88,12 @@ type Config struct {
// AllowPacketEndpointWrite enables write operations on packet endpoints.
AllowPacketEndpointWrite bool `flag:"TESTONLY-allow-packet-endpoint-write"`
// HardwareGSO indicates that hardware segmentation offload is enabled.
HardwareGSO bool `flag:"gso"`
// HostGSO indicates that host segmentation offload is enabled.
HostGSO bool `flag:"gso"`
// SoftwareGSO indicates that software segmentation offload is enabled.
SoftwareGSO bool `flag:"software-gso"`
// GvisorGSO indicates that gVisor segmentation offload is enabled. The flag
// retains its old name of "software" GSO for API consistency.
GvisorGSO bool `flag:"software-gso"`
// TXChecksumOffload indicates that TX Checksum Offload is enabled.
TXChecksumOffload bool `flag:"tx-checksum-offload"`
+2 -2
View File
@@ -90,8 +90,8 @@ func RegisterFlags(flagSet *flag.FlagSet) {
// Flags that control sandbox runtime behavior: network related.
flagSet.Var(networkTypePtr(NetworkSandbox), "network", "specifies which network to use: sandbox (default), host, none. Using network inside the sandbox is more secure because it's isolated from the host network.")
flagSet.Bool("net-raw", false, "enable raw sockets. When false, raw sockets are disabled by removing CAP_NET_RAW from containers (`runsc exec` will still be able to utilize raw sockets). Raw sockets allow malicious containers to craft packets and potentially attack the network.")
flagSet.Bool("gso", true, "enable hardware segmentation offload if it is supported by a network device.")
flagSet.Bool("software-gso", true, "enable software segmentation offload when hardware offload can't be enabled.")
flagSet.Bool("gso", true, "enable host segmentation offload if it is supported by a network device.")
flagSet.Bool("software-gso", true, "enable gVisor segmentation offload when host offload can't be enabled.")
flagSet.Bool("tx-checksum-offload", false, "enable TX checksum offload.")
flagSet.Bool("rx-checksum-offload", true, "enable RX checksum offload.")
flagSet.Var(queueingDisciplinePtr(QDiscFIFO), "qdisc", "specifies which queueing discipline to apply by default to the non loopback nics used by the sandbox.")
+7 -7
View File
@@ -63,7 +63,7 @@ func setupNetwork(conn *urpc.Client, pid int, conf *config.Config) error {
// Build the path to the net namespace of the sandbox process.
// This is what we will copy.
nsPath := filepath.Join("/proc", strconv.Itoa(pid), "ns/net")
if err := createInterfacesAndRoutesFromNS(conn, nsPath, conf.HardwareGSO, conf.SoftwareGSO, conf.TXChecksumOffload, conf.RXChecksumOffload, conf.NumNetworkChannels, conf.QDisc); err != nil {
if err := createInterfacesAndRoutesFromNS(conn, nsPath, conf.HostGSO, conf.GvisorGSO, conf.TXChecksumOffload, conf.RXChecksumOffload, conf.NumNetworkChannels, conf.QDisc); err != nil {
return fmt.Errorf("creating interfaces from net namespace %q: %v", nsPath, err)
}
case config.NetworkHost:
@@ -116,7 +116,7 @@ func isRootNS() (bool, error) {
// createInterfacesAndRoutesFromNS scrapes the interface and routes from the
// net namespace with the given path, creates them in the sandbox, and removes
// them from the host.
func createInterfacesAndRoutesFromNS(conn *urpc.Client, nsPath string, hardwareGSO bool, softwareGSO bool, txChecksumOffload bool, rxChecksumOffload bool, numNetworkChannels int, qDisc config.QueueingDiscipline) error {
func createInterfacesAndRoutesFromNS(conn *urpc.Client, nsPath string, hostGSO bool, gvisorGSO bool, txChecksumOffload bool, rxChecksumOffload bool, numNetworkChannels int, qDisc config.QueueingDiscipline) error {
// Join the network namespace that we will be copying.
restore, err := joinNetNS(nsPath)
if err != nil {
@@ -235,7 +235,7 @@ func createInterfacesAndRoutesFromNS(conn *urpc.Client, nsPath string, hardwareG
// Create the socket for the device.
for i := 0; i < link.NumChannels; i++ {
log.Debugf("Creating Channel %d", i)
socketEntry, err := createSocket(iface, ifaceLink, hardwareGSO)
socketEntry, err := createSocket(iface, ifaceLink, hostGSO)
if err != nil {
return fmt.Errorf("failed to createSocket for %s : %w", iface.Name, err)
}
@@ -250,10 +250,10 @@ func createInterfacesAndRoutesFromNS(conn *urpc.Client, nsPath string, hardwareG
args.FilePayload.Files = append(args.FilePayload.Files, socketEntry.deviceFile)
}
if link.GSOMaxSize == 0 && softwareGSO {
// Hardware GSO is disabled. Let's enable software GSO.
link.GSOMaxSize = stack.SoftwareGSOMaxSize
link.SoftwareGSOEnabled = true
if link.GSOMaxSize == 0 && gvisorGSO {
// Host GSO is disabled. Let's enable gVisor GSO.
link.GSOMaxSize = stack.GvisorGSOMaxSize
link.GvisorGSOEnabled = true
}
// Collect the addresses for the interface, enable forwarding,
+2 -2
View File
@@ -59,7 +59,7 @@ var (
moderateRecvBuf = flag.Bool("moderate_recv_buf", false, "enable TCP Receive Buffer Auto-tuning")
cubic = flag.Bool("cubic", false, "enable use of CUBIC congestion control for netstack")
gso = flag.Int("gso", 0, "GSO maximum size")
swgso = flag.Bool("swgso", false, "software-level GSO")
swgso = flag.Bool("swgso", false, "gVisor-level GSO")
clientTCPProbeFile = flag.String("client_tcp_probe_file", "", "if specified, installs a tcp probe to dump endpoint state to the specified file.")
serverTCPProbeFile = flag.String("server_tcp_probe_file", "", "if specified, installs a tcp probe to dump endpoint state to the specified file.")
cpuprofile = flag.String("cpuprofile", "", "write cpu profile to the specified file.")
@@ -200,7 +200,7 @@ func newNetstackImpl(mode string) (impl, error) {
RXChecksumOffload: true,
PacketDispatchMode: fdbased.RecvMMsg,
GSOMaxSize: uint32(*gso),
SoftwareGSOEnabled: *swgso,
GvisorGSOEnabled: *swgso,
})
if err != nil {
return nil, fmt.Errorf("failed to create FD endpoint: %v", err)