Beispiel #1
0
 def test_stdio(self):
     require_user('root')
     nsid = self.alloc_nsname()
     nsp = NSPopen(nsid, ['ip', 'ad'],
                   flags=os.O_CREAT,
                   stdout=subprocess.PIPE)
     output = nsp.stdout.read()
     nsp.release()
     assert output is not None
Beispiel #2
0
 def execute(self, command):
     # Run a command in the node's namespace
     # Return the command's exit code
     self.message(self.name, "Executing", command)
     nsn = self.get_ns_name()
     pipe = NSPopen(nsn, command)
     result = pipe.wait()
     pipe.release()
     return result
Beispiel #3
0
 def execute(self, command):
     # Run a command in the node's namespace
     # Return the command's exit code
     self.message(self.name, "Executing", command)
     nsn = self.get_ns_name()
     pipe = NSPopen(nsn, command)
     result = pipe.wait()
     pipe.release()
     return result
Beispiel #4
0
 def test_fcntl(self):
     require_user('root')
     nsid = self.alloc_nsname()
     nsp = NSPopen(nsid, ['ip', 'ad'],
                   flags=os.O_CREAT,
                   stdout=subprocess.PIPE)
     flags = nsp.stdout.fcntl(fcntl.F_GETFL)
     nsp.release()
     assert flags == 0
Beispiel #5
0
 def test_stdio(self):
     require_user('root')
     nsid = self.alloc_nsname()
     nsp = NSPopen(nsid, ['ip', 'ad'],
                   flags=os.O_CREAT,
                   stdout=subprocess.PIPE)
     output = nsp.stdout.read()
     nsp.release()
     assert output is not None
Beispiel #6
0
 def test_fcntl(self):
     require_user('root')
     nsid = self.alloc_nsname()
     nsp = NSPopen(nsid, ['ip', 'ad'],
                   flags=os.O_CREAT,
                   stdout=subprocess.PIPE)
     flags = nsp.stdout.fcntl(fcntl.F_GETFL)
     nsp.release()
     assert flags == 0
Beispiel #7
0
    def add_values(self,subnet,VMs):
	x = 0
	for sub in range(5,subnet+5):
   	    for mac in range(2,VMs+2):
		print 'ns_array[%d], ARP address:  192.168.%d.1' % (x,sub)
                cmd1 = ["route", "add", "default", "gw",'192.168.%d.1' % (sub)]
                nsp = NSPopen(self.ns_array[x].id.nl.netns, cmd1)
                nsp.wait(); nsp.release()
                cmd1 = ["arping", "-c", "1", "-I", "eth0", '192.168.%d.1' % (sub),"-q"]
                nsp = NSPopen(self.ns_array[x].id.nl.netns, cmd1)
                nsp.wait(); nsp.release()
		x+=1
Beispiel #8
0
def managed_nspopen(*args, **kwds):
    proc = NSPopen(*args, **kwds)
    try:
        yield proc
    finally:
        if proc.poll() is None:
            # send SIGKILL to the process and wait for it to die if it's still
            # running
            proc.kill()
            proc.communicate()
        # release proxy process resourecs
        proc.release()
Beispiel #9
0
def createEndpoint(name, svcName, endpointtype):
    if endpointtype == 'ns':
        ip_host = IPDB()
        ip_host.create(ifname=name, kind='veth', peer=name + '_' + svcName).commit()
        ip_ns = IPDB(nl=NetNS(name))
        with ip_host.interfaces[name] as veth:
            veth.net_ns_fd = name
            veth.up()
        with ip_host.interfaces[name + '_' + svcName] as veth:
            veth.up()
        subprocess.call(["ovs-vsctl", "add-port", "vs-" + svcName, name + '_' + svcName])
        ip_host.release()
        ip_ns.release()
        nsp = NSPopen(name, ['dhclient', '-lf', '/tmp/' + name + '.lease', name], stdout=subprocess.PIPE)
        nsp.wait()
        nsp.release()
    if endpointtype == 'lxc':
        subprocess.call(['/usr/bin/lxc-clone','template',name])
        lxcUpOvsScript = '#!/bin/bash\n'
        lxcUpOvsScript += 'BRIDGE="vs-'+ svcName + '"\n'
        lxcUpOvsScript += 'ovs-vsctl --if-exists del-port $BRIDGE $5\n'
        lxcUpOvsScript += 'ovs-vsctl add-port $BRIDGE $5\n'
        f = open('/var/lib/lxc/' + name + '/ovsup.sh','w+')
        f.write(lxcUpOvsScript)
        f.close()
        lxcDownOvsScript = '#!/bin/bash\n'
        lxcDownOvsScript += 'BRIDGE="vs-'+ svcName + '"\n'
        lxcDownOvsScript += 'ovs-vsctl --if-exists del-port $BRIDGE $5\n'
        f = open('/var/lib/lxc/' + name + '/ovsdown.sh','w+')
        f.write(lxcDownOvsScript)
        f.close()
        os.chmod('/var/lib/lxc/' + name + '/ovsup.sh',stat.S_IRWXU)
        os.chmod('/var/lib/lxc/' + name + '/ovsdown.sh',stat.S_IRWXU)
        lxcConfig = 'lxc.include = /usr/share/lxc/config/ubuntu.common.conf\n'
        lxcConfig += 'lxc.arch = x86_64\n' 
        lxcConfig += 'lxc.rootfs = /var/lib/lxc/' + name + '/rootfs\n'
        lxcConfig += 'lxc.utsname = ' + name + '\n'
        lxcConfig += 'lxc.network.type = veth\n'
        lxcConfig += 'lxc.network.veth.pair = ' + name + '\n'
        lxcConfig += 'lxc.network.script.up = /var/lib/lxc/' + name + '/ovsup.sh\n'
        lxcConfig += 'lxc.network.script.down = /var/lib/lxc/' + name + '/ovsdown.sh\n'
        lxcConfig += 'lxc.network.flags = up\n'
        f = open('/var/lib/lxc/' + name + '/config','w+')
        f.write(lxcConfig)
        f.close()
        subprocess.call(['/usr/bin/lxc-start','-d','-n',name])
        pass
    return json.dumps({ 'status' : 'created endpoint'})
Beispiel #10
0
def execute(graph, dry_run=False, instance_id=None):
    """
    Fire up whatever's in each node's ``command`` attribute.

    Note: The returned graph contains handles for the commands specified inside

    :param networkx.Graph graph: The graph to run the scripts for
    :param bool dry_run: If set makes Meshinery not touch any namespaces
    :param str instance_id: If set changes the middle section of each
    namespace's name; current PID by default
    :return networkx.Graph: The same graph but with script runtime annotations
    """

    if instance_id is None:
        instance_id = os.getpid()

    for node_name in graph.nodes:
        node = graph.nodes[node_name]

        if node.get('command') is None:
            logging.info('"command" not defined for node {}'.format(node_name))
            continue

        # Turn node attributes into a JSON for the command
        attribs = dict(node)
        attribs['node_name'] = node_name
        attribs['neighs'] = dict(graph[node_name])

        attrib_string = json.dumps(attribs) + '\n'

        # TODO:
        # * Provide every per-node command with complete optimum paths to other
        # nodes relevant to all metric attributes

        logging.info('{}: running "{}"'.format(node_name, node['command']))

        command_line = shlex.split(node['command'])

        # Start the command in the node's namespace netns
        try:
            node['command_handle'] = NSPopen(node['netns'],
                                             command_line,
                                             stdin=subprocess.PIPE,
                                             stdout=subprocess.PIPE,
                                             stderr=subprocess.PIPE)
        except Exception as e:
            logging.debug(
                'Exception "{}" was thrown while running "{}"'.format(
                    e, node['command']))
            if type(e) is FileNotFoundError:
                logging.error('Executable "{}" does not exist!'.format(
                    command_line[0]))
                logging.debug('PATH="{}"'.format(os.environ['PATH']))
            raise e

        node['command_handle'].stdin.write(
            bytes(attrib_string, encoding='utf-8'))
        node['command_handle'].stdin.flush()

    return graph
Beispiel #11
0
def deleteEndpoint(name, svcName, endpointtype):
    if endpointtype == 'ns':
        nsp = NSPopen(name, ['dhclient', '-r', name], stdout=subprocess.PIPE)
        nsp.wait()
        nsp.release()
        netns.remove(name)
        ip_host = IPDB()
        if name + '_' + svcName in ip_host.interfaces:
            with ip_host.interfaces[name + '_' + svcName] as veth:
                veth.remove()
        subprocess.call(["ovs-vsctl", "del-port", "vs-" + svcName, name + '_' + svcName])
    if endpointtype == 'lxc':
        subprocess.call(['/usr/bin/lxc-stop','-n',name])
        subprocess.call(['/usr/bin/lxc-destroy','-n',name])
        pass
    return json.dumps({ 'status' : 'deleted endpoint'})
