aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWei Yongjun <yjwei@cn.fujitsu.com>2011-04-17 13:27:08 -0400
committerDavid S. Miller <davem@davemloft.net>2011-04-21 13:35:43 -0400
commit209ba424c2c6e5ff4dd0ff79bb23659aa6048eac (patch)
treedf443b83a4d458cfb46ea2e08e176b2433fa5b66
parent4c6a6f42131dd750dcfe3c71e63bfc046e5a227e (diff)
sctp: implement socket option SCTP_GET_ASSOC_ID_LIST
This patch Implement socket option SCTP_GET_ASSOC_ID_LIST. SCTP Socket API Extension: 8.2.6. Get the Current Identifiers of Associations (SCTP_GET_ASSOC_ID_LIST) This option gets the current list of SCTP association identifiers of the SCTP associations handled by a one-to-many style socket. Signed-off-by: Wei Yongjun <yjwei@cn.fujitsu.com> Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/net/sctp/user.h13
-rw-r--r--net/sctp/socket.c52
2 files changed, 65 insertions, 0 deletions
diff --git a/include/net/sctp/user.h b/include/net/sctp/user.h
index e73ebdae323d..793617ecbfdf 100644
--- a/include/net/sctp/user.h
+++ b/include/net/sctp/user.h
@@ -91,6 +91,7 @@ typedef __s32 sctp_assoc_t;
91#define SCTP_PEER_AUTH_CHUNKS 26 /* Read only */ 91#define SCTP_PEER_AUTH_CHUNKS 26 /* Read only */
92#define SCTP_LOCAL_AUTH_CHUNKS 27 /* Read only */ 92#define SCTP_LOCAL_AUTH_CHUNKS 27 /* Read only */
93#define SCTP_GET_ASSOC_NUMBER 28 /* Read only */ 93#define SCTP_GET_ASSOC_NUMBER 28 /* Read only */
94#define SCTP_GET_ASSOC_ID_LIST 29 /* Read only */
94 95
95/* Internal Socket Options. Some of the sctp library functions are 96/* Internal Socket Options. Some of the sctp library functions are
96 * implemented using these socket options. 97 * implemented using these socket options.
@@ -669,6 +670,18 @@ struct sctp_authchunks {
669}; 670};
670 671
671/* 672/*
673 * 8.2.6. Get the Current Identifiers of Associations
674 * (SCTP_GET_ASSOC_ID_LIST)
675 *
676 * This option gets the current list of SCTP association identifiers of
677 * the SCTP associations handled by a one-to-many style socket.
678 */
679struct sctp_assoc_ids {
680 __u32 gaids_number_of_ids;
681 sctp_assoc_t gaids_assoc_id[];
682};
683
684/*
672 * 8.3, 8.5 get all peer/local addresses in an association. 685 * 8.3, 8.5 get all peer/local addresses in an association.
673 * This parameter struct is used by SCTP_GET_PEER_ADDRS and 686 * This parameter struct is used by SCTP_GET_PEER_ADDRS and
674 * SCTP_GET_LOCAL_ADDRS socket options used internally to implement 687 * SCTP_GET_LOCAL_ADDRS socket options used internally to implement
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 431b8905c570..f694ee116746 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -5277,6 +5277,55 @@ static int sctp_getsockopt_assoc_number(struct sock *sk, int len,
5277 return 0; 5277 return 0;
5278} 5278}
5279 5279
5280/*
5281 * 8.2.6. Get the Current Identifiers of Associations
5282 * (SCTP_GET_ASSOC_ID_LIST)
5283 *
5284 * This option gets the current list of SCTP association identifiers of
5285 * the SCTP associations handled by a one-to-many style socket.
5286 */
5287static int sctp_getsockopt_assoc_ids(struct sock *sk, int len,
5288 char __user *optval, int __user *optlen)
5289{
5290 struct sctp_sock *sp = sctp_sk(sk);
5291 struct sctp_association *asoc;
5292 struct sctp_assoc_ids *ids;
5293 u32 num = 0;
5294
5295 if (sctp_style(sk, TCP))
5296 return -EOPNOTSUPP;
5297
5298 if (len < sizeof(struct sctp_assoc_ids))
5299 return -EINVAL;
5300
5301 list_for_each_entry(asoc, &(sp->ep->asocs), asocs) {
5302 num++;
5303 }
5304
5305 if (len < sizeof(struct sctp_assoc_ids) + sizeof(sctp_assoc_t) * num)
5306 return -EINVAL;
5307
5308 len = sizeof(struct sctp_assoc_ids) + sizeof(sctp_assoc_t) * num;
5309
5310 ids = kmalloc(len, GFP_KERNEL);
5311 if (unlikely(!ids))
5312 return -ENOMEM;
5313
5314 ids->gaids_number_of_ids = num;
5315 num = 0;
5316 list_for_each_entry(asoc, &(sp->ep->asocs), asocs) {
5317 ids->gaids_assoc_id[num++] = asoc->assoc_id;
5318 }
5319
5320 if (put_user(len, optlen) || copy_to_user(optval, ids, len)) {
5321 kfree(ids);
5322 return -EFAULT;
5323 }
5324
5325 kfree(ids);
5326 return 0;
5327}
5328
5280SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname, 5329SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
5281 char __user *optval, int __user *optlen) 5330 char __user *optval, int __user *optlen)
5282{ 5331{
@@ -5409,6 +5458,9 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
5409 case SCTP_GET_ASSOC_NUMBER: 5458 case SCTP_GET_ASSOC_NUMBER:
5410 retval = sctp_getsockopt_assoc_number(sk, len, optval, optlen); 5459 retval = sctp_getsockopt_assoc_number(sk, len, optval, optlen);
5411 break; 5460 break;
5461 case SCTP_GET_ASSOC_ID_LIST:
5462 retval = sctp_getsockopt_assoc_ids(sk, len, optval, optlen);
5463 break;
5412 default: 5464 default:
5413 retval = -ENOPROTOOPT; 5465 retval = -ENOPROTOOPT;
5414 break; 5466 break;