]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: Allow to configure addr_gen_mode 15167/head
authorSusant Sahani <ssahani@vmware.com>
Sat, 18 Apr 2020 15:59:29 +0000 (17:59 +0200)
committerSusant Sahani <ssahani@vmware.com>
Thu, 21 May 2020 12:41:04 +0000 (14:41 +0200)
Defines how link-local and autoconf addresses are generated.

0: generate address based on EUI64 (default)
1: do no generate a link-local address, use EUI64 for addresses generated
   from autoconf
2: generate stable privacy addresses, using the secret from
   stable_secret (RFC7217)
3: generate stable privacy addresses, using a random secret if unset

man/systemd.network.xml
src/network/networkd-link.c
src/network/networkd-link.h
src/network/networkd-network-gperf.gperf
src/network/networkd-network.c
src/network/networkd-network.h
test/fuzz/fuzz-network-parser/directives.network

index 1aa9b132df71efe677fabc0dacb35f9e6bf05a76..f9e8fa5c258f64630e7dc457d43961bb1cadd83d 100644 (file)
           This happens when multicast routing is enabled.</para>
         </listitem>
       </varlistentry>
+      <varlistentry>
+        <term><varname>IPv6LinkLocalAddressGenerationMode=</varname></term>
+        <listitem>
+          <para>Specifies how IPv6 link local address is generated. Takes one of <literal>eui64</literal>,
+          <literal>none</literal>, <literal>stable-privacy</literal> and <literal>random</literal>.
+          When unset, the kernel's default will be used. Note that if <varname>LinkLocalAdressing=</varname>
+          not configured as <literal>ipv6</literal> then <varname>IPv6LinkLocalAddressGenerationMode=</varname>
+          is ignored.</para>
+        </listitem>
+      </varlistentry>
       <varlistentry>
         <term><varname>Unmanaged=</varname></term>
         <listitem>
