+++ This bug was initially created as a clone of Bug #2152601 +++
Description of problem:
nmcli does not show actual DHCP settings
In order to use DHCP with a bond0 device we are explicitly setting a client ID for the bond0 device using the following procedure.
https://access.redhat.com/solutions/6747451
/usr/local/bin/set-dhcp-client-id.sh
#!/usr/bin/bash
cat <<EOF > /etc/NetworkManager/conf.d/99-client-id.conf
[connection-bond0]
match-device=interface-name:=bond0
ipv4.dhcp-client-id=01:$(cat /sys/class/net/enp5s0/address)
ipv6.dhcp-duid=00:03:00:01:$(cat /sys/class/net/enp5s0/address)
EOF
DHCP settings specified in this manner are not displayed with `nmcli`
Version-Release number of selected component (if applicable):
NetworkManager-1.36.0-11.el8_6.x86_64
How reproducible:
Always
Steps to Reproduce:
1.
cat <<EOF > /etc/NetworkManager/conf.d/99-client-id.conf
[connection-bond0]
match-device=interface-name:=bond0,interface-name:=br-ex
ipv4.dhcp-client-id=01:$(cat /sys/class/net/enp5s0/address)
ipv6.dhcp-duid=00:03:00:01:$(cat /sys/class/net/enp5s0/address)
EOF
2. reboot
3. nmcli --get-values ipv4.dhcp-client-id conn show
4. nmcli c show bond0 | grep 'dhcp.*id'
Actual results:
# nmcli --get-values ipv4.dhcp-client-id conn show bond0 | od -c
0000000 \n
0000001
# nmcli c show bond0 | grep 'dhcp.*id'
ipv4.dhcp-client-id: --
ipv4.dhcp-iaid: --
ipv4.dhcp-vendor-class-identifier: --
ipv6.dhcp-duid: --
ipv6.dhcp-iaid: --
The TRACE logs show actual values
Dec 09 00:39:48 master-0-0 NetworkManager[1373]: <debug> [1670546388.9265] CONFIG: ipv4.dhcp-client-id=mac
Dec 09 00:39:48 master-0-0 NetworkManager[1373]: <debug> [1670546388.9265] CONFIG: ipv6.dhcp-duid=ll
Dec 09 00:39:48 master-0-0 NetworkManager[1373]: <debug> [1670546388.9265] CONFIG: ipv6.dhcp-iaid=mac
Dec 09 00:39:48 master-0-0 NetworkManager[1373]: <debug> [1670546388.9265] CONFIG: ipv4.dhcp-client-id=01:52:54:00:56:88:e5
Dec 09 00:39:48 master-0-0 NetworkManager[1373]: <debug> [1670546388.9265] CONFIG: ipv6.dhcp-duid=00:03:00:01:52:54:00:56:88:e5
Dec 09 00:40:10 master-0-0 NetworkManager[1373]: <debug> [1670546410.3974] device[2818202ed4949e8f] (bond0): ipv4.dhcp-client-id: use "01:52:54:00:56:88:e5" client ID: 01:52:54:00:56:88:e5
Dec 09 00:40:12 master-0-0 NetworkManager[1373]: <debug> [1670546412.1798] device[2818202ed4949e8f] (bond0): ipv6.dhcp-iaid: using 7424379 (0x0071497b) IAID (str: 'mac', explicit 1)
Dec 09 00:40:12 master-0-0 NetworkManager[1373]: <debug> [1670546412.1798] device[2818202ed4949e8f] (bond0): ipv6.dhcp-duid: generate 00:03:00:01:52:54:00:56:88:e5 DUID '00:03:00:01:52:54:00:56:88:e5' (enforcing)
Dec 09 00:40:12 master-0-0 NetworkManager[1373]: <trace> [1670546412.1798] dhcp6 (bond0): duid: set 00:03:00:01:52:54:00:56:88:e5
Expected results:
# nmcli c show bond0 | grep 'dhcp.*id'
ipv4.dhcp-client-id: 01:52:54:00:56:88:e5
ipv4.dhcp-iaid: --
ipv4.dhcp-vendor-class-identifier: --
ipv6.dhcp-duid: 00:03:00:01:52:54:00:56:88:e5
ipv6.dhcp-iaid: --
Additional info:
For OpenShift OVN we attach the bond0 device to an OVS bridge `br-ex`. To do this we need to copy nmcli settings from the bond0 device to the OVS br-ex device.
https://github.com/openshift/machine-config-operator/blob/master/templates/common/_base/files/configure-ovs-network.yaml#L313
# check for dhcp client ids
dhcp_client_id=$(nmcli --get-values ipv4.dhcp-client-id conn show ${old_conn})
if [ -n "$dhcp_client_id" ]; then
extra_if_brex_args+="ipv4.dhcp-client-id ${dhcp_client_id} "
fi
dhcp6_client_id=$(nmcli --get-values ipv6.dhcp-duid conn show ${old_conn})
if [ -n "$dhcp6_client_id" ]; then
extra_if_brex_args+="ipv6.dhcp-duid ${dhcp6_client_id} "
fi
ipv6_addr_gen_mode=$(nmcli --get-values ipv6.addr-gen-mode conn show ${old_conn})
if [ -n "$ipv6_addr_gen_mode" ]; then
extra_if_brex_args+="ipv6.addr-gen-mode ${ipv6_addr_gen_mode} "
fi
Because of this issue we fail to copy the bond0 dhcp settings.
Dec 08 03:47:47 master-0-0 configure-ovs.sh[2720]: ++ ip -j a show dev bond0
Dec 08 03:47:47 master-0-0 configure-ovs.sh[2721]: ++ jq '.[0].addr_info | map(. | select(.family == "inet6" and .scope != "link")) | length'
Dec 08 03:47:47 master-0-0 configure-ovs.sh[2397]: + num_ip6_addrs=1
Dec 08 03:47:47 master-0-0 configure-ovs.sh[2397]: + '[' 1 -gt 0 ']'
Dec 08 03:47:47 master-0-0 configure-ovs.sh[2397]: + extra_if_brex_args+='ipv6.may-fail no '
Dec 08 03:47:47 master-0-0 configure-ovs.sh[2722]: ++ nmcli --get-values ipv4.dhcp-client-id conn show a661c652-5ada-3efd-9deb-f73f9d08a896
Dec 08 03:47:47 master-0-0 configure-ovs.sh[2397]: + dhcp_client_id=
Dec 08 03:47:47 master-0-0 configure-ovs.sh[2397]: + '[' -n '' ']'
Dec 08 03:47:47 master-0-0 configure-ovs.sh[2726]: ++ nmcli --get-values ipv6.dhcp-duid conn show a661c652-5ada-3efd-9deb-f73f9d08a896
Dec 08 03:47:47 master-0-0 configure-ovs.sh[2397]: + dhcp6_client_id=
Dec 08 03:47:47 master-0-0 configure-ovs.sh[2397]: + '[' -n '' ']'
Dec 08 03:47:47 master-0-0 configure-ovs.sh[2730]: ++ nmcli --get-values ipv6.addr-gen-mode conn show a661c652-5ada-3efd-9deb-f73f9d08a896
Dec 08 03:47:48 master-0-0 configure-ovs.sh[2397]: + ipv6_addr_gen_mode=eui64
Dec 08 03:47:48 master-0-0 configure-ovs.sh[2397]: + '[' -n eui64 ']'
--- Additional comment from Ross Brattain on 2022-12-12 12:54:40 UTC ---
Affecting OpenShift baremetal IPI.
--- Additional comment from Beniamino Galvani on 2022-12-12 13:51:01 UTC ---
Some properties (such as ipv4.dhcp-client-id) support a global default, meaning that when the value in the connection profile is not set, the global default is used instead. This doesn't mean that the value in the profile gets updated; if you query the connection profile it still displays an empty value.
Unfortunately at the moment there isn't an easy way to show the effective value of a property that uses a global default.
Your script could notice that the value of ipv4.dhcp-client-id is empty in the profile and then it could try to parse the global default from the output of "NetworkManager --print-config", but that works only for very simple cases, because the script would need to understand the various "match*" lines and their precedence. So, I don't consider this feasible in the general case.
--- Additional comment from Ross Brattain on 2022-12-12 14:20:52 UTC ---
Is there another mechanism for getting DHCP client IDs used for the current leases?
--- Additional comment from Thomas Haller on 2022-12-12 14:49:44 UTC ---
> Is there another mechanism for getting DHCP client IDs used for the current leases?
unless you hardcode a MAC address in the profile's `ipv4.dhcp-client-id`, the actually used client-id depends on the interface and the moment of activation. That's the case with `ipv4.dhcp-client-id="mac"`, with `ipv4.dhcp-client-id="stable"` or with leaving it unset to fallback to the global connection default from NetworkManager.conf.
The first solution is to just explicitly hardcode the client-id in the profile. That seems to be what you want anyway.
If you clone a profile that has the client-id set to something else (one of the special keywords like "mac", "stable" or unset to mean global default), you cannot know the used client-id, unless you activate the profile. Because it depends on the device (with `ipv4.dhcp-client-id="stable" connection.stable-id="${RANDOM}"` it is even randomized at the moment of activation).
What we should add, is to expose the used client-id/DUID together with the lease information. We already expose the lease information on D-Bus, nmcli and /run/NetworkManager/devices. It would be simple and good to have also the client-id/DUID there. Then you could check at a particular moment which client ID was used. It's not clear to me what you are going to do with that information though.
> To do this we need to copy nmcli settings from the bond0 device to the OVS br-ex device.
> ...
> Because of this issue we fail to copy the bond0 dhcp settings.
Hm? You copy the profile. And the profile does not specify the client-id.
Maybe that is your real problem? If you want a fixed client-id per-profile, why do you write it to NetworkManager.conf, instead of configuring it in the profile?
--- Additional comment from Ross Brattain on 2023-01-03 15:02:27 UTC ---
(In reply to Thomas Haller from comment #4)
> > To do this we need to copy nmcli settings from the bond0 device to the OVS br-ex device.
> > ...
> > Because of this issue we fail to copy the bond0 dhcp settings.
>
> Hm? You copy the profile. And the profile does not specify the client-id.
>
> Maybe that is your real problem? If you want a fixed client-id per-profile,
> why do you write it to NetworkManager.conf, instead of configuring it in the
> profile?
We generate profiles via template for all worker and control-plane nodes before installation so we don't know each node's MAC at profile creation time, we only know primary interface, eth0, etc. We use systemd oneshot to run a script on boot to write /etc/NetworkManager/conf.d/99-client-id.conf
https://access.redhat.com/solutions/6747451
{% macro set_dhcp_ip(bond, interfaces) -%}
#!/usr/bin/bash
cat <<EOF > /etc/NetworkManager/conf.d/99-client-id.conf
[connection-{{ bond }}]
match-device=interface-name:={{ bond }},interface-name:=br-ex
ipv4.dhcp-client-id=01:$(cat /sys/class/net/{{ interfaces | first }}/address)
ipv6.dhcp-duid=00:03:00:01:$(cat /sys/class/net/{{ interfaces | first }}/address)
EOF
{%- endmacro %}
Maybe if there was a nm-settings macro that could set lookup an arbitrary interface hwaddr or perm_hwaddr. We also need to set IAID.
FYI DHCPv6 DUID doesn't really work in our use case because of dnsmasq DHCPv6 reservation issues when IAID changes.
--- Additional comment from Ross Brattain on 2023-01-03 15:26:35 UTC ---
(In reply to Ross Brattain from comment #5)
> FYI DHCPv6 DUID doesn't really work in our use case because of dnsmasq
> DHCPv6 reservation issues when IAID changes.
In theory we might need something like:
ipv6.dhcp-iaid=$(awk -Wposix -F: '{ printf "%d\n", "0x" $4 $5 $6}' /sys/class/net/{{ interfaces | first }}/address)
Untested.