From e341a55fa3cba7684f5e66a2d6cceb8fe94bbd09 Mon Sep 17 00:00:00 2001 From: Vlad Yasevich Date: Thu, 7 Jun 2007 14:21:05 -0400 Subject: [PATCH] --- yaml --- r: 57724 b: refs/heads/master c: 8a4794914f9cf2681235ec2311e189fe307c28c7 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/include/net/sctp/sctp.h | 7 +++++++ trunk/include/net/sctp/structs.h | 6 ++++++ trunk/net/sctp/associola.c | 4 ++++ trunk/net/sctp/input.c | 8 +++++++- trunk/net/sctp/socket.c | 3 +++ 6 files changed, 28 insertions(+), 2 deletions(-) diff --git a/[refs] b/[refs] index 620aa3216206..a01dd123a8e5 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: c910b47e1811b3f8b184108c48de3d7af3e2999b +refs/heads/master: 8a4794914f9cf2681235ec2311e189fe307c28c7 diff --git a/trunk/include/net/sctp/sctp.h b/trunk/include/net/sctp/sctp.h index dda72bf5b9b4..16baef4dab7e 100644 --- a/trunk/include/net/sctp/sctp.h +++ b/trunk/include/net/sctp/sctp.h @@ -503,6 +503,13 @@ static inline int sctp_frag_point(const struct sctp_sock *sp, int pmtu) return frag; } +static inline void sctp_assoc_pending_pmtu(struct sctp_association *asoc) +{ + + sctp_assoc_sync_pmtu(asoc); + asoc->pmtu_pending = 0; +} + /* Walk through a list of TLV parameters. Don't trust the * individual parameter lengths and instead depend on * the chunk length to indicate when to stop. Make sure diff --git a/trunk/include/net/sctp/structs.h b/trunk/include/net/sctp/structs.h index dc0e70cb0f8b..ee4559b11302 100644 --- a/trunk/include/net/sctp/structs.h +++ b/trunk/include/net/sctp/structs.h @@ -912,6 +912,9 @@ struct sctp_transport { */ __u16 pathmaxrxt; + /* is the Path MTU update pending on this tranport */ + __u8 pmtu_pending; + /* PMTU : The current known path MTU. */ __u32 pathmtu; @@ -1566,6 +1569,9 @@ struct sctp_association { */ __u16 pathmaxrxt; + /* Flag that path mtu update is pending */ + __u8 pmtu_pending; + /* Association : The smallest PMTU discovered for all of the * PMTU : peer's transport addresses. */ diff --git a/trunk/net/sctp/associola.c b/trunk/net/sctp/associola.c index df94e3cdfba3..498edb0cd4e5 100644 --- a/trunk/net/sctp/associola.c +++ b/trunk/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/trunk/net/sctp/input.c b/trunk/net/sctp/input.c index 45d6a644cf06..d57ff7f3c576 100644 --- a/trunk/net/sctp/input.c +++ b/trunk/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/trunk/net/sctp/socket.c b/trunk/net/sctp/socket.c index 45510c46c223..6edaaa009d62 100644 --- a/trunk/net/sctp/socket.c +++ b/trunk/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