]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: make degraded-carrier bond/bridge as routable (#27776)
authorHenrik Holst <henrik.holst@millistream.com>
Thu, 15 Jun 2023 04:32:10 +0000 (06:32 +0200)
committerGitHub <noreply@github.com>
Thu, 15 Jun 2023 04:32:10 +0000 (13:32 +0900)
This makes a bond or bridge interface in the degraded-carrier state but has a routable address
handled as routable operational state.

If the carrier is degraded but the address state is routable then the operational state should be
seen as routable and not degraded because that may be the case for bonds if some of the links are down,
but when that happens the bond as whole is still routable.

This also makes operational state to degraded if address state is degraded even if the link state is
degraded-carrier.

Fixes #22713.

man/networkctl.xml
src/network/networkd-link.c
test/test-network/systemd-networkd-tests.py

index 497d88a15f83139fa3e8e86bf52103f803272ba8..7d461786d750ff2078aaee9faf69fcfec9aab713 100644 (file)
@@ -96,8 +96,7 @@
               <varlistentry>
                 <term>degraded-carrier</term>
                 <listitem>
-                  <para>for bond or bridge master, one of the bonding or bridge slave network interfaces is
-                  in off, no-carrier, or dormant state</para>
+                  <para>one of the bonding or bridge slave network interfaces is in off, no-carrier, or dormant state, and the master interface has no address.</para>
                 </listitem>
               </varlistentry>
               <varlistentry>
               <varlistentry>
                 <term>degraded</term>
                 <listitem>
-                  <para>the link has carrier and addresses valid on the local link configured</para>
+                  <para>the link has carrier and addresses valid on the local link configured. For bond or
+                  bridge master this means that not all slave network interfaces have carrier but at least
+                  one does.</para>
                 </listitem>
               </varlistentry>
               <varlistentry>
               <varlistentry>
                 <term>routable</term>
                 <listitem>
-                  <para>the link has carrier and routable address configured</para>
+                  <para>the link has carrier and routable address configured. For bond or bridge master it is
+                  not necessary for all slave network interfaces to have carrier, but at least one must.</para>
                 </listitem>
               </varlistentry>
             </variablelist>
index d16090dbcd20915bd1d8570b304968bed244d731..62dd892afaa42ed9f62cf9cdd0ecd75e385e82f6 100644 (file)
@@ -1775,11 +1775,15 @@ void link_update_operstate(Link *link, bool also_update_master) {
          *                          | off | no-carrier | dormant | degraded-carrier | carrier  | enslaved
          *                 ------------------------------------------------------------------------------
          *                 off      | off | no-carrier | dormant | degraded-carrier | carrier  | enslaved
-         * address_state   degraded | off | no-carrier | dormant | degraded-carrier | degraded | enslaved
-         *                 routable | off | no-carrier | dormant | degraded-carrier | routable | routable
+         * address_state   degraded | off | no-carrier | dormant | degraded         | degraded | enslaved
+         *                 routable | off | no-carrier | dormant | routable         | routable | routable
          */
 
-        if (carrier_state < LINK_CARRIER_STATE_CARRIER || address_state == LINK_ADDRESS_STATE_OFF)
+        if (carrier_state == LINK_CARRIER_STATE_DEGRADED_CARRIER && address_state == LINK_ADDRESS_STATE_ROUTABLE)
+                operstate = LINK_OPERSTATE_ROUTABLE;
+        else if (carrier_state == LINK_CARRIER_STATE_DEGRADED_CARRIER && address_state == LINK_ADDRESS_STATE_DEGRADED)
+                operstate = LINK_OPERSTATE_DEGRADED;
+        else if (carrier_state < LINK_CARRIER_STATE_CARRIER || address_state == LINK_ADDRESS_STATE_OFF)
                 operstate = (LinkOperationalState) carrier_state;
         else if (address_state == LINK_ADDRESS_STATE_ROUTABLE)
                 operstate = LINK_OPERSTATE_ROUTABLE;
index 5658433bca89c16d76cd6c7493fef529eacf72ee..b5ef83a9c08b24253bb953f2f8070197162fe4a1 100755 (executable)
@@ -3950,7 +3950,7 @@ class NetworkdBondTests(unittest.TestCase, Utilities):
 
         self.wait_operstate('dummy98', 'off')
         self.wait_operstate('test1', 'enslaved')
-        self.wait_operstate('bond99', 'degraded-carrier')
+        self.wait_operstate('bond99', 'routable')
 
         check_output('ip link set dummy98 up')
 
@@ -4121,7 +4121,7 @@ class NetworkdBridgeTests(unittest.TestCase, Utilities):
         self.assertRegex(output, 'ff00::/8 table local (proto kernel )?metric 256 (linkdown )?pref medium')
 
         remove_link('test1')
-        self.wait_operstate('bridge99', 'degraded-carrier')
+        self.wait_operstate('bridge99', 'routable')
 
         output = check_output('ip -d link show bridge99')
         print(output)