diff options
author | YOSHIFUJI Hideaki / 吉藤英明 <yoshfuji@linux-ipv6.org> | 2013-01-21 01:48:39 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-01-21 13:33:16 -0500 |
commit | 527a150fb2292a59ca0545dace8d482581253532 (patch) | |
tree | aacc2e11dd66402416e5fce19d11bd356955971d /net/ipv6 | |
parent | af9a997629488ba5f92dc3d76e1ec51fcd759c5d (diff) |
ndisc: Defer building IPv6 header.
Build ICMPv6 message first and make buffer management easier;
we can use skb->len when filling checksum in ICMPv6 header,
and then build IP header with length field.
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/ndisc.c | 22 |
1 files changed, 11 insertions, 11 deletions
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 200b2b22b9ba..09171fdbc312 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
@@ -387,7 +387,7 @@ static struct sk_buff *ndisc_alloc_skb(struct net_device *dev, | |||
387 | skb->protocol = htons(ETH_P_IPV6); | 387 | skb->protocol = htons(ETH_P_IPV6); |
388 | skb->dev = dev; | 388 | skb->dev = dev; |
389 | 389 | ||
390 | skb_reserve(skb, hlen); | 390 | skb_reserve(skb, hlen + sizeof(struct ipv6hdr)); |
391 | 391 | ||
392 | return skb; | 392 | return skb; |
393 | } | 393 | } |
@@ -399,8 +399,8 @@ static void ip6_nd_hdr(struct sk_buff *skb, | |||
399 | { | 399 | { |
400 | struct ipv6hdr *hdr; | 400 | struct ipv6hdr *hdr; |
401 | 401 | ||
402 | skb_push(skb, sizeof(*hdr)); | ||
402 | skb_reset_network_header(skb); | 403 | skb_reset_network_header(skb); |
403 | skb_put(skb, sizeof(struct ipv6hdr)); | ||
404 | hdr = ipv6_hdr(skb); | 404 | hdr = ipv6_hdr(skb); |
405 | 405 | ||
406 | ip6_flow_hdr(hdr, 0, 0); | 406 | ip6_flow_hdr(hdr, 0, 0); |
@@ -438,8 +438,6 @@ static struct sk_buff *ndisc_build_skb(struct net_device *dev, | |||
438 | if (!skb) | 438 | if (!skb) |
439 | return NULL; | 439 | return NULL; |
440 | 440 | ||
441 | ip6_nd_hdr(skb, saddr, daddr, inet6_sk(sk)->hop_limit, len); | ||
442 | |||
443 | skb->transport_header = skb->tail; | 441 | skb->transport_header = skb->tail; |
444 | skb_put(skb, len); | 442 | skb_put(skb, len); |
445 | 443 | ||
@@ -455,10 +453,12 @@ static struct sk_buff *ndisc_build_skb(struct net_device *dev, | |||
455 | if (llinfo) | 453 | if (llinfo) |
456 | ndisc_fill_addr_option(opt, llinfo, dev->dev_addr, dev); | 454 | ndisc_fill_addr_option(opt, llinfo, dev->dev_addr, dev); |
457 | 455 | ||
458 | hdr->icmp6_cksum = csum_ipv6_magic(saddr, daddr, len, | 456 | hdr->icmp6_cksum = csum_ipv6_magic(saddr, daddr, skb->len, |
459 | IPPROTO_ICMPV6, | 457 | IPPROTO_ICMPV6, |
460 | csum_partial(hdr, | 458 | csum_partial(hdr, |
461 | len, 0)); | 459 | skb->len, 0)); |
460 | |||
461 | ip6_nd_hdr(skb, saddr, daddr, inet6_sk(sk)->hop_limit, skb->len); | ||
462 | 462 | ||
463 | return skb; | 463 | return skb; |
464 | } | 464 | } |
@@ -1479,9 +1479,6 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target) | |||
1479 | if (!buff) | 1479 | if (!buff) |
1480 | goto release; | 1480 | goto release; |
1481 | 1481 | ||
1482 | ip6_nd_hdr(buff, &saddr_buf, &ipv6_hdr(skb)->saddr, | ||
1483 | inet6_sk(sk)->hop_limit, len); | ||
1484 | |||
1485 | skb_set_transport_header(buff, skb_tail_pointer(buff) - buff->data); | 1482 | skb_set_transport_header(buff, skb_tail_pointer(buff) - buff->data); |
1486 | skb_put(buff, len); | 1483 | skb_put(buff, len); |
1487 | msg = (struct rd_msg *)icmp6_hdr(buff); | 1484 | msg = (struct rd_msg *)icmp6_hdr(buff); |
@@ -1513,8 +1510,11 @@ void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target) | |||
1513 | opt = ndisc_fill_redirect_hdr_option(opt, skb, rd_len); | 1510 | opt = ndisc_fill_redirect_hdr_option(opt, skb, rd_len); |
1514 | 1511 | ||
1515 | msg->icmph.icmp6_cksum = csum_ipv6_magic(&saddr_buf, &ipv6_hdr(skb)->saddr, | 1512 | msg->icmph.icmp6_cksum = csum_ipv6_magic(&saddr_buf, &ipv6_hdr(skb)->saddr, |
1516 | len, IPPROTO_ICMPV6, | 1513 | buff->len, IPPROTO_ICMPV6, |
1517 | csum_partial(msg, len, 0)); | 1514 | csum_partial(msg, buff->len, 0)); |
1515 | |||
1516 | ip6_nd_hdr(buff, &saddr_buf, &ipv6_hdr(skb)->saddr, | ||
1517 | inet6_sk(sk)->hop_limit, buff->len); | ||
1518 | 1518 | ||
1519 | skb_dst_set(buff, dst); | 1519 | skb_dst_set(buff, dst); |
1520 | rcu_read_lock(); | 1520 | rcu_read_lock(); |