Exemple #1
0
def get_ipdb(netns=None):
    if netns:
        netns = utils.convert_netns(netns)
        ipdb = pyroute2.IPDB(nl=pyroute2.NetNS(netns))
    else:
        ipdb = pyroute2.IPDB()
    return ipdb
Exemple #2
0
def netns_with_veth():
    """High level API for netns based debugging"""

    assert os.getuid() == 0

    # Configure namespace and interfaces
    ip = pyroute2.IPDB()
    ip.create(kind="veth", ifname="pycoz0", peer="pycoz1")
    ip.commit()

    ns = pyroute2.IPDB(nl=pyroute2.NetNS("pycoz"))

    with ip.interfaces.pycoz0 as veth:
        veth.net_ns_fd = "pycoz"
    with ns.interfaces.pycoz0 as veth:
        veth.add_ip("192.168.0.1/24")
        veth.up()
    with ip.interfaces.pycoz1 as veth:
        veth.add_ip("192.168.0.2/24")
        veth.up()

    ip.release()
    ns.release()

    # Switch namespace
    pyroute2.netns.setns("pycoz")
Exemple #3
0
def get_ipdb(netns=None):
    try:
        return _IPDB[netns]
    except KeyError:
        if netns:
            ipdb = pyroute2.IPDB(nl=pyroute2.NetNS(netns))
        else:
            ipdb = pyroute2.IPDB()
    _IPDB[netns] = ipdb
    return ipdb
Exemple #4
0
def get_routing_table(ip_version, namespace=None):
    """Return a list of dictionaries, each representing a route.

    :param ip_version: IP version of routes to return, for example 4
    :param namespace: The name of the namespace from which to get the routes
    :return: a list of dictionaries, each representing a route.
    The dictionary format is: {'destination': cidr,
                               'nexthop': ip,
                               'device': device_name,
                               'scope': scope}
    """
    family = _IP_VERSION_FAMILY_MAP[ip_version]
    try:
        netns = pyroute2.NetNS(namespace, flags=0) if namespace else None
    except OSError as e:
        if e.errno == errno.ENOENT:
            raise NetworkNamespaceNotFound(netns_name=namespace)
        raise
    with pyroute2.IPDB(nl=netns) as ipdb:
        ipdb_routes = ipdb.routes
        ipdb_interfaces = ipdb.interfaces
        routes = [{'destination': route['dst'],
                   'nexthop': route.get('gateway'),
                   'device': ipdb_interfaces[route['oif']]['ifname'],
                   'scope': _get_scope_name(route['scope'])}
                  for route in ipdb_routes if route['family'] == family]
    return routes
Exemple #5
0
def _get_addr_interface(addr: IPv4Address):
    ipdb = pyroute2.IPDB()
    for idx, addresses in ipdb.ipaddr.items():
        for ifaddr, prefix in addresses:
            if ip_address(ifaddr) == addr:
                return ipdb.by_index[idx]['ifname']
    return None
Exemple #6
0
    def __init__(self):
        self.host_ns = pyroute2.NetNS('host')
        self.ipdb = pyroute2.IPDB(nl=self.host_ns)
        self.dockerc = docker.from_env()

        self.challenges = {}
        self.challenges_lock = threading.RLock()
def main(args):
    flags = 0

    if len(sys.argv) == 2:
        device = sys.argv[1]

    elif len(sys.argv) == 3:
        if "-S" in sys.argv:
            # XDP_FLAGS_SKB_MODE
            flags |= 2 << 0

        if "-S" == sys.argv[1]:
            device = sys.argv[2]
        else:
            device = sys.argv[1]

    else:
        print("Usage: {0} [-S] <ifdev>".format(sys.argv[0]))
        print("       -S: use skb mode\n")
        print("e.g.: {0} eth0\n".format(sys.argv[0]))
        return 1

    mode = BPF.XDP
    #mode = BPF.SCHED_CLS

    if mode == BPF.XDP:
        ret = "XDP_DROP"
        ctxtype = "xdp_md"
    else:
        ret = "TC_ACT_SHOT"
        ctxtype = "__sk_buff"

    # load BPF program
    with open('syn_flood_mitigator.c') as f:
        lines = f.read()

    # load BPF program
    b = BPF(text=lines, cflags=["-w"], debug=0)

    fn = b.load_func("xdp_program", mode)

    if mode == BPF.XDP:
        print("BPF_XDP")
        b.attach_xdp(device, fn, flags)

        bpf_logic(b)

    else:
        ip = pyroute2.IPRoute()
        ipdb = pyroute2.IPDB(nl=ip)
        idx = ipdb.interfaces[device].index
        ip.tc("add", "clsact", idx)
        ip.tc("add-filter", "bpf", idx, ":1", fd=fn.fd, name=fn.name,
              parent="ffff:fff2", classid=1, direct_action=True)

    if mode == BPF.XDP:
        b.remove_xdp(device, flags)
    else:
        ip.tc("del", "clsact", idx)
        ipdb.release()
