Skip to content

Commit e1246c3

Browse files
committed
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.)
1 parent 2d924f8 commit e1246c3

2 files changed

Lines changed: 55 additions & 80 deletions

File tree

mininet/net.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -269,11 +269,7 @@ def buildFromTopo( self, topo=None ):
269269
src, dst = self.nameToNode[ srcName ], self.nameToNode[ dstName ]
270270
params = topo.linkInfo( srcName, dstName )
271271
srcPort, dstPort = topo.port( srcName, dstName )
272-
if not params:
273-
params = {}
274-
params.setdefault( 'port1', srcPort)
275-
params.setdefault( 'port2', dstPort)
276-
self.addLink( src, dst, **params )
272+
self.addLink( src, dst, srcPort, dstPort, **params )
277273
info( '(%s, %s) ' % ( src.name, dst.name ) )
278274

279275
info( '\n' )

mininet/topo.py

Lines changed: 54 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -30,83 +30,73 @@ def __init__(self, hopts=None, sopts=None, lopts=None):
3030
self.node_info = {}
3131
self.link_info = {} # (src, dst) tuples hash to EdgeInfo objects
3232
self.hopts = {} if hopts is None else hopts
33-
self.sopts = {} if sopts is None else lopts
33+
self.sopts = {} if sopts is None else sopts
3434
self.lopts = {} if lopts is None else lopts
3535
self.ports = {} # ports[src][dst] is port on src that connects to dst
3636

37-
def add_node(self, name, *args, **opts):
37+
def add_node(self, name, **opts):
3838
"""Add Node to graph.
39-
add_node('name', dict) <or> add_node('name', **opts)
4039
name: name
41-
args: dict of node options
42-
opts: node options"""
40+
opts: node options
41+
returns: node name"""
4342
self.g.add_node(name)
44-
if args and type(args[0]) is dict:
45-
opts = args[0]
4643
self.node_info[name] = opts
4744
return name
4845

49-
def add_host(self, name, *args, **opts):
46+
def add_host(self, name, **opts):
5047
"""Convenience method: Add host to graph.
51-
add_host('name', dict) <or> add_host('name', **opts)
52-
name: name
53-
args: dict of node options
54-
opts: node options"""
48+
name: host name
49+
opts: host options
50+
returns: host name"""
5551
if not opts and self.hopts:
5652
opts = self.hopts
57-
return self.add_node(name, *args, **opts)
53+
return self.add_node(name, **opts)
5854

