def test_setup_expert(self):
        """
        This UnitTest executes the wca_setup_expert-function with the given config-file.
        It sets the values of all the  from WebInterface of the Router.
        """
        print("Test if the 'wca_setup_wizard'-function is working")
        router = self._create_router()
        # NVAssisten
        nv_assist = NVAssistent("eth0")
        nv_assist.create_namespace_vlan(router)
        # Set netns for the current process
        netns.setns(router.namespace_name)
        try:
            # Config
            config = ConfigManager.get_web_interface_list()[router.id]
            self.assertEqual(len(config), 30, "Wrong size of the Config-Directory")

            print("Set the following configuration: \n" + str(config))

            router_web_config = RouterWebConfiguration(router, config, wizard=True)
            router_web_config.start()
            router_web_config.join()
        except Exception as e:
            nv_assist.close()
            raise e

        assert router.mode == Mode.normal
        nv_assist.close()
Example #2
0
	def single(self, ns):
		self.signal()
		netns.setns(ns)

		k = ns + '_' + self.check

		while True:
			self.results[k] = { 'check': self.check, 'type': self.type, 'ns': ns, 'state': 'RUN' }
			res = self.results[k]

			try:
				r = pyping.ping(self.host, count=self.count, packet_size=self.length)

				res['max_rtt'] = r.max_rtt
				res['avg_rtt'] = r.avg_rtt
				res['min_rtt'] = r.min_rtt
				res['packet_lost'] = r.packet_lost
				res['state'] = 'OK'

				logging.info("[PING:%s] host = %s, max time = %s, avg time = %s, min time = %s, lost packets = %d" % (ns, self.host, r.max_rtt, r.avg_rtt, r.min_rtt, r.packet_lost))
			except:
				res['state'] = 'FAIL'

				logging.info("[PING:%s] Cannot ping host %s" % (ns, self.host))

			self.results[k] = res

			time.sleep(float(self.delay))
    def __init__(self, nsp_name: str, ipdb: IPDB):
        """
        Creats a namespace for a specific vlan_iface

        :param nsp_name:
        :param vlan_iface_name:
        :param ipdb: IPDB is a transactional database, containing records, representing network stack objects.
                    Any change in the database is not reflected immidiately in OS, but waits until commit() is called.
        """
        Logger().debug("Create Namespace ...", 2)
        self.nsp_name = nsp_name
        self.id = id
        self.vlan_iface_name = ""
        self.vlan_iface_ip = "0.0.0.0"
        self.ipdb = ipdb
        self.ipdb_netns = None
        try:
            self.ipdb_netns = IPDB(nl=NetNS(nsp_name))
            netns.setns(nsp_name)
            self.ipdb_netns.interfaces['lo'].up().commit()
            Logger().debug("[+] Namespace(" + nsp_name + ") successfully created", 3)
            # self.encapsulate_interface()
        except Exception as e:
            Logger().debug("[-] Couldn't create Namespace(" + nsp_name + ")", 3)
            for tb in traceback.format_tb(sys.exc_info()[2]):
                Logger().error(tb, 3)
            Logger().error(str(e), 3)
            self.remove()
    def test_flash_firmware(self):
        print("Test Router_Flash_Firmware")
        router = self._create_router()

        print("Download/Import firmware-image from UpdateServer/PI ...")
        # Download firmare-image from UpdateServer
        sysupdate = Sysupdate(router)
        sysupdate.start()
        sysupdate.join()

        # NVAssisten
        nv_assist = NVAssistent("eth0")
        nv_assist.create_namespace_vlan(router)
        # Set netns for the current process
        netns.setns(router.namespace_name)
        # The IP where the Router can download the firmware image (should be the frameworks IP)
        web_server_ip = nv_assist.get_ip_address(router.namespace_name, router.vlan_iface_name)[0]

        try:
            # Copy firmware-image to the Router (/tmp/image)
            print("Copy firmware-image to Router ...")
            sysupgrade = Sysupgrade(router, n=True, web_server_ip=web_server_ip, debug=True)
            sysupgrade.start()
            sysupgrade.join()
        except Exception:
            raise
        finally:
            nv_assist.close()
 def setUpClass(cls):
     cls.router = cls._create_router()
     # NVAssisten
     cls.nv_assist = NVAssistent("eth0")
     cls.nv_assist.create_namespace_vlan(cls.router)
     # Set netns for the current process
     netns.setns(cls.router.namespace_name)
     # Create NetworkCrtl
     cls.network_ctrl = NetworkCtrl(cls.router)
     assert isinstance(cls.network_ctrl, NetworkCtrl)
Example #6
0
    def __setns(cls, remote_sys: RemoteSystem) -> None:
        """
        Set Namespace and VLAN for the current process.

        :param remote_sys: The RemoteSystem which you want to connect over VLAN
        """
        if cls.VLAN:
            logging.debug("%sSet Namespace and VLAN for the current process(" + str(os.getpid()) + ")",
                          LoggerSetup.get_log_deep(2))
            netns.setns(remote_sys.namespace_name)
Example #7
0
def NSPopenServer(nsname, flags, channel_in, channel_out, argv, kwarg):
    # set netns
    try:
        setns(nsname, flags=flags)
    except Exception as e:
        channel_out.put(e)
        return
    # create the Popen object
    child = subprocess.Popen(*argv, **kwarg)
    for fname in ['stdout', 'stderr', 'stdin']:
        obj = getattr(child, fname)
        if obj is not None:
            fproxy = NSPopenFile(obj)
            setattr(child, fname, fproxy)

    # send the API map
    channel_out.put(None)

    while True:
        # synchronous mode
        # 1. get the command from the API
        try:
            call = channel_in.get()
        except:
            (et, ev, tb) = sys.exc_info()
            try:
                channel_out.put({'code': 500, 'data': ev})
            except:
                pass
            break

        # 2. stop?
        if call['name'] == 'release':
            break

        # 3. run the call
        try:
            # get the object namespace
            ns = call.get('namespace')
            obj = child
            if ns:
                for step in ns.split('.'):
                    obj = getattr(obj, step)
            attr = getattr(obj, call['name'])
            if isinstance(attr, (types.MethodType,
                                 types.FunctionType,
                                 types.BuiltinMethodType)):
                result = attr(*call['argv'], **call['kwarg'])
            else:
                result = attr
            channel_out.put({'code': 200, 'data': result})
        except:
            (et, ev, tb) = sys.exc_info()
            channel_out.put({'code': 500, 'data': ev})
    child.wait()
