aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorHannes Frederic Sowa <hannes@stressinduktion.org>2013-12-14 21:41:14 -0500
committerDavid S. Miller <davem@davemloft.net>2013-12-18 17:37:05 -0500
commit93b36cf3425b9bd9c56df7680fb237686b9c82ae (patch)
tree1562e2899394e011e22ce21523dd6ce1defc3ee8 /net
parentcd174e67a6b312fce9bab502ba2b0583e11f537f (diff)
ipv6: support IPV6_PMTU_INTERFACE on sockets
IPV6_PMTU_INTERFACE is the same as IPV6_PMTU_PROBE for ipv6. Add it nontheless for symmetry with IPv4 sockets. Also drop incoming MTU information if this mode is enabled. The additional bit in ipv6_pinfo just eats in the padding behind the bitfield. There are no changes to the layout of the struct at all. Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/dccp/ipv6.c3
-rw-r--r--net/ipv6/ip6_output.c6
-rw-r--r--net/ipv6/ipv6_sockglue.c2
-rw-r--r--net/ipv6/tcp_ipv6.c3
-rw-r--r--net/ipv6/udp.c5
-rw-r--r--net/sctp/input.c3
6 files changed, 17 insertions, 5 deletions
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index 2b90a786e475..629019e6f8e9 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -141,6 +141,9 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
141 if (type == ICMPV6_PKT_TOOBIG) { 141 if (type == ICMPV6_PKT_TOOBIG) {
142 struct dst_entry *dst = NULL; 142 struct dst_entry *dst = NULL;
143 143
144 if (!ip6_sk_accept_pmtu(sk))
145 goto out;
146
144 if (sock_owned_by_user(sk)) 147 if (sock_owned_by_user(sk))
145 goto out; 148 goto out;
146 if ((1 << sk->sk_state) & (DCCPF_LISTEN | DCCPF_CLOSED)) 149 if ((1 << sk->sk_state) & (DCCPF_LISTEN | DCCPF_CLOSED))
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 9a311cc79672..bc4e1bcdf4c0 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1165,10 +1165,10 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
1165 np->cork.hop_limit = hlimit; 1165 np->cork.hop_limit = hlimit;
1166 np->cork.tclass = tclass; 1166 np->cork.tclass = tclass;
1167 if (rt->dst.flags & DST_XFRM_TUNNEL) 1167 if (rt->dst.flags & DST_XFRM_TUNNEL)
1168 mtu = np->pmtudisc == IPV6_PMTUDISC_PROBE ? 1168 mtu = np->pmtudisc >= IPV6_PMTUDISC_PROBE ?
1169 rt->dst.dev->mtu : dst_mtu(&rt->dst); 1169 rt->dst.dev->mtu : dst_mtu(&rt->dst);
1170 else 1170 else
1171 mtu = np->pmtudisc == IPV6_PMTUDISC_PROBE ? 1171 mtu = np->pmtudisc >= IPV6_PMTUDISC_PROBE ?
1172 rt->dst.dev->mtu : dst_mtu(rt->dst.path); 1172 rt->dst.dev->mtu : dst_mtu(rt->dst.path);
1173 if (np->frag_size < mtu) { 1173 if (np->frag_size < mtu) {
1174 if (np->frag_size) 1174 if (np->frag_size)
@@ -1270,7 +1270,7 @@ alloc_new_skb:
1270 if (skb == NULL || skb_prev == NULL) 1270 if (skb == NULL || skb_prev == NULL)
1271 ip6_append_data_mtu(&mtu, &maxfraglen, 1271 ip6_append_data_mtu(&mtu, &maxfraglen,
1272 fragheaderlen, skb, rt, 1272 fragheaderlen, skb, rt,
1273 np->pmtudisc == 1273 np->pmtudisc >=
1274 IPV6_PMTUDISC_PROBE); 1274 IPV6_PMTUDISC_PROBE);
1275 1275
1276 skb_prev = skb; 1276 skb_prev = skb;
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 759fbf96515b..af0ecb94b3b4 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -722,7 +722,7 @@ done:
722 case IPV6_MTU_DISCOVER: 722 case IPV6_MTU_DISCOVER:
723 if (optlen < sizeof(int)) 723 if (optlen < sizeof(int))
724 goto e_inval; 724 goto e_inval;
725 if (val < IP_PMTUDISC_DONT || val > IP_PMTUDISC_PROBE) 725 if (val < IPV6_PMTUDISC_DONT || val > IPV6_PMTUDISC_INTERFACE)
726 goto e_inval; 726 goto e_inval;
727 np->pmtudisc = val; 727 np->pmtudisc = val;
728 retv = 0; 728 retv = 0;
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index da046a5d7ffb..d955487f2c54 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -397,6 +397,9 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
397 if (sk->sk_state == TCP_LISTEN) 397 if (sk->sk_state == TCP_LISTEN)
398 goto out; 398 goto out;
399 399
400 if (!ip6_sk_accept_pmtu(sk))
401 goto out;
402
400 tp->mtu_info = ntohl(info); 403 tp->mtu_info = ntohl(info);
401 if (!sock_owned_by_user(sk)) 404 if (!sock_owned_by_user(sk))
402 tcp_v6_mtu_reduced(sk); 405 tcp_v6_mtu_reduced(sk);
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 089c741a3992..65ed5cd79264 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -538,8 +538,11 @@ void __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
538 if (sk == NULL) 538 if (sk == NULL)
539 return; 539 return;
540 540
541 if (type == ICMPV6_PKT_TOOBIG) 541 if (type == ICMPV6_PKT_TOOBIG) {
542 if (!ip6_sk_accept_pmtu(sk))
543 goto out;
542 ip6_sk_update_pmtu(skb, sk, info); 544 ip6_sk_update_pmtu(skb, sk, info);
545 }
543 if (type == NDISC_REDIRECT) { 546 if (type == NDISC_REDIRECT) {
544 ip6_sk_redirect(skb, sk); 547 ip6_sk_redirect(skb, sk);
545 goto out; 548 goto out;
diff --git a/net/sctp/input.c b/net/sctp/input.c
index 2a192a7c5d81..042ec6c9ae24 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -389,6 +389,9 @@ void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc,
389 if (!t || (t->pathmtu <= pmtu)) 389 if (!t || (t->pathmtu <= pmtu))
390 return; 390 return;
391 391
392 if (!ip6_sk_accept_pmtu(sk))
393 return;
394
392 if (sock_owned_by_user(sk)) { 395 if (sock_owned_by_user(sk)) {
393 asoc->pmtu_pending = 1; 396 asoc->pmtu_pending = 1;
394 t->pmtu_pending = 1; 397 t->pmtu_pending = 1;