diff options
Diffstat (limited to 'net/sctp/associola.c')
-rw-r--r-- | net/sctp/associola.c | 29 |
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 */ | ||
1387 | int sctp_assoc_set_id(struct sctp_association *asoc, gfp_t gfp) | ||
1388 | { | ||
1389 | int assoc_id; | ||
1390 | int error = 0; | ||
1391 | retry: | ||
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 | } | ||