All of lore.kernel.org
 help / color / mirror / Atom feed
From: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
To: Xin Long <lucien.xin@gmail.com>
Cc: network dev <netdev@vger.kernel.org>,
	linux-sctp@vger.kernel.org, Neil Horman <nhorman@tuxdriver.com>,
	davem@davemloft.net
Subject: Re: [PATCH net-next 2/3] sctp: add support for SCTP_DSTADDRV4/6 Information for sendmsg
Date: Mon, 05 Mar 2018 23:39:34 +0000	[thread overview]
Message-ID: <20180305233934.GA27351@localhost.localdomain> (raw)
In-Reply-To: <6ea3660f31c8410bc9e54f32734e4fddab85cf49.1520253539.git.lucien.xin@gmail.com>

On Mon, Mar 05, 2018 at 08:44:19PM +0800, Xin Long wrote:
> This patch is to add support for Destination IPv4/6 Address options
> for sendmsg, as described in section 5.3.9/10 of RFC6458.
> 
> With this option, you can provide more than one destination addrs
> to sendmsg when creating asoc, like sctp_connectx.
> 
> It's also a necessary send info for sctp_sendv.
> 
> Signed-off-by: Xin Long <lucien.xin@gmail.com>
> ---
>  include/net/sctp/structs.h |  1 +
>  include/uapi/linux/sctp.h  |  6 ++++
>  net/sctp/socket.c          | 77 ++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 84 insertions(+)
> 
> diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
> index d40a2a3..ec6e46b 100644
> --- a/include/net/sctp/structs.h
> +++ b/include/net/sctp/structs.h
> @@ -2113,6 +2113,7 @@ struct sctp_cmsgs {
>  	struct sctp_sndrcvinfo *srinfo;
>  	struct sctp_sndinfo *sinfo;
>  	struct sctp_prinfo *prinfo;
> +	struct msghdr *addrs_msg;
>  };
>  
>  /* Structure for tracking memory objects */
> diff --git a/include/uapi/linux/sctp.h b/include/uapi/linux/sctp.h
> index 0dd1f82..a1bc350 100644
> --- a/include/uapi/linux/sctp.h
> +++ b/include/uapi/linux/sctp.h
> @@ -308,6 +308,12 @@ typedef enum sctp_cmsg_type {
>  #define SCTP_NXTINFO	SCTP_NXTINFO
>  	SCTP_PRINFO,		/* 5.3.7 SCTP PR-SCTP Information Structure */
>  #define SCTP_PRINFO	SCTP_PRINFO
> +	SCTP_AUTHINFO,		/* 5.3.8 SCTP AUTH Information Structure (RESERVED) */
> +#define SCTP_AUTHINFO	SCTP_AUTHINFO
> +	SCTP_DSTADDRV4,		/* 5.3.9 SCTP Destination IPv4 Address Structure */
> +#define SCTP_DSTADDRV4	SCTP_DSTADDRV4
> +	SCTP_DSTADDRV6,		/* 5.3.10 SCTP Destination IPv6 Address Structure */
> +#define SCTP_DSTADDRV6	SCTP_DSTADDRV6
>  } sctp_cmsg_t;
>  
>  /*
> diff --git a/net/sctp/socket.c b/net/sctp/socket.c
> index fdde697..067b57a 100644
> --- a/net/sctp/socket.c
> +++ b/net/sctp/socket.c
> @@ -1676,6 +1676,7 @@ static int sctp_sendmsg_new_asoc(struct sock *sk, __u16 sflags,
>  	struct net *net = sock_net(sk);
>  	struct sctp_association *asoc;
>  	enum sctp_scope scope;
> +	struct cmsghdr *cmsg;
>  	int err = -EINVAL;
>  
>  	*tp = NULL;
> @@ -1741,6 +1742,67 @@ static int sctp_sendmsg_new_asoc(struct sock *sk, __u16 sflags,
>  		goto free;
>  	}
>  
> +	if (!cmsgs->addrs_msg)
> +		return 0;
> +
> +	/* sendv addr list parse */
> +	for_each_cmsghdr(cmsg, cmsgs->addrs_msg) {
> +		struct sctp_transport *transport;
> +		struct sctp_association *old;
> +		union sctp_addr _daddr;
> +		int dlen;
> +
> +		if (cmsg->cmsg_level != IPPROTO_SCTP ||
> +		    (cmsg->cmsg_type != SCTP_DSTADDRV4 &&
> +		     cmsg->cmsg_type != SCTP_DSTADDRV6))
> +			continue;
> +
> +		daddr = &_daddr;
> +		memset(daddr, 0, sizeof(*daddr));
> +		dlen = cmsg->cmsg_len - sizeof(struct cmsghdr);
> +		if (cmsg->cmsg_type = SCTP_DSTADDRV4) {
> +			if (dlen < sizeof(struct in_addr))
> +				goto free;
> +
> +			dlen = sizeof(struct in_addr);
> +			daddr->v4.sin_family = AF_INET;
> +			daddr->v4.sin_port = htons(asoc->peer.port);
> +			memcpy(&daddr->v4.sin_addr, CMSG_DATA(cmsg), dlen);
> +		} else {
> +			if (dlen < sizeof(struct in6_addr))
> +				goto free;
> +
> +			dlen = sizeof(struct in6_addr);
> +			daddr->v6.sin6_family = AF_INET6;
> +			daddr->v6.sin6_port = htons(asoc->peer.port);
> +			memcpy(&daddr->v6.sin6_addr, CMSG_DATA(cmsg), dlen);
> +		}
> +		err = sctp_verify_addr(sk, daddr, sizeof(*daddr));
> +		if (err)
> +			goto free;
> +
> +		old = sctp_endpoint_lookup_assoc(ep, daddr, &transport);
> +		if (old && old != asoc) {
> +			if (old->state >= SCTP_STATE_ESTABLISHED)
> +				err = -EISCONN;
> +			else
> +				err = -EALREADY;
> +			goto free;
> +		}
> +
> +		if (sctp_endpoint_is_peeled_off(ep, daddr)) {
> +			err = -EADDRNOTAVAIL;
> +			goto free;
> +		}
> +
> +		transport = sctp_assoc_add_peer(asoc, daddr, GFP_KERNEL,
> +						SCTP_UNKNOWN);
> +		if (!transport) {
> +			err = -ENOMEM;
> +			goto free;
> +		}
> +	}
> +
>  	return 0;
>  
>  free:
> @@ -7778,6 +7840,21 @@ static int sctp_msghdr_parse(const struct msghdr *msg, struct sctp_cmsgs *cmsgs)
>  			if (cmsgs->prinfo->pr_policy = SCTP_PR_SCTP_NONE)
>  				cmsgs->prinfo->pr_value = 0;
>  			break;
> +		case SCTP_DSTADDRV4:
> +		case SCTP_DSTADDRV6:
> +			/* SCTP Socket API Extension
> +			 * 5.3.9/10 SCTP Destination IPv4/6 Address Structure (SCTP_DSTADDRV4/6)
> +			 *
> +			 * This cmsghdr structure specifies SCTP options for sendmsg().
> +			 *
> +			 * cmsg_level    cmsg_type         cmsg_data[]
> +			 * ------------  ------------   ---------------------
> +			 * IPPROTO_SCTP  SCTP_DSTADDRV4 struct in_addr
> +			 * ------------  ------------   ---------------------
> +			 * IPPROTO_SCTP  SCTP_DSTADDRV6 struct in6_addr
> +			 */
> +			cmsgs->addrs_msg = my_msg;

