[DCCP] ccid3: Consolidate handling of t_RTO
[linux-2.6-block.git] / net / dccp / ccids / ccid3.c
index 090bc39e8199d1b62ede66c0f39f92f12ba77780..f0ed67c84a556672221ab73dfed52896fa0cce43 100644 (file)
@@ -60,13 +60,11 @@ static u32 usecs_div(const u32 a, const u32 b)
        return (b >= 2 * div) ? tmp / (b / div) : tmp;
 }
 
-static int ccid3_debug;
 
-#ifdef CCID3_DEBUG
-#define ccid3_pr_debug(format, a...) \
-       do { if (ccid3_debug) \
-               printk(KERN_DEBUG "%s: " format, __FUNCTION__, ##a); \
-       } while (0)
+
+#ifdef CONFIG_IP_DCCP_CCID3_DEBUG
+static int ccid3_debug;
+#define ccid3_pr_debug(format, a...)   DCCP_PR_DEBUG(ccid3_debug, format, ##a)
 #else
 #define ccid3_pr_debug(format, a...)
 #endif
@@ -75,15 +73,7 @@ static struct dccp_tx_hist *ccid3_tx_hist;
 static struct dccp_rx_hist *ccid3_rx_hist;
 static struct dccp_li_hist *ccid3_li_hist;
 
-/* TFRC sender states */
-enum ccid3_hc_tx_states {
-               TFRC_SSTATE_NO_SENT = 1,
-       TFRC_SSTATE_NO_FBACK,
-       TFRC_SSTATE_FBACK,
-       TFRC_SSTATE_TERM,
-};
-
-#ifdef CCID3_DEBUG
+#ifdef CONFIG_IP_DCCP_CCID3_DEBUG
 static const char *ccid3_tx_state_name(enum ccid3_hc_tx_states state)
 {
        static char *ccid3_state_names[] = {
@@ -110,25 +100,24 @@ static void ccid3_hc_tx_set_state(struct sock *sk,
        hctx->ccid3hctx_state = state;
 }
 
-/* Calculate new t_ipi (inter packet interval) by t_ipi = s / X_inst */
-static inline void ccid3_calc_new_t_ipi(struct ccid3_hc_tx_sock *hctx)
+/*
+ * Recalculate scheduled nominal send time t_nom, inter-packet interval
+ * t_ipi, and delta value. Should be called after each change to X.
+ */
+static inline void ccid3_update_send_time(struct ccid3_hc_tx_sock *hctx)
 {
-       /*
-        * If no feedback spec says t_ipi is 1 second (set elsewhere and then
-        * doubles after every no feedback timer (separate function)
-        */
-       if (hctx->ccid3hctx_state != TFRC_SSTATE_NO_FBACK)
-               hctx->ccid3hctx_t_ipi = usecs_div(hctx->ccid3hctx_s,
-                                                 hctx->ccid3hctx_x);
-}
+       timeval_sub_usecs(&hctx->ccid3hctx_t_nom, hctx->ccid3hctx_t_ipi);
 
-/* Calculate new delta by delta = min(t_ipi / 2, t_gran / 2) */
-static inline void ccid3_calc_new_delta(struct ccid3_hc_tx_sock *hctx)
-{
+       /* Calculate new t_ipi (inter packet interval) by t_ipi = s / X_inst */
+       hctx->ccid3hctx_t_ipi = usecs_div(hctx->ccid3hctx_s, hctx->ccid3hctx_x);
+
+       /* Update nominal send time with regard to the new t_ipi */
+       timeval_add_usecs(&hctx->ccid3hctx_t_nom, hctx->ccid3hctx_t_ipi);
+
+       /* Calculate new delta by delta = min(t_ipi / 2, t_gran / 2) */
        hctx->ccid3hctx_delta = min_t(u32, hctx->ccid3hctx_t_ipi / 2,
                                           TFRC_OPSYS_HALF_TIME_GRAN);
 }
-
 /*
  * Update X by
  *    If (p > 0)
@@ -142,6 +131,7 @@ static inline void ccid3_calc_new_delta(struct ccid3_hc_tx_sock *hctx)
 static void ccid3_hc_tx_update_x(struct sock *sk)
 {
        struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
+       const __u32 old_x = hctx->ccid3hctx_x;
 
        /* To avoid large error in calcX */
        if (hctx->ccid3hctx_p >= TFRC_SMALLEST_P) {
@@ -165,29 +155,27 @@ static void ccid3_hc_tx_update_x(struct sock *sk)
                        hctx->ccid3hctx_t_ld = now;
                }
        }
+       if (hctx->ccid3hctx_x != old_x)
+               ccid3_update_send_time(hctx);
 }
 
 static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
 {
        struct sock *sk = (struct sock *)data;
-       unsigned long next_tmout = 0;
        struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
+       unsigned long next_tmout = USEC_PER_SEC / 5;
 
        bh_lock_sock(sk);
        if (sock_owned_by_user(sk)) {
                /* Try again later. */
                /* XXX: set some sensible MIB */
-               sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
-                              jiffies + HZ / 5);
-               goto out;
+               goto restart_timer;
        }
 
        ccid3_pr_debug("%s, sk=%p, state=%s\n", dccp_role(sk), sk,
                       ccid3_tx_state_name(hctx->ccid3hctx_state));
        
        switch (hctx->ccid3hctx_state) {
-       case TFRC_SSTATE_TERM:
-               goto out;
        case TFRC_SSTATE_NO_FBACK:
                /* Halve send rate */
                hctx->ccid3hctx_x /= 2;
@@ -201,14 +189,10 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
                               dccp_role(sk), sk,
                               ccid3_tx_state_name(hctx->ccid3hctx_state),
                               hctx->ccid3hctx_x);
-               next_tmout = max_t(u32, 2 * usecs_div(hctx->ccid3hctx_s,
-                                                     hctx->ccid3hctx_x),
-                                       TFRC_INITIAL_TIMEOUT);
-               /*
-                * FIXME - not sure above calculation is correct. See section
-                * 5 of CCID3 11 should adjust tx_t_ipi and double that to
-                * achieve it really
-                */
+               /* The value of R is still undefined and so we can not recompute
+                * the timout value. Keep initial value as per [RFC 4342, 5]. */
+               next_tmout = TFRC_INITIAL_TIMEOUT;
+               ccid3_update_send_time(hctx);
                break;
        case TFRC_SSTATE_FBACK:
                /*
@@ -244,27 +228,34 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
                }
                /*
                 * Schedule no feedback timer to expire in
-                * max(4 * R, 2 * s / X)
+                * max(4 * t_RTO, 2 * s/X)  =  max(4 * t_RTO, 2 * t_ipi)
+                * XXX This is non-standard, RFC 3448, 4.3 uses 4 * R
                 */
-               next_tmout = max_t(u32, hctx->ccid3hctx_t_rto, 
-                                       2 * usecs_div(hctx->ccid3hctx_s,
-                                                     hctx->ccid3hctx_x));
+               next_tmout = max(hctx->ccid3hctx_t_rto, 2*hctx->ccid3hctx_t_ipi);
                break;
-       default:
-               printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
-                      __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state);
-               dump_stack();
+       case TFRC_SSTATE_NO_SENT:
+               DCCP_BUG("Illegal %s state NO_SENT, sk=%p", dccp_role(sk), sk);
+               /* fall through */
+       case TFRC_SSTATE_TERM:
                goto out;
        }
 
