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.c23
1 files changed, 11 insertions, 12 deletions
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 4ec876066b3f..3dcc4b7f41b4 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -177,7 +177,8 @@ static inline int icmpv6_xrlim_allow(struct sock *sk, int type,
177 */ 177 */
178 dst = ip6_route_output(sk, fl); 178 dst = ip6_route_output(sk, fl);
179 if (dst->error) { 179 if (dst->error) {
180 IP6_INC_STATS(IPSTATS_MIB_OUTNOROUTES); 180 IP6_INC_STATS(ip6_dst_idev(dst),
181 IPSTATS_MIB_OUTNOROUTES);
181 } else if (dst->dev && (dst->dev->flags&IFF_LOOPBACK)) { 182 } else if (dst->dev && (dst->dev->flags&IFF_LOOPBACK)) {
182 res = 1; 183 res = 1;
183 } else { 184 } else {
@@ -233,7 +234,7 @@ static int icmpv6_push_pending_frames(struct sock *sk, struct flowi *fl, struct
233 len, fl->proto, 234 len, fl->proto,
234 skb->csum); 235 skb->csum);
235 } else { 236 } else {
236 u32 tmp_csum = 0; 237 __wsum tmp_csum = 0;
237 238
238 skb_queue_walk(&sk->sk_write_queue, skb) { 239 skb_queue_walk(&sk->sk_write_queue, skb) {
239 tmp_csum = csum_add(tmp_csum, skb->csum); 240 tmp_csum = csum_add(tmp_csum, skb->csum);
@@ -241,13 +242,11 @@ static int icmpv6_push_pending_frames(struct sock *sk, struct flowi *fl, struct
241 242
242 tmp_csum = csum_partial((char *)icmp6h, 243 tmp_csum = csum_partial((char *)icmp6h,
243 sizeof(struct icmp6hdr), tmp_csum); 244 sizeof(struct icmp6hdr), tmp_csum);
244 tmp_csum = csum_ipv6_magic(&fl->fl6_src, 245 icmp6h->icmp6_cksum = csum_ipv6_magic(&fl->fl6_src,
245 &fl->fl6_dst, 246 &fl->fl6_dst,
246 len, fl->proto, tmp_csum); 247 len, fl->proto,
247 icmp6h->icmp6_cksum = tmp_csum; 248 tmp_csum);
248 } 249 }
249 if (icmp6h->icmp6_cksum == 0)
250 icmp6h->icmp6_cksum = -1;
251 ip6_push_pending_frames(sk); 250 ip6_push_pending_frames(sk);
252out: 251out:
253 return err; 252 return err;
@@ -263,7 +262,7 @@ static int icmpv6_getfrag(void *from, char *to, int offset, int len, int odd, st
263{ 262{
264 struct icmpv6_msg *msg = (struct icmpv6_msg *) from; 263 struct icmpv6_msg *msg = (struct icmpv6_msg *) from;
265 struct sk_buff *org_skb = msg->skb; 264 struct sk_buff *org_skb = msg->skb;
266 __u32 csum = 0; 265 __wsum csum = 0;
267 266
268 csum = skb_copy_and_csum_bits(org_skb, msg->offset + offset, 267 csum = skb_copy_and_csum_bits(org_skb, msg->offset + offset,
269 to, len, csum); 268 to, len, csum);
@@ -555,7 +554,7 @@ out:
555 icmpv6_xmit_unlock(); 554 icmpv6_xmit_unlock();
556} 555}
557 556
558static void icmpv6_notify(struct sk_buff *skb, int type, int code, u32 info) 557static void icmpv6_notify(struct sk_buff *skb, int type, int code, __be32 info)
559{ 558{
560 struct in6_addr *saddr, *daddr; 559 struct in6_addr *saddr, *daddr;
561 struct inet6_protocol *ipprot; 560 struct inet6_protocol *ipprot;
@@ -637,8 +636,8 @@ static int icmpv6_rcv(struct sk_buff **pskb)
637 break; 636 break;
638 /* fall through */ 637 /* fall through */
639 case CHECKSUM_NONE: 638 case CHECKSUM_NONE:
640 skb->csum = ~csum_ipv6_magic(saddr, daddr, skb->len, 639 skb->csum = ~csum_unfold(csum_ipv6_magic(saddr, daddr, skb->len,
641 IPPROTO_ICMPV6, 0); 640 IPPROTO_ICMPV6, 0));
642 if (__skb_checksum_complete(skb)) { 641 if (__skb_checksum_complete(skb)) {
643 LIMIT_NETDEBUG(KERN_DEBUG "ICMPv6 checksum failed [" NIP6_FMT " > " NIP6_FMT "]\n", 642 LIMIT_NETDEBUG(KERN_DEBUG "ICMPv6 checksum failed [" NIP6_FMT " > " NIP6_FMT "]\n",
644 NIP6(*saddr), NIP6(*daddr)); 643 NIP6(*saddr), NIP6(*daddr));