diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h index 318593743b6e..541da2dde626 100644 --- a/include/net/ip_fib.h +++ b/include/net/ip_fib.h @@ -629,6 +629,11 @@ static inline void fib_info_hold(struct fib_info *fi) refcount_inc(&fi->fib_clntref); } +static inline bool fib_info_hold_safe(struct fib_info *fi) +{ + return refcount_inc_not_zero(&fi->fib_clntref); +} + static inline void fib_info_put(struct fib_info *fi) { if (refcount_dec_and_test(&fi->fib_clntref)) diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 1308213791f1..dac543c1d686 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -2172,10 +2172,14 @@ static int fib_leaf_notify(struct key_vector *l, struct fib_table *tb, if (fa->fa_slen == last_slen) continue; + if (!fib_info_hold_safe(fa->fa_info)) + continue; + last_slen = fa->fa_slen; err = call_fib_entry_notifier(nb, FIB_EVENT_ENTRY_REPLACE, l->key, KEYLENGTH - fa->fa_slen, fa, extack); + fib_info_put(fa->fa_info); if (err) return err; }