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.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index db73ef97485a..df94e3cdfba3 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -1103,6 +1103,13 @@ void sctp_assoc_update(struct sctp_association *asoc,
1103 asoc->ssnmap = new->ssnmap; 1103 asoc->ssnmap = new->ssnmap;
1104 new->ssnmap = NULL; 1104 new->ssnmap = NULL;
1105 } 1105 }
1106
1107 if (!asoc->assoc_id) {
1108 /* get a new association id since we don't have one
1109 * yet.
1110 */
1111 sctp_assoc_set_id(asoc, GFP_ATOMIC);
1112 }
1106 } 1113 }
1107} 1114}
1108 1115
@@ -1375,3 +1382,25 @@ out:
1375 sctp_read_unlock(&asoc->base.addr_lock); 1382 sctp_read_unlock(&asoc->base.addr_lock);
1376 return found; 1383 return found;
1377} 1384}
1385
1386/* Set an association id for a given association */
1387int sctp_assoc_set_id(struct sctp_association *asoc, gfp_t gfp)
1388{
1389 int assoc_id;
1390 int error = 0;
1391retry:
1392 if (unlikely(!idr_pre_get(&sctp_assocs_id, gfp)))
1393 return -ENOMEM;
1394
1395 spin_lock_bh(&sctp_assocs_id_lock);
1396 error = idr_get_new_above(&sctp_assocs_id, (void *)asoc,
1397 1, &assoc_id);
1398 spin_unlock_bh(&sctp_assocs_id_lock);
1399 if (error == -EAGAIN)
1400 goto retry;
1401 else if (error)
1402 return error;
1403
1404 asoc->assoc_id = (sctp_assoc_t) assoc_id;
1405 return error;
1406}