Exemple #8
0
def ip_ifaces(version=4):
    '''return the list of ips corresponding to each NIC'''
    with pyroute2.IPDB() as ipdb:
        for ifname, data in ipdb.by_name.items():
            for addr in utils.iter_addrs(data):
                if addr.version == version and not addr.is_link_local:
                    yield ifname, addr
	def send_rs ( self, pvdId = None, iface = None, src = None, dest = None ):
		'''Send Router-Solicitation message'''
		_iface = iface or self.iface
		if not _iface:
			# error, or should RS be sent to all interfaces by default?
			LOG.error("Interface must be provided for RS!")
			return None

		_src = src or self.__lla
		if not _src:
			# get ip address from interface with pyroute2
			ip = pyroute2.IPDB()
			if _iface in ip.interfaces and 'ipaddr' in ip.interfaces[_iface]:
				for i in range(len(ip.interfaces[_iface]['ipaddr'])):
					a = ip.interfaces[_iface]['ipaddr'][i]
					if 'address' in a:
						ipaddr = ipaddress.ip_address ( a['address'] )
						if ipaddr.is_link_local and ipaddr.version == 6:
							_src = a['address']
							break
			if not _src:
				LOG.error("Source address must be provided!")
				return None

		msg = NdpMsg.create_rs ( src = _src, dest = dest, pvdId = pvdId, iface = _iface )
		addr = ( msg.dest, 0, 0, socket.if_nametoindex(_iface) )
		self.__sock.sendto ( msg.packet, addr )
		return msg
Exemple #10
0
def bridge_iface_together(*args, **kwargs):
    """
    :param args: list of interface names to add to the bridge
    :param kwargs: keyword argument "bridge" allows the caller to specify to which bridge the interfaces must be added. If not specified, a new bridge is created, and named
    :return:
    """
    with pyroute2.IPDB() as ipdb:
        if 'bridge' in kwargs and not isinstance(kwargs['bridge'], type(None)):
            br = ipdb.interfaces[kwargs['bridge']]
        else:
            # Get a new bridge identifier
            l = ([
                int(x[len('pwbr'):]) for x in ipdb.interfaces.keys()
                if isinstance(x, str) and x.startswith('pwbr')
            ])
            if len(l) == 0:
                i = 0
            else:
                i = max(l) + 1
            br = ipdb.create(kind='bridge', ifname='pwbr{}'.format(i))
            br.up()
        # Create the new bridge and add the two interfaces in it
        for a in args:
            br.add_port(a)
        ipdb.commit()
        return br.ifname
    def run(self):
        if not self.is_alive():
            print("Printing, hit CTRL+C to stop")

        # use print_raw if executed as a child
        fields = [
            'layer', 'ts', 'guid', 'seqnum', 'msg_id', 'saddr', 'sport',
            'daddr', 'dport'
        ]
        fmtstr = '{:<20} {:<13.5f} {:<40} {:<7d} {:<10} {:<#12x} {:<#12x} {:<#12x} {:<#12x}'
        self.log = sofa_ros2_utilities.Log(
            fields=fields,
            fmtstr=fmtstr,
            cvsfilename=os.path.join(self.cfg.logdir, self.cfg.ros2logdir,
                                     'cls_bpf_log.csv'),
            print_raw=self.is_alive())

        b = self.b
        fn_egress = b.load_func("cls_ros2_egress_prog", mode)
        fn_ingress = b.load_func("cls_ros2_ingress_prog", mode)

        ip = pyroute2.IPRoute()
        ipdb = pyroute2.IPDB(nl=ip)
        idx = ipdb.interfaces[device].index
        ip.tc("add", "clsact", idx)
        # add egress clsact
        ip.tc("add-filter",
              "bpf",
              idx,
              ":1",
              fd=fn_egress.fd,
              name=fn_egress.name,
              parent="ffff:fff3",
              classid=1,
              direct_action=True)
        # add ingress clsact
        ip.tc("add-filter",
              "bpf",
              idx,
              ":1",
              fd=fn_ingress.fd,
              name=fn_ingress.name,
              parent="ffff:fff2",
              classid=1,
              direct_action=True)

        b["cls_egress"].open_perf_buffer(self.print_cls_egress)
        b["cls_ingress"].open_perf_buffer(self.print_cls_ingress)
        while not self.set.is_set():
            try:
                b.perf_buffer_poll(timeout=1000)
            except KeyboardInterrupt:
                print('')
                break
        print("[trace_tc_act] Removing filter from device")
        self.log.close()

        ip.tc("del", "clsact", idx)
        ipdb.release()
