aboutsummaryrefslogtreecommitdiffstats
path: root/net/sctp
diff options
context:
space:
mode:
authorGeir Ola Vaagland <geirola@gmail.com>2014-07-12 14:30:39 -0400
committerDavid S. Miller <davem@davemloft.net>2014-07-16 17:40:04 -0400
commit6b3fd5f3a2bbc8464a8e0bf134a183b8fa026439 (patch)
tree0c8fbc13226cbaa0e21401b0d1d438c6764d45f2 /net/sctp
parent2347c80ff127b94ddaa675e2b78ab4cef46dc905 (diff)
net: sctp: implement rfc6458, 8.1.31. SCTP_DEFAULT_SNDINFO support
This patch implements section 8.1.31. of RFC6458, which adds support for setting/retrieving SCTP_DEFAULT_SNDINFO: Applications that wish to use the sendto() system call may wish to specify a default set of parameters that would normally be supplied through the inclusion of ancillary data. This socket option allows such an application to set the default sctp_sndinfo structure. The application that wishes to use this socket option simply passes the sctp_sndinfo structure (defined in Section 5.3.4) to this call. The input parameters accepted by this call include snd_sid, snd_flags, snd_ppid, and snd_context. The snd_flags parameter is composed of a bitwise OR of SCTP_UNORDERED, SCTP_EOF, and SCTP_SENDALL. The snd_assoc_id field specifies the association to which to apply the parameters. For a one-to-many style socket, any of the predefined constants are also allowed in this field. The field is ignored for one-to-one style sockets. 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.c107
1 files changed, 98 insertions, 9 deletions
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index 9bca87ee5152..d95a50c013c9 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -2770,19 +2770,22 @@ static int sctp_setsockopt_default_send_param(struct sock *sk,
2770 char __user *optval, 2770 char __user *optval,
2771 unsigned int optlen) 2771 unsigned int optlen)
2772{ 2772{
2773 struct sctp_sndrcvinfo info;
2774 struct sctp_association *asoc;
2775 struct sctp_sock *sp = sctp_sk(sk); 2773 struct sctp_sock *sp = sctp_sk(sk);
2774 struct sctp_association *asoc;
2775 struct sctp_sndrcvinfo info;
2776 2776
2777 if (optlen != sizeof(struct sctp_sndrcvinfo)) 2777 if (optlen != sizeof(info))
2778 return -EINVAL; 2778 return -EINVAL;
2779 if (copy_from_user(&info, optval, optlen)) 2779 if (copy_from_user(&info, optval, optlen))
2780 return -EFAULT; 2780 return -EFAULT;
2781 if (info.sinfo_flags &
2782 ~(SCTP_UNORDERED | SCTP_ADDR_OVER |
2783 SCTP_ABORT | SCTP_EOF))
2784 return -EINVAL;
2781 2785
2782 asoc = sctp_id2assoc(sk, info.sinfo_assoc_id); 2786 asoc = sctp_id2assoc(sk, info.sinfo_assoc_id);
2783 if (!asoc && info.sinfo_assoc_id && sctp_style(sk, UDP)) 2787 if (!asoc && info.sinfo_assoc_id && sctp_style(sk, UDP))
2784 return -EINVAL; 2788 return -EINVAL;
2785
2786 if (asoc) { 2789 if (asoc) {
2787 asoc->default_stream = info.sinfo_stream; 2790 asoc->default_stream = info.sinfo_stream;
2788 asoc->default_flags = info.sinfo_flags; 2791 asoc->default_flags = info.sinfo_flags;
@@ -2800,6 +2803,44 @@ static int sctp_setsockopt_default_send_param(struct sock *sk,
2800 return 0; 2803 return 0;
2801} 2804}
2802 2805
2806/* RFC6458, Section 8.1.31. Set/get Default Send Parameters
2807 * (SCTP_DEFAULT_SNDINFO)
2808 */
2809static int sctp_setsockopt_default_sndinfo(struct sock *sk,
2810 char __user *optval,
2811 unsigned int optlen)
2812{
2813 struct sctp_sock *sp = sctp_sk(sk);
2814 struct sctp_association *asoc;
2815 struct sctp_sndinfo info;
2816
2817 if (optlen != sizeof(info))
2818 return -EINVAL;
2819 if (copy_from_user(&info, optval, optlen))
2820 return -EFAULT;
2821 if (info.snd_flags &
2822 ~(SCTP_UNORDERED | SCTP_ADDR_OVER |
2823 SCTP_ABORT | SCTP_EOF))
2824 return -EINVAL;
2825
2826 asoc = sctp_id2assoc(sk, info.snd_assoc_id);
2827 if (!asoc && info.snd_assoc_id && sctp_style(sk, UDP))
2828 return -EINVAL;
2829 if (asoc) {
2830 asoc->default_stream = info.snd_sid;
2831 asoc->default_flags = info.snd_flags;
2832 asoc->default_ppid = info.snd_ppid;
2833 asoc->default_context = info.snd_context;
2834 } else {
2835 sp->default_stream = info.snd_sid;
2836 sp->default_flags = info.snd_flags;
2837 sp->default_ppid = info.snd_ppid;
2838 sp->default_context = info.snd_context;
2839 }
2840
2841 return 0;
2842}
2843
2803/* 7.1.10 Set Primary Address (SCTP_PRIMARY_ADDR) 2844/* 7.1.10 Set Primary Address (SCTP_PRIMARY_ADDR)
2804 * 2845 *
2805 * Requests that the local SCTP stack use the enclosed peer address as 2846 * Requests that the local SCTP stack use the enclosed peer address as
@@ -3725,6 +3766,9 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname,
3725 retval = sctp_setsockopt_default_send_param(sk, optval, 3766 retval = sctp_setsockopt_default_send_param(sk, optval,
3726 optlen); 3767 optlen);
3727 break; 3768 break;
3769 case SCTP_DEFAULT_SNDINFO:
3770 retval = sctp_setsockopt_default_sndinfo(sk, optval, optlen);
3771 break;
3728 case SCTP_PRIMARY_ADDR: 3772 case SCTP_PRIMARY_ADDR:
3729 retval = sctp_setsockopt_primary_addr(sk, optval, optlen); 3773 retval = sctp_setsockopt_primary_addr(sk, optval, optlen);
3730 break; 3774 break;
@@ -5027,14 +5071,14 @@ static int sctp_getsockopt_default_send_param(struct sock *sk,
5027 int len, char __user *optval, 5071 int len, char __user *optval,
5028 int __user *optlen) 5072 int __user *optlen)
5029{ 5073{
5030 struct sctp_sndrcvinfo info;
5031 struct sctp_association *asoc;
5032 struct sctp_sock *sp = sctp_sk(sk); 5074 struct sctp_sock *sp = sctp_sk(sk);
5075 struct sctp_association *asoc;
5076 struct sctp_sndrcvinfo info;
5033 5077
5034 if (len < sizeof(struct sctp_sndrcvinfo)) 5078 if (len < sizeof(info))
5035 return -EINVAL; 5079 return -EINVAL;
5036 5080
5037 len = sizeof(struct sctp_sndrcvinfo); 5081 len = sizeof(info);
5038 5082
5039 if (copy_from_user(&info, optval, len)) 5083 if (copy_from_user(&info, optval, len))
5040 return -EFAULT; 5084 return -EFAULT;
@@ -5042,7 +5086,6 @@ static int sctp_getsockopt_default_send_param(struct sock *sk,
5042 asoc = sctp_id2assoc(sk, info.sinfo_assoc_id); 5086 asoc = sctp_id2assoc(sk, info.sinfo_assoc_id);
5043 if (!asoc && info.sinfo_assoc_id && sctp_style(sk, UDP)) 5087 if (!asoc && info.sinfo_assoc_id && sctp_style(sk, UDP))
5044 return -EINVAL; 5088 return -EINVAL;
5045
5046 if (asoc) { 5089 if (asoc) {
5047 info.sinfo_stream = asoc->default_stream; 5090 info.sinfo_stream = asoc->default_stream;
5048 info.sinfo_flags = asoc->default_flags; 5091 info.sinfo_flags = asoc->default_flags;
@@ -5065,6 +5108,48 @@ static int sctp_getsockopt_default_send_param(struct sock *sk,
5065 return 0; 5108 return 0;
5066} 5109}
5067 5110
5111/* RFC6458, Section 8.1.31. Set/get Default Send Parameters
5112 * (SCTP_DEFAULT_SNDINFO)
5113 */
5114static int sctp_getsockopt_default_sndinfo(struct sock *sk, int len,
5115 char __user *optval,
5116 int __user *optlen)
5117{
5118 struct sctp_sock *sp = sctp_sk(sk);
5119 struct sctp_association *asoc;
5120 struct sctp_sndinfo info;
5121
5122 if (len < sizeof(info))
5123 return -EINVAL;
5124
5125 len = sizeof(info);
5126
5127 if (copy_from_user(&info, optval, len))
5128 return -EFAULT;
5129
5130 asoc = sctp_id2assoc(sk, info.snd_assoc_id);
5131 if (!asoc && info.snd_assoc_id && sctp_style(sk, UDP))
5132 return -EINVAL;
5133 if (asoc) {
5134 info.snd_sid = asoc->default_stream;
5135 info.snd_flags = asoc->default_flags;
5136 info.snd_ppid = asoc->default_ppid;
5137 info.snd_context = asoc->default_context;
5138 } else {
5139 info.snd_sid = sp->default_stream;
5140 info.snd_flags = sp->default_flags;
5141 info.snd_ppid = sp->default_ppid;
5142 info.snd_context = sp->default_context;
5143 }
5144
5145 if (put_user(len, optlen))
5146 return -EFAULT;
5147 if (copy_to_user(optval, &info, len))
5148 return -EFAULT;
5149
5150 return 0;
5151}
5152
5068/* 5153/*
5069 * 5154 *
5070 * 7.1.5 SCTP_NODELAY 5155 * 7.1.5 SCTP_NODELAY
@@ -5924,6 +6009,10 @@ static int sctp_getsockopt(struct sock *sk, int level, int optname,
5924 retval = sctp_getsockopt_default_send_param(sk, len, 6009 retval = sctp_getsockopt_default_send_param(sk, len,
5925 optval, optlen); 6010 optval, optlen);
5926 break; 6011 break;
6012 case SCTP_DEFAULT_SNDINFO:
6013 retval = sctp_getsockopt_default_sndinfo(sk, len,
6014 optval, optlen);
6015 break;
5927 case SCTP_PRIMARY_ADDR: 6016 case SCTP_PRIMARY_ADDR:
5928 retval = sctp_getsockopt_primary_addr(sk, len, optval, optlen); 6017 retval = sctp_getsockopt_primary_addr(sk, len, optval, optlen);
5929 break; 6018 break;