On Fedora 38, the version of NetworkMnager is 1.42.8, and the “default” setting for ipv6.add-gen-mode is default. The possible value for ipv6.add-gen-mode is eui64, stable-privacy, default-or-eui64, and default.

This blog post is my attempt to understand a bit more about this IPv6 setting addr-gen-mode. On my workstation, the NetworkManager connection in use in this post is called br0. Here are are some commands to display the version number of NetworkManager and the (default) current setting of ipv6.addr-gen-mode:

➜ rpm -qf `which nmcli`
NetworkManager-1.42.8-1.fc38.x86_64

➜ nmcli -g ipv6.addr-gen-mode con show br0
default

With my limited understanding of IPv6, when ipv6.addr-gen-mode is set to eui64, the result is that the IPv6 assigned to a network interface via SLAAC, will be generated from the physical MAC address of the network interface. The stable-privacy setting, on the other hand, refers to the method used to generate the interface identify for temporary address used in Privacy Extensions for Stateless Address Auto-configuration (SLAAC).

I’ve been trying to find out what both default and default-or-eui64 settings do by searching online without much luck. But, with some perseverance, I switched to search for fedora 38 ipv6.addr-gen-mode, and this time I was lead to this page nm-settings: NetworkManager Reference Manual [1], where some detail about addr-gen-mode is available under “Table 37.ipv6 setting”.

Further more, the nm-settings.html from the URL of [1] gave me some ideas that there might be a MAN page for for nm-settings. So I tried running man 5 nm-settings and I got similar information and more.

   ipv6 setting
       IPv6 Settings.

       Properties:

       addr-gen-mode
           Configure method for creating the address for use with RFC4862 IPv6 Stateless Address Autoconfiguration. The permitted values are:
           NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64 (0), NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY (1).
           NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_DEFAULT_OR_EUI64 (2) or NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_DEFAULT (3).

           If the property is set to EUI64, the addresses will be generated using the interface tokens derived from hardware address. This makes the host
           part of the address to stay constant, making it possible to track host's presence when it changes networks. The address changes when the
           interface hardware is replaced.

           The value of stable-privacy enables use of cryptographically secure hash of a secret host-specific key along with the connection's stable-id and
           the network address as specified by RFC7217. This makes it impossible to use the address track host's presence, and makes the address stable
           when the network interface hardware is replaced.

           The special values "default" and "default-or-eui64" will fallback to the global connection default in as documented in NetworkManager.conf(5)
           manual. If the global default is not specified, the fallback value is "stable-privacy" or "eui64", respectively.

           For libnm, the property defaults to "default" since 1.40. Previously it defaulted to "stable-privacy". On D-Bus, the absence of an addr-gen-mode
           setting equals "default". For keyfile plugin, the absence of the setting on disk means "default-or-eui64" so that the property doesn't change on
           upgrade from older versions.

           Note that this setting is distinct from the Privacy Extensions as configured by "ip6-privacy" property and it does not affect the temporary
           addresses configured with this option.

           Format: int32

Following the suggestion from the above output, I further checked the NeworkManager.conf(5).

➜ man 5 NetworkManager.conf
...
       ipv6.addr-gen-mode
           If the per-profile setting is either "default" or "default-or-eui64", the global default is used. If the default is unspecified, the fallback
           value is either "stable-privacy" or "eui64", depending on whether the per-profile setting is "default" or "default-or-eui64, respectively.

Checking the ipv6.addr-gen-mode in global config of NetworkManager.conf and found nothing:

✗ sudo rg 'ipv6.addr-gen-mode' /etc/NetworkManager/NetworkManager.conf

✗ sudo rg 'ipv6.addr-gen-mode' /etc/NetworkManager/system-connections/*

I think that may explain it, “the default is unspecified, the fallback value is either “stable-privacy”…, … the per-profile setting is ‘default’”.

Well, on my workstation, I’d like its IPv6 to be predictable and to stay constant so that I can conveniently assign an AAAA dns record for it. How to do this? Easy, just change the ipv6.addr-gen-mode in the NetworkManager connection br0 from default to eui64.

➜ sudo nmcli con mod br0 ipv6.addr-gen-mode eui64
...

➜ nmcli -g ipv6.addr-gen-mode conn show br0
eui64

Here’s the output before the br0 connection was restarted (note: the value of IPv6 has been modified to some make up values).

➜ ip -6 a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 state UNKNOWN qlen 1000
    inet6 ::1/128 scope host noprefixroute
       valid_lft forever preferred_lft forever
8: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 state UP qlen 1000
    inet6 2403:5555:cccc:0:7777:bc8a:fd4e:2bd1/64 scope global dynamic noprefixroute
       valid_lft 86330sec preferred_lft 14330sec
    inet6 fe80::dd97:a3dc:7b06:5712/64 scope link noprefixroute
       valid_lft forever preferred_lft forever

Let’s reconnect the br0 connection, which is kinda like restarting the connection:

➜ sudo nmcli con up br0
Connection successfully activated (master waiting for slaves) (D-Bus active path: /org/freedesktop/NetworkManager/ActiveConnection/9)
➜ ip a show br0
8: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether dd:cc:ee:f1:37:83 brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.114/24 brd 192.168.1.255 scope global noprefixroute br0
       valid_lft forever preferred_lft forever
    inet6 2403:5555:cccc:0:7777:efff:fef1:3783/64 scope global dynamic noprefixroute
       valid_lft 86369sec preferred_lft 14369sec
    inet6 fe80::d6c9:efff:fef1:3783/64 scope link noprefixroute
       valid_lft forever preferred_lft forever

That’s it. I learned a bit more about IPv6 today than a few weeks ago, and each day I’m more and more less scared of IPv6.

References: