Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1815 commits) mac80211: fix reorder buffer release iwmc3200wifi: Enable wimax core through module parameter iwmc3200wifi: Add wifi-wimax coexistence mode as a module parameter iwmc3200wifi: Coex table command does not expect a response iwmc3200wifi: Update wiwi priority table iwlwifi: driver version track kernel version iwlwifi: indicate uCode type when fail dump error/event log iwl3945: remove duplicated event logging code b43: fix two warnings ipw2100: fix rebooting hang with driver loaded cfg80211: indent regulatory messages with spaces iwmc3200wifi: fix NULL pointer dereference in pmkid update mac80211: Fix TX status reporting for injected data frames ath9k: enable 2GHz band only if the device supports it airo: Fix integer overflow warning rt2x00: Fix padding bug on L2PAD devices. WE: Fix set events not propagated b43legacy: avoid PPC fault during resume b43: avoid PPC fault during resume tcp: fix a timewait refcnt race ... Fix up conflicts due to sysctl cleanups (dead sysctl_check code and CTL_UNNUMBERED removed) in kernel/sysctl_check.c net/ipv4/sysctl_net_ipv4.c net/ipv6/addrconf.c net/sctp/sysctl.c
This commit is contained in:
@@ -33,20 +33,20 @@
|
||||
static int ccid2_debug;
|
||||
#define ccid2_pr_debug(format, a...) DCCP_PR_DEBUG(ccid2_debug, format, ##a)
|
||||
|
||||
static void ccid2_hc_tx_check_sanity(const struct ccid2_hc_tx_sock *hctx)
|
||||
static void ccid2_hc_tx_check_sanity(const struct ccid2_hc_tx_sock *hc)
|
||||
{
|
||||
int len = 0;
|
||||
int pipe = 0;
|
||||
struct ccid2_seq *seqp = hctx->ccid2hctx_seqh;
|
||||
struct ccid2_seq *seqp = hc->tx_seqh;
|
||||
|
||||
/* there is data in the chain */
|
||||
if (seqp != hctx->ccid2hctx_seqt) {
|
||||
if (seqp != hc->tx_seqt) {
|
||||
seqp = seqp->ccid2s_prev;
|
||||
len++;
|
||||
if (!seqp->ccid2s_acked)
|
||||
pipe++;
|
||||
|
||||
while (seqp != hctx->ccid2hctx_seqt) {
|
||||
while (seqp != hc->tx_seqt) {
|
||||
struct ccid2_seq *prev = seqp->ccid2s_prev;
|
||||
|
||||
len++;
|
||||
@@ -63,30 +63,30 @@ static void ccid2_hc_tx_check_sanity(const struct ccid2_hc_tx_sock *hctx)
|
||||
}
|
||||
}
|
||||
|
||||
BUG_ON(pipe != hctx->ccid2hctx_pipe);
|
||||
BUG_ON(pipe != hc->tx_pipe);
|
||||
ccid2_pr_debug("len of chain=%d\n", len);
|
||||
|
||||
do {
|
||||
seqp = seqp->ccid2s_prev;
|
||||
len++;
|
||||
} while (seqp != hctx->ccid2hctx_seqh);
|
||||
} while (seqp != hc->tx_seqh);
|
||||
|
||||
ccid2_pr_debug("total len=%d\n", len);
|
||||
BUG_ON(len != hctx->ccid2hctx_seqbufc * CCID2_SEQBUF_LEN);
|
||||
BUG_ON(len != hc->tx_seqbufc * CCID2_SEQBUF_LEN);
|
||||
}
|
||||
#else
|
||||
#define ccid2_pr_debug(format, a...)
|
||||
#define ccid2_hc_tx_check_sanity(hctx)
|
||||
#define ccid2_hc_tx_check_sanity(hc)
|
||||
#endif
|
||||
|
||||
static int ccid2_hc_tx_alloc_seq(struct ccid2_hc_tx_sock *hctx)
|
||||
static int ccid2_hc_tx_alloc_seq(struct ccid2_hc_tx_sock *hc)
|
||||
{
|
||||
struct ccid2_seq *seqp;
|
||||
int i;
|
||||
|
||||
/* check if we have space to preserve the pointer to the buffer */
|
||||
if (hctx->ccid2hctx_seqbufc >= (sizeof(hctx->ccid2hctx_seqbuf) /
|
||||
sizeof(struct ccid2_seq*)))
|
||||
if (hc->tx_seqbufc >= (sizeof(hc->tx_seqbuf) /
|
||||
sizeof(struct ccid2_seq *)))
|
||||
return -ENOMEM;
|
||||
|
||||
/* allocate buffer and initialize linked list */
|
||||
@@ -102,29 +102,29 @@ static int ccid2_hc_tx_alloc_seq(struct ccid2_hc_tx_sock *hctx)
|
||||
seqp->ccid2s_prev = &seqp[CCID2_SEQBUF_LEN - 1];
|
||||
|
||||
/* This is the first allocation. Initiate the head and tail. */
|
||||
if (hctx->ccid2hctx_seqbufc == 0)
|
||||
hctx->ccid2hctx_seqh = hctx->ccid2hctx_seqt = seqp;
|
||||
if (hc->tx_seqbufc == 0)
|
||||
hc->tx_seqh = hc->tx_seqt = seqp;
|
||||
else {
|
||||
/* link the existing list with the one we just created */
|
||||
hctx->ccid2hctx_seqh->ccid2s_next = seqp;
|
||||
seqp->ccid2s_prev = hctx->ccid2hctx_seqh;
|
||||
hc->tx_seqh->ccid2s_next = seqp;
|
||||
seqp->ccid2s_prev = hc->tx_seqh;
|
||||
|
||||
hctx->ccid2hctx_seqt->ccid2s_prev = &seqp[CCID2_SEQBUF_LEN - 1];
|
||||
seqp[CCID2_SEQBUF_LEN - 1].ccid2s_next = hctx->ccid2hctx_seqt;
|
||||
hc->tx_seqt->ccid2s_prev = &seqp[CCID2_SEQBUF_LEN - 1];
|
||||
seqp[CCID2_SEQBUF_LEN - 1].ccid2s_next = hc->tx_seqt;
|
||||
}
|
||||
|
||||
/* store the original pointer to the buffer so we can free it */
|
||||
hctx->ccid2hctx_seqbuf[hctx->ccid2hctx_seqbufc] = seqp;
|
||||
hctx->ccid2hctx_seqbufc++;
|
||||
hc->tx_seqbuf[hc->tx_seqbufc] = seqp;
|
||||
hc->tx_seqbufc++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ccid2_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
|
||||
struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk);
|
||||
|
||||
if (hctx->ccid2hctx_pipe < hctx->ccid2hctx_cwnd)
|
||||
if (hc->tx_pipe < hc->tx_cwnd)
|
||||
return 0;
|
||||
|
||||
return 1; /* XXX CCID should dequeue when ready instead of polling */
|
||||
@@ -133,7 +133,7 @@ static int ccid2_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
|
||||
static void ccid2_change_l_ack_ratio(struct sock *sk, u32 val)
|
||||
{
|
||||
struct dccp_sock *dp = dccp_sk(sk);
|
||||
u32 max_ratio = DIV_ROUND_UP(ccid2_hc_tx_sk(sk)->ccid2hctx_cwnd, 2);
|
||||
u32 max_ratio = DIV_ROUND_UP(ccid2_hc_tx_sk(sk)->tx_cwnd, 2);
|
||||
|
||||
/*
|
||||
* Ensure that Ack Ratio does not exceed ceil(cwnd/2), which is (2) from
|
||||
@@ -155,10 +155,10 @@ static void ccid2_change_l_ack_ratio(struct sock *sk, u32 val)
|
||||
dp->dccps_l_ack_ratio = val;
|
||||
}
|
||||
|
||||
static void ccid2_change_srtt(struct ccid2_hc_tx_sock *hctx, long val)
|
||||
static void ccid2_change_srtt(struct ccid2_hc_tx_sock *hc, long val)
|
||||
{
|
||||
ccid2_pr_debug("change SRTT to %ld\n", val);
|
||||
hctx->ccid2hctx_srtt = val;
|
||||
hc->tx_srtt = val;
|
||||
}
|
||||
|
||||
static void ccid2_start_rto_timer(struct sock *sk);
|
||||
@@ -166,45 +166,44 @@ static void ccid2_start_rto_timer(struct sock *sk);
|
||||
static void ccid2_hc_tx_rto_expire(unsigned long data)
|
||||
{
|
||||
struct sock *sk = (struct sock *)data;
|
||||
struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
|
||||
struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk);
|
||||
long s;
|
||||
|
||||
bh_lock_sock(sk);
|
||||
if (sock_owned_by_user(sk)) {
|
||||
sk_reset_timer(sk, &hctx->ccid2hctx_rtotimer,
|
||||
jiffies + HZ / 5);
|
||||
sk_reset_timer(sk, &hc->tx_rtotimer, jiffies + HZ / 5);
|
||||
goto out;
|
||||
}
|
||||
|
||||
ccid2_pr_debug("RTO_EXPIRE\n");
|
||||
|
||||
ccid2_hc_tx_check_sanity(hctx);
|
||||
ccid2_hc_tx_check_sanity(hc);
|
||||
|
||||
/* back-off timer */
|
||||
hctx->ccid2hctx_rto <<= 1;
|
||||
hc->tx_rto <<= 1;
|
||||
|
||||
s = hctx->ccid2hctx_rto / HZ;
|
||||
s = hc->tx_rto / HZ;
|
||||
if (s > 60)
|
||||
hctx->ccid2hctx_rto = 60 * HZ;
|
||||
hc->tx_rto = 60 * HZ;
|
||||
|
||||
ccid2_start_rto_timer(sk);
|
||||
|
||||
/* adjust pipe, cwnd etc */
|
||||
hctx->ccid2hctx_ssthresh = hctx->ccid2hctx_cwnd / 2;
|
||||
if (hctx->ccid2hctx_ssthresh < 2)
|
||||
hctx->ccid2hctx_ssthresh = 2;
|
||||
hctx->ccid2hctx_cwnd = 1;
|
||||
hctx->ccid2hctx_pipe = 0;
|
||||
hc->tx_ssthresh = hc->tx_cwnd / 2;
|
||||
if (hc->tx_ssthresh < 2)
|
||||
hc->tx_ssthresh = 2;
|
||||
hc->tx_cwnd = 1;
|
||||
hc->tx_pipe = 0;
|
||||
|
||||
/* clear state about stuff we sent */
|
||||
hctx->ccid2hctx_seqt = hctx->ccid2hctx_seqh;
|
||||
hctx->ccid2hctx_packets_acked = 0;
|
||||
hc->tx_seqt = hc->tx_seqh;
|
||||
hc->tx_packets_acked = 0;
|
||||
|
||||
/* clear ack ratio state. */
|
||||
hctx->ccid2hctx_rpseq = 0;
|
||||
hctx->ccid2hctx_rpdupack = -1;
|
||||
hc->tx_rpseq = 0;
|
||||
hc->tx_rpdupack = -1;
|
||||
ccid2_change_l_ack_ratio(sk, 1);
|
||||
ccid2_hc_tx_check_sanity(hctx);
|
||||
ccid2_hc_tx_check_sanity(hc);
|
||||
out:
|
||||
bh_unlock_sock(sk);
|
||||
sock_put(sk);
|
||||
@@ -212,42 +211,40 @@ out:
|
||||
|
||||
static void ccid2_start_rto_timer(struct sock *sk)
|
||||
{
|
||||
struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
|
||||
struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk);
|
||||
|
||||
ccid2_pr_debug("setting RTO timeout=%ld\n", hctx->ccid2hctx_rto);
|
||||
ccid2_pr_debug("setting RTO timeout=%ld\n", hc->tx_rto);
|
||||
|
||||
BUG_ON(timer_pending(&hctx->ccid2hctx_rtotimer));
|
||||
sk_reset_timer(sk, &hctx->ccid2hctx_rtotimer,
|
||||
jiffies + hctx->ccid2hctx_rto);
|
||||
BUG_ON(timer_pending(&hc->tx_rtotimer));
|
||||
sk_reset_timer(sk, &hc->tx_rtotimer, jiffies + hc->tx_rto);
|
||||
}
|
||||
|
||||
static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, unsigned int len)
|
||||
{
|
||||
struct dccp_sock *dp = dccp_sk(sk);
|
||||
struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
|
||||
struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk);
|
||||
struct ccid2_seq *next;
|
||||
|
||||
hctx->ccid2hctx_pipe++;
|
||||
hc->tx_pipe++;
|
||||
|
||||
hctx->ccid2hctx_seqh->ccid2s_seq = dp->dccps_gss;
|
||||
hctx->ccid2hctx_seqh->ccid2s_acked = 0;
|
||||
hctx->ccid2hctx_seqh->ccid2s_sent = jiffies;
|
||||
hc->tx_seqh->ccid2s_seq = dp->dccps_gss;
|
||||
hc->tx_seqh->ccid2s_acked = 0;
|
||||
hc->tx_seqh->ccid2s_sent = jiffies;
|
||||
|
||||
next = hctx->ccid2hctx_seqh->ccid2s_next;
|
||||
next = hc->tx_seqh->ccid2s_next;
|
||||
/* check if we need to alloc more space */
|
||||
if (next == hctx->ccid2hctx_seqt) {
|
||||
if (ccid2_hc_tx_alloc_seq(hctx)) {
|
||||
if (next == hc->tx_seqt) {
|
||||
if (ccid2_hc_tx_alloc_seq(hc)) {
|
||||
DCCP_CRIT("packet history - out of memory!");
|
||||
/* FIXME: find a more graceful way to bail out */
|
||||
return;
|
||||
}
|
||||
next = hctx->ccid2hctx_seqh->ccid2s_next;
|
||||
BUG_ON(next == hctx->ccid2hctx_seqt);
|
||||
next = hc->tx_seqh->ccid2s_next;
|
||||
BUG_ON(next == hc->tx_seqt);
|
||||
}
|
||||
hctx->ccid2hctx_seqh = next;
|
||||
hc->tx_seqh = next;
|
||||
|
||||
ccid2_pr_debug("cwnd=%d pipe=%d\n", hctx->ccid2hctx_cwnd,
|
||||
hctx->ccid2hctx_pipe);
|
||||
ccid2_pr_debug("cwnd=%d pipe=%d\n", hc->tx_cwnd, hc->tx_pipe);
|
||||
|
||||
/*
|
||||
* FIXME: The code below is broken and the variables have been removed
|
||||
@@ -270,12 +267,12 @@ static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, unsigned int len)
|
||||
*/
|
||||
#if 0
|
||||
/* Ack Ratio. Need to maintain a concept of how many windows we sent */
|
||||
hctx->ccid2hctx_arsent++;
|
||||
hc->tx_arsent++;
|
||||
/* We had an ack loss in this window... */
|
||||
if (hctx->ccid2hctx_ackloss) {
|
||||
if (hctx->ccid2hctx_arsent >= hctx->ccid2hctx_cwnd) {
|
||||
hctx->ccid2hctx_arsent = 0;
|
||||
hctx->ccid2hctx_ackloss = 0;
|
||||
if (hc->tx_ackloss) {
|
||||
if (hc->tx_arsent >= hc->tx_cwnd) {
|
||||
hc->tx_arsent = 0;
|
||||
hc->tx_ackloss = 0;
|
||||
}
|
||||
} else {
|
||||
/* No acks lost up to now... */
|
||||
@@ -285,28 +282,28 @@ static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, unsigned int len)
|
||||
int denom = dp->dccps_l_ack_ratio * dp->dccps_l_ack_ratio -
|
||||
dp->dccps_l_ack_ratio;
|
||||
|
||||
denom = hctx->ccid2hctx_cwnd * hctx->ccid2hctx_cwnd / denom;
|
||||
denom = hc->tx_cwnd * hc->tx_cwnd / denom;
|
||||
|
||||
if (hctx->ccid2hctx_arsent >= denom) {
|
||||
if (hc->tx_arsent >= denom) {
|
||||
ccid2_change_l_ack_ratio(sk, dp->dccps_l_ack_ratio - 1);
|
||||
hctx->ccid2hctx_arsent = 0;
|
||||
hc->tx_arsent = 0;
|
||||
}
|
||||
} else {
|
||||
/* we can't increase ack ratio further [1] */
|
||||
hctx->ccid2hctx_arsent = 0; /* or maybe set it to cwnd*/
|
||||
hc->tx_arsent = 0; /* or maybe set it to cwnd*/
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* setup RTO timer */
|
||||
if (!timer_pending(&hctx->ccid2hctx_rtotimer))
|
||||
if (!timer_pending(&hc->tx_rtotimer))
|
||||
ccid2_start_rto_timer(sk);
|
||||
|
||||
#ifdef CONFIG_IP_DCCP_CCID2_DEBUG
|
||||
do {
|
||||
struct ccid2_seq *seqp = hctx->ccid2hctx_seqt;
|
||||
struct ccid2_seq *seqp = hc->tx_seqt;
|
||||
|
||||
while (seqp != hctx->ccid2hctx_seqh) {
|
||||
while (seqp != hc->tx_seqh) {
|
||||
ccid2_pr_debug("out seq=%llu acked=%d time=%lu\n",
|
||||
(unsigned long long)seqp->ccid2s_seq,
|
||||
seqp->ccid2s_acked, seqp->ccid2s_sent);
|
||||
@@ -314,7 +311,7 @@ static void ccid2_hc_tx_packet_sent(struct sock *sk, int more, unsigned int len)
|
||||
}
|
||||
} while (0);
|
||||
ccid2_pr_debug("=========\n");
|
||||
ccid2_hc_tx_check_sanity(hctx);
|
||||
ccid2_hc_tx_check_sanity(hc);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -382,9 +379,9 @@ out_invalid_option:
|
||||
|
||||
static void ccid2_hc_tx_kill_rto_timer(struct sock *sk)
|
||||
{
|
||||
struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
|
||||
struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk);
|
||||
|
||||
sk_stop_timer(sk, &hctx->ccid2hctx_rtotimer);
|
||||
sk_stop_timer(sk, &hc->tx_rtotimer);
|
||||
ccid2_pr_debug("deleted RTO timer\n");
|
||||
}
|
||||
|
||||
@@ -392,75 +389,75 @@ static inline void ccid2_new_ack(struct sock *sk,
|
||||
struct ccid2_seq *seqp,
|
||||
unsigned int *maxincr)
|
||||
{
|
||||
struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
|
||||
struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk);
|
||||
|
||||
if (hctx->ccid2hctx_cwnd < hctx->ccid2hctx_ssthresh) {
|
||||
if (*maxincr > 0 && ++hctx->ccid2hctx_packets_acked == 2) {
|
||||
hctx->ccid2hctx_cwnd += 1;
|
||||
*maxincr -= 1;
|
||||
hctx->ccid2hctx_packets_acked = 0;
|
||||
if (hc->tx_cwnd < hc->tx_ssthresh) {
|
||||
if (*maxincr > 0 && ++hc->tx_packets_acked == 2) {
|
||||
hc->tx_cwnd += 1;
|
||||
*maxincr -= 1;
|
||||
hc->tx_packets_acked = 0;
|
||||
}
|
||||
} else if (++hctx->ccid2hctx_packets_acked >= hctx->ccid2hctx_cwnd) {
|
||||
hctx->ccid2hctx_cwnd += 1;
|
||||
hctx->ccid2hctx_packets_acked = 0;
|
||||
} else if (++hc->tx_packets_acked >= hc->tx_cwnd) {
|
||||
hc->tx_cwnd += 1;
|
||||
hc->tx_packets_acked = 0;
|
||||
}
|
||||
|
||||
/* update RTO */
|
||||
if (hctx->ccid2hctx_srtt == -1 ||
|
||||
time_after(jiffies, hctx->ccid2hctx_lastrtt + hctx->ccid2hctx_srtt)) {
|
||||
if (hc->tx_srtt == -1 ||
|
||||
time_after(jiffies, hc->tx_lastrtt + hc->tx_srtt)) {
|
||||
unsigned long r = (long)jiffies - (long)seqp->ccid2s_sent;
|
||||
int s;
|
||||
|
||||
/* first measurement */
|
||||
if (hctx->ccid2hctx_srtt == -1) {
|
||||
if (hc->tx_srtt == -1) {
|
||||
ccid2_pr_debug("R: %lu Time=%lu seq=%llu\n",
|
||||
r, jiffies,
|
||||
(unsigned long long)seqp->ccid2s_seq);
|
||||
ccid2_change_srtt(hctx, r);
|
||||
hctx->ccid2hctx_rttvar = r >> 1;
|
||||
ccid2_change_srtt(hc, r);
|
||||
hc->tx_rttvar = r >> 1;
|
||||
} else {
|
||||
/* RTTVAR */
|
||||
long tmp = hctx->ccid2hctx_srtt - r;
|
||||
long tmp = hc->tx_srtt - r;
|
||||
long srtt;
|
||||
|
||||
if (tmp < 0)
|
||||
tmp *= -1;
|
||||
|
||||
tmp >>= 2;
|
||||
hctx->ccid2hctx_rttvar *= 3;
|
||||
hctx->ccid2hctx_rttvar >>= 2;
|
||||
hctx->ccid2hctx_rttvar += tmp;
|
||||
hc->tx_rttvar *= 3;
|
||||
hc->tx_rttvar >>= 2;
|
||||
hc->tx_rttvar += tmp;
|
||||
|
||||
/* SRTT */
|
||||
srtt = hctx->ccid2hctx_srtt;
|
||||
srtt = hc->tx_srtt;
|
||||
srtt *= 7;
|
||||
srtt >>= 3;
|
||||
tmp = r >> 3;
|
||||
srtt += tmp;
|
||||
ccid2_change_srtt(hctx, srtt);
|
||||
ccid2_change_srtt(hc, srtt);
|
||||
}
|
||||
s = hctx->ccid2hctx_rttvar << 2;
|
||||
s = hc->tx_rttvar << 2;
|
||||
/* clock granularity is 1 when based on jiffies */
|
||||
if (!s)
|
||||
s = 1;
|
||||
hctx->ccid2hctx_rto = hctx->ccid2hctx_srtt + s;
|
||||
hc->tx_rto = hc->tx_srtt + s;
|
||||
|
||||
/* must be at least a second */
|
||||
s = hctx->ccid2hctx_rto / HZ;
|
||||
s = hc->tx_rto / HZ;
|
||||
/* DCCP doesn't require this [but I like it cuz my code sux] */
|
||||
#if 1
|
||||
if (s < 1)
|
||||
hctx->ccid2hctx_rto = HZ;
|
||||
hc->tx_rto = HZ;
|
||||
#endif
|
||||
/* max 60 seconds */
|
||||
if (s > 60)
|
||||
hctx->ccid2hctx_rto = HZ * 60;
|
||||
hc->tx_rto = HZ * 60;
|
||||
|
||||
hctx->ccid2hctx_lastrtt = jiffies;
|
||||
hc->tx_lastrtt = jiffies;
|
||||
|
||||
ccid2_pr_debug("srtt: %ld rttvar: %ld rto: %ld (HZ=%d) R=%lu\n",
|
||||
hctx->ccid2hctx_srtt, hctx->ccid2hctx_rttvar,
|
||||
hctx->ccid2hctx_rto, HZ, r);
|
||||
hc->tx_srtt, hc->tx_rttvar,
|
||||
hc->tx_rto, HZ, r);
|
||||
}
|
||||
|
||||
/* we got a new ack, so re-start RTO timer */
|
||||
@@ -470,40 +467,40 @@ static inline void ccid2_new_ack(struct sock *sk,
|
||||
|
||||
static void ccid2_hc_tx_dec_pipe(struct sock *sk)
|
||||
{
|
||||
struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
|
||||
struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk);
|
||||
|
||||
if (hctx->ccid2hctx_pipe == 0)
|
||||
if (hc->tx_pipe == 0)
|
||||
DCCP_BUG("pipe == 0");
|
||||
else
|
||||
hctx->ccid2hctx_pipe--;
|
||||
hc->tx_pipe--;
|
||||
|
||||
if (hctx->ccid2hctx_pipe == 0)
|
||||
if (hc->tx_pipe == 0)
|
||||
ccid2_hc_tx_kill_rto_timer(sk);
|
||||
}
|
||||
|
||||
static void ccid2_congestion_event(struct sock *sk, struct ccid2_seq *seqp)
|
||||
{
|
||||
struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
|
||||
struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk);
|
||||
|
||||
if (time_before(seqp->ccid2s_sent, hctx->ccid2hctx_last_cong)) {
|
||||
if (time_before(seqp->ccid2s_sent, hc->tx_last_cong)) {
|
||||
ccid2_pr_debug("Multiple losses in an RTT---treating as one\n");
|
||||
return;
|
||||
}
|
||||
|
||||
hctx->ccid2hctx_last_cong = jiffies;
|
||||
hc->tx_last_cong = jiffies;
|
||||
|
||||
hctx->ccid2hctx_cwnd = hctx->ccid2hctx_cwnd / 2 ? : 1U;
|
||||
hctx->ccid2hctx_ssthresh = max(hctx->ccid2hctx_cwnd, 2U);
|
||||
hc->tx_cwnd = hc->tx_cwnd / 2 ? : 1U;
|
||||
hc->tx_ssthresh = max(hc->tx_cwnd, 2U);
|
||||
|
||||
/* Avoid spurious timeouts resulting from Ack Ratio > cwnd */
|
||||
if (dccp_sk(sk)->dccps_l_ack_ratio > hctx->ccid2hctx_cwnd)
|
||||
ccid2_change_l_ack_ratio(sk, hctx->ccid2hctx_cwnd);
|
||||
if (dccp_sk(sk)->dccps_l_ack_ratio > hc->tx_cwnd)
|
||||
ccid2_change_l_ack_ratio(sk, hc->tx_cwnd);
|
||||
}
|
||||
|
||||
static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
struct dccp_sock *dp = dccp_sk(sk);
|
||||
struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
|
||||
struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk);
|
||||
u64 ackno, seqno;
|
||||
struct ccid2_seq *seqp;
|
||||
unsigned char *vector;
|
||||
@@ -512,7 +509,7 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
|
||||
int done = 0;
|
||||
unsigned int maxincr = 0;
|
||||
|
||||
ccid2_hc_tx_check_sanity(hctx);
|
||||
ccid2_hc_tx_check_sanity(hc);
|
||||
/* check reverse path congestion */
|
||||
seqno = DCCP_SKB_CB(skb)->dccpd_seq;
|
||||
|
||||
@@ -521,21 +518,21 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
|
||||
* -sorbo.
|
||||
*/
|
||||
/* need to bootstrap */
|
||||
if (hctx->ccid2hctx_rpdupack == -1) {
|
||||
hctx->ccid2hctx_rpdupack = 0;
|
||||
hctx->ccid2hctx_rpseq = seqno;
|
||||
if (hc->tx_rpdupack == -1) {
|
||||
hc->tx_rpdupack = 0;
|
||||
hc->tx_rpseq = seqno;
|
||||
} else {
|
||||
/* check if packet is consecutive */
|
||||
if (dccp_delta_seqno(hctx->ccid2hctx_rpseq, seqno) == 1)
|
||||
hctx->ccid2hctx_rpseq = seqno;
|
||||
if (dccp_delta_seqno(hc->tx_rpseq, seqno) == 1)
|
||||
hc->tx_rpseq = seqno;
|
||||
/* it's a later packet */
|
||||
else if (after48(seqno, hctx->ccid2hctx_rpseq)) {
|
||||
hctx->ccid2hctx_rpdupack++;
|
||||
else if (after48(seqno, hc->tx_rpseq)) {
|
||||
hc->tx_rpdupack++;
|
||||
|
||||
/* check if we got enough dupacks */
|
||||
if (hctx->ccid2hctx_rpdupack >= NUMDUPACK) {
|
||||
hctx->ccid2hctx_rpdupack = -1; /* XXX lame */
|
||||
hctx->ccid2hctx_rpseq = 0;
|
||||
if (hc->tx_rpdupack >= NUMDUPACK) {
|
||||
hc->tx_rpdupack = -1; /* XXX lame */
|
||||
hc->tx_rpseq = 0;
|
||||
|
||||
ccid2_change_l_ack_ratio(sk, 2 * dp->dccps_l_ack_ratio);
|
||||
}
|
||||
@@ -544,7 +541,7 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
|
||||
|
||||
/* check forward path congestion */
|
||||
/* still didn't send out new data packets */
|
||||
if (hctx->ccid2hctx_seqh == hctx->ccid2hctx_seqt)
|
||||
if (hc->tx_seqh == hc->tx_seqt)
|
||||
return;
|
||||
|
||||
switch (DCCP_SKB_CB(skb)->dccpd_type) {
|
||||
@@ -556,14 +553,14 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
|
||||
}
|
||||
|
||||
ackno = DCCP_SKB_CB(skb)->dccpd_ack_seq;
|
||||
if (after48(ackno, hctx->ccid2hctx_high_ack))
|
||||
hctx->ccid2hctx_high_ack = ackno;
|
||||
if (after48(ackno, hc->tx_high_ack))
|
||||
hc->tx_high_ack = ackno;
|
||||
|
||||
seqp = hctx->ccid2hctx_seqt;
|
||||
seqp = hc->tx_seqt;
|
||||
while (before48(seqp->ccid2s_seq, ackno)) {
|
||||
seqp = seqp->ccid2s_next;
|
||||
if (seqp == hctx->ccid2hctx_seqh) {
|
||||
seqp = hctx->ccid2hctx_seqh->ccid2s_prev;
|
||||
if (seqp == hc->tx_seqh) {
|
||||
seqp = hc->tx_seqh->ccid2s_prev;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -573,7 +570,7 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
|
||||
* packets per acknowledgement. Rounding up avoids that cwnd is not
|
||||
* advanced when Ack Ratio is 1 and gives a slight edge otherwise.
|
||||
*/
|
||||
if (hctx->ccid2hctx_cwnd < hctx->ccid2hctx_ssthresh)
|
||||
if (hc->tx_cwnd < hc->tx_ssthresh)
|
||||
maxincr = DIV_ROUND_UP(dp->dccps_l_ack_ratio, 2);
|
||||
|
||||
/* go through all ack vectors */
|
||||
@@ -592,7 +589,7 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
|
||||
* seqnos.
|
||||
*/
|
||||
while (after48(seqp->ccid2s_seq, ackno)) {
|
||||
if (seqp == hctx->ccid2hctx_seqt) {
|
||||
if (seqp == hc->tx_seqt) {
|
||||
done = 1;
|
||||
break;
|
||||
}
|
||||
@@ -624,7 +621,7 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
|
||||
(unsigned long long)seqp->ccid2s_seq);
|
||||
ccid2_hc_tx_dec_pipe(sk);
|
||||
}
|
||||
if (seqp == hctx->ccid2hctx_seqt) {
|
||||
if (seqp == hc->tx_seqt) {
|
||||
done = 1;
|
||||
break;
|
||||
}
|
||||
@@ -643,11 +640,11 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
|
||||
/* The state about what is acked should be correct now
|
||||
* Check for NUMDUPACK
|
||||
*/
|
||||
seqp = hctx->ccid2hctx_seqt;
|
||||
while (before48(seqp->ccid2s_seq, hctx->ccid2hctx_high_ack)) {
|
||||
seqp = hc->tx_seqt;
|
||||
while (before48(seqp->ccid2s_seq, hc->tx_high_ack)) {
|
||||
seqp = seqp->ccid2s_next;
|
||||
if (seqp == hctx->ccid2hctx_seqh) {
|
||||
seqp = hctx->ccid2hctx_seqh->ccid2s_prev;
|
||||
if (seqp == hc->tx_seqh) {
|
||||
seqp = hc->tx_seqh->ccid2s_prev;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -658,7 +655,7 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
|
||||
if (done == NUMDUPACK)
|
||||
break;
|
||||
}
|
||||
if (seqp == hctx->ccid2hctx_seqt)
|
||||
if (seqp == hc->tx_seqt)
|
||||
break;
|
||||
seqp = seqp->ccid2s_prev;
|
||||
}
|
||||
@@ -681,86 +678,86 @@ static void ccid2_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
|
||||
ccid2_congestion_event(sk, seqp);
|
||||
ccid2_hc_tx_dec_pipe(sk);
|
||||
}
|
||||
if (seqp == hctx->ccid2hctx_seqt)
|
||||
if (seqp == hc->tx_seqt)
|
||||
break;
|
||||
seqp = seqp->ccid2s_prev;
|
||||
}
|
||||
|
||||
hctx->ccid2hctx_seqt = last_acked;
|
||||
hc->tx_seqt = last_acked;
|
||||
}
|
||||
|
||||
/* trim acked packets in tail */
|
||||
while (hctx->ccid2hctx_seqt != hctx->ccid2hctx_seqh) {
|
||||
if (!hctx->ccid2hctx_seqt->ccid2s_acked)
|
||||
while (hc->tx_seqt != hc->tx_seqh) {
|
||||
if (!hc->tx_seqt->ccid2s_acked)
|
||||
break;
|
||||
|
||||
hctx->ccid2hctx_seqt = hctx->ccid2hctx_seqt->ccid2s_next;
|
||||
hc->tx_seqt = hc->tx_seqt->ccid2s_next;
|
||||
}
|
||||
|
||||
ccid2_hc_tx_check_sanity(hctx);
|
||||
ccid2_hc_tx_check_sanity(hc);
|
||||
}
|
||||
|
||||
static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk)
|
||||
{
|
||||
struct ccid2_hc_tx_sock *hctx = ccid_priv(ccid);
|
||||
struct ccid2_hc_tx_sock *hc = ccid_priv(ccid);
|
||||
struct dccp_sock *dp = dccp_sk(sk);
|
||||
u32 max_ratio;
|
||||
|
||||
/* RFC 4341, 5: initialise ssthresh to arbitrarily high (max) value */
|
||||
hctx->ccid2hctx_ssthresh = ~0U;
|
||||
hc->tx_ssthresh = ~0U;
|
||||
|
||||
/*
|
||||
* RFC 4341, 5: "The cwnd parameter is initialized to at most four
|
||||
* packets for new connections, following the rules from [RFC3390]".
|
||||
* We need to convert the bytes of RFC3390 into the packets of RFC 4341.
|
||||
*/
|
||||
hctx->ccid2hctx_cwnd = clamp(4380U / dp->dccps_mss_cache, 2U, 4U);
|
||||
hc->tx_cwnd = clamp(4380U / dp->dccps_mss_cache, 2U, 4U);
|
||||
|
||||
/* Make sure that Ack Ratio is enabled and within bounds. */
|
||||
max_ratio = DIV_ROUND_UP(hctx->ccid2hctx_cwnd, 2);
|
||||
max_ratio = DIV_ROUND_UP(hc->tx_cwnd, 2);
|
||||
if (dp->dccps_l_ack_ratio == 0 || dp->dccps_l_ack_ratio > max_ratio)
|
||||
dp->dccps_l_ack_ratio = max_ratio;
|
||||
|
||||
/* XXX init ~ to window size... */
|
||||
if (ccid2_hc_tx_alloc_seq(hctx))
|
||||
if (ccid2_hc_tx_alloc_seq(hc))
|
||||
return -ENOMEM;
|
||||
|
||||
hctx->ccid2hctx_rto = 3 * HZ;
|
||||
ccid2_change_srtt(hctx, -1);
|
||||
hctx->ccid2hctx_rttvar = -1;
|
||||
hctx->ccid2hctx_rpdupack = -1;
|
||||
hctx->ccid2hctx_last_cong = jiffies;
|
||||
setup_timer(&hctx->ccid2hctx_rtotimer, ccid2_hc_tx_rto_expire,
|
||||
hc->tx_rto = 3 * HZ;
|
||||
ccid2_change_srtt(hc, -1);
|
||||
hc->tx_rttvar = -1;
|
||||
hc->tx_rpdupack = -1;
|
||||
hc->tx_last_cong = jiffies;
|
||||
setup_timer(&hc->tx_rtotimer, ccid2_hc_tx_rto_expire,
|
||||
(unsigned long)sk);
|
||||
|
||||
ccid2_hc_tx_check_sanity(hctx);
|
||||
ccid2_hc_tx_check_sanity(hc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ccid2_hc_tx_exit(struct sock *sk)
|
||||
{
|
||||
struct ccid2_hc_tx_sock *hctx = ccid2_hc_tx_sk(sk);
|
||||
struct ccid2_hc_tx_sock *hc = ccid2_hc_tx_sk(sk);
|
||||
int i;
|
||||
|
||||
ccid2_hc_tx_kill_rto_timer(sk);
|
||||
|
||||
for (i = 0; i < hctx->ccid2hctx_seqbufc; i++)
|
||||
kfree(hctx->ccid2hctx_seqbuf[i]);
|
||||
hctx->ccid2hctx_seqbufc = 0;
|
||||
for (i = 0; i < hc->tx_seqbufc; i++)
|
||||
kfree(hc->tx_seqbuf[i]);
|
||||
hc->tx_seqbufc = 0;
|
||||
}
|
||||
|
||||
static void ccid2_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
const struct dccp_sock *dp = dccp_sk(sk);
|
||||
struct ccid2_hc_rx_sock *hcrx = ccid2_hc_rx_sk(sk);
|
||||
struct ccid2_hc_rx_sock *hc = ccid2_hc_rx_sk(sk);
|
||||
|
||||
switch (DCCP_SKB_CB(skb)->dccpd_type) {
|
||||
case DCCP_PKT_DATA:
|
||||
case DCCP_PKT_DATAACK:
|
||||
hcrx->ccid2hcrx_data++;
|
||||
if (hcrx->ccid2hcrx_data >= dp->dccps_r_ack_ratio) {
|
||||
hc->rx_data++;
|
||||
if (hc->rx_data >= dp->dccps_r_ack_ratio) {
|
||||
dccp_send_ack(sk);
|
||||
hcrx->ccid2hcrx_data = 0;
|
||||
hc->rx_data = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@@ -40,34 +40,34 @@ struct ccid2_seq {
|
||||
|
||||
/**
|
||||
* struct ccid2_hc_tx_sock - CCID2 TX half connection
|
||||
* @ccid2hctx_{cwnd,ssthresh,pipe}: as per RFC 4341, section 5
|
||||
* @ccid2hctx_packets_acked - Ack counter for deriving cwnd growth (RFC 3465)
|
||||
* @ccid2hctx_lastrtt -time RTT was last measured
|
||||
* @ccid2hctx_rpseq - last consecutive seqno
|
||||
* @ccid2hctx_rpdupack - dupacks since rpseq
|
||||
* @tx_{cwnd,ssthresh,pipe}: as per RFC 4341, section 5
|
||||
* @tx_packets_acked: Ack counter for deriving cwnd growth (RFC 3465)
|
||||
* @tx_lastrtt: time RTT was last measured
|
||||
* @tx_rpseq: last consecutive seqno
|
||||
* @tx_rpdupack: dupacks since rpseq
|
||||
*/
|
||||
struct ccid2_hc_tx_sock {
|
||||
u32 ccid2hctx_cwnd;
|
||||
u32 ccid2hctx_ssthresh;
|
||||
u32 ccid2hctx_pipe;
|
||||
u32 ccid2hctx_packets_acked;
|
||||
struct ccid2_seq *ccid2hctx_seqbuf[CCID2_SEQBUF_MAX];
|
||||
int ccid2hctx_seqbufc;
|
||||
struct ccid2_seq *ccid2hctx_seqh;
|
||||
struct ccid2_seq *ccid2hctx_seqt;
|
||||
long ccid2hctx_rto;
|
||||
long ccid2hctx_srtt;
|
||||
long ccid2hctx_rttvar;
|
||||
unsigned long ccid2hctx_lastrtt;
|
||||
struct timer_list ccid2hctx_rtotimer;
|
||||
u64 ccid2hctx_rpseq;
|
||||
int ccid2hctx_rpdupack;
|
||||
unsigned long ccid2hctx_last_cong;
|
||||
u64 ccid2hctx_high_ack;
|
||||
u32 tx_cwnd;
|
||||
u32 tx_ssthresh;
|
||||
u32 tx_pipe;
|
||||
u32 tx_packets_acked;
|
||||
struct ccid2_seq *tx_seqbuf[CCID2_SEQBUF_MAX];
|
||||
int tx_seqbufc;
|
||||
struct ccid2_seq *tx_seqh;
|
||||
struct ccid2_seq *tx_seqt;
|
||||
long tx_rto;
|
||||
long tx_srtt;
|
||||
long tx_rttvar;
|
||||
unsigned long tx_lastrtt;
|
||||
struct timer_list tx_rtotimer;
|
||||
u64 tx_rpseq;
|
||||
int tx_rpdupack;
|
||||
unsigned long tx_last_cong;
|
||||
u64 tx_high_ack;
|
||||
};
|
||||
|
||||
struct ccid2_hc_rx_sock {
|
||||
int ccid2hcrx_data;
|
||||
int rx_data;
|
||||
};
|
||||
|
||||
static inline struct ccid2_hc_tx_sock *ccid2_hc_tx_sk(const struct sock *sk)
|
||||
|
@@ -64,14 +64,14 @@ static const char *ccid3_tx_state_name(enum ccid3_hc_tx_states state)
|
||||
static void ccid3_hc_tx_set_state(struct sock *sk,
|
||||
enum ccid3_hc_tx_states state)
|
||||
{
|
||||
struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
|
||||
enum ccid3_hc_tx_states oldstate = hctx->ccid3hctx_state;
|
||||
struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk);
|
||||
enum ccid3_hc_tx_states oldstate = hc->tx_state;
|
||||
|
||||
ccid3_pr_debug("%s(%p) %-8.8s -> %s\n",
|
||||
dccp_role(sk), sk, ccid3_tx_state_name(oldstate),
|
||||
ccid3_tx_state_name(state));
|
||||
WARN_ON(state == oldstate);
|
||||
hctx->ccid3hctx_state = state;
|
||||
hc->tx_state = state;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -85,37 +85,32 @@ static void ccid3_hc_tx_set_state(struct sock *sk,
|
||||
*/
|
||||
static inline u64 rfc3390_initial_rate(struct sock *sk)
|
||||
{
|
||||
const struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
|
||||
const __u32 w_init = clamp_t(__u32, 4380U,
|
||||
2 * hctx->ccid3hctx_s, 4 * hctx->ccid3hctx_s);
|
||||
const struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk);
|
||||
const __u32 w_init = clamp_t(__u32, 4380U, 2 * hc->tx_s, 4 * hc->tx_s);
|
||||
|
||||
return scaled_div(w_init << 6, hctx->ccid3hctx_rtt);
|
||||
return scaled_div(w_init << 6, hc->tx_rtt);
|
||||
}
|
||||
|
||||
/*
|
||||
* Recalculate t_ipi and delta (should be called whenever X changes)
|
||||
*/
|
||||
static void ccid3_update_send_interval(struct ccid3_hc_tx_sock *hctx)
|
||||
static void ccid3_update_send_interval(struct ccid3_hc_tx_sock *hc)
|
||||
{
|
||||
/* Calculate new t_ipi = s / X_inst (X_inst is in 64 * bytes/second) */
|
||||
hctx->ccid3hctx_t_ipi = scaled_div32(((u64)hctx->ccid3hctx_s) << 6,
|
||||
hctx->ccid3hctx_x);
|
||||
hc->tx_t_ipi = scaled_div32(((u64)hc->tx_s) << 6, hc->tx_x);
|
||||
|
||||
/* 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);
|
||||
|
||||
ccid3_pr_debug("t_ipi=%u, delta=%u, s=%u, X=%u\n",
|
||||
hctx->ccid3hctx_t_ipi, hctx->ccid3hctx_delta,
|
||||
hctx->ccid3hctx_s, (unsigned)(hctx->ccid3hctx_x >> 6));
|
||||
hc->tx_delta = min_t(u32, hc->tx_t_ipi / 2, TFRC_OPSYS_HALF_TIME_GRAN);
|
||||
|
||||
ccid3_pr_debug("t_ipi=%u, delta=%u, s=%u, X=%u\n", hc->tx_t_ipi,
|
||||
hc->tx_delta, hc->tx_s, (unsigned)(hc->tx_x >> 6));
|
||||
}
|
||||
|
||||
static u32 ccid3_hc_tx_idle_rtt(struct ccid3_hc_tx_sock *hctx, ktime_t now)
|
||||
static u32 ccid3_hc_tx_idle_rtt(struct ccid3_hc_tx_sock *hc, ktime_t now)
|
||||
{
|
||||
u32 delta = ktime_us_delta(now, hctx->ccid3hctx_t_last_win_count);
|
||||
u32 delta = ktime_us_delta(now, hc->tx_t_last_win_count);
|
||||
|
||||
return delta / hctx->ccid3hctx_rtt;
|
||||
return delta / hc->tx_rtt;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -130,9 +125,9 @@ static u32 ccid3_hc_tx_idle_rtt(struct ccid3_hc_tx_sock *hctx, ktime_t now)
|
||||
*/
|
||||
static void ccid3_hc_tx_update_x(struct sock *sk, ktime_t *stamp)
|
||||
{
|
||||
struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
|
||||
__u64 min_rate = 2 * hctx->ccid3hctx_x_recv;
|
||||
const __u64 old_x = hctx->ccid3hctx_x;
|
||||
struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk);
|
||||
__u64 min_rate = 2 * hc->tx_x_recv;
|
||||
const __u64 old_x = hc->tx_x;
|
||||
ktime_t now = stamp ? *stamp : ktime_get_real();
|
||||
|
||||
/*
|
||||
@@ -141,37 +136,31 @@ static void ccid3_hc_tx_update_x(struct sock *sk, ktime_t *stamp)
|
||||
* a sender is idle if it has not sent anything over a 2-RTT-period.
|
||||
* For consistency with X and X_recv, min_rate is also scaled by 2^6.
|
||||
*/
|
||||
if (ccid3_hc_tx_idle_rtt(hctx, now) >= 2) {
|
||||
if (ccid3_hc_tx_idle_rtt(hc, now) >= 2) {
|
||||
min_rate = rfc3390_initial_rate(sk);
|
||||
min_rate = max(min_rate, 2 * hctx->ccid3hctx_x_recv);
|
||||
min_rate = max(min_rate, 2 * hc->tx_x_recv);
|
||||
}
|
||||
|
||||
if (hctx->ccid3hctx_p > 0) {
|
||||
if (hc->tx_p > 0) {
|
||||
|
||||
hctx->ccid3hctx_x = min(((__u64)hctx->ccid3hctx_x_calc) << 6,
|
||||
min_rate);
|
||||
hctx->ccid3hctx_x = max(hctx->ccid3hctx_x,
|
||||
(((__u64)hctx->ccid3hctx_s) << 6) /
|
||||
TFRC_T_MBI);
|
||||
hc->tx_x = min(((__u64)hc->tx_x_calc) << 6, min_rate);
|
||||
hc->tx_x = max(hc->tx_x, (((__u64)hc->tx_s) << 6) / TFRC_T_MBI);
|
||||
|
||||
} else if (ktime_us_delta(now, hctx->ccid3hctx_t_ld)
|
||||
- (s64)hctx->ccid3hctx_rtt >= 0) {
|
||||
} else if (ktime_us_delta(now, hc->tx_t_ld) - (s64)hc->tx_rtt >= 0) {
|
||||
|
||||
hctx->ccid3hctx_x = min(2 * hctx->ccid3hctx_x, min_rate);
|
||||
hctx->ccid3hctx_x = max(hctx->ccid3hctx_x,
|
||||
scaled_div(((__u64)hctx->ccid3hctx_s) << 6,
|
||||
hctx->ccid3hctx_rtt));
|
||||
hctx->ccid3hctx_t_ld = now;
|
||||
hc->tx_x = min(2 * hc->tx_x, min_rate);
|
||||
hc->tx_x = max(hc->tx_x,
|
||||
scaled_div(((__u64)hc->tx_s) << 6, hc->tx_rtt));
|
||||
hc->tx_t_ld = now;
|
||||
}
|
||||
|
||||
if (hctx->ccid3hctx_x != old_x) {
|
||||
if (hc->tx_x != old_x) {
|
||||
ccid3_pr_debug("X_prev=%u, X_now=%u, X_calc=%u, "
|
||||
"X_recv=%u\n", (unsigned)(old_x >> 6),
|
||||
(unsigned)(hctx->ccid3hctx_x >> 6),
|
||||
hctx->ccid3hctx_x_calc,
|
||||
(unsigned)(hctx->ccid3hctx_x_recv >> 6));
|
||||
(unsigned)(hc->tx_x >> 6), hc->tx_x_calc,
|
||||
(unsigned)(hc->tx_x_recv >> 6));
|
||||
|
||||
ccid3_update_send_interval(hctx);
|
||||
ccid3_update_send_interval(hc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,37 +168,37 @@ static void ccid3_hc_tx_update_x(struct sock *sk, ktime_t *stamp)
|
||||
* Track the mean packet size `s' (cf. RFC 4342, 5.3 and RFC 3448, 4.1)
|
||||
* @len: DCCP packet payload size in bytes
|
||||
*/
|
||||
static inline void ccid3_hc_tx_update_s(struct ccid3_hc_tx_sock *hctx, int len)
|
||||
static inline void ccid3_hc_tx_update_s(struct ccid3_hc_tx_sock *hc, int len)
|
||||
{
|
||||
const u16 old_s = hctx->ccid3hctx_s;
|
||||
const u16 old_s = hc->tx_s;
|
||||
|
||||
hctx->ccid3hctx_s = tfrc_ewma(hctx->ccid3hctx_s, len, 9);
|
||||
hc->tx_s = tfrc_ewma(hc->tx_s, len, 9);
|
||||
|
||||
if (hctx->ccid3hctx_s != old_s)
|
||||
ccid3_update_send_interval(hctx);
|
||||
if (hc->tx_s != old_s)
|
||||
ccid3_update_send_interval(hc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Update Window Counter using the algorithm from [RFC 4342, 8.1].
|
||||
* As elsewhere, RTT > 0 is assumed by using dccp_sample_rtt().
|
||||
*/
|
||||
static inline void ccid3_hc_tx_update_win_count(struct ccid3_hc_tx_sock *hctx,
|
||||
static inline void ccid3_hc_tx_update_win_count(struct ccid3_hc_tx_sock *hc,
|
||||
ktime_t now)
|
||||
{
|
||||
u32 delta = ktime_us_delta(now, hctx->ccid3hctx_t_last_win_count),
|
||||
quarter_rtts = (4 * delta) / hctx->ccid3hctx_rtt;
|
||||
u32 delta = ktime_us_delta(now, hc->tx_t_last_win_count),
|
||||
quarter_rtts = (4 * delta) / hc->tx_rtt;
|
||||
|
||||
if (quarter_rtts > 0) {
|
||||
hctx->ccid3hctx_t_last_win_count = now;
|
||||
hctx->ccid3hctx_last_win_count += min(quarter_rtts, 5U);
|
||||
hctx->ccid3hctx_last_win_count &= 0xF; /* mod 16 */
|
||||
hc->tx_t_last_win_count = now;
|
||||
hc->tx_last_win_count += min(quarter_rtts, 5U);
|
||||
hc->tx_last_win_count &= 0xF; /* mod 16 */
|
||||
}
|
||||
}
|
||||
|
||||
static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
|
||||
{
|
||||
struct sock *sk = (struct sock *)data;
|
||||
struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
|
||||
struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk);
|
||||
unsigned long t_nfb = USEC_PER_SEC / 5;
|
||||
|
||||
bh_lock_sock(sk);
|
||||
@@ -220,24 +209,23 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
|
||||
}
|
||||
|
||||
ccid3_pr_debug("%s(%p, state=%s) - entry \n", dccp_role(sk), sk,
|
||||
ccid3_tx_state_name(hctx->ccid3hctx_state));
|
||||
ccid3_tx_state_name(hc->tx_state));
|
||||
|
||||
if (hctx->ccid3hctx_state == TFRC_SSTATE_FBACK)
|
||||
if (hc->tx_state == TFRC_SSTATE_FBACK)
|
||||
ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK);
|
||||
else if (hctx->ccid3hctx_state != TFRC_SSTATE_NO_FBACK)
|
||||
else if (hc->tx_state != TFRC_SSTATE_NO_FBACK)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Determine new allowed sending rate X as per draft rfc3448bis-00, 4.4
|
||||
*/
|
||||
if (hctx->ccid3hctx_t_rto == 0 || /* no feedback received yet */
|
||||
hctx->ccid3hctx_p == 0) {
|
||||
if (hc->tx_t_rto == 0 || /* no feedback received yet */
|
||||
hc->tx_p == 0) {
|
||||
|
||||
/* halve send rate directly */
|
||||
hctx->ccid3hctx_x = max(hctx->ccid3hctx_x / 2,
|
||||
(((__u64)hctx->ccid3hctx_s) << 6) /
|
||||
TFRC_T_MBI);
|
||||
ccid3_update_send_interval(hctx);
|
||||
hc->tx_x = max(hc->tx_x / 2,
|
||||
(((__u64)hc->tx_s) << 6) / TFRC_T_MBI);
|
||||
ccid3_update_send_interval(hc);
|
||||
} else {
|
||||
/*
|
||||
* Modify the cached value of X_recv
|
||||
@@ -249,33 +237,32 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
|
||||
*
|
||||
* Note that X_recv is scaled by 2^6 while X_calc is not
|
||||
*/
|
||||
BUG_ON(hctx->ccid3hctx_p && !hctx->ccid3hctx_x_calc);
|
||||
BUG_ON(hc->tx_p && !hc->tx_x_calc);
|
||||
|
||||
if (hctx->ccid3hctx_x_calc > (hctx->ccid3hctx_x_recv >> 5))
|
||||
hctx->ccid3hctx_x_recv =
|
||||
max(hctx->ccid3hctx_x_recv / 2,
|
||||
(((__u64)hctx->ccid3hctx_s) << 6) /
|
||||
(2 * TFRC_T_MBI));
|
||||
if (hc->tx_x_calc > (hc->tx_x_recv >> 5))
|
||||
hc->tx_x_recv =
|
||||
max(hc->tx_x_recv / 2,
|
||||
(((__u64)hc->tx_s) << 6) / (2*TFRC_T_MBI));
|
||||
else {
|
||||
hctx->ccid3hctx_x_recv = hctx->ccid3hctx_x_calc;
|
||||
hctx->ccid3hctx_x_recv <<= 4;
|
||||
hc->tx_x_recv = hc->tx_x_calc;
|
||||
hc->tx_x_recv <<= 4;
|
||||
}
|
||||
ccid3_hc_tx_update_x(sk, NULL);
|
||||
}
|
||||
ccid3_pr_debug("Reduced X to %llu/64 bytes/sec\n",
|
||||
(unsigned long long)hctx->ccid3hctx_x);
|
||||
(unsigned long long)hc->tx_x);
|
||||
|
||||
/*
|
||||
* Set new timeout for the nofeedback timer.
|
||||
* See comments in packet_recv() regarding the value of t_RTO.
|
||||
*/
|
||||
if (unlikely(hctx->ccid3hctx_t_rto == 0)) /* no feedback yet */
|
||||
if (unlikely(hc->tx_t_rto == 0)) /* no feedback yet */
|
||||
t_nfb = TFRC_INITIAL_TIMEOUT;
|
||||
else
|
||||
t_nfb = max(hctx->ccid3hctx_t_rto, 2 * hctx->ccid3hctx_t_ipi);
|
||||
t_nfb = max(hc->tx_t_rto, 2 * hc->tx_t_ipi);
|
||||
|
||||
restart_timer:
|
||||
sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
|
||||
sk_reset_timer(sk, &hc->tx_no_feedback_timer,
|
||||
jiffies + usecs_to_jiffies(t_nfb));
|
||||
out:
|
||||
bh_unlock_sock(sk);
|
||||
@@ -291,7 +278,7 @@ out:
|
||||
static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
struct dccp_sock *dp = dccp_sk(sk);
|
||||
struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
|
||||
struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk);
|
||||
ktime_t now = ktime_get_real();
|
||||
s64 delay;
|
||||
|
||||
@@ -303,18 +290,17 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
|
||||
if (unlikely(skb->len == 0))
|
||||
return -EBADMSG;
|
||||
|
||||
switch (hctx->ccid3hctx_state) {
|
||||
switch (hc->tx_state) {
|
||||
case TFRC_SSTATE_NO_SENT:
|
||||
sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
|
||||
(jiffies +
|
||||
usecs_to_jiffies(TFRC_INITIAL_TIMEOUT)));
|
||||
hctx->ccid3hctx_last_win_count = 0;
|
||||
hctx->ccid3hctx_t_last_win_count = now;
|
||||
sk_reset_timer(sk, &hc->tx_no_feedback_timer, (jiffies +
|
||||
usecs_to_jiffies(TFRC_INITIAL_TIMEOUT)));
|
||||
hc->tx_last_win_count = 0;
|
||||
hc->tx_t_last_win_count = now;
|
||||
|
||||
/* Set t_0 for initial packet */
|
||||
hctx->ccid3hctx_t_nom = now;
|
||||
hc->tx_t_nom = now;
|
||||
|
||||
hctx->ccid3hctx_s = skb->len;
|
||||
hc->tx_s = skb->len;
|
||||
|
||||
/*
|
||||
* Use initial RTT sample when available: recommended by erratum
|
||||
@@ -323,9 +309,9 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
|
||||
*/
|
||||
if (dp->dccps_syn_rtt) {
|
||||
ccid3_pr_debug("SYN RTT = %uus\n", dp->dccps_syn_rtt);
|
||||
hctx->ccid3hctx_rtt = dp->dccps_syn_rtt;
|
||||
hctx->ccid3hctx_x = rfc3390_initial_rate(sk);
|
||||
hctx->ccid3hctx_t_ld = now;
|
||||
hc->tx_rtt = dp->dccps_syn_rtt;
|
||||
hc->tx_x = rfc3390_initial_rate(sk);
|
||||
hc->tx_t_ld = now;
|
||||
} else {
|
||||
/*
|
||||
* Sender does not have RTT sample:
|
||||
@@ -333,17 +319,17 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
|
||||
* is needed in several parts (e.g. window counter);
|
||||
* - set sending rate X_pps = 1pps as per RFC 3448, 4.2.
|
||||
*/
|
||||
hctx->ccid3hctx_rtt = DCCP_FALLBACK_RTT;
|
||||
hctx->ccid3hctx_x = hctx->ccid3hctx_s;
|
||||
hctx->ccid3hctx_x <<= 6;
|
||||
hc->tx_rtt = DCCP_FALLBACK_RTT;
|
||||
hc->tx_x = hc->tx_s;
|
||||
hc->tx_x <<= 6;
|
||||
}
|
||||
ccid3_update_send_interval(hctx);
|
||||
ccid3_update_send_interval(hc);
|
||||
|
||||
ccid3_hc_tx_set_state(sk, TFRC_SSTATE_NO_FBACK);
|
||||
break;
|
||||
case TFRC_SSTATE_NO_FBACK:
|
||||
case TFRC_SSTATE_FBACK:
|
||||
delay = ktime_us_delta(hctx->ccid3hctx_t_nom, now);
|
||||
delay = ktime_us_delta(hc->tx_t_nom, now);
|
||||
ccid3_pr_debug("delay=%ld\n", (long)delay);
|
||||
/*
|
||||
* Scheduling of packet transmissions [RFC 3448, 4.6]
|
||||
@@ -353,10 +339,10 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
|
||||
* else
|
||||
* // send the packet in (t_nom - t_now) milliseconds.
|
||||
*/
|
||||
if (delay - (s64)hctx->ccid3hctx_delta >= 1000)
|
||||
if (delay - (s64)hc->tx_delta >= 1000)
|
||||
return (u32)delay / 1000L;
|
||||
|
||||
ccid3_hc_tx_update_win_count(hctx, now);
|
||||
ccid3_hc_tx_update_win_count(hc, now);
|
||||
break;
|
||||
case TFRC_SSTATE_TERM:
|
||||
DCCP_BUG("%s(%p) - Illegal state TERM", dccp_role(sk), sk);
|
||||
@@ -365,28 +351,27 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
|
||||
|
||||
/* prepare to send now (add options etc.) */
|
||||
dp->dccps_hc_tx_insert_options = 1;
|
||||
DCCP_SKB_CB(skb)->dccpd_ccval = hctx->ccid3hctx_last_win_count;
|
||||
DCCP_SKB_CB(skb)->dccpd_ccval = hc->tx_last_win_count;
|
||||
|
||||
/* set the nominal send time for the next following packet */
|
||||
hctx->ccid3hctx_t_nom = ktime_add_us(hctx->ccid3hctx_t_nom,
|
||||
hctx->ccid3hctx_t_ipi);
|
||||
hc->tx_t_nom = ktime_add_us(hc->tx_t_nom, hc->tx_t_ipi);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ccid3_hc_tx_packet_sent(struct sock *sk, int more,
|
||||
unsigned int len)
|
||||
{
|
||||
struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
|
||||
struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk);
|
||||
|
||||
ccid3_hc_tx_update_s(hctx, len);
|
||||
ccid3_hc_tx_update_s(hc, len);
|
||||
|
||||
if (tfrc_tx_hist_add(&hctx->ccid3hctx_hist, dccp_sk(sk)->dccps_gss))
|
||||
if (tfrc_tx_hist_add(&hc->tx_hist, dccp_sk(sk)->dccps_gss))
|
||||
DCCP_CRIT("packet history - out of memory!");
|
||||
}
|
||||
|
||||
static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
|
||||
struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk);
|
||||
struct ccid3_options_received *opt_recv;
|
||||
ktime_t now;
|
||||
unsigned long t_nfb;
|
||||
@@ -397,15 +382,15 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
|
||||
DCCP_SKB_CB(skb)->dccpd_type == DCCP_PKT_DATAACK))
|
||||
return;
|
||||
/* ... and only in the established state */
|
||||
if (hctx->ccid3hctx_state != TFRC_SSTATE_FBACK &&
|
||||
hctx->ccid3hctx_state != TFRC_SSTATE_NO_FBACK)
|
||||
if (hc->tx_state != TFRC_SSTATE_FBACK &&
|
||||
hc->tx_state != TFRC_SSTATE_NO_FBACK)
|
||||
return;
|
||||
|
||||
opt_recv = &hctx->ccid3hctx_options_received;
|
||||
opt_recv = &hc->tx_options_received;
|
||||
now = ktime_get_real();
|
||||
|
||||
/* Estimate RTT from history if ACK number is valid */
|
||||
r_sample = tfrc_tx_hist_rtt(hctx->ccid3hctx_hist,
|
||||
r_sample = tfrc_tx_hist_rtt(hc->tx_hist,
|
||||
DCCP_SKB_CB(skb)->dccpd_ack_seq, now);
|
||||
if (r_sample == 0) {
|
||||
DCCP_WARN("%s(%p): %s with bogus ACK-%llu\n", dccp_role(sk), sk,
|
||||
@@ -415,37 +400,37 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
|
||||
}
|
||||
|
||||
/* Update receive rate in units of 64 * bytes/second */
|
||||
hctx->ccid3hctx_x_recv = opt_recv->ccid3or_receive_rate;
|
||||
hctx->ccid3hctx_x_recv <<= 6;
|
||||
hc->tx_x_recv = opt_recv->ccid3or_receive_rate;
|
||||
hc->tx_x_recv <<= 6;
|
||||
|
||||
/* Update loss event rate (which is scaled by 1e6) */
|
||||
pinv = opt_recv->ccid3or_loss_event_rate;
|
||||
if (pinv == ~0U || pinv == 0) /* see RFC 4342, 8.5 */
|
||||
hctx->ccid3hctx_p = 0;
|
||||
hc->tx_p = 0;
|
||||
else /* can not exceed 100% */
|
||||
hctx->ccid3hctx_p = scaled_div(1, pinv);
|
||||
hc->tx_p = scaled_div(1, pinv);
|
||||
/*
|
||||
* Validate new RTT sample and update moving average
|
||||
*/
|
||||
r_sample = dccp_sample_rtt(sk, r_sample);
|
||||
hctx->ccid3hctx_rtt = tfrc_ewma(hctx->ccid3hctx_rtt, r_sample, 9);
|
||||
hc->tx_rtt = tfrc_ewma(hc->tx_rtt, r_sample, 9);
|
||||
/*
|
||||
* Update allowed sending rate X as per draft rfc3448bis-00, 4.2/3
|
||||
*/
|
||||
if (hctx->ccid3hctx_state == TFRC_SSTATE_NO_FBACK) {
|
||||
if (hc->tx_state == TFRC_SSTATE_NO_FBACK) {
|
||||
ccid3_hc_tx_set_state(sk, TFRC_SSTATE_FBACK);
|
||||
|
||||
if (hctx->ccid3hctx_t_rto == 0) {
|
||||
if (hc->tx_t_rto == 0) {
|
||||
/*
|
||||
* Initial feedback packet: Larger Initial Windows (4.2)
|
||||
*/
|
||||
hctx->ccid3hctx_x = rfc3390_initial_rate(sk);
|
||||
hctx->ccid3hctx_t_ld = now;
|
||||
hc->tx_x = rfc3390_initial_rate(sk);
|
||||
hc->tx_t_ld = now;
|
||||
|
||||
ccid3_update_send_interval(hctx);
|
||||
ccid3_update_send_interval(hc);
|
||||
|
||||
goto done_computing_x;
|
||||
} else if (hctx->ccid3hctx_p == 0) {
|
||||
} else if (hc->tx_p == 0) {
|
||||
/*
|
||||
* First feedback after nofeedback timer expiry (4.3)
|
||||
*/
|
||||
@@ -454,25 +439,20 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
|
||||
}
|
||||
|
||||
/* Update sending rate (step 4 of [RFC 3448, 4.3]) */
|
||||
if (hctx->ccid3hctx_p > 0)
|
||||
hctx->ccid3hctx_x_calc =
|
||||
tfrc_calc_x(hctx->ccid3hctx_s,
|
||||
hctx->ccid3hctx_rtt,
|
||||
hctx->ccid3hctx_p);
|
||||
if (hc->tx_p > 0)
|
||||
hc->tx_x_calc = tfrc_calc_x(hc->tx_s, hc->tx_rtt, hc->tx_p);
|
||||
ccid3_hc_tx_update_x(sk, &now);
|
||||
|
||||
done_computing_x:
|
||||
ccid3_pr_debug("%s(%p), RTT=%uus (sample=%uus), s=%u, "
|
||||
"p=%u, X_calc=%u, X_recv=%u, X=%u\n",
|
||||
dccp_role(sk),
|
||||
sk, hctx->ccid3hctx_rtt, r_sample,
|
||||
hctx->ccid3hctx_s, hctx->ccid3hctx_p,
|
||||
hctx->ccid3hctx_x_calc,
|
||||
(unsigned)(hctx->ccid3hctx_x_recv >> 6),
|
||||
(unsigned)(hctx->ccid3hctx_x >> 6));
|
||||
dccp_role(sk), sk, hc->tx_rtt, r_sample,
|
||||
hc->tx_s, hc->tx_p, hc->tx_x_calc,
|
||||
(unsigned)(hc->tx_x_recv >> 6),
|
||||
(unsigned)(hc->tx_x >> 6));
|
||||
|
||||
/* unschedule no feedback timer */
|
||||
sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer);
|
||||
sk_stop_timer(sk, &hc->tx_no_feedback_timer);
|
||||
|
||||
/*
|
||||
* As we have calculated new ipi, delta, t_nom it is possible
|
||||
@@ -486,21 +466,19 @@ done_computing_x:
|
||||
* This can help avoid triggering the nofeedback timer too
|
||||
* often ('spinning') on LANs with small RTTs.
|
||||
*/
|
||||
hctx->ccid3hctx_t_rto = max_t(u32, 4 * hctx->ccid3hctx_rtt,
|
||||
(CONFIG_IP_DCCP_CCID3_RTO *
|
||||
(USEC_PER_SEC / 1000)));
|
||||
hc->tx_t_rto = max_t(u32, 4 * hc->tx_rtt, (CONFIG_IP_DCCP_CCID3_RTO *
|
||||
(USEC_PER_SEC / 1000)));
|
||||
/*
|
||||
* Schedule no feedback timer to expire in
|
||||
* max(t_RTO, 2 * s/X) = max(t_RTO, 2 * t_ipi)
|
||||
*/
|
||||
t_nfb = max(hctx->ccid3hctx_t_rto, 2 * hctx->ccid3hctx_t_ipi);
|
||||
t_nfb = max(hc->tx_t_rto, 2 * hc->tx_t_ipi);
|
||||
|
||||
ccid3_pr_debug("%s(%p), Scheduled no feedback timer to "
|
||||
"expire in %lu jiffies (%luus)\n",
|
||||
dccp_role(sk),
|
||||
sk, usecs_to_jiffies(t_nfb), t_nfb);
|
||||
dccp_role(sk), sk, usecs_to_jiffies(t_nfb), t_nfb);
|
||||
|
||||
sk_reset_timer(sk, &hctx->ccid3hctx_no_feedback_timer,
|
||||
sk_reset_timer(sk, &hc->tx_no_feedback_timer,
|
||||
jiffies + usecs_to_jiffies(t_nfb));
|
||||
}
|
||||
|
||||
@@ -510,11 +488,11 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
|
||||
{
|
||||
int rc = 0;
|
||||
const struct dccp_sock *dp = dccp_sk(sk);
|
||||
struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
|
||||
struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk);
|
||||
struct ccid3_options_received *opt_recv;
|
||||
__be32 opt_val;
|
||||
|
||||
opt_recv = &hctx->ccid3hctx_options_received;
|
||||
opt_recv = &hc->tx_options_received;
|
||||
|
||||
if (opt_recv->ccid3or_seqno != dp->dccps_gsr) {
|
||||
opt_recv->ccid3or_seqno = dp->dccps_gsr;
|
||||
@@ -568,56 +546,55 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
|
||||
|
||||
static int ccid3_hc_tx_init(struct ccid *ccid, struct sock *sk)
|
||||
{
|
||||
struct ccid3_hc_tx_sock *hctx = ccid_priv(ccid);
|
||||
struct ccid3_hc_tx_sock *hc = ccid_priv(ccid);
|
||||
|
||||
hctx->ccid3hctx_state = TFRC_SSTATE_NO_SENT;
|
||||
hctx->ccid3hctx_hist = NULL;
|
||||
setup_timer(&hctx->ccid3hctx_no_feedback_timer,
|
||||
hc->tx_state = TFRC_SSTATE_NO_SENT;
|
||||
hc->tx_hist = NULL;
|
||||
setup_timer(&hc->tx_no_feedback_timer,
|
||||
ccid3_hc_tx_no_feedback_timer, (unsigned long)sk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ccid3_hc_tx_exit(struct sock *sk)
|
||||
{
|
||||
struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
|
||||
struct ccid3_hc_tx_sock *hc = ccid3_hc_tx_sk(sk);
|
||||
|
||||
ccid3_hc_tx_set_state(sk, TFRC_SSTATE_TERM);
|
||||
sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer);
|
||||
sk_stop_timer(sk, &hc->tx_no_feedback_timer);
|
||||
|
||||
tfrc_tx_hist_purge(&hctx->ccid3hctx_hist);
|
||||
tfrc_tx_hist_purge(&hc->tx_hist);
|
||||
}
|
||||
|
||||
static void ccid3_hc_tx_get_info(struct sock *sk, struct tcp_info *info)
|
||||
{
|
||||
struct ccid3_hc_tx_sock *hctx;
|
||||
struct ccid3_hc_tx_sock *hc;
|
||||
|
||||
/* Listen socks doesn't have a private CCID block */
|
||||
if (sk->sk_state == DCCP_LISTEN)
|
||||
return;
|
||||
|
||||
hctx = ccid3_hc_tx_sk(sk);
|
||||
info->tcpi_rto = hctx->ccid3hctx_t_rto;
|
||||
info->tcpi_rtt = hctx->ccid3hctx_rtt;
|
||||
hc = ccid3_hc_tx_sk(sk);
|
||||
info->tcpi_rto = hc->tx_t_rto;
|
||||
info->tcpi_rtt = hc->tx_rtt;
|
||||
}
|
||||
|
||||
static int ccid3_hc_tx_getsockopt(struct sock *sk, const int optname, int len,
|
||||
u32 __user *optval, int __user *optlen)
|
||||
{
|
||||
const struct ccid3_hc_tx_sock *hctx;
|
||||
const struct ccid3_hc_tx_sock *hc;
|
||||
const void *val;
|
||||
|
||||
/* Listen socks doesn't have a private CCID block */
|
||||
if (sk->sk_state == DCCP_LISTEN)
|
||||
return -EINVAL;
|
||||
|
||||
hctx = ccid3_hc_tx_sk(sk);
|
||||
hc = ccid3_hc_tx_sk(sk);
|
||||
switch (optname) {
|
||||
case DCCP_SOCKOPT_CCID_TX_INFO:
|
||||
if (len < sizeof(hctx->ccid3hctx_tfrc))
|
||||
if (len < sizeof(hc->tx_tfrc))
|
||||
return -EINVAL;
|
||||
len = sizeof(hctx->ccid3hctx_tfrc);
|
||||
val = &hctx->ccid3hctx_tfrc;
|
||||
len = sizeof(hc->tx_tfrc);
|
||||
val = &hc->tx_tfrc;
|
||||
break;
|
||||
default:
|
||||
return -ENOPROTOOPT;
|
||||
@@ -657,34 +634,34 @@ static const char *ccid3_rx_state_name(enum ccid3_hc_rx_states state)
|
||||
static void ccid3_hc_rx_set_state(struct sock *sk,
|
||||
enum ccid3_hc_rx_states state)
|
||||
{
|
||||
struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
|
||||
enum ccid3_hc_rx_states oldstate = hcrx->ccid3hcrx_state;
|
||||
struct ccid3_hc_rx_sock *hc = ccid3_hc_rx_sk(sk);
|
||||
enum ccid3_hc_rx_states oldstate = hc->rx_state;
|
||||
|
||||
ccid3_pr_debug("%s(%p) %-8.8s -> %s\n",
|
||||
dccp_role(sk), sk, ccid3_rx_state_name(oldstate),
|
||||
ccid3_rx_state_name(state));
|
||||
WARN_ON(state == oldstate);
|
||||
hcrx->ccid3hcrx_state = state;
|
||||
hc->rx_state = state;
|
||||
}
|
||||
|
||||
static void ccid3_hc_rx_send_feedback(struct sock *sk,
|
||||
const struct sk_buff *skb,
|
||||
enum ccid3_fback_type fbtype)
|
||||
{
|
||||
struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
|
||||
struct ccid3_hc_rx_sock *hc = ccid3_hc_rx_sk(sk);
|
||||
struct dccp_sock *dp = dccp_sk(sk);
|
||||
ktime_t now;
|
||||
s64 delta = 0;
|
||||
|
||||
if (unlikely(hcrx->ccid3hcrx_state == TFRC_RSTATE_TERM))
|
||||
if (unlikely(hc->rx_state == TFRC_RSTATE_TERM))
|
||||
return;
|
||||
|
||||
now = ktime_get_real();
|
||||
|
||||
switch (fbtype) {
|
||||
case CCID3_FBACK_INITIAL:
|
||||
hcrx->ccid3hcrx_x_recv = 0;
|
||||
hcrx->ccid3hcrx_pinv = ~0U; /* see RFC 4342, 8.5 */
|
||||
hc->rx_x_recv = 0;
|
||||
hc->rx_pinv = ~0U; /* see RFC 4342, 8.5 */
|
||||
break;
|
||||
case CCID3_FBACK_PARAM_CHANGE:
|
||||
/*
|
||||
@@ -697,27 +674,26 @@ static void ccid3_hc_rx_send_feedback(struct sock *sk,
|
||||
* the number of bytes since last feedback.
|
||||
* This is a safe fallback, since X is bounded above by X_calc.
|
||||
*/
|
||||
if (hcrx->ccid3hcrx_x_recv > 0)
|
||||
if (hc->rx_x_recv > 0)
|
||||
break;
|
||||
/* fall through */
|
||||
case CCID3_FBACK_PERIODIC:
|
||||
delta = ktime_us_delta(now, hcrx->ccid3hcrx_tstamp_last_feedback);
|
||||
delta = ktime_us_delta(now, hc->rx_tstamp_last_feedback);
|
||||
if (delta <= 0)
|
||||
DCCP_BUG("delta (%ld) <= 0", (long)delta);
|
||||
else
|
||||
hcrx->ccid3hcrx_x_recv =
|
||||
scaled_div32(hcrx->ccid3hcrx_bytes_recv, delta);
|
||||
hc->rx_x_recv = scaled_div32(hc->rx_bytes_recv, delta);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
ccid3_pr_debug("Interval %ldusec, X_recv=%u, 1/p=%u\n", (long)delta,
|
||||
hcrx->ccid3hcrx_x_recv, hcrx->ccid3hcrx_pinv);
|
||||
hc->rx_x_recv, hc->rx_pinv);
|
||||
|
||||
hcrx->ccid3hcrx_tstamp_last_feedback = now;
|
||||
hcrx->ccid3hcrx_last_counter = dccp_hdr(skb)->dccph_ccval;
|
||||
hcrx->ccid3hcrx_bytes_recv = 0;
|
||||
hc->rx_tstamp_last_feedback = now;
|
||||
hc->rx_last_counter = dccp_hdr(skb)->dccph_ccval;
|
||||
hc->rx_bytes_recv = 0;
|
||||
|
||||
dp->dccps_hc_rx_insert_options = 1;
|
||||
dccp_send_ack(sk);
|
||||
@@ -725,19 +701,19 @@ static void ccid3_hc_rx_send_feedback(struct sock *sk,
|
||||
|
||||
static int ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
const struct ccid3_hc_rx_sock *hcrx;
|
||||
const struct ccid3_hc_rx_sock *hc;
|
||||
__be32 x_recv, pinv;
|
||||
|
||||
if (!(sk->sk_state == DCCP_OPEN || sk->sk_state == DCCP_PARTOPEN))
|
||||
return 0;
|
||||
|
||||
hcrx = ccid3_hc_rx_sk(sk);
|
||||
hc = ccid3_hc_rx_sk(sk);
|
||||
|
||||
if (dccp_packet_without_ack(skb))
|
||||
return 0;
|
||||
|
||||
x_recv = htonl(hcrx->ccid3hcrx_x_recv);
|
||||
pinv = htonl(hcrx->ccid3hcrx_pinv);
|
||||
x_recv = htonl(hc->rx_x_recv);
|
||||
pinv = htonl(hc->rx_pinv);
|
||||
|
||||
if (dccp_insert_option(sk, skb, TFRC_OPT_LOSS_EVENT_RATE,
|
||||
&pinv, sizeof(pinv)) ||
|
||||
@@ -760,26 +736,26 @@ static int ccid3_hc_rx_insert_options(struct sock *sk, struct sk_buff *skb)
|
||||
*/
|
||||
static u32 ccid3_first_li(struct sock *sk)
|
||||
{
|
||||
struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
|
||||
struct ccid3_hc_rx_sock *hc = ccid3_hc_rx_sk(sk);
|
||||
u32 x_recv, p, delta;
|
||||
u64 fval;
|
||||
|
||||
if (hcrx->ccid3hcrx_rtt == 0) {
|
||||
if (hc->rx_rtt == 0) {
|
||||
DCCP_WARN("No RTT estimate available, using fallback RTT\n");
|
||||
hcrx->ccid3hcrx_rtt = DCCP_FALLBACK_RTT;
|
||||
hc->rx_rtt = DCCP_FALLBACK_RTT;
|
||||
}
|
||||
|
||||
delta = ktime_to_us(net_timedelta(hcrx->ccid3hcrx_tstamp_last_feedback));
|
||||
x_recv = scaled_div32(hcrx->ccid3hcrx_bytes_recv, delta);
|
||||
delta = ktime_to_us(net_timedelta(hc->rx_tstamp_last_feedback));
|
||||
x_recv = scaled_div32(hc->rx_bytes_recv, delta);
|
||||
if (x_recv == 0) { /* would also trigger divide-by-zero */
|
||||
DCCP_WARN("X_recv==0\n");
|
||||
if ((x_recv = hcrx->ccid3hcrx_x_recv) == 0) {
|
||||
if ((x_recv = hc->rx_x_recv) == 0) {
|
||||
DCCP_BUG("stored value of X_recv is zero");
|
||||
return ~0U;
|
||||
}
|
||||
}
|
||||
|
||||
fval = scaled_div(hcrx->ccid3hcrx_s, hcrx->ccid3hcrx_rtt);
|
||||
fval = scaled_div(hc->rx_s, hc->rx_rtt);
|
||||
fval = scaled_div32(fval, x_recv);
|
||||
p = tfrc_calc_x_reverse_lookup(fval);
|
||||
|
||||
@@ -791,19 +767,19 @@ static u32 ccid3_first_li(struct sock *sk)
|
||||
|
||||
static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
|
||||
{
|
||||
struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
|
||||
struct ccid3_hc_rx_sock *hc = ccid3_hc_rx_sk(sk);
|
||||
enum ccid3_fback_type do_feedback = CCID3_FBACK_NONE;
|
||||
const u64 ndp = dccp_sk(sk)->dccps_options_received.dccpor_ndp;
|
||||
const bool is_data_packet = dccp_data_packet(skb);
|
||||
|
||||
if (unlikely(hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA)) {
|
||||
if (unlikely(hc->rx_state == TFRC_RSTATE_NO_DATA)) {
|
||||
if (is_data_packet) {
|
||||
const u32 payload = skb->len - dccp_hdr(skb)->dccph_doff * 4;
|
||||
do_feedback = CCID3_FBACK_INITIAL;
|
||||
ccid3_hc_rx_set_state(sk, TFRC_RSTATE_DATA);
|
||||
hcrx->ccid3hcrx_s = payload;
|
||||
hc->rx_s = payload;
|
||||
/*
|
||||
* Not necessary to update ccid3hcrx_bytes_recv here,
|
||||
* Not necessary to update rx_bytes_recv here,
|
||||
* since X_recv = 0 for the first feedback packet (cf.
|
||||
* RFC 3448, 6.3) -- gerrit
|
||||
*/
|
||||
@@ -811,7 +787,7 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
|
||||
goto update_records;
|
||||
}
|
||||
|
||||
if (tfrc_rx_hist_duplicate(&hcrx->ccid3hcrx_hist, skb))
|
||||
if (tfrc_rx_hist_duplicate(&hc->rx_hist, skb))
|
||||
return; /* done receiving */
|
||||
|
||||
if (is_data_packet) {
|
||||
@@ -819,20 +795,20 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
|
||||
/*
|
||||
* Update moving-average of s and the sum of received payload bytes
|
||||
*/
|
||||
hcrx->ccid3hcrx_s = tfrc_ewma(hcrx->ccid3hcrx_s, payload, 9);
|
||||
hcrx->ccid3hcrx_bytes_recv += payload;
|
||||
hc->rx_s = tfrc_ewma(hc->rx_s, payload, 9);
|
||||
hc->rx_bytes_recv += payload;
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform loss detection and handle pending losses
|
||||
*/
|
||||
if (tfrc_rx_handle_loss(&hcrx->ccid3hcrx_hist, &hcrx->ccid3hcrx_li_hist,
|
||||
if (tfrc_rx_handle_loss(&hc->rx_hist, &hc->rx_li_hist,
|
||||
skb, ndp, ccid3_first_li, sk)) {
|
||||
do_feedback = CCID3_FBACK_PARAM_CHANGE;
|
||||
goto done_receiving;
|
||||
}
|
||||
|
||||
if (tfrc_rx_hist_loss_pending(&hcrx->ccid3hcrx_hist))
|
||||
if (tfrc_rx_hist_loss_pending(&hc->rx_hist))
|
||||
return; /* done receiving */
|
||||
|
||||
/*
|
||||
@@ -841,17 +817,17 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
|
||||
if (unlikely(!is_data_packet))
|
||||
goto update_records;
|
||||
|
||||
if (!tfrc_lh_is_initialised(&hcrx->ccid3hcrx_li_hist)) {
|
||||
const u32 sample = tfrc_rx_hist_sample_rtt(&hcrx->ccid3hcrx_hist, skb);
|
||||
if (!tfrc_lh_is_initialised(&hc->rx_li_hist)) {
|
||||
const u32 sample = tfrc_rx_hist_sample_rtt(&hc->rx_hist, skb);
|
||||
/*
|
||||
* Empty loss history: no loss so far, hence p stays 0.
|
||||
* Sample RTT values, since an RTT estimate is required for the
|
||||
* computation of p when the first loss occurs; RFC 3448, 6.3.1.
|
||||
*/
|
||||
if (sample != 0)
|
||||
hcrx->ccid3hcrx_rtt = tfrc_ewma(hcrx->ccid3hcrx_rtt, sample, 9);
|
||||
hc->rx_rtt = tfrc_ewma(hc->rx_rtt, sample, 9);
|
||||
|
||||
} else if (tfrc_lh_update_i_mean(&hcrx->ccid3hcrx_li_hist, skb)) {
|
||||
} else if (tfrc_lh_update_i_mean(&hc->rx_li_hist, skb)) {
|
||||
/*
|
||||
* Step (3) of [RFC 3448, 6.1]: Recompute I_mean and, if I_mean
|
||||
* has decreased (resp. p has increased), send feedback now.
|
||||
@@ -862,11 +838,11 @@ static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff *skb)
|
||||
/*
|
||||
* Check if the periodic once-per-RTT feedback is due; RFC 4342, 10.3
|
||||
*/
|
||||
if (SUB16(dccp_hdr(skb)->dccph_ccval, hcrx->ccid3hcrx_last_counter) > 3)
|
||||
if (SUB16(dccp_hdr(skb)->dccph_ccval, hc->rx_last_counter) > 3)
|
||||
do_feedback = CCID3_FBACK_PERIODIC;
|
||||
|
||||
update_records:
|
||||
tfrc_rx_hist_add_packet(&hcrx->ccid3hcrx_hist, skb, ndp);
|
||||
tfrc_rx_hist_add_packet(&hc->rx_hist, skb, ndp);
|
||||
|
||||
done_receiving:
|
||||
if (do_feedback)
|
||||
@@ -875,41 +851,41 @@ done_receiving:
|
||||
|
||||
static int ccid3_hc_rx_init(struct ccid *ccid, struct sock *sk)
|
||||
{
|
||||
struct ccid3_hc_rx_sock *hcrx = ccid_priv(ccid);
|
||||
struct ccid3_hc_rx_sock *hc = ccid_priv(ccid);
|
||||
|
||||
hcrx->ccid3hcrx_state = TFRC_RSTATE_NO_DATA;
|
||||
tfrc_lh_init(&hcrx->ccid3hcrx_li_hist);
|
||||
return tfrc_rx_hist_alloc(&hcrx->ccid3hcrx_hist);
|
||||
hc->rx_state = TFRC_RSTATE_NO_DATA;
|
||||
tfrc_lh_init(&hc->rx_li_hist);
|
||||
return tfrc_rx_hist_alloc(&hc->rx_hist);
|
||||
}
|
||||
|
||||
static void ccid3_hc_rx_exit(struct sock *sk)
|
||||
{
|
||||
struct ccid3_hc_rx_sock *hcrx = ccid3_hc_rx_sk(sk);
|
||||
struct ccid3_hc_rx_sock *hc = ccid3_hc_rx_sk(sk);
|
||||
|
||||
ccid3_hc_rx_set_state(sk, TFRC_RSTATE_TERM);
|
||||
|
||||
tfrc_rx_hist_purge(&hcrx->ccid3hcrx_hist);
|
||||
tfrc_lh_cleanup(&hcrx->ccid3hcrx_li_hist);
|
||||
tfrc_rx_hist_purge(&hc->rx_hist);
|
||||
tfrc_lh_cleanup(&hc->rx_li_hist);
|
||||
}
|
||||
|
||||
static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info)
|
||||
{
|
||||
const struct ccid3_hc_rx_sock *hcrx;
|
||||
const struct ccid3_hc_rx_sock *hc;
|
||||
|
||||
/* Listen socks doesn't have a private CCID block */
|
||||
if (sk->sk_state == DCCP_LISTEN)
|
||||
return;
|
||||
|
||||
hcrx = ccid3_hc_rx_sk(sk);
|
||||
info->tcpi_ca_state = hcrx->ccid3hcrx_state;
|
||||
hc = ccid3_hc_rx_sk(sk);
|
||||
info->tcpi_ca_state = hc->rx_state;
|
||||
info->tcpi_options |= TCPI_OPT_TIMESTAMPS;
|
||||
info->tcpi_rcv_rtt = hcrx->ccid3hcrx_rtt;
|
||||
info->tcpi_rcv_rtt = hc->rx_rtt;
|
||||
}
|
||||
|
||||
static int ccid3_hc_rx_getsockopt(struct sock *sk, const int optname, int len,
|
||||
u32 __user *optval, int __user *optlen)
|
||||
{
|
||||
const struct ccid3_hc_rx_sock *hcrx;
|
||||
const struct ccid3_hc_rx_sock *hc;
|
||||
struct tfrc_rx_info rx_info;
|
||||
const void *val;
|
||||
|
||||
@@ -917,15 +893,15 @@ static int ccid3_hc_rx_getsockopt(struct sock *sk, const int optname, int len,
|
||||
if (sk->sk_state == DCCP_LISTEN)
|
||||
return -EINVAL;
|
||||
|
||||
hcrx = ccid3_hc_rx_sk(sk);
|
||||
hc = ccid3_hc_rx_sk(sk);
|
||||
switch (optname) {
|
||||
case DCCP_SOCKOPT_CCID_RX_INFO:
|
||||
if (len < sizeof(rx_info))
|
||||
return -EINVAL;
|
||||
rx_info.tfrcrx_x_recv = hcrx->ccid3hcrx_x_recv;
|
||||
rx_info.tfrcrx_rtt = hcrx->ccid3hcrx_rtt;
|
||||
rx_info.tfrcrx_p = hcrx->ccid3hcrx_pinv == 0 ? ~0U :
|
||||
scaled_div(1, hcrx->ccid3hcrx_pinv);
|
||||
rx_info.tfrcrx_x_recv = hc->rx_x_recv;
|
||||
rx_info.tfrcrx_rtt = hc->rx_rtt;
|
||||
rx_info.tfrcrx_p = hc->rx_pinv == 0 ? ~0U :
|
||||
scaled_div(1, hc->rx_pinv);
|
||||
len = sizeof(rx_info);
|
||||
val = &rx_info;
|
||||
break;
|
||||
|
@@ -75,44 +75,44 @@ enum ccid3_hc_tx_states {
|
||||
|
||||
/**
|
||||
* struct ccid3_hc_tx_sock - CCID3 sender half-connection socket
|
||||
* @ccid3hctx_x - Current sending rate in 64 * bytes per second
|
||||
* @ccid3hctx_x_recv - Receive rate in 64 * bytes per second
|
||||
* @ccid3hctx_x_calc - Calculated rate in bytes per second
|
||||
* @ccid3hctx_rtt - Estimate of current round trip time in usecs
|
||||
* @ccid3hctx_p - Current loss event rate (0-1) scaled by 1000000
|
||||
* @ccid3hctx_s - Packet size in bytes
|
||||
* @ccid3hctx_t_rto - Nofeedback Timer setting in usecs
|
||||
* @ccid3hctx_t_ipi - Interpacket (send) interval (RFC 3448, 4.6) in usecs
|
||||
* @ccid3hctx_state - Sender state, one of %ccid3_hc_tx_states
|
||||
* @ccid3hctx_last_win_count - Last window counter sent
|
||||
* @ccid3hctx_t_last_win_count - Timestamp of earliest packet
|
||||
* with last_win_count value sent
|
||||
* @ccid3hctx_no_feedback_timer - Handle to no feedback timer
|
||||
* @ccid3hctx_t_ld - Time last doubled during slow start
|
||||
* @ccid3hctx_t_nom - Nominal send time of next packet
|
||||
* @ccid3hctx_delta - Send timer delta (RFC 3448, 4.6) in usecs
|
||||
* @ccid3hctx_hist - Packet history
|
||||
* @ccid3hctx_options_received - Parsed set of retrieved options
|
||||
* @tx_x: Current sending rate in 64 * bytes per second
|
||||
* @tx_x_recv: Receive rate in 64 * bytes per second
|
||||
* @tx_x_calc: Calculated rate in bytes per second
|
||||
* @tx_rtt: Estimate of current round trip time in usecs
|
||||
* @tx_p: Current loss event rate (0-1) scaled by 1000000
|
||||
* @tx_s: Packet size in bytes
|
||||
* @tx_t_rto: Nofeedback Timer setting in usecs
|
||||
* @tx_t_ipi: Interpacket (send) interval (RFC 3448, 4.6) in usecs
|
||||
* @tx_state: Sender state, one of %ccid3_hc_tx_states
|
||||
* @tx_last_win_count: Last window counter sent
|
||||
* @tx_t_last_win_count: Timestamp of earliest packet
|
||||
* with last_win_count value sent
|
||||
* @tx_no_feedback_timer: Handle to no feedback timer
|
||||
* @tx_t_ld: Time last doubled during slow start
|
||||
* @tx_t_nom: Nominal send time of next packet
|
||||
* @tx_delta: Send timer delta (RFC 3448, 4.6) in usecs
|
||||
* @tx_hist: Packet history
|
||||
* @tx_options_received: Parsed set of retrieved options
|
||||
*/
|
||||
struct ccid3_hc_tx_sock {
|
||||
struct tfrc_tx_info ccid3hctx_tfrc;
|
||||
#define ccid3hctx_x ccid3hctx_tfrc.tfrctx_x
|
||||
#define ccid3hctx_x_recv ccid3hctx_tfrc.tfrctx_x_recv
|
||||
#define ccid3hctx_x_calc ccid3hctx_tfrc.tfrctx_x_calc
|
||||
#define ccid3hctx_rtt ccid3hctx_tfrc.tfrctx_rtt
|
||||
#define ccid3hctx_p ccid3hctx_tfrc.tfrctx_p
|
||||
#define ccid3hctx_t_rto ccid3hctx_tfrc.tfrctx_rto
|
||||
#define ccid3hctx_t_ipi ccid3hctx_tfrc.tfrctx_ipi
|
||||
u16 ccid3hctx_s;
|
||||
enum ccid3_hc_tx_states ccid3hctx_state:8;
|
||||
u8 ccid3hctx_last_win_count;
|
||||
ktime_t ccid3hctx_t_last_win_count;
|
||||
struct timer_list ccid3hctx_no_feedback_timer;
|
||||
ktime_t ccid3hctx_t_ld;
|
||||
ktime_t ccid3hctx_t_nom;
|
||||
u32 ccid3hctx_delta;
|
||||
struct tfrc_tx_hist_entry *ccid3hctx_hist;
|
||||
struct ccid3_options_received ccid3hctx_options_received;
|
||||
struct tfrc_tx_info tx_tfrc;
|
||||
#define tx_x tx_tfrc.tfrctx_x
|
||||
#define tx_x_recv tx_tfrc.tfrctx_x_recv
|
||||
#define tx_x_calc tx_tfrc.tfrctx_x_calc
|
||||
#define tx_rtt tx_tfrc.tfrctx_rtt
|
||||
#define tx_p tx_tfrc.tfrctx_p
|
||||
#define tx_t_rto tx_tfrc.tfrctx_rto
|
||||
#define tx_t_ipi tx_tfrc.tfrctx_ipi
|
||||
u16 tx_s;
|
||||
enum ccid3_hc_tx_states tx_state:8;
|
||||
u8 tx_last_win_count;
|
||||
ktime_t tx_t_last_win_count;
|
||||
struct timer_list tx_no_feedback_timer;
|
||||
ktime_t tx_t_ld;
|
||||
ktime_t tx_t_nom;
|
||||
u32 tx_delta;
|
||||
struct tfrc_tx_hist_entry *tx_hist;
|
||||
struct ccid3_options_received tx_options_received;
|
||||
};
|
||||
|
||||
static inline struct ccid3_hc_tx_sock *ccid3_hc_tx_sk(const struct sock *sk)
|
||||
@@ -131,32 +131,32 @@ enum ccid3_hc_rx_states {
|
||||
|
||||
/**
|
||||
* struct ccid3_hc_rx_sock - CCID3 receiver half-connection socket
|
||||
* @ccid3hcrx_x_recv - Receiver estimate of send rate (RFC 3448 4.3)
|
||||
* @ccid3hcrx_rtt - Receiver estimate of rtt (non-standard)
|
||||
* @ccid3hcrx_p - Current loss event rate (RFC 3448 5.4)
|
||||
* @ccid3hcrx_last_counter - Tracks window counter (RFC 4342, 8.1)
|
||||
* @ccid3hcrx_state - Receiver state, one of %ccid3_hc_rx_states
|
||||
* @ccid3hcrx_bytes_recv - Total sum of DCCP payload bytes
|
||||
* @ccid3hcrx_x_recv - Receiver estimate of send rate (RFC 3448, sec. 4.3)
|
||||
* @ccid3hcrx_rtt - Receiver estimate of RTT
|
||||
* @ccid3hcrx_tstamp_last_feedback - Time at which last feedback was sent
|
||||
* @ccid3hcrx_tstamp_last_ack - Time at which last feedback was sent
|
||||
* @ccid3hcrx_hist - Packet history (loss detection + RTT sampling)
|
||||
* @ccid3hcrx_li_hist - Loss Interval database
|
||||
* @ccid3hcrx_s - Received packet size in bytes
|
||||
* @ccid3hcrx_pinv - Inverse of Loss Event Rate (RFC 4342, sec. 8.5)
|
||||
* @rx_x_recv: Receiver estimate of send rate (RFC 3448 4.3)
|
||||
* @rx_rtt: Receiver estimate of rtt (non-standard)
|
||||
* @rx_p: Current loss event rate (RFC 3448 5.4)
|
||||
* @rx_last_counter: Tracks window counter (RFC 4342, 8.1)
|
||||
* @rx_state: Receiver state, one of %ccid3_hc_rx_states
|
||||
* @rx_bytes_recv: Total sum of DCCP payload bytes
|
||||
* @rx_x_recv: Receiver estimate of send rate (RFC 3448, sec. 4.3)
|
||||
* @rx_rtt: Receiver estimate of RTT
|
||||
* @rx_tstamp_last_feedback: Time at which last feedback was sent
|
||||
* @rx_tstamp_last_ack: Time at which last feedback was sent
|
||||
* @rx_hist: Packet history (loss detection + RTT sampling)
|
||||
* @rx_li_hist: Loss Interval database
|
||||
* @rx_s: Received packet size in bytes
|
||||
* @rx_pinv: Inverse of Loss Event Rate (RFC 4342, sec. 8.5)
|
||||
*/
|
||||
struct ccid3_hc_rx_sock {
|
||||
u8 ccid3hcrx_last_counter:4;
|
||||
enum ccid3_hc_rx_states ccid3hcrx_state:8;
|
||||
u32 ccid3hcrx_bytes_recv;
|
||||
u32 ccid3hcrx_x_recv;
|
||||
u32 ccid3hcrx_rtt;
|
||||
ktime_t ccid3hcrx_tstamp_last_feedback;
|
||||
struct tfrc_rx_hist ccid3hcrx_hist;
|
||||
struct tfrc_loss_hist ccid3hcrx_li_hist;
|
||||
u16 ccid3hcrx_s;
|
||||
#define ccid3hcrx_pinv ccid3hcrx_li_hist.i_mean
|
||||
u8 rx_last_counter:4;
|
||||
enum ccid3_hc_rx_states rx_state:8;
|
||||
u32 rx_bytes_recv;
|
||||
u32 rx_x_recv;
|
||||
u32 rx_rtt;
|
||||
ktime_t rx_tstamp_last_feedback;
|
||||
struct tfrc_rx_hist rx_hist;
|
||||
struct tfrc_loss_hist rx_li_hist;
|
||||
u16 rx_s;
|
||||
#define rx_pinv rx_li_hist.i_mean
|
||||
};
|
||||
|
||||
static inline struct ccid3_hc_rx_sock *ccid3_hc_rx_sk(const struct sock *sk)
|
||||
|
@@ -62,10 +62,10 @@ int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
|
||||
nexthop = inet->opt->faddr;
|
||||
}
|
||||
|
||||
tmp = ip_route_connect(&rt, nexthop, inet->saddr,
|
||||
tmp = ip_route_connect(&rt, nexthop, inet->inet_saddr,
|
||||
RT_CONN_FLAGS(sk), sk->sk_bound_dev_if,
|
||||
IPPROTO_DCCP,
|
||||
inet->sport, usin->sin_port, sk, 1);
|
||||
inet->inet_sport, usin->sin_port, sk, 1);
|
||||
if (tmp < 0)
|
||||
return tmp;
|
||||
|
||||
@@ -77,12 +77,12 @@ int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
|
||||
if (inet->opt == NULL || !inet->opt->srr)
|
||||
daddr = rt->rt_dst;
|
||||
|
||||
if (inet->saddr == 0)
|
||||
inet->saddr = rt->rt_src;
|
||||
inet->rcv_saddr = inet->saddr;
|
||||
if (inet->inet_saddr == 0)
|
||||
inet->inet_saddr = rt->rt_src;
|
||||
inet->inet_rcv_saddr = inet->inet_saddr;
|
||||
|
||||
inet->dport = usin->sin_port;
|
||||
inet->daddr = daddr;
|
||||
inet->inet_dport = usin->sin_port;
|
||||
inet->inet_daddr = daddr;
|
||||
|
||||
inet_csk(sk)->icsk_ext_hdr_len = 0;
|
||||
if (inet->opt != NULL)
|
||||
@@ -98,17 +98,19 @@ int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
|
||||
if (err != 0)
|
||||
goto failure;
|
||||
|
||||
err = ip_route_newports(&rt, IPPROTO_DCCP, inet->sport, inet->dport,
|
||||
sk);
|
||||
err = ip_route_newports(&rt, IPPROTO_DCCP, inet->inet_sport,
|
||||
inet->inet_dport, sk);
|
||||
if (err != 0)
|
||||
goto failure;
|
||||
|
||||
/* OK, now commit destination to socket. */
|
||||
sk_setup_caps(sk, &rt->u.dst);
|
||||
|
||||
dp->dccps_iss = secure_dccp_sequence_number(inet->saddr, inet->daddr,
|
||||
inet->sport, inet->dport);
|
||||
inet->id = dp->dccps_iss ^ jiffies;
|
||||
dp->dccps_iss = secure_dccp_sequence_number(inet->inet_saddr,
|
||||
inet->inet_daddr,
|
||||
inet->inet_sport,
|
||||
inet->inet_dport);
|
||||
inet->inet_id = dp->dccps_iss ^ jiffies;
|
||||
|
||||
err = dccp_connect(sk);
|
||||
rt = NULL;
|
||||
@@ -123,7 +125,7 @@ failure:
|
||||
dccp_set_state(sk, DCCP_CLOSED);
|
||||
ip_rt_put(rt);
|
||||
sk->sk_route_caps = 0;
|
||||
inet->dport = 0;
|
||||
inet->inet_dport = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -352,7 +354,9 @@ void dccp_v4_send_check(struct sock *sk, int unused, struct sk_buff *skb)
|
||||
struct dccp_hdr *dh = dccp_hdr(skb);
|
||||
|
||||
dccp_csum_outgoing(skb);
|
||||
dh->dccph_checksum = dccp_v4_csum_finish(skb, inet->saddr, inet->daddr);
|
||||
dh->dccph_checksum = dccp_v4_csum_finish(skb,
|
||||
inet->inet_saddr,
|
||||
inet->inet_daddr);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL_GPL(dccp_v4_send_check);
|
||||
@@ -393,14 +397,14 @@ struct sock *dccp_v4_request_recv_sock(struct sock *sk, struct sk_buff *skb,
|
||||
|
||||
newinet = inet_sk(newsk);
|
||||
ireq = inet_rsk(req);
|
||||
newinet->daddr = ireq->rmt_addr;
|
||||
newinet->rcv_saddr = ireq->loc_addr;
|
||||
newinet->saddr = ireq->loc_addr;
|
||||
newinet->inet_daddr = ireq->rmt_addr;
|
||||
newinet->inet_rcv_saddr = ireq->loc_addr;
|
||||
newinet->inet_saddr = ireq->loc_addr;
|
||||
newinet->opt = ireq->opt;
|
||||
ireq->opt = NULL;
|
||||
newinet->mc_index = inet_iif(skb);
|
||||
newinet->mc_ttl = ip_hdr(skb)->ttl;
|
||||
newinet->id = jiffies;
|
||||
newinet->inet_id = jiffies;
|
||||
|
||||
dccp_sync_mss(newsk, dst_mtu(dst));
|
||||
|
||||
@@ -473,7 +477,8 @@ static struct dst_entry* dccp_v4_route_skb(struct net *net, struct sock *sk,
|
||||
return &rt->u.dst;
|
||||
}
|
||||
|
||||
static int dccp_v4_send_response(struct sock *sk, struct request_sock *req)
|
||||
static int dccp_v4_send_response(struct sock *sk, struct request_sock *req,
|
||||
struct request_values *rv_unused)
|
||||
{
|
||||
int err = -1;
|
||||
struct sk_buff *skb;
|
||||
@@ -622,7 +627,7 @@ int dccp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
|
||||
dreq->dreq_iss = dccp_v4_init_sequence(skb);
|
||||
dreq->dreq_service = service;
|
||||
|
||||
if (dccp_v4_send_response(sk, req))
|
||||
if (dccp_v4_send_response(sk, req, NULL))
|
||||
goto drop_and_free;
|
||||
|
||||
inet_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT);
|
||||
@@ -987,7 +992,6 @@ static struct inet_protosw dccp_v4_protosw = {
|
||||
.protocol = IPPROTO_DCCP,
|
||||
.prot = &dccp_v4_prot,
|
||||
.ops = &inet_dccp_ops,
|
||||
.capability = -1,
|
||||
.no_check = 0,
|
||||
.flags = INET_PROTOSW_ICSK,
|
||||
};
|
||||
|
@@ -158,8 +158,8 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
|
||||
ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
|
||||
ipv6_addr_copy(&fl.fl6_src, &np->saddr);
|
||||
fl.oif = sk->sk_bound_dev_if;
|
||||
fl.fl_ip_dport = inet->dport;
|
||||
fl.fl_ip_sport = inet->sport;
|
||||
fl.fl_ip_dport = inet->inet_dport;
|
||||
fl.fl_ip_sport = inet->inet_sport;
|
||||
security_sk_classify_flow(sk, &fl);
|
||||
|
||||
err = ip6_dst_lookup(sk, &dst, &fl);
|
||||
@@ -241,7 +241,8 @@ out:
|
||||
}
|
||||
|
||||
|
||||
static int dccp_v6_send_response(struct sock *sk, struct request_sock *req)
|
||||
static int dccp_v6_send_response(struct sock *sk, struct request_sock *req,
|
||||
struct request_values *rv_unused)
|
||||
{
|
||||
struct inet6_request_sock *ireq6 = inet6_rsk(req);
|
||||
struct ipv6_pinfo *np = inet6_sk(sk);
|
||||
@@ -468,7 +469,7 @@ static int dccp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
|
||||
dreq->dreq_iss = dccp_v6_init_sequence(skb);
|
||||
dreq->dreq_service = service;
|
||||
|
||||
if (dccp_v6_send_response(sk, req))
|
||||
if (dccp_v6_send_response(sk, req, NULL))
|
||||
goto drop_and_free;
|
||||
|
||||
inet6_csk_reqsk_queue_hash_add(sk, req, DCCP_TIMEOUT_INIT);
|
||||
@@ -510,11 +511,9 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
|
||||
|
||||
memcpy(newnp, np, sizeof(struct ipv6_pinfo));
|
||||
|
||||
ipv6_addr_set(&newnp->daddr, 0, 0, htonl(0x0000FFFF),
|
||||
newinet->daddr);
|
||||
ipv6_addr_set_v4mapped(newinet->inet_daddr, &newnp->daddr);
|
||||
|
||||
ipv6_addr_set(&newnp->saddr, 0, 0, htonl(0x0000FFFF),
|
||||
newinet->saddr);
|
||||
ipv6_addr_set_v4mapped(newinet->inet_saddr, &newnp->saddr);
|
||||
|
||||
ipv6_addr_copy(&newnp->rcv_saddr, &newnp->saddr);
|
||||
|
||||
@@ -642,7 +641,8 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
|
||||
|
||||
dccp_sync_mss(newsk, dst_mtu(dst));
|
||||
|
||||
newinet->daddr = newinet->saddr = newinet->rcv_saddr = LOOPBACK4_IPV6;
|
||||
newinet->inet_daddr = newinet->inet_saddr = LOOPBACK4_IPV6;
|
||||
newinet->inet_rcv_saddr = LOOPBACK4_IPV6;
|
||||
|
||||
__inet6_hash(newsk);
|
||||
__inet_inherit_port(sk, newsk);
|
||||
@@ -970,12 +970,9 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
|
||||
icsk->icsk_af_ops = &dccp_ipv6_af_ops;
|
||||
sk->sk_backlog_rcv = dccp_v6_do_rcv;
|
||||
goto failure;
|
||||
} else {
|
||||
ipv6_addr_set(&np->saddr, 0, 0, htonl(0x0000FFFF),
|
||||
inet->saddr);
|
||||
ipv6_addr_set(&np->rcv_saddr, 0, 0, htonl(0x0000FFFF),
|
||||
inet->rcv_saddr);
|
||||
}
|
||||
ipv6_addr_set_v4mapped(inet->inet_saddr, &np->saddr);
|
||||
ipv6_addr_set_v4mapped(inet->inet_rcv_saddr, &np->rcv_saddr);
|
||||
|
||||
return err;
|
||||
}
|
||||
@@ -988,7 +985,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
|
||||
ipv6_addr_copy(&fl.fl6_src, saddr ? saddr : &np->saddr);
|
||||
fl.oif = sk->sk_bound_dev_if;
|
||||
fl.fl_ip_dport = usin->sin6_port;
|
||||
fl.fl_ip_sport = inet->sport;
|
||||
fl.fl_ip_sport = inet->inet_sport;
|
||||
security_sk_classify_flow(sk, &fl);
|
||||
|
||||
if (np->opt != NULL && np->opt->srcrt != NULL) {
|
||||
@@ -1021,7 +1018,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
|
||||
|
||||
/* set the source address */
|
||||
ipv6_addr_copy(&np->saddr, saddr);
|
||||
inet->rcv_saddr = LOOPBACK4_IPV6;
|
||||
inet->inet_rcv_saddr = LOOPBACK4_IPV6;
|
||||
|
||||
__ip6_dst_store(sk, dst, NULL, NULL);
|
||||
|
||||
@@ -1030,7 +1027,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
|
||||
icsk->icsk_ext_hdr_len = (np->opt->opt_flen +
|
||||
np->opt->opt_nflen);
|
||||
|
||||
inet->dport = usin->sin6_port;
|
||||
inet->inet_dport = usin->sin6_port;
|
||||
|
||||
dccp_set_state(sk, DCCP_REQUESTING);
|
||||
err = inet6_hash_connect(&dccp_death_row, sk);
|
||||
@@ -1039,7 +1036,8 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
|
||||
|
||||
dp->dccps_iss = secure_dccpv6_sequence_number(np->saddr.s6_addr32,
|
||||
np->daddr.s6_addr32,
|
||||
inet->sport, inet->dport);
|
||||
inet->inet_sport,
|
||||
inet->inet_dport);
|
||||
err = dccp_connect(sk);
|
||||
if (err)
|
||||
goto late_failure;
|
||||
@@ -1050,7 +1048,7 @@ late_failure:
|
||||
dccp_set_state(sk, DCCP_CLOSED);
|
||||
__sk_dst_reset(sk);
|
||||
failure:
|
||||
inet->dport = 0;
|
||||
inet->inet_dport = 0;
|
||||
sk->sk_route_caps = 0;
|
||||
return err;
|
||||
}
|
||||
@@ -1188,7 +1186,6 @@ static struct inet_protosw dccp_v6_protosw = {
|
||||
.protocol = IPPROTO_DCCP,
|
||||
.prot = &dccp_v6_prot,
|
||||
.ops = &inet6_dccp_ops,
|
||||
.capability = -1,
|
||||
.flags = INET_PROTOSW_ICSK,
|
||||
};
|
||||
|
||||
|
@@ -184,7 +184,7 @@ struct sock *dccp_check_req(struct sock *sk, struct sk_buff *skb,
|
||||
* counter (backoff, monitored by dccp_response_timer).
|
||||
*/
|
||||
req->retrans++;
|
||||
req->rsk_ops->rtx_syn_ack(sk, req);
|
||||
req->rsk_ops->rtx_syn_ack(sk, req, NULL);
|
||||
}
|
||||
/* Network Duplicate, discard packet */
|
||||
return NULL;
|
||||
|
@@ -99,8 +99,8 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
|
||||
/* Build DCCP header and checksum it. */
|
||||
dh = dccp_zeroed_hdr(skb, dccp_header_size);
|
||||
dh->dccph_type = dcb->dccpd_type;
|
||||
dh->dccph_sport = inet->sport;
|
||||
dh->dccph_dport = inet->dport;
|
||||
dh->dccph_sport = inet->inet_sport;
|
||||
dh->dccph_dport = inet->inet_dport;
|
||||
dh->dccph_doff = (dccp_header_size + dcb->dccpd_opt_len) / 4;
|
||||
dh->dccph_ccval = dcb->dccpd_ccval;
|
||||
dh->dccph_cscov = dp->dccps_pcslen;
|
||||
|
@@ -75,26 +75,25 @@ static int jdccp_sendmsg(struct kiocb *iocb, struct sock *sk,
|
||||
struct msghdr *msg, size_t size)
|
||||
{
|
||||
const struct inet_sock *inet = inet_sk(sk);
|
||||
struct ccid3_hc_tx_sock *hctx = NULL;
|
||||
struct ccid3_hc_tx_sock *hc = NULL;
|
||||
|
||||
if (ccid_get_current_tx_ccid(dccp_sk(sk)) == DCCPC_CCID3)
|
||||
hctx = ccid3_hc_tx_sk(sk);
|
||||
hc = ccid3_hc_tx_sk(sk);
|
||||
|
||||
if (port == 0 || ntohs(inet->dport) == port ||
|
||||
ntohs(inet->sport) == port) {
|
||||
if (hctx)
|
||||
printl("%pI4:%u %pI4:%u %d %d %d %d %u "
|
||||
"%llu %llu %d\n",
|
||||
&inet->saddr, ntohs(inet->sport),
|
||||
&inet->daddr, ntohs(inet->dport), size,
|
||||
hctx->ccid3hctx_s, hctx->ccid3hctx_rtt,
|
||||
hctx->ccid3hctx_p, hctx->ccid3hctx_x_calc,
|
||||
hctx->ccid3hctx_x_recv >> 6,
|
||||
hctx->ccid3hctx_x >> 6, hctx->ccid3hctx_t_ipi);
|
||||
if (port == 0 || ntohs(inet->inet_dport) == port ||
|
||||
ntohs(inet->inet_sport) == port) {
|
||||
if (hc)
|
||||
printl("%pI4:%u %pI4:%u %d %d %d %d %u %llu %llu %d\n",
|
||||
&inet->inet_saddr, ntohs(inet->inet_sport),
|
||||
&inet->inet_daddr, ntohs(inet->inet_dport), size,
|
||||
hc->tx_s, hc->tx_rtt, hc->tx_p,
|
||||
hc->tx_x_calc, hc->tx_x_recv >> 6,
|
||||
hc->tx_x >> 6, hc->tx_t_ipi);
|
||||
else
|
||||
printl("%pI4:%u %pI4:%u %d\n",
|
||||
&inet->saddr, ntohs(inet->sport),
|
||||
&inet->daddr, ntohs(inet->dport), size);
|
||||
&inet->inet_saddr, ntohs(inet->inet_sport),
|
||||
&inet->inet_daddr, ntohs(inet->inet_dport),
|
||||
size);
|
||||
}
|
||||
|
||||
jprobe_return();
|
||||
|
@@ -278,7 +278,7 @@ int dccp_disconnect(struct sock *sk, int flags)
|
||||
sk->sk_send_head = NULL;
|
||||
}
|
||||
|
||||
inet->dport = 0;
|
||||
inet->inet_dport = 0;
|
||||
|
||||
if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK))
|
||||
inet_reset_saddr(sk);
|
||||
@@ -290,7 +290,7 @@ int dccp_disconnect(struct sock *sk, int flags)
|
||||
inet_csk_delack_init(sk);
|
||||
__sk_dst_reset(sk);
|
||||
|
||||
WARN_ON(inet->num && !icsk->icsk_bind_hash);
|
||||
WARN_ON(inet->inet_num && !icsk->icsk_bind_hash);
|
||||
|
||||
sk->sk_error_report(sk);
|
||||
return err;
|
||||
@@ -1060,11 +1060,12 @@ static int __init dccp_init(void)
|
||||
for (ehash_order = 0; (1UL << ehash_order) < goal; ehash_order++)
|
||||
;
|
||||
do {
|
||||
dccp_hashinfo.ehash_size = (1UL << ehash_order) * PAGE_SIZE /
|
||||
unsigned long hash_size = (1UL << ehash_order) * PAGE_SIZE /
|
||||
sizeof(struct inet_ehash_bucket);
|
||||
while (dccp_hashinfo.ehash_size &
|
||||
(dccp_hashinfo.ehash_size - 1))
|
||||
dccp_hashinfo.ehash_size--;
|
||||
|
||||
while (hash_size & (hash_size - 1))
|
||||
hash_size--;
|
||||
dccp_hashinfo.ehash_mask = hash_size - 1;
|
||||
dccp_hashinfo.ehash = (struct inet_ehash_bucket *)
|
||||
__get_free_pages(GFP_ATOMIC|__GFP_NOWARN, ehash_order);
|
||||
} while (!dccp_hashinfo.ehash && --ehash_order > 0);
|
||||
@@ -1074,7 +1075,7 @@ static int __init dccp_init(void)
|
||||
goto out_free_bind_bucket_cachep;
|
||||
}
|
||||
|
||||
for (i = 0; i < dccp_hashinfo.ehash_size; i++) {
|
||||
for (i = 0; i <= dccp_hashinfo.ehash_mask; i++) {
|
||||
INIT_HLIST_NULLS_HEAD(&dccp_hashinfo.ehash[i].chain, i);
|
||||
INIT_HLIST_NULLS_HEAD(&dccp_hashinfo.ehash[i].twchain, i);
|
||||
}
|
||||
@@ -1153,7 +1154,7 @@ static void __exit dccp_fini(void)
|
||||
get_order(dccp_hashinfo.bhash_size *
|
||||
sizeof(struct inet_bind_hashbucket)));
|
||||
free_pages((unsigned long)dccp_hashinfo.ehash,
|
||||
get_order(dccp_hashinfo.ehash_size *
|
||||
get_order((dccp_hashinfo.ehash_mask + 1) *
|
||||
sizeof(struct inet_ehash_bucket)));
|
||||
inet_ehash_locks_free(&dccp_hashinfo);
|
||||
kmem_cache_destroy(dccp_hashinfo.bind_bucket_cachep);
|
||||
|
@@ -38,7 +38,7 @@ static int dccp_write_timeout(struct sock *sk)
|
||||
|
||||
if (sk->sk_state == DCCP_REQUESTING || sk->sk_state == DCCP_PARTOPEN) {
|
||||
if (icsk->icsk_retransmits != 0)
|
||||
dst_negative_advice(&sk->sk_dst_cache);
|
||||
dst_negative_advice(&sk->sk_dst_cache, sk);
|
||||
retry_until = icsk->icsk_syn_retries ?
|
||||
: sysctl_dccp_request_retries;
|
||||
} else {
|
||||
@@ -63,7 +63,7 @@ static int dccp_write_timeout(struct sock *sk)
|
||||
Golden words :-).
|
||||
*/
|
||||
|
||||
dst_negative_advice(&sk->sk_dst_cache);
|
||||
dst_negative_advice(&sk->sk_dst_cache, sk);
|
||||
}
|
||||
|
||||
retry_until = sysctl_dccp_retries2;
|
||||
|
Reference in New Issue
Block a user