Commit 386520e0 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller
Browse files

rtnetlink: add RTNL_FLAG_DUMP_UNLOCKED flag



Similarly to RTNL_FLAG_DOIT_UNLOCKED, this new flag
allows dump operations registered via rtnl_register()
or rtnl_register_module() to opt-out from RTNL protection.

Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Reviewed-by: default avatarDonald Hunter <donald.hunter@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e39951d9
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -291,6 +291,7 @@ struct netlink_callback {
	u16			answer_flags;
	u32			min_dump_alloc;
	unsigned int		prev_seq, seq;
	int			flags;
	bool			strict_check;
	union {
		u8		ctx[48];
@@ -323,6 +324,7 @@ struct netlink_dump_control {
	void *data;
	struct module *module;
	u32 min_dump_alloc;
	int flags;
};

int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
+1 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@ typedef int (*rtnl_dumpit_func)(struct sk_buff *, struct netlink_callback *);
enum rtnl_link_flags {
	RTNL_FLAG_DOIT_UNLOCKED		= BIT(0),
	RTNL_FLAG_BULK_DEL_SUPPORTED	= BIT(1),
	RTNL_FLAG_DUMP_UNLOCKED		= BIT(2),
};

enum rtnl_kinds {
+2 −0
Original line number Diff line number Diff line
@@ -6532,6 +6532,7 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
		}
		owner = link->owner;
		dumpit = link->dumpit;
		flags = link->flags;

		if (type == RTM_GETLINK - RTM_BASE)
			min_dump_alloc = rtnl_calcit(skb, nlh);
@@ -6549,6 +6550,7 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
				.dump		= dumpit,
				.min_dump_alloc	= min_dump_alloc,
				.module		= owner,
				.flags		= flags,
			};
			err = netlink_dump_start(rtnl, skb, nlh, &c);
			/* netlink_dump_start() will keep a reference on
+3 −0
Original line number Diff line number Diff line
@@ -2261,6 +2261,8 @@ static int netlink_dump(struct sock *sk, bool lock_taken)

		cb->extack = &extack;

		if (cb->flags & RTNL_FLAG_DUMP_UNLOCKED)
			extra_mutex = NULL;
		if (extra_mutex)
			mutex_lock(extra_mutex);
		nlk->dump_done_errno = cb->dump(skb, cb);
@@ -2355,6 +2357,7 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
	cb->data = control->data;
	cb->module = control->module;
	cb->min_dump_alloc = control->min_dump_alloc;
	cb->flags = control->flags;
	cb->skb = skb;

	cb->strict_check = nlk_test_bit(STRICT_CHK, NETLINK_CB(skb).sk);