def makeTunnel(self, node1, node2, intfname1, intfname2, addr1=None, addr2=None): "Make a tunnel across switches on different servers" # We should never try to create a tunnel to ourselves! assert node1.server != 'localhost' or node2.server != 'localhost' # And we can't ssh into this server remotely as 'localhost', # so try again swappping node1 and node2 if node2.server == 'localhost': return self.makeTunnel(node2, node1, intfname2, intfname1, addr2, addr1) # 1. Create tap interfaces for node in node1, node2: # For now we are hard-wiring tap9, which we will rename node.rcmd('ip link delete tap9', stderr=PIPE) cmd = 'ip tuntap add dev tap9 mode tap user ' + node.user node.rcmd(cmd) links = node.rcmd('ip link show') # print 'after add, links =', links assert 'tap9' in links # 2. Create ssh tunnel between tap interfaces # -n: close stdin dest = '%s@%s' % (node2.user, node2.serverIP) cmd = [ 'ssh', '-n', '-o', 'Tunnel=Ethernet', '-w', '9:9', dest, 'echo @' ] self.cmd = cmd tunnel = node1.rpopen(cmd, sudo=False) # When we receive the character '@', it means that our # tunnel should be set up debug('Waiting for tunnel to come up...\n') ch = tunnel.stdout.read(1) if ch != '@': error('makeTunnel:\n', 'Tunnel setup failed for', '%s:%s' % (node1, node1.dest), 'to', '%s:%s\n' % (node2, node2.dest), 'command was:', cmd, '\n') tunnel.terminate() tunnel.wait() error(ch + tunnel.stdout.read()) error(tunnel.stderr.read()) exit(1) # 3. Move interfaces if necessary for node in node1, node2: if node.inNamespace: retry(3, .01, RemoteLink.moveIntf, 'tap9', node) # 4. Rename tap interfaces to desired names for node, intf, addr in ((node1, intfname1, addr1), (node2, intfname2, addr2)): if not addr: node.cmd('ip link set tap9 name', intf) else: node.cmd('ip link set tap9 name', intf, 'address', addr) for node, intf in ((node1, intfname1), (node2, intfname2)): assert intf in node.cmd('ip link show') return tunnel
def makeTunnel( self, node1, node2, intfname1, intfname2, addr1=None, addr2=None ): "Make a tunnel across switches on different servers" # We should never try to create a tunnel to ourselves! assert node1.server != 'localhost' or node2.server != 'localhost' # And we can't ssh into this server remotely as 'localhost', # so try again swappping node1 and node2 if node2.server == 'localhost': return self.makeTunnel( node2, node1, intfname2, intfname1, addr2, addr1 ) # 1. Create tap interfaces for node in node1, node2: # For now we are hard-wiring tap9, which we will rename node.rcmd( 'ip link delete tap9', stderr=PIPE ) cmd = 'ip tuntap add dev tap9 mode tap user ' + node.user node.rcmd( cmd ) links = node.rcmd( 'ip link show' ) # print 'after add, links =', links assert 'tap9' in links # 2. Create ssh tunnel between tap interfaces # -n: close stdin dest = '%s@%s' % ( node2.user, node2.serverIP ) cmd = [ 'ssh', '-n', '-o', 'Tunnel=Ethernet', '-w', '9:9', dest, 'echo @' ] self.cmd = cmd tunnel = node1.rpopen( cmd, sudo=False ) # When we receive the character '@', it means that our # tunnel should be set up debug( 'Waiting for tunnel to come up...\n' ) ch = tunnel.stdout.read( 1 ) if ch != '@': error( 'makeTunnel:\n', 'Tunnel setup failed for', '%s:%s' % ( node1, node1.dest ), 'to', '%s:%s\n' % ( node2, node2.dest ), 'command was:', cmd, '\n' ) tunnel.terminate() tunnel.wait() error( ch + tunnel.stdout.read() ) error( tunnel.stderr.read() ) sys.exit( 1 ) # 3. Move interfaces if necessary for node in node1, node2: if node.inNamespace: retry( 3, .01, RemoteLink.moveIntf, 'tap9', node ) # 4. Rename tap interfaces to desired names for node, intf, addr in ( ( node1, intfname1, addr1 ), ( node2, intfname2, addr2 ) ): if not addr: node.cmd( 'ip link set tap9 name', intf ) else: node.cmd( 'ip link set tap9 name', intf, 'address', addr ) for node, intf in ( ( node1, intfname1 ), ( node2, intfname2 ) ): assert intf in node.cmd( 'ip link show' ) return tunnel
def moveIntf(intf, dstNode, printError=True, retries=3, delaySecs=0.001): """Move interface to node, retrying on failure. intf: string, interface dstNode: destination Node printError: if true, print error""" from mn_wifi.node import AP if not isinstance(dstNode, AP): retry(retries, delaySecs, moveIntfNoRetry, intf, dstNode, printError=printError)
def cleanup( self ): "Clean up our cgroup" retry( retries=3, delaySecs=1, fn=self.cgroupDel )
def cleanup(self): "Clean up Node, then clean up our cgroup" super(CPULimitedHost, self).cleanup() retry(retries=3, delaySecs=1, fn=self.cgroupDel)
def cleanup( self ): "Clean up Node, then clean up our cgroup" super( CPULimitedHost, self ).cleanup() retry( retries=3, delaySecs=1, fn=self.cgroupDel )