diff options
author | Thomas Haller <thaller@redhat.com> | 2017-09-08 11:05:48 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2017-09-08 11:09:42 +0200 |
commit | a214f398e7b17cacad335f70462a606affc2ad63 (patch) | |
tree | c85be9e489b37b8a3a5e8cc46dfec2bebbae9786 | |
parent | 19716df23ddfd3047b64620c389fa336e4427c69 (diff) | |
parent | 96f1358eeff52cd441dfd910d341082cc957cecd (diff) |
core: merge branch 'th/platform-route-pt4' (part 1)
Several patches with cleanup and in prepration for dropping
NMDefaultRouteManager.
https://github.com/NetworkManager/NetworkManager/pull/26
-rw-r--r-- | shared/nm-utils/nm-macros-internal.h | 55 | ||||
-rw-r--r-- | src/NetworkManagerUtils.c | 49 | ||||
-rw-r--r-- | src/devices/nm-device.c | 44 | ||||
-rw-r--r-- | src/devices/nm-device.h | 16 | ||||
-rw-r--r-- | src/devices/wwan/nm-modem-ofono.c | 2 | ||||
-rw-r--r-- | src/dhcp/nm-dhcp-systemd.c | 2 | ||||
-rw-r--r-- | src/dhcp/nm-dhcp-utils.c | 6 | ||||
-rw-r--r-- | src/dhcp/tests/test-dhcp-dhclient.c | 4 | ||||
-rw-r--r-- | src/dhcp/tests/test-dhcp-utils.c | 14 | ||||
-rw-r--r-- | src/nm-core-utils.h | 10 | ||||
-rw-r--r-- | src/nm-default-route-manager.c | 61 | ||||
-rw-r--r-- | src/nm-default-route-manager.h | 3 | ||||
-rw-r--r-- | src/nm-ip4-config.c | 98 | ||||
-rw-r--r-- | src/nm-ip4-config.h | 16 | ||||
-rw-r--r-- | src/nm-ip6-config.c | 79 | ||||
-rw-r--r-- | src/nm-ip6-config.h | 10 | ||||
-rw-r--r-- | src/nm-policy.c | 138 | ||||
-rw-r--r-- | src/platform/nm-platform.c | 110 | ||||
-rw-r--r-- | src/platform/nm-platform.h | 5 | ||||
-rw-r--r-- | src/platform/nmp-object.h | 15 | ||||
-rw-r--r-- | src/tests/test-ip4-config.c | 42 | ||||
-rw-r--r-- | src/tests/test-ip6-config.c | 105 | ||||
-rw-r--r-- | src/vpn/nm-vpn-connection.c | 16 |
23 files changed, 530 insertions, 370 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 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 55ad6c323..364f142a7 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 @@ -5378,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; } @@ -5553,10 +5540,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; @@ -5769,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) { @@ -5815,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: @@ -6505,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) { @@ -6552,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/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); 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/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-core-utils.h b/src/nm-core-utils.h index 42afcb0e2..aca69fce6 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); @@ -286,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); diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c index ad939d000..9037c2d6f 100644 --- a/src/nm-ip4-config.c +++ b/src/nm-ip4-config.c @@ -165,10 +165,13 @@ _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_old /* returns a reference! */, + const NMPObject **out_obj_new /* does not return a reference */) { NMPObject obj_new_stackinit; const NMDedupMultiEntry *entry_old; + const NMDedupMultiEntry *entry_new; nm_assert (multi_idx); nm_assert (idx_type); @@ -271,15 +274,19 @@ _nm_ip_config_add_obj (NMDedupMultiIndex *multi_idx, NULL, entry_old ?: NM_DEDUP_MULTI_ENTRY_MISSING, NULL, - NULL, - NULL)) { + &entry_new, + out_obj_old)) { 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_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)) return TRUE; @@ -396,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); @@ -641,7 +648,9 @@ nm_ip4_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i plobj, NULL, FALSE, - TRUE)) + TRUE, + NULL, + NULL)) nm_assert_not_reached (); } head_entry = nm_ip4_config_lookup_addresses (self); @@ -665,7 +674,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; @@ -673,22 +683,20 @@ 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->table_coerced) + continue; 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); + _add_route (self, plobj, NULL, 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. */ @@ -946,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 */ @@ -1128,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) @@ -1580,7 +1588,9 @@ nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relev ipconf_iter_src.current->obj, NULL, FALSE, - TRUE); + TRUE, + NULL, + NULL); } nm_dedup_multi_index_dirty_remove_idx (dst_priv->multi_idx, &dst_priv->idx_ip4_addresses, FALSE); _notify_addresses (dst); @@ -1619,12 +1629,15 @@ 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, + NULL, + NULL); } nm_dedup_multi_index_dirty_remove_idx (dst_priv->multi_idx, &dst_priv->idx_ip4_routes, FALSE); _notify_routes (dst); @@ -1985,7 +1998,9 @@ _add_address (NMIP4Config *self, const NMPObject *obj_new, const NMPlatformIP4Ad obj_new, (const NMPlatformObject *) new, TRUE, - FALSE)) + FALSE, + NULL, + NULL)) _notify_addresses (self); } @@ -2011,12 +2026,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, @@ -2048,7 +2063,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; @@ -2111,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)); @@ -2125,14 +2144,21 @@ _add_route (NMIP4Config *self, const NMPObject *obj_new, const NMPlatformIP4Rout obj_new, (const NMPlatformObject *) new, TRUE, - FALSE)) + FALSE, + 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 @@ -2140,23 +2166,25 @@ _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 -_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, @@ -2178,7 +2206,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 aa529b54d..1113c9928 100644 --- a/src/nm-ip4-config.h +++ b/src/nm-ip4-config.h @@ -90,7 +90,9 @@ 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_old, + const NMPObject **out_obj_new); const NMDedupMultiEntry *_nm_ip_config_lookup_ip_route (const NMDedupMultiIndex *multi_idx, const NMIPConfigDedupMultiIdxType *idx_type, @@ -164,18 +166,20 @@ 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 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_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 86d76347b..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); /*****************************************************************************/ @@ -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; @@ -439,7 +439,9 @@ nm_ip6_config_capture (NMDedupMultiIndex *multi_idx, NMPlatform *platform, int i plobj, NULL, FALSE, - TRUE)) + TRUE, + NULL, + NULL)) nm_assert_not_reached (); has_addresses = TRUE; } @@ -462,7 +464,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; @@ -470,23 +473,20 @@ 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->table_coerced) + continue; 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); + _add_route (self, plobj, NULL, 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. */ @@ -671,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 */ @@ -860,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,7 +1254,9 @@ nm_ip6_config_replace (NMIP6Config *dst, const NMIP6Config *src, gboolean *relev ipconf_iter_src.current->obj, NULL, FALSE, - TRUE); + TRUE, + NULL, + NULL); } nm_dedup_multi_index_dirty_remove_idx (dst_priv->multi_idx, &dst_priv->idx_ip6_addresses, FALSE); _notify_addresses (dst); @@ -1299,7 +1301,9 @@ nm_ip6_config_replace (NMIP6Config *dst, const NMIP6Config *src, gboolean *relev ipconf_iter_src.current->obj, NULL, FALSE, - TRUE); + TRUE, + NULL, + NULL); } nm_dedup_multi_index_dirty_remove_idx (dst_priv->multi_idx, &dst_priv->idx_ip6_routes, FALSE); _notify_routes (dst); @@ -1561,7 +1565,9 @@ nm_ip6_config_reset_addresses_ndisc (NMIP6Config *self, &obj, NULL, FALSE, - TRUE)) + TRUE, + NULL, + NULL)) changed = TRUE; } @@ -1595,7 +1601,9 @@ _add_address (NMIP6Config *self, obj_new, (const NMPlatformObject *) new, TRUE, - FALSE)) + FALSE, + NULL, + NULL)) _notify_addresses (self); } @@ -1621,12 +1629,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, @@ -1658,7 +1666,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; @@ -1788,7 +1796,9 @@ nm_ip6_config_reset_routes_ndisc (NMIP6Config *self, &obj, NULL, FALSE, - TRUE)) + TRUE, + NULL, + NULL)) changed = TRUE; } @@ -1810,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)); @@ -1824,14 +1838,21 @@ _add_route (NMIP6Config *self, const NMPObject *obj_new, const NMPlatformIP6Rout obj_new, (const NMPlatformObject *) new, TRUE, - FALSE)) + FALSE, + 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 @@ -1839,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 e3da0eca9..0a7fe1749 100644 --- a/src/nm-ip6-config.h +++ b/src/nm-ip6-config.h @@ -130,21 +130,23 @@ 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); 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/nm-policy.c b/src/nm-policy.c index 1a97b0273..f3c915db9 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,47 +659,39 @@ 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) { - 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); } } - } else 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) { - 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); @@ -726,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' */ @@ -745,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))) { @@ -830,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; @@ -840,18 +831,17 @@ 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 (nm_clear_g_object (&priv->default_device4)) { + _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) { @@ -869,19 +859,17 @@ 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 (!nm_g_object_ref_set (&priv->default_device4, best)) return; + _LOGt (LOGD_DNS, "set-default-device-4: %p", priv->default_device4); - priv->default_device4 = default_device; - connection = nm_active_connection_get_applied_connection (best_ac); _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); } @@ -958,8 +946,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; @@ -968,18 +955,17 @@ 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 (nm_clear_g_object (&priv->default_device6)) { + _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) { @@ -997,21 +983,19 @@ 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 (!nm_g_object_ref_set (&priv->default_device6, best)) return; - priv->default_device6 = default_device6; + _LOGt (LOGD_DNS, "set-default-device-6: %p", priv->default_device6); update_ip6_prefix_delegation (self); - connection = nm_active_connection_get_applied_connection (best_ac); _LOGI (LOGD_CORE, "set '%s' (%s) as default for IPv6 routing and DNS", - nm_connection_get_id (connection), ip_iface); + nm_connection_get_id (nm_active_connection_get_applied_connection (best_ac)), + ip_iface); _notify (self, PROP_DEFAULT_IP6_DEVICE); } @@ -1029,7 +1013,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__); } @@ -1038,24 +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) { - 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) { - 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 { @@ -1260,7 +1243,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 @@ -1742,7 +1725,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) @@ -1778,7 +1761,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) @@ -2405,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); diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 7e91b7547..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; } @@ -3778,6 +3764,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(), 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); diff --git a/src/tests/test-ip4-config.c b/src/tests/test-ip4-config.c index d47ff2e64..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); @@ -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); @@ -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)); @@ -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); @@ -234,29 +234,29 @@ 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_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); + nm_ip4_config_add_route (a, &route, NULL); - 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); + nm_ip4_config_add_route (a, &route, NULL); - 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); + nm_ip4_config_add_route (a, &route, NULL); - 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 707900953..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); @@ -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); @@ -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)); @@ -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); @@ -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); @@ -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 (); } @@ -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_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); + } + 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 (); } 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); |