Commit cf1fc11b authored by Xin Long's avatar Xin Long Committed by Ben Hutchings

sctp: fix the transports round robin issue when init is retransmitted

commit 39d2adeb upstream.

prior to this patch, at the beginning if we have two paths in one assoc,
they may have the same params other than the last_time_heard, it will try
the paths like this:

1st cycle
  try trans1 fail.
  then trans2 is selected.(cause it's last_time_heard is after trans1).

2nd cycle:
  try  trans2 fail
  then trans2 is selected.(cause it's last_time_heard is after trans1).

3rd cycle:
  try  trans2 fail
  then trans2 is selected.(cause it's last_time_heard is after trans1).

....

trans1 will never have change to be selected, which is not what we expect.
we should keeping round robin all the paths if they are just added at the
beginning.

So at first every tranport's last_time_heard should be initialized 0, so
that we ensure they have the same value at the beginning, only by this,
all the transports could get equal chance to be selected.

Then for sctp_trans_elect_best, it should return the trans_next one when
*trans == *trans_next, so that we can try next if it fails,  but now it
always return trans. so we can fix it by exchanging these two params when
we calls sctp_trans_elect_tie().

Fixes: 4c47af4d ('net: sctp: rework multihoming retransmission path selection to rfc4960')
Signed-off-by: default avatarXin Long <lucien.xin@gmail.com>
Acked-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Acked-by: default avatarMarcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarBen Hutchings <ben@decadent.org.uk>
parent b7303b38
...@@ -1256,7 +1256,7 @@ static struct sctp_transport *sctp_trans_elect_best(struct sctp_transport *curr, ...@@ -1256,7 +1256,7 @@ static struct sctp_transport *sctp_trans_elect_best(struct sctp_transport *curr,
if (score_curr > score_best) if (score_curr > score_best)
return curr; return curr;
else if (score_curr == score_best) else if (score_curr == score_best)
return sctp_trans_elect_tie(curr, best); return sctp_trans_elect_tie(best, curr);
else else
return best; return best;
} }
......
...@@ -72,7 +72,7 @@ static struct sctp_transport *sctp_transport_init(struct net *net, ...@@ -72,7 +72,7 @@ static struct sctp_transport *sctp_transport_init(struct net *net,
*/ */
peer->rto = msecs_to_jiffies(net->sctp.rto_initial); peer->rto = msecs_to_jiffies(net->sctp.rto_initial);
peer->last_time_heard = ktime_get(); peer->last_time_heard = ktime_set(0, 0);
peer->last_time_ecne_reduced = jiffies; peer->last_time_ecne_reduced = jiffies;
peer->param_flags = SPP_HB_DISABLE | peer->param_flags = SPP_HB_DISABLE |
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment