diff options
Diffstat (limited to 'net/ipv6/icmp.c')
-rw-r--r-- | net/ipv6/icmp.c | 23 |
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); |
252 | out: | 251 | out: |
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 | ||
558 | static void icmpv6_notify(struct sk_buff *skb, int type, int code, u32 info) | 557 | static 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)); |