def connectToInternet( network ):
    "Connect the network to the internet"
    switch = network.switches[ 0 ]  # switch to use
    ip = '10.0.0.254'  # our IP address on host network
    routes = [ '10.0.0.0/24' ]  # host networks to route to
    prefixLen = 24 # subnet mask length
    inetIface = "eth0" # host interface for internet connectivity

    # Create a node in root namespace and link to switch 0
    root = Node( 'root', inNamespace=False )
    intf = Link( root, switch ).intf1
    #intf = createLink( root, switch )[ 0 ]
    #root.setIP( intf, ip, prefixLen )
    root.setIP( ip, prefixLen, intf)

    # Start network that now includes link to root namespace
    network.start()

    # Start NAT and establish forwarding
    startNAT( inetIface, root )

    # Establish routes from end hosts
    for host in network.hosts:
        host.cmd( 'ip route flush root 0/0' )
        #host.cmd( 'route add -net 10.0.0.0/24 dev ' + host.intfs[0] )
        host.cmd( 'route add -net 10.0.0.0/24 dev ' + host.intfs[0].name )
        host.cmd( 'route add default gw ' + ip )
        
    return root
Exemple #2
0
def connectToRootNS(network, switch, ip, routes):
    root = Node('root', inNamespace=False)
    intf = network.addLink(root, switch).intf1
    root.setIP(ip, intf=intf)
    network.start()
    for route in routes:
        root.cmd('route add -net {} dev {} '.format(route, intf)) 
class MyTopo(object):
    def __init__(self, cname='onos', cips=['10.0.3.1']):
        # Create network with multiple controllers
        self.net = Mininet(controller=RemoteController, switch=OVSKernelSwitch,
                           build=False)
 
        # Add controllers with input IPs to the network
        ctrls = [RemoteController(cname, cip, 6633) for cip in cips]
        for ctrl in ctrls:
            print ctrl.ip
            self.net.addController(ctrl)
 
        # Add switch
        self.s2 = self.net.addSwitch('s2', dpid='00000000000000a2')
	
	# Connect root namespace to the switch
	self.root = Node('root', inNamespace=False)
	intf = self.net.addLink(self.root, self.s2).intf1
	self.root.setIP('10.0.0.1/32', intf=intf)

	# Add host
	h2 = self.net.addHost('h2', ip='10.0.0.12/24', mac='00:00:00:00:00:02')
	self.net.addLink(h2, self.s2)

    def run(self):
        self.net.build()
        self.net.start()
        self.s2.cmd('ovs-vsctl set bridge s2 protocols=OpenFlow13')
        self.s2.cmd('ovs-vsctl add-port s2 vxlan2')
        self.s2.cmd('ovs-vsctl set interface vxlan2 type=vxlan option:remote_ip=104.236.158.75 option:key=flow')
	self.root.cmd('route add -net 10.0.0.0/24 dev root-eth0')
        CLI(self.net)
        self.net.stop()
Exemple #4
0
def startNetwork(network, switch, ip, routes):
    root = Node('root', inNamespace=False)
    intf = Link(root, switch).intf1
    root.setIP(ip, intf=intf)
    network.start()
    for route in routes:
        root.cmd( 'route add -net ' + route + ' dev ' + str( intf ) )
Exemple #5
0
def connectToRootNS(net,
                    ip='10.123.123.1',
                    mac='00123456789A',
                    prefixLen=8,
                    routes=['10.0.0.0/8']):
    print "*** Creating controller"
    c0 = net.addController('c0', ip='127.0.0.1', port=6633)
    rootswitch = net.addSwitch('roots1', )
    rootswitch.dpid = 'FFFFFFFFFFFFFFFF'
    # Connect hosts to root namespace via switch. Starts network.
    # network: Mininet() network object
    # ip: IP address for root namespace node
    # prefixLen: IP address prefix length (e.g. 8, 16, 24)
    # routes: host networks to route to"
    # Create a node in root namespace and link to switch 0
    root = Node('root', inNamespace=False)
    intf = Link(root, rootswitch).intf1
    intf.setMAC(mac)
    root.setIP(ip, prefixLen, intf)
    print "*** Added Interface", str(intf), "Connected To Root-NameSpace"
    fixNetworkManager(str(intf))
    for host in net.hosts:
        net.addLink(host, rootswitch)
    # Add routes from root ns to hosts
    for route in routes:
        root.cmd('route add -net ' + route + ' dev ' + str(intf))
    root.cmd('service network-manager restart')
    return rootswitch
Exemple #6
0
def connectToRootNS(network, switch, ip, routes):
    root = Node('root', inNamespace=False)
    intf = network.addLink(root, switch).intf1
    root.setIP(ip, intf=intf)
    network.start()

    for route in routes:
        root.cmd('route add -net ' + route + ' dev ' + str(intf))
Exemple #7
0
def start():

    global net, attacker, running

    if running:
        return '\nServer already running.\n'

    setLogLevel('info')

    topo = MixTopo()
    net = Mininet(topo=topo)

    s1 = net['s1']
    plc2 = net['plc2']
    plc3 = net['plc3']

    s2, rtu2a, scada = net.get('s2', 'rtu2a', 'scada')
    rtu2b, attacker2 = net.get('rtu2b', 'attacker2')
    s3 = net.get('s3')

    # NOTE: root-eth0 interface on the host
    root = Node('root', inNamespace=False)
    intf = net.addLink(root, s3).intf1
    print('DEBUG root intf: {}'.format(intf))
    root.setIP('10.0.0.30', intf=intf)
    # NOTE: all packet from root to the 10.0.0.0 network
    root.cmd('route add -net ' + '10.0.0.0' + ' dev ' + str(intf))


    net.start()
    info('Welcome')

    # NOTE: use for debugging
    #s1.cmd('tcpdump -i s1-eth1 -w /tmp/s1-eth1.pcap &')
    #s1.cmd('tcpdump -i s1-eth2 -w /tmp/s1-eth2.pcap &')

    SLEEP = 0.5

    # NOTE: swat challenge 1 and 2
    plc3.cmd(sys.executable + ' plc3.py &')
    sleep(SLEEP)
    plc2.cmd(sys.executable + ' plc2.py &')
    sleep(SLEEP)

    # NOTE: wadi challenge 1
    scada.cmd(sys.executable + ' scada.py &')
    sleep(SLEEP)
    rtu2a.cmd(sys.executable + ' rtu2a.py &')
    sleep(SLEEP)
    # NOTE: wadi challenge 2
    rtu2b.cmd(sys.executable + ' rtu2b.py &')
    sleep(SLEEP)


    running = True
    return '\nServer started.\n'
Exemple #8
0
def start():

    global net, attacker, running

    if running:
        return '\nServer already running.\n'

    setLogLevel('info')

    topo = MixTopo()
    net = Mininet(topo=topo)

    s1 = net['s1']
    plc2 = net['plc2']
    plc3 = net['plc3']

    s2, rtu2a, scada = net.get('s2', 'rtu2a', 'scada')
    rtu2b, attacker2 = net.get('rtu2b', 'attacker2')
    s3 = net.get('s3')

    # NOTE: root-eth0 interface on the host
    root = Node('root', inNamespace=False)
    intf = net.addLink(root, s3).intf1
    print('DEBUG root intf: {}'.format(intf))
    root.setIP('10.0.0.30', intf=intf)
    # NOTE: all packet from root to the 10.0.0.0 network
    root.cmd('route add -net ' + '10.0.0.0' + ' dev ' + str(intf))


    net.start()
    info('Welcome')

    # NOTE: use for debugging
    #s1.cmd('tcpdump -i s1-eth1 -w /tmp/s1-eth1.pcap &')
    #s1.cmd('tcpdump -i s1-eth2 -w /tmp/s1-eth2.pcap &')

    SLEEP = 0.5

    # NOTE: swat challenge 1 and 2
    plc3.cmd(sys.executable + ' plc3.py &')
    sleep(SLEEP)
    plc2.cmd(sys.executable + ' plc2.py &')
    sleep(SLEEP)

    # NOTE: wadi challenge 1
    scada.cmd(sys.executable + ' scada.py &')
    sleep(SLEEP)
    rtu2a.cmd(sys.executable + ' rtu2a.py &')
    sleep(SLEEP)
    # NOTE: wadi challenge 2
    rtu2b.cmd(sys.executable + ' rtu2b.py &')
    sleep(SLEEP)


    running = True
    return '\nServer started.\n'
Exemple #9
0
def sshd(net):
    root = Node('root', inNamespace=False)
    intf = net.addLink(root, net['s3']).intf1
    root.setIP('10.0.0.4/24', intf=intf)

    net.start()
    root.cmd('route add -net 10.0.0.0/24 dev ' + str(intf))

    for host in net.hosts:
        host.cmd('/usr/sbin/sshd -D -o UseDNS=no -u0&')
def scratchNet(cname='controller', cargs='-v ptcp:'):
    "Create network from scratch using Open vSwitch."

    info("*** Creating nodes\n")
    controller = Node('c0', inNamespace=False)
    switch = Node('s0', inNamespace=False)
    h0 = Node('h0')
    h1 = Node('h1')

    info("*** Creating links\n")
    Link(h0, switch)
    Link(h1, switch)

    info("*** Configuring hosts\n")
    h0.setIP('192.168.123.1/24')
    h1.setIP('192.168.123.2/24')
    info(str(h0) + '\n')
    info(str(h1) + '\n')

    info("*** Starting network using Open vSwitch\n")
    controller.cmd(cname + ' ' + cargs + '&')
    switch.cmd('ovs-vsctl del-br dp0')
    switch.cmd(
        'ovs-vsctl add-br dp0 other-config:datapath-id={}'.format(datapath_id))
    for intf in switch.intfs.values():
        print switch.cmd('ovs-vsctl add-port dp0 %s' % intf)

    # Note: controller and switch are in root namespace, and we
    # can connect via loopback interface
    s_cmd = 'ovs-vsctl set-controller dp0 tcp:[{}]:{}'.format(
        CTLR_IP, CTLR_PRT)
    print s_cmd
    switch.cmd(s_cmd)
    ping_results = [
        'received,host,jitter,packet_loss,avgping,minping,time,sent,maxping\n'
    ]
    try:
        h0.cmd('echo "" > pings.txt')
        if mode == 0:
            step_wise_testing(h0, h1, ping_results)
        else:
            continuous_testing(h0, h1, ping_results)
    except KeyboardInterrupt:
        print "Warning: Caught KeyboardInterrupt, stopping network"
        tm_local = time.localtime()
        dt = time.gmtime()
        file_name = 'pings_{}_{}_{}-{}_{}_{}.csv'.format(
            dt.tm_year, dt.tm_mon, dt.tm_mday, tm_local.tm_hour,
            tm_local.tm_min, tm_local.tm_sec)
        f = open(file_name, 'w+')
        for item in ping_results:
            f.write(item)
        stop_net(controller, cname, switch)
Exemple #11
0
def DeltaNetwork():
    #Make topology
    net = Mininet(topo=None, controller=None, build=False)

    #Add switch
    proto = sys.argv[5]
    s0 = net.addSwitch('s0', dpid='00:00:00:00:00:01', protocols=proto)
    s1 = net.addSwitch('s1', dpid='00:00:00:00:00:02',
                       protocols=proto)  # for connections with DELTA

    #Add hosts
    h1 = net.addHost('h1', ip='10.0.0.1/24', mac='00:00:00:00:00:11')
    h2 = net.addHost('h2', ip='10.0.0.2/24', mac='00:00:00:00:00:22')

    #Add links
    net.addLink(s0, h1)
    net.addLink(s0, h2)

    net.addLink(s1, h1, intfName2='host-eth')

    root = Node('root', inNamespace=False)
    intf = net.addLink(root, s1).intf1
    root.setIP('10.0.1.1', intf=intf)

    #       net.build()
    net.start()

    f = os.popen(
        'ifconfig eth0 | grep "inet\ addr" | cut -d: -f2 | cut -d" " -f1')
    ip = f.read()[:-1]

    root.cmd('route add -net 10.0.1.0/24 dev ' + str(intf))
    h1.cmd("ifconfig host-eth 10.0.1.2/24 netmask 255.255.255.0")
    h1.cmd('route add -net 10.0.3.0/24 dev host-eth')
    h1.cmd('route add -net 10.0.3.0/24 gw ' + str(ip) + ' dev host-eth')

    #Set ip
    os.system(
        "sudo ovs-ofctl -O OpenFlow13 add-flow s1 in_port=1,actions=output:2")
    os.system(
        "sudo ovs-ofctl -O OpenFlow13 add-flow s1 in_port=2,actions=output:1")

    #h1.cmd("dhclient eth0")

    #connect a controller
    os.system("sudo ovs-vsctl set-controller s0 tcp:" + sys.argv[1] + ":" +
              sys.argv[2])

    h1.cmd("java -jar $HOME/delta-agent-host-1.0-SNAPSHOT.jar " + sys.argv[3] +
           " " + sys.argv[4])
    CLI(net)
    net.stop()
Exemple #12
0
 def enableSSH(self, net):
     print 'Enabling ssh'
     routes = ['10.0.0.0/24']
     ip = '10.123.123.1/32'
     switch = self.CoreSwitchList[0]
     print switch
     switch = net[switch]
     root = Node('root', inNamespace=False)
     intf = Link(root, switch).intf1
     root.setIP(ip, intf=intf)
     net.start()
     for route in routes:
         root.cmd('route add -net ' + route + ' dev ' + str(intf))
Exemple #13
0
def sshd_connectToRootNS(args,network):
	
	#we create node root and attach it to a swtich
	switch = network.getNodeByName(args.names.sw_sshd[0])

	#ip of root
	ip = '172.16.255.1/32' 
	
	root = Node( 'root', inNamespace=False )
	intf = Link( root, switch ).intf1
	root.setIP( ip, intf=intf )

	return root,intf
Exemple #14
0
def connectToRootNS(network, switch, ip, routes):
    root = Node('root', inNamespace=False)
    intf = network.addLink(root, switch).intf1
    root.setIP(ip, intf=intf)
    root.setMAC("10:00:00:00:00:00")

    network.start()
    sleep(10)
    for route in routes:
        root.cmd('route add -net ' + route + ' dev ' + str(intf))
        print("route add completed=================")
    for route in routes:
        root.cmd('route add -net ' + route + ' dev ' + str(intf))
        print("route add completed=================")
Exemple #15
0
def scratchNet(cname='controller', cargs='-v ptcp:'):
    "Create network from scratch using Open vSwitch."

    info("*** Creating nodes\n")
    controller = Node('c0', inNamespace=False)
    switch = Node('s0', inNamespace=False)
    h0 = Node('h0')
    h1 = Node('h1')

    info("*** Creating links\n")
    Link(h0, switch)
    Link(h1, switch)

    info("*** Configuring hosts\n")
    h0.setIP('192.168.123.1/24')
    h1.setIP('192.168.123.2/24')
    info(str(h0) + '\n')
    info(str(h1) + '\n')

    info("*** Starting network using Open vSwitch\n")
    controller.cmd(cname + ' ' + cargs + '&')
    switch.cmd('ovs-vsctl del-br dp0')
    switch.cmd('ovs-vsctl add-br dp0')
    for intf in switch.intfs.values():
        print switch.cmd('ovs-vsctl add-port dp0 %s' % intf)

    # Note: controller and switch are in root namespace, and we
    # can connect via loopback interface
    s_cmd = 'ovs-vsctl set-controller dp0 tcp:[{}]:{}'.format(
        CTLR_IP, CTLR_PRT)
    print s_cmd
    switch.cmd(s_cmd)

    info('*** Waiting for switch to connect to controller')
    try:
        while 'is_connected' not in quietRun('ovs-vsctl show'):
            sleep(1)
            info('.')

        info('\n')

        while True:
            info("*** Running test\n")
            h0.cmdPrint('ping -c1 ' + h1.IP())
            info("*** Sleep\n")
            sleep(2)
    except KeyboardInterrupt:
        print "Warning: Caught KeyboardInterrupt, stopping network"
        stop_net(controller, cname, switch)
Exemple #16
0
def scratchNet(cname='controller', cargs='-v ptcp:'):
    "Create network from scratch using Open vSwitch."

    info("*** Creating nodes\n")
    controller = Node('c0', inNamespace=False)
    switch0 = Node('s0', inNamespace=False)
    h0 = Node('h0')
    h1 = Node('h1')

    info("*** Creating links\n")
    Link(h0, switch0)
    Link(h1, switch0)

    info("*** Configuring hosts\n")
    h0.setIP('192.168.123.1/24')
    h1.setIP('192.168.123.2/24')
    info(str(h0) + '\n')
    info(str(h1) + '\n')

    info("*** Starting network using Open vSwitch\n")
    controller.cmd(cname + ' ' + cargs + '&')
    switch0.cmd('ovs-vsctl del-br dp0')
    switch0.cmd('ovs-vsctl add-br dp0')

    for intf in switch0.intfs.values():
        print intf
        print switch0.cmd('ovs-vsctl add-port dp0 %s' % intf)

    # Note: controller and switch are in root namespace, and we
    # can connect via loopback interface
    switch0.cmd('ovs-vsctl set-controller dp0 tcp:127.0.0.1:6633')
    switch0.cmd('ovs-ofctl add-flow dp0 \"in_port=1 actions=output:2\"')
    switch0.cmd('ovs-ofctl add-flow dp0 \"in_port=2 actions=output:1\"')

    info('*** Waiting for switch to connect to controller')
    while 'is_connected' not in quietRun('ovs-vsctl show'):
        sleep(1)
        info('.')
    info('\n')

    info("*** Running test\n")
    h0.cmdPrint('ping -c3 ' + h1.IP())
    h1.cmdPrint('ping -c3 ' + h0.IP())

    info("*** Stopping network\n")
    controller.cmd('kill %' + cname)
    switch0.cmd('ovs-vsctl del-br dp0')
    switch0.deleteIntfs()
    info('\n')
def connectToRootNS( network, switch, ip, routes ):
    """Connect hosts to root namespace via switch. Starts network.
      network: Mininet() network object
      switch: switch to connect to root namespace
      ip: IP address for root namespace node
      routes: host networks to route to"""
    # Create a node in root namespace and link to switch 0
    root = Node( 'root', inNamespace=False )
    intf = network.addLink( root, switch ).intf1
    root.setIP( ip, intf=intf )
    # Start network that now includes link to root namespace
    network.start()
    # Add routes from root ns to hosts
    for route in routes:
        root.cmd( 'route add -net ' + route + ' dev ' + str( intf ) )
def connectToRootNS(network, switch, ip, routes):
    """Connect hosts to root namespace via switch. Starts network.
      network: Mininet() network object
      switch: switch to connect to root namespace
      ip: IP address for root namespace node
      routes: host networks to route to"""
    # Create a node in root namespace and link to switch 0
    root = Node('root', inNamespace=False)
    intf = network.addLink(root, switch).intf1
    root.setIP(ip, intf=intf)
    # Start network that now includes link to root namespace
    network.start()
    # Add routes from root ns to hosts
    for route in routes:
        root.cmd('route add -net ' + route + ' dev ' + str(intf))
Exemple #19
0
def start_network():
    '''
    Start mininet network
    '''
    lg.setLogLevel('info')
    topo = TreeTopo(1, options.hosts)
    net = Mininet(topo=topo, switch=OVSBridge, controller=None, waitConnected=True)
    switch = net['s1']
    routes = ['10.0.0.0/24']
    root = Node('root', inNamespace=False)
    interface = net.addLink(root, switch).intf1
    root.setIP('10.123.123.1/32', intf=interface)
    net.start()
    for route in routes:
        root.cmd('route add -net {} dev {}'.format(route, interface))
    return net
Exemple #20
0
def connectToRootNS(network, switch, ip, prefixLen, routes):
    "Connect hosts to root namespace via switch. Starts network."
    "network: Mininet() network object"
    "switch: switch to connect to root namespace"
    "ip: IP address for root namespace node"
    "prefixLen: IP address prefix length (e.g. 8, 16, 24)"
    "routes: host networks to route to"
    # Create a node in root namespace and link to switch 0
    root = Node('root', inNamespace=False)
    intf = TCLink(root, switch).intf1
    root.setIP(ip, prefixLen, intf)
    # Start network that now includes link to root namespace
    network.start()
    # Add routes from root ns to hosts
    for route in routes:
        root.cmd('route add -net ' + route + ' dev ' + str(intf))
def connectToRootNS( network, switch, ip, prefixLen, routes ):
    "Connect hosts to root namespace via switch. Starts network."
    "network: Mininet() network object"
    "switch: switch to connect to root namespace"
    "ip: IP address for root namespace node"
    "prefixLen: IP address prefix length (e.g. 8, 16, 24)"
    "routes: host networks to route to"
    # Create a node in root namespace and link to switch 0
    root = Node( 'root', inNamespace=False )
    intf = TCLink( root, switch ).intf1
    root.setIP( ip, prefixLen, intf )
    # Start network that now includes link to root namespace
    network.start()
    # Add routes from root ns to hosts
    for route in routes:
        root.cmd( 'route add -net ' + route + ' dev ' + str( intf ) )
Exemple #22
0
def scratchNet(cname='controller', cargs='-v ptcp:'):
    #create network from scratch using Open vswitch
    info("***Creating nodes\n")
    controller = Node('c0', inNamespace=False)
    switch0 = Node('s0', inNamespace=False)
    h0 = Node('h0')
    h1 = Node('h1')

    info("***Creating links\n")
    Link(h0, switch0)
    Link(h1, switch0)

    info(" ***Configuring hosts\n")
    h0.setIP('192.168.123.1/24')
    h1.setIP('192.168.123.2/24')
    info(str(h0) + '\n')
    info(str(h1) + '\n')
Exemple #23
0
def run():
    topo = MyTopo()
    net = Mininet(topo=topo, controller=None, link=TCLink)
    net.addController('c0',
                      controller=RemoteController,
                      ip='127.0.0.1',
                      port=6633)

    print("=== Add root ===")
    root = Node('root', inNamespace=False)
    intf = net.addLink(root, net['s1']).intf1
    root.setIP('192.168.44.100/32', intf=intf)

    net.start()
    s8 = net.getNodeByName('s8')
    h9 = net.getNodeByName('h9')
    net.configLinkStatus(s8, h9, 'down')

    print("=== Run apache server ===")
    portal = net.getNodeByName('portal')
    portal.cmdPrint('/etc/init.d/apache2 restart')

    print("=== Run DHCP server ===")
    dhcp = net.getNodeByName('dhcp')
    # dhcp.cmdPrint('service isc-dhcp-server restart &')
    dhcp.cmdPrint(
        '/usr/sbin/dhcpd -q 4 -pf /run/dhcp-server-dhcpd.pid -cf ./dhcpd.conf %s'
        % dhcp.defaultIntf())

    print("=== Request IP ===")
    for host in net.hosts:
        if str(host) != 'portal' and str(host) != 'dhcp' and str(
                host) != 'web' and str(host) != 'h9':
            host.cmdPrint('dhclient ' + host.defaultIntf().name)

    print("=== Open simple HTTP server ===")
    web = net.getNodeByName('web')
    web.cmdPrint('python -m SimpleHTTPServer 80 &')

    print("=== Set route ===")
    for route in ['192.168.44.0/24']:
        root.cmd('route add -net ' + route + ' dev ' + str(intf))

    CLI(net)
    net.stop()
