Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions coriolis/osmorphing/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1149,6 +1149,14 @@ def _setup_network_preservation(self, nics_info) -> None:
break
if ip_addresses and nic_ips:
if set(ip_addresses) & set(nic_ips):
# A ':' in the name marks an address label on the parent
# device. udev can only rename the parent.
if ":" in iface:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do other network renderers/managers handle the creation or management of these address labels? Is : used for netplan or nmconnections for example? Do we need different handlers?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The : form is a legacy address label and the kernel treats eth0:0 as an alias of eth0: it is not a real netdev, so a udev NAME has to be the parent device.

An ifcfg alias file is like this: ifcfg-<if>:<label> with DEVICE=eth0:0, and NetworkManager stores that as a label on the master interface.

netplan and NetworkManager don't have this format:

  • Netplan lists extra addresses under the real interface id
  • NetworkManager binds the profile with connection.interface-name and adds further addresses as address1, address2, and so on...

LOG.info(
"Skipping IP alias interface '%s' for the udev rule.",
iface,
)
continue
LOG.info(
"Found matching interface for NIC '%s' "
"with new MAC '%s', identified by IP.",
Expand Down
44 changes: 44 additions & 0 deletions coriolis/tests/osmorphing/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2085,6 +2085,50 @@ def test__add_net_udev_rules(self, mock_write_file_sudo, mock_test_path):
"eth0": "ff:aa:11:22:33:44",
},
),
# An ifcfg IP alias is listed before the parent and its address is on
# the source NIC. The alias name must be ignored; the parent is used.
(
[
{
"name": "Network adapter 1",
"mac_address": "00:50:56:8e:74:51",
"ip_addresses": ["10.203.180.156", "10.203.181.192"],
},
],
{
"ens192:SAB": {
"mac_address": None,
"ip_addresses": ["10.203.181.192"],
},
"ens192": {
"mac_address": "00:50:56:8e:74:51",
"ip_addresses": ["10.203.180.156"],
},
},
{"ens192": "00:50:56:8e:74:51"},
),
# Same layout when the guest ifcfg files have no HWADDR. The IP match
# must still select the name without ':'.
(
[
{
"name": "Network adapter 1",
"mac_address": "00:50:56:8e:74:51",
"ip_addresses": ["10.203.180.156", "10.203.181.192"],
},
],
{
"ens192:SAB": {
"mac_address": None,
"ip_addresses": ["10.203.181.192"],
},
"ens192": {
"mac_address": None,
"ip_addresses": ["10.203.180.156"],
},
},
{"ens192": "00:50:56:8e:74:51"},
),
)
@ddt.unpack
def test__setup_network_preservation(
Expand Down
Loading