Example #8
0
	def single(self, ns):
		self.signal()
		netns.setns(ns)

		self.results[ns + '_torrent_state'] = "RUN"

		session = libtorrent.session()
		session.listen_on(6881, 6891)

		info = libtorrent.torrent_info(self.file)
		resource = session.add_torrent({'ti' : info, 'save_path' : '/var/tmp/' + ns})

		download_rates_sum = 0 
		download_rates_avg = 0.0 
		upload_rates_sum = 0 
		upload_rates_avg = 0.0 
		download_count = 0 
		upload_count = 0 

		start = time.time()

		while (not resource.is_seed()):
			status = resource.status()
			download_rate = status.download_rate
			upload_rate = status.upload_rate

			if download_rate != 0:
				download_rates_sum += download_rate
				download_count += 1

			if upload_rate != 0:
				upload_rates_sum += upload_rate
				upload_count += 1

			time.sleep(1)

		end = time.time()

		if download_count == 0:
			download_count = 1 

		if upload_count == 0:
			upload_count = 1 

		download_rates_avg = float(download_rates_sum) / download_count
		upload_rates_avg = float(upload_rates_sum) / upload_count

		shutil.rmtree('/var/tmp/' + ns, ignore_errors=True)

		self.results[ns + "_torrent_downspeed"] = download_rates_avg
		self.results[ns + "_torrent_upspeed"] = upload_rates_avg
		self.results[ns + "_torrent_time"] = end - start
		self.results[ns + '_torrent_state'] = "OK"

		logging.info("[TORRENT:%s] download speed = %.2f b/s, upload speed = %.2f b/s, time = %.2f sec" % (ns, download_rates_avg, upload_rates_avg, (end - start)))
Example #9
0
	def single(self, ns):
		self.signal()
		netns.setns(ns)

		k = ns + '_' + self.check

		recursor = dns.resolver.Resolver()

		while True:
			self.results[k] = { 'check': self.check, 'type': self.type, 'ns': ns, 'state': 'RUN' }
			res = self.results[k]

			recursor.nameservers = [self.server]
			error = ""

			# Если резолвим IP адрес, приводим его к правильному виду
			if re.search("^\d+\.\d+\.\d+\.\d+$", self.host):
				self.host = dns.reversename.from_address(self.host)

			# Замеряем время выполнения запроса
			start = time.time()

			# Выполняем запрос
			try:
				answers = recursor.query (self.host, self.query_type)
			except dns.exception.DNSException as e:
				if isinstance(e, dns.resolver.NXDOMAIN):
					error = "No such domain " + str(self.host)
				elif isinstance(e, dns.resolver.Timeout):
					error = "Timed out while resolving " + str(self.host)
				elif isinstance(e, dns.resolver.NoAnswer):
					error = "No answer while resolving " + str(self.host)
				elif isinstance(e, dns.resolver.NoNameservers):
					error = "Nameserver " + str(self.server) + " not available"
				else:
					error = "Unhandled DNS exception"

			# Замеряем время выполнения запроса
			end = time.time()

			if error != "":
				res['qtime'] = (end - start) * 1000
				res['state'] = 'FAIL'

				logging.info("[DNS:%s] host = %s, query time = %.2f msec, return message = %s" % (ns, self.host, (end - start) * 1000, error))
			else:
				res['qtime'] = (end - start) * 1000
				res['state'] = 'OK'

				logging.info("[DNS:%s] host = %s, query time = %.2f msec, return message = Success" % (ns, self.host, (end - start) * 1000))

			self.results[k] = res

			time.sleep(float(self.delay))
    def _power_off(self, ps: Ubnt, q: Queue, port: int):
        nv_assist = NVAssistent("eth0")
        nv_assist.create_namespace_vlan(ps)
        netns.setns(ps.namespace_name)

        power_on = PowerStripControl(self.router, ps, False, port)
        power_on.start()
        power_on.join()

        nv_assist.close()
        q.put(ps)
    def _reboot_into_normal(self, router: Router, q: Queue):
        print("Reboot Router back into normalmode ...")
        nv_assist = NVAssistent("eth0")
        nv_assist.create_namespace_vlan(router)
        # Set netns for the current process
        netns.setns(router.namespace_name)

        router_reboot = RouterReboot(router, configmode=False)
        router_reboot.start()
        router_reboot.join()
        assert router.mode == Mode.normal
        nv_assist.close()
        q.put(router)
Example #12
0
	def single(self, ns):
		self.signal()
		netns.setns(ns)

		logger_rzs = logging.getLogger('RZS')
		logger_rzs.propagate = False
		log_handler_rzs = logging.FileHandler('/var/log/sensors_rzs_' + ns + '.log')
		logger_rzs.addHandler(log_handler_rzs)

		logging.getLogger("urllib3").propagate = False

		k = ns + '_' + self.check

		headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36'}

		while True:
			self.results[k] = { 'check': self.check, 'type': self.type, 'ns': ns, 'state': 'RUN' }
			res = self.results[k]
			available_hosts_count = 0
			unavailable_hosts_count = 0
			total_hosts_count = 0

			try:
				f = open(self.blockfile, 'r')
				blocked_urls = f.read()
				f.close()

				for url in blocked_urls.splitlines():
					total_hosts_count += 1

					try:
						response = requests.get(url, headers=headers, timeout=0.5)
						available_hosts_count += 1
						logger_rzs.info("[RZS:%s] %s Available host: %s" % (ns, time.strftime("%H:%M:%S %d/%m/%Y", time.localtime(time.time())), url))
					except Exception as e:
						unavailable_hosts_count += 1

				res['rzs_total'] = total_hosts_count
				res['rzs_available'] = available_hosts_count
				res['rzs_unavailable'] = unavailable_hosts_count
				res['state'] = 'OK'

				logging.info("[RZS:%s] Total hosts count = %d, available hosts count = %d, unavailable hosts count = %d" % (ns, total_hosts_count, available_hosts_count, unavailable_hosts_count))
			except:
				res['state'] = 'FAIL'

				logging.info("[RZS:%s] Cannot open block file %s" % (ns, self.blockfile))

			self.results[k] = res

			time.sleep(float(self.delay))
Example #13
0
  def __createNetns(self, phyIfaceIndex):
    netnsName = self.__getNetnsName()
    (pvdIfaceName, pvdIfaceIndex) = self.__getPvdIfaceParams()
    netns.create(netnsName)
    LOG.debug('network namespace {0} created'.format(netnsName))

    # create a virtual interface where PvD parameters are going to be configured, then move the interface to the new network namespace
    self.ipRoot.link_create(ifname=pvdIfaceName, index=pvdIfaceIndex, kind=self.__PVD_IFACE_TYPE, link=phyIfaceIndex)
    LOG.debug('macvlan {0} created in default network namespace'.format(pvdIfaceName))
    pvdIfaceIndex = self.ipRoot.link_lookup(ifname=pvdIfaceName)
    self.ipRoot.link('set', index=pvdIfaceIndex[0], net_ns_fd=netnsName)
    LOG.debug('macvlan {0} moved to network namespace {1}'.format(pvdIfaceName, netnsName))

    # change the namespace and get new NETLINK handles to operate in new namespace
    netns.setns(netnsName)
    LOG.debug('network namespace switched to {0}'.format(netnsName))
    ip = IPRoute()
    ipdb = IPDB()
    ipdb.register_callback(self.__onIfaceStateChange)
    # disable kernel to auto-configure the interface associated with the PvD, let the pvdman to solely control interface configuration
    acceptRaConfFile = self.__ACCEPT_RA_CONF_FILE.replace(self.__IFACENAME_REPLACE_PATTERN, pvdIfaceName)
    acceptRaConfFile = open(acceptRaConfFile, 'w')
    acceptRaConfFile.write('0')
    LOG.debug('processing of RAs by kernel disabled in {0}'.format(acceptRaConfFile.name))
    # return to a default network namespace to not cause a colision with other modules
    # ip and ipdb handles continue to work in the target network namespace
    netns.setns(self.__NETNS_DEFAULT_NAME)
    LOG.debug('network namespace switched to default')

    # get new index since interface has been moved to a different namespace
    loIfaceIndex = ip.link_lookup(ifname=self.__LOOPBACK_IFACE_NAME)
    if (len(loIfaceIndex) > 0):
      loIfaceIndex = loIfaceIndex[0]
    pvdIfaceIndex = ip.link_lookup(ifname=pvdIfaceName)
    if (len(pvdIfaceIndex) > 0):
      pvdIfaceIndex = pvdIfaceIndex[0]

    # start interfaces
    ip.link_up(loIfaceIndex)
    ip.link_up(pvdIfaceIndex)

    # clear network configuration if exists
    ip.flush_addr(index=pvdIfaceIndex)
    ip.flush_routes(index=pvdIfaceIndex)
    ip.flush_rules(index=pvdIfaceIndex)

    LOG.debug('macvlan {0} in network namespace {1} initialized'.format(pvdIfaceName, netnsName))

    return (netnsName, pvdIfaceName, ip)
    def _reboot_into_config(self, router: Router, q: Queue):
        print("Reboot Router into configmode ...")
        # Create NVAssistent
        nv_assist = NVAssistent("eth0")
        nv_assist.create_namespace_vlan(router)
        # Set netns for the current process
        netns.setns(router.namespace_name)

        # Reboot Router into configmode
        router_reboot = RouterReboot(router, configmode=True)
        router_reboot.start()
        router_reboot.join()
        assert router.mode == Mode.configuration
        nv_assist.close()
        q.put(router)
Example #15
0
def NetNServer(netns, cmdch, brdch, flags=os.O_CREAT):
    '''
    The netns server supposed to be started automatically by NetNS.
    It has two communication channels: one simplex to forward incoming
    netlink packets, `rcvch`, and other synchronous duplex to get
    commands and send back responses, `cmdch`.

    Channels should support standard socket API, should be compatible
    with poll/select and should be able to transparently pickle objects.
    NetNS uses `multiprocessing.Pipe` for this purpose, but it can be
    any other implementation with compatible API.

    The first parameter, `netns`, is a netns name. Depending on the
    `flags`, the netns can be created automatically. The `flags` semantics
    is exactly the same as for `open(2)` system call.

    ...

    The server workflow is simple. The startup sequence::

        1. Create or open a netns.

        2. Start `IPRoute` instance. It will be used only on the low level,
           the `IPRoute` will not parse any packet.

        3. Start poll/select loop on `cmdch` and `IPRoute`.

    On the startup, the server sends via `cmdch` the status packet. It can be
    `None` if all is OK, or some exception.

    Further data handling, depending on the channel, server side::

        1. `IPRoute`: read an incoming netlink packet and send it unmodified
           to the peer via `rcvch`. The peer, polling `rcvch`, can handle
           the packet on its side.

        2. `cmdch`: read tuple (cmd, argv, kwarg). If the `cmd` starts with
           "send", then take `argv[0]` as a packet buffer, treat it as one
           netlink packet and substitute PID field (offset 12, uint32) with
           its own. Strictly speaking, it is not mandatory for modern netlink
           implementations, but it is required by the protocol standard.

    '''
    signal.signal(signal.SIGINT, signal.SIG_IGN)
    try:
        nsfd = setns(netns, flags)
    except OSError as e:
        cmdch.send({'stage': 'init',
                    'error': e})
        return e.errno
    except Exception as e:
        cmdch.send({'stage': 'init',
                    'error': OSError(errno.ECOMM, str(e), netns)})
        return 255

    Server(cmdch, brdch)
    os.close(nsfd)