def scratchNet( cname='controller', cargs='-v ptcp:' ):
    "Create network from scratch using Open vSwitch."

    info( "*** Creating nodes\n" )
    controller = Node( 'c0', inNamespace=False )
    switch = Node( 's0', inNamespace=False )
    h0 = Node( 'h0' )
    h1 = Node( 'h1' )

    info( "*** Creating links\n" )
    Link( h0, switch )
    Link( h1, switch )

    info( "*** Configuring hosts\n" )
    h0.setIP( '192.168.123.1/24' )
    h1.setIP( '192.168.123.2/24' )
    info( str( h0 ) + '\n' )
    info( str( h1 ) + '\n' )

    info( "*** Starting network using Open vSwitch\n" )
    controller.cmd( cname + ' ' + cargs + '&' )
    switch.cmd( 'ovs-vsctl del-br dp0' )
    switch.cmd( 'ovs-vsctl add-br dp0' )
    for intf in switch.intfs.values():
        print switch.cmd( 'ovs-vsctl add-port dp0 %s' % intf )

    # Note: controller and switch are in root namespace, and we
    # can connect via loopback interface
    switch.cmd( 'ovs-vsctl set-controller dp0 tcp:127.0.0.1:6633' )

    info( '*** Waiting for switch to connect to controller' )
    while 'is_connected' not in quietRun( 'ovs-vsctl show' ):
        sleep( 1 )
        info( '.' )
    info( '\n' )

    info( "*** Running test\n" )
    h0.cmdPrint( 'ping -c1 ' + h1.IP() )

    info( "*** Stopping network\n" )
    controller.cmd( 'kill %' + cname )
    switch.cmd( 'ovs-vsctl del-br dp0' )
    switch.deleteIntfs()
    info( '\n' )
Exemple #25
0
def scratchNet(cname="controller", cargs="-v ptcp:"):
    "Create network from scratch using Open vSwitch."

    info("*** Creating nodes\n")
    controller = Node("c0", inNamespace=False)
    switch = Node("s0", inNamespace=False)
    h0 = Node("h0")
    h1 = Node("h1")

    info("*** Creating links\n")
    Link(h0, switch)
    Link(h1, switch)

    info("*** Configuring hosts\n")
    h0.setIP("192.168.123.1/24")
    h1.setIP("192.168.123.2/24")
    info(str(h0) + "\n")
    info(str(h1) + "\n")

    info("*** Starting network using Open vSwitch\n")
    controller.cmd(cname + " " + cargs + "&")
    switch.cmd("ovs-vsctl del-br dp0")
    switch.cmd("ovs-vsctl add-br dp0")
    for intf in switch.intfs.values():
        print(switch.cmd("ovs-vsctl add-port dp0 %s" % intf))

    # Note: controller and switch are in root namespace, and we
    # can connect via loopback interface
    switch.cmd("ovs-vsctl set-controller dp0 tcp:127.0.0.1:6633")

    info("*** Waiting for switch to connect to controller")
    while "is_connected" not in quietRun("ovs-vsctl show"):
        sleep(1)
        info(".")
    info("\n")

    info("*** Running test\n")
    h0.cmdPrint("ping -c1 " + h1.IP())

    info("*** Stopping network\n")
    controller.cmd("kill %" + cname)
    switch.cmd("ovs-vsctl del-br dp0")
    switch.deleteIntfs()
    info("\n")
Exemple #26
0
def myNet():
    "Create network from scratch using Open vSwitch."
 
    info( "*** Creating nodes\n" )
    switch0 = Node( 's0', inNamespace=False )
 
    h0 = Node( 'h0' )
    h1 = Node( 'h1' )
    h2 = Node( 'h2' )
 
    info( "*** Creating links\n" )
    Link( h0, switch0)
    Link( h1, switch0)
    Link( h2, switch0)
 
    info( "*** Configuring hosts\n" )
    h0.setIP( '192.168.123.1/24' )
    h1.setIP( '192.168.123.2/24' )
    h2.setIP( '192.168.123.3/24' )
       
    info( "*** Starting network using Open vSwitch\n" )
    switch0.cmd( 'ovs-vsctl del-br dp0' )
    switch0.cmd( 'ovs-vsctl add-br dp0' )
 
    for intf in switch0.intfs.values():
        print intf
        print switch0.cmd( 'ovs-vsctl add-port dp0 %s' % intf )
 
    # Note: controller and switch are in root namespace, and we
    # can connect via loopback interface
    #switch0.cmd( 'ovs-vsctl set-controller dp0 tcp:127.0.0.1:6633' )
  
    print switch0.cmd(r'ovs-vsctl show')
 
    print switch0.cmd(r'ovs-ofctl add-flow dp0 idle_timeout=0,priority=1,in_port=1,actions=flood' ) 
    print switch0.cmd(r'ovs-ofctl add-flow dp0 idle_timeout=0,priority=1,in_port=2,actions=flood' )
    print switch0.cmd(r'ovs-ofctl add-flow dp0 idle_timeout=0,priority=1,in_port=3,actions=flood' )
  
    print switch0.cmd(r'ovs-ofctl add-flow dp0 idle_timeout=0,priority=10,ip,nw_dst=192.168.123.1,actions=output:1' ) 
    print switch0.cmd(r'ovs-ofctl add-flow dp0 idle_timeout=0,priority=10,ip,nw_dst=192.168.123.2,actions=output:2' ) 
    print switch0.cmd(r'ovs-ofctl add-flow dp0 idle_timeout=0,priority=10,ip,nw_dst=192.168.123.3,actions=output:3')
 
    #switch0.cmd('tcpdump -i s0-eth0 -U -w aaa &')
    #h0.cmd('tcpdump -i h0-eth0 -U -w aaa &')
    info( "*** Running test\n" )
    h0.cmdPrint( 'ping -c 3 ' + h1.IP() )
    h0.cmdPrint( 'ping -c 3 ' + h2.IP() )
 
    #print switch0.cmd( 'ovs-ofctl show dp0' )    
    #print switch0.cmd( 'ovs-ofctl dump-tables  dp0' )
    #print switch0.cmd( 'ovs-ofctl dump-ports   dp0' )
    #print switch0.cmd( 'ovs-ofctl dump-flows  dp0' )
    #print switch0.cmd( 'ovs-ofctl dump-aggregate  dp0' )
    #print switch0.cmd( 'ovs-ofctl queue-stats dp0' )
 
    info( "*** Stopping network\n" )
    switch0.cmd( 'ovs-vsctl del-br dp0' )
    switch0.deleteIntfs()
    info( '\n' )
Exemple #27
0
def createAgentNet( k, routeIP ):
    net = Mininet( controller=Controller, switch=OVSBridge )

    print "*** Creating agent network"
    sw = net.addSwitch( 's%s' % (k+1) )
    for i in range( 1, k+1 ):
        host = net.addHost( 'agent%s' % i, ip='171.0.0.%s/16' % i )
        intf = net.addLink( sw, host ).intf2
        if routeIP != '127.0.0.1':
            # host.setHostRoute( routeIP, intf ) # this api does not work!!!
            host.cmd( 'ip route add %s dev %s' % ( routeIP, str( intf ) ) )

    # c = net.addController('c1', controller=Controller, ip='127.0.0.1', port=6699)

    root = Node( 'root', inNamespace=False )
    intf = net.addLink( root, sw ).intf1
    root.setIP( '171.0.123.1/16', intf=intf )
    # root.cmd( 'route add -net 171.0.0.0/16 dev ' + str( intf ) )

    net.build()
    # c.start()
    sw.start( [] )
    return net
Exemple #28
0
def createAgentNet(k, routeIP):
    net = Mininet(controller=Controller, switch=OVSBridge)

    print "*** Creating agent network"
    sw = net.addSwitch('s%s' % (k + 1))
    for i in range(1, k + 1):
        host = net.addHost('agent%s' % i, ip='171.0.0.%s/16' % i)
        intf = net.addLink(sw, host).intf2
        if routeIP != '127.0.0.1':
            # host.setHostRoute( routeIP, intf ) # this api does not work!!!
            host.cmd('ip route add %s dev %s' % (routeIP, str(intf)))

    # c = net.addController('c1', controller=Controller, ip='127.0.0.1', port=6699)

    root = Node('root', inNamespace=False)
    intf = net.addLink(root, sw).intf1
    root.setIP('171.0.123.1/16', intf=intf)
    # root.cmd( 'route add -net 171.0.0.0/16 dev ' + str( intf ) )

    net.build()
    # c.start()
    sw.start([])
    return net
def scratchNet(cname='controller', cargs='ptcp:'):
    "Create network from scratch using kernel switch."

    info("*** Creating nodes\n")
    controller = Node('c0', inNamespace=False)
    switch = Node('s0', inNamespace=False)
    h0 = Node('h0')
    h1 = Node('h1')

    info("*** Creating links\n")
    createLink(node1=h0, node2=switch, port1=0, port2=0)
    createLink(node1=h1, node2=switch, port1=0, port2=1)

    info("*** Configuring hosts\n")
    h0.setIP(h0.intfs[0], '192.168.123.1', 24)
    h1.setIP(h1.intfs[0], '192.168.123.2', 24)
    info(str(h0) + '\n')
    info(str(h1) + '\n')

    info("*** Starting network using Open vSwitch kernel datapath\n")
    controller.cmd(cname + ' ' + cargs + '&')
    switch.cmd('ovs-dpctl del-dp dp0')
    switch.cmd('ovs-dpctl add-dp dp0')
    for intf in switch.intfs.values():
        print switch.cmd('ovs-dpctl add-if dp0 ' + intf)
    print switch.cmd('ovs-openflowd dp0 tcp:127.0.0.1 &')

    info("*** Running test\n")
    h0.cmdPrint('ping -c1 ' + h1.IP())

    info("*** Stopping network\n")
    controller.cmd('kill %' + cname)
    switch.cmd('ovs-dpctl del-dp dp0')
    switch.cmd('kill %ovs-openflowd')
    switch.deleteIntfs()
    info('\n')
Exemple #30
0
def scratchNet( cname='controller', cargs='ptcp:' ):
    "Create network from scratch using kernel switch."

    info( "*** Creating nodes\n" )
    controller = Node( 'c0', inNamespace=False )
    switch = Node( 's0', inNamespace=False )
    h0 = Node( 'h0' )
    h1 = Node( 'h1' )

    info( "*** Creating links\n" )
    createLink( node1=h0, node2=switch, port1=0, port2=0 )
    createLink( node1=h1, node2=switch, port1=0, port2=1 )

    info( "*** Configuring hosts\n" )
    h0.setIP( h0.intfs[ 0 ], '192.168.123.1', 24 )
    h1.setIP( h1.intfs[ 0 ], '192.168.123.2', 24 )
    info( str( h0 ) + '\n' )
    info( str( h1 ) + '\n' )

    info( "*** Starting network using Open vSwitch kernel datapath\n" )
    controller.cmd( cname + ' ' + cargs + '&' )
    switch.cmd( 'ovs-dpctl del-dp dp0' )
    switch.cmd( 'ovs-dpctl add-dp dp0' )
    for intf in switch.intfs.values():
        print switch.cmd( 'ovs-dpctl add-if dp0 ' + intf )
    print switch.cmd( 'ovs-openflowd dp0 tcp:127.0.0.1 &' )

    info( "*** Running test\n" )
    h0.cmdPrint( 'ping -c1 ' + h1.IP() )

    info( "*** Stopping network\n" )
    controller.cmd( 'kill %' + cname )
    switch.cmd( 'ovs-dpctl del-dp dp0' )
    switch.cmd( 'kill %ovs-openflowd' )
    switch.deleteIntfs()
    info( '\n' )
Exemple #31
0
def connectToRootNS(net, num_cloudlets):
    root = Node('root', inNamespace=False)
    switch = net['cs0']
    ip = config.master_root_ip
    main_intf = net.addLink(root, switch).intf1
    root.setIP(ip, intf=main_intf)

    # TODO better id?
    dpid = '%010x' % 130013
    device_switch = net.addSwitch('ds', dpid=dpid)
    intf = net.addLink(root, device_switch).intf1
    root.setIP(config.master_to_device_ip, intf=intf)

    intf = net.addLink(net['device'],
                       device_switch,
                       intf1Name="dev_root",
                       intf2Name="root_dev").intf1
    net['device'].setIP(config.device_to_master_ip, intf=intf)
    # TODO do we need routing rules for device?

    routes = [
        get_ip(a=x, suffix=16) for x in (
            config.mesh_network_prefix,
            config.tower_network_prefix,
        )
    ]
    for i in range(1, num_cloudlets):
        routes.append(get_ip(a=config.cloudlet_network_prefix, c=i, suffix=24))

    default_route_ip = get_ip(a=config.cloudlet_network_prefix, d=1)
    print "root routes"
    for route in routes:
        print 'ip route add to %s via %s dev %s' % (route, default_route_ip,
                                                    main_intf)
        root.cmd('ip route add to %s via %s dev %s' %
                 (route, default_route_ip, main_intf))
def connectToRootNS( net, ip='10.123.123.1', mac='00123456789A', prefixLen=8, routes=['10.0.0.0/8']):
	print "*** Creating controller"
	c0 = net.addController( 'c0', ip='127.0.0.1', port=6633 )
	rootswitch = net.addSwitch('roots1',)
	rootswitch.dpid = 'FFFFFFFFFFFFFFFF'
	# Connect hosts to root namespace via switch. Starts network.
	# network: Mininet() network object
	# ip: IP address for root namespace node
	# prefixLen: IP address prefix length (e.g. 8, 16, 24)
	# routes: host networks to route to"
	# Create a node in root namespace and link to switch 0
	root = Node( 'root', inNamespace=False )
	intf = Link( root, rootswitch ).intf1
	intf.setMAC(mac)
	root.setIP( ip, prefixLen, intf )
	print "*** Added Interface", str(intf), "Connected To Root-NameSpace"
	fixNetworkManager(str(intf))
	for host in net.hosts:
	    net.addLink(host,rootswitch)
	# Add routes from root ns to hosts
	for route in routes:
         root.cmd( 'route add -net ' + route + ' dev ' + str( intf ) )
	root.cmd('service network-manager restart')
	return rootswitch
Exemple #33
0
def scratchNetUser( cname='controller', cargs='ptcp:' ):
    "Create network from scratch using user switch."

    # It's not strictly necessary for the controller and switches
    # to be in separate namespaces. For performance, they probably
    # should be in the root namespace. However, it's interesting to
    # see how they could work even if they are in separate namespaces.

    info( '*** Creating Network\n' )
    controller = Node( 'c0' )
    switch = Node( 's0')
    h0 = Node( 'h0' )
    h1 = Node( 'h1' )
    cintf, sintf = createLink( controller, switch )
    h0intf, sintf1 = createLink( h0, switch )
    h1intf, sintf2 = createLink( h1, switch )

    info( '*** Configuring control network\n' )
    controller.setIP( cintf, '10.0.123.1', 24 )
    switch.setIP( sintf, '10.0.123.2', 24 )

    info( '*** Configuring hosts\n' )
    h0.setIP( h0intf, '192.168.123.1', 24 )
    h1.setIP( h1intf, '192.168.123.2', 24 )

    info( '*** Network state:\n' )
    for node in controller, switch, h0, h1:
        info( str( node ) + '\n' )

    info( '*** Starting controller and user datapath\n' )
    controller.cmd( cname + ' ' + cargs + '&' )
    switch.cmd( 'ifconfig lo 127.0.0.1' )
    intfs = [ sintf1, sintf2 ]
    switch.cmd( 'ofdatapath -i ' + ','.join( intfs ) + ' ptcp: &' )
    switch.cmd( 'ofprotocol tcp:' + controller.IP() + ' tcp:localhost &' )

    info( '*** Running test\n' )
    h0.cmdPrint( 'ping -c1 ' + h1.IP() )

    info( '*** Stopping network\n' )
    controller.cmd( 'kill %' + cname )
    switch.cmd( 'kill %ofdatapath' )
    switch.cmd( 'kill %ofprotocol' )
    switch.deleteIntfs()
    info( '\n' )
def scratchNetUser(cname='controller', cargs='ptcp:'):
    "Create network from scratch using user switch."

    # It's not strictly necessary for the controller and switches
    # to be in separate namespaces. For performance, they probably
    # should be in the root namespace. However, it's interesting to
    # see how they could work even if they are in separate namespaces.

    info('*** Creating Network\n')
    controller = Node('c0')
    switch = Node('s0')
    h0 = Node('h0')
    h1 = Node('h1')
    cintf, sintf = createLink(controller, switch)
    h0intf, sintf1 = createLink(h0, switch)
    h1intf, sintf2 = createLink(h1, switch)

    info('*** Configuring control network\n')
    controller.setIP(cintf, '10.0.123.1', 24)
    switch.setIP(sintf, '10.0.123.2', 24)

    info('*** Configuring hosts\n')
    h0.setIP(h0intf, '192.168.123.1', 24)
    h1.setIP(h1intf, '192.168.123.2', 24)

    info('*** Network state:\n')
    for node in controller, switch, h0, h1:
        info(str(node) + '\n')

    info('*** Starting controller and user datapath\n')
    controller.cmd(cname + ' ' + cargs + '&')
    switch.cmd('ifconfig lo 127.0.0.1')
    intfs = [sintf1, sintf2]
    switch.cmd('ofdatapath -i ' + ','.join(intfs) + ' ptcp: &')
    switch.cmd('ofprotocol tcp:' + controller.IP() + ' tcp:localhost &')

    info('*** Running test\n')
    h0.cmdPrint('ping -c1 ' + h1.IP())

    info('*** Stopping network\n')
    controller.cmd('kill %' + cname)
    switch.cmd('kill %ofdatapath')
    switch.cmd('kill %ofprotocol')
    switch.deleteIntfs()
    info('\n')
Exemple #35
0
def myNet(cname='controller', cargs='-v ptcp:'):
    "Create network from scratch using Open vSwitch."
    info( "*** Creating nodes\n" )
    controller = Node( 'c0', inNamespace=False )
    switch = Node( 's0', inNamespace=False )
    h0 = Node( 'h0' )
    h1 = Node( 'h1' )
    h2 = Node( 'h2' )
 
    info( "*** Creating links\n" )
    linkopts0=dict(bw=100, delay='1ms', loss=0)
    TCLink( h0, switch, **linkopts0)
    TCLink( h1, switch, **linkopts0)
    TCLink( h2, switch, **linkopts0)
 
    info( "*** Configuring hosts\n" )
    h0.setIP( '192.168.123.1/24' )
    h1.setIP( '192.168.123.2/24' )
    h2.setIP( '192.168.123.3/24' )
       
    info( "*** Starting network using Open vSwitch\n" )
    switch.cmd( 'ovs-vsctl del-br dp0' )
    switch.cmd( 'ovs-vsctl add-br dp0' )
 
    controller.cmd( cname + ' ' + cargs + '&' )    
    for intf in switch.intfs.values():
        print intf
        print switch.cmd( 'ovs-vsctl add-port dp0 %s' % intf )
  
    # Note: controller and switch are in root namespace, and we
    # can connect via loopback interface
    switch.cmd( 'ovs-vsctl set-controller dp0 tcp:127.0.0.1:6633' )
   
    info( '*** Waiting for switch to connect to controller' )
    while 'is_connected' not in quietRun( 'ovs-vsctl show' ):
        sleep( 1 )
        info( '.' )
    info( '\n' )
 
    #info( "*** Running test\n" )
    h0.cmdPrint( 'ping -c 3 ' + h1.IP() )
    h0.cmdPrint( 'ping -c 3 ' + h2.IP() )
    h2.cmdPrint( 'ping -c 3 ' + h1.IP() )
 
    info( "*** Stopping network\n" )
    controller.cmd( 'kill %' + cname )
    switch.cmd( 'ovs-vsctl del-br dp0' )
    switch.deleteIntfs()
    info( '\n' )
	net.addLink(s1,s2)
	net.addLink(s2,s3)
	net.addLink(s2,s4)
	net.addLink(s4,p1s1)
	net.addLink(s4,p1s2)
	net.addLink(s3,p1s3)
	net.addLink(s3,p1s4)
	



	#
	# Connect to root namespace (borrowed from mininet/examples/sshd.py)
	root = Node( 'root', inNamespace=False )
	intf = Link( root, net[ 's1' ] ).intf1
	root.setIP( '10.10.10.10/8', intf=intf )

	net.start()



	p1.setIP('10.1.0.1')
	p1s1.setIP('10.1.1.1')
	p1s2.setIP('10.1.1.2')
	p1s3.setIP('10.1.1.3')
	p1s4.setIP('10.1.1.4')


	#
	# Add route for multicast range 230.0.0.0/8 on hosts
	info( '*** Adding route for multicast range 230.0.0.0/8\n' )