-       sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer, 
-                     jiffies + max_t(u32, 1, usecs_to_jiffies(next_tmout)));
        hctx->ccid3hctx_idle = 1;
+
+restart_timer:
+       sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
+                          jiffies + usecs_to_jiffies(next_tmout));
 out:
        bh_unlock_sock(sk);
        sock_put(sk);
 }
 
+/*
+ * returns
+ *   > 0: delay (in msecs) that should pass before actually sending
+ *   = 0: can send immediately
+ *   < 0: error condition; do not send packet
+ */
 static int ccid3_hc_tx_send_packet(struct sock *sk,
                                   struct sk_buff *skb, int len)
 {
@@ -273,17 +264,16 @@ static int ccid3_hc_tx_send_packet(struct sock *sk,
        struct dccp_tx_hist_entry *new_packet;
        struct timeval now;
        long delay;
-       int rc = -ENOTCONN;
 
-       BUG_ON(hctx == NULL || hctx->ccid3hctx_state == TFRC_SSTATE_TERM);
+       BUG_ON(hctx == NULL);
 
-       /* Check if pure ACK or Terminating*/
        /*
-        * XXX: We only call this function for DATA and DATAACK, on, these
-        * packets can have zero length, but why the comment about "pure ACK"?
+        * This function is called only for Data and DataAck packets. Sending
+        * zero-sized Data(Ack)s is theoretically possible, but for congestion
+        * control this case is pathological - ignore it.
         */
        if (unlikely(len == 0))
-               goto out;
+               return -EBADMSG;
 
        /* See if last packet allocated was not sent */
        new_packet = dccp_tx_hist_head(&hctx->ccid3hctx_hist);
@@ -291,12 +281,10 @@ static int ccid3_hc_tx_send_packet(struct sock *sk,
                new_packet = dccp_tx_hist_entry_new(ccid3_tx_hist,
                                                    SLAB_ATOMIC);
 
-               rc = -ENOBUFS;
                if (unlikely(new_packet == NULL)) {
-                       LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, not enough "
-                                      "mem to add to history, send refused\n",
-                                      __FUNCTION__, dccp_role(sk), sk);
-                       goto out;
+                       DCCP_WARN("%s, sk=%p, not enough mem to add to history,"
+                                 "send refused\n", dccp_role(sk), sk);
+                       return -ENOBUFS;
                }
 
                dccp_tx_hist_add_entry(&hctx->ccid3hctx_hist, new_packet);
@@ -311,42 +299,41 @@ static int ccid3_hc_tx_send_packet(struct sock *sk,
                hctx->ccid3hctx_last_win_count   = 0;
                hctx->ccid3hctx_t_last_win_count = now;
                ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK);
-               hctx->ccid3hctx_t_ipi = TFRC_INITIAL_IPI;
 
-               /* Set nominal send time for initial packet */
+               /* First timeout, according to [RFC 3448, 4.2], is 1 second */
+               hctx->ccid3hctx_t_ipi = USEC_PER_SEC;
+               /* Initial delta: minimum of 0.5 sec and t_gran/2 */
+               hctx->ccid3hctx_delta = TFRC_OPSYS_HALF_TIME_GRAN;
+
+               /* Set t_0 for initial packet */
                hctx->ccid3hctx_t_nom = now;
-               timeval_add_usecs(&hctx->ccid3hctx_t_nom,
-                                 hctx->ccid3hctx_t_ipi);
-               ccid3_calc_new_delta(hctx);
-               rc = 0;
                break;
        case TFRC_SSTATE_NO_FBACK:
        case TFRC_SSTATE_FBACK:
-               delay = (timeval_delta(&now, &hctx->ccid3hctx_t_nom) -
-                        hctx->ccid3hctx_delta);
-               delay /= -1000;
-               /* divide by -1000 is to convert to ms and get sign right */
-               rc = delay > 0 ? delay : 0;
-               break;
-       default:
-               printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
-                      __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state);
-               dump_stack();
-               rc = -EINVAL;
+               delay = timeval_delta(&hctx->ccid3hctx_t_nom, &now);
+               /*
+                *      Scheduling of packet transmissions [RFC 3448, 4.6]
+                *
+                * if (t_now > t_nom - delta)
+                *       // send the packet now
+                * else
+                *       // send the packet in (t_nom - t_now) milliseconds.
+                */
+               if (delay >= hctx->ccid3hctx_delta)
+                       return delay / 1000L;
                break;
+       case TFRC_SSTATE_TERM:
+               DCCP_BUG("Illegal %s state TERM, sk=%p", dccp_role(sk), sk);
+               return -EINVAL;
        }
 
