sctp: Implement socket option SCTP_GET_ASSOC_NUMBER
authorWei Yongjun <yjwei@cn.fujitsu.com>
Fri, 26 Dec 2008 00:57:24 +0000 (16:57 -0800)
committerDavid S. Miller <davem@davemloft.net>
Fri, 26 Dec 2008 00:57:24 +0000 (16:57 -0800)
Implement socket option SCTP_GET_ASSOC_NUMBER of the latest ietf socket
extensions API draft.

  8.2.5.  Get the Current Number of Associations (SCTP_GET_ASSOC_NUMBER)

   This option gets the current number of associations that are attached
   to a one-to-many style socket.  The option value is an uint32_t.

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>
include/net/sctp/user.h
net/sctp/socket.c

index f205b10f0ab95f05ec3cef5aea549991c4f0f0d7..b259fc5798fb2f909fda0cc80be04d906b3879cc 100644 (file)
@@ -118,6 +118,8 @@ enum sctp_optname {
 #define SCTP_PEER_AUTH_CHUNKS SCTP_PEER_AUTH_CHUNKS
        SCTP_LOCAL_AUTH_CHUNKS,         /* Read only */
 #define SCTP_LOCAL_AUTH_CHUNKS SCTP_LOCAL_AUTH_CHUNKS
+       SCTP_GET_ASSOC_NUMBER,          /* Read only */
+#define SCTP_GET_ASSOC_NUMBER SCTP_GET_ASSOC_NUMBER
 
 
        /* Internal Socket Options. Some of the sctp library functions are 
index e432927310c9135f0ed99482dd84f8a626eab354..9f5fe23773a9e3ac55b4b12812e02282a49977d1 100644 (file)
@@ -5460,6 +5460,38 @@ num:
        return 0;
 }
 
+/*
+ * 8.2.5.  Get the Current Number of Associations (SCTP_GET_ASSOC_NUMBER)
+ * This option gets the current number of associations that are attached
+ * to a one-to-many style socket.  The option value is an uint32_t.
+ */
+static int sctp_getsockopt_assoc_number(struct sock *sk, int len,
+                                   char __user *optval, int __user *optlen)
+{
+       struct sctp_sock *sp = sctp_sk(sk);
+       struct sctp_association *asoc;
+       u32 val = 0;
+
+       if (sctp_style(sk, TCP))
+               return -EOPNOTSUPP;
+
+       if (len < sizeof(u32))
+               return -EINVAL;
+
+       len = sizeof(u32);
+
+       list_for_each_entry(asoc, &(sp->ep->asocs), asocs) {
+               val++;
+       }
+
+       if (put_user(len, optlen))
+               return -EFAULT;
+       if (copy_to_user(optval, &val, len))
+               return -EFAULT;
+
+       return 0;
+}
+
 SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
                                char __user *optval, int __user *optlen)
 {
@@ -5602,6 +5634,9 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
                retval = sctp_getsockopt_local_auth_chunks(sk, len, optval,
                                                        optlen);
                break;
+       case SCTP_GET_ASSOC_NUMBER:
+               retval = sctp_getsockopt_assoc_number(sk, len, optval, optlen);
+               break;
        default:
                retval = -ENOPROTOOPT;
                break;