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.
This commit is contained in:
Beniamino Galvani 2021-09-17 17:32:57 +02:00
parent c896973deb
commit 864e4e6369
7 changed files with 52 additions and 16 deletions

View file

@ -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));
}

View file

@ -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];

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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__ */

View file

@ -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 \
{ \

View file

@ -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);