Revert "BACKPORT: net: fix __dst_negative_advice() race"

This reverts commit c17f876810.

Reason for revert: Conflicts with upstream commits.

Change-Id: Iee731e1eca0f9a2cef4d301f92bbff758c1afe02
This commit is contained in:
Michael Bestas 2025-03-19 07:32:00 +02:00
commit 5740e39ff5
No known key found for this signature in database
5 changed files with 47 additions and 30 deletions

View file

@ -24,7 +24,7 @@ struct dst_ops {
void (*destroy)(struct dst_entry *);
void (*ifdown)(struct dst_entry *,
struct net_device *dev, int how);
void (*negative_advice)(struct sock *sk, struct dst_entry *);
struct dst_entry * (*negative_advice)(struct dst_entry *);
void (*link_failure)(struct sk_buff *);
void (*update_pmtu)(struct dst_entry *dst, struct sock *sk,
struct sk_buff *skb, u32 mtu,

View file

@ -1936,12 +1936,19 @@ sk_dst_get(struct sock *sk)
static inline void dst_negative_advice(struct sock *sk)
{
struct dst_entry *dst = __sk_dst_get(sk);
struct dst_entry *ndst, *dst = __sk_dst_get(sk);
sk_rethink_txhash(sk);
if (dst && dst->ops->negative_advice)
dst->ops->negative_advice(sk, dst);
if (dst && dst->ops->negative_advice) {
ndst = dst->ops->negative_advice(dst);
if (ndst != dst) {
rcu_assign_pointer(sk->sk_dst_cache, ndst);
sk_tx_queue_clear(sk);
sk->sk_dst_pending_confirm = 0;
}
}
}
static inline void

View file

@ -137,8 +137,7 @@ static int ip_rt_gc_timeout __read_mostly = RT_GC_TIMEOUT;
static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie);
static unsigned int ipv4_default_advmss(const struct dst_entry *dst);
static unsigned int ipv4_mtu(const struct dst_entry *dst);
static void ipv4_negative_advice(struct sock *sk,
struct dst_entry *dst);
static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst);
static void ipv4_link_failure(struct sk_buff *skb);
static void ip_rt_update_pmtu(struct dst_entry *dst, struct sock *sk,
struct sk_buff *skb, u32 mtu,
@ -857,15 +856,22 @@ static void ip_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_buf
__ip_do_redirect(rt, skb, &fl4, true);
}
static void ipv4_negative_advice(struct sock *sk,
struct dst_entry *dst)
static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst)
{
struct rtable *rt = (struct rtable *)dst;
struct dst_entry *ret = dst;
if ((dst->obsolete > 0) ||
(rt->rt_flags & RTCF_REDIRECTED) ||
rt->dst.expires)
sk_dst_reset(sk);
if (rt) {
if (dst->obsolete > 0) {
ip_rt_put(rt);
ret = NULL;
} else if ((rt->rt_flags & RTCF_REDIRECTED) ||
rt->dst.expires) {
ip_rt_put(rt);
ret = NULL;
}
}
return ret;
}
/*

View file

@ -84,8 +84,7 @@ enum rt6_nud_state {
static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie);
static unsigned int ip6_default_advmss(const struct dst_entry *dst);
static unsigned int ip6_mtu(const struct dst_entry *dst);
static void ip6_negative_advice(struct sock *sk,
struct dst_entry *dst);
static struct dst_entry *ip6_negative_advice(struct dst_entry *);
static void ip6_dst_destroy(struct dst_entry *);
static void ip6_dst_ifdown(struct dst_entry *,
struct net_device *dev, int how);
@ -2659,24 +2658,24 @@ static struct dst_entry *ip6_dst_check(struct dst_entry *dst, u32 cookie)
return dst_ret;
}
static void ip6_negative_advice(struct sock *sk,
struct dst_entry *dst)
static struct dst_entry *ip6_negative_advice(struct dst_entry *dst)
{
struct rt6_info *rt = (struct rt6_info *) dst;
if (rt->rt6i_flags & RTF_CACHE) {
rcu_read_lock();
if (rt6_check_expired(rt)) {
/* counteract the dst_release() in sk_dst_reset() */
dst_hold(dst);
sk_dst_reset(sk);
rt6_remove_exception_rt(rt);
if (rt) {
if (rt->rt6i_flags & RTF_CACHE) {
rcu_read_lock();
if (rt6_check_expired(rt)) {
rt6_remove_exception_rt(rt);
dst = NULL;
}
rcu_read_unlock();
} else {
dst_release(dst);
dst = NULL;
}
rcu_read_unlock();
return;
}
sk_dst_reset(sk);
return dst;
}
static void ip6_link_failure(struct sk_buff *skb)

View file

@ -3778,10 +3778,15 @@ static void xfrm_link_failure(struct sk_buff *skb)
/* Impossible. Such dst must be popped before reaches point of failure. */
}
static void xfrm_negative_advice(struct sock *sk, struct dst_entry *dst)
static struct dst_entry *xfrm_negative_advice(struct dst_entry *dst)
{
if (dst->obsolete)
sk_dst_reset(sk);
if (dst) {
if (dst->obsolete) {
dst_release(dst);
dst = NULL;
}
}
return dst;
}
static void xfrm_init_pmtu(struct xfrm_dst **bundle, int nr)