* [PATCH net-next 0/3] sctp: add support for some msg_control options from RFC6458
@ 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
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: Xin Long @ 2018-03-05 12:44 UTC (permalink / raw)
To: network dev, linux-sctp; +Cc: Marcelo Ricardo Leitner, Neil Horman, davem
This patchset is to add support for 3 msg_control options described
in RFC6458:
5.3.7. SCTP PR-SCTP Information Structure (SCTP_PRINFO)
5.3.9. SCTP Destination IPv4 Address Structure (SCTP_DSTADDRV4)
5.3.10. SCTP Destination IPv6 Address Structure (SCTP_DSTADDRV6)
one send flag described in RFC6458:
SCTP_SENDALL: This flag, if set, will cause a one-to-many
style socket to send the message to all associations that
are currently established on this socket. For the one-to-
one style socket, this flag has no effect.
Note there is another msg_control option:
5.3.8. SCTP AUTH Information Structure (SCTP_AUTHINFO)
It's a little complicated, I will post it in another patchset after
this.
Xin Long (3):
sctp: add support for PR-SCTP Information for sendmsg
sctp: add support for SCTP_DSTADDRV4/6 Information for sendmsg
sctp: add support for snd flag SCTP_SENDALL process in sendmsg
include/net/sctp/structs.h | 2 +
include/uapi/linux/sctp.h | 23 ++++++++
net/sctp/socket.c | 143 +++++++++++++++++++++++++++++++++++++++++++--
3 files changed, 163 insertions(+), 5 deletions(-)
--
2.1.0
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH net-next 1/3] sctp: add support for PR-SCTP Information for sendmsg
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 2/3] sctp: add support for SCTP_DSTADDRV4/6 " Xin Long
2018-03-06 12:22 ` [PATCH net-next 1/3] sctp: add support for PR-SCTP " 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-07 15:56 ` David Miller
2 siblings, 2 replies; 12+ messages in thread
From: Xin Long @ 2018-03-05 12:44 UTC (permalink / raw)
To: network dev, linux-sctp; +Cc: Marcelo Ricardo Leitner, Neil Horman, davem
This patch is to add support for PR-SCTP Information for sendmsg,
as described in section 5.3.7 of RFC6458.
With this option, you can specify pr_policy and pr_value for user
data in sendmsg.
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 | 15 +++++++++++++++
net/sctp/socket.c | 31 ++++++++++++++++++++++++++++++-
3 files changed, 46 insertions(+), 1 deletion(-)
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 03e92dd..d40a2a3 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -2112,6 +2112,7 @@ struct sctp_cmsgs {
struct sctp_initmsg *init;
struct sctp_sndrcvinfo *srinfo;
struct sctp_sndinfo *sinfo;
+ struct sctp_prinfo *prinfo;
};
/* Structure for tracking memory objects */
diff --git a/include/uapi/linux/sctp.h b/include/uapi/linux/sctp.h
index 4c4db14..0dd1f82 100644
--- a/include/uapi/linux/sctp.h
+++ b/include/uapi/linux/sctp.h
@@ -260,6 +260,19 @@ struct sctp_nxtinfo {
sctp_assoc_t nxt_assoc_id;
};
+/* 5.3.7 SCTP PR-SCTP Information Structure (SCTP_PRINFO)
+ *
+ * This cmsghdr structure specifies SCTP options for sendmsg().
+ *
+ * cmsg_level cmsg_type cmsg_data[]
+ * ------------ ------------ -------------------
+ * IPPROTO_SCTP SCTP_PRINFO struct sctp_prinfo
+ */
+struct sctp_prinfo {
+ __u16 pr_policy;
+ __u32 pr_value;
+};
+
/*
* sinfo_flags: 16 bits (unsigned integer)
*
@@ -293,6 +306,8 @@ typedef enum sctp_cmsg_type {
#define SCTP_RCVINFO SCTP_RCVINFO
SCTP_NXTINFO, /* 5.3.6 SCTP Next Receive Information Structure */
#define SCTP_NXTINFO SCTP_NXTINFO
+ SCTP_PRINFO, /* 5.3.7 SCTP PR-SCTP Information Structure */
+#define SCTP_PRINFO SCTP_PRINFO
} sctp_cmsg_t;
/*
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 7fa7603..fdde697 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -1644,6 +1644,12 @@ static int sctp_sendmsg_parse(struct sock *sk, struct sctp_cmsgs *cmsgs,
srinfo->sinfo_assoc_id = cmsgs->sinfo->snd_assoc_id;
}
+ if (cmsgs->prinfo) {
+ srinfo->sinfo_timetolive = cmsgs->prinfo->pr_value;
+ SCTP_PR_SET_POLICY(srinfo->sinfo_flags,
+ cmsgs->prinfo->pr_policy);
+ }
+
sflags = srinfo->sinfo_flags;
if (!sflags && msg_len)
return 0;
@@ -1901,9 +1907,12 @@ static void sctp_sendmsg_update_sinfo(struct sctp_association *asoc,
sinfo->sinfo_ppid = asoc->default_ppid;
sinfo->sinfo_context = asoc->default_context;
sinfo->sinfo_assoc_id = sctp_assoc2id(asoc);
+
+ if (!cmsgs->prinfo)
+ sinfo->sinfo_flags = asoc->default_flags;
}
- if (!cmsgs->srinfo)
+ if (!cmsgs->srinfo && !cmsgs->prinfo)
sinfo->sinfo_timetolive = asoc->default_timetolive;
}
@@ -7749,6 +7758,26 @@ static int sctp_msghdr_parse(const struct msghdr *msg, struct sctp_cmsgs *cmsgs)
SCTP_ABORT | SCTP_EOF))
return -EINVAL;
break;
+ case SCTP_PRINFO:
+ /* SCTP Socket API Extension
+ * 5.3.7 SCTP PR-SCTP Information Structure (SCTP_PRINFO)
+ *
+ * This cmsghdr structure specifies SCTP options for sendmsg().
+ *
+ * cmsg_level cmsg_type cmsg_data[]
+ * ------------ ------------ ---------------------
+ * IPPROTO_SCTP SCTP_PRINFO struct sctp_prinfo
+ */
+ if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct sctp_prinfo)))
+ return -EINVAL;
+
+ cmsgs->prinfo = CMSG_DATA(cmsg);
+ if (cmsgs->prinfo->pr_policy & ~SCTP_PR_SCTP_MASK)
+ return -EINVAL;
+
+ if (cmsgs->prinfo->pr_policy == SCTP_PR_SCTP_NONE)
+ cmsgs->prinfo->pr_value = 0;
+ break;
default:
return -EINVAL;
}
--
2.1.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH net-next 2/3] sctp: add support for SCTP_DSTADDRV4/6 Information for sendmsg
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 3/3] sctp: add support for snd flag SCTP_SENDALL process in sendmsg Xin Long
` (2 more replies)
2018-03-06 12:22 ` [PATCH net-next 1/3] sctp: add support for PR-SCTP " Marcelo Ricardo Leitner
1 sibling, 3 replies; 12+ messages in thread
From: Xin Long @ 2018-03-05 12:44 UTC (permalink / raw)
To: network dev, linux-sctp; +Cc: Marcelo Ricardo Leitner, Neil Horman, davem
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;
+ break;
default:
return -EINVAL;
}
--
2.1.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH net-next 3/3] sctp: add support for snd flag SCTP_SENDALL process in sendmsg
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-06 12:22 ` Marcelo Ricardo Leitner
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 12:22 ` Marcelo Ricardo Leitner
2 siblings, 1 reply; 12+ messages in thread
From: Xin Long @ 2018-03-05 12:44 UTC (permalink / raw)
To: network dev, linux-sctp; +Cc: Marcelo Ricardo Leitner, Neil Horman, davem
This patch is to add support for snd flag SCTP_SENDALL process
in sendmsg, as described in section 5.3.4 of RFC6458.
With this flag, you can send the same data to all the asocs of
this sk once.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
include/uapi/linux/sctp.h | 2 ++
net/sctp/socket.c | 35 +++++++++++++++++++++++++++++++----
2 files changed, 33 insertions(+), 4 deletions(-)
diff --git a/include/uapi/linux/sctp.h b/include/uapi/linux/sctp.h
index a1bc350..e94b6d2 100644
--- a/include/uapi/linux/sctp.h
+++ b/include/uapi/linux/sctp.h
@@ -284,6 +284,8 @@ enum sctp_sinfo_flags {
SCTP_ADDR_OVER = (1 << 1), /* Override the primary destination. */
SCTP_ABORT = (1 << 2), /* Send an ABORT message to the peer. */
SCTP_SACK_IMMEDIATELY = (1 << 3), /* SACK should be sent without delay. */
+ /* 2 bits here have been used by SCTP_PR_SCTP_MASK */
+ SCTP_SENDALL = (1 << 6),
SCTP_NOTIFICATION = MSG_NOTIFICATION, /* Next message is not user msg but notification. */
SCTP_EOF = MSG_FIN, /* Initiate graceful shutdown process. */
};
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 067b57a..7d3476a 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -1820,6 +1820,10 @@ static int sctp_sendmsg_check_sflags(struct sctp_association *asoc,
if (sctp_state(asoc, CLOSED) && sctp_style(sk, TCP))
return -EPIPE;
+ if ((sflags & SCTP_SENDALL) && sctp_style(sk, UDP) &&
+ !sctp_state(asoc, ESTABLISHED))
+ return 0;
+
if (sflags & SCTP_EOF) {
pr_debug("%s: shutting down association:%p\n", __func__, asoc);
sctp_primitive_SHUTDOWN(net, asoc, NULL);
@@ -2007,6 +2011,29 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len)
lock_sock(sk);
+ /* SCTP_SENDALL process */
+ if ((sflags & SCTP_SENDALL) && sctp_style(sk, UDP)) {
+ list_for_each_entry(asoc, &ep->asocs, asocs) {
+ err = sctp_sendmsg_check_sflags(asoc, sflags, msg,
+ msg_len);
+ if (err == 0)
+ continue;
+ if (err < 0)
+ goto out_unlock;
+
+ sctp_sendmsg_update_sinfo(asoc, sinfo, &cmsgs);
+
+ err = sctp_sendmsg_to_asoc(asoc, msg, msg_len,
+ NULL, sinfo);
+ if (err < 0)
+ goto out_unlock;
+
+ iov_iter_revert(&msg->msg_iter, err);
+ }
+
+ goto out_unlock;
+ }
+
/* Get and check or create asoc */
if (daddr) {
asoc = sctp_endpoint_lookup_assoc(ep, daddr, &transport);
@@ -7792,8 +7819,8 @@ static int sctp_msghdr_parse(const struct msghdr *msg, struct sctp_cmsgs *cmsgs)
if (cmsgs->srinfo->sinfo_flags &
~(SCTP_UNORDERED | SCTP_ADDR_OVER |
- SCTP_SACK_IMMEDIATELY | SCTP_PR_SCTP_MASK |
- SCTP_ABORT | SCTP_EOF))
+ SCTP_SACK_IMMEDIATELY | SCTP_SENDALL |
+ SCTP_PR_SCTP_MASK | SCTP_ABORT | SCTP_EOF))
return -EINVAL;
break;
@@ -7816,8 +7843,8 @@ static int sctp_msghdr_parse(const struct msghdr *msg, struct sctp_cmsgs *cmsgs)
if (cmsgs->sinfo->snd_flags &
~(SCTP_UNORDERED | SCTP_ADDR_OVER |
- SCTP_SACK_IMMEDIATELY | SCTP_PR_SCTP_MASK |
- SCTP_ABORT | SCTP_EOF))
+ SCTP_SACK_IMMEDIATELY | SCTP_SENDALL |
+ SCTP_PR_SCTP_MASK | SCTP_ABORT | SCTP_EOF))
return -EINVAL;
break;
case SCTP_PRINFO:
--
2.1.0
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH net-next 2/3] sctp: add support for SCTP_DSTADDRV4/6 Information for sendmsg
2018-03-05 12:44 ` [PATCH net-next 2/3] sctp: add support for SCTP_DSTADDRV4/6 " 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 23:39 ` Marcelo Ricardo Leitner
2018-03-06 7:03 ` Xin Long
2018-03-06 12:22 ` Marcelo Ricardo Leitner
2 siblings, 1 reply; 12+ messages in thread
From: Marcelo Ricardo Leitner @ 2018-03-05 23:39 UTC (permalink / raw)
To: Xin Long; +Cc: network dev, linux-sctp, Neil Horman, davem
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
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net-next 0/3] sctp: add support for some msg_control options from RFC6458
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 ` [PATCH net-next 1/3] sctp: add support for PR-SCTP Information for sendmsg Xin Long
@ 2018-03-05 23:52 ` Marcelo Ricardo Leitner
2018-03-07 15:56 ` David Miller
2 siblings, 0 replies; 12+ messages in thread
From: Marcelo Ricardo Leitner @ 2018-03-05 23:52 UTC (permalink / raw)
To: Xin Long; +Cc: network dev, linux-sctp, Neil Horman, davem
On Mon, Mar 05, 2018 at 08:44:17PM +0800, Xin Long wrote:
> This patchset is to add support for 3 msg_control options described
> in RFC6458:
>
> 5.3.7. SCTP PR-SCTP Information Structure (SCTP_PRINFO)
> 5.3.9. SCTP Destination IPv4 Address Structure (SCTP_DSTADDRV4)
> 5.3.10. SCTP Destination IPv6 Address Structure (SCTP_DSTADDRV6)
>
> one send flag described in RFC6458:
>
> SCTP_SENDALL: This flag, if set, will cause a one-to-many
> style socket to send the message to all associations that
> are currently established on this socket. For the one-to-
> one style socket, this flag has no effect.
Other patches (than the 2nd one) LGTM.
Marcelo
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net-next 2/3] sctp: add support for SCTP_DSTADDRV4/6 Information for sendmsg
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 12:21 ` Marcelo Ricardo Leitner
0 siblings, 1 reply; 12+ messages in thread
From: Xin Long @ 2018-03-06 7:03 UTC (permalink / raw)
To: Marcelo Ricardo Leitner; +Cc: network dev, linux-sctp, Neil Horman, davem
On Tue, Mar 6, 2018 at 7:39 AM, Marcelo Ricardo Leitner
<marcelo.leitner@gmail.com> wrote:
> 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.
Hi, Marcelo.
>From section 5.3.9 of RFC6458:
This ancillary data can be used to provide more than one destination
address to sendmsg(). It can be used to implement sctp_sendv() using
sendmsg().
It doesn't say to put "more than one destination address" into an array of
one option, or put "more than one destination address" into many options.
I was also confused, then I checked sctp_process_cmsgs_for_init() in
freebsd, I think it's in MANY options.
>
> The patch is saving both options into a single pointer, which later is
> processed as a list of (in_addr or in6_addr) elements.
It's not, 'my_msg' is the whole msghdr, not only in_addr or in6_addr.
later in sctp_sendmsg_new_asoc, it will parse this msghdr again but
this time only to pick up SCTP_DSTADDRV4/6 options.
(by this way I don't need to alloc list or array to save them)
Note that: one option is just one address, NOT a list of addresses.
like, it can even be:
SCTP_DSTADDRV4 (one option)
SCTP_DSTADDRV6 (one option)
SCTP_DSTADDRV4 (one option)
SCTP_DSTADDRV4 (one option)
SCTP_DSTADDRV6 (one option)
Maybe the name of cmsgs->addrs_msg is confusing here, but I
actually think it as a flag to see if there is addrs info in the msghdr,
and also as a parameter to pass the msghdr into sctp_sendmsg_new_asoc.
>
> If an application specifies both options, each with a list of its own
> addresses, it will ignore one of the options.
If an application specifies many options, some are SCTP_DSTADDRV4
and some are SCTP_DSTADDRV6, none of them will be ignored in
sctp_sendmsg_new_asoc().
>
>> + break;
>> default:
>> return -EINVAL;
>> }
>> --
>> 2.1.0
>>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net-next 2/3] sctp: add support for SCTP_DSTADDRV4/6 Information for sendmsg
2018-03-06 7:03 ` Xin Long
@ 2018-03-06 12:21 ` Marcelo Ricardo Leitner
0 siblings, 0 replies; 12+ messages in thread
From: Marcelo Ricardo Leitner @ 2018-03-06 12:21 UTC (permalink / raw)
To: Xin Long; +Cc: network dev, linux-sctp, Neil Horman, davem
On Tue, Mar 06, 2018 at 03:03:13PM +0800, Xin Long wrote:
> On Tue, Mar 6, 2018 at 7:39 AM, Marcelo Ricardo Leitner
> <marcelo.leitner@gmail.com> wrote:
> > 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.
> Hi, Marcelo.
>
> From section 5.3.9 of RFC6458:
>
> This ancillary data can be used to provide more than one destination
> address to sendmsg(). It can be used to implement sctp_sendv() using
> sendmsg().
>
> It doesn't say to put "more than one destination address" into an array of
> one option, or put "more than one destination address" into many options.
Spot on. And I went with the first interpretation, thus why the
difference.
>
> I was also confused, then I checked sctp_process_cmsgs_for_init() in
> freebsd, I think it's in MANY options.
Nice, ok
>
>
> >
> > The patch is saving both options into a single pointer, which later is
> > processed as a list of (in_addr or in6_addr) elements.
> It's not, 'my_msg' is the whole msghdr, not only in_addr or in6_addr.
> later in sctp_sendmsg_new_asoc, it will parse this msghdr again but
> this time only to pick up SCTP_DSTADDRV4/6 options.
> (by this way I don't need to alloc list or array to save them)
Which is nice, btw.
>
> Note that: one option is just one address, NOT a list of addresses.
> like, it can even be:
> SCTP_DSTADDRV4 (one option)
> SCTP_DSTADDRV6 (one option)
> SCTP_DSTADDRV4 (one option)
> SCTP_DSTADDRV4 (one option)
> SCTP_DSTADDRV6 (one option)
>
> Maybe the name of cmsgs->addrs_msg is confusing here, but I
> actually think it as a flag to see if there is addrs info in the msghdr,
> and also as a parameter to pass the msghdr into sctp_sendmsg_new_asoc.
What was more confusing to me is that it seems to overwrite the
pointer at every other addr option, but I should have noticed that it
is saving the entire cmsg.
>
> >
> > If an application specifies both options, each with a list of its own
> > addresses, it will ignore one of the options.
> If an application specifies many options, some are SCTP_DSTADDRV4
> and some are SCTP_DSTADDRV6, none of them will be ignored in
> sctp_sendmsg_new_asoc().
Yep. Thanks.
>
> >
> >> + break;
> >> default:
> >> return -EINVAL;
> >> }
> >> --
> >> 2.1.0
> >>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net-next 1/3] sctp: add support for PR-SCTP Information for sendmsg
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 ` [PATCH net-next 2/3] sctp: add support for SCTP_DSTADDRV4/6 " Xin Long
@ 2018-03-06 12:22 ` Marcelo Ricardo Leitner
1 sibling, 0 replies; 12+ messages in thread
From: Marcelo Ricardo Leitner @ 2018-03-06 12:22 UTC (permalink / raw)
To: Xin Long; +Cc: network dev, linux-sctp, Neil Horman, davem
On Mon, Mar 05, 2018 at 08:44:18PM +0800, Xin Long wrote:
> This patch is to add support for PR-SCTP Information for sendmsg,
> as described in section 5.3.7 of RFC6458.
>
> With this option, you can specify pr_policy and pr_value for user
> data in sendmsg.
>
> It's also a necessary send info for sctp_sendv.
>
> Signed-off-by: Xin Long <lucien.xin@gmail.com>
Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
> ---
> include/net/sctp/structs.h | 1 +
> include/uapi/linux/sctp.h | 15 +++++++++++++++
> net/sctp/socket.c | 31 ++++++++++++++++++++++++++++++-
> 3 files changed, 46 insertions(+), 1 deletion(-)
>
> diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
> index 03e92dd..d40a2a3 100644
> --- a/include/net/sctp/structs.h
> +++ b/include/net/sctp/structs.h
> @@ -2112,6 +2112,7 @@ struct sctp_cmsgs {
> struct sctp_initmsg *init;
> struct sctp_sndrcvinfo *srinfo;
> struct sctp_sndinfo *sinfo;
> + struct sctp_prinfo *prinfo;
> };
>
> /* Structure for tracking memory objects */
> diff --git a/include/uapi/linux/sctp.h b/include/uapi/linux/sctp.h
> index 4c4db14..0dd1f82 100644
> --- a/include/uapi/linux/sctp.h
> +++ b/include/uapi/linux/sctp.h
> @@ -260,6 +260,19 @@ struct sctp_nxtinfo {
> sctp_assoc_t nxt_assoc_id;
> };
>
> +/* 5.3.7 SCTP PR-SCTP Information Structure (SCTP_PRINFO)
> + *
> + * This cmsghdr structure specifies SCTP options for sendmsg().
> + *
> + * cmsg_level cmsg_type cmsg_data[]
> + * ------------ ------------ -------------------
> + * IPPROTO_SCTP SCTP_PRINFO struct sctp_prinfo
> + */
> +struct sctp_prinfo {
> + __u16 pr_policy;
> + __u32 pr_value;
> +};
> +
> /*
> * sinfo_flags: 16 bits (unsigned integer)
> *
> @@ -293,6 +306,8 @@ typedef enum sctp_cmsg_type {
> #define SCTP_RCVINFO SCTP_RCVINFO
> SCTP_NXTINFO, /* 5.3.6 SCTP Next Receive Information Structure */
> #define SCTP_NXTINFO SCTP_NXTINFO
> + SCTP_PRINFO, /* 5.3.7 SCTP PR-SCTP Information Structure */
> +#define SCTP_PRINFO SCTP_PRINFO
> } sctp_cmsg_t;
>
> /*
> diff --git a/net/sctp/socket.c b/net/sctp/socket.c
> index 7fa7603..fdde697 100644
> --- a/net/sctp/socket.c
> +++ b/net/sctp/socket.c
> @@ -1644,6 +1644,12 @@ static int sctp_sendmsg_parse(struct sock *sk, struct sctp_cmsgs *cmsgs,
> srinfo->sinfo_assoc_id = cmsgs->sinfo->snd_assoc_id;
> }
>
> + if (cmsgs->prinfo) {
> + srinfo->sinfo_timetolive = cmsgs->prinfo->pr_value;
> + SCTP_PR_SET_POLICY(srinfo->sinfo_flags,
> + cmsgs->prinfo->pr_policy);
> + }
> +
> sflags = srinfo->sinfo_flags;
> if (!sflags && msg_len)
> return 0;
> @@ -1901,9 +1907,12 @@ static void sctp_sendmsg_update_sinfo(struct sctp_association *asoc,
> sinfo->sinfo_ppid = asoc->default_ppid;
> sinfo->sinfo_context = asoc->default_context;
> sinfo->sinfo_assoc_id = sctp_assoc2id(asoc);
> +
> + if (!cmsgs->prinfo)
> + sinfo->sinfo_flags = asoc->default_flags;
> }
>
> - if (!cmsgs->srinfo)
> + if (!cmsgs->srinfo && !cmsgs->prinfo)
> sinfo->sinfo_timetolive = asoc->default_timetolive;
> }
>
> @@ -7749,6 +7758,26 @@ static int sctp_msghdr_parse(const struct msghdr *msg, struct sctp_cmsgs *cmsgs)
> SCTP_ABORT | SCTP_EOF))
> return -EINVAL;
> break;
> + case SCTP_PRINFO:
> + /* SCTP Socket API Extension
> + * 5.3.7 SCTP PR-SCTP Information Structure (SCTP_PRINFO)
> + *
> + * This cmsghdr structure specifies SCTP options for sendmsg().
> + *
> + * cmsg_level cmsg_type cmsg_data[]
> + * ------------ ------------ ---------------------
> + * IPPROTO_SCTP SCTP_PRINFO struct sctp_prinfo
> + */
> + if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct sctp_prinfo)))
> + return -EINVAL;
> +
> + cmsgs->prinfo = CMSG_DATA(cmsg);
> + if (cmsgs->prinfo->pr_policy & ~SCTP_PR_SCTP_MASK)
> + return -EINVAL;
> +
> + if (cmsgs->prinfo->pr_policy == SCTP_PR_SCTP_NONE)
> + cmsgs->prinfo->pr_value = 0;
> + break;
> default:
> return -EINVAL;
> }
> --
> 2.1.0
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net-next 2/3] sctp: add support for SCTP_DSTADDRV4/6 Information for sendmsg
2018-03-05 12:44 ` [PATCH net-next 2/3] sctp: add support for SCTP_DSTADDRV4/6 " 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 23:39 ` [PATCH net-next 2/3] sctp: add support for SCTP_DSTADDRV4/6 Information for sendmsg Marcelo Ricardo Leitner
@ 2018-03-06 12:22 ` Marcelo Ricardo Leitner
2 siblings, 0 replies; 12+ messages in thread
From: Marcelo Ricardo Leitner @ 2018-03-06 12:22 UTC (permalink / raw)
To: Xin Long; +Cc: network dev, linux-sctp, Neil Horman, davem
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>
Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@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;
> + break;
> default:
> return -EINVAL;
> }
> --
> 2.1.0
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net-next 3/3] sctp: add support for snd flag SCTP_SENDALL process in sendmsg
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-06 12:22 ` Marcelo Ricardo Leitner
0 siblings, 0 replies; 12+ messages in thread
From: Marcelo Ricardo Leitner @ 2018-03-06 12:22 UTC (permalink / raw)
To: Xin Long; +Cc: network dev, linux-sctp, Neil Horman, davem
On Mon, Mar 05, 2018 at 08:44:20PM +0800, Xin Long wrote:
> This patch is to add support for snd flag SCTP_SENDALL process
> in sendmsg, as described in section 5.3.4 of RFC6458.
>
> With this flag, you can send the same data to all the asocs of
> this sk once.
>
> Signed-off-by: Xin Long <lucien.xin@gmail.com>
Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
> ---
> include/uapi/linux/sctp.h | 2 ++
> net/sctp/socket.c | 35 +++++++++++++++++++++++++++++++----
> 2 files changed, 33 insertions(+), 4 deletions(-)
>
> diff --git a/include/uapi/linux/sctp.h b/include/uapi/linux/sctp.h
> index a1bc350..e94b6d2 100644
> --- a/include/uapi/linux/sctp.h
> +++ b/include/uapi/linux/sctp.h
> @@ -284,6 +284,8 @@ enum sctp_sinfo_flags {
> SCTP_ADDR_OVER = (1 << 1), /* Override the primary destination. */
> SCTP_ABORT = (1 << 2), /* Send an ABORT message to the peer. */
> SCTP_SACK_IMMEDIATELY = (1 << 3), /* SACK should be sent without delay. */
> + /* 2 bits here have been used by SCTP_PR_SCTP_MASK */
> + SCTP_SENDALL = (1 << 6),
> SCTP_NOTIFICATION = MSG_NOTIFICATION, /* Next message is not user msg but notification. */
> SCTP_EOF = MSG_FIN, /* Initiate graceful shutdown process. */
> };
> diff --git a/net/sctp/socket.c b/net/sctp/socket.c
> index 067b57a..7d3476a 100644
> --- a/net/sctp/socket.c
> +++ b/net/sctp/socket.c
> @@ -1820,6 +1820,10 @@ static int sctp_sendmsg_check_sflags(struct sctp_association *asoc,
> if (sctp_state(asoc, CLOSED) && sctp_style(sk, TCP))
> return -EPIPE;
>
> + if ((sflags & SCTP_SENDALL) && sctp_style(sk, UDP) &&
> + !sctp_state(asoc, ESTABLISHED))
> + return 0;
> +
> if (sflags & SCTP_EOF) {
> pr_debug("%s: shutting down association:%p\n", __func__, asoc);
> sctp_primitive_SHUTDOWN(net, asoc, NULL);
> @@ -2007,6 +2011,29 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len)
>
> lock_sock(sk);
>
> + /* SCTP_SENDALL process */
> + if ((sflags & SCTP_SENDALL) && sctp_style(sk, UDP)) {
> + list_for_each_entry(asoc, &ep->asocs, asocs) {
> + err = sctp_sendmsg_check_sflags(asoc, sflags, msg,
> + msg_len);
> + if (err == 0)
> + continue;
> + if (err < 0)
> + goto out_unlock;
> +
> + sctp_sendmsg_update_sinfo(asoc, sinfo, &cmsgs);
> +
> + err = sctp_sendmsg_to_asoc(asoc, msg, msg_len,
> + NULL, sinfo);
> + if (err < 0)
> + goto out_unlock;
> +
> + iov_iter_revert(&msg->msg_iter, err);
> + }
> +
> + goto out_unlock;
> + }
> +
> /* Get and check or create asoc */
> if (daddr) {
> asoc = sctp_endpoint_lookup_assoc(ep, daddr, &transport);
> @@ -7792,8 +7819,8 @@ static int sctp_msghdr_parse(const struct msghdr *msg, struct sctp_cmsgs *cmsgs)
>
> if (cmsgs->srinfo->sinfo_flags &
> ~(SCTP_UNORDERED | SCTP_ADDR_OVER |
> - SCTP_SACK_IMMEDIATELY | SCTP_PR_SCTP_MASK |
> - SCTP_ABORT | SCTP_EOF))
> + SCTP_SACK_IMMEDIATELY | SCTP_SENDALL |
> + SCTP_PR_SCTP_MASK | SCTP_ABORT | SCTP_EOF))
> return -EINVAL;
> break;
>
> @@ -7816,8 +7843,8 @@ static int sctp_msghdr_parse(const struct msghdr *msg, struct sctp_cmsgs *cmsgs)
>
> if (cmsgs->sinfo->snd_flags &
> ~(SCTP_UNORDERED | SCTP_ADDR_OVER |
> - SCTP_SACK_IMMEDIATELY | SCTP_PR_SCTP_MASK |
> - SCTP_ABORT | SCTP_EOF))
> + SCTP_SACK_IMMEDIATELY | SCTP_SENDALL |
> + SCTP_PR_SCTP_MASK | SCTP_ABORT | SCTP_EOF))
> return -EINVAL;
> break;
> case SCTP_PRINFO:
> --
> 2.1.0
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH net-next 0/3] sctp: add support for some msg_control options from RFC6458
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 ` [PATCH net-next 1/3] sctp: add support for PR-SCTP Information for sendmsg Xin Long
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-07 15:56 ` David Miller
2 siblings, 0 replies; 12+ messages in thread
From: David Miller @ 2018-03-07 15:56 UTC (permalink / raw)
To: lucien.xin; +Cc: netdev, linux-sctp, marcelo.leitner, nhorman
From: Xin Long <lucien.xin@gmail.com>
Date: Mon, 5 Mar 2018 20:44:17 +0800
> This patchset is to add support for 3 msg_control options described
> in RFC6458:
>
> 5.3.7. SCTP PR-SCTP Information Structure (SCTP_PRINFO)
> 5.3.9. SCTP Destination IPv4 Address Structure (SCTP_DSTADDRV4)
> 5.3.10. SCTP Destination IPv6 Address Structure (SCTP_DSTADDRV6)
>
> one send flag described in RFC6458:
>
> SCTP_SENDALL: This flag, if set, will cause a one-to-many
> style socket to send the message to all associations that
> are currently established on this socket. For the one-to-
> one style socket, this flag has no effect.
>
> Note there is another msg_control option:
>
> 5.3.8. SCTP AUTH Information Structure (SCTP_AUTHINFO)
>
> It's a little complicated, I will post it in another patchset after
> this.
Series applied, thanks Xin.
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2018-03-07 15:57 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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 ` [PATCH net-next 1/3] sctp: add support for PR-SCTP Information for sendmsg 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 ` [PATCH net-next 3/3] sctp: add support for snd flag SCTP_SENDALL process in sendmsg Xin Long
2018-03-06 12:22 ` Marcelo Ricardo Leitner
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 12:21 ` 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-05 23:52 ` [PATCH net-next 0/3] sctp: add support for some msg_control options from RFC6458 Marcelo Ricardo Leitner
2018-03-07 15:56 ` David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).