Merge ~raharper/netplan:fix/accept-ra-no-default into ~netplan-developers/netplan/+git/netplan:master

Proposed by Ryan Harper
Status: Work in progress
Proposed branch: ~raharper/netplan:fix/accept-ra-no-default
Merge into: ~netplan-developers/netplan/+git/netplan:master
Diff against target: 366 lines (+107/-36)
5 files modified
doc/netplan.md (+2/-1)
src/networkd.c (+13/-3)
src/parse.c (+24/-6)
src/parse.h (+7/-1)
tests/generate.py (+61/-25)
Reviewer Review Type Date Requested Status
Mathieu Trudel-Lapierre Pending
Review via email: mp+342976@code.launchpad.net

Commit message

accept-ra: do not enable by default, default to unset

Do not always emit an IPv6AcceptRA value into network configurations.
Systemd-networkd defaults to kernel value as long as the value stays
unset in the configuration. When IPv6AcceptRA is enabled in systemd
this makes networkd wait 10 seconds for potential RAs to arrive. This
delays boot by 10 seconds always whether or not the network has an
IPV6 Router running. Leaving things unsets keeps existing behavior
of Ubuntu systems where RAs are accepted and processed at the time
they are received and boot is not delayed by waiting for an RA to arrive.

If users want to forcibly enable or disable, they may do so by including
a value for accept-ra in their yaml configuraion.

LP: #1732002

To post a comment you must log in.
Revision history for this message
Ryan Harper (raharper) wrote :

This has been moved to a github pull:

https://github.com/CanonicalLtd/netplan/pull/19

Unmerged commits

22ffd4d... by Ryan Harper

accept-ra: do not enable by default, default to unset

Do not always emit an IPv6AcceptRA value into network configurations.
Systemd-networkd defaults to kernel value as long as the value stays
unset in the configuration. When IPv6AcceptRA is enabled in systemd
this makes networkd wait 10 seconds for potential RAs to arrive. This
delays boot by 10 seconds always whether or not the network has an
IPV6 Router running. Leaving things unsets keeps existing behavior
of Ubuntu systems where RAs are accepted and processed at the time
they are received and boot is not delayed by waiting for an RA to arrive.

If users want to forcibly enable or disable, they may do so by including
a value for accept-ra in their yaml configuraion.

