Add TCULink and make it the default for --switch user

For some time, UserSwitch has suffered from abysmal performance due
to rx and tx offload settings. In the latest Ubuntu 16.04/Linux 4.4
kernel, it simply doesn't work with the default settings, since
packets with bad TCP checksums are generated at one end, passed through
the user switch, and dropped at the other. It doesn't seem to be
something we can fix in UserSwitch itself although it may be possible
to do something in the C code of the Stanford reference switch and
CPqD switch.
This commit is contained in:
Bob Lantz
2016-09-20 12:43:27 -07:00
parent 0f9c1b33c7
commit 8def6752f3
2 changed files with 57 additions and 10 deletions
+12 -4
View File
@@ -30,7 +30,7 @@ from mininet.node import ( Host, CPULimitedHost, Controller, OVSController,
UserSwitch, OVSSwitch, OVSBridge,
IVSSwitch )
from mininet.nodelib import LinuxBridge
from mininet.link import Link, TCLink, OVSLink
from mininet.link import Link, TCLink, TCULink, OVSLink
from mininet.topo import ( SingleSwitchTopo, LinearTopo,
SingleSwitchReversedTopo, MinimalTopo )
from mininet.topolib import TreeTopo, TorusTopo
@@ -73,18 +73,18 @@ HOSTS = { 'proc': Host,
'cfs': specialClass( CPULimitedHost, defaults=dict( sched='cfs' ) ) }
CONTROLLERDEF = 'default'
CONTROLLERS = { 'ref': Controller,
'ovsc': OVSController,
'nox': NOX,
'remote': RemoteController,
'ryu': Ryu,
'default': DefaultController, # Note: replaced below
'default': DefaultController, # Note: overridden below
'none': NullController }
LINKDEF = 'default'
LINKS = { 'default': Link,
LINKS = { 'default': Link, # Note: overridden below
'tc': TCLink,
'tcu': TCULink,
'ovs': OVSLink }
# TESTS dict can contain functions and/or Mininet() method names
@@ -341,11 +341,19 @@ class MininetRunner( object ):
"for switch %s" %
opts.switch )
topo = buildTopo( TOPOS, opts.topo )
switch = customClass( SWITCHES, opts.switch )
host = customClass( HOSTS, opts.host )
controller = [ customClass( CONTROLLERS, c )
for c in opts.controller ]
if opts.switch == 'user' and opts.link == 'default':
debug( '*** Using TCULink with UserSwitch\n' )
# Use link configured correctly for UserSwitch
opts.link = 'tcu'
link = customClass( LINKS, opts.link )
if self.validate:
+45 -6
View File
@@ -313,16 +313,40 @@ class TCIntf( Intf ):
return self.cmd( c )
def config( self, bw=None, delay=None, jitter=None, loss=None,
disable_gro=True, speedup=0, use_hfsc=False, use_tbf=False,
gro=False, txo=True, rxo=True,
speedup=0, use_hfsc=False, use_tbf=False,
latency_ms=None, enable_ecn=False, enable_red=False,
max_queue_size=None, **params ):
"Configure the port and set its properties."
"""Configure the port and set its properties.
bw: bandwidth in b/s (e.g. '10m')
delay: transmit delay (e.g. '1ms' )
jitter: jitter (e.g. '1ms')
loss: loss (e.g. '1%' )
gro: enable GRO (False)
txo: enable transmit checksum offload (True)
rxo: enable receive checksum offload (True)
speedup: experimental switch-side bw option
use_hfsc: use HFSC scheduling
use_tbf: use TBF scheduling
latency_ms: TBF latency parameter
enable_ecn: enable ECN (False)
enable_red: enable RED (False)
max_queue_size: queue limit parameter for netem"""
# Support old names for parameters
gro = not params.pop( 'disable_gro', not gro )
result = Intf.config( self, **params)
# Disable GRO
if disable_gro:
self.cmd( 'ethtool -K %s gro off' % self )
def on( isOn ):
"Helper method: bool -> 'on'/'off'"
return 'on' if isOn else 'off'
# Set offload parameters with ethool
self.cmd( 'ethtool -K', self,
'gro', on( gro ),
'tx', on( txo ),
'rx', on( rxo ) )
# Optimization: return if nothing else to configure
# Question: what happens if we want to reset things?
@@ -476,7 +500,7 @@ class Link( object ):
self.intf1 = None
self.intf2.delete()
self.intf2 = None
def stop( self ):
"Override to stop and clean up link as needed"
self.delete()
@@ -535,3 +559,18 @@ class TCLink( Link ):
addr1=addr1, addr2=addr2,
params1=params,
params2=params )
class TCULink( TCLink ):
"""TCLink with default settings optimized for UserSwitch
(txo=rxo=0/False). Unfortunately with recent Linux kernels,
enabling TX and RX checksum offload on veth pairs doesn't work
well with UserSwitch: either it gets terrible performance or
TCP packets with bad checksums are generated, forwarded, and
*dropped* due to having bad checksums! OVS and LinuxBridge seem
to cope with this somehow, but it is likely to be an issue with
many software Ethernet bridges."""
def __init__( self, *args, **kwargs ):
kwargs.update( txo=False, rxo=False )
TCLink.__init__( self, *args, **kwargs )