diff options
author | Brian Haley <brian.haley@hp.com> | 2010-04-23 07:26:09 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-04-24 02:35:29 -0400 |
commit | 4b340ae20d0e2366792abe70f46629e576adaf5e (patch) | |
tree | b0c413a0348e722fbc23d45508224076b6e60f92 /net/ipv6/ip6_output.c | |
parent | 13b52cd44670e3359055e9918d0e766d89836425 (diff) |
IPv6: Complete IPV6_DONTFRAG support
Finally add support to detect a local IPV6_DONTFRAG event
and return the relevant data to the user if they've enabled
IPV6_RECVPATHMTU on the socket. The next recvmsg() will
return no data, but have an IPV6_PATHMTU as ancillary data.
Signed-off-by: Brian Haley <brian.haley@hp.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/ip6_output.c')
-rw-r--r-- | net/ipv6/ip6_output.c | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 54d43dd1f085..61e2bef56090 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -1219,15 +1219,23 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, | |||
1219 | */ | 1219 | */ |
1220 | 1220 | ||
1221 | inet->cork.length += length; | 1221 | inet->cork.length += length; |
1222 | if (((length > mtu) && (sk->sk_protocol == IPPROTO_UDP)) && | 1222 | if (length > mtu) { |
1223 | (rt->u.dst.dev->features & NETIF_F_UFO)) { | 1223 | int proto = sk->sk_protocol; |
1224 | if (dontfrag && (proto == IPPROTO_UDP || proto == IPPROTO_RAW)){ | ||
1225 | ipv6_local_rxpmtu(sk, fl, mtu-exthdrlen); | ||
1226 | return -EMSGSIZE; | ||
1227 | } | ||
1224 | 1228 | ||
1225 | err = ip6_ufo_append_data(sk, getfrag, from, length, hh_len, | 1229 | if (proto == IPPROTO_UDP && |
1226 | fragheaderlen, transhdrlen, mtu, | 1230 | (rt->u.dst.dev->features & NETIF_F_UFO)) { |
1227 | flags); | 1231 | |
1228 | if (err) | 1232 | err = ip6_ufo_append_data(sk, getfrag, from, length, |
1229 | goto error; | 1233 | hh_len, fragheaderlen, |
1230 | return 0; | 1234 | transhdrlen, mtu, flags); |
1235 | if (err) | ||
1236 | goto error; | ||
1237 | return 0; | ||
1238 | } | ||
1231 | } | 1239 | } |
1232 | 1240 | ||
1233 | if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) | 1241 | if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) |