Exemple #37
0
class OpenstackManage(object):
    """
    OpenstackManage is a singleton and management component for the emulator.
    It is the brain of the Openstack component and manages everything that is not datacenter specific like
    network chains or load balancers.
    """
    __instance = None

    def __new__(cls):
        if OpenstackManage.__instance is None:
            OpenstackManage.__instance = object.__new__(cls)
        return OpenstackManage.__instance

    def __init__(self, ip="0.0.0.0", port=4000):
        # we are a singleton, only initialize once!
        self.lock = threading.Lock()
        with self.lock:
            if hasattr(self, "init"):
                return
            self.init = True

        self.endpoints = dict()
        self.cookies = set()
        self.cookies.add(0)
        self.ip = ip
        self.port = port
        self._net = None
        # to keep track which src_vnf(input port on the switch) handles a load balancer
        self.lb_flow_cookies = dict()
        self.chain_flow_cookies = dict()

        # for the visualization also store the complete chain data incl. paths
        self.full_chain_data = dict()
        self.full_lb_data = dict()

        # flow groups could be handled for each switch separately, but this global group counter should be easier to
        # debug and to maintain
        self.flow_groups = dict()

        # we want one global chain api. this should not be datacenter dependent!
        self.chain = chain_api.ChainApi(ip, port, self)
        self.thread = threading.Thread(target=self.chain._start_flask, args=())
        self.thread.daemon = True
        self.thread.name = self.chain.__class__
        self.thread.start()

        # floating ip network setup
        self.floating_switch = None
        self.floating_network = None
        self.floating_netmask = "192.168.100.0/24"
        self.floating_nodes = dict()
        self.floating_cookies = dict()
        self.floating_intf = None
        self.floating_links = dict()

    @property
    def net(self):
        return self._net

    @net.setter
    def net(self, value):
        if self._net is None:
            self._net = value
            self.init_floating_network()
        self._net = value

    def init_floating_network(self):
        """
        Initialize the floating network component for the emulator.
        Will not do anything if already initialized.
        """
        if self.net is not None and self.floating_switch is None:
            # create a floating network
            fn = self.floating_network = Net("default")
            fn.id = str(uuid.uuid4())
            fn.set_cidr(self.floating_netmask)

            # create a subnet
            fn.subnet_id = str(uuid.uuid4())
            fn.subnet_name = fn.name + "-sub"

            # create a port for the host
            port = Port("root-port")
            #port.id = str(uuid.uuid4())
            port.net_name = fn.name

            # get next free ip
            root_ip = fn.get_new_ip_address(port.name)
            port.ip_address = root_ip
            # floating ip network setup
            # wierd way of getting a datacenter object
            first_dc = self.net.dcs.values()[0]
            # set a dpid for the switch. for this we have to get the id of the next possible dc
            self.floating_switch = self.net.addSwitch("fs1", dpid=hex(first_dc._get_next_dc_dpid())[2:])
            # this is the interface appearing on the physical host
            self.floating_root = Node('root', inNamespace=False)
            self.net.hosts.append(self.floating_root)
            self.net.nameToNode['root'] = self.floating_root
            self.floating_intf = self.net.addLink(self.floating_root, self.floating_switch).intf1
            self.floating_root.setIP(root_ip, intf=self.floating_intf)
            self.floating_nodes[(self.floating_root.name, root_ip)] = self.floating_root


    def stop_floating_network(self):
        self._net = None
        self.floating_switch = None

    def add_endpoint(self, ep):
        """
        Registers an openstack endpoint with manage

        :param ep: Openstack API endpoint
        :type ep: :class:`heat.openstack_api_endpoint`
        """
        key = "%s:%s" % (ep.ip, ep.port)
        self.endpoints[key] = ep

    def get_cookie(self):
        """
        Get an unused cookie.

        :return: Cookie
        :rtype: ``int``
        """
        cookie = int(max(self.cookies) + 1)
        self.cookies.add(cookie)
        return cookie

    def get_flow_group(self, src_vnf_name, src_vnf_interface):
        """
        Gets free group that is not currently used by any other flow for the specified interface / VNF.

        :param src_vnf_name: Source VNF name
        :type src_vnf_name: ``str``
        :param src_vnf_interface: Source VNF interface name
        :type src_vnf_interface: ``str``
        :return: Flow group identifier.
        :rtype: ``int``
        """
        if (src_vnf_name, src_vnf_interface) not in self.flow_groups:
            grp = int(len(self.flow_groups) + 1)
            self.flow_groups[(src_vnf_name, src_vnf_interface)] = grp
        else:
            grp = self.flow_groups[(src_vnf_name, src_vnf_interface)]
        return grp

    def check_vnf_intf_pair(self, vnf_name, vnf_intf_name):
        """
        Checks if a VNF exists and has the given interface

        :param vnf_name: Name of the VNF to be checked
        :type vnf_name: ``str``
        :param vnf_intf_name: Name of the interface that belongst to the VNF
        :type vnf_intf_name: ``str``
        :return: ``True`` if it is valid pair, else ``False``
        :rtype: ``bool``
        """

        if vnf_name in self.net:
            vnf = self.net.getNodeByName(vnf_name)
            return vnf_intf_name in vnf.nameToIntf

    def network_action_start(self, vnf_src_name, vnf_dst_name, **kwargs):
        """
        Starts a network chain for a source destination pair

        :param vnf_src_name: Name of the source VNF
        :type vnf_src_name: ``str``
        :param vnf_dst_name: Name of the source VNF interface
        :type vnf_dst_name: ``str``
        :param \**kwargs: See below

        :Keyword Arguments:
            * *vnf_src_interface* (``str``): Name of source interface.
            * *vnf_dst_interface* (``str``): Name of destination interface.
            * *weight* (``int``): This value is fed into the shortest path computation if no path is specified.
            * *match* (``str``): A custom match entry for the openflow flow rules. Only vlanid or port possible.
            * *bidirectional* (``bool``): If set the chain will be set in both directions, else it will just set up \
                            from source to destination.
            * *cookie* (``int``): Cookie value used by openflow. Used to identify the flows in the switches to be \
                            able to modify the correct flows.
            * *no_route* (``bool``): If set a layer 3 route to the target interface will not be set up.
        :return: The cookie chosen for the flow.
        :rtype: ``int``
        """
        try:
            vnf_src_interface = kwargs.get('vnf_src_interface')
            vnf_dst_interface = kwargs.get('vnf_dst_interface')
            layer2 = kwargs.get('layer2', True)
            match = kwargs.get('match')
            flow = (vnf_src_name, vnf_src_interface, vnf_dst_name, vnf_dst_interface)
            if flow in self.chain_flow_cookies:
                raise Exception("There is already a chain at the specified src/dst pair!")
            # set up a layer 2 chain, this allows multiple chains for the same interface
            src_node = self.net.getNodeByName(vnf_src_name)
            dst_node = self.net.getNodeByName(vnf_dst_name)
            dst_intf = dst_node.intf(vnf_dst_interface)
            if layer2:
                switch, inport = self._get_connected_switch_data(vnf_src_name, vnf_src_interface)
                self.setup_arp_reply_at(switch, inport, dst_intf.IP(), dst_intf.MAC())
                if isinstance(match, str):
                    match += ",dl_dst=%s" % dst_intf.MAC()
                else:
                    match = "dl_dst=%s" % dst_intf.MAC()

            cookie = kwargs.get('cookie', self.get_cookie())
            self.cookies.add(cookie)
            c = self.net.setChain(
                vnf_src_name, vnf_dst_name,
                vnf_src_interface=vnf_src_interface,
                vnf_dst_interface=vnf_dst_interface,
                cmd='add-flow',
                weight=kwargs.get('weight'),
                match=match,
                bidirectional=False,
                cookie=cookie,
                path=kwargs.get('path'))

            # to keep this logic seperate of the core son-emu do the housekeeping here
            data = dict()
            data["src_vnf"] = vnf_src_name
            data["src_intf"] = vnf_src_interface
            data["dst_vnf"] = vnf_dst_name
            data["dst_intf"] = vnf_dst_interface
            data["cookie"] = cookie
            data["layer2"] = layer2
            if kwargs.get('path') is not None:
                data["path"] = kwargs.get('path')
            else:
                data["path"] = self._get_path(vnf_src_name, vnf_dst_name, vnf_src_interface,
                                              vnf_dst_interface)[0]

            # add route to dst ip to this interface
            # this might block on containers that are still setting up, so start a new thread
            if not kwargs.get('no_route'):
                # son_emu does not like concurrent commands for a container so we need to lock this if multiple chains
                # on the same interface are created
                src_node.setHostRoute(dst_node.intf(vnf_dst_interface).IP(), vnf_src_interface)

            try:
                son_emu_data = json.loads(self.get_son_emu_chain_data(vnf_src_name))
            except:
                son_emu_data = dict()
            if "son_emu_data" not in son_emu_data:
                son_emu_data["son_emu_data"] = dict()
            if "interfaces" not in son_emu_data["son_emu_data"]:
                son_emu_data["son_emu_data"]["interfaces"] = dict()
            if vnf_src_interface not in son_emu_data["son_emu_data"]["interfaces"]:
                son_emu_data["son_emu_data"]["interfaces"][vnf_src_interface] = list()
                son_emu_data["son_emu_data"]["interfaces"][vnf_src_interface].append(dst_intf.IP())

            self.set_son_emu_chain_data(vnf_src_name, son_emu_data)

            if kwargs.get('bidirectional', False):
                # call the reverse direction
                path = kwargs.get('path')
                if path is not None:
                    path = list(reversed(path))
                self.network_action_start(vnf_dst_name, vnf_src_name, vnf_src_interface=vnf_dst_interface,
                                          vnf_dst_interface=vnf_src_interface, bidirectional=False,
                                          layer2=kwargs.get('layer2', False), path=path,
                                          no_route=kwargs.get('no_route'))

            self.full_chain_data[flow] = data
            self.chain_flow_cookies[flow] = cookie
            return cookie
        except Exception as ex:
            logging.exception("RPC error.")
            raise Exception(ex.message)

    def network_action_stop(self, vnf_src_name, vnf_dst_name, **kwargs):
        """
        Starts a network chain for a source destination pair

        :param vnf_src_name: Name of the source VNF
        :type vnf_src_name: ``str``
        :param vnf_dst_name: Name of the source VNF interface
        :type vnf_dst_name: ``str``
        :param \**kwargs: See below

        :Keyword Arguments:
            * *vnf_src_interface* (``str``): Name of source interface.
            * *vnf_dst_interface* (``str``): Name of destination interface.
            * *bidirectional* (``bool``): If set the chain will be torn down in both directions, else it will just\
                            be torn down from source to destination.
            * *cookie* (``int``): Cookie value used by openflow. Used to identify the flows in the switches to be \
                            able to modify the correct flows.
        """
        try:
            if 'cookie' in kwargs:
                return self.delete_flow_by_cookie(kwargs.get('cookie'))

            if kwargs.get('bidirectional', False):
                self.delete_chain_by_intf(vnf_dst_name, kwargs.get('vnf_dst_interface'),
                                          vnf_src_name, kwargs.get('vnf_src_interface'))

            return self.delete_chain_by_intf(vnf_src_name, kwargs.get('vnf_src_interface'),
                                             vnf_dst_name, kwargs.get('vnf_dst_interface'))
        except Exception as ex:
            logging.exception("RPC error.")
            return ex.message

    def set_son_emu_chain_data(self, vnf_name, data):
        """
        Set son-emu chain data for this node.

        :param vnf_name: The name of the vnf where the data is stored.
        :type vnf_name: ``str``
        :param data: Raw data to store on the node.
        :type data: ``str``
        """
        self.net.getNodeByName(vnf_name).cmd("echo \'%s\' > /tmp/son_emu_data.json" % json.dumps(data))
        ip_list = []
        for intf in data['son_emu_data']['interfaces'].values():
            ip_list.extend(intf)

        self.net.getNodeByName(vnf_name).cmd("echo \'%s\' > /tmp/son_emu_data" % "\n".join(ip_list))

    def get_son_emu_chain_data(self, vnf_name):
        """
        Get the current son-emu chain data set for this node.

        :param vnf_name: The name of the vnf where the data is stored.
        :type vnf_name: ``str``
        :return: raw data stored on the node
        :rtype: ``str``
        """
        return self.net.getNodeByName(vnf_name).cmd("cat /tmp/son_emu_data.json")

    def _get_connected_switch_data(self, vnf_name, vnf_interface):
        """
        Get the switch an interface is connected to
        :param vnf_name: Name of the VNF
        :type vnf_name: ``str``
        :param vnf_interface: Name of the VNF interface
        :type vnf_interface: ``str``
        :return: List containing the switch, and the inport number
        :rtype: [``str``, ``int``]
        """
        src_sw = None
        src_sw_inport_nr = None
        for connected_sw in self.net.DCNetwork_graph.neighbors(vnf_name):
            link_dict = self.net.DCNetwork_graph[vnf_name][connected_sw]
            for link in link_dict:
                if (link_dict[link]['src_port_id'] == vnf_interface or
                            link_dict[link][
                                'src_port_name'] == vnf_interface):
                    # found the right link and connected switch
                    src_sw = connected_sw
                    src_sw_inport_nr = link_dict[link]['dst_port_nr']
                    break

        return src_sw, src_sw_inport_nr

    def _get_path(self, src_vnf, dst_vnf, src_vnf_intf, dst_vnf_intf):
        """
        Own implementation of the get_path function from DCNetwork, because we just want the path and not set up
        flows on the way.

        :param src_vnf: Name of the source VNF
        :type src_vnf: ``str``
        :param dst_vnf: Name of the destination VNF
        :type dst_vnf: ``str``
        :param src_vnf_intf: Name of the source VNF interface
        :type src_vnf_intf: ``str``
        :param dst_vnf_intf: Name of the destination VNF interface
        :type dst_vnf_intf: ``str``
        :return: path, src_sw, dst_sw
        :rtype: ``list``, ``str``, ``str``
        """
        # modified version of the _chainAddFlow from emuvim.dcemulator.net._chainAddFlow
        src_sw = None
        dst_sw = None
        logging.debug("Find shortest path from vnf %s to %s",
                      src_vnf, dst_vnf)

        for connected_sw in self.net.DCNetwork_graph.neighbors(src_vnf):
            link_dict = self.net.DCNetwork_graph[src_vnf][connected_sw]
            for link in link_dict:
                if (link_dict[link]['src_port_id'] == src_vnf_intf or
                            link_dict[link][
                                'src_port_name'] == src_vnf_intf):
                    # found the right link and connected switch
                    src_sw = connected_sw
                    break

        for connected_sw in self.net.DCNetwork_graph.neighbors(dst_vnf):
            link_dict = self.net.DCNetwork_graph[connected_sw][dst_vnf]
            for link in link_dict:
                if link_dict[link]['dst_port_id'] == dst_vnf_intf or \
                                link_dict[link][
                                    'dst_port_name'] == dst_vnf_intf:
                    # found the right link and connected
                    dst_sw = connected_sw
                    break
        logging.debug("From switch %s to %s " % (src_sw, dst_sw))

        # get shortest path
        try:
            # returns the first found shortest path
            # if all shortest paths are wanted, use: all_shortest_paths
            path = nx.shortest_path(self.net.DCNetwork_graph, src_sw, dst_sw)
        except:
            logging.exception("No path could be found between {0} and {1} using src_sw={2} and dst_sw={3}".format(
                src_vnf, dst_vnf, src_sw, dst_sw))
            logging.debug("Graph nodes: %r" % self.net.DCNetwork_graph.nodes())
            logging.debug("Graph edges: %r" % self.net.DCNetwork_graph.edges())
            for e, v in self.net.DCNetwork_graph.edges():
                logging.debug("%r" % self.net.DCNetwork_graph[e][v])
            return "No path could be found between {0} and {1}".format(src_vnf, dst_vnf)

        logging.info("Shortest path between {0} and {1}: {2}".format(src_vnf, dst_vnf, path))
        return path, src_sw, dst_sw

    def add_loadbalancer(self, src_vnf_name, src_vnf_interface, lb_data):
        """
        This function will set up a loadbalancer at the given interface.

        :param src_vnf_name: Name of the source VNF
        :type src_vnf_name: ``str``
        :param src_vnf_interface: Name of the destination VNF
        :type src_vnf_interface: ``str``
        :param lb_data: A dictionary containing the destination data as well as custom path settings
        :type lb_data: ``dict``

        :Example:
         lbdata = {"dst_vnf_interfaces": {"dc2_man_web0": "port-man-2",
         "dc3_man_web0": "port-man-4","dc4_man_web0": "port-man-6"}, "path": {"dc2_man_web0": {"port-man-2": [ "dc1.s1",\
         "s1", "dc2.s1"]}}}
        """
        net = self.net
        src_sw_inport_nr = 0
        src_sw = None
        dest_intfs_mapping = lb_data.get('dst_vnf_interfaces', dict())
        # a custom path can be specified as a list of switches
        custom_paths = lb_data.get('path', dict())
        dest_vnf_outport_nrs = list()

        logging.debug("Call to add_loadbalancer at %s intfs:%s" % (src_vnf_name, src_vnf_interface))

        if not self.check_vnf_intf_pair(src_vnf_name, src_vnf_interface):
            raise Exception(u"Source VNF %s or intfs %s does not exist" % (src_vnf_name, src_vnf_interface))

        # find the switch belonging to the source interface, as well as the inport nr
        for connected_sw in net.DCNetwork_graph.neighbors(src_vnf_name):
            link_dict = net.DCNetwork_graph[src_vnf_name][connected_sw]
            for link in link_dict:
                if link_dict[link]['src_port_name'] == src_vnf_interface:
                    src_sw = connected_sw
                    src_sw_inport_nr = link_dict[link]['dst_port_nr']
                    break

        if src_sw is None or src_sw_inport_nr == 0:
            raise Exception(u"Source VNF or interface can not be found.")

        # get all target interface outport numbers
        for vnf_name in dest_intfs_mapping:
            if vnf_name not in net.DCNetwork_graph:
                raise Exception(u"Target VNF %s is not known." % vnf_name)
            for connected_sw in net.DCNetwork_graph.neighbors(vnf_name):
                link_dict = net.DCNetwork_graph[vnf_name][connected_sw]
                for link in link_dict:
                    if link_dict[link]['src_port_name'] == dest_intfs_mapping[vnf_name]:
                        dest_vnf_outport_nrs.append(int(link_dict[link]['dst_port_nr']))
        # get first switch
        if (src_vnf_name, src_vnf_interface) not in self.lb_flow_cookies:
            self.lb_flow_cookies[(src_vnf_name, src_vnf_interface)] = list()

        src_intf = None
        src_ip = None
        src_mac = None
        for intf in net[src_vnf_name].intfs.values():
            if intf.name == src_vnf_interface:
                src_mac = intf.mac
                src_ip = intf.ip
                src_intf = intf

        # set up paths for each destination vnf individually
        index = 0
        cookie = self.get_cookie()
        main_cmd = "add-flow -OOpenFlow13"
        self.lb_flow_cookies[(src_vnf_name, src_vnf_interface)].append(cookie)

        # bookkeeping
        data = dict()
        data["src_vnf"] = src_vnf_name
        data["src_intf"] = src_vnf_interface
        data["paths"] = list()
        data["cookie"] = cookie

        # lb mac for src -> target connections
        lb_mac = "31:33:70:%02x:%02x:%02x" % (random.randint(0, 255),random.randint(0, 255),random.randint(0, 255))

        # calculate lb ip as src_intf.ip +1
        octets = src_ip.split('.')
        octets[3] = str(int(octets[3]) + 1)
        plus_one = '.'.join(octets)

        # set up arp reply as well as add the route to the interface
        self.setup_arp_reply_at(src_sw, src_sw_inport_nr, plus_one, lb_mac, cookie=cookie)
        net.getNodeByName(src_vnf_name).setHostRoute(plus_one, src_vnf_interface)

        for dst_vnf_name, dst_vnf_interface in dest_intfs_mapping.items():
            path, src_sw, dst_sw = self._get_path(src_vnf_name, dst_vnf_name,
                                                  src_vnf_interface, dst_vnf_interface)

            # use custom path if one is supplied
            # json does not support hashing on tuples so we use nested dicts
            if custom_paths is not None and dst_vnf_name in custom_paths:
                if dst_vnf_interface in custom_paths[dst_vnf_name]:
                    path = custom_paths[dst_vnf_name][dst_vnf_interface]
                    logging.debug("Taking custom path from %s to %s: %s" % (src_vnf_name, dst_vnf_name, path))

            if not self.check_vnf_intf_pair(dst_vnf_name, dst_vnf_interface):
                self.delete_loadbalancer(src_vnf_name, src_vnf_interface)
                raise Exception(u"VNF %s or intfs %s does not exist" % (dst_vnf_name, dst_vnf_interface))
            if isinstance(path, dict):
                self.delete_loadbalancer(src_vnf_name, src_vnf_interface)
                raise Exception(u"Can not find a valid path. Are you specifying the right interfaces?.")

            target_mac = "fa:17:00:03:13:37"
            target_ip = "0.0.0.0"
            for intf in net[dst_vnf_name].intfs.values():
                if intf.name == dst_vnf_interface:
                    target_mac = str(intf.mac)
                    target_ip = str(intf.ip)
            dst_sw_outport_nr = dest_vnf_outport_nrs[index]
            current_hop = src_sw
            switch_inport_nr = src_sw_inport_nr

            #self.setup_arp_reply_at(src_sw, src_sw_inport_nr, target_ip, target_mac, cookie=cookie)
            net.getNodeByName(dst_vnf_name).setHostRoute(src_ip, dst_vnf_interface)

            # choose free vlan if path contains more than 1 switch
            if len(path) > 1:
                vlan = net.vlans.pop()
                if vlan == 0:
                    vlan = net.vlans.pop()
            else:
                vlan = None

            single_flow_data = dict()
            single_flow_data["dst_vnf"] = dst_vnf_name
            single_flow_data["dst_intf"] = dst_vnf_interface
            single_flow_data["path"] = path
            single_flow_data["vlan"] = vlan
            single_flow_data["cookie"] = cookie

            data["paths"].append(single_flow_data)

            # src to target
            for i in range(0, len(path)):
                if i < len(path) - 1:
                    next_hop = path[i + 1]
                else:
                    # last switch reached
                    next_hop = dst_vnf_name
                next_node = net.getNodeByName(next_hop)
                if next_hop == dst_vnf_name:
                    switch_outport_nr = dst_sw_outport_nr
                    logging.info("end node reached: {0}".format(dst_vnf_name))
                elif not isinstance(next_node, OVSSwitch):
                    logging.info("Next node: {0} is not a switch".format(next_hop))
                    return "Next node: {0} is not a switch".format(next_hop)
                else:
                    # take first link between switches by default
                    index_edge_out = 0
                    switch_outport_nr = net.DCNetwork_graph[current_hop][next_hop][index_edge_out]['src_port_nr']

                cmd = 'priority=1,in_port=%s,cookie=%s' % (switch_inport_nr, cookie)
                cmd_back = 'priority=1,in_port=%s,cookie=%s' % (switch_outport_nr, cookie)
                # if a vlan is picked, the connection is routed through multiple switches
                if vlan is not None:
                    if path.index(current_hop) == 0:  # first node
                        # flow #index set up
                        cmd = 'in_port=%s' % src_sw_inport_nr
                        cmd += ',cookie=%s' % cookie
                        cmd += ',table=%s' % cookie
                        cmd += ',ip'
                        cmd += ',reg1=%s' % index
                        cmd += ',actions='
                        # set vlan id
                        cmd += ',push_vlan:0x8100'
                        masked_vlan = vlan | 0x1000
                        cmd += ',set_field:%s->vlan_vid' % masked_vlan
                        cmd += ',set_field:%s->eth_dst' % target_mac
                        cmd += ',set_field:%s->ip_dst' % target_ip
                        cmd += ',output:%s' % switch_outport_nr

                        # last switch for reverse route
                        # remove any vlan tags
                        cmd_back += ',dl_vlan=%s' % vlan
                        cmd_back += ',actions=pop_vlan,output:%s' % switch_inport_nr
                    elif next_hop == dst_vnf_name:  # last switch
                        # remove any vlan tags
                        cmd += ',dl_vlan=%s' % vlan
                        cmd += ',actions=pop_vlan,output:%s' % switch_outport_nr
                        # set up arp replys at the port so the dst nodes know the src
                        self.setup_arp_reply_at(current_hop, switch_outport_nr, src_ip, src_mac, cookie=cookie)

                        # reverse route
                        cmd_back = 'in_port=%s' % switch_outport_nr
                        cmd_back += ',cookie=%s' % cookie
                        cmd_back += ',ip'
                        cmd_back += ',actions='
                        cmd_back += 'push_vlan:0x8100'
                        masked_vlan = vlan | 0x1000
                        cmd_back += ',set_field:%s->vlan_vid' % masked_vlan
                        cmd_back += ',set_field:%s->eth_src' % lb_mac
                        cmd_back += ',set_field:%s->ip_src' % plus_one
                        cmd_back += ',output:%s' % switch_inport_nr
                    else:  # middle nodes
                        # if we have a circle in the path we need to specify this, as openflow will ignore the packet
                        # if we just output it on the same port as it came in
                        if switch_inport_nr == switch_outport_nr:
                            cmd += ',dl_vlan=%s,actions=IN_PORT' % (vlan)
                            cmd_back += ',dl_vlan=%s,actions=IN_PORT' % (vlan)
                        else:
                            cmd += ',dl_vlan=%s,actions=output:%s' % (vlan, switch_outport_nr)
                            cmd_back += ',dl_vlan=%s,actions=output:%s' % (vlan, switch_inport_nr)
                # output the packet at the correct outport
                else:
                    cmd = 'in_port=%s' % src_sw_inport_nr
                    cmd += ',cookie=%s' % cookie
                    cmd += ',table=%s' % cookie
                    cmd += ',ip'
                    cmd += ',reg1=%s' % index
                    cmd += ',actions='
                    cmd += ',set_field:%s->eth_dst' % target_mac
                    cmd += ',set_field:%s->ip_dst' % target_ip
                    cmd += ',output:%s' % switch_outport_nr

                    # reverse route
                    cmd_back = 'in_port=%s' % switch_outport_nr
                    cmd_back += ',cookie=%s' % cookie
                    cmd_back += ',ip'
                    cmd_back += ',actions='
                    cmd_back += ',set_field:%s->eth_src' % lb_mac
                    cmd_back += ',set_field:%s->ip_src' % plus_one
                    cmd_back += ',output:%s' % src_sw_inport_nr

                    self.setup_arp_reply_at(current_hop, switch_outport_nr, src_ip, src_mac, cookie=cookie)

                # excecute the command on the target switch
                logging.debug(cmd)
                cmd = "\"%s\"" % cmd
                cmd_back = "\"%s\"" % cmd_back
                net[current_hop].dpctl(main_cmd, cmd)
                net[current_hop].dpctl(main_cmd, cmd_back)

                # set next hop for the next iteration step
                if isinstance(next_node, OVSSwitch):
                    switch_inport_nr = net.DCNetwork_graph[current_hop][next_hop][0]['dst_port_nr']
                    current_hop = next_hop

            # advance to next destination
            index += 1

        # set up the actual load balancing rule as a multipath on the very first switch
        cmd = '"in_port=%s' % src_sw_inport_nr
        cmd += ',cookie=%s' % (cookie)
        cmd += ',ip'
        cmd += ',actions='
        # push 0x01 into the first register
        cmd += 'load:0x1->NXM_NX_REG0[]'
        # load balance modulo n over all dest interfaces
        # TODO: in newer openvswitch implementations this should be changed to symmetric_l3l4+udp
        # to balance any kind of traffic
        cmd += ',multipath(symmetric_l4,1024,modulo_n,%s,0,NXM_NX_REG1[0..12])' % len(dest_intfs_mapping)
        # reuse the cookie as table entry as it will be unique
        cmd += ',resubmit(, %s)"' % cookie

        # actually add the flow
        logging.debug("Switch: %s, CMD: %s" % (src_sw, cmd))
        net[src_sw].dpctl(main_cmd, cmd)

        # finally add all flow data to the internal data storage
        self.full_lb_data[(src_vnf_name, src_vnf_interface)] = data

    def add_floating_lb(self, datacenter, lb_data):
        """
        This function will set up a loadbalancer at the given datacenter.
        This function returns the floating ip assigned to the loadbalancer as multiple ones are possible.

        :param datacenter: The datacenter entrypoint
        :type datacenter: ``str``
        :param lb_data: A dictionary containing the destination data as well as custom path settings
        :type lb_data: ``dict``

        :Example:
         lbdata = {"dst_vnf_interfaces": {"dc2_man_web0": "port-man-2",
         "dc3_man_web0": "port-man-4","dc4_man_web0": "port-man-6"}, "path": {"dc2_man_web0": {"port-man-2": [ "dc1.s1",\
         "s1", "dc2.s1"]}}}
        """
        net = self.net
        src_sw_inport_nr = 1
        src_sw = self.floating_switch.name
        dest_intfs_mapping = lb_data.get('dst_vnf_interfaces', dict())
        # a custom path can be specified as a list of switches
        custom_paths = lb_data.get('path', dict())
        dest_vnf_outport_nrs = list()

        if datacenter not in self.net.dcs:
            raise Exception(u"Source datacenter can not be found.")

        # get all target interface outport numbers
        for vnf_name in dest_intfs_mapping:
            if vnf_name not in net.DCNetwork_graph:
                raise Exception(u"Target VNF %s is not known." % vnf_name)
            for connected_sw in net.DCNetwork_graph.neighbors(vnf_name):
                link_dict = net.DCNetwork_graph[vnf_name][connected_sw]
                for link in link_dict:
                    if link_dict[link]['src_port_name'] == dest_intfs_mapping[vnf_name]:
                        dest_vnf_outport_nrs.append(int(link_dict[link]['dst_port_nr']))

        if len(dest_vnf_outport_nrs) == 0:
            raise Exception("There are no paths specified for the loadbalancer")
        src_ip = self.floating_intf.IP()
        src_mac = self.floating_intf.MAC()

        # set up paths for each destination vnf individually
        index = 0
        cookie = self.get_cookie()
        main_cmd = "add-flow -OOpenFlow13"
        floating_ip = self.floating_network.get_new_ip_address("floating-ip").split("/")[0]

        for dst_vnf_name, dst_vnf_interface in dest_intfs_mapping.items():
            path = None
            # use custom path if one is supplied
            # json does not support hashing on tuples so we use nested dicts
            if custom_paths is not None and dst_vnf_name in custom_paths:
                if dst_vnf_interface in custom_paths[dst_vnf_name]:
                    path = custom_paths[dst_vnf_name][dst_vnf_interface]
                    logging.debug("Taking custom path to %s: %s" % (dst_vnf_name, path))
            else:
                if datacenter not in self.floating_links:
                    self.floating_links[datacenter] = \
                        net.addLink(self.floating_switch, datacenter)
                path = \
                self._get_path(self.floating_root.name, dst_vnf_name, self.floating_intf.name, dst_vnf_interface)[0]

            if isinstance(path, dict):
                self.delete_flow_by_cookie(cookie)
                raise Exception(u"Can not find a valid path. Are you specifying the right interfaces?.")

            intf = net[dst_vnf_name].nameToIntf[dst_vnf_interface]
            target_mac = str(intf.MAC())
            target_ip = str(intf.IP())
            dst_sw_outport_nr = dest_vnf_outport_nrs[index]
            current_hop = src_sw
            switch_inport_nr = src_sw_inport_nr
            vlan = net.vlans.pop()

            # iterate all switches on the path
            for i in range(0, len(path)):
                if i < len(path) - 1:
                    next_hop = path[i + 1]
                else:
                    # last switch reached
                    next_hop = dst_vnf_name
                next_node = net.getNodeByName(next_hop)

                # sanity checks
                if next_hop == dst_vnf_name:
                    switch_outport_nr = dst_sw_outport_nr
                    logging.info("end node reached: {0}".format(dst_vnf_name))
                elif not isinstance(next_node, OVSSwitch):
                    logging.info("Next node: {0} is not a switch".format(next_hop))
                    return "Next node: {0} is not a switch".format(next_hop)
                else:
                    # take first link between switches by default
                    index_edge_out = 0
                    switch_outport_nr = net.DCNetwork_graph[current_hop][next_hop][index_edge_out]['src_port_nr']

                # default filters, just overwritten on the first node and last node
                cmd = 'priority=1,in_port=%s,cookie=%s' % (switch_inport_nr, cookie)
                cmd_back = 'priority=1,in_port=%s,cookie=%s' % (switch_outport_nr, cookie)
                if i == 0:  # first node
                    cmd = 'in_port=%s' % src_sw_inport_nr
                    cmd += ',cookie=%s' % cookie
                    cmd += ',table=%s' % cookie
                    cmd += ',ip'
                    cmd += ',ip_dst=%s' % floating_ip
                    cmd += ',reg1=%s' % index
                    cmd += ',actions='
                    # set vlan id
                    cmd += ',push_vlan:0x8100'
                    masked_vlan = vlan | 0x1000
                    cmd += ',set_field:%s->vlan_vid' % masked_vlan
                    cmd += ',set_field:%s->eth_dst' % target_mac
                    cmd += ',set_field:%s->ip_dst' % target_ip
                    cmd += ',output:%s' % switch_outport_nr

                    # last switch for reverse route
                    # remove any vlan tags
                    cmd_back += ',dl_vlan=%s' % vlan
                    cmd_back += ',actions=pop_vlan,output:%s' % switch_inport_nr
                    self.setup_arp_reply_at(current_hop, src_sw_inport_nr, floating_ip, target_mac, cookie=cookie)
                elif next_hop == dst_vnf_name:  # last switch
                    # remove any vlan tags
                    cmd += ',dl_vlan=%s' % vlan
                    cmd += ',actions=pop_vlan,output:%s' % switch_outport_nr
                    # set up arp replys at the port so the dst nodes know the src
                    self.setup_arp_reply_at(current_hop, switch_outport_nr, src_ip, src_mac, cookie=cookie)

                    # reverse route
                    cmd_back = 'in_port=%s' % switch_outport_nr
                    cmd_back += ',cookie=%s' % cookie
                    cmd_back += ',ip'
                    cmd_back += ',actions='
                    cmd_back += 'push_vlan:0x8100'
                    masked_vlan = vlan | 0x1000
                    cmd_back += ',set_field:%s->vlan_vid' % masked_vlan
                    cmd_back += ',set_field:%s->eth_src' % src_mac
                    cmd_back += ',set_field:%s->ip_src' % floating_ip
                    cmd_back += ',output:%s' % switch_inport_nr
                    net.getNodeByName(dst_vnf_name).setHostRoute(src_ip, dst_vnf_interface)
                else:  # middle node
                    # if we have a circle in the path we need to specify this, as openflow will ignore the packet
                    # if we just output it on the same port as it came in
                    if switch_inport_nr == switch_outport_nr:
                        cmd += ',dl_vlan=%s,actions=IN_PORT' % (vlan)
                        cmd_back += ',dl_vlan=%s,actions=IN_PORT' % (vlan)
                    else:
                        cmd += ',dl_vlan=%s,actions=output:%s' % (vlan, switch_outport_nr)
                        cmd_back += ',dl_vlan=%s,actions=output:%s' % (vlan, switch_inport_nr)

                # excecute the command on the target switch
                logging.debug(cmd)
                cmd = "\"%s\"" % cmd
                cmd_back = "\"%s\"" % cmd_back
                net[current_hop].dpctl(main_cmd, cmd)
                net[current_hop].dpctl(main_cmd, cmd_back)

                # set next hop for the next iteration step
                if isinstance(next_node, OVSSwitch):
                    switch_inport_nr = net.DCNetwork_graph[current_hop][next_hop][0]['dst_port_nr']
                    current_hop = next_hop

            # advance to next destination
            index += 1

        # set up the actual load balancing rule as a multipath on the very first switch
        cmd = '"in_port=%s' % src_sw_inport_nr
        cmd += ',cookie=%s' % (cookie)
        cmd += ',ip'
        cmd += ',actions='
        # push 0x01 into the first register
        cmd += 'load:0x1->NXM_NX_REG0[]'
        # load balance modulo n over all dest interfaces
        # TODO: in newer openvswitch implementations this should be changed to symmetric_l3l4+udp
        # to balance any kind of traffic
        cmd += ',multipath(symmetric_l4,1024,modulo_n,%s,0,NXM_NX_REG1[0..12])' % len(dest_intfs_mapping)
        # reuse the cookie as table entry as it will be unique
        cmd += ',resubmit(, %s)"' % cookie

        # actually add the flow
        logging.debug("Switch: %s, CMD: %s" % (src_sw, cmd))
        net[src_sw].dpctl(main_cmd, cmd)

        self.floating_cookies[cookie] = floating_ip

        return cookie, floating_ip

    def setup_arp_reply_at(self, switch, port_nr, target_ip, target_mac, cookie=None):
        """
        Sets up a custom ARP reply at a switch.
        An ARP request coming in on the `port_nr` for `target_ip` will be answered with target IP/MAC.

        :param switch: The switch belonging to the interface
        :type switch: ``str``
        :param port_nr: The port number at the switch that is connected to the interface
        :type port_nr: ``int``
        :param target_ip: The IP for which to set up the ARP reply
        :type target_ip: ``str``
        :param target_mac: The MAC address of the target interface
        :type target_mac: ``str``
        :param cookie: cookie to identify the ARP request, if None a new one will be picked
        :type cookie: ``int`` or ``None``
        :return: cookie
        :rtype: ``int``
        """
        if cookie is None:
            cookie = self.get_cookie()
        main_cmd = "add-flow -OOpenFlow13"

        # first set up ARP requests for the source node, so it will always 'find' a partner
        cmd = '"in_port=%s' % port_nr
        cmd += ',cookie=%s' % cookie
        cmd += ',arp'
        # only answer for target ip arp requests
        cmd += ',arp_tpa=%s' % target_ip
        cmd += ',actions='
        # set message type to ARP reply
        cmd += 'load:0x2->NXM_OF_ARP_OP[]'
        # set src ip as dst ip
        cmd += ',move:NXM_OF_ETH_SRC[]->NXM_OF_ETH_DST[]'
        # set src mac
        cmd += ',set_field:%s->eth_src' % target_mac
        # set src as target
        cmd += ',move:NXM_NX_ARP_SHA[]->NXM_NX_ARP_THA[], move:NXM_OF_ARP_SPA[]->NXM_OF_ARP_TPA[]'
        # set target mac as hex
        cmd += ',load:0x%s->NXM_NX_ARP_SHA[]' % "".join(target_mac.split(':'))
        # set target ip as hex
        octets = target_ip.split('.')
        dst_ip_hex = '{:02X}{:02X}{:02X}{:02X}'.format(*map(int, octets))
        cmd += ',load:0x%s->NXM_OF_ARP_SPA[]' % dst_ip_hex
        # output to incoming port remember the closing "
        cmd += ',IN_PORT"'
        self.net[switch].dpctl(main_cmd, cmd)
        logging.debug(
            "Set up ARP reply at %s port %s." % (switch, port_nr))

    def delete_flow_by_cookie(self, cookie):
        """
        Removes a flow identified by the cookie

        :param cookie: The cookie for the specified flow
        :type cookie: ``int``
        :return: True if successful, else false
        :rtype: ``bool``
        """
        if not cookie:
            return False
        logging.debug("Deleting flow by cookie %d" % (cookie))
        flows = list()
        # we have to call delete-group for each switch
        for node in self.net.switches:
            flow = dict()
            flow["dpid"] = int(node.dpid, 16)
            flow["cookie"] = cookie
            flow['cookie_mask'] = int('0xffffffffffffffff', 16)

            flows.append(flow)
        for flow in flows:
            logging.debug("Deleting flowentry with cookie %d" % (
                flow["cookie"]))
            if self.net.controller == RemoteController:
                self.net.ryu_REST('stats/flowentry/delete', data=flow)

        self.cookies.remove(cookie)
        return True

    def delete_chain_by_intf(self, src_vnf_name, src_vnf_intf, dst_vnf_name, dst_vnf_intf):
        """
        Removes a flow identified by the vnf_name/vnf_intf pairs

        :param src_vnf_name: The vnf name for the specified flow
        :type src_vnf_name: ``str``
        :param src_vnf_intf: The interface name for the specified flow
        :type src_vnf_intf: ``str``
        :param dst_vnf_name: The vnf name for the specified flow
        :type dst_vnf_name: ``str``
        :param dst_vnf_intf: The interface name for the specified flow
        :type dst_vnf_intf: ``str``
        :return: True if successful, else false
        :rtype: ``bool``
        """
        logging.debug("Deleting flow for vnf/intf pair %s %s" % (src_vnf_name, src_vnf_intf))
        if not self.check_vnf_intf_pair(src_vnf_name, src_vnf_intf):
            return False
        if not self.check_vnf_intf_pair(dst_vnf_name, dst_vnf_intf):
            return False
        target_flow = (src_vnf_name, src_vnf_intf, dst_vnf_name, dst_vnf_intf)
        if not target_flow in self.chain_flow_cookies:
            return False

        success = self.delete_flow_by_cookie(self.chain_flow_cookies[target_flow])

        if success:
            del self.chain_flow_cookies[target_flow]
            del self.full_chain_data[target_flow]
            return True
        return False

    def delete_loadbalancer(self, vnf_src_name, vnf_src_interface):
        '''
        Removes a loadbalancer that is configured for the node and interface

        :param src_vnf_name: Name of the source VNF
        :param src_vnf_interface: Name of the destination VNF
        '''
        flows = list()
        # we have to call delete-group for each switch
        delete_group = list()
        group_id = self.get_flow_group(vnf_src_name, vnf_src_interface)
        for node in self.net.switches:
            for cookie in self.lb_flow_cookies[(vnf_src_name, vnf_src_interface)]:
                flow = dict()
                flow["dpid"] = int(node.dpid, 16)
                flow["cookie"] = cookie
                flow['cookie_mask'] = int('0xffffffffffffffff', 16)

                flows.append(flow)
            group_del = dict()
            group_del["dpid"] = int(node.dpid, 16)
            group_del["group_id"] = group_id
            delete_group.append(group_del)

        for flow in flows:
            logging.debug("Deleting flowentry with cookie %d belonging to lb at %s:%s" % (
                flow["cookie"], vnf_src_name, vnf_src_interface))
            if self.net.controller == RemoteController:
                self.net.ryu_REST('stats/flowentry/delete', data=flow)

        logging.debug("Deleting group with id %s" % group_id)
        for switch_del_group in delete_group:
            if self.net.controller == RemoteController:
                self.net.ryu_REST("stats/groupentry/delete", data=switch_del_group)

        # unmap groupid from the interface
        target_pair = (vnf_src_name, vnf_src_interface)
        if target_pair in self.flow_groups:
            del self.flow_groups[target_pair]
        if target_pair in self.full_lb_data:
            del self.full_lb_data[target_pair]

    def delete_floating_lb(self, cookie):
        """
        Delete a floating loadbalancer.
        Floating loadbalancers are different from normal ones as there are multiple ones on the same interface.
        :param cookie: The cookie of the loadbalancer
        :type cookie: ``int``
        """
        cookie = int(cookie)
        if cookie not in self.floating_cookies:
            raise Exception("Can not delete floating loadbalancer as the flowcookie is not known")

        self.delete_flow_by_cookie(cookie)
        floating_ip = self.floating_cookies[cookie]
        self.floating_network.withdraw_ip_address(floating_ip)

    def set_arp_entry(self, vnf_name, vnf_interface, ip, mac):
        """
        Sets an arp entry on the specified VNF. This is done on the node directly and not by open vswitch!
        :param vnf_name: Name of the VNF
        :type vnf_name: ``str``
        :param vnf_interface: Name of the interface
        :type vnf_interface: ``str``
        :param ip: IP to reply to
        :type ip: ``str``
        :param mac: Answer with this MAC
        :type mac: ``str``
        """
        node = self.net.getNodeByName(vnf_name)
        node.cmd("arp -i %s -s %s %s" % (vnf_interface, ip, mac))
