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.c20
1 files changed, 14 insertions, 6 deletions
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index fa8f1bb0aa52..b7185fb3377c 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();