Beispiel #12
0
 def run_unmanaged(self, command, user=os.getenv("USER")):
     """
     Executes a command under the given user from this virtual node. Returns
     an NSPopen object to control the process. NSOpen has the same API as
     subprocess.Popen. This NSPopen object needs to be manually release. In
     general you should prefer using run, where this is done automatically
     by the context manager.
     """
     sudo_command = [
         "sudo",
         "-E",
         "-u",
         user,
         "env",
         "PATH=" + os.getenv("PATH"),
     ] + command
     return NSPopen(
         self.namespace,
         sudo_command,
         stdin=subprocess.PIPE,
         stdout=subprocess.PIPE,
         stderr=subprocess.PIPE,
         universal_newlines=True,
         start_new_session=True,
     )
Beispiel #13
0
 def test_basic(self):
     require_user('root')
     nsid = self.alloc_nsname()
     # create NS and run a child
     nsp = NSPopen(nsid,
                   ['ip', '-o', 'link'],
                   stdout=subprocess.PIPE,
                   flags=os.O_CREAT)
     ret = nsp.communicate()[0].decode('utf-8')
     host_links = [x.get_attr('IFLA_IFNAME') for x in self.ip.get_links()]
     netns_links = [x.split(':')[1].split('@')[0].strip()
                    for x in ret.split('\n') if len(x)]
     assert nsp.wait() == nsp.returncode == 0
     assert set(host_links) & set(netns_links) == set(netns_links)
     assert set(netns_links) < set(host_links)
     assert not set(netns_links) > set(host_links)
     nsp.release()
Beispiel #14
0
def managed_nspopen(*args, **kwds):
    proc = NSPopen(*args, **kwds)
    try:
        yield proc
    finally:
        if proc.poll() is None:
            # send SIGKILL to the process and wait for it to die if it's still
            # running
            proc.kill()
            # If it's not dead after 2 seconds we throw an error
            proc.communicate(timeout=2)

        # release proxy process resourecs
        proc.release()
Beispiel #15
0
 def test_release(self):
     require_user('root')
     nsid = self.alloc_nsname()
     nsp = NSPopen(nsid, ['true'], flags=os.O_CREAT, stdout=subprocess.PIPE)
     nsp.communicate()
     nsp.wait()
     nsp.release()
     try:
         print(nsp.returncode)
     except RuntimeError:
         pass
 def run(self, command, user=os.getenv("USER")):
     """
     Executes a command under the given user from this virtual node. Returns
     an NSOpen object to control the process. NSOpen has the same API as
     subprocess.POpen.
     """
     sudo_command = ['sudo', '-E', '-u', user, 'env', 'PATH=' + os.getenv("PATH")] + command
     return NSPopen(self.namespace, sudo_command, stdin=subprocess.PIPE,
                    stdout=subprocess.PIPE, stderr=subprocess.PIPE,
                    universal_newlines=True, start_new_session=True)
Beispiel #17
0
 def _ns_add_ifc(self, name, ns_ifc, ifc_base_name=None, in_ifc=None,
                 out_ifc=None, ipaddr=None, macaddr=None, fn=None, cmd=None,
                 action="ok", disable_ipv6=False):
     if name in self.ipdbs:
         ns_ipdb = self.ipdbs[name]
     else:
         ns_ipdb = IPDB(nl=NetNS(name))
         if disable_ipv6:
             cmd = ["sysctl", "-q", "-w",
                    "net.ipv6.conf.default.disable_ipv6=1"]
             nsp = NSPopen(ns_ipdb.nl.netns, cmd)
             nsp.wait(); nsp.release()
         ns_ipdb.interfaces.lo.up().commit()
     if in_ifc:
         in_ifname = in_ifc.ifname
     else:
         out_ifc = self.ipdb.create(ifname="%sa" % ifc_base_name, kind="veth",
                                    peer="%sb" % ifc_base_name).commit()
         in_ifc = self.ipdb.interfaces[out_ifc.peer]
         in_ifname = in_ifc.ifname
     with in_ifc as v:
         # move half of veth into namespace
         v.net_ns_fd = ns_ipdb.nl.netns
     in_ifc = ns_ipdb.interfaces[in_ifname]
     if out_ifc: out_ifc.up().commit()
     ns_ipdb.interfaces.lo.up().commit()
     with in_ifc as v:
         v.ifname = ns_ifc
         if ipaddr: v.add_ip("%s" % ipaddr)
         if macaddr: v.address = macaddr
         v.up()
     if disable_ipv6:
         cmd = ["sysctl", "-q", "-w",
                "net.ipv6.conf.%s.disable_ipv6=1" % out_ifc.ifname]
         subprocess.call(cmd)
     if fn and out_ifc:
         self.ipdb.nl.tc("add", "ingress", out_ifc["index"], "ffff:")
         self.ipdb.nl.tc("add-filter", "bpf", out_ifc["index"], ":1",
                         fd=fn.fd, name=fn.name, parent="ffff:",
                         action=action, classid=1)
     if cmd:
         self.processes.append(NSPopen(ns_ipdb.nl.netns, cmd))
     return (ns_ipdb, out_ifc, in_ifc)
Beispiel #18
0
    def start(self):
        # each entry is tuple of ns_ipdb, out_ifc, in_ifc
        host_info = []
        for i in range(0, num_hosts):
            print("Launching host %i of %i" % (i + 1, num_hosts))
            ipaddr = "172.16.1.%d/24" % (100 + i)
            host_info.append(self._create_ns("host%d" % i, ipaddr=ipaddr))
        with self.ipdb.create(ifname="br100", kind="bridge") as br100:
            for host in host_info:
                br100.add_port(host[1])
            br100.up()
        # create a vxlan device inside each namespace
        for host in host_info:
            print("Starting tunnel %i of %i" %
                  (len(self.processes) + 1, num_hosts))
            cmd = ["netserver", "-D"]
            self.processes.append(NSPopen(host[0].nl.netns, cmd, stdout=null))
            for i in range(0, num_vnis):
                with host[0].create(ifname="vxlan%d" % i,
                                    kind="vxlan",
                                    vxlan_id=10000 + i,
                                    vxlan_link=host[0].interfaces.eth0,
                                    vxlan_port=4789,
                                    vxlan_group="239.1.1.%d" % (1 + i)) as vx:
                    vx.up()
                with host[0].create(ifname="br%d" % i, kind="bridge") as br:
                    br.add_port(host[0].interfaces["vxlan%d" % i])
                    br.up()
                    with host[0].create(ifname="c%da" % i,
                                        kind="veth",
                                        peer="c%db" % i) as c:
                        c.up()
                        c.add_ip("%s/24" % self.available_ips[i].pop(0))
                        c.mtu = 1450
                    br.add_port(host[0].interfaces["c%db" % i])
                    host[0].interfaces["c%db" % i].up().commit()

        # pick one host to start the monitor in
        host = host_info[0]
        cmd = ["python", "monitor.py"]
        p = NSPopen(host[0].nl.netns, cmd)
        self.processes.append(p)
Beispiel #19
0
    def start(self):
        # each entry is tuple of ns_ipdb, out_ifc, in_ifc
        host_info = []
        for i in range(0, num_hosts):
            print("Launching host %i of %i" % (i + 1, num_hosts))
            ipaddr = "172.16.1.%d/24" % (100 + i)
            host_info.append(
                self._create_ns("host%d" % i, ipaddr=ipaddr,
                                disable_ipv6=True))
            if multicast:
                cmd = ["python", "tunnel.py", str(i)]
            else:
                cmd = [
                    "python", "tunnel_mesh.py",
                    str(num_hosts),
                    str(i),
                    str(dhcp),
                    str(gretap)
                ]
            p = NSPopen(host_info[i][0].nl.netns, cmd, stdin=PIPE)
            self.processes.append(p)
        with self.ipdb.create(ifname="br-fabric", kind="bridge") as br:
            for host in host_info:
                br.add_port(host[1])
            br.up()

        # get host0 bridge ip's
        host0_br_ips = []
        if dhcp == 1:
            print("Waiting for host0 br1/br2 ip addresses available")
            for j in range(0, 2):
                interface = host_info[0][0].interfaces["br%d" % j]
                interface.wait_ip("99.1.0.0", 16, timeout=60)
                host0_br_ips = [
                    x[0] for x in interface.ipaddr if x[0].startswith("99.1")
                ]
        else:
            host0_br_ips.append("99.1.0.1")
            host0_br_ips.append("99.1.1.1")

        # traffic test
        print("Validating connectivity")
        for i in range(1, num_hosts):
            for j in range(0, 2):
                interface = host_info[i][0].interfaces["br%d" % j]
                interface.wait_ip("99.1.0.0", 16, timeout=60)
                print("VNI%d between host0 and host%d" % (10000 + j, i))
                call([
                    "ip", "netns", "exec",
                    "host%d" % i, "ping", host0_br_ips[j], "-c", "3", "-i",
                    "0.2", "-q"
                ])