-       /* Can we send? if so add options and add to packet history */
-       if (rc == 0) {
-               dp->dccps_hc_tx_insert_options = 1;
-               new_packet->dccphtx_ccval =
-                       DCCP_SKB_CB(skb)->dccpd_ccval =
-                               hctx->ccid3hctx_last_win_count;
-               timeval_add_usecs(&hctx->ccid3hctx_t_nom,
-                                 hctx->ccid3hctx_t_ipi);
-       }
-out:
-       return rc;
+       /* prepare to send now (add options etc.) */
+       dp->dccps_hc_tx_insert_options = 1;
+       new_packet->dccphtx_ccval = DCCP_SKB_CB(skb)->dccpd_ccval =
+                                   hctx->ccid3hctx_last_win_count;
+       timeval_add_usecs(&hctx->ccid3hctx_t_nom, hctx->ccid3hctx_t_ipi);
+
+       return 0;
 }
 
 static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, int len)
@@ -355,7 +342,7 @@ static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, int len)
        struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
        struct timeval now;
 
-       BUG_ON(hctx == NULL || hctx->ccid3hctx_state == TFRC_SSTATE_TERM);
+       BUG_ON(hctx == NULL);
 
        dccp_timestamp(sk, &now);
 
@@ -366,21 +353,18 @@ static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, int len)
 
                packet = dccp_tx_hist_head(&hctx->ccid3hctx_hist);
                if (unlikely(packet == NULL)) {
-                       LIMIT_NETDEBUG(KERN_WARNING "%s: packet doesn't "
-                                      "exists in history!\n", __FUNCTION__);
+                       DCCP_WARN("packet doesn't exist in history!\n");
                        return;
                }
                if (unlikely(packet->dccphtx_sent)) {
-                       LIMIT_NETDEBUG(KERN_WARNING "%s: no unsent packet in "
-                                      "history!\n", __FUNCTION__);
+                       DCCP_WARN("no unsent packet in history!\n");
                        return;
                }
                packet->dccphtx_tstamp = now;
                packet->dccphtx_seqno  = dp->dccps_gss;
                /*
                 * Check if win_count have changed
-                * Algorithm in "8.1. Window Counter Valuer" in
-                * draft-ietf-dccp-ccid3-11.txt
+                * Algorithm in "8.1. Window Counter Value" in RFC 4342.
                 */
                quarter_rtt = timeval_delta(&now, &hctx->ccid3hctx_t_last_win_count);
                if (likely(hctx->ccid3hctx_rtt > 8))
