Ejemplo n.º 1
0
 def addIntf( self, intf, port=None ):
     """Add an interface.
        intf: interface name (e.g. nodeN-ethM)
        port: port number (optional, typically OpenFlow port number)"""
     if port is None:
         port = self.newPort()
     self.intfs[ port ] = intf
     self.ports[ intf ] = port
     #info( '\n' )
     #info( 'added intf %s:%d to node %s\n' % ( intf,port, self.name ) )
     if self.inNamespace:
         #info( 'moving w/inNamespace set\n' )
         moveIntf( intf, self )
Ejemplo n.º 2
0
 def moveIntfFrom( self, intf, intf_node, port=None ):
     """Move an interface.
        intf: interface
        intf_node: original node containing interface
        port: port number (optional, typically OpenFlow port number)"""
     if port is None:
         port = self.newPort()
     self.intfs[ port ] = intf
     self.ports[ intf ] = port
     self.nameToIntf[ intf.name ] = intf
     debug( '\nmoving intf %s:%d to node %s\n' % ( intf, port, self.name ))
     debug( 'moving', intf, 'into namespace for', self.name, '\n' )
     moveIntf( intf.name, self, intf_node )
Ejemplo n.º 3
0
 def moveIntfFrom(self, intf, intf_node, port=None):
     """Move an interface.
        intf: interface
        intf_node: original node containing interface
        port: port number (optional, typically OpenFlow port number)"""
     if port is None:
         port = self.newPort()
     self.intfs[port] = intf
     self.ports[intf] = port
     self.nameToIntf[intf.name] = intf
     debug('\nmoving intf %s:%d to node %s\n' % (intf, port, self.name))
     debug('moving', intf, 'into namespace for', self.name, '\n')
     moveIntf(intf.name, self, intf_node)
Ejemplo n.º 4
0
 def addIntf(self, intf, port=None):
     """Add an interface.
        intf: interface name (e.g. nodeN-ethM)
        port: port number (optional, typically OpenFlow port number)"""
     if port is None:
         port = self.newPort()
     self.intfs[port] = intf
     self.ports[intf] = port
     #info( '\n' )
     #info( 'added intf %s:%d to node %s\n' % ( intf,port, self.name ) )
     if self.inNamespace:
         #info( 'moving w/inNamespace set\n' )
         moveIntf(intf, self)
Ejemplo n.º 5
0
 def addIntf( self, intf, port=None ):
     """Add an interface.
        intf: interface
        port: port number (optional, typically OpenFlow port number)"""
     if port is None:
         port = self.newPort()
     self.intfs[ port ] = intf
     self.ports[ intf ] = port
     self.nameToIntf[ intf.name ] = intf
     debug( '\n' )
     debug( 'added intf %s:%d to node %s\n' % ( intf, port, self.name ) )
     if self.inNamespace:
         debug( 'moving', intf, 'into namespace for', self.name, '\n' )
         moveIntf( intf.name, self )
Ejemplo n.º 6
0
def _makeIntfPair(intf1,
                  intf2,
                  addr1=None,
                  addr2=None,
                  node1=None,
                  node2=None,
                  deleteIntfs=True,
                  runCmd=None):
    """Make a veth pair connnecting new interfaces intf1 and intf2
	   intf1: name for interface 1
	   intf2: name for interface 2
	   addr1: MAC address for interface 1 (optional)
	   addr2: MAC address for interface 2 (optional)
	   node1: home node for interface 1 (optional)
	   node2: home node for interface 2 (optional)
	   deleteIntfs: delete intfs before creating them
	   runCmd: function to run shell commands (quietRun)
	   raises Exception on failure

		Changes:
		The problem here is that we can not add a link to another
		netns within a Docker container since it does not know
		the other process (process not found error).
		So we have to do it different:
		We create the veth pair inside the default netns and move them
		into their netns (container) afterwards."""

    if deleteIntfs:
        # Delete any old interfaces with the same names
        quietRun('ip link del ' + intf1, shell=True)
        quietRun('ip link del ' + intf2, shell=True)

    # first: create the veth pair in default namespace
    if addr1 is None and addr2 is None:
        cmdOutput = quietRun('ip link add name %s '
                             'type veth peer name %s ' % (intf1, intf2),
                             shell=True)
    else:
        cmdOutput = quietRun('ip link add name %s '
                             'address %s '
                             'type veth peer name %s '
                             'address %s ' % (intf1, addr1, intf2, addr2),
                             shell=True)
    if cmdOutput:
        raise Exception("Error creating interface pair (%s,%s): %s " %
                        (intf1, intf2, cmdOutput))
    # second: move both endpoints into the corresponding namespaces
    moveIntf(intf1, node1)
    moveIntf(intf2, node2)
Ejemplo n.º 7
0
 def namespaceMove( self ):
     loops = 0
     while not self.isConnected():
         time.sleep( 0.01 )
         loops += 1
         if loops > 10:
             warn( "Cannot move TBIntf to mininet Node namespace: "
                   "ns-3 has not connected yet to the TAP interface\n" )
             return
     moveIntf( self.name, self.node )
     self.inRightNamespace = True
     # IP address has been reset while moving to namespace, needs to be set again
     if self.ip is not None:
         self.setIP( self.ip, self.prefixLen )
     # The same for 'up'
     self.isUp( True )
Ejemplo n.º 8
0
 def namespaceMove(self):
     loops = 0
     while not self.isConnected():
         time.sleep(0.01)
         loops += 1
         if loops > 10:
             warn("Cannot move TBIntf to mininet Node namespace: "
                  "ns-3 has not connected yet to the TAP interface\n")
             return
     time.sleep(0.01)
     moveIntf(self.name, self.node)
     self.inRightNamespace = True
     # IP address has been reset while moving to namespace, needs to be set again
     if self.ip is not None:
         self.setIP(self.ip, self.prefixLen)
     # The same for 'up'
     self.isUp(True)
Ejemplo n.º 9
0
    def configureLeafPacketECMP(self):
        # per-packet ECMP using bond device and RR.
        # Insert one bond device per leaf.
        bond = "bond%d" % self.switch_id
        # Move bond intf to each leaf.
        moveIntf(bond, self)
        # configure mac-address on bond interface
        mac = LeafMAC(self.switch_id)
        setMac(self, bond, mac)
        # enslave all links to spines
        intfs = []
        for spine in xrange(self.num_spines):
            intf = "%s-eth%d" % (self.name, 1+spine+self.hosts_per_leaf)
            intfs.append(intf)
        cmd = "ifconfig %s up; ifenslave %s %s" % (bond, bond, ' '.join(intfs))
        self.log(cmd)
        self.cmd(cmd)
        # configure routes to spines; in this case all spines have the
        # same IP address.
        spine_ip = SpineIP(0)
        cmd = "route add -host %s dev %s" % (spine_ip, bond)
        self.cmd(cmd)

        # configure routes to all other leaves
        for leaf in xrange(self.num_leafs):
            leaf += 1
            if leaf == self.switch_id:
                continue
            net = LeafNet(leaf)
            sip = SpineIP(0)
            cmd = "ip route add %s nexthop via %s dev %s" % (net, sip, bond)
            self.cmd(cmd)
        # set spine mac address
        sip = SpineIP(0)
        mac = SpineMAC(0)
        cmd = "arp -s -i %s %s %s" % (bond, sip, mac)
        self.cmd(cmd)
        return
