Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=8a4794914f9cf2681235ec2311e189fe307c28c7
Commit:     8a4794914f9cf2681235ec2311e189fe307c28c7
Parent:     c910b47e1811b3f8b184108c48de3d7af3e2999b
Author:     Vlad Yasevich <[EMAIL PROTECTED]>
AuthorDate: Thu Jun 7 14:21:05 2007 -0400
Committer:  Vladislav Yasevich <[EMAIL PROTECTED]>
CommitDate: Wed Jun 13 20:44:42 2007 +0000

    [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 <[EMAIL PROTECTED]>
    Acked-by: Sridhar Samudrala <[EMAIL PROTECTED]>
---
 include/net/sctp/sctp.h    |    7 +++++++
 include/net/sctp/structs.h |    6 ++++++
 net/sctp/associola.c       |    4 ++++
 net/sctp/input.c           |    8 +++++++-
 net/sctp/socket.c          |    3 +++
 5 files changed, 27 insertions(+), 1 deletions(-)

diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index dda72bf..16baef4 100644
--- a/include/net/sctp/sctp.h
+++ b/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/include/net/sctp/structs.h b/include/net/sctp/structs.h
index dc0e70c..ee4559b 100644
--- a/include/net/sctp/structs.h
+++ b/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/net/sctp/associola.c b/net/sctp/associola.c
index df94e3c..498edb0 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 45d6a64..d57ff7f 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 45510c4..6edaaa0 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
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to