@@ -403,32 +387,6 @@ static void ccid3_hc_tx_packet_sent(struct sock *sk, int more, int len)
        } else
                ccid3_pr_debug("%s, sk=%p, seqno=%llu NOT inserted!\n",
                               dccp_role(sk), sk, dp->dccps_gss);
-
-       switch (hctx->ccid3hctx_state) {
-       case TFRC_SSTATE_NO_SENT:
-               /* if first wasn't pure ack */
-               if (len != 0)
-                       printk(KERN_CRIT "%s: %s, First packet sent is noted "
-                                        "as a data packet\n",
-                              __FUNCTION__, dccp_role(sk));
-               return;
-       case TFRC_SSTATE_NO_FBACK:
-       case TFRC_SSTATE_FBACK:
-               if (len > 0) {
-                       timeval_sub_usecs(&hctx->ccid3hctx_t_nom,
-                                 hctx->ccid3hctx_t_ipi);
-                       ccid3_calc_new_t_ipi(hctx);
-                       ccid3_calc_new_delta(hctx);
-                       timeval_add_usecs(&hctx->ccid3hctx_t_nom,
-                                         hctx->ccid3hctx_t_ipi);
-               }
-               break;
-       default:
-               printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
-                      __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state);
-               dump_stack();
-               break;
-       }
 }
 
 static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
@@ -444,7 +402,7 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
        u32 x_recv;
        u32 r_sample;
 
