Skip to content

Commit 3e522b7

Browse files
authored
nm:parse-nm: handle differing ip6-privacy default value (#263)
Commit 64e381e (#244) changed netplan's behaviour to always write out the ipv6-privacy value (default to 0=off), in order to comply with what is written in our documentation and how it is implemented in the networkd backend. This is a problem for our NetworkManager integration, as NM's default value is -1=unknown. Netplan only supports values 0=off and 2=on while NM supports -1, 0, 1 and 2. We need to handle unsupported cases (-1 and 1) via passthrough.
1 parent 7030ca9 commit 3e522b7

File tree

4 files changed

+101
-1
lines changed

4 files changed

+101
-1
lines changed

src/nm.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -531,7 +531,12 @@ write_fallback_key_value(GQuark key_id, gpointer value, gpointer user_data)
531531
/* delete the dummy key, if this was just an empty group */
532532
if (!g_strcmp0(k, NETPLAN_NM_EMPTY_GROUP))
533533
g_key_file_remove_key(kf, group, k, NULL);
534-
else if (!has_key) {
534+
/* handle differing defaults:
535+
* ipv6.ip6-privacy is "-1 (unknown)" by default in NM, it is "0 (off)" in netplan */
536+
else if (g_strcmp0(key, "ipv6.ip6-privacy") == 0 && g_strcmp0(val, "-1") == 0) {
537+
g_debug("NetworkManager: default override: clearing %s.%s", group, k);
538+
g_key_file_remove_key(kf, group, k, NULL);
539+
} else if (!has_key) {
535540
g_debug("NetworkManager: passing through fallback key: %s.%s=%s", group, k, val);
536541
g_key_file_set_comment(kf, group, k, "Netplan: passthrough setting", NULL);
537542
} else if (!!g_strcmp0(val, old_key)) {

src/parse-nm.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,15 @@ netplan_parser_load_keyfile(NetplanParser* npp, const char* filename, GError** e
497497
if (nd_type == NETPLAN_DEF_TYPE_NM)
498498
goto only_passthrough; //do not try to handle any keys for connections types unknown to netplan
499499

500+
/* Handle some differing NM/netplan defaults */
501+
tmp_str = g_key_file_get_string(kf, "ipv6", "method", NULL);
502+
if ( g_key_file_has_group(kf, "ipv6") && g_strcmp0(tmp_str, "ignore") != 0 &&
503+
!g_key_file_has_key(kf, "ipv6", "ip6-privacy", NULL)) {
504+
/* put NM's default into passthrough, as this is not currently supported by netplan */
505+
g_key_file_set_integer(kf, "ipv6", "ip6-privacy", -1);
506+
}
507+
g_free(tmp_str);
508+
500509
/* remove supported values from passthrough, which have been handled */
501510
if ( nd_type == NETPLAN_DEF_TYPE_ETHERNET
502511
|| nd_type == NETPLAN_DEF_TYPE_WIFI
@@ -556,6 +565,21 @@ netplan_parser_load_keyfile(NetplanParser* npp, const char* filename, GError** e
556565
g_free(tmp_str);
557566
handle_generic_str(kf, "ipv6", "token", &nd->ip6_addr_gen_token);
558567

568+
/* ip6-privacy is not fully supported, NM supports additional modes, like -1 or 1
569+
* handle known modes, but keep any unsupported "ip6-privacy" value in passthrough */
570+
if (g_key_file_has_group(kf, "ipv6")) {
571+
if (g_key_file_has_key(kf, "ipv6", "ip6-privacy", NULL)) {
572+
int ip6_privacy = g_key_file_get_integer(kf, "ipv6", "ip6-privacy", NULL);
573+
if (ip6_privacy == 0) {
574+
nd->ip6_privacy = FALSE;
575+
_kf_clear_key(kf, "ipv6", "ip6-privacy");
576+
} else if (ip6_privacy == 2) {
577+
nd->ip6_privacy = TRUE;
578+
_kf_clear_key(kf, "ipv6", "ip6-privacy");
579+
}
580+
}
581+
}
582+
559583
/* Modem parameters
560584
* NM differentiates between GSM and CDMA connections, while netplan
561585
* combines them as "modems". We need to parse a basic set of parameters

tests/generator/test_passthrough.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,4 +283,35 @@ def test_passthrough_interface_rename_existing_id(self):
283283
284284
[ipv6]
285285
method=ignore
286+
'''})
287+
288+
def test_passthrough_ip6_privacy_default(self):
289+
self.generate('''network:
290+
version: 2
291+
renderer: NetworkManager
292+
ethernets:
293+
eth0:
294+
dhcp4: true
295+
dhcp6: true
296+
networkmanager:
297+
uuid: 626dd384-8b3d-3690-9511-192b2c79b3fd
298+
name: "netplan-eth0"
299+
passthrough:
300+
"ipv6.ip6-privacy": "-1"
301+
''')
302+
303+
self.assert_nm({'eth0': '''[connection]
304+
id=netplan-eth0
305+
type=ethernet
306+
uuid=626dd384-8b3d-3690-9511-192b2c79b3fd
307+
interface-name=eth0
308+
309+
[ethernet]
310+
wake-on-lan=0
311+
312+
[ipv4]
313+
method=auto
314+
315+
[ipv6]
316+
method=auto
286317
'''})

tests/parser/test_keyfile.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ def test_keyfile_gsm(self):
6969
[ipv6]
7070
dns-search=
7171
method=auto
72+
ip6-privacy=0
7273
'''.format(UUID))
7374
self.assert_netplan({UUID: '''network:
7475
version: 2
@@ -204,6 +205,7 @@ def test_keyfile_method_auto(self):
204205
addr-gen-mode=eui64
205206
dns-search=
206207
method=auto
208+
ip6-privacy=0
207209
ignore-auto-routes=true
208210
never-default=true
209211
route-metric=4242
@@ -280,6 +282,7 @@ def test_keyfile_method_manual(self):
280282
dns-search=bar.local
281283
dns=dead:beef::2;
282284
method=manual
285+
ip6-privacy=2
283286
address1=1:2:3::9/128
284287
gateway=6:6::6
285288
route1=dead:beef::1/128,2001:1234::2
@@ -310,6 +313,7 @@ def test_keyfile_method_manual(self):
310313
gateway4: 6.6.6.6
311314
gateway6: 6:6::6
312315
ipv6-address-generation: "stable-privacy"
316+
ipv6-privacy: true
313317
routes:
314318
- metric: 42
315319
table: 102
@@ -710,6 +714,7 @@ def test_keyfile_yaml_wifi_hotspot(self):
710714
method=ignore
711715
addr-gen-mode=1
712716
dns-search=
717+
ip6-privacy=0
713718
714719
[wifi]
715720
ssid=my-hotspot
@@ -1018,6 +1023,7 @@ def test_keyfile_customer_A2(self):
10181023
[ipv6]
10191024
method=auto
10201025
addr-gen-mode=1
1026+
ip6-privacy=0
10211027
'''.format(UUID))
10221028
self.assert_netplan({UUID: '''network:
10231029
version: 2
@@ -1080,6 +1086,7 @@ def test_keyfile_netplan0103_compat(self):
10801086
dns=1::cafe;2::cafe;
10811087
dns-search=wallaceandgromit.com;
10821088
method=manual
1089+
ip6-privacy=1
10831090
route1=1:2:3:4:5:6:7:8/64,8:7:6:5:4:3:2:1,3
10841091
route2=2001::1000/56,2001::1111,1
10851092
route3=4:5:6:7:8:9:0:1/63,::,5
@@ -1151,6 +1158,7 @@ def test_keyfile_netplan0103_compat(self):
11511158
ipv4.route4: "3.3.3.3/6,0.0.0.0,4"
11521159
ipv4.route4_options: "cwnd=10,mtu=1492,src=1.2.3.4"
11531160
ipv6.dns-search: "wallaceandgromit.com;"
1161+
ipv6.ip6-privacy: "1"
11541162
proxy._: ""
11551163
'''.format(UUID, UUID)})
11561164

@@ -1202,3 +1210,35 @@ def test_keyfile_tunnel_regression_lp1952967(self):
12021210
ipv6.method: "auto"
12031211
proxy._: ""
12041212
'''.format(UUID, UUID)})
1213+
1214+
def test_keyfile_ip6_privacy_default_netplan_0104_compat(self):
1215+
self.generate_from_keyfile('''[connection]
1216+
id=Test
1217+
uuid={}
1218+
type=ethernet
1219+
1220+
[ethernet]
1221+
mac-address=99:88:77:66:55:44
1222+
1223+
[ipv4]
1224+
method=auto
1225+
1226+
[ipv6]
1227+
method=auto
1228+
'''.format(UUID))
1229+
self.assert_netplan({UUID: '''network:
1230+
version: 2
1231+
ethernets:
1232+
NM-{}:
1233+
renderer: NetworkManager
1234+
match:
1235+
macaddress: "99:88:77:66:55:44"
1236+
dhcp4: true
1237+
dhcp6: true
1238+
wakeonlan: true
1239+
networkmanager:
1240+
uuid: "{}"
1241+
name: "Test"
1242+
passthrough:
1243+
ipv6.ip6-privacy: "-1"
1244+
'''.format(UUID, UUID)})

0 commit comments

Comments
 (0)