summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSusant Sahani <ssahani@vmware.com>2019-06-03 12:31:13 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2019-06-06 22:50:29 +0900
commit7da377ef16a2112a673247b39041a180b07e973a (patch)
tree65d9e287940a1456fd18796b522035245ddffea7
parentf0c53dfe3ce7304e888690f3f72b8561ae9d3e18 (diff)
downloadsystemd-7da377ef16a2112a673247b39041a180b07e973a.tar.gz
systemd-7da377ef16a2112a673247b39041a180b07e973a.tar.bz2
systemd-7da377ef16a2112a673247b39041a180b07e973a.zip
networkd: add support to keep configuration
-rw-r--r--src/network/networkd-dhcp4.c8
-rw-r--r--src/network/networkd-link.c3
-rw-r--r--src/network/networkd-network-gperf.gperf3
-rw-r--r--src/network/networkd-network.c29
-rw-r--r--src/network/networkd-network.h16
-rw-r--r--test/fuzz/fuzz-network-parser/directives.network1
6 files changed, 53 insertions, 7 deletions
diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c
index 4ed020ea8e..88a72e39a9 100644
--- a/src/network/networkd-dhcp4.c
+++ b/src/network/networkd-dhcp4.c
@@ -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;
}
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 6613992a09..b38a3a00b2 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -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;
diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf
index 9ef07ea372..2986ff1123 100644
--- a/src/network/networkd-network-gperf.gperf
+++ b/src/network/networkd-network-gperf.gperf
@@ -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)
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index a5e7cad58a..941adebaf1 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -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);
diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h
index d2a0b8c5f1..ca1c6fcdb3 100644
--- a/src/network/networkd-network.h
+++ b/src/network/networkd-network.h
@@ -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_;
diff --git a/test/fuzz/fuzz-network-parser/directives.network b/test/fuzz/fuzz-network-parser/directives.network
index bba8948d35..496c52336c 100644
--- a/test/fuzz/fuzz-network-parser/directives.network
+++ b/test/fuzz/fuzz-network-parser/directives.network
@@ -135,6 +135,7 @@ DHCPServer=
BindCarrier=
VRF=
IgnoreCarrierLoss=
+KeepConfiguration=
[IPv6Prefix]
Prefix=
OnLink=