Browse Source

Veth pair "IFLA_LINK" populated since kernel 4.15.0-60-generic

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

NOTE: this patch is merged in master combined with another bug
resolution [1] due to the existing problems in the CI. However, this
patch can be pushed alone in stable releases.

Conflicts:
        neutron/tests/functional/privileged/agent/linux/test_ip_lib.py

[1] https://review.opendev.org/#/c/680001/

Change-Id: Id161423737189bf822716be953c0db9c1f09589d
Closes-Bug: #1842482
(cherry picked from commit fc2a4becd0)
changes/03/680803/2
Rodolfo Alonso Hernandez 2 weeks ago
parent
commit
e0f498aae9
1 changed files with 24 additions and 19 deletions
  1. 24
    19
      neutron/tests/functional/privileged/agent/linux/test_ip_lib.py

+ 24
- 19
neutron/tests/functional/privileged/agent/linux/test_ip_lib.py View File

@@ -12,6 +12,8 @@
12 12
 #    License for the specific language governing permissions and limitations
13 13
 #    under the License.
14 14
 
15
+import random
16
+
15 17
 from oslo_utils import uuidutils
16 18
 import testtools
17 19
 
@@ -183,42 +185,45 @@ class GetDevicesInfoTestCase(functional_base.BaseSudoTestCase):
183 185
         self.assertEqual(sorted(interfaces_tested),
184 186
                          sorted(self.interfaces + vxlan_interfaces))
185 187
 
188
+    def _retrieve_interface(self, interface_name, namespace):
189
+        for device in priv_ip_lib.get_link_devices(namespace):
190
+            if interface_name == ip_lib.get_attr(device, 'IFLA_IFNAME'):
191
+                return device
192
+        else:
193
+            self.fail('Interface "%s" not found' % interface_name)
194
+
186 195
     def test_get_devices_info_veth_different_namespaces(self):
187 196
         namespace2 = 'ns_test-' + uuidutils.generate_uuid()
188 197
         priv_ip_lib.create_netns(namespace2)
189 198
         self.addCleanup(self._remove_ns, namespace2)
199
+        # Create a random number of dummy interfaces in namespace2, in order
200
+        # to increase the 'veth1_2' interface index in its namespace.
201
+        for idx in range(5, random.randint(15, 20)):
202
+            priv_ip_lib.create_interface('int_%s' % idx, namespace2, 'dummy')
203
+
190 204
         ip_wrapper = ip_lib.IPWrapper(self.namespace)
191 205
         ip_wrapper.add_veth('veth1_1', 'veth1_2', namespace2)
192 206
 
193
-        devices = priv_ip_lib.get_link_devices(self.namespace)
194
-        for device in devices:
195
-            name = ip_lib.get_attr(device, 'IFLA_IFNAME')
196
-            if name == 'veth1_1':
197
-                veth1_1 = device
198
-                break
199
-        else:
200
-            self.fail('Interface "veth1_1" not found')
207
+        veth1_1 = self._retrieve_interface('veth1_1', self.namespace)
208
+        veth1_2 = self._retrieve_interface('veth1_2', namespace2)
201 209
 
202 210
         ifla_linkinfo = ip_lib.get_attr(veth1_1, 'IFLA_LINKINFO')
203 211
         self.assertEqual(ip_lib.get_attr(ifla_linkinfo, 'IFLA_INFO_KIND'),
204 212
                          'veth')
205
-        self.assertIsNone(ip_lib.get_attr(veth1_1, 'IFLA_LINK'))
213
+        # NOTE(ralonsoh): since kernel_version=4.15.0-60-generic, iproute2
214
+        # provides the veth pair index, even if the pair interface is in other
215
+        # namespace. In previous versions, the parameter 'IFLA_LINK' was not
216
+        # present. We need to handle both cases.
217
+        self.assertIn(ip_lib.get_attr(veth1_1, 'IFLA_LINK'),
218
+                      [None, veth1_2['index']])
206 219
 
207 220
     def test_get_devices_info_veth_same_namespaces(self):
208 221
         ip_wrapper = ip_lib.IPWrapper(self.namespace)
209 222
         ip_wrapper.add_veth('veth1_1', 'veth1_2')
210 223
 
211
-        devices = priv_ip_lib.get_link_devices(self.namespace)
212
-        veth1_1 = veth1_2 = None
213
-        for device in devices:
214
-            name = ip_lib.get_attr(device, 'IFLA_IFNAME')
215
-            if name == 'veth1_1':
216
-                veth1_1 = device
217
-            elif name == 'veth1_2':
218
-                veth1_2 = device
224
+        veth1_1 = self._retrieve_interface('veth1_1', self.namespace)
225
+        veth1_2 = self._retrieve_interface('veth1_2', self.namespace)
219 226
 
220
-        self.assertIsNotNone(veth1_1)
221
-        self.assertIsNotNone(veth1_2)
222 227
         veth1_1_link = ip_lib.get_attr(veth1_1, 'IFLA_LINK')
223 228
         veth1_2_link = ip_lib.get_attr(veth1_2, 'IFLA_LINK')
224 229
         self.assertEqual(veth1_1['index'], veth1_2_link)

Loading…
Cancel
Save