Skip to content

Commit e992a6e

Browse files
kuba-moodavem330
authored andcommitted
genetlink: allow dumping command-specific policy
Right now CTRL_CMD_GETPOLICY can only dump the family-wide policy. Support dumping policy of a specific op. v3: - rebase after per-op policy export and handle that 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 <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Johannes Berg <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 50a896c commit e992a6e

File tree

2 files changed

+37
-5
lines changed

2 files changed

+37
-5
lines changed

include/uapi/linux/genetlink.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ enum {
6565
CTRL_ATTR_MCAST_GROUPS,
6666
CTRL_ATTR_POLICY,
6767
CTRL_ATTR_OP_POLICY,
68+
CTRL_ATTR_OP,
6869
__CTRL_ATTR_MAX,
6970
};
7071

net/netlink/genetlink.c

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ static void genl_op_from_full(const struct genl_family *family,
123123
op->policy = family->policy;
124124
}
125125

126-
static int genl_get_cmd_full(u8 cmd, const struct genl_family *family,
126+
static int genl_get_cmd_full(u32 cmd, const struct genl_family *family,
127127
struct genl_ops *op)
128128
{
129129
int i;
@@ -152,7 +152,7 @@ static void genl_op_from_small(const struct genl_family *family,
152152
op->policy = family->policy;
153153
}
154154

155-
static int genl_get_cmd_small(u8 cmd, const struct genl_family *family,
155+
static int genl_get_cmd_small(u32 cmd, const struct genl_family *family,
156156
struct genl_ops *op)
157157
{
158158
int i;
@@ -166,7 +166,7 @@ static int genl_get_cmd_small(u8 cmd, const struct genl_family *family,
166166
return -ENOENT;
167167
}
168168

169-
static int genl_get_cmd(u8 cmd, const struct genl_family *family,
169+
static int genl_get_cmd(u32 cmd, const struct genl_family *family,
170170
struct genl_ops *op)
171171
{
172172
if (!genl_get_cmd_full(cmd, family, op))
@@ -1114,14 +1114,17 @@ struct ctrl_dump_policy_ctx {
11141114
struct netlink_policy_dump_state *state;
11151115
const struct genl_family *rt;
11161116
unsigned int opidx;
1117+
u32 op;
11171118
u16 fam_id;
1118-
u8 policies:1;
1119+
u8 policies:1,
1120+
single_op:1;
11191121
};
11201122

11211123
static const struct nla_policy ctrl_policy_policy[] = {
11221124
[CTRL_ATTR_FAMILY_ID] = { .type = NLA_U16 },
11231125
[CTRL_ATTR_FAMILY_NAME] = { .type = NLA_NUL_STRING,
11241126
.len = GENL_NAMSIZ - 1 },
1127+
[CTRL_ATTR_OP] = { .type = NLA_U32 },
11251128
};
11261129

11271130
static int ctrl_dumppolicy_start(struct netlink_callback *cb)
@@ -1154,6 +1157,23 @@ static int ctrl_dumppolicy_start(struct netlink_callback *cb)
11541157

11551158
ctx->rt = rt;
11561159

1160+
if (tb[CTRL_ATTR_OP]) {
1161+
ctx->single_op = true;
1162+
ctx->op = nla_get_u32(tb[CTRL_ATTR_OP]);
1163+
1164+
err = genl_get_cmd(ctx->op, rt, &op);
1165+
if (err) {
1166+
NL_SET_BAD_ATTR(cb->extack, tb[CTRL_ATTR_OP]);
1167+
return err;
1168+
}
1169+
1170+
if (!op.policy)
1171+
return -ENODATA;
1172+
1173+
return netlink_policy_dump_add_policy(&ctx->state, op.policy,
1174+
op.maxattr);
1175+
}
1176+
11571177
for (i = 0; i < genl_get_cmd_cnt(rt); i++) {
11581178
genl_get_cmd_by_index(i, rt, &op);
11591179

@@ -1248,7 +1268,18 @@ static int ctrl_dumppolicy(struct sk_buff *skb, struct netlink_callback *cb)
12481268
while (ctx->opidx < genl_get_cmd_cnt(ctx->rt)) {
12491269
struct genl_ops op;
12501270

1251-
genl_get_cmd_by_index(ctx->opidx, ctx->rt, &op);
1271+
if (ctx->single_op) {
1272+
int err;
1273+
1274+
err = genl_get_cmd(ctx->op, ctx->rt, &op);
1275+
if (WARN_ON(err))
1276+
return skb->len;
1277+
1278+
/* break out of the loop after this one */
1279+
ctx->opidx = genl_get_cmd_cnt(ctx->rt);
1280+
} else {
1281+
genl_get_cmd_by_index(ctx->opidx, ctx->rt, &op);
1282+
}
12521283

12531284
if (ctrl_dumppolicy_put_op(skb, cb, &op))
12541285
return skb->len;

0 commit comments

Comments
 (0)