Merge ~ubuntu-core-dev/ubuntu/+source/systemd:lp1664844-hirsute into ~ubuntu-core-dev/ubuntu/+source/systemd:ubuntu-hirsute

Proposed by Łukasz Zemczak
Status: Merged
Merged at revision: 85b4a5ba7086f93859e13d7b025212c383043b67
Proposed branch: ~ubuntu-core-dev/ubuntu/+source/systemd:lp1664844-hirsute
Merge into: ~ubuntu-core-dev/ubuntu/+source/systemd:ubuntu-hirsute
Diff against target: 622 lines (+588/-0)
5 files modified
debian/changelog (+10/-0)
debian/patches/lp1664844/0001-network-add-ActivationPolicy-configuration-parameter.patch (+344/-0)
debian/patches/lp1664844/0002-test-add-ActivationPolicy-unit-tests.patch (+121/-0)
debian/patches/lp1664844/0003-save-link-activation-policy-to-state-file-and-displa.patch (+110/-0)
debian/patches/series (+3/-0)
Reviewer Review Type Date Requested Status
Dan Streetman Approve
Balint Reczey Approve
Dimitri John Ledkov Pending
Review via email: mp+402646@code.launchpad.net

Commit message

add support for configuring the activation policy for an interface

Description of the change

add support for configuring the activation policy for an interface

To post a comment you must log in.
Revision history for this message
Balint Reczey (rbalint) wrote :

LGTM, but adding Dan if there is anything I missed.

review: Approve
Revision history for this message
Balint Reczey (rbalint) wrote :

Also please don't use this central repository for bugfix branches, it is big enough with the release branches already.

Revision history for this message
Łukasz Zemczak (sil2100) wrote :

