From 864e4e6369397f6cbface423773e24ff6c774dd2 Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Fri, 17 Sep 2021 17:32:57 +0200 Subject: [PATCH] platform: allow disabling caching of tc objects Introduce a construct-only property for platform objects to enable or disable the caching of tc objects. When disabled, the netlink socket doesn't receive netlink events for tc objects, and objects are never added to the cache. This commit doesn't change behavior yet. --- src/core/NetworkManagerUtils.c | 2 +- src/core/platform/tests/test-link.c | 12 ++++----- .../platform/tests/test-platform-general.c | 4 +-- src/libnm-platform/nm-linux-platform.c | 25 ++++++++++++++----- src/libnm-platform/nm-linux-platform.h | 2 +- src/libnm-platform/nm-platform.c | 21 ++++++++++++++++ src/libnm-platform/nm-platform.h | 2 ++ 7 files changed, 52 insertions(+), 16 deletions(-) diff --git a/src/core/NetworkManagerUtils.c b/src/core/NetworkManagerUtils.c index 04e7ef5500..69b8d83ab4 100644 --- a/src/core/NetworkManagerUtils.c +++ b/src/core/NetworkManagerUtils.c @@ -1709,5 +1709,5 @@ nm_platform_get() void nm_linux_platform_setup(void) { - nm_platform_setup(nm_linux_platform_new(FALSE, FALSE)); + nm_platform_setup(nm_linux_platform_new(FALSE, FALSE, TRUE)); } diff --git a/src/core/platform/tests/test-link.c b/src/core/platform/tests/test-link.c index 394274daf3..24e3fd999d 100644 --- a/src/core/platform/tests/test-link.c +++ b/src/core/platform/tests/test-link.c @@ -2751,7 +2751,7 @@ _test_netns_create_platform(void) netns = nmp_netns_new(); g_assert(NMP_IS_NETNS(netns)); - platform = nm_linux_platform_new(TRUE, TRUE); + platform = nm_linux_platform_new(TRUE, TRUE, TRUE); g_assert(NM_IS_LINUX_PLATFORM(platform)); nmp_netns_pop(netns); @@ -2840,7 +2840,7 @@ test_netns_general(gpointer fixture, gconstpointer test_data) if (_check_sysctl_skip()) return; - platform_1 = nm_linux_platform_new(TRUE, TRUE); + platform_1 = nm_linux_platform_new(TRUE, TRUE, TRUE); platform_2 = _test_netns_create_platform(); /* add some dummy devices. The "other-*" devices are there to bump the ifindex */ @@ -2968,7 +2968,7 @@ test_netns_set_netns(gpointer fixture, gconstpointer test_data) if (_test_netns_check_skip()) return; - platforms[0] = platform_0 = nm_linux_platform_new(TRUE, TRUE); + platforms[0] = platform_0 = nm_linux_platform_new(TRUE, TRUE, TRUE); platforms[1] = platform_1 = _test_netns_create_platform(); platforms[2] = platform_2 = _test_netns_create_platform(); @@ -3067,7 +3067,7 @@ test_netns_push(gpointer fixture, gconstpointer test_data) if (_check_sysctl_skip()) return; - pl[0].platform = platform_0 = nm_linux_platform_new(TRUE, TRUE); + pl[0].platform = platform_0 = nm_linux_platform_new(TRUE, TRUE, TRUE); pl[1].platform = platform_1 = _test_netns_create_platform(); pl[2].platform = platform_2 = _test_netns_create_platform(); @@ -3214,7 +3214,7 @@ test_netns_bind_to_path(gpointer fixture, gconstpointer test_data) if (_test_netns_check_skip()) return; - platforms[0] = platform_0 = nm_linux_platform_new(TRUE, TRUE); + platforms[0] = platform_0 = nm_linux_platform_new(TRUE, TRUE, TRUE); platforms[1] = platform_1 = _test_netns_create_platform(); platforms[2] = platform_2 = _test_netns_create_platform(); @@ -3379,7 +3379,7 @@ test_sysctl_netns_switch(void) if (_test_netns_check_skip()) return; - platforms[0] = platform_0 = nm_linux_platform_new(TRUE, TRUE); + platforms[0] = platform_0 = nm_linux_platform_new(TRUE, TRUE, TRUE); platforms[1] = platform_1 = _test_netns_create_platform(); platforms[2] = platform_2 = _test_netns_create_platform(); PL = platforms[nmtst_get_rand_uint32() % 3]; diff --git a/src/core/platform/tests/test-platform-general.c b/src/core/platform/tests/test-platform-general.c index 8474e0427d..8ffd92b5a5 100644 --- a/src/core/platform/tests/test-platform-general.c +++ b/src/core/platform/tests/test-platform-general.c @@ -31,7 +31,7 @@ test_init_linux_platform(void) { gs_unref_object NMPlatform *platform = NULL; - platform = nm_linux_platform_new(TRUE, NM_PLATFORM_NETNS_SUPPORT_DEFAULT); + platform = nm_linux_platform_new(TRUE, NM_PLATFORM_NETNS_SUPPORT_DEFAULT, TRUE); } /*****************************************************************************/ @@ -42,7 +42,7 @@ test_link_get_all(void) gs_unref_object NMPlatform *platform = NULL; gs_unref_ptrarray GPtrArray *links = NULL; - platform = nm_linux_platform_new(TRUE, NM_PLATFORM_NETNS_SUPPORT_DEFAULT); + platform = nm_linux_platform_new(TRUE, NM_PLATFORM_NETNS_SUPPORT_DEFAULT, TRUE); links = nm_platform_link_get_all(platform, TRUE); } diff --git a/src/libnm-platform/nm-linux-platform.c b/src/libnm-platform/nm-linux-platform.c index a1c03c7dbe..4ea545a434 100644 --- a/src/libnm-platform/nm-linux-platform.c +++ b/src/libnm-platform/nm-linux-platform.c @@ -3880,6 +3880,9 @@ _new_from_nl_qdisc(NMPlatform *platform, struct nlmsghdr *nlh, gboolean id_only) const struct tcmsg *tcm; nm_auto_nmpobj NMPObject *obj = NULL; + if (!nm_platform_get_cache_tc(platform)) + return NULL; + if (nlmsg_parse_arr(nlh, sizeof(*tcm), tb, policy) < 0) return NULL; @@ -3980,7 +3983,7 @@ _new_from_nl_qdisc(NMPlatform *platform, struct nlmsghdr *nlh, gboolean id_only) } static NMPObject * -_new_from_nl_tfilter(struct nlmsghdr *nlh, gboolean id_only) +_new_from_nl_tfilter(NMPlatform *platform, struct nlmsghdr *nlh, gboolean id_only) { static const struct nla_policy policy[] = { [TCA_KIND] = {.type = NLA_STRING}, @@ -3989,6 +3992,9 @@ _new_from_nl_tfilter(struct nlmsghdr *nlh, gboolean id_only) NMPObject * obj = NULL; const struct tcmsg *tcm; + if (!nm_platform_get_cache_tc(platform)) + return NULL; + if (nlmsg_parse_arr(nlh, sizeof(*tcm), tb, policy) < 0) return NULL; @@ -4059,7 +4065,7 @@ nmp_object_new_from_nl(NMPlatform * platform, case RTM_NEWTFILTER: case RTM_DELTFILTER: case RTM_GETTFILTER: - return _new_from_nl_tfilter(msghdr, id_only); + return _new_from_nl_tfilter(platform, msghdr, id_only); default: return NULL; } @@ -9466,7 +9472,7 @@ constructed(GObject *_object) priv->udev_client = nm_udev_client_new(NM_MAKE_STRV("net"), handle_udev_event, platform); } - _LOGD("create (%s netns, %s, %s udev)", + _LOGD("create (%s netns, %s, %s udev, %s tc-cache)", !platform->_netns ? "ignore" : "use", !platform->_netns && nmp_netns_is_initial() ? "initial netns" @@ -9477,7 +9483,8 @@ constructed(GObject *_object) nmp_netns_get_current(), nmp_netns_get_current() == nmp_netns_get_initial() ? "/main" : "")), - nm_platform_get_use_udev(platform) ? "use" : "no"); + nm_platform_get_use_udev(platform) ? "use" : "no", + nm_platform_get_cache_tc(platform) ? "use" : "no"); priv->genl = nl_socket_alloc(); g_assert(priv->genl); @@ -9523,10 +9530,14 @@ constructed(GObject *_object) RTNLGRP_IPV6_IFADDR, RTNLGRP_IPV6_ROUTE, RTNLGRP_LINK, - RTNLGRP_TC, 0); g_assert(!nle); + if (nm_platform_get_cache_tc(platform)) { + nle = nl_socket_add_memberships(priv->nlh, RTNLGRP_TC, 0); + nm_assert(!nle); + } + fd = nl_socket_get_fd(priv->nlh); _LOGD("Netlink socket for events established: port=%u, fd=%d", @@ -9610,7 +9621,7 @@ path_is_read_only_fs(const char *path) } NMPlatform * -nm_linux_platform_new(gboolean log_with_ptr, gboolean netns_support) +nm_linux_platform_new(gboolean log_with_ptr, gboolean netns_support, gboolean cache_tc) { gboolean use_udev = FALSE; @@ -9624,6 +9635,8 @@ nm_linux_platform_new(gboolean log_with_ptr, gboolean netns_support) use_udev, NM_PLATFORM_NETNS_SUPPORT, netns_support, + NM_PLATFORM_CACHE_TC, + cache_tc, NULL); } diff --git a/src/libnm-platform/nm-linux-platform.h b/src/libnm-platform/nm-linux-platform.h index 26c31e3e4c..85e0693424 100644 --- a/src/libnm-platform/nm-linux-platform.h +++ b/src/libnm-platform/nm-linux-platform.h @@ -23,6 +23,6 @@ typedef struct _NMLinuxPlatformClass NMLinuxPlatformClass; GType nm_linux_platform_get_type(void); -NMPlatform *nm_linux_platform_new(gboolean log_with_ptr, gboolean netns_support); +NMPlatform *nm_linux_platform_new(gboolean log_with_ptr, gboolean netns_support, gboolean cache_tc); #endif /* __NETWORKMANAGER_LINUX_PLATFORM_H__ */ diff --git a/src/libnm-platform/nm-platform.c b/src/libnm-platform/nm-platform.c index 0426172d4c..0a7b4458b6 100644 --- a/src/libnm-platform/nm-platform.c +++ b/src/libnm-platform/nm-platform.c @@ -176,12 +176,14 @@ enum { PROP_NETNS_SUPPORT, PROP_USE_UDEV, PROP_LOG_WITH_PTR, + PROP_CACHE_TC, LAST_PROP, }; typedef struct _NMPlatformPrivate { bool use_udev : 1; bool log_with_ptr : 1; + bool cache_tc : 1; guint ip4_dev_route_blacklist_check_id; guint ip4_dev_route_blacklist_gc_timeout_id; @@ -212,6 +214,12 @@ nm_platform_get_log_with_ptr(NMPlatform *self) return NM_PLATFORM_GET_PRIVATE(self)->log_with_ptr; } +gboolean +nm_platform_get_cache_tc(NMPlatform *self) +{ + return NM_PLATFORM_GET_PRIVATE(self)->cache_tc; +} + /*****************************************************************************/ guint @@ -8861,6 +8869,10 @@ set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *ps /* construct-only */ priv->log_with_ptr = g_value_get_boolean(value); break; + case PROP_CACHE_TC: + /* construct-only */ + priv->cache_tc = g_value_get_boolean(value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); break; @@ -8946,6 +8958,15 @@ nm_platform_class_init(NMPlatformClass *platform_class) TRUE, G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property( + object_class, + PROP_CACHE_TC, + g_param_spec_boolean(NM_PLATFORM_CACHE_TC, + "", + "", + FALSE, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + #define SIGNAL(signal, signal_id, method) \ G_STMT_START \ { \ diff --git a/src/libnm-platform/nm-platform.h b/src/libnm-platform/nm-platform.h index f41cf7cb24..a13f921dc7 100644 --- a/src/libnm-platform/nm-platform.h +++ b/src/libnm-platform/nm-platform.h @@ -25,6 +25,7 @@ #define NM_PLATFORM_NETNS_SUPPORT "netns-support" #define NM_PLATFORM_USE_UDEV "use-udev" #define NM_PLATFORM_LOG_WITH_PTR "log-with-ptr" +#define NM_PLATFORM_CACHE_TC "cache-tc" /*****************************************************************************/ @@ -1449,6 +1450,7 @@ nm_platform_route_type_uncoerce(guint8 type_coerced) 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); NMPNetns *nm_platform_netns_get(NMPlatform *self); gboolean nm_platform_netns_push(NMPlatform *self, NMPNetns **netns);