aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/ip6_output.c
diff options
context:
space:
mode:
authorBrian Haley <brian.haley@hp.com>2010-04-23 07:26:09 -0400
committerDavid S. Miller <davem@davemloft.net>2010-04-24 02:35:29 -0400
commit4b340ae20d0e2366792abe70f46629e576adaf5e (patch)
treeb0c413a0348e722fbc23d45508224076b6e60f92 /net/ipv6/ip6_output.c
parent13b52cd44670e3359055e9918d0e766d89836425 (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.c24
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)