Skip to content

Commit

Permalink
Add external_ids:ovn-chassis-mac-mappings
Browse files Browse the repository at this point in the history
The ovn-chassis-mac-mappings allows a chassis to replace the vrouter
MAC address with the MAC address of the physical network if the packet
is going from a distributed router port on vlan type logical switch.

This in essence makes VLAN tenant network distributed ports work just
like geneve distributed ports.

Closes-Bug: #2084127

Signed-off-by: Gabriel Adrian Samfira <[email protected]>
  • Loading branch information
gabriel-samfira committed Oct 22, 2024
1 parent ca4f640 commit 1d2ecdf
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 4 deletions.
31 changes: 31 additions & 0 deletions lib/charms/ovn_charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import charmhelpers.contrib.network.ovs as ch_ovs
import charmhelpers.contrib.network.ovs.ovsdb as ch_ovsdb
import charmhelpers.contrib.openstack.deferred_events as deferred_events
import charmhelpers.core.host as ch_host
import charmhelpers.fetch as ch_fetch

import charms_openstack.adapters
Expand Down Expand Up @@ -1297,6 +1298,12 @@ def configure_bridges(self):
'other-config': {'disable-in-band': 'true'},
},
})

# We need to build a mac mapping to enable distributed ports on tenant
# VLAN networks.
# see: https://www.ovn.org/support/dist-docs/ovn-architecture.7.html
ovn_chassis_mac_mapping = ''

for br in bim:
if br not in ovnbridges:
continue
Expand Down Expand Up @@ -1328,13 +1335,37 @@ def configure_bridges(self):
portdata={
'external-ids': {
'charm-ovn-chassis': br}})
# We can use the MAC of the bridge as the unique chassis MAC. If
# a physical port has been added to the bridge, the MAC will most
# likely be inherited. If not, a unique mac will be generated
# anyway.
hw_addr = None
try:
hw_addr = ch_host.get_nic_hwaddr(br)
except Exception as err:
ch_core.hookenv.log('failed to get MAC for bridge "{}": {}'
.format(br, err),
level=ch_core.hookenv.ERROR)
if hw_addr:
networks = ovnbridges.get(br, [])
for net in networks:
if ovn_chassis_mac_mapping:
ovn_chassis_mac_mapping += ','
ovn_chassis_mac_mapping += '{}:{}'.format(
net, hw_addr)

opvs = ch_ovsdb.SimpleOVSDB('ovs-vsctl').open_vswitch
if ovn_br_map_str:
opvs.set('.', 'external_ids:ovn-bridge-mappings', ovn_br_map_str)
else:
opvs.remove('.', 'external_ids', 'ovn-bridge-mappings')

if ovn_chassis_mac_mapping:
opvs.set('.', 'external_ids:ovn-chassis-mac-mappings',
ovn_chassis_mac_mapping)
else:
opvs.remove('.', 'external_ids', 'ovn-chassis-mac-mappings')

cms_opts = self._get_ovn_cms_options()
if cms_opts:
opvs.set('.', 'external_ids:ovn-cms-options', ','.join(cms_opts))
Expand Down
27 changes: 23 additions & 4 deletions unit_tests/test_lib_charms_ovn_charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,18 @@ def test__init__(self):
})

def test_configure_bridges(self):
def mock_get_nic_hwaddr_fn(iface):
mac_mapping = {
"br-ex": "a0:36:9f:dd:37:dd",
"br-data": "a0:36:9f:dd:37:db",
}
return mac_mapping.get(iface, "")
mock_get_nic_hwaddr = mock.MagicMock()
mock_get_nic_hwaddr.side_effect = mock_get_nic_hwaddr_fn

self.patch_object(ovn_charm.ch_host, "get_nic_hwaddr")
self.get_nic_hwaddr.side_effect = mock_get_nic_hwaddr

self.patch_object(ovn_charm.os_context, 'BridgePortInterfaceMap')
dict_bpi = {
'br-ex': { # bridge
Expand Down Expand Up @@ -891,10 +903,17 @@ def test_configure_bridges(self):
'data': 'fake',
'external-ids': {'charm-ovn-chassis': 'br-ex'}},
linkup=False, promisc=None, portdata={
'external-ids': {'charm-ovn-chassis': 'br-ex'}}),
ovsdb.open_vswitch.set.assert_called_once_with(
'.', 'external_ids:ovn-bridge-mappings',
'other:br-data,provider:br-ex')
'external-ids': {'charm-ovn-chassis': 'br-ex'}})
ovsdb.open_vswitch.set.assert_has_calls([
mock.call(
'.', 'external_ids:ovn-bridge-mappings',
'other:br-data,provider:br-ex'
),
mock.call(
'.', 'external_ids:ovn-chassis-mac-mappings',
'provider:a0:36:9f:dd:37:dd,other:a0:36:9f:dd:37:db'
),
], any_order=False)
ovsdb.open_vswitch.remove.assert_called_once_with(
'.', 'external_ids', 'ovn-cms-options')

Expand Down

0 comments on commit 1d2ecdf

Please sign in to comment.