From aa71530aaad3e4c9a7fa2e0c5aa3bff1490172db Mon Sep 17 00:00:00 2001 From: Rodolfo Alonso Hernandez Date: Tue, 29 Jan 2019 18:07:14 +0000 Subject: [PATCH] Add VLAN and VXLAN link information in get_devices_info Added VLAN parent device name and index and VXLAN link device name and index. Change-Id: Ib44a63c0648a7b5b07b1021b10e8994002031ce8 Related-Bug: #1804274 --- neutron/agent/linux/ip_lib.py | 18 ++++++++++-- .../privileged/agent/linux/test_ip_lib.py | 19 +++++++++++++ neutron/tests/unit/agent/linux/test_ip_lib.py | 28 ++++++++++++++----- 3 files changed, 55 insertions(+), 10 deletions(-) diff --git a/neutron/agent/linux/ip_lib.py b/neutron/agent/linux/ip_lib.py index 2698d1df060..56ae4d215a7 100644 --- a/neutron/agent/linux/ip_lib.py +++ b/neutron/agent/linux/ip_lib.py @@ -1396,7 +1396,7 @@ def get_devices_with_ip(namespace, name=None, **kwargs): def get_devices_info(namespace, **kwargs): devices = privileged.get_link_devices(namespace, **kwargs) - retval = [] + retval = {} for device in devices: ret = {'index': device['index'], 'name': get_attr(device, 'IFLA_IFNAME'), @@ -1406,6 +1406,9 @@ def get_devices_info(namespace, **kwargs): 'promiscuity': get_attr(device, 'IFLA_PROMISCUITY'), 'mac': get_attr(device, 'IFLA_ADDRESS'), 'broadcast': get_attr(device, 'IFLA_BROADCAST')} + ifla_link = get_attr(device, 'IFLA_LINK') + if ifla_link: + ret['parent_index'] = ifla_link ifla_linkinfo = get_attr(device, 'IFLA_LINKINFO') if ifla_linkinfo: ret['kind'] = get_attr(ifla_linkinfo, 'IFLA_INFO_KIND') @@ -1413,8 +1416,17 @@ def get_devices_info(namespace, **kwargs): if ret['kind'] == 'vxlan': ret['vxlan_id'] = get_attr(ifla_data, 'IFLA_VXLAN_ID') ret['vxlan_group'] = get_attr(ifla_data, 'IFLA_VXLAN_GROUP') + ret['vxlan_link_index'] = get_attr(ifla_data, + 'IFLA_VXLAN_LINK') elif ret['kind'] == 'vlan': ret['vlan_id'] = get_attr(ifla_data, 'IFLA_VLAN_ID') - retval.append(ret) + retval[device['index']] = ret - return retval + for device in retval.values(): + if device.get('parent_index'): + device['parent_name'] = retval[device['parent_index']]['name'] + elif device.get('vxlan_link_index'): + device['vxlan_link_name'] = ( + retval[device['vxlan_link_index']]['name']) + + return list(retval.values()) diff --git a/neutron/tests/functional/privileged/agent/linux/test_ip_lib.py b/neutron/tests/functional/privileged/agent/linux/test_ip_lib.py index 89caab81cae..7bcdc67cf37 100644 --- a/neutron/tests/functional/privileged/agent/linux/test_ip_lib.py +++ b/neutron/tests/functional/privileged/agent/linux/test_ip_lib.py @@ -108,6 +108,11 @@ class GetDevicesInfoTestCase(functional_base.BaseSudoTestCase): 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: @@ -122,6 +127,10 @@ class GetDevicesInfoTestCase(functional_base.BaseSudoTestCase): vlan_id = int(name.split('_')[-1]) self.assertEqual( ip_lib.get_attr(ifla_infodata, 'IFLA_VLAN_ID'), vlan_id) + vlan_link_name = self.interfaces[vlan_interfaces.index(name)] + vlan_link_index = device_name_index[vlan_link_name] + self.assertEqual(vlan_link_index, ip_lib.get_attr(device, + 'IFLA_LINK')) interfaces_tested.append(name) self.assertEqual(sorted(interfaces_tested), sorted(self.interfaces + vlan_interfaces)) @@ -142,6 +151,11 @@ class GetDevicesInfoTestCase(functional_base.BaseSudoTestCase): 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: @@ -160,6 +174,11 @@ class GetDevicesInfoTestCase(functional_base.BaseSudoTestCase): 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)) diff --git a/neutron/tests/unit/agent/linux/test_ip_lib.py b/neutron/tests/unit/agent/linux/test_ip_lib.py index 620ce35609d..726152f19ba 100644 --- a/neutron/tests/unit/agent/linux/test_ip_lib.py +++ b/neutron/tests/unit/agent/linux/test_ip_lib.py @@ -1936,6 +1936,7 @@ class GetDevicesInfoTestCase(base.BaseTestCase): ('IFLA_PROMISCUITY', 0), ('IFLA_ADDRESS', '5a:76:ed:cc:ce:91'), ('IFLA_BROADCAST', 'ff:ff:ff:ff:ff:f1'), + ('IFLA_LINK', 2), ('IFLA_LINKINFO', {'attrs': ( ('IFLA_INFO_KIND', 'vlan'), ('IFLA_INFO_DATA', {'attrs': (('IFLA_VLAN_ID', 1000), )}) @@ -1952,7 +1953,8 @@ class GetDevicesInfoTestCase(base.BaseTestCase): ('IFLA_INFO_KIND', 'vxlan'), ('IFLA_INFO_DATA', {'attrs': ( ('IFLA_VXLAN_ID', 1001), - ('IFLA_VXLAN_GROUP', '239.1.1.1'))}) + ('IFLA_VXLAN_GROUP', '239.1.1.1'), + ('IFLA_VXLAN_LINK', 2))}) )})) } @@ -1989,7 +1991,7 @@ class GetDevicesInfoTestCase(base.BaseTestCase): self.assertEqual(expected, ret[0]) def test_get_devices_info_vlan(self): - self.mock_getdevs.return_value = (self.DEVICE_VLAN, ) + self.mock_getdevs.return_value = (self.DEVICE_VLAN, self.DEVICE_DUMMY) ret = ip_lib.get_devices_info('namespace') expected = {'index': 5, 'name': 'int_02', @@ -2000,11 +2002,17 @@ class GetDevicesInfoTestCase(base.BaseTestCase): 'mac': '5a:76:ed:cc:ce:91', 'broadcast': 'ff:ff:ff:ff:ff:f1', 'kind': 'vlan', - 'vlan_id': 1000} - self.assertEqual(expected, ret[0]) + 'vlan_id': 1000, + 'parent_index': 2, + 'parent_name': 'int_01'} + for device in (device for device in ret if device['kind'] == 'vlan'): + self.assertEqual(expected, device) + break + else: + self.fail('No VLAN device found') def test_get_devices_info_vxlan(self): - self.mock_getdevs.return_value = (self.DEVICE_VXLAN, ) + self.mock_getdevs.return_value = (self.DEVICE_VXLAN, self.DEVICE_DUMMY) ret = ip_lib.get_devices_info('namespace') expected = {'index': 9, 'name': 'int_03', @@ -2016,5 +2024,11 @@ class GetDevicesInfoTestCase(base.BaseTestCase): 'broadcast': 'ff:ff:ff:ff:ff:f2', 'kind': 'vxlan', 'vxlan_id': 1001, - 'vxlan_group': '239.1.1.1'} - self.assertEqual(expected, ret[0]) + 'vxlan_group': '239.1.1.1', + 'vxlan_link_index': 2, + 'vxlan_link_name': 'int_01'} + for device in (device for device in ret if device['kind'] == 'vxlan'): + self.assertEqual(expected, device) + break + else: + self.fail('No VXLAN device found')