Example #16
0
    def test_router_info(self):
        print("Test Router_Info")
        router = self._create_router()

        # NVAssisten
        nv_assist = NVAssistent("eth0")
        nv_assist.create_namespace_vlan(router)
        # Set netns for the current process
        netns.setns(router.namespace_name)

        print("Get informations via ssh-commands ...")
        router_info = RouterInfo(router)
        router_info.start()
        router_info.join()

        print(str(router))

        # Close Namespaces and VLANs
        nv_assist.close()
Example #17
0
    def test_router_info(self):
        print("Test Router_Info")
        router = self._create_router()

        # NVAssisten
        nv_assist = NVAssistent("eth0")
        nv_assist.create_namespace_vlan(router)
        # Set netns for the current process
        netns.setns(router.namespace_name)

        print("Get informations via ssh-commands ...")
        router_info = RouterInfo(router)
        router_info.start()
        router_info.join()

        print(str(router))

        # Close Namespaces and VLANs
        nv_assist.close()
Example #18
0
    def _reboot_into_config(self, router: Router, q: Queue):
        print("Reboot Router into configmode ...")
        # Create NVAssistent
        nv_assist = NVAssistent("eth0")
        nv_assist.create_namespace_vlan(router)
        # Set netns for the current process
        netns.setns(router.namespace_name)

        # Reboot Router into configmode
        try:
            router_reboot = RouterReboot(router, configmode=True)
            router_reboot.start()
            router_reboot.join()
        except Exception as e:
            nv_assist.close()
            raise e
        assert router.mode == Mode.configuration
        nv_assist.close()
        q.put(router)
Example #19
0
 def test_there_and_back(self):
     require_user('root')
     fd = open('/proc/self/ns/net', 'r')
     foo = str(uuid4())
     #
     # please notice, that IPRoute / IPDB, started in a netns, will continue
     # to work in a given netns even if the process changes to another netns
     #
     with IPRoute() as ip:
         links_main1 = set([x.get('index', None) for x in ip.get_links()])
     netnsmod.setns(foo)
     with IPRoute() as ip:
         links_foo = set([x.get('index', None) for x in ip.get_links()])
     netnsmod.setns(fd)
     with IPRoute() as ip:
         links_main2 = set([x.get('index', None) for x in ip.get_links()])
     assert links_main1 == links_main2
     assert links_main1 != links_foo
     netnsmod.remove(foo)
     fd.close()
Example #20
0
            def in_cgroup():
                try:
                    pid = os.getpid()
                    cg = Cgroup(name)
                    for env in env_vars:
                        #log.info('Setting ENV %s' % env)
                        os.putenv(*env.split('=', 1))

                    # Set network namespace
                    netns.setns(netns_name)

                    # add process to cgroup
                    cg.add(pid)

                    os.chroot(layer_dir)
                    if working_dir != '':
                        #log.info("Setting working directory to %s" % working_dir)
                        os.chdir(working_dir)
                except Exception as e:
                    traceback.print_exc()
Example #21
0
def NSPopenServer(nsname, flags, channel_in, channel_out, argv, kwarg):
    # set netns
    try:
        setns(nsname, flags=flags)
    except Exception as e:
        channel_out.put(e)
        return
    # create the Popen object
    child = subprocess.Popen(*argv, **kwarg)
    # send the API map
    channel_out.put(None)

    while True:
        # synchronous mode
        # 1. get the command from the API
        try:
            call = channel_in.get()
        except:
            (et, ev, tb) = sys.exc_info()
            try:
                channel_out.put({'code': 500, 'data': ev})
            except:
                pass
            break

        # 2. stop?
        if call['name'] == 'release':
            break

        # 3. run the call
        try:
            attr = getattr(child, call['name'])
            if isinstance(attr, types.MethodType):
                result = attr(*call['argv'], **call['kwarg'])
            else:
                result = attr
            channel_out.put({'code': 200, 'data': result})
        except:
            (et, ev, tb) = sys.exc_info()
            channel_out.put({'code': 500, 'data': ev})
    child.wait()
Example #22
0
    def __init__(self, netns, flags=os.O_CREAT):
        self.netns = netns
        self.flags = flags
        trnsp_in, self.remote_trnsp_out = [Transport(FD(x))
                                           for x in os.pipe()]
        self.remote_trnsp_in, trnsp_out = [Transport(FD(x))
                                           for x in os.pipe()]

        self.child = os.fork()
        if self.child == 0:
            # child process
            trnsp_in.close()
            trnsp_out.close()
            try:
                setns(self.netns, self.flags)
            except OSError as e:
                (self
                 .remote_trnsp_out
                 .send({'stage': 'init', 'error': e}))
                os._exit(e.errno)
            except Exception as e:
                (self.
                 remote_trnsp_out
                 .send({'stage': 'init',
                        'error': OSError(errno.ECOMM,
                                         str(e),
                                         self.netns)}))
                os._exit(255)

            try:
                Server(self.remote_trnsp_in, self.remote_trnsp_out)
            finally:
                os._exit(0)

        try:
            super(NetNS, self).__init__(trnsp_in, trnsp_out)
        except Exception:
            self.close()
            raise
        atexit.register(self.close)
        self.marshal = MarshalRtnl()
