aboutsummaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorVlad Yasevich <vladislav.yasevich@hp.com>2007-06-07 14:21:05 -0400
committerVladislav Yasevich <vxy@hera.kernel.org>2007-06-13 20:44:42 +0000
commit8a4794914f9cf2681235ec2311e189fe307c28c7 (patch)
tree029530de3f65445050e7f4c3ad4cd0195b127fa4 /net
parentc910b47e1811b3f8b184108c48de3d7af3e2999b (diff)
[SCTP] Flag a pmtu change request
Currently, if the socket is owned by the user, we drop the ICMP message. As a result SCTP forgets that path MTU changed and never adjusting it's estimate. This causes all subsequent packets to be fragmented. With this patch, we'll flag the association that it needs to udpate it's estimate based on the already updated routing information. Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com> Acked-by: Sridhar Samudrala <sri@us.ibm.com>
Diffstat (limited to 'net')
-rw-r--r--net/sctp/associola.c4
-rw-r--r--net/sctp/input.c8
-rw-r--r--net/sctp/socket.c3
3 files changed, 14 insertions, 1 deletions
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index df94e3cdfba..498edb0cd4e 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -1231,6 +1231,10 @@ void sctp_assoc_sync_pmtu(struct sctp_association *asoc)
/* Get the lowest pmtu of all the transports. */
list_for_each(pos, &asoc->peer.transport_addr_list) {
t = list_entry(pos, struct sctp_transport, transports);
+ if (t->pmtu_pending && t->dst) {
+ sctp_transport_update_pmtu(t, dst_mtu(t->dst));
+ t->pmtu_pending = 0;
+ }
if (!pmtu || (t->pathmtu < pmtu))
pmtu = t->pathmtu;
}
diff --git a/net/sctp/input.c b/net/sctp/input.c
index 45d6a644cf0..d57ff7f3c57 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -367,9 +367,15 @@ static void sctp_add_backlog(struct sock *sk, struct sk_buff *skb)
void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc,
struct sctp_transport *t, __u32 pmtu)
{
- if (sock_owned_by_user(sk) || !t || (t->pathmtu == pmtu))
+ if (!t || (t->pathmtu == pmtu))
return;
+ if (sock_owned_by_user(sk)) {
+ asoc->pmtu_pending = 1;
+ t->pmtu_pending = 1;
+ return;
+ }
+
if (t->param_flags & SPP_PMTUD_ENABLE) {
/* Update transports view of the MTU */
sctp_transport_update_pmtu(t, pmtu);
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 45510c46c22..6edaaa009d6 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -1662,6 +1662,9 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
goto out_free;
}
+ if (asoc->pmtu_pending)
+ sctp_assoc_pending_pmtu(asoc);
+
/* If fragmentation is disabled and the message length exceeds the
* association fragmentation point, return EMSGSIZE. The I-D
* does not specify what this error is, but this looks like