From patchwork Sat Jul 9 11:47:40 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xin Long X-Patchwork-Id: 646669 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3rmqP34k9rz9sXx for ; Sat, 9 Jul 2016 21:48:07 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b=SyzuKJcY; dkim-atps=neutral Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756748AbcGILr7 (ORCPT ); Sat, 9 Jul 2016 07:47:59 -0400 Received: from mail-pa0-f68.google.com ([209.85.220.68]:33344 "EHLO mail-pa0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751897AbcGILr5 (ORCPT ); Sat, 9 Jul 2016 07:47:57 -0400 Received: by mail-pa0-f68.google.com with SMTP id ts6so9801293pac.0; Sat, 09 Jul 2016 04:47:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=QfPjPmFTq7licVQUaoobkcdwkdrkaWC7qcvW0EizNYE=; b=SyzuKJcYQIdgNvLyOERJsumsCij3DFJYg4TjLrKiWwTZrhvcCQFBeKiiTFsxFRxPEH YWcEKemhHipfYqlQVG0tRX+0sfZPO9D0uV+7VtjdGyqiaYzFqfBogOi6q5OsrjKP1iUY 3hgGF2scNdqCmyf46WV/SMK+UjjI19EZqU1O3xjjG+lAPB88iSyA33xnuGbKGgwW3qwo Xn31BdNvv84fe4LKW/1ulAoRGrdtUuXT1/nhWkJIdTmT6/gEZCLriVOe7po0wANRZWX0 1CdlMRJN5GqvaRfTy9YuugvO6TjHG4+iNRSPpQsoS7JqMFFdHxkv9VgZAQfS7PB8RTrt 3RPQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=QfPjPmFTq7licVQUaoobkcdwkdrkaWC7qcvW0EizNYE=; b=kTTYJ6CScqYELmrSEQsBaTHRoE1bpdXYZxYG5Y0zBRHcCfy4StkhkG8PWEskzTc0Kl TaTsUG2EmNhtaVu4cE7PZHE4M7KVASTKjfgCwVbiCtV1QpTUxsyD7ozx7AfGJtFGvbly ScLAnE+tpKslr6zuSiucFIOLHYxUbt/OgCEbwWEtT9H0ZRY3VK5EP3hF+CJ4KV1W3ASP SFEkdhl8wAHu3b/nOQ5nu37zX8Vx2jVxxKVFf0u/8MVAD5Pdd9lDuWkFsEE7II2LQLy5 Crphf1jKkYbMLADCTV5e1pD34kzk7HsONC1mANUD4h3xXKizxfXjHv076G0om7uCoDSl eJBw== X-Gm-Message-State: ALyK8tK6GiuxCSbEQabmWT//ZkR3Kc57EkDxBDkLTXAhrh8mGX+ooQzYIu6ePBtG4cxBgQ== X-Received: by 10.66.134.52 with SMTP id ph20mr18334745pab.72.1468064875985; Sat, 09 Jul 2016 04:47:55 -0700 (PDT) Received: from localhost (138.128.208.20.16clouds.com. [138.128.208.20]) by smtp.gmail.com with ESMTPSA id s23sm3400503pfd.23.2016.07.09.04.47.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 09 Jul 2016 04:47:55 -0700 (PDT) From: Xin Long To: network dev , linux-sctp@vger.kernel.org Cc: Marcelo Ricardo Leitner , Vlad Yasevich , daniel@iogearbox.net, davem@davemloft.net Subject: [PATCH net-next 1/6] sctp: add SCTP_PR_SUPPORTED on sctp sockopt Date: Sat, 9 Jul 2016 19:47:40 +0800 Message-Id: <121aa41aceff56b3dda51c41b8f3c4d8662d65b7.1468064737.git.lucien.xin@gmail.com> X-Mailer: git-send-email 2.1.0 In-Reply-To: References: In-Reply-To: References: Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org According to section 4.5 of rfc7496, prsctp_enable should be per asoc. We will add prsctp_enable to both asoc and ep, and replace the places where it used net.sctp->prsctp_enable with asoc->prsctp_enable. ep->prsctp_enable will be initialized with net.sctp->prsctp_enable, and asoc->prsctp_enable will be initialized with ep->prsctp_enable. We can also modify it's value through sockopt SCTP_PR_SUPPORTED. Signed-off-by: Xin Long --- include/net/sctp/structs.h | 6 ++-- include/uapi/linux/sctp.h | 1 + net/sctp/associola.c | 1 + net/sctp/endpointola.c | 1 + net/sctp/sm_make_chunk.c | 12 +++---- net/sctp/socket.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 93 insertions(+), 8 deletions(-) diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 83c5ec5..07115ca 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -1256,7 +1256,8 @@ struct sctp_endpoint { /* SCTP-AUTH: endpoint shared keys */ struct list_head endpoint_shared_keys; __u16 active_key_id; - __u8 auth_enable; + __u8 auth_enable:1, + prsctp_enable:1; }; /* Recover the outter endpoint structure. */ @@ -1848,7 +1849,8 @@ struct sctp_association { __u16 active_key_id; __u8 need_ecne:1, /* Need to send an ECNE Chunk? */ - temp:1; /* Is it a temporary association? */ + temp:1, /* Is it a temporary association? */ + prsctp_enable:1; struct sctp_priv_assoc_stats stats; }; diff --git a/include/uapi/linux/sctp.h b/include/uapi/linux/sctp.h index ce70fe6..aa08906 100644 --- a/include/uapi/linux/sctp.h +++ b/include/uapi/linux/sctp.h @@ -112,6 +112,7 @@ typedef __s32 sctp_assoc_t; #define SCTP_SOCKOPT_CONNECTX 110 /* CONNECTX requests. */ #define SCTP_SOCKOPT_CONNECTX3 111 /* CONNECTX requests (updated) */ #define SCTP_GET_ASSOC_STATS 112 /* Read only */ +#define SCTP_PR_SUPPORTED 113 /* These are bit fields for msghdr->msg_flags. See section 5.1. */ /* On user space Linux, these live in as an enum. */ diff --git a/net/sctp/associola.c b/net/sctp/associola.c index e1849f3..1c23060 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c @@ -268,6 +268,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a goto fail_init; asoc->active_key_id = ep->active_key_id; + asoc->prsctp_enable = ep->prsctp_enable; /* Save the hmacs and chunks list into this association */ if (ep->auth_hmacs_list) diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c index 9d494e3..1f03065 100644 --- a/net/sctp/endpointola.c +++ b/net/sctp/endpointola.c @@ -163,6 +163,7 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep, */ ep->auth_hmacs_list = auth_hmacs; ep->auth_chunk_list = auth_chunks; + ep->prsctp_enable = net->sctp.prsctp_enable; return ep; diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c index 56f364d..0e3045e 100644 --- a/net/sctp/sm_make_chunk.c +++ b/net/sctp/sm_make_chunk.c @@ -261,7 +261,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, chunksize += WORD_ROUND(SCTP_SAT_LEN(num_types)); chunksize += sizeof(ecap_param); - if (net->sctp.prsctp_enable) + if (asoc->prsctp_enable) chunksize += sizeof(prsctp_param); /* ADDIP: Section 4.2.7: @@ -355,7 +355,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc, sctp_addto_param(retval, num_ext, extensions); } - if (net->sctp.prsctp_enable) + if (asoc->prsctp_enable) sctp_addto_chunk(retval, sizeof(prsctp_param), &prsctp_param); if (sp->adaptation_ind) { @@ -2024,8 +2024,8 @@ static void sctp_process_ext_param(struct sctp_association *asoc, for (i = 0; i < num_ext; i++) { switch (param.ext->chunks[i]) { case SCTP_CID_FWD_TSN: - if (net->sctp.prsctp_enable && !asoc->peer.prsctp_capable) - asoc->peer.prsctp_capable = 1; + if (asoc->prsctp_enable && !asoc->peer.prsctp_capable) + asoc->peer.prsctp_capable = 1; break; case SCTP_CID_AUTH: /* if the peer reports AUTH, assume that he @@ -2169,7 +2169,7 @@ static sctp_ierror_t sctp_verify_param(struct net *net, break; case SCTP_PARAM_FWD_TSN_SUPPORT: - if (net->sctp.prsctp_enable) + if (ep->prsctp_enable) break; goto fallthrough; @@ -2653,7 +2653,7 @@ do_addr_param: break; case SCTP_PARAM_FWD_TSN_SUPPORT: - if (net->sctp.prsctp_enable) { + if (asoc->prsctp_enable) { asoc->peer.prsctp_capable = 1; break; } diff --git a/net/sctp/socket.c b/net/sctp/socket.c index cdabbd8..7460dde 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -3661,6 +3661,39 @@ static int sctp_setsockopt_recvnxtinfo(struct sock *sk, return 0; } +static int sctp_setsockopt_pr_supported(struct sock *sk, + char __user *optval, + unsigned int optlen) +{ + struct sctp_assoc_value params; + struct sctp_association *asoc; + int retval = -EINVAL; + + if (optlen != sizeof(params)) + goto out; + + if (copy_from_user(¶ms, optval, optlen)) { + retval = -EFAULT; + goto out; + } + + asoc = sctp_id2assoc(sk, params.assoc_id); + if (asoc) { + asoc->prsctp_enable = !!params.assoc_value; + } else if (!params.assoc_id) { + struct sctp_sock *sp = sctp_sk(sk); + + sp->ep->prsctp_enable = !!params.assoc_value; + } else { + goto out; + } + + retval = 0; + +out: + return retval; +} + /* API 6.2 setsockopt(), getsockopt() * * Applications use setsockopt() and getsockopt() to set or retrieve @@ -3821,6 +3854,9 @@ static int sctp_setsockopt(struct sock *sk, int level, int optname, case SCTP_RECVNXTINFO: retval = sctp_setsockopt_recvnxtinfo(sk, optval, optlen); break; + case SCTP_PR_SUPPORTED: + retval = sctp_setsockopt_pr_supported(sk, optval, optlen); + break; default: retval = -ENOPROTOOPT; break; @@ -6166,6 +6202,47 @@ static int sctp_getsockopt_recvnxtinfo(struct sock *sk, int len, return 0; } +static int sctp_getsockopt_pr_supported(struct sock *sk, int len, + char __user *optval, + int __user *optlen) +{ + struct sctp_assoc_value params; + struct sctp_association *asoc; + int retval = -EFAULT; + + if (len < sizeof(params)) { + retval = -EINVAL; + goto out; + } + + len = sizeof(params); + if (copy_from_user(¶ms, optval, len)) + goto out; + + asoc = sctp_id2assoc(sk, params.assoc_id); + if (asoc) { + params.assoc_value = asoc->prsctp_enable; + } else if (!params.assoc_id) { + struct sctp_sock *sp = sctp_sk(sk); + + params.assoc_value = sp->ep->prsctp_enable; + } else { + retval = -EINVAL; + goto out; + } + + if (put_user(len, optlen)) + goto out; + + if (copy_to_user(optval, ¶ms, len)) + goto out; + + retval = 0; + +out: + return retval; +} + static int sctp_getsockopt(struct sock *sk, int level, int optname, char __user *optval, int __user *optlen) { @@ -6319,6 +6396,9 @@ static int sctp_getsockopt(struct sock *sk, int level, int optname, case SCTP_RECVNXTINFO: retval = sctp_getsockopt_recvnxtinfo(sk, len, optval, optlen); break; + case SCTP_PR_SUPPORTED: + retval = sctp_getsockopt_pr_supported(sk, len, optval, optlen); + break; default: retval = -ENOPROTOOPT; break;