diff options
| author | Michael Biebl <biebl@debian.org> | 2022-02-14 19:23:28 +0100 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2022-02-14 19:23:28 +0100 |
| commit | 2f94dba7385fd0e0ef19a06eb4a2fcf6c43d7946 (patch) | |
| tree | e2222f5577115985dd52044d2991253403cdd952 /src/core/NetworkManagerUtils.c | |
| parent | 88c227d90a6b7b388c5c85d72802a0ca8f05ed5c (diff) | |
New upstream version 1.35.91 upstream/1.35.91
Diffstat (limited to 'src/core/NetworkManagerUtils.c')
| -rw-r--r-- | src/core/NetworkManagerUtils.c | 358 |
1 files changed, 243 insertions, 115 deletions
diff --git a/src/core/NetworkManagerUtils.c b/src/core/NetworkManagerUtils.c index 0da8e0a9..c50dbada 100644 --- a/src/core/NetworkManagerUtils.c +++ b/src/core/NetworkManagerUtils.c @@ -28,6 +28,7 @@ #include "libnm-platform/nm-platform.h" #include "libnm-platform/nm-linux-platform.h" +#include "libnm-platform/nm-platform-utils.h" #include "nm-auth-utils.h" #include "libnm-systemd-shared/nm-sd-utils-shared.h" @@ -42,9 +43,9 @@ const char * nm_utils_get_shared_wifi_permission(NMConnection *connection) { - NMSettingWireless * s_wifi; + NMSettingWireless *s_wifi; NMSettingWirelessSecurity *s_wsec; - const char * method; + const char *method; method = nm_utils_get_ip_config_method(connection, AF_INET); if (!nm_streq(method, NM_SETTING_IP4_CONFIG_METHOD_SHARED)) @@ -66,8 +67,8 @@ nm_utils_get_shared_wifi_permission(NMConnection *connection) static char * get_new_connection_name(NMConnection *const *existing_connections, - const char * preferred, - const char * fallback_prefix) + const char *preferred, + const char *fallback_prefix) { gs_free const char **existing_names = NULL; guint i, existing_len = 0; @@ -79,7 +80,7 @@ get_new_connection_name(NMConnection *const *existing_connections, existing_names = g_new(const char *, existing_len); for (i = 0; i < existing_len; i++) { NMConnection *candidate; - const char * id; + const char *id; candidate = existing_connections[i]; nm_assert(NM_IS_CONNECTION(candidate)); @@ -121,9 +122,9 @@ get_new_connection_name(NMConnection *const *existing_connections, } static char * -get_new_connection_ifname(NMPlatform * platform, +get_new_connection_ifname(NMPlatform *platform, NMConnection *const *existing_connections, - const char * prefix) + const char *prefix) { guint i, j; @@ -153,8 +154,8 @@ const char * nm_utils_get_ip_config_method(NMConnection *connection, int addr_family) { NMSettingConnection *s_con; - NMSettingIPConfig * s_ip; - const char * method; + NMSettingIPConfig *s_ip; + const char *method; s_con = nm_connection_get_setting_connection(connection); @@ -184,9 +185,9 @@ nm_utils_get_ip_config_method(NMConnection *connection, int addr_family) gboolean nm_utils_connection_has_default_route(NMConnection *connection, int addr_family, - gboolean * out_is_never_default) + gboolean *out_is_never_default) { - const char * method; + const char *method; NMSettingIPConfig *s_ip; gboolean is_never_default = FALSE; gboolean has_default_route = FALSE; @@ -228,23 +229,38 @@ out: /*****************************************************************************/ void -_nm_utils_complete_generic_with_params(NMPlatform * platform, - NMConnection * connection, - const char * ctype, +nm_utils_ppp_ip_methods_enabled(NMConnection *connection, + gboolean *out_ip4_enabled, + gboolean *out_ip6_enabled) +{ + NM_SET_OUT(out_ip4_enabled, + nm_streq0(nm_utils_get_ip_config_method(connection, AF_INET), + NM_SETTING_IP4_CONFIG_METHOD_AUTO)); + NM_SET_OUT(out_ip6_enabled, + nm_streq0(nm_utils_get_ip_config_method(connection, AF_INET6), + NM_SETTING_IP6_CONFIG_METHOD_AUTO)); +} + +/*****************************************************************************/ + +void +_nm_utils_complete_generic_with_params(NMPlatform *platform, + NMConnection *connection, + const char *ctype, NMConnection *const *existing_connections, - const char * preferred_id, - const char * fallback_id_prefix, - const char * ifname_prefix, - const char * ifname, + const char *preferred_id, + const char *fallback_id_prefix, + const char *ifname_prefix, + const char *ifname, ...) { - NMSettingConnection *s_con; - char * id; - char * generated_ifname; + NMSettingConnection *s_con; + char *id; + char *generated_ifname; gs_unref_hashtable GHashTable *parameters = NULL; va_list ap; - const char * p_val; - const char * p_key; + const char *p_val; + const char *p_key; g_assert(fallback_id_prefix); g_return_if_fail(ifname_prefix == NULL || ifname == NULL); @@ -324,8 +340,8 @@ remove_from_hash(GHashTable *s_hash, GHashTable *p_hash, const char *s_name, con static gboolean check_ip6_method(NMConnection *orig, NMConnection *candidate, GHashTable *settings) { - GHashTable * props; - const char * orig_ip6_method, *candidate_ip6_method; + GHashTable *props; + const char *orig_ip6_method, *candidate_ip6_method; NMSettingIPConfig *candidate_ip6; gboolean allow = FALSE; @@ -415,16 +431,16 @@ route_ptr_compare(const void *a, const void *b, gpointer metric) static gboolean check_ip_routes(NMConnection *orig, NMConnection *candidate, - GHashTable * settings, + GHashTable *settings, gint64 default_metric, gboolean v4) { gs_free NMIPRoute **routes1 = NULL; - NMIPRoute ** routes2; - NMSettingIPConfig * s_ip1, *s_ip2; + NMIPRoute **routes2; + NMSettingIPConfig *s_ip1, *s_ip2; gint64 m; - const char * s_name; - GHashTable * props; + const char *s_name; + GHashTable *props; guint i, i1, i2, num1, num2; const guint8 PLEN = v4 ? 32 : 128; @@ -493,11 +509,11 @@ check_ip_routes(NMConnection *orig, static gboolean check_ip4_method(NMConnection *orig, NMConnection *candidate, - GHashTable * settings, + GHashTable *settings, gboolean device_has_carrier) { - GHashTable * props; - const char * orig_ip4_method, *candidate_ip4_method; + GHashTable *props; + const char *orig_ip4_method, *candidate_ip4_method; NMSettingIPConfig *candidate_ip4; props = check_property_in_hash(settings, @@ -531,8 +547,8 @@ check_ip4_method(NMConnection *orig, static gboolean check_connection_interface_name(NMConnection *orig, NMConnection *candidate, GHashTable *settings) { - GHashTable * props; - const char * orig_ifname, *cand_ifname; + GHashTable *props; + const char *orig_ifname, *cand_ifname; NMSettingConnection *s_con_orig, *s_con_cand; props = check_property_in_hash(settings, @@ -560,8 +576,8 @@ check_connection_interface_name(NMConnection *orig, NMConnection *candidate, GHa static gboolean check_connection_mac_address(NMConnection *orig, NMConnection *candidate, GHashTable *settings) { - GHashTable * props; - const char * orig_mac = NULL, *cand_mac = NULL; + GHashTable *props; + const char *orig_mac = NULL, *cand_mac = NULL; NMSettingWired *s_wired_orig, *s_wired_cand; props = check_property_in_hash(settings, @@ -592,10 +608,10 @@ check_connection_mac_address(NMConnection *orig, NMConnection *candidate, GHashT static gboolean check_connection_infiniband_mac_address(NMConnection *orig, NMConnection *candidate, - GHashTable * settings) + GHashTable *settings) { - GHashTable * props; - const char * orig_mac = NULL, *cand_mac = NULL; + GHashTable *props; + const char *orig_mac = NULL, *cand_mac = NULL; NMSettingInfiniband *s_infiniband_orig, *s_infiniband_cand; props = check_property_in_hash(settings, @@ -626,10 +642,10 @@ check_connection_infiniband_mac_address(NMConnection *orig, static gboolean check_connection_cloned_mac_address(NMConnection *orig, NMConnection *candidate, - GHashTable * settings) + GHashTable *settings) { - GHashTable * props; - const char * orig_mac = NULL, *cand_mac = NULL; + GHashTable *props; + const char *orig_mac = NULL, *cand_mac = NULL; NMSettingWired *s_wired_orig, *s_wired_cand; props = check_property_in_hash(settings, @@ -666,7 +682,7 @@ check_connection_cloned_mac_address(NMConnection *orig, static gboolean check_connection_s390_props(NMConnection *orig, NMConnection *candidate, GHashTable *settings) { - GHashTable * props1, *props2, *props3; + GHashTable *props1, *props2, *props3; NMSettingWired *s_wired_orig, *s_wired_cand; props1 = check_property_in_hash(settings, @@ -688,7 +704,7 @@ check_connection_s390_props(NMConnection *orig, NMConnection *candidate, GHashTa s_wired_cand = nm_connection_get_setting_wired(candidate); if (!s_wired_orig && s_wired_cand) { const char *const *subchans = nm_setting_wired_get_s390_subchannels(s_wired_cand); - const char * nettype = nm_setting_wired_get_s390_nettype(s_wired_cand); + const char *nettype = nm_setting_wired_get_s390_nettype(s_wired_cand); guint32 num_options = nm_setting_wired_get_num_s390_options(s_wired_cand); if ((!subchans || !*subchans) && !nettype && num_options == 0) { @@ -713,7 +729,7 @@ check_connection_s390_props(NMConnection *orig, NMConnection *candidate, GHashTa static NMConnection * check_possible_match(NMConnection *orig, NMConnection *candidate, - GHashTable * settings, + GHashTable *settings, gboolean device_has_carrier, gint64 default_v4_metric, gint64 default_v6_metric) @@ -779,8 +795,8 @@ check_possible_match(NMConnection *orig, * matches well enough. */ NMConnection * -nm_utils_match_connection(NMConnection *const * connections, - NMConnection * original, +nm_utils_match_connection(NMConnection *const *connections, + NMConnection *original, gboolean indicated, gboolean device_has_carrier, gint64 default_v4_metric, @@ -795,7 +811,7 @@ nm_utils_match_connection(NMConnection *const * connections, for (; *connections; connections++) { NMConnection *candidate = *connections; - GHashTable * diffs = NULL; + GHashTable *diffs = NULL; nm_assert(NM_IS_CONNECTION(candidate)); @@ -835,7 +851,7 @@ nm_utils_match_connection(NMConnection *const * connections, } if (!best_match && nm_logging_enabled(LOGL_DEBUG, LOGD_CORE)) { - GString * diff_string; + GString *diff_string; GHashTableIter s_iter, p_iter; gpointer setting_name, setting; gpointer property_name, value; @@ -878,9 +894,9 @@ nm_utils_match_connection(NMConnection *const * connections, int nm_match_spec_device_by_pllink(const NMPlatformLink *pllink, - const char * match_device_type, - const char * match_dhcp_plugin, - const GSList * specs, + const char *match_device_type, + const char *match_dhcp_plugin, + const GSList *specs, int no_match_value) { NMMatchSpecMatchType m; @@ -971,7 +987,7 @@ nm_ip_routing_rule_to_platform(const NMIPRoutingRule *rule, NMPlatformRoutingRul struct _NMShutdownWaitObjHandle { CList lst; gpointer watched_obj; - char * msg_reason; + char *msg_reason; bool free_msg_reason : 1; bool is_cancellable : 1; }; @@ -1044,7 +1060,7 @@ _shutdown_waitobj_cb(gpointer user_data, GObject *where_the_object_was) NMShutdownWaitObjHandle * nm_shutdown_wait_obj_register_full(gpointer watched_obj, NMShutdownWaitType wait_type, - char * msg_reason, + char *msg_reason, gboolean free_msg_reason) { NMShutdownWaitObjHandle *handle; @@ -1164,8 +1180,8 @@ nm_utils_qdiscs_from_tc_setting(NMPlatform *platform, NMSettingTCConfig *s_tc, i qdiscs = g_ptr_array_new_full(nqdiscs, (GDestroyNotify) nmp_object_unref); for (i = 0; i < nqdiscs; i++) { - NMTCQdisc * s_qdisc = nm_setting_tc_config_get_qdisc(s_tc, i); - NMPObject * q = nmp_object_new(NMP_OBJECT_TYPE_QDISC, NULL); + NMTCQdisc *s_qdisc = nm_setting_tc_config_get_qdisc(s_tc, i); + NMPObject *q = nmp_object_new(NMP_OBJECT_TYPE_QDISC, NULL); NMPlatformQdisc *qdisc = NMP_OBJECT_CAST_QDISC(q); qdisc->ifindex = ip_ifindex; @@ -1238,9 +1254,9 @@ nm_utils_tfilters_from_tc_setting(NMPlatform *platform, NMSettingTCConfig *s_tc, tfilters = g_ptr_array_new_full(ntfilters, (GDestroyNotify) nmp_object_unref); for (i = 0; i < ntfilters; i++) { - NMTCTfilter * s_tfilter = nm_setting_tc_config_get_tfilter(s_tc, i); - NMTCAction * action; - NMPObject * t = nmp_object_new(NMP_OBJECT_TYPE_TFILTER, NULL); + NMTCTfilter *s_tfilter = nm_setting_tc_config_get_tfilter(s_tc, i); + NMTCAction *action; + NMPObject *t = nmp_object_new(NMP_OBJECT_TYPE_TFILTER, NULL); NMPlatformTfilter *tfilter = NMP_OBJECT_CAST_TFILTER(t); tfilter->ifindex = ip_ifindex; @@ -1296,11 +1312,12 @@ nm_utils_tfilters_from_tc_setting(NMPlatform *platform, NMSettingTCConfig *s_tc, void nm_utils_ip_route_attribute_to_platform(int addr_family, - NMIPRoute * s_route, + NMIPRoute *s_route, NMPlatformIPRoute *r, - guint32 route_table) + gint64 route_table) { - GVariant * variant; + const int IS_IPv4 = NM_IS_IPv4(addr_family); + GVariant *variant; guint32 table; NMIPAddr addr; NMPlatformIP4Route *r4 = (NMPlatformIP4Route *) r; @@ -1308,8 +1325,10 @@ nm_utils_ip_route_attribute_to_platform(int addr_family, gboolean onlink; nm_assert(s_route); - nm_assert_addr_family(addr_family); + nm_assert(addr_family == nm_ip_route_get_family(s_route)); nm_assert(r); + nm_assert(route_table >= -1); + nm_assert(route_table <= (gint64) G_MAXUINT32); #define GET_ATTR(name, dst, variant_type, type, dflt) \ G_STMT_START \ @@ -1328,7 +1347,8 @@ nm_utils_ip_route_attribute_to_platform(int addr_family, int type; type = nm_net_aux_rtnl_rtntype_a2n(g_variant_get_string(variant, NULL)); - nm_assert(NM_IN_SET(type, RTN_UNICAST, RTN_LOCAL)); + nm_assert( + NM_IN_SET(type, RTN_UNICAST, RTN_LOCAL, RTN_BLACKHOLE, RTN_UNREACHABLE, RTN_PROHIBIT)); r->type_coerced = nm_platform_route_type_coerce(type); } else @@ -1336,12 +1356,18 @@ nm_utils_ip_route_attribute_to_platform(int addr_family, GET_ATTR(NM_IP_ROUTE_ATTRIBUTE_TABLE, table, UINT32, uint32, 0); - if (!table && r->type_coerced == nm_platform_route_type_coerce(RTN_LOCAL)) + if (table != 0) + r->table_coerced = nm_platform_route_table_coerce(table); + else if (r->type_coerced == nm_platform_route_type_coerce(RTN_LOCAL)) r->table_coerced = nm_platform_route_table_coerce(RT_TABLE_LOCAL); + else if (route_table == 0) + r->table_coerced = nm_platform_route_table_coerce(RT_TABLE_MAIN); + else if (route_table > 0) + r->table_coerced = nm_platform_route_table_coerce(route_table); else - r->table_coerced = nm_platform_route_table_coerce(table ?: (route_table ?: RT_TABLE_MAIN)); + r->table_any = TRUE; - if (NM_IS_IPv4(addr_family)) { + if (IS_IPv4) { guint8 scope; GET_ATTR(NM_IP_ROUTE_ATTRIBUTE_TOS, r4->tos, BYTE, byte, 0); @@ -1367,15 +1393,14 @@ nm_utils_ip_route_attribute_to_platform(int addr_family, if ((variant = nm_ip_route_get_attribute(s_route, NM_IP_ROUTE_ATTRIBUTE_SRC)) && g_variant_is_of_type(variant, G_VARIANT_TYPE_STRING)) { if (inet_pton(addr_family, g_variant_get_string(variant, NULL), &addr) == 1) { - if (NM_IS_IPv4(addr_family)) + if (IS_IPv4) r4->pref_src = addr.addr4; else r6->pref_src = addr.addr6; } } - if (!NM_IS_IPv4(addr_family) - && (variant = nm_ip_route_get_attribute(s_route, NM_IP_ROUTE_ATTRIBUTE_FROM)) + if (!IS_IPv4 && (variant = nm_ip_route_get_attribute(s_route, NM_IP_ROUTE_ATTRIBUTE_FROM)) && g_variant_is_of_type(variant, G_VARIANT_TYPE_STRING)) { int prefix; @@ -1395,39 +1420,20 @@ nm_utils_ip_route_attribute_to_platform(int addr_family, /*****************************************************************************/ -static int -_addresses_sort_cmp_4(gconstpointer a, gconstpointer b, gpointer user_data) -{ - return nm_platform_ip4_address_pretty_sort_cmp( - NMP_OBJECT_CAST_IP4_ADDRESS(*((const NMPObject **) a)), - NMP_OBJECT_CAST_IP4_ADDRESS(*((const NMPObject **) b))); -} - -static int -_addresses_sort_cmp_6(gconstpointer a, gconstpointer b, gpointer user_data) -{ - return nm_platform_ip6_address_pretty_sort_cmp( - NMP_OBJECT_CAST_IP6_ADDRESS(*((const NMPObject **) a)), - NMP_OBJECT_CAST_IP6_ADDRESS(*((const NMPObject **) b)), - (((NMSettingIP6ConfigPrivacy) GPOINTER_TO_INT(user_data)) - == NM_SETTING_IP6_CONFIG_PRIVACY_PREFER_TEMP_ADDR)); -} - void nm_utils_ip_addresses_to_dbus(int addr_family, const NMDedupMultiHeadEntry *head_entry, - const NMPObject * best_default_route, - NMSettingIP6ConfigPrivacy ipv6_privacy, - GVariant ** out_address_data, - GVariant ** out_addresses) + const NMPObject *best_default_route, + GVariant **out_address_data, + GVariant **out_addresses) { - const int IS_IPv4 = NM_IS_IPv4(addr_family); - GVariantBuilder builder_data; - GVariantBuilder builder_legacy; - char addr_str[NM_UTILS_INET_ADDRSTRLEN]; - gs_free const NMPObject **addresses = NULL; - guint naddr; - guint i; + const int IS_IPv4 = NM_IS_IPv4(addr_family); + GVariantBuilder builder_data; + GVariantBuilder builder_legacy; + char addr_str[NM_UTILS_INET_ADDRSTRLEN]; + NMDedupMultiIter iter; + const NMPObject *obj; + guint i; nm_assert_addr_family(addr_family); @@ -1443,19 +1449,11 @@ nm_utils_ip_addresses_to_dbus(int addr_family, if (!head_entry) goto out; - addresses = - (const NMPObject **) nm_dedup_multi_objs_to_array_head(head_entry, NULL, NULL, &naddr); - - nm_assert(addresses && naddr); - - g_qsort_with_data(addresses, - naddr, - sizeof(addresses[0]), - IS_IPv4 ? _addresses_sort_cmp_4 : _addresses_sort_cmp_6, - GINT_TO_POINTER(ipv6_privacy)); - - for (i = 0; i < naddr; i++) { - const NMPlatformIPXAddress *address = NMP_OBJECT_CAST_IPX_ADDRESS(addresses[i]); + i = 0; + nm_dedup_multi_iter_init(&iter, head_entry); + while ( + nm_platform_dedup_multi_iter_next_obj(&iter, &obj, NMP_OBJECT_TYPE_IP_ADDRESS(IS_IPv4))) { + const NMPlatformIPXAddress *address = NMP_OBJECT_CAST_IPX_ADDRESS(obj); if (out_address_data) { GVariantBuilder addr_builder; @@ -1527,6 +1525,8 @@ nm_utils_ip_addresses_to_dbus(int addr_family, : &in6addr_any)); } } + + i++; } out: @@ -1537,8 +1537,8 @@ out: void nm_utils_ip_routes_to_dbus(int addr_family, const NMDedupMultiHeadEntry *head_entry, - GVariant ** out_route_data, - GVariant ** out_routes) + GVariant **out_route_data, + GVariant **out_routes) { const int IS_IPv4 = NM_IS_IPv4(addr_family); NMDedupMultiIter iter; @@ -1654,6 +1654,134 @@ nm_utils_ip_routes_to_dbus(int addr_family, /*****************************************************************************/ +NMSetting * +nm_utils_platform_capture_ip_setting(NMPlatform *platform, + int addr_family, + int ifindex, + gboolean maybe_ipv6_disabled) +{ + const int IS_IPv4 = NM_IS_IPv4(addr_family); + gs_unref_object NMSettingIPConfig *s_ip = NULL; + NMPLookup lookup; + NMDedupMultiIter iter; + const NMPObject *obj; + const char *method = NULL; + char sbuf[NM_UTILS_INET_ADDRSTRLEN]; + const NMPlatformIPXRoute *best_default_route = NULL; + + s_ip = + NM_SETTING_IP_CONFIG(IS_IPv4 ? nm_setting_ip4_config_new() : nm_setting_ip6_config_new()); + + if (ifindex <= 0 || !nm_platform_link_get(platform, ifindex)) { + g_object_set(s_ip, + NM_SETTING_IP_CONFIG_METHOD, + IS_IPv4 ? NM_SETTING_IP4_CONFIG_METHOD_DISABLED + : NM_SETTING_IP6_CONFIG_METHOD_IGNORE, + NULL); + return NM_SETTING(g_steal_pointer(&s_ip)); + } + + nmp_lookup_init_object(&lookup, NMP_OBJECT_TYPE_IP_ADDRESS(IS_IPv4), ifindex); + nm_platform_iter_obj_for_each (&iter, platform, &lookup, &obj) { + const NMPlatformIPXAddress *address = NMP_OBJECT_CAST_IPX_ADDRESS(obj); + nm_auto_unref_ip_address NMIPAddress *s_addr = NULL; + + if (!IS_IPv4) { + /* Ignore link-local address. */ + if (IN6_IS_ADDR_LINKLOCAL(address->ax.address_ptr)) { + if (!method) + method = NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL; + continue; + } + } + + /* Detect dynamic address */ + if (address->ax.lifetime != NM_PLATFORM_LIFETIME_PERMANENT) { + method = + IS_IPv4 ? NM_SETTING_IP4_CONFIG_METHOD_AUTO : NM_SETTING_IP6_CONFIG_METHOD_AUTO; + continue; + } + + /* Static address found. */ + if (IS_IPv4) { + if (!method) + method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL; + } else { + if (NM_IN_STRSET(method, NULL, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL)) + method = NM_SETTING_IP6_CONFIG_METHOD_MANUAL; + } + + s_addr = + nm_ip_address_new_binary(addr_family, address->ax.address_ptr, address->ax.plen, NULL); + + if (IS_IPv4) { + if (address->a4.label[0]) { + nm_ip_address_set_attribute(s_addr, + NM_IP_ADDRESS_ATTRIBUTE_LABEL, + g_variant_new_string(address->a4.label)); + } + } + + nm_setting_ip_config_add_address(s_ip, s_addr); + } + + if (!method) { + /* Use 'disabled/ignore' if the method wasn't previously set */ + if (IS_IPv4) + method = NM_SETTING_IP4_CONFIG_METHOD_DISABLED; + else + method = maybe_ipv6_disabled ? NM_SETTING_IP6_CONFIG_METHOD_DISABLED + : NM_SETTING_IP6_CONFIG_METHOD_IGNORE; + } + g_object_set(s_ip, NM_SETTING_IP_CONFIG_METHOD, method, NULL); + + nmp_lookup_init_object(&lookup, NMP_OBJECT_TYPE_IP_ROUTE(IS_IPv4), ifindex); + nm_platform_iter_obj_for_each (&iter, platform, &lookup, &obj) { + const NMPlatformIPXRoute *route = NMP_OBJECT_CAST_IPX_ROUTE(obj); + nm_auto_unref_ip_route NMIPRoute *s_route = NULL; + + if (!IS_IPv4) { + /* Ignore link-local route. */ + if (IN6_IS_ADDR_LINKLOCAL(route->rx.network_ptr)) + continue; + } + + if (NM_PLATFORM_IP_ROUTE_IS_DEFAULT(route)) { + if (!best_default_route) + best_default_route = route; + continue; + } + + if (route->rx.rt_source + != nmp_utils_ip_config_source_round_trip_rtprot(NM_IP_CONFIG_SOURCE_USER)) { + /* Ignore routes provided by external sources */ + continue; + } + + s_route = nm_ip_route_new_binary(addr_family, + route->rx.network_ptr, + route->rx.plen, + nm_platform_ip_route_get_gateway(addr_family, &route->rx), + route->rx.metric, + NULL); + nm_setting_ip_config_add_route(s_ip, s_route); + } + + if (best_default_route && nm_setting_ip_config_get_num_addresses(s_ip) > 0) { + g_object_set(s_ip, + NM_SETTING_IP_CONFIG_GATEWAY, + nm_utils_inet_ntop( + addr_family, + nm_platform_ip_route_get_gateway(addr_family, &best_default_route->rx), + sbuf), + NULL); + } + + return NM_SETTING(g_steal_pointer(&s_ip)); +} + +/*****************************************************************************/ + /* Singleton NMPlatform subclass instance and cached class object */ NM_DEFINE_SINGLETON_INSTANCE(NMPlatform); |