Skip to content

Commit b775ecf

Browse files
edumazetkuba-moo
authored andcommitted
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: 4a6ce2b ("net: introduce a new function dst_dev_put()") Signed-off-by: Eric Dumazet <[email protected]> Reviewed-by: David Ahern <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
1 parent caedcc5 commit b775ecf

File tree

6 files changed

+14
-13
lines changed

6 files changed

+14
-13
lines changed

net/ipv6/anycast.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
104104
rcu_read_lock();
105105
rt = rt6_lookup(net, addr, NULL, 0, NULL, 0);
106106
if (rt) {
107-
dev = dst_dev(&rt->dst);
107+
dev = dst_dev_rcu(&rt->dst);
108108
netdev_hold(dev, &dev_tracker, GFP_ATOMIC);
109109
ip6_rt_put(rt);
110110
} else if (ishost) {

net/ipv6/icmp.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,8 @@ static bool icmpv6_xrlim_allow(struct sock *sk, u8 type,
209209
* this lookup should be more aggressive (not longer than timeout).
210210
*/
211211
dst = ip6_route_output(net, sk, fl6);
212-
dev = dst_dev(dst);
212+
rcu_read_lock();
213+
dev = dst_dev_rcu(dst);
213214
if (dst->error) {
214215
IP6_INC_STATS(net, ip6_dst_idev(dst),
215216
IPSTATS_MIB_OUTNOROUTES);
@@ -224,11 +225,10 @@ static bool icmpv6_xrlim_allow(struct sock *sk, u8 type,
224225
if (rt->rt6i_dst.plen < 128)
225226
tmo >>= ((128 - rt->rt6i_dst.plen)>>5);
226227

227-
rcu_read_lock();
228228
peer = inet_getpeer_v6(net->ipv6.peers, &fl6->daddr);
229229
res = inet_peer_xrlim_allow(peer, tmo);
230-
rcu_read_unlock();
231230
}
231+
rcu_read_unlock();
232232
if (!res)
233233
__ICMP6_INC_STATS(net, ip6_dst_idev(dst),
234234
ICMP6_MIB_RATELIMITHOST);

net/ipv6/mcast.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ static struct net_device *ip6_mc_find_dev(struct net *net,
180180
rcu_read_lock();
181181
rt = rt6_lookup(net, group, NULL, 0, NULL, 0);
182182
if (rt) {
183-
dev = dst_dev(&rt->dst);
183+
dev = dst_dev_rcu(&rt->dst);
184184
dev_hold(dev);
185185
ip6_rt_put(rt);
186186
}

net/ipv6/ndisc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,7 @@ void ndisc_send_skb(struct sk_buff *skb, const struct in6_addr *daddr,
505505

506506
ip6_nd_hdr(skb, saddr, daddr, READ_ONCE(inet6_sk(sk)->hop_limit), skb->len);
507507

508-
dev = dst_dev(dst);
508+
dev = dst_dev_rcu(dst);
509509
idev = __in6_dev_get(dev);
510510
IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTREQUESTS);
511511

net/ipv6/output_core.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,18 +104,20 @@ EXPORT_SYMBOL(ip6_find_1stfragopt);
104104
int ip6_dst_hoplimit(struct dst_entry *dst)
105105
{
106106
int hoplimit = dst_metric_raw(dst, RTAX_HOPLIMIT);
107+
108+
rcu_read_lock();
107109
if (hoplimit == 0) {
108-
struct net_device *dev = dst_dev(dst);
110+
struct net_device *dev = dst_dev_rcu(dst);
109111
struct inet6_dev *idev;
110112

111-
rcu_read_lock();
112113
idev = __in6_dev_get(dev);
113114
if (idev)
114115
hoplimit = READ_ONCE(idev->cnf.hop_limit);
115116
else
116117
hoplimit = READ_ONCE(dev_net(dev)->ipv6.devconf_all->hop_limit);
117-
rcu_read_unlock();
118118
}
119+
rcu_read_unlock();
120+
119121
return hoplimit;
120122
}
121123
EXPORT_SYMBOL(ip6_dst_hoplimit);

net/ipv6/route.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2943,7 +2943,7 @@ static void __ip6_rt_update_pmtu(struct dst_entry *dst, const struct sock *sk,
29432943

29442944
if (res.f6i->nh) {
29452945
struct fib6_nh_match_arg arg = {
2946-
.dev = dst_dev(dst),
2946+
.dev = dst_dev_rcu(dst),
29472947
.gw = &rt6->rt6i_gateway,
29482948
};
29492949

@@ -3238,15 +3238,14 @@ EXPORT_SYMBOL_GPL(ip6_sk_redirect);
32383238

32393239
static unsigned int ip6_default_advmss(const struct dst_entry *dst)
32403240
{
3241-
struct net_device *dev = dst_dev(dst);
32423241
unsigned int mtu = dst_mtu(dst);
32433242
struct net *net;
32443243

32453244
mtu -= sizeof(struct ipv6hdr) + sizeof(struct tcphdr);
32463245

32473246
rcu_read_lock();
32483247

3249-
net = dev_net_rcu(dev);
3248+
net = dst_dev_net_rcu(dst);
32503249
if (mtu < net->ipv6.sysctl.ip6_rt_min_advmss)
32513250
mtu = net->ipv6.sysctl.ip6_rt_min_advmss;
32523251

@@ -4301,7 +4300,7 @@ static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_bu
43014300

43024301
if (res.f6i->nh) {
43034302
struct fib6_nh_match_arg arg = {
4304-
.dev = dst_dev(dst),
4303+
.dev = dst_dev_rcu(dst),
43054304
.gw = &rt->rt6i_gateway,
43064305
};
43074306

0 commit comments

Comments
 (0)