Exemple #38
0
def myNet(cname='controller', cargs='-v ptcp:'):
    "Create network from scratch using Open vSwitch."
    info("*** Creating nodes\n")
    controller = Node('c0', inNamespace=False)
    switch = Node('s0', inNamespace=False)
    switch1 = Node('s1', inNamespace=False)
    h0 = Node('h0')
    h1 = Node('h1')

    info("*** Creating links\n")
    linkopts0 = dict(bw=100, delay='1ms', loss=0)
    linkopts1 = dict(bw=100, delay='10ms', loss=0)
    link0 = TCLink(h0, switch, **linkopts0)
    #initially, the delay from switch to switch1 is 10ms
    link1 = TCLink(switch, switch1, **linkopts1)
    link2 = TCLink(h1, switch1, **linkopts0)

    #print link0.intf1, link0.intf2
    link0.intf2.setMAC("0:0:0:0:0:1")
    link1.intf1.setMAC("0:0:0:0:0:2")
    link1.intf2.setMAC("0:1:0:0:0:1")
    link2.intf2.setMAC("0:1:0:0:0:2")

    info("*** Configuring hosts\n")
    h0.setIP('192.168.123.1/24')
    h1.setIP('192.168.123.2/24')
    h0.setMAC("a:a:a:a:a:a")
    h1.setMAC("8:8:8:8:8:8")

    info("*** Starting network using Open vSwitch\n")
    switch.cmd('ovs-vsctl del-br dp0')
    switch.cmd('ovs-vsctl add-br dp0')
    switch1.cmd('ovs-vsctl del-br dp1')
    switch1.cmd('ovs-vsctl add-br dp1')

    controller.cmd(cname + ' ' + cargs + '&')
    for intf in switch.intfs.values():
        print intf
        print switch.cmd('ovs-vsctl add-port dp0 %s' % intf)

    for intf in switch1.intfs.values():
        print intf
        print switch1.cmd('ovs-vsctl add-port dp1 %s' % intf)

    # Note: controller and switch are in root namespace, and we
    # can connect via loopback interface
    switch.cmd('ovs-vsctl set-controller dp0 tcp:127.0.0.1:6633')
    switch1.cmd('ovs-vsctl set-controller dp1 tcp:127.0.0.1:6633')

    info('*** Waiting for switch to connect to controller')
    while 'is_connected' not in quietRun('ovs-vsctl show'):
        sleep(1)
        info('.')
    info('\n')

    def cDelay1():
        switch.cmdPrint('ethtool -K s0-eth1 gro off')
        switch.cmdPrint('tc qdisc del dev s0-eth1 root')
        switch.cmdPrint(
            'tc qdisc add dev s0-eth1 root handle 10: netem delay 50ms')
        switch1.cmdPrint('ethtool -K s1-eth0 gro off')
        switch1.cmdPrint('tc qdisc del dev s1-eth0 root')
        switch1.cmdPrint(
            'tc qdisc add dev s1-eth0 root handle 10: netem delay 50ms')

    def cDelay2():
        switch.cmdPrint('ethtool -K s0-eth1 gro off')
        switch.cmdPrint('tc qdisc del dev s0-eth1 root')
        switch.cmdPrint(
            'tc qdisc add dev s0-eth1 root handle 10: netem delay 200ms')
        switch1.cmdPrint('ethtool -K s1-eth0 gro off')
        switch1.cmdPrint('tc qdisc del dev s1-eth0 root')
        switch1.cmdPrint(
            'tc qdisc add dev s1-eth0 root handle 10: netem delay 200ms')

    # 15 seconds later, the delay from switch to switch 1 will change to 50ms
    t1 = Timer(15, cDelay1)
    t1.start()
    # 30 seconds later, the delay from switch to switch 1 will change to 200ms
    t2 = Timer(30, cDelay2)
    t2.start()

    #info( "*** Running test\n" )
    h0.cmdPrint('ping -i 1 -c 45 ' + h1.IP())
    sleep(1)
    info("*** Stopping network\n")
    controller.cmd('kill %' + cname)
    switch.cmd('ovs-vsctl del-br dp0')
    switch.deleteIntfs()
    switch1.cmd('ovs-vsctl del-br dp1')
    switch1.deleteIntfs()
    info('\n')
    h2 = Node( 'h2' )

    net.hosts.append( h0 )
    net.hosts.append( h1 )
    net.hosts.append( h2 )

    wifi = WIFISegment()

    wifi.addAp( h0 )
    wifi.addSta( h1 )
    wifi.addSta( h2 )
    
    wifi.phyhelper.EnablePcap( "Ap-trace.pcap", h0.nsNode.GetDevice( 0 ), True, True );

    info( '*** Configuring hosts\n' )
    h0.setIP( '192.168.123.1/24' )
    h1.setIP( '192.168.123.2/24')
    h2.setIP( '192.168.123.3/24')

    mininet.ns3.start()


    info( '*** Network state:\n' )
    for node in h0, h1, h2:
        info( str( node ) + '\n' )

    info( '*** Running test\n' )
    h0.cmdPrint( 'ping -c1 ' + h1.IP() )
    h0.cmdPrint( 'ping -c1 ' + h2.IP() )

    CLI(net)
