From 24b9c341ce60f6a8512b2e9162d1b50187f2a053 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 15 Jan 2024 15:40:07 +0900 Subject: [PATCH 1/3] network/link: shorten code a bit --- src/network/networkd-link.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 5dd2fc12f64..4e5ad3c035e 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -416,11 +416,9 @@ void link_check_ready(Link *link) { if (!link->activated) return (void) log_link_debug(link, "%s(): link is not activated.", __func__); - if (link->iftype == ARPHRD_CAN) { + if (link->iftype == ARPHRD_CAN) /* let's shortcut things for CAN which doesn't need most of checks below. */ - link_set_state(link, LINK_STATE_CONFIGURED); - return; - } + goto ready; if (!link->stacked_netdevs_created) return (void) log_link_debug(link, "%s(): stacked netdevs are not created.", __func__); From c2eb7753dd47ec04ae0d66400e70bc87fbf1adcc Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 15 Jan 2024 15:40:54 +0900 Subject: [PATCH 2/3] network/link: automatically reconfigure interface on failure Closes #29246. --- src/network/networkd-link.c | 20 +++++++++++++++++++- src/network/networkd-link.h | 2 ++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 4e5ad3c035e..9e69624fd2b 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -381,6 +381,8 @@ int link_stop_engines(Link *link, bool may_keep_dhcp) { } void link_enter_failed(Link *link) { + int r; + assert(link); if (IN_SET(link->state, LINK_STATE_FAILED, LINK_STATE_LINGER)) @@ -390,7 +392,22 @@ void link_enter_failed(Link *link) { link_set_state(link, LINK_STATE_FAILED); - (void) link_stop_engines(link, false); + if (!ratelimit_below(&link->automatic_reconfigure_ratelimit)) { + log_link_warning(link, "The interface entered the failed state frequently, refusing to reconfigure it automatically."); + goto stop; + } + + log_link_info(link, "Trying to reconfigure the interface."); + r = link_reconfigure(link, /* force = */ true); + if (r < 0) { + log_link_warning_errno(link, r, "Failed to reconfigure interface: %m"); + goto stop; + } + + return; + +stop: + (void) link_stop_engines(link, /* may_keep_dhcp = */ false); } void link_check_ready(Link *link) { @@ -2552,6 +2569,7 @@ static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) { .n_ref = 1, .state = LINK_STATE_PENDING, .online_state = _LINK_ONLINE_STATE_INVALID, + .automatic_reconfigure_ratelimit = (const RateLimit) { .interval = 10 * USEC_PER_SEC, .burst = 5 }, .ifindex = ifindex, .iftype = iftype, .ifname = TAKE_PTR(ifname), diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h index cad9fa84106..05b028dff31 100644 --- a/src/network/networkd-link.h +++ b/src/network/networkd-link.h @@ -25,6 +25,7 @@ #include "networkd-ipv6ll.h" #include "networkd-util.h" #include "ordered-set.h" +#include "ratelimit.h" #include "resolve-util.h" #include "set.h" @@ -106,6 +107,7 @@ typedef struct Link { LinkAddressState ipv4_address_state; LinkAddressState ipv6_address_state; LinkOnlineState online_state; + RateLimit automatic_reconfigure_ratelimit; unsigned static_address_messages; unsigned static_address_label_messages; From 6d1cea7bc6b26695fa6121e2d4270a30af9af3b3 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 15 Jan 2024 15:17:57 +0900 Subject: [PATCH 3/3] test-network: try to flip interface state frequently --- test/test-network/systemd-networkd-tests.py | 25 ++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index 16103210531..44970193677 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -12,6 +12,7 @@ import itertools import json import os import pathlib +import random import re import shutil import signal @@ -5109,9 +5110,7 @@ class NetworkdRATests(unittest.TestCase, Utilities): self.teardown_nftset('addr6', 'network6', 'ifindex') - def test_ipv6_token_static(self): - copy_network_unit('25-veth.netdev', '25-ipv6-prefix.network', '25-ipv6-prefix-veth-token-static.network') - start_networkd() + def check_ipv6_token_static(self): self.wait_online(['veth99:routable', 'veth-peer:degraded']) output = networkctl_status('veth99') @@ -5121,6 +5120,26 @@ class NetworkdRATests(unittest.TestCase, Utilities): self.assertRegex(output, '2002:da8:2:0:1a:2b:3c:4d') self.assertRegex(output, '2002:da8:2:0:fa:de:ca:fe') + def test_ipv6_token_static(self): + copy_network_unit('25-veth.netdev', '25-ipv6-prefix.network', '25-ipv6-prefix-veth-token-static.network') + start_networkd() + + self.check_ipv6_token_static() + + for _ in range(20): + check_output('ip link set veth99 down') + check_output('ip link set veth99 up') + + self.check_ipv6_token_static() + + for _ in range(20): + check_output('ip link set veth99 down') + time.sleep(random.uniform(0, 0.1)) + check_output('ip link set veth99 up') + time.sleep(random.uniform(0, 0.1)) + + self.check_ipv6_token_static() + def test_ipv6_token_prefixstable(self): copy_network_unit('25-veth.netdev', '25-ipv6-prefix.network', '25-ipv6-prefix-veth-token-prefixstable.network') start_networkd()