Skip to content

Commit b82e8f3

Browse files
Daniel Borkmanndavem330
authored andcommitted
net: sctp: refactor active path selection
This patch just refactors and moves the code for the active path selection into its own helper function outside of sctp_assoc_control_transport() which is already big enough. No functional changes here. Signed-off-by: Daniel Borkmann <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 67cb936 commit b82e8f3

File tree

1 file changed

+61
-59
lines changed

1 file changed

+61
-59
lines changed

net/sctp/associola.c

Lines changed: 61 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
#include <net/sctp/sm.h>
5656

5757
/* Forward declarations for internal functions. */
58+
static void sctp_select_active_and_retran_path(struct sctp_association *asoc);
5859
static void sctp_assoc_bh_rcv(struct work_struct *work);
5960
static void sctp_assoc_free_asconf_acks(struct sctp_association *asoc);
6061
static void sctp_assoc_free_asconf_queue(struct sctp_association *asoc);
@@ -774,9 +775,6 @@ void sctp_assoc_control_transport(struct sctp_association *asoc,
774775
sctp_transport_cmd_t command,
775776
sctp_sn_error_t error)
776777
{
777-
struct sctp_transport *t = NULL;
778-
struct sctp_transport *first;
779-
struct sctp_transport *second;
780778
struct sctp_ulpevent *event;
781779
struct sockaddr_storage addr;
782780
int spc_state = 0;
@@ -829,74 +827,22 @@ void sctp_assoc_control_transport(struct sctp_association *asoc,
829827
return;
830828
}
831829

832-
/* Generate and send a SCTP_PEER_ADDR_CHANGE notification to the
833-
* user.
830+
/* Generate and send a SCTP_PEER_ADDR_CHANGE notification
831+
* to the user.
834832
*/
835833
if (ulp_notify) {
836834
memset(&addr, 0, sizeof(struct sockaddr_storage));
837835
memcpy(&addr, &transport->ipaddr,
838836
transport->af_specific->sockaddr_len);
837+
839838
event = sctp_ulpevent_make_peer_addr_change(asoc, &addr,
840839
0, spc_state, error, GFP_ATOMIC);
841840
if (event)
842841
sctp_ulpq_tail_event(&asoc->ulpq, event);
843842
}
844843

845844
/* Select new active and retran paths. */
846-
847-
/* Look for the two most recently used active transports.
848-
*
849-
* This code produces the wrong ordering whenever jiffies
850-
* rolls over, but we still get usable transports, so we don't
851-
* worry about it.
852-
*/
853-
first = NULL; second = NULL;
854-
855-
list_for_each_entry(t, &asoc->peer.transport_addr_list,
856-
transports) {
857-
858-
if ((t->state == SCTP_INACTIVE) ||
859-
(t->state == SCTP_UNCONFIRMED) ||
860-
(t->state == SCTP_PF))
861-
continue;
862-
if (!first || t->last_time_heard > first->last_time_heard) {
863-
second = first;
864-
first = t;
865-
} else if (!second ||
866-
t->last_time_heard > second->last_time_heard)
867-
second = t;
868-
}
869-
870-
/* RFC 2960 6.4 Multi-Homed SCTP Endpoints
871-
*
872-
* By default, an endpoint should always transmit to the
873-
* primary path, unless the SCTP user explicitly specifies the
874-
* destination transport address (and possibly source
875-
* transport address) to use.
876-
*
877-
* [If the primary is active but not most recent, bump the most
878-
* recently used transport.]
879-
*/
880-
if (((asoc->peer.primary_path->state == SCTP_ACTIVE) ||
881-
(asoc->peer.primary_path->state == SCTP_UNKNOWN)) &&
882-
first != asoc->peer.primary_path) {
883-
second = first;
884-
first = asoc->peer.primary_path;
885-
}
886-
887-
if (!second)
888-
second = first;
889-
/* If we failed to find a usable transport, just camp on the
890-
* primary, even if it is inactive.
891-
*/
892-
if (!first) {
893-
first = asoc->peer.primary_path;
894-
second = asoc->peer.primary_path;
895-
}
896-
897-
/* Set the active and retran transports. */
898-
asoc->peer.active_path = first;
899-
asoc->peer.retran_path = second;
845+
sctp_select_active_and_retran_path(asoc);
900846
}
901847

902848
/* Hold a reference to an association. */
@@ -1325,6 +1271,62 @@ void sctp_assoc_update_retran_path(struct sctp_association *asoc)
13251271
__func__, asoc, &asoc->peer.retran_path->ipaddr.sa);
13261272
}
13271273

1274+
static void sctp_select_active_and_retran_path(struct sctp_association *asoc)
1275+
{
1276+
struct sctp_transport *trans, *trans_pri = NULL, *trans_sec = NULL;
1277+
1278+
/* Look for the two most recently used active transports. */
1279+
list_for_each_entry(trans, &asoc->peer.transport_addr_list,
1280+
transports) {
1281+
if (trans->state == SCTP_INACTIVE ||
1282+
trans->state == SCTP_UNCONFIRMED ||
1283+
trans->state == SCTP_PF)
1284+
continue;
1285+
if (trans_pri == NULL ||
1286+
trans->last_time_heard > trans_pri->last_time_heard) {
1287+
trans_sec = trans_pri;
1288+
trans_pri = trans;
1289+
} else if (trans_sec == NULL ||
1290+
trans->last_time_heard > trans_sec->last_time_heard) {
1291+
trans_sec = trans;
1292+
}
1293+
}
1294+
1295+
/* RFC 2960 6.4 Multi-Homed SCTP Endpoints
1296+
*
1297+
* By default, an endpoint should always transmit to the primary
1298+
* path, unless the SCTP user explicitly specifies the
1299+
* destination transport address (and possibly source transport
1300+
* address) to use. [If the primary is active but not most recent,
1301+
* bump the most recently used transport.]
1302+
*/
1303+
if ((asoc->peer.primary_path->state == SCTP_ACTIVE ||
1304+
asoc->peer.primary_path->state == SCTP_UNKNOWN) &&
1305+
asoc->peer.primary_path != trans_pri) {
1306+
trans_sec = trans_pri;
1307+
trans_pri = asoc->peer.primary_path;
1308+
}
1309+
1310+
/* We did not find anything useful for a possible retransmission
1311+
* path; either primary path that we found is the the same as
1312+
* the current one, or we didn't generally find an active one.
1313+
*/
1314+
if (trans_sec == NULL)
1315+
trans_sec = trans_pri;
1316+
1317+
/* If we failed to find a usable transport, just camp on the
1318+
* primary, even if they are inactive.
1319+
*/
1320+
if (trans_pri == NULL) {
1321+
trans_pri = asoc->peer.primary_path;
1322+
trans_sec = asoc->peer.primary_path;
1323+
}
1324+
1325+
/* Set the active and retran transports. */
1326+
asoc->peer.active_path = trans_pri;
1327+
asoc->peer.retran_path = trans_sec;
1328+
}
1329+
13281330
struct sctp_transport *
13291331
sctp_assoc_choose_alter_transport(struct sctp_association *asoc,
13301332
struct sctp_transport *last_sent_to)

0 commit comments

Comments
 (0)