On Sun, Feb 18, 2018 at 05:43:00PM -0800, Ayaka Koshibe wrote: > Hi, > > These are fixes for various bugs. > > - Repeated output for 'dpctl' CLI command > - Iperf ignoring interrupt from CLI > - DPID value not passed to switch(4) nodes for assignment > - switch(4) nodes with control channels created later in startup won't have > their channels forwarded to a remote controller > - ping tests waiting forever when controller is explicitly disabled > - local forwarding controller not correctly tracked for teardown > - trying to log to extraneous file for switchd(8) node > - wrong method used for getting bridge(4) node info > > OK? > > Thanks and regards, > Ayaka >
ping? > Index: Makefile > =================================================================== > RCS file: /cvs/ports/net/mininet/Makefile,v > retrieving revision 1.6 > diff -u -p -u -r1.6 Makefile > --- Makefile 7 Dec 2017 06:33:40 -0000 1.6 > +++ Makefile 18 Feb 2018 23:24:50 -0000 > @@ -3,7 +3,7 @@ > COMMENT = emulator for rapid prototyping of software defined networks > > DISTNAME = mininet-0.0.20170813 > -REVISION = 3 > +REVISION = 4 > GH_ACCOUNT = mininet > GH_PROJECT = mininet > GH_COMMIT = 87e26ef931ee6063332ceba77db472140f832d3a > Index: patches/patch-mininet_cli_py > =================================================================== > RCS file: /cvs/ports/net/mininet/patches/patch-mininet_cli_py,v > retrieving revision 1.1.1.1 > diff -u -p -u -r1.1.1.1 patch-mininet_cli_py > --- patches/patch-mininet_cli_py 21 Aug 2017 18:47:12 -0000 1.1.1.1 > +++ patches/patch-mininet_cli_py 18 Feb 2018 23:24:50 -0000 > @@ -3,7 +3,24 @@ split() automatically splits on whitespa > Index: mininet/cli.py > --- mininet/cli.py.orig > +++ mininet/cli.py > -@@ -411,7 +411,7 @@ class CLI( Cmd ): > +@@ -356,12 +356,11 @@ class CLI( Cmd ): > + """Run dpctl (or ovs-ofctl) command on all switches. > + Usage: dpctl command [arg1] [arg2] ...""" > + args = line.split() > +- if len(args) < 1: > +- error( 'usage: dpctl command [arg1] [arg2] ...\n' ) > +- return > + for sw in self.mn.switches: > +- output( '*** ' + sw.name + ' ' + ('-' * 72) + '\n' ) > +- output( sw.dpctl( *args ) ) > ++ res = sw.dpctl( *args ) > ++ if res: > ++ output( '*** ' + sw.name + ' ' + ('-' * 72) + '\n' ) > ++ output( res ) > + > + def do_time( self, line ): > + "Measure time taken for any command in Mininet." > +@@ -411,7 +410,7 @@ class CLI( Cmd ): > % first ) > return > node = self.mn[ first ] > Index: patches/patch-mininet_net_py > =================================================================== > RCS file: /cvs/ports/net/mininet/patches/patch-mininet_net_py,v > retrieving revision 1.2 > diff -u -p -u -r1.2 patch-mininet_net_py > --- patches/patch-mininet_net_py 9 Sep 2017 21:18:30 -0000 1.2 > +++ patches/patch-mininet_net_py 18 Feb 2018 23:24:50 -0000 > @@ -3,7 +3,7 @@ $OpenBSD: patch-mininet_net_py,v 1.2 201 > Index: mininet/net.py > --- mininet/net.py.orig > +++ mininet/net.py > -@@ -96,13 +96,27 @@ from time import sleep > +@@ -96,15 +96,29 @@ from time import sleep > from itertools import chain, groupby > from math import ceil > > @@ -19,7 +19,7 @@ Index: mininet/net.py > +else: > + from mininet.openbsd.node import Node > + from mininet.openbsd.intf import Intf > -+ from mininet.openbsd.util import fixLimits, numCores > ++ from mininet.openbsd.util import fixLimits, numCores, waitListening > + > from mininet.cli import CLI > from mininet.log import info, error, debug, output, warn > @@ -30,11 +30,15 @@ Index: mininet/net.py > from mininet.nodelib import NAT > -from mininet.link import Link, Intf > -from mininet.util import ( quietRun, fixLimits, numCores, ensureRoot, > +- macColonHex, ipStr, ipParse, netParse, ipAdd, > +- waitListening ) > +from mininet.link import Link > +from mininet.util import ( quietRun, ensureRoot, > - macColonHex, ipStr, ipParse, netParse, ipAdd, > - waitListening ) > ++ macColonHex, ipStr, ipParse, netParse, ipAdd > ++ ) > from mininet.term import cleanUpScreens, makeTerms > + > + # Mininet version: should be consistent with README and LICENSE > @@ -113,7 +127,7 @@ VERSION = "2.3.0d1" > class Mininet( object ): > "Network emulation with hosts spawned in network namespaces." > @@ -53,24 +57,29 @@ Index: mininet/net.py > iperfArgs = 'iperf -p %d ' % port > bwArgs = '' > if l4Type == 'UDP': > -@@ -817,7 +831,7 @@ class Mininet( object ): > +@@ -817,9 +831,9 @@ class Mininet( object ): > raise Exception( 'Unexpected l4 type: %s' % l4Type ) > if fmt: > iperfArgs += '-f %s ' % fmt > - server.sendCmd( iperfArgs + '-s' ) > + server.cmd( iperfArgs + '-s &' ) > if l4Type == 'TCP': > - if not waitListening( client, server.IP(), port ): > +- if not waitListening( client, server.IP(), port ): > ++ if not waitListening( client, server, port ): > raise Exception( 'Could not connect to iperf on port %d' > -@@ -827,7 +841,7 @@ class Mininet( object ): > + % port ) > + cliout = client.cmd( iperfArgs + '-t %d -c ' % seconds + > +@@ -827,8 +841,8 @@ class Mininet( object ): > debug( 'Client output: %s\n' % cliout ) > servout = '' > # We want the last *b/sec from the iperf server output > - # for TCP, there are two of them because of waitListening > +- count = 2 if l4Type == 'TCP' else 1 > + # for TCP, there are two fo them because of waitListening > - count = 2 if l4Type == 'TCP' else 1 > ++ count = 1 > while len( re.findall( '/sec', servout ) ) < count: > servout += server.monitor( timeoutms=5000 ) > + server.sendInt() > @@ -849,7 +863,7 @@ class Mininet( object ): > pct = cpu * 100 > info( '*** Testing CPU %.0f%% bandwidth limit\n' % pct ) > Index: patches/patch-mininet_node_py > =================================================================== > RCS file: /cvs/ports/net/mininet/patches/patch-mininet_node_py,v > retrieving revision 1.4 > diff -u -p -u -r1.4 patch-mininet_node_py > --- patches/patch-mininet_node_py 7 Dec 2017 06:33:40 -0000 1.4 > +++ patches/patch-mininet_node_py 18 Feb 2018 23:24:51 -0000 > @@ -804,7 +804,7 @@ Index: mininet/node.py > super( OVSSwitch, self ).stop( deleteIntfs ) > > @classmethod > -@@ -1259,9 +800,88 @@ class OVSSwitch( Switch ): > +@@ -1259,9 +800,85 @@ class OVSSwitch( Switch ): > return switches > > > @@ -827,13 +827,14 @@ Index: mininet/node.py > + > + def connected( self ): > + "Are we forwarding yet?" > -+ return self.bname in self.cmd( 'switchctl show switches' ) > ++ return self.bname in self.cmd( 'ifconfig switch' ) > + > + def start( self, controllers ): > + "Start bridge. Retain the bridge's name to save on ifconfig calls" > + rdarg = 'rdomain %d' % self.rdid if self.inNamespace else '' > -+ quietRun( 'ifconfig %s create %s description "%s" up' % > -+ ( self.bname, rdarg, self.name ) ) > ++ dparg = 'datapath 0x%s' % self.dpid > ++ quietRun( 'ifconfig %s create %s %s description "%s" up' % > ++ ( self.bname, dparg, rdarg, self.name ) ) > + addcmd, stpcmd = '', '' > + for i in self.intfList(): > + if i.realname and 'pair' in i.realname: > @@ -843,10 +844,16 @@ Index: mininet/node.py > + quietRun( 'ifconfig ' + self.bname + addcmd ) > + > + # Connect to controller using switchctl(8) using /dev/switch* > ++ if not os.path.exists( self.cdev ): > ++ # try to make character device, check and try to connect again > ++ quietRun( '/dev/MAKEDEV ' + self.bname ) > ++ quietRun( 'mv %s /dev/' % self.bname ) > ++ self.newcdev = True > ++ > + if os.path.exists( self.cdev ): > + args = 'switchctl connect ' + self.cdev > + ctl = controllers[ 0 ] if controllers else None > -+ if not isinstance( ctl, Switchd ): > ++ if ctl and isinstance( ctl, RemoteController ): > + args += ' forward-to %s:%d' % ( ctl.IP(), ctl.port ) > + # start local Switchd instance and have it forward > + if not IfSwitch.local: > @@ -854,26 +861,18 @@ Index: mininet/node.py > + IfSwitch.local.start() > + quietRun( args ) > + else: > -+ # try to make character device, check and try to connect again > -+ quietRun( '/dev/MAKEDEV ' + self.bname ) > -+ quietRun( 'mv %s /dev/' % self.bname ) > -+ self.newcdev = True > -+ if os.path.exists( self.cdev ): > -+ # TODO : need to forward-to for RemoteController > -+ quietRun( 'switchctl connect %s' % self.cdev ) > -+ else: > -+ error( "Can't connect to controller: %s doesn't exist" % > -+ self.cdev ) > -+ exit( 1 ) > ++ error( "Can't connect to controller: %s doesn't exist" % > ++ self.cdev ) > ++ exit( 1 ) > + > + def stop( self, deleteIntfs=True ): > + """Stop bridge > + deleteIntfs: delete interfaces? (True)""" > + quietRun( 'ifconfig %s destroy' % self.bname ) > + # hack: the last switch destroys the local controller > -+ last = 'switch%d' % ( IfSwitch.unitNo - 1 ) > -+ if self.bname == last: > -+ quietRun( 'pkill switchd' ) > ++ if IfSwitch.local: > ++ IfSwitch.local.stop() > ++ IfSwitch.local = None > + if self.newcdev: > + quietRun( 'rm ' + self.cdev ) > + super( IfSwitch, self ).stop( deleteIntfs ) > @@ -881,29 +880,29 @@ Index: mininet/node.py > + def dpctl( self, *args ): > + "Run brctl command" > + # actually switchctl > -+ return self.cmd( 'switchctl', *args ) > ++ # choose the first switch to run switchctl(8) from > ++ if self.bname == 'switch0': > ++ return self.cmd( 'switchctl', *args ) > + > + > -+# technically there are only userspace OF switches for FreeBSD. > -+if plat == 'Linux' or plat == 'FreeBSD': > -+ KernelSwitch = OVSSwitch > -+else: > -+ KernelSwitch = IfSwitch # OpenBSD > ++KernelSwitch = IfSwitch # OpenBSD > + > + > class OVSBridge( OVSSwitch ): > "OVSBridge is an OVSSwitch in standalone/bridge mode" > > -@@ -1386,7 +1006,7 @@ class Controller( Node ): > +@@ -1386,8 +1003,8 @@ class Controller( Node ): > listening = self.cmd( "echo A | telnet -e A %s %d" % > ( self.ip, self.port ) ) > if 'Connected' in listening: > - servers = self.cmd( 'netstat -natp' ).split( '\n' ) > -+ servers = self.cmd( 'netstat -nap tcp' ).split( '\n' ) > - pstr = ':%d ' % self.port > +- pstr = ':%d ' % self.port > ++ servers = self.cmd( 'netstat -nlp tcp' ).split( '\n' ) > ++ pstr = '.%d ' % self.port > clist = servers[ 0:1 ] + [ s for s in servers if pstr in s ] > raise Exception( "Please shut down the controller which is" > -@@ -1405,7 +1025,10 @@ class Controller( Node ): > + " running on port %d:\n" % self.port + > +@@ -1405,7 +1022,10 @@ class Controller( Node ): > self.execed = False > > def stop( self, *args, **kwargs ): > @@ -915,7 +914,7 @@ Index: mininet/node.py > self.cmd( 'kill %' + self.command ) > self.cmd( 'wait %' + self.command ) > super( Controller, self ).stop( *args, **kwargs ) > -@@ -1470,12 +1093,19 @@ class NOX( Controller ): > +@@ -1470,12 +1090,19 @@ class NOX( Controller ): > > class Ryu( Controller ): > "Controller to run Ryu application" > @@ -937,7 +936,7 @@ Index: mininet/node.py > if not ryuArgs: > warn( 'warning: no Ryu modules specified; ' > 'running simple_switch only\n' ) > -@@ -1538,7 +1168,50 @@ class RemoteController( Controller ): > +@@ -1538,7 +1165,53 @@ class RemoteController( Controller ): > else: > return True > > @@ -965,14 +964,17 @@ Index: mininet/node.py > + cargs=cmd, **kwargs ) > + > + def start( self ): > -+ """Start <controller> <args> on controller. Log to /tmp/cN.log""" > ++ """Start <controller> <args> on controller.""" > + pathCheck( self.command ) > -+ cout = '/tmp/' + self.name + '.log' > + if self.cdir is not None: > + self.cmd( 'cd ' + self.cdir ) > -+ self.cmd( self.command + ' ' + self.cargs + > -+ ' 1>' + cout + ' 2>' + cout ) > ++ self.cmd( self.command + ' ' + self.cargs ) > ++ self.ctlpid = quietRun( 'pgrep -n switchd' ) > + self.execed = False > ++ > ++ def stop( self, *args, **kwargs ): > ++ self.cmd( 'kill ' + self.ctlpid ) > ++ super( Node, self ).stop() > + > + > +# TODO: push these uname-ey things elsewhere > Index: patches/patch-mininet_nodelib_py > =================================================================== > RCS file: /cvs/ports/net/mininet/patches/patch-mininet_nodelib_py,v > retrieving revision 1.1.1.1 > diff -u -p -u -r1.1.1.1 patch-mininet_nodelib_py > --- patches/patch-mininet_nodelib_py 21 Aug 2017 18:47:12 -0000 1.1.1.1 > +++ patches/patch-mininet_nodelib_py 18 Feb 2018 23:24:51 -0000 > @@ -130,7 +130,7 @@ Index: mininet/nodelib.py > + def dpctl( self, *args ): > + "Run brctl command" > + # actually ifconfig > -+ return quietRun( 'ifconfig', self.bname, *args ) > ++ return self.cmd( 'ifconfig', self.bname, *args ) > + > + > +class IptablesNAT( Node ): > Index: patches/patch-mininet_openbsd_util_py > =================================================================== > RCS file: /cvs/ports/net/mininet/patches/patch-mininet_openbsd_util_py,v > retrieving revision 1.1.1.1 > diff -u -p -u -r1.1.1.1 patch-mininet_openbsd_util_py > --- patches/patch-mininet_openbsd_util_py 21 Aug 2017 18:47:12 -0000 > 1.1.1.1 > +++ patches/patch-mininet_openbsd_util_py 18 Feb 2018 23:24:51 -0000 > @@ -3,7 +3,7 @@ $OpenBSD: patch-mininet_openbsd_util_py, > Index: mininet/openbsd/util.py > --- mininet/openbsd/util.py.orig > +++ mininet/openbsd/util.py > -@@ -0,0 +1,180 @@ > +@@ -0,0 +1,201 @@ > +""" > +OS-specific utility functions for OpenBSD, counterpart to util.py. > +""" > @@ -184,3 +184,24 @@ Index: mininet/openbsd/util.py > + """Attempt to load a specified module. > + mod: module string""" > + pass > ++ > ++def waitListening( client, server, port=80, timeout=None ): > ++ """Wait until server is listening on port. > ++ returns True if server is listening""" > ++ # pylint: disable=maybe-no-member > ++ serverIP = server.IP().replace('.', '\.') > ++ rdid = 0 if not server.rdid else server.rdid > ++ cmd = ( 'netstat -nlp tcp -T %d | grep -e %s\.%s -e \*\.%s' \ > ++ % ( server.rdid, serverIP, port, port ) ) > ++ time = 0 > ++ result = server.cmd( cmd ) > ++ while 'LISTEN' not in result: > ++ if timeout and time >= timeout: > ++ error( 'could not connect to %s on port %d\n' % ( server, port > ) ) > ++ return False > ++ debug( 'waiting for', server, 'to listen on port', port, '\n' ) > ++ info( '.' ) > ++ sleep( .5 ) > ++ time += .5 > ++ result = server.cmd( cmd ) > ++ return True