Example #23
0
    def test_router_online(self):
        print("Test if the Router is reachable")
        router = self._create_router()
        # NVAssisten
        nv_assist = NVAssistent("eth0")
        nv_assist.create_namespace_vlan(router)
        # Set netns for the current process
        netns.setns(router.namespace_name)

        print("Send a Ping to the two static IP-addresses ...")
        router_online = RouterOnline(router)
        router_online.start()
        router_online.join()

        print("Router is online with IP " + router.ip + "/" +
              str(router.ip_mask))

        self.assertEqual(router.mode, Mode.configuration,
                         "The Configuration Mode is not correct")

        # Close Namespaces and VLANs
        nv_assist.close()
Example #24
0
                def in_cgroup():
                    try:
                        pid = os.getpid()
                        cg = Cgroup(name)
                        for env in env_vars:
                            log.info('Setting ENV %s' % env)
                            os.putenv(*env.split('=', 1))

                        # Set network namespace
                        netns.setns(netns_name)

                        # add process to cgroup
                        cg.add(pid)

                        os.chroot(layer_dir)
                        if working_dir != '':
                            log.info("Setting working directory to %s" % working_dir)
                            os.chdir(working_dir)
                    except Exception as e:
                        traceback.print_exc()
                        log.error("Failed to preexecute function")
                        log.error(e)
Example #25
0
    def __init__(self, netns, flags=os.O_CREAT):
        self.netns = netns
        self.flags = flags
        trnsp_in, self.remote_trnsp_out = [Transport(FD(x)) for x in os.pipe()]
        self.remote_trnsp_in, trnsp_out = [Transport(FD(x)) for x in os.pipe()]

        self.child = os.fork()
        if self.child == 0:
            # child process
            trnsp_in.close()
            trnsp_out.close()
            try:
                setns(self.netns, self.flags)
            except OSError as e:
                (self.remote_trnsp_out.send({'stage': 'init', 'error': e}))
                os._exit(e.errno)
            except Exception as e:
                (self.remote_trnsp_out.send({
                    'stage':
                    'init',
                    'error':
                    OSError(errno.ECOMM, str(e), self.netns)
                }))
                os._exit(255)

            try:
                Server(self.remote_trnsp_in, self.remote_trnsp_out)
            finally:
                os._exit(0)

        try:
            self.remote_trnsp_in.close()
            self.remote_trnsp_out.close()
            super(NetNS, self).__init__(trnsp_in, trnsp_out)
        except Exception:
            self.close()
            raise
        atexit.register(self.close)
        self.marshal = MarshalRtnl()
Example #26
0
	def single(self, ns):
		self.signal()
		netns.setns(ns)

		k = ns + '_' + self.check

		c = pycurl.Curl()
		c.setopt(pycurl.WRITEFUNCTION, lambda x: None)
		c.setopt(c.FOLLOWLOCATION, 1)
		c.setopt(c.MAXREDIRS, 5)
		c.setopt(c.OPT_FILETIME, 1)
		c.setopt(pycurl.CONNECTTIMEOUT, 15)
		c.setopt(pycurl.TIMEOUT, 30)
		c.setopt(pycurl.NOSIGNAL, 1)

		while True:
			self.results[k] = { 'check': self.check, 'type': self.type, 'ns': ns, 'state': 'RUN' }
			res = self.results[k]

			try:
				c.setopt(c.URL, self.host)
				c.perform()

				res['code'] = c.getinfo(c.HTTP_CODE)
				res['time'] = c.getinfo(c.TOTAL_TIME)
				res['speed'] = c.getinfo(c.SPEED_DOWNLOAD)
				res['size'] = c.getinfo(c.SIZE_DOWNLOAD)
				res['state'] = 'OK'

				logging.info("[HTTP:%s] host = %s, return code = %d, total time = %.2f sec, download speed = %.2f b/sec, download size = %d Kb" % (ns, self.host, c.getinfo(c.HTTP_CODE), c.getinfo(c.TOTAL_TIME), c.getinfo(c.SPEED_DOWNLOAD), c.getinfo(c.SIZE_DOWNLOAD) / 1024))
			except:
				res['state'] = 'FAIL'

				logging.info("[HTTP:%s] Cannot get %s" % (ns, self.host))

			self.results[k] = res

			time.sleep(float(self.delay))
Example #27
0
 def test_there_and_back(self):
     require_user('root')
     # wait until the previous test's side effects are gone
     time.sleep(2)
     #
     fd = open('/proc/self/ns/net', 'r')
     foo = str(uuid4())
     #
     # please notice, that IPRoute / IPDB, started in a netns, will continue
     # to work in a given netns even if the process changes to another netns
     #
     with IPRoute() as ip:
         links_main1 = set([x.get('index', None) for x in ip.get_links()])
     netnsmod.setns(foo)
     with IPRoute() as ip:
         links_foo = set([x.get('index', None) for x in ip.get_links()])
     netnsmod.setns(fd)
     with IPRoute() as ip:
         links_main2 = set([x.get('index', None) for x in ip.get_links()])
     assert links_main1 == links_main2
     assert links_main1 != links_foo
     netnsmod.remove(foo)
     fd.close()
