From 2cc7659545bbf5e87795726cb15d09827c6f0fa6 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Tue, 15 Aug 2017 16:34:41 +0200 Subject: [PATCH 1/4] selftests: add 'ip get' to rtnetlink.sh exercise ip/ip6 RTM_GETROUTE doit() callpath. Signed-off-by: Florian Westphal Signed-off-by: David S. Miller --- tools/testing/selftests/net/rtnetlink.sh | 32 ++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/tools/testing/selftests/net/rtnetlink.sh b/tools/testing/selftests/net/rtnetlink.sh index 5b04ad912525..84b4acf5baa9 100755 --- a/tools/testing/selftests/net/rtnetlink.sh +++ b/tools/testing/selftests/net/rtnetlink.sh @@ -164,6 +164,37 @@ kci_test_polrouting() echo "PASS: policy routing" } +kci_test_route_get() +{ + ret=0 + + ip route get 127.0.0.1 > /dev/null + check_err $? + ip route get 127.0.0.1 dev "$devdummy" > /dev/null + check_err $? + ip route get ::1 > /dev/null + check_err $? + ip route get fe80::1 dev "$devdummy" > /dev/null + check_err $? + ip route get 127.0.0.1 from 127.0.0.1 oif lo tos 0x1 mark 0x1 > /dev/null + check_err $? + ip route get ::1 from ::1 iif lo oif lo tos 0x1 mark 0x1 > /dev/null + check_err $? + ip addr add dev "$devdummy" 10.23.7.11/24 + check_err $? + ip route get 10.23.7.11 from 10.23.7.12 iif "$devdummy" > /dev/null + check_err $? + ip addr del dev "$devdummy" 10.23.7.11/24 + check_err $? + + if [ $ret -ne 0 ];then + echo "FAIL: route get" + return 1 + fi + + echo "PASS: route get" +} + kci_test_rtnl() { kci_add_dummy @@ -173,6 +204,7 @@ kci_test_rtnl() fi kci_test_polrouting + kci_test_route_get kci_test_tc kci_test_gre kci_test_bridge From 121622dba8da9c709b72d801eae7664fa7da7c36 Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Tue, 15 Aug 2017 16:34:42 +0200 Subject: [PATCH 2/4] ipv6: route: make rtm_getroute not assume rtnl is locked __dev_get_by_index assumes RTNL is held, use _rcu version instead. Signed-off-by: Florian Westphal Signed-off-by: David S. Miller --- net/ipv6/route.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 6793135d49db..60705b4d2c62 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -3611,8 +3611,11 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, struct net_device *dev; int flags = 0; - dev = __dev_get_by_index(net, iif); + rcu_read_lock(); + + dev = dev_get_by_index_rcu(net, iif); if (!dev) { + rcu_read_unlock(); err = -ENODEV; goto errout; } @@ -3624,6 +3627,8 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, if (!fibmatch) dst = ip6_route_input_lookup(net, dev, &fl6, flags); + + rcu_read_unlock(); } else { fl6.flowi6_oif = oif; From e3a22b7f5cfb3b422669fbf3d668315ac7634e5a Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Tue, 15 Aug 2017 16:34:43 +0200 Subject: [PATCH 3/4] ipv6: route: set ipv6 RTM_GETROUTE to not use rtnl Signed-off-by: Florian Westphal Signed-off-by: David S. Miller --- net/ipv6/route.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 60705b4d2c62..11ff19ba7efd 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -4107,7 +4107,8 @@ int __init ip6_route_init(void) ret = -ENOBUFS; if (__rtnl_register(PF_INET6, RTM_NEWROUTE, inet6_rtm_newroute, NULL, 0) || __rtnl_register(PF_INET6, RTM_DELROUTE, inet6_rtm_delroute, NULL, 0) || - __rtnl_register(PF_INET6, RTM_GETROUTE, inet6_rtm_getroute, NULL, 0)) + __rtnl_register(PF_INET6, RTM_GETROUTE, inet6_rtm_getroute, NULL, + RTNL_FLAG_DOIT_UNLOCKED)) goto out_register_late_subsys; ret = register_netdevice_notifier(&ip6_route_dev_notifier); From 394f51abb3d04f33fb798f04b16ae6b0491ea4ec Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Tue, 15 Aug 2017 16:34:44 +0200 Subject: [PATCH 4/4] ipv4: route: set ipv4 RTM_GETROUTE to not use rtnl Signed-off-by: Florian Westphal Signed-off-by: David S. Miller --- net/ipv4/route.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 6810d2076b1b..618bbe1405fc 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -3073,7 +3073,8 @@ int __init ip_rt_init(void) xfrm_init(); xfrm4_init(); #endif - rtnl_register(PF_INET, RTM_GETROUTE, inet_rtm_getroute, NULL, 0); + rtnl_register(PF_INET, RTM_GETROUTE, inet_rtm_getroute, NULL, + RTNL_FLAG_DOIT_UNLOCKED); #ifdef CONFIG_SYSCTL register_pernet_subsys(&sysctl_route_ops);