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
1diff --git a/debian/changelog b/debian/changelog
2index 5efa976..161740e 100644
3--- a/debian/changelog
4+++ b/debian/changelog
5@@ -1,3 +1,13 @@
6+systemd (247.3-3ubuntu4) UNRELEASED; urgency=medium
7+
8+ * d/p/lp1664844/0001-network-add-ActivationPolicy-configuration-parameter.patch,
9+ d/p/lp1664844/0002-test-add-ActivationPolicy-unit-tests.patch,
10+ d/p/lp1664844/0003-save-link-activation-policy-to-state-file-and-displa.patch:
11+ - add support for configuring the activation policy for an interface
12+ (LP: #1664844)
13+
14+ -- Łukasz 'sil2100' Zemczak <lukasz.zemczak@ubuntu.com> Wed, 12 May 2021 11:56:50 +0200
15+
16 systemd (247.3-3ubuntu3) hirsute; urgency=medium
17
18 * Make systemd-rfkill work with latest Linux kernels (LP: #1921696)
19diff --git a/debian/patches/lp1664844/0001-network-add-ActivationPolicy-configuration-parameter.patch b/debian/patches/lp1664844/0001-network-add-ActivationPolicy-configuration-parameter.patch
20new file mode 100644
21index 0000000..08a8fb5
22--- /dev/null
23+++ b/debian/patches/lp1664844/0001-network-add-ActivationPolicy-configuration-parameter.patch
24@@ -0,0 +1,344 @@
25+From 61135582e0b2e847e49c96af05e4d101323ce00c Mon Sep 17 00:00:00 2001
26+From: Dan Streetman <ddstreet@canonical.com>
27+Date: Thu, 18 Jun 2020 16:09:40 -0400
28+Subject: [PATCH 1/3] network: add ActivationPolicy= configuration parameter
29+Origin: upstream, https://github.com/systemd/systemd/pull/16228
30+Bug-Ubuntu: https://bugs.launchpad.net/netplan/+bug/1664844
31+
32+This parameter allows configuring the activation policy for an interface,
33+meaning how it manages the interface's administrative state (IFF_UP flag).
34+The policy can be configured to bring the interface either up or down when
35+the interface is (re)configured, to always force the interface either up or
36+down, or to never change the interface administrative state.
37+
38+If the interface is bound with BindCarrier=, its administrative state is
39+controlled by the interface(s) it's bound to, and this parameter is forced
40+to 'bound'.
41+
42+This changes the default behavior of how systemd-networkd sets the IFF_UP
43+flag; previously, it was set up (if not already up) every time the
44+link_joined() function was called. Now, with the default ActivationPolicy=
45+setting of 'up', it will only set the IFF_UP flag once, the first time
46+link_joined() is called, during an interface's configuration; and on
47+the first link_joined() call each time the interface is reconfigured.
48+
49+Fixes: #3031
50+Fixes: #17437
51+---
52+ man/systemd.network.xml | 39 ++++++++++++-
53+ src/network/networkd-link.c | 58 ++++++++++++++++++-
54+ src/network/networkd-link.h | 1 +
55+ src/network/networkd-network-gperf.gperf | 1 +
56+ src/network/networkd-network.c | 40 ++++++++++++-
57+ src/network/networkd-network.h | 16 +++++
58+ .../fuzz-network-parser/directives.network | 1 +
59+ 7 files changed, 148 insertions(+), 8 deletions(-)
60+
61+--- a/man/systemd.network.xml
62++++ b/man/systemd.network.xml
63+@@ -228,6 +228,36 @@
64+ if <literal>RequiredForOnline=no</literal>.</para>
65+ </listitem>
66+ </varlistentry>
67++ <varlistentry>
68++ <term><varname>ActivationPolicy=</varname></term>
69++ <listitem>
70++ <para>Specifies the policy for <command>systemd-networkd</command> managing the link
71++ administrative state. Specifically, this controls how <command>systemd-networkd</command>
72++ changes the network device's <literal>IFF_UP</literal> flag, which is sometimes
73++ controlled by system administrators by running e.g., <command>ip set dev eth0 up</command>
74++ or <command>ip set dev eth0 down</command>, and can also be changed with
75++ <command>networkctl up eth0</command> or <command>networkctl down eth0</command>.</para>
76++
77++ <para>Takes one of <literal>up</literal>, <literal>always-up</literal>,
78++ <literal>manual</literal>, <literal>always-down</literal>, <literal>down</literal>,
79++ or <literal>bound</literal>. When <literal>manual</literal>, <command>systemd-networkd</command>
80++ will not change the link's admin state automatically; the system administrator must bring the
81++ interface up or down manually, as desired. When <literal>up</literal> (the default) or
82++ <literal>always-up</literal>, or <literal>down</literal> or <literal>always-down</literal>,
83++ <command>systemd-networkd</command> will set the link up or down, respectively,
84++ when the interface is (re)configured. When <literal>always-up</literal> or
85++ <literal>always-down</literal>, <command>systemd-networkd</command> will set the link up
86++ or down, respectively, any time <command>systemd-networkd</command> detects a change in
87++ the administrative state. When <varname>BindCarrier=</varname> is also set, this is
88++ automatically set to <literal>bound</literal> and any other value is ignored.</para>
89++
90++ <para>The administrative state is not the same as the carrier state, so using
91++ <literal>always-up</literal> does not mean the link will never lose carrier. The link
92++ carrier depends on both the administrative state as well as the network device's physical
93++ connection. However, to avoid reconfiguration failures, when using <literal>always-up</literal>,
94++ <varname>IgnoreCarrierLoss=</varname> is forced to true.</para>
95++ </listitem>
96++ </varlistentry>
97+ </variablelist>
98+ </refsect1>
99+
100+@@ -573,8 +603,9 @@
101+ <listitem>
102+ <para>A link name or a list of link names. When set, controls the behavior of the current
103+ link. When all links in the list are in an operational down state, the current link is brought
104+- down. When at least one link has carrier, the current interface is brought up.
105+- </para>
106++ down. When at least one link has carrier, the current interface is brought up.</para>
107++
108++ <para>This forces <varname>ActivationPolicy=</varname> to be set to <literal>bound</literal>.</para>
109+ </listitem>
110+ </varlistentry>
111+ <varlistentry>
112+@@ -947,6 +978,10 @@
113+ of the interface even if its carrier is lost. When unset, the value specified with
114+ <option>ConfigureWithoutCarrier=</option> is used.
115+ </para>
116++
117++ <para>When <varname>ActivationPolicy=</varname> is set to <literal>always-up</literal>, this
118++ is forced to <literal>true</literal>.
119++ </para>
120+ </listitem>
121+ </varlistentry>
122+ <varlistentry>
123+--- a/src/network/networkd-link.c
124++++ b/src/network/networkd-link.c
125+@@ -1812,17 +1812,38 @@
126+ assert(link);
127+ assert(link->network);
128+
129+- if (!hashmap_isempty(link->bound_to_links)) {
130++ switch (link->network->activation_policy) {
131++ case ACTIVATION_POLICY_BOUND:
132+ r = link_handle_bound_to_list(link);
133+ if (r < 0)
134+ return r;
135+- } else if (!(link->flags & IFF_UP)) {
136++ break;
137++ case ACTIVATION_POLICY_UP:
138++ if (link->activated)
139++ break;
140++ _fallthrough_;
141++ case ACTIVATION_POLICY_ALWAYS_UP:
142+ r = link_up(link);
143+ if (r < 0) {
144+ link_enter_failed(link);
145+ return r;
146+ }
147++ break;
148++ case ACTIVATION_POLICY_DOWN:
149++ if (link->activated)
150++ break;
151++ _fallthrough_;
152++ case ACTIVATION_POLICY_ALWAYS_DOWN:
153++ r = link_down(link, NULL);
154++ if (r < 0) {
155++ link_enter_failed(link);
156++ return r;
157++ }
158++ break;
159++ default:
160++ break;
161+ }
162++ link->activated = true;
163+
164+ if (link->network->bridge) {
165+ r = link_set_bridge(link);
166+@@ -2216,6 +2237,7 @@
167+ return r;
168+
169+ link_set_state(link, LINK_STATE_INITIALIZED);
170++ link->activated = false;
171+ link_dirty(link);
172+
173+ /* link_configure_duid() returns 0 if it requests product UUID. In that case,
174+@@ -2687,6 +2709,16 @@
175+ static int link_admin_state_up(Link *link) {
176+ int r;
177+
178++ assert(link);
179++
180++ if (!link->network)
181++ return 0;
182++
183++ if (link->network->activation_policy == ACTIVATION_POLICY_ALWAYS_DOWN) {
184++ log_link_info(link, "ActivationPolicy is \"always-off\", forcing link down");
185++ return link_down(link, NULL);
186++ }
187++
188+ /* We set the ipv6 mtu after the device mtu, but the kernel resets
189+ * ipv6 mtu on NETDEV_UP, so we need to reset it. The check for
190+ * ipv6_mtu_set prevents this from trying to set it too early before
191+@@ -2701,6 +2733,21 @@
192+ return 0;
193+ }
194+
195++static int link_admin_state_down(Link *link) {
196++
197++ assert(link);
198++
199++ if (!link->network)
200++ return 0;
201++
202++ if (link->network->activation_policy == ACTIVATION_POLICY_ALWAYS_UP) {
203++ log_link_info(link, "ActivationPolicy is \"always-on\", forcing link up");
204++ return link_up(link);
205++ }
206++
207++ return 0;
208++}
209++
210+ int link_update(Link *link, sd_netlink_message *m) {
211+ _cleanup_strv_free_ char **s = NULL;
212+ hw_addr_data hw_addr;
213+@@ -2813,9 +2860,14 @@
214+ r = link_admin_state_up(link);
215+ if (r < 0)
216+ return r;
217+- } else if (link_was_admin_up && !(link->flags & IFF_UP))
218++ } else if (link_was_admin_up && !(link->flags & IFF_UP)) {
219+ log_link_info(link, "Link DOWN");
220+
221++ r = link_admin_state_down(link);
222++ if (r < 0)
223++ return r;
224++ }
225++
226+ r = link_update_lldp(link);
227+ if (r < 0)
228+ return r;
229+--- a/src/network/networkd-link.h
230++++ b/src/network/networkd-link.h
231+@@ -130,6 +130,7 @@
232+ bool setting_genmode:1;
233+ bool ipv6_mtu_set:1;
234+ bool bridge_mdb_configured:1;
235++ bool activated:1;
236+
237+ sd_dhcp_server *dhcp_server;
238+
239+--- a/src/network/networkd-network-gperf.gperf
240++++ b/src/network/networkd-network-gperf.gperf
241+@@ -63,6 +63,7 @@
242+ Link.Multicast, config_parse_tristate, 0, offsetof(Network, multicast)
243+ Link.AllMulticast, config_parse_tristate, 0, offsetof(Network, allmulticast)
244+ Link.Unmanaged, config_parse_bool, 0, offsetof(Network, unmanaged)
245++Link.ActivationPolicy, config_parse_activation_policy, 0, offsetof(Network, activation_policy)
246+ Link.RequiredForOnline, config_parse_required_for_online, 0, 0
247+ SR-IOV.VirtualFunction, config_parse_sr_iov_uint32, 0, 0
248+ SR-IOV.VLANId, config_parse_sr_iov_uint32, 0, 0
249+--- a/src/network/networkd-network.c
250++++ b/src/network/networkd-network.c
251+@@ -238,9 +238,6 @@
252+ if (network->dhcp_use_gateway < 0)
253+ network->dhcp_use_gateway = network->dhcp_use_routes;
254+
255+- if (network->ignore_carrier_loss < 0)
256+- network->ignore_carrier_loss = network->configure_without_carrier;
257+-
258+ if (network->dhcp_critical >= 0) {
259+ if (network->keep_configuration >= 0)
260+ log_warning("%s: Both KeepConfiguration= and deprecated CriticalConnection= are set. "
261+@@ -252,6 +249,30 @@
262+ network->keep_configuration = KEEP_CONFIGURATION_NO;
263+ }
264+
265++ if (!strv_isempty(network->bind_carrier)) {
266++ if (!IN_SET(network->activation_policy, _ACTIVATION_POLICY_INVALID, ACTIVATION_POLICY_BOUND))
267++ log_warning("%s: ActivationPolicy=bound is required with BindCarrier=. "
268++ "Setting ActivationPolicy=bound.", network->filename);
269++ network->activation_policy = ACTIVATION_POLICY_BOUND;
270++ } else if (network->activation_policy == ACTIVATION_POLICY_BOUND) {
271++ log_warning("%s: ActivationPolicy=bound requires BindCarrier=. "
272++ "Ignoring ActivationPolicy=bound.", network->filename);
273++ network->activation_policy = ACTIVATION_POLICY_UP;
274++ }
275++
276++ if (network->activation_policy == _ACTIVATION_POLICY_INVALID)
277++ network->activation_policy = ACTIVATION_POLICY_UP;
278++
279++ if (network->activation_policy == ACTIVATION_POLICY_ALWAYS_UP) {
280++ if (network->ignore_carrier_loss == false)
281++ log_warning("%s: IgnoreCarrierLoss=false conflicts with ActivationPolicy=always-up. "
282++ "Setting IgnoreCarrierLoss=true.", network->filename);
283++ network->ignore_carrier_loss = true;
284++ }
285++
286++ if (network->ignore_carrier_loss < 0)
287++ network->ignore_carrier_loss = network->configure_without_carrier;
288++
289+ if (network->keep_configuration < 0)
290+ network->keep_configuration = KEEP_CONFIGURATION_NO;
291+
292+@@ -329,6 +350,7 @@
293+
294+ .required_for_online = true,
295+ .required_operstate_for_online = LINK_OPERSTATE_RANGE_DEFAULT,
296++ .activation_policy = _ACTIVATION_POLICY_INVALID,
297+ .arp = -1,
298+ .multicast = -1,
299+ .allmulticast = -1,
300+@@ -1238,3 +1260,15 @@
301+
302+ DEFINE_STRING_TABLE_LOOKUP(ipv6_link_local_address_gen_mode, IPv6LinkLocalAddressGenMode);
303+ 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");
304++
305++static const char* const activation_policy_table[_ACTIVATION_POLICY_MAX] = {
306++ [ACTIVATION_POLICY_UP] = "up",
307++ [ACTIVATION_POLICY_ALWAYS_UP] = "always-up",
308++ [ACTIVATION_POLICY_MANUAL] = "manual",
309++ [ACTIVATION_POLICY_ALWAYS_DOWN] = "always-down",
310++ [ACTIVATION_POLICY_DOWN] = "down",
311++ [ACTIVATION_POLICY_BOUND] = "bound",
312++};
313++
314++DEFINE_STRING_TABLE_LOOKUP(activation_policy, ActivationPolicy);
315++DEFINE_CONFIG_PARSE_ENUM(config_parse_activation_policy, activation_policy, ActivationPolicy, "Failed to parse activation policy");
316+--- a/src/network/networkd-network.h
317++++ b/src/network/networkd-network.h
318+@@ -46,6 +46,17 @@
319+ _IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_INVALID = -1
320+ } IPv6LinkLocalAddressGenMode;
321+
322++typedef enum ActivationPolicy {
323++ ACTIVATION_POLICY_UP,
324++ ACTIVATION_POLICY_ALWAYS_UP,
325++ ACTIVATION_POLICY_MANUAL,
326++ ACTIVATION_POLICY_ALWAYS_DOWN,
327++ ACTIVATION_POLICY_DOWN,
328++ ACTIVATION_POLICY_BOUND,
329++ _ACTIVATION_POLICY_MAX,
330++ _ACTIVATION_POLICY_INVALID = -1
331++} ActivationPolicy;
332++
333+ typedef struct Manager Manager;
334+
335+ typedef struct NetworkDHCPServerEmitAddress {
336+@@ -98,6 +109,7 @@
337+ bool unmanaged;
338+ bool required_for_online; /* Is this network required to be considered online? */
339+ LinkOperationalStateRange required_operstate_for_online;
340++ ActivationPolicy activation_policy;
341+
342+ /* misc settings */
343+ bool configure_without_carrier;
344+@@ -330,6 +342,7 @@
345+ CONFIG_PARSER_PROTOTYPE(config_parse_required_for_online);
346+ CONFIG_PARSER_PROTOTYPE(config_parse_keep_configuration);
347+ CONFIG_PARSER_PROTOTYPE(config_parse_ipv6_link_local_address_gen_mode);
348++CONFIG_PARSER_PROTOTYPE(config_parse_activation_policy);
349+
350+ const struct ConfigPerfItem* network_network_gperf_lookup(const char *key, GPERF_LEN_TYPE length);
351+
352+@@ -338,3 +351,6 @@
353+
354+ const char* ipv6_link_local_address_gen_mode_to_string(IPv6LinkLocalAddressGenMode s) _const_;
355+ IPv6LinkLocalAddressGenMode ipv6_link_local_address_gen_mode_from_string(const char *s) _pure_;
356++
357++const char* activation_policy_to_string(ActivationPolicy i) _const_;
358++ActivationPolicy activation_policy_from_string(const char *s) _pure_;
359+--- a/test/fuzz/fuzz-network-parser/directives.network
360++++ b/test/fuzz/fuzz-network-parser/directives.network
361+@@ -30,6 +30,7 @@
362+ MACAddress=
363+ PermanentMACAddress=
364+ [Link]
365++ActivationPolicy=
366+ RequiredForOnline=
367+ ARP=
368+ AllMulticast=
369diff --git a/debian/patches/lp1664844/0002-test-add-ActivationPolicy-unit-tests.patch b/debian/patches/lp1664844/0002-test-add-ActivationPolicy-unit-tests.patch
370new file mode 100644
371index 0000000..80a31ef
372--- /dev/null
373+++ b/debian/patches/lp1664844/0002-test-add-ActivationPolicy-unit-tests.patch
374@@ -0,0 +1,121 @@
375+From 2236d75df955118ad5d84c5ab787484c0921dfda Mon Sep 17 00:00:00 2001
376+From: Dan Streetman <ddstreet@canonical.com>
377+Date: Thu, 18 Jun 2020 18:31:18 -0400
378+Subject: [PATCH 2/3] test: add ActivationPolicy= unit tests
379+Origin: upstream, https://github.com/systemd/systemd/pull/16228
380+Bug-Ubuntu: https://bugs.launchpad.net/netplan/+bug/1664844
381+
382+---
383+ .../conf/25-activation-policy.network | 6 +++
384+ .../always-down.conf | 2 +
385+ .../always-up.conf | 2 +
386+ .../25-activation-policy.network.d/down.conf | 2 +
387+ .../manual.conf | 2 +
388+ .../25-activation-policy.network.d/up.conf | 2 +
389+ test/test-network/systemd-networkd-tests.py | 48 +++++++++++++++++++
390+ 7 files changed, 64 insertions(+)
391+ create mode 100644 test/test-network/conf/25-activation-policy.network
392+ create mode 100644 test/test-network/conf/25-activation-policy.network.d/always-down.conf
393+ create mode 100644 test/test-network/conf/25-activation-policy.network.d/always-up.conf
394+ create mode 100644 test/test-network/conf/25-activation-policy.network.d/down.conf
395+ create mode 100644 test/test-network/conf/25-activation-policy.network.d/manual.conf
396+ create mode 100644 test/test-network/conf/25-activation-policy.network.d/up.conf
397+
398+--- /dev/null
399++++ b/test/test-network/conf/25-activation-policy.network
400+@@ -0,0 +1,6 @@
401++[Match]
402++Name=test1
403++
404++[Network]
405++Address=192.168.10.30/24
406++Gateway=192.168.10.1
407+--- /dev/null
408++++ b/test/test-network/conf/25-activation-policy.network.d/always-down.conf
409+@@ -0,0 +1,2 @@
410++[Link]
411++ActivationPolicy=always-down
412+--- /dev/null
413++++ b/test/test-network/conf/25-activation-policy.network.d/always-up.conf
414+@@ -0,0 +1,2 @@
415++[Link]
416++ActivationPolicy=always-up
417+--- /dev/null
418++++ b/test/test-network/conf/25-activation-policy.network.d/down.conf
419+@@ -0,0 +1,2 @@
420++[Link]
421++ActivationPolicy=down
422+--- /dev/null
423++++ b/test/test-network/conf/25-activation-policy.network.d/manual.conf
424+@@ -0,0 +1,2 @@
425++[Link]
426++ActivationPolicy=manual
427+--- /dev/null
428++++ b/test/test-network/conf/25-activation-policy.network.d/up.conf
429+@@ -0,0 +1,2 @@
430++[Link]
431++ActivationPolicy=up
432+--- a/test/test-network/systemd-networkd-tests.py
433++++ b/test/test-network/systemd-networkd-tests.py
434+@@ -1745,6 +1745,7 @@
435+ '25-address-peer-ipv4.network',
436+ '25-address-preferred-lifetime-zero.network',
437+ '25-address-static.network',
438++ '25-activation-policy.network',
439+ '25-bind-carrier.network',
440+ '25-bond-active-backup-slave.netdev',
441+ '25-fibrule-invert.network',
442+@@ -2609,6 +2610,53 @@
443+ self.assertRegex(output, 'inet 192.168.10.30/24 brd 192.168.10.255 scope global test1')
444+ self.wait_operstate('test1', 'routable')
445+
446++ def _test_activation_policy(self, test):
447++ self.setUp()
448++ conffile = '25-activation-policy.network'
449++ if test:
450++ conffile = f'{conffile}.d/{test}.conf'
451++ copy_unit_to_networkd_unit_path('11-dummy.netdev', conffile, dropins=False)
452++ start_networkd()
453++
454++ always = test.startswith('always')
455++ if test == 'manual':
456++ initial_up = 'UP' in check_output('ip link show test1')
457++ else:
458++ initial_up = not test.endswith('down') # note: default is up
459++ expect_up = initial_up
460++ next_up = not expect_up
461++
462++ # if initial expected state is down, must wait for setup_state to reach configuring
463++ # so systemd-networkd considers it 'activated'
464++ setup_state = None if initial_up else 'configuring'
465++
466++ for iteration in range(4):
467++ with self.subTest(iteration=iteration, expect_up=expect_up):
468++ operstate = 'routable' if expect_up else 'off'
469++ self.wait_operstate('test1', operstate, setup_state=setup_state, setup_timeout=20)
470++ setup_state = None
471++
472++ if expect_up:
473++ self.assertIn('UP', check_output('ip link show test1'))
474++ self.assertIn('192.168.10.30/24', check_output('ip address show test1'))
475++ self.assertIn('default via 192.168.10.1', check_output('ip route show'))
476++ else:
477++ self.assertIn('DOWN', check_output('ip link show test1'))
478++
479++ if next_up:
480++ check_output('ip link set dev test1 up')
481++ else:
482++ check_output('ip link set dev test1 down')
483++ expect_up = initial_up if always else next_up
484++ next_up = not next_up
485++
486++ self.tearDown()
487++
488++ def test_activation_policy(self):
489++ for test in ['up', 'always-up', 'manual', 'always-down', 'down', '']:
490++ with self.subTest(test=test):
491++ self._test_activation_policy(test)
492++
493+ def test_domain(self):
494+ copy_unit_to_networkd_unit_path('12-dummy.netdev', '24-search-domain.network')
495+ start_networkd()
496diff --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
497new file mode 100644
498index 0000000..be89aae
499--- /dev/null
500+++ b/debian/patches/lp1664844/0003-save-link-activation-policy-to-state-file-and-displa.patch
501@@ -0,0 +1,110 @@
502+From a853652ae983699460b160bc2bf72f6fae0bfcd6 Mon Sep 17 00:00:00 2001
503+From: Dan Streetman <ddstreet@canonical.com>
504+Date: Thu, 13 Aug 2020 11:52:53 -0400
505+Subject: [PATCH 3/3] save link activation policy to state file and display in
506+ networkctl
507+Origin: upstream, https://github.com/systemd/systemd/pull/16228
508+Bug-Ubuntu: https://bugs.launchpad.net/netplan/+bug/1664844
509+
510+---
511+ src/libsystemd/sd-network/sd-network.c | 21 +++++++++++++++++++++
512+ src/network/networkctl.c | 12 +++++++++++-
513+ src/network/networkd-link.c | 3 +++
514+ src/systemd/sd-network.h | 5 +++++
515+ test/test-network/systemd-networkd-tests.py | 1 +
516+ 5 files changed, 41 insertions(+), 1 deletion(-)
517+
518+--- a/src/libsystemd/sd-network/sd-network.c
519++++ b/src/libsystemd/sd-network/sd-network.c
520+@@ -212,6 +212,27 @@
521+ return 0;
522+ }
523+
524++_public_ int sd_network_link_get_activation_policy(int ifindex, char **policy) {
525++ _cleanup_free_ char *s = NULL;
526++ int r;
527++
528++ assert_return(policy, -EINVAL);
529++
530++ r = network_link_get_string(ifindex, "ACTIVATION_POLICY", &s);
531++ if (r < 0) {
532++ if (r != -ENODATA)
533++ return r;
534++
535++ /* For compatibility, assuming up. */
536++ s = strdup("up");
537++ if (!s)
538++ return -ENOMEM;
539++ }
540++
541++ *policy = TAKE_PTR(s);
542++ return 0;
543++}
544++
545+ _public_ int sd_network_link_get_llmnr(int ifindex, char **llmnr) {
546+ return network_link_get_string(ifindex, "LLMNR", llmnr);
547+ }
548+--- a/src/network/networkctl.c
549++++ b/src/network/networkctl.c
550+@@ -1390,7 +1390,7 @@
551+
552+ _cleanup_strv_free_ char **dns = NULL, **ntp = NULL, **sip = NULL, **search_domains = NULL, **route_domains = NULL;
553+ _cleanup_free_ char *t = NULL, *network = NULL, *iaid = NULL, *duid = NULL,
554+- *setup_state = NULL, *operational_state = NULL, *lease_file = NULL;
555++ *setup_state = NULL, *operational_state = NULL, *lease_file = NULL, *activation_policy = NULL;
556+ const char *driver = NULL, *path = NULL, *vendor = NULL, *model = NULL, *link = NULL,
557+ *on_color_operational, *off_color_operational, *on_color_setup, *off_color_setup;
558+ _cleanup_free_ int *carrier_bound_to = NULL, *carrier_bound_by = NULL;
559+@@ -2065,6 +2065,16 @@
560+ if (r < 0)
561+ return r;
562+
563++ r = sd_network_link_get_activation_policy(info->ifindex, &activation_policy);
564++ if (r >= 0) {
565++ r = table_add_many(table,
566++ TABLE_EMPTY,
567++ TABLE_STRING, "Activation Policy:",
568++ TABLE_STRING, activation_policy);
569++ if (r < 0)
570++ return table_log_add_error(r);
571++ }
572++
573+ if (lease) {
574+ const void *client_id;
575+ size_t client_id_len;
576+--- a/src/network/networkd-link.c
577++++ b/src/network/networkd-link.c
578+@@ -3040,6 +3040,9 @@
579+ st.max != LINK_OPERSTATE_RANGE_DEFAULT.max ? ":" : "",
580+ st.max != LINK_OPERSTATE_RANGE_DEFAULT.max ? strempty(link_operstate_to_string(st.max)) : "");
581+
582++ fprintf(f, "ACTIVATION_POLICY=%s\n",
583++ activation_policy_to_string(link->network->activation_policy));
584++
585+ fprintf(f, "NETWORK_FILE=%s\n", link->network->filename);
586+
587+ /************************************************************/
588+--- a/src/systemd/sd-network.h
589++++ b/src/systemd/sd-network.h
590+@@ -103,6 +103,11 @@
591+ */
592+ int sd_network_link_get_required_for_online(int ifindex);
593+
594++/* Get activation policy for ifindex.
595++ * Possible values are as specified for ActivationPolicy=
596++ */
597++int sd_network_link_get_activation_policy(int ifindex, char **policy);
598++
599+ /* Get path to .network file applied to link */
600+ int sd_network_link_get_network_file(int ifindex, char **filename);
601+
602+--- a/test/test-network/systemd-networkd-tests.py
603++++ b/test/test-network/systemd-networkd-tests.py
604+@@ -2931,6 +2931,7 @@
605+ self.assertRegex(data, r'OPER_STATE=routable')
606+ self.assertRegex(data, r'REQUIRED_FOR_ONLINE=yes')
607+ self.assertRegex(data, r'REQUIRED_OPER_STATE_FOR_ONLINE=routable')
608++ self.assertRegex(data, r'ACTIVATION_POLICY=up')
609+ self.assertRegex(data, r'NETWORK_FILE=/run/systemd/network/state-file-tests.network')
610+ self.assertRegex(data, r'DNS=10.10.10.10#aaa.com 10.10.10.11:1111#bbb.com \[1111:2222::3333\]:1234#ccc.com')
611+ self.assertRegex(data, r'NTP=0.fedora.pool.ntp.org 1.fedora.pool.ntp.org')
612diff --git a/debian/patches/series b/debian/patches/series
613index afeff62..b220c6e 100644
614--- a/debian/patches/series
615+++ b/debian/patches/series
616@@ -62,3 +62,6 @@ lp1887744-basic-unit-file-when-loading-linked-unit-files-use-l.patch
617 lp1921696/rfkill-improve-error-logging.patch
618 lp1921696/rfkill-use-short-writes-and-accept-long-reads.patch
619 LoadCredentials-do-not-assert-on-invalid-syntax.patch
620+lp1664844/0001-network-add-ActivationPolicy-configuration-parameter.patch
621+lp1664844/0002-test-add-ActivationPolicy-unit-tests.patch
622+lp1664844/0003-save-link-activation-policy-to-state-file-and-displa.patch

Subscribers

People subscribed via source and target branches