aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2007-10-15 04:29:10 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-10-15 15:26:31 -0400
commit65c88466602c61b639f75623e5ba72c1534df9bd (patch)
tree423b5dc6391dfa05acc0d8ea214306e966ef23be /net
parentf61944efdf0d2569721ed6d7b0445e9f1214b295 (diff)
[IPV6]: Avoid skb_copy/pskb_copy/skb_realloc_headroom on input
This patch replaces unnecessary uses of skb_copy by pskb_expand_head on the IPv6 input path. This allows us to remove the double pointers later. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/ipv6/exthdrs.c23
1 files changed, 5 insertions, 18 deletions
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index c82d4d49f71f..0ff2bf12ecd1 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -234,22 +234,13 @@ static int ipv6_dest_hao(struct sk_buff **skbp, int optoff)
234 goto discard; 234 goto discard;
235 235
236 if (skb_cloned(skb)) { 236 if (skb_cloned(skb)) {
237 struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC); 237 if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
238 struct inet6_skb_parm *opt2;
239
240 if (skb2 == NULL)
241 goto discard; 238 goto discard;
242 239
243 opt2 = IP6CB(skb2);
244 memcpy(opt2, opt, sizeof(*opt2));
245
246 kfree_skb(skb);
247
248 /* update all variable using below by copied skbuff */ 240 /* update all variable using below by copied skbuff */
249 *skbp = skb = skb2; 241 hao = (struct ipv6_destopt_hao *)(skb_network_header(skb) +
250 hao = (struct ipv6_destopt_hao *)(skb_network_header(skb2) +
251 optoff); 242 optoff);
252 ipv6h = ipv6_hdr(skb2); 243 ipv6h = ipv6_hdr(skb);
253 } 244 }
254 245
255 if (skb->ip_summed == CHECKSUM_COMPLETE) 246 if (skb->ip_summed == CHECKSUM_COMPLETE)
@@ -464,18 +455,14 @@ looped_back:
464 Do not damage packets queued somewhere. 455 Do not damage packets queued somewhere.
465 */ 456 */
466 if (skb_cloned(skb)) { 457 if (skb_cloned(skb)) {
467 struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC);
468 /* the copy is a forwarded packet */ 458 /* the copy is a forwarded packet */
469 if (skb2 == NULL) { 459 if (pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) {
470 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), 460 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
471 IPSTATS_MIB_OUTDISCARDS); 461 IPSTATS_MIB_OUTDISCARDS);
472 kfree_skb(skb); 462 kfree_skb(skb);
473 return -1; 463 return -1;
474 } 464 }
475 kfree_skb(skb); 465 hdr = (struct ipv6_rt_hdr *)skb_transport_header(skb);
476 *skbp = skb = skb2;
477 opt = IP6CB(skb2);
478 hdr = (struct ipv6_rt_hdr *)skb_transport_header(skb2);
479 } 466 }
480 467
481 if (skb->ip_summed == CHECKSUM_COMPLETE) 468 if (skb->ip_summed == CHECKSUM_COMPLETE)