diff options
| author | Michael Biebl <biebl@debian.org> | 2022-08-16 18:24:19 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2022-08-16 18:24:19 +0200 |
| commit | 0018d1f3cf71d680d7b6bceda55a5717244d8b26 (patch) | |
| tree | a058f1d106d172d3354179437ef034c9355cdf9c /src/libnm-platform/nmp-object.c | |
| parent | 6accbd3ec0e42d8633bbde4d47ed7bfe854e7e0b (diff) | |
New upstream version 1.39.90 upstream/1.39.90
Diffstat (limited to 'src/libnm-platform/nmp-object.c')
| -rw-r--r-- | src/libnm-platform/nmp-object.c | 204 |
1 files changed, 128 insertions, 76 deletions
diff --git a/src/libnm-platform/nmp-object.c b/src/libnm-platform/nmp-object.c index 6c177b4c..d06aa9cd 100644 --- a/src/libnm-platform/nmp-object.c +++ b/src/libnm-platform/nmp-object.c @@ -20,25 +20,26 @@ /*****************************************************************************/ #define _NMLOG_DOMAIN LOGD_PLATFORM -#define _NMLOG(level, obj, ...) \ - G_STMT_START \ - { \ - const NMLogLevel __level = (level); \ - \ - if (nm_logging_enabled(__level, _NMLOG_DOMAIN)) { \ - const NMPObject *const __obj = (obj); \ - \ - _nm_log(__level, \ - _NMLOG_DOMAIN, \ - 0, \ - NULL, \ - NULL, \ - "nmp-object[%p/%s]: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ - __obj, \ - (__obj ? NMP_OBJECT_GET_CLASS(__obj)->obj_type_name \ - : "???") _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ - } \ - } \ +#define _NMLOG(level, obj, ...) \ + G_STMT_START \ + { \ + const NMLogLevel __level = (level); \ + \ + if (nm_logging_enabled(__level, _NMLOG_DOMAIN)) { \ + const NMPObject *const __obj = (obj); \ + \ + _nm_log(__level, \ + _NMLOG_DOMAIN, \ + 0, \ + NULL, \ + NULL, \ + "nmp-object[" NM_HASH_OBFUSCATE_PTR_FMT "" \ + "/%s]: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \ + NM_HASH_OBFUSCATE_PTR(__obj), \ + (__obj ? NMP_OBJECT_GET_CLASS(__obj)->obj_type_name \ + : "???") _NM_UTILS_MACRO_REST(__VA_ARGS__)); \ + } \ + } \ G_STMT_END /*****************************************************************************/ @@ -380,7 +381,8 @@ _idx_obj_part(const DedupMultiIdxType *idx_type, NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE, NMP_OBJECT_TYPE_QDISC, - NMP_OBJECT_TYPE_TFILTER) + NMP_OBJECT_TYPE_TFILTER, + NMP_OBJECT_TYPE_MPTCP_ADDR) || !nmp_object_is_visible(obj_a)) { if (h) nm_hash_update_val(h, obj_a); @@ -805,13 +807,9 @@ _nmp_object_stackinit_from_class(NMPObject *obj, const NMPClass *klass) nm_assert(obj); nm_assert(klass); - *obj = (NMPObject){ - .parent = - { - .klass = (const NMDedupMultiObjClass *) klass, - ._ref_count = NM_OBJ_REF_COUNT_STACKINIT, - }, - }; + memset(obj, 0, sizeof(NMPObject)); + obj->_class = klass; + obj->parent._ref_count = NM_OBJ_REF_COUNT_STACKINIT; return obj; } @@ -844,6 +842,17 @@ nmp_object_stackinit_id(NMPObject *obj, const NMPObject *src) _nmp_object_stackinit_from_class(obj, klass); if (klass->cmd_plobj_id_copy) klass->cmd_plobj_id_copy(&obj->object, &src->object); + else { + /* This object must not implement cmd_obj_copy(). + * If it would, it would mean that we require a deep copy + * of the data. As @obj is stack-allocated, it cannot track + * ownership. The caller must not use nmp_object_stackinit_id() + * with an object of such a type. */ + nm_assert(!klass->cmd_obj_copy); + + /* plain memcpy of the public part suffices. */ + memcpy(&obj->object, &src->object, klass->sizeof_data); + } return obj; } @@ -904,7 +913,7 @@ nmp_object_to_string(const NMPObject *obj, switch (to_string_mode) { case NMP_OBJECT_TO_STRING_ID: if (!klass->cmd_plobj_to_string_id) { - g_snprintf(buf, buf_size, "%p", obj); + g_snprintf(buf, buf_size, NM_HASH_OBFUSCATE_PTR_FMT, NM_HASH_OBFUSCATE_PTR(obj)); return buf; } return klass->cmd_plobj_to_string_id(&obj->object, buf, buf_size); @@ -912,9 +921,9 @@ nmp_object_to_string(const NMPObject *obj, g_snprintf( buf, buf_size, - "[%s,%p,%u,%calive,%cvisible; %s]", + "[%s," NM_HASH_OBFUSCATE_PTR_FMT ",%u,%calive,%cvisible; %s]", klass->obj_type_name, - obj, + NM_HASH_OBFUSCATE_PTR(obj), obj->parent._ref_count, nmp_object_is_alive(obj) ? '+' : '-', nmp_object_is_visible(obj) ? '+' : '-', @@ -943,14 +952,15 @@ _vt_cmd_obj_to_string_link(const NMPObject *obj, case NMP_OBJECT_TO_STRING_ALL: nm_strbuf_append(&b, &buf_size, - "[%s,%p,%u,%calive,%cvisible,%cin-nl,%p; ", + "[%s," NM_HASH_OBFUSCATE_PTR_FMT + ",%u,%calive,%cvisible,%cin-nl," NM_HASH_OBFUSCATE_PTR_FMT "; ", klass->obj_type_name, - obj, + NM_HASH_OBFUSCATE_PTR(obj), obj->parent._ref_count, nmp_object_is_alive(obj) ? '+' : '-', nmp_object_is_visible(obj) ? '+' : '-', obj->_link.netlink.is_in_netlink ? '+' : '-', - obj->_link.udev.device); + NM_HASH_OBFUSCATE_PTR(obj->_link.udev.device)); NMP_OBJECT_GET_CLASS(obj)->cmd_plobj_to_string(&obj->object, b, buf_size); nm_strbuf_seek_end(&b, &buf_size); if (obj->_link.netlink.lnk) { @@ -988,15 +998,15 @@ _vt_cmd_obj_to_string_lnk_vlan(const NMPObject *obj, switch (to_string_mode) { case NMP_OBJECT_TO_STRING_ID: - g_snprintf(buf, buf_size, "%p", obj); + g_snprintf(buf, buf_size, NM_HASH_OBFUSCATE_PTR_FMT, NM_HASH_OBFUSCATE_PTR(obj)); return buf; case NMP_OBJECT_TO_STRING_ALL: g_snprintf(buf, buf_size, - "[%s,%p,%u,%calive,%cvisible; %s]", + "[%s," NM_HASH_OBFUSCATE_PTR_FMT ",%u,%calive,%cvisible; %s]", klass->obj_type_name, - obj, + NM_HASH_OBFUSCATE_PTR(obj), obj->parent._ref_count, nmp_object_is_alive(obj) ? '+' : '-', nmp_object_is_visible(obj) ? '+' : '-', @@ -1052,17 +1062,17 @@ _vt_cmd_obj_to_string_lnk_wireguard(const NMPObject *obj, switch (to_string_mode) { case NMP_OBJECT_TO_STRING_ID: - g_snprintf(buf, buf_size, "%p", obj); + g_snprintf(buf, buf_size, NM_HASH_OBFUSCATE_PTR_FMT, NM_HASH_OBFUSCATE_PTR(obj)); return buf; case NMP_OBJECT_TO_STRING_ALL: b = buf; nm_strbuf_append(&b, &buf_size, - "[%s,%p,%u,%calive,%cvisible; %s" + "[%s," NM_HASH_OBFUSCATE_PTR_FMT ",%u,%calive,%cvisible; %s" "%s", klass->obj_type_name, - obj, + NM_HASH_OBFUSCATE_PTR(obj), obj->parent._ref_count, nmp_object_is_alive(obj) ? '+' : '-', nmp_object_is_visible(obj) ? '+' : '-', @@ -1153,10 +1163,7 @@ _vt_cmd_obj_hash_update_link(const NMPObject *obj, NMHashState *h) nm_assert(NMP_OBJECT_GET_TYPE(obj) == NMP_OBJECT_TYPE_LINK); nm_platform_link_hash_update(&obj->link, h); - nm_hash_update_vals(h, - obj->_link.netlink.is_in_netlink, - obj->_link.wireguard_family_id, - obj->_link.udev.device); + nm_hash_update_vals(h, obj->_link.netlink.is_in_netlink, obj->_link.udev.device); if (obj->_link.netlink.lnk) nmp_object_hash_update(obj->_link.netlink.lnk, h); } @@ -1236,7 +1243,6 @@ _vt_cmd_obj_cmp_link(const NMPObject *obj1, const NMPObject *obj2) NM_CMP_RETURN(nm_platform_link_cmp(&obj1->link, &obj2->link)); NM_CMP_DIRECT(obj1->_link.netlink.is_in_netlink, obj2->_link.netlink.is_in_netlink); NM_CMP_RETURN(nmp_object_cmp(obj1->_link.netlink.lnk, obj2->_link.netlink.lnk)); - NM_CMP_DIRECT(obj1->_link.wireguard_family_id, obj2->_link.wireguard_family_id); if (obj1->_link.udev.device != obj2->_link.udev.device) { if (!obj1->_link.udev.device) @@ -1428,21 +1434,6 @@ _vt_cmd_plobj_id_copy(ip6_address, NMPlatformIP6Address, { dst->address = src->address; }); -_vt_cmd_plobj_id_copy(ip4_route, NMPlatformIP4Route, { - *dst = *src; - nm_assert(nm_platform_ip4_route_cmp(dst, src, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) == 0); -}); - -_vt_cmd_plobj_id_copy(ip6_route, NMPlatformIP6Route, { - *dst = *src; - nm_assert(nm_platform_ip6_route_cmp(dst, src, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) == 0); -}); - -_vt_cmd_plobj_id_copy(routing_rule, NMPlatformRoutingRule, { - *dst = *src; - nm_assert(nm_platform_routing_rule_cmp(dst, src, NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID) == 0); -}); - /* Uses internally nmp_object_copy(), hence it also violates the const * promise for @obj. * */ @@ -1561,6 +1552,37 @@ _vt_cmd_plobj_id_cmp_routing_rule(const NMPlatformObject *obj1, const NMPlatform NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID); } +_vt_cmd_plobj_id_cmp(mptcp_addr, NMPlatformMptcpAddr, { + /* The primary key of an MPTCP endpoint is only the address:port@ifindex. + * + * Which does not fully correspond to kernel's view. Kernel's view is determined + * by the question whether you can add two objects that only differ by one + * attribute. If you can, the attribute is part of the ID otherwise it isn't. + * + * Note that for kernel, the "ifindex" is not part of the identity. + * That is, you cannot two add two endpoints that only differ by + * ifindex. However, for our purpose, it is very useful to make + * the "ifindex" part of the identity. For example, NMPGlobalTracker will use + * this to track MPTCP addresses from independent callers (NML3Cfg). + * It would be bad, if objects that differ by "ifindex" would be + * combined. + * + * The "id" is intentionally not part of the identity for us. Note however, that kernel + * does not allow configuring duplicates "id" -- so the "id" could be a primary key + * as far as kernel is concerned. However, when we track MPTCP endpoints that + * we want to configure, the "id" is left undefined (and we let kernel choose it). + * If the "id" would be part of the NMPObject's ID, we could not lookup + * an object unless we know the "id" -- which we often don't. + */ + NM_CMP_FIELD(obj1, obj2, ifindex); + NM_CMP_FIELD(obj1, obj2, addr_family); + NM_CMP_FIELD_MEMCMP_LEN(obj1, + obj2, + addr, + nm_utils_addr_family_to_size_untrusted(obj1->addr_family)); + NM_CMP_FIELD(obj1, obj2, port); +}); + void nmp_object_id_hash_update(const NMPObject *obj, NMHashState *h) { @@ -1646,6 +1668,12 @@ _vt_cmd_plobj_id_hash_update(tfilter, NMPlatformTfilter, { nm_hash_update_vals(h, obj->ifindex, obj->handle); }); +_vt_cmd_plobj_id_hash_update(mptcp_addr, NMPlatformMptcpAddr, { + /* See the corresponding ID cmp function for details. */ + nm_hash_update_vals(h, obj->addr_family, obj->port, obj->ifindex); + nm_hash_update(h, &obj->addr, nm_utils_addr_family_to_size_untrusted(obj->addr_family)); +}); + static void _vt_cmd_plobj_hash_update_ip4_route(const NMPlatformObject *obj, NMHashState *h) { @@ -1754,6 +1782,12 @@ _vt_cmd_obj_is_alive_tfilter(const NMPObject *obj) return NMP_OBJECT_CAST_TFILTER(obj)->ifindex > 0; } +static gboolean +_vt_cmd_obj_is_alive_mptcp_addr(const NMPObject *obj) +{ + return NM_IN_SET(obj->mptcp_addr.addr_family, AF_INET, AF_INET6, AF_UNSPEC); +} + gboolean nmp_object_is_visible(const NMPObject *obj) { @@ -2099,6 +2133,7 @@ nmp_lookup_init_obj_type(NMPLookup *lookup, NMPObjectType obj_type) case NMP_OBJECT_TYPE_ROUTING_RULE: case NMP_OBJECT_TYPE_QDISC: case NMP_OBJECT_TYPE_TFILTER: + case NMP_OBJECT_TYPE_MPTCP_ADDR: _nmp_object_stackinit_from_type(&lookup->selector_obj, obj_type); lookup->cache_id_type = NMP_CACHE_ID_TYPE_OBJECT_TYPE; return _L(lookup); @@ -2122,7 +2157,7 @@ nmp_lookup_init_link_by_ifname(NMPLookup *lookup, const char *ifname) } const NMPLookup * -nmp_lookup_init_object(NMPLookup *lookup, NMPObjectType obj_type, int ifindex) +nmp_lookup_init_object_by_ifindex(NMPLookup *lookup, NMPObjectType obj_type, int ifindex) { NMPObject *o; @@ -2133,19 +2168,11 @@ nmp_lookup_init_object(NMPLookup *lookup, NMPObjectType obj_type, int ifindex) NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE, NMP_OBJECT_TYPE_QDISC, - NMP_OBJECT_TYPE_TFILTER)); - - if (G_UNLIKELY( - (ifindex < 0) - || (ifindex == 0 - && !NM_IN_SET(obj_type, NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE)))) { - /* This function used to have a fallback that meant to lookup all objects, if - * ifindex is non-positive. As routes can have a zero ifindex, that fallback is - * confusing and no longer supported. Only have this code, to catch accidental bugs - * after the API change. */ - nm_assert_not_reached(); - return nmp_lookup_init_obj_type(lookup, obj_type); - } + NMP_OBJECT_TYPE_TFILTER, + NMP_OBJECT_TYPE_MPTCP_ADDR)); + nm_assert(ifindex > 0 + || (ifindex == 0 + && NM_IN_SET(obj_type, NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE))); o = _nmp_object_stackinit_from_type(&lookup->selector_obj, obj_type); o->obj_with_ifindex.ifindex = ifindex; @@ -3183,7 +3210,6 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { .signal_type = NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED, .supported_cache_ids = _supported_cache_ids_ipx_route, .cmd_obj_is_alive = _vt_cmd_obj_is_alive_ipx_route, - .cmd_plobj_id_copy = _vt_cmd_plobj_id_copy_ip4_route, .cmd_plobj_id_cmp = _vt_cmd_plobj_id_cmp_ip4_route, .cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_ip4_route, .cmd_plobj_to_string_id = (CmdPlobjToStringIdFunc) nm_platform_ip4_route_to_string, @@ -3204,7 +3230,6 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { .signal_type = NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED, .supported_cache_ids = _supported_cache_ids_ipx_route, .cmd_obj_is_alive = _vt_cmd_obj_is_alive_ipx_route, - .cmd_plobj_id_copy = _vt_cmd_plobj_id_copy_ip6_route, .cmd_plobj_id_cmp = _vt_cmd_plobj_id_cmp_ip6_route, .cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_ip6_route, .cmd_plobj_to_string_id = (CmdPlobjToStringIdFunc) nm_platform_ip6_route_to_string, @@ -3224,7 +3249,6 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { .signal_type = NM_PLATFORM_SIGNAL_ROUTING_RULE_CHANGED, .supported_cache_ids = _supported_cache_ids_routing_rules, .cmd_obj_is_alive = _vt_cmd_obj_is_alive_routing_rule, - .cmd_plobj_id_copy = _vt_cmd_plobj_id_copy_routing_rule, .cmd_plobj_id_cmp = _vt_cmd_plobj_id_cmp_routing_rule, .cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_routing_rule, .cmd_plobj_to_string_id = (CmdPlobjToStringIdFunc) nm_platform_routing_rule_to_string, @@ -3485,4 +3509,32 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = { .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_wireguard_hash_update, .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_wireguard_cmp, }, + [NMP_OBJECT_TYPE_LNK_BOND - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_LNK_BOND, + .sizeof_data = sizeof(NMPObjectLnkBond), + .sizeof_public = sizeof(NMPlatformLnkBond), + .obj_type_name = "bond", + .lnk_link_type = NM_LINK_TYPE_BOND, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_lnk_bond_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_bond_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_bond_cmp, + }, + [NMP_OBJECT_TYPE_MPTCP_ADDR - 1] = + { + .parent = DEDUP_MULTI_OBJ_CLASS_INIT(), + .obj_type = NMP_OBJECT_TYPE_MPTCP_ADDR, + .sizeof_data = sizeof(NMPObjectMptcpAddr), + .sizeof_public = sizeof(NMPlatformMptcpAddr), + .obj_type_name = "mptcp-addr", + .supported_cache_ids = _supported_cache_ids_object, + .cmd_obj_is_alive = _vt_cmd_obj_is_alive_mptcp_addr, + .cmd_plobj_id_cmp = _vt_cmd_plobj_id_cmp_mptcp_addr, + .cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_mptcp_addr, + .cmd_plobj_to_string_id = (CmdPlobjToStringIdFunc) nm_platform_mptcp_addr_to_string, + .cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_mptcp_addr_to_string, + .cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_mptcp_addr_hash_update, + .cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_mptcp_addr_cmp, + }, }; |