aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/exthdrs.c
diff options
context:
space:
mode:
authorEric Dumazet <eric.dumazet@gmail.com>2011-07-28 00:00:35 -0400
committerDavid S. Miller <davem@davemloft.net>2011-08-01 03:12:00 -0400
commit897dc80b951e996ba4d26c0038e81a505b92aec1 (patch)
tree867cca9dafcf3d89fa30a04a254a2d1cc3220cba /net/ipv6/exthdrs.c
parentd14730b8e9117c9b77aacd391c049b50163e9b61 (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.c7
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