index 32fe86045d6172cdaae813b1eaf7aff2ad3e09b2..59e37baa6bf1b7bab94185f97f6bcca93ca732b9 100644 (file)
@@ -1692,12 +1692,18 @@ static int link_configure_addrgen_mode(Link *link) {
 
         if (!link_ipv6ll_enabled(link))
                 ipv6ll_mode = IN6_ADDR_GEN_MODE_NONE;
-        else if (sysctl_read_ip_property(AF_INET6, link->ifname, "stable_secret", NULL) < 0)
-                /* The file may not exist. And even if it exists, when stable_secret is unset,
-                 * reading the file fails with EIO. */
-                ipv6ll_mode = IN6_ADDR_GEN_MODE_EUI64;
-        else
-                ipv6ll_mode = IN6_ADDR_GEN_MODE_STABLE_PRIVACY;
+        else if (link->network->ipv6_address_gen_mode < 0) {
+                r = sysctl_read_ip_property(AF_INET6, link->ifname, "stable_secret", NULL);
+                if (r < 0) {
+                        /* The file may not exist. And even if it exists, when stable_secret is unset,
+                         * reading the file fails with EIO. */
+                        log_link_debug_errno(link, r, "Failed to read sysctl property stable_secret: %m");
+
+                        ipv6ll_mode = IN6_ADDR_GEN_MODE_EUI64;
+                } else
+                        ipv6ll_mode = IN6_ADDR_GEN_MODE_STABLE_PRIVACY;
+        } else
+                ipv6ll_mode = link->network->ipv6_address_gen_mode;
 
         r = sd_netlink_message_append_u8(req, IFLA_INET6_ADDR_GEN_MODE, ipv6ll_mode);
         if (r < 0)
@@ -4434,6 +4440,16 @@ void link_clean(Link *link) {
         link_unref(set_remove(link->manager->dirty_links, link));
 }
 
+static const char* const link_ipv6_address_gen_mode_table[_LINK_IPV6_ADDRESS_GEN_MODE_MAX] = {
+        [LINK_IPV6_ADDRESSS_GEN_MODE_EUI64] = "eui64",
+        [LINK_IPV6_ADDRESSS_GEN_MODE_NONE] = "none",
+        [LINK_IPV6_ADDRESSS_GEN_MODE_STABLE_PRIVACY] = "stable-privacy",
+        [LINK_IPV6_ADDRESSS_GEN_MODE_RANDOM] = "random",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(link_ipv6_address_gen_mode, LinkIPv6AddressGenMode);
+DEFINE_CONFIG_PARSE_ENUM(config_parse_link_ipv6_address_gen_mode, link_ipv6_address_gen_mode, LinkIPv6AddressGenMode, "Failed to parse link IPv6 address generation mode");
+
 static const char* const link_state_table[_LINK_STATE_MAX] = {
         [LINK_STATE_PENDING] = "pending",
         [LINK_STATE_INITIALIZED] = "initialized",
index 3d07d882cda14a4d9cc6269a85aadbf142781657..e8d67e0d64fc817a604fcdf3ec21ccbae4e8143a 100644 (file)
@@ -35,6 +35,15 @@ typedef enum LinkState {
         _LINK_STATE_INVALID = -1
 } LinkState;
 
+typedef enum LinkIPv6AddressGenMode {
+       LINK_IPV6_ADDRESSS_GEN_MODE_EUI64          = IN6_ADDR_GEN_MODE_EUI64,
+       LINK_IPV6_ADDRESSS_GEN_MODE_NONE           = IN6_ADDR_GEN_MODE_NONE,
+       LINK_IPV6_ADDRESSS_GEN_MODE_STABLE_PRIVACY = IN6_ADDR_GEN_MODE_STABLE_PRIVACY,
+       LINK_IPV6_ADDRESSS_GEN_MODE_RANDOM         = IN6_ADDR_GEN_MODE_RANDOM,
+       _LINK_IPV6_ADDRESS_GEN_MODE_MAX,
+       _LINK_IPV6_ADDRESS_GEN_MODE_INVALID        = -1
+} LinkIPv6AddressGenMode;
+
 typedef struct Manager Manager;
 typedef struct Network Network;
 typedef struct Address Address;
@@ -209,6 +218,9 @@ int link_stop_clients(Link *link, bool may_keep_dhcp);
 const char* link_state_to_string(LinkState s) _const_;
 LinkState link_state_from_string(const char *s) _pure_;
 
+const char* link_ipv6_address_gen_mode_to_string(LinkIPv6AddressGenMode s) _const_;
+LinkIPv6AddressGenMode link_ipv6_address_gen_mode_from_string(const char *s) _pure_;
+
 uint32_t link_get_vrf_table(Link *link);
 uint32_t link_get_dhcp_route_table(Link *link);
 uint32_t link_get_ipv6_accept_ra_route_table(Link *link);
@@ -217,6 +229,8 @@ int link_request_set_nexthop(Link *link);
 
 int link_reconfigure(Link *link, bool force);
 
+CONFIG_PARSER_PROTOTYPE(config_parse_link_ipv6_address_gen_mode);
+
 int log_link_message_full_errno(Link *link, sd_netlink_message *m, int level, int err, const char *msg);
 #define log_link_message_error_errno(link, m, err, msg)   log_link_message_full_errno(link, m, LOG_ERR, err, msg)
 #define log_link_message_warning_errno(link, m, err, msg) log_link_message_full_errno(link, m, LOG_WARNING, err, msg)
index 3749ff6b8d994cdcf6e60917e723594fcc142a52..a2dd5479b2173467cf8eb6710b16ea87a1a216ab 100644 (file)
@@ -51,6 +51,7 @@ Link.ARP,                                    config_parse_tristate,
 Link.Multicast,                              config_parse_tristate,                                    0,                             offsetof(Network, multicast)
 Link.AllMulticast,                           config_parse_tristate,                                    0,                             offsetof(Network, allmulticast)
 Link.Unmanaged,                              config_parse_bool,                                        0,                             offsetof(Network, unmanaged)
+Link.IPv6LinkLocalAddressGenerationMode,     config_parse_link_ipv6_address_gen_mode,                  0,                             offsetof(Network, ipv6_address_gen_mode)
 Link.RequiredForOnline,                      config_parse_required_for_online,                         0,                             0
 Network.Description,                         config_parse_string,                                      0,                             offsetof(Network, description)
 Network.Bridge,                              config_parse_ifname,                                      0,                             offsetof(Network, bridge_name)
index cd57df6d3dbe81e141c2c2279d4dc707deff9213..1b4083febf23432d7b32093b28a7b10ef97ac1b0 100644 (file)
@@ -461,7 +461,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
                 .ipv6_accept_ra_start_dhcp6_client = true,
 
                 .keep_configuration = _KEEP_CONFIGURATION_INVALID,
-
+                .ipv6_address_gen_mode = _LINK_IPV6_ADDRESS_GEN_MODE_INVALID,
                 .can_triple_sampling = -1,
                 .can_termination = -1,
                 .ip_service_type = -1,
index 6811658fcc238857d29e956d0efe0835ee160629..362ef6508f7f468d453bad7ead50a70ce0dc5c33 100644 (file)
@@ -259,6 +259,7 @@ struct Network {
         bool configure_without_carrier;
         bool ignore_carrier_loss;
         KeepConfiguration keep_configuration;
+        LinkIPv6AddressGenMode ipv6_address_gen_mode;
         uint32_t iaid;
         DUID duid;
 
index 625842a9ba18dc0c43483d337c887b5393e7c3b3..2b95192672507acb3c1006eee44741ab554cf3b2 100644 (file)
@@ -38,6 +38,7 @@ MTUBytes=
 Multicast=
 MACAddress=
 Group=
+IPv6LinkLocalAddressGenerationMode=
 [BridgeFDB]
 VLANId=
 MACAddress=