All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next v2 00/10] genetlink: support per-command policy dump
@ 2020-10-01 22:59 Jakub Kicinski
  2020-10-01 22:59 ` [PATCH net-next v2 01/10] genetlink: reorg struct genl_family Jakub Kicinski
                   ` (10 more replies)
  0 siblings, 11 replies; 35+ messages in thread
From: Jakub Kicinski @ 2020-10-01 22:59 UTC (permalink / raw)
  To: davem
  Cc: netdev, andrew, johannes, jiri, mkubecek, dsahern, pablo, Jakub Kicinski

Hi!

The objective of this series is to dump ethtool policies
to be able to tell which flags are supported by the kernel.
Current release adds ETHTOOL_FLAG_STATS for dumping extra
stats, but because of strict checking we need to make sure
that the flag is actually supported before setting it in
a request.

Ethtool policies are per command, and so far only dumping
family policies was supported.

The series adds new set of "light" ops to genl families which
don't have all the callbacks, and won't have the policy.
Most of families are then moved to these ops. This gives
us 4096B in savings on an allyesconfig build (not counting
the growth that would have happened when policy is added):

     text       data       bss        dec       hex
244415581  227958581  78372980  550747142  20d3bc06
244415581  227962677  78372980  550751238  20d3cc06

Next 6 patches deal the dumping per-op policy.

v2:
 - remove the stale comment in taskstats
 - split patch 8 -> 8, 9
 - now the getfamily policy is also in the op
 - make cmd u32
