On Sat, Apr 07, 2018 at 05:50:54PM -0700, Ayaka Koshibe wrote: > 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. How about these on top of your diff:
Use CFLAGS in do-build, enabling DEBUG. Compact .for loops in targets to smaller brace expansion. IMO the examples/ path is clear enough, so I also avoided renaming switchd.conf. Set SEPARATE_BUILD since you're already using WRKSRC and WRKBUILD accordingly. Feedback? Maybe also use the latest git commit instead of bumping revision? Index: Makefile =================================================================== RCS file: /cvs/ports/net/mininet/Makefile,v retrieving revision 1.6 diff -u -p -r1.6 Makefile --- Makefile 7 Dec 2017 06:33:40 -0000 1.6 +++ Makefile 8 Apr 2018 17:16:12 -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 @@ -18,33 +18,32 @@ MAINTAINER = Ayaka Koshibe <akoshibe@gma PERMIT_PACKAGE_CDROM = Yes WANTLIB = c + MODULES = lang/python MODPY_SETUPTOOLS = Yes BUILD_DEPENDS = devel/help2man RUN_DEPENDS = net/socat \ net/iperf +SEPARATE_BUILD = Yes + do-build: - $(CC) ${WRKSRC}/mnexec.c -o ${WRKBUILD}/mnexec + ${CC} ${CFLAGS} ${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 pre-install: ${INSTALL_PROGRAM} ${WRKBUILD}/mnexec ${PREFIX}/bin -.for m in mnexec mn - ${INSTALL_MAN} ${WRKBUILD}/$m.1 ${PREFIX}/man/man1 -.endfor + ${INSTALL_MAN} ${WRKBUILD}/{mnexec,mn}.1 ${PREFIX}/man/man1 ${INSTALL_DATA_DIR} ${PREFIX}/share/doc/mininet ${INSTALL_DATA} ${WRKBUILD}/README.md ${PREFIX}/share/doc/mininet post-install: ${INSTALL_DATA_DIR} ${PREFIX}/share/examples/mininet - ${INSTALL_DATA} ${WRKSRC}/util/switchd.conf \ - ${PREFIX}/share/examples/mininet/switchd.mininet.conf-sample -.for f in examples/README.md examples/*.py - ${INSTALL_DATA} ${WRKSRC}/$f ${PREFIX}/share/examples/mininet -.endfor + ${INSTALL_DATA} ${WRKSRC}/{examples{README.md,*.py},util/switchd.conf} \ + ${PREFIX}/share/examples/mininet .include <bsd.port.mk> 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 -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 8 Apr 2018 17:16:12 -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 -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 8 Apr 2018 17:16:12 -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 -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 8 Apr 2018 17:16:12 -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 -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 8 Apr 2018 17:16:12 -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 -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 8 Apr 2018 17:16:12 -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