def test_get_devices_info_vlan(self): interfaces_tested = [] vlan_interfaces = [] vlan_id = 1000 for interface in self.interfaces: priv_ip_lib.create_interface(interface, self.namespace, 'dummy') vlan_interface = interface + '_' + str(vlan_id) vlan_interfaces.append(vlan_interface) priv_ip_lib.create_interface(vlan_interface, self.namespace, 'vlan', physical_interface=interface, vlan_id=vlan_id) vlan_id += 1 devices = priv_ip_lib.get_link_devices(self.namespace) self.assertGreater(len(devices), 0) for device in devices: name = ip_lib.get_attr(device, 'IFLA_IFNAME') if name in self.interfaces_to_exclude: continue self.assertIn(name, self.interfaces + vlan_interfaces) ifla_linkinfo = ip_lib.get_attr(device, 'IFLA_LINKINFO') if name in vlan_interfaces: self.assertEqual( ip_lib.get_attr(ifla_linkinfo, 'IFLA_INFO_KIND'), 'vlan') ifla_infodata = ip_lib.get_attr(ifla_linkinfo, 'IFLA_INFO_DATA') vlan_id = int(name.split('_')[-1]) self.assertEqual( ip_lib.get_attr(ifla_infodata, 'IFLA_VLAN_ID'), vlan_id) interfaces_tested.append(name) self.assertEqual(sorted(interfaces_tested), sorted(self.interfaces + vlan_interfaces))
def _check_routes(self, cidrs, table=None, gateway=None, metric=None, scope=None): table = table or iproute_linux.DEFAULT_TABLE if not scope: scope = 'universe' if gateway else 'link' scope = priv_ip_lib._get_scope_name(scope) for cidr in cidrs: ip_version = common_utils.get_ip_version(cidr) if ip_version == n_cons.IP_VERSION_6 and not metric: metric = ipdb_routes.IP6_RT_PRIO_USER if ip_version == n_cons.IP_VERSION_6: scope = 0 routes = priv_ip_lib.list_ip_routes(self.namespace, ip_version) for route in routes: ip = ip_lib.get_attr(route, 'RTA_DST') mask = route['dst_len'] if not (ip == str(netaddr.IPNetwork(cidr).ip) and mask == netaddr.IPNetwork(cidr).cidr.prefixlen): continue self.assertEqual(table, route['table']) self.assertEqual( priv_ip_lib._IP_VERSION_FAMILY_MAP[ip_version], route['family']) self.assertEqual(gateway, ip_lib.get_attr(route, 'RTA_GATEWAY')) self.assertEqual(metric, ip_lib.get_attr(route, 'RTA_PRIORITY')) self.assertEqual(scope, route['scope']) break else: self.fail('CIDR %s not found in the list of routes' % cidr)
def _check_gateway_or_multipath(self, route, gateway): if gateway is None or isinstance(gateway, str): self.assertEqual(gateway, ip_lib.get_attr(route, 'RTA_GATEWAY')) return rta_multipath = ip_lib.get_attr(route, 'RTA_MULTIPATH') self.assertEqual(len(gateway), len(rta_multipath)) for nexthop in gateway: to_check = {'hops': 0} if nexthop.get('device'): to_check['oif'] = priv_ip_lib.privileged_get_link_id( nexthop['device'], self.namespace) if nexthop.get('weight'): to_check['hops'] = nexthop['weight'] - 1 if nexthop.get('via'): to_check['gateway'] = nexthop['via'] for mp in rta_multipath: mp['gateway'] = ip_lib.get_attr(mp, 'RTA_GATEWAY') for key in to_check: if to_check[key] != mp[key]: break else: break else: self.fail('Route nexthops %s do not match with defined ones ' '%s' % (rta_multipath, gateway))
def show(dev=None, namespace=None, **kwargs): """List the FDB entries in a namespace :parameter dev: device name to filter the query :parameter namespace: namespace name :returns: a dictionary with the device names and the list of entries per device. """ def find_device_name(ifindex, devices): for device in (device for device in devices if device['index'] == ifindex): return device['name'] ret = collections.defaultdict(list) fdbs = priv_ip_lib.list_bridge_fdb(namespace=namespace, **kwargs) devices = ip_lib.get_devices_info(namespace) for fdb in fdbs: name = find_device_name(fdb['ifindex'], devices) if dev and dev != name: continue master = find_device_name(ip_lib.get_attr(fdb, 'NDA_MASTER'), devices) fdb_info = {'mac': ip_lib.get_attr(fdb, 'NDA_LLADDR'), 'master': master, 'vlan': ip_lib.get_attr(fdb, 'NDA_VLAN'), 'dst_ip': ip_lib.get_attr(fdb, 'NDA_DST')} ret[name].append(fdb_info) return ret
def test_get_devices_info_lo(self): devices = priv_ip_lib.get_link_devices(self.namespace) self.assertGreater(len(devices), 0) for device in devices: if ip_lib.get_attr(device, 'IFLA_IFNAME') != 'lo': continue self.assertIsNone(ip_lib.get_attr(device, 'IFLA_LINKINFO')) break else: self.fail('Device "lo" not found')
def test_get_devices_info_veth_same_namespaces(self): ip_wrapper = ip_lib.IPWrapper(self.namespace) ip_wrapper.add_veth('veth1_1', 'veth1_2') veth1_1 = self._retrieve_interface('veth1_1', self.namespace) veth1_2 = self._retrieve_interface('veth1_2', self.namespace) veth1_1_link = ip_lib.get_attr(veth1_1, 'IFLA_LINK') veth1_2_link = ip_lib.get_attr(veth1_2, 'IFLA_LINK') self.assertEqual(veth1_1['index'], veth1_2_link) self.assertEqual(veth1_2['index'], veth1_1_link)
def test_get_ip_addresses(self): namespace = 'ns_test-' + uuidutils.generate_uuid() priv_ip_lib.create_netns(namespace) self.addCleanup(self._remove_ns, namespace) interfaces = { '20': { 'cidr': '192.168.10.20/24', 'scope': 'link', 'add_broadcast': True }, '30': { 'cidr': '2001::1/64', 'scope': 'global', 'add_broadcast': False } } for int_name, int_parameters in interfaces.items(): priv_ip_lib.create_interface(int_name, namespace, 'dummy', index=int(int_name)) ip_lib.add_ip_address(int_parameters['cidr'], int_name, namespace, int_parameters['scope'], int_parameters['add_broadcast']) ip_addresses = priv_ip_lib.get_ip_addresses(namespace) for ip_address in ip_addresses: int_name = str(ip_address['index']) ip = ip_lib.get_attr(ip_address, 'IFA_ADDRESS') mask = ip_address['prefixlen'] cidr = common_utils.ip_to_cidr(ip, mask) self.assertEqual(interfaces[int_name]['cidr'], cidr) self.assertEqual(interfaces[int_name]['scope'], ip_lib.IP_ADDRESS_SCOPE[ip_address['scope']])
def test_get_devices_info_dummy(self): interfaces_tested = [] for interface in self.interfaces: priv_ip_lib.create_interface(interface, self.namespace, 'dummy') devices = priv_ip_lib.get_link_devices(self.namespace) self.assertGreater(len(devices), 0) for device in devices: name = ip_lib.get_attr(device, 'IFLA_IFNAME') if name in self.interfaces_to_exclude: continue self.assertIn(name, self.interfaces) ifla_linkinfo = ip_lib.get_attr(device, 'IFLA_LINKINFO') self.assertEqual(ip_lib.get_attr(ifla_linkinfo, 'IFLA_INFO_KIND'), 'dummy') interfaces_tested.append(name) self.assertEqual(sorted(interfaces_tested), sorted(self.interfaces))
def test_get_devices_info_veth_same_namespaces(self): ip_wrapper = ip_lib.IPWrapper(self.namespace) ip_wrapper.add_veth('veth1_1', 'veth1_2') devices = priv_ip_lib.get_link_devices(self.namespace) veth1_1 = veth1_2 = None for device in devices: name = ip_lib.get_attr(device, 'IFLA_IFNAME') if name == 'veth1_1': veth1_1 = device elif name == 'veth1_2': veth1_2 = device self.assertIsNotNone(veth1_1) self.assertIsNotNone(veth1_2) veth1_1_link = ip_lib.get_attr(veth1_1, 'IFLA_LINK') veth1_2_link = ip_lib.get_attr(veth1_2, 'IFLA_LINK') self.assertEqual(veth1_1['index'], veth1_2_link) self.assertEqual(veth1_2['index'], veth1_1_link)
def test_get_devices_info_veth_different_namespaces(self): namespace2 = 'ns_test-' + uuidutils.generate_uuid() priv_ip_lib.create_netns(namespace2) self.addCleanup(self._remove_ns, namespace2) ip_wrapper = ip_lib.IPWrapper(self.namespace) ip_wrapper.add_veth('veth1_1', 'veth1_2', namespace2) devices = priv_ip_lib.get_link_devices(self.namespace) for device in devices: name = ip_lib.get_attr(device, 'IFLA_IFNAME') if name == 'veth1_1': veth1_1 = device break else: self.fail('Interface "veth1_1" not found') ifla_linkinfo = ip_lib.get_attr(veth1_1, 'IFLA_LINKINFO') self.assertEqual(ip_lib.get_attr(ifla_linkinfo, 'IFLA_INFO_KIND'), 'veth') self.assertIsNone(ip_lib.get_attr(veth1_1, 'IFLA_LINK'))
def _check_gateway(self, gateway, table=None, metric=None): table = table or iproute_linux.DEFAULT_TABLE ip_version = common_utils.get_ip_version(gateway) if ip_version == n_cons.IP_VERSION_6 and not metric: metric = ipdb_routes.IP6_RT_PRIO_USER scope = 0 routes = priv_ip_lib.list_ip_routes(self.namespace, ip_version) for route in routes: if not (ip_lib.get_attr(route, 'RTA_GATEWAY') == gateway): continue self.assertEqual(table, route['table']) self.assertEqual(priv_ip_lib._IP_VERSION_FAMILY_MAP[ip_version], route['family']) self.assertEqual(gateway, ip_lib.get_attr(route, 'RTA_GATEWAY')) self.assertEqual(scope, route['scope']) self.assertEqual(0, route['dst_len']) self.assertEqual(metric, ip_lib.get_attr(route, 'RTA_PRIORITY')) break else: self.fail('Default gateway %s not found in the list of routes' % gateway)
def test_get_devices_info_vxlan(self): interfaces_tested = [] vxlan_interfaces = [] vxlan_id = 1000 for interface in self.interfaces: priv_ip_lib.create_interface(interface, self.namespace, 'dummy') vxlan_interface = interface + '_' + str(vxlan_id) vxlan_interfaces.append(vxlan_interface) priv_ip_lib.create_interface(vxlan_interface, self.namespace, 'vxlan', physical_interface=interface, vxlan_id=vxlan_id, vxlan_group='239.1.1.1') vxlan_id += 1 devices = priv_ip_lib.get_link_devices(self.namespace) self.assertGreater(len(devices), 0) device_name_index = {} for device in devices: name = ip_lib.get_attr(device, 'IFLA_IFNAME') device_name_index[name] = device['index'] for device in devices: name = ip_lib.get_attr(device, 'IFLA_IFNAME') if name in self.interfaces_to_exclude: continue self.assertIn(name, self.interfaces + vxlan_interfaces) ifla_linkinfo = ip_lib.get_attr(device, 'IFLA_LINKINFO') if name in vxlan_interfaces: self.assertEqual( ip_lib.get_attr(ifla_linkinfo, 'IFLA_INFO_KIND'), 'vxlan') ifla_infodata = ip_lib.get_attr(ifla_linkinfo, 'IFLA_INFO_DATA') vxlan_id = int(name.split('_')[-1]) self.assertEqual( ip_lib.get_attr(ifla_infodata, 'IFLA_VXLAN_ID'), vxlan_id) self.assertEqual( ip_lib.get_attr(ifla_infodata, 'IFLA_VXLAN_GROUP'), '239.1.1.1') vxlan_link_name = self.interfaces[vxlan_interfaces.index(name)] vxlan_link_index = device_name_index[vxlan_link_name] self.assertEqual( vxlan_link_index, ip_lib.get_attr(ifla_infodata, 'IFLA_VXLAN_LINK')) interfaces_tested.append(name) self.assertEqual(sorted(interfaces_tested), sorted(self.interfaces + vxlan_interfaces))
def test_get_devices_info_veth_different_namespaces(self): namespace2 = 'ns_test-' + uuidutils.generate_uuid() priv_ip_lib.create_netns(namespace2) self.addCleanup(self._remove_ns, namespace2) # Create a random number of dummy interfaces in namespace2, in order # to increase the 'veth1_2' interface index in its namespace. for idx in range(5, random.randint(15, 20)): priv_ip_lib.create_interface('int_%s' % idx, namespace2, 'dummy') ip_wrapper = ip_lib.IPWrapper(self.namespace) ip_wrapper.add_veth('veth1_1', 'veth1_2', namespace2) veth1_1 = self._retrieve_interface('veth1_1', self.namespace) veth1_2 = self._retrieve_interface('veth1_2', namespace2) ifla_linkinfo = ip_lib.get_attr(veth1_1, 'IFLA_LINKINFO') self.assertEqual(ip_lib.get_attr(ifla_linkinfo, 'IFLA_INFO_KIND'), 'veth') # NOTE(ralonsoh): since kernel_version=4.15.0-60-generic, iproute2 # provides the veth pair index, even if the pair interface is in other # namespace. In previous versions, the parameter 'IFLA_LINK' was not # present. We need to handle both cases. self.assertIn(ip_lib.get_attr(veth1_1, 'IFLA_LINK'), [None, veth1_2['index']])
def test_get_link_attribute_kind(self): ifla_linkinfo = ip_lib.get_attr(self.pyroute_dev, 'IFLA_LINKINFO') ifla_link_kind = ip_lib.get_attr(ifla_linkinfo, 'IFLA_INFO_KIND') self.assertEqual('dummy', ifla_link_kind) self.assertEqual(ifla_link_kind, self.device.link.link_kind)
def _retrieve_interface(self, interface_name, namespace): for device in priv_ip_lib.get_link_devices(namespace): if interface_name == ip_lib.get_attr(device, 'IFLA_IFNAME'): return device else: self.fail('Interface "%s" not found' % interface_name)