Ejemplo n.º 10
0
 def namespaceMove(self):
     """Move tap Linux interface to the right namespace."""
     loops = 0
     # Wait until ns-3 process connects to the tap Linux interface. ns-3 process resides in the root
     # network namespace, so it must manage to connect to the interface before it is moved to the node
     # namespace. After interface move ns-3 process will not see the interface.
     while not self.isConnected():
         time.sleep(0.01)
         loops += 1
         if loops > 10:
             warn("Cannot move TBIntf to mininet Node namespace: "
                  "ns-3 has not connected yet to the TAP interface\n")
             return
     # Wait a little more, just for be sure ns-3 process not miss that.
     time.sleep(0.01)
     # Move interface to the right namespace.
     moveIntf(self.name, self.node)
     self.inRightNamespace = True
     # IP address has been reset while moving to namespace, needs to be set again.
     if self.ip is not None:
         self.setIP(self.ip, self.prefixLen)
     # The same for 'up'.
     self.isUp(True)
Ejemplo n.º 11
0
 def namespaceMove( self ):
     """Move tap Linux interface to the right namespace."""
     loops = 0
     # Wait until ns-3 process connects to the tap Linux interface. ns-3 process resides in the root
     # network namespace, so it must manage to connect to the interface before it is moved to the node
     # namespace. After interface move ns-3 process will not see the interface.
     while not self.isConnected():
         time.sleep( 0.01 )
         loops += 1
         if loops > 10:
             warn( "Cannot move TBIntf to mininet Node namespace: "
                   "ns-3 has not connected yet to the TAP interface\n" )
             return
     # Wait a little more, just for be sure ns-3 process not miss that.
     time.sleep( 0.01 )
     # Move interface to the right namespace.
     moveIntf( self.name, self.node )
     self.inRightNamespace = True
     # IP address has been reset while moving to namespace, needs to be set again.
     if self.ip is not None:
         self.setIP( self.ip, self.prefixLen )
     # The same for 'up'.
     self.isUp( True )
Ejemplo n.º 12
0
    def _moveLink( self, node1, node2, intf1_name=None, intf2_name=None ):
        """
        Move a host node to destination node in Mininet.

        node1: Moving node instance.
        node2: Destination node instance.
        intf1_name: Moving node interface name. Default if None.
        intf2_name: Destination node interface name. Default if None.
        """
        if self.debug_flag1:
            args = (node1, node2, intf1_name, intf2_name)
            print "EXEC: moveLink(%s, %s, %s, %s):" % args

        # Part 0: Main assertions.
        assert isinstance(node1, Host)
        assert isinstance(node2, Switch) or isinstance(node2, Dummy)
        assert not intf1_name or intf1_name in node1.nameToIntf
        assert not intf2_name or intf2_name not in node2.nameToIntf

        # Part 1: Extracting intf1 information.
        intf1 = node1.intf(intf=intf1_name)  # <- Uses defaultIntf if None.
        assert intf1 is not None
        intf1_name = intf1_name if intf1_name else intf1.name
        assert intf1.link != None
        assert intf1.link.intf1 == intf1 or intf1.link.intf2 == intf1
        assert intf1.node == node1
        intf1_other = None
        if intf1.link.intf1 == intf1:
            intf1_other = intf1.link.intf2
        elif intf1.link.intf2 == intf1:
            intf1_other = intf1.link.intf1
        node1_other = intf1_other.node
        intf1_name_other = intf1_other.name
        intf1_port_other = node1_other.ports[intf1_other]

        # Special case: Node already connected to other node.
        if node1_other == node2:
            if not intf2_name or intf2_name == intf1_name_other:
                warn('connection already established\n')
                return

        # Part 1.5: Call detach() on switch.
        if hasattr(node1_other, 'detach'):
            if self.debug_flag1: 
                print "Detach %s from %s" % (intf1_other, node1_other)
            node1_other.detach(intf1_other)

        # Part 2: Exchange information between node1_other and node2.
        del node1_other.intfs[ intf1_port_other ]
        del node1_other.ports[ intf1_other ]
        del node1_other.nameToIntf[ intf1_name_other ]
        intf2_port = node2.newPort()          # For now, just assign new port.
        intf2 = intf1_other
        if not intf2_name:
            intf2_name = "%s-eth%d" % (node2.name, intf2_port)
        intf2.rename(intf2_name)
        intf2.node = node2
        node2.intfs[ intf2_port ] = intf2
        node2.ports[ intf2 ] = intf2_port
        node2.nameToIntf[ intf2_name ] = intf2

        # Part 3: Moving intf1_other to intf2 by namespace.
        debug( '\nmoving', intf2, 'into namespace for', node2, '\n' )
        moveIntf( intf2_name, node2, srcNode=node1_other )

        # Part 3.5: Call detach() on switch.
        if hasattr(node2, 'attach'):
            if self.debug_flag1:
                print "Attach %s to %s" % (intf2, node2)
            node2.attach(intf2)
