diff options
| author | Stanislav Fomichev <sdf@fomichev.me> | 2025-08-18 08:40:26 -0700 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2025-08-19 17:54:13 -0700 |
| commit | c3f0c02997c7f8489fec259e28e0e04e9811edac (patch) | |
| tree | 3ec6463a3aa14015e41cc3ef657826cba8b100ef /include | |
| parent | Merge branch 'net-speedup-some-nexthop-handling-when-having-a-lot-of-nexthops' (diff) | |
| download | linux-c3f0c02997c7f8489fec259e28e0e04e9811edac.tar.gz linux-c3f0c02997c7f8489fec259e28e0e04e9811edac.zip | |
net: Add skb_dstref_steal and skb_dstref_restore
Going forward skb_dst_set will assert that skb dst_entry
is empty during skb_dst_set to prevent potential leaks. There
are few places that still manually manage dst_entry not using
the helpers. Convert them to the following new helpers:
- skb_dstref_steal that resets dst_entry and returns previous dst_entry
value
- skb_dstref_restore that restores dst_entry previously reset via
skb_dstref_steal
Signed-off-by: Stanislav Fomichev <sdf@fomichev.me>
Link: https://patch.msgid.link/20250818154032.3173645-2-sdf@fomichev.me
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'include')
| -rw-r--r-- | include/linux/skbuff.h | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 14b923ddb6df..7538ca507ee9 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -1160,6 +1160,38 @@ static inline struct dst_entry *skb_dst(const struct sk_buff *skb) } /** + * skb_dstref_steal() - return current dst_entry value and clear it + * @skb: buffer + * + * Resets skb dst_entry without adjusting its reference count. Useful in + * cases where dst_entry needs to be temporarily reset and restored. + * Note that the returned value cannot be used directly because it + * might contain SKB_DST_NOREF bit. + * + * When in doubt, prefer skb_dst_drop() over skb_dstref_steal() to correctly + * handle dst_entry reference counting. + * + * Returns: original skb dst_entry. + */ +static inline unsigned long skb_dstref_steal(struct sk_buff *skb) +{ + unsigned long refdst = skb->_skb_refdst; + + skb->_skb_refdst = 0; + return refdst; +} + +/** + * skb_dstref_restore() - restore skb dst_entry removed via skb_dstref_steal() + * @skb: buffer + * @refdst: dst entry from a call to skb_dstref_steal() + */ +static inline void skb_dstref_restore(struct sk_buff *skb, unsigned long refdst) +{ + skb->_skb_refdst = refdst; +} + +/** * skb_dst_set - sets skb dst * @skb: buffer * @dst: dst entry |