Exemple #12
0
    def __init__(self, config):
        lg.LookingGlassLocalLogger.__init__(self)

        self.log.info("Initializing MPLSLinuxVRFDataplane")
        dp_drivers.DataplaneDriver.__init__(self, config)

        self.config = config
        self.ip = pyroute2.IPDB()  # pylint: disable=no-member
Exemple #13
0
def main():
    hostname_list = sys.argv[1:]

    logging.info('Adding current interfaces')
    dispatcher = Dispatcher(hostname_list)
    with pyroute2.IPRoute() as netlink_route:
        for interface in netlink_route.get_links():
            dispatcher.add_interface(interface['index'],
                                     dict(interface['attrs'])['IFLA_IFNAME'])

    def ipdb_callback(ipdb, msg, action):
        logging.debug('NETLINK event: %s, %s' % (repr(msg), action))

        if action == 'RTM_NEWLINK':
            ifindex = msg['index']
            ifname = ipdb.interfaces[ifindex]['ifname']
            dispatcher.add_interface(ifindex, ifname)
            return

        if action == 'RTM_DELLINK':
            ifindex = msg['index']
            dispatcher.remove_interface(ifindex)
            return

        if action in ['RTM_NEWADDR', 'RTM_DELADDR']:
            ifindex = msg['index']
            ifname = ipdb.interfaces[ifindex]['ifname']
            dispatcher.update_addresses(ifindex, ifname)
            return

    ipdb = pyroute2.IPDB()
    ipdb_cb = ipdb.register_callback(ipdb_callback)

    termination_event = Event()

    import signal

    def signal_handler(signum, frame):
        logging.warning('Received signal %s. Exiting' % signum)
        termination_event.set()

    signal.signal(signal.SIGTERM, signal_handler)
    signal.signal(signal.SIGINT, signal_handler)
    signal.signal(signal.SIGHUP, signal_handler)

    while True:
        try:
            if termination_event.wait(60):
                logging.info('Event triggered. Shutting down ...')
                break
            logging.info('Still working ...')
        except (InterruptedError, KeyboardInterrupt):
            logging.info('Interrupt received. Shutting down ...')
            break

    ipdb.unregister_callback(ipdb_cb)
    ipdb.release()
    dispatcher.shutdown()
 def _flush_ip_addresses(self):
     """
 Delete all IP addresses from the interface.
 """
     log.debug(f"Removing all addresses from {self.interface}")
     ipdb = pyroute2.IPDB()
     with ipdb.interfaces[self.interface] as i:
         for addr in i.ipaddr:
             i.del_ip(*addr)
Exemple #15
0
    def is_valid(self, v):
        if v is None:
            return True

        if not HAS_PYROUTE2:
            return True

        with pyroute2.IPDB() as ipdb:
            return v in ipdb.interfaces
