diff options
Diffstat (limited to 'net/sctp/socket.c')
-rw-r--r-- | net/sctp/socket.c | 85 |
1 files changed, 54 insertions, 31 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index fbb70770ad05..e34ca9cc1167 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -57,6 +57,8 @@ | |||
57 | * be incorporated into the next SCTP release. | 57 | * be incorporated into the next SCTP release. |
58 | */ | 58 | */ |
59 | 59 | ||
60 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
61 | |||
60 | #include <linux/types.h> | 62 | #include <linux/types.h> |
61 | #include <linux/kernel.h> | 63 | #include <linux/kernel.h> |
62 | #include <linux/wait.h> | 64 | #include <linux/wait.h> |
@@ -2469,9 +2471,8 @@ static int sctp_setsockopt_delayed_ack(struct sock *sk, | |||
2469 | if (params.sack_delay == 0 && params.sack_freq == 0) | 2471 | if (params.sack_delay == 0 && params.sack_freq == 0) |
2470 | return 0; | 2472 | return 0; |
2471 | } else if (optlen == sizeof(struct sctp_assoc_value)) { | 2473 | } else if (optlen == sizeof(struct sctp_assoc_value)) { |
2472 | printk(KERN_WARNING "SCTP: Use of struct sctp_assoc_value " | 2474 | pr_warn("Use of struct sctp_assoc_value in delayed_ack socket option deprecated\n"); |
2473 | "in delayed_ack socket option deprecated\n"); | 2475 | pr_warn("Use struct sctp_sack_info instead\n"); |
2474 | printk(KERN_WARNING "SCTP: Use struct sctp_sack_info instead\n"); | ||
2475 | if (copy_from_user(¶ms, optval, optlen)) | 2476 | if (copy_from_user(¶ms, optval, optlen)) |
2476 | return -EFAULT; | 2477 | return -EFAULT; |
2477 | 2478 | ||
@@ -2879,10 +2880,8 @@ static int sctp_setsockopt_maxseg(struct sock *sk, char __user *optval, unsigned | |||
2879 | int val; | 2880 | int val; |
2880 | 2881 | ||
2881 | if (optlen == sizeof(int)) { | 2882 | if (optlen == sizeof(int)) { |
2882 | printk(KERN_WARNING | 2883 | pr_warn("Use of int in maxseg socket option deprecated\n"); |
2883 | "SCTP: Use of int in maxseg socket option deprecated\n"); | 2884 | pr_warn("Use struct sctp_assoc_value instead\n"); |
2884 | printk(KERN_WARNING | ||
2885 | "SCTP: Use struct sctp_assoc_value instead\n"); | ||
2886 | if (copy_from_user(&val, optval, optlen)) | 2885 | if (copy_from_user(&val, optval, optlen)) |
2887 | return -EFAULT; | 2886 | return -EFAULT; |
2888 | params.assoc_id = 0; | 2887 | params.assoc_id = 0; |
@@ -3132,10 +3131,8 @@ static int sctp_setsockopt_maxburst(struct sock *sk, | |||
3132 | int assoc_id = 0; | 3131 | int assoc_id = 0; |
3133 | 3132 | ||
3134 | if (optlen == sizeof(int)) { | 3133 | if (optlen == sizeof(int)) { |
3135 | printk(KERN_WARNING | 3134 | pr_warn("Use of int in max_burst socket option deprecated\n"); |
3136 | "SCTP: Use of int in max_burst socket option deprecated\n"); | 3135 | pr_warn("Use struct sctp_assoc_value instead\n"); |
3137 | printk(KERN_WARNING | ||
3138 | "SCTP: Use struct sctp_assoc_value instead\n"); | ||
3139 | if (copy_from_user(&val, optval, optlen)) | 3136 | if (copy_from_user(&val, optval, optlen)) |
3140 | return -EFAULT; | 3137 | return -EFAULT; |
3141 | } else if (optlen == sizeof(struct sctp_assoc_value)) { | 3138 | } else if (optlen == sizeof(struct sctp_assoc_value)) { |
@@ -3606,7 +3603,40 @@ out: | |||
3606 | /* The SCTP ioctl handler. */ | 3603 | /* The SCTP ioctl handler. */ |
3607 | SCTP_STATIC int sctp_ioctl(struct sock *sk, int cmd, unsigned long arg) | 3604 | SCTP_STATIC int sctp_ioctl(struct sock *sk, int cmd, unsigned long arg) |
3608 | { | 3605 | { |
3609 | return -ENOIOCTLCMD; | 3606 | int rc = -ENOTCONN; |
3607 | |||
3608 | sctp_lock_sock(sk); | ||
3609 | |||
3610 | /* | ||
3611 | * SEQPACKET-style sockets in LISTENING state are valid, for | ||
3612 | * SCTP, so only discard TCP-style sockets in LISTENING state. | ||
3613 | */ | ||
3614 | if (sctp_style(sk, TCP) && sctp_sstate(sk, LISTENING)) | ||
3615 | goto out; | ||
3616 | |||
3617 | switch (cmd) { | ||
3618 | case SIOCINQ: { | ||
3619 | struct sk_buff *skb; | ||
3620 | unsigned int amount = 0; | ||
3621 | |||
3622 | skb = skb_peek(&sk->sk_receive_queue); | ||
3623 | if (skb != NULL) { | ||
3624 | /* | ||
3625 | * We will only return the amount of this packet since | ||
3626 | * that is all that will be read. | ||
3627 | */ | ||
3628 | amount = skb->len; | ||
3629 | } | ||
3630 | rc = put_user(amount, (int __user *)arg); | ||
3631 | break; | ||
3632 | } | ||
3633 | default: | ||
3634 | rc = -ENOIOCTLCMD; | ||
3635 | break; | ||
3636 | } | ||
3637 | out: | ||
3638 | sctp_release_sock(sk); | ||
3639 | return rc; | ||
3610 | } | 3640 | } |
3611 | 3641 | ||
3612 | /* This is the function which gets called during socket creation to | 3642 | /* This is the function which gets called during socket creation to |
@@ -3865,7 +3895,7 @@ static int sctp_getsockopt_sctp_status(struct sock *sk, int len, | |||
3865 | } | 3895 | } |
3866 | 3896 | ||
3867 | out: | 3897 | out: |
3868 | return (retval); | 3898 | return retval; |
3869 | } | 3899 | } |
3870 | 3900 | ||
3871 | 3901 | ||
@@ -3921,7 +3951,7 @@ static int sctp_getsockopt_peer_addr_info(struct sock *sk, int len, | |||
3921 | } | 3951 | } |
3922 | 3952 | ||
3923 | out: | 3953 | out: |
3924 | return (retval); | 3954 | return retval; |
3925 | } | 3955 | } |
3926 | 3956 | ||
3927 | /* 7.1.12 Enable/Disable message fragmentation (SCTP_DISABLE_FRAGMENTS) | 3957 | /* 7.1.12 Enable/Disable message fragmentation (SCTP_DISABLE_FRAGMENTS) |
@@ -4292,9 +4322,8 @@ static int sctp_getsockopt_delayed_ack(struct sock *sk, int len, | |||
4292 | if (copy_from_user(¶ms, optval, len)) | 4322 | if (copy_from_user(¶ms, optval, len)) |
4293 | return -EFAULT; | 4323 | return -EFAULT; |
4294 | } else if (len == sizeof(struct sctp_assoc_value)) { | 4324 | } else if (len == sizeof(struct sctp_assoc_value)) { |
4295 | printk(KERN_WARNING "SCTP: Use of struct sctp_assoc_value " | 4325 | pr_warn("Use of struct sctp_assoc_value in delayed_ack socket option deprecated\n"); |
4296 | "in delayed_ack socket option deprecated\n"); | 4326 | pr_warn("Use struct sctp_sack_info instead\n"); |
4297 | printk(KERN_WARNING "SCTP: Use struct sctp_sack_info instead\n"); | ||
4298 | if (copy_from_user(¶ms, optval, len)) | 4327 | if (copy_from_user(¶ms, optval, len)) |
4299 | return -EFAULT; | 4328 | return -EFAULT; |
4300 | } else | 4329 | } else |
@@ -4940,10 +4969,8 @@ static int sctp_getsockopt_maxseg(struct sock *sk, int len, | |||
4940 | struct sctp_association *asoc; | 4969 | struct sctp_association *asoc; |
4941 | 4970 | ||
4942 | if (len == sizeof(int)) { | 4971 | if (len == sizeof(int)) { |
4943 | printk(KERN_WARNING | 4972 | pr_warn("Use of int in maxseg socket option deprecated\n"); |
4944 | "SCTP: Use of int in maxseg socket option deprecated\n"); | 4973 | pr_warn("Use struct sctp_assoc_value instead\n"); |
4945 | printk(KERN_WARNING | ||
4946 | "SCTP: Use struct sctp_assoc_value instead\n"); | ||
4947 | params.assoc_id = 0; | 4974 | params.assoc_id = 0; |
4948 | } else if (len >= sizeof(struct sctp_assoc_value)) { | 4975 | } else if (len >= sizeof(struct sctp_assoc_value)) { |
4949 | len = sizeof(struct sctp_assoc_value); | 4976 | len = sizeof(struct sctp_assoc_value); |
@@ -5034,10 +5061,8 @@ static int sctp_getsockopt_maxburst(struct sock *sk, int len, | |||
5034 | struct sctp_association *asoc; | 5061 | struct sctp_association *asoc; |
5035 | 5062 | ||
5036 | if (len == sizeof(int)) { | 5063 | if (len == sizeof(int)) { |
5037 | printk(KERN_WARNING | 5064 | pr_warn("Use of int in max_burst socket option deprecated\n"); |
5038 | "SCTP: Use of int in max_burst socket option deprecated\n"); | 5065 | pr_warn("Use struct sctp_assoc_value instead\n"); |
5039 | printk(KERN_WARNING | ||
5040 | "SCTP: Use struct sctp_assoc_value instead\n"); | ||
5041 | params.assoc_id = 0; | 5066 | params.assoc_id = 0; |
5042 | } else if (len >= sizeof(struct sctp_assoc_value)) { | 5067 | } else if (len >= sizeof(struct sctp_assoc_value)) { |
5043 | len = sizeof(struct sctp_assoc_value); | 5068 | len = sizeof(struct sctp_assoc_value); |
@@ -5580,7 +5605,7 @@ static int sctp_get_port(struct sock *sk, unsigned short snum) | |||
5580 | /* Note: sk->sk_num gets filled in if ephemeral port request. */ | 5605 | /* Note: sk->sk_num gets filled in if ephemeral port request. */ |
5581 | ret = sctp_get_port_local(sk, &addr); | 5606 | ret = sctp_get_port_local(sk, &addr); |
5582 | 5607 | ||
5583 | return (ret ? 1 : 0); | 5608 | return ret ? 1 : 0; |
5584 | } | 5609 | } |
5585 | 5610 | ||
5586 | /* | 5611 | /* |
@@ -5597,8 +5622,7 @@ SCTP_STATIC int sctp_listen_start(struct sock *sk, int backlog) | |||
5597 | tfm = crypto_alloc_hash(sctp_hmac_alg, 0, CRYPTO_ALG_ASYNC); | 5622 | tfm = crypto_alloc_hash(sctp_hmac_alg, 0, CRYPTO_ALG_ASYNC); |
5598 | if (IS_ERR(tfm)) { | 5623 | if (IS_ERR(tfm)) { |
5599 | if (net_ratelimit()) { | 5624 | if (net_ratelimit()) { |
5600 | printk(KERN_INFO | 5625 | pr_info("failed to load transform for %s: %ld\n", |
5601 | "SCTP: failed to load transform for %s: %ld\n", | ||
5602 | sctp_hmac_alg, PTR_ERR(tfm)); | 5626 | sctp_hmac_alg, PTR_ERR(tfm)); |
5603 | } | 5627 | } |
5604 | return -ENOSYS; | 5628 | return -ENOSYS; |
@@ -5727,13 +5751,12 @@ unsigned int sctp_poll(struct file *file, struct socket *sock, poll_table *wait) | |||
5727 | if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) | 5751 | if (sk->sk_err || !skb_queue_empty(&sk->sk_error_queue)) |
5728 | mask |= POLLERR; | 5752 | mask |= POLLERR; |
5729 | if (sk->sk_shutdown & RCV_SHUTDOWN) | 5753 | if (sk->sk_shutdown & RCV_SHUTDOWN) |
5730 | mask |= POLLRDHUP; | 5754 | mask |= POLLRDHUP | POLLIN | POLLRDNORM; |
5731 | if (sk->sk_shutdown == SHUTDOWN_MASK) | 5755 | if (sk->sk_shutdown == SHUTDOWN_MASK) |
5732 | mask |= POLLHUP; | 5756 | mask |= POLLHUP; |
5733 | 5757 | ||
5734 | /* Is it readable? Reconsider this code with TCP-style support. */ | 5758 | /* Is it readable? Reconsider this code with TCP-style support. */ |
5735 | if (!skb_queue_empty(&sk->sk_receive_queue) || | 5759 | if (!skb_queue_empty(&sk->sk_receive_queue)) |
5736 | (sk->sk_shutdown & RCV_SHUTDOWN)) | ||
5737 | mask |= POLLIN | POLLRDNORM; | 5760 | mask |= POLLIN | POLLRDNORM; |
5738 | 5761 | ||
5739 | /* The association is either gone or not ready. */ | 5762 | /* The association is either gone or not ready. */ |