Exemple #40
0
def myNet(cname='controller', cargs='-v ptcp:'):
    "Create network from scratch using Open vSwitch."
    info( "*** Creating nodes\n" )
    controller = Node( 'c0', inNamespace=False )
    s0 = Node( 's0', inNamespace=False )
    s1 = Node( 's1', inNamespace=False )
    h0 = Node( 'h0' )
    h1 = Node( 'h1' )
    h2 = Node( 'h2' )

    info( "*** Creating links..." )
    linkopts0=dict(bw=10, delay='1ms', loss=0)
    info( '\nLink h0-s0 | ' )
    TCLink( h0, s0, **linkopts0)
    info( '\nLink h1-s0 | ' )
    TCLink( h1, s0, **linkopts0)
    info( '\nLink s0-s1 | ' )
    TCLink( s0, s1, **linkopts0)
    info( '\nLink s1-h2 | ' )
    TCLink( s1, h2, **linkopts0)

    info( '\n' )
    info( "*** Configuring hosts...\n" )
    h0.setIP( '192.168.1.1/24' )
    h1.setIP( '192.168.1.2/24' )
    h2.setIP( '192.168.1.3/24' )

    info( "*** Starting network using Open vSwitch...\n" )
    s0.cmd( 'ovs-vsctl del-br s0' )
    s0.cmd( 'ovs-vsctl add-br s0' )
    s1.cmd( 'ovs-vsctl del-br s1' )
    s1.cmd( 'ovs-vsctl add-br s1' )

    controller.cmd( cname + ' ' + cargs + '&' )          
    for intf in s0.intfs.values():
        print intf
        print s0.cmd( 'ovs-vsctl add-port s0 %s' % intf )
   
    for intf in s1.intfs.values():
        print intf
        print s1.cmd( 'ovs-vsctl add-port s1 %s' % intf )
  
    # Note: controller and switch are in root namespace, and we
    # can connect via loopback interface
    info( '*** Connect to controller with tcp port...' )
    s0.cmd( 'ovs-vsctl set-controller s0 tcp:127.0.0.1:6633' )
    s1.cmd( 'ovs-vsctl set-controller s0 tcp:127.0.0.1:6633' )
 
    info( '\n' )  
    info( '*** Waiting for switch to connect to controller..' )
    while 'is_connected' not in quietRun( 'ovs-vsctl show' ):
        sleep( 1 )
        info( '.' )
    info( 'connected!\n' )

    #print s0.cmd('ovs-ofctl show dp0')

    info( "*** Running test...\n" )
    info( '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n' )
    h0.cmdPrint( 'ping -c 2 ' + h2.IP() )
    info( '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n' )
    h1.cmdPrint( 'ping -c 2 ' + h2.IP() )
    info( '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n' )

    info( '*** Starting iperf Server...\n' )
    h2.cmdPrint('iperf -s -i 1 > bandwidth_result &')

    info( '*** Original link bandwidth testing...\n' )
    print "iperf: h0--s0--s1--h2"
    h0.cmdPrint('iperf -c 192.168.1.3 -t 15')
    info( '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n' )
    print "iperf: h1--s0--s1--h2"
    h1.cmdPrint('iperf -c 192.168.1.3 -t 15')
    info( '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n' )

    print "!!! Limiting the bandwidth for flow entry [h0] -> [h2]"
    s0.cmdPrint('ethtool -K s0-eth2 gro off')
    s0.cmdPrint('tc qdisc del dev s0-eth2 root')
    s0.cmdPrint('tc qdisc add dev s0-eth2 root handle 1: cbq avpkt 1000 bandwidth 10Mbit')
    s0.cmdPrint('tc class add dev s0-eth2 parent 1: classid 1:1 cbq rate 512kbit allot 1500 prio 5 bounded isolated')
    s0.cmdPrint('tc filter add dev s0-eth2 parent 1: protocol ip prio 16 u32 match ip src 192.168.1.1 flowid 1:1')
    s0.cmdPrint('tc qdisc add dev s0-eth2 parent 1:1 sfq perturb 10')

    info( '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~' )
    info( '\n*** Limited link bandwidth testing...\n' )
    print "iperf: h0--s0--s1--h2"
    h0.cmdPrint('iperf -c 192.168.1.3 -t 15')
    info( '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n' )
    print "iperf: h1--s0--s1--h2" 
    h1.cmdPrint('iperf -c 192.168.1.3 -t 15')

    info( '*** Done...\n' )
    info( "*** Stopping network...\n" )
    controller.cmd( 'kill %' + cname )
    s0.cmd( 'ovs-vsctl del-br s0' )
    s0.deleteIntfs()
    s1.cmd( 'ovs-vsctl del-br s1' )
    s1.deleteIntfs()
    info( '\n' )
Exemple #41
0
def scratchNet(cname='controller', cargs='-v ptcp:'):
    "Create network from scratch using Open vSwitch."

    info("*** Creating nodes\n")
    controller = Node('c0', inNamespace=False)
    switch = Node('s0', inNamespace=False)
    switch1 = Node('s1', inNamespace=False)
    h0 = Node('h0')
    h1 = Node('h1')
    h2 = Node('h2')
    h3 = Node('h3')
    h4 = Node('h4')
    h5 = Node('h5')
    h6 = Node('h6')
    h7 = Node('h7')

    info("*** Creating links\n")
    Link(h0, switch)
    Link(h1, switch)
    Link(h2, switch)
    Link(h3, switch)
    Link(h4, switch1)
    Link(h5, switch1)
    Link(h6, switch1)
    Link(h7, switch1)
    info("*** Configuring hosts\n")
    h0.setIP('192.168.123.1/24')
    h1.setIP('192.168.123.2/24')
    h2.setIP('192.168.123.3/24')
    h3.setIP('192.168.123.4/24')
    h4.setIP('192.168.123.5/24')
    h5.setIP('192.168.123.6/24')
    h6.setIP('192.168.123.7/24')
    h7.setIP('192.168.123.8/24')
    info(str(h0) + '\n')
    info(str(h1) + '\n')
    info(str(h2) + '\n')
    info(str(h3) + '\n')
    info(str(h4) + '\n')
    info(str(h5) + '\n')
    info(str(h6) + '\n')
    info(str(h7) + '\n')

    info("*** Starting network using Open vSwitch\n")
    controller.cmd(cname + ' ' + cargs + '&')
    switch.cmd('ovs-vsctl del-br dp0')
    switch.cmd('ovs-vsctl add-br dp0')
    switch1.cmd('ovs-vsctl del-br dp0')
    switch1.cmd('ovs-vsctl add-br dp0')

    net.addLink(switch, switch1, delay='5ms', loss=20)
    for intf in switch.intfs.values():
        print switch.cmd('ovs-vsctl add-port dp0 %s' % intf)
    for intf in switch1.intfs.values():
        print switch1.cmd('ovs-vsctl add-port dp0 %s' % intf)

    # Note: controller and switch are in root namespace, and we
    # can connect via loopback interface
    switch.cmd('ovs-vsctl set-controller dp0 tcp:127.0.0.1:6633')
    switch1.cmd('ovs-vsctl set-controller dp0 tcp:127.0.0.1:6633')

    linkopts = dict(bw=10,
                    delay='5ms',
                    loss=20,
                    max_queue_size=1000,
                    use_htb=True)
    info('*** Waiting for switch to connect to controller')
    while 'is_connected' not in quietRun('ovs-vsctl show'):
        sleep(1)
        info('.')
    info('\n')

    info("*** Running test\n")

    h0.sendCmd(
        ' /home/amellalghamdi/Desktop/cse223bFinalProject/lib/kv_server 1 239.0.2.1 9000 1 2 3 4 >&1 > `ifconfig | grep eth | cut -f1 -d`.out1`'
    )
    h1.cmdPrint(
        ' /home/amellalghamdi/Desktop/cse223bFinalProject/lib/kv_server 2 239.0.2.1 9000 1 2 3 4 >&1 > `ifconfig | grep eth | cut -f1 -d`.out2`'
    )
    h2.cmdPrint(
        '/home/amellalghamdi/Desktop/cse223bFinalProject/lib/kv_server 3 239.0.2.1 9000 1 2 3 4 >&1 > `ifconfig | grep eth | cut -f1 -d`.out3'
    )
    h3.cmdPrint(
        ' /home/amellalghamdi/Desktop/cse223bFinalProject/lib/kv_server 4 239.0.2.1 9000 1 2 3 4 >&1 > `ifconfig | grep eth | cut -f1 -d`.out4'
    )

    info("*** Stopping network\n")
    #controller.cmd( 'kill %' + cname )
    #switch.cmd( 'ovs-vsctl del-br dp0' )
    #switch.deleteIntfs()
    #switch1.cmd( 'ovs-vsctl del-br dp0' )
    #switch1.deleteIntfs()
    info('\n')
def scratchNet( cname='controller', cargs='-v ptcp:' ):
    "Create network from scratch using Open vSwitch."

    info( "*** Creating nodes\n" )
    controller = Node( 'c0', inNamespace=False )
    s1 = Node( 's0', inNamespace=False )
    s2 = Node( 's1', inNamespace=False )
    s3 = Node( 's2', inNamespace=False )
    s4 = Node( 's3', inNamespace=False )
    s5 = Node( 's4', inNamespace=False )
    s6 = Node( 's5', inNamespace=False )
    s7 = Node( 's6', inNamespace=False )
    s8 = Node( 's7', inNamespace=False )
    s9 = Node( 's8', inNamespace=False )
    s10 = Node( 's9', inNamespace=False )
    s11 = Node( 's10', inNamespace=False )
    s12 = Node( 's11', inNamespace=False )
    s13 = Node( 's12', inNamespace=False )
    s14 = Node( 's13', inNamespace=False )
    s15 = Node( 's14', inNamespace=False )
    s16 = Node( 's15', inNamespace=False )

    h1 = Node( 'h1' )
    h2 = Node( 'h2' )
    h3 = Node( 'h3' )
    h4 = Node( 'h4' )
    h5 = Node( 'h5' )
    h6 = Node( 'h6' )
    h7 = Node( 'h7' )
    h8 = Node( 'h8' )
    h9 = Node( 'h9' )
    h10 = Node( 'h10' )
    h11 = Node( 'h11' )
    h12 = Node( 'h12' )
    h13 = Node( 'h13' )
    h14 = Node( 'h14' )
    h15 = Node( 'h15' )
    h16 = Node( 'h16' )

    info( "*** Creating Host-Switch links\n" )
    Link( h1, s1 )
    Link( h2, s2 )
    Link( h3, s3 )
    Link( h4, s4 )
    Link( h5, s5 )
    Link( h6, s6 )
    Link( h7, s7 )
    Link( h8, s8 )
    Link( h9, s9 )
    Link( h10, s10 )
    Link( h11, s11 )
    Link( h12, s12 )
    Link( h13, s13 )
    Link( h14, s14 )
    Link( h15, s15 )
    Link( h16, s16 )

    info( "*** Creating Switch-Switch links\n" )
    Link( s1, s2 )
    Link( s2, s3 )
    Link( s3, s4 )
    Link( s4, s5 )
    Link( s5, s6 )
    Link( s6, s7 )
    Link( s7, s8 )
    Link( s8, s9 )
    Link( s9, s10 )
    Link( s10, s11 )
    Link( s11, s12 )
    Link( s12, s13 )
    Link( s13, s14 )
    Link( s14, s15 )
    Link( s15, s16 )

    info( "*** Configuring hosts\n" )
    h1.setIP( '192.168.123.1/24' )
    h2.setIP( '192.168.123.2/24' )
    h3.setIP( '192.168.123.3/24' )
    h4.setIP( '192.168.123.4/24' )
    h5.setIP( '192.168.123.5/24' )
    h6.setIP( '192.168.123.6/24' )
    h7.setIP( '192.168.123.7/24' )
    h8.setIP( '192.168.123.8/24' )
    h9.setIP( '192.168.123.9/24' )
    h10.setIP( '192.168.123.10/24' )
    h11.setIP( '192.168.123.11/24' )
    h12.setIP( '192.168.123.12/24' )
    h13.setIP( '192.168.123.13/24' )
    h14.setIP( '192.168.123.14/24' )
    h15.setIP( '192.168.123.15/24' )
    h16.setIP( '192.168.123.16/24' )
    info( str( h1 ) + '\n' )
    info( str( h2 ) + '\n' )
    info( str( h3 ) + '\n' )
    info( str( h4 ) + '\n' )
    info( str( h5 ) + '\n' )
    info( str( h6 ) + '\n' )
    info( str( h7 ) + '\n' )
    info( str( h8 ) + '\n' )
    info( str( h9 ) + '\n' )
    info( str( h10 ) + '\n' )
    info( str( h11 ) + '\n' )
    info( str( h12 ) + '\n' )
    info( str( h13 ) + '\n' )
    info( str( h14 ) + '\n' )
    info( str( h15 ) + '\n' )
    info( str( h16 ) + '\n' )

    info( "*** Running test\n" )
    h1.cmdPrint( 'iperf -s &')
    h16.cmdPrint( 'time iperf -c ' + h1.IP() + ' -t2 -n 100M &')
    h16.cmdPrint( 'ping -c100 ' + h1.IP() + ' &')

    info( "*** Stopping network\n" )
    controller.cmd( 'kill %' + cname )
    info( '\n' )
def myNet():
    "Defines a custom topology on mininet."

    print "*** Starting MyNet ***"
    cParams = ControllerParams( '10.0.3.0', 24 )
    net = Mininet( controller=RemoteController, switch=OVSKernelSwitch, cparams=cParams )

    print "** Adding controller"
    c = net.addController( 'c0' )

    print "** Adding switches"
    s1 = net.addSwitch( 's1' )
    s2 = net.addSwitch( 's2' )
    s3 = net.addSwitch( 's3' )
    s4 = net.addSwitch( 's4' )
    s5 = net.addSwitch( 's5' )
    s6 = net.addSwitch( 's6' )
    s7 = net.addSwitch( 's7' )
    s8 = net.addSwitch( 's8' )
    s9 = net.addSwitch( 's9' )
    s10 = net.addSwitch( 's10' )

    print "** Adding hosts"
    h1 = net.addHost( 'h1', ip='10.0.3.1' )
    h2 = net.addHost( 'h2', ip='10.0.3.2' )
    h3 = net.addHost( 'h3', ip='10.0.3.3' )
    h4 = net.addHost( 'h4', ip='10.0.3.4' )
    h5 = net.addHost( 'h5', ip='10.0.3.5' )
    h6 = net.addHost( 'h6', ip='10.0.3.6' )
    h7 = net.addHost( 'h7', ip='10.0.3.7' )
    h8 = net.addHost( 'h8', ip='10.0.3.8' )
    h9 = net.addHost( 'h9', ip='10.0.3.9' )
    h10 = net.addHost( 'h10', ip='10.0.3.10' )
    h11 = net.addHost( 'h11', ip='10.0.3.11' )
    h12 = net.addHost( 'h12', ip='10.0.3.12' )
    h13 = net.addHost( 'h13', ip='10.0.3.13' )
    h14 = net.addHost( 'h14', ip='10.0.3.14' )
    h15 = net.addHost( 'h15', ip='10.0.3.15' )
    h16 = net.addHost( 'h16', ip='10.0.3.16' )
    h17 = net.addHost( 'h17', ip='10.0.3.17' )
    h18 = net.addHost( 'h18', ip='10.0.3.18' )
    h19 = net.addHost( 'h19', ip='10.0.3.19' )
    h20 = net.addHost( 'h20', ip='10.0.3.20' )

    print "** Linking switches and hosts"
    # S1
    s1.linkTo( s2 )
    s1.linkTo( h1 )
    s1.linkTo( h2 )
    s1.linkTo( h3 )
    # S2
    s2.linkTo( s3 )
    s2.linkTo( s4 )
    s2.linkTo( s5 )
    # S3
    s3.linkTo( s6 )
    s3.linkTo( h4 )
    s3.linkTo( h5 )
    # S4
    s4.linkTo( s8 )
    s4.linkTo( h6 )
    s4.linkTo( h7 )
    s4.linkTo( h8 )
    # S5
    s5.linkTo( s9 )
    s5.linkTo( s10 )
    s5.linkTo( h9 )
    s5.linkTo( h10 )
    # S6
    s6.linkTo( s7 )
    s6.linkTo( h11 )
    s6.linkTo( h12 )
    s6.linkTo( h13 )
    # S7
    s7.linkTo( h14 )
    s7.linkTo( h15 )
    s7.linkTo( h16 )
    # S8
    s8.linkTo( h17 )
    s8.linkTo( h18 )
    # S9
    s9.linkTo( h19 )
    # S10
    s10.linkTo( h20 )

    print "** Creating extra node to enable access to others"
    # Create a node in root namespace and link to switch 0
    root = Node( 'root', inNamespace=False )
    root.linkTo( s1 )
    root.setMAC( root.defaultIntf(), "00:00:00:11:00:64" )
    root.setIP( root.defaultIntf(), "10.0.3.100", 24 )

    # Configure everything
    s1.setMAC ( 's1-eth1', '00:00:00:10:01:01' )
    s1.setMAC ( 's1-eth2', '00:00:00:10:01:02' )
    s1.setMAC ( 's1-eth3', '00:00:00:10:01:03' )
    s1.setMAC ( 's1-eth4', '00:00:00:10:01:04' )
    s1.setMAC ( 's1-eth5', '00:00:00:10:01:05' ) # Extra for the root

    s2.setMAC ( 's2-eth1', '00:00:00:10:02:01' )
    s2.setMAC ( 's2-eth2', '00:00:00:10:02:02' )
    s2.setMAC ( 's2-eth3', '00:00:00:10:02:03' )
    s2.setMAC ( 's2-eth4', '00:00:00:10:02:04' )

    s3.setMAC ( 's3-eth1', '00:00:00:10:03:01' )
    s3.setMAC ( 's3-eth2', '00:00:00:10:03:02' )
    s3.setMAC ( 's3-eth3', '00:00:00:10:03:03' )
    s3.setMAC ( 's3-eth4', '00:00:00:10:03:04' )

    s4.setMAC ( 's4-eth1', '00:00:00:10:04:01' )
    s4.setMAC ( 's4-eth2', '00:00:00:10:04:02' )
    s4.setMAC ( 's4-eth3', '00:00:00:10:04:03' )
    s4.setMAC ( 's4-eth4', '00:00:00:10:04:04' )
    s4.setMAC ( 's4-eth5', '00:00:00:10:04:05' )

    s5.setMAC ( 's5-eth1', '00:00:00:10:05:01' )
    s5.setMAC ( 's5-eth2', '00:00:00:10:05:02' )
    s5.setMAC ( 's5-eth3', '00:00:00:10:05:03' )
    s5.setMAC ( 's5-eth4', '00:00:00:10:05:04' )
    s5.setMAC ( 's5-eth5', '00:00:00:10:05:05' )

    s6.setMAC ( 's6-eth1', '00:00:00:10:06:01' )
    s6.setMAC ( 's6-eth2', '00:00:00:10:06:02' )
    s6.setMAC ( 's6-eth3', '00:00:00:10:06:03' )
    s6.setMAC ( 's6-eth4', '00:00:00:10:06:04' )
    s6.setMAC ( 's6-eth5', '00:00:00:10:06:05' )

    s7.setMAC ( 's7-eth1', '00:00:00:10:07:01' )
    s7.setMAC ( 's7-eth2', '00:00:00:10:07:02' )
    s7.setMAC ( 's7-eth3', '00:00:00:10:07:03' )
    s7.setMAC ( 's7-eth4', '00:00:00:10:07:04' )

    s8.setMAC ( 's8-eth1', '00:00:00:10:08:01' )
    s8.setMAC ( 's8-eth2', '00:00:00:10:08:02' )
    s8.setMAC ( 's8-eth3', '00:00:00:10:08:03' )

    s9.setMAC ( 's9-eth1', '00:00:00:10:09:01' )
    s9.setMAC ( 's9-eth2', '00:00:00:10:09:02' )

    s10.setMAC ( 's10-eth1', '00:00:00:10:10:01' )
    s10.setMAC ( 's10-eth2', '00:00:00:10:10:02' )

    s1.setIP ( s1.defaultIntf(), '10.0.3.101', 24 )
    s2.setIP ( s2.defaultIntf(), '10.0.3.102', 24 )
    s3.setIP ( s3.defaultIntf(), '10.0.3.103', 24 )
    s4.setIP ( s4.defaultIntf(), '10.0.3.104', 24 )
    s5.setIP ( s5.defaultIntf(), '10.0.3.105', 24 )
    s6.setIP ( s6.defaultIntf(), '10.0.3.106', 24 )
    s7.setIP ( s7.defaultIntf(), '10.0.3.107', 24 )
    s8.setIP ( s8.defaultIntf(), '10.0.3.108', 24 )
    s9.setIP ( s9.defaultIntf(), '10.0.3.109', 24 )
    s10.setIP ( s10.defaultIntf(), '10.0.3.110', 24 )

    h1.setMAC( h1.defaultIntf(), "00:00:00:11:00:01" )
    h2.setMAC( h2.defaultIntf(), "00:00:00:11:00:02" )
    h3.setMAC( h3.defaultIntf(), "00:00:00:11:00:03" )
    h4.setMAC( h4.defaultIntf(), "00:00:00:11:00:04" )
    h5.setMAC( h5.defaultIntf(), "00:00:00:11:00:05" )
    h6.setMAC( h6.defaultIntf(), "00:00:00:11:00:06" )
    h7.setMAC( h7.defaultIntf(), "00:00:00:11:00:07" )
    h8.setMAC( h8.defaultIntf(), "00:00:00:11:00:08" )
    h9.setMAC( h9.defaultIntf(), "00:00:00:11:00:09" )
    h10.setMAC( h10.defaultIntf(), "00:00:00:11:00:10" )
    h11.setMAC( h11.defaultIntf(), "00:00:00:11:00:11" )
    h12.setMAC( h12.defaultIntf(), "00:00:00:11:00:12" )
    h13.setMAC( h13.defaultIntf(), "00:00:00:11:00:13" )
    h14.setMAC( h14.defaultIntf(), "00:00:00:11:00:14" )
    h15.setMAC( h15.defaultIntf(), "00:00:00:11:00:15" )
    h16.setMAC( h16.defaultIntf(), "00:00:00:11:00:16" )
    h17.setMAC( h17.defaultIntf(), "00:00:00:11:00:17" )
    h18.setMAC( h18.defaultIntf(), "00:00:00:11:00:18" )
    h19.setMAC( h19.defaultIntf(), "00:00:00:11:00:19" )
    h20.setMAC( h20.defaultIntf(), "00:00:00:11:00:20" )

    print "** Firing up the network"
    net.build()
    c.start()
    for s in net.switches:
        s.start( [ c ] )
    
    print "** Starting SSH Server in every host"
    sshpids = {}
    for h in net.hosts:
        h.cmd( '/usr/sbin/sshd -D &' )
        time.sleep(0.5) # Whait for the daemon to come up so we can see its pid (this is not very safe)
        output = h.cmd( 'cat /var/run/sshd.pid' )
        sshpids[h.name] = output.rstrip()

    print "** Starting Libvirt in every host"
    for h in net.hosts:
        ip = h.IP()
        h.cmd( 'ip addr flush ' + h.defaultIntf() )
        if not os.path.exists( '/usr/local/etc/openvswitch/' + h.name + '-conf.db' ):
            h.cmd( 'ovsdb-tool create /usr/local/etc/openvswitch/' + h.name + '-conf.db /home/jwickboldt/openvswitch-1.10.0/vswitchd/vswitch.ovsschema' )
        h.cmd( 'ovsdb-server /usr/local/etc/openvswitch/' + h.name + '-conf.db --remote=punix:/usr/local/var/run/openvswitch/' + h.name + '-db.sock --pidfile=/usr/local/var/run/openvswitch/' + h.name + '-ovsdb-server.pid --detach' )
        h.cmd( 'ovs-vsctl --db=unix:/usr/local/var/run/openvswitch/' + h.name + '-db.sock --no-wait init' )
        h.cmd( 'ovs-vswitchd unix:/usr/local/var/run/openvswitch/' + h.name + '-db.sock --pidfile=/usr/local/var/run/openvswitch/' + h.name + '-ovs-vswitchd.pid --detach' )
        h.cmd( 'ovs-vsctl --db=unix:/usr/local/var/run/openvswitch/' + h.name + '-db.sock add-br virbr1' )
        h.cmd( 'ovs-vsctl --db=unix:/usr/local/var/run/openvswitch/' + h.name + '-db.sock add-port virbr1 ' + h.defaultIntf() )
        h.cmd( 'ovs-vsctl --db=unix:/usr/local/var/run/openvswitch/' + h.name + '-db.sock set-controller virbr1 tcp:10.0.3.100:6633' )
        h.cmd( 'ip link set dev virbr1 up' )
        h.setIP( 'virbr1', ip, 24 )

        # Default route through root-eth0
        h.cmd ( 'route add default gw 10.0.3.100' )
        h.cmd ( 'libvirtd-' + h.name + ' -d -l' )

    #print "** Testing network"
    #net.pingAll()

    print "** Running CLI"
    CLI( net )

    print "** Killing daemons"
    for h in net.hosts:
        h.cmd( 'kill `pidof libvirtd-' + h.name + '`' )
        h.cmd( 'ovs-vsctl --db=unix:/usr/local/var/run/openvswitch/' + h.name + '-db.sock del-br virbr1' )
        h.cmd( 'kill $(cat /usr/local/var/run/openvswitch/' + h.name + '-ovsdb-server.pid)' )
        h.cmd( 'kill $(cat /usr/local/var/run/openvswitch/' + h.name + '-ovs-vswitchd.pid)' )
        if len( sshpids[h.name] ) < 7:
            h.cmd( 'kill ' + sshpids[h.name] )

    print "** Stopping network"
    net.stop()