-       BUG_ON(hctx == NULL || hctx->ccid3hctx_state == TFRC_SSTATE_TERM);
+       BUG_ON(hctx == NULL);
 
        /* we are only interested in ACKs */
        if (!(DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK ||
@@ -458,9 +416,6 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
        pinv = opt_recv->ccid3or_loss_event_rate;
 
        switch (hctx->ccid3hctx_state) {
-       case TFRC_SSTATE_NO_SENT:
-               /* FIXME: what to do here? */
-               return;
        case TFRC_SSTATE_NO_FBACK:
        case TFRC_SSTATE_FBACK:
                /* Calculate new round trip sample by
@@ -469,11 +424,10 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
                packet = dccp_tx_hist_find_entry(&hctx->ccid3hctx_hist,
                                                 DCCP_SKB_CB(skb)->dccpd_ack_seq);
                if (unlikely(packet == NULL)) {
-                       LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, seqno "
-                                      "%llu(%s) does't exist in history!\n",
-                                      __FUNCTION__, dccp_role(sk), sk,
+                       DCCP_WARN("%s, sk=%p, seqno %llu(%s) does't exist "
+                                 "in history!\n",  dccp_role(sk), sk,
                            (unsigned long long)DCCP_SKB_CB(skb)->dccpd_ack_seq,
-                               dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type));
+                                 dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type));
                        return;
                }
 
@@ -481,9 +435,8 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
                dccp_timestamp(sk, &now);
                r_sample = timeval_delta(&now, &packet->dccphtx_tstamp);
                if (unlikely(r_sample <= t_elapsed))
-                       LIMIT_NETDEBUG(KERN_WARNING "%s: r_sample=%uus, "
-                                      "t_elapsed=%uus\n",
-                                      __FUNCTION__, r_sample, t_elapsed);
+                       DCCP_WARN("r_sample=%uus,t_elapsed=%uus\n",
+                                 r_sample, t_elapsed);
                else
                        r_sample -= t_elapsed;
 
@@ -506,10 +459,6 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
                               "r_sample=%us\n", dccp_role(sk), sk,
                               hctx->ccid3hctx_rtt, r_sample);
 
-               /* Update timeout interval */
-               hctx->ccid3hctx_t_rto = max_t(u32, 4 * hctx->ccid3hctx_rtt,
-                                             USEC_PER_SEC);
-
                /* Update receive rate */
                hctx->ccid3hctx_x_recv = x_recv;/* X_recv in bytes per sec */
 
@@ -529,33 +478,30 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
                /* unschedule no feedback timer */
                sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer);
 
-               /* Update sending rate */
+               /* Update sending rate (and likely t_ipi, t_nom, and delta) */
                ccid3_hc_tx_update_x(sk);
 
-               /* Update next send time */
-               timeval_sub_usecs(&hctx->ccid3hctx_t_nom,
-                                 hctx->ccid3hctx_t_ipi);
-               ccid3_calc_new_t_ipi(hctx);
-               timeval_add_usecs(&hctx->ccid3hctx_t_nom,
-                                 hctx->ccid3hctx_t_ipi);
-               ccid3_calc_new_delta(hctx);
-
                /* remove all packets older than the one acked from history */
                dccp_tx_hist_purge_older(ccid3_tx_hist,
                                         &hctx->ccid3hctx_hist, packet);
                /*
                 * As we have calculated new ipi, delta, t_nom it is possible that
-                * we now can send a packet, so wake up dccp_wait_for_ccids.
+                * we now can send a packet, so wake up dccp_wait_for_ccid
                 */
                sk->sk_write_space(sk);
 
+
+               /* Update timeout interval. We use the alternative variant of
+                * [RFC 3448, 3.1] which sets the upper bound of t_rto to one
+                * second, as it is suggested for TCP (see RFC 2988, 2.4). */
+               hctx->ccid3hctx_t_rto = max_t(u32, 4 * hctx->ccid3hctx_rtt,
+                                                  USEC_PER_SEC            );
                /*
                 * Schedule no feedback timer to expire in
-                * max(4 * R, 2 * s / X)
+                * max(4 * t_RTO, 2 * s/X)  =  max(4 * t_RTO, 2 * t_ipi)
+                * XXX This is non-standard, RFC 3448, 4.3 uses 4 * R
                 */
-               next_tmout = max(hctx->ccid3hctx_t_rto,
-                                2 * usecs_div(hctx->ccid3hctx_s,
-                                              hctx->ccid3hctx_x));
+               next_tmout = max(hctx->ccid3hctx_t_rto, 2*hctx->ccid3hctx_t_ipi);
                        
                ccid3_pr_debug("%s, sk=%p, Scheduled no feedback timer to "
                               "expire in %lu jiffies (%luus)\n",
@@ -563,15 +509,15 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
                               usecs_to_jiffies(next_tmout), next_tmout); 
 
                sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer, 
-                              jiffies + max_t(u32, 1, usecs_to_jiffies(next_tmout)));
+                                  jiffies + usecs_to_jiffies(next_tmout));
 
                /* set idle flag */
                hctx->ccid3hctx_idle = 1;   
                break;
-       default:
-               printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
-                      __FUNCTION__, dccp_role(sk), sk, hctx->ccid3hctx_state);
-               dump_stack();
+       case TFRC_SSTATE_NO_SENT:
+               DCCP_WARN("Illegal ACK received - no packet has been sent\n");
+               /* fall through */
+       case TFRC_SSTATE_TERM:          /* ignore feedback when closing */
                break;
        }
 }
@@ -611,9 +557,9 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
        switch (option) {
        case TFRC_OPT_LOSS_EVENT_RATE:
                if (unlikely(len != 4)) {
-                       LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, invalid "
-                                      "len for TFRC_OPT_LOSS_EVENT_RATE\n",
-                                      __FUNCTION__, dccp_role(sk), sk);
+                       DCCP_WARN("%s, sk=%p, invalid len %d "
+                                 "for TFRC_OPT_LOSS_EVENT_RATE\n",
+                                 dccp_role(sk), sk, len);
                        rc = -EINVAL;
                } else {
                        opt_recv->ccid3or_loss_event_rate = ntohl(*(__be32 *)value);
@@ -632,9 +578,9 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
                break;
        case TFRC_OPT_RECEIVE_RATE:
                if (unlikely(len != 4)) {
-                       LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, invalid "
-                                      "len for TFRC_OPT_RECEIVE_RATE\n",
-                                      __FUNCTION__, dccp_role(sk), sk);
+                       DCCP_WARN("%s, sk=%p, invalid len %d "
+                                 "for TFRC_OPT_RECEIVE_RATE\n",
+                                 dccp_role(sk), sk, len);
                        rc = -EINVAL;
                } else {
                        opt_recv->ccid3or_receive_rate = ntohl(*(__be32 *)value);
@@ -661,7 +607,6 @@ static int ccid3_hc_tx_init(struct ccid *ccid, struct sock *sk)
 
        /* Set transmission rate to 1 packet per second */
        hctx->ccid3hctx_x     = hctx->ccid3hctx_s;
-       hctx->ccid3hctx_t_rto = USEC_PER_SEC;
        hctx->ccid3hctx_state = TFRC_SSTATE_NO_SENT;
        INIT_LIST_HEAD(&hctx->ccid3hctx_hist);
 
@@ -689,14 +634,7 @@ static void ccid3_hc_tx_exit(struct sock *sk)
  * RX Half Connection methods
  */
 
-/* TFRC receiver states */
-enum ccid3_hc_rx_states {
-               TFRC_RSTATE_NO_DATA = 1,
-       TFRC_RSTATE_DATA,
-       TFRC_RSTATE_TERM    = 127,
-};
-
-#ifdef CCID3_DEBUG
+#ifdef CONFIG_IP_DCCP_CCID3_DEBUG
 static const char *ccid3_rx_state_name(enum ccid3_hc_rx_states state)
 {
        static char *ccid3_rx_state_names[] = {
@@ -744,18 +682,15 @@ static void ccid3_hc_rx_send_feedback(struct sock *sk)
                                                   delta);
        }
                break;
-       default:
-               printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
-                      __FUNCTION__, dccp_role(sk), sk, hcrx->ccid3hcrx_state);
-               dump_stack();
+       case TFRC_RSTATE_TERM:
+               DCCP_BUG("Illegal %s state TERM, sk=%p", dccp_role(sk), sk);
                return;
        }
 
        packet = dccp_rx_hist_find_data_packet(&hcrx->ccid3hcrx_hist);
        if (unlikely(packet == NULL)) {
-               LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, no data packet "
-                              "in history!\n",
-                              __FUNCTION__, dccp_role(sk), sk);
+               DCCP_WARN("%s, sk=%p, no data packet in history!\n",
+                         dccp_role(sk), sk);
                return;
        }
 
