diff options
Diffstat (limited to 'net/ipv6/icmp.c')
| -rw-r--r-- | net/ipv6/icmp.c | 20 |
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) | |||
| 496 | out_put: | 505 | out_put: |
| 497 | if (likely(idev != NULL)) | 506 | if (likely(idev != NULL)) |
| 498 | in6_dev_put(idev); | 507 | in6_dev_put(idev); |
| 499 | out_dst_release: | ||
| 500 | dst_release(dst); | 508 | dst_release(dst); |
| 501 | out: | 509 | out: |
| 502 | icmpv6_xmit_unlock(); | 510 | icmpv6_xmit_unlock(); |
