And I found the manpage for mn isn't generated properly during last-minute
testing...
Updated Makefile diff, plus cleanup to run MAKEDEV in /dev, rather than create
and move a file, as suggested by phessler.
Thanks,
Ayaka
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 7 Apr 2018 23:42:39 -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
@@ -27,7 +27,8 @@ RUN_DEPENDS = net/socat \
do-build:
$(CC) ${WRKSRC}/mnexec.c -o ${WRKBUILD}/mnexec
help2man -N -n "create a Mininet network." --no-discard-stderr \
- "${MODPY_BIN} -B ${WRKBUILD}/bin/mn" -o ${WRKBUILD}/mn.1
+ "PYTHONPATH=${WRKBUILD} ${MODPY_BIN} -B ${WRKBUILD}/bin/mn" \
+ -o ${WRKBUILD}/mn.1
help2man -N -n "execution utility for Mininet." -h "-h" -v "-v" \
--no-discard-stderr ${WRKBUILD}/mnexec -o ${WRKBUILD}/mnexec.1
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 7 Apr 2018 23:42:39 -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 7 Apr 2018 23:42:39 -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 7 Apr 2018 23:42:39 -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,84 @@ 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,15 @@ 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
++ self.cmd( 'cd /dev/ && ./MAKEDEV ' + 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 +860,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 +879,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 +1002,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 +1021,10 @@ class Controller( Node ):
self.execed = False
def stop( self, *args, **kwargs ):
@@ -915,7 +913,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 +1089,19 @@ class NOX( Controller ):
class Ryu( Controller ):
"Controller to run Ryu application"
@@ -937,7 +935,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 +1164,53 @@ class RemoteController( Controller ):
else:
return True
@@ -965,14 +963,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 7 Apr 2018 23:42:39 -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 7 Apr 2018 23:42:39 -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