From c2ceacb4190e5bfa181d0b807a7678a0967dd007 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Wed, 9 Nov 2016 13:06:11 +0100 Subject: [PATCH 01/29] device: make some asserts less harsh We're terrible programmers, but we don't need anyone to notice! --- src/devices/nm-device.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 7b41ee911b..f825b084f7 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -9069,10 +9069,10 @@ nm_device_start_ip_check (NMDevice *self) * first IP method completes. Any subsequently completing IP method doesn't * get checked. */ - g_assert (!priv->gw_ping.watch); - g_assert (!priv->gw_ping.timeout); - g_assert (!priv->gw_ping.pid); - g_assert (priv->ip4_state == IP_DONE || priv->ip6_state == IP_DONE); + g_return_if_fail (!priv->gw_ping.watch); + g_return_if_fail (!priv->gw_ping.timeout); + g_return_if_fail (!priv->gw_ping.pid); + g_return_if_fail (priv->ip4_state == IP_DONE || priv->ip6_state == IP_DONE); connection = nm_device_get_applied_connection (self); g_assert (connection); From 888d8f4b102b4ba7216d2700dd468a40f4c07c1c Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Wed, 9 Nov 2016 13:01:51 +0100 Subject: [PATCH 02/29] ifcfg-rh: add parentheses The code is now perfect. --- src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c index 142c2251a5..bead1cfb42 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c @@ -1480,8 +1480,8 @@ make_ip6_setting (shvarFile *ifcfg, if (tmp) { ip6_privacy = svGetValueBoolean (ifcfg, "IPV6_PRIVACY", FALSE); if (!ip6_privacy) - ip6_privacy = g_strcmp0 (tmp, "rfc4941") == 0 || - g_strcmp0 (tmp, "rfc3041") == 0; + ip6_privacy = (g_strcmp0 (tmp, "rfc4941") == 0) || + (g_strcmp0 (tmp, "rfc3041") == 0); } ip6_privacy_prefer_public_ip = svGetValueBoolean (ifcfg, "IPV6_PRIVACY_PREFER_PUBLIC_IP", FALSE); ip6_privacy_val = tmp ? From f708184d6f24cfd807b5b20d749d8f701bbe74c0 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Sat, 5 Nov 2016 18:31:13 +0100 Subject: [PATCH 03/29] device: don't fail the device if IPv4 forwarding fails Just fail the IPv4 method. Plus improve some comments. --- src/devices/nm-device.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index f825b084f7..afc28d4085 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -7161,14 +7161,14 @@ share_init (void) if (!nm_platform_sysctl_set (NM_PLATFORM_GET, "/proc/sys/net/ipv4/ip_forward", "1")) { errsv = errno; - nm_log_err (LOGD_SHARING, "share: error starting IP forwarding: (%d) %s", + nm_log_err (LOGD_SHARING, "share: error enabling IPv4 forwarding: (%d) %s", errsv, strerror (errsv)); return FALSE; } if (!nm_platform_sysctl_set (NM_PLATFORM_GET, "/proc/sys/net/ipv4/ip_dynaddr", "1")) { errsv = errno; - nm_log_err (LOGD_SHARING, "share: error starting IP forwarding: (%d) %s", + nm_log_err (LOGD_SHARING, "share: error enabling dynamic addresses: (%d) %s", errsv, strerror (errsv)); } @@ -7340,7 +7340,7 @@ activate_stage5_ip4_config_commit (NMDevice *self) if (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_SHARED) == 0) { if (!start_sharing (self, priv->ip4_config)) { _LOGW (LOGD_SHARING, "Activation: Stage 5 of 5 (IPv4 Commit) start sharing failed."); - nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SHARED_START_FAILED); + nm_device_ip_method_failed (self, AF_INET, NM_DEVICE_STATE_REASON_SHARED_START_FAILED); return; } } From ccb789edc2079d7486c5cbc9989a2483bc7c16bf Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Sat, 5 Nov 2016 18:37:53 +0100 Subject: [PATCH 04/29] device: ipv6.method=link-local does not need slaves It already waits for carrier, which is sufficient -- DAD won't start until there's carrier. --- src/devices/nm-device.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index afc28d4085..e67948cb2a 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -6666,12 +6666,10 @@ ip6_requires_slaves (NMConnection *connection) method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); /* SLAAC, DHCP, and Link-Local depend on connectivity (and thus slaves) - * to complete addressing. SLAAC and DHCP obviously need a peer to - * provide a prefix, while Link-Local must perform DAD on the local link. + * to complete addressing. SLAAC and DHCP need a peer to provide a prefix. */ return strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0 - || strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_DHCP) == 0 - || strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0; + || strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_DHCP) == 0; } static NMActStageReturn From 2dd384c817f320e0fcc925c90df86e1239cdd4a1 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Tue, 1 Nov 2016 19:25:40 +0100 Subject: [PATCH 05/29] utils: allow valid_lft=0 addresses We use the lifetime of 0 to indicate permanent addresses while DHCP uses that lifetime to indicate the addresses should be removed. Use the presence of a timestamp to differentiate the two. dhclient[10867]: XMT: Rebind on wls1, interval 1030ms. dhclient[10867]: RCV: Reply message on wls1 from fe80::21e:8cff:feec:3ca2. NetworkManager[10481]: [1478020967.7634] dhcp6 (wls1): valid_lft 0 NetworkManager[10481]: [1478020967.7634] dhcp6 (wls1): preferred_lft 0 NetworkManager[10481]: [1478020967.7636] dhcp6 (wls1): address fd25:d463:2f14::927 NetworkManager[10481]: [1478020967.7636] dhcp6 (wls1): nameserver 'fe80::21e:8cff:feec:3ca2' NetworkManager[10481]: [1478020967.7637] dhcp (wls1): domain search 'venom.' NetworkManager[10481]: [1478020967.7637] dhcp6 (wls1): state changed unknown -> bound, event ID="fa:cd:2c:86|1478020967" NetworkManager[10481]: ((src/nm-core-utils.c:3521)): assertion '' failed --- src/nm-core-utils.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/nm-core-utils.c b/src/nm-core-utils.c index c48bf6cd45..d4d9be5bc8 100644 --- a/src/nm-core-utils.c +++ b/src/nm-core-utils.c @@ -3511,14 +3511,15 @@ nm_utils_lifetime_get (guint32 timestamp, nm_assert (now >= 0); - if (lifetime == 0) { + if (timestamp == 0 && lifetime == 0) { + /* We treat lifetime==0 && timestamp == 0 addresses as permanent addresses to allow easy + * creation of such addresses (without requiring to set the lifetime fields to + * NM_PLATFORM_LIFETIME_PERMANENT). The real lifetime==0 addresses (E.g. DHCP6 telling us + * to drop an address will have timestamp set. + */ *out_lifetime = NM_PLATFORM_LIFETIME_PERMANENT; *out_preferred = NM_PLATFORM_LIFETIME_PERMANENT; - - /* We treat lifetime==0 as permanent addresses to allow easy creation of such addresses - * (without requiring to set the lifetime fields to NM_PLATFORM_LIFETIME_PERMANENT). - * In that case we also expect that the other fields (timestamp and preferred) are left unset. */ - g_return_val_if_fail (timestamp == 0 && preferred == 0, TRUE); + g_return_val_if_fail (preferred == 0, TRUE); } else { if (now <= 0) now = nm_utils_get_monotonic_timestamp_s (); From 7279ea1317767353d5d32e387e6b5f741cfe1f0b Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Wed, 12 Oct 2016 12:30:41 +0000 Subject: [PATCH 06/29] client: don't do g_criticals Also, be a bit more careful about the layers of errors. Just don't do this: (process:236): nmcli-CRITICAL **: Error: Could not create NMClient object: Permissions request failed: Authorization check failed: The name org.freedesktop.PolicyKit1 was not provided by any .service files. --- clients/cli/nmcli.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clients/cli/nmcli.c b/clients/cli/nmcli.c index 890dc0d062..6e27c3d668 100644 --- a/clients/cli/nmcli.c +++ b/clients/cli/nmcli.c @@ -520,7 +520,7 @@ nmc_get_client (NmCli *nmc) if (!nmc->client) { nmc->client = nm_client_new (NULL, &error); if (!nmc->client) { - g_critical (_("Error: Could not create NMClient object: %s."), error->message); + g_printerr ("%s\n", error->message); g_clear_error (&error); exit (NMC_RESULT_ERROR_UNKNOWN); } From b49c194f844e4c2cc0efcb3e59143939ed2fe5f4 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Fri, 28 Oct 2016 18:15:45 +0000 Subject: [PATCH 07/29] linux: don't assume short write when the kernel ignores the trailing whitespace Certain sysctls don't appreciate the final newline. That's completely fine. 17941 open("/proc/sys/net/ipv6/conf/eth2/forwarding", O_WRONLY|O_TRUNC) = 21 17941 write(21, "1\n", 2) = 1 --- src/platform/nm-linux-platform.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index bd69298fe8..c180f3c841 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -2579,7 +2579,7 @@ sysctl_set (NMPlatform *platform, const char *path, const char *value) /* Try to write the entire value three times if a partial write occurs */ errsv = 0; - for (tries = 0, nwrote = 0; tries < 3 && nwrote != len; tries++) { + for (tries = 0, nwrote = 0; tries < 3 && nwrote < len - 1; tries++) { nwrote = write (fd, actual, len); if (nwrote == -1) { errsv = errno; @@ -2593,12 +2593,12 @@ sysctl_set (NMPlatform *platform, const char *path, const char *value) if (nwrote == -1 && errsv != EEXIST) { _LOGE ("sysctl: failed to set '%s' to '%s': (%d) %s", path, value, errsv, strerror (errsv)); - } else if (nwrote < len) { + } else if (nwrote < len - 1) { _LOGE ("sysctl: failed to set '%s' to '%s' after three attempts", path, value); } - if (nwrote != len) { + if (nwrote < len - 1) { if (close (fd) != 0) { if (errsv != 0) errno = errsv; From 577ba42e18ba99db72ce3b9f0a52342e481647cc Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Thu, 13 Oct 2016 13:24:36 +0000 Subject: [PATCH 08/29] ifcfg-rh: get rid of an extra unused variable This saves a couple of bits we could instead use to save memories of the better days. --- .../plugins/ifcfg-rh/nms-ifcfg-rh-reader.c | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c index bead1cfb42..aef24dc555 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c @@ -1392,7 +1392,6 @@ make_ip6_setting (shvarFile *ifcfg, gboolean ip6_privacy = FALSE, ip6_privacy_prefer_public_ip; NMSettingIP6ConfigPrivacy ip6_privacy_val; NMSettingIP6ConfigAddrGenMode addr_gen_mode; - char *tmp; s_ip6 = (NMSettingIPConfig *) nm_setting_ip6_config_new (); @@ -1476,20 +1475,20 @@ make_ip6_setting (shvarFile *ifcfg, /* TODO - handle other methods */ /* Read IPv6 Privacy Extensions configuration */ - tmp = svGetValueString (ifcfg, "IPV6_PRIVACY"); - if (tmp) { + str_value = svGetValueString (ifcfg, "IPV6_PRIVACY"); + if (str_value) { ip6_privacy = svGetValueBoolean (ifcfg, "IPV6_PRIVACY", FALSE); if (!ip6_privacy) - ip6_privacy = (g_strcmp0 (tmp, "rfc4941") == 0) || - (g_strcmp0 (tmp, "rfc3041") == 0); + ip6_privacy = (g_strcmp0 (str_value, "rfc4941") == 0) || + (g_strcmp0 (str_value, "rfc3041") == 0); } ip6_privacy_prefer_public_ip = svGetValueBoolean (ifcfg, "IPV6_PRIVACY_PREFER_PUBLIC_IP", FALSE); - ip6_privacy_val = tmp ? + ip6_privacy_val = str_value ? (ip6_privacy ? (ip6_privacy_prefer_public_ip ? NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR : NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR) : NM_SETTING_IP6_CONFIG_PRIVACY_DISABLED) : NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN; - g_free (tmp); + g_free (str_value); g_object_set (s_ip6, NM_SETTING_IP_CONFIG_METHOD, method, @@ -1574,14 +1573,14 @@ make_ip6_setting (shvarFile *ifcfg, } /* IPv6 addressing mode configuration */ - tmp = svGetValueString (ifcfg, "IPV6_ADDR_GEN_MODE"); - if (tmp) { - if (nm_utils_enum_from_str (nm_setting_ip6_config_addr_gen_mode_get_type (), tmp, + str_value = svGetValueString (ifcfg, "IPV6_ADDR_GEN_MODE"); + if (str_value) { + if (nm_utils_enum_from_str (nm_setting_ip6_config_addr_gen_mode_get_type (), str_value, (int *) &addr_gen_mode, NULL)) g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE, addr_gen_mode, NULL); else PARSE_WARNING ("Invalid IPV6_ADDR_GEN_MODE"); - g_free (tmp); + g_free (str_value); } else { g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE, @@ -1590,10 +1589,10 @@ make_ip6_setting (shvarFile *ifcfg, } /* IPv6 tokenized interface identifier */ - tmp = svGetValueString (ifcfg, "IPV6_TOKEN"); - if (tmp) { - g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_TOKEN, tmp, NULL); - g_free (tmp); + str_value = svGetValueString (ifcfg, "IPV6_TOKEN"); + if (str_value) { + g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_TOKEN, str_value, NULL); + g_free (str_value); } /* DNS servers From 2e8f40f2c97f0d87bb8feaaf42863c4f933b6ab7 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Thu, 13 Oct 2016 13:24:36 +0000 Subject: [PATCH 09/29] ifcfg-rh: avoid parsing the IPV6_PRIVACY string twice This saves a couple of CPU cycles that would be better used for something more useful, such as looking for transmissions from aliens. --- src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c index aef24dc555..c77a360477 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c @@ -1477,7 +1477,7 @@ make_ip6_setting (shvarFile *ifcfg, /* Read IPv6 Privacy Extensions configuration */ str_value = svGetValueString (ifcfg, "IPV6_PRIVACY"); if (str_value) { - ip6_privacy = svGetValueBoolean (ifcfg, "IPV6_PRIVACY", FALSE); + ip6_privacy = svParseBoolean (str_value, FALSE); if (!ip6_privacy) ip6_privacy = (g_strcmp0 (str_value, "rfc4941") == 0) || (g_strcmp0 (str_value, "rfc3041") == 0); From aa71dbc6c42d2c4ffaf921a8e5dd9c1175f20372 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Fri, 14 Oct 2016 19:57:34 +0200 Subject: [PATCH 10/29] device: avoid a crash when L3 configuration fails Don't call the IP check until at either IPv4 or IPv6 is actually configured. --- src/devices/nm-device.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index e67948cb2a..50c065f6b4 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -6984,12 +6984,16 @@ fw_change_zone_cb_ip_check (NMFirewallManager *firewall_manager, gpointer user_data) { NMDevice *self = user_data; + NMDevicePrivate *priv; if (!fw_change_zone_handle (self, call_id, error)) return; /* FIXME: fail the device on error? */ - nm_device_start_ip_check (self); + + priv = NM_DEVICE_GET_PRIVATE (self); + if (priv->ip4_state == IP_DONE || priv->ip6_state == IP_DONE) + nm_device_start_ip_check (self); } /* From 44fca246a7cb4df7bc84f3cdad07e5eb81246741 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Thu, 13 Oct 2016 11:06:25 +0000 Subject: [PATCH 11/29] rdisc: rename to ndisc We'll soon not only do the router discovery, but announce ourselves as a reouter. "Neighbor discovery" sounds to be a more appropriate name for the class than "Router discovery". --- .gitignore | 5 +- Makefile.am | 38 +- src/devices/nm-device.c | 132 +++--- .../nm-fake-rdisc.c => ndisc/nm-fake-ndisc.c} | 170 ++++---- .../nm-fake-rdisc.h => ndisc/nm-fake-ndisc.h} | 52 +-- .../nm-lndp-rdisc.c => ndisc/nm-lndp-ndisc.c} | 176 ++++---- .../nm-lndp-rdisc.h => ndisc/nm-lndp-ndisc.h} | 30 +- .../nm-ndisc-private.h} | 36 +- src/{rdisc/nm-rdisc.c => ndisc/nm-ndisc.c} | 388 +++++++++--------- src/ndisc/nm-ndisc.h | 170 ++++++++ src/ndisc/tests/.gitignore | 1 + .../tests/test-ndisc-fake.c} | 260 ++++++------ .../tests/test-ndisc-linux.c} | 20 +- src/nm-iface-helper.c | 88 ++-- src/nm-types.h | 2 +- src/platform/nm-platform-utils.c | 6 +- src/rdisc/nm-rdisc.h | 170 -------- src/rdisc/tests/.gitignore | 1 - src/tests/test-general.c | 2 +- src/tests/test-ip6-config.c | 4 +- 20 files changed, 876 insertions(+), 875 deletions(-) rename src/{rdisc/nm-fake-rdisc.c => ndisc/nm-fake-ndisc.c} (65%) rename src/{rdisc/nm-fake-rdisc.h => ndisc/nm-fake-ndisc.h} (55%) rename src/{rdisc/nm-lndp-rdisc.c => ndisc/nm-lndp-ndisc.c} (72%) rename src/{rdisc/nm-lndp-rdisc.h => ndisc/nm-lndp-ndisc.h} (54%) rename src/{rdisc/nm-rdisc-private.h => ndisc/nm-ndisc-private.h} (68%) rename src/{rdisc/nm-rdisc.c => ndisc/nm-ndisc.c} (70%) create mode 100644 src/ndisc/nm-ndisc.h create mode 100644 src/ndisc/tests/.gitignore rename src/{rdisc/tests/test-rdisc-fake.c => ndisc/tests/test-ndisc-fake.c} (60%) rename src/{rdisc/tests/test-rdisc-linux.c => ndisc/tests/test-ndisc-linux.c} (86%) delete mode 100644 src/rdisc/nm-rdisc.h delete mode 100644 src/rdisc/tests/.gitignore diff --git a/.gitignore b/.gitignore index d2632d4d09..21de7800fa 100644 --- a/.gitignore +++ b/.gitignore @@ -247,8 +247,8 @@ test-*.trs /src/dhcp-manager/tests/test-dhcp-utils /src/dnsmasq-manager/tests/test-dnsmasq-utils /src/nm-iface-helper -/src/rdisc/tests/test-rdisc-fake -/src/rdisc/tests/test-rdisc-linux +/src/ndisc/tests/test-ndisc-fake +/src/ndisc/tests/test-ndisc-linux /src/settings/plugins/ibft/tests/test-ibft /src/settings/plugins/ifcfg-rh/nmdbus-ifcfg-rh.[ch] /src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh @@ -289,3 +289,4 @@ test-*.trs /src/devices/wifi/tests/test-wifi-ap-utils /src/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh-utils /src/settings/plugins/ifnet/tests/check_ifnet +/src/rdisc/ diff --git a/Makefile.am b/Makefile.am index 643a7ff118..80729373cc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -900,7 +900,7 @@ src_cppflags = \ -I$(top_srcdir)/src/platform \ -I$(top_srcdir)/src/platform/wifi \ -I$(top_srcdir)/src/ppp-manager \ - -I$(top_srcdir)/src/rdisc \ + -I$(top_srcdir)/src/ndisc \ -I$(top_srcdir)/src/settings \ -I$(top_srcdir)/src/supplicant-manager \ -I$(top_srcdir)/src/vpn-manager \ @@ -1142,11 +1142,11 @@ src_libNetworkManagerBase_la_SOURCES = \ src/platform/wifi/wifi-utils.c \ src/platform/wifi/wifi-utils.h \ \ - src/rdisc/nm-lndp-rdisc.c \ - src/rdisc/nm-lndp-rdisc.h \ - src/rdisc/nm-rdisc.c \ - src/rdisc/nm-rdisc.h \ - src/rdisc/nm-rdisc-private.h \ + src/ndisc/nm-lndp-ndisc.c \ + src/ndisc/nm-lndp-ndisc.h \ + src/ndisc/nm-ndisc.c \ + src/ndisc/nm-ndisc.h \ + src/ndisc/nm-ndisc-private.h \ \ src/nm-exported-object.c \ src/nm-exported-object.h \ @@ -1381,8 +1381,8 @@ src_tests_cppflags_linux = $(src_tests_cppflags) -DSETUP=nm_linux_platform_setup src_libNetworkManagerTest_la_CPPFLAGS = $(src_tests_cppflags) src_libNetworkManagerTest_la_SOURCES = \ - src/rdisc/nm-fake-rdisc.c \ - src/rdisc/nm-fake-rdisc.h \ + src/ndisc/nm-fake-ndisc.c \ + src/ndisc/nm-fake-ndisc.h \ src/platform/nm-fake-platform.c \ src/platform/nm-fake-platform.h \ src/platform/tests/test-common.c \ @@ -2613,26 +2613,26 @@ src_devices_tests_test_arping_LDADD = \ src/libNetworkManagerTest.la ############################################################################### -# src/rdisc/tests +# src/ndisc/tests ############################################################################### -src_rdisc_tests_ldflags = \ +src_ndisc_tests_ldflags = \ $(CODE_COVERAGE_LDFLAGS) -src_rdisc_tests_ldadd = \ +src_ndisc_tests_ldadd = \ src/libNetworkManagerTest.la \ $(GLIB_LIBS) -check_programs += src/rdisc/tests/test-rdisc-fake -check_programs_norun += src/rdisc/tests/test-rdisc-linux +check_programs += src/ndisc/tests/test-ndisc-fake +check_programs_norun += src/ndisc/tests/test-ndisc-linux -src_rdisc_tests_test_rdisc_linux_CPPFLAGS = $(src_tests_cppflags) -src_rdisc_tests_test_rdisc_linux_LDFLAGS = $(src_rdisc_tests_flags) -src_rdisc_tests_test_rdisc_linux_LDADD = $(src_rdisc_tests_ldadd) +src_ndisc_tests_test_ndisc_linux_CPPFLAGS = $(src_tests_cppflags) +src_ndisc_tests_test_ndisc_linux_LDFLAGS = $(src_ndisc_tests_flags) +src_ndisc_tests_test_ndisc_linux_LDADD = $(src_ndisc_tests_ldadd) -src_rdisc_tests_test_rdisc_fake_CPPFLAGS = $(src_tests_cppflags) -src_rdisc_tests_test_rdisc_fake_LDFLAGS = $(src_rdisc_tests_flags) -src_rdisc_tests_test_rdisc_fake_LDADD = $(src_rdisc_tests_ldadd) +src_ndisc_tests_test_ndisc_fake_CPPFLAGS = $(src_tests_cppflags) +src_ndisc_tests_test_ndisc_fake_LDFLAGS = $(src_ndisc_tests_flags) +src_ndisc_tests_test_ndisc_fake_LDADD = $(src_ndisc_tests_ldadd) ############################################################################### # src/supplicant-manager/tests diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 50c065f6b4..9dfb436452 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -40,8 +40,8 @@ #include "NetworkManagerUtils.h" #include "nm-manager.h" #include "nm-platform.h" -#include "nm-rdisc.h" -#include "nm-lndp-rdisc.h" +#include "nm-ndisc.h" +#include "nm-lndp-ndisc.h" #include "nm-dhcp-manager.h" #include "nm-act-request.h" #include "nm-proxy-config.h" @@ -373,10 +373,10 @@ typedef struct _NMDevicePrivate { guint32 ip6_mtu; NMIP6Config * dad6_ip6_config; - NMRDisc * rdisc; - gulong rdisc_changed_id; - gulong rdisc_timeout_id; - NMSettingIP6ConfigPrivacy rdisc_use_tempaddr; + NMNDisc * ndisc; + gulong ndisc_changed_id; + gulong ndisc_timeout_id; + NMSettingIP6ConfigPrivacy ndisc_use_tempaddr; /* IP6 config from autoconf */ NMIP6Config * ac_ip6_config; @@ -387,7 +387,7 @@ typedef struct _NMDevicePrivate { struct { NMDhcpClient * client; - NMRDiscDHCPLevel mode; + NMNDiscDHCPLevel mode; gulong state_sigid; NMDhcp6Config * config; /* IP6 config from DHCP */ @@ -1626,7 +1626,7 @@ nm_device_update_dynamic_ip_setup (NMDevice *self) return; } } - if (priv->rdisc) { + if (priv->ndisc) { /* FIXME: todo */ } if (priv->dnsmasq_manager) { @@ -1896,10 +1896,10 @@ device_link_changed (NMDevice *self) nm_device_emit_recheck_auto_activate (self); } - if (priv->rdisc && info.inet6_token.id) { - if (nm_rdisc_set_iid (priv->rdisc, info.inet6_token)) { + if (priv->ndisc && info.inet6_token.id) { + if (nm_ndisc_set_iid (priv->ndisc, info.inet6_token)) { _LOGD (LOGD_DEVICE, "IPv6 tokenized identifier present on device %s", priv->iface); - nm_rdisc_start (priv->rdisc); + nm_ndisc_start (priv->ndisc); } } @@ -5428,7 +5428,7 @@ dhcp6_cleanup (NMDevice *self, CleanupType cleanup_type, gboolean release) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - priv->dhcp6.mode = NM_RDISC_DHCP_LEVEL_NONE; + priv->dhcp6.mode = NM_NDISC_DHCP_LEVEL_NONE; g_clear_object (&priv->dhcp6.ip6_config); g_clear_pointer (&priv->dhcp6.event_id, g_free); nm_clear_g_source (&priv->dhcp6.restart_id); @@ -5635,7 +5635,7 @@ END_ADD_DEFAULT_ROUTE: } nm_ip6_config_addresses_sort (composite, - priv->rdisc ? priv->rdisc_use_tempaddr : NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN); + priv->ndisc ? priv->ndisc_use_tempaddr : NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN); /* Allow setting MTU etc */ if (commit) { @@ -5755,7 +5755,7 @@ dhcp6_fail (NMDevice *self, gboolean timeout) dhcp6_cleanup (self, CLEANUP_TYPE_DECONFIGURE, FALSE); - if (priv->dhcp6.mode == NM_RDISC_DHCP_LEVEL_MANAGED) { + if (priv->dhcp6.mode == NM_NDISC_DHCP_LEVEL_MANAGED) { /* Don't fail if there are static addresses configured on * the device, instead retry after some time. */ @@ -5801,7 +5801,7 @@ dhcp6_timeout (NMDevice *self, NMDhcpClient *client) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - if (priv->dhcp6.mode == NM_RDISC_DHCP_LEVEL_MANAGED) + if (priv->dhcp6.mode == NM_NDISC_DHCP_LEVEL_MANAGED) dhcp6_fail (self, TRUE); else { /* not a hard failure; just live with the RA info */ @@ -5878,7 +5878,7 @@ dhcp6_state_changed (NMDhcpClient *client, * may exit right after getting a response from the server. That's * normal. In that case we just ignore the exit. */ - if (priv->dhcp6.mode == NM_RDISC_DHCP_LEVEL_OTHERCONF) + if (priv->dhcp6.mode == NM_NDISC_DHCP_LEVEL_OTHERCONF) break; /* Otherwise, fall through */ case NM_DHCP_STATE_FAIL: @@ -5925,7 +5925,7 @@ dhcp6_start_with_link_ready (NMDevice *self, NMConnection *connection) nm_setting_ip_config_get_dhcp_hostname (s_ip6), priv->dhcp_timeout, priv->dhcp_anycast_address, - (priv->dhcp6.mode == NM_RDISC_DHCP_LEVEL_OTHERCONF) ? TRUE : FALSE, + (priv->dhcp6.mode == NM_NDISC_DHCP_LEVEL_OTHERCONF) ? TRUE : FALSE, nm_setting_ip6_config_get_ip6_privacy (NM_SETTING_IP6_CONFIG (s_ip6))); if (tmp) g_byte_array_free (tmp, TRUE); @@ -6234,9 +6234,9 @@ nm_device_ipv6_set_mtu (NMDevice *self, guint32 mtu) } static void -rdisc_config_changed (NMRDisc *rdisc, const NMRDiscData *rdata, guint changed_int, NMDevice *self) +ndisc_config_changed (NMNDisc *ndisc, const NMNDiscData *rdata, guint changed_int, NMDevice *self) { - NMRDiscConfigMap changed = changed_int; + NMNDiscConfigMap changed = changed_int; NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); int i; int system_support; @@ -6252,8 +6252,8 @@ rdisc_config_changed (NMRDisc *rdisc, const NMRDiscData *rdata, guint changed_in if (system_support) ifa_flags = IFA_F_NOPREFIXROUTE; - if ( priv->rdisc_use_tempaddr == NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR - || priv->rdisc_use_tempaddr == NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR) + if ( priv->ndisc_use_tempaddr == NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR + || priv->ndisc_use_tempaddr == NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR) { /* without system_support, this flag will be ignored. Still set it, doesn't seem to do any harm. */ ifa_flags |= IFA_F_MANAGETEMPADDR; @@ -6264,25 +6264,25 @@ rdisc_config_changed (NMRDisc *rdisc, const NMRDiscData *rdata, guint changed_in if (!priv->ac_ip6_config) priv->ac_ip6_config = nm_ip6_config_new (nm_device_get_ip_ifindex (self)); - if (changed & NM_RDISC_CONFIG_GATEWAYS) { - /* Use the first gateway as ordered in router discovery cache. */ + if (changed & NM_NDISC_CONFIG_GATEWAYS) { + /* Use the first gateway as ordered in neighbor discovery cache. */ if (rdata->gateways_n) nm_ip6_config_set_gateway (priv->ac_ip6_config, &rdata->gateways[0].address); else nm_ip6_config_set_gateway (priv->ac_ip6_config, NULL); } - if (changed & NM_RDISC_CONFIG_ADDRESSES) { - /* Rebuild address list from router discovery cache. */ + if (changed & NM_NDISC_CONFIG_ADDRESSES) { + /* Rebuild address list from neighbor discovery cache. */ nm_ip6_config_reset_addresses (priv->ac_ip6_config); - /* rdisc->addresses contains at most max_addresses entries. + /* ndisc->addresses contains at most max_addresses entries. * This is different from what the kernel does, which * also counts static and temporary addresses when checking * max_addresses. **/ for (i = 0; i < rdata->addresses_n; i++) { - const NMRDiscAddress *discovered_address = &rdata->addresses[i]; + const NMNDiscAddress *discovered_address = &rdata->addresses[i]; NMPlatformIP6Address address; memset (&address, 0, sizeof (address)); @@ -6293,24 +6293,24 @@ rdisc_config_changed (NMRDisc *rdisc, const NMRDiscData *rdata, guint changed_in address.preferred = discovered_address->preferred; if (address.preferred > address.lifetime) address.preferred = address.lifetime; - address.addr_source = NM_IP_CONFIG_SOURCE_RDISC; + address.addr_source = NM_IP_CONFIG_SOURCE_NDISC; address.n_ifa_flags = ifa_flags; nm_ip6_config_add_address (priv->ac_ip6_config, &address); } } - if (changed & NM_RDISC_CONFIG_ROUTES) { - /* Rebuild route list from router discovery cache. */ + if (changed & NM_NDISC_CONFIG_ROUTES) { + /* Rebuild route list from neighbor discovery cache. */ nm_ip6_config_reset_routes (priv->ac_ip6_config); for (i = 0; i < rdata->routes_n; i++) { - const NMRDiscRoute *discovered_route = &rdata->routes[i]; + const NMNDiscRoute *discovered_route = &rdata->routes[i]; const NMPlatformIP6Route route = { .network = discovered_route->network, .plen = discovered_route->plen, .gateway = discovered_route->gateway, - .rt_source = NM_IP_CONFIG_SOURCE_RDISC, + .rt_source = NM_IP_CONFIG_SOURCE_NDISC, .metric = nm_device_get_ip6_route_metric (self), }; @@ -6318,34 +6318,34 @@ rdisc_config_changed (NMRDisc *rdisc, const NMRDiscData *rdata, guint changed_in } } - if (changed & NM_RDISC_CONFIG_DNS_SERVERS) { - /* Rebuild DNS server list from router discovery cache. */ + if (changed & NM_NDISC_CONFIG_DNS_SERVERS) { + /* Rebuild DNS server list from neighbor discovery cache. */ nm_ip6_config_reset_nameservers (priv->ac_ip6_config); for (i = 0; i < rdata->dns_servers_n; i++) nm_ip6_config_add_nameserver (priv->ac_ip6_config, &rdata->dns_servers[i].address); } - if (changed & NM_RDISC_CONFIG_DNS_DOMAINS) { - /* Rebuild domain list from router discovery cache. */ + if (changed & NM_NDISC_CONFIG_DNS_DOMAINS) { + /* Rebuild domain list from neighbor discovery cache. */ nm_ip6_config_reset_domains (priv->ac_ip6_config); for (i = 0; i < rdata->dns_domains_n; i++) nm_ip6_config_add_domain (priv->ac_ip6_config, rdata->dns_domains[i].domain); } - if (changed & NM_RDISC_CONFIG_DHCP_LEVEL) { + if (changed & NM_NDISC_CONFIG_DHCP_LEVEL) { dhcp6_cleanup (self, CLEANUP_TYPE_DECONFIGURE, TRUE); priv->dhcp6.mode = rdata->dhcp_level; - if (priv->dhcp6.mode != NM_RDISC_DHCP_LEVEL_NONE) { + if (priv->dhcp6.mode != NM_NDISC_DHCP_LEVEL_NONE) { NMDeviceStateReason reason; _LOGD (LOGD_DEVICE | LOGD_DHCP6, "Activation: Stage 3 of 5 (IP Configure Start) starting DHCPv6" " as requested by IPv6 router..."); if (!dhcp6_start (self, FALSE, &reason)) { - if (priv->dhcp6.mode == NM_RDISC_DHCP_LEVEL_MANAGED) { + if (priv->dhcp6.mode == NM_NDISC_DHCP_LEVEL_MANAGED) { nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason); return; } @@ -6353,17 +6353,17 @@ rdisc_config_changed (NMRDisc *rdisc, const NMRDiscData *rdata, guint changed_in } } - if (changed & NM_RDISC_CONFIG_HOP_LIMIT) + if (changed & NM_NDISC_CONFIG_HOP_LIMIT) nm_platform_sysctl_set_ip6_hop_limit_safe (NM_PLATFORM_GET, nm_device_get_ip_iface (self), rdata->hop_limit); - if (changed & NM_RDISC_CONFIG_MTU) + if (changed & NM_NDISC_CONFIG_MTU) priv->ip6_mtu = rdata->mtu; nm_device_activate_schedule_ip6_config_result (self); } static void -rdisc_ra_timeout (NMRDisc *rdisc, NMDevice *self) +ndisc_ra_timeout (NMNDisc *ndisc, NMDevice *self) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); @@ -6393,13 +6393,13 @@ addrconf6_start_with_link_ready (NMDevice *self) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMUtilsIPv6IfaceId iid; - g_assert (priv->rdisc); + g_assert (priv->ndisc); if (nm_device_get_ip_iface_identifier (self, &iid, FALSE)) { _LOGD (LOGD_IP6, "addrconf6: using the device EUI-64 identifier"); - nm_rdisc_set_iid (priv->rdisc, iid); + nm_ndisc_set_iid (priv->ndisc, iid); } else { - /* Don't abort the addrconf at this point -- if rdisc needs the iid + /* Don't abort the addrconf at this point -- if ndisc needs the iid * it will notice this itself. */ _LOGI (LOGD_IP6, "addrconf6: no interface identifier; IPv6 adddress creation may fail"); } @@ -6413,16 +6413,16 @@ addrconf6_start_with_link_ready (NMDevice *self) nm_device_ipv6_sysctl_set (self, "accept_ra_pinfo", "0"); nm_device_ipv6_sysctl_set (self, "accept_ra_rtr_pref", "0"); - priv->rdisc_changed_id = g_signal_connect (priv->rdisc, - NM_RDISC_CONFIG_CHANGED, - G_CALLBACK (rdisc_config_changed), + priv->ndisc_changed_id = g_signal_connect (priv->ndisc, + NM_NDISC_CONFIG_CHANGED, + G_CALLBACK (ndisc_config_changed), self); - priv->rdisc_timeout_id = g_signal_connect (priv->rdisc, - NM_RDISC_RA_TIMEOUT, - G_CALLBACK (rdisc_ra_timeout), + priv->ndisc_timeout_id = g_signal_connect (priv->ndisc, + NM_NDISC_RA_TIMEOUT, + G_CALLBACK (ndisc_ra_timeout), self); - nm_rdisc_start (priv->rdisc); + nm_ndisc_start (priv->ndisc); return TRUE; } @@ -6451,7 +6451,7 @@ addrconf6_start (NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr) stable_id = _get_stable_id (connection, &stable_type); if (stable_id) { - priv->rdisc = nm_lndp_rdisc_new (NM_PLATFORM_GET, + priv->ndisc = nm_lndp_ndisc_new (NM_PLATFORM_GET, nm_device_get_ip_ifindex (self), nm_device_get_ip_iface (self), stable_type, @@ -6459,13 +6459,13 @@ addrconf6_start (NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr) nm_setting_ip6_config_get_addr_gen_mode (s_ip6), &error); } - if (!priv->rdisc) { - _LOGE (LOGD_IP6, "addrconf6: failed to start router discovery: %s", error->message); + if (!priv->ndisc) { + _LOGE (LOGD_IP6, "addrconf6: failed to start neighbor discovery: %s", error->message); g_error_free (error); return FALSE; } - priv->rdisc_use_tempaddr = use_tempaddr; + priv->ndisc_use_tempaddr = use_tempaddr; if ( NM_IN_SET (use_tempaddr, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR, NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_PUBLIC_ADDR) && !nm_platform_check_support_kernel_extended_ifa_flags (NM_PLATFORM_GET)) { @@ -6483,7 +6483,7 @@ addrconf6_start (NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr) return TRUE; } - /* success; already have the LL address; kick off router discovery */ + /* success; already have the LL address; kick off neighbor discovery */ g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS); return addrconf6_start_with_link_ready (self); } @@ -6493,13 +6493,13 @@ addrconf6_cleanup (NMDevice *self) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - nm_clear_g_signal_handler (priv->rdisc, &priv->rdisc_changed_id); - nm_clear_g_signal_handler (priv->rdisc, &priv->rdisc_timeout_id); + nm_clear_g_signal_handler (priv->ndisc, &priv->ndisc_changed_id); + nm_clear_g_signal_handler (priv->ndisc, &priv->ndisc_timeout_id); nm_device_remove_pending_action (self, PENDING_ACTION_AUTOCONF6, FALSE); g_clear_object (&priv->ac_ip6_config); - g_clear_object (&priv->rdisc); + g_clear_object (&priv->ndisc); } /*****************************************************************************/ @@ -6714,7 +6714,7 @@ act_stage3_ip6_config_start (NMDevice *self, } } - priv->dhcp6.mode = NM_RDISC_DHCP_LEVEL_NONE; + priv->dhcp6.mode = NM_NDISC_DHCP_LEVEL_NONE; priv->dhcp6.num_tries_left = DHCP_NUM_TRIES_MAX; method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); @@ -6763,7 +6763,7 @@ act_stage3_ip6_config_start (NMDevice *self, } else if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) == 0) { ret = linklocal6_start (self); } else if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_DHCP) == 0) { - priv->dhcp6.mode = NM_RDISC_DHCP_LEVEL_MANAGED; + priv->dhcp6.mode = NM_NDISC_DHCP_LEVEL_MANAGED; if (!dhcp6_start (self, TRUE, reason)) { /* IPv6 might be disabled; allow IPv4 to proceed */ ret = NM_ACT_STAGE_RETURN_IP_FAIL; @@ -7482,7 +7482,7 @@ activate_stage5_ip6_config_commit (NMDevice *self) } if (ip6_config_merge_and_apply (self, TRUE, &reason)) { - if ( priv->dhcp6.mode != NM_RDISC_DHCP_LEVEL_NONE + if ( priv->dhcp6.mode != NM_NDISC_DHCP_LEVEL_NONE && priv->ip6_state == IP_CONF) { if (priv->dhcp6.ip6_config) { /* If IPv6 wasn't the first IP to complete, and DHCP was used, @@ -9635,8 +9635,8 @@ queued_ip6_config_change (gpointer user_data) if (IN6_IS_ADDR_LINKLOCAL (&addr->address)) need_ipv6ll = TRUE; - else if (priv->rdisc) - nm_rdisc_dad_failed (priv->rdisc, &addr->address); + else if (priv->ndisc) + nm_ndisc_dad_failed (priv->ndisc, &addr->address); } /* If no IPv6 link-local address exists but other addresses do then we @@ -11047,7 +11047,7 @@ nm_device_spawn_iface_helper (NMDevice *self) g_ptr_array_add (argv, g_strdup ("--slaac-required")); g_ptr_array_add (argv, g_strdup ("--slaac-tempaddr")); - g_ptr_array_add (argv, g_strdup_printf ("%d", priv->rdisc_use_tempaddr)); + g_ptr_array_add (argv, g_strdup_printf ("%d", priv->ndisc_use_tempaddr)); if (nm_device_get_ip_iface_identifier (self, &iid, FALSE)) { g_ptr_array_add (argv, g_strdup ("--iid")); diff --git a/src/rdisc/nm-fake-rdisc.c b/src/ndisc/nm-fake-ndisc.c similarity index 65% rename from src/rdisc/nm-fake-rdisc.c rename to src/ndisc/nm-fake-ndisc.c index aee94a39be..3b2c4d4dd0 100644 --- a/src/rdisc/nm-fake-rdisc.c +++ b/src/ndisc/nm-fake-ndisc.c @@ -1,5 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* nm-fake-rdisc.c - Fake implementation of router discovery +/* nm-fake-ndisc.c - Fake implementation of neighbor discovery * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,14 +20,14 @@ #include "nm-default.h" -#include "nm-fake-rdisc.h" +#include "nm-fake-ndisc.h" #include #include -#include "nm-rdisc-private.h" +#include "nm-ndisc-private.h" -#define _NMLOG_PREFIX_NAME "rdisc-fake" +#define _NMLOG_PREFIX_NAME "ndisc-fake" /*****************************************************************************/ @@ -35,7 +35,7 @@ typedef struct { guint id; guint when; - NMRDiscDHCPLevel dhcp_level; + NMNDiscDHCPLevel dhcp_level; GArray *gateways; GArray *prefixes; GArray *dns_servers; @@ -51,7 +51,7 @@ typedef struct { guint32 timestamp; guint32 lifetime; guint32 preferred; - NMRDiscPreference preference; + NMNDiscPreference preference; } FakePrefix; /*****************************************************************************/ @@ -65,20 +65,20 @@ static guint signals[LAST_SIGNAL] = { 0 }; typedef struct { guint receive_ra_id; GSList *ras; -} NMFakeRDiscPrivate; +} NMFakeNDiscPrivate; -struct _NMFakeRRDisc { - NMRDisc parent; - NMFakeRDiscPrivate _priv; +struct _NMFakeRNDisc { + NMNDisc parent; + NMFakeNDiscPrivate _priv; }; -struct _NMFakeRRDiscClass { - NMRDiscClass parent; +struct _NMFakeRNDiscClass { + NMNDiscClass parent; }; -G_DEFINE_TYPE (NMFakeRDisc, nm_fake_rdisc, NM_TYPE_RDISC) +G_DEFINE_TYPE (NMFakeNDisc, nm_fake_ndisc, NM_TYPE_NDISC) -#define NM_FAKE_RDISC_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMFakeRDisc, NM_IS_FAKE_RDISC) +#define NM_FAKE_NDISC_GET_PRIVATE(self) _NM_GET_PRIVATE (self, NMFakeNDisc, NM_IS_FAKE_NDISC) /*****************************************************************************/ @@ -97,7 +97,7 @@ fake_ra_free (gpointer data) static void ra_dns_domain_free (gpointer data) { - g_free (((NMRDiscDNSDomain *)(data))->domain); + g_free (((NMNDiscDNSDomain *)(data))->domain); } static FakeRa * @@ -113,13 +113,13 @@ find_ra (GSList *ras, guint id) } guint -nm_fake_rdisc_add_ra (NMFakeRDisc *self, +nm_fake_ndisc_add_ra (NMFakeNDisc *self, guint seconds_after_previous, - NMRDiscDHCPLevel dhcp_level, + NMNDiscDHCPLevel dhcp_level, int hop_limit, guint32 mtu) { - NMFakeRDiscPrivate *priv = NM_FAKE_RDISC_GET_PRIVATE (self); + NMFakeNDiscPrivate *priv = NM_FAKE_NDISC_GET_PRIVATE (self); static guint counter = 1; FakeRa *ra; @@ -129,10 +129,10 @@ nm_fake_rdisc_add_ra (NMFakeRDisc *self, ra->dhcp_level = dhcp_level; ra->hop_limit = hop_limit; ra->mtu = mtu; - ra->gateways = g_array_new (FALSE, FALSE, sizeof (NMRDiscGateway)); + ra->gateways = g_array_new (FALSE, FALSE, sizeof (NMNDiscGateway)); ra->prefixes = g_array_new (FALSE, FALSE, sizeof (FakePrefix)); - ra->dns_servers = g_array_new (FALSE, FALSE, sizeof (NMRDiscDNSServer)); - ra->dns_domains = g_array_new (FALSE, FALSE, sizeof (NMRDiscDNSDomain)); + ra->dns_servers = g_array_new (FALSE, FALSE, sizeof (NMNDiscDNSServer)); + ra->dns_domains = g_array_new (FALSE, FALSE, sizeof (NMNDiscDNSDomain)); g_array_set_clear_func (ra->dns_domains, ra_dns_domain_free); priv->ras = g_slist_append (priv->ras, ra); @@ -140,20 +140,20 @@ nm_fake_rdisc_add_ra (NMFakeRDisc *self, } void -nm_fake_rdisc_add_gateway (NMFakeRDisc *self, +nm_fake_ndisc_add_gateway (NMFakeNDisc *self, guint ra_id, const char *addr, guint32 timestamp, guint32 lifetime, - NMRDiscPreference preference) + NMNDiscPreference preference) { - NMFakeRDiscPrivate *priv = NM_FAKE_RDISC_GET_PRIVATE (self); + NMFakeNDiscPrivate *priv = NM_FAKE_NDISC_GET_PRIVATE (self); FakeRa *ra = find_ra (priv->ras, ra_id); - NMRDiscGateway *gw; + NMNDiscGateway *gw; g_assert (ra); g_array_set_size (ra->gateways, ra->gateways->len + 1); - gw = &g_array_index (ra->gateways, NMRDiscGateway, ra->gateways->len - 1); + gw = &g_array_index (ra->gateways, NMNDiscGateway, ra->gateways->len - 1); g_assert (inet_pton (AF_INET6, addr, &gw->address) == 1); gw->timestamp = timestamp; gw->lifetime = lifetime; @@ -161,7 +161,7 @@ nm_fake_rdisc_add_gateway (NMFakeRDisc *self, } void -nm_fake_rdisc_add_prefix (NMFakeRDisc *self, +nm_fake_ndisc_add_prefix (NMFakeNDisc *self, guint ra_id, const char *network, guint plen, @@ -169,9 +169,9 @@ nm_fake_rdisc_add_prefix (NMFakeRDisc *self, guint32 timestamp, guint32 lifetime, guint32 preferred, - NMRDiscPreference preference) + NMNDiscPreference preference) { - NMFakeRDiscPrivate *priv = NM_FAKE_RDISC_GET_PRIVATE (self); + NMFakeNDiscPrivate *priv = NM_FAKE_NDISC_GET_PRIVATE (self); FakeRa *ra = find_ra (priv->ras, ra_id); FakePrefix *prefix; @@ -189,70 +189,70 @@ nm_fake_rdisc_add_prefix (NMFakeRDisc *self, } void -nm_fake_rdisc_add_dns_server (NMFakeRDisc *self, +nm_fake_ndisc_add_dns_server (NMFakeNDisc *self, guint ra_id, const char *address, guint32 timestamp, guint32 lifetime) { - NMFakeRDiscPrivate *priv = NM_FAKE_RDISC_GET_PRIVATE (self); + NMFakeNDiscPrivate *priv = NM_FAKE_NDISC_GET_PRIVATE (self); FakeRa *ra = find_ra (priv->ras, ra_id); - NMRDiscDNSServer *dns; + NMNDiscDNSServer *dns; g_assert (ra); g_array_set_size (ra->dns_servers, ra->dns_servers->len + 1); - dns = &g_array_index (ra->dns_servers, NMRDiscDNSServer, ra->dns_servers->len - 1); + dns = &g_array_index (ra->dns_servers, NMNDiscDNSServer, ra->dns_servers->len - 1); g_assert (inet_pton (AF_INET6, address, &dns->address) == 1); dns->timestamp = timestamp; dns->lifetime = lifetime; } void -nm_fake_rdisc_add_dns_domain (NMFakeRDisc *self, +nm_fake_ndisc_add_dns_domain (NMFakeNDisc *self, guint ra_id, const char *domain, guint32 timestamp, guint32 lifetime) { - NMFakeRDiscPrivate *priv = NM_FAKE_RDISC_GET_PRIVATE (self); + NMFakeNDiscPrivate *priv = NM_FAKE_NDISC_GET_PRIVATE (self); FakeRa *ra = find_ra (priv->ras, ra_id); - NMRDiscDNSDomain *dns; + NMNDiscDNSDomain *dns; g_assert (ra); g_array_set_size (ra->dns_domains, ra->dns_domains->len + 1); - dns = &g_array_index (ra->dns_domains, NMRDiscDNSDomain, ra->dns_domains->len - 1); + dns = &g_array_index (ra->dns_domains, NMNDiscDNSDomain, ra->dns_domains->len - 1); dns->domain = g_strdup (domain); dns->timestamp = timestamp; dns->lifetime = lifetime; } gboolean -nm_fake_rdisc_done (NMFakeRDisc *self) +nm_fake_ndisc_done (NMFakeNDisc *self) { - return !NM_FAKE_RDISC_GET_PRIVATE (self)->ras; + return !NM_FAKE_NDISC_GET_PRIVATE (self)->ras; } /*****************************************************************************/ static gboolean -send_rs (NMRDisc *rdisc, GError **error) +send_rs (NMNDisc *ndisc, GError **error) { - g_signal_emit (rdisc, signals[RS_SENT], 0); + g_signal_emit (ndisc, signals[RS_SENT], 0); return TRUE; } static gboolean receive_ra (gpointer user_data) { - NMFakeRDisc *self = user_data; - NMFakeRDiscPrivate *priv = NM_FAKE_RDISC_GET_PRIVATE (self); - NMRDisc *rdisc = NM_RDISC (self); - NMRDiscDataInternal *rdata = rdisc->rdata; + NMFakeNDisc *self = user_data; + NMFakeNDiscPrivate *priv = NM_FAKE_NDISC_GET_PRIVATE (self); + NMNDisc *ndisc = NM_NDISC (self); + NMNDiscDataInternal *rdata = ndisc->rdata; FakeRa *ra = priv->ras->data; - NMRDiscConfigMap changed = 0; + NMNDiscConfigMap changed = 0; guint32 now = nm_utils_get_monotonic_timestamp_s (); guint i; - NMRDiscDHCPLevel dhcp_level; + NMNDiscDHCPLevel dhcp_level; priv->receive_ra_id = 0; @@ -261,19 +261,19 @@ receive_ra (gpointer user_data) if (rdata->public.dhcp_level != dhcp_level) { rdata->public.dhcp_level = dhcp_level; - changed |= NM_RDISC_CONFIG_DHCP_LEVEL; + changed |= NM_NDISC_CONFIG_DHCP_LEVEL; } for (i = 0; i < ra->gateways->len; i++) { - NMRDiscGateway *item = &g_array_index (ra->gateways, NMRDiscGateway, i); + NMNDiscGateway *item = &g_array_index (ra->gateways, NMNDiscGateway, i); - if (nm_rdisc_add_gateway (rdisc, item)) - changed |= NM_RDISC_CONFIG_GATEWAYS; + if (nm_ndisc_add_gateway (ndisc, item)) + changed |= NM_NDISC_CONFIG_GATEWAYS; } for (i = 0; i < ra->prefixes->len; i++) { FakePrefix *item = &g_array_index (ra->prefixes, FakePrefix, i); - NMRDiscRoute route = { + NMNDiscRoute route = { .network = item->network, .plen = item->plen, .gateway = item->gateway, @@ -284,11 +284,11 @@ receive_ra (gpointer user_data) g_assert (route.plen > 0 && route.plen <= 128); - if (nm_rdisc_add_route (rdisc, &route)) - changed |= NM_RDISC_CONFIG_ROUTES; + if (nm_ndisc_add_route (ndisc, &route)) + changed |= NM_NDISC_CONFIG_ROUTES; if (item->plen == 64) { - NMRDiscAddress address = { + NMNDiscAddress address = { .address = item->network, .timestamp = item->timestamp, .lifetime = item->lifetime, @@ -296,39 +296,39 @@ receive_ra (gpointer user_data) .dad_counter = 0, }; - if (nm_rdisc_complete_and_add_address (rdisc, &address)) - changed |= NM_RDISC_CONFIG_ADDRESSES; + if (nm_ndisc_complete_and_add_address (ndisc, &address)) + changed |= NM_NDISC_CONFIG_ADDRESSES; } } for (i = 0; i < ra->dns_servers->len; i++) { - NMRDiscDNSServer *item = &g_array_index (ra->dns_servers, NMRDiscDNSServer, i); + NMNDiscDNSServer *item = &g_array_index (ra->dns_servers, NMNDiscDNSServer, i); - if (nm_rdisc_add_dns_server (rdisc, item)) - changed |= NM_RDISC_CONFIG_DNS_SERVERS; + if (nm_ndisc_add_dns_server (ndisc, item)) + changed |= NM_NDISC_CONFIG_DNS_SERVERS; } for (i = 0; i < ra->dns_domains->len; i++) { - NMRDiscDNSDomain *item = &g_array_index (ra->dns_domains, NMRDiscDNSDomain, i); + NMNDiscDNSDomain *item = &g_array_index (ra->dns_domains, NMNDiscDNSDomain, i); - if (nm_rdisc_add_dns_domain (rdisc, item)) - changed |= NM_RDISC_CONFIG_DNS_DOMAINS; + if (nm_ndisc_add_dns_domain (ndisc, item)) + changed |= NM_NDISC_CONFIG_DNS_DOMAINS; } if (rdata->public.mtu != ra->mtu) { rdata->public.mtu = ra->mtu; - changed |= NM_RDISC_CONFIG_MTU; + changed |= NM_NDISC_CONFIG_MTU; } if (rdata->public.hop_limit != ra->hop_limit) { rdata->public.hop_limit = ra->hop_limit; - changed |= NM_RDISC_CONFIG_HOP_LIMIT; + changed |= NM_NDISC_CONFIG_HOP_LIMIT; } priv->ras = g_slist_remove (priv->ras, priv->ras->data); fake_ra_free (ra); - nm_rdisc_ra_received (NM_RDISC (self), now, changed); + nm_ndisc_ra_received (NM_NDISC (self), now, changed); /* Schedule next RA */ if (priv->ras) { @@ -340,9 +340,9 @@ receive_ra (gpointer user_data) } static void -start (NMRDisc *rdisc) +start (NMNDisc *ndisc) { - NMFakeRDiscPrivate *priv = NM_FAKE_RDISC_GET_PRIVATE ((NMFakeRDisc *) rdisc); + NMFakeNDiscPrivate *priv = NM_FAKE_NDISC_GET_PRIVATE ((NMFakeNDisc *) ndisc); FakeRa *ra; /* Queue up the first fake RA */ @@ -350,58 +350,58 @@ start (NMRDisc *rdisc) ra = priv->ras->data; g_assert (!priv->receive_ra_id); - priv->receive_ra_id = g_timeout_add_seconds (ra->when, receive_ra, rdisc); + priv->receive_ra_id = g_timeout_add_seconds (ra->when, receive_ra, ndisc); } void -nm_fake_rdisc_emit_new_ras (NMFakeRDisc *self) +nm_fake_ndisc_emit_new_ras (NMFakeNDisc *self) { - if (!NM_FAKE_RDISC_GET_PRIVATE (self)->receive_ra_id) - start (NM_RDISC (self)); + if (!NM_FAKE_NDISC_GET_PRIVATE (self)->receive_ra_id) + start (NM_NDISC (self)); } /*****************************************************************************/ static void -nm_fake_rdisc_init (NMFakeRDisc *fake_rdisc) +nm_fake_ndisc_init (NMFakeNDisc *fake_ndisc) { } -NMRDisc * -nm_fake_rdisc_new (int ifindex, const char *ifname) +NMNDisc * +nm_fake_ndisc_new (int ifindex, const char *ifname) { - return g_object_new (NM_TYPE_FAKE_RDISC, - NM_RDISC_IFINDEX, ifindex, - NM_RDISC_IFNAME, ifname, + return g_object_new (NM_TYPE_FAKE_NDISC, + NM_NDISC_IFINDEX, ifindex, + NM_NDISC_IFNAME, ifname, NULL); } static void dispose (GObject *object) { - NMFakeRDiscPrivate *priv = NM_FAKE_RDISC_GET_PRIVATE ((NMFakeRDisc *) object); + NMFakeNDiscPrivate *priv = NM_FAKE_NDISC_GET_PRIVATE ((NMFakeNDisc *) object); nm_clear_g_source (&priv->receive_ra_id); g_slist_free_full (priv->ras, fake_ra_free); priv->ras = NULL; - G_OBJECT_CLASS (nm_fake_rdisc_parent_class)->dispose (object); + G_OBJECT_CLASS (nm_fake_ndisc_parent_class)->dispose (object); } static void -nm_fake_rdisc_class_init (NMFakeRDiscClass *klass) +nm_fake_ndisc_class_init (NMFakeNDiscClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMRDiscClass *rdisc_class = NM_RDISC_CLASS (klass); + NMNDiscClass *ndisc_class = NM_NDISC_CLASS (klass); object_class->dispose = dispose; - rdisc_class->start = start; - rdisc_class->send_rs = send_rs; + ndisc_class->start = start; + ndisc_class->send_rs = send_rs; signals[RS_SENT] = - g_signal_new (NM_FAKE_RDISC_RS_SENT, + g_signal_new (NM_FAKE_NDISC_RS_SENT, G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL, diff --git a/src/rdisc/nm-fake-rdisc.h b/src/ndisc/nm-fake-ndisc.h similarity index 55% rename from src/rdisc/nm-fake-rdisc.h rename to src/ndisc/nm-fake-ndisc.h index 5f6509568d..2544c45644 100644 --- a/src/rdisc/nm-fake-rdisc.h +++ b/src/ndisc/nm-fake-ndisc.h @@ -1,5 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* nm-fake-rdisc.h - Fake implementation of router discovery +/* nm-fake-ndisc.h - Fake implementation of neighbor discovery * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,41 +18,41 @@ * Copyright (C) 2013 Red Hat, Inc. */ -#ifndef __NETWORKMANAGER_FAKE_RDISC_H__ -#define __NETWORKMANAGER_FAKE_RDISC_H__ +#ifndef __NETWORKMANAGER_FAKE_NDISC_H__ +#define __NETWORKMANAGER_FAKE_NDISC_H__ -#include "nm-rdisc.h" +#include "nm-ndisc.h" -#define NM_TYPE_FAKE_RDISC (nm_fake_rdisc_get_type ()) -#define NM_FAKE_RDISC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_FAKE_RDISC, NMFakeRDisc)) -#define NM_FAKE_RDISC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_FAKE_RDISC, NMFakeRDiscClass)) -#define NM_IS_FAKE_RDISC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_FAKE_RDISC)) -#define NM_IS_FAKE_RDISC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_FAKE_RDISC)) -#define NM_FAKE_RDISC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_FAKE_RDISC, NMFakeRDiscClass)) +#define NM_TYPE_FAKE_NDISC (nm_fake_ndisc_get_type ()) +#define NM_FAKE_NDISC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_FAKE_NDISC, NMFakeNDisc)) +#define NM_FAKE_NDISC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_FAKE_NDISC, NMFakeNDiscClass)) +#define NM_IS_FAKE_NDISC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_FAKE_NDISC)) +#define NM_IS_FAKE_NDISC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_FAKE_NDISC)) +#define NM_FAKE_NDISC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_FAKE_NDISC, NMFakeNDiscClass)) -#define NM_FAKE_RDISC_RS_SENT "rs-sent" +#define NM_FAKE_NDISC_RS_SENT "rs-sent" -typedef struct _NMFakeRRDisc NMFakeRDisc; -typedef struct _NMFakeRRDiscClass NMFakeRDiscClass; +typedef struct _NMFakeRNDisc NMFakeNDisc; +typedef struct _NMFakeRNDiscClass NMFakeNDiscClass; -GType nm_fake_rdisc_get_type (void); +GType nm_fake_ndisc_get_type (void); -NMRDisc *nm_fake_rdisc_new (int ifindex, const char *ifname); +NMNDisc *nm_fake_ndisc_new (int ifindex, const char *ifname); -guint nm_fake_rdisc_add_ra (NMFakeRDisc *self, +guint nm_fake_ndisc_add_ra (NMFakeNDisc *self, guint seconds, - NMRDiscDHCPLevel dhcp_level, + NMNDiscDHCPLevel dhcp_level, int hop_limit, guint32 mtu); -void nm_fake_rdisc_add_gateway (NMFakeRDisc *self, +void nm_fake_ndisc_add_gateway (NMFakeNDisc *self, guint ra_id, const char *addr, guint32 timestamp, guint32 lifetime, - NMRDiscPreference preference); + NMNDiscPreference preference); -void nm_fake_rdisc_add_prefix (NMFakeRDisc *self, +void nm_fake_ndisc_add_prefix (NMFakeNDisc *self, guint ra_id, const char *network, guint plen, @@ -60,22 +60,22 @@ void nm_fake_rdisc_add_prefix (NMFakeRDisc *self, guint32 timestamp, guint32 lifetime, guint32 preferred, - NMRDiscPreference preference); + NMNDiscPreference preference); -void nm_fake_rdisc_add_dns_server (NMFakeRDisc *self, +void nm_fake_ndisc_add_dns_server (NMFakeNDisc *self, guint ra_id, const char *address, guint32 timestamp, guint32 lifetime); -void nm_fake_rdisc_add_dns_domain (NMFakeRDisc *self, +void nm_fake_ndisc_add_dns_domain (NMFakeNDisc *self, guint ra_id, const char *domain, guint32 timestamp, guint32 lifetime); -void nm_fake_rdisc_emit_new_ras (NMFakeRDisc *self); +void nm_fake_ndisc_emit_new_ras (NMFakeNDisc *self); -gboolean nm_fake_rdisc_done (NMFakeRDisc *self); +gboolean nm_fake_ndisc_done (NMFakeNDisc *self); -#endif /* __NETWORKMANAGER_FAKE_RDISC_H__ */ +#endif /* __NETWORKMANAGER_FAKE_NDISC_H__ */ diff --git a/src/rdisc/nm-lndp-rdisc.c b/src/ndisc/nm-lndp-ndisc.c similarity index 72% rename from src/rdisc/nm-lndp-rdisc.c rename to src/ndisc/nm-lndp-ndisc.c index db2965b155..0259c52efd 100644 --- a/src/rdisc/nm-lndp-rdisc.c +++ b/src/ndisc/nm-lndp-ndisc.c @@ -1,5 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* nm-lndp-rdisc.c - Router discovery implementation using libndp +/* nm-lndp-ndisc.c - Router discovery implementation using libndp * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,7 +20,7 @@ #include "nm-default.h" -#include "nm-lndp-rdisc.h" +#include "nm-lndp-ndisc.h" #include #include @@ -28,12 +28,12 @@ #include #include -#include "nm-rdisc-private.h" +#include "nm-ndisc-private.h" #include "NetworkManagerUtils.h" #include "nm-platform.h" #include "nmp-netns.h" -#define _NMLOG_PREFIX_NAME "rdisc-lndp" +#define _NMLOG_PREFIX_NAME "ndisc-lndp" /*****************************************************************************/ @@ -43,31 +43,31 @@ typedef struct { GIOChannel *event_channel; guint event_id; guint ra_timeout_id; /* first RA timeout */ -} NMLndpRDiscPrivate; +} NMLndpNDiscPrivate; /*****************************************************************************/ -struct _NMLndpRDisc { - NMRDisc parent; - NMLndpRDiscPrivate _priv; +struct _NMLndpNDisc { + NMNDisc parent; + NMLndpNDiscPrivate _priv; }; -struct _NMLndpRDiscClass { - NMRDiscClass parent; +struct _NMLndpNDiscClass { + NMNDiscClass parent; }; /*****************************************************************************/ -G_DEFINE_TYPE (NMLndpRDisc, nm_lndp_rdisc, NM_TYPE_RDISC) +G_DEFINE_TYPE (NMLndpNDisc, nm_lndp_ndisc, NM_TYPE_NDISC) -#define NM_LNDP_RDISC_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMLndpRDisc, NM_IS_LNDP_RDISC) +#define NM_LNDP_NDISC_GET_PRIVATE(self) _NM_GET_PRIVATE(self, NMLndpNDisc, NM_IS_LNDP_NDISC) /*****************************************************************************/ static gboolean -send_rs (NMRDisc *rdisc, GError **error) +send_rs (NMNDisc *ndisc, GError **error) { - NMLndpRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE ((NMLndpRDisc *) rdisc); + NMLndpNDiscPrivate *priv = NM_LNDP_NDISC_GET_PRIVATE ((NMLndpNDisc *) ndisc); struct ndp_msg *msg; int errsv; @@ -78,7 +78,7 @@ send_rs (NMRDisc *rdisc, GError **error) "cannot create router solicitation"); return FALSE; } - ndp_msg_ifindex_set (msg, nm_rdisc_get_ifindex (rdisc)); + ndp_msg_ifindex_set (msg, nm_ndisc_get_ifindex (ndisc)); errsv = ndp_msg_send (priv->ndp, msg); ndp_msg_destroy (msg); @@ -93,19 +93,19 @@ send_rs (NMRDisc *rdisc, GError **error) return TRUE; } -_NM_UTILS_LOOKUP_DEFINE (static, translate_preference, enum ndp_route_preference, NMRDiscPreference, - NM_UTILS_LOOKUP_DEFAULT (NM_RDISC_PREFERENCE_INVALID), - NM_UTILS_LOOKUP_ITEM (NDP_ROUTE_PREF_LOW, NM_RDISC_PREFERENCE_LOW), - NM_UTILS_LOOKUP_ITEM (NDP_ROUTE_PREF_MEDIUM, NM_RDISC_PREFERENCE_MEDIUM), - NM_UTILS_LOOKUP_ITEM (NDP_ROUTE_PREF_HIGH, NM_RDISC_PREFERENCE_HIGH), +_NM_UTILS_LOOKUP_DEFINE (static, translate_preference, enum ndp_route_preference, NMNDiscPreference, + NM_UTILS_LOOKUP_DEFAULT (NM_NDISC_PREFERENCE_INVALID), + NM_UTILS_LOOKUP_ITEM (NDP_ROUTE_PREF_LOW, NM_NDISC_PREFERENCE_LOW), + NM_UTILS_LOOKUP_ITEM (NDP_ROUTE_PREF_MEDIUM, NM_NDISC_PREFERENCE_MEDIUM), + NM_UTILS_LOOKUP_ITEM (NDP_ROUTE_PREF_HIGH, NM_NDISC_PREFERENCE_HIGH), ); static int receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data) { - NMRDisc *rdisc = (NMRDisc *) user_data; - NMRDiscDataInternal *rdata = rdisc->rdata; - NMRDiscConfigMap changed = 0; + NMNDisc *ndisc = (NMNDisc *) user_data; + NMNDiscDataInternal *rdata = ndisc->rdata; + NMNDiscConfigMap changed = 0; struct ndp_msgra *msgra = ndp_msgra (msg); struct in6_addr gateway_addr; guint32 now = nm_utils_get_monotonic_timestamp_s (); @@ -132,24 +132,24 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data) * rewrite the flag with every inbound RA. */ { - NMRDiscDHCPLevel dhcp_level; + NMNDiscDHCPLevel dhcp_level; if (ndp_msgra_flag_managed (msgra)) - dhcp_level = NM_RDISC_DHCP_LEVEL_MANAGED; + dhcp_level = NM_NDISC_DHCP_LEVEL_MANAGED; else if (ndp_msgra_flag_other (msgra)) - dhcp_level = NM_RDISC_DHCP_LEVEL_OTHERCONF; + dhcp_level = NM_NDISC_DHCP_LEVEL_OTHERCONF; else - dhcp_level = NM_RDISC_DHCP_LEVEL_NONE; + dhcp_level = NM_NDISC_DHCP_LEVEL_NONE; /* when receiving multiple RA (possibly from different routers), * let's keep the "most managed" level. */ - G_STATIC_ASSERT_EXPR (NM_RDISC_DHCP_LEVEL_MANAGED > NM_RDISC_DHCP_LEVEL_OTHERCONF); - G_STATIC_ASSERT_EXPR (NM_RDISC_DHCP_LEVEL_OTHERCONF > NM_RDISC_DHCP_LEVEL_NONE); + G_STATIC_ASSERT_EXPR (NM_NDISC_DHCP_LEVEL_MANAGED > NM_NDISC_DHCP_LEVEL_OTHERCONF); + G_STATIC_ASSERT_EXPR (NM_NDISC_DHCP_LEVEL_OTHERCONF > NM_NDISC_DHCP_LEVEL_NONE); dhcp_level = MAX (dhcp_level, rdata->public.dhcp_level); if (dhcp_level != rdata->public.dhcp_level) { rdata->public.dhcp_level = dhcp_level; - changed |= NM_RDISC_CONFIG_DHCP_LEVEL; + changed |= NM_NDISC_CONFIG_DHCP_LEVEL; } } @@ -161,15 +161,15 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data) */ gateway_addr = *ndp_msg_addrto (msg); { - NMRDiscGateway gateway = { + NMNDiscGateway gateway = { .address = gateway_addr, .timestamp = now, .lifetime = ndp_msgra_router_lifetime (msgra), .preference = translate_preference (ndp_msgra_route_preference (msgra)), }; - if (nm_rdisc_add_gateway (rdisc, &gateway)) - changed |= NM_RDISC_CONFIG_GATEWAYS; + if (nm_ndisc_add_gateway (ndisc, &gateway)) + changed |= NM_NDISC_CONFIG_GATEWAYS; } /* Addresses & Routes */ @@ -185,21 +185,21 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data) nm_utils_ip6_address_clear_host_address (&r_network, ndp_msg_opt_prefix (msg, offset), r_plen); if (ndp_msg_opt_prefix_flag_on_link (msg, offset)) { - NMRDiscRoute route = { + NMNDiscRoute route = { .network = r_network, .plen = r_plen, .timestamp = now, .lifetime = ndp_msg_opt_prefix_valid_time (msg, offset), }; - if (nm_rdisc_add_route (rdisc, &route)) - changed |= NM_RDISC_CONFIG_ROUTES; + if (nm_ndisc_add_route (ndisc, &route)) + changed |= NM_NDISC_CONFIG_ROUTES; } /* Address */ if ( r_plen == 64 && ndp_msg_opt_prefix_flag_auto_addr_conf (msg, offset)) { - NMRDiscAddress address = { + NMNDiscAddress address = { .address = r_network, .timestamp = now, .lifetime = ndp_msg_opt_prefix_valid_time (msg, offset), @@ -208,12 +208,12 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data) if (address.preferred > address.lifetime) address.preferred = address.lifetime; - if (nm_rdisc_complete_and_add_address (rdisc, &address)) - changed |= NM_RDISC_CONFIG_ADDRESSES; + if (nm_ndisc_complete_and_add_address (ndisc, &address)) + changed |= NM_NDISC_CONFIG_ADDRESSES; } } ndp_msg_opt_for_each_offset(offset, msg, NDP_MSG_OPT_ROUTE) { - NMRDiscRoute route = { + NMNDiscRoute route = { .gateway = gateway_addr, .plen = ndp_msg_opt_route_prefix_len (msg, offset), .timestamp = now, @@ -226,8 +226,8 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data) /* Routers through this particular gateway */ nm_utils_ip6_address_clear_host_address (&route.network, ndp_msg_opt_route_prefix (msg, offset), route.plen); - if (nm_rdisc_add_route (rdisc, &route)) - changed |= NM_RDISC_CONFIG_ROUTES; + if (nm_ndisc_add_route (ndisc, &route)) + changed |= NM_NDISC_CONFIG_ROUTES; } /* DNS information */ @@ -236,7 +236,7 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data) int addr_index; ndp_msg_opt_rdnss_for_each_addr (addr, addr_index, msg, offset) { - NMRDiscDNSServer dns_server = { + NMNDiscDNSServer dns_server = { .address = *addr, .timestamp = now, .lifetime = ndp_msg_opt_rdnss_lifetime (msg, offset), @@ -249,8 +249,8 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data) */ if (dns_server.lifetime && dns_server.lifetime < 7200) dns_server.lifetime = 7200; - if (nm_rdisc_add_dns_server (rdisc, &dns_server)) - changed |= NM_RDISC_CONFIG_DNS_SERVERS; + if (nm_ndisc_add_dns_server (ndisc, &dns_server)) + changed |= NM_NDISC_CONFIG_DNS_SERVERS; } } ndp_msg_opt_for_each_offset(offset, msg, NDP_MSG_OPT_DNSSL) { @@ -258,7 +258,7 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data) int domain_index; ndp_msg_opt_dnssl_for_each_domain (domain, domain_index, msg, offset) { - NMRDiscDNSDomain dns_domain = { + NMNDiscDNSDomain dns_domain = { .domain = domain, .timestamp = now, .lifetime = ndp_msg_opt_rdnss_lifetime (msg, offset), @@ -271,15 +271,15 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data) */ if (dns_domain.lifetime && dns_domain.lifetime < 7200) dns_domain.lifetime = 7200; - if (nm_rdisc_add_dns_domain (rdisc, &dns_domain)) - changed |= NM_RDISC_CONFIG_DNS_DOMAINS; + if (nm_ndisc_add_dns_domain (ndisc, &dns_domain)) + changed |= NM_NDISC_CONFIG_DNS_DOMAINS; } } hop_limit = ndp_msgra_curhoplimit (msgra); if (rdata->public.hop_limit != hop_limit) { rdata->public.hop_limit = hop_limit; - changed |= NM_RDISC_CONFIG_HOP_LIMIT; + changed |= NM_NDISC_CONFIG_HOP_LIMIT; } /* MTU */ @@ -288,7 +288,7 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data) if (mtu >= 1280) { if (rdata->public.mtu != mtu) { rdata->public.mtu = mtu; - changed |= NM_RDISC_CONFIG_MTU; + changed |= NM_NDISC_CONFIG_MTU; } } else { /* All sorts of bad things would happen if we accepted this. @@ -299,19 +299,19 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data) } } - nm_rdisc_ra_received (rdisc, now, changed); + nm_ndisc_ra_received (ndisc, now, changed); return 0; } static gboolean -event_ready (GIOChannel *source, GIOCondition condition, NMRDisc *rdisc) +event_ready (GIOChannel *source, GIOCondition condition, NMNDisc *ndisc) { nm_auto_pop_netns NMPNetns *netns = NULL; - NMLndpRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE ((NMLndpRDisc *) rdisc); + NMLndpNDiscPrivate *priv = NM_LNDP_NDISC_GET_PRIVATE ((NMLndpNDisc *) ndisc); _LOGD ("processing libndp events"); - if (!nm_rdisc_netns_push (rdisc, &netns)) + if (!nm_ndisc_netns_push (ndisc, &netns)) return G_SOURCE_CONTINUE; ndp_callall_eventfd_handler (priv->ndp); @@ -319,18 +319,18 @@ event_ready (GIOChannel *source, GIOCondition condition, NMRDisc *rdisc) } static void -start (NMRDisc *rdisc) +start (NMNDisc *ndisc) { - NMLndpRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE ((NMLndpRDisc *) rdisc); + NMLndpNDiscPrivate *priv = NM_LNDP_NDISC_GET_PRIVATE ((NMLndpNDisc *) ndisc); int fd = ndp_get_eventfd (priv->ndp); priv->event_channel = g_io_channel_unix_new (fd); - priv->event_id = g_io_add_watch (priv->event_channel, G_IO_IN, (GIOFunc) event_ready, rdisc); + priv->event_id = g_io_add_watch (priv->event_channel, G_IO_IN, (GIOFunc) event_ready, ndisc); /* Flush any pending messages to avoid using obsolete information */ - event_ready (priv->event_channel, 0, rdisc); + event_ready (priv->event_channel, 0, ndisc); - ndp_msgrcv_handler_register (priv->ndp, receive_ra, NDP_MSG_RA, nm_rdisc_get_ifindex (rdisc), rdisc); + ndp_msgrcv_handler_register (priv->ndp, receive_ra, NDP_MSG_RA, nm_ndisc_get_ifindex (ndisc), ndisc); } /*****************************************************************************/ @@ -347,12 +347,12 @@ ipv6_sysctl_get (NMPlatform *platform, const char *ifname, const char *property, } static void -nm_lndp_rdisc_init (NMLndpRDisc *lndp_rdisc) +nm_lndp_ndisc_init (NMLndpNDisc *lndp_ndisc) { } -NMRDisc * -nm_lndp_rdisc_new (NMPlatform *platform, +NMNDisc * +nm_lndp_ndisc_new (NMPlatform *platform, int ifindex, const char *ifname, NMUtilsStableType stable_type, @@ -361,8 +361,8 @@ nm_lndp_rdisc_new (NMPlatform *platform, GError **error) { nm_auto_pop_netns NMPNetns *netns = NULL; - NMRDisc *rdisc; - NMLndpRDiscPrivate *priv; + NMNDisc *ndisc; + NMLndpNDiscPrivate *priv; int errsv; g_return_val_if_fail (NM_IS_PLATFORM (platform), NULL); @@ -371,25 +371,25 @@ nm_lndp_rdisc_new (NMPlatform *platform, if (!nm_platform_netns_push (platform, &netns)) return NULL; - rdisc = g_object_new (NM_TYPE_LNDP_RDISC, - NM_RDISC_PLATFORM, platform, - NM_RDISC_STABLE_TYPE, (int) stable_type, - NM_RDISC_IFINDEX, ifindex, - NM_RDISC_IFNAME, ifname, - NM_RDISC_NETWORK_ID, network_id, - NM_RDISC_ADDR_GEN_MODE, (int) addr_gen_mode, - NM_RDISC_MAX_ADDRESSES, ipv6_sysctl_get (platform, ifname, + ndisc = g_object_new (NM_TYPE_LNDP_NDISC, + NM_NDISC_PLATFORM, platform, + NM_NDISC_STABLE_TYPE, (int) stable_type, + NM_NDISC_IFINDEX, ifindex, + NM_NDISC_IFNAME, ifname, + NM_NDISC_NETWORK_ID, network_id, + NM_NDISC_ADDR_GEN_MODE, (int) addr_gen_mode, + NM_NDISC_MAX_ADDRESSES, ipv6_sysctl_get (platform, ifname, "max_addresses", - 0, G_MAXINT32, NM_RDISC_MAX_ADDRESSES_DEFAULT), - NM_RDISC_ROUTER_SOLICITATIONS, ipv6_sysctl_get (platform, ifname, + 0, G_MAXINT32, NM_NDISC_MAX_ADDRESSES_DEFAULT), + NM_NDISC_ROUTER_SOLICITATIONS, ipv6_sysctl_get (platform, ifname, "router_solicitations", - 1, G_MAXINT32, NM_RDISC_ROUTER_SOLICITATIONS_DEFAULT), - NM_RDISC_ROUTER_SOLICITATION_INTERVAL, ipv6_sysctl_get (platform, ifname, + 1, G_MAXINT32, NM_NDISC_ROUTER_SOLICITATIONS_DEFAULT), + NM_NDISC_ROUTER_SOLICITATION_INTERVAL, ipv6_sysctl_get (platform, ifname, "router_solicitation_interval", - 1, G_MAXINT32, NM_RDISC_ROUTER_SOLICITATION_INTERVAL_DEFAULT), + 1, G_MAXINT32, NM_NDISC_ROUTER_SOLICITATION_INTERVAL_DEFAULT), NULL); - priv = NM_LNDP_RDISC_GET_PRIVATE ((NMLndpRDisc *) rdisc); + priv = NM_LNDP_NDISC_GET_PRIVATE ((NMLndpNDisc *) ndisc); errsv = ndp_open (&priv->ndp); @@ -398,37 +398,37 @@ nm_lndp_rdisc_new (NMPlatform *platform, g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, "failure creating libndp socket: %s (%d)", g_strerror (errsv), errsv); - g_object_unref (rdisc); + g_object_unref (ndisc); return NULL; } - return rdisc; + return ndisc; } static void dispose (GObject *object) { - NMRDisc *rdisc = (NMRDisc *) object; - NMLndpRDiscPrivate *priv = NM_LNDP_RDISC_GET_PRIVATE ((NMLndpRDisc *) rdisc); + NMNDisc *ndisc = (NMNDisc *) object; + NMLndpNDiscPrivate *priv = NM_LNDP_NDISC_GET_PRIVATE ((NMLndpNDisc *) ndisc); nm_clear_g_source (&priv->event_id); g_clear_pointer (&priv->event_channel, g_io_channel_unref); if (priv->ndp) { - ndp_msgrcv_handler_unregister (priv->ndp, receive_ra, NDP_MSG_RA, nm_rdisc_get_ifindex (rdisc), rdisc); + ndp_msgrcv_handler_unregister (priv->ndp, receive_ra, NDP_MSG_RA, nm_ndisc_get_ifindex (ndisc), ndisc); ndp_close (priv->ndp); priv->ndp = NULL; } - G_OBJECT_CLASS (nm_lndp_rdisc_parent_class)->dispose (object); + G_OBJECT_CLASS (nm_lndp_ndisc_parent_class)->dispose (object); } static void -nm_lndp_rdisc_class_init (NMLndpRDiscClass *klass) +nm_lndp_ndisc_class_init (NMLndpNDiscClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - NMRDiscClass *rdisc_class = NM_RDISC_CLASS (klass); + NMNDiscClass *ndisc_class = NM_NDISC_CLASS (klass); object_class->dispose = dispose; - rdisc_class->start = start; - rdisc_class->send_rs = send_rs; + ndisc_class->start = start; + ndisc_class->send_rs = send_rs; } diff --git a/src/rdisc/nm-lndp-rdisc.h b/src/ndisc/nm-lndp-ndisc.h similarity index 54% rename from src/rdisc/nm-lndp-rdisc.h rename to src/ndisc/nm-lndp-ndisc.h index e2b47c0400..9b97a164dc 100644 --- a/src/rdisc/nm-lndp-rdisc.h +++ b/src/ndisc/nm-lndp-ndisc.h @@ -1,5 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* nm-lndp-rdisc.h - Implementation of router discovery using libndp +/* nm-lndp-ndisc.h - Implementation of neighbor discovery using libndp * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,25 +18,25 @@ * Copyright (C) 2013 Red Hat, Inc. */ -#ifndef __NETWORKMANAGER_LNDP_RDISC_H__ -#define __NETWORKMANAGER_LNDP_RDISC_H__ +#ifndef __NETWORKMANAGER_LNDP_NDISC_H__ +#define __NETWORKMANAGER_LNDP_NDISC_H__ -#include "nm-rdisc.h" +#include "nm-ndisc.h" #include "nm-core-utils.h" -#define NM_TYPE_LNDP_RDISC (nm_lndp_rdisc_get_type ()) -#define NM_LNDP_RDISC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_LNDP_RDISC, NMLndpRDisc)) -#define NM_LNDP_RDISC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_LNDP_RDISC, NMLndpRDiscClass)) -#define NM_IS_LNDP_RDISC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_LNDP_RDISC)) -#define NM_IS_LNDP_RDISC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_LNDP_RDISC)) -#define NM_LNDP_RDISC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_LNDP_RDISC, NMLndpRDiscClass)) +#define NM_TYPE_LNDP_NDISC (nm_lndp_ndisc_get_type ()) +#define NM_LNDP_NDISC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_LNDP_NDISC, NMLndpNDisc)) +#define NM_LNDP_NDISC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_LNDP_NDISC, NMLndpNDiscClass)) +#define NM_IS_LNDP_NDISC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_LNDP_NDISC)) +#define NM_IS_LNDP_NDISC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_LNDP_NDISC)) +#define NM_LNDP_NDISC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_LNDP_NDISC, NMLndpNDiscClass)) -typedef struct _NMLndpRDisc NMLndpRDisc; -typedef struct _NMLndpRDiscClass NMLndpRDiscClass; +typedef struct _NMLndpNDisc NMLndpNDisc; +typedef struct _NMLndpNDiscClass NMLndpNDiscClass; -GType nm_lndp_rdisc_get_type (void); +GType nm_lndp_ndisc_get_type (void); -NMRDisc *nm_lndp_rdisc_new (NMPlatform *platform, +NMNDisc *nm_lndp_ndisc_new (NMPlatform *platform, int ifindex, const char *ifname, NMUtilsStableType stable_type, @@ -44,4 +44,4 @@ NMRDisc *nm_lndp_rdisc_new (NMPlatform *platform, NMSettingIP6ConfigAddrGenMode addr_gen_mode, GError **error); -#endif /* __NETWORKMANAGER_LNDP_RDISC_H__ */ +#endif /* __NETWORKMANAGER_LNDP_NDISC_H__ */ diff --git a/src/rdisc/nm-rdisc-private.h b/src/ndisc/nm-ndisc-private.h similarity index 68% rename from src/rdisc/nm-rdisc-private.h rename to src/ndisc/nm-ndisc-private.h index cc2f1ae10d..999f38dd70 100644 --- a/src/rdisc/nm-rdisc-private.h +++ b/src/ndisc/nm-ndisc-private.h @@ -1,5 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* nm-rdisc.h - Perform IPv6 router discovery +/* nm-ndisc.h - Perform IPv6 neighbor discovery * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,15 +18,15 @@ * Copyright 2015 Red Hat, Inc. */ -#ifndef __NETWORKMANAGER_RDISC_PRIVATE_H__ -#define __NETWORKMANAGER_RDISC_PRIVATE_H__ +#ifndef __NETWORKMANAGER_NDISC_PRIVATE_H__ +#define __NETWORKMANAGER_NDISC_PRIVATE_H__ -#include "nm-rdisc.h" +#include "nm-ndisc.h" -/* Functions only used by rdisc implementations */ +/* Functions only used by ndisc implementations */ -struct _NMRDiscDataInternal { - NMRDiscData public; +struct _NMNDiscDataInternal { + NMNDiscData public; GArray *gateways; GArray *addresses; GArray *routes; @@ -34,20 +34,20 @@ struct _NMRDiscDataInternal { GArray *dns_domains; }; -typedef struct _NMRDiscDataInternal NMRDiscDataInternal; +typedef struct _NMNDiscDataInternal NMNDiscDataInternal; -void nm_rdisc_ra_received (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap changed); +void nm_ndisc_ra_received (NMNDisc *ndisc, guint32 now, NMNDiscConfigMap changed); -gboolean nm_rdisc_add_gateway (NMRDisc *rdisc, const NMRDiscGateway *new); -gboolean nm_rdisc_complete_and_add_address (NMRDisc *rdisc, NMRDiscAddress *new); -gboolean nm_rdisc_add_route (NMRDisc *rdisc, const NMRDiscRoute *new); -gboolean nm_rdisc_add_dns_server (NMRDisc *rdisc, const NMRDiscDNSServer *new); -gboolean nm_rdisc_add_dns_domain (NMRDisc *rdisc, const NMRDiscDNSDomain *new); +gboolean nm_ndisc_add_gateway (NMNDisc *ndisc, const NMNDiscGateway *new); +gboolean nm_ndisc_complete_and_add_address (NMNDisc *ndisc, NMNDiscAddress *new); +gboolean nm_ndisc_add_route (NMNDisc *ndisc, const NMNDiscRoute *new); +gboolean nm_ndisc_add_dns_server (NMNDisc *ndisc, const NMNDiscDNSServer *new); +gboolean nm_ndisc_add_dns_domain (NMNDisc *ndisc, const NMNDiscDNSDomain *new); /*****************************************************************************/ #define _NMLOG_DOMAIN LOGD_IP6 -#define _NMLOG(level, ...) _LOG(level, _NMLOG_DOMAIN, rdisc, __VA_ARGS__) +#define _NMLOG(level, ...) _LOG(level, _NMLOG_DOMAIN, ndisc, __VA_ARGS__) #define _LOG(level, domain, self, ...) \ G_STMT_START { \ @@ -55,14 +55,14 @@ gboolean nm_rdisc_add_dns_domain (NMRDisc *rdisc, const NMRDiscDNSDoma const NMLogDomain __domain = (domain); \ \ if (nm_logging_enabled (__level, __domain)) { \ - NMRDisc *const __self = (self); \ + NMNDisc *const __self = (self); \ char __prefix[64]; \ \ _nm_log (__level, __domain, 0, \ "%s: " _NM_UTILS_MACRO_FIRST (__VA_ARGS__), \ (__self \ ? ({ \ - const char *__ifname = nm_rdisc_get_ifname (__self); \ + const char *__ifname = nm_ndisc_get_ifname (__self); \ nm_sprintf_buf (__prefix, "%s[%p,%s%s%s]", \ _NMLOG_PREFIX_NAME, __self, \ NM_PRINT_FMT_QUOTE_STRING (__ifname)); \ @@ -74,4 +74,4 @@ gboolean nm_rdisc_add_dns_domain (NMRDisc *rdisc, const NMRDiscDNSDoma /*****************************************************************************/ -#endif /* __NETWORKMANAGER_RDISC_PRIVATE_H__ */ +#endif /* __NETWORKMANAGER_NDISC_PRIVATE_H__ */ diff --git a/src/rdisc/nm-rdisc.c b/src/ndisc/nm-ndisc.c similarity index 70% rename from src/rdisc/nm-rdisc.c rename to src/ndisc/nm-ndisc.c index c7437a106c..667d7fec49 100644 --- a/src/rdisc/nm-rdisc.c +++ b/src/ndisc/nm-ndisc.c @@ -1,5 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* nm-rdisc.c - Perform IPv6 router discovery +/* nm-ndisc.c - Perform IPv6 neighbor discovery * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,7 +20,7 @@ #include "nm-default.h" -#include "nm-rdisc.h" +#include "nm-ndisc.h" #include #include @@ -28,18 +28,18 @@ #include "nm-setting-ip6-config.h" -#include "nm-rdisc-private.h" +#include "nm-ndisc-private.h" #include "nm-utils.h" #include "nm-platform.h" #include "nmp-netns.h" -#define _NMLOG_PREFIX_NAME "rdisc" +#define _NMLOG_PREFIX_NAME "ndisc" /*****************************************************************************/ -struct _NMRDiscPrivate { +struct _NMNDiscPrivate { /* this *must* be the first field. */ - NMRDiscDataInternal rdata; + NMNDiscDataInternal rdata; gint32 solicitations_left; guint send_rs_id; @@ -63,7 +63,7 @@ struct _NMRDiscPrivate { NMPNetns *netns; }; -typedef struct _NMRDiscPrivate NMRDiscPrivate; +typedef struct _NMNDiscPrivate NMNDiscPrivate; NM_GOBJECT_PROPERTIES_DEFINE_BASE ( PROP_PLATFORM, @@ -85,32 +85,32 @@ enum { static guint signals[LAST_SIGNAL] = { 0 }; -G_DEFINE_TYPE (NMRDisc, nm_rdisc, G_TYPE_OBJECT) +G_DEFINE_TYPE (NMNDisc, nm_ndisc, G_TYPE_OBJECT) -#define NM_RDISC_GET_PRIVATE(self) _NM_GET_PRIVATE_PTR(self, NMRDisc, NM_IS_RDISC) +#define NM_NDISC_GET_PRIVATE(self) _NM_GET_PRIVATE_PTR(self, NMNDisc, NM_IS_NDISC) /*****************************************************************************/ -static void _config_changed_log (NMRDisc *rdisc, NMRDiscConfigMap changed); +static void _config_changed_log (NMNDisc *ndisc, NMNDiscConfigMap changed); /*****************************************************************************/ NMPNetns * -nm_rdisc_netns_get (NMRDisc *self) +nm_ndisc_netns_get (NMNDisc *self) { - g_return_val_if_fail (NM_IS_RDISC (self), NULL); + g_return_val_if_fail (NM_IS_NDISC (self), NULL); - return NM_RDISC_GET_PRIVATE (self)->netns; + return NM_NDISC_GET_PRIVATE (self)->netns; } gboolean -nm_rdisc_netns_push (NMRDisc *self, NMPNetns **netns) +nm_ndisc_netns_push (NMNDisc *self, NMPNetns **netns) { - NMRDiscPrivate *priv; + NMNDiscPrivate *priv; - g_return_val_if_fail (NM_IS_RDISC (self), FALSE); + g_return_val_if_fail (NM_IS_NDISC (self), FALSE); - priv = NM_RDISC_GET_PRIVATE (self); + priv = NM_NDISC_GET_PRIVATE (self); if ( priv->netns && !nmp_netns_push (priv->netns)) { NM_SET_OUT (netns, NULL); @@ -124,25 +124,25 @@ nm_rdisc_netns_push (NMRDisc *self, NMPNetns **netns) /*****************************************************************************/ int -nm_rdisc_get_ifindex (NMRDisc *self) +nm_ndisc_get_ifindex (NMNDisc *self) { - g_return_val_if_fail (NM_IS_RDISC (self), 0); + g_return_val_if_fail (NM_IS_NDISC (self), 0); - return NM_RDISC_GET_PRIVATE (self)->ifindex; + return NM_NDISC_GET_PRIVATE (self)->ifindex; } const char * -nm_rdisc_get_ifname (NMRDisc *self) +nm_ndisc_get_ifname (NMNDisc *self) { - g_return_val_if_fail (NM_IS_RDISC (self), NULL); + g_return_val_if_fail (NM_IS_NDISC (self), NULL); - return NM_RDISC_GET_PRIVATE (self)->ifname; + return NM_NDISC_GET_PRIVATE (self)->ifname; } /*****************************************************************************/ -static const NMRDiscData * -_data_complete (NMRDiscDataInternal *data) +static const NMNDiscData * +_data_complete (NMNDiscDataInternal *data) { #define _SET(data, field) \ G_STMT_START { \ @@ -161,24 +161,24 @@ _data_complete (NMRDiscDataInternal *data) } static void -_emit_config_change (NMRDisc *self, NMRDiscConfigMap changed) +_emit_config_change (NMNDisc *self, NMNDiscConfigMap changed) { _config_changed_log (self, changed); g_signal_emit (self, signals[CONFIG_CHANGED], 0, - _data_complete (&NM_RDISC_GET_PRIVATE (self)->rdata), + _data_complete (&NM_NDISC_GET_PRIVATE (self)->rdata), (guint) changed); } /*****************************************************************************/ gboolean -nm_rdisc_add_gateway (NMRDisc *rdisc, const NMRDiscGateway *new) +nm_ndisc_add_gateway (NMNDisc *ndisc, const NMNDiscGateway *new) { - NMRDiscDataInternal *rdata = &NM_RDISC_GET_PRIVATE(rdisc)->rdata; + NMNDiscDataInternal *rdata = &NM_NDISC_GET_PRIVATE(ndisc)->rdata; int i, insert_idx = -1; for (i = 0; i < rdata->gateways->len; i++) { - NMRDiscGateway *item = &g_array_index (rdata->gateways, NMRDiscGateway, i); + NMNDiscGateway *item = &g_array_index (rdata->gateways, NMNDiscGateway, i); if (IN6_ARE_ADDR_EQUAL (&item->address, &new->address)) { if (new->lifetime == 0) { @@ -207,8 +207,8 @@ nm_rdisc_add_gateway (NMRDisc *rdisc, const NMRDiscGateway *new) /** * complete_address: - * @rdisc: the #NMRDisc - * @addr: the #NMRDiscAddress + * @ndisc: the #NMNDisc + * @addr: the #NMNDiscAddress * * Adds the host part to the address that has network part set. * If the address already has a host part, add a different host part @@ -220,14 +220,14 @@ nm_rdisc_add_gateway (NMRDisc *rdisc, const NMRDiscGateway *new) * Returns: %TRUE if the address could be completed, %FALSE otherwise. **/ static gboolean -complete_address (NMRDisc *rdisc, NMRDiscAddress *addr) +complete_address (NMNDisc *ndisc, NMNDiscAddress *addr) { - NMRDiscPrivate *priv; + NMNDiscPrivate *priv; GError *error = NULL; - g_return_val_if_fail (NM_IS_RDISC (rdisc), FALSE); + g_return_val_if_fail (NM_IS_NDISC (ndisc), FALSE); - priv = NM_RDISC_GET_PRIVATE (rdisc); + priv = NM_NDISC_GET_PRIVATE (ndisc); if (priv->addr_gen_mode == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY) { if (!nm_utils_ipv6_addr_set_stable_privacy (priv->stable_type, &addr->address, @@ -260,20 +260,20 @@ complete_address (NMRDisc *rdisc, NMRDiscAddress *addr) } gboolean -nm_rdisc_complete_and_add_address (NMRDisc *rdisc, NMRDiscAddress *new) +nm_ndisc_complete_and_add_address (NMNDisc *ndisc, NMNDiscAddress *new) { - NMRDiscPrivate *priv; - NMRDiscDataInternal *rdata; + NMNDiscPrivate *priv; + NMNDiscDataInternal *rdata; int i; - if (!complete_address (rdisc, new)) + if (!complete_address (ndisc, new)) return FALSE; - priv = NM_RDISC_GET_PRIVATE (rdisc); + priv = NM_NDISC_GET_PRIVATE (ndisc); rdata = &priv->rdata; for (i = 0; i < rdata->addresses->len; i++) { - NMRDiscAddress *item = &g_array_index (rdata->addresses, NMRDiscAddress, i); + NMNDiscAddress *item = &g_array_index (rdata->addresses, NMNDiscAddress, i); if (IN6_ARE_ADDR_EQUAL (&item->address, &new->address)) { gboolean changed; @@ -303,28 +303,28 @@ nm_rdisc_complete_and_add_address (NMRDisc *rdisc, NMRDiscAddress *new) } gboolean -nm_rdisc_add_route (NMRDisc *rdisc, const NMRDiscRoute *new) +nm_ndisc_add_route (NMNDisc *ndisc, const NMNDiscRoute *new) { - NMRDiscPrivate *priv; - NMRDiscDataInternal *rdata; + NMNDiscPrivate *priv; + NMNDiscDataInternal *rdata; int i, insert_idx = -1; if (new->plen == 0 || new->plen > 128) { /* Only expect non-default routes. The router has no idea what the * local configuration or user preferences are, so sending routes - * with a prefix length of 0 must be ignored by NMRDisc. + * with a prefix length of 0 must be ignored by NMNDisc. * - * Also, upper layers also don't expect that NMRDisc exposes routes + * Also, upper layers also don't expect that NMNDisc exposes routes * with a plen or zero or larger then 128. */ g_return_val_if_reached (FALSE); } - priv = NM_RDISC_GET_PRIVATE (rdisc); + priv = NM_NDISC_GET_PRIVATE (ndisc); rdata = &priv->rdata; for (i = 0; i < rdata->routes->len; i++) { - NMRDiscRoute *item = &g_array_index (rdata->routes, NMRDiscRoute, i); + NMNDiscRoute *item = &g_array_index (rdata->routes, NMNDiscRoute, i); if (IN6_ARE_ADDR_EQUAL (&item->network, &new->network) && item->plen == new->plen) { if (new->lifetime == 0) { @@ -352,17 +352,17 @@ nm_rdisc_add_route (NMRDisc *rdisc, const NMRDiscRoute *new) } gboolean -nm_rdisc_add_dns_server (NMRDisc *rdisc, const NMRDiscDNSServer *new) +nm_ndisc_add_dns_server (NMNDisc *ndisc, const NMNDiscDNSServer *new) { - NMRDiscPrivate *priv; - NMRDiscDataInternal *rdata; + NMNDiscPrivate *priv; + NMNDiscDataInternal *rdata; int i; - priv = NM_RDISC_GET_PRIVATE (rdisc); + priv = NM_NDISC_GET_PRIVATE (ndisc); rdata = &priv->rdata; for (i = 0; i < rdata->dns_servers->len; i++) { - NMRDiscDNSServer *item = &g_array_index (rdata->dns_servers, NMRDiscDNSServer, i); + NMNDiscDNSServer *item = &g_array_index (rdata->dns_servers, NMNDiscDNSServer, i); if (IN6_ARE_ADDR_EQUAL (&item->address, &new->address)) { if (new->lifetime == 0) { @@ -384,18 +384,18 @@ nm_rdisc_add_dns_server (NMRDisc *rdisc, const NMRDiscDNSServer *new) /* Copies new->domain if 'new' is added to the dns_domains list */ gboolean -nm_rdisc_add_dns_domain (NMRDisc *rdisc, const NMRDiscDNSDomain *new) +nm_ndisc_add_dns_domain (NMNDisc *ndisc, const NMNDiscDNSDomain *new) { - NMRDiscPrivate *priv; - NMRDiscDataInternal *rdata; - NMRDiscDNSDomain *item; + NMNDiscPrivate *priv; + NMNDiscDataInternal *rdata; + NMNDiscDNSDomain *item; int i; - priv = NM_RDISC_GET_PRIVATE (rdisc); + priv = NM_NDISC_GET_PRIVATE (ndisc); rdata = &priv->rdata; for (i = 0; i < rdata->dns_domains->len; i++) { - item = &g_array_index (rdata->dns_domains, NMRDiscDNSDomain, i); + item = &g_array_index (rdata->dns_domains, NMNDiscDNSDomain, i); if (!g_strcmp0 (item->domain, new->domain)) { gboolean changed; @@ -417,7 +417,7 @@ nm_rdisc_add_dns_domain (NMRDisc *rdisc, const NMRDiscDNSDomain *new) if (new->lifetime) { g_array_insert_val (rdata->dns_domains, i, *new); - item = &g_array_index (rdata->dns_domains, NMRDiscDNSDomain, i); + item = &g_array_index (rdata->dns_domains, NMNDiscDNSDomain, i); item->domain = g_strdup (new->domain); } return !!new->lifetime; @@ -426,8 +426,8 @@ nm_rdisc_add_dns_domain (NMRDisc *rdisc, const NMRDiscDNSDomain *new) /*****************************************************************************/ /** - * nm_rdisc_set_iid: - * @rdisc: the #NMRDisc + * nm_ndisc_set_iid: + * @ndisc: the #NMNDisc * @iid: the new interface ID * * Sets the "Modified EUI-64" interface ID to be used when generating @@ -445,14 +445,14 @@ nm_rdisc_add_dns_domain (NMRDisc *rdisc, const NMRDiscDNSDomain *new) * Returns: %TRUE if addresses need to be regenerated, %FALSE otherwise. **/ gboolean -nm_rdisc_set_iid (NMRDisc *rdisc, const NMUtilsIPv6IfaceId iid) +nm_ndisc_set_iid (NMNDisc *ndisc, const NMUtilsIPv6IfaceId iid) { - NMRDiscPrivate *priv; - NMRDiscDataInternal *rdata; + NMNDiscPrivate *priv; + NMNDiscDataInternal *rdata; - g_return_val_if_fail (NM_IS_RDISC (rdisc), FALSE); + g_return_val_if_fail (NM_IS_NDISC (ndisc), FALSE); - priv = NM_RDISC_GET_PRIVATE (rdisc); + priv = NM_NDISC_GET_PRIVATE (ndisc); rdata = &priv->rdata; if (priv->iid.id != iid.id) { @@ -464,7 +464,7 @@ nm_rdisc_set_iid (NMRDisc *rdisc, const NMUtilsIPv6IfaceId iid) if (rdata->addresses->len) { _LOGD ("IPv6 interface identifier changed, flushing addresses"); g_array_remove_range (rdata->addresses, 0, rdata->addresses->len); - _emit_config_change (rdisc, NM_RDISC_CONFIG_ADDRESSES); + _emit_config_change (ndisc, NM_NDISC_CONFIG_ADDRESSES); } return TRUE; } @@ -473,19 +473,19 @@ nm_rdisc_set_iid (NMRDisc *rdisc, const NMUtilsIPv6IfaceId iid) } static gboolean -send_rs_timeout (NMRDisc *rdisc) +send_rs_timeout (NMNDisc *ndisc) { nm_auto_pop_netns NMPNetns *netns = NULL; - NMRDiscClass *klass = NM_RDISC_GET_CLASS (rdisc); - NMRDiscPrivate *priv = NM_RDISC_GET_PRIVATE (rdisc); + NMNDiscClass *klass = NM_NDISC_GET_CLASS (ndisc); + NMNDiscPrivate *priv = NM_NDISC_GET_PRIVATE (ndisc); GError *error = NULL; priv->send_rs_id = 0; - if (!nm_rdisc_netns_push (rdisc, &netns)) + if (!nm_ndisc_netns_push (ndisc, &netns)) return G_SOURCE_REMOVE; - if (klass->send_rs (rdisc, &error)) { + if (klass->send_rs (ndisc, &error)) { _LOGD ("router solicitation sent"); priv->solicitations_left--; g_clear_pointer (&priv->last_send_rs_error, g_free); @@ -507,7 +507,7 @@ send_rs_timeout (NMRDisc *rdisc) _LOGD ("scheduling router solicitation retry in %d seconds.", (int) priv->router_solicitation_interval); priv->send_rs_id = g_timeout_add_seconds (priv->router_solicitation_interval, - (GSourceFunc) send_rs_timeout, rdisc); + (GSourceFunc) send_rs_timeout, ndisc); } else { _LOGD ("did not receive a router advertisement after %d solicitations.", (int) priv->router_solicitations); @@ -517,9 +517,9 @@ send_rs_timeout (NMRDisc *rdisc) } static void -solicit (NMRDisc *rdisc) +solicit (NMNDisc *ndisc) { - NMRDiscPrivate *priv = NM_RDISC_GET_PRIVATE (rdisc); + NMNDiscPrivate *priv = NM_NDISC_GET_PRIVATE (ndisc); gint64 next, now; if (priv->send_rs_id) @@ -533,100 +533,100 @@ solicit (NMRDisc *rdisc) next = CLAMP (next, 0, G_MAXINT32); _LOGD ("scheduling explicit router solicitation request in %" G_GINT64_FORMAT " seconds.", next); - priv->send_rs_id = g_timeout_add_seconds ((guint32) next, (GSourceFunc) send_rs_timeout, rdisc); + priv->send_rs_id = g_timeout_add_seconds ((guint32) next, (GSourceFunc) send_rs_timeout, ndisc); } static gboolean -rdisc_ra_timeout_cb (gpointer user_data) +ndisc_ra_timeout_cb (gpointer user_data) { - NMRDisc *rdisc = NM_RDISC (user_data); + NMNDisc *ndisc = NM_NDISC (user_data); - NM_RDISC_GET_PRIVATE (rdisc)->ra_timeout_id = 0; - g_signal_emit (rdisc, signals[RA_TIMEOUT], 0); + NM_NDISC_GET_PRIVATE (ndisc)->ra_timeout_id = 0; + g_signal_emit (ndisc, signals[RA_TIMEOUT], 0); return G_SOURCE_REMOVE; } void -nm_rdisc_start (NMRDisc *rdisc) +nm_ndisc_start (NMNDisc *ndisc) { nm_auto_pop_netns NMPNetns *netns = NULL; - NMRDiscPrivate *priv = NM_RDISC_GET_PRIVATE (rdisc); - NMRDiscClass *klass = NM_RDISC_GET_CLASS (rdisc); + NMNDiscPrivate *priv = NM_NDISC_GET_PRIVATE (ndisc); + NMNDiscClass *klass = NM_NDISC_GET_CLASS (ndisc); gint64 ra_wait_secs; g_assert (klass->start); - _LOGD ("starting router discovery: %d", priv->ifindex); + _LOGD ("starting neighbor discovery: %d", priv->ifindex); - if (!nm_rdisc_netns_push (rdisc, &netns)) + if (!nm_ndisc_netns_push (ndisc, &netns)) return; nm_clear_g_source (&priv->ra_timeout_id); ra_wait_secs = (((gint64) priv->router_solicitations) * priv->router_solicitation_interval) + 1; ra_wait_secs = CLAMP (ra_wait_secs, 30, 120); - priv->ra_timeout_id = g_timeout_add_seconds (ra_wait_secs, rdisc_ra_timeout_cb, rdisc); + priv->ra_timeout_id = g_timeout_add_seconds (ra_wait_secs, ndisc_ra_timeout_cb, ndisc); _LOGD ("scheduling RA timeout in %d seconds", (int) ra_wait_secs); if (klass->start) - klass->start (rdisc); + klass->start (ndisc); - solicit (rdisc); + solicit (ndisc); } void -nm_rdisc_dad_failed (NMRDisc *rdisc, struct in6_addr *address) +nm_ndisc_dad_failed (NMNDisc *ndisc, struct in6_addr *address) { - NMRDiscDataInternal *rdata; + NMNDiscDataInternal *rdata; int i; gboolean changed = FALSE; - rdata = &NM_RDISC_GET_PRIVATE (rdisc)->rdata; + rdata = &NM_NDISC_GET_PRIVATE (ndisc)->rdata; for (i = 0; i < rdata->addresses->len; i++) { - NMRDiscAddress *item = &g_array_index (rdata->addresses, NMRDiscAddress, i); + NMNDiscAddress *item = &g_array_index (rdata->addresses, NMNDiscAddress, i); if (!IN6_ARE_ADDR_EQUAL (&item->address, address)) continue; _LOGD ("DAD failed for discovered address %s", nm_utils_inet6_ntop (address, NULL)); - if (!complete_address (rdisc, item)) + if (!complete_address (ndisc, item)) g_array_remove_index (rdata->addresses, i--); changed = TRUE; } if (changed) - _emit_config_change (rdisc, NM_RDISC_CONFIG_ADDRESSES); + _emit_config_change (ndisc, NM_NDISC_CONFIG_ADDRESSES); } #define CONFIG_MAP_MAX_STR 7 static void -config_map_to_string (NMRDiscConfigMap map, char *p) +config_map_to_string (NMNDiscConfigMap map, char *p) { - if (map & NM_RDISC_CONFIG_DHCP_LEVEL) + if (map & NM_NDISC_CONFIG_DHCP_LEVEL) *p++ = 'd'; - if (map & NM_RDISC_CONFIG_GATEWAYS) + if (map & NM_NDISC_CONFIG_GATEWAYS) *p++ = 'G'; - if (map & NM_RDISC_CONFIG_ADDRESSES) + if (map & NM_NDISC_CONFIG_ADDRESSES) *p++ = 'A'; - if (map & NM_RDISC_CONFIG_ROUTES) + if (map & NM_NDISC_CONFIG_ROUTES) *p++ = 'R'; - if (map & NM_RDISC_CONFIG_DNS_SERVERS) + if (map & NM_NDISC_CONFIG_DNS_SERVERS) *p++ = 'S'; - if (map & NM_RDISC_CONFIG_DNS_DOMAINS) + if (map & NM_NDISC_CONFIG_DNS_DOMAINS) *p++ = 'D'; *p = '\0'; } static const char * -dhcp_level_to_string (NMRDiscDHCPLevel dhcp_level) +dhcp_level_to_string (NMNDiscDHCPLevel dhcp_level) { switch (dhcp_level) { - case NM_RDISC_DHCP_LEVEL_NONE: + case NM_NDISC_DHCP_LEVEL_NONE: return "none"; - case NM_RDISC_DHCP_LEVEL_OTHERCONF: + case NM_NDISC_DHCP_LEVEL_OTHERCONF: return "otherconf"; - case NM_RDISC_DHCP_LEVEL_MANAGED: + case NM_NDISC_DHCP_LEVEL_MANAGED: return "managed"; default: return "INVALID"; @@ -636,10 +636,10 @@ dhcp_level_to_string (NMRDiscDHCPLevel dhcp_level) #define expiry(item) (item->timestamp + item->lifetime) static void -_config_changed_log (NMRDisc *rdisc, NMRDiscConfigMap changed) +_config_changed_log (NMNDisc *ndisc, NMNDiscConfigMap changed) { - NMRDiscPrivate *priv; - NMRDiscDataInternal *rdata; + NMNDiscPrivate *priv; + NMNDiscDataInternal *rdata; int i; char changedstr[CONFIG_MAP_MAX_STR]; char addrstr[INET6_ADDRSTRLEN]; @@ -647,26 +647,26 @@ _config_changed_log (NMRDisc *rdisc, NMRDiscConfigMap changed) if (!_LOGD_ENABLED ()) return; - priv = NM_RDISC_GET_PRIVATE (rdisc); + priv = NM_NDISC_GET_PRIVATE (ndisc); rdata = &priv->rdata; config_map_to_string (changed, changedstr); - _LOGD ("router discovery configuration changed [%s]:", changedstr); + _LOGD ("neighbor discovery configuration changed [%s]:", changedstr); _LOGD (" dhcp-level %s", dhcp_level_to_string (priv->rdata.public.dhcp_level)); for (i = 0; i < rdata->gateways->len; i++) { - NMRDiscGateway *gateway = &g_array_index (rdata->gateways, NMRDiscGateway, i); + NMNDiscGateway *gateway = &g_array_index (rdata->gateways, NMNDiscGateway, i); inet_ntop (AF_INET6, &gateway->address, addrstr, sizeof (addrstr)); _LOGD (" gateway %s pref %d exp %u", addrstr, gateway->preference, expiry (gateway)); } for (i = 0; i < rdata->addresses->len; i++) { - NMRDiscAddress *address = &g_array_index (rdata->addresses, NMRDiscAddress, i); + NMNDiscAddress *address = &g_array_index (rdata->addresses, NMNDiscAddress, i); inet_ntop (AF_INET6, &address->address, addrstr, sizeof (addrstr)); _LOGD (" address %s exp %u", addrstr, expiry (address)); } for (i = 0; i < rdata->routes->len; i++) { - NMRDiscRoute *route = &g_array_index (rdata->routes, NMRDiscRoute, i); + NMNDiscRoute *route = &g_array_index (rdata->routes, NMNDiscRoute, i); inet_ntop (AF_INET6, &route->network, addrstr, sizeof (addrstr)); _LOGD (" route %s/%d via %s pref %d exp %u", addrstr, (int) route->plen, @@ -674,28 +674,28 @@ _config_changed_log (NMRDisc *rdisc, NMRDiscConfigMap changed) expiry (route)); } for (i = 0; i < rdata->dns_servers->len; i++) { - NMRDiscDNSServer *dns_server = &g_array_index (rdata->dns_servers, NMRDiscDNSServer, i); + NMNDiscDNSServer *dns_server = &g_array_index (rdata->dns_servers, NMNDiscDNSServer, i); inet_ntop (AF_INET6, &dns_server->address, addrstr, sizeof (addrstr)); _LOGD (" dns_server %s exp %u", addrstr, expiry (dns_server)); } for (i = 0; i < rdata->dns_domains->len; i++) { - NMRDiscDNSDomain *dns_domain = &g_array_index (rdata->dns_domains, NMRDiscDNSDomain, i); + NMNDiscDNSDomain *dns_domain = &g_array_index (rdata->dns_domains, NMNDiscDNSDomain, i); _LOGD (" dns_domain %s exp %u", dns_domain->domain, expiry (dns_domain)); } } static void -clean_gateways (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32 *nextevent) +clean_gateways (NMNDisc *ndisc, guint32 now, NMNDiscConfigMap *changed, guint32 *nextevent) { - NMRDiscDataInternal *rdata; + NMNDiscDataInternal *rdata; guint i; - rdata = &NM_RDISC_GET_PRIVATE (rdisc)->rdata; + rdata = &NM_NDISC_GET_PRIVATE (ndisc)->rdata; for (i = 0; i < rdata->gateways->len; i++) { - NMRDiscGateway *item = &g_array_index (rdata->gateways, NMRDiscGateway, i); + NMNDiscGateway *item = &g_array_index (rdata->gateways, NMNDiscGateway, i); guint64 expiry = (guint64) item->timestamp + item->lifetime; if (item->lifetime == G_MAXUINT32) @@ -703,22 +703,22 @@ clean_gateways (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32 if (now >= expiry) { g_array_remove_index (rdata->gateways, i--); - *changed |= NM_RDISC_CONFIG_GATEWAYS; + *changed |= NM_NDISC_CONFIG_GATEWAYS; } else if (*nextevent > expiry) *nextevent = expiry; } } static void -clean_addresses (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32 *nextevent) +clean_addresses (NMNDisc *ndisc, guint32 now, NMNDiscConfigMap *changed, guint32 *nextevent) { - NMRDiscDataInternal *rdata; + NMNDiscDataInternal *rdata; guint i; - rdata = &NM_RDISC_GET_PRIVATE (rdisc)->rdata; + rdata = &NM_NDISC_GET_PRIVATE (ndisc)->rdata; for (i = 0; i < rdata->addresses->len; i++) { - NMRDiscAddress *item = &g_array_index (rdata->addresses, NMRDiscAddress, i); + NMNDiscAddress *item = &g_array_index (rdata->addresses, NMNDiscAddress, i); guint64 expiry = (guint64) item->timestamp + item->lifetime; if (item->lifetime == G_MAXUINT32) @@ -726,22 +726,22 @@ clean_addresses (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32 if (now >= expiry) { g_array_remove_index (rdata->addresses, i--); - *changed |= NM_RDISC_CONFIG_ADDRESSES; + *changed |= NM_NDISC_CONFIG_ADDRESSES; } else if (*nextevent > expiry) *nextevent = expiry; } } static void -clean_routes (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32 *nextevent) +clean_routes (NMNDisc *ndisc, guint32 now, NMNDiscConfigMap *changed, guint32 *nextevent) { - NMRDiscDataInternal *rdata; + NMNDiscDataInternal *rdata; guint i; - rdata = &NM_RDISC_GET_PRIVATE (rdisc)->rdata; + rdata = &NM_NDISC_GET_PRIVATE (ndisc)->rdata; for (i = 0; i < rdata->routes->len; i++) { - NMRDiscRoute *item = &g_array_index (rdata->routes, NMRDiscRoute, i); + NMNDiscRoute *item = &g_array_index (rdata->routes, NMNDiscRoute, i); guint64 expiry = (guint64) item->timestamp + item->lifetime; if (item->lifetime == G_MAXUINT32) @@ -749,22 +749,22 @@ clean_routes (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32 *n if (now >= expiry) { g_array_remove_index (rdata->routes, i--); - *changed |= NM_RDISC_CONFIG_ROUTES; + *changed |= NM_NDISC_CONFIG_ROUTES; } else if (*nextevent > expiry) *nextevent = expiry; } } static void -clean_dns_servers (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32 *nextevent) +clean_dns_servers (NMNDisc *ndisc, guint32 now, NMNDiscConfigMap *changed, guint32 *nextevent) { - NMRDiscDataInternal *rdata; + NMNDiscDataInternal *rdata; guint i; - rdata = &NM_RDISC_GET_PRIVATE (rdisc)->rdata; + rdata = &NM_NDISC_GET_PRIVATE (ndisc)->rdata; for (i = 0; i < rdata->dns_servers->len; i++) { - NMRDiscDNSServer *item = &g_array_index (rdata->dns_servers, NMRDiscDNSServer, i); + NMNDiscDNSServer *item = &g_array_index (rdata->dns_servers, NMNDiscDNSServer, i); guint64 expiry = (guint64) item->timestamp + item->lifetime; guint64 refresh = (guint64) item->timestamp + item->lifetime / 2; @@ -773,24 +773,24 @@ clean_dns_servers (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint if (now >= expiry) { g_array_remove_index (rdata->dns_servers, i--); - *changed |= NM_RDISC_CONFIG_DNS_SERVERS; + *changed |= NM_NDISC_CONFIG_DNS_SERVERS; } else if (now >= refresh) - solicit (rdisc); + solicit (ndisc); else if (*nextevent > refresh) *nextevent = refresh; } } static void -clean_dns_domains (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint32 *nextevent) +clean_dns_domains (NMNDisc *ndisc, guint32 now, NMNDiscConfigMap *changed, guint32 *nextevent) { - NMRDiscDataInternal *rdata; + NMNDiscDataInternal *rdata; guint i; - rdata = &NM_RDISC_GET_PRIVATE (rdisc)->rdata; + rdata = &NM_NDISC_GET_PRIVATE (ndisc)->rdata; for (i = 0; i < rdata->dns_domains->len; i++) { - NMRDiscDNSDomain *item = &g_array_index (rdata->dns_domains, NMRDiscDNSDomain, i); + NMNDiscDNSDomain *item = &g_array_index (rdata->dns_domains, NMNDiscDNSDomain, i); guint64 expiry = (guint64) item->timestamp + item->lifetime; guint64 refresh = (guint64) item->timestamp + item->lifetime / 2; @@ -799,9 +799,9 @@ clean_dns_domains (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint if (now >= expiry) { g_array_remove_index (rdata->dns_domains, i--); - *changed |= NM_RDISC_CONFIG_DNS_DOMAINS; + *changed |= NM_NDISC_CONFIG_DNS_DOMAINS; } else if (now >= refresh) - solicit (rdisc); + solicit (ndisc); else if (*nextevent > refresh) *nextevent = refresh; } @@ -810,51 +810,51 @@ clean_dns_domains (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap *changed, guint static gboolean timeout_cb (gpointer user_data); static void -check_timestamps (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap changed) +check_timestamps (NMNDisc *ndisc, guint32 now, NMNDiscConfigMap changed) { - NMRDiscPrivate *priv = NM_RDISC_GET_PRIVATE (rdisc); + NMNDiscPrivate *priv = NM_NDISC_GET_PRIVATE (ndisc); /* Use a magic date in the distant future (~68 years) */ guint32 never = G_MAXINT32; guint32 nextevent = never; nm_clear_g_source (&priv->timeout_id); - clean_gateways (rdisc, now, &changed, &nextevent); - clean_addresses (rdisc, now, &changed, &nextevent); - clean_routes (rdisc, now, &changed, &nextevent); - clean_dns_servers (rdisc, now, &changed, &nextevent); - clean_dns_domains (rdisc, now, &changed, &nextevent); + clean_gateways (ndisc, now, &changed, &nextevent); + clean_addresses (ndisc, now, &changed, &nextevent); + clean_routes (ndisc, now, &changed, &nextevent); + clean_dns_servers (ndisc, now, &changed, &nextevent); + clean_dns_domains (ndisc, now, &changed, &nextevent); if (changed) - _emit_config_change (rdisc, changed); + _emit_config_change (ndisc, changed); if (nextevent != never) { g_return_if_fail (nextevent > now); _LOGD ("scheduling next now/lifetime check: %u seconds", nextevent - now); - priv->timeout_id = g_timeout_add_seconds (nextevent - now, timeout_cb, rdisc); + priv->timeout_id = g_timeout_add_seconds (nextevent - now, timeout_cb, ndisc); } } static gboolean timeout_cb (gpointer user_data) { - NMRDisc *self = user_data; + NMNDisc *self = user_data; - NM_RDISC_GET_PRIVATE (self)->timeout_id = 0; + NM_NDISC_GET_PRIVATE (self)->timeout_id = 0; check_timestamps (self, nm_utils_get_monotonic_timestamp_s (), 0); return G_SOURCE_REMOVE; } void -nm_rdisc_ra_received (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap changed) +nm_ndisc_ra_received (NMNDisc *ndisc, guint32 now, NMNDiscConfigMap changed) { - NMRDiscPrivate *priv = NM_RDISC_GET_PRIVATE (rdisc); + NMNDiscPrivate *priv = NM_NDISC_GET_PRIVATE (ndisc); nm_clear_g_source (&priv->ra_timeout_id); nm_clear_g_source (&priv->send_rs_id); g_clear_pointer (&priv->last_send_rs_error, g_free); - check_timestamps (rdisc, now, changed); + check_timestamps (ndisc, now, changed); } /*****************************************************************************/ @@ -862,15 +862,15 @@ nm_rdisc_ra_received (NMRDisc *rdisc, guint32 now, NMRDiscConfigMap changed) static void dns_domain_free (gpointer data) { - g_free (((NMRDiscDNSDomain *)(data))->domain); + g_free (((NMNDiscDNSDomain *)(data))->domain); } static void set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { - NMRDisc *self = NM_RDISC (object); - NMRDiscPrivate *priv = NM_RDISC_GET_PRIVATE (self); + NMNDisc *self = NM_NDISC (object); + NMNDiscPrivate *priv = NM_NDISC_GET_PRIVATE (self); switch (prop_id) { case PROP_PLATFORM: @@ -928,21 +928,21 @@ set_property (GObject *object, guint prop_id, } static void -nm_rdisc_init (NMRDisc *rdisc) +nm_ndisc_init (NMNDisc *ndisc) { - NMRDiscPrivate *priv; - NMRDiscDataInternal *rdata; + NMNDiscPrivate *priv; + NMNDiscDataInternal *rdata; - priv = G_TYPE_INSTANCE_GET_PRIVATE (rdisc, NM_TYPE_RDISC, NMRDiscPrivate); - rdisc->_priv = priv; + priv = G_TYPE_INSTANCE_GET_PRIVATE (ndisc, NM_TYPE_NDISC, NMNDiscPrivate); + ndisc->_priv = priv; rdata = &priv->rdata; - rdata->gateways = g_array_new (FALSE, FALSE, sizeof (NMRDiscGateway)); - rdata->addresses = g_array_new (FALSE, FALSE, sizeof (NMRDiscAddress)); - rdata->routes = g_array_new (FALSE, FALSE, sizeof (NMRDiscRoute)); - rdata->dns_servers = g_array_new (FALSE, FALSE, sizeof (NMRDiscDNSServer)); - rdata->dns_domains = g_array_new (FALSE, FALSE, sizeof (NMRDiscDNSDomain)); + rdata->gateways = g_array_new (FALSE, FALSE, sizeof (NMNDiscGateway)); + rdata->addresses = g_array_new (FALSE, FALSE, sizeof (NMNDiscAddress)); + rdata->routes = g_array_new (FALSE, FALSE, sizeof (NMNDiscRoute)); + rdata->dns_servers = g_array_new (FALSE, FALSE, sizeof (NMNDiscDNSServer)); + rdata->dns_domains = g_array_new (FALSE, FALSE, sizeof (NMNDiscDNSDomain)); g_array_set_clear_func (rdata->dns_domains, dns_domain_free); priv->rdata.public.hop_limit = 64; @@ -955,8 +955,8 @@ nm_rdisc_init (NMRDisc *rdisc) static void dispose (GObject *object) { - NMRDisc *rdisc = NM_RDISC (object); - NMRDiscPrivate *priv = NM_RDISC_GET_PRIVATE (rdisc); + NMNDisc *ndisc = NM_NDISC (object); + NMNDiscPrivate *priv = NM_NDISC_GET_PRIVATE (ndisc); nm_clear_g_source (&priv->ra_timeout_id); nm_clear_g_source (&priv->send_rs_id); @@ -964,15 +964,15 @@ dispose (GObject *object) nm_clear_g_source (&priv->timeout_id); - G_OBJECT_CLASS (nm_rdisc_parent_class)->dispose (object); + G_OBJECT_CLASS (nm_ndisc_parent_class)->dispose (object); } static void finalize (GObject *object) { - NMRDisc *rdisc = NM_RDISC (object); - NMRDiscPrivate *priv = NM_RDISC_GET_PRIVATE (rdisc); - NMRDiscDataInternal *rdata = &priv->rdata; + NMNDisc *ndisc = NM_NDISC (object); + NMNDiscPrivate *priv = NM_NDISC_GET_PRIVATE (ndisc); + NMNDiscDataInternal *rdata = &priv->rdata; g_free (priv->ifname); g_free (priv->network_id); @@ -986,85 +986,85 @@ finalize (GObject *object) g_clear_object (&priv->netns); g_clear_object (&priv->platform); - G_OBJECT_CLASS (nm_rdisc_parent_class)->finalize (object); + G_OBJECT_CLASS (nm_ndisc_parent_class)->finalize (object); } static void -nm_rdisc_class_init (NMRDiscClass *klass) +nm_ndisc_class_init (NMNDiscClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); - g_type_class_add_private (klass, sizeof (NMRDiscPrivate)); + g_type_class_add_private (klass, sizeof (NMNDiscPrivate)); object_class->set_property = set_property; object_class->dispose = dispose; object_class->finalize = finalize; obj_properties[PROP_PLATFORM] = - g_param_spec_object (NM_RDISC_PLATFORM, "", "", + g_param_spec_object (NM_NDISC_PLATFORM, "", "", NM_TYPE_PLATFORM, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); obj_properties[PROP_IFINDEX] = - g_param_spec_int (NM_RDISC_IFINDEX, "", "", + g_param_spec_int (NM_NDISC_IFINDEX, "", "", 0, G_MAXINT, 0, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); obj_properties[PROP_IFNAME] = - g_param_spec_string (NM_RDISC_IFNAME, "", "", + g_param_spec_string (NM_NDISC_IFNAME, "", "", NULL, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); obj_properties[PROP_STABLE_TYPE] = - g_param_spec_int (NM_RDISC_STABLE_TYPE, "", "", + g_param_spec_int (NM_NDISC_STABLE_TYPE, "", "", NM_UTILS_STABLE_TYPE_UUID, NM_UTILS_STABLE_TYPE_STABLE_ID, NM_UTILS_STABLE_TYPE_UUID, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); obj_properties[PROP_NETWORK_ID] = - g_param_spec_string (NM_RDISC_NETWORK_ID, "", "", + g_param_spec_string (NM_NDISC_NETWORK_ID, "", "", NULL, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); obj_properties[PROP_ADDR_GEN_MODE] = - g_param_spec_int (NM_RDISC_ADDR_GEN_MODE, "", "", + g_param_spec_int (NM_NDISC_ADDR_GEN_MODE, "", "", NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64, NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY, NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); obj_properties[PROP_MAX_ADDRESSES] = - g_param_spec_int (NM_RDISC_MAX_ADDRESSES, "", "", - 0, G_MAXINT32, NM_RDISC_MAX_ADDRESSES_DEFAULT, + g_param_spec_int (NM_NDISC_MAX_ADDRESSES, "", "", + 0, G_MAXINT32, NM_NDISC_MAX_ADDRESSES_DEFAULT, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); obj_properties[PROP_ROUTER_SOLICITATIONS] = - g_param_spec_int (NM_RDISC_ROUTER_SOLICITATIONS, "", "", - 1, G_MAXINT32, NM_RDISC_ROUTER_SOLICITATIONS_DEFAULT, + g_param_spec_int (NM_NDISC_ROUTER_SOLICITATIONS, "", "", + 1, G_MAXINT32, NM_NDISC_ROUTER_SOLICITATIONS_DEFAULT, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); obj_properties[PROP_ROUTER_SOLICITATION_INTERVAL] = - g_param_spec_int (NM_RDISC_ROUTER_SOLICITATION_INTERVAL, "", "", - 1, G_MAXINT32, NM_RDISC_ROUTER_SOLICITATION_INTERVAL_DEFAULT, + g_param_spec_int (NM_NDISC_ROUTER_SOLICITATION_INTERVAL, "", "", + 1, G_MAXINT32, NM_NDISC_ROUTER_SOLICITATION_INTERVAL_DEFAULT, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); signals[CONFIG_CHANGED] = - g_signal_new (NM_RDISC_CONFIG_CHANGED, + g_signal_new (NM_NDISC_CONFIG_CHANGED, G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_FIRST, 0, NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_POINTER, G_TYPE_UINT); signals[RA_TIMEOUT] = - g_signal_new (NM_RDISC_RA_TIMEOUT, + g_signal_new (NM_NDISC_RA_TIMEOUT, G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_FIRST, 0, diff --git a/src/ndisc/nm-ndisc.h b/src/ndisc/nm-ndisc.h new file mode 100644 index 0000000000..8861a17be1 --- /dev/null +++ b/src/ndisc/nm-ndisc.h @@ -0,0 +1,170 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ +/* nm-ndisc.h - Perform IPv6 neighbor discovery + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Copyright (C) 2013 Red Hat, Inc. + */ + +#ifndef __NETWORKMANAGER_NDISC_H__ +#define __NETWORKMANAGER_NDISC_H__ + +#include +#include + +#include "nm-setting-ip6-config.h" +#include "NetworkManagerUtils.h" + +#define NM_TYPE_NDISC (nm_ndisc_get_type ()) +#define NM_NDISC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_NDISC, NMNDisc)) +#define NM_NDISC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_NDISC, NMNDiscClass)) +#define NM_IS_NDISC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_NDISC)) +#define NM_IS_NDISC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_NDISC)) +#define NM_NDISC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_NDISC, NMNDiscClass)) + +#define NM_NDISC_PLATFORM "platform" +#define NM_NDISC_IFINDEX "ifindex" +#define NM_NDISC_IFNAME "ifname" +#define NM_NDISC_NETWORK_ID "network-id" +#define NM_NDISC_ADDR_GEN_MODE "addr-gen-mode" +#define NM_NDISC_STABLE_TYPE "stable-type" +#define NM_NDISC_MAX_ADDRESSES "max-addresses" +#define NM_NDISC_ROUTER_SOLICITATIONS "router-solicitations" +#define NM_NDISC_ROUTER_SOLICITATION_INTERVAL "router-solicitation-interval" + +#define NM_NDISC_CONFIG_CHANGED "config-changed" +#define NM_NDISC_RA_TIMEOUT "ra-timeout" + +typedef enum { + NM_NDISC_DHCP_LEVEL_UNKNOWN, + NM_NDISC_DHCP_LEVEL_NONE, + NM_NDISC_DHCP_LEVEL_OTHERCONF, + NM_NDISC_DHCP_LEVEL_MANAGED +} NMNDiscDHCPLevel; + +typedef enum { + NM_NDISC_PREFERENCE_INVALID, + NM_NDISC_PREFERENCE_LOW, + NM_NDISC_PREFERENCE_MEDIUM, + NM_NDISC_PREFERENCE_HIGH +} NMNDiscPreference; + +typedef struct { + struct in6_addr address; + guint32 timestamp; + guint32 lifetime; + NMNDiscPreference preference; +} NMNDiscGateway; + +typedef struct { + struct in6_addr address; + guint8 dad_counter; + guint32 timestamp; + guint32 lifetime; + guint32 preferred; +} NMNDiscAddress; + +typedef struct { + struct in6_addr network; + guint8 plen; + struct in6_addr gateway; + guint32 timestamp; + guint32 lifetime; + NMNDiscPreference preference; +} NMNDiscRoute; + +typedef struct { + struct in6_addr address; + guint32 timestamp; + guint32 lifetime; +} NMNDiscDNSServer; + +typedef struct { + char *domain; + guint32 timestamp; + guint32 lifetime; +} NMNDiscDNSDomain; + +typedef enum { + NM_NDISC_CONFIG_DHCP_LEVEL = 1 << 0, + NM_NDISC_CONFIG_GATEWAYS = 1 << 1, + NM_NDISC_CONFIG_ADDRESSES = 1 << 2, + NM_NDISC_CONFIG_ROUTES = 1 << 3, + NM_NDISC_CONFIG_DNS_SERVERS = 1 << 4, + NM_NDISC_CONFIG_DNS_DOMAINS = 1 << 5, + NM_NDISC_CONFIG_HOP_LIMIT = 1 << 6, + NM_NDISC_CONFIG_MTU = 1 << 7, +} NMNDiscConfigMap; + +#define NM_NDISC_MAX_ADDRESSES_DEFAULT 16 +#define NM_NDISC_ROUTER_SOLICITATIONS_DEFAULT 3 +#define NM_NDISC_ROUTER_SOLICITATION_INTERVAL_DEFAULT 4 + +struct _NMNDiscPrivate; +struct _NMNDiscDataInternal; + +typedef struct { + NMNDiscDHCPLevel dhcp_level; + guint32 mtu; + int hop_limit; + + guint gateways_n; + guint addresses_n; + guint routes_n; + guint dns_servers_n; + guint dns_domains_n; + + const NMNDiscGateway *gateways; + const NMNDiscAddress *addresses; + const NMNDiscRoute *routes; + const NMNDiscDNSServer *dns_servers; + const NMNDiscDNSDomain *dns_domains; +} NMNDiscData; + +/** + * NMNDisc: + * + * Interface-specific structure that handles incoming router advertisements, + * caches advertised items and removes them when they are obsolete. + */ +typedef struct { + GObject parent; + union { + struct _NMNDiscPrivate *_priv; + struct _NMNDiscDataInternal *rdata; + }; +} NMNDisc; + +typedef struct { + GObjectClass parent; + + void (*start) (NMNDisc *ndisc); + gboolean (*send_rs) (NMNDisc *ndisc, GError **error); +} NMNDiscClass; + +GType nm_ndisc_get_type (void); + +int nm_ndisc_get_ifindex (NMNDisc *self); +const char *nm_ndisc_get_ifname (NMNDisc *self); + +gboolean nm_ndisc_set_iid (NMNDisc *ndisc, const NMUtilsIPv6IfaceId iid); +void nm_ndisc_start (NMNDisc *ndisc); +void nm_ndisc_dad_failed (NMNDisc *ndisc, struct in6_addr *address); + +NMPlatform *nm_ndisc_get_platform (NMNDisc *self); +NMPNetns *nm_ndisc_netns_get (NMNDisc *self); +gboolean nm_ndisc_netns_push (NMNDisc *self, NMPNetns **netns); + +#endif /* __NETWORKMANAGER_NDISC_H__ */ diff --git a/src/ndisc/tests/.gitignore b/src/ndisc/tests/.gitignore new file mode 100644 index 0000000000..605f4b0125 --- /dev/null +++ b/src/ndisc/tests/.gitignore @@ -0,0 +1 @@ +/ndisc diff --git a/src/rdisc/tests/test-rdisc-fake.c b/src/ndisc/tests/test-ndisc-fake.c similarity index 60% rename from src/rdisc/tests/test-rdisc-fake.c rename to src/ndisc/tests/test-ndisc-fake.c index 02ffb5100e..09644232cc 100644 --- a/src/rdisc/tests/test-rdisc-fake.c +++ b/src/ndisc/tests/test-ndisc-fake.c @@ -1,5 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* rdisc.c - test program +/* ndisc.c - test program * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,32 +23,32 @@ #include #include -#include "nm-rdisc.h" -#include "nm-fake-rdisc.h" +#include "nm-ndisc.h" +#include "nm-fake-ndisc.h" #include "nm-fake-platform.h" #include "nm-test-utils-core.h" -static NMFakeRDisc * -rdisc_new (void) +static NMFakeNDisc * +ndisc_new (void) { - NMRDisc *rdisc; + NMNDisc *ndisc; const int ifindex = 1; const char *ifname = nm_platform_link_get_name (NM_PLATFORM_GET, ifindex); NMUtilsIPv6IfaceId iid = { }; - rdisc = nm_fake_rdisc_new (ifindex, ifname); + ndisc = nm_fake_ndisc_new (ifindex, ifname); iid.id_u8[7] = 1; - nm_rdisc_set_iid (rdisc, iid); - g_assert (rdisc); - return NM_FAKE_RDISC (rdisc); + nm_ndisc_set_iid (ndisc, iid); + g_assert (ndisc); + return NM_FAKE_NDISC (ndisc); } static void -match_gateway (const NMRDiscData *rdata, guint idx, const char *addr, guint32 ts, guint32 lt, NMRDiscPreference pref) +match_gateway (const NMNDiscData *rdata, guint idx, const char *addr, guint32 ts, guint32 lt, NMNDiscPreference pref) { - const NMRDiscGateway *gw; + const NMNDiscGateway *gw; char buf[INET6_ADDRSTRLEN]; g_assert (rdata); @@ -64,9 +64,9 @@ match_gateway (const NMRDiscData *rdata, guint idx, const char *addr, guint32 ts } static void -match_address (const NMRDiscData *rdata, guint idx, const char *addr, guint32 ts, guint32 lt, guint32 preferred) +match_address (const NMNDiscData *rdata, guint idx, const char *addr, guint32 ts, guint32 lt, guint32 preferred) { - const NMRDiscAddress *a; + const NMNDiscAddress *a; char buf[INET6_ADDRSTRLEN]; g_assert (rdata); @@ -82,9 +82,9 @@ match_address (const NMRDiscData *rdata, guint idx, const char *addr, guint32 ts } static void -match_route (const NMRDiscData *rdata, guint idx, const char *nw, int plen, const char *gw, guint32 ts, guint32 lt, NMRDiscPreference pref) +match_route (const NMNDiscData *rdata, guint idx, const char *nw, int plen, const char *gw, guint32 ts, guint32 lt, NMNDiscPreference pref) { - const NMRDiscRoute *route; + const NMNDiscRoute *route; char buf[INET6_ADDRSTRLEN]; g_assert (rdata); @@ -103,9 +103,9 @@ match_route (const NMRDiscData *rdata, guint idx, const char *nw, int plen, cons } static void -match_dns_server (const NMRDiscData *rdata, guint idx, const char *addr, guint32 ts, guint32 lt) +match_dns_server (const NMNDiscData *rdata, guint idx, const char *addr, guint32 ts, guint32 lt) { - const NMRDiscDNSServer *dns; + const NMNDiscDNSServer *dns; char buf[INET6_ADDRSTRLEN]; g_assert (rdata); @@ -120,9 +120,9 @@ match_dns_server (const NMRDiscData *rdata, guint idx, const char *addr, guint32 } static void -match_dns_domain (const NMRDiscData *rdata, guint idx, const char *domain, guint32 ts, guint32 lt) +match_dns_domain (const NMNDiscData *rdata, guint idx, const char *domain, guint32 ts, guint32 lt) { - const NMRDiscDNSDomain *dns; + const NMNDiscDNSDomain *dns; g_assert (rdata); g_assert_cmpint (idx, <, rdata->dns_domains_n); @@ -145,26 +145,26 @@ typedef struct { } TestData; static void -test_simple_changed (NMRDisc *rdisc, const NMRDiscData *rdata, guint changed_int, TestData *data) +test_simple_changed (NMNDisc *ndisc, const NMNDiscData *rdata, guint changed_int, TestData *data) { - NMRDiscConfigMap changed = changed_int; + NMNDiscConfigMap changed = changed_int; - g_assert_cmpint (changed, ==, NM_RDISC_CONFIG_DHCP_LEVEL | - NM_RDISC_CONFIG_GATEWAYS | - NM_RDISC_CONFIG_ADDRESSES | - NM_RDISC_CONFIG_ROUTES | - NM_RDISC_CONFIG_DNS_SERVERS | - NM_RDISC_CONFIG_DNS_DOMAINS | - NM_RDISC_CONFIG_HOP_LIMIT | - NM_RDISC_CONFIG_MTU); - g_assert_cmpint (rdata->dhcp_level, ==, NM_RDISC_DHCP_LEVEL_OTHERCONF); - match_gateway (rdata, 0, "fe80::1", data->timestamp1, 10, NM_RDISC_PREFERENCE_MEDIUM); + g_assert_cmpint (changed, ==, NM_NDISC_CONFIG_DHCP_LEVEL | + NM_NDISC_CONFIG_GATEWAYS | + NM_NDISC_CONFIG_ADDRESSES | + NM_NDISC_CONFIG_ROUTES | + NM_NDISC_CONFIG_DNS_SERVERS | + NM_NDISC_CONFIG_DNS_DOMAINS | + NM_NDISC_CONFIG_HOP_LIMIT | + NM_NDISC_CONFIG_MTU); + g_assert_cmpint (rdata->dhcp_level, ==, NM_NDISC_DHCP_LEVEL_OTHERCONF); + match_gateway (rdata, 0, "fe80::1", data->timestamp1, 10, NM_NDISC_PREFERENCE_MEDIUM); match_address (rdata, 0, "2001:db8:a:a::1", data->timestamp1, 10, 10); match_route (rdata, 0, "2001:db8:a:a::", 64, "fe80::1", data->timestamp1, 10, 10); match_dns_server (rdata, 0, "2001:db8:c:c::1", data->timestamp1, 10); match_dns_domain (rdata, 0, "foobar.com", data->timestamp1, 10); - g_assert (nm_fake_rdisc_done (NM_FAKE_RDISC (rdisc))); + g_assert (nm_fake_ndisc_done (NM_FAKE_NDISC (ndisc))); data->counter++; g_main_loop_quit (data->loop); } @@ -172,67 +172,67 @@ test_simple_changed (NMRDisc *rdisc, const NMRDiscData *rdata, guint changed_int static void test_simple (void) { - NMFakeRDisc *rdisc = rdisc_new (); + NMFakeNDisc *ndisc = ndisc_new (); guint32 now = nm_utils_get_monotonic_timestamp_s (); TestData data = { g_main_loop_new (NULL, FALSE), 0, 0, now }; guint id; - id = nm_fake_rdisc_add_ra (rdisc, 1, NM_RDISC_DHCP_LEVEL_OTHERCONF, 4, 1500); + id = nm_fake_ndisc_add_ra (ndisc, 1, NM_NDISC_DHCP_LEVEL_OTHERCONF, 4, 1500); g_assert (id); - nm_fake_rdisc_add_gateway (rdisc, id, "fe80::1", now, 10, NM_RDISC_PREFERENCE_MEDIUM); - nm_fake_rdisc_add_prefix (rdisc, id, "2001:db8:a:a::", 64, "fe80::1", now, 10, 10, 10); - nm_fake_rdisc_add_dns_server (rdisc, id, "2001:db8:c:c::1", now, 10); - nm_fake_rdisc_add_dns_domain (rdisc, id, "foobar.com", now, 10); + nm_fake_ndisc_add_gateway (ndisc, id, "fe80::1", now, 10, NM_NDISC_PREFERENCE_MEDIUM); + nm_fake_ndisc_add_prefix (ndisc, id, "2001:db8:a:a::", 64, "fe80::1", now, 10, 10, 10); + nm_fake_ndisc_add_dns_server (ndisc, id, "2001:db8:c:c::1", now, 10); + nm_fake_ndisc_add_dns_domain (ndisc, id, "foobar.com", now, 10); - g_signal_connect (rdisc, - NM_RDISC_CONFIG_CHANGED, + g_signal_connect (ndisc, + NM_NDISC_CONFIG_CHANGED, G_CALLBACK (test_simple_changed), &data); - nm_rdisc_start (NM_RDISC (rdisc)); + nm_ndisc_start (NM_NDISC (ndisc)); g_main_loop_run (data.loop); g_assert_cmpint (data.counter, ==, 1); - g_object_unref (rdisc); + g_object_unref (ndisc); g_main_loop_unref (data.loop); } static void -test_everything_rs_sent (NMRDisc *rdisc, TestData *data) +test_everything_rs_sent (NMNDisc *ndisc, TestData *data) { g_assert_cmpint (data->rs_counter, ==, 0); data->rs_counter++; } static void -test_everything_changed (NMRDisc *rdisc, const NMRDiscData *rdata, guint changed_int, TestData *data) +test_everything_changed (NMNDisc *ndisc, const NMNDiscData *rdata, guint changed_int, TestData *data) { - NMRDiscConfigMap changed = changed_int; + NMNDiscConfigMap changed = changed_int; if (data->counter == 0) { g_assert_cmpint (data->rs_counter, ==, 1); - g_assert_cmpint (changed, ==, NM_RDISC_CONFIG_DHCP_LEVEL | - NM_RDISC_CONFIG_GATEWAYS | - NM_RDISC_CONFIG_ADDRESSES | - NM_RDISC_CONFIG_ROUTES | - NM_RDISC_CONFIG_DNS_SERVERS | - NM_RDISC_CONFIG_DNS_DOMAINS | - NM_RDISC_CONFIG_HOP_LIMIT | - NM_RDISC_CONFIG_MTU); - match_gateway (rdata, 0, "fe80::1", data->timestamp1, 10, NM_RDISC_PREFERENCE_MEDIUM); + g_assert_cmpint (changed, ==, NM_NDISC_CONFIG_DHCP_LEVEL | + NM_NDISC_CONFIG_GATEWAYS | + NM_NDISC_CONFIG_ADDRESSES | + NM_NDISC_CONFIG_ROUTES | + NM_NDISC_CONFIG_DNS_SERVERS | + NM_NDISC_CONFIG_DNS_DOMAINS | + NM_NDISC_CONFIG_HOP_LIMIT | + NM_NDISC_CONFIG_MTU); + match_gateway (rdata, 0, "fe80::1", data->timestamp1, 10, NM_NDISC_PREFERENCE_MEDIUM); match_address (rdata, 0, "2001:db8:a:a::1", data->timestamp1, 10, 10); match_route (rdata, 0, "2001:db8:a:a::", 64, "fe80::1", data->timestamp1, 10, 10); match_dns_server (rdata, 0, "2001:db8:c:c::1", data->timestamp1, 10); match_dns_domain (rdata, 0, "foobar.com", data->timestamp1, 10); } else if (data->counter == 1) { - g_assert_cmpint (changed, ==, NM_RDISC_CONFIG_GATEWAYS | - NM_RDISC_CONFIG_ADDRESSES | - NM_RDISC_CONFIG_ROUTES | - NM_RDISC_CONFIG_DNS_SERVERS | - NM_RDISC_CONFIG_DNS_DOMAINS); + g_assert_cmpint (changed, ==, NM_NDISC_CONFIG_GATEWAYS | + NM_NDISC_CONFIG_ADDRESSES | + NM_NDISC_CONFIG_ROUTES | + NM_NDISC_CONFIG_DNS_SERVERS | + NM_NDISC_CONFIG_DNS_DOMAINS); g_assert_cmpint (rdata->gateways_n, ==, 1); - match_gateway (rdata, 0, "fe80::2", data->timestamp1, 10, NM_RDISC_PREFERENCE_MEDIUM); + match_gateway (rdata, 0, "fe80::2", data->timestamp1, 10, NM_NDISC_PREFERENCE_MEDIUM); g_assert_cmpint (rdata->addresses_n, ==, 1); match_address (rdata, 0, "2001:db8:a:b::1", data->timestamp1, 10, 10); g_assert_cmpint (rdata->routes_n, ==, 1); @@ -242,7 +242,7 @@ test_everything_changed (NMRDisc *rdisc, const NMRDiscData *rdata, guint changed g_assert_cmpint (rdata->dns_domains_n, ==, 1); match_dns_domain (rdata, 0, "foobar2.com", data->timestamp1, 10); - g_assert (nm_fake_rdisc_done (NM_FAKE_RDISC (rdisc))); + g_assert (nm_fake_ndisc_done (NM_FAKE_NDISC (ndisc))); g_main_loop_quit (data->loop); } else g_assert_not_reached (); @@ -253,62 +253,62 @@ test_everything_changed (NMRDisc *rdisc, const NMRDiscData *rdata, guint changed static void test_everything (void) { - NMFakeRDisc *rdisc = rdisc_new (); + NMFakeNDisc *ndisc = ndisc_new (); guint32 now = nm_utils_get_monotonic_timestamp_s (); TestData data = { g_main_loop_new (NULL, FALSE), 0, 0, now }; guint id; - id = nm_fake_rdisc_add_ra (rdisc, 1, NM_RDISC_DHCP_LEVEL_NONE, 4, 1500); + id = nm_fake_ndisc_add_ra (ndisc, 1, NM_NDISC_DHCP_LEVEL_NONE, 4, 1500); g_assert (id); - nm_fake_rdisc_add_gateway (rdisc, id, "fe80::1", now, 10, NM_RDISC_PREFERENCE_MEDIUM); - nm_fake_rdisc_add_prefix (rdisc, id, "2001:db8:a:a::", 64, "fe80::1", now, 10, 10, 10); - nm_fake_rdisc_add_dns_server (rdisc, id, "2001:db8:c:c::1", now, 10); - nm_fake_rdisc_add_dns_domain (rdisc, id, "foobar.com", now, 10); + nm_fake_ndisc_add_gateway (ndisc, id, "fe80::1", now, 10, NM_NDISC_PREFERENCE_MEDIUM); + nm_fake_ndisc_add_prefix (ndisc, id, "2001:db8:a:a::", 64, "fe80::1", now, 10, 10, 10); + nm_fake_ndisc_add_dns_server (ndisc, id, "2001:db8:c:c::1", now, 10); + nm_fake_ndisc_add_dns_domain (ndisc, id, "foobar.com", now, 10); /* expire everything from the first RA in the second */ - id = nm_fake_rdisc_add_ra (rdisc, 1, NM_RDISC_DHCP_LEVEL_NONE, 4, 1500); + id = nm_fake_ndisc_add_ra (ndisc, 1, NM_NDISC_DHCP_LEVEL_NONE, 4, 1500); g_assert (id); - nm_fake_rdisc_add_gateway (rdisc, id, "fe80::1", now, 0, NM_RDISC_PREFERENCE_MEDIUM); - nm_fake_rdisc_add_prefix (rdisc, id, "2001:db8:a:a::", 64, "fe80::1", now, 0, 0, 0); - nm_fake_rdisc_add_dns_server (rdisc, id, "2001:db8:c:c::1", now, 0); - nm_fake_rdisc_add_dns_domain (rdisc, id, "foobar.com", now, 0); + nm_fake_ndisc_add_gateway (ndisc, id, "fe80::1", now, 0, NM_NDISC_PREFERENCE_MEDIUM); + nm_fake_ndisc_add_prefix (ndisc, id, "2001:db8:a:a::", 64, "fe80::1", now, 0, 0, 0); + nm_fake_ndisc_add_dns_server (ndisc, id, "2001:db8:c:c::1", now, 0); + nm_fake_ndisc_add_dns_domain (ndisc, id, "foobar.com", now, 0); /* and add some new stuff */ - nm_fake_rdisc_add_gateway (rdisc, id, "fe80::2", now, 10, NM_RDISC_PREFERENCE_MEDIUM); - nm_fake_rdisc_add_prefix (rdisc, id, "2001:db8:a:b::", 64, "fe80::2", now, 10, 10, 10); - nm_fake_rdisc_add_dns_server (rdisc, id, "2001:db8:c:c::2", now, 10); - nm_fake_rdisc_add_dns_domain (rdisc, id, "foobar2.com", now, 10); + nm_fake_ndisc_add_gateway (ndisc, id, "fe80::2", now, 10, NM_NDISC_PREFERENCE_MEDIUM); + nm_fake_ndisc_add_prefix (ndisc, id, "2001:db8:a:b::", 64, "fe80::2", now, 10, 10, 10); + nm_fake_ndisc_add_dns_server (ndisc, id, "2001:db8:c:c::2", now, 10); + nm_fake_ndisc_add_dns_domain (ndisc, id, "foobar2.com", now, 10); - g_signal_connect (rdisc, - NM_RDISC_CONFIG_CHANGED, + g_signal_connect (ndisc, + NM_NDISC_CONFIG_CHANGED, G_CALLBACK (test_everything_changed), &data); - g_signal_connect (rdisc, - NM_FAKE_RDISC_RS_SENT, + g_signal_connect (ndisc, + NM_FAKE_NDISC_RS_SENT, G_CALLBACK (test_everything_rs_sent), &data); - nm_rdisc_start (NM_RDISC (rdisc)); + nm_ndisc_start (NM_NDISC (ndisc)); g_main_loop_run (data.loop); g_assert_cmpint (data.counter, ==, 2); g_assert_cmpint (data.rs_counter, ==, 1); - g_object_unref (rdisc); + g_object_unref (ndisc); g_main_loop_unref (data.loop); } static void -test_preference_changed (NMRDisc *rdisc, const NMRDiscData *rdata, guint changed_int, TestData *data) +test_preference_changed (NMNDisc *ndisc, const NMNDiscData *rdata, guint changed_int, TestData *data) { - NMRDiscConfigMap changed = changed_int; + NMNDiscConfigMap changed = changed_int; if (data->counter == 1) { - g_assert_cmpint (changed, ==, NM_RDISC_CONFIG_GATEWAYS | - NM_RDISC_CONFIG_ADDRESSES | - NM_RDISC_CONFIG_ROUTES); + g_assert_cmpint (changed, ==, NM_NDISC_CONFIG_GATEWAYS | + NM_NDISC_CONFIG_ADDRESSES | + NM_NDISC_CONFIG_ROUTES); g_assert_cmpint (rdata->gateways_n, ==, 2); - match_gateway (rdata, 0, "fe80::2", data->timestamp1 + 1, 10, NM_RDISC_PREFERENCE_MEDIUM); - match_gateway (rdata, 1, "fe80::1", data->timestamp1, 10, NM_RDISC_PREFERENCE_LOW); + match_gateway (rdata, 0, "fe80::2", data->timestamp1 + 1, 10, NM_NDISC_PREFERENCE_MEDIUM); + match_gateway (rdata, 1, "fe80::1", data->timestamp1, 10, NM_NDISC_PREFERENCE_LOW); g_assert_cmpint (rdata->addresses_n, ==, 2); match_address (rdata, 0, "2001:db8:a:a::1", data->timestamp1, 10, 10); match_address (rdata, 1, "2001:db8:a:b::1", data->timestamp1 + 1, 10, 10); @@ -316,13 +316,13 @@ test_preference_changed (NMRDisc *rdisc, const NMRDiscData *rdata, guint changed match_route (rdata, 0, "2001:db8:a:b::", 64, "fe80::2", data->timestamp1 + 1, 10, 10); match_route (rdata, 1, "2001:db8:a:a::", 64, "fe80::1", data->timestamp1, 10, 5); } else if (data->counter == 2) { - g_assert_cmpint (changed, ==, NM_RDISC_CONFIG_GATEWAYS | - NM_RDISC_CONFIG_ADDRESSES | - NM_RDISC_CONFIG_ROUTES); + g_assert_cmpint (changed, ==, NM_NDISC_CONFIG_GATEWAYS | + NM_NDISC_CONFIG_ADDRESSES | + NM_NDISC_CONFIG_ROUTES); g_assert_cmpint (rdata->gateways_n, ==, 2); - match_gateway (rdata, 0, "fe80::1", data->timestamp1 + 2, 10, NM_RDISC_PREFERENCE_HIGH); - match_gateway (rdata, 1, "fe80::2", data->timestamp1 + 1, 10, NM_RDISC_PREFERENCE_MEDIUM); + match_gateway (rdata, 0, "fe80::1", data->timestamp1 + 2, 10, NM_NDISC_PREFERENCE_HIGH); + match_gateway (rdata, 1, "fe80::2", data->timestamp1 + 1, 10, NM_NDISC_PREFERENCE_MEDIUM); g_assert_cmpint (rdata->addresses_n, ==, 2); match_address (rdata, 0, "2001:db8:a:a::1", data->timestamp1 + 2, 10, 10); match_address (rdata, 1, "2001:db8:a:b::1", data->timestamp1 + 1, 10, 10); @@ -330,7 +330,7 @@ test_preference_changed (NMRDisc *rdisc, const NMRDiscData *rdata, guint changed match_route (rdata, 0, "2001:db8:a:a::", 64, "fe80::1", data->timestamp1 + 2, 10, 15); match_route (rdata, 1, "2001:db8:a:b::", 64, "fe80::2", data->timestamp1 + 1, 10, 10); - g_assert (nm_fake_rdisc_done (NM_FAKE_RDISC (rdisc))); + g_assert (nm_fake_ndisc_done (NM_FAKE_NDISC (ndisc))); g_main_loop_quit (data->loop); } @@ -340,7 +340,7 @@ test_preference_changed (NMRDisc *rdisc, const NMRDiscData *rdata, guint changed static void test_preference (void) { - NMFakeRDisc *rdisc = rdisc_new (); + NMFakeNDisc *ndisc = ndisc_new (); guint32 now = nm_utils_get_monotonic_timestamp_s (); TestData data = { g_main_loop_new (NULL, FALSE), 0, 0, now }; guint id; @@ -350,36 +350,36 @@ test_preference (void) * not get duplicates in the gateway list. */ - id = nm_fake_rdisc_add_ra (rdisc, 1, NM_RDISC_DHCP_LEVEL_NONE, 4, 1500); + id = nm_fake_ndisc_add_ra (ndisc, 1, NM_NDISC_DHCP_LEVEL_NONE, 4, 1500); g_assert (id); - nm_fake_rdisc_add_gateway (rdisc, id, "fe80::1", now, 10, NM_RDISC_PREFERENCE_LOW); - nm_fake_rdisc_add_prefix (rdisc, id, "2001:db8:a:a::", 64, "fe80::1", now, 10, 10, 5); + nm_fake_ndisc_add_gateway (ndisc, id, "fe80::1", now, 10, NM_NDISC_PREFERENCE_LOW); + nm_fake_ndisc_add_prefix (ndisc, id, "2001:db8:a:a::", 64, "fe80::1", now, 10, 10, 5); - id = nm_fake_rdisc_add_ra (rdisc, 1, NM_RDISC_DHCP_LEVEL_NONE, 4, 1500); + id = nm_fake_ndisc_add_ra (ndisc, 1, NM_NDISC_DHCP_LEVEL_NONE, 4, 1500); g_assert (id); - nm_fake_rdisc_add_gateway (rdisc, id, "fe80::2", ++now, 10, NM_RDISC_PREFERENCE_MEDIUM); - nm_fake_rdisc_add_prefix (rdisc, id, "2001:db8:a:b::", 64, "fe80::2", now, 10, 10, 10); + nm_fake_ndisc_add_gateway (ndisc, id, "fe80::2", ++now, 10, NM_NDISC_PREFERENCE_MEDIUM); + nm_fake_ndisc_add_prefix (ndisc, id, "2001:db8:a:b::", 64, "fe80::2", now, 10, 10, 10); - id = nm_fake_rdisc_add_ra (rdisc, 1, NM_RDISC_DHCP_LEVEL_NONE, 4, 1500); + id = nm_fake_ndisc_add_ra (ndisc, 1, NM_NDISC_DHCP_LEVEL_NONE, 4, 1500); g_assert (id); - nm_fake_rdisc_add_gateway (rdisc, id, "fe80::1", ++now, 10, NM_RDISC_PREFERENCE_HIGH); - nm_fake_rdisc_add_prefix (rdisc, id, "2001:db8:a:a::", 64, "fe80::1", now, 10, 10, 15); + nm_fake_ndisc_add_gateway (ndisc, id, "fe80::1", ++now, 10, NM_NDISC_PREFERENCE_HIGH); + nm_fake_ndisc_add_prefix (ndisc, id, "2001:db8:a:a::", 64, "fe80::1", now, 10, 10, 15); - g_signal_connect (rdisc, - NM_RDISC_CONFIG_CHANGED, + g_signal_connect (ndisc, + NM_NDISC_CONFIG_CHANGED, G_CALLBACK (test_preference_changed), &data); - nm_rdisc_start (NM_RDISC (rdisc)); + nm_ndisc_start (NM_NDISC (ndisc)); g_main_loop_run (data.loop); g_assert_cmpint (data.counter, ==, 3); - g_object_unref (rdisc); + g_object_unref (ndisc); g_main_loop_unref (data.loop); } static void -test_dns_solicit_loop_changed (NMRDisc *rdisc, const NMRDiscData *rdata, guint changed_int, TestData *data) +test_dns_solicit_loop_changed (NMNDisc *ndisc, const NMNDiscData *rdata, guint changed_int, TestData *data) { data->counter++; } @@ -393,7 +393,7 @@ success_timeout (TestData *data) } static void -test_dns_solicit_loop_rs_sent (NMFakeRDisc *rdisc, TestData *data) +test_dns_solicit_loop_rs_sent (NMFakeNDisc *ndisc, TestData *data) { guint32 now = nm_utils_get_monotonic_timestamp_s (); guint id; @@ -409,11 +409,11 @@ test_dns_solicit_loop_rs_sent (NMFakeRDisc *rdisc, TestData *data) * DNS servers reaching 1/2 lifetime, emit a new RA without the DNS * servers again. */ - id = nm_fake_rdisc_add_ra (rdisc, 0, NM_RDISC_DHCP_LEVEL_NONE, 4, 1500); + id = nm_fake_ndisc_add_ra (ndisc, 0, NM_NDISC_DHCP_LEVEL_NONE, 4, 1500); g_assert (id); - nm_fake_rdisc_add_gateway (rdisc, id, "fe80::1", now, 10, NM_RDISC_PREFERENCE_MEDIUM); + nm_fake_ndisc_add_gateway (ndisc, id, "fe80::1", now, 10, NM_NDISC_PREFERENCE_MEDIUM); - nm_fake_rdisc_emit_new_ras (rdisc); + nm_fake_ndisc_emit_new_ras (ndisc); } else if (data->rs_counter >= 6) { /* Fail if we've sent too many solicitations in the past 4 seconds */ g_assert_cmpint (now - data->first_solicit, >, 4); @@ -426,7 +426,7 @@ test_dns_solicit_loop_rs_sent (NMFakeRDisc *rdisc, TestData *data) static void test_dns_solicit_loop (void) { - NMFakeRDisc *rdisc = rdisc_new (); + NMFakeNDisc *ndisc = ndisc_new (); guint32 now = nm_utils_get_monotonic_timestamp_s (); TestData data = { g_main_loop_new (NULL, FALSE), 0, 0, now, 0 }; guint id; @@ -438,25 +438,25 @@ test_dns_solicit_loop (void) * first. */ - id = nm_fake_rdisc_add_ra (rdisc, 1, NM_RDISC_DHCP_LEVEL_NONE, 4, 1500); + id = nm_fake_ndisc_add_ra (ndisc, 1, NM_NDISC_DHCP_LEVEL_NONE, 4, 1500); g_assert (id); - nm_fake_rdisc_add_gateway (rdisc, id, "fe80::1", now, 10, NM_RDISC_PREFERENCE_LOW); - nm_fake_rdisc_add_dns_server (rdisc, id, "2001:db8:c:c::1", now, 6); + nm_fake_ndisc_add_gateway (ndisc, id, "fe80::1", now, 10, NM_NDISC_PREFERENCE_LOW); + nm_fake_ndisc_add_dns_server (ndisc, id, "2001:db8:c:c::1", now, 6); - g_signal_connect (rdisc, - NM_RDISC_CONFIG_CHANGED, + g_signal_connect (ndisc, + NM_NDISC_CONFIG_CHANGED, G_CALLBACK (test_dns_solicit_loop_changed), &data); - g_signal_connect (rdisc, - NM_FAKE_RDISC_RS_SENT, + g_signal_connect (ndisc, + NM_FAKE_NDISC_RS_SENT, G_CALLBACK (test_dns_solicit_loop_rs_sent), &data); - nm_rdisc_start (NM_RDISC (rdisc)); + nm_ndisc_start (NM_NDISC (ndisc)); g_main_loop_run (data.loop); g_assert_cmpint (data.counter, ==, 3); - g_object_unref (rdisc); + g_object_unref (ndisc); g_main_loop_unref (data.loop); } @@ -468,16 +468,16 @@ main (int argc, char **argv) nmtst_init_with_logging (&argc, &argv, NULL, "DEFAULT"); if (nmtst_test_quick ()) { - g_print ("Skipping test: don't run long running test %s (NMTST_DEBUG=slow)\n", g_get_prgname () ?: "test-rdisc-fake"); + g_print ("Skipping test: don't run long running test %s (NMTST_DEBUG=slow)\n", g_get_prgname () ?: "test-ndisc-fake"); return g_test_run (); } nm_fake_platform_setup (); - g_test_add_func ("/rdisc/simple", test_simple); - g_test_add_func ("/rdisc/everything-changed", test_everything); - g_test_add_func ("/rdisc/preference-changed", test_preference); - g_test_add_func ("/rdisc/dns-solicit-loop", test_dns_solicit_loop); + g_test_add_func ("/ndisc/simple", test_simple); + g_test_add_func ("/ndisc/everything-changed", test_everything); + g_test_add_func ("/ndisc/preference-changed", test_preference); + g_test_add_func ("/ndisc/dns-solicit-loop", test_dns_solicit_loop); return g_test_run (); } diff --git a/src/rdisc/tests/test-rdisc-linux.c b/src/ndisc/tests/test-ndisc-linux.c similarity index 86% rename from src/rdisc/tests/test-rdisc-linux.c rename to src/ndisc/tests/test-ndisc-linux.c index 299abf3eeb..a2bb7e721d 100644 --- a/src/rdisc/tests/test-rdisc-linux.c +++ b/src/ndisc/tests/test-ndisc-linux.c @@ -1,5 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* rdisc.c - test program +/* ndisc.c - test program * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -23,8 +23,8 @@ #include #include -#include "nm-rdisc.h" -#include "nm-lndp-rdisc.h" +#include "nm-ndisc.h" +#include "nm-lndp-ndisc.h" #include "nm-linux-platform.h" @@ -36,7 +36,7 @@ int main (int argc, char **argv) { GMainLoop *loop; - NMRDisc *rdisc; + NMNDisc *ndisc; int ifindex = 1; const char *ifname; NMUtilsIPv6IfaceId iid = { }; @@ -61,25 +61,25 @@ main (int argc, char **argv) return EXIT_FAILURE; } - rdisc = nm_lndp_rdisc_new (NM_PLATFORM_GET, + ndisc = nm_lndp_ndisc_new (NM_PLATFORM_GET, ifindex, ifname, NM_UTILS_STABLE_TYPE_UUID, "8ce666e8-d34d-4fb1-b858-f15a7al28086", NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64, &error); - if (!rdisc) { - g_print ("Failed to create NMRDisc instance: %s\n", error->message); + if (!ndisc) { + g_print ("Failed to create NMNDisc instance: %s\n", error->message); g_error_free (error); return EXIT_FAILURE; } iid.id_u8[7] = 1; - nm_rdisc_set_iid (rdisc, iid); - nm_rdisc_start (rdisc); + nm_ndisc_set_iid (ndisc, iid); + nm_ndisc_start (ndisc); g_main_loop_run (loop); - g_clear_object (&rdisc); + g_clear_object (&ndisc); return EXIT_SUCCESS; } diff --git a/src/nm-iface-helper.c b/src/nm-iface-helper.c index a64f876126..12218a662c 100644 --- a/src/nm-iface-helper.c +++ b/src/nm-iface-helper.c @@ -40,8 +40,8 @@ extern unsigned int if_nametoindex (const char *__ifname); #include "NetworkManagerUtils.h" #include "nm-linux-platform.h" #include "nm-dhcp-manager.h" -#include "nm-rdisc.h" -#include "nm-lndp-rdisc.h" +#include "nm-ndisc.h" +#include "nm-lndp-ndisc.h" #include "nm-utils.h" #include "nm-setting-ip6-config.h" #include "systemd/nm-sd.h" @@ -146,10 +146,10 @@ dhcp4_state_changed (NMDhcpClient *client, } static void -rdisc_config_changed (NMRDisc *rdisc, const NMRDiscData *rdata, guint changed_int, gpointer user_data) +ndisc_config_changed (NMNDisc *ndisc, const NMNDiscData *rdata, guint changed_int, gpointer user_data) { - NMRDiscConfigMap changed = changed_int; - static NMIP6Config *rdisc_config = NULL; + NMNDiscConfigMap changed = changed_int; + static NMIP6Config *ndisc_config = NULL; NMIP6Config *existing; static int system_support = -1; guint32 ifa_flags = 0x00; @@ -176,30 +176,30 @@ rdisc_config_changed (NMRDisc *rdisc, const NMRDiscData *rdata, guint changed_in } existing = nm_ip6_config_capture (gl.ifindex, FALSE, global_opt.tempaddr); - if (rdisc_config) - nm_ip6_config_subtract (existing, rdisc_config); + if (ndisc_config) + nm_ip6_config_subtract (existing, ndisc_config); else - rdisc_config = nm_ip6_config_new (gl.ifindex); + ndisc_config = nm_ip6_config_new (gl.ifindex); - if (changed & NM_RDISC_CONFIG_GATEWAYS) { - /* Use the first gateway as ordered in router discovery cache. */ + if (changed & NM_NDISC_CONFIG_GATEWAYS) { + /* Use the first gateway as ordered in neighbor discovery cache. */ if (rdata->gateways_n) - nm_ip6_config_set_gateway (rdisc_config, &rdata->gateways[0].address); + nm_ip6_config_set_gateway (ndisc_config, &rdata->gateways[0].address); else - nm_ip6_config_set_gateway (rdisc_config, NULL); + nm_ip6_config_set_gateway (ndisc_config, NULL); } - if (changed & NM_RDISC_CONFIG_ADDRESSES) { - /* Rebuild address list from router discovery cache. */ - nm_ip6_config_reset_addresses (rdisc_config); + if (changed & NM_NDISC_CONFIG_ADDRESSES) { + /* Rebuild address list from neighbor discovery cache. */ + nm_ip6_config_reset_addresses (ndisc_config); - /* rdisc->addresses contains at most max_addresses entries. + /* ndisc->addresses contains at most max_addresses entries. * This is different from what the kernel does, which * also counts static and temporary addresses when checking * max_addresses. **/ for (i = 0; i < rdata->addresses_n; i++) { - const NMRDiscAddress *discovered_address = &rdata->addresses[i]; + const NMNDiscAddress *discovered_address = &rdata->addresses[i]; NMPlatformIP6Address address; memset (&address, 0, sizeof (address)); @@ -210,52 +210,52 @@ rdisc_config_changed (NMRDisc *rdisc, const NMRDiscData *rdata, guint changed_in address.preferred = discovered_address->preferred; if (address.preferred > address.lifetime) address.preferred = address.lifetime; - address.addr_source = NM_IP_CONFIG_SOURCE_RDISC; + address.addr_source = NM_IP_CONFIG_SOURCE_NDISC; address.n_ifa_flags = ifa_flags; - nm_ip6_config_add_address (rdisc_config, &address); + nm_ip6_config_add_address (ndisc_config, &address); } } - if (changed & NM_RDISC_CONFIG_ROUTES) { - /* Rebuild route list from router discovery cache. */ - nm_ip6_config_reset_routes (rdisc_config); + if (changed & NM_NDISC_CONFIG_ROUTES) { + /* Rebuild route list from neighbor discovery cache. */ + nm_ip6_config_reset_routes (ndisc_config); for (i = 0; i < rdata->routes_n; i++) { - const NMRDiscRoute *discovered_route = &rdata->routes[i]; + const NMNDiscRoute *discovered_route = &rdata->routes[i]; const NMPlatformIP6Route route = { .network = discovered_route->network, .plen = discovered_route->plen, .gateway = discovered_route->gateway, - .rt_source = NM_IP_CONFIG_SOURCE_RDISC, + .rt_source = NM_IP_CONFIG_SOURCE_NDISC, .metric = global_opt.priority_v6, }; - nm_ip6_config_add_route (rdisc_config, &route); + nm_ip6_config_add_route (ndisc_config, &route); } } - if (changed & NM_RDISC_CONFIG_DHCP_LEVEL) { + if (changed & NM_NDISC_CONFIG_DHCP_LEVEL) { /* Unsupported until systemd DHCPv6 is ready */ } - if (changed & NM_RDISC_CONFIG_HOP_LIMIT) + if (changed & NM_NDISC_CONFIG_HOP_LIMIT) nm_platform_sysctl_set_ip6_hop_limit_safe (NM_PLATFORM_GET, global_opt.ifname, rdata->hop_limit); - if (changed & NM_RDISC_CONFIG_MTU) { + if (changed & NM_NDISC_CONFIG_MTU) { char val[16]; g_snprintf (val, sizeof (val), "%d", rdata->mtu); nm_platform_sysctl_set (NM_PLATFORM_GET, nm_utils_ip6_property_path (global_opt.ifname, "mtu"), val); } - nm_ip6_config_merge (existing, rdisc_config, NM_IP_CONFIG_MERGE_DEFAULT); + nm_ip6_config_merge (existing, ndisc_config, NM_IP_CONFIG_MERGE_DEFAULT); if (!nm_ip6_config_commit (existing, gl.ifindex, TRUE)) _LOGW (LOGD_IP6, "failed to apply IPv6 config"); } static void -rdisc_ra_timeout (NMRDisc *rdisc, gpointer user_data) +ndisc_ra_timeout (NMNDisc *ndisc, gpointer user_data) { if (global_opt.slaac_required) { _LOGW (LOGD_IP6, "IPv6 timed out or failed, quitting..."); @@ -337,13 +337,13 @@ ip6_address_changed (NMPlatform *platform, int iface, NMPlatformIP6Address *addr, int change_type_i, - NMRDisc *rdisc) + NMNDisc *ndisc) { const NMPlatformSignalChangeType change_type = change_type_i; if ( (change_type == NM_PLATFORM_SIGNAL_CHANGED && addr->n_ifa_flags & IFA_F_DADFAILED) || (change_type == NM_PLATFORM_SIGNAL_REMOVED && addr->n_ifa_flags & IFA_F_TENTATIVE)) - nm_rdisc_dad_failed (rdisc, &addr->address); + nm_ndisc_dad_failed (ndisc, &addr->address); } int @@ -354,7 +354,7 @@ main (int argc, char *argv[]) gboolean wrote_pidfile = FALSE; gs_free char *pidfile = NULL; gs_unref_object NMDhcpClient *dhcp4_client = NULL; - gs_unref_object NMRDisc *rdisc = NULL; + gs_unref_object NMNDisc *ndisc = NULL; GByteArray *hwaddr = NULL; size_t hwaddr_len = 0; gconstpointer tmp; @@ -502,13 +502,13 @@ main (int argc, char *argv[]) stable_type = (global_opt.stable_id[0] - '0'); stable_id = &global_opt.stable_id[2]; } - rdisc = nm_lndp_rdisc_new (NM_PLATFORM_GET, gl.ifindex, global_opt.ifname, + ndisc = nm_lndp_ndisc_new (NM_PLATFORM_GET, gl.ifindex, global_opt.ifname, stable_type, stable_id, global_opt.addr_gen_mode, NULL); - g_assert (rdisc); + g_assert (ndisc); if (iid) - nm_rdisc_set_iid (rdisc, *iid); + nm_ndisc_set_iid (ndisc, *iid); nm_platform_sysctl_set (NM_PLATFORM_GET, nm_utils_ip6_property_path (global_opt.ifname, "accept_ra"), "1"); nm_platform_sysctl_set (NM_PLATFORM_GET, nm_utils_ip6_property_path (global_opt.ifname, "accept_ra_defrtr"), "0"); @@ -518,16 +518,16 @@ main (int argc, char *argv[]) g_signal_connect (NM_PLATFORM_GET, NM_PLATFORM_SIGNAL_IP6_ADDRESS_CHANGED, G_CALLBACK (ip6_address_changed), - rdisc); - g_signal_connect (rdisc, - NM_RDISC_CONFIG_CHANGED, - G_CALLBACK (rdisc_config_changed), + ndisc); + g_signal_connect (ndisc, + NM_NDISC_CONFIG_CHANGED, + G_CALLBACK (ndisc_config_changed), NULL); - g_signal_connect (rdisc, - NM_RDISC_RA_TIMEOUT, - G_CALLBACK (rdisc_ra_timeout), + g_signal_connect (ndisc, + NM_NDISC_RA_TIMEOUT, + G_CALLBACK (ndisc_ra_timeout), NULL); - nm_rdisc_start (rdisc); + nm_ndisc_start (ndisc); } sd_id = nm_sd_event_attach_default (); diff --git a/src/nm-types.h b/src/nm-types.h index 45c9284f3f..8f0cc5849f 100644 --- a/src/nm-types.h +++ b/src/nm-types.h @@ -79,7 +79,7 @@ typedef enum { NM_IP_CONFIG_SOURCE_WWAN, NM_IP_CONFIG_SOURCE_VPN, NM_IP_CONFIG_SOURCE_DHCP, - NM_IP_CONFIG_SOURCE_RDISC, + NM_IP_CONFIG_SOURCE_NDISC, NM_IP_CONFIG_SOURCE_USER, } NMIPConfigSource; diff --git a/src/platform/nm-platform-utils.c b/src/platform/nm-platform-utils.c index 068801ee69..f3983d3d74 100644 --- a/src/platform/nm-platform-utils.c +++ b/src/platform/nm-platform-utils.c @@ -469,7 +469,7 @@ nmp_utils_ip_config_source_coerce_to_rtprot (NMIPConfigSource source) return RTPROT_KERNEL; case NM_IP_CONFIG_SOURCE_DHCP: return RTPROT_DHCP; - case NM_IP_CONFIG_SOURCE_RDISC: + case NM_IP_CONFIG_SOURCE_NDISC: return RTPROT_RA; default: @@ -501,7 +501,7 @@ nmp_utils_ip_config_source_coerce_from_rtprot (NMIPConfigSource source) return NM_IP_CONFIG_SOURCE_KERNEL; case NM_IP_CONFIG_SOURCE_RTPROT_RA: - return NM_IP_CONFIG_SOURCE_RDISC; + return NM_IP_CONFIG_SOURCE_NDISC; case NM_IP_CONFIG_SOURCE_RTPROT_DHCP: return NM_IP_CONFIG_SOURCE_DHCP; @@ -538,7 +538,7 @@ nmp_utils_ip_config_source_to_string (NMIPConfigSource source, char *buf, gsize case NM_IP_CONFIG_SOURCE_WWAN: s = "wwan"; break; case NM_IP_CONFIG_SOURCE_VPN: s = "vpn"; break; case NM_IP_CONFIG_SOURCE_DHCP: s = "dhcp"; break; - case NM_IP_CONFIG_SOURCE_RDISC: s = "rdisc"; break; + case NM_IP_CONFIG_SOURCE_NDISC: s = "ndisc"; break; case NM_IP_CONFIG_SOURCE_USER: s = "user"; break; default: break; diff --git a/src/rdisc/nm-rdisc.h b/src/rdisc/nm-rdisc.h deleted file mode 100644 index 9e5e9349bc..0000000000 --- a/src/rdisc/nm-rdisc.h +++ /dev/null @@ -1,170 +0,0 @@ -/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ -/* nm-rdisc.h - Perform IPv6 router discovery - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Copyright (C) 2013 Red Hat, Inc. - */ - -#ifndef __NETWORKMANAGER_RDISC_H__ -#define __NETWORKMANAGER_RDISC_H__ - -#include -#include - -#include "nm-setting-ip6-config.h" -#include "NetworkManagerUtils.h" - -#define NM_TYPE_RDISC (nm_rdisc_get_type ()) -#define NM_RDISC(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_RDISC, NMRDisc)) -#define NM_RDISC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_RDISC, NMRDiscClass)) -#define NM_IS_RDISC(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_RDISC)) -#define NM_IS_RDISC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_RDISC)) -#define NM_RDISC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), NM_TYPE_RDISC, NMRDiscClass)) - -#define NM_RDISC_PLATFORM "platform" -#define NM_RDISC_IFINDEX "ifindex" -#define NM_RDISC_IFNAME "ifname" -#define NM_RDISC_NETWORK_ID "network-id" -#define NM_RDISC_ADDR_GEN_MODE "addr-gen-mode" -#define NM_RDISC_STABLE_TYPE "stable-type" -#define NM_RDISC_MAX_ADDRESSES "max-addresses" -#define NM_RDISC_ROUTER_SOLICITATIONS "router-solicitations" -#define NM_RDISC_ROUTER_SOLICITATION_INTERVAL "router-solicitation-interval" - -#define NM_RDISC_CONFIG_CHANGED "config-changed" -#define NM_RDISC_RA_TIMEOUT "ra-timeout" - -typedef enum { - NM_RDISC_DHCP_LEVEL_UNKNOWN, - NM_RDISC_DHCP_LEVEL_NONE, - NM_RDISC_DHCP_LEVEL_OTHERCONF, - NM_RDISC_DHCP_LEVEL_MANAGED -} NMRDiscDHCPLevel; - -typedef enum { - NM_RDISC_PREFERENCE_INVALID, - NM_RDISC_PREFERENCE_LOW, - NM_RDISC_PREFERENCE_MEDIUM, - NM_RDISC_PREFERENCE_HIGH -} NMRDiscPreference; - -typedef struct { - struct in6_addr address; - guint32 timestamp; - guint32 lifetime; - NMRDiscPreference preference; -} NMRDiscGateway; - -typedef struct { - struct in6_addr address; - guint8 dad_counter; - guint32 timestamp; - guint32 lifetime; - guint32 preferred; -} NMRDiscAddress; - -typedef struct { - struct in6_addr network; - guint8 plen; - struct in6_addr gateway; - guint32 timestamp; - guint32 lifetime; - NMRDiscPreference preference; -} NMRDiscRoute; - -typedef struct { - struct in6_addr address; - guint32 timestamp; - guint32 lifetime; -} NMRDiscDNSServer; - -typedef struct { - char *domain; - guint32 timestamp; - guint32 lifetime; -} NMRDiscDNSDomain; - -typedef enum { - NM_RDISC_CONFIG_DHCP_LEVEL = 1 << 0, - NM_RDISC_CONFIG_GATEWAYS = 1 << 1, - NM_RDISC_CONFIG_ADDRESSES = 1 << 2, - NM_RDISC_CONFIG_ROUTES = 1 << 3, - NM_RDISC_CONFIG_DNS_SERVERS = 1 << 4, - NM_RDISC_CONFIG_DNS_DOMAINS = 1 << 5, - NM_RDISC_CONFIG_HOP_LIMIT = 1 << 6, - NM_RDISC_CONFIG_MTU = 1 << 7, -} NMRDiscConfigMap; - -#define NM_RDISC_MAX_ADDRESSES_DEFAULT 16 -#define NM_RDISC_ROUTER_SOLICITATIONS_DEFAULT 3 -#define NM_RDISC_ROUTER_SOLICITATION_INTERVAL_DEFAULT 4 - -struct _NMRDiscPrivate; -struct _NMRDiscDataInternal; - -typedef struct { - NMRDiscDHCPLevel dhcp_level; - guint32 mtu; - int hop_limit; - - guint gateways_n; - guint addresses_n; - guint routes_n; - guint dns_servers_n; - guint dns_domains_n; - - const NMRDiscGateway *gateways; - const NMRDiscAddress *addresses; - const NMRDiscRoute *routes; - const NMRDiscDNSServer *dns_servers; - const NMRDiscDNSDomain *dns_domains; -} NMRDiscData; - -/** - * NMRDisc: - * - * Interface-specific structure that handles incoming router advertisements, - * caches advertised items and removes them when they are obsolete. - */ -typedef struct { - GObject parent; - union { - struct _NMRDiscPrivate *_priv; - struct _NMRDiscDataInternal *rdata; - }; -} NMRDisc; - -typedef struct { - GObjectClass parent; - - void (*start) (NMRDisc *rdisc); - gboolean (*send_rs) (NMRDisc *rdisc, GError **error); -} NMRDiscClass; - -GType nm_rdisc_get_type (void); - -int nm_rdisc_get_ifindex (NMRDisc *self); -const char *nm_rdisc_get_ifname (NMRDisc *self); - -gboolean nm_rdisc_set_iid (NMRDisc *rdisc, const NMUtilsIPv6IfaceId iid); -void nm_rdisc_start (NMRDisc *rdisc); -void nm_rdisc_dad_failed (NMRDisc *rdisc, struct in6_addr *address); - -NMPlatform *nm_rdisc_get_platform (NMRDisc *self); -NMPNetns *nm_rdisc_netns_get (NMRDisc *self); -gboolean nm_rdisc_netns_push (NMRDisc *self, NMPNetns **netns); - -#endif /* __NETWORKMANAGER_RDISC_H__ */ diff --git a/src/rdisc/tests/.gitignore b/src/rdisc/tests/.gitignore deleted file mode 100644 index a773713bb0..0000000000 --- a/src/rdisc/tests/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/rdisc diff --git a/src/tests/test-general.c b/src/tests/test-general.c index 2596cff6af..a7337ba7b0 100644 --- a/src/tests/test-general.c +++ b/src/tests/test-general.c @@ -29,7 +29,7 @@ #include "nm-test-utils-core.h" /* Reference implementation for nm_utils_ip6_address_clear_host_address. - * Taken originally from set_address_masked(), src/rdisc/nm-lndp-rdisc.c + * Taken originally from set_address_masked(), src/ndisc/nm-lndp-ndisc.c **/ static void ip6_address_clear_host_address_reference (struct in6_addr *dst, struct in6_addr *src, guint8 plen) diff --git a/src/tests/test-ip6-config.c b/src/tests/test-ip6-config.c index 05b0320610..8e34f6c945 100644 --- a/src/tests/test-ip6-config.c +++ b/src/tests/test-ip6-config.c @@ -288,7 +288,7 @@ test_nm_ip6_config_addresses_sort (void) nm_ip6_config_reset_addresses (config); ADDR_ADD("2607:f0d0:1002:51::4", NULL, 64, 0, NM_IP_CONFIG_SOURCE_USER, 0, 0, 0, 0); ADDR_ADD("2607:f0d0:1002:51::5", NULL, 64, 0, NM_IP_CONFIG_SOURCE_USER, 0, 0, 0, 0); - ADDR_ADD("2607:f0d0:1002:51::6", NULL, 64, 0, NM_IP_CONFIG_SOURCE_RDISC, 0, 0, 0, IFA_F_MANAGETEMPADDR); + ADDR_ADD("2607:f0d0:1002:51::6", NULL, 64, 0, NM_IP_CONFIG_SOURCE_NDISC, 0, 0, 0, IFA_F_MANAGETEMPADDR); ADDR_ADD("2607:f0d0:1002:51::3", NULL, 64, 0, NM_IP_CONFIG_SOURCE_USER, 0, 0, 0, IFA_F_SECONDARY); ADDR_ADD("2607:f0d0:1002:51::8", NULL, 64, 0, NM_IP_CONFIG_SOURCE_USER, 0, 0, 0, IFA_F_SECONDARY); ADDR_ADD("2607:f0d0:1002:51::0", NULL, 64, 0, NM_IP_CONFIG_SOURCE_KERNEL, 0, 0, 0, IFA_F_SECONDARY); @@ -307,7 +307,7 @@ test_nm_ip6_config_addresses_sort (void) ADDR_ADD("2607:f0d0:1002:51::5", NULL, 64, 0, NM_IP_CONFIG_SOURCE_USER, 0, 0, 0, 0); ADDR_ADD("2607:f0d0:1002:51::8", NULL, 64, 0, NM_IP_CONFIG_SOURCE_USER, 0, 0, 0, IFA_F_SECONDARY); ADDR_ADD("2607:f0d0:1002:51::0", NULL, 64, 0, NM_IP_CONFIG_SOURCE_KERNEL, 0, 0, 0, IFA_F_SECONDARY); - ADDR_ADD("2607:f0d0:1002:51::6", NULL, 64, 0, NM_IP_CONFIG_SOURCE_RDISC, 0, 0, 0, IFA_F_MANAGETEMPADDR); + ADDR_ADD("2607:f0d0:1002:51::6", NULL, 64, 0, NM_IP_CONFIG_SOURCE_NDISC, 0, 0, 0, IFA_F_MANAGETEMPADDR); ADDR_ADD("fec0::1", NULL, 128, 0, NM_IP_CONFIG_SOURCE_KERNEL, 0, 0, 0, 0); ADDR_ADD("fe80::208:74ff:feda:625c", NULL, 128, 0, NM_IP_CONFIG_SOURCE_KERNEL, 0, 0, 0, 0); ADDR_ADD("fe80::208:74ff:feda:625d", NULL, 128, 0, NM_IP_CONFIG_SOURCE_KERNEL, 0, 0, 0, 0); From f69b6c038e846ecebffc783f6cced0ec76cbcaf1 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Tue, 1 Nov 2016 13:33:32 +0100 Subject: [PATCH 12/29] device: the domain list from DNSSL is in fact a search list --- src/devices/nm-device.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 9dfb436452..83a0774708 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -6328,10 +6328,10 @@ ndisc_config_changed (NMNDisc *ndisc, const NMNDiscData *rdata, guint changed_in if (changed & NM_NDISC_CONFIG_DNS_DOMAINS) { /* Rebuild domain list from neighbor discovery cache. */ - nm_ip6_config_reset_domains (priv->ac_ip6_config); + nm_ip6_config_reset_searches (priv->ac_ip6_config); for (i = 0; i < rdata->dns_domains_n; i++) - nm_ip6_config_add_domain (priv->ac_ip6_config, rdata->dns_domains[i].domain); + nm_ip6_config_add_search (priv->ac_ip6_config, rdata->dns_domains[i].domain); } if (changed & NM_NDISC_CONFIG_DHCP_LEVEL) { From d09aea62eed373f56c7cfed5fa89623dfb4b608e Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Thu, 3 Nov 2016 11:58:08 +0100 Subject: [PATCH 13/29] ndisc/trivial: add a couple of comments of where do the constants come from --- src/ndisc/nm-ndisc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ndisc/nm-ndisc.h b/src/ndisc/nm-ndisc.h index 8861a17be1..34595b0dcb 100644 --- a/src/ndisc/nm-ndisc.h +++ b/src/ndisc/nm-ndisc.h @@ -109,8 +109,8 @@ typedef enum { } NMNDiscConfigMap; #define NM_NDISC_MAX_ADDRESSES_DEFAULT 16 -#define NM_NDISC_ROUTER_SOLICITATIONS_DEFAULT 3 -#define NM_NDISC_ROUTER_SOLICITATION_INTERVAL_DEFAULT 4 +#define NM_NDISC_ROUTER_SOLICITATIONS_DEFAULT 3 /* RFC4861 MAX_RTR_SOLICITATIONS */ +#define NM_NDISC_ROUTER_SOLICITATION_INTERVAL_DEFAULT 4 /* RFC4861 RTR_SOLICITATION_INTERVAL */ struct _NMNDiscPrivate; struct _NMNDiscDataInternal; From c84313a2b78fc1aed1f045596682416029b00075 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Fri, 14 Oct 2016 19:55:53 +0200 Subject: [PATCH 14/29] ndisc/lndp: drop an unused variable --- src/ndisc/nm-lndp-ndisc.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ndisc/nm-lndp-ndisc.c b/src/ndisc/nm-lndp-ndisc.c index 0259c52efd..b86aad2cc2 100644 --- a/src/ndisc/nm-lndp-ndisc.c +++ b/src/ndisc/nm-lndp-ndisc.c @@ -42,7 +42,6 @@ typedef struct { GIOChannel *event_channel; guint event_id; - guint ra_timeout_id; /* first RA timeout */ } NMLndpNDiscPrivate; /*****************************************************************************/ From 679f8dfc7d0e064dee26218f6aa914df0a0bddef Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Fri, 14 Oct 2016 19:52:52 +0200 Subject: [PATCH 15/29] ndisc/trivial: move nm_ndisc_set_iid upwards --- src/ndisc/nm-ndisc.c | 96 ++++++++++++++++++++++---------------------- 1 file changed, 49 insertions(+), 47 deletions(-) diff --git a/src/ndisc/nm-ndisc.c b/src/ndisc/nm-ndisc.c index 667d7fec49..f78c4fd453 100644 --- a/src/ndisc/nm-ndisc.c +++ b/src/ndisc/nm-ndisc.c @@ -425,53 +425,6 @@ nm_ndisc_add_dns_domain (NMNDisc *ndisc, const NMNDiscDNSDomain *new) /*****************************************************************************/ -/** - * nm_ndisc_set_iid: - * @ndisc: the #NMNDisc - * @iid: the new interface ID - * - * Sets the "Modified EUI-64" interface ID to be used when generating - * IPv6 addresses using received prefixes. Identifiers are either generated - * from the hardware addresses or manually set by the operator with - * "ip token" command. - * - * Upon token change (or initial setting) all addresses generated using - * the old identifier are removed. The caller should ensure the addresses - * will be reset by soliciting router advertisements. - * - * In case the stable privacy addressing is used %FALSE is returned and - * addresses are left untouched. - * - * Returns: %TRUE if addresses need to be regenerated, %FALSE otherwise. - **/ -gboolean -nm_ndisc_set_iid (NMNDisc *ndisc, const NMUtilsIPv6IfaceId iid) -{ - NMNDiscPrivate *priv; - NMNDiscDataInternal *rdata; - - g_return_val_if_fail (NM_IS_NDISC (ndisc), FALSE); - - priv = NM_NDISC_GET_PRIVATE (ndisc); - rdata = &priv->rdata; - - if (priv->iid.id != iid.id) { - priv->iid = iid; - - if (priv->addr_gen_mode == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY) - return FALSE; - - if (rdata->addresses->len) { - _LOGD ("IPv6 interface identifier changed, flushing addresses"); - g_array_remove_range (rdata->addresses, 0, rdata->addresses->len); - _emit_config_change (ndisc, NM_NDISC_CONFIG_ADDRESSES); - } - return TRUE; - } - - return FALSE; -} - static gboolean send_rs_timeout (NMNDisc *ndisc) { @@ -536,6 +489,55 @@ solicit (NMNDisc *ndisc) priv->send_rs_id = g_timeout_add_seconds ((guint32) next, (GSourceFunc) send_rs_timeout, ndisc); } +/*****************************************************************************/ + +/** + * nm_ndisc_set_iid: + * @ndisc: the #NMNDisc + * @iid: the new interface ID + * + * Sets the "Modified EUI-64" interface ID to be used when generating + * IPv6 addresses using received prefixes. Identifiers are either generated + * from the hardware addresses or manually set by the operator with + * "ip token" command. + * + * Upon token change (or initial setting) all addresses generated using + * the old identifier are removed. The caller should ensure the addresses + * will be reset by soliciting router advertisements. + * + * In case the stable privacy addressing is used %FALSE is returned and + * addresses are left untouched. + * + * Returns: %TRUE if addresses need to be regenerated, %FALSE otherwise. + **/ +gboolean +nm_ndisc_set_iid (NMNDisc *ndisc, const NMUtilsIPv6IfaceId iid) +{ + NMNDiscPrivate *priv; + NMNDiscDataInternal *rdata; + + g_return_val_if_fail (NM_IS_NDISC (ndisc), FALSE); + + priv = NM_NDISC_GET_PRIVATE (ndisc); + rdata = &priv->rdata; + + if (priv->iid.id != iid.id) { + priv->iid = iid; + + if (priv->addr_gen_mode == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_STABLE_PRIVACY) + return FALSE; + + if (rdata->addresses->len) { + _LOGD ("IPv6 interface identifier changed, flushing addresses"); + g_array_remove_range (rdata->addresses, 0, rdata->addresses->len); + _emit_config_change (ndisc, NM_NDISC_CONFIG_ADDRESSES); + } + return TRUE; + } + + return FALSE; +} + static gboolean ndisc_ra_timeout_cb (gpointer user_data) { From aed2106d3e37d835d3b80f28f626a489e67cd400 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Fri, 14 Oct 2016 19:53:53 +0200 Subject: [PATCH 16/29] ndisc: avoid calling start() multiple times It hooks on ndp event callbacks and we'll end up in them being done redundantly, leaking them on dispose and potentially even calling them. --- src/devices/nm-device.c | 4 +--- src/ndisc/nm-lndp-ndisc.c | 3 +++ src/ndisc/nm-ndisc.c | 8 ++++---- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 83a0774708..72417afc44 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -1897,10 +1897,8 @@ device_link_changed (NMDevice *self) } if (priv->ndisc && info.inet6_token.id) { - if (nm_ndisc_set_iid (priv->ndisc, info.inet6_token)) { + if (nm_ndisc_set_iid (priv->ndisc, info.inet6_token)) _LOGD (LOGD_DEVICE, "IPv6 tokenized identifier present on device %s", priv->iface); - nm_ndisc_start (priv->ndisc); - } } if (klass->link_changed) diff --git a/src/ndisc/nm-lndp-ndisc.c b/src/ndisc/nm-lndp-ndisc.c index b86aad2cc2..d01c128fb0 100644 --- a/src/ndisc/nm-lndp-ndisc.c +++ b/src/ndisc/nm-lndp-ndisc.c @@ -323,6 +323,9 @@ start (NMNDisc *ndisc) NMLndpNDiscPrivate *priv = NM_LNDP_NDISC_GET_PRIVATE ((NMLndpNDisc *) ndisc); int fd = ndp_get_eventfd (priv->ndp); + g_return_if_fail (!priv->event_channel); + g_return_if_fail (!priv->event_id); + priv->event_channel = g_io_channel_unix_new (fd); priv->event_id = g_io_add_watch (priv->event_channel, G_IO_IN, (GIOFunc) event_ready, ndisc); diff --git a/src/ndisc/nm-ndisc.c b/src/ndisc/nm-ndisc.c index f78c4fd453..a7f0dd8589 100644 --- a/src/ndisc/nm-ndisc.c +++ b/src/ndisc/nm-ndisc.c @@ -531,6 +531,7 @@ nm_ndisc_set_iid (NMNDisc *ndisc, const NMUtilsIPv6IfaceId iid) _LOGD ("IPv6 interface identifier changed, flushing addresses"); g_array_remove_range (rdata->addresses, 0, rdata->addresses->len); _emit_config_change (ndisc, NM_NDISC_CONFIG_ADDRESSES); + solicit (ndisc); } return TRUE; } @@ -556,21 +557,20 @@ nm_ndisc_start (NMNDisc *ndisc) NMNDiscClass *klass = NM_NDISC_GET_CLASS (ndisc); gint64 ra_wait_secs; - g_assert (klass->start); + g_return_if_fail (klass->start); + g_return_if_fail (!priv->ra_timeout_id); _LOGD ("starting neighbor discovery: %d", priv->ifindex); if (!nm_ndisc_netns_push (ndisc, &netns)) return; - nm_clear_g_source (&priv->ra_timeout_id); ra_wait_secs = (((gint64) priv->router_solicitations) * priv->router_solicitation_interval) + 1; ra_wait_secs = CLAMP (ra_wait_secs, 30, 120); priv->ra_timeout_id = g_timeout_add_seconds (ra_wait_secs, ndisc_ra_timeout_cb, ndisc); _LOGD ("scheduling RA timeout in %d seconds", (int) ra_wait_secs); - if (klass->start) - klass->start (ndisc); + klass->start (ndisc); solicit (ndisc); } From be6a0c7ce5106a7baee710c90106328f8c05d4d7 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Fri, 14 Oct 2016 15:17:56 +0000 Subject: [PATCH 17/29] ndisc: move the logging deduplication into a macro We'll want to use it elsewhere. --- src/ndisc/nm-ndisc.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/ndisc/nm-ndisc.c b/src/ndisc/nm-ndisc.c index a7f0dd8589..b4b7970f75 100644 --- a/src/ndisc/nm-ndisc.c +++ b/src/ndisc/nm-ndisc.c @@ -46,7 +46,7 @@ struct _NMNDiscPrivate { gint32 last_rs; guint ra_timeout_id; /* first RA timeout */ guint timeout_id; /* prefix/dns/etc lifetime timeout */ - char *last_send_rs_error; + char *last_error; NMUtilsIPv6IfaceId iid; /* immutable values: */ @@ -425,6 +425,17 @@ nm_ndisc_add_dns_domain (NMNDisc *ndisc, const NMNDiscDNSDomain *new) /*****************************************************************************/ +#define _MAYBE_WARN(...) G_STMT_START { \ + gboolean _different_message; \ + \ + _different_message = g_strcmp0 (priv->last_error, error->message) != 0; \ + _NMLOG (_different_message ? LOGL_WARN : LOGL_DEBUG, __VA_ARGS__); \ + if (_different_message) { \ + g_clear_pointer (&priv->last_error, g_free); \ + priv->last_error = g_strdup (error->message); \ + } \ + } G_STMT_END + static gboolean send_rs_timeout (NMNDisc *ndisc) { @@ -441,17 +452,9 @@ send_rs_timeout (NMNDisc *ndisc) if (klass->send_rs (ndisc, &error)) { _LOGD ("router solicitation sent"); priv->solicitations_left--; - g_clear_pointer (&priv->last_send_rs_error, g_free); + g_clear_pointer (&priv->last_error, g_free); } else { - gboolean different_message; - - different_message = g_strcmp0 (priv->last_send_rs_error, error->message) != 0; - _NMLOG (different_message ? LOGL_WARN : LOGL_DEBUG, - "failure sending router solicitation: %s", error->message); - if (different_message) { - g_clear_pointer (&priv->last_send_rs_error, g_free); - priv->last_send_rs_error = g_strdup (error->message); - } + _MAYBE_WARN ("failure sending router solicitation: %s", error->message); g_clear_error (&error); } @@ -855,7 +858,7 @@ nm_ndisc_ra_received (NMNDisc *ndisc, guint32 now, NMNDiscConfigMap changed) nm_clear_g_source (&priv->ra_timeout_id); nm_clear_g_source (&priv->send_rs_id); - g_clear_pointer (&priv->last_send_rs_error, g_free); + g_clear_pointer (&priv->last_error, g_free); check_timestamps (ndisc, now, changed); } @@ -962,7 +965,7 @@ dispose (GObject *object) nm_clear_g_source (&priv->ra_timeout_id); nm_clear_g_source (&priv->send_rs_id); - g_clear_pointer (&priv->last_send_rs_error, g_free); + g_clear_pointer (&priv->last_error, g_free); nm_clear_g_source (&priv->timeout_id); From 87624a6c50c71cc3f0f6a02729179826d038ae01 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Fri, 14 Oct 2016 20:07:27 +0200 Subject: [PATCH 18/29] ndisc: add logic for acting as a router --- src/ndisc/nm-fake-ndisc.c | 1 + src/ndisc/nm-lndp-ndisc.c | 1 + src/ndisc/nm-ndisc-private.h | 1 + src/ndisc/nm-ndisc.c | 203 ++++++++++++++++++++++++++++++----- src/ndisc/nm-ndisc.h | 17 +++ 5 files changed, 199 insertions(+), 24 deletions(-) diff --git a/src/ndisc/nm-fake-ndisc.c b/src/ndisc/nm-fake-ndisc.c index 3b2c4d4dd0..f1ada6c0cd 100644 --- a/src/ndisc/nm-fake-ndisc.c +++ b/src/ndisc/nm-fake-ndisc.c @@ -373,6 +373,7 @@ nm_fake_ndisc_new (int ifindex, const char *ifname) return g_object_new (NM_TYPE_FAKE_NDISC, NM_NDISC_IFINDEX, ifindex, NM_NDISC_IFNAME, ifname, + NM_NDISC_NODE_TYPE, (int) NM_NDISC_NODE_TYPE_HOST, NULL); } diff --git a/src/ndisc/nm-lndp-ndisc.c b/src/ndisc/nm-lndp-ndisc.c index d01c128fb0..cd89fd6283 100644 --- a/src/ndisc/nm-lndp-ndisc.c +++ b/src/ndisc/nm-lndp-ndisc.c @@ -380,6 +380,7 @@ nm_lndp_ndisc_new (NMPlatform *platform, NM_NDISC_IFNAME, ifname, NM_NDISC_NETWORK_ID, network_id, NM_NDISC_ADDR_GEN_MODE, (int) addr_gen_mode, + NM_NDISC_NODE_TYPE, (int) NM_NDISC_NODE_TYPE_HOST, NM_NDISC_MAX_ADDRESSES, ipv6_sysctl_get (platform, ifname, "max_addresses", 0, G_MAXINT32, NM_NDISC_MAX_ADDRESSES_DEFAULT), diff --git a/src/ndisc/nm-ndisc-private.h b/src/ndisc/nm-ndisc-private.h index 999f38dd70..2308675a7d 100644 --- a/src/ndisc/nm-ndisc-private.h +++ b/src/ndisc/nm-ndisc-private.h @@ -37,6 +37,7 @@ struct _NMNDiscDataInternal { typedef struct _NMNDiscDataInternal NMNDiscDataInternal; void nm_ndisc_ra_received (NMNDisc *ndisc, guint32 now, NMNDiscConfigMap changed); +void nm_ndisc_rs_received (NMNDisc *ndisc); gboolean nm_ndisc_add_gateway (NMNDisc *ndisc, const NMNDiscGateway *new); gboolean nm_ndisc_complete_and_add_address (NMNDisc *ndisc, NMNDiscAddress *new); diff --git a/src/ndisc/nm-ndisc.c b/src/ndisc/nm-ndisc.c index b4b7970f75..01415cf5c5 100644 --- a/src/ndisc/nm-ndisc.c +++ b/src/ndisc/nm-ndisc.c @@ -41,9 +41,18 @@ struct _NMNDiscPrivate { /* this *must* be the first field. */ NMNDiscDataInternal rdata; - gint32 solicitations_left; - guint send_rs_id; - gint32 last_rs; + union { + gint32 solicitations_left; + gint32 announcements_left; + }; + union { + guint send_rs_id; + guint send_ra_id; + }; + union { + gint32 last_rs; + gint32 last_ra; + }; guint ra_timeout_id; /* first RA timeout */ guint timeout_id; /* prefix/dns/etc lifetime timeout */ char *last_error; @@ -58,6 +67,7 @@ struct _NMNDiscPrivate { gint32 max_addresses; gint32 router_solicitations; gint32 router_solicitation_interval; + NMNDiscNodeType node_type; NMPlatform *platform; NMPNetns *netns; @@ -75,6 +85,7 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE ( PROP_MAX_ADDRESSES, PROP_ROUTER_SOLICITATIONS, PROP_ROUTER_SOLICITATION_INTERVAL, + PROP_NODE_TYPE, ); enum { @@ -139,6 +150,14 @@ nm_ndisc_get_ifname (NMNDisc *self) return NM_NDISC_GET_PRIVATE (self)->ifname; } +NMNDiscNodeType +nm_ndisc_get_node_type (NMNDisc *self) +{ + g_return_val_if_fail (NM_IS_NDISC (self), NM_NDISC_NODE_TYPE_INVALID); + + return NM_NDISC_GET_PRIVATE (self)->node_type; +} + /*****************************************************************************/ static const NMNDiscData * @@ -259,19 +278,13 @@ complete_address (NMNDisc *ndisc, NMNDiscAddress *addr) return FALSE; } -gboolean -nm_ndisc_complete_and_add_address (NMNDisc *ndisc, NMNDiscAddress *new) +static gboolean +nm_ndisc_add_address (NMNDisc *ndisc, const NMNDiscAddress *new) { - NMNDiscPrivate *priv; - NMNDiscDataInternal *rdata; + NMNDiscPrivate *priv = NM_NDISC_GET_PRIVATE (ndisc); + NMNDiscDataInternal *rdata = &priv->rdata; int i; - if (!complete_address (ndisc, new)) - return FALSE; - - priv = NM_NDISC_GET_PRIVATE (ndisc); - rdata = &priv->rdata; - for (i = 0; i < rdata->addresses->len; i++) { NMNDiscAddress *item = &g_array_index (rdata->addresses, NMNDiscAddress, i); @@ -302,6 +315,15 @@ nm_ndisc_complete_and_add_address (NMNDisc *ndisc, NMNDiscAddress *new) return !!new->lifetime; } +gboolean +nm_ndisc_complete_and_add_address (NMNDisc *ndisc, NMNDiscAddress *new) +{ + if (!complete_address (ndisc, new)) + return FALSE; + + return nm_ndisc_add_address (ndisc, new); +} + gboolean nm_ndisc_add_route (NMNDisc *ndisc, const NMNDiscRoute *new) { @@ -473,7 +495,7 @@ send_rs_timeout (NMNDisc *ndisc) } static void -solicit (NMNDisc *ndisc) +solicit_routers (NMNDisc *ndisc) { NMNDiscPrivate *priv = NM_NDISC_GET_PRIVATE (ndisc); gint64 next, now; @@ -482,7 +504,6 @@ solicit (NMNDisc *ndisc) return; now = nm_utils_get_monotonic_timestamp_s (); - priv->solicitations_left = priv->router_solicitations; next = (((gint64) priv->last_rs) + priv->router_solicitation_interval) - now; @@ -492,8 +513,114 @@ solicit (NMNDisc *ndisc) priv->send_rs_id = g_timeout_add_seconds ((guint32) next, (GSourceFunc) send_rs_timeout, ndisc); } +static gboolean +announce_router (NMNDisc *ndisc) +{ + nm_auto_pop_netns NMPNetns *netns = NULL; + NMNDiscClass *klass = NM_NDISC_GET_CLASS (ndisc); + NMNDiscPrivate *priv = NM_NDISC_GET_PRIVATE (ndisc); + GError *error = NULL; + + if (!nm_ndisc_netns_push (ndisc, &netns)) + return G_SOURCE_REMOVE; + + priv->last_ra = nm_utils_get_monotonic_timestamp_s (); + if (klass->send_ra (ndisc, &error)) { + _LOGD ("router advertisement sent"); + g_clear_pointer (&priv->last_error, g_free); + } else { + _MAYBE_WARN ("failure sending router advertisement: %s", error->message); + g_clear_error (&error); + } + + if (--priv->announcements_left) { + _LOGD ("will resend an initial router advertisement"); + + /* Schedule next initial announcement retransmit. */ + priv->send_ra_id = g_timeout_add_seconds (g_random_int_range (0, NM_NDISC_ROUTER_ADVERT_INITIAL_INTERVAL), + (GSourceFunc) announce_router, ndisc); + } else { + _LOGD ("will send an unsolicited router advertisement"); + + /* Schedule next unsolicited announcement. */ + priv->announcements_left = 1; + priv->send_ra_id = g_timeout_add_seconds (NM_NDISC_ROUTER_ADVERT_MAX_INTERVAL, + (GSourceFunc) announce_router, + ndisc); + } + + return G_SOURCE_REMOVE; +} + +static void +announce_router_initial (NMNDisc *ndisc) +{ + NMNDiscPrivate *priv = NM_NDISC_GET_PRIVATE (ndisc); + + _LOGD ("will send an initial router advertisement"); + + /* Retry three more times. */ + priv->announcements_left = NM_NDISC_ROUTER_ADVERTISEMENTS_DEFAULT; + + /* Unschedule an unsolicited resend if we are allowed to send now. */ + if (G_LIKELY (nm_utils_get_monotonic_timestamp_s () - priv->last_ra > NM_NDISC_ROUTER_ADVERT_DELAY)) + nm_clear_g_source (&priv->send_ra_id); + + /* Schedule the initial send rather early. Clamp the delay by minimal + * delay and not the initial advert internal so that we start fast. */ + if (G_LIKELY (!priv->send_ra_id)) { + priv->send_ra_id = g_timeout_add_seconds (g_random_int_range (0, NM_NDISC_ROUTER_ADVERT_DELAY), + (GSourceFunc) announce_router, ndisc); + } +} + +static void +announce_router_solicited (NMNDisc *ndisc) +{ + NMNDiscPrivate *priv = NM_NDISC_GET_PRIVATE (ndisc); + + _LOGD ("will send an solicited router advertisement"); + + /* Unschedule an unsolicited resend if we are allowed to send now. */ + if (nm_utils_get_monotonic_timestamp_s () - priv->last_ra > NM_NDISC_ROUTER_ADVERT_DELAY) + nm_clear_g_source (&priv->send_ra_id); + + if (!priv->send_ra_id) { + priv->send_ra_id = g_timeout_add (g_random_int_range (0, 500), + (GSourceFunc) announce_router, ndisc); + } +} + /*****************************************************************************/ +void +nm_ndisc_set_config (NMNDisc *ndisc, + const GArray *addresses, + const GArray *dns_servers, + const GArray *dns_domains) +{ + int changed = FALSE; + guint i; + + for (i = 0; i < addresses->len; i++) { + if (nm_ndisc_add_address (ndisc, &g_array_index (addresses, NMNDiscAddress, i))) + changed = TRUE; + } + + for (i = 0; i < dns_servers->len; i++) { + if (nm_ndisc_add_dns_server (ndisc, &g_array_index (dns_servers, NMNDiscDNSServer, i))) + changed = TRUE; + } + + for (i = 0; i < dns_domains->len; i++) { + if (nm_ndisc_add_dns_domain (ndisc, &g_array_index (dns_domains, NMNDiscDNSDomain, i))) + changed = TRUE; + } + + if (changed) + announce_router_initial (ndisc); +} + /** * nm_ndisc_set_iid: * @ndisc: the #NMNDisc @@ -534,7 +661,7 @@ nm_ndisc_set_iid (NMNDisc *ndisc, const NMUtilsIPv6IfaceId iid) _LOGD ("IPv6 interface identifier changed, flushing addresses"); g_array_remove_range (rdata->addresses, 0, rdata->addresses->len); _emit_config_change (ndisc, NM_NDISC_CONFIG_ADDRESSES); - solicit (ndisc); + solicit_routers (ndisc); } return TRUE; } @@ -568,14 +695,22 @@ nm_ndisc_start (NMNDisc *ndisc) if (!nm_ndisc_netns_push (ndisc, &netns)) return; - ra_wait_secs = (((gint64) priv->router_solicitations) * priv->router_solicitation_interval) + 1; - ra_wait_secs = CLAMP (ra_wait_secs, 30, 120); - priv->ra_timeout_id = g_timeout_add_seconds (ra_wait_secs, ndisc_ra_timeout_cb, ndisc); - _LOGD ("scheduling RA timeout in %d seconds", (int) ra_wait_secs); - klass->start (ndisc); - solicit (ndisc); + switch (priv->node_type) { + case NM_NDISC_NODE_TYPE_HOST: + ra_wait_secs = (((gint64) priv->router_solicitations) * priv->router_solicitation_interval) + 1; + ra_wait_secs = CLAMP (ra_wait_secs, 30, 120); + priv->ra_timeout_id = g_timeout_add_seconds (ra_wait_secs, ndisc_ra_timeout_cb, ndisc); + _LOGD ("scheduling RA timeout in %d seconds", (int) ra_wait_secs); + solicit_routers (ndisc); + break; + case NM_NDISC_NODE_TYPE_ROUTER: + announce_router_initial (ndisc); + break; + default: + g_assert_not_reached (); + } } void @@ -780,7 +915,7 @@ clean_dns_servers (NMNDisc *ndisc, guint32 now, NMNDiscConfigMap *changed, guint g_array_remove_index (rdata->dns_servers, i--); *changed |= NM_NDISC_CONFIG_DNS_SERVERS; } else if (now >= refresh) - solicit (ndisc); + solicit_routers (ndisc); else if (*nextevent > refresh) *nextevent = refresh; } @@ -806,7 +941,7 @@ clean_dns_domains (NMNDisc *ndisc, guint32 now, NMNDiscConfigMap *changed, guint g_array_remove_index (rdata->dns_domains, i--); *changed |= NM_NDISC_CONFIG_DNS_DOMAINS; } else if (now >= refresh) - solicit (ndisc); + solicit_routers (ndisc); else if (*nextevent > refresh) *nextevent = refresh; } @@ -862,6 +997,15 @@ nm_ndisc_ra_received (NMNDisc *ndisc, guint32 now, NMNDiscConfigMap changed) check_timestamps (ndisc, now, changed); } +void +nm_ndisc_rs_received (NMNDisc *ndisc) +{ + NMNDiscPrivate *priv = NM_NDISC_GET_PRIVATE (ndisc); + + g_clear_pointer (&priv->last_error, g_free); + announce_router_solicited (ndisc); +} + /*****************************************************************************/ static void @@ -926,6 +1070,10 @@ set_property (GObject *object, guint prop_id, /* construct-only */ priv->router_solicitation_interval = g_value_get_int (value); break; + case PROP_NODE_TYPE: + /* construct-only */ + priv->node_type = g_value_get_int (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -965,6 +1113,7 @@ dispose (GObject *object) nm_clear_g_source (&priv->ra_timeout_id); nm_clear_g_source (&priv->send_rs_id); + nm_clear_g_source (&priv->send_ra_id); g_clear_pointer (&priv->last_error, g_free); nm_clear_g_source (&priv->timeout_id); @@ -1059,6 +1208,12 @@ nm_ndisc_class_init (NMNDiscClass *klass) G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_NODE_TYPE] = + g_param_spec_int (NM_NDISC_NODE_TYPE, "", "", + NM_NDISC_NODE_TYPE_INVALID, NM_NDISC_NODE_TYPE_ROUTER, NM_NDISC_NODE_TYPE_INVALID, + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); signals[CONFIG_CHANGED] = diff --git a/src/ndisc/nm-ndisc.h b/src/ndisc/nm-ndisc.h index 34595b0dcb..ef58e23854 100644 --- a/src/ndisc/nm-ndisc.h +++ b/src/ndisc/nm-ndisc.h @@ -40,6 +40,7 @@ #define NM_NDISC_NETWORK_ID "network-id" #define NM_NDISC_ADDR_GEN_MODE "addr-gen-mode" #define NM_NDISC_STABLE_TYPE "stable-type" +#define NM_NDISC_NODE_TYPE "node-type" #define NM_NDISC_MAX_ADDRESSES "max-addresses" #define NM_NDISC_ROUTER_SOLICITATIONS "router-solicitations" #define NM_NDISC_ROUTER_SOLICITATION_INTERVAL "router-solicitation-interval" @@ -108,9 +109,19 @@ typedef enum { NM_NDISC_CONFIG_MTU = 1 << 7, } NMNDiscConfigMap; +typedef enum { + NM_NDISC_NODE_TYPE_INVALID, + NM_NDISC_NODE_TYPE_HOST, + NM_NDISC_NODE_TYPE_ROUTER, +} NMNDiscNodeType; + #define NM_NDISC_MAX_ADDRESSES_DEFAULT 16 #define NM_NDISC_ROUTER_SOLICITATIONS_DEFAULT 3 /* RFC4861 MAX_RTR_SOLICITATIONS */ #define NM_NDISC_ROUTER_SOLICITATION_INTERVAL_DEFAULT 4 /* RFC4861 RTR_SOLICITATION_INTERVAL */ +#define NM_NDISC_ROUTER_ADVERTISEMENTS_DEFAULT 3 /* RFC4861 MAX_INITIAL_RTR_ADVERTISEMENTS */ +#define NM_NDISC_ROUTER_ADVERT_DELAY 3 /* RFC4861 MIN_DELAY_BETWEEN_RAS */ +#define NM_NDISC_ROUTER_ADVERT_INITIAL_INTERVAL 16 /* RFC4861 MAX_INITIAL_RTR_ADVERT_INTERVAL */ +#define NM_NDISC_ROUTER_ADVERT_MAX_INTERVAL 600 /* RFC4861 MaxRtrAdvInterval default */ struct _NMNDiscPrivate; struct _NMNDiscDataInternal; @@ -152,16 +163,22 @@ typedef struct { void (*start) (NMNDisc *ndisc); gboolean (*send_rs) (NMNDisc *ndisc, GError **error); + gboolean (*send_ra) (NMNDisc *ndisc, GError **error); } NMNDiscClass; GType nm_ndisc_get_type (void); int nm_ndisc_get_ifindex (NMNDisc *self); const char *nm_ndisc_get_ifname (NMNDisc *self); +NMNDiscNodeType nm_ndisc_get_node_type (NMNDisc *self); gboolean nm_ndisc_set_iid (NMNDisc *ndisc, const NMUtilsIPv6IfaceId iid); void nm_ndisc_start (NMNDisc *ndisc); void nm_ndisc_dad_failed (NMNDisc *ndisc, struct in6_addr *address); +void nm_ndisc_set_config (NMNDisc *ndisc, + const GArray *addresses, + const GArray *dns_servers, + const GArray *dns_domains); NMPlatform *nm_ndisc_get_platform (NMNDisc *self); NMPNetns *nm_ndisc_netns_get (NMNDisc *self); From 425ce65ed0059950e0cc67971b2e1cfdb4162a44 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Wed, 9 Nov 2016 17:21:41 +0100 Subject: [PATCH 19/29] ndisc: rename the config-changed signal The ndisc config can now be changed by NMDevice as well when the NDisc is in ROUTER mode. But what we're really interested in is when we receive a new one from the outside. --- src/devices/nm-device.c | 2 +- src/ndisc/nm-ndisc.c | 2 +- src/ndisc/nm-ndisc.h | 4 ++-- src/ndisc/tests/test-ndisc-fake.c | 8 ++++---- src/nm-iface-helper.c | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 72417afc44..5fac5d64d9 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -6412,7 +6412,7 @@ addrconf6_start_with_link_ready (NMDevice *self) nm_device_ipv6_sysctl_set (self, "accept_ra_rtr_pref", "0"); priv->ndisc_changed_id = g_signal_connect (priv->ndisc, - NM_NDISC_CONFIG_CHANGED, + NM_NDISC_CONFIG_RECEIVED, G_CALLBACK (ndisc_config_changed), self); priv->ndisc_timeout_id = g_signal_connect (priv->ndisc, diff --git a/src/ndisc/nm-ndisc.c b/src/ndisc/nm-ndisc.c index 01415cf5c5..eaadc82cea 100644 --- a/src/ndisc/nm-ndisc.c +++ b/src/ndisc/nm-ndisc.c @@ -1217,7 +1217,7 @@ nm_ndisc_class_init (NMNDiscClass *klass) g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); signals[CONFIG_CHANGED] = - g_signal_new (NM_NDISC_CONFIG_CHANGED, + g_signal_new (NM_NDISC_CONFIG_RECEIVED, G_OBJECT_CLASS_TYPE (klass), G_SIGNAL_RUN_FIRST, 0, diff --git a/src/ndisc/nm-ndisc.h b/src/ndisc/nm-ndisc.h index ef58e23854..bc4ebe265c 100644 --- a/src/ndisc/nm-ndisc.h +++ b/src/ndisc/nm-ndisc.h @@ -45,8 +45,8 @@ #define NM_NDISC_ROUTER_SOLICITATIONS "router-solicitations" #define NM_NDISC_ROUTER_SOLICITATION_INTERVAL "router-solicitation-interval" -#define NM_NDISC_CONFIG_CHANGED "config-changed" -#define NM_NDISC_RA_TIMEOUT "ra-timeout" +#define NM_NDISC_CONFIG_RECEIVED "config-received" +#define NM_NDISC_RA_TIMEOUT "ra-timeout" typedef enum { NM_NDISC_DHCP_LEVEL_UNKNOWN, diff --git a/src/ndisc/tests/test-ndisc-fake.c b/src/ndisc/tests/test-ndisc-fake.c index 09644232cc..dce066eaf8 100644 --- a/src/ndisc/tests/test-ndisc-fake.c +++ b/src/ndisc/tests/test-ndisc-fake.c @@ -185,7 +185,7 @@ test_simple (void) nm_fake_ndisc_add_dns_domain (ndisc, id, "foobar.com", now, 10); g_signal_connect (ndisc, - NM_NDISC_CONFIG_CHANGED, + NM_NDISC_CONFIG_RECEIVED, G_CALLBACK (test_simple_changed), &data); @@ -280,7 +280,7 @@ test_everything (void) nm_fake_ndisc_add_dns_domain (ndisc, id, "foobar2.com", now, 10); g_signal_connect (ndisc, - NM_NDISC_CONFIG_CHANGED, + NM_NDISC_CONFIG_RECEIVED, G_CALLBACK (test_everything_changed), &data); g_signal_connect (ndisc, @@ -366,7 +366,7 @@ test_preference (void) nm_fake_ndisc_add_prefix (ndisc, id, "2001:db8:a:a::", 64, "fe80::1", now, 10, 10, 15); g_signal_connect (ndisc, - NM_NDISC_CONFIG_CHANGED, + NM_NDISC_CONFIG_RECEIVED, G_CALLBACK (test_preference_changed), &data); @@ -444,7 +444,7 @@ test_dns_solicit_loop (void) nm_fake_ndisc_add_dns_server (ndisc, id, "2001:db8:c:c::1", now, 6); g_signal_connect (ndisc, - NM_NDISC_CONFIG_CHANGED, + NM_NDISC_CONFIG_RECEIVED, G_CALLBACK (test_dns_solicit_loop_changed), &data); g_signal_connect (ndisc, diff --git a/src/nm-iface-helper.c b/src/nm-iface-helper.c index 12218a662c..a18f9902d7 100644 --- a/src/nm-iface-helper.c +++ b/src/nm-iface-helper.c @@ -520,7 +520,7 @@ main (int argc, char *argv[]) G_CALLBACK (ip6_address_changed), ndisc); g_signal_connect (ndisc, - NM_NDISC_CONFIG_CHANGED, + NM_NDISC_CONFIG_RECEIVED, G_CALLBACK (ndisc_config_changed), NULL); g_signal_connect (ndisc, From 63878566020b8dab0180f6b8000f521fd43ada53 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Fri, 14 Oct 2016 20:13:32 +0200 Subject: [PATCH 20/29] ndisc/lndp: add ability to announce the managed IPv6 configuration Announce the prefixes and DNS configuration. --- src/devices/nm-device.c | 1 + src/ndisc/nm-lndp-ndisc.c | 197 ++++++++++++++++++++++++++++- src/ndisc/nm-lndp-ndisc.h | 1 + src/ndisc/nm-ndisc.c | 5 +- src/ndisc/nm-ndisc.h | 2 + src/ndisc/tests/test-ndisc-linux.c | 1 + src/nm-iface-helper.c | 4 +- 7 files changed, 205 insertions(+), 6 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 5fac5d64d9..543a3241bb 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -6455,6 +6455,7 @@ addrconf6_start (NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr) stable_type, stable_id, nm_setting_ip6_config_get_addr_gen_mode (s_ip6), + NM_NDISC_NODE_TYPE_HOST, &error); } if (!priv->ndisc) { diff --git a/src/ndisc/nm-lndp-ndisc.c b/src/ndisc/nm-lndp-ndisc.c index cd89fd6283..d711e60459 100644 --- a/src/ndisc/nm-lndp-ndisc.c +++ b/src/ndisc/nm-lndp-ndisc.c @@ -24,6 +24,7 @@ #include #include +#include /* stdarg.h included because of a bug in ndp.h */ #include #include @@ -302,6 +303,176 @@ receive_ra (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data) return 0; } +static void * +_ndp_msg_add_option (struct ndp_msg *msg, int len) +{ + void *ret = (uint8_t *)msg + ndp_msg_payload_len (msg); + + len += ndp_msg_payload_len (msg); + if (len > ndp_msg_payload_maxlen (msg)) + return NULL; + + ndp_msg_payload_len_set (msg, len); + return ret; +} + +#define NM_ND_OPT_RDNSS 25 +typedef struct { + struct nd_opt_hdr header; + uint16_t reserved; + uint32_t lifetime;; + struct in6_addr addrs[0]; +} NMLndpRdnssOption; + +#define NM_ND_OPT_DNSSL 31 +typedef struct { + struct nd_opt_hdr header; + uint16_t reserved; + uint32_t lifetime; + char search_list[0]; +} NMLndpDnsslOption; + +static gboolean +send_ra (NMNDisc *ndisc, GError **error) +{ + NMLndpNDiscPrivate *priv = NM_LNDP_NDISC_GET_PRIVATE ((NMLndpNDisc *) ndisc); + NMNDiscDataInternal *rdata = ndisc->rdata; + guint32 now = nm_utils_get_monotonic_timestamp_s (); + int errsv; + struct in6_addr *addr; + struct ndp_msg *msg; + struct nd_opt_prefix_info *prefix; + int i; + + errsv = ndp_msg_new (&msg, NDP_MSG_RA); + if (errsv) { + errsv = errsv > 0 ? errsv : -errsv; + g_set_error_literal (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, + "cannot create a router advertisement"); + return FALSE; + } + + ndp_msg_ifindex_set (msg, nm_ndisc_get_ifindex (ndisc)); + + /* Multicast to all nodes. */ + addr = ndp_msg_addrto (msg); + addr->s6_addr32[0] = htonl(0xff020000); + addr->s6_addr32[1] = 0; + addr->s6_addr32[2] = 0; + addr->s6_addr32[3] = htonl(0x1); + + ndp_msgra_router_lifetime_set (ndp_msgra (msg), NM_NDISC_ROUTER_LIFETIME); + + /* The device let us know about all addresses that the device got + * whose prefixes are suitable for delegating. Let's announce them. */ + for (i = 0; i < rdata->addresses->len; i++) { + NMNDiscAddress *address = &g_array_index (rdata->addresses, NMNDiscAddress, i); + guint32 age = now - address->timestamp; + guint32 lifetime = address->lifetime; + guint32 preferred = address->preferred; + + /* Clamp the life times if they're not forever. */ + if (lifetime != 0xffffffff) + lifetime = lifetime > age ? lifetime - age : 0; + if (preferred != 0xffffffff) + preferred = preferred > age ? preferred - age : 0; + + prefix = _ndp_msg_add_option (msg, sizeof(*prefix)); + if (!prefix) { + /* Maybe we could sent separate RAs, but why bother... */ + _LOGW ("The RA is too big, had to omit some some prefixes."); + break; + } + + prefix->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION; + prefix->nd_opt_pi_len = 4; + prefix->nd_opt_pi_prefix_len = 64; + prefix->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_ONLINK; + prefix->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_AUTO; + prefix->nd_opt_pi_valid_time = htonl(lifetime); + prefix->nd_opt_pi_preferred_time = htonl(preferred); + prefix->nd_opt_pi_prefix.s6_addr32[0] = address->address.s6_addr32[0]; + prefix->nd_opt_pi_prefix.s6_addr32[1] = address->address.s6_addr32[1]; + prefix->nd_opt_pi_prefix.s6_addr32[2] = 0; + prefix->nd_opt_pi_prefix.s6_addr32[3] = 0; + } + + if (rdata->dns_servers->len) { + NMLndpRdnssOption *option; + int len = sizeof(*option) + sizeof(option->addrs[0]) * rdata->dns_servers->len; + + option = _ndp_msg_add_option (msg, len); + if (option) { + option->header.nd_opt_type = NM_ND_OPT_RDNSS; + option->header.nd_opt_len = len / 8; + option->lifetime = htonl (900); + + for (i = 0; i < rdata->dns_servers->len; i++) { + NMNDiscDNSServer *dns_server = &g_array_index (rdata->dns_servers, NMNDiscDNSServer, i); + option->addrs[i] = dns_server->address; + } + } else { + _LOGW ("The RA is too big, had to omit DNS information."); + } + + } + + if (rdata->dns_domains->len) { + NMLndpDnsslOption *option; + NMNDiscDNSDomain *dns_server; + int len = sizeof(*option); + char *search_list; + + for (i = 0; i < rdata->dns_domains->len; i++) { + dns_server = &g_array_index (rdata->dns_domains, NMNDiscDNSDomain, i); + len += strlen (dns_server->domain) + 2; + } + len = (len + 8) & ~0x7; + + option = _ndp_msg_add_option (msg, len); + if (option) { + option->header.nd_opt_type = NM_ND_OPT_DNSSL; + option->header.nd_opt_len = len / 8; + option->lifetime = htonl (900); + + search_list = option->search_list; + for (i = 0; i < rdata->dns_domains->len; i++) { + NMNDiscDNSDomain *dns_domain = &g_array_index (rdata->dns_domains, NMNDiscDNSDomain, i); + uint8_t domain_len = strlen (dns_domain->domain); + + *search_list++ = domain_len; + memcpy (search_list, dns_domain->domain, domain_len); + search_list += domain_len; + *search_list++ = '\0'; + } + } else { + _LOGW ("The RA is too big, had to omit DNS search list."); + } + } + + errsv = ndp_msg_send (priv->ndp, msg); + + ndp_msg_destroy (msg); + if (errsv) { + errsv = errsv > 0 ? errsv : -errsv; + g_set_error (error, NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, + "%s (%d)", + g_strerror (errsv), errsv); + return FALSE; + } + + return TRUE; +} + +static int +receive_rs (struct ndp *ndp, struct ndp_msg *msg, gpointer user_data) +{ + NMNDisc *ndisc = user_data; + + nm_ndisc_rs_received (ndisc); + return 0; +} + static gboolean event_ready (GIOChannel *source, GIOCondition condition, NMNDisc *ndisc) { @@ -332,7 +503,16 @@ start (NMNDisc *ndisc) /* Flush any pending messages to avoid using obsolete information */ event_ready (priv->event_channel, 0, ndisc); - ndp_msgrcv_handler_register (priv->ndp, receive_ra, NDP_MSG_RA, nm_ndisc_get_ifindex (ndisc), ndisc); + switch (nm_ndisc_get_node_type (ndisc)) { + case NM_NDISC_NODE_TYPE_HOST: + ndp_msgrcv_handler_register (priv->ndp, receive_ra, NDP_MSG_RA, nm_ndisc_get_ifindex (ndisc), ndisc); + break; + case NM_NDISC_NODE_TYPE_ROUTER: + ndp_msgrcv_handler_register (priv->ndp, receive_rs, NDP_MSG_RS, nm_ndisc_get_ifindex (ndisc), ndisc); + break; + default: + g_assert_not_reached (); + } } /*****************************************************************************/ @@ -360,6 +540,7 @@ nm_lndp_ndisc_new (NMPlatform *platform, NMUtilsStableType stable_type, const char *network_id, NMSettingIP6ConfigAddrGenMode addr_gen_mode, + NMNDiscNodeType node_type, GError **error) { nm_auto_pop_netns NMPNetns *netns = NULL; @@ -380,7 +561,7 @@ nm_lndp_ndisc_new (NMPlatform *platform, NM_NDISC_IFNAME, ifname, NM_NDISC_NETWORK_ID, network_id, NM_NDISC_ADDR_GEN_MODE, (int) addr_gen_mode, - NM_NDISC_NODE_TYPE, (int) NM_NDISC_NODE_TYPE_HOST, + NM_NDISC_NODE_TYPE, (int) node_type, NM_NDISC_MAX_ADDRESSES, ipv6_sysctl_get (platform, ifname, "max_addresses", 0, G_MAXINT32, NM_NDISC_MAX_ADDRESSES_DEFAULT), @@ -417,7 +598,16 @@ dispose (GObject *object) g_clear_pointer (&priv->event_channel, g_io_channel_unref); if (priv->ndp) { - ndp_msgrcv_handler_unregister (priv->ndp, receive_ra, NDP_MSG_RA, nm_ndisc_get_ifindex (ndisc), ndisc); + switch (nm_ndisc_get_node_type (ndisc)) { + case NM_NDISC_NODE_TYPE_HOST: + ndp_msgrcv_handler_unregister (priv->ndp, receive_rs, NDP_MSG_RA, nm_ndisc_get_ifindex (ndisc), ndisc); + break; + case NM_NDISC_NODE_TYPE_ROUTER: + ndp_msgrcv_handler_unregister (priv->ndp, receive_ra, NDP_MSG_RA, nm_ndisc_get_ifindex (ndisc), ndisc); + break; + default: + g_assert_not_reached (); + } ndp_close (priv->ndp); priv->ndp = NULL; } @@ -434,4 +624,5 @@ nm_lndp_ndisc_class_init (NMLndpNDiscClass *klass) object_class->dispose = dispose; ndisc_class->start = start; ndisc_class->send_rs = send_rs; + ndisc_class->send_ra = send_ra; } diff --git a/src/ndisc/nm-lndp-ndisc.h b/src/ndisc/nm-lndp-ndisc.h index 9b97a164dc..f042fb74a2 100644 --- a/src/ndisc/nm-lndp-ndisc.h +++ b/src/ndisc/nm-lndp-ndisc.h @@ -42,6 +42,7 @@ NMNDisc *nm_lndp_ndisc_new (NMPlatform *platform, NMUtilsStableType stable_type, const char *network_id, NMSettingIP6ConfigAddrGenMode addr_gen_mode, + NMNDiscNodeType node_type, GError **error); #endif /* __NETWORKMANAGER_LNDP_NDISC_H__ */ diff --git a/src/ndisc/nm-ndisc.c b/src/ndisc/nm-ndisc.c index eaadc82cea..1294c9974b 100644 --- a/src/ndisc/nm-ndisc.c +++ b/src/ndisc/nm-ndisc.c @@ -537,7 +537,8 @@ announce_router (NMNDisc *ndisc) _LOGD ("will resend an initial router advertisement"); /* Schedule next initial announcement retransmit. */ - priv->send_ra_id = g_timeout_add_seconds (g_random_int_range (0, NM_NDISC_ROUTER_ADVERT_INITIAL_INTERVAL), + priv->send_ra_id = g_timeout_add_seconds (g_random_int_range (NM_NDISC_ROUTER_ADVERT_DELAY, + NM_NDISC_ROUTER_ADVERT_INITIAL_INTERVAL), (GSourceFunc) announce_router, ndisc); } else { _LOGD ("will send an unsolicited router advertisement"); @@ -586,7 +587,7 @@ announce_router_solicited (NMNDisc *ndisc) nm_clear_g_source (&priv->send_ra_id); if (!priv->send_ra_id) { - priv->send_ra_id = g_timeout_add (g_random_int_range (0, 500), + priv->send_ra_id = g_timeout_add (g_random_int_range (0, NM_NDISC_ROUTER_ADVERT_DELAY_MS), (GSourceFunc) announce_router, ndisc); } } diff --git a/src/ndisc/nm-ndisc.h b/src/ndisc/nm-ndisc.h index bc4ebe265c..7c67289d1e 100644 --- a/src/ndisc/nm-ndisc.h +++ b/src/ndisc/nm-ndisc.h @@ -121,7 +121,9 @@ typedef enum { #define NM_NDISC_ROUTER_ADVERTISEMENTS_DEFAULT 3 /* RFC4861 MAX_INITIAL_RTR_ADVERTISEMENTS */ #define NM_NDISC_ROUTER_ADVERT_DELAY 3 /* RFC4861 MIN_DELAY_BETWEEN_RAS */ #define NM_NDISC_ROUTER_ADVERT_INITIAL_INTERVAL 16 /* RFC4861 MAX_INITIAL_RTR_ADVERT_INTERVAL */ +#define NM_NDISC_ROUTER_ADVERT_DELAY_MS 500 /* RFC4861 MAX_RA_DELAY_TIME */ #define NM_NDISC_ROUTER_ADVERT_MAX_INTERVAL 600 /* RFC4861 MaxRtrAdvInterval default */ +#define NM_NDISC_ROUTER_LIFETIME 900 /* 1.5 * NM_NDISC_ROUTER_ADVERT_MAX_INTERVAL */ struct _NMNDiscPrivate; struct _NMNDiscDataInternal; diff --git a/src/ndisc/tests/test-ndisc-linux.c b/src/ndisc/tests/test-ndisc-linux.c index a2bb7e721d..e621eba952 100644 --- a/src/ndisc/tests/test-ndisc-linux.c +++ b/src/ndisc/tests/test-ndisc-linux.c @@ -67,6 +67,7 @@ main (int argc, char **argv) NM_UTILS_STABLE_TYPE_UUID, "8ce666e8-d34d-4fb1-b858-f15a7al28086", NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64, + NM_NDISC_NODE_TYPE_HOST, &error); if (!ndisc) { g_print ("Failed to create NMNDisc instance: %s\n", error->message); diff --git a/src/nm-iface-helper.c b/src/nm-iface-helper.c index a18f9902d7..cd437752fd 100644 --- a/src/nm-iface-helper.c +++ b/src/nm-iface-helper.c @@ -504,7 +504,9 @@ main (int argc, char *argv[]) } ndisc = nm_lndp_ndisc_new (NM_PLATFORM_GET, gl.ifindex, global_opt.ifname, stable_type, stable_id, - global_opt.addr_gen_mode, NULL); + global_opt.addr_gen_mode, + NM_NDISC_NODE_TYPE_HOST, + NULL); g_assert (ndisc); if (iid) From 611870347a26bd3ed1839064aedf34c22b37b74e Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Thu, 13 Oct 2016 13:39:30 +0000 Subject: [PATCH 21/29] ifcfg: add ability to save/restore ipv6.method=shared We use IPV6_AUTOCONF=shared for this. --- src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c | 8 +++++--- src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c index c77a360477..978804f498 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c @@ -1381,7 +1381,7 @@ make_ip6_setting (shvarFile *ifcfg, char *route6_path = NULL; gs_free char *dns_options_free = NULL; const char *dns_options = NULL; - gboolean ipv6init, ipv6forwarding, ipv6_autoconf, dhcp6 = FALSE; + gboolean ipv6init, ipv6forwarding, dhcp6 = FALSE; char *method = NM_SETTING_IP6_CONFIG_METHOD_MANUAL; char *ipv6addr, *ipv6addr_secondaries; char **list = NULL, **iter; @@ -1454,10 +1454,12 @@ make_ip6_setting (shvarFile *ifcfg, method = NM_SETTING_IP6_CONFIG_METHOD_IGNORE; /* IPv6 is disabled */ else { ipv6forwarding = svGetValueBoolean (ifcfg, "IPV6FORWARDING", FALSE); - ipv6_autoconf = svGetValueBoolean (ifcfg, "IPV6_AUTOCONF", !ipv6forwarding); + str_value = svGetValueString (ifcfg, "IPV6_AUTOCONF"); dhcp6 = svGetValueBoolean (ifcfg, "DHCPV6C", FALSE); - if (ipv6_autoconf) + if (!g_strcmp0 (str_value, "shared")) + method = NM_SETTING_IP6_CONFIG_METHOD_SHARED; + else if (svParseBoolean (str_value, !ipv6forwarding)) method = NM_SETTING_IP6_CONFIG_METHOD_AUTO; else if (dhcp6) method = NM_SETTING_IP6_CONFIG_METHOD_DHCP; diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c index d456f1a2a6..1696e1ad43 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c @@ -2477,8 +2477,8 @@ write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) svUnsetValue (ifcfg, "DHCPV6C"); } else if (!strcmp (value, NM_SETTING_IP6_CONFIG_METHOD_SHARED)) { svSetValueString (ifcfg, "IPV6INIT", "yes"); + svSetValueString (ifcfg, "IPV6_AUTOCONF", "shared"); svUnsetValue (ifcfg, "DHCPV6C"); - /* TODO */ } /* Write out IP addresses */ From 0e6d1940601250e72a85fbcbdce43920f6f052ef Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Tue, 1 Nov 2016 13:43:01 +0100 Subject: [PATCH 22/29] settings: allow method=shared with manual IPv6 configuration IPv4 already allows setting an address, reusing its prefix for the network it shares connection with. Additionally, for IPv6, the NDP can also share the DNS configuration. --- libnm-core/nm-setting-ip6-config.c | 56 ++++++++++++++++-------------- libnm-util/nm-setting-ip6-config.c | 19 +++++----- 2 files changed, 41 insertions(+), 34 deletions(-) diff --git a/libnm-core/nm-setting-ip6-config.c b/libnm-core/nm-setting-ip6-config.c index 50b3654301..4ef3333dc3 100644 --- a/libnm-core/nm-setting-ip6-config.c +++ b/libnm-core/nm-setting-ip6-config.c @@ -172,34 +172,38 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) } else if ( !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) || !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL) || !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_SHARED)) { - if (nm_setting_ip_config_get_num_dns (s_ip) > 0) { - g_set_error (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("this property is not allowed for '%s=%s'"), - NM_SETTING_IP_CONFIG_METHOD, method); - g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_DNS); - return FALSE; - } - if (nm_setting_ip_config_get_num_dns_searches (s_ip) > 0) { - g_set_error (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("this property is not allowed for '%s=%s'"), - NM_SETTING_IP_CONFIG_METHOD, method); - g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_DNS_SEARCH); - return FALSE; - } + /* Shared allows IP addresses and DNS; link-local and disabled do not */ + if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_SHARED) != 0) { + if (nm_setting_ip_config_get_num_dns (s_ip) > 0) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("this property is not allowed for '%s=%s'"), + NM_SETTING_IP_CONFIG_METHOD, method); + g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_DNS); + return FALSE; + } - if (nm_setting_ip_config_get_num_addresses (s_ip) > 0) { - g_set_error (error, - NM_CONNECTION_ERROR, - NM_CONNECTION_ERROR_INVALID_PROPERTY, - _("this property is not allowed for '%s=%s'"), - NM_SETTING_IP_CONFIG_METHOD, method); - g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_ADDRESSES); - return FALSE; + if (nm_setting_ip_config_get_num_dns_searches (s_ip) > 0) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("this property is not allowed for '%s=%s'"), + NM_SETTING_IP_CONFIG_METHOD, method); + g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_DNS_SEARCH); + return FALSE; + } + + if (nm_setting_ip_config_get_num_addresses (s_ip) > 0) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("this property is not allowed for '%s=%s'"), + NM_SETTING_IP_CONFIG_METHOD, method); + g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP_CONFIG_ADDRESSES); + return FALSE; + } } } else if ( !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) || !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_DHCP)) { diff --git a/libnm-util/nm-setting-ip6-config.c b/libnm-util/nm-setting-ip6-config.c index 9ad93ac16c..37bdd0ed73 100644 --- a/libnm-util/nm-setting-ip6-config.c +++ b/libnm-util/nm-setting-ip6-config.c @@ -868,14 +868,17 @@ verify (NMSetting *setting, GSList *all_settings, GError **error) return FALSE; } - if (g_slist_length (priv->addresses)) { - g_set_error (error, - NM_SETTING_IP6_CONFIG_ERROR, - NM_SETTING_IP6_CONFIG_ERROR_NOT_ALLOWED_FOR_METHOD, - _("this property is not allowed for '%s=%s'"), - NM_SETTING_IP6_CONFIG_METHOD, priv->method); - g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP6_CONFIG_ADDRESSES); - return FALSE; + /* Shared allows IP addresses; link-local and disabled do not */ + if (strcmp (priv->method, NM_SETTING_IP6_CONFIG_METHOD_SHARED) != 0) { + if (g_slist_length (priv->addresses)) { + g_set_error (error, + NM_SETTING_IP6_CONFIG_ERROR, + NM_SETTING_IP6_CONFIG_ERROR_NOT_ALLOWED_FOR_METHOD, + _("this property is not allowed for '%s=%s'"), + NM_SETTING_IP6_CONFIG_METHOD, priv->method); + g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP6_CONFIG_ADDRESSES); + return FALSE; + } } } else if ( !strcmp (priv->method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) || !strcmp (priv->method, NM_SETTING_IP6_CONFIG_METHOD_DHCP)) { From 46e63e03af587d405324205997aee3b9a49b4052 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Thu, 3 Nov 2016 12:15:32 +0100 Subject: [PATCH 23/29] device: announce the managed IPv6 configuration with ipv6.method=shared This esentially causes us to announce the prefixes of the addresses we own and the DNS configuration. Currently the only way to get the IPv6 configuration on such device is manual setting in the connection. This will change with IPv6 prefix delegation. --- src/devices/nm-device.c | 120 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 111 insertions(+), 9 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 543a3241bb..35d81cdf5f 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -1811,6 +1811,73 @@ device_recheck_slave_status (NMDevice *self, const NMPlatformLink *plink) } } +static void +ndisc_set_router_config (NMNDisc *ndisc, NMDevice *self) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + guint32 now = nm_utils_get_monotonic_timestamp_s (); + GArray *addresses, *dns_servers, *dns_domains; + guint len, i; + + if (nm_ndisc_get_node_type (ndisc) != NM_NDISC_NODE_TYPE_ROUTER) + return; + + /* Addresses whose prefixes we announce. */ + len = nm_ip6_config_get_num_addresses (priv->ip6_config); + addresses = g_array_sized_new (FALSE, FALSE, sizeof (NMNDiscAddress), len); + for (i = 0; i < len; i++) { + const NMPlatformIP6Address *addr = nm_ip6_config_get_address (priv->ip6_config, i); + NMNDiscAddress *ndisc_addr; + + if (IN6_IS_ADDR_LINKLOCAL (&addr->address)) + continue; + + if ( addr->n_ifa_flags & IFA_F_TENTATIVE + || addr->n_ifa_flags & IFA_F_DADFAILED) + continue; + + if (addr->plen != 64) + continue; + + ndisc_addr = &g_array_index (addresses, NMNDiscAddress, addresses->len-1); + ndisc_addr->address = addr->address; + ndisc_addr->timestamp = addr->timestamp; + ndisc_addr->lifetime = addr->lifetime; + ndisc_addr->preferred = addr->preferred; + } + + /* DNS servers. */ + len = nm_ip6_config_get_num_nameservers (priv->ip6_config); + dns_servers = g_array_sized_new (FALSE, FALSE, sizeof (NMNDiscDNSServer), len); + for (i = 0; i < len; i++) { + const struct in6_addr *nameserver = nm_ip6_config_get_nameserver (priv->ip6_config, i); + NMNDiscDNSServer *ndisc_nameserver; + + ndisc_nameserver = &g_array_index (dns_servers, NMNDiscDNSServer, dns_servers->len-1); + ndisc_nameserver->address = *nameserver; + ndisc_nameserver->timestamp = now; + ndisc_nameserver->lifetime = NM_NDISC_ROUTER_LIFETIME; + } + + /* DNS domains. */ + len = nm_ip6_config_get_num_searches (priv->ip6_config); + dns_domains = g_array_sized_new (FALSE, FALSE, sizeof (NMNDiscDNSDomain), len); + for (i = 0; i < len; i++) { + const char *search = nm_ip6_config_get_search (priv->ip6_config, i); + NMNDiscDNSDomain *ndisc_search; + + ndisc_search = &g_array_index (dns_domains, NMNDiscDNSDomain, dns_domains->len-1); + ndisc_search->domain = g_strdup (search); + ndisc_search->timestamp = now; + ndisc_search->lifetime = NM_NDISC_ROUTER_LIFETIME; + } + + nm_ndisc_set_config (ndisc, addresses, dns_servers, dns_domains); + g_array_free (addresses, TRUE); + g_array_free (dns_servers, TRUE); + g_array_free (dns_domains, TRUE); +} + static gboolean device_link_changed (NMDevice *self) { @@ -5266,6 +5333,7 @@ connection_ip6_method_requires_carrier (NMConnection *connection, static const char *ip6_carrier_methods[] = { NM_SETTING_IP6_CONFIG_METHOD_AUTO, NM_SETTING_IP6_CONFIG_METHOD_DHCP, + NM_SETTING_IP6_CONFIG_METHOD_SHARED, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL, NULL }; @@ -6043,7 +6111,8 @@ linklocal6_complete (NMDevice *self) _LOGD (LOGD_DEVICE, "linklocal6: waiting for link-local addresses successful, continue with method %s", method); - if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0) { + if ( strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0 + || strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_SHARED) == 0) { if (!addrconf6_start_with_link_ready (self)) { /* Time out IPv6 instead of failing the entire activation */ nm_device_activate_schedule_ip6_config_timeout (self); @@ -6406,10 +6475,23 @@ addrconf6_start_with_link_ready (NMDevice *self) if (!ip6_config_merge_and_apply (self, TRUE, NULL)) _LOGW (LOGD_IP6, "failed to apply manual IPv6 configuration"); - nm_device_ipv6_sysctl_set (self, "accept_ra", "1"); - nm_device_ipv6_sysctl_set (self, "accept_ra_defrtr", "0"); - nm_device_ipv6_sysctl_set (self, "accept_ra_pinfo", "0"); - nm_device_ipv6_sysctl_set (self, "accept_ra_rtr_pref", "0"); + /* XXX: These sysctls would probably be better set by the lndp ndisc itself. */ + switch (nm_ndisc_get_node_type (priv->ndisc)) { + case NM_NDISC_NODE_TYPE_HOST: + /* Accepting prefixes from discovered routers. */ + nm_device_ipv6_sysctl_set (self, "accept_ra", "1"); + nm_device_ipv6_sysctl_set (self, "accept_ra_defrtr", "0"); + nm_device_ipv6_sysctl_set (self, "accept_ra_pinfo", "0"); + nm_device_ipv6_sysctl_set (self, "accept_ra_rtr_pref", "0"); + break; + case NM_NDISC_NODE_TYPE_ROUTER: + /* We're the router. */ + nm_device_ipv6_sysctl_set (self, "forwarding", "1"); + nm_device_activate_schedule_ip6_config_result (self); + break; + default: + g_assert_not_reached (); + } priv->ndisc_changed_id = g_signal_connect (priv->ndisc, NM_NDISC_CONFIG_RECEIVED, @@ -6420,10 +6502,26 @@ addrconf6_start_with_link_ready (NMDevice *self) G_CALLBACK (ndisc_ra_timeout), self); + ndisc_set_router_config (priv->ndisc, self); nm_ndisc_start (priv->ndisc); return TRUE; } +static NMNDiscNodeType +ndisc_node_type (NMDevice *self) +{ + NMConnection *connection; + + connection = nm_device_get_applied_connection (self); + g_assert (connection); + + if (strcmp (nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG), + NM_SETTING_IP4_CONFIG_METHOD_SHARED) == 0) + return NM_NDISC_NODE_TYPE_ROUTER; + else + return NM_NDISC_NODE_TYPE_HOST; +} + static gboolean addrconf6_start (NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr) { @@ -6455,7 +6553,7 @@ addrconf6_start (NMDevice *self, NMSettingIP6ConfigPrivacy use_tempaddr) stable_type, stable_id, nm_setting_ip6_config_get_addr_gen_mode (s_ip6), - NM_NDISC_NODE_TYPE_HOST, + ndisc_node_type (self), &error); } if (!priv->ndisc) { @@ -6508,6 +6606,7 @@ static const char *ip6_properties_to_save[] = { "accept_ra_defrtr", "accept_ra_pinfo", "accept_ra_rtr_pref", + "forwarding", "disable_ipv6", "hop_limit", "use_tempaddr", @@ -6753,7 +6852,8 @@ act_stage3_ip6_config_start (NMDevice *self, ip6_privacy = _ip6_privacy_get (self); - if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0) { + if ( strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_AUTO) == 0 + || strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_SHARED) == 0) { if (!addrconf6_start (self, ip6_privacy)) { /* IPv6 might be disabled; allow IPv4 to proceed */ ret = NM_ACT_STAGE_RETURN_IP_FAIL; @@ -6773,8 +6873,6 @@ act_stage3_ip6_config_start (NMDevice *self, } else _LOGW (LOGD_IP6, "unhandled IPv6 config method '%s'; will fail", method); - /* Other methods (shared) aren't implemented yet */ - if ( ret != NM_ACT_STAGE_RETURN_FAILURE && !nm_device_uses_assumed_connection (self)) { switch (ip6_privacy) { @@ -8800,6 +8898,9 @@ nm_device_set_ip6_config (NMDevice *self, } nm_device_queue_recheck_assume (self); + + if (priv->ndisc) + ndisc_set_router_config (priv->ndisc, self); } if (reason) @@ -11116,6 +11217,7 @@ ip6_managed_setup (NMDevice *self) nm_device_ipv6_sysctl_set (self, "accept_ra_pinfo", "0"); nm_device_ipv6_sysctl_set (self, "accept_ra_rtr_pref", "0"); nm_device_ipv6_sysctl_set (self, "use_tempaddr", "0"); + nm_device_ipv6_sysctl_set (self, "forwarding", "0"); } static void From bda1e880de119075ff971af95ffbc45b064432c8 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Sat, 5 Nov 2016 18:31:20 +0100 Subject: [PATCH 24/29] device: enable the IPv6 forwarding for shared connections Useful when they have internet-routable prefixes, consistent with IPv4. --- src/devices/nm-device.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 35d81cdf5f..2c4d4421b5 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -7561,9 +7561,11 @@ activate_stage5_ip6_config_commit (NMDevice *self) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMActRequest *req; + const char *method; NMConnection *connection; NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE; int ip_ifindex; + int errsv; req = nm_device_get_act_request (self); g_assert (req); @@ -7600,6 +7602,17 @@ activate_stage5_ip6_config_commit (NMDevice *self) nm_device_remove_pending_action (self, PENDING_ACTION_DHCP6, FALSE); nm_device_remove_pending_action (self, PENDING_ACTION_AUTOCONF6, FALSE); + /* Start IPv6 forwarding if we need it */ + method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); + + if (strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_SHARED) == 0) { + if (!nm_platform_sysctl_set (NM_PLATFORM_GET, "/proc/sys/net/ipv6/conf/all/forwarding", "1")) { + errsv = errno; + _LOGE (LOGD_SHARING, "share: error enabling IPv6 forwarding: (%d) %s", errsv, strerror (errsv)); + nm_device_ip_method_failed (self, AF_INET6, NM_DEVICE_STATE_REASON_SHARED_START_FAILED); + } + } + /* Check if we have to wait for DAD */ if (priv->ip6_state == IP_CONF && !priv->dad6_ip6_config) { priv->dad6_ip6_config = dad6_get_pending_addresses (self); From d74e5e45e56a69aa8596764244ee4da4d799b101 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Tue, 1 Nov 2016 13:43:07 +0100 Subject: [PATCH 25/29] manager: allow ipv6.medhod=shared connections --- src/nm-manager.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/nm-manager.c b/src/nm-manager.c index 61f7404712..e6b60d1863 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -3404,18 +3404,6 @@ validate_activation_request (NMManager *self, goto error; } - /* Not implemented yet, we want to fail early */ - if ( nm_connection_get_setting_connection (connection) - && nm_connection_get_setting_ip6_config (connection) - && !strcmp (nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG), - NM_SETTING_IP6_CONFIG_METHOD_SHARED)) { - g_set_error_literal (error, - NM_MANAGER_ERROR, - NM_MANAGER_ERROR_CONNECTION_NOT_AVAILABLE, - "Sharing IPv6 connections is not supported yet."); - goto error; - } - /* Check whether it's a VPN or not */ if ( nm_connection_get_setting_vpn (connection) || nm_connection_is_type (connection, NM_SETTING_VPN_SETTING_NAME)) From 7d195856cc057f18964f69925739a36b9c29b1ec Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Thu, 27 Oct 2016 16:09:38 +0000 Subject: [PATCH 26/29] dhcp-manager: move the options logging one level up It will make sense to log the options even if we're not creating an ip6_config (e.g. we got a prefix option, not an address). Also, guard it with a logging enable conditional. That way we save precious microseconds so that we'll feel less guilty about the demise of mankind and universe. --- src/dhcp-manager/nm-dhcp-client.c | 9 +++++++++ src/dhcp-manager/nm-dhcp-utils.c | 8 -------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/dhcp-manager/nm-dhcp-client.c b/src/dhcp-manager/nm-dhcp-client.c index 0e28726363..15eb7a9f09 100644 --- a/src/dhcp-manager/nm-dhcp-client.c +++ b/src/dhcp-manager/nm-dhcp-client.c @@ -741,6 +741,15 @@ nm_dhcp_client_handle_event (gpointer unused, g_variant_unref (value); } + if (nm_logging_enabled (LOGL_DEBUG, LOGD_DHCP6)) { + GHashTableIter hash_iter; + gpointer key, val; + + g_hash_table_iter_init (&hash_iter, str_options); + while (g_hash_table_iter_next (&hash_iter, &key, &val)) + _LOGD ("option '%s'=>'%s'", (const char *) key, (const char *) val); + } + /* Create the IP config */ g_warn_if_fail (g_hash_table_size (str_options)); if (g_hash_table_size (str_options)) { diff --git a/src/dhcp-manager/nm-dhcp-utils.c b/src/dhcp-manager/nm-dhcp-utils.c index a7d4f4a4ee..0fdc31a46d 100644 --- a/src/dhcp-manager/nm-dhcp-utils.c +++ b/src/dhcp-manager/nm-dhcp-utils.c @@ -615,8 +615,6 @@ nm_dhcp_utils_ip6_config_from_options (int ifindex, struct in6_addr tmp_addr; NMPlatformIP6Address address; char *str = NULL; - GHashTableIter iter; - gpointer key, value; g_return_val_if_fail (options != NULL, NULL); @@ -624,12 +622,6 @@ nm_dhcp_utils_ip6_config_from_options (int ifindex, address.plen = 128; address.timestamp = nm_utils_get_monotonic_timestamp_s (); - g_hash_table_iter_init (&iter, options); - while (g_hash_table_iter_next (&iter, &key, &value)) { - _LOG2D (LOGD_DHCP6, iface, "(%s): option '%s'=>'%s'", - iface, (const char *) key, (const char *) value); - } - ip6_config = nm_ip6_config_new (ifindex); str = g_hash_table_lookup (options, "max_life"); From 4ec37b0364d399d38a9d3634a01a6d0249b26330 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Mon, 31 Oct 2016 23:30:37 +0100 Subject: [PATCH 27/29] dhcp-manager: add ability to specify the number of IPv6 prefixes to request Utilizes RFC 3633 prefix option in role of requesting router to ask the delegating router for prefixes. In future we'll be able to use the addresses from those prefixes on ipv6.method=shared connections. --- src/devices/nm-device.c | 3 +- src/dhcp-manager/nm-dhcp-client.c | 43 +++++++++++++++++++------- src/dhcp-manager/nm-dhcp-client.h | 7 +++-- src/dhcp-manager/nm-dhcp-dhclient.c | 14 ++++++--- src/dhcp-manager/nm-dhcp-dhcpcd.c | 3 +- src/dhcp-manager/nm-dhcp-manager.c | 12 +++++--- src/dhcp-manager/nm-dhcp-manager.h | 3 +- src/dhcp-manager/nm-dhcp-systemd.c | 10 ++++-- src/dhcp-manager/nm-dhcp-utils.c | 48 +++++++++++++++++++++++++++++ src/dhcp-manager/nm-dhcp-utils.h | 2 ++ 10 files changed, 117 insertions(+), 28 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 2c4d4421b5..4269bc8ada 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -5992,7 +5992,8 @@ dhcp6_start_with_link_ready (NMDevice *self, NMConnection *connection) priv->dhcp_timeout, priv->dhcp_anycast_address, (priv->dhcp6.mode == NM_NDISC_DHCP_LEVEL_OTHERCONF) ? TRUE : FALSE, - nm_setting_ip6_config_get_ip6_privacy (NM_SETTING_IP6_CONFIG (s_ip6))); + nm_setting_ip6_config_get_ip6_privacy (NM_SETTING_IP6_CONFIG (s_ip6)), + 0); if (tmp) g_byte_array_free (tmp, TRUE); diff --git a/src/dhcp-manager/nm-dhcp-client.c b/src/dhcp-manager/nm-dhcp-client.c index 15eb7a9f09..ec981e0ead 100644 --- a/src/dhcp-manager/nm-dhcp-client.c +++ b/src/dhcp-manager/nm-dhcp-client.c @@ -41,6 +41,7 @@ enum { SIGNAL_STATE_CHANGED, + SIGNAL_PREFIX_DELEGATED, LAST_SIGNAL }; @@ -511,7 +512,8 @@ nm_dhcp_client_start_ip6 (NMDhcpClient *self, const struct in6_addr *ll_addr, const char *hostname, gboolean info_only, - NMSettingIP6ConfigPrivacy privacy) + NMSettingIP6ConfigPrivacy privacy, + guint needed_prefixes) { NMDhcpClientPrivate *priv; gs_free char *str = NULL; @@ -544,7 +546,8 @@ nm_dhcp_client_start_ip6 (NMDhcpClient *self, ll_addr, info_only, privacy, - priv->duid); + priv->duid, + needed_prefixes); } void @@ -709,6 +712,7 @@ nm_dhcp_client_handle_event (gpointer unused, guint32 new_state; GHashTable *str_options = NULL; GObject *ip_config = NULL; + NMPlatformIP6Address prefix = { 0, }; g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), FALSE); g_return_val_if_fail (iface != NULL, FALSE); @@ -754,6 +758,7 @@ nm_dhcp_client_handle_event (gpointer unused, g_warn_if_fail (g_hash_table_size (str_options)); if (g_hash_table_size (str_options)) { if (priv->ipv6) { + prefix = nm_dhcp_utils_ip6_prefix_from_options (str_options); ip_config = (GObject *) nm_dhcp_utils_ip6_config_from_options (priv->ifindex, priv->iface, str_options, @@ -765,17 +770,26 @@ nm_dhcp_client_handle_event (gpointer unused, str_options, priv->priority); } - - /* Fail if no valid IP config was received */ - if (ip_config == NULL) { - _LOGW ("client bound but IP config not received"); - new_state = NM_DHCP_STATE_FAIL; - g_clear_pointer (&str_options, g_hash_table_unref); - } } } - nm_dhcp_client_set_state (self, new_state, ip_config, str_options); + if (!IN6_IS_ADDR_UNSPECIFIED (&prefix.address)) { + /* If we got an IPv6 prefix to delegate, we don't change the state + * of the DHCP client instance. Instead, we just signal the prefix + * to the device. */ + g_signal_emit (G_OBJECT (self), + signals[SIGNAL_PREFIX_DELEGATED], 0, + &prefix); + } else { + /* Fail if no valid IP config was received */ + if (new_state == NM_DHCP_STATE_BOUND && ip_config == NULL) { + _LOGW ("client bound but IP config not received"); + new_state = NM_DHCP_STATE_FAIL; + g_clear_pointer (&str_options, g_hash_table_unref); + } + + nm_dhcp_client_set_state (self, new_state, ip_config, str_options); + } if (str_options) g_hash_table_destroy (str_options); @@ -972,5 +986,12 @@ nm_dhcp_client_class_init (NMDhcpClientClass *client_class) G_STRUCT_OFFSET (NMDhcpClientClass, state_changed), NULL, NULL, NULL, G_TYPE_NONE, 4, G_TYPE_UINT, G_TYPE_OBJECT, G_TYPE_HASH_TABLE, G_TYPE_STRING); -} + signals[SIGNAL_PREFIX_DELEGATED] = + g_signal_new (NM_DHCP_CLIENT_SIGNAL_PREFIX_DELEGATED, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (NMDhcpClientClass, state_changed), + NULL, NULL, NULL, + G_TYPE_NONE, 1, G_TYPE_POINTER); +} diff --git a/src/dhcp-manager/nm-dhcp-client.h b/src/dhcp-manager/nm-dhcp-client.h index 9a2d21f713..7a083ae7a3 100644 --- a/src/dhcp-manager/nm-dhcp-client.h +++ b/src/dhcp-manager/nm-dhcp-client.h @@ -40,6 +40,7 @@ #define NM_DHCP_CLIENT_TIMEOUT "timeout" #define NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED "state-changed" +#define NM_DHCP_CLIENT_SIGNAL_PREFIX_DELEGATED "prefix-delegated" typedef enum { NM_DHCP_STATE_UNKNOWN = 0, @@ -73,7 +74,8 @@ typedef struct { const struct in6_addr *ll_addr, gboolean info_only, NMSettingIP6ConfigPrivacy privacy, - const GByteArray *duid); + const GByteArray *duid, + guint needed_prefixes); void (*stop) (NMDhcpClient *self, gboolean release, @@ -133,7 +135,8 @@ gboolean nm_dhcp_client_start_ip6 (NMDhcpClient *self, const struct in6_addr *ll_addr, const char *hostname, gboolean info_only, - NMSettingIP6ConfigPrivacy privacy); + NMSettingIP6ConfigPrivacy privacy, + guint needed_prefixes); void nm_dhcp_client_stop (NMDhcpClient *self, gboolean release); diff --git a/src/dhcp-manager/nm-dhcp-dhclient.c b/src/dhcp-manager/nm-dhcp-dhclient.c index a055e54179..64d93744f2 100644 --- a/src/dhcp-manager/nm-dhcp-dhclient.c +++ b/src/dhcp-manager/nm-dhcp-dhclient.c @@ -330,7 +330,8 @@ dhclient_start (NMDhcpClient *client, const char *mode_opt, const GByteArray *duid, gboolean release, - pid_t *out_pid) + pid_t *out_pid, + int prefixes) { NMDhcpDhclient *self = NM_DHCP_DHCLIENT (client); NMDhcpDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (self); @@ -424,6 +425,8 @@ dhclient_start (NMDhcpClient *client, g_ptr_array_add (argv, (gpointer) "-6"); if (mode_opt) g_ptr_array_add (argv, (gpointer) mode_opt); + while (prefixes--) + g_ptr_array_add (argv, (gpointer) "-P"); } g_ptr_array_add (argv, (gpointer) "-sf"); /* Set script file */ g_ptr_array_add (argv, (gpointer) nm_dhcp_helper_path); @@ -503,7 +506,7 @@ ip4_start (NMDhcpClient *client, const char *dhcp_anycast_addr, const char *last if (priv->conf_file) { if (new_client_id) nm_dhcp_client_set_client_id (client, new_client_id); - success = dhclient_start (client, NULL, NULL, FALSE, NULL); + success = dhclient_start (client, NULL, NULL, FALSE, NULL, 0); } else _LOGW ("error creating dhclient configuration file"); @@ -516,7 +519,8 @@ ip6_start (NMDhcpClient *client, const struct in6_addr *ll_addr, gboolean info_only, NMSettingIP6ConfigPrivacy privacy, - const GByteArray *duid) + const GByteArray *duid, + guint needed_prefixes) { NMDhcpDhclient *self = NM_DHCP_DHCLIENT (client); NMDhcpDhclientPrivate *priv = NM_DHCP_DHCLIENT_GET_PRIVATE (self); @@ -532,7 +536,7 @@ ip6_start (NMDhcpClient *client, return FALSE; } - return dhclient_start (client, info_only ? "-S" : "-N", duid, FALSE, NULL); + return dhclient_start (client, info_only ? "-S" : "-N", duid, FALSE, NULL, needed_prefixes); } static void @@ -557,7 +561,7 @@ stop (NMDhcpClient *client, gboolean release, const GByteArray *duid) if (release) { pid_t rpid = -1; - if (dhclient_start (client, NULL, duid, TRUE, &rpid)) { + if (dhclient_start (client, NULL, duid, TRUE, &rpid, 0)) { /* Wait a few seconds for the release to happen */ nm_dhcp_client_stop_pid (rpid, nm_dhcp_client_get_iface (client)); } diff --git a/src/dhcp-manager/nm-dhcp-dhcpcd.c b/src/dhcp-manager/nm-dhcp-dhcpcd.c index 6b7fe38bbf..c8643881fc 100644 --- a/src/dhcp-manager/nm-dhcp-dhcpcd.c +++ b/src/dhcp-manager/nm-dhcp-dhcpcd.c @@ -185,7 +185,8 @@ ip6_start (NMDhcpClient *client, const struct in6_addr *ll_addr, gboolean info_only, NMSettingIP6ConfigPrivacy privacy, - const GByteArray *duid) + const GByteArray *duid, + guint needed_prefixes) { NMDhcpDhcpcd *self = NM_DHCP_DHCPCD (client); diff --git a/src/dhcp-manager/nm-dhcp-manager.c b/src/dhcp-manager/nm-dhcp-manager.c index dee4039a5c..6cb5c105b9 100644 --- a/src/dhcp-manager/nm-dhcp-manager.c +++ b/src/dhcp-manager/nm-dhcp-manager.c @@ -166,7 +166,8 @@ client_start (NMDhcpManager *self, const char *fqdn, gboolean info_only, NMSettingIP6ConfigPrivacy privacy, - const char *last_ip4_address) + const char *last_ip4_address, + guint needed_prefixes) { NMDhcpManagerPrivate *priv; NMDhcpClient *client; @@ -206,7 +207,7 @@ client_start (NMDhcpManager *self, g_signal_connect (client, NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED, G_CALLBACK (client_state_changed), self); if (ipv6) - success = nm_dhcp_client_start_ip6 (client, dhcp_anycast_addr, ipv6_ll_addr, hostname, info_only, privacy); + success = nm_dhcp_client_start_ip6 (client, dhcp_anycast_addr, ipv6_ll_addr, hostname, info_only, privacy, needed_prefixes); else success = nm_dhcp_client_start_ip4 (client, dhcp_client_id, dhcp_anycast_addr, hostname, fqdn, last_ip4_address); @@ -254,7 +255,7 @@ nm_dhcp_manager_start_ip4 (NMDhcpManager *self, } return client_start (self, iface, ifindex, hwaddr, uuid, priority, FALSE, NULL, dhcp_client_id, timeout, dhcp_anycast_addr, hostname, - fqdn, FALSE, 0, last_ip_address); + fqdn, FALSE, 0, last_ip_address, 0); } /* Caller owns a reference to the NMDhcpClient on return */ @@ -271,7 +272,8 @@ nm_dhcp_manager_start_ip6 (NMDhcpManager *self, guint32 timeout, const char *dhcp_anycast_addr, gboolean info_only, - NMSettingIP6ConfigPrivacy privacy) + NMSettingIP6ConfigPrivacy privacy, + guint needed_prefixes) { const char *hostname = NULL; @@ -281,7 +283,7 @@ nm_dhcp_manager_start_ip6 (NMDhcpManager *self, hostname = get_send_hostname (self, dhcp_hostname); return client_start (self, iface, ifindex, hwaddr, uuid, priority, TRUE, ll_addr, NULL, timeout, dhcp_anycast_addr, hostname, NULL, info_only, - privacy, NULL); + privacy, NULL, needed_prefixes); } void diff --git a/src/dhcp-manager/nm-dhcp-manager.h b/src/dhcp-manager/nm-dhcp-manager.h index e525180d43..a948b60970 100644 --- a/src/dhcp-manager/nm-dhcp-manager.h +++ b/src/dhcp-manager/nm-dhcp-manager.h @@ -69,7 +69,8 @@ NMDhcpClient * nm_dhcp_manager_start_ip6 (NMDhcpManager *manager, guint32 timeout, const char *dhcp_anycast_addr, gboolean info_only, - NMSettingIP6ConfigPrivacy privacy); + NMSettingIP6ConfigPrivacy privacy, + guint needed_prefixes); GSList * nm_dhcp_manager_get_lease_ip_configs (NMDhcpManager *self, const char *iface, diff --git a/src/dhcp-manager/nm-dhcp-systemd.c b/src/dhcp-manager/nm-dhcp-systemd.c index 4e3f85deb9..b6c9e27c17 100644 --- a/src/dhcp-manager/nm-dhcp-systemd.c +++ b/src/dhcp-manager/nm-dhcp-systemd.c @@ -894,7 +894,8 @@ ip6_start (NMDhcpClient *client, const struct in6_addr *ll_addr, gboolean info_only, NMSettingIP6ConfigPrivacy privacy, - const GByteArray *duid) + const GByteArray *duid, + guint needed_prefixes) { NMDhcpSystemd *self = NM_DHCP_SYSTEMD (client); NMDhcpSystemdPrivate *priv = NM_DHCP_SYSTEMD_GET_PRIVATE (self); @@ -916,7 +917,12 @@ ip6_start (NMDhcpClient *client, return FALSE; } - _LOGT ("dhcp-client6: set %p", priv->client4); + if (needed_prefixes > 0) { + _LOGW ("dhcp-client6: prefix delegation not yet supported, won't supply %d prefixes\n", + needed_prefixes); + } + + _LOGT ("dhcp-client6: set %p", priv->client6); if (info_only) sd_dhcp6_client_set_information_request (priv->client6, 1); diff --git a/src/dhcp-manager/nm-dhcp-utils.c b/src/dhcp-manager/nm-dhcp-utils.c index 0fdc31a46d..4205d021b7 100644 --- a/src/dhcp-manager/nm-dhcp-utils.c +++ b/src/dhcp-manager/nm-dhcp-utils.c @@ -604,6 +604,54 @@ ip6_add_domain_search (gpointer data, gpointer user_data) nm_ip6_config_add_search (NM_IP6_CONFIG (user_data), (const char *) data); } +NMPlatformIP6Address +nm_dhcp_utils_ip6_prefix_from_options (GHashTable *options) +{ + gs_strfreev gchar **split_addr = NULL; + NMPlatformIP6Address address = { 0, }; + struct in6_addr tmp_addr; + char *str = NULL; + int prefix; + + g_return_val_if_fail (options != NULL, address); + + str = g_hash_table_lookup (options, "ip6_prefix"); + if (!str) + return address; + + split_addr = g_strsplit (str, "/", 2); + if (split_addr[0] == NULL && split_addr[1] == NULL) { + nm_log_warn (LOGD_DHCP6, "DHCP returned prefix without length '%s'", str); + return address; + } + + if (!inet_pton (AF_INET6, split_addr[0], &tmp_addr)) { + nm_log_warn (LOGD_DHCP6, "DHCP returned invalid prefix '%s'", str); + return address; + } + + prefix = _nm_utils_ascii_str_to_int64 (split_addr[1], 10, 0, 128, -1); + if (prefix < 0) { + nm_log_warn (LOGD_DHCP6, "DHCP returned prefix with invalid length '%s'", str); + return address; + } + + address.address = tmp_addr; + address.addr_source = NM_IP_CONFIG_SOURCE_DHCP; + address.plen = prefix; + address.timestamp = nm_utils_get_monotonic_timestamp_s (); + + str = g_hash_table_lookup (options, "max_life"); + if (str) + address.lifetime = strtoul (str, NULL, 10); + + str = g_hash_table_lookup (options, "preferred_life"); + if (str) + address.preferred = strtoul (str, NULL, 10); + + return address; +} + NMIP6Config * nm_dhcp_utils_ip6_config_from_options (int ifindex, const char *iface, diff --git a/src/dhcp-manager/nm-dhcp-utils.h b/src/dhcp-manager/nm-dhcp-utils.h index 6540b1ff80..b45c5e89a2 100644 --- a/src/dhcp-manager/nm-dhcp-utils.h +++ b/src/dhcp-manager/nm-dhcp-utils.h @@ -35,6 +35,8 @@ NMIP6Config *nm_dhcp_utils_ip6_config_from_options (int ifindex, guint priority, gboolean info_only); +NMPlatformIP6Address nm_dhcp_utils_ip6_prefix_from_options (GHashTable *options); + char * nm_dhcp_utils_duid_to_string (const GByteArray *duid); GBytes * nm_dhcp_utils_client_id_string_to_bytes (const char *client_id); From 479ad5065e96abe4588c52c9588faf046cc182d1 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Thu, 3 Nov 2016 12:05:12 +0100 Subject: [PATCH 28/29] device: add IPv6 configuration delegation machinery There's two parts of the configuration involved: the subnet addresses and the DNS information. For the addressing, the shared (downlink) device signals the policy needs for a /64 subnet. When it gets one, it merges it into the autoconf configuration and forwards to the NDisc. When more prefixes are needed, the (uplink) device asks the DHCP manager and eventually signals delegation (reception) of a prefix. The NMDevice only provides the mechanism, the actual subnetting needs to be done by the NMPolicy. For the DNS configuration, the shared device just copies it from whichever device the policy deems suitable. --- src/devices/nm-device.c | 133 +++++++++++++++++++++++++++++++++++++++- src/devices/nm-device.h | 12 ++++ 2 files changed, 144 insertions(+), 1 deletion(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 4269bc8ada..d3b6d95581 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -83,6 +83,8 @@ enum { AUTH_REQUEST, IP4_CONFIG_CHANGED, IP6_CONFIG_CHANGED, + IP6_PREFIX_DELEGATED, + IP6_SUBNET_NEEDED, REMOVED, RECHECK_AUTO_ACTIVATE, RECHECK_ASSUME, @@ -389,6 +391,7 @@ typedef struct _NMDevicePrivate { NMDhcpClient * client; NMNDiscDHCPLevel mode; gulong state_sigid; + gulong prefix_sigid; NMDhcp6Config * config; /* IP6 config from DHCP */ NMIP6Config * ip6_config; @@ -396,8 +399,11 @@ typedef struct _NMDevicePrivate { char * event_id; guint restart_id; guint num_tries_left; + guint needed_prefixes; } dhcp6; + gboolean needs_ip6_subnet; + /* allow autoconnect feature */ bool autoconnect; @@ -5501,6 +5507,7 @@ dhcp6_cleanup (NMDevice *self, CleanupType cleanup_type, gboolean release) if (priv->dhcp6.client) { nm_clear_g_signal_handler (priv->dhcp6.client, &priv->dhcp6.state_sigid); + nm_clear_g_signal_handler (priv->dhcp6.client, &priv->dhcp6.prefix_sigid); if ( cleanup_type == CLEANUP_TYPE_DECONFIGURE || cleanup_type == CLEANUP_TYPE_REMOVED) @@ -5955,6 +5962,19 @@ dhcp6_state_changed (NMDhcpClient *client, } } +static void +dhcp6_prefix_delegated (NMDhcpClient *client, + NMPlatformIP6Address *prefix, + gpointer user_data) +{ + NMDevice *self = NM_DEVICE (user_data); + + /* Just re-emit. The device just contributes the prefix to the + * pool in NMPolicy, which decides about subnet allocation + * on the shared devices. */ + g_signal_emit (self, signals[IP6_PREFIX_DELEGATED], 0, prefix); +} + static gboolean dhcp6_start_with_link_ready (NMDevice *self, NMConnection *connection) { @@ -5993,7 +6013,7 @@ dhcp6_start_with_link_ready (NMDevice *self, NMConnection *connection) priv->dhcp_anycast_address, (priv->dhcp6.mode == NM_NDISC_DHCP_LEVEL_OTHERCONF) ? TRUE : FALSE, nm_setting_ip6_config_get_ip6_privacy (NM_SETTING_IP6_CONFIG (s_ip6)), - 0); + priv->dhcp6.needed_prefixes); if (tmp) g_byte_array_free (tmp, TRUE); @@ -6002,6 +6022,10 @@ dhcp6_start_with_link_ready (NMDevice *self, NMConnection *connection) NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED, G_CALLBACK (dhcp6_state_changed), self); + priv->dhcp6.prefix_sigid = g_signal_connect (priv->dhcp6.client, + NM_DHCP_CLIENT_SIGNAL_PREFIX_DELEGATED, + G_CALLBACK (dhcp6_prefix_delegated), + self); } return !!priv->dhcp6.client; @@ -6068,6 +6092,95 @@ nm_device_dhcp6_renew (NMDevice *self, gboolean release) /*****************************************************************************/ +/* + * Called on the requesting interface when a subnet can't be obtained + * from known prefixes for a newly active shared connection. + */ +void +nm_device_request_ip6_prefixes (NMDevice *self, int needed_prefixes) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + + priv->dhcp6.needed_prefixes = needed_prefixes; + + if (priv->dhcp6.client) { + _LOGD (LOGD_IP6, "ipv6-pd: asking DHCPv6 for %d prefixes", needed_prefixes); + nm_device_dhcp6_renew (self, FALSE); + } else { + _LOGI (LOGD_IP6, "ipv6-pd: device doesn't use DHCPv6, can't request prefixes"); + } +} + +gboolean +nm_device_needs_ip6_subnet (NMDevice *self) +{ + return NM_DEVICE_GET_PRIVATE (self)->needs_ip6_subnet; +} + +/* + * Called on the ipv6.method=shared interface when a new subnet is allocated + * or the prefix from which it is allocated is renewed. + */ +void +nm_device_use_ip6_subnet (NMDevice *self, const NMPlatformIP6Address *subnet) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMPlatformIP6Address address = *subnet; + + if (!priv->ac_ip6_config) + priv->ac_ip6_config = nm_ip6_config_new (nm_device_get_ip_ifindex (self)); + + /* Assign a ::1 address in the subnet for us. */ + address.address.s6_addr32[3] |= htonl (1); + nm_ip6_config_add_address (priv->ac_ip6_config, &address); + + _LOGD (LOGD_IP6, "ipv6-pd: using %s address (preferred for %u seconds)", + nm_utils_inet6_ntop (&address.address, NULL), + subnet->preferred); + + /* This also updates the ndisc if there are actual changes. */ + if (!ip6_config_merge_and_apply (self, TRUE, NULL)) + _LOGW (LOGD_IP6, "ipv6-pd: failed applying IP6 config for connection sharing"); +} + +/* + * Called whenever the policy picks a default IPv6 device. + * The ipv6.method=shared devices just reuse its DNS configuration. + */ +void +nm_device_copy_ip6_dns_config (NMDevice *self, NMDevice *from_device) +{ + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); + NMIP6Config *from_config = NULL; + int i; + + if (priv->ac_ip6_config) { + nm_ip6_config_reset_nameservers (priv->ac_ip6_config); + nm_ip6_config_reset_searches (priv->ac_ip6_config); + } else + priv->ac_ip6_config = nm_ip6_config_new (nm_device_get_ip_ifindex (self)); + + if (from_device) + from_config = nm_device_get_ip6_config (from_device); + if (!from_config) + return; + + for (i = 0; i < nm_ip6_config_get_num_nameservers (from_config); i++) { + nm_ip6_config_add_nameserver (priv->ac_ip6_config, + nm_ip6_config_get_nameserver (from_config, i)); + } + + for (i = 0; i < nm_ip6_config_get_num_searches (from_config); i++) { + nm_ip6_config_add_search (priv->ac_ip6_config, + nm_ip6_config_get_search (from_config, i)); + } + + if (!ip6_config_merge_and_apply (self, TRUE, NULL)) + _LOGW (LOGD_IP6, "ipv6-pd: failed applying DNS config for connection sharing"); +} + +/*****************************************************************************/ + static void linklocal6_cleanup (NMDevice *self) { @@ -6489,6 +6602,8 @@ addrconf6_start_with_link_ready (NMDevice *self) /* We're the router. */ nm_device_ipv6_sysctl_set (self, "forwarding", "1"); nm_device_activate_schedule_ip6_config_result (self); + priv->needs_ip6_subnet = TRUE; + g_signal_emit (self, signals[IP6_SUBNET_NEEDED], 0); break; default: g_assert_not_reached (); @@ -10924,6 +11039,8 @@ _cleanup_generic_post (NMDevice *self, CleanupType cleanup_type) g_slist_free_full (priv->vpn6_configs, g_object_unref); priv->vpn6_configs = NULL; + priv->needs_ip6_subnet = FALSE; + clear_act_request (self); /* Clear legacy IPv4 address property */ @@ -13209,6 +13326,20 @@ nm_device_class_init (NMDeviceClass *klass) 0, NULL, NULL, NULL, G_TYPE_NONE, 2, G_TYPE_OBJECT, G_TYPE_OBJECT); + signals[IP6_PREFIX_DELEGATED] = + g_signal_new (NM_DEVICE_IP6_PREFIX_DELEGATED, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 1, G_TYPE_POINTER); + + signals[IP6_SUBNET_NEEDED] = + g_signal_new (NM_DEVICE_IP6_SUBNET_NEEDED, + G_OBJECT_CLASS_TYPE (object_class), + G_SIGNAL_RUN_FIRST, + 0, NULL, NULL, NULL, + G_TYPE_NONE, 0); + signals[REMOVED] = g_signal_new (NM_DEVICE_REMOVED, G_OBJECT_CLASS_TYPE (object_class), diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index 356331189c..ab6852e40e 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -82,6 +82,8 @@ #define NM_DEVICE_AUTH_REQUEST "auth-request" #define NM_DEVICE_IP4_CONFIG_CHANGED "ip4-config-changed" #define NM_DEVICE_IP6_CONFIG_CHANGED "ip6-config-changed" +#define NM_DEVICE_IP6_PREFIX_DELEGATED "ip6-prefix-delegated" +#define NM_DEVICE_IP6_SUBNET_NEEDED "ip6-subnet-needed" #define NM_DEVICE_REMOVED "removed" #define NM_DEVICE_RECHECK_AUTO_ACTIVATE "recheck-auto-activate" #define NM_DEVICE_RECHECK_ASSUME "recheck-assume" @@ -439,6 +441,16 @@ void nm_device_set_enabled (NMDevice *device, gboolean enabled); RfKillType nm_device_get_rfkill_type (NMDevice *device); +/* IPv6 prefix delegation */ + +void nm_device_request_ip6_prefixes (NMDevice *self, int needed_prefixes); + +gboolean nm_device_needs_ip6_subnet (NMDevice *self); + +void nm_device_use_ip6_subnet (NMDevice *self, const NMPlatformIP6Address *subnet); + +void nm_device_copy_ip6_dns_config (NMDevice *self, NMDevice *from_device); + /** * NMUnmanagedFlags: * @NM_UNMANAGED_NONE: placeholder value From ec12fcf6bf4f306d426271c286db3c28b7025ba4 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Mon, 31 Oct 2016 23:31:14 +0100 Subject: [PATCH 29/29] policy: delegate IPv6 configuration to ipv6.method=shared connections The policy listens to signals from shared devices that need subnets and requesting devices that provide prefixes. Whenever a subnet is needed, policy tries to obtain a subnets from all of default6 device's prefixes. When it fails to get any, it asks for more prefixes. This way we make it possible for the delegating router to either provide us with a /64 for each of our shared interfaces, or provide a larger prefix that we could subnet. The policy also updates the shared device's DNS information to keep it in sync with the best requesting device changes. --- src/nm-policy.c | 282 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 281 insertions(+), 1 deletion(-) diff --git a/src/nm-policy.c b/src/nm-policy.c index 6993438cf0..8be0dbcf7e 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -88,6 +88,8 @@ typedef struct { char *orig_hostname; /* hostname at NM start time */ char *cur_hostname; /* hostname we want to assign */ gboolean hostname_changed; /* TRUE if NM ever set the hostname */ + + GArray *ip6_prefix_delegations; /* pool of ip6 prefixes delegated to all devices */ } NMPolicyPrivate; struct _NMPolicy { @@ -133,6 +135,236 @@ static void schedule_activate_all (NMPolicy *self); /*****************************************************************************/ +typedef struct { + NMPlatformIP6Address prefix; + NMDevice *device; /* The requesting ("uplink") device */ + guint64 next_subnet; /* Cache of the next subnet number to be + * assigned from this prefix */ + GHashTable *subnets; /* ifindex -> NMPlatformIP6Address */ +} IP6PrefixDelegation; + +static void +_clear_ip6_subnet (gpointer key, gpointer value, gpointer user_data) +{ + NMPlatformIP6Address *subnet = value; + NMDevice *device = nm_manager_get_device_by_ifindex (nm_manager_get (), + GPOINTER_TO_INT (key)); + + if (!device) + return; + + /* We can not remove a subnet we already started announcing. + * Just un-prefer it. */ + subnet->preferred = 0; + nm_device_use_ip6_subnet (device, subnet); + g_slice_free (NMPlatformIP6Address, subnet); +} + +static void +clear_ip6_prefix_delegation (gpointer data) +{ + IP6PrefixDelegation *delegation = data; + + _LOGD (LOGD_IP6, "ipv6-pd: undelegating prefix %s/%d", + nm_utils_inet6_ntop (&delegation->prefix.address, NULL), + delegation->prefix.plen); + + g_hash_table_foreach (delegation->subnets, _clear_ip6_subnet, NULL); + g_hash_table_destroy (delegation->subnets); +} + +static void +expire_ip6_delegations (NMPolicy *self) +{ + NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); + guint32 now = nm_utils_get_monotonic_timestamp_s (); + IP6PrefixDelegation *delegation = NULL; + int i; + + for (i = 0; i < priv->ip6_prefix_delegations->len; i++) { + delegation = &g_array_index (priv->ip6_prefix_delegations, + IP6PrefixDelegation, i); + if (delegation->prefix.timestamp + delegation->prefix.lifetime < now) + g_array_remove_index_fast (priv->ip6_prefix_delegations, i); + } +} + +/* + * Try to obtain a new subnet for a particular active connection from given + * delegated prefix, possibly reusing the existing subnet. + * Return value of FALSE indicates no more subnets are available from + * this prefix (and other prefix should be used -- and requested if necessary). + */ +static gboolean +ip6_subnet_from_delegation (IP6PrefixDelegation *delegation, NMDevice *device) +{ + NMPlatformIP6Address *subnet; + int ifindex = nm_device_get_ifindex (device); + + subnet = g_hash_table_lookup (delegation->subnets, GINT_TO_POINTER (ifindex)); + if (!subnet) { + /* Check for out-of-prefixes condition. */ + if (delegation->next_subnet >= (1 << (64 - delegation->prefix.plen))) { + _LOGD (LOGD_IP6, "ipv6-pd: no more prefixes in %s/%d", + nm_utils_inet6_ntop (&delegation->prefix.address, NULL), + delegation->prefix.plen); + return FALSE; + } + + /* Allocate a new subnet. */ + subnet = g_slice_new0 (NMPlatformIP6Address); + g_hash_table_insert (delegation->subnets, GINT_TO_POINTER (ifindex), subnet); + + subnet->plen = 64; + subnet->address.s6_addr32[0] = delegation->prefix.address.s6_addr32[0] + | htonl (delegation->next_subnet >> 32); + subnet->address.s6_addr32[1] = delegation->prefix.address.s6_addr32[1] + | htonl (delegation->next_subnet); + + /* Out subnet pool management is pretty unsophisticated. We only add + * the subnets and index them by ifindex. That keeps the implementation + * simple and the dead entries make it easy to reuse the same subnet on + * subsequent activations. On the other hand they may waste the subnet + * space. */ + delegation->next_subnet++; + } + + subnet->timestamp = delegation->prefix.timestamp; + subnet->lifetime = delegation->prefix.lifetime; + subnet->preferred = delegation->prefix.preferred; + + _LOGD (LOGD_IP6, "ipv6-pd: %s allocated from a /%d prefix on %s", + nm_utils_inet6_ntop (&subnet->address, NULL), + delegation->prefix.plen, + nm_device_get_iface (device)); + + nm_device_use_ip6_subnet (device, subnet); + + return TRUE; +} + +/* + * Try to obtain a subnet from each prefix delegated to given requesting + * ("uplink") device and assign it to the downlink device. + * Requests a new prefix if no subnet could be found. + */ +static void +ip6_subnet_from_device (NMPolicy *self, NMDevice *from_device, NMDevice *device) +{ + NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); + IP6PrefixDelegation *delegation = NULL; + gboolean got_subnet = FALSE; + int have_prefixes = 0; + int i; + + expire_ip6_delegations (self); + + for (i = 0; i < priv->ip6_prefix_delegations->len; i++) { + delegation = &g_array_index (priv->ip6_prefix_delegations, + IP6PrefixDelegation, i); + + if (delegation->device != from_device) + continue; + + if (ip6_subnet_from_delegation (delegation, device)) + got_subnet = TRUE; + have_prefixes++; + } + + if (!got_subnet) { + _LOGI (LOGD_IP6, "ipv6-pd: none of %d prefixes of %s can be shared on %s", + have_prefixes, nm_device_get_iface (from_device), + nm_device_get_iface (device)); + nm_device_request_ip6_prefixes (from_device, have_prefixes + 1); + } +} + +static void +ip6_remove_device_prefix_delegations (NMPolicy *self, NMDevice *device) +{ + NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); + IP6PrefixDelegation *delegation = NULL; + int i; + + for (i = 0; i < priv->ip6_prefix_delegations->len; i++) { + delegation = &g_array_index (priv->ip6_prefix_delegations, + IP6PrefixDelegation, i); + if (delegation->device == device) + g_array_remove_index_fast (priv->ip6_prefix_delegations, i); + } +} + +static void +device_ip6_prefix_delegated (NMDevice *device, + NMPlatformIP6Address *prefix, + gpointer user_data) +{ + NMPolicyPrivate *priv = user_data; + NMPolicy *self = _PRIV_TO_SELF (priv); + IP6PrefixDelegation *delegation = NULL; + const GSList *connections, *iter; + int i; + + _LOGI (LOGD_IP6, "ipv6-pd: received a prefix %s/%d from %s", + nm_utils_inet6_ntop (&prefix->address, NULL), + prefix->plen, + nm_device_get_iface (device)); + + expire_ip6_delegations (self); + + for (i = 0; i < priv->ip6_prefix_delegations->len; i++) { + /* Look for an already known prefix to update. */ + delegation = &g_array_index (priv->ip6_prefix_delegations, IP6PrefixDelegation, i); + if (IN6_ARE_ADDR_EQUAL (&delegation->prefix.address, &prefix->address)) + break; + } + + if (i == priv->ip6_prefix_delegations->len) { + /* Allocate a delegation delegation for new prefix. */ + g_array_set_size (priv->ip6_prefix_delegations, i + 1); + delegation = &g_array_index (priv->ip6_prefix_delegations, IP6PrefixDelegation, i); + delegation->subnets = g_hash_table_new (NULL, NULL); + delegation->next_subnet = 0; + } + + delegation->device = device; + delegation->prefix = *prefix; + + /* The newly activated connections are added to the list beginning, + * so traversing it from the beginning makes it likely for newly + * activated connections that have no subnet assigned to be served + * first. That is a simple yet fair policy, which is good. */ + connections = nm_manager_get_active_connections (priv->manager); + for (iter = connections; iter; iter = g_slist_next (iter)) { + NMDevice *to_device = nm_active_connection_get_device (iter->data); + + if (nm_device_needs_ip6_subnet (to_device)) + ip6_subnet_from_delegation (delegation, to_device); + } +} + +static void +device_ip6_subnet_needed (NMDevice *device, + gpointer user_data) +{ + NMPolicyPrivate *priv = user_data; + NMPolicy *self = _PRIV_TO_SELF (priv); + + _LOGD (LOGD_IP6, "ipv6-pd: %s needs a subnet", + nm_device_get_iface (device)); + + if (!priv->default_device6) { + /* We request the prefixes when the default IPv6 device is set. */ + _LOGI (LOGD_IP6, "ipv6-pd: no device to obtain a subnet to share on %s from", + nm_device_get_iface (device)); + return; + } + ip6_subnet_from_device (self, priv->default_device6, device); + nm_device_copy_ip6_dns_config (device, priv->default_device6); +} + +/*****************************************************************************/ + static NMDevice * get_best_ip4_device (NMPolicy *self, gboolean fully_activated) { @@ -544,6 +776,21 @@ get_best_ip6_config (NMPolicy *self, out_vpn); } +static void +update_ip6_dns_delegation (NMPolicy *self) +{ + NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); + const GSList *connections, *iter; + + connections = nm_manager_get_active_connections (priv->manager); + for (iter = connections; iter; iter = g_slist_next (iter)) { + NMDevice *device = nm_active_connection_get_device (iter->data); + + if (device && nm_device_needs_ip6_subnet (device)) + nm_device_copy_ip6_dns_config (device, priv->default_device6); + } +} + static void update_ip6_dns (NMPolicy *self, NMDnsManager *dns_mgr) { @@ -562,6 +809,24 @@ update_ip6_dns (NMPolicy *self, NMDnsManager *dns_mgr) */ nm_dns_manager_add_ip6_config (dns_mgr, ip_iface, ip6_config, dns_type); } + + update_ip6_dns_delegation (self); +} + +static void +update_ip6_prefix_delegation (NMPolicy *self) +{ + NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); + const GSList *connections, *iter; + + /* There's new default IPv6 connection, try to get a prefix for everyone. */ + connections = nm_manager_get_active_connections (priv->manager); + for (iter = connections; iter; iter = g_slist_next (iter)) { + NMDevice *device = nm_active_connection_get_device (iter->data); + + if (device && nm_device_needs_ip6_subnet (device)) + ip6_subnet_from_device (self, priv->default_device6, device); + } } static void @@ -615,8 +880,10 @@ update_ip6_routing (NMPolicy *self, gboolean force_update) if (default_device6 == priv->default_device6) return; - priv->default_device6 = default_device6; + + update_ip6_prefix_delegation (self); + connection = nm_active_connection_get_applied_connection (best_ac); _LOGI (LOGD_CORE, "set '%s' (%s) as default for IPv6 routing and DNS", nm_connection_get_id (connection), ip_iface); @@ -1276,6 +1543,7 @@ device_state_changed (NMDevice *device, } } } + ip6_remove_device_prefix_delegations (self, device); break; case NM_DEVICE_STATE_DISCONNECTED: /* Reset retry counts for a device's connections when carrier on; if cable @@ -1394,6 +1662,8 @@ device_ip6_config_changed (NMDevice *device, nm_dns_manager_end_updates (priv->dns_manager, __func__); } +/*****************************************************************************/ + static void device_autoconnect_changed (NMDevice *device, GParamSpec *pspec, @@ -1432,6 +1702,8 @@ devices_list_register (NMPolicy *self, NMDevice *device) g_signal_connect_after (device, NM_DEVICE_STATE_CHANGED, (GCallback) device_state_changed, priv); g_signal_connect (device, NM_DEVICE_IP4_CONFIG_CHANGED, (GCallback) device_ip4_config_changed, priv); g_signal_connect (device, NM_DEVICE_IP6_CONFIG_CHANGED, (GCallback) device_ip6_config_changed, priv); + g_signal_connect (device, NM_DEVICE_IP6_PREFIX_DELEGATED, (GCallback) device_ip6_prefix_delegated, priv); + g_signal_connect (device, NM_DEVICE_IP6_SUBNET_NEEDED, (GCallback) device_ip6_subnet_needed, priv); g_signal_connect (device, "notify::" NM_DEVICE_AUTOCONNECT, (GCallback) device_autoconnect_changed, priv); g_signal_connect (device, NM_DEVICE_RECHECK_AUTO_ACTIVATE, (GCallback) device_recheck_auto_activate, priv); } @@ -1458,6 +1730,10 @@ device_removed (NMManager *manager, NMDevice *device, gpointer user_data) NMPolicyPrivate *priv = user_data; NMPolicy *self = _PRIV_TO_SELF (priv); + /* XXX is this needed? The delegations are cleaned up + * on transition to deactivated too. */ + ip6_remove_device_prefix_delegations (self, device); + /* Clear any idle callbacks for this device */ clear_pending_activate_check (self, device); @@ -1886,6 +2162,8 @@ nm_policy_init (NMPolicy *self) NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); priv->devices = g_hash_table_new (NULL, NULL); + priv->ip6_prefix_delegations = g_array_new (FALSE, FALSE, sizeof (IP6PrefixDelegation)); + g_array_set_clear_func (priv->ip6_prefix_delegations, clear_ip6_prefix_delegation); } static void @@ -2006,6 +2284,8 @@ dispose (GObject *object) g_signal_handlers_disconnect_by_data (priv->manager, priv); } + g_array_free (priv->ip6_prefix_delegations, TRUE); + nm_assert (NM_IS_MANAGER (priv->manager)); G_OBJECT_CLASS (nm_policy_parent_class)->dispose (object);