diff options
author | John Heffner <jheffner@psc.edu> | 2007-04-21 00:52:39 +0200 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2007-04-26 07:29:09 +0200 |
commit | b881ef7603230550aa0150b22af94089f07ab00d (patch) | |
tree | ec74ff083cc84590e7a48510bb912821bb6cab6c /net | |
parent | [NET_SCHED]: ingress: switch back to using ingress_lock (diff) | |
download | linux-b881ef7603230550aa0150b22af94089f07ab00d.tar.xz linux-b881ef7603230550aa0150b22af94089f07ab00d.zip |
[IPV6]: MTU discovery check in ip6_fragment()
Adds a check in ip6_fragment() mirroring ip_fragment() for packets
that we can't fragment, and sends an ICMP Packet Too Big message
in response.
Signed-off-by: John Heffner <jheffner@psc.edu>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv6/ip6_output.c | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 4cfdad4e8356..5a5b7d4ad31c 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -567,6 +567,19 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) nexthdr = *prevhdr; mtu = dst_mtu(&rt->u.dst); + + /* We must not fragment if the socket is set to force MTU discovery + * or if the skb it not generated by a local socket. (This last + * check should be redundant, but it's free.) + */ + if (!np || np->pmtudisc >= IPV6_PMTUDISC_DO) { + skb->dev = skb->dst->dev; + icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); + IP6_INC_STATS(ip6_dst_idev(skb->dst), IPSTATS_MIB_FRAGFAILS); + kfree_skb(skb); + return -EMSGSIZE; + } + if (np && np->frag_size < mtu) { if (np->frag_size) mtu = np->frag_size; |