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
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")
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
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
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
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()
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
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()
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
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)
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
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
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}")
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()
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
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']})
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
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
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
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)
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')