summaryrefslogtreecommitdiffstats
path: root/net/netlink
diff options
context:
space:
mode:
authorJakub Kicinski <kuba@kernel.org>2024-02-16 02:49:24 +0100
committerJakub Kicinski <kuba@kernel.org>2024-02-16 02:49:24 +0100
commitfc906e79229b84eda0efa1c64951a7918f184b6c (patch)
tree426ba5bf181b7cd02bfcbc189d1bf4cabab6ba20 /net/netlink
parentconfigs/debug: add NET debug config (diff)
parentgenetlink: Add per family bind/unbind callbacks (diff)
downloadlinux-fc906e79229b84eda0efa1c64951a7918f184b6c.tar.xz
linux-fc906e79229b84eda0efa1c64951a7918f184b6c.zip
Merge branch 'for-thermal-genetlink-family-bind-unbind-callbacks'
Stanislaw Gruszka says: ==================== thermal/netlink/intel_hfi: Enable HFI feature only when required The patchset introduces a new genetlink family bind/unbind callbacks and thermal/netlink notifications, which allow drivers to send netlink multicast events based on the presence of actual user-space consumers. This functionality optimizes resource usage by allowing disabling of features when not needed. v1: https://lore.kernel.org/linux-pm/20240131120535.933424-1-stanislaw.gruszka@linux.intel.com// v2: https://lore.kernel.org/linux-pm/20240206133605.1518373-1-stanislaw.gruszka@linux.intel.com/ v3: https://lore.kernel.org/linux-pm/20240209120625.1775017-1-stanislaw.gruszka@linux.intel.com/ ==================== Link: https://lore.kernel.org/r/20240212161615.161935-1-stanislaw.gruszka@linux.intel.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net/netlink')
-rw-r--r--net/netlink/genetlink.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 8c7af02f8454..50ec599a5cff 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -1836,6 +1836,9 @@ static int genl_bind(struct net *net, int group)
!ns_capable(net->user_ns, CAP_SYS_ADMIN))
ret = -EPERM;
+ if (family->bind)
+ family->bind(i);
+
break;
}
@@ -1843,12 +1846,39 @@ static int genl_bind(struct net *net, int group)
return ret;
}
+static void genl_unbind(struct net *net, int group)
+{
+ const struct genl_family *family;
+ unsigned int id;
+
+ down_read(&cb_lock);
+
+ idr_for_each_entry(&genl_fam_idr, family, id) {
+ int i;
+
+ if (family->n_mcgrps == 0)
+ continue;
+
+ i = group - family->mcgrp_offset;
+ if (i < 0 || i >= family->n_mcgrps)
+ continue;
+
+ if (family->unbind)
+ family->unbind(i);
+
+ break;
+ }
+
+ up_read(&cb_lock);
+}
+
static int __net_init genl_pernet_init(struct net *net)
{
struct netlink_kernel_cfg cfg = {
.input = genl_rcv,
.flags = NL_CFG_F_NONROOT_RECV,
.bind = genl_bind,
+ .unbind = genl_unbind,
.release = genl_release,
};