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.c29
1 files changed, 16 insertions, 13 deletions
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index fa8f1bb0aa52..23e540365a14 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -287,7 +287,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
287 int iif = 0; 287 int iif = 0;
288 int addr_type = 0; 288 int addr_type = 0;
289 int len; 289 int len;
290 int hlimit; 290 int hlimit, tclass;
291 int err = 0; 291 int err = 0;
292 292
293 if ((u8*)hdr < skb->head || (u8*)(hdr+1) > skb->tail) 293 if ((u8*)hdr < skb->head || (u8*)(hdr+1) > skb->tail)
@@ -374,7 +374,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
374 if (err) 374 if (err)
375 goto out; 375 goto out;
376 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) 376 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
377 goto out_dst_release; 377 goto out;
378 378
379 if (ipv6_addr_is_multicast(&fl.fl6_dst)) 379 if (ipv6_addr_is_multicast(&fl.fl6_dst))
380 hlimit = np->mcast_hops; 380 hlimit = np->mcast_hops;
@@ -385,6 +385,10 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
385 if (hlimit < 0) 385 if (hlimit < 0)
386 hlimit = ipv6_get_hoplimit(dst->dev); 386 hlimit = ipv6_get_hoplimit(dst->dev);
387 387
388 tclass = np->cork.tclass;
389 if (tclass < 0)
390 tclass = 0;
391
388 msg.skb = skb; 392 msg.skb = skb;
389 msg.offset = skb->nh.raw - skb->data; 393 msg.offset = skb->nh.raw - skb->data;
390 394
@@ -400,7 +404,7 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
400 err = ip6_append_data(sk, icmpv6_getfrag, &msg, 404 err = ip6_append_data(sk, icmpv6_getfrag, &msg,
401 len + sizeof(struct icmp6hdr), 405 len + sizeof(struct icmp6hdr),
402 sizeof(struct icmp6hdr), 406 sizeof(struct icmp6hdr),
403 hlimit, NULL, &fl, (struct rt6_info*)dst, 407 hlimit, tclass, NULL, &fl, (struct rt6_info*)dst,
404 MSG_DONTWAIT); 408 MSG_DONTWAIT);
405 if (err) { 409 if (err) {
406 ip6_flush_pending_frames(sk); 410 ip6_flush_pending_frames(sk);
@@ -434,6 +438,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
434 struct dst_entry *dst; 438 struct dst_entry *dst;
435 int err = 0; 439 int err = 0;
436 int hlimit; 440 int hlimit;
441 int tclass;
437 442
438 saddr = &skb->nh.ipv6h->daddr; 443 saddr = &skb->nh.ipv6h->daddr;
439 444
@@ -464,7 +469,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
464 if (err) 469 if (err)
465 goto out; 470 goto out;
466 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0) 471 if ((err = xfrm_lookup(&dst, &fl, sk, 0)) < 0)
467 goto out_dst_release; 472 goto out;
468 473
469 if (ipv6_addr_is_multicast(&fl.fl6_dst)) 474 if (ipv6_addr_is_multicast(&fl.fl6_dst))
470 hlimit = np->mcast_hops; 475 hlimit = np->mcast_hops;
@@ -475,13 +480,17 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
475 if (hlimit < 0) 480 if (hlimit < 0)
476 hlimit = ipv6_get_hoplimit(dst->dev); 481 hlimit = ipv6_get_hoplimit(dst->dev);
477 482
483 tclass = np->cork.tclass;
484 if (tclass < 0)
485 tclass = 0;
486
478 idev = in6_dev_get(skb->dev); 487 idev = in6_dev_get(skb->dev);
479 488
480 msg.skb = skb; 489 msg.skb = skb;
481 msg.offset = 0; 490 msg.offset = 0;
482 491
483 err = ip6_append_data(sk, icmpv6_getfrag, &msg, skb->len + sizeof(struct icmp6hdr), 492 err = ip6_append_data(sk, icmpv6_getfrag, &msg, skb->len + sizeof(struct icmp6hdr),
484 sizeof(struct icmp6hdr), hlimit, NULL, &fl, 493 sizeof(struct icmp6hdr), hlimit, tclass, NULL, &fl,
485 (struct rt6_info*)dst, MSG_DONTWAIT); 494 (struct rt6_info*)dst, MSG_DONTWAIT);
486 495
487 if (err) { 496 if (err) {
@@ -496,7 +505,6 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
496out_put: 505out_put:
497 if (likely(idev != NULL)) 506 if (likely(idev != NULL))
498 in6_dev_put(idev); 507 in6_dev_put(idev);
499out_dst_release:
500 dst_release(dst); 508 dst_release(dst);
501out: 509out:
502 icmpv6_xmit_unlock(); 510 icmpv6_xmit_unlock();
@@ -692,10 +700,7 @@ int __init icmpv6_init(struct net_proto_family *ops)
692 struct sock *sk; 700 struct sock *sk;
693 int err, i, j; 701 int err, i, j;
694 702
695 for (i = 0; i < NR_CPUS; i++) { 703 for_each_cpu(i) {
696 if (!cpu_possible(i))
697 continue;
698
699 err = sock_create_kern(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, 704 err = sock_create_kern(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6,
700 &per_cpu(__icmpv6_socket, i)); 705 &per_cpu(__icmpv6_socket, i));
701 if (err < 0) { 706 if (err < 0) {
@@ -741,9 +746,7 @@ void icmpv6_cleanup(void)
741{ 746{
742 int i; 747 int i;
743 748
744 for (i = 0; i < NR_CPUS; i++) { 749 for_each_cpu(i) {
745 if (!cpu_possible(i))
746 continue;
747 sock_release(per_cpu(__icmpv6_socket, i)); 750 sock_release(per_cpu(__icmpv6_socket, i));
748 } 751 }
749 inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6); 752 inet6_del_protocol(&icmpv6_protocol, IPPROTO_ICMPV6);