mirror of
https://github.com/systemd/systemd.git
synced 2026-08-04 23:20:32 +00:00
Merge pull request #12511 from ssahani/high-avilability-12050
networkd: add new KeepConfiguration= setting
This commit is contained in:
@@ -838,6 +838,22 @@
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>KeepConfiguration=</varname></term>
|
||||
<listitem>
|
||||
<para>Takes a boolean or one of <literal>static</literal>, <literal>dhcp-on-stop</literal>,
|
||||
<literal>dhcp</literal>. When <literal>static</literal>, <command>systemd-networkd</command>
|
||||
will not drop static addresses and routes on starting up process. When set to
|
||||
<literal>dhcp-on-stop</literal>, <command>systemd-networkd</command> will not drop addresses
|
||||
and routes on stopping the daemon. When <literal>dhcp</literal>,
|
||||
the addresses and routes provided by a DHCP server will never be dropped even if the DHCP
|
||||
lease expires. This is contrary to the DHCP specification, but may be the best choice if,
|
||||
e.g., the root filesystem relies on this connection. The setting <literal>dhcp</literal>
|
||||
implies <literal>dhcp-on-stop</literal>, and <literal>yes</literal> implies
|
||||
<literal>dhcp</literal> and <literal>static</literal>. Defaults to
|
||||
<literal>dhcp-on-stop</literal>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
|
||||
@@ -1381,17 +1397,6 @@
|
||||
system. Defaults to <literal>no</literal>.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>CriticalConnection=</varname></term>
|
||||
<listitem>
|
||||
<para>When true, the connection will never be torn down
|
||||
even if the DHCP lease expires. This is contrary to the
|
||||
DHCP specification, but may be the best choice if, say,
|
||||
the root filesystem relies on this connection. Defaults to
|
||||
false.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>ClientIdentifier=</varname></term>
|
||||
<listitem>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -680,14 +680,15 @@ static void link_enter_unmanaged(Link *link) {
|
||||
link_dirty(link);
|
||||
}
|
||||
|
||||
int link_stop_clients(Link *link) {
|
||||
int link_stop_clients(Link *link, bool may_keep_dhcp) {
|
||||
int r = 0, k;
|
||||
|
||||
assert(link);
|
||||
assert(link->manager);
|
||||
assert(link->manager->event);
|
||||
|
||||
if (link->dhcp_client) {
|
||||
if (link->dhcp_client && (!may_keep_dhcp || !link->network ||
|
||||
!FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP_ON_STOP))) {
|
||||
k = sd_dhcp_client_stop(link->dhcp_client);
|
||||
if (k < 0)
|
||||
r = log_link_warning_errno(link, k, "Could not stop DHCPv4 client: %m");
|
||||
@@ -731,7 +732,7 @@ void link_enter_failed(Link *link) {
|
||||
|
||||
link_set_state(link, LINK_STATE_FAILED);
|
||||
|
||||
link_stop_clients(link);
|
||||
link_stop_clients(link, false);
|
||||
|
||||
link_dirty(link);
|
||||
}
|
||||
@@ -2485,6 +2486,33 @@ static bool link_is_static_route_configured(Link *link, Route *route) {
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool link_address_is_dynamic(Link *link, Address *address) {
|
||||
Route *route;
|
||||
Iterator i;
|
||||
|
||||
assert(link);
|
||||
assert(address);
|
||||
|
||||
if (address->cinfo.ifa_prefered != CACHE_INFO_INFINITY_LIFE_TIME)
|
||||
return true;
|
||||
|
||||
/* Even when the address is leased from a DHCP server, networkd assign the address
|
||||
* without lifetime when KeepConfiguration=dhcp. So, let's check that we have
|
||||
* corresponding routes with RTPROT_DHCP. */
|
||||
SET_FOREACH(route, link->routes_foreign, i) {
|
||||
if (route->protocol != RTPROT_DHCP)
|
||||
continue;
|
||||
|
||||
if (address->family != route->family)
|
||||
continue;
|
||||
|
||||
if (in_addr_equal(address->family, &address->in_addr, &route->prefsrc))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static int link_drop_foreign_config(Link *link) {
|
||||
Address *address;
|
||||
Route *route;
|
||||
@@ -2496,6 +2524,12 @@ static int link_drop_foreign_config(Link *link) {
|
||||
if (address->family == AF_INET6 && in_addr_is_link_local(AF_INET6, &address->in_addr) == 1)
|
||||
continue;
|
||||
|
||||
if (link_address_is_dynamic(link, address)) {
|
||||
if (FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP))
|
||||
continue;
|
||||
} else if (FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_STATIC))
|
||||
continue;
|
||||
|
||||
if (link_is_static_address_configured(link, address)) {
|
||||
r = address_add(link, address->family, &address->in_addr, address->prefixlen, NULL);
|
||||
if (r < 0)
|
||||
@@ -2512,6 +2546,14 @@ static int link_drop_foreign_config(Link *link) {
|
||||
if (route->protocol == RTPROT_KERNEL)
|
||||
continue;
|
||||
|
||||
if (route->protocol == RTPROT_STATIC &&
|
||||
FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_STATIC))
|
||||
continue;
|
||||
|
||||
if (route->protocol == RTPROT_DHCP &&
|
||||
FLAGS_SET(link->network->keep_configuration, KEEP_CONFIGURATION_DHCP))
|
||||
continue;
|
||||
|
||||
if (link_is_static_route_configured(link, route)) {
|
||||
r = route_add(link, route->family, &route->dst, route->dst_prefixlen, route->tos, route->priority, route->table, NULL);
|
||||
if (r < 0)
|
||||
@@ -2578,7 +2620,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_YES) {
|
||||
r = link_drop_foreign_config(link);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -3264,7 +3307,7 @@ static int link_carrier_lost(Link *link) {
|
||||
if (link->setting_mtu)
|
||||
return 0;
|
||||
|
||||
r = link_stop_clients(link);
|
||||
r = link_stop_clients(link, false);
|
||||
if (r < 0) {
|
||||
link_enter_failed(link);
|
||||
return r;
|
||||
|
||||
@@ -175,7 +175,7 @@ int dhcp6_configure(Link *link);
|
||||
int dhcp6_request_address(Link *link, int ir);
|
||||
int dhcp6_lease_pd_prefix_lost(sd_dhcp6_client *client, Link* link);
|
||||
|
||||
int link_stop_clients(Link *link);
|
||||
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_;
|
||||
|
||||
@@ -1447,7 +1447,7 @@ void manager_free(Manager *m) {
|
||||
if (link->dhcp6_client)
|
||||
(void) dhcp6_lease_pd_prefix_lost(link->dhcp6_client, link);
|
||||
|
||||
link_stop_clients(link);
|
||||
(void) link_stop_clients(link, true);
|
||||
|
||||
link_unref(link);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -239,6 +239,22 @@ 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
|
||||
/* For backward compatibility, we do not release DHCP addresses on manager stop. */
|
||||
network->keep_configuration = KEEP_CONFIGURATION_DHCP_ON_STOP;
|
||||
}
|
||||
|
||||
if (network->keep_configuration < 0)
|
||||
/* For backward compatibility, we do not release DHCP addresses on manager stop. */
|
||||
network->keep_configuration = KEEP_CONFIGURATION_DHCP_ON_STOP;
|
||||
|
||||
LIST_FOREACH_SAFE(addresses, address, address_next, network->static_addresses)
|
||||
if (address_section_verify(address) < 0)
|
||||
address_free(address);
|
||||
@@ -324,6 +340,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 +409,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 +1771,16 @@ 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_ON_STOP] = "dhcp-on-stop",
|
||||
[KEEP_CONFIGURATION_DHCP] = "dhcp",
|
||||
[KEEP_CONFIGURATION_STATIC] = "static",
|
||||
[KEEP_CONFIGURATION_YES] = "yes",
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(keep_configuration, KeepConfiguration, KEEP_CONFIGURATION_YES);
|
||||
|
||||
@@ -78,6 +78,17 @@ typedef enum RADVPrefixDelegation {
|
||||
_RADV_PREFIX_DELEGATION_INVALID = -1,
|
||||
} RADVPrefixDelegation;
|
||||
|
||||
typedef enum KeepConfiguration {
|
||||
KEEP_CONFIGURATION_NO = 0,
|
||||
KEEP_CONFIGURATION_DHCP_ON_START = 1 << 0,
|
||||
KEEP_CONFIGURATION_DHCP_ON_STOP = 1 << 1,
|
||||
KEEP_CONFIGURATION_DHCP = KEEP_CONFIGURATION_DHCP_ON_START | KEEP_CONFIGURATION_DHCP_ON_STOP,
|
||||
KEEP_CONFIGURATION_STATIC = 1 << 2,
|
||||
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 +130,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 +238,7 @@ struct Network {
|
||||
bool unmanaged;
|
||||
bool configure_without_carrier;
|
||||
bool ignore_carrier_loss;
|
||||
KeepConfiguration keep_configuration;
|
||||
uint32_t iaid;
|
||||
DUID duid;
|
||||
|
||||
@@ -318,6 +330,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 +349,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_;
|
||||
|
||||
@@ -135,6 +135,7 @@ DHCPServer=
|
||||
BindCarrier=
|
||||
VRF=
|
||||
IgnoreCarrierLoss=
|
||||
KeepConfiguration=
|
||||
[IPv6Prefix]
|
||||
Prefix=
|
||||
OnLink=
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
[Match]
|
||||
Name=dummy98
|
||||
|
||||
[Network]
|
||||
KeepConfiguration=static
|
||||
@@ -4,6 +4,4 @@ Name=veth99
|
||||
[Network]
|
||||
DHCP=ipv4
|
||||
IPv6AcceptRA=false
|
||||
|
||||
[DHCP]
|
||||
CriticalConnection=true
|
||||
KeepConfiguration=dhcp-on-stop
|
||||
@@ -0,0 +1,7 @@
|
||||
[Match]
|
||||
Name=veth99
|
||||
|
||||
[Network]
|
||||
DHCP=ipv4
|
||||
IPv6AcceptRA=false
|
||||
KeepConfiguration=dhcp
|
||||
@@ -1235,6 +1235,7 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
||||
'11-dummy.netdev',
|
||||
'12-dummy.netdev',
|
||||
'23-active-slave.network',
|
||||
'24-keep-configuration-static.network',
|
||||
'24-search-domain.network',
|
||||
'25-address-link-section.network',
|
||||
'25-address-preferred-lifetime-zero-ipv6.network',
|
||||
@@ -1658,6 +1659,28 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
||||
self.assertRegex(output, 'DNS: 192.168.42.1')
|
||||
self.assertRegex(output, 'Search Domains: one')
|
||||
|
||||
def test_keep_configuration_static(self):
|
||||
check_output('systemctl stop systemd-networkd')
|
||||
|
||||
check_output('ip link add name dummy98 type dummy')
|
||||
check_output('ip address add 10.1.2.3/16 dev dummy98')
|
||||
check_output('ip address add 10.2.3.4/16 dev dummy98 valid_lft 600 preferred_lft 500')
|
||||
output = check_output('ip address show dummy98')
|
||||
print(output)
|
||||
self.assertRegex(output, 'inet 10.1.2.3/16 scope global dummy98')
|
||||
self.assertRegex(output, 'inet 10.2.3.4/16 scope global dynamic dummy98')
|
||||
output = check_output('ip route show dev dummy98')
|
||||
print(output)
|
||||
|
||||
copy_unit_to_networkd_unit_path('24-keep-configuration-static.network')
|
||||
start_networkd(0)
|
||||
wait_online(['dummy98:routable'])
|
||||
|
||||
output = check_output('ip address show dummy98')
|
||||
print(output)
|
||||
self.assertRegex(output, 'inet 10.1.2.3/16 scope global dummy98')
|
||||
self.assertNotRegex(output, 'inet 10.2.3.4/16 scope global dynamic dummy98')
|
||||
|
||||
class NetworkdBondTests(unittest.TestCase, Utilities):
|
||||
links = [
|
||||
'bond199',
|
||||
@@ -2026,13 +2049,14 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
|
||||
'25-vrf.netdev',
|
||||
'25-vrf.network',
|
||||
'dhcp-client-anonymize.network',
|
||||
'dhcp-client-critical-connection.network',
|
||||
'dhcp-client-gateway-onlink-implicit.network',
|
||||
'dhcp-client-ipv4-dhcp-settings.network',
|
||||
'dhcp-client-ipv4-only-ipv6-disabled.network',
|
||||
'dhcp-client-ipv4-only.network',
|
||||
'dhcp-client-ipv6-only.network',
|
||||
'dhcp-client-ipv6-rapid-commit.network',
|
||||
'dhcp-client-keep-configuration-dhcp-on-stop.network',
|
||||
'dhcp-client-keep-configuration-dhcp.network',
|
||||
'dhcp-client-listen-port.network',
|
||||
'dhcp-client-route-metric.network',
|
||||
'dhcp-client-route-table.network',
|
||||
@@ -2210,26 +2234,84 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
|
||||
print(output)
|
||||
self.assertRegex(output, 'metric 24')
|
||||
|
||||
def test_dhcp_route_criticalconnection_true(self):
|
||||
copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-critical-connection.network')
|
||||
def test_dhcp_keep_configuration_dhcp(self):
|
||||
copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-keep-configuration-dhcp.network')
|
||||
start_networkd(0)
|
||||
wait_online(['veth-peer:carrier'])
|
||||
start_dnsmasq()
|
||||
start_dnsmasq(lease_time='2m')
|
||||
wait_online(['veth99:routable', 'veth-peer:routable'])
|
||||
|
||||
output = check_output('ip address show dev veth99 scope global')
|
||||
print(output)
|
||||
self.assertRegex(output, r'192.168.5.*')
|
||||
|
||||
output = check_output(*networkctl_cmd, 'status', 'veth99', env=env)
|
||||
print(output)
|
||||
self.assertRegex(output, '192.168.5.*')
|
||||
self.assertRegex(output, r'192.168.5.*')
|
||||
|
||||
# Stopping dnsmasq as networkd won't be allowed to renew the DHCP lease.
|
||||
stop_dnsmasq(dnsmasq_pid_file)
|
||||
|
||||
# Sleep for 120 sec as the dnsmasq minimum lease time can only be set to 120
|
||||
print('Wait for the dynamic address to be expired')
|
||||
time.sleep(125)
|
||||
|
||||
print('The lease address should be kept after lease expired')
|
||||
output = check_output('ip address show dev veth99 scope global')
|
||||
print(output)
|
||||
self.assertRegex(output, r'192.168.5.*')
|
||||
|
||||
output = check_output(*networkctl_cmd, 'status', 'veth99', env=env)
|
||||
print(output)
|
||||
self.assertRegex(output, '192.168.5.*')
|
||||
self.assertRegex(output, r'192.168.5.*')
|
||||
|
||||
check_output('systemctl stop systemd-networkd')
|
||||
|
||||
print('The lease address should be kept after networkd stopped')
|
||||
output = check_output('ip address show dev veth99 scope global')
|
||||
print(output)
|
||||
self.assertRegex(output, r'192.168.5.*')
|
||||
|
||||
output = check_output(*networkctl_cmd, 'status', 'veth99', env=env)
|
||||
print(output)
|
||||
self.assertRegex(output, r'192.168.5.*')
|
||||
|
||||
check_output('systemctl start systemd-networkd')
|
||||
wait_online(['veth-peer:routable'])
|
||||
|
||||
print('Still the lease address should be kept after networkd restarted')
|
||||
output = check_output('ip address show dev veth99 scope global')
|
||||
print(output)
|
||||
self.assertRegex(output, r'192.168.5.*')
|
||||
|
||||
output = check_output(*networkctl_cmd, 'status', 'veth99', env=env)
|
||||
print(output)
|
||||
self.assertRegex(output, r'192.168.5.*')
|
||||
|
||||
def test_dhcp_keep_configuration_dhcp_on_stop(self):
|
||||
copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-keep-configuration-dhcp-on-stop.network')
|
||||
start_networkd(0)
|
||||
wait_online(['veth-peer:carrier'])
|
||||
start_dnsmasq(lease_time='2m')
|
||||
wait_online(['veth99:routable', 'veth-peer:routable'])
|
||||
|
||||
output = check_output('ip address show dev veth99 scope global')
|
||||
print(output)
|
||||
self.assertRegex(output, r'192.168.5.*')
|
||||
|
||||
stop_dnsmasq(dnsmasq_pid_file)
|
||||
check_output('systemctl stop systemd-networkd')
|
||||
|
||||
output = check_output('ip address show dev veth99 scope global')
|
||||
print(output)
|
||||
self.assertRegex(output, r'192.168.5.*')
|
||||
|
||||
start_networkd(0)
|
||||
wait_online(['veth-peer:routable'])
|
||||
|
||||
output = check_output('ip address show dev veth99 scope global')
|
||||
print(output)
|
||||
self.assertNotRegex(output, r'192.168.5.*')
|
||||
|
||||
def test_dhcp_client_reuse_address_as_static(self):
|
||||
copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client.network')
|
||||
|
||||
Reference in New Issue
Block a user