Create veth peer in namespace.
* 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
This commit is contained in:
parent
941bb2122b
commit
152f3cf112
@ -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()
|
||||
|
||||
|
@ -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):
|
||||
|
@ -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)])
|
||||
|
@ -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')
|
||||
|
Loading…
x
Reference in New Issue
Block a user