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
;
24 } policies
[] __counted_by(n_alloc
);
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 old_n_alloc
, 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 old_n_alloc
= state
->n_alloc
;
56 state
->n_alloc
= n_alloc
;
57 memset(&state
->policies
[old_n_alloc
], 0,
58 flex_array_size(state
, policies
, n_alloc
- old_n_alloc
));
60 state
->policies
[old_n_alloc
].policy
= policy
;
61 state
->policies
[old_n_alloc
].maxtype
= maxtype
;
68 * netlink_policy_dump_get_policy_idx - retrieve policy index
69 * @state: the policy dump state
70 * @policy: the policy to find
71 * @maxtype: the policy's maxattr
73 * Returns: the index of the given policy in the dump state
75 * Call this to find a policy index when you've added multiple and e.g.
76 * need to tell userspace which command has which policy (by index).
78 * Note: this will WARN and return 0 if the policy isn't found, which
79 * means it wasn't added in the first place, which would be an
80 * internal consistency bug.
82 int netlink_policy_dump_get_policy_idx(struct netlink_policy_dump_state
*state
,
83 const struct nla_policy
*policy
,
88 if (WARN_ON(!policy
|| !maxtype
))
91 for (i
= 0; i
< state
->n_alloc
; i
++) {
92 if (state
->policies
[i
].policy
== policy
&&
93 state
->policies
[i
].maxtype
== maxtype
)
101 static struct netlink_policy_dump_state
*alloc_state(void)
103 struct netlink_policy_dump_state
*state
;
105 state
= kzalloc(struct_size(state
, policies
, INITIAL_POLICIES_ALLOC
),
108 return ERR_PTR(-ENOMEM
);
109 state
->n_alloc
= INITIAL_POLICIES_ALLOC
;
115 * netlink_policy_dump_add_policy - add a policy to the dump
116 * @pstate: state to add to, may be reallocated, must be %NULL the first time
117 * @policy: the new policy to add to the dump
118 * @maxtype: the new policy's max attr type
120 * Returns: 0 on success, a negative error code otherwise.
122 * Call this to allocate a policy dump state, and to add policies to it. This
123 * should be called from the dump start() callback.
125 * Note: on failures, any previously allocated state is freed.
127 int netlink_policy_dump_add_policy(struct netlink_policy_dump_state
**pstate
,
128 const struct nla_policy
*policy
,
129 unsigned int maxtype
)
131 struct netlink_policy_dump_state
*state
= *pstate
;
132 unsigned int policy_idx
;
136 state
= alloc_state();
138 return PTR_ERR(state
);
142 * walk the policies and nested ones first, and build
143 * a linear list of them.
146 err
= add_policy(&state
, policy
, maxtype
);
151 policy_idx
< state
->n_alloc
&& state
->policies
[policy_idx
].policy
;
153 const struct nla_policy
*policy
;
156 policy
= state
->policies
[policy_idx
].policy
;
159 type
<= state
->policies
[policy_idx
].maxtype
;
161 switch (policy
[type
].type
) {
163 case NLA_NESTED_ARRAY
:
164 err
= add_policy(&state
,
165 policy
[type
].nested_policy
,
180 /* Try to preserve reasonable unwind semantics - if we're starting from
181 * scratch clean up fully, otherwise record what we got and caller will.
184 netlink_policy_dump_free(state
);
191 netlink_policy_dump_finished(struct netlink_policy_dump_state
*state
)
193 return state
->policy_idx
>= state
->n_alloc
||
194 !state
->policies
[state
->policy_idx
].policy
;
198 * netlink_policy_dump_loop - dumping loop indicator
199 * @state: the policy dump state
201 * Returns: %true if the dump continues, %false otherwise
203 * Note: this frees the dump state when finishing
205 bool netlink_policy_dump_loop(struct netlink_policy_dump_state
*state
)
207 return !netlink_policy_dump_finished(state
);
210 int netlink_policy_dump_attr_size_estimate(const struct nla_policy
*pt
)
213 int common
= 2 * nla_attr_size(sizeof(u32
));
218 /* these actually don't need any space */
221 case NLA_NESTED_ARRAY
:
222 /* common, policy idx, policy maxattr */
223 return common
+ 2 * nla_attr_size(sizeof(u32
));
235 /* maximum is common, u64 min/max with padding */
237 2 * (nla_attr_size(0) + nla_attr_size(sizeof(u64
)));
239 return common
+ nla_attr_size(sizeof(u32
));
243 /* maximum is common, u32 min-length/max-length */
244 return common
+ 2 * nla_attr_size(sizeof(u32
));
249 /* this should then cause a warning later */
254 __netlink_policy_dump_write_attr(struct netlink_policy_dump_state
*state
,
256 const struct nla_policy
*pt
,
259 int estimate
= netlink_policy_dump_attr_size_estimate(pt
);
260 enum netlink_attribute_type type
;
263 attr
= nla_nest_start(skb
, nestattr
);
271 /* skip - use NLA_MIN_LEN to advertise such */
272 nla_nest_cancel(skb
, attr
);
275 type
= NL_ATTR_TYPE_NESTED
;
277 case NLA_NESTED_ARRAY
:
278 if (pt
->type
== NLA_NESTED_ARRAY
)
279 type
= NL_ATTR_TYPE_NESTED_ARRAY
;
280 if (state
&& pt
->nested_policy
&& pt
->len
&&
281 (nla_put_u32(skb
, NL_POLICY_TYPE_ATTR_POLICY_IDX
,
282 netlink_policy_dump_get_policy_idx(state
,
285 nla_put_u32(skb
, NL_POLICY_TYPE_ATTR_POLICY_MAXTYPE
,
287 goto nla_put_failure
;
295 struct netlink_range_validation range
;
297 if (pt
->type
== NLA_U8
)
298 type
= NL_ATTR_TYPE_U8
;
299 else if (pt
->type
== NLA_U16
)
300 type
= NL_ATTR_TYPE_U16
;
301 else if (pt
->type
== NLA_U32
)
302 type
= NL_ATTR_TYPE_U32
;
303 else if (pt
->type
== NLA_U64
)
304 type
= NL_ATTR_TYPE_U64
;
306 type
= NL_ATTR_TYPE_UINT
;
308 if (pt
->validation_type
== NLA_VALIDATE_MASK
) {
309 if (nla_put_u64_64bit(skb
, NL_POLICY_TYPE_ATTR_MASK
,
311 NL_POLICY_TYPE_ATTR_PAD
))
312 goto nla_put_failure
;
316 nla_get_range_unsigned(pt
, &range
);
318 if (nla_put_u64_64bit(skb
, NL_POLICY_TYPE_ATTR_MIN_VALUE_U
,
319 range
.min
, NL_POLICY_TYPE_ATTR_PAD
) ||
320 nla_put_u64_64bit(skb
, NL_POLICY_TYPE_ATTR_MAX_VALUE_U
,
321 range
.max
, NL_POLICY_TYPE_ATTR_PAD
))
322 goto nla_put_failure
;
330 struct netlink_range_validation_signed range
;
332 if (pt
->type
== NLA_S8
)
333 type
= NL_ATTR_TYPE_S8
;
334 else if (pt
->type
== NLA_S16
)
335 type
= NL_ATTR_TYPE_S16
;
336 else if (pt
->type
== NLA_S32
)
337 type
= NL_ATTR_TYPE_S32
;
338 else if (pt
->type
== NLA_S64
)
339 type
= NL_ATTR_TYPE_S64
;
341 type
= NL_ATTR_TYPE_SINT
;
343 nla_get_range_signed(pt
, &range
);
345 if (nla_put_s64(skb
, NL_POLICY_TYPE_ATTR_MIN_VALUE_S
,
346 range
.min
, NL_POLICY_TYPE_ATTR_PAD
) ||
347 nla_put_s64(skb
, NL_POLICY_TYPE_ATTR_MAX_VALUE_S
,
348 range
.max
, NL_POLICY_TYPE_ATTR_PAD
))
349 goto nla_put_failure
;
353 type
= NL_ATTR_TYPE_BITFIELD32
;
354 if (nla_put_u32(skb
, NL_POLICY_TYPE_ATTR_BITFIELD32_MASK
,
355 pt
->bitfield32_valid
))
356 goto nla_put_failure
;
361 if (pt
->type
== NLA_STRING
)
362 type
= NL_ATTR_TYPE_STRING
;
363 else if (pt
->type
== NLA_NUL_STRING
)
364 type
= NL_ATTR_TYPE_NUL_STRING
;
366 type
= NL_ATTR_TYPE_BINARY
;
368 if (pt
->validation_type
== NLA_VALIDATE_RANGE
||
369 pt
->validation_type
== NLA_VALIDATE_RANGE_WARN_TOO_LONG
) {
370 struct netlink_range_validation range
;
372 nla_get_range_unsigned(pt
, &range
);
375 nla_put_u32(skb
, NL_POLICY_TYPE_ATTR_MIN_LENGTH
,
377 goto nla_put_failure
;
379 if (range
.max
< U16_MAX
&&
380 nla_put_u32(skb
, NL_POLICY_TYPE_ATTR_MAX_LENGTH
,
382 goto nla_put_failure
;
383 } else if (pt
->len
&&
384 nla_put_u32(skb
, NL_POLICY_TYPE_ATTR_MAX_LENGTH
,
386 goto nla_put_failure
;
390 type
= NL_ATTR_TYPE_FLAG
;
394 if (nla_put_u32(skb
, NL_POLICY_TYPE_ATTR_TYPE
, type
))
395 goto nla_put_failure
;
397 nla_nest_end(skb
, attr
);
398 WARN_ON(attr
->nla_len
> estimate
);
402 nla_nest_cancel(skb
, attr
);
407 * netlink_policy_dump_write_attr - write a given attribute policy
408 * @skb: the message skb to write to
409 * @pt: the attribute's policy
410 * @nestattr: the nested attribute ID to use
412 * Returns: 0 on success, an error code otherwise; -%ENODATA is
413 * special, indicating that there's no policy data and
414 * the attribute is generally rejected.
416 int netlink_policy_dump_write_attr(struct sk_buff
*skb
,
417 const struct nla_policy
*pt
,
420 return __netlink_policy_dump_write_attr(NULL
, skb
, pt
, nestattr
);
424 * netlink_policy_dump_write - write current policy dump attributes
425 * @skb: the message skb to write to
426 * @state: the policy dump state
428 * Returns: 0 on success, an error code otherwise
430 int netlink_policy_dump_write(struct sk_buff
*skb
,
431 struct netlink_policy_dump_state
*state
)
433 const struct nla_policy
*pt
;
434 struct nlattr
*policy
;
441 pt
= &state
->policies
[state
->policy_idx
].policy
[state
->attr_idx
];
443 policy
= nla_nest_start(skb
, state
->policy_idx
);
447 err
= __netlink_policy_dump_write_attr(state
, skb
, pt
, state
->attr_idx
);
448 if (err
== -ENODATA
) {
449 nla_nest_cancel(skb
, policy
);
453 goto nla_put_failure
;
456 /* finish and move state to next attribute */
457 nla_nest_end(skb
, policy
);
460 state
->attr_idx
+= 1;
461 if (state
->attr_idx
> state
->policies
[state
->policy_idx
].maxtype
) {
467 if (netlink_policy_dump_finished(state
))
475 nla_nest_cancel(skb
, policy
);
480 * netlink_policy_dump_free - free policy dump state
481 * @state: the policy dump state to free
483 * Call this from the done() method to ensure dump state is freed.
485 void netlink_policy_dump_free(struct netlink_policy_dump_state
*state
)