1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 #pragma once
3 
4 #include <stdbool.h>
5 
6 #include "macro.h"
7 
8 /* So here's the deal: net_id is supposed to be an exercise in providing stable names for network devices. However, we
9  * also want to keep updating the naming scheme used in future versions of net_id. These two goals of course are
10  * contradictory: on one hand we want things to not change and on the other hand we want them to improve. Our way out
11  * of this dilemma is to introduce the "naming scheme" concept: each time we improve the naming logic we define a new
12  * flag for it. Then, we keep a list of schemes, each identified by a name associated with the flags it implements. Via
13  * a kernel command line and environment variable we then allow the user to pick the scheme they want us to follow:
14  * installers could "freeze" the used scheme at the moment of installation this way.
15  *
16  * Developers: each time you tweak the naming logic here, define a new flag below, and condition the tweak with
17  * it. Each time we do a release we'll then add a new scheme entry and include all newly defined flags.
18  *
19  * Note that this is only half a solution to the problem though: not only udev/net_id gets updated all the time, the
20  * kernel gets too. And thus a kernel that previously didn't expose some sysfs attribute we look for might eventually
21  * do, and thus affect our naming scheme too. Thus, enforcing a naming scheme will make interfacing more stable across
22  * OS versions, but not fully stabilize them. */
23 typedef enum NamingSchemeFlags {
24         /* First, the individual features */
25         NAMING_SR_IOV_V                  = 1 << 0, /* Use "v" suffix for SR-IOV, see 609948c7043a */
26         NAMING_NPAR_ARI                  = 1 << 1, /* Use NPAR "ARI", see 6bc04997b6ea */
27         NAMING_INFINIBAND                = 1 << 2, /* Use "ib" prefix for infiniband, see 938d30aa98df */
28         NAMING_ZERO_ACPI_INDEX           = 1 << 3, /* Use zero acpi_index field, see d81186ef4f6a */
29         NAMING_ALLOW_RERENAMES           = 1 << 4, /* Allow re-renaming of devices, see #9006 */
30         NAMING_STABLE_VIRTUAL_MACS       = 1 << 5, /* Use device name to generate MAC, see 6d3646406560 */
31         NAMING_NETDEVSIM                 = 1 << 6, /* Generate names for netdevsim devices, see eaa9d507d855 */
32         NAMING_LABEL_NOPREFIX            = 1 << 7, /* Don't prepend ID_NET_LABEL_ONBOARD with interface type prefix */
33         NAMING_NSPAWN_LONG_HASH          = 1 << 8, /* Shorten nspawn interfaces by including 24bit hash, instead of simple truncation  */
34         NAMING_BRIDGE_NO_SLOT            = 1 << 9, /* Don't use PCI hotplug slot information if the corresponding device is a PCI bridge */
35         NAMING_SLOT_FUNCTION_ID          = 1 << 10, /* Use function_id if present to identify PCI hotplug slots */
36         NAMING_16BIT_INDEX               = 1 << 11, /* Allow full 16-bit for the onboard index */
37         NAMING_REPLACE_STRICTLY          = 1 << 12, /* Use udev_replace_ifname() for NAME= rule */
38         NAMING_XEN_VIF                   = 1 << 13, /* Generate names for Xen netfront devices */
39         NAMING_BRIDGE_MULTIFUNCTION_SLOT = 1 << 14, /* Use PCI hotplug slot information associated with bridge, but only if PCI device is multifunction */
40 
41         /* And now the masks that combine the features above */
42         NAMING_V238 = 0,
43         NAMING_V239 = NAMING_V238 | NAMING_SR_IOV_V | NAMING_NPAR_ARI,
44         NAMING_V240 = NAMING_V239 | NAMING_INFINIBAND | NAMING_ZERO_ACPI_INDEX | NAMING_ALLOW_RERENAMES,
45         NAMING_V241 = NAMING_V240 | NAMING_STABLE_VIRTUAL_MACS,
46         NAMING_V243 = NAMING_V241 | NAMING_NETDEVSIM | NAMING_LABEL_NOPREFIX,
47         NAMING_V245 = NAMING_V243 | NAMING_NSPAWN_LONG_HASH,
48         NAMING_V247 = NAMING_V245 | NAMING_BRIDGE_NO_SLOT,
49         NAMING_V249 = NAMING_V247 | NAMING_SLOT_FUNCTION_ID | NAMING_16BIT_INDEX | NAMING_REPLACE_STRICTLY,
50         NAMING_V250 = NAMING_V249 | NAMING_XEN_VIF,
51         NAMING_V251 = NAMING_V250 | NAMING_BRIDGE_MULTIFUNCTION_SLOT,
52 
53         EXTRA_NET_NAMING_SCHEMES
54 
55         _NAMING_SCHEME_FLAGS_INVALID = -EINVAL,
56 } NamingSchemeFlags;
57 
58 typedef struct NamingScheme {
59         const char *name;
60         NamingSchemeFlags flags;
61 } NamingScheme;
62 
63 const NamingScheme* naming_scheme_from_name(const char *name);
64 const NamingScheme* naming_scheme(void);
65 
naming_scheme_has(NamingSchemeFlags flags)66 static inline bool naming_scheme_has(NamingSchemeFlags flags) {
67         return FLAGS_SET(naming_scheme()->flags, flags);
68 }
69 
70 typedef enum NamePolicy {
71         NAMEPOLICY_KERNEL,
72         NAMEPOLICY_KEEP,
73         NAMEPOLICY_DATABASE,
74         NAMEPOLICY_ONBOARD,
75         NAMEPOLICY_SLOT,
76         NAMEPOLICY_PATH,
77         NAMEPOLICY_MAC,
78         _NAMEPOLICY_MAX,
79         _NAMEPOLICY_INVALID = -EINVAL,
80 } NamePolicy;
81 
82 const char *name_policy_to_string(NamePolicy p) _const_;
83 NamePolicy name_policy_from_string(const char *p) _pure_;
84 
85 const char *alternative_names_policy_to_string(NamePolicy p) _const_;
86 NamePolicy alternative_names_policy_from_string(const char *p) _pure_;
87