Exemple #16
0
def in_bridge(ifname):
    with pyroute2.IPDB() as ipdb:
        for iface in ipdb.interfaces:
            if (hasattr(iface, 'kind') and iface.kind == 'bridge'
                    and hasattr(iface, 'ports') and hasattr(iface, 'ifname')):
                for port in iface.ports:
                    if port.ifname == ifname:
                        return iface.ifname
    return None
    def _gather_interface_configuration(self):
        ipdb = pyroute2.IPDB()
        self.ip_addresses = []

        # Gather interface config
        with ipdb.interfaces[self.interface] as i:
            if i.ipaddr:
                self.ip_addresses.append(i.ipaddr[0])
            self.mtu = i.mtu
    def __init__(self):
        super(MPLSLinuxDataplaneDriver, self).__init__()

        self._run_command("modprobe mpls_router")
        self._run_command("modprobe mpls_gso")
        self._run_command("modprobe mpls_iptunnel")
        self._run_command("modprobe vrf")

        self.ip = pyroute2.IPDB()  # pylint: disable=no-member
Exemple #19
0
 def _is_if_on_bridge(self, ifname):
     with pyroute2.IPDB(plugins=('interfaces',)) as ipdb:
         try:
             for port_id in ipdb.interfaces[self.bridge_name].ports:
                 port = ipdb.interfaces[port_id]
                 if port.ifname == ifname:
                     return True
         except KeyError:
             return False
     return False
 def _create_bridge(self):
     ipdb = pyroute2.IPDB()
     if not self.br_interface in ipdb.interfaces:
         log.info(f"Creating bridge: {self.br_interface}")
         with ipdb.create(kind='bridge', ifname=self.br_interface) as i:
             i.up()
             i.add_port(ipdb.interfaces[self.tap_interface])
             i.add_port(ipdb.interfaces[self.interface])
     else:
         log.info(f"Not re-creating bridge: {self.br_interface}")
Exemple #21
0
def unbridge(brif):
    with pyroute2.IPDB() as ipdb:
        ports = copy.copy(ipdb.interfaces[brif].ports)
        ipdb.interfaces[brif].down()
        ipdb.commit()
        ipdb.interfaces[brif].remove()
        ipdb.commit()
        for port in ports:
            ipdb.interfaces[port].up()
        ipdb.commit()
Exemple #22
0
def activate_ex_intf():
    '''
    Activates the external interface.
    '''
    ipdb = pyroute2.IPDB(mode='explicit')
    ex_intf = get_external_interface()
    ex_gw_ip = get_external_gateway_ip()

    if ex_intf is None:
        return

    if ex_gw_ip is None:
        return

    if has_interface(ex_intf) is False:
        return

    try:
        ext_ip_address = "127.0.0.1/24"
        ext_mac_address = "02:11:22:33:44:55"
        empty_ip_address = "0.0.0.0"
        with ipdb.interfaces[ex_intf] as ext_iface:
            ipv4_addr = ext_iface.ipaddr.ipv4
            if not ipv4_addr:
                print "External interface does not have any IP address"
                return
            ext_ip_address = ipv4_addr[0]["address"] + '/' + str(
                ipv4_addr[0]["prefixlen"])
            ext_mac_address = ext_iface.address
            for addr in ext_iface.ipaddr:
                addr_str = '/'.join(map(str, addr))
                ext_iface.del_ip(addr_str)

        with ipdb.interfaces[EXT_BRIDGE] as ext_bridge_iface:
            for addr in ext_bridge_iface.ipaddr:
                addr_str = '/'.join(map(str, addr))
                ext_bridge_iface.del_ip(addr_str)

            ext_bridge_iface.add_ip(ext_ip_address)
            addr_config_str = 'other-config:hwaddr=\"' + ext_mac_address + '\"'
            if ext_bridge_iface.operstate == "DOWN":
                ext_bridge_iface.up()

            ovs_vsctl('set', 'bridge', EXT_BRIDGE, addr_config_str)

        intfs = ovs_vsctl('list-ifaces', EXT_BRIDGE)
        if ex_intf not in intfs:
            ovs_vsctl('add-port', EXT_BRIDGE, ex_intf)

    except Exception as e:
        raise SonaException(108,
                            "failure activate external interface " + str(e))