Ejemplo n.º 13
0
    def moveLink( self, node1, node2, intf1_name, intf2_name ):
        if self.debug_flag1:
            args = (node1, node2, intf1_name, intf2_name)
            print "EXEC: moveLink(%s, %s, %s, %s):" % args
        assert isinstance(node1, Host) #Node)
        assert isinstance(node2, Switch) or isinstance(node2, Dummy) #Node)
        assert intf1_name in node1.nameToIntf
        assert intf2_name in node2.nameToUnusedPorts
        if self.debug_flag2:    #Make debug_flag false when not testing.
            intf1 = node1.nameToIntf[intf1_name]
            if intf1.link.intf1 == intf1:
                intf1_other = intf1.link.intf2
            elif intf1.link.intf2 == intf2:
                intf1_other = intf1.link.intf1
            node1_other = intf1_other.node
            intf1_name_other = intf1_other.name
            node1_other.nameToUnusedPorts[intf1_name_other] = None
            del node2.nameToUnusedPorts[intf2_name]
            return

        # TODO: Fix below~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~``
        # CODE HERE!
        if self.debug_flag3:
            node1_intf = node1.nameToIntf[intf1_name]
            if node1_intf.link.intf1==node1_intf:
                predest_intf=node1_intf.link.intf2
            else:
                predest_intf=node1_intf.link.intf1
            #TODO:Figure out the present switch-intf name and the port,move them to nameToUnunsedport
            #     And move the intf object to node2
            for name in predest_intf.node.nameToIntf:
                if predest_intf == predest_intf.node.nameToIntf[name]:
                    predest_intf_name=name
                    break 
            predest_intf.node.nameToUnusedPorts[predest_intf_name]=predest_intf.node.ports[predest_intf]
            from mininet.util import moveIntf
            moveIntf(predest_intf, node2)
            #TODO:Put the intf previously moved to node2 in the dicts, that is, replace the dummy_intf
            node2.nameToIntf[intf2_name] = predest_intf
            return

        print "FFFFFFFFFFFFFFFFFFFF"
        intf1 = node1.nameToIntf[intf1_name]
        intf1_other = None
        assert intf1.link != None
        assert intf1.link.intf1 == intf1 or intf1.link.intf2 == intf1
        assert intf1.node == node1
        if intf1.link.intf1 == intf1:
            intf1_other = intf1.link.intf2
        elif intf1.link.intf2 == intf1:
            intf1_other = intf1.link.intf1
        node1_other = intf1_other.node
        intf1_name_other = intf1_other.name   # These three must be saved.
        intf1_port_other = node1_other.ports[intf1_other]

        # Special case: Node already connected to other node.
        if node1_other == node2 and intf1_name_other == intf2_name:
            warn('connection already established\n')
            return

        del node1_other.intfs[ intf1_port_other ]
        del node1_other.ports[ intf1_other ]
        del node1_other.nameToIntf[ intf1_name_other ]
        node1_other.nameToUnusedPorts[ intf1_name_other ] = intf1_port_other

        intf2_port = node2.nameToUnusedPorts[ intf2_name ]
        intf2 = intf1_other
        intf2.rename(intf2_name)
        #intf2.node = node2
        node2.moveIntfFrom(intf2, node1_other, intf2_port)
        intf2.node = node2
        del node2.nameToUnusedPorts[ intf2_name ]