]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: automatically determine timeout of waiting for carrier regain
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 29 Mar 2022 15:52:09 +0000 (00:52 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 31 Mar 2022 00:29:42 +0000 (09:29 +0900)
The commit 6706ce2fd2a13df0ae5e469b72d688eaf643dac4 made
IgnoreCarrierLoss= setting also take timespan, to make users handle
issues like #18738 or #20887. But still users needed to explicitly set
a timespan.

This makes networkd automatically determine the timeout when the
situations #18738 or #19832 is detected. Unfortunately, still users have
issue #20887 need to specify a value.

Closes #19832.

man/systemd.network.xml
src/network/networkd-link.c

index c849cfc4fee3aae35d192558c09f17b2015f262a..8c984c5b228639f217457b04c82e2f8c5b6d934b 100644 (file)
@@ -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>
 
index d509855f48d05d4a42dc8a433a19609588f1b0dc..73850cdea596aa3608b8481097ec84a3e671bbb9 100644 (file)
@@ -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,