def get_veth_name_for_container(container_info):
    """Returns the name of the veth interface associated with the container

    :param container_info: the container info dictionary returned by Docker API
    :returns: the veth name as string
    """
    logger.info(container_info)
    if not os.path.exists(NETNS_PREFIX):
        os.mkdir(NETNS_PREFIX)
    pid = container_info['State']['Pid']
    proc_dir = PROC_TEMPLATE.format(pid)
    netns_symlink_path = NETNS_PREFIX + str(pid)
    veth_name = ''

    try:
        if not os.path.exists(netns_symlink_path):
            os.symlink(proc_dir, netns_symlink_path)
            logger.debug('Created a symlink {0}'.format(netns_symlink_path))
        container_netns = pyroute2.IPDB(nl=pyroute2.NetNS(str(pid)))

        main_netns = pyroute2.IPDB()
        try:
            logger.debug(container_netns.interfaces)
            # logger.debug(main_netns.interfaces)
            with container_netns.by_name['eth0'] as eth0:
                eth0_index = eth0['index']
                veth_index = eth0_index + 1
                with main_netns.by_index[veth_index] as veth:
                    veth_name = veth['ifname']
        finally:
            container_netns.release()
            main_netns.release()
    finally:
        if os.path.exists(netns_symlink_path):
            os.remove(netns_symlink_path)
            logger.debug('Deleted the symlink {0}'.format(netns_symlink_path))

    return veth_name
Exemple #24
0
def get_ipdb():
    """Returns the already cached or a newly created IPDB instance.

    IPDB reads the Linux specific file when it's instantiated. This behaviour
    prevents Mac OSX users from running unit tests. This function makes the
    loading IPDB lazyily and therefore it can be mocked after the import of
    modules that import this module.

    :returns: The already cached or newly created ``pyroute2.IPDB`` instance
    """
    global _IPDB_CACHE
    if not _IPDB_CACHE:
        _IPDB_CACHE = pyroute2.IPDB()
    return _IPDB_CACHE
    def _gather_routes(self):
        ipdb = pyroute2.IPDB()
        self.routes = []

        # Gather routes
        for route in ipdb.routes:
            if route['dst'] == 'default':
                dst = '0.0.0.0/0'
            else:
                dst = route['dst']

            if not route['gateway']:
                self.routes.append({"to": dst, "scope": "link"})
            else:
                self.routes.append({"to": dst, "via": route['gateway']})
Exemple #26
0
def get_default_gateway():
    """Returns the default gateway of this machine (container).

    This method is primarily intended for use communicating with
    ad-hoc Glot HTTP servers for file transfer (not an intended
    application of WAMP, so an alternative approach must be used).

    """
    if not pyroute2:
        return None

    ip = pyroute2.IPDB()
    gateway = ip.routes['default']['gateway']
    ip.release()

    return gateway
Exemple #27
0
def get_routing_table(ip_version, namespace=None):
    """Return a list of dictionaries, each representing a route.

    :param ip_version: IP version of routes to return, for example 4
    :param namespace: The name of the namespace from which to get the routes
    :return: a list of dictionaries, each representing a route.
    The dictionary format is: {'destination': cidr,
                               'nexthop': ip,
                               'device': device_name,
                               'scope': scope}
    """
    family = _IP_VERSION_FAMILY_MAP[ip_version]
    try:
        netns = pyroute2.NetNS(namespace, flags=0) if namespace else None
    except OSError as e:
        if e.errno == errno.ENOENT:
            raise NetworkNamespaceNotFound(netns_name=namespace)
        raise
    routes = []
    with pyroute2.IPDB(nl=netns) as ipdb:
        ipdb_routes = ipdb.routes
        ipdb_interfaces = ipdb.interfaces
        for route in ipdb_routes:
            if route['family'] != family:
                continue
            dst = route['dst']
            nexthop = route.get('gateway')
            oif = route.get('oif')
            scope = _get_scope_name(route['scope'])

            # If there is not a valid outgoing interface id, check if
            # this is a multipath route (i.e. same destination with
            # multiple outgoing interfaces)
            if oif:
                device = ipdb_interfaces[oif]['ifname']
                rt = _make_route_dict(dst, nexthop, device, scope)
                routes.append(rt)
            elif route.get('multipath'):
                for mpr in route['multipath']:
                    oif = mpr['oif']
                    device = ipdb_interfaces[oif]['ifname']
                    rt = _make_route_dict(dst, nexthop, device, scope)
                    routes.append(rt)

    return routes