Beispiel #20
0
 def test_release(self):
     require_user('root')
     nsid = self.alloc_nsname()
     nsp = NSPopen(nsid, ['true'], flags=os.O_CREAT, stdout=subprocess.PIPE)
     nsp.communicate()
     nsp.wait()
     nsp.release()
     try:
         print(nsp.returncode)
     except RuntimeError:
         pass
Beispiel #21
0
 def test_api_object(self):
     require_user('root')
     nsid = self.alloc_nsname()
     nsp = NSPopen(nsid, ['true'], flags=os.O_CREAT, stdout=subprocess.PIPE)
     smp = subprocess.Popen(['true'], stdout=subprocess.PIPE)
     nsp.communicate()
     smp.communicate()
     api_nspopen = set(dir(nsp))
     api_popen = set(dir(smp))
     minimal = set(('communicate', 'kill', 'wait'))
     assert minimal & (api_nspopen & api_popen) == minimal
     smp.wait()
     nsp.wait()
     assert nsp.returncode == smp.returncode == 0
     nsp.release()
Beispiel #22
0
 def test_api_object(self):
     require_user('root')
     nsid = self.alloc_nsname()
     nsp = NSPopen(nsid, ['true'], flags=os.O_CREAT, stdout=subprocess.PIPE)
     smp = subprocess.Popen(['true'], stdout=subprocess.PIPE)
     nsp.communicate()
     smp.communicate()
     api_nspopen = set(dir(nsp))
     api_popen = set(dir(smp))
     minimal = set(('communicate', 'kill', 'wait'))
     assert minimal & (api_nspopen & api_popen) == minimal
     smp.wait()
     nsp.wait()
     assert nsp.returncode == smp.returncode == 0
     nsp.release()
Beispiel #23
0
def createEndpoint(name, svcName, endpointtype):
    if endpointtype == 'ns':
        ip_host = IPDB()
        ip_host.create(ifname=name, kind='veth',
                       peer=name + '_' + svcName).commit()
        ip_ns = IPDB(nl=NetNS(name))
        with ip_host.interfaces[name] as veth:
            veth.net_ns_fd = name
            veth.up()
        with ip_host.interfaces[name + '_' + svcName] as veth:
            veth.up()
        subprocess.call(
            ["ovs-vsctl", "add-port", "vs-" + svcName, name + '_' + svcName])
        ip_host.release()
        ip_ns.release()
        nsp = NSPopen(name,
                      ['dhclient', '-lf', '/tmp/' + name + '.lease', name],
                      stdout=subprocess.PIPE)
        nsp.wait()
        nsp.release()
    if endpointtype == 'lxc':
        subprocess.call(['/usr/bin/lxc-clone', 'template', name])
        lxcUpOvsScript = '#!/bin/bash\n'
        lxcUpOvsScript += 'BRIDGE="vs-' + svcName + '"\n'
        lxcUpOvsScript += 'ovs-vsctl --if-exists del-port $BRIDGE $5\n'
        lxcUpOvsScript += 'ovs-vsctl add-port $BRIDGE $5\n'
        f = open('/var/lib/lxc/' + name + '/ovsup.sh', 'w+')
        f.write(lxcUpOvsScript)
        f.close()
        lxcDownOvsScript = '#!/bin/bash\n'
        lxcDownOvsScript += 'BRIDGE="vs-' + svcName + '"\n'
        lxcDownOvsScript += 'ovs-vsctl --if-exists del-port $BRIDGE $5\n'
        f = open('/var/lib/lxc/' + name + '/ovsdown.sh', 'w+')
        f.write(lxcDownOvsScript)
        f.close()
        os.chmod('/var/lib/lxc/' + name + '/ovsup.sh', stat.S_IRWXU)
        os.chmod('/var/lib/lxc/' + name + '/ovsdown.sh', stat.S_IRWXU)
        lxcConfig = 'lxc.include = /usr/share/lxc/config/ubuntu.common.conf\n'
        lxcConfig += 'lxc.arch = x86_64\n'
        lxcConfig += 'lxc.rootfs = /var/lib/lxc/' + name + '/rootfs\n'
        lxcConfig += 'lxc.utsname = ' + name + '\n'
        lxcConfig += 'lxc.network.type = veth\n'
        lxcConfig += 'lxc.network.veth.pair = ' + name + '\n'
        lxcConfig += 'lxc.network.script.up = /var/lib/lxc/' + name + '/ovsup.sh\n'
        lxcConfig += 'lxc.network.script.down = /var/lib/lxc/' + name + '/ovsdown.sh\n'
        lxcConfig += 'lxc.network.flags = up\n'
        f = open('/var/lib/lxc/' + name + '/config', 'w+')
        f.write(lxcConfig)
        f.close()
        subprocess.call(['/usr/bin/lxc-start', '-d', '-n', name])
        pass
    return json.dumps({'status': 'created endpoint'})
Beispiel #24
0
def deleteEndpoint(name, svcName, endpointtype):
    if endpointtype == 'ns':
        nsp = NSPopen(name, ['dhclient', '-r', name], stdout=subprocess.PIPE)
        nsp.wait()
        nsp.release()
        netns.remove(name)
        ip_host = IPDB()
        if name + '_' + svcName in ip_host.interfaces:
            with ip_host.interfaces[name + '_' + svcName] as veth:
                veth.remove()
        subprocess.call(
            ["ovs-vsctl", "del-port", "vs-" + svcName, name + '_' + svcName])
    if endpointtype == 'lxc':
        subprocess.call(['/usr/bin/lxc-stop', '-n', name])
        subprocess.call(['/usr/bin/lxc-destroy', '-n', name])
        pass
    return json.dumps({'status': 'deleted endpoint'})
Beispiel #25
0
 def test_basic(self):
     require_user('root')
     nsid = self.alloc_nsname()
     # create NS and run a child
     nsp = NSPopen(nsid,
                   ['ip', '-o', 'link'],
                   stdout=subprocess.PIPE,
                   flags=os.O_CREAT)
     ret = nsp.communicate()[0].decode('utf-8')
     host_links = [x.get_attr('IFLA_IFNAME') for x in self.ip.get_links()]
     netns_links = [x.split(':')[1].split('@')[0].strip()
                    for x in ret.split('\n') if len(x)]
     assert nsp.wait() == nsp.returncode == 0
     assert set(host_links) & set(netns_links) == set(netns_links)
     assert set(netns_links) < set(host_links)
     assert not set(netns_links) > set(host_links)
     nsp.release()
