diff --git a/mininet/link.py b/mininet/link.py index 3e325380ef2779abef042dd8e47a2c02a2687ebe..e9df6cc85c8f84234fda2bd0a9b05c198e2ca878 100644 --- a/mininet/link.py +++ b/mininet/link.py @@ -32,7 +32,7 @@ class Intf( object ): "Basic interface object that can configure itself." - def __init__( self, name, node=None, port=None, link=None, **params ): + def __init__( self, name, node=None, port=None, link=None, mac=None, **params ): """name: interface name (e.g. h1-eth0) node: owning node (where this intf most likely lives) link: parent link if we're part of a link @@ -40,7 +40,10 @@ def __init__( self, name, node=None, port=None, link=None, **params ): self.node = node self.name = name self.link = link - self.mac, self.ip, self.prefixLen = None, None, None + self.mac = mac + self.ip, self.prefixLen = None, None + if self.name == 'lo': + self.ip = '127.0.0.1' # Add to node (and move ourselves if necessary ) node.addIntf( self, port=port ) # Save params for future reference @@ -147,7 +150,6 @@ def setParam( self, results, method, **param ): def updateAddr( self ): "instead of updating ip and mac separately, use one ifconfig call to do it simultaneously" ifconfig = self.ifconfig() - print ifconfig ips = self._ipMatchRegex.findall( ifconfig ) macs = self._macMatchRegex.findall( ifconfig ) self.ip = ips[ 0 ] if ips else None @@ -170,7 +172,6 @@ def config( self, mac=None, ip=None, ifconfig=None, self.setParam( r, 'setIP', ip=ip ) self.setParam( r, 'isUp', up=up ) self.setParam( r, 'ifconfig', ifconfig=ifconfig ) - #should combine these next two operations into one. this is unecessary #self.updateAddr() #self.updateIP() #self.updateMAC() @@ -339,7 +340,7 @@ class Link( object ): Other types of links could be tunnels, link emulators, etc..""" def __init__( self, node1, node2, port1=None, port2=None, - intfName1=None, intfName2=None, + intfName1=None, intfName2=None, addr1=None, addr2=None, intf=Intf, cls1=None, cls2=None, params1=None, params2=None ): """Create veth link to another node, making two new interfaces. @@ -365,7 +366,7 @@ def __init__( self, node1, node2, port1=None, port2=None, if not intfName2: intfName2 = self.intfName( node2, port2 ) - self.makeIntfPair( intfName1, intfName2 ) + self.makeIntfPair( intfName1, intfName2, addr1, addr2 ) if not cls1: cls1 = intf @@ -377,9 +378,9 @@ def __init__( self, node1, node2, port1=None, port2=None, params2 = {} intf1 = cls1( name=intfName1, node=node1, port=port1, - link=self, **params1 ) + link=self, mac=addr1, **params1 ) intf2 = cls2( name=intfName2, node=node2, port=port2, - link=self, **params2 ) + link=self, mac=addr2, **params2 ) # All we are is dust in the wind, and our two interfaces self.intf1, self.intf2 = intf1, intf2 @@ -390,13 +391,13 @@ def intfName( cls, node, n ): return node.name + '-eth' + repr( n ) @classmethod - def makeIntfPair( cls, intf1, intf2 ): + def makeIntfPair( cls, intf1, intf2, addr1=None, addr2=None ): """Create pair of interfaces intf1: name of interface 1 intf2: name of interface 2 (override this class method [and possibly delete()] to change link type)""" - makeIntfPair( intf1, intf2 ) + makeIntfPair( intf1, intf2, addr1, addr2 ) def delete( self ): "Delete this link" diff --git a/mininet/net.py b/mininet/net.py index 4224b974dacef4b24a20cb77f99a5cc09f1e9685..5be34f8a31df688a1033bfc803758931f7885c1a 100755 --- a/mininet/net.py +++ b/mininet/net.py @@ -90,6 +90,7 @@ import re import select import signal +import random import copy from time import sleep from itertools import chain, groupby @@ -101,7 +102,7 @@ from mininet.util import quietRun, fixLimits, numCores, ensureRoot from mininet.util import macColonHex, ipStr, ipParse, netParse, ipAdd from mininet.term import cleanUpScreens, makeTerms -from multiprocessing.pool import ThreadPool +from multiprocessing import Process # Mininet version: should be consistent with README and LICENSE VERSION = "2.1.0+" @@ -160,7 +161,7 @@ def __init__( self, topo=None, switch=OVSKernelSwitch, host=Host, self.terms = [] # list of spawned xterm processes - self.pool = ThreadPool( 64 ) + #self.pool = Pool( 64 ) Mininet.init() # Initialize Mininet if necessary @@ -306,6 +307,21 @@ def items( self ): "return (key,value) tuple list for every node in net" return zip( self.keys(), self.values() ) + def generateMac( self ): + newMac = True + while True: + macList = [ 0x00 ] + for i in xrange ( 0, 5 ): + macList.append( random.randint( 0x00, 0xff ) ) + mac = ':'.join( map(lambda x: "%02x" % x, macList ) ) + for node in self.switches + self.hosts: + for intf in node.ports: + if intf.mac == mac: + newMac = False + break + if newMac: + return mac + def addLink( self, node1, node2, port1=None, port2=None, cls=None, **params ): """"Add a link from node1 to node2 @@ -314,8 +330,12 @@ def addLink( self, node1, node2, port1=None, port2=None, port1: source port port2: dest port returns: link object""" + mac1 = self.generateMac() + mac2 = self.generateMac() defaults = { 'port1': port1, 'port2': port2, + 'addr1': mac1, + 'addr2': mac2, 'intf': self.intf } defaults.update( params ) if not cls: @@ -383,8 +403,7 @@ def buildFromTopo( self, topo=None ): params = topo.linkInfo( srcName, dstName ) srcPort, dstPort = topo.port( srcName, dstName ) self.addLink( src, dst, srcPort, dstPort, **params ) - #self.pool.apply( self.addLink, ( src, dst, srcPort, dstPort, params, ) ) - #self.pool.apply_async( self.addLink, args = ( src, dst )+ params, kwds = { 'Port1':srcPort, 'Port2':dstPort } ) + #self.pool.apply_async( self.addLink, ( src, dst, srcPort, dstPort, params ) ) info( '(%s, %s) ' % ( src.name, dst.name ) ) #self.pool.close() #self.pool.join() diff --git a/mininet/node.py b/mininet/node.py index d9052fab7e6f1a8a5134044edc6f869e08e2a05a..bf1afb9f30b206b39a7b0a2ab54596de0ddddc61 100644 --- a/mininet/node.py +++ b/mininet/node.py @@ -1082,11 +1082,9 @@ def start( self, controllers ): if self.inNamespace: raise Exception( 'OVS kernel switch does not work in a namespace' ) - # We should probably call config instead, but this - # requires some rethinking... - self.cmd( 'ifconfig lo up' ) # Annoyingly, --if-exists option seems not to work - self.cmd( 'ovs-vsctl del-br', self ) + self.sendCmd( 'ovs-vsctl del-br', self ) + self.waiting = False int( self.dpid, 16 ) # DPID must be a hex string # Interfaces and controllers intfs = ' '.join( '-- add-port %s %s ' % ( self, intf ) + @@ -1107,10 +1105,12 @@ def start( self, controllers ): '-- set-controller %s %s ' % ( self, clist ) ) # Construct ovs-vsctl commands for old versions of OVS else: - self.cmd( 'ovs-vsctl add-br', self ) + self.sendCmd( 'ovs-vsctl add-br', self ) + self.waiting = False for intf in self.intfList(): if not intf.IP(): - self.cmd( 'ovs-vsctl add-port', self, intf ) + self.sendCmd( 'ovs-vsctl add-port', self, intf ) + self.waiting = False cmd = ( 'ovs-vsctl set Bridge %s ' % self + 'other_config:datapath-id=%s ' % self.dpid + '-- set-fail-mode %s %s ' % ( self, self.failMode ) + diff --git a/mininet/util.py b/mininet/util.py index b4d213a046d78373bf09ce9b00b51208f38fd35b..1a866fab641d8b6fdcc7edaa6d244843c70a87f0 100644 --- a/mininet/util.py +++ b/mininet/util.py @@ -147,7 +147,7 @@ def isShellBuiltin( cmd ): # live in the root namespace and thus do not have to be # explicitly moved. -def makeIntfPair( intf1, intf2 ): +def makeIntfPair( intf1, intf2, addr1=None, addr2=None ): """Make a veth pair connecting intf1 and intf2. intf1: string, interface intf2: string, interface @@ -156,7 +156,11 @@ def makeIntfPair( intf1, intf2 ): quietRun( 'ip link del ' + intf1 ) quietRun( 'ip link del ' + intf2 ) # Create new pair - cmd = 'ip link add name ' + intf1 + ' type veth peer name ' + intf2 + if addr1 is None and addr2 is None: + cmd = 'ip link add name ' + intf1 + ' type veth peer name ' + intf2 + else: + cmd = ( 'ip link add name ' + intf1 + ' address ' + addr1 + + ' type veth peer name ' + intf2 + ' address ' + addr2 ) cmdOutput = quietRun( cmd ) if cmdOutput == '': return True