summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--man/systemd.network.xml39
-rw-r--r--src/network/networkd-dhcp4.c12
-rw-r--r--src/network/networkd-link.c30
3 files changed, 57 insertions, 24 deletions
diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index c849cfc4fe..8c984c5b22 100644
--- a/man/systemd.network.xml
+++ b/man/systemd.network.xml
@@ -917,17 +917,36 @@ Table=1234</programlisting></para>
<varlistentry>
<term><varname>IgnoreCarrierLoss=</varname></term>
<listitem>
- <para>Takes a boolean or a timespan. When true, networkd retains both the static and dynamic
- configuration of the interface even if its carrier is lost. When a timespan is specified,
- networkd waits for the specified timespan, and ignores the carrier loss if the link regain
- its carrier within the timespan. Setting a finite timespan may be useful for a wireless
- interface connecting to a network which has multiple access points with the same SSID, or an
- interface which is reset on changing MTU. When unset, the value specified with
- <varname>ConfigureWithoutCarrier=</varname> is used.</para>
-
- <para>When <varname>ActivationPolicy=</varname> is set to <literal>always-up</literal>, this
- is forced to <literal>true</literal>.
+ <para>Takes a boolean or a timespan. When true, <command>systemd-networkd</command> retains
+ both the static and dynamic configuration of the interface even if its carrier is lost. When
+ false, <command>systemd-networkd</command> drops both the static and dynamic configuration of
+ the interface. When a timespan is specified, <command>systemd-networkd</command> waits for
+ the specified timespan, and ignores the carrier loss if the link regain its carrier within
+ the timespan. Setting 0 seconds is equivalent to <literal>no</literal>, and
+ <literal>infinite</literal> is equivalent to <literal>yes</literal>.</para>
+
+ <para>Setting a finite timespan may be useful when e.g. in the following cases:
+ <itemizedlist>
+ <listitem>
+ <para>A wireless interface connecting to a network which has multiple access points with
+ the same SSID.</para>
+ </listitem>
+ <listitem>
+ <para>Enslaving a wireless interface to a bond interface, which may disconnect from the
+ connected access point and causes its carrier to be lost.</para>
+ </listitem>
+ <listitem>
+ <para>The driver of the interface resets when the MTU is changed.</para>
+ </listitem>
+ </itemizedlist>
</para>
+
+ <para>When <varname>Bond=</varname> is specified to a wireless interface, defaults to 3
+ seconds. When the DHCPv4 client is enabled and <varname>UseMTU=</varname> in the [DHCPv4]
+ sectionis enabled, defaults to 5 seconds. Otherwise, defaults to the value specified with
+ <varname>ConfigureWithoutCarrier=</varname>. When <varname>ActivationPolicy=</varname> is set
+ to <literal>always-up</literal>, this is forced to <literal>yes</literal>, and ignored any
+ user specified values.</para>
</listitem>
</varlistentry>
diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c
index 6bfcf67dd9..d3fd2571e0 100644
--- a/src/network/networkd-dhcp4.c
+++ b/src/network/networkd-dhcp4.c
@@ -735,7 +735,6 @@ static int dhcp4_request_routes(Link *link) {
}
static int dhcp_reset_mtu(Link *link) {
- uint16_t mtu;
int r;
assert(link);
@@ -743,18 +742,9 @@ static int dhcp_reset_mtu(Link *link) {
if (!link->network->dhcp_use_mtu)
return 0;
- r = sd_dhcp_lease_get_mtu(link->dhcp_lease, &mtu);
- if (r == -ENODATA)
- return 0;
- if (r < 0)
- return log_link_error_errno(link, r, "DHCP error: failed to get MTU from lease: %m");
-
- if (link->original_mtu == mtu)
- return 0;
-
r = link_request_to_set_mtu(link, link->original_mtu);
if (r < 0)
- return log_link_error_errno(link, r, "DHCP error: could not reset MTU: %m");
+ return log_link_error_errno(link, r, "DHCP error: Could not queue request to reset MTU: %m");
return 0;
}
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index d509855f48..73850cdea5 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -1636,6 +1636,8 @@ static int link_carrier_lost_handler(sd_event_source *s, uint64_t usec, void *us
}
static int link_carrier_lost(Link *link) {
+ uint16_t dhcp_mtu;
+ usec_t usec;
int r;
assert(link);
@@ -1651,16 +1653,38 @@ static int link_carrier_lost(Link *link) {
if (!link->network)
return 0;
- if (link->network->ignore_carrier_loss_usec == USEC_INFINITY)
+ if (link->network->ignore_carrier_loss_set)
+ /* If IgnoreCarrierLoss= is explicitly specified, then use the specified value. */
+ usec = link->network->ignore_carrier_loss_usec;
+
+ else if (link->network->bond && link->wlan_iftype > 0)
+ /* Enslaving wlan interface to a bond disconnects from the connected AP, and causes its
+ * carrier to be lost. See #19832. */
+ usec = 3 * USEC_PER_SEC;
+
+ else if (link->network->dhcp_use_mtu &&
+ link->dhcp_lease &&
+ sd_dhcp_lease_get_mtu(link->dhcp_lease, &dhcp_mtu) >= 0 &&
+ dhcp_mtu != link->original_mtu)
+ /* Some drivers reset interfaces when changing MTU. Resetting interfaces by the static
+ * MTU should not cause any issues, as MTU is changed only once. However, setting MTU
+ * through DHCP lease causes an infinite loop of resetting the interface. See #18738. */
+ usec = 5 * USEC_PER_SEC;
+
+ else
+ /* Otherwise, use the currently set value. */
+ usec = link->network->ignore_carrier_loss_usec;
+
+ if (usec == USEC_INFINITY)
return 0;
- if (link->network->ignore_carrier_loss_usec == 0)
+ if (usec == 0)
return link_carrier_lost_impl(link);
return event_reset_time_relative(link->manager->event,
&link->carrier_lost_timer,
CLOCK_BOOTTIME,
- link->network->ignore_carrier_loss_usec,
+ usec,
0,
link_carrier_lost_handler,
link,