From 51625013d4bc610569422ad22f824a82a92a21e1 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 22 Jul 2022 20:27:39 +0200 Subject: [PATCH 01/12] glib-aux: add code comment to nm_ip_addr_set() about using it for NMIPAddr argument --- src/libnm-glib-aux/nm-shared-utils.h | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/libnm-glib-aux/nm-shared-utils.h b/src/libnm-glib-aux/nm-shared-utils.h index 6cdc8875ef..20810e4cd5 100644 --- a/src/libnm-glib-aux/nm-shared-utils.h +++ b/src/libnm-glib-aux/nm-shared-utils.h @@ -277,8 +277,15 @@ nm_ip_addr_set(int addr_family, gpointer dst, gconstpointer src) nm_assert(dst); nm_assert(src); - /* this MUST use memcpy() (or similar means) to support unaligned src/dst pointers. */ + /* this MUST use memcpy() to support unaligned src/dst pointers. */ memcpy(dst, src, nm_utils_addr_family_to_size(addr_family)); + + /* Note that @dst is not necessarily a NMIPAddr, it could also be just + * an in_addr_t/struct in6_addr. We thus can only set the bytes that + * we know are present based on the address family. + * + * Using this function to initialize an NMIPAddr union (for IPv4) leaves + * uninitalized bytes. Avoid that by using nm_ip_addr_init() instead. */ } static inline NMIPAddr @@ -291,6 +298,8 @@ nm_ip_addr_init(int addr_family, gconstpointer src) G_STATIC_ASSERT_EXPR(sizeof(NMIPAddr) == sizeof(struct in6_addr)); + /* this MUST use memcpy() to support unaligned src/dst pointers. */ + if (NM_IS_IPv4(addr_family)) { memcpy(&a, src, sizeof(in_addr_t)); From 76d63c66d773afe40640c1199ebdcc7e5a85b15b Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 22 Jul 2022 18:30:44 +0200 Subject: [PATCH 02/12] glib-aux: add nm_utils_ip4_address_is_loopback() --- src/libnm-glib-aux/nm-shared-utils.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/libnm-glib-aux/nm-shared-utils.h b/src/libnm-glib-aux/nm-shared-utils.h index 20810e4cd5..81c7260612 100644 --- a/src/libnm-glib-aux/nm-shared-utils.h +++ b/src/libnm-glib-aux/nm-shared-utils.h @@ -508,8 +508,16 @@ gboolean nm_utils_ip_is_site_local(int addr_family, const void *address); /*****************************************************************************/ -#define NM_IPV4LL_NETWORK ((in_addr_t) (htonl(0xA9FE0000lu))) -#define NM_IPV4LL_NETMASK ((in_addr_t) (htonl(0xFFFF0000lu))) +#define NM_IPV4LL_NETWORK ((in_addr_t) htonl(0xA9FE0000lu)) +#define NM_IPV4LL_NETMASK ((in_addr_t) htonl(0xFFFF0000lu)) + +static inline gboolean +nm_utils_ip4_address_is_loopback(in_addr_t addr) +{ + /* There is also IN_LOOPBACK() in , but there the + * argument is in host order not `in_addr_t`. */ + return (addr & htonl(0xFF000000u)) == htonl(0x7F000000u); +} static inline gboolean nm_utils_ip4_address_is_link_local(in_addr_t addr) From 1f7db38dd79e101735bf625cb8f5d0f28e32a016 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 25 Jul 2022 15:36:50 +0200 Subject: [PATCH 03/12] glib-aux: add nm_ip_addr_cmp_for_sort() helper for sorting IP addresses It's similar to nm_ip_addr_cmp(), but it can be used as an argument to g_qsort_with_data() to sort a list of NMIPAddr (or in_addr_t or struct in6_addr). The address family needs to be given as user-data. --- src/libnm-glib-aux/nm-shared-utils.c | 9 +++++++++ src/libnm-glib-aux/nm-shared-utils.h | 5 +++++ 2 files changed, 14 insertions(+) diff --git a/src/libnm-glib-aux/nm-shared-utils.c b/src/libnm-glib-aux/nm-shared-utils.c index 6128b0cb8a..9c0d16164a 100644 --- a/src/libnm-glib-aux/nm-shared-utils.c +++ b/src/libnm-glib-aux/nm-shared-utils.c @@ -44,6 +44,15 @@ G_STATIC_ASSERT(_nm_alignof(struct in_addr) <= _nm_alignof(NMIPAddr)); G_STATIC_ASSERT(_nm_alignof(struct in6_addr) <= _nm_alignof(NMIPAddr)); G_STATIC_ASSERT(_nm_alignof(NMEtherAddr) <= _nm_alignof(NMIPAddr)); +int +nm_ip_addr_cmp_for_sort(gconstpointer a, gconstpointer b, gpointer user_data) +{ + /* This is a compare function that can be used for sorting IP addresses. + * Essentially, it calls memcmp(). @user_data must be GINT_TO_POINTER(addr_family). + * @a and @b must be either pointers to in_addr_t, struct in6_addr or NMIPAddr. */ + return nm_ip_addr_cmp(GPOINTER_TO_INT(user_data), a, b); +} + /* this initializes a struct in_addr/in6_addr and allows for untrusted * arguments (like unsuitable @addr_family or @src_len). It's almost safe * in the sense that it verifies input arguments strictly. Also, it diff --git a/src/libnm-glib-aux/nm-shared-utils.h b/src/libnm-glib-aux/nm-shared-utils.h index 81c7260612..ab183d9ac8 100644 --- a/src/libnm-glib-aux/nm-shared-utils.h +++ b/src/libnm-glib-aux/nm-shared-utils.h @@ -243,11 +243,16 @@ extern const NMIPAddr nm_ip_addr_zero; static inline int nm_ip_addr_cmp(int addr_family, gconstpointer a, gconstpointer b) { + /* Note that @a and @b are not required to be full NMIPAddr unions. + * Depending on @addr_family, they can also be only in_addr_t or + * struct in6_addr. */ NM_CMP_SELF(a, b); NM_CMP_DIRECT_MEMCMP(a, b, nm_utils_addr_family_to_size(addr_family)); return 0; } +int nm_ip_addr_cmp_for_sort(gconstpointer a, gconstpointer b, gpointer user_data); + static inline gboolean nm_ip_addr_equal(int addr_family, gconstpointer a, gconstpointer b) { From 9c3e0846ee16b1f0074961b12e98376651389b15 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 25 Jul 2022 15:47:02 +0200 Subject: [PATCH 04/12] platform/trivial: add blank line after variable declaration in NLA_PUT_TYPE() --- src/libnm-platform/nm-netlink.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libnm-platform/nm-netlink.h b/src/libnm-platform/nm-netlink.h index ccd4b787c7..ec4fd4f3b8 100644 --- a/src/libnm-platform/nm-netlink.h +++ b/src/libnm-platform/nm-netlink.h @@ -304,6 +304,7 @@ nla_put_uint32(struct nl_msg *msg, int attrtype, uint32_t val) G_STMT_START \ { \ type __nla_tmp = value; \ + \ NLA_PUT(msg, attrtype, sizeof(type), &__nla_tmp); \ } \ G_STMT_END From b3f60d891f1303de05db74c22a7c20ecddad3fae Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 25 Jul 2022 15:46:21 +0200 Subject: [PATCH 05/12] platform: assert for success genlmsg_put() in _nl802154_alloc_msg() --- src/libnm-platform/wpan/nm-wpan-utils.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libnm-platform/wpan/nm-wpan-utils.c b/src/libnm-platform/wpan/nm-wpan-utils.c index 0afbe58d3e..9350a2a780 100644 --- a/src/libnm-platform/wpan/nm-wpan-utils.c +++ b/src/libnm-platform/wpan/nm-wpan-utils.c @@ -80,7 +80,8 @@ _nl802154_alloc_msg(guint16 genl_family_id, int ifindex, uint8_t cmd, uint16_t f nm_auto_nlmsg struct nl_msg *msg = NULL; msg = nlmsg_alloc(); - genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, genl_family_id, 0, flags, cmd, 0); + if (!genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, genl_family_id, 0, flags, cmd, 0)) + goto nla_put_failure; NLA_PUT_U32(msg, NL802154_ATTR_IFINDEX, ifindex); return g_steal_pointer(&msg); From dc98ab807ca89cfec9a6ec8b441088a4bed30c8f Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 25 Jul 2022 13:37:19 +0200 Subject: [PATCH 06/12] platform: include "linux-headers" via "libnm-std-aux/nm-linux-compat.h" We have our own copy of linux kernel headers, and we must never directly include the corresponding versions from the system. Avoid that, by only including the clones via "libnm-std-aux/nm-linux-compat.h" and by including the compat wrapper header before other system headers. --- src/libnm-platform/nm-linux-platform.c | 3 ++- src/libnm-platform/wifi/nm-wifi-utils-nl80211.c | 4 ++-- src/libnm-std-aux/nm-linux-compat.h | 2 ++ 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/libnm-platform/nm-linux-platform.c b/src/libnm-platform/nm-linux-platform.c index 26831c3718..7601db5cc2 100644 --- a/src/libnm-platform/nm-linux-platform.c +++ b/src/libnm-platform/nm-linux-platform.c @@ -7,6 +7,8 @@ #include "nm-linux-platform.h" +#include "libnm-std-aux/nm-linux-compat.h" + #include #include #include @@ -23,7 +25,6 @@ #include #include #include -#include #include #include #include diff --git a/src/libnm-platform/wifi/nm-wifi-utils-nl80211.c b/src/libnm-platform/wifi/nm-wifi-utils-nl80211.c index 1875a42068..eab50f1615 100644 --- a/src/libnm-platform/wifi/nm-wifi-utils-nl80211.c +++ b/src/libnm-platform/wifi/nm-wifi-utils-nl80211.c @@ -9,14 +9,14 @@ #include "nm-wifi-utils-nl80211.h" +#include "libnm-std-aux/nm-linux-compat.h" + #include #include #include #include #include -#include "linux-headers/nl80211-vnd-intel.h" - #include "libnm-log-core/nm-logging.h" #include "libnm-platform/nm-netlink.h" #include "nm-wifi-utils-private.h" diff --git a/src/libnm-std-aux/nm-linux-compat.h b/src/libnm-std-aux/nm-linux-compat.h index 7ca7ec781c..2675393d87 100644 --- a/src/libnm-std-aux/nm-linux-compat.h +++ b/src/libnm-std-aux/nm-linux-compat.h @@ -21,5 +21,7 @@ #include "linux-headers/ethtool.h" #include "linux-headers/nl802154.h" +#include "linux-headers/nl80211-vnd-intel.h" +#include "linux-headers/mptcp.h" #endif /* __NM_LINUX_COMPAT_H__ */ From e25b7a579e8ca9fb6f7764f898481af37f11ab33 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 22 Jul 2022 20:28:35 +0200 Subject: [PATCH 07/12] platform: add nm_platform_ip{4,6,}_address_get_scope() helper --- src/libnm-platform/nm-platform.h | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/src/libnm-platform/nm-platform.h b/src/libnm-platform/nm-platform.h index 121886707d..26fffe23ac 100644 --- a/src/libnm-platform/nm-platform.h +++ b/src/libnm-platform/nm-platform.h @@ -1549,6 +1549,37 @@ nm_platform_route_type_uncoerce(guint8 type_coerced) return nm_platform_route_type_coerce(type_coerced); } +static inline guint8 +nm_platform_ip4_address_get_scope(in_addr_t addr) +{ + /* For IPv4 addresses, we can set any scope we want (for any address). + * However, there are scopes that make sense based on the address, + * so choose those. */ + return nm_utils_ip4_address_is_loopback(addr) ? (254 /* RT_SCOPE_HOST */) + : nm_utils_ip4_address_is_link_local(addr) ? (253 /* RT_SCOPE_LINK */) + : (0 /* RT_SCOPE_UNIVERSE */); +} + +static inline guint8 +nm_platform_ip6_address_get_scope(const struct in6_addr *addr) +{ + /* For IPv6, kernel does not allow userspace to configure the address scope. + * Instead, it is calculated based on the address. See rt_scope() and + * ipv6_addr_scope(). We do the same here. */ + return IN6_IS_ADDR_LOOPBACK(addr) ? (254 /* RT_SCOPE_HOST */) + : IN6_IS_ADDR_LINKLOCAL(addr) ? (253 /* RT_SCOPE_LINK */) + : IN6_IS_ADDR_SITELOCAL(addr) ? (200 /* RT_SCOPE_SITE */) + : (0 /* RT_SCOPE_UNIVERSE */); +} + +static inline guint8 +nm_platform_ip_address_get_scope(int addr_family, gconstpointer addr) +{ + if (NM_IS_IPv4(addr_family)) + return nm_platform_ip4_address_get_scope(*((in_addr_t *) addr)); + return nm_platform_ip6_address_get_scope(addr); +} + gboolean nm_platform_get_use_udev(NMPlatform *self); gboolean nm_platform_get_log_with_ptr(NMPlatform *self); gboolean nm_platform_get_cache_tc(NMPlatform *self); From e466ad62e5d77c5d02d0fa572583c8e93785022a Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Fri, 22 Jul 2022 18:34:33 +0200 Subject: [PATCH 08/12] platform: set the scope for IPv4 loopback address to "host" For IPv6, kernel does not accept the ifa_scope parameter and always determines the scope based on the address itself. For IPv4, it honors whatever scope the user sets via netlink. NetworkManager does not allow to directly configure the address scope, but autodetects it. Use nm_platform_ip4_address_get_scope() for detecting the scopt. This also fixes the issue that to detect loopback addresses 127.0.0.0/8 and use scope "host". Try: $ nmcli device modify "$IFACE" +ipv4.addresses 127.0.0.5/8 --- src/libnm-platform/nm-linux-platform.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libnm-platform/nm-linux-platform.c b/src/libnm-platform/nm-linux-platform.c index 7601db5cc2..e445d0757b 100644 --- a/src/libnm-platform/nm-linux-platform.c +++ b/src/libnm-platform/nm-linux-platform.c @@ -8964,8 +8964,7 @@ ip4_address_add(NMPlatform *platform, plen, &peer_addr, flags, - nm_utils_ip4_address_is_link_local(addr) ? RT_SCOPE_LINK - : RT_SCOPE_UNIVERSE, + nm_platform_ip4_address_get_scope(addr), lifetime, preferred, broadcast_address, From bf248e04005cc08dd989c950f62d168fccca5ebe Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 18 Jul 2022 09:12:09 +0200 Subject: [PATCH 09/12] platform: rename NMPRouteManager to NMPGlobalTracker NetworkManager primarily manages interfaces in an independent fashion. That means, whenever possible, we want to have a interface specific view. In many cases, the underlying kernel API also supports that view. For example, when configuring IP addresses or unicast routes, we do so per interfaces and don't need a holistic view. However, that is not always sufficient. For routing rules and certain route types (blackhole, unreachable, etc), we need a system wide view of all the objects in the network namespace. Originally, NMPRulesManager was added to track routing rules. Then, it was extended to also track certain route types, and the API was renamed to NMPRouteManager. This will also be used to track MPTCP addresses. So rename again, to give it a general name that is suitable for what it does. Still, the name is not great (suggestion welcome), but it should cover the purpose of the API well enough. And it's the best I came up with. Rename. --- src/core/devices/nm-device.c | 40 ++--- src/core/nm-l3cfg.c | 36 ++-- src/core/nm-l3cfg.h | 16 +- src/core/nm-netns.c | 46 ++--- src/core/nm-netns.h | 2 +- src/core/platform/tests/test-route.c | 64 +++---- src/libnm-platform/nmp-route-manager.c | 240 ++++++++++++------------- src/libnm-platform/nmp-route-manager.h | 100 +++++------ 8 files changed, 274 insertions(+), 270 deletions(-) diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c index 8c58453b55..915c40eea0 100644 --- a/src/core/devices/nm-device.c +++ b/src/core/devices/nm-device.c @@ -9491,13 +9491,13 @@ lldp_setup(NMDevice *self, NMTernary enabled) static void _routing_rules_sync(NMDevice *self, NMTernary set_mode) { - NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); - NMPRouteManager *route_manager = nm_netns_get_route_manager(nm_device_get_netns(self)); - NMDeviceClass *klass = NM_DEVICE_GET_CLASS(self); - gboolean untrack_only_dirty = FALSE; - gboolean keep_deleted_rules; - gpointer user_tag_1; - gpointer user_tag_2; + NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self); + NMPGlobalTracker *global_tracker = nm_netns_get_global_tracker(nm_device_get_netns(self)); + NMDeviceClass *klass = NM_DEVICE_GET_CLASS(self); + gboolean untrack_only_dirty = FALSE; + gboolean keep_deleted_rules; + gpointer user_tag_1; + gpointer user_tag_2; /* take two arbitrary user-tag pointers that belong to @self. */ user_tag_1 = &priv->v4_route_table; @@ -9529,13 +9529,13 @@ _routing_rules_sync(NMDevice *self, NMTernary set_mode) nm_ip_routing_rule_to_platform(rule, &plrule); /* We track this rule, but we also make it explicitly not weakly-tracked - * (meaning to untrack NMP_ROUTE_MANAGER_EXTERN_WEAKLY_TRACKED_USER_TAG at + * (meaning to untrack NMP_GLOBAL_TRACKER_EXTERN_WEAKLY_TRACKED_USER_TAG at * the same time). */ - nmp_route_manager_track_rule(route_manager, - &plrule, - 10, - user_tag_1, - NMP_ROUTE_MANAGER_EXTERN_WEAKLY_TRACKED_USER_TAG); + nmp_global_tracker_track_rule(global_tracker, + &plrule, + 10, + user_tag_1, + NMP_GLOBAL_TRACKER_EXTERN_WEAKLY_TRACKED_USER_TAG); } } @@ -9545,25 +9545,25 @@ _routing_rules_sync(NMDevice *self, NMTernary set_mode) extra_rules = klass->get_extra_rules(self); if (extra_rules) { for (i = 0; i < extra_rules->len; i++) { - nmp_route_manager_track_rule( - route_manager, + nmp_global_tracker_track_rule( + global_tracker, NMP_OBJECT_CAST_ROUTING_RULE(extra_rules->pdata[i]), 10, user_tag_2, - NMP_ROUTE_MANAGER_EXTERN_WEAKLY_TRACKED_USER_TAG); + NMP_GLOBAL_TRACKER_EXTERN_WEAKLY_TRACKED_USER_TAG); } } } } - nmp_route_manager_untrack_all(route_manager, user_tag_1, !untrack_only_dirty, TRUE); + nmp_global_tracker_untrack_all(global_tracker, user_tag_1, !untrack_only_dirty, TRUE); if (klass->get_extra_rules) - nmp_route_manager_untrack_all(route_manager, user_tag_2, !untrack_only_dirty, TRUE); + nmp_global_tracker_untrack_all(global_tracker, user_tag_2, !untrack_only_dirty, TRUE); keep_deleted_rules = FALSE; if (set_mode == NM_TERNARY_DEFAULT) { /* when exiting NM, we leave the device up and the rules configured. - * We just call nmp_route_manager_sync() to forget about the synced rules, + * We just call nmp_global_tracker_sync() to forget about the synced rules, * but we don't actually delete them. * * FIXME: that is a problem after restart of NetworkManager, because these @@ -9577,7 +9577,7 @@ _routing_rules_sync(NMDevice *self, NMTernary set_mode) * file and track them after restart again. */ keep_deleted_rules = TRUE; } - nmp_route_manager_sync(route_manager, NMP_OBJECT_TYPE_ROUTING_RULE, keep_deleted_rules); + nmp_global_tracker_sync(global_tracker, NMP_OBJECT_TYPE_ROUTING_RULE, keep_deleted_rules); } static gboolean diff --git a/src/core/nm-l3cfg.c b/src/core/nm-l3cfg.c index 23afa1833e..f70c035cb6 100644 --- a/src/core/nm-l3cfg.c +++ b/src/core/nm-l3cfg.c @@ -3450,15 +3450,16 @@ nm_l3cfg_remove_config_all_dirty(NML3Cfg *self, gconstpointer tag) /*****************************************************************************/ -#define _NODEV_ROUTES_TAG(self, IS_IPv4) ((gconstpointer) (&(&(self)->priv.route_manager)[IS_IPv4])) +#define _NODEV_ROUTES_TAG(self, IS_IPv4) \ + ((gconstpointer) (&(&(self)->priv.global_tracker)[IS_IPv4])) static gboolean _nodev_routes_untrack(NML3Cfg *self, int addr_family) { - return nmp_route_manager_untrack_all(self->priv.route_manager, - _NODEV_ROUTES_TAG(self, NM_IS_IPv4(addr_family)), - FALSE, - TRUE); + return nmp_global_tracker_untrack_all(self->priv.global_tracker, + _NODEV_ROUTES_TAG(self, NM_IS_IPv4(addr_family)), + FALSE, + TRUE); } static void @@ -3478,12 +3479,12 @@ _nodev_routes_sync(NML3Cfg *self, for (i = 0; i < routes_nodev->len; i++) { const NMPObject *obj = routes_nodev->pdata[i]; - if (nmp_route_manager_track(self->priv.route_manager, - obj_type, - NMP_OBJECT_CAST_IP_ROUTE(obj), - 1, - _NODEV_ROUTES_TAG(self, IS_IPv4), - NULL)) + if (nmp_global_tracker_track(self->priv.global_tracker, + obj_type, + NMP_OBJECT_CAST_IP_ROUTE(obj), + 1, + _NODEV_ROUTES_TAG(self, IS_IPv4), + NULL)) changed = TRUE; } @@ -3492,7 +3493,9 @@ out_clear: changed = TRUE; if (changed || commit_type >= NM_L3_CFG_COMMIT_TYPE_REAPPLY) - nmp_route_manager_sync(self->priv.route_manager, NMP_OBJECT_TYPE_IP_ROUTE(IS_IPv4), FALSE); + nmp_global_tracker_sync(self->priv.global_tracker, + NMP_OBJECT_TYPE_IP_ROUTE(IS_IPv4), + FALSE); } /*****************************************************************************/ @@ -4764,7 +4767,8 @@ constructed(GObject *object) self->priv.platform = g_object_ref(nm_netns_get_platform(self->priv.netns)); nm_assert(NM_IS_PLATFORM(self->priv.platform)); - self->priv.route_manager = nmp_route_manager_ref(nm_netns_get_route_manager(self->priv.netns)); + self->priv.global_tracker = + nmp_global_tracker_ref(nm_netns_get_global_tracker(self->priv.netns)); _LOGT("created (netns=" NM_HASH_OBFUSCATE_PTR_FMT ")", NM_HASH_OBFUSCATE_PTR(self->priv.netns)); @@ -4819,13 +4823,13 @@ finalize(GObject *object) nm_assert(c_list_is_empty(&self->priv.p->obj_state_zombie_lst_head)); if (_nodev_routes_untrack(self, AF_INET)) - nmp_route_manager_sync(self->priv.route_manager, NMP_OBJECT_TYPE_IP4_ROUTE, FALSE); + nmp_global_tracker_sync(self->priv.global_tracker, NMP_OBJECT_TYPE_IP4_ROUTE, FALSE); if (_nodev_routes_untrack(self, AF_INET6)) - nmp_route_manager_sync(self->priv.route_manager, NMP_OBJECT_TYPE_IP6_ROUTE, FALSE); + nmp_global_tracker_sync(self->priv.global_tracker, NMP_OBJECT_TYPE_IP6_ROUTE, FALSE); g_clear_object(&self->priv.netns); g_clear_object(&self->priv.platform); - nm_clear_pointer(&self->priv.route_manager, nmp_route_manager_unref); + nm_clear_pointer(&self->priv.global_tracker, nmp_global_tracker_unref); nm_clear_l3cd(&self->priv.p->combined_l3cd_merged); nm_clear_l3cd(&self->priv.p->combined_l3cd_commited); diff --git a/src/core/nm-l3cfg.h b/src/core/nm-l3cfg.h index bead34933e..e0257623eb 100644 --- a/src/core/nm-l3cfg.h +++ b/src/core/nm-l3cfg.h @@ -196,18 +196,18 @@ typedef struct { } NML3ConfigNotifyData; struct _NML3CfgPrivate; -struct _NMPRouteManager; +struct _NMPGlobalTracker; struct _NML3Cfg { GObject parent; struct { - struct _NML3CfgPrivate *p; - NMNetns *netns; - NMPlatform *platform; - struct _NMPRouteManager *route_manager; - const NMPObject *plobj; - const NMPObject *plobj_next; - int ifindex; + struct _NML3CfgPrivate *p; + NMNetns *netns; + NMPlatform *platform; + struct _NMPGlobalTracker *global_tracker; + const NMPObject *plobj; + const NMPObject *plobj_next; + int ifindex; } priv; }; diff --git a/src/core/nm-netns.c b/src/core/nm-netns.c index f120e43d06..774e26bd58 100644 --- a/src/core/nm-netns.c +++ b/src/core/nm-netns.c @@ -22,14 +22,14 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_PLATFORM, ); typedef struct { - NMNetns *_self_signal_user_data; - NMPlatform *platform; - NMPNetns *platform_netns; - NMPRouteManager *route_manager; - GHashTable *l3cfgs; - GHashTable *shared_ips; - CList l3cfg_signal_pending_lst_head; - GSource *signal_pending_idle_source; + NMNetns *_self_signal_user_data; + NMPlatform *platform; + NMPNetns *platform_netns; + NMPGlobalTracker *global_tracker; + GHashTable *l3cfgs; + GHashTable *shared_ips; + CList l3cfg_signal_pending_lst_head; + GSource *signal_pending_idle_source; } NMNetnsPrivate; struct _NMNetns { @@ -79,10 +79,10 @@ nm_netns_get_platform(NMNetns *self) return NM_NETNS_GET_PRIVATE(self)->platform; } -NMPRouteManager * -nm_netns_get_route_manager(NMNetns *self) +NMPGlobalTracker * +nm_netns_get_global_tracker(NMNetns *self) { - return NM_NETNS_GET_PRIVATE(self)->route_manager; + return NM_NETNS_GET_PRIVATE(self)->global_tracker; } NMDedupMultiIndex * @@ -397,14 +397,14 @@ constructed(GObject *object) priv->platform_netns = nm_platform_netns_get(priv->platform); - priv->route_manager = nmp_route_manager_new(priv->platform); + priv->global_tracker = nmp_global_tracker_new(priv->platform); /* Weakly track the default rules with a dummy user-tag. These * rules are always weekly tracked... */ - nmp_route_manager_track_rule_default(priv->route_manager, - AF_UNSPEC, - 0, - nm_netns_parent_class /* static dummy user-tag */); + nmp_global_tracker_track_rule_default(priv->global_tracker, + AF_UNSPEC, + 0, + nm_netns_parent_class /* static dummy user-tag */); /* Also weakly track all existing rules. These were added before NetworkManager * starts, so they are probably none of NetworkManager's business. @@ -414,12 +414,12 @@ constructed(GObject *object) * of NetworkManager, we just don't know. * * For that reason, whenever we will touch such rules later one, we make them - * fully owned and no longer weekly tracked. See %NMP_ROUTE_MANAGER_EXTERN_WEAKLY_TRACKED_USER_TAG. */ - nmp_route_manager_track_rule_from_platform(priv->route_manager, - NULL, - AF_UNSPEC, - 0, - NMP_ROUTE_MANAGER_EXTERN_WEAKLY_TRACKED_USER_TAG); + * fully owned and no longer weekly tracked. See %NMP_GLOBAL_TRACKER_EXTERN_WEAKLY_TRACKED_USER_TAG. */ + nmp_global_tracker_track_rule_from_platform(priv->global_tracker, + NULL, + AF_UNSPEC, + 0, + NMP_GLOBAL_TRACKER_EXTERN_WEAKLY_TRACKED_USER_TAG); G_OBJECT_CLASS(nm_netns_parent_class)->constructed(object); @@ -469,7 +469,7 @@ dispose(GObject *object) g_clear_object(&priv->platform); nm_clear_pointer(&priv->l3cfgs, g_hash_table_unref); - nm_clear_pointer(&priv->route_manager, nmp_route_manager_unref); + nm_clear_pointer(&priv->global_tracker, nmp_global_tracker_unref); G_OBJECT_CLASS(nm_netns_parent_class)->dispose(object); } diff --git a/src/core/nm-netns.h b/src/core/nm-netns.h index deb1d1f006..17c1c63743 100644 --- a/src/core/nm-netns.h +++ b/src/core/nm-netns.h @@ -29,7 +29,7 @@ NMNetns *nm_netns_new(struct _NMPlatform *platform); struct _NMPlatform *nm_netns_get_platform(NMNetns *self); NMPNetns *nm_netns_get_platform_netns(NMNetns *self); -struct _NMPRouteManager *nm_netns_get_route_manager(NMNetns *self); +struct _NMPGlobalTracker *nm_netns_get_global_tracker(NMNetns *self); struct _NMDedupMultiIndex *nm_netns_get_multi_idx(NMNetns *self); diff --git a/src/core/platform/tests/test-route.c b/src/core/platform/tests/test-route.c index 322293e927..e3303e05fc 100644 --- a/src/core/platform/tests/test-route.c +++ b/src/core/platform/tests/test-route.c @@ -1647,8 +1647,8 @@ again: if (TEST_SYNC) { gs_unref_hashtable GHashTable *unique_priorities = g_hash_table_new(NULL, NULL); - nm_auto_unref_route_manager NMPRouteManager *route_manager = - nmp_route_manager_new(platform); + nm_auto_unref_global_tracker NMPGlobalTracker *global_tracker = + nmp_global_tracker_new(platform); gs_unref_ptrarray GPtrArray *objs_sync = NULL; gconstpointer USER_TAG_1 = &platform; gconstpointer USER_TAG_2 = &unique_priorities; @@ -1670,29 +1670,29 @@ again: } for (i = 0; i < objs_sync->len; i++) { - nmp_route_manager_track_rule(route_manager, - NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]), - 1, - USER_TAG_1, - NULL); + nmp_global_tracker_track_rule(global_tracker, + NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]), + 1, + USER_TAG_1, + NULL); if (nmtst_get_rand_bool()) { /* this has no effect, because a negative priority (of same absolute value) * has lower priority than the positive priority above. */ - nmp_route_manager_track_rule(route_manager, - NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]), - -1, - USER_TAG_2, - NULL); + nmp_global_tracker_track_rule(global_tracker, + NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]), + -1, + USER_TAG_2, + NULL); } if (nmtst_get_rand_uint32() % objs_sync->len == 0) { - nmp_route_manager_sync(route_manager, NMP_OBJECT_TYPE_ROUTING_RULE, FALSE); + nmp_global_tracker_sync(global_tracker, NMP_OBJECT_TYPE_ROUTING_RULE, FALSE); g_assert_cmpint(nmtstp_platform_routing_rules_get_count(platform, AF_UNSPEC), ==, i + 1); } } - nmp_route_manager_sync(route_manager, NMP_OBJECT_TYPE_ROUTING_RULE, FALSE); + nmp_global_tracker_sync(global_tracker, NMP_OBJECT_TYPE_ROUTING_RULE, FALSE); g_assert_cmpint(nmtstp_platform_routing_rules_get_count(platform, AF_UNSPEC), ==, objs_sync->len); @@ -1700,37 +1700,37 @@ again: for (i = 0; i < objs_sync->len; i++) { switch (nmtst_get_rand_uint32() % 3) { case 0: - nmp_route_manager_untrack_rule(route_manager, - NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]), - USER_TAG_1); - nmp_route_manager_untrack_rule(route_manager, - NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]), - USER_TAG_1); + nmp_global_tracker_untrack_rule(global_tracker, + NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]), + USER_TAG_1); + nmp_global_tracker_untrack_rule(global_tracker, + NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]), + USER_TAG_1); break; case 1: - nmp_route_manager_track_rule(route_manager, - NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]), - -1, - USER_TAG_1, - NULL); + nmp_global_tracker_track_rule(global_tracker, + NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]), + -1, + USER_TAG_1, + NULL); break; case 2: - nmp_route_manager_track_rule(route_manager, - NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]), - -2, - USER_TAG_2, - NULL); + nmp_global_tracker_track_rule(global_tracker, + NMP_OBJECT_CAST_ROUTING_RULE(objs_sync->pdata[i]), + -2, + USER_TAG_2, + NULL); break; } if (nmtst_get_rand_uint32() % objs_sync->len == 0) { - nmp_route_manager_sync(route_manager, NMP_OBJECT_TYPE_ROUTING_RULE, FALSE); + nmp_global_tracker_sync(global_tracker, NMP_OBJECT_TYPE_ROUTING_RULE, FALSE); g_assert_cmpint(nmtstp_platform_routing_rules_get_count(platform, AF_UNSPEC), ==, objs_sync->len - i - 1); } } - nmp_route_manager_sync(route_manager, NMP_OBJECT_TYPE_ROUTING_RULE, FALSE); + nmp_global_tracker_sync(global_tracker, NMP_OBJECT_TYPE_ROUTING_RULE, FALSE); } else { for (i = 0; i < objs->len;) { diff --git a/src/libnm-platform/nmp-route-manager.c b/src/libnm-platform/nmp-route-manager.c index 842301b1bd..4bf44f2778 100644 --- a/src/libnm-platform/nmp-route-manager.c +++ b/src/libnm-platform/nmp-route-manager.c @@ -13,7 +13,7 @@ /*****************************************************************************/ -struct _NMPRouteManager { +struct _NMPGlobalTracker { NMPlatform *platform; GHashTable *by_obj; GHashTable *by_user_tag; @@ -25,17 +25,17 @@ struct _NMPRouteManager { /*****************************************************************************/ #define _NMLOG_DOMAIN LOGD_PLATFORM -#define _NMLOG_PREFIX_NAME "route-manager" +#define _NMLOG_PREFIX_NAME "global-tracker" #define _NMLOG(level, ...) __NMLOG_DEFAULT(level, LOGD_PLATFORM, _NMLOG_PREFIX_NAME, __VA_ARGS__) /*****************************************************************************/ static gboolean -NMP_IS_ROUTE_MANAGER(gpointer self) +NMP_IS_GLOBAL_TRACKER(gpointer self) { - return self && ((NMPRouteManager *) self)->ref_count > 0 - && NM_IS_PLATFORM(((NMPRouteManager *) self)->platform); + return self && ((NMPGlobalTracker *) self)->ref_count > 0 + && NM_IS_PLATFORM(((NMPGlobalTracker *) self)->platform); } /*****************************************************************************/ @@ -91,13 +91,13 @@ typedef struct { /* indicates whether we configured/removed the rule (during sync()). We need that, so * if the rule gets untracked, that we know to remove/restore it. * - * This makes NMPRouteManager stateful (beyond the configuration that indicates + * This makes NMPGlobalTracker stateful (beyond the configuration that indicates * which rules are tracked). * After a restart, NetworkManager would no longer remember which rules were added * by us. * * That is partially fixed by NetworkManager taking over the rules that it - * actively configures (see %NMP_ROUTE_MANAGER_EXTERN_WEAKLY_TRACKED_USER_TAG). */ + * actively configures (see %NMP_GLOBAL_TRACKER_EXTERN_WEAKLY_TRACKED_USER_TAG). */ ConfigState config_state; } TrackObjData; @@ -108,15 +108,15 @@ typedef struct { /*****************************************************************************/ -static void _track_data_untrack(NMPRouteManager *self, - TrackData *track_data, - gboolean remove_user_tag_data, - gboolean make_owned_by_us); +static void _track_data_untrack(NMPGlobalTracker *self, + TrackData *track_data, + gboolean remove_user_tag_data, + gboolean make_owned_by_us); /*****************************************************************************/ static CList * -_by_obj_lst_head(NMPRouteManager *self, NMPObjectType obj_type) +_by_obj_lst_head(NMPGlobalTracker *self, NMPObjectType obj_type) { G_STATIC_ASSERT(G_N_ELEMENTS(self->by_obj_lst_heads) == 3); @@ -266,8 +266,8 @@ _track_data_lookup(GHashTable *by_data, const NMPObject *obj, gconstpointer user /*****************************************************************************/ /** - * nmp_route_manager_track: - * @self: the #NMPRouteManager instance + * nmp_global_tracker_track: + * @self: the #NMPGlobalTracker instance * @obj_type: the NMPObjectType of @obj that we are tracking. * @obj: the NMPlatformObject (of type NMPObjectType) to track. Usually * a #NMPlatformRoutingRule, #NMPlatformIP4Route or #NMPlatformIP6Route @@ -282,20 +282,20 @@ _track_data_lookup(GHashTable *by_data, const NMPObject *obj, gconstpointer user * @user_tag: the tag associated with tracking this rule. The same tag * must be used to untrack the rule later. * @user_tag_untrack: if not %NULL, at the same time untrack this user-tag - * for the same rule. Note that this is different from a plain nmp_route_manager_untrack_rule(), + * for the same rule. Note that this is different from a plain nmp_global_tracker_untrack_rule(), * because it enforces ownership of the now tracked rule. On the other hand, - * a plain nmp_route_manager_untrack_rule() merely forgets about the tracking. - * The purpose here is to set this to %NMP_ROUTE_MANAGER_EXTERN_WEAKLY_TRACKED_USER_TAG. + * a plain nmp_global_tracker_untrack_rule() merely forgets about the tracking. + * The purpose here is to set this to %NMP_GLOBAL_TRACKER_EXTERN_WEAKLY_TRACKED_USER_TAG. * * Returns: %TRUE, if something changed. */ gboolean -nmp_route_manager_track(NMPRouteManager *self, - NMPObjectType obj_type, - gconstpointer obj, - gint32 track_priority, - gconstpointer user_tag, - gconstpointer user_tag_untrack) +nmp_global_tracker_track(NMPGlobalTracker *self, + NMPObjectType obj_type, + gconstpointer obj, + gint32 track_priority, + gconstpointer user_tag, + gconstpointer user_tag_untrack) { NMPObject obj_stack; const NMPObject *p_obj_stack; @@ -307,7 +307,7 @@ nmp_route_manager_track(NMPRouteManager *self, guint32 track_priority_val; gboolean track_priority_present; - g_return_val_if_fail(NMP_IS_ROUTE_MANAGER(self), FALSE); + g_return_val_if_fail(NMP_IS_GLOBAL_TRACKER(self), FALSE); g_return_val_if_fail(obj, FALSE); g_return_val_if_fail(user_tag, FALSE); @@ -414,15 +414,15 @@ nmp_route_manager_track(NMPRouteManager *self, } static void -_track_data_untrack(NMPRouteManager *self, - TrackData *track_data, - gboolean remove_user_tag_data, - gboolean make_owned_by_us) +_track_data_untrack(NMPGlobalTracker *self, + TrackData *track_data, + gboolean remove_user_tag_data, + gboolean make_owned_by_us) { char sbuf[NM_UTILS_TO_STRING_BUFFER_SIZE]; TrackObjData *obj_data; - nm_assert(NMP_IS_ROUTE_MANAGER(self)); + nm_assert(NMP_IS_GLOBAL_TRACKER(self)); _track_data_assert(track_data, TRUE); nm_assert(self->by_data); nm_assert(g_hash_table_lookup(self->by_data, track_data) == track_data); @@ -467,17 +467,17 @@ _track_data_untrack(NMPRouteManager *self, } gboolean -nmp_route_manager_untrack(NMPRouteManager *self, - NMPObjectType obj_type, - gconstpointer obj, - gconstpointer user_tag) +nmp_global_tracker_untrack(NMPGlobalTracker *self, + NMPObjectType obj_type, + gconstpointer obj, + gconstpointer user_tag) { NMPObject obj_stack; const NMPObject *p_obj_stack; TrackData *track_data; gboolean changed = FALSE; - g_return_val_if_fail(NMP_IS_ROUTE_MANAGER(self), FALSE); + g_return_val_if_fail(NMP_IS_GLOBAL_TRACKER(self), FALSE); nm_assert(NM_IN_SET(obj_type, NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE, @@ -499,12 +499,12 @@ nmp_route_manager_untrack(NMPRouteManager *self, } void -nmp_route_manager_set_dirty(NMPRouteManager *self, gconstpointer user_tag) +nmp_global_tracker_set_dirty(NMPGlobalTracker *self, gconstpointer user_tag) { TrackData *track_data; TrackUserTagData *user_tag_data; - g_return_if_fail(NMP_IS_ROUTE_MANAGER(self)); + g_return_if_fail(NMP_IS_GLOBAL_TRACKER(self)); g_return_if_fail(user_tag); user_tag_data = g_hash_table_lookup(self->by_user_tag, &user_tag); @@ -516,17 +516,17 @@ nmp_route_manager_set_dirty(NMPRouteManager *self, gconstpointer user_tag) } gboolean -nmp_route_manager_untrack_all(NMPRouteManager *self, - gconstpointer user_tag, - gboolean all /* or only dirty */, - gboolean make_survivors_dirty) +nmp_global_tracker_untrack_all(NMPGlobalTracker *self, + gconstpointer user_tag, + gboolean all /* or only dirty */, + gboolean make_survivors_dirty) { TrackData *track_data; TrackData *track_data_safe; TrackUserTagData *user_tag_data; gboolean changed = FALSE; - g_return_val_if_fail(NMP_IS_ROUTE_MANAGER(self), FALSE); + g_return_val_if_fail(NMP_IS_GLOBAL_TRACKER(self), FALSE); g_return_val_if_fail(user_tag, FALSE); user_tag_data = g_hash_table_lookup(self->by_user_tag, &user_tag); @@ -554,7 +554,7 @@ nmp_route_manager_untrack_all(NMPRouteManager *self, /*****************************************************************************/ void -nmp_route_manager_sync(NMPRouteManager *self, NMPObjectType obj_type, gboolean keep_deleted) +nmp_global_tracker_sync(NMPGlobalTracker *self, NMPObjectType obj_type, gboolean keep_deleted) { char sbuf[NM_UTILS_TO_STRING_BUFFER_SIZE]; const NMDedupMultiHeadEntry *pl_head_entry; @@ -567,7 +567,7 @@ nmp_route_manager_sync(NMPRouteManager *self, NMPObjectType obj_type, gboolean k guint i; const TrackData *td_best; - g_return_if_fail(NMP_IS_ROUTE_MANAGER(self)); + g_return_if_fail(NMP_IS_GLOBAL_TRACKER(self)); g_return_if_fail(NM_IN_SET(obj_type, NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE, @@ -677,18 +677,18 @@ nmp_route_manager_sync(NMPRouteManager *self, NMPObjectType obj_type, gboolean k /*****************************************************************************/ void -nmp_route_manager_track_rule_from_platform(NMPRouteManager *self, - NMPlatform *platform, - int addr_family, - gint32 tracking_priority, - gconstpointer user_tag) +nmp_global_tracker_track_rule_from_platform(NMPGlobalTracker *self, + NMPlatform *platform, + int addr_family, + gint32 tracking_priority, + gconstpointer user_tag) { NMPLookup lookup; const NMDedupMultiHeadEntry *head_entry; NMDedupMultiIter iter; const NMPObject *o; - g_return_if_fail(NMP_IS_ROUTE_MANAGER(self)); + g_return_if_fail(NMP_IS_GLOBAL_TRACKER(self)); if (!platform) platform = self->platform; @@ -705,98 +705,98 @@ nmp_route_manager_track_rule_from_platform(NMPRouteManager *self, if (addr_family != AF_UNSPEC && rr->addr_family != addr_family) continue; - nmp_route_manager_track_rule(self, rr, tracking_priority, user_tag, NULL); + nmp_global_tracker_track_rule(self, rr, tracking_priority, user_tag, NULL); } } /*****************************************************************************/ void -nmp_route_manager_track_rule_default(NMPRouteManager *self, - int addr_family, - gint32 track_priority, - gconstpointer user_tag) +nmp_global_tracker_track_rule_default(NMPGlobalTracker *self, + int addr_family, + gint32 track_priority, + gconstpointer user_tag) { - g_return_if_fail(NMP_IS_ROUTE_MANAGER(self)); + g_return_if_fail(NMP_IS_GLOBAL_TRACKER(self)); nm_assert(NM_IN_SET(addr_family, AF_UNSPEC, AF_INET, AF_INET6)); /* track the default rules. See also `man ip-rule`. */ if (NM_IN_SET(addr_family, AF_UNSPEC, AF_INET)) { - nmp_route_manager_track_rule(self, - &((NMPlatformRoutingRule){ - .addr_family = AF_INET, - .priority = 0, - .table = RT_TABLE_LOCAL, - .action = FR_ACT_TO_TBL, - .protocol = RTPROT_KERNEL, - }), - track_priority, - user_tag, - NULL); - nmp_route_manager_track_rule(self, - &((NMPlatformRoutingRule){ - .addr_family = AF_INET, - .priority = 32766, - .table = RT_TABLE_MAIN, - .action = FR_ACT_TO_TBL, - .protocol = RTPROT_KERNEL, - }), - track_priority, - user_tag, - NULL); - nmp_route_manager_track_rule(self, - &((NMPlatformRoutingRule){ - .addr_family = AF_INET, - .priority = 32767, - .table = RT_TABLE_DEFAULT, - .action = FR_ACT_TO_TBL, - .protocol = RTPROT_KERNEL, - }), - track_priority, - user_tag, - NULL); + nmp_global_tracker_track_rule(self, + &((NMPlatformRoutingRule){ + .addr_family = AF_INET, + .priority = 0, + .table = RT_TABLE_LOCAL, + .action = FR_ACT_TO_TBL, + .protocol = RTPROT_KERNEL, + }), + track_priority, + user_tag, + NULL); + nmp_global_tracker_track_rule(self, + &((NMPlatformRoutingRule){ + .addr_family = AF_INET, + .priority = 32766, + .table = RT_TABLE_MAIN, + .action = FR_ACT_TO_TBL, + .protocol = RTPROT_KERNEL, + }), + track_priority, + user_tag, + NULL); + nmp_global_tracker_track_rule(self, + &((NMPlatformRoutingRule){ + .addr_family = AF_INET, + .priority = 32767, + .table = RT_TABLE_DEFAULT, + .action = FR_ACT_TO_TBL, + .protocol = RTPROT_KERNEL, + }), + track_priority, + user_tag, + NULL); } if (NM_IN_SET(addr_family, AF_UNSPEC, AF_INET6)) { - nmp_route_manager_track_rule(self, - &((NMPlatformRoutingRule){ - .addr_family = AF_INET6, - .priority = 0, - .table = RT_TABLE_LOCAL, - .action = FR_ACT_TO_TBL, - .protocol = RTPROT_KERNEL, - }), - track_priority, - user_tag, - NULL); - nmp_route_manager_track_rule(self, - &((NMPlatformRoutingRule){ - .addr_family = AF_INET6, - .priority = 32766, - .table = RT_TABLE_MAIN, - .action = FR_ACT_TO_TBL, - .protocol = RTPROT_KERNEL, - }), - track_priority, - user_tag, - NULL); + nmp_global_tracker_track_rule(self, + &((NMPlatformRoutingRule){ + .addr_family = AF_INET6, + .priority = 0, + .table = RT_TABLE_LOCAL, + .action = FR_ACT_TO_TBL, + .protocol = RTPROT_KERNEL, + }), + track_priority, + user_tag, + NULL); + nmp_global_tracker_track_rule(self, + &((NMPlatformRoutingRule){ + .addr_family = AF_INET6, + .priority = 32766, + .table = RT_TABLE_MAIN, + .action = FR_ACT_TO_TBL, + .protocol = RTPROT_KERNEL, + }), + track_priority, + user_tag, + NULL); } } /*****************************************************************************/ -NMPRouteManager * -nmp_route_manager_new(NMPlatform *platform) +NMPGlobalTracker * +nmp_global_tracker_new(NMPlatform *platform) { - NMPRouteManager *self; + NMPGlobalTracker *self; g_return_val_if_fail(NM_IS_PLATFORM(platform), NULL); G_STATIC_ASSERT_EXPR(G_STRUCT_OFFSET(TrackUserTagData, user_tag) == 0); - self = g_slice_new(NMPRouteManager); - *self = (NMPRouteManager){ + self = g_slice_new(NMPGlobalTracker); + *self = (NMPGlobalTracker){ .ref_count = 1, .platform = g_object_ref(platform), .by_data = @@ -816,19 +816,19 @@ nmp_route_manager_new(NMPlatform *platform) return self; } -NMPRouteManager * -nmp_route_manager_ref(NMPRouteManager *self) +NMPGlobalTracker * +nmp_global_tracker_ref(NMPGlobalTracker *self) { - g_return_val_if_fail(NMP_IS_ROUTE_MANAGER(self), NULL); + g_return_val_if_fail(NMP_IS_GLOBAL_TRACKER(self), NULL); self->ref_count++; return self; } void -nmp_route_manager_unref(NMPRouteManager *self) +nmp_global_tracker_unref(NMPGlobalTracker *self) { - g_return_if_fail(NMP_IS_ROUTE_MANAGER(self)); + g_return_if_fail(NMP_IS_GLOBAL_TRACKER(self)); if (--self->ref_count > 0) return; diff --git a/src/libnm-platform/nmp-route-manager.h b/src/libnm-platform/nmp-route-manager.h index 97ec3840df..61a4c1eb58 100644 --- a/src/libnm-platform/nmp-route-manager.h +++ b/src/libnm-platform/nmp-route-manager.h @@ -1,79 +1,79 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ -#ifndef __NMP_ROUTE_MANAGER_H__ -#define __NMP_ROUTE_MANAGER_H__ +#ifndef __NMP_GLOBAL_TRACKER_H__ +#define __NMP_GLOBAL_TRACKER_H__ #include "nm-platform.h" /*****************************************************************************/ -#define NMP_ROUTE_MANAGER_EXTERN_WEAKLY_TRACKED_USER_TAG ((const void *) nmp_route_manager_new) +#define NMP_GLOBAL_TRACKER_EXTERN_WEAKLY_TRACKED_USER_TAG ((const void *) nmp_global_tracker_new) -typedef struct _NMPRouteManager NMPRouteManager; +typedef struct _NMPGlobalTracker NMPGlobalTracker; -NMPRouteManager *nmp_route_manager_new(NMPlatform *platform); +NMPGlobalTracker *nmp_global_tracker_new(NMPlatform *platform); -NMPRouteManager *nmp_route_manager_ref(NMPRouteManager *self); -void nmp_route_manager_unref(NMPRouteManager *self); +NMPGlobalTracker *nmp_global_tracker_ref(NMPGlobalTracker *self); +void nmp_global_tracker_unref(NMPGlobalTracker *self); -#define nm_auto_unref_route_manager nm_auto(_nmp_route_manager_unref) -NM_AUTO_DEFINE_FCN0(NMPRouteManager *, _nmp_route_manager_unref, nmp_route_manager_unref); +#define nm_auto_unref_global_tracker nm_auto(_nmp_global_tracker_unref) +NM_AUTO_DEFINE_FCN0(NMPGlobalTracker *, _nmp_global_tracker_unref, nmp_global_tracker_unref); -gboolean nmp_route_manager_track(NMPRouteManager *self, - NMPObjectType obj_type, - gconstpointer obj, - gint32 track_priority, - gconstpointer user_tag, - gconstpointer user_tag_untrack); +gboolean nmp_global_tracker_track(NMPGlobalTracker *self, + NMPObjectType obj_type, + gconstpointer obj, + gint32 track_priority, + gconstpointer user_tag, + gconstpointer user_tag_untrack); static inline gboolean -nmp_route_manager_track_rule(NMPRouteManager *self, - const NMPlatformRoutingRule *routing_rule, - gint32 track_priority, - gconstpointer user_tag, - gconstpointer user_tag_untrack) +nmp_global_tracker_track_rule(NMPGlobalTracker *self, + const NMPlatformRoutingRule *routing_rule, + gint32 track_priority, + gconstpointer user_tag, + gconstpointer user_tag_untrack) { - return nmp_route_manager_track(self, - NMP_OBJECT_TYPE_ROUTING_RULE, - routing_rule, - track_priority, - user_tag, - user_tag_untrack); + return nmp_global_tracker_track(self, + NMP_OBJECT_TYPE_ROUTING_RULE, + routing_rule, + track_priority, + user_tag, + user_tag_untrack); } -void nmp_route_manager_track_rule_default(NMPRouteManager *self, - int addr_family, - gint32 track_priority, - gconstpointer user_tag); +void nmp_global_tracker_track_rule_default(NMPGlobalTracker *self, + int addr_family, + gint32 track_priority, + gconstpointer user_tag); -void nmp_route_manager_track_rule_from_platform(NMPRouteManager *self, - NMPlatform *platform, - int addr_family, - gint32 tracking_priority, - gconstpointer user_tag); +void nmp_global_tracker_track_rule_from_platform(NMPGlobalTracker *self, + NMPlatform *platform, + int addr_family, + gint32 tracking_priority, + gconstpointer user_tag); -gboolean nmp_route_manager_untrack(NMPRouteManager *self, - NMPObjectType obj_type, - gconstpointer obj, - gconstpointer user_tag); +gboolean nmp_global_tracker_untrack(NMPGlobalTracker *self, + NMPObjectType obj_type, + gconstpointer obj, + gconstpointer user_tag); static inline gboolean -nmp_route_manager_untrack_rule(NMPRouteManager *self, - const NMPlatformRoutingRule *routing_rule, - gconstpointer user_tag) +nmp_global_tracker_untrack_rule(NMPGlobalTracker *self, + const NMPlatformRoutingRule *routing_rule, + gconstpointer user_tag) { - return nmp_route_manager_untrack(self, NMP_OBJECT_TYPE_ROUTING_RULE, routing_rule, user_tag); + return nmp_global_tracker_untrack(self, NMP_OBJECT_TYPE_ROUTING_RULE, routing_rule, user_tag); } -void nmp_route_manager_set_dirty(NMPRouteManager *self, gconstpointer user_tag); +void nmp_global_tracker_set_dirty(NMPGlobalTracker *self, gconstpointer user_tag); -gboolean nmp_route_manager_untrack_all(NMPRouteManager *self, - gconstpointer user_tag, - gboolean all /* or only dirty */, - gboolean make_survivors_dirty); +gboolean nmp_global_tracker_untrack_all(NMPGlobalTracker *self, + gconstpointer user_tag, + gboolean all /* or only dirty */, + gboolean make_survivors_dirty); -void nmp_route_manager_sync(NMPRouteManager *self, NMPObjectType obj_type, gboolean keep_deleted); +void nmp_global_tracker_sync(NMPGlobalTracker *self, NMPObjectType obj_type, gboolean keep_deleted); /*****************************************************************************/ -#endif /* __NMP_ROUTE_MANAGER_H__ */ +#endif /* __NMP_GLOBAL_TRACKER_H__ */ From d3c9bb46669de701c0fac54d73e438eb77513784 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 18 Jul 2022 10:07:21 +0200 Subject: [PATCH 10/12] platform: rename file "nmp-route-manager.[hc]" to "nmp-global-tracker.[hc]" --- Makefile.am | 4 ++-- src/core/devices/nm-device-wireguard.c | 2 +- src/core/devices/nm-device.c | 2 +- src/core/nm-l3cfg.c | 2 +- src/core/nm-netns.c | 2 +- src/core/platform/tests/test-route.c | 2 +- src/libnm-platform/meson.build | 2 +- .../{nmp-route-manager.c => nmp-global-tracker.c} | 2 +- .../{nmp-route-manager.h => nmp-global-tracker.h} | 0 9 files changed, 9 insertions(+), 9 deletions(-) rename src/libnm-platform/{nmp-route-manager.c => nmp-global-tracker.c} (99%) rename src/libnm-platform/{nmp-route-manager.h => nmp-global-tracker.h} (100%) diff --git a/Makefile.am b/Makefile.am index f4b892e96c..762e229b86 100644 --- a/Makefile.am +++ b/Makefile.am @@ -604,12 +604,12 @@ src_libnm_platform_libnm_platform_la_SOURCES = \ src/libnm-platform/nm-platform.c \ src/libnm-platform/nm-platform.h \ src/libnm-platform/nmp-base.h \ + src/libnm-platform/nmp-global-tracker.c \ + src/libnm-platform/nmp-global-tracker.h \ src/libnm-platform/nmp-netns.c \ src/libnm-platform/nmp-netns.h \ src/libnm-platform/nmp-object.c \ src/libnm-platform/nmp-object.h \ - src/libnm-platform/nmp-route-manager.c \ - src/libnm-platform/nmp-route-manager.h \ src/libnm-platform/wifi/nm-wifi-utils-nl80211.c \ src/libnm-platform/wifi/nm-wifi-utils-nl80211.h \ src/libnm-platform/wifi/nm-wifi-utils-private.h \ diff --git a/src/core/devices/nm-device-wireguard.c b/src/core/devices/nm-device-wireguard.c index bdb96cb298..179c2a22a5 100644 --- a/src/core/devices/nm-device-wireguard.c +++ b/src/core/devices/nm-device-wireguard.c @@ -18,7 +18,7 @@ #include "nm-device-private.h" #include "libnm-platform/nm-platform.h" #include "libnm-platform/nmp-object.h" -#include "libnm-platform/nmp-route-manager.h" +#include "libnm-platform/nmp-global-tracker.h" #include "nm-device-factory.h" #include "nm-active-connection.h" #include "nm-act-request.h" diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c index 915c40eea0..f2de8c9c89 100644 --- a/src/core/devices/nm-device.c +++ b/src/core/devices/nm-device.c @@ -41,7 +41,7 @@ #include "libnm-platform/nm-platform.h" #include "libnm-platform/nm-platform-utils.h" #include "libnm-platform/nmp-object.h" -#include "libnm-platform/nmp-route-manager.h" +#include "libnm-platform/nmp-global-tracker.h" #include "ndisc/nm-ndisc.h" #include "ndisc/nm-lndp-ndisc.h" diff --git a/src/core/nm-l3cfg.c b/src/core/nm-l3cfg.c index f70c035cb6..839aacb853 100644 --- a/src/core/nm-l3cfg.c +++ b/src/core/nm-l3cfg.c @@ -12,7 +12,7 @@ #include "libnm-glib-aux/nm-time-utils.h" #include "libnm-platform/nm-platform.h" #include "libnm-platform/nmp-object.h" -#include "libnm-platform/nmp-route-manager.h" +#include "libnm-platform/nmp-global-tracker.h" #include "nm-netns.h" #include "n-acd/src/n-acd.h" #include "nm-l3-ipv4ll.h" diff --git a/src/core/nm-netns.c b/src/core/nm-netns.c index 774e26bd58..5ee6315292 100644 --- a/src/core/nm-netns.c +++ b/src/core/nm-netns.c @@ -15,7 +15,7 @@ #include "nm-l3cfg.h" #include "libnm-platform/nm-platform.h" #include "libnm-platform/nmp-netns.h" -#include "libnm-platform/nmp-route-manager.h" +#include "libnm-platform/nmp-global-tracker.h" /*****************************************************************************/ diff --git a/src/core/platform/tests/test-route.c b/src/core/platform/tests/test-route.c index e3303e05fc..f0142fcb5f 100644 --- a/src/core/platform/tests/test-route.c +++ b/src/core/platform/tests/test-route.c @@ -10,7 +10,7 @@ #include "nm-core-utils.h" #include "libnm-platform/nm-platform-utils.h" -#include "libnm-platform/nmp-route-manager.h" +#include "libnm-platform/nmp-global-tracker.h" #include "test-common.h" diff --git a/src/libnm-platform/meson.build b/src/libnm-platform/meson.build index d0a7c6c20e..e273046f10 100644 --- a/src/libnm-platform/meson.build +++ b/src/libnm-platform/meson.build @@ -7,9 +7,9 @@ libnm_platform = static_library( 'nm-netlink.c', 'nm-platform-utils.c', 'nm-platform.c', + 'nmp-global-tracker.c', 'nmp-netns.c', 'nmp-object.c', - 'nmp-route-manager.c', 'wifi/nm-wifi-utils-nl80211.c', 'wifi/nm-wifi-utils.c', 'wpan/nm-wpan-utils.c', diff --git a/src/libnm-platform/nmp-route-manager.c b/src/libnm-platform/nmp-global-tracker.c similarity index 99% rename from src/libnm-platform/nmp-route-manager.c rename to src/libnm-platform/nmp-global-tracker.c index 4bf44f2778..f4e5606429 100644 --- a/src/libnm-platform/nmp-route-manager.c +++ b/src/libnm-platform/nmp-global-tracker.c @@ -2,7 +2,7 @@ #include "libnm-glib-aux/nm-default-glib-i18n-lib.h" -#include "nmp-route-manager.h" +#include "nmp-global-tracker.h" #include #include diff --git a/src/libnm-platform/nmp-route-manager.h b/src/libnm-platform/nmp-global-tracker.h similarity index 100% rename from src/libnm-platform/nmp-route-manager.h rename to src/libnm-platform/nmp-global-tracker.h From 766349879ed2d822fca12a7b38426a3a418aad54 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 26 Jul 2022 12:55:15 +0200 Subject: [PATCH 11/12] platform/trivial: add code comments for NMPGlobalTracker --- src/libnm-platform/nmp-global-tracker.c | 57 +++++++++++++++++++------ 1 file changed, 44 insertions(+), 13 deletions(-) diff --git a/src/libnm-platform/nmp-global-tracker.c b/src/libnm-platform/nmp-global-tracker.c index f4e5606429..dd3df38d80 100644 --- a/src/libnm-platform/nmp-global-tracker.c +++ b/src/libnm-platform/nmp-global-tracker.c @@ -13,6 +13,36 @@ /*****************************************************************************/ +/* NMPGlobalTracker tracks certain objects for the entire network namespace and can + * commit them. + * + * We tend to configure things per-interface and per-profile. In many cases, + * we thereby only need to care about the things for that interface. For example, + * we can configure IP addresses and (unicast) routes without having a system wide + * view. That is mainly, because such objects are themselves tied to an ifindex. + * + * However, for certain objects that's not the case. For example, policy routing + * rules, certain route types (blackhole, unavailable, prohibit, throw) and MPTCP + * endpoints require a holistic view of the system. That is, because rules and + * these route types have no ifindex. For MPTCP endpoints, they have an ifindex, + * however we can only configure a small number of them at a time, so we need a + * central (global) instance that can track which endpoints to configure. + * + * In general, the NMPGlobalTracker tracks objects for the entire namespace, and + * it's sync() method will figure out how to configure them. + * + * Since the users of NMPGloablTracker (NML3Cfg, NMDevice) themselves don't + * have this holistic view, the API of NMPGlobalTracker allows them to track + * individual objects independently (they register their objects for a private + * user-tag). If multiple such independent users track the same object, the tracking + * priority (track_priority_val) determines which one wins. + * + * NMPGlobalTracker can not only track whether an object should be present, + * it also can track whether it should be absent. See track_priority_present. + */ + +/*****************************************************************************/ + struct _NMPGlobalTracker { NMPlatform *platform; GHashTable *by_obj; @@ -46,19 +76,20 @@ typedef struct { CList obj_lst; CList user_tag_lst; - /* track_priority_val zero is special: those are weakly tracked rules. + /* @track_priority_val zero is special: those are weakly tracked objects. * That means: NetworkManager will restore them only if it removed them earlier. * But it will not remove or add them otherwise. * - * Otherwise, the track_priority_val goes together with track_priority_present. - * In case of one rule being tracked multiple times (with different priorities), + * Otherwise, @track_priority_val goes together with @track_priority_present. + * In case of one object being tracked multiple times (with different priorities), * the one with higher priority wins. See _track_obj_data_get_best_data(). * Then, the winning present state either enforces that the rule is present * or absent. * - * If a rules is not tracked at all, it is ignored by NetworkManager. Assuming - * that it was added externally by the user. But unlike weakly tracked rules, - * NM will *not* restore such rules if NetworkManager themself removed them. */ + * If an object is not tracked at all, it is ignored by NetworkManager (except + * for MPTCP endpoints for the tracked interface). Assuming that it was added + * externally by the user. But unlike weakly tracked rules, NM will *not* restore + * such rules if NetworkManager themself removed them. */ guint32 track_priority_val; bool track_priority_present : 1; @@ -70,9 +101,9 @@ typedef enum { CONFIG_STATE_ADDED_BY_US = 1, CONFIG_STATE_REMOVED_BY_US = 2, - /* ConfigState encodes whether the rule was touched by us at all (CONFIG_STATE_NONE). + /* ConfigState encodes whether the object was touched by us at all (CONFIG_STATE_NONE). * - * Maybe we would only need to track whether we touched the rule at all. But we + * Maybe we would only need to track whether we touched the object at all. But we * track it more in detail what we did: did we add it (CONFIG_STATE_ADDED_BY_US) * or did we remove it (CONFIG_STATE_REMOVED_BY_US)? * Finally, we need CONFIG_STATE_OWNED_BY_US, which means that we didn't actively @@ -88,15 +119,15 @@ typedef struct { CList by_obj_lst; - /* indicates whether we configured/removed the rule (during sync()). We need that, so - * if the rule gets untracked, that we know to remove/restore it. + /* indicates whether we configured/removed the object (during sync()). We need that, so + * if the object gets untracked, that we know to remove/restore it. * * This makes NMPGlobalTracker stateful (beyond the configuration that indicates - * which rules are tracked). - * After a restart, NetworkManager would no longer remember which rules were added + * which objects are tracked). + * After a restart, NetworkManager would no longer remember which objects were added * by us. * - * That is partially fixed by NetworkManager taking over the rules that it + * That is partially fixed by NetworkManager taking over the objects that it * actively configures (see %NMP_GLOBAL_TRACKER_EXTERN_WEAKLY_TRACKED_USER_TAG). */ ConfigState config_state; } TrackObjData; From 0b9384187b89bd8ef1f42761a8ce81f417eff140 Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Mon, 25 Jul 2022 17:47:11 +0200 Subject: [PATCH 12/12] platform: fix identity for MPTCP NMPObject to honor port --- src/libnm-platform/nmp-object.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libnm-platform/nmp-object.c b/src/libnm-platform/nmp-object.c index eb5306a66d..edccef3373 100644 --- a/src/libnm-platform/nmp-object.c +++ b/src/libnm-platform/nmp-object.c @@ -1564,6 +1564,8 @@ _vt_cmd_plobj_id_cmp(mptcp_addr, NMPlatformMptcpAddr, { * for instances which are not "in_kernel". While we might receive unexpected values * from kernel, we should not create them for internal purposes. */ NM_CMP_FIELD_MEMCMP_LEN(obj1, obj2, addr, nm_utils_addr_family_to_size(obj1->addr_family)); + + NM_CMP_FIELD(obj1, obj2, port); } }); @@ -1657,7 +1659,7 @@ _vt_cmd_plobj_id_hash_update(mptcp_addr, NMPlatformMptcpAddr, { nm_hash_update_val(h, obj->id); } else { /* _vt_cmd_plobj_id_cmp_mptcp_addr for why. */ - nm_hash_update_vals(h, obj->id, obj->addr_family); + nm_hash_update_vals(h, obj->id, obj->addr_family, obj->port); nm_hash_update(h, &obj->addr, nm_utils_addr_family_to_size(obj->addr_family)); } });