]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/sctp/transport.c
x86: coding style fixes in arch/x86/lib/io_64.c
[linux-2.6-omap-h63xx.git] / net / sctp / transport.c
index 4d8c2ab864fcdeae38533dce7c24f042e8bca626..d9f8af852b5634d608c2ae6d36c42a2174e477b4 100644 (file)
@@ -1,23 +1,23 @@
-/* SCTP kernel reference Implementation
+/* SCTP kernel implementation
  * Copyright (c) 1999-2000 Cisco, Inc.
  * Copyright (c) 1999-2001 Motorola, Inc.
  * Copyright (c) 2001-2003 International Business Machines Corp.
  * Copyright (c) 2001 Intel Corp.
  * Copyright (c) 2001 La Monte H.P. Yarroll
  *
- * This file is part of the SCTP kernel reference Implementation
+ * This file is part of the SCTP kernel implementation
  *
  * This module provides the abstraction for an SCTP tranport representing
  * a remote transport address.  For local transport addresses, we just use
  * union sctp_addr.
  *
- * The SCTP reference implementation is free software;
+ * This SCTP implementation is free software;
  * you can redistribute it and/or modify it under the terms of
  * the GNU General Public License as published by
  * the Free Software Foundation; either version 2, or (at your option)
  * any later version.
  *
- * The SCTP reference implementation is distributed in the hope that it
+ * This SCTP implementation is distributed in the hope that it
  * will be useful, but WITHOUT ANY WARRANTY; without even the implied
  *                 ************************
  * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
@@ -74,8 +74,8 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
         * given destination transport address, set RTO to the protocol
         * parameter 'RTO.Initial'.
         */
+       peer->last_rto = peer->rto = msecs_to_jiffies(sctp_rto_initial);
        peer->rtt = 0;
-       peer->rto = msecs_to_jiffies(sctp_rto_initial);
        peer->rttvar = 0;
        peer->srtt = 0;
        peer->rto_pending = 0;
@@ -99,15 +99,10 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,
        INIT_LIST_HEAD(&peer->send_ready);
        INIT_LIST_HEAD(&peer->transports);
 
-       /* Set up the retransmission timer.  */
-       init_timer(&peer->T3_rtx_timer);
-       peer->T3_rtx_timer.function = sctp_generate_t3_rtx_event;
-       peer->T3_rtx_timer.data = (unsigned long)peer;
-
-       /* Set up the heartbeat timer. */
-       init_timer(&peer->hb_timer);
-       peer->hb_timer.function = sctp_generate_heartbeat_event;
-       peer->hb_timer.data = (unsigned long)peer;
+       setup_timer(&peer->T3_rtx_timer, sctp_generate_t3_rtx_event,
+                       (unsigned long)peer);
+       setup_timer(&peer->hb_timer, sctp_generate_heartbeat_event,
+                       (unsigned long)peer);
 
        /* Initialize the 64-bit random nonce sent with heartbeat. */
        get_random_bytes(&peer->hb_nonce, sizeof(peer->hb_nonce));
@@ -241,6 +236,45 @@ void sctp_transport_pmtu(struct sctp_transport *transport)
                transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT;
 }
 
+/* this is a complete rip-off from __sk_dst_check
+ * the cookie is always 0 since this is how it's used in the
+ * pmtu code
+ */
+static struct dst_entry *sctp_transport_dst_check(struct sctp_transport *t)
+{
+       struct dst_entry *dst = t->dst;
+
+       if (dst && dst->obsolete && dst->ops->check(dst, 0) == NULL) {
+               dst_release(t->dst);
+               t->dst = NULL;
+               return NULL;
+       }
+
+       return dst;
+}
+
+void sctp_transport_update_pmtu(struct sctp_transport *t, u32 pmtu)
+{
+       struct dst_entry *dst;
+
+       if (unlikely(pmtu < SCTP_DEFAULT_MINSEGMENT)) {
+               printk(KERN_WARNING "%s: Reported pmtu %d too low, "
+                      "using default minimum of %d\n",
+                      __FUNCTION__, pmtu,
+                      SCTP_DEFAULT_MINSEGMENT);
+               /* Use default minimum segment size and disable
+                * pmtu discovery on this transport.
+                */
+               t->pathmtu = SCTP_DEFAULT_MINSEGMENT;
+       } else {
+               t->pathmtu = pmtu;
+       }
+
+       dst = sctp_transport_dst_check(t);
+       if (dst)
+               dst->ops->update_pmtu(dst, pmtu);
+}
+
 /* Caches the dst entry and source address for a transport's destination
  * address.
  */
@@ -346,6 +380,7 @@ void sctp_transport_update_rto(struct sctp_transport *tp, __u32 rtt)
                tp->rto = tp->asoc->rto_max;
 
        tp->rtt = rtt;
+       tp->last_rto = tp->rto;
 
        /* Reset rto_pending so that a new RTT measurement is started when a
         * new data chunk is sent.
@@ -507,7 +542,7 @@ void sctp_transport_lower_cwnd(struct sctp_transport *transport,
                        transport->cwnd = max(transport->cwnd/2,
                                                 4*transport->asoc->pathmtu);
                break;
-       };
+       }
 
        transport->partial_bytes_acked = 0;
        SCTP_DEBUG_PRINTK("%s: transport: %p reason: %d cwnd: "
@@ -539,7 +574,7 @@ void sctp_transport_reset(struct sctp_transport *t)
         */
        t->cwnd = min(4*asoc->pathmtu, max_t(__u32, 2*asoc->pathmtu, 4380));
        t->ssthresh = asoc->peer.i.a_rwnd;
-       t->rto = asoc->rto_initial;
+       t->last_rto = t->rto = asoc->rto_initial;
        t->rtt = 0;
        t->srtt = 0;
        t->rttvar = 0;