Exemple #44
0
class OpenstackManage(object):
    """
    OpenstackManage is a singleton and management component for the emulator.
    It is the brain of the Openstack component and manages everything that is not datacenter specific like
    network chains or load balancers.
    """
    __instance = None

    def __new__(cls):
        if OpenstackManage.__instance is None:
            OpenstackManage.__instance = object.__new__(cls)
        return OpenstackManage.__instance

    def __init__(self, ip="0.0.0.0", port=4000):
        # we are a singleton, only initialize once!
        self.lock = threading.Lock()
        with self.lock:
            if hasattr(self, "init"):
                return
            self.init = True

        self.endpoints = dict()
        self.cookies = set()
        self.cookies.add(0)
        self.ip = ip
        self.port = port
        self._net = None
        # to keep track which src_vnf(input port on the switch) handles a load balancer
        self.lb_flow_cookies = dict()
        self.chain_flow_cookies = dict()

        # for the visualization also store the complete chain data incl. paths
        self.full_chain_data = dict()
        self.full_lb_data = dict()

        # flow groups could be handled for each switch separately, but this global group counter should be easier to
        # debug and to maintain
        self.flow_groups = dict()

        # we want one global chain api. this should not be datacenter dependent!
        self.chain = chain_api.ChainApi(ip, port, self)
        self.thread = threading.Thread(target=self.chain._start_flask, args=())
        self.thread.daemon = True
        self.thread.name = self.chain.__class__
        self.thread.start()

        # floating ip network setup
        self.floating_switch = None
        self.floating_network = None
        self.floating_netmask = "192.168.100.0/24"
        self.floating_nodes = dict()
        self.floating_cookies = dict()
        self.floating_intf = None
        self.floating_links = dict()

    @property
    def net(self):
        return self._net

    @net.setter
    def net(self, value):
        if self._net is None:
            self._net = value
            self.init_floating_network()
        self._net = value

    def init_floating_network(self):
        """
        Initialize the floating network component for the emulator.
        Will not do anything if already initialized.
        """
        if self.net is not None and self.floating_switch is None:
            # create a floating network
            fn = self.floating_network = Net("default")
            fn.id = str(uuid.uuid4())
            fn.set_cidr(self.floating_netmask)

            # create a subnet
            fn.subnet_id = str(uuid.uuid4())
            fn.subnet_name = fn.name + "-sub"

            # create a port for the host
            port = Port("root-port")
            #port.id = str(uuid.uuid4())
            port.net_name = fn.name

            # get next free ip
            root_ip = fn.get_new_ip_address(port.name)
            port.ip_address = root_ip
            # floating ip network setup
            # wierd way of getting a datacenter object
            first_dc = self.net.dcs.values()[0]
            # set a dpid for the switch. for this we have to get the id of the next possible dc
            self.floating_switch = self.net.addSwitch("fs1", dpid=hex(first_dc._get_next_dc_dpid())[2:])
            # this is the interface appearing on the physical host
            self.floating_root = Node('root', inNamespace=False)
            self.net.hosts.append(self.floating_root)
            self.net.nameToNode['root'] = self.floating_root
            self.floating_intf = self.net.addLink(self.floating_root, self.floating_switch).intf1
            self.floating_root.setIP(root_ip, intf=self.floating_intf)
            self.floating_nodes[(self.floating_root.name, root_ip)] = self.floating_root


    def stop_floating_network(self):
        self._net = None
        self.floating_switch = None

    def add_endpoint(self, ep):
        """
        Registers an openstack endpoint with manage

        :param ep: Openstack API endpoint
        :type ep: :class:`heat.openstack_api_endpoint`
        """
        key = "%s:%s" % (ep.ip, ep.port)
        self.endpoints[key] = ep

    def get_cookie(self):
        """
        Get an unused cookie.

        :return: Cookie
        :rtype: ``int``
        """
        cookie = int(max(self.cookies) + 1)
        self.cookies.add(cookie)
        return cookie

    def get_flow_group(self, src_vnf_name, src_vnf_interface):
        """
        Gets free group that is not currently used by any other flow for the specified interface / VNF.

        :param src_vnf_name: Source VNF name
        :type src_vnf_name: ``str``
        :param src_vnf_interface: Source VNF interface name
        :type src_vnf_interface: ``str``
        :return: Flow group identifier.
        :rtype: ``int``
        """
        if (src_vnf_name, src_vnf_interface) not in self.flow_groups:
            grp = int(len(self.flow_groups) + 1)
            self.flow_groups[(src_vnf_name, src_vnf_interface)] = grp
        else:
            grp = self.flow_groups[(src_vnf_name, src_vnf_interface)]
        return grp

    def check_vnf_intf_pair(self, vnf_name, vnf_intf_name):
        """
        Checks if a VNF exists and has the given interface

        :param vnf_name: Name of the VNF to be checked
        :type vnf_name: ``str``
        :param vnf_intf_name: Name of the interface that belongst to the VNF
        :type vnf_intf_name: ``str``
        :return: ``True`` if it is valid pair, else ``False``
        :rtype: ``bool``
        """

        if vnf_name in self.net:
            vnf = self.net.getNodeByName(vnf_name)
            return vnf_intf_name in vnf.nameToIntf

    def network_action_start(self, vnf_src_name, vnf_dst_name, **kwargs):
        """
        Starts a network chain for a source destination pair

        :param vnf_src_name: Name of the source VNF
        :type vnf_src_name: ``str``
        :param vnf_dst_name: Name of the source VNF interface
        :type vnf_dst_name: ``str``
        :param \**kwargs: See below

        :Keyword Arguments:
            * *vnf_src_interface* (``str``): Name of source interface.
            * *vnf_dst_interface* (``str``): Name of destination interface.
            * *weight* (``int``): This value is fed into the shortest path computation if no path is specified.
            * *match* (``str``): A custom match entry for the openflow flow rules. Only vlanid or port possible.
            * *bidirectional* (``bool``): If set the chain will be set in both directions, else it will just set up \
                            from source to destination.
            * *cookie* (``int``): Cookie value used by openflow. Used to identify the flows in the switches to be \
                            able to modify the correct flows.
            * *no_route* (``bool``): If set a layer 3 route to the target interface will not be set up.
        :return: The cookie chosen for the flow.
        :rtype: ``int``
        """
        try:
            vnf_src_interface = kwargs.get('vnf_src_interface')
            vnf_dst_interface = kwargs.get('vnf_dst_interface')
            layer2 = kwargs.get('layer2', True)
            match = kwargs.get('match')
            flow = (vnf_src_name, vnf_src_interface, vnf_dst_name, vnf_dst_interface)
            if flow in self.chain_flow_cookies:
                raise Exception("There is already a chain at the specified src/dst pair!")
            # set up a layer 2 chain, this allows multiple chains for the same interface
            src_node = self.net.getNodeByName(vnf_src_name)
            dst_node = self.net.getNodeByName(vnf_dst_name)
            dst_intf = dst_node.intf(vnf_dst_interface)
            if layer2:
                switch, inport = self._get_connected_switch_data(vnf_src_name, vnf_src_interface)
                self.setup_arp_reply_at(switch, inport, dst_intf.IP(), dst_intf.MAC())
                if isinstance(match, str):
                    match += ",dl_dst=%s" % dst_intf.MAC()
                else:
                    match = "dl_dst=%s" % dst_intf.MAC()

            cookie = kwargs.get('cookie', self.get_cookie())
            self.cookies.add(cookie)
            c = self.net.setChain(
                vnf_src_name, vnf_dst_name,
                vnf_src_interface=vnf_src_interface,
                vnf_dst_interface=vnf_dst_interface,
                cmd='add-flow',
                weight=kwargs.get('weight'),
                match=match,
                bidirectional=False,
                cookie=cookie,
                path=kwargs.get('path'))

            # to keep this logic seperate of the core son-emu do the housekeeping here
            data = dict()
            data["src_vnf"] = vnf_src_name
            data["src_intf"] = vnf_src_interface
            data["dst_vnf"] = vnf_dst_name
            data["dst_intf"] = vnf_dst_interface
            data["cookie"] = cookie
            data["layer2"] = layer2
            if kwargs.get('path') is not None:
                data["path"] = kwargs.get('path')
            else:
                data["path"] = self._get_path(vnf_src_name, vnf_dst_name, vnf_src_interface,
                                              vnf_dst_interface)[0]

            # add route to dst ip to this interface
            # this might block on containers that are still setting up, so start a new thread
            if not kwargs.get('no_route'):
                # son_emu does not like concurrent commands for a container so we need to lock this if multiple chains
                # on the same interface are created
                src_node.setHostRoute(dst_node.intf(vnf_dst_interface).IP(), vnf_src_interface)

            try:
                son_emu_data = json.loads(self.get_son_emu_chain_data(vnf_src_name))
            except:
                son_emu_data = dict()
            if "son_emu_data" not in son_emu_data:
                son_emu_data["son_emu_data"] = dict()
            if "interfaces" not in son_emu_data["son_emu_data"]:
                son_emu_data["son_emu_data"]["interfaces"] = dict()
            if vnf_src_interface not in son_emu_data["son_emu_data"]["interfaces"]:
                son_emu_data["son_emu_data"]["interfaces"][vnf_src_interface] = list()
                son_emu_data["son_emu_data"]["interfaces"][vnf_src_interface].append(dst_intf.IP())

            self.set_son_emu_chain_data(vnf_src_name, son_emu_data)

            if kwargs.get('bidirectional', False):
                # call the reverse direction
                path = kwargs.get('path')
                if path is not None:
                    path = list(reversed(path))
                self.network_action_start(vnf_dst_name, vnf_src_name, vnf_src_interface=vnf_dst_interface,
                                          vnf_dst_interface=vnf_src_interface, bidirectional=False,
                                          layer2=kwargs.get('layer2', False), path=path,
                                          no_route=kwargs.get('no_route'))

            self.full_chain_data[flow] = data
            self.chain_flow_cookies[flow] = cookie
            return cookie
        except Exception as ex:
            logging.exception("RPC error.")
            raise Exception(ex.message)

    def network_action_stop(self, vnf_src_name, vnf_dst_name, **kwargs):
        """
        Starts a network chain for a source destination pair

        :param vnf_src_name: Name of the source VNF
        :type vnf_src_name: ``str``
        :param vnf_dst_name: Name of the source VNF interface
        :type vnf_dst_name: ``str``
        :param \**kwargs: See below

        :Keyword Arguments:
            * *vnf_src_interface* (``str``): Name of source interface.
            * *vnf_dst_interface* (``str``): Name of destination interface.
            * *bidirectional* (``bool``): If set the chain will be torn down in both directions, else it will just\
                            be torn down from source to destination.
            * *cookie* (``int``): Cookie value used by openflow. Used to identify the flows in the switches to be \
                            able to modify the correct flows.
        """
        try:
            if 'cookie' in kwargs:
                return self.delete_flow_by_cookie(kwargs.get('cookie'))

            if kwargs.get('bidirectional', False):
                self.delete_chain_by_intf(vnf_dst_name, kwargs.get('vnf_dst_interface'),
                                          vnf_src_name, kwargs.get('vnf_src_interface'))

            return self.delete_chain_by_intf(vnf_src_name, kwargs.get('vnf_src_interface'),
                                             vnf_dst_name, kwargs.get('vnf_dst_interface'))
        except Exception as ex:
            logging.exception("RPC error.")
            return ex.message

    def set_son_emu_chain_data(self, vnf_name, data):
        """
        Set son-emu chain data for this node.

        :param vnf_name: The name of the vnf where the data is stored.
        :type vnf_name: ``str``
        :param data: Raw data to store on the node.
        :type data: ``str``
        """
        self.net.getNodeByName(vnf_name).cmd("echo \'%s\' > /tmp/son_emu_data.json" % json.dumps(data))
        ip_list = []
        for intf in data['son_emu_data']['interfaces'].values():
            ip_list.extend(intf)

        self.net.getNodeByName(vnf_name).cmd("echo \'%s\' > /tmp/son_emu_data" % "\n".join(ip_list))

    def get_son_emu_chain_data(self, vnf_name):
        """
        Get the current son-emu chain data set for this node.

        :param vnf_name: The name of the vnf where the data is stored.
        :type vnf_name: ``str``
        :return: raw data stored on the node
        :rtype: ``str``
        """
        return self.net.getNodeByName(vnf_name).cmd("cat /tmp/son_emu_data.json")

    def _get_connected_switch_data(self, vnf_name, vnf_interface):
        """
        Get the switch an interface is connected to
        :param vnf_name: Name of the VNF
        :type vnf_name: ``str``
        :param vnf_interface: Name of the VNF interface
        :type vnf_interface: ``str``
        :return: List containing the switch, and the inport number
        :rtype: [``str``, ``int``]
        """
        src_sw = None
        src_sw_inport_nr = None
        for connected_sw in self.net.DCNetwork_graph.neighbors(vnf_name):
            link_dict = self.net.DCNetwork_graph[vnf_name][connected_sw]
            for link in link_dict:
                if (link_dict[link]['src_port_id'] == vnf_interface or
                            link_dict[link][
                                'src_port_name'] == vnf_interface):
                    # found the right link and connected switch
                    src_sw = connected_sw
                    src_sw_inport_nr = link_dict[link]['dst_port_nr']
                    break

        return src_sw, src_sw_inport_nr

    def _get_path(self, src_vnf, dst_vnf, src_vnf_intf, dst_vnf_intf):
        """
        Own implementation of the get_path function from DCNetwork, because we just want the path and not set up
        flows on the way.

        :param src_vnf: Name of the source VNF
        :type src_vnf: ``str``
        :param dst_vnf: Name of the destination VNF
        :type dst_vnf: ``str``
        :param src_vnf_intf: Name of the source VNF interface
        :type src_vnf_intf: ``str``
        :param dst_vnf_intf: Name of the destination VNF interface
        :type dst_vnf_intf: ``str``
        :return: path, src_sw, dst_sw
        :rtype: ``list``, ``str``, ``str``
        """
        # modified version of the _chainAddFlow from emuvim.dcemulator.net._chainAddFlow
        src_sw = None
        dst_sw = None
        logging.debug("Find shortest path from vnf %s to %s",
                      src_vnf, dst_vnf)

        for connected_sw in self.net.DCNetwork_graph.neighbors(src_vnf):
            link_dict = self.net.DCNetwork_graph[src_vnf][connected_sw]
            for link in link_dict:
                if (link_dict[link]['src_port_id'] == src_vnf_intf or
                            link_dict[link][
                                'src_port_name'] == src_vnf_intf):
                    # found the right link and connected switch
                    src_sw = connected_sw
                    break

        for connected_sw in self.net.DCNetwork_graph.neighbors(dst_vnf):
            link_dict = self.net.DCNetwork_graph[connected_sw][dst_vnf]
            for link in link_dict:
                if link_dict[link]['dst_port_id'] == dst_vnf_intf or \
                                link_dict[link][
                                    'dst_port_name'] == dst_vnf_intf:
                    # found the right link and connected
                    dst_sw = connected_sw
                    break
        logging.debug("From switch %s to %s " % (src_sw, dst_sw))

        # get shortest path
        try:
            # returns the first found shortest path
            # if all shortest paths are wanted, use: all_shortest_paths
            path = nx.shortest_path(self.net.DCNetwork_graph, src_sw, dst_sw)
        except:
            logging.exception("No path could be found between {0} and {1} using src_sw={2} and dst_sw={3}".format(
                src_vnf, dst_vnf, src_sw, dst_sw))
            logging.debug("Graph nodes: %r" % self.net.DCNetwork_graph.nodes())
            logging.debug("Graph edges: %r" % self.net.DCNetwork_graph.edges())
            for e, v in self.net.DCNetwork_graph.edges():
                logging.debug("%r" % self.net.DCNetwork_graph[e][v])
            return "No path could be found between {0} and {1}".format(src_vnf, dst_vnf)

        logging.info("Shortest path between {0} and {1}: {2}".format(src_vnf, dst_vnf, path))
        return path, src_sw, dst_sw

    def add_loadbalancer(self, src_vnf_name, src_vnf_interface, lb_data):
        """
        This function will set up a loadbalancer at the given interface.

        :param src_vnf_name: Name of the source VNF
        :type src_vnf_name: ``str``
        :param src_vnf_interface: Name of the destination VNF
        :type src_vnf_interface: ``str``
        :param lb_data: A dictionary containing the destination data as well as custom path settings
        :type lb_data: ``dict``

        :Example:
         lbdata = {"dst_vnf_interfaces": {"dc2_man_web0": "port-man-2",
         "dc3_man_web0": "port-man-4","dc4_man_web0": "port-man-6"}, "path": {"dc2_man_web0": {"port-man-2": [ "dc1.s1",\
         "s1", "dc2.s1"]}}}
        """
        net = self.net
        src_sw_inport_nr = 0
        src_sw = None
        dest_intfs_mapping = lb_data.get('dst_vnf_interfaces', dict())
        # a custom path can be specified as a list of switches
        custom_paths = lb_data.get('path', dict())
        dest_vnf_outport_nrs = list()

        logging.debug("Call to add_loadbalancer at %s intfs:%s" % (src_vnf_name, src_vnf_interface))

        if not self.check_vnf_intf_pair(src_vnf_name, src_vnf_interface):
            raise Exception(u"Source VNF %s or intfs %s does not exist" % (src_vnf_name, src_vnf_interface))

        # find the switch belonging to the source interface, as well as the inport nr
        for connected_sw in net.DCNetwork_graph.neighbors(src_vnf_name):
            link_dict = net.DCNetwork_graph[src_vnf_name][connected_sw]
            for link in link_dict:
                if link_dict[link]['src_port_name'] == src_vnf_interface:
                    src_sw = connected_sw
                    src_sw_inport_nr = link_dict[link]['dst_port_nr']
                    break

        if src_sw is None or src_sw_inport_nr == 0:
            raise Exception(u"Source VNF or interface can not be found.")

        # get all target interface outport numbers
        for vnf_name in dest_intfs_mapping:
            if vnf_name not in net.DCNetwork_graph:
                raise Exception(u"Target VNF %s is not known." % vnf_name)
            for connected_sw in net.DCNetwork_graph.neighbors(vnf_name):
                link_dict = net.DCNetwork_graph[vnf_name][connected_sw]
                for link in link_dict:
                    if link_dict[link]['src_port_name'] == dest_intfs_mapping[vnf_name]:
                        dest_vnf_outport_nrs.append(int(link_dict[link]['dst_port_nr']))
        # get first switch
        if (src_vnf_name, src_vnf_interface) not in self.lb_flow_cookies:
            self.lb_flow_cookies[(src_vnf_name, src_vnf_interface)] = list()

        src_intf = None
        src_ip = None
        src_mac = None
        for intf in net[src_vnf_name].intfs.values():
            if intf.name == src_vnf_interface:
                src_mac = intf.mac
                src_ip = intf.ip
                src_intf = intf

        # set up paths for each destination vnf individually
        index = 0
        cookie = self.get_cookie()
        main_cmd = "add-flow -OOpenFlow13"
        self.lb_flow_cookies[(src_vnf_name, src_vnf_interface)].append(cookie)

        # bookkeeping
        data = dict()
        data["src_vnf"] = src_vnf_name
        data["src_intf"] = src_vnf_interface
        data["paths"] = list()
        data["cookie"] = cookie

        # lb mac for src -> target connections
        lb_mac = "31:33:70:%02x:%02x:%02x" % (random.randint(0, 255),random.randint(0, 255),random.randint(0, 255))

        # calculate lb ip as src_intf.ip +1
        octets = src_ip.split('.')
        octets[3] = str(int(octets[3]) + 1)
        plus_one = '.'.join(octets)

        # set up arp reply as well as add the route to the interface
        self.setup_arp_reply_at(src_sw, src_sw_inport_nr, plus_one, lb_mac, cookie=cookie)
        net.getNodeByName(src_vnf_name).setHostRoute(plus_one, src_vnf_interface)

        for dst_vnf_name, dst_vnf_interface in dest_intfs_mapping.items():
            path, src_sw, dst_sw = self._get_path(src_vnf_name, dst_vnf_name,
                                                  src_vnf_interface, dst_vnf_interface)

            # use custom path if one is supplied
            # json does not support hashing on tuples so we use nested dicts
            if custom_paths is not None and dst_vnf_name in custom_paths:
                if dst_vnf_interface in custom_paths[dst_vnf_name]:
                    path = custom_paths[dst_vnf_name][dst_vnf_interface]
                    logging.debug("Taking custom path from %s to %s: %s" % (src_vnf_name, dst_vnf_name, path))

            if not self.check_vnf_intf_pair(dst_vnf_name, dst_vnf_interface):
                self.delete_loadbalancer(src_vnf_name, src_vnf_interface)
                raise Exception(u"VNF %s or intfs %s does not exist" % (dst_vnf_name, dst_vnf_interface))
            if isinstance(path, dict):
                self.delete_loadbalancer(src_vnf_name, src_vnf_interface)
                raise Exception(u"Can not find a valid path. Are you specifying the right interfaces?.")

            target_mac = "fa:17:00:03:13:37"
            target_ip = "0.0.0.0"
            for intf in net[dst_vnf_name].intfs.values():
                if intf.name == dst_vnf_interface:
                    target_mac = str(intf.mac)
                    target_ip = str(intf.ip)
            dst_sw_outport_nr = dest_vnf_outport_nrs[index]
            current_hop = src_sw
            switch_inport_nr = src_sw_inport_nr

            #self.setup_arp_reply_at(src_sw, src_sw_inport_nr, target_ip, target_mac, cookie=cookie)
            net.getNodeByName(dst_vnf_name).setHostRoute(src_ip, dst_vnf_interface)

            # choose free vlan if path contains more than 1 switch
            if len(path) > 1:
                vlan = net.vlans.pop()
                if vlan == 0:
                    vlan = net.vlans.pop()
            else:
                vlan = None

            single_flow_data = dict()
            single_flow_data["dst_vnf"] = dst_vnf_name
            single_flow_data["dst_intf"] = dst_vnf_interface
            single_flow_data["path"] = path
            single_flow_data["vlan"] = vlan
            single_flow_data["cookie"] = cookie

            data["paths"].append(single_flow_data)

            # src to target
            for i in range(0, len(path)):
                if i < len(path) - 1:
                    next_hop = path[i + 1]
                else:
                    # last switch reached
                    next_hop = dst_vnf_name
                next_node = net.getNodeByName(next_hop)
                if next_hop == dst_vnf_name:
                    switch_outport_nr = dst_sw_outport_nr
                    logging.info("end node reached: {0}".format(dst_vnf_name))
                elif not isinstance(next_node, OVSSwitch):
                    logging.info("Next node: {0} is not a switch".format(next_hop))
                    return "Next node: {0} is not a switch".format(next_hop)
                else:
                    # take first link between switches by default
                    index_edge_out = 0
                    switch_outport_nr = net.DCNetwork_graph[current_hop][next_hop][index_edge_out]['src_port_nr']

                cmd = 'priority=1,in_port=%s,cookie=%s' % (switch_inport_nr, cookie)
                cmd_back = 'priority=1,in_port=%s,cookie=%s' % (switch_outport_nr, cookie)
                # if a vlan is picked, the connection is routed through multiple switches
                if vlan is not None:
                    if path.index(current_hop) == 0:  # first node
                        # flow #index set up
                        cmd = 'in_port=%s' % src_sw_inport_nr
                        cmd += ',cookie=%s' % cookie
                        cmd += ',table=%s' % cookie
                        cmd += ',ip'
                        cmd += ',reg1=%s' % index
                        cmd += ',actions='
                        # set vlan id
                        cmd += ',push_vlan:0x8100'
                        masked_vlan = vlan | 0x1000
                        cmd += ',set_field:%s->vlan_vid' % masked_vlan
                        cmd += ',set_field:%s->eth_dst' % target_mac
                        cmd += ',set_field:%s->ip_dst' % target_ip
                        cmd += ',output:%s' % switch_outport_nr

                        # last switch for reverse route
                        # remove any vlan tags
                        cmd_back += ',dl_vlan=%s' % vlan
                        cmd_back += ',actions=pop_vlan,output:%s' % switch_inport_nr
                    elif next_hop == dst_vnf_name:  # last switch
                        # remove any vlan tags
                        cmd += ',dl_vlan=%s' % vlan
                        cmd += ',actions=pop_vlan,output:%s' % switch_outport_nr
                        # set up arp replys at the port so the dst nodes know the src
                        self.setup_arp_reply_at(current_hop, switch_outport_nr, src_ip, src_mac, cookie=cookie)

                        # reverse route
                        cmd_back = 'in_port=%s' % switch_outport_nr
                        cmd_back += ',cookie=%s' % cookie
                        cmd_back += ',ip'
                        cmd_back += ',actions='
                        cmd_back += 'push_vlan:0x8100'
                        masked_vlan = vlan | 0x1000
                        cmd_back += ',set_field:%s->vlan_vid' % masked_vlan
                        cmd_back += ',set_field:%s->eth_src' % lb_mac
                        cmd_back += ',set_field:%s->ip_src' % plus_one
                        cmd_back += ',output:%s' % switch_inport_nr
                    else:  # middle nodes
                        # if we have a circle in the path we need to specify this, as openflow will ignore the packet
                        # if we just output it on the same port as it came in
                        if switch_inport_nr == switch_outport_nr:
                            cmd += ',dl_vlan=%s,actions=IN_PORT' % (vlan)
                            cmd_back += ',dl_vlan=%s,actions=IN_PORT' % (vlan)
                        else:
                            cmd += ',dl_vlan=%s,actions=output:%s' % (vlan, switch_outport_nr)
                            cmd_back += ',dl_vlan=%s,actions=output:%s' % (vlan, switch_inport_nr)
                # output the packet at the correct outport
                else:
                    cmd = 'in_port=%s' % src_sw_inport_nr
                    cmd += ',cookie=%s' % cookie
                    cmd += ',table=%s' % cookie
                    cmd += ',ip'
                    cmd += ',reg1=%s' % index
                    cmd += ',actions='
                    cmd += ',set_field:%s->eth_dst' % target_mac
                    cmd += ',set_field:%s->ip_dst' % target_ip
                    cmd += ',output:%s' % switch_outport_nr

                    # reverse route
                    cmd_back = 'in_port=%s' % switch_outport_nr
                    cmd_back += ',cookie=%s' % cookie
                    cmd_back += ',ip'
                    cmd_back += ',actions='
                    cmd_back += ',set_field:%s->eth_src' % lb_mac
                    cmd_back += ',set_field:%s->ip_src' % plus_one
                    cmd_back += ',output:%s' % src_sw_inport_nr

                    self.setup_arp_reply_at(current_hop, switch_outport_nr, src_ip, src_mac, cookie=cookie)

                # excecute the command on the target switch
                logging.debug(cmd)
                cmd = "\"%s\"" % cmd
                cmd_back = "\"%s\"" % cmd_back
                net[current_hop].dpctl(main_cmd, cmd)
                net[current_hop].dpctl(main_cmd, cmd_back)

                # set next hop for the next iteration step
                if isinstance(next_node, OVSSwitch):
                    switch_inport_nr = net.DCNetwork_graph[current_hop][next_hop][0]['dst_port_nr']
                    current_hop = next_hop

            # advance to next destination
            index += 1

        # set up the actual load balancing rule as a multipath on the very first switch
        cmd = '"in_port=%s' % src_sw_inport_nr
        cmd += ',cookie=%s' % (cookie)
        cmd += ',ip'
        cmd += ',actions='
        # push 0x01 into the first register
        cmd += 'load:0x1->NXM_NX_REG0[]'
        # load balance modulo n over all dest interfaces
        # TODO: in newer openvswitch implementations this should be changed to symmetric_l3l4+udp
        # to balance any kind of traffic
        cmd += ',multipath(symmetric_l4,1024,modulo_n,%s,0,NXM_NX_REG1[0..12])' % len(dest_intfs_mapping)
        # reuse the cookie as table entry as it will be unique
        cmd += ',resubmit(, %s)"' % cookie

        # actually add the flow
        logging.debug("Switch: %s, CMD: %s" % (src_sw, cmd))
        net[src_sw].dpctl(main_cmd, cmd)

        # finally add all flow data to the internal data storage
        self.full_lb_data[(src_vnf_name, src_vnf_interface)] = data

    def add_floating_lb(self, datacenter, lb_data):
        """
        This function will set up a loadbalancer at the given datacenter.
        This function returns the floating ip assigned to the loadbalancer as multiple ones are possible.

        :param datacenter: The datacenter entrypoint
        :type datacenter: ``str``
        :param lb_data: A dictionary containing the destination data as well as custom path settings
        :type lb_data: ``dict``

        :Example:
         lbdata = {"dst_vnf_interfaces": {"dc2_man_web0": "port-man-2",
         "dc3_man_web0": "port-man-4","dc4_man_web0": "port-man-6"}, "path": {"dc2_man_web0": {"port-man-2": [ "dc1.s1",\
         "s1", "dc2.s1"]}}}
        """
        net = self.net
        src_sw_inport_nr = 1
        src_sw = self.floating_switch.name
        dest_intfs_mapping = lb_data.get('dst_vnf_interfaces', dict())
        # a custom path can be specified as a list of switches
        custom_paths = lb_data.get('path', dict())
        dest_vnf_outport_nrs = list()

        if datacenter not in self.net.dcs:
            raise Exception(u"Source datacenter can not be found.")

        # get all target interface outport numbers
        for vnf_name in dest_intfs_mapping:
            if vnf_name not in net.DCNetwork_graph:
                raise Exception(u"Target VNF %s is not known." % vnf_name)
            for connected_sw in net.DCNetwork_graph.neighbors(vnf_name):
                link_dict = net.DCNetwork_graph[vnf_name][connected_sw]
                for link in link_dict:
                    if link_dict[link]['src_port_name'] == dest_intfs_mapping[vnf_name]:
                        dest_vnf_outport_nrs.append(int(link_dict[link]['dst_port_nr']))

        if len(dest_vnf_outport_nrs) == 0:
            raise Exception("There are no paths specified for the loadbalancer")
        src_ip = self.floating_intf.IP()
        src_mac = self.floating_intf.MAC()

        # set up paths for each destination vnf individually
        index = 0
        cookie = self.get_cookie()
        main_cmd = "add-flow -OOpenFlow13"
        floating_ip = self.floating_network.get_new_ip_address("floating-ip").split("/")[0]

        for dst_vnf_name, dst_vnf_interface in dest_intfs_mapping.items():
            path = None
            # use custom path if one is supplied
            # json does not support hashing on tuples so we use nested dicts
            if custom_paths is not None and dst_vnf_name in custom_paths:
                if dst_vnf_interface in custom_paths[dst_vnf_name]:
                    path = custom_paths[dst_vnf_name][dst_vnf_interface]
                    logging.debug("Taking custom path to %s: %s" % (dst_vnf_name, path))
            else:
                if datacenter not in self.floating_links:
                    self.floating_links[datacenter] = \
                        net.addLink(self.floating_switch, datacenter)
                path = \
                self._get_path(self.floating_root.name, dst_vnf_name, self.floating_intf.name, dst_vnf_interface)[0]

            if isinstance(path, dict):
                self.delete_flow_by_cookie(cookie)
                raise Exception(u"Can not find a valid path. Are you specifying the right interfaces?.")

            intf = net[dst_vnf_name].nameToIntf[dst_vnf_interface]
            target_mac = str(intf.MAC())
            target_ip = str(intf.IP())
            dst_sw_outport_nr = dest_vnf_outport_nrs[index]
            current_hop = src_sw
            switch_inport_nr = src_sw_inport_nr
            vlan = net.vlans.pop()

            # iterate all switches on the path
            for i in range(0, len(path)):
                if i < len(path) - 1:
                    next_hop = path[i + 1]
                else:
                    # last switch reached
                    next_hop = dst_vnf_name
                next_node = net.getNodeByName(next_hop)

                # sanity checks
                if next_hop == dst_vnf_name:
                    switch_outport_nr = dst_sw_outport_nr
                    logging.info("end node reached: {0}".format(dst_vnf_name))
                elif not isinstance(next_node, OVSSwitch):
                    logging.info("Next node: {0} is not a switch".format(next_hop))
                    return "Next node: {0} is not a switch".format(next_hop)
                else:
                    # take first link between switches by default
                    index_edge_out = 0
                    switch_outport_nr = net.DCNetwork_graph[current_hop][next_hop][index_edge_out]['src_port_nr']

                # default filters, just overwritten on the first node and last node
                cmd = 'priority=1,in_port=%s,cookie=%s' % (switch_inport_nr, cookie)
                cmd_back = 'priority=1,in_port=%s,cookie=%s' % (switch_outport_nr, cookie)
                if i == 0:  # first node
                    cmd = 'in_port=%s' % src_sw_inport_nr
                    cmd += ',cookie=%s' % cookie
                    cmd += ',table=%s' % cookie
                    cmd += ',ip'
                    cmd += ',ip_dst=%s' % floating_ip
                    cmd += ',reg1=%s' % index
                    cmd += ',actions='
                    # set vlan id
                    cmd += ',push_vlan:0x8100'
                    masked_vlan = vlan | 0x1000
                    cmd += ',set_field:%s->vlan_vid' % masked_vlan
                    cmd += ',set_field:%s->eth_dst' % target_mac
                    cmd += ',set_field:%s->ip_dst' % target_ip
                    cmd += ',output:%s' % switch_outport_nr

                    # last switch for reverse route
                    # remove any vlan tags
                    cmd_back += ',dl_vlan=%s' % vlan
                    cmd_back += ',actions=pop_vlan,output:%s' % switch_inport_nr
                    self.setup_arp_reply_at(current_hop, src_sw_inport_nr, floating_ip, target_mac, cookie=cookie)
                elif next_hop == dst_vnf_name:  # last switch
                    # remove any vlan tags
                    cmd += ',dl_vlan=%s' % vlan
                    cmd += ',actions=pop_vlan,output:%s' % switch_outport_nr
                    # set up arp replys at the port so the dst nodes know the src
                    self.setup_arp_reply_at(current_hop, switch_outport_nr, src_ip, src_mac, cookie=cookie)

                    # reverse route
                    cmd_back = 'in_port=%s' % switch_outport_nr
                    cmd_back += ',cookie=%s' % cookie
                    cmd_back += ',ip'
                    cmd_back += ',actions='
                    cmd_back += 'push_vlan:0x8100'
                    masked_vlan = vlan | 0x1000
                    cmd_back += ',set_field:%s->vlan_vid' % masked_vlan
                    cmd_back += ',set_field:%s->eth_src' % src_mac
                    cmd_back += ',set_field:%s->ip_src' % floating_ip
                    cmd_back += ',output:%s' % switch_inport_nr
                    net.getNodeByName(dst_vnf_name).setHostRoute(src_ip, dst_vnf_interface)
                else:  # middle node
                    # if we have a circle in the path we need to specify this, as openflow will ignore the packet
                    # if we just output it on the same port as it came in
                    if switch_inport_nr == switch_outport_nr:
                        cmd += ',dl_vlan=%s,actions=IN_PORT' % (vlan)
                        cmd_back += ',dl_vlan=%s,actions=IN_PORT' % (vlan)
                    else:
                        cmd += ',dl_vlan=%s,actions=output:%s' % (vlan, switch_outport_nr)
                        cmd_back += ',dl_vlan=%s,actions=output:%s' % (vlan, switch_inport_nr)

                # excecute the command on the target switch
                logging.debug(cmd)
                cmd = "\"%s\"" % cmd
                cmd_back = "\"%s\"" % cmd_back
                net[current_hop].dpctl(main_cmd, cmd)
                net[current_hop].dpctl(main_cmd, cmd_back)

                # set next hop for the next iteration step
                if isinstance(next_node, OVSSwitch):
                    switch_inport_nr = net.DCNetwork_graph[current_hop][next_hop][0]['dst_port_nr']
                    current_hop = next_hop

            # advance to next destination
            index += 1

        # set up the actual load balancing rule as a multipath on the very first switch
        cmd = '"in_port=%s' % src_sw_inport_nr
        cmd += ',cookie=%s' % (cookie)
        cmd += ',ip'
        cmd += ',actions='
        # push 0x01 into the first register
        cmd += 'load:0x1->NXM_NX_REG0[]'
        # load balance modulo n over all dest interfaces
        # TODO: in newer openvswitch implementations this should be changed to symmetric_l3l4+udp
        # to balance any kind of traffic
        cmd += ',multipath(symmetric_l4,1024,modulo_n,%s,0,NXM_NX_REG1[0..12])' % len(dest_intfs_mapping)
        # reuse the cookie as table entry as it will be unique
        cmd += ',resubmit(, %s)"' % cookie

        # actually add the flow
        logging.debug("Switch: %s, CMD: %s" % (src_sw, cmd))
        net[src_sw].dpctl(main_cmd, cmd)

        self.floating_cookies[cookie] = floating_ip

        return cookie, floating_ip

    def setup_arp_reply_at(self, switch, port_nr, target_ip, target_mac, cookie=None):
        """
        Sets up a custom ARP reply at a switch.
        An ARP request coming in on the `port_nr` for `target_ip` will be answered with target IP/MAC.

        :param switch: The switch belonging to the interface
        :type switch: ``str``
        :param port_nr: The port number at the switch that is connected to the interface
        :type port_nr: ``int``
        :param target_ip: The IP for which to set up the ARP reply
        :type target_ip: ``str``
        :param target_mac: The MAC address of the target interface
        :type target_mac: ``str``
        :param cookie: cookie to identify the ARP request, if None a new one will be picked
        :type cookie: ``int`` or ``None``
        :return: cookie
        :rtype: ``int``
        """
        if cookie is None:
            cookie = self.get_cookie()
        main_cmd = "add-flow -OOpenFlow13"

        # first set up ARP requests for the source node, so it will always 'find' a partner
        cmd = '"in_port=%s' % port_nr
        cmd += ',cookie=%s' % cookie
        cmd += ',arp'
        # only answer for target ip arp requests
        cmd += ',arp_tpa=%s' % target_ip
        cmd += ',actions='
        # set message type to ARP reply
        cmd += 'load:0x2->NXM_OF_ARP_OP[]'
        # set src ip as dst ip
        cmd += ',move:NXM_OF_ETH_SRC[]->NXM_OF_ETH_DST[]'
        # set src mac
        cmd += ',set_field:%s->eth_src' % target_mac
        # set src as target
        cmd += ',move:NXM_NX_ARP_SHA[]->NXM_NX_ARP_THA[], move:NXM_OF_ARP_SPA[]->NXM_OF_ARP_TPA[]'
        # set target mac as hex
        cmd += ',load:0x%s->NXM_NX_ARP_SHA[]' % "".join(target_mac.split(':'))
        # set target ip as hex
        octets = target_ip.split('.')
        dst_ip_hex = '{:02X}{:02X}{:02X}{:02X}'.format(*map(int, octets))
        cmd += ',load:0x%s->NXM_OF_ARP_SPA[]' % dst_ip_hex
        # output to incoming port remember the closing "
        cmd += ',IN_PORT"'
        self.net[switch].dpctl(main_cmd, cmd)
        logging.debug(
            "Set up ARP reply at %s port %s." % (switch, port_nr))

    def delete_flow_by_cookie(self, cookie):
        """
        Removes a flow identified by the cookie

        :param cookie: The cookie for the specified flow
        :type cookie: ``int``
        :return: True if successful, else false
        :rtype: ``bool``
        """
        if not cookie:
            return False
        logging.debug("Deleting flow by cookie %d" % (cookie))
        flows = list()
        # we have to call delete-group for each switch
        for node in self.net.switches:
            flow = dict()
            flow["dpid"] = int(node.dpid, 16)
            flow["cookie"] = cookie
            flow['cookie_mask'] = int('0xffffffffffffffff', 16)

            flows.append(flow)
        for flow in flows:
            logging.debug("Deleting flowentry with cookie %d" % (
                flow["cookie"]))
            if self.net.controller == RemoteController:
                self.net.ryu_REST('stats/flowentry/delete', data=flow)

        self.cookies.remove(cookie)
        return True

    def delete_chain_by_intf(self, src_vnf_name, src_vnf_intf, dst_vnf_name, dst_vnf_intf):
        """
        Removes a flow identified by the vnf_name/vnf_intf pairs

        :param src_vnf_name: The vnf name for the specified flow
        :type src_vnf_name: ``str``
        :param src_vnf_intf: The interface name for the specified flow
        :type src_vnf_intf: ``str``
        :param dst_vnf_name: The vnf name for the specified flow
        :type dst_vnf_name: ``str``
        :param dst_vnf_intf: The interface name for the specified flow
        :type dst_vnf_intf: ``str``
        :return: True if successful, else false
        :rtype: ``bool``
        """
        logging.debug("Deleting flow for vnf/intf pair %s %s" % (src_vnf_name, src_vnf_intf))
        if not self.check_vnf_intf_pair(src_vnf_name, src_vnf_intf):
            return False
        if not self.check_vnf_intf_pair(dst_vnf_name, dst_vnf_intf):
            return False
        target_flow = (src_vnf_name, src_vnf_intf, dst_vnf_name, dst_vnf_intf)
        if not target_flow in self.chain_flow_cookies:
            return False

        success = self.delete_flow_by_cookie(self.chain_flow_cookies[target_flow])

        if success:
            del self.chain_flow_cookies[target_flow]
            del self.full_chain_data[target_flow]
            return True
        return False

    def delete_loadbalancer(self, vnf_src_name, vnf_src_interface):
        '''
        Removes a loadbalancer that is configured for the node and interface

        :param src_vnf_name: Name of the source VNF
        :param src_vnf_interface: Name of the destination VNF
        '''
        flows = list()
        # we have to call delete-group for each switch
        delete_group = list()
        group_id = self.get_flow_group(vnf_src_name, vnf_src_interface)
        for node in self.net.switches:
            for cookie in self.lb_flow_cookies[(vnf_src_name, vnf_src_interface)]:
                flow = dict()
                flow["dpid"] = int(node.dpid, 16)
                flow["cookie"] = cookie
                flow['cookie_mask'] = int('0xffffffffffffffff', 16)

                flows.append(flow)
            group_del = dict()
            group_del["dpid"] = int(node.dpid, 16)
            group_del["group_id"] = group_id
            delete_group.append(group_del)

        for flow in flows:
            logging.debug("Deleting flowentry with cookie %d belonging to lb at %s:%s" % (
                flow["cookie"], vnf_src_name, vnf_src_interface))
            if self.net.controller == RemoteController:
                self.net.ryu_REST('stats/flowentry/delete', data=flow)

        logging.debug("Deleting group with id %s" % group_id)
        for switch_del_group in delete_group:
            if self.net.controller == RemoteController:
                self.net.ryu_REST("stats/groupentry/delete", data=switch_del_group)

        # unmap groupid from the interface
        target_pair = (vnf_src_name, vnf_src_interface)
        if target_pair in self.flow_groups:
            del self.flow_groups[target_pair]
        if target_pair in self.full_lb_data:
            del self.full_lb_data[target_pair]

    def delete_floating_lb(self, cookie):
        """
        Delete a floating loadbalancer.
        Floating loadbalancers are different from normal ones as there are multiple ones on the same interface.
        :param cookie: The cookie of the loadbalancer
        :type cookie: ``int``
        """
        cookie = int(cookie)
        if cookie not in self.floating_cookies:
            raise Exception("Can not delete floating loadbalancer as the flowcookie is not known")

        self.delete_flow_by_cookie(cookie)
        floating_ip = self.floating_cookies[cookie]
        self.floating_network.withdraw_ip_address(floating_ip)

    def set_arp_entry(self, vnf_name, vnf_interface, ip, mac):
        """
        Sets an arp entry on the specified VNF. This is done on the node directly and not by open vswitch!
        :param vnf_name: Name of the VNF
        :type vnf_name: ``str``
        :param vnf_interface: Name of the interface
        :type vnf_interface: ``str``
        :param ip: IP to reply to
        :type ip: ``str``
        :param mac: Answer with this MAC
        :type mac: ``str``
        """
        node = self.net.getNodeByName(vnf_name)
        node.cmd("arp -i %s -s %s %s" % (vnf_interface, ip, mac))