Beispiel #26
0
    def test_topology(self):
            nsp = NSPopen(self.ns_array[0].id.nl.netns, ["ping", "192.168.6.2", "-c", "2"]); nsp.wait(); nsp.release()
            # one arp request/reply, 2 icmp request/reply per VM, total 6 packets per VM, 12 packets total
            nsp_server = NSPopen(self.ns_array[2].id.nl.netns, ["iperf", "-s", "-xSC"])
            sleep(1)
            nsp = NSPopen(self.ns_array[0].id.nl.netns, ["iperf", "-c", "192.168.6.2", "-t", "1", "-xSC"])
            nsp.wait(); nsp.release()
            nsp_server.kill(); nsp_server.wait(); nsp_server.release()

            nsp_server = NSPopen(self.ns_array[2].id.nl.netns, ["netserver", "-D"])
            sleep(1)
            nsp = NSPopen(self.ns_array[0].id.nl.netns, ["netperf", "-l", "1", "-H", "192.168.6.2", "--", "-m", "65160"])
            nsp.wait(); nsp.release()
            nsp = NSPopen(self.ns_array[0].id.nl.netns, ["netperf", "-l", "1", "-H", "192.168.6.2", "-t", "TCP_RR"])
            nsp.wait(); nsp.release()
            nsp_server.kill(); nsp_server.wait(); nsp_server.release()
    def start(self):
        # Ingress = attached to tc ingress class on bridge
        # Egress = attached to tc engress class on namespace (outside) interface
        # Loading bpf functions/maps.
        brb_code = BPF(src_file="brb_topology_with_patch_pannel.c")
        pvm_fn = brb_code.load_func("pvm_function_p2v", BPF.SCHED_CLS)
        patchpanel_fn  = brb_code.load_func("patch_panel_function", BPF.SCHED_CLS)
        broadcaster_fn = brb_code.load_func("broadcaster", BPF.SCHED_CLS)
        br1_fn = brb_code.load_func("br1_function", BPF.SCHED_CLS)
        print("loading router code")
        rt_fn = brb_code.load_func("router_function", BPF.SCHED_CLS)
        br2_fn = brb_code.load_func("br2_function", BPF.SCHED_CLS)

        vnf_prog   = brb_code.get_table("vnf_prog")
        pvm_ifc2vi = brb_code.get_table("pvm_ifc2vi")
        forward_vi = brb_code.get_table("forwarder_vi")

        mac2host_br1 = brb_code.get_table("mac2host_br1")
        conf_br1 = brb_code.get_table("conf_br1")
        mac2host_br2 = brb_code.get_table("mac2host_br2")
        conf_br2 = brb_code.get_table("conf_br2")
        router_host = brb_code.get_table("router_host")
        #arp_table = brb_code.get_table("arp_table")


        vnf_prog[c_int(0)] = c_int(patchpanel_fn.fd)
        vnf_prog[c_int(1)] = c_int(pvm_fn.fd)
        vnf_prog[c_int(2)] = c_int(br1_fn.fd)
        vnf_prog[c_int(3)] = c_int(rt_fn.fd)
        vnf_prog[c_int(4)] = c_int(br2_fn.fd)
        #Need to add pem into this list.

        # Setup namespace and their interfaces for demostration of br1.
        host_info_br1 = []
        for i in range(0, num_hosts):
            print("Launching host %i of %i in br1" % (i + 1, num_hosts))
            ipaddr = "172.16.1.%d/24" % (100 + i)
            host_info_br1.append(self._create_ns("host%d" % i, ipaddr=ipaddr,
                disable_ipv6=True))

        # Setup namespace and their interfaces for demostration of br2.
        host_info_br2 = []
        for i in range(0, num_hosts):
            print("Launching host %i of %i in br2" % (i + 1, num_hosts))
            ipaddr = "192.168.1.%d/24" % (100 + i)
            host_info_br2.append(self._create_ns("host%d" % (i+4), ipaddr=ipaddr,
                disable_ipv6=True))

        # creating broadcaster, to help broadcast the unknown packets from bridge
        print("creating broadcaster interface")
        broadcaster = ipdb.create(ifname="bc", kind="dummy").up().commit()
        ipr.tc("add", "ingress", broadcaster.index, "ffff:")
        ipr.tc("add-filter", "bpf", broadcaster.index, ":1", fd=broadcaster_fn.fd,
           name=broadcaster_fn.name, parent="ffff:", action="drop", classid=1)
        print("adding it into bridges")
        conf_br1[c_uint(0)] = conf_br1.Leaf(c_uint(broadcaster.index))
        conf_br2[c_uint(0)] = conf_br2.Leaf(c_uint(broadcaster.index))

        print("attaching router between the bridges br1 and br2")
        conf_br1[c_uint(1)] = conf_br1.Leaf(c_uint(2000))
        conf_br2[c_uint(1)] = conf_br2.Leaf(c_uint(4000))

        forward_vi[c_int(2000)] = forward_vi.Leaf(1, c_uint(5000), c_uint(3) , 0)
        forward_vi[c_int(5000)] = forward_vi.Leaf(1, c_uint(2000), c_uint(2) , 0)

        forward_vi[c_int(4000)] = forward_vi.Leaf(1, c_uint(5001), c_uint(3) , 0)
        forward_vi[c_int(5001)] = forward_vi.Leaf(1, c_uint(4000), c_uint(4) , 0)

        #now tell router about it's interfaces
        router_host[c_int(5000)] = router_host.Leaf(self.ip2bin("172.16.1.1"), self.mac2bin("0d:b5:2f:b4:0b:1f"),0,0,0)
        router_host[c_int(5001)] = router_host.Leaf(self.ip2bin("192.168.1.1"), self.mac2bin("64:65:9c:b4:85:2d"),0,0,0)

        print("creating virutal topology for br1")
        # For each namespace that want to connect to the ebpf bridge
        index = 1
        for host in host_info_br1:
            ipr.tc("add", "ingress", host[1].index, "ffff:")
            ipr.tc("add-filter", "bpf", host[1].index, ":1", fd=pvm_fn.fd,
                   name=pvm_fn.name, parent="ffff:", action="drop", classid=1)
            # Passing namespace interface info to dataplane module.
            pvm_ifc2vi[c_uint(host[1].index)] = c_uint(index+1000)
            forward_vi[c_int(index+1000)] = forward_vi.Leaf(1, c_uint(index+2000), c_uint(2) , 0)
            forward_vi[c_int(index+2000)] = forward_vi.Leaf(0, c_uint(host[1].index), 0 , 0)
            conf_br1[c_uint(index+1)]= conf_br1.Leaf(c_uint(index+2000))
            cmd1 = ["route", "add", "default", "gw","172.16.1.1"]
            nsp = NSPopen(host[0].nl.netns, cmd1)
            nsp.wait(); nsp.release()
            cmd1 = ["arping", "-c", "1", "172.16.1.1","-q"]
            nsp = NSPopen(host[0].nl.netns, cmd1)
            nsp.wait(); nsp.release()
            index = index+1

        print("creating virtual topology for br2")
        # For each namespace that want to connect to the ebpf bridge
        index = 1
        for host in host_info_br2:
            ipr.tc("add", "ingress", host[1].index, "ffff:")
            ipr.tc("add-filter", "bpf", host[1].index, ":1", fd=pvm_fn.fd,
                   name=pvm_fn.name, parent="ffff:", action="drop", classid=1)
            # Passing namespace interface info to dataplane module.
            pvm_ifc2vi[c_uint(host[1].index)] = c_uint(index+3000)
            forward_vi[c_int(index+3000)] = forward_vi.Leaf(1, c_uint(index+4000), c_uint(4) , 0)
            forward_vi[c_int(index+4000)] = forward_vi.Leaf(0, c_uint(host[1].index), 0 , 0)
            conf_br2[c_uint(index+1)]= conf_br2.Leaf(c_uint(index+4000))
            index = index+1
            cmd1 = ["route", "add", "default", "gw","192.168.1.1"]
            nsp = NSPopen(host[0].nl.netns, cmd1)
            nsp.wait(); nsp.release()
            cmd1 = ["arping", "-c", "1", "192.168.1.1","-q"]
            nsp = NSPopen(host[0].nl.netns, cmd1)
            nsp.wait(); nsp.release()
            index = index+1
