]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
networkd: add support to keep configuration
authorSusant Sahani <ssahani@vmware.com>
Mon, 3 Jun 2019 03:31:13 +0000 (12:31 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 6 Jun 2019 13:50:29 +0000 (22:50 +0900)
src/network/networkd-dhcp4.c
src/network/networkd-link.c
src/network/networkd-network-gperf.gperf
src/network/networkd-network.c
src/network/networkd-network.h
test/fuzz/fuzz-network-parser/directives.network

index 4ed020ea8e59b5f9e9bac8605ec03a2371387127..88a72e39a98bbc5fd9483edcbbd0e977b5c5477b 100644 (file)
@@ -464,7 +464,7 @@ static int dhcp_lease_renew(sd_dhcp_client *client, Link *link) {
         if (r < 0)
                 return log_link_warning_errno(link, r, "DHCP error: no netmask: %m");
 
-        if (!link->network->dhcp_critical) {
+        if (!FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP)) {
                 r = sd_dhcp_lease_get_lifetime(link->dhcp_lease, &lifetime);
                 if (r < 0)
                         return log_link_warning_errno(link, r, "DHCP error: no lifetime: %m");
@@ -581,7 +581,7 @@ static int dhcp_lease_acquired(sd_dhcp_client *client, Link *link) {
                 }
         }
 
-        if (!link->network->dhcp_critical) {
+        if (!FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP)) {
                 r = sd_dhcp_lease_get_lifetime(link->dhcp_lease, &lifetime);
                 if (r < 0)
                         return log_link_warning_errno(link, r, "DHCP error: no lifetime: %m");
@@ -649,7 +649,7 @@ static int dhcp4_handler(sd_dhcp_client *client, int event, void *userdata) {
                                         return log_link_warning_errno(link, r, "Could not acquire IPv4 link-local address: %m");
                         }
 
-                        if (link->network->dhcp_critical) {
+                        if (FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP)) {
                                 log_link_notice(link, "DHCPv4 connection considered critical, ignoring request to reconfigure it.");
                                 return 0;
                         }
@@ -669,7 +669,7 @@ static int dhcp4_handler(sd_dhcp_client *client, int event, void *userdata) {
                 case SD_DHCP_CLIENT_EVENT_EXPIRED:
                 case SD_DHCP_CLIENT_EVENT_IP_CHANGE:
 
-                        if (link->network->dhcp_critical) {
+                        if (FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP)) {
                                 log_link_notice(link, "DHCPv4 connection considered critical, ignoring request to reconfigure it.");
                                 return 0;
                         }
index 6613992a091f5fe043a7c24d676dc568f9f1498b..b38a3a00b207c808bf419ffaad76c1cf37fe4fdd 100644 (file)
@@ -2578,7 +2578,8 @@ static int link_configure(Link *link) {
 
         /* Drop foreign config, but ignore loopback or critical devices.
          * We do not want to remove loopback address or addresses used for root NFS. */
-        if (!(link->flags & IFF_LOOPBACK) && !(link->network->dhcp_critical)) {
+        if (!(link->flags & IFF_LOOPBACK) &&
+            !(link->network->keep_configuration & (KEEP_CONFIGURATION_DHCP | KEEP_CONFIGURATION_STATIC))) {
                 r = link_drop_foreign_config(link);
                 if (r < 0)
                         return r;
index 9ef07ea372be1927393cc95028d4f5284b51aa0d..2986ff1123d92c95cd3c9b356f8864410abba513 100644 (file)
@@ -87,6 +87,7 @@ Network.IPv6ProxyNDPAddress,            config_parse_ipv6_proxy_ndp_address,
 Network.BindCarrier,                    config_parse_strv,                               0,                             offsetof(Network, bind_carrier)
 Network.ConfigureWithoutCarrier,        config_parse_bool,                               0,                             offsetof(Network, configure_without_carrier)
 Network.IgnoreCarrierLoss,              config_parse_bool,                               0,                             offsetof(Network, ignore_carrier_loss)
+Network.KeepConfiguration,              config_parse_keep_configuration,                 0,                             offsetof(Network, keep_configuration)
 Address.Address,                        config_parse_address,                            0,                             0
 Address.Peer,                           config_parse_address,                            0,                             0
 Address.Broadcast,                      config_parse_broadcast,                          0,                             0
@@ -143,7 +144,7 @@ DHCP.Anonymize,                         config_parse_bool,
 DHCP.SendHostname,                      config_parse_bool,                               0,                             offsetof(Network, dhcp_send_hostname)
 DHCP.Hostname,                          config_parse_hostname,                           0,                             offsetof(Network, dhcp_hostname)
 DHCP.RequestBroadcast,                  config_parse_bool,                               0,                             offsetof(Network, dhcp_broadcast)
-DHCP.CriticalConnection,                config_parse_bool,                               0,                             offsetof(Network, dhcp_critical)
+DHCP.CriticalConnection,                config_parse_tristate,                           0,                             offsetof(Network, dhcp_critical) /* deprecated */
 DHCP.VendorClassIdentifier,             config_parse_string,                             0,                             offsetof(Network, dhcp_vendor_class_identifier)
 DHCP.MaxAttempts,                       config_parse_dhcp_max_attempts,                  0,                             0
 DHCP.UserClass,                         config_parse_dhcp_user_class,                    0,                             offsetof(Network, dhcp_user_class)
index a5e7cad58a4c9b910d4bd647e8397fe26912a424..941adebaf1e58f4675d863f08ae767235d1de221 100644 (file)
@@ -239,6 +239,20 @@ int network_verify(Network *network) {
                 network->dhcp_use_mtu = false;
         }
 
+        if (network->dhcp_critical >= 0) {
+                if (network->keep_configuration >= 0)
+                        log_warning("%s: Both KeepConfiguration= and deprecated CriticalConnection= are set. "
+                                    "Ignoring CriticalConnection=.", network->filename);
+                else if (network->dhcp_critical)
+                        /* CriticalConnection=yes also preserve foreign static configurations. */
+                        network->keep_configuration = KEEP_CONFIGURATION_YES;
+                else
+                        network->keep_configuration = KEEP_CONFIGURATION_NO;
+        }
+
+        if (network->keep_configuration < 0)
+                network->keep_configuration = KEEP_CONFIGURATION_NO;
+
         LIST_FOREACH_SAFE(addresses, address, address_next, network->static_addresses)
                 if (address_section_verify(address) < 0)
                         address_free(address);
@@ -324,6 +338,7 @@ int network_load_one(Manager *manager, const char *filename) {
                 .required_for_online = true,
                 .required_operstate_for_online = LINK_OPERSTATE_DEGRADED,
                 .dhcp = ADDRESS_FAMILY_NO,
+                .dhcp_critical = -1,
                 .dhcp_use_ntp = true,
                 .dhcp_use_dns = true,
                 .dhcp_use_hostname = true,
@@ -392,6 +407,8 @@ int network_load_one(Manager *manager, const char *filename) {
                 .ipv6_accept_ra_route_table = RT_TABLE_MAIN,
                 .ipv6_accept_ra_route_table_set = false,
 
+                .keep_configuration = _KEEP_CONFIGURATION_INVALID,
+
                 .can_triple_sampling = -1,
         };
 
@@ -1752,3 +1769,15 @@ int config_parse_required_for_online(
 
         return 0;
 }
+
+DEFINE_CONFIG_PARSE_ENUM(config_parse_keep_configuration, keep_configuration, KeepConfiguration,
+                         "Failed to parse KeepConfiguration= setting");
+
+static const char* const keep_configuration_table[_KEEP_CONFIGURATION_MAX] = {
+        [KEEP_CONFIGURATION_NO]     = "no",
+        [KEEP_CONFIGURATION_DHCP]   = "dhcp",
+        [KEEP_CONFIGURATION_STATIC] = "static",
+        [KEEP_CONFIGURATION_YES]    = "yes",
+};
+
+DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration, KeepConfiguration, KEEP_CONFIGURATION_YES);
index d2a0b8c5f14ee6d59e637d4033d7da34390ae7a7..ca1c6fcdb316f93c7a0eea773e2adc324b358bcb 100644 (file)
@@ -78,6 +78,15 @@ typedef enum RADVPrefixDelegation {
         _RADV_PREFIX_DELEGATION_INVALID = -1,
 } RADVPrefixDelegation;
 
+typedef enum KeepConfiguration {
+        KEEP_CONFIGURATION_NO     = 0,
+        KEEP_CONFIGURATION_DHCP   = 1 << 0,
+        KEEP_CONFIGURATION_STATIC = 1 << 1,
+        KEEP_CONFIGURATION_YES    = KEEP_CONFIGURATION_DHCP | KEEP_CONFIGURATION_STATIC,
+        _KEEP_CONFIGURATION_MAX,
+        _KEEP_CONFIGURATION_INVALID = -1,
+} KeepConfiguration;
+
 typedef struct Manager Manager;
 
 struct Network {
@@ -119,7 +128,7 @@ struct Network {
         bool dhcp_anonymize;
         bool dhcp_send_hostname;
         bool dhcp_broadcast;
-        bool dhcp_critical;
+        int dhcp_critical;
         bool dhcp_use_dns;
         bool dhcp_use_ntp;
         bool dhcp_use_mtu;
@@ -227,6 +236,7 @@ struct Network {
         bool unmanaged;
         bool configure_without_carrier;
         bool ignore_carrier_loss;
+        KeepConfiguration keep_configuration;
         uint32_t iaid;
         DUID duid;
 
@@ -318,6 +328,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_ntp);
 CONFIG_PARSER_PROTOTYPE(config_parse_iaid);
 CONFIG_PARSER_PROTOTYPE(config_parse_required_for_online);
 CONFIG_PARSER_PROTOTYPE(config_parse_dhcp_max_attempts);
+CONFIG_PARSER_PROTOTYPE(config_parse_keep_configuration);
 /* Legacy IPv4LL support */
 CONFIG_PARSER_PROTOTYPE(config_parse_ipv4ll);
 
@@ -336,3 +347,6 @@ DHCPUseDomains dhcp_use_domains_from_string(const char *s) _pure_;
 
 const char* radv_prefix_delegation_to_string(RADVPrefixDelegation i) _const_;
 RADVPrefixDelegation radv_prefix_delegation_from_string(const char *s) _pure_;
+
+const char* keep_configuration_to_string(KeepConfiguration i) _const_;
+KeepConfiguration keep_configuration_from_string(const char *s) _pure_;
index bba8948d35271dcc0a8a3ed1f8d19f9722fc07c6..496c52336cb6d312241c306e52c48536ba4ba806 100644 (file)
@@ -135,6 +135,7 @@ DHCPServer=
 BindCarrier=
 VRF=
 IgnoreCarrierLoss=
+KeepConfiguration=
 [IPv6Prefix]
 Prefix=
 OnLink=