diff options
Diffstat (limited to 'include/net/dst.h')
-rw-r--r-- | include/net/dst.h | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/include/net/dst.h b/include/net/dst.h index 1279f9b09791..c7329dcd90cc 100644 --- a/include/net/dst.h +++ b/include/net/dst.h | |||
@@ -322,6 +322,39 @@ static inline void skb_dst_force(struct sk_buff *skb) | |||
322 | } | 322 | } |
323 | } | 323 | } |
324 | 324 | ||
325 | /** | ||
326 | * dst_hold_safe - Take a reference on a dst if possible | ||
327 | * @dst: pointer to dst entry | ||
328 | * | ||
329 | * This helper returns false if it could not safely | ||
330 | * take a reference on a dst. | ||
331 | */ | ||
332 | static inline bool dst_hold_safe(struct dst_entry *dst) | ||
333 | { | ||
334 | if (dst->flags & DST_NOCACHE) | ||
335 | return atomic_inc_not_zero(&dst->__refcnt); | ||
336 | dst_hold(dst); | ||
337 | return true; | ||
338 | } | ||
339 | |||
340 | /** | ||
341 | * skb_dst_force_safe - makes sure skb dst is refcounted | ||
342 | * @skb: buffer | ||
343 | * | ||
344 | * If dst is not yet refcounted and not destroyed, grab a ref on it. | ||
345 | */ | ||
346 | static inline void skb_dst_force_safe(struct sk_buff *skb) | ||
347 | { | ||
348 | if (skb_dst_is_noref(skb)) { | ||
349 | struct dst_entry *dst = skb_dst(skb); | ||
350 | |||
351 | if (!dst_hold_safe(dst)) | ||
352 | dst = NULL; | ||
353 | |||
354 | skb->_skb_refdst = (unsigned long)dst; | ||
355 | } | ||
356 | } | ||
357 | |||
325 | 358 | ||
326 | /** | 359 | /** |
327 | * __skb_tunnel_rx - prepare skb for rx reinsert | 360 | * __skb_tunnel_rx - prepare skb for rx reinsert |