LP: #1732002

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/doc/netplan.md b/doc/netplan.md
2index 146ae01..978eb6b 100644
3--- a/doc/netplan.md
4+++ b/doc/netplan.md
5@@ -168,7 +168,8 @@ Virtual devices
6 ``accept-ra`` (bool)
7
8 : Accept Router Advertisement that would have the kernel configure IPv6 by itself.
9- On by default.
10+ When enabled, accept Router Advertisements. When disabled, do not respond to
11+ Router Advertisements. If unset use the host kernel default setting.
12
13 ``addresses`` (sequence of scalars)
14
15diff --git a/src/networkd.c b/src/networkd.c
16index 7b9d2be..c092c22 100644
17--- a/src/networkd.c
18+++ b/src/networkd.c
19@@ -286,7 +286,9 @@ write_network_file(net_definition* def, const char* rootdir, const char* path)
20 if (def->ip6_addresses)
21 for (unsigned i = 0; i < def->ip6_addresses->len; ++i)
22 g_string_append_printf(s, "Address=%s\n", g_array_index(def->ip6_addresses, char*, i));
23- if (!def->accept_ra)
24+ if (def->accept_ra == ACCEPT_RA_ENABLED)
25+ g_string_append_printf(s, "IPv6AcceptRA=yes\n");
26+ else if (def->accept_ra == ACCEPT_RA_DISABLED)
27 g_string_append_printf(s, "IPv6AcceptRA=no\n");
28 if (def->gateway4)
29 g_string_append_printf(s, "Gateway=%s\n", def->gateway4);
30@@ -305,8 +307,12 @@ write_network_file(net_definition* def, const char* rootdir, const char* path)
31 g_string_append(s, "\n");
32 }
33 if (def->bridge) {
34- g_string_append_printf(s, "Bridge=%s\nLinkLocalAddressing=no\nIPv6AcceptRA=no\n", def->bridge);
35+ g_string_append_printf(s, "Bridge=%s\nLinkLocalAddressing=no\n", def->bridge);
36
37+ if (def->accept_ra == ACCEPT_RA_ENABLED)
38+ g_string_append_printf(s, "IPv6AcceptRA=yes\n");
39+ else if (def->accept_ra == ACCEPT_RA_DISABLED)
40+ g_string_append_printf(s, "IPv6AcceptRA=no\n");
41 if (def->bridge_params.path_cost || def->bridge_params.port_priority)
42 g_string_append_printf(s, "\n[Bridge]\n");
43 if (def->bridge_params.path_cost)
44@@ -315,8 +321,12 @@ write_network_file(net_definition* def, const char* rootdir, const char* path)
45 g_string_append_printf(s, "Priority=%u\n", def->bridge_params.port_priority);
46 }
47 if (def->bond) {
48- g_string_append_printf(s, "Bond=%s\nLinkLocalAddressing=no\nIPv6AcceptRA=no\n", def->bond);
49+ g_string_append_printf(s, "Bond=%s\nLinkLocalAddressing=no\n", def->bond);
50
51+ if (def->accept_ra == ACCEPT_RA_ENABLED)
52+ g_string_append_printf(s, "IPv6AcceptRA=yes\n");
53+ else if (def->accept_ra == ACCEPT_RA_DISABLED)
54+ g_string_append_printf(s, "IPv6AcceptRA=no\n");
55 if (def->bond_params.primary_slave)
56 g_string_append_printf(s, "PrimarySlave=true\n");
57 }
58diff --git a/src/parse.c b/src/parse.c
59index 7627462..c0a16f3 100644
60--- a/src/parse.c
61+++ b/src/parse.c
62@@ -462,6 +462,25 @@ handle_netdef_renderer(yaml_document_t* doc, yaml_node_t* node, const void* _, G
63 }
64
65 static gboolean
66+handle_accept_ra(yaml_document_t* doc, yaml_node_t* node, const void* data, GError** error)
67+{
68+ if (g_ascii_strcasecmp(scalar(node), "true") == 0 ||
69+ g_ascii_strcasecmp(scalar(node), "on") == 0 ||
70+ g_ascii_strcasecmp(scalar(node), "yes") == 0 ||
71+ g_ascii_strcasecmp(scalar(node), "y") == 0)
72+ cur_netdef->accept_ra = ACCEPT_RA_ENABLED;
73+ else if (g_ascii_strcasecmp(scalar(node), "false") == 0 ||
74+ g_ascii_strcasecmp(scalar(node), "off") == 0 ||
75+ g_ascii_strcasecmp(scalar(node), "no") == 0 ||
76+ g_ascii_strcasecmp(scalar(node), "n") == 0)
77+ cur_netdef->accept_ra = ACCEPT_RA_DISABLED;
78+ else
79+ return yaml_error(node, error, "invalid boolean value %s", scalar(node));
80+
81+ return TRUE;
82+}
83+
84+static gboolean
85 handle_match(yaml_document_t* doc, yaml_node_t* node, const void* _, GError** error)
86 {
87 cur_netdef->has_match = TRUE;
88@@ -1219,7 +1238,7 @@ const mapping_entry_handler ethernet_def_handlers[] = {
89 {"dhcp4", YAML_SCALAR_NODE, handle_netdef_bool, NULL, netdef_offset(dhcp4)},
90 {"dhcp6", YAML_SCALAR_NODE, handle_netdef_bool, NULL, netdef_offset(dhcp6)},
91 {"dhcp-identifier", YAML_SCALAR_NODE, handle_dhcp_identifier},
92- {"accept-ra", YAML_SCALAR_NODE, handle_netdef_bool, NULL, netdef_offset(accept_ra)},
93+ {"accept-ra", YAML_SCALAR_NODE, handle_accept_ra},
94 {"gateway4", YAML_SCALAR_NODE, handle_gateway4},
95 {"gateway6", YAML_SCALAR_NODE, handle_gateway6},
96 {"macaddress", YAML_SCALAR_NODE, handle_netdef_mac, NULL, netdef_offset(set_mac)},
97@@ -1241,7 +1260,7 @@ const mapping_entry_handler wifi_def_handlers[] = {
98 {"dhcp4", YAML_SCALAR_NODE, handle_netdef_bool, NULL, netdef_offset(dhcp4)},
99 {"dhcp6", YAML_SCALAR_NODE, handle_netdef_bool, NULL, netdef_offset(dhcp6)},
100 {"dhcp-identifier", YAML_SCALAR_NODE, handle_dhcp_identifier},
101- {"accept-ra", YAML_SCALAR_NODE, handle_netdef_bool, NULL, netdef_offset(accept_ra)},
102+ {"accept-ra", YAML_SCALAR_NODE, handle_accept_ra},
103 {"gateway4", YAML_SCALAR_NODE, handle_gateway4},
104 {"gateway6", YAML_SCALAR_NODE, handle_gateway6},
105 {"macaddress", YAML_SCALAR_NODE, handle_netdef_mac, NULL, netdef_offset(set_mac)},
106@@ -1262,7 +1281,7 @@ const mapping_entry_handler bridge_def_handlers[] = {
107 {"dhcp4", YAML_SCALAR_NODE, handle_netdef_bool, NULL, netdef_offset(dhcp4)},
108 {"dhcp6", YAML_SCALAR_NODE, handle_netdef_bool, NULL, netdef_offset(dhcp6)},
109 {"dhcp-identifier", YAML_SCALAR_NODE, handle_dhcp_identifier},
110- {"accept-ra", YAML_SCALAR_NODE, handle_netdef_bool, NULL, netdef_offset(accept_ra)},
111+ {"accept-ra", YAML_SCALAR_NODE, handle_accept_ra},
112 {"gateway4", YAML_SCALAR_NODE, handle_gateway4},
113 {"gateway6", YAML_SCALAR_NODE, handle_gateway6},
114 {"interfaces", YAML_SEQUENCE_NODE, handle_bridge_interfaces, NULL, NULL},
115@@ -1282,7 +1301,7 @@ const mapping_entry_handler bond_def_handlers[] = {
116 {"dhcp4", YAML_SCALAR_NODE, handle_netdef_bool, NULL, netdef_offset(dhcp4)},
117 {"dhcp6", YAML_SCALAR_NODE, handle_netdef_bool, NULL, netdef_offset(dhcp6)},
118 {"dhcp-identifier", YAML_SCALAR_NODE, handle_dhcp_identifier},
119- {"accept-ra", YAML_SCALAR_NODE, handle_netdef_bool, NULL, netdef_offset(accept_ra)},
120+ {"accept-ra", YAML_SCALAR_NODE, handle_accept_ra},
121 {"gateway4", YAML_SCALAR_NODE, handle_gateway4},
122 {"gateway6", YAML_SCALAR_NODE, handle_gateway6},
123 {"interfaces", YAML_SEQUENCE_NODE, handle_bond_interfaces, NULL, NULL},
124@@ -1302,7 +1321,7 @@ const mapping_entry_handler vlan_def_handlers[] = {
125 {"dhcp4", YAML_SCALAR_NODE, handle_netdef_bool, NULL, netdef_offset(dhcp4)},
126 {"dhcp6", YAML_SCALAR_NODE, handle_netdef_bool, NULL, netdef_offset(dhcp6)},
127 {"dhcp-identifier", YAML_SCALAR_NODE, handle_dhcp_identifier},
128- {"accept-ra", YAML_SCALAR_NODE, handle_netdef_bool, NULL, netdef_offset(accept_ra)},
129+ {"accept-ra", YAML_SCALAR_NODE, handle_accept_ra},
130 {"gateway4", YAML_SCALAR_NODE, handle_gateway4},
131 {"gateway6", YAML_SCALAR_NODE, handle_gateway6},
132 {"id", YAML_SCALAR_NODE, handle_netdef_guint, NULL, netdef_offset(vlan_id)},
133@@ -1414,7 +1433,6 @@ handle_network_type(yaml_document_t* doc, yaml_node_t* node, const void* data, G
134 cur_netdef->backend = backend_cur_type ?: BACKEND_NONE;
135 cur_netdef->id = g_strdup(scalar(key));
136 cur_netdef->vlan_id = G_MAXUINT; /* 0 is a valid ID */
137- cur_netdef->accept_ra = TRUE; /* By default, accept RAs */
138 cur_netdef->dhcp_identifier = g_strdup("duid"); /* keep networkd's default */
139 g_hash_table_insert(netdefs, cur_netdef->id, cur_netdef);
140 }
141diff --git a/src/parse.h b/src/parse.h
142index 510f09f..8cf5e12 100644
143--- a/src/parse.h
144+++ b/src/parse.h
145@@ -49,6 +49,12 @@ static const char* const netdef_backend_to_name[_BACKEND_MAX] = {
146 [BACKEND_NM] = "NetworkManager",
147 };
148
149+typedef enum {
150+ ACCEPT_RA_KERNEL,
151+ ACCEPT_RA_ENABLED,
152+ ACCEPT_RA_DISABLED,
153+} ra_mode;
154+
155 typedef struct missing_node {
156 char* netdef_id;
157 const yaml_node_t* node;
158@@ -71,7 +77,7 @@ typedef struct net_definition {
159 gboolean dhcp4;
160 gboolean dhcp6;
161 char* dhcp_identifier;
162- gboolean accept_ra;
163+ ra_mode accept_ra;
164 GArray* ip4_addresses;
165 GArray* ip6_addresses;
166 char* gateway4;
167diff --git a/tests/generate.py b/tests/generate.py
168index b168c47..29cd2f6 100755
169--- a/tests/generate.py
170+++ b/tests/generate.py
171@@ -345,7 +345,7 @@ unmanaged-devices+=interface-name:eth0,''')
172 'bond0.netdev': '[NetDev]\nName=bond0\nMTUBytes=9000\nKind=bond\n',
173 'bond0.network': '[Match]\nName=bond0\n\n[Network]\nVLAN=bond0.108\n',
174 'eth1.link': '[Match]\nOriginalName=eth1\n\n[Link]\nWakeOnLan=off\nMTUBytes=1280\n',
175- 'eth1.network': '[Match]\nName=eth1\n\n[Network]\nBond=bond0\nLinkLocalAddressing=no\nIPv6AcceptRA=no\n'
176+ 'eth1.network': '[Match]\nName=eth1\n\n[Network]\nBond=bond0\nLinkLocalAddressing=no\n'
177 })
178
179 def test_eth_match_by_driver_rename(self):
180@@ -592,6 +592,42 @@ UseMTU=true
181 RouteMetric=100
182 '''})
183
184+ def test_eth_dhcp6_accept_ra(self):
185+ self.generate('''network:
186+ version: 2
187+ ethernets:
188+ eth0:
189+ dhcp6: true
190+ accept-ra: yes''')
191+ self.assert_networkd({'eth0.network': '''[Match]
192+Name=eth0
193+
194+[Network]
195+DHCP=ipv6
196+IPv6AcceptRA=yes
197+
198+[DHCP]
199+UseMTU=true
200+RouteMetric=100
201+'''})
202+
203+ def test_eth_dhcp6_accept_ra_unset(self):
204+ self.generate('''network:
205+ version: 2
206+ ethernets:
207+ eth0:
208+ dhcp6: true''')
209+ self.assert_networkd({'eth0.network': '''[Match]
210+Name=eth0
211+
212+[Network]
213+DHCP=ipv6
214+
215+[DHCP]
216+UseMTU=true
217+RouteMetric=100
218+'''})
219+
220 def test_eth_dhcp4_and_6(self):
221 self.generate('''network:
222 version: 2
223@@ -1222,9 +1258,9 @@ unmanaged-devices+=interface-name:br0,''')
224 self.assert_networkd({'br0.netdev': '[NetDev]\nName=br0\nKind=bridge\n',
225 'br0.network': ND_DHCP4 % 'br0',
226 'eno1.network': '[Match]\nName=eno1\n\n'
227- '[Network]\nBridge=br0\nLinkLocalAddressing=no\nIPv6AcceptRA=no\n',
228+ '[Network]\nBridge=br0\nLinkLocalAddressing=no\n',
229 'switchports.network': '[Match]\nDriver=yayroute\n\n'
230- '[Network]\nBridge=br0\nLinkLocalAddressing=no\nIPv6AcceptRA=no\n'})
231+ '[Network]\nBridge=br0\nLinkLocalAddressing=no\n'})
232
233 def test_eth_bridge_nm_blacklist(self):
234 self.generate('''network:
235@@ -1258,9 +1294,9 @@ unmanaged-devices+=interface-name:eth42,interface-name:eth43,interface-name:mybr
236 self.assert_networkd({'br0.netdev': '[NetDev]\nName=br0\nKind=bridge\n',
237 'br0.network': ND_DHCP4 % 'br0',
238 'eno1.network': '[Match]\nName=eno1\n\n'
239- '[Network]\nBridge=br0\nLinkLocalAddressing=no\nIPv6AcceptRA=no\n',
240+ '[Network]\nBridge=br0\nLinkLocalAddressing=no\n',
241 'switchports.network': '[Match]\nDriver=yayroute\n\n'
242- '[Network]\nBridge=br0\nLinkLocalAddressing=no\nIPv6AcceptRA=no\n'})
243+ '[Network]\nBridge=br0\nLinkLocalAddressing=no\n'})
244
245 def test_bridge_params(self):
246 self.generate('''network:
247@@ -1295,10 +1331,10 @@ unmanaged-devices+=interface-name:eth42,interface-name:eth43,interface-name:mybr
248 'STP=true\n',
249 'br0.network': ND_DHCP4 % 'br0',
250 'eno1.network': '[Match]\nName=eno1\n\n'
251- '[Network]\nBridge=br0\nLinkLocalAddressing=no\nIPv6AcceptRA=no\n\n'
252+ '[Network]\nBridge=br0\nLinkLocalAddressing=no\n\n'
253 '[Bridge]\nCost=70\nPriority=14\n',
254 'switchports.network': '[Match]\nDriver=yayroute\n\n'
255- '[Network]\nBridge=br0\nLinkLocalAddressing=no\nIPv6AcceptRA=no\n'})
256+ '[Network]\nBridge=br0\nLinkLocalAddressing=no\n'})
257
258 def test_bond_empty(self):
259 self.generate('''network:
260@@ -1330,9 +1366,9 @@ unmanaged-devices+=interface-name:bn0,''')
261 self.assert_networkd({'bn0.netdev': '[NetDev]\nName=bn0\nKind=bond\n',
262 'bn0.network': ND_DHCP4 % 'bn0',
263 'eno1.network': '[Match]\nName=eno1\n\n'
264- '[Network]\nBond=bn0\nLinkLocalAddressing=no\nIPv6AcceptRA=no\n',
265+ '[Network]\nBond=bn0\nLinkLocalAddressing=no\n',
266 'switchports.network': '[Match]\nDriver=yayroute\n\n'
267- '[Network]\nBond=bn0\nLinkLocalAddressing=no\nIPv6AcceptRA=no\n'})
268+ '[Network]\nBond=bn0\nLinkLocalAddressing=no\n'})
269
270 def test_bond_empty_parameters(self):
271 self.generate('''network:
272@@ -1351,9 +1387,9 @@ unmanaged-devices+=interface-name:bn0,''')
273 self.assert_networkd({'bn0.netdev': '[NetDev]\nName=bn0\nKind=bond\n',
274 'bn0.network': ND_DHCP4 % 'bn0',
275 'eno1.network': '[Match]\nName=eno1\n\n'
276- '[Network]\nBond=bn0\nLinkLocalAddressing=no\nIPv6AcceptRA=no\n',
277+ '[Network]\nBond=bn0\nLinkLocalAddressing=no\n',
278 'switchports.network': '[Match]\nDriver=yayroute\n\n'
279- '[Network]\nBond=bn0\nLinkLocalAddressing=no\nIPv6AcceptRA=no\n'})
280+ '[Network]\nBond=bn0\nLinkLocalAddressing=no\n'})
281
282 def test_bond_with_parameters(self):
283 self.generate('''network:
284@@ -1413,9 +1449,9 @@ unmanaged-devices+=interface-name:bn0,''')
285 'LearnPacketIntervalSec=10\n',
286 'bn0.network': ND_DHCP4 % 'bn0',
287 'eno1.network': '[Match]\nName=eno1\n\n'
288- '[Network]\nBond=bn0\nLinkLocalAddressing=no\nIPv6AcceptRA=no\n',
289+ '[Network]\nBond=bn0\nLinkLocalAddressing=no\n',
290 'switchports.network': '[Match]\nDriver=yayroute\n\n'
291- '[Network]\nBond=bn0\nLinkLocalAddressing=no\nIPv6AcceptRA=no\n'})
292+ '[Network]\nBond=bn0\nLinkLocalAddressing=no\n'})
293
294 def test_bond_primary_slave(self):
295 self.generate('''network:
296@@ -1438,9 +1474,9 @@ unmanaged-devices+=interface-name:bn0,''')
297 'Mode=active-backup\n',
298 'bn0.network': ND_DHCP4 % 'bn0',
299 'eno1.network': '[Match]\nName=eno1\n\n'
300- '[Network]\nBond=bn0\nLinkLocalAddressing=no\nIPv6AcceptRA=no\nPrimarySlave=true\n',
301+ '[Network]\nBond=bn0\nLinkLocalAddressing=no\nPrimarySlave=true\n',
302 'switchports.network': '[Match]\nDriver=yayroute\n\n'
303- '[Network]\nBond=bn0\nLinkLocalAddressing=no\nIPv6AcceptRA=no\n'})
304+ '[Network]\nBond=bn0\nLinkLocalAddressing=no\n'})
305
306 def test_gateway(self):
307 self.generate('''network:
308@@ -4181,15 +4217,15 @@ class TestForwardDeclaration(TestBase):
309 'br0.network': ND_DHCP4 % 'br0',
310 'bond0.netdev': '[NetDev]\nName=bond0\nKind=bond\n',
311 'bond0.network': '[Match]\nName=bond0\n\n'
312- '[Network]\nBridge=br0\nLinkLocalAddressing=no\nIPv6AcceptRA=no\n',
313+ '[Network]\nBridge=br0\nLinkLocalAddressing=no\n',
314 'eth0.link': '[Match]\nMACAddress=00:01:02:03:04:05\n\n'
315 '[Link]\nName=eth0\nWakeOnLan=off\n',
316 'eth0.network': '[Match]\nMACAddress=00:01:02:03:04:05\nName=eth0\n\n'
317- '[Network]\nBond=bond0\nLinkLocalAddressing=no\nIPv6AcceptRA=no\n',
318+ '[Network]\nBond=bond0\nLinkLocalAddressing=no\n',
319 'eth1.link': '[Match]\nMACAddress=02:01:02:03:04:05\n\n'
320 '[Link]\nName=eth1\nWakeOnLan=off\n',
321 'eth1.network': '[Match]\nMACAddress=02:01:02:03:04:05\nName=eth1\n\n'
322- '[Network]\nBond=bond0\nLinkLocalAddressing=no\nIPv6AcceptRA=no\n'})
323+ '[Network]\nBond=bond0\nLinkLocalAddressing=no\n'})
324
325 def test_fwdecl_feature_blend(self):
326 self.generate('''network:
327@@ -4236,22 +4272,22 @@ class TestForwardDeclaration(TestBase):
328 '[Network]\nVLAN=vlan1\n',
329 'bond0.netdev': '[NetDev]\nName=bond0\nKind=bond\n',
330 'bond0.network': '[Match]\nName=bond0\n\n'
331- '[Network]\nBridge=br0\nLinkLocalAddressing=no\nIPv6AcceptRA=no\n\n'
332+ '[Network]\nBridge=br0\nLinkLocalAddressing=no\n\n'
333 '[Bridge]\nCost=8888\n',
334 'eth2.network': '[Match]\nName=eth2\n\n'
335- '[Network]\nBridge=br0\nLinkLocalAddressing=no\nIPv6AcceptRA=no\n\n'
336+ '[Network]\nBridge=br0\nLinkLocalAddressing=no\n\n'
337 '[Bridge]\nCost=1000\n',
338 'br1.netdev': '[NetDev]\nName=br1\nKind=bridge\n',
339 'br1.network': '[Match]\nName=br1\n\n'
340- '[Network]\nBond=bond0\nLinkLocalAddressing=no\nIPv6AcceptRA=no\n',
341+ '[Network]\nBond=bond0\nLinkLocalAddressing=no\n',
342 'eth0.link': '[Match]\nMACAddress=00:01:02:03:04:05\n\n'
343 '[Link]\nName=eth0\nWakeOnLan=off\n',
344 'eth0.network': '[Match]\nMACAddress=00:01:02:03:04:05\nName=eth0\n\n'
345- '[Network]\nBond=bond0\nLinkLocalAddressing=no\nIPv6AcceptRA=no\n',
346+ '[Network]\nBond=bond0\nLinkLocalAddressing=no\n',
347 'eth1.link': '[Match]\nMACAddress=02:01:02:03:04:05\n\n'
348 '[Link]\nName=eth1\nWakeOnLan=off\n',
349 'eth1.network': '[Match]\nMACAddress=02:01:02:03:04:05\nName=eth1\n\n'
350- '[Network]\nBridge=br1\nLinkLocalAddressing=no\nIPv6AcceptRA=no\n'})
351+ '[Network]\nBridge=br1\nLinkLocalAddressing=no\n'})
352
353
354 class TestMerging(TestBase):
355@@ -4349,9 +4385,9 @@ unmanaged-devices+=interface-name:engreen,''')
356 self.assert_networkd({'br0.netdev': '[NetDev]\nName=br0\nKind=bridge\n',
357 'br0.network': ND_DHCP4 % 'br0',
358 'eno1.network': '[Match]\nName=eno1\n\n'
359- '[Network]\nBridge=br0\nLinkLocalAddressing=no\nIPv6AcceptRA=no\n',
360+ '[Network]\nBridge=br0\nLinkLocalAddressing=no\n',
361 'switchports.network': '[Match]\nDriver=yayroute\n\n'
362- '[Network]\nBridge=br0\nLinkLocalAddressing=no\nIPv6AcceptRA=no\n'})
363+ '[Network]\nBridge=br0\nLinkLocalAddressing=no\n'})
364
365 def test_def_in_run(self):
366 rundir = os.path.join(self.workdir.name, 'run', 'netplan')

Subscribers

People subscribed via source and target branches