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
134#define SCTP_INTERLEAVING_SUPPORTED 125134#define SCTP_INTERLEAVING_SUPPORTED 125
135#define SCTP_SENDMSG_CONNECT 126135#define SCTP_SENDMSG_CONNECT 126
136#define SCTP_EVENT 127136#define SCTP_EVENT 127
137#define SCTP_ASCONF_SUPPORTED 128
137 138
138/* PR-SCTP policies */139/* PR-SCTP policies */
139#define SCTP_PR_SCTP_NONE 0x0000140#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
4496 return retval;4496 return retval;
4497}4497}
4498 4498
4499static 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
4531out:
4532 return retval;
4533}
4534
4499/* API 6.2 setsockopt(), getsockopt()4535/* API 6.2 setsockopt(), getsockopt()
4500 *4536 *
4501 * Applications use setsockopt() and getsockopt() to set or retrieve4537 * 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
4696 case SCTP_EVENT:4732 case SCTP_EVENT:
4697 retval = sctp_setsockopt_event(sk, optval, optlen);4733 retval = sctp_setsockopt_event(sk, optval, optlen);
4698 break;4734 break;
4735 case SCTP_ASCONF_SUPPORTED:
4736 retval = sctp_setsockopt_asconf_supported(sk, optval, optlen);
4737 break;
4699 default:4738 default:
4700 retval = -ENOPROTOOPT;4739 retval = -ENOPROTOOPT;
4701 break;4740 break;
@@ -7675,6 +7714,45 @@ static int sctp_getsockopt_event(struct sock *sk, int len, char __user *optval, · 2973 unmodified lines
7675 return 0;7714 return 0;
7676}7715}
7677 7716
7717static 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
7752out:
7753 return retval;
7754}
7755
7678static int sctp_getsockopt(struct sock *sk, int level, int optname,7756static int sctp_getsockopt(struct sock *sk, int level, int optname,
7679 char __user *optval, int __user *optlen)7757 char __user *optval, int __user *optlen)
7680{7758{
@@ -7876,6 +7954,10 @@ static int sctp_getsockopt(struct sock *sk, int level, int optname, · 195 unmodified lines
7876 case SCTP_EVENT:7954 case SCTP_EVENT:
7877 retval = sctp_getsockopt_event(sk, len, optval, optlen);7955 retval = sctp_getsockopt_event(sk, len, optval, optlen);
7878 break;7956 break;
7957 case SCTP_ASCONF_SUPPORTED:
7958 retval = sctp_getsockopt_asconf_supported(sk, len, optval,
7959 optlen);
7960 break;
7879 default:7961 default:
7880 retval = -ENOPROTOOPT;7962 retval = -ENOPROTOOPT;
7881 break;7963 break;