From 959944d6230e4a9e3983f4c24bb4454790d62ebf Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 6 Sep 2017 15:32:52 +0200 Subject: shared: add nm_g_object_ref_set() and nm_clear_g_object() - nm_clear_g_object() is like g_clear_object() but: - it returns a boolean value, indicating that something was cleared. - it includes an nm_assert() to check that the pointer is still valid. - it uses typeof() instead of blindly casting the argument. - nm_g_object_ref_set() combines nm_clear_g_object() and resetting the pointer to a new object, including taking a reference. - also returns a boolean, indicating whether something changed. - it gets the order of operations right: first it increses the ref-count, before unrefing the old object. - like nm_clear_g_object() and nm_clear_g_free() it first sets the destination to NULL, instead of leaving a dangling pointer for the duraction of the unref/free call. - fix nm_clear_g_free() not to use a possibly dangling pointer. Striclty speaking, that is undefined behavior. --- shared/nm-utils/nm-macros-internal.h | 55 ++++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 3 deletions(-) diff --git a/shared/nm-utils/nm-macros-internal.h b/shared/nm-utils/nm-macros-internal.h index d11766f91..556419756 100644 --- a/shared/nm-utils/nm-macros-internal.h +++ b/shared/nm-utils/nm-macros-internal.h @@ -619,6 +619,36 @@ nm_g_object_unref (gpointer obj) g_object_unref (obj); } +/* Assigns GObject @obj to destination @pdst, and takes an additional ref. + * The previous value of @pdst is unrefed. + * + * It makes sure to first increase the ref-count of @obj, and handles %NULL + * @obj correctly. + * */ +#define nm_g_object_ref_set(pp, obj) \ + ({ \ + typeof (*(pp)) *const _pp = (pp); \ + typeof (**_pp) *const _obj = (obj); \ + typeof (**_pp) *_p; \ + gboolean _changed = FALSE; \ + \ + if ( _pp \ + && ((_p = *_pp) != _obj)) { \ + if (_obj) { \ + nm_assert (G_IS_OBJECT (_obj)); \ + g_object_ref (_obj); \ + } \ + if (_p) { \ + nm_assert (G_IS_OBJECT (_p)); \ + *_pp = NULL; \ + g_object_unref (_p); \ + } \ + *_pp = _obj; \ + _changed = TRUE; \ + } \ + _changed; \ + }) + /* basically, replaces * g_clear_pointer (&location, g_free) * with @@ -631,13 +661,32 @@ nm_g_object_unref (gpointer obj) #define nm_clear_g_free(pp) \ ({ \ typeof (*(pp)) *_pp = (pp); \ - typeof (**_pp) *_p = *_pp; \ + typeof (**_pp) *_p; \ + gboolean _changed = FALSE; \ \ - if (_p) { \ + if ( _pp \ + && (_p = *_pp)) { \ *_pp = NULL; \ g_free (_p); \ + _changed = TRUE; \ + } \ + _changed; \ + }) + +#define nm_clear_g_object(pp) \ + ({ \ + typeof (*(pp)) *_pp = (pp); \ + typeof (**_pp) *_p; \ + gboolean _changed = FALSE; \ + \ + if ( _pp \ + && (_p = *_pp)) { \ + nm_assert (G_IS_OBJECT (_p)); \ + *_pp = NULL; \ + g_object_unref (_p); \ + _changed = TRUE; \ } \ - !!_p; \ + _changed; \ }) static inline gboolean -- cgit v1.2.3 From 9574472f9b8f7841d7e0ffb7a1eefa39214e8263 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 6 Sep 2017 13:13:22 +0200 Subject: policy: refactor setting hostname from DHCP in update_system_hostname() --- src/nm-policy.c | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/src/nm-policy.c b/src/nm-policy.c index 1a97b0273..2d4dc7e03 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -671,15 +671,13 @@ update_system_hostname (NMPolicy *self, NMDevice *best4, NMDevice *best6, const /* Grab a hostname out of the device's DHCP4 config */ dhcp4_config = nm_device_get_dhcp4_config (best4); if (dhcp4_config) { - p = dhcp_hostname = nm_dhcp4_config_get_option (dhcp4_config, "host_name"); - if (dhcp_hostname && strlen (dhcp_hostname)) { - /* Sanity check; strip leading spaces */ - while (*p) { - if (!g_ascii_isspace (*p++)) { - _set_hostname (self, p-1, "from DHCPv4"); - priv->dhcp_hostname = TRUE; - return; - } + dhcp_hostname = nm_dhcp4_config_get_option (dhcp4_config, "host_name"); + if (dhcp_hostname && dhcp_hostname[0]) { + p = nm_str_skip_leading_spaces (dhcp_hostname); + if (p[0]) { + _set_hostname (self, p, "from DHCPv4"); + priv->dhcp_hostname = TRUE; + return; } _LOGW (LOGD_DNS, "set-hostname: DHCPv4-provided hostname '%s' looks invalid; ignoring it", dhcp_hostname); @@ -691,15 +689,13 @@ update_system_hostname (NMPolicy *self, NMDevice *best4, NMDevice *best6, const /* Grab a hostname out of the device's DHCP6 config */ dhcp6_config = nm_device_get_dhcp6_config (best6); if (dhcp6_config) { - p = dhcp_hostname = nm_dhcp6_config_get_option (dhcp6_config, "host_name"); - if (dhcp_hostname && strlen (dhcp_hostname)) { - /* Sanity check; strip leading spaces */ - while (*p) { - if (!g_ascii_isspace (*p++)) { - _set_hostname (self, p-1, "from DHCPv6"); - priv->dhcp_hostname = TRUE; - return; - } + dhcp_hostname = nm_dhcp6_config_get_option (dhcp6_config, "host_name"); + if (dhcp_hostname && dhcp_hostname[0]) { + p = nm_str_skip_leading_spaces (dhcp_hostname); + if (p[0]) { + _set_hostname (self, p, "from DHCPv6"); + priv->dhcp_hostname = TRUE; + return; } _LOGW (LOGD_DNS, "set-hostname: DHCPv6-provided hostname '%s' looks invalid; ignoring it", dhcp_hostname); -- cgit v1.2.3 From 8881c11f939a653771e181a272ae00b7a8c7c057 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 6 Sep 2017 13:21:39 +0200 Subject: policy: always check for hostname from DHCPv6 in update_system_hostname() There is no reason for if-else-if. If DHCPv4 doesn't provide a hostname (but we are doing DHCP), just check for DHCPv6. --- src/nm-policy.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/nm-policy.c b/src/nm-policy.c index 2d4dc7e03..3d8c73e46 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -683,7 +683,9 @@ update_system_hostname (NMPolicy *self, NMDevice *best4, NMDevice *best6, const dhcp_hostname); } } - } else if (best6) { + } + + if (best6) { NMDhcp6Config *dhcp6_config; /* Grab a hostname out of the device's DHCP6 config */ -- cgit v1.2.3 From a75f528618be8abbae2c693443ce8292f10719ef Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 6 Sep 2017 13:01:55 +0200 Subject: policy: don't re-lookup the best device during update_system_hostname() We already track the best device as priv->default_device4 / priv->default_device6. Don't try to look it up again. If the cached values from @priv are invalid/outdated, that should be fixed instead. This was already introduced by commit 773c006a4c9d3162e9b371762dc59fd5948e4b43. But I don't think it should be done. --- src/nm-policy.c | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/src/nm-policy.c b/src/nm-policy.c index 3d8c73e46..c21b1c928 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -596,7 +596,7 @@ lookup_by_address (NMPolicy *self) } static void -update_system_hostname (NMPolicy *self, NMDevice *best4, NMDevice *best6, const char *msg) +update_system_hostname (NMPolicy *self, const char *msg) { NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); const char *configured_hostname; @@ -659,17 +659,11 @@ update_system_hostname (NMPolicy *self, NMDevice *best4, NMDevice *best6, const return; } - /* Try automatically determined hostname from the best device's IP config */ - if (!best4) - best4 = get_best_ip4_device (self, TRUE); - if (!best6) - best6 = get_best_ip6_device (self, TRUE); - - if (best4) { + if (priv->default_device4) { NMDhcp4Config *dhcp4_config; /* Grab a hostname out of the device's DHCP4 config */ - dhcp4_config = nm_device_get_dhcp4_config (best4); + dhcp4_config = nm_device_get_dhcp4_config (priv->default_device4); if (dhcp4_config) { dhcp_hostname = nm_dhcp4_config_get_option (dhcp4_config, "host_name"); if (dhcp_hostname && dhcp_hostname[0]) { @@ -685,11 +679,11 @@ update_system_hostname (NMPolicy *self, NMDevice *best4, NMDevice *best6, const } } - if (best6) { + if (priv->default_device6) { NMDhcp6Config *dhcp6_config; /* Grab a hostname out of the device's DHCP6 config */ - dhcp6_config = nm_device_get_dhcp6_config (best6); + dhcp6_config = nm_device_get_dhcp6_config (priv->default_device6); if (dhcp6_config) { dhcp_hostname = nm_dhcp6_config_get_option (dhcp6_config, "host_name"); if (dhcp_hostname && dhcp_hostname[0]) { @@ -724,7 +718,7 @@ update_system_hostname (NMPolicy *self, NMDevice *best4, NMDevice *best6, const priv->dhcp_hostname = FALSE; - if (!best4 && !best6) { + if (!priv->default_device4 && !priv->default_device6) { /* No best device; fall back to the last hostname set externally * to NM or if there wasn't one, 'localhost.localdomain' */ @@ -743,8 +737,8 @@ update_system_hostname (NMPolicy *self, NMDevice *best4, NMDevice *best6, const /* No configured hostname, no automatically determined hostname, and no * bootup hostname. Start reverse DNS of the current IPv4 or IPv6 address. */ - ip4_config = best4 ? nm_device_get_ip4_config (best4) : NULL; - ip6_config = best6 ? nm_device_get_ip6_config (best6) : NULL; + ip4_config = priv->default_device4 ? nm_device_get_ip4_config (priv->default_device4) : NULL; + ip6_config = priv->default_device6 ? nm_device_get_ip6_config (priv->default_device6) : NULL; if ( ip4_config && (addr4 = nm_ip4_config_get_first_address (ip4_config))) { @@ -1027,7 +1021,7 @@ update_routing_and_dns (NMPolicy *self, gboolean force_update) update_ip6_routing (self, force_update); /* Update the system hostname */ - update_system_hostname (self, priv->default_device4, priv->default_device6, "routing and dns"); + update_system_hostname (self, "routing and dns"); nm_dns_manager_end_updates (priv->dns_manager, __func__); } @@ -1258,7 +1252,7 @@ hostname_changed (NMHostnameManager *hostname_manager, GParamSpec *pspec, gpoint NMPolicyPrivate *priv = user_data; NMPolicy *self = _PRIV_TO_SELF (priv); - update_system_hostname (self, NULL, NULL, "hostname changed"); + update_system_hostname (self, "hostname changed"); } static void @@ -1740,7 +1734,7 @@ device_ip4_config_changed (NMDevice *device, } update_ip4_dns (self, priv->dns_manager); update_ip4_routing (self, TRUE); - update_system_hostname (self, priv->default_device4, priv->default_device6, "ip4 conf"); + update_system_hostname (self, "ip4 conf"); } else { /* Old configs get removed immediately */ if (old_config) @@ -1776,7 +1770,7 @@ device_ip6_config_changed (NMDevice *device, } update_ip6_dns (self, priv->dns_manager); update_ip6_routing (self, TRUE); - update_system_hostname (self, priv->default_device4, priv->default_device6, "ip6 conf"); + update_system_hostname (self, "ip6 conf"); } else { /* Old configs get removed immediately */ if (old_config) -- cgit v1.2.3 From f8cb6dcbb1b4fe985957e6349e6f97f642f9ff8e Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 6 Sep 2017 13:39:28 +0200 Subject: policy: cleanup setting default_device/activating_device - _LOGt() whenever the properties change. - some minor refactoring --- src/nm-policy.c | 64 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/src/nm-policy.c b/src/nm-policy.c index c21b1c928..cde86c574 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -822,8 +822,7 @@ static void update_ip4_routing (NMPolicy *self, gboolean force_update) { NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - NMDevice *best = NULL, *default_device; - NMConnection *connection = NULL; + NMDevice *best = NULL; NMVpnConnection *vpn = NULL; NMActiveConnection *best_ac = NULL; const char *ip_iface = NULL; @@ -832,18 +831,18 @@ update_ip4_routing (NMPolicy *self, gboolean force_update) * so we can get (vpn != NULL && best == NULL). */ if (!get_best_ip4_config (self, FALSE, &ip_iface, &best_ac, &best, &vpn)) { - gboolean changed; - - changed = (priv->default_device4 != NULL); - priv->default_device4 = NULL; - if (changed) + if (priv->default_device4) { + priv->default_device4 = NULL; + _LOGt (LOGD_DNS, "set-default-device-4: %p", NULL); _notify (self, PROP_DEFAULT_IP4_DEVICE); - + } return; } g_assert ((best || vpn) && best_ac); - if (!force_update && best && (best == priv->default_device4)) + if ( !force_update + && best + && best == priv->default_device4) return; if (best) { @@ -861,19 +860,18 @@ update_ip4_routing (NMPolicy *self, gboolean force_update) } if (vpn) - default_device = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (vpn)); - else - default_device = best; + best = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (vpn)); update_default_ac (self, best_ac, nm_active_connection_set_default); - if (default_device == priv->default_device4) + if (best == priv->default_device4) return; - priv->default_device4 = default_device; - connection = nm_active_connection_get_applied_connection (best_ac); + priv->default_device4 = best; + _LOGt (LOGD_DNS, "set-default-device-4: %p", best); _LOGI (LOGD_CORE, "set '%s' (%s) as default for IPv4 routing and DNS", - nm_connection_get_id (connection), ip_iface); + nm_connection_get_id (nm_active_connection_get_applied_connection (best_ac)), + ip_iface); _notify (self, PROP_DEFAULT_IP4_DEVICE); } @@ -950,8 +948,7 @@ static void update_ip6_routing (NMPolicy *self, gboolean force_update) { NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - NMDevice *best = NULL, *default_device6; - NMConnection *connection = NULL; + NMDevice *best = NULL; NMVpnConnection *vpn = NULL; NMActiveConnection *best_ac = NULL; const char *ip_iface = NULL; @@ -960,18 +957,18 @@ update_ip6_routing (NMPolicy *self, gboolean force_update) * so we can get (vpn != NULL && best == NULL). */ if (!get_best_ip6_config (self, FALSE, &ip_iface, &best_ac, &best, &vpn)) { - gboolean changed; - - changed = (priv->default_device6 != NULL); - priv->default_device6 = NULL; - if (changed) + if (priv->default_device6) { + priv->default_device6 = NULL; + _LOGt (LOGD_DNS, "set-default-device-6: %p", NULL); _notify (self, PROP_DEFAULT_IP6_DEVICE); - + } return; } g_assert ((best || vpn) && best_ac); - if (!force_update && best && (best == priv->default_device6)) + if ( !force_update + && best + && best == priv->default_device6) return; if (best) { @@ -989,21 +986,22 @@ update_ip6_routing (NMPolicy *self, gboolean force_update) } if (vpn) - default_device6 = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (vpn)); - else - default_device6 = best; + best = nm_active_connection_get_device (NM_ACTIVE_CONNECTION (vpn)); update_default_ac (self, best_ac, nm_active_connection_set_default6); - if (default_device6 == priv->default_device6) + if (best == priv->default_device6) return; - priv->default_device6 = default_device6; + + priv->default_device6 = best; + _LOGt (LOGD_DNS, "set-default-device-6: %p", best); 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); + nm_connection_get_id (nm_active_connection_get_applied_connection (best_ac)), + ip_iface); + _notify (self, PROP_DEFAULT_IP6_DEVICE); } @@ -1039,10 +1037,12 @@ check_activating_devices (NMPolicy *self) g_object_freeze_notify (object); if (best4 != priv->activating_device4) { + _LOGt (LOGD_DNS, "set-activating-device-4: %p", best4); priv->activating_device4 = best4; _notify (self, PROP_ACTIVATING_IP4_DEVICE); } if (best6 != priv->activating_device6) { + _LOGt (LOGD_DNS, "set-activating-device-6: %p", best4); priv->activating_device6 = best6; _notify (self, PROP_ACTIVATING_IP6_DEVICE); } -- cgit v1.2.3 From 5c7e0654ebc64bc84b18f66854686f896d18e4ca Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 6 Sep 2017 15:41:12 +0200 Subject: policy: take reference to best_device/activating_device Don't rely on manager keeping them alive long enough. E.g. get-best-device() is used when resetting the best device, however, it accesses the current device (hence, it relies on manager removing the device from the list, but keeping it alive long enough). --- src/nm-policy.c | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/src/nm-policy.c b/src/nm-policy.c index cde86c574..f3c915db9 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -831,8 +831,7 @@ update_ip4_routing (NMPolicy *self, gboolean force_update) * so we can get (vpn != NULL && best == NULL). */ if (!get_best_ip4_config (self, FALSE, &ip_iface, &best_ac, &best, &vpn)) { - if (priv->default_device4) { - priv->default_device4 = NULL; + if (nm_clear_g_object (&priv->default_device4)) { _LOGt (LOGD_DNS, "set-default-device-4: %p", NULL); _notify (self, PROP_DEFAULT_IP4_DEVICE); } @@ -864,11 +863,10 @@ update_ip4_routing (NMPolicy *self, gboolean force_update) update_default_ac (self, best_ac, nm_active_connection_set_default); - if (best == priv->default_device4) + if (!nm_g_object_ref_set (&priv->default_device4, best)) return; + _LOGt (LOGD_DNS, "set-default-device-4: %p", priv->default_device4); - priv->default_device4 = best; - _LOGt (LOGD_DNS, "set-default-device-4: %p", best); _LOGI (LOGD_CORE, "set '%s' (%s) as default for IPv4 routing and DNS", nm_connection_get_id (nm_active_connection_get_applied_connection (best_ac)), ip_iface); @@ -957,8 +955,7 @@ update_ip6_routing (NMPolicy *self, gboolean force_update) * so we can get (vpn != NULL && best == NULL). */ if (!get_best_ip6_config (self, FALSE, &ip_iface, &best_ac, &best, &vpn)) { - if (priv->default_device6) { - priv->default_device6 = NULL; + if (nm_clear_g_object (&priv->default_device6)) { _LOGt (LOGD_DNS, "set-default-device-6: %p", NULL); _notify (self, PROP_DEFAULT_IP6_DEVICE); } @@ -990,18 +987,15 @@ update_ip6_routing (NMPolicy *self, gboolean force_update) update_default_ac (self, best_ac, nm_active_connection_set_default6); - if (best == priv->default_device6) + if (!nm_g_object_ref_set (&priv->default_device6, best)) return; - - priv->default_device6 = best; - _LOGt (LOGD_DNS, "set-default-device-6: %p", best); + _LOGt (LOGD_DNS, "set-default-device-6: %p", priv->default_device6); update_ip6_prefix_delegation (self); _LOGI (LOGD_CORE, "set '%s' (%s) as default for IPv6 routing and DNS", nm_connection_get_id (nm_active_connection_get_applied_connection (best_ac)), ip_iface); - _notify (self, PROP_DEFAULT_IP6_DEVICE); } @@ -1028,26 +1022,23 @@ static void check_activating_devices (NMPolicy *self) { NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE (self); - GObject *object = G_OBJECT (self); NMDevice *best4, *best6 = NULL; best4 = get_best_ip4_device (self, FALSE); best6 = get_best_ip6_device (self, FALSE); - g_object_freeze_notify (object); + g_object_freeze_notify (G_OBJECT (self)); - if (best4 != priv->activating_device4) { - _LOGt (LOGD_DNS, "set-activating-device-4: %p", best4); - priv->activating_device4 = best4; + if (nm_g_object_ref_set (&priv->activating_device4, best4)) { + _LOGt (LOGD_DNS, "set-activating-device-4: %p", priv->activating_device4); _notify (self, PROP_ACTIVATING_IP4_DEVICE); } - if (best6 != priv->activating_device6) { - _LOGt (LOGD_DNS, "set-activating-device-6: %p", best4); - priv->activating_device6 = best6; + if (nm_g_object_ref_set (&priv->activating_device6, best6)) { + _LOGt (LOGD_DNS, "set-activating-device-6: %p", priv->activating_device6); _notify (self, PROP_ACTIVATING_IP6_DEVICE); } - g_object_thaw_notify (object); + g_object_thaw_notify (G_OBJECT (self)); } typedef struct { @@ -2397,6 +2388,11 @@ dispose (GObject *object) g_clear_object (&priv->lookup.addr); g_clear_object (&priv->lookup.resolver); + nm_clear_g_object (&priv->default_device4); + nm_clear_g_object (&priv->default_device6); + nm_clear_g_object (&priv->activating_device4); + nm_clear_g_object (&priv->activating_device6); + while (priv->pending_activation_checks) activate_data_free (priv->pending_activation_checks->data); -- cgit v1.2.3 From b3254da173f5c91d9e9e2fb042d03ea9c19fe774 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Sat, 2 Sep 2017 16:56:27 +0200 Subject: platform/trivial: add code comments --- src/platform/nm-platform.c | 4 ++++ src/platform/nm-platform.h | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 7e91b7547..1b47702cc 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -3778,6 +3778,10 @@ _ip_route_scope_inv_get_normalized (const NMPlatformIP4Route *route) * Adding a route to kernel via nm_platform_ip_route_add() will normalize/coerce some * properties of the route. This function modifies (normalizes) the route like it * would be done by adding the route in kernel. + * + * Note that this function is related to NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY + * in that if two routes compare semantically equal, after normalizing they also shall + * compare equal with NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL. */ void nm_platform_ip_route_normalize (int addr_family, diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index b29e6668d..a703d4c87 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -138,7 +138,10 @@ typedef enum { * a route destination 192.168.1.5/24 is not accepted by kernel and * we treat it identical to 192.168.1.0/24. Semantically these * routes are identical, but NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL will - * report them as different. */ + * report them as different. + * + * The result shall be identical to call first nm_platform_ip_route_normalize() + * on both routes and then doing a full comparison. */ NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY, /* compare all fields. This should have the same effect as memcmp(), -- cgit v1.2.3 From af1ad0eed7a9188d2b6fc0ad5035dadb729f1836 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 31 Aug 2017 11:26:58 +0200 Subject: core/tests: add test for nm_ip6_config_replace() --- src/tests/test-ip6-config.c | 67 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/src/tests/test-ip6-config.c b/src/tests/test-ip6-config.c index 707900953..9eb4d35fd 100644 --- a/src/tests/test-ip6-config.c +++ b/src/tests/test-ip6-config.c @@ -345,6 +345,71 @@ test_strip_search_trailing_dot (void) /*****************************************************************************/ +static void +test_replace (gconstpointer user_data) +{ + nm_auto_unref_dedup_multi_index NMDedupMultiIndex *multi_idx = nm_dedup_multi_index_new (); + const int TEST_IDX = GPOINTER_TO_INT (user_data); + const int IFINDEX = 1; + gs_unref_object NMIP6Config *src_conf = NULL; + gs_unref_object NMIP6Config *dst_conf = NULL; + NMPlatformIP6Address *addr; + NMPlatformIP6Address addrs[5] = { }; + guint addrs_n = 0; + guint i; + + dst_conf = nm_ip6_config_new (multi_idx, IFINDEX); + src_conf = nm_ip6_config_new (multi_idx, IFINDEX); + + switch (TEST_IDX) { + case 1: + addr = &addrs[addrs_n++]; + addr->ifindex = IFINDEX; + addr->address = *nmtst_inet6_from_string ("fe80::78ec:7a6d:602d:20f2"); + addr->plen = 64; + addr->n_ifa_flags = IFA_F_PERMANENT; + addr->addr_source = NM_IP_CONFIG_SOURCE_KERNEL; + break; + case 2: + addr = &addrs[addrs_n++]; + addr->ifindex = IFINDEX; + addr->address = *nmtst_inet6_from_string ("fe80::78ec:7a6d:602d:20f2"); + addr->plen = 64; + addr->n_ifa_flags = IFA_F_PERMANENT; + addr->addr_source = NM_IP_CONFIG_SOURCE_KERNEL; + + addr = &addrs[addrs_n++]; + addr->ifindex = IFINDEX; + addr->address = *nmtst_inet6_from_string ("1::1"); + addr->plen = 64; + addr->addr_source = NM_IP_CONFIG_SOURCE_USER; + + nm_ip6_config_add_address (dst_conf, addr); + break; + default: + g_assert_not_reached (); + } + + g_assert (addrs_n < G_N_ELEMENTS (addrs)); + + for (i = 0; i < addrs_n; i++) + nm_ip6_config_add_address (src_conf, &addrs[i]); + + nm_ip6_config_replace (dst_conf, src_conf, NULL); + + for (i = 0; i < addrs_n; i++) { + const NMPlatformIP6Address *a = _nmtst_nm_ip6_config_get_address (dst_conf, i); + const NMPlatformIP6Address *b = _nmtst_nm_ip6_config_get_address (src_conf, i); + + g_assert (nm_platform_ip6_address_cmp (&addrs[i], a) == 0); + g_assert (nm_platform_ip6_address_cmp (&addrs[i], b) == 0); + } + g_assert (addrs_n == nm_ip6_config_get_num_addresses (dst_conf)); + g_assert (addrs_n == nm_ip6_config_get_num_addresses (src_conf)); +} + +/*****************************************************************************/ + NMTST_DEFINE(); int @@ -358,6 +423,8 @@ main (int argc, char **argv) g_test_add_func ("/ip6-config/add-route-with-source", test_add_route_with_source); g_test_add_func ("/ip6-config/test_nm_ip6_config_addresses_sort", test_nm_ip6_config_addresses_sort); g_test_add_func ("/ip6-config/strip-search-trailing-dot", test_strip_search_trailing_dot); + g_test_add_data_func ("/ip6-config/replace/1", GINT_TO_POINTER (1), test_replace); + g_test_add_data_func ("/ip6-config/replace/2", GINT_TO_POINTER (2), test_replace); return g_test_run (); } -- cgit v1.2.3 From 546e12417a77b6550db98d974f7b5fcf9b24fa62 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Thu, 31 Aug 2017 13:01:19 +0200 Subject: core: use _nm_ip_config_add_obj() in nm_ip4_config_replace() for routes Avoid calling nm_dedup_multi_index_add() directly, like we do for all other places. Instead, call the wrapper _nm_ip_config_add_obj() which does some pre-precessing. In practice, the result is exactly the same (at the moment). But there should by only one way to add the route. --- src/nm-ip4-config.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c index ad939d000..01088fb7a 100644 --- a/src/nm-ip4-config.c +++ b/src/nm-ip4-config.c @@ -1619,12 +1619,13 @@ nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relev has_minor_changes = TRUE; nm_dedup_multi_index_dirty_set_idx (dst_priv->multi_idx, &dst_priv->idx_ip4_routes); nm_dedup_multi_iter_for_each (&ipconf_iter_src, head_entry_src) { - nm_dedup_multi_index_add (dst_priv->multi_idx, - &dst_priv->idx_ip4_routes, - ipconf_iter_src.current->obj, - NM_DEDUP_MULTI_IDX_MODE_APPEND_FORCE, - NULL, - NULL); + _nm_ip_config_add_obj (dst_priv->multi_idx, + &dst_priv->idx_ip4_routes_, + dst_priv->ifindex, + ipconf_iter_src.current->obj, + NULL, + FALSE, + TRUE); } nm_dedup_multi_index_dirty_remove_idx (dst_priv->multi_idx, &dst_priv->idx_ip4_routes, FALSE); _notify_routes (dst); -- cgit v1.2.3 From a0ca6070806cd62e90ae0660c4c3652606e0fbcf Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 30 Aug 2017 19:05:38 +0200 Subject: core: return new object from _nm_ip_config_add_obj() Will be used later. --- src/nm-ip4-config.c | 24 +++++++++++++++++------- src/nm-ip4-config.h | 3 ++- src/nm-ip6-config.c | 21 ++++++++++++++------- 3 files changed, 33 insertions(+), 15 deletions(-) diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c index 01088fb7a..bd9f9beb2 100644 --- a/src/nm-ip4-config.c +++ b/src/nm-ip4-config.c @@ -165,10 +165,12 @@ _nm_ip_config_add_obj (NMDedupMultiIndex *multi_idx, const NMPObject *obj_new, const NMPlatformObject *pl_new, gboolean merge, - gboolean append_force) + gboolean append_force, + const NMPObject **out_obj_new) { NMPObject obj_new_stackinit; const NMDedupMultiEntry *entry_old; + const NMDedupMultiEntry *entry_new; nm_assert (multi_idx); nm_assert (idx_type); @@ -271,15 +273,18 @@ _nm_ip_config_add_obj (NMDedupMultiIndex *multi_idx, NULL, entry_old ?: NM_DEDUP_MULTI_ENTRY_MISSING, NULL, - NULL, + &entry_new, NULL)) { nm_assert_not_reached (); + NM_SET_OUT (out_obj_new, NULL); return FALSE; } + NM_SET_OUT (out_obj_new, entry_new->obj); return TRUE; append_force_and_out: + NM_SET_OUT (out_obj_new, entry_old->obj); if (append_force) { if (nm_dedup_multi_entry_reorder (entry_old, NULL, TRUE)) return TRUE; @@ -641,7 +646,8 @@ nm_ip4_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i plobj, NULL, FALSE, - TRUE)) + TRUE, + NULL)) nm_assert_not_reached (); } head_entry = nm_ip4_config_lookup_addresses (self); @@ -1580,7 +1586,8 @@ nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relev ipconf_iter_src.current->obj, NULL, FALSE, - TRUE); + TRUE, + NULL); } nm_dedup_multi_index_dirty_remove_idx (dst_priv->multi_idx, &dst_priv->idx_ip4_addresses, FALSE); _notify_addresses (dst); @@ -1625,7 +1632,8 @@ nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relev ipconf_iter_src.current->obj, NULL, FALSE, - TRUE); + TRUE, + NULL); } nm_dedup_multi_index_dirty_remove_idx (dst_priv->multi_idx, &dst_priv->idx_ip4_routes, FALSE); _notify_routes (dst); @@ -1986,7 +1994,8 @@ _add_address (NMIP4Config *self, const NMPObject *obj_new, const NMPlatformIP4Ad obj_new, (const NMPlatformObject *) new, TRUE, - FALSE)) + FALSE, + NULL)) _notify_addresses (self); } @@ -2126,7 +2135,8 @@ _add_route (NMIP4Config *self, const NMPObject *obj_new, const NMPlatformIP4Rout obj_new, (const NMPlatformObject *) new, TRUE, - FALSE)) + FALSE, + NULL)) _notify_routes (self); } diff --git a/src/nm-ip4-config.h b/src/nm-ip4-config.h index aa529b54d..cd1392ce6 100644 --- a/src/nm-ip4-config.h +++ b/src/nm-ip4-config.h @@ -90,7 +90,8 @@ gboolean _nm_ip_config_add_obj (NMDedupMultiIndex *multi_idx, const NMPObject *obj_new, const NMPlatformObject *pl_new, gboolean merge, - gboolean append_force); + gboolean append_force, + const NMPObject **out_obj_new); const NMDedupMultiEntry *_nm_ip_config_lookup_ip_route (const NMDedupMultiIndex *multi_idx, const NMIPConfigDedupMultiIdxType *idx_type, diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c index 86d76347b..feee1f71c 100644 --- a/src/nm-ip6-config.c +++ b/src/nm-ip6-config.c @@ -439,7 +439,8 @@ nm_ip6_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i plobj, NULL, FALSE, - TRUE)) + TRUE, + NULL)) nm_assert_not_reached (); has_addresses = TRUE; } @@ -1254,7 +1255,8 @@ nm_ip6_config_replace (NMIP6Config *dst, const NMIP6Config *src, gboolean *relev ipconf_iter_src.current->obj, NULL, FALSE, - TRUE); + TRUE, + NULL); } nm_dedup_multi_index_dirty_remove_idx (dst_priv->multi_idx, &dst_priv->idx_ip6_addresses, FALSE); _notify_addresses (dst); @@ -1299,7 +1301,8 @@ nm_ip6_config_replace (NMIP6Config *dst, const NMIP6Config *src, gboolean *relev ipconf_iter_src.current->obj, NULL, FALSE, - TRUE); + TRUE, + NULL); } nm_dedup_multi_index_dirty_remove_idx (dst_priv->multi_idx, &dst_priv->idx_ip6_routes, FALSE); _notify_routes (dst); @@ -1561,7 +1564,8 @@ nm_ip6_config_reset_addresses_ndisc (NMIP6Config *self, &obj, NULL, FALSE, - TRUE)) + TRUE, + NULL)) changed = TRUE; } @@ -1595,7 +1599,8 @@ _add_address (NMIP6Config *self, obj_new, (const NMPlatformObject *) new, TRUE, - FALSE)) + FALSE, + NULL)) _notify_addresses (self); } @@ -1788,7 +1793,8 @@ nm_ip6_config_reset_routes_ndisc (NMIP6Config *self, &obj, NULL, FALSE, - TRUE)) + TRUE, + NULL)) changed = TRUE; } @@ -1824,7 +1830,8 @@ _add_route (NMIP6Config *self, const NMPObject *obj_new, const NMPlatformIP6Rout obj_new, (const NMPlatformObject *) new, TRUE, - FALSE)) + FALSE, + NULL)) _notify_routes (self); } -- cgit v1.2.3 From 6801cd65bf5b429d7295f335605742b92642c508 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 30 Aug 2017 19:15:39 +0200 Subject: platform: add nm_clear_nmp_object() util --- src/platform/nmp-object.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/platform/nmp-object.h b/src/platform/nmp-object.h index 6b4a28c25..6aeb1fb1b 100644 --- a/src/platform/nmp-object.h +++ b/src/platform/nmp-object.h @@ -435,6 +435,21 @@ nmp_object_unref (const NMPObject *obj) return NULL; } +#define nm_clear_nmp_object(ptr) \ + ({ \ + typeof (ptr) _ptr = (ptr); \ + typeof (*_ptr) _pptr; \ + gboolean _changed = FALSE; \ + \ + if ( _ptr \ + && (_pptr = *_ptr)) { \ + *_ptr = NULL; \ + nmp_object_unref (_pptr); \ + _changed = TRUE; \ + } \ + _changed; \ + }) + NMPObject *nmp_object_new (NMPObjectType obj_type, const NMPlatformObject *plob); NMPObject *nmp_object_new_link (int ifindex); -- cgit v1.2.3 From c16e8718880b18fcaa8d2e4bf3b4ee98ee995768 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 30 Aug 2017 19:10:59 +0200 Subject: core: nm_utils_ip_route_metric_normalize() util Functions that take and addr_family argument are just nicer to use at places where we treat IPv4 and IPv6 generically. --- src/devices/nm-device.c | 5 +---- src/nm-core-utils.h | 6 ++++++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 55ad6c323..b861f2cb6 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -5553,10 +5553,7 @@ _device_get_default_route_from_platform (NMDevice *self, int addr_family, NMPlat continue; /* if there are several default routes, find the one with the best metric */ - m = r->metric; - if (addr_family != AF_INET) - m = nm_utils_ip6_route_metric_normalize (r->metric); - + m = nm_utils_ip_route_metric_normalize (addr_family, r->metric); if (!route || m < route_metric) { route = NMP_OBJECT_CAST_IP_ROUTE (plobj); route_metric = m; diff --git a/src/nm-core-utils.h b/src/nm-core-utils.h index 42afcb0e2..f9545653d 100644 --- a/src/nm-core-utils.h +++ b/src/nm-core-utils.h @@ -174,6 +174,12 @@ nm_utils_ip6_route_metric_normalize (guint32 metric) return metric ? metric : 1024 /*NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP6*/; } +static inline guint32 +nm_utils_ip_route_metric_normalize (int addr_family, guint32 metric) +{ + return addr_family == AF_INET6 ? nm_utils_ip6_route_metric_normalize (metric) : metric; +} + int nm_utils_modprobe (GError **error, gboolean suppress_error_loggin, const char *arg1, ...) G_GNUC_NULL_TERMINATED; guint64 nm_utils_get_start_time_for_pid (pid_t pid, char *out_state, pid_t *out_ppid); -- cgit v1.2.3 From e99a6039445445c4c9d9cef18abd2022985e7dfc Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 30 Aug 2017 19:10:15 +0200 Subject: device: expose nm_device_get_ip_route_metric() function Will be used later. --- src/devices/nm-device.c | 27 +++++++-------------------- src/devices/nm-device.h | 16 ++++++++++++++-- 2 files changed, 21 insertions(+), 22 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index b861f2cb6..397296373 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -1645,9 +1645,9 @@ route_metric_with_penalty (NMDevice *self, guint32 metric) return metric; } -static guint32 -_get_ipx_route_metric (NMDevice *self, - gboolean is_v4) +guint32 +nm_device_get_ip_route_metric (NMDevice *self, + int addr_family) { char *value; gint64 route_metric; @@ -1655,10 +1655,11 @@ _get_ipx_route_metric (NMDevice *self, NMConnection *connection; g_return_val_if_fail (NM_IS_DEVICE (self), G_MAXUINT32); + g_return_val_if_fail (NM_IN_SET (addr_family, AF_INET, AF_INET6), G_MAXUINT32); connection = nm_device_get_applied_connection (self); if (connection) { - s_ip = is_v4 + s_ip = addr_family == AF_INET ? nm_connection_get_setting_ip4_config (connection) : nm_connection_get_setting_ip6_config (connection); @@ -1677,7 +1678,7 @@ _get_ipx_route_metric (NMDevice *self, * Note that that means that the route-metric might change between SIGHUP. * You must cache the returned value if that is a problem. */ value = nm_config_data_get_connection_default (NM_CONFIG_GET_DATA, - is_v4 ? "ipv4.route-metric" : "ipv6.route-metric", self); + addr_family == AF_INET ? "ipv4.route-metric" : "ipv6.route-metric", self); if (value) { route_metric = _nm_utils_ascii_str_to_int64 (value, 10, 0, G_MAXUINT32, -1); g_free (value); @@ -1687,21 +1688,7 @@ _get_ipx_route_metric (NMDevice *self, } route_metric = nm_device_get_priority (self); out: - if (!is_v4) - route_metric = nm_utils_ip6_route_metric_normalize (route_metric); - return route_metric; -} - -guint32 -nm_device_get_ip4_route_metric (NMDevice *self) -{ - return _get_ipx_route_metric (self, TRUE); -} - -guint32 -nm_device_get_ip6_route_metric (NMDevice *self) -{ - return _get_ipx_route_metric (self, FALSE); + return nm_utils_ip_route_metric_normalize (addr_family, route_metric); } static void diff --git a/src/devices/nm-device.h b/src/devices/nm-device.h index 358b59af2..f46a64ca2 100644 --- a/src/devices/nm-device.h +++ b/src/devices/nm-device.h @@ -445,8 +445,20 @@ NMLinkType nm_device_get_link_type (NMDevice *dev); NMMetered nm_device_get_metered (NMDevice *dev); int nm_device_get_priority (NMDevice *dev); -guint32 nm_device_get_ip4_route_metric (NMDevice *dev); -guint32 nm_device_get_ip6_route_metric (NMDevice *dev); + +guint32 nm_device_get_ip_route_metric (NMDevice *dev, int addr_family); + +static inline guint32 +nm_device_get_ip4_route_metric (NMDevice *self) +{ + return nm_device_get_ip_route_metric (self, AF_INET); +} + +static inline guint32 +nm_device_get_ip6_route_metric (NMDevice *self) +{ + return nm_device_get_ip_route_metric (self, AF_INET6); +} const char * nm_device_get_hw_address (NMDevice *dev); const char * nm_device_get_permanent_hw_address (NMDevice *self); -- cgit v1.2.3 From 315bd0a97d0f05f0e04297a48ed62d92d1b3aa9b Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Wed, 30 Aug 2017 19:17:29 +0200 Subject: core: add nm_utils_connection_has_default_route() Taken from "src/nm-default-route-manager.c". --- src/NetworkManagerUtils.c | 49 +++++++++++++++++++++++++++++++++ src/devices/nm-device.c | 6 ++--- src/nm-core-utils.h | 4 +++ src/nm-default-route-manager.c | 61 +----------------------------------------- src/nm-default-route-manager.h | 3 --- 5 files changed, 56 insertions(+), 67 deletions(-) diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index 229b05a3e..316f4acf1 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -206,6 +206,55 @@ nm_utils_get_ip_config_method (NMConnection *connection, g_assert_not_reached (); } +gboolean +nm_utils_connection_has_default_route (NMConnection *connection, + int addr_family, + gboolean *out_is_never_default) +{ + const char *method; + NMSettingIPConfig *s_ip; + gboolean is_never_default = FALSE; + gboolean has_default_route = FALSE; + + g_return_val_if_fail (NM_IS_CONNECTION (connection), FALSE); + g_return_val_if_fail (NM_IN_SET (addr_family, AF_INET, AF_INET6), FALSE); + + if (!connection) + goto out; + + if (addr_family == AF_INET) + s_ip = nm_connection_get_setting_ip4_config (connection); + else + s_ip = nm_connection_get_setting_ip6_config (connection); + if (!s_ip) + goto out; + if (nm_setting_ip_config_get_never_default (s_ip)) { + is_never_default = TRUE; + goto out; + } + + if (addr_family == AF_INET) { + method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG); + if (NM_IN_STRSET (method, NULL, + NM_SETTING_IP4_CONFIG_METHOD_DISABLED, + NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)) + goto out; + } else { + method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); + if (NM_IN_STRSET (method, NULL, + NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL)) + goto out; + } + + has_default_route = TRUE; +out: + NM_SET_OUT (out_is_never_default, is_never_default); + return has_default_route; +} + +/*****************************************************************************/ + void nm_utils_complete_generic (NMPlatform *platform, NMConnection *connection, diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 397296373..9f015951a 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -5753,8 +5753,7 @@ ip4_config_merge_and_apply (NMDevice *self, */ connection_has_default_route - = nm_default_route_manager_ip4_connection_has_default_route (nm_netns_get_default_route_manager (priv->netns), - connection, &connection_is_never_default); + = nm_utils_connection_has_default_route (connection, AF_INET, &connection_is_never_default); if ( !priv->v4_commit_first_time && connection_is_never_default) { @@ -6489,8 +6488,7 @@ ip6_config_merge_and_apply (NMDevice *self, */ connection_has_default_route - = nm_default_route_manager_ip6_connection_has_default_route (nm_netns_get_default_route_manager (priv->netns), - connection, &connection_is_never_default); + = nm_utils_connection_has_default_route (connection, AF_INET6, &connection_is_never_default); if ( !priv->v6_commit_first_time && connection_is_never_default) { diff --git a/src/nm-core-utils.h b/src/nm-core-utils.h index f9545653d..aca69fce6 100644 --- a/src/nm-core-utils.h +++ b/src/nm-core-utils.h @@ -292,6 +292,10 @@ fcn_name (lookup_type val, char *buf, gsize len) \ const char *nm_utils_get_ip_config_method (NMConnection *connection, GType ip_setting_type); +gboolean nm_utils_connection_has_default_route (NMConnection *connection, + int addr_family, + gboolean *out_is_never_default); + char *nm_utils_new_vlan_name (const char *parent_iface, guint32 vlan_id); const char *nm_utils_new_infiniband_name (char *name, const char *parent_name, int p_key); diff --git a/src/nm-default-route-manager.c b/src/nm-default-route-manager.c index cde53089e..dc8f83b4a 100644 --- a/src/nm-default-route-manager.c +++ b/src/nm-default-route-manager.c @@ -964,65 +964,6 @@ nm_default_route_manager_ip6_update_default_route (NMDefaultRouteManager *self, /*****************************************************************************/ -static gboolean -_ipx_connection_has_default_route (const VTableIP *vtable, NMDefaultRouteManager *self, NMConnection *connection, gboolean *out_is_never_default) -{ - const char *method; - NMSettingIPConfig *s_ip; - gboolean is_never_default = FALSE; - gboolean has_default_route = FALSE; - - g_return_val_if_fail (NM_IS_DEFAULT_ROUTE_MANAGER (self), FALSE); - - if (!connection) - goto out; - - if (vtable->vt->is_ip4) - s_ip = nm_connection_get_setting_ip4_config (connection); - else - s_ip = nm_connection_get_setting_ip6_config (connection); - if (!s_ip) - goto out; - if (nm_setting_ip_config_get_never_default (s_ip)) { - is_never_default = TRUE; - goto out; - } - - if (vtable->vt->is_ip4) { - method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP4_CONFIG); - if ( !method - || !strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) - || !strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)) - goto out; - } else { - method = nm_utils_get_ip_config_method (connection, NM_TYPE_SETTING_IP6_CONFIG); - if ( !method - || !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_IGNORE) - || !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL)) - goto out; - } - - has_default_route = TRUE; -out: - if (out_is_never_default) - *out_is_never_default = is_never_default; - return has_default_route; -} - -gboolean -nm_default_route_manager_ip4_connection_has_default_route (NMDefaultRouteManager *self, NMConnection *connection, gboolean *out_is_never_default) -{ - return _ipx_connection_has_default_route (&vtable_ip4, self, connection, out_is_never_default); -} - -gboolean -nm_default_route_manager_ip6_connection_has_default_route (NMDefaultRouteManager *self, NMConnection *connection, gboolean *out_is_never_default) -{ - return _ipx_connection_has_default_route (&vtable_ip6, self, connection, out_is_never_default); -} - -/*****************************************************************************/ - static NMDevice * _ipx_get_best_device (const VTableIP *vtable, NMDefaultRouteManager *self, const GSList *devices) { @@ -1117,7 +1058,7 @@ _ipx_get_best_activating_device (const VTableIP *vtable, NMDefaultRouteManager * || state >= NM_DEVICE_STATE_DEACTIVATING) continue; - if (!_ipx_connection_has_default_route (vtable, self, nm_device_get_applied_connection (device), NULL)) + if (!nm_utils_connection_has_default_route (nm_device_get_applied_connection (device), vtable->vt->addr_family, NULL)) continue; prio = nm_device_get_ip4_route_metric (device); diff --git a/src/nm-default-route-manager.h b/src/nm-default-route-manager.h index bac8a6eba..d6ad719b0 100644 --- a/src/nm-default-route-manager.h +++ b/src/nm-default-route-manager.h @@ -42,9 +42,6 @@ NMDefaultRouteManager *nm_default_route_manager_new (gboolean log_with_ptr, NMPl gboolean nm_default_route_manager_ip4_update_default_route (NMDefaultRouteManager *manager, gpointer source); gboolean nm_default_route_manager_ip6_update_default_route (NMDefaultRouteManager *manager, gpointer source); -gboolean nm_default_route_manager_ip4_connection_has_default_route (NMDefaultRouteManager *manager, NMConnection *connection, gboolean *out_is_never_default); -gboolean nm_default_route_manager_ip6_connection_has_default_route (NMDefaultRouteManager *manager, NMConnection *connection, gboolean *out_is_never_default); - NMDevice *nm_default_route_manager_ip4_get_best_device (NMDefaultRouteManager *manager, const GSList *devices, gboolean fully_activated, NMDevice *preferred_device); NMDevice *nm_default_route_manager_ip6_get_best_device (NMDefaultRouteManager *manager, const GSList *devices, gboolean fully_activated, NMDevice *preferred_device); -- cgit v1.2.3 From 199499967a04b123f2a842a94bdb637c3ac74a76 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 1 Sep 2017 13:38:13 +0200 Subject: core: don't loop twice over routes in nm_ip4_config_capture() and nm_ip6_config_capture(). --- src/nm-ip4-config.c | 12 ++++-------- src/nm-ip6-config.c | 13 ++++--------- 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c index bd9f9beb2..0603a4348 100644 --- a/src/nm-ip4-config.c +++ b/src/nm-ip4-config.c @@ -679,14 +679,6 @@ nm_ip4_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i } priv->has_gateway = TRUE; } - } - - /* we detect the route metric based on the default route. All non-default - * routes have their route metrics explicitly set. */ - priv->route_metric = priv->has_gateway ? (gint64) lowest_metric : (gint64) -1; - - nmp_cache_iter_for_each (&iter, head_entry, &plobj) { - const NMPlatformIP4Route *route = NMP_OBJECT_CAST_IP4_ROUTE (plobj); if (route->rt_source == NM_IP_CONFIG_SOURCE_RTPROT_KERNEL) continue; @@ -695,6 +687,10 @@ nm_ip4_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i _add_route (self, plobj, NULL); } + /* we detect the route metric based on the default route. All non-default + * routes have their route metrics explicitly set. */ + priv->route_metric = priv->has_gateway ? (gint64) lowest_metric : (gint64) -1; + /* If the interface has the default route, and has IPv4 addresses, capture * nameservers from /etc/resolv.conf. */ diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c index feee1f71c..5bc17cd18 100644 --- a/src/nm-ip6-config.c +++ b/src/nm-ip6-config.c @@ -471,23 +471,18 @@ nm_ip6_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i } has_gateway = TRUE; } - } - - /* we detect the route metric based on the default route. All non-default - * routes have their route metrics explicitly set. */ - priv->route_metric = has_gateway ? (gint64) lowest_metric : (gint64) -1; - - nmp_cache_iter_for_each (&iter, head_entry, &plobj) { - const NMPlatformIP6Route *route = NMP_OBJECT_CAST_IP6_ROUTE (plobj); if (route->rt_source == NM_IP_CONFIG_SOURCE_RTPROT_KERNEL) continue; if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route)) continue; - _add_route (self, plobj, NULL); } + /* we detect the route metric based on the default route. All non-default + * routes have their route metrics explicitly set. */ + priv->route_metric = has_gateway ? (gint64) lowest_metric : (gint64) -1; + /* If the interface has the default route, and has IPv6 addresses, capture * nameservers from /etc/resolv.conf. */ -- cgit v1.2.3 From 7ab40b9e108f969dcc06b427a6d88e22f74f5e94 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 1 Sep 2017 13:53:36 +0200 Subject: core: ignore routes from non-main table in nm_ip4_config_capture() and nm_ip6_config_capture(). --- src/nm-ip4-config.c | 5 ++++- src/nm-ip6-config.c | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c index 0603a4348..1e0083ed0 100644 --- a/src/nm-ip4-config.c +++ b/src/nm-ip4-config.c @@ -671,7 +671,8 @@ nm_ip4_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i nmp_cache_iter_for_each (&iter, head_entry, &plobj) { const NMPlatformIP4Route *route = NMP_OBJECT_CAST_IP4_ROUTE (plobj); - if ( NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route) + if ( !route->table_coerced + && NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route) && route->rt_source != NM_IP_CONFIG_SOURCE_RTPROT_KERNEL) { if (route->metric < lowest_metric) { priv->gateway = route->gateway; @@ -680,6 +681,8 @@ nm_ip4_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i priv->has_gateway = TRUE; } + if (route->table_coerced) + continue; if (route->rt_source == NM_IP_CONFIG_SOURCE_RTPROT_KERNEL) continue; if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route)) diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c index 5bc17cd18..cbba554c8 100644 --- a/src/nm-ip6-config.c +++ b/src/nm-ip6-config.c @@ -463,7 +463,8 @@ nm_ip6_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i nmp_cache_iter_for_each (&iter, head_entry, &plobj) { const NMPlatformIP6Route *route = NMP_OBJECT_CAST_IP6_ROUTE (plobj); - if ( NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route) + if ( !route->table_coerced + && NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route) && route->rt_source != NM_IP_CONFIG_SOURCE_RTPROT_KERNEL) { if (route->metric < lowest_metric) { priv->gateway = route->gateway; @@ -472,6 +473,8 @@ nm_ip6_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i has_gateway = TRUE; } + if (route->table_coerced) + continue; if (route->rt_source == NM_IP_CONFIG_SOURCE_RTPROT_KERNEL) continue; if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route)) -- cgit v1.2.3 From e805201f4b75434641b400c59a1a0f30a9422ca9 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 4 Sep 2017 07:10:42 +0200 Subject: platform: delete routes after adding in nm_platform_ip_route_sync() Previously, we would first delete routes that are not to be added, before adding the new ones. This has the advantage, that even if delete removes the wrong route, add would restore the expected state. This tries to workaround the fact that RTM_DELROUTE allows for wild-card fields, and might delete the wrong route. However, for example when bumping the route metric after connectivty check (removing the default-route with metric 20100 and adding the one with metric 100), there is a short moment when there is no default-route. To avoid that, don't do delete-then-add, but add-then-delete. --- src/platform/nm-platform.c | 106 ++++++++++++++++++++------------------------- 1 file changed, 46 insertions(+), 60 deletions(-) diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 1b47702cc..0d40e0773 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -3592,54 +3592,7 @@ nm_platform_ip_route_sync (NMPlatform *self, ? &nm_platform_vtable_route_v4 : &nm_platform_vtable_route_v6; - plat_routes = nm_platform_lookup_addrroute_clone (self, - vt->obj_type, - ifindex, - kernel_delete_predicate, - kernel_delete_userdata); - /* first delete routes which are in platform (@plat_routes), but not to configure (@routes/@routes_idx). */ - if (plat_routes) { - - /* create a lookup index. */ - if (routes && routes->len > 0) { - routes_idx = g_hash_table_new ((GHashFunc) nmp_object_id_hash, - (GEqualFunc) nmp_object_id_equal); - for (i = 0; i < routes->len; i++) { - conf_o = routes->pdata[i]; - if (!nm_g_hash_table_insert (routes_idx, (gpointer) conf_o, (gpointer) conf_o)) { - /* we ignore duplicate @routes. */ - } - } - } - - for (i = 0; i < plat_routes->len; i++) { - plat_o = plat_routes->pdata[i]; - - if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (NMP_OBJECT_CAST_IP_ROUTE (plat_o))) { - /* don't delete default routes. */ - continue; - } - - if ( routes_idx - && (conf_o = g_hash_table_lookup (routes_idx, plat_o)) - && vt->route_cmp (NMP_OBJECT_CAST_IPX_ROUTE (conf_o), - NMP_OBJECT_CAST_IPX_ROUTE (plat_o), - NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) == 0) { - /* the route in platform is identical to the one we want to add. - * Keep it. */ - continue; - } - - if (!nm_platform_ip_route_delete (self, plat_o)) { - /* ignore error... */ - } - } - } - - if (!routes) - return success; - - for (i_type = 0; i_type < 2; i_type++) { + for (i_type = 0; routes && i_type < 2; i_type++) { for (i = 0; i < routes->len; i++) { NMPlatformError plerr; @@ -3657,23 +3610,32 @@ nm_platform_ip_route_sync (NMPlatform *self, continue; } + if (!routes_idx) { + routes_idx = g_hash_table_new ((GHashFunc) nmp_object_id_hash, + (GEqualFunc) nmp_object_id_equal); + } + if (!nm_g_hash_table_insert (routes_idx, (gpointer) conf_o, (gpointer) conf_o)) { + _LOGD ("route-sync: skip adding duplicate route %s", + nmp_object_to_string (conf_o, NMP_OBJECT_TO_STRING_PUBLIC, sbuf1, sizeof (sbuf1))); + continue; + } + plat_entry = nm_platform_lookup_entry (self, NMP_CACHE_ID_TYPE_OBJECT_TYPE, conf_o); if (plat_entry) { - /* we alreay have a route with the same ID in the platform cache. - * Skip adding it again. It should be identical already, otherwise we - * would have deleted above. */ - if (_LOGD_ENABLED ()) { - if (vt->route_cmp (NMP_OBJECT_CAST_IPX_ROUTE (conf_o), - NMP_OBJECT_CAST_IPX_ROUTE (plat_entry->obj), - NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) != 0) { - _LOGD ("route-sync: skip adding route %s due to existing (different!) route %s", - nmp_object_to_string (conf_o, NMP_OBJECT_TO_STRING_PUBLIC, sbuf1, sizeof (sbuf1)), - nmp_object_to_string (plat_entry->obj, NMP_OBJECT_TO_STRING_PUBLIC, sbuf2, sizeof (sbuf2))); - } + plat_o = plat_entry->obj; + + if (vt->route_cmp (NMP_OBJECT_CAST_IPX_ROUTE (conf_o), + NMP_OBJECT_CAST_IPX_ROUTE (plat_o), + NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) == 0) + continue; + + /* we need to replace the existing route with a (slightly) differnt + * one. Delete it first. */ + if (!nm_platform_ip_route_delete (self, plat_o)) { + /* ignore error. */ } - continue; } plerr = nm_platform_ip_route_add (self, @@ -3725,6 +3687,30 @@ nm_platform_ip_route_sync (NMPlatform *self, } } + plat_routes = nm_platform_lookup_addrroute_clone (self, + vt->obj_type, + ifindex, + kernel_delete_predicate, + kernel_delete_userdata); + + if (plat_routes) { + for (i = 0; i < plat_routes->len; i++) { + plat_o = plat_routes->pdata[i]; + + if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (NMP_OBJECT_CAST_IP_ROUTE (plat_o))) { + /* don't delete default routes. */ + continue; + } + + if ( !routes_idx + || !g_hash_table_lookup (routes_idx, plat_o)) { + if (!nm_platform_ip_route_delete (self, plat_o)) { + /* ignore error... */ + } + } + } + } + return success; } -- cgit v1.2.3 From ead1ffd9bc5571c76210cd457db131984569cc46 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 5 Sep 2017 10:31:56 +0200 Subject: core/trivial: rename test functions _nmtst_nm_ip*_config_*() to _nmtst_ip*_config_*() --- src/dhcp/tests/test-dhcp-dhclient.c | 4 ++-- src/dhcp/tests/test-dhcp-utils.c | 14 +++++++------- src/nm-ip4-config.c | 12 ++++++------ src/nm-ip4-config.h | 8 ++++---- src/nm-ip6-config.c | 8 ++++---- src/nm-ip6-config.h | 6 +++--- src/tests/test-ip4-config.c | 24 ++++++++++++------------ src/tests/test-ip6-config.c | 24 ++++++++++++------------ 8 files changed, 50 insertions(+), 50 deletions(-) diff --git a/src/dhcp/tests/test-dhcp-dhclient.c b/src/dhcp/tests/test-dhcp-dhclient.c index 2e68a6e08..7a6bcb542 100644 --- a/src/dhcp/tests/test-dhcp-dhclient.c +++ b/src/dhcp/tests/test-dhcp-dhclient.c @@ -922,7 +922,7 @@ test_read_lease_ip4_config_basic (void) /* Address */ g_assert_cmpint (nm_ip4_config_get_num_addresses (config), ==, 1); expected_addr = nmtst_inet4_from_string ("192.168.1.180"); - addr = _nmtst_nm_ip4_config_get_address (config, 0); + addr = _nmtst_ip4_config_get_address (config, 0); g_assert_cmpint (addr->address, ==, expected_addr); g_assert_cmpint (addr->peer_address, ==, expected_addr); g_assert_cmpint (addr->plen, ==, 24); @@ -945,7 +945,7 @@ test_read_lease_ip4_config_basic (void) /* Address */ g_assert_cmpint (nm_ip4_config_get_num_addresses (config), ==, 1); expected_addr = nmtst_inet4_from_string ("10.77.52.141"); - addr = _nmtst_nm_ip4_config_get_address (config, 0); + addr = _nmtst_ip4_config_get_address (config, 0); g_assert_cmpint (addr->address, ==, expected_addr); g_assert_cmpint (addr->peer_address, ==, expected_addr); g_assert_cmpint (addr->plen, ==, 8); diff --git a/src/dhcp/tests/test-dhcp-utils.c b/src/dhcp/tests/test-dhcp-utils.c index f31d7d645..a03c684fa 100644 --- a/src/dhcp/tests/test-dhcp-utils.c +++ b/src/dhcp/tests/test-dhcp-utils.c @@ -105,7 +105,7 @@ test_generic_options (void) /* IP4 address */ g_assert_cmpint (nm_ip4_config_get_num_addresses (ip4_config), ==, 1); - address = _nmtst_nm_ip4_config_get_address (ip4_config, 0); + address = _nmtst_ip4_config_get_address (ip4_config, 0); g_assert (inet_pton (AF_INET, expected_addr, &tmp) > 0); g_assert (address->address == tmp); g_assert (address->peer_address == tmp); @@ -135,7 +135,7 @@ test_generic_options (void) g_assert_cmpint (nm_ip4_config_get_num_routes (ip4_config), ==, 2); /* Route #1 */ - route = _nmtst_nm_ip4_config_get_route (ip4_config, 0); + route = _nmtst_ip4_config_get_route (ip4_config, 0); g_assert (inet_pton (AF_INET, expected_route1_dest, &tmp) > 0); g_assert (route->network == tmp); g_assert (inet_pton (AF_INET, expected_route1_gw, &tmp) > 0); @@ -144,7 +144,7 @@ test_generic_options (void) g_assert_cmpint (route->metric, ==, 0); /* Route #2 */ - route = _nmtst_nm_ip4_config_get_route (ip4_config, 1); + route = _nmtst_ip4_config_get_route (ip4_config, 1); g_assert (inet_pton (AF_INET, expected_route2_dest, &tmp) > 0); g_assert (route->network == tmp); g_assert (inet_pton (AF_INET, expected_route2_gw, &tmp) > 0); @@ -175,7 +175,7 @@ test_wins_options (void) /* IP4 address */ g_assert_cmpint (nm_ip4_config_get_num_addresses (ip4_config), ==, 1); - address = _nmtst_nm_ip4_config_get_address (ip4_config, 0); + address = _nmtst_ip4_config_get_address (ip4_config, 0); g_assert (address); g_assert_cmpint (nm_ip4_config_get_num_wins (ip4_config), ==, 2); g_assert (inet_pton (AF_INET, expected_wins1, &tmp) > 0); @@ -221,7 +221,7 @@ ip4_test_route (NMIP4Config *ip4_config, g_assert (expected_prefix <= 32); - route = _nmtst_nm_ip4_config_get_route (ip4_config, route_num); + route = _nmtst_ip4_config_get_route (ip4_config, route_num); g_assert (inet_pton (AF_INET, expected_dest, &tmp) > 0); g_assert (route->network == tmp); g_assert (inet_pton (AF_INET, expected_gw, &tmp) > 0); @@ -624,7 +624,7 @@ test_ip4_missing_prefix (const char *ip, guint32 expected_prefix) ip4_config = _ip4_config_from_options (1, "eth0", options, 0); g_assert_cmpint (nm_ip4_config_get_num_addresses (ip4_config), ==, 1); - address = _nmtst_nm_ip4_config_get_address (ip4_config, 0); + address = _nmtst_ip4_config_get_address (ip4_config, 0); g_assert (address); g_assert_cmpint (address->plen, ==, expected_prefix); @@ -668,7 +668,7 @@ test_ip4_prefix_classless (void) ip4_config = _ip4_config_from_options (1, "eth0", options, 0); g_assert_cmpint (nm_ip4_config_get_num_addresses (ip4_config), ==, 1); - address = _nmtst_nm_ip4_config_get_address (ip4_config, 0); + address = _nmtst_ip4_config_get_address (ip4_config, 0); g_assert (address); g_assert_cmpint (address->plen, ==, 22); diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c index 1e0083ed0..bffa50167 100644 --- a/src/nm-ip4-config.c +++ b/src/nm-ip4-config.c @@ -2020,12 +2020,12 @@ nm_ip4_config_add_address (NMIP4Config *self, const NMPlatformIP4Address *new) } void -_nmtst_nm_ip4_config_del_address (NMIP4Config *self, guint i) +_nmtst_ip4_config_del_address (NMIP4Config *self, guint i) { NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self); const NMPlatformIP4Address *a; - a = _nmtst_nm_ip4_config_get_address (self, i); + a = _nmtst_ip4_config_get_address (self, i); g_return_if_fail (a); if (nm_dedup_multi_index_remove_obj (priv->multi_idx, @@ -2057,7 +2057,7 @@ nm_ip4_config_get_first_address (const NMIP4Config *self) } const NMPlatformIP4Address * -_nmtst_nm_ip4_config_get_address (const NMIP4Config *self, guint i) +_nmtst_ip4_config_get_address (const NMIP4Config *self, guint i) { NMDedupMultiIter iter; const NMPlatformIP4Address *a = NULL; @@ -2161,12 +2161,12 @@ nm_ip4_config_add_route (NMIP4Config *self, const NMPlatformIP4Route *new) } void -_nmtst_nm_ip4_config_del_route (NMIP4Config *self, guint i) +_nmtst_ip4_config_del_route (NMIP4Config *self, guint i) { NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self); const NMPlatformIP4Route *r; - r = _nmtst_nm_ip4_config_get_route (self, i); + r = _nmtst_ip4_config_get_route (self, i); g_return_if_fail (r); if (nm_dedup_multi_index_remove_obj (priv->multi_idx, @@ -2188,7 +2188,7 @@ nm_ip4_config_get_num_routes (const NMIP4Config *self) } const NMPlatformIP4Route * -_nmtst_nm_ip4_config_get_route (const NMIP4Config *self, guint i) +_nmtst_ip4_config_get_route (const NMIP4Config *self, guint i) { NMDedupMultiIter iter; const NMPlatformIP4Route *r = NULL; diff --git a/src/nm-ip4-config.h b/src/nm-ip4-config.h index cd1392ce6..f786ef5e7 100644 --- a/src/nm-ip4-config.h +++ b/src/nm-ip4-config.h @@ -165,18 +165,18 @@ gint64 nm_ip4_config_get_route_metric (const NMIP4Config *self); const NMDedupMultiHeadEntry *nm_ip4_config_lookup_addresses (const NMIP4Config *self); void nm_ip4_config_reset_addresses (NMIP4Config *self); void nm_ip4_config_add_address (NMIP4Config *self, const NMPlatformIP4Address *address); -void _nmtst_nm_ip4_config_del_address (NMIP4Config *self, guint i); +void _nmtst_ip4_config_del_address (NMIP4Config *self, guint i); guint nm_ip4_config_get_num_addresses (const NMIP4Config *self); const NMPlatformIP4Address *nm_ip4_config_get_first_address (const NMIP4Config *self); -const NMPlatformIP4Address *_nmtst_nm_ip4_config_get_address (const NMIP4Config *self, guint i); +const NMPlatformIP4Address *_nmtst_ip4_config_get_address (const NMIP4Config *self, guint i); gboolean nm_ip4_config_address_exists (const NMIP4Config *self, const NMPlatformIP4Address *address); const NMDedupMultiHeadEntry *nm_ip4_config_lookup_routes (const NMIP4Config *self); void nm_ip4_config_reset_routes (NMIP4Config *self); void nm_ip4_config_add_route (NMIP4Config *self, const NMPlatformIP4Route *route); -void _nmtst_nm_ip4_config_del_route (NMIP4Config *self, guint i); +void _nmtst_ip4_config_del_route (NMIP4Config *self, guint i); guint nm_ip4_config_get_num_routes (const NMIP4Config *self); -const NMPlatformIP4Route *_nmtst_nm_ip4_config_get_route (const NMIP4Config *self, guint i); +const NMPlatformIP4Route *_nmtst_ip4_config_get_route (const NMIP4Config *self, guint i); const NMPlatformIP4Route *nm_ip4_config_get_direct_route_for_host (const NMIP4Config *self, guint32 host); diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c index cbba554c8..3179c72a4 100644 --- a/src/nm-ip6-config.c +++ b/src/nm-ip6-config.c @@ -364,7 +364,7 @@ sort_captured_addresses (const CList *lst_a, const CList *lst_b, gconstpointer u } gboolean -_nmtst_nm_ip6_config_addresses_sort (NMIP6Config *self) +_nmtst_ip6_config_addresses_sort (NMIP6Config *self) { NMIP6ConfigPrivate *priv; const NMDedupMultiHeadEntry *head_entry; @@ -1624,12 +1624,12 @@ nm_ip6_config_add_address (NMIP6Config *self, const NMPlatformIP6Address *new) } void -_nmtst_nm_ip6_config_del_address (NMIP6Config *self, guint i) +_nmtst_ip6_config_del_address (NMIP6Config *self, guint i) { NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self); const NMPlatformIP6Address *a; - a = _nmtst_nm_ip6_config_get_address (self, i); + a = _nmtst_ip6_config_get_address (self, i); g_return_if_fail (a); if (nm_dedup_multi_index_remove_obj (priv->multi_idx, @@ -1661,7 +1661,7 @@ nm_ip6_config_get_first_address (const NMIP6Config *self) } const NMPlatformIP6Address * -_nmtst_nm_ip6_config_get_address (const NMIP6Config *self, guint i) +_nmtst_ip6_config_get_address (const NMIP6Config *self, guint i) { NMDedupMultiIter iter; const NMPlatformIP6Address *a = NULL; diff --git a/src/nm-ip6-config.h b/src/nm-ip6-config.h index e3da0eca9..779f1099f 100644 --- a/src/nm-ip6-config.h +++ b/src/nm-ip6-config.h @@ -130,15 +130,15 @@ gint64 nm_ip6_config_get_route_metric (const NMIP6Config *self); const NMDedupMultiHeadEntry *nm_ip6_config_lookup_addresses (const NMIP6Config *self); void nm_ip6_config_reset_addresses (NMIP6Config *self); void nm_ip6_config_add_address (NMIP6Config *self, const NMPlatformIP6Address *address); -void _nmtst_nm_ip6_config_del_address (NMIP6Config *self, guint i); +void _nmtst_ip6_config_del_address (NMIP6Config *self, guint i); guint nm_ip6_config_get_num_addresses (const NMIP6Config *self); const NMPlatformIP6Address *nm_ip6_config_get_first_address (const NMIP6Config *self); -const NMPlatformIP6Address *_nmtst_nm_ip6_config_get_address (const NMIP6Config *self, guint i); +const NMPlatformIP6Address *_nmtst_ip6_config_get_address (const NMIP6Config *self, guint i); const NMPlatformIP6Address *nm_ip6_config_get_address_first_nontentative (const NMIP6Config *self, gboolean linklocal); gboolean nm_ip6_config_address_exists (const NMIP6Config *self, const NMPlatformIP6Address *address); const NMPlatformIP6Address *nm_ip6_config_lookup_address (const NMIP6Config *self, const struct in6_addr *addr); -gboolean _nmtst_nm_ip6_config_addresses_sort (NMIP6Config *self); +gboolean _nmtst_ip6_config_addresses_sort (NMIP6Config *self); gboolean nm_ip6_config_has_any_dad_pending (const NMIP6Config *self, const NMIP6Config *candidates); diff --git a/src/tests/test-ip4-config.c b/src/tests/test-ip4-config.c index d47ff2e64..f5620d95c 100644 --- a/src/tests/test-ip4-config.c +++ b/src/tests/test-ip4-config.c @@ -112,7 +112,7 @@ test_subtract (void) /* ensure what's left is what we expect */ g_assert_cmpuint (nm_ip4_config_get_num_addresses (dst), ==, 1); - test_addr = _nmtst_nm_ip4_config_get_address (dst, 0); + test_addr = _nmtst_ip4_config_get_address (dst, 0); g_assert (test_addr != NULL); g_assert_cmpuint (test_addr->address, ==, nmtst_inet4_from_string (expected_addr)); g_assert_cmpuint (test_addr->peer_address, ==, test_addr->address); @@ -121,7 +121,7 @@ test_subtract (void) g_assert_cmpuint (nm_ip4_config_get_gateway (dst), ==, 0); g_assert_cmpuint (nm_ip4_config_get_num_routes (dst), ==, 1); - test_route = _nmtst_nm_ip4_config_get_route (dst, 0); + test_route = _nmtst_ip4_config_get_route (dst, 0); g_assert (test_route != NULL); g_assert_cmpuint (test_route->network, ==, nmtst_inet4_from_string (expected_route_dest)); g_assert_cmpuint (test_route->plen, ==, expected_route_plen); @@ -196,27 +196,27 @@ test_add_address_with_source (void) addr.addr_source = NM_IP_CONFIG_SOURCE_USER; nm_ip4_config_add_address (a, &addr); - test_addr = _nmtst_nm_ip4_config_get_address (a, 0); + test_addr = _nmtst_ip4_config_get_address (a, 0); g_assert_cmpint (test_addr->addr_source, ==, NM_IP_CONFIG_SOURCE_USER); addr.addr_source = NM_IP_CONFIG_SOURCE_VPN; nm_ip4_config_add_address (a, &addr); - test_addr = _nmtst_nm_ip4_config_get_address (a, 0); + test_addr = _nmtst_ip4_config_get_address (a, 0); g_assert_cmpint (test_addr->addr_source, ==, NM_IP_CONFIG_SOURCE_USER); /* Test that a lower priority address source is overwritten */ - _nmtst_nm_ip4_config_del_address (a, 0); + _nmtst_ip4_config_del_address (a, 0); addr.addr_source = NM_IP_CONFIG_SOURCE_KERNEL; nm_ip4_config_add_address (a, &addr); - test_addr = _nmtst_nm_ip4_config_get_address (a, 0); + test_addr = _nmtst_ip4_config_get_address (a, 0); g_assert_cmpint (test_addr->addr_source, ==, NM_IP_CONFIG_SOURCE_KERNEL); addr.addr_source = NM_IP_CONFIG_SOURCE_USER; nm_ip4_config_add_address (a, &addr); - test_addr = _nmtst_nm_ip4_config_get_address (a, 0); + test_addr = _nmtst_ip4_config_get_address (a, 0); g_assert_cmpint (test_addr->addr_source, ==, NM_IP_CONFIG_SOURCE_USER); g_object_unref (a); @@ -236,27 +236,27 @@ test_add_route_with_source (void) route.rt_source = NM_IP_CONFIG_SOURCE_USER; nm_ip4_config_add_route (a, &route); - test_route = _nmtst_nm_ip4_config_get_route (a, 0); + test_route = _nmtst_ip4_config_get_route (a, 0); g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_USER); route.rt_source = NM_IP_CONFIG_SOURCE_VPN; nm_ip4_config_add_route (a, &route); - test_route = _nmtst_nm_ip4_config_get_route (a, 0); + test_route = _nmtst_ip4_config_get_route (a, 0); g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_USER); /* Test that a lower priority address source is overwritten */ - _nmtst_nm_ip4_config_del_route (a, 0); + _nmtst_ip4_config_del_route (a, 0); route.rt_source = NM_IP_CONFIG_SOURCE_KERNEL; nm_ip4_config_add_route (a, &route); - test_route = _nmtst_nm_ip4_config_get_route (a, 0); + test_route = _nmtst_ip4_config_get_route (a, 0); g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_KERNEL); route.rt_source = NM_IP_CONFIG_SOURCE_USER; nm_ip4_config_add_route (a, &route); - test_route = _nmtst_nm_ip4_config_get_route (a, 0); + test_route = _nmtst_ip4_config_get_route (a, 0); g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_USER); g_object_unref (a); diff --git a/src/tests/test-ip6-config.c b/src/tests/test-ip6-config.c index 9eb4d35fd..32eaeb6f8 100644 --- a/src/tests/test-ip6-config.c +++ b/src/tests/test-ip6-config.c @@ -88,7 +88,7 @@ test_subtract (void) /* ensure what's left is what we expect */ g_assert_cmpuint (nm_ip6_config_get_num_addresses (dst), ==, 1); - test_addr = _nmtst_nm_ip6_config_get_address (dst, 0); + test_addr = _nmtst_ip6_config_get_address (dst, 0); g_assert (test_addr != NULL); tmp = *nmtst_inet6_from_string (expected_addr); g_assert (memcmp (&test_addr->address, &tmp, sizeof (tmp)) == 0); @@ -167,27 +167,27 @@ test_add_address_with_source (void) addr.addr_source = NM_IP_CONFIG_SOURCE_USER; nm_ip6_config_add_address (a, &addr); - test_addr = _nmtst_nm_ip6_config_get_address (a, 0); + test_addr = _nmtst_ip6_config_get_address (a, 0); g_assert_cmpint (test_addr->addr_source, ==, NM_IP_CONFIG_SOURCE_USER); addr.addr_source = NM_IP_CONFIG_SOURCE_VPN; nm_ip6_config_add_address (a, &addr); - test_addr = _nmtst_nm_ip6_config_get_address (a, 0); + test_addr = _nmtst_ip6_config_get_address (a, 0); g_assert_cmpint (test_addr->addr_source, ==, NM_IP_CONFIG_SOURCE_USER); /* Test that a lower priority address source is overwritten */ - _nmtst_nm_ip6_config_del_address (a, 0); + _nmtst_ip6_config_del_address (a, 0); addr.addr_source = NM_IP_CONFIG_SOURCE_KERNEL; nm_ip6_config_add_address (a, &addr); - test_addr = _nmtst_nm_ip6_config_get_address (a, 0); + test_addr = _nmtst_ip6_config_get_address (a, 0); g_assert_cmpint (test_addr->addr_source, ==, NM_IP_CONFIG_SOURCE_KERNEL); addr.addr_source = NM_IP_CONFIG_SOURCE_USER; nm_ip6_config_add_address (a, &addr); - test_addr = _nmtst_nm_ip6_config_get_address (a, 0); + test_addr = _nmtst_ip6_config_get_address (a, 0); g_assert_cmpint (test_addr->addr_source, ==, NM_IP_CONFIG_SOURCE_USER); g_object_unref (a); @@ -256,18 +256,18 @@ test_nm_ip6_config_addresses_sort_check (NMIP6Config *config, NMSettingIP6Config int j = g_rand_int_range (nmtst_get_rand (), i, addr_count); NMTST_SWAP (idx[i], idx[j]); - nm_ip6_config_add_address (copy, _nmtst_nm_ip6_config_get_address (config, idx[i])); + nm_ip6_config_add_address (copy, _nmtst_ip6_config_get_address (config, idx[i])); } /* reorder them again */ - _nmtst_nm_ip6_config_addresses_sort (copy); + _nmtst_ip6_config_addresses_sort (copy); /* check equality using nm_ip6_config_equal() */ if (!nm_ip6_config_equal (copy, config)) { g_message ("%s", "SORTING yields unexpected output:"); for (i = 0; i < addr_count; i++) { - g_message (" >> [%d] = %s", i, nm_platform_ip6_address_to_string (_nmtst_nm_ip6_config_get_address (config, i), NULL, 0)); - g_message (" << [%d] = %s", i, nm_platform_ip6_address_to_string (_nmtst_nm_ip6_config_get_address (copy, i), NULL, 0)); + g_message (" >> [%d] = %s", i, nm_platform_ip6_address_to_string (_nmtst_ip6_config_get_address (config, i), NULL, 0)); + g_message (" << [%d] = %s", i, nm_platform_ip6_address_to_string (_nmtst_ip6_config_get_address (copy, i), NULL, 0)); } g_assert_not_reached (); } @@ -398,8 +398,8 @@ test_replace (gconstpointer user_data) nm_ip6_config_replace (dst_conf, src_conf, NULL); for (i = 0; i < addrs_n; i++) { - const NMPlatformIP6Address *a = _nmtst_nm_ip6_config_get_address (dst_conf, i); - const NMPlatformIP6Address *b = _nmtst_nm_ip6_config_get_address (src_conf, i); + const NMPlatformIP6Address *a = _nmtst_ip6_config_get_address (dst_conf, i); + const NMPlatformIP6Address *b = _nmtst_ip6_config_get_address (src_conf, i); g_assert (nm_platform_ip6_address_cmp (&addrs[i], a) == 0); g_assert (nm_platform_ip6_address_cmp (&addrs[i], b) == 0); -- cgit v1.2.3 From 96f1358eeff52cd441dfd910d341082cc957cecd Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 5 Sep 2017 10:36:50 +0200 Subject: core: return new route from _nm_ip_config_add_obj() Later we will need the exact instance that we just added (or the previously existing one, if the new route is already tracked). --- src/devices/nm-device.c | 6 +++--- src/devices/wwan/nm-modem-ofono.c | 2 +- src/dhcp/nm-dhcp-systemd.c | 2 +- src/dhcp/nm-dhcp-utils.c | 6 +++--- src/nm-ip4-config.c | 38 ++++++++++++++++++++++++++++---------- src/nm-ip4-config.h | 5 ++++- src/nm-ip6-config.c | 34 ++++++++++++++++++++++++++-------- src/nm-ip6-config.h | 4 +++- src/tests/test-ip4-config.c | 18 +++++++++--------- src/tests/test-ip6-config.c | 18 +++++++++--------- src/vpn/nm-vpn-connection.c | 16 ++++++++-------- 11 files changed, 95 insertions(+), 54 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 9f015951a..364f142a7 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -5365,7 +5365,7 @@ ipv4ll_get_ip4_config (NMDevice *self, guint32 lla) route.plen = 4; route.rt_source = NM_IP_CONFIG_SOURCE_IP4LL; route.metric = nm_device_get_ip4_route_metric (self); - nm_ip4_config_add_route (config, &route); + nm_ip4_config_add_route (config, &route, NULL); return config; } @@ -5798,7 +5798,7 @@ ip4_config_merge_and_apply (NMDevice *self, r.network = gateway; r.plen = 32; r.gateway = 0; - nm_ip4_config_add_route (composite, &r); + nm_ip4_config_add_route (composite, &r, NULL); } END_ADD_DEFAULT_ROUTE: @@ -6534,7 +6534,7 @@ ip6_config_merge_and_apply (NMDevice *self, r.network = *gateway; r.plen = 128; r.gateway = in6addr_any; - nm_ip6_config_add_route (composite, &r); + nm_ip6_config_add_route (composite, &r, NULL); } END_ADD_DEFAULT_ROUTE: diff --git a/src/devices/wwan/nm-modem-ofono.c b/src/devices/wwan/nm-modem-ofono.c index e0b45e07c..41b77e91d 100644 --- a/src/devices/wwan/nm-modem-ofono.c +++ b/src/devices/wwan/nm-modem-ofono.c @@ -997,7 +997,7 @@ context_property_changed (GDBusProxy *proxy, mms_route.metric = 1; - nm_ip4_config_add_route (priv->ip4_config, &mms_route); + nm_ip4_config_add_route (priv->ip4_config, &mms_route, NULL); } else { _LOGW ("invalid MessageProxy: %s", s); } diff --git a/src/dhcp/nm-dhcp-systemd.c b/src/dhcp/nm-dhcp-systemd.c index e720400e5..61e2f69b3 100644 --- a/src/dhcp/nm-dhcp-systemd.c +++ b/src/dhcp/nm-dhcp-systemd.c @@ -359,7 +359,7 @@ lease_to_ip4_config (NMDedupMultiIndex *multi_idx, if (route.plen) { route.rt_source = NM_IP_CONFIG_SOURCE_DHCP; route.metric = default_priority; - nm_ip4_config_add_route (ip4_config, &route); + nm_ip4_config_add_route (ip4_config, &route, NULL); s = nm_utils_inet4_ntop (route.network, buf); gw_str = nm_utils_inet4_ntop (route.gateway, NULL); diff --git a/src/dhcp/nm-dhcp-utils.c b/src/dhcp/nm-dhcp-utils.c index f544a644b..8eb980c4b 100644 --- a/src/dhcp/nm-dhcp-utils.c +++ b/src/dhcp/nm-dhcp-utils.c @@ -91,7 +91,7 @@ ip4_process_dhcpcd_rfc3442_routes (const char *iface, route.gateway = rt_route; route.rt_source = NM_IP_CONFIG_SOURCE_DHCP; route.metric = priority; - nm_ip4_config_add_route (ip4_config, &route); + nm_ip4_config_add_route (ip4_config, &route, NULL); } } @@ -199,7 +199,7 @@ ip4_process_dhclient_rfc3442_routes (const char *iface, /* normal route */ route.rt_source = NM_IP_CONFIG_SOURCE_DHCP; route.metric = priority; - nm_ip4_config_add_route (ip4_config, &route); + nm_ip4_config_add_route (ip4_config, &route, NULL); _LOG2I (LOGD_DHCP4, iface, " classless static route %s/%d gw %s", nm_utils_inet4_ntop (route.network, addr), route.plen, @@ -328,7 +328,7 @@ process_classful_routes (const char *iface, route.network = nm_utils_ip4_address_clear_host_address (route.network, route.plen); - nm_ip4_config_add_route (ip4_config, &route); + nm_ip4_config_add_route (ip4_config, &route, NULL); _LOG2I (LOGD_DHCP, iface, " static route %s", nm_platform_ip4_route_to_string (&route, NULL, 0)); } diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c index bffa50167..9037c2d6f 100644 --- a/src/nm-ip4-config.c +++ b/src/nm-ip4-config.c @@ -166,7 +166,8 @@ _nm_ip_config_add_obj (NMDedupMultiIndex *multi_idx, const NMPlatformObject *pl_new, gboolean merge, gboolean append_force, - const NMPObject **out_obj_new) + const NMPObject **out_obj_old /* returns a reference! */, + const NMPObject **out_obj_new /* does not return a reference */) { NMPObject obj_new_stackinit; const NMDedupMultiEntry *entry_old; @@ -274,7 +275,7 @@ _nm_ip_config_add_obj (NMDedupMultiIndex *multi_idx, entry_old ?: NM_DEDUP_MULTI_ENTRY_MISSING, NULL, &entry_new, - NULL)) { + out_obj_old)) { nm_assert_not_reached (); NM_SET_OUT (out_obj_new, NULL); return FALSE; @@ -284,6 +285,7 @@ _nm_ip_config_add_obj (NMDedupMultiIndex *multi_idx, return TRUE; append_force_and_out: + NM_SET_OUT (out_obj_old, nmp_object_ref (entry_old->obj)); NM_SET_OUT (out_obj_new, entry_old->obj); if (append_force) { if (nm_dedup_multi_entry_reorder (entry_old, NULL, TRUE)) @@ -401,7 +403,7 @@ G_DEFINE_TYPE (NMIP4Config, nm_ip4_config, NM_TYPE_EXPORTED_OBJECT) /*****************************************************************************/ static void _add_address (NMIP4Config *self, const NMPObject *obj_new, const NMPlatformIP4Address *new); -static void _add_route (NMIP4Config *self, const NMPObject *obj_new, const NMPlatformIP4Route *new); +static void _add_route (NMIP4Config *self, const NMPObject *obj_new, const NMPlatformIP4Route *new, const NMPObject **out_obj_new); static const NMDedupMultiEntry *_lookup_route (const NMIP4Config *self, const NMPObject *needle, NMPlatformIPRouteCmpType cmp_type); @@ -647,6 +649,7 @@ nm_ip4_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i NULL, FALSE, TRUE, + NULL, NULL)) nm_assert_not_reached (); } @@ -687,7 +690,7 @@ nm_ip4_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i continue; if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route)) continue; - _add_route (self, plobj, NULL); + _add_route (self, plobj, NULL, NULL); } /* we detect the route metric based on the default route. All non-default @@ -951,7 +954,7 @@ nm_ip4_config_merge_setting (NMIP4Config *self, NMSettingIPConfig *setting, guin route.network = nm_utils_ip4_address_clear_host_address (route.network, route.plen); merge_route_attributes (s_route, &route); - _add_route (self, NULL, &route); + _add_route (self, NULL, &route, NULL); } /* DNS */ @@ -1133,7 +1136,7 @@ nm_ip4_config_merge (NMIP4Config *dst, const NMIP4Config *src, NMIPConfigMergeFl const NMPlatformIP4Route *route; nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, src, &route) - _add_route (dst, NMP_OBJECT_UP_CAST (route), NULL); + _add_route (dst, NMP_OBJECT_UP_CAST (route), NULL, NULL); } if (dst_priv->route_metric == -1) @@ -1586,6 +1589,7 @@ nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relev NULL, FALSE, TRUE, + NULL, NULL); } nm_dedup_multi_index_dirty_remove_idx (dst_priv->multi_idx, &dst_priv->idx_ip4_addresses, FALSE); @@ -1632,6 +1636,7 @@ nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relev NULL, FALSE, TRUE, + NULL, NULL); } nm_dedup_multi_index_dirty_remove_idx (dst_priv->multi_idx, &dst_priv->idx_ip4_routes, FALSE); @@ -1994,6 +1999,7 @@ _add_address (NMIP4Config *self, const NMPObject *obj_new, const NMPlatformIP4Ad (const NMPlatformObject *) new, TRUE, FALSE, + NULL, NULL)) _notify_addresses (self); } @@ -2120,9 +2126,13 @@ nm_ip4_config_reset_routes (NMIP4Config *self) } static void -_add_route (NMIP4Config *self, const NMPObject *obj_new, const NMPlatformIP4Route *new) +_add_route (NMIP4Config *self, + const NMPObject *obj_new, + const NMPlatformIP4Route *new, + const NMPObject **out_obj_new) { NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self); + const NMPObject *obj_new_2; nm_assert ((!new) != (!obj_new)); nm_assert (!new || _route_valid (new)); @@ -2135,14 +2145,20 @@ _add_route (NMIP4Config *self, const NMPObject *obj_new, const NMPlatformIP4Rout (const NMPlatformObject *) new, TRUE, FALSE, - NULL)) + NULL, + &obj_new_2)) { + NM_SET_OUT (out_obj_new, nmp_object_ref (obj_new_2)); _notify_routes (self); + } else + NM_SET_OUT (out_obj_new, nmp_object_ref (obj_new_2)); } /** * nm_ip4_config_add_route: * @self: the #NMIP4Config * @new: the new route to add to @self + * @out_obj_new: (allow-none): (out): the added route object. Must be unrefed + * by caller. * * Adds the new route to @self. If a route with the same basic properties * (network, prefix) already exists in @self, it is overwritten including the @@ -2150,14 +2166,16 @@ _add_route (NMIP4Config *self, const NMPObject *obj_new, const NMPlatformIP4Rout * from @new if that source is higher priority. */ void -nm_ip4_config_add_route (NMIP4Config *self, const NMPlatformIP4Route *new) +nm_ip4_config_add_route (NMIP4Config *self, + const NMPlatformIP4Route *new, + const NMPObject **out_obj_new) { g_return_if_fail (self); g_return_if_fail (new); g_return_if_fail (new->plen > 0 && new->plen <= 32); g_return_if_fail (NM_IP4_CONFIG_GET_PRIVATE (self)->ifindex > 0); - _add_route (self, NULL, new); + _add_route (self, NULL, new, out_obj_new); } void diff --git a/src/nm-ip4-config.h b/src/nm-ip4-config.h index f786ef5e7..1113c9928 100644 --- a/src/nm-ip4-config.h +++ b/src/nm-ip4-config.h @@ -91,6 +91,7 @@ gboolean _nm_ip_config_add_obj (NMDedupMultiIndex *multi_idx, const NMPlatformObject *pl_new, gboolean merge, gboolean append_force, + const NMPObject **out_obj_old, const NMPObject **out_obj_new); const NMDedupMultiEntry *_nm_ip_config_lookup_ip_route (const NMDedupMultiIndex *multi_idx, @@ -173,7 +174,9 @@ gboolean nm_ip4_config_address_exists (const NMIP4Config *self, const NMPlatform const NMDedupMultiHeadEntry *nm_ip4_config_lookup_routes (const NMIP4Config *self); void nm_ip4_config_reset_routes (NMIP4Config *self); -void nm_ip4_config_add_route (NMIP4Config *self, const NMPlatformIP4Route *route); +void nm_ip4_config_add_route (NMIP4Config *self, + const NMPlatformIP4Route *route, + const NMPObject **out_obj_new); void _nmtst_ip4_config_del_route (NMIP4Config *self, guint i); guint nm_ip4_config_get_num_routes (const NMIP4Config *self); const NMPlatformIP4Route *_nmtst_ip4_config_get_route (const NMIP4Config *self, guint i); diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c index 3179c72a4..641e73434 100644 --- a/src/nm-ip6-config.c +++ b/src/nm-ip6-config.c @@ -113,7 +113,7 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMIP6Config, /*****************************************************************************/ static void _add_address (NMIP6Config *self, const NMPObject *obj_new, const NMPlatformIP6Address *new); -static void _add_route (NMIP6Config *self, const NMPObject *obj_new, const NMPlatformIP6Route *new); +static void _add_route (NMIP6Config *self, const NMPObject *obj_new, const NMPlatformIP6Route *new, const NMPObject **out_obj_new); /*****************************************************************************/ @@ -440,6 +440,7 @@ nm_ip6_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i NULL, FALSE, TRUE, + NULL, NULL)) nm_assert_not_reached (); has_addresses = TRUE; @@ -479,7 +480,7 @@ nm_ip6_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i continue; if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT (route)) continue; - _add_route (self, plobj, NULL); + _add_route (self, plobj, NULL, NULL); } /* we detect the route metric based on the default route. All non-default @@ -670,7 +671,7 @@ nm_ip6_config_merge_setting (NMIP6Config *self, NMSettingIPConfig *setting, guin nm_utils_ip6_address_clear_host_address (&route.network, &route.network, route.plen); merge_route_attributes (s_route, &route); - _add_route (self, NULL, &route); + _add_route (self, NULL, &route, NULL); } /* DNS */ @@ -859,7 +860,7 @@ nm_ip6_config_merge (NMIP6Config *dst, const NMIP6Config *src, NMIPConfigMergeFl const NMPlatformIP6Route *route; nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, src, &route) - _add_route (dst, NMP_OBJECT_UP_CAST (route), NULL); + _add_route (dst, NMP_OBJECT_UP_CAST (route), NULL, NULL); } if (dst_priv->route_metric == -1) @@ -1254,6 +1255,7 @@ nm_ip6_config_replace (NMIP6Config *dst, const NMIP6Config *src, gboolean *relev NULL, FALSE, TRUE, + NULL, NULL); } nm_dedup_multi_index_dirty_remove_idx (dst_priv->multi_idx, &dst_priv->idx_ip6_addresses, FALSE); @@ -1300,6 +1302,7 @@ nm_ip6_config_replace (NMIP6Config *dst, const NMIP6Config *src, gboolean *relev NULL, FALSE, TRUE, + NULL, NULL); } nm_dedup_multi_index_dirty_remove_idx (dst_priv->multi_idx, &dst_priv->idx_ip6_routes, FALSE); @@ -1563,6 +1566,7 @@ nm_ip6_config_reset_addresses_ndisc (NMIP6Config *self, NULL, FALSE, TRUE, + NULL, NULL)) changed = TRUE; } @@ -1598,6 +1602,7 @@ _add_address (NMIP6Config *self, (const NMPlatformObject *) new, TRUE, FALSE, + NULL, NULL)) _notify_addresses (self); } @@ -1792,6 +1797,7 @@ nm_ip6_config_reset_routes_ndisc (NMIP6Config *self, NULL, FALSE, TRUE, + NULL, NULL)) changed = TRUE; } @@ -1814,9 +1820,13 @@ nm_ip6_config_reset_routes (NMIP6Config *self) } static void -_add_route (NMIP6Config *self, const NMPObject *obj_new, const NMPlatformIP6Route *new) +_add_route (NMIP6Config *self, + const NMPObject *obj_new, + const NMPlatformIP6Route *new, + const NMPObject **out_obj_new) { NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self); + const NMPObject *obj_new_2; nm_assert ((!new) != (!obj_new)); nm_assert (!new || _route_valid (new)); @@ -1829,14 +1839,20 @@ _add_route (NMIP6Config *self, const NMPObject *obj_new, const NMPlatformIP6Rout (const NMPlatformObject *) new, TRUE, FALSE, - NULL)) + NULL, + &obj_new_2)) { + NM_SET_OUT (out_obj_new, nmp_object_ref (obj_new_2)); _notify_routes (self); + } else + NM_SET_OUT (out_obj_new, nmp_object_ref (obj_new_2)); } /** * nm_ip6_config_add_route: * @self: the #NMIP6Config * @new: the new route to add to @self + * @out_obj_new: (allow-none): (out): the added route object. Must be unrefed + * by caller. * * Adds the new route to @self. If a route with the same basic properties * (network, prefix) already exists in @self, it is overwritten including the @@ -1844,14 +1860,16 @@ _add_route (NMIP6Config *self, const NMPObject *obj_new, const NMPlatformIP6Rout * from @new if that source is higher priority. */ void -nm_ip6_config_add_route (NMIP6Config *self, const NMPlatformIP6Route *new) +nm_ip6_config_add_route (NMIP6Config *self, + const NMPlatformIP6Route *new, + const NMPObject **out_obj_new) { g_return_if_fail (self); g_return_if_fail (new); g_return_if_fail (new->plen > 0 && new->plen <= 128); g_return_if_fail (NM_IP6_CONFIG_GET_PRIVATE (self)->ifindex > 0); - _add_route (self, NULL, new); + _add_route (self, NULL, new, out_obj_new); } void diff --git a/src/nm-ip6-config.h b/src/nm-ip6-config.h index 779f1099f..0a7fe1749 100644 --- a/src/nm-ip6-config.h +++ b/src/nm-ip6-config.h @@ -144,7 +144,9 @@ gboolean nm_ip6_config_has_any_dad_pending (const NMIP6Config *self, const NMDedupMultiHeadEntry *nm_ip6_config_lookup_routes (const NMIP6Config *self); void nm_ip6_config_reset_routes (NMIP6Config *self); -void nm_ip6_config_add_route (NMIP6Config *self, const NMPlatformIP6Route *route); +void nm_ip6_config_add_route (NMIP6Config *self, + const NMPlatformIP6Route *route, + const NMPObject **out_obj_new); void _nmtst_ip6_config_del_route (NMIP6Config *self, guint i); guint nm_ip6_config_get_num_routes (const NMIP6Config *self); const NMPlatformIP6Route *_nmtst_ip6_config_get_route (const NMIP6Config *self, guint i); diff --git a/src/tests/test-ip4-config.c b/src/tests/test-ip4-config.c index f5620d95c..d8b6f2de0 100644 --- a/src/tests/test-ip4-config.c +++ b/src/tests/test-ip4-config.c @@ -42,10 +42,10 @@ build_test_config (void) nm_ip4_config_add_address (config, &addr); route = *nmtst_platform_ip4_route ("10.0.0.0", 8, "192.168.1.1"); - nm_ip4_config_add_route (config, &route); + nm_ip4_config_add_route (config, &route, NULL); route = *nmtst_platform_ip4_route ("172.16.0.0", 16, "192.168.1.1"); - nm_ip4_config_add_route (config, &route); + nm_ip4_config_add_route (config, &route, NULL); nm_ip4_config_set_gateway (config, nmtst_inet4_from_string ("192.168.1.1")); @@ -95,7 +95,7 @@ test_subtract (void) nm_ip4_config_add_address (dst, &addr); route = *nmtst_platform_ip4_route (expected_route_dest, expected_route_plen, expected_route_next_hop); - nm_ip4_config_add_route (dst, &route); + nm_ip4_config_add_route (dst, &route, NULL); nm_ip4_config_add_nameserver (dst, expected_ns1); nm_ip4_config_add_nameserver (dst, expected_ns2); @@ -170,10 +170,10 @@ test_compare_with_source (void) /* Route */ route = *nmtst_platform_ip4_route ("10.0.0.0", 8, "192.168.1.1"); route.rt_source = NM_IP_CONFIG_SOURCE_USER; - nm_ip4_config_add_route (a, &route); + nm_ip4_config_add_route (a, &route, NULL); route.rt_source = NM_IP_CONFIG_SOURCE_VPN; - nm_ip4_config_add_route (b, &route); + nm_ip4_config_add_route (b, &route, NULL); /* Assert that the configs are basically the same, eg that the source is ignored */ g_assert (nm_ip4_config_equal (a, b)); @@ -234,13 +234,13 @@ test_add_route_with_source (void) /* Test that a higher priority source is not overwritten */ route = *nmtst_platform_ip4_route ("1.2.3.0", 24, "1.2.3.1"); route.rt_source = NM_IP_CONFIG_SOURCE_USER; - nm_ip4_config_add_route (a, &route); + nm_ip4_config_add_route (a, &route, NULL); test_route = _nmtst_ip4_config_get_route (a, 0); g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_USER); route.rt_source = NM_IP_CONFIG_SOURCE_VPN; - nm_ip4_config_add_route (a, &route); + nm_ip4_config_add_route (a, &route, NULL); test_route = _nmtst_ip4_config_get_route (a, 0); g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_USER); @@ -248,13 +248,13 @@ test_add_route_with_source (void) /* Test that a lower priority address source is overwritten */ _nmtst_ip4_config_del_route (a, 0); route.rt_source = NM_IP_CONFIG_SOURCE_KERNEL; - nm_ip4_config_add_route (a, &route); + nm_ip4_config_add_route (a, &route, NULL); test_route = _nmtst_ip4_config_get_route (a, 0); g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_KERNEL); route.rt_source = NM_IP_CONFIG_SOURCE_USER; - nm_ip4_config_add_route (a, &route); + nm_ip4_config_add_route (a, &route, NULL); test_route = _nmtst_ip4_config_get_route (a, 0); g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_USER); diff --git a/src/tests/test-ip6-config.c b/src/tests/test-ip6-config.c index 32eaeb6f8..bc703dd44 100644 --- a/src/tests/test-ip6-config.c +++ b/src/tests/test-ip6-config.c @@ -37,8 +37,8 @@ build_test_config (void) config = nmtst_ip6_config_new (1); nm_ip6_config_add_address (config, nmtst_platform_ip6_address ("abcd:1234:4321::cdde", "1:2:3:4::5", 64)); - nm_ip6_config_add_route (config, nmtst_platform_ip6_route ("abcd:1200::", 24, "abcd:1234:4321:cdde::2", NULL)); - nm_ip6_config_add_route (config, nmtst_platform_ip6_route ("2001::", 16, "2001:abba::2234", NULL)); + nm_ip6_config_add_route (config, nmtst_platform_ip6_route ("abcd:1200::", 24, "abcd:1234:4321:cdde::2", NULL), NULL); + nm_ip6_config_add_route (config, nmtst_platform_ip6_route ("2001::", 16, "2001:abba::2234", NULL), NULL); nm_ip6_config_set_gateway (config, nmtst_inet6_from_string ("3001:abba::3234")); @@ -74,7 +74,7 @@ test_subtract (void) /* add a couple more things to the test config */ dst = build_test_config (); nm_ip6_config_add_address (dst, nmtst_platform_ip6_address (expected_addr, NULL, expected_addr_plen)); - nm_ip6_config_add_route (dst, nmtst_platform_ip6_route (expected_route_dest, expected_route_plen, expected_route_next_hop, NULL)); + nm_ip6_config_add_route (dst, nmtst_platform_ip6_route (expected_route_dest, expected_route_plen, expected_route_next_hop, NULL), NULL); expected_ns1 = *nmtst_inet6_from_string ("2222:3333:4444::5555"); nm_ip6_config_add_nameserver (dst, &expected_ns1); @@ -141,10 +141,10 @@ test_compare_with_source (void) /* Route */ route = *nmtst_platform_ip6_route ("abcd:1200::", 24, "abcd:1234:4321:cdde::2", NULL); route.rt_source = NM_IP_CONFIG_SOURCE_USER; - nm_ip6_config_add_route (a, &route); + nm_ip6_config_add_route (a, &route, NULL); route.rt_source = NM_IP_CONFIG_SOURCE_VPN; - nm_ip6_config_add_route (b, &route); + nm_ip6_config_add_route (b, &route, NULL); /* Assert that the configs are basically the same, eg that the source is ignored */ g_assert (nm_ip6_config_equal (a, b)); @@ -205,13 +205,13 @@ test_add_route_with_source (void) /* Test that a higher priority source is not overwritten */ route = *nmtst_platform_ip6_route ("abcd:1200::", 24, "abcd:1234:4321:cdde::2", NULL); route.rt_source = NM_IP_CONFIG_SOURCE_USER; - nm_ip6_config_add_route (a, &route); + nm_ip6_config_add_route (a, &route, NULL); test_route = _nmtst_ip6_config_get_route (a, 0); g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_USER); route.rt_source = NM_IP_CONFIG_SOURCE_VPN; - nm_ip6_config_add_route (a, &route); + nm_ip6_config_add_route (a, &route, NULL); test_route = _nmtst_ip6_config_get_route (a, 0); g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_USER); @@ -219,13 +219,13 @@ test_add_route_with_source (void) /* Test that a lower priority address source is overwritten */ _nmtst_ip6_config_del_route (a, 0); route.rt_source = NM_IP_CONFIG_SOURCE_KERNEL; - nm_ip6_config_add_route (a, &route); + nm_ip6_config_add_route (a, &route, NULL); test_route = _nmtst_ip6_config_get_route (a, 0); g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_KERNEL); route.rt_source = NM_IP_CONFIG_SOURCE_USER; - nm_ip6_config_add_route (a, &route); + nm_ip6_config_add_route (a, &route, NULL); test_route = _nmtst_ip6_config_get_route (a, 0); g_assert_cmpint (test_route->rt_source, ==, NM_IP_CONFIG_SOURCE_USER); diff --git a/src/vpn/nm-vpn-connection.c b/src/vpn/nm-vpn-connection.c index bd86007ac..a22a55e0a 100644 --- a/src/vpn/nm-vpn-connection.c +++ b/src/vpn/nm-vpn-connection.c @@ -760,7 +760,7 @@ add_ip4_vpn_gateway_route (NMIP4Config *config, route.gateway = parent_gw; route.rt_source = NM_IP_CONFIG_SOURCE_VPN; route.metric = route_metric; - nm_ip4_config_add_route (config, &route); + nm_ip4_config_add_route (config, &route, NULL); if (parent_gw) { /* Ensure there's a route to the parent device's gateway through the @@ -773,7 +773,7 @@ add_ip4_vpn_gateway_route (NMIP4Config *config, route.plen = 32; route.rt_source = NM_IP_CONFIG_SOURCE_VPN; route.metric = route_metric; - nm_ip4_config_add_route (config, &route); + nm_ip4_config_add_route (config, &route, NULL); } } @@ -834,7 +834,7 @@ add_ip6_vpn_gateway_route (NMIP6Config *config, route.gateway = *parent_gw; route.rt_source = NM_IP_CONFIG_SOURCE_VPN; route.metric = route_metric; - nm_ip6_config_add_route (config, &route); + nm_ip6_config_add_route (config, &route, NULL); /* Ensure there's a route to the parent device's gateway through the * parent device, since if the VPN claims the default route and the VPN @@ -847,7 +847,7 @@ add_ip6_vpn_gateway_route (NMIP6Config *config, route.plen = 128; route.rt_source = NM_IP_CONFIG_SOURCE_VPN; route.metric = route_metric; - nm_ip6_config_add_route (config, &route); + nm_ip6_config_add_route (config, &route, NULL); } } @@ -1548,7 +1548,7 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict) const NMPlatformIP4Route *route; nm_ip_config_iter_ip4_route_for_each (&ipconf_iter, priv->ip4_config, &route) - nm_ip4_config_add_route (config, route); + nm_ip4_config_add_route (config, route, NULL); } } else if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP4_CONFIG_ROUTES, "aau", &iter)) { while (g_variant_iter_next (iter, "@au", &v)) { @@ -1578,7 +1578,7 @@ nm_vpn_connection_ip4_config_get (NMVpnConnection *self, GVariant *dict) * whatever the server provides. */ if (!(priv->ip4_external_gw && route.network == priv->ip4_external_gw && route.plen == 32)) - nm_ip4_config_add_route (config, &route); + nm_ip4_config_add_route (config, &route, NULL); break; default: break; @@ -1713,7 +1713,7 @@ nm_vpn_connection_ip6_config_get (NMVpnConnection *self, GVariant *dict) const NMPlatformIP6Route *route; nm_ip_config_iter_ip6_route_for_each (&ipconf_iter, priv->ip6_config, &route) - nm_ip6_config_add_route (config, route); + nm_ip6_config_add_route (config, route, NULL); } } else if (g_variant_lookup (dict, NM_VPN_PLUGIN_IP6_CONFIG_ROUTES, "a(ayuayu)", &iter)) { GVariant *dest, *next_hop; @@ -1741,7 +1741,7 @@ nm_vpn_connection_ip6_config_get (NMVpnConnection *self, GVariant *dict) * the server provides. */ if (!(priv->ip6_external_gw && IN6_ARE_ADDR_EQUAL (&route.network, priv->ip6_external_gw) && route.plen == 128)) - nm_ip6_config_add_route (config, &route); + nm_ip6_config_add_route (config, &route, NULL); next: g_variant_unref (dest); -- cgit v1.2.3