diff options
Diffstat (limited to 'src/libnm-platform/nm-platform.c')
| -rw-r--r-- | src/libnm-platform/nm-platform.c | 696 |
1 files changed, 596 insertions, 100 deletions
diff --git a/src/libnm-platform/nm-platform.c b/src/libnm-platform/nm-platform.c index 090af26d..df177485 100644 --- a/src/libnm-platform/nm-platform.c +++ b/src/libnm-platform/nm-platform.c @@ -7,6 +7,8 @@ #include "nm-platform.h" +#include "libnm-std-aux/nm-linux-compat.h" + #include <stdlib.h> #include <unistd.h> #include <netinet/in.h> @@ -113,24 +115,29 @@ nmp_link_address_get_as_bytes(const NMPLinkAddress *addr) #define _NMLOG_DOMAIN LOGD_PLATFORM #define _NMLOG_PREFIX_NAME "platform" -#define NMLOG_COMMON(level, name, ...) \ - char __prefix[32]; \ - const char *__p_prefix = _NMLOG_PREFIX_NAME; \ - const NMPlatform *const __self = (self); \ - const char *__name = name; \ - \ - if (__self && NM_PLATFORM_GET_PRIVATE(__self)->log_with_ptr) { \ - g_snprintf(__prefix, sizeof(__prefix), "%s[%p]", _NMLOG_PREFIX_NAME, __self); \ - __p_prefix = __prefix; \ - } \ - _nm_log(__level, \ - _NMLOG_DOMAIN, \ - 0, \ - __name, \ - NULL, \ - "%s: %s%s%s" _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ - __p_prefix, \ - NM_PRINT_FMT_QUOTED(__name, "(", __name, ") ", "") _NM_UTILS_MACRO_REST(__VA_ARGS__)); +#define NMLOG_COMMON(level, name, ...) \ + G_STMT_START \ + { \ + char __prefix[32]; \ + const char *__p_prefix = _NMLOG_PREFIX_NAME; \ + const NMPlatform *const __self = (self); \ + const char *__name = name; \ + \ + if (__self && NM_PLATFORM_GET_PRIVATE(__self)->log_with_ptr) { \ + g_snprintf(__prefix, sizeof(__prefix), "%s[%p]", _NMLOG_PREFIX_NAME, __self); \ + __p_prefix = __prefix; \ + } \ + _nm_log((level), \ + _NMLOG_DOMAIN, \ + 0, \ + __name, \ + NULL, \ + "%s: %s%s%s" _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + __p_prefix, \ + NM_PRINT_FMT_QUOTED(__name, "(", __name, ") ", "") \ + _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + G_STMT_END #define _NMLOG(level, ...) \ G_STMT_START \ @@ -395,6 +402,76 @@ _nm_platform_kernel_support_init(NMPlatformKernelSupportType type, int value) /*****************************************************************************/ +const NMPGenlFamilyInfo nmp_genl_family_infos[_NMP_GENL_FAMILY_TYPE_NUM] = { + [NMP_GENL_FAMILY_TYPE_ETHTOOL] = + { + .name = "ethtool", + }, + [NMP_GENL_FAMILY_TYPE_MPTCP_PM] = + { + .name = MPTCP_PM_NAME, + }, + [NMP_GENL_FAMILY_TYPE_NL80211] = + { + .name = "nl80211", + }, + [NMP_GENL_FAMILY_TYPE_NL802154] = + { + .name = "nl802154", + }, + [NMP_GENL_FAMILY_TYPE_WIREGUARD] = + { + .name = "wireguard", + }, +}; + +NMPGenlFamilyType +nmp_genl_family_type_from_name(const char *name) +{ + int imin, imax, imid; + + if (NM_MORE_ASSERT_ONCE(50)) { + int i; + + for (i = 0; i < (int) G_N_ELEMENTS(nmp_genl_family_infos); i++) { + nm_assert(nmp_genl_family_infos[i].name); + if (i > 0) + nm_assert(strcmp(nmp_genl_family_infos[i - 1].name, nmp_genl_family_infos[i].name) + < 0); + } + } + + if (!name) + goto out; + + imin = 0; + imax = G_N_ELEMENTS(nmp_genl_family_infos) - 1; + imid = imax / 2; + + while (TRUE) { + int c; + + c = strcmp(nmp_genl_family_infos[imid].name, name); + if (c == 0) + return (NMPGenlFamilyType) imid; + + if (c < 0) + imin = imid + 1; + else + imax = imid - 1; + + if (imin > imax) + break; + + imid = (imax + imin) / 2; + } + +out: + return _NMP_GENL_FAMILY_TYPE_NONE; +} + +/*****************************************************************************/ + /** * nm_platform_process_events: * @self: platform instance @@ -1292,6 +1369,12 @@ nm_platform_link_add(NMPlatform *self, buf_p, buf_len); break; + case NM_LINK_TYPE_BOND: + nm_strbuf_append_str(&buf_p, &buf_len, ", "); + nm_platform_lnk_bond_to_string((const NMPlatformLnkBond *) extra_data, + buf_p, + buf_len); + break; default: nm_assert(!extra_data); break; @@ -1332,6 +1415,12 @@ nm_platform_link_change(NMPlatform *self, NMLinkType type, int ifindex, gconstpo buf_p, buf_len); break; + case NM_LINK_TYPE_BOND: + nm_strbuf_append_str(&buf_p, &buf_len, ", "); + nm_platform_lnk_bond_to_string((const NMPlatformLnkBond *) extra_data, + buf_p, + buf_len); + break; default: nm_assert(!extra_data); break; @@ -2232,6 +2321,12 @@ _link_get_lnk(NMPlatform *self, int ifindex, NMLinkType link_type, const NMPlatf return lnk ? &lnk->object : NULL; } +const NMPlatformLnkBond * +nm_platform_link_get_lnk_bond(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) +{ + return _link_get_lnk(self, ifindex, NM_LINK_TYPE_BOND, out_link); +} + const NMPlatformLnkBridge * nm_platform_link_get_lnk_bridge(NMPlatform *self, int ifindex, const NMPlatformLink **out_link) { @@ -4133,7 +4228,7 @@ nm_platform_ip_address_sync(NMPlatform *self, * we check the "secondary" flag. */ plat_addresses = nm_platform_lookup_clone( self, - nmp_lookup_init_object(&lookup, NMP_OBJECT_TYPE_IP_ADDRESS(IS_IPv4), ifindex), + nmp_lookup_init_object_by_ifindex(&lookup, NMP_OBJECT_TYPE_IP_ADDRESS(IS_IPv4), ifindex), NULL, NULL); @@ -4436,18 +4531,20 @@ next_plat:; nm_platform_ip4_broadcast_address_from_addr(&known_address->a4), lifetime, preferred, - IFA_F_NOPREFIXROUTE, + known_address->ax.a_no_auto_noprefixroute ? 0 : IFA_F_NOPREFIXROUTE, known_address->a4.label)) success = FALSE; } else { - if (!nm_platform_ip6_address_add(self, - ifindex, - known_address->a6.address, - known_address->a6.plen, - known_address->a6.peer_address, - lifetime, - preferred, - IFA_F_NOPREFIXROUTE | known_address->a6.n_ifa_flags)) + if (!nm_platform_ip6_address_add( + self, + ifindex, + known_address->a6.address, + known_address->a6.plen, + known_address->a6.peer_address, + lifetime, + preferred, + (known_address->ax.a_no_auto_noprefixroute ? 0 : IFA_F_NOPREFIXROUTE) + | known_address->a6.n_ifa_flags)) success = FALSE; } } @@ -4545,7 +4642,9 @@ nm_platform_ip_address_get_prune_list(NMPlatform *self, GPtrArray *result = NULL; CList *iter; - nmp_lookup_init_object(&lookup, NMP_OBJECT_TYPE_IP_ADDRESS(NM_IS_IPv4(addr_family)), ifindex); + nmp_lookup_init_object_by_ifindex(&lookup, + NMP_OBJECT_TYPE_IP_ADDRESS(NM_IS_IPv4(addr_family)), + ifindex); head_entry = nm_platform_lookup(self, &lookup); @@ -4626,7 +4725,9 @@ nm_platform_ip_route_get_prune_list(NMPlatform *self, NM_IP_ROUTE_TABLE_SYNC_MODE_ALL, NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_PRUNE)); - nmp_lookup_init_object(&lookup, NMP_OBJECT_TYPE_IP_ROUTE(NM_IS_IPv4(addr_family)), ifindex); + nmp_lookup_init_object_by_ifindex(&lookup, + NMP_OBJECT_TYPE_IP_ROUTE(NM_IS_IPv4(addr_family)), + ifindex); head_entry = nm_platform_lookup(self, &lookup); if (!head_entry) return NULL; @@ -5226,23 +5327,26 @@ nm_platform_object_delete(NMPlatform *self, const NMPObject *obj) _CHECK_SELF(self, klass, FALSE); - switch (NMP_OBJECT_GET_TYPE(obj)) { - case NMP_OBJECT_TYPE_ROUTING_RULE: - _LOGD("%s: delete %s", - NMP_OBJECT_GET_CLASS(obj)->obj_type_name, - nmp_object_to_string(obj, NMP_OBJECT_TO_STRING_PUBLIC, sbuf, sizeof(sbuf))); - break; - case NMP_OBJECT_TYPE_IP4_ROUTE: - case NMP_OBJECT_TYPE_IP6_ROUTE: - case NMP_OBJECT_TYPE_QDISC: - case NMP_OBJECT_TYPE_TFILTER: - ifindex = NMP_OBJECT_CAST_OBJ_WITH_IFINDEX(obj)->ifindex; - _LOG3D("%s: delete %s", - NMP_OBJECT_GET_CLASS(obj)->obj_type_name, - nmp_object_to_string(obj, NMP_OBJECT_TO_STRING_PUBLIC, sbuf, sizeof(sbuf))); - break; - default: - g_return_val_if_reached(FALSE); + if (_LOGD_ENABLED()) { + switch (NMP_OBJECT_GET_TYPE(obj)) { + case NMP_OBJECT_TYPE_ROUTING_RULE: + case NMP_OBJECT_TYPE_MPTCP_ADDR: + _LOGD("%s: delete %s", + NMP_OBJECT_GET_CLASS(obj)->obj_type_name, + nmp_object_to_string(obj, NMP_OBJECT_TO_STRING_PUBLIC, sbuf, sizeof(sbuf))); + break; + case NMP_OBJECT_TYPE_IP4_ROUTE: + case NMP_OBJECT_TYPE_IP6_ROUTE: + case NMP_OBJECT_TYPE_QDISC: + case NMP_OBJECT_TYPE_TFILTER: + ifindex = NMP_OBJECT_CAST_OBJ_WITH_IFINDEX(obj)->ifindex; + _LOG3D("%s: delete %s", + NMP_OBJECT_GET_CLASS(obj)->obj_type_name, + nmp_object_to_string(obj, NMP_OBJECT_TO_STRING_PUBLIC, sbuf, sizeof(sbuf))); + break; + default: + g_return_val_if_reached(FALSE); + } } return klass->object_delete(self, obj); @@ -5972,6 +6076,123 @@ nm_platform_lnk_bridge_to_string(const NMPlatformLnkBridge *lnk, char *buf, gsiz } const char * +nm_platform_lnk_bond_to_string(const NMPlatformLnkBond *lnk, char *buf, gsize len) +{ + char sbuf_miimon[30]; + char sbuf_updelay[30]; + char sbuf_downdelay[30]; + char sbuf_peer_notif_delay[60]; + char sbuf_arp_all_targets[30]; + char sbuf_resend_igmp[30]; + char sbuf_lp_interval[30]; + char sbuf_tlb_dynamic_lb[30]; + int i; + + if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len)) + return buf; + + nm_strbuf_append( + &buf, + &len, + "bond" + " mode %u" + " primary %u" + "%s" /* miimon */ + "%s" /* updelay */ + "%s" /* downdelay */ + " arp_interval %u" + "%s" /* resend_igmp */ + " min_links %u" + "%s" /* lp_interval */ + " packets_per_port %u" + "%s" /* peer_notif_delay */ + "%s" /* arp_all_targets */ + " arp_validate %u" + " ad_actor_sys_prio %u" + " ad_user_port_key %u" + " ad_actor_system " NM_ETHER_ADDR_FORMAT_STR "" + " primary_reselect %u" + " fail_over_mac %u" + " xmit_hash_policy %u" + " num_gray_arp %u" + " all_ports_active %u" + " lacp_rate %u" + " ad_select %u" + " use_carrier %d" + "%s" /* tlb_dynamic_lb */, + lnk->mode, + lnk->primary, + lnk->miimon_has || lnk->miimon != 0 + ? nm_sprintf_buf(sbuf_miimon, " miimon%s %u", !lnk->miimon_has ? "?" : "", lnk->miimon) + : "", + lnk->updelay_has || lnk->updelay != 0 ? nm_sprintf_buf(sbuf_updelay, + " updelay%s %u", + !lnk->updelay_has ? "?" : "", + lnk->updelay) + : "", + lnk->downdelay_has || lnk->downdelay != 0 ? nm_sprintf_buf(sbuf_downdelay, + " downdelay%s %u", + !lnk->downdelay_has ? "?" : "", + lnk->downdelay) + : "", + lnk->arp_interval, + lnk->resend_igmp_has || lnk->resend_igmp != 0 + ? nm_sprintf_buf(sbuf_resend_igmp, + " resend_igmp%s %u", + !lnk->resend_igmp_has ? "?" : "", + lnk->resend_igmp) + : "", + lnk->min_links, + lnk->lp_interval_has || lnk->lp_interval != 1 + ? nm_sprintf_buf(sbuf_lp_interval, + " lp_interval%s %u", + !lnk->lp_interval_has ? "?" : "", + lnk->lp_interval) + : "", + lnk->packets_per_port, + lnk->peer_notif_delay_has || lnk->peer_notif_delay != 0 + ? nm_sprintf_buf(sbuf_peer_notif_delay, + " peer_notif_delay%s %u", + !lnk->peer_notif_delay_has ? "?" : "", + lnk->peer_notif_delay) + : "", + lnk->arp_all_targets_has || lnk->arp_all_targets != 0 + ? nm_sprintf_buf(sbuf_arp_all_targets, + " arp_all_targets%s %u", + !lnk->arp_all_targets_has ? "?" : "", + lnk->arp_all_targets) + : "", + lnk->arp_validate, + lnk->ad_actor_sys_prio, + lnk->ad_user_port_key, + NM_ETHER_ADDR_FORMAT_VAL(&lnk->ad_actor_system), + lnk->primary_reselect, + lnk->fail_over_mac, + lnk->xmit_hash_policy, + lnk->num_grat_arp, + lnk->all_ports_active, + lnk->lacp_rate, + lnk->ad_select, + (int) lnk->use_carrier, + lnk->tlb_dynamic_lb_has ? nm_sprintf_buf(sbuf_tlb_dynamic_lb, + " tlb_dynamic_lb%s %u", + !lnk->tlb_dynamic_lb_has ? "?" : "", + (int) lnk->tlb_dynamic_lb) + : ""); + + if (lnk->arp_ip_targets_num > 0) { + nm_strbuf_append_str(&buf, &len, " arp_ip_target"); + for (i = 0; i < lnk->arp_ip_targets_num; i++) { + char target[INET_ADDRSTRLEN]; + + nm_strbuf_append_c(&buf, &len, ' '); + nm_strbuf_append_str(&buf, &len, _nm_utils_inet4_ntop(lnk->arp_ip_target[i], target)); + } + } + return buf; +} + +const char * nm_platform_lnk_gre_to_string(const NMPlatformLnkGre *lnk, char *buf, gsize len) { char str_local[30]; @@ -6580,6 +6801,7 @@ nm_platform_ip4_address_to_string(const NMPlatformIP4Address *address, char *buf " src %s" "%s" /* a_acd_not_ready */ "%s" /* a_force_commit */ + "%s" /* a_no_auto_noprefixroute */ "", s_address, address->plen, @@ -6598,7 +6820,8 @@ nm_platform_ip4_address_to_string(const NMPlatformIP4Address *address, char *buf str_label, nmp_utils_ip_config_source_to_string(address->addr_source, s_source, sizeof(s_source)), address->a_acd_not_ready ? " ip4acd-not-ready" : "", - address->a_force_commit ? " force-commit" : ""); + address->a_force_commit ? " force-commit" : "", + address->a_no_auto_noprefixroute ? " no-auto-noprefixroute" : ""); g_free(str_peer); return buf; } @@ -6719,6 +6942,7 @@ nm_platform_ip6_address_to_string(const NMPlatformIP6Address *address, char *buf len, "%s/%d lft %s pref %s%s%s%s%s src %s" "%s" /* a_force_commit */ + "%s" /* a_no_auto_noprefixroute */ "", s_address, address->plen, @@ -6729,7 +6953,8 @@ nm_platform_ip6_address_to_string(const NMPlatformIP6Address *address, char *buf str_dev, _to_string_ifa_flags(address->n_ifa_flags, s_flags, sizeof(s_flags)), nmp_utils_ip_config_source_to_string(address->addr_source, s_source, sizeof(s_source)), - address->a_force_commit ? " force-commit" : ""); + address->a_force_commit ? " force-commit" : "", + address->a_no_auto_noprefixroute ? " no-auto-noprefixroute" : ""); g_free(str_peer); return buf; } @@ -6787,6 +7012,7 @@ nm_platform_ip4_route_to_string(const NMPlatformIP4Route *route, char *buf, gsiz char s_gateway[INET_ADDRSTRLEN]; char s_pref_src[INET_ADDRSTRLEN]; char str_dev[TO_STRING_DEV_BUF_SIZE]; + char str_mss[32]; char str_table[30]; char str_scope[30]; char s_source[50]; @@ -6795,6 +7021,7 @@ nm_platform_ip4_route_to_string(const NMPlatformIP4Route *route, char *buf, gsiz char str_cwnd[32]; char str_initcwnd[32]; char str_initrwnd[32]; + char str_rto_min[32]; char str_mtu[32]; char str_rtm_flags[_RTM_FLAGS_TO_STRING_MAXLEN]; char str_type[30]; @@ -6821,18 +7048,20 @@ nm_platform_ip4_route_to_string(const NMPlatformIP4Route *route, char *buf, gsiz "%s%s" /* gateway */ "%s" " metric %s" - " mss %" G_GUINT32_FORMAT /* mss */ - " rt-src %s" /* protocol */ - "%s" /* rtm_flags */ - "%s%s" /* scope */ - "%s%s" /* pref-src */ - "%s" /* tos */ - "%s" /* window */ - "%s" /* cwnd */ - "%s" /* initcwnd */ - "%s" /* initrwnd */ - "%s" /* mtu */ - "%s" /* r_force_commit */ + "%s" /* mss */ + " rt-src %s" /* protocol */ + "%s" /* rtm_flags */ + "%s%s" /* scope */ + "%s%s" /* pref-src */ + "%s" /* tos */ + "%s" /* window */ + "%s" /* cwnd */ + "%s" /* initcwnd */ + "%s" /* initrwnd */ + "%s" /* rto_min */ + "%s" /* quickack */ + "%s" /* mtu */ + "%s" /* r_force_commit */ "", nm_net_aux_rtnl_rtntype_n2a_maybe_buf(nm_platform_route_type_uncoerce(route->type_coerced), str_type), @@ -6851,7 +7080,10 @@ nm_platform_ip4_route_to_string(const NMPlatformIP4Route *route, char *buf, gsiz route->metric_any ? (route->metric ? nm_sprintf_buf(str_metric, "??+%u", route->metric) : "??") : nm_sprintf_buf(str_metric, "%u", route->metric), - route->mss, + nm_sprintf_buf(str_mss, + " mss %s%" G_GUINT32_FORMAT, + route->lock_mss ? "lock " : "", + route->mss), nmp_utils_ip_config_source_to_string(route->rt_source, s_source, sizeof(s_source)), _rtm_flags_to_string_full(str_rtm_flags, sizeof(str_rtm_flags), route->r_rtm_flags), route->scope_inv ? " scope " : "", @@ -6885,6 +7117,9 @@ nm_platform_ip4_route_to_string(const NMPlatformIP4Route *route, char *buf, gsiz route->lock_initrwnd ? "lock " : "", route->initrwnd) : "", + route->rto_min ? nm_sprintf_buf(str_rto_min, " rto_min %" G_GUINT32_FORMAT, route->rto_min) + : "", + route->quickack ? " quickack 1" : "", route->mtu || route->lock_mtu ? nm_sprintf_buf(str_mtu, " mtu %s%" G_GUINT32_FORMAT, route->lock_mtu ? "lock " : "", @@ -6919,11 +7154,13 @@ nm_platform_ip6_route_to_string(const NMPlatformIP6Route *route, char *buf, gsiz char str_pref[40]; char str_pref2[30]; char str_dev[TO_STRING_DEV_BUF_SIZE]; + char str_mss[32]; char s_source[50]; char str_window[32]; char str_cwnd[32]; char str_initcwnd[32]; char str_initrwnd[32]; + char str_rto_min[32]; char str_mtu[32]; char str_rtm_flags[_RTM_FLAGS_TO_STRING_MAXLEN]; char str_metric[30]; @@ -6954,18 +7191,20 @@ nm_platform_ip6_route_to_string(const NMPlatformIP6Route *route, char *buf, gsiz "%s%s" /* gateway */ "%s" " metric %s" - " mss %" G_GUINT32_FORMAT /* mss */ - " rt-src %s" /* protocol */ - "%s" /* source */ - "%s" /* rtm_flags */ - "%s%s" /* pref-src */ - "%s" /* window */ - "%s" /* cwnd */ - "%s" /* initcwnd */ - "%s" /* initrwnd */ - "%s" /* mtu */ - "%s" /* pref */ - "%s" /* r_force_commit */ + "%s" /* mss */ + " rt-src %s" /* protocol */ + "%s" /* source */ + "%s" /* rtm_flags */ + "%s%s" /* pref-src */ + "%s" /* window */ + "%s" /* cwnd */ + "%s" /* initcwnd */ + "%s" /* initrwnd */ + "%s" /* rto_min */ + "%s" /* quickack */ + "%s" /* mtu */ + "%s" /* pref */ + "%s" /* r_force_commit */ "", nm_net_aux_rtnl_rtntype_n2a_maybe_buf(nm_platform_route_type_uncoerce(route->type_coerced), str_type), @@ -6984,7 +7223,10 @@ nm_platform_ip6_route_to_string(const NMPlatformIP6Route *route, char *buf, gsiz route->metric_any ? (route->metric ? nm_sprintf_buf(str_metric, "??+%u", route->metric) : "??") : nm_sprintf_buf(str_metric, "%u", route->metric), - route->mss, + nm_sprintf_buf(str_mss, + " mss %s%" G_GUINT32_FORMAT, + route->lock_mss ? "lock " : "", + route->mss), nmp_utils_ip_config_source_to_string(route->rt_source, s_source, sizeof(s_source)), route->src_plen || !IN6_IS_ADDR_UNSPECIFIED(&route->src) ? nm_sprintf_buf(s_src_all, @@ -7017,6 +7259,9 @@ nm_platform_ip6_route_to_string(const NMPlatformIP6Route *route, char *buf, gsiz route->lock_initrwnd ? "lock " : "", route->initrwnd) : "", + route->rto_min ? nm_sprintf_buf(str_rto_min, " rto_min %" G_GUINT32_FORMAT, route->rto_min) + : "", + route->quickack ? " quickack 1" : "", route->mtu || route->lock_mtu ? nm_sprintf_buf(str_mtu, " mtu %s%" G_GUINT32_FORMAT, route->lock_mtu ? "lock " : "", @@ -7492,6 +7737,107 @@ nm_platform_tfilter_cmp(const NMPlatformTfilter *a, const NMPlatformTfilter *b) return 0; } +static NM_UTILS_FLAGS2STR_DEFINE(_mptcp_flags_to_string, + guint32, + NM_UTILS_FLAGS2STR(NM_MPTCP_PM_ADDR_FLAG_SIGNAL, "signal"), + NM_UTILS_FLAGS2STR(NM_MPTCP_PM_ADDR_FLAG_SUBFLOW, "subflow"), + NM_UTILS_FLAGS2STR(NM_MPTCP_PM_ADDR_FLAG_BACKUP, "backup"), + NM_UTILS_FLAGS2STR(NM_MPTCP_PM_ADDR_FLAG_FULLMESH, "fullmesh")); + +const char * +nm_platform_mptcp_addr_to_string(const NMPlatformMptcpAddr *mptcp_addr, char *buf, gsize len) +{ + char str_addr[30 + NM_UTILS_INET_ADDRSTRLEN]; + char str_port[30]; + char str_id[30]; + char str_flags[200]; + char str_flags2[30 + sizeof(str_flags)]; + char str_ifindex[30]; + + if (!nm_utils_to_string_buffer_init_null(mptcp_addr, &buf, &len)) + return buf; + + if (mptcp_addr->addr_family == 0) + nm_sprintf_buf(str_addr, "no-addr"); + else if (NM_IN_SET(mptcp_addr->addr_family, AF_INET, AF_INET6)) + nm_utils_inet_ntop(mptcp_addr->addr_family, &mptcp_addr->addr, str_addr); + else + nm_sprintf_buf(str_addr, "af %d", mptcp_addr->addr_family); + + if (mptcp_addr->flags != 0) + _mptcp_flags_to_string(mptcp_addr->flags, str_flags, sizeof(str_flags)); + else + str_flags[0] = '\0'; + + g_snprintf(buf, + len, + "%s" /* address */ + "%s" /* port */ + "%s" /* id */ + "%s" /* flags */ + "%s" /* ifindex */ + "", + str_addr, + mptcp_addr->port == 0 ? "" : nm_sprintf_buf(str_port, " port %u", mptcp_addr->port), + mptcp_addr->id == 0 ? "" : nm_sprintf_buf(str_id, " id %u", mptcp_addr->id), + str_flags[0] == '\0' ? "" : nm_sprintf_buf(str_flags2, " flags %s", str_flags), + mptcp_addr->ifindex == 0 + ? "" + : nm_sprintf_buf(str_ifindex, " ifindex %d", mptcp_addr->ifindex)); + return buf; +} + +void +nm_platform_mptcp_addr_hash_update(const NMPlatformMptcpAddr *obj, NMHashState *h) +{ + nm_assert(obj); + nm_assert_addr_family_or_unspec(obj->addr_family); + + nm_hash_update_vals(h, obj->id, obj->flags, obj->port, obj->addr_family, obj->ifindex); + if (NM_IN_SET(obj->addr_family, AF_INET, AF_INET6)) + nm_hash_update(h, &obj->addr, nm_utils_addr_family_to_size(obj->addr_family)); +} + +int +nm_platform_mptcp_addr_cmp(const NMPlatformMptcpAddr *a, const NMPlatformMptcpAddr *b) +{ + NM_CMP_SELF(a, b); + + nm_assert_addr_family_or_unspec(a->addr_family); + nm_assert_addr_family_or_unspec(b->addr_family); + + NM_CMP_FIELD(a, b, ifindex); + NM_CMP_FIELD(a, b, id); + NM_CMP_FIELD(a, b, addr_family); + if (NM_IN_SET(a->addr_family, AF_INET, AF_INET6)) + NM_CMP_FIELD_MEMCMP_LEN(a, b, addr, nm_utils_addr_family_to_size(a->addr_family)); + NM_CMP_FIELD(a, b, port); + + return 0; +} + +guint +nm_platform_mptcp_addr_index_addr_cmp(gconstpointer data) +{ + const NMPlatformMptcpAddr *mptcp_addr = data; + NMHashState h; + + nm_hash_init(&h, 1408914077u); + nm_hash_update_val(&h, mptcp_addr->addr_family); + nm_hash_update(&h, &mptcp_addr->addr, nm_utils_addr_family_to_size(mptcp_addr->addr_family)); + return nm_hash_complete(&h); +} + +gboolean +nm_platform_mptcp_addr_index_addr_equal(gconstpointer data_a, gconstpointer data_b) +{ + const NMPlatformMptcpAddr *mptcp_addr_a = data_a; + const NMPlatformMptcpAddr *mptcp_addr_b = data_b; + + return mptcp_addr_a->addr_family == mptcp_addr_b->addr_family + && nm_ip_addr_equal(mptcp_addr_a->addr_family, &mptcp_addr_a->addr, &mptcp_addr_b->addr); +} + const char * nm_platform_vf_to_string(const NMPlatformVF *vf, char *buf, gsize len) { @@ -7668,6 +8014,95 @@ nm_platform_lnk_bridge_hash_update(const NMPlatformLnkBridge *obj, NMHashState * obj->vlan_stats_enabled)); } +void +nm_platform_lnk_bond_hash_update(const NMPlatformLnkBond *obj, NMHashState *h) +{ + nm_hash_update_vals(h, + obj->arp_all_targets, + obj->arp_interval, + obj->arp_validate, + obj->downdelay, + obj->lp_interval, + obj->miimon, + obj->min_links, + obj->packets_per_port, + obj->peer_notif_delay, + obj->primary, + obj->resend_igmp, + obj->updelay, + obj->ad_actor_sys_prio, + obj->ad_user_port_key, + obj->ad_actor_system, + obj->ad_select, + obj->all_ports_active, + obj->arp_ip_targets_num, + obj->fail_over_mac, + obj->lacp_rate, + obj->num_grat_arp, + obj->mode, + obj->primary_reselect, + obj->xmit_hash_policy, + NM_HASH_COMBINE_BOOLS(guint16, + obj->arp_all_targets_has, + obj->downdelay_has, + obj->lp_interval_has, + obj->miimon_has, + obj->peer_notif_delay_has, + obj->resend_igmp_has, + obj->tlb_dynamic_lb, + obj->tlb_dynamic_lb_has, + obj->updelay_has, + obj->use_carrier)); + + nm_hash_update(h, obj->arp_ip_target, obj->arp_ip_targets_num * sizeof(obj->arp_ip_target[0])); +} + +int +nm_platform_lnk_bond_cmp(const NMPlatformLnkBond *a, const NMPlatformLnkBond *b) +{ + NM_CMP_SELF(a, b); + NM_CMP_FIELD_MEMCMP_LEN(a, + b, + arp_ip_target, + a->arp_ip_targets_num * sizeof(a->arp_ip_target[0])); + NM_CMP_FIELD(a, b, arp_all_targets); + NM_CMP_FIELD(a, b, arp_interval); + NM_CMP_FIELD(a, b, arp_validate); + NM_CMP_FIELD(a, b, downdelay); + NM_CMP_FIELD(a, b, lp_interval); + NM_CMP_FIELD(a, b, miimon); + NM_CMP_FIELD(a, b, min_links); + NM_CMP_FIELD(a, b, packets_per_port); + NM_CMP_FIELD(a, b, peer_notif_delay); + NM_CMP_FIELD(a, b, primary); + NM_CMP_FIELD(a, b, resend_igmp); + NM_CMP_FIELD(a, b, updelay); + NM_CMP_FIELD(a, b, ad_actor_sys_prio); + NM_CMP_FIELD(a, b, ad_user_port_key); + NM_CMP_FIELD_MEMCMP(a, b, ad_actor_system); + NM_CMP_FIELD(a, b, ad_select); + NM_CMP_FIELD(a, b, all_ports_active); + NM_CMP_FIELD(a, b, arp_ip_targets_num); + NM_CMP_FIELD(a, b, fail_over_mac); + NM_CMP_FIELD(a, b, lacp_rate); + NM_CMP_FIELD(a, b, num_grat_arp); + NM_CMP_FIELD(a, b, mode); + NM_CMP_FIELD(a, b, primary_reselect); + NM_CMP_FIELD(a, b, xmit_hash_policy); + NM_CMP_FIELD_BOOL(a, b, arp_all_targets_has); + NM_CMP_FIELD_BOOL(a, b, downdelay_has); + NM_CMP_FIELD_BOOL(a, b, lp_interval_has); + NM_CMP_FIELD_BOOL(a, b, miimon_has); + NM_CMP_FIELD_BOOL(a, b, peer_notif_delay_has); + NM_CMP_FIELD_BOOL(a, b, resend_igmp_has); + NM_CMP_FIELD_BOOL(a, b, tlb_dynamic_lb); + NM_CMP_FIELD_BOOL(a, b, tlb_dynamic_lb_has); + NM_CMP_FIELD_BOOL(a, b, updelay_has); + NM_CMP_FIELD_BOOL(a, b, use_carrier); + + return 0; +} + int nm_platform_lnk_bridge_cmp(const NMPlatformLnkBridge *a, const NMPlatformLnkBridge *b) { @@ -8182,7 +8617,8 @@ nm_platform_ip4_address_hash_update(const NMPlatformIP4Address *obj, NMHashState NM_HASH_COMBINE_BOOLS(guint8, obj->use_ip4_broadcast_address, obj->a_acd_not_ready, - obj->a_force_commit)); + obj->a_force_commit, + obj->a_no_auto_noprefixroute)); nm_hash_update_strarr(h, obj->label); } @@ -8231,6 +8667,7 @@ nm_platform_ip4_address_cmp(const NMPlatformIP4Address *a, NM_CMP_FIELD(a, b, broadcast_address); NM_CMP_FIELD_UNSAFE(a, b, a_acd_not_ready); NM_CMP_FIELD_UNSAFE(a, b, a_force_commit); + NM_CMP_FIELD_UNSAFE(a, b, a_no_auto_noprefixroute); } return 0; } @@ -8240,17 +8677,18 @@ nm_platform_ip4_address_cmp(const NMPlatformIP4Address *a, void nm_platform_ip6_address_hash_update(const NMPlatformIP6Address *obj, NMHashState *h) { - nm_hash_update_vals(h, - obj->ifindex, - obj->addr_source, - obj->timestamp, - obj->lifetime, - obj->preferred, - obj->n_ifa_flags, - obj->plen, - obj->address, - obj->peer_address, - NM_HASH_COMBINE_BOOLS(guint8, obj->a_force_commit)); + nm_hash_update_vals( + h, + obj->ifindex, + obj->addr_source, + obj->timestamp, + obj->lifetime, + obj->preferred, + obj->n_ifa_flags, + obj->plen, + obj->address, + obj->peer_address, + NM_HASH_COMBINE_BOOLS(guint8, obj->a_force_commit, obj->a_no_auto_noprefixroute)); } int @@ -8294,6 +8732,7 @@ nm_platform_ip6_address_cmp(const NMPlatformIP6Address *a, NM_CMP_FIELD(a, b, n_ifa_flags); NM_CMP_FIELD(a, b, addr_source); NM_CMP_FIELD_UNSAFE(a, b, a_force_commit); + NM_CMP_FIELD_UNSAFE(a, b, a_no_auto_noprefixroute); } return 0; } @@ -8337,15 +8776,18 @@ nm_platform_ip4_route_hash_update(const NMPlatformIP4Route *obj, obj->initcwnd, obj->initrwnd, obj->mtu, + obj->rto_min, obj->r_rtm_flags & RTNH_F_ONLINK, - NM_HASH_COMBINE_BOOLS(guint8, + NM_HASH_COMBINE_BOOLS(guint16, obj->metric_any, obj->table_any, + obj->quickack, obj->lock_window, obj->lock_cwnd, obj->lock_initcwnd, obj->lock_initrwnd, - obj->lock_mtu)); + obj->lock_mtu, + obj->lock_mss)); break; case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY: nm_hash_update_vals( @@ -8367,15 +8809,18 @@ nm_platform_ip4_route_hash_update(const NMPlatformIP4Route *obj, obj->initcwnd, obj->initrwnd, obj->mtu, + obj->rto_min, obj->r_rtm_flags & (RTM_F_CLONED | RTNH_F_ONLINK), - NM_HASH_COMBINE_BOOLS(guint8, + NM_HASH_COMBINE_BOOLS(guint16, obj->metric_any, obj->table_any, + obj->quickack, obj->lock_window, obj->lock_cwnd, obj->lock_initcwnd, obj->lock_initrwnd, - obj->lock_mtu)); + obj->lock_mtu, + obj->lock_mss)); break; case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL: nm_hash_update_vals(h, @@ -8396,15 +8841,18 @@ nm_platform_ip4_route_hash_update(const NMPlatformIP4Route *obj, obj->initcwnd, obj->initrwnd, obj->mtu, + obj->rto_min, obj->r_rtm_flags, - NM_HASH_COMBINE_BOOLS(guint8, + NM_HASH_COMBINE_BOOLS(guint16, obj->metric_any, obj->table_any, + obj->quickack, obj->lock_window, obj->lock_cwnd, obj->lock_initcwnd, obj->lock_initrwnd, obj->lock_mtu, + obj->lock_mss, obj->r_force_commit)); break; } @@ -8442,12 +8890,15 @@ nm_platform_ip4_route_cmp(const NMPlatformIP4Route *a, NM_CMP_FIELD(a, b, initcwnd); NM_CMP_FIELD(a, b, initrwnd); NM_CMP_FIELD(a, b, mtu); + NM_CMP_FIELD(a, b, rto_min); NM_CMP_DIRECT(a->r_rtm_flags & RTNH_F_ONLINK, b->r_rtm_flags & RTNH_F_ONLINK); + NM_CMP_FIELD_UNSAFE(a, b, quickack); NM_CMP_FIELD_UNSAFE(a, b, lock_window); NM_CMP_FIELD_UNSAFE(a, b, lock_cwnd); NM_CMP_FIELD_UNSAFE(a, b, lock_initcwnd); NM_CMP_FIELD_UNSAFE(a, b, lock_initrwnd); NM_CMP_FIELD_UNSAFE(a, b, lock_mtu); + NM_CMP_FIELD_UNSAFE(a, b, lock_mss); } break; case NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY: @@ -8485,16 +8936,19 @@ nm_platform_ip4_route_cmp(const NMPlatformIP4Route *a, } else NM_CMP_FIELD(a, b, r_rtm_flags); NM_CMP_FIELD(a, b, tos); + NM_CMP_FIELD_UNSAFE(a, b, quickack); NM_CMP_FIELD_UNSAFE(a, b, lock_window); NM_CMP_FIELD_UNSAFE(a, b, lock_cwnd); NM_CMP_FIELD_UNSAFE(a, b, lock_initcwnd); NM_CMP_FIELD_UNSAFE(a, b, lock_initrwnd); NM_CMP_FIELD_UNSAFE(a, b, lock_mtu); + NM_CMP_FIELD_UNSAFE(a, b, lock_mss); NM_CMP_FIELD(a, b, window); NM_CMP_FIELD(a, b, cwnd); NM_CMP_FIELD(a, b, initcwnd); NM_CMP_FIELD(a, b, initrwnd); NM_CMP_FIELD(a, b, mtu); + NM_CMP_FIELD(a, b, rto_min); if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL) NM_CMP_FIELD_UNSAFE(a, b, r_force_commit); break; @@ -8552,19 +9006,22 @@ nm_platform_ip6_route_hash_update(const NMPlatformIP6Route *obj, nmp_utils_ip_config_source_round_trip_rtprot(obj->rt_source), obj->mss, obj->r_rtm_flags & RTM_F_CLONED, - NM_HASH_COMBINE_BOOLS(guint8, + NM_HASH_COMBINE_BOOLS(guint16, obj->metric_any, obj->table_any, + obj->quickack, obj->lock_window, obj->lock_cwnd, obj->lock_initcwnd, obj->lock_initrwnd, - obj->lock_mtu), + obj->lock_mtu, + obj->lock_mss), obj->window, obj->cwnd, obj->initcwnd, obj->initrwnd, obj->mtu, + obj->rto_min, _route_pref_normalize(obj->rt_pref)); break; case NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL: @@ -8584,17 +9041,20 @@ nm_platform_ip6_route_hash_update(const NMPlatformIP6Route *obj, NM_HASH_COMBINE_BOOLS(guint16, obj->metric_any, obj->table_any, + obj->quickack, obj->lock_window, obj->lock_cwnd, obj->lock_initcwnd, obj->lock_initrwnd, obj->lock_mtu, + obj->lock_mss, obj->r_force_commit), obj->window, obj->cwnd, obj->initcwnd, obj->initrwnd, obj->mtu, + obj->rto_min, obj->rt_pref); break; } @@ -8658,16 +9118,19 @@ nm_platform_ip6_route_cmp(const NMPlatformIP6Route *a, NM_CMP_DIRECT(a->r_rtm_flags & RTM_F_CLONED, b->r_rtm_flags & RTM_F_CLONED); } else NM_CMP_FIELD(a, b, r_rtm_flags); + NM_CMP_FIELD_UNSAFE(a, b, quickack); NM_CMP_FIELD_UNSAFE(a, b, lock_window); NM_CMP_FIELD_UNSAFE(a, b, lock_cwnd); NM_CMP_FIELD_UNSAFE(a, b, lock_initcwnd); NM_CMP_FIELD_UNSAFE(a, b, lock_initrwnd); NM_CMP_FIELD_UNSAFE(a, b, lock_mtu); + NM_CMP_FIELD_UNSAFE(a, b, lock_mss); NM_CMP_FIELD(a, b, window); NM_CMP_FIELD(a, b, cwnd); NM_CMP_FIELD(a, b, initcwnd); NM_CMP_FIELD(a, b, initrwnd); NM_CMP_FIELD(a, b, mtu); + NM_CMP_FIELD(a, b, rto_min); if (cmp_type == NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY) NM_CMP_DIRECT(_route_pref_normalize(a->rt_pref), _route_pref_normalize(b->rt_pref)); else @@ -8927,6 +9390,37 @@ nm_platform_ip_address_cmp_expiry(const NMPlatformIPAddress *a, const NMPlatform /*****************************************************************************/ +guint16 +nm_platform_genl_get_family_id(NMPlatform *self, NMPGenlFamilyType family_type) +{ + _CHECK_SELF(self, klass, 0); + + if (!_NM_INT_NOT_NEGATIVE(family_type) || family_type >= _NMP_GENL_FAMILY_TYPE_NUM) + g_return_val_if_reached(0); + + return klass->genl_get_family_id(self, family_type); +} + +/*****************************************************************************/ + +int +nm_platform_mptcp_addr_update(NMPlatform *self, NMOptionBool add, const NMPlatformMptcpAddr *addr) +{ + _CHECK_SELF(self, klass, -NME_BUG); + + return klass->mptcp_addr_update(self, add, addr); +} + +GPtrArray * +nm_platform_mptcp_addrs_dump(NMPlatform *self) +{ + _CHECK_SELF(self, klass, NULL); + + return klass->mptcp_addrs_dump(self); +} + +/*****************************************************************************/ + GHashTable * nm_platform_ip4_address_addr_to_hash(NMPlatform *self, int ifindex) { @@ -8939,7 +9433,7 @@ nm_platform_ip4_address_addr_to_hash(NMPlatform *self, int ifindex) g_return_val_if_fail(NM_IS_PLATFORM(self), NULL); g_return_val_if_fail(ifindex > 0, NULL); - nmp_lookup_init_object(&lookup, NMP_OBJECT_TYPE_IP4_ADDRESS, ifindex); + nmp_lookup_init_object_by_ifindex(&lookup, NMP_OBJECT_TYPE_IP4_ADDRESS, ifindex); head_entry = nmp_cache_lookup(NM_PLATFORM_GET_PRIVATE(self)->cache, &lookup); @@ -8975,8 +9469,6 @@ nm_platform_ip4_address_generate_device_route(const NMPlatformIP4Address *addr, nm_assert(addr); nm_assert(addr->plen <= 32); - if (addr->plen == 0) - return NULL; if (addr->plen == 0) return NULL; @@ -9037,9 +9529,13 @@ log_link(NMPlatform *self, { char sbuf[NM_UTILS_TO_STRING_BUFFER_SIZE]; - _LOG3D("signal: link %7s: %s", - nm_platform_signal_change_type_to_string(change_type), - nm_platform_link_to_string(device, sbuf, sizeof(sbuf))); + if (_LOGD_ENABLED()) { + NMLOG_COMMON(LOGL_DEBUG, + device->name, + "signal: link %7s: %s", + nm_platform_signal_change_type_to_string(change_type), + nm_platform_link_to_string(device, sbuf, sizeof(sbuf))); + } } static void |