diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2011-07-28 00:00:35 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-08-01 03:12:00 -0400 |
commit | 897dc80b951e996ba4d26c0038e81a505b92aec1 (patch) | |
tree | 867cca9dafcf3d89fa30a04a254a2d1cc3220cba /net/ipv6/exthdrs.c | |
parent | d14730b8e9117c9b77aacd391c049b50163e9b61 (diff) |
ipv6: avoid a dst_entry refcount change in ipv6_destopt_rcv()
ipv6_destopt_rcv() runs with rcu_read_lock(), so there is no need to
take a temporay reference on dst_entry, even if skb is freed by
ip6_parse_tlv()
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/exthdrs.c')
-rw-r--r-- | net/ipv6/exthdrs.c | 7 |
1 files changed, 2 insertions, 5 deletions
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index 79a485e8a700..1318de4c3e8d 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c | |||
@@ -273,12 +273,12 @@ static int ipv6_destopt_rcv(struct sk_buff *skb) | |||
273 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 273 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) |
274 | __u16 dstbuf; | 274 | __u16 dstbuf; |
275 | #endif | 275 | #endif |
276 | struct dst_entry *dst; | 276 | struct dst_entry *dst = skb_dst(skb); |
277 | 277 | ||
278 | if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) || | 278 | if (!pskb_may_pull(skb, skb_transport_offset(skb) + 8) || |
279 | !pskb_may_pull(skb, (skb_transport_offset(skb) + | 279 | !pskb_may_pull(skb, (skb_transport_offset(skb) + |
280 | ((skb_transport_header(skb)[1] + 1) << 3)))) { | 280 | ((skb_transport_header(skb)[1] + 1) << 3)))) { |
281 | IP6_INC_STATS_BH(dev_net(skb_dst(skb)->dev), ip6_dst_idev(skb_dst(skb)), | 281 | IP6_INC_STATS_BH(dev_net(dst->dev), ip6_dst_idev(dst), |
282 | IPSTATS_MIB_INHDRERRORS); | 282 | IPSTATS_MIB_INHDRERRORS); |
283 | kfree_skb(skb); | 283 | kfree_skb(skb); |
284 | return -1; | 284 | return -1; |
@@ -289,9 +289,7 @@ static int ipv6_destopt_rcv(struct sk_buff *skb) | |||
289 | dstbuf = opt->dst1; | 289 | dstbuf = opt->dst1; |
290 | #endif | 290 | #endif |
291 | 291 | ||
292 | dst = dst_clone(skb_dst(skb)); | ||
293 | if (ip6_parse_tlv(tlvprocdestopt_lst, skb)) { | 292 | if (ip6_parse_tlv(tlvprocdestopt_lst, skb)) { |
294 | dst_release(dst); | ||
295 | skb->transport_header += (skb_transport_header(skb)[1] + 1) << 3; | 293 | skb->transport_header += (skb_transport_header(skb)[1] + 1) << 3; |
296 | opt = IP6CB(skb); | 294 | opt = IP6CB(skb); |
297 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 295 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) |
@@ -304,7 +302,6 @@ static int ipv6_destopt_rcv(struct sk_buff *skb) | |||
304 | 302 | ||
305 | IP6_INC_STATS_BH(dev_net(dst->dev), | 303 | IP6_INC_STATS_BH(dev_net(dst->dev), |
306 | ip6_dst_idev(dst), IPSTATS_MIB_INHDRERRORS); | 304 | ip6_dst_idev(dst), IPSTATS_MIB_INHDRERRORS); |
307 | dst_release(dst); | ||
308 | return -1; | 305 | return -1; |
309 | } | 306 | } |
310 | 307 | ||