From: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
To: Neil Horman <nhorman@tuxdriver.com>
Cc: linux-sctp@vger.kernel.org, netdev@vger.kernel.org,
Vlad Yasevich <vyasevich@gmail.com>,
"David S. Miller" <davem@davemloft.net>,
Andreas Steinmetz <ast@domdv.de>
Subject: Re: [PATCH v3] sctp: Add peeloff-flags socket option
Date: Sat, 01 Jul 2017 17:29:19 +0000 [thread overview]
Message-ID: <20170701172919.GQ18138@localhost.localdomain> (raw)
In-Reply-To: <20170630173257.18990-1-nhorman@tuxdriver.com>
On Fri, Jun 30, 2017 at 01:32:57PM -0400, Neil Horman wrote:
> Based on a request raised on the sctp devel list, there is a need to
> augment the sctp_peeloff operation while specifying the O_CLOEXEC and
> O_NONBLOCK flags (simmilar to the socket syscall). Since modifying the
> SCTP_SOCKOPT_PEELOFF socket option would break user space ABI for existing
> programs, this patch creates a new socket option
> SCTP_SOCKOPT_PEELOFF_FLAGS, which accepts a third flags parameter to
> allow atomic assignment of the socket descriptor flags.
>
> Tested successfully by myself and the requestor
>
> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
> CC: Vlad Yasevich <vyasevich@gmail.com>
> CC: "David S. Miller" <davem@davemloft.net>
> CC: Andreas Steinmetz <ast@domdv.de>
> CC: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Thanks!
>
> ---
> Change notes:
>
> v2)
>
> * Per Marcellos comments, move to use of get_unused_fd_flags() and
> clean up code to independently set CLOEXEC
>
> * clean up a stray tab
>
> v3)
>
> * Clean up some long lines
> ---
> include/uapi/linux/sctp.h | 6 ++++
> net/sctp/socket.c | 87 +++++++++++++++++++++++++++++++++++++++--------
> 2 files changed, 78 insertions(+), 15 deletions(-)
>
> diff --git a/include/uapi/linux/sctp.h b/include/uapi/linux/sctp.h
> index ced9d8b..6217ff8 100644
> --- a/include/uapi/linux/sctp.h
> +++ b/include/uapi/linux/sctp.h
> @@ -121,6 +121,7 @@ typedef __s32 sctp_assoc_t;
> #define SCTP_RESET_STREAMS 119
> #define SCTP_RESET_ASSOC 120
> #define SCTP_ADD_STREAMS 121
> +#define SCTP_SOCKOPT_PEELOFF_FLAGS 122
>
> /* PR-SCTP policies */
> #define SCTP_PR_SCTP_NONE 0x0000
> @@ -978,6 +979,11 @@ typedef struct {
> int sd;
> } sctp_peeloff_arg_t;
>
> +typedef struct {
> + sctp_peeloff_arg_t p_arg;
> + unsigned flags;
> +} sctp_peeloff_flags_arg_t;
> +
> /*
> * Peer Address Thresholds socket option
> */
> diff --git a/net/sctp/socket.c b/net/sctp/socket.c
> index 7b6e20e..72de049 100644
> --- a/net/sctp/socket.c
> +++ b/net/sctp/socket.c
> @@ -4933,11 +4933,47 @@ int sctp_do_peeloff(struct sock *sk, sctp_assoc_t id, struct socket **sockp)
> }
> EXPORT_SYMBOL(sctp_do_peeloff);
>
> +static int sctp_getsockopt_peeloff_common(struct sock *sk, sctp_peeloff_arg_t *peeloff,
> + struct file **newfile, unsigned flags)
> +{
> + struct socket *newsock;
> + int retval;
> +
> + retval = sctp_do_peeloff(sk, peeloff->associd, &newsock);
> + if (retval < 0)
> + goto out;
> +
> + /* Map the socket to an unused fd that can be returned to the user. */
> + retval = get_unused_fd_flags(flags & SOCK_CLOEXEC);
> + if (retval < 0) {
> + sock_release(newsock);
> + goto out;
> + }
> +
> + *newfile = sock_alloc_file(newsock, 0, NULL);
> + if (IS_ERR(*newfile)) {
> + put_unused_fd(retval);
> + sock_release(newsock);
> + retval = PTR_ERR(*newfile);
> + *newfile = NULL;
> + return retval;
> + }
> +
> + pr_debug("%s: sk:%p, newsk:%p, sd:%d\n", __func__, sk, newsock->sk,
> + retval);
> +
> + peeloff->sd = retval;
> +
> + if (flags & SOCK_NONBLOCK)
> + (*newfile)->f_flags |= O_NONBLOCK;
> +out:
> + return retval;
> +}
> +
> static int sctp_getsockopt_peeloff(struct sock *sk, int len, char __user *optval, int __user *optlen)
> {
> sctp_peeloff_arg_t peeloff;
> - struct socket *newsock;
> - struct file *newfile;
> + struct file *newfile = NULL;
> int retval = 0;
>
> if (len < sizeof(sctp_peeloff_arg_t))
> @@ -4946,26 +4982,44 @@ static int sctp_getsockopt_peeloff(struct sock *sk, int len, char __user *optval
> if (copy_from_user(&peeloff, optval, len))
> return -EFAULT;
>
> - retval = sctp_do_peeloff(sk, peeloff.associd, &newsock);
> + retval = sctp_getsockopt_peeloff_common(sk, &peeloff, &newfile, 0);
> if (retval < 0)
> goto out;
>
> - /* Map the socket to an unused fd that can be returned to the user. */
> - retval = get_unused_fd_flags(0);
> - if (retval < 0) {
> - sock_release(newsock);
> - goto out;
> + /* Return the fd mapped to the new socket. */
> + if (put_user(len, optlen)) {
> + fput(newfile);
> + put_unused_fd(retval);
> + return -EFAULT;
> }
>
> - newfile = sock_alloc_file(newsock, 0, NULL);
> - if (IS_ERR(newfile)) {
> + if (copy_to_user(optval, &peeloff, len)) {
> + fput(newfile);
> put_unused_fd(retval);
> - sock_release(newsock);
> - return PTR_ERR(newfile);
> + return -EFAULT;
> }
> + fd_install(retval, newfile);
> +out:
> + return retval;
> +}
>
> - pr_debug("%s: sk:%p, newsk:%p, sd:%d\n", __func__, sk, newsock->sk,
> - retval);
> +static int sctp_getsockopt_peeloff_flags(struct sock *sk, int len,
> + char __user *optval, int __user *optlen)
> +{
> + sctp_peeloff_flags_arg_t peeloff;
> + struct file *newfile = NULL;
> + int retval = 0;
> +
> + if (len < sizeof(sctp_peeloff_flags_arg_t))
> + return -EINVAL;
> + len = sizeof(sctp_peeloff_flags_arg_t);
> + if (copy_from_user(&peeloff, optval, len))
> + return -EFAULT;
> +
> + retval = sctp_getsockopt_peeloff_common(sk, &peeloff.p_arg,
> + &newfile, peeloff.flags);
> + if (retval < 0)
> + goto out;
>
> /* Return the fd mapped to the new socket. */
> if (put_user(len, optlen)) {
> @@ -4973,7 +5027,7 @@ static int sctp_getsockopt_peeloff(struct sock *sk, int len, char __user *optval
> put_unused_fd(retval);
> return -EFAULT;
> }
> - peeloff.sd = retval;
> +
> if (copy_to_user(optval, &peeloff, len)) {
> fput(newfile);
> put_unused_fd(retval);
> @@ -6758,6 +6812,9 @@ static int sctp_getsockopt(struct sock *sk, int level, int optname,
> case SCTP_SOCKOPT_PEELOFF:
> retval = sctp_getsockopt_peeloff(sk, len, optval, optlen);
> break;
> + case SCTP_SOCKOPT_PEELOFF_FLAGS:
> + retval = sctp_getsockopt_peeloff_flags(sk, len, optval, optlen);
> + break;
> case SCTP_PEER_ADDR_PARAMS:
> retval = sctp_getsockopt_peer_addr_params(sk, len, optval,
> optlen);
> --
> 2.9.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sctp" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
WARNING: multiple messages have this Message-ID (diff)
From: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
To: Neil Horman <nhorman@tuxdriver.com>
Cc: linux-sctp@vger.kernel.org, netdev@vger.kernel.org,
Vlad Yasevich <vyasevich@gmail.com>,
"David S. Miller" <davem@davemloft.net>,
Andreas Steinmetz <ast@domdv.de>
Subject: Re: [PATCH v3] sctp: Add peeloff-flags socket option
Date: Sat, 1 Jul 2017 14:29:19 -0300 [thread overview]
Message-ID: <20170701172919.GQ18138@localhost.localdomain> (raw)
In-Reply-To: <20170630173257.18990-1-nhorman@tuxdriver.com>
On Fri, Jun 30, 2017 at 01:32:57PM -0400, Neil Horman wrote:
> Based on a request raised on the sctp devel list, there is a need to
> augment the sctp_peeloff operation while specifying the O_CLOEXEC and
> O_NONBLOCK flags (simmilar to the socket syscall). Since modifying the
> SCTP_SOCKOPT_PEELOFF socket option would break user space ABI for existing
> programs, this patch creates a new socket option
> SCTP_SOCKOPT_PEELOFF_FLAGS, which accepts a third flags parameter to
> allow atomic assignment of the socket descriptor flags.
>
> Tested successfully by myself and the requestor
>
> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
> CC: Vlad Yasevich <vyasevich@gmail.com>
> CC: "David S. Miller" <davem@davemloft.net>
> CC: Andreas Steinmetz <ast@domdv.de>
> CC: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Thanks!
>
> ---
> Change notes:
>
> v2)
>
> * Per Marcellos comments, move to use of get_unused_fd_flags() and
> clean up code to independently set CLOEXEC
>
> * clean up a stray tab
>
> v3)
>
> * Clean up some long lines
> ---
> include/uapi/linux/sctp.h | 6 ++++
> net/sctp/socket.c | 87 +++++++++++++++++++++++++++++++++++++++--------
> 2 files changed, 78 insertions(+), 15 deletions(-)
>
> diff --git a/include/uapi/linux/sctp.h b/include/uapi/linux/sctp.h
> index ced9d8b..6217ff8 100644
> --- a/include/uapi/linux/sctp.h
> +++ b/include/uapi/linux/sctp.h
> @@ -121,6 +121,7 @@ typedef __s32 sctp_assoc_t;
> #define SCTP_RESET_STREAMS 119
> #define SCTP_RESET_ASSOC 120
> #define SCTP_ADD_STREAMS 121
> +#define SCTP_SOCKOPT_PEELOFF_FLAGS 122
>
> /* PR-SCTP policies */
> #define SCTP_PR_SCTP_NONE 0x0000
> @@ -978,6 +979,11 @@ typedef struct {
> int sd;
> } sctp_peeloff_arg_t;
>
> +typedef struct {
> + sctp_peeloff_arg_t p_arg;
> + unsigned flags;
> +} sctp_peeloff_flags_arg_t;
> +
> /*
> * Peer Address Thresholds socket option
> */
> diff --git a/net/sctp/socket.c b/net/sctp/socket.c
> index 7b6e20e..72de049 100644
> --- a/net/sctp/socket.c
> +++ b/net/sctp/socket.c
> @@ -4933,11 +4933,47 @@ int sctp_do_peeloff(struct sock *sk, sctp_assoc_t id, struct socket **sockp)
> }
> EXPORT_SYMBOL(sctp_do_peeloff);
>
> +static int sctp_getsockopt_peeloff_common(struct sock *sk, sctp_peeloff_arg_t *peeloff,
> + struct file **newfile, unsigned flags)
> +{
> + struct socket *newsock;
> + int retval;
> +
> + retval = sctp_do_peeloff(sk, peeloff->associd, &newsock);
> + if (retval < 0)
> + goto out;
> +
> + /* Map the socket to an unused fd that can be returned to the user. */
> + retval = get_unused_fd_flags(flags & SOCK_CLOEXEC);
> + if (retval < 0) {
> + sock_release(newsock);
> + goto out;
> + }
> +
> + *newfile = sock_alloc_file(newsock, 0, NULL);
> + if (IS_ERR(*newfile)) {
> + put_unused_fd(retval);
> + sock_release(newsock);
> + retval = PTR_ERR(*newfile);
> + *newfile = NULL;
> + return retval;
> + }
> +
> + pr_debug("%s: sk:%p, newsk:%p, sd:%d\n", __func__, sk, newsock->sk,
> + retval);
> +
> + peeloff->sd = retval;
> +
> + if (flags & SOCK_NONBLOCK)
> + (*newfile)->f_flags |= O_NONBLOCK;
> +out:
> + return retval;
> +}
> +
> static int sctp_getsockopt_peeloff(struct sock *sk, int len, char __user *optval, int __user *optlen)
> {
> sctp_peeloff_arg_t peeloff;
> - struct socket *newsock;
> - struct file *newfile;
> + struct file *newfile = NULL;
> int retval = 0;
>
> if (len < sizeof(sctp_peeloff_arg_t))
> @@ -4946,26 +4982,44 @@ static int sctp_getsockopt_peeloff(struct sock *sk, int len, char __user *optval
> if (copy_from_user(&peeloff, optval, len))
> return -EFAULT;
>
> - retval = sctp_do_peeloff(sk, peeloff.associd, &newsock);
> + retval = sctp_getsockopt_peeloff_common(sk, &peeloff, &newfile, 0);
> if (retval < 0)
> goto out;
>
> - /* Map the socket to an unused fd that can be returned to the user. */
> - retval = get_unused_fd_flags(0);
> - if (retval < 0) {
> - sock_release(newsock);
> - goto out;
> + /* Return the fd mapped to the new socket. */
> + if (put_user(len, optlen)) {
> + fput(newfile);
> + put_unused_fd(retval);
> + return -EFAULT;
> }
>
> - newfile = sock_alloc_file(newsock, 0, NULL);
> - if (IS_ERR(newfile)) {
> + if (copy_to_user(optval, &peeloff, len)) {
> + fput(newfile);
> put_unused_fd(retval);
> - sock_release(newsock);
> - return PTR_ERR(newfile);
> + return -EFAULT;
> }
> + fd_install(retval, newfile);
> +out:
> + return retval;
> +}
>
> - pr_debug("%s: sk:%p, newsk:%p, sd:%d\n", __func__, sk, newsock->sk,
> - retval);
> +static int sctp_getsockopt_peeloff_flags(struct sock *sk, int len,
> + char __user *optval, int __user *optlen)
> +{
> + sctp_peeloff_flags_arg_t peeloff;
> + struct file *newfile = NULL;
> + int retval = 0;
> +
> + if (len < sizeof(sctp_peeloff_flags_arg_t))
> + return -EINVAL;
> + len = sizeof(sctp_peeloff_flags_arg_t);
> + if (copy_from_user(&peeloff, optval, len))
> + return -EFAULT;
> +
> + retval = sctp_getsockopt_peeloff_common(sk, &peeloff.p_arg,
> + &newfile, peeloff.flags);
> + if (retval < 0)
> + goto out;
>
> /* Return the fd mapped to the new socket. */
> if (put_user(len, optlen)) {
> @@ -4973,7 +5027,7 @@ static int sctp_getsockopt_peeloff(struct sock *sk, int len, char __user *optval
> put_unused_fd(retval);
> return -EFAULT;
> }
> - peeloff.sd = retval;
> +
> if (copy_to_user(optval, &peeloff, len)) {
> fput(newfile);
> put_unused_fd(retval);
> @@ -6758,6 +6812,9 @@ static int sctp_getsockopt(struct sock *sk, int level, int optname,
> case SCTP_SOCKOPT_PEELOFF:
> retval = sctp_getsockopt_peeloff(sk, len, optval, optlen);
> break;
> + case SCTP_SOCKOPT_PEELOFF_FLAGS:
> + retval = sctp_getsockopt_peeloff_flags(sk, len, optval, optlen);
> + break;
> case SCTP_PEER_ADDR_PARAMS:
> retval = sctp_getsockopt_peer_addr_params(sk, len, optval,
> optlen);
> --
> 2.9.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-sctp" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
next prev parent reply other threads:[~2017-07-01 17:29 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-06-29 18:13 [PATCH] sctp: Add peeloff-flags socket option Neil Horman
2017-06-29 18:13 ` Neil Horman
2017-06-29 19:04 ` Marcelo Ricardo Leitner
2017-06-29 19:04 ` Marcelo Ricardo Leitner
2017-06-29 22:56 ` Al Viro
2017-06-29 22:56 ` Al Viro
2017-06-30 15:35 ` [PATCH v2] " Neil Horman
2017-06-30 15:35 ` Neil Horman
2017-06-30 16:29 ` Marcelo Ricardo Leitner
2017-06-30 16:29 ` Marcelo Ricardo Leitner
2017-06-30 17:32 ` [PATCH v3] " Neil Horman
2017-06-30 17:32 ` Neil Horman
2017-07-01 17:29 ` Marcelo Ricardo Leitner [this message]
2017-07-01 17:29 ` Marcelo Ricardo Leitner
2017-07-01 22:26 ` David Miller
2017-07-01 22:26 ` David Miller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170701172919.GQ18138@localhost.localdomain \
--to=marcelo.leitner@gmail.com \
--cc=ast@domdv.de \
--cc=davem@davemloft.net \
--cc=linux-sctp@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=nhorman@tuxdriver.com \
--cc=vyasevich@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.