net/netlink/policy.c

Source file repositories/reference/linux-study-clean/net/netlink/policy.c

File Facts

System
Linux kernel
Corpus path
net/netlink/policy.c
Extension
.c
Size
12095 bytes
Lines
493
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: implementation source
Status
source implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

struct netlink_policy_dump_state {
	unsigned int policy_idx;
	unsigned int attr_idx;
	unsigned int n_alloc;
	struct {
		const struct nla_policy *policy;
		unsigned int maxtype;
	} policies[] __counted_by(n_alloc);
};

static int add_policy(struct netlink_policy_dump_state **statep,
		      const struct nla_policy *policy,
		      unsigned int maxtype)
{
	struct netlink_policy_dump_state *state = *statep;
	unsigned int old_n_alloc, n_alloc, i;

	if (!policy)
		return 0;

	for (i = 0; i < state->n_alloc; i++) {
		if (state->policies[i].policy == policy &&
		    state->policies[i].maxtype == maxtype)
			return 0;

		if (!state->policies[i].policy) {
			state->policies[i].policy = policy;
			state->policies[i].maxtype = maxtype;
			return 0;
		}
	}

	n_alloc = state->n_alloc + INITIAL_POLICIES_ALLOC;
	state = krealloc(state, struct_size(state, policies, n_alloc),
			 GFP_KERNEL);
	if (!state)
		return -ENOMEM;

	old_n_alloc = state->n_alloc;
	state->n_alloc = n_alloc;
	memset(&state->policies[old_n_alloc], 0,
	       flex_array_size(state, policies, n_alloc - old_n_alloc));

	state->policies[old_n_alloc].policy = policy;
	state->policies[old_n_alloc].maxtype = maxtype;
	*statep = state;

	return 0;
}

/**
 * netlink_policy_dump_get_policy_idx - retrieve policy index
 * @state: the policy dump state
 * @policy: the policy to find
 * @maxtype: the policy's maxattr
 *
 * Returns: the index of the given policy in the dump state
 *
 * Call this to find a policy index when you've added multiple and e.g.
 * need to tell userspace which command has which policy (by index).
 *
 * Note: this will WARN and return 0 if the policy isn't found, which
 *	 means it wasn't added in the first place, which would be an
 *	 internal consistency bug.
 */
int netlink_policy_dump_get_policy_idx(struct netlink_policy_dump_state *state,
				       const struct nla_policy *policy,
				       unsigned int maxtype)
{
	unsigned int i;

	if (WARN_ON(!policy))
                return 0;

	for (i = 0; i < state->n_alloc; i++) {
		if (state->policies[i].policy == policy &&
		    state->policies[i].maxtype == maxtype)
			return i;
	}

	WARN_ON(1);
	return 0;
}

static struct netlink_policy_dump_state *alloc_state(void)
{
	struct netlink_policy_dump_state *state;

	state = kzalloc_flex(*state, policies, INITIAL_POLICIES_ALLOC);
	if (!state)

Annotation

Implementation Notes