diff options
Diffstat (limited to 'net/core/dst.c')
-rw-r--r-- | net/core/dst.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/net/core/dst.c b/net/core/dst.c index 35fd12f1a69c..df9cc810ec8e 100644 --- a/net/core/dst.c +++ b/net/core/dst.c | |||
@@ -320,27 +320,28 @@ void __dst_destroy_metrics_generic(struct dst_entry *dst, unsigned long old) | |||
320 | EXPORT_SYMBOL(__dst_destroy_metrics_generic); | 320 | EXPORT_SYMBOL(__dst_destroy_metrics_generic); |
321 | 321 | ||
322 | /** | 322 | /** |
323 | * skb_dst_set_noref - sets skb dst, without a reference | 323 | * __skb_dst_set_noref - sets skb dst, without a reference |
324 | * @skb: buffer | 324 | * @skb: buffer |
325 | * @dst: dst entry | 325 | * @dst: dst entry |
326 | * @force: if force is set, use noref version even for DST_NOCACHE entries | ||
326 | * | 327 | * |
327 | * Sets skb dst, assuming a reference was not taken on dst | 328 | * Sets skb dst, assuming a reference was not taken on dst |
328 | * skb_dst_drop() should not dst_release() this dst | 329 | * skb_dst_drop() should not dst_release() this dst |
329 | */ | 330 | */ |
330 | void skb_dst_set_noref(struct sk_buff *skb, struct dst_entry *dst) | 331 | void __skb_dst_set_noref(struct sk_buff *skb, struct dst_entry *dst, bool force) |
331 | { | 332 | { |
332 | WARN_ON(!rcu_read_lock_held() && !rcu_read_lock_bh_held()); | 333 | WARN_ON(!rcu_read_lock_held() && !rcu_read_lock_bh_held()); |
333 | /* If dst not in cache, we must take a reference, because | 334 | /* If dst not in cache, we must take a reference, because |
334 | * dst_release() will destroy dst as soon as its refcount becomes zero | 335 | * dst_release() will destroy dst as soon as its refcount becomes zero |
335 | */ | 336 | */ |
336 | if (unlikely(dst->flags & DST_NOCACHE)) { | 337 | if (unlikely((dst->flags & DST_NOCACHE) && !force)) { |
337 | dst_hold(dst); | 338 | dst_hold(dst); |
338 | skb_dst_set(skb, dst); | 339 | skb_dst_set(skb, dst); |
339 | } else { | 340 | } else { |
340 | skb->_skb_refdst = (unsigned long)dst | SKB_DST_NOREF; | 341 | skb->_skb_refdst = (unsigned long)dst | SKB_DST_NOREF; |
341 | } | 342 | } |
342 | } | 343 | } |
343 | EXPORT_SYMBOL(skb_dst_set_noref); | 344 | EXPORT_SYMBOL(__skb_dst_set_noref); |
344 | 345 | ||
345 | /* Dirty hack. We did it in 2.2 (in __dst_free), | 346 | /* Dirty hack. We did it in 2.2 (in __dst_free), |
346 | * we have _very_ good reasons not to repeat | 347 | * we have _very_ good reasons not to repeat |