Beispiel #28
0
def createService(data):
    print data
    name = data['name']
    svcId = data['Id']
    svcIdString = str(data['Id'])
    ip = data['dhcpip']
    network = data['subnet']
    customer = data['customer']
    routetarget = data['routetarget']
    terminal = data['terminal']
    vr = data['virtualrouter']
    if 'move' in data:
        move = data['move']
        oldvr = data['oldvr']
        oldId = data['oldId']
    else:
        move = False
    if 'add' in data:
        add = data['add']
    else:
        add = False
    print name
    if_svc_name = name + '_' + svcIdString
    if_svc_peer_name = name + '_' + svcIdString + '_v'
    ip_ns = IPDB(nl=NetNS(name + '_' + svcIdString))
    ip_host = IPDB()
    ip_host.create(ifname=if_svc_name, kind='veth', peer=if_svc_peer_name).commit()
    subprocess.call(["ovs-vsctl", "add-port", "br0", if_svc_name])
    subprocess.call(["ovs-vsctl", "set", "port", if_svc_name, "tag=" + str(svcId)])
    netmask = network.split('/')[1]
    ip = ip + '/' + netmask
    createDhcpConfig(name, network, vr, customer, svcIdString)
    with ip_host.interfaces[if_svc_name] as veth:
        veth.up()
    with ip_host.interfaces[if_svc_peer_name] as veth:
        veth.net_ns_fd = name + '_' + svcIdString
    with ip_ns.interfaces[if_svc_peer_name] as veth:
        veth.address = 'de:ad:be:ef:ba:be'
        veth.add_ip(ip)
        veth.up()
    ip_host.release()
    ip_ns.release()
    nsp = NSPopen(name + '_' + svcIdString, ['dnsmasq', '-C', '/etc/dnsmasq.d/' + name + '.conf'], stdout=subprocess.PIPE)
    nsp.wait()
    nsp.release()
    if not move or add:
        try:
            vn = createVirtualNetwork(customer, name, network, routetarget)
        except:
            print 'failed to create VN'
    phInt = getPhysicalInterface(vr, serviceInterface)
    lif = createLogicalInterface(phInt, name + '_' + svcIdString, str(svcId))
    if move:
        oldlif = getLogicalInterface(oldvr, name + '_' + str(oldId))
        if oldlif.get_virtual_machine_interface_refs():
            for vmInt in oldlif.get_virtual_machine_interface_refs():
                vmIntObj = vnc_client.virtual_machine_interface_read(id = vmInt['uuid'])
                '''
                if vmIntObj.get_instance_ip_back_refs():
                    for instIp in vmIntObj.get_instance_ip_back_refs():
                        instIpObj = vnc_client.instance_ip_read(id = instIp['uuid'])
                        epIp = instIpObj.get_instance_ip_address()
                epMac = vmIntObj.get_virtual_machine_interface_mac_addresses().get_mac_address()[0]
                vn = getVirtualNetwork(customer, name)
                vmInterface = createVirtualMachineInterface(customer, name, epMac)
                createInstanceIp(epIp, vmInterface, vn)
                lif.add_virtual_machine_interface(vmInterface)
                '''
                oldlif.del_virtual_machine_interface(vmIntObj)
                lif.add_virtual_machine_interface(vmIntObj)
                vnc_client.logical_interface_update(oldlif)
                vnc_client.logical_interface_update(lif)
        '''
        if os.path.isfile('/mnt/' + name + '.lease'):
            f = open('/mnt/' + name + '.lease', 'r')
            leases = f.readlines()
            f.close()
            for lease in leases:
                epMac = lease.split(' ')[1]
                epIp = lease.split(' ')[2]
                vn = getVirtualNetwork(customer, name)
                vmInterface = createVirtualMachineInterface(customer, name, epMac)
                createInstanceIp(epIp, vmInterface, vn)
                lif.add_virtual_machine_interface(vmInterface)
                vnc_client.logical_interface_update(lif)
        '''
    return json.dumps({ 'status' : 'created service'})
 def execCmd(self, cmd):
     cmdList = cmd.split()
     nsp = NSPopen(self.nSname, cmdList, stdout=subprocess.PIPE)
     nsp.wait()
     nsp.release()
Beispiel #30
0
    def test_brb(self):
        try:
            b = BPF(src_file=arg1, debug=0)
            self.pem_fn = b.load_func("pem", BPF.SCHED_CLS)
            self.br1_fn = b.load_func("br1", BPF.SCHED_CLS)
            self.br2_fn = b.load_func("br2", BPF.SCHED_CLS)
            self.get_table(b)

            # set up the topology
            self.set_default_const()
            (ns1_ipdb, self.ns1_eth_out,
             _) = sim._create_ns(self.ns1,
                                 ipaddr=self.vm1_ip + '/24',
                                 fn=self.pem_fn,
                                 action='drop',
                                 disable_ipv6=True)
            (ns2_ipdb, self.ns2_eth_out,
             _) = sim._create_ns(self.ns2,
                                 ipaddr=self.vm2_ip + '/24',
                                 fn=self.pem_fn,
                                 action='drop',
                                 disable_ipv6=True)
            ns1_ipdb.routes.add({
                'dst': self.vm2_rtr_mask,
                'gateway': self.vm1_rtr_ip
            }).commit()
            ns2_ipdb.routes.add({
                'dst': self.vm1_rtr_mask,
                'gateway': self.vm2_rtr_ip
            }).commit()
            self.vm1_mac = ns1_ipdb.interfaces['eth0'].address
            self.vm2_mac = ns2_ipdb.interfaces['eth0'].address

            (_, self.nsrtr_eth0_out,
             _) = sim._create_ns(self.ns_router,
                                 ipaddr=self.vm1_rtr_ip + '/24',
                                 fn=self.br1_fn,
                                 action='drop',
                                 disable_ipv6=True)
            (rt_ipdb, self.nsrtr_eth1_out,
             _) = sim._ns_add_ifc(self.ns_router,
                                  "eth1",
                                  "ns_router2",
                                  ipaddr=self.vm2_rtr_ip + '/24',
                                  fn=self.br2_fn,
                                  action='drop',
                                  disable_ipv6=True)
            nsp = NSPopen(rt_ipdb.nl.netns,
                          ["sysctl", "-w", "net.ipv4.ip_forward=1"])
            nsp.wait()
            nsp.release()

            # configure maps
            self.config_maps()

            # our bridge is not smart enough, so send arping for router learning to prevent router
            # from sending out arp request
            nsp = NSPopen(ns1_ipdb.nl.netns, [
                "arping", "-w", "1", "-c", "1", "-I", "eth0", self.vm1_rtr_ip
            ])
            nsp.wait()
            nsp.release()
            nsp = NSPopen(ns2_ipdb.nl.netns, [
                "arping", "-w", "1", "-c", "1", "-I", "eth0", self.vm2_rtr_ip
            ])
            nsp.wait()
            nsp.release()

            # ping
            nsp = NSPopen(ns1_ipdb.nl.netns, ["ping", self.vm2_ip, "-c", "2"])
            nsp.wait()
            nsp.release()
            # pem_stats only counts pem->bridge traffic, each VM has 4: arping/arp request/2 icmp request
            # total 8 packets should be counted
            self.assertEqual(self.pem_stats[c_uint(0)].value, 8)

            nsp_server = NSPopenWithCheck(ns2_ipdb.nl.netns,
                                          ["iperf", "-s", "-xSC"])
            sleep(1)
            nsp = NSPopen(ns1_ipdb.nl.netns,
                          ["iperf", "-c", self.vm2_ip, "-t", "1", "-xSC"])
            nsp.wait()
            nsp.release()
            nsp_server.kill()
            nsp_server.wait()
            nsp_server.release()

            nsp_server = NSPopenWithCheck(ns2_ipdb.nl.netns,
                                          ["netserver", "-D"])
            sleep(1)
            nsp = NSPopenWithCheck(
                ns1_ipdb.nl.netns,
                ["netperf", "-l", "1", "-H", self.vm2_ip, "--", "-m", "65160"])
            nsp.wait()
            nsp.release()
            nsp = NSPopen(
                ns1_ipdb.nl.netns,
                ["netperf", "-l", "1", "-H", self.vm2_ip, "-t", "TCP_RR"])
            nsp.wait()
            nsp.release()
            nsp_server.kill()
            nsp_server.wait()
            nsp_server.release()

        finally:
            sim.release()
            ipdb.release()
Beispiel #31
0
    def test_brb2(self):
        try:
            b = BPF(src_file=arg1, debug=0)
            self.pem_fn = b.load_func("pem", BPF.SCHED_CLS)
            self.pem_dest= b.get_table("pem_dest")
            self.pem_stats = b.get_table("pem_stats")

            # set up the topology
            self.set_default_const()
            (ns1_ipdb, self.ns1_eth_out, _) = sim._create_ns(self.ns1, ipaddr=self.vm1_ip+'/24',
                                                             fn=self.pem_fn, action='drop',
                                                             disable_ipv6=True)
            (ns2_ipdb, self.ns2_eth_out, _) = sim._create_ns(self.ns2, ipaddr=self.vm2_ip+'/24',
                                                             fn=self.pem_fn, action='drop',
                                                             disable_ipv6=True)
            ns1_ipdb.routes.add({'dst': self.vm2_rtr_mask, 'gateway': self.vm1_rtr_ip}).commit()
            ns2_ipdb.routes.add({'dst': self.vm1_rtr_mask, 'gateway': self.vm2_rtr_ip}).commit()

            (_, self.nsrtr_eth0_out, _) = sim._create_ns(self.ns_router, ipaddr=self.vm1_rtr_ip+'/24',
                                                         disable_ipv6=True)
            (rt_ipdb, self.nsrtr_eth1_out, _) = sim._ns_add_ifc(self.ns_router, "eth1", "ns_router2",
                                                                ipaddr=self.vm2_rtr_ip+'/24',
                                                                disable_ipv6=True)
            # enable ip forwarding in router ns
            nsp = NSPopen(rt_ipdb.nl.netns, ["sysctl", "-w", "net.ipv4.ip_forward=1"])
            nsp.wait(); nsp.release()

            # for each VM connecting to pem, there will be a corresponding veth connecting to the bridge
            self.setup_br(self.br1, self.nsrtr_eth0_out.ifname, self.veth_pem_2_br1, self.veth_br1_2_pem)
            self.setup_br(self.br2, self.nsrtr_eth1_out.ifname, self.veth_pem_2_br2, self.veth_br2_2_pem)

            # load the program and configure maps
            self.config_maps()

            # ping
            nsp = NSPopen(ns1_ipdb.nl.netns, ["ping", self.vm2_ip, "-c", "2"]); nsp.wait(); nsp.release()
            # one arp request/reply, 2 icmp request/reply per VM, total 6 packets per VM, 12 packets total
            self.assertEqual(self.pem_stats[c_uint(0)].value, 12)

            nsp_server = NSPopen(ns2_ipdb.nl.netns, ["iperf", "-s", "-xSC"])
            sleep(1)
            nsp = NSPopen(ns1_ipdb.nl.netns, ["iperf", "-c", self.vm2_ip, "-t", "1", "-xSC"])
            nsp.wait(); nsp.release()
            nsp_server.kill(); nsp_server.wait(); nsp_server.release()

            nsp_server = NSPopen(ns2_ipdb.nl.netns, ["netserver", "-D"])
            sleep(1)
            nsp = NSPopen(ns1_ipdb.nl.netns, ["netperf", "-l", "1", "-H", self.vm2_ip, "--", "-m", "65160"])
            nsp.wait(); nsp.release()
            nsp = NSPopen(ns1_ipdb.nl.netns, ["netperf", "-l", "1", "-H", self.vm2_ip, "-t", "TCP_RR"])
            nsp.wait(); nsp.release()
            nsp_server.kill(); nsp_server.wait(); nsp_server.release()

        finally:
            if self.br1 in ipdb.interfaces: ipdb.interfaces[self.br1].remove().commit()
            if self.br2 in ipdb.interfaces: ipdb.interfaces[self.br2].remove().commit()
            if self.veth_pem_2_br1 in ipdb.interfaces: ipdb.interfaces[self.veth_pem_2_br1].remove().commit()
            if self.veth_pem_2_br2 in ipdb.interfaces: ipdb.interfaces[self.veth_pem_2_br2].remove().commit()
            sim.release()
            ipdb.release()
