Skip to content

Commit

Permalink
nm:parse-nm: handle differing ip6-privacy default value (#263)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
slyon committed Feb 16, 2022
1 parent 7030ca9 commit 3e522b7
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 1 deletion.
7 changes: 6 additions & 1 deletion src/nm.c
Original file line number Diff line number Diff line change
Expand Up @@ -531,7 +531,12 @@ write_fallback_key_value(GQuark key_id, gpointer value, gpointer user_data)
/* delete the dummy key, if this was just an empty group */
if (!g_strcmp0(k, NETPLAN_NM_EMPTY_GROUP))
g_key_file_remove_key(kf, group, k, NULL);
else if (!has_key) {
/* handle differing defaults:
* ipv6.ip6-privacy is "-1 (unknown)" by default in NM, it is "0 (off)" in netplan */
else if (g_strcmp0(key, "ipv6.ip6-privacy") == 0 && g_strcmp0(val, "-1") == 0) {
g_debug("NetworkManager: default override: clearing %s.%s", group, k);
g_key_file_remove_key(kf, group, k, NULL);
} else if (!has_key) {
g_debug("NetworkManager: passing through fallback key: %s.%s=%s", group, k, val);
g_key_file_set_comment(kf, group, k, "Netplan: passthrough setting", NULL);
} else if (!!g_strcmp0(val, old_key)) {
Expand Down
24 changes: 24 additions & 0 deletions src/parse-nm.c
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,15 @@ netplan_parser_load_keyfile(NetplanParser* npp, const char* filename, GError** e
if (nd_type == NETPLAN_DEF_TYPE_NM)
goto only_passthrough; //do not try to handle any keys for connections types unknown to netplan

/* Handle some differing NM/netplan defaults */
tmp_str = g_key_file_get_string(kf, "ipv6", "method", NULL);
if ( g_key_file_has_group(kf, "ipv6") && g_strcmp0(tmp_str, "ignore") != 0 &&
!g_key_file_has_key(kf, "ipv6", "ip6-privacy", NULL)) {
/* put NM's default into passthrough, as this is not currently supported by netplan */
g_key_file_set_integer(kf, "ipv6", "ip6-privacy", -1);
}
g_free(tmp_str);

/* remove supported values from passthrough, which have been handled */
if ( nd_type == NETPLAN_DEF_TYPE_ETHERNET
|| nd_type == NETPLAN_DEF_TYPE_WIFI
Expand Down Expand Up @@ -556,6 +565,21 @@ netplan_parser_load_keyfile(NetplanParser* npp, const char* filename, GError** e
g_free(tmp_str);
handle_generic_str(kf, "ipv6", "token", &nd->ip6_addr_gen_token);

/* ip6-privacy is not fully supported, NM supports additional modes, like -1 or 1
* handle known modes, but keep any unsupported "ip6-privacy" value in passthrough */
if (g_key_file_has_group(kf, "ipv6")) {
if (g_key_file_has_key(kf, "ipv6", "ip6-privacy", NULL)) {
int ip6_privacy = g_key_file_get_integer(kf, "ipv6", "ip6-privacy", NULL);
if (ip6_privacy == 0) {
nd->ip6_privacy = FALSE;
_kf_clear_key(kf, "ipv6", "ip6-privacy");
} else if (ip6_privacy == 2) {
nd->ip6_privacy = TRUE;
_kf_clear_key(kf, "ipv6", "ip6-privacy");
}
}
}

/* Modem parameters
* NM differentiates between GSM and CDMA connections, while netplan
* combines them as "modems". We need to parse a basic set of parameters
Expand Down
31 changes: 31 additions & 0 deletions tests/generator/test_passthrough.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,4 +283,35 @@ def test_passthrough_interface_rename_existing_id(self):
[ipv6]
method=ignore
'''})

def test_passthrough_ip6_privacy_default(self):
self.generate('''network:
version: 2
renderer: NetworkManager
ethernets:
eth0:
dhcp4: true
dhcp6: true
networkmanager:
uuid: 626dd384-8b3d-3690-9511-192b2c79b3fd
name: "netplan-eth0"
passthrough:
"ipv6.ip6-privacy": "-1"
''')

self.assert_nm({'eth0': '''[connection]
id=netplan-eth0
type=ethernet
uuid=626dd384-8b3d-3690-9511-192b2c79b3fd
interface-name=eth0
[ethernet]
wake-on-lan=0
[ipv4]
method=auto
[ipv6]
method=auto
'''})
40 changes: 40 additions & 0 deletions tests/parser/test_keyfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ def test_keyfile_gsm(self):
[ipv6]
dns-search=
method=auto
ip6-privacy=0
'''.format(UUID))
self.assert_netplan({UUID: '''network:
version: 2
Expand Down Expand Up @@ -204,6 +205,7 @@ def test_keyfile_method_auto(self):
addr-gen-mode=eui64
dns-search=
method=auto
ip6-privacy=0
ignore-auto-routes=true
never-default=true
route-metric=4242
Expand Down Expand Up @@ -280,6 +282,7 @@ def test_keyfile_method_manual(self):
dns-search=bar.local
dns=dead:beef::2;
method=manual
ip6-privacy=2
address1=1:2:3::9/128
gateway=6:6::6
route1=dead:beef::1/128,2001:1234::2
Expand Down Expand Up @@ -310,6 +313,7 @@ def test_keyfile_method_manual(self):
gateway4: 6.6.6.6
gateway6: 6:6::6
ipv6-address-generation: "stable-privacy"
ipv6-privacy: true
routes:
- metric: 42
table: 102
Expand Down Expand Up @@ -710,6 +714,7 @@ def test_keyfile_yaml_wifi_hotspot(self):
method=ignore
addr-gen-mode=1
dns-search=
ip6-privacy=0
[wifi]
ssid=my-hotspot
Expand Down Expand Up @@ -1018,6 +1023,7 @@ def test_keyfile_customer_A2(self):
[ipv6]
method=auto
addr-gen-mode=1
ip6-privacy=0
'''.format(UUID))
self.assert_netplan({UUID: '''network:
version: 2
Expand Down Expand Up @@ -1080,6 +1086,7 @@ def test_keyfile_netplan0103_compat(self):
dns=1::cafe;2::cafe;
dns-search=wallaceandgromit.com;
method=manual
ip6-privacy=1
route1=1:2:3:4:5:6:7:8/64,8:7:6:5:4:3:2:1,3
route2=2001::1000/56,2001::1111,1
route3=4:5:6:7:8:9:0:1/63,::,5
Expand Down Expand Up @@ -1151,6 +1158,7 @@ def test_keyfile_netplan0103_compat(self):
ipv4.route4: "3.3.3.3/6,0.0.0.0,4"
ipv4.route4_options: "cwnd=10,mtu=1492,src=1.2.3.4"
ipv6.dns-search: "wallaceandgromit.com;"
ipv6.ip6-privacy: "1"
proxy._: ""
'''.format(UUID, UUID)})

Expand Down Expand Up @@ -1202,3 +1210,35 @@ def test_keyfile_tunnel_regression_lp1952967(self):
ipv6.method: "auto"
proxy._: ""
'''.format(UUID, UUID)})

def test_keyfile_ip6_privacy_default_netplan_0104_compat(self):
self.generate_from_keyfile('''[connection]
id=Test
uuid={}
type=ethernet
[ethernet]
mac-address=99:88:77:66:55:44
[ipv4]
method=auto
[ipv6]
method=auto
'''.format(UUID))
self.assert_netplan({UUID: '''network:
version: 2
ethernets:
NM-{}:
renderer: NetworkManager
match:
macaddress: "99:88:77:66:55:44"
dhcp4: true
dhcp6: true
wakeonlan: true
networkmanager:
uuid: "{}"
name: "Test"
passthrough:
ipv6.ip6-privacy: "-1"
'''.format(UUID, UUID)})

0 comments on commit 3e522b7

Please sign in to comment.