I think this is being handled differently from what the RFC specifies.
AFAIU the rfc defines these two options being each one an array of a
specific element type, in_addr and in6_addr.

The patch is saving both options into a single pointer, which later is
processed as a list of (in_addr or in6_addr) elements.

If an application specifies both options, each with a list of its own
addresses, it will ignore one of the options.

> +			break;
>  		default:
>  			return -EINVAL;
>  		}
> -- 
> 2.1.0
> 

WARNING: multiple messages have this Message-ID (diff)
From: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
To: Xin Long <lucien.xin@gmail.com>
Cc: network dev <netdev@vger.kernel.org>,
	linux-sctp@vger.kernel.org, Neil Horman <nhorman@tuxdriver.com>,
	davem@davemloft.net
Subject: Re: [PATCH net-next 2/3] sctp: add support for SCTP_DSTADDRV4/6 Information for sendmsg
Date: Mon, 5 Mar 2018 20:39:34 -0300	[thread overview]
Message-ID: <20180305233934.GA27351@localhost.localdomain> (raw)
In-Reply-To: <6ea3660f31c8410bc9e54f32734e4fddab85cf49.1520253539.git.lucien.xin@gmail.com>

On Mon, Mar 05, 2018 at 08:44:19PM +0800, Xin Long wrote:
> This patch is to add support for Destination IPv4/6 Address options
> for sendmsg, as described in section 5.3.9/10 of RFC6458.
> 
> With this option, you can provide more than one destination addrs
> to sendmsg when creating asoc, like sctp_connectx.
> 
> It's also a necessary send info for sctp_sendv.
> 
> Signed-off-by: Xin Long <lucien.xin@gmail.com>
> ---
>  include/net/sctp/structs.h |  1 +
>  include/uapi/linux/sctp.h  |  6 ++++
>  net/sctp/socket.c          | 77 ++++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 84 insertions(+)
> 
> diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
> index d40a2a3..ec6e46b 100644
> --- a/include/net/sctp/structs.h
> +++ b/include/net/sctp/structs.h
> @@ -2113,6 +2113,7 @@ struct sctp_cmsgs {
>  	struct sctp_sndrcvinfo *srinfo;
>  	struct sctp_sndinfo *sinfo;
>  	struct sctp_prinfo *prinfo;
> +	struct msghdr *addrs_msg;
>  };
>  
>  /* Structure for tracking memory objects */
> diff --git a/include/uapi/linux/sctp.h b/include/uapi/linux/sctp.h
> index 0dd1f82..a1bc350 100644
> --- a/include/uapi/linux/sctp.h
> +++ b/include/uapi/linux/sctp.h
> @@ -308,6 +308,12 @@ typedef enum sctp_cmsg_type {
>  #define SCTP_NXTINFO	SCTP_NXTINFO
>  	SCTP_PRINFO,		/* 5.3.7 SCTP PR-SCTP Information Structure */
>  #define SCTP_PRINFO	SCTP_PRINFO
> +	SCTP_AUTHINFO,		/* 5.3.8 SCTP AUTH Information Structure (RESERVED) */
> +#define SCTP_AUTHINFO	SCTP_AUTHINFO
> +	SCTP_DSTADDRV4,		/* 5.3.9 SCTP Destination IPv4 Address Structure */
> +#define SCTP_DSTADDRV4	SCTP_DSTADDRV4
> +	SCTP_DSTADDRV6,		/* 5.3.10 SCTP Destination IPv6 Address Structure */
> +#define SCTP_DSTADDRV6	SCTP_DSTADDRV6
>  } sctp_cmsg_t;
>  
>  /*
> diff --git a/net/sctp/socket.c b/net/sctp/socket.c
> index fdde697..067b57a 100644
> --- a/net/sctp/socket.c
> +++ b/net/sctp/socket.c
> @@ -1676,6 +1676,7 @@ static int sctp_sendmsg_new_asoc(struct sock *sk, __u16 sflags,
>  	struct net *net = sock_net(sk);
>  	struct sctp_association *asoc;
>  	enum sctp_scope scope;
> +	struct cmsghdr *cmsg;
>  	int err = -EINVAL;
>  
>  	*tp = NULL;
> @@ -1741,6 +1742,67 @@ static int sctp_sendmsg_new_asoc(struct sock *sk, __u16 sflags,
>  		goto free;
>  	}
>  
> +	if (!cmsgs->addrs_msg)
> +		return 0;
> +
> +	/* sendv addr list parse */
> +	for_each_cmsghdr(cmsg, cmsgs->addrs_msg) {
> +		struct sctp_transport *transport;
> +		struct sctp_association *old;
> +		union sctp_addr _daddr;
> +		int dlen;
> +
> +		if (cmsg->cmsg_level != IPPROTO_SCTP ||
> +		    (cmsg->cmsg_type != SCTP_DSTADDRV4 &&
> +		     cmsg->cmsg_type != SCTP_DSTADDRV6))
> +			continue;
> +
> +		daddr = &_daddr;
> +		memset(daddr, 0, sizeof(*daddr));
> +		dlen = cmsg->cmsg_len - sizeof(struct cmsghdr);
> +		if (cmsg->cmsg_type == SCTP_DSTADDRV4) {
> +			if (dlen < sizeof(struct in_addr))
> +				goto free;
> +
> +			dlen = sizeof(struct in_addr);
> +			daddr->v4.sin_family = AF_INET;
> +			daddr->v4.sin_port = htons(asoc->peer.port);
> +			memcpy(&daddr->v4.sin_addr, CMSG_DATA(cmsg), dlen);
> +		} else {
> +			if (dlen < sizeof(struct in6_addr))
> +				goto free;
> +
> +			dlen = sizeof(struct in6_addr);
> +			daddr->v6.sin6_family = AF_INET6;
> +			daddr->v6.sin6_port = htons(asoc->peer.port);
> +			memcpy(&daddr->v6.sin6_addr, CMSG_DATA(cmsg), dlen);
> +		}
> +		err = sctp_verify_addr(sk, daddr, sizeof(*daddr));
> +		if (err)
> +			goto free;
> +
> +		old = sctp_endpoint_lookup_assoc(ep, daddr, &transport);
> +		if (old && old != asoc) {
> +			if (old->state >= SCTP_STATE_ESTABLISHED)
> +				err = -EISCONN;
> +			else
> +				err = -EALREADY;
> +			goto free;
> +		}
> +
> +		if (sctp_endpoint_is_peeled_off(ep, daddr)) {
> +			err = -EADDRNOTAVAIL;
> +			goto free;
> +		}
> +
> +		transport = sctp_assoc_add_peer(asoc, daddr, GFP_KERNEL,
> +						SCTP_UNKNOWN);
> +		if (!transport) {
> +			err = -ENOMEM;
> +			goto free;
> +		}
> +	}
> +
>  	return 0;
>  
>  free:
> @@ -7778,6 +7840,21 @@ static int sctp_msghdr_parse(const struct msghdr *msg, struct sctp_cmsgs *cmsgs)
>  			if (cmsgs->prinfo->pr_policy == SCTP_PR_SCTP_NONE)
>  				cmsgs->prinfo->pr_value = 0;
>  			break;
> +		case SCTP_DSTADDRV4:
> +		case SCTP_DSTADDRV6:
> +			/* SCTP Socket API Extension
> +			 * 5.3.9/10 SCTP Destination IPv4/6 Address Structure (SCTP_DSTADDRV4/6)
> +			 *
> +			 * This cmsghdr structure specifies SCTP options for sendmsg().
> +			 *
> +			 * cmsg_level    cmsg_type         cmsg_data[]
> +			 * ------------  ------------   ---------------------
> +			 * IPPROTO_SCTP  SCTP_DSTADDRV4 struct in_addr
> +			 * ------------  ------------   ---------------------
> +			 * IPPROTO_SCTP  SCTP_DSTADDRV6 struct in6_addr
> +			 */
> +			cmsgs->addrs_msg = my_msg;

