aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp/associola.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sctp/associola.c')
-rw-r--r--net/sctp/associola.c64
1 files changed, 28 insertions, 36 deletions
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index f4b23043b610..525864bf4f07 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -293,7 +293,8 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
293 * told otherwise. 293 * told otherwise.
294 */ 294 */
295 asoc->peer.ipv4_address = 1; 295 asoc->peer.ipv4_address = 1;
296 asoc->peer.ipv6_address = 1; 296 if (asoc->base.sk->sk_family == PF_INET6)
297 asoc->peer.ipv6_address = 1;
297 INIT_LIST_HEAD(&asoc->asocs); 298 INIT_LIST_HEAD(&asoc->asocs);
298 299
299 asoc->autoclose = sp->autoclose; 300 asoc->autoclose = sp->autoclose;
@@ -566,6 +567,21 @@ void sctp_assoc_rm_peer(struct sctp_association *asoc,
566 if (asoc->init_last_sent_to == peer) 567 if (asoc->init_last_sent_to == peer)
567 asoc->init_last_sent_to = NULL; 568 asoc->init_last_sent_to = NULL;
568 569
570 /* If we remove the transport an SHUTDOWN was last sent to, set it
571 * to NULL. Combined with the update of the retran path above, this
572 * will cause the next SHUTDOWN to be sent to the next available
573 * transport, maintaining the cycle.
574 */
575 if (asoc->shutdown_last_sent_to == peer)
576 asoc->shutdown_last_sent_to = NULL;
577
578 /* If we remove the transport an ASCONF was last sent to, set it to
579 * NULL.
580 */
581 if (asoc->addip_last_asconf &&
582 asoc->addip_last_asconf->transport == peer)
583 asoc->addip_last_asconf->transport = NULL;
584
569 asoc->peer.transport_count--; 585 asoc->peer.transport_count--;
570 586
571 sctp_transport_free(peer); 587 sctp_transport_free(peer);
@@ -1268,49 +1284,21 @@ void sctp_assoc_update_retran_path(struct sctp_association *asoc)
1268 ntohs(t->ipaddr.v4.sin_port)); 1284 ntohs(t->ipaddr.v4.sin_port));
1269} 1285}
1270 1286
1271/* Choose the transport for sending a INIT packet. */ 1287/* Choose the transport for sending retransmit packet. */
1272struct sctp_transport *sctp_assoc_choose_init_transport( 1288struct sctp_transport *sctp_assoc_choose_alter_transport(
1273 struct sctp_association *asoc) 1289 struct sctp_association *asoc, struct sctp_transport *last_sent_to)
1274{
1275 struct sctp_transport *t;
1276
1277 /* Use the retran path. If the last INIT was sent over the
1278 * retran path, update the retran path and use it.
1279 */
1280 if (!asoc->init_last_sent_to) {
1281 t = asoc->peer.active_path;
1282 } else {
1283 if (asoc->init_last_sent_to == asoc->peer.retran_path)
1284 sctp_assoc_update_retran_path(asoc);
1285 t = asoc->peer.retran_path;
1286 }
1287
1288 SCTP_DEBUG_PRINTK_IPADDR("sctp_assoc_update_retran_path:association"
1289 " %p addr: ",
1290 " port: %d\n",
1291 asoc,
1292 (&t->ipaddr),
1293 ntohs(t->ipaddr.v4.sin_port));
1294
1295 return t;
1296}
1297
1298/* Choose the transport for sending a SHUTDOWN packet. */
1299struct sctp_transport *sctp_assoc_choose_shutdown_transport(
1300 struct sctp_association *asoc)
1301{ 1290{
1302 /* If this is the first time SHUTDOWN is sent, use the active path, 1291 /* If this is the first time packet is sent, use the active path,
1303 * else use the retran path. If the last SHUTDOWN was sent over the 1292 * else use the retran path. If the last packet was sent over the
1304 * retran path, update the retran path and use it. 1293 * retran path, update the retran path and use it.
1305 */ 1294 */
1306 if (!asoc->shutdown_last_sent_to) 1295 if (!last_sent_to)
1307 return asoc->peer.active_path; 1296 return asoc->peer.active_path;
1308 else { 1297 else {
1309 if (asoc->shutdown_last_sent_to == asoc->peer.retran_path) 1298 if (last_sent_to == asoc->peer.retran_path)
1310 sctp_assoc_update_retran_path(asoc); 1299 sctp_assoc_update_retran_path(asoc);
1311 return asoc->peer.retran_path; 1300 return asoc->peer.retran_path;
1312 } 1301 }
1313
1314} 1302}
1315 1303
1316/* Update the association's pmtu and frag_point by going through all the 1304/* Update the association's pmtu and frag_point by going through all the
@@ -1482,6 +1470,10 @@ int sctp_assoc_set_id(struct sctp_association *asoc, gfp_t gfp)
1482{ 1470{
1483 int assoc_id; 1471 int assoc_id;
1484 int error = 0; 1472 int error = 0;
1473
1474 /* If the id is already assigned, keep it. */
1475 if (asoc->assoc_id)
1476 return error;
1485retry: 1477retry:
1486 if (unlikely(!idr_pre_get(&sctp_assocs_id, gfp))) 1478 if (unlikely(!idr_pre_get(&sctp_assocs_id, gfp)))
1487 return -ENOMEM; 1479 return -ENOMEM;