Description of problem: Currently the only way to identify a network interface card is to specify its `name` as part of the configuration. This causes problems when the names of the network interface cards change. For example, when upgrading from RHEL 8 to RHEL 9 the names of Mellanox ConnectX-4 NICs change from `eno1` to `eno1np0`. This means that after the upgrade the NetworkManager connection configuration files no longer apply to the interfaces. In our use case we run `nmstatectl gc` to generate NetworkManger configiguration files, and then we copy them to the target machine. We would like to have the possibility to generate NetworkManager files where the network interface card is identified by MAC instead of by name. For example, a hypothetical input YAML could look like this: interfaces: - name: eno1 type: ethernet identifier: mac-address mac-address: 48:67:a9:69:b1:08 state: up ipv4: address: - ip: 192.168.150.10 prefix-length: 24 enabled: true ipv6: enabled: false - name: eno2 type: ethernet identifier: mac-address mac-address: fc:dc:52:03:3a:04 state: up ipv4: address: - ip: 192.168.7.10 prefix-length: 24 enabled: true ipv6: enabled: false In this hypthetical configuration the `identifier` would be `name` by default, but changing it to `mac-address` would specify that the NIC should be identified by MAC address. Version-Release number of selected component (if applicable): We are currently using `nmstate-1.4.2-4.el8.x86_64`. How reproducible: Always. Steps to Reproduce: 1. Create a configuration YAML like in the example above. 2. Run `nmstatectl gc ...`. Actual results: The generated NetworkManager configuration files use the `name` field to identify the NIC. For example: # eno1.nmconnection [connection] id=eno1 uuid=40ebdf15-cda9-483a-b91b-d437b10c80c4 type=ethernet interface-name=eno1 # <- This is what we would like to remove autoconnect=true autoconnect-priority=1 [ipv4] address1=192.168.150.10/24 dhcp-client-id=mac dns=192.168.150.1; dns-priority=40 method=manual route1=0.0.0.0/0,192.168.150.1 route1_options=table=254 Expected results: We would like to use the MAC address to identify the interface. Something like this: # eno1.nmconnection [connection] id=eno1 uuid=40ebdf15-cda9-483a-b91b-d437b10c80c4 type=ethernet autoconnect=true autoconnect-priority=1 [802-3-ethernet] mac-address=48:67:a9:69:b1:08 # <- This is what we would like to add [ipv4] address1=192.168.150.10/24 dhcp-client-id=mac dns=192.168.150.1; dns-priority=40 method=manual route1=0.0.0.0/0,192.168.150.1 route1_options=table=254
You can find more details abut our use case here: https://issues.redhat.com/browse/MGMT-13970
Patch sent to upstream: https://bugzilla.redhat.com/show_bug.cgi?id=2183214 Introducing two properties to base interface: * `identifier` -- `name` or `mac-address`, default to `name` * `profile-name`: string When identifier been set to `mac-address`, nmstate will not use `interface.name` for NIC matching but use the `interface.mac-address`, The `interface.name` will be used for `profile-name` when storing the network configuration in backend. The `profile-name` will be hide if it is equal to interface name. Example on creating MAC based profile: ```yml --- interfaces: - name: wan0 type: ethernet state: up identifier: mac-address mac-address: 1e:bd:23:e9:fb:94 ``` You may delete above profile using `name: wan0` or its real interface name. Of course, gen_conf mode is also supported as this bug requested.
Verified with: nmstate-2.2.10-3.el9.x86_64 nispor-1.2.10-1.el9.x86_64 NetworkManager-1.43.8-1.el9.x86_64 DISTRO=RHEL-9.3.0-updates-20230520.44 [17:03:32@dell-per730-20 ~]0# nms set nic-by-mac.yaml /tmp/nmstatelog/2023-05-21-17:05:09-855797622.log dns-resolver: {} route-rules: {} routes: {} interfaces: - name: test0 type: ethernet state: up identifier: mac-address mac-address: 00:1B:21:97:78:CC mtu: 2000 ipv4: enabled: true address: - ip: 192.168.199.1 prefix-length: 24 ipv6: enabled: true address: - ip: 192:168:199::1 prefix-length: 64 accept-all-mac-addresses: false ethtool: pause: rx: true tx: false autoneg: true feature: tx-gso-partial: true rx-hashing: true tx-udp-segmentation: true tx-gre-segmentation: true tx-udp_tnl-csum-segmentation: true tx-ipxip4-segmentation: true tx-ipxip6-segmentation: true tx-checksum-sctp: true rx-checksum: true tx-generic-segmentation: true tx-gre-csum-segmentation: true tx-tcp-mangleid-segmentation: false rx-gro: true tx-tcp-segmentation: true tx-vlan-hw-insert: true tx-nocache-copy: false rx-vlan-hw-parse: true tx-tcp6-segmentation: true rx-gro-list: false tx-checksum-ip-generic: true rx-all: false tx-udp_tnl-segmentation: true rx-udp-gro-forwarding: false coalesce: rx-usecs: 3 tx-usecs: 0 ring: rx: 256 rx-max: 4096 tx: 256 tx-max: 4096 ethernet: sr-iov: total-vfs: 0 vfs: [] auto-negotiation: true speed: 1000 duplex: full ovs-db: {} /tmp/nmstatelog/2023-05-21-17:05:09-855797622.0.log nmstatectl set nic-by-mac.yaml return 0 [17:05:13@dell-per730-20 ~]0# nmcli c NAME UUID TYPE DEVICE eno1 184ea86d-0bc4-4e19-9d4e-a828056a451c ethernet eno1 test0 c1a12d19-08c5-414b-b50f-8da90d14a3f7 ethernet enp6s0f0 lo 5da60107-645d-487a-9c27-64bdd88dd1b7 loopback lo eno2 93dd178f-bff5-4b1f-9e20-9174698cb3de ethernet -- eno3 4d892a58-32da-4c87-af42-29e88e1ad90e ethernet -- eno4 58573d6e-2149-4293-829c-614f4cc8357e ethernet -- enp6s0f0 a165c5a4-c222-4a41-940c-f459def0b28b ethernet -- enp6s0f1 a4bd6ede-f508-4b2b-bc9a-247f661bac4a ethernet -- [17:05:17@dell-per730-20 ~]0# nms show test0 dns-resolver: {} route-rules: {} routes: {} interfaces: [] [17:07:57@dell-per730-20 ~]0# nms show enp6s0f0 dns-resolver: {} route-rules: {} routes: {} interfaces: - name: enp6s0f0 profile-name: test0 type: ethernet state: up identifier: mac-address mac-address: 00:1B:21:97:78:CC mtu: 2000 min-mtu: 68 max-mtu: 9216 wait-ip: any ipv4: enabled: true dhcp: false address: - ip: 192.168.199.1 prefix-length: 24 ipv6: enabled: true dhcp: false autoconf: false address: - ip: 192:168:199::1 prefix-length: 64 - ip: fe80::21b:21ff:fe97:78cc prefix-length: 64 addr-gen-mode: eui64 mptcp: address-flags: [] accept-all-mac-addresses: false lldp: enabled: false ethtool: pause: rx: true tx: false autoneg: true feature: tx-tcp-segmentation: true tx-ipxip6-segmentation: true tx-udp_tnl-segmentation: true tx-tcp-mangleid-segmentation: false tx-gre-segmentation: true tx-generic-segmentation: true tx-nocache-copy: false tx-udp_tnl-csum-segmentation: true rx-gro: true rx-gro-list: false tx-checksum-ip-generic: true tx-gre-csum-segmentation: true tx-checksum-sctp: true tx-tcp6-segmentation: true tx-ipxip4-segmentation: true rx-hashing: true rx-vlan-hw-parse: true rx-checksum: true tx-vlan-hw-insert: true rx-all: false tx-gso-partial: true rx-udp-gro-forwarding: false tx-udp-segmentation: true coalesce: rx-usecs: 3 tx-usecs: 0 ring: rx: 256 rx-max: 4096 tx: 256 tx-max: 4096 ethernet: sr-iov: total-vfs: 0 vfs: [] auto-negotiation: true speed: 1000 duplex: full