Skip to content

Commit 678cdd4

Browse files
committed
Merge branch 'genetlink-support-per-command-policy-dump'
Jakub Kicinski says: ==================== genetlink: support per-command policy dump 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 5 patches deal the dumping per-op policy. v3: The actually patch to dump per-op policy was taken out and will come in a series from Johannes, to make sure uAPI is consistent from the start. For dump-specific policies I think it should be fine to add a new pair of members to the "full" ops, and not overthink it. 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. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 5a38b4f + a4bb4f5 commit 678cdd4

File tree

36 files changed

+334
-244
lines changed

36 files changed

+334
-244
lines changed

drivers/block/nbd.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2183,7 +2183,7 @@ static int nbd_genl_reconfigure(struct sk_buff *skb, struct genl_info *info)
21832183
return ret;
21842184
}
21852185

2186-
static const struct genl_ops nbd_connect_genl_ops[] = {
2186+
static const struct genl_small_ops nbd_connect_genl_ops[] = {
21872187
{
21882188
.cmd = NBD_CMD_CONNECT,
21892189
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
@@ -2215,8 +2215,8 @@ static struct genl_family nbd_genl_family __ro_after_init = {
22152215
.name = NBD_GENL_FAMILY_NAME,
22162216
.version = NBD_GENL_VERSION,
22172217
.module = THIS_MODULE,
2218-
.ops = nbd_connect_genl_ops,
2219-
.n_ops = ARRAY_SIZE(nbd_connect_genl_ops),
2218+
.small_ops = nbd_connect_genl_ops,
2219+
.n_small_ops = ARRAY_SIZE(nbd_connect_genl_ops),
22202220
.maxattr = NBD_ATTR_MAX,
22212221
.policy = nbd_attr_policy,
22222222
.mcgrps = nbd_mcast_grps,

drivers/net/gtp.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1339,7 +1339,7 @@ static const struct nla_policy gtp_genl_policy[GTPA_MAX + 1] = {
13391339
[GTPA_O_TEI] = { .type = NLA_U32, },
13401340
};
13411341

1342-
static const struct genl_ops gtp_genl_ops[] = {
1342+
static const struct genl_small_ops gtp_genl_ops[] = {
13431343
{
13441344
.cmd = GTP_CMD_NEWPDP,
13451345
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
@@ -1369,8 +1369,8 @@ static struct genl_family gtp_genl_family __ro_after_init = {
13691369
.policy = gtp_genl_policy,
13701370
.netnsok = true,
13711371
.module = THIS_MODULE,
1372-
.ops = gtp_genl_ops,
1373-
.n_ops = ARRAY_SIZE(gtp_genl_ops),
1372+
.small_ops = gtp_genl_ops,
1373+
.n_small_ops = ARRAY_SIZE(gtp_genl_ops),
13741374
.mcgrps = gtp_genl_mcgrps,
13751375
.n_mcgrps = ARRAY_SIZE(gtp_genl_mcgrps),
13761376
};

drivers/net/ieee802154/mac802154_hwsim.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -583,7 +583,7 @@ static const struct nla_policy hwsim_genl_policy[MAC802154_HWSIM_ATTR_MAX + 1] =
583583
};
584584

585585
/* Generic Netlink operations array */
586-
static const struct genl_ops hwsim_nl_ops[] = {
586+
static const struct genl_small_ops hwsim_nl_ops[] = {
587587
{
588588
.cmd = MAC802154_HWSIM_CMD_NEW_RADIO,
589589
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
@@ -628,8 +628,8 @@ static struct genl_family hwsim_genl_family __ro_after_init = {
628628
.maxattr = MAC802154_HWSIM_ATTR_MAX,
629629
.policy = hwsim_genl_policy,
630630
.module = THIS_MODULE,
631-
.ops = hwsim_nl_ops,
632-
.n_ops = ARRAY_SIZE(hwsim_nl_ops),
631+
.small_ops = hwsim_nl_ops,
632+
.n_small_ops = ARRAY_SIZE(hwsim_nl_ops),
633633
.mcgrps = hwsim_mcgrps,
634634
.n_mcgrps = ARRAY_SIZE(hwsim_mcgrps),
635635
};

drivers/net/macsec.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3285,7 +3285,7 @@ static int macsec_dump_txsc(struct sk_buff *skb, struct netlink_callback *cb)
32853285
return skb->len;
32863286
}
32873287

3288-
static const struct genl_ops macsec_genl_ops[] = {
3288+
static const struct genl_small_ops macsec_genl_ops[] = {
32893289
{
32903290
.cmd = MACSEC_CMD_GET_TXSC,
32913291
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
@@ -3361,8 +3361,8 @@ static struct genl_family macsec_fam __ro_after_init = {
33613361
.policy = macsec_genl_policy,
33623362
.netnsok = true,
33633363
.module = THIS_MODULE,
3364-
.ops = macsec_genl_ops,
3365-
.n_ops = ARRAY_SIZE(macsec_genl_ops),
3364+
.small_ops = macsec_genl_ops,
3365+
.n_small_ops = ARRAY_SIZE(macsec_genl_ops),
33663366
};
33673367

33683368
static netdev_tx_t macsec_start_xmit(struct sk_buff *skb,

drivers/net/team/team.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2795,7 +2795,7 @@ static int team_nl_cmd_port_list_get(struct sk_buff *skb,
27952795
return err;
27962796
}
27972797

2798-
static const struct genl_ops team_nl_ops[] = {
2798+
static const struct genl_small_ops team_nl_ops[] = {
27992799
{
28002800
.cmd = TEAM_CMD_NOOP,
28012801
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
@@ -2832,8 +2832,8 @@ static struct genl_family team_nl_family __ro_after_init = {
28322832
.policy = team_nl_policy,
28332833
.netnsok = true,
28342834
.module = THIS_MODULE,
2835-
.ops = team_nl_ops,
2836-
.n_ops = ARRAY_SIZE(team_nl_ops),
2835+
.small_ops = team_nl_ops,
2836+
.n_small_ops = ARRAY_SIZE(team_nl_ops),
28372837
.mcgrps = team_nl_mcgrps,
28382838
.n_mcgrps = ARRAY_SIZE(team_nl_mcgrps),
28392839
};

drivers/net/wireless/mac80211_hwsim.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3964,7 +3964,7 @@ static int hwsim_dump_radio_nl(struct sk_buff *skb,
39643964
}
39653965

39663966
/* Generic Netlink operations array */
3967-
static const struct genl_ops hwsim_ops[] = {
3967+
static const struct genl_small_ops hwsim_ops[] = {
39683968
{
39693969
.cmd = HWSIM_CMD_REGISTER,
39703970
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
@@ -4008,8 +4008,8 @@ static struct genl_family hwsim_genl_family __ro_after_init = {
40084008
.policy = hwsim_genl_policy,
40094009
.netnsok = true,
40104010
.module = THIS_MODULE,
4011-
.ops = hwsim_ops,
4012-
.n_ops = ARRAY_SIZE(hwsim_ops),
4011+
.small_ops = hwsim_ops,
4012+
.n_small_ops = ARRAY_SIZE(hwsim_ops),
40134013
.mcgrps = hwsim_mcgrps,
40144014
.n_mcgrps = ARRAY_SIZE(hwsim_mcgrps),
40154015
};

drivers/target/target_core_user.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,7 @@ static int tcmu_genl_set_features(struct sk_buff *skb, struct genl_info *info)
436436
return 0;
437437
}
438438

439-
static const struct genl_ops tcmu_genl_ops[] = {
439+
static const struct genl_small_ops tcmu_genl_ops[] = {
440440
{
441441
.cmd = TCMU_CMD_SET_FEATURES,
442442
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
@@ -474,8 +474,8 @@ static struct genl_family tcmu_genl_family __ro_after_init = {
474474
.mcgrps = tcmu_mcgrps,
475475
.n_mcgrps = ARRAY_SIZE(tcmu_mcgrps),
476476
.netnsok = true,
477-
.ops = tcmu_genl_ops,
478-
.n_ops = ARRAY_SIZE(tcmu_genl_ops),
477+
.small_ops = tcmu_genl_ops,
478+
.n_small_ops = ARRAY_SIZE(tcmu_genl_ops),
479479
};
480480

481481
#define tcmu_cmd_set_dbi_cur(cmd, index) ((cmd)->dbi_cur = (index))

drivers/thermal/thermal_netlink.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -545,7 +545,7 @@ static int thermal_genl_cmd_dumpit(struct sk_buff *skb,
545545
{
546546
struct param p = { .msg = skb };
547547
const struct genl_dumpit_info *info = genl_dumpit_info(cb);
548-
int cmd = info->ops->cmd;
548+
int cmd = info->op.cmd;
549549
int ret;
550550
void *hdr;
551551

@@ -601,7 +601,7 @@ static int thermal_genl_cmd_doit(struct sk_buff *skb,
601601
return ret;
602602
}
603603

604-
static const struct genl_ops thermal_genl_ops[] = {
604+
static const struct genl_small_ops thermal_genl_ops[] = {
605605
{
606606
.cmd = THERMAL_GENL_CMD_TZ_GET_ID,
607607
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
@@ -635,8 +635,8 @@ static struct genl_family thermal_gnl_family __ro_after_init = {
635635
.version = THERMAL_GENL_VERSION,
636636
.maxattr = THERMAL_GENL_ATTR_MAX,
637637
.policy = thermal_genl_policy,
638-
.ops = thermal_genl_ops,
639-
.n_ops = ARRAY_SIZE(thermal_genl_ops),
638+
.small_ops = thermal_genl_ops,
639+
.n_small_ops = ARRAY_SIZE(thermal_genl_ops),
640640
.mcgrps = thermal_genl_mcgrps,
641641
.n_mcgrps = ARRAY_SIZE(thermal_genl_mcgrps),
642642
};

fs/dlm/netlink.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ static int user_cmd(struct sk_buff *skb, struct genl_info *info)
6262
return 0;
6363
}
6464

65-
static const struct genl_ops dlm_nl_ops[] = {
65+
static const struct genl_small_ops dlm_nl_ops[] = {
6666
{
6767
.cmd = DLM_CMD_HELLO,
6868
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
@@ -73,8 +73,8 @@ static const struct genl_ops dlm_nl_ops[] = {
7373
static struct genl_family family __ro_after_init = {
7474
.name = DLM_GENL_NAME,
7575
.version = DLM_GENL_VERSION,
76-
.ops = dlm_nl_ops,
77-
.n_ops = ARRAY_SIZE(dlm_nl_ops),
76+
.small_ops = dlm_nl_ops,
77+
.n_small_ops = ARRAY_SIZE(dlm_nl_ops),
7878
.module = THIS_MODULE,
7979
};
8080

include/net/genetlink.h

Lines changed: 48 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,21 @@ struct genl_info;
4141
* (private)
4242
* @ops: the operations supported by this family
4343
* @n_ops: number of operations supported by this family
44+
* @small_ops: the small-struct operations supported by this family
45+
* @n_small_ops: number of small-struct operations supported by this family
4446
*/
4547
struct genl_family {
4648
int id; /* private */
4749
unsigned int hdrsize;
4850
char name[GENL_NAMSIZ];
4951
unsigned int version;
5052
unsigned int maxattr;
51-
bool netnsok;
52-
bool parallel_ops;
53+
unsigned int mcgrp_offset; /* private */
54+
u8 netnsok:1;
55+
u8 parallel_ops:1;
56+
u8 n_ops;
57+
u8 n_small_ops;
58+
u8 n_mcgrps;
5359
const struct nla_policy *policy;
5460
int (*pre_doit)(const struct genl_ops *ops,
5561
struct sk_buff *skb,
@@ -58,10 +64,8 @@ struct genl_family {
5864
struct sk_buff *skb,
5965
struct genl_info *info);
6066
const struct genl_ops * ops;
67+
const struct genl_small_ops *small_ops;
6168
const struct genl_multicast_group *mcgrps;
62-
unsigned int n_ops;
63-
unsigned int n_mcgrps;
64-
unsigned int mcgrp_offset; /* private */
6569
struct module *module;
6670
};
6771

@@ -108,28 +112,33 @@ enum genl_validate_flags {
108112
};
109113

110114
/**
111-
* struct genl_info - info that is available during dumpit op call
112-
* @family: generic netlink family - for internal genl code usage
113-
* @ops: generic netlink ops - for internal genl code usage
114-
* @attrs: netlink attributes
115+
* struct genl_small_ops - generic netlink operations (small version)
116+
* @cmd: command identifier
117+
* @internal_flags: flags used by the family
118+
* @flags: flags
119+
* @validate: validation flags from enum genl_validate_flags
120+
* @doit: standard command callback
121+
* @dumpit: callback for dumpers
122+
*
123+
* This is a cut-down version of struct genl_ops for users who don't need
124+
* most of the ancillary infra and want to save space.
115125
*/
116-
struct genl_dumpit_info {
117-
const struct genl_family *family;
118-
const struct genl_ops *ops;
119-
struct nlattr **attrs;
126+
struct genl_small_ops {
127+
int (*doit)(struct sk_buff *skb, struct genl_info *info);
128+
int (*dumpit)(struct sk_buff *skb, struct netlink_callback *cb);
129+
u8 cmd;
130+
u8 internal_flags;
131+
u8 flags;
132+
u8 validate;
120133
};
121134

122-
static inline const struct genl_dumpit_info *
123-
genl_dumpit_info(struct netlink_callback *cb)
124-
{
125-
return cb->data;
126-
}
127-
128135
/**
129136
* struct genl_ops - generic netlink operations
130137
* @cmd: command identifier
131138
* @internal_flags: flags used by the family
132139
* @flags: flags
140+
* @maxattr: maximum number of attributes supported
141+
* @policy: netlink policy (takes precedence over family policy)
133142
* @doit: standard command callback
134143
* @start: start callback for dumps
135144
* @dumpit: callback for dumpers
@@ -142,12 +151,32 @@ struct genl_ops {
142151
int (*dumpit)(struct sk_buff *skb,
143152
struct netlink_callback *cb);
144153
int (*done)(struct netlink_callback *cb);
154+
const struct nla_policy *policy;
155+
unsigned int maxattr;
145156
u8 cmd;
146157
u8 internal_flags;
147158
u8 flags;
148159
u8 validate;
149160
};
150161

162+
/**
163+
* struct genl_info - info that is available during dumpit op call
164+
* @family: generic netlink family - for internal genl code usage
165+
* @ops: generic netlink ops - for internal genl code usage
166+
* @attrs: netlink attributes
167+
*/
168+
struct genl_dumpit_info {
169+
const struct genl_family *family;
170+
struct genl_ops op;
171+
struct nlattr **attrs;
172+
};
173+
174+
static inline const struct genl_dumpit_info *
175+
genl_dumpit_info(struct netlink_callback *cb)
176+
{
177+
return cb->data;
178+
}
179+
151180
int genl_register_family(struct genl_family *family);
152181
int genl_unregister_family(const struct genl_family *family);
153182
void genl_notify(const struct genl_family *family, struct sk_buff *skb,

include/net/netlink.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1935,11 +1935,14 @@ void nla_get_range_unsigned(const struct nla_policy *pt,
19351935
void nla_get_range_signed(const struct nla_policy *pt,
19361936
struct netlink_range_validation_signed *range);
19371937

1938+
struct netlink_policy_dump_state;
1939+
19381940
int netlink_policy_dump_start(const struct nla_policy *policy,
19391941
unsigned int maxtype,
1940-
unsigned long *state);
1941-
bool netlink_policy_dump_loop(unsigned long state);
1942-
int netlink_policy_dump_write(struct sk_buff *skb, unsigned long state);
1943-
void netlink_policy_dump_free(unsigned long state);
1942+
struct netlink_policy_dump_state **state);
1943+
bool netlink_policy_dump_loop(struct netlink_policy_dump_state *state);
1944+
int netlink_policy_dump_write(struct sk_buff *skb,
1945+
struct netlink_policy_dump_state *state);
1946+
void netlink_policy_dump_free(struct netlink_policy_dump_state *state);
19441947

19451948
#endif

kernel/taskstats.c

Lines changed: 7 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,13 @@ struct kmem_cache *taskstats_cache;
3434

3535
static struct genl_family family;
3636

37-
static const struct nla_policy taskstats_cmd_get_policy[TASKSTATS_CMD_ATTR_MAX+1] = {
37+
static const struct nla_policy taskstats_cmd_get_policy[] = {
3838
[TASKSTATS_CMD_ATTR_PID] = { .type = NLA_U32 },
3939
[TASKSTATS_CMD_ATTR_TGID] = { .type = NLA_U32 },
4040
[TASKSTATS_CMD_ATTR_REGISTER_CPUMASK] = { .type = NLA_STRING },
4141
[TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK] = { .type = NLA_STRING },};
4242

43-
/*
44-
* We have to use TASKSTATS_CMD_ATTR_MAX here, it is the maxattr in the family.
45-
* Make sure they are always aligned.
46-
*/
47-
static const struct nla_policy cgroupstats_cmd_get_policy[TASKSTATS_CMD_ATTR_MAX+1] = {
43+
static const struct nla_policy cgroupstats_cmd_get_policy[] = {
4844
[CGROUPSTATS_CMD_ATTR_FD] = { .type = NLA_U32 },
4945
};
5046

@@ -649,47 +645,25 @@ static const struct genl_ops taskstats_ops[] = {
649645
.cmd = TASKSTATS_CMD_GET,
650646
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
651647
.doit = taskstats_user_cmd,
652-
/* policy enforced later */
653-
.flags = GENL_ADMIN_PERM | GENL_CMD_CAP_HASPOL,
648+
.policy = taskstats_cmd_get_policy,
649+
.maxattr = ARRAY_SIZE(taskstats_cmd_get_policy) - 1,
650+
.flags = GENL_ADMIN_PERM,
654651
},
655652
{
656653
.cmd = CGROUPSTATS_CMD_GET,
657654
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
658655
.doit = cgroupstats_user_cmd,
659-
/* policy enforced later */
660-
.flags = GENL_CMD_CAP_HASPOL,
656+
.policy = cgroupstats_cmd_get_policy,
657+
.maxattr = ARRAY_SIZE(cgroupstats_cmd_get_policy) - 1,
661658
},
662659
};
663660

664-
static int taskstats_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
665-
struct genl_info *info)
666-
{
667-
const struct nla_policy *policy = NULL;
668-
669-
switch (ops->cmd) {
670-
case TASKSTATS_CMD_GET:
671-
policy = taskstats_cmd_get_policy;
672-
break;
673-
case CGROUPSTATS_CMD_GET:
674-
policy = cgroupstats_cmd_get_policy;
675-
break;
676-
default:
677-
return -EINVAL;
678-
}
679-
680-
return nlmsg_validate_deprecated(info->nlhdr, GENL_HDRLEN,
681-
TASKSTATS_CMD_ATTR_MAX, policy,
682-
info->extack);
683-
}
684-
685661
static struct genl_family family __ro_after_init = {
686662
.name = TASKSTATS_GENL_NAME,
687663
.version = TASKSTATS_GENL_VERSION,
688-
.maxattr = TASKSTATS_CMD_ATTR_MAX,
689664
.module = THIS_MODULE,
690665
.ops = taskstats_ops,
691666
.n_ops = ARRAY_SIZE(taskstats_ops),
692-
.pre_doit = taskstats_pre_doit,
693667
};
694668

695669
/* Needed early in initialization */

0 commit comments

Comments
 (0)