diff options
Diffstat (limited to 'src/core/nm-l3-config-data.c')
| -rw-r--r-- | src/core/nm-l3-config-data.c | 539 |
1 files changed, 387 insertions, 152 deletions
diff --git a/src/core/nm-l3-config-data.c b/src/core/nm-l3-config-data.c index 033c8942..03593ea2 100644 --- a/src/core/nm-l3-config-data.c +++ b/src/core/nm-l3-config-data.c @@ -117,8 +117,10 @@ struct _NML3ConfigData { NMIPRouteTableSyncMode route_table_sync_x[2]; }; - NMSettingConnectionMdns mdns; - NMSettingConnectionLlmnr llmnr; + NMSettingConnectionMdns mdns; + NMSettingConnectionLlmnr llmnr; + NMSettingConnectionDnsOverTls dns_over_tls; + NMUtilsIPv6IfaceId ip6_token; NML3ConfigDatFlags flags; @@ -177,7 +179,7 @@ static GArray * _garray_inaddr_clone(const GArray *src, int addr_family) { const gsize elt_size = nm_utils_addr_family_to_size(addr_family); - GArray * dst; + GArray *dst; nm_assert_addr_family(addr_family); @@ -226,7 +228,7 @@ next:; } static gssize -_garray_inaddr_find(GArray * arr, +_garray_inaddr_find(GArray *arr, int addr_family, gconstpointer needle, /* (const NMIPAddr **) */ gpointer out_addr) @@ -342,8 +344,8 @@ _strv_ptrarray_merge(GPtrArray **p_dst, const GPtrArray *src) void nm_l3_config_data_log(const NML3ConfigData *self, - const char * title, - const char * prefix, + const char *title, + const char *prefix, NMLogLevel log_level, NMLogDomain log_domain) { @@ -443,7 +445,7 @@ nm_l3_config_data_log(const NML3ConfigData *self, if (self->ndisc_hop_limit_set || self->ndisc_reachable_time_msec_set || self->ndisc_retrans_timer_msec_set) { gsize l = sizeof(sbuf); - char * p = sbuf; + char *p = sbuf; const char *s_prefix = "ndisc: "; if (self->ndisc_hop_limit_set) { @@ -524,7 +526,7 @@ nm_l3_config_data_log(const NML3ConfigData *self, if (self->dhcp_lease_x[IS_IPv4]) { gs_free NMUtilsNamedValue *options_free = NULL; NMUtilsNamedValue options_buffer[30]; - NMUtilsNamedValue * options; + NMUtilsNamedValue *options; guint options_len; options = nm_utils_named_values_from_strdict( @@ -570,6 +572,21 @@ nm_l3_config_data_log(const NML3ConfigData *self, NULL))); } + if (self->dns_over_tls != NM_SETTING_CONNECTION_DNS_OVER_TLS_DEFAULT) { + gs_free char *s = NULL; + + _L("dns-over-tls: %s", + (s = _nm_utils_enum_to_str_full(nm_setting_connection_dns_over_tls_get_type(), + self->dns_over_tls, + " ", + NULL))); + } + + if (self->ip6_token.id != 0) { + _L("ipv6-token: %s", + nm_utils_inet6_interface_identifier_to_token(&self->ip6_token, sbuf_addr)); + } + if (self->metered != NM_TERNARY_DEFAULT) _L("metered: %s", self->metered ? "yes" : "no"); @@ -617,22 +634,22 @@ _route_valid(int addr_family, gconstpointer r) static gboolean _NM_IS_L3_CONFIG_DATA(const NML3ConfigData *self, gboolean allow_sealed) { - nm_assert(!self || (self->ifindex > 0 && self->multi_idx && self->ref_count > 0)); + nm_assert(!self || (self->ifindex >= 0 && self->multi_idx && self->ref_count > 0)); return self && self->ref_count > 0 && (allow_sealed || !self->is_sealed); } static void _idx_obj_id_hash_update(const NMDedupMultiIdxType *idx_type, - const NMDedupMultiObj * obj, - NMHashState * h) + const NMDedupMultiObj *obj, + NMHashState *h) { nmp_object_id_hash_update((NMPObject *) obj, h); } static gboolean _idx_obj_id_equal(const NMDedupMultiIdxType *idx_type, - const NMDedupMultiObj * obj_a, - const NMDedupMultiObj * obj_b) + const NMDedupMultiObj *obj_a, + const NMDedupMultiObj *obj_b) { return nmp_object_id_equal((NMPObject *) obj_a, (NMPObject *) obj_b); } @@ -666,6 +683,7 @@ nm_l3_config_data_new(NMDedupMultiIndex *multi_idx, int ifindex, NMIPConfigSourc .multi_idx = nm_dedup_multi_index_ref(multi_idx), .mdns = NM_SETTING_CONNECTION_MDNS_DEFAULT, .llmnr = NM_SETTING_CONNECTION_LLMNR_DEFAULT, + .dns_over_tls = NM_SETTING_CONNECTION_DNS_OVER_TLS_DEFAULT, .flags = NM_L3_CONFIG_DAT_FLAGS_NONE, .metered = NM_TERNARY_DEFAULT, .proxy_browser_only = NM_TERNARY_DEFAULT, @@ -788,7 +806,7 @@ nm_l3_config_data_unref(const NML3ConfigData *self) static const NMDedupMultiEntry * _lookup_route(const NMDedupMultiIndex *multi_idx, const DedupMultiIdxType *idx_type, - const NMPObject * needle) + const NMPObject *needle) { const NMDedupMultiEntry *entry; @@ -828,7 +846,7 @@ nm_l3_config_data_lookup_route_obj(const NML3ConfigData *self, const NMPObject * } const NMDedupMultiEntry * -nm_l3_config_data_lookup_route(const NML3ConfigData * self, +nm_l3_config_data_lookup_route(const NML3ConfigData *self, int addr_family, const NMPlatformIPRoute *needle) { @@ -952,7 +970,7 @@ gboolean nm_l3_config_data_has_routes_with_type_local(const NML3ConfigData *self, int addr_family) { const int IS_IPv4 = NM_IS_IPv4(addr_family); - NML3ConfigData * self_mutable; + NML3ConfigData *self_mutable; NMDedupMultiIter iter; const NMPObject *obj; gboolean val; @@ -1020,7 +1038,7 @@ nm_l3_config_data_get_flags(const NML3ConfigData *self) } void -nm_l3_config_data_set_flags_full(NML3ConfigData * self, +nm_l3_config_data_set_flags_full(NML3ConfigData *self, NML3ConfigDatFlags flags, NML3ConfigDatFlags mask) { @@ -1053,14 +1071,14 @@ nm_l3_config_data_get_first_obj(const NML3ConfigData *self, /*****************************************************************************/ static gboolean -_l3_config_data_add_obj(NMDedupMultiIndex * multi_idx, - DedupMultiIdxType * idx_type, +_l3_config_data_add_obj(NMDedupMultiIndex *multi_idx, + DedupMultiIdxType *idx_type, int ifindex, - const NMPObject * obj_new, + const NMPObject *obj_new, const NMPlatformObject *pl_new, NML3ConfigAddFlags add_flags, - const NMPObject ** out_obj_old /* returns a reference! */, - const NMPObject ** out_obj_new /* does not return a reference */) + 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; @@ -1076,8 +1094,22 @@ _l3_config_data_add_obj(NMDedupMultiIndex * multi_idx, NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ADDRESS, NMP_OBJECT_TYPE_IP6_ROUTE)); + nm_assert((!!obj_new) != (!!pl_new)); + + if (NM_IN_SET(idx_type->obj_type, NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE)) { + const NMPlatformIPRoute *r; + + r = obj_new ? NMP_OBJECT_CAST_IP_ROUTE(obj_new) : (NMPlatformIPRoute *) pl_new; + + if (nm_platform_route_type_is_nodev(nm_platform_route_type_uncoerce(r->type_coerced))) { + /* such routes don't have a device/next-hop. We track them without ifindex. */ + ifindex = 0; + } + } + /* we go through extra lengths to accept a full obj_new object. That one, - * can be reused by increasing the ref-count. */ + * can be reused by increasing the ref-count. We thus accept any ifindex, and + * set it here. */ if (!obj_new) { nm_assert(pl_new); obj_new = nmp_object_stackinit(&obj_new_stackinit, idx_type->obj_type, pl_new); @@ -1258,12 +1290,12 @@ _l3_config_best_default_route_find_better(const NMPObject *obj_cur, const NMPObj } gboolean -nm_l3_config_data_add_address_full(NML3ConfigData * self, +nm_l3_config_data_add_address_full(NML3ConfigData *self, int addr_family, - const NMPObject * obj_new, + const NMPObject *obj_new, const NMPlatformIPAddress *pl_new, NML3ConfigAddFlags add_flags, - const NMPObject ** out_obj_new) + const NMPObject **out_obj_new) { const NMPObject *new; gboolean changed; @@ -1287,24 +1319,24 @@ nm_l3_config_data_add_address_full(NML3ConfigData * self, static gboolean _l3_config_best_default_route_merge(const NMPObject **best_default_route, - const NMPObject * new_candidate) + const NMPObject *new_candidate) { new_candidate = _l3_config_best_default_route_find_better(*best_default_route, new_candidate); return nmp_object_ref_set(best_default_route, new_candidate); } gboolean -nm_l3_config_data_add_route_full(NML3ConfigData * self, +nm_l3_config_data_add_route_full(NML3ConfigData *self, int addr_family, - const NMPObject * obj_new, + const NMPObject *obj_new, const NMPlatformIPRoute *pl_new, NML3ConfigAddFlags add_flags, - const NMPObject ** out_obj_new, - gboolean * out_changed_best_default_route) + const NMPObject **out_obj_new, + gboolean *out_changed_best_default_route) { - const int IS_IPv4 = NM_IS_IPv4(addr_family); + const int IS_IPv4 = NM_IS_IPv4(addr_family); nm_auto_nmpobj const NMPObject *obj_old = NULL; - const NMPObject * obj_new_2; + const NMPObject *obj_new_2; gboolean changed = FALSE; gboolean changed_best_default_route = FALSE; @@ -1407,7 +1439,7 @@ nm_l3_config_data_get_nameservers(const NML3ConfigData *self, int addr_family, g } gboolean -nm_l3_config_data_add_nameserver(NML3ConfigData * self, +nm_l3_config_data_add_nameserver(NML3ConfigData *self, int addr_family, gconstpointer /* (const NMIPAddr *) */ nameserver) { @@ -1679,6 +1711,26 @@ nm_l3_config_data_set_llmnr(NML3ConfigData *self, NMSettingConnectionLlmnr llmnr return TRUE; } +NMSettingConnectionDnsOverTls +nm_l3_config_data_get_dns_over_tls(const NML3ConfigData *self) +{ + nm_assert(_NM_IS_L3_CONFIG_DATA(self, TRUE)); + + return self->dns_over_tls; +} + +gboolean +nm_l3_config_data_set_dns_over_tls(NML3ConfigData *self, NMSettingConnectionDnsOverTls dns_over_tls) +{ + nm_assert(_NM_IS_L3_CONFIG_DATA(self, FALSE)); + + if (self->dns_over_tls == dns_over_tls) + return FALSE; + + self->dns_over_tls = dns_over_tls; + return TRUE; +} + NMIPRouteTableSyncMode nm_l3_config_data_get_route_table_sync(const NML3ConfigData *self, int addr_family) { @@ -1689,7 +1741,7 @@ nm_l3_config_data_get_route_table_sync(const NML3ConfigData *self, int addr_fami } gboolean -nm_l3_config_data_set_route_table_sync(NML3ConfigData * self, +nm_l3_config_data_set_route_table_sync(NML3ConfigData *self, int addr_family, NMIPRouteTableSyncMode route_table_sync) { @@ -1817,6 +1869,26 @@ nm_l3_config_data_set_ip6_privacy(NML3ConfigData *self, NMSettingIP6ConfigPrivac return TRUE; } +NMUtilsIPv6IfaceId +nm_l3_config_data_get_ip6_token(const NML3ConfigData *self) +{ + nm_assert(_NM_IS_L3_CONFIG_DATA(self, TRUE)); + + return self->ip6_token; +} + +gboolean +nm_l3_config_data_set_ip6_token(NML3ConfigData *self, NMUtilsIPv6IfaceId ipv6_token) +{ + nm_assert(_NM_IS_L3_CONFIG_DATA(self, FALSE)); + + if (self->ip6_token.id == ipv6_token.id) + return FALSE; + + self->ip6_token.id = ipv6_token.id; + return TRUE; +} + NMProxyConfigMethod nm_l3_config_data_get_proxy_method(const NML3ConfigData *self) { @@ -1977,7 +2049,7 @@ gboolean nm_l3_config_data_set_dhcp_lease(NML3ConfigData *self, int addr_family, NMDhcpLease *lease) { nm_auto_unref_dhcplease NMDhcpLease *lease_old = NULL; - NMDhcpLease ** p_lease; + NMDhcpLease **p_lease; nm_assert(_NM_IS_L3_CONFIG_DATA(self, FALSE)); @@ -1996,11 +2068,11 @@ nm_l3_config_data_set_dhcp_lease(NML3ConfigData *self, int addr_family, NMDhcpLe gboolean nm_l3_config_data_set_dhcp_lease_from_options(NML3ConfigData *self, int addr_family, - GHashTable * options_take) + GHashTable *options_take) { nm_auto_unref_dhcplease NMDhcpLease *lease = NULL; nm_auto_unref_dhcplease NMDhcpLease *lease_old = NULL; - NMDhcpLease ** p_lease; + NMDhcpLease **p_lease; nm_assert(_NM_IS_L3_CONFIG_DATA(self, FALSE)); @@ -2023,7 +2095,8 @@ static int _dedup_multi_index_cmp(const NML3ConfigData *a, const NML3ConfigData *b, NMPObjectType obj_type, - gboolean ignore_ifindex) + gboolean cmp_ifindex, + gboolean cmp_full) { const NMDedupMultiHeadEntry *h_a = nm_l3_config_data_lookup_objs(a, obj_type); const NMDedupMultiHeadEntry *h_b = nm_l3_config_data_lookup_objs(b, obj_type); @@ -2062,91 +2135,221 @@ _dedup_multi_index_cmp(const NML3ConfigData *a, have_b = nm_platform_dedup_multi_iter_next_obj(&iter_b, &obj_b, obj_type); nm_assert(have_b); - NM_CMP_RETURN(nmp_object_cmp_full(obj_a, - obj_b, - ignore_ifindex ? NMP_OBJECT_CMP_FLAGS_IGNORE_IFINDEX - : NMP_OBJECT_CMP_FLAGS_NONE)); + if (cmp_full) { + NM_CMP_RETURN(nmp_object_cmp_full(obj_a, + obj_b, + cmp_ifindex ? NMP_OBJECT_CMP_FLAGS_NONE + : NMP_OBJECT_CMP_FLAGS_IGNORE_IFINDEX)); + } else { + if (cmp_ifindex) { + NM_CMP_DIRECT(obj_a->obj_with_ifindex.ifindex, obj_b->obj_with_ifindex.ifindex); + } + + switch (obj_type) { + case NMP_OBJECT_TYPE_IP4_ADDRESS: + NM_CMP_DIRECT(obj_a->ip4_address.plen, obj_b->ip4_address.plen); + NM_CMP_DIRECT(obj_b->ip4_address.address, obj_b->ip4_address.address); + NM_CMP_DIRECT(obj_b->ip4_address.peer_address, obj_b->ip4_address.peer_address); + break; + case NMP_OBJECT_TYPE_IP6_ADDRESS: + NM_CMP_DIRECT(obj_a->ip6_address.plen, obj_b->ip6_address.plen); + NM_CMP_DIRECT_IN6ADDR(&obj_a->ip6_address.address, &obj_b->ip6_address.address); + break; + case NMP_OBJECT_TYPE_IP4_ROUTE: + { + NMPlatformIP4Route ra = obj_a->ip4_route; + NMPlatformIP4Route rb = obj_b->ip4_route; + + NM_CMP_DIRECT(ra.metric, rb.metric); + NM_CMP_DIRECT(ra.plen, rb.plen); + NM_CMP_RETURN_DIRECT( + nm_utils_ip4_address_same_prefix_cmp(ra.network, rb.network, ra.plen)); + break; + } + case NMP_OBJECT_TYPE_IP6_ROUTE: + { + NMPlatformIP6Route ra = obj_a->ip6_route; + NMPlatformIP6Route rb = obj_b->ip6_route; + + NM_CMP_DIRECT(ra.metric, rb.metric); + NM_CMP_DIRECT(ra.plen, rb.plen); + NM_CMP_RETURN_DIRECT( + nm_utils_ip6_address_same_prefix_cmp(&ra.network, &rb.network, ra.plen)); + break; + } + default: + nm_assert_not_reached(); + } + } + } +} + +static const NML3ConfigData * +get_empty_l3cd(void) +{ + static NML3ConfigData *empty_l3cd; + + if (!empty_l3cd) { + empty_l3cd = + nm_l3_config_data_new(nm_dedup_multi_index_new(), 1, NM_IP_CONFIG_SOURCE_UNKNOWN); + empty_l3cd->ifindex = 0; } + + return empty_l3cd; } int nm_l3_config_data_cmp_full(const NML3ConfigData *a, const NML3ConfigData *b, - NML3ConfigCmpFlags cmp_flags) + NML3ConfigCmpFlags flags) { - int IS_IPv4; - gboolean ignore_ifindex; + int IS_IPv4; + + if (a == b) + return 0; - NM_CMP_SELF(a, b); + if (NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_ADDRESSES)) + flags |= NM_L3_CONFIG_CMP_FLAGS_ADDRESSES_ID; + if (NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_ROUTES)) + flags |= NM_L3_CONFIG_CMP_FLAGS_ROUTES_ID; - ignore_ifindex = NM_FLAGS_HAS(cmp_flags, NM_L3_CONFIG_CMP_FLAGS_IGNORE_IFINDEX); + if (!a) + a = get_empty_l3cd(); + if (!b) + b = get_empty_l3cd(); - if (!ignore_ifindex) + if (NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_IFINDEX)) NM_CMP_DIRECT(a->ifindex, b->ifindex); - NM_CMP_DIRECT(a->flags, b->flags); + if (NM_FLAGS_ANY(flags, + NM_L3_CONFIG_CMP_FLAGS_ADDRESSES | NM_L3_CONFIG_CMP_FLAGS_ADDRESSES_ID)) { + NM_CMP_RETURN( + _dedup_multi_index_cmp(a, + b, + NMP_OBJECT_TYPE_IP4_ADDRESS, + NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_IFINDEX), + NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_ADDRESSES))); + NM_CMP_RETURN( + _dedup_multi_index_cmp(a, + b, + NMP_OBJECT_TYPE_IP6_ADDRESS, + NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_IFINDEX), + NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_ADDRESSES))); + } - NM_CMP_RETURN(_dedup_multi_index_cmp(a, b, NMP_OBJECT_TYPE_IP4_ADDRESS, ignore_ifindex)); - NM_CMP_RETURN(_dedup_multi_index_cmp(a, b, NMP_OBJECT_TYPE_IP6_ADDRESS, ignore_ifindex)); - NM_CMP_RETURN(_dedup_multi_index_cmp(a, b, NMP_OBJECT_TYPE_IP4_ROUTE, ignore_ifindex)); - NM_CMP_RETURN(_dedup_multi_index_cmp(a, b, NMP_OBJECT_TYPE_IP6_ROUTE, ignore_ifindex)); + if (NM_FLAGS_ANY(flags, NM_L3_CONFIG_CMP_FLAGS_ROUTES | NM_L3_CONFIG_CMP_FLAGS_ROUTES_ID)) { + NM_CMP_RETURN(_dedup_multi_index_cmp(a, + b, + NMP_OBJECT_TYPE_IP4_ROUTE, + NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_IFINDEX), + NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_ROUTES))); + NM_CMP_RETURN(_dedup_multi_index_cmp(a, + b, + NMP_OBJECT_TYPE_IP6_ROUTE, + NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_IFINDEX), + NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_ROUTES))); + } for (IS_IPv4 = 1; IS_IPv4 >= 0; IS_IPv4--) { - const int addr_family = IS_IPv4 ? AF_INET : AF_INET6; + const int addr_family = IS_IPv4 ? AF_INET : AF_INET6; + const NMPObject *def_route_a = a->best_default_route_x[IS_IPv4]; + const NMPObject *def_route_b = b->best_default_route_x[IS_IPv4]; + + NM_CMP_SELF(def_route_a, def_route_b); + + if (NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_ROUTES)) { + NM_CMP_RETURN(nmp_object_cmp_full(def_route_a, + def_route_b, + NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_IFINDEX) + ? NMP_OBJECT_CMP_FLAGS_NONE + : NMP_OBJECT_CMP_FLAGS_IGNORE_IFINDEX)); + } else if (NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_ROUTES_ID)) { + if (NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_IFINDEX)) { + NM_CMP_DIRECT(def_route_a->obj_with_ifindex.ifindex, + def_route_b->obj_with_ifindex.ifindex); + } - NM_CMP_RETURN(nmp_object_cmp_full(a->best_default_route_x[IS_IPv4], - b->best_default_route_x[IS_IPv4], - ignore_ifindex ? NMP_OBJECT_CMP_FLAGS_IGNORE_IFINDEX - : NMP_OBJECT_CMP_FLAGS_NONE)); + if (IS_IPv4) { + NMPlatformIP4Route ra = def_route_a->ip4_route; + NMPlatformIP4Route rb = def_route_b->ip4_route; + + NM_CMP_DIRECT(ra.metric, rb.metric); + NM_CMP_DIRECT(ra.plen, rb.plen); + NM_CMP_RETURN_DIRECT( + nm_utils_ip4_address_same_prefix_cmp(ra.network, rb.network, ra.plen)); + } else { + NMPlatformIP6Route ra = def_route_a->ip6_route; + NMPlatformIP6Route rb = def_route_b->ip6_route; + + NM_CMP_DIRECT(ra.metric, rb.metric); + NM_CMP_DIRECT(ra.plen, rb.plen); + NM_CMP_RETURN_DIRECT( + nm_utils_ip6_address_same_prefix_cmp(&ra.network, &rb.network, ra.plen)); + } + } - NM_CMP_RETURN( - _garray_inaddr_cmp(a->nameservers_x[IS_IPv4], b->nameservers_x[IS_IPv4], addr_family)); - - NM_CMP_RETURN(nm_utils_hashtable_cmp(nm_dhcp_lease_get_options(a->dhcp_lease_x[IS_IPv4]), - nm_dhcp_lease_get_options(b->dhcp_lease_x[IS_IPv4]), - TRUE, - nm_strcmp_with_data, - nm_strcmp_with_data, - NULL)); - - NM_CMP_RETURN(nm_strv_ptrarray_cmp(a->domains_x[IS_IPv4], b->domains_x[IS_IPv4])); - NM_CMP_RETURN(nm_strv_ptrarray_cmp(a->searches_x[IS_IPv4], b->searches_x[IS_IPv4])); - NM_CMP_RETURN(nm_strv_ptrarray_cmp(a->dns_options_x[IS_IPv4], b->dns_options_x[IS_IPv4])); - - if (NM_FLAGS_ANY(a->flags, NM_L3_CONFIG_DAT_FLAGS_HAS_DNS_PRIORITY(IS_IPv4))) - NM_CMP_DIRECT(a->dns_priority_x[IS_IPv4], b->dns_priority_x[IS_IPv4]); - - NM_CMP_DIRECT(a->route_table_sync_x[IS_IPv4], b->route_table_sync_x[IS_IPv4]); - NM_CMP_DIRECT(a->never_default_x[IS_IPv4], b->never_default_x[IS_IPv4]); - } - - NM_CMP_RETURN(_garray_inaddr_cmp(a->wins, b->wins, AF_INET)); - NM_CMP_RETURN(_garray_inaddr_cmp(a->nis_servers, b->nis_servers, AF_INET)); - NM_CMP_DIRECT_REF_STRING(a->nis_domain, b->nis_domain); - NM_CMP_DIRECT(a->mdns, b->mdns); - NM_CMP_DIRECT(a->llmnr, b->llmnr); - NM_CMP_DIRECT(a->mtu, b->mtu); - NM_CMP_DIRECT(a->ip6_mtu, b->ip6_mtu); - NM_CMP_DIRECT_UNSAFE(a->metered, b->metered); - NM_CMP_DIRECT_UNSAFE(a->proxy_browser_only, b->proxy_browser_only); - NM_CMP_DIRECT_UNSAFE(a->proxy_method, b->proxy_method); - NM_CMP_DIRECT_REF_STRING(a->proxy_pac_url, b->proxy_pac_url); - NM_CMP_DIRECT_REF_STRING(a->proxy_pac_script, b->proxy_pac_script); - NM_CMP_DIRECT_UNSAFE(a->ip6_privacy, b->ip6_privacy); - - NM_CMP_DIRECT_UNSAFE(a->ndisc_hop_limit_set, b->ndisc_hop_limit_set); - if (a->ndisc_hop_limit_set) - NM_CMP_DIRECT(a->ndisc_hop_limit_val, b->ndisc_hop_limit_val); - - NM_CMP_DIRECT_UNSAFE(a->ndisc_reachable_time_msec_set, b->ndisc_reachable_time_msec_set); - if (a->ndisc_reachable_time_msec_set) - NM_CMP_DIRECT(a->ndisc_reachable_time_msec_val, b->ndisc_reachable_time_msec_val); - - NM_CMP_DIRECT_UNSAFE(a->ndisc_retrans_timer_msec_set, b->ndisc_retrans_timer_msec_set); - if (a->ndisc_retrans_timer_msec_set) - NM_CMP_DIRECT(a->ndisc_retrans_timer_msec_val, b->ndisc_retrans_timer_msec_val); - - NM_CMP_FIELD(a, b, source); + if (NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_DNS)) { + NM_CMP_RETURN(_garray_inaddr_cmp(a->nameservers_x[IS_IPv4], + b->nameservers_x[IS_IPv4], + addr_family)); + NM_CMP_RETURN(nm_strv_ptrarray_cmp(a->domains_x[IS_IPv4], b->domains_x[IS_IPv4])); + NM_CMP_RETURN(nm_strv_ptrarray_cmp(a->searches_x[IS_IPv4], b->searches_x[IS_IPv4])); + NM_CMP_RETURN( + nm_strv_ptrarray_cmp(a->dns_options_x[IS_IPv4], b->dns_options_x[IS_IPv4])); + + if (NM_FLAGS_ANY(a->flags, NM_L3_CONFIG_DAT_FLAGS_HAS_DNS_PRIORITY(IS_IPv4))) + NM_CMP_DIRECT(a->dns_priority_x[IS_IPv4], b->dns_priority_x[IS_IPv4]); + } + + if (NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_OTHER)) { + NM_CMP_RETURN( + nm_utils_hashtable_cmp(nm_dhcp_lease_get_options(a->dhcp_lease_x[IS_IPv4]), + nm_dhcp_lease_get_options(b->dhcp_lease_x[IS_IPv4]), + TRUE, + nm_strcmp_with_data, + nm_strcmp_with_data, + NULL)); + + NM_CMP_DIRECT(a->route_table_sync_x[IS_IPv4], b->route_table_sync_x[IS_IPv4]); + NM_CMP_DIRECT(a->never_default_x[IS_IPv4], b->never_default_x[IS_IPv4]); + } + } + + if (NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_DNS)) { + NM_CMP_RETURN(_garray_inaddr_cmp(a->wins, b->wins, AF_INET)); + NM_CMP_RETURN(_garray_inaddr_cmp(a->nis_servers, b->nis_servers, AF_INET)); + NM_CMP_DIRECT_REF_STRING(a->nis_domain, b->nis_domain); + NM_CMP_DIRECT(a->mdns, b->mdns); + NM_CMP_DIRECT(a->llmnr, b->llmnr); + NM_CMP_DIRECT(a->dns_over_tls, b->dns_over_tls); + } + + if (NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_OTHER)) { + NM_CMP_DIRECT(a->flags, b->flags); + NM_CMP_DIRECT(a->ip6_token.id, b->ip6_token.id); + NM_CMP_DIRECT(a->mtu, b->mtu); + NM_CMP_DIRECT(a->ip6_mtu, b->ip6_mtu); + NM_CMP_DIRECT_UNSAFE(a->metered, b->metered); + NM_CMP_DIRECT_UNSAFE(a->proxy_browser_only, b->proxy_browser_only); + NM_CMP_DIRECT_UNSAFE(a->proxy_method, b->proxy_method); + NM_CMP_DIRECT_REF_STRING(a->proxy_pac_url, b->proxy_pac_url); + NM_CMP_DIRECT_REF_STRING(a->proxy_pac_script, b->proxy_pac_script); + NM_CMP_DIRECT_UNSAFE(a->ip6_privacy, b->ip6_privacy); + + NM_CMP_DIRECT_UNSAFE(a->ndisc_hop_limit_set, b->ndisc_hop_limit_set); + if (a->ndisc_hop_limit_set) + NM_CMP_DIRECT(a->ndisc_hop_limit_val, b->ndisc_hop_limit_val); + + NM_CMP_DIRECT_UNSAFE(a->ndisc_reachable_time_msec_set, b->ndisc_reachable_time_msec_set); + if (a->ndisc_reachable_time_msec_set) + NM_CMP_DIRECT(a->ndisc_reachable_time_msec_val, b->ndisc_reachable_time_msec_val); + + NM_CMP_DIRECT_UNSAFE(a->ndisc_retrans_timer_msec_set, b->ndisc_retrans_timer_msec_set); + if (a->ndisc_retrans_timer_msec_set) + NM_CMP_DIRECT(a->ndisc_retrans_timer_msec_val, b->ndisc_retrans_timer_msec_val); + + NM_CMP_FIELD(a, b, source); + } /* these fields are not considered by cmp(): * @@ -2167,9 +2370,9 @@ _data_get_direct_route_for_host(const NML3ConfigData *self, guint32 route_table) { const int IS_IPv4 = NM_IS_IPv4(addr_family); - const NMPObject * best_route_obj = NULL; + const NMPObject *best_route_obj = NULL; const NMPlatformIPXRoute *best_route = NULL; - const NMPObject * item_obj; + const NMPObject *item_obj; NMDedupMultiIter ipconf_iter; nm_assert(_NM_IS_L3_CONFIG_DATA(self, TRUE)); @@ -2230,7 +2433,7 @@ GPtrArray * nm_l3_config_data_get_blacklisted_ip4_routes(const NML3ConfigData *self, gboolean is_vrf) { gs_unref_ptrarray GPtrArray *ip4_dev_route_blacklist = NULL; - const NMPObject * my_addr_obj; + const NMPObject *my_addr_obj; NMDedupMultiIter iter; nm_assert(_NM_IS_L3_CONFIG_DATA(self, TRUE)); @@ -2295,7 +2498,7 @@ void nm_l3_config_data_add_dependent_onlink_routes(NML3ConfigData *self, int addr_family) { gs_unref_ptrarray GPtrArray *extra_onlink_routes = NULL; - const NMPObject * obj_src; + const NMPObject *obj_src; NMDedupMultiIter iter; int IS_IPv4; guint i; @@ -2316,16 +2519,17 @@ nm_l3_config_data_add_dependent_onlink_routes(NML3ConfigData *self, int addr_fam nm_l3_config_data_iter_obj_for_each (&iter, self, &obj_src, NMP_OBJECT_TYPE_IP_ROUTE(IS_IPv4)) { const NMPlatformIPXRoute *route_src = NMP_OBJECT_CAST_IPX_ROUTE(obj_src); - NMPObject * new_route; - NMPlatformIPXRoute * new_r; - const NMIPAddr * p_gateway; + NMPObject *new_route; + NMPlatformIPXRoute *new_r; + const NMIPAddr *p_gateway; p_gateway = nm_platform_ip_route_get_gateway(addr_family, &route_src->rx); if (nm_ip_addr_is_null(addr_family, p_gateway)) continue; - if (_data_get_direct_route_for_host( + if (!NM_PLATFORM_IP_ROUTE_IS_DEFAULT(route_src) + || _data_get_direct_route_for_host( self, addr_family, p_gateway, @@ -2363,14 +2567,15 @@ nm_l3_config_data_add_dependent_onlink_routes(NML3ConfigData *self, int addr_fam } void -nm_l3_config_data_add_dependent_device_routes(NML3ConfigData * self, +nm_l3_config_data_add_dependent_device_routes(NML3ConfigData *self, int addr_family, guint32 route_table, guint32 route_metric, + gboolean force_commit, const NML3ConfigData *source) { const int IS_IPv4 = NM_IS_IPv4(addr_family); - const NMPObject * obj_src; + const NMPObject *obj_src; NMPlatformIPXRoute rx; NMDedupMultiIter iter; @@ -2393,7 +2598,7 @@ nm_l3_config_data_add_dependent_device_routes(NML3ConfigData * self, &obj_src, NMP_OBJECT_TYPE_IP_ADDRESS(IS_IPv4)) { const NMPlatformIPXAddress *const addr_src = NMP_OBJECT_CAST_IPX_ADDRESS(obj_src); - const NMPlatformIPXAddress * addr_dst; + const NMPlatformIPXAddress *addr_dst; addr_dst = NMP_OBJECT_CAST_IPX_ADDRESS( nm_dedup_multi_entry_get_obj(nm_l3_config_data_lookup_obj(self, obj_src))); @@ -2411,6 +2616,7 @@ nm_l3_config_data_add_dependent_device_routes(NML3ConfigData * self, self->ifindex, route_table, route_metric, + force_commit, &r_stack.r4); if (r) nm_l3_config_data_add_route(self, addr_family, NULL, r); @@ -2449,13 +2655,15 @@ nm_l3_config_data_add_dependent_device_routes(NML3ConfigData * self, } rx.r6 = (NMPlatformIP6Route){ - .ifindex = self->ifindex, - .rt_source = NM_IP_CONFIG_SOURCE_KERNEL, - .table_coerced = nm_platform_route_table_coerce(route_table), - .metric = route_metric, - .network = *a6, - .plen = plen, + .ifindex = self->ifindex, + .rt_source = NM_IP_CONFIG_SOURCE_KERNEL, + .table_coerced = nm_platform_route_table_coerce(route_table), + .metric = route_metric, + .network = *a6, + .plen = plen, + .r_force_commit = force_commit, }; + nm_platform_ip_route_normalize(addr_family, &rx.rx); nm_l3_config_data_add_route(self, addr_family, NULL, &rx.rx); } @@ -2475,7 +2683,7 @@ _init_from_connection_ip(NML3ConfigData *self, int addr_family, NMConnection *co guint nroutes; guint nnameservers; guint nsearches; - const char * gateway_str; + const char *gateway_str; NMIPAddr gateway_bin; guint i; int idx; @@ -2521,10 +2729,10 @@ _init_from_connection_ip(NML3ConfigData *self, int addr_family, NMConnection *co naddresses = nm_setting_ip_config_get_num_addresses(s_ip); for (i = 0; i < naddresses; i++) { - NMIPAddress * s_addr = nm_setting_ip_config_get_address(s_ip, i); + NMIPAddress *s_addr = nm_setting_ip_config_get_address(s_ip, i); NMPlatformIPXAddress a; NMIPAddr addr_bin; - GVariant * label; + GVariant *label; nm_assert(nm_ip_address_get_family(s_addr) == addr_family); @@ -2561,7 +2769,7 @@ _init_from_connection_ip(NML3ConfigData *self, int addr_family, NMConnection *co nroutes = nm_setting_ip_config_get_num_routes(s_ip); for (i = 0; i < nroutes; i++) { - NMIPRoute * s_route = nm_setting_ip_config_get_route(s_ip, i); + NMIPRoute *s_route = nm_setting_ip_config_get_route(s_ip, i); NMPlatformIPXRoute r; NMIPAddr network_bin; NMIPAddr next_hop_bin; @@ -2656,7 +2864,7 @@ _init_from_connection_ip(NML3ConfigData *self, int addr_family, NMConnection *co NML3ConfigData * nm_l3_config_data_new_from_connection(NMDedupMultiIndex *multi_idx, int ifindex, - NMConnection * connection) + NMConnection *connection) { NML3ConfigData *self; NMSettingProxy *s_proxy; @@ -2716,14 +2924,14 @@ sort_captured_addresses_6(const CList *lst_a, const CList *lst_b, gconstpointer } static void -_init_from_platform(NML3ConfigData * self, +_init_from_platform(NML3ConfigData *self, int addr_family, - NMPlatform * platform, + NMPlatform *platform, NMSettingIP6ConfigPrivacy ipv6_privacy_rfc4941) { const int IS_IPv4 = NM_IS_IPv4(addr_family); const NMDedupMultiHeadEntry *head_entry; - const NMPObject * plobj = NULL; + const NMPObject *plobj = NULL; NMDedupMultiIter iter; nm_assert(_NM_IS_L3_CONFIG_DATA(self, FALSE)); @@ -2766,9 +2974,9 @@ _init_from_platform(NML3ConfigData * self, } NML3ConfigData * -nm_l3_config_data_new_from_platform(NMDedupMultiIndex * multi_idx, +nm_l3_config_data_new_from_platform(NMDedupMultiIndex *multi_idx, int ifindex, - NMPlatform * platform, + NMPlatform *platform, NMSettingIP6ConfigPrivacy ipv6_privacy_rfc4941) { NML3ConfigData *self; @@ -2791,31 +2999,39 @@ nm_l3_config_data_new_from_platform(NMDedupMultiIndex * multi_idx, /*****************************************************************************/ void -nm_l3_config_data_merge(NML3ConfigData * self, +nm_l3_config_data_merge(NML3ConfigData *self, const NML3ConfigData *src, NML3ConfigMergeFlags merge_flags, - const guint32 * default_route_table_x /* length 2, for IS_IPv4 */, - const guint32 * default_route_metric_x /* length 2, for IS_IPv4 */, - const guint32 * default_route_penalty_x /* length 2, for IS_IPv4 */, - const int * default_dns_priority_x /* length 2, for IS_IPv4 */, + const guint32 *default_route_table_x /* length 2, for IS_IPv4 */, + const guint32 *default_route_metric_x /* length 2, for IS_IPv4 */, + const guint32 *default_route_penalty_x /* length 2, for IS_IPv4 */, + const int *default_dns_priority_x /* length 2, for IS_IPv4 */, NML3ConfigMergeHookAddObj hook_add_obj, gpointer hook_user_data) { - static const guint32 x_default_route_table_x[2] = {RT_TABLE_MAIN, RT_TABLE_MAIN}; static const guint32 x_default_route_metric_x[2] = {NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP6, NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP4}; static const guint32 x_default_route_penalty_x[2] = {0, 0}; static const int x_default_dns_priority_x[2] = {NM_DNS_PRIORITY_DEFAULT_NORMAL, NM_DNS_PRIORITY_DEFAULT_NORMAL}; + guint32 default_route_table_coerced_x[2]; NMDedupMultiIter iter; - const NMPObject * obj; + const NMPObject *obj; int IS_IPv4; nm_assert(_NM_IS_L3_CONFIG_DATA(self, FALSE)); nm_assert(_NM_IS_L3_CONFIG_DATA(src, TRUE)); - if (!default_route_table_x) - default_route_table_x = x_default_route_table_x; + if (default_route_table_x) { + default_route_table_coerced_x[0] = nm_platform_route_table_coerce(default_route_table_x[0]); + default_route_table_coerced_x[1] = nm_platform_route_table_coerce(default_route_table_x[1]); + } else { + default_route_table_coerced_x[0] = nm_platform_route_table_coerce(RT_TABLE_MAIN); + default_route_table_coerced_x[1] = nm_platform_route_table_coerce(RT_TABLE_MAIN); + } + nm_assert(nm_platform_route_table_uncoerce(default_route_table_coerced_x[0], FALSE) != 0); + nm_assert(nm_platform_route_table_uncoerce(default_route_table_coerced_x[1], FALSE) != 0); + if (!default_route_metric_x) default_route_metric_x = x_default_route_metric_x; if (!default_route_penalty_x) @@ -2823,8 +3039,6 @@ nm_l3_config_data_merge(NML3ConfigData * self, if (!default_dns_priority_x) default_dns_priority_x = x_default_dns_priority_x; - nm_assert(default_route_table_x[0] != 0); - nm_assert(default_route_table_x[1] != 0); nm_assert(default_route_metric_x[0] != 0); /* IPv6 route metric cannot be zero. */ nm_assert(!NM_FLAGS_HAS(merge_flags, NM_L3_CONFIG_MERGE_FLAGS_CLONE) @@ -2842,8 +3056,9 @@ nm_l3_config_data_merge(NML3ConfigData * self, const NMPlatformIPAddress *a_src = NMP_OBJECT_CAST_IP_ADDRESS(obj); NMPlatformIPXAddress a; NML3ConfigMergeHookResult hook_result = { - .ip4acd_not_ready = NM_OPTION_BOOL_DEFAULT, - .assume_config_once = NM_OPTION_BOOL_DEFAULT, + .ip4acd_not_ready = NM_OPTION_BOOL_DEFAULT, + .assume_config_once = NM_OPTION_BOOL_DEFAULT, + .force_commit = NM_OPTION_BOOL_DEFAULT, }; #define _ensure_a() \ @@ -2882,6 +3097,12 @@ nm_l3_config_data_merge(NML3ConfigData * self, a.ax.a_assume_config_once = (!!hook_result.assume_config_once); } + if (hook_result.force_commit != NM_OPTION_BOOL_DEFAULT + && (!!hook_result.force_commit) != a_src->a_force_commit) { + _ensure_a(); + a.ax.a_force_commit = (!!hook_result.force_commit); + } + nm_l3_config_data_add_address_full(self, addr_family, a_src == &a.ax ? NULL : obj, @@ -2897,11 +3118,12 @@ nm_l3_config_data_merge(NML3ConfigData * self, src, &obj, NMP_OBJECT_TYPE_IP_ROUTE(IS_IPv4)) { - const NMPlatformIPRoute * r_src = NMP_OBJECT_CAST_IP_ROUTE(obj); + const NMPlatformIPRoute *r_src = NMP_OBJECT_CAST_IP_ROUTE(obj); NMPlatformIPXRoute r; NML3ConfigMergeHookResult hook_result = { .ip4acd_not_ready = NM_OPTION_BOOL_DEFAULT, .assume_config_once = NM_OPTION_BOOL_DEFAULT, + .force_commit = NM_OPTION_BOOL_DEFAULT, }; #define _ensure_r() \ @@ -2933,11 +3155,17 @@ nm_l3_config_data_merge(NML3ConfigData * self, r.rx.r_assume_config_once = (!!hook_result.assume_config_once); } + if (hook_result.force_commit != NM_OPTION_BOOL_DEFAULT + && (!!hook_result.force_commit) != r_src->r_force_commit) { + _ensure_r(); + r.rx.r_force_commit = (!!hook_result.force_commit); + } + if (!NM_FLAGS_HAS(merge_flags, NM_L3_CONFIG_MERGE_FLAGS_CLONE)) { if (r_src->table_any) { _ensure_r(); r.rx.table_any = FALSE; - r.rx.table_coerced = default_route_table_x[IS_IPv4]; + r.rx.table_coerced = default_route_table_coerced_x[IS_IPv4]; } if (r_src->metric_any) { @@ -3019,6 +3247,12 @@ nm_l3_config_data_merge(NML3ConfigData * self, if (self->llmnr == NM_SETTING_CONNECTION_LLMNR_DEFAULT) self->llmnr = src->llmnr; + if (self->dns_over_tls == NM_SETTING_CONNECTION_DNS_OVER_TLS_DEFAULT) + self->dns_over_tls = src->dns_over_tls; + + if (self->ip6_token.id == 0) + self->ip6_token.id = src->ip6_token.id; + self->metered = NM_MAX((NMTernary) self->metered, (NMTernary) src->metered); if (self->proxy_method == NM_PROXY_CONFIG_METHOD_UNKNOWN) @@ -3095,9 +3329,10 @@ nm_l3_config_data_new_clone(const NML3ConfigData *src, int ifindex) nm_assert(nm_l3_config_data_cmp_full(src, self, - src->ifindex != ifindex - ? NM_L3_CONFIG_CMP_FLAGS_IGNORE_IFINDEX - : NM_L3_CONFIG_CMP_FLAGS_NONE) + src->ifindex == ifindex + ? NM_L3_CONFIG_CMP_FLAGS_ALL + : NM_L3_CONFIG_CMP_FLAGS_ALL + & ~(NM_L3_CONFIG_CMP_FLAGS_IFINDEX)) == 0); nm_assert(nm_l3_config_data_get_ifindex(self) == ifindex); |