]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - net/sctp/socket.c
sctp: Fix break indentation in sctp_ioctl().
[net-next-2.6.git] / net / sctp / socket.c
index 44a1ab03a3f0124ac33c63aa62f54b5663b52914..d4bf2a78cb8a2ce4b8742243511307862f6604f5 100644 (file)
@@ -57,6 +57,8 @@
  * be incorporated into the next SCTP release.
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/types.h>
 #include <linux/kernel.h>
 #include <linux/wait.h>
@@ -2458,9 +2460,8 @@ static int sctp_setsockopt_delayed_ack(struct sock *sk,
                if (params.sack_delay == 0 && params.sack_freq == 0)
                        return 0;
        } else if (optlen == sizeof(struct sctp_assoc_value)) {
-               printk(KERN_WARNING "SCTP: Use of struct sctp_assoc_value "
-                      "in delayed_ack socket option deprecated\n");
-               printk(KERN_WARNING "SCTP: Use struct sctp_sack_info instead\n");
+               pr_warn("Use of struct sctp_assoc_value in delayed_ack socket option deprecated\n");
+               pr_warn("Use struct sctp_sack_info instead\n");
                if (copy_from_user(&params, optval, optlen))
                        return -EFAULT;
 
@@ -2868,10 +2869,8 @@ static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, unsigned
        int val;
 
        if (optlen == sizeof(int)) {
-               printk(KERN_WARNING
-                  "SCTP: Use of int in maxseg socket option deprecated\n");
-               printk(KERN_WARNING
-                  "SCTP: Use struct sctp_assoc_value instead\n");
+               pr_warn("Use of int in maxseg socket option deprecated\n");
+               pr_warn("Use struct sctp_assoc_value instead\n");
                if (copy_from_user(&val, optval, optlen))
                        return -EFAULT;
                params.assoc_id = 0;
@@ -3121,10 +3120,8 @@ static int sctp_setsockopt_maxburst(struct sock *sk,
        int assoc_id = 0;
 
        if (optlen == sizeof(int)) {
-               printk(KERN_WARNING
-                  "SCTP: Use of int in max_burst socket option deprecated\n");
-               printk(KERN_WARNING
-                  "SCTP: Use struct sctp_assoc_value instead\n");
+               pr_warn("Use of int in max_burst socket option deprecated\n");
+               pr_warn("Use struct sctp_assoc_value instead\n");
                if (copy_from_user(&val, optval, optlen))
                        return -EFAULT;
        } else if (optlen == sizeof(struct sctp_assoc_value)) {
@@ -3595,7 +3592,40 @@ out:
 /* The SCTP ioctl handler. */
 SCTP_STATIC int sctp_ioctl(struct sock *sk, int cmd, unsigned long arg)
 {
-       return -ENOIOCTLCMD;
+       int rc = -ENOTCONN;
+
+       sctp_lock_sock(sk);
+
+       /*
+        * SEQPACKET-style sockets in LISTENING state are valid, for
+        * SCTP, so only discard TCP-style sockets in LISTENING state.
+        */
+       if (sctp_style(sk, TCP) && sctp_sstate(sk, LISTENING))
+               goto out;
+
+       switch (cmd) {
+       case SIOCINQ: {
+               struct sk_buff *skb;
+               unsigned int amount = 0;
+
+               skb = skb_peek(&sk->sk_receive_queue);
+               if (skb != NULL) {
+                       /*
+                        * We will only return the amount of this packet since
+                        * that is all that will be read.
+                        */
+                       amount = skb->len;
+               }
+               rc = put_user(amount, (int __user *)arg);
+               break;
+       }
+       default:
+               rc = -ENOIOCTLCMD;
+               break;
+       }
+out:
+       sctp_release_sock(sk);
+       return rc;
 }
 
 /* This is the function which gets called during socket creation to
@@ -3720,9 +3750,6 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
 
        SCTP_DBG_OBJCNT_INC(sock);
 
-       /* Set socket backlog limit. */
-       sk->sk_backlog.limit = sysctl_sctp_rmem[1];
-
        local_bh_disable();
        percpu_counter_inc(&sctp_sockets_allocated);
        sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
@@ -3857,7 +3884,7 @@ static int sctp_getsockopt_sctp_status(struct sock *sk, int len,
        }
 
 out:
-       return (retval);
+       return retval;
 }
 
 
@@ -3913,7 +3940,7 @@ static int sctp_getsockopt_peer_addr_info(struct sock *sk, int len,
        }
 
 out:
-       return (retval);
+       return retval;
 }
 
 /* 7.1.12 Enable/Disable message fragmentation (SCTP_DISABLE_FRAGMENTS)
@@ -4284,9 +4311,8 @@ static int sctp_getsockopt_delayed_ack(struct sock *sk, int len,
                if (copy_from_user(&params, optval, len))
                        return -EFAULT;
        } else if (len == sizeof(struct sctp_assoc_value)) {
-               printk(KERN_WARNING "SCTP: Use of struct sctp_assoc_value "
-                      "in delayed_ack socket option deprecated\n");
-               printk(KERN_WARNING "SCTP: Use struct sctp_sack_info instead\n");
+               pr_warn("Use of struct sctp_assoc_value in delayed_ack socket option deprecated\n");
+               pr_warn("Use struct sctp_sack_info instead\n");
                if (copy_from_user(&params, optval, len))
                        return -EFAULT;
        } else
@@ -4387,7 +4413,7 @@ static int sctp_getsockopt_peer_addrs(struct sock *sk, int len,
                                transports) {
                memcpy(&temp, &from->ipaddr, sizeof(temp));
                sctp_get_pf_specific(sk->sk_family)->addr_v4map(sp, &temp);
-               addrlen = sctp_get_af_specific(sk->sk_family)->sockaddr_len;
+               addrlen = sctp_get_af_specific(temp.sa.sa_family)->sockaddr_len;
                if (space_left < addrlen)
                        return -ENOMEM;
                if (copy_to_user(to, &temp, addrlen))
@@ -4932,10 +4958,8 @@ static int sctp_getsockopt_maxseg(struct sock *sk, int len,
        struct sctp_association *asoc;
 
        if (len == sizeof(int)) {
-               printk(KERN_WARNING
-                  "SCTP: Use of int in maxseg socket option deprecated\n");
-               printk(KERN_WARNING
-                  "SCTP: Use struct sctp_assoc_value instead\n");
+               pr_warn("Use of int in maxseg socket option deprecated\n");
+               pr_warn("Use struct sctp_assoc_value instead\n");
                params.assoc_id = 0;
        } else if (len >= sizeof(struct sctp_assoc_value)) {
                len = sizeof(struct sctp_assoc_value);
@@ -5026,10 +5050,8 @@ static int sctp_getsockopt_maxburst(struct sock *sk, int len,
        struct sctp_association *asoc;
 
        if (len == sizeof(int)) {
-               printk(KERN_WARNING
-                  "SCTP: Use of int in max_burst socket option deprecated\n");
-               printk(KERN_WARNING
-                  "SCTP: Use struct sctp_assoc_value instead\n");
+               pr_warn("Use of int in max_burst socket option deprecated\n");
+               pr_warn("Use struct sctp_assoc_value instead\n");
                params.assoc_id = 0;
        } else if (len >= sizeof(struct sctp_assoc_value)) {
                len = sizeof(struct sctp_assoc_value);
@@ -5436,6 +5458,8 @@ static long sctp_get_port_local(struct sock *sk, union sctp_addr *addr)
                        rover++;
                        if ((rover < low) || (rover > high))
                                rover = low;
+                       if (inet_is_reserved_local_port(rover))
+                               continue;
                        index = sctp_phashfn(rover);
                        head = &sctp_port_hashtable[index];
                        sctp_spin_lock(&head->lock);
@@ -5482,7 +5506,6 @@ pp_found:
                 */
                int reuse = sk->sk_reuse;
                struct sock *sk2;
-               struct hlist_node *node;
 
                SCTP_DEBUG_PRINTK("sctp_get_port() found a possible match\n");
                if (pp->fastreuse && sk->sk_reuse &&
@@ -5571,7 +5594,7 @@ static int sctp_get_port(struct sock *sk, unsigned short snum)
        /* Note: sk->sk_num gets filled in if ephemeral port request. */
        ret = sctp_get_port_local(sk, &addr);
 
-       return (ret ? 1 : 0);
+       return ret ? 1 : 0;
 }
 
 /*
@@ -5588,8 +5611,7 @@ SCTP_STATIC int sctp_listen_start(struct sock *sk, int backlog)
                tfm = crypto_alloc_hash(sctp_hmac_alg, 0, CRYPTO_ALG_ASYNC);
                if (IS_ERR(tfm)) {
                        if (net_ratelimit()) {
-                               printk(KERN_INFO
-                                      "SCTP: failed to load transform for %s: %ld\n",
+                               pr_info("failed to load transform for %s: %ld\n",
                                        sctp_hmac_alg, PTR_ERR(tfm));
                        }
                        return -ENOSYS;
@@ -5703,7 +5725,7 @@ unsigned int sctp_poll(struct file *file, struct socket *sock, poll_table *wait)
        struct sctp_sock *sp = sctp_sk(sk);
        unsigned int mask;
 
-       poll_wait(file, sk->sk_sleep, wait);
+       poll_wait(file, sk_sleep(sk), wait);
 
        /* A TCP-style listening socket becomes readable when the accept queue
         * is not empty.
@@ -5718,13 +5740,12 @@ unsigned int sctp_poll(struct file *file, struct socket *sock, poll_table *wait)
        if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue))
                mask |= POLLERR;
        if (sk->sk_shutdown & RCV_SHUTDOWN)
-               mask |= POLLRDHUP;
+               mask |= POLLRDHUP | POLLIN | POLLRDNORM;
        if (sk->sk_shutdown == SHUTDOWN_MASK)
                mask |= POLLHUP;
 
        /* Is it readable?  Reconsider this code with TCP-style support.  */
-       if (!skb_queue_empty(&sk->sk_receive_queue) ||
-           (sk->sk_shutdown & RCV_SHUTDOWN))
+       if (!skb_queue_empty(&sk->sk_receive_queue))
                mask |= POLLIN | POLLRDNORM;
 
        /* The association is either gone or not ready.  */
@@ -5944,7 +5965,7 @@ static int sctp_wait_for_packet(struct sock * sk, int *err, long *timeo_p)
        int error;
        DEFINE_WAIT(wait);
 
-       prepare_to_wait_exclusive(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
+       prepare_to_wait_exclusive(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
 
        /* Socket errors? */
        error = sock_error(sk);
@@ -5981,14 +6002,14 @@ static int sctp_wait_for_packet(struct sock * sk, int *err, long *timeo_p)
        sctp_lock_sock(sk);
 
 ready:
-       finish_wait(sk->sk_sleep, &wait);
+       finish_wait(sk_sleep(sk), &wait);
        return 0;
 
 interrupted:
        error = sock_intr_errno(*timeo_p);
 
 out:
-       finish_wait(sk->sk_sleep, &wait);
+       finish_wait(sk_sleep(sk), &wait);
        *err = error;
        return error;
 }
@@ -6062,14 +6083,14 @@ static void __sctp_write_space(struct sctp_association *asoc)
                        wake_up_interruptible(&asoc->wait);
 
                if (sctp_writeable(sk)) {
-                       if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))
-                               wake_up_interruptible(sk->sk_sleep);
+                       if (sk_sleep(sk) && waitqueue_active(sk_sleep(sk)))
+                               wake_up_interruptible(sk_sleep(sk));
 
                        /* Note that we try to include the Async I/O support
                         * here by modeling from the current TCP/UDP code.
                         * We have not tested with it yet.
                         */
-                       if (sock->fasync_list &&
+                       if (sock->wq->fasync_list &&
                            !(sk->sk_shutdown & SEND_SHUTDOWN))
                                sock_wake_async(sock,
                                                SOCK_WAKE_SPACE, POLL_OUT);
@@ -6191,12 +6212,15 @@ do_nonblock:
 
 void sctp_data_ready(struct sock *sk, int len)
 {
-       read_lock_bh(&sk->sk_callback_lock);
-       if (sk_has_sleeper(sk))
-               wake_up_interruptible_sync_poll(sk->sk_sleep, POLLIN |
+       struct socket_wq *wq;
+
+       rcu_read_lock();
+       wq = rcu_dereference(sk->sk_wq);
+       if (wq_has_sleeper(wq))
+               wake_up_interruptible_sync_poll(&wq->wait, POLLIN |
                                                POLLRDNORM | POLLRDBAND);
        sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN);
-       read_unlock_bh(&sk->sk_callback_lock);
+       rcu_read_unlock();
 }
 
 /* If socket sndbuf has changed, wake up all per association waiters.  */
@@ -6307,7 +6331,7 @@ static int sctp_wait_for_accept(struct sock *sk, long timeo)
 
 
        for (;;) {
-               prepare_to_wait_exclusive(sk->sk_sleep, &wait,
+               prepare_to_wait_exclusive(sk_sleep(sk), &wait,
                                          TASK_INTERRUPTIBLE);
 
                if (list_empty(&ep->asocs)) {
@@ -6333,7 +6357,7 @@ static int sctp_wait_for_accept(struct sock *sk, long timeo)
                        break;
        }
 
-       finish_wait(sk->sk_sleep, &wait);
+       finish_wait(sk_sleep(sk), &wait);
 
        return err;
 }
@@ -6343,7 +6367,7 @@ static void sctp_wait_for_close(struct sock *sk, long timeout)
        DEFINE_WAIT(wait);
 
        do {
-               prepare_to_wait(sk->sk_sleep, &wait, TASK_INTERRUPTIBLE);
+               prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE);
                if (list_empty(&sctp_sk(sk)->ep->asocs))
                        break;
                sctp_release_sock(sk);
@@ -6351,7 +6375,7 @@ static void sctp_wait_for_close(struct sock *sk, long timeout)
                sctp_lock_sock(sk);
        } while (!signal_pending(current) && timeout);
 
-       finish_wait(sk->sk_sleep, &wait);
+       finish_wait(sk_sleep(sk), &wait);
 }
 
 static void sctp_skb_set_owner_r_frag(struct sk_buff *skb, struct sock *sk)