Add net.delNode(), net.delLink() and associated methods

This makes the mid-level net.add*() API symmetric.
You can now delete hosts, switches, controllers and links using
a new net.del*() API, as well as del net[ 'nodename' ].
This commit is contained in:
Bob Lantz
2015-04-02 16:21:27 -07:00
parent 57abd9baef
commit 511d71a110
3 changed files with 74 additions and 9 deletions
+6 -4
View File
@@ -202,6 +202,8 @@ class Intf( object ):
# if self.node.inNamespace:
# Link may have been dumped into root NS
# quietRun( 'ip link del ' + self.name )
self.node.delIntf( self )
self.link = None
def status( self ):
"Return intf status as a string"
@@ -471,10 +473,10 @@ class Link( object ):
def delete( self ):
"Delete this link"
self.intf1.delete()
# We only need to delete one side, though this doesn't seem to
# cost us much and might help subclasses.
# self.intf2.delete()
self.intf1 = None
self.intf2.delete()
self.intf2 = None
def stop( self ):
"Override to stop and clean up link as needed"
self.delete()
+59 -5
View File
@@ -226,6 +226,24 @@ class Mininet( object ):
self.nameToNode[ name ] = h
return h
def delNode( self, node, nodes=None):
"""Delete node
node: node to delete
nodes: optional list to delete from (e.g. self.hosts)"""
if nodes is None:
nodes = ( self.hosts if node in self.hosts else
( self.switches if node in self.switches else
( self.controllers if node in self.controllers else
[] ) ) )
node.stop( deleteIntfs=True )
node.terminate()
nodes.remove( node )
del self.nameToNode[ node.name ]
def delHost( self, host ):
"Delete a host"
self.delNode( host, nodes=self.hosts )
def addSwitch( self, name, cls=None, **params ):
"""Add switch.
name: name of switch to add
@@ -244,6 +262,10 @@ class Mininet( object ):
self.nameToNode[ name ] = sw
return sw
def delSwitch( self, switch ):
"Delete a switch"
self.delNode( switch, nodes=self.switches )
def addController( self, name='c0', controller=None, **params ):
"""Add controller.
controller: Controller class"""
@@ -265,6 +287,12 @@ class Mininet( object ):
self.nameToNode[ name ] = controller_new
return controller_new
def delController( self, controller ):
"""Delete a controller
Warning - does not reconfigure switches, so they
may still attempt to connect to it!"""
self.delNode( controller )
def addNAT( self, name='nat0', connect=True, inNamespace=False,
**params):
"""Add a NAT to the Mininet network
@@ -303,9 +331,13 @@ class Mininet( object ):
# Even more convenient syntax for node lookup and iteration
def __getitem__( self, key ):
"""net [ name ] operator: Return node(s) with given name(s)"""
"net[ name ] operator: Return node with given name"
return self.nameToNode[ key ]
def __delitem__( self, key ):
"del net[ name ] operator - delete node with given name"
self.delNode( self.nameToNode[ key ] )
def __iter__( self ):
"return iterator over node names"
for node in chain( self.hosts, self.switches, self.controllers ):
@@ -367,6 +399,30 @@ class Mininet( object ):
self.links.append( link )
return link
def delLink( self, link ):
"Remove a link from this network"
link.delete()
self.links.remove( link )
def linksBetween( self, node1, node2 ):
"Return Links between node1 and node2"
return [ link for link in self.links
if ( node1, node2 ) in (
( link.intf1.node, link.intf2.node ),
( link.intf2.node, link.intf1.node ) ) ]
def delLinkBetween( self, node1, node2, index=0, allLinks=False ):
"""Delete link(s) between node1 and node2
index: index of link to delete if multiple links (0)
allLinks: ignore index and delete all such links (False)
returns: deleted link(s)"""
links = self.linksBetween( node1, node2 )
if not allLinks:
links = [ links[ index ] ]
for link in links:
self.delLink( link )
return links
def configHosts( self ):
"Configure a set of hosts."
for host in self.hosts:
@@ -840,10 +896,8 @@ class Mininet( object ):
elif dst not in self.nameToNode:
error( 'dst not in network: %s\n' % dst )
else:
if isinstance( src, basestring ):
src = self.nameToNode[ src ]
if isinstance( dst, basestring ):
dst = self.nameToNode[ dst ]
src = self.nameToNode[ src ]
dst = self.nameToNode[ dst ]
connections = src.connectionsTo( dst )
if len( connections ) == 0:
error( 'src and dst not connected: %s %s\n' % ( src, dst) )
+9
View File
@@ -431,6 +431,15 @@ class Node( object ):
debug( 'moving', intf, 'into namespace for', self.name, '\n' )
moveIntfFn( intf.name, self )
def delIntf( self, intf ):
"""Remove interface from Node's known interfaces
Note: to fully delete interface, call intf.delete() instead"""
port = self.ports.get( intf )
if port is not None:
del self.intfs[ port ]
del self.ports[ intf ]
del self.nameToIntf[ intf.name ]
def defaultIntf( self ):
"Return interface for lowest port"
ports = self.intfs.keys()