diff --git a/docs/ENVIRONMENT.md b/docs/ENVIRONMENT.md index e9e82cfca4..eaac288ec5 100644 --- a/docs/ENVIRONMENT.md +++ b/docs/ENVIRONMENT.md @@ -92,13 +92,14 @@ systemd-logind: for it. * `$NET_NAMING_SCHEME=` – if set, takes a network naming scheme (i.e. one of - v238, v239, v240 …) as parameter. If specified udev's net_id builtin will - follow the specified naming scheme when determining stable network interface - names. This may be used to revert to naming schemes of older udev versions, - in order to provide more stable naming across updates. This environment - variable takes precedence over the kernel command line option - `net.naming-scheme=`, except if the value is prefixed with `:` in which case - the kernel command line option takes precedence, if it is specified as well. + "v238", "v239", "v240"…, or the special value "latest") as parameter. If + specified udev's net_id builtin will follow the specified naming scheme when + determining stable network interface names. This may be used to revert to + naming schemes of older udev versions, in order to provide more stable naming + across updates. This environment variable takes precedence over the kernel + command line option `net.naming-scheme=`, except if the value is prefixed + with `:` in which case the kernel command line option takes precedence, if it + is specified as well. installed systemd tests: diff --git a/man/systemd-udevd.service.xml b/man/systemd-udevd.service.xml index b1409698ab..330700d7dd 100644 --- a/man/systemd-udevd.service.xml +++ b/man/systemd-udevd.service.xml @@ -174,16 +174,20 @@ net.naming-scheme= Network interfaces are renamed to give them predictable names when possible (unless - net.ifnames=0 is specified, see above). The names are derived from various device metadata - fields. Newer versions of systemd-udevd.service take more of these fields into account, - improving (and thus possibly changing) the names used for the same devices. With this kernel command line - option it is possible to pick a specific version of this algorithm. It expects a naming scheme identifier as - argument. Currently the following identifiers are known: v238, v239, - v240 which each implement the naming scheme that was the default in the indicated systemd - version. Note that selecting a specific scheme is not sufficient to fully stabilize interface naming: the - naming is generally derived from driver attributes exposed by the kernel. As the kernel is updated, - previously missing attributes systemd-udevd.service is checking might appear, which - affects older name derivation algorithms, too. + net.ifnames=0 is specified, see above). The names are derived from various + device metadata fields. Newer versions of systemd-udevd.service take more of + these fields into account, improving (and thus possibly changing) the names used for the same + devices. With this kernel command line option it is possible to pick a specific version of this + algorithm. It expects a naming scheme identifier as argument. Currently the following identifiers + are known: v238, v239, v240 which each + implement the naming scheme that was the default in the indicated systemd version. In addition, + latest may be used to designate the latest scheme known (to this particular + version of systemd-udevd.service). + + Note that selecting a specific scheme is not sufficient to fully stabilize interface naming: + the naming is generally derived from driver attributes exposed by the kernel. As the kernel is + updated, previously missing attributes systemd-udevd.service is checking might + appear, which affects older name derivation algorithms, too. diff --git a/meson.build b/meson.build index 1f44c0fe70..d8e35e618d 100644 --- a/meson.build +++ b/meson.build @@ -694,6 +694,9 @@ else conf.set('DEFAULT_HIERARCHY', 'CGROUP_UNIFIED_ALL') endif +default_net_naming_scheme = get_option('default-net-naming-scheme') +conf.set_quoted('DEFAULT_NET_NAMING_SCHEME', default_net_naming_scheme) + time_epoch = get_option('time-epoch') if time_epoch == -1 NEWS = files('NEWS') @@ -3093,6 +3096,7 @@ status = [ 'default DNSSEC mode: @0@'.format(default_dnssec), 'default DNS-over-TLS mode: @0@'.format(default_dns_over_tls), 'default cgroup hierarchy: @0@'.format(default_hierarchy), + 'default net.naming-scheme setting: @0@'.format(default_net_naming_scheme), 'default KillUserProcesses setting: @0@'.format(kill_user_processes)] alt_dns_servers = '\n '.join(dns_servers.split(' ')) diff --git a/meson_options.txt b/meson_options.txt index 62167ae92d..1423b8998e 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -156,6 +156,9 @@ option('compat-gateway-hostname', type : 'boolean', value : 'false', option('default-hierarchy', type : 'combo', choices : ['legacy', 'hybrid', 'unified'], value : 'hybrid', description : 'default cgroup hierarchy') +option('default-net-naming-scheme', type : 'combo', + choices : ['latest', 'v238', 'v239', 'v240'], + description : 'default net.naming-scheme= value') option('time-epoch', type : 'integer', value : '-1', description : 'time epoch for time clients') option('system-uid-max', type : 'integer', value : '-1', diff --git a/src/udev/udev-builtin-net_id.c b/src/udev/udev-builtin-net_id.c index 18d8d3b8e8..0292c4973c 100644 --- a/src/udev/udev-builtin-net_id.c +++ b/src/udev/udev-builtin-net_id.c @@ -193,6 +193,19 @@ struct virtfn_info { char suffix[IFNAMSIZ]; }; +static const NamingScheme* naming_scheme_from_name(const char *name) { + size_t i; + + if (streq(name, "latest")) + return naming_schemes + ELEMENTSOF(naming_schemes) - 1; + + for (i = 0; i < ELEMENTSOF(naming_schemes); i++) + if (streq(naming_schemes[i].name, name)) + return naming_schemes + i; + + return NULL; +} + static const NamingScheme* naming_scheme(void) { static const NamingScheme *cache = NULL; _cleanup_free_ char *buffer = NULL; @@ -216,24 +229,18 @@ static const NamingScheme* naming_scheme(void) { k = buffer; if (k) { - size_t i; + cache = naming_scheme_from_name(k); + if (cache) { + log_info("Using interface naming scheme '%s'.", cache->name); + return cache; + } - for (i = 0; i < ELEMENTSOF(naming_schemes); i++) - if (streq(naming_schemes[i].name, k)) { - cache = naming_schemes + i; - break; - } - - if (!cache) - log_warning("Unknown interface naming scheme '%s' requested, ignoring.", k); + log_warning("Unknown interface naming scheme '%s' requested, ignoring.", k); } - if (cache) - log_info("Using interface naming scheme '%s'.", cache->name); - else { - cache = naming_schemes + ELEMENTSOF(naming_schemes) - 1; - log_info("Using default interface naming scheme '%s'.", cache->name); - } + cache = naming_scheme_from_name(DEFAULT_NET_NAMING_SCHEME); + assert(cache); + log_info("Using default interface naming scheme '%s'.", cache->name); return cache; }