Beispiel #32
0
    def _ns_add_ifc(self,
                    name,
                    ns_ifc,
                    ifc_base_name=None,
                    in_ifc=None,
                    out_ifc=None,
                    ipaddr=None,
                    macaddr=None,
                    fn=None,
                    cmd=None,
                    action="ok",
                    disable_ipv6=False):
        if name in self.ipdbs:
            ns_ipdb = self.ipdbs[name]
        else:
            try:
                nl = NetNS(name)
                self.namespaces.append(nl)
            except KeyboardInterrupt:
                # remove the namespace if it has been created
                pyroute2.netns.remove(name)
                raise
            ns_ipdb = IPDB(nl)
            self.ipdbs[nl.netns] = ns_ipdb
            if disable_ipv6:
                cmd1 = [
                    "sysctl", "-q", "-w",
                    "net.ipv6.conf.default.disable_ipv6=1"
                ]
                nsp = NSPopen(ns_ipdb.nl.netns, cmd1)
                nsp.wait()
                nsp.release()
            try:
                ns_ipdb.interfaces.lo.up().commit()
            except pyroute2.ipdb.exceptions.CommitException:
                print(
                    "Warning, commit for lo failed, operstate may be unknown")
        if in_ifc:
            in_ifname = in_ifc.ifname
            with in_ifc as v:
                # move half of veth into namespace
                v.net_ns_fd = ns_ipdb.nl.netns
        else:
            # delete the potentially leaf-over veth interfaces
            ipr = IPRoute()
            for i in ipr.link_lookup(ifname='%sa' % ifc_base_name):
                ipr.link("del", index=i)
            ipr.close()
            try:
                out_ifc = self.ipdb.create(ifname="%sa" % ifc_base_name,
                                           kind="veth",
                                           peer="%sb" %
                                           ifc_base_name).commit()
                in_ifc = self.ipdb.interfaces[out_ifc.peer]
                in_ifname = in_ifc.ifname
                with in_ifc as v:
                    v.net_ns_fd = ns_ipdb.nl.netns
            except KeyboardInterrupt:
                # explicitly remove the interface
                out_ifname = "%sa" % ifc_base_name
                if out_ifname in self.ipdb.interfaces:
                    self.ipdb.interfaces[out_ifname].remove().commit()
                raise

        if out_ifc: out_ifc.up().commit()
        try:
            # this is a workaround for fc31 and possible other disto's.
            # when interface 'lo' is already up, do another 'up().commit()'
            # has issues in fc31.
            # the workaround may become permanent if we upgrade pyroute2
            # in all machines.
            if 'state' in ns_ipdb.interfaces.lo.keys():
                if ns_ipdb.interfaces.lo['state'] != 'up':
                    ns_ipdb.interfaces.lo.up().commit()
            else:
                ns_ipdb.interfaces.lo.up().commit()
        except pyroute2.ipdb.exceptions.CommitException:
            print("Warning, commit for lo failed, operstate may be unknown")
        ns_ipdb.initdb()
        in_ifc = ns_ipdb.interfaces[in_ifname]
        with in_ifc as v:
            v.ifname = ns_ifc
            if ipaddr: v.add_ip("%s" % ipaddr)
            if macaddr: v.address = macaddr
            v.up()
        if disable_ipv6:
            cmd1 = [
                "sysctl", "-q", "-w",
                "net.ipv6.conf.%s.disable_ipv6=1" % out_ifc.ifname
            ]
            subprocess.call(cmd1)
        if fn and out_ifc:
            self.ipdb.nl.tc("add", "ingress", out_ifc["index"], "ffff:")
            self.ipdb.nl.tc("add-filter",
                            "bpf",
                            out_ifc["index"],
                            ":1",
                            fd=fn.fd,
                            name=fn.name,
                            parent="ffff:",
                            action=action,
                            classid=1)
        if cmd:
            self.processes.append(NSPopen(ns_ipdb.nl.netns, cmd))
        return (ns_ipdb, out_ifc, in_ifc)
Beispiel #33
0
 def add_values(self, subnet, VMs):
     x = 0
     for sub in range(5, subnet + 5):
         for mac in range(2, VMs + 2):
             print 'ns_array[%d], ARP address:  192.168.%d.1' % (x, sub)
             cmd1 = [
                 "route", "add", "default", "gw",
                 '192.168.%d.1' % (sub)
             ]
             nsp = NSPopen(self.ns_array[x].id.nl.netns, cmd1)
             nsp.wait()
             nsp.release()
             cmd1 = [
                 "arping", "-c", "1", "-I", "eth0",
                 '192.168.%d.1' % (sub), "-q"
             ]
             nsp = NSPopen(self.ns_array[x].id.nl.netns, cmd1)
             nsp.wait()
             nsp.release()
             x += 1
Beispiel #34
0
    def test_topology(self):
        nsp = NSPopen(self.ns_array[0].id.nl.netns,
                      ["ping", "192.168.6.2", "-c", "2"])
        nsp.wait()
        nsp.release()
        # one arp request/reply, 2 icmp request/reply per VM, total 6 packets per VM, 12 packets total
        nsp_server = NSPopen(self.ns_array[2].id.nl.netns,
                             ["iperf", "-s", "-xSC"])
        sleep(1)
        nsp = NSPopen(self.ns_array[0].id.nl.netns,
                      ["iperf", "-c", "192.168.6.2", "-t", "1", "-xSC"])
        nsp.wait()
        nsp.release()
        nsp_server.kill()
        nsp_server.wait()
        nsp_server.release()

        nsp_server = NSPopen(self.ns_array[2].id.nl.netns, ["netserver", "-D"])
        sleep(1)
        nsp = NSPopen(
            self.ns_array[0].id.nl.netns,
            ["netperf", "-l", "1", "-H", "192.168.6.2", "--", "-m", "65160"])
        nsp.wait()
        nsp.release()
        nsp = NSPopen(
            self.ns_array[0].id.nl.netns,
            ["netperf", "-l", "1", "-H", "192.168.6.2", "-t", "TCP_RR"])
        nsp.wait()
        nsp.release()
        nsp_server.kill()
        nsp_server.wait()
        nsp_server.release()
Beispiel #35
0
    def start(self):
        # each entry is tuple of ns_ipdb, out_ifc, in_ifc
        host_info = []
        for i in range(0, num_hosts):
            print("Launching host %i of %i" % (i + 1, num_hosts))
            ipaddr = "172.16.1.%d/24" % (100 + i)
            host_info.append(
                self._create_ns("host%d" % i, ipaddr=ipaddr,
                                disable_ipv6=True))
            if multicast:
                cmd = ["python", "tunnel.py", str(i)]
            else:
                cmd = [
                    "python", "tunnel_mesh.py",
                    str(num_hosts),
                    str(i),
                    str(dhcp)
                ]
            p = NSPopen(host_info[i][0].nl.netns, cmd, stdin=PIPE)
            self.processes.append(p)
        with self.ipdb.create(ifname="br-fabric", kind="bridge") as br:
            for host in host_info:
                br.add_port(host[1])
            br.up()

        # get host0 bridge ip's
        host0_br_ips = []
        if dhcp == 1:
            print("Waiting for host0 br1/br2 ip addresses available")
            for j in range(0, 2):
                retry = -1
                ip_out = None
                while retry < 0:
                    check = Popen([
                        "ip", "netns", "exec", "host0", "ip", "addr", "show",
                        "br%d" % j
                    ],
                                  stdout=PIPE,
                                  stderr=PIPE)
                    ip_out = check.stdout.read()
                    checkip = "99.1.%d" % j
                    retry = ip_out.find(checkip)
                p = re.compile(("99.1.%d." % j) + "\d+")
                host0_br_ips.append(p.findall(ip_out)[0])
        else:
            host0_br_ips.append("99.1.0.1")
            host0_br_ips.append("99.1.1.1")

        # traffic test
        print("Validating connectivity")
        for i in range(1, num_hosts):
            for j in range(0, 2):
                retry = -1
                while retry < 0:
                    check = Popen([
                        "ip", "netns", "exec",
                        "host%d" % i, "ip", "addr", "show",
                        "br%d" % j
                    ],
                                  stdout=PIPE,
                                  stderr=PIPE)
                    out = check.stdout.read()
                    checkip = "99.1.%d" % j
                    retry = out.find(checkip)
                print("VNI%d between host0 and host%d" % (10000 + j, i))
                call([
                    "ip", "netns", "exec",
                    "host%d" % i, "ping", host0_br_ips[j], "-c", "3", "-i",
                    "0.2", "-q"
                ])
Beispiel #36
0
 if args.debug:
     fname = f'{nsname}-ndb.db'
     print(f'dump: netns topology database {fname}')
     netns.schema.backup(fname)
 netns.close()
 # set up the emulation QDisc
 nsp = NSPopen(
     nsname,
     [
         'tc',
         'qdisc',
         'add',
         'dev',
         veth,
         'root',
         'netem',
         'delay',
         f'{args.delay}ms',
         f'{int(args.delay)/2}ms',
         'loss',
         f'{args.loss}%',
         '25%',
     ],
     stdout=subprocess.PIPE,
 )
 nsp.communicate()
 nsp.wait()
 nsp.release()
 if args.verbose:
     print(f'netem: add {nsname}/{veth}, '
           f'{args.delay}, {args.loss}')
Beispiel #37
0
    def test_brb(self):
        try:
            b = BPF(src_file=arg1, debug=0)
            self.pem_fn = b.load_func("pem", BPF.SCHED_CLS)
            self.br1_fn = b.load_func("br1", BPF.SCHED_CLS)
            self.br2_fn = b.load_func("br2", BPF.SCHED_CLS)
            self.get_table(b)

            # set up the topology
            self.set_default_const()
            (ns1_ipdb, self.ns1_eth_out, _) = sim._create_ns(self.ns1, ipaddr=self.vm1_ip+'/24',
                                                             fn=self.pem_fn, action='drop',
                                                             disable_ipv6=True)
            (ns2_ipdb, self.ns2_eth_out, _) = sim._create_ns(self.ns2, ipaddr=self.vm2_ip+'/24',
                                                             fn=self.pem_fn, action='drop',
                                                             disable_ipv6=True)
            ns1_ipdb.routes.add({'dst': self.vm2_rtr_mask, 'gateway': self.vm1_rtr_ip}).commit()
            ns2_ipdb.routes.add({'dst': self.vm1_rtr_mask, 'gateway': self.vm2_rtr_ip}).commit()
            self.vm1_mac = ns1_ipdb.interfaces['eth0'].address
            self.vm2_mac = ns2_ipdb.interfaces['eth0'].address

            (_, self.nsrtr_eth0_out, _) = sim._create_ns(self.ns_router, ipaddr=self.vm1_rtr_ip+'/24',
                                                         fn=self.br1_fn, action='drop',
                                                         disable_ipv6=True)
            (rt_ipdb, self.nsrtr_eth1_out, _) = sim._ns_add_ifc(self.ns_router, "eth1", "ns_router2",
                                                                ipaddr=self.vm2_rtr_ip+'/24',
                                                                fn=self.br2_fn, action='drop',
                                                                disable_ipv6=True)
            nsp = NSPopen(rt_ipdb.nl.netns, ["sysctl", "-w", "net.ipv4.ip_forward=1"])
            nsp.wait(); nsp.release()

            # configure maps
            self.config_maps()

            # our bridge is not smart enough, so send arping for router learning to prevent router
            # from sending out arp request
            nsp = NSPopen(ns1_ipdb.nl.netns,
                          ["arping", "-w", "1", "-c", "1", "-I", "eth0", self.vm1_rtr_ip])
            nsp.wait(); nsp.release()
            nsp = NSPopen(ns2_ipdb.nl.netns,
                          ["arping", "-w", "1", "-c", "1", "-I", "eth0", self.vm2_rtr_ip])
            nsp.wait(); nsp.release()

            # ping
            nsp = NSPopen(ns1_ipdb.nl.netns, ["ping", self.vm2_ip, "-c", "2"])
            nsp.wait(); nsp.release()
            # pem_stats only counts pem->bridge traffic, each VM has 4: arping/arp request/2 icmp request
            # total 8 packets should be counted
            self.assertEqual(self.pem_stats[c_uint(0)].value, 8)

            nsp_server = NSPopen(ns2_ipdb.nl.netns, ["iperf", "-s", "-xSC"])
            sleep(1)
            nsp = NSPopen(ns1_ipdb.nl.netns, ["iperf", "-c", self.vm2_ip, "-t", "1", "-xSC"])
            nsp.wait(); nsp.release()
            nsp_server.kill(); nsp_server.wait(); nsp_server.release()

            nsp_server = NSPopen(ns2_ipdb.nl.netns, ["netserver", "-D"])
            sleep(1)
            nsp = NSPopen(ns1_ipdb.nl.netns, ["netperf", "-l", "1", "-H", self.vm2_ip, "--", "-m", "65160"])
            nsp.wait(); nsp.release()
            nsp = NSPopen(ns1_ipdb.nl.netns, ["netperf", "-l", "1", "-H", self.vm2_ip, "-t", "TCP_RR"])
            nsp.wait(); nsp.release()
            nsp_server.kill(); nsp_server.wait(); nsp_server.release()

        finally:
            sim.release()
            ipdb.release()
