diff options
Diffstat (limited to 'net/ipv6/ip6_output.c')
| -rw-r--r-- | net/ipv6/ip6_output.c | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index eb6d09728633..dabf108ad811 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
| @@ -267,7 +267,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl, | |||
| 267 | if (net_ratelimit()) | 267 | if (net_ratelimit()) |
| 268 | printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n"); | 268 | printk(KERN_DEBUG "IPv6: sending pkt_too_big to self\n"); |
| 269 | skb->dev = dst->dev; | 269 | skb->dev = dst->dev; |
| 270 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); | 270 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); |
| 271 | IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_FRAGFAILS); | 271 | IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_FRAGFAILS); |
| 272 | kfree_skb(skb); | 272 | kfree_skb(skb); |
| 273 | return -EMSGSIZE; | 273 | return -EMSGSIZE; |
| @@ -402,6 +402,7 @@ int ip6_forward(struct sk_buff *skb) | |||
| 402 | struct ipv6hdr *hdr = ipv6_hdr(skb); | 402 | struct ipv6hdr *hdr = ipv6_hdr(skb); |
| 403 | struct inet6_skb_parm *opt = IP6CB(skb); | 403 | struct inet6_skb_parm *opt = IP6CB(skb); |
| 404 | struct net *net = dev_net(dst->dev); | 404 | struct net *net = dev_net(dst->dev); |
| 405 | u32 mtu; | ||
| 405 | 406 | ||
| 406 | if (net->ipv6.devconf_all->forwarding == 0) | 407 | if (net->ipv6.devconf_all->forwarding == 0) |
| 407 | goto error; | 408 | goto error; |
| @@ -441,8 +442,7 @@ int ip6_forward(struct sk_buff *skb) | |||
| 441 | if (hdr->hop_limit <= 1) { | 442 | if (hdr->hop_limit <= 1) { |
| 442 | /* Force OUTPUT device used as source address */ | 443 | /* Force OUTPUT device used as source address */ |
| 443 | skb->dev = dst->dev; | 444 | skb->dev = dst->dev; |
| 444 | icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, | 445 | icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, 0); |
| 445 | 0, skb->dev); | ||
| 446 | IP6_INC_STATS_BH(net, | 446 | IP6_INC_STATS_BH(net, |
| 447 | ip6_dst_idev(dst), IPSTATS_MIB_INHDRERRORS); | 447 | ip6_dst_idev(dst), IPSTATS_MIB_INHDRERRORS); |
| 448 | 448 | ||
| @@ -504,15 +504,19 @@ int ip6_forward(struct sk_buff *skb) | |||
| 504 | goto error; | 504 | goto error; |
| 505 | if (addrtype & IPV6_ADDR_LINKLOCAL) { | 505 | if (addrtype & IPV6_ADDR_LINKLOCAL) { |
| 506 | icmpv6_send(skb, ICMPV6_DEST_UNREACH, | 506 | icmpv6_send(skb, ICMPV6_DEST_UNREACH, |
| 507 | ICMPV6_NOT_NEIGHBOUR, 0, skb->dev); | 507 | ICMPV6_NOT_NEIGHBOUR, 0); |
| 508 | goto error; | 508 | goto error; |
| 509 | } | 509 | } |
| 510 | } | 510 | } |
| 511 | 511 | ||
| 512 | if (skb->len > dst_mtu(dst)) { | 512 | mtu = dst_mtu(dst); |
| 513 | if (mtu < IPV6_MIN_MTU) | ||
| 514 | mtu = IPV6_MIN_MTU; | ||
| 515 | |||
| 516 | if (skb->len > mtu) { | ||
| 513 | /* Again, force OUTPUT device used as source address */ | 517 | /* Again, force OUTPUT device used as source address */ |
| 514 | skb->dev = dst->dev; | 518 | skb->dev = dst->dev; |
| 515 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, dst_mtu(dst), skb->dev); | 519 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); |
| 516 | IP6_INC_STATS_BH(net, | 520 | IP6_INC_STATS_BH(net, |
| 517 | ip6_dst_idev(dst), IPSTATS_MIB_INTOOBIGERRORS); | 521 | ip6_dst_idev(dst), IPSTATS_MIB_INTOOBIGERRORS); |
| 518 | IP6_INC_STATS_BH(net, | 522 | IP6_INC_STATS_BH(net, |
| @@ -622,12 +626,11 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
| 622 | mtu = ip6_skb_dst_mtu(skb); | 626 | mtu = ip6_skb_dst_mtu(skb); |
| 623 | 627 | ||
| 624 | /* We must not fragment if the socket is set to force MTU discovery | 628 | /* We must not fragment if the socket is set to force MTU discovery |
| 625 | * or if the skb it not generated by a local socket. (This last | 629 | * or if the skb it not generated by a local socket. |
| 626 | * check should be redundant, but it's free.) | ||
| 627 | */ | 630 | */ |
| 628 | if (!skb->local_df) { | 631 | if (!skb->local_df) { |
| 629 | skb->dev = skb_dst(skb)->dev; | 632 | skb->dev = skb_dst(skb)->dev; |
| 630 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); | 633 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); |
| 631 | IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), | 634 | IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), |
| 632 | IPSTATS_MIB_FRAGFAILS); | 635 | IPSTATS_MIB_FRAGFAILS); |
| 633 | kfree_skb(skb); | 636 | kfree_skb(skb); |
