38 #include <asm/unaligned.h>
40 #ifdef CONFIG_IP_DCCP_CCID3_DEBUG
41 static bool ccid3_debug;
42 #define ccid3_pr_debug(format, a...) DCCP_PR_DEBUG(ccid3_debug, format, ##a)
44 #define ccid3_pr_debug(format, a...)
50 #ifdef CONFIG_IP_DCCP_CCID3_DEBUG
53 static const char *
const ccid3_state_names[] = {
59 return ccid3_state_names[
state];
63 static void ccid3_hc_tx_set_state(
struct sock *
sk,
70 dccp_role(sk), sk, ccid3_tx_state_name(oldstate),
71 ccid3_tx_state_name(state));
85 static inline u64 rfc3390_initial_rate(
struct sock *sk)
90 return scaled_div(w_init << 6, hc->
tx_rtt);
103 hc->
tx_s, (
unsigned int)(hc->
tx_x >> 6));
110 return delta / hc->
tx_rtt;
137 if (ccid3_hc_tx_idle_rtt(hc, now) >= 2) {
138 min_rate = rfc3390_initial_rate(sk);
155 if (hc->
tx_x != old_x) {
157 "X_recv=%u\n", (
unsigned int)(old_x >> 6),
161 ccid3_update_send_interval(hc);
171 static inline void ccid3_hc_tx_update_s(
struct ccid3_hc_tx_sock *hc,
int len)
175 hc->
tx_s = tfrc_ewma(hc->
tx_s, len, 9);
177 if (hc->
tx_s != old_s)
178 ccid3_update_send_interval(hc);
185 static inline void ccid3_hc_tx_update_win_count(
struct ccid3_hc_tx_sock *hc,
191 if (quarter_rtts > 0) {
198 static void ccid3_hc_tx_no_feedback_timer(
unsigned long data)
200 struct sock *sk = (
struct sock *)data;
212 ccid3_tx_state_name(hc->tx_state));
231 ccid3_update_send_interval(hc);
251 ccid3_hc_tx_update_x(sk,
NULL);
254 (
unsigned long long)hc->
tx_x);
280 static int ccid3_hc_tx_send_packet(
struct sock *sk,
struct sk_buff *
skb)
311 if (dp->dccps_syn_rtt) {
313 hc->
tx_rtt = dp->dccps_syn_rtt;
314 hc->
tx_x = rfc3390_initial_rate(sk);
327 ccid3_update_send_interval(hc);
332 delay = ktime_us_delta(hc->
tx_t_nom, now);
345 ccid3_hc_tx_update_win_count(hc, now);
357 static void ccid3_hc_tx_packet_sent(
struct sock *sk,
unsigned int len)
361 ccid3_hc_tx_update_s(hc, len);
364 DCCP_CRIT(
"packet history - out of memory!");
367 static void ccid3_hc_tx_packet_recv(
struct sock *sk,
struct sk_buff *skb)
387 acked = tfrc_tx_hist_find_entry(hc->
tx_hist, dccp_hdr_ack_seq(skb));
408 hc->
tx_x = rfc3390_initial_rate(sk);
411 ccid3_update_send_interval(hc);
413 goto done_computing_x;
414 }
else if (hc->
tx_p == 0) {
418 goto done_computing_x;
425 ccid3_hc_tx_update_x(sk, &now);
429 "p=%u, X_calc=%u, X_recv=%u, X=%u\n",
433 (
unsigned int)(hc->
tx_x >> 6));
458 "expire in %lu jiffies (%luus)\n",
478 DCCP_WARN(
"%s(%p), invalid len %d for %u\n",
502 static int ccid3_hc_tx_init(
struct ccid *
ccid,
struct sock *sk)
509 ccid3_hc_tx_no_feedback_timer, (
unsigned long)sk);
513 static void ccid3_hc_tx_exit(
struct sock *sk)
523 info->
tcpi_rto = ccid3_hc_tx_sk(sk)->tx_t_rto;
524 info->
tcpi_rtt = ccid3_hc_tx_sk(sk)->tx_rtt;
527 static int ccid3_hc_tx_getsockopt(
struct sock *sk,
const int optname,
int len,
528 u32 __user *optval,
int __user *optlen)
536 if (len <
sizeof(tfrc))
538 memset(&tfrc, 0,
sizeof(tfrc));
539 tfrc.tfrctx_x = hc->
tx_x;
542 tfrc.tfrctx_rtt = hc->
tx_rtt;
543 tfrc.tfrctx_p = hc->
tx_p;
571 #ifdef CONFIG_IP_DCCP_CCID3_DEBUG
574 static const char *
const ccid3_rx_state_names[] = {
579 return ccid3_rx_state_names[
state];
583 static void ccid3_hc_rx_set_state(
struct sock *sk,
590 dccp_role(sk), sk, ccid3_rx_state_name(oldstate),
591 ccid3_rx_state_name(state));
593 hc->rx_state =
state;
596 static void ccid3_hc_rx_send_feedback(
struct sock *sk,
627 DCCP_BUG(
"delta (%ld) <= 0", (
long)delta);
635 ccid3_pr_debug(
"Interval %ldusec, X_recv=%u, 1/p=%u\n", (
long)delta,
646 static int ccid3_hc_rx_insert_options(
struct sock *sk,
struct sk_buff *skb)
654 if (dccp_packet_without_ack(skb))
658 pinv =
htonl(hc->rx_pinv);
661 &pinv,
sizeof(pinv)) ||
663 &x_recv,
sizeof(x_recv)))
679 static u32 ccid3_first_li(
struct sock *sk)
686 DCCP_WARN(
"No RTT estimate available, using fallback RTT\n");
695 DCCP_BUG(
"stored value of X_recv is zero");
702 fval = scaled_div32(fval, x_recv);
706 "loss rate=%u\n",
dccp_role(sk), sk, x_recv, p);
708 return p == 0 ? ~0
U : scaled_div(1, p);
711 static void ccid3_hc_rx_packet_recv(
struct sock *sk,
struct sk_buff *skb)
715 const u64 ndp = dccp_sk(sk)->dccps_options_received.dccpor_ndp;
716 const bool is_data_packet = dccp_data_packet(skb);
719 if (is_data_packet) {
736 if (is_data_packet) {
741 hc->
rx_s = tfrc_ewma(hc->
rx_s, payload, 9);
749 skb, ndp, ccid3_first_li, sk)) {
754 if (tfrc_rx_hist_loss_pending(&hc->
rx_hist))
763 if (!tfrc_lh_is_initialised(&hc->
rx_li_hist)) {
792 ccid3_hc_rx_send_feedback(sk, skb, do_feedback);
795 static int ccid3_hc_rx_init(
struct ccid *
ccid,
struct sock *sk)
804 static void ccid3_hc_rx_exit(
struct sock *sk)
819 static int ccid3_hc_rx_getsockopt(
struct sock *sk,
const int optname,
int len,
820 u32 __user *optval,
int __user *optlen)
848 .ccid_name =
"TCP-Friendly Rate Control",
850 .ccid_hc_tx_init = ccid3_hc_tx_init,
851 .ccid_hc_tx_exit = ccid3_hc_tx_exit,
852 .ccid_hc_tx_send_packet = ccid3_hc_tx_send_packet,
853 .ccid_hc_tx_packet_sent = ccid3_hc_tx_packet_sent,
854 .ccid_hc_tx_packet_recv = ccid3_hc_tx_packet_recv,
855 .ccid_hc_tx_parse_options = ccid3_hc_tx_parse_options,
857 .ccid_hc_rx_init = ccid3_hc_rx_init,
858 .ccid_hc_rx_exit = ccid3_hc_rx_exit,
859 .ccid_hc_rx_insert_options = ccid3_hc_rx_insert_options,
860 .ccid_hc_rx_packet_recv = ccid3_hc_rx_packet_recv,
861 .ccid_hc_rx_get_info = ccid3_hc_rx_get_info,
862 .ccid_hc_tx_get_info = ccid3_hc_tx_get_info,
863 .ccid_hc_rx_getsockopt = ccid3_hc_rx_getsockopt,
864 .ccid_hc_tx_getsockopt = ccid3_hc_tx_getsockopt,
867 #ifdef CONFIG_IP_DCCP_CCID3_DEBUG