Allow various subsets of (delay, bw, loss) and clean up status output.
This commit is contained in:
+62
-55
@@ -33,11 +33,11 @@ class Intf( object ):
|
|||||||
|
|
||||||
"Basic interface object that can configure itself."
|
"Basic interface object that can configure itself."
|
||||||
|
|
||||||
def __init__( self, node, name=None, link=None, **kwargs ):
|
def __init__( self, name, node=None, link=None, **kwargs ):
|
||||||
"""node: owning node (where this intf most likely lives)
|
"""name: interface name (e.g. h1-eth0)
|
||||||
name: interface name (e.g. h1-eth0)
|
node: owning node (where this intf most likely lives)
|
||||||
link: parent link if any
|
link: parent link if we're part of a link
|
||||||
other arguments are used to configure link parameters"""
|
other arguments are passed to config()"""
|
||||||
self.node = node
|
self.node = node
|
||||||
self.name = name
|
self.name = name
|
||||||
self.link = link
|
self.link = link
|
||||||
@@ -152,9 +152,9 @@ class Intf( object ):
|
|||||||
class TCIntf( Intf ):
|
class TCIntf( Intf ):
|
||||||
"Interface customized by tc (traffic control) utility"
|
"Interface customized by tc (traffic control) utility"
|
||||||
|
|
||||||
def config( self, bw=None, delay=None, loss=0, disable_gro=True,
|
def config( self, bw=None, delay=None, loss=None, disable_gro=True,
|
||||||
speedup=0, use_hfsc=False, use_tbf=False, enable_ecn=False,
|
speedup=0, use_hfsc=False, use_tbf=False, enable_ecn=False,
|
||||||
enable_red=False, max_queue_size=1000, **params ):
|
enable_red=False, max_queue_size=None, **params ):
|
||||||
"Configure the port and set its properties."
|
"Configure the port and set its properties."
|
||||||
|
|
||||||
result = Intf.config( self, **params)
|
result = Intf.config( self, **params)
|
||||||
@@ -163,7 +163,8 @@ class TCIntf( Intf ):
|
|||||||
if disable_gro:
|
if disable_gro:
|
||||||
self.cmd( 'ethtool -K %s gro off' % self )
|
self.cmd( 'ethtool -K %s gro off' % self )
|
||||||
|
|
||||||
if bw is None and not delay and not loss:
|
if ( bw is None and not delay and not loss
|
||||||
|
and max_queue_size is None ):
|
||||||
return
|
return
|
||||||
|
|
||||||
if bw and ( bw < 0 or bw > 1000 ):
|
if bw and ( bw < 0 or bw > 1000 ):
|
||||||
@@ -177,59 +178,65 @@ class TCIntf( Intf ):
|
|||||||
if loss and ( loss < 0 or loss > 100 ):
|
if loss and ( loss < 0 or loss > 100 ):
|
||||||
error( 'Bad loss percentage', loss, '%%\n' )
|
error( 'Bad loss percentage', loss, '%%\n' )
|
||||||
return
|
return
|
||||||
|
|
||||||
if delay is None:
|
# Ugly but functional
|
||||||
delay = '0ms'
|
stuff = ( ( [ '%.2fMbit' % bw ] if bw is not None else [] ) +
|
||||||
|
( [ '%s delay' % delay ] if delay is not None else [] ) +
|
||||||
if bw is not None and delay is not None:
|
( ['%d%% loss' % loss ] if loss is not None else [] ) +
|
||||||
info( self, '(bw %.2fMbit, delay %s, loss %d%%) ' %
|
( [ 'ECN' ] if enable_ecn else [ 'RED' ] if enable_red else [] ) )
|
||||||
( bw, delay, loss ) )
|
info( '(' + ' '.join( stuff ) + ') ' )
|
||||||
|
|
||||||
# BL: hmm... what exactly is this???
|
cmds = [ '%s qdisc del dev %s root' ]
|
||||||
# This seems kind of brittle
|
|
||||||
if speedup > 0 and self.node.name[0:2] == 'sw':
|
|
||||||
bw = speedup
|
|
||||||
|
|
||||||
tc = 'tc' # was getCmd( 'tc' )
|
tc = 'tc' # was getCmd( 'tc' )
|
||||||
|
|
||||||
# Bandwidth control algorithms
|
# Bandwidth control algorithms
|
||||||
if use_hfsc:
|
if bw is None:
|
||||||
cmds = [ '%s qdisc del dev %s root',
|
parent = ' root '
|
||||||
'%s qdisc add dev %s root handle 1:0 hfsc default 1' ]
|
|
||||||
if bw is not None:
|
|
||||||
cmds.append( '%s class add dev %s parent 1:0 classid 1:1 hfsc sc ' +
|
|
||||||
'rate %fMbit ul rate %fMbit' % ( bw, bw ) )
|
|
||||||
elif use_tbf:
|
|
||||||
latency_us = 10 * 1500 * 8 / bw
|
|
||||||
cmds = ['%s qdisc del dev %s root',
|
|
||||||
'%s qdisc add dev %s root handle 1: tbf ' +
|
|
||||||
'rate %fMbit burst 15000 latency %fus' % (bw, latency_us) ]
|
|
||||||
else:
|
else:
|
||||||
cmds = [ '%s qdisc del dev %s root',
|
parent = ' parent 1:1 '
|
||||||
'%s qdisc add dev %s root handle 1:0 htb default 1',
|
# BL: hmm... this seems a bit brittle
|
||||||
'%s class add dev %s parent 1:0 classid 1:1 htb ' +
|
if speedup > 0 and self.node.name[0:2] == 'sw':
|
||||||
'rate %fMbit burst 15k' % bw ]
|
bw = speedup
|
||||||
|
if use_hfsc:
|
||||||
|
cmds += [ '%s qdisc add dev %s root handle 1:0 hfsc default 1',
|
||||||
|
'%s class add dev %s parent 1:0 classid 1:1 hfsc sc ' +
|
||||||
|
'rate %fMbit ul rate %fMbit' % ( bw, bw ) ]
|
||||||
|
elif use_tbf:
|
||||||
|
latency_us = 10 * 1500 * 8 / bw
|
||||||
|
cmds += ['%s qdisc add dev %s root handle 1: tbf ' +
|
||||||
|
'rate %fMbit burst 15000 latency %fus' % (bw, latency_us) ]
|
||||||
|
else:
|
||||||
|
cmds += [ '%s qdisc add dev %s root handle 1:0 htb default 1',
|
||||||
|
'%s class add dev %s parent 1:0 classid 1:1 htb ' +
|
||||||
|
'rate %fMbit burst 15k' % bw ]
|
||||||
|
parent = ' parent 1:1 '
|
||||||
|
|
||||||
|
# ECN or RED
|
||||||
|
if enable_ecn:
|
||||||
|
cmds += [ '%s qdisc add dev %s' + parent +
|
||||||
|
'handle 10: red limit 1000000 '+
|
||||||
|
'min 20000 max 25000 avpkt 1000 '+
|
||||||
|
'burst 20 '+
|
||||||
|
'bandwidth %fmbit probability 1 ecn' % bw ]
|
||||||
|
parent = ' parent 10: '
|
||||||
|
elif enable_red:
|
||||||
|
cmds += [ '%s qdisc add dev %s' + parent +
|
||||||
|
'handle 10: red limit 1000000 '+
|
||||||
|
'min 20000 max 25000 avpkt 1000 '+
|
||||||
|
'burst 20 '+
|
||||||
|
'bandwidth %fmbit probability 1' % bw ]
|
||||||
|
parent = ' parent 10: '
|
||||||
|
|
||||||
|
# Delay/loss/max queue size
|
||||||
|
netemargs = '%s%s%s' % (
|
||||||
|
'delay %s ' % delay if delay is not None else '',
|
||||||
|
'loss %d ' % loss if loss is not None else '',
|
||||||
|
'limit %d' % max_queue_size if max_queue_size is not None else '' )
|
||||||
|
if netemargs:
|
||||||
|
cmds += [ '%s qdisc add dev %s ' + parent + ' netem ' +
|
||||||
|
netemargs ]
|
||||||
|
|
||||||
# ECN or RED
|
|
||||||
if enable_ecn:
|
|
||||||
info( 'Enabling ECN\n' )
|
|
||||||
cmds += [ '%s qdisc add dev %s parent 1:1 '+
|
|
||||||
'handle 10: red limit 1000000 '+
|
|
||||||
'min 20000 max 25000 avpkt 1000 '+
|
|
||||||
'burst 20 '+
|
|
||||||
'bandwidth %fmbit probability 1 ecn' % bw ]
|
|
||||||
elif enable_red:
|
|
||||||
info( 'Enabling RED\n' )
|
|
||||||
cmds += [ '%s qdisc add dev %s parent 1:1 '+
|
|
||||||
'handle 10: red limit 1000000 '+
|
|
||||||
'min 20000 max 25000 avpkt 1000 '+
|
|
||||||
'burst 20 '+
|
|
||||||
'bandwidth %fmbit probability 1' % bw ]
|
|
||||||
else:
|
|
||||||
cmds += [ '%s qdisc add dev %s parent 1:1 handle 10:0 netem ' +
|
|
||||||
'delay ' + '%s' % delay + ' loss ' + '%d' % loss +
|
|
||||||
' limit %d' % (max_queue_size) ]
|
|
||||||
|
|
||||||
# Execute all the commands in the container
|
# Execute all the commands in the container
|
||||||
debug("at map stage w/cmds: %s\n" % cmds)
|
debug("at map stage w/cmds: %s\n" % cmds)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user