5955
def add_switch(self, name, **opts):
6056
"""Convenience method: Add switch to graph.
61-
add_switch('name', dict) <or> add_switch('name', **opts)
62-
name: name
63-
args: dict of node options
64-
opts: node options"""
57+
name: switch name
58+
opts: switch options
59+
returns: switch name"""
6560
if not opts and self.sopts:
6661
opts = self.sopts
6762
result = self.add_node(name, is_switch=True, **opts)
6863
return result
6964

70-
def add_link(self, src, dst, *args, **opts):
71-
"""Add link (Node, Node) to topo.
72-
add_link(src, dst, dict) <or> add_link(src, dst, **opts)
73-
src: src name
74-
dst: dst name
75-
args: dict of node options
76-
params: link parameters"""
77-
src, dst = sorted([src, dst], key=naturalSeq)
78-
self.g.add_edge(src, dst)
79-
if args and type(args[0]) is dict:
80-
opts = args[0]
81-
if not opts and self.sopts:
82-
opts = self.sopts
83-
self.link_info[(src, dst)] = opts
84-
self.add_port(src, dst)
85-
return src, dst
86-
87-
def add_port(self, src, dst):
65+
def add_link(self, node1, node2, port1=None, port2=None,
66+
*default, **opts):
67+
"""node1, node2: nodes to link together
68+
port1, port2: ports (optional)
69+
opts: link options (optional)
70+
returns: link info key"""
71+
if not opts and self.lopts:
72+
opts = self.lopts
73+
self.add_port(node1, node2, port1, port2)
74+
key = tuple(self.sorted([node1, node2]))
75+
self.link_info[key] = opts
76+
self.g.add_edge(*key)
77+
return key
78+
79+
def add_port(self, src, dst, sport=None, dport=None):
8880
'''Generate port mapping for new edge.
89-
90-
@param src source switch DPID
91-
@param dst destination switch DPID
81+
@param src source switch name
82+
@param dst destination switch name
9283
'''
84+
self.ports.setdefault(src, {})
85+
self.ports.setdefault(dst, {})
86+
# New port: number of outlinks + base
9387
src_base = 1 if self.is_switch(src) else 0
9488
dst_base = 1 if self.is_switch(dst) else 0
95-
if src not in self.ports:
96-
self.ports[src] = {}
97-
if dst not in self.ports[src]:
98-
# num outlinks
99-
self.ports[src][dst] = len(self.ports[src]) + src_base
100-
if dst not in self.ports:
101-
self.ports[dst] = {}
102-
if src not in self.ports[dst]:
103-
# num outlinks
104-
self.ports[dst][src] = len(self.ports[dst]) + dst_base
89+
if sport is None:
90+
sport = len(self.ports[src]) + src_base
91+
if dport is None:
92+
dport = len(self.ports[dst]) + dst_base
93+
self.ports[src][dst] = sport
94+
self.ports[dst][src] = dport
10595

10696
def nodes(self, sort=True):
10797
"Return nodes in graph"
10898
if sort:
109-
return sorted( self.g.nodes(), key=natural )
99+
return self.sorted( self.g.nodes() )
110100
else:
111101
return self.g.nodes()
112102

@@ -137,7 +127,8 @@ def links(self, sort=True):
137127
if not sort:
138128
return self.g.edges()
139129
else:
140-
return sorted( self.g.edges(), key=naturalSeq )
130+
links = [tuple(self.sorted(e)) for e in self.g.edges()]
131+
return sorted( links, key=naturalSeq )
141132

142133
def port(self, src, dst):
143134
'''Get port number.
@@ -154,9 +145,9 @@ def port(self, src, dst):
154145

155146
def linkInfo( self, src, dst ):
156147
"Return link metadata"
157-
src, dst = sorted((src, dst), key=naturalSeq)
148+
src, dst = self.sorted([src, dst])
158149
return self.link_info[(src, dst)]
159-
150+
160151
def nodeInfo( self, name ):
161152
"Return metadata (dict) for node"
162153
info = self.node_info[ name ]
@@ -197,31 +188,19 @@ class SingleSwitchReversedTopo(SingleSwitchTopo):
197188
198189
Useful to verify that Mininet properly handles custom port numberings.
199190
'''
191+
def __init__(self, k=2, **opts):
192+
'''Init.
200193
201-
def port(self, src, dst):
202-
'''Get port number.
203-
204-
@param src source switch DPID
205-
@param dst destination switch DPID
206-
@return tuple (src_port, dst_port):
207-
src_port: port on source switch leading to the destination switch
208-
dst_port: port on destination switch leading to the source switch
194+
@param k number of hosts
195+
@param enable_all enables all nodes and switches?
209196
'''
210-
if src == 1:
211-
if dst in range(2, self.k + 2):
212-
dst_index = dst - 2
213-
highest = self.k - 1
214-
return (highest - dst_index, 0)
215-
else:
216-
raise Exception('unexpected dst: %i' % dst)
217-
elif src in range(2, self.k + 2):
218-
if dst == 1:
219-
raise Exception('unexpected dst: %i' % dst)
220-
else:
221-
src_index = src - 2
222-
highest = self.k - 1
223-
return (0, highest - src_index)
224-
197+
super(SingleSwitchTopo, self).__init__(**opts)
198+
self.k = k
199+
switch = self.add_switch('s1')
200+
for h in irange(1, k):
201+
host = self.add_host('h%s' % h)
202+
self.add_link(host, switch,
203+
port1=0, port2=(k - h + 1))
225204

226205
class LinearTopo(Topo):
227206
"Linear topology of k switches, with one host per switch."

0 commit comments

Comments
 (0)