Example #28
0
 def __updatePvd(self, phyIfaceName, pvdInfo):
   pvd = self.pvds.get((phyIfaceName, pvdInfo.pvdId))
   if (pvd):
     if (pvd.pvdInfo == pvdInfo):
       # if PvD parameters did not change, just update the timestamp in the PvD manager's log
       pvd.updateTimestamp()
       LOG.info('PvD {0} received through {1} UNCHANGED, timestamp UPDATED, type {2}'.format(pvd.pvdId, pvd.phyIfaceName, pvd.pvdInfo.pvdType))
     else:
       # if any of the PvD parameters has changed, reconfigure the PvD
       netns.setns(pvd.netnsName)
       ip = IPRoute()
       # return to a default network namespace to not cause a colision with other modules
       # ip handle continues to work in the target network namespace
       netns.setns(self.__NETNS_DEFAULT_NAME)
       self.__configureNetwork(pvd.pvdIfaceName, pvdInfo, ip)
       self.__configureDns(pvdInfo, pvd.netnsName)
       # update the PvD record in the PvD manager's log
       pvd.pvdInfo = pvdInfo
       pvd.updateTimestamp()
       LOG.info('PvD {0} received through {1} RECONFIGURED in network namespace {2} on macvlan {3}, type {4}'.format(pvd.pvdId, pvd.phyIfaceName, pvd.netnsName, pvd.pvdIfaceName, pvd.pvdInfo.pvdType))
       self.pvdserver.stateChanged ("updated", pvdInfo.pvdId)
   else:
     raise Exception('There is no PvD {0} configured on {1}'.format(pvdInfo.pvdId, phyIfaceName))
Example #29
0
def in_namespace(namespace):
    """Move current process in a specific namespace.

    This contextmanager moves current process in a specific namespace and
    ensures to move it back in original namespace or kills it if we fail to
    move back in original namespace.
    """
    if not namespace:
        yield
        return

    org_netns_fd = os.open(PROCESS_NETNS, os.O_RDONLY)
    pynetns.setns(namespace)
    try:
        yield
    finally:
        try:
            # NOTE(cby): this code is not executed only if we fail to
            # move in target namespace
            pynetns.setns(org_netns_fd)
        except Exception as e:
            msg = _('Failed to move back in original netns: %s') % e
            LOG.critical(msg)
            raise BackInNamespaceExit(msg)
Example #30
0
def in_namespace(namespace):
    """Move current process in a specific namespace.

    This contextmanager moves current process in a specific namespace and
    ensures to move it back in original namespace or kills it if we fail to
    move back in original namespace.
    """
    if not namespace:
        yield
        return

    org_netns_fd = os.open(PROCESS_NETNS, os.O_RDONLY)
    pynetns.setns(namespace)
    try:
        yield
    finally:
        try:
            # NOTE(cby): this code is not executed only if we fail to
            # move in target namespace
            pynetns.setns(org_netns_fd)
        except Exception as e:
            msg = _('Failed to move back in original netns: %s') % e
            LOG.critical(msg)
            raise BackInNamespaceExit(msg)
Example #31
0
def NetNServer(netns, rcvch, cmdch, flags=os.O_CREAT):
    '''
    The netns server supposed to be started automatically by NetNS.
    It has two communication channels: one simplex to forward incoming
    netlink packets, `rcvch`, and other synchronous duplex to get
    commands and send back responses, `cmdch`.

    Channels should support standard socket API, should be compatible
    with poll/select and should be able to transparently pickle objects.
    NetNS uses `multiprocessing.Pipe` for this purpose, but it can be
    any other implementation with compatible API.

    The first parameter, `netns`, is a netns name. Depending on the
    `flags`, the netns can be created automatically. The `flags` semantics
    is exactly the same as for `open(2)` system call.

    ...

    The server workflow is simple. The startup sequence::

        1. Create or open a netns.

        2. Start `IPRoute` instance. It will be used only on the low level,
           the `IPRoute` will not parse any packet.

        3. Start poll/select loop on `cmdch` and `IPRoute`.

    On the startup, the server sends via `cmdch` the status packet. It can be
    `None` if all is OK, or some exception.

    Further data handling, depending on the channel, server side::

        1. `IPRoute`: read an incoming netlink packet and send it unmodified
           to the peer via `rcvch`. The peer, polling `rcvch`, can handle
           the packet on its side.

        2. `cmdch`: read tuple (cmd, argv, kwarg). If the `cmd` starts with
           "send", then take `argv[0]` as a packet buffer, treat it as one
           netlink packet and substitute PID field (offset 12, uint32) with
           its own. Strictly speaking, it is not mandatory for modern netlink
           implementations, but it is required by the protocol standard.

    '''
    try:
        nsfd = setns(netns, flags)
    except OSError as e:
        cmdch.send(e)
        return e.errno
    except Exception as e:
        cmdch.send(OSError(errno.ECOMM, str(e), netns))
        return 255

    #
    try:
        ipr = IPRoute()
        rcvch_lock = ipr._sproxy.lock
        ipr._s_channel = rcvch
        poll = select.poll()
        poll.register(ipr, select.POLLIN | select.POLLPRI)
        poll.register(cmdch, select.POLLIN | select.POLLPRI)
    except Exception as e:
        cmdch.send(e)
        return 255

    # all is OK so far
    cmdch.send(None)
    # 8<-------------------------------------------------------------
    while True:
        events = poll.poll()
        for (fd, event) in events:
            if fd == ipr.fileno():
                bufsize = ipr.getsockopt(SOL_SOCKET, SO_RCVBUF) // 2
                with rcvch_lock:
                    rcvch.send(ipr.recv(bufsize))
            elif fd == cmdch.fileno():
                try:
                    cmdline = cmdch.recv()
                    if cmdline is None:
                        poll.unregister(ipr)
                        poll.unregister(cmdch)
                        ipr.close()
                        os.close(nsfd)
                        return
                    (cmd, argv, kwarg) = cmdline
                    if cmd[:4] == 'send':
                        # Achtung
                        #
                        # It's a hack, but we just have to do it: one
                        # must use actual pid in netlink messages
                        #
                        # FIXME: there can be several messages in one
                        # call buffer; but right now we can ignore it
                        msg = argv[0][:12]
                        msg += struct.pack("I", os.getpid())
                        msg += argv[0][16:]
                        argv = list(argv)
                        argv[0] = msg
                    cmdch.send(getattr(ipr, cmd)(*argv, **kwarg))
                except Exception as e:
                    e.tb = traceback.format_exc()
                    cmdch.send(e)
Example #32
0
def exec_ns(ns_name, cmd):
    netns.setns(ns_name)
    subprocess.Popen(cmd)
Example #33
0
def main(argv):
    if (len(argv) !=  2):
        print('Usage: python pvdtest_veth.py PVD_ID')
        print('PVD_ID := name of the interface that contains PvD-related network configuration')
        sys.exit()

    # Get user-entered PVD ID
    pvdId = sys.argv[1]
    
    # Create IPRoute object for manipulation with a default network namespace
    ipMain = IPRoute()

    # Create a PvD-related network namespace
    pvdNetnsName = getPvdNetnsName(pvdId);
    if (pvdNetnsName in netns.listnetns()):
        netns.remove(pvdNetnsName)
    netns.create(pvdNetnsName)

    # Create IPRoute object for manipulation with a PvD-related network namespace
    netns.setns(pvdNetnsName)
    ipPvd = IPRoute()

    # Activate loopback interface in a PvD-related network namespace
    loIndex = ipPvd.link_lookup(ifname='lo')[0]
    ipPvd.link_up(loIndex)

    # Get addresses from a PvD-related network interface
    pvdIfIndex = ipMain.link_lookup(ifname=getPvdIfName(pvdId))[0]
    pvdAddresses = ipMain.get_addr(index=pvdIfIndex)

    # Get current routes
    pvdRoutes = ipMain.get_routes()

    # Create bridge
    bridge = getPvdBridgeName(pvdId)
    ipMain.link_create(ifname=bridge, kind='bridge')

    # Create veth interface
    (veth0, veth1) = getPvdVethNames(pvdId)
    ipMain.link_create(ifname=veth0, kind='veth', peer=veth1)

    # Move one end of the veth interafce to a PvD-related network namespace
    veth1Index = ipMain.link_lookup(ifname=veth1)[0]
    ipMain.link('set', index=veth1Index, net_ns_fd=pvdNetnsName)

    # Shut down and remove addresses from the PvD interface before adding it to the bridge
    ipMain.link_down(pvdIfIndex)
    ipMain.flush_addr(pvdIfIndex)

    # Make a bridge between PvD interface and one end of veth interface
    veth0Index = ipMain.link_lookup(ifname=veth0)[0]
    bridgeIndex = ipMain.link_lookup(ifname=bridge)[0]
    ipMain.link('set', index=veth0Index, master=bridgeIndex)
    ipMain.link('set', index=pvdIfIndex, master=bridgeIndex)

    # Activate bridge and connected interfaces
    ipMain.link_up(pvdIfIndex)
    ipMain.link_up(veth0Index)
    ipMain.link_up(bridgeIndex)
    ipPvd.link_up(veth1Index)

    # Configure bridge and another end of the veth interface with PvD-related network parameters + add routes
    ipMain.flush_routes()
    ipPvd.flush_routes()
    for address in pvdAddresses:
        ipAddress = broadcastAddress = netmask = addrFamily = None
        for attr in address['attrs']:
            if attr[0] == 'IFA_ADDRESS':
                ipAddress = attr[1]
            if attr[0] == 'IFA_BROADCAST':
                broadcastAddress = attr[1]
        netmask = address['prefixlen']
        addrFamily = address['family']
        # Configure bridge
        try:
            ipMain.addr('add', index=bridgeIndex, family=addrFamily, address=ipAddress, broadcast=broadcastAddress, mask=netmask)
        except:
            pass
        # Configure veth
        try:
            ipPvd.addr('add', index=veth1Index, family=addrFamily, address=ipAddress, broadcast=broadcastAddress, mask=netmask)
        except:
            pass
        # Configure routes
        # Some routes are added during interface IP address/netmask configuration, skip them if already there
        ipNetwork = IPNetwork(ipAddress + '/' + str(netmask))
        try:
            ipMain.route('add', dst=str(ipNetwork.network), mask=netmask, oif=bridgeIndex, src=ipAddress, rtproto='RTPROT_STATIC', rtscope='RT_SCOPE_LINK')
        except:
            pass
        try:
            ipPvd.route('add', dst=str(ipNetwork.network), mask=netmask, oif=veth1Index, src=ipAddress, rtproto='RTPROT_STATIC', rtscope='RT_SCOPE_LINK')
        except:
            pass

    # Fing gateway(s) and add default routes
    defGateways = []
    for route in pvdRoutes:
        for attr in route['attrs']:
            if (attr[0] == 'RTA_GATEWAY' and attr[1] not in defGateways):
                defGateways.append(attr[1])
    if (len(defGateways) > 0):
        ipMain.route('add', dst='0.0.0.0', oif=bridgeIndex, gateway=defGateways[0], rtproto='RTPROT_STATIC')
        ipPvd.route('add', dst='0.0.0.0', oif=veth1Index, gateway=defGateways[0], rtproto='RTPROT_STATIC')
