1 // SPDX-License-Identifier: GPL-2.0
3 * NETLINK Policy advertisement to userspace
5 * Authors: Johannes Berg <johannes@sipsolutions.net>
7 * Copyright 2019 Intel Corporation
10 #include <linux/kernel.h>
11 #include <linux/errno.h>
12 #include <linux/types.h>
13 #include <net/netlink.h>
15 #define INITIAL_POLICIES_ALLOC 10
17 struct netlink_policy_dump_state
{
18 unsigned int policy_idx
;
19 unsigned int attr_idx
;
22 const struct nla_policy
*policy
;
27 static int add_policy(struct netlink_policy_dump_state
**statep
,
28 const struct nla_policy
*policy
,
31 struct netlink_policy_dump_state
*state
= *statep
;
32 unsigned int n_alloc
, i
;
34 if (!policy
|| !maxtype
)
37 for (i
= 0; i
< state
->n_alloc
; i
++) {
38 if (state
->policies
[i
].policy
== policy
&&
39 state
->policies
[i
].maxtype
== maxtype
)
42 if (!state
->policies
[i
].policy
) {
43 state
->policies
[i
].policy
= policy
;
44 state
->policies
[i
].maxtype
= maxtype
;
49 n_alloc
= state
->n_alloc
+ INITIAL_POLICIES_ALLOC
;
50 state
= krealloc(state
, struct_size(state
, policies
, n_alloc
),
55 memset(&state
->policies
[state
->n_alloc
], 0,
56 flex_array_size(state
, policies
, n_alloc
- state
->n_alloc
));
58 state
->policies
[state
->n_alloc
].policy
= policy
;
59 state
->policies
[state
->n_alloc
].maxtype
= maxtype
;
60 state
->n_alloc
= n_alloc
;
67 * netlink_policy_dump_get_policy_idx - retrieve policy index
68 * @state: the policy dump state
69 * @policy: the policy to find
70 * @maxtype: the policy's maxattr
72 * Returns: the index of the given policy in the dump state
74 * Call this to find a policy index when you've added multiple and e.g.
75 * need to tell userspace which command has which policy (by index).
77 * Note: this will WARN and return 0 if the policy isn't found, which
78 * means it wasn't added in the first place, which would be an
79 * internal consistency bug.
81 int netlink_policy_dump_get_policy_idx(struct netlink_policy_dump_state
*state
,
82 const struct nla_policy
*policy
,
87 if (WARN_ON(!policy
|| !maxtype
))
90 for (i
= 0; i
< state
->n_alloc
; i
++) {
91 if (state
->policies
[i
].policy
== policy
&&
92 state
->policies
[i
].maxtype
== maxtype
)
100 static struct netlink_policy_dump_state
*alloc_state(void)
102 struct netlink_policy_dump_state
*state
;
104 state
= kzalloc(struct_size(state
, policies
, INITIAL_POLICIES_ALLOC
),
107 return ERR_PTR(-ENOMEM
);
108 state
->n_alloc
= INITIAL_POLICIES_ALLOC
;
114 * netlink_policy_dump_add_policy - add a policy to the dump
115 * @pstate: state to add to, may be reallocated, must be %NULL the first time
116 * @policy: the new policy to add to the dump
117 * @maxtype: the new policy's max attr type
119 * Returns: 0 on success, a negative error code otherwise.
121 * Call this to allocate a policy dump state, and to add policies to it. This
122 * should be called from the dump start() callback.
124 * Note: on failures, any previously allocated state is freed.
126 int netlink_policy_dump_add_policy(struct netlink_policy_dump_state
**pstate
,
127 const struct nla_policy
*policy
,
128 unsigned int maxtype
)
130 struct netlink_policy_dump_state
*state
= *pstate
;
131 unsigned int policy_idx
;
135 state
= alloc_state();
137 return PTR_ERR(state
);
141 * walk the policies and nested ones first, and build
142 * a linear list of them.
145 err
= add_policy(&state
, policy
, maxtype
);
150 policy_idx
< state
->n_alloc
&& state
->policies
[policy_idx
].policy
;
152 const struct nla_policy
*policy
;
155 policy
= state
->policies
[policy_idx
].policy
;
158 type
<= state
->policies
[policy_idx
].maxtype
;
160 switch (policy
[type
].type
) {
162 case NLA_NESTED_ARRAY
:
163 err
= add_policy(&state
,
164 policy
[type
].nested_policy
,
180 netlink_policy_dump_finished(struct netlink_policy_dump_state
*state
)
182 return state
->policy_idx
>= state
->n_alloc
||
183 !state
->policies
[state
->policy_idx
].policy
;
187 * netlink_policy_dump_loop - dumping loop indicator
188 * @state: the policy dump state
190 * Returns: %true if the dump continues, %false otherwise
192 * Note: this frees the dump state when finishing
194 bool netlink_policy_dump_loop(struct netlink_policy_dump_state
*state
)
196 return !netlink_policy_dump_finished(state
);
199 int netlink_policy_dump_attr_size_estimate(const struct nla_policy
*pt
)
202 int common
= 2 * nla_attr_size(sizeof(u32
));
207 /* these actually don't need any space */
210 case NLA_NESTED_ARRAY
:
211 /* common, policy idx, policy maxattr */
212 return common
+ 2 * nla_attr_size(sizeof(u32
));
222 /* maximum is common, u64 min/max with padding */
224 2 * (nla_attr_size(0) + nla_attr_size(sizeof(u64
)));
226 return common
+ nla_attr_size(sizeof(u32
));
230 /* maximum is common, u32 min-length/max-length */
231 return common
+ 2 * nla_attr_size(sizeof(u32
));
236 /* this should then cause a warning later */
241 __netlink_policy_dump_write_attr(struct netlink_policy_dump_state
*state
,
243 const struct nla_policy
*pt
,
246 int estimate
= netlink_policy_dump_attr_size_estimate(pt
);
247 enum netlink_attribute_type type
;
250 attr
= nla_nest_start(skb
, nestattr
);
258 /* skip - use NLA_MIN_LEN to advertise such */
259 nla_nest_cancel(skb
, attr
);
262 type
= NL_ATTR_TYPE_NESTED
;
264 case NLA_NESTED_ARRAY
:
265 if (pt
->type
== NLA_NESTED_ARRAY
)
266 type
= NL_ATTR_TYPE_NESTED_ARRAY
;
267 if (state
&& pt
->nested_policy
&& pt
->len
&&
268 (nla_put_u32(skb
, NL_POLICY_TYPE_ATTR_POLICY_IDX
,
269 netlink_policy_dump_get_policy_idx(state
,
272 nla_put_u32(skb
, NL_POLICY_TYPE_ATTR_POLICY_MAXTYPE
,
274 goto nla_put_failure
;
281 struct netlink_range_validation range
;
283 if (pt
->type
== NLA_U8
)
284 type
= NL_ATTR_TYPE_U8
;
285 else if (pt
->type
== NLA_U16
)
286 type
= NL_ATTR_TYPE_U16
;
287 else if (pt
->type
== NLA_U32
)
288 type
= NL_ATTR_TYPE_U32
;
290 type
= NL_ATTR_TYPE_U64
;
292 if (pt
->validation_type
== NLA_VALIDATE_MASK
) {
293 if (nla_put_u64_64bit(skb
, NL_POLICY_TYPE_ATTR_MASK
,
295 NL_POLICY_TYPE_ATTR_PAD
))
296 goto nla_put_failure
;
300 nla_get_range_unsigned(pt
, &range
);
302 if (nla_put_u64_64bit(skb
, NL_POLICY_TYPE_ATTR_MIN_VALUE_U
,
303 range
.min
, NL_POLICY_TYPE_ATTR_PAD
) ||
304 nla_put_u64_64bit(skb
, NL_POLICY_TYPE_ATTR_MAX_VALUE_U
,
305 range
.max
, NL_POLICY_TYPE_ATTR_PAD
))
306 goto nla_put_failure
;
313 struct netlink_range_validation_signed range
;
315 if (pt
->type
== NLA_S8
)
316 type
= NL_ATTR_TYPE_S8
;
317 else if (pt
->type
== NLA_S16
)
318 type
= NL_ATTR_TYPE_S16
;
319 else if (pt
->type
== NLA_S32
)
320 type
= NL_ATTR_TYPE_S32
;
322 type
= NL_ATTR_TYPE_S64
;
324 nla_get_range_signed(pt
, &range
);
326 if (nla_put_s64(skb
, NL_POLICY_TYPE_ATTR_MIN_VALUE_S
,
327 range
.min
, NL_POLICY_TYPE_ATTR_PAD
) ||
328 nla_put_s64(skb
, NL_POLICY_TYPE_ATTR_MAX_VALUE_S
,
329 range
.max
, NL_POLICY_TYPE_ATTR_PAD
))
330 goto nla_put_failure
;
334 type
= NL_ATTR_TYPE_BITFIELD32
;
335 if (nla_put_u32(skb
, NL_POLICY_TYPE_ATTR_BITFIELD32_MASK
,
336 pt
->bitfield32_valid
))
337 goto nla_put_failure
;
342 if (pt
->type
== NLA_STRING
)
343 type
= NL_ATTR_TYPE_STRING
;
344 else if (pt
->type
== NLA_NUL_STRING
)
345 type
= NL_ATTR_TYPE_NUL_STRING
;
347 type
= NL_ATTR_TYPE_BINARY
;
349 if (pt
->validation_type
== NLA_VALIDATE_RANGE
||
350 pt
->validation_type
== NLA_VALIDATE_RANGE_WARN_TOO_LONG
) {
351 struct netlink_range_validation range
;
353 nla_get_range_unsigned(pt
, &range
);
356 nla_put_u32(skb
, NL_POLICY_TYPE_ATTR_MIN_LENGTH
,
358 goto nla_put_failure
;
360 if (range
.max
< U16_MAX
&&
361 nla_put_u32(skb
, NL_POLICY_TYPE_ATTR_MAX_LENGTH
,
363 goto nla_put_failure
;
364 } else if (pt
->len
&&
365 nla_put_u32(skb
, NL_POLICY_TYPE_ATTR_MAX_LENGTH
,
367 goto nla_put_failure
;
371 type
= NL_ATTR_TYPE_FLAG
;
375 if (nla_put_u32(skb
, NL_POLICY_TYPE_ATTR_TYPE
, type
))
376 goto nla_put_failure
;
378 nla_nest_end(skb
, attr
);
379 WARN_ON(attr
->nla_len
> estimate
);
383 nla_nest_cancel(skb
, attr
);
388 * netlink_policy_dump_write_attr - write a given attribute policy
389 * @skb: the message skb to write to
390 * @pt: the attribute's policy
391 * @nestattr: the nested attribute ID to use
393 * Returns: 0 on success, an error code otherwise; -%ENODATA is
394 * special, indicating that there's no policy data and
395 * the attribute is generally rejected.
397 int netlink_policy_dump_write_attr(struct sk_buff
*skb
,
398 const struct nla_policy
*pt
,
401 return __netlink_policy_dump_write_attr(NULL
, skb
, pt
, nestattr
);
405 * netlink_policy_dump_write - write current policy dump attributes
406 * @skb: the message skb to write to
407 * @state: the policy dump state
409 * Returns: 0 on success, an error code otherwise
411 int netlink_policy_dump_write(struct sk_buff
*skb
,
412 struct netlink_policy_dump_state
*state
)
414 const struct nla_policy
*pt
;
415 struct nlattr
*policy
;
422 pt
= &state
->policies
[state
->policy_idx
].policy
[state
->attr_idx
];
424 policy
= nla_nest_start(skb
, state
->policy_idx
);
428 err
= __netlink_policy_dump_write_attr(state
, skb
, pt
, state
->attr_idx
);
429 if (err
== -ENODATA
) {
430 nla_nest_cancel(skb
, policy
);
434 goto nla_put_failure
;
437 /* finish and move state to next attribute */
438 nla_nest_end(skb
, policy
);
441 state
->attr_idx
+= 1;
442 if (state
->attr_idx
> state
->policies
[state
->policy_idx
].maxtype
) {
448 if (netlink_policy_dump_finished(state
))
456 nla_nest_cancel(skb
, policy
);
461 * netlink_policy_dump_free - free policy dump state
462 * @state: the policy dump state to free
464 * Call this from the done() method to ensure dump state is freed.
466 void netlink_policy_dump_free(struct netlink_policy_dump_state
*state
)