diff options
| author | Steffen Klassert <steffen.klassert@secunet.com> | 2010-06-03 21:57:38 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2010-06-04 18:56:00 -0400 |
| commit | 8764ab2ca7ab5055e1ca80f9cfa4970c34acb804 (patch) | |
| tree | ca0a6ea6c6fabbb98220f5b700981f7f23855f42 | |
| parent | 4f4aeb7fd0f7e6ca008bb2147ba36cee13876595 (diff) | |
net: check for refcount if pop a stacked dst_entry
xfrm triggers a warning if dst_pop() drops a refcount
on a noref dst. This patch changes dst_pop() to
skb_dst_pop(). skb_dst_pop() drops the refcnt only
on a refcounted dst. Also we don't clone the child
dst_entry, so it is not refcounted and we can use
skb_dst_set_noref() in xfrm_output_one().
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | include/net/dst.h | 6 | ||||
| -rw-r--r-- | net/xfrm/xfrm_output.c | 4 |
2 files changed, 5 insertions, 5 deletions
diff --git a/include/net/dst.h b/include/net/dst.h index 612069beda73..81d1413a8701 100644 --- a/include/net/dst.h +++ b/include/net/dst.h | |||
| @@ -250,11 +250,11 @@ static inline void skb_tunnel_rx(struct sk_buff *skb, struct net_device *dev) | |||
| 250 | * Linux networking. Thus, destinations are stackable. | 250 | * Linux networking. Thus, destinations are stackable. |
| 251 | */ | 251 | */ |
| 252 | 252 | ||
| 253 | static inline struct dst_entry *dst_pop(struct dst_entry *dst) | 253 | static inline struct dst_entry *skb_dst_pop(struct sk_buff *skb) |
| 254 | { | 254 | { |
| 255 | struct dst_entry *child = dst_clone(dst->child); | 255 | struct dst_entry *child = skb_dst(skb)->child; |
| 256 | 256 | ||
| 257 | dst_release(dst); | 257 | skb_dst_drop(skb); |
| 258 | return child; | 258 | return child; |
| 259 | } | 259 | } |
| 260 | 260 | ||
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c index 6a329158bdfa..a3cca0a94346 100644 --- a/net/xfrm/xfrm_output.c +++ b/net/xfrm/xfrm_output.c | |||
| @@ -95,13 +95,13 @@ resume: | |||
| 95 | goto error_nolock; | 95 | goto error_nolock; |
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | dst = dst_pop(dst); | 98 | dst = skb_dst_pop(skb); |
| 99 | if (!dst) { | 99 | if (!dst) { |
| 100 | XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTERROR); | 100 | XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTERROR); |
| 101 | err = -EHOSTUNREACH; | 101 | err = -EHOSTUNREACH; |
| 102 | goto error_nolock; | 102 | goto error_nolock; |
| 103 | } | 103 | } |
| 104 | skb_dst_set(skb, dst); | 104 | skb_dst_set_noref(skb, dst); |
| 105 | x = dst->xfrm; | 105 | x = dst->xfrm; |
| 106 | } while (x && !(x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL)); | 106 | } while (x && !(x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL)); |
| 107 | 107 | ||
