9c875bbffefa5df437395e16749713bda854e221
[openstack-build/neutron-build.git] / rpm / SOURCES / 0003-Create-veth-peer-in-namespace.patch
1 From edd624ef23d7e6e410aaaf356765c2568e46247d Mon Sep 17 00:00:00 2001
2 From: Maru Newby <marun@redhat.com>
3 Date: Tue, 2 Apr 2013 22:43:37 +0000
4 Subject: [PATCH] Create veth peer in namespace.
5
6  * Update veth pair creation to set the namespace of the peer
7    device on creation rather than subsequently adding it to the
8    namespace.
9  * This change supports kernels with limited namespace support
10    (e.g. RHEL 6.5) so long as ovs_use_veth is set to True.
11  * Addresses bug 1171727
12
13 Change-Id: I1885acc9934e7627bb9872703df7f5edf2980722
14 ---
15  quantum/agent/linux/interface.py           |   19 +++++++++++--------
16  quantum/agent/linux/ip_lib.py              |   15 +++++++++++----
17  quantum/tests/unit/test_linux_interface.py |   22 ++++++----------------
18  quantum/tests/unit/test_linux_ip_lib.py    |   11 +++++++++++
19  4 files changed, 39 insertions(+), 28 deletions(-)
20
21 diff --git a/quantum/agent/linux/interface.py b/quantum/agent/linux/interface.py
22 index e057b24..c0305a2 100644
23 --- a/quantum/agent/linux/interface.py
24 +++ b/quantum/agent/linux/interface.py
25 @@ -167,13 +167,17 @@ class OVSInterfaceDriver(LinuxInterfaceDriver):
26              tap_name = self._get_tap_name(device_name, prefix)
27  
28              if self.conf.ovs_use_veth:
29 -                root_dev, ns_dev = ip.add_veth(tap_name, device_name)
30 +                # Create ns_dev in a namespace if one is configured.
31 +                root_dev, ns_dev = ip.add_veth(tap_name,
32 +                                               device_name,
33 +                                               namespace2=namespace)
34 +            else:
35 +                ns_dev = ip.device(device_name)
36  
37              internal = not self.conf.ovs_use_veth
38              self._ovs_add_port(bridge, tap_name, port_id, mac_address,
39                                 internal=internal)
40  
41 -            ns_dev = ip.device(device_name)
42              ns_dev.link.set_address(mac_address)
43  
44              if self.conf.network_device_mtu:
45 @@ -181,7 +185,8 @@ class OVSInterfaceDriver(LinuxInterfaceDriver):
46                  if self.conf.ovs_use_veth:
47                      root_dev.link.set_mtu(self.conf.network_device_mtu)
48  
49 -            if namespace:
50 +            # Add an interface created by ovs to the namespace.
51 +            if not self.conf.ovs_use_veth and namespace:
52                  namespace_obj = ip.ensure_namespace(namespace)
53                  namespace_obj.add_device_to_namespace(ns_dev)
54  
55 @@ -231,17 +236,15 @@ class BridgeInterfaceDriver(LinuxInterfaceDriver):
56                  tap_name = device_name.replace(prefix, 'tap')
57              else:
58                  tap_name = device_name.replace(self.DEV_NAME_PREFIX, 'tap')
59 -            root_veth, ns_veth = ip.add_veth(tap_name, device_name)
60 +            # Create ns_veth in a namespace if one is configured.
61 +            root_veth, ns_veth = ip.add_veth(tap_name, device_name,
62 +                                             namespace2=namespace)
63              ns_veth.link.set_address(mac_address)
64  
65              if self.conf.network_device_mtu:
66                  root_veth.link.set_mtu(self.conf.network_device_mtu)
67                  ns_veth.link.set_mtu(self.conf.network_device_mtu)
68  
69 -            if namespace:
70 -                namespace_obj = ip.ensure_namespace(namespace)
71 -                namespace_obj.add_device_to_namespace(ns_veth)
72 -
73              root_veth.link.set_up()
74              ns_veth.link.set_up()
75  
76 diff --git a/quantum/agent/linux/ip_lib.py b/quantum/agent/linux/ip_lib.py
77 index 5207c23..2f56672 100644
78 --- a/quantum/agent/linux/ip_lib.py
79 +++ b/quantum/agent/linux/ip_lib.py
80 @@ -90,12 +90,19 @@ class IPWrapper(SubProcessBase):
81          self._as_root('', 'tuntap', ('add', name, 'mode', mode))
82          return IPDevice(name, self.root_helper, self.namespace)
83  
84 -    def add_veth(self, name1, name2):
85 -        self._as_root('', 'link',
86 -                      ('add', name1, 'type', 'veth', 'peer', 'name', name2))
87 +    def add_veth(self, name1, name2, namespace2=None):
88 +        args = ['add', name1, 'type', 'veth', 'peer', 'name', name2]
89 +
90 +        if namespace2 is None:
91 +            namespace2 = self.namespace
92 +        else:
93 +            self.ensure_namespace(namespace2)
94 +            args += ['netns', namespace2]
95 +
96 +        self._as_root('', 'link', tuple(args))
97  
98          return (IPDevice(name1, self.root_helper, self.namespace),
99 -                IPDevice(name2, self.root_helper, self.namespace))
100 +                IPDevice(name2, self.root_helper, namespace2))
101  
102      def ensure_namespace(self, name):
103          if not self.netns.exists(name):
104 diff --git a/quantum/tests/unit/test_linux_interface.py b/quantum/tests/unit/test_linux_interface.py
105 index a386f93..dc1e464 100644
106 --- a/quantum/tests/unit/test_linux_interface.py
107 +++ b/quantum/tests/unit/test_linux_interface.py
108 @@ -199,12 +199,11 @@ class TestOVSInterfaceDriverWithVeth(TestOVSInterfaceDriver):
109          self.device_exists.side_effect = device_exists
110  
111          root_dev = mock.Mock()
112 -        _ns_dev = mock.Mock()
113          ns_dev = mock.Mock()
114 -        self.ip().add_veth = mock.Mock(return_value=(root_dev, _ns_dev))
115 -        self.ip().device = mock.Mock(return_value=(ns_dev))
116 -        expected = [mock.call('sudo'), mock.call().add_veth('tap0', devname),
117 -                    mock.call().device(devname)]
118 +        self.ip().add_veth = mock.Mock(return_value=(root_dev, ns_dev))
119 +        expected = [mock.call('sudo'),
120 +                    mock.call().add_veth('tap0', devname,
121 +                                         namespace2=namespace)]
122  
123          vsctl_cmd = ['ovs-vsctl', '--', '--may-exist', 'add-port',
124                       bridge, 'tap0', '--', 'set', 'Interface', 'tap0',
125 @@ -228,11 +227,6 @@ class TestOVSInterfaceDriverWithVeth(TestOVSInterfaceDriver):
126          if mtu:
127              ns_dev.assert_has_calls([mock.call.link.set_mtu(mtu)])
128              root_dev.assert_has_calls([mock.call.link.set_mtu(mtu)])
129 -        if namespace:
130 -            expected.extend(
131 -                [mock.call().ensure_namespace(namespace),
132 -                 mock.call().ensure_namespace().add_device_to_namespace(
133 -                     mock.ANY)])
134  
135          self.ip.assert_has_calls(expected)
136          root_dev.assert_has_calls([mock.call.link.set_up()])
137 @@ -284,13 +278,9 @@ class TestBridgeInterfaceDriver(TestBase):
138                  mac_address,
139                  namespace=namespace)
140  
141 -        ip_calls = [mock.call('sudo'), mock.call().add_veth('tap0', 'ns-0')]
142 +        ip_calls = [mock.call('sudo'),
143 +                    mock.call().add_veth('tap0', 'ns-0', namespace2=namespace)]
144          ns_veth.assert_has_calls([mock.call.link.set_address(mac_address)])
145 -        if namespace:
146 -            ip_calls.extend([
147 -                mock.call().ensure_namespace('01234567-1234-1234-99'),
148 -                mock.call().ensure_namespace().add_device_to_namespace(
149 -                    ns_veth)])
150          if mtu:
151              ns_veth.assert_has_calls([mock.call.link.set_mtu(mtu)])
152              root_veth.assert_has_calls([mock.call.link.set_mtu(mtu)])
153 diff --git a/quantum/tests/unit/test_linux_ip_lib.py b/quantum/tests/unit/test_linux_ip_lib.py
154 index 47b4063..e477f2f 100644
155 --- a/quantum/tests/unit/test_linux_ip_lib.py
156 +++ b/quantum/tests/unit/test_linux_ip_lib.py
157 @@ -205,6 +205,17 @@ class TestIpWrapper(base.BaseTestCase):
158                                               'peer', 'name', 'tap1'),
159                                               'sudo', None)
160  
161 +    def test_add_veth_with_namespaces(self):
162 +        ns2 = 'ns2'
163 +        with mock.patch.object(ip_lib.IPWrapper, 'ensure_namespace') as en:
164 +            ip_lib.IPWrapper('sudo').add_veth('tap0', 'tap1', namespace2=ns2)
165 +            en.assert_has_calls([mock.call(ns2)])
166 +        self.execute.assert_called_once_with('', 'link',
167 +                                             ('add', 'tap0', 'type', 'veth',
168 +                                              'peer', 'name', 'tap1',
169 +                                              'netns', ns2),
170 +                                             'sudo', None)
171 +
172      def test_get_device(self):
173          dev = ip_lib.IPWrapper('sudo', 'ns').device('eth0')
174          self.assertEqual(dev.root_helper, 'sudo')