aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/icmp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/icmp.c')
-rw-r--r--net/ipv6/icmp.c48
1 files changed, 28 insertions, 20 deletions
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index edfe98bf64c3..e9bcce9e7bdf 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -68,6 +68,7 @@
68#include <asm/system.h> 68#include <asm/system.h>
69 69
70DEFINE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics) __read_mostly; 70DEFINE_SNMP_STAT(struct icmpv6_mib, icmpv6_statistics) __read_mostly;
71EXPORT_SYMBOL(icmpv6_statistics);
71 72
72/* 73/*
73 * The ICMP socket(s). This is the most convenient way to flow control 74 * The ICMP socket(s). This is the most convenient way to flow control
@@ -128,9 +129,9 @@ void icmpv6_param_prob(struct sk_buff *skb, int code, int pos)
128 129
129static int is_ineligible(struct sk_buff *skb) 130static int is_ineligible(struct sk_buff *skb)
130{ 131{
131 int ptr = (u8*)(skb->nh.ipv6h+1) - skb->data; 132 int ptr = (u8 *)(ipv6_hdr(skb) + 1) - skb->data;
132 int len = skb->len - ptr; 133 int len = skb->len - ptr;
133 __u8 nexthdr = skb->nh.ipv6h->nexthdr; 134 __u8 nexthdr = ipv6_hdr(skb)->nexthdr;
134 135
135 if (len < 0) 136 if (len < 0)
136 return 1; 137 return 1;
@@ -205,7 +206,7 @@ static __inline__ int opt_unrec(struct sk_buff *skb, __u32 offset)
205{ 206{
206 u8 _optval, *op; 207 u8 _optval, *op;
207 208
208 offset += skb->nh.raw - skb->data; 209 offset += skb_network_offset(skb);
209 op = skb_header_pointer(skb, offset, sizeof(_optval), &_optval); 210 op = skb_header_pointer(skb, offset, sizeof(_optval), &_optval);
210 if (op == NULL) 211 if (op == NULL)
211 return 1; 212 return 1;
@@ -221,7 +222,7 @@ static int icmpv6_push_pending_frames(struct sock *sk, struct flowi *fl, struct
221 if ((skb = skb_peek(&sk->sk_write_queue)) == NULL) 222 if ((skb = skb_peek(&sk->sk_write_queue)) == NULL)
222 goto out; 223 goto out;
223 224
224 icmp6h = (struct icmp6hdr*) skb->h.raw; 225 icmp6h = icmp6_hdr(skb);
225 memcpy(icmp6h, thdr, sizeof(struct icmp6hdr)); 226 memcpy(icmp6h, thdr, sizeof(struct icmp6hdr));
226 icmp6h->icmp6_cksum = 0; 227 icmp6h->icmp6_cksum = 0;
227 228
@@ -274,7 +275,7 @@ static int icmpv6_getfrag(void *from, char *to, int offset, int len, int odd, st
274#ifdef CONFIG_IPV6_MIP6 275#ifdef CONFIG_IPV6_MIP6
275static void mip6_addr_swap(struct sk_buff *skb) 276static void mip6_addr_swap(struct sk_buff *skb)
276{ 277{
277 struct ipv6hdr *iph = skb->nh.ipv6h; 278 struct ipv6hdr *iph = ipv6_hdr(skb);
278 struct inet6_skb_parm *opt = IP6CB(skb); 279 struct inet6_skb_parm *opt = IP6CB(skb);
279 struct ipv6_destopt_hao *hao; 280 struct ipv6_destopt_hao *hao;
280 struct in6_addr tmp; 281 struct in6_addr tmp;
@@ -283,7 +284,8 @@ static void mip6_addr_swap(struct sk_buff *skb)
283 if (opt->dsthao) { 284 if (opt->dsthao) {
284 off = ipv6_find_tlv(skb, opt->dsthao, IPV6_TLV_HAO); 285 off = ipv6_find_tlv(skb, opt->dsthao, IPV6_TLV_HAO);
285 if (likely(off >= 0)) { 286 if (likely(off >= 0)) {
286 hao = (struct ipv6_destopt_hao *)(skb->nh.raw + off); 287 hao = (struct ipv6_destopt_hao *)
288 (skb_network_header(skb) + off);
287 ipv6_addr_copy(&tmp, &iph->saddr); 289 ipv6_addr_copy(&tmp, &iph->saddr);
288 ipv6_addr_copy(&iph->saddr, &hao->addr); 290 ipv6_addr_copy(&iph->saddr, &hao->addr);
289 ipv6_addr_copy(&hao->addr, &tmp); 291 ipv6_addr_copy(&hao->addr, &tmp);
@@ -301,7 +303,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
301 struct net_device *dev) 303 struct net_device *dev)
302{ 304{
303 struct inet6_dev *idev = NULL; 305 struct inet6_dev *idev = NULL;
304 struct ipv6hdr *hdr = skb->nh.ipv6h; 306 struct ipv6hdr *hdr = ipv6_hdr(skb);
305 struct sock *sk; 307 struct sock *sk;
306 struct ipv6_pinfo *np; 308 struct ipv6_pinfo *np;
307 struct in6_addr *saddr = NULL; 309 struct in6_addr *saddr = NULL;
@@ -315,7 +317,8 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
315 int hlimit, tclass; 317 int hlimit, tclass;
316 int err = 0; 318 int err = 0;
317 319
318 if ((u8*)hdr < skb->head || (u8*)(hdr+1) > skb->tail) 320 if ((u8 *)hdr < skb->head ||
321 (skb->network_header + sizeof(*hdr)) > skb->tail)
319 return; 322 return;
320 323
321 /* 324 /*
@@ -430,7 +433,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
430 tclass = 0; 433 tclass = 0;
431 434
432 msg.skb = skb; 435 msg.skb = skb;
433 msg.offset = skb->nh.raw - skb->data; 436 msg.offset = skb_network_offset(skb);
434 msg.type = type; 437 msg.type = type;
435 438
436 len = skb->len - msg.offset; 439 len = skb->len - msg.offset;
@@ -466,13 +469,15 @@ out:
466 icmpv6_xmit_unlock(); 469 icmpv6_xmit_unlock();
467} 470}
468 471
472EXPORT_SYMBOL(icmpv6_send);
473
469static void icmpv6_echo_reply(struct sk_buff *skb) 474static void icmpv6_echo_reply(struct sk_buff *skb)
470{ 475{
471 struct sock *sk; 476 struct sock *sk;
472 struct inet6_dev *idev; 477 struct inet6_dev *idev;
473 struct ipv6_pinfo *np; 478 struct ipv6_pinfo *np;
474 struct in6_addr *saddr = NULL; 479 struct in6_addr *saddr = NULL;
475 struct icmp6hdr *icmph = (struct icmp6hdr *) skb->h.raw; 480 struct icmp6hdr *icmph = icmp6_hdr(skb);
476 struct icmp6hdr tmp_hdr; 481 struct icmp6hdr tmp_hdr;
477 struct flowi fl; 482 struct flowi fl;
478 struct icmpv6_msg msg; 483 struct icmpv6_msg msg;
@@ -481,7 +486,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
481 int hlimit; 486 int hlimit;
482 int tclass; 487 int tclass;
483 488
484 saddr = &skb->nh.ipv6h->daddr; 489 saddr = &ipv6_hdr(skb)->daddr;
485 490
486 if (!ipv6_unicast_destination(skb)) 491 if (!ipv6_unicast_destination(skb))
487 saddr = NULL; 492 saddr = NULL;
@@ -491,7 +496,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
491 496
492 memset(&fl, 0, sizeof(fl)); 497 memset(&fl, 0, sizeof(fl));
493 fl.proto = IPPROTO_ICMPV6; 498 fl.proto = IPPROTO_ICMPV6;
494 ipv6_addr_copy(&fl.fl6_dst, &skb->nh.ipv6h->saddr); 499 ipv6_addr_copy(&fl.fl6_dst, &ipv6_hdr(skb)->saddr);
495 if (saddr) 500 if (saddr)
496 ipv6_addr_copy(&fl.fl6_src, saddr); 501 ipv6_addr_copy(&fl.fl6_src, saddr);
497 fl.oif = skb->dev->ifindex; 502 fl.oif = skb->dev->ifindex;
@@ -579,8 +584,8 @@ static void icmpv6_notify(struct sk_buff *skb, int type, int code, __be32 info)
579 if (!pskb_may_pull(skb, inner_offset+8)) 584 if (!pskb_may_pull(skb, inner_offset+8))
580 return; 585 return;
581 586
582 saddr = &skb->nh.ipv6h->saddr; 587 saddr = &ipv6_hdr(skb)->saddr;
583 daddr = &skb->nh.ipv6h->daddr; 588 daddr = &ipv6_hdr(skb)->daddr;
584 589
585 /* BUGGG_FUTURE: we should try to parse exthdrs in this packet. 590 /* BUGGG_FUTURE: we should try to parse exthdrs in this packet.
586 Without this we will not able f.e. to make source routed 591 Without this we will not able f.e. to make source routed
@@ -624,8 +629,8 @@ static int icmpv6_rcv(struct sk_buff **pskb)
624 629
625 ICMP6_INC_STATS_BH(idev, ICMP6_MIB_INMSGS); 630 ICMP6_INC_STATS_BH(idev, ICMP6_MIB_INMSGS);
626 631
627 saddr = &skb->nh.ipv6h->saddr; 632 saddr = &ipv6_hdr(skb)->saddr;
628 daddr = &skb->nh.ipv6h->daddr; 633 daddr = &ipv6_hdr(skb)->daddr;
629 634
630 /* Perform checksum. */ 635 /* Perform checksum. */
631 switch (skb->ip_summed) { 636 switch (skb->ip_summed) {
@@ -647,7 +652,7 @@ static int icmpv6_rcv(struct sk_buff **pskb)
647 if (!pskb_pull(skb, sizeof(struct icmp6hdr))) 652 if (!pskb_pull(skb, sizeof(struct icmp6hdr)))
648 goto discard_it; 653 goto discard_it;
649 654
650 hdr = (struct icmp6hdr *) skb->h.raw; 655 hdr = icmp6_hdr(skb);
651 656
652 type = hdr->icmp6_type; 657 type = hdr->icmp6_type;
653 658
@@ -673,7 +678,7 @@ static int icmpv6_rcv(struct sk_buff **pskb)
673 */ 678 */
674 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) 679 if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
675 goto discard_it; 680 goto discard_it;
676 hdr = (struct icmp6hdr *) skb->h.raw; 681 hdr = icmp6_hdr(skb);
677 orig_hdr = (struct ipv6hdr *) (hdr + 1); 682 orig_hdr = (struct ipv6hdr *) (hdr + 1);
678 rt6_pmtu_discovery(&orig_hdr->daddr, &orig_hdr->saddr, dev, 683 rt6_pmtu_discovery(&orig_hdr->daddr, &orig_hdr->saddr, dev,
679 ntohl(hdr->icmp6_mtu)); 684 ntohl(hdr->icmp6_mtu));
@@ -727,7 +732,8 @@ static int icmpv6_rcv(struct sk_buff **pskb)
727 */ 732 */
728 733
729 icmpv6_notify(skb, type, hdr->icmp6_code, hdr->icmp6_mtu); 734 icmpv6_notify(skb, type, hdr->icmp6_code, hdr->icmp6_mtu);
730 }; 735 }
736
731 kfree_skb(skb); 737 kfree_skb(skb);
732 return 0; 738 return 0;
733 739
@@ -860,11 +866,13 @@ int icmpv6_err_convert(int type, int code, int *err)
860 case ICMPV6_TIME_EXCEED: 866 case ICMPV6_TIME_EXCEED:
861 *err = EHOSTUNREACH; 867 *err = EHOSTUNREACH;
862 break; 868 break;
863 }; 869 }
864 870
865 return fatal; 871 return fatal;
866} 872}
867 873
874EXPORT_SYMBOL(icmpv6_err_convert);
875
868#ifdef CONFIG_SYSCTL 876#ifdef CONFIG_SYSCTL
869ctl_table ipv6_icmp_table[] = { 877ctl_table ipv6_icmp_table[] = {
870 { 878 {