def myNet():
   "Defines a custom topology on mininet."

   print "*** Starting MyNet ***"
   cParams = ControllerParams( '10.0.3.0', 24 )
   net = Mininet( controller=RemoteController, switch=OVSKernelSwitch, cparams=cParams )

   print "** Adding controller"
   c = net.addController( 'c0' )

   print "** Adding switches"
   s1 = net.addSwitch( 's1' )
   s2 = net.addSwitch( 's2' )
   s3 = net.addSwitch( 's3' )
   s4 = net.addSwitch( 's4' )

   print "** Adding hosts"
   h5 = net.addHost( 'h5', ip='10.0.3.5' )
   h6 = net.addHost( 'h6', ip='10.0.3.6' )
   h7 = net.addHost( 'h7', ip='10.0.3.7' )
   h8 = net.addHost( 'h8', ip='10.0.3.8' )
   h9 = net.addHost( 'h9', ip='10.0.3.9' )

   print "** Linking switches together"
   s1.linkTo( s2 )
   s2.linkTo( s3 )
   s2.linkTo( s4 )

   print "** Linking hosts to switches"
   h5.linkTo( s1 )
   h6.linkTo( s3 )
   h7.linkTo( s3 )
   h8.linkTo( s4 )
   h9.linkTo( s4 )

   #print "** Setting up IP addresses"
   #h5.setIP( h5.defaultIntf(), '10.0.3.5', 24)

   #extraPort1 = s1.newPort()
   #extraPortName1 = s1.intfName( extraPort1 )
   #print "** Adding extra port to s1 - " + extraPortName1
   #s1.addIntf( extraPortName1, extraPort1 )

   #print "** Linking xeth0 to s1 port " + extraPortName1
   #makeIntfPair( "xeth0", extraPortName1 )

   #extraPort2 = s4.newPort()
   #extraPortName2 = s4.intfName( extraPort2 )
   #print "** Adding extra port to s4 - " + extraPortName2
   #s4.addIntf( extraPortName2, extraPort2 )

   #print "** Linking xeth1 to s4 port " + extraPortName2
   #makeIntfPair( "xeth1", extraPortName2 )

   print "** Creating extra node to enable access to others"
   # Create a node in root namespace and link to switch 0
   root = Node( 'root', inNamespace=False )
   root.linkTo( s1 )
   root.setMAC( root.defaultIntf(), "00:00:00:10:00:64" )
   root.setIP( root.defaultIntf(), "10.0.3.100", 24 )

   #Configure everything
   s1.setMAC ( 's1-eth1', '00:00:00:10:01:01' )
   s1.setMAC ( 's1-eth2', '00:00:00:10:01:02' )
   s1.setMAC ( 's1-eth3', '00:00:00:10:01:03' )
   s2.setMAC ( 's2-eth1', '00:00:00:10:02:01' )
   s2.setMAC ( 's2-eth2', '00:00:00:10:02:02' )
   s2.setMAC ( 's2-eth3', '00:00:00:10:02:03' )
   s3.setMAC ( 's3-eth1', '00:00:00:10:03:01' )
   s3.setMAC ( 's3-eth2', '00:00:00:10:03:02' )
   s3.setMAC ( 's3-eth3', '00:00:00:10:03:03' )
   s4.setMAC ( 's4-eth1', '00:00:00:10:04:01' )
   s4.setMAC ( 's4-eth2', '00:00:00:10:04:02' )
   s4.setMAC ( 's4-eth3', '00:00:00:10:04:03' )
   s1.setIP ( s1.defaultIntf(), '10.0.3.1', 24 )
   s2.setIP ( s2.defaultIntf(), '10.0.3.2', 24 )
   s3.setIP ( s3.defaultIntf(), '10.0.3.3', 24 )
   s4.setIP ( s4.defaultIntf(), '10.0.3.4', 24 )

   h5.setMAC( h5.defaultIntf(), "00:00:00:10:00:05" )
   h6.setMAC( h6.defaultIntf(), "00:00:00:10:00:06" )
   h7.setMAC( h7.defaultIntf(), "00:00:00:10:00:07" )
   h8.setMAC( h8.defaultIntf(), "00:00:00:10:00:08" )
   h9.setMAC( h9.defaultIntf(), "00:00:00:10:00:09" )

   print "** Firing up the network"
   net.build()
   # Try to add eth1 into s1
   #print s1.cmd( 'ovs-dpctl add-if dp0 eth1' )
   c.start()
   s1.start( [ c ] )
   s2.start( [ c ] )
   s3.start( [ c ] )
   s4.start( [ c ] )

   print "** Starting SSH Server in every host"
   sshpids = {}
   for h in net.hosts:
      h.cmd( '/usr/sbin/sshd -D &' )
      time.sleep(2) # Whait for the daemon to come up so we can see its pid (this is not very safe)
      output = h.cmd( 'cat /var/run/sshd.pid' )
      sshpids[h.name] = output.rstrip()

   print "** Starting Libvirt in every host"
   for h in net.hosts:
      ip = h.IP()
      h.cmd( 'ip addr flush ' + h.defaultIntf() )
      h.cmd( 'brctl addbr virbr1' )
      h.cmd( 'brctl addif virbr1 ' + h.defaultIntf() )
      h.cmd( 'ip link set dev virbr1 up' )
      h.setIP( 'virbr1', ip, 24 )
      h.cmd( '/home/juliano/' + h.name + '/sbin/libvirtd -d -l -p /home/juliano/' + h.name + '/var/run/libvirtd.pid -f /home/juliano/' + h.name + '/etc/libvirt/libvirtd.conf' )

   print "** Testing network"
   # net.pingAll()

   print "** Running CLI"
   CLI( net )

   print "** Killing daemons"
   for h in net.hosts:
      h.cmd( 'kill `cat /home/juliano/' + h.name + '/var/run/libvirtd.pid`' )
      if len( sshpids[h.name] ) < 7:
         h.cmd( 'kill ' + sshpids[h.name] )

   print "** Stopping network"
   net.stop()