I think this is being handled differently from what the RFC specifies.
AFAIU the rfc defines these two options being each one an array of a
specific element type, in_addr and in6_addr.

The patch is saving both options into a single pointer, which later is
processed as a list of (in_addr or in6_addr) elements.

If an application specifies both options, each with a list of its own
addresses, it will ignore one of the options.

> +			break;
>  		default:
>  			return -EINVAL;
>  		}
> -- 
> 2.1.0
> 

  parent reply	other threads:[~2018-03-05 23:39 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-03-05 12:44 [PATCH net-next 0/3] sctp: add support for some msg_control options from RFC6458 Xin Long
2018-03-05 12:44 ` Xin Long
2018-03-05 12:44 ` [PATCH net-next 1/3] sctp: add support for PR-SCTP Information for sendmsg Xin Long
2018-03-05 12:44   ` Xin Long
2018-03-05 12:44   ` [PATCH net-next 2/3] sctp: add support for SCTP_DSTADDRV4/6 " Xin Long
2018-03-05 12:44     ` Xin Long
2018-03-05 12:44     ` [PATCH net-next 3/3] sctp: add support for snd flag SCTP_SENDALL process in sendmsg Xin Long
2018-03-05 12:44       ` Xin Long
2018-03-06 12:22       ` Marcelo Ricardo Leitner
2018-03-06 12:22         ` Marcelo Ricardo Leitner
2018-03-05 23:39     ` Marcelo Ricardo Leitner [this message]
2018-03-05 23:39       ` [PATCH net-next 2/3] sctp: add support for SCTP_DSTADDRV4/6 Information for sendmsg Marcelo Ricardo Leitner
2018-03-06  7:03       ` Xin Long
2018-03-06  7:03         ` Xin Long
2018-03-06 12:21         ` Marcelo Ricardo Leitner
2018-03-06 12:21           ` Marcelo Ricardo Leitner
2018-03-06 12:22     ` Marcelo Ricardo Leitner
2018-03-06 12:22       ` Marcelo Ricardo Leitner
2018-03-06 12:22   ` [PATCH net-next 1/3] sctp: add support for PR-SCTP " Marcelo Ricardo Leitner
2018-03-06 12:22     ` Marcelo Ricardo Leitner
2018-03-05 23:52 ` [PATCH net-next 0/3] sctp: add support for some msg_control options from RFC6458 Marcelo Ricardo Leitner
2018-03-05 23:52   ` Marcelo Ricardo Leitner
2018-03-07 15:56 ` David Miller
2018-03-07 15:56   ` David Miller
2018-10-21  4:43 ` [PATCH net-next 0/3] sctp: add support for sk_reuseport Xin Long
2018-10-21  4:43   ` Xin Long
2018-10-21  4:43   ` [PATCH net-next 1/3] sctp: do reuseport_select_sock in __sctp_rcv_lookup_endpoint Xin Long
2018-10-21  4:43     ` Xin Long
2018-10-21  4:43     ` [PATCH net-next 2/3] sctp: add sock_reuseport for the sock in __sctp_hash_endpoint Xin Long
2018-10-21  4:43       ` Xin Long
2018-10-21  4:43       ` [PATCH net-next 3/3] sctp: process sk_reuseport in sctp_get_port_local Xin Long
2018-10-21  4:43         ` Xin Long
2018-10-22 14:15       ` [PATCH net-next 2/3] sctp: add sock_reuseport for the sock in __sctp_hash_endpoint Marcelo Ricardo Leitner
2018-10-22 14:15         ` Marcelo Ricardo Leitner
2018-11-12  9:58         ` Xin Long
2018-11-12  9:58           ` Xin Long
2018-10-22 14:17     ` [PATCH net-next 1/3] sctp: do reuseport_select_sock in __sctp_rcv_lookup_endpoint Marcelo Ricardo Leitner
2018-10-22 14:17       ` Marcelo Ricardo Leitner
2018-11-12  9:56       ` Xin Long
2018-11-12  9:56         ` Xin Long
2018-10-21  6:58   ` [PATCH net-next 0/3] sctp: add support for sk_reuseport Xin Long
2018-10-21  6:58     ` Xin Long
2018-10-22 11:40   ` Neil Horman
2018-10-22 11:40     ` Neil Horman
2018-10-22 14:20   ` Marcelo Ricardo Leitner
2018-10-22 14:20     ` Marcelo Ricardo Leitner

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=20180305233934.GA27351@localhost.localdomain \
    --to=marcelo.leitner@gmail.com \
    --cc=davem@davemloft.net \
    --cc=linux-sctp@vger.kernel.org \
    --cc=lucien.xin@gmail.com \
    --cc=netdev@vger.kernel.org \
    --cc=nhorman@tuxdriver.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.