Skip to content

Commit 99a2ace

Browse files
edumazetkuba-moo
authored andcommitted
net: use dst_dev_rcu() in sk_setup_caps()
Use RCU to protect accesses to dst->dev from sk_setup_caps() and sk_dst_gso_max_size(). Also use dst_dev_rcu() in ip6_dst_mtu_maybe_forward(), and ip_dst_mtu_maybe_forward(). ip4_dst_hoplimit() can use dst_dev_net_rcu(). 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 1170957 commit 99a2ace

File tree

4 files changed

+16
-10
lines changed

4 files changed

+16
-10
lines changed

include/net/ip.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -467,12 +467,14 @@ static inline unsigned int ip_dst_mtu_maybe_forward(const struct dst_entry *dst,
467467
bool forwarding)
468468
{
469469
const struct rtable *rt = dst_rtable(dst);
470+
const struct net_device *dev;
470471
unsigned int mtu, res;
471472
struct net *net;
472473

473474
rcu_read_lock();
474475

475-
net = dev_net_rcu(dst_dev(dst));
476+
dev = dst_dev_rcu(dst);
477+
net = dev_net_rcu(dev);
476478
if (READ_ONCE(net->ipv4.sysctl_ip_fwd_use_pmtu) ||
477479
ip_mtu_locked(dst) ||
478480
!forwarding) {
@@ -486,7 +488,7 @@ static inline unsigned int ip_dst_mtu_maybe_forward(const struct dst_entry *dst,
486488
if (mtu)
487489
goto out;
488490

489-
mtu = READ_ONCE(dst_dev(dst)->mtu);
491+
mtu = READ_ONCE(dev->mtu);
490492

491493
if (unlikely(ip_mtu_locked(dst))) {
492494
if (rt->rt_uses_gateway && mtu > 576)

include/net/ip6_route.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ static inline unsigned int ip6_dst_mtu_maybe_forward(const struct dst_entry *dst
337337

338338
mtu = IPV6_MIN_MTU;
339339
rcu_read_lock();
340-
idev = __in6_dev_get(dst_dev(dst));
340+
idev = __in6_dev_get(dst_dev_rcu(dst));
341341
if (idev)
342342
mtu = READ_ONCE(idev->cnf.mtu6);
343343
rcu_read_unlock();

include/net/route.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,7 @@ static inline int ip4_dst_hoplimit(const struct dst_entry *dst)
390390
const struct net *net;
391391

392392
rcu_read_lock();
393-
net = dev_net_rcu(dst_dev(dst));
393+
net = dst_dev_net_rcu(dst);
394394
hoplimit = READ_ONCE(net->ipv4.sysctl_ip_default_ttl);
395395
rcu_read_unlock();
396396
}

net/core/sock.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2587,7 +2587,7 @@ struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority)
25872587
}
25882588
EXPORT_SYMBOL_GPL(sk_clone_lock);
25892589

2590-
static u32 sk_dst_gso_max_size(struct sock *sk, struct dst_entry *dst)
2590+
static u32 sk_dst_gso_max_size(struct sock *sk, const struct net_device *dev)
25912591
{
25922592
bool is_ipv6 = false;
25932593
u32 max_size;
@@ -2597,8 +2597,8 @@ static u32 sk_dst_gso_max_size(struct sock *sk, struct dst_entry *dst)
25972597
!ipv6_addr_v4mapped(&sk->sk_v6_rcv_saddr));
25982598
#endif
25992599
/* pairs with the WRITE_ONCE() in netif_set_gso(_ipv4)_max_size() */
2600-
max_size = is_ipv6 ? READ_ONCE(dst_dev(dst)->gso_max_size) :
2601-
READ_ONCE(dst_dev(dst)->gso_ipv4_max_size);
2600+
max_size = is_ipv6 ? READ_ONCE(dev->gso_max_size) :
2601+
READ_ONCE(dev->gso_ipv4_max_size);
26022602
if (max_size > GSO_LEGACY_MAX_SIZE && !sk_is_tcp(sk))
26032603
max_size = GSO_LEGACY_MAX_SIZE;
26042604

@@ -2607,9 +2607,12 @@ static u32 sk_dst_gso_max_size(struct sock *sk, struct dst_entry *dst)
26072607

26082608
void sk_setup_caps(struct sock *sk, struct dst_entry *dst)
26092609
{
2610+
const struct net_device *dev;
26102611
u32 max_segs = 1;
26112612

2612-
sk->sk_route_caps = dst_dev(dst)->features;
2613+
rcu_read_lock();
2614+
dev = dst_dev_rcu(dst);
2615+
sk->sk_route_caps = dev->features;
26132616
if (sk_is_tcp(sk)) {
26142617
struct inet_connection_sock *icsk = inet_csk(sk);
26152618

@@ -2625,13 +2628,14 @@ void sk_setup_caps(struct sock *sk, struct dst_entry *dst)
26252628
sk->sk_route_caps &= ~NETIF_F_GSO_MASK;
26262629
} else {
26272630
sk->sk_route_caps |= NETIF_F_SG | NETIF_F_HW_CSUM;
2628-
sk->sk_gso_max_size = sk_dst_gso_max_size(sk, dst);
2631+
sk->sk_gso_max_size = sk_dst_gso_max_size(sk, dev);
26292632
/* pairs with the WRITE_ONCE() in netif_set_gso_max_segs() */
2630-
max_segs = max_t(u32, READ_ONCE(dst_dev(dst)->gso_max_segs), 1);
2633+
max_segs = max_t(u32, READ_ONCE(dev->gso_max_segs), 1);
26312634
}
26322635
}
26332636
sk->sk_gso_max_segs = max_segs;
26342637
sk_dst_set(sk, dst);
2638+
rcu_read_unlock();
26352639
}
26362640
EXPORT_SYMBOL_GPL(sk_setup_caps);
26372641

0 commit comments

Comments
 (0)