aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-09-21 19:00:40 -0400
committerDavid S. Miller <davem@davemloft.net>2010-09-21 19:00:40 -0400
commit98e684bd5c927cb94ff23fb6f1dd34dd346a19cf (patch)
tree4274d2b1d7c5314e1bb4d33197211aa8faa08687
parente254c274ae19888e5693ba6d32576ab03a8ae8a4 (diff)
parent536bb20b45dee3f9b77b0d250f8ed0733a5cb025 (diff)
Merge branch 'dccp' of git://eden-feed.erg.abdn.ac.uk/net-next-2.6
-rw-r--r--include/linux/dccp.h6
-rw-r--r--net/dccp/ccid.h46
-rw-r--r--net/dccp/ccids/ccid3.c78
-rw-r--r--net/dccp/ccids/ccid3.h9
-rw-r--r--net/dccp/ccids/lib/tfrc.h1
-rw-r--r--net/dccp/ccids/lib/tfrc_equation.c14
-rw-r--r--net/dccp/options.c25
7 files changed, 73 insertions, 106 deletions
diff --git a/include/linux/dccp.h b/include/linux/dccp.h
index 7434a8353e23..7187bd8a75f6 100644
--- a/include/linux/dccp.h
+++ b/include/linux/dccp.h
@@ -165,8 +165,10 @@ enum {
165 DCCPO_TIMESTAMP_ECHO = 42, 165 DCCPO_TIMESTAMP_ECHO = 42,
166 DCCPO_ELAPSED_TIME = 43, 166 DCCPO_ELAPSED_TIME = 43,
167 DCCPO_MAX = 45, 167 DCCPO_MAX = 45,
168 DCCPO_MIN_CCID_SPECIFIC = 128, 168 DCCPO_MIN_RX_CCID_SPECIFIC = 128, /* from sender to receiver */
169 DCCPO_MAX_CCID_SPECIFIC = 255, 169 DCCPO_MAX_RX_CCID_SPECIFIC = 191,
170 DCCPO_MIN_TX_CCID_SPECIFIC = 192, /* from receiver to sender */
171 DCCPO_MAX_TX_CCID_SPECIFIC = 255,
170}; 172};
171/* maximum size of a single TLV-encoded DCCP option (sans type/len bytes) */ 173/* maximum size of a single TLV-encoded DCCP option (sans type/len bytes) */
172#define DCCP_SINGLE_OPT_MAXLEN 253 174#define DCCP_SINGLE_OPT_MAXLEN 253
diff --git a/net/dccp/ccid.h b/net/dccp/ccid.h
index 6df6f8ac9636..6d16a9070ff0 100644
--- a/net/dccp/ccid.h
+++ b/net/dccp/ccid.h
@@ -62,18 +62,14 @@ struct ccid_operations {
62 void (*ccid_hc_tx_exit)(struct sock *sk); 62 void (*ccid_hc_tx_exit)(struct sock *sk);
63 void (*ccid_hc_rx_packet_recv)(struct sock *sk, 63 void (*ccid_hc_rx_packet_recv)(struct sock *sk,
64 struct sk_buff *skb); 64 struct sk_buff *skb);
65 int (*ccid_hc_rx_parse_options)(struct sock *sk, 65 int (*ccid_hc_rx_parse_options)(struct sock *sk, u8 pkt,
66 unsigned char option, 66 u8 opt, u8 *val, u8 len);
67 unsigned char len, u16 idx,
68 unsigned char* value);
69 int (*ccid_hc_rx_insert_options)(struct sock *sk, 67 int (*ccid_hc_rx_insert_options)(struct sock *sk,
70 struct sk_buff *skb); 68 struct sk_buff *skb);
71 void (*ccid_hc_tx_packet_recv)(struct sock *sk, 69 void (*ccid_hc_tx_packet_recv)(struct sock *sk,
72 struct sk_buff *skb); 70 struct sk_buff *skb);
73 int (*ccid_hc_tx_parse_options)(struct sock *sk, 71 int (*ccid_hc_tx_parse_options)(struct sock *sk, u8 pkt,
74 unsigned char option, 72 u8 opt, u8 *val, u8 len);
75 unsigned char len, u16 idx,
76 unsigned char* value);
77 int (*ccid_hc_tx_send_packet)(struct sock *sk, 73 int (*ccid_hc_tx_send_packet)(struct sock *sk,
78 struct sk_buff *skb); 74 struct sk_buff *skb);
79 void (*ccid_hc_tx_packet_sent)(struct sock *sk, 75 void (*ccid_hc_tx_packet_sent)(struct sock *sk,
@@ -168,27 +164,31 @@ static inline void ccid_hc_tx_packet_recv(struct ccid *ccid, struct sock *sk,
168 ccid->ccid_ops->ccid_hc_tx_packet_recv(sk, skb); 164 ccid->ccid_ops->ccid_hc_tx_packet_recv(sk, skb);
169} 165}
170 166
167/**
168 * ccid_hc_tx_parse_options - Parse CCID-specific options sent by the receiver
169 * @pkt: type of packet that @opt appears on (RFC 4340, 5.1)
170 * @opt: the CCID-specific option type (RFC 4340, 5.8 and 10.3)
171 * @val: value of @opt
172 * @len: length of @val in bytes
173 */
171static inline int ccid_hc_tx_parse_options(struct ccid *ccid, struct sock *sk, 174static inline int ccid_hc_tx_parse_options(struct ccid *ccid, struct sock *sk,
172 unsigned char option, 175 u8 pkt, u8 opt, u8 *val, u8 len)
173 unsigned char len, u16 idx,
174 unsigned char* value)
175{ 176{
176 int rc = 0; 177 if (ccid->ccid_ops->ccid_hc_tx_parse_options == NULL)
177 if (ccid->ccid_ops->ccid_hc_tx_parse_options != NULL) 178 return 0;
178 rc = ccid->ccid_ops->ccid_hc_tx_parse_options(sk, option, len, idx, 179 return ccid->ccid_ops->ccid_hc_tx_parse_options(sk, pkt, opt, val, len);
179 value);
180 return rc;
181} 180}
182 181
182/**
183 * ccid_hc_rx_parse_options - Parse CCID-specific options sent by the sender
184 * Arguments are analogous to ccid_hc_tx_parse_options()
185 */
183static inline int ccid_hc_rx_parse_options(struct ccid *ccid, struct sock *sk, 186static inline int ccid_hc_rx_parse_options(struct ccid *ccid, struct sock *sk,
184 unsigned char option, 187 u8 pkt, u8 opt, u8 *val, u8 len)
185 unsigned char len, u16 idx,
186 unsigned char* value)
187{ 188{
188 int rc = 0; 189 if (ccid->ccid_ops->ccid_hc_rx_parse_options == NULL)
189 if (ccid->ccid_ops->ccid_hc_rx_parse_options != NULL) 190 return 0;
190 rc = ccid->ccid_ops->ccid_hc_rx_parse_options(sk, option, len, idx, value); 191 return ccid->ccid_ops->ccid_hc_rx_parse_options(sk, pkt, opt, val, len);
191 return rc;
192} 192}
193 193
194static inline int ccid_hc_rx_insert_options(struct ccid *ccid, struct sock *sk, 194static inline int ccid_hc_rx_insert_options(struct ccid *ccid, struct sock *sk,
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index ce8059130070..c3f3a25bbd7a 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -54,7 +54,6 @@ static const char *ccid3_tx_state_name(enum ccid3_hc_tx_states state)
54 [TFRC_SSTATE_NO_SENT] = "NO_SENT", 54 [TFRC_SSTATE_NO_SENT] = "NO_SENT",
55 [TFRC_SSTATE_NO_FBACK] = "NO_FBACK", 55 [TFRC_SSTATE_NO_FBACK] = "NO_FBACK",
56 [TFRC_SSTATE_FBACK] = "FBACK", 56 [TFRC_SSTATE_FBACK] = "FBACK",
57 [TFRC_SSTATE_TERM] = "TERM",
58 }; 57 };
59 58
60 return ccid3_state_names[state]; 59 return ccid3_state_names[state];
@@ -208,10 +207,13 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
208 ccid3_pr_debug("%s(%p, state=%s) - entry\n", dccp_role(sk), sk, 207 ccid3_pr_debug("%s(%p, state=%s) - entry\n", dccp_role(sk), sk,
209 ccid3_tx_state_name(hc->tx_state)); 208 ccid3_tx_state_name(hc->tx_state));
210 209
210 /* Ignore and do not restart after leaving the established state */
211 if ((1 << sk->sk_state) & ~(DCCPF_OPEN | DCCPF_PARTOPEN))
212 goto out;
213
214 /* Reset feedback state to "no feedback received" */
211 if (hc->tx_state == TFRC_SSTATE_FBACK) 215 if (hc->tx_state == TFRC_SSTATE_FBACK)
212 ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK); 216 ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK);
213 else if (hc->tx_state != TFRC_SSTATE_NO_FBACK)
214 goto out;
215 217
216 /* 218 /*
217 * Determine new allowed sending rate X as per draft rfc3448bis-00, 4.4 219 * Determine new allowed sending rate X as per draft rfc3448bis-00, 4.4
@@ -287,8 +289,7 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
287 if (unlikely(skb->len == 0)) 289 if (unlikely(skb->len == 0))
288 return -EBADMSG; 290 return -EBADMSG;
289 291
290 switch (hc->tx_state) { 292 if (hc->tx_state == TFRC_SSTATE_NO_SENT) {
291 case TFRC_SSTATE_NO_SENT:
292 sk_reset_timer(sk, &hc->tx_no_feedback_timer, (jiffies + 293 sk_reset_timer(sk, &hc->tx_no_feedback_timer, (jiffies +
293 usecs_to_jiffies(TFRC_INITIAL_TIMEOUT))); 294 usecs_to_jiffies(TFRC_INITIAL_TIMEOUT)));
294 hc->tx_last_win_count = 0; 295 hc->tx_last_win_count = 0;
@@ -323,9 +324,8 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
323 ccid3_update_send_interval(hc); 324 ccid3_update_send_interval(hc);
324 325
325 ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK); 326 ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK);
326 break; 327
327 case TFRC_SSTATE_NO_FBACK: 328 } else {
328 case TFRC_SSTATE_FBACK:
329 delay = ktime_us_delta(hc->tx_t_nom, now); 329 delay = ktime_us_delta(hc->tx_t_nom, now);
330 ccid3_pr_debug("delay=%ld\n", (long)delay); 330 ccid3_pr_debug("delay=%ld\n", (long)delay);
331 /* 331 /*
@@ -340,10 +340,6 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
340 return (u32)delay / USEC_PER_MSEC; 340 return (u32)delay / USEC_PER_MSEC;
341 341
342 ccid3_hc_tx_update_win_count(hc, now); 342 ccid3_hc_tx_update_win_count(hc, now);
343 break;
344 case TFRC_SSTATE_TERM:
345 DCCP_BUG("%s(%p) - Illegal state TERM", dccp_role(sk), sk);
346 return -EINVAL;
347 } 343 }
348 344
349 /* prepare to send now (add options etc.) */ 345 /* prepare to send now (add options etc.) */
@@ -369,21 +365,15 @@ static void ccid3_hc_tx_packet_sent(struct sock *sk, int more,
369static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb) 365static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
370{ 366{
371 struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk); 367 struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk);
372 struct ccid3_options_received *opt_recv = &hc->tx_options_received;
373 struct tfrc_tx_hist_entry *acked; 368 struct tfrc_tx_hist_entry *acked;
374 ktime_t now; 369 ktime_t now;
375 unsigned long t_nfb; 370 unsigned long t_nfb;
376 u32 pinv, r_sample; 371 u32 r_sample;
377 372
378 /* we are only interested in ACKs */ 373 /* we are only interested in ACKs */
379 if (!(DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK || 374 if (!(DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_ACK ||
380 DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_DATAACK)) 375 DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_DATAACK))
381 return; 376 return;
382 /* ... and only in the established state */
383 if (hc->tx_state != TFRC_SSTATE_FBACK &&
384 hc->tx_state != TFRC_SSTATE_NO_FBACK)
385 return;
386
387 /* 377 /*
388 * Locate the acknowledged packet in the TX history. 378 * Locate the acknowledged packet in the TX history.
389 * 379 *
@@ -403,17 +393,6 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
403 r_sample = dccp_sample_rtt(sk, ktime_us_delta(now, acked->stamp)); 393 r_sample = dccp_sample_rtt(sk, ktime_us_delta(now, acked->stamp));
404 hc->tx_rtt = tfrc_ewma(hc->tx_rtt, r_sample, 9); 394 hc->tx_rtt = tfrc_ewma(hc->tx_rtt, r_sample, 9);
405 395
406 /* Update receive rate in units of 64 * bytes/second */
407 hc->tx_x_recv = opt_recv->ccid3or_receive_rate;
408 hc->tx_x_recv <<= 6;
409
410 /* Update loss event rate (which is scaled by 1e6) */
411 pinv = opt_recv->ccid3or_loss_event_rate;
412 if (pinv == ~0U || pinv == 0) /* see RFC 4342, 8.5 */
413 hc->tx_p = 0;
414 else /* can not exceed 100% */
415 hc->tx_p = scaled_div(1, pinv);
416
417 /* 396 /*
418 * Update allowed sending rate X as per draft rfc3448bis-00, 4.2/3 397 * Update allowed sending rate X as per draft rfc3448bis-00, 4.2/3
419 */ 398 */
@@ -481,30 +460,36 @@ done_computing_x:
481 jiffies + usecs_to_jiffies(t_nfb)); 460 jiffies + usecs_to_jiffies(t_nfb));
482} 461}
483 462
484static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option, 463static int ccid3_hc_tx_parse_options(struct sock *sk, u8 packet_type,
485 unsigned char len, u16 idx, 464 u8 option, u8 *optval, u8 optlen)
486 unsigned char *value)
487{ 465{
488 struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk); 466 struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk);
489 struct ccid3_options_received *opt_recv = &hc->tx_options_received;
490 __be32 opt_val; 467 __be32 opt_val;
491 468
492 switch (option) { 469 switch (option) {
493 case TFRC_OPT_RECEIVE_RATE: 470 case TFRC_OPT_RECEIVE_RATE:
494 case TFRC_OPT_LOSS_EVENT_RATE: 471 case TFRC_OPT_LOSS_EVENT_RATE:
495 if (unlikely(len != 4)) { 472 /* Must be ignored on Data packets, cf. RFC 4342 8.3 and 8.5 */
473 if (packet_type == DCCP_PKT_DATA)
474 break;
475 if (unlikely(optlen != 4)) {
496 DCCP_WARN("%s(%p), invalid len %d for %u\n", 476 DCCP_WARN("%s(%p), invalid len %d for %u\n",
497 dccp_role(sk), sk, len, option); 477 dccp_role(sk), sk, optlen, option);
498 return -EINVAL; 478 return -EINVAL;
499 } 479 }
500 opt_val = ntohl(get_unaligned((__be32 *)value)); 480 opt_val = ntohl(get_unaligned((__be32 *)optval));
501 481
502 if (option == TFRC_OPT_RECEIVE_RATE) { 482 if (option == TFRC_OPT_RECEIVE_RATE) {
503 opt_recv->ccid3or_receive_rate = opt_val; 483 /* Receive Rate is kept in units of 64 bytes/second */
484 hc->tx_x_recv = opt_val;
485 hc->tx_x_recv <<= 6;
486
504 ccid3_pr_debug("%s(%p), RECEIVE_RATE=%u\n", 487 ccid3_pr_debug("%s(%p), RECEIVE_RATE=%u\n",
505 dccp_role(sk), sk, opt_val); 488 dccp_role(sk), sk, opt_val);
506 } else { 489 } else {
507 opt_recv->ccid3or_loss_event_rate = opt_val; 490 /* Update the fixpoint Loss Event Rate fraction */
491 hc->tx_p = tfrc_invert_loss_event_rate(opt_val);
492
508 ccid3_pr_debug("%s(%p), LOSS_EVENT_RATE=%u\n", 493 ccid3_pr_debug("%s(%p), LOSS_EVENT_RATE=%u\n",
509 dccp_role(sk), sk, opt_val); 494 dccp_role(sk), sk, opt_val);
510 } 495 }
@@ -527,9 +512,7 @@ static void ccid3_hc_tx_exit(struct sock *sk)
527{ 512{
528 struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk); 513 struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk);
529 514
530 ccid3_hc_tx_set_state(sk, TFRC_SSTATE_TERM);
531 sk_stop_timer(sk, &hc->tx_no_feedback_timer); 515 sk_stop_timer(sk, &hc->tx_no_feedback_timer);
532
533 tfrc_tx_hist_purge(&hc->tx_hist); 516 tfrc_tx_hist_purge(&hc->tx_hist);
534} 517}
535 518
@@ -588,7 +571,6 @@ static const char *ccid3_rx_state_name(enum ccid3_hc_rx_states state)
588 static const char *const ccid3_rx_state_names[] = { 571 static const char *const ccid3_rx_state_names[] = {
589 [TFRC_RSTATE_NO_DATA] = "NO_DATA", 572 [TFRC_RSTATE_NO_DATA] = "NO_DATA",
590 [TFRC_RSTATE_DATA] = "DATA", 573 [TFRC_RSTATE_DATA] = "DATA",
591 [TFRC_RSTATE_TERM] = "TERM",
592 }; 574 };
593 575
594 return ccid3_rx_state_names[state]; 576 return ccid3_rx_state_names[state];
@@ -614,14 +596,9 @@ static void ccid3_hc_rx_send_feedback(struct sock *sk,
614{ 596{
615 struct ccid3_hc_rx_sock *hc = ccid3_hc_rx_sk(sk); 597 struct ccid3_hc_rx_sock *hc = ccid3_hc_rx_sk(sk);
616 struct dccp_sock *dp = dccp_sk(sk); 598 struct dccp_sock *dp = dccp_sk(sk);
617 ktime_t now; 599 ktime_t now = ktime_get_real();
618 s64 delta = 0; 600 s64 delta = 0;
619 601
620 if (unlikely(hc->rx_state == TFRC_RSTATE_TERM))
621 return;
622
623 now = ktime_get_real();
624
625 switch (fbtype) { 602 switch (fbtype) {
626 case CCID3_FBACK_INITIAL: 603 case CCID3_FBACK_INITIAL:
627 hc->rx_x_recv = 0; 604 hc->rx_x_recv = 0;
@@ -825,8 +802,6 @@ static void ccid3_hc_rx_exit(struct sock *sk)
825{ 802{
826 struct ccid3_hc_rx_sock *hc = ccid3_hc_rx_sk(sk); 803 struct ccid3_hc_rx_sock *hc = ccid3_hc_rx_sk(sk);
827 804
828 ccid3_hc_rx_set_state(sk, TFRC_RSTATE_TERM);
829
830 tfrc_rx_hist_purge(&hc->rx_hist); 805 tfrc_rx_hist_purge(&hc->rx_hist);
831 tfrc_lh_cleanup(&hc->rx_li_hist); 806 tfrc_lh_cleanup(&hc->rx_li_hist);
832} 807}
@@ -851,8 +826,7 @@ static int ccid3_hc_rx_getsockopt(struct sock *sk, const int optname, int len,
851 return -EINVAL; 826 return -EINVAL;
852 rx_info.tfrcrx_x_recv = hc->rx_x_recv; 827 rx_info.tfrcrx_x_recv = hc->rx_x_recv;
853 rx_info.tfrcrx_rtt = hc->rx_rtt; 828 rx_info.tfrcrx_rtt = hc->rx_rtt;
854 rx_info.tfrcrx_p = hc->rx_pinv == 0 ? ~0U : 829 rx_info.tfrcrx_p = tfrc_invert_loss_event_rate(hc->rx_pinv);
855 scaled_div(1, hc->rx_pinv);
856 len = sizeof(rx_info); 830 len = sizeof(rx_info);
857 val = &rx_info; 831 val = &rx_info;
858 break; 832 break;
diff --git a/net/dccp/ccids/ccid3.h b/net/dccp/ccids/ccid3.h
index 9eb90b863abd..1a9933c29672 100644
--- a/net/dccp/ccids/ccid3.h
+++ b/net/dccp/ccids/ccid3.h
@@ -67,17 +67,11 @@ enum ccid3_options {
67 TFRC_OPT_RECEIVE_RATE = 194, 67 TFRC_OPT_RECEIVE_RATE = 194,
68}; 68};
69 69
70struct ccid3_options_received {
71 u32 ccid3or_loss_event_rate;
72 u32 ccid3or_receive_rate;
73};
74
75/* TFRC sender states */ 70/* TFRC sender states */
76enum ccid3_hc_tx_states { 71enum ccid3_hc_tx_states {
77 TFRC_SSTATE_NO_SENT = 1, 72 TFRC_SSTATE_NO_SENT = 1,
78 TFRC_SSTATE_NO_FBACK, 73 TFRC_SSTATE_NO_FBACK,
79 TFRC_SSTATE_FBACK, 74 TFRC_SSTATE_FBACK,
80 TFRC_SSTATE_TERM,
81}; 75};
82 76
83/** 77/**
@@ -98,7 +92,6 @@ enum ccid3_hc_tx_states {
98 * @tx_t_ld: Time last doubled during slow start 92 * @tx_t_ld: Time last doubled during slow start
99 * @tx_t_nom: Nominal send time of next packet 93 * @tx_t_nom: Nominal send time of next packet
100 * @tx_hist: Packet history 94 * @tx_hist: Packet history
101 * @tx_options_received: Parsed set of retrieved options
102 */ 95 */
103struct ccid3_hc_tx_sock { 96struct ccid3_hc_tx_sock {
104 u64 tx_x; 97 u64 tx_x;
@@ -116,7 +109,6 @@ struct ccid3_hc_tx_sock {
116 ktime_t tx_t_ld; 109 ktime_t tx_t_ld;
117 ktime_t tx_t_nom; 110 ktime_t tx_t_nom;
118 struct tfrc_tx_hist_entry *tx_hist; 111 struct tfrc_tx_hist_entry *tx_hist;
119 struct ccid3_options_received tx_options_received;
120}; 112};
121 113
122static inline struct ccid3_hc_tx_sock *ccid3_hc_tx_sk(const struct sock *sk) 114static inline struct ccid3_hc_tx_sock *ccid3_hc_tx_sk(const struct sock *sk)
@@ -130,7 +122,6 @@ static inline struct ccid3_hc_tx_sock *ccid3_hc_tx_sk(const struct sock *sk)
130enum ccid3_hc_rx_states { 122enum ccid3_hc_rx_states {
131 TFRC_RSTATE_NO_DATA = 1, 123 TFRC_RSTATE_NO_DATA = 1,
132 TFRC_RSTATE_DATA, 124 TFRC_RSTATE_DATA,
133 TFRC_RSTATE_TERM = 127,
134}; 125};
135 126
136/** 127/**
diff --git a/net/dccp/ccids/lib/tfrc.h b/net/dccp/ccids/lib/tfrc.h
index 01bb48e96c2e..f8ee3f549770 100644
--- a/net/dccp/ccids/lib/tfrc.h
+++ b/net/dccp/ccids/lib/tfrc.h
@@ -57,6 +57,7 @@ static inline u32 tfrc_ewma(const u32 avg, const u32 newval, const u8 weight)
57 57
58extern u32 tfrc_calc_x(u16 s, u32 R, u32 p); 58extern u32 tfrc_calc_x(u16 s, u32 R, u32 p);
59extern u32 tfrc_calc_x_reverse_lookup(u32 fvalue); 59extern u32 tfrc_calc_x_reverse_lookup(u32 fvalue);
60extern u32 tfrc_invert_loss_event_rate(u32 loss_event_rate);
60 61
61extern int tfrc_tx_packet_history_init(void); 62extern int tfrc_tx_packet_history_init(void);
62extern void tfrc_tx_packet_history_exit(void); 63extern void tfrc_tx_packet_history_exit(void);
diff --git a/net/dccp/ccids/lib/tfrc_equation.c b/net/dccp/ccids/lib/tfrc_equation.c
index 22ca1cf0eb55..a052a4377e26 100644
--- a/net/dccp/ccids/lib/tfrc_equation.c
+++ b/net/dccp/ccids/lib/tfrc_equation.c
@@ -687,3 +687,17 @@ u32 tfrc_calc_x_reverse_lookup(u32 fvalue)
687 index = tfrc_binsearch(fvalue, 0); 687 index = tfrc_binsearch(fvalue, 0);
688 return (index + 1) * 1000000 / TFRC_CALC_X_ARRSIZE; 688 return (index + 1) * 1000000 / TFRC_CALC_X_ARRSIZE;
689} 689}
690
691/**
692 * tfrc_invert_loss_event_rate - Compute p so that 10^6 corresponds to 100%
693 * When @loss_event_rate is large, there is a chance that p is truncated to 0.
694 * To avoid re-entering slow-start in that case, we set p = TFRC_SMALLEST_P > 0.
695 */
696u32 tfrc_invert_loss_event_rate(u32 loss_event_rate)
697{
698 if (loss_event_rate == UINT_MAX) /* see RFC 4342, 8.5 */
699 return 0;
700 if (unlikely(loss_event_rate == 0)) /* map 1/0 into 100% */
701 return 1000000;
702 return max_t(u32, scaled_div(1, loss_event_rate), TFRC_SMALLEST_P);
703}
diff --git a/net/dccp/options.c b/net/dccp/options.c
index bfda087bd90d..92718511eac5 100644
--- a/net/dccp/options.c
+++ b/net/dccp/options.c
@@ -96,18 +96,11 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq,
96 } 96 }
97 97
98 /* 98 /*
99 * CCID-Specific Options (from RFC 4340, sec. 10.3):
100 *
101 * Option numbers 128 through 191 are for options sent from the
102 * HC-Sender to the HC-Receiver; option numbers 192 through 255
103 * are for options sent from the HC-Receiver to the HC-Sender.
104 *
105 * CCID-specific options are ignored during connection setup, as 99 * CCID-specific options are ignored during connection setup, as
106 * negotiation may still be in progress (see RFC 4340, 10.3). 100 * negotiation may still be in progress (see RFC 4340, 10.3).
107 * The same applies to Ack Vectors, as these depend on the CCID. 101 * The same applies to Ack Vectors, as these depend on the CCID.
108 *
109 */ 102 */
110 if (dreq != NULL && (opt >= 128 || 103 if (dreq != NULL && (opt >= DCCPO_MIN_RX_CCID_SPECIFIC ||
111 opt == DCCPO_ACK_VECTOR_0 || opt == DCCPO_ACK_VECTOR_1)) 104 opt == DCCPO_ACK_VECTOR_0 || opt == DCCPO_ACK_VECTOR_1))
112 goto ignore_option; 105 goto ignore_option;
113 106
@@ -226,23 +219,15 @@ int dccp_parse_options(struct sock *sk, struct dccp_request_sock *dreq,
226 dccp_pr_debug("%s rx opt: ELAPSED_TIME=%d\n", 219 dccp_pr_debug("%s rx opt: ELAPSED_TIME=%d\n",
227 dccp_role(sk), elapsed_time); 220 dccp_role(sk), elapsed_time);
228 break; 221 break;
229 case 128 ... 191: { 222 case DCCPO_MIN_RX_CCID_SPECIFIC ... DCCPO_MAX_RX_CCID_SPECIFIC:
230 const u16 idx = value - options;
231
232 if (ccid_hc_rx_parse_options(dp->dccps_hc_rx_ccid, sk, 223 if (ccid_hc_rx_parse_options(dp->dccps_hc_rx_ccid, sk,
233 opt, len, idx, 224 pkt_type, opt, value, len))
234 value) != 0)
235 goto out_invalid_option; 225 goto out_invalid_option;
236 }
237 break; 226 break;
238 case 192 ... 255: { 227 case DCCPO_MIN_TX_CCID_SPECIFIC ... DCCPO_MAX_TX_CCID_SPECIFIC:
239 const u16 idx = value - options;
240
241 if (ccid_hc_tx_parse_options(dp->dccps_hc_tx_ccid, sk, 228 if (ccid_hc_tx_parse_options(dp->dccps_hc_tx_ccid, sk,
242 opt, len, idx, 229 pkt_type, opt, value, len))
243 value) != 0)
244 goto out_invalid_option; 230 goto out_invalid_option;
245 }
246 break; 231 break;
247 default: 232 default:
248 DCCP_CRIT("DCCP(%p): option %d(len=%d) not " 233 DCCP_CRIT("DCCP(%p): option %d(len=%d) not "