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 db73ef97485..df94e3cdfba 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 | } | ||
