mirror of https://github.com/torvalds/linux.git
ipv6: start using dst_dev_rcu()
Refactor icmpv6_xrlim_allow() and ip6_dst_hoplimit()
so that we acquire rcu_read_lock() a bit longer
to be able to use dst_dev_rcu() instead of dst_dev().
__ip6_rt_update_pmtu() and rt6_do_redirect can directly
use dst_dev_rcu() in sections already holding rcu_read_lock().
Small changes to use dst_dev_net_rcu() in
ip6_default_advmss(), ipv6_sock_ac_join(),
ip6_mc_find_dev() and ndisc_send_skb().
Fixes: 4a6ce2b6f2 ("net: introduce a new function dst_dev_put()")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Link: https://patch.msgid.link/20250828195823.3958522-3-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
caedcc5b6d
commit
b775ecf165
|
|
@ -104,7 +104,7 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
rt = rt6_lookup(net, addr, NULL, 0, NULL, 0);
|
rt = rt6_lookup(net, addr, NULL, 0, NULL, 0);
|
||||||
if (rt) {
|
if (rt) {
|
||||||
dev = dst_dev(&rt->dst);
|
dev = dst_dev_rcu(&rt->dst);
|
||||||
netdev_hold(dev, &dev_tracker, GFP_ATOMIC);
|
netdev_hold(dev, &dev_tracker, GFP_ATOMIC);
|
||||||
ip6_rt_put(rt);
|
ip6_rt_put(rt);
|
||||||
} else if (ishost) {
|
} else if (ishost) {
|
||||||
|
|
|
||||||
|
|
@ -209,7 +209,8 @@ static bool icmpv6_xrlim_allow(struct sock *sk, u8 type,
|
||||||
* this lookup should be more aggressive (not longer than timeout).
|
* this lookup should be more aggressive (not longer than timeout).
|
||||||
*/
|
*/
|
||||||
dst = ip6_route_output(net, sk, fl6);
|
dst = ip6_route_output(net, sk, fl6);
|
||||||
dev = dst_dev(dst);
|
rcu_read_lock();
|
||||||
|
dev = dst_dev_rcu(dst);
|
||||||
if (dst->error) {
|
if (dst->error) {
|
||||||
IP6_INC_STATS(net, ip6_dst_idev(dst),
|
IP6_INC_STATS(net, ip6_dst_idev(dst),
|
||||||
IPSTATS_MIB_OUTNOROUTES);
|
IPSTATS_MIB_OUTNOROUTES);
|
||||||
|
|
@ -224,11 +225,10 @@ static bool icmpv6_xrlim_allow(struct sock *sk, u8 type,
|
||||||
if (rt->rt6i_dst.plen < 128)
|
if (rt->rt6i_dst.plen < 128)
|
||||||
tmo >>= ((128 - rt->rt6i_dst.plen)>>5);
|
tmo >>= ((128 - rt->rt6i_dst.plen)>>5);
|
||||||
|
|
||||||
rcu_read_lock();
|
|
||||||
peer = inet_getpeer_v6(net->ipv6.peers, &fl6->daddr);
|
peer = inet_getpeer_v6(net->ipv6.peers, &fl6->daddr);
|
||||||
res = inet_peer_xrlim_allow(peer, tmo);
|
res = inet_peer_xrlim_allow(peer, tmo);
|
||||||
rcu_read_unlock();
|
|
||||||
}
|
}
|
||||||
|
rcu_read_unlock();
|
||||||
if (!res)
|
if (!res)
|
||||||
__ICMP6_INC_STATS(net, ip6_dst_idev(dst),
|
__ICMP6_INC_STATS(net, ip6_dst_idev(dst),
|
||||||
ICMP6_MIB_RATELIMITHOST);
|
ICMP6_MIB_RATELIMITHOST);
|
||||||
|
|
|
||||||
|
|
@ -180,7 +180,7 @@ static struct net_device *ip6_mc_find_dev(struct net *net,
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
rt = rt6_lookup(net, group, NULL, 0, NULL, 0);
|
rt = rt6_lookup(net, group, NULL, 0, NULL, 0);
|
||||||
if (rt) {
|
if (rt) {
|
||||||
dev = dst_dev(&rt->dst);
|
dev = dst_dev_rcu(&rt->dst);
|
||||||
dev_hold(dev);
|
dev_hold(dev);
|
||||||
ip6_rt_put(rt);
|
ip6_rt_put(rt);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -505,7 +505,7 @@ void ndisc_send_skb(struct sk_buff *skb, const struct in6_addr *daddr,
|
||||||
|
|
||||||
ip6_nd_hdr(skb, saddr, daddr, READ_ONCE(inet6_sk(sk)->hop_limit), skb->len);
|
ip6_nd_hdr(skb, saddr, daddr, READ_ONCE(inet6_sk(sk)->hop_limit), skb->len);
|
||||||
|
|
||||||
dev = dst_dev(dst);
|
dev = dst_dev_rcu(dst);
|
||||||
idev = __in6_dev_get(dev);
|
idev = __in6_dev_get(dev);
|
||||||
IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTREQUESTS);
|
IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTREQUESTS);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -104,18 +104,20 @@ EXPORT_SYMBOL(ip6_find_1stfragopt);
|
||||||
int ip6_dst_hoplimit(struct dst_entry *dst)
|
int ip6_dst_hoplimit(struct dst_entry *dst)
|
||||||
{
|
{
|
||||||
int hoplimit = dst_metric_raw(dst, RTAX_HOPLIMIT);
|
int hoplimit = dst_metric_raw(dst, RTAX_HOPLIMIT);
|
||||||
|
|
||||||
|
rcu_read_lock();
|
||||||
if (hoplimit == 0) {
|
if (hoplimit == 0) {
|
||||||
struct net_device *dev = dst_dev(dst);
|
struct net_device *dev = dst_dev_rcu(dst);
|
||||||
struct inet6_dev *idev;
|
struct inet6_dev *idev;
|
||||||
|
|
||||||
rcu_read_lock();
|
|
||||||
idev = __in6_dev_get(dev);
|
idev = __in6_dev_get(dev);
|
||||||
if (idev)
|
if (idev)
|
||||||
hoplimit = READ_ONCE(idev->cnf.hop_limit);
|
hoplimit = READ_ONCE(idev->cnf.hop_limit);
|
||||||
else
|
else
|
||||||
hoplimit = READ_ONCE(dev_net(dev)->ipv6.devconf_all->hop_limit);
|
hoplimit = READ_ONCE(dev_net(dev)->ipv6.devconf_all->hop_limit);
|
||||||
rcu_read_unlock();
|
|
||||||
}
|
}
|
||||||
|
rcu_read_unlock();
|
||||||
|
|
||||||
return hoplimit;
|
return hoplimit;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(ip6_dst_hoplimit);
|
EXPORT_SYMBOL(ip6_dst_hoplimit);
|
||||||
|
|
|
||||||
|
|
@ -2943,7 +2943,7 @@ static void __ip6_rt_update_pmtu(struct dst_entry *dst, const struct sock *sk,
|
||||||
|
|
||||||
if (res.f6i->nh) {
|
if (res.f6i->nh) {
|
||||||
struct fib6_nh_match_arg arg = {
|
struct fib6_nh_match_arg arg = {
|
||||||
.dev = dst_dev(dst),
|
.dev = dst_dev_rcu(dst),
|
||||||
.gw = &rt6->rt6i_gateway,
|
.gw = &rt6->rt6i_gateway,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -3238,7 +3238,6 @@ EXPORT_SYMBOL_GPL(ip6_sk_redirect);
|
||||||
|
|
||||||
static unsigned int ip6_default_advmss(const struct dst_entry *dst)
|
static unsigned int ip6_default_advmss(const struct dst_entry *dst)
|
||||||
{
|
{
|
||||||
struct net_device *dev = dst_dev(dst);
|
|
||||||
unsigned int mtu = dst_mtu(dst);
|
unsigned int mtu = dst_mtu(dst);
|
||||||
struct net *net;
|
struct net *net;
|
||||||
|
|
||||||
|
|
@ -3246,7 +3245,7 @@ static unsigned int ip6_default_advmss(const struct dst_entry *dst)
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
|
|
||||||
net = dev_net_rcu(dev);
|
net = dst_dev_net_rcu(dst);
|
||||||
if (mtu < net->ipv6.sysctl.ip6_rt_min_advmss)
|
if (mtu < net->ipv6.sysctl.ip6_rt_min_advmss)
|
||||||
mtu = net->ipv6.sysctl.ip6_rt_min_advmss;
|
mtu = net->ipv6.sysctl.ip6_rt_min_advmss;
|
||||||
|
|
||||||
|
|
@ -4301,7 +4300,7 @@ static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_bu
|
||||||
|
|
||||||
if (res.f6i->nh) {
|
if (res.f6i->nh) {
|
||||||
struct fib6_nh_match_arg arg = {
|
struct fib6_nh_match_arg arg = {
|
||||||
.dev = dst_dev(dst),
|
.dev = dst_dev_rcu(dst),
|
||||||
.gw = &rt->rt6i_gateway,
|
.gw = &rt->rt6i_gateway,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue