Commit 395059c5 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'rtnetlink-rtnl_lock'



Jakub Kicinski says:

====================
rtnetlink: move rtnl_lock handling out of af_netlink

With the changes done in commit 5b4b62a1 ("rtnetlink: make
the "split" NLM_DONE handling generic") we can also move the
rtnl locking out of af_netlink.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents c917b26e 5fbf57a9
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -47,7 +47,6 @@ struct netlink_kernel_cfg {
	unsigned int	groups;
	unsigned int	flags;
	void		(*input)(struct sk_buff *skb);
	struct mutex	*cb_mutex;
	int		(*bind)(struct net *net, int group);
	void		(*unbind)(struct net *net, int group);
	void            (*release) (struct sock *sk, unsigned long *groups);
+7 −2
Original line number Diff line number Diff line
@@ -6486,6 +6486,7 @@ static int rtnl_mdb_del(struct sk_buff *skb, struct nlmsghdr *nlh,

static int rtnl_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
{
	const bool needs_lock = !(cb->flags & RTNL_FLAG_DUMP_UNLOCKED);
	rtnl_dumpit_func dumpit = cb->data;
	int err;

@@ -6495,7 +6496,11 @@ static int rtnl_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
	if (!dumpit)
		return 0;

	if (needs_lock)
		rtnl_lock();
	err = dumpit(skb, cb);
	if (needs_lock)
		rtnl_unlock();

	/* Old dump handlers used to send NLM_DONE as in a separate recvmsg().
	 * Some applications which parse netlink manually depend on this.
@@ -6515,7 +6520,8 @@ static int rtnetlink_dump_start(struct sock *ssk, struct sk_buff *skb,
				const struct nlmsghdr *nlh,
				struct netlink_dump_control *control)
{
	if (control->flags & RTNL_FLAG_DUMP_SPLIT_NLM_DONE) {
	if (control->flags & RTNL_FLAG_DUMP_SPLIT_NLM_DONE ||
	    !(control->flags & RTNL_FLAG_DUMP_UNLOCKED)) {
		WARN_ON(control->data);
		control->data = control->dump;
		control->dump = rtnl_dumpit;
@@ -6703,7 +6709,6 @@ static int __net_init rtnetlink_net_init(struct net *net)
	struct netlink_kernel_cfg cfg = {
		.groups		= RTNLGRP_MAX,
		.input		= rtnetlink_rcv,
		.cb_mutex	= &rtnl_mutex,
		.flags		= NL_CFG_F_NONROOT_RECV,
		.bind		= rtnetlink_bind,
	};
+3 −17
Original line number Diff line number Diff line
@@ -636,8 +636,7 @@ static struct proto netlink_proto = {
};

static int __netlink_create(struct net *net, struct socket *sock,
			    struct mutex *dump_cb_mutex, int protocol,
			    int kern)
			    int protocol, int kern)
{
	struct sock *sk;
	struct netlink_sock *nlk;
@@ -655,7 +654,6 @@ static int __netlink_create(struct net *net, struct socket *sock,
	lockdep_set_class_and_name(&nlk->nl_cb_mutex,
					   nlk_cb_mutex_keys + protocol,
					   nlk_cb_mutex_key_strings[protocol]);
	nlk->dump_cb_mutex = dump_cb_mutex;
	init_waitqueue_head(&nlk->wait);

	sk->sk_destruct = netlink_sock_destruct;
@@ -667,7 +665,6 @@ static int netlink_create(struct net *net, struct socket *sock, int protocol,
			  int kern)
{
	struct module *module = NULL;
	struct mutex *cb_mutex;
	struct netlink_sock *nlk;
	int (*bind)(struct net *net, int group);
	void (*unbind)(struct net *net, int group);
@@ -696,7 +693,6 @@ static int netlink_create(struct net *net, struct socket *sock, int protocol,
		module = nl_table[protocol].module;
	else
		err = -EPROTONOSUPPORT;
	cb_mutex = nl_table[protocol].cb_mutex;
	bind = nl_table[protocol].bind;
	unbind = nl_table[protocol].unbind;
	release = nl_table[protocol].release;
@@ -705,7 +701,7 @@ static int netlink_create(struct net *net, struct socket *sock, int protocol,
	if (err < 0)
		goto out;

	err = __netlink_create(net, sock, cb_mutex, protocol, kern);
	err = __netlink_create(net, sock, protocol, kern);
	if (err < 0)
		goto out_module;

@@ -2016,7 +2012,6 @@ __netlink_kernel_create(struct net *net, int unit, struct module *module,
	struct sock *sk;
	struct netlink_sock *nlk;
	struct listeners *listeners = NULL;
	struct mutex *cb_mutex = cfg ? cfg->cb_mutex : NULL;
	unsigned int groups;

	BUG_ON(!nl_table);
@@ -2027,7 +2022,7 @@ __netlink_kernel_create(struct net *net, int unit, struct module *module,
	if (sock_create_lite(PF_NETLINK, SOCK_DGRAM, unit, &sock))
		return NULL;

	if (__netlink_create(net, sock, cb_mutex, unit, 1) < 0)
	if (__netlink_create(net, sock, unit, 1) < 0)
		goto out_sock_release_nosk;

	sk = sock->sk;
@@ -2055,7 +2050,6 @@ __netlink_kernel_create(struct net *net, int unit, struct module *module,
	if (!nl_table[unit].registered) {
		nl_table[unit].groups = groups;
		rcu_assign_pointer(nl_table[unit].listeners, listeners);
		nl_table[unit].cb_mutex = cb_mutex;
		nl_table[unit].module = module;
		if (cfg) {
			nl_table[unit].bind = cfg->bind;
@@ -2326,17 +2320,9 @@ static int netlink_dump(struct sock *sk, bool lock_taken)
	netlink_skb_set_owner_r(skb, sk);

	if (nlk->dump_done_errno > 0) {
		struct mutex *extra_mutex = nlk->dump_cb_mutex;

		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);
		if (extra_mutex)
			mutex_unlock(extra_mutex);

		/* EMSGSIZE plus something already in the skb means
		 * that there's more to dump but current skb has filled up.