Beispiel #38
0
    def test_brb2(self):
        try:
            b = BPF(src_file=arg1, debug=0)
            self.pem_fn = b.load_func("pem", BPF.SCHED_CLS)
            self.pem_dest = b.get_table("pem_dest")
            self.pem_stats = b.get_table("pem_stats")

            # set up the topology
            self.set_default_const()
            (ns1_ipdb, self.ns1_eth_out,
             _) = sim._create_ns(self.ns1,
                                 ipaddr=self.vm1_ip + '/24',
                                 fn=self.pem_fn,
                                 action='drop',
                                 disable_ipv6=True)
            (ns2_ipdb, self.ns2_eth_out,
             _) = sim._create_ns(self.ns2,
                                 ipaddr=self.vm2_ip + '/24',
                                 fn=self.pem_fn,
                                 action='drop',
                                 disable_ipv6=True)
            ns1_ipdb.routes.add({
                'dst': self.vm2_rtr_mask,
                'gateway': self.vm1_rtr_ip
            }).commit()
            ns2_ipdb.routes.add({
                'dst': self.vm1_rtr_mask,
                'gateway': self.vm2_rtr_ip
            }).commit()

            (_, self.nsrtr_eth0_out,
             _) = sim._create_ns(self.ns_router,
                                 ipaddr=self.vm1_rtr_ip + '/24',
                                 disable_ipv6=True)
            (rt_ipdb, self.nsrtr_eth1_out,
             _) = sim._ns_add_ifc(self.ns_router,
                                  "eth1",
                                  "ns_router2",
                                  ipaddr=self.vm2_rtr_ip + '/24',
                                  disable_ipv6=True)
            # enable ip forwarding in router ns
            nsp = NSPopen(rt_ipdb.nl.netns,
                          ["sysctl", "-w", "net.ipv4.ip_forward=1"])
            nsp.wait()
            nsp.release()

            # for each VM connecting to pem, there will be a corresponding veth connecting to the bridge
            self.setup_br(self.br1, self.nsrtr_eth0_out.ifname,
                          self.veth_pem_2_br1, self.veth_br1_2_pem)
            self.setup_br(self.br2, self.nsrtr_eth1_out.ifname,
                          self.veth_pem_2_br2, self.veth_br2_2_pem)

            # load the program and configure maps
            self.config_maps()

            # ping
            nsp = NSPopen(ns1_ipdb.nl.netns, ["ping", self.vm2_ip, "-c", "2"])
            nsp.wait()
            nsp.release()
            # one arp request/reply, 2 icmp request/reply per VM, total 6 packets per VM, 12 packets total
            self.assertEqual(self.pem_stats[c_uint(0)].value, 12)

            nsp_server = NSPopen(ns2_ipdb.nl.netns, ["iperf", "-s", "-xSC"])
            sleep(1)
            nsp = NSPopen(ns1_ipdb.nl.netns,
                          ["iperf", "-c", self.vm2_ip, "-t", "1", "-xSC"])
            nsp.wait()
            nsp.release()
            nsp_server.kill()
            nsp_server.wait()
            nsp_server.release()

            nsp_server = NSPopen(ns2_ipdb.nl.netns, ["netserver", "-D"])
            sleep(1)
            nsp = NSPopen(
                ns1_ipdb.nl.netns,
                ["netperf", "-l", "1", "-H", self.vm2_ip, "--", "-m", "65160"])
            nsp.wait()
            nsp.release()
            nsp = NSPopen(
                ns1_ipdb.nl.netns,
                ["netperf", "-l", "1", "-H", self.vm2_ip, "-t", "TCP_RR"])
            nsp.wait()
            nsp.release()
            nsp_server.kill()
            nsp_server.wait()
            nsp_server.release()

        finally:
            if self.br1 in ipdb.interfaces:
                ipdb.interfaces[self.br1].remove().commit()
            if self.br2 in ipdb.interfaces:
                ipdb.interfaces[self.br2].remove().commit()
            if self.veth_pem_2_br1 in ipdb.interfaces:
                ipdb.interfaces[self.veth_pem_2_br1].remove().commit()
            if self.veth_pem_2_br2 in ipdb.interfaces:
                ipdb.interfaces[self.veth_pem_2_br2].remove().commit()
            sim.release()
            ipdb.release()
Beispiel #39
0
    def _ns_add_ifc(self,
                    name,
                    ns_ifc,
                    ifc_base_name=None,
                    in_ifc=None,
                    out_ifc=None,
                    ipaddr=None,
                    macaddr=None,
                    fn=None,
                    cmd=None,
                    action="ok",
                    disable_ipv6=False):
        if name in self.ipdbs:
            ns_ipdb = self.ipdbs[name]
        else:
            try:
                nl = NetNS(name)
                self.namespaces.append(nl)
            except KeyboardInterrupt:
                # remove the namespace if it has been created
                pyroute2.netns.remove(name)
                raise
            ns_ipdb = IPDB(nl)
            self.ipdbs[nl.netns] = ns_ipdb
            if disable_ipv6:
                cmd1 = [
                    "sysctl", "-q", "-w",
                    "net.ipv6.conf.default.disable_ipv6=1"
                ]
                nsp = NSPopen(ns_ipdb.nl.netns, cmd1)
                nsp.wait()
                nsp.release()
            ns_ipdb.interfaces.lo.up().commit()
        if in_ifc:
            in_ifname = in_ifc.ifname
            with in_ifc as v:
                # move half of veth into namespace
                v.net_ns_fd = ns_ipdb.nl.netns
        else:
            # delete the potentially leaf-over veth interfaces
            ipr = IPRoute()
            for i in ipr.link_lookup(ifname='%sa' % ifc_base_name):
                ipr.link_remove(i)
            ipr.close()
            try:
                out_ifc = self.ipdb.create(ifname="%sa" % ifc_base_name,
                                           kind="veth",
                                           peer="%sb" %
                                           ifc_base_name).commit()
                in_ifc = self.ipdb.interfaces[out_ifc.peer]
                in_ifname = in_ifc.ifname
                with in_ifc as v:
                    v.net_ns_fd = ns_ipdb.nl.netns
            except KeyboardInterrupt:
                # explicitly remove the interface
                out_ifname = "%sa" % ifc_base_name
                if out_ifname in self.ipdb.interfaces:
                    self.ipdb.interfaces[out_ifname].remove().commit()
                raise

        if out_ifc: out_ifc.up().commit()
        ns_ipdb.interfaces.lo.up().commit()
        in_ifc = ns_ipdb.interfaces[in_ifname]
        with in_ifc as v:
            v.ifname = ns_ifc
            if ipaddr: v.add_ip("%s" % ipaddr)
            if macaddr: v.address = macaddr
            v.up()
        if disable_ipv6:
            cmd1 = [
                "sysctl", "-q", "-w",
                "net.ipv6.conf.%s.disable_ipv6=1" % out_ifc.ifname
            ]
            subprocess.call(cmd1)
        if fn and out_ifc:
            self.ipdb.nl.tc("add", "ingress", out_ifc["index"], "ffff:")
            self.ipdb.nl.tc("add-filter",
                            "bpf",
                            out_ifc["index"],
                            ":1",
                            fd=fn.fd,
                            name=fn.name,
                            parent="ffff:",
                            action=action,
                            classid=1)
        if cmd:
            self.processes.append(NSPopen(ns_ipdb.nl.netns, cmd))
        return (ns_ipdb, out_ifc, in_ifc)
Beispiel #40
0
    def _ns_add_ifc(self, name, ns_ifc, ifc_base_name=None, in_ifc=None,
                    out_ifc=None, ipaddr=None, macaddr=None, fn=None, cmd=None,
                    action="ok", disable_ipv6=False):
        if name in self.ipdbs:
            ns_ipdb = self.ipdbs[name]
        else:
            try:
                nl=NetNS(name)
                self.namespaces.append(nl)
            except KeyboardInterrupt:
                # remove the namespace if it has been created
                pyroute2.netns.remove(name)
                raise
            ns_ipdb = IPDB(nl)
            self.ipdbs[nl.netns] = ns_ipdb
            if disable_ipv6:
                cmd1 = ["sysctl", "-q", "-w",
                       "net.ipv6.conf.default.disable_ipv6=1"]
                nsp = NSPopen(ns_ipdb.nl.netns, cmd1)
                nsp.wait(); nsp.release()
            ns_ipdb.interfaces.lo.up().commit()
        if in_ifc:
            in_ifname = in_ifc.ifname
            with in_ifc as v:
                # move half of veth into namespace
                v.net_ns_fd = ns_ipdb.nl.netns
        else:
            # delete the potentially leaf-over veth interfaces
            ipr = IPRoute()
            for i in ipr.link_lookup(ifname='%sa' % ifc_base_name): ipr.link_remove(i)
            ipr.close()
            try:
                out_ifc = self.ipdb.create(ifname="%sa" % ifc_base_name, kind="veth",
                                           peer="%sb" % ifc_base_name).commit()
                in_ifc = self.ipdb.interfaces[out_ifc.peer]
                in_ifname = in_ifc.ifname
                with in_ifc as v:
                    v.net_ns_fd = ns_ipdb.nl.netns
            except KeyboardInterrupt:
                # explicitly remove the interface
                out_ifname = "%sa" % ifc_base_name
                if out_ifname in self.ipdb.interfaces: self.ipdb.interfaces[out_ifname].remove().commit()
                raise

        if out_ifc: out_ifc.up().commit()
        ns_ipdb.interfaces.lo.up().commit()
        ns_ipdb.initdb()
        in_ifc = ns_ipdb.interfaces[in_ifname]
        with in_ifc as v:
            v.ifname = ns_ifc
            if ipaddr: v.add_ip("%s" % ipaddr)
            if macaddr: v.address = macaddr
            v.up()
        if disable_ipv6:
            cmd1 = ["sysctl", "-q", "-w",
                   "net.ipv6.conf.%s.disable_ipv6=1" % out_ifc.ifname]
            subprocess.call(cmd1)
        if fn and out_ifc:
            self.ipdb.nl.tc("add", "ingress", out_ifc["index"], "ffff:")
            self.ipdb.nl.tc("add-filter", "bpf", out_ifc["index"], ":1",
                            fd=fn.fd, name=fn.name, parent="ffff:",
                            action=action, classid=1)
        if cmd:
            self.processes.append(NSPopen(ns_ipdb.nl.netns, cmd))
        return (ns_ipdb, out_ifc, in_ifc)
 def execCmd(self, cmd):
     cmdList = cmd.split()
     nsp = NSPopen(self.nSname, cmdList, stdout=subprocess.PIPE)
     nsp.wait()
     nsp.release()