History

sctp: add SCTP_ASCONF_SUPPORTED sockopt

SCTP_ASCONF_SUPPORTED sockopt is used to set enpoint's asconf flag. With this feature, each endpoint will have its own flag for its future asoc's asconf_capable, instead of netns asconf flag. Note that when both ep's asconf_enable and auth_enable are enabled, SCTP_CID_ASCONF and SCTP_CID_ASCONF_ACK should be added into auth_chunk_list.

Xin Long committed 7 years ago

Commit df2c71f1 parent a2eeacc2 files · +83 −0Browse files

Unified · Split

2 files
  1. include/uapi/linux/sctp.h +1 −0
  2. net/sctp/socket.c +82 −0
include/uapi/linux/sctp.h+1−0
@@ -134,6 +134,7 @@ typedef __s32 sctp_assoc_t; · 133 unmodified lines
134134 #define SCTP_INTERLEAVING_SUPPORTED 125
135135 #define SCTP_SENDMSG_CONNECT 126
136136 #define SCTP_EVENT 127
137+#define SCTP_ASCONF_SUPPORTED 128
137138
138139 /* PR-SCTP policies */
139140 #define SCTP_PR_SCTP_NONE 0x0000
net/sctp/socket.c+82−0
@@ -4496,6 +4496,42 @@ static int sctp_setsockopt_event(struct sock *sk, char __user *optval, · 4495 unmodified lines
44964496 return retval;
44974497 }
44984498
4499+static int sctp_setsockopt_asconf_supported(struct sock *sk,
4500+ char __user *optval,
4501+ unsigned int optlen)
4502+{
4503+ struct sctp_assoc_value params;
4504+ struct sctp_association *asoc;
4505+ struct sctp_endpoint *ep;
4506+ int retval = -EINVAL;
4507+
4508+ if (optlen != sizeof(params))
4509+ goto out;
4510+
4511+ if (copy_from_user(&params, optval, optlen)) {
4512+ retval = -EFAULT;
4513+ goto out;
4514+ }
4515+
4516+ asoc = sctp_id2assoc(sk, params.assoc_id);
4517+ if (!asoc && params.assoc_id != SCTP_FUTURE_ASSOC &&
4518+ sctp_style(sk, UDP))
4519+ goto out;
4520+
4521+ ep = sctp_sk(sk)->ep;
4522+ ep->asconf_enable = !!params.assoc_value;
4523+
4524+ if (ep->asconf_enable && ep->auth_enable) {
4525+ sctp_auth_ep_add_chunkid(ep, SCTP_CID_ASCONF);
4526+ sctp_auth_ep_add_chunkid(ep, SCTP_CID_ASCONF_ACK);
4527+ }
4528+
4529+ retval = 0;
4530+
4531+out:
4532+ return retval;
4533+}
4534+
44994535 /* API 6.2 setsockopt(), getsockopt()
45004536 *
45014537 * Applications use setsockopt() and getsockopt() to set or retrieve
@@ -4696,6 +4732,9 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname, · 194 unmodified lines
46964732 case SCTP_EVENT:
46974733 retval = sctp_setsockopt_event(sk, optval, optlen);
46984734 break;
4735+ case SCTP_ASCONF_SUPPORTED:
4736+ retval = sctp_setsockopt_asconf_supported(sk, optval, optlen);
4737+ break;
46994738 default:
47004739 retval = -ENOPROTOOPT;
47014740 break;
@@ -7675,6 +7714,45 @@ static int sctp_getsockopt_event(struct sock *sk, int len, char __user *optval, · 2973 unmodified lines
76757714 return 0;
76767715 }
76777716
7717+static int sctp_getsockopt_asconf_supported(struct sock *sk, int len,
7718+ char __user *optval,
7719+ int __user *optlen)
7720+{
7721+ struct sctp_assoc_value params;
7722+ struct sctp_association *asoc;
7723+ int retval = -EFAULT;
7724+
7725+ if (len < sizeof(params)) {
7726+ retval = -EINVAL;
7727+ goto out;
7728+ }
7729+
7730+ len = sizeof(params);
7731+ if (copy_from_user(&params, optval, len))
7732+ goto out;
7733+
7734+ asoc = sctp_id2assoc(sk, params.assoc_id);
7735+ if (!asoc && params.assoc_id != SCTP_FUTURE_ASSOC &&
7736+ sctp_style(sk, UDP)) {
7737+ retval = -EINVAL;
7738+ goto out;
7739+ }
7740+
7741+ params.assoc_value = asoc ? asoc->peer.asconf_capable
7742+ : sctp_sk(sk)->ep->asconf_enable;
7743+
7744+ if (put_user(len, optlen))
7745+ goto out;
7746+
7747+ if (copy_to_user(optval, &params, len))
7748+ goto out;
7749+
7750+ retval = 0;
7751+
7752+out:
7753+ return retval;
7754+}
7755+
76787756 static int sctp_getsockopt(struct sock *sk, int level, int optname,
76797757 char __user *optval, int __user *optlen)
76807758 {
@@ -7876,6 +7954,10 @@ static int sctp_getsockopt(struct sock *sk, int level, int optname, · 195 unmodified lines
78767954 case SCTP_EVENT:
78777955 retval = sctp_getsockopt_event(sk, len, optval, optlen);
78787956 break;
7957+ case SCTP_ASCONF_SUPPORTED:
7958+ retval = sctp_getsockopt_asconf_supported(sk, len, optval,
7959+ optlen);
7960+ break;
78797961 default:
78807962 retval = -ENOPROTOOPT;
78817963 break;