Exemple #28
0
def find_best_route(dst_host, dev_list=None, version=4):
    '''
    Return the best IP and interface in a 'IpDevice' named tuple
    Use in order to reach a given destination IP

    Parameters
    ----------
    dst_host : string
        hostname or ip for which a socket addr is needed
    dev_list : list of strings, optional
        list of interface names to consider
    version : int, optional
        version number of IP protocol to use. Useful when providing
        a hostname as the dst_host to enforce IP version.

    Returns
    -------
    ifacename, ipaddr: tuple of (<interface name>, <ipaddr>)
    '''
    dst_host = utils.check_ipaddr(dst_host, version=version)[0]
    family = utils.version_to_family(version)

    RT_TABLE_MAIN = 254

    with pyroute2.IPDB() as ipdb:
        # We have to do it manually for now because the ipdb.routes API
        # to too buggy at the moment.
        routes = ipdb.nl.get_routes(family=family,
                                    dst=str(dst_host),
                                    table=RT_TABLE_MAIN)

        try:
            route = routes[0]
        except IndexError:
            raise RuntimeError('No suitable route found')

        rta_oif = route.get_attr('RTA_OIF')
        interface = ipdb.interfaces[rta_oif]

        for addr in utils.iter_addrs(interface):
            if addr.version == version and not addr.is_link_local:
                return interface['ifname'], addr.ip
Exemple #29
0
    def _create_and_plug_vxlan_if(self):
        # if a VXLAN interface, with the VNI we want to use, is already plugged
        # in the bridge, we want to reuse it
        with pyroute2.IPDB(plugins=('interfaces',)) as ipdb:
            for port_id in ipdb.interfaces[self.bridge_name].ports:
                port = ipdb.interfaces[port_id]
                if (port.kind == "vxlan" and
                        port.vxlan_id == self.instance_label):
                    self.log.info("reuse vxlan interface %s for VXLAN VNI %s",
                                  port.ifname, self.instance_label)
                    self.vxlan_if_name = port.ifname
                    return

        self.vxlan_if_name = (VXLAN_INTERFACE_PREFIX +
                              self.external_instance_id)[:consts.LINUX_DEV_LEN]

        self.log.debug("Creating and plugging VXLAN interface %s",
                       self.vxlan_if_name)

        if self._interface_exists(self.vxlan_if_name):
            self._remove_vxlan_if()

        dst_port_spec = ""
        if self.driver.config.vxlan_dst_port:
            dst_port_spec = ("dstport %d" %
                             self.driver.config.vxlan_dst_port)

        # Create VXLAN interface
        self._run_command(
            "ip link add %s type vxlan id %d local %s nolearning proxy %s" %
            (self.vxlan_if_name, self.instance_label,
             self.driver.get_local_address(), dst_port_spec),
            run_as_root=True
        )

        self._run_command("ip link set %s up" % self.vxlan_if_name,
                          run_as_root=True)

        # Plug VXLAN interface into bridge
        self._run_command("brctl addif %s %s" % (self.bridge_name,
                                                 self.vxlan_if_name),
                          run_as_root=True)
Exemple #30
0
    def initialize(self, configurationFile=None):
        """
        Initialize the probe.

        Returns:
        The probe name list.
        """
        self._logger.log(
            Logger.DEBUG_LEVEL, "/iproute/routing initialize"
            " configuration: %s" % configurationFile)

        self._ipdb = pyroute2.IPDB()

        self._mroute_regex = re.compile(
            r'\(([^,]+), ([^,]+)\)\s+Iif: ([^\s]+)\s+Oifs:(( [^\s]+){0,})')

        labels = [
            'Table', 'Dst', 'Pref Src', 'Priority', 'OIF', 'Gateway',
            'Dst Len', 'Proto', 'TOS'
        ]

        mcast_labels = ['Src', 'Group', 'IFace', 'OFaces']

        self._measurement4 = Measurement_iproute_routing_tables_ipv4()

        self._measurement4.routingtable.labels.extend(labels)

        self._measurement4.mcastroutingtable.labels.extend(mcast_labels)

        self._measurement6 = Measurement_iproute_routing_tables_ipv6()

        self._measurement6.routingtable.labels.extend(labels)

        self._measurement6.mcastroutingtable.labels.extend(mcast_labels)

        return ('IPRoute.Routing.Tables.IPv4', 'IPRoute.Routing.Tables.IPv6')