aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@citi.umich.edu>2008-07-03 16:24:06 -0400
committerJ. Bruce Fields <bfields@citi.umich.edu>2008-07-03 16:24:06 -0400
commite86322f611eef95aafaf726fd3965e5b211f1985 (patch)
tree28547e26df4fc6ae671dc8cc6912a53717e4db08 /net/dccp
parentb001a1b6aa960949a24c2cdc28257dfcc9428d74 (diff)
parent8948896c9e098c6fd31a6a698a598a7cbd7fa40e (diff)
Merge branch 'for-bfields' of git://linux-nfs.org/~tomtucker/xprt-switch-2.6 into for-2.6.27
Diffstat (limited to 'net/dccp')
-rw-r--r--net/dccp/ackvec.c29
-rw-r--r--net/dccp/ccids/ccid3.c27
-rw-r--r--net/dccp/ccids/lib/tfrc.c8
-rw-r--r--net/dccp/ccids/lib/tfrc.h25
-rw-r--r--net/dccp/ccids/lib/tfrc_equation.c8
-rw-r--r--net/dccp/ipv4.c7
-rw-r--r--net/dccp/ipv6.c1
-rw-r--r--net/dccp/minisocks.c8
-rw-r--r--net/dccp/options.c4
-rw-r--r--net/dccp/output.c2
-rw-r--r--net/dccp/probe.c2
11 files changed, 48 insertions, 73 deletions
diff --git a/net/dccp/ackvec.c b/net/dccp/ackvec.c
index 6de4bd195d28..1e8be246ad15 100644
--- a/net/dccp/ackvec.c
+++ b/net/dccp/ackvec.c
@@ -290,12 +290,12 @@ int dccp_ackvec_add(struct dccp_ackvec *av, const struct sock *sk,
290 290
291 while (1) { 291 while (1) {
292 const u8 len = dccp_ackvec_len(av, index); 292 const u8 len = dccp_ackvec_len(av, index);
293 const u8 state = dccp_ackvec_state(av, index); 293 const u8 av_state = dccp_ackvec_state(av, index);
294 /* 294 /*
295 * valid packets not yet in av_buf have a reserved 295 * valid packets not yet in av_buf have a reserved
296 * entry, with a len equal to 0. 296 * entry, with a len equal to 0.
297 */ 297 */
298 if (state == DCCP_ACKVEC_STATE_NOT_RECEIVED && 298 if (av_state == DCCP_ACKVEC_STATE_NOT_RECEIVED &&
299 len == 0 && delta == 0) { /* Found our 299 len == 0 && delta == 0) { /* Found our
300 reserved seat! */ 300 reserved seat! */
301 dccp_pr_debug("Found %llu reserved seat!\n", 301 dccp_pr_debug("Found %llu reserved seat!\n",
@@ -325,31 +325,6 @@ out_duplicate:
325 return -EILSEQ; 325 return -EILSEQ;
326} 326}
327 327
328#ifdef CONFIG_IP_DCCP_DEBUG
329void dccp_ackvector_print(const u64 ackno, const unsigned char *vector, int len)
330{
331 dccp_pr_debug_cat("ACK vector len=%d, ackno=%llu |", len,
332 (unsigned long long)ackno);
333
334 while (len--) {
335 const u8 state = (*vector & DCCP_ACKVEC_STATE_MASK) >> 6;
336 const u8 rl = *vector & DCCP_ACKVEC_LEN_MASK;
337
338 dccp_pr_debug_cat("%d,%d|", state, rl);
339 ++vector;
340 }
341
342 dccp_pr_debug_cat("\n");
343}
344
345void dccp_ackvec_print(const struct dccp_ackvec *av)
346{
347 dccp_ackvector_print(av->av_buf_ackno,
348 av->av_buf + av->av_buf_head,
349 av->av_vec_len);
350}
351#endif
352
353static void dccp_ackvec_throw_record(struct dccp_ackvec *av, 328static void dccp_ackvec_throw_record(struct dccp_ackvec *av,
354 struct dccp_ackvec_record *avr) 329 struct dccp_ackvec_record *avr)
355{ 330{
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index cd61dea2eea1..a1929f33d703 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -159,8 +159,8 @@ static void ccid3_hc_tx_update_x(struct sock *sk, ktime_t *stamp)
159 } else if (ktime_us_delta(now, hctx->ccid3hctx_t_ld) 159 } else if (ktime_us_delta(now, hctx->ccid3hctx_t_ld)
160 - (s64)hctx->ccid3hctx_rtt >= 0) { 160 - (s64)hctx->ccid3hctx_rtt >= 0) {
161 161
162 hctx->ccid3hctx_x = 162 hctx->ccid3hctx_x = min(2 * hctx->ccid3hctx_x, min_rate);
163 max(min(2 * hctx->ccid3hctx_x, min_rate), 163 hctx->ccid3hctx_x = max(hctx->ccid3hctx_x,
164 scaled_div(((__u64)hctx->ccid3hctx_s) << 6, 164 scaled_div(((__u64)hctx->ccid3hctx_s) << 6,
165 hctx->ccid3hctx_rtt)); 165 hctx->ccid3hctx_rtt));
166 hctx->ccid3hctx_t_ld = now; 166 hctx->ccid3hctx_t_ld = now;
@@ -193,22 +193,17 @@ static inline void ccid3_hc_tx_update_s(struct ccid3_hc_tx_sock *hctx, int len)
193 193
194/* 194/*
195 * Update Window Counter using the algorithm from [RFC 4342, 8.1]. 195 * Update Window Counter using the algorithm from [RFC 4342, 8.1].
196 * The algorithm is not applicable if RTT < 4 microseconds. 196 * As elsewhere, RTT > 0 is assumed by using dccp_sample_rtt().
197 */ 197 */
198static inline void ccid3_hc_tx_update_win_count(struct ccid3_hc_tx_sock *hctx, 198static inline void ccid3_hc_tx_update_win_count(struct ccid3_hc_tx_sock *hctx,
199 ktime_t now) 199 ktime_t now)
200{ 200{
201 u32 quarter_rtts; 201 u32 delta = ktime_us_delta(now, hctx->ccid3hctx_t_last_win_count),
202 202 quarter_rtts = (4 * delta) / hctx->ccid3hctx_rtt;
203 if (unlikely(hctx->ccid3hctx_rtt < 4)) /* avoid divide-by-zero */
204 return;
205
206 quarter_rtts = ktime_us_delta(now, hctx->ccid3hctx_t_last_win_count);
207 quarter_rtts /= hctx->ccid3hctx_rtt / 4;
208 203
209 if (quarter_rtts > 0) { 204 if (quarter_rtts > 0) {
210 hctx->ccid3hctx_t_last_win_count = now; 205 hctx->ccid3hctx_t_last_win_count = now;
211 hctx->ccid3hctx_last_win_count += min_t(u32, quarter_rtts, 5); 206 hctx->ccid3hctx_last_win_count += min(quarter_rtts, 5U);
212 hctx->ccid3hctx_last_win_count &= 0xF; /* mod 16 */ 207 hctx->ccid3hctx_last_win_count &= 0xF; /* mod 16 */
213 } 208 }
214} 209}
@@ -334,8 +329,14 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
334 hctx->ccid3hctx_x = rfc3390_initial_rate(sk); 329 hctx->ccid3hctx_x = rfc3390_initial_rate(sk);
335 hctx->ccid3hctx_t_ld = now; 330 hctx->ccid3hctx_t_ld = now;
336 } else { 331 } else {
337 /* Sender does not have RTT sample: X_pps = 1 pkt/sec */ 332 /*
338 hctx->ccid3hctx_x = hctx->ccid3hctx_s; 333 * Sender does not have RTT sample:
334 * - set fallback RTT (RFC 4340, 3.4) since a RTT value
335 * is needed in several parts (e.g. window counter);
336 * - set sending rate X_pps = 1pps as per RFC 3448, 4.2.
337 */
338 hctx->ccid3hctx_rtt = DCCP_FALLBACK_RTT;
339 hctx->ccid3hctx_x = hctx->ccid3hctx_s;
339 hctx->ccid3hctx_x <<= 6; 340 hctx->ccid3hctx_x <<= 6;
340 } 341 }
341 ccid3_update_send_interval(hctx); 342 ccid3_update_send_interval(hctx);
diff --git a/net/dccp/ccids/lib/tfrc.c b/net/dccp/ccids/lib/tfrc.c
index d1dfbb8de64c..97ecec0a8e76 100644
--- a/net/dccp/ccids/lib/tfrc.c
+++ b/net/dccp/ccids/lib/tfrc.c
@@ -14,14 +14,6 @@ module_param(tfrc_debug, bool, 0444);
14MODULE_PARM_DESC(tfrc_debug, "Enable debug messages"); 14MODULE_PARM_DESC(tfrc_debug, "Enable debug messages");
15#endif 15#endif
16 16
17extern int tfrc_tx_packet_history_init(void);
18extern void tfrc_tx_packet_history_exit(void);
19extern int tfrc_rx_packet_history_init(void);
20extern void tfrc_rx_packet_history_exit(void);
21
22extern int tfrc_li_init(void);
23extern void tfrc_li_exit(void);
24
25static int __init tfrc_module_init(void) 17static int __init tfrc_module_init(void)
26{ 18{
27 int rc = tfrc_li_init(); 19 int rc = tfrc_li_init();
diff --git a/net/dccp/ccids/lib/tfrc.h b/net/dccp/ccids/lib/tfrc.h
index 1fb1187bbf1c..ed9857527acf 100644
--- a/net/dccp/ccids/lib/tfrc.h
+++ b/net/dccp/ccids/lib/tfrc.h
@@ -15,7 +15,7 @@
15 * (at your option) any later version. 15 * (at your option) any later version.
16 */ 16 */
17#include <linux/types.h> 17#include <linux/types.h>
18#include <asm/div64.h> 18#include <linux/math64.h>
19#include "../../dccp.h" 19#include "../../dccp.h"
20/* internal includes that this module exports: */ 20/* internal includes that this module exports: */
21#include "loss_interval.h" 21#include "loss_interval.h"
@@ -29,21 +29,19 @@ extern int tfrc_debug;
29#endif 29#endif
30 30
31/* integer-arithmetic divisions of type (a * 1000000)/b */ 31/* integer-arithmetic divisions of type (a * 1000000)/b */
32static inline u64 scaled_div(u64 a, u32 b) 32static inline u64 scaled_div(u64 a, u64 b)
33{ 33{
34 BUG_ON(b==0); 34 BUG_ON(b==0);
35 a *= 1000000; 35 return div64_u64(a * 1000000, b);
36 do_div(a, b);
37 return a;
38} 36}
39 37
40static inline u32 scaled_div32(u64 a, u32 b) 38static inline u32 scaled_div32(u64 a, u64 b)
41{ 39{
42 u64 result = scaled_div(a, b); 40 u64 result = scaled_div(a, b);
43 41
44 if (result > UINT_MAX) { 42 if (result > UINT_MAX) {
45 DCCP_CRIT("Overflow: a(%llu)/b(%u) > ~0U", 43 DCCP_CRIT("Overflow: %llu/%llu > UINT_MAX",
46 (unsigned long long)a, b); 44 (unsigned long long)a, (unsigned long long)b);
47 return UINT_MAX; 45 return UINT_MAX;
48 } 46 }
49 return result; 47 return result;
@@ -58,7 +56,14 @@ static inline u32 tfrc_ewma(const u32 avg, const u32 newval, const u8 weight)
58 return avg ? (weight * avg + (10 - weight) * newval) / 10 : newval; 56 return avg ? (weight * avg + (10 - weight) * newval) / 10 : newval;
59} 57}
60 58
61extern u32 tfrc_calc_x(u16 s, u32 R, u32 p); 59extern u32 tfrc_calc_x(u16 s, u32 R, u32 p);
62extern u32 tfrc_calc_x_reverse_lookup(u32 fvalue); 60extern u32 tfrc_calc_x_reverse_lookup(u32 fvalue);
63 61
62extern int tfrc_tx_packet_history_init(void);
63extern void tfrc_tx_packet_history_exit(void);
64extern int tfrc_rx_packet_history_init(void);
65extern void tfrc_rx_packet_history_exit(void);
66
67extern int tfrc_li_init(void);
68extern void tfrc_li_exit(void);
64#endif /* _TFRC_H_ */ 69#endif /* _TFRC_H_ */
diff --git a/net/dccp/ccids/lib/tfrc_equation.c b/net/dccp/ccids/lib/tfrc_equation.c
index e4e64b76c10c..2f20a29cffe4 100644
--- a/net/dccp/ccids/lib/tfrc_equation.c
+++ b/net/dccp/ccids/lib/tfrc_equation.c
@@ -661,7 +661,7 @@ u32 tfrc_calc_x(u16 s, u32 R, u32 p)
661 661
662EXPORT_SYMBOL_GPL(tfrc_calc_x); 662EXPORT_SYMBOL_GPL(tfrc_calc_x);
663 663
664/* 664/**
665 * tfrc_calc_x_reverse_lookup - try to find p given f(p) 665 * tfrc_calc_x_reverse_lookup - try to find p given f(p)
666 * 666 *
667 * @fvalue: function value to match, scaled by 1000000 667 * @fvalue: function value to match, scaled by 1000000
@@ -676,11 +676,11 @@ u32 tfrc_calc_x_reverse_lookup(u32 fvalue)
676 676
677 /* Error cases. */ 677 /* Error cases. */
678 if (fvalue < tfrc_calc_x_lookup[0][1]) { 678 if (fvalue < tfrc_calc_x_lookup[0][1]) {
679 DCCP_WARN("fvalue %d smaller than resolution\n", fvalue); 679 DCCP_WARN("fvalue %u smaller than resolution\n", fvalue);
680 return tfrc_calc_x_lookup[0][1]; 680 return TFRC_SMALLEST_P;
681 } 681 }
682 if (fvalue > tfrc_calc_x_lookup[TFRC_CALC_X_ARRSIZE - 1][0]) { 682 if (fvalue > tfrc_calc_x_lookup[TFRC_CALC_X_ARRSIZE - 1][0]) {
683 DCCP_WARN("fvalue %d exceeds bounds!\n", fvalue); 683 DCCP_WARN("fvalue %u exceeds bounds!\n", fvalue);
684 return 1000000; 684 return 1000000;
685 } 685 }
686 686
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c
index b348dd70c685..37d27bcb361f 100644
--- a/net/dccp/ipv4.c
+++ b/net/dccp/ipv4.c
@@ -589,7 +589,7 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
589 if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1) 589 if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1)
590 goto drop; 590 goto drop;
591 591
592 req = reqsk_alloc(&dccp_request_sock_ops); 592 req = inet_reqsk_alloc(&dccp_request_sock_ops);
593 if (req == NULL) 593 if (req == NULL)
594 goto drop; 594 goto drop;
595 595
@@ -605,7 +605,6 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
605 ireq = inet_rsk(req); 605 ireq = inet_rsk(req);
606 ireq->loc_addr = ip_hdr(skb)->daddr; 606 ireq->loc_addr = ip_hdr(skb)->daddr;
607 ireq->rmt_addr = ip_hdr(skb)->saddr; 607 ireq->rmt_addr = ip_hdr(skb)->saddr;
608 ireq->opt = NULL;
609 608
610 /* 609 /*
611 * Step 3: Process LISTEN state 610 * Step 3: Process LISTEN state
@@ -739,8 +738,8 @@ int dccp_invalid_packet(struct sk_buff *skb)
739 * If P.type is not Data, Ack, or DataAck and P.X == 0 (the packet 738 * If P.type is not Data, Ack, or DataAck and P.X == 0 (the packet
740 * has short sequence numbers), drop packet and return 739 * has short sequence numbers), drop packet and return
741 */ 740 */
742 if (dh->dccph_type >= DCCP_PKT_DATA && 741 if ((dh->dccph_type < DCCP_PKT_DATA ||
743 dh->dccph_type <= DCCP_PKT_DATAACK && dh->dccph_x == 0) { 742 dh->dccph_type > DCCP_PKT_DATAACK) && dh->dccph_x == 0) {
744 DCCP_WARN("P.type (%s) not Data || [Data]Ack, while P.X == 0\n", 743 DCCP_WARN("P.type (%s) not Data || [Data]Ack, while P.X == 0\n",
745 dccp_packet_name(dh->dccph_type)); 744 dccp_packet_name(dh->dccph_type));
746 return 1; 745 return 1;
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index 9b1129bb7ece..f7fe2a572d7b 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -421,7 +421,6 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
421 ireq6 = inet6_rsk(req); 421 ireq6 = inet6_rsk(req);
422 ipv6_addr_copy(&ireq6->rmt_addr, &ipv6_hdr(skb)->saddr); 422 ipv6_addr_copy(&ireq6->rmt_addr, &ipv6_hdr(skb)->saddr);
423 ipv6_addr_copy(&ireq6->loc_addr, &ipv6_hdr(skb)->daddr); 423 ipv6_addr_copy(&ireq6->loc_addr, &ipv6_hdr(skb)->daddr);
424 ireq6->pktopts = NULL;
425 424
426 if (ipv6_opt_accepted(sk, skb) || 425 if (ipv6_opt_accepted(sk, skb) ||
427 np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo || 426 np->rxopt.bits.rxinfo || np->rxopt.bits.rxoinfo ||
diff --git a/net/dccp/minisocks.c b/net/dccp/minisocks.c
index 33ad48321b08..66dca5bba858 100644
--- a/net/dccp/minisocks.c
+++ b/net/dccp/minisocks.c
@@ -165,12 +165,12 @@ out_free:
165 /* See dccp_v4_conn_request */ 165 /* See dccp_v4_conn_request */
166 newdmsk->dccpms_sequence_window = req->rcv_wnd; 166 newdmsk->dccpms_sequence_window = req->rcv_wnd;
167 167
168 newdp->dccps_gar = newdp->dccps_isr = dreq->dreq_isr; 168 newdp->dccps_gar = newdp->dccps_iss = dreq->dreq_iss;
169 dccp_update_gsr(newsk, dreq->dreq_isr);
170
171 newdp->dccps_iss = dreq->dreq_iss;
172 dccp_update_gss(newsk, dreq->dreq_iss); 169 dccp_update_gss(newsk, dreq->dreq_iss);
173 170
171 newdp->dccps_isr = dreq->dreq_isr;
172 dccp_update_gsr(newsk, dreq->dreq_isr);
173
174 /* 174 /*
175 * SWL and AWL are initially adjusted so that they are not less than 175 * SWL and AWL are initially adjusted so that they are not less than
176 * the initial Sequence Numbers received and sent, respectively: 176 * the initial Sequence Numbers received and sent, respectively:
diff --git a/net/dccp/options.c b/net/dccp/options.c
index d2a84a2fecee..43bc24e761d0 100644
--- a/net/dccp/options.c
+++ b/net/dccp/options.c
@@ -107,9 +107,11 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq,
107 * 107 *
108 * CCID-specific options are ignored during connection setup, as 108 * CCID-specific options are ignored during connection setup, as
109 * negotiation may still be in progress (see RFC 4340, 10.3). 109 * negotiation may still be in progress (see RFC 4340, 10.3).
110 * The same applies to Ack Vectors, as these depend on the CCID.
110 * 111 *
111 */ 112 */
112 if (dreq != NULL && opt >= 128) 113 if (dreq != NULL && (opt >= 128 ||
114 opt == DCCPO_ACK_VECTOR_0 || opt == DCCPO_ACK_VECTOR_1))
113 goto ignore_option; 115 goto ignore_option;
114 116
115 switch (opt) { 117 switch (opt) {
diff --git a/net/dccp/output.c b/net/dccp/output.c
index 1f8a9b64c083..fe20068c5d8e 100644
--- a/net/dccp/output.c
+++ b/net/dccp/output.c
@@ -508,6 +508,7 @@ void dccp_send_ack(struct sock *sk)
508 508
509EXPORT_SYMBOL_GPL(dccp_send_ack); 509EXPORT_SYMBOL_GPL(dccp_send_ack);
510 510
511#if 0
511/* FIXME: Is this still necessary (11.3) - currently nowhere used by DCCP. */ 512/* FIXME: Is this still necessary (11.3) - currently nowhere used by DCCP. */
512void dccp_send_delayed_ack(struct sock *sk) 513void dccp_send_delayed_ack(struct sock *sk)
513{ 514{
@@ -538,6 +539,7 @@ void dccp_send_delayed_ack(struct sock *sk)
538 icsk->icsk_ack.timeout = timeout; 539 icsk->icsk_ack.timeout = timeout;
539 sk_reset_timer(sk, &icsk->icsk_delack_timer, timeout); 540 sk_reset_timer(sk, &icsk->icsk_delack_timer, timeout);
540} 541}
542#endif
541 543
542void dccp_send_sync(struct sock *sk, const u64 ackno, 544void dccp_send_sync(struct sock *sk, const u64 ackno,
543 const enum dccp_pkt_type pkt_type) 545 const enum dccp_pkt_type pkt_type)
diff --git a/net/dccp/probe.c b/net/dccp/probe.c
index 0bcdc9250279..81368a7f5379 100644
--- a/net/dccp/probe.c
+++ b/net/dccp/probe.c
@@ -42,7 +42,7 @@ static int bufsize = 64 * 1024;
42 42
43static const char procname[] = "dccpprobe"; 43static const char procname[] = "dccpprobe";
44 44
45struct { 45static struct {
46 struct kfifo *fifo; 46 struct kfifo *fifo;
47 spinlock_t lock; 47 spinlock_t lock;
48 wait_queue_head_t wait; 48 wait_queue_head_t wait;