Did a quick sanity test with a dummy interface on multipass using test packages from a bileto PPA (https://bileto.ubuntu.com/#/ticket/4553) and at least always-up, always-down and manual seem to be working as expected!

Revision history for this message
Dan Streetman (ddstreet) wrote :

lgtm

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/debian/changelog b/debian/changelog
index 5efa976..161740e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,13 @@
1systemd (247.3-3ubuntu4) UNRELEASED; urgency=medium
2
3 * d/p/lp1664844/0001-network-add-ActivationPolicy-configuration-parameter.patch,
4 d/p/lp1664844/0002-test-add-ActivationPolicy-unit-tests.patch,
5 d/p/lp1664844/0003-save-link-activation-policy-to-state-file-and-displa.patch:
6 - add support for configuring the activation policy for an interface
7 (LP: #1664844)
8
9 -- Łukasz 'sil2100' Zemczak <lukasz.zemczak@ubuntu.com> Wed, 12 May 2021 11:56:50 +0200
10
1systemd (247.3-3ubuntu3) hirsute; urgency=medium11systemd (247.3-3ubuntu3) hirsute; urgency=medium
212
3 * Make systemd-rfkill work with latest Linux kernels (LP: #1921696)13 * Make systemd-rfkill work with latest Linux kernels (LP: #1921696)
diff --git a/debian/patches/lp1664844/0001-network-add-ActivationPolicy-configuration-parameter.patch b/debian/patches/lp1664844/0001-network-add-ActivationPolicy-configuration-parameter.patch
4new file mode 10064414new file mode 100644
index 0000000..08a8fb5
--- /dev/null
+++ b/debian/patches/lp1664844/0001-network-add-ActivationPolicy-configuration-parameter.patch
@@ -0,0 +1,344 @@
1From 61135582e0b2e847e49c96af05e4d101323ce00c Mon Sep 17 00:00:00 2001
2From: Dan Streetman <ddstreet@canonical.com>
3Date: Thu, 18 Jun 2020 16:09:40 -0400
4Subject: [PATCH 1/3] network: add ActivationPolicy= configuration parameter
5Origin: upstream, https://github.com/systemd/systemd/pull/16228
6Bug-Ubuntu: https://bugs.launchpad.net/netplan/+bug/1664844
7
8This parameter allows configuring the activation policy for an interface,
9meaning how it manages the interface's administrative state (IFF_UP flag).
10The policy can be configured to bring the interface either up or down when
11the interface is (re)configured, to always force the interface either up or
12down, or to never change the interface administrative state.
13
14If the interface is bound with BindCarrier=, its administrative state is
15controlled by the interface(s) it's bound to, and this parameter is forced
16to 'bound'.
17
18This changes the default behavior of how systemd-networkd sets the IFF_UP
19flag; previously, it was set up (if not already up) every time the
20link_joined() function was called. Now, with the default ActivationPolicy=
21setting of 'up', it will only set the IFF_UP flag once, the first time
22link_joined() is called, during an interface's configuration; and on
23the first link_joined() call each time the interface is reconfigured.
24
25Fixes: #3031
26Fixes: #17437
27---
28 man/systemd.network.xml | 39 ++++++++++++-
29 src/network/networkd-link.c | 58 ++++++++++++++++++-
30 src/network/networkd-link.h | 1 +
31 src/network/networkd-network-gperf.gperf | 1 +
32 src/network/networkd-network.c | 40 ++++++++++++-
33 src/network/networkd-network.h | 16 +++++
34 .../fuzz-network-parser/directives.network | 1 +
35 7 files changed, 148 insertions(+), 8 deletions(-)
36
37--- a/man/systemd.network.xml
38+++ b/man/systemd.network.xml
39@@ -228,6 +228,36 @@
40 if <literal>RequiredForOnline=no</literal>.</para>
41 </listitem>
42 </varlistentry>
43+ <varlistentry>
44+ <term><varname>ActivationPolicy=</varname></term>
45+ <listitem>
46+ <para>Specifies the policy for <command>systemd-networkd</command> managing the link
47+ administrative state. Specifically, this controls how <command>systemd-networkd</command>
48+ changes the network device's <literal>IFF_UP</literal> flag, which is sometimes
49+ controlled by system administrators by running e.g., <command>ip set dev eth0 up</command>
50+ or <command>ip set dev eth0 down</command>, and can also be changed with
51+ <command>networkctl up eth0</command> or <command>networkctl down eth0</command>.</para>
52+
53+ <para>Takes one of <literal>up</literal>, <literal>always-up</literal>,
54+ <literal>manual</literal>, <literal>always-down</literal>, <literal>down</literal>,
55+ or <literal>bound</literal>. When <literal>manual</literal>, <command>systemd-networkd</command>
56+ will not change the link's admin state automatically; the system administrator must bring the
57+ interface up or down manually, as desired. When <literal>up</literal> (the default) or
58+ <literal>always-up</literal>, or <literal>down</literal> or <literal>always-down</literal>,
59+ <command>systemd-networkd</command> will set the link up or down, respectively,
60+ when the interface is (re)configured. When <literal>always-up</literal> or
61+ <literal>always-down</literal>, <command>systemd-networkd</command> will set the link up
62+ or down, respectively, any time <command>systemd-networkd</command> detects a change in
63+ the administrative state. When <varname>BindCarrier=</varname> is also set, this is
64+ automatically set to <literal>bound</literal> and any other value is ignored.</para>
65+
66+ <para>The administrative state is not the same as the carrier state, so using
67+ <literal>always-up</literal> does not mean the link will never lose carrier. The link
68+ carrier depends on both the administrative state as well as the network device's physical
69+ connection. However, to avoid reconfiguration failures, when using <literal>always-up</literal>,
70+ <varname>IgnoreCarrierLoss=</varname> is forced to true.</para>
71+ </listitem>
72+ </varlistentry>
73 </variablelist>
74 </refsect1>
75
76@@ -573,8 +603,9 @@
77 <listitem>
78 <para>A link name or a list of link names. When set, controls the behavior of the current
79 link. When all links in the list are in an operational down state, the current link is brought
80- down. When at least one link has carrier, the current interface is brought up.
81- </para>
82+ down. When at least one link has carrier, the current interface is brought up.</para>
83+
84+ <para>This forces <varname>ActivationPolicy=</varname> to be set to <literal>bound</literal>.</para>
85 </listitem>
86 </varlistentry>
87 <varlistentry>
88@@ -947,6 +978,10 @@
89 of the interface even if its carrier is lost. When unset, the value specified with
90 <option>ConfigureWithoutCarrier=</option> is used.
91 </para>
92+
93+ <para>When <varname>ActivationPolicy=</varname> is set to <literal>always-up</literal>, this
94+ is forced to <literal>true</literal>.
95+ </para>
96 </listitem>
97 </varlistentry>
98 <varlistentry>
99--- a/src/network/networkd-link.c
100+++ b/src/network/networkd-link.c
101@@ -1812,17 +1812,38 @@
102 assert(link);
103 assert(link->network);
104
105- if (!hashmap_isempty(link->bound_to_links)) {
106+ switch (link->network->activation_policy) {
107+ case ACTIVATION_POLICY_BOUND:
108 r = link_handle_bound_to_list(link);
109 if (r < 0)
110 return r;
111- } else if (!(link->flags & IFF_UP)) {
112+ break;
113+ case ACTIVATION_POLICY_UP:
114+ if (link->activated)
115+ break;
116+ _fallthrough_;
117+ case ACTIVATION_POLICY_ALWAYS_UP:
118 r = link_up(link);
119 if (r < 0) {
120 link_enter_failed(link);
121 return r;
122 }
123+ break;
124+ case ACTIVATION_POLICY_DOWN:
125+ if (link->activated)
126+ break;
127+ _fallthrough_;
128+ case ACTIVATION_POLICY_ALWAYS_DOWN:
129+ r = link_down(link, NULL);
130+ if (r < 0) {
131+ link_enter_failed(link);
132+ return r;
133+ }
134+ break;
135+ default:
136+ break;
137 }
138+ link->activated = true;
139
140 if (link->network->bridge) {
141 r = link_set_bridge(link);
142@@ -2216,6 +2237,7 @@
143 return r;
144
145 link_set_state(link, LINK_STATE_INITIALIZED);
146+ link->activated = false;
147 link_dirty(link);
148
149 /* link_configure_duid() returns 0 if it requests product UUID. In that case,
150@@ -2687,6 +2709,16 @@
151 static int link_admin_state_up(Link *link) {
152 int r;
153
154+ assert(link);
155+
156+ if (!link->network)
157+ return 0;
158+
159+ if (link->network->activation_policy == ACTIVATION_POLICY_ALWAYS_DOWN) {
160+ log_link_info(link, "ActivationPolicy is \"always-off\", forcing link down");
161+ return link_down(link, NULL);
162+ }
163+
164 /* We set the ipv6 mtu after the device mtu, but the kernel resets
165 * ipv6 mtu on NETDEV_UP, so we need to reset it. The check for
166 * ipv6_mtu_set prevents this from trying to set it too early before
167@@ -2701,6 +2733,21 @@
168 return 0;
169 }
170
171+static int link_admin_state_down(Link *link) {
172+
173+ assert(link);
174+
175+ if (!link->network)
176+ return 0;
177+
178+ if (link->network->activation_policy == ACTIVATION_POLICY_ALWAYS_UP) {
179+ log_link_info(link, "ActivationPolicy is \"always-on\", forcing link up");
180+ return link_up(link);
181+ }
182+
183+ return 0;
184+}
185+
186 int link_update(Link *link, sd_netlink_message *m) {
187 _cleanup_strv_free_ char **s = NULL;
188 hw_addr_data hw_addr;
189@@ -2813,9 +2860,14 @@
190 r = link_admin_state_up(link);
191 if (r < 0)
192 return r;
193- } else if (link_was_admin_up && !(link->flags & IFF_UP))
194+ } else if (link_was_admin_up && !(link->flags & IFF_UP)) {
195 log_link_info(link, "Link DOWN");
196
197+ r = link_admin_state_down(link);
198+ if (r < 0)
199+ return r;
200+ }
201+
202 r = link_update_lldp(link);
203 if (r < 0)
204 return r;
205--- a/src/network/networkd-link.h
206+++ b/src/network/networkd-link.h
207@@ -130,6 +130,7 @@
208 bool setting_genmode:1;
209 bool ipv6_mtu_set:1;
210 bool bridge_mdb_configured:1;
211+ bool activated:1;
212
213 sd_dhcp_server *dhcp_server;
214
215--- a/src/network/networkd-network-gperf.gperf
216+++ b/src/network/networkd-network-gperf.gperf
217@@ -63,6 +63,7 @@
218 Link.Multicast, config_parse_tristate, 0, offsetof(Network, multicast)
219 Link.AllMulticast, config_parse_tristate, 0, offsetof(Network, allmulticast)
220 Link.Unmanaged, config_parse_bool, 0, offsetof(Network, unmanaged)
221+Link.ActivationPolicy, config_parse_activation_policy, 0, offsetof(Network, activation_policy)
222 Link.RequiredForOnline, config_parse_required_for_online, 0, 0
223 SR-IOV.VirtualFunction, config_parse_sr_iov_uint32, 0, 0
224 SR-IOV.VLANId, config_parse_sr_iov_uint32, 0, 0
225--- a/src/network/networkd-network.c
226+++ b/src/network/networkd-network.c
227@@ -238,9 +238,6 @@
228 if (network->dhcp_use_gateway < 0)
229 network->dhcp_use_gateway = network->dhcp_use_routes;
230
231- if (network->ignore_carrier_loss < 0)
232- network->ignore_carrier_loss = network->configure_without_carrier;
233-
234 if (network->dhcp_critical >= 0) {
235 if (network->keep_configuration >= 0)
236 log_warning("%s: Both KeepConfiguration= and deprecated CriticalConnection= are set. "
237@@ -252,6 +249,30 @@
238 network->keep_configuration = KEEP_CONFIGURATION_NO;
239 }
240
241+ if (!strv_isempty(network->bind_carrier)) {
242+ if (!IN_SET(network->activation_policy, _ACTIVATION_POLICY_INVALID, ACTIVATION_POLICY_BOUND))
243+ log_warning("%s: ActivationPolicy=bound is required with BindCarrier=. "
244+ "Setting ActivationPolicy=bound.", network->filename);
245+ network->activation_policy = ACTIVATION_POLICY_BOUND;
246+ } else if (network->activation_policy == ACTIVATION_POLICY_BOUND) {
247+ log_warning("%s: ActivationPolicy=bound requires BindCarrier=. "
248+ "Ignoring ActivationPolicy=bound.", network->filename);
249+ network->activation_policy = ACTIVATION_POLICY_UP;
250+ }
251+
252+ if (network->activation_policy == _ACTIVATION_POLICY_INVALID)
253+ network->activation_policy = ACTIVATION_POLICY_UP;
254+
255+ if (network->activation_policy == ACTIVATION_POLICY_ALWAYS_UP) {
256+ if (network->ignore_carrier_loss == false)
257+ log_warning("%s: IgnoreCarrierLoss=false conflicts with ActivationPolicy=always-up. "
258+ "Setting IgnoreCarrierLoss=true.", network->filename);
259+ network->ignore_carrier_loss = true;
260+ }
261+
262+ if (network->ignore_carrier_loss < 0)
263+ network->ignore_carrier_loss = network->configure_without_carrier;
264+
265 if (network->keep_configuration < 0)
266 network->keep_configuration = KEEP_CONFIGURATION_NO;
267
268@@ -329,6 +350,7 @@
269
270 .required_for_online = true,
271 .required_operstate_for_online = LINK_OPERSTATE_RANGE_DEFAULT,
272+ .activation_policy = _ACTIVATION_POLICY_INVALID,
273 .arp = -1,
274 .multicast = -1,
275 .allmulticast = -1,
276@@ -1238,3 +1260,15 @@
277
278 DEFINE_STRING_TABLE_LOOKUP(ipv6_link_local_address_gen_mode, IPv6LinkLocalAddressGenMode);
279 DEFINE_CONFIG_PARSE_ENUM(config_parse_ipv6_link_local_address_gen_mode, ipv6_link_local_address_gen_mode, IPv6LinkLocalAddressGenMode, "Failed to parse IPv6 link local address generation mode");
280+
281+static const char* const activation_policy_table[_ACTIVATION_POLICY_MAX] = {
282+ [ACTIVATION_POLICY_UP] = "up",
283+ [ACTIVATION_POLICY_ALWAYS_UP] = "always-up",
284+ [ACTIVATION_POLICY_MANUAL] = "manual",
285+ [ACTIVATION_POLICY_ALWAYS_DOWN] = "always-down",
286+ [ACTIVATION_POLICY_DOWN] = "down",
287+ [ACTIVATION_POLICY_BOUND] = "bound",
288+};
289+
290+DEFINE_STRING_TABLE_LOOKUP(activation_policy, ActivationPolicy);
291+DEFINE_CONFIG_PARSE_ENUM(config_parse_activation_policy, activation_policy, ActivationPolicy, "Failed to parse activation policy");
292--- a/src/network/networkd-network.h
293+++ b/src/network/networkd-network.h
294@@ -46,6 +46,17 @@
295 _IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_INVALID = -1
296 } IPv6LinkLocalAddressGenMode;
297
298+typedef enum ActivationPolicy {
299+ ACTIVATION_POLICY_UP,
300+ ACTIVATION_POLICY_ALWAYS_UP,
301+ ACTIVATION_POLICY_MANUAL,
302+ ACTIVATION_POLICY_ALWAYS_DOWN,
303+ ACTIVATION_POLICY_DOWN,
304+ ACTIVATION_POLICY_BOUND,
305+ _ACTIVATION_POLICY_MAX,
306+ _ACTIVATION_POLICY_INVALID = -1
307+} ActivationPolicy;
308+
309 typedef struct Manager Manager;
310
311 typedef struct NetworkDHCPServerEmitAddress {
312@@ -98,6 +109,7 @@
313 bool unmanaged;
314 bool required_for_online; /* Is this network required to be considered online? */
315 LinkOperationalStateRange required_operstate_for_online;
316+ ActivationPolicy activation_policy;
317
318 /* misc settings */
319 bool configure_without_carrier;
320@@ -330,6 +342,7 @@
321 CONFIG_PARSER_PROTOTYPE(config_parse_required_for_online);
322 CONFIG_PARSER_PROTOTYPE(config_parse_keep_configuration);
323 CONFIG_PARSER_PROTOTYPE(config_parse_ipv6_link_local_address_gen_mode);
324+CONFIG_PARSER_PROTOTYPE(config_parse_activation_policy);
325
326 const struct ConfigPerfItem* network_network_gperf_lookup(const char *key, GPERF_LEN_TYPE length);
327
328@@ -338,3 +351,6 @@
329
330 const char* ipv6_link_local_address_gen_mode_to_string(IPv6LinkLocalAddressGenMode s) _const_;
331 IPv6LinkLocalAddressGenMode ipv6_link_local_address_gen_mode_from_string(const char *s) _pure_;
332+
333+const char* activation_policy_to_string(ActivationPolicy i) _const_;
334+ActivationPolicy activation_policy_from_string(const char *s) _pure_;
335--- a/test/fuzz/fuzz-network-parser/directives.network
336+++ b/test/fuzz/fuzz-network-parser/directives.network
337@@ -30,6 +30,7 @@
338 MACAddress=
339 PermanentMACAddress=
340 [Link]
341+ActivationPolicy=
342 RequiredForOnline=
343 ARP=
344 AllMulticast=
diff --git a/debian/patches/lp1664844/0002-test-add-ActivationPolicy-unit-tests.patch b/debian/patches/lp1664844/0002-test-add-ActivationPolicy-unit-tests.patch
0new file mode 100644345new file mode 100644
index 0000000..80a31ef
--- /dev/null
+++ b/debian/patches/lp1664844/0002-test-add-ActivationPolicy-unit-tests.patch
@@ -0,0 +1,121 @@
1From 2236d75df955118ad5d84c5ab787484c0921dfda Mon Sep 17 00:00:00 2001
2From: Dan Streetman <ddstreet@canonical.com>
3Date: Thu, 18 Jun 2020 18:31:18 -0400
4Subject: [PATCH 2/3] test: add ActivationPolicy= unit tests
5Origin: upstream, https://github.com/systemd/systemd/pull/16228
6Bug-Ubuntu: https://bugs.launchpad.net/netplan/+bug/1664844
7
8---
9 .../conf/25-activation-policy.network | 6 +++
10 .../always-down.conf | 2 +
11 .../always-up.conf | 2 +
12 .../25-activation-policy.network.d/down.conf | 2 +
13 .../manual.conf | 2 +
14 .../25-activation-policy.network.d/up.conf | 2 +
15 test/test-network/systemd-networkd-tests.py | 48 +++++++++++++++++++
16 7 files changed, 64 insertions(+)
17 create mode 100644 test/test-network/conf/25-activation-policy.network
18 create mode 100644 test/test-network/conf/25-activation-policy.network.d/always-down.conf
19 create mode 100644 test/test-network/conf/25-activation-policy.network.d/always-up.conf
20 create mode 100644 test/test-network/conf/25-activation-policy.network.d/down.conf
21 create mode 100644 test/test-network/conf/25-activation-policy.network.d/manual.conf
22 create mode 100644 test/test-network/conf/25-activation-policy.network.d/up.conf
23
24--- /dev/null
25+++ b/test/test-network/conf/25-activation-policy.network
26@@ -0,0 +1,6 @@
27+[Match]
28+Name=test1
29+
30+[Network]
31+Address=192.168.10.30/24
32+Gateway=192.168.10.1
33--- /dev/null
34+++ b/test/test-network/conf/25-activation-policy.network.d/always-down.conf
35@@ -0,0 +1,2 @@
36+[Link]
37+ActivationPolicy=always-down
38--- /dev/null
39+++ b/test/test-network/conf/25-activation-policy.network.d/always-up.conf
40@@ -0,0 +1,2 @@
41+[Link]
42+ActivationPolicy=always-up
43--- /dev/null
44+++ b/test/test-network/conf/25-activation-policy.network.d/down.conf
45@@ -0,0 +1,2 @@
46+[Link]
47+ActivationPolicy=down
48--- /dev/null
49+++ b/test/test-network/conf/25-activation-policy.network.d/manual.conf
50@@ -0,0 +1,2 @@
51+[Link]
52+ActivationPolicy=manual
53--- /dev/null
54+++ b/test/test-network/conf/25-activation-policy.network.d/up.conf
55@@ -0,0 +1,2 @@
56+[Link]
57+ActivationPolicy=up
58--- a/test/test-network/systemd-networkd-tests.py
59+++ b/test/test-network/systemd-networkd-tests.py
60@@ -1745,6 +1745,7 @@
61 '25-address-peer-ipv4.network',
62 '25-address-preferred-lifetime-zero.network',
63 '25-address-static.network',
64+ '25-activation-policy.network',
65 '25-bind-carrier.network',
66 '25-bond-active-backup-slave.netdev',
67 '25-fibrule-invert.network',
68@@ -2609,6 +2610,53 @@
69 self.assertRegex(output, 'inet 192.168.10.30/24 brd 192.168.10.255 scope global test1')
70 self.wait_operstate('test1', 'routable')
71
72+ def _test_activation_policy(self, test):
73+ self.setUp()
74+ conffile = '25-activation-policy.network'
75+ if test:
76+ conffile = f'{conffile}.d/{test}.conf'
77+ copy_unit_to_networkd_unit_path('11-dummy.netdev', conffile, dropins=False)
78+ start_networkd()
79+
80+ always = test.startswith('always')
81+ if test == 'manual':
82+ initial_up = 'UP' in check_output('ip link show test1')
83+ else:
84+ initial_up = not test.endswith('down') # note: default is up
85+ expect_up = initial_up
86+ next_up = not expect_up
87+
88+ # if initial expected state is down, must wait for setup_state to reach configuring
89+ # so systemd-networkd considers it 'activated'
90+ setup_state = None if initial_up else 'configuring'
91+
92+ for iteration in range(4):
93+ with self.subTest(iteration=iteration, expect_up=expect_up):
94+ operstate = 'routable' if expect_up else 'off'
95+ self.wait_operstate('test1', operstate, setup_state=setup_state, setup_timeout=20)
96+ setup_state = None
97+
98+ if expect_up:
99+ self.assertIn('UP', check_output('ip link show test1'))
100+ self.assertIn('192.168.10.30/24', check_output('ip address show test1'))
101+ self.assertIn('default via 192.168.10.1', check_output('ip route show'))
102+ else:
103+ self.assertIn('DOWN', check_output('ip link show test1'))
104+
105+ if next_up:
106+ check_output('ip link set dev test1 up')
107+ else:
108+ check_output('ip link set dev test1 down')
109+ expect_up = initial_up if always else next_up
110+ next_up = not next_up
111+
112+ self.tearDown()
113+
114+ def test_activation_policy(self):
115+ for test in ['up', 'always-up', 'manual', 'always-down', 'down', '']:
116+ with self.subTest(test=test):
117+ self._test_activation_policy(test)
118+
119 def test_domain(self):
120 copy_unit_to_networkd_unit_path('12-dummy.netdev', '24-search-domain.network')
121 start_networkd()
diff --git a/debian/patches/lp1664844/0003-save-link-activation-policy-to-state-file-and-displa.patch b/debian/patches/lp1664844/0003-save-link-activation-policy-to-state-file-and-displa.patch
0new file mode 100644122new file mode 100644
index 0000000..be89aae
--- /dev/null
+++ b/debian/patches/lp1664844/0003-save-link-activation-policy-to-state-file-and-displa.patch
@@ -0,0 +1,110 @@
1From a853652ae983699460b160bc2bf72f6fae0bfcd6 Mon Sep 17 00:00:00 2001
2From: Dan Streetman <ddstreet@canonical.com>
3Date: Thu, 13 Aug 2020 11:52:53 -0400
4Subject: [PATCH 3/3] save link activation policy to state file and display in
5 networkctl
6Origin: upstream, https://github.com/systemd/systemd/pull/16228
7Bug-Ubuntu: https://bugs.launchpad.net/netplan/+bug/1664844
8
9---
10 src/libsystemd/sd-network/sd-network.c | 21 +++++++++++++++++++++
11 src/network/networkctl.c | 12 +++++++++++-
12 src/network/networkd-link.c | 3 +++
13 src/systemd/sd-network.h | 5 +++++
14 test/test-network/systemd-networkd-tests.py | 1 +
15 5 files changed, 41 insertions(+), 1 deletion(-)
16
17--- a/src/libsystemd/sd-network/sd-network.c
18+++ b/src/libsystemd/sd-network/sd-network.c
19@@ -212,6 +212,27 @@
20 return 0;
21 }
22
23+_public_ int sd_network_link_get_activation_policy(int ifindex, char **policy) {
24+ _cleanup_free_ char *s = NULL;
25+ int r;
26+
27+ assert_return(policy, -EINVAL);
28+
29+ r = network_link_get_string(ifindex, "ACTIVATION_POLICY", &s);
30+ if (r < 0) {
31+ if (r != -ENODATA)
32+ return r;
33+
34+ /* For compatibility, assuming up. */
35+ s = strdup("up");
36+ if (!s)
37+ return -ENOMEM;
38+ }
39+
40+ *policy = TAKE_PTR(s);
41+ return 0;
42+}
43+
44 _public_ int sd_network_link_get_llmnr(int ifindex, char **llmnr) {
45 return network_link_get_string(ifindex, "LLMNR", llmnr);
46 }
47--- a/src/network/networkctl.c
48+++ b/src/network/networkctl.c
49@@ -1390,7 +1390,7 @@
50
51 _cleanup_strv_free_ char **dns = NULL, **ntp = NULL, **sip = NULL, **search_domains = NULL, **route_domains = NULL;
52 _cleanup_free_ char *t = NULL, *network = NULL, *iaid = NULL, *duid = NULL,
53- *setup_state = NULL, *operational_state = NULL, *lease_file = NULL;
54+ *setup_state = NULL, *operational_state = NULL, *lease_file = NULL, *activation_policy = NULL;
55 const char *driver = NULL, *path = NULL, *vendor = NULL, *model = NULL, *link = NULL,
56 *on_color_operational, *off_color_operational, *on_color_setup, *off_color_setup;
57 _cleanup_free_ int *carrier_bound_to = NULL, *carrier_bound_by = NULL;
58@@ -2065,6 +2065,16 @@
59 if (r < 0)
60 return r;
61
62+ r = sd_network_link_get_activation_policy(info->ifindex, &activation_policy);
63+ if (r >= 0) {
64+ r = table_add_many(table,
65+ TABLE_EMPTY,
66+ TABLE_STRING, "Activation Policy:",
67+ TABLE_STRING, activation_policy);
68+ if (r < 0)
69+ return table_log_add_error(r);
70+ }
71+
72 if (lease) {
73 const void *client_id;
74 size_t client_id_len;
75--- a/src/network/networkd-link.c
76+++ b/src/network/networkd-link.c
77@@ -3040,6 +3040,9 @@
78 st.max != LINK_OPERSTATE_RANGE_DEFAULT.max ? ":" : "",
79 st.max != LINK_OPERSTATE_RANGE_DEFAULT.max ? strempty(link_operstate_to_string(st.max)) : "");
80
81+ fprintf(f, "ACTIVATION_POLICY=%s\n",
82+ activation_policy_to_string(link->network->activation_policy));
83+
84 fprintf(f, "NETWORK_FILE=%s\n", link->network->filename);
85
86 /************************************************************/
87--- a/src/systemd/sd-network.h
88+++ b/src/systemd/sd-network.h
89@@ -103,6 +103,11 @@
90 */
91 int sd_network_link_get_required_for_online(int ifindex);
92
93+/* Get activation policy for ifindex.
94+ * Possible values are as specified for ActivationPolicy=
95+ */
96+int sd_network_link_get_activation_policy(int ifindex, char **policy);
97+
98 /* Get path to .network file applied to link */
99 int sd_network_link_get_network_file(int ifindex, char **filename);
100
101--- a/test/test-network/systemd-networkd-tests.py
102+++ b/test/test-network/systemd-networkd-tests.py
103@@ -2931,6 +2931,7 @@
104 self.assertRegex(data, r'OPER_STATE=routable')
105 self.assertRegex(data, r'REQUIRED_FOR_ONLINE=yes')
106 self.assertRegex(data, r'REQUIRED_OPER_STATE_FOR_ONLINE=routable')
107+ self.assertRegex(data, r'ACTIVATION_POLICY=up')
108 self.assertRegex(data, r'NETWORK_FILE=/run/systemd/network/state-file-tests.network')
109 self.assertRegex(data, r'DNS=10.10.10.10#aaa.com 10.10.10.11:1111#bbb.com \[1111:2222::3333\]:1234#ccc.com')
110 self.assertRegex(data, r'NTP=0.fedora.pool.ntp.org 1.fedora.pool.ntp.org')
diff --git a/debian/patches/series b/debian/patches/series
index afeff62..b220c6e 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -62,3 +62,6 @@ lp1887744-basic-unit-file-when-loading-linked-unit-files-use-l.patch
62lp1921696/rfkill-improve-error-logging.patch62lp1921696/rfkill-improve-error-logging.patch
63lp1921696/rfkill-use-short-writes-and-accept-long-reads.patch63lp1921696/rfkill-use-short-writes-and-accept-long-reads.patch
64LoadCredentials-do-not-assert-on-invalid-syntax.patch64LoadCredentials-do-not-assert-on-invalid-syntax.patch
65lp1664844/0001-network-add-ActivationPolicy-configuration-parameter.patch
66lp1664844/0002-test-add-ActivationPolicy-unit-tests.patch
67lp1664844/0003-save-link-activation-policy-to-state-file-and-displa.patch

Subscribers

People subscribed via source and target branches