Merge "[OVN] Set MTU of the VETH interfaces between OVS and metadata"
This commit is contained in:
@@ -109,7 +109,7 @@ class PortBindingEvent(row_event.RowEvent):
|
||||
with _SYNC_STATE_LOCK.read_lock():
|
||||
self.log_row(row)
|
||||
try:
|
||||
self.agent.provision_datapath(row.datapath)
|
||||
self.agent.provision_datapath(row)
|
||||
except ConfigException:
|
||||
# We're now in the reader lock mode, we need to exit the
|
||||
# context and then use writer lock
|
||||
@@ -463,13 +463,13 @@ class MetadataAgent(object):
|
||||
"br-int instead.")
|
||||
return 'br-int'
|
||||
|
||||
def get_networks_datapaths(self):
|
||||
"""Return a set of datapath objects of the VIF ports on the current
|
||||
def get_networks_port_bindings(self):
|
||||
"""Return a set of Port_Binding objects of the VIF ports on the current
|
||||
chassis.
|
||||
"""
|
||||
ports = self.sb_idl.get_ports_on_chassis(
|
||||
self.chassis, include_additional_chassis=True)
|
||||
return set(p.datapath for p in self._vif_ports(ports))
|
||||
return list(self._vif_ports(ports))
|
||||
|
||||
@_sync_lock
|
||||
def sync(self, provision=True):
|
||||
@@ -484,12 +484,12 @@ class MetadataAgent(object):
|
||||
system_namespaces = tuple(
|
||||
ns.decode('utf-8') if isinstance(ns, bytes) else ns
|
||||
for ns in ip_lib.list_network_namespaces())
|
||||
net_datapaths = self.get_networks_datapaths()
|
||||
metadata_namespaces = [
|
||||
net_port_bindings = self.get_networks_port_bindings()
|
||||
metadata_namespaces = set(
|
||||
self._get_namespace_name(
|
||||
ovn_utils.get_network_name_from_datapath(datapath))
|
||||
for datapath in net_datapaths
|
||||
]
|
||||
for datapath in (pb.datapath for pb in net_port_bindings)
|
||||
)
|
||||
unused_namespaces = [ns for ns in system_namespaces if
|
||||
ns.startswith(NS_PREFIX) and
|
||||
ns not in metadata_namespaces]
|
||||
@@ -503,8 +503,8 @@ class MetadataAgent(object):
|
||||
# even those that are already running. This is to make sure
|
||||
# everything within each namespace is up to date.
|
||||
if provision:
|
||||
for datapath in net_datapaths:
|
||||
self.provision_datapath(datapath)
|
||||
for port_binding in net_port_bindings:
|
||||
self.provision_datapath(port_binding)
|
||||
|
||||
@staticmethod
|
||||
def _get_veth_name(datapath):
|
||||
@@ -675,7 +675,7 @@ class MetadataAgent(object):
|
||||
|
||||
return net_name, datapath_ports_ips, metadata_port_info
|
||||
|
||||
def provision_datapath(self, datapath):
|
||||
def provision_datapath(self, port_binding):
|
||||
"""Provision the datapath so that it can serve metadata.
|
||||
|
||||
This function will create the namespace and VETH pair if needed
|
||||
@@ -683,11 +683,13 @@ class MetadataAgent(object):
|
||||
metadata port of the network. It will also remove existing IP from
|
||||
the namespace if they are no longer needed.
|
||||
|
||||
:param datapath: datapath object.
|
||||
:return: The metadata namespace name for the datapath or None
|
||||
if namespace was not provisioned
|
||||
:param port_binding: Port_Binding object.
|
||||
:return: The metadata namespace name for the Port_Binding.datapath or
|
||||
None if namespace was not provisioned
|
||||
"""
|
||||
|
||||
datapath = port_binding.datapath
|
||||
mtu = int(port_binding.external_ids.get(
|
||||
ovn_const.OVN_NETWORK_MTU_EXT_ID_KEY) or '0')
|
||||
provision_params = self._get_provision_params(datapath)
|
||||
if not provision_params:
|
||||
return
|
||||
@@ -716,6 +718,11 @@ class MetadataAgent(object):
|
||||
# Configure the MAC address.
|
||||
ip2.link.set_address(metadata_port_info.mac)
|
||||
|
||||
# Set VETH ports MTU.
|
||||
if mtu:
|
||||
ip1.link.set_mtu(mtu)
|
||||
ip2.link.set_mtu(mtu)
|
||||
|
||||
# Make sure both ends of the VETH are up
|
||||
ip1.link.set_up()
|
||||
ip2.link.set_up()
|
||||
|
@@ -82,6 +82,7 @@ OvnPortInfo = collections.namedtuple(
|
||||
"address6_scope_id",
|
||||
"vnic_type",
|
||||
"capabilities",
|
||||
"mtu",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -340,6 +341,7 @@ class OVNClient(object):
|
||||
address6_scope_id = ""
|
||||
dhcpv4_options = self._get_port_dhcp_options(port, const.IP_VERSION_4)
|
||||
dhcpv6_options = self._get_port_dhcp_options(port, const.IP_VERSION_6)
|
||||
mtu = ''
|
||||
if vtep_physical_switch:
|
||||
vtep_logical_switch = bp_info.bp_param.get('vtep-logical-switch')
|
||||
port_type = 'vtep'
|
||||
@@ -433,10 +435,10 @@ class OVNClient(object):
|
||||
ovn_const.VIF_DETAILS_PF_MAC_ADDRESS in bp_info.bp_param):
|
||||
port_net = self._plugin.get_network(
|
||||
context, port['network_id'])
|
||||
mtu = str(port_net['mtu'])
|
||||
options.update({
|
||||
ovn_const.LSP_OPTIONS_VIF_PLUG_TYPE_KEY: 'representor',
|
||||
ovn_const.LSP_OPTIONS_VIF_PLUG_MTU_REQUEST_KEY: str(
|
||||
port_net['mtu']),
|
||||
ovn_const.LSP_OPTIONS_VIF_PLUG_MTU_REQUEST_KEY: mtu,
|
||||
ovn_const.LSP_OPTIONS_VIF_PLUG_REPRESENTOR_PF_MAC_KEY: (
|
||||
bp_info.bp_param.get(
|
||||
ovn_const.VIF_DETAILS_PF_MAC_ADDRESS)),
|
||||
@@ -477,7 +479,7 @@ class OVNClient(object):
|
||||
parent_name, tag, dhcpv4_options, dhcpv6_options,
|
||||
cidrs.strip(), device_owner, sg_ids,
|
||||
address4_scope_id, address6_scope_id,
|
||||
bp_info.vnic_type, bp_info.capabilities
|
||||
bp_info.vnic_type, bp_info.capabilities, mtu
|
||||
)
|
||||
|
||||
def update_port_dhcp_options(self, port_info, txn):
|
||||
@@ -518,6 +520,7 @@ class OVNClient(object):
|
||||
ovn_const.OVN_PORT_VNIC_TYPE_KEY: port_info.vnic_type,
|
||||
ovn_const.OVN_PORT_BP_CAPABILITIES_KEY:
|
||||
';'.join(port_info.capabilities),
|
||||
ovn_const.OVN_NETWORK_MTU_EXT_ID_KEY: port_info.mtu,
|
||||
}
|
||||
return port_info, external_ids
|
||||
|
||||
|
@@ -103,14 +103,8 @@ class TestMetadataAgent(base.BaseTestCase):
|
||||
|
||||
self.agent.sync()
|
||||
|
||||
pdp.assert_has_calls(
|
||||
[
|
||||
mock.call(p.datapath)
|
||||
for p in self.ports
|
||||
],
|
||||
any_order=True
|
||||
)
|
||||
|
||||
pdp.assert_has_calls([mock.call(p) for p in self.ports],
|
||||
any_order=True)
|
||||
lnn.assert_called_once_with()
|
||||
tdp.assert_not_called()
|
||||
|
||||
@@ -129,13 +123,8 @@ class TestMetadataAgent(base.BaseTestCase):
|
||||
|
||||
self.agent.sync()
|
||||
|
||||
pdp.assert_has_calls(
|
||||
[
|
||||
mock.call(p.datapath)
|
||||
for p in self.ports
|
||||
],
|
||||
any_order=True
|
||||
)
|
||||
pdp.assert_has_calls([mock.call(p) for p in self.ports],
|
||||
any_order=True)
|
||||
lnn.assert_called_once_with()
|
||||
tdp.assert_called_once_with('3')
|
||||
|
||||
@@ -154,27 +143,23 @@ class TestMetadataAgent(base.BaseTestCase):
|
||||
side_effect=Exception()) as tdp:
|
||||
self.agent.sync()
|
||||
|
||||
pdp.assert_has_calls(
|
||||
[
|
||||
mock.call(p.datapath)
|
||||
for p in self.ports
|
||||
],
|
||||
any_order=True
|
||||
)
|
||||
pdp.assert_has_calls([mock.call(p) for p in self.ports],
|
||||
any_order=True)
|
||||
lnn.assert_called_once_with()
|
||||
tdp.assert_called_once_with('3')
|
||||
|
||||
def test_get_networks_datapaths(self):
|
||||
"""Test get_networks_datapaths returns only datapath objects for the
|
||||
networks containing vif ports of type ''(blank) and 'external'.
|
||||
def test_get_networks_port_bindings(self):
|
||||
"""Test get_networks_port_bindings returns only the port binding
|
||||
objects for ports with VIF type empty ('') or 'external'.
|
||||
This test simulates that this chassis has the following ports:
|
||||
* datapath '1': 1 port type '' , 1 port 'external' and
|
||||
1 port 'unknown'
|
||||
* datapath '2': 1 port type ''
|
||||
* datapath '3': 1 port with type 'external'
|
||||
* datapath '4': 1 port with type 'unknown'
|
||||
* port0: datapath 1, type ''
|
||||
* port1: datapath 1, type 'external'
|
||||
* port2: datapath 1, type 'unknown'
|
||||
* port3: datapath 2, type ''
|
||||
* port4: datapath 3, type 'external'
|
||||
* port5: datapath 4, type 'unknown'
|
||||
|
||||
It is expected that only datapaths '1', '2' and '3' are returned
|
||||
Only port bindings from ports 0, 1, 3, and 4 are expected.
|
||||
"""
|
||||
|
||||
datapath_1 = DatapathInfo(uuid='uuid1',
|
||||
@@ -197,11 +182,8 @@ class TestMetadataAgent(base.BaseTestCase):
|
||||
|
||||
with mock.patch.object(self.agent.sb_idl, 'get_ports_on_chassis',
|
||||
return_value=ports):
|
||||
expected_datapaths = set([datapath_1, datapath_2, datapath_3])
|
||||
self.assertSetEqual(
|
||||
expected_datapaths,
|
||||
self.agent.get_networks_datapaths()
|
||||
)
|
||||
self.assertEqual([ports[0], ports[1], ports[3], ports[4]],
|
||||
self.agent.get_networks_port_bindings())
|
||||
|
||||
def test_teardown_datapath(self):
|
||||
"""Test teardown datapath.
|
||||
@@ -444,7 +426,8 @@ class TestMetadataAgent(base.BaseTestCase):
|
||||
mock.patch.object(agent.MetadataAgent, '_get_namespace_name',
|
||||
return_value=nemaspace_name),\
|
||||
mock.patch.object(ip_link, 'set_up') as link_set_up,\
|
||||
mock.patch.object(ip_link, 'set_address') as link_set_addr,\
|
||||
mock.patch.object(ip_link, 'set_address') as link_set_addr, \
|
||||
mock.patch.object(ip_link, 'set_mtu') as link_set_mtu, \
|
||||
mock.patch.object(ip_addr, 'list', return_value=[]),\
|
||||
mock.patch.object(
|
||||
ip_addr, 'add_multiple') as ip_addr_add_multiple,\
|
||||
@@ -464,7 +447,11 @@ class TestMetadataAgent(base.BaseTestCase):
|
||||
# We need to assert that it was deleted first.
|
||||
self.agent.ovs_idl.list_br.return_value.execute.return_value = (
|
||||
['br-int', 'br-fake'])
|
||||
self.agent.provision_datapath('fake_datapath')
|
||||
mtu = 1500
|
||||
port_binding = mock.Mock(
|
||||
datapath='fake_datapath',
|
||||
external_ids={ovn_const.OVN_NETWORK_MTU_EXT_ID_KEY: str(mtu)})
|
||||
self.agent.provision_datapath(port_binding)
|
||||
|
||||
# Check that the port was deleted from br-fake
|
||||
self.agent.ovs_idl.del_port.assert_called_once_with(
|
||||
@@ -474,6 +461,7 @@ class TestMetadataAgent(base.BaseTestCase):
|
||||
nemaspace_name)
|
||||
# Make sure that the two ends of the VETH pair have been set as up.
|
||||
self.assertEqual(2, link_set_up.call_count)
|
||||
link_set_mtu.assert_has_calls([mock.call(mtu), mock.call(mtu)])
|
||||
link_set_addr.assert_called_once_with('aa:bb:cc:dd:ee:ff')
|
||||
# Make sure that the port has been added to OVS.
|
||||
self.agent.ovs_idl.add_port.assert_called_once_with(
|
||||
|
Reference in New Issue
Block a user