v1:
 - replace remaining uses of "light" with "small"
 - fix dump (ops can't be on the stack there)
 - coding changes in patch 4
 - new patch 7
 - don't echo op in responses - to make dump all easier

Dave - this series will cause a very trivial conflict with
the patch I sent to net. Both sides add some kdoc to struct
genl_ops so we'll need to keep it all.  I'm sending this
already because I also need to restructure ethool policies
in time for 5.10 if we want to use it for the stats flag.

Jakub Kicinski (10):
  genetlink: reorg struct genl_family
  genetlink: add small version of ops
  genetlink: move to smaller ops wherever possible
  genetlink: add a structure for dump state
  genetlink: use .start callback for dumppolicy
  genetlink: bring back per op policy
  taskstats: move specifying netlink policy back to ops
  genetlink: use parsed attrs in dumppolicy
  genetlink: switch control commands to per-op policies
  genetlink: allow dumping command-specific policy

 drivers/block/nbd.c                      |   6 +-
 drivers/net/gtp.c                        |   6 +-
 drivers/net/ieee802154/mac802154_hwsim.c |   6 +-
 drivers/net/macsec.c                     |   6 +-
 drivers/net/team/team.c                  |   6 +-
 drivers/net/wireless/mac80211_hwsim.c    |   6 +-
 drivers/target/target_core_user.c        |   6 +-
 drivers/thermal/thermal_netlink.c        |   8 +-
 fs/dlm/netlink.c                         |   6 +-
 include/net/genetlink.h                  |  67 +++++--
 include/net/netlink.h                    |   9 +-
 include/uapi/linux/genetlink.h           |   1 +
 kernel/taskstats.c                       |  40 +---
 net/batman-adv/netlink.c                 |   6 +-
 net/core/devlink.c                       |   6 +-
 net/core/drop_monitor.c                  |   6 +-
 net/hsr/hsr_netlink.c                    |   6 +-
 net/ieee802154/netlink.c                 |   6 +-
 net/ipv4/fou.c                           |   6 +-
 net/ipv4/tcp_metrics.c                   |   6 +-
 net/l2tp/l2tp_netlink.c                  |   6 +-
 net/mptcp/pm_netlink.c                   |   6 +-
 net/ncsi/ncsi-netlink.c                  |   6 +-
 net/netfilter/ipvs/ip_vs_ctl.c           |   6 +-
 net/netlabel/netlabel_calipso.c          |   6 +-
 net/netlabel/netlabel_cipso_v4.c         |   6 +-
 net/netlabel/netlabel_mgmt.c             |   6 +-
 net/netlabel/netlabel_unlabeled.c        |   6 +-
 net/netlink/genetlink.c                  | 234 ++++++++++++++++-------
 net/netlink/policy.c                     |  29 +--
 net/openvswitch/conntrack.c              |   6 +-
 net/openvswitch/datapath.c               |  24 +--
 net/openvswitch/meter.c                  |   6 +-
 net/psample/psample.c                    |   6 +-
 net/tipc/netlink_compat.c                |   6 +-
 net/wimax/stack.c                        |   6 +-
 net/wireless/nl80211.c                   |   5 +
 37 files changed, 346 insertions(+), 239 deletions(-)

-- 
2.26.2


^ permalink raw reply	[flat|nested] 35+ messages in thread

* [PATCH net-next v2 01/10] genetlink: reorg struct genl_family
  2020-10-01 22:59 [PATCH net-next v2 00/10] genetlink: support per-command policy dump Jakub Kicinski
@ 2020-10-01 22:59 ` Jakub Kicinski
  2020-10-01 22:59 ` [PATCH net-next v2 02/10] genetlink: add small version of ops Jakub Kicinski
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 35+ messages in thread
From: Jakub Kicinski @ 2020-10-01 22:59 UTC (permalink / raw)
  To: davem
  Cc: netdev, andrew, johannes, jiri, mkubecek, dsahern, pablo, Jakub Kicinski

There are holes and oversized members in struct genl_family.

Before: /* size: 104, cachelines: 2, members: 16 */
After:  /* size:  88, cachelines: 2, members: 16 */

The command field in struct genlmsghdr is a u8, so no point
in the operation count being 32 bit. Also operation 0 is
usually undefined, so we only need 255 entries.

netnsok and parallel_ops are only ever initialized to true.

We can grow the fields as needed, compiler should warn us
if someone tries to assign larger constants.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Reviewed-by: Johannes Berg <johannes@sipsolutions.net>
---
 include/net/genetlink.h | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/include/net/genetlink.h b/include/net/genetlink.h
index b9eb92f3fe86..5cd9ab0c6bd9 100644
--- a/include/net/genetlink.h
+++ b/include/net/genetlink.h
@@ -48,8 +48,11 @@ struct genl_family {
 	char			name[GENL_NAMSIZ];
 	unsigned int		version;
 	unsigned int		maxattr;
-	bool			netnsok;
-	bool			parallel_ops;
+	unsigned int		mcgrp_offset;	/* private */
+	u8			netnsok:1;
+	u8			parallel_ops:1;
+	u8			n_ops;
+	u8			n_mcgrps;
 	const struct nla_policy *policy;
 	int			(*pre_doit)(const struct genl_ops *ops,
 					    struct sk_buff *skb,
@@ -59,9 +62,6 @@ struct genl_family {
 					     struct genl_info *info);
 	const struct genl_ops *	ops;
 	const struct genl_multicast_group *mcgrps;
-	unsigned int		n_ops;
-	unsigned int		n_mcgrps;
-	unsigned int		mcgrp_offset;	/* private */
 	struct module		*module;
 };
 
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH net-next v2 02/10] genetlink: add small version of ops
  2020-10-01 22:59 [PATCH net-next v2 00/10] genetlink: support per-command policy dump Jakub Kicinski
  2020-10-01 22:59 ` [PATCH net-next v2 01/10] genetlink: reorg struct genl_family Jakub Kicinski
@ 2020-10-01 22:59 ` Jakub Kicinski
  2020-10-01 22:59 ` [PATCH net-next v2 03/10] genetlink: move to smaller ops wherever possible Jakub Kicinski
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 35+ messages in thread
From: Jakub Kicinski @ 2020-10-01 22:59 UTC (permalink / raw)
  To: davem
  Cc: netdev, andrew, johannes, jiri, mkubecek, dsahern, pablo, Jakub Kicinski

We want to add maxattr and policy back to genl_ops, to enable
dumping per command policy to user space. This, however, would
cause bloat for all the families with global policies. Introduce
smaller version of ops (half the size of genl_ops). Translate
these smaller ops into a full blown struct before use in the
core.

v1:
 - use struct assignment
 - put a full copy of the op in struct genl_dumpit_info
 - s/light/small/

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Reviewed-by: Johannes Berg <johannes@sipsolutions.net>
---
 drivers/thermal/thermal_netlink.c |   2 +-
 include/net/genetlink.h           |  53 +++++++++----
 net/netlink/genetlink.c           | 127 ++++++++++++++++++++++--------
 3 files changed, 135 insertions(+), 47 deletions(-)

diff --git a/drivers/thermal/thermal_netlink.c b/drivers/thermal/thermal_netlink.c
index af7b2383e8f6..e9999d5dfdd5 100644
--- a/drivers/thermal/thermal_netlink.c
+++ b/drivers/thermal/thermal_netlink.c
@@ -545,7 +545,7 @@ static int thermal_genl_cmd_dumpit(struct sk_buff *skb,
 {
 	struct param p = { .msg = skb };
 	const struct genl_dumpit_info *info = genl_dumpit_info(cb);
-	int cmd = info->ops->cmd;
+	int cmd = info->op.cmd;
 	int ret;
 	void *hdr;
 
diff --git a/include/net/genetlink.h b/include/net/genetlink.h
index 5cd9ab0c6bd9..8ea1fc1ed1c7 100644
--- a/include/net/genetlink.h
+++ b/include/net/genetlink.h
@@ -41,6 +41,8 @@ struct genl_info;
  *	(private)
  * @ops: the operations supported by this family
  * @n_ops: number of operations supported by this family
+ * @small_ops: the small-struct operations supported by this family
+ * @n_small_ops: number of small-struct operations supported by this family
  */
 struct genl_family {
 	int			id;		/* private */
@@ -52,6 +54,7 @@ struct genl_family {
 	u8			netnsok:1;
 	u8			parallel_ops:1;
 	u8			n_ops;
+	u8			n_small_ops;
 	u8			n_mcgrps;
 	const struct nla_policy *policy;
 	int			(*pre_doit)(const struct genl_ops *ops,
@@ -61,6 +64,7 @@ struct genl_family {
 					     struct sk_buff *skb,
 					     struct genl_info *info);
 	const struct genl_ops *	ops;
+	const struct genl_small_ops *small_ops;
 	const struct genl_multicast_group *mcgrps;
 	struct module		*module;
 };
@@ -108,23 +112,26 @@ enum genl_validate_flags {
 };
 
 /**
- * struct genl_info - info that is available during dumpit op call
- * @family: generic netlink family - for internal genl code usage
- * @ops: generic netlink ops - for internal genl code usage
- * @attrs: netlink attributes
+ * struct genl_small_ops - generic netlink operations (small version)
+ * @cmd: command identifier
+ * @internal_flags: flags used by the family
+ * @flags: flags
+ * @validate: validation flags from enum genl_validate_flags
+ * @doit: standard command callback
+ * @dumpit: callback for dumpers
+ *
+ * This is a cut-down version of struct genl_ops for users who don't need
+ * most of the ancillary infra and want to save space.
  */
-struct genl_dumpit_info {
-	const struct genl_family *family;
-	const struct genl_ops *ops;
-	struct nlattr **attrs;
+struct genl_small_ops {
+	int	(*doit)(struct sk_buff *skb, struct genl_info *info);
+	int	(*dumpit)(struct sk_buff *skb, struct netlink_callback *cb);
+	u8	cmd;
+	u8	internal_flags;
+	u8	flags;
+	u8	validate;
 };
 
-static inline const struct genl_dumpit_info *
-genl_dumpit_info(struct netlink_callback *cb)
-{
-	return cb->data;
-}
-
 /**
  * struct genl_ops - generic netlink operations
  * @cmd: command identifier
@@ -148,6 +155,24 @@ struct genl_ops {
 	u8			validate;
 };
 
+/**
+ * struct genl_info - info that is available during dumpit op call
+ * @family: generic netlink family - for internal genl code usage
+ * @ops: generic netlink ops - for internal genl code usage
+ * @attrs: netlink attributes
+ */
+struct genl_dumpit_info {
+	const struct genl_family *family;
+	struct genl_ops op;
+	struct nlattr **attrs;
+};
+
+static inline const struct genl_dumpit_info *
+genl_dumpit_info(struct netlink_callback *cb)
+{
+	return cb->data;
+}
+
 int genl_register_family(struct genl_family *family);
 int genl_unregister_family(const struct genl_family *family);
 void genl_notify(const struct genl_family *family, struct sk_buff *skb,
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 3a718e327515..094ebfff8889 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -107,16 +107,75 @@ static const struct genl_family *genl_family_find_byname(char *name)
 	return NULL;
 }
 
-static const struct genl_ops *genl_get_cmd(u8 cmd,
-					   const struct genl_family *family)
+static int genl_get_cmd_cnt(const struct genl_family *family)
+{
+	return family->n_ops + family->n_small_ops;
+}
+
+static void genl_op_from_full(const struct genl_family *family,
+			      unsigned int i, struct genl_ops *op)
+{
+	*op = family->ops[i];
+}
+
+static int genl_get_cmd_full(u8 cmd, const struct genl_family *family,
+			     struct genl_ops *op)
 {
 	int i;
 
 	for (i = 0; i < family->n_ops; i++)
-		if (family->ops[i].cmd == cmd)
-			return &family->ops[i];
+		if (family->ops[i].cmd == cmd) {
+			genl_op_from_full(family, i, op);
+			return 0;
+		}
 
-	return NULL;
+	return -ENOENT;
+}
+
+static void genl_op_from_small(const struct genl_family *family,
+			       unsigned int i, struct genl_ops *op)
+{
+	memset(op, 0, sizeof(*op));
+	op->doit	= family->small_ops[i].doit;
+	op->dumpit	= family->small_ops[i].dumpit;
+	op->cmd		= family->small_ops[i].cmd;
+	op->internal_flags = family->small_ops[i].internal_flags;
+	op->flags	= family->small_ops[i].flags;
+	op->validate	= family->small_ops[i].validate;
+}
+
+static int genl_get_cmd_small(u8 cmd, const struct genl_family *family,
+			      struct genl_ops *op)
+{
+	int i;
+
+	for (i = 0; i < family->n_small_ops; i++)
+		if (family->small_ops[i].cmd == cmd) {
+			genl_op_from_small(family, i, op);
+			return 0;
+		}
+
+	return -ENOENT;
+}
+
+static int genl_get_cmd(u8 cmd, const struct genl_family *family,
+			struct genl_ops *op)
+{
+	if (!genl_get_cmd_full(cmd, family, op))
+		return 0;
+	return genl_get_cmd_small(cmd, family, op);
+}
+
+static void genl_get_cmd_by_index(unsigned int i,
+				  const struct genl_family *family,
+				  struct genl_ops *op)
+{
+	if (i < family->n_ops)
+		genl_op_from_full(family, i, op);
+	else if (i < family->n_ops + family->n_small_ops)
+		genl_op_from_small(family, i - family->n_ops, op);
+	else
+		WARN_ON_ONCE(1);
 }
 
 static int genl_allocate_reserve_groups(int n_groups, int *first_id)
@@ -286,22 +345,25 @@ static void genl_unregister_mc_groups(const struct genl_family *family)
 
 static int genl_validate_ops(const struct genl_family *family)
 {
-	const struct genl_ops *ops = family->ops;
-	unsigned int n_ops = family->n_ops;
 	int i, j;
 
-	if (WARN_ON(n_ops && !ops))
+	if (WARN_ON(family->n_ops && !family->ops) ||
+	    WARN_ON(family->n_small_ops && !family->small_ops))
 		return -EINVAL;
 
-	if (!n_ops)
-		return 0;
+	for (i = 0; i < genl_get_cmd_cnt(family); i++) {
+		struct genl_ops op;
 
-	for (i = 0; i < n_ops; i++) {
-		if (ops[i].dumpit == NULL && ops[i].doit == NULL)
+		genl_get_cmd_by_index(i, family, &op);
+		if (op.dumpit == NULL && op.doit == NULL)
 			return -EINVAL;
-		for (j = i + 1; j < n_ops; j++)
-			if (ops[i].cmd == ops[j].cmd)
+		for (j = i + 1; j < genl_get_cmd_cnt(family); j++) {
+			struct genl_ops op2;
+
+			genl_get_cmd_by_index(j, family, &op2);
+			if (op.cmd == op2.cmd)
 				return -EINVAL;
+		}
 	}
 
 	return 0;
@@ -524,7 +586,7 @@ static int genl_start(struct netlink_callback *cb)
 		return -ENOMEM;
 	}
 	info->family = ctx->family;
-	info->ops = ops;
+	info->op = *ops;
 	info->attrs = attrs;
 
 	cb->data = info;
@@ -546,7 +608,7 @@ static int genl_start(struct netlink_callback *cb)
 
 static int genl_lock_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
 {
-	const struct genl_ops *ops = genl_dumpit_info(cb)->ops;
+	const struct genl_ops *ops = &genl_dumpit_info(cb)->op;
 	int rc;
 
 	genl_lock();
@@ -558,7 +620,7 @@ static int genl_lock_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
 static int genl_lock_done(struct netlink_callback *cb)
 {
 	const struct genl_dumpit_info *info = genl_dumpit_info(cb);
-	const struct genl_ops *ops = info->ops;
+	const struct genl_ops *ops = &info->op;
 	int rc = 0;
 
 	if (ops->done) {
@@ -574,7 +636,7 @@ static int genl_lock_done(struct netlink_callback *cb)
 static int genl_parallel_done(struct netlink_callback *cb)
 {
 	const struct genl_dumpit_info *info = genl_dumpit_info(cb);
-	const struct genl_ops *ops = info->ops;
+	const struct genl_ops *ops = &info->op;
 	int rc = 0;
 
 	if (ops->done)
@@ -682,9 +744,9 @@ static int genl_family_rcv_msg(const struct genl_family *family,
 			       struct nlmsghdr *nlh,
 			       struct netlink_ext_ack *extack)
 {
-	const struct genl_ops *ops;
 	struct net *net = sock_net(skb->sk);
 	struct genlmsghdr *hdr = nlmsg_data(nlh);
+	struct genl_ops op;
 	int hdrlen;
 
 	/* this family doesn't exist in this netns */
@@ -695,24 +757,23 @@ static int genl_family_rcv_msg(const struct genl_family *family,
 	if (nlh->nlmsg_len < nlmsg_msg_size(hdrlen))
 		return -EINVAL;
 
-	ops = genl_get_cmd(hdr->cmd, family);
-	if (ops == NULL)
+	if (genl_get_cmd(hdr->cmd, family, &op))
 		return -EOPNOTSUPP;
 
-	if ((ops->flags & GENL_ADMIN_PERM) &&
+	if ((op.flags & GENL_ADMIN_PERM) &&
 	    !netlink_capable(skb, CAP_NET_ADMIN))
 		return -EPERM;
 
-	if ((ops->flags & GENL_UNS_ADMIN_PERM) &&
+	if ((op.flags & GENL_UNS_ADMIN_PERM) &&
 	    !netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN))
 		return -EPERM;
 
 	if ((nlh->nlmsg_flags & NLM_F_DUMP) == NLM_F_DUMP)
 		return genl_family_rcv_msg_dumpit(family, skb, nlh, extack,
-						  ops, hdrlen, net);
+						  &op, hdrlen, net);
 	else
 		return genl_family_rcv_msg_doit(family, skb, nlh, extack,
-						ops, hdrlen, net);
+						&op, hdrlen, net);
 }
 
 static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
@@ -765,7 +826,7 @@ static int ctrl_fill_info(const struct genl_family *family, u32 portid, u32 seq,
 	    nla_put_u32(skb, CTRL_ATTR_MAXATTR, family->maxattr))
 		goto nla_put_failure;
 
-	if (family->n_ops) {
+	if (genl_get_cmd_cnt(family)) {
 		struct nlattr *nla_ops;
 		int i;
 
@@ -773,14 +834,16 @@ static int ctrl_fill_info(const struct genl_family *family, u32 portid, u32 seq,
 		if (nla_ops == NULL)
 			goto nla_put_failure;
 
-		for (i = 0; i < family->n_ops; i++) {
+		for (i = 0; i < genl_get_cmd_cnt(family); i++) {
 			struct nlattr *nest;
-			const struct genl_ops *ops = &family->ops[i];
-			u32 op_flags = ops->flags;
+			struct genl_ops op;
+			u32 op_flags;
 
-			if (ops->dumpit)
+			genl_get_cmd_by_index(i, family, &op);
+			op_flags = op.flags;
+			if (op.dumpit)
 				op_flags |= GENL_CMD_CAP_DUMP;
-			if (ops->doit)
+			if (op.doit)
 				op_flags |= GENL_CMD_CAP_DO;
 			if (family->policy)
 				op_flags |= GENL_CMD_CAP_HASPOL;
@@ -789,7 +852,7 @@ static int ctrl_fill_info(const struct genl_family *family, u32 portid, u32 seq,
 			if (nest == NULL)
 				goto nla_put_failure;
 
-			if (nla_put_u32(skb, CTRL_ATTR_OP_ID, ops->cmd) ||
+			if (nla_put_u32(skb, CTRL_ATTR_OP_ID, op.cmd) ||
 			    nla_put_u32(skb, CTRL_ATTR_OP_FLAGS, op_flags))
 				goto nla_put_failure;
 
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH net-next v2 03/10] genetlink: move to smaller ops wherever possible
  2020-10-01 22:59 [PATCH net-next v2 00/10] genetlink: support per-command policy dump Jakub Kicinski
  2020-10-01 22:59 ` [PATCH net-next v2 01/10] genetlink: reorg struct genl_family Jakub Kicinski
  2020-10-01 22:59 ` [PATCH net-next v2 02/10] genetlink: add small version of ops Jakub Kicinski
@ 2020-10-01 22:59 ` Jakub Kicinski
  2020-10-01 22:59 ` [PATCH net-next v2 04/10] genetlink: add a structure for dump state Jakub Kicinski
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 35+ messages in thread
From: Jakub Kicinski @ 2020-10-01 22:59 UTC (permalink / raw)
  To: davem
  Cc: netdev, andrew, johannes, jiri, mkubecek, dsahern, pablo, Jakub Kicinski

Bulk of the genetlink users can use smaller ops, move them.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Reviewed-by: Johannes Berg <johannes@sipsolutions.net>
---
 drivers/block/nbd.c                      |  6 +++---
 drivers/net/gtp.c                        |  6 +++---
 drivers/net/ieee802154/mac802154_hwsim.c |  6 +++---
 drivers/net/macsec.c                     |  6 +++---
 drivers/net/team/team.c                  |  6 +++---
 drivers/net/wireless/mac80211_hwsim.c    |  6 +++---
 drivers/target/target_core_user.c        |  6 +++---
 drivers/thermal/thermal_netlink.c        |  6 +++---
 fs/dlm/netlink.c                         |  6 +++---
 kernel/taskstats.c                       |  6 +++---
 net/batman-adv/netlink.c                 |  6 +++---
 net/core/devlink.c                       |  6 +++---
 net/core/drop_monitor.c                  |  6 +++---
 net/hsr/hsr_netlink.c                    |  6 +++---
 net/ieee802154/netlink.c                 |  6 +++---
 net/ipv4/fou.c                           |  6 +++---
 net/ipv4/tcp_metrics.c                   |  6 +++---
 net/l2tp/l2tp_netlink.c                  |  6 +++---
 net/mptcp/pm_netlink.c                   |  6 +++---
 net/ncsi/ncsi-netlink.c                  |  6 +++---
 net/netfilter/ipvs/ip_vs_ctl.c           |  6 +++---
 net/netlabel/netlabel_calipso.c          |  6 +++---
 net/netlabel/netlabel_cipso_v4.c         |  6 +++---
 net/netlabel/netlabel_mgmt.c             |  6 +++---
 net/netlabel/netlabel_unlabeled.c        |  6 +++---
 net/openvswitch/conntrack.c              |  6 +++---
 net/openvswitch/datapath.c               | 24 ++++++++++++------------
 net/openvswitch/meter.c                  |  6 +++---
 net/psample/psample.c                    |  6 +++---
 net/tipc/netlink_compat.c                |  6 +++---
 net/wimax/stack.c                        |  6 +++---
 net/wireless/nl80211.c                   |  5 +++++
 32 files changed, 107 insertions(+), 102 deletions(-)

diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index edf8b632e3d2..ab2bbe2208ef 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -2183,7 +2183,7 @@ static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info)
 	return ret;
 }
 
-static const struct genl_ops nbd_connect_genl_ops[] = {
+static const struct genl_small_ops nbd_connect_genl_ops[] = {
 	{
 		.cmd	= NBD_CMD_CONNECT,
 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
@@ -2215,8 +2215,8 @@ static struct genl_family nbd_genl_family __ro_after_init = {
 	.name		= NBD_GENL_FAMILY_NAME,
 	.version	= NBD_GENL_VERSION,
 	.module		= THIS_MODULE,
-	.ops		= nbd_connect_genl_ops,
-	.n_ops		= ARRAY_SIZE(nbd_connect_genl_ops),
+	.small_ops	= nbd_connect_genl_ops,
+	.n_small_ops	= ARRAY_SIZE(nbd_connect_genl_ops),
 	.maxattr	= NBD_ATTR_MAX,
 	.policy = nbd_attr_policy,
 	.mcgrps		= nbd_mcast_grps,
diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
index 611722eafed8..c09fe18c6c52 100644
--- a/drivers/net/gtp.c
+++ b/drivers/net/gtp.c
@@ -1339,7 +1339,7 @@ static const struct nla_policy gtp_genl_policy[GTPA_MAX + 1] = {
 	[GTPA_O_TEI]		= { .type = NLA_U32, },
 };
 
-static const struct genl_ops gtp_genl_ops[] = {
+static const struct genl_small_ops gtp_genl_ops[] = {
 	{
 		.cmd = GTP_CMD_NEWPDP,
 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
@@ -1369,8 +1369,8 @@ static struct genl_family gtp_genl_family __ro_after_init = {
 	.policy = gtp_genl_policy,
 	.netnsok	= true,
 	.module		= THIS_MODULE,
-	.ops		= gtp_genl_ops,
-	.n_ops		= ARRAY_SIZE(gtp_genl_ops),
+	.small_ops	= gtp_genl_ops,
+	.n_small_ops	= ARRAY_SIZE(gtp_genl_ops),
 	.mcgrps		= gtp_genl_mcgrps,
 	.n_mcgrps	= ARRAY_SIZE(gtp_genl_mcgrps),
 };
diff --git a/drivers/net/ieee802154/mac802154_hwsim.c b/drivers/net/ieee802154/mac802154_hwsim.c
index c20e7ef18bc9..c0bf7d78276e 100644
--- a/drivers/net/ieee802154/mac802154_hwsim.c
+++ b/drivers/net/ieee802154/mac802154_hwsim.c
@@ -583,7 +583,7 @@ static const struct nla_policy hwsim_genl_policy[MAC802154_HWSIM_ATTR_MAX + 1] =
 };
 
 /* Generic Netlink operations array */
-static const struct genl_ops hwsim_nl_ops[] = {
+static const struct genl_small_ops hwsim_nl_ops[] = {
 	{
 		.cmd = MAC802154_HWSIM_CMD_NEW_RADIO,
 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
@@ -628,8 +628,8 @@ static struct genl_family hwsim_genl_family __ro_after_init = {
 	.maxattr = MAC802154_HWSIM_ATTR_MAX,
 	.policy = hwsim_genl_policy,
 	.module = THIS_MODULE,
-	.ops = hwsim_nl_ops,
-	.n_ops = ARRAY_SIZE(hwsim_nl_ops),
+	.small_ops = hwsim_nl_ops,
+	.n_small_ops = ARRAY_SIZE(hwsim_nl_ops),
 	.mcgrps = hwsim_mcgrps,
 	.n_mcgrps = ARRAY_SIZE(hwsim_mcgrps),
 };
diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c
index 124045cbcda3..3f4d8c6625de 100644
--- a/drivers/net/macsec.c
+++ b/drivers/net/macsec.c
@@ -3285,7 +3285,7 @@ static int macsec_dump_txsc(struct sk_buff *skb, struct netlink_callback *cb)
 	return skb->len;
 }
 
-static const struct genl_ops macsec_genl_ops[] = {
+static const struct genl_small_ops macsec_genl_ops[] = {
 	{
 		.cmd = MACSEC_CMD_GET_TXSC,
 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
@@ -3361,8 +3361,8 @@ static struct genl_family macsec_fam __ro_after_init = {
 	.policy = macsec_genl_policy,
 	.netnsok	= true,
 	.module		= THIS_MODULE,
-	.ops		= macsec_genl_ops,
-	.n_ops		= ARRAY_SIZE(macsec_genl_ops),
+	.small_ops	= macsec_genl_ops,
+	.n_small_ops	= ARRAY_SIZE(macsec_genl_ops),
 };
 
 static netdev_tx_t macsec_start_xmit(struct sk_buff *skb,
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index 8c1e02752ff6..a0c8c2fe6c3e 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -2795,7 +2795,7 @@ static int team_nl_cmd_port_list_get(struct sk_buff *skb,
 	return err;
 }
 
-static const struct genl_ops team_nl_ops[] = {
+static const struct genl_small_ops team_nl_ops[] = {
 	{
 		.cmd = TEAM_CMD_NOOP,
 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
@@ -2832,8 +2832,8 @@ static struct genl_family team_nl_family __ro_after_init = {
 	.policy = team_nl_policy,
 	.netnsok	= true,
 	.module		= THIS_MODULE,
-	.ops		= team_nl_ops,
-	.n_ops		= ARRAY_SIZE(team_nl_ops),
+	.small_ops	= team_nl_ops,
+	.n_small_ops	= ARRAY_SIZE(team_nl_ops),
 	.mcgrps		= team_nl_mcgrps,
 	.n_mcgrps	= ARRAY_SIZE(team_nl_mcgrps),
 };
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index dce3bc9c9f84..7a86145b8226 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -3886,7 +3886,7 @@ static int hwsim_dump_radio_nl(struct sk_buff *skb,
 }
 
 /* Generic Netlink operations array */
-static const struct genl_ops hwsim_ops[] = {
+static const struct genl_small_ops hwsim_ops[] = {
 	{
 		.cmd = HWSIM_CMD_REGISTER,
 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
@@ -3930,8 +3930,8 @@ static struct genl_family hwsim_genl_family __ro_after_init = {
 	.policy = hwsim_genl_policy,
 	.netnsok = true,
 	.module = THIS_MODULE,
-	.ops = hwsim_ops,
-	.n_ops = ARRAY_SIZE(hwsim_ops),
+	.small_ops = hwsim_ops,
+	.n_small_ops = ARRAY_SIZE(hwsim_ops),
 	.mcgrps = hwsim_mcgrps,
 	.n_mcgrps = ARRAY_SIZE(hwsim_mcgrps),
 };
diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c
index 9b7592350502..1a060a2c98d6 100644
--- a/drivers/target/target_core_user.c
+++ b/drivers/target/target_core_user.c
@@ -436,7 +436,7 @@ static int tcmu_genl_set_features(struct sk_buff *skb, struct genl_info *info)
 	return 0;
 }
 
-static const struct genl_ops tcmu_genl_ops[] = {
+static const struct genl_small_ops tcmu_genl_ops[] = {
 	{
 		.cmd	= TCMU_CMD_SET_FEATURES,
 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
@@ -474,8 +474,8 @@ static struct genl_family tcmu_genl_family __ro_after_init = {
 	.mcgrps = tcmu_mcgrps,
 	.n_mcgrps = ARRAY_SIZE(tcmu_mcgrps),
 	.netnsok = true,
-	.ops = tcmu_genl_ops,
-	.n_ops = ARRAY_SIZE(tcmu_genl_ops),
+	.small_ops = tcmu_genl_ops,
+	.n_small_ops = ARRAY_SIZE(tcmu_genl_ops),
 };
 
 #define tcmu_cmd_set_dbi_cur(cmd, index) ((cmd)->dbi_cur = (index))
diff --git a/drivers/thermal/thermal_netlink.c b/drivers/thermal/thermal_netlink.c
index e9999d5dfdd5..da2891fcac89 100644
--- a/drivers/thermal/thermal_netlink.c
+++ b/drivers/thermal/thermal_netlink.c
@@ -601,7 +601,7 @@ static int thermal_genl_cmd_doit(struct sk_buff *skb,
 	return ret;
 }
 
-static const struct genl_ops thermal_genl_ops[] = {
+static const struct genl_small_ops thermal_genl_ops[] = {
 	{
 		.cmd = THERMAL_GENL_CMD_TZ_GET_ID,
 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
@@ -635,8 +635,8 @@ static struct genl_family thermal_gnl_family __ro_after_init = {
 	.version	= THERMAL_GENL_VERSION,
 	.maxattr	= THERMAL_GENL_ATTR_MAX,
 	.policy		= thermal_genl_policy,
-	.ops		= thermal_genl_ops,
-	.n_ops		= ARRAY_SIZE(thermal_genl_ops),
+	.small_ops	= thermal_genl_ops,
+	.n_small_ops	= ARRAY_SIZE(thermal_genl_ops),
 	.mcgrps		= thermal_genl_mcgrps,
 	.n_mcgrps	= ARRAY_SIZE(thermal_genl_mcgrps),
 };
diff --git a/fs/dlm/netlink.c b/fs/dlm/netlink.c
index e338c407cb75..67f68d48d60c 100644
--- a/fs/dlm/netlink.c
+++ b/fs/dlm/netlink.c
@@ -62,7 +62,7 @@ static int user_cmd(struct sk_buff *skb, struct genl_info *info)
 	return 0;
 }
 
-static const struct genl_ops dlm_nl_ops[] = {
+static const struct genl_small_ops dlm_nl_ops[] = {
 	{
 		.cmd	= DLM_CMD_HELLO,
 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
@@ -73,8 +73,8 @@ static const struct genl_ops dlm_nl_ops[] = {
 static struct genl_family family __ro_after_init = {
 	.name		= DLM_GENL_NAME,
 	.version	= DLM_GENL_VERSION,
-	.ops		= dlm_nl_ops,
-	.n_ops		= ARRAY_SIZE(dlm_nl_ops),
+	.small_ops	= dlm_nl_ops,
+	.n_small_ops	= ARRAY_SIZE(dlm_nl_ops),
 	.module		= THIS_MODULE,
 };
 
diff --git a/kernel/taskstats.c b/kernel/taskstats.c
index e2ac0e37c4ae..ef4de29fbe8a 100644
--- a/kernel/taskstats.c
+++ b/kernel/taskstats.c
@@ -644,7 +644,7 @@ void taskstats_exit(struct task_struct *tsk, int group_dead)
 	nlmsg_free(rep_skb);
 }
 
-static const struct genl_ops taskstats_ops[] = {
+static const struct genl_small_ops taskstats_ops[] = {
 	{
 		.cmd		= TASKSTATS_CMD_GET,
 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
@@ -687,8 +687,8 @@ static struct genl_family family __ro_after_init = {
 	.version	= TASKSTATS_GENL_VERSION,
 	.maxattr	= TASKSTATS_CMD_ATTR_MAX,
 	.module		= THIS_MODULE,
-	.ops		= taskstats_ops,
-	.n_ops		= ARRAY_SIZE(taskstats_ops),
+	.small_ops	= taskstats_ops,
+	.n_small_ops	= ARRAY_SIZE(taskstats_ops),
 	.pre_doit	= taskstats_pre_doit,
 };
 
diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c
index dc193618a761..c7a55647b520 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -1350,7 +1350,7 @@ static void batadv_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
 	}
 }
 
-static const struct genl_ops batadv_netlink_ops[] = {
+static const struct genl_small_ops batadv_netlink_ops[] = {
 	{
 		.cmd = BATADV_CMD_GET_MESH,
 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
@@ -1484,8 +1484,8 @@ struct genl_family batadv_netlink_family __ro_after_init = {
 	.pre_doit = batadv_pre_doit,
 	.post_doit = batadv_post_doit,
 	.module = THIS_MODULE,
-	.ops = batadv_netlink_ops,
-	.n_ops = ARRAY_SIZE(batadv_netlink_ops),
+	.small_ops = batadv_netlink_ops,
+	.n_small_ops = ARRAY_SIZE(batadv_netlink_ops),
 	.mcgrps = batadv_netlink_mcgrps,
 	.n_mcgrps = ARRAY_SIZE(batadv_netlink_mcgrps),
 };
diff --git a/net/core/devlink.c b/net/core/devlink.c
index 6f2863e717a9..09442ab012ae 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -7121,7 +7121,7 @@ static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
 	[DEVLINK_ATTR_PORT_FUNCTION] = { .type = NLA_NESTED },
 };
 
-static const struct genl_ops devlink_nl_ops[] = {
+static const struct genl_small_ops devlink_nl_ops[] = {
 	{
 		.cmd = DEVLINK_CMD_GET,
 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
@@ -7446,8 +7446,8 @@ static struct genl_family devlink_nl_family __ro_after_init = {
 	.pre_doit	= devlink_nl_pre_doit,
 	.post_doit	= devlink_nl_post_doit,
 	.module		= THIS_MODULE,
-	.ops		= devlink_nl_ops,
-	.n_ops		= ARRAY_SIZE(devlink_nl_ops),
+	.small_ops	= devlink_nl_ops,
+	.n_small_ops	= ARRAY_SIZE(devlink_nl_ops),
 	.mcgrps		= devlink_nl_mcgrps,
 	.n_mcgrps	= ARRAY_SIZE(devlink_nl_mcgrps),
 };
diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c
index a28b743489c5..571f191c06d9 100644
--- a/net/core/drop_monitor.c
+++ b/net/core/drop_monitor.c
@@ -1575,7 +1575,7 @@ static const struct nla_policy net_dm_nl_policy[NET_DM_ATTR_MAX + 1] = {
 	[NET_DM_ATTR_HW_DROPS]	= {. type = NLA_FLAG },
 };
 
-static const struct genl_ops dropmon_ops[] = {
+static const struct genl_small_ops dropmon_ops[] = {
 	{
 		.cmd = NET_DM_CMD_CONFIG,
 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
@@ -1625,8 +1625,8 @@ static struct genl_family net_drop_monitor_family __ro_after_init = {
 	.pre_doit	= net_dm_nl_pre_doit,
 	.post_doit	= net_dm_nl_post_doit,
 	.module		= THIS_MODULE,
-	.ops		= dropmon_ops,
-	.n_ops		= ARRAY_SIZE(dropmon_ops),
+	.small_ops	= dropmon_ops,
+	.n_small_ops	= ARRAY_SIZE(dropmon_ops),
 	.mcgrps		= dropmon_mcgrps,
 	.n_mcgrps	= ARRAY_SIZE(dropmon_mcgrps),
 };
diff --git a/net/hsr/hsr_netlink.c b/net/hsr/hsr_netlink.c
index 0e4681cf71db..f3c8f91dbe2c 100644
--- a/net/hsr/hsr_netlink.c
+++ b/net/hsr/hsr_netlink.c
@@ -493,7 +493,7 @@ static int hsr_get_node_list(struct sk_buff *skb_in, struct genl_info *info)
 	return res;
 }
 
-static const struct genl_ops hsr_ops[] = {
+static const struct genl_small_ops hsr_ops[] = {
 	{
 		.cmd = HSR_C_GET_NODE_STATUS,
 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
@@ -518,8 +518,8 @@ static struct genl_family hsr_genl_family __ro_after_init = {
 	.policy = hsr_genl_policy,
 	.netnsok = true,
 	.module = THIS_MODULE,
-	.ops = hsr_ops,
-	.n_ops = ARRAY_SIZE(hsr_ops),
+	.small_ops = hsr_ops,
+	.n_small_ops = ARRAY_SIZE(hsr_ops),
 	.mcgrps = hsr_mcgrps,
 	.n_mcgrps = ARRAY_SIZE(hsr_mcgrps),
 };
diff --git a/net/ieee802154/netlink.c b/net/ieee802154/netlink.c
index 7fe3b6b6c495..b07abc38b4b3 100644
--- a/net/ieee802154/netlink.c
+++ b/net/ieee802154/netlink.c
@@ -81,7 +81,7 @@ int ieee802154_nl_reply(struct sk_buff *msg, struct genl_info *info)
 	return genlmsg_reply(msg, info);
 }
 
-static const struct genl_ops ieee802154_ops[] = {
+static const struct genl_small_ops ieee802154_ops[] = {
 	/* see nl-phy.c */
 	IEEE802154_DUMP(IEEE802154_LIST_PHY, ieee802154_list_phy,
 			ieee802154_dump_phy),
@@ -130,8 +130,8 @@ struct genl_family nl802154_family __ro_after_init = {
 	.maxattr	= IEEE802154_ATTR_MAX,
 	.policy		= ieee802154_policy,
 	.module		= THIS_MODULE,
-	.ops		= ieee802154_ops,
-	.n_ops		= ARRAY_SIZE(ieee802154_ops),
+	.small_ops	= ieee802154_ops,
+	.n_small_ops	= ARRAY_SIZE(ieee802154_ops),
 	.mcgrps		= ieee802154_mcgrps,
 	.n_mcgrps	= ARRAY_SIZE(ieee802154_mcgrps),
 };
diff --git a/net/ipv4/fou.c b/net/ipv4/fou.c
index 5308cfa3de62..e5f69b0bf3df 100644
--- a/net/ipv4/fou.c
+++ b/net/ipv4/fou.c
@@ -911,7 +911,7 @@ static int fou_nl_dump(struct sk_buff *skb, struct netlink_callback *cb)
 	return skb->len;
 }
 
-static const struct genl_ops fou_nl_ops[] = {
+static const struct genl_small_ops fou_nl_ops[] = {
 	{
 		.cmd = FOU_CMD_ADD,
 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
@@ -940,8 +940,8 @@ static struct genl_family fou_nl_family __ro_after_init = {
 	.policy = fou_nl_policy,
 	.netnsok	= true,
 	.module		= THIS_MODULE,
-	.ops		= fou_nl_ops,
-	.n_ops		= ARRAY_SIZE(fou_nl_ops),
+	.small_ops	= fou_nl_ops,
+	.n_small_ops	= ARRAY_SIZE(fou_nl_ops),
 };
 
 size_t fou_encap_hlen(struct ip_tunnel_encap *e)
diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c
index 279db8822439..6b27c481fe18 100644
--- a/net/ipv4/tcp_metrics.c
+++ b/net/ipv4/tcp_metrics.c
@@ -943,7 +943,7 @@ static int tcp_metrics_nl_cmd_del(struct sk_buff *skb, struct genl_info *info)
 	return 0;
 }
 
-static const struct genl_ops tcp_metrics_nl_ops[] = {
+static const struct genl_small_ops tcp_metrics_nl_ops[] = {
 	{
 		.cmd = TCP_METRICS_CMD_GET,
 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
@@ -966,8 +966,8 @@ static struct genl_family tcp_metrics_nl_family __ro_after_init = {
 	.policy = tcp_metrics_nl_policy,
 	.netnsok	= true,
 	.module		= THIS_MODULE,
-	.ops		= tcp_metrics_nl_ops,
-	.n_ops		= ARRAY_SIZE(tcp_metrics_nl_ops),
+	.small_ops	= tcp_metrics_nl_ops,
+	.n_small_ops	= ARRAY_SIZE(tcp_metrics_nl_ops),
 };
 
 static unsigned int tcpmhash_entries;
diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c
index 5ca5056e9636..83956c9ee1fc 100644
--- a/net/l2tp/l2tp_netlink.c
+++ b/net/l2tp/l2tp_netlink.c
@@ -914,7 +914,7 @@ static const struct nla_policy l2tp_nl_policy[L2TP_ATTR_MAX + 1] = {
 	},
 };
 
-static const struct genl_ops l2tp_nl_ops[] = {
+static const struct genl_small_ops l2tp_nl_ops[] = {
 	{
 		.cmd = L2TP_CMD_NOOP,
 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
@@ -981,8 +981,8 @@ static struct genl_family l2tp_nl_family __ro_after_init = {
 	.policy = l2tp_nl_policy,
 	.netnsok	= true,
 	.module		= THIS_MODULE,
-	.ops		= l2tp_nl_ops,
-	.n_ops		= ARRAY_SIZE(l2tp_nl_ops),
+	.small_ops	= l2tp_nl_ops,
+	.n_small_ops	= ARRAY_SIZE(l2tp_nl_ops),
 	.mcgrps		= l2tp_multicast_group,
 	.n_mcgrps	= ARRAY_SIZE(l2tp_multicast_group),
 };
diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
index 5a0e4d11bcc3..9f9cd41b7733 100644
--- a/net/mptcp/pm_netlink.c
+++ b/net/mptcp/pm_netlink.c
@@ -1054,7 +1054,7 @@ mptcp_nl_cmd_get_limits(struct sk_buff *skb, struct genl_info *info)
 	return -EMSGSIZE;
 }
 
-static struct genl_ops mptcp_pm_ops[] = {
+static struct genl_small_ops mptcp_pm_ops[] = {
 	{
 		.cmd    = MPTCP_PM_CMD_ADD_ADDR,
 		.doit   = mptcp_nl_cmd_add_addr,
@@ -1093,8 +1093,8 @@ static struct genl_family mptcp_genl_family __ro_after_init = {
 	.policy		= mptcp_pm_policy,
 	.netnsok	= true,
 	.module		= THIS_MODULE,
-	.ops		= mptcp_pm_ops,
-	.n_ops		= ARRAY_SIZE(mptcp_pm_ops),
+	.small_ops	= mptcp_pm_ops,
+	.n_small_ops	= ARRAY_SIZE(mptcp_pm_ops),
 	.mcgrps		= mptcp_pm_mcgrps,
 	.n_mcgrps	= ARRAY_SIZE(mptcp_pm_mcgrps),
 };
diff --git a/net/ncsi/ncsi-netlink.c b/net/ncsi/ncsi-netlink.c
index 8b386d766e7d..adddc7707aa4 100644
--- a/net/ncsi/ncsi-netlink.c
+++ b/net/ncsi/ncsi-netlink.c
@@ -716,7 +716,7 @@ static int ncsi_set_channel_mask_nl(struct sk_buff *msg,
 	return 0;
 }
 
-static const struct genl_ops ncsi_ops[] = {
+static const struct genl_small_ops ncsi_ops[] = {
 	{
 		.cmd = NCSI_CMD_PKG_INFO,
 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
@@ -762,8 +762,8 @@ static struct genl_family ncsi_genl_family __ro_after_init = {
 	.maxattr = NCSI_ATTR_MAX,
 	.policy = ncsi_genl_policy,
 	.module = THIS_MODULE,
-	.ops = ncsi_ops,
-	.n_ops = ARRAY_SIZE(ncsi_ops),
+	.small_ops = ncsi_ops,
+	.n_small_ops = ARRAY_SIZE(ncsi_ops),
 };
 
 int ncsi_init_netlink(struct net_device *dev)
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index 8dbfd84322a8..e279ded4e306 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -3893,7 +3893,7 @@ static int ip_vs_genl_get_cmd(struct sk_buff *skb, struct genl_info *info)
 }
 
 
-static const struct genl_ops ip_vs_genl_ops[] = {
+static const struct genl_small_ops ip_vs_genl_ops[] = {
 	{
 		.cmd	= IPVS_CMD_NEW_SERVICE,
 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
@@ -4001,8 +4001,8 @@ static struct genl_family ip_vs_genl_family __ro_after_init = {
 	.policy = ip_vs_cmd_policy,
 	.netnsok        = true,         /* Make ipvsadm to work on netns */
 	.module		= THIS_MODULE,
-	.ops		= ip_vs_genl_ops,
-	.n_ops		= ARRAY_SIZE(ip_vs_genl_ops),
+	.small_ops	= ip_vs_genl_ops,
+	.n_small_ops	= ARRAY_SIZE(ip_vs_genl_ops),
 };
 
 static int __init ip_vs_genl_register(void)
diff --git a/net/netlabel/netlabel_calipso.c b/net/netlabel/netlabel_calipso.c
index 1a98247ab148..4e62f2ad3575 100644
--- a/net/netlabel/netlabel_calipso.c
+++ b/net/netlabel/netlabel_calipso.c
@@ -304,7 +304,7 @@ static int netlbl_calipso_remove(struct sk_buff *skb, struct genl_info *info)
 /* NetLabel Generic NETLINK Command Definitions
  */
 
-static const struct genl_ops netlbl_calipso_ops[] = {
+static const struct genl_small_ops netlbl_calipso_ops[] = {
 	{
 	.cmd = NLBL_CALIPSO_C_ADD,
 	.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
@@ -342,8 +342,8 @@ static struct genl_family netlbl_calipso_gnl_family __ro_after_init = {
 	.maxattr = NLBL_CALIPSO_A_MAX,
 	.policy = calipso_genl_policy,
 	.module = THIS_MODULE,
-	.ops = netlbl_calipso_ops,
-	.n_ops = ARRAY_SIZE(netlbl_calipso_ops),
+	.small_ops = netlbl_calipso_ops,
+	.n_small_ops = ARRAY_SIZE(netlbl_calipso_ops),
 };
 
 /* NetLabel Generic NETLINK Protocol Functions
diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c
index 0f16080b87cb..726dda95934c 100644
--- a/net/netlabel/netlabel_cipso_v4.c
+++ b/net/netlabel/netlabel_cipso_v4.c
@@ -724,7 +724,7 @@ static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info)
  * NetLabel Generic NETLINK Command Definitions
  */
 
-static const struct genl_ops netlbl_cipsov4_ops[] = {
+static const struct genl_small_ops netlbl_cipsov4_ops[] = {
 	{
 	.cmd = NLBL_CIPSOV4_C_ADD,
 	.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
@@ -762,8 +762,8 @@ static struct genl_family netlbl_cipsov4_gnl_family __ro_after_init = {
 	.maxattr = NLBL_CIPSOV4_A_MAX,
 	.policy = netlbl_cipsov4_genl_policy,
 	.module = THIS_MODULE,
-	.ops = netlbl_cipsov4_ops,
-	.n_ops = ARRAY_SIZE(netlbl_cipsov4_ops),
+	.small_ops = netlbl_cipsov4_ops,
+	.n_small_ops = ARRAY_SIZE(netlbl_cipsov4_ops),
 };
 
 /*
diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c
index e7a25fbfaf8b..eb1d66d20afb 100644
--- a/net/netlabel/netlabel_mgmt.c
+++ b/net/netlabel/netlabel_mgmt.c
@@ -757,7 +757,7 @@ static int netlbl_mgmt_version(struct sk_buff *skb, struct genl_info *info)
  * NetLabel Generic NETLINK Command Definitions
  */
 
-static const struct genl_ops netlbl_mgmt_genl_ops[] = {
+static const struct genl_small_ops netlbl_mgmt_genl_ops[] = {
 	{
 	.cmd = NLBL_MGMT_C_ADD,
 	.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
@@ -823,8 +823,8 @@ static struct genl_family netlbl_mgmt_gnl_family __ro_after_init = {
 	.maxattr = NLBL_MGMT_A_MAX,
 	.policy = netlbl_mgmt_genl_policy,
 	.module = THIS_MODULE,
-	.ops = netlbl_mgmt_genl_ops,
-	.n_ops = ARRAY_SIZE(netlbl_mgmt_genl_ops),
+	.small_ops = netlbl_mgmt_genl_ops,
+	.n_small_ops = ARRAY_SIZE(netlbl_mgmt_genl_ops),
 };
 
 /*
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
index 77bb1bb22c3b..2e8e3f7b2111 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -1301,7 +1301,7 @@ static int netlbl_unlabel_staticlistdef(struct sk_buff *skb,
  * NetLabel Generic NETLINK Command Definitions
  */
 
-static const struct genl_ops netlbl_unlabel_genl_ops[] = {
+static const struct genl_small_ops netlbl_unlabel_genl_ops[] = {
 	{
 	.cmd = NLBL_UNLABEL_C_STATICADD,
 	.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
@@ -1367,8 +1367,8 @@ static struct genl_family netlbl_unlabel_gnl_family __ro_after_init = {
 	.maxattr = NLBL_UNLABEL_A_MAX,
 	.policy = netlbl_unlabel_genl_policy,
 	.module = THIS_MODULE,
-	.ops = netlbl_unlabel_genl_ops,
-	.n_ops = ARRAY_SIZE(netlbl_unlabel_genl_ops),
+	.small_ops = netlbl_unlabel_genl_ops,
+	.n_small_ops = ARRAY_SIZE(netlbl_unlabel_genl_ops),
 };
 
 /*
diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c
index e86b9601f5b1..18af10b7ef0e 100644
--- a/net/openvswitch/conntrack.c
+++ b/net/openvswitch/conntrack.c
@@ -2231,7 +2231,7 @@ static int ovs_ct_limit_cmd_get(struct sk_buff *skb, struct genl_info *info)
 	return err;
 }
 
-static struct genl_ops ct_limit_genl_ops[] = {
+static struct genl_small_ops ct_limit_genl_ops[] = {
 	{ .cmd = OVS_CT_LIMIT_CMD_SET,
 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 		.flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN
@@ -2263,8 +2263,8 @@ struct genl_family dp_ct_limit_genl_family __ro_after_init = {
 	.policy = ct_limit_policy,
 	.netnsok = true,
 	.parallel_ops = true,
-	.ops = ct_limit_genl_ops,
-	.n_ops = ARRAY_SIZE(ct_limit_genl_ops),
+	.small_ops = ct_limit_genl_ops,
+	.n_small_ops = ARRAY_SIZE(ct_limit_genl_ops),
 	.mcgrps = &ovs_ct_limit_multicast_group,
 	.n_mcgrps = 1,
 	.module = THIS_MODULE,
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 00df39b736ed..832f898edb6a 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -652,7 +652,7 @@ static const struct nla_policy packet_policy[OVS_PACKET_ATTR_MAX + 1] = {
 	[OVS_PACKET_ATTR_HASH] = { .type = NLA_U64 },
 };
 
-static const struct genl_ops dp_packet_genl_ops[] = {
+static const struct genl_small_ops dp_packet_genl_ops[] = {
 	{ .cmd = OVS_PACKET_CMD_EXECUTE,
 	  .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 	  .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
@@ -668,8 +668,8 @@ static struct genl_family dp_packet_genl_family __ro_after_init = {
 	.policy = packet_policy,
 	.netnsok = true,
 	.parallel_ops = true,
-	.ops = dp_packet_genl_ops,
-	.n_ops = ARRAY_SIZE(dp_packet_genl_ops),
+	.small_ops = dp_packet_genl_ops,
+	.n_small_ops = ARRAY_SIZE(dp_packet_genl_ops),
 	.module = THIS_MODULE,
 };
 
@@ -1453,7 +1453,7 @@ static const struct nla_policy flow_policy[OVS_FLOW_ATTR_MAX + 1] = {
 	[OVS_FLOW_ATTR_UFID_FLAGS] = { .type = NLA_U32 },
 };
 
-static const struct genl_ops dp_flow_genl_ops[] = {
+static const struct genl_small_ops dp_flow_genl_ops[] = {
 	{ .cmd = OVS_FLOW_CMD_NEW,
 	  .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 	  .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
@@ -1485,8 +1485,8 @@ static struct genl_family dp_flow_genl_family __ro_after_init = {
 	.policy = flow_policy,
 	.netnsok = true,
 	.parallel_ops = true,
-	.ops = dp_flow_genl_ops,
-	.n_ops = ARRAY_SIZE(dp_flow_genl_ops),
+	.small_ops = dp_flow_genl_ops,
+	.n_small_ops = ARRAY_SIZE(dp_flow_genl_ops),
 	.mcgrps = &ovs_dp_flow_multicast_group,
 	.n_mcgrps = 1,
 	.module = THIS_MODULE,
@@ -1918,7 +1918,7 @@ static const struct nla_policy datapath_policy[OVS_DP_ATTR_MAX + 1] = {
 		PCPU_MIN_UNIT_SIZE / sizeof(struct mask_cache_entry)),
 };
 
-static const struct genl_ops dp_datapath_genl_ops[] = {
+static const struct genl_small_ops dp_datapath_genl_ops[] = {
 	{ .cmd = OVS_DP_CMD_NEW,
 	  .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 	  .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
@@ -1950,8 +1950,8 @@ static struct genl_family dp_datapath_genl_family __ro_after_init = {
 	.policy = datapath_policy,
 	.netnsok = true,
 	.parallel_ops = true,
-	.ops = dp_datapath_genl_ops,
-	.n_ops = ARRAY_SIZE(dp_datapath_genl_ops),
+	.small_ops = dp_datapath_genl_ops,
+	.n_small_ops = ARRAY_SIZE(dp_datapath_genl_ops),
 	.mcgrps = &ovs_dp_datapath_multicast_group,
 	.n_mcgrps = 1,
 	.module = THIS_MODULE,
@@ -2401,7 +2401,7 @@ static const struct nla_policy vport_policy[OVS_VPORT_ATTR_MAX + 1] = {
 	[OVS_VPORT_ATTR_NETNSID] = { .type = NLA_S32 },
 };
 
-static const struct genl_ops dp_vport_genl_ops[] = {
+static const struct genl_small_ops dp_vport_genl_ops[] = {
 	{ .cmd = OVS_VPORT_CMD_NEW,
 	  .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 	  .flags = GENL_UNS_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
@@ -2433,8 +2433,8 @@ struct genl_family dp_vport_genl_family __ro_after_init = {
 	.policy = vport_policy,
 	.netnsok = true,
 	.parallel_ops = true,
-	.ops = dp_vport_genl_ops,
-	.n_ops = ARRAY_SIZE(dp_vport_genl_ops),
+	.small_ops = dp_vport_genl_ops,
+	.n_small_ops = ARRAY_SIZE(dp_vport_genl_ops),
 	.mcgrps = &ovs_dp_vport_multicast_group,
 	.n_mcgrps = 1,
 	.module = THIS_MODULE,
diff --git a/net/openvswitch/meter.c b/net/openvswitch/meter.c
index 3d3d8e094546..50541e874726 100644
--- a/net/openvswitch/meter.c
+++ b/net/openvswitch/meter.c
@@ -672,7 +672,7 @@ bool ovs_meter_execute(struct datapath *dp, struct sk_buff *skb,
 	return false;
 }
 
-static struct genl_ops dp_meter_genl_ops[] = {
+static struct genl_small_ops dp_meter_genl_ops[] = {
 	{ .cmd = OVS_METER_CMD_FEATURES,
 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 		.flags = 0,		  /* OK for unprivileged users. */
@@ -711,8 +711,8 @@ struct genl_family dp_meter_genl_family __ro_after_init = {
 	.policy = meter_policy,
 	.netnsok = true,
 	.parallel_ops = true,
-	.ops = dp_meter_genl_ops,
-	.n_ops = ARRAY_SIZE(dp_meter_genl_ops),
+	.small_ops = dp_meter_genl_ops,
+	.n_small_ops = ARRAY_SIZE(dp_meter_genl_ops),
 	.mcgrps = &ovs_meter_multicast_group,
 	.n_mcgrps = 1,
 	.module = THIS_MODULE,
diff --git a/net/psample/psample.c b/net/psample/psample.c
index a042261a45c5..33e238c965bd 100644
--- a/net/psample/psample.c
+++ b/net/psample/psample.c
@@ -96,7 +96,7 @@ static int psample_nl_cmd_get_group_dumpit(struct sk_buff *msg,
 	return msg->len;
 }
 
-static const struct genl_ops psample_nl_ops[] = {
+static const struct genl_small_ops psample_nl_ops[] = {
 	{
 		.cmd = PSAMPLE_CMD_GET_GROUP,
 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
@@ -112,8 +112,8 @@ static struct genl_family psample_nl_family __ro_after_init = {
 	.netnsok	= true,
 	.module		= THIS_MODULE,
 	.mcgrps		= psample_nl_mcgrps,
-	.ops		= psample_nl_ops,
-	.n_ops		= ARRAY_SIZE(psample_nl_ops),
+	.small_ops	= psample_nl_ops,
+	.n_small_ops	= ARRAY_SIZE(psample_nl_ops),
 	.n_mcgrps	= ARRAY_SIZE(psample_nl_mcgrps),
 };
 
diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c
index 90e3c70a91ad..1c7aa51cc2a3 100644
--- a/net/tipc/netlink_compat.c
+++ b/net/tipc/netlink_compat.c
@@ -1337,7 +1337,7 @@ static int tipc_nl_compat_recv(struct sk_buff *skb, struct genl_info *info)
 	return err;
 }
 
-static const struct genl_ops tipc_genl_compat_ops[] = {
+static const struct genl_small_ops tipc_genl_compat_ops[] = {
 	{
 		.cmd		= TIPC_GENL_CMD,
 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
@@ -1352,8 +1352,8 @@ static struct genl_family tipc_genl_compat_family __ro_after_init = {
 	.maxattr	= 0,
 	.netnsok	= true,
 	.module		= THIS_MODULE,
-	.ops		= tipc_genl_compat_ops,
-	.n_ops		= ARRAY_SIZE(tipc_genl_compat_ops),
+	.small_ops	= tipc_genl_compat_ops,
+	.n_small_ops	= ARRAY_SIZE(tipc_genl_compat_ops),
 };
 
 int __init tipc_netlink_compat_start(void)
diff --git a/net/wimax/stack.c b/net/wimax/stack.c
index 4b9b1c5e8f3a..b6dd9d956ed8 100644
--- a/net/wimax/stack.c
+++ b/net/wimax/stack.c
@@ -401,7 +401,7 @@ static const struct nla_policy wimax_gnl_policy[WIMAX_GNL_ATTR_MAX + 1] = {
 	},
 };
 
-static const struct genl_ops wimax_gnl_ops[] = {
+static const struct genl_small_ops wimax_gnl_ops[] = {
 	{
 		.cmd = WIMAX_GNL_OP_MSG_FROM_USER,
 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
@@ -560,8 +560,8 @@ struct genl_family wimax_gnl_family __ro_after_init = {
 	.maxattr = WIMAX_GNL_ATTR_MAX,
 	.policy = wimax_gnl_policy,
 	.module = THIS_MODULE,
-	.ops = wimax_gnl_ops,
-	.n_ops = ARRAY_SIZE(wimax_gnl_ops),
+	.small_ops = wimax_gnl_ops,
+	.n_small_ops = ARRAY_SIZE(wimax_gnl_ops),
 	.mcgrps = wimax_gnl_mcgrps,
 	.n_mcgrps = ARRAY_SIZE(wimax_gnl_mcgrps),
 };
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 1a212db7a300..ee852e70ac12 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -14603,6 +14603,9 @@ static const struct genl_ops nl80211_ops[] = {
 		.internal_flags = NL80211_FLAG_NEED_WIPHY |
 				  NL80211_FLAG_NEED_RTNL,
 	},
+};
+
+static const struct genl_small_ops nl80211_small_ops[] = {
 	{
 		.cmd = NL80211_CMD_SET_WIPHY,
 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
@@ -15464,6 +15467,8 @@ static struct genl_family nl80211_fam __ro_after_init = {
 	.module = THIS_MODULE,
 	.ops = nl80211_ops,
 	.n_ops = ARRAY_SIZE(nl80211_ops),
+	.small_ops = nl80211_small_ops,
+	.n_small_ops = ARRAY_SIZE(nl80211_small_ops),
 	.mcgrps = nl80211_mcgrps,
 	.n_mcgrps = ARRAY_SIZE(nl80211_mcgrps),
 	.parallel_ops = true,
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH net-next v2 04/10] genetlink: add a structure for dump state
  2020-10-01 22:59 [PATCH net-next v2 00/10] genetlink: support per-command policy dump Jakub Kicinski
                   ` (2 preceding siblings ...)
  2020-10-01 22:59 ` [PATCH net-next v2 03/10] genetlink: move to smaller ops wherever possible Jakub Kicinski
@ 2020-10-01 22:59 ` Jakub Kicinski
  2020-10-01 22:59 ` [PATCH net-next v2 05/10] genetlink: use .start callback for dumppolicy Jakub Kicinski
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 35+ messages in thread
From: Jakub Kicinski @ 2020-10-01 22:59 UTC (permalink / raw)
  To: davem
  Cc: netdev, andrew, johannes, jiri, mkubecek, dsahern, pablo, Jakub Kicinski

Whenever netlink dump uses more than 2 cb->args[] entries
code gets hard to read. We're about to add more state to
ctrl_dumppolicy() so create a structure.

Since the structure is typed and clearly named we can remove
the local fam_id variable and use ctx->fam_id directly.

v1:
 - s/nl_policy_dump/netlink_policy_dump_state/
 - forward declare struct netlink_policy_dump_state,
   and move from passing unsigned long to actual pointer type
 - add build bug on
 - u16 fam_id
 - s/args/ctx/

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Reviewed-by: Johannes Berg <johannes@sipsolutions.net>
---
 include/net/netlink.h   |  9 ++++++---
 net/netlink/genetlink.c | 24 +++++++++++++++---------
 net/netlink/policy.c    | 29 +++++++++++++++--------------
 3 files changed, 36 insertions(+), 26 deletions(-)

diff --git a/include/net/netlink.h b/include/net/netlink.h
index b2cf34f53e55..7ddf92ffce5a 100644
--- a/include/net/netlink.h
+++ b/include/net/netlink.h
@@ -1935,10 +1935,13 @@ void nla_get_range_unsigned(const struct nla_policy *pt,
 void nla_get_range_signed(const struct nla_policy *pt,
 			  struct netlink_range_validation_signed *range);
 
+struct netlink_policy_dump_state;
+
 int netlink_policy_dump_start(const struct nla_policy *policy,
 			      unsigned int maxtype,
-			      unsigned long *state);
-bool netlink_policy_dump_loop(unsigned long *state);
-int netlink_policy_dump_write(struct sk_buff *skb, unsigned long state);
+			      struct netlink_policy_dump_state **state);
+bool netlink_policy_dump_loop(struct netlink_policy_dump_state **state);
+int netlink_policy_dump_write(struct sk_buff *skb,
+			      struct netlink_policy_dump_state *state);
 
 #endif
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 094ebfff8889..c27653b61bcf 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -1102,13 +1102,20 @@ static int genl_ctrl_event(int event, const struct genl_family *family,
 	return 0;
 }
 
+struct ctrl_dump_policy_ctx {
+	struct netlink_policy_dump_state *state;
+	u16 fam_id;
+};
+
 static int ctrl_dumppolicy(struct sk_buff *skb, struct netlink_callback *cb)
 {
+	struct ctrl_dump_policy_ctx *ctx = (void *)cb->ctx;
 	const struct genl_family *rt;
-	unsigned int fam_id = cb->args[0];
 	int err;
 
-	if (!fam_id) {
+	BUILD_BUG_ON(sizeof(*ctx) > sizeof(cb->ctx));
+
+	if (!ctx->fam_id) {
 		struct nlattr *tb[CTRL_ATTR_MAX + 1];
 
 		err = genlmsg_parse(cb->nlh, &genl_ctrl, tb,
@@ -1121,28 +1128,28 @@ static int ctrl_dumppolicy(struct sk_buff *skb, struct netlink_callback *cb)
 			return -EINVAL;
 
 		if (tb[CTRL_ATTR_FAMILY_ID]) {
-			fam_id = nla_get_u16(tb[CTRL_ATTR_FAMILY_ID]);
+			ctx->fam_id = nla_get_u16(tb[CTRL_ATTR_FAMILY_ID]);
 		} else {
 			rt = genl_family_find_byname(
 				nla_data(tb[CTRL_ATTR_FAMILY_NAME]));
 			if (!rt)
 				return -ENOENT;
-			fam_id = rt->id;
+			ctx->fam_id = rt->id;
 		}
 	}
 
-	rt = genl_family_find_byid(fam_id);
+	rt = genl_family_find_byid(ctx->fam_id);
 	if (!rt)
 		return -ENOENT;
 
 	if (!rt->policy)
 		return -ENODATA;
 
-	err = netlink_policy_dump_start(rt->policy, rt->maxattr, &cb->args[1]);
+	err = netlink_policy_dump_start(rt->policy, rt->maxattr, &ctx->state);
 	if (err)
 		return err;
 
-	while (netlink_policy_dump_loop(&cb->args[1])) {
+	while (netlink_policy_dump_loop(&ctx->state)) {
 		void *hdr;
 		struct nlattr *nest;
 
@@ -1159,7 +1166,7 @@ static int ctrl_dumppolicy(struct sk_buff *skb, struct netlink_callback *cb)
 		if (!nest)
 			goto nla_put_failure;
 
-		if (netlink_policy_dump_write(skb, cb->args[1]))
+		if (netlink_policy_dump_write(skb, ctx->state))
 			goto nla_put_failure;
 
 		nla_nest_end(skb, nest);
@@ -1172,7 +1179,6 @@ static int ctrl_dumppolicy(struct sk_buff *skb, struct netlink_callback *cb)
 		break;
 	}
 
-	cb->args[0] = fam_id;
 	return skb->len;
 }
 
diff --git a/net/netlink/policy.c b/net/netlink/policy.c
index 62f977fa645a..5874734e41a1 100644
--- a/net/netlink/policy.c
+++ b/net/netlink/policy.c
@@ -14,7 +14,7 @@
 
 #define INITIAL_POLICIES_ALLOC	10
 
-struct nl_policy_dump {
+struct netlink_policy_dump_state {
 	unsigned int policy_idx;
 	unsigned int attr_idx;
 	unsigned int n_alloc;
@@ -24,11 +24,11 @@ struct nl_policy_dump {
 	} policies[];
 };
 
-static int add_policy(struct nl_policy_dump **statep,
+static int add_policy(struct netlink_policy_dump_state **statep,
 		      const struct nla_policy *policy,
 		      unsigned int maxtype)
 {
-	struct nl_policy_dump *state = *statep;
+	struct netlink_policy_dump_state *state = *statep;
 	unsigned int n_alloc, i;
 
 	if (!policy || !maxtype)
@@ -62,7 +62,7 @@ static int add_policy(struct nl_policy_dump **statep,
 	return 0;
 }
 
-static unsigned int get_policy_idx(struct nl_policy_dump *state,
+static unsigned int get_policy_idx(struct netlink_policy_dump_state *state,
 				   const struct nla_policy *policy)
 {
 	unsigned int i;
@@ -78,14 +78,14 @@ static unsigned int get_policy_idx(struct nl_policy_dump *state,
 
 int netlink_policy_dump_start(const struct nla_policy *policy,
 			      unsigned int maxtype,
-                              unsigned long *_state)
+                              struct netlink_policy_dump_state **statep)
 {
-	struct nl_policy_dump *state;
+	struct netlink_policy_dump_state *state;
 	unsigned int policy_idx;
 	int err;
 
 	/* also returns 0 if "*_state" is our ERR_PTR() end marker */
-	if (*_state)
+	if (*statep)
 		return 0;
 
 	/*
@@ -129,20 +129,21 @@ int netlink_policy_dump_start(const struct nla_policy *policy,
 		}
 	}
 
-	*_state = (unsigned long)state;
+	*statep = state;
 
 	return 0;
 }
 
-static bool netlink_policy_dump_finished(struct nl_policy_dump *state)
+static bool
+netlink_policy_dump_finished(struct netlink_policy_dump_state *state)
 {
 	return state->policy_idx >= state->n_alloc ||
 	       !state->policies[state->policy_idx].policy;
 }
 
-bool netlink_policy_dump_loop(unsigned long *_state)
+bool netlink_policy_dump_loop(struct netlink_policy_dump_state **statep)
 {
-	struct nl_policy_dump *state = (void *)*_state;
+	struct netlink_policy_dump_state *state = *statep;
 
 	if (IS_ERR(state))
 		return false;
@@ -150,16 +151,16 @@ bool netlink_policy_dump_loop(unsigned long *_state)
 	if (netlink_policy_dump_finished(state)) {
 		kfree(state);
 		/* store end marker instead of freed state */
-		*_state = (unsigned long)ERR_PTR(-ENOENT);
+		*statep = ERR_PTR(-ENOENT);
 		return false;
 	}
 
 	return true;
 }
 
-int netlink_policy_dump_write(struct sk_buff *skb, unsigned long _state)
+int netlink_policy_dump_write(struct sk_buff *skb,
+			      struct netlink_policy_dump_state *state)
 {
-	struct nl_policy_dump *state = (void *)_state;
 	const struct nla_policy *pt;
 	struct nlattr *policy, *attr;
 	enum netlink_attribute_type type;
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH net-next v2 05/10] genetlink: use .start callback for dumppolicy
  2020-10-01 22:59 [PATCH net-next v2 00/10] genetlink: support per-command policy dump Jakub Kicinski
                   ` (3 preceding siblings ...)
  2020-10-01 22:59 ` [PATCH net-next v2 04/10] genetlink: add a structure for dump state Jakub Kicinski
@ 2020-10-01 22:59 ` Jakub Kicinski
  2020-10-01 22:59 ` [PATCH net-next v2 06/10] genetlink: bring back per op policy Jakub Kicinski
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 35+ messages in thread
From: Jakub Kicinski @ 2020-10-01 22:59 UTC (permalink / raw)
  To: davem
  Cc: netdev, andrew, johannes, jiri, mkubecek, dsahern, pablo, Jakub Kicinski

The structure of ctrl_dumppolicy() is clearly split into
init and dumping. Move the init to a .start callback
for clarity, it's a more idiomatic netlink dump code structure.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Reviewed-by: Johannes Berg <johannes@sipsolutions.net>
---
 net/netlink/genetlink.c | 48 ++++++++++++++++++++---------------------
 1 file changed, 24 insertions(+), 24 deletions(-)

diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index c27653b61bcf..183f01e62ae9 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -1107,35 +1107,31 @@ struct ctrl_dump_policy_ctx {
 	u16 fam_id;
 };
 
-static int ctrl_dumppolicy(struct sk_buff *skb, struct netlink_callback *cb)
+static int ctrl_dumppolicy_start(struct netlink_callback *cb)
 {
 	struct ctrl_dump_policy_ctx *ctx = (void *)cb->ctx;
+	struct nlattr *tb[CTRL_ATTR_MAX + 1];
 	const struct genl_family *rt;
 	int err;
 
 	BUILD_BUG_ON(sizeof(*ctx) > sizeof(cb->ctx));
 
-	if (!ctx->fam_id) {
-		struct nlattr *tb[CTRL_ATTR_MAX + 1];
-
-		err = genlmsg_parse(cb->nlh, &genl_ctrl, tb,
-				    genl_ctrl.maxattr,
-				    genl_ctrl.policy, cb->extack);
-		if (err)
-			return err;
+	err = genlmsg_parse(cb->nlh, &genl_ctrl, tb, genl_ctrl.maxattr,
+			    genl_ctrl.policy, cb->extack);
+	if (err)
+		return err;
 
-		if (!tb[CTRL_ATTR_FAMILY_ID] && !tb[CTRL_ATTR_FAMILY_NAME])
-			return -EINVAL;
+	if (!tb[CTRL_ATTR_FAMILY_ID] && !tb[CTRL_ATTR_FAMILY_NAME])
+		return -EINVAL;
 
-		if (tb[CTRL_ATTR_FAMILY_ID]) {
-			ctx->fam_id = nla_get_u16(tb[CTRL_ATTR_FAMILY_ID]);
-		} else {
-			rt = genl_family_find_byname(
-				nla_data(tb[CTRL_ATTR_FAMILY_NAME]));
-			if (!rt)
-				return -ENOENT;
-			ctx->fam_id = rt->id;
-		}
+	if (tb[CTRL_ATTR_FAMILY_ID]) {
+		ctx->fam_id = nla_get_u16(tb[CTRL_ATTR_FAMILY_ID]);
+	} else {
+		rt = genl_family_find_byname(
+			nla_data(tb[CTRL_ATTR_FAMILY_NAME]));
+		if (!rt)
+			return -ENOENT;
+		ctx->fam_id = rt->id;
 	}
 
 	rt = genl_family_find_byid(ctx->fam_id);
@@ -1145,9 +1141,12 @@ static int ctrl_dumppolicy(struct sk_buff *skb, struct netlink_callback *cb)
 	if (!rt->policy)
 		return -ENODATA;
 
-	err = netlink_policy_dump_start(rt->policy, rt->maxattr, &ctx->state);
-	if (err)
-		return err;
+	return netlink_policy_dump_start(rt->policy, rt->maxattr, &ctx->state);
+}
+
+static int ctrl_dumppolicy(struct sk_buff *skb, struct netlink_callback *cb)
+{
+	struct ctrl_dump_policy_ctx *ctx = (void *)cb->ctx;
 
 	while (netlink_policy_dump_loop(&ctx->state)) {
 		void *hdr;
@@ -1159,7 +1158,7 @@ static int ctrl_dumppolicy(struct sk_buff *skb, struct netlink_callback *cb)
 		if (!hdr)
 			goto nla_put_failure;
 
-		if (nla_put_u16(skb, CTRL_ATTR_FAMILY_ID, rt->id))
+		if (nla_put_u16(skb, CTRL_ATTR_FAMILY_ID, ctx->fam_id))
 			goto nla_put_failure;
 
 		nest = nla_nest_start(skb, CTRL_ATTR_POLICY);
@@ -1191,6 +1190,7 @@ static const struct genl_ops genl_ctrl_ops[] = {
 	},
 	{
 		.cmd		= CTRL_CMD_GETPOLICY,
+		.start		= ctrl_dumppolicy_start,
 		.dumpit		= ctrl_dumppolicy,
 	},
 };
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH net-next v2 06/10] genetlink: bring back per op policy
  2020-10-01 22:59 [PATCH net-next v2 00/10] genetlink: support per-command policy dump Jakub Kicinski
                   ` (4 preceding siblings ...)
  2020-10-01 22:59 ` [PATCH net-next v2 05/10] genetlink: use .start callback for dumppolicy Jakub Kicinski
@ 2020-10-01 22:59 ` Jakub Kicinski
  2020-10-01 22:59 ` [PATCH net-next v2 07/10] taskstats: move specifying netlink policy back to ops Jakub Kicinski
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 35+ messages in thread
From: Jakub Kicinski @ 2020-10-01 22:59 UTC (permalink / raw)
  To: davem
  Cc: netdev, andrew, johannes, jiri, mkubecek, dsahern, pablo, Jakub Kicinski

Add policy to the struct genl_ops structure, this time
with maxattr, so it can be used properly.

Propagate .policy and .maxattr from the family
in genl_get_cmd() if needed, this way the rest of the
code does not have to worry if the policy is per op
or global.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Reviewed-by: Johannes Berg <johannes@sipsolutions.net>
---
 include/net/genetlink.h |  4 ++++
 net/netlink/genetlink.c | 18 +++++++++++++-----
 2 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/include/net/genetlink.h b/include/net/genetlink.h
index 8ea1fc1ed1c7..cb35625d001e 100644
--- a/include/net/genetlink.h
+++ b/include/net/genetlink.h
@@ -137,6 +137,8 @@ struct genl_small_ops {
  * @cmd: command identifier
  * @internal_flags: flags used by the family
  * @flags: flags
+ * @maxattr: maximum number of attributes supported
+ * @policy: netlink policy (takes precedence over family policy)
  * @doit: standard command callback
  * @start: start callback for dumps
  * @dumpit: callback for dumpers
@@ -149,6 +151,8 @@ struct genl_ops {
 	int		       (*dumpit)(struct sk_buff *skb,
 					 struct netlink_callback *cb);
 	int		       (*done)(struct netlink_callback *cb);
+	const struct nla_policy *policy;
+	unsigned int		maxattr;
 	u8			cmd;
 	u8			internal_flags;
 	u8			flags;
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 183f01e62ae9..2a3608cfb179 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -116,6 +116,11 @@ static void genl_op_from_full(const struct genl_family *family,
 			      unsigned int i, struct genl_ops *op)
 {
 	*op = family->ops[i];
+
+	if (!op->maxattr)
+		op->maxattr = family->maxattr;
+	if (!op->policy)
+		op->policy = family->policy;
 }
 
 static int genl_get_cmd_full(u8 cmd, const struct genl_family *family,
@@ -142,6 +147,9 @@ static void genl_op_from_small(const struct genl_family *family,
 	op->internal_flags = family->small_ops[i].internal_flags;
 	op->flags	= family->small_ops[i].flags;
 	op->validate	= family->small_ops[i].validate;
+
+	op->maxattr = family->maxattr;
+	op->policy = family->policy;
 }
 
 static int genl_get_cmd_small(u8 cmd, const struct genl_family *family,
@@ -529,16 +537,16 @@ genl_family_rcv_msg_attrs_parse(const struct genl_family *family,
 	struct nlattr **attrbuf;
 	int err;
 
-	if (!family->maxattr)
+	if (!ops->maxattr)
 		return NULL;
 
-	attrbuf = kmalloc_array(family->maxattr + 1,
+	attrbuf = kmalloc_array(ops->maxattr + 1,
 				sizeof(struct nlattr *), GFP_KERNEL);
 	if (!attrbuf)
 		return ERR_PTR(-ENOMEM);
 
-	err = __nlmsg_parse(nlh, hdrlen, attrbuf, family->maxattr,
-			    family->policy, validate, extack);
+	err = __nlmsg_parse(nlh, hdrlen, attrbuf, ops->maxattr, ops->policy,
+			    validate, extack);
 	if (err) {
 		kfree(attrbuf);
 		return ERR_PTR(err);
@@ -845,7 +853,7 @@ static int ctrl_fill_info(const struct genl_family *family, u32 portid, u32 seq,
 				op_flags |= GENL_CMD_CAP_DUMP;
 			if (op.doit)
 				op_flags |= GENL_CMD_CAP_DO;
-			if (family->policy)
+			if (op.policy)
 				op_flags |= GENL_CMD_CAP_HASPOL;
 
 			nest = nla_nest_start_noflag(skb, i + 1);
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH net-next v2 07/10] taskstats: move specifying netlink policy back to ops
  2020-10-01 22:59 [PATCH net-next v2 00/10] genetlink: support per-command policy dump Jakub Kicinski
                   ` (5 preceding siblings ...)
  2020-10-01 22:59 ` [PATCH net-next v2 06/10] genetlink: bring back per op policy Jakub Kicinski
@ 2020-10-01 22:59 ` Jakub Kicinski
  2020-10-01 22:59 ` [PATCH net-next v2 08/10] genetlink: use parsed attrs in dumppolicy Jakub Kicinski
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 35+ messages in thread
From: Jakub Kicinski @ 2020-10-01 22:59 UTC (permalink / raw)
  To: davem
  Cc: netdev, andrew, johannes, jiri, mkubecek, dsahern, pablo,
	Jakub Kicinski, bsingharora

commit 3b0f31f2b8c9 ("genetlink: make policy common to family")
had to work around removal of policy from ops by parsing in
the pre_doit callback. Now that policy is back in full ops
we can switch again. Set maxattr to actual size of the policies
- both commands set GENL_DONT_VALIDATE_STRICT so out of range
attributes will be silently ignored, anyway.

v2:
 - remove stale comment

Suggested-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Reviewed-by: Johannes Berg <johannes@sipsolutions.net>
---
CC: bsingharora@gmail.com
---
 kernel/taskstats.c | 46 ++++++++++------------------------------------
 1 file changed, 10 insertions(+), 36 deletions(-)

diff --git a/kernel/taskstats.c b/kernel/taskstats.c
index ef4de29fbe8a..a2802b6ff4bb 100644
--- a/kernel/taskstats.c
+++ b/kernel/taskstats.c
@@ -34,17 +34,13 @@ struct kmem_cache *taskstats_cache;
 
 static struct genl_family family;
 
-static const struct nla_policy taskstats_cmd_get_policy[TASKSTATS_CMD_ATTR_MAX+1] = {
+static const struct nla_policy taskstats_cmd_get_policy[] = {
 	[TASKSTATS_CMD_ATTR_PID]  = { .type = NLA_U32 },
 	[TASKSTATS_CMD_ATTR_TGID] = { .type = NLA_U32 },
 	[TASKSTATS_CMD_ATTR_REGISTER_CPUMASK] = { .type = NLA_STRING },
 	[TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK] = { .type = NLA_STRING },};
 
-/*
- * We have to use TASKSTATS_CMD_ATTR_MAX here, it is the maxattr in the family.
- * Make sure they are always aligned.
- */
-static const struct nla_policy cgroupstats_cmd_get_policy[TASKSTATS_CMD_ATTR_MAX+1] = {
+static const struct nla_policy cgroupstats_cmd_get_policy[] = {
 	[CGROUPSTATS_CMD_ATTR_FD] = { .type = NLA_U32 },
 };
 
@@ -644,52 +640,30 @@ void taskstats_exit(struct task_struct *tsk, int group_dead)
 	nlmsg_free(rep_skb);
 }
 
-static const struct genl_small_ops taskstats_ops[] = {
+static const struct genl_ops taskstats_ops[] = {
 	{
 		.cmd		= TASKSTATS_CMD_GET,
 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 		.doit		= taskstats_user_cmd,
-		/* policy enforced later */
-		.flags		= GENL_ADMIN_PERM | GENL_CMD_CAP_HASPOL,
+		.policy		= taskstats_cmd_get_policy,
+		.maxattr	= ARRAY_SIZE(taskstats_cmd_get_policy) - 1,
+		.flags		= GENL_ADMIN_PERM,
 	},
 	{
 		.cmd		= CGROUPSTATS_CMD_GET,
 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
 		.doit		= cgroupstats_user_cmd,
-		/* policy enforced later */
-		.flags		= GENL_CMD_CAP_HASPOL,
+		.policy		= cgroupstats_cmd_get_policy,
+		.maxattr	= ARRAY_SIZE(cgroupstats_cmd_get_policy) - 1,
 	},
 };
 
-static int taskstats_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
-			      struct genl_info *info)
-{
-	const struct nla_policy *policy = NULL;
-
-	switch (ops->cmd) {
-	case TASKSTATS_CMD_GET:
-		policy = taskstats_cmd_get_policy;
-		break;
-	case CGROUPSTATS_CMD_GET:
-		policy = cgroupstats_cmd_get_policy;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	return nlmsg_validate_deprecated(info->nlhdr, GENL_HDRLEN,
-					 TASKSTATS_CMD_ATTR_MAX, policy,
-					 info->extack);
-}
-
 static struct genl_family family __ro_after_init = {
 	.name		= TASKSTATS_GENL_NAME,
 	.version	= TASKSTATS_GENL_VERSION,
-	.maxattr	= TASKSTATS_CMD_ATTR_MAX,
 	.module		= THIS_MODULE,
-	.small_ops	= taskstats_ops,
-	.n_small_ops	= ARRAY_SIZE(taskstats_ops),
-	.pre_doit	= taskstats_pre_doit,
+	.ops		= taskstats_ops,
+	.n_ops		= ARRAY_SIZE(taskstats_ops),
 };
 
 /* Needed early in initialization */
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH net-next v2 08/10] genetlink: use parsed attrs in dumppolicy
  2020-10-01 22:59 [PATCH net-next v2 00/10] genetlink: support per-command policy dump Jakub Kicinski
                   ` (6 preceding siblings ...)
  2020-10-01 22:59 ` [PATCH net-next v2 07/10] taskstats: move specifying netlink policy back to ops Jakub Kicinski
@ 2020-10-01 22:59 ` Jakub Kicinski
  2020-10-02  6:30   ` Johannes Berg
  2020-10-01 22:59 ` [PATCH net-next v2 09/10] genetlink: switch control commands to per-op policies Jakub Kicinski
                   ` (2 subsequent siblings)
  10 siblings, 1 reply; 35+ messages in thread
From: Jakub Kicinski @ 2020-10-01 22:59 UTC (permalink / raw)
  To: davem
  Cc: netdev, andrew, johannes, jiri, mkubecek, dsahern, pablo, Jakub Kicinski

Attributes are already parsed based on the policy specified
in the family and ready-to-use in info->attrs. No need to
call genlmsg_parse() again.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 net/netlink/genetlink.c | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 2a3608cfb179..9e50a8e4abf9 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -1117,18 +1117,13 @@ struct ctrl_dump_policy_ctx {
 
 static int ctrl_dumppolicy_start(struct netlink_callback *cb)
 {
+	const struct genl_dumpit_info *info = genl_dumpit_info(cb);
 	struct ctrl_dump_policy_ctx *ctx = (void *)cb->ctx;
-	struct nlattr *tb[CTRL_ATTR_MAX + 1];
+	struct nlattr **tb = info->attrs;
 	const struct genl_family *rt;
-	int err;
 
 	BUILD_BUG_ON(sizeof(*ctx) > sizeof(cb->ctx));
 
-	err = genlmsg_parse(cb->nlh, &genl_ctrl, tb, genl_ctrl.maxattr,
-			    genl_ctrl.policy, cb->extack);
-	if (err)
-		return err;
-
 	if (!tb[CTRL_ATTR_FAMILY_ID] && !tb[CTRL_ATTR_FAMILY_NAME])
 		return -EINVAL;
 
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH net-next v2 09/10] genetlink: switch control commands to per-op policies
  2020-10-01 22:59 [PATCH net-next v2 00/10] genetlink: support per-command policy dump Jakub Kicinski
                   ` (7 preceding siblings ...)
  2020-10-01 22:59 ` [PATCH net-next v2 08/10] genetlink: use parsed attrs in dumppolicy Jakub Kicinski
@ 2020-10-01 22:59 ` Jakub Kicinski
  2020-10-02  6:33   ` Johannes Berg
  2020-10-01 22:59 ` [PATCH net-next v2 10/10] genetlink: allow dumping command-specific policy Jakub Kicinski
  2020-10-02  0:36 ` [PATCH net-next v2 00/10] genetlink: support per-command policy dump Jakub Kicinski
  10 siblings, 1 reply; 35+ messages in thread
From: Jakub Kicinski @ 2020-10-01 22:59 UTC (permalink / raw)
  To: davem
  Cc: netdev, andrew, johannes, jiri, mkubecek, dsahern, pablo, Jakub Kicinski

In preparation for adding a new attribute to CTRL_CMD_GETPOLICY
split the policies for getpolicy and getfamily apart.

This will cause a slight user-visible change in that dumping
the policies will switch from per family to per op, but
supposedly sniffer-type applications (which are the main use
case for policy dumping thus far) should support both, anyway.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 net/netlink/genetlink.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 9e50a8e4abf9..fc5d25bd5698 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -1016,7 +1016,7 @@ ctrl_build_mcgrp_msg(const struct genl_family *family,
 	return skb;
 }
 
-static const struct nla_policy ctrl_policy[CTRL_ATTR_MAX+1] = {
+static const struct nla_policy ctrl_policy_family[] = {
 	[CTRL_ATTR_FAMILY_ID]	= { .type = NLA_U16 },
 	[CTRL_ATTR_FAMILY_NAME]	= { .type = NLA_NUL_STRING,
 				    .len = GENL_NAMSIZ - 1 },
@@ -1115,6 +1115,12 @@ struct ctrl_dump_policy_ctx {
 	u16 fam_id;
 };
 
+static const struct nla_policy ctrl_policy_policy[] = {
+	[CTRL_ATTR_FAMILY_ID]	= { .type = NLA_U16 },
+	[CTRL_ATTR_FAMILY_NAME]	= { .type = NLA_NUL_STRING,
+				    .len = GENL_NAMSIZ - 1 },
+};
+
 static int ctrl_dumppolicy_start(struct netlink_callback *cb)
 {
 	const struct genl_dumpit_info *info = genl_dumpit_info(cb);
@@ -1188,11 +1194,15 @@ static const struct genl_ops genl_ctrl_ops[] = {
 	{
 		.cmd		= CTRL_CMD_GETFAMILY,
 		.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
+		.policy		= ctrl_policy_family,
+		.maxattr	= ARRAY_SIZE(ctrl_policy_family) - 1,
 		.doit		= ctrl_getfamily,
 		.dumpit		= ctrl_dumpfamily,
 	},
 	{
 		.cmd		= CTRL_CMD_GETPOLICY,
+		.policy		= ctrl_policy_policy,
+		.maxattr	= ARRAY_SIZE(ctrl_policy_policy) - 1,
 		.start		= ctrl_dumppolicy_start,
 		.dumpit		= ctrl_dumppolicy,
 	},
@@ -1211,8 +1221,6 @@ static struct genl_family genl_ctrl __ro_after_init = {
 	.id = GENL_ID_CTRL,
 	.name = "nlctrl",
 	.version = 0x2,
-	.maxattr = CTRL_ATTR_MAX,
-	.policy = ctrl_policy,
 	.netnsok = true,
 };
 
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* [PATCH net-next v2 10/10] genetlink: allow dumping command-specific policy
  2020-10-01 22:59 [PATCH net-next v2 00/10] genetlink: support per-command policy dump Jakub Kicinski
                   ` (8 preceding siblings ...)
  2020-10-01 22:59 ` [PATCH net-next v2 09/10] genetlink: switch control commands to per-op policies Jakub Kicinski
@ 2020-10-01 22:59 ` Jakub Kicinski
  2020-10-02  6:34   ` Johannes Berg
  2020-10-02  0:36 ` [PATCH net-next v2 00/10] genetlink: support per-command policy dump Jakub Kicinski
  10 siblings, 1 reply; 35+ messages in thread
From: Jakub Kicinski @ 2020-10-01 22:59 UTC (permalink / raw)
  To: davem
  Cc: netdev, andrew, johannes, jiri, mkubecek, dsahern, pablo, Jakub Kicinski

Right now CTRL_CMD_GETPOLICY can only dump the family-wide
policy. Support dumping policy of a specific op.

v2:
 - make cmd U32, just in case.
v1:
 - don't echo op in the output in a naive way, this should
   make it cleaner to extend the output format for dumping
   policies for all the commands at once in the future.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 include/uapi/linux/genetlink.h |  1 +
 net/netlink/genetlink.c        | 24 +++++++++++++++++++-----
 2 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/include/uapi/linux/genetlink.h b/include/uapi/linux/genetlink.h
index 9c0636ec2286..7dbe2d5d7d46 100644
--- a/include/uapi/linux/genetlink.h
+++ b/include/uapi/linux/genetlink.h
@@ -64,6 +64,7 @@ enum {
 	CTRL_ATTR_OPS,
 	CTRL_ATTR_MCAST_GROUPS,
 	CTRL_ATTR_POLICY,
+	CTRL_ATTR_OP,
 	__CTRL_ATTR_MAX,
 };
 
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index fc5d25bd5698..dd4b7a2979ac 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -123,7 +123,7 @@ static void genl_op_from_full(const struct genl_family *family,
 		op->policy = family->policy;
 }
 
-static int genl_get_cmd_full(u8 cmd, const struct genl_family *family,
+static int genl_get_cmd_full(u32 cmd, const struct genl_family *family,
 			     struct genl_ops *op)
 {
 	int i;
@@ -152,7 +152,7 @@ static void genl_op_from_small(const struct genl_family *family,
 	op->policy = family->policy;
 }
 
-static int genl_get_cmd_small(u8 cmd, const struct genl_family *family,
+static int genl_get_cmd_small(u32 cmd, const struct genl_family *family,
 			      struct genl_ops *op)
 {
 	int i;
@@ -166,7 +166,7 @@ static int genl_get_cmd_small(u8 cmd, const struct genl_family *family,
 	return -ENOENT;
 }
 
-static int genl_get_cmd(u8 cmd, const struct genl_family *family,
+static int genl_get_cmd(u32 cmd, const struct genl_family *family,
 			struct genl_ops *op)
 {
 	if (!genl_get_cmd_full(cmd, family, op))
@@ -1119,6 +1119,7 @@ static const struct nla_policy ctrl_policy_policy[] = {
 	[CTRL_ATTR_FAMILY_ID]	= { .type = NLA_U16 },
 	[CTRL_ATTR_FAMILY_NAME]	= { .type = NLA_NUL_STRING,
 				    .len = GENL_NAMSIZ - 1 },
+	[CTRL_ATTR_OP]		= { .type = NLA_U32 },
 };
 
 static int ctrl_dumppolicy_start(struct netlink_callback *cb)
@@ -1127,6 +1128,8 @@ static int ctrl_dumppolicy_start(struct netlink_callback *cb)
 	struct ctrl_dump_policy_ctx *ctx = (void *)cb->ctx;
 	struct nlattr **tb = info->attrs;
 	const struct genl_family *rt;
+	struct genl_ops op;
+	int err;
 
 	BUILD_BUG_ON(sizeof(*ctx) > sizeof(cb->ctx));
 
@@ -1147,10 +1150,21 @@ static int ctrl_dumppolicy_start(struct netlink_callback *cb)
 	if (!rt)
 		return -ENOENT;
 
-	if (!rt->policy)
+	if (tb[CTRL_ATTR_OP]) {
+		err = genl_get_cmd(nla_get_u32(tb[CTRL_ATTR_OP]), rt, &op);
+		if (err) {
+			NL_SET_BAD_ATTR(cb->extack, tb[CTRL_ATTR_OP]);
+			return err;
+		}
+	} else {
+		op.policy = rt->policy;
+		op.maxattr = rt->maxattr;
+	}
+
+	if (!op.policy)
 		return -ENODATA;
 
-	return netlink_policy_dump_start(rt->policy, rt->maxattr, &ctx->state);
+	return netlink_policy_dump_start(op.policy, op.maxattr, &ctx->state);
 }
 
 static int ctrl_dumppolicy(struct sk_buff *skb, struct netlink_callback *cb)
-- 
2.26.2


^ permalink raw reply related	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next v2 00/10] genetlink: support per-command policy dump
  2020-10-01 22:59 [PATCH net-next v2 00/10] genetlink: support per-command policy dump Jakub Kicinski
                   ` (9 preceding siblings ...)
  2020-10-01 22:59 ` [PATCH net-next v2 10/10] genetlink: allow dumping command-specific policy Jakub Kicinski
@ 2020-10-02  0:36 ` Jakub Kicinski
  2020-10-02  6:29   ` Johannes Berg
  10 siblings, 1 reply; 35+ messages in thread
From: Jakub Kicinski @ 2020-10-02  0:36 UTC (permalink / raw)
  To: davem; +Cc: netdev, andrew, johannes, jiri, mkubecek, dsahern, pablo

On Thu,  1 Oct 2020 15:59:23 -0700 Jakub Kicinski wrote:
> Hi!
> 
> The objective of this series is to dump ethtool policies
> to be able to tell which flags are supported by the kernel.
> Current release adds ETHTOOL_FLAG_STATS for dumping extra
> stats, but because of strict checking we need to make sure
> that the flag is actually supported before setting it in
> a request.

Do we need support for separate .doit and .dumpit policies?
Or is that an overkill?

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next v2 00/10] genetlink: support per-command policy dump
  2020-10-02  0:36 ` [PATCH net-next v2 00/10] genetlink: support per-command policy dump Jakub Kicinski
@ 2020-10-02  6:29   ` Johannes Berg
  2020-10-02 14:40     ` Jakub Kicinski
  0 siblings, 1 reply; 35+ messages in thread
From: Johannes Berg @ 2020-10-02  6:29 UTC (permalink / raw)
  To: Jakub Kicinski, davem; +Cc: netdev, andrew, jiri, mkubecek, dsahern, pablo

On Thu, 2020-10-01 at 17:36 -0700, Jakub Kicinski wrote:
> On Thu,  1 Oct 2020 15:59:23 -0700 Jakub Kicinski wrote:
> > Hi!
> > 
> > The objective of this series is to dump ethtool policies
> > to be able to tell which flags are supported by the kernel.
> > Current release adds ETHTOOL_FLAG_STATS for dumping extra
> > stats, but because of strict checking we need to make sure
> > that the flag is actually supported before setting it in
> > a request.
> 
> Do we need support for separate .doit and .dumpit policies?
> Or is that an overkill?

I suppose you could make an argument that only some attrs might be
accepted in doit and somewhat others in dumpit, or perhaps none in
dumpit because filtering wasn't implemented?

But still ... often we treat filtering as "advisory" anyway (except
perhaps where there's no doit at all, like the dump_policy thing here),
so it wouldn't matter if some attribute is ending up ignored?

johannes


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next v2 08/10] genetlink: use parsed attrs in dumppolicy
  2020-10-01 22:59 ` [PATCH net-next v2 08/10] genetlink: use parsed attrs in dumppolicy Jakub Kicinski
@ 2020-10-02  6:30   ` Johannes Berg
  0 siblings, 0 replies; 35+ messages in thread
From: Johannes Berg @ 2020-10-02  6:30 UTC (permalink / raw)
  To: Jakub Kicinski, davem; +Cc: netdev, andrew, jiri, mkubecek, dsahern, pablo

On Thu, 2020-10-01 at 15:59 -0700, Jakub Kicinski wrote:
> Attributes are already parsed based on the policy specified
> in the family and ready-to-use in info->attrs. No need to
> call genlmsg_parse() again.

:)

Reviewed-by: Johannes Berg <johannes@sipsolutions.net>

johannes


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next v2 09/10] genetlink: switch control commands to per-op policies
  2020-10-01 22:59 ` [PATCH net-next v2 09/10] genetlink: switch control commands to per-op policies Jakub Kicinski
@ 2020-10-02  6:33   ` Johannes Berg
  0 siblings, 0 replies; 35+ messages in thread
From: Johannes Berg @ 2020-10-02  6:33 UTC (permalink / raw)
  To: Jakub Kicinski, davem; +Cc: netdev, andrew, jiri, mkubecek, dsahern, pablo

On Thu, 2020-10-01 at 15:59 -0700, Jakub Kicinski wrote:
> In preparation for adding a new attribute to CTRL_CMD_GETPOLICY
> split the policies for getpolicy and getfamily apart.
> 
> This will cause a slight user-visible change in that dumping
> the policies will switch from per family to per op, but
> supposedly sniffer-type applications (which are the main use
> case for policy dumping thus far) 

For the record, I don't think anything there has actually been
implemented ... I've been meaning to, but not gotten to it, the only
thing I had done was a "dummy" policy dump helper in iproute2/genl.

Which I guess will no longer work with this, and thus I should in fact
implement the scheme I outlined for dumping all commands at once, so the
"manual" introspection there can work again.

Still, it's all very new and not really in use yet, so I see no issues
with it all.

Reviewed-by: Johannes Berg <johannes@sipsolutions.net>

johannes



^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next v2 10/10] genetlink: allow dumping command-specific policy
  2020-10-01 22:59 ` [PATCH net-next v2 10/10] genetlink: allow dumping command-specific policy Jakub Kicinski
@ 2020-10-02  6:34   ` Johannes Berg
  0 siblings, 0 replies; 35+ messages in thread
From: Johannes Berg @ 2020-10-02  6:34 UTC (permalink / raw)
  To: Jakub Kicinski, davem; +Cc: netdev, andrew, jiri, mkubecek, dsahern, pablo

On Thu, 2020-10-01 at 15:59 -0700, Jakub Kicinski wrote:
> Right now CTRL_CMD_GETPOLICY can only dump the family-wide
> policy. Support dumping policy of a specific op.
> 
> v2:
>  - make cmd U32, just in case.
> v1:
>  - don't echo op in the output in a naive way, this should
>    make it cleaner to extend the output format for dumping
>    policies for all the commands at once in the future.

Great, thanks :)

Reviewed-by: Johannes Berg <johannes@sipsolutions.net>

johannes


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next v2 00/10] genetlink: support per-command policy dump
  2020-10-02  6:29   ` Johannes Berg
@ 2020-10-02 14:40     ` Jakub Kicinski
  2020-10-02 14:42       ` Johannes Berg
  0 siblings, 1 reply; 35+ messages in thread
From: Jakub Kicinski @ 2020-10-02 14:40 UTC (permalink / raw)
  To: Johannes Berg; +Cc: davem, netdev, andrew, jiri, mkubecek, dsahern, pablo

On Fri, 02 Oct 2020 08:29:27 +0200 Johannes Berg wrote:
> On Thu, 2020-10-01 at 17:36 -0700, Jakub Kicinski wrote:
> > Do we need support for separate .doit and .dumpit policies?
> > Or is that an overkill?  
> 
> I suppose you could make an argument that only some attrs might be
> accepted in doit and somewhat others in dumpit, or perhaps none in
> dumpit because filtering wasn't implemented?

Right? Feels like it goes against our strict validation policy to
ignore input on dumpit.

> But still ... often we treat filtering as "advisory" anyway (except
> perhaps where there's no doit at all, like the dump_policy thing here),
> so it wouldn't matter if some attribute is ending up ignored?

It may be useful for feature discovery to know if an attribute is
supported.

I don't think it matters for any user right now, but maybe we should
require user space to specify if they are interested in normal req
policy or dump policy? That'd give us the ability to report different
ones in the future when the need arises.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next v2 00/10] genetlink: support per-command policy dump
  2020-10-02 14:40     ` Jakub Kicinski
@ 2020-10-02 14:42       ` Johannes Berg
  2020-10-02 14:55         ` Jakub Kicinski
  0 siblings, 1 reply; 35+ messages in thread
From: Johannes Berg @ 2020-10-02 14:42 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: davem, netdev, andrew, jiri, mkubecek, dsahern, pablo

On Fri, 2020-10-02 at 07:40 -0700, Jakub Kicinski wrote:

> > I suppose you could make an argument that only some attrs might be
> > accepted in doit and somewhat others in dumpit, or perhaps none in
> > dumpit because filtering wasn't implemented?
> 
> Right? Feels like it goes against our strict validation policy to
> ignore input on dumpit.
> 
> > But still ... often we treat filtering as "advisory" anyway (except
> > perhaps where there's no doit at all, like the dump_policy thing here),
> > so it wouldn't matter if some attribute is ending up ignored?
> 
> It may be useful for feature discovery to know if an attribute is
> supported.

Fair point.

> I don't think it matters for any user right now, but maybe we should
> require user space to specify if they are interested in normal req
> policy or dump policy? That'd give us the ability to report different
> ones in the future when the need arises.

Or just give them both? I mean, in many (most?) cases they're anyway
going to be the same, so with the patches I posted you could just give
them the two different policy indexes, and they can be the same?

But whichever, doesn't really matter much.

johannes


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next v2 00/10] genetlink: support per-command policy dump
  2020-10-02 14:42       ` Johannes Berg
@ 2020-10-02 14:55         ` Jakub Kicinski
  2020-10-02 14:58           ` Johannes Berg
  0 siblings, 1 reply; 35+ messages in thread
From: Jakub Kicinski @ 2020-10-02 14:55 UTC (permalink / raw)
  To: Johannes Berg; +Cc: davem, netdev, andrew, jiri, mkubecek, dsahern, pablo

On Fri, 02 Oct 2020 16:42:09 +0200 Johannes Berg wrote:
> On Fri, 2020-10-02 at 07:40 -0700, Jakub Kicinski wrote:
> 
> > > I suppose you could make an argument that only some attrs might be
> > > accepted in doit and somewhat others in dumpit, or perhaps none in
> > > dumpit because filtering wasn't implemented?  
> > 
> > Right? Feels like it goes against our strict validation policy to
> > ignore input on dumpit.
> >   
> > > But still ... often we treat filtering as "advisory" anyway (except
> > > perhaps where there's no doit at all, like the dump_policy thing here),
> > > so it wouldn't matter if some attribute is ending up ignored?  
> > 
> > It may be useful for feature discovery to know if an attribute is
> > supported.  
> 
> Fair point.
> 
> > I don't think it matters for any user right now, but maybe we should
> > require user space to specify if they are interested in normal req
> > policy or dump policy? That'd give us the ability to report different
> > ones in the future when the need arises.  
> 
> Or just give them both? I mean, in many (most?) cases they're anyway
> going to be the same, so with the patches I posted you could just give
> them the two different policy indexes, and they can be the same?

Ah, I missed your posting! Like this?

[OP_POLICY]
   [OP]
      [DO]   -> u32
      [DUMP] -> u32

> But whichever, doesn't really matter much.


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next v2 00/10] genetlink: support per-command policy dump
  2020-10-02 14:55         ` Jakub Kicinski
@ 2020-10-02 14:58           ` Johannes Berg
  2020-10-02 15:03             ` Jakub Kicinski
  0 siblings, 1 reply; 35+ messages in thread
From: Johannes Berg @ 2020-10-02 14:58 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: davem, netdev, andrew, jiri, mkubecek, dsahern, pablo


> > Or just give them both? I mean, in many (most?) cases they're anyway
> > going to be the same, so with the patches I posted you could just give
> > them the two different policy indexes, and they can be the same?
> 
> Ah, I missed your posting!

Huh, I even CC'ed you I think?

https://lore.kernel.org/netdev/20201002090944.195891-1-johannes@sipsolutions.net/t/#u

and userspace:

https://lore.kernel.org/netdev/20201002102609.224150-1-johannes@sipsolutions.net/t/#u

>  Like this?
> 
> [OP_POLICY]
>    [OP]
>       [DO]   -> u32
>       [DUMP] -> u32

Yeah, that'd work. I'd probably wonder if we shouldn't do

[OP_POLICY]
  [OP] -> (u32, u32)

in a struct with two u32's, since that's quite a bit more compact.

I did only:

[OP_POLICY]
  [OP] -> u32

johannes


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next v2 00/10] genetlink: support per-command policy dump
  2020-10-02 14:58           ` Johannes Berg
@ 2020-10-02 15:03             ` Jakub Kicinski
  2020-10-02 15:04               ` Johannes Berg
  0 siblings, 1 reply; 35+ messages in thread
From: Jakub Kicinski @ 2020-10-02 15:03 UTC (permalink / raw)
  To: Johannes Berg; +Cc: davem, netdev, andrew, jiri, mkubecek, dsahern, pablo

On Fri, 02 Oct 2020 16:58:33 +0200 Johannes Berg wrote:
> > > Or just give them both? I mean, in many (most?) cases they're anyway
> > > going to be the same, so with the patches I posted you could just give
> > > them the two different policy indexes, and they can be the same?  
> > 
> > Ah, I missed your posting!  
> 
> Huh, I even CC'ed you I think?

I filter stuff which is to:netdev cc:me and get to it when I read the
ML. There's too much of it.

> https://lore.kernel.org/netdev/20201002090944.195891-1-johannes@sipsolutions.net/t/#u
> 
> and userspace:
> 
> https://lore.kernel.org/netdev/20201002102609.224150-1-johannes@sipsolutions.net/t/#u
> 
> >  Like this?
> > 
> > [OP_POLICY]
> >    [OP]
> >       [DO]   -> u32
> >       [DUMP] -> u32  
> 
> Yeah, that'd work. I'd probably wonder if we shouldn't do
> 
> [OP_POLICY]
>   [OP] -> (u32, u32)
> 
> in a struct with two u32's, since that's quite a bit more compact.

What do we do if the op doesn't have a dump or do callback?
0 is a valid policy ID, sadly :(

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next v2 00/10] genetlink: support per-command policy dump
  2020-10-02 15:03             ` Jakub Kicinski
@ 2020-10-02 15:04               ` Johannes Berg
  2020-10-02 15:09                 ` Jakub Kicinski
  0 siblings, 1 reply; 35+ messages in thread
From: Johannes Berg @ 2020-10-02 15:04 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: davem, netdev, andrew, jiri, mkubecek, dsahern, pablo

On Fri, 2020-10-02 at 08:03 -0700, Jakub Kicinski wrote:

> > Huh, I even CC'ed you I think?
> 
> I filter stuff which is to:netdev cc:me and get to it when I read the
> ML. There's too much of it.

Ah, ok :)

> > Yeah, that'd work. I'd probably wonder if we shouldn't do
> > 
> > [OP_POLICY]
> >   [OP] -> (u32, u32)
> > 
> > in a struct with two u32's, since that's quite a bit more compact.
> 
> What do we do if the op doesn't have a dump or do callback?
> 0 is a valid policy ID, sadly :(

Hm, good point. We could do -1 since that can't ever be reached though.

But compactness isn't really that necessary here anyway, so ...

johannes


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next v2 00/10] genetlink: support per-command policy dump
  2020-10-02 15:04               ` Johannes Berg
@ 2020-10-02 15:09                 ` Jakub Kicinski
  2020-10-02 15:13                   ` Johannes Berg
  2020-10-02 20:27                   ` Johannes Berg
  0 siblings, 2 replies; 35+ messages in thread
From: Jakub Kicinski @ 2020-10-02 15:09 UTC (permalink / raw)
  To: Johannes Berg; +Cc: davem, netdev, andrew, jiri, mkubecek, dsahern, pablo

On Fri, 02 Oct 2020 17:04:11 +0200 Johannes Berg wrote:
> > > Yeah, that'd work. I'd probably wonder if we shouldn't do
> > > 
> > > [OP_POLICY]
> > >   [OP] -> (u32, u32)
> > > 
> > > in a struct with two u32's, since that's quite a bit more compact.  
> > 
> > What do we do if the op doesn't have a dump or do callback?
> > 0 is a valid policy ID, sadly :(  
> 
> Hm, good point. We could do -1 since that can't ever be reached though.
> 
> But compactness isn't really that necessary here anyway, so ...

Cool, sounds like a plan.

This series should be good to merge, then.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next v2 00/10] genetlink: support per-command policy dump
  2020-10-02 15:09                 ` Jakub Kicinski
@ 2020-10-02 15:13                   ` Johannes Berg
  2020-10-02 15:25                     ` Jakub Kicinski
  2020-10-02 20:27                   ` Johannes Berg
  1 sibling, 1 reply; 35+ messages in thread
From: Johannes Berg @ 2020-10-02 15:13 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: davem, netdev, andrew, jiri, mkubecek, dsahern, pablo

On Fri, 2020-10-02 at 08:09 -0700, Jakub Kicinski wrote:
> On Fri, 02 Oct 2020 17:04:11 +0200 Johannes Berg wrote:
> > > > Yeah, that'd work. I'd probably wonder if we shouldn't do
> > > > 
> > > > [OP_POLICY]
> > > >   [OP] -> (u32, u32)
> > > > 
> > > > in a struct with two u32's, since that's quite a bit more compact.  
> > > 
> > > What do we do if the op doesn't have a dump or do callback?
> > > 0 is a valid policy ID, sadly :(  
> > 
> > Hm, good point. We could do -1 since that can't ever be reached though.
> > 
> > But compactness isn't really that necessary here anyway, so ...
> 
> Cool, sounds like a plan.
> 
> This series should be good to merge, then.

I suppose, I thought you wanted to change it to have separate dump/do
policies? Whatever you like there, I don't really care much :)

But I can also change my patches later to separately advertise dump/do
policies, and simply always use the same one for now.

But this series does conflict with the little bugfix I also sent, could
you please take a look?

https://lore.kernel.org/netdev/20201002094604.480c760e3c47.I7811da1539351a26cd0e5a10b98a8842cfbc1b55@changeid/

I'm not really sure how to handle.

Thanks,
johannes


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next v2 00/10] genetlink: support per-command policy dump
  2020-10-02 15:13                   ` Johannes Berg
@ 2020-10-02 15:25                     ` Jakub Kicinski
  2020-10-02 15:28                       ` Johannes Berg
                                         ` (2 more replies)
  0 siblings, 3 replies; 35+ messages in thread
From: Jakub Kicinski @ 2020-10-02 15:25 UTC (permalink / raw)
  To: Johannes Berg, davem; +Cc: netdev, andrew, jiri, mkubecek, dsahern, pablo

On Fri, 02 Oct 2020 17:13:28 +0200 Johannes Berg wrote:
> On Fri, 2020-10-02 at 08:09 -0700, Jakub Kicinski wrote:
> > On Fri, 02 Oct 2020 17:04:11 +0200 Johannes Berg wrote:  
> > > > > Yeah, that'd work. I'd probably wonder if we shouldn't do
> > > > > 
> > > > > [OP_POLICY]
> > > > >   [OP] -> (u32, u32)
> > > > > 
> > > > > in a struct with two u32's, since that's quite a bit more compact.    
> > > > 
> > > > What do we do if the op doesn't have a dump or do callback?
> > > > 0 is a valid policy ID, sadly :(    
> > > 
> > > Hm, good point. We could do -1 since that can't ever be reached though.
> > > 
> > > But compactness isn't really that necessary here anyway, so ...  
> > 
> > Cool, sounds like a plan.
> > 
> > This series should be good to merge, then.  
> 
> I suppose, I thought you wanted to change it to have separate dump/do
> policies? Whatever you like there, I don't really care much :)

I just want to make the uAPI future-proof for now.

At a quick look ethtool doesn't really accept any attributes but
headers for GET requests. DO and DUMP are the same there so it's 
not a priority for me.

> But I can also change my patches later to separately advertise dump/do
> policies, and simply always use the same one for now.

Right that was what I was thinking. Basically:

	if ((op.doit && nla_put_u32(skb, CTRL_whatever_DO, idx)) ||
	    (op.dumpit && nla_put_u32(skb, CTRL_whatever_DUMP, idx)))
		goto nla_put_failure;

> But this series does conflict with the little bugfix I also sent, could
> you please take a look?
> 
> https://lore.kernel.org/netdev/20201002094604.480c760e3c47.I7811da1539351a26cd0e5a10b98a8842cfbc1b55@changeid/
> 
> I'm not really sure how to handle.

Yeah, just noticed that one now :S

Dave, are you planning a PR to Linus soon by any chance? The conflict
between this series and Johannes's fix would be logically simple to
resolve but not trivial :(

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next v2 00/10] genetlink: support per-command policy dump
  2020-10-02 15:25                     ` Jakub Kicinski
@ 2020-10-02 15:28                       ` Johannes Berg
  2020-10-02 16:55                       ` Michal Kubecek
  2020-10-02 20:07                       ` David Miller
  2 siblings, 0 replies; 35+ messages in thread
From: Johannes Berg @ 2020-10-02 15:28 UTC (permalink / raw)
  To: Jakub Kicinski, davem; +Cc: netdev, andrew, jiri, mkubecek, dsahern, pablo

On Fri, 2020-10-02 at 08:25 -0700, Jakub Kicinski wrote:
> 
> > I suppose, I thought you wanted to change it to have separate dump/do
> > policies? Whatever you like there, I don't really care much :)
> 
> I just want to make the uAPI future-proof for now.

Yeah, makes sense.

> At a quick look ethtool doesn't really accept any attributes but
> headers for GET requests. DO and DUMP are the same there so it's 
> not a priority for me.

OK.

> > But I can also change my patches later to separately advertise dump/do
> > policies, and simply always use the same one for now.
> 
> Right that was what I was thinking. Basically:
> 
> 	if ((op.doit && nla_put_u32(skb, CTRL_whatever_DO, idx)) ||
> 	    (op.dumpit && nla_put_u32(skb, CTRL_whatever_DUMP, idx)))
> 		goto nla_put_failure;

Right, easy enough.

> > But this series does conflict with the little bugfix I also sent, could
> > you please take a look?
> > 
> > https://lore.kernel.org/netdev/20201002094604.480c760e3c47.I7811da1539351a26cd0e5a10b98a8842cfbc1b55@changeid/
> > 
> > I'm not really sure how to handle.
> 
> Yeah, just noticed that one now :S

Yeah, sorry ... The conflicts indeed weren't difficult, but non-trivial
unless you know what's going on in each side. I pushed them to my
mac80211-next tree, in the genetlink-op-policy-export branch (not sure
you saw my patches and cover letter yet :) )

I'll wait for this to get resolved and then respin my patches with the
above doit/dumpit after your series is in, and will also respin the
userspace side then.

johannes


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next v2 00/10] genetlink: support per-command policy dump
  2020-10-02 15:25                     ` Jakub Kicinski
  2020-10-02 15:28                       ` Johannes Berg
@ 2020-10-02 16:55                       ` Michal Kubecek
  2020-10-02 20:07                       ` David Miller
  2 siblings, 0 replies; 35+ messages in thread
From: Michal Kubecek @ 2020-10-02 16:55 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: Johannes Berg, davem, netdev, andrew, jiri, dsahern, pablo

On Fri, Oct 02, 2020 at 08:25:17AM -0700, Jakub Kicinski wrote:
> On Fri, 02 Oct 2020 17:13:28 +0200 Johannes Berg wrote:
> > I suppose, I thought you wanted to change it to have separate dump/do
> > policies? Whatever you like there, I don't really care much :)
> 
> I just want to make the uAPI future-proof for now.
> 
> At a quick look ethtool doesn't really accept any attributes but
> headers for GET requests. DO and DUMP are the same there so it's 
> not a priority for me.

This is likely to change, for -x / --show-rxfh-indir / --show-rxfh we
will neeed to specify RSS context id. This is also an example where
different policy for doit and dumpit would make sense.

Michal

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next v2 00/10] genetlink: support per-command policy dump
  2020-10-02 15:25                     ` Jakub Kicinski
  2020-10-02 15:28                       ` Johannes Berg
  2020-10-02 16:55                       ` Michal Kubecek
@ 2020-10-02 20:07                       ` David Miller
  2 siblings, 0 replies; 35+ messages in thread
From: David Miller @ 2020-10-02 20:07 UTC (permalink / raw)
  To: kuba; +Cc: johannes, netdev, andrew, jiri, mkubecek, dsahern, pablo

From: Jakub Kicinski <kuba@kernel.org>
Date: Fri, 2 Oct 2020 08:25:17 -0700

> Dave, are you planning a PR to Linus soon by any chance? The conflict
> between this series and Johannes's fix would be logically simple to
> resolve but not trivial :(

Let me apply Johannes's fix to both net and net-next, and then you can
respin a v3 of this series on top of that.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next v2 00/10] genetlink: support per-command policy dump
  2020-10-02 15:09                 ` Jakub Kicinski
  2020-10-02 15:13                   ` Johannes Berg
@ 2020-10-02 20:27                   ` Johannes Berg
  2020-10-02 20:50                     ` Jakub Kicinski
  1 sibling, 1 reply; 35+ messages in thread
From: Johannes Berg @ 2020-10-02 20:27 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: davem, netdev, andrew, jiri, mkubecek, dsahern, pablo

On Fri, 2020-10-02 at 08:09 -0700, Jakub Kicinski wrote:
> On Fri, 02 Oct 2020 17:04:11 +0200 Johannes Berg wrote:
> > > > Yeah, that'd work. I'd probably wonder if we shouldn't do
> > > > 
> > > > [OP_POLICY]
> > > >   [OP] -> (u32, u32)
> > > > 
> > > > in a struct with two u32's, since that's quite a bit more compact.  
> > > 
> > > What do we do if the op doesn't have a dump or do callback?
> > > 0 is a valid policy ID, sadly :(  
> > 
> > Hm, good point. We could do -1 since that can't ever be reached though.
> > 
> > But compactness isn't really that necessary here anyway, so ...
> 
> Cool, sounds like a plan.
> 
> This series should be good to merge, then.

So I'm having second thoughts on this now :)

If you ask me to split the policy dump to do/dump, like we discussed
above, then what you did here for "retrieve a single policy" doesn't
really make any sense? Because you'd be able to do that properly only
for do, or you need my patches to get both?

Perhaps it would make sense if you removed patch 10 from your set, and
we add it back after my patches?

Or I could submit my patches right after yours, but that leaves the code
between the commits doing something weird, in that it would only give
you the policies but no indication of which is for do/dump? Obviously
today it'd only be one, but still, from a uAPI perspective.

I guess it doesn't matter too much though, we get to the state that we
want to be in, just the intermediate steps won't necessarily make much
sense.

For now I'll respin my patches so we see how the above do/dump
separating looks.

johannes


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next v2 00/10] genetlink: support per-command policy dump
  2020-10-02 20:27                   ` Johannes Berg
@ 2020-10-02 20:50                     ` Jakub Kicinski
  2020-10-02 20:59                       ` Johannes Berg
  0 siblings, 1 reply; 35+ messages in thread
From: Jakub Kicinski @ 2020-10-02 20:50 UTC (permalink / raw)
  To: Johannes Berg; +Cc: davem, netdev, andrew, jiri, mkubecek, dsahern, pablo

On Fri, 02 Oct 2020 22:27:19 +0200 Johannes Berg wrote:
> On Fri, 2020-10-02 at 08:09 -0700, Jakub Kicinski wrote:
> > On Fri, 02 Oct 2020 17:04:11 +0200 Johannes Berg wrote:  
> > > > > Yeah, that'd work. I'd probably wonder if we shouldn't do
> > > > > 
> > > > > [OP_POLICY]
> > > > >   [OP] -> (u32, u32)
> > > > > 
> > > > > in a struct with two u32's, since that's quite a bit more compact.    
> > > > 
> > > > What do we do if the op doesn't have a dump or do callback?
> > > > 0 is a valid policy ID, sadly :(    
> > > 
> > > Hm, good point. We could do -1 since that can't ever be reached though.
> > > 
> > > But compactness isn't really that necessary here anyway, so ...  
> > 
> > Cool, sounds like a plan.
> > 
> > This series should be good to merge, then.  
> 
> So I'm having second thoughts on this now :)
> 
> If you ask me to split the policy dump to do/dump, like we discussed
> above, then what you did here for "retrieve a single policy" doesn't
> really make any sense? Because you'd be able to do that properly only
> for do, or you need my patches to get both?
> 
> Perhaps it would make sense if you removed patch 10 from your set, and
> we add it back after my patches?
> 
> Or I could submit my patches right after yours, but that leaves the code
> between the commits doing something weird, in that it would only give
> you the policies but no indication of which is for do/dump? Obviously
> today it'd only be one, but still, from a uAPI perspective.

My thinking was that until kernel actually start using separate dump
policies user space can assume policy 0 is relevant. But yeah, merging
your changes first would probably be best.

> I guess it doesn't matter too much though, we get to the state that we
> want to be in, just the intermediate steps won't necessarily make much
> sense.
> 
> For now I'll respin my patches so we see how the above do/dump
> separating looks.

I, OTOH, am having second thoughts about not implementing separate
policies for dump right away, since Michal said he'll need them soon :)

Any ideas on how to do that cleanly? At some point it will make sense
to have dumps and doits in separate structures, as you said earlier,
but can we have "small" and "full" ops for both? That seems like too
much :/

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next v2 00/10] genetlink: support per-command policy dump
  2020-10-02 20:50                     ` Jakub Kicinski
@ 2020-10-02 20:59                       ` Johannes Berg
  2020-10-02 21:00                         ` Johannes Berg
  0 siblings, 1 reply; 35+ messages in thread
From: Johannes Berg @ 2020-10-02 20:59 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: davem, netdev, andrew, jiri, mkubecek, dsahern, pablo

On Fri, 2020-10-02 at 13:50 -0700, Jakub Kicinski wrote:
> 
> My thinking was that until kernel actually start using separate dump
> policies user space can assume policy 0 is relevant. But yeah, merging
> your changes first would probably be best.

Works for me. I have it based on yours. Just updated my branch (top
commit is 4d5045adfe90), but I'll probably only actually email it out
once things are a bit more settled wrt. your changes.

> I, OTOH, am having second thoughts about not implementing separate
> policies for dump right away, since Michal said he'll need them soon :)

:)

> Any ideas on how to do that cleanly? At some point it will make sense
> to have dumps and doits in separate structures, as you said earlier,
> but can we have "small" and "full" ops for both? That seems like too
> much :/

Not sure I understand what you just wrote :)

I had originally assumed dumps would be "infrequent", and so having the
small ops without dumps would be worthwhile. You said it wasn't true for
other users, so small ops still have .doit and .dumpit entries. Which is
fine?

But in the small ops anyway you don't have a policy pointer - I guess
you could have two "fallbacks" (for do and dump) in the family rather
than just one?

Another option - though it requires some rejiggering in my new policy
dump code - would be to key the lookup based on do/dump as well. Then
you could have the *same* op listed twice like

struct genl_ops my_ops[] = {
	{
		.cmd = SOMETHING,
		.doit = do_something,
		.policy = something_do_policy,
	},
	{
		.cmd = SOMETHING,
		.dumpit = dump_something,
		.policy = something_dump_policy,
	},
};

That way you only pay where needed? But ultimately with large ops you
already pay for the start/dump/done pointers, and you'd have that even
for the extra entry with _doit_ because ...

Unless we put three different kinds of ops (small, full-do, full-dump),
but that gets a bit awkward too?

johannes


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next v2 00/10] genetlink: support per-command policy dump
  2020-10-02 20:59                       ` Johannes Berg
@ 2020-10-02 21:00                         ` Johannes Berg
  2020-10-02 21:17                           ` Jakub Kicinski
  0 siblings, 1 reply; 35+ messages in thread
From: Johannes Berg @ 2020-10-02 21:00 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: davem, netdev, andrew, jiri, mkubecek, dsahern, pablo

On Fri, 2020-10-02 at 22:59 +0200, Johannes Berg wrote:
> On Fri, 2020-10-02 at 13:50 -0700, Jakub Kicinski wrote:
> > My thinking was that until kernel actually start using separate dump
> > policies user space can assume policy 0 is relevant. But yeah, merging
> > your changes first would probably be best.
> 
> Works for me. I have it based on yours. Just updated my branch (top
> commit is 4d5045adfe90), but I'll probably only actually email it out
> once things are a bit more settled wrt. your changes.

Forgot the link ...

https://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git/log/?h=genetlink-op-policy-export

johannes


^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next v2 00/10] genetlink: support per-command policy dump
  2020-10-02 21:00                         ` Johannes Berg
@ 2020-10-02 21:17                           ` Jakub Kicinski
  2020-10-02 21:22                             ` Jakub Kicinski
  0 siblings, 1 reply; 35+ messages in thread
From: Jakub Kicinski @ 2020-10-02 21:17 UTC (permalink / raw)
  To: Johannes Berg; +Cc: davem, netdev, andrew, jiri, mkubecek, dsahern, pablo

On Fri, 02 Oct 2020 23:00:15 +0200 Johannes Berg wrote:
> On Fri, 2020-10-02 at 22:59 +0200, Johannes Berg wrote:
> > On Fri, 2020-10-02 at 13:50 -0700, Jakub Kicinski wrote:  
> > > My thinking was that until kernel actually start using separate dump
> > > policies user space can assume policy 0 is relevant. But yeah, merging
> > > your changes first would probably be best.  
> > 
> > Works for me. I have it based on yours. Just updated my branch (top
> > commit is 4d5045adfe90), but I'll probably only actually email it out
> > once things are a bit more settled wrt. your changes.  
> 
> Forgot the link ...
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git/log/?h=genetlink-op-policy-export

If it's not too late for you - do you want to merge the two series and
post everything together? Perhaps squashing patch 10 into something if
that makes sense?

You already seem to have it rebased.

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next v2 00/10] genetlink: support per-command policy dump
  2020-10-02 21:17                           ` Jakub Kicinski
@ 2020-10-02 21:22                             ` Jakub Kicinski
  2020-10-02 21:52                               ` Jakub Kicinski
  0 siblings, 1 reply; 35+ messages in thread
From: Jakub Kicinski @ 2020-10-02 21:22 UTC (permalink / raw)
  To: Johannes Berg; +Cc: davem, netdev, andrew, jiri, mkubecek, dsahern, pablo

On Fri, 2 Oct 2020 14:17:01 -0700 Jakub Kicinski wrote:
> On Fri, 02 Oct 2020 23:00:15 +0200 Johannes Berg wrote:
> > On Fri, 2020-10-02 at 22:59 +0200, Johannes Berg wrote:  
> > > On Fri, 2020-10-02 at 13:50 -0700, Jakub Kicinski wrote:    
> > > > My thinking was that until kernel actually start using separate dump
> > > > policies user space can assume policy 0 is relevant. But yeah, merging
> > > > your changes first would probably be best.    
> > > 
> > > Works for me. I have it based on yours. Just updated my branch (top
> > > commit is 4d5045adfe90), but I'll probably only actually email it out
> > > once things are a bit more settled wrt. your changes.    
> > 
> > Forgot the link ...
> > 
> > https://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git/log/?h=genetlink-op-policy-export  
> 
> If it's not too late for you - do you want to merge the two series and
> post everything together? Perhaps squashing patch 10 into something if
> that makes sense?
> 
> You already seem to have it rebased.

FWIW earlier I said:

	if ((op.doit && nla_put_u32(skb, CTRL_whatever_DO, idx)) ||
	    (op.dumpit && nla_put_u32(skb, CTRL_whatever_DUMP, idx)))
		goto nla_put_failure;

 - we should probably also check GENL_DONT_VALIDATE_DUMP here?

^ permalink raw reply	[flat|nested] 35+ messages in thread

* Re: [PATCH net-next v2 00/10] genetlink: support per-command policy dump
  2020-10-02 21:22                             ` Jakub Kicinski
@ 2020-10-02 21:52                               ` Jakub Kicinski
  0 siblings, 0 replies; 35+ messages in thread
From: Jakub Kicinski @ 2020-10-02 21:52 UTC (permalink / raw)
  To: Johannes Berg; +Cc: davem, netdev, andrew, jiri, mkubecek, dsahern, pablo

On Fri, 2 Oct 2020 14:22:05 -0700 Jakub Kicinski wrote:
> > > Forgot the link ...
> > > 
> > > https://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git/log/?h=genetlink-op-policy-export    
> > 
> > If it's not too late for you - do you want to merge the two series and
> > post everything together? Perhaps squashing patch 10 into something if
> > that makes sense?
> > 
> > You already seem to have it rebased.  

After double checking your tree has @policy in the wrong kdoc.

Let me post the first 9 patches and please squash patch 10 into your
series.

> FWIW earlier I said:
> 
> 	if ((op.doit && nla_put_u32(skb, CTRL_whatever_DO, idx)) ||
> 	    (op.dumpit && nla_put_u32(skb, CTRL_whatever_DUMP, idx)))
> 		goto nla_put_failure;
> 
>  - we should probably also check GENL_DONT_VALIDATE_DUMP here?


^ permalink raw reply	[flat|nested] 35+ messages in thread

end of thread, other threads:[~2020-10-02 21:52 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-10-01 22:59 [PATCH net-next v2 00/10] genetlink: support per-command policy dump Jakub Kicinski
2020-10-01 22:59 ` [PATCH net-next v2 01/10] genetlink: reorg struct genl_family Jakub Kicinski
2020-10-01 22:59 ` [PATCH net-next v2 02/10] genetlink: add small version of ops Jakub Kicinski
2020-10-01 22:59 ` [PATCH net-next v2 03/10] genetlink: move to smaller ops wherever possible Jakub Kicinski
2020-10-01 22:59 ` [PATCH net-next v2 04/10] genetlink: add a structure for dump state Jakub Kicinski
2020-10-01 22:59 ` [PATCH net-next v2 05/10] genetlink: use .start callback for dumppolicy Jakub Kicinski
2020-10-01 22:59 ` [PATCH net-next v2 06/10] genetlink: bring back per op policy Jakub Kicinski
2020-10-01 22:59 ` [PATCH net-next v2 07/10] taskstats: move specifying netlink policy back to ops Jakub Kicinski
2020-10-01 22:59 ` [PATCH net-next v2 08/10] genetlink: use parsed attrs in dumppolicy Jakub Kicinski
2020-10-02  6:30   ` Johannes Berg
2020-10-01 22:59 ` [PATCH net-next v2 09/10] genetlink: switch control commands to per-op policies Jakub Kicinski
2020-10-02  6:33   ` Johannes Berg
2020-10-01 22:59 ` [PATCH net-next v2 10/10] genetlink: allow dumping command-specific policy Jakub Kicinski
2020-10-02  6:34   ` Johannes Berg
2020-10-02  0:36 ` [PATCH net-next v2 00/10] genetlink: support per-command policy dump Jakub Kicinski
2020-10-02  6:29   ` Johannes Berg
2020-10-02 14:40     ` Jakub Kicinski
2020-10-02 14:42       ` Johannes Berg
2020-10-02 14:55         ` Jakub Kicinski
2020-10-02 14:58           ` Johannes Berg
2020-10-02 15:03             ` Jakub Kicinski
2020-10-02 15:04               ` Johannes Berg
2020-10-02 15:09                 ` Jakub Kicinski
2020-10-02 15:13                   ` Johannes Berg
2020-10-02 15:25                     ` Jakub Kicinski
2020-10-02 15:28                       ` Johannes Berg
2020-10-02 16:55                       ` Michal Kubecek
2020-10-02 20:07                       ` David Miller
2020-10-02 20:27                   ` Johannes Berg
2020-10-02 20:50                     ` Jakub Kicinski
2020-10-02 20:59                       ` Johannes Berg
2020-10-02 21:00                         ` Johannes Berg
2020-10-02 21:17                           ` Jakub Kicinski
2020-10-02 21:22                             ` Jakub Kicinski
2020-10-02 21:52                               ` Jakub Kicinski

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.