aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp
diff options
context:
space:
mode:
authorGeir Ola Vaagland <geirola@gmail.com>2014-07-12 14:30:36 -0400
committerDavid S. Miller <davem@davemloft.net>2014-07-16 17:40:03 -0400
commit63b949382c5f263746b1c177f6ff84de2201ae9d (patch)
tree5e946189fa98de8699606a6f6ec8165ee8e0ed1e /net/sctp
parent1a98c69af1ecd97bfd1f4e4539924a9192434e36 (diff)
net: sctp: implement rfc6458, 5.3.4. SCTP_SNDINFO cmsg support
This patch implements section 5.3.4. of RFC6458, that is, support for 'SCTP Send Information Structure' (SCTP_SNDINFO) which can be placed into ancillary data cmsghdr structure for sendmsg() calls. The sctp_sndinfo structure is defined as per RFC as below ... struct sctp_sndinfo { uint16_t snd_sid; uint16_t snd_flags; uint32_t snd_ppid; uint32_t snd_context; sctp_assoc_t snd_assoc_id; }; ... and supplied under cmsg_level IPPROTO_SCTP, cmsg_type SCTP_SNDINFO, while cmsg_data[] contains struct sctp_sndinfo. An sctp_sndinfo item always corresponds to the data in msg_iov. Joint work with Daniel Borkmann. Signed-off-by: Geir Ola Vaagland <geirola@gmail.com> Signed-off-by: Daniel Borkmann <dborkman@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/sctp')
-rw-r--r--net/sctp/socket.c77
1 files changed, 57 insertions, 20 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 429899689408..d61729e99856 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -1602,12 +1602,13 @@ static int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
1602 struct sctp_initmsg *sinit; 1602 struct sctp_initmsg *sinit;
1603 sctp_assoc_t associd = 0; 1603 sctp_assoc_t associd = 0;
1604 sctp_cmsgs_t cmsgs = { NULL }; 1604 sctp_cmsgs_t cmsgs = { NULL };
1605 int err;
1606 sctp_scope_t scope; 1605 sctp_scope_t scope;
1607 long timeo; 1606 bool fill_sinfo_ttl = false;
1608 __u16 sinfo_flags = 0;
1609 struct sctp_datamsg *datamsg; 1607 struct sctp_datamsg *datamsg;
1610 int msg_flags = msg->msg_flags; 1608 int msg_flags = msg->msg_flags;
1609 __u16 sinfo_flags = 0;
1610 long timeo;
1611 int err;
1611 1612
1612 err = 0; 1613 err = 0;
1613 sp = sctp_sk(sk); 1614 sp = sctp_sk(sk);
@@ -1648,10 +1649,21 @@ static int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
1648 msg_name = msg->msg_name; 1649 msg_name = msg->msg_name;
1649 } 1650 }
1650 1651
1651 sinfo = cmsgs.info;
1652 sinit = cmsgs.init; 1652 sinit = cmsgs.init;
1653 if (cmsgs.sinfo != NULL) {
1654 memset(&default_sinfo, 0, sizeof(default_sinfo));
1655 default_sinfo.sinfo_stream = cmsgs.sinfo->snd_sid;
1656 default_sinfo.sinfo_flags = cmsgs.sinfo->snd_flags;
1657 default_sinfo.sinfo_ppid = cmsgs.sinfo->snd_ppid;
1658 default_sinfo.sinfo_context = cmsgs.sinfo->snd_context;
1659 default_sinfo.sinfo_assoc_id = cmsgs.sinfo->snd_assoc_id;
1653 1660
1654 /* Did the user specify SNDRCVINFO? */ 1661 sinfo = &default_sinfo;
1662 fill_sinfo_ttl = true;
1663 } else {
1664 sinfo = cmsgs.srinfo;
1665 }
1666 /* Did the user specify SNDINFO/SNDRCVINFO? */
1655 if (sinfo) { 1667 if (sinfo) {
1656 sinfo_flags = sinfo->sinfo_flags; 1668 sinfo_flags = sinfo->sinfo_flags;
1657 associd = sinfo->sinfo_assoc_id; 1669 associd = sinfo->sinfo_assoc_id;
@@ -1858,8 +1870,8 @@ static int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
1858 pr_debug("%s: we have a valid association\n", __func__); 1870 pr_debug("%s: we have a valid association\n", __func__);
1859 1871
1860 if (!sinfo) { 1872 if (!sinfo) {
1861 /* If the user didn't specify SNDRCVINFO, make up one with 1873 /* If the user didn't specify SNDINFO/SNDRCVINFO, make up
1862 * some defaults. 1874 * one with some defaults.
1863 */ 1875 */
1864 memset(&default_sinfo, 0, sizeof(default_sinfo)); 1876 memset(&default_sinfo, 0, sizeof(default_sinfo));
1865 default_sinfo.sinfo_stream = asoc->default_stream; 1877 default_sinfo.sinfo_stream = asoc->default_stream;
@@ -1868,7 +1880,13 @@ static int sctp_sendmsg(struct kiocb *iocb, struct sock *sk,
1868 default_sinfo.sinfo_context = asoc->default_context; 1880 default_sinfo.sinfo_context = asoc->default_context;
1869 default_sinfo.sinfo_timetolive = asoc->default_timetolive; 1881 default_sinfo.sinfo_timetolive = asoc->default_timetolive;
1870 default_sinfo.sinfo_assoc_id = sctp_assoc2id(asoc); 1882 default_sinfo.sinfo_assoc_id = sctp_assoc2id(asoc);
1883
1871 sinfo = &default_sinfo; 1884 sinfo = &default_sinfo;
1885 } else if (fill_sinfo_ttl) {
1886 /* In case SNDINFO was specified, we still need to fill
1887 * it with a default ttl from the assoc here.
1888 */
1889 sinfo->sinfo_timetolive = asoc->default_timetolive;
1872 } 1890 }
1873 1891
1874 /* API 7.1.7, the sndbuf size per association bounds the 1892 /* API 7.1.7, the sndbuf size per association bounds the
@@ -6390,8 +6408,7 @@ static int sctp_msghdr_parse(const struct msghdr *msg, sctp_cmsgs_t *cmsgs)
6390 struct cmsghdr *cmsg; 6408 struct cmsghdr *cmsg;
6391 struct msghdr *my_msg = (struct msghdr *)msg; 6409 struct msghdr *my_msg = (struct msghdr *)msg;
6392 6410
6393 for (cmsg = CMSG_FIRSTHDR(msg); 6411 for (cmsg = CMSG_FIRSTHDR(msg); cmsg != NULL;
6394 cmsg != NULL;
6395 cmsg = CMSG_NXTHDR(my_msg, cmsg)) { 6412 cmsg = CMSG_NXTHDR(my_msg, cmsg)) {
6396 if (!CMSG_OK(my_msg, cmsg)) 6413 if (!CMSG_OK(my_msg, cmsg))
6397 return -EINVAL; 6414 return -EINVAL;
@@ -6404,7 +6421,7 @@ static int sctp_msghdr_parse(const struct msghdr *msg, sctp_cmsgs_t *cmsgs)
6404 switch (cmsg->cmsg_type) { 6421 switch (cmsg->cmsg_type) {
6405 case SCTP_INIT: 6422 case SCTP_INIT:
6406 /* SCTP Socket API Extension 6423 /* SCTP Socket API Extension
6407 * 5.2.1 SCTP Initiation Structure (SCTP_INIT) 6424 * 5.3.1 SCTP Initiation Structure (SCTP_INIT)
6408 * 6425 *
6409 * This cmsghdr structure provides information for 6426 * This cmsghdr structure provides information for
6410 * initializing new SCTP associations with sendmsg(). 6427 * initializing new SCTP associations with sendmsg().
@@ -6416,15 +6433,15 @@ static int sctp_msghdr_parse(const struct msghdr *msg, sctp_cmsgs_t *cmsgs)
6416 * ------------ ------------ ---------------------- 6433 * ------------ ------------ ----------------------
6417 * IPPROTO_SCTP SCTP_INIT struct sctp_initmsg 6434 * IPPROTO_SCTP SCTP_INIT struct sctp_initmsg
6418 */ 6435 */
6419 if (cmsg->cmsg_len != 6436 if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct sctp_initmsg)))
6420 CMSG_LEN(sizeof(struct sctp_initmsg)))
6421 return -EINVAL; 6437 return -EINVAL;
6422 cmsgs->init = (struct sctp_initmsg *)CMSG_DATA(cmsg); 6438
6439 cmsgs->init = CMSG_DATA(cmsg);
6423 break; 6440 break;
6424 6441
6425 case SCTP_SNDRCV: 6442 case SCTP_SNDRCV:
6426 /* SCTP Socket API Extension 6443 /* SCTP Socket API Extension
6427 * 5.2.2 SCTP Header Information Structure(SCTP_SNDRCV) 6444 * 5.3.2 SCTP Header Information Structure(SCTP_SNDRCV)
6428 * 6445 *
6429 * This cmsghdr structure specifies SCTP options for 6446 * This cmsghdr structure specifies SCTP options for
6430 * sendmsg() and describes SCTP header information 6447 * sendmsg() and describes SCTP header information
@@ -6434,24 +6451,44 @@ static int sctp_msghdr_parse(const struct msghdr *msg, sctp_cmsgs_t *cmsgs)
6434 * ------------ ------------ ---------------------- 6451 * ------------ ------------ ----------------------
6435 * IPPROTO_SCTP SCTP_SNDRCV struct sctp_sndrcvinfo 6452 * IPPROTO_SCTP SCTP_SNDRCV struct sctp_sndrcvinfo
6436 */ 6453 */
6437 if (cmsg->cmsg_len != 6454 if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct sctp_sndrcvinfo)))
6438 CMSG_LEN(sizeof(struct sctp_sndrcvinfo)))
6439 return -EINVAL; 6455 return -EINVAL;
6440 6456
6441 cmsgs->info = 6457 cmsgs->srinfo = CMSG_DATA(cmsg);
6442 (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
6443 6458
6444 /* Minimally, validate the sinfo_flags. */ 6459 if (cmsgs->srinfo->sinfo_flags &
6445 if (cmsgs->info->sinfo_flags &
6446 ~(SCTP_UNORDERED | SCTP_ADDR_OVER | 6460 ~(SCTP_UNORDERED | SCTP_ADDR_OVER |
6447 SCTP_ABORT | SCTP_EOF)) 6461 SCTP_ABORT | SCTP_EOF))
6448 return -EINVAL; 6462 return -EINVAL;
6449 break; 6463 break;
6450 6464
6465 case SCTP_SNDINFO:
6466 /* SCTP Socket API Extension
6467 * 5.3.4 SCTP Send Information Structure (SCTP_SNDINFO)
6468 *
6469 * This cmsghdr structure specifies SCTP options for
6470 * sendmsg(). This structure and SCTP_RCVINFO replaces
6471 * SCTP_SNDRCV which has been deprecated.
6472 *
6473 * cmsg_level cmsg_type cmsg_data[]
6474 * ------------ ------------ ---------------------
6475 * IPPROTO_SCTP SCTP_SNDINFO struct sctp_sndinfo
6476 */
6477 if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct sctp_sndinfo)))
6478 return -EINVAL;
6479
6480 cmsgs->sinfo = CMSG_DATA(cmsg);
6481
6482 if (cmsgs->sinfo->snd_flags &
6483 ~(SCTP_UNORDERED | SCTP_ADDR_OVER |
6484 SCTP_ABORT | SCTP_EOF))
6485 return -EINVAL;
6486 break;
6451 default: 6487 default:
6452 return -EINVAL; 6488 return -EINVAL;
6453 } 6489 }
6454 } 6490 }
6491
6455 return 0; 6492 return 0;
6456} 6493}
6457 6494