Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3d86e352 authored by David S. Miller's avatar David S. Miller
Browse files

Merge branch 'addrlabel-no-rtnl-locking'



Florian Westphal says:

====================
addrlabel: don't use rtnl locking

addrlabel doesn't appear to require rtnl lock as the addrlabel
table uses a spinlock to serialize add/delete operations.

Also, entries are reference counted so it should be safe
to call the rtnl ops without the rtnl mutex.
====================

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 6c766db6 a6f57028
Loading
Loading
Loading
Loading
+17 −5
Original line number Diff line number Diff line
@@ -405,6 +405,18 @@ static const struct nla_policy ifal_policy[IFAL_MAX+1] = {
	[IFAL_LABEL]		= { .len = sizeof(u32), },
};

static bool addrlbl_ifindex_exists(struct net *net, int ifindex)
{

	struct net_device *dev;

	rcu_read_lock();
	dev = dev_get_by_index_rcu(net, ifindex);
	rcu_read_unlock();

	return dev != NULL;
}

static int ip6addrlbl_newdel(struct sk_buff *skb, struct nlmsghdr *nlh,
			     struct netlink_ext_ack *extack)
{
@@ -439,7 +451,7 @@ static int ip6addrlbl_newdel(struct sk_buff *skb, struct nlmsghdr *nlh,
	switch (nlh->nlmsg_type) {
	case RTM_NEWADDRLABEL:
		if (ifal->ifal_index &&
		    !__dev_get_by_index(net, ifal->ifal_index))
		    !addrlbl_ifindex_exists(net, ifal->ifal_index))
			return -EINVAL;

		err = ip6addrlbl_add(net, pfx, ifal->ifal_prefixlen,
@@ -548,7 +560,7 @@ static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
		return -EINVAL;

	if (ifal->ifal_index &&
	    !__dev_get_by_index(net, ifal->ifal_index))
	    !addrlbl_ifindex_exists(net, ifal->ifal_index))
		return -EINVAL;

	if (!tb[IFAL_ADDRESS])
@@ -593,10 +605,10 @@ static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr *nlh,
void __init ipv6_addr_label_rtnl_register(void)
{
	__rtnl_register(PF_INET6, RTM_NEWADDRLABEL, ip6addrlbl_newdel,
			NULL, 0);
			NULL, RTNL_FLAG_DOIT_UNLOCKED);
	__rtnl_register(PF_INET6, RTM_DELADDRLABEL, ip6addrlbl_newdel,
			NULL, 0);
			NULL, RTNL_FLAG_DOIT_UNLOCKED);
	__rtnl_register(PF_INET6, RTM_GETADDRLABEL, ip6addrlbl_get,
			ip6addrlbl_dump, 0);
			ip6addrlbl_dump, RTNL_FLAG_DOIT_UNLOCKED);
}
+41 −0
Original line number Diff line number Diff line
@@ -195,6 +195,46 @@ kci_test_route_get()
	echo "PASS: route get"
}

kci_test_addrlabel()
{
	ret=0

	ip addrlabel add prefix dead::/64 dev lo label 1
	check_err $?

	ip addrlabel list |grep -q "prefix dead::/64 dev lo label 1"
	check_err $?

	ip addrlabel del prefix dead::/64 dev lo label 1 2> /dev/null
	check_err $?

	ip addrlabel add prefix dead::/64 label 1 2> /dev/null
	check_err $?

	ip addrlabel del prefix dead::/64 label 1 2> /dev/null
	check_err $?

	# concurrent add/delete
	for i in $(seq 1 1000); do
		ip addrlabel add prefix 1c3::/64 label 12345 2>/dev/null
	done &

	for i in $(seq 1 1000); do
		ip addrlabel del prefix 1c3::/64 label 12345 2>/dev/null
	done

	wait

	ip addrlabel del prefix 1c3::/64 label 12345 2>/dev/null

	if [ $ret -ne 0 ];then
		echo "FAIL: ipv6 addrlabel"
		return 1
	fi

	echo "PASS: ipv6 addrlabel"
}

kci_test_rtnl()
{
	kci_add_dummy
@@ -208,6 +248,7 @@ kci_test_rtnl()
	kci_test_tc
	kci_test_gre
	kci_test_bridge
	kci_test_addrlabel

	kci_del_dummy
}