Exemple #46
0
    net = Mininet(topo=topo)

    s1 = net['s1']

    plc2 = net['plc2']
    plc3 = net['plc3']

    s2, rtu2a, scada = net.get('s2', 'rtu2a', 'scada')
    rtu2b, attacker2 = net.get('rtu2b', 'attacker2')
    s3 = net.get('s3')

    # NOTE: root-eth0 interface on the host
    root = Node('root', inNamespace=False)
    intf = net.addLink(root, s3).intf1
    print('DEBUG root intf: {}'.format(intf))
    root.setIP('10.0.0.30', intf=intf)
    # NOTE: all packet from root to the 10.0.0.0 network
    root.cmd('route add -net ' + '10.0.0.0' + ' dev ' + str(intf))


    net.start()

    # NOTE: use for debugging
    #s1.cmd('tcpdump -i s1-eth1 -w /tmp/s1-eth1.pcap &')
    #s1.cmd('tcpdump -i s1-eth2 -w /tmp/s1-eth2.pcap &')

    SLEEP = 0.5

    # NOTE: swat challenge 1 and 2
    plc3.cmd(sys.executable + ' plc3.py &')
    sleep(SLEEP)
Exemple #47
0
def myNet():
    "Create network from scratch using Open vSwitch."
    info( "*** Creating nodes\n" )
    switch0 = Node( 's0', inNamespace=False )
    switch1 = Node( 's1', inNamespace=False )
    switch2 = Node( 's2', inNamespace=False )
    switch3 = Node( 's3', inNamespace=False )
    switch4 = Node( 's4', inNamespace=False )
    h0 = Node( 'h0' )
    h1 = Node( 'h1' )
 
    info( "*** Creating links\n" )
    linkopts0=dict(bw=100, delay='1ms', loss=0)
    linkopts1=dict(bw=1, delay='100ms', loss=0)
    linkopts2=dict(bw=10, delay='50ms', loss=0)
    linkopts3=dict(bw=100, delay='1ms', loss=0)
    link1=TCLink( h0, switch0, **linkopts0)
    TCLink( switch0, switch1, **linkopts0)
    TCLink( switch0, switch2, **linkopts0)
    TCLink( switch0, switch3, **linkopts0)
    TCLink( switch1, switch4,**linkopts1)
    TCLink( switch2, switch4,**linkopts2)
    TCLink( switch3, switch4,**linkopts3)
    link2=TCLink( h1, switch4, **linkopts0)
 
    info( "*** Configuring hosts\n" )
    h0.setIP( '192.168.123.1/24' )
    h1.setIP( '192.168.123.2/24' )
    info( str( h0 ) + '\n' )
    info( str( h1 ) + '\n' )
       
    info( "*** Starting network using Open vSwitch\n" )
    switch0.cmd( 'ovs-vsctl del-br dp0' )
    switch0.cmd( 'ovs-vsctl add-br dp0' )
    switch1.cmd( 'ovs-vsctl del-br dp1' )
    switch1.cmd( 'ovs-vsctl add-br dp1' )
    switch2.cmd( 'ovs-vsctl del-br dp2' )
    switch2.cmd( 'ovs-vsctl add-br dp2' )
    switch3.cmd( 'ovs-vsctl del-br dp3' )
    switch3.cmd( 'ovs-vsctl add-br dp3' )
    switch4.cmd( 'ovs-vsctl del-br dp4' )
    switch4.cmd( 'ovs-vsctl add-br dp4' )
 
    for intf in switch0.intfs.values():
        print intf
        print switch0.cmd( 'ovs-vsctl add-port dp0 %s' % intf )
 
    for intf in switch1.intfs.values():
        print intf
        print switch1.cmd( 'ovs-vsctl add-port dp1 %s' % intf )
 
    for intf in switch2.intfs.values():
        print intf
        print switch2.cmd( 'ovs-vsctl add-port dp2 %s' % intf )
 
    for intf in switch3.intfs.values():
        print intf
        print switch3.cmd( 'ovs-vsctl add-port dp3 %s' % intf )
 
    for intf in switch4.intfs.values():
        print intf
        print switch4.cmd( 'ovs-vsctl add-port dp4 %s' % intf )
   
    print switch1.cmd(r'ovs-ofctl add-flow dp1 idle_timeout=0,priority=1,in_port=1,actions=flood' )
    print switch1.cmd(r'ovs-ofctl add-flow dp1 idle_timeout=0,priority=1,in_port=1,actions=output:2' ) 
    print switch1.cmd(r'ovs-ofctl add-flow dp1 idle_timeout=0,priority=1,in_port=2,actions=output:1' )
    print switch2.cmd(r'ovs-ofctl add-flow dp2 idle_timeout=0,priority=1,in_port=1,actions=output:2' )
    print switch2.cmd(r'ovs-ofctl add-flow dp2 idle_timeout=0,priority=1,in_port=2,actions=output:1' )
    print switch3.cmd(r'ovs-ofctl add-flow dp3 idle_timeout=0,priority=1,in_port=1,actions=output:2' )    
    print switch3.cmd(r'ovs-ofctl add-flow dp3 idle_timeout=0,priority=1,in_port=2,actions=output:1' )
    print switch4.cmd(r'ovs-ofctl add-flow dp4 idle_timeout=0,priority=1,in_port=1,actions=output:4' )
    print switch4.cmd(r'ovs-ofctl add-flow dp4 idle_timeout=0,priority=1,in_port=2,actions=output:4' )
    print switch4.cmd(r'ovs-ofctl add-flow dp4 idle_timeout=0,priority=1,in_port=3,actions=output:4' )
    print switch4.cmd(r'ovs-ofctl add-flow dp4 idle_timeout=0,priority=1,in_port=4,actions=output:3' )
   
    #print switch0.cmd(r'ovs-ofctl add-flow dp0 idle_timeout=0,priority=10,ip,nw_dst=192.168.123.2,actions=output:4')
    print switch0.cmd(r'ovs-ofctl add-flow dp0 idle_timeout=0,priority=10,ip,nw_dst=192.168.123.2,nw_tos=0x10,actions=output:2') 
    print switch0.cmd(r'ovs-ofctl add-flow dp0 idle_timeout=0,priority=10,ip,nw_dst=192.168.123.2,nw_tos=0x20,actions=output:3')
    print switch0.cmd(r'ovs-ofctl add-flow dp0 idle_timeout=0,priority=10,ip,nw_dst=192.168.123.2,nw_tos=0x30,actions=output:4') 
    #print switch0.cmd(r'ovs-ofctl add-flow dp0 idle_timeout=0,priority=10,ip,nw_dst=192.168.123.1,actions=output:1')
 
    #switch0.cmd('tcpdump -i s0-eth0 -U -w aaa &')
    #h0.cmd('tcpdump -i h0-eth0 -U -w aaa &')
    def cDelay1():
        h1.cmdPrint('ethtool -K h1-eth0 gro off')
        h1.cmdPrint('tc qdisc del dev h1-eth0 root')
        h1.cmdPrint('tc qdisc add dev h1-eth0 root handle 10: netem delay 100ms')
 
    def hello(a, b='4'):
       print a
       print b
 
    #t=Timer(3.0, hello, args=('aaaa',),kwargs={'b':'7'})
    t=Timer(5.0, cDelay1)
    t.start()
 
    info( "*** Running test\n" )
    #h0.cmdPrint( 'ping -Q 0x10 -c 3 ' + h1.IP() )
    #h0.cmdPrint( 'ping -Q 0x20 -c 3 ' + h1.IP() )
    h0.cmdPrint( 'ping -Q 0x30 -c 10 ' + h1.IP() )
    #link2.intf1.config(delay='100ms')
    #h1.cmdPrint('ifconfig -a')
    #h1.cmdPrint('tc qdisc show dev h1-eth0')
    #h1.cmdPrint('ethtook -K h1-eth0 gro off')
    #h1.cmdPrint('tc qdisc del dev h1-eth0 root')
    #h1.cmdPrint('tc qdisc add dev h1-eth0 root handle 10: netem delay 100ms')
    #h1.cmdPrint('ifconfig -a')
    #h1.cmdPrint('tc qdisc show dev h1-eth0')
    #h1.cmdPrint('tc -s qdisc ls dev h1-eth0')
    #h0.cmdPrint( 'ping -Q 0x30 -c 5 ' + h1.IP() )
 
    #print switch0.cmd( 'ovs-ofctl show dp0' )    
    #print switch1.cmd( 'ovs-ofctl show dp1' )
    #print switch2.cmd( 'ovs-ofctl show dp2' )
    #print switch3.cmd( 'ovs-ofctl show dp3' )
    #print switch4.cmd( 'ovs-ofctl show dp4' )  
    #print switch0.cmd( 'ovs-ofctl dump-tables  dp0' )
    #print switch0.cmd( 'ovs-ofctl dump-ports   dp0' )
    #print switch0.cmd( 'ovs-ofctl dump-flows  dp0' )
    #print switch0.cmd( 'ovs-ofctl dump-aggregate  dp0' )
    #print switch0.cmd( 'ovs-ofctl queue-stats dp0' )
 
    #print "Testing video transmission between h1 and h2"
    #h1.cmd('./myrtg_svc -u > myrd &')
    #h0.cmd('./mystg_svc -trace st 192.168.123.2')
 
    info( "*** Stopping network\n" )
    switch0.cmd( 'ovs-vsctl del-br dp0' )
    switch0.deleteIntfs()
    switch1.cmd( 'ovs-vsctl del-br dp1' )
    switch1.deleteIntfs()
    switch2.cmd( 'ovs-vsctl del-br dp2' )
    switch2.deleteIntfs()
    switch3.cmd( 'ovs-vsctl del-br dp3' )
    switch3.deleteIntfs()
    switch4.cmd( 'ovs-vsctl del-br dp4' )
    switch4.deleteIntfs()
    info( '\n' )
Exemple #48
0
def scratchNet(cname='controller', cargs='-v ptcp:'):
    "Create network from scratch using Open vSwitch."

    info("*** Creating nodes\n")
    controller = Node('c0', inNamespace=False)
    switch = Node('s0', inNamespace=False)
    h0 = Node('h0')
    h1 = Node('h1')

    info("*** Creating links\n")
    Link(h0, switch)
    Link(h1, switch)

    info("*** Configuring hosts\n")
    h0.setIP('192.168.123.1/24')
    h1.setIP('192.168.123.2/24')
    info(str(h0) + '\n')
    info(str(h1) + '\n')

    info("*** Starting network using Open vSwitch\n")
    controller.cmd(cname + ' ' + cargs + '&')

    #issue_switch_cmd(switch, 'ovs-vsctl del-br br-ex')
    issue_switch_cmd(switch, 'ovs-vsctl del-br br-int')
    #issue_switch_cmd(switch, 'ovs-vsctl add-br br-ex')
    issue_switch_cmd(switch, 'ovs-vsctl add-br br-int')

    # CONCLUSION
    # ovs-vsctl add-br br-ex
    # ovs-vsctl add-port br-ex {external_nic}
    # ovs-vsctl add-br br-int
    # ovs-vsctl add-port br-int {internal_nic}
    # ovs-vsctl --no-wait set bridge br-int fail-mode=secure other-config:disable-in-band=true
    # ovs-vsctl set bridge br-int protocols=OpenFlow10,OpenFlow13
    # ovs-vsctl set-manager ptcp:6640:0.0.0.0

    for intf in switch.intfs.values():
        print issue_switch_cmd(switch, 'ovs-vsctl add-port br-int %s' % intf)

    # for intf in switch.intfs.values():
    #    print issue_switch_cmd(switch, 'ovs-vsctl add-port br-ex %s' % intf)

    issue_switch_cmd(switch, 'ovs-vsctl --no-wait set bridge br-int fail-mode=secure other-config:disable-in-band=true')
    issue_switch_cmd(switch, 'ovs-vsctl set bridge br-int protocols=OpenFlow10,OpenFlow13')
    #issue_switch_cmd(switch, 'ovs-vsctl set-manager ptcp:6640:0.0.0.0')
    # issue_switch_cmd(switch, 'ovs-ofctl -O OpenFlow13  dump-flows br-int')

    # Note: controller and switch are in root namespace, and we
    # can connect via loopback interface
    s_cmd = 'ovs-vsctl set-controller br-int tcp:{}:{}'.format(CTLR_IP, CTLR_PRT)
    issue_switch_cmd(switch, s_cmd)

    ping_results = ['received,host,jitter,packet_loss,avgping,minping,time,sent,maxping\n']
    try:
        h0.cmd('echo "" > pings.txt')
        if mode == 0:
            step_wise_testing(h0, h1, ping_results)
        else:
            continuous_testing(h0, h1, ping_results)
    except KeyboardInterrupt:
        print "Warning: Caught KeyboardInterrupt, stopping network"
        tm_local = time.localtime()
        dt = time.gmtime()
        file_name = 'pings_{}_{}_{}-{}_{}_{}.csv'.format(dt.tm_year, dt.tm_mon, dt.tm_mday, tm_local.tm_hour,
                                                         tm_local.tm_min, tm_local.tm_sec)
        f = open(file_name, 'w+')
        for item in ping_results:
            f.write(item)
        stop_net(controller, cname, switch)
Exemple #49
0
    info( '*** Creating Network\n' )
    h0 = Node( 'h0' )
    h1 = Node( 'h1' )

    net.hosts.append( h0 )
    net.hosts.append( h1 )

    link = CSMALink( h0, h1, DataRate="10Mbps")

    ns.csma.CsmaHelper().EnablePcap( "h0-trace.pcap", h0.nsNode.GetDevice( 0 ), True, True );
    ns.csma.CsmaHelper().EnablePcap( "h1-trace.pcap", h1.nsNode.GetDevice( 0 ), True, True );

    mininet.ns3.start()

    info( '*** Configuring hosts\n' )
    h0.setIP( '192.168.123.1/24' )
    h1.setIP( '192.168.123.2/24')

    info( 'Testing network connectivity\n' )
    net.pingAll()
    info( 'Testing bandwidth between h0 and h1\n' )
    net.iperf( ( h0, h1 ) )

    mininet.ns3.clear()
    net.stop()

    info( "Run: \"wireshark h0-trace.pcap\" to see packets captured in ns device\n" )