Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * NETLINK      Policy advertisement to userspace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * 		Authors:	Johannes Berg <johannes@sipsolutions.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Copyright 2019 Intel Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <net/netlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #define INITIAL_POLICIES_ALLOC	10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) struct netlink_policy_dump_state {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 	unsigned int policy_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) 	unsigned int attr_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 	unsigned int n_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 	struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 		const struct nla_policy *policy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 		unsigned int maxtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 	} policies[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) static int add_policy(struct netlink_policy_dump_state **statep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 		      const struct nla_policy *policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 		      unsigned int maxtype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	struct netlink_policy_dump_state *state = *statep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	unsigned int n_alloc, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	if (!policy || !maxtype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	for (i = 0; i < state->n_alloc; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 		if (state->policies[i].policy == policy &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 		    state->policies[i].maxtype == maxtype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 		if (!state->policies[i].policy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 			state->policies[i].policy = policy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 			state->policies[i].maxtype = maxtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	n_alloc = state->n_alloc + INITIAL_POLICIES_ALLOC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	state = krealloc(state, struct_size(state, policies, n_alloc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 			 GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	if (!state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	memset(&state->policies[state->n_alloc], 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	       flex_array_size(state, policies, n_alloc - state->n_alloc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	state->policies[state->n_alloc].policy = policy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	state->policies[state->n_alloc].maxtype = maxtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	state->n_alloc = n_alloc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	*statep = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67)  * netlink_policy_dump_get_policy_idx - retrieve policy index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68)  * @state: the policy dump state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69)  * @policy: the policy to find
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70)  * @maxtype: the policy's maxattr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72)  * Returns: the index of the given policy in the dump state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74)  * Call this to find a policy index when you've added multiple and e.g.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75)  * need to tell userspace which command has which policy (by index).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77)  * Note: this will WARN and return 0 if the policy isn't found, which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78)  *	 means it wasn't added in the first place, which would be an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79)  *	 internal consistency bug.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) int netlink_policy_dump_get_policy_idx(struct netlink_policy_dump_state *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 				       const struct nla_policy *policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 				       unsigned int maxtype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	if (WARN_ON(!policy || !maxtype))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88)                 return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	for (i = 0; i < state->n_alloc; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		if (state->policies[i].policy == policy &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 		    state->policies[i].maxtype == maxtype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 			return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	WARN_ON(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static struct netlink_policy_dump_state *alloc_state(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	struct netlink_policy_dump_state *state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 	state = kzalloc(struct_size(state, policies, INITIAL_POLICIES_ALLOC),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 			GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	if (!state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	state->n_alloc = INITIAL_POLICIES_ALLOC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	return state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)  * netlink_policy_dump_add_policy - add a policy to the dump
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)  * @pstate: state to add to, may be reallocated, must be %NULL the first time
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)  * @policy: the new policy to add to the dump
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)  * @maxtype: the new policy's max attr type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)  * Returns: 0 on success, a negative error code otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)  * Call this to allocate a policy dump state, and to add policies to it. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)  * should be called from the dump start() callback.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)  * Note: on failures, any previously allocated state is freed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) int netlink_policy_dump_add_policy(struct netlink_policy_dump_state **pstate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 				   const struct nla_policy *policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 				   unsigned int maxtype)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	struct netlink_policy_dump_state *state = *pstate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	unsigned int policy_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	if (!state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		state = alloc_state();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 		if (IS_ERR(state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 			return PTR_ERR(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	 * walk the policies and nested ones first, and build
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	 * a linear list of them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	err = add_policy(&state, policy, maxtype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	for (policy_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	     policy_idx < state->n_alloc && state->policies[policy_idx].policy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	     policy_idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		const struct nla_policy *policy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		unsigned int type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		policy = state->policies[policy_idx].policy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		for (type = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 		     type <= state->policies[policy_idx].maxtype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		     type++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 			switch (policy[type].type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 			case NLA_NESTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 			case NLA_NESTED_ARRAY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 				err = add_policy(&state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 						 policy[type].nested_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 						 policy[type].len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 				if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 					return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 			default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	*pstate = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) static bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) netlink_policy_dump_finished(struct netlink_policy_dump_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	return state->policy_idx >= state->n_alloc ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	       !state->policies[state->policy_idx].policy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)  * netlink_policy_dump_loop - dumping loop indicator
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)  * @state: the policy dump state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)  * Returns: %true if the dump continues, %false otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)  * Note: this frees the dump state when finishing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) bool netlink_policy_dump_loop(struct netlink_policy_dump_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	return !netlink_policy_dump_finished(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) int netlink_policy_dump_attr_size_estimate(const struct nla_policy *pt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	/* nested + type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 	int common = 2 * nla_attr_size(sizeof(u32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	switch (pt->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	case NLA_UNSPEC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	case NLA_REJECT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 		/* these actually don't need any space */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	case NLA_NESTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	case NLA_NESTED_ARRAY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		/* common, policy idx, policy maxattr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		return common + 2 * nla_attr_size(sizeof(u32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	case NLA_U8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	case NLA_U16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	case NLA_U32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	case NLA_U64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	case NLA_MSECS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	case NLA_S8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	case NLA_S16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	case NLA_S32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	case NLA_S64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		/* maximum is common, u64 min/max with padding */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		return common +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		       2 * (nla_attr_size(0) + nla_attr_size(sizeof(u64)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	case NLA_BITFIELD32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		return common + nla_attr_size(sizeof(u32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	case NLA_STRING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	case NLA_NUL_STRING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	case NLA_BINARY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 		/* maximum is common, u32 min-length/max-length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 		return common + 2 * nla_attr_size(sizeof(u32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	case NLA_FLAG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		return common;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	/* this should then cause a warning later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) __netlink_policy_dump_write_attr(struct netlink_policy_dump_state *state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 				 struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 				 const struct nla_policy *pt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 				 int nestattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	int estimate = netlink_policy_dump_attr_size_estimate(pt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	enum netlink_attribute_type type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	struct nlattr *attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	attr = nla_nest_start(skb, nestattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	if (!attr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	switch (pt->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	case NLA_UNSPEC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	case NLA_REJECT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		/* skip - use NLA_MIN_LEN to advertise such */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		nla_nest_cancel(skb, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 		return -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	case NLA_NESTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		type = NL_ATTR_TYPE_NESTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	case NLA_NESTED_ARRAY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 		if (pt->type == NLA_NESTED_ARRAY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 			type = NL_ATTR_TYPE_NESTED_ARRAY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		if (state && pt->nested_policy && pt->len &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 		    (nla_put_u32(skb, NL_POLICY_TYPE_ATTR_POLICY_IDX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 				 netlink_policy_dump_get_policy_idx(state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 								    pt->nested_policy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 								    pt->len)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 		     nla_put_u32(skb, NL_POLICY_TYPE_ATTR_POLICY_MAXTYPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 				 pt->len)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	case NLA_U8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	case NLA_U16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	case NLA_U32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	case NLA_U64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	case NLA_MSECS: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		struct netlink_range_validation range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		if (pt->type == NLA_U8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 			type = NL_ATTR_TYPE_U8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 		else if (pt->type == NLA_U16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 			type = NL_ATTR_TYPE_U16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		else if (pt->type == NLA_U32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 			type = NL_ATTR_TYPE_U32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 			type = NL_ATTR_TYPE_U64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 		if (pt->validation_type == NLA_VALIDATE_MASK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 			if (nla_put_u64_64bit(skb, NL_POLICY_TYPE_ATTR_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 					      pt->mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 					      NL_POLICY_TYPE_ATTR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 				goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		nla_get_range_unsigned(pt, &range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 		if (nla_put_u64_64bit(skb, NL_POLICY_TYPE_ATTR_MIN_VALUE_U,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 				      range.min, NL_POLICY_TYPE_ATTR_PAD) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 		    nla_put_u64_64bit(skb, NL_POLICY_TYPE_ATTR_MAX_VALUE_U,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 				      range.max, NL_POLICY_TYPE_ATTR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	case NLA_S8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	case NLA_S16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	case NLA_S32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	case NLA_S64: {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 		struct netlink_range_validation_signed range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 		if (pt->type == NLA_S8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 			type = NL_ATTR_TYPE_S8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		else if (pt->type == NLA_S16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 			type = NL_ATTR_TYPE_S16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 		else if (pt->type == NLA_S32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 			type = NL_ATTR_TYPE_S32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 			type = NL_ATTR_TYPE_S64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 		nla_get_range_signed(pt, &range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 		if (nla_put_s64(skb, NL_POLICY_TYPE_ATTR_MIN_VALUE_S,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 				range.min, NL_POLICY_TYPE_ATTR_PAD) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 		    nla_put_s64(skb, NL_POLICY_TYPE_ATTR_MAX_VALUE_S,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 				range.max, NL_POLICY_TYPE_ATTR_PAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	case NLA_BITFIELD32:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 		type = NL_ATTR_TYPE_BITFIELD32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 		if (nla_put_u32(skb, NL_POLICY_TYPE_ATTR_BITFIELD32_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 				pt->bitfield32_valid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 	case NLA_STRING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	case NLA_NUL_STRING:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	case NLA_BINARY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 		if (pt->type == NLA_STRING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 			type = NL_ATTR_TYPE_STRING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 		else if (pt->type == NLA_NUL_STRING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 			type = NL_ATTR_TYPE_NUL_STRING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 			type = NL_ATTR_TYPE_BINARY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 		if (pt->validation_type == NLA_VALIDATE_RANGE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 		    pt->validation_type == NLA_VALIDATE_RANGE_WARN_TOO_LONG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 			struct netlink_range_validation range;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 			nla_get_range_unsigned(pt, &range);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 			if (range.min &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 			    nla_put_u32(skb, NL_POLICY_TYPE_ATTR_MIN_LENGTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 					range.min))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 				goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 			if (range.max < U16_MAX &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 			    nla_put_u32(skb, NL_POLICY_TYPE_ATTR_MAX_LENGTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 					range.max))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 				goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 		} else if (pt->len &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 			   nla_put_u32(skb, NL_POLICY_TYPE_ATTR_MAX_LENGTH,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 				       pt->len)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 			goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	case NLA_FLAG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 		type = NL_ATTR_TYPE_FLAG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	if (nla_put_u32(skb, NL_POLICY_TYPE_ATTR_TYPE, type))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	nla_nest_end(skb, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	WARN_ON(attr->nla_len > estimate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	nla_nest_cancel(skb, attr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)  * netlink_policy_dump_write_attr - write a given attribute policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)  * @skb: the message skb to write to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)  * @pt: the attribute's policy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)  * @nestattr: the nested attribute ID to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)  * Returns: 0 on success, an error code otherwise; -%ENODATA is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)  *	    special, indicating that there's no policy data and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)  *	    the attribute is generally rejected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) int netlink_policy_dump_write_attr(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 				   const struct nla_policy *pt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 				   int nestattr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 	return __netlink_policy_dump_write_attr(NULL, skb, pt, nestattr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405)  * netlink_policy_dump_write - write current policy dump attributes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)  * @skb: the message skb to write to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)  * @state: the policy dump state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)  * Returns: 0 on success, an error code otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) int netlink_policy_dump_write(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 			      struct netlink_policy_dump_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	const struct nla_policy *pt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	struct nlattr *policy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 	bool again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) send_attribute:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	again = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	pt = &state->policies[state->policy_idx].policy[state->attr_idx];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	policy = nla_nest_start(skb, state->policy_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	if (!policy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 		return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 	err = __netlink_policy_dump_write_attr(state, skb, pt, state->attr_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	if (err == -ENODATA) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 		nla_nest_cancel(skb, policy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 		again = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 		goto next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	} else if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 		goto nla_put_failure;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 	/* finish and move state to next attribute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 	nla_nest_end(skb, policy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) next:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	state->attr_idx += 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	if (state->attr_idx > state->policies[state->policy_idx].maxtype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 		state->attr_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 		state->policy_idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	if (again) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 		if (netlink_policy_dump_finished(state))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 			return -ENODATA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 		goto send_attribute;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) nla_put_failure:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	nla_nest_cancel(skb, policy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)  * netlink_policy_dump_free - free policy dump state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)  * @state: the policy dump state to free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)  * Call this from the done() method to ensure dump state is freed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) void netlink_policy_dump_free(struct netlink_policy_dump_state *state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	kfree(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) }