Simplify port specification.
For the moment, I've removed the ability to specify a dict of options without using **. This is a slightly unfortunate trade-off since it simplifies implementation at the expense of making the API slightly less convenient (if somewhat more consistent.)
This commit is contained in:
+1
-5
@@ -269,11 +269,7 @@ class Mininet( object ):
|
|||||||
src, dst = self.nameToNode[ srcName ], self.nameToNode[ dstName ]
|
src, dst = self.nameToNode[ srcName ], self.nameToNode[ dstName ]
|
||||||
params = topo.linkInfo( srcName, dstName )
|
params = topo.linkInfo( srcName, dstName )
|
||||||
srcPort, dstPort = topo.port( srcName, dstName )
|
srcPort, dstPort = topo.port( srcName, dstName )
|
||||||
if not params:
|
self.addLink( src, dst, srcPort, dstPort, **params )
|
||||||
params = {}
|
|
||||||
params.setdefault( 'port1', srcPort)
|
|
||||||
params.setdefault( 'port2', dstPort)
|
|
||||||
self.addLink( src, dst, **params )
|
|
||||||
info( '(%s, %s) ' % ( src.name, dst.name ) )
|
info( '(%s, %s) ' % ( src.name, dst.name ) )
|
||||||
|
|
||||||
info( '\n' )
|
info( '\n' )
|
||||||
|
|||||||
+52
-73
@@ -30,83 +30,73 @@ class Topo(object):
|
|||||||
self.node_info = {}
|
self.node_info = {}
|
||||||
self.link_info = {} # (src, dst) tuples hash to EdgeInfo objects
|
self.link_info = {} # (src, dst) tuples hash to EdgeInfo objects
|
||||||
self.hopts = {} if hopts is None else hopts
|
self.hopts = {} if hopts is None else hopts
|
||||||
self.sopts = {} if sopts is None else lopts
|
self.sopts = {} if sopts is None else sopts
|
||||||
self.lopts = {} if lopts is None else lopts
|
self.lopts = {} if lopts is None else lopts
|
||||||
self.ports = {} # ports[src][dst] is port on src that connects to dst
|
self.ports = {} # ports[src][dst] is port on src that connects to dst
|
||||||
|
|
||||||
def add_node(self, name, *args, **opts):
|
def add_node(self, name, **opts):
|
||||||
"""Add Node to graph.
|
"""Add Node to graph.
|
||||||
add_node('name', dict) <or> add_node('name', **opts)
|
|
||||||
name: name
|
name: name
|
||||||
args: dict of node options
|
opts: node options
|
||||||
opts: node options"""
|
returns: node name"""
|
||||||
self.g.add_node(name)
|
self.g.add_node(name)
|
||||||
if args and type(args[0]) is dict:
|
|
||||||
opts = args[0]
|
|
||||||
self.node_info[name] = opts
|
self.node_info[name] = opts
|
||||||
return name
|
return name
|
||||||
|
|
||||||
def add_host(self, name, *args, **opts):
|
def add_host(self, name, **opts):
|
||||||
"""Convenience method: Add host to graph.
|
"""Convenience method: Add host to graph.
|
||||||
add_host('name', dict) <or> add_host('name', **opts)
|
name: host name
|
||||||
name: name
|
opts: host options
|
||||||
args: dict of node options
|
returns: host name"""
|
||||||
opts: node options"""
|
|
||||||
if not opts and self.hopts:
|
if not opts and self.hopts:
|
||||||
opts = self.hopts
|
opts = self.hopts
|
||||||
return self.add_node(name, *args, **opts)
|
return self.add_node(name, **opts)
|
||||||
|
|
||||||
def add_switch(self, name, **opts):
|
def add_switch(self, name, **opts):
|
||||||
"""Convenience method: Add switch to graph.
|
"""Convenience method: Add switch to graph.
|
||||||
add_switch('name', dict) <or> add_switch('name', **opts)
|
name: switch name
|
||||||
name: name
|
opts: switch options
|
||||||
args: dict of node options
|
returns: switch name"""
|
||||||
opts: node options"""
|
|
||||||
if not opts and self.sopts:
|
if not opts and self.sopts:
|
||||||
opts = self.sopts
|
opts = self.sopts
|
||||||
result = self.add_node(name, is_switch=True, **opts)
|
result = self.add_node(name, is_switch=True, **opts)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def add_link(self, src, dst, *args, **opts):
|
def add_link(self, node1, node2, port1=None, port2=None,
|
||||||
"""Add link (Node, Node) to topo.
|
*default, **opts):
|
||||||
add_link(src, dst, dict) <or> add_link(src, dst, **opts)
|
"""node1, node2: nodes to link together
|
||||||
src: src name
|
port1, port2: ports (optional)
|
||||||
dst: dst name
|
opts: link options (optional)
|
||||||
args: dict of node options
|
returns: link info key"""
|
||||||
params: link parameters"""
|
if not opts and self.lopts:
|
||||||
src, dst = sorted([src, dst], key=naturalSeq)
|
opts = self.lopts
|
||||||
self.g.add_edge(src, dst)
|
self.add_port(node1, node2, port1, port2)
|
||||||
if args and type(args[0]) is dict:
|
key = tuple(self.sorted([node1, node2]))
|
||||||
opts = args[0]
|
self.link_info[key] = opts
|
||||||
if not opts and self.sopts:
|
self.g.add_edge(*key)
|
||||||
opts = self.sopts
|
return key
|
||||||
self.link_info[(src, dst)] = opts
|
|
||||||
self.add_port(src, dst)
|
|
||||||
return src, dst
|
|
||||||
|
|
||||||
def add_port(self, src, dst):
|
def add_port(self, src, dst, sport=None, dport=None):
|
||||||
'''Generate port mapping for new edge.
|
'''Generate port mapping for new edge.
|
||||||
|
@param src source switch name
|
||||||
@param src source switch DPID
|
@param dst destination switch name
|
||||||
@param dst destination switch DPID
|
|
||||||
'''
|
'''
|
||||||
|
self.ports.setdefault(src, {})
|
||||||
|
self.ports.setdefault(dst, {})
|
||||||
|
# New port: number of outlinks + base
|
||||||
src_base = 1 if self.is_switch(src) else 0
|
src_base = 1 if self.is_switch(src) else 0
|
||||||
dst_base = 1 if self.is_switch(dst) else 0
|
dst_base = 1 if self.is_switch(dst) else 0
|
||||||
if src not in self.ports:
|
if sport is None:
|
||||||
self.ports[src] = {}
|
sport = len(self.ports[src]) + src_base
|
||||||
if dst not in self.ports[src]:
|
if dport is None:
|
||||||
# num outlinks
|
dport = len(self.ports[dst]) + dst_base
|
||||||
self.ports[src][dst] = len(self.ports[src]) + src_base
|
self.ports[src][dst] = sport
|
||||||
if dst not in self.ports:
|
self.ports[dst][src] = dport
|
||||||
self.ports[dst] = {}
|
|
||||||
if src not in self.ports[dst]:
|
|
||||||
# num outlinks
|
|
||||||
self.ports[dst][src] = len(self.ports[dst]) + dst_base
|
|
||||||
|
|
||||||
def nodes(self, sort=True):
|
def nodes(self, sort=True):
|
||||||
"Return nodes in graph"
|
"Return nodes in graph"
|
||||||
if sort:
|
if sort:
|
||||||
return sorted( self.g.nodes(), key=natural )
|
return self.sorted( self.g.nodes() )
|
||||||
else:
|
else:
|
||||||
return self.g.nodes()
|
return self.g.nodes()
|
||||||
|
|
||||||
@@ -137,7 +127,8 @@ class Topo(object):
|
|||||||
if not sort:
|
if not sort:
|
||||||
return self.g.edges()
|
return self.g.edges()
|
||||||
else:
|
else:
|
||||||
return sorted( self.g.edges(), key=naturalSeq )
|
links = [tuple(self.sorted(e)) for e in self.g.edges()]
|
||||||
|
return sorted( links, key=naturalSeq )
|
||||||
|
|
||||||
def port(self, src, dst):
|
def port(self, src, dst):
|
||||||
'''Get port number.
|
'''Get port number.
|
||||||
@@ -154,7 +145,7 @@ class Topo(object):
|
|||||||
|
|
||||||
def linkInfo( self, src, dst ):
|
def linkInfo( self, src, dst ):
|
||||||
"Return link metadata"
|
"Return link metadata"
|
||||||
src, dst = sorted((src, dst), key=naturalSeq)
|
src, dst = self.sorted([src, dst])
|
||||||
return self.link_info[(src, dst)]
|
return self.link_info[(src, dst)]
|
||||||
|
|
||||||
def nodeInfo( self, name ):
|
def nodeInfo( self, name ):
|
||||||
@@ -197,31 +188,19 @@ class SingleSwitchReversedTopo(SingleSwitchTopo):
|
|||||||
|
|
||||||
Useful to verify that Mininet properly handles custom port numberings.
|
Useful to verify that Mininet properly handles custom port numberings.
|
||||||
'''
|
'''
|
||||||
|
def __init__(self, k=2, **opts):
|
||||||
|
'''Init.
|
||||||
|
|
||||||
def port(self, src, dst):
|
@param k number of hosts
|
||||||
'''Get port number.
|
@param enable_all enables all nodes and switches?
|
||||||
|
|
||||||
@param src source switch DPID
|
|
||||||
@param dst destination switch DPID
|
|
||||||
@return tuple (src_port, dst_port):
|
|
||||||
src_port: port on source switch leading to the destination switch
|
|
||||||
dst_port: port on destination switch leading to the source switch
|
|
||||||
'''
|
'''
|
||||||
if src == 1:
|
super(SingleSwitchTopo, self).__init__(**opts)
|
||||||
if dst in range(2, self.k + 2):
|
self.k = k
|
||||||
dst_index = dst - 2
|
switch = self.add_switch('s1')
|
||||||
highest = self.k - 1
|
for h in irange(1, k):
|
||||||
return (highest - dst_index, 0)
|
host = self.add_host('h%s' % h)
|
||||||
else:
|
self.add_link(host, switch,
|
||||||
raise Exception('unexpected dst: %i' % dst)
|
port1=0, port2=(k - h + 1))
|
||||||
elif src in range(2, self.k + 2):
|
|
||||||
if dst == 1:
|
|
||||||
raise Exception('unexpected dst: %i' % dst)
|
|
||||||
else:
|
|
||||||
src_index = src - 2
|
|
||||||
highest = self.k - 1
|
|
||||||
return (0, highest - src_index)
|
|
||||||
|
|
||||||
|
|
||||||
class LinearTopo(Topo):
|
class LinearTopo(Topo):
|
||||||
"Linear topology of k switches, with one host per switch."
|
"Linear topology of k switches, with one host per switch."
|
||||||
|
|||||||
Reference in New Issue
Block a user