Example #34
0
def NetNServer(netns, rcvch, cmdch, flags=os.O_CREAT):
    '''
    The netns server supposed to be started automatically by NetNS.
    It has two communication channels: one simplex to forward incoming
    netlink packets, `rcvch`, and other synchronous duplex to get
    commands and send back responses, `cmdch`.

    Channels should support standard socket API, should be compatible
    with poll/select and should be able to transparently pickle objects.
    NetNS uses `multiprocessing.Pipe` for this purpose, but it can be
    any other implementation with compatible API.

    The first parameter, `netns`, is a netns name. Depending on the
    `flags`, the netns can be created automatically. The `flags` semantics
    is exactly the same as for `open(2)` system call.

    ...

    The server workflow is simple. The startup sequence::

        1. Create or open a netns.

        2. Start `IPRoute` instance. It will be used only on the low level,
           the `IPRoute` will not parse any packet.

        3. Start poll/select loop on `cmdch` and `IPRoute`.

    On the startup, the server sends via `cmdch` the status packet. It can be
    `None` if all is OK, or some exception.

    Further data handling, depending on the channel, server side::

        1. `IPRoute`: read an incoming netlink packet and send it unmodified
           to the peer via `rcvch`. The peer, polling `rcvch`, can handle
           the packet on its side.

        2. `cmdch`: read tuple (cmd, argv, kwarg). If the `cmd` starts with
           "send", then take `argv[0]` as a packet buffer, treat it as one
           netlink packet and substitute PID field (offset 12, uint32) with
           its own. Strictly speaking, it is not mandatory for modern netlink
           implementations, but it is required by the protocol standard.

    '''
    signal.signal(signal.SIGINT, signal.SIG_IGN)
    try:
        nsfd = setns(netns, flags)
    except OSError as e:
        cmdch.send(e)
        return e.errno
    except Exception as e:
        cmdch.send(OSError(errno.ECOMM, str(e), netns))
        return 255

    #
    try:
        ipr = IPRoute()
        rcvch_lock = ipr._sproxy.lock
        ipr._s_channel = rcvch
        poll = select.poll()
        poll.register(ipr, select.POLLIN | select.POLLPRI)
        poll.register(cmdch, select.POLLIN | select.POLLPRI)
    except Exception as e:
        cmdch.send(e)
        return 255

    # all is OK so far
    cmdch.send(None)
    # 8<-------------------------------------------------------------
    while True:
        events = poll.poll()
        for (fd, event) in events:
            if fd == ipr.fileno():
                bufsize = ipr.getsockopt(SOL_SOCKET, SO_RCVBUF) // 2
                with rcvch_lock:
                    rcvch.send(ipr.recv(bufsize))
            elif fd == cmdch.fileno():
                try:
                    cmdline = cmdch.recv()
                    if cmdline is None:
                        poll.unregister(ipr)
                        poll.unregister(cmdch)
                        ipr.close()
                        os.close(nsfd)
                        return
                    (cmd, argv, kwarg) = cmdline
                    if cmd[:4] == 'send':
                        # Achtung
                        #
                        # It's a hack, but we just have to do it: one
                        # must use actual pid in netlink messages
                        #
                        # FIXME: there can be several messages in one
                        # call buffer; but right now we can ignore it
                        msg = argv[0][:12]
                        msg += struct.pack("I", os.getpid())
                        msg += argv[0][16:]
                        argv = list(argv)
                        argv[0] = msg
                    cmdch.send(getattr(ipr, cmd)(*argv, **kwarg))
                except Exception as e:
                    e.tb = traceback.format_exc()
                    cmdch.send(e)
Example #35
0
 def preexec():
     cgroup.add(os.getpid())
     netns.setns(netns_names.netns)
Example #36
0
def Server(trnsp_in, trnsp_out, netns=None, target='localhost'):
    def stop_server(signum, frame):
        Server.run = False

    Server.run = True
    signal.signal(signal.SIGTERM, stop_server)

    try:
        if netns is not None:
            netnsmod.setns(netns)
        ipr = IPRoute(target=target)
        lock = ipr._sproxy.lock
        ipr._s_channel = ProxyChannel(trnsp_out, 'broadcast')
    except Exception as e:
        trnsp_out.send({'stage': 'init', 'error': e})
        return 255

    inputs = [ipr.fileno(), trnsp_in.fileno()]
    broadcasts = {ipr.fileno(): ipr}
    outputs = []

    # all is OK so far
    trnsp_out.send({'stage': 'init', 'uname': config.uname, 'error': None})

    # 8<-------------------------------------------------------------
    while Server.run:
        try:
            events, _, _ = select.select(inputs, outputs, inputs)
        except:
            continue
        for fd in events:
            if fd in broadcasts:
                sock = broadcasts[fd]
                bufsize = sock.getsockopt(SOL_SOCKET, SO_RCVBUF) // 2
                with lock:
                    error = None
                    data = None
                    try:
                        data = sock.recv(bufsize)
                    except Exception as e:
                        error = e
                        error.tb = traceback.format_exc()
                    trnsp_out.send({
                        'stage': 'broadcast',
                        'data': data,
                        'error': error
                    })
            elif fd == trnsp_in.fileno():
                cmd = trnsp_in.recv_cmd()
                if cmd['stage'] == 'shutdown':
                    ipr.close()
                    data = struct.pack('IHHQIQQ', 28, 2, 0, 0, 104, 0, 0)
                    trnsp_out.send({
                        'stage': 'broadcast',
                        'data': data,
                        'error': None
                    })
                    return
                elif cmd['stage'] == 'reconstruct':
                    error = None
                    try:
                        msg = cmd['argv'][0]()
                        msg.load(pickle.loads(cmd['argv'][1]))
                        ipr.sendto_gate(msg, cmd['argv'][2])
                    except Exception as e:
                        error = e
                        error.tb = traceback.format_exc()
                    trnsp_out.send({
                        'stage': 'reconstruct',
                        'error': error,
                        'return': None,
                        'cookie': cmd['cookie']
                    })

                elif cmd['stage'] == 'command':
                    error = None
                    try:
                        ret = getattr(ipr, cmd['name'])(*cmd['argv'],
                                                        **cmd['kwarg'])
                        if cmd['name'] == 'bind' and \
                                ipr._brd_socket is not None:
                            inputs.append(ipr._brd_socket.fileno())
                            broadcasts[ipr._brd_socket.fileno()] = \
                                ipr._brd_socket
                    except Exception as e:
                        ret = None
                        error = e
                        error.tb = traceback.format_exc()
                    trnsp_out.send({
                        'stage': 'command',
                        'error': error,
                        'return': ret,
                        'cookie': cmd['cookie']
                    })