]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Create veth peer in namespace.
authorMaru Newby <marun@redhat.com>
Tue, 2 Apr 2013 22:43:37 +0000 (22:43 +0000)
committerMaru Newby <marun@redhat.com>
Thu, 25 Apr 2013 17:07:35 +0000 (17:07 +0000)
 * Update veth pair creation to set the namespace of the peer
   device on creation rather than subsequently adding it to the
   namespace.
 * This change supports kernels with limited namespace support
   (e.g. RHEL 6.5) so long as ovs_use_veth is set to True.
 * Addresses bug 1171727

Change-Id: I1885acc9934e7627bb9872703df7f5edf2980722

quantum/agent/linux/interface.py
quantum/agent/linux/ip_lib.py
quantum/tests/unit/test_linux_interface.py
quantum/tests/unit/test_linux_ip_lib.py

index e057b24a860ce784484873bbf9854cef1a234374..c0305a26f6a3098ee02abed2827c28180a12e356 100644 (file)
@@ -167,13 +167,17 @@ class OVSInterfaceDriver(LinuxInterfaceDriver):
             tap_name = self._get_tap_name(device_name, prefix)
 
             if self.conf.ovs_use_veth:
-                root_dev, ns_dev = ip.add_veth(tap_name, device_name)
+                # Create ns_dev in a namespace if one is configured.
+                root_dev, ns_dev = ip.add_veth(tap_name,
+                                               device_name,
+                                               namespace2=namespace)
+            else:
+                ns_dev = ip.device(device_name)
 
             internal = not self.conf.ovs_use_veth
             self._ovs_add_port(bridge, tap_name, port_id, mac_address,
                                internal=internal)
 
-            ns_dev = ip.device(device_name)
             ns_dev.link.set_address(mac_address)
 
             if self.conf.network_device_mtu:
@@ -181,7 +185,8 @@ class OVSInterfaceDriver(LinuxInterfaceDriver):
                 if self.conf.ovs_use_veth:
                     root_dev.link.set_mtu(self.conf.network_device_mtu)
 
-            if namespace:
+            # Add an interface created by ovs to the namespace.
+            if not self.conf.ovs_use_veth and namespace:
                 namespace_obj = ip.ensure_namespace(namespace)
                 namespace_obj.add_device_to_namespace(ns_dev)
 
@@ -231,17 +236,15 @@ class BridgeInterfaceDriver(LinuxInterfaceDriver):
                 tap_name = device_name.replace(prefix, 'tap')
             else:
                 tap_name = device_name.replace(self.DEV_NAME_PREFIX, 'tap')
-            root_veth, ns_veth = ip.add_veth(tap_name, device_name)
+            # Create ns_veth in a namespace if one is configured.
+            root_veth, ns_veth = ip.add_veth(tap_name, device_name,
+                                             namespace2=namespace)
             ns_veth.link.set_address(mac_address)
 
             if self.conf.network_device_mtu:
                 root_veth.link.set_mtu(self.conf.network_device_mtu)
                 ns_veth.link.set_mtu(self.conf.network_device_mtu)
 
-            if namespace:
-                namespace_obj = ip.ensure_namespace(namespace)
-                namespace_obj.add_device_to_namespace(ns_veth)
-
             root_veth.link.set_up()
             ns_veth.link.set_up()
 
index 88294d1be30787d2324b2b235bef640332527c17..ed110556f92660b04a8c6658d91ac5e296118116 100644 (file)
@@ -90,12 +90,19 @@ class IPWrapper(SubProcessBase):
         self._as_root('', 'tuntap', ('add', name, 'mode', mode))
         return IPDevice(name, self.root_helper, self.namespace)
 
-    def add_veth(self, name1, name2):
-        self._as_root('', 'link',
-                      ('add', name1, 'type', 'veth', 'peer', 'name', name2))
+    def add_veth(self, name1, name2, namespace2=None):
+        args = ['add', name1, 'type', 'veth', 'peer', 'name', name2]
+
+        if namespace2 is None:
+            namespace2 = self.namespace
+        else:
+            self.ensure_namespace(namespace2)
+            args += ['netns', namespace2]
+
+        self._as_root('', 'link', tuple(args))
 
         return (IPDevice(name1, self.root_helper, self.namespace),
-                IPDevice(name2, self.root_helper, self.namespace))
+                IPDevice(name2, self.root_helper, namespace2))
 
     def ensure_namespace(self, name):
         if not self.netns.exists(name):
index 9f7a5c90e66eb6301c15fe0aa027959a50ca1d73..9ae8c82c7efa276e6b642108af096975842a3cca 100644 (file)
@@ -195,12 +195,11 @@ class TestOVSInterfaceDriverWithVeth(TestOVSInterfaceDriver):
         self.device_exists.side_effect = device_exists
 
         root_dev = mock.Mock()
-        _ns_dev = mock.Mock()
         ns_dev = mock.Mock()
-        self.ip().add_veth = mock.Mock(return_value=(root_dev, _ns_dev))
-        self.ip().device = mock.Mock(return_value=(ns_dev))
-        expected = [mock.call('sudo'), mock.call().add_veth('tap0', devname),
-                    mock.call().device(devname)]
+        self.ip().add_veth = mock.Mock(return_value=(root_dev, ns_dev))
+        expected = [mock.call('sudo'),
+                    mock.call().add_veth('tap0', devname,
+                                         namespace2=namespace)]
 
         vsctl_cmd = ['ovs-vsctl', '--', '--may-exist', 'add-port',
                      bridge, 'tap0', '--', 'set', 'Interface', 'tap0',
@@ -224,11 +223,6 @@ class TestOVSInterfaceDriverWithVeth(TestOVSInterfaceDriver):
         if mtu:
             ns_dev.assert_has_calls([mock.call.link.set_mtu(mtu)])
             root_dev.assert_has_calls([mock.call.link.set_mtu(mtu)])
-        if namespace:
-            expected.extend(
-                [mock.call().ensure_namespace(namespace),
-                 mock.call().ensure_namespace().add_device_to_namespace(
-                     mock.ANY)])
 
         self.ip.assert_has_calls(expected)
         root_dev.assert_has_calls([mock.call.link.set_up()])
@@ -280,13 +274,9 @@ class TestBridgeInterfaceDriver(TestBase):
                 mac_address,
                 namespace=namespace)
 
-        ip_calls = [mock.call('sudo'), mock.call().add_veth('tap0', 'ns-0')]
+        ip_calls = [mock.call('sudo'),
+                    mock.call().add_veth('tap0', 'ns-0', namespace2=namespace)]
         ns_veth.assert_has_calls([mock.call.link.set_address(mac_address)])
-        if namespace:
-            ip_calls.extend([
-                mock.call().ensure_namespace('01234567-1234-1234-99'),
-                mock.call().ensure_namespace().add_device_to_namespace(
-                    ns_veth)])
         if mtu:
             ns_veth.assert_has_calls([mock.call.link.set_mtu(mtu)])
             root_veth.assert_has_calls([mock.call.link.set_mtu(mtu)])
index 7ac394cd9cca4dc6a1cb6680a43e81d0f2882327..8f241c29da7f362ec040db09512a04e04687ec06 100644 (file)
@@ -205,6 +205,17 @@ class TestIpWrapper(base.BaseTestCase):
                                              'peer', 'name', 'tap1'),
                                              'sudo', None)
 
+    def test_add_veth_with_namespaces(self):
+        ns2 = 'ns2'
+        with mock.patch.object(ip_lib.IPWrapper, 'ensure_namespace') as en:
+            ip_lib.IPWrapper('sudo').add_veth('tap0', 'tap1', namespace2=ns2)
+            en.assert_has_calls([mock.call(ns2)])
+        self.execute.assert_called_once_with('', 'link',
+                                             ('add', 'tap0', 'type', 'veth',
+                                              'peer', 'name', 'tap1',
+                                              'netns', ns2),
+                                             'sudo', None)
+
     def test_get_device(self):
         dev = ip_lib.IPWrapper('sudo', 'ns').device('eth0')
         self.assertEqual(dev.root_helper, 'sudo')