@@ -843,29 +778,29 @@ static u32 ccid3_hc_rx_calc_first_li(struct sock *sk)
        }
 
        if (unlikely(step == 0)) {
-               LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, packet history "
-                              "contains no data packets!\n",
-                              __FUNCTION__, dccp_role(sk), sk);
+               DCCP_WARN("%s, sk=%p, packet history has no data packets!\n",
+                         dccp_role(sk), sk);
                return ~0;
        }
 
        if (unlikely(interval == 0)) {
-               LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, Could not find a "
-                              "win_count interval > 0. Defaulting to 1\n",
-                              __FUNCTION__, dccp_role(sk), sk);
+               DCCP_WARN("%s, sk=%p, Could not find a win_count interval > 0."
+                         "Defaulting to 1\n", dccp_role(sk), sk);
                interval = 1;
        }
 found:
        if (!tail) {
-               LIMIT_NETDEBUG(KERN_WARNING "%s: tail is null\n",
-                  __FUNCTION__);
+               DCCP_CRIT("tail is null\n");
                return ~0;
        }
        rtt = timeval_delta(&tstamp, &tail->dccphrx_tstamp) * 4 / interval;
        ccid3_pr_debug("%s, sk=%p, approximated RTT to %uus\n",
                       dccp_role(sk), sk, rtt);
-       if (rtt == 0)
-               rtt = 1;
+
+       if (rtt == 0) {
+               DCCP_WARN("RTT==0, setting to 1\n");
+               rtt = 1;
+       }
 
        dccp_timestamp(sk, &tstamp);
        delta = timeval_delta(&tstamp, &hcrx->ccid3hcrx_tstamp_last_feedback);
@@ -879,9 +814,7 @@ found:
        tmp2 = (u32)tmp1;
 
        if (!tmp2) {
-               LIMIT_NETDEBUG(KERN_WARNING "tmp2 = 0 "
-                  "%s: x_recv = %u, rtt =%u\n",
-                  __FUNCTION__, x_recv, rtt);
+               DCCP_CRIT("tmp2 = 0, x_recv = %u, rtt =%u\n", x_recv, rtt);
                return ~0;
        }
 
@@ -900,7 +833,7 @@ found:
 static void ccid3_hc_rx_update_li(struct sock *sk, u64 seq_loss, u8 win_loss)
 {
        struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
-       struct dccp_li_hist_entry *next, *head;
+       struct dccp_li_hist_entry *head;
        u64 seq_temp;
 
        if (list_empty(&hcrx->ccid3hcrx_li_hist)) {
@@ -908,15 +841,15 @@ static void ccid3_hc_rx_update_li(struct sock *sk, u64 seq_loss, u8 win_loss)
                   &hcrx->ccid3hcrx_li_hist, seq_loss, win_loss))
                        return;
 
-               next = (struct dccp_li_hist_entry *)
-                  hcrx->ccid3hcrx_li_hist.next;
-               next->dccplih_interval = ccid3_hc_rx_calc_first_li(sk);
+               head = list_entry(hcrx->ccid3hcrx_li_hist.next,
+                  struct dccp_li_hist_entry, dccplih_node);
+               head->dccplih_interval = ccid3_hc_rx_calc_first_li(sk);
        } else {
                struct dccp_li_hist_entry *entry;
                struct list_head *tail;
 
-               head = (struct dccp_li_hist_entry *)
-                  hcrx->ccid3hcrx_li_hist.next;
+               head = list_entry(hcrx->ccid3hcrx_li_hist.next,
+                  struct dccp_li_hist_entry, dccplih_node);
                /* FIXME win count check removed as was wrong */
                /* should make this check with receive history */
                /* and compare there as per section 10.2 of RFC4342 */
@@ -927,8 +860,7 @@ static void ccid3_hc_rx_update_li(struct sock *sk, u64 seq_loss, u8 win_loss)
                entry = dccp_li_hist_entry_new(ccid3_li_hist, SLAB_ATOMIC);
 
                if (entry == NULL) {
-                       printk(KERN_CRIT "%s: out of memory\n",__FUNCTION__);
-                       dump_stack();
+                       DCCP_BUG("out of memory - can not allocate entry");
                        return;
                }
 
@@ -1003,13 +935,10 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
        const struct dccp_options_received *opt_recv;
        struct dccp_rx_hist_entry *packet;
        struct timeval now;
-       u8 win_count;
        u32 p_prev, rtt_prev, r_sample, t_elapsed;
        int loss;
 
-       BUG_ON(hcrx == NULL ||
-              !(hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA ||
-                hcrx->ccid3hcrx_state == TFRC_RSTATE_DATA));
+       BUG_ON(hcrx == NULL);
 
        opt_recv = &dccp_sk(sk)->dccps_options_received;
 
@@ -1027,9 +956,8 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
                t_elapsed = opt_recv->dccpor_elapsed_time * 10;
 
                if (unlikely(r_sample <= t_elapsed))
-                       LIMIT_NETDEBUG(KERN_WARNING "%s: r_sample=%uus, "
-                                      "t_elapsed=%uus\n",
-                                      __FUNCTION__, r_sample, t_elapsed);
+                       DCCP_WARN("r_sample=%uus, t_elapsed=%uus\n",
+                                 r_sample, t_elapsed);
                else
                        r_sample -= t_elapsed;
 
@@ -1053,14 +981,11 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
        packet = dccp_rx_hist_entry_new(ccid3_rx_hist, sk, opt_recv->dccpor_ndp,
                                        skb, SLAB_ATOMIC);
        if (unlikely(packet == NULL)) {
-               LIMIT_NETDEBUG(KERN_WARNING "%s: %s, sk=%p, Not enough mem to "
-                               "add rx packet to history, consider it lost!\n",
-                              __FUNCTION__, dccp_role(sk), sk);
+               DCCP_WARN("%s, sk=%p, Not enough mem to add rx packet "
+                         "to history, consider it lost!\n", dccp_role(sk), sk);
                return;
        }
 
-       win_count = packet->dccphrx_ccval;
-
        loss = ccid3_hc_rx_detect_loss(sk, packet);
 
        if (DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK)
@@ -1088,10 +1013,8 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
                        ccid3_hc_rx_send_feedback(sk);
                }
                return;
-       default:
-               printk(KERN_CRIT "%s: %s, sk=%p, Illegal state (%d)!\n",
-                      __FUNCTION__, dccp_role(sk), sk, hcrx->ccid3hcrx_state);
-               dump_stack();
+       case TFRC_RSTATE_TERM:
+               DCCP_BUG("Illegal %s state TERM, sk=%p", dccp_role(sk), sk);
                return;
        }
 
@@ -1108,10 +1031,8 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
                /* Scaling up by 1000000 as fixed decimal */
                if (i_mean != 0)
                        hcrx->ccid3hcrx_p = 1000000 / i_mean;
-       } else {
-               printk(KERN_CRIT "%s: empty loss hist\n",__FUNCTION__);
-               dump_stack();
-       }
+       } else
+               DCCP_BUG("empty loss history");
 
        if (hcrx->ccid3hcrx_p > p_prev) {
                ccid3_hc_rx_send_feedback(sk);
@@ -1240,7 +1161,7 @@ static int ccid3_hc_tx_getsockopt(struct sock *sk, const int optname, int len,
 }
 
 static struct ccid_operations ccid3 = {
-       .ccid_id                   = 3,
+       .ccid_id                   = DCCPC_CCID3,
        .ccid_name                 = "ccid3",
        .ccid_owner                = THIS_MODULE,
        .ccid_hc_tx_obj_size       = sizeof(struct ccid3_hc_tx_sock),
@@ -1262,8 +1183,10 @@ static struct ccid_operations ccid3 = {
        .ccid_hc_tx_getsockopt     = ccid3_hc_tx_getsockopt,
 };
  
+#ifdef CONFIG_IP_DCCP_CCID3_DEBUG
 module_param(ccid3_debug, int, 0444);
 MODULE_PARM_DESC(ccid3_debug, "Enable debug messages");
+#endif
 
 static __init int ccid3_module_init(void)
 {