networkd: start ipv4ll when dhcp has trouble getting a lease

Fixes #13316.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2020-10-08 20:14:51 +02:00 committed by Yu Watanabe
parent fb536bc5da
commit 0107b769b1
5 changed files with 28 additions and 15 deletions

View File

@ -367,7 +367,9 @@
<para>Enables link-local address autoconfiguration. Accepts <option>yes</option>, <para>Enables link-local address autoconfiguration. Accepts <option>yes</option>,
<option>no</option>, <option>ipv4</option>, and <option>ipv6</option>. An IPv6 link-local address <option>no</option>, <option>ipv4</option>, and <option>ipv6</option>. An IPv6 link-local address
is configured when <option>yes</option> or <option>ipv6</option>. An IPv4 link-local address is is configured when <option>yes</option> or <option>ipv6</option>. An IPv4 link-local address is
configured when <option>yes</option> or <option>ipv4</option>.</para> configured when <option>yes</option> or <option>ipv4</option> and when DHCPv4 autoconfiguration
has been unsuccessful for some time. (IPv4 link-local address autoconfiguration will usually
happen in parallel with repeated attempts to acquire a DHCPv4 lease).</para>
<para>Defaults to <option>no</option> when <varname>Bridge=yes</varname> is set, and <para>Defaults to <option>no</option> when <varname>Bridge=yes</varname> is set, and
<option>ipv6</option> otherwise.</para> <option>ipv6</option> otherwise.</para>
@ -1662,7 +1664,8 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
<para>Specifies how many times the DHCPv4 client configuration should be attempted. Takes a <para>Specifies how many times the DHCPv4 client configuration should be attempted. Takes a
number or <literal>infinity</literal>. Defaults to <literal>infinity</literal>. Note that the number or <literal>infinity</literal>. Defaults to <literal>infinity</literal>. Note that the
time between retries is increased exponentially, up to approximately one per minute, so the time between retries is increased exponentially, up to approximately one per minute, so the
network will not be overloaded even if this number is high.</para> network will not be overloaded even if this number is high. The default is suitable in most
circumstances.</para>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@ -1135,6 +1135,21 @@ static int dhcp4_handler(sd_dhcp_client *client, int event, void *userdata) {
return -ENOMSG; return -ENOMSG;
} }
break; break;
case SD_DHCP_CLIENT_EVENT_TRANSIENT_FAILURE:
if (link_ipv4ll_enabled(link)) {
assert(link->ipv4ll);
if (!sd_ipv4ll_is_running(link->ipv4ll)) {
log_link_debug(link, "Problems acquiring DHCP lease, acquiring IPv4 link-local address");
r = sd_ipv4ll_start(link->ipv4ll);
if (r < 0)
return log_link_warning_errno(link, r, "Could not acquire IPv4 link-local address: %m");
}
}
break;
default: default:
if (event < 0) if (event < 0)
log_link_warning_errno(link, event, "DHCP error: Client failed: %m"); log_link_warning_errno(link, event, "DHCP error: Client failed: %m");

View File

@ -1229,7 +1229,14 @@ static int link_acquire_ipv4_conf(Link *link) {
assert(link->manager); assert(link->manager);
assert(link->manager->event); assert(link->manager->event);
if (link_ipv4ll_enabled(link)) { if (link->dhcp_client) {
log_link_debug(link, "Acquiring DHCPv4 lease");
r = sd_dhcp_client_start(link->dhcp_client);
if (r < 0)
return log_link_warning_errno(link, r, "Could not acquire DHCPv4 lease: %m");
} else if (link_ipv4ll_enabled(link)) {
assert(link->ipv4ll); assert(link->ipv4ll);
log_link_debug(link, "Acquiring IPv4 link-local address"); log_link_debug(link, "Acquiring IPv4 link-local address");
@ -1239,14 +1246,6 @@ static int link_acquire_ipv4_conf(Link *link) {
return log_link_warning_errno(link, r, "Could not acquire IPv4 link-local address: %m"); return log_link_warning_errno(link, r, "Could not acquire IPv4 link-local address: %m");
} }
if (link->dhcp_client) {
log_link_debug(link, "Acquiring DHCPv4 lease");
r = sd_dhcp_client_start(link->dhcp_client);
if (r < 0)
return log_link_warning_errno(link, r, "Could not acquire DHCPv4 lease: %m");
}
return 0; return 0;
} }

View File

@ -4,5 +4,4 @@ Name=veth99
[Network] [Network]
DHCP=yes DHCP=yes
IPv6AcceptRA=yes IPv6AcceptRA=yes
LinkLocalAddressing=yes
VRF=vrf99 VRF=vrf99

View File

@ -3925,7 +3925,6 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
print('## ip address show vrf vrf99') print('## ip address show vrf vrf99')
output = check_output('ip address show vrf vrf99') output = check_output('ip address show vrf vrf99')
print(output) print(output)
self.assertRegex(output, 'inet 169.254.[0-9]*.[0-9]*/16 brd 169.254.255.255 scope link veth99')
self.assertRegex(output, 'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic veth99') self.assertRegex(output, 'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic veth99')
self.assertRegex(output, 'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)') self.assertRegex(output, 'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)')
self.assertRegex(output, 'inet6 .* scope link') self.assertRegex(output, 'inet6 .* scope link')
@ -3933,7 +3932,6 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
print('## ip address show dev veth99') print('## ip address show dev veth99')
output = check_output('ip address show dev veth99') output = check_output('ip address show dev veth99')
print(output) print(output)
self.assertRegex(output, 'inet 169.254.[0-9]*.[0-9]*/16 brd 169.254.255.255 scope link veth99')
self.assertRegex(output, 'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic veth99') self.assertRegex(output, 'inet 192.168.5.[0-9]*/24 brd 192.168.5.255 scope global dynamic veth99')
self.assertRegex(output, 'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)') self.assertRegex(output, 'inet6 2600::[0-9a-f]*/128 scope global (dynamic noprefixroute|noprefixroute dynamic)')
self.assertRegex(output, 'inet6 .* scope link') self.assertRegex(output, 'inet6 .* scope link')
@ -3942,7 +3940,6 @@ class NetworkdDHCPClientTests(unittest.TestCase, Utilities):
output = check_output('ip route show vrf vrf99') output = check_output('ip route show vrf vrf99')
print(output) print(output)
self.assertRegex(output, 'default via 192.168.5.1 dev veth99 proto dhcp src 192.168.5.') self.assertRegex(output, 'default via 192.168.5.1 dev veth99 proto dhcp src 192.168.5.')
self.assertRegex(output, '169.254.0.0/16 dev veth99 proto kernel scope link src 169.254')
self.assertRegex(output, '192.168.5.0/24 dev veth99 proto kernel scope link src 192.168.5') self.assertRegex(output, '192.168.5.0/24 dev veth99 proto kernel scope link src 192.168.5')
self.assertRegex(output, '192.168.5.0/24 via 192.168.5.5 dev veth99 proto dhcp') self.assertRegex(output, '192.168.5.0/24 via 192.168.5.5 dev veth99 proto dhcp')
self.assertRegex(output, '192.168.5.1 dev veth99 proto dhcp scope link src 192.168.5') self.assertRegex(output, '192.168.5.1 dev veth99 proto dhcp scope link src 192.168.5')