From patchwork Fri Apr 14 17:45:02 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anoob Joseph X-Patchwork-Id: 126112 X-Patchwork-Delegate: gakhil@marvell.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 8F2E442943; Fri, 14 Apr 2023 19:47:17 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 7D8C642D0B; Fri, 14 Apr 2023 19:47:17 +0200 (CEST) Received: from mx0b-0016f401.pphosted.com (mx0b-0016f401.pphosted.com [67.231.156.173]) by mails.dpdk.org (Postfix) with ESMTP id 5C789410F6 for ; Fri, 14 Apr 2023 19:47:15 +0200 (CEST) Received: from pps.filterd (m0045851.ppops.net [127.0.0.1]) by mx0b-0016f401.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 33EFFBRF009805; Fri, 14 Apr 2023 10:47:14 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marvell.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=pfpt0220; bh=XtUdpJ8QdUXSDvWbUA/QZkknn1mx//ENKnmSrGfV/0c=; b=Ux38A/Rq7qnuiD0yrsHGoryCU0t4ftD956V9zW/3ltjceziSo2QjaWVTBOZ6WLpzWxe7 7a0nbnZYnezxLG5DQGXIrtjIm9khNLHEgW+bvtm05FFtRZyCHE/cAjkgbMlrGIt3aJAE RAcLxuA9MWyStFyeZs/rQf85lu/JoTRgF5Gy8Z0ioyeKlsyYBuEm6DCMvJzUQXWT9SmE Um4tDDHY4OrA2IV4VkGIczbw0oxUg+BrUIYxNRABV/adwtL88AgFmNIwnN/zMcRu2XQj 3VlihCTPeql3WIArjVAD6SRUYMStv8v/rHNbbwdM3odVpd2gAqDUqahyn3NRbP8e5YdZ 9g== Received: from dc5-exch02.marvell.com ([199.233.59.182]) by mx0b-0016f401.pphosted.com (PPS) with ESMTPS id 3py646s6rx-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Fri, 14 Apr 2023 10:47:14 -0700 Received: from DC5-EXCH02.marvell.com (10.69.176.39) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server (TLS) id 15.0.1497.48; Fri, 14 Apr 2023 10:47:12 -0700 Received: from maili.marvell.com (10.69.176.80) by DC5-EXCH02.marvell.com (10.69.176.39) with Microsoft SMTP Server id 15.0.1497.48 via Frontend Transport; Fri, 14 Apr 2023 10:47:12 -0700 Received: from BG-LT92004.corp.innovium.com (unknown [10.28.161.183]) by maili.marvell.com (Postfix) with ESMTP id 249683F707F; Fri, 14 Apr 2023 10:47:06 -0700 (PDT) From: Anoob Joseph To: Thomas Monjalon , Akhil Goyal , Jerin Jacob , Konstantin Ananyev , Bernard Iremonger CC: Hemant Agrawal , =?utf-8?q?Mattias_R=C3=B6nnblom?= , "Kiran Kumar K" , Volodymyr Fialko , , Olivier Matz Subject: [PATCH v2 12/22] pdcp: add control PDU handling Date: Fri, 14 Apr 2023 23:15:02 +0530 Message-ID: <20230414174512.642-13-anoobj@marvell.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20230414174512.642-1-anoobj@marvell.com> References: <20221222092522.1628-1-anoobj@marvell.com> <20230414174512.642-1-anoobj@marvell.com> MIME-Version: 1.0 X-Proofpoint-GUID: qT1v4RQMC6k56Cc7_fu0iFbyQEem8MH2 X-Proofpoint-ORIG-GUID: qT1v4RQMC6k56Cc7_fu0iFbyQEem8MH2 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.254,Aquarius:18.0.942,Hydra:6.0.573,FMLib:17.11.170.22 definitions=2023-04-14_10,2023-04-14_01,2023-02-09_01 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Add control PDU handling and implement status report generation. Status report generation works only when RX_DELIV = RX_NEXT. Signed-off-by: Anoob Joseph Signed-off-by: Volodymyr Fialko --- app/test/test_pdcp.c | 1 + doc/guides/prog_guide/pdcp_lib.rst | 10 +++++++ lib/pdcp/meson.build | 2 ++ lib/pdcp/pdcp_cnt.c | 29 ++++++++++++++++++ lib/pdcp/pdcp_cnt.h | 14 +++++++++ lib/pdcp/pdcp_ctrl_pdu.c | 46 +++++++++++++++++++++++++++++ lib/pdcp/pdcp_ctrl_pdu.h | 15 ++++++++++ lib/pdcp/pdcp_entity.h | 15 ++++++++-- lib/pdcp/pdcp_process.c | 13 +++++++++ lib/pdcp/rte_pdcp.c | 47 +++++++++++++++++++++++++++++- lib/pdcp/rte_pdcp.h | 31 ++++++++++++++++++++ lib/pdcp/version.map | 2 ++ 12 files changed, 222 insertions(+), 3 deletions(-) create mode 100644 lib/pdcp/pdcp_cnt.c create mode 100644 lib/pdcp/pdcp_cnt.h create mode 100644 lib/pdcp/pdcp_ctrl_pdu.c create mode 100644 lib/pdcp/pdcp_ctrl_pdu.h diff --git a/app/test/test_pdcp.c b/app/test/test_pdcp.c index fc49947ba2..4ecb4d9572 100644 --- a/app/test/test_pdcp.c +++ b/app/test/test_pdcp.c @@ -415,6 +415,7 @@ create_test_conf_from_index(const int index, struct pdcp_test_conf *conf) conf->entity.sess_mpool = ts_params->sess_pool; conf->entity.cop_pool = ts_params->cop_pool; + conf->entity.ctr_pdu_pool = ts_params->mbuf_pool; conf->entity.pdcp_xfrm.bearer = pdcp_test_bearer[index]; conf->entity.pdcp_xfrm.en_ordering = 0; conf->entity.pdcp_xfrm.remove_duplicates = 0; diff --git a/doc/guides/prog_guide/pdcp_lib.rst b/doc/guides/prog_guide/pdcp_lib.rst index abd874f2cc..f23360dfc3 100644 --- a/doc/guides/prog_guide/pdcp_lib.rst +++ b/doc/guides/prog_guide/pdcp_lib.rst @@ -67,6 +67,15 @@ Data PDUs are regular packets submitted by upper layers for transmission to other end. Such packets would need to be ciphered and authenticated based on the entity configuration. +PDCP packet processing API for control PDU +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Control PDUs are used in PDCP as a communication channel between transmitting +and receiving entities. When upper layer request for operations such +re-establishment, receiving PDCP entity need to prepare a status report and +send it to the other end. The API ``pdcp_ctrl_pdu_status_gen`` allows +application to request the same. + PDCP packet processing API for data PDU ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -228,6 +237,7 @@ Supported features - Uplink & downlink traffic - HFN increment - IV generation as required per algorithm +- Control PDU generation Supported ciphering algorithms ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/lib/pdcp/meson.build b/lib/pdcp/meson.build index 08679b743a..75d476bf6d 100644 --- a/lib/pdcp/meson.build +++ b/lib/pdcp/meson.build @@ -8,7 +8,9 @@ if is_windows endif sources = files( + 'pdcp_cnt.c', 'pdcp_crypto.c', + 'pdcp_ctrl_pdu.c', 'pdcp_process.c', 'rte_pdcp.c', ) diff --git a/lib/pdcp/pdcp_cnt.c b/lib/pdcp/pdcp_cnt.c new file mode 100644 index 0000000000..c9b952184b --- /dev/null +++ b/lib/pdcp/pdcp_cnt.c @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2023 Marvell. + */ + +#include + +#include "pdcp_cnt.h" +#include "pdcp_entity.h" + +int +pdcp_cnt_ring_create(struct rte_pdcp_entity *en, const struct rte_pdcp_entity_conf *conf) +{ + struct entity_priv_dl_part *en_priv_dl; + uint32_t window_sz; + + if (en == NULL || conf == NULL) + return -EINVAL; + + if (conf->pdcp_xfrm.pkt_dir == RTE_SECURITY_PDCP_UPLINK) + return 0; + + en_priv_dl = entity_dl_part_get(en); + window_sz = pdcp_window_size_get(conf->pdcp_xfrm.sn_size); + + RTE_SET_USED(window_sz); + RTE_SET_USED(en_priv_dl); + + return 0; +} diff --git a/lib/pdcp/pdcp_cnt.h b/lib/pdcp/pdcp_cnt.h new file mode 100644 index 0000000000..bbda478b55 --- /dev/null +++ b/lib/pdcp/pdcp_cnt.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2023 Marvell. + */ + +#ifndef PDCP_CNT_H +#define PDCP_CNT_H + +#include + +#include "pdcp_entity.h" + +int pdcp_cnt_ring_create(struct rte_pdcp_entity *en, const struct rte_pdcp_entity_conf *conf); + +#endif /* PDCP_CNT_H */ diff --git a/lib/pdcp/pdcp_ctrl_pdu.c b/lib/pdcp/pdcp_ctrl_pdu.c new file mode 100644 index 0000000000..feb05fd863 --- /dev/null +++ b/lib/pdcp/pdcp_ctrl_pdu.c @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2023 Marvell. + */ + +#include +#include +#include + +#include "pdcp_ctrl_pdu.h" +#include "pdcp_entity.h" + +static __rte_always_inline void +pdcp_hdr_fill(struct rte_pdcp_up_ctrl_pdu_hdr *pdu_hdr, uint32_t rx_deliv) +{ + pdu_hdr->d_c = RTE_PDCP_PDU_TYPE_CTRL; + pdu_hdr->pdu_type = RTE_PDCP_CTRL_PDU_TYPE_STATUS_REPORT; + pdu_hdr->r = 0; + pdu_hdr->fmc = rte_cpu_to_be_32(rx_deliv); +} + +int +pdcp_ctrl_pdu_status_gen(struct entity_priv *en_priv, struct rte_mbuf *m) +{ + struct rte_pdcp_up_ctrl_pdu_hdr *pdu_hdr; + uint32_t rx_deliv; + int pdu_sz; + + if (!en_priv->flags.is_status_report_required) + return -EINVAL; + + pdu_sz = sizeof(struct rte_pdcp_up_ctrl_pdu_hdr); + + rx_deliv = en_priv->state.rx_deliv; + + /* Zero missing PDUs - status report contains only FMC */ + if (rx_deliv >= en_priv->state.rx_next) { + pdu_hdr = (struct rte_pdcp_up_ctrl_pdu_hdr *)rte_pktmbuf_append(m, pdu_sz); + if (pdu_hdr == NULL) + return -ENOMEM; + pdcp_hdr_fill(pdu_hdr, rx_deliv); + + return 0; + } + + return -ENOTSUP; +} diff --git a/lib/pdcp/pdcp_ctrl_pdu.h b/lib/pdcp/pdcp_ctrl_pdu.h new file mode 100644 index 0000000000..a2424fbd10 --- /dev/null +++ b/lib/pdcp/pdcp_ctrl_pdu.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(C) 2023 Marvell. + */ + +#ifndef PDCP_CTRL_PDU_H +#define PDCP_CTRL_PDU_H + +#include + +#include "pdcp_entity.h" + +int +pdcp_ctrl_pdu_status_gen(struct entity_priv *en_priv, struct rte_mbuf *m); + +#endif /* PDCP_CTRL_PDU_H */ diff --git a/lib/pdcp/pdcp_entity.h b/lib/pdcp/pdcp_entity.h index 3108795977..7b7e7f69dd 100644 --- a/lib/pdcp/pdcp_entity.h +++ b/lib/pdcp/pdcp_entity.h @@ -109,6 +109,13 @@ union cipher_iv_partial { uint64_t u64[2]; }; +struct pdcp_cnt_bitmap { + /** Number of entries that can be stored. */ + uint32_t size; + /** Bitmap of the count values already received.*/ + struct rte_bitmap *bmp; +}; + /* * Layout of PDCP entity: [rte_pdcp_entity] [entity_priv] [entity_dl/ul] */ @@ -136,9 +143,13 @@ struct entity_priv { uint64_t is_ul_entity : 1; /** Is NULL auth. */ uint64_t is_null_auth : 1; + /** Is status report required.*/ + uint64_t is_status_report_required : 1; } flags; /** Crypto op pool. */ struct rte_mempool *cop_pool; + /** Control PDU pool. */ + struct rte_mempool *ctr_pdu_pool; /** PDCP header size. */ uint8_t hdr_sz; /** PDCP AAD size. For AES-CMAC, additional message is prepended for the operation. */ @@ -148,8 +159,8 @@ struct entity_priv { }; struct entity_priv_dl_part { - /* NOTE: when in-order-delivery is supported, post PDCP packets would need to cached. */ - uint8_t dummy; + /** PDCP would need to track the count values that are already received.*/ + struct pdcp_cnt_bitmap bitmap; }; struct entity_priv_ul_part { diff --git a/lib/pdcp/pdcp_process.c b/lib/pdcp/pdcp_process.c index 9c1a5e0669..267b3b7723 100644 --- a/lib/pdcp/pdcp_process.c +++ b/lib/pdcp/pdcp_process.c @@ -1157,6 +1157,19 @@ pdcp_entity_priv_populate(struct entity_priv *en_priv, const struct rte_pdcp_ent if (a_xfrm != NULL && a_xfrm->auth.algo == RTE_CRYPTO_AUTH_NULL) en_priv->flags.is_null_auth = 1; + /** + * flags.is_status_report_required + * + * Indicate whether status report is required. + */ + if (conf->status_report_required) { + /** Status report is required only for DL entities. */ + if (conf->pdcp_xfrm.pkt_dir != RTE_SECURITY_PDCP_DOWNLINK) + return -EINVAL; + + en_priv->flags.is_status_report_required = 1; + } + /** * hdr_sz * diff --git a/lib/pdcp/rte_pdcp.c b/lib/pdcp/rte_pdcp.c index 8914548dbd..5cd3f5ca31 100644 --- a/lib/pdcp/rte_pdcp.c +++ b/lib/pdcp/rte_pdcp.c @@ -6,7 +6,9 @@ #include #include +#include "pdcp_cnt.h" #include "pdcp_crypto.h" +#include "pdcp_ctrl_pdu.h" #include "pdcp_entity.h" #include "pdcp_process.h" @@ -34,7 +36,7 @@ rte_pdcp_entity_establish(const struct rte_pdcp_entity_conf *conf) struct entity_priv *en_priv; int ret, entity_size; - if (conf == NULL || conf->cop_pool == NULL) { + if (conf == NULL || conf->cop_pool == NULL || conf->ctr_pdu_pool == NULL) { rte_errno = -EINVAL; return NULL; } @@ -79,6 +81,7 @@ rte_pdcp_entity_establish(const struct rte_pdcp_entity_conf *conf) en_priv->state.rx_deliv = conf->count; en_priv->state.tx_next = conf->count; en_priv->cop_pool = conf->cop_pool; + en_priv->ctr_pdu_pool = conf->ctr_pdu_pool; /* Setup crypto session */ ret = pdcp_crypto_sess_create(entity, conf); @@ -89,6 +92,10 @@ rte_pdcp_entity_establish(const struct rte_pdcp_entity_conf *conf) if (ret) goto crypto_sess_destroy; + ret = pdcp_cnt_ring_create(entity, conf); + if (ret) + goto crypto_sess_destroy; + return entity; crypto_sess_destroy: @@ -136,3 +143,41 @@ rte_pdcp_entity_suspend(struct rte_pdcp_entity *pdcp_entity, return 0; } + +struct rte_mbuf * +rte_pdcp_control_pdu_create(struct rte_pdcp_entity *pdcp_entity, + enum rte_pdcp_ctrl_pdu_type type) +{ + struct entity_priv *en_priv; + struct rte_mbuf *m; + int ret; + + if (pdcp_entity == NULL) { + rte_errno = -EINVAL; + return NULL; + } + + en_priv = entity_priv_get(pdcp_entity); + + m = rte_pktmbuf_alloc(en_priv->ctr_pdu_pool); + if (m == NULL) { + rte_errno = -ENOMEM; + return NULL; + } + + switch (type) { + case RTE_PDCP_CTRL_PDU_TYPE_STATUS_REPORT: + ret = pdcp_ctrl_pdu_status_gen(en_priv, m); + break; + default: + ret = -ENOTSUP; + } + + if (ret) { + rte_pktmbuf_free(m); + rte_errno = ret; + return NULL; + } + + return m; +} diff --git a/lib/pdcp/rte_pdcp.h b/lib/pdcp/rte_pdcp.h index 54f88e3fd3..d2db25d7d9 100644 --- a/lib/pdcp/rte_pdcp.h +++ b/lib/pdcp/rte_pdcp.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #ifdef __cplusplus @@ -78,6 +79,8 @@ struct rte_pdcp_entity_conf { struct rte_mempool *sess_mpool; /** Crypto op pool.*/ struct rte_mempool *cop_pool; + /** Mbuf pool to be used for allocating control PDUs.*/ + struct rte_mempool *ctr_pdu_pool; /** * 32 bit count value (HFN + SN) to be used for the first packet. * pdcp_xfrm.hfn would be ignored as the HFN would be derived from this value. @@ -91,6 +94,15 @@ struct rte_pdcp_entity_conf { uint8_t dev_id; /** Reverse direction during IV generation. Can be used to simulate UE crypto processing.*/ bool reverse_iv_direction; + /** + * Status report required (specified in TS 38.331). + * + * If PDCP entity is configured to send a PDCP status report, the upper layer application + * may request a receiving PDCP entity to generate a PDCP status report using + * ``rte_pdcp_ctrl_pdu_create``. In addition, PDCP status reports may be generated during + * operations such as entity re-establishment. + */ + bool status_report_required; }; /* >8 End of structure rte_pdcp_entity_conf. */ @@ -169,6 +181,25 @@ int rte_pdcp_entity_suspend(struct rte_pdcp_entity *pdcp_entity, struct rte_mbuf *out_mb[]); +/** + * @warning + * @b EXPERIMENTAL: this API may change without prior notice + * + * Create control PDU packet of the `type` specified. + * + * @param pdcp_entity + * Pointer to the PDCP entity for which the control PDU need to be generated. + * @param type + * Type of control PDU to be generated. + * @return + * - Control PDU generated, in case of success. + * - NULL in case of failure. rte_errno will be set to error code. + */ +__rte_experimental +struct rte_mbuf * +rte_pdcp_control_pdu_create(struct rte_pdcp_entity *pdcp_entity, + enum rte_pdcp_ctrl_pdu_type type); + /** * @warning * @b EXPERIMENTAL: this API may change without prior notice diff --git a/lib/pdcp/version.map b/lib/pdcp/version.map index f9ff30600a..d0cf338e1f 100644 --- a/lib/pdcp/version.map +++ b/lib/pdcp/version.map @@ -6,6 +6,8 @@ EXPERIMENTAL { rte_pdcp_entity_release; rte_pdcp_entity_suspend; + rte_pdcp_control_pdu_create; + rte_pdcp_pkt_post_process; rte_pdcp_pkt_pre_process;