Merge "[OVN] Set MTU of the VETH interfaces between OVS and metadata"

This commit is contained in:
Zuul
2024-03-05 09:48:42 +00:00
committed by Gerrit Code Review
3 changed files with 54 additions and 56 deletions

View File

@@ -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()

View File

@@ -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

View File

@@ -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(