Add support for specifying host IP range with --ipbase.
This commit is contained in:
@@ -192,6 +192,8 @@ class MininetRunner( object ):
|
|||||||
help='|'.join( TESTS ) )
|
help='|'.join( TESTS ) )
|
||||||
opts.add_option( '--xterms', '-x', action='store_true',
|
opts.add_option( '--xterms', '-x', action='store_true',
|
||||||
default=False, help='spawn xterms for each node' )
|
default=False, help='spawn xterms for each node' )
|
||||||
|
opts.add_option( '--ipbase', '-i', type='string', default='10.0.0.0/8',
|
||||||
|
help='base IP address for hosts' )
|
||||||
opts.add_option( '--mac', action='store_true',
|
opts.add_option( '--mac', action='store_true',
|
||||||
default=False, help='automatically set host MACs' )
|
default=False, help='automatically set host MACs' )
|
||||||
opts.add_option( '--arp', action='store_true',
|
opts.add_option( '--arp', action='store_true',
|
||||||
@@ -248,6 +250,7 @@ class MininetRunner( object ):
|
|||||||
self.validate( self.options )
|
self.validate( self.options )
|
||||||
|
|
||||||
inNamespace = self.options.innamespace
|
inNamespace = self.options.innamespace
|
||||||
|
ipBase = self.options.ipbase
|
||||||
xterms = self.options.xterms
|
xterms = self.options.xterms
|
||||||
mac = self.options.mac
|
mac = self.options.mac
|
||||||
arp = self.options.arp
|
arp = self.options.arp
|
||||||
@@ -257,6 +260,7 @@ class MininetRunner( object ):
|
|||||||
mn = Mininet( topo=topo,
|
mn = Mininet( topo=topo,
|
||||||
switch=switch, host=host, controller=controller,
|
switch=switch, host=host, controller=controller,
|
||||||
intf=intf,
|
intf=intf,
|
||||||
|
ipBase=ipBase,
|
||||||
inNamespace=inNamespace,
|
inNamespace=inNamespace,
|
||||||
xterms=xterms, autoSetMacs=mac,
|
xterms=xterms, autoSetMacs=mac,
|
||||||
autoStaticArp=arp, listenPort=listenPort )
|
autoStaticArp=arp, listenPort=listenPort )
|
||||||
|
|||||||
+8
-3
@@ -97,7 +97,7 @@ from mininet.log import info, error, debug, output
|
|||||||
from mininet.node import Host, OVSKernelSwitch, Controller
|
from mininet.node import Host, OVSKernelSwitch, Controller
|
||||||
from mininet.link import Link
|
from mininet.link import Link
|
||||||
from mininet.util import quietRun, fixLimits
|
from mininet.util import quietRun, fixLimits
|
||||||
from mininet.util import macColonHex, ipStr, ipParse
|
from mininet.util import macColonHex, ipStr, ipParse, netParse
|
||||||
from mininet.term import cleanUpScreens, makeTerms
|
from mininet.term import cleanUpScreens, makeTerms
|
||||||
|
|
||||||
class Mininet( object ):
|
class Mininet( object ):
|
||||||
@@ -105,7 +105,7 @@ class Mininet( object ):
|
|||||||
|
|
||||||
def __init__( self, topo=None, switch=OVSKernelSwitch, host=Host,
|
def __init__( self, topo=None, switch=OVSKernelSwitch, host=Host,
|
||||||
controller=Controller, link=Link, intf=None,
|
controller=Controller, link=Link, intf=None,
|
||||||
build=True, xterms=False, cleanup=False,
|
build=True, xterms=False, cleanup=False, ipBase='10.0.0.0/8',
|
||||||
inNamespace=False,
|
inNamespace=False,
|
||||||
autoSetMacs=False, autoStaticArp=False, listenPort=None ):
|
autoSetMacs=False, autoStaticArp=False, listenPort=None ):
|
||||||
"""Create Mininet object.
|
"""Create Mininet object.
|
||||||
@@ -130,6 +130,7 @@ class Mininet( object ):
|
|||||||
self.controller = controller
|
self.controller = controller
|
||||||
self.link = link
|
self.link = link
|
||||||
self.intf = intf
|
self.intf = intf
|
||||||
|
self.ipBase = ipBase
|
||||||
self.inNamespace = inNamespace
|
self.inNamespace = inNamespace
|
||||||
self.xterms = xterms
|
self.xterms = xterms
|
||||||
self.cleanup = cleanup
|
self.cleanup = cleanup
|
||||||
@@ -214,6 +215,8 @@ class Mininet( object ):
|
|||||||
At the end of this function, everything should be connected
|
At the end of this function, everything should be connected
|
||||||
and up."""
|
and up."""
|
||||||
|
|
||||||
|
ipBaseNum, prefixLen = netParse( self.ipBase )
|
||||||
|
|
||||||
if not topo:
|
if not topo:
|
||||||
topo = self.topo()
|
topo = self.topo()
|
||||||
|
|
||||||
@@ -222,7 +225,9 @@ class Mininet( object ):
|
|||||||
name = prefix + topo.name( nodeId )
|
name = prefix + topo.name( nodeId )
|
||||||
ni = topo.nodeInfo( nodeId )
|
ni = topo.nodeInfo( nodeId )
|
||||||
# Default IP and MAC addresses
|
# Default IP and MAC addresses
|
||||||
defaults = { 'ip': topo.ip( nodeId ) }
|
defaults = { 'ip': topo.ip( nodeId,
|
||||||
|
ipBaseNum=ipBaseNum,
|
||||||
|
prefixLen=prefixLen ) }
|
||||||
if self.autoSetMacs:
|
if self.autoSetMacs:
|
||||||
defaults[ 'mac'] = macColonHex( nodeId )
|
defaults[ 'mac'] = macColonHex( nodeId )
|
||||||
defaults.update( ni.params )
|
defaults.update( ni.params )
|
||||||
|
|||||||
+19
-10
@@ -16,6 +16,7 @@ setup for testing, and can even be emulated with the Mininet package.
|
|||||||
# from networkx.classes.graph import Graph
|
# from networkx.classes.graph import Graph
|
||||||
|
|
||||||
from networkx import Graph
|
from networkx import Graph
|
||||||
|
from util import netParse, ipStr
|
||||||
|
|
||||||
class NodeID(object):
|
class NodeID(object):
|
||||||
'''Topo node identifier.'''
|
'''Topo node identifier.'''
|
||||||
@@ -42,15 +43,22 @@ class NodeID(object):
|
|||||||
'''
|
'''
|
||||||
return str(self.dpid)
|
return str(self.dpid)
|
||||||
|
|
||||||
def ip_str(self):
|
def ip_str(self, ipBase=None, prefixLen=8, ipBaseNum=0x0a000000):
|
||||||
'''Name conversion.
|
'''Name conversion.
|
||||||
|
ipBase: optional base IP address string
|
||||||
|
prefixLen: optional IP prefix length
|
||||||
|
ipBaseNum: option base IP address as int
|
||||||
@return ip ip as string
|
@return ip ip as string
|
||||||
'''
|
'''
|
||||||
hi = (self.dpid & 0xff0000) >> 16
|
if ipBase:
|
||||||
mid = (self.dpid & 0xff00) >> 8
|
ipnum, prefixLen = netParse( ipBase )
|
||||||
lo = self.dpid & 0xff
|
else:
|
||||||
return "10.%i.%i.%i" % (hi, mid, lo)
|
ipBaseNum = ipBaseNum
|
||||||
|
# Ugly but functional
|
||||||
|
assert self.dpid < ( 1 << ( 32 - prefixLen ) )
|
||||||
|
mask = 0xffffffff ^ ( ( 1 << prefixLen ) - 1 )
|
||||||
|
ipnum = self.dpid + ( ipBaseNum & mask )
|
||||||
|
return ipStr( ipnum )
|
||||||
|
|
||||||
|
|
||||||
class Node( object ):
|
class Node( object ):
|
||||||
@@ -113,7 +121,8 @@ class Topo(object):
|
|||||||
"""Create Topo object.
|
"""Create Topo object.
|
||||||
node: default node/host class (optional)
|
node: default node/host class (optional)
|
||||||
switch: default switch class (optional)
|
switch: default switch class (optional)
|
||||||
link: default link class (optional)"""
|
link: default link class (optional)
|
||||||
|
ipBase: default IP address base (optional)"""
|
||||||
self.g = Graph()
|
self.g = Graph()
|
||||||
self.node_info = {} # dpids hash to Node objects
|
self.node_info = {} # dpids hash to Node objects
|
||||||
self.edge_info = {} # (src_dpid, dst_dpid) tuples hash to Edge objects
|
self.edge_info = {} # (src_dpid, dst_dpid) tuples hash to Edge objects
|
||||||
@@ -342,13 +351,13 @@ class Topo(object):
|
|||||||
'''
|
'''
|
||||||
return self.id_gen(dpid = dpid).name_str()
|
return self.id_gen(dpid = dpid).name_str()
|
||||||
|
|
||||||
def ip(self, dpid):
|
def ip(self, dpid, **params):
|
||||||
'''Get IP dotted-decimal string of node ID.
|
'''Get IP dotted-decimal string of node ID.
|
||||||
|
|
||||||
@param dpid DPID of host or switch
|
@param dpid DPID of host or switch
|
||||||
|
@param params: params to pass to ip_str
|
||||||
@return ip_str
|
@return ip_str
|
||||||
'''
|
'''
|
||||||
return self.id_gen(dpid = dpid).ip_str()
|
return self.id_gen(dpid = dpid).ip_str(**params)
|
||||||
|
|
||||||
def nodeInfo( self, dpid ):
|
def nodeInfo( self, dpid ):
|
||||||
"Return metadata for node"
|
"Return metadata for node"
|
||||||
|
|||||||
+13
-4
@@ -204,14 +204,14 @@ def macColonHex( mac ):
|
|||||||
returns: macStr MAC colon-hex string"""
|
returns: macStr MAC colon-hex string"""
|
||||||
return _colonHex( mac, 6 )
|
return _colonHex( mac, 6 )
|
||||||
|
|
||||||
def ipStr( ip ):
|
def ipStr( ip, defaultNet=10 ):
|
||||||
"""Generate IP address string from an unsigned int.
|
"""Generate IP address string from an unsigned int.
|
||||||
ip: unsigned int of form w << 24 | x << 16 | y << 8 | z
|
ip: unsigned int of form w << 24 | x << 16 | y << 8 | z
|
||||||
returns: ip address string w.x.y.z, or 10.x.y.z if w==0"""
|
returns: ip address string w.x.y.z, or 10.x.y.z if w==0"""
|
||||||
w = ( ip & 0xff000000 ) >> 24
|
w = ( ip >> 24 ) & 0xff
|
||||||
w = 10 if w == 0 else w
|
w = 10 if w == 0 else w
|
||||||
x = ( ip & 0xff0000 ) >> 16
|
x = ( ip >> 16 ) & 0xff
|
||||||
y = ( ip & 0xff00 ) >> 8
|
y = ( ip >> 8 ) & 0xff
|
||||||
z = ip & 0xff
|
z = ip & 0xff
|
||||||
return "%i.%i.%i.%i" % ( w, x, y, z )
|
return "%i.%i.%i.%i" % ( w, x, y, z )
|
||||||
|
|
||||||
@@ -225,6 +225,15 @@ def ipParse( ip ):
|
|||||||
args = [ int( arg ) for arg in ip.split( '.' ) ]
|
args = [ int( arg ) for arg in ip.split( '.' ) ]
|
||||||
return ipNum( *args )
|
return ipNum( *args )
|
||||||
|
|
||||||
|
def netParse( ipstr ):
|
||||||
|
"""Parse an IP network specification, returning
|
||||||
|
address and prefix len as unsigned ints"""
|
||||||
|
prefixLen = 0
|
||||||
|
if '/' in ipstr:
|
||||||
|
ip, pf = ipstr.split( '/' )
|
||||||
|
prefixLen = int( pf )
|
||||||
|
return ipParse( ip ), prefixLen
|
||||||
|
|
||||||
def checkInt( s ):
|
def checkInt( s ):
|
||||||
"Check if input string is an int"
|
"Check if input string is an int"
|
||||||
try:
|
try:
|
||||||
|
|||||||
Reference in New Issue
Block a user