lib: add pdcp protocol
Subsystems (2)
cover lib: add pdcp protocol
Add Packet Data Convergence Protocol (PDCP) processing library.
The library is similar to lib_ipsec which provides IPsec processing capabilities in DPDK.
PDCP would involve roughly the following options,
1. Transfer of user plane data
2. Transfer of control plane data
3. Header compression
4. Uplink data compression
5. Ciphering and integrity protection
PDCP library provides following control path APIs that is used to configure various PDCP entities,
1. rte_pdcp_establish()
2. rte_pdcp_suspend()
3. rte_pdcp_release()
PDCP process is split into 2 parts. One before crypto processing (rte_pdcp_pkt_pre_process()) and one after crypto processing (rte_pdcp_pkt_post_process()). Since cryptodev dequeue can return crypto operations belonging to multiple entities, rte_pdcp_pkt_crypto_group() is added to help grouping crypto operations belonging to same entity.
Similar to lib IPsec, lib PDCP would allow application to use same API sequence while leveraging protocol offload features enabled by rte_security library. Lib PDCP would internally change the handles registered for *pre_process* and *post_process* based on features enabled in the entity.
Lib PDCP would create the required sessions on the device provided in entity to minimize the application requirements. Also, the crypto_op allocation and free would also be done internally by lib PDCP to allow the library to create crypto ops as required for the input packets. For example, when control PDUs are received, no cryptodev enqueue-dequeue is expected for the same and lib PDCP is expected to handle it differently.
Changes planned for next version
- Add APIs for rte_pdcp_entity_re_establish, rte_pdcp_entity_reconfigure
- Implementation for all APIs covering basic control plane & user plane packets
- Framework to handle control PDUs
- Unit test leveraging existing PDCP vectors available in test_cryptodev
- Eventdev based timer integration for t-Reordering & discardTimer
- Integration with reorder library to handle in-order delivery
Sample application sequence:
struct rte_mbuf **out_mb, *pkts[MAX_BURST_SIZE];
struct rte_crypto_op *cop[MAX_BURST_SIZE];
struct rte_pdcp_group grp[MAX_BURST_SIZE];
struct rte_pdcp_entity *pdcp_entity;
int nb_max_out_mb, ret, nb_grp;
/* Create PDCP entity */
pdcp_entity = rte_pdcp_entity_establish(&conf);
/**
* Allocate buffer for holding mbufs returned during PDCP suspend,
* release & post-process APIs.
*/
/* Max packets that can be cached in entity + burst size */
nb_max_out_mb = pdcp_entity->max_pkt_cache + 1;
out_mb = rte_malloc(NULL, nb_max_out_mb * sizeof(uintptr_t), 0);
if (out_mb == NULL) {
/* Handle error */
}
while (1) {
/* Receive packet and form mbuf */
/**
* Prepare packets for crypto operation. Following operations
* would be done,
*
* Transmiting entity/UL (only data PDUs):
* - Perform compression
* - Assign sequence number
* - Add PDCP header
* - Create & prepare crypto_op
* - Prepare IV for crypto operation (auth_gen, encrypt)
* - Save original PDCP SDU (during PDCP re-establishment,
* unconfirmed PDCP SDUs need to crypto processed again and
* transmitted/re-transmitted)
*
* Receiving entity/DL:
* - Any control PDUs received would be processed and
* appropriate actions taken. If data PDU, continue.
* - Determine sequence number (based on HFN & per packet SN)
* - Prepare crypto_op
* - Prepare IV for crypto operation (decrypt, auth_verify)
*/
nb_success = rte_pdcp_pkt_pre_process(pdcp_entity, pkts, cop,
nb_rx, &nb_err);
if (nb_err != 0) {
/* Handle error packets */
}
if ((rte_cryptodev_enqueue_burst(dev_id, qp_id, cop, nb_success)
!= nb_success) {
/* Retry for enqueue failure packets */
}
...
ret = rte_cryptodev_dequeue_burst(dev_id, qp_id, cop,
MAX_BURST_SIZE);
if (ret == 0)
continue;
/**
* Received a burst of completed crypto ops from cryptodev. It
* may belong to various entities. Group similar ones together
* for entity specific post-processing.
*/
/**
* Groups similar entities together. Frees crypto op and based
* on crypto_op status, set mbuf->ol_flags which would be
* checked in rte_pdcp_pkt_post_process().
*/
nb_grp = rte_pdcp_pkt_crypto_group(cop, pkts, grp, ret);
for (i = 0; i != nb_grp; i++) {
/**
* Post process packets after crypto completion.
* Following operations would be done,
*
* Transmiting entity/UL:
* - Check crypto result
*
* Receiving entity/DL:
* - Check crypto operation status
* - Check for duplication (if yes, drop duplicate)
* - Perform decompression
* - Trim PDCP header
* - Hold packet (SDU) for in-order delivery (return
* completed packets as and when sequence is
* completed)
* - If not in sequence, cache the packet and start
* t-Reordering timer. When timer expires, the
* packets need to delivered to upper layers (not
* treated as error packets).
*/
nb_success = rte_pdcp_pkt_post_process(grp[i].id.ptr,
grp[i].m, out_mb,
grp[i].cnt,
&nb_err);
if (nb_err != 0) {
/* Handle error packets */
}
/* Perform additional operations */
/**
* Tranmitting entity/UL
* - If duplication is enabled, duplicate PDCP PDUs
* - When lower layers confirm reception of a PDCP PDU,
* it should be communicated to PDCP layer so that
* PDCP can drop the corresponding SDU
*/
}
}Anoob Joseph (1):
lib: add pdcp protocol
doc/api/doxy-api-index.md | 3 +- doc/api/doxy-api.conf.in | 1 + lib/meson.build | 1 + lib/pdcp/meson.build | 7 ++ lib/pdcp/rte_pdcp.h | 244 ++++++++++++++++++++++++++++++++++++++ lib/pdcp/rte_pdcp_group.h | 134 +++++++++++++++++++++ lib/pdcp/version.map | 13 ++ 7 files changed, 402 insertions(+), 1 deletion(-) create mode 100644 lib/pdcp/meson.build create mode 100644 lib/pdcp/rte_pdcp.h create mode 100644 lib/pdcp/rte_pdcp_group.h create mode 100644 lib/pdcp/version.map
--
2.28.0
RFC 1/1 lib: add pdcp protocol
Add Packet Data Convergence Protocol (PDCP) processing library.
The library is similar to lib_ipsec which provides IPsec processing capabilities in DPDK.
PDCP would involve roughly the following options,
1. Transfer of user plane data
2. Transfer of control plane data
3. Header compression
4. Uplink data compression
5. Ciphering and integrity protection
PDCP library provides following control path APIs that is used to configure various PDCP entities,
1. rte_pdcp_establish()
2. rte_pdcp_suspend()
3. rte_pdcp_release()
PDCP process is split into 2 parts. One before crypto processing (rte_pdcp_pkt_pre_process()) and one after crypto processing (rte_pdcp_pkt_post_process()). Since cryptodev dequeue can return crypto operations belonging to multiple entities, rte_pdcp_pkt_crypto_group() is added to help grouping crypto operations beloning to same entity.
--- doc/api/doxy-api-index.md | 3 +- doc/api/doxy-api.conf.in | 1 + lib/meson.build | 1 + lib/pdcp/meson.build | 7 ++ lib/pdcp/rte_pdcp.h | 244 ++++++++++++++++++++++++++++++++++++++ lib/pdcp/rte_pdcp_group.h | 134 +++++++++++++++++++++ lib/pdcp/version.map | 13 ++ 7 files changed, 402 insertions(+), 1 deletion(-) create mode 100644 lib/pdcp/meson.build create mode 100644 lib/pdcp/rte_pdcp.h create mode 100644 lib/pdcp/rte_pdcp_group.h create mode 100644 lib/pdcp/version.map
doc/api/doxy-api-index.md +2 -1
@@ -125,7 +125,8 @@ The public API headers are grouped by topics: [Geneve](@ref rte_geneve.h), [eCPRI](@ref rte_ecpri.h), [L2TPv2](@ref rte_l2tpv2.h), - [PPP](@ref rte_ppp.h) + [PPP](@ref rte_ppp.h), + [PDCP](@ref rte_pdcp.h) - **QoS**: [metering](@ref rte_meter.h),
doc/api/doxy-api.conf.in +1 -0
@@ -61,6 +61,7 @@ INPUT = @TOPDIR@/doc/api/doxy-api-index.md \ @TOPDIR@/lib/net \ @TOPDIR@/lib/pcapng \ @TOPDIR@/lib/pci \ + @TOPDIR@/lib/pdcp \ @TOPDIR@/lib/pdump \ @TOPDIR@/lib/pipeline \ @TOPDIR@/lib/port \
lib/meson.build +1 -0
@@ -63,6 +63,7 @@ libraries = [ 'flow_classify', # flow_classify lib depends on pkt framework table lib 'graph', 'node', + 'pdcp', # pdcp lib depends on crypto and security ] optional_libs = [
lib/pdcp/meson.build new file +7 -0
@@ -0,0 +1,7 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(C) 2022 Marvell. +# + +headers = files('rte_pdcp.h') + +deps += ['security']
lib/pdcp/rte_pdcp.h new file +244 -0
244 lines not on this page · raw message
lib/pdcp/rte_pdcp_group.h new file +134 -0
135 lines not on this page · raw message
lib/pdcp/version.map new file +13 -0
@@ -0,0 +1,13 @@ +EXPERIMENTAL { + global: + + # added in 23.03 + rte_pdcp_entity_establish; + rte_pdcp_entity_release; + rte_pdcp_entity_suspend; + + rte_pdcp_pkt_post_process; + rte_pdcp_pkt_pre_process; + + local: *; +};
Signature · 1 line
2.28.0
Quoted 39 lines
Subject: [RFC 0/1] lib: add pdcp protocol
Add Packet Data Convergence Protocol (PDCP) processing library.
The library is similar to
lib_ipsecwhich provides IPsec processing capabilities in DPDK.PDCP would involve roughly the following options,
1. Transfer of user plane data
2. Transfer of control plane data
3. Header compression
4. Uplink data compression
5. Ciphering and integrity protectionPDCP library provides following control path APIs that is used to configure various PDCP entities,
1.rte_pdcp_establish()
2.rte_pdcp_suspend()
3.rte_pdcp_release()PDCP process is split into 2 parts. One before crypto processing (
rte_pdcp_pkt_pre_process()) and one after crypto processing (rte_pdcp_pkt_post_process()). Since cryptodev dequeue can return crypto operations belonging to multiple entities,rte_pdcp_pkt_crypto_group()is added to help grouping crypto operations belonging to same entity.Similar to lib IPsec, lib PDCP would allow application to use same API sequence while leveraging protocol offload features enabled by
rte_securitylibrary. Lib PDCP would internally change the handles registered for *pre_process* and *post_process* based on features enabled in the entity.Lib PDCP would create the required sessions on the device provided in entity to minimize the application requirements. Also, the
crypto_opallocation and free would also be done internally by lib PDCP to allow the library to create crypto ops as required for the input packets. For example, when control PDUs are
received, no cryptodev enqueue-dequeue is expected for the same and lib PDCP is expected to handle it differently.
Quoted 8 lines
Changes planned for next version
- Add APIs forrte_pdcp_entity_re_establish,rte_pdcp_entity_reconfigure
- Implementation for all APIs covering basic control plane & user plane packets
- Framework to handle control PDUs
- Unit test leveraging existing PDCP vectors available intest_cryptodev
- Eventdev based timer integration for t-Reordering & discardTimer
- Integration with reorder library to handle in-order delivery
Can you send the next version rebased over v22.11?
Also add documentation (pdcp.rst) file explaining about the new library. Add sample sequence also in that.
Do you also plan to add, header compression? I see that it is mentioned above, But there is no API as of now?
Quoted 142 lines
Sample application sequence:
struct rte_mbuf **out_mb, *pkts[MAX_BURST_SIZE]; struct rte_crypto_op *cop[MAX_BURST_SIZE]; struct rte_pdcp_group grp[MAX_BURST_SIZE]; struct rte_pdcp_entity *pdcp_entity; int nb_max_out_mb, ret, nb_grp; /* Create PDCP entity */ pdcp_entity = rte_pdcp_entity_establish(&conf); /** * Allocate buffer for holding mbufs returned during PDCP suspend, * release & post-process APIs. */ /* Max packets that can be cached in entity + burst size */ nb_max_out_mb = pdcp_entity->max_pkt_cache + 1; out_mb = rte_malloc(NULL, nb_max_out_mb * sizeof(uintptr_t), 0); if (out_mb == NULL) { /* Handle error */ } while (1) { /* Receive packet and form mbuf */ /** * Prepare packets for crypto operation. Following operations * would be done, * * Transmiting entity/UL (only data PDUs): * - Perform compression * - Assign sequence number * - Add PDCP header * - Create & prepare crypto_op * - Prepare IV for crypto operation (auth_gen, encrypt) * - Save original PDCP SDU (during PDCP re-establishment, * unconfirmed PDCP SDUs need to crypto processed againand
* transmitted/re-transmitted)
*
* Receiving entity/DL:
* - Any control PDUs received would be processed and
* appropriate actions taken. If data PDU, continue.
* - Determine sequence number (based on HFN & per packet
SN)* - Prepare crypto_op * - Prepare IV for crypto operation (decrypt, auth_verify) */ nb_success = rte_pdcp_pkt_pre_process(pdcp_entity, pkts, cop, nb_rx, &nb_err); if (nb_err != 0) { /* Handle error packets */ } if ((rte_cryptodev_enqueue_burst(dev_id, qp_id, cop,
nb_success)
!=nb_success) {
/* Retry for enqueue failure packets */
}...
ret = rte_cryptodev_dequeue_burst(dev_id,
qp_id, cop,
MAX_BURST_SIZE);
if (ret == 0)
continue;/**
* Received a burst of completed crypto ops from cryptodev. It
* may belong to various entities. Group similar ones together
* for entity specific post-processing.
*//**
* Groups similar entities together. Frees crypto op and based
* oncrypto_opstatus, setmbuf->ol_flagswhich would be
* checked inrte_pdcp_pkt_post_process().
*/
nb_grp=rte_pdcp_pkt_crypto_group(cop, pkts, grp, ret);for (i = 0; i !=
nb_grp; i++) {/**
* Post process packets after crypto completion.
* Following operations would be done,
*
* Transmiting entity/UL:
* - Check crypto result
*
* Receiving entity/DL:
* - Check crypto operation status
* - Check for duplication (if yes, drop duplicate)
* - Perform decompression
* - Trim PDCP header
* - Hold packet (SDU) for in-order delivery (return
* completed packets as and when sequence is
* completed)
* - If not in sequence, cache the packet and start
* t-Reordering timer. When timer expires, the
* packets need to delivered to upper layers (not
* treated as error packets).
*/
nb_success= rte_pdcp_pkt_post_process(grp[i].id.ptr,
grp[i].m,out_mb, grp[i].cnt,&nb_err);
if (nb_err!= 0) {
/* Handle error packets */
}/* Perform additional operations */
/**
* Tranmitting entity/UL
* - If duplication is enabled, duplicate PDCP PDUs
* - When lower layers confirm reception of a PDCP
PDU,* it should be communicated to PDCP layer so that * PDCP can drop the corresponding SDU */ } }Anoob Joseph (1):
lib: add pdcp protocoldoc/api/doxy-api-index.md | 3 +- doc/api/doxy-api.conf.in | 1 + lib/meson.build | 1 + lib/pdcp/meson.build | 7 ++ lib/pdcp/rte_pdcp.h | 244 ++++++++++++++++++++++++++++++++++++++ lib/pdcp/rte_pdcp_group.h | 134 +++++++++++++++++++++ lib/pdcp/version.map | 13 ++ 7 files changed, 402 insertions(+), 1 deletion(-) create mode 100644 lib/pdcp/meson.build create mode 100644 lib/pdcp/rte_pdcp.h create mode 100644 lib/pdcp/rte_pdcp_group.h create mode 100644 lib/pdcp/version.map--
2.28.0
Hi Akhil,
Thanks for the review. Please see inline.
Thanks
Anoob
Quoted 62 lines
-----Original Message-----
From: Akhil Goyal <[email protected]>
Sent: Tuesday, December 13, 2022 12:32 PM
To: Anoob Joseph <[email protected]>; Thomas Monjalon <[email protected]>; Jerin Jacob Kollanukkaran <[email protected]>; Konstantin Ananyev <[email protected]>; Bernard Iremonger <[email protected]>
Cc: Hemant Agrawal <[email protected]>; Mattias Rönnblom <[email protected]>; Kiran Kumar Kokkilagadda <[email protected]>; Volodymyr Fialko <[email protected]>; [email protected]
Subject: RE: [RFC 0/1] lib: add pdcp protocolQuoted 15 lines
Subject: [RFC 0/1] lib: add pdcp protocol
Add Packet Data Convergence Protocol (PDCP) processing library.
The library is similar to
lib_ipsecwhich provides IPsec processing capabilities in DPDK.PDCP would involve roughly the following options, 1. Transfer of user plane data 2. Transfer of control plane data 3. Header compression 4. Uplink data compression 5. Ciphering and integrity protection
PDCP library provides following control path APIs that is used to configure various PDCP entities, 1.
rte_pdcp_establish()2.rte_pdcp_suspend()3.rte_pdcp_release()Quoted 5 lines
PDCP process is split into 2 parts. One before crypto processing (
rte_pdcp_pkt_pre_process()) and one after crypto processing (rte_pdcp_pkt_post_process()). Since cryptodev dequeue can return crypto operations belonging to multiple entities,rte_pdcp_pkt_crypto_group()is added to help grouping crypto operationsbelonging to same entity.
Quoted 6 lines
Similar to lib IPsec, lib PDCP would allow application to use same API sequence while leveraging protocol offload features enabled by
rte_securitylibrary. Lib PDCP would internally change the handles registered for
*pre_process* and *post_process* based on features enabled in theentity.
Quoted 9 lines
Lib PDCP would create the required sessions on the device provided in entity to minimize the application requirements. Also, the
crypto_opallocation and free would also be done internally by lib PDCP to allow the library to create crypto ops as required for the input packets. For example, when control PDUs are received, no cryptodev enqueue-dequeue is expected for the same and lib PDCP is expected to handle it differently.Quoted 11 lines
Changes planned for next version
- Add APIs forrte_pdcp_entity_re_establish,rte_pdcp_entity_reconfigure
- Implementation for all APIs covering basic control plane & user plane packets
- Framework to handle control PDUs
- Unit test leveraging existing PDCP vectors available intest_cryptodev
- Eventdev based timer integration for t-Reordering & discardTimer
- Integration with reorder library to handle in-order delivery
Quoted 3 lines
Can you send the next version rebased over v22.11?
Also add documentation (pdcp.rst) file explaining about the new library. Add sample sequence also in that.
[Anoob] Sure. Will send v1 with test application in another couple of days.
Quoted 3 lines
Do you also plan to add, header compression? I see that it is mentioned above, But there is no API as of now?
There are 2 kinds of compression when dealing with PDCP.
1. Header compression (which is more like a dictionary lookup)
2. UDC compression (which uses standard compression methods).
[Anoob] We have plans to support Item 1, ie, header compression. For item 2, we are evaluating the practical usage requirements to decide on whether PDCP lib would need to natively support it. Adding an interface to compressdev would increase the API requirements, but since it would come outside (& before) any of the proposed APIs, the feature can be added as a standalone item.
Quoted 150 lines
Quoted 40 lines
Sample application sequence:
struct rte_mbuf **out_mb, *pkts[MAX_BURST_SIZE]; struct rte_crypto_op *cop[MAX_BURST_SIZE]; struct rte_pdcp_group grp[MAX_BURST_SIZE]; struct rte_pdcp_entity *pdcp_entity; int nb_max_out_mb, ret, nb_grp; /* Create PDCP entity */ pdcp_entity = rte_pdcp_entity_establish(&conf); /** * Allocate buffer for holding mbufs returned during PDCP suspend, * release & post-process APIs. */ /* Max packets that can be cached in entity + burst size */ nb_max_out_mb = pdcp_entity->max_pkt_cache + 1; out_mb = rte_malloc(NULL, nb_max_out_mb * sizeof(uintptr_t), 0); if (out_mb == NULL) { /* Handle error */ } while (1) { /* Receive packet and form mbuf */ /** * Prepare packets for crypto operation. Following operations * would be done, * * Transmiting entity/UL (only data PDUs): * - Perform compression * - Assign sequence number * - Add PDCP header * - Create & prepare crypto_op * - Prepare IV for crypto operation (auth_gen, encrypt) * - Save original PDCP SDU (during PDCP re-establishment, * unconfirmed PDCP SDUs need to crypto processed againQuoted 7 lines
and
* transmitted/re-transmitted)
*
* Receiving entity/DL:
* - Any control PDUs received would be processed and
* appropriate actions taken. If data PDU, continue.
* - Determine sequence number (based on HFN & perpacket
Quoted 5 lines
SN)
* - Preparecrypto_op
* - Prepare IV for crypto operation (decrypt,auth_verify) */
nb_success= rte_pdcp_pkt_pre_process(pdcp_entity, pkts,cop,
Quoted 13 lines
nb_rx, &nb_err); if (nb_err != 0) { /* Handle error packets */ } if ((rte_cryptodev_enqueue_burst(dev_id, qp_id, cop, nb_success) != nb_success) { /* Retry for enqueue failure packets */ } ...Quoted 7 lines
ret = rte_cryptodev_dequeue_burst(dev_id, qp_id, cop, MAX_BURST_SIZE); if (ret == 0) continue; /** * Received a burst of completed crypto ops from cryptodev.It
Quoted 1 line
* may belong to various entities. Group similar ones
together
Quoted 5 lines
* for entity specific post-processing. */ /** * Groups similar entities together. Frees crypto op andbased
Quoted 20 lines
* on
crypto_opstatus, setmbuf->ol_flagswhich would be
* checked inrte_pdcp_pkt_post_process().
*/
nb_grp=rte_pdcp_pkt_crypto_group(cop, pkts, grp, ret);for (i = 0; i !=
nb_grp; i++) {/**
* Post process packets after crypto completion.
* Following operations would be done,
*
* Transmiting entity/UL:
* - Check crypto result
*
* Receiving entity/DL:
* - Check crypto operation status
* - Check for duplication (if yes, drop duplicate)
* - Perform decompression
* - Trim PDCP header
* - Hold packet (SDU) for in-order delivery (returnQuoted 8 lines
* completed packets as and when sequence is
* completed)
* - If not in sequence, cache the packet and start
* t-Reordering timer. When timer expires, the
* packets need to delivered to upper layers (not
* treated as error packets).
*/
nb_success=rte_pdcp_pkt_post_process(grp[i].id.ptr,
Quoted 5 lines
grp[i].m, out_mb, grp[i].cnt, &nb_err); if (nb_err != 0) { /* Handle error packets */Quoted 8 lines
} /* Perform additional operations */ /** * Tranmitting entity/UL * - If duplication is enabled, duplicate PDCP PDUs * - When lower layers confirm reception of a PDCPPDU,
Quoted 6 lines
* it should be communicated to PDCP layer so that * PDCP can drop the corresponding SDU */ } }Quoted 8 lines
Anoob Joseph (1):
lib: add pdcp protocoldoc/api/doxy-api-index.md | 3 +- doc/api/doxy-api.conf.in | 1 + lib/meson.build | 1 + lib/pdcp/meson.build | 7 ++ lib/pdcp/rte_pdcp.h | 244++++++++++++++++++++++++++++++++++++++
Quoted 9 lines
lib/pdcp/rte_pdcp_group.h | 134 +++++++++++++++++++++ lib/pdcp/version.map | 13 ++ 7 files changed, 402 insertions(+), 1 deletion(-) create mode 100644
lib/pdcp/meson.buildcreate mode 100644lib/pdcp/rte_pdcp.hcreate mode 100644lib/pdcp/rte_pdcp_group.hcreate mode 100644lib/pdcp/version.map--
2.28.0
cover lib: add pdcp protocol
In reply to Anoob JosephAdd Packet Data Convergence Protocol (PDCP) processing library.
The library is similar to lib_ipsec which provides IPsec processing capabilities in DPDK.
PDCP would involve roughly the following options,
1. Transfer of user plane data
2. Transfer of control plane data
3. Header compression
4. Uplink data compression
5. Ciphering and integrity protection
PDCP library provides following control path APIs that is used to configure various PDCP entities,
1. rte_pdcp_entity_establish()
2. rte_pdcp_entity_suspend()
3. rte_pdcp_entity_release()
PDCP process is split into 2 parts. One before crypto processing (rte_pdcp_pkt_pre_process()) and one after crypto processing (rte_pdcp_pkt_post_process()). Since cryptodev dequeue can return crypto operations belonging to multiple entities, rte_pdcp_pkt_crypto_group() is added to help grouping crypto operations belonging to same entity.
Similar to lib IPsec, lib PDCP would allow application to use same API sequence while leveraging protocol offload features enabled by rte_security library. Lib PDCP would internally change the handles registered for *pre_process* and *post_process* based on features enabled in the entity.
Lib PDCP would create the required sessions on the device provided in entity to minimize the application requirements. Also, the crypto_op allocation and free would also be done internally by lib PDCP to allow the library to create crypto ops as required for the input packets. For example, when control PDUs are received, no cryptodev enqueue-dequeue is expected for the same and lib PDCP is expected to handle it differently.
Changes from RFC
- Implementation for all APIs covering basic control plane & user plane packets
- Unit test leveraging existing PDCP vectors available in test_cryptodev
- Unit test performing both UL & DL operations to verify various protocol features
- Updated documentation
Changes planned for next version
- Add APIs for rte_pdcp_entity_re_establish, rte_pdcp_entity_reconfigure
- Framework to handle control PDUs
- Eventdev based timer integration for t-Reordering & discardTimer
- Integration with reorder library to handle in-order delivery
Sample application sequence:
struct rte_mbuf **out_mb, *pkts[MAX_BURST_SIZE];
struct rte_crypto_op *cop[MAX_BURST_SIZE];
struct rte_pdcp_group grp[MAX_BURST_SIZE];
struct rte_pdcp_entity *pdcp_entity;
int nb_max_out_mb, ret, nb_grp;
/* Create PDCP entity */
pdcp_entity = rte_pdcp_entity_establish(&conf);
/**
* Allocate buffer for holding mbufs returned during PDCP suspend,
* release & post-process APIs.
*/
/* Max packets that can be cached in entity + burst size */
nb_max_out_mb = pdcp_entity->max_pkt_cache + 1;
out_mb = rte_malloc(NULL, nb_max_out_mb * sizeof(uintptr_t), 0);
if (out_mb == NULL) {
/* Handle error */
}
while (1) {
/* Receive packet and form mbuf */
/**
* Prepare packets for crypto operation. Following operations
* would be done,
*
* Transmitting entity/UL (only data PDUs):
* - Perform compression
* - Assign sequence number
* - Add PDCP header
* - Create & prepare crypto_op
* - Prepare IV for crypto operation (auth_gen, encrypt)
* - Save original PDCP SDU (during PDCP re-establishment,
* unconfirmed PDCP SDUs need to crypto processed again and
* transmitted/re-transmitted)
*
* Receiving entity/DL:
* - Any control PDUs received would be processed and
* appropriate actions taken. If data PDU, continue.
* - Determine sequence number (based on HFN & per packet SN)
* - Prepare crypto_op
* - Prepare IV for crypto operation (decrypt, auth_verify)
*/
nb_success = rte_pdcp_pkt_pre_process(pdcp_entity, pkts, cop,
nb_rx, &nb_err);
if (nb_err != 0) {
/* Handle error packets */
}
if ((rte_cryptodev_enqueue_burst(dev_id, qp_id, cop, nb_success)
!= nb_success) {
/* Retry for enqueue failure packets */
}
...
ret = rte_cryptodev_dequeue_burst(dev_id, qp_id, cop,
MAX_BURST_SIZE);
if (ret == 0)
continue;
/**
* Received a burst of completed crypto ops from cryptodev. It
* may belong to various entities. Group similar ones together
* for entity specific post-processing.
*/
/**
* Groups similar entities together. Frees crypto op and based
* on crypto_op status, set mbuf->ol_flags which would be
* checked in rte_pdcp_pkt_post_process().
*/
nb_grp = rte_pdcp_pkt_crypto_group(cop, pkts, grp, ret);
for (i = 0; i != nb_grp; i++) {
/**
* Post process packets after crypto completion.
* Following operations would be done,
*
* Transmitting entity/UL:
* - Check crypto result
*
* Receiving entity/DL:
* - Check crypto operation status
* - Check for duplication (if yes, drop duplicate)
* - Perform decompression
* - Trim PDCP header
* - Hold packet (SDU) for in-order delivery (return
* completed packets as and when sequence is
* completed)
* - If not in sequence, cache the packet and start
* t-Reordering timer. When timer expires, the
* packets need to delivered to upper layers (not
* treated as error packets).
*/
nb_success = rte_pdcp_pkt_post_process(grp[i].id.ptr,
grp[i].m, out_mb,
grp[i].cnt,
&nb_err);
if (nb_err != 0) {
/* Handle error packets */
}
/* Perform additional operations */
/**
* Tranmitting entity/UL
* - If duplication is enabled, duplicate PDCP PDUs
* - When lower layers confirm reception of a PDCP PDU,
* it should be communicated to PDCP layer so that
* PDCP can drop the corresponding SDU
*/
}
}Anoob Joseph (3):
lib: add pdcp protocol
app/test: add lib pdcp tests
doc: add PDCP library guide
Volodymyr Fialko (2):
net: add PDCP header
app/test: pdcp HFN tests in combined mode
app/test/meson.build | 1 + app/test/test_cryptodev.h | 3 + app/test/test_pdcp.c | 999 ++++++++++++++ doc/api/doxy-api-index.md | 4 +- doc/api/doxy-api.conf.in | 1 + .../img/pdcp_functional_overview.svg | 1 + doc/guides/prog_guide/index.rst | 1 + doc/guides/prog_guide/pdcp_lib.rst | 211 +++ lib/meson.build | 1 + lib/net/meson.build | 1 + lib/net/rte_pdcp_hdr.h | 93 ++ lib/pdcp/meson.build | 8 + lib/pdcp/pdcp_crypto.c | 240 ++++ lib/pdcp/pdcp_crypto.h | 20 + lib/pdcp/pdcp_entity.h | 218 +++ lib/pdcp/pdcp_process.c | 1195 +++++++++++++++++ lib/pdcp/pdcp_process.h | 13 + lib/pdcp/rte_pdcp.c | 136 ++ lib/pdcp/rte_pdcp.h | 263 ++++ lib/pdcp/rte_pdcp_group.h | 133 ++ lib/pdcp/version.map | 13 + 21 files changed, 3554 insertions(+), 1 deletion(-) create mode 100644 app/test/test_pdcp.c create mode 100644 doc/guides/prog_guide/img/pdcp_functional_overview.svg create mode 100644 doc/guides/prog_guide/pdcp_lib.rst create mode 100644 lib/net/rte_pdcp_hdr.h create mode 100644 lib/pdcp/meson.build create mode 100644 lib/pdcp/pdcp_crypto.c create mode 100644 lib/pdcp/pdcp_crypto.h create mode 100644 lib/pdcp/pdcp_entity.h create mode 100644 lib/pdcp/pdcp_process.c create mode 100644 lib/pdcp/pdcp_process.h create mode 100644 lib/pdcp/rte_pdcp.c create mode 100644 lib/pdcp/rte_pdcp.h create mode 100644 lib/pdcp/rte_pdcp_group.h create mode 100644 lib/pdcp/version.map
Signature · 1 line
2.25.1
PATCH 1/5 net: add PDCP header
From: Volodymyr Fialko <[email protected]>
Added PDCP protocol header to be used for supporting PDCP protocol processing.
--- doc/api/doxy-api-index.md | 3 +- lib/net/meson.build | 1 + lib/net/rte_pdcp_hdr.h | 93 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 lib/net/rte_pdcp_hdr.h
doc/api/doxy-api-index.md +2 -1
@@ -125,7 +125,8 @@ The public API headers are grouped by topics: [Geneve](@ref rte_geneve.h), [eCPRI](@ref rte_ecpri.h), [L2TPv2](@ref rte_l2tpv2.h), - [PPP](@ref rte_ppp.h) + [PPP](@ref rte_ppp.h), + [PDCP hdr](@ref rte_pdcp_hdr.h) - **QoS**: [metering](@ref rte_meter.h),
lib/net/meson.build +1 -0
@@ -22,6 +22,7 @@ headers = files( 'rte_geneve.h', 'rte_l2tpv2.h', 'rte_ppp.h', + 'rte_pdcp_hdr.h', ) sources = files(
lib/net/rte_pdcp_hdr.h new file +93 -0
93 lines not on this page · raw message
Signature · 1 line
2.25.1
Re: [PATCH 1/5] net: add PDCP header
22/12/2022 10:25, Anoob Joseph:
lib/net/rte_pdcp_hdr.h line 6
Quoted 9 lines
lib/net/rte_pdcp_hdr.h new file +6
-0@@ -0,0 +1,93 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2022 Marvell. +*/ + +#ifndef _RTE_PDCP_HDR_H_ +#define _RTE_PDCP_HDR_H_
No need of extra underscores before and after.
Sorry I cannot review the rest of this, it is out of my knowledge :)
RE: [EXT] Re: [PATCH 1/5] net: add PDCP header
Hi Thomas,
Please see inline.
Thanks,
Anoob
Quoted 6 lines
Subject: [EXT] Re: [PATCH 1/5] net: add PDCP header
External Email
----------------------------------------------------------------------
22/12/2022 10:25, Anoob Joseph:
Quoted 11 lines
lib/net/rte_pdcp_hdr.h line 6
Quoted 9 lines
lib/net/rte_pdcp_hdr.h new file +6
-0@@ -0,0 +1,93 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2022 Marvell. +*/ + +#ifndef _RTE_PDCP_HDR_H_ +#define _RTE_PDCP_HDR_H_No need of extra underscores before and after.
[Anoob] I was following the example quoted in https://doc.dpdk.org/guides/contributing/coding_style.html. Also, other files such as rte_esp.h, rte_udp.h, etc. follow the same.
Isn't it better to have a uniform coding style?
Re: [EXT] Re: [PATCH 1/5] net: add PDCP header
18/01/2023 18:39, Anoob Joseph:
Quoted 13 lines
Quoted 12 lines
22/12/2022 10:25, Anoob Joseph:
lib/net/rte_pdcp_hdr.h line 6
Quoted 9 lines
lib/net/rte_pdcp_hdr.h new file +6
-0@@ -0,0 +1,93 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2022 Marvell. +*/ + +#ifndef _RTE_PDCP_HDR_H_ +#define _RTE_PDCP_HDR_H_No need of extra underscores before and after.
Quoted 1 line
[Anoob] I was following the example quoted in https://doc.dpdk.org/guides/contributing/coding_style.html.
Oh thanks for the reference, I will fix it.
Quoted 1 line
Also, other files such as
rte_esp.h,rte_udp.h, etc. follow the same.
Some other files don't have underscores.
Quoted 1 line
Isn't it better to have a uniform coding style?
No really I prefer no underscores,
they are supposed to be used for standard libraries.
RE: [EXT] Re: [PATCH 1/5] net: add PDCP header
Hi Thomas,
Please see inline.
Thanks,
Anoob
Quoted 26 lines
Subject: Re: [EXT] Re: [PATCH 1/5] net: add PDCP header
18/01/2023 18:39, Anoob Joseph:
Quoted 13 lines
Quoted 12 lines
22/12/2022 10:25, Anoob Joseph:
lib/net/rte_pdcp_hdr.h line 6
Quoted 9 lines
lib/net/rte_pdcp_hdr.h new file +6
-0@@ -0,0 +1,93 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2022 Marvell. +*/ + +#ifndef _RTE_PDCP_HDR_H_ +#define _RTE_PDCP_HDR_H_No need of extra underscores before and after.
Quoted 1 line
[Anoob] I was following the example quoted in
https://urldefense.proofpoint.com/v2/url?u=https-
3A__doc.dpdk.org_guides_contributing_coding- 5Fstyle.html&d=DwICAg&c=nKjWec2b6R0mOyPaz7xtfQ&r=jPfB8rwwviRSxyL Ws2n6B-WYLn1v9SyTMrT5EQqh2TU&m=Btr0wWqHo_dHGchyRWTnjO6xY- 7p33pUSKSBLIXtL4DOAv-GsZmL2lZ2OHyJWoiZ&s=- AQhSWF0bWFXTyxL0rPCW6fz6I7GYhwyQ9qjYG3FFn0&e= .Oh thanks for the reference, I will fix it.
Quoted 8 lines
Quoted 1 line
Also, other files such as
rte_esp.h,rte_udp.h, etc. follow the same.Some other files don't have underscores.
Quoted 1 line
Isn't it better to have a uniform coding style?
No really I prefer no underscores,
they are supposed to be used for standard libraries.
[Anoob] I see that most of the files do have underscores. While I do not have any personal preference, I would really prefer new code to not stand out from the rest. If you have considered this already, then I'll make the change in next version. Please confirm.
Re: [EXT] Re: [PATCH 1/5] net: add PDCP header
23/01/2023 10:21, Anoob Joseph:
Quoted 35 lines
Hi Thomas,
Please see inline.
Thanks,
AnoobQuoted 28 lines
Subject: Re: [EXT] Re: [PATCH 1/5] net: add PDCP header
18/01/2023 18:39, Anoob Joseph:
Quoted 13 lines
Quoted 12 lines
22/12/2022 10:25, Anoob Joseph:
lib/net/rte_pdcp_hdr.h line 6
Quoted 9 lines
lib/net/rte_pdcp_hdr.h new file +6
-0@@ -0,0 +1,93 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2022 Marvell. +*/ + +#ifndef _RTE_PDCP_HDR_H_ +#define _RTE_PDCP_HDR_H_No need of extra underscores before and after.
Quoted 1 line
[Anoob] I was following the example quoted in
https://urldefense.proofpoint.com/v2/url?u=https-
3A__doc.dpdk.org_guides_contributing_coding- 5Fstyle.html&d=DwICAg&c=nKjWec2b6R0mOyPaz7xtfQ&r=jPfB8rwwviRSxyL Ws2n6B-WYLn1v9SyTMrT5EQqh2TU&m=Btr0wWqHo_dHGchyRWTnjO6xY- 7p33pUSKSBLIXtL4DOAv-GsZmL2lZ2OHyJWoiZ&s=- AQhSWF0bWFXTyxL0rPCW6fz6I7GYhwyQ9qjYG3FFn0&e= .Oh thanks for the reference, I will fix it.
Quoted 1 line
Also, other files such as
rte_esp.h,rte_udp.h, etc. follow the same.
Quoted 8 lines
Quoted 6 lines
Some other files don't have underscores.
Quoted 1 line
Isn't it better to have a uniform coding style?
No really I prefer no underscores,
they are supposed to be used for standard libraries.[Anoob] I see that most of the files do have underscores. While I do not have any personal preference, I would really prefer new code to not stand out from the rest. If you have considered this already, then I'll make the change in next version. Please confirm.
I prefer no underscore, and I will probably propose to change all files while updating the contributing guide.
For new patch, I gave my opinion, now you can choose it is not a big deal.
PATCH 2/5 lib: add pdcp protocol
In reply to Anoob JosephAdd Packet Data Convergence Protocol (PDCP) processing library.
The library is similar to lib_ipsec which provides IPsec processing capabilities in DPDK.
PDCP would involve roughly the following options,
1. Transfer of user plane data
2. Transfer of control plane data
3. Header compression
4. Uplink data compression
5. Ciphering and integrity protection
PDCP library provides following control path APIs that is used to configure various PDCP entities,
1. rte_pdcp_entity_establish()
2. rte_pdcp_entity_suspend()
3. rte_pdcp_entity_release()
PDCP process is split into 2 parts. One before crypto processing (rte_pdcp_pkt_pre_process()) and one after crypto processing (rte_pdcp_pkt_post_process()). Since cryptodev dequeue can return crypto operations belonging to multiple entities, rte_pdcp_pkt_crypto_group() is added to help grouping crypto operations belonging to same entity.
--- doc/api/doxy-api-index.md | 3 +- doc/api/doxy-api.conf.in | 1 + lib/meson.build | 1 + lib/pdcp/meson.build | 8 + lib/pdcp/pdcp_crypto.c | 240 ++++++++ lib/pdcp/pdcp_crypto.h | 20 + lib/pdcp/pdcp_entity.h | 218 +++++++ lib/pdcp/pdcp_process.c | 1195 +++++++++++++++++++++++++++++++++++++ lib/pdcp/pdcp_process.h | 13 + lib/pdcp/rte_pdcp.c | 136 +++++ lib/pdcp/rte_pdcp.h | 263 ++++++++ lib/pdcp/rte_pdcp_group.h | 133 +++++ lib/pdcp/version.map | 13 + 13 files changed, 2243 insertions(+), 1 deletion(-) create mode 100644 lib/pdcp/meson.build create mode 100644 lib/pdcp/pdcp_crypto.c create mode 100644 lib/pdcp/pdcp_crypto.h create mode 100644 lib/pdcp/pdcp_entity.h create mode 100644 lib/pdcp/pdcp_process.c create mode 100644 lib/pdcp/pdcp_process.h create mode 100644 lib/pdcp/rte_pdcp.c create mode 100644 lib/pdcp/rte_pdcp.h create mode 100644 lib/pdcp/rte_pdcp_group.h create mode 100644 lib/pdcp/version.map
doc/api/doxy-api-index.md +2 -1
@@ -126,7 +126,8 @@ The public API headers are grouped by topics: [eCPRI](@ref rte_ecpri.h), [L2TPv2](@ref rte_l2tpv2.h), [PPP](@ref rte_ppp.h), - [PDCP hdr](@ref rte_pdcp_hdr.h) + [PDCP hdr](@ref rte_pdcp_hdr.h), + [PDCP](@ref rte_pdcp.h), - **QoS**: [metering](@ref rte_meter.h),
doc/api/doxy-api.conf.in +1 -0
@@ -61,6 +61,7 @@ INPUT = @TOPDIR@/doc/api/doxy-api-index.md \ @TOPDIR@/lib/net \ @TOPDIR@/lib/pcapng \ @TOPDIR@/lib/pci \ + @TOPDIR@/lib/pdcp \ @TOPDIR@/lib/pdump \ @TOPDIR@/lib/pipeline \ @TOPDIR@/lib/port \
lib/meson.build +1 -0
@@ -63,6 +63,7 @@ libraries = [ 'flow_classify', # flow_classify lib depends on pkt framework table lib 'graph', 'node', + 'pdcp', # pdcp lib depends on crypto and security ] optional_libs = [
lib/pdcp/meson.build new file +8 -0
@@ -0,0 +1,8 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(C) 2022 Marvell. +# + +sources = files('pdcp_crypto.c', 'pdcp_process.c', 'rte_pdcp.c') +headers = files('rte_pdcp.h') + +deps += ['security']
lib/pdcp/pdcp_crypto.c new file +240 -0
240 lines not on this page · raw message
lib/pdcp/pdcp_crypto.h new file +20 -0
@@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2022 Marvell. +*/ + +#ifndef _PDCP_CRYPTO_H_ +#define _PDCP_CRYPTO_H_ + +#include <rte_crypto.h> +#include <rte_crypto_sym.h> +#include <rte_pdcp.h> + +#define PDCP_IV_OFFSET (sizeof(struct rte_crypto_op) + sizeof(struct rte_crypto_sym_op)) +#define PDCP_IV_LENGTH 16 + +int pdcp_crypto_sess_create (struct rte_pdcp_entity *entity, +const struct rte_pdcp_entity_conf *conf); + +int pdcp_crypto_sess_destroy (struct rte_pdcp_entity *entity); + +#endif /* _PDCP_CRYPTO_H_ */
lib/pdcp/pdcp_entity.h new file +218 -0
218 lines not on this page · raw message
lib/pdcp/pdcp_process.c new file +1195 -0
1,195 lines not on this page · raw message
lib/pdcp/pdcp_process.h new file +13 -0
@@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2022 Marvell. +*/ + +#ifndef _PDCP_PROCESS_H_ +#define _PDCP_PROCESS_H_ + +#include <rte_pdcp.h> + +int +pdcp_process_func_set (struct rte_pdcp_entity *entity,const struct rte_pdcp_entity_conf *conf); + +#endif /* _PDCP_PROCESS_H_ */
lib/pdcp/rte_pdcp.c new file +136 -0
136 lines not on this page · raw message
lib/pdcp/rte_pdcp.h new file +263 -0
263 lines not on this page · raw message
lib/pdcp/rte_pdcp_group.h new file +133 -0
133 lines not on this page · raw message
lib/pdcp/version.map new file +13 -0
@@ -0,0 +1,13 @@ +EXPERIMENTAL { + global: + + # added in 22.11 + rte_pdcp_entity_establish; + rte_pdcp_entity_release; + rte_pdcp_entity_suspend; + + rte_pdcp_pkt_post_process; + rte_pdcp_pkt_pre_process; + + local: *; +};
Signature · 1 line
2.25.1
Hi Anoob,
Please see inline comments.
Quoted 100 lines
Subject: [PATCH 2/5] lib: add pdcp protocol
Add Packet Data Convergence Protocol (PDCP) processing library.
The library is similar to
lib_ipsecwhich provides IPsec processing capabilities in DPDK.PDCP would involve roughly the following options,
1. Transfer of user plane data
2. Transfer of control plane data
3. Header compression
4. Uplink data compression
5. Ciphering and integrity protectionPDCP library provides following control path APIs that is used to configure various PDCP entities,
1.rte_pdcp_entity_establish()
2.rte_pdcp_entity_suspend()
3.rte_pdcp_entity_release()PDCP process is split into 2 parts. One before crypto processing (
rte_pdcp_pkt_pre_process()) and one after crypto processing (rte_pdcp_pkt_post_process()). Since cryptodev dequeue can return crypto operations belonging to multiple entities,rte_pdcp_pkt_crypto_group()is added to help grouping crypto operations belonging to same entity.Signed-off-by Anoob Joseph <[email protected]>Signed-off-by Kiran Kumar K <[email protected]>Signed-off-by Volodymyr Fialko <[email protected]>--- doc/api/doxy-api-index.md | 3 +- doc/api/doxy-api.conf.in | 1 + lib/meson.build | 1 + lib/pdcp/meson.build | 8 + lib/pdcp/pdcp_crypto.c | 240 ++++++++ lib/pdcp/pdcp_crypto.h | 20 + lib/pdcp/pdcp_entity.h | 218 +++++++ lib/pdcp/pdcp_process.c | 1195 +++++++++++++++++++++++++++++++++++++ lib/pdcp/pdcp_process.h | 13 + lib/pdcp/rte_pdcp.c | 136 +++++ lib/pdcp/rte_pdcp.h | 263 ++++++++ lib/pdcp/rte_pdcp_group.h | 133 +++++ lib/pdcp/version.map | 13 + 13 files changed, 2243 insertions(+), 1 deletion(-) create mode 100644 lib/pdcp/meson.build create mode 100644 lib/pdcp/pdcp_crypto.c create mode 100644 lib/pdcp/pdcp_crypto.h create mode 100644 lib/pdcp/pdcp_entity.h create mode 100644 lib/pdcp/pdcp_process.c create mode 100644 lib/pdcp/pdcp_process.h create mode 100644 lib/pdcp/rte_pdcp.c create mode 100644 lib/pdcp/rte_pdcp.h create mode 100644 lib/pdcp/rte_pdcp_group.h create mode 100644 lib/pdcp/version.mapdoc/api/doxy-api-index.md +2
-1@@ -126,7 +126,8 @@ The public API headers are grouped by topics: [eCPRI](@ref rte_ecpri.h), [L2TPv2](@ref rte_l2tpv2.h), [PPP](@ref rte_ppp.h), - [PDCP hdr](@ref rte_pdcp_hdr.h) + [PDCP hdr](@ref rte_pdcp_hdr.h), + [PDCP](@ref rte_pdcp.h), - **QoS**: [metering](@ref rte_meter.h),doc/api/doxy-api.conf.in +1
-0@@ -61,6 +61,7 @@ INPUT = @TOPDIR@/doc/api/doxy-api- index.md \ @TOPDIR@/lib/net \ @TOPDIR@/lib/pcapng \ @TOPDIR@/lib/pci \ + @TOPDIR@/lib/pdcp \ @TOPDIR@/lib/pdump \ @TOPDIR@/lib/pipeline \@TOPDIR@/lib/port \lib/meson.build +1
-0@@ -63,6 +63,7 @@ libraries = [ 'flow_classify', # flow_classify lib depends on pkt framework table lib 'graph', 'node', + 'pdcp', # pdcp lib depends on crypto and security ] optional_libs = [lib/pdcp/meson.build new file +0
-0
lib/pdcp/meson.build line 3
Quoted 3 lines
lib/pdcp/meson.build new file +3
-0@@ -0,0 +1,8 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(C) 2022 Marvell. +#
Extra # here.
Do we support compilation on Windows as well?
Check missing here.
lib/pdcp/meson.build line 6
Quoted 3 lines
lib/pdcp/meson.build new file +3
-0+ +sources = files('pdcp_crypto.c', 'pdcp_process.c', 'rte_pdcp.c') +headers = files('rte_pdcp.h')
Do we need to add the indirect header as well for lib/pdcp/rte_pdcp_group.h?
lib/pdcp/meson.build line 8
Quoted 2 lines
lib/pdcp/meson.build new file +2
-0+ +deps += ['security']
Crypto not needed as dependency?
Quoted 143 lines
lib/pdcp/pdcp_crypto.c new file +14
-0@@ -0,0 +1,240 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2022 Marvell. +*/ + +#include <rte_crypto.h> +#include <rte_crypto_sym.h> +#include <rte_cryptodev.h> +#include <rte_pdcp.h> + +#include "pdcp_crypto.h" +#include "pdcp_entity.h" + +static int +pdcp_crypto_caps_cipher_verify(uint8_t dev_id, const struct
rte_crypto_sym_xform*c_xfrm)lib/pdcp/pdcp_crypto.c new file +13
-0+{ +const struct rte_cryptodev_symmetric_capability *cap; +struct rte_cryptodev_sym_capability_idx cap_idx; +int ret; + + cap_idx.type =RTE_CRYPTO_SYM_XFORM_CIPHER ; + cap_idx.algo.cipher = c_xfrm->cipher.algo; + + cap =rte_cryptodev_sym_capability_get (dev_id, &cap_idx); +if (cap ==NULL ) +return -1 ; + + ret = rte_cryptodev_sym_capability_check_cipher(cap, c_xfrm-Quoted 1 line
cipher.key.length,
lib/pdcp/pdcp_crypto.c new file +1
-0+ c_xfrm-Quoted 1 line
cipher.iv.length);
lib/pdcp/pdcp_crypto.c new file +6
-0+ +return ret; +} + +static int +pdcp_crypto_caps_auth_verify(uint8_t dev_id, const struct
rte_crypto_sym_xform*a_xfrm)lib/pdcp/pdcp_crypto.c new file +13
-0+{ +const struct rte_cryptodev_symmetric_capability *cap; +struct rte_cryptodev_sym_capability_idx cap_idx; +int ret; + + cap_idx.type =RTE_CRYPTO_SYM_XFORM_AUTH ; + cap_idx.algo.auth = a_xfrm->auth.algo; + + cap =rte_cryptodev_sym_capability_get (dev_id, &cap_idx); +if (cap ==NULL ) +return -1 ; + + ret = rte_cryptodev_sym_capability_check_auth(cap, a_xfrm-Quoted 1 line
auth.key.length,
lib/pdcp/pdcp_crypto.c new file +1
-0+ a_xfrm-Quoted 1 line
auth.digest_length,
lib/pdcp/pdcp_crypto.c new file +16
-0+ a_xfrm->auth.iv.length); + +return ret; +} + +static int +pdcp_crypto_xfrm_validate (const struct rte_pdcp_entity_conf *conf, +const struct rte_crypto_sym_xform *c_xfrm, +const struct rte_crypto_sym_xform *a_xfrm, +bool is_auth_then_cipher) +{ +uint16_t ciph_iv_len, auth_digest_len, auth_iv_len; +int ret; + +/* +* Uplink means PDCP entity is configured for transmit. Downlink means PDCP entity is
lib/pdcp/pdcp_crypto.c new file +1
-0+* configured for receive. When integrity protection is enabled, PDCP always performs
lib/pdcp/pdcp_crypto.c new file +1
-0+* digest-encrypted or auth-gen-encrypt for uplink (and decrypt-auth- verify for downlink).
lib/pdcp/pdcp_crypto.c new file +1
-0+* So for uplink, crypto chain would be auth-cipher while for downlink it would be
lib/pdcp/pdcp_crypto.c new file +20
-0+* cipher-auth. +* +* When integrity protection is not required, xform would be cipher only. +*/ + +if (c_xfrm ==NULL ) +return -EINVAL ; + + if (conf->pdcp_xfrm.pkt_dir == RTE_SECURITY_PDCP_UPLINK) { + + /* With UPLINK, if auth is enabled, it should be before cipher */ + if (a_xfrm != NULL && !is_auth_then_cipher) + return -EINVAL; + + /* With UPLINK, cipher operation must be encrypt */ + if (c_xfrm->cipher.op != RTE_CRYPTO_CIPHER_OP_ENCRYPT) + return -EINVAL; + + /* With UPLINK, auth operation (if present) must be generate */ + if (a_xfrm != NULL && a_xfrm->auth.op !=
RTE_CRYPTO_AUTH_OP_GENERATE)lib/pdcp/pdcp_crypto.c new file +3
-0+return -EINVAL ; + + }else if (conf->pdcp_xfrm.pkt_dir ==RTE_SECURITY_PDCP_DOWNLINK ){
lib/pdcp/pdcp_crypto.c new file +2
-0+ +/* With DOWNLINK, if auth is enabled, it should be after cipher */
lib/pdcp/pdcp_crypto.c new file +8
-0+if (a_xfrm !=NULL && is_auth_then_cipher) +return -EINVAL ; + +/* With DOWNLINK, cipher operation must be decrypt */ +if (c_xfrm->cipher.op !=RTE_CRYPTO_CIPHER_OP_DECRYPT ) +return -EINVAL ; + +/* With DOWNLINK, auth operation (if present) must be verify */
lib/pdcp/pdcp_crypto.c new file +1
-0+ if (a_xfrm != NULL && a_xfrm->auth.op !=
RTE_CRYPTO_AUTH_OP_VERIFY)lib/pdcp/pdcp_crypto.c new file +21
-0+return -EINVAL ; + + }else { +return -EINVAL ; + } + +if ((c_xfrm->cipher.algo !=RTE_CRYPTO_CIPHER_NULL ) && + (c_xfrm->cipher.algo !=RTE_CRYPTO_CIPHER_AES_CTR ) && + (c_xfrm->cipher.algo !=RTE_CRYPTO_CIPHER_ZUC_EEA3 ) && + (c_xfrm->cipher.algo !=RTE_CRYPTO_CIPHER_SNOW3G_UEA2 )) +return -EINVAL ; + +if (c_xfrm->cipher.algo ==RTE_CRYPTO_CIPHER_NULL ) + ciph_iv_len =0 ; +else + ciph_iv_len =PDCP_IV_LENGTH ; + +if (ciph_iv_len != c_xfrm->cipher.iv.length) +return -EINVAL ; + +if (a_xfrm !=NULL ) {
lib/pdcp/pdcp_crypto.c line 132
Quoted 10 lines
lib/pdcp/pdcp_crypto.c new file +10
-0+if ((a_xfrm->auth.algo !=RTE_CRYPTO_AUTH_NULL ) && + (a_xfrm->auth.algo !=RTE_CRYPTO_AUTH_AES_CMAC ) && + (a_xfrm->auth.algo !=RTE_CRYPTO_AUTH_ZUC_EIA3 ) && + (a_xfrm->auth.algo !=RTE_CRYPTO_AUTH_SNOW3G_UIA2 )) +return -EINVAL ; + +if (a_xfrm->auth.algo ==RTE_CRYPTO_AUTH_NULL ) + auth_digest_len =0 ; +else + auth_digest_len =4 ;
If we have a macro for IV length, why not for digest also?
Moreover, for NULL integrity, digest length is also 4 with all 0s.
Refer Annex D.1 in https://www.etsi.org/deliver/etsi_ts/133500_133599/133501/15.04.00_60/ts_133501v150400p.pdf
Digest len would be 0 only in case of a_xfrm == NULL
Quoted 177 lines
lib/pdcp/pdcp_crypto.c new file +32
-0+ +if (auth_digest_len != a_xfrm->auth.digest_length) +return -EINVAL ; + +if ((a_xfrm->auth.algo ==RTE_CRYPTO_AUTH_ZUC_EIA3 ) || + (a_xfrm->auth.algo ==RTE_CRYPTO_AUTH_SNOW3G_UIA2 )) + auth_iv_len =PDCP_IV_LENGTH ; +else + auth_iv_len =0 ; + +if (a_xfrm->auth.iv.length != auth_iv_len) +return -EINVAL ; + } + +if (!rte_cryptodev_is_valid_dev (conf->dev_id)) +return -EINVAL ; + + ret =pdcp_crypto_caps_cipher_verify (conf->dev_id, c_xfrm); +if (ret) +return -ENOTSUP ; + +if (a_xfrm !=NULL ) { + ret =pdcp_crypto_caps_auth_verify (conf->dev_id, a_xfrm); +if (ret) +return -ENOTSUP ; + } + +return 0 ; +} + +int +pdcp_crypto_sess_create(struct rte_pdcp_entity *entity, const struct
rte_pdcp_entity_conf*conf)lib/pdcp/pdcp_crypto.c new file +18
-0+{ +struct rte_crypto_sym_xform *c_xfrm, *a_xfrm; +struct entity_priv *en_priv; +bool is_auth_then_cipher; +int ret; + +if (entity ==NULL || conf ==NULL || conf->crypto_xfrm ==NULL ) +return -EINVAL ; + + en_priv =entity_priv_get (entity); + + en_priv->dev_id = conf->dev_id; + +if (conf->crypto_xfrm->type ==RTE_CRYPTO_SYM_XFORM_CIPHER ) { + c_xfrm = conf->crypto_xfrm; + a_xfrm = conf->crypto_xfrm->next; + is_auth_then_cipher = false; + } else if (conf->crypto_xfrm->type ==
RTE_CRYPTO_SYM_XFORM_AUTH) {lib/pdcp/pdcp_crypto.c new file +8
-0+ a_xfrm = conf->crypto_xfrm; + c_xfrm = conf->crypto_xfrm->next; + is_auth_then_cipher = true; + }else { +return -EINVAL ; + } + + ret = pdcp_crypto_xfrm_validate(conf, c_xfrm, a_xfrm,
is_auth_then_cipher);lib/pdcp/pdcp_crypto.c new file +14
-0+if (ret) +return ret; + +if (c_xfrm->cipher.algo ==RTE_CRYPTO_CIPHER_NULL ) + c_xfrm->cipher.iv.offset =0 ; +else + c_xfrm->cipher.iv.offset =PDCP_IV_OFFSET ; + +if (a_xfrm !=NULL ) { +if (a_xfrm->auth.algo ==RTE_CRYPTO_AUTH_NULL ) + a_xfrm->auth.iv.offset =0 ; +else +if (c_xfrm->cipher.iv.offset) + a_xfrm->auth.iv.offset = PDCP_IV_OFFSET +
PDCP_IV_LENGTH;lib/pdcp/pdcp_crypto.c new file +8
-0+else + a_xfrm->auth.iv.offset =PDCP_IV_OFFSET ; + } + +if (conf->sess_mpool ==NULL ) +return -EINVAL ; + + en_priv->crypto_sess = rte_cryptodev_sym_session_create(conf-Quoted 1 line
dev_id,conf->crypto_xfrm,lib/pdcp/pdcp_crypto.c new file +1
-0+ conf-Quoted 1 line
sess_mpool);lib/pdcp/pdcp_crypto.c new file +6
-0+if (en_priv->crypto_sess ==NULL ) { +/* API returns positive values as error codes */ +return -rte_errno; + } + + rte_cryptodev_sym_session_opaque_data_set(en_priv->crypto_sess,(uint64_t)entity);
lib/pdcp/pdcp_crypto.c new file +16
-0+ +return 0 ; +} + +int +pdcp_crypto_sess_destroy (struct rte_pdcp_entity *entity) +{ +struct entity_priv *en_priv; + +if (entity ==NULL ) +return -EINVAL ; + + en_priv =entity_priv_get (entity); + +if (en_priv->crypto_sess !=NULL ) { + rte_cryptodev_sym_session_free(en_priv->dev_id, en_priv-Quoted 1 line
crypto_sess);lib/pdcp/pdcp_crypto.c new file +5
-0+ en_priv->crypto_sess =NULL ; + } + +return 0 ; +}lib/pdcp/pdcp_crypto.h new file +12
-0@@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2022 Marvell. +*/ + +#ifndef _PDCP_CRYPTO_H_ +#define _PDCP_CRYPTO_H_ + +#include <rte_crypto.h> +#include <rte_crypto_sym.h> +#include <rte_pdcp.h> + +#define PDCP_IV_OFFSET (sizeof(struct rte_crypto_op) + sizeof(struct
rte_crypto_sym_op))lib/pdcp/pdcp_crypto.h new file +8
-0+#define PDCP_IV_LENGTH 16 + +int pdcp_crypto_sess_create (struct rte_pdcp_entity *entity, +const struct rte_pdcp_entity_conf *conf); + +int pdcp_crypto_sess_destroy (struct rte_pdcp_entity *entity); + +#endif /* _PDCP_CRYPTO_H_ */ lib/pdcp/pdcp_entity.h new file +25
-0@@ -0,0 +1,218 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2022 Marvell. +*/ + +#ifndef _PDCP_ENTITY_H_ +#define _PDCP_ENTITY_H_ + +#include <rte_common.h> +#include <rte_crypto_sym.h> +#include <rte_mempool.h> +#include <rte_pdcp.h> +#include <rte_security.h> + +struct entity_priv ; + +#define PDCP_PDU_HDR_SIZE_SN_12 (RTE_ALIGN_MUL_CEIL(12, 8) / 8) +#define PDCP_PDU_HDR_SIZE_SN_18 (RTE_ALIGN_MUL_CEIL(18, 8) / 8) + +#define PDCP_GET_SN_12_FROM_COUNT (c) ((c) & 0xfff) +#define PDCP_GET_SN_18_FROM_COUNT (c) ((c) & 0x3ffff) + +#define PDCP_GET_HFN_SN_12_FROM_COUNT (c) (((c) >> 12) & 0xfffff) +#define PDCP_GET_HFN_SN_18_FROM_COUNT (c) (((c) >> 18) & 0x3fff) + +#define PDCP_SET_COUNT_FROM_HFN_SN_12 (h, s) ((((h) & 0xfffff) << 12) | ((s)&
0xfff))
+#definePDCP_SET_COUNT_FROM_HFN_SN_18(h, s)((((h) &0x3fff) << 18) | ((s) &0x3ffff))
lib/pdcp/pdcp_entity.h line 35
Quoted 9 lines
lib/pdcp/pdcp_entity.h new file +9
-0+ +#define PDCP_SN_12_WINDOW_SZ 0x800 +#define PDCP_SN_18_WINDOW_SZ 0x20000 + +#define PDCP_SN_12_HFN_MAX ((1 << (32 - 12)) - 1) +#define PDCP_SN_12_HFN_MIN 0 +#define PDCP_SN_18_HFN_MAX ((1 << (32 - 18)) - 1) +#define PDCP_SN_18_HFN_MIN 0 +
Can we have common defines for SN-12 and SN-18 and take SN as parameter? We can have something like this.
#define PDCP_PDU_HDR_SIZE(sn_size) (RTE_ALIGN_MUL_CEIL((sn_size), 8) / 8)
#define PDCP_GET_SN_FROM_COUNT(c, sn_size) ((c) & ((1<<sn_size)-1))
#define PDCP_GET_HFN_FROM_COUNT(c, sn_size) (((c) >> sn_size) & ((1 << (32 - sn_size)) - 1))
#define PDCP_SET_COUNT_FROM_HFN_SN(h, s, sn_size) ((((h) & ((1 << (32 - sn_size)) - 1)) << sn_size) | ((s) & ((1<<sn_size)-1))) #define PDCP_HFN_MAX(sn_size) ((1 << (32 - (sn_size))) - 1)
#define PDCP_HFN_MIN 0
Quoted 79 lines
lib/pdcp/pdcp_entity.h new file +2
-0+/* IV generation function based on the entity configuration */ +typedef void (*iv_gen_t)(struct rte_crypto_op *cop, const struct entity_priv
*en_priv,lib/pdcp/pdcp_entity.h new file +76
-0+ uint32_t count); + +enum pdcp_pdu_type { +PDCP_PDU_TYPE_CTRL =0 , +PDCP_PDU_TYPE_DATA =1 , +}; + +enum pdcp_up_ctrl_pdu_type { +PDCP_UP_CTRL_PDU_TYPE_STATUS_REPORT , +PDCP_UP_CTRL_PDU_TYPE_ROHC_FEEDBACK , +PDCP_UP_CTRL_PDU_TYPE_EHC_FEEDBACK , +PDCP_UP_CRTL_PDU_TYPE_UDC_FEEDBACK +}; + +struct entity_state { +uint32_t rx_next; +uint32_t tx_next; +uint32_t rx_deliv; +uint32_t rx_reord; +}; + +union auth_iv_partial { +/* For AES-CMAC, there is no IV, but message gets prepended */ +struct { +#if RTE_BYTE_ORDER ==RTE_LITTLE_ENDIAN +uint64_t count :32 ; +uint64_t zero_38_39 :2 ; +uint64_t direction :1 ; +uint64_t bearer :5 ; +uint64_t zero_40_63 :24 ; +#else +uint64_t count :32 ; +uint64_t bearer :5 ; +uint64_t direction :1 ; +uint64_t zero_38_39 :2 ; +uint64_t zero_40_63 :24 ; +#endif + } aes_cmac; +struct { +#if RTE_BYTE_ORDER ==RTE_LITTLE_ENDIAN +uint64_t count :32 ; +uint64_t zero_37_39 :3 ; +uint64_t bearer :5 ; +uint64_t zero_40_63 :24 ; + +uint64_t rsvd_65_71 :7 ; +uint64_t direction_64 :1 ; +uint64_t rsvd_72_111 :40 ; +uint64_t rsvd_113_119 :7 ; +uint64_t direction_112 :1 ; +uint64_t rsvd_120_127 :8 ; +#else +uint64_t count :32 ; +uint64_t bearer :5 ; +uint64_t zero_37_39 :3 ; +uint64_t zero_40_63 :24 ; + +uint64_t direction_64 :1 ; +uint64_t rsvd_65_71 :7 ; +uint64_t rsvd_72_111 :40 ; +uint64_t direction_112 :1 ; +uint64_t rsvd_113_119 :7 ; +uint64_t rsvd_120_127 :8 ; +#endif + } zs; +uint64_t u64[2 ]; +}; + +union cipher_iv_partial { +struct { +#if RTE_BYTE_ORDER ==RTE_LITTLE_ENDIAN +uint64_t count :32 ; +uint64_t zero_38_39 :2 ; +uint64_t direction :1 ; +uint64_t bearer :5 ; +uint64_t zero_40_63 :24 ;
lib/pdcp/pdcp_entity.h line 123
Quoted 10 lines
lib/pdcp/pdcp_entity.h new file +10
-0+ +uint64_t zero_64_127; +#else + uint64_t count : 32; + uint64_t bearer : 5; + uint64_t direction : 1; + uint64_t zero_38_39 : 2; + uint64_t zero_40_63 : 24; + +uint64_t zero_64_127;
Can we take zero_64_127 out of #if-else
Quoted 10 lines
lib/pdcp/pdcp_entity.h new file +10
-0+#endif + } aes_ctr; +struct { +#if RTE_BYTE_ORDER ==RTE_LITTLE_ENDIAN +uint64_t count :32 ; +uint64_t zero_38_39 :2 ; +uint64_t direction :1 ; +uint64_t bearer :5 ; +uint64_t zero_40_63 :24 ; +
lib/pdcp/pdcp_entity.h line 143
Quoted 10 lines
lib/pdcp/pdcp_entity.h new file +10
-0+uint64_t rsvd_64_127; +#else + uint64_t count : 32; + uint64_t bearer : 5; + uint64_t direction : 1; + uint64_t zero_38_39 : 2; + uint64_t zero_40_63 : 24; + +uint64_t rsvd_64_127; +#endif
rsvd_64_127 can also be out of #if-else
lib/pdcp/pdcp_entity.h line 149
Quoted 6 lines
lib/pdcp/pdcp_entity.h new file +6
-0+ } zs; +uint64_t u64[2 ]; +}; + +/* +* Layout of PDCP entity: [rte_pdcp_entity] [entity_priv] [entity_dl/ul]
If the layout is fixed, can we have 0 length array in rte_pdcp_entity for entity_priv and in entity_priv for entity_dl/ul. I see that entity_dl/ul are not completely defined. You can define them later when they are supported.
Quoted 2 lines
+ */
+
Extra line
Quoted 62 lines
lib/pdcp/pdcp_entity.h new file +27
-0+struct entity_priv { +/** Crypto sym session. */ +struct rte_cryptodev_sym_session *crypto_sess; +/** Entity specific IV generation function. */ +iv_gen_t iv_gen; +/** Pre-prepared auth IV. */ +union auth_iv_partial auth_iv_part; +/** Pre-prepared cipher IV. */ +union cipher_iv_partial cipher_iv_part; +/** Entity state variables. */ +struct entity_state state; +/** Flags. */ +struct { +/** PDCP PDU has 4 byte MAC-I. */ +uint64_t is_authenticated :1 ; +/** Cipher offset & length in bits. */ +uint64_t is_ciph_in_bits :1 ; +/** Auth offset & length in bits. */ +uint64_t is_auth_in_bits :1 ; +/** Is UL/transmitting PDCP entity */ +uint64_t is_ul_entity :1 ; + } flags; +/** Crypto op pool. */ +struct rte_mempool *cop_pool; +/** PDCP header size. */ +uint8_t hdr_sz; +/** PDCP AAD size. For AES-CMAC, additional message is prepended for the operation. */
lib/pdcp/pdcp_entity.h new file +7
-0+uint8_t aad_sz; +/** Device ID of the device to be used for offload. */ +uint8_t dev_id; +}; + +struct entity_priv_dl_part { +/* TODO - when in-order-delivery is supported, post PDCP packets would need to cached. */
lib/pdcp/pdcp_entity.h new file +6
-0+uint8_t dummy; +}; + +struct entity_priv_ul_part { +/* +* TODO - when re-establish is supported, both plain & post PDCP packets would need to be
lib/pdcp/pdcp_entity.h new file +13
-0+* cached. +*/ +uint8_t dummy; +}; + +static inline struct entity_priv * +entity_priv_get (const struct rte_pdcp_entity *entity) { +return RTE_PTR_ADD (entity,sizeof (struct rte_pdcp_entity )); +} + +static inline struct entity_priv_dl_part * +entity_dl_part_get (const struct rte_pdcp_entity *entity) { + return RTE_PTR_ADD(entity, sizeof(struct rte_pdcp_entity) +
sizeof(struct entity_priv));lib/pdcp/pdcp_entity.h new file +5
-0+} + +static inline struct entity_priv_ul_part * +entity_ul_part_get (const struct rte_pdcp_entity *entity) { + return RTE_PTR_ADD(entity, sizeof(struct rte_pdcp_entity) +
Quoted 2 lines
sizeof(struct entity_priv));
+}
Above inline functions may not be needed also if we have 0 len arrays.
lib/pdcp/pdcp_entity.h line 216
Quoted 6 lines
lib/pdcp/pdcp_entity.h new file +6
-0+ +static inline int +pdcp_hdr_size_get (enum rte_security_pdcp_sn_size sn_size) +{ +return RTE_ALIGN_MUL_CEIL (sn_size,8 ) /8 ; +}
PDCP_PDU_HDR_SIZE is same as this inline function. Can we get away with this one?
Quoted 14 lines
lib/pdcp/pdcp_entity.h new file +2
-0+ +#endif /* _PDCP_ENTITY_H_ */ lib/pdcp/pdcp_process.c new file +6
-0@@ -0,0 +1,1195 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2022 Marvell. +*/ + +#include <rte_crypto.h> +#include <rte_crypto_sym.h>
lib/pdcp/pdcp_process.c line 16
Quoted 10 lines
lib/pdcp/pdcp_process.c new file +10
-0+#include <rte_cryptodev.h> +#include <rte_memcpy.h> +#include <rte_pdcp.h> +#include <rte_pdcp_hdr.h> + +#include "pdcp_crypto.h" +#include "pdcp_entity.h" +#include "pdcp_process.h" + +#define PDCP_MAC_I_LEN 4
Can you define it at same place where PDCP_IV_LENGTH is defined and use this in xform validate.
Quoted 1,531 lines
lib/pdcp/pdcp_process.c new file +23
-0+ +/* Enum of supported algorithms for ciphering */ +enum pdcp_cipher_algo { +PDCP_CIPHER_ALGO_NULL , +PDCP_CIPHER_ALGO_AES , +PDCP_CIPHER_ALGO_ZUC , +PDCP_CIPHER_ALGO_SNOW3G , +PDCP_CIPHER_ALGO_MAX +}; + +/* Enum of supported algorithms for integrity */ +enum pdcp_auth_algo { +PDCP_AUTH_ALGO_NULL , +PDCP_AUTH_ALGO_AES , +PDCP_AUTH_ALGO_ZUC , +PDCP_AUTH_ALGO_SNOW3G , +PDCP_AUTH_ALGO_MAX +}; + +/* IV generation functions based on type of operation (cipher - auth) */ + +static void +pdcp_iv_gen_null_null(struct rte_crypto_op *cop, const struct entity_priv
*en_priv,uint32_tcount)lib/pdcp/pdcp_process.c new file +9
-0+{ +/* No IV required for NULL cipher + NULL auth */ +RTE_SET_USED (cop); +RTE_SET_USED (en_priv); +RTE_SET_USED (count); +} + +static void +pdcp_iv_gen_null_aes_cmac(struct rte_crypto_op *cop, const struct
entity_priv*en_priv,lib/pdcp/pdcp_process.c new file +8
-0+ uint32_t count) +{ +struct rte_crypto_sym_op *op = cop->sym; +struct rte_mbuf *mb = op->m_src; +uint8_t *m_ptr; +uint64_t m; + +/* AES-CMAC requires message to be prepended with info on count etc */
lib/pdcp/pdcp_process.c new file +5
-0+ +/* Prepend by 8 bytes to add custom message */ + m_ptr = (uint8_t *)rte_pktmbuf_prepend (mb,8 ); + + m = en_priv->auth_iv_part.u64[0] |((uint64_t)(rte_cpu_to_be_32(count)));
lib/pdcp/pdcp_process.c new file +6
-0+ +rte_memcpy (m_ptr, &m,8 ); +} + +static void +pdcp_iv_gen_null_zs(struct rte_crypto_op *cop, const struct entity_priv
*en_priv,uint32_tcount)lib/pdcp/pdcp_process.c new file +7
-0+{ +uint64_t iv_u64[2 ]; +uint8_t *iv; + + iv = rte_crypto_op_ctod_offset(cop, uint8_t *, PDCP_IV_OFFSET); + + iv_u64[0] = en_priv->auth_iv_part.u64[0] |((uint64_t)(rte_cpu_to_be_32(count)));
lib/pdcp/pdcp_process.c new file +8
-0+rte_memcpy (iv, &iv_u64[0 ],8 ); + + iv_u64[1 ] = iv_u64[0 ] ^ en_priv->auth_iv_part.u64[1 ]; +rte_memcpy (iv +8 , &iv_u64[1 ],8 ); +} + +static void +pdcp_iv_gen_aes_ctr_null(struct rte_crypto_op *cop, const struct entity_priv
*en_priv,lib/pdcp/pdcp_process.c new file +8
-0+ uint32_t count) +{ +uint64_t iv_u64[2 ]; +uint8_t *iv; + + iv = rte_crypto_op_ctod_offset(cop, uint8_t *, PDCP_IV_OFFSET); + + iv_u64[0] = en_priv->cipher_iv_part.u64[0] |((uint64_t)(rte_cpu_to_be_32(count)));
lib/pdcp/pdcp_process.c new file +6
-0+ iv_u64[1 ] =0 ; +rte_memcpy (iv, iv_u64,16 ); +} + +static void +pdcp_iv_gen_zs_null(struct rte_crypto_op *cop, const struct entity_priv
*en_priv,uint32_tcount)lib/pdcp/pdcp_process.c new file +7
-0+{ +uint64_t iv_u64; +uint8_t *iv; + + iv = rte_crypto_op_ctod_offset(cop, uint8_t *, PDCP_IV_OFFSET); + + iv_u64 = en_priv->cipher_iv_part.u64[0] |((uint64_t)(rte_cpu_to_be_32(count)));
lib/pdcp/pdcp_process.c new file +6
-0+rte_memcpy (iv, &iv_u64,8 ); +rte_memcpy (iv +8 , &iv_u64,8 ); +} + +static void +pdcp_iv_gen_zs_zs(struct rte_crypto_op *cop, const struct entity_priv
*en_priv,uint32_tcount)lib/pdcp/pdcp_process.c new file +8
-0+{ +uint64_t iv_u64[2 ]; +uint8_t *iv; + + iv = rte_crypto_op_ctod_offset(cop, uint8_t *, PDCP_IV_OFFSET); + +/* Generating cipher IV */ + iv_u64[0] = en_priv->cipher_iv_part.u64[0] |((uint64_t)(rte_cpu_to_be_32(count)));
lib/pdcp/pdcp_process.c new file +7
-0+rte_memcpy (iv, &iv_u64[0 ],8 ); +rte_memcpy (iv +8 , &iv_u64[0 ],8 ); + + iv +=PDCP_IV_LENGTH ; + +/* Generating auth IV */ + iv_u64[0] = en_priv->auth_iv_part.u64[0] |((uint64_t)(rte_cpu_to_be_32(count)));
lib/pdcp/pdcp_process.c new file +8
-0+rte_memcpy (iv, &iv_u64[0 ],8 ); + + iv_u64[1 ] = iv_u64[0 ] ^ en_priv->auth_iv_part.u64[1 ]; +rte_memcpy (iv +8 , &iv_u64[1 ],8 ); +} + +static void +pdcp_iv_gen_zs_aes_cmac(struct rte_crypto_op *cop, const struct entity_priv
*en_priv,lib/pdcp/pdcp_process.c new file +10
-0+ uint32_t count) +{ +struct rte_crypto_sym_op *op = cop->sym; +struct rte_mbuf *mb = op->m_src; +uint8_t *m_ptr, *iv; +uint64_t iv_u64[2 ]; +uint64_t m; + + iv = rte_crypto_op_ctod_offset(cop, uint8_t *, PDCP_IV_OFFSET); + iv_u64[0] = en_priv->cipher_iv_part.u64[0] |((uint64_t)(rte_cpu_to_be_32(count)));
lib/pdcp/pdcp_process.c new file +5
-0+rte_memcpy (iv, &iv_u64[0 ],8 ); +rte_memcpy (iv +8 , &iv_u64[0 ],8 ); + + m_ptr = (uint8_t *)rte_pktmbuf_prepend (mb,8 ); + m = en_priv->auth_iv_part.u64[0] |((uint64_t)(rte_cpu_to_be_32(count)));
lib/pdcp/pdcp_process.c new file +5
-0+rte_memcpy (m_ptr, &m,8 ); +} + +static void +pdcp_iv_gen_aes_ctr_aes_cmac(struct rte_crypto_op *cop, const struct
entity_priv*en_priv,lib/pdcp/pdcp_process.c new file +11
-0+ uint32_t count) +{ +struct rte_crypto_sym_op *op = cop->sym; +struct rte_mbuf *mb = op->m_src; +uint8_t *m_ptr, *iv; +uint64_t iv_u64[2 ]; +uint64_t m; + + iv = rte_crypto_op_ctod_offset(cop, uint8_t *, PDCP_IV_OFFSET); + + iv_u64[0] = en_priv->cipher_iv_part.u64[0] |((uint64_t)(rte_cpu_to_be_32(count)));
lib/pdcp/pdcp_process.c new file +5
-0+ iv_u64[1 ] =0 ; +rte_memcpy (iv, iv_u64,PDCP_IV_LENGTH ); + + m_ptr = (uint8_t *)rte_pktmbuf_prepend (mb,8 ); + m = en_priv->auth_iv_part.u64[0] |((uint64_t)(rte_cpu_to_be_32(count)));
lib/pdcp/pdcp_process.c new file +5
-0+rte_memcpy (m_ptr, &m,8 ); +} + +static void +pdcp_iv_gen_aes_ctr_zs(struct rte_crypto_op *cop, const struct entity_priv
*en_priv,uint32_tcount)lib/pdcp/pdcp_process.c new file +7
-0+{ +uint64_t iv_u64[2 ]; +uint8_t *iv; + + iv = rte_crypto_op_ctod_offset(cop, uint8_t *, PDCP_IV_OFFSET); + + iv_u64[0] = en_priv->cipher_iv_part.u64[0] |((uint64_t)(rte_cpu_to_be_32(count)));
lib/pdcp/pdcp_process.c new file +6
-0+ iv_u64[1 ] =0 ; +rte_memcpy (iv, iv_u64,PDCP_IV_LENGTH ); + + iv +=PDCP_IV_LENGTH ; + + iv_u64[0] = en_priv->auth_iv_part.u64[0] |((uint64_t)(rte_cpu_to_be_32(count)));
lib/pdcp/pdcp_process.c new file +8
-0+rte_memcpy (iv, &iv_u64[0 ],8 ); + + iv_u64[1 ] = iv_u64[0 ] ^ en_priv->auth_iv_part.u64[1 ]; +rte_memcpy (iv +8 , &iv_u64[1 ],8 ); +} + +static int +pdcp_crypto_xfrm_get(const struct rte_pdcp_entity_conf *conf, struct
rte_crypto_sym_xform**c_xfrm,lib/pdcp/pdcp_process.c new file +12
-0+ struct rte_crypto_sym_xform **a_xfrm) +{ + *c_xfrm =NULL ; + *a_xfrm =NULL ; + +if (conf->crypto_xfrm ==NULL ) +return -EINVAL ; + +if (conf->crypto_xfrm->type ==RTE_CRYPTO_SYM_XFORM_CIPHER ) { + *c_xfrm = conf->crypto_xfrm; + *a_xfrm = conf->crypto_xfrm->next; + } else if (conf->crypto_xfrm->type ==
RTE_CRYPTO_SYM_XFORM_AUTH) {lib/pdcp/pdcp_process.c new file +11
-0+ *a_xfrm = conf->crypto_xfrm; + *c_xfrm = conf->crypto_xfrm->next; + }else { +return -EINVAL ; + } + +return 0 ; +} + +static int +pdcp_iv_gen_func_set(struct rte_pdcp_entity *entity, const struct
rte_pdcp_entity_conf*conf)lib/pdcp/pdcp_process.c new file +31
-0+{ +struct rte_crypto_sym_xform *c_xfrm, *a_xfrm; +enum rte_security_pdcp_direction direction; +enum pdcp_cipher_algo ciph_algo; +enum pdcp_auth_algo auth_algo; +struct entity_priv *en_priv; +int ret; + + en_priv =entity_priv_get (entity); + + direction = conf->pdcp_xfrm.pkt_dir; +if (conf->reverse_iv_direction) + direction = !direction; + + ret =pdcp_crypto_xfrm_get (conf, &c_xfrm, &a_xfrm); +if (ret) +return ret; + +if (c_xfrm ==NULL ) +return -EINVAL ; + +memset (&en_priv->auth_iv_part,0 ,sizeof (en_priv->auth_iv_part)); +memset (&en_priv->cipher_iv_part,0 ,sizeof (en_priv->cipher_iv_part)); + +switch (c_xfrm->cipher.algo) { +case RTE_CRYPTO_CIPHER_NULL : + ciph_algo =PDCP_CIPHER_ALGO_NULL ; +break ; +case RTE_CRYPTO_CIPHER_AES_CTR : + ciph_algo =PDCP_CIPHER_ALGO_AES ; + en_priv->cipher_iv_part.aes_ctr.bearer = conf-Quoted 1 line
pdcp_xfrm.bearer;
lib/pdcp/pdcp_process.c new file +24
-0+ en_priv->cipher_iv_part.aes_ctr.direction = direction; +break ; +case RTE_CRYPTO_CIPHER_SNOW3G_UEA2 : + ciph_algo =PDCP_CIPHER_ALGO_SNOW3G ; + en_priv->cipher_iv_part.zs.bearer = conf->pdcp_xfrm.bearer; + en_priv->cipher_iv_part.zs.direction = direction; +break ; +case RTE_CRYPTO_CIPHER_ZUC_EEA3 : + ciph_algo =PDCP_CIPHER_ALGO_ZUC ; + en_priv->cipher_iv_part.zs.bearer = conf->pdcp_xfrm.bearer; + en_priv->cipher_iv_part.zs.direction = direction; +break ; +default : +return -ENOTSUP ; + } + +if (a_xfrm !=NULL ) { +switch (a_xfrm->auth.algo) { +case RTE_CRYPTO_AUTH_NULL : + auth_algo =PDCP_AUTH_ALGO_NULL ; +break ; +case RTE_CRYPTO_AUTH_AES_CMAC : + auth_algo =PDCP_AUTH_ALGO_AES ; + en_priv->auth_iv_part.aes_cmac.bearer = conf-Quoted 1 line
pdcp_xfrm.bearer;
lib/pdcp/pdcp_process.c new file +5
-0+ en_priv->auth_iv_part.aes_cmac.direction = direction; +break ; +case RTE_CRYPTO_AUTH_SNOW3G_UIA2 : + auth_algo =PDCP_AUTH_ALGO_SNOW3G ; + en_priv->auth_iv_part.zs.bearer = conf-Quoted 1 line
pdcp_xfrm.bearer;
lib/pdcp/pdcp_process.c new file +6
-0+ en_priv->auth_iv_part.zs.direction_64 = direction; + en_priv->auth_iv_part.zs.direction_112 = direction; +break ; +case RTE_CRYPTO_AUTH_ZUC_EIA3 : + auth_algo =PDCP_AUTH_ALGO_ZUC ; + en_priv->auth_iv_part.zs.bearer = conf-Quoted 1 line
pdcp_xfrm.bearer;
lib/pdcp/pdcp_process.c new file +11
-0+ en_priv->auth_iv_part.zs.direction_64 = direction; + en_priv->auth_iv_part.zs.direction_112 = direction; +break ; +default : +return -ENOTSUP ; + } + }else { + auth_algo =PDCP_AUTH_ALGO_NULL ; + } + + static const iv_gen_tiv_gen_map[PDCP_CIPHER_ALGO_MAX][PDCP_AUTH_ALGO_MAX] = {
lib/pdcp/pdcp_process.c new file +1
-0+ [PDCP_CIPHER_ALGO_NULL][PDCP_AUTH_ALGO_NULL] =
pdcp_iv_gen_null_null,lib/pdcp/pdcp_process.c new file +1
-0+ [PDCP_CIPHER_ALGO_NULL][PDCP_AUTH_ALGO_AES] =
pdcp_iv_gen_null_aes_cmac,lib/pdcp/pdcp_process.c new file +1
-0+ [PDCP_CIPHER_ALGO_NULL][PDCP_AUTH_ALGO_SNOW3G] =
pdcp_iv_gen_null_zs,lib/pdcp/pdcp_process.c new file +1
-0+ [PDCP_CIPHER_ALGO_NULL][PDCP_AUTH_ALGO_ZUC] =
pdcp_iv_gen_null_zs,lib/pdcp/pdcp_process.c new file +2
-0+ + [PDCP_CIPHER_ALGO_AES][PDCP_AUTH_ALGO_NULL] =
pdcp_iv_gen_aes_ctr_null,lib/pdcp/pdcp_process.c new file +1
-0+ [PDCP_CIPHER_ALGO_AES][PDCP_AUTH_ALGO_AES] =
pdcp_iv_gen_aes_ctr_aes_cmac,lib/pdcp/pdcp_process.c new file +1
-0+ [PDCP_CIPHER_ALGO_AES][PDCP_AUTH_ALGO_SNOW3G] =
pdcp_iv_gen_aes_ctr_zs,lib/pdcp/pdcp_process.c new file +1
-0+ [PDCP_CIPHER_ALGO_AES][PDCP_AUTH_ALGO_ZUC] =
pdcp_iv_gen_aes_ctr_zs,lib/pdcp/pdcp_process.c new file +2
-0+ + [PDCP_CIPHER_ALGO_SNOW3G][PDCP_AUTH_ALGO_NULL] =
pdcp_iv_gen_zs_null,lib/pdcp/pdcp_process.c new file +1
-0+ [PDCP_CIPHER_ALGO_SNOW3G][PDCP_AUTH_ALGO_AES] =
pdcp_iv_gen_zs_aes_cmac,
+[PDCP_CIPHER_ALGO_SNOW3G][PDCP_AUTH_ALGO_SNOW3G] =
pdcp_iv_gen_zs_zs,lib/pdcp/pdcp_process.c new file +1
-0+ [PDCP_CIPHER_ALGO_SNOW3G][PDCP_AUTH_ALGO_ZUC] =
pdcp_iv_gen_zs_zs,lib/pdcp/pdcp_process.c new file +2
-0+ + [PDCP_CIPHER_ALGO_ZUC][PDCP_AUTH_ALGO_NULL] =
pdcp_iv_gen_zs_null,lib/pdcp/pdcp_process.c new file +1
-0+ [PDCP_CIPHER_ALGO_ZUC][PDCP_AUTH_ALGO_AES] =
pdcp_iv_gen_zs_aes_cmac,lib/pdcp/pdcp_process.c new file +1
-0+ [PDCP_CIPHER_ALGO_ZUC][PDCP_AUTH_ALGO_SNOW3G] =
pdcp_iv_gen_zs_zs,lib/pdcp/pdcp_process.c new file +1
-0+ [PDCP_CIPHER_ALGO_ZUC][PDCP_AUTH_ALGO_ZUC] =
pdcp_iv_gen_zs_zs,lib/pdcp/pdcp_process.c new file +9
-0+ }; + + en_priv->iv_gen = iv_gen_map[ciph_algo][auth_algo]; + +return 0 ; +} + +static inline void +cop_prepare(const struct entity_priv *en_priv, struct rte_mbuf *mb, struct
rte_crypto_op*cop,lib/pdcp/pdcp_process.c new file +29
-0+ uint8_t data_offset, uint32_t count, const bool is_auth) +{ + const struct rte_crypto_op cop_init = { + .type =RTE_CRYPTO_OP_TYPE_SYMMETRIC , + .status =RTE_CRYPTO_OP_STATUS_NOT_PROCESSED , + .sess_type =RTE_CRYPTO_OP_WITH_SESSION , + }; +struct rte_crypto_sym_op *op; +uint32_t pkt_len; + +const uint8_t ciph_shift =3 * en_priv->flags.is_ciph_in_bits; +const uint8_t auth_shift =3 * en_priv->flags.is_auth_in_bits; + + op = cop->sym; + cop->raw = cop_init.raw; + op->m_src = mb; + op->m_dst = mb; + +/* Set IV */ + en_priv->iv_gen (cop, en_priv, count); + +/* Prepare op */ + pkt_len =rte_pktmbuf_pkt_len (mb); + op->cipher.data.offset = data_offset << ciph_shift; + op->cipher.data.length = (pkt_len - data_offset) << ciph_shift; + +if (is_auth) { + op->auth.data.offset =0 ; + op->auth.data.length = (pkt_len - PDCP_MAC_I_LEN) <<
auth_shift;lib/pdcp/pdcp_process.c new file +1
-0+ op->auth.digest.data = rte_pktmbuf_mtod_offset(mb, uint8_t*,
lib/pdcp/pdcp_process.c new file +1
-0+ (pkt_len -
PDCP_MAC_I_LEN));lib/pdcp/pdcp_process.c new file +7
-0+ } + +__rte_crypto_sym_op_attach_sym_session (op, en_priv->crypto_sess); +} + +static inline bool +pdcp_pre_process_uplane_sn_12_ul_set_sn(struct entity_priv *en_priv, struct
rte_mbuf*mb,lib/pdcp/pdcp_process.c new file +8
-0+ uint32_t *count) +{ +struct rte_pdcp_up_data_pdu_sn_12_hdr *pdu_hdr; +const uint8_t hdr_sz = en_priv->hdr_sz; +uint32_t sn; + +/* Prepend PDU header */ + pdu_hdr = (struct rte_pdcp_up_data_pdu_sn_12_hdr*)rte_pktmbuf_prepend(mb,
hdr_sz);lib/pdcp/pdcp_process.c new file +5
-0+if (unlikely (pdu_hdr ==NULL )) +return false; + +/* Update sequence num in the PDU header */ + *count = __atomic_fetch_add(&en_priv->state.tx_next, 1,
__ATOMIC_RELAXED);lib/pdcp/pdcp_process.c new file +11
-0+ sn =PDCP_GET_SN_12_FROM_COUNT (*count); + + pdu_hdr->d_c =PDCP_PDU_TYPE_DATA ; + pdu_hdr->sn_11_8 = ((sn &0xf00 ) >>8 ); + pdu_hdr->sn_7_0 = (sn &0xff ); + pdu_hdr->r =0 ; +return true; +} + +static uint16_t +pdcp_pre_process_uplane_sn_12_ul(const struct rte_pdcp_entity *entity,struct
rte_mbuf*mb[],lib/pdcp/pdcp_process.c new file +1
-0+ struct rte_crypto_op *cop[], uint16_t num,
uint16_t*nb_err)lib/pdcp/pdcp_process.c new file +9
-0+{ +struct entity_priv *en_priv =entity_priv_get (entity); +uint16_t nb_cop; +uint32_t count; +int i; + +const uint8_t data_offset = en_priv->hdr_sz + en_priv->aad_sz; + + nb_cop = rte_crypto_op_bulk_alloc(en_priv->cop_pool,
RTE_CRYPTO_OP_TYPE_SYMMETRIC, cop,lib/pdcp/pdcp_process.c new file +5
-0+ num); + +if (en_priv->flags.is_authenticated) { +for (i =0 ; i < nb_cop; i++) { + if (unlikely(rte_pktmbuf_append(mb[i],
PDCP_MAC_I_LEN) == NULL))lib/pdcp/pdcp_process.c new file +2
-0+ goto cop_free; + if(unlikely(!pdcp_pre_process_uplane_sn_12_ul_set_sn(en_priv, mb[i], +
&count)))lib/pdcp/pdcp_process.c new file +2
-0+ goto cop_free; + cop_prepare(en_priv, mb[i], cop[i], data_offset, count,true);
lib/pdcp/pdcp_process.c new file +4
-0+ } + }else { +for (i =0 ; i < nb_cop; i++) { + if(unlikely(!pdcp_pre_process_uplane_sn_12_ul_set_sn(en_priv, mb[i], +
&count)))lib/pdcp/pdcp_process.c new file +2
-0+ goto cop_free; + cop_prepare(en_priv, mb[i], cop[i], data_offset, count,false);
lib/pdcp/pdcp_process.c new file +14
-0+ } + } + + *nb_err = num - nb_cop; +return nb_cop; +cop_free: +/* Using mempool API since crypto API is not providing bulk free */ +rte_mempool_put_bulk (en_priv->cop_pool, (void *)&cop[i], nb_cop - i); + *nb_err = num - i; +return i; +} + +static inline bool +pdcp_pre_process_uplane_sn_18_ul_set_sn(struct entity_priv *en_priv, struct
rte_mbuf*mb,lib/pdcp/pdcp_process.c new file +8
-0+ uint32_t *count) +{ +struct rte_pdcp_up_data_pdu_sn_18_hdr *pdu_hdr; +const uint8_t hdr_sz = en_priv->hdr_sz; +uint32_t sn; + +/* Prepend PDU header */ + pdu_hdr = (struct rte_pdcp_up_data_pdu_sn_18_hdr*)rte_pktmbuf_prepend(mb,
hdr_sz);lib/pdcp/pdcp_process.c new file +5
-0+if (unlikely (pdu_hdr ==NULL )) +return false; + +/* Update sequence num in the PDU header */ + *count = __atomic_fetch_add(&en_priv->state.tx_next, 1,
__ATOMIC_RELAXED);lib/pdcp/pdcp_process.c new file +13
-0+ sn =PDCP_GET_SN_18_FROM_COUNT (*count); + + pdu_hdr->d_c =PDCP_PDU_TYPE_DATA ; + pdu_hdr->sn_17_16 = ((sn &0x30000 ) >>16 ); + pdu_hdr->sn_15_8 = ((sn &0xff00 ) >>8 ); + pdu_hdr->sn_7_0 = (sn &0xff ); + pdu_hdr->r =0 ; + +return true; +} + +static inline uint16_t +pdcp_pre_process_uplane_sn_18_ul(const struct rte_pdcp_entity *entity,struct
rte_mbuf*mb[],lib/pdcp/pdcp_process.c new file +1
-0+ struct rte_crypto_op *cop[], uint16_t num,
uint16_t*nb_err)lib/pdcp/pdcp_process.c new file +9
-0+{ +struct entity_priv *en_priv =entity_priv_get (entity); +uint16_t nb_cop; +uint32_t count; +int i; + +const uint8_t data_offset = en_priv->hdr_sz + en_priv->aad_sz; + + nb_cop = rte_crypto_op_bulk_alloc(en_priv->cop_pool,
RTE_CRYPTO_OP_TYPE_SYMMETRIC, cop,lib/pdcp/pdcp_process.c new file +5
-0+ num); + +if (en_priv->flags.is_authenticated) { +for (i =0 ; i < nb_cop; i++) { + if (unlikely(rte_pktmbuf_append(mb[i],
PDCP_MAC_I_LEN) == NULL))lib/pdcp/pdcp_process.c new file +2
-0+ goto cop_free; + if(unlikely(!pdcp_pre_process_uplane_sn_18_ul_set_sn(en_priv, mb[i], +
&count)))lib/pdcp/pdcp_process.c new file +2
-0+ goto cop_free; + cop_prepare(en_priv, mb[i], cop[i], data_offset, count,true);
lib/pdcp/pdcp_process.c new file +4
-0+ } + }else { +for (i =0 ; i < nb_cop; i++) { + if(unlikely(!pdcp_pre_process_uplane_sn_18_ul_set_sn(en_priv, mb[i], +
&count)))lib/pdcp/pdcp_process.c new file +2
-0+ goto cop_free; + cop_prepare(en_priv, mb[i], cop[i], data_offset, count,false);
lib/pdcp/pdcp_process.c new file +15
-0+ } + } + + *nb_err = num - nb_cop; +return nb_cop; + +cop_free: +/* Using mempool API since crypto API is not providing bulk free */ +rte_mempool_put_bulk (en_priv->cop_pool, (void *)&cop[i], nb_cop - i); + *nb_err = num - i; +return i; +} + +static uint16_t +pdcp_pre_process_cplane_sn_12_ul(const struct rte_pdcp_entity *entity,struct
rte_mbuf*mb[],lib/pdcp/pdcp_process.c new file +1
-0+ struct rte_crypto_op *cop[], uint16_t num,
uint16_t*nb_err)lib/pdcp/pdcp_process.c new file +11
-0+{ +struct entity_priv *en_priv =entity_priv_get (entity); +struct rte_pdcp_cp_data_pdu_sn_12_hdr *pdu_hdr; +uint32_t count, sn; +uint16_t nb_cop; +int i; + +const uint8_t hdr_sz = en_priv->hdr_sz; +const uint8_t data_offset = hdr_sz + en_priv->aad_sz; + + nb_cop = rte_crypto_op_bulk_alloc(en_priv->cop_pool,
RTE_CRYPTO_OP_TYPE_SYMMETRIC, cop,lib/pdcp/pdcp_process.c new file +5
-0+ num); + +for (i =0 ; i < nb_cop; i++) { +/* Prepend PDU header */ + pdu_hdr = (struct rte_pdcp_cp_data_pdu_sn_12_hdr*)rte_pktmbuf_prepend(mb[i],
+hdr_sz);lib/pdcp/pdcp_process.c new file +3
-0+if (unlikely (pdu_hdr ==NULL )) + goto cop_free; + if (unlikely(rte_pktmbuf_append(mb[i], PDCP_MAC_I_LEN) ==NULL))
lib/pdcp/pdcp_process.c new file +4
-0+ goto cop_free; + +/* Update sequence number in the PDU header */ + count = __atomic_fetch_add(&en_priv->state.tx_next, 1,
__ATOMIC_RELAXED);lib/pdcp/pdcp_process.c new file +34
-0+ sn =PDCP_GET_SN_12_FROM_COUNT (count); + + pdu_hdr->sn_11_8 = ((sn &0xf00 ) >>8 ); + pdu_hdr->sn_7_0 = (sn &0xff ); + pdu_hdr->r =0 ; + +cop_prepare (en_priv, mb[i], cop[i], data_offset, count, true); + } + + *nb_err = num - nb_cop; +return nb_cop; + +cop_free: +/* Using mempool API since crypto API is not providing bulk free */ +rte_mempool_put_bulk (en_priv->cop_pool, (void *)&cop[i], nb_cop - i); + *nb_err = num - i; +return i; +} + +static uint16_t +pdcp_post_process_uplane_sn_12_ul (const struct rte_pdcp_entity *entity, +struct rte_mbuf *in_mb[], +struct rte_mbuf *out_mb[], +uint16_t num,uint16_t *nb_err_ret) +{ +struct entity_priv *en_priv =entity_priv_get (entity); +const uint32_t hdr_trim_sz = en_priv->aad_sz; +int i, nb_success =0 , nb_err =0 ; +struct rte_mbuf *err_mb[num]; +struct rte_mbuf *mb; + +for (i =0 ; i < num; i++) { + mb = in_mb[i]; + if (unlikely(mb->ol_flags &
RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED)) {lib/pdcp/pdcp_process.c new file +12
-0+ err_mb[nb_err++] = mb; +continue ; + } + +if (hdr_trim_sz) +rte_pktmbuf_adj (mb, hdr_trim_sz); + + out_mb[nb_success++] = mb; + } + +if (unlikely (nb_err !=0 )) + rte_memcpy(&out_mb[nb_success], err_mb, nb_err *
sizeof(struct rte_mbuf *));lib/pdcp/pdcp_process.c new file +20
-0+ + *nb_err_ret = nb_err; +return nb_success; +} + +static uint16_t +pdcp_post_process_uplane_sn_18_ul (const struct rte_pdcp_entity *entity, +struct rte_mbuf *in_mb[], +struct rte_mbuf *out_mb[], +uint16_t num,uint16_t *nb_err_ret) +{ +struct entity_priv *en_priv =entity_priv_get (entity); +const uint32_t hdr_trim_sz = en_priv->aad_sz; +int i, nb_success =0 , nb_err =0 ; +struct rte_mbuf *err_mb[num]; +struct rte_mbuf *mb; + +for (i =0 ; i < num; i++) { + mb = in_mb[i]; + if (unlikely(mb->ol_flags &
RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED)) {lib/pdcp/pdcp_process.c new file +12
-0+ err_mb[nb_err++] = mb; +continue ; + } + +if (hdr_trim_sz) +rte_pktmbuf_adj (mb, hdr_trim_sz); + + out_mb[nb_success++] = mb; + } + +if (unlikely (nb_err !=0 )) + rte_memcpy(&out_mb[nb_success], err_mb, nb_err *
sizeof(struct rte_mbuf *));lib/pdcp/pdcp_process.c new file +19
-0+ + *nb_err_ret = nb_err; +return nb_success; +} + +static uint16_t +pdcp_post_process_cplane_sn_12_ul (const struct rte_pdcp_entity *entity, +struct rte_mbuf *in_mb[], +struct rte_mbuf *out_mb[], +uint16_t num,uint16_t *nb_err_ret) +{ +struct entity_priv *en_priv =entity_priv_get (entity); +const uint32_t hdr_trim_sz = en_priv->aad_sz; +int i, nb_success =0 , nb_err =0 ; +struct rte_mbuf *mb, *err_mb[num]; + +for (i =0 ; i < num; i++) { + mb = in_mb[i]; + if (unlikely(mb->ol_flags &
RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED)) {lib/pdcp/pdcp_process.c new file +12
-0+ err_mb[nb_err++] = mb; +continue ; + } + +if (hdr_trim_sz) +rte_pktmbuf_adj (mb, hdr_trim_sz); + + out_mb[nb_success++] = mb; + } + +if (unlikely (nb_err !=0 )) + rte_memcpy(&out_mb[nb_success], err_mb, nb_err *
sizeof(struct rte_mbuf *));lib/pdcp/pdcp_process.c new file +7
-0+ + *nb_err_ret = nb_err; +return nb_success; +} + +static inline int +pdcp_sn_18_count_get(const struct rte_pdcp_entity *entity, int32_t rsn,
uint32_t*count)lib/pdcp/pdcp_process.c new file +5
-0+{ +struct entity_priv *en_priv =entity_priv_get (entity); +uint32_t rhfn, rx_deliv; + + rx_deliv = __atomic_load_n(&en_priv->state.rx_deliv,
__ATOMIC_RELAXED);lib/pdcp/pdcp_process.c new file +3
-0+ rhfn =PDCP_GET_HFN_SN_18_FROM_COUNT (rx_deliv); + + if (rsn < (int32_t)(PDCP_GET_SN_18_FROM_COUNT(rx_deliv) -
PDCP_SN_18_WINDOW_SZ)) {lib/pdcp/pdcp_process.c new file +4
-0+if (unlikely (rhfn ==PDCP_SN_18_HFN_MAX )) +return -ERANGE ; + rhfn +=1 ; + } else if ((uint32_t)rsn >= (PDCP_GET_SN_18_FROM_COUNT(rx_deliv) +
PDCP_SN_18_WINDOW_SZ)) {lib/pdcp/pdcp_process.c new file +12
-0+if (unlikely (rhfn ==PDCP_SN_18_HFN_MIN )) +return -ERANGE ; + rhfn -=1 ; + } + + *count =PDCP_SET_COUNT_FROM_HFN_SN_18 (rhfn, rsn); + +return 0 ; +} + +static inline int +pdcp_sn_12_count_get(const struct rte_pdcp_entity *entity, int32_t rsn,
uint32_t*count)lib/pdcp/pdcp_process.c new file +5
-0+{ +struct entity_priv *en_priv =entity_priv_get (entity); +uint32_t rhfn, rx_deliv; + + rx_deliv = __atomic_load_n(&en_priv->state.rx_deliv,
__ATOMIC_RELAXED);lib/pdcp/pdcp_process.c new file +3
-0+ rhfn =PDCP_GET_HFN_SN_12_FROM_COUNT (rx_deliv); + + if (rsn < (int32_t)(PDCP_GET_SN_12_FROM_COUNT(rx_deliv) -
PDCP_SN_12_WINDOW_SZ)) {lib/pdcp/pdcp_process.c new file +4
-0+if (unlikely (rhfn ==PDCP_SN_12_HFN_MAX )) +return -ERANGE ; + rhfn +=1 ; + } else if ((uint32_t)rsn >= (PDCP_GET_SN_12_FROM_COUNT(rx_deliv) +
PDCP_SN_12_WINDOW_SZ)) {lib/pdcp/pdcp_process.c new file +12
-0+if (unlikely (rhfn ==PDCP_SN_12_HFN_MIN )) +return -ERANGE ; + rhfn -=1 ; + } + + *count =PDCP_SET_COUNT_FROM_HFN_SN_12 (rhfn, rsn); + +return 0 ; +} + +static inline uint16_t +pdcp_pre_process_uplane_sn_12_dl_flags(const struct rte_pdcp_entity*entity, struct
rte_mbuf*mb[],lib/pdcp/pdcp_process.c new file +1
-0+ struct rte_crypto_op *cop[], uint16_t num,
uint16_t*nb_err,lib/pdcp/pdcp_process.c new file +12
-0+ const bool is_integ_protected) +{ +struct entity_priv *en_priv =entity_priv_get (entity); +struct rte_pdcp_up_data_pdu_sn_12_hdr *pdu_hdr; +uint16_t nb_cop; +int32_t rsn =0 ; +uint32_t count; +int i; + +const uint8_t data_offset = en_priv->hdr_sz + en_priv->aad_sz; + + nb_cop = rte_crypto_op_bulk_alloc(en_priv->cop_pool,
RTE_CRYPTO_OP_TYPE_SYMMETRIC, cop,lib/pdcp/pdcp_process.c new file +5
-0+ num); + +for (i =0 ; i < nb_cop; i++) { + + pdu_hdr = rte_pktmbuf_mtod(mb[i], struct
rte_pdcp_up_data_pdu_sn_12_hdr*);lib/pdcp/pdcp_process.c new file +10
-0+ +/* Check for PDU type */ +if (likely (pdu_hdr->d_c ==PDCP_PDU_TYPE_DATA )) + rsn = ((pdu_hdr->sn_11_8 <<8 ) | (pdu_hdr->sn_7_0)); +else +rte_panic ("TODO: Control PDU not handled" ); + +if (unlikely (pdcp_sn_12_count_get (entity, rsn, &count))) +break ; + cop_prepare(en_priv, mb[i], cop[i], data_offset, count,
is_integ_protected);lib/pdcp/pdcp_process.c new file +9
-0+ } + + *nb_err = num - nb_cop; + +return nb_cop; +} + +static uint16_t +pdcp_pre_process_uplane_sn_12_dl_ip(const struct rte_pdcp_entity *entity,struct
rte_mbuf*mb[],lib/pdcp/pdcp_process.c new file +1
-0+ struct rte_crypto_op *cop[], uint16_t num,
uint16_t*nb_err)lib/pdcp/pdcp_process.c new file +2
-0+{ + return pdcp_pre_process_uplane_sn_12_dl_flags(entity, mb, cop, num,
nb_err, true);lib/pdcp/pdcp_process.c new file +4
-0+} + +static uint16_t +pdcp_pre_process_uplane_sn_12_dl(const struct rte_pdcp_entity *entity,struct
rte_mbuf*mb[],lib/pdcp/pdcp_process.c new file +1
-0+ struct rte_crypto_op *cop[], uint16_t num,
uint16_t*nb_err)lib/pdcp/pdcp_process.c new file +2
-0+{ + return pdcp_pre_process_uplane_sn_12_dl_flags(entity, mb, cop, num,
nb_err, false);lib/pdcp/pdcp_process.c new file +4
-0+} + +static inline uint16_t +pdcp_pre_process_uplane_sn_18_dl_flags(const struct rte_pdcp_entity*entity, struct
rte_mbuf*mb[],lib/pdcp/pdcp_process.c new file +1
-0+ struct rte_crypto_op *cop[], uint16_t num,
uint16_t*nb_err,lib/pdcp/pdcp_process.c new file +11
-0+ const bool is_integ_protected) +{ +struct entity_priv *en_priv =entity_priv_get (entity); +struct rte_pdcp_up_data_pdu_sn_18_hdr *pdu_hdr; +uint16_t nb_cop; +int32_t rsn =0 ; +uint32_t count; +int i; + +const uint8_t data_offset = en_priv->hdr_sz + en_priv->aad_sz; + nb_cop = rte_crypto_op_bulk_alloc(en_priv->cop_pool,
RTE_CRYPTO_OP_TYPE_SYMMETRIC, cop,lib/pdcp/pdcp_process.c new file +4
-0+ num); + +for (i =0 ; i < nb_cop; i++) { + pdu_hdr = rte_pktmbuf_mtod(mb[i], struct
rte_pdcp_up_data_pdu_sn_18_hdr*);lib/pdcp/pdcp_process.c new file +4
-0+ +/* Check for PDU type */ +if (likely (pdu_hdr->d_c ==PDCP_PDU_TYPE_DATA )) + rsn = ((pdu_hdr->sn_17_16 << 16) | (pdu_hdr->sn_15_8<< 8) |
lib/pdcp/pdcp_process.c new file +7
-0+ (pdu_hdr->sn_7_0)); + else + rte_panic("TODO: Control PDU not handled"); + +if (unlikely (pdcp_sn_18_count_get (entity, rsn, &count))) +break ; + cop_prepare(en_priv, mb[i], cop[i], data_offset, count,
is_integ_protected);lib/pdcp/pdcp_process.c new file +9
-0+ } + + *nb_err = num - nb_cop; + +return nb_cop; +} + +static uint16_t +pdcp_pre_process_uplane_sn_18_dl_ip(const struct rte_pdcp_entity *entity,struct
rte_mbuf*mb[],lib/pdcp/pdcp_process.c new file +1
-0+ struct rte_crypto_op *cop[], uint16_t num,
uint16_t*nb_err)lib/pdcp/pdcp_process.c new file +2
-0+{ + return pdcp_pre_process_uplane_sn_18_dl_flags(entity, mb, cop, num,
nb_err, true);lib/pdcp/pdcp_process.c new file +4
-0+} + +static uint16_t +pdcp_pre_process_uplane_sn_18_dl(const struct rte_pdcp_entity *entity,struct
rte_mbuf*mb[],lib/pdcp/pdcp_process.c new file +1
-0+ struct rte_crypto_op *cop[], uint16_t num,
uint16_t*nb_err)lib/pdcp/pdcp_process.c new file +2
-0+{ + return pdcp_pre_process_uplane_sn_18_dl_flags(entity, mb, cop, num,
nb_err, false);lib/pdcp/pdcp_process.c new file +4
-0+} + +static uint16_t +pdcp_pre_process_cplane_sn_12_dl(const struct rte_pdcp_entity *entity,struct
rte_mbuf*mb[],lib/pdcp/pdcp_process.c new file +1
-0+ struct rte_crypto_op *cop[], uint16_t num,
uint16_t*nb_err)lib/pdcp/pdcp_process.c new file +11
-0+{ +struct entity_priv *en_priv =entity_priv_get (entity); +struct rte_pdcp_cp_data_pdu_sn_12_hdr *pdu_hdr; +uint16_t nb_cop; +uint32_t count; +int32_t rsn; +int i; + +const uint8_t data_offset = en_priv->hdr_sz + en_priv->aad_sz; + + nb_cop = rte_crypto_op_bulk_alloc(en_priv->cop_pool,
RTE_CRYPTO_OP_TYPE_SYMMETRIC, cop,lib/pdcp/pdcp_process.c new file +4
-0+ num); + +for (i =0 ; i < nb_cop; i++) { + pdu_hdr = rte_pktmbuf_mtod(mb[i], struct
rte_pdcp_cp_data_pdu_sn_12_hdr*);lib/pdcp/pdcp_process.c new file +17
-0+ rsn = ((pdu_hdr->sn_11_8 <<8 ) | (pdu_hdr->sn_7_0)); +if (unlikely (pdcp_sn_12_count_get (entity, rsn, &count))) +break ; +cop_prepare (en_priv, mb[i], cop[i], data_offset, count, true); + } + + *nb_err = num - nb_cop; +return nb_cop; +} + +static inline bool +pdcp_post_process_update_entity_state(const struct rte_pdcp_entity *entity, + const uint32_t count) +{ + struct entity_priv *en_priv = entity_priv_get(entity); + + if (count < __atomic_load_n(&en_priv->state.rx_deliv,
__ATOMIC_RELAXED))lib/pdcp/pdcp_process.c new file +3
-0+return false; + +/* t-Reordering timer is not supported - SDU will be delivered immediately.
lib/pdcp/pdcp_process.c new file +1
-0+* Update RX_DELIV to the COUNT value of the first PDCP SDU which has not
lib/pdcp/pdcp_process.c new file +3
-0+* been delivered to upper layers +*/ + __atomic_store_n(&en_priv->state.rx_deliv, (count + 1),
__ATOMIC_RELAXED);lib/pdcp/pdcp_process.c new file +2
-0+ + if (count >= __atomic_load_n(&en_priv->state.rx_next,
__ATOMIC_RELAXED))lib/pdcp/pdcp_process.c new file +1
-0+ __atomic_store_n(&en_priv->state.rx_next, (count + 1),
__ATOMIC_RELAXED);lib/pdcp/pdcp_process.c new file +6
-0+ +return true; +} + +static inline uint16_t +pdcp_post_process_uplane_sn_12_dl_flags(const struct rte_pdcp_entity*entity,
lib/pdcp/pdcp_process.c new file +18
-0+struct rte_mbuf *in_mb[], + struct rte_mbuf *out_mb[], + uint16_t num, uint16_t *nb_err_ret, + const bool is_integ_protected) +{ + struct entity_priv *en_priv = entity_priv_get(entity); +struct rte_pdcp_up_data_pdu_sn_12_hdr *pdu_hdr; +int i, nb_success =0 , nb_err =0 , rsn =0 ; +const uint32_t aad_sz = en_priv->aad_sz; +struct rte_mbuf *err_mb[num]; +struct rte_mbuf *mb; +uint32_t count; + +const uint32_t hdr_trim_sz = en_priv->hdr_sz + aad_sz; + +for (i =0 ; i < num; i++) { + mb = in_mb[i]; + if (unlikely(mb->ol_flags &
RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED))lib/pdcp/pdcp_process.c new file +2
-0+ goto error; + pdu_hdr = rte_pktmbuf_mtod_offset(mb, struct
rte_pdcp_up_data_pdu_sn_12_hdr*,lib/pdcp/pdcp_process.c new file +12
-0+ aad_sz); + +/* Check for PDU type */ +if (likely (pdu_hdr->d_c ==PDCP_PDU_TYPE_DATA )) + rsn = ((pdu_hdr->sn_11_8 <<8 ) | (pdu_hdr->sn_7_0)); +else +rte_panic ("Control PDU should not be received" ); + +if (unlikely (pdcp_sn_12_count_get (entity, rsn, &count))) + goto error; + + if (unlikely(!pdcp_post_process_update_entity_state(entity,count)))
lib/pdcp/pdcp_process.c new file +14
-0+ goto error; + +rte_pktmbuf_adj (mb, hdr_trim_sz); +if (is_integ_protected) +rte_pktmbuf_trim (mb,PDCP_MAC_I_LEN ); + out_mb[nb_success++] = mb; +continue ; + +error: + err_mb[nb_err++] = mb; + } + +if (unlikely (nb_err !=0 )) + rte_memcpy(&out_mb[nb_success], err_mb, nb_err *
sizeof(struct rte_mbuf *));lib/pdcp/pdcp_process.c new file +12
-0+ + *nb_err_ret = nb_err; +return nb_success; +} + +static uint16_t +pdcp_post_process_uplane_sn_12_dl_ip (const struct rte_pdcp_entity *entity, +struct rte_mbuf *in_mb[], +struct rte_mbuf *out_mb[], +uint16_t num,uint16_t *nb_err) +{ + return pdcp_post_process_uplane_sn_12_dl_flags(entity, in_mb,
out_mb, num,nb_err, true);lib/pdcp/pdcp_process.c new file +9
-0+} + +static uint16_t +pdcp_post_process_uplane_sn_12_dl (const struct rte_pdcp_entity *entity, +struct rte_mbuf *in_mb[], +struct rte_mbuf *out_mb[], +uint16_t num,uint16_t *nb_err) +{ + return pdcp_post_process_uplane_sn_12_dl_flags(entity, in_mb,
out_mb, num,nb_err, false);lib/pdcp/pdcp_process.c new file +4
-0+} + +static inline uint16_t +pdcp_post_process_uplane_sn_18_dl_flags(const struct rte_pdcp_entity*entity,
lib/pdcp/pdcp_process.c new file +18
-0+struct rte_mbuf *in_mb[], + struct rte_mbuf *out_mb[], + uint16_t num, uint16_t *nb_err_ret, + const bool is_integ_protected) +{ + struct entity_priv *en_priv = entity_priv_get(entity); +struct rte_pdcp_up_data_pdu_sn_18_hdr *pdu_hdr; +const uint32_t aad_sz = en_priv->aad_sz; +int i, nb_success =0 , nb_err =0 ; +struct rte_mbuf *mb, *err_mb[num]; +int32_t rsn =0 ; +uint32_t count; + +const uint32_t hdr_trim_sz = en_priv->hdr_sz + aad_sz; + +for (i =0 ; i < num; i++) { + mb = in_mb[i]; + if (unlikely(mb->ol_flags &
RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED))lib/pdcp/pdcp_process.c new file +3
-0+ goto error; + + pdu_hdr = rte_pktmbuf_mtod_offset(mb, struct
rte_pdcp_up_data_pdu_sn_18_hdr*,lib/pdcp/pdcp_process.c new file +5
-0+ aad_sz); + +/* Check for PDU type */ +if (likely (pdu_hdr->d_c ==PDCP_PDU_TYPE_DATA )) + rsn = ((pdu_hdr->sn_17_16 << 16) | (pdu_hdr->sn_15_8<< 8) |
lib/pdcp/pdcp_process.c new file +8
-0+ (pdu_hdr->sn_7_0)); + else + rte_panic("Control PDU should not be received"); + +if (unlikely (pdcp_sn_18_count_get (entity, rsn, &count))) + goto error; + + if (unlikely(!pdcp_post_process_update_entity_state(entity,count)))
lib/pdcp/pdcp_process.c new file +14
-0+ goto error; + +rte_pktmbuf_adj (mb, hdr_trim_sz); +if (is_integ_protected) +rte_pktmbuf_trim (mb,PDCP_MAC_I_LEN ); + out_mb[nb_success++] = mb; +continue ; + +error: + err_mb[nb_err++] = mb; + } + +if (unlikely (nb_err !=0 )) + rte_memcpy(&out_mb[nb_success], err_mb, nb_err *
sizeof(struct rte_mbuf *));lib/pdcp/pdcp_process.c new file +12
-0+ + *nb_err_ret = nb_err; +return nb_success; +} + +static uint16_t +pdcp_post_process_uplane_sn_18_dl_ip (const struct rte_pdcp_entity *entity, +struct rte_mbuf *in_mb[], +struct rte_mbuf *out_mb[], +uint16_t num,uint16_t *nb_err) +{ + return pdcp_post_process_uplane_sn_18_dl_flags(entity, in_mb,
out_mb, num,nb_err, true);lib/pdcp/pdcp_process.c new file +9
-0+} + +static uint16_t +pdcp_post_process_uplane_sn_18_dl (const struct rte_pdcp_entity *entity, +struct rte_mbuf *in_mb[], +struct rte_mbuf *out_mb[], +uint16_t num,uint16_t *nb_err) +{ + return pdcp_post_process_uplane_sn_18_dl_flags(entity, in_mb,
out_mb, num,nb_err, false);lib/pdcp/pdcp_process.c new file +22
-0+} + +static uint16_t +pdcp_post_process_cplane_sn_12_dl (const struct rte_pdcp_entity *entity, +struct rte_mbuf *in_mb[], +struct rte_mbuf *out_mb[], +uint16_t num,uint16_t *nb_err_ret) +{ +struct entity_priv *en_priv =entity_priv_get (entity); +struct rte_pdcp_cp_data_pdu_sn_12_hdr *pdu_hdr; +const uint32_t aad_sz = en_priv->aad_sz; +int i, nb_success =0 , nb_err =0 ; +struct rte_mbuf *err_mb[num]; +struct rte_mbuf *mb; +uint32_t count; +int32_t rsn; + +const uint32_t hdr_trim_sz = en_priv->hdr_sz + aad_sz; + +for (i =0 ; i < num; i++) { + mb = in_mb[i]; + if (unlikely(mb->ol_flags &
RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED))lib/pdcp/pdcp_process.c new file +3
-0+ goto error; + + pdu_hdr = rte_pktmbuf_mtod_offset(mb, struct
rte_pdcp_cp_data_pdu_sn_12_hdr*,lib/pdcp/pdcp_process.c new file +7
-0+ aad_sz); + rsn = ((pdu_hdr->sn_11_8 <<8 ) | (pdu_hdr->sn_7_0)); + +if (unlikely (pdcp_sn_12_count_get (entity, rsn, &count))) + goto error; + + if (unlikely(!pdcp_post_process_update_entity_state(entity,count)))
lib/pdcp/pdcp_process.c new file +13
-0+ goto error; + +rte_pktmbuf_adj (mb, hdr_trim_sz); +rte_pktmbuf_trim (mb,PDCP_MAC_I_LEN ); + out_mb[nb_success++] = mb; +continue ; + +error: + err_mb[nb_err++] = mb; + } + +if (unlikely (nb_err !=0 )) + rte_memcpy(&out_mb[nb_success], err_mb, nb_err *
sizeof(struct rte_mbuf *));lib/pdcp/pdcp_process.c new file +7
-0+ + *nb_err_ret = nb_err; +return nb_success; +} + +static int +pdcp_pre_process_func_set(struct rte_pdcp_entity *entity, const struct
rte_pdcp_entity_conf*conf)lib/pdcp/pdcp_process.c new file +7
-0+{ +struct entity_priv *en_priv =entity_priv_get (entity); + + entity->pre_process =NULL ; + entity->post_process =NULL ; + + if ((conf->pdcp_xfrm.domain ==
RTE_SECURITY_PDCP_MODE_CONTROL) &&lib/pdcp/pdcp_process.c new file +7
-0+ (conf->pdcp_xfrm.sn_size ==RTE_SECURITY_PDCP_SN_SIZE_12 ) && + (conf->pdcp_xfrm.pkt_dir == RTE_SECURITY_PDCP_UPLINK)) { + entity->pre_process = pdcp_pre_process_cplane_sn_12_ul; + entity->post_process = pdcp_post_process_cplane_sn_12_ul; + } + + if ((conf->pdcp_xfrm.domain ==
RTE_SECURITY_PDCP_MODE_CONTROL) &&lib/pdcp/pdcp_process.c new file +7
-0+ (conf->pdcp_xfrm.sn_size ==RTE_SECURITY_PDCP_SN_SIZE_12 ) && + (conf->pdcp_xfrm.pkt_dir == RTE_SECURITY_PDCP_DOWNLINK)) { + entity->pre_process = pdcp_pre_process_cplane_sn_12_dl; + entity->post_process = pdcp_post_process_cplane_sn_12_dl; + } + + if ((conf->pdcp_xfrm.domain == RTE_SECURITY_PDCP_MODE_DATA)&&
lib/pdcp/pdcp_process.c new file +7
-0+ (conf->pdcp_xfrm.sn_size ==RTE_SECURITY_PDCP_SN_SIZE_12 ) && + (conf->pdcp_xfrm.pkt_dir == RTE_SECURITY_PDCP_UPLINK)) { + entity->pre_process = pdcp_pre_process_uplane_sn_12_ul; + entity->post_process = pdcp_post_process_uplane_sn_12_ul; + } + + if ((conf->pdcp_xfrm.domain == RTE_SECURITY_PDCP_MODE_DATA)&&
lib/pdcp/pdcp_process.c new file +7
-0+ (conf->pdcp_xfrm.sn_size ==RTE_SECURITY_PDCP_SN_SIZE_18 ) && + (conf->pdcp_xfrm.pkt_dir == RTE_SECURITY_PDCP_UPLINK)) { + entity->pre_process = pdcp_pre_process_uplane_sn_18_ul; + entity->post_process = pdcp_post_process_uplane_sn_18_ul; + } + + if ((conf->pdcp_xfrm.domain == RTE_SECURITY_PDCP_MODE_DATA)&&
lib/pdcp/pdcp_process.c new file +5
-0+ (conf->pdcp_xfrm.sn_size ==RTE_SECURITY_PDCP_SN_SIZE_12 ) && + (conf->pdcp_xfrm.pkt_dir ==RTE_SECURITY_PDCP_DOWNLINK ) && + (en_priv->flags.is_authenticated)) { + entity->pre_process = pdcp_pre_process_uplane_sn_12_dl_ip; + entity->post_process =
pdcp_post_process_uplane_sn_12_dl_ip;lib/pdcp/pdcp_process.c new file +3
-0+ } + + if ((conf->pdcp_xfrm.domain == RTE_SECURITY_PDCP_MODE_DATA)&&
lib/pdcp/pdcp_process.c new file +8
-0+ (conf->pdcp_xfrm.sn_size ==RTE_SECURITY_PDCP_SN_SIZE_12 ) && + (conf->pdcp_xfrm.pkt_dir ==RTE_SECURITY_PDCP_DOWNLINK ) && + (!en_priv->flags.is_authenticated)) { + entity->pre_process = pdcp_pre_process_uplane_sn_12_dl; + entity->post_process = pdcp_post_process_uplane_sn_12_dl; + } + + if ((conf->pdcp_xfrm.domain == RTE_SECURITY_PDCP_MODE_DATA)&&
lib/pdcp/pdcp_process.c new file +5
-0+ (conf->pdcp_xfrm.sn_size ==RTE_SECURITY_PDCP_SN_SIZE_18 ) && + (conf->pdcp_xfrm.pkt_dir ==RTE_SECURITY_PDCP_DOWNLINK ) && + (en_priv->flags.is_authenticated)) { + entity->pre_process = pdcp_pre_process_uplane_sn_18_dl_ip; + entity->post_process =
pdcp_post_process_uplane_sn_18_dl_ip;lib/pdcp/pdcp_process.c new file +3
-0+ } + + if ((conf->pdcp_xfrm.domain == RTE_SECURITY_PDCP_MODE_DATA)&&
lib/pdcp/pdcp_process.c new file +15
-0+ (conf->pdcp_xfrm.sn_size ==RTE_SECURITY_PDCP_SN_SIZE_18 ) && + (conf->pdcp_xfrm.pkt_dir ==RTE_SECURITY_PDCP_DOWNLINK ) && + (!en_priv->flags.is_authenticated)) { + entity->pre_process = pdcp_pre_process_uplane_sn_18_dl; + entity->post_process = pdcp_post_process_uplane_sn_18_dl; + } + +if (entity->pre_process ==NULL || entity->post_process ==NULL ) +return -ENOTSUP ; + +return 0 ; +} + +static int +pdcp_entity_priv_populate(struct entity_priv *en_priv, const struct
rte_pdcp_entity_conf*conf)lib/pdcp/pdcp_process.c new file +8
-0+{ +struct rte_crypto_sym_xform *c_xfrm, *a_xfrm; +int ret; + +/** +* flags.is_authenticated +* +* MAC-I would be added in case of control plane packets and when authentication
lib/pdcp/pdcp_process.c new file +4
-0+* transform is not NULL. +*/ + + if (conf->pdcp_xfrm.domain ==
RTE_SECURITY_PDCP_MODE_CONTROL)lib/pdcp/pdcp_process.c new file +13
-0+ en_priv->flags.is_authenticated =1 ; + + ret =pdcp_crypto_xfrm_get (conf, &c_xfrm, &a_xfrm); +if (ret) +return ret; + +if (a_xfrm !=NULL ) + en_priv->flags.is_authenticated =1 ; + +/** +* flags.is_ciph_in_bits +* +* For ZUC & SNOW3G cipher algos, offset & length need to be provided in bits.
lib/pdcp/pdcp_process.c new file +10
-0+*/ + +if ((c_xfrm->cipher.algo ==RTE_CRYPTO_CIPHER_SNOW3G_UEA2 ) || + (c_xfrm->cipher.algo ==RTE_CRYPTO_CIPHER_ZUC_EEA3 )) + en_priv->flags.is_ciph_in_bits =1 ; + +/** +* flags.is_auth_in_bits +* +* For ZUC & SNOW3G authentication algos, offset & length need to be provided in bits.
lib/pdcp/pdcp_process.c new file +4
-0+*/ + +if (a_xfrm !=NULL ) { + if ((a_xfrm->auth.algo == RTE_CRYPTO_AUTH_SNOW3G_UIA2)||
lib/pdcp/pdcp_process.c new file +23
-0+ (a_xfrm->auth.algo == RTE_CRYPTO_AUTH_ZUC_EIA3)) + en_priv->flags.is_auth_in_bits = 1; + } + +/** +* flags.is_ul_entity +* +* Indicate whether the entity is UL/transmitting PDCP entity. +*/ +if (conf->pdcp_xfrm.pkt_dir ==RTE_SECURITY_PDCP_UPLINK ) + en_priv->flags.is_ul_entity =1 ; + +/** +* hdr_sz +* +* PDCP header size of the entity +*/ + en_priv->hdr_sz =pdcp_hdr_size_get (conf->pdcp_xfrm.sn_size); + +/** +* aad_sz +* +* For AES-CMAC, additional message is prepended for processing. Need to be trimmed after
lib/pdcp/pdcp_process.c new file +3
-0+* crypto processing is done. +*/ + if (a_xfrm != NULL && a_xfrm->auth.algo ==
RTE_CRYPTO_AUTH_AES_CMAC)lib/pdcp/pdcp_process.c new file +9
-0+ en_priv->aad_sz =8 ; + else + en_priv->aad_sz = 0; + +return 0 ; +} + +int +pdcp_process_func_set(struct rte_pdcp_entity *entity, const struct
rte_pdcp_entity_conf*conf)lib/pdcp/pdcp_process.c new file +23
-0+{ +struct entity_priv *en_priv; +int ret; + +if (entity ==NULL || conf ==NULL ) +return -EINVAL ; + + en_priv =entity_priv_get (entity); + + ret =pdcp_iv_gen_func_set (entity, conf); +if (ret) +return ret; + + ret =pdcp_entity_priv_populate (en_priv, conf); +if (ret) +return ret; + + ret =pdcp_pre_process_func_set (entity, conf); +if (ret) +return ret; + +return 0 ; +}lib/pdcp/pdcp_process.h new file +11
-0@@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2022 Marvell. +*/ + +#ifndef _PDCP_PROCESS_H_ +#define _PDCP_PROCESS_H_ + +#include <rte_pdcp.h> + +int +pdcp_process_func_set(struct rte_pdcp_entity *entity, const struct
rte_pdcp_entity_conf*conf);lib/pdcp/pdcp_process.h new file +2
-0+ +#endif /* _PDCP_PROCESS_H_ */ lib/pdcp/rte_pdcp.c new file +41
-0@@ -0,0 +1,136 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2022 Marvell. +*/ + +#include <rte_pdcp.h> +#include <rte_malloc.h> + +#include "pdcp_crypto.h" +#include "pdcp_entity.h" +#include "pdcp_process.h" + +static int +pdcp_entity_size_get (const struct rte_pdcp_entity_conf *conf) +{ +int size; + + size =sizeof (struct rte_pdcp_entity ) +sizeof (struct entity_priv ); + +if (conf->pdcp_xfrm.pkt_dir ==RTE_SECURITY_PDCP_DOWNLINK ) + size +=sizeof (struct entity_priv_dl_part ); +else if (conf->pdcp_xfrm.pkt_dir ==RTE_SECURITY_PDCP_UPLINK ) + size +=sizeof (struct entity_priv_ul_part ); +else +return -EINVAL ; + +return RTE_ALIGN_CEIL (size,RTE_CACHE_LINE_SIZE ); +} + +struct rte_pdcp_entity * +rte_pdcp_entity_establish(const struct rte_pdcp_entity_conf *conf) +{ + struct rte_pdcp_entity *entity = NULL; + struct entity_priv *en_priv; + int ret; + + if (conf == NULL || conf->cop_pool == NULL) { + rte_errno = -EINVAL; + return NULL; + } + + if (conf->pdcp_xfrm.en_ordering || conf-Quoted 1 line
pdcp_xfrm.remove_duplicates ||
conf->is_slrb||lib/pdcp/rte_pdcp.c new file +8
-0+ conf->en_sec_offload) { + rte_errno = -ENOTSUP ; +return NULL ; + } + +/* +* 6.3.2 PDCP SN +* Length: 12 or 18 bits as indicated in table 6.3.2-1. The length of the PDCP SN is
lib/pdcp/rte_pdcp.c new file +1
-0+* configured by upper layers (pdcp-SN-SizeUL, pdcp-SN-SizeDL, or sl- PDCP-SN-Size in
lib/pdcp/rte_pdcp.c new file +47
-0+* TS 38.331 [3]) +*/ +if ((conf->pdcp_xfrm.sn_size !=RTE_SECURITY_PDCP_SN_SIZE_12 ) && + (conf->pdcp_xfrm.sn_size !=RTE_SECURITY_PDCP_SN_SIZE_18 )) { + rte_errno = -ENOTSUP ; +return NULL ; + } + +if (conf->pdcp_xfrm.hfn || conf->pdcp_xfrm.hfn_threshold) { + rte_errno = -EINVAL ; +return NULL ; + } + + entity =rte_zmalloc_socket ("pdcp_entity" ,pdcp_entity_size_get (conf), +RTE_CACHE_LINE_SIZE ,SOCKET_ID_ANY ); +if (entity ==NULL ) { + rte_errno = -ENOMEM ; +return NULL ; + } + + en_priv =entity_priv_get (entity); + + en_priv->state.rx_deliv = conf->count; + en_priv->state.tx_next = conf->count; + en_priv->cop_pool = conf->cop_pool; + +/* Setup crypto session */ + ret =pdcp_crypto_sess_create (entity, conf); +if (ret) + goto entity_free; + + ret =pdcp_process_func_set (entity, conf); +if (ret) + goto crypto_sess_destroy; + +return entity; + +crypto_sess_destroy: +pdcp_crypto_sess_destroy (entity); +entity_free: +rte_free (entity); + rte_errno = ret; +return NULL ; +} + +int +rte_pdcp_entity_release(struct rte_pdcp_entity *pdcp_entity, struct rte_mbuf*out_mb[])
lib/pdcp/rte_pdcp.c new file +39
-0+{ +int ret; + +if (pdcp_entity ==NULL ) +return -EINVAL ; + +/* Teardown crypto sessions */ + ret =pdcp_crypto_sess_destroy (pdcp_entity); +if (ret) +return ret; + +rte_free (pdcp_entity); + +RTE_SET_USED (out_mb); +return 0 ; +} + +int +rte_pdcp_entity_suspend (struct rte_pdcp_entity *pdcp_entity, +struct rte_mbuf *out_mb[]) +{ +struct entity_priv *en_priv; + +if (pdcp_entity ==NULL ) +return -EINVAL ; + + en_priv =entity_priv_get (pdcp_entity); + +if (en_priv->flags.is_ul_entity) { + en_priv->state.tx_next =0 ; + }else { + en_priv->state.rx_next =0 ; + en_priv->state.rx_deliv =0 ; + } + +RTE_SET_USED (out_mb); + +return 0 ; +}lib/pdcp/rte_pdcp.h new file +10
-0@@ -0,0 +1,263 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2022 Marvell. +*/ + +#ifndef _RTE_PDCP_H_ +#define _RTE_PDCP_H_ + +/** +* @file rte_pdcp.h +*
lib/pdcp/rte_pdcp.h line 20
Quoted 10 lines
lib/pdcp/rte_pdcp.h new file +10
-0+* RTE PDCP support. +* +* librte_pdcp provides a framework for PDCP protocol processing. +*/ + +#include <rte_compat.h> +#include <rte_common.h> +#include <rte_errno.h> +#include <rte_mempool.h> +#include <rte_security.h>
Remove header file which is not needed.
I do not see use of rte_errno.h
I believe rte_common.h and rte_compat.h are also not needed.
lib/pdcp/rte_pdcp_group.h
Quoted 278 lines
lib/pdcp/rte_pdcp.h new file +69
-0+ +#ifdef __cplusplus +extern "C" { +#endif + +/* Forward declarations */ +struct rte_pdcp_entity ; + +/* PDCP pre-process function based on entity configuration */ +typedef uint16_t (*rte_pdcp_pre_p_t )(const struct rte_pdcp_entity *entity, +struct rte_mbuf *mb[], +struct rte_crypto_op *cop[], +uint16_t num,uint16_t *nb_err); + +/* PDCP post-process function based on entity configuration */ +typedef uint16_t (*rte_pdcp_post_p_t )(const struct rte_pdcp_entity *entity, +struct rte_mbuf *in_mb[], +struct rte_mbuf *out_mb[], +uint16_t num,uint16_t *nb_err); + +/** +* PDCP entity. +*/ +struct rte_pdcp_entity { +/** Entity specific pre-process handle. */ +rte_pdcp_pre_p_t pre_process; +/** Entity specific post-process handle. */ +rte_pdcp_post_p_t post_process; +/** +* PDCP entities may hold packets for purposes of in-order delivery (in +* case of receiving PDCP entity) and re-transmission (in case of +* transmitting PDCP entity). +* +* For receiving PDCP entity, it may hold packets when in-order +* delivery is enabled. The packets would be cached until either a +* packet that completes the sequence arrives or when discard timer +* expires. +* +* When post-processing of PDCP packet which completes a sequence is +* done, the API may return more packets than enqueued. Application is +* expected to provide *rte_pdcp_pkt_post_process()* with *out_mb* +* which can hold maximum number of packets which may be returned. +* +* For transmitting PDCP entity, during re-establishment (5.1.2), +* entity may be required to perform re-transmission of the buffers +* after applying new ciphering & integrity algorithms. For performing +* crypto operation, *rte_pdcp_entity_re_establish()* would return as +* many crypto_ops as the ones cached. +*/ +uint16_t max_pkt_cache; +/** User area for saving application data. */ +uint64_t user_area[2 ]; +} __rte_cache_aligned; + +/** +* PDCP entity configuration to be used for establishing an entity. +*/ +struct rte_pdcp_entity_conf { +/** PDCP transform for the entity. */ +struct rte_security_pdcp_xform pdcp_xfrm; +/** Crypto transform applicable for the entity. */ +struct rte_crypto_sym_xform *crypto_xfrm; +/** Mempool for crypto symmetric session. */ +struct rte_mempool *sess_mpool; +/** Crypto op pool.*/ +struct rte_mempool *cop_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.
lib/pdcp/rte_pdcp.h new file +3
-0+*/ +uint32_t count; +/** Indicate whether the PDCP entity belongs to Side Link Radio Bearer. */
lib/pdcp/rte_pdcp.h new file +8
-0+bool is_slrb; +/** Enable security offload on the device specified. */ +bool en_sec_offload; +/** Enable non-atomic usage of entity. */ +bool en_non_atomic; +/** Device on which security/crypto session need to be created. */ +uint8_t dev_id; +/** Reverse direction during IV generation. Can be used to simulate UE crypto processing.*/
lib/pdcp/rte_pdcp.h new file +38
-0+bool reverse_iv_direction; +}; + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice +* +* 5.1.1 PDCP entity establishment +* +* Establish PDCP entity based on provided input configuration. +* +* @param conf +* Parameters to be used for initializing PDCP entity object. +* @return +* - Valid handle if success +* - NULL in case of failure. rte_errno will be set to error code +*/ +__rte_experimental +struct rte_pdcp_entity * +rte_pdcp_entity_establish (const struct rte_pdcp_entity_conf *conf); + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice +* +* 5.1.3 PDCP entity release +* +* Release PDCP entity. +* +* For UL/transmitting PDCP entity, all stored PDCP SDUs would be dropped. +* For DL/receiving PDCP entity, the stored PDCP SDUs would be returned in +* *out_mb* buffer. The buffer should be large enough to hold all cached +* packets in the entity. +* +* @param pdcp_entity +* Pointer to the PDCP entity to be released. +* @param[out] out_mb +* The address of an array that can hold up to *rte_pdcp_entity.max_pkt_cache*
+ * pointers to *rte_mbuf* structures.
+ * @return+ * - 0: Success and no cached packets to return + * - >0: Success and the number of packets returned in out_mb + * - <0: Error code in case of failures+ */
lib/pdcp/rte_pdcp.h new file +23
-0+__rte_experimental +int +rte_pdcp_entity_release (struct rte_pdcp_entity *pdcp_entity, +struct rte_mbuf *out_mb[]); + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice +* +* 5.1.4 PDCP entity suspend +* +* Suspend PDCP entity. +* +* For DL/receiving PDCP entity, the stored PDCP SDUs would be returned in +* *out_mb* buffer. The buffer should be large enough to hold all cached +* packets in the entity. +* +* For UL/transmitting PDCP entity, *out_mb* buffer would be unused. +* +* @param pdcp_entity +* Pointer to the PDCP entity to be suspended. +* @param[out] out_mb +* The address of an array that can hold up to *rte_pdcp_entity.max_pkt_cache*
+ * pointers to *rte_mbuf* structures.
+ * @return+ * - 0: Success and no cached packets to return + * - >0: Success and the number of packets returned in out_mb + * - <0: Error code in case of failures+ */
lib/pdcp/rte_pdcp.h new file +48
-0+__rte_experimental +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 +* +* For input mbufs and given PDCP entity pre-process the mbufs and prepare +* crypto ops that can be enqueued to the cryptodev associated with given +* session. Only error packets would be moved returned in the input buffer, +* *mb*, and it is the responsibility of the application to free the same. +* +* @param entity +* Pointer to the *rte_pdcp_entity* object the packets belong to. +* @param[in, out] mb +* The address of an array of *num* pointers to *rte_mbuf* structures +* which contain the input packets. Any error packets would be returned in the +* same buffer. +* @param[out] cop +* The address of an array that can hold up to *num* pointers to +* *rte_crypto_op* structures. Crypto ops would be allocated by +* ``rte_pdcp_pkt_pre_process`` API. +* @param num +* The maximum number of packets to process. +* @param[out] nb_err +* Pointer to return the number of error packets returned in *mb* +* @return +* Count of crypto_ops prepared +*/ +__rte_experimental +static inline uint16_t +rte_pdcp_pkt_pre_process (const struct rte_pdcp_entity *entity, +struct rte_mbuf *mb[],struct rte_crypto_op *cop[], +uint16_t num,uint16_t *nb_err) +{ +return entity->pre_process (entity, mb, cop, num, nb_err); +} + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice +* +* For input mbufs and given PDCP entity, perform PDCP post-processing of the +* mbufs. Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
cryptodev
+ * and grouped by *rte_pdcp_pkt_crypto_group()*.
+ *
+ * The post-processed packets would be returned in the *out_mb* buffer.
+ * The resultant mbufs would be grouped into success packets and error packets.
+ * Error packets would be grouped in the end of the array and it is the
+ * responsibility of the application to handle the same.
+ *
+ * When in-order delivery is enabled, PDCP entity may buffer packets and would
+ * deliver packets only when all prior packets have been post-processed. That
+ * would result in returning more/less packets than enqueued.
+ *
+ * @param entity
+ * Pointer to the *rte_pdcp_entity* object the packets belong to.
+ * @paramin_mb
+ * The address of an array of *num* pointers to *rte_mbuf* structures.
+ * @param[out]out_mb
+ * The address of an array of *num* pointers to *rte_mbuf* structures
+ * to output packets after PDCP post-processing.
+ * @param num
+ * The maximum number of packets to process.
+ * @param[out]nb_err
+ * The number of error packets returned in *out_mb* buffer.
+ * @return
+ * Count of packets returned in *out_mb* buffer.
+ */lib/pdcp/rte_pdcp.h new file +17
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
related
+ * packets by sessions they belong to.
+ */lib/pdcp/rte_pdcp_group.h new file +5
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
Remove header files which are not needed.
lib/pdcp/rte_pdcp_group.h
Quoted 37 lines
lib/pdcp/rte_pdcp_group.h new file +37
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
This patchset is not supporting security sessions, so it would be better to return NULL for that. Moreover, we can directly call rte_cryptodev_sym_session_opaque_data_get(cop->sym[0].session) From rte_pdcp_pkt_crypto_group. No need to have a wrapper.
lib/pdcp/version.map
Quoted 89 lines
lib/pdcp/rte_pdcp_group.h new file +6
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
22 lines not shown · raw message
lib/pdcp/rte_pdcp_group.h new file +2
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
1 line not shown · raw message
lib/pdcp/rte_pdcp_group.h new file +13
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
1 line not shown · raw message
lib/pdcp/rte_pdcp_group.h new file +34
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
12 lines not shown · raw message
Parts of this message are not shown here. View the raw message.
Hi Akhil,
Thanks for the review. Please see inline.
Thanks,
Anoob
Quoted 123 lines
-----Original Message-----
From: Akhil Goyal <[email protected]>
Sent: Wednesday, January 18, 2023 9:57 PM
To: Anoob Joseph <[email protected]>; Thomas Monjalon <[email protected]>; Jerin Jacob Kollanukkaran <[email protected]>; Konstantin Ananyev <[email protected]>; Bernard Iremonger <[email protected]>
Cc: Hemant Agrawal <[email protected]>; Mattias Rönnblom <[email protected]>; Kiran Kumar Kokkilagadda <[email protected]>; Volodymyr Fialko <[email protected]>; [email protected]; Olivier Matz <[email protected]>
Subject: RE: [PATCH 2/5] lib: add pdcp protocolHi Anoob,
Please see inline comments.
Quoted 20 lines
Subject: [PATCH 2/5] lib: add pdcp protocol
Add Packet Data Convergence Protocol (PDCP) processing library.
The library is similar to
lib_ipsecwhich provides IPsec processing capabilities in DPDK.PDCP would involve roughly the following options,
1. Transfer of user plane data
2. Transfer of control plane data
3. Header compression
4. Uplink data compression
5. Ciphering and integrity protectionPDCP library provides following control path APIs that is used to configure various PDCP entities,
1.rte_pdcp_entity_establish()
2.rte_pdcp_entity_suspend()
3.rte_pdcp_entity_release()Quoted 3 lines
PDCP process is split into 2 parts. One before crypto processing (
rte_pdcp_pkt_pre_process()) and one after crypto processing (rte_pdcp_pkt_post_process()). Since cryptodev dequeue can returncrypto
Quoted 6 lines
operations belonging to multiple entities,
rte_pdcp_pkt_crypto_group()is added to help grouping crypto operations belonging to same entity.Signed-off-by Anoob Joseph <[email protected]>Signed-off-by Kiran Kumar K <[email protected]>Signed-off-by Volodymyr Fialko <[email protected]>Quoted 9 lines
--- doc/api/doxy-api-index.md | 3 +- doc/api/doxy-api.conf.in | 1 + lib/meson.build | 1 + lib/pdcp/meson.build | 8 + lib/pdcp/pdcp_crypto.c | 240 ++++++++ lib/pdcp/pdcp_crypto.h | 20 + lib/pdcp/pdcp_entity.h | 218 +++++++ lib/pdcp/pdcp_process.c | 1195+++++++++++++++++++++++++++++++++++++
Quoted 62 lines
lib/pdcp/pdcp_process.h | 13 + lib/pdcp/rte_pdcp.c | 136 +++++ lib/pdcp/rte_pdcp.h | 263 ++++++++ lib/pdcp/rte_pdcp_group.h | 133 +++++ lib/pdcp/version.map | 13 + 13 files changed, 2243 insertions(+), 1 deletion(-) create mode 100644 lib/pdcp/meson.build create mode 100644 lib/pdcp/pdcp_crypto.c create mode 100644 lib/pdcp/pdcp_crypto.h create mode 100644 lib/pdcp/pdcp_entity.h create mode 100644 lib/pdcp/pdcp_process.c create mode 100644 lib/pdcp/pdcp_process.h create mode 100644 lib/pdcp/rte_pdcp.c create mode 100644 lib/pdcp/rte_pdcp.h create mode 100644 lib/pdcp/rte_pdcp_group.h create mode 100644 lib/pdcp/version.mapdoc/api/doxy-api-index.md +2
-1@@ -126,7 +126,8 @@ The public API headers are grouped by topics: [eCPRI](@ref rte_ecpri.h), [L2TPv2](@ref rte_l2tpv2.h), [PPP](@ref rte_ppp.h), - [PDCP hdr](@ref rte_pdcp_hdr.h) + [PDCP hdr](@ref rte_pdcp_hdr.h), + [PDCP](@ref rte_pdcp.h), - **QoS**: [metering](@ref rte_meter.h),doc/api/doxy-api.conf.in +1
-0@@ -61,6 +61,7 @@ INPUT = @TOPDIR@/doc/api/doxy-api- index.md \ @TOPDIR@/lib/net \ @TOPDIR@/lib/pcapng \ @TOPDIR@/lib/pci \ + @TOPDIR@/lib/pdcp \ @TOPDIR@/lib/pdump \ @TOPDIR@/lib/pipeline \@TOPDIR@/lib/port \lib/meson.build +1
-0@@ -63,6 +63,7 @@ libraries = [ 'flow_classify', # flow_classify lib depends on pkt framework table lib 'graph', 'node', + 'pdcp', # pdcp lib depends on crypto and security ] optional_libs = [lib/pdcp/meson.build new file +0
-0lib/pdcp/meson.build line 3
Quoted 3 lines
lib/pdcp/meson.build new file +3
-0@@ -0,0 +1,8 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(C) 2022 Marvell. +#Extra # here.
Quoted 3 lines
Do we support compilation on Windows as well?
Check missing here.
[Anoob] Will add checks in next version.
Quoted 6 lines
lib/pdcp/meson.build line 6
Quoted 3 lines
lib/pdcp/meson.build new file +3
-0+ +sources = files('pdcp_crypto.c', 'pdcp_process.c', 'rte_pdcp.c') +headers = files('rte_pdcp.h')Do we need to add the indirect header as well for
lib/pdcp/rte_pdcp_group.h?
[Anoob] Yes. Will update in next version.
Quoted 5 lines
lib/pdcp/meson.build line 8
Quoted 3 lines
lib/pdcp/meson.build new file +2
-0+ +deps += ['security']Crypto not needed as dependency?
[Anoob] Yes. Will include other dependencies as well.
Quoted 160 lines
Quoted 61 lines
lib/pdcp/pdcp_crypto.c new file +14
-0@@ -0,0 +1,240 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2022 Marvell. +*/ + +#include <rte_crypto.h> +#include <rte_crypto_sym.h> +#include <rte_cryptodev.h> +#include <rte_pdcp.h> + +#include "pdcp_crypto.h" +#include "pdcp_entity.h" + +static int +pdcp_crypto_caps_cipher_verify(uint8_t dev_id, const struct
rte_crypto_sym_xform*c_xfrm)lib/pdcp/pdcp_crypto.c new file +13
-0+{ +const struct rte_cryptodev_symmetric_capability *cap; +struct rte_cryptodev_sym_capability_idx cap_idx; +int ret; + + cap_idx.type =RTE_CRYPTO_SYM_XFORM_CIPHER ; + cap_idx.algo.cipher = c_xfrm->cipher.algo; + + cap =rte_cryptodev_sym_capability_get (dev_id, &cap_idx); +if (cap ==NULL ) +return -1 ; + + ret = rte_cryptodev_sym_capability_check_cipher(cap, c_xfrm-Quoted 1 line
cipher.key.length,
lib/pdcp/pdcp_crypto.c new file +1
-0+ c_xfrm-Quoted 1 line
cipher.iv.length);
lib/pdcp/pdcp_crypto.c new file +6
-0+ +return ret; +} + +static int +pdcp_crypto_caps_auth_verify(uint8_t dev_id, const struct
rte_crypto_sym_xform*a_xfrm)lib/pdcp/pdcp_crypto.c new file +13
-0+{ +const struct rte_cryptodev_symmetric_capability *cap; +struct rte_cryptodev_sym_capability_idx cap_idx; +int ret; + + cap_idx.type =RTE_CRYPTO_SYM_XFORM_AUTH ; + cap_idx.algo.auth = a_xfrm->auth.algo; + + cap =rte_cryptodev_sym_capability_get (dev_id, &cap_idx); +if (cap ==NULL ) +return -1 ; + + ret = rte_cryptodev_sym_capability_check_auth(cap, a_xfrm-Quoted 1 line
auth.key.length,
lib/pdcp/pdcp_crypto.c new file +1
-0+ a_xfrm-Quoted 1 line
auth.digest_length,
lib/pdcp/pdcp_crypto.c
Quoted 9 lines
lib/pdcp/pdcp_crypto.c new file +9
-0+ a_xfrm->auth.iv.length); + +return ret; +} + +static int +pdcp_crypto_xfrm_validate (const struct rte_pdcp_entity_conf *conf, +const struct rte_crypto_sym_xform *c_xfrm, + const struct rte_crypto_sym_xform
*a_xfrm,lib/pdcp/pdcp_crypto.c
Quoted 7 lines
lib/pdcp/pdcp_crypto.c new file +7
-0+ bool is_auth_then_cipher) +{ +uint16_t ciph_iv_len, auth_digest_len, auth_iv_len; +int ret; + +/* +* Uplink means PDCP entity is configured for transmit. Downlink means
lib/pdcp/pdcp_crypto.c
Quoted 4 lines
PDCP entity is
lib/pdcp/pdcp_crypto.c new file +1
-0+* configured for receive. When integrity protection is enabled, PDCP always performs
lib/pdcp/pdcp_crypto.c new file +1
-0+* digest-encrypted or auth-gen-encrypt for uplink (and decrypt- auth-
lib/pdcp/pdcp_crypto.c
Quoted 2 lines
verify for downlink).
lib/pdcp/pdcp_crypto.c new file +1
-0+* So for uplink, crypto chain would be auth-cipher while for downlink it
lib/pdcp/pdcp_crypto.c
Quoted 4 lines
would be
lib/pdcp/pdcp_crypto.c new file +3
-0+* cipher-auth. +* +* When integrity protection is not required, xform would be cipher only.
lib/pdcp/pdcp_crypto.c
Quoted 8 lines
lib/pdcp/pdcp_crypto.c new file +8
-0+*/ + +if (c_xfrm ==NULL ) +return -EINVAL ; + +if (conf->pdcp_xfrm.pkt_dir ==RTE_SECURITY_PDCP_UPLINK ) { + +/* With UPLINK, if auth is enabled, it should be before cipher */
lib/pdcp/pdcp_crypto.c
Quoted 8 lines
lib/pdcp/pdcp_crypto.c new file +8
-0+if (a_xfrm !=NULL && !is_auth_then_cipher) +return -EINVAL ; + +/* With UPLINK, cipher operation must be encrypt */ +if (c_xfrm->cipher.op !=RTE_CRYPTO_CIPHER_OP_ENCRYPT ) +return -EINVAL ; + +/* With UPLINK, auth operation (if present) must be generate */
lib/pdcp/pdcp_crypto.c
Quoted 5 lines
lib/pdcp/pdcp_crypto.c new file +1
-0+ if (a_xfrm != NULL && a_xfrm->auth.op !=
RTE_CRYPTO_AUTH_OP_GENERATE)lib/pdcp/pdcp_crypto.c new file +3
-0+return -EINVAL ; + + } else if (conf->pdcp_xfrm.pkt_dir ==
RTE_SECURITY_PDCP_DOWNLINK)lib/pdcp/pdcp_crypto.c
Quoted 3 lines
{
lib/pdcp/pdcp_crypto.c new file +2
-0+ +/* With DOWNLINK, if auth is enabled, it should be after cipher
lib/pdcp/pdcp_crypto.c
Quoted 9 lines
*/
lib/pdcp/pdcp_crypto.c new file +8
-0+if (a_xfrm !=NULL && is_auth_then_cipher) +return -EINVAL ; + +/* With DOWNLINK, cipher operation must be decrypt */ +if (c_xfrm->cipher.op !=RTE_CRYPTO_CIPHER_OP_DECRYPT ) +return -EINVAL ; + +/* With DOWNLINK, auth operation (if present) must be verify
Quoted 16 lines
*/
lib/pdcp/pdcp_crypto.c new file +1
-0+ if (a_xfrm != NULL && a_xfrm->auth.op !=
RTE_CRYPTO_AUTH_OP_VERIFY)lib/pdcp/pdcp_crypto.c new file +13
-0+return -EINVAL ; + + }else { +return -EINVAL ; + } + +if ((c_xfrm->cipher.algo !=RTE_CRYPTO_CIPHER_NULL ) && + (c_xfrm->cipher.algo !=RTE_CRYPTO_CIPHER_AES_CTR ) && + (c_xfrm->cipher.algo !=RTE_CRYPTO_CIPHER_ZUC_EEA3 ) && + (c_xfrm->cipher.algo !=RTE_CRYPTO_CIPHER_SNOW3G_UEA2 )) +return -EINVAL ; + +if (c_xfrm->cipher.algo ==RTE_CRYPTO_CIPHER_NULL )lib/pdcp/pdcp_crypto.c
Quoted 10 lines
lib/pdcp/pdcp_crypto.c new file +10
-0+ ciph_iv_len =0 ; + else + ciph_iv_len =PDCP_IV_LENGTH ; + +if (ciph_iv_len != c_xfrm->cipher.iv.length) +return -EINVAL ; + +if (a_xfrm !=NULL ) { +if ((a_xfrm->auth.algo !=RTE_CRYPTO_AUTH_NULL ) && + (a_xfrm->auth.algo != RTE_CRYPTO_AUTH_AES_CMAC)&&
lib/pdcp/pdcp_crypto.c
Quoted 2 lines
lib/pdcp/pdcp_crypto.c new file +2
-0+ (a_xfrm->auth.algo != RTE_CRYPTO_AUTH_ZUC_EIA3) && + (a_xfrm->auth.algo !=
RTE_CRYPTO_AUTH_SNOW3G_UIA2))
Quoted 8 lines
lib/pdcp/pdcp_crypto.c line 132
Quoted 6 lines
lib/pdcp/pdcp_crypto.c new file +6
-0+return -EINVAL ; + +if (a_xfrm->auth.algo ==RTE_CRYPTO_AUTH_NULL ) + auth_digest_len =0 ; +else + auth_digest_len =4 ;If we have a macro for IV length, why not for digest also?
[Anoob] Will add macro for digest length.
Quoted 6 lines
Moreover, for NULL integrity, digest length is also 4 with all 0s. Refer Annex D.1 in
https://www.etsi.org/deliver/etsi_ts/133500_133599/133501/15.04.00_60/ts
_133501v150400p.pdfDigest len would be 0 only in case of
a_xfrm== NULL
[Anoob] I agree that PDCP requires AUTH NULL to add all 0s. And we satisfy the same by having lib PDCP add zeros. Most of the crypto drivers in DPDK doesn't allow non-zero digest length for NULL auth. The above change was added to make sure the library works well with existing drivers.
Quoted 197 lines
lib/pdcp/pdcp_crypto.c
Quoted 7 lines
lib/pdcp/pdcp_crypto.c new file +6
-0+ +if (auth_digest_len != a_xfrm->auth.digest_length) +return -EINVAL ; + + if ((a_xfrm->auth.algo == RTE_CRYPTO_AUTH_ZUC_EIA3) || + (a_xfrm->auth.algo ==
RTE_CRYPTO_AUTH_SNOW3G_UIA2))Quoted 31 lines
lib/pdcp/pdcp_crypto.c new file +26
-0+ auth_iv_len =PDCP_IV_LENGTH ; + else + auth_iv_len =0 ; + +if (a_xfrm->auth.iv.length != auth_iv_len) +return -EINVAL ; + } + +if (!rte_cryptodev_is_valid_dev (conf->dev_id)) +return -EINVAL ; + + ret =pdcp_crypto_caps_cipher_verify (conf->dev_id, c_xfrm); +if (ret) +return -ENOTSUP ; + +if (a_xfrm !=NULL ) { + ret =pdcp_crypto_caps_auth_verify (conf->dev_id, a_xfrm); +if (ret) +return -ENOTSUP ; + } + +return 0 ; +} + +int +pdcp_crypto_sess_create(struct rte_pdcp_entity *entity, const struct
rte_pdcp_entity_conf*conf)lib/pdcp/pdcp_crypto.c new file +4
-0+{ +struct rte_crypto_sym_xform *c_xfrm, *a_xfrm; +struct entity_priv *en_priv; +bool is_auth_then_cipher;lib/pdcp/pdcp_crypto.c
Quoted 10 lines
lib/pdcp/pdcp_crypto.c new file +10
-0+int ret; + +if (entity ==NULL || conf ==NULL || conf->crypto_xfrm ==NULL ) +return -EINVAL ; + + en_priv =entity_priv_get (entity); + + en_priv->dev_id = conf->dev_id; + +if (conf->crypto_xfrm->type ==RTE_CRYPTO_SYM_XFORM_CIPHER ){
Quoted 118 lines
lib/pdcp/pdcp_crypto.c new file +4
-0+ c_xfrm = conf->crypto_xfrm; + a_xfrm = conf->crypto_xfrm->next; + is_auth_then_cipher = false; + } else if (conf->crypto_xfrm->type ==
RTE_CRYPTO_SYM_XFORM_AUTH) {lib/pdcp/pdcp_crypto.c new file +8
-0+ a_xfrm = conf->crypto_xfrm; + c_xfrm = conf->crypto_xfrm->next; + is_auth_then_cipher = true; + }else { +return -EINVAL ; + } + + ret = pdcp_crypto_xfrm_validate(conf, c_xfrm, a_xfrm,
is_auth_then_cipher);lib/pdcp/pdcp_crypto.c new file +14
-0+if (ret) +return ret; + +if (c_xfrm->cipher.algo ==RTE_CRYPTO_CIPHER_NULL ) + c_xfrm->cipher.iv.offset =0 ; +else + c_xfrm->cipher.iv.offset =PDCP_IV_OFFSET ; + +if (a_xfrm !=NULL ) { +if (a_xfrm->auth.algo ==RTE_CRYPTO_AUTH_NULL ) + a_xfrm->auth.iv.offset =0 ; +else +if (c_xfrm->cipher.iv.offset) + a_xfrm->auth.iv.offset = PDCP_IV_OFFSET +
PDCP_IV_LENGTH;lib/pdcp/pdcp_crypto.c new file +8
-0+else + a_xfrm->auth.iv.offset =PDCP_IV_OFFSET ; + } + +if (conf->sess_mpool ==NULL ) +return -EINVAL ; + + en_priv->crypto_sess = rte_cryptodev_sym_session_create(conf-Quoted 1 line
dev_id,conf->crypto_xfrm,lib/pdcp/pdcp_crypto.c new file +1
-0+ conf-Quoted 1 line
sess_mpool);lib/pdcp/pdcp_crypto.c new file +6
-0+if (en_priv->crypto_sess ==NULL ) { +/* API returns positive values as error codes */ +return -rte_errno; + } + + rte_cryptodev_sym_session_opaque_data_set(en_priv-
crypto_sess,
(uint64_t)entity);lib/pdcp/pdcp_crypto.c new file +16
-0+ +return 0 ; +} + +int +pdcp_crypto_sess_destroy (struct rte_pdcp_entity *entity) +{ +struct entity_priv *en_priv; + +if (entity ==NULL ) +return -EINVAL ; + + en_priv =entity_priv_get (entity); + +if (en_priv->crypto_sess !=NULL ) { + rte_cryptodev_sym_session_free(en_priv->dev_id, en_priv-Quoted 1 line
crypto_sess);lib/pdcp/pdcp_crypto.c new file +5
-0+ en_priv->crypto_sess =NULL ; + } + +return 0 ; +}lib/pdcp/pdcp_crypto.h new file +12
-0@@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2022 Marvell. +*/ + +#ifndef _PDCP_CRYPTO_H_ +#define _PDCP_CRYPTO_H_ + +#include <rte_crypto.h> +#include <rte_crypto_sym.h> +#include <rte_pdcp.h> + +#define PDCP_IV_OFFSET (sizeof(struct rte_crypto_op) + sizeof(struct
rte_crypto_sym_op))lib/pdcp/pdcp_crypto.h new file +8
-0+#define PDCP_IV_LENGTH 16 + +int pdcp_crypto_sess_create (struct rte_pdcp_entity *entity, +const struct rte_pdcp_entity_conf *conf); + +int pdcp_crypto_sess_destroy (struct rte_pdcp_entity *entity); + +#endif /* _PDCP_CRYPTO_H_ */ lib/pdcp/pdcp_entity.h new file +15
-0@@ -0,0 +1,218 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2022 Marvell. +*/ + +#ifndef _PDCP_ENTITY_H_ +#define _PDCP_ENTITY_H_ + +#include <rte_common.h> +#include <rte_crypto_sym.h> +#include <rte_mempool.h> +#include <rte_pdcp.h> +#include <rte_security.h> + +struct entity_priv ; +lib/pdcp/pdcp_entity.h line 25
Quoted 10 lines
lib/pdcp/pdcp_entity.h new file +10
-0+#define PDCP_PDU_HDR_SIZE_SN_12 (RTE_ALIGN_MUL_CEIL(12, 8) / 8) +#define PDCP_PDU_HDR_SIZE_SN_18 (RTE_ALIGN_MUL_CEIL(18, 8) / 8) + +#define PDCP_GET_SN_12_FROM_COUNT (c) ((c) & 0xfff) +#define PDCP_GET_SN_18_FROM_COUNT (c) ((c) & 0x3ffff) + +#define PDCP_GET_HFN_SN_12_FROM_COUNT (c) (((c) >> 12) & 0xfffff) +#define PDCP_GET_HFN_SN_18_FROM_COUNT (c) (((c) >> 18) & 0x3fff) + +#define PDCP_SET_COUNT_FROM_HFN_SN_12 (h, s) ((((h) & 0xfffff) <<12) | ((s)
Quoted 2 lines
&
0xfff))
+#definePDCP_SET_COUNT_FROM_HFN_SN_18(h, s)((((h) &0x3fff) <<18) | ((s)
lib/pdcp/pdcp_entity.h line 35
Quoted 10 lines
&
0x3ffff))lib/pdcp/pdcp_entity.h new file +9
-0+ +#define PDCP_SN_12_WINDOW_SZ 0x800 +#define PDCP_SN_18_WINDOW_SZ 0x20000 + +#define PDCP_SN_12_HFN_MAX ((1 << (32 - 12)) - 1) +#define PDCP_SN_12_HFN_MIN 0 +#define PDCP_SN_18_HFN_MAX ((1 << (32 - 18)) - 1) +#define PDCP_SN_18_HFN_MIN 0 +Can we have common defines for SN-12 and SN-18 and take SN as parameter?
We can have something like this.
Quoted 10 lines
#define
PDCP_PDU_HDR_SIZE(sn_size)(RTE_ALIGN_MUL_CEIL((sn_size), 8)/ 8)
#definePDCP_GET_SN_FROM_COUNT(c, sn_size)((c) & ((1<<sn_size)-1)) #definePDCP_GET_HFN_FROM_COUNT(c, sn_size)(((c) >>sn_size) & ((1 << (32 -sn_size)) - 1))
#definePDCP_SET_COUNT_FROM_HFN_SN(h, s, sn_size)((((h) & ((1 << (32
-sn_size)) - 1)) <<sn_size) | ((s) & ((1<<sn_size)-1))) #definePDCP_HFN_MAX(sn_size)((1 << (32 - (sn_size))) - 1) #definePDCP_HFN_MIN0
[Anoob] Agreed. Will replace these macros with generic static inlines.
Quoted 84 lines
lib/pdcp/pdcp_entity.h
Quoted 2 lines
lib/pdcp/pdcp_entity.h new file +2
-0+/* IV generation function based on the entity configuration */ +typedef void (*iv_gen_t)(struct rte_crypto_op *cop, const struct
entity_privQuoted 81 lines
*en_priv,lib/pdcp/pdcp_entity.h new file +80
-0+ uint32_t count); + +enum pdcp_pdu_type { +PDCP_PDU_TYPE_CTRL =0 , +PDCP_PDU_TYPE_DATA =1 , +}; + +enum pdcp_up_ctrl_pdu_type { +PDCP_UP_CTRL_PDU_TYPE_STATUS_REPORT , +PDCP_UP_CTRL_PDU_TYPE_ROHC_FEEDBACK , +PDCP_UP_CTRL_PDU_TYPE_EHC_FEEDBACK , +PDCP_UP_CRTL_PDU_TYPE_UDC_FEEDBACK +}; + +struct entity_state { +uint32_t rx_next; +uint32_t tx_next; +uint32_t rx_deliv; +uint32_t rx_reord; +}; + +union auth_iv_partial { +/* For AES-CMAC, there is no IV, but message gets prepended */ +struct { +#if RTE_BYTE_ORDER ==RTE_LITTLE_ENDIAN +uint64_t count :32 ; +uint64_t zero_38_39 :2 ; +uint64_t direction :1 ; +uint64_t bearer :5 ; +uint64_t zero_40_63 :24 ; +#else +uint64_t count :32 ; +uint64_t bearer :5 ; +uint64_t direction :1 ; +uint64_t zero_38_39 :2 ; +uint64_t zero_40_63 :24 ; +#endif + } aes_cmac; +struct { +#if RTE_BYTE_ORDER ==RTE_LITTLE_ENDIAN +uint64_t count :32 ; +uint64_t zero_37_39 :3 ; +uint64_t bearer :5 ; +uint64_t zero_40_63 :24 ; + +uint64_t rsvd_65_71 :7 ; +uint64_t direction_64 :1 ; +uint64_t rsvd_72_111 :40 ; +uint64_t rsvd_113_119 :7 ; +uint64_t direction_112 :1 ; +uint64_t rsvd_120_127 :8 ; +#else +uint64_t count :32 ; +uint64_t bearer :5 ; +uint64_t zero_37_39 :3 ; +uint64_t zero_40_63 :24 ; + +uint64_t direction_64 :1 ; +uint64_t rsvd_65_71 :7 ; +uint64_t rsvd_72_111 :40 ; +uint64_t direction_112 :1 ; +uint64_t rsvd_113_119 :7 ; +uint64_t rsvd_120_127 :8 ; +#endif + } zs; +uint64_t u64[2 ]; +}; + +union cipher_iv_partial { +struct { +#if RTE_BYTE_ORDER ==RTE_LITTLE_ENDIAN +uint64_t count :32 ; +uint64_t zero_38_39 :2 ; +uint64_t direction :1 ; +uint64_t bearer :5 ; +uint64_t zero_40_63 :24 ; + +uint64_t zero_64_127; +#else +uint64_t count :32 ;
Quoted 8 lines
lib/pdcp/pdcp_entity.h line 115
Quoted 6 lines
lib/pdcp/pdcp_entity.h new file +6
-0+ uint64_t bearer : 5; + uint64_t direction : 1; + uint64_t zero_38_39 : 2; + uint64_t zero_40_63 : 24; + +uint64_t zero_64_127;Can we take
zero_64_127out of #if-else
[Anoob] Agreed. Will address in next version.
Quoted 24 lines
Quoted 11 lines
lib/pdcp/pdcp_entity.h new file +10
-0+#endif + } aes_ctr; +struct { +#if RTE_BYTE_ORDER ==RTE_LITTLE_ENDIAN +uint64_t count :32 ; +uint64_t zero_38_39 :2 ; +uint64_t direction :1 ; +uint64_t bearer :5 ; +uint64_t zero_40_63 :24 ; +lib/pdcp/pdcp_entity.h line 143
Quoted 10 lines
lib/pdcp/pdcp_entity.h new file +10
-0+uint64_t rsvd_64_127; +#else + uint64_t count : 32; + uint64_t bearer : 5; + uint64_t direction : 1; + uint64_t zero_38_39 : 2; + uint64_t zero_40_63 : 24; + +uint64_t rsvd_64_127; +#endif
rsvd_64_127can also be out of #if-else
Quoted 11 lines
lib/pdcp/pdcp_entity.h line 149
Quoted 6 lines
lib/pdcp/pdcp_entity.h new file +6
-0+ } zs; +uint64_t u64[2 ]; +}; + +/* +* Layout of PDCP entity: [rte_pdcp_entity] [entity_priv] [entity_dl/ul] If the layout is fixed, can we have 0 length array in
rte_pdcp_entityforentity_privand inentity_privfor entity_dl/ul.
I see that entity_dl/ul are not completely defined. You can define them later when they are supported.
[Anoob] The implementation will be part of next version.
Quoted 5 lines
Quoted 3 lines
+ */
+Extra line
[Anoob] The description was not just for the following struct, but the section (3 structures basically). Hence kept a blank line in between.
Quoted 69 lines
Quoted 18 lines
lib/pdcp/pdcp_entity.h new file +17
-0+struct entity_priv { +/** Crypto sym session. */ +struct rte_cryptodev_sym_session *crypto_sess; +/** Entity specific IV generation function. */ +iv_gen_t iv_gen; +/** Pre-prepared auth IV. */ +union auth_iv_partial auth_iv_part; +/** Pre-prepared cipher IV. */ +union cipher_iv_partial cipher_iv_part; +/** Entity state variables. */ +struct entity_state state; +/** Flags. */ +struct { +/** PDCP PDU has 4 byte MAC-I. */ +uint64_t is_authenticated :1 ; +/** Cipher offset & length in bits. */ +uint64_t is_ciph_in_bits :1 ;lib/pdcp/pdcp_entity.h
Quoted 10 lines
lib/pdcp/pdcp_entity.h new file +10
-0+/** Auth offset & length in bits. */ + uint64_t is_auth_in_bits : 1; +/** Is UL/transmitting PDCP entity */ + uint64_t is_ul_entity : 1; + } flags; +/** Crypto op pool. */ +struct rte_mempool *cop_pool; +/** PDCP header size. */ +uint8_t hdr_sz; +/** PDCP AAD size. For AES-CMAC, additional message is prepended for
Quoted 35 lines
the operation. */
lib/pdcp/pdcp_entity.h new file +7
-0+uint8_t aad_sz; +/** Device ID of the device to be used for offload. */ +uint8_t dev_id; +}; + +struct entity_priv_dl_part { +/* TODO - when in-order-delivery is supported, post PDCP packets would need to cached. */
lib/pdcp/pdcp_entity.h new file +6
-0+uint8_t dummy; +}; + +struct entity_priv_ul_part { +/* +* TODO - when re-establish is supported, both plain & post PDCP packets would need to be
lib/pdcp/pdcp_entity.h new file +13
-0+* cached. +*/ +uint8_t dummy; +}; + +static inline struct entity_priv * +entity_priv_get (const struct rte_pdcp_entity *entity) { +return RTE_PTR_ADD (entity,sizeof (struct rte_pdcp_entity )); +} + +static inline struct entity_priv_dl_part * +entity_dl_part_get (const struct rte_pdcp_entity *entity) { + return RTE_PTR_ADD(entity, sizeof(struct rte_pdcp_entity) +
sizeof(struct entity_priv));lib/pdcp/pdcp_entity.h new file +5
-0+} + +static inline struct entity_priv_ul_part * +entity_ul_part_get (const struct rte_pdcp_entity *entity) { + return RTE_PTR_ADD(entity, sizeof(struct rte_pdcp_entity) +Quoted 2 lines
sizeof(struct entity_priv));
+}Above inline functions may not be needed also if we have 0 len arrays.
Quoted 9 lines
lib/pdcp/pdcp_entity.h line 216
Quoted 6 lines
lib/pdcp/pdcp_entity.h new file +6
-0+ +static inline int +pdcp_hdr_size_get (enum rte_security_pdcp_sn_size sn_size) +{ +return RTE_ALIGN_MUL_CEIL (sn_size,8 ) /8 ; +}
PDCP_PDU_HDR_SIZEis same as this inline function. Can we get away with this one?
[Anoob] Removed the macro.
Quoted 20 lines
Quoted 20 lines
lib/pdcp/pdcp_entity.h new file +2
-0+ +#endif /* _PDCP_ENTITY_H_ */ lib/pdcp/pdcp_process.c new file +11
-0@@ -0,0 +1,1195 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2022 Marvell. +*/ + +#include <rte_crypto.h> +#include <rte_crypto_sym.h> +#include <rte_cryptodev.h> +#include <rte_memcpy.h> +#include <rte_pdcp.h> +#include <rte_pdcp_hdr.h> +
Quoted 8 lines
lib/pdcp/pdcp_process.c line 16
Quoted 5 lines
lib/pdcp/pdcp_process.c new file +5
-0+#include "pdcp_crypto.h" +#include "pdcp_entity.h" +#include "pdcp_process.h" + +#define PDCP_MAC_I_LEN 4Can you define it at same place where
PDCP_IV_LENGTHis defined and use this in xform validate.
[Anoob] Moved to pdcp_crypto.h
Quoted 1,630 lines
Quoted 14 lines
lib/pdcp/pdcp_process.c new file +13
-0+ +/* Enum of supported algorithms for ciphering */ +enum pdcp_cipher_algo { +PDCP_CIPHER_ALGO_NULL , +PDCP_CIPHER_ALGO_AES , +PDCP_CIPHER_ALGO_ZUC , +PDCP_CIPHER_ALGO_SNOW3G , +PDCP_CIPHER_ALGO_MAX +}; + +/* Enum of supported algorithms for integrity */ +enum pdcp_auth_algo { +PDCP_AUTH_ALGO_NULL ,lib/pdcp/pdcp_process.c
Quoted 10 lines
lib/pdcp/pdcp_process.c new file +10
-0+PDCP_AUTH_ALGO_AES , +PDCP_AUTH_ALGO_ZUC , +PDCP_AUTH_ALGO_SNOW3G , +PDCP_AUTH_ALGO_MAX +}; + +/* IV generation functions based on type of operation (cipher - auth) */ + +static void +pdcp_iv_gen_null_null(struct rte_crypto_op *cop, const struct
entity_privQuoted 11 lines
*en_priv,uint32_tcount)lib/pdcp/pdcp_process.c new file +9
-0+{ +/* No IV required for NULL cipher + NULL auth */ +RTE_SET_USED (cop); +RTE_SET_USED (en_priv); +RTE_SET_USED (count); +} + +static void +pdcp_iv_gen_null_aes_cmac(struct rte_crypto_op *cop, const struct
entity_priv*en_priv,lib/pdcp/pdcp_process.c
Quoted 8 lines
lib/pdcp/pdcp_process.c new file +8
-0+ uint32_t count) +{ +struct rte_crypto_sym_op *op = cop->sym; +struct rte_mbuf *mb = op->m_src; +uint8_t *m_ptr; +uint64_t m; + +/* AES-CMAC requires message to be prepended with info on count etc
Quoted 22 lines
*/
lib/pdcp/pdcp_process.c new file +5
-0+ +/* Prepend by 8 bytes to add custom message */ + m_ptr = (uint8_t *)rte_pktmbuf_prepend (mb,8 ); + + m = en_priv->auth_iv_part.u64[0] |((uint64_t)(rte_cpu_to_be_32(count)));
lib/pdcp/pdcp_process.c new file +6
-0+ +rte_memcpy (m_ptr, &m,8 ); +} + +static void +pdcp_iv_gen_null_zs(struct rte_crypto_op *cop, const struct entity_priv
*en_priv,uint32_tcount)lib/pdcp/pdcp_process.c new file +7
-0+{ +uint64_t iv_u64[2 ]; +uint8_t *iv; + + iv = rte_crypto_op_ctod_offset(cop, uint8_t *, PDCP_IV_OFFSET); + + iv_u64[0] = en_priv->auth_iv_part.u64[0] |((uint64_t)(rte_cpu_to_be_32(count)));
lib/pdcp/pdcp_process.c
Quoted 8 lines
lib/pdcp/pdcp_process.c new file +8
-0+rte_memcpy (iv, &iv_u64[0 ],8 ); + + iv_u64[1 ] = iv_u64[0 ] ^ en_priv->auth_iv_part.u64[1 ]; +rte_memcpy (iv +8 , &iv_u64[1 ],8 ); +} + +static void +pdcp_iv_gen_aes_ctr_null(struct rte_crypto_op *cop, const struct
entity_privQuoted 49 lines
*en_priv,lib/pdcp/pdcp_process.c new file +8
-0+ uint32_t count) +{ +uint64_t iv_u64[2 ]; +uint8_t *iv; + + iv = rte_crypto_op_ctod_offset(cop, uint8_t *, PDCP_IV_OFFSET); + + iv_u64[0] = en_priv->cipher_iv_part.u64[0] |((uint64_t)(rte_cpu_to_be_32(count)));
lib/pdcp/pdcp_process.c new file +6
-0+ iv_u64[1 ] =0 ; +rte_memcpy (iv, iv_u64,16 ); +} + +static void +pdcp_iv_gen_zs_null(struct rte_crypto_op *cop, const struct entity_priv
*en_priv,uint32_tcount)lib/pdcp/pdcp_process.c new file +7
-0+{ +uint64_t iv_u64; +uint8_t *iv; + + iv = rte_crypto_op_ctod_offset(cop, uint8_t *, PDCP_IV_OFFSET); + + iv_u64 = en_priv->cipher_iv_part.u64[0] |((uint64_t)(rte_cpu_to_be_32(count)));
lib/pdcp/pdcp_process.c new file +6
-0+rte_memcpy (iv, &iv_u64,8 ); +rte_memcpy (iv +8 , &iv_u64,8 ); +} + +static void +pdcp_iv_gen_zs_zs(struct rte_crypto_op *cop, const struct entity_priv
*en_priv,uint32_tcount)lib/pdcp/pdcp_process.c new file +8
-0+{ +uint64_t iv_u64[2 ]; +uint8_t *iv; + + iv = rte_crypto_op_ctod_offset(cop, uint8_t *, PDCP_IV_OFFSET); + +/* Generating cipher IV */ + iv_u64[0] = en_priv->cipher_iv_part.u64[0] |((uint64_t)(rte_cpu_to_be_32(count)));
lib/pdcp/pdcp_process.c new file +7
-0+rte_memcpy (iv, &iv_u64[0 ],8 ); +rte_memcpy (iv +8 , &iv_u64[0 ],8 ); + + iv +=PDCP_IV_LENGTH ; + +/* Generating auth IV */ + iv_u64[0] = en_priv->auth_iv_part.u64[0] |((uint64_t)(rte_cpu_to_be_32(count)));
lib/pdcp/pdcp_process.c
Quoted 8 lines
lib/pdcp/pdcp_process.c new file +8
-0+rte_memcpy (iv, &iv_u64[0 ],8 ); + + iv_u64[1 ] = iv_u64[0 ] ^ en_priv->auth_iv_part.u64[1 ]; +rte_memcpy (iv +8 , &iv_u64[1 ],8 ); +} + +static void +pdcp_iv_gen_zs_aes_cmac(struct rte_crypto_op *cop, const struct
entity_privQuoted 42 lines
*en_priv,lib/pdcp/pdcp_process.c new file +10
-0+ uint32_t count) +{ +struct rte_crypto_sym_op *op = cop->sym; +struct rte_mbuf *mb = op->m_src; +uint8_t *m_ptr, *iv; +uint64_t iv_u64[2 ]; +uint64_t m; + + iv = rte_crypto_op_ctod_offset(cop, uint8_t *, PDCP_IV_OFFSET); + iv_u64[0] = en_priv->cipher_iv_part.u64[0] |((uint64_t)(rte_cpu_to_be_32(count)));
lib/pdcp/pdcp_process.c new file +5
-0+rte_memcpy (iv, &iv_u64[0 ],8 ); +rte_memcpy (iv +8 , &iv_u64[0 ],8 ); + + m_ptr = (uint8_t *)rte_pktmbuf_prepend (mb,8 ); + m = en_priv->auth_iv_part.u64[0] |((uint64_t)(rte_cpu_to_be_32(count)));
lib/pdcp/pdcp_process.c new file +5
-0+rte_memcpy (m_ptr, &m,8 ); +} + +static void +pdcp_iv_gen_aes_ctr_aes_cmac(struct rte_crypto_op *cop, const struct
entity_priv*en_priv,lib/pdcp/pdcp_process.c new file +11
-0+ uint32_t count) +{ +struct rte_crypto_sym_op *op = cop->sym; +struct rte_mbuf *mb = op->m_src; +uint8_t *m_ptr, *iv; +uint64_t iv_u64[2 ]; +uint64_t m; + + iv = rte_crypto_op_ctod_offset(cop, uint8_t *, PDCP_IV_OFFSET); + + iv_u64[0] = en_priv->cipher_iv_part.u64[0] |((uint64_t)(rte_cpu_to_be_32(count)));
lib/pdcp/pdcp_process.c new file +5
-0+ iv_u64[1 ] =0 ; +rte_memcpy (iv, iv_u64,PDCP_IV_LENGTH ); + + m_ptr = (uint8_t *)rte_pktmbuf_prepend (mb,8 ); + m = en_priv->auth_iv_part.u64[0] |((uint64_t)(rte_cpu_to_be_32(count)));
lib/pdcp/pdcp_process.c
Quoted 5 lines
lib/pdcp/pdcp_process.c new file +5
-0+rte_memcpy (m_ptr, &m,8 ); +} + +static void +pdcp_iv_gen_aes_ctr_zs(struct rte_crypto_op *cop, const struct
entity_privQuoted 25 lines
*en_priv,uint32_tcount)lib/pdcp/pdcp_process.c new file +7
-0+{ +uint64_t iv_u64[2 ]; +uint8_t *iv; + + iv = rte_crypto_op_ctod_offset(cop, uint8_t *, PDCP_IV_OFFSET); + + iv_u64[0] = en_priv->cipher_iv_part.u64[0] |((uint64_t)(rte_cpu_to_be_32(count)));
lib/pdcp/pdcp_process.c new file +6
-0+ iv_u64[1 ] =0 ; +rte_memcpy (iv, iv_u64,PDCP_IV_LENGTH ); + + iv +=PDCP_IV_LENGTH ; + + iv_u64[0] = en_priv->auth_iv_part.u64[0] |((uint64_t)(rte_cpu_to_be_32(count)));
lib/pdcp/pdcp_process.c new file +8
-0+rte_memcpy (iv, &iv_u64[0 ],8 ); + + iv_u64[1 ] = iv_u64[0 ] ^ en_priv->auth_iv_part.u64[1 ]; +rte_memcpy (iv +8 , &iv_u64[1 ],8 ); +} + +static int +pdcp_crypto_xfrm_get(const struct rte_pdcp_entity_conf *conf, struct
rte_crypto_sym_xform**c_xfrm,lib/pdcp/pdcp_process.c
Quoted 9 lines
lib/pdcp/pdcp_process.c new file +9
-0+ struct rte_crypto_sym_xform **a_xfrm) +{ + *c_xfrm =NULL ; + *a_xfrm =NULL ; + +if (conf->crypto_xfrm ==NULL ) +return -EINVAL ; + +if (conf->crypto_xfrm->type ==RTE_CRYPTO_SYM_XFORM_CIPHER ){
Quoted 76 lines
lib/pdcp/pdcp_process.c new file +3
-0+ *c_xfrm = conf->crypto_xfrm; + *a_xfrm = conf->crypto_xfrm->next; + } else if (conf->crypto_xfrm->type ==
RTE_CRYPTO_SYM_XFORM_AUTH) {lib/pdcp/pdcp_process.c new file +11
-0+ *a_xfrm = conf->crypto_xfrm; + *c_xfrm = conf->crypto_xfrm->next; + }else { +return -EINVAL ; + } + +return 0 ; +} + +static int +pdcp_iv_gen_func_set(struct rte_pdcp_entity *entity, const struct
rte_pdcp_entity_conf*conf)lib/pdcp/pdcp_process.c new file +23
-0+{ +struct rte_crypto_sym_xform *c_xfrm, *a_xfrm; +enum rte_security_pdcp_direction direction; +enum pdcp_cipher_algo ciph_algo; +enum pdcp_auth_algo auth_algo; +struct entity_priv *en_priv; +int ret; + + en_priv =entity_priv_get (entity); + + direction = conf->pdcp_xfrm.pkt_dir; +if (conf->reverse_iv_direction) + direction = !direction; + + ret =pdcp_crypto_xfrm_get (conf, &c_xfrm, &a_xfrm); +if (ret) +return ret; + +if (c_xfrm ==NULL ) +return -EINVAL ; + +memset (&en_priv->auth_iv_part,0 ,sizeof (en_priv->auth_iv_part)); + memset(&en_priv->cipher_iv_part, 0, sizeof(en_priv-
cipher_iv_part));lib/pdcp/pdcp_process.c new file +8
-0+ +switch (c_xfrm->cipher.algo) { +case RTE_CRYPTO_CIPHER_NULL : + ciph_algo =PDCP_CIPHER_ALGO_NULL ; +break ; +case RTE_CRYPTO_CIPHER_AES_CTR : + ciph_algo =PDCP_CIPHER_ALGO_AES ; + en_priv->cipher_iv_part.aes_ctr.bearer = conf-Quoted 1 line
pdcp_xfrm.bearer;
lib/pdcp/pdcp_process.c new file +5
-0+ en_priv->cipher_iv_part.aes_ctr.direction = direction; +break ; +case RTE_CRYPTO_CIPHER_SNOW3G_UEA2 : + ciph_algo =PDCP_CIPHER_ALGO_SNOW3G ; + en_priv->cipher_iv_part.zs.bearer = conf-pdcp_xfrm.bearer;
lib/pdcp/pdcp_process.c new file +5
-0+ en_priv->cipher_iv_part.zs.direction = direction; +break ; +case RTE_CRYPTO_CIPHER_ZUC_EEA3 : + ciph_algo =PDCP_CIPHER_ALGO_ZUC ; + en_priv->cipher_iv_part.zs.bearer = conf-pdcp_xfrm.bearer;
lib/pdcp/pdcp_process.c new file +14
-0+ en_priv->cipher_iv_part.zs.direction = direction; +break ; +default : +return -ENOTSUP ; + } + +if (a_xfrm !=NULL ) { +switch (a_xfrm->auth.algo) { +case RTE_CRYPTO_AUTH_NULL : + auth_algo =PDCP_AUTH_ALGO_NULL ; +break ; +case RTE_CRYPTO_AUTH_AES_CMAC : + auth_algo =PDCP_AUTH_ALGO_AES ; + en_priv->auth_iv_part.aes_cmac.bearer = conf-Quoted 1 line
pdcp_xfrm.bearer;
lib/pdcp/pdcp_process.c
Quoted 1 line
lib/pdcp/pdcp_process.c new file +1
-0+ en_priv->auth_iv_part.aes_cmac.direction =direction;
Quoted 28 lines
lib/pdcp/pdcp_process.c new file +4
-0+break ; +case RTE_CRYPTO_AUTH_SNOW3G_UIA2 : + auth_algo =PDCP_AUTH_ALGO_SNOW3G ; + en_priv->auth_iv_part.zs.bearer = conf-Quoted 1 line
pdcp_xfrm.bearer;
lib/pdcp/pdcp_process.c new file +6
-0+ en_priv->auth_iv_part.zs.direction_64 = direction; + en_priv->auth_iv_part.zs.direction_112 = direction; +break ; +case RTE_CRYPTO_AUTH_ZUC_EIA3 : + auth_algo =PDCP_AUTH_ALGO_ZUC ; + en_priv->auth_iv_part.zs.bearer = conf-Quoted 1 line
pdcp_xfrm.bearer;
lib/pdcp/pdcp_process.c new file +11
-0+ en_priv->auth_iv_part.zs.direction_64 = direction; + en_priv->auth_iv_part.zs.direction_112 = direction; +break ; +default : +return -ENOTSUP ; + } + }else { + auth_algo =PDCP_AUTH_ALGO_NULL ; + } + + static const iv_gen_tiv_gen_map[PDCP_CIPHER_ALGO_MAX][PDCP_AUTH_ALGO_MAX] = {
lib/pdcp/pdcp_process.c new file +1
-0+ [PDCP_CIPHER_ALGO_NULL][PDCP_AUTH_ALGO_NULL] =
pdcp_iv_gen_null_null,lib/pdcp/pdcp_process.c new file +1
-0+ [PDCP_CIPHER_ALGO_NULL][PDCP_AUTH_ALGO_AES] =
pdcp_iv_gen_null_aes_cmac,lib/pdcp/pdcp_process.c
Quoted 1 line
lib/pdcp/pdcp_process.c new file +1
-0+ [PDCP_CIPHER_ALGO_NULL ][PDCP_AUTH_ALGO_SNOW3G ]=
Quoted 12 lines
pdcp_iv_gen_null_zs,lib/pdcp/pdcp_process.c new file +1
-0+ [PDCP_CIPHER_ALGO_NULL][PDCP_AUTH_ALGO_ZUC] =
pdcp_iv_gen_null_zs,lib/pdcp/pdcp_process.c new file +2
-0+ + [PDCP_CIPHER_ALGO_AES][PDCP_AUTH_ALGO_NULL] =
pdcp_iv_gen_aes_ctr_null,lib/pdcp/pdcp_process.c new file +1
-0+ [PDCP_CIPHER_ALGO_AES][PDCP_AUTH_ALGO_AES] =
pdcp_iv_gen_aes_ctr_aes_cmac,lib/pdcp/pdcp_process.c new file +1
-0+ [PDCP_CIPHER_ALGO_AES][PDCP_AUTH_ALGO_SNOW3G] =
pdcp_iv_gen_aes_ctr_zs,lib/pdcp/pdcp_process.c new file +1
-0+ [PDCP_CIPHER_ALGO_AES][PDCP_AUTH_ALGO_ZUC] =
pdcp_iv_gen_aes_ctr_zs,lib/pdcp/pdcp_process.c
Quoted 2 lines
lib/pdcp/pdcp_process.c new file +2
-0+ + [PDCP_CIPHER_ALGO_SNOW3G ][PDCP_AUTH_ALGO_NULL ]=
lib/pdcp/pdcp_process.c
Quoted 7 lines
pdcp_iv_gen_zs_null,lib/pdcp/pdcp_process.c new file +1
-0+ [PDCP_CIPHER_ALGO_SNOW3G][PDCP_AUTH_ALGO_AES] =
pdcp_iv_gen_zs_aes_cmac,
+[PDCP_CIPHER_ALGO_SNOW3G][PDCP_AUTH_ALGO_SNOW3G] =
pdcp_iv_gen_zs_zs,lib/pdcp/pdcp_process.c new file +1
-0+ [PDCP_CIPHER_ALGO_SNOW3G ][PDCP_AUTH_ALGO_ZUC ]=
lib/pdcp/pdcp_process.c
Quoted 7 lines
pdcp_iv_gen_zs_zs,lib/pdcp/pdcp_process.c new file +2
-0+ + [PDCP_CIPHER_ALGO_ZUC][PDCP_AUTH_ALGO_NULL] =
pdcp_iv_gen_zs_null,lib/pdcp/pdcp_process.c new file +1
-0+ [PDCP_CIPHER_ALGO_ZUC][PDCP_AUTH_ALGO_AES] =
pdcp_iv_gen_zs_aes_cmac,lib/pdcp/pdcp_process.c new file +1
-0+ [PDCP_CIPHER_ALGO_ZUC ][PDCP_AUTH_ALGO_SNOW3G ]=
lib/pdcp/pdcp_process.c
Quoted 12 lines
pdcp_iv_gen_zs_zs,lib/pdcp/pdcp_process.c new file +1
-0+ [PDCP_CIPHER_ALGO_ZUC][PDCP_AUTH_ALGO_ZUC] =
pdcp_iv_gen_zs_zs,lib/pdcp/pdcp_process.c new file +9
-0+ }; + + en_priv->iv_gen = iv_gen_map[ciph_algo][auth_algo]; + +return 0 ; +} + +static inline void +cop_prepare(const struct entity_priv *en_priv, struct rte_mbuf *mb,struct
Quoted 31 lines
rte_crypto_op*cop,lib/pdcp/pdcp_process.c new file +29
-0+ uint8_t data_offset, uint32_t count, const bool is_auth) +{ + const struct rte_crypto_op cop_init = { + .type =RTE_CRYPTO_OP_TYPE_SYMMETRIC , + .status =RTE_CRYPTO_OP_STATUS_NOT_PROCESSED , + .sess_type =RTE_CRYPTO_OP_WITH_SESSION , + }; +struct rte_crypto_sym_op *op; +uint32_t pkt_len; + +const uint8_t ciph_shift =3 * en_priv->flags.is_ciph_in_bits; +const uint8_t auth_shift =3 * en_priv->flags.is_auth_in_bits; + + op = cop->sym; + cop->raw = cop_init.raw; + op->m_src = mb; + op->m_dst = mb; + +/* Set IV */ + en_priv->iv_gen (cop, en_priv, count); + +/* Prepare op */ + pkt_len =rte_pktmbuf_pkt_len (mb); + op->cipher.data.offset = data_offset << ciph_shift; + op->cipher.data.length = (pkt_len - data_offset) << ciph_shift; + +if (is_auth) { + op->auth.data.offset =0 ; + op->auth.data.length = (pkt_len - PDCP_MAC_I_LEN) <<
auth_shift;lib/pdcp/pdcp_process.c
Quoted 1 line
lib/pdcp/pdcp_process.c new file +1
-0+ op->auth.digest.data = rte_pktmbuf_mtod_offset(mb,
uint8_tlib/pdcp/pdcp_process.c
Quoted 11 lines
*,
lib/pdcp/pdcp_process.c new file +1
-0+ (pkt_len -
PDCP_MAC_I_LEN));lib/pdcp/pdcp_process.c new file +3
-0+ } + + __rte_crypto_sym_op_attach_sym_session(op, en_priv-
crypto_sess);lib/pdcp/pdcp_process.c new file +4
-0+} + +static inline bool +pdcp_pre_process_uplane_sn_12_ul_set_sn(struct entity_priv *en_priv,struct
Quoted 17 lines
rte_mbuf*mb,lib/pdcp/pdcp_process.c new file +8
-0+ uint32_t *count) +{ +struct rte_pdcp_up_data_pdu_sn_12_hdr *pdu_hdr; +const uint8_t hdr_sz = en_priv->hdr_sz; +uint32_t sn; + +/* Prepend PDU header */ + pdu_hdr = (struct rte_pdcp_up_data_pdu_sn_12_hdr*)rte_pktmbuf_prepend(mb,
hdr_sz);lib/pdcp/pdcp_process.c new file +5
-0+if (unlikely (pdu_hdr ==NULL )) +return false; + +/* Update sequence num in the PDU header */ + *count = __atomic_fetch_add(&en_priv->state.tx_next, 1,
__ATOMIC_RELAXED);lib/pdcp/pdcp_process.c new file +1
-0+ sn =PDCP_GET_SN_12_FROM_COUNT (*count);lib/pdcp/pdcp_process.c
Quoted 10 lines
lib/pdcp/pdcp_process.c new file +10
-0+ + pdu_hdr->d_c =PDCP_PDU_TYPE_DATA ; + pdu_hdr->sn_11_8 = ((sn &0xf00 ) >>8 ); + pdu_hdr->sn_7_0 = (sn &0xff ); + pdu_hdr->r =0 ; +return true; +} + +static uint16_t +pdcp_pre_process_uplane_sn_12_ul(const struct rte_pdcp_entity*entity,
Quoted 24 lines
struct
rte_mbuf*mb[],lib/pdcp/pdcp_process.c new file +1
-0+ struct rte_crypto_op *cop[], uint16_t num,
uint16_t*nb_err)lib/pdcp/pdcp_process.c new file +9
-0+{ +struct entity_priv *en_priv =entity_priv_get (entity); +uint16_t nb_cop; +uint32_t count; +int i; + +const uint8_t data_offset = en_priv->hdr_sz + en_priv->aad_sz; + + nb_cop = rte_crypto_op_bulk_alloc(en_priv->cop_pool,
RTE_CRYPTO_OP_TYPE_SYMMETRIC, cop,lib/pdcp/pdcp_process.c new file +5
-0+ num); + +if (en_priv->flags.is_authenticated) { +for (i =0 ; i < nb_cop; i++) { + if (unlikely(rte_pktmbuf_append(mb[i],
PDCP_MAC_I_LEN) == NULL))lib/pdcp/pdcp_process.c new file +2
-0+ goto cop_free; + if(unlikely(!pdcp_pre_process_uplane_sn_12_ul_set_sn(en_priv, mb[i], +
&count)))lib/pdcp/pdcp_process.c
Quoted 2 lines
lib/pdcp/pdcp_process.c new file +2
-0+ goto cop_free; + cop_prepare(en_priv, mb[i], cop[i], data_offset,count,
lib/pdcp/pdcp_process.c
Quoted 10 lines
true);
lib/pdcp/pdcp_process.c new file +4
-0+ } + }else { +for (i =0 ; i < nb_cop; i++) { + if(unlikely(!pdcp_pre_process_uplane_sn_12_ul_set_sn(en_priv, mb[i], +
&count)))lib/pdcp/pdcp_process.c new file +2
-0+ goto cop_free; + cop_prepare(en_priv, mb[i], cop[i], data_offset,count,
lib/pdcp/pdcp_process.c
Quoted 9 lines
false);
lib/pdcp/pdcp_process.c new file +8
-0+ } + } + + *nb_err = num - nb_cop; +return nb_cop; +cop_free: +/* Using mempool API since crypto API is not providing bulk free */ + rte_mempool_put_bulk(en_priv->cop_pool, (void *)&cop[i], nb_cop- i);
lib/pdcp/pdcp_process.c
Quoted 6 lines
lib/pdcp/pdcp_process.c new file +6
-0+ *nb_err = num - i; +return i; +} + +static inline bool +pdcp_pre_process_uplane_sn_18_ul_set_sn(struct entity_priv *en_priv,struct
Quoted 19 lines
rte_mbuf*mb,lib/pdcp/pdcp_process.c new file +8
-0+ uint32_t *count) +{ +struct rte_pdcp_up_data_pdu_sn_18_hdr *pdu_hdr; +const uint8_t hdr_sz = en_priv->hdr_sz; +uint32_t sn; + +/* Prepend PDU header */ + pdu_hdr = (struct rte_pdcp_up_data_pdu_sn_18_hdr*)rte_pktmbuf_prepend(mb,
hdr_sz);lib/pdcp/pdcp_process.c new file +5
-0+if (unlikely (pdu_hdr ==NULL )) +return false; + +/* Update sequence num in the PDU header */ + *count = __atomic_fetch_add(&en_priv->state.tx_next, 1,
__ATOMIC_RELAXED);lib/pdcp/pdcp_process.c new file +3
-0+ sn =PDCP_GET_SN_18_FROM_COUNT (*count); + + pdu_hdr->d_c =PDCP_PDU_TYPE_DATA ;lib/pdcp/pdcp_process.c
Quoted 10 lines
lib/pdcp/pdcp_process.c new file +10
-0+ pdu_hdr->sn_17_16 = ((sn &0x30000 ) >>16 ); + pdu_hdr->sn_15_8 = ((sn &0xff00 ) >>8 ); + pdu_hdr->sn_7_0 = (sn &0xff ); + pdu_hdr->r =0 ; + +return true; +} + +static inline uint16_t +pdcp_pre_process_uplane_sn_18_ul(const struct rte_pdcp_entity*entity,
Quoted 24 lines
struct
rte_mbuf*mb[],lib/pdcp/pdcp_process.c new file +1
-0+ struct rte_crypto_op *cop[], uint16_t num,
uint16_t*nb_err)lib/pdcp/pdcp_process.c new file +9
-0+{ +struct entity_priv *en_priv =entity_priv_get (entity); +uint16_t nb_cop; +uint32_t count; +int i; + +const uint8_t data_offset = en_priv->hdr_sz + en_priv->aad_sz; + + nb_cop = rte_crypto_op_bulk_alloc(en_priv->cop_pool,
RTE_CRYPTO_OP_TYPE_SYMMETRIC, cop,lib/pdcp/pdcp_process.c new file +5
-0+ num); + +if (en_priv->flags.is_authenticated) { +for (i =0 ; i < nb_cop; i++) { + if (unlikely(rte_pktmbuf_append(mb[i],
PDCP_MAC_I_LEN) == NULL))lib/pdcp/pdcp_process.c new file +2
-0+ goto cop_free; + if(unlikely(!pdcp_pre_process_uplane_sn_18_ul_set_sn(en_priv, mb[i], +
&count)))lib/pdcp/pdcp_process.c
Quoted 2 lines
lib/pdcp/pdcp_process.c new file +2
-0+ goto cop_free; + cop_prepare(en_priv, mb[i], cop[i], data_offset,count,
lib/pdcp/pdcp_process.c
Quoted 10 lines
true);
lib/pdcp/pdcp_process.c new file +4
-0+ } + }else { +for (i =0 ; i < nb_cop; i++) { + if(unlikely(!pdcp_pre_process_uplane_sn_18_ul_set_sn(en_priv, mb[i], +
&count)))lib/pdcp/pdcp_process.c new file +2
-0+ goto cop_free; + cop_prepare(en_priv, mb[i], cop[i], data_offset,count,
lib/pdcp/pdcp_process.c
Quoted 10 lines
false);
lib/pdcp/pdcp_process.c new file +9
-0+ } + } + + *nb_err = num - nb_cop; +return nb_cop; + +cop_free: +/* Using mempool API since crypto API is not providing bulk free */ + rte_mempool_put_bulk(en_priv->cop_pool, (void *)&cop[i], nb_cop- i);
lib/pdcp/pdcp_process.c
Quoted 6 lines
lib/pdcp/pdcp_process.c new file +6
-0+ *nb_err = num - i; +return i; +} + +static uint16_t +pdcp_pre_process_cplane_sn_12_ul(const struct rte_pdcp_entity*entity,
Quoted 23 lines
struct
rte_mbuf*mb[],lib/pdcp/pdcp_process.c new file +1
-0+ struct rte_crypto_op *cop[], uint16_t num,
uint16_t*nb_err)lib/pdcp/pdcp_process.c new file +11
-0+{ +struct entity_priv *en_priv =entity_priv_get (entity); +struct rte_pdcp_cp_data_pdu_sn_12_hdr *pdu_hdr; +uint32_t count, sn; +uint16_t nb_cop; +int i; + +const uint8_t hdr_sz = en_priv->hdr_sz; +const uint8_t data_offset = hdr_sz + en_priv->aad_sz; + + nb_cop = rte_crypto_op_bulk_alloc(en_priv->cop_pool,
RTE_CRYPTO_OP_TYPE_SYMMETRIC, cop,lib/pdcp/pdcp_process.c new file +5
-0+ num); + +for (i =0 ; i < nb_cop; i++) { +/* Prepend PDU header */ + pdu_hdr = (struct rte_pdcp_cp_data_pdu_sn_12_hdr*)rte_pktmbuf_prepend(mb[i],
+hdr_sz);lib/pdcp/pdcp_process.c
Quoted 3 lines
lib/pdcp/pdcp_process.c new file +3
-0+if (unlikely (pdu_hdr ==NULL )) + goto cop_free; + if (unlikely(rte_pktmbuf_append(mb[i], PDCP_MAC_I_LEN)==
lib/pdcp/pdcp_process.c
Quoted 13 lines
NULL))
lib/pdcp/pdcp_process.c new file +4
-0+ goto cop_free; + +/* Update sequence number in the PDU header */ + count = __atomic_fetch_add(&en_priv->state.tx_next, 1,
__ATOMIC_RELAXED);lib/pdcp/pdcp_process.c new file +7
-0+ sn =PDCP_GET_SN_12_FROM_COUNT (count); + + pdu_hdr->sn_11_8 = ((sn &0xf00 ) >>8 ); + pdu_hdr->sn_7_0 = (sn &0xff ); + pdu_hdr->r =0 ; + + cop_prepare(en_priv, mb[i], cop[i], data_offset, count,true);
lib/pdcp/pdcp_process.c
Quoted 8 lines
lib/pdcp/pdcp_process.c new file +8
-0+ } + + *nb_err = num - nb_cop; +return nb_cop; + +cop_free: +/* Using mempool API since crypto API is not providing bulk free */ + rte_mempool_put_bulk(en_priv->cop_pool, (void *)&cop[i], nb_cop- i);
lib/pdcp/pdcp_process.c
Quoted 6 lines
lib/pdcp/pdcp_process.c new file +6
-0+ *nb_err = num - i; +return i; +} + +static uint16_t +pdcp_post_process_uplane_sn_12_ul(const struct rte_pdcp_entity*entity,
Quoted 27 lines
lib/pdcp/pdcp_process.c new file +13
-0+struct rte_mbuf *in_mb[], + struct rte_mbuf *out_mb[], + uint16_t num, uint16_t *nb_err_ret) +{ + struct entity_priv *en_priv = entity_priv_get(entity); +const uint32_t hdr_trim_sz = en_priv->aad_sz; +int i, nb_success =0 , nb_err =0 ; +struct rte_mbuf *err_mb[num]; +struct rte_mbuf *mb; + +for (i =0 ; i < num; i++) { + mb = in_mb[i]; + if (unlikely(mb->ol_flags &
RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED)) {lib/pdcp/pdcp_process.c new file +12
-0+ err_mb[nb_err++] = mb; +continue ; + } + +if (hdr_trim_sz) +rte_pktmbuf_adj (mb, hdr_trim_sz); + + out_mb[nb_success++] = mb; + } + +if (unlikely (nb_err !=0 )) + rte_memcpy(&out_mb[nb_success], err_mb, nb_err *
sizeof(struct rte_mbuf *));lib/pdcp/pdcp_process.c
Quoted 7 lines
lib/pdcp/pdcp_process.c new file +7
-0+ + *nb_err_ret = nb_err; +return nb_success; +} + +static uint16_t +pdcp_post_process_uplane_sn_18_ul(const struct rte_pdcp_entity*entity,
Quoted 27 lines
lib/pdcp/pdcp_process.c new file +13
-0+struct rte_mbuf *in_mb[], + struct rte_mbuf *out_mb[], + uint16_t num, uint16_t *nb_err_ret) +{ + struct entity_priv *en_priv = entity_priv_get(entity); +const uint32_t hdr_trim_sz = en_priv->aad_sz; +int i, nb_success =0 , nb_err =0 ; +struct rte_mbuf *err_mb[num]; +struct rte_mbuf *mb; + +for (i =0 ; i < num; i++) { + mb = in_mb[i]; + if (unlikely(mb->ol_flags &
RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED)) {lib/pdcp/pdcp_process.c new file +12
-0+ err_mb[nb_err++] = mb; +continue ; + } + +if (hdr_trim_sz) +rte_pktmbuf_adj (mb, hdr_trim_sz); + + out_mb[nb_success++] = mb; + } + +if (unlikely (nb_err !=0 )) + rte_memcpy(&out_mb[nb_success], err_mb, nb_err *
sizeof(struct rte_mbuf *));lib/pdcp/pdcp_process.c
Quoted 7 lines
lib/pdcp/pdcp_process.c new file +7
-0+ + *nb_err_ret = nb_err; +return nb_success; +} + +static uint16_t +pdcp_post_process_cplane_sn_12_ul(const struct rte_pdcp_entity*entity,
Quoted 44 lines
lib/pdcp/pdcp_process.c new file +12
-0+struct rte_mbuf *in_mb[], + struct rte_mbuf *out_mb[], + uint16_t num, uint16_t *nb_err_ret) +{ + struct entity_priv *en_priv = entity_priv_get(entity); +const uint32_t hdr_trim_sz = en_priv->aad_sz; +int i, nb_success =0 , nb_err =0 ; +struct rte_mbuf *mb, *err_mb[num]; + +for (i =0 ; i < num; i++) { + mb = in_mb[i]; + if (unlikely(mb->ol_flags &
RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED)) {lib/pdcp/pdcp_process.c new file +12
-0+ err_mb[nb_err++] = mb; +continue ; + } + +if (hdr_trim_sz) +rte_pktmbuf_adj (mb, hdr_trim_sz); + + out_mb[nb_success++] = mb; + } + +if (unlikely (nb_err !=0 )) + rte_memcpy(&out_mb[nb_success], err_mb, nb_err *
sizeof(struct rte_mbuf *));lib/pdcp/pdcp_process.c new file +7
-0+ + *nb_err_ret = nb_err; +return nb_success; +} + +static inline int +pdcp_sn_18_count_get(const struct rte_pdcp_entity *entity, int32_t rsn,
uint32_t*count)lib/pdcp/pdcp_process.c new file +5
-0+{ +struct entity_priv *en_priv =entity_priv_get (entity); +uint32_t rhfn, rx_deliv; + + rx_deliv = __atomic_load_n(&en_priv->state.rx_deliv,
__ATOMIC_RELAXED);lib/pdcp/pdcp_process.c new file +3
-0+ rhfn =PDCP_GET_HFN_SN_18_FROM_COUNT (rx_deliv); + + if (rsn < (int32_t)(PDCP_GET_SN_18_FROM_COUNT(rx_deliv) -
PDCP_SN_18_WINDOW_SZ)) {lib/pdcp/pdcp_process.c
Quoted 4 lines
lib/pdcp/pdcp_process.c new file +4
-0+if (unlikely (rhfn ==PDCP_SN_18_HFN_MAX )) +return -ERANGE ; + rhfn +=1 ; + } else if ((uint32_t)rsn >=(
PDCP_GET_SN_18_FROM_COUNT(rx_deliv)+Quoted 24 lines
PDCP_SN_18_WINDOW_SZ)) {lib/pdcp/pdcp_process.c new file +12
-0+if (unlikely (rhfn ==PDCP_SN_18_HFN_MIN )) +return -ERANGE ; + rhfn -=1 ; + } + + *count =PDCP_SET_COUNT_FROM_HFN_SN_18 (rhfn, rsn); + +return 0 ; +} + +static inline int +pdcp_sn_12_count_get(const struct rte_pdcp_entity *entity, int32_t rsn,
uint32_t*count)lib/pdcp/pdcp_process.c new file +5
-0+{ +struct entity_priv *en_priv =entity_priv_get (entity); +uint32_t rhfn, rx_deliv; + + rx_deliv = __atomic_load_n(&en_priv->state.rx_deliv,
__ATOMIC_RELAXED);lib/pdcp/pdcp_process.c new file +3
-0+ rhfn =PDCP_GET_HFN_SN_12_FROM_COUNT (rx_deliv); + + if (rsn < (int32_t)(PDCP_GET_SN_12_FROM_COUNT(rx_deliv) -
PDCP_SN_12_WINDOW_SZ)) {lib/pdcp/pdcp_process.c
Quoted 4 lines
lib/pdcp/pdcp_process.c new file +4
-0+if (unlikely (rhfn ==PDCP_SN_12_HFN_MAX )) +return -ERANGE ; + rhfn +=1 ; + } else if ((uint32_t)rsn >=(
PDCP_GET_SN_12_FROM_COUNT(rx_deliv)+Quoted 14 lines
PDCP_SN_12_WINDOW_SZ)) {lib/pdcp/pdcp_process.c new file +12
-0+if (unlikely (rhfn ==PDCP_SN_12_HFN_MIN )) +return -ERANGE ; + rhfn -=1 ; + } + + *count =PDCP_SET_COUNT_FROM_HFN_SN_12 (rhfn, rsn); + +return 0 ; +} + +static inline uint16_t +pdcp_pre_process_uplane_sn_12_dl_flags(const struct rte_pdcp_entity*entity, struct
rte_mbuf*mb[],lib/pdcp/pdcp_process.c
Quoted 1 line
lib/pdcp/pdcp_process.c new file +1
-0+struct rte_crypto_op *cop[], uint16_tnum,
Quoted 32 lines
uint16_t*nb_err,lib/pdcp/pdcp_process.c new file +12
-0+ const bool is_integ_protected) +{ +struct entity_priv *en_priv =entity_priv_get (entity); +struct rte_pdcp_up_data_pdu_sn_12_hdr *pdu_hdr; +uint16_t nb_cop; +int32_t rsn =0 ; +uint32_t count; +int i; + +const uint8_t data_offset = en_priv->hdr_sz + en_priv->aad_sz; + + nb_cop = rte_crypto_op_bulk_alloc(en_priv->cop_pool,
RTE_CRYPTO_OP_TYPE_SYMMETRIC, cop,lib/pdcp/pdcp_process.c new file +5
-0+ num); + +for (i =0 ; i < nb_cop; i++) { + + pdu_hdr = rte_pktmbuf_mtod(mb[i], struct
rte_pdcp_up_data_pdu_sn_12_hdr*);lib/pdcp/pdcp_process.c new file +4
-0+ +/* Check for PDU type */ +if (likely (pdu_hdr->d_c ==PDCP_PDU_TYPE_DATA )) + rsn = ((pdu_hdr->sn_11_8 << 8) | (pdu_hdr-
sn_7_0));lib/pdcp/pdcp_process.c new file +6
-0+else +rte_panic ("TODO: Control PDU not handled" ); + +if (unlikely (pdcp_sn_12_count_get (entity, rsn, &count))) +break ; + cop_prepare(en_priv, mb[i], cop[i], data_offset, count,
is_integ_protected);lib/pdcp/pdcp_process.c
Quoted 9 lines
lib/pdcp/pdcp_process.c new file +9
-0+ } + + *nb_err = num - nb_cop; + +return nb_cop; +} + +static uint16_t +pdcp_pre_process_uplane_sn_12_dl_ip(const struct rte_pdcp_entity*entity,
lib/pdcp/pdcp_process.c
Quoted 5 lines
struct
rte_mbuf*mb[],lib/pdcp/pdcp_process.c new file +1
-0+ struct rte_crypto_op *cop[], uint16_t num,
uint16_t*nb_err)lib/pdcp/pdcp_process.c new file +2
-0+{ + return pdcp_pre_process_uplane_sn_12_dl_flags(entity, mb, cop,num,
lib/pdcp/pdcp_process.c
Quoted 5 lines
nb_err, true);lib/pdcp/pdcp_process.c new file +4
-0+} + +static uint16_t +pdcp_pre_process_uplane_sn_12_dl(const struct rte_pdcp_entity*entity,
lib/pdcp/pdcp_process.c
Quoted 5 lines
struct
rte_mbuf*mb[],lib/pdcp/pdcp_process.c new file +1
-0+ struct rte_crypto_op *cop[], uint16_t num,
uint16_t*nb_err)lib/pdcp/pdcp_process.c new file +2
-0+{ + return pdcp_pre_process_uplane_sn_12_dl_flags(entity, mb, cop,num,
lib/pdcp/pdcp_process.c
Quoted 7 lines
nb_err, false);lib/pdcp/pdcp_process.c new file +4
-0+} + +static inline uint16_t +pdcp_pre_process_uplane_sn_18_dl_flags(const struct rte_pdcp_entity*entity, struct
rte_mbuf*mb[],lib/pdcp/pdcp_process.c new file +1
-0+struct rte_crypto_op *cop[], uint16_tnum,
Quoted 32 lines
uint16_t*nb_err,lib/pdcp/pdcp_process.c new file +11
-0+ const bool is_integ_protected) +{ +struct entity_priv *en_priv =entity_priv_get (entity); +struct rte_pdcp_up_data_pdu_sn_18_hdr *pdu_hdr; +uint16_t nb_cop; +int32_t rsn =0 ; +uint32_t count; +int i; + +const uint8_t data_offset = en_priv->hdr_sz + en_priv->aad_sz; + nb_cop = rte_crypto_op_bulk_alloc(en_priv->cop_pool,
RTE_CRYPTO_OP_TYPE_SYMMETRIC, cop,lib/pdcp/pdcp_process.c new file +4
-0+ num); + +for (i =0 ; i < nb_cop; i++) { + pdu_hdr = rte_pktmbuf_mtod(mb[i], struct
rte_pdcp_up_data_pdu_sn_18_hdr*);lib/pdcp/pdcp_process.c new file +4
-0+ +/* Check for PDU type */ +if (likely (pdu_hdr->d_c ==PDCP_PDU_TYPE_DATA )) + rsn = ((pdu_hdr->sn_17_16 << 16) | (pdu_hdr-
sn_15_8
<< 8) |lib/pdcp/pdcp_process.c new file +7
-0+ (pdu_hdr->sn_7_0)); + else + rte_panic("TODO: Control PDU not handled"); + +if (unlikely (pdcp_sn_18_count_get (entity, rsn, &count))) +break ; + cop_prepare(en_priv, mb[i], cop[i], data_offset, count,
is_integ_protected);lib/pdcp/pdcp_process.c
Quoted 9 lines
lib/pdcp/pdcp_process.c new file +9
-0+ } + + *nb_err = num - nb_cop; + +return nb_cop; +} + +static uint16_t +pdcp_pre_process_uplane_sn_18_dl_ip(const struct rte_pdcp_entity*entity,
lib/pdcp/pdcp_process.c
Quoted 5 lines
struct
rte_mbuf*mb[],lib/pdcp/pdcp_process.c new file +1
-0+ struct rte_crypto_op *cop[], uint16_t num,
uint16_t*nb_err)lib/pdcp/pdcp_process.c new file +2
-0+{ + return pdcp_pre_process_uplane_sn_18_dl_flags(entity, mb, cop,num,
lib/pdcp/pdcp_process.c
Quoted 5 lines
nb_err, true);lib/pdcp/pdcp_process.c new file +4
-0+} + +static uint16_t +pdcp_pre_process_uplane_sn_18_dl(const struct rte_pdcp_entity*entity,
lib/pdcp/pdcp_process.c
Quoted 5 lines
struct
rte_mbuf*mb[],lib/pdcp/pdcp_process.c new file +1
-0+ struct rte_crypto_op *cop[], uint16_t num,
uint16_t*nb_err)lib/pdcp/pdcp_process.c new file +2
-0+{ + return pdcp_pre_process_uplane_sn_18_dl_flags(entity, mb, cop,num,
lib/pdcp/pdcp_process.c
Quoted 5 lines
nb_err, false);lib/pdcp/pdcp_process.c new file +4
-0+} + +static uint16_t +pdcp_pre_process_cplane_sn_12_dl(const struct rte_pdcp_entity*entity,
Quoted 20 lines
struct
rte_mbuf*mb[],lib/pdcp/pdcp_process.c new file +1
-0+ struct rte_crypto_op *cop[], uint16_t num,
uint16_t*nb_err)lib/pdcp/pdcp_process.c new file +11
-0+{ +struct entity_priv *en_priv =entity_priv_get (entity); +struct rte_pdcp_cp_data_pdu_sn_12_hdr *pdu_hdr; +uint16_t nb_cop; +uint32_t count; +int32_t rsn; +int i; + +const uint8_t data_offset = en_priv->hdr_sz + en_priv->aad_sz; + + nb_cop = rte_crypto_op_bulk_alloc(en_priv->cop_pool,
RTE_CRYPTO_OP_TYPE_SYMMETRIC, cop,lib/pdcp/pdcp_process.c new file +4
-0+ num); + +for (i =0 ; i < nb_cop; i++) { + pdu_hdr = rte_pktmbuf_mtod(mb[i], struct
rte_pdcp_cp_data_pdu_sn_12_hdr*);lib/pdcp/pdcp_process.c
Quoted 4 lines
lib/pdcp/pdcp_process.c new file +4
-0+ rsn = ((pdu_hdr->sn_11_8 <<8 ) | (pdu_hdr->sn_7_0)); +if (unlikely (pdcp_sn_12_count_get (entity, rsn, &count))) +break ; + cop_prepare(en_priv, mb[i], cop[i], data_offset, count,true);
lib/pdcp/pdcp_process.c
Quoted 8 lines
lib/pdcp/pdcp_process.c new file +8
-0+ } + + *nb_err = num - nb_cop; +return nb_cop; +} + +static inline bool +pdcp_post_process_update_entity_state(const struct rte_pdcp_entity*entity,
Quoted 83 lines
lib/pdcp/pdcp_process.c new file +5
-0+ const uint32_t count) +{ + struct entity_priv *en_priv = entity_priv_get(entity); + + if (count < __atomic_load_n(&en_priv->state.rx_deliv,
__ATOMIC_RELAXED))lib/pdcp/pdcp_process.c new file +3
-0+return false; + +/* t-Reordering timer is not supported - SDU will be delivered immediately.
lib/pdcp/pdcp_process.c new file +1
-0+* Update RX_DELIV to the COUNT value of the first PDCP SDU which has not
lib/pdcp/pdcp_process.c new file +3
-0+* been delivered to upper layers +*/ + __atomic_store_n(&en_priv->state.rx_deliv, (count + 1),
__ATOMIC_RELAXED);lib/pdcp/pdcp_process.c new file +2
-0+ + if (count >= __atomic_load_n(&en_priv->state.rx_next,
__ATOMIC_RELAXED))lib/pdcp/pdcp_process.c new file +1
-0+ __atomic_store_n(&en_priv->state.rx_next, (count + 1),
__ATOMIC_RELAXED);lib/pdcp/pdcp_process.c new file +6
-0+ +return true; +} + +static inline uint16_t +pdcp_post_process_uplane_sn_12_dl_flags(const struct rte_pdcp_entity*entity,
lib/pdcp/pdcp_process.c new file +18
-0+struct rte_mbuf *in_mb[], + struct rte_mbuf *out_mb[], + uint16_t num, uint16_t *nb_err_ret, + const bool is_integ_protected) +{ + struct entity_priv *en_priv = entity_priv_get(entity); +struct rte_pdcp_up_data_pdu_sn_12_hdr *pdu_hdr; +int i, nb_success =0 , nb_err =0 , rsn =0 ; +const uint32_t aad_sz = en_priv->aad_sz; +struct rte_mbuf *err_mb[num]; +struct rte_mbuf *mb; +uint32_t count; + +const uint32_t hdr_trim_sz = en_priv->hdr_sz + aad_sz; + +for (i =0 ; i < num; i++) { + mb = in_mb[i]; + if (unlikely(mb->ol_flags &
RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED))lib/pdcp/pdcp_process.c new file +2
-0+ goto error; + pdu_hdr = rte_pktmbuf_mtod_offset(mb, struct
rte_pdcp_up_data_pdu_sn_12_hdr*,lib/pdcp/pdcp_process.c new file +5
-0+ aad_sz); + +/* Check for PDU type */ +if (likely (pdu_hdr->d_c ==PDCP_PDU_TYPE_DATA )) + rsn = ((pdu_hdr->sn_11_8 << 8) | (pdu_hdr-
sn_7_0));lib/pdcp/pdcp_process.c new file +7
-0+ else + rte_panic("Control PDU should not be received"); + +if (unlikely (pdcp_sn_12_count_get (entity, rsn, &count))) + goto error; + + if (unlikely(!pdcp_post_process_update_entity_state(entity,count)))
lib/pdcp/pdcp_process.c new file +14
-0+ goto error; + +rte_pktmbuf_adj (mb, hdr_trim_sz); +if (is_integ_protected) +rte_pktmbuf_trim (mb,PDCP_MAC_I_LEN ); + out_mb[nb_success++] = mb; +continue ; + +error: + err_mb[nb_err++] = mb; + } + +if (unlikely (nb_err !=0 )) + rte_memcpy(&out_mb[nb_success], err_mb, nb_err *
sizeof(struct rte_mbuf *));lib/pdcp/pdcp_process.c line 567
Quoted 3 lines
lib/pdcp/pdcp_process.c new file +3
-0+ + *nb_err_ret = nb_err; +return nb_success;*entity,
lib/pdcp/pdcp_process.c
Quoted 10 lines
lib/pdcp/pdcp_process.c new file +5
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
out_mb, num,nb_err, true);lib/pdcp/pdcp_process.c new file +4
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
*entity,
lib/pdcp/pdcp_process.c
Quoted 72 lines
lib/pdcp/pdcp_process.c new file +5
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
out_mb, num,nb_err, false);lib/pdcp/pdcp_process.c new file +4
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
*entity,
lib/pdcp/pdcp_process.c new file +18
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED))lib/pdcp/pdcp_process.c new file +3
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
rte_pdcp_up_data_pdu_sn_18_hdr*,lib/pdcp/pdcp_process.c new file +5
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
sn_15_8
<< 8) |lib/pdcp/pdcp_process.c new file +8
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
count)))
lib/pdcp/pdcp_process.c new file +14
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
sizeof(struct rte_mbuf *));lib/pdcp/pdcp_process.c new file +7
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
*entity,
lib/pdcp/pdcp_process.c
Quoted 10 lines
lib/pdcp/pdcp_process.c new file +5
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
out_mb, num,nb_err, true);lib/pdcp/pdcp_process.c new file +4
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
*entity,
lib/pdcp/pdcp_process.c
Quoted 10 lines
lib/pdcp/pdcp_process.c new file +5
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
out_mb, num,nb_err, false);lib/pdcp/pdcp_process.c new file +4
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
*entity,
lib/pdcp/pdcp_process.c
Quoted 62 lines
lib/pdcp/pdcp_process.c new file +18
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED))lib/pdcp/pdcp_process.c new file +3
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
rte_pdcp_cp_data_pdu_sn_12_hdr*,lib/pdcp/pdcp_process.c new file +7
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
count)))
lib/pdcp/pdcp_process.c new file +13
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
sizeof(struct rte_mbuf *));lib/pdcp/pdcp_process.c new file +7
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
rte_pdcp_entity_conf*conf)lib/pdcp/pdcp_process.c new file +7
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
RTE_SECURITY_PDCP_MODE_CONTROL) &&lib/pdcp/pdcp_process.c new file +1
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
&&
lib/pdcp/pdcp_process.c
Quoted 3 lines
lib/pdcp/pdcp_process.c new file +3
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
pdcp_post_process_cplane_sn_12_ul;lib/pdcp/pdcp_process.c
Quoted 5 lines
lib/pdcp/pdcp_process.c new file +3
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
RTE_SECURITY_PDCP_MODE_CONTROL) &&lib/pdcp/pdcp_process.c new file +1
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
&&
lib/pdcp/pdcp_process.c
Quoted 3 lines
lib/pdcp/pdcp_process.c new file +3
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
pdcp_post_process_cplane_sn_12_dl;lib/pdcp/pdcp_process.c
Quoted 3 lines
lib/pdcp/pdcp_process.c new file +3
-0Lines of this file are not shown. View the raw message.
The rest of this diff is not shown. View the raw message.
RTE_SECURITY_PDCP_MODE_DATA)384 lines not shown · raw message
Quoted 8 lines
7 lines not shown · raw message
474 lines not shown · raw message
Parts of this message are not shown here. View the raw message.
PATCH 3/5 app/test: add lib pdcp tests
In reply to Anoob JosephAdd tests to verify lib PDCP operations. Tests leverage existing PDCP test vectors.
--- app/test/meson.build | 1 + app/test/test_cryptodev.h | 3 + app/test/test_pdcp.c | 663 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 667 insertions(+) create mode 100644 app/test/test_pdcp.c
app/test/meson.build +1 -0
@@ -95,6 +95,7 @@ test_sources = files( 'test_meter.c', 'test_mcslock.c', 'test_mp_secondary.c', + 'test_pdcp.c', 'test_per_lcore.c', 'test_pflock.c', 'test_pmd_perf.c',
app/test/test_cryptodev.h +3 -0
@@ -4,6 +4,9 @@#ifndef TEST_CRYPTODEV_H_ #define TEST_CRYPTODEV_H_ +#include <rte_crypto.h> +#include <rte_cryptodev.h> +#define HEX_DUMP 0#define FALSE 0
app/test/test_pdcp.c new file +663 -0
663 lines not on this page · raw message
Signature · 1 line
2.25.1
PATCH 4/5 app/test: pdcp HFN tests in combined mode
In reply to Anoob JosephFrom: Volodymyr Fialko <[email protected]>
Add tests to verify HFN/SN behaviour.
--- app/test/test_pdcp.c | 390 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 363 insertions(+), 27 deletions(-)
app/test/test_pdcp.c +363 -27
@@ -4,6 +4,7 @@#include <rte_malloc.h> #include <rte_pdcp.h> +#include <rte_pdcp_hdr.h> #include "test.h" #include "test_cryptodev.h"
@@ -19,17 +20,17 @@ struct pdcp_testsuite_params {static struct pdcp_testsuite_params testsuite_params; -#define PDCP_MAX_TEST_INPUT_LEN 2048 +#define PDCP_MAX_TEST_DATA_LEN 2048struct pdcp_test_conf {struct rte_pdcp_entity_conf entity;struct rte_crypto_sym_xform c_xfrm;struct rte_crypto_sym_xform a_xfrm;bool is_integrity_protected; -uint8_t input[PDCP_MAX_TEST_INPUT_LEN ]; +uint8_t input[PDCP_MAX_TEST_DATA_LEN ];uint32_t input_len; -const uint8_t *expected; -uint32_t expected_len; +uint8_t output[PDCP_MAX_TEST_DATA_LEN ]; +uint32_t output_len; }; static inline int
@@ -38,6 +39,19 @@ pdcp_hdr_size_get(enum rte_security_pdcp_sn_size sn_size)return RTE_ALIGN_MUL_CEIL (sn_size,8 ) /8 ; } +static int +pktmbuf_read_into (const struct rte_mbuf *m,void *buf,size_t buf_len) +{ +if (m->pkt_len > buf_len) +return -ENOMEM ; + +const void *read =rte_pktmbuf_read (m,0 , m->pkt_len, buf); +if (read !=NULL && read != buf) +memcpy (buf, read, m->pkt_len); + +return 0 ; +} +static int cryptodev_init (int dev_id) {
@@ -300,14 +314,45 @@ process_crypto_request(uint8_t dev_id, struct rte_crypto_op *op)return op; } +static uint32_t +pdcp_sn_from_raw_get (const void *data,enum rte_security_pdcp_sn_size size) +{ +uint32_t sn =0 ; + +if (size ==RTE_SECURITY_PDCP_SN_SIZE_12 ) { + sn =rte_cpu_to_be_16 (*(const uint16_t *)data); + sn = sn &0xfff ; + }else if (size ==RTE_SECURITY_PDCP_SN_SIZE_18 ) { + sn =rte_cpu_to_be_32 (*(const uint32_t *)data); + sn = (sn &0x3ffff00 ) >>8 ; + } + +return sn; +} + +static void +pdcp_sn_to_raw_set (void *data,uint32_t sn,int size) +{ +if (size ==RTE_SECURITY_PDCP_SN_SIZE_12 ) { +struct rte_pdcp_up_data_pdu_sn_12_hdr *pdu_hdr = data; + pdu_hdr->sn_11_8 = ((sn &0xf00 ) >>8 ); + pdu_hdr->sn_7_0 = (sn &0xff ); + }else if (size ==RTE_SECURITY_PDCP_SN_SIZE_18 ) { +struct rte_pdcp_up_data_pdu_sn_18_hdr *pdu_hdr = data; + pdu_hdr->sn_17_16 = ((sn &0x30000 ) >>16 ); + pdu_hdr->sn_15_8 = ((sn &0xff00 ) >>8 ); + pdu_hdr->sn_7_0 = (sn &0xff ); + } +} +static int create_test_conf_from_index (const int index,struct pdcp_test_conf *conf) {const struct pdcp_testsuite_params *ts_params = &testsuite_params;struct rte_crypto_sym_xform c_xfrm, a_xfrm; -uint32_t hfn, sn, count =0 ; +uint32_t hfn, sn, expected_len, count =0 ; +uint8_t *data, *expected;int pdcp_hdr_sz; -uint8_t *data;memset (conf,0 ,sizeof (*conf));memset (&c_xfrm,0 ,sizeof (c_xfrm));
@@ -326,6 +371,7 @@ create_test_conf_from_index(const int index, struct pdcp_test_conf *conf) conf->entity.pdcp_xfrm.pkt_dir =RTE_SECURITY_PDCP_DOWNLINK ; conf->entity.pdcp_xfrm.sn_size = pdcp_test_data_sn_size[index]; +/* Zero initialize unsupported flags */ conf->entity.pdcp_xfrm.hfn_threshold =0 ; conf->entity.pdcp_xfrm.hfn_ovrd =0 ; conf->entity.pdcp_xfrm.sdap_enabled =0 ;
@@ -414,14 +460,7 @@ create_test_conf_from_index(const int index, struct pdcp_test_conf *conf) pdcp_test_params[index].domain == RTE_SECURITY_PDCP_MODE_DATA) { data = pdcp_test_data_in[index]; hfn = pdcp_test_hfn[index] << pdcp_test_data_sn_size[index]; - sn =0 ; -if (pdcp_test_data_sn_size[index] ==RTE_SECURITY_PDCP_SN_SIZE_12 ) { - sn =rte_cpu_to_be_16 (*(uint16_t *)data); - sn = sn &0xfff ; - }else if (pdcp_test_data_sn_size[index] ==RTE_SECURITY_PDCP_SN_SIZE_18 ) { - sn =rte_cpu_to_be_32 (*(uint32_t *)data); - sn = (sn &0x3ffff00 ) >>8 ; - } + sn =pdcp_sn_from_raw_get (data, pdcp_test_data_sn_size[index]); count = hfn | sn; } conf->entity.count = count;
@@ -448,29 +487,32 @@ create_test_conf_from_index(const int index, struct pdcp_test_conf *conf) }if (conf->entity.pdcp_xfrm.pkt_dir ==RTE_SECURITY_PDCP_UPLINK ) - conf->expected = pdcp_test_data_out[index]; + expected = pdcp_test_data_out[index];else - conf->expected = pdcp_test_data_in[index]; + expected = pdcp_test_data_in[index];/* Calculate expected packet length */ - conf->expected_len = pdcp_test_data_in_len[index]; + expected_len = pdcp_test_data_in_len[index];/* In DL processing, PDCP header would be stripped */ if (conf->entity.pdcp_xfrm.pkt_dir ==RTE_SECURITY_PDCP_DOWNLINK ) { - conf->expected += pdcp_hdr_sz; - conf->expected_len -= pdcp_hdr_sz; + expected += pdcp_hdr_sz; + expected_len -= pdcp_hdr_sz; }/* In UL processing with integrity protection, MAC would be added */ if (conf->is_integrity_protected && conf->entity.pdcp_xfrm.pkt_dir ==RTE_SECURITY_PDCP_UPLINK ) - conf->expected_len +=4 ; + expected_len +=4 ; + +memcpy (conf->output, expected, expected_len); + conf->output_len = expected_len;return 0 ; }static int -test_attempt_single (const struct pdcp_test_conf *t_conf) +test_attempt_single (struct pdcp_test_conf *t_conf) {const struct pdcp_testsuite_params *ts_params = &testsuite_params;struct rte_mbuf *mbuf, *mb, **out_mb =NULL ;
@@ -584,9 +626,17 @@ test_attempt_single(const struct pdcp_test_conf *t_conf) goto mbuf_free; } - ret =pdcp_known_vec_verify (mbuf, t_conf->expected, t_conf->expected_len); -if (ret) - goto mbuf_free; +/* If expected output provided - verify, else - store for future use */ +if (t_conf->output_len) { + ret =pdcp_known_vec_verify (mbuf, t_conf->output, t_conf->output_len); +if (ret) + goto mbuf_free; + }else { + ret =pktmbuf_read_into (mbuf, t_conf->output,PDCP_MAX_TEST_DATA_LEN ); +if (ret) + goto mbuf_free; + t_conf->output_len = mbuf->pkt_len; + } ret =rte_pdcp_entity_suspend (pdcp_entity, out_mb);if (ret) {
@@ -609,6 +659,195 @@ test_attempt_single(const struct pdcp_test_conf *t_conf)return TEST_FAILED ; } +static void +uplink_to_downlink_convert (const struct pdcp_test_conf *ul_cfg, +struct pdcp_test_conf *dl_cfg) +{ +assert (ul_cfg->entity.pdcp_xfrm.pkt_dir ==RTE_SECURITY_PDCP_UPLINK ); + +memcpy (dl_cfg, ul_cfg,sizeof (*dl_cfg)); + dl_cfg->entity.pdcp_xfrm.pkt_dir =RTE_SECURITY_PDCP_DOWNLINK ; + dl_cfg->entity.reverse_iv_direction = false; + +if (dl_cfg->is_integrity_protected) { + dl_cfg->entity.crypto_xfrm = &dl_cfg->c_xfrm; + + dl_cfg->c_xfrm.cipher.op =RTE_CRYPTO_CIPHER_OP_DECRYPT ; + dl_cfg->c_xfrm.next = &dl_cfg->a_xfrm; + + dl_cfg->a_xfrm.auth.op =RTE_CRYPTO_AUTH_OP_VERIFY ; + dl_cfg->a_xfrm.next =NULL ; + }else { + dl_cfg->entity.crypto_xfrm = &dl_cfg->c_xfrm; + dl_cfg->c_xfrm.next =NULL ; + dl_cfg->c_xfrm.cipher.op =RTE_CRYPTO_CIPHER_OP_DECRYPT ; + } + +memcpy (dl_cfg->input, ul_cfg->output, ul_cfg->output_len); + dl_cfg->input_len = ul_cfg->output_len; + +memcpy (dl_cfg->output, ul_cfg->input, ul_cfg->input_len); + dl_cfg->output_len = ul_cfg->input_len; +} + +/* +* According to ETSI TS 138 323 V17.1.0, Section 5.2.2.1, +* SN could be divided into following ranges, +* relatively to current value of RX_DELIV state: +* +-------------+-------------+-------------+-------------+ +* | -Outside | -Window | +Window | +Outside | +* | (valid) | (Invalid) | (Valid) | (Invalid) | +* +-------------+-------------^-------------+-------------+ +* | +* v +* SN(RX_DELIV) +*/ +enum sn_range_type { +SN_RANGE_MINUS_OUTSIDE , +SN_RANGE_MINUS_WINDOW , +SN_RANGE_PLUS_WINDOW , +SN_RANGE_PLUS_OUTSIDE , +}; + +#define PDCP_SET_COUNT (hfn, sn, size) ((hfn << size) | (sn & ((1 << size) - 1))) + +/* +* Take uplink test case as base, modify RX_DELIV in state and SN in input +*/ +static int +test_sn_range_type_with_config (enum sn_range_type type,struct pdcp_test_conf *conf) +{ +uint32_t rx_deliv_hfn, rx_deliv_sn, rx_deliv, new_hfn, new_sn; +const int domain = conf->entity.pdcp_xfrm.domain; +struct pdcp_test_conf dl_conf; +int ret, expected_ret; + +if (domain !=RTE_SECURITY_PDCP_MODE_CONTROL && domain !=RTE_SECURITY_PDCP_MODE_DATA ) +return TEST_SKIPPED ; + +const uint32_t sn_size = conf->entity.pdcp_xfrm.sn_size; +/* According to formula(7.2.a Window_Size) */ +const uint32_t window_size =1 << (sn_size -1 ); +/* Max value of SN that could fit in `sn_size` bits */ +const uint32_t max_sn = (1 << sn_size) -1 ; +const uint32_t shift = (max_sn - window_size) /2 ; +/* Could be any number up to `shift` value */ +const uint32_t default_sn =RTE_MIN (2u , shift); + +/* Initialize HFN as non zero value, to be able check values before */ + rx_deliv_hfn =0xa ; + +switch (type) { +case SN_RANGE_PLUS_WINDOW : +/* Within window size, HFN stay same */ + new_hfn = rx_deliv_hfn; + rx_deliv_sn = default_sn; + new_sn = rx_deliv_sn +1 ; + expected_ret =TEST_SUCCESS ; +break ; +case SN_RANGE_MINUS_WINDOW : +/* Within window size, HFN stay same */ + new_hfn = rx_deliv_hfn; + rx_deliv_sn = default_sn; + new_sn = rx_deliv_sn -1 ; + expected_ret =TEST_FAILED ; +break ; +case SN_RANGE_PLUS_OUTSIDE : +/* RCVD_SN >= SN(RX_DELIV) + Window_Size */ + new_hfn = rx_deliv_hfn -1 ; + rx_deliv_sn = default_sn; + new_sn = rx_deliv_sn + window_size; + expected_ret =TEST_FAILED ; +break ; +case SN_RANGE_MINUS_OUTSIDE : +/* RCVD_SN < SN(RX_DELIV) - Window_Size */ + new_hfn = rx_deliv_hfn +1 ; + rx_deliv_sn = window_size + default_sn; + new_sn = rx_deliv_sn - window_size -1 ; + expected_ret =TEST_SUCCESS ; +break ; +default : +return TEST_FAILED ; + } + + rx_deliv =PDCP_SET_COUNT (rx_deliv_hfn, rx_deliv_sn, sn_size); + +/* Configure Uplink to generate expected, encrypted packet */ +pdcp_sn_to_raw_set (conf->input, new_sn, conf->entity.pdcp_xfrm.sn_size); + conf->entity.reverse_iv_direction = true; + conf->entity.count =PDCP_SET_COUNT (new_hfn, new_sn, sn_size); + conf->output_len =0 ; + ret =test_attempt_single (conf); +if (ret !=TEST_SUCCESS ) +return ret; + +/* Flip configuration to downlink */ +uplink_to_downlink_convert (conf, &dl_conf); +/* Modify the rx_deliv to verify the expected behaviour */ + dl_conf.entity.count = rx_deliv; + ret =test_attempt_single (&dl_conf); +if (ret ==TEST_SKIPPED ) +return TEST_SKIPPED ; +TEST_ASSERT_EQUAL (ret, expected_ret,"Unexpected result" ); + +return TEST_SUCCESS ; +} + +static int +test_sn_range_type (enum sn_range_type type) +{ +int i, ret, passed =0 ; +struct pdcp_test_conf t_conf; + +int nb_test =RTE_DIM (pdcp_test_params); + +for (i =0 ; i < nb_test; i++) { +create_test_conf_from_index (i, &t_conf); +if (t_conf.entity.pdcp_xfrm.pkt_dir ==RTE_SECURITY_PDCP_DOWNLINK ) +continue ; +printf ("[%03i] - %s" , i, pdcp_test_params[i].name); + ret =test_sn_range_type_with_config (type, &t_conf); +if (ret ==TEST_FAILED ) { +printf (" - failed\n" ); +return ret; + }else if (ret ==TEST_SKIPPED ) { +printf (" - skipped\n" ); +continue ; + } +printf (" - passed\n" ); + passed +=1 ; + } + +printf ("Passed: %i\n" , passed); + +return TEST_SUCCESS ; +} + +static int +test_sn_plus_window (void ) +{ +return test_sn_range_type (SN_RANGE_PLUS_WINDOW ); +} + +static int +test_sn_minus_window (void ) +{ +return test_sn_range_type (SN_RANGE_MINUS_WINDOW ); +} + + +static int +test_sn_plus_outside (void ) +{ +return test_sn_range_type (SN_RANGE_PLUS_OUTSIDE ); +} + +static int +test_sn_minus_outside (void ) +{ +return test_sn_range_type (SN_RANGE_MINUS_OUTSIDE ); +} +static int test_iterate_all (void ) {
@@ -632,6 +871,7 @@ test_iterate_all(void)printf (" - passed\n" ); passed +=1 ; } +printf ("Passed: %i\n" , passed);return TEST_SUCCESS ;
@@ -643,8 +883,52 @@ test_sample(void)return test_iterate_all (); } -static struct unit_test_suite pdcp_testsuite = { - .suite_name ="PDCP Unit Test Suite" , +static int +test_combined (void ) +{ +struct pdcp_test_conf ul_conf, dl_conf; +int ret, nb_test, i, passed =0 ; + + nb_test =RTE_DIM (pdcp_test_params); + +for (i =0 ; i < nb_test; i++) { +create_test_conf_from_index (i, &ul_conf); +if (ul_conf.entity.pdcp_xfrm.pkt_dir ==RTE_SECURITY_PDCP_DOWNLINK ) +continue ; + + ul_conf.entity.reverse_iv_direction = true; + ul_conf.output_len =0 ; +printf ("[%03i] - %s" , i, pdcp_test_params[i].name); + + ret =test_attempt_single (&ul_conf); +if (ret ==TEST_FAILED ) { +printf (" - failed\n" ); +return ret; + }else if (ret ==TEST_SKIPPED ) { +printf (" - skipped\n" ); +continue ; + } + +uplink_to_downlink_convert (&ul_conf, &dl_conf); + ret =test_attempt_single (&dl_conf); +if (ret ==TEST_FAILED ) { +printf (" - failed\n" ); +return ret; + }else if (ret ==TEST_SKIPPED ) { +printf (" - skipped\n" ); +continue ; + } + +printf (" - passed\n" ); + passed +=1 ; + } +printf ("Passed: %i\n" , passed); + +return TEST_SUCCESS ; +} + +static struct unit_test_suite known_vector_cases = { + .suite_name ="PDCP known vectors" , .setup = testsuite_setup, .teardown = testsuite_teardown, .unit_test_cases = {
@@ -654,10 +938,62 @@ static struct unit_test_suite pdcp_testsuite = { } }; +static struct unit_test_suite combined_mode_cases = { + .suite_name ="PDCP combined mode" , + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { +TEST_CASE_ST (ut_setup_pdcp, ut_teardown_pdcp, + test_combined), +TEST_CASES_END ()/**< NULL terminate unit test array */ + } +}; + +static struct unit_test_suite hfn_sn_test_cases = { + .suite_name ="PDCP HFN/SN" , + .setup = testsuite_setup, + .teardown = testsuite_teardown, + .unit_test_cases = { +TEST_CASE_ST (ut_setup_pdcp, ut_teardown_pdcp, + test_sn_plus_window), +TEST_CASE_ST (ut_setup_pdcp, ut_teardown_pdcp, + test_sn_minus_window), +TEST_CASE_ST (ut_setup_pdcp, ut_teardown_pdcp, + test_sn_plus_outside), +TEST_CASE_ST (ut_setup_pdcp, ut_teardown_pdcp, + test_sn_minus_outside), +TEST_CASES_END ()/**< NULL terminate unit test array */ + } +}; +static int test_pdcp (void ) { -return unit_test_suite_runner (&pdcp_testsuite); +int ret; + +static struct unit_test_suite pdcp_testsuite = { + .suite_name ="PDCP Unit Test Suite" , + .unit_test_cases = {TEST_CASES_END ()}, + }; + +struct unit_test_suite *static_suites[] = { + &known_vector_cases, + &combined_mode_cases, + &hfn_sn_test_cases, +NULL /* End of suites list */ + }; + + pdcp_testsuite.unit_test_suites =rte_zmalloc (NULL ,sizeof (static_suites),0 ); +if (pdcp_testsuite.unit_test_suites ==NULL ) { +RTE_LOG (ERR ,USER1 ,"No memory for: '%s'\n" , pdcp_testsuite.suite_name); +return TEST_FAILED ; + } + +memcpy (pdcp_testsuite.unit_test_suites, static_suites,sizeof (static_suites)); + + ret =unit_test_suite_runner (&pdcp_testsuite); +rte_free (pdcp_testsuite.unit_test_suites); +return ret; }REGISTER_TEST_COMMAND (pdcp_autotest, test_pdcp);
Signature · 1 line
2.25.1
PATCH 5/5 doc: add PDCP library guide
In reply to Anoob JosephAdd guide for PDCP library.
--- .../img/pdcp_functional_overview.svg | 1 + doc/guides/prog_guide/index.rst | 1 + doc/guides/prog_guide/pdcp_lib.rst | 211 ++++++++++++++++++ 3 files changed, 213 insertions(+) create mode 100644 doc/guides/prog_guide/img/pdcp_functional_overview.svg create mode 100644 doc/guides/prog_guide/pdcp_lib.rst
doc/guides/prog_guide/img/pdcp_functional_overview.svg new file +1 -0
@@ -0,0 +1 @@ +<svg width="1280" height="720" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" overflow="hidden"><defs><clipPath id="clip0"><rect x="0" y="0" width="1280" height="720"/></clipPath></defs><g clip-path="url(#clip0)"><rect x="0" y="0" width="1280" height="720" fill="#FFFFFF"/><rect x="202" y="100" width="369" height="457" fill="#A5A5A5" fill-opacity="0.501961"/><rect x="640" y="100" width="369" height="457" fill="#A5A5A5" fill-opacity="0.501961"/><path d="M605.5 73.5001 605.5 590.633" stroke="#000000" stroke-width="1.33333" stroke-miterlimit="8" fill="none" fill-rule="evenodd"/><path d="M380.5 634 803.25 634 803.25 585.907 790.5 585.907 816 557.5 841.5 585.907 828.75 585.907 828.75 659.5 380.5 659.5Z" stroke="#787878" stroke-width="1.33333" stroke-miterlimit="8" fill="#A5A5A5" fill-rule="evenodd"/><rect x="362.5" y="557.5" width="28" height="102" stroke="#787878" stroke-width="1.33333" stroke-miterlimit="8" fill="#A5A5A5"/><rect x="412.5" y="671.5" width="370" height="32" stroke="#000000" stroke-linejoin="round" stroke-miterlimit="10" fill="none"/><text font-family="Arial,Arial_MSFontService,sans-serif" font-weight="400" font-size="19" transform="translate(492.364 694)">Radio Interface (<tspan font-size="19" x="137.5" y="0">Uu</tspan><tspan font-size="19" x="161.333" y="0">/PC5)</tspan><tspan font-size="19" x="-282.121" y="-653">UE/NG</tspan><tspan font-size="19" x="-222.955" y="-653">-</tspan><tspan font-size="19" x="-216.788" y="-653">RAN/UE A</tspan><tspan font-size="19" x="375.54" y="-653">NG</tspan>-<tspan font-size="19" x="409.706" y="-653">RAN/UE/UE B</tspan><tspan font-size="14" x="0.896851" y="-647">Transmitting </tspan><tspan font-size="14" x="1.31018" y="-631">PDCP entity</tspan><tspan font-size="14" x="167.401" y="-647">Receiving </tspan><tspan font-size="14" x="160.148" y="-631">PDCP entity</tspan></text><path d="M314.5 71.5001 431.364 71.6549" stroke="#000000" stroke-width="0.666667" stroke-miterlimit="8" fill="none" fill-rule="evenodd"/><path d="M331.5 71.5001C331.5 65.9772 349.633 61.5001 372 61.5001 394.368 61.5001 412.5 65.9772 412.5 71.5001 412.5 77.0229 394.368 81.5001 372 81.5001 349.633 81.5001 331.5 77.0229 331.5 71.5001Z" stroke="#000000" stroke-width="1.33333" stroke-miterlimit="8" fill="#FFFFFF" fill-rule="evenodd"/><path d="M353.5 90.5001 363.5 90.5001 363.5 48.5001 383.5 48.5001 383.5 90.5001 393.5 90.5001 373.5 110.5Z" stroke="#000000" stroke-width="1.33333" stroke-miterlimit="8" fill="#FFFFFF" fill-rule="evenodd"/><path d="M877.364 82.6549 760.5 82.5001" stroke="#000000" stroke-width="0.666667" stroke-miterlimit="8" fill="none" fill-rule="evenodd"/><path d="M860.5 83.5001C860.5 89.0229 842.368 93.5001 820 93.5001 797.633 93.5001 779.5 89.0229 779.5 83.5001 779.5 77.9772 797.633 73.5001 820 73.5001 842.368 73.5001 860.5 77.9772 860.5 83.5001Z" stroke="#000000" stroke-width="1.33333" stroke-miterlimit="8" fill="#FFFFFF" fill-rule="evenodd"/><path d="M838.5 64.5 828.5 64.5 828.5 106.5 808.5 106.5 808.5 64.5 798.5 64.5 818.5 44.5001Z" stroke="#000000" stroke-width="1.33333" stroke-miterlimit="8" fill="#FFFFFF" fill-rule="evenodd"/><rect x="244.5" y="128.5" width="285" height="55" stroke="#000000" stroke-width="1.33333" stroke-miterlimit="8" fill="#FFFFFF"/><text font-family="Arial,Arial_MSFontService,sans-serif" font-weight="400" font-size="19" transform="translate(302.494 150)">Transmission buffer:<tspan font-size="19" x="-4.67999" y="23">Sequence</tspan><tspan font-size="19" x="84.32" y="23">numberin</tspan>g</text><rect x="244.5" y="199.5" width="285" height="55" stroke="#000000" stroke-width="1.33333" stroke-miterlimit="8" fill="#FFFFFF"/><text font-family="Arial,Arial_MSFontService,sans-serif" font-weight="400" font-size="19" transform="translate(297.314 222)">Header or uplink data<tspan font-size="19" x="34.08" y="23">Compressio</tspan>n</text><rect x="682.5" y="141.5" width="285" height="55" stroke="#000000" stroke-width="1.33333" stroke-miterlimit="8" fill="#FFFFFF"/><text font-family="Arial,Arial_MSFontService,sans-serif" font-weight="400" font-size="19" transform="translate(735.782 164)">Header or uplink data<tspan font-size="19" x="24.2466" y="23">Decompressio</tspan>n</text><rect x="244.5" y="482.5" width="285" height="33" stroke="#000000" stroke-width="1.33333" stroke-miterlimit="8" fill="#FFFFFF"/><text font-family="Arial,Arial_MSFontService,sans-serif" font-weight="400" font-size="19" transform="translate(300.314 505)">Routing / Duplication</text><rect x="244.5" y="437.5" width="285" height="32" stroke="#000000" stroke-width="1.33333" stroke-miterlimit="8" fill="#FFFFFF"/><text font-family="Arial,Arial_MSFontService,sans-serif" font-weight="400" font-size="19" transform="translate(309.734 460)">Add PDCP header</text><rect x="244.5" y="383.5" width="189" height="33" stroke="#000000" stroke-width="1.33333" stroke-miterlimit="8" fill="#FFFFFF"/><text font-family="Arial,Arial_MSFontService,sans-serif" font-weight="400" font-size="19" transform="translate(298.62 406)">Ciphering</text><rect x="244.5" y="333.5" width="189" height="32" stroke="#000000" stroke-width="1.33333" stroke-miterlimit="8" fill="#FFFFFF"/><text font-family="Arial,Arial_MSFontService,sans-serif" font-weight="400" font-size="19" transform="translate(261.953 356)">Integrity protection</text><path d="M472.167 267.5 472.167 409.802 470.833 409.802 470.833 267.5ZM475.5 408.468 471.5 416.468 467.5 408.468Z"/><path d="M332.167 267.5 332.167 319.552 330.833 319.552 330.833 267.5ZM335.5 318.218 331.5 326.218 327.5 318.219Z"/><text font-family="Arial,Arial_MSFontService,sans-serif" font-weight="400" font-size="19" transform="translate(253.644 291)">Packets associated <tspan font-size="19" x="14.0067" y="23">to a PDCP SDU</tspan></text><text font-family="Arial,Arial_MSFontService,sans-serif" font-weight="400" font-size="19" transform="matrix(6.12323e-17 1 -1 6.12323e-17 499.312 299)">Packets not <tspan font-size="19" x="-14" y="23">associated to a </tspan><tspan font-size="19" x="-2.75546e-15" y="45">PDCP SDU</tspan></text><rect x="682.5" y="482.5" width="285" height="33" stroke="#000000" stroke-width="1.33333" stroke-miterlimit="8" fill="#FFFFFF"/><text font-family="Arial,Arial_MSFontService,sans-serif" font-weight="400" font-size="19" transform="translate(728.535 505)">Remove PDCP Header</text><rect x="682.5" y="437.5" width="203" height="32" stroke="#000000" stroke-width="1.33333" stroke-miterlimit="8" fill="#FFFFFF"/><text font-family="Arial,Arial_MSFontService,sans-serif" font-weight="400" font-size="19" transform="translate(733.729 460)">Deciphering</text><rect x="682.5" y="389.5" width="203" height="33" stroke="#000000" stroke-width="1.33333" stroke-miterlimit="8" fill="#FFFFFF"/><text font-family="Arial,Arial_MSFontService,sans-serif" font-weight="400" font-size="19" transform="translate(702.159 412)">Integrity Verification</text><rect x="682.5" y="303.5" width="203" height="77" stroke="#000000" stroke-width="1.33333" stroke-miterlimit="8" fill="#FFFFFF"/><text font-family="Arial,Arial_MSFontService,sans-serif" font-weight="400" font-size="19" transform="translate(712.729 325)">Reception buffer:<tspan font-size="19" x="24.6667" y="23">Reordering</tspan><tspan font-size="19" x="-13.1667" y="45">Duplicate discardin</tspan><tspan font-size="19" x="144.167" y="45">g</tspan><tspan font-size="19" x="-10.0989" y="-84">Packets associated </tspan><tspan font-size="19" x="3.90784" y="-61">to a PDCP SDU</tspan></text><text font-family="Arial,Arial_MSFontService,sans-serif" font-weight="400" font-size="19" transform="matrix(6.12323e-17 1 -1 6.12323e-17 960.34 294)">Packets not <tspan font-size="19" x="-14" y="23">associated to a </tspan><tspan font-size="19" x="1" y="45">PDCP SDU</tspan></text><path d="M0.666667-8.2074e-07 0.666763 78.6116-0.66657 78.6116-0.666667 8.2074e-07ZM4.00009 77.2782 0.000104987 85.2782-3.9999 77.2782Z" transform="matrix(1 0 0 -1 779.5 296.778)"/><path d="M0.666667-2.88742e-07 0.666769 235.734-0.666565 235.734-0.666667 2.88742e-07ZM4.0001 234.401 0.000104987 242.401-3.9999 234.401Z" transform="matrix(1 0 0 -1 931.5 453.901)"/></g></svg>
doc/guides/prog_guide/index.rst +1 -0
@@ -76,4 +76,5 @@ Programmer's Guide lto profile_app asan + pdcp_lib glossary
doc/guides/prog_guide/pdcp_lib.rst new file +211 -0
211 lines not on this page · raw message
Signature · 1 line
2.25.1
For such new library, I think we need to vote in techboard to accept it. That's a process we had in recent years to keep the project scope in control.
22/12/2022 10:25, Anoob Joseph:
Quoted 35 lines
Add Packet Data Convergence Protocol (PDCP) processing library.
The library is similar to
lib_ipsecwhich provides IPsec processing capabilities in DPDK.PDCP would involve roughly the following options,
1. Transfer of user plane data
2. Transfer of control plane data
3. Header compression
4. Uplink data compression
5. Ciphering and integrity protectionPDCP library provides following control path APIs that is used to configure various PDCP entities,
1.rte_pdcp_entity_establish()
2.rte_pdcp_entity_suspend()
3.rte_pdcp_entity_release()PDCP process is split into 2 parts. One before crypto processing (
rte_pdcp_pkt_pre_process()) and one after crypto processing (rte_pdcp_pkt_post_process()). Since cryptodev dequeue can return crypto operations belonging to multiple entities,rte_pdcp_pkt_crypto_group()is added to help grouping crypto operations belonging to same entity.Similar to lib IPsec, lib PDCP would allow application to use same API sequence while leveraging protocol offload features enabled by
rte_securitylibrary. Lib PDCP would internally change the handles registered for *pre_process* and *post_process* based on features enabled in the entity.Lib PDCP would create the required sessions on the device provided in entity to minimize the application requirements. Also, the
crypto_opallocation and free would also be done internally by lib PDCP to allow the library to create crypto ops as required for the input packets. For example, when control PDUs are received, no cryptodev enqueue-dequeue is expected for the same and lib PDCP is expected to handle it differently.
Quoted 3 lines · Thomas Monjalon
For such new library, I think we need to vote in techboard to accept it. That's a process we had in recent years to keep the project scope in control.
Looks like this process not defined nor documented. In order to bring clarity for new library acceptance and make life easy for contributors (also, less forking the DPDK repo),
IMO, we should document the process as there is a lot of effort involved and send multiple version, and finally it gets rejected due to various reasons.
I would suggest, some guideline to get started for discussion. I would suggest taking up this for TB meeting to define it.
1)For new library(new directory under lib/ directory) needs to get approval from DPDK tech board.
2)Author needs to send any of the following to start the approval process -Send a write-up on the scope and purpose library. TB may ask for sending API specification RFC is the scope or purpose is not clear. OR
-Send RFC with API specification.
If it's above, following new libraries needs approval. So I suggest we take approval in coming TB meeting to conclude one way or another.
1) pdcp library (https://patches.dpdk.org/project/dpdk/list/?series=26246)
2) mldev library or device class(https://patches.dpdk.org/project/dpdk/list/?series=25753)
3) memara (https://patches.dpdk.org/project/dpdk/list/?series=26546)
4) pmu ( started as EAL file and moving to separate library at
https://patches.dpdk.org/project/dpdk/list/?series=26616)
Please add the libraries if I missed something.
v2 cover lib: add pdcp protocol
In reply to Anoob JosephAdd Packet Data Convergence Protocol (PDCP) processing library.
The library is similar to lib_ipsec which provides IPsec processing capabilities in DPDK.
PDCP would involve roughly the following operations,
1. Transfer of user plane data
2. Transfer of control plane data
3. Header compression
4. Uplink data compression
5. Ciphering and integrity protection
PDCP library provides following control path APIs that is used to configure various PDCP entities,
1. rte_pdcp_entity_establish()
2. rte_pdcp_entity_suspend()
3. rte_pdcp_entity_release()
PDCP process is split into 2 parts. One before crypto processing (rte_pdcp_pkt_pre_process()) and one after crypto processing (rte_pdcp_pkt_post_process()). Since cryptodev dequeue can return crypto operations belonging to multiple entities, rte_pdcp_pkt_crypto_group() is added to help grouping crypto operations belonging to same entity.
Similar to lib IPsec, lib PDCP would allow application to use same API sequence while leveraging protocol offload features enabled by rte_security library. Lib PDCP would internally change the handles registered for *pre_process* and *post_process* based on features enabled in the entity.
Lib PDCP would create the required sessions on the device provided in entity to minimize the application requirements. Also, the crypto_op allocation and free would also be done internally by lib PDCP to allow the library to create crypto ops as required for the input packets. For example, when control PDUs are received, no cryptodev enqueue-dequeue is expected for the same and lib PDCP is expected to handle it differently.
Lib PDCP utilizes reorder library for implementing in-order delivery. It utilizes bitmap library for implementing status reports and track the COUNT value of the packets received. To allow application to choose timer implementation of choice, lib PDCP allows application to configure handles that can be used for starting & stopping timers. Upon expiry, application can call corresponding PDCP API(``rte_pdcp_t_reordering_expiry_handle``) for handling the event. Unit tests are added to verify both rte_timer based timers as well as rte_eventdev based timers.
PDCP tracks the sequence number of the received packets and during events such as re-establishment, it is required to generate reports and transmit to the peer. This series introduces ``rte_pdcp_control_pdu_create`` for handling control PDU generation.
Changes in v2:
- Added control PDU handling
- Added t-Reordering timer
- Added in-order delivery
- Added status PDU generation
- Rebased on top of new features added in reorder library
- Split base patch
- Increased test coverage
- Improved thread safety
Changes from RFC
- Implementation for all APIs covering basic control plane & user plane packets
- Unit test leveraging existing PDCP vectors available in test_cryptodev
- Unit test performing both UL & DL operations to verify various protocol features
- Updated documentation
Sample application sequence:
struct rte_mbuf **out_mb, *pkts[MAX_BURST_SIZE];
struct rte_crypto_op *cop[MAX_BURST_SIZE];
struct rte_pdcp_group grp[MAX_BURST_SIZE];
struct rte_pdcp_entity *pdcp_entity;
int nb_max_out_mb, ret, nb_grp;
/* Create PDCP entity */
pdcp_entity = rte_pdcp_entity_establish(&conf);
/**
* Allocate buffer for holding mbufs returned during PDCP suspend,
* release & post-process APIs.
*/
/* Max packets that can be cached in entity + burst size */
nb_max_out_mb = pdcp_entity->max_pkt_cache + 1;
out_mb = rte_malloc(NULL, nb_max_out_mb * sizeof(uintptr_t), 0);
if (out_mb == NULL) {
/* Handle error */
}
while (1) {
/* Receive packet and form mbuf */
/**
* Prepare packets for crypto operation. Following operations
* would be done,
*
* Transmitting entity/UL (only data PDUs):
* - Perform compression
* - Assign sequence number
* - Add PDCP header
* - Create & prepare crypto_op
* - Prepare IV for crypto operation (auth_gen, encrypt)
* - Save original PDCP SDU (during PDCP re-establishment,
* unconfirmed PDCP SDUs need to crypto processed again and
* transmitted/re-transmitted)
*
* Receiving entity/DL:
* - Any control PDUs received would be processed and
* appropriate actions taken. If data PDU, continue.
* - Determine sequence number (based on HFN & per packet SN)
* - Prepare crypto_op
* - Prepare IV for crypto operation (decrypt, auth_verify)
*/
nb_success = rte_pdcp_pkt_pre_process(pdcp_entity, pkts, cop,
nb_rx, &nb_err);
if (nb_err != 0) {
/* Handle error packets */
}
if ((rte_cryptodev_enqueue_burst(dev_id, qp_id, cop, nb_success)
!= nb_success) {
/* Retry for enqueue failure packets */
}
...
ret = rte_cryptodev_dequeue_burst(dev_id, qp_id, cop,
MAX_BURST_SIZE);
if (ret == 0)
continue;
/**
* Received a burst of completed crypto ops from cryptodev. It
* may belong to various entities. Group similar ones together
* for entity specific post-processing.
*/
/**
* Groups similar entities together. Frees crypto op and based
* on crypto_op status, set mbuf->ol_flags which would be
* checked in rte_pdcp_pkt_post_process().
*/
nb_grp = rte_pdcp_pkt_crypto_group(cop, pkts, grp, ret);
for (i = 0; i != nb_grp; i++) {
/**
* Post process packets after crypto completion.
* Following operations would be done,
*
* Transmitting entity/UL:
* - Check crypto result
*
* Receiving entity/DL:
* - Check crypto operation status
* - Check for duplication (if yes, drop duplicate)
* - Perform decompression
* - Trim PDCP header
* - Hold packet (SDU) for in-order delivery (return
* completed packets as and when sequence is
* completed)
* - If not in sequence, cache the packet and start
* t-Reordering timer. When timer expires, the
* packets need to delivered to upper layers (not
* treated as error packets).
*/
nb_success = rte_pdcp_pkt_post_process(grp[i].id.ptr,
grp[i].m, out_mb,
grp[i].cnt,
&nb_err);
if (nb_err != 0) {
/* Handle error packets */
}
/* Perform additional operations */
/**
* Tranmitting entity/UL
* - If duplication is enabled, duplicate PDCP PDUs
* - When lower layers confirm reception of a PDCP PDU,
* it should be communicated to PDCP layer so that
* PDCP can drop the corresponding SDU
*/
}
}Sample output from unit test executed on crypto_cn10k PMD(summary):
~# DPDK_TEST=pdcp_autotest ./dpdk-test --log-level=7
<snip>
+ ------------------------------------------------------- +
+ Test Suite Summary : PDCP Unit Test Suite
+ ------------------------------------------------------- +
+ Known vector cases : 109/160 passed, 0/160 skipped, 0/160 failed, 51/160 unsupported
+ PDCP combined mode : 1/1 passed, 0/1 skipped, 0/1 failed, 0/1 unsupported
+ PDCP HFN/SN : 4/4 passed, 0/4 skipped, 0/4 failed, 0/4 unsupported
+ PDCP reorder : 5/5 passed, 0/5 skipped, 0/5 failed, 0/5 unsupported
+ PDCP status report : 9/9 passed, 0/9 skipped, 0/9 failed, 0/9 unsupported
+ ------------------------------------------------------- +
+ Sub Testsuites Total : 5 + Sub Testsuites Skipped : 0 + Sub Testsuites Passed : 5 + Sub Testsuites Failed : 0 + ------------------------------------------------------- + + Tests Total : 179 + Tests Skipped : 0 + Tests Executed : 179 + Tests Unsupported: 51 + Tests Passed : 128
+ Tests Failed : 0
+ ------------------------------------------------------- +
Test OK
Anoob Joseph (10):
lib: add pdcp protocol
pdcp: add pre and post-process
pdcp: add packet group
pdcp: add crypto session create and destroy
pdcp: add pre and post process for UL
pdcp: add pre and post process for DL
pdcp: add IV generation routines
app/test: add lib pdcp tests
doc: add PDCP library guide
pdcp: add control PDU handling
Volodymyr Fialko (12):
net: add PDCP header
test/pdcp: pdcp HFN tests in combined mode
pdcp: implement t-Reordering and packet buffering test/pdcp: add in-order delivery cases
pdcp: add timer callback handlers
pdcp: add timer expiry handle
test/pdcp: add timer expiry cases test/pdcp: add timer restart case
pdcp: add support for status report
pdcp: allocate reorder buffer alongside with entity
pdcp: add thread safe processing
test/pdcp: add PDCP status report cases
app/test/meson.build | 1 + app/test/test_cryptodev.h | 3 + app/test/test_pdcp.c | 1923 +++++++++++++++++ doc/api/doxy-api-index.md | 4 +- doc/api/doxy-api.conf.in | 1 + .../img/pdcp_functional_overview.svg | 1 + doc/guides/prog_guide/index.rst | 1 + doc/guides/prog_guide/pdcp_lib.rst | 285 +++ lib/meson.build | 1 + lib/net/meson.build | 1 + lib/net/rte_pdcp_hdr.h | 140 ++ lib/pdcp/meson.build | 21 + lib/pdcp/pdcp_cnt.c | 164 ++ lib/pdcp/pdcp_cnt.h | 24 + lib/pdcp/pdcp_crypto.c | 237 ++ lib/pdcp/pdcp_crypto.h | 21 + lib/pdcp/pdcp_ctrl_pdu.c | 72 + lib/pdcp/pdcp_ctrl_pdu.h | 16 + lib/pdcp/pdcp_entity.h | 306 +++ lib/pdcp/pdcp_process.c | 1379 ++++++++++++ lib/pdcp/pdcp_process.h | 13 + lib/pdcp/pdcp_reorder.c | 20 + lib/pdcp/pdcp_reorder.h | 68 + lib/pdcp/rte_pdcp.c | 261 +++ lib/pdcp/rte_pdcp.h | 369 ++++ lib/pdcp/rte_pdcp_group.h | 125 ++ lib/pdcp/version.map | 17 + 27 files changed, 5473 insertions(+), 1 deletion(-) create mode 100644 app/test/test_pdcp.c create mode 100644 doc/guides/prog_guide/img/pdcp_functional_overview.svg create mode 100644 doc/guides/prog_guide/pdcp_lib.rst create mode 100644 lib/net/rte_pdcp_hdr.h create mode 100644 lib/pdcp/meson.build create mode 100644 lib/pdcp/pdcp_cnt.c create mode 100644 lib/pdcp/pdcp_cnt.h create mode 100644 lib/pdcp/pdcp_crypto.c create mode 100644 lib/pdcp/pdcp_crypto.h create mode 100644 lib/pdcp/pdcp_ctrl_pdu.c create mode 100644 lib/pdcp/pdcp_ctrl_pdu.h create mode 100644 lib/pdcp/pdcp_entity.h create mode 100644 lib/pdcp/pdcp_process.c create mode 100644 lib/pdcp/pdcp_process.h create mode 100644 lib/pdcp/pdcp_reorder.c create mode 100644 lib/pdcp/pdcp_reorder.h create mode 100644 lib/pdcp/rte_pdcp.c create mode 100644 lib/pdcp/rte_pdcp.h create mode 100644 lib/pdcp/rte_pdcp_group.h create mode 100644 lib/pdcp/version.map
Signature · 1 line
2.25.1
PATCH v2 1/22 net: add PDCP header
From: Volodymyr Fialko <[email protected]>
Add PDCP protocol header to be used for supporting PDCP protocol processing.
--- doc/api/doxy-api-index.md | 3 +- lib/net/meson.build | 1 + lib/net/rte_pdcp_hdr.h | 140 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 lib/net/rte_pdcp_hdr.h
doc/api/doxy-api-index.md +2 -1
@@ -127,7 +127,8 @@ The public API headers are grouped by topics: [Geneve](@ref rte_geneve.h), [eCPRI](@ref rte_ecpri.h), [L2TPv2](@ref rte_l2tpv2.h), - [PPP](@ref rte_ppp.h) + [PPP](@ref rte_ppp.h), + [PDCP hdr](@ref rte_pdcp_hdr.h) - **QoS**: [metering](@ref rte_meter.h),
lib/net/meson.build +1 -0
@@ -22,6 +22,7 @@ headers = files( 'rte_geneve.h', 'rte_l2tpv2.h', 'rte_ppp.h', + 'rte_pdcp_hdr.h', ) sources = files(
lib/net/rte_pdcp_hdr.h new file +140 -0
140 lines not on this page · raw message
Signature · 1 line
2.25.1
RE: [PATCH v2 01/22] net: add PDCP header
Quoted 11 lines
Subject: [PATCH v2 01/22] net: add PDCP header
From: Volodymyr Fialko <[email protected]>
Add PDCP protocol header to be used for supporting PDCP protocol processing.
Signed-off-by Anoob Joseph <[email protected]>Signed-off-by Kiran Kumar K <[email protected]>Signed-off-by Volodymyr Fialko <[email protected]>---
PATCH v2 2/22 lib: add pdcp protocol
In reply to Anoob JosephAdd Packet Data Convergence Protocol (PDCP) processing library.
The library is similar to lib_ipsec which provides IPsec processing capabilities in DPDK.
PDCP would involve roughly the following options,
1. Transfer of user plane data
2. Transfer of control plane data
3. Header compression
4. Uplink data compression
5. Ciphering and integrity protection
PDCP library provides following control path APIs that is used to configure various PDCP entities,
1. rte_pdcp_entity_establish()
2. rte_pdcp_entity_suspend()
3. rte_pdcp_entity_release()
--- doc/api/doxy-api-index.md | 3 +- doc/api/doxy-api.conf.in | 1 + lib/meson.build | 1 + lib/pdcp/meson.build | 17 +++++ lib/pdcp/pdcp_crypto.c | 21 +++++ lib/pdcp/pdcp_crypto.h | 15 ++++ lib/pdcp/pdcp_entity.h | 95 +++++++++++++++++++++++ lib/pdcp/pdcp_process.c | 138 +++++++++++++++++++++++++++++++++ lib/pdcp/pdcp_process.h | 13 ++++ lib/pdcp/rte_pdcp.c | 138 +++++++++++++++++++++++++++++++++ lib/pdcp/rte_pdcp.h | 157 ++++++++++++++++++++++++++++++++++++++ lib/pdcp/version.map | 10 +++ 12 files changed, 608 insertions(+), 1 deletion(-) create mode 100644 lib/pdcp/meson.build create mode 100644 lib/pdcp/pdcp_crypto.c create mode 100644 lib/pdcp/pdcp_crypto.h create mode 100644 lib/pdcp/pdcp_entity.h create mode 100644 lib/pdcp/pdcp_process.c create mode 100644 lib/pdcp/pdcp_process.h create mode 100644 lib/pdcp/rte_pdcp.c create mode 100644 lib/pdcp/rte_pdcp.h create mode 100644 lib/pdcp/version.map
doc/api/doxy-api-index.md +2 -1
@@ -128,7 +128,8 @@ The public API headers are grouped by topics: [eCPRI](@ref rte_ecpri.h), [L2TPv2](@ref rte_l2tpv2.h), [PPP](@ref rte_ppp.h), - [PDCP hdr](@ref rte_pdcp_hdr.h) + [PDCP hdr](@ref rte_pdcp_hdr.h), + [PDCP](@ref rte_pdcp.h) - **QoS**: [metering](@ref rte_meter.h),
doc/api/doxy-api.conf.in +1 -0
@@ -62,6 +62,7 @@ INPUT = @TOPDIR@/doc/api/doxy-api-index.md \ @TOPDIR@/lib/net \ @TOPDIR@/lib/pcapng \ @TOPDIR@/lib/pci \ + @TOPDIR@/lib/pdcp \ @TOPDIR@/lib/pdump \ @TOPDIR@/lib/pipeline \ @TOPDIR@/lib/port \
lib/meson.build +1 -0
@@ -64,6 +64,7 @@ libraries = [ 'flow_classify', # flow_classify lib depends on pkt framework table lib 'graph', 'node', + 'pdcp', # pdcp lib depends on crypto and security ] optional_libs = [
lib/pdcp/meson.build new file +17 -0
@@ -0,0 +1,17 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(C) 2023 Marvell. + +if is_windows + build = false + reason = 'not supported on Windows' + subdir_done() +endif + +sources = files( + 'pdcp_crypto.c', + 'pdcp_process.c', + 'rte_pdcp.c', + ) +headers = files('rte_pdcp.h') + +deps += ['mbuf', 'net', 'cryptodev', 'security']
lib/pdcp/pdcp_crypto.c new file +21 -0
@@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2023 Marvell. +*/ + +#include <rte_pdcp.h> + +#include "pdcp_crypto.h" + +int +pdcp_crypto_sess_create (struct rte_pdcp_entity *entity,const struct rte_pdcp_entity_conf *conf) +{ +RTE_SET_USED (entity); +RTE_SET_USED (conf); +return 0 ; +} + +void +pdcp_crypto_sess_destroy (struct rte_pdcp_entity *entity) +{ +RTE_SET_USED (entity); +}
lib/pdcp/pdcp_crypto.h new file +15 -0
@@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2023 Marvell. +*/ + +#ifndef PDCP_CRYPTO_H +#define PDCP_CRYPTO_H + +#include <rte_pdcp.h> + +int pdcp_crypto_sess_create (struct rte_pdcp_entity *entity, +const struct rte_pdcp_entity_conf *conf); + +void pdcp_crypto_sess_destroy (struct rte_pdcp_entity *entity); + +#endif /* PDCP_CRYPTO_H */
lib/pdcp/pdcp_entity.h new file +95 -0
95 lines not on this page · raw message
lib/pdcp/pdcp_process.c new file +138 -0
138 lines not on this page · raw message
lib/pdcp/pdcp_process.h new file +13 -0
@@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2023 Marvell. +*/ + +#ifndef PDCP_PROCESS_H +#define PDCP_PROCESS_H + +#include <rte_pdcp.h> + +int +pdcp_process_func_set (struct rte_pdcp_entity *entity,const struct rte_pdcp_entity_conf *conf); + +#endif /* PDCP_PROCESS_H */
lib/pdcp/rte_pdcp.c new file +138 -0
138 lines not on this page · raw message
lib/pdcp/rte_pdcp.h new file +157 -0
157 lines not on this page · raw message
lib/pdcp/version.map new file +10 -0
@@ -0,0 +1,10 @@ +EXPERIMENTAL { + global: + + # added in 23.07 + rte_pdcp_entity_establish; + rte_pdcp_entity_release; + rte_pdcp_entity_suspend; + + local: *; +};
Signature · 1 line
2.25.1
Hi Anoob,
Fix check patch issues and please see some inline comments.
Quoted 328 lines
Subject: [PATCH v2 02/22] lib: add pdcp protocol
Add Packet Data Convergence Protocol (PDCP) processing library.
The library is similar to
lib_ipsecwhich provides IPsec processing capabilities in DPDK.PDCP would involve roughly the following options,
1. Transfer of user plane data
2. Transfer of control plane data
3. Header compression
4. Uplink data compression
5. Ciphering and integrity protectionPDCP library provides following control path APIs that is used to configure various PDCP entities,
1.rte_pdcp_entity_establish()
2.rte_pdcp_entity_suspend()
3.rte_pdcp_entity_release()Signed-off-by Anoob Joseph <[email protected]>Signed-off-by Kiran Kumar K <[email protected]>Signed-off-by Volodymyr Fialko <[email protected]>--- doc/api/doxy-api-index.md | 3 +- doc/api/doxy-api.conf.in | 1 + lib/meson.build | 1 + lib/pdcp/meson.build | 17 +++++ lib/pdcp/pdcp_crypto.c | 21 +++++ lib/pdcp/pdcp_crypto.h | 15 ++++ lib/pdcp/pdcp_entity.h | 95 +++++++++++++++++++++++ lib/pdcp/pdcp_process.c | 138 +++++++++++++++++++++++++++++++++ lib/pdcp/pdcp_process.h | 13 ++++ lib/pdcp/rte_pdcp.c | 138 +++++++++++++++++++++++++++++++++ lib/pdcp/rte_pdcp.h | 157 ++++++++++++++++++++++++++++++++++++++ lib/pdcp/version.map | 10 +++ 12 files changed, 608 insertions(+), 1 deletion(-) create mode 100644 lib/pdcp/meson.build create mode 100644 lib/pdcp/pdcp_crypto.c create mode 100644 lib/pdcp/pdcp_crypto.h create mode 100644 lib/pdcp/pdcp_entity.h create mode 100644 lib/pdcp/pdcp_process.c create mode 100644 lib/pdcp/pdcp_process.h create mode 100644 lib/pdcp/rte_pdcp.c create mode 100644 lib/pdcp/rte_pdcp.h create mode 100644 lib/pdcp/version.mapdoc/api/doxy-api-index.md +2
-1@@ -128,7 +128,8 @@ The public API headers are grouped by topics: [eCPRI](@ref rte_ecpri.h), [L2TPv2](@ref rte_l2tpv2.h), [PPP](@ref rte_ppp.h), - [PDCP hdr](@ref rte_pdcp_hdr.h) + [PDCP hdr](@ref rte_pdcp_hdr.h), + [PDCP](@ref rte_pdcp.h) - **QoS**: [metering](@ref rte_meter.h),doc/api/doxy-api.conf.in +1
-0@@ -62,6 +62,7 @@ INPUT = @TOPDIR@/doc/api/doxy-api- index.md \ @TOPDIR@/lib/net \ @TOPDIR@/lib/pcapng \ @TOPDIR@/lib/pci \ + @TOPDIR@/lib/pdcp \ @TOPDIR@/lib/pdump \ @TOPDIR@/lib/pipeline \@TOPDIR@/lib/port \lib/meson.build +1
-0@@ -64,6 +64,7 @@ libraries = [ 'flow_classify', # flow_classify lib depends on pkt framework table lib 'graph', 'node', + 'pdcp', # pdcp lib depends on crypto and security ] optional_libs = [lib/pdcp/meson.build new file +17
-0@@ -0,0 +1,17 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright(C) 2023 Marvell. + +if is_windows + build = false + reason = 'not supported on Windows' + subdir_done() +endif + +sources = files( + 'pdcp_crypto.c', + 'pdcp_process.c', + 'rte_pdcp.c', + ) +headers = files('rte_pdcp.h') + +deps += ['mbuf', 'net', 'cryptodev', 'security']lib/pdcp/pdcp_crypto.c new file +10
-0@@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2023 Marvell. +*/ + +#include <rte_pdcp.h> + +#include "pdcp_crypto.h" + +int +pdcp_crypto_sess_create(struct rte_pdcp_entity *entity, const struct
rte_pdcp_entity_conf*conf)lib/pdcp/pdcp_crypto.c new file +11
-0+{ +RTE_SET_USED (entity); +RTE_SET_USED (conf); +return 0 ; +} + +void +pdcp_crypto_sess_destroy (struct rte_pdcp_entity *entity) +{ +RTE_SET_USED (entity); +}lib/pdcp/pdcp_crypto.h new file +15
-0@@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2023 Marvell. +*/ + +#ifndef PDCP_CRYPTO_H +#define PDCP_CRYPTO_H + +#include <rte_pdcp.h> + +int pdcp_crypto_sess_create (struct rte_pdcp_entity *entity, +const struct rte_pdcp_entity_conf *conf); + +void pdcp_crypto_sess_destroy (struct rte_pdcp_entity *entity); + +#endif /* PDCP_CRYPTO_H */ lib/pdcp/pdcp_entity.h new file +17
-0@@ -0,0 +1,95 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2023 Marvell. +*/ + +#ifndef PDCP_ENTITY_H +#define PDCP_ENTITY_H + +#include <rte_common.h> +#include <rte_crypto_sym.h> +#include <rte_mempool.h> +#include <rte_pdcp.h> +#include <rte_security.h> + +struct entity_priv ; + +/* IV generation function based on the entity configuration */ +typedef void (*iv_gen_t)(struct rte_crypto_op *cop, const struct entity_priv
*en_priv,lib/pdcp/pdcp_entity.h new file +38
-0+ uint32_t count); + +struct entity_state { +uint32_t rx_next; +uint32_t tx_next; +uint32_t rx_deliv; +uint32_t rx_reord; +}; + +/* +* Layout of PDCP entity: [rte_pdcp_entity] [entity_priv] [entity_dl/ul] +*/ + +struct entity_priv { +/** Crypto sym session. */ +struct rte_cryptodev_sym_session *crypto_sess; +/** Entity specific IV generation function. */ +iv_gen_t iv_gen; +/** Entity state variables. */ +struct entity_state state; +/** Flags. */ +struct { +/** PDCP PDU has 4 byte MAC-I. */ +uint64_t is_authenticated :1 ; +/** Cipher offset & length in bits. */ +uint64_t is_ciph_in_bits :1 ; +/** Auth offset & length in bits. */ +uint64_t is_auth_in_bits :1 ; +/** Is UL/transmitting PDCP entity. */ +uint64_t is_ul_entity :1 ; +/** Is NULL auth. */ +uint64_t is_null_auth :1 ; + } flags; +/** Crypto op pool. */ +struct rte_mempool *cop_pool; +/** PDCP header size. */ +uint8_t hdr_sz; +/** PDCP AAD size. For AES-CMAC, additional message is prepended for the operation. */
lib/pdcp/pdcp_entity.h new file +7
-0+uint8_t aad_sz; +/** Device ID of the device to be used for offload. */ +uint8_t dev_id; +}; + +struct entity_priv_dl_part { +/* NOTE: when in-order-delivery is supported, post PDCP packets would need to cached. */
lib/pdcp/pdcp_entity.h new file +6
-0+uint8_t dummy; +}; + +struct entity_priv_ul_part { +/* +* NOTE: when re-establish is supported, plain PDCP packets & COUNT values need to be
lib/pdcp/pdcp_entity.h new file +13
-0+* cached. +*/ +uint8_t dummy; +}; + +static inline struct entity_priv * +entity_priv_get (const struct rte_pdcp_entity *entity) { +return RTE_PTR_ADD (entity,sizeof (struct rte_pdcp_entity )); +} + +static inline struct entity_priv_dl_part * +entity_dl_part_get (const struct rte_pdcp_entity *entity) { + return RTE_PTR_ADD(entity, sizeof(struct rte_pdcp_entity) +
sizeof(struct entity_priv));lib/pdcp/pdcp_entity.h new file +5
-0+} + +static inline struct entity_priv_ul_part * +entity_ul_part_get (const struct rte_pdcp_entity *entity) { + return RTE_PTR_ADD(entity, sizeof(struct rte_pdcp_entity) +
sizeof(struct entity_priv));lib/pdcp/pdcp_entity.h new file +9
-0+} + +static inline int +pdcp_hdr_size_get (enum rte_security_pdcp_sn_size sn_size) +{ +return RTE_ALIGN_MUL_CEIL (sn_size,8 ) /8 ; +} + +#endif /* PDCP_ENTITY_H */ lib/pdcp/pdcp_process.c new file +17
-0@@ -0,0 +1,138 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2023 Marvell. +*/ + +#include <rte_crypto.h> +#include <rte_crypto_sym.h> +#include <rte_cryptodev.h> +#include <rte_memcpy.h> +#include <rte_pdcp.h> +#include <rte_pdcp_hdr.h> + +#include "pdcp_crypto.h" +#include "pdcp_entity.h" +#include "pdcp_process.h" + +static int +pdcp_crypto_xfrm_get(const struct rte_pdcp_entity_conf *conf, struct
rte_crypto_sym_xform**c_xfrm,lib/pdcp/pdcp_process.c new file +12
-0+ struct rte_crypto_sym_xform **a_xfrm) +{ + *c_xfrm =NULL ; + *a_xfrm =NULL ; + +if (conf->crypto_xfrm ==NULL ) +return -EINVAL ; + +if (conf->crypto_xfrm->type ==RTE_CRYPTO_SYM_XFORM_CIPHER ) { + *c_xfrm = conf->crypto_xfrm; + *a_xfrm = conf->crypto_xfrm->next; + } else if (conf->crypto_xfrm->type ==
RTE_CRYPTO_SYM_XFORM_AUTH) {lib/pdcp/pdcp_process.c new file +11
-0+ *a_xfrm = conf->crypto_xfrm; + *c_xfrm = conf->crypto_xfrm->next; + }else { +return -EINVAL ; + } + +return 0 ; +} + +static int +pdcp_entity_priv_populate(struct entity_priv *en_priv, const struct
rte_pdcp_entity_conf*conf)lib/pdcp/pdcp_process.c new file +8
-0+{ +struct rte_crypto_sym_xform *c_xfrm, *a_xfrm; +int ret; + +/** +* flags.is_authenticated +* +* MAC-I would be added in case of control plane packets and when authentication
lib/pdcp/pdcp_process.c new file +4
-0+* transform is not NULL. +*/ + + if (conf->pdcp_xfrm.domain ==
RTE_SECURITY_PDCP_MODE_CONTROL)
lib/pdcp/pdcp_process.c
Quoted 1 line
lib/pdcp/pdcp_process.c new file +1
-0+ en_priv->flags.is_authenticated =1 ;
This check should be added after getting the xfrm.
If domain == control and a_xfrm is NULL, then it should be error, right?
Quoted 148 lines
lib/pdcp/pdcp_process.c new file +12
-0+ + ret =pdcp_crypto_xfrm_get (conf, &c_xfrm, &a_xfrm); +if (ret) +return ret; + +if (a_xfrm !=NULL ) + en_priv->flags.is_authenticated =1 ; + +/** +* flags.is_ciph_in_bits +* +* For ZUC & SNOW3G cipher algos, offset & length need to be provided in bits.
lib/pdcp/pdcp_process.c new file +10
-0+*/ + +if ((c_xfrm->cipher.algo ==RTE_CRYPTO_CIPHER_SNOW3G_UEA2 ) || + (c_xfrm->cipher.algo ==RTE_CRYPTO_CIPHER_ZUC_EEA3 )) + en_priv->flags.is_ciph_in_bits =1 ; + +/** +* flags.is_auth_in_bits +* +* For ZUC & SNOW3G authentication algos, offset & length need to be provided in bits.
lib/pdcp/pdcp_process.c new file +4
-0+*/ + +if (a_xfrm !=NULL ) { + if ((a_xfrm->auth.algo == RTE_CRYPTO_AUTH_SNOW3G_UIA2)||
lib/pdcp/pdcp_process.c new file +19
-0+ (a_xfrm->auth.algo == RTE_CRYPTO_AUTH_ZUC_EIA3)) + en_priv->flags.is_auth_in_bits = 1; + } + +/** +* flags.is_ul_entity +* +* Indicate whether the entity is UL/transmitting PDCP entity. +*/ +if (conf->pdcp_xfrm.pkt_dir ==RTE_SECURITY_PDCP_UPLINK ) + en_priv->flags.is_ul_entity =1 ; + +/** +* flags.is_null_auth +* +* For NULL auth, 4B zeros need to be added by lib PDCP. Indicate that +* algo is NULL auth to perform the same. +*/ + if (a_xfrm != NULL && a_xfrm->auth.algo ==
RTE_CRYPTO_AUTH_NULL)lib/pdcp/pdcp_process.c new file +13
-0+ en_priv->flags.is_null_auth =1 ; + +/** +* hdr_sz +* +* PDCP header size of the entity +*/ + en_priv->hdr_sz =pdcp_hdr_size_get (conf->pdcp_xfrm.sn_size); + +/** +* aad_sz +* +* For AES-CMAC, additional message is prepended for processing. Need to be trimmed after
lib/pdcp/pdcp_process.c new file +3
-0+* crypto processing is done. +*/ + if (a_xfrm != NULL && a_xfrm->auth.algo ==
RTE_CRYPTO_AUTH_AES_CMAC)lib/pdcp/pdcp_process.c new file +9
-0+ en_priv->aad_sz =8 ; + else + en_priv->aad_sz = 0; + +return 0 ; +} + +int +pdcp_process_func_set(struct rte_pdcp_entity *entity, const struct
rte_pdcp_entity_conf*conf)lib/pdcp/pdcp_process.c new file +15
-0+{ +struct entity_priv *en_priv; +int ret; + +if (entity ==NULL || conf ==NULL ) +return -EINVAL ; + + en_priv =entity_priv_get (entity); + + ret =pdcp_entity_priv_populate (en_priv, conf); +if (ret) +return ret; + +return 0 ; +}lib/pdcp/pdcp_process.h new file +11
-0@@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2023 Marvell. +*/ + +#ifndef PDCP_PROCESS_H +#define PDCP_PROCESS_H + +#include <rte_pdcp.h> + +int +pdcp_process_func_set(struct rte_pdcp_entity *entity, const struct
rte_pdcp_entity_conf*conf);lib/pdcp/pdcp_process.h new file +2
-0+ +#endif /* PDCP_PROCESS_H */ lib/pdcp/rte_pdcp.c new file +30
-0@@ -0,0 +1,138 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2023 Marvell. +*/ + +#include <rte_errno.h> +#include <rte_pdcp.h> +#include <rte_malloc.h> + +#include "pdcp_crypto.h" +#include "pdcp_entity.h" +#include "pdcp_process.h" + +static int +pdcp_entity_size_get (const struct rte_pdcp_entity_conf *conf) +{ +int size; + + size =sizeof (struct rte_pdcp_entity ) +sizeof (struct entity_priv ); + +if (conf->pdcp_xfrm.pkt_dir ==RTE_SECURITY_PDCP_DOWNLINK ) + size +=sizeof (struct entity_priv_dl_part ); +else if (conf->pdcp_xfrm.pkt_dir ==RTE_SECURITY_PDCP_UPLINK ) + size +=sizeof (struct entity_priv_ul_part ); +else +return -EINVAL ; + +return RTE_ALIGN_CEIL (size,RTE_CACHE_LINE_SIZE ); +} + +struct rte_pdcp_entity *
lib/pdcp/rte_pdcp.c line 40
Quoted 10 lines
lib/pdcp/rte_pdcp.c new file +10
-0+rte_pdcp_entity_establish(const struct rte_pdcp_entity_conf *conf) +{ +struct rte_pdcp_entity *entity =NULL ; +struct entity_priv *en_priv; +int ret, entity_size; + +if (conf ==NULL || conf->cop_pool ==NULL ) { + rte_errno = -EINVAL ; +return NULL ; + }
errnos are normally set as positive values.
Quoted 14 lines
lib/pdcp/rte_pdcp.c new file +2
-0+ + if (conf->pdcp_xfrm.en_ordering || conf-Quoted 1 line
pdcp_xfrm.remove_duplicates ||
conf->is_slrb||lib/pdcp/rte_pdcp.c new file +8
-0+ conf->en_sec_offload) { + rte_errno = -ENOTSUP ; +return NULL ; + } + +/* +* 6.3.2 PDCP SN +* Length: 12 or 18 bits as indicated in table 6.3.2-1. The length of the PDCP SN is
lib/pdcp/rte_pdcp.c new file +1
-0+* configured by upper layers (pdcp-SN-SizeUL, pdcp-SN-SizeDL, or sl- PDCP-SN-Size in
lib/pdcp/rte_pdcp.c line 58
Quoted 7 lines
lib/pdcp/rte_pdcp.c new file +7
-0+* TS 38.331 [3]) +*/ +if ((conf->pdcp_xfrm.sn_size !=RTE_SECURITY_PDCP_SN_SIZE_12 ) && + (conf->pdcp_xfrm.sn_size !=RTE_SECURITY_PDCP_SN_SIZE_18 )) { + rte_errno = -ENOTSUP ; +return NULL ; + }
Check for PDCP crypto algos may also be added.
As only 4 cipher and 4 auth algos are supported in case of PDCP.
lib/pdcp/rte_pdcp.c line 63
Quoted 5 lines
lib/pdcp/rte_pdcp.c new file +5
-0+ +if (conf->pdcp_xfrm.hfn || conf->pdcp_xfrm.hfn_threshold) { + rte_errno = -EINVAL ; +return NULL ; + }
What is the reason to set errno as EINVAL when HFN is set?
Quoted 86 lines
lib/pdcp/rte_pdcp.c new file +8
-0+ + entity_size =pdcp_entity_size_get (conf); +if (entity_size <0 ) { + rte_errno = -EINVAL ; +return NULL ; + } + + entity = rte_zmalloc_socket("pdcp_entity", entity_size,
RTE_CACHE_LINE_SIZE,SOCKET_ID_ANY);lib/pdcp/rte_pdcp.c new file +32
-0+if (entity ==NULL ) { + rte_errno = -ENOMEM ; +return NULL ; + } + + en_priv =entity_priv_get (entity); + + en_priv->state.rx_deliv = conf->count; + en_priv->state.tx_next = conf->count; + en_priv->cop_pool = conf->cop_pool; + +/* Setup crypto session */ + ret =pdcp_crypto_sess_create (entity, conf); +if (ret) + goto entity_free; + + ret =pdcp_process_func_set (entity, conf); +if (ret) + goto crypto_sess_destroy; + +return entity; + +crypto_sess_destroy: +pdcp_crypto_sess_destroy (entity); +entity_free: +rte_free (entity); + rte_errno = ret; +return NULL ; +} + +int +rte_pdcp_entity_release(struct rte_pdcp_entity *pdcp_entity, struct rte_mbuf*out_mb[])
lib/pdcp/rte_pdcp.c new file +35
-0+{ +if (pdcp_entity ==NULL ) +return -EINVAL ; + +/* Teardown crypto sessions */ +pdcp_crypto_sess_destroy (pdcp_entity); + +rte_free (pdcp_entity); + +RTE_SET_USED (out_mb); +return 0 ; +} + +int +rte_pdcp_entity_suspend (struct rte_pdcp_entity *pdcp_entity, +struct rte_mbuf *out_mb[]) +{ +struct entity_priv *en_priv; + +if (pdcp_entity ==NULL ) +return -EINVAL ; + + en_priv =entity_priv_get (pdcp_entity); + +if (en_priv->flags.is_ul_entity) { + en_priv->state.tx_next =0 ; + }else { + en_priv->state.rx_next =0 ; + en_priv->state.rx_deliv =0 ; + } + +RTE_SET_USED (out_mb); + +return 0 ; +}lib/pdcp/rte_pdcp.h new file +3
-0@@ -0,0 +1,157 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2023 Marvell. +*/
lib/pdcp/rte_pdcp.h line 13
Quoted 10 lines
lib/pdcp/rte_pdcp.h new file +10
-0+ +#ifndef RTE_PDCP_H +#define RTE_PDCP_H + +/** +* @file rte_pdcp.h +* +* RTE PDCP support. +* +* librte_pdcp provides a framework for PDCP protocol processing.
A framework for PDCP protocol processing.
lib/pdcp/rte_pdcp.h line 26
Quoted 13 lines
lib/pdcp/rte_pdcp.h new file +13
-0+*/ + +#include <rte_compat.h> +#include <rte_common.h> +#include <rte_mempool.h> +#include <rte_security.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** +* PDCP entity.
You can probably explain more on what a PDCP entity is.
Quoted 11 lines
lib/pdcp/rte_pdcp.h new file +10
-0+*/ +struct rte_pdcp_entity { +/** +* PDCP entities may hold packets for purposes of in-order delivery (in +* case of receiving PDCP entity) and re-transmission (in case of +* transmitting PDCP entity). +* +* For receiving PDCP entity, it may hold packets when in-order +* delivery is enabled. The packets would be cached until either a +* packet that completes the sequence arrives or when t-Reordering timer
lib/pdcp/rte_pdcp.h line 43
Quoted 7 lines
lib/pdcp/rte_pdcp.h new file +7
-0+* expires. +* +* When post-processing of PDCP packet which completes a sequence is +* done, the API may return more packets than enqueued. Application is +* expected to provide *rte_pdcp_pkt_post_process()* with *out_mb* +* which can hold maximum number of packets which may be returned. +*/
The above comment explains the need for holding the packets.
But it does not talk about the parameter it is explaining.
This explanation should be part of programmer's guide and not the API guide.
lib/pdcp/rte_pdcp.h line 46
Quoted 3 lines
lib/pdcp/rte_pdcp.h new file +3
-0+uint32_t max_pkt_cache; +/** User area for saving application data. */ +uint64_t user_area[2 ];
Is it being used right now in the patches? If not, can we add it later?
And if really needed now, can we rename to user_data
Quoted 19 lines
lib/pdcp/rte_pdcp.h new file +18
-0+} __rte_cache_aligned; + +/** +* PDCP entity configuration to be used for establishing an entity. +*/ +/* Structure rte_pdcp_entity_conf 8< */ +struct rte_pdcp_entity_conf { +/** PDCP transform for the entity. */ +struct rte_security_pdcp_xform pdcp_xfrm; +/** Crypto transform applicable for the entity. */ +struct rte_crypto_sym_xform *crypto_xfrm; +/** Mempool for crypto symmetric session. */ +struct rte_mempool *sess_mpool; +/** Crypto op pool.*/ +struct rte_mempool *cop_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.
lib/pdcp/rte_pdcp.h
Quoted 1 line
lib/pdcp/rte_pdcp.h new file +1
-0+*/
If the HFN is to be ignored, then why to add a check in entity establish and return EINVAL? It should be silently ignored in that case with a debug print at max.
Quoted 114 lines
lib/pdcp/rte_pdcp.h new file +2
-0+uint32_t count; +/** Indicate whether the PDCP entity belongs to Side Link Radio Bearer. */
lib/pdcp/rte_pdcp.h new file +6
-0+bool is_slrb; +/** Enable security offload on the device specified. */ +bool en_sec_offload; +/** Device on which security/crypto session need to be created. */ +uint8_t dev_id; +/** Reverse direction during IV generation. Can be used to simulate UE crypto processing.*/
lib/pdcp/rte_pdcp.h new file +39
-0+bool reverse_iv_direction; +}; +/* >8 End of structure rte_pdcp_entity_conf. */ + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice +* +* 5.1.1 PDCP entity establishment +* +* Establish PDCP entity based on provided input configuration. +* +* @param conf +* Parameters to be used for initializing PDCP entity object. +* @return +* - Valid handle if success +* - NULL in case of failure. rte_errno will be set to error code +*/ +__rte_experimental +struct rte_pdcp_entity * +rte_pdcp_entity_establish (const struct rte_pdcp_entity_conf *conf); + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice +* +* 5.1.3 PDCP entity release +* +* Release PDCP entity. +* +* For UL/transmitting PDCP entity, all stored PDCP SDUs would be dropped. +* For DL/receiving PDCP entity, the stored PDCP SDUs would be returned in +* *out_mb* buffer. The buffer should be large enough to hold all cached +* packets in the entity. +* +* @param pdcp_entity +* Pointer to the PDCP entity to be released. +* @param[out] out_mb +* The address of an array that can hold up to *rte_pdcp_entity.max_pkt_cache*
+ * pointers to *rte_mbuf* structures.
+ * @return+ * - 0: Success and no cached packets to return + * - >0: Success and the number of packets returned in out_mb + * - <0: Error code in case of failures+ */
lib/pdcp/rte_pdcp.h new file +23
-0+__rte_experimental +int +rte_pdcp_entity_release (struct rte_pdcp_entity *pdcp_entity, +struct rte_mbuf *out_mb[]); + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice +* +* 5.1.4 PDCP entity suspend +* +* Suspend PDCP entity. +* +* For DL/receiving PDCP entity, the stored PDCP SDUs would be returned in +* *out_mb* buffer. The buffer should be large enough to hold all cached +* packets in the entity. +* +* For UL/transmitting PDCP entity, *out_mb* buffer would be unused. +* +* @param pdcp_entity +* Pointer to the PDCP entity to be suspended. +* @param[out] out_mb +* The address of an array that can hold up to *rte_pdcp_entity.max_pkt_cache*
+ * pointers to *rte_mbuf* structures.
+ * @return+ * - 0: Success and no cached packets to return + * - >0: Success and the number of packets returned in out_mb + * - <0: Error code in case of failures+ */
lib/pdcp/rte_pdcp.h new file +10
-0+__rte_experimental +int +rte_pdcp_entity_suspend (struct rte_pdcp_entity *pdcp_entity, +struct rte_mbuf *out_mb[]); + +#ifdef __cplusplus +} +#endif + +#endif /* RTE_PDCP_H */ lib/pdcp/version.map new file +10
-1@@ -0,0 +1,10 @@ +EXPERIMENTAL { + global: + + # added in 23.07 + rte_pdcp_entity_establish; + rte_pdcp_entity_release; + rte_pdcp_entity_suspend; + + local: *; +}; --2.25.1
Hi Akhil,
Thanks for the review. Please see inline.
Thanks,
Anoob
Quoted 13 lines
-----Original Message-----
From: Akhil Goyal <[email protected]>
Sent: Tuesday, May 16, 2023 9:01 PM
To: Anoob Joseph <[email protected]>; Thomas Monjalon <[email protected]>; Jerin Jacob Kollanukkaran <[email protected]>; Konstantin Ananyev <[email protected]>; Bernard Iremonger <[email protected]>
Cc: Hemant Agrawal <[email protected]>; Mattias Rönnblom <[email protected]>; Kiran Kumar Kokkilagadda <[email protected]>; Volodymyr Fialko <[email protected]>; [email protected]; Olivier Matz <[email protected]>
Subject: RE: [PATCH v2 02/22] lib: add pdcp protocol
Quoted 3 lines
Hi Anoob,
Fix check patch issues and please see some inline comments.
[Anoob] Checkpatch warnings are false positives. I'll try to work around couple of them. Rest we may need to ignore.
Quoted 313 lines
Quoted 19 lines
Subject: [PATCH v2 02/22] lib: add pdcp protocol
Add Packet Data Convergence Protocol (PDCP) processing library.
The library is similar to
lib_ipsecwhich provides IPsec processing capabilities in DPDK.PDCP would involve roughly the following options, 1. Transfer of user plane data 2. Transfer of control plane data 3. Header compression 4. Uplink data compression 5. Ciphering and integrity protection
PDCP library provides following control path APIs that is used to configure various PDCP entities, 1.
rte_pdcp_entity_establish()2.rte_pdcp_entity_suspend()3.rte_pdcp_entity_release()Signed-off-by Anoob Joseph <[email protected]>Signed-off-by Kiran Kumar K <[email protected]>Signed-off-by Volodymyr Fialko <[email protected]>Quoted 9 lines
--- doc/api/doxy-api-index.md | 3 +- doc/api/doxy-api.conf.in | 1 + lib/meson.build | 1 + lib/pdcp/meson.build | 17 +++++ lib/pdcp/pdcp_crypto.c | 21 +++++ lib/pdcp/pdcp_crypto.h | 15 ++++ lib/pdcp/pdcp_entity.h | 95 +++++++++++++++++++++++ lib/pdcp/pdcp_process.c | 138+++++++++++++++++++++++++++++++++
Quoted 3 lines
lib/pdcp/pdcp_process.h | 13 ++++ lib/pdcp/rte_pdcp.c | 138 +++++++++++++++++++++++++++++++++ lib/pdcp/rte_pdcp.h | 157++++++++++++++++++++++++++++++++++++++
Quoted 167 lines
lib/pdcp/version.map | 10 +++ 12 files changed, 608 insertions(+), 1 deletion(-) create mode100644
lib/pdcp/meson.buildcreate mode 100644lib/pdcp/pdcp_crypto.ccreate mode 100644lib/pdcp/pdcp_crypto.hcreate mode 100644lib/pdcp/pdcp_entity.hcreate mode 100644lib/pdcp/pdcp_process.ccreate mode 100644lib/pdcp/pdcp_process.hcreate mode 100644lib/pdcp/rte_pdcp.ccreate mode 100644lib/pdcp/rte_pdcp.hcreate mode 100644lib/pdcp/version.mapdoc/api/doxy-api-index.md +2
-1@@ -128,7 +128,8 @@ The public API headers are grouped by topics: [eCPRI](@ref rte_ecpri.h), [L2TPv2](@ref rte_l2tpv2.h), [PPP](@ref rte_ppp.h), - [PDCP hdr](@ref rte_pdcp_hdr.h) + [PDCP hdr](@ref rte_pdcp_hdr.h), + [PDCP](@ref rte_pdcp.h) - **QoS**: [metering](@ref rte_meter.h),doc/api/doxy-api.conf.in index renamed from doc/api/doxy-api.conf.in +0
-0
d230a19e1f..58789308a9100644doc/api/doxy-api.conf.in +1
-0@@ -62,6 +62,7 @@ INPUT = @TOPDIR@/doc/api/doxy-api- index.md \ @TOPDIR@/lib/net \ @TOPDIR@/lib/pcapng \ @TOPDIR@/lib/pci \ + @TOPDIR@/lib/pdcp \ @TOPDIR@/lib/pdump \ @TOPDIR@/lib/pipeline \@TOPDIR@/lib/port \ diff --gita/lib/meson.build b/lib/meson.build index
0812ce6026..d217c04ea9100644lib/meson.build +1
-0@@ -64,6 +64,7 @@ libraries = [ 'flow_classify', # flow_classify lib depends on pkt framework table lib 'graph', 'node', + 'pdcp', # pdcp lib depends on crypto and security ] optional_libs = [lib/pdcp/meson.build new file mode renamed from lib/pdcp/meson.build +0
-0100644 index 0000000000..ccaf426240
lib/pdcp/meson.build new file +16
-0@@ -0,0 +1,17 @@ +# SPDX-License-Identifier: BSD-3-Clause # Copyright(C) 2023 Marvell. + +if is_windows + build = false + reason = 'not supported on Windows' + subdir_done() +endif + +sources = files( + 'pdcp_crypto.c', + 'pdcp_process.c', + 'rte_pdcp.c', + ) +headers = files('rte_pdcp.h') + +deps += ['mbuf', 'net', 'cryptodev', 'security']lib/pdcp/pdcp_crypto.c new file renamed from lib/pdcp/pdcp_crypto.c +0
-0mode 100644 index 0000000000..755e27ec9e
lib/pdcp/pdcp_crypto.c new file +10
-0@@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2023 Marvell. +*/ + +#include <rte_pdcp.h> + +#include "pdcp_crypto.h" + +int +pdcp_crypto_sess_create(struct rte_pdcp_entity *entity, const struct
rte_pdcp_entity_conf*conf)lib/pdcp/pdcp_crypto.c new file +10
-0+{ +RTE_SET_USED (entity); +RTE_SET_USED (conf); +return 0 ; +} + +void +pdcp_crypto_sess_destroy (struct rte_pdcp_entity *entity) { +RTE_SET_USED (entity); +}lib/pdcp/pdcp_crypto.h new file renamed from lib/pdcp/pdcp_crypto.h +0
-0mode 100644 index 0000000000..6563331d37
lib/pdcp/pdcp_crypto.h new file +15
-0@@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2023 Marvell. +*/ + +#ifndef PDCP_CRYPTO_H +#define PDCP_CRYPTO_H + +#include <rte_pdcp.h> + +int pdcp_crypto_sess_create (struct rte_pdcp_entity *entity, +const struct rte_pdcp_entity_conf *conf); + +void pdcp_crypto_sess_destroy (struct rte_pdcp_entity *entity); + +#endif /* PDCP_CRYPTO_H */ lib/pdcp/pdcp_entity.h new file renamed from lib/pdcp/pdcp_entity.h +0
-0mode 100644 index 0000000000..ca1d56b516
lib/pdcp/pdcp_entity.h new file +18
-0@@ -0,0 +1,95 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2023 Marvell. +*/ + +#ifndef PDCP_ENTITY_H +#define PDCP_ENTITY_H + +#include <rte_common.h> +#include <rte_crypto_sym.h> +#include <rte_mempool.h> +#include <rte_pdcp.h> +#include <rte_security.h> + +struct entity_priv ; + +/* IV generation function based on the entity configuration */ +typedef void (*iv_gen_t )(struct rte_crypto_op *cop,const struct +entity_priv
*en_priv,lib/pdcp/pdcp_entity.h new file +28
-0+ uint32_t count); + +struct entity_state { +uint32_t rx_next; +uint32_t tx_next; +uint32_t rx_deliv; +uint32_t rx_reord; +}; + +/* +* Layout of PDCP entity: [rte_pdcp_entity] [entity_priv] +[entity_dl/ul] */ + +struct entity_priv { +/** Crypto sym session. */ +struct rte_cryptodev_sym_session *crypto_sess; +/** Entity specific IV generation function. */ +iv_gen_t iv_gen; +/** Entity state variables. */ +struct entity_state state; +/** Flags. */ +struct { +/** PDCP PDU has 4 byte MAC-I. */ +uint64_t is_authenticated :1 ; +/** Cipher offset & length in bits. */ +uint64_t is_ciph_in_bits :1 ; +/** Auth offset & length in bits. */ +uint64_t is_auth_in_bits :1 ;lib/pdcp/pdcp_entity.h
Quoted 10 lines
lib/pdcp/pdcp_entity.h new file +10
-0+/** Is UL/transmitting PDCP entity. */ + uint64_t is_ul_entity : 1; +/** Is NULL auth. */ + uint64_t is_null_auth : 1; + } flags; +/** Crypto op pool. */ +struct rte_mempool *cop_pool; +/** PDCP header size. */ +uint8_t hdr_sz; +/** PDCP AAD size. For AES-CMAC, additional message is prepended for
Quoted 10 lines
the operation. */
lib/pdcp/pdcp_entity.h new file +8
-0+uint8_t aad_sz; +/** Device ID of the device to be used for offload. */ +uint8_t dev_id; +}; + +struct entity_priv_dl_part { +/* NOTE: when in-order-delivery is supported, post PDCP packets +would need to cached. */
lib/pdcp/pdcp_entity.h
Quoted 6 lines
lib/pdcp/pdcp_entity.h new file +6
-0+uint8_t dummy; +}; + +struct entity_priv_ul_part { +/* +* NOTE: when re-establish is supported, plain PDCP packets & COUNT
Quoted 50 lines
values need to be
lib/pdcp/pdcp_entity.h new file +12
-0+* cached. +*/ +uint8_t dummy; +}; + +static inline struct entity_priv * +entity_priv_get (const struct rte_pdcp_entity *entity) { +return RTE_PTR_ADD (entity,sizeof (struct rte_pdcp_entity )); } + +static inline struct entity_priv_dl_part *entity_dl_part_get (const +struct rte_pdcp_entity *entity) { + return RTE_PTR_ADD(entity, sizeof(struct rte_pdcp_entity) +
sizeof(struct entity_priv));lib/pdcp/pdcp_entity.h new file +5
-0+} + +static inline struct entity_priv_ul_part *entity_ul_part_get (const +struct rte_pdcp_entity *entity) { + return RTE_PTR_ADD(entity, sizeof(struct rte_pdcp_entity) +
sizeof(struct entity_priv));lib/pdcp/pdcp_entity.h new file +7
-0+} + +static inline int +pdcp_hdr_size_get (enum rte_security_pdcp_sn_size sn_size) { +return RTE_ALIGN_MUL_CEIL (sn_size,8 ) /8 ; } + +#endif /* PDCP_ENTITY_H */ lib/pdcp/pdcp_process.c new renamed from lib/pdcp/pdcp_process.c +0
-0file mode 100644 index 0000000000..d4b158536d
lib/pdcp/pdcp_process.c new file +17
-0@@ -0,0 +1,138 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2023 Marvell. +*/ + +#include <rte_crypto.h> +#include <rte_crypto_sym.h> +#include <rte_cryptodev.h> +#include <rte_memcpy.h> +#include <rte_pdcp.h> +#include <rte_pdcp_hdr.h> + +#include "pdcp_crypto.h" +#include "pdcp_entity.h" +#include "pdcp_process.h" + +static int +pdcp_crypto_xfrm_get(const struct rte_pdcp_entity_conf *conf, struct
rte_crypto_sym_xform**c_xfrm,lib/pdcp/pdcp_process.c
Quoted 8 lines
lib/pdcp/pdcp_process.c new file +8
-0+ struct rte_crypto_sym_xform **a_xfrm) { + *c_xfrm =NULL ; + *a_xfrm =NULL ; + +if (conf->crypto_xfrm ==NULL ) +return -EINVAL ; + +if (conf->crypto_xfrm->type ==RTE_CRYPTO_SYM_XFORM_CIPHER ){
Quoted 26 lines
lib/pdcp/pdcp_process.c new file +3
-0+ *c_xfrm = conf->crypto_xfrm; + *a_xfrm = conf->crypto_xfrm->next; + } else if (conf->crypto_xfrm->type ==
RTE_CRYPTO_SYM_XFORM_AUTH) {lib/pdcp/pdcp_process.c new file +11
-0+ *a_xfrm = conf->crypto_xfrm; + *c_xfrm = conf->crypto_xfrm->next; + }else { +return -EINVAL ; + } + +return 0 ; +} + +static int +pdcp_entity_priv_populate(struct entity_priv *en_priv, const struct
rte_pdcp_entity_conf*conf)lib/pdcp/pdcp_process.c new file +8
-0+{ +struct rte_crypto_sym_xform *c_xfrm, *a_xfrm; +int ret; + +/** +* flags.is_authenticated +* +* MAC-I would be added in case of control plane packets and when authentication
lib/pdcp/pdcp_process.c new file +1
-0+* transform is not NULL.
Quoted 8 lines
lib/pdcp/pdcp_process.c
Quoted 5 lines
lib/pdcp/pdcp_process.c new file +3
-0+*/ + + if (conf->pdcp_xfrm.domain ==
RTE_SECURITY_PDCP_MODE_CONTROL)lib/pdcp/pdcp_process.c new file +1
-0+ en_priv->flags.is_authenticated =1 ;This check should be added after getting the xfrm.
If domain == control anda_xfrmis NULL, then it should be error, right?
[Anoob] Lib PDCP would handle such cases. Even if a_xfrm is non NULL but is NULL auth, it is lib PDCP which would add zeroized digest. And a_xfrm == NULL is also treated as NULL auth generally. The comment above this explains the same. Idea is to have lib PDCP handle all possible cases rather than putting too much restrictions on both app & PMD.
Quoted 154 lines
Quoted 15 lines
lib/pdcp/pdcp_process.c new file +13
-0+ + ret =pdcp_crypto_xfrm_get (conf, &c_xfrm, &a_xfrm); +if (ret) +return ret; + +if (a_xfrm !=NULL ) + en_priv->flags.is_authenticated =1 ; + +/** +* flags.is_ciph_in_bits +* +* For ZUC & SNOW3G cipher algos, offset & length need to be +provided in bits.
lib/pdcp/pdcp_process.c
Quoted 3 lines
lib/pdcp/pdcp_process.c new file +3
-0+*/ + + if ((c_xfrm->cipher.algo == RTE_CRYPTO_CIPHER_SNOW3G_UEA2)|| > + (c_xfrm->cipher.algo == RTE_CRYPTO_CIPHER_ZUC_EEA3))lib/pdcp/pdcp_process.c
Quoted 6 lines
lib/pdcp/pdcp_process.c new file +6
-0+ en_priv->flags.is_ciph_in_bits =1 ; + +/** +* flags.is_auth_in_bits +* +* For ZUC & SNOW3G authentication algos, offset & length need to be
lib/pdcp/pdcp_process.c
Quoted 5 lines
provided in bits.
lib/pdcp/pdcp_process.c new file +4
-0+*/ + +if (a_xfrm !=NULL ) { + if ((a_xfrm->auth.algo ==
RTE_CRYPTO_AUTH_SNOW3G_UIA2)Quoted 7 lines
||
lib/pdcp/pdcp_process.c new file +6
-0+ (a_xfrm->auth.algo == RTE_CRYPTO_AUTH_ZUC_EIA3)) + en_priv->flags.is_auth_in_bits = 1; + } + +/** +* flags.is_ul_entity lib/pdcp/pdcp_process.c
Quoted 10 lines
lib/pdcp/pdcp_process.c new file +10
-0+* +* Indicate whether the entity is UL/transmitting PDCP entity. +*/ +if (conf->pdcp_xfrm.pkt_dir ==RTE_SECURITY_PDCP_UPLINK ) + en_priv->flags.is_ul_entity =1 ; + +/** +* flags.is_null_auth +* +* For NULL auth, 4B zeros need to be added by lib PDCP. Indicate that
Quoted 103 lines
lib/pdcp/pdcp_process.c new file +3
-0+* algo is NULL auth to perform the same. +*/ + if (a_xfrm != NULL && a_xfrm->auth.algo ==
RTE_CRYPTO_AUTH_NULL)lib/pdcp/pdcp_process.c new file +14
-0+ en_priv->flags.is_null_auth =1 ; + +/** +* hdr_sz +* +* PDCP header size of the entity +*/ + en_priv->hdr_sz =pdcp_hdr_size_get (conf->pdcp_xfrm.sn_size); + +/** +* aad_sz +* +* For AES-CMAC, additional message is prepended for processing. +Need to be trimmed after
lib/pdcp/pdcp_process.c new file +3
-0+* crypto processing is done. +*/ + if (a_xfrm != NULL && a_xfrm->auth.algo ==
RTE_CRYPTO_AUTH_AES_CMAC)lib/pdcp/pdcp_process.c new file +9
-0+ en_priv->aad_sz =8 ; + else + en_priv->aad_sz = 0; + +return 0 ; +} + +int +pdcp_process_func_set(struct rte_pdcp_entity *entity, const struct
rte_pdcp_entity_conf*conf)lib/pdcp/pdcp_process.c new file +15
-0+{ +struct entity_priv *en_priv; +int ret; + +if (entity ==NULL || conf ==NULL ) +return -EINVAL ; + + en_priv =entity_priv_get (entity); + + ret =pdcp_entity_priv_populate (en_priv, conf); +if (ret) +return ret; + +return 0 ; +}lib/pdcp/pdcp_process.h new renamed from lib/pdcp/pdcp_process.h +0
-0file mode 100644 index 0000000000..fd53fff0aa
lib/pdcp/pdcp_process.h new file +11
-0@@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2023 Marvell. +*/ + +#ifndef PDCP_PROCESS_H +#define PDCP_PROCESS_H + +#include <rte_pdcp.h> + +int +pdcp_process_func_set(struct rte_pdcp_entity *entity, const struct
rte_pdcp_entity_conf*conf);lib/pdcp/pdcp_process.h new file +2
-0+ +#endif /* PDCP_PROCESS_H */ lib/pdcp/rte_pdcp.c new file mode renamed from lib/pdcp/rte_pdcp.c +0
-0100644 index 0000000000..8914548dbd
lib/pdcp/rte_pdcp.c new file +31
-0@@ -0,0 +1,138 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2023 Marvell. +*/ + +#include <rte_errno.h> +#include <rte_pdcp.h> +#include <rte_malloc.h> + +#include "pdcp_crypto.h" +#include "pdcp_entity.h" +#include "pdcp_process.h" + +static int +pdcp_entity_size_get (const struct rte_pdcp_entity_conf *conf) { +int size; + + size =sizeof (struct rte_pdcp_entity ) +sizeof (struct entity_priv ); + +if (conf->pdcp_xfrm.pkt_dir ==RTE_SECURITY_PDCP_DOWNLINK ) + size +=sizeof (struct entity_priv_dl_part ); +else if (conf->pdcp_xfrm.pkt_dir ==RTE_SECURITY_PDCP_UPLINK ) + size +=sizeof (struct entity_priv_ul_part ); +else +return -EINVAL ; + +return RTE_ALIGN_CEIL (size,RTE_CACHE_LINE_SIZE ); } + +struct rte_pdcp_entity * +rte_pdcp_entity_establish (const struct rte_pdcp_entity_conf *conf) { +struct rte_pdcp_entity *entity =NULL ; +struct entity_priv *en_priv;
Quoted 8 lines
lib/pdcp/rte_pdcp.c line 40
Quoted 6 lines
lib/pdcp/rte_pdcp.c new file +6
-0+int ret, entity_size; + +if (conf ==NULL || conf->cop_pool ==NULL ) { + rte_errno = -EINVAL ; +return NULL ; + }errnos are normally set as positive values.
[Anoob] I do not think so. I checked rte_ethdev.h, rte_flow.h etc and all APIs are returning negative values in case of errors.
Quoted 22 lines
Quoted 18 lines
lib/pdcp/rte_pdcp.c new file +2
-0+ + if (conf->pdcp_xfrm.en_ordering || conf-Quoted 1 line
pdcp_xfrm.remove_duplicates ||
conf->is_slrb||lib/pdcp/rte_pdcp.c new file +9
-0+ conf->en_sec_offload) { + rte_errno = -ENOTSUP ; +return NULL ; + } + +/* +* 6.3.2 PDCP SN +* Length: 12 or 18 bits as indicated in table 6.3.2-1. The length +of the PDCP SN is
lib/pdcp/rte_pdcp.c new file +2
-0+ * configured by upper layers (pdcp-SN-SizeUL, pdcp-SN-SizeDL, or +sl-PDCP-SN-Size in
lib/pdcp/rte_pdcp.c
Quoted 3 lines
lib/pdcp/rte_pdcp.c new file +3
-0+* TS 38.331 [3]) +*/ + if ((conf->pdcp_xfrm.sn_size != RTE_SECURITY_PDCP_SN_SIZE_12)&&
Quoted 7 lines
lib/pdcp/rte_pdcp.c line 58
Quoted 4 lines
lib/pdcp/rte_pdcp.c new file +4
-0+ (conf->pdcp_xfrm.sn_size != RTE_SECURITY_PDCP_SN_SIZE_18)) { + rte_errno = -ENOTSUP ; +return NULL ; + }Check for PDCP crypto algos may also be added.
As only 4 cipher and 4 auth algos are supported in case of PDCP.
[Anoob] Validation happens when we create session. Please check,
pdcp: add crypto session create and destroy
Quoted 8 lines
lib/pdcp/rte_pdcp.c line 63
Quoted 6 lines
lib/pdcp/rte_pdcp.c new file +5
-0+ +if (conf->pdcp_xfrm.hfn || conf->pdcp_xfrm.hfn_threshold) { + rte_errno = -EINVAL ; +return NULL ; + }What is the reason to set errno as EINVAL when HFN is set?
[Anoob] HFN is part of pdcp_xfrm which is defined in rte_security. Lib PDCP allows user to specify complete 32 bit count value using rte_pdcp_entity_conf.count. Since HFN is also used to construct 32 bit count value, having two ways to set count would be misleading. Hence lib PDCP would enforce that application does not set this value.
Quoted 91 lines
Quoted 91 lines
lib/pdcp/rte_pdcp.c new file +8
-0+ + entity_size =pdcp_entity_size_get (conf); +if (entity_size <0 ) { + rte_errno = -EINVAL ; +return NULL ; + } + + entity = rte_zmalloc_socket("pdcp_entity", entity_size,
RTE_CACHE_LINE_SIZE,SOCKET_ID_ANY);lib/pdcp/rte_pdcp.c new file +33
-0+if (entity ==NULL ) { + rte_errno = -ENOMEM ; +return NULL ; + } + + en_priv =entity_priv_get (entity); + + en_priv->state.rx_deliv = conf->count; + en_priv->state.tx_next = conf->count; + en_priv->cop_pool = conf->cop_pool; + +/* Setup crypto session */ + ret =pdcp_crypto_sess_create (entity, conf); +if (ret) + goto entity_free; + + ret =pdcp_process_func_set (entity, conf); +if (ret) + goto crypto_sess_destroy; + +return entity; + +crypto_sess_destroy: +pdcp_crypto_sess_destroy (entity); +entity_free: +rte_free (entity); + rte_errno = ret; +return NULL ; +} + +int +rte_pdcp_entity_release (struct rte_pdcp_entity *pdcp_entity,struct +rte_mbuf*out_mb[])
lib/pdcp/rte_pdcp.c new file +35
-0+{ +if (pdcp_entity ==NULL ) +return -EINVAL ; + +/* Teardown crypto sessions */ +pdcp_crypto_sess_destroy (pdcp_entity); + +rte_free (pdcp_entity); + +RTE_SET_USED (out_mb); +return 0 ; +} + +int +rte_pdcp_entity_suspend (struct rte_pdcp_entity *pdcp_entity, +struct rte_mbuf *out_mb[]) +{ +struct entity_priv *en_priv; + +if (pdcp_entity ==NULL ) +return -EINVAL ; + + en_priv =entity_priv_get (pdcp_entity); + +if (en_priv->flags.is_ul_entity) { + en_priv->state.tx_next =0 ; + }else { + en_priv->state.rx_next =0 ; + en_priv->state.rx_deliv =0 ; + } + +RTE_SET_USED (out_mb); + +return 0 ; +}lib/pdcp/rte_pdcp.h new file mode renamed from lib/pdcp/rte_pdcp.h +0
-0100644 index 0000000000..33c355b05a
lib/pdcp/rte_pdcp.h new file +7
-0@@ -0,0 +1,157 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2023 Marvell. +*/ + +#ifndef RTE_PDCP_H +#define RTE_PDCP_H +
Quoted 8 lines
lib/pdcp/rte_pdcp.h line 13
Quoted 6 lines
lib/pdcp/rte_pdcp.h new file +6
-0+/** +* @file rte_pdcp.h +* +* RTE PDCP support. +* +* librte_pdcp provides a framework for PDCP protocol processing. A framework for PDCP protocol processing.
[Anoob] Will do next version.
Quoted 16 lines
Quoted 4 lines
lib/pdcp/rte_pdcp.h new file +3
-0+*/ + +#include <rte_compat.h> lib/pdcp/rte_pdcp.h line 26
Quoted 10 lines
lib/pdcp/rte_pdcp.h new file +10
-0+#include <rte_common.h> +#include <rte_mempool.h> +#include <rte_security.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** +* PDCP entity. You can probably explain more on what a PDCP entity is.
[Anoob] Will do in next version.
Quoted 21 lines
lib/pdcp/rte_pdcp.h
Quoted 5 lines
lib/pdcp/rte_pdcp.h new file +4
-0+*/ +struct rte_pdcp_entity { +/** +* PDCP entities may hold packets for purposes of in-order delivery (in
lib/pdcp/rte_pdcp.h
Quoted 10 lines
lib/pdcp/rte_pdcp.h new file +6
-0+* case of receiving PDCP entity) and re-transmission (in case of +* transmitting PDCP entity). +* +* For receiving PDCP entity, it may hold packets when in-order +* delivery is enabled. The packets would be cached until either a +* packet that completes the sequence arrives or when t-Reordering timer
lib/pdcp/rte_pdcp.h new file +3
-0+* expires. +* +* When post-processing of PDCP packet which completes a sequence is
lib/pdcp/rte_pdcp.h
Quoted 1 line
lib/pdcp/rte_pdcp.h new file +1
-0+* done, the API may return more packets than enqueued. Application is
lib/pdcp/rte_pdcp.h
Quoted 1 line
lib/pdcp/rte_pdcp.h new file +1
-0+* expected to provide *rte_pdcp_pkt_post_process()* with *out_mb*
Quoted 8 lines
lib/pdcp/rte_pdcp.h
Quoted 1 line
lib/pdcp/rte_pdcp.h new file +1
-0+* which can hold maximum number of packets which may be returned.
lib/pdcp/rte_pdcp.h
Quoted 1 line
lib/pdcp/rte_pdcp.h new file +1
-0+*/ The above comment explains the need for holding the packets. But it does not talk about the parameter it is explaining. This explanation should be part of programmer's guide and not the API guide.
[Anoob] Agreed. Will make the required changes.
Quoted 8 lines
lib/pdcp/rte_pdcp.h line 46
Quoted 4 lines
lib/pdcp/rte_pdcp.h new file +3
-0+uint32_t max_pkt_cache; +/** User area for saving application data. */ +uint64_t user_area[2 ];Is it being used right now in the patches? If not, can we add it later?
And if really needed now, can we rename touser_data
[Anoob] Agreed. Will remove.
Quoted 19 lines
Quoted 8 lines
lib/pdcp/rte_pdcp.h new file +7
-0+} __rte_cache_aligned; + +/** +* PDCP entity configuration to be used for establishing an entity. +*/ +/* Structure rte_pdcp_entity_conf 8< */ struct rte_pdcp_entity_conf { +/** PDCP transform for the entity. */ lib/pdcp/rte_pdcp.h
Quoted 10 lines
lib/pdcp/rte_pdcp.h new file +10
-0+struct rte_security_pdcp_xform pdcp_xfrm; +/** Crypto transform applicable for the entity. */ +struct rte_crypto_sym_xform *crypto_xfrm; +/** Mempool for crypto symmetric session. */ +struct rte_mempool *sess_mpool; +/** Crypto op pool.*/ +struct rte_mempool *cop_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
Quoted 6 lines
lib/pdcp/rte_pdcp.h
Quoted 2 lines
this value.
lib/pdcp/rte_pdcp.h new file +1
-0+*/ If the HFN is to be ignored, then why to add a check in entity establish and return EINVAL?
It should be silently ignored in that case with a debug print at max.
[Anoob] Explained above. Please check.
Quoted 122 lines
lib/pdcp/rte_pdcp.h
Quoted 4 lines
lib/pdcp/rte_pdcp.h new file +2
-0+uint32_t count; +/** Indicate whether the PDCP entity belongs to Side Link Radio Bearer.
Quoted 30 lines
*/
lib/pdcp/rte_pdcp.h new file +7
-0+bool is_slrb; +/** Enable security offload on the device specified. */ +bool en_sec_offload; +/** Device on which security/crypto session need to be created. */ +uint8_t dev_id; +/** Reverse direction during IV generation. Can be used to simulate +UE crypto processing.*/
lib/pdcp/rte_pdcp.h new file +21
-0+bool reverse_iv_direction; +}; +/* >8 End of structure rte_pdcp_entity_conf. */ + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice +* +* 5.1.1 PDCP entity establishment +* +* Establish PDCP entity based on provided input configuration. +* +* @param conf +* Parameters to be used for initializing PDCP entity object. +* @return +* - Valid handle if success +* - NULL in case of failure. rte_errno will be set to error code +*/ +__rte_experimental +struct rte_pdcp_entity * +rte_pdcp_entity_establish (const struct rte_pdcp_entity_conf *conf);lib/pdcp/rte_pdcp.h
Quoted 10 lines
lib/pdcp/rte_pdcp.h new file +10
-0+ +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice +* +* 5.1.3 PDCP entity release +* +* Release PDCP entity. +* +* For UL/transmitting PDCP entity, all stored PDCP SDUs would be dropped.
Quoted 76 lines
+ * For DL/receiving PDCP entity, the stored PDCP SDUs would be
lib/pdcp/rte_pdcp.h new file +9
-0+returned in + * *out_mb* buffer. The buffer should be large enough to hold all +cached + * packets in the entity. + * + * @param pdcp_entity + * Pointer to the PDCP entity to be released. + * @param[out] out_mb + * The address of an array that can hold up to*rte_pdcp_entity.max_pkt_cache*
+ * pointers to *rte_mbuf* structures.
+ * @return+ * - 0: Success and no cached packets to return + * - >0: Success and the number of packets returned in out_mb + * - <0: Error code in case of failures+ */
lib/pdcp/rte_pdcp.h new file +25
-0+__rte_experimental +int +rte_pdcp_entity_release (struct rte_pdcp_entity *pdcp_entity, +struct rte_mbuf *out_mb[]); + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice +* +* 5.1.4 PDCP entity suspend +* +* Suspend PDCP entity. +* +* For DL/receiving PDCP entity, the stored PDCP SDUs would be +returned in +* *out_mb* buffer. The buffer should be large enough to hold all +cached +* packets in the entity. +* +* For UL/transmitting PDCP entity, *out_mb* buffer would be unused. +* +* @param pdcp_entity +* Pointer to the PDCP entity to be suspended. +* @param[out] out_mb +* The address of an array that can hold up to *rte_pdcp_entity.max_pkt_cache*
+ * pointers to *rte_mbuf* structures.
+ * @return+ * - 0: Success and no cached packets to return + * - >0: Success and the number of packets returned in out_mb + * - <0: Error code in case of failures+ */
lib/pdcp/rte_pdcp.h new file +10
-0+__rte_experimental +int +rte_pdcp_entity_suspend (struct rte_pdcp_entity *pdcp_entity, +struct rte_mbuf *out_mb[]); + +#ifdef __cplusplus +} +#endif + +#endif /* RTE_PDCP_H */ lib/pdcp/version.map new file mode renamed from lib/pdcp/version.map +0
-0100644 index 0000000000..923e165f3f
lib/pdcp/version.map new file +10
-1@@ -0,0 +1,10 @@ +EXPERIMENTAL { + global: + + # added in 23.07 + rte_pdcp_entity_establish; + rte_pdcp_entity_release; + rte_pdcp_entity_suspend; + + local: *; +}; --2.25.1
Hi Anoob,
Quoted 22 lines
Quoted 13 lines
Quoted 13 lines
(quoted diff) +2
-0+static int +pdcp_entity_priv_populate(struct entity_priv *en_priv, const struct
rte_pdcp_entity_conf*conf)lib/pdcp/pdcp_process.c new file +8
-0+{ +struct rte_crypto_sym_xform *c_xfrm, *a_xfrm; +int ret; + +/** +* flags.is_authenticated +* +* MAC-I would be added in case of control plane packets and when authentication
lib/pdcp/pdcp_process.c new file +1
-0+* transform is not NULL. Quoted 8 lines
Review
Quoted 5 lines
lib/pdcp/pdcp_crypto.c new file +3
-0+*/ + + if (conf->pdcp_xfrm.domain ==
RTE_SECURITY_PDCP_MODE_CONTROL)(quoted diff) +1
-0+ en_priv->flags.is_authenticated = 1;This check should be added after getting the xfrm.
If domain == control anda_xfrmis NULL, then it should be error, right?
Quoted 5 lines
[Anoob] Lib PDCP would handle such cases. Even if
a_xfrmis non NULL but is NULL auth, it is lib PDCP which would add zeroized digest. Anda_xfrm== NULL is also treated as NULL auth generally. The comment above this explains the same. Idea is to have lib PDCP handle all possible cases rather than putting too much restrictions on both app & PMD.
I believe there is a case in PDCP which allows no integrity as well.(LTE Uplane) In that case, a_xfrm is NULL is not equivalent to NULL auth.
No integrity would mean no MAC-I.
Quoted 45 lines
Quoted 36 lines
Quoted 36 lines
lib/pdcp/rte_pdcp.c new file mode renamed from lib/pdcp/rte_pdcp.c +0
-0100644 index 0000000000..8914548dbd
lib/pdcp/rte_pdcp.c new file +31
-0@@ -0,0 +1,138 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2023 Marvell. +*/ + +#include <rte_errno.h> +#include <rte_pdcp.h> +#include <rte_malloc.h> + +#include "pdcp_crypto.h" +#include "pdcp_entity.h" +#include "pdcp_process.h" + +static int +pdcp_entity_size_get (const struct rte_pdcp_entity_conf *conf) { +int size; + + size =sizeof (struct rte_pdcp_entity ) +sizeof (struct entity_priv ); + +if (conf->pdcp_xfrm.pkt_dir ==RTE_SECURITY_PDCP_DOWNLINK ) + size +=sizeof (struct entity_priv_dl_part ); +else if (conf->pdcp_xfrm.pkt_dir ==RTE_SECURITY_PDCP_UPLINK ) + size +=sizeof (struct entity_priv_ul_part ); +else +return -EINVAL ; + +return RTE_ALIGN_CEIL (size,RTE_CACHE_LINE_SIZE ); } + +struct rte_pdcp_entity * +rte_pdcp_entity_establish (const struct rte_pdcp_entity_conf *conf) { +struct rte_pdcp_entity *entity =NULL ; +struct entity_priv *en_priv;Quoted 8 lines
lib/pdcp/rte_pdcp.c line 40
Quoted 6 lines
lib/pdcp/rte_pdcp.c new file +6
-0+int ret, entity_size; + +if (conf ==NULL || conf->cop_pool ==NULL ) { + rte_errno = -EINVAL ; +return NULL ; + }errnos are normally set as positive values.
Quoted 2 lines
[Anoob] I do not think so. I checked
rte_ethdev.h,rte_flow.hetc and all APIs are returning negative values in case of errors.
Check again lib/ethdev/rte_ethdev.crte_errno are set as positive values only and
APIs return error numbers as negative values.
Quoted 31 lines
Quoted 23 lines
Quoted 19 lines
lib/pdcp/rte_pdcp.c new file +2
-0+ + if (conf->pdcp_xfrm.en_ordering || conf-Quoted 1 line
pdcp_xfrm.remove_duplicates ||
conf->is_slrb||lib/pdcp/rte_pdcp.c new file +9
-0+ conf->en_sec_offload) { + rte_errno = -ENOTSUP ; +return NULL ; + } + +/* +* 6.3.2 PDCP SN +* Length: 12 or 18 bits as indicated in table 6.3.2-1. The length +of the PDCP SN is
lib/pdcp/rte_pdcp.c new file +2
-0+ * configured by upper layers (pdcp-SN-SizeUL, pdcp-SN-SizeDL, or +sl-PDCP-SN-Size in
lib/pdcp/rte_pdcp.c
Quoted 3 lines
lib/pdcp/rte_pdcp.c new file +3
-0+* TS 38.331 [3]) +*/ + if ((conf->pdcp_xfrm.sn_size != RTE_SECURITY_PDCP_SN_SIZE_12)&&
Quoted 7 lines
lib/pdcp/rte_pdcp.c line 58
Quoted 4 lines
lib/pdcp/rte_pdcp.c new file +4
-0+ (conf->pdcp_xfrm.sn_size != RTE_SECURITY_PDCP_SN_SIZE_18)) { + rte_errno = -ENOTSUP ; +return NULL ; + }Check for PDCP crypto algos may also be added.
As only 4 cipher and 4 auth algos are supported in case of PDCP.
Quoted 2 lines
[Anoob] Validation happens when we create session. Please check,
pdcp: add crypto session create and destroy
Agreed, already acked that.
Quoted 33 lines
Quoted 9 lines
lib/pdcp/rte_pdcp.c line 63
Quoted 7 lines
lib/pdcp/rte_pdcp.c new file +5
-0+ +if (conf->pdcp_xfrm.hfn || conf->pdcp_xfrm.hfn_threshold) { + rte_errno = -EINVAL ; +return NULL ; + }What is the reason to set errno as EINVAL when HFN is set?
[Anoob] HFN is part of
pdcp_xfrmwhich is defined inrte_security. Lib PDCP allows user to specify complete 32 bit count value using rte_pdcp_entity_conf.count. Since HFN is also used to construct 32 bit count value, having two ways to set count would be misleading. Hence lib PDCP would enforce that application does not set this value.Quoted 17 lines
Quoted 6 lines
lib/pdcp/rte_pdcp.c new file +5
-0+/** +* PDCP entity configuration to be used for establishing an entity. +*/ +/* Structure rte_pdcp_entity_conf 8< */ struct rte_pdcp_entity_conf { +/** PDCP transform for the entity. */ lib/pdcp/rte_pdcp.c
Quoted 10 lines
lib/pdcp/rte_pdcp.c new file +10
-0+struct rte_security_pdcp_xform pdcp_xfrm; +/** Crypto transform applicable for the entity. */ +struct rte_crypto_sym_xform *crypto_xfrm; +/** Mempool for crypto symmetric session. */ +struct rte_mempool *sess_mpool; +/** Crypto op pool.*/ +struct rte_mempool *cop_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
Quoted 9 lines
Quoted 6 lines
lib/pdcp/rte_pdcp.c
Quoted 2 lines
this value.
lib/pdcp/rte_pdcp.c new file +1
-0+*/ If the HFN is to be ignored, then why to add a check in entity establish and return EINVAL?
It should be silently ignored in that case with a debug print at max.[Anoob] Explained above. Please check.
No it is not explained. Above comments says
" pdcp_xfrm.hfn would be ignored as the HFN would be derived from this value"
Here you are saying the field will be ignored.
But while creating entity, it is returning EINVAL if hfn is provided.
Hi Akhil,
Please see inline.
Thanks,
Anoob
Quoted 43 lines
-----Original Message-----
From: Akhil Goyal <[email protected]>
Sent: Thursday, May 18, 2023 1:10 PM
To: Anoob Joseph <[email protected]>; Thomas Monjalon <[email protected]>; Jerin Jacob Kollanukkaran <[email protected]>; Konstantin Ananyev <[email protected]>; Bernard Iremonger <[email protected]>
Cc: Hemant Agrawal <[email protected]>; Mattias Rönnblom <[email protected]>; Kiran Kumar Kokkilagadda <[email protected]>; Volodymyr Fialko <[email protected]>; [email protected]; Olivier Matz <[email protected]>
Subject: RE: [PATCH v2 02/22] lib: add pdcp protocolHi Anoob,
Quoted 24 lines
Quoted 15 lines
Quoted 15 lines
(quoted diff) +3
-0+static int +pdcp_entity_priv_populate(struct entity_priv *en_priv, const +struct
rte_pdcp_entity_conf*conf)lib/pdcp/pdcp_process.c new file +9
-0+{ +struct rte_crypto_sym_xform *c_xfrm, *a_xfrm; +int ret; + +/** +* flags.is_authenticated +* +* MAC-I would be added in case of control plane packets and +when authentication
lib/pdcp/pdcp_process.c new file +1
-0+* transform is not NULL. Quoted 8 lines
Review
Quoted 5 lines
lib/pdcp/pdcp_crypto.c new file +3
-0+*/ + + if (conf->pdcp_xfrm.domain ==
RTE_SECURITY_PDCP_MODE_CONTROL)(quoted diff) +1
-0+ en_priv->flags.is_authenticated = 1;This check should be added after getting the xfrm.
If domain == control anda_xfrmis NULL, then it should be error, right?Quoted 5 lines
[Anoob] Lib PDCP would handle such cases. Even if
a_xfrmis non NULL but is NULL auth, it is lib PDCP which would add zeroized digest. Anda_xfrm== NULL is also treated as NULL auth generally. The comment above this explains the same. Idea is to have lib PDCP handle all possible cases rather than putting too much restrictions on both app &
Quoted 5 lines
PMD.
I believe there is a case in PDCP which allows no integrity as well.(LTE Uplane) In that case,
a_xfrmis NULL is not equivalent to NULL auth.
No integrity would mean no MAC-I.
[Anoob] The comment explains the logic. If it is control plane, then digest is must and that case lib PDCP is trying to handle. Anyway, adding an extra error check and returning error in that case is not a big deal. Will add that in the appropriate place.
Quoted 50 lines
Quoted 50 lines
Quoted 49 lines
Quoted 37 lines
lib/pdcp/rte_pdcp.c new file renamed from lib/pdcp/rte_pdcp.c +0
-0mode
100644 index 0000000000..8914548dbdlib/pdcp/rte_pdcp.c new file +28
-0@@ -0,0 +1,138 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2023 Marvell. +*/ + +#include <rte_errno.h> +#include <rte_pdcp.h> +#include <rte_malloc.h> + +#include "pdcp_crypto.h" +#include "pdcp_entity.h" +#include "pdcp_process.h" + +static int +pdcp_entity_size_get (const struct rte_pdcp_entity_conf *conf) { +int size; + + size =sizeof (struct rte_pdcp_entity ) +sizeof (struct +entity_priv ); + +if (conf->pdcp_xfrm.pkt_dir ==RTE_SECURITY_PDCP_DOWNLINK ) + size +=sizeof (struct entity_priv_dl_part ); +else if (conf->pdcp_xfrm.pkt_dir ==RTE_SECURITY_PDCP_UPLINK ) + size +=sizeof (struct entity_priv_ul_part ); +else +return -EINVAL ; + +return RTE_ALIGN_CEIL (size,RTE_CACHE_LINE_SIZE ); } +lib/pdcp/rte_pdcp.c line 38
Quoted 10 lines
lib/pdcp/rte_pdcp.c new file +10
-0+struct rte_pdcp_entity * +rte_pdcp_entity_establish (const struct rte_pdcp_entity_conf *conf) { +struct rte_pdcp_entity *entity =NULL ; +struct entity_priv *en_priv; +int ret, entity_size; + +if (conf ==NULL || conf->cop_pool ==NULL ) { + rte_errno = -EINVAL ; +return NULL ; + }errnos are normally set as positive values.
Quoted 6 lines
Quoted 2 lines
[Anoob] I do not think so. I checked
rte_ethdev.h,rte_flow.hetc and all APIs are returning negative values in case of errors.Check again
lib/ethdev/rte_ethdev.crte_errnoare set as positive values only and APIs return error numbers as negative values.
[Anoob] Okay. There are many APIs were this is not done correctly (check rte_flow.h) . For lib PDCP additions, I'll have this handled. Some of these conventions should be documented to avoid confusion.
Quoted 82 lines
Quoted 33 lines
Quoted 25 lines
Quoted 21 lines
lib/pdcp/rte_pdcp.c new file +2
-0+ + if (conf->pdcp_xfrm.en_ordering || conf-Quoted 1 line
pdcp_xfrm.remove_duplicates ||
conf->is_slrb||lib/pdcp/rte_pdcp.c new file +9
-0+ conf->en_sec_offload) { + rte_errno = -ENOTSUP ; +return NULL ; + } + +/* +* 6.3.2 PDCP SN +* Length: 12 or 18 bits as indicated in table 6.3.2-1. The length +of the PDCP SN is
lib/pdcp/rte_pdcp.c new file +2
-0+ * configured by upper layers (pdcp-SN-SizeUL, pdcp-SN-SizeDL, or +sl-PDCP-SN-Size in
lib/pdcp/rte_pdcp.c
Quoted 3 lines
lib/pdcp/rte_pdcp.c new file +3
-0+* TS 38.331 [3]) +*/ + if ((conf->pdcp_xfrm.sn_size != RTE_SECURITY_PDCP_SN_SIZE_12)&&
Quoted 7 lines
lib/pdcp/rte_pdcp.c line 58
Quoted 4 lines
lib/pdcp/rte_pdcp.c new file +4
-0+ (conf->pdcp_xfrm.sn_size != RTE_SECURITY_PDCP_SN_SIZE_18)) { + rte_errno = -ENOTSUP ; +return NULL ; + }Check for PDCP crypto algos may also be added.
As only 4 cipher and 4 auth algos are supported in case of PDCP.Quoted 2 lines
[Anoob] Validation happens when we create session. Please check,
pdcp: add crypto session create and destroyAgreed, already acked that.
Quoted 10 lines
Quoted 9 lines
lib/pdcp/rte_pdcp.c line 63
Quoted 7 lines
lib/pdcp/rte_pdcp.c new file +5
-0+ +if (conf->pdcp_xfrm.hfn || conf->pdcp_xfrm.hfn_threshold) { + rte_errno = -EINVAL ; +return NULL ; + }What is the reason to set errno as EINVAL when HFN is set?
Quoted 3 lines
[Anoob] HFN is part of
pdcp_xfrmwhich is defined inrte_security. Lib PDCP allows user to specify complete 32 bit count value using rte_pdcp_entity_conf.count. Since HFN is also used to construct 32 bitcount
Quoted 1 line
value, having two ways to set count would be misleading. Hence lib PDCP
would
Quoted 7 lines
enforce that application does not set this value.
Quoted 5 lines
lib/pdcp/rte_pdcp.c
Quoted 5 lines
lib/pdcp/rte_pdcp.c new file +4
-0+/** +* PDCP entity configuration to be used for establishing an entity. +*/ +/* Structure rte_pdcp_entity_conf 8< */ struct rte_pdcp_entity_conf {
Quoted 12 lines
Quoted 12 lines
lib/pdcp/rte_pdcp.c
Quoted 11 lines
lib/pdcp/rte_pdcp.c new file +11
-0+/** PDCP transform for the entity. */ +struct rte_security_pdcp_xform pdcp_xfrm; +/** Crypto transform applicable for the entity. */ +struct rte_crypto_sym_xform *crypto_xfrm; +/** Mempool for crypto symmetric session. */ +struct rte_mempool *sess_mpool; +/** Crypto op pool.*/ +struct rte_mempool *cop_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
Quoted 4 lines
Quoted 4 lines
lib/pdcp/rte_pdcp.c
Quoted 2 lines
this value.
lib/pdcp/rte_pdcp.c new file +1
-0+*/ If the HFN is to be ignored, then why to add a check in entity establish
and
Quoted 3 lines
Quoted 2 lines
return EINVAL?
It should be silently ignored in that case with a debug print at max.
Quoted 8 lines
Quoted 2 lines
[Anoob] Explained above. Please check.
No it is not explained. Above comments says
" pdcp_xfrm.hfn would be ignored as the HFN would be derived from this value"Here you are saying the field will be ignored.
But while creating entity, it is returning EINVAL if hfn is provided.
[Anoob] Agreed. Will address in next version.
Quoted 52 lines
Quoted 18 lines
Quoted 18 lines
Quoted 18 lines
Quoted 18 lines
lib/pdcp/rte_pdcp.c new file renamed from lib/pdcp/rte_pdcp.c +0
-0mode
100644 index 0000000000..8914548dbdlib/pdcp/rte_pdcp.c new file +12
-0@@ -0,0 +1,138 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2023 Marvell. +*/ + +#include <rte_errno.h> +#include <rte_pdcp.h> +#include <rte_malloc.h> + +#include "pdcp_crypto.h" +#include "pdcp_entity.h" +#include "pdcp_process.h" +Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
lib/pdcp/rte_pdcp.c
Quoted 8 lines
lib/pdcp/rte_pdcp.c new file +8
-0+static int +pdcp_entity_size_get (const struct rte_pdcp_entity_conf *conf) { +int size; + + size =sizeof (struct rte_pdcp_entity ) +sizeof (struct +entity_priv ); + + if (conf->pdcp_xfrm.pkt_dir ==
RTE_SECURITY_PDCP_DOWNLINK)Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
lib/pdcp/rte_pdcp.c line 22
Quoted 2 lines
lib/pdcp/rte_pdcp.c new file +2
-0+ size +=sizeof (struct entity_priv_dl_part ); + else if (conf->pdcp_xfrm.pkt_dir ==
RTE_SECURITY_PDCP_UPLINK)Quoted 22 lines
Quoted 21 lines
Quoted 10 lines
Quoted 10 lines
lib/pdcp/rte_pdcp.c new file +10
-0+ size +=sizeof (struct entity_priv_ul_part ); + else + return -EINVAL; + +return RTE_ALIGN_CEIL (size,RTE_CACHE_LINE_SIZE ); } + +struct rte_pdcp_entity * +rte_pdcp_entity_establish (const struct rte_pdcp_entity_conf *conf) { +struct rte_pdcp_entity *entity =NULL ; +struct entity_priv *en_priv;Quoted 8 lines
lib/pdcp/rte_pdcp.c line 40
Quoted 6 lines
lib/pdcp/rte_pdcp.c new file +6
-0+int ret, entity_size; + +if (conf ==NULL || conf->cop_pool ==NULL ) { + rte_errno = -EINVAL ; +return NULL ; + }errnos are normally set as positive values.
[Anoob] I do not think so. I checked
rte_ethdev.h,rte_flow.hetc and all APIs are returning negative values in case of errors.
Quoted 7 lines
Quoted 3 lines
Check again
lib/ethdev/rte_ethdev.crte_errnoare set as positive values only and APIs return error numbers as negative values.[Anoob] Okay. There are many APIs were this is not done correctly (check
rte_flow.h) . For lib PDCP additions, I'll have this handled. Some of these conventions should be documented to avoid confusion.
I am not sure what you are referring to.
I cannot find any discrepancy in rte_flow.c as well.
Can you give an example where it is wrong. We can ask specific people to fix that.
Regarding documentation.
It is mentioned in rte_errno.h
/**
* Error number value, stored per-thread, which can be queried after
* calls to certain functions to determine why those functions failed. *
* Uses standard values from errno.h wherever possible, with a small number
* of additional possible values for RTE-specific conditions. */
#define rte_errno RTE_PER_LCORE(_rte_errno)
And errno.h has all positive values defined.
Hi Akhil,
Please see inline.
Thanks,
Anoob
Quoted 93 lines
-----Original Message-----
From: Akhil Goyal <[email protected]>
Sent: Thursday, May 18, 2023 2:16 PM
To: Anoob Joseph <[email protected]>; Thomas Monjalon <[email protected]>; Jerin Jacob Kollanukkaran <[email protected]>; Konstantin Ananyev <[email protected]>; Bernard Iremonger <[email protected]>
Cc: Hemant Agrawal <[email protected]>; Mattias Rönnblom <[email protected]>; Kiran Kumar Kokkilagadda <[email protected]>; Volodymyr Fialko <[email protected]>; [email protected]; Olivier Matz <[email protected]>
Subject: RE: [PATCH v2 02/22] lib: add pdcp protocolQuoted 30 lines
Quoted 18 lines
Quoted 18 lines
Quoted 18 lines
Quoted 18 lines
lib/pdcp/rte_pdcp.c new renamed from lib/pdcp/rte_pdcp.c +0
-0file mode
100644 index 0000000000..8914548dbdlib/pdcp/rte_pdcp.c new file +12
-0@@ -0,0 +1,138 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2023 Marvell. +*/ + +#include <rte_errno.h> +#include <rte_pdcp.h> +#include <rte_malloc.h> + +#include "pdcp_crypto.h" +#include "pdcp_entity.h" +#include "pdcp_process.h" +Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
lib/pdcp/rte_pdcp.c
Quoted 8 lines
lib/pdcp/rte_pdcp.c new file +8
-0+static int +pdcp_entity_size_get (const struct rte_pdcp_entity_conf *conf) { +int size; + + size =sizeof (struct rte_pdcp_entity ) +sizeof (struct +entity_priv ); + + if (conf->pdcp_xfrm.pkt_dir ==
RTE_SECURITY_PDCP_DOWNLINK)Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
lib/pdcp/rte_pdcp.c line 22
Quoted 2 lines
lib/pdcp/rte_pdcp.c new file +2
-0+ size +=sizeof (struct entity_priv_dl_part ); + else if (conf->pdcp_xfrm.pkt_dir ==
RTE_SECURITY_PDCP_UPLINK)Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
Quoted 8 lines
lib/pdcp/rte_pdcp.c
Quoted 8 lines
lib/pdcp/rte_pdcp.c new file +8
-0+ size +=sizeof (struct entity_priv_ul_part ); + else + return -EINVAL; + +return RTE_ALIGN_CEIL (size,RTE_CACHE_LINE_SIZE ); } + +struct rte_pdcp_entity * +rte_pdcp_entity_establish(const struct rte_pdcp_entity_conf*conf) {
Quoted 14 lines
Quoted 14 lines
Quoted 13 lines
Quoted 10 lines
lib/pdcp/rte_pdcp.c line 40
Quoted 8 lines
lib/pdcp/rte_pdcp.c new file +8
-0+struct rte_pdcp_entity *entity =NULL ; +struct entity_priv *en_priv; +int ret, entity_size; + +if (conf ==NULL || conf->cop_pool ==NULL ) { + rte_errno = -EINVAL ; +return NULL ; + }errnos are normally set as positive values.
[Anoob] I do not think so. I checked
rte_ethdev.h,rte_flow.hetc and all APIs are returning negative values in case of errors.Quoted 8 lines
Quoted 3 lines
Check again
lib/ethdev/rte_ethdev.crte_errnoare set as positive values only and APIs return error numbers as negative values.[Anoob] Okay. There are many APIs were this is not done correctly (check
rte_flow.h) . For lib PDCP additions, I'll have this handled. Some of these conventions should be documented to avoid confusion.I am not sure what you are referring to.
I cannot find any discrepancy inrte_flow.cas well.Can you give an example where it is wrong. We can ask specific people to fix that.
Regarding documentation.
It is mentioned inrte_errno.h
/**
* Error number value, stored per-thread, which can be queried after
* calls to certain functions to determine why those functions failed. *
* Uses standard values fromerrno.hwherever possible, with a small
number
* of additional possible values for RTE-specific conditions. */
#definerte_errnoRTE_PER_LCORE(_rte_errno)
Quoted 1 line
And
errno.hhas all positive values defined.
[Anoob] Agreed. There are descriptions in rte_flow.h which got us confused. Thanks for the clarification. Changes in PDCP will come in next version.
PATCH v2 3/22 pdcp: add pre and post-process
In reply to Anoob JosephPDCP process is split into 2 parts. One before crypto processing (rte_pdcp_pkt_pre_process()) and one after crypto processing (rte_pdcp_pkt_post_process()). Functionality of pre-process & post-process varies based on the type of entity. Registration of entity specific function pointer allows skipping multiple checks that would come in datapath otherwise.
--- lib/pdcp/rte_pdcp.h | 97 ++++++++++++++++++++++++++++++++++++++++++++ lib/pdcp/version.map | 3 ++ 2 files changed, 100 insertions(+)
lib/pdcp/rte_pdcp.h +97 -0
@@ -22,10 +22,29 @@extern "C" {#endif +/* Forward declarations */ +struct rte_pdcp_entity ; + +/* PDCP pre-process function based on entity configuration */ +typedef uint16_t (*rte_pdcp_pre_p_t )(const struct rte_pdcp_entity *entity, +struct rte_mbuf *mb[], +struct rte_crypto_op *cop[], +uint16_t num,uint16_t *nb_err); + +/* PDCP post-process function based on entity configuration */ +typedef uint16_t (*rte_pdcp_post_p_t )(const struct rte_pdcp_entity *entity, +struct rte_mbuf *in_mb[], +struct rte_mbuf *out_mb[], +uint16_t num,uint16_t *nb_err); +/** * PDCP entity. */ struct rte_pdcp_entity { +/** Entity specific pre-process handle. */ +rte_pdcp_pre_p_t pre_process; +/** Entity specific post-process handle. */ +rte_pdcp_post_p_t post_process;/** * PDCP entities may hold packets for purposes of in-order delivery (in * case of receiving PDCP entity) and re-transmission (in case of
@@ -150,6 +169,84 @@ 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 +* +* For input mbufs and given PDCP entity pre-process the mbufs and prepare +* crypto ops that can be enqueued to the cryptodev associated with given +* session. Only error packets would be moved returned in the input buffer, +* *mb*, and it is the responsibility of the application to free the same. +* +* @param entity +* Pointer to the *rte_pdcp_entity* object the packets belong to. +* @param[in, out] mb +* The address of an array of *num* pointers to *rte_mbuf* structures +* which contain the input packets. Any error packets would be returned in the +* same buffer. +* @param[out] cop +* The address of an array that can hold up to *num* pointers to +* *rte_crypto_op* structures. Crypto ops would be allocated by +* ``rte_pdcp_pkt_pre_process`` API. +* @param num +* The maximum number of packets to process. +* @param[out] nb_err +* Pointer to return the number of error packets returned in *mb* +* @return +* Count of crypto_ops prepared +*/ +__rte_experimental +static inline uint16_t +rte_pdcp_pkt_pre_process (const struct rte_pdcp_entity *entity, +struct rte_mbuf *mb[],struct rte_crypto_op *cop[], +uint16_t num,uint16_t *nb_err) +{ +return entity->pre_process (entity, mb, cop, num, nb_err); +} + +/** +* @warning +* @b EXPERIMENTAL: this API may change without prior notice +* +* For input mbufs and given PDCP entity, perform PDCP post-processing of the +* mbufs. +* +* Input mbufs are the ones retrieved from crypto_ops dequeued from cryptodev +* and grouped by *rte_pdcp_pkt_crypto_group()*. +* +* The post-processed packets would be returned in the *out_mb* buffer. +* The resultant mbufs would be grouped into success packets and error packets. +* Error packets would be grouped in the end of the array and it is the +* responsibility of the application to handle the same. +* +* When in-order delivery is enabled, PDCP entity may buffer packets and would +* deliver packets only when all prior packets have been post-processed. That +* would result in returning more/less packets than enqueued. +* +* @param entity +* Pointer to the *rte_pdcp_entity* object the packets belong to. +* @param in_mb +* The address of an array of *num* pointers to *rte_mbuf* structures. +* @param[out] out_mb +* The address of an array of *num* pointers to *rte_mbuf* structures +* to output packets after PDCP post-processing. +* @param num +* The maximum number of packets to process. +* @param[out] nb_err +* The number of error packets returned in *out_mb* buffer. +* @return +* Count of packets returned in *out_mb* buffer. +*/ +__rte_experimental +static inline uint16_t +rte_pdcp_pkt_post_process (const struct rte_pdcp_entity *entity, +struct rte_mbuf *in_mb[], +struct rte_mbuf *out_mb[], +uint16_t num,uint16_t *nb_err) +{ +return entity->post_process (entity, in_mb, out_mb, num, nb_err); +} + #ifdef __cplusplus }#endif
lib/pdcp/version.map +3 -0
@@ -6,5 +6,8 @@ EXPERIMENTAL { rte_pdcp_entity_release; rte_pdcp_entity_suspend; + rte_pdcp_pkt_post_process; + rte_pdcp_pkt_pre_process; + local: *; };
Signature · 1 line
2.25.1
RE: [PATCH v2 03/22] pdcp: add pre and post-process
Quoted 9 lines
Subject: [PATCH v2 03/22] pdcp: add pre and post-process
PDCP process is split into 2 parts. One before crypto processing (
rte_pdcp_pkt_pre_process()) and one after crypto processing (rte_pdcp_pkt_post_process()). Functionality of pre-process & post-process varies based on the type of entity. Registration of entity specific function pointer allows skipping multiple checks that would come in datapath otherwise.
Quoted 3 lines
Signed-off-by Anoob Joseph <[email protected]>Signed-off-by Kiran Kumar K <[email protected]>Signed-off-by Volodymyr Fialko <[email protected]>
Haven't compiled it yet. Check for doxygen build issues if any.
PATCH v2 4/22 pdcp: add packet group
In reply to Anoob JosephCrypto processing in PDCP is performed asynchronously by rte_cryptodev_enqueue_burst() and rte_cryptodev_dequeue_burst(). Since cryptodev dequeue can return crypto operations belonging to multiple entities, rte_pdcp_pkt_crypto_group() is added to help grouping crypto operations belonging to same entity.
--- lib/pdcp/meson.build | 1 + lib/pdcp/rte_pdcp.h | 2 + lib/pdcp/rte_pdcp_group.h | 125 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 128 insertions(+) create mode 100644 lib/pdcp/rte_pdcp_group.h
lib/pdcp/meson.build +1 -0
@@ -13,5 +13,6 @@ sources = files( 'rte_pdcp.c', ) headers = files('rte_pdcp.h') +indirect_headers += files('rte_pdcp_group.h') deps += ['mbuf', 'net', 'cryptodev', 'security']
lib/pdcp/rte_pdcp.h +2 -0
@@ -247,6 +247,8 @@ rte_pdcp_pkt_post_process(const struct rte_pdcp_entity *entity,return entity->post_process (entity, in_mb, out_mb, num, nb_err); } +#include <rte_pdcp_group.h> + #ifdef __cplusplus }#endif
lib/pdcp/rte_pdcp_group.h new file +125 -0
125 lines not on this page · raw message
Signature · 1 line
2.25.1
RE: [PATCH v2 04/22] pdcp: add packet group
Quoted 64 lines
Subject: [PATCH v2 04/22] pdcp: add packet group
Crypto processing in PDCP is performed asynchronously by
rte_cryptodev_enqueue_burst()andrte_cryptodev_dequeue_burst(). Since cryptodev dequeue can return crypto operations belonging to multiple entities,rte_pdcp_pkt_crypto_group()is added to help grouping crypto operations belonging to same entity.Signed-off-by Anoob Joseph <[email protected]>Signed-off-by Kiran Kumar K <[email protected]>Signed-off-by Volodymyr Fialko <[email protected]>--- lib/pdcp/meson.build | 1 + lib/pdcp/rte_pdcp.h | 2 + lib/pdcp/rte_pdcp_group.h | 125 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 128 insertions(+) create mode 100644 lib/pdcp/rte_pdcp_group.hlib/pdcp/meson.build +1
-0@@ -13,5 +13,6 @@ sources = files( 'rte_pdcp.c', ) headers = files('rte_pdcp.h') +indirect_headers += files('rte_pdcp_group.h') deps += ['mbuf', 'net', 'cryptodev', 'security']lib/pdcp/rte_pdcp.h +2
-0@@ -247,6 +247,8 @@ rte_pdcp_pkt_post_process(const structrte_pdcp_entity *entity, return entity->post_process(entity, in_mb, out_mb, num, nb_err); } +#include <rte_pdcp_group.h> + #ifdef __cplusplus }#endif
lib/pdcp/rte_pdcp_group.h new file +14
-0@@ -0,0 +1,125 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2023 Marvell. +*/ + +#ifndef RTE_PDCP_GROUP_H +#define RTE_PDCP_GROUP_H + +/** +* @file rte_pdcp_group.h +* +* RTE PDCP grouping support. +* It is not recommended to include this file directly, include <rte_pdcp.h> +* instead. +* Provides helper functions to process completed crypto-ops and group
Quoted 3 lines
related
+ * packets by sessions they belong to.
+ */
Why do we need to have a separate public header file which we do not wish user to use directly for just a single API?
Can it not be added into rte_pdcp.h?
Quoted 97 lines
lib/pdcp/rte_pdcp_group.h new file +40
-0+ +#include <rte_common.h> +#include <rte_crypto.h> +#include <rte_cryptodev.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** +* Group packets belonging to same PDCP entity. +*/ +struct rte_pdcp_group { +union { +uint64_t val; +void *ptr; + } id;/**< Grouped by value */ +struct rte_mbuf **m;/**< Start of the group */ +uint32_t cnt;/**< Number of entries in the group */ +int32_t rc;/**< Status code associated with the group */ +}; + +/** +* Take crypto-op as an input and extract pointer to related PDCP entity. +* @param cop +* The address of an input *rte_crypto_op* structure. +* @return +* The pointer to the related *rte_pdcp_entity* structure. +*/ +static inline struct rte_pdcp_entity * +rte_pdcp_en_from_cop (const struct rte_crypto_op *cop) +{ +void *sess = cop->sym[0 ].session; + +return (struct rte_pdcp_entity *) +rte_cryptodev_sym_session_opaque_data_get (sess); +} + +/** +* Take as input completed crypto ops, extract related mbufs and group them by
+ * *rte_pdcp_entity* they belong to. Mbuf for which the crypto operation has
+ * failed would be flagged using *RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED* flag
+ * in rte_mbuf.ol_flags. Thecrypto_opswould be freed after the grouping.
+ *
+ * Note that application must ensure only crypto-ops prepared bylib_pdcpis
+ * provided back to @seerte_pdcp_pkt_crypto_group().
+ *
+ * @param cop
+ * The address of an array of *num* pointers to the input *rte_crypto_op*
+ * structures.
+ * @param[out] mb
+ * The address of an array of *num* pointers to output *rte_mbuf* structures.
+ * @param[out] grp
+ * The address of an array of *num* to output *rte_pdcp_group* structures.
+ * @param num
+ * The maximum number of crypto-ops to process.
+ * @return
+ * Number of filled elements in *grp* array.
+ *
+ */lib/pdcp/rte_pdcp_group.h new file +2
-0+static inline uint16_t +rte_pdcp_pkt_crypto_group(struct rte_crypto_op *cop[], struct rte_mbuf*mb[],
lib/pdcp/rte_pdcp_group.h new file +13
-0+ struct rte_pdcp_group grp[], uint16_t num) +{ + uint32_t i, j = 0, n = 0; +void *ns, *ps =NULL ; +struct rte_mbuf *m; + +for (i =0 ; i != num; i++) { + m = cop[i]->sym[0 ].m_src; + ns = cop[i]->sym[0 ].session; + + m->ol_flags |=RTE_MBUF_F_RX_SEC_OFFLOAD ; +if (cop[i]->status !=RTE_CRYPTO_OP_STATUS_SUCCESS ) + m->ol_flags |=
RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED;lib/pdcp/rte_pdcp_group.h new file +18
-0+ +/* Different entity */ +if (ps != ns) { + +/* Finalize open group and start a new one */ +if (ps !=NULL ) { + grp[n].cnt = mb + j - grp[n].m; + n++; + } + +/* Start new group */ + grp[n].m = mb + j; + ps = ns; + grp[n].id.ptr =rte_pdcp_en_from_cop (cop[i]); + } + + mb[j++] = m; +rte_crypto_op_free (cop[i]);
lib/pdcp/rte_pdcp_group.h line 119
Quoted 10 lines
lib/pdcp/rte_pdcp_group.h new file +10
-0+ } + +/* Finalize last group */ +if (ps !=NULL ) { + grp[n].cnt = mb + j - grp[n].m; + n++; + } + +return n; +}
These APIs are being called from application directly (as per the cover letter). Should be marked as experimental and also add them in version.map
Quoted 8 lines
lib/pdcp/rte_pdcp_group.h new file +6
-1+ +#ifdef __cplusplus +} +#endif + +#endif /* RTE_PDCP_GROUP_H */ --2.25.1
RE: [PATCH v2 04/22] pdcp: add packet group
Hi Akhil, Konstantin,
Please see inline.
Thanks,
Anoob
Quoted 85 lines
-----Original Message-----
From: Akhil Goyal <[email protected]>
Sent: Tuesday, May 16, 2023 9:27 PM
To: Anoob Joseph <[email protected]>; Thomas Monjalon <[email protected]>; Jerin Jacob Kollanukkaran <[email protected]>; Konstantin Ananyev <[email protected]>; Bernard Iremonger <[email protected]>
Cc: Hemant Agrawal <[email protected]>; Mattias Rönnblom <[email protected]>; Kiran Kumar Kokkilagadda <[email protected]>; Volodymyr Fialko <[email protected]>; [email protected]; Olivier Matz <[email protected]>
Subject: RE: [PATCH v2 04/22] pdcp: add packet groupQuoted 4 lines
Subject: [PATCH v2 04/22] pdcp: add packet group
Crypto processing in PDCP is performed asynchronously by
rte_cryptodev_enqueue_burst()andrte_cryptodev_dequeue_burst().Since
Quoted 60 lines
cryptodev dequeue can return crypto operations belonging to multiple entities,
rte_pdcp_pkt_crypto_group()is added to help grouping crypto operations belonging to same entity.Signed-off-by Anoob Joseph <[email protected]>Signed-off-by Kiran Kumar K <[email protected]>Signed-off-by Volodymyr Fialko <[email protected]>--- lib/pdcp/meson.build | 1 + lib/pdcp/rte_pdcp.h | 2 + lib/pdcp/rte_pdcp_group.h | 125 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 128 insertions(+) create mode 100644 lib/pdcp/rte_pdcp_group.hlib/pdcp/meson.build index renamed from lib/pdcp/meson.build +0
-0
ccaf426240..08679b743a100644lib/pdcp/meson.build +1
-0@@ -13,5 +13,6 @@ sources = files( 'rte_pdcp.c', ) headers = files('rte_pdcp.h') +indirect_headers += files('rte_pdcp_group.h') deps += ['mbuf', 'net', 'cryptodev', 'security'] diff --git
a/lib/pdcp/rte_pdcp.hb/lib/pdcp/rte_pdcp.hindex75dc569f66..54f88e3fd3100644lib/pdcp/rte_pdcp.h +2
-0@@ -247,6 +247,8 @@ rte_pdcp_pkt_post_process(const structrte_pdcp_entity *entity, return entity->post_process(entity, in_mb, out_mb, num, nb_err); } +#include <rte_pdcp_group.h> + #ifdef __cplusplus }#endif lib/pdcp/rte_pdcp_group.h new renamed from lib/pdcp/rte_pdcp_group.h +0
-0file mode 100644 index 0000000000..cb322f55c7
lib/pdcp/rte_pdcp_group.h new file +16
-0@@ -0,0 +1,125 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2023 Marvell. +*/ + +#ifndef RTE_PDCP_GROUP_H +#define RTE_PDCP_GROUP_H + +/** +* @file rte_pdcp_group.h +* +* RTE PDCP grouping support. +* It is not recommended to include this file directly, include +<rte_pdcp.h> +* instead. +* Provides helper functions to process completed crypto-ops and +group Quoted 3 lines
related
+ * packets by sessions they belong to.
+ */Why do we need to have a separate public header file which we do not wish user to use directly for just a single API?
Quoted 1 line
Can it not be added into
rte_pdcp.h?
[Anoob] This follows how the code organization is done in lib IPsec. My understanding is, it is done for 2 reasons,
1. Separate out helper inline functions into a separate header
2. Main header focus on core design of the protocol interface, ie, structs, macros & APIs.
Also, lib_pdcp.h is bound to grow. So rather than splitting it later, why don't we start with better organized code layout which is already followed in similar use case, ie, lib IPsec.
@Konstantin, did you have any other thoughts when you made the split this way?
Quoted 110 lines
Quoted 41 lines
lib/pdcp/rte_pdcp_group.h new file +40
-0+ +#include <rte_common.h> +#include <rte_crypto.h> +#include <rte_cryptodev.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/** +* Group packets belonging to same PDCP entity. +*/ +struct rte_pdcp_group { +union { +uint64_t val; +void *ptr; + } id;/**< Grouped by value */ +struct rte_mbuf **m;/**< Start of the group */ +uint32_t cnt;/**< Number of entries in the group */ +int32_t rc;/**< Status code associated with the group */ +}; + +/** +* Take crypto-op as an input and extract pointer to related PDCP entity. +* @param cop +* The address of an input *rte_crypto_op* structure. +* @return +* The pointer to the related *rte_pdcp_entity* structure. +*/ +static inline struct rte_pdcp_entity *rte_pdcp_en_from_cop (const +struct rte_crypto_op *cop) { +void *sess = cop->sym[0 ].session; + +return (struct rte_pdcp_entity *) +rte_cryptodev_sym_session_opaque_data_get (sess); +} + +/** +* Take as input completed crypto ops, extract related mbufs and +group them Quoted 4 lines
by
+ * *rte_pdcp_entity* they belong to. Mbuf for which the crypto
+ operation has
+ * failed would be flagged using*RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED*
Quoted 2 lines
flag
+ * in rte_mbuf.ol_flags. Thecrypto_opswould be freed after thegrouping.
Quoted 7 lines
+ *
+ * Note that application must ensure only crypto-ops prepared by +lib_pdcp is
+ * provided back to @seerte_pdcp_pkt_crypto_group().
+ *
+ * @param cop
+ * The address of an array of *num* pointers to the input*rte_crypto_op*
Quoted 3 lines
+ * structures.
+ * @param[out] mb
+ * The address of an array of *num* pointers to output *rte_mbuf*structures.
Quoted 2 lines
+ * @param[out] grp
+ * The address of an array of *num* to output *rte_pdcp_group*structures.
Quoted 46 lines
+ * @param num
+ * The maximum number of crypto-ops to process.
+ * @return
+ * Number of filled elements in *grp* array.
+ *
+ */lib/pdcp/rte_pdcp_group.h new file +3
-0+static inline uint16_t +rte_pdcp_pkt_crypto_group (struct rte_crypto_op *cop[],struct +rte_mbuf*mb[],
lib/pdcp/rte_pdcp_group.h new file +12
-0+ struct rte_pdcp_group grp[], uint16_t num) { + uint32_t i, j = 0, n = 0; +void *ns, *ps =NULL ; +struct rte_mbuf *m; + +for (i =0 ; i != num; i++) { + m = cop[i]->sym[0 ].m_src; + ns = cop[i]->sym[0 ].session; + + m->ol_flags |=RTE_MBUF_F_RX_SEC_OFFLOAD ; +if (cop[i]->status !=RTE_CRYPTO_OP_STATUS_SUCCESS ) + m->ol_flags |=
RTE_MBUF_F_RX_SEC_OFFLOAD_FAILED;lib/pdcp/rte_pdcp_group.h new file +23
-0+ +/* Different entity */ +if (ps != ns) { + +/* Finalize open group and start a new one */ +if (ps !=NULL ) { + grp[n].cnt = mb + j - grp[n].m; + n++; + } + +/* Start new group */ + grp[n].m = mb + j; + ps = ns; + grp[n].id.ptr =rte_pdcp_en_from_cop (cop[i]); + } + + mb[j++] = m; +rte_crypto_op_free (cop[i]); + } + +/* Finalize last group */ +if (ps !=NULL ) { + grp[n].cnt = mb + j - grp[n].m;
Quoted 8 lines
lib/pdcp/rte_pdcp_group.h line 119
Quoted 5 lines
lib/pdcp/rte_pdcp_group.h new file +5
-0+ n++; + } + +return n; +}These APIs are being called from application directly (as per the cover letter). Should be marked as experimental and also add them in version.map
[Anoob] Agreed. Will do.
Quoted 10 lines
Quoted 10 lines
lib/pdcp/rte_pdcp_group.h new file +6
-1+ +#ifdef __cplusplus +} +#endif + +#endif /* RTE_PDCP_GROUP_H */ --2.25.1
PATCH v2 5/22 pdcp: add crypto session create and destroy
In reply to Anoob JosephAdd routines to create & destroy sessions. PDCP lib would take crypto transforms as input and creates the session on the corresponding device after verifying capabilities.
--- lib/pdcp/pdcp_crypto.c | 222 ++++++++++++++++++++++++++++++++++++++++- lib/pdcp/pdcp_crypto.h | 6 ++ 2 files changed, 225 insertions(+), 3 deletions(-)
lib/pdcp/pdcp_crypto.c +219 -3
@@ -2,20 +2,236 @@* Copyright(C) 2023 Marvell. */ +#include <rte_crypto.h> +#include <rte_crypto_sym.h> +#include <rte_cryptodev.h> +#include <rte_errno.h> #include <rte_pdcp.h> #include "pdcp_crypto.h" +#include "pdcp_entity.h" + +static int +pdcp_crypto_caps_cipher_verify (uint8_t dev_id,const struct rte_crypto_sym_xform *c_xfrm) +{ +const struct rte_cryptodev_symmetric_capability *cap; +struct rte_cryptodev_sym_capability_idx cap_idx; +int ret; + + cap_idx.type =RTE_CRYPTO_SYM_XFORM_CIPHER ; + cap_idx.algo.cipher = c_xfrm->cipher.algo; + + cap =rte_cryptodev_sym_capability_get (dev_id, &cap_idx); +if (cap ==NULL ) +return -1 ; + + ret =rte_cryptodev_sym_capability_check_cipher (cap, c_xfrm->cipher.key.length, + c_xfrm->cipher.iv.length); + +return ret; +} + +static int +pdcp_crypto_caps_auth_verify (uint8_t dev_id,const struct rte_crypto_sym_xform *a_xfrm) +{ +const struct rte_cryptodev_symmetric_capability *cap; +struct rte_cryptodev_sym_capability_idx cap_idx; +int ret; + + cap_idx.type =RTE_CRYPTO_SYM_XFORM_AUTH ; + cap_idx.algo.auth = a_xfrm->auth.algo; + + cap =rte_cryptodev_sym_capability_get (dev_id, &cap_idx); +if (cap ==NULL ) +return -1 ; + + ret =rte_cryptodev_sym_capability_check_auth (cap, a_xfrm->auth.key.length, + a_xfrm->auth.digest_length, + a_xfrm->auth.iv.length); + +return ret; +} + +static int +pdcp_crypto_xfrm_validate (const struct rte_pdcp_entity_conf *conf, +const struct rte_crypto_sym_xform *c_xfrm, +const struct rte_crypto_sym_xform *a_xfrm, +bool is_auth_then_cipher) +{ +uint16_t ciph_iv_len, auth_digest_len, auth_iv_len; +int ret; + +/* +* Uplink means PDCP entity is configured for transmit. Downlink means PDCP entity is +* configured for receive. When integrity protection is enabled, PDCP always performs +* digest-encrypted or auth-gen-encrypt for uplink (and decrypt-auth-verify for downlink). +* So for uplink, crypto chain would be auth-cipher while for downlink it would be +* cipher-auth. +* +* When integrity protection is not required, xform would be cipher only. +*/ + +if (c_xfrm ==NULL ) +return -EINVAL ; + +if (conf->pdcp_xfrm.pkt_dir ==RTE_SECURITY_PDCP_UPLINK ) { + +/* With UPLINK, if auth is enabled, it should be before cipher */ +if (a_xfrm !=NULL && !is_auth_then_cipher) +return -EINVAL ; + +/* With UPLINK, cipher operation must be encrypt */ +if (c_xfrm->cipher.op !=RTE_CRYPTO_CIPHER_OP_ENCRYPT ) +return -EINVAL ; + +/* With UPLINK, auth operation (if present) must be generate */ +if (a_xfrm !=NULL && a_xfrm->auth.op !=RTE_CRYPTO_AUTH_OP_GENERATE ) +return -EINVAL ; + + }else if (conf->pdcp_xfrm.pkt_dir ==RTE_SECURITY_PDCP_DOWNLINK ) { + +/* With DOWNLINK, if auth is enabled, it should be after cipher */ +if (a_xfrm !=NULL && is_auth_then_cipher) +return -EINVAL ; + +/* With DOWNLINK, cipher operation must be decrypt */ +if (c_xfrm->cipher.op !=RTE_CRYPTO_CIPHER_OP_DECRYPT ) +return -EINVAL ; + +/* With DOWNLINK, auth operation (if present) must be verify */ +if (a_xfrm !=NULL && a_xfrm->auth.op !=RTE_CRYPTO_AUTH_OP_VERIFY ) +return -EINVAL ; + + }else { +return -EINVAL ; + } + +if ((c_xfrm->cipher.algo !=RTE_CRYPTO_CIPHER_NULL ) && + (c_xfrm->cipher.algo !=RTE_CRYPTO_CIPHER_AES_CTR ) && + (c_xfrm->cipher.algo !=RTE_CRYPTO_CIPHER_ZUC_EEA3 ) && + (c_xfrm->cipher.algo !=RTE_CRYPTO_CIPHER_SNOW3G_UEA2 )) +return -EINVAL ; + +if (c_xfrm->cipher.algo ==RTE_CRYPTO_CIPHER_NULL ) + ciph_iv_len =0 ; +else + ciph_iv_len =PDCP_IV_LEN ; + +if (ciph_iv_len != c_xfrm->cipher.iv.length) +return -EINVAL ; + +if (a_xfrm !=NULL ) { +if ((a_xfrm->auth.algo !=RTE_CRYPTO_AUTH_NULL ) && + (a_xfrm->auth.algo !=RTE_CRYPTO_AUTH_AES_CMAC ) && + (a_xfrm->auth.algo !=RTE_CRYPTO_AUTH_ZUC_EIA3 ) && + (a_xfrm->auth.algo !=RTE_CRYPTO_AUTH_SNOW3G_UIA2 )) +return -EINVAL ; + +/* For AUTH NULL, lib PDCP would add 4 byte 0s */ +if (a_xfrm->auth.algo ==RTE_CRYPTO_AUTH_NULL ) + auth_digest_len =0 ; +else + auth_digest_len =PDCP_MAC_I_LEN ; + +if (auth_digest_len != a_xfrm->auth.digest_length) +return -EINVAL ; + +if ((a_xfrm->auth.algo ==RTE_CRYPTO_AUTH_ZUC_EIA3 ) || + (a_xfrm->auth.algo ==RTE_CRYPTO_AUTH_SNOW3G_UIA2 )) + auth_iv_len =PDCP_IV_LEN ; +else + auth_iv_len =0 ; + +if (a_xfrm->auth.iv.length != auth_iv_len) +return -EINVAL ; + } + +if (!rte_cryptodev_is_valid_dev (conf->dev_id)) +return -EINVAL ; + + ret =pdcp_crypto_caps_cipher_verify (conf->dev_id, c_xfrm); +if (ret) +return -ENOTSUP ; + +if (a_xfrm !=NULL ) { + ret =pdcp_crypto_caps_auth_verify (conf->dev_id, a_xfrm); +if (ret) +return -ENOTSUP ; + } + +return 0 ; +}int pdcp_crypto_sess_create (struct rte_pdcp_entity *entity,const struct rte_pdcp_entity_conf *conf) { -RTE_SET_USED (entity); -RTE_SET_USED (conf); +struct rte_crypto_sym_xform *c_xfrm, *a_xfrm; +struct entity_priv *en_priv; +bool is_auth_then_cipher; +int ret; + +if (entity ==NULL || conf ==NULL || conf->crypto_xfrm ==NULL ) +return -EINVAL ; + + en_priv =entity_priv_get (entity); + + en_priv->dev_id = conf->dev_id; + +if (conf->crypto_xfrm->type ==RTE_CRYPTO_SYM_XFORM_CIPHER ) { + c_xfrm = conf->crypto_xfrm; + a_xfrm = conf->crypto_xfrm->next; + is_auth_then_cipher = false; + }else if (conf->crypto_xfrm->type ==RTE_CRYPTO_SYM_XFORM_AUTH ) { + a_xfrm = conf->crypto_xfrm; + c_xfrm = conf->crypto_xfrm->next; + is_auth_then_cipher = true; + }else { +return -EINVAL ; + } + + ret =pdcp_crypto_xfrm_validate (conf, c_xfrm, a_xfrm, is_auth_then_cipher); +if (ret) +return ret; + +if (c_xfrm->cipher.algo ==RTE_CRYPTO_CIPHER_NULL ) + c_xfrm->cipher.iv.offset =0 ; +else + c_xfrm->cipher.iv.offset =PDCP_IV_OFFSET ; + +if (a_xfrm !=NULL ) { +if (a_xfrm->auth.algo ==RTE_CRYPTO_AUTH_NULL ) + a_xfrm->auth.iv.offset =0 ; +else +if (c_xfrm->cipher.iv.offset) + a_xfrm->auth.iv.offset =PDCP_IV_OFFSET +PDCP_IV_LEN ; +else + a_xfrm->auth.iv.offset =PDCP_IV_OFFSET ; + } + +if (conf->sess_mpool ==NULL ) +return -EINVAL ; + + en_priv->crypto_sess =rte_cryptodev_sym_session_create (conf->dev_id, conf->crypto_xfrm, + conf->sess_mpool); +if (en_priv->crypto_sess ==NULL ) { +/* API returns positive values as error codes */ +return -rte_errno; + } + +rte_cryptodev_sym_session_opaque_data_set (en_priv->crypto_sess, (uint64_t )entity); +return 0 ; }void pdcp_crypto_sess_destroy (struct rte_pdcp_entity *entity) { -RTE_SET_USED (entity); +struct entity_priv *en_priv; + + en_priv =entity_priv_get (entity); + +if (en_priv->crypto_sess !=NULL ) { +rte_cryptodev_sym_session_free (en_priv->dev_id, en_priv->crypto_sess); + en_priv->crypto_sess =NULL ; + } }
lib/pdcp/pdcp_crypto.h +6 -0
@@ -5,8 +5,14 @@#ifndef PDCP_CRYPTO_H #define PDCP_CRYPTO_H +#include <rte_crypto.h> +#include <rte_crypto_sym.h> #include <rte_pdcp.h> +#define PDCP_IV_OFFSET (sizeof(struct rte_crypto_op) + sizeof(struct rte_crypto_sym_op)) +#define PDCP_IV_LEN 16 +#define PDCP_MAC_I_LEN 4 +int pdcp_crypto_sess_create (struct rte_pdcp_entity *entity,const struct rte_pdcp_entity_conf *conf);
Signature · 1 line
2.25.1
RE: [PATCH v2 05/22] pdcp: add crypto session create and destroy
Quoted 8 lines
Subject: [PATCH v2 05/22] pdcp: add crypto session create and destroy
Add routines to create & destroy sessions. PDCP lib would take crypto transforms as input and creates the session on the corresponding device after verifying capabilities.
Signed-off-by Anoob Joseph <[email protected]>Signed-off-by Volodymyr Fialko <[email protected]>
PATCH v2 6/22 pdcp: add pre and post process for UL
In reply to Anoob JosephAdd routines to perform pre & post processing based on the type of entity. To avoid checks in datapath, there are different function pointers registered based on the following,
1. Control plane v/s user plane
2. 12 bit v/s 18 bit SN
For control plane only 12 bit SN need to be supported (as per PDCP specification).
--- lib/pdcp/pdcp_entity.h | 42 +++++ lib/pdcp/pdcp_process.c | 330 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 372 insertions(+)
lib/pdcp/pdcp_entity.h +42 -0
@@ -92,4 +92,46 @@ pdcp_hdr_size_get(enum rte_security_pdcp_sn_size sn_size)return RTE_ALIGN_MUL_CEIL (sn_size,8 ) /8 ; } +static inline uint32_t +pdcp_window_size_get (enum rte_security_pdcp_sn_size sn_size) +{ +return 1 << (sn_size -1 ); +} + +static inline uint32_t +pdcp_sn_mask_get (enum rte_security_pdcp_sn_size sn_size) +{ +return (1 << sn_size) -1 ; +} + +static inline uint32_t +pdcp_sn_from_count_get (uint32_t count,enum rte_security_pdcp_sn_size sn_size) +{ +return (count &pdcp_sn_mask_get (sn_size)); +} + +static inline uint32_t +pdcp_hfn_mask_get (enum rte_security_pdcp_sn_size sn_size) +{ +return ~pdcp_sn_mask_get (sn_size); +} + +static inline uint32_t +pdcp_hfn_from_count_get (uint32_t count,enum rte_security_pdcp_sn_size sn_size) +{ +return (count &pdcp_hfn_mask_get (sn_size)) >> sn_size; +} + +static inline uint32_t +pdcp_count_from_hfn_sn_get (uint32_t hfn,uint32_t sn,enum rte_security_pdcp_sn_size sn_size) +{ +return (((hfn << sn_size) &pdcp_hfn_mask_get (sn_size)) | (sn &pdcp_sn_mask_get (sn_size))); +} + +static inline uint32_t +pdcp_hfn_max (enum rte_security_pdcp_sn_size sn_size) +{ +return (1 << (32 - sn_size)) -1 ; +} +#endif /* PDCP_ENTITY_H */
lib/pdcp/pdcp_process.c +330 -0
341 lines not on this page · raw message
Signature · 1 line
2.25.1
RE: [PATCH v2 06/22] pdcp: add pre and post process for UL
Quoted 8 lines
Subject: [PATCH v2 06/22] pdcp: add pre and post process for UL
Add routines to perform pre & post processing based on the type of entity. To avoid checks in datapath, there are different function pointers registered based on the following,
1. Control plane v/s user plane
2. 12 bit v/s 18 bit SN
Quoted 7 lines
For control plane only 12 bit SN need to be supported (as per PDCP specification).
Signed-off-by Anoob Joseph <[email protected]>Signed-off-by Kiran Kumar K <[email protected]>Signed-off-by Volodymyr Fialko <[email protected]>---
PATCH v2 7/22 pdcp: add pre and post process for DL
In reply to Anoob JosephAdd routines to perform pre & post processing for down link entities.
--- lib/pdcp/pdcp_entity.h | 2 + lib/pdcp/pdcp_process.c | 453 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 455 insertions(+)
lib/pdcp/pdcp_entity.h +2 -0
@@ -13,6 +13,8 @@struct entity_priv ; +#define PDCP_HFN_MIN 0 +/* IV generation function based on the entity configuration */ typedef void (*iv_gen_t )(struct rte_crypto_op *cop,const struct entity_priv *en_priv,uint32_t count);
lib/pdcp/pdcp_process.c +453 -0
474 lines not on this page · raw message
Signature · 1 line
2.25.1
RE: [PATCH v2 07/22] pdcp: add pre and post process for DL
Quoted 33 lines
static int
pdcp_pre_post_func_set(structrte_pdcp_entity*entity, const structrte_pdcp_entity_conf*conf)
{lib/pdcp/pdcp_process.c +3
-0+struct entity_priv *en_priv =entity_priv_get (entity); + entity->pre_process =NULL ; entity->post_process =NULL ;@@ -342,6 +756,13 @@ pdcp_pre_post_func_set(struct rte_pdcp_entity *entity, const struct rte_pdcp_ent entity->post_process = pdcp_post_process_ul; } + if ((conf->pdcp_xfrm.domain ==
RTE_SECURITY_PDCP_MODE_CONTROL) &&lib/pdcp/pdcp_process.c +6
-0+ (conf->pdcp_xfrm.sn_size ==RTE_SECURITY_PDCP_SN_SIZE_12 ) && + (conf->pdcp_xfrm.pkt_dir == RTE_SECURITY_PDCP_DOWNLINK)) { + entity->pre_process = pdcp_pre_process_cplane_sn_12_dl; + entity->post_process = pdcp_post_process_cplane_sn_12_dl; + } + if ((conf->pdcp_xfrm.domain == RTE_SECURITY_PDCP_MODE_DATA)&&
lib/pdcp/pdcp_process.c +1
-0(conf->pdcp_xfrm.sn_size == RTE_SECURITY_PDCP_SN_SIZE_12) && (conf->pdcp_xfrm.pkt_dir == RTE_SECURITY_PDCP_UPLINK)) {@@ -356,6 +777,38 @@ pdcp_pre_post_func_set(struct rte_pdcp_entity *entity, const struct rte_pdcp_ent entity->post_process = pdcp_post_process_ul; } + if ((conf->pdcp_xfrm.domain == RTE_SECURITY_PDCP_MODE_DATA)&&
lib/pdcp/pdcp_process.c pdcp_pre_post_func_set(struct rte_pdcp_entity *entity, const struct rte_pdcp_ent · line 783
Quoted 3 lines
lib/pdcp/pdcp_process.c +3
-0+ (conf->pdcp_xfrm.sn_size == RTE_SECURITY_PDCP_SN_SIZE_12) && + (conf->pdcp_xfrm.pkt_dir == RTE_SECURITY_PDCP_DOWNLINK) && + (en_priv->flags.is_authenticated)) {
is_authenticated is checked only in case of DL.
For UL, the check is there in the same function.
Can we have it consistent with UL?
Quoted 38 lines
(quoted diff) +2
-0+ entity->pre_process = pdcp_pre_process_uplane_sn_12_dl_ip; + entity->post_process =
pdcp_post_process_uplane_sn_12_dl_ip;lib/pdcp/pdcp_process.c +3
-0+ } + + if ((conf->pdcp_xfrm.domain == RTE_SECURITY_PDCP_MODE_DATA)&&
lib/pdcp/pdcp_process.c +8
-0+ (conf->pdcp_xfrm.sn_size ==RTE_SECURITY_PDCP_SN_SIZE_12 ) && + (conf->pdcp_xfrm.pkt_dir ==RTE_SECURITY_PDCP_DOWNLINK ) && + (!en_priv->flags.is_authenticated)) { + entity->pre_process = pdcp_pre_process_uplane_sn_12_dl; + entity->post_process = pdcp_post_process_uplane_sn_12_dl; + } + + if ((conf->pdcp_xfrm.domain == RTE_SECURITY_PDCP_MODE_DATA)&&
lib/pdcp/pdcp_process.c +5
-0+ (conf->pdcp_xfrm.sn_size ==RTE_SECURITY_PDCP_SN_SIZE_18 ) && + (conf->pdcp_xfrm.pkt_dir ==RTE_SECURITY_PDCP_DOWNLINK ) && + (en_priv->flags.is_authenticated)) { + entity->pre_process = pdcp_pre_process_uplane_sn_18_dl_ip; + entity->post_process =
pdcp_post_process_uplane_sn_18_dl_ip;lib/pdcp/pdcp_process.c +3
-0+ } + + if ((conf->pdcp_xfrm.domain == RTE_SECURITY_PDCP_MODE_DATA)&&
lib/pdcp/pdcp_process.c +7
-1+ (conf->pdcp_xfrm.sn_size ==RTE_SECURITY_PDCP_SN_SIZE_18 ) && + (conf->pdcp_xfrm.pkt_dir ==RTE_SECURITY_PDCP_DOWNLINK ) && + (!en_priv->flags.is_authenticated)) { + entity->pre_process = pdcp_pre_process_uplane_sn_18_dl; + entity->post_process = pdcp_post_process_uplane_sn_18_dl; + } +if (entity->pre_process ==NULL || entity->post_process ==NULL )return -ENOTSUP ; --2.25.1
RE: [PATCH v2 07/22] pdcp: add pre and post process for DL
HI Akhil,
Please see inline.
Thanks,
Anoob
Quoted 52 lines
-----Original Message-----
From: Akhil Goyal <[email protected]>
Sent: Thursday, May 18, 2023 12:17 PM
To: Anoob Joseph <[email protected]>; Thomas Monjalon <[email protected]>; Jerin Jacob Kollanukkaran <[email protected]>; Konstantin Ananyev <[email protected]>; Bernard Iremonger <[email protected]>
Cc: Hemant Agrawal <[email protected]>; Mattias Rönnblom <[email protected]>; Kiran Kumar Kokkilagadda <[email protected]>; Volodymyr Fialko <[email protected]>; [email protected]; Olivier Matz <[email protected]>
Subject: RE: [PATCH v2 07/22] pdcp: add pre and post process for DLQuoted 15 lines
static int
pdcp_pre_post_func_set(structrte_pdcp_entity*entity, const structrte_pdcp_entity_conf*conf) {lib/pdcp/pdcp_process.c +3
-0+struct entity_priv *en_priv =entity_priv_get (entity); + entity->pre_process =NULL ; entity->post_process =NULL ;@@ -342,6 +756,13 @@ pdcp_pre_post_func_set(struct rte_pdcp_entity *entity, const struct rte_pdcp_ent entity->post_process = pdcp_post_process_ul; } + if ((conf->pdcp_xfrm.domain ==
RTE_SECURITY_PDCP_MODE_CONTROL) &&Review
Quoted 1 line
(quoted diff) +1
-0+ (conf->pdcp_xfrm.sn_size == RTE_SECURITY_PDCP_SN_SIZE_12)&&
lib/pdcp/pdcp_process.c pdcp_pre_post_func_set(struct rte_pdcp_entity *entity, const struct rte_pdcp_ent
Quoted 3 lines
lib/pdcp/pdcp_process.c +3
-0+ (conf->pdcp_xfrm.pkt_dir == RTE_SECURITY_PDCP_DOWNLINK)) { + entity->pre_process = pdcp_pre_process_cplane_sn_12_dl; + entity->post_process =
pdcp_post_process_cplane_sn_12_dl;lib/pdcp/pdcp_process.c pdcp_post_process_ul(const struct rte_pdcp_entity *entity,
Quoted 3 lines
lib/pdcp/pdcp_process.c +2
-0+ } + if ((conf->pdcp_xfrm.domain ==
RTE_SECURITY_PDCP_MODE_DATA) &&Quoted 1 line
(
conf->pdcp_xfrm.sn_size==RTE_SECURITY_PDCP_SN_SIZE_12)&&
Quoted 1 line
(
conf->pdcp_xfrm.pkt_dir==RTE_SECURITY_PDCP_UPLINK)) {@@
lib/pdcp/pdcp_process.c pdcp_pre_post_func_set(struct rte_pdcp_entity *entity, const struct rte_pdcp_ent
Quoted 6 lines
-356,6 +777,38 @@ pdcp_pre_post_func_set(struct
rte_pdcp_entity*entity, const structrte_pdcp_entlib/pdcp/pdcp_process.c +1
-0entity->post_process = pdcp_post_process_ul; } + if ((conf->pdcp_xfrm.domain ==
RTE_SECURITY_PDCP_MODE_DATA)Review
Quoted 2 lines
&&
(quoted diff) +1
-0+ (conf->pdcp_xfrm.sn_size == RTE_SECURITY_PDCP_SN_SIZE_12)&&
Quoted 7 lines
Review
Quoted 1 line
(quoted diff) +1
-0+ (conf->pdcp_xfrm.pkt_dir == RTE_SECURITY_PDCP_DOWNLINK)&&
Review
Quoted 1 line
(quoted diff) +1
-0+ (en_priv->flags.is_authenticated)) {
is_authenticatedis checked only in case of DL. For UL, the check is there in the same function. Can we have it consistent with UL?
[Anoob] The check here allows registering different function pointers so that datapath checks are avoided. The level of optimization vs level of code complexity is the reason for delta. For DL, most of the code is the same and so we added const flags & allowed different functions to call with flags. For UL, the code had significant changes in both paths. Hence an extra top level check was okay.
Quoted 52 lines
Review
Quoted 2 lines
(quoted diff) +1
-0+ entity->pre_process =
pdcp_pre_process_uplane_sn_12_dl_ip;lib/pdcp/pdcp_process.c pdcp_post_process_ul(const struct rte_pdcp_entity *entity,
Quoted 5 lines
(quoted diff) +1
-0+ entity->post_process =
pdcp_post_process_uplane_sn_12_dl_ip;lib/pdcp/pdcp_process.c +3
-0+ } + + if ((conf->pdcp_xfrm.domain ==
RTE_SECURITY_PDCP_MODE_DATA)Review
Quoted 2 lines
&&
(quoted diff) +1
-0+ (conf->pdcp_xfrm.sn_size == RTE_SECURITY_PDCP_SN_SIZE_12)&&
Review
Quoted 1 line
(quoted diff) +1
-0+ (conf->pdcp_xfrm.pkt_dir == RTE_SECURITY_PDCP_DOWNLINK)&&
lib/pdcp/pdcp_process.c pdcp_pre_post_func_set(struct rte_pdcp_entity *entity, const struct rte_pdcp_ent
Quoted 3 lines
lib/pdcp/pdcp_process.c +3
-0+ (!en_priv->flags.is_authenticated)) { + entity->pre_process = pdcp_pre_process_uplane_sn_12_dl; + entity->post_process =
pdcp_post_process_uplane_sn_12_dl;lib/pdcp/pdcp_process.c pdcp_post_process_ul(const struct rte_pdcp_entity *entity,
Quoted 3 lines
lib/pdcp/pdcp_process.c +3
-0+ } + + if ((conf->pdcp_xfrm.domain ==
RTE_SECURITY_PDCP_MODE_DATA)Review
Quoted 2 lines
&&
(quoted diff) +1
-0+ (conf->pdcp_xfrm.sn_size == RTE_SECURITY_PDCP_SN_SIZE_18)&&
Review
Quoted 1 line
(quoted diff) +1
-0+ (conf->pdcp_xfrm.pkt_dir == RTE_SECURITY_PDCP_DOWNLINK)&&
Review
Quoted 2 lines
(quoted diff) +2
-0+ (en_priv->flags.is_authenticated)) { + entity->pre_process =
pdcp_pre_process_uplane_sn_18_dl_ip;lib/pdcp/pdcp_process.c pdcp_post_process_ul(const struct rte_pdcp_entity *entity,
Quoted 5 lines
(quoted diff) +1
-0+ entity->post_process =
pdcp_post_process_uplane_sn_18_dl_ip;lib/pdcp/pdcp_process.c +3
-0+ } + + if ((conf->pdcp_xfrm.domain ==
RTE_SECURITY_PDCP_MODE_DATA)Review
Quoted 2 lines
&&
(quoted diff) +1
-0+ (conf->pdcp_xfrm.sn_size == RTE_SECURITY_PDCP_SN_SIZE_18)&&
Review
Quoted 1 line
(quoted diff) +1
-0+ (conf->pdcp_xfrm.pkt_dir == RTE_SECURITY_PDCP_DOWNLINK)&&
lib/pdcp/pdcp_process.c pdcp_pre_post_func_set(struct rte_pdcp_entity *entity, const struct rte_pdcp_ent
Quoted 3 lines
lib/pdcp/pdcp_process.c +3
-0+ (!en_priv->flags.is_authenticated)) { + entity->pre_process = pdcp_pre_process_uplane_sn_18_dl; + entity->post_process =
pdcp_post_process_uplane_sn_18_dl;Quoted 7 lines
lib/pdcp/pdcp_process.c +2
-1+ } +if (entity->pre_process ==NULL || entity->post_process ==NULL )return -ENOTSUP ; --2.25.1
PATCH v2 8/22 pdcp: add IV generation routines
In reply to Anoob JosephFor PDCP, IV generated has varying formats depending on the ciphering and authentication algorithm used. Add routines to populate IV accordingly.
--- lib/pdcp/pdcp_entity.h | 87 ++++++++++++ lib/pdcp/pdcp_process.c | 284 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 371 insertions(+)
lib/pdcp/pdcp_entity.h +87 -0
@@ -26,6 +26,89 @@ struct entity_state {uint32_t rx_reord; }; +union auth_iv_partial { +/* For AES-CMAC, there is no IV, but message gets prepended */ +struct { +#if RTE_BYTE_ORDER ==RTE_LITTLE_ENDIAN +uint64_t count :32 ; +uint64_t zero_38_39 :2 ; +uint64_t direction :1 ; +uint64_t bearer :5 ; +uint64_t zero_40_63 :24 ; +#else +uint64_t count :32 ; +uint64_t bearer :5 ; +uint64_t direction :1 ; +uint64_t zero_38_39 :2 ; +uint64_t zero_40_63 :24 ; +#endif + } aes_cmac; +struct { +#if RTE_BYTE_ORDER ==RTE_LITTLE_ENDIAN +uint64_t count :32 ; +uint64_t zero_37_39 :3 ; +uint64_t bearer :5 ; +uint64_t zero_40_63 :24 ; + +uint64_t rsvd_65_71 :7 ; +uint64_t direction_64 :1 ; +uint64_t rsvd_72_111 :40 ; +uint64_t rsvd_113_119 :7 ; +uint64_t direction_112 :1 ; +uint64_t rsvd_120_127 :8 ; +#else +uint64_t count :32 ; +uint64_t bearer :5 ; +uint64_t zero_37_39 :3 ; +uint64_t zero_40_63 :24 ; + +uint64_t direction_64 :1 ; +uint64_t rsvd_65_71 :7 ; +uint64_t rsvd_72_111 :40 ; +uint64_t direction_112 :1 ; +uint64_t rsvd_113_119 :7 ; +uint64_t rsvd_120_127 :8 ; +#endif + } zs; +uint64_t u64[2 ]; +}; + +union cipher_iv_partial { +struct { +#if RTE_BYTE_ORDER ==RTE_LITTLE_ENDIAN +uint64_t count :32 ; +uint64_t zero_38_39 :2 ; +uint64_t direction :1 ; +uint64_t bearer :5 ; +uint64_t zero_40_63 :24 ; +#else +uint64_t count :32 ; +uint64_t bearer :5 ; +uint64_t direction :1 ; +uint64_t zero_38_39 :2 ; +uint64_t zero_40_63 :24 ; +#endif +uint64_t zero_64_127; + } aes_ctr; +struct { +#if RTE_BYTE_ORDER ==RTE_LITTLE_ENDIAN +uint64_t count :32 ; +uint64_t zero_38_39 :2 ; +uint64_t direction :1 ; +uint64_t bearer :5 ; +uint64_t zero_40_63 :24 ; +#else +uint64_t count :32 ; +uint64_t bearer :5 ; +uint64_t direction :1 ; +uint64_t zero_38_39 :2 ; +uint64_t zero_40_63 :24 ; +#endif +uint64_t rsvd_64_127; + } zs; +uint64_t u64[2 ]; +}; +/* * Layout of PDCP entity: [rte_pdcp_entity] [entity_priv] [entity_dl/ul] */
@@ -35,6 +118,10 @@ struct entity_priv {struct rte_cryptodev_sym_session *crypto_sess;/** Entity specific IV generation function. */ iv_gen_t iv_gen; +/** Pre-prepared auth IV. */ +union auth_iv_partial auth_iv_part; +/** Pre-prepared cipher IV. */ +union cipher_iv_partial cipher_iv_part;/** Entity state variables. */ struct entity_state state;/** Flags. */
lib/pdcp/pdcp_process.c +284 -0
302 lines not on this page · raw message
Signature · 1 line
2.25.1
RE: [PATCH v2 08/22] pdcp: add IV generation routines
Quoted 57 lines
Subject: [PATCH v2 08/22] pdcp: add IV generation routines
For PDCP, IV generated has varying formats depending on the ciphering and authentication algorithm used. Add routines to populate IV accordingly.
Signed-off-by Anoob Joseph <[email protected]>Signed-off-by Volodymyr Fialko <[email protected]>--- lib/pdcp/pdcp_entity.h | 87 ++++++++++++ lib/pdcp/pdcp_process.c | 284 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 371 insertions(+)lib/pdcp/pdcp_entity.h +36
-0@@ -26,6 +26,89 @@ struct entity_state {uint32_t rx_reord; }; +union auth_iv_partial { +/* For AES-CMAC, there is no IV, but message gets prepended */ +struct { +#if RTE_BYTE_ORDER ==RTE_LITTLE_ENDIAN +uint64_t count :32 ; +uint64_t zero_38_39 :2 ; +uint64_t direction :1 ; +uint64_t bearer :5 ; +uint64_t zero_40_63 :24 ; +#else +uint64_t count :32 ; +uint64_t bearer :5 ; +uint64_t direction :1 ; +uint64_t zero_38_39 :2 ; +uint64_t zero_40_63 :24 ; +#endif + } aes_cmac; +struct { +#if RTE_BYTE_ORDER ==RTE_LITTLE_ENDIAN +uint64_t count :32 ; +uint64_t zero_37_39 :3 ; +uint64_t bearer :5 ; +uint64_t zero_40_63 :24 ; + +uint64_t rsvd_65_71 :7 ; +uint64_t direction_64 :1 ; +uint64_t rsvd_72_111 :40 ; +uint64_t rsvd_113_119 :7 ; +uint64_t direction_112 :1 ; +uint64_t rsvd_120_127 :8 ; +#else +uint64_t count :32 ; +uint64_t bearer :5 ; +uint64_t zero_37_39 :3 ; +uint64_t zero_40_63 :24 ; +
lib/pdcp/pdcp_entity.h struct entity_state { · line 74
Quoted 10 lines
lib/pdcp/pdcp_entity.h +10
-0+ uint64_t direction_64 : 1; + uint64_t rsvd_65_71 : 7; + uint64_t rsvd_72_111 : 40; + uint64_t direction_112 : 1; + uint64_t rsvd_113_119 : 7; + uint64_t rsvd_120_127 : 8; +#endif + } zs; +uint64_t u64[2 ]; +};
Can we add pictorial comments for each of the IV formats? So that we may not need to refer the specifications again and again.
Quoted 411 lines
lib/pdcp/pdcp_entity.h +41
-0+ +union cipher_iv_partial { +struct { +#if RTE_BYTE_ORDER ==RTE_LITTLE_ENDIAN +uint64_t count :32 ; +uint64_t zero_38_39 :2 ; +uint64_t direction :1 ; +uint64_t bearer :5 ; +uint64_t zero_40_63 :24 ; +#else +uint64_t count :32 ; +uint64_t bearer :5 ; +uint64_t direction :1 ; +uint64_t zero_38_39 :2 ; +uint64_t zero_40_63 :24 ; +#endif +uint64_t zero_64_127; + } aes_ctr; +struct { +#if RTE_BYTE_ORDER ==RTE_LITTLE_ENDIAN +uint64_t count :32 ; +uint64_t zero_38_39 :2 ; +uint64_t direction :1 ; +uint64_t bearer :5 ; +uint64_t zero_40_63 :24 ; +#else +uint64_t count :32 ; +uint64_t bearer :5 ; +uint64_t direction :1 ; +uint64_t zero_38_39 :2 ; +uint64_t zero_40_63 :24 ; +#endif +uint64_t rsvd_64_127; + } zs; +uint64_t u64[2 ]; +}; +/* * Layout of PDCP entity: [rte_pdcp_entity] [entity_priv] [entity_dl/ul] */ @@ -35,6 +118,10 @@ struct entity_priv {struct rte_cryptodev_sym_session *crypto_sess;/** Entity specific IV generation function. */ iv_gen_t iv_gen; +/** Pre-prepared auth IV. */ +union auth_iv_partial auth_iv_part; +/** Pre-prepared cipher IV. */ +union cipher_iv_partial cipher_iv_part;/** Entity state variables. */ struct entity_state state;/** Flags. */ lib/pdcp/pdcp_process.c +44
-0@@ -13,6 +13,181 @@#include "pdcp_entity.h" #include "pdcp_process.h" +/* Enum of supported algorithms for ciphering */ +enum pdcp_cipher_algo { +PDCP_CIPHER_ALGO_NULL , +PDCP_CIPHER_ALGO_AES , +PDCP_CIPHER_ALGO_ZUC , +PDCP_CIPHER_ALGO_SNOW3G , +PDCP_CIPHER_ALGO_MAX +}; + +/* Enum of supported algorithms for integrity */ +enum pdcp_auth_algo { +PDCP_AUTH_ALGO_NULL , +PDCP_AUTH_ALGO_AES , +PDCP_AUTH_ALGO_ZUC , +PDCP_AUTH_ALGO_SNOW3G , +PDCP_AUTH_ALGO_MAX +}; + +/* IV generation functions based on type of operation (cipher - auth) */ + +static void +pdcp_iv_gen_null_null (struct rte_crypto_op *cop,const struct entity_priv *en_priv,uint32_t count) +{ +/* No IV required for NULL cipher + NULL auth */ +RTE_SET_USED (cop); +RTE_SET_USED (en_priv); +RTE_SET_USED (count); +} + +static void +pdcp_iv_gen_null_aes_cmac (struct rte_crypto_op *cop,const struct entity_priv *en_priv, +uint32_t count) +{ +struct rte_crypto_sym_op *op = cop->sym; +struct rte_mbuf *mb = op->m_src; +uint8_t *m_ptr; +uint64_t m; + +/* AES-CMAC requires message to be prepended with info on count etc */ + +/* Prepend by 8 bytes to add custom message */ + m_ptr = (uint8_t *)rte_pktmbuf_prepend (mb,8 ); + + m = en_priv->auth_iv_part.u64[0] |((uint64_t)(rte_cpu_to_be_32(count)));
lib/pdcp/pdcp_process.c +6
-0+ +rte_memcpy (m_ptr, &m,8 ); +} + +static void +pdcp_iv_gen_null_zs(struct rte_crypto_op *cop, const struct entity_priv
*en_priv,uint32_tcount)lib/pdcp/pdcp_process.c +7
-0+{ +uint64_t iv_u64[2 ]; +uint8_t *iv; + + iv = rte_crypto_op_ctod_offset(cop, uint8_t *, PDCP_IV_OFFSET); + + iv_u64[0] = en_priv->auth_iv_part.u64[0] |((uint64_t)(rte_cpu_to_be_32(count)));
lib/pdcp/pdcp_process.c +8
-0+rte_memcpy (iv, &iv_u64[0 ],8 ); + + iv_u64[1 ] = iv_u64[0 ] ^ en_priv->auth_iv_part.u64[1 ]; +rte_memcpy (iv +8 , &iv_u64[1 ],8 ); +} + +static void +pdcp_iv_gen_aes_ctr_null(struct rte_crypto_op *cop, const struct entity_priv
*en_priv,lib/pdcp/pdcp_process.c +8
-0+ uint32_t count) +{ +uint64_t iv_u64[2 ]; +uint8_t *iv; + + iv = rte_crypto_op_ctod_offset(cop, uint8_t *, PDCP_IV_OFFSET); + + iv_u64[0] = en_priv->cipher_iv_part.u64[0] |((uint64_t)(rte_cpu_to_be_32(count)));
lib/pdcp/pdcp_process.c +6
-0+ iv_u64[1 ] =0 ; +rte_memcpy (iv, iv_u64,16 ); +} + +static void +pdcp_iv_gen_zs_null(struct rte_crypto_op *cop, const struct entity_priv
*en_priv,uint32_tcount)lib/pdcp/pdcp_process.c +7
-0+{ +uint64_t iv_u64; +uint8_t *iv; + + iv = rte_crypto_op_ctod_offset(cop, uint8_t *, PDCP_IV_OFFSET); + + iv_u64 = en_priv->cipher_iv_part.u64[0] |((uint64_t)(rte_cpu_to_be_32(count)));
lib/pdcp/pdcp_process.c +6
-0+rte_memcpy (iv, &iv_u64,8 ); +rte_memcpy (iv +8 , &iv_u64,8 ); +} + +static void +pdcp_iv_gen_zs_zs(struct rte_crypto_op *cop, const struct entity_priv
*en_priv,uint32_tcount)lib/pdcp/pdcp_process.c +8
-0+{ +uint64_t iv_u64[2 ]; +uint8_t *iv; + + iv = rte_crypto_op_ctod_offset(cop, uint8_t *, PDCP_IV_OFFSET); + +/* Generating cipher IV */ + iv_u64[0] = en_priv->cipher_iv_part.u64[0] |((uint64_t)(rte_cpu_to_be_32(count)));
lib/pdcp/pdcp_process.c +7
-0+rte_memcpy (iv, &iv_u64[0 ],8 ); +rte_memcpy (iv +8 , &iv_u64[0 ],8 ); + + iv +=PDCP_IV_LEN ; + +/* Generating auth IV */ + iv_u64[0] = en_priv->auth_iv_part.u64[0] |((uint64_t)(rte_cpu_to_be_32(count)));
lib/pdcp/pdcp_process.c +8
-0+rte_memcpy (iv, &iv_u64[0 ],8 ); + + iv_u64[1 ] = iv_u64[0 ] ^ en_priv->auth_iv_part.u64[1 ]; +rte_memcpy (iv +8 , &iv_u64[1 ],8 ); +} + +static void +pdcp_iv_gen_zs_aes_cmac(struct rte_crypto_op *cop, const struct entity_priv
*en_priv,lib/pdcp/pdcp_process.c +10
-0+ uint32_t count) +{ +struct rte_crypto_sym_op *op = cop->sym; +struct rte_mbuf *mb = op->m_src; +uint8_t *m_ptr, *iv; +uint64_t iv_u64[2 ]; +uint64_t m; + + iv = rte_crypto_op_ctod_offset(cop, uint8_t *, PDCP_IV_OFFSET); + iv_u64[0] = en_priv->cipher_iv_part.u64[0] |((uint64_t)(rte_cpu_to_be_32(count)));
lib/pdcp/pdcp_process.c +5
-0+rte_memcpy (iv, &iv_u64[0 ],8 ); +rte_memcpy (iv +8 , &iv_u64[0 ],8 ); + + m_ptr = (uint8_t *)rte_pktmbuf_prepend (mb,8 ); + m = en_priv->auth_iv_part.u64[0] |((uint64_t)(rte_cpu_to_be_32(count)));
lib/pdcp/pdcp_process.c +5
-0+rte_memcpy (m_ptr, &m,8 ); +} + +static void +pdcp_iv_gen_aes_ctr_aes_cmac(struct rte_crypto_op *cop, const struct
entity_priv*en_priv,lib/pdcp/pdcp_process.c +11
-0+ uint32_t count) +{ +struct rte_crypto_sym_op *op = cop->sym; +struct rte_mbuf *mb = op->m_src; +uint8_t *m_ptr, *iv; +uint64_t iv_u64[2 ]; +uint64_t m; + + iv = rte_crypto_op_ctod_offset(cop, uint8_t *, PDCP_IV_OFFSET); + + iv_u64[0] = en_priv->cipher_iv_part.u64[0] |((uint64_t)(rte_cpu_to_be_32(count)));
lib/pdcp/pdcp_process.c +5
-0+ iv_u64[1 ] =0 ; +rte_memcpy (iv, iv_u64,PDCP_IV_LEN ); + + m_ptr = (uint8_t *)rte_pktmbuf_prepend (mb,8 ); + m = en_priv->auth_iv_part.u64[0] |((uint64_t)(rte_cpu_to_be_32(count)));
lib/pdcp/pdcp_process.c +5
-0+rte_memcpy (m_ptr, &m,8 ); +} + +static void +pdcp_iv_gen_aes_ctr_zs(struct rte_crypto_op *cop, const struct entity_priv
*en_priv,uint32_tcount)lib/pdcp/pdcp_process.c +7
-0+{ +uint64_t iv_u64[2 ]; +uint8_t *iv; + + iv = rte_crypto_op_ctod_offset(cop, uint8_t *, PDCP_IV_OFFSET); + + iv_u64[0] = en_priv->cipher_iv_part.u64[0] |((uint64_t)(rte_cpu_to_be_32(count)));
lib/pdcp/pdcp_process.c +6
-0+ iv_u64[1 ] =0 ; +rte_memcpy (iv, iv_u64,PDCP_IV_LEN ); + + iv +=PDCP_IV_LEN ; + + iv_u64[0] = en_priv->auth_iv_part.u64[0] |((uint64_t)(rte_cpu_to_be_32(count)));
lib/pdcp/pdcp_process.c +6
-0+rte_memcpy (iv, &iv_u64[0 ],8 ); + + iv_u64[1 ] = iv_u64[0 ] ^ en_priv->auth_iv_part.u64[1 ]; +rte_memcpy (iv +8 , &iv_u64[1 ],8 ); +} + static int pdcp_crypto_xfrm_get(const struct rte_pdcp_entity_conf *conf, struct
rte_crypto_sym_xform**c_xfrm,lib/pdcp/pdcp_process.c +0
-0struct rte_crypto_sym_xform **a_xfrm)@@ -36,6 +211,111 @@ pdcp_crypto_xfrm_get(const struct
rte_pdcp_entity_conf*conf, structrte_crypto_lib/pdcp/pdcp_process.c +2
-0return 0 ; } +static int +pdcp_iv_gen_func_set(struct rte_pdcp_entity *entity, const struct
rte_pdcp_entity_conf*conf)lib/pdcp/pdcp_process.c +31
-0+{ +struct rte_crypto_sym_xform *c_xfrm, *a_xfrm; +enum rte_security_pdcp_direction direction; +enum pdcp_cipher_algo ciph_algo; +enum pdcp_auth_algo auth_algo; +struct entity_priv *en_priv; +int ret; + + en_priv =entity_priv_get (entity); + + direction = conf->pdcp_xfrm.pkt_dir; +if (conf->reverse_iv_direction) + direction = !direction; + + ret =pdcp_crypto_xfrm_get (conf, &c_xfrm, &a_xfrm); +if (ret) +return ret; + +if (c_xfrm ==NULL ) +return -EINVAL ; + +memset (&en_priv->auth_iv_part,0 ,sizeof (en_priv->auth_iv_part)); +memset (&en_priv->cipher_iv_part,0 ,sizeof (en_priv->cipher_iv_part)); + +switch (c_xfrm->cipher.algo) { +case RTE_CRYPTO_CIPHER_NULL : + ciph_algo =PDCP_CIPHER_ALGO_NULL ; +break ; +case RTE_CRYPTO_CIPHER_AES_CTR : + ciph_algo =PDCP_CIPHER_ALGO_AES ; + en_priv->cipher_iv_part.aes_ctr.bearer = conf-Quoted 1 line
pdcp_xfrm.bearer;
lib/pdcp/pdcp_process.c +24
-0+ en_priv->cipher_iv_part.aes_ctr.direction = direction; +break ; +case RTE_CRYPTO_CIPHER_SNOW3G_UEA2 : + ciph_algo =PDCP_CIPHER_ALGO_SNOW3G ; + en_priv->cipher_iv_part.zs.bearer = conf->pdcp_xfrm.bearer; + en_priv->cipher_iv_part.zs.direction = direction; +break ; +case RTE_CRYPTO_CIPHER_ZUC_EEA3 : + ciph_algo =PDCP_CIPHER_ALGO_ZUC ; + en_priv->cipher_iv_part.zs.bearer = conf->pdcp_xfrm.bearer; + en_priv->cipher_iv_part.zs.direction = direction; +break ; +default : +return -ENOTSUP ; + } + +if (a_xfrm !=NULL ) { +switch (a_xfrm->auth.algo) { +case RTE_CRYPTO_AUTH_NULL : + auth_algo =PDCP_AUTH_ALGO_NULL ; +break ; +case RTE_CRYPTO_AUTH_AES_CMAC : + auth_algo =PDCP_AUTH_ALGO_AES ; + en_priv->auth_iv_part.aes_cmac.bearer = conf-Quoted 1 line
pdcp_xfrm.bearer;
lib/pdcp/pdcp_process.c +5
-0+ en_priv->auth_iv_part.aes_cmac.direction = direction; +break ; +case RTE_CRYPTO_AUTH_SNOW3G_UIA2 : + auth_algo =PDCP_AUTH_ALGO_SNOW3G ; + en_priv->auth_iv_part.zs.bearer = conf-Quoted 1 line
pdcp_xfrm.bearer;
lib/pdcp/pdcp_process.c +6
-0+ en_priv->auth_iv_part.zs.direction_64 = direction; + en_priv->auth_iv_part.zs.direction_112 = direction; +break ; +case RTE_CRYPTO_AUTH_ZUC_EIA3 : + auth_algo =PDCP_AUTH_ALGO_ZUC ; + en_priv->auth_iv_part.zs.bearer = conf-Quoted 1 line
pdcp_xfrm.bearer;
lib/pdcp/pdcp_process.c +11
-0+ en_priv->auth_iv_part.zs.direction_64 = direction; + en_priv->auth_iv_part.zs.direction_112 = direction; +break ; +default : +return -ENOTSUP ; + } + }else { + auth_algo =PDCP_AUTH_ALGO_NULL ; + } + + static const iv_gen_tiv_gen_map[PDCP_CIPHER_ALGO_MAX][PDCP_AUTH_ALGO_MAX] = {
lib/pdcp/pdcp_process.c +1
-0+ [PDCP_CIPHER_ALGO_NULL][PDCP_AUTH_ALGO_NULL] =
pdcp_iv_gen_null_null,lib/pdcp/pdcp_process.c +1
-0+ [PDCP_CIPHER_ALGO_NULL][PDCP_AUTH_ALGO_AES] =
pdcp_iv_gen_null_aes_cmac,lib/pdcp/pdcp_process.c +1
-0+ [PDCP_CIPHER_ALGO_NULL][PDCP_AUTH_ALGO_SNOW3G] =
pdcp_iv_gen_null_zs,lib/pdcp/pdcp_process.c +1
-0+ [PDCP_CIPHER_ALGO_NULL][PDCP_AUTH_ALGO_ZUC] =
pdcp_iv_gen_null_zs,lib/pdcp/pdcp_process.c +2
-0+ + [PDCP_CIPHER_ALGO_AES][PDCP_AUTH_ALGO_NULL] =
pdcp_iv_gen_aes_ctr_null,lib/pdcp/pdcp_process.c +1
-0+ [PDCP_CIPHER_ALGO_AES][PDCP_AUTH_ALGO_AES] =
pdcp_iv_gen_aes_ctr_aes_cmac,lib/pdcp/pdcp_process.c +1
-0+ [PDCP_CIPHER_ALGO_AES][PDCP_AUTH_ALGO_SNOW3G] =
pdcp_iv_gen_aes_ctr_zs,lib/pdcp/pdcp_process.c +1
-0+ [PDCP_CIPHER_ALGO_AES][PDCP_AUTH_ALGO_ZUC] =
pdcp_iv_gen_aes_ctr_zs,lib/pdcp/pdcp_process.c +2
-0+ + [PDCP_CIPHER_ALGO_SNOW3G][PDCP_AUTH_ALGO_NULL] =
pdcp_iv_gen_zs_null,lib/pdcp/pdcp_process.c +1
-0+ [PDCP_CIPHER_ALGO_SNOW3G][PDCP_AUTH_ALGO_AES] =
pdcp_iv_gen_zs_aes_cmac,
+[PDCP_CIPHER_ALGO_SNOW3G][PDCP_AUTH_ALGO_SNOW3G] =
pdcp_iv_gen_zs_zs,lib/pdcp/pdcp_process.c +1
-0+ [PDCP_CIPHER_ALGO_SNOW3G][PDCP_AUTH_ALGO_ZUC] =
pdcp_iv_gen_zs_zs,lib/pdcp/pdcp_process.c +2
-0+ + [PDCP_CIPHER_ALGO_ZUC][PDCP_AUTH_ALGO_NULL] =
pdcp_iv_gen_zs_null,lib/pdcp/pdcp_process.c +1
-0+ [PDCP_CIPHER_ALGO_ZUC][PDCP_AUTH_ALGO_AES] =
pdcp_iv_gen_zs_aes_cmac,lib/pdcp/pdcp_process.c +1
-0+ [PDCP_CIPHER_ALGO_ZUC][PDCP_AUTH_ALGO_SNOW3G] =
pdcp_iv_gen_zs_zs,lib/pdcp/pdcp_process.c +1
-0+ [PDCP_CIPHER_ALGO_ZUC][PDCP_AUTH_ALGO_ZUC] =
pdcp_iv_gen_zs_zs,lib/pdcp/pdcp_process.c +7
-0+ }; + + en_priv->iv_gen = iv_gen_map[ciph_algo][auth_algo]; + +return 0 ; +} + static inline void cop_prepare(const struct entity_priv *en_priv, struct rte_mbuf *mb, struct
rte_crypto_op*cop,lib/pdcp/pdcp_process.c +4
-0uint8_t data_offset, uint32_t count, const bool is_auth)@@ -909,6 +1189,10 @@ pdcp_process_func_set(struct rte_pdcp_entity *entity, const struct rte_pdcp_enti en_priv =entity_priv_get (entity); + ret =pdcp_iv_gen_func_set (entity, conf); +if (ret) +return ret; + ret =pdcp_entity_priv_populate (en_priv, conf);if (ret)return ret;
--
2.25.1
PATCH v2 9/22 app/test: add lib pdcp tests
In reply to Anoob JosephAdd tests to verify lib PDCP operations. Tests leverage existing PDCP test vectors.
--- app/test/meson.build | 1 + app/test/test_cryptodev.h | 3 + app/test/test_pdcp.c | 729 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 733 insertions(+) create mode 100644 app/test/test_pdcp.c
app/test/meson.build +1 -0
@@ -96,6 +96,7 @@ test_sources = files( 'test_meter.c', 'test_mcslock.c', 'test_mp_secondary.c', + 'test_pdcp.c', 'test_per_lcore.c', 'test_pflock.c', 'test_pmd_perf.c',
app/test/test_cryptodev.h +3 -0
@@ -4,6 +4,9 @@#ifndef TEST_CRYPTODEV_H_ #define TEST_CRYPTODEV_H_ +#include <rte_crypto.h> +#include <rte_cryptodev.h> +#define HEX_DUMP 0#define FALSE 0
app/test/test_pdcp.c new file +729 -0
729 lines not on this page · raw message
Signature · 1 line
2.25.1
RE: [PATCH v2 09/22] app/test: add lib pdcp tests
Quoted 17 lines
app/test/meson.build +1
-0@@ -96,6 +96,7 @@ test_sources = files( 'test_meter.c', 'test_mcslock.c', 'test_mp_secondary.c', + 'test_pdcp.c', 'test_per_lcore.c', 'test_pflock.c', 'test_pmd_perf.c',app/test/test_cryptodev.h +0
-0
app/test/test_cryptodev.h line 9
Quoted 6 lines
app/test/test_cryptodev.h +3
-0@@ -4,6 +4,9 @@#ifndef TEST_CRYPTODEV_H_ #define TEST_CRYPTODEV_H_ +#include <rte_crypto.h> +#include <rte_cryptodev.h> +
Can we remove these includes from here and add in test_pdcp.c directly?
Quoted 37 lines
app/test/test_cryptodev.h +8
-0+if (conf->is_integrity_protected) { +if (conf->entity.pdcp_xfrm.pkt_dir ==RTE_SECURITY_PDCP_UPLINK ) { + conf->entity.crypto_xfrm = &conf->a_xfrm; + + a_xfrm.auth.op =RTE_CRYPTO_AUTH_OP_GENERATE ; + a_xfrm.next = &conf->c_xfrm; + + c_xfrm.cipher.op =
RTE_CRYPTO_CIPHER_OP_ENCRYPT;app/test/test_cryptodev.h +5
-0+ c_xfrm.next =NULL ; + }else { + conf->entity.crypto_xfrm = &conf->c_xfrm; + + c_xfrm.cipher.op =
RTE_CRYPTO_CIPHER_OP_DECRYPT;app/test/test_cryptodev.h +10
-0+ c_xfrm.next = &conf->a_xfrm; + + a_xfrm.auth.op =RTE_CRYPTO_AUTH_OP_VERIFY ; + a_xfrm.next =NULL ; + } + }else { + conf->entity.crypto_xfrm = &conf->c_xfrm; + c_xfrm.next =NULL ; + + if (conf->entity.pdcp_xfrm.pkt_dir ==
RTE_SECURITY_PDCP_UPLINK)app/test/test_cryptodev.h +1
-0+ c_xfrm.cipher.op =
RTE_CRYPTO_CIPHER_OP_ENCRYPT;app/test/test_cryptodev.h +2
-0+else + c_xfrm.cipher.op =
RTE_CRYPTO_CIPHER_OP_DECRYPT;app/test/test_cryptodev.h +5
-0+ } +/* Update xforms to match PDCP requirements */ + + if ((c_xfrm.cipher.algo == RTE_CRYPTO_CIPHER_AES_CTR) || + (c_xfrm.cipher.algo == RTE_CRYPTO_CIPHER_ZUC_EEA3 ||
app/test/test_cryptodev.h
Quoted 10 lines
app/test/test_cryptodev.h +10
-0+ (c_xfrm.cipher.algo == RTE_CRYPTO_CIPHER_SNOW3G_UEA2))) + c_xfrm.cipher.iv.length = 16; + else + c_xfrm.cipher.iv.length = 0; + +if (conf->is_integrity_protected) { +if (a_xfrm.auth.algo ==RTE_CRYPTO_AUTH_NULL ) + a_xfrm.auth.digest_length =0 ; +else + a_xfrm.auth.digest_length =4 ;
This if-else is not needed. If is_integrity_protected, digest_length should always be 4. Also define a macro for MAC-I len. It is being used at multiple places. Similarly for IV length macro can be defined.
Quoted 23 lines
app/test/test_cryptodev.h +12
-0+ +if ((a_xfrm.auth.algo ==RTE_CRYPTO_AUTH_ZUC_EIA3 ) || + (a_xfrm.auth.algo ==RTE_CRYPTO_AUTH_SNOW3G_UIA2 )) + a_xfrm.auth.iv.length =16 ; +else + a_xfrm.auth.iv.length =0 ; + } + + conf->c_xfrm = c_xfrm; + conf->a_xfrm = a_xfrm; + + conf->entity.dev_id = (uint8_t)cryptodev_id_get(conf-Quoted 1 line
is_integrity_protected,app/test/test_cryptodev.h +3
-0+ &conf->c_xfrm, &conf->a_xfrm); + + if (pdcp_test_params[index].domain ==
RTE_SECURITY_PDCP_MODE_CONTROL||app/test/test_cryptodev.h +1
-0+ pdcp_test_params[index].domain ==
RTE_SECURITY_PDCP_MODE_DATA) {app/test/test_cryptodev.h +3
-0+ data = pdcp_test_data_in[index]; + hfn = pdcp_test_hfn[index] << pdcp_test_data_sn_size[index]; + sn = pdcp_sn_from_raw_get(data,pdcp_test_data_sn_size[index]);
app/test/test_cryptodev.h
Quoted 2 lines
app/test/test_cryptodev.h +2
-0+ count = hfn | sn; + }
The above logic can go inside lib PDCP as well.
This is specific to PDCP and not user dependent.
You can reuse the pdcp_xfrm.hfn as well.
RE: [PATCH v2 09/22] app/test: add lib pdcp tests
Hi Akhil,
Please see inline.
Thanks,
Anoob
Quoted 33 lines
-----Original Message-----
From: Akhil Goyal <[email protected]>
Sent: Thursday, May 18, 2023 1:34 PM
To: Anoob Joseph <[email protected]>; Thomas Monjalon <[email protected]>; Jerin Jacob Kollanukkaran <[email protected]>; Konstantin Ananyev <[email protected]>; Bernard Iremonger <[email protected]>
Cc: Hemant Agrawal <[email protected]>; Mattias Rönnblom <[email protected]>; Kiran Kumar Kokkilagadda <[email protected]>; Volodymyr Fialko <[email protected]>; [email protected]; Olivier Matz <[email protected]>
Subject: RE: [PATCH v2 09/22] app/test: add lib pdcp testsQuoted 20 lines
app/test/meson.build index renamed from app/test/meson.build +0
-0
52d9088578..0f658aa2ab100644app/test/meson.build +1
-0@@ -96,6 +96,7 @@ test_sources = files( 'test_meter.c', 'test_mcslock.c', 'test_mp_secondary.c', + 'test_pdcp.c', 'test_per_lcore.c', 'test_pflock.c', 'test_pmd_perf.c',app/test/test_cryptodev.h +0
-0@@ -4,6 +4,9 @@#ifndef TEST_CRYPTODEV_H_ #define TEST_CRYPTODEV_H_
Quoted 5 lines
app/test/test_cryptodev.h line 9
Quoted 3 lines
app/test/test_cryptodev.h +3
-0+#include <rte_crypto.h> +#include <rte_cryptodev.h> +Can we remove these includes from here and add in
test_pdcp.cdirectly?
[Anoob] Why? 'test_cryptodev.h' already has many references to rte_cryptodev symbols. Not including the dependencies is not correct.
Quoted 45 lines
app/test/test_cryptodev.h
Quoted 8 lines
app/test/test_cryptodev.h +5
-0+if (conf->is_integrity_protected) { +if (conf->entity.pdcp_xfrm.pkt_dir ==RTE_SECURITY_PDCP_UPLINK ) { + conf->entity.crypto_xfrm = &conf->a_xfrm; + + a_xfrm.auth.op =
RTE_CRYPTO_AUTH_OP_GENERATE;Quoted 36 lines
app/test/test_cryptodev.h +3
-0+ a_xfrm.next = &conf->c_xfrm; + + c_xfrm.cipher.op =
RTE_CRYPTO_CIPHER_OP_ENCRYPT;app/test/test_cryptodev.h +5
-0+ c_xfrm.next =NULL ; + }else { + conf->entity.crypto_xfrm = &conf->c_xfrm; + + c_xfrm.cipher.op =
RTE_CRYPTO_CIPHER_OP_DECRYPT;app/test/test_cryptodev.h +10
-0+ c_xfrm.next = &conf->a_xfrm; + + a_xfrm.auth.op =RTE_CRYPTO_AUTH_OP_VERIFY ; + a_xfrm.next =NULL ; + } + }else { + conf->entity.crypto_xfrm = &conf->c_xfrm; + c_xfrm.next =NULL ; + + if (conf->entity.pdcp_xfrm.pkt_dir ==
RTE_SECURITY_PDCP_UPLINK)app/test/test_cryptodev.h +1
-0+ c_xfrm.cipher.op =
RTE_CRYPTO_CIPHER_OP_ENCRYPT;app/test/test_cryptodev.h +2
-0+else + c_xfrm.cipher.op =
RTE_CRYPTO_CIPHER_OP_DECRYPT;app/test/test_cryptodev.h +10
-0+ } +/* Update xforms to match PDCP requirements */ + +if ((c_xfrm.cipher.algo ==RTE_CRYPTO_CIPHER_AES_CTR ) || + (c_xfrm.cipher.algo ==RTE_CRYPTO_CIPHER_ZUC_EEA3 || + (c_xfrm.cipher.algo ==RTE_CRYPTO_CIPHER_SNOW3G_UEA2 ))) + c_xfrm.cipher.iv.length =16 ; +else + c_xfrm.cipher.iv.length =0 ; +
Quoted 8 lines
app/test/test_cryptodev.h
Quoted 5 lines
app/test/test_cryptodev.h +5
-0+if (conf->is_integrity_protected) { +if (a_xfrm.auth.algo ==RTE_CRYPTO_AUTH_NULL ) + a_xfrm.auth.digest_length =0 ; +else + a_xfrm.auth.digest_length =4 ;This if-else is not needed. If
is_integrity_protected,digest_lengthshould always be 4.
[Anoob] I had explained this in v1 patch set. Will try again.
In PDCP, with AUTH_NULL it is expected to have 4 bytes of zeroized digest.
With AUTH_NULL, it is lib PDCP which would add zeroized digest. No PMD currently supported in DPDK supports non-zero digest with AUTH-NULL. Also, it is not specified what is the digest added in case of AUTH-NULL.
Quoted 3 lines
Also define a macro for MAC-I len. It is being used at multiple places. Similarly for IV length macro can be defined.
[Anoob] Agreed. You want me to introduce RTE_PDCP_MAC_I_LEN or something local would do?
Quoted 23 lines
app/test/test_cryptodev.h
Quoted 3 lines
app/test/test_cryptodev.h +3
-0+ + if ((a_xfrm.auth.algo == RTE_CRYPTO_AUTH_ZUC_EIA3) || + (a_xfrm.auth.algo ==
RTE_CRYPTO_AUTH_SNOW3G_UIA2))Quoted 16 lines
app/test/test_cryptodev.h +9
-0+ a_xfrm.auth.iv.length =16 ; + else + a_xfrm.auth.iv.length = 0; + } + + conf->c_xfrm = c_xfrm; + conf->a_xfrm = a_xfrm; + + conf->entity.dev_id = (uint8_t)cryptodev_id_get(conf-Quoted 1 line
is_integrity_protected,app/test/test_cryptodev.h +3
-0+ &conf->c_xfrm, &conf->a_xfrm); + + if (pdcp_test_params[index].domain ==
RTE_SECURITY_PDCP_MODE_CONTROL||app/test/test_cryptodev.h +1
-0+ pdcp_test_params[index].domain ==
RTE_SECURITY_PDCP_MODE_DATA) {app/test/test_cryptodev.h
Quoted 2 lines
app/test/test_cryptodev.h +2
-0+ data = pdcp_test_data_in[index]; + hfn = pdcp_test_hfn[index] <<pdcp_test_data_sn_size[index];
Quoted 9 lines
app/test/test_cryptodev.h
Quoted 4 lines
app/test/test_cryptodev.h +1
-0+ sn = pdcp_sn_from_raw_get(data,pdcp_test_data_sn_size[index]);
app/test/test_cryptodev.h +2
-0+ count = hfn | sn; + }The above logic can go inside lib PDCP as well.
This is specific to PDCP and not user dependent.
You can reuse the pdcp_xfrm.hfn as well.
[Anoob] Sorry, what exactly can go into lib PDCP? This snippet is reading SN used in a test vector and constructs the count based on SN & HFN value from vector.
RE: [PATCH v2 09/22] app/test: add lib pdcp tests
Quoted 20 lines
Quoted 20 lines
Quoted 20 lines
app/test/meson.build index renamed from app/test/meson.build +0
-0
52d9088578..0f658aa2ab100644app/test/meson.build +1
-0@@ -96,6 +96,7 @@ test_sources = files( 'test_meter.c', 'test_mcslock.c', 'test_mp_secondary.c', + 'test_pdcp.c', 'test_per_lcore.c', 'test_pflock.c', 'test_pmd_perf.c',app/test/test_cryptodev.h +0
-0@@ -4,6 +4,9 @@#ifndef TEST_CRYPTODEV_H_ #define TEST_CRYPTODEV_H_
Quoted 9 lines
Quoted 5 lines
app/test/test_cryptodev.h line 9
Quoted 3 lines
app/test/test_cryptodev.h +3
-0+#include <rte_crypto.h> +#include <rte_cryptodev.h> +Can we remove these includes from here and add in
test_pdcp.cdirectly?[Anoob] Why? '
test_cryptodev.h' already has many references torte_cryptodevsymbols. Not including the dependencies is not correct.
In that case, it can be a separate patch. But not in this patch.
Quoted 54 lines
Quoted 45 lines
app/test/test_cryptodev.h
Quoted 8 lines
app/test/test_cryptodev.h +5
-0+if (conf->is_integrity_protected) { +if (conf->entity.pdcp_xfrm.pkt_dir ==RTE_SECURITY_PDCP_UPLINK ) { + conf->entity.crypto_xfrm = &conf->a_xfrm; + + a_xfrm.auth.op =
RTE_CRYPTO_AUTH_OP_GENERATE;Quoted 36 lines
app/test/test_cryptodev.h +3
-0+ a_xfrm.next = &conf->c_xfrm; + + c_xfrm.cipher.op =
RTE_CRYPTO_CIPHER_OP_ENCRYPT;app/test/test_cryptodev.h +5
-0+ c_xfrm.next =NULL ; + }else { + conf->entity.crypto_xfrm = &conf->c_xfrm; + + c_xfrm.cipher.op =
RTE_CRYPTO_CIPHER_OP_DECRYPT;app/test/test_cryptodev.h +10
-0+ c_xfrm.next = &conf->a_xfrm; + + a_xfrm.auth.op =RTE_CRYPTO_AUTH_OP_VERIFY ; + a_xfrm.next =NULL ; + } + }else { + conf->entity.crypto_xfrm = &conf->c_xfrm; + c_xfrm.next =NULL ; + + if (conf->entity.pdcp_xfrm.pkt_dir ==
RTE_SECURITY_PDCP_UPLINK)app/test/test_cryptodev.h +1
-0+ c_xfrm.cipher.op =
RTE_CRYPTO_CIPHER_OP_ENCRYPT;app/test/test_cryptodev.h +2
-0+else + c_xfrm.cipher.op =
RTE_CRYPTO_CIPHER_OP_DECRYPT;app/test/test_cryptodev.h +10
-0+ } +/* Update xforms to match PDCP requirements */ + +if ((c_xfrm.cipher.algo ==RTE_CRYPTO_CIPHER_AES_CTR ) || + (c_xfrm.cipher.algo ==RTE_CRYPTO_CIPHER_ZUC_EEA3 || + (c_xfrm.cipher.algo ==RTE_CRYPTO_CIPHER_SNOW3G_UEA2 ))) + c_xfrm.cipher.iv.length =16 ; +else + c_xfrm.cipher.iv.length =0 ; +Quoted 8 lines
app/test/test_cryptodev.h
Quoted 5 lines
app/test/test_cryptodev.h +5
-0+if (conf->is_integrity_protected) { +if (a_xfrm.auth.algo ==RTE_CRYPTO_AUTH_NULL ) + a_xfrm.auth.digest_length =0 ; +else + a_xfrm.auth.digest_length =4 ;This if-else is not needed. If
is_integrity_protected,digest_lengthshould always be 4.
Quoted 7 lines
[Anoob] I had explained this in v1 patch set. Will try again.
In PDCP, with
AUTH_NULLit is expected to have 4 bytes of zeroized digest.With
AUTH_NULL, it is lib PDCP which would add zeroized digest. No PMD currently supported in DPDK supports non-zero digest with AUTH-NULL. Also, it is not specified what is the digest added in case of AUTH-NULL.
In auth_xform, digest_length is the expected length of digest coming out of crypto device. Now if the device is expected to support PDCP, and we are reusing the crypto APIs, We can specify the digest length required for NULL auth.
The PMDs capability can be updated accordingly.
You can add a comment in the rte_crypto_auth_xform specifically for NULL auth for PDCP case.
The reason, I am insisting on this is, for the user, while configuring auth_xform, it is setting digest length as 0 and when the packet is received the packet length is increased by digest. This will create confusion.
And it will also help in identifying the case of no integrity and null integrity.
Quoted 7 lines
Quoted 4 lines
Also define a macro for MAC-I len. It is being used at multiple places. Similarly for IV length macro can be defined.
[Anoob] Agreed. You want me to introduce
RTE_PDCP_MAC_I_LENor something local would do?
I am ok either way. Having defined in library would be better, to be used in lib and PMD as well.
Quoted 34 lines
Quoted 24 lines
app/test/test_cryptodev.h
Quoted 4 lines
app/test/test_cryptodev.h +3
-0+ + if ((a_xfrm.auth.algo == RTE_CRYPTO_AUTH_ZUC_EIA3) || + (a_xfrm.auth.algo ==
RTE_CRYPTO_AUTH_SNOW3G_UIA2))Quoted 16 lines
app/test/test_cryptodev.h +9
-0+ a_xfrm.auth.iv.length =16 ; + else + a_xfrm.auth.iv.length = 0; + } + + conf->c_xfrm = c_xfrm; + conf->a_xfrm = a_xfrm; + + conf->entity.dev_id = (uint8_t)cryptodev_id_get(conf-Quoted 1 line
is_integrity_protected,app/test/test_cryptodev.h +3
-0+ &conf->c_xfrm, &conf->a_xfrm); + + if (pdcp_test_params[index].domain ==
RTE_SECURITY_PDCP_MODE_CONTROL||app/test/test_cryptodev.h +1
-0+ pdcp_test_params[index].domain ==
RTE_SECURITY_PDCP_MODE_DATA) {app/test/test_cryptodev.h
Quoted 2 lines
app/test/test_cryptodev.h +2
-0+ data = pdcp_test_data_in[index]; + hfn = pdcp_test_hfn[index] <<pdcp_test_data_sn_size[index];
Quoted 9 lines
app/test/test_cryptodev.h
Quoted 4 lines
app/test/test_cryptodev.h +1
-0+ sn = pdcp_sn_from_raw_get(data,pdcp_test_data_sn_size[index]);
app/test/test_cryptodev.h +2
-0+ count = hfn | sn; + }The above logic can go inside lib PDCP as well.
This is specific to PDCP and not user dependent.
You can reuse the pdcp_xfrm.hfn as well.
Quoted 2 lines
[Anoob] Sorry, what exactly can go into lib PDCP? This snippet is reading SN used in a test vector and constructs the count based on SN & HFN value from vector.
This count value is being used to establish entity. I am saying, instead of taking Count, take sn as input and in the libpdcp combine pdcp_xfrm.hfn and sn as needed to create count and store in entity_priv.
Just wanted to reduce the application headache to make bitshifting and ORing to SN.
RE: [PATCH v2 09/22] app/test: add lib pdcp tests
Hi Akhil,
Please see inline.
Thanks,
Anoob
Quoted 39 lines
-----Original Message-----
From: Akhil Goyal <[email protected]>
Sent: Thursday, May 18, 2023 5:36 PM
To: Anoob Joseph <[email protected]>; Thomas Monjalon <[email protected]>; Jerin Jacob Kollanukkaran <[email protected]>; Konstantin Ananyev <[email protected]>; Bernard Iremonger <[email protected]>
Cc: Hemant Agrawal <[email protected]>; Mattias Rönnblom <[email protected]>; Kiran Kumar Kokkilagadda <[email protected]>; Volodymyr Fialko <[email protected]>; [email protected]; Olivier Matz <[email protected]>
Subject: RE: [PATCH v2 09/22] app/test: add lib pdcp testsQuoted 26 lines
Quoted 25 lines
Quoted 17 lines
app/test/meson.build index renamed from app/test/meson.build +0
-0
52d9088578..0f658aa2ab100644app/test/meson.build +1
-0@@ -96,6 +96,7 @@ test_sources = files( 'test_meter.c', 'test_mcslock.c', 'test_mp_secondary.c', + 'test_pdcp.c', 'test_per_lcore.c', 'test_pflock.c', 'test_pmd_perf.c',app/test/test_cryptodev.h +0
-0app/test/test_cryptodev.h line 9
Quoted 6 lines
app/test/test_cryptodev.h +3
-0@@ -4,6 +4,9 @@#ifndef TEST_CRYPTODEV_H_ #define TEST_CRYPTODEV_H_ +#include <rte_crypto.h> +#include <rte_cryptodev.h> +Can we remove these includes from here and add in
test_pdcp.cdirectly?
Quoted 4 lines
Quoted 3 lines
[Anoob] Why? '
test_cryptodev.h' already has many references torte_cryptodevsymbols. Not including the dependencies is not correct.In that case, it can be a separate patch. But not in this patch.
[Anoob] Is your suggestion to push this specific change as a separate patch? I can do that if you suggest so.
Quoted 57 lines
Quoted 57 lines
Quoted 46 lines
app/test/test_cryptodev.h
Quoted 9 lines
app/test/test_cryptodev.h +5
-0+if (conf->is_integrity_protected) { +if (conf->entity.pdcp_xfrm.pkt_dir ==RTE_SECURITY_PDCP_UPLINK ) { + conf->entity.crypto_xfrm = &conf->a_xfrm; + + a_xfrm.auth.op =
RTE_CRYPTO_AUTH_OP_GENERATE;Quoted 36 lines
app/test/test_cryptodev.h +3
-0+ a_xfrm.next = &conf->c_xfrm; + + c_xfrm.cipher.op =
RTE_CRYPTO_CIPHER_OP_ENCRYPT;app/test/test_cryptodev.h +5
-0+ c_xfrm.next =NULL ; + }else { + conf->entity.crypto_xfrm = &conf->c_xfrm; + + c_xfrm.cipher.op =
RTE_CRYPTO_CIPHER_OP_DECRYPT;app/test/test_cryptodev.h +10
-0+ c_xfrm.next = &conf->a_xfrm; + + a_xfrm.auth.op =RTE_CRYPTO_AUTH_OP_VERIFY ; + a_xfrm.next =NULL ; + } + }else { + conf->entity.crypto_xfrm = &conf->c_xfrm; + c_xfrm.next =NULL ; + + if (conf->entity.pdcp_xfrm.pkt_dir ==
RTE_SECURITY_PDCP_UPLINK)app/test/test_cryptodev.h +1
-0+ c_xfrm.cipher.op =
RTE_CRYPTO_CIPHER_OP_ENCRYPT;app/test/test_cryptodev.h +2
-0+else + c_xfrm.cipher.op =
RTE_CRYPTO_CIPHER_OP_DECRYPT;app/test/test_cryptodev.h +10
-0+ } +/* Update xforms to match PDCP requirements */ + +if ((c_xfrm.cipher.algo ==RTE_CRYPTO_CIPHER_AES_CTR ) || + (c_xfrm.cipher.algo ==RTE_CRYPTO_CIPHER_ZUC_EEA3 || + (c_xfrm.cipher.algo ==RTE_CRYPTO_CIPHER_SNOW3G_UEA2 ))) + c_xfrm.cipher.iv.length =16 ; +else + c_xfrm.cipher.iv.length =0 ; +Quoted 8 lines
app/test/test_cryptodev.h
Quoted 5 lines
app/test/test_cryptodev.h +5
-0+if (conf->is_integrity_protected) { +if (a_xfrm.auth.algo ==RTE_CRYPTO_AUTH_NULL ) + a_xfrm.auth.digest_length =0 ; +else + a_xfrm.auth.digest_length =4 ;This if-else is not needed. If
is_integrity_protected,digest_lengthshould always be 4.[Anoob] I had explained this in v1 patch set. Will try again.
Quoted 8 lines
Quoted 5 lines
In PDCP, with
AUTH_NULLit is expected to have 4 bytes of zeroized digest.With
AUTH_NULL, it is lib PDCP which would add zeroized digest. No PMD currently supported in DPDK supports non-zero digest with AUTH-NULL. Also, it is not specified what is the digest added in case of AUTH-NULL.In
auth_xform,digest_lengthis the expected length of digest coming out of crypto device.
[Anoob] Yes. But the packet append is the duty lib PDCP. Crypto PMD is expected to just write the digest at a specific location.
Quoted 3 lines
Now if the device is expected to support PDCP, and we are reusing the crypto APIs, We can specify the digest length required for NULL auth. The PMDs capability can be updated accordingly.
[Anoob] Again, none of the current PMDs do a zeroized digest with NULL auth. And it is not a requirement as well. Here, we are doing PDCP offload and the crypto_xforms provided here are for specific crypto transformations.
Quoted 7 lines
You can add a comment in the
rte_crypto_auth_xformspecifically for NULL auth for PDCP case.The reason, I am insisting on this is, for the user, while configuring
auth_xform, it is setting digest length as 0 and when the packet is received the packet length is increased by digest. This will create confusion. And it will also help in identifying the case of no integrity and null integrity.
[Anoob] When working with protocol, the packet would change both at header and trailer. It is just that for PDCP, the trailer is only digest. For IPsec, the change is more than digest.
Quoted 47 lines
Quoted 8 lines
Quoted 5 lines
Also define a macro for MAC-I len. It is being used at multiple places. Similarly for IV length macro can be defined.
[Anoob] Agreed. You want me to introduce
RTE_PDCP_MAC_I_LENor something local would do?I am ok either way. Having defined in library would be better, to be used in lib and PMD as well.
Quoted 34 lines
Quoted 24 lines
app/test/test_cryptodev.h
Quoted 4 lines
app/test/test_cryptodev.h +3
-0+ + if ((a_xfrm.auth.algo == RTE_CRYPTO_AUTH_ZUC_EIA3) || + (a_xfrm.auth.algo ==
RTE_CRYPTO_AUTH_SNOW3G_UIA2))Quoted 16 lines
app/test/test_cryptodev.h +9
-0+ a_xfrm.auth.iv.length =16 ; + else + a_xfrm.auth.iv.length = 0; + } + + conf->c_xfrm = c_xfrm; + conf->a_xfrm = a_xfrm; + + conf->entity.dev_id = (uint8_t)cryptodev_id_get(conf-Quoted 1 line
is_integrity_protected,app/test/test_cryptodev.h +3
-0+ &conf->c_xfrm, &conf->a_xfrm); + + if (pdcp_test_params[index].domain ==
RTE_SECURITY_PDCP_MODE_CONTROL||app/test/test_cryptodev.h +1
-0+ pdcp_test_params[index].domain ==
RTE_SECURITY_PDCP_MODE_DATA) {app/test/test_cryptodev.h
Quoted 2 lines
app/test/test_cryptodev.h +2
-0+ data = pdcp_test_data_in[index]; + hfn = pdcp_test_hfn[index] <<pdcp_test_data_sn_size[index];
Quoted 9 lines
app/test/test_cryptodev.h
Quoted 4 lines
app/test/test_cryptodev.h +1
-0+ sn = pdcp_sn_from_raw_get(data,pdcp_test_data_sn_size[index]);
app/test/test_cryptodev.h +2
-0+ count = hfn | sn; + }The above logic can go inside lib PDCP as well.
This is specific to PDCP and not user dependent.
You can reuse the pdcp_xfrm.hfn as well.Quoted 2 lines
[Anoob] Sorry, what exactly can go into lib PDCP? This snippet is reading SN used in a test vector and constructs the count based on SN &
Quoted 7 lines
HFN value from vector.
This count value is being used to establish entity. I am saying, instead of taking Count, take sn as input and in the libpdcp combine pdcp_xfrm.hfn and sn as needed to create count and store in
entity_priv.
Just wanted to reduce the application headache to make bitshifting and ORing to SN.
[Anoob] I was not able to identify a use case where having two 32 bit values for HFN & SN would make sense. But then, it would align better with current rte_security specification. Will make the change in next version.
PATCH v2 10/22 test/pdcp: pdcp HFN tests in combined mode
In reply to Anoob JosephFrom: Volodymyr Fialko <[email protected]>
Add tests to verify HFN/SN behaviour.
--- app/test/test_pdcp.c | 302 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 299 insertions(+), 3 deletions(-)
app/test/test_pdcp.c +299 -3
@@ -15,6 +15,9 @@#define CDEV_INVALID_ID UINT8_MAX#define NB_TESTS RTE_DIM(pdcp_test_params) +/* According to formula(7.2.a Window_Size) */ +#define PDCP_WINDOW_SIZE (sn_size) (1 << (sn_size - 1)) +struct pdcp_testsuite_params {struct rte_mempool *mbuf_pool;struct rte_mempool *cop_pool;
@@ -35,12 +38,69 @@ struct pdcp_test_conf {uint32_t output_len; }; +static int create_test_conf_from_index (const int index,struct pdcp_test_conf *conf); + +typedef int (*test_with_conf_t )(struct pdcp_test_conf *conf); + +static int +run_test_foreach_known_vec (test_with_conf_t test,bool stop_on_first_pass) +{ +struct pdcp_test_conf test_conf; +bool all_tests_skipped = true; +uint32_t i; +int ret; + +for (i =0 ; i <NB_TESTS ; i++) { +create_test_conf_from_index (i, &test_conf); + ret =test (&test_conf); + +if (ret ==TEST_FAILED ) { +printf ("[%03i] - %s - failed\n" , i, pdcp_test_params[i].name); +return TEST_FAILED ; + } + +if ((ret ==TEST_SKIPPED ) || (ret == -ENOTSUP )) +continue ; + +if (stop_on_first_pass) +return TEST_SUCCESS ; + + all_tests_skipped = false; + } + +if (all_tests_skipped) +return TEST_SKIPPED ; + +return TEST_SUCCESS ; +} + +static int +run_test_with_all_known_vec (const void *args) +{ +test_with_conf_t test = args; + +return run_test_foreach_known_vec (test, false); +} +static inline int pdcp_hdr_size_get (enum rte_security_pdcp_sn_size sn_size) {return RTE_ALIGN_MUL_CEIL (sn_size,8 ) /8 ; } +static int +pktmbuf_read_into (const struct rte_mbuf *m,void *buf,size_t buf_len) +{ +if (m->pkt_len > buf_len) +return -ENOMEM ; + +const void *read =rte_pktmbuf_read (m,0 , m->pkt_len, buf); +if (read !=NULL && read != buf) +memcpy (buf, read, m->pkt_len); + +return 0 ; +} +static int cryptodev_init (int dev_id) {
@@ -325,6 +385,21 @@ pdcp_sn_from_raw_get(const void *data, enum rte_security_pdcp_sn_size size)return sn; } +static void +pdcp_sn_to_raw_set (void *data,uint32_t sn,int size) +{ +if (size ==RTE_SECURITY_PDCP_SN_SIZE_12 ) { +struct rte_pdcp_up_data_pdu_sn_12_hdr *pdu_hdr = data; + pdu_hdr->sn_11_8 = ((sn &0xf00 ) >>8 ); + pdu_hdr->sn_7_0 = (sn &0xff ); + }else if (size ==RTE_SECURITY_PDCP_SN_SIZE_18 ) { +struct rte_pdcp_up_data_pdu_sn_18_hdr *pdu_hdr = data; + pdu_hdr->sn_17_16 = ((sn &0x30000 ) >>16 ); + pdu_hdr->sn_15_8 = ((sn &0xff00 ) >>8 ); + pdu_hdr->sn_7_0 = (sn &0xff ); + } +} +static int create_test_conf_from_index (const int index,struct pdcp_test_conf *conf) {
@@ -645,9 +720,17 @@ test_attempt_single(struct pdcp_test_conf *t_conf) goto mbuf_free; } - ret =pdcp_known_vec_verify (mbuf, t_conf->output, t_conf->output_len); -if (ret) - goto mbuf_free; +/* If expected output provided - verify, else - store for future use */ +if (t_conf->output_len) { + ret =pdcp_known_vec_verify (mbuf, t_conf->output, t_conf->output_len); +if (ret) + goto mbuf_free; + }else { + ret =pktmbuf_read_into (mbuf, t_conf->output,RTE_PDCP_CTRL_PDU_SIZE_MAX ); +if (ret) + goto mbuf_free; + t_conf->output_len = mbuf->pkt_len; + } ret =rte_pdcp_entity_suspend (pdcp_entity, out_mb);if (ret) {
@@ -664,6 +747,193 @@ test_attempt_single(struct pdcp_test_conf *t_conf)return ret; } +static void +uplink_to_downlink_convert (const struct pdcp_test_conf *ul_cfg, +struct pdcp_test_conf *dl_cfg) +{ +assert (ul_cfg->entity.pdcp_xfrm.pkt_dir ==RTE_SECURITY_PDCP_UPLINK ); + +memcpy (dl_cfg, ul_cfg,sizeof (*dl_cfg)); + dl_cfg->entity.pdcp_xfrm.pkt_dir =RTE_SECURITY_PDCP_DOWNLINK ; + dl_cfg->entity.reverse_iv_direction = false; + +if (dl_cfg->is_integrity_protected) { + dl_cfg->entity.crypto_xfrm = &dl_cfg->c_xfrm; + + dl_cfg->c_xfrm.cipher.op =RTE_CRYPTO_CIPHER_OP_DECRYPT ; + dl_cfg->c_xfrm.next = &dl_cfg->a_xfrm; + + dl_cfg->a_xfrm.auth.op =RTE_CRYPTO_AUTH_OP_VERIFY ; + dl_cfg->a_xfrm.next =NULL ; + }else { + dl_cfg->entity.crypto_xfrm = &dl_cfg->c_xfrm; + dl_cfg->c_xfrm.next =NULL ; + dl_cfg->c_xfrm.cipher.op =RTE_CRYPTO_CIPHER_OP_DECRYPT ; + } + + dl_cfg->entity.dev_id = (uint8_t )cryptodev_id_get (dl_cfg->is_integrity_protected, + &dl_cfg->c_xfrm, &dl_cfg->a_xfrm); + +memcpy (dl_cfg->input, ul_cfg->output, ul_cfg->output_len); + dl_cfg->input_len = ul_cfg->output_len; + +memcpy (dl_cfg->output, ul_cfg->input, ul_cfg->input_len); + dl_cfg->output_len = ul_cfg->input_len; +} + +/* +* According to ETSI TS 138 323 V17.1.0, Section 5.2.2.1, +* SN could be divided into following ranges, +* relatively to current value of RX_DELIV state: +* +-------------+-------------+-------------+-------------+ +* | -Outside | -Window | +Window | +Outside | +* | (valid) | (Invalid) | (Valid) | (Invalid) | +* +-------------+-------------^-------------+-------------+ +* | +* v +* SN(RX_DELIV) +*/ +enum sn_range_type { +SN_RANGE_MINUS_OUTSIDE , +SN_RANGE_MINUS_WINDOW , +SN_RANGE_PLUS_WINDOW , +SN_RANGE_PLUS_OUTSIDE , +}; + +#define PDCP_SET_COUNT (hfn, sn, size) ((hfn << size) | (sn & ((1 << size) - 1))) + +/* +* Take uplink test case as base, modify RX_DELIV in state and SN in input +*/ +static int +test_sn_range_type (enum sn_range_type type,struct pdcp_test_conf *conf) +{ +uint32_t rx_deliv_hfn, rx_deliv_sn, rx_deliv, new_hfn, new_sn; +const int domain = conf->entity.pdcp_xfrm.domain; +struct pdcp_test_conf dl_conf; +int ret, expected_ret; + +if (conf->entity.pdcp_xfrm.pkt_dir ==RTE_SECURITY_PDCP_DOWNLINK ) +return TEST_SKIPPED ; + +if (domain !=RTE_SECURITY_PDCP_MODE_CONTROL && domain !=RTE_SECURITY_PDCP_MODE_DATA ) +return TEST_SKIPPED ; + +const uint32_t sn_size = conf->entity.pdcp_xfrm.sn_size; +const uint32_t window_size =PDCP_WINDOW_SIZE (sn_size); +/* Max value of SN that could fit in `sn_size` bits */ +const uint32_t max_sn = (1 << sn_size) -1 ; +const uint32_t shift = (max_sn - window_size) /2 ; +/* Could be any number up to `shift` value */ +const uint32_t default_sn =RTE_MIN (2u , shift); + +/* Initialize HFN as non zero value, to be able check values before */ + rx_deliv_hfn =0xa ; + +switch (type) { +case SN_RANGE_PLUS_WINDOW : +/* Within window size, HFN stay same */ + new_hfn = rx_deliv_hfn; + rx_deliv_sn = default_sn; + new_sn = rx_deliv_sn +1 ; + expected_ret =TEST_SUCCESS ; +break ; +case SN_RANGE_MINUS_WINDOW : +/* Within window size, HFN stay same */ + new_hfn = rx_deliv_hfn; + rx_deliv_sn = default_sn; + new_sn = rx_deliv_sn -1 ; + expected_ret =TEST_FAILED ; +break ; +case SN_RANGE_PLUS_OUTSIDE : +/* RCVD_SN >= SN(RX_DELIV) + Window_Size */ + new_hfn = rx_deliv_hfn -1 ; + rx_deliv_sn = default_sn; + new_sn = rx_deliv_sn + window_size; + expected_ret =TEST_FAILED ; +break ; +case SN_RANGE_MINUS_OUTSIDE : +/* RCVD_SN < SN(RX_DELIV) - Window_Size */ + new_hfn = rx_deliv_hfn +1 ; + rx_deliv_sn = window_size + default_sn; + new_sn = rx_deliv_sn - window_size -1 ; + expected_ret =TEST_SUCCESS ; +break ; +default : +return TEST_FAILED ; + } + + rx_deliv =PDCP_SET_COUNT (rx_deliv_hfn, rx_deliv_sn, sn_size); + +/* Configure Uplink to generate expected, encrypted packet */ +pdcp_sn_to_raw_set (conf->input, new_sn, conf->entity.pdcp_xfrm.sn_size); + conf->entity.reverse_iv_direction = true; + conf->entity.count =PDCP_SET_COUNT (new_hfn, new_sn, sn_size); + conf->output_len =0 ; + ret =test_attempt_single (conf); +if (ret !=TEST_SUCCESS ) +return ret; + +/* Flip configuration to downlink */ +uplink_to_downlink_convert (conf, &dl_conf); + +/* Modify the rx_deliv to verify the expected behaviour */ + dl_conf.entity.count = rx_deliv; + ret =test_attempt_single (&dl_conf); +if ((ret ==TEST_SKIPPED ) || (ret == -ENOTSUP )) +return ret; + +TEST_ASSERT_EQUAL (ret, expected_ret,"Unexpected result" ); + +return TEST_SUCCESS ; +} + +static int +test_sn_plus_window (struct pdcp_test_conf *t_conf) +{ +return test_sn_range_type (SN_RANGE_PLUS_WINDOW , t_conf); +} + +static int +test_sn_minus_window (struct pdcp_test_conf *t_conf) +{ +return test_sn_range_type (SN_RANGE_MINUS_WINDOW , t_conf); +} + +static int +test_sn_plus_outside (struct pdcp_test_conf *t_conf) +{ +return test_sn_range_type (SN_RANGE_PLUS_OUTSIDE , t_conf); +} + +static int +test_sn_minus_outside (struct pdcp_test_conf *t_conf) +{ +return test_sn_range_type (SN_RANGE_MINUS_OUTSIDE , t_conf); +} + +static int +test_combined (struct pdcp_test_conf *ul_conf) +{ +struct pdcp_test_conf dl_conf; +int ret; + +if (ul_conf->entity.pdcp_xfrm.pkt_dir ==RTE_SECURITY_PDCP_DOWNLINK ) +return TEST_SKIPPED ; + + ul_conf->entity.reverse_iv_direction = true; + ul_conf->output_len =0 ; + + ret =test_attempt_single (ul_conf); +if (ret !=TEST_SUCCESS ) +return ret; + +uplink_to_downlink_convert (ul_conf, &dl_conf); + ret =test_attempt_single (&dl_conf); + +return ret; +} +static int run_test_for_one_known_vec (const void *arg) {
@@ -674,8 +944,34 @@ run_test_for_one_known_vec(const void *arg)return test_attempt_single (&test_conf); } +static struct unit_test_suite combined_mode_cases = { + .suite_name ="PDCP combined mode" , + .unit_test_cases = { +TEST_CASE_NAMED_WITH_DATA ("combined mode" , ut_setup_pdcp, ut_teardown_pdcp, + run_test_with_all_known_vec, test_combined), +TEST_CASES_END ()/**< NULL terminate unit test array */ + } +}; + +static struct unit_test_suite hfn_sn_test_cases = { + .suite_name ="PDCP HFN/SN" , + .unit_test_cases = { +TEST_CASE_NAMED_WITH_DATA ("SN plus window" , ut_setup_pdcp, ut_teardown_pdcp, + run_test_with_all_known_vec, test_sn_plus_window), +TEST_CASE_NAMED_WITH_DATA ("SN minus window" , ut_setup_pdcp, ut_teardown_pdcp, + run_test_with_all_known_vec, test_sn_minus_window), +TEST_CASE_NAMED_WITH_DATA ("SN plus outside" , ut_setup_pdcp, ut_teardown_pdcp, + run_test_with_all_known_vec, test_sn_plus_outside), +TEST_CASE_NAMED_WITH_DATA ("SN minus outside" , ut_setup_pdcp, ut_teardown_pdcp, + run_test_with_all_known_vec, test_sn_minus_outside), +TEST_CASES_END ()/**< NULL terminate unit test array */ + } +}; +struct unit_test_suite *test_suites[] = {NULL ,/* Place holder for known_vector_cases */ + &combined_mode_cases, + &hfn_sn_test_cases,NULL /* End of suites list */ };
Signature · 1 line
2.25.1
PATCH v2 11/22 doc: add PDCP library guide
In reply to Anoob JosephAdd guide for PDCP library.
--- .../img/pdcp_functional_overview.svg | 1 + doc/guides/prog_guide/index.rst | 1 + doc/guides/prog_guide/pdcp_lib.rst | 246 ++++++++++++++++++ 3 files changed, 248 insertions(+) create mode 100644 doc/guides/prog_guide/img/pdcp_functional_overview.svg create mode 100644 doc/guides/prog_guide/pdcp_lib.rst
doc/guides/prog_guide/img/pdcp_functional_overview.svg new file +1 -0
@@ -0,0 +1 @@ +<svg width="1280" height="720" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" overflow="hidden"><defs><clipPath id="clip0"><rect x="0" y="0" width="1280" height="720"/></clipPath></defs><g clip-path="url(#clip0)"><rect x="0" y="0" width="1280" height="720" fill="#FFFFFF"/><rect x="202" y="100" width="369" height="457" fill="#A5A5A5" fill-opacity="0.501961"/><rect x="640" y="100" width="369" height="457" fill="#A5A5A5" fill-opacity="0.501961"/><path d="M605.5 73.5001 605.5 590.633" stroke="#000000" stroke-width="1.33333" stroke-miterlimit="8" fill="none" fill-rule="evenodd"/><path d="M380.5 634 803.25 634 803.25 585.907 790.5 585.907 816 557.5 841.5 585.907 828.75 585.907 828.75 659.5 380.5 659.5Z" stroke="#787878" stroke-width="1.33333" stroke-miterlimit="8" fill="#A5A5A5" fill-rule="evenodd"/><rect x="362.5" y="557.5" width="28" height="102" stroke="#787878" stroke-width="1.33333" stroke-miterlimit="8" fill="#A5A5A5"/><rect x="412.5" y="671.5" width="370" height="32" stroke="#000000" stroke-linejoin="round" stroke-miterlimit="10" fill="none"/><text font-family="Arial,Arial_MSFontService,sans-serif" font-weight="400" font-size="19" transform="translate(492.364 694)">Radio Interface (<tspan font-size="19" x="137.5" y="0">Uu</tspan><tspan font-size="19" x="161.333" y="0">/PC5)</tspan><tspan font-size="19" x="-282.121" y="-653">UE/NG</tspan><tspan font-size="19" x="-222.955" y="-653">-</tspan><tspan font-size="19" x="-216.788" y="-653">RAN/UE A</tspan><tspan font-size="19" x="375.54" y="-653">NG</tspan>-<tspan font-size="19" x="409.706" y="-653">RAN/UE/UE B</tspan><tspan font-size="14" x="0.896851" y="-647">Transmitting </tspan><tspan font-size="14" x="1.31018" y="-631">PDCP entity</tspan><tspan font-size="14" x="167.401" y="-647">Receiving </tspan><tspan font-size="14" x="160.148" y="-631">PDCP entity</tspan></text><path d="M314.5 71.5001 431.364 71.6549" stroke="#000000" stroke-width="0.666667" stroke-miterlimit="8" fill="none" fill-rule="evenodd"/><path d="M331.5 71.5001C331.5 65.9772 349.633 61.5001 372 61.5001 394.368 61.5001 412.5 65.9772 412.5 71.5001 412.5 77.0229 394.368 81.5001 372 81.5001 349.633 81.5001 331.5 77.0229 331.5 71.5001Z" stroke="#000000" stroke-width="1.33333" stroke-miterlimit="8" fill="#FFFFFF" fill-rule="evenodd"/><path d="M353.5 90.5001 363.5 90.5001 363.5 48.5001 383.5 48.5001 383.5 90.5001 393.5 90.5001 373.5 110.5Z" stroke="#000000" stroke-width="1.33333" stroke-miterlimit="8" fill="#FFFFFF" fill-rule="evenodd"/><path d="M877.364 82.6549 760.5 82.5001" stroke="#000000" stroke-width="0.666667" stroke-miterlimit="8" fill="none" fill-rule="evenodd"/><path d="M860.5 83.5001C860.5 89.0229 842.368 93.5001 820 93.5001 797.633 93.5001 779.5 89.0229 779.5 83.5001 779.5 77.9772 797.633 73.5001 820 73.5001 842.368 73.5001 860.5 77.9772 860.5 83.5001Z" stroke="#000000" stroke-width="1.33333" stroke-miterlimit="8" fill="#FFFFFF" fill-rule="evenodd"/><path d="M838.5 64.5 828.5 64.5 828.5 106.5 808.5 106.5 808.5 64.5 798.5 64.5 818.5 44.5001Z" stroke="#000000" stroke-width="1.33333" stroke-miterlimit="8" fill="#FFFFFF" fill-rule="evenodd"/><rect x="244.5" y="128.5" width="285" height="55" stroke="#000000" stroke-width="1.33333" stroke-miterlimit="8" fill="#FFFFFF"/><text font-family="Arial,Arial_MSFontService,sans-serif" font-weight="400" font-size="19" transform="translate(302.494 150)">Transmission buffer:<tspan font-size="19" x="-4.67999" y="23">Sequence</tspan><tspan font-size="19" x="84.32" y="23">numberin</tspan>g</text><rect x="244.5" y="199.5" width="285" height="55" stroke="#000000" stroke-width="1.33333" stroke-miterlimit="8" fill="#FFFFFF"/><text font-family="Arial,Arial_MSFontService,sans-serif" font-weight="400" font-size="19" transform="translate(297.314 222)">Header or uplink data<tspan font-size="19" x="34.08" y="23">Compressio</tspan>n</text><rect x="682.5" y="141.5" width="285" height="55" stroke="#000000" stroke-width="1.33333" stroke-miterlimit="8" fill="#FFFFFF"/><text font-family="Arial,Arial_MSFontService,sans-serif" font-weight="400" font-size="19" transform="translate(735.782 164)">Header or uplink data<tspan font-size="19" x="24.2466" y="23">Decompressio</tspan>n</text><rect x="244.5" y="482.5" width="285" height="33" stroke="#000000" stroke-width="1.33333" stroke-miterlimit="8" fill="#FFFFFF"/><text font-family="Arial,Arial_MSFontService,sans-serif" font-weight="400" font-size="19" transform="translate(300.314 505)">Routing / Duplication</text><rect x="244.5" y="437.5" width="285" height="32" stroke="#000000" stroke-width="1.33333" stroke-miterlimit="8" fill="#FFFFFF"/><text font-family="Arial,Arial_MSFontService,sans-serif" font-weight="400" font-size="19" transform="translate(309.734 460)">Add PDCP header</text><rect x="244.5" y="383.5" width="189" height="33" stroke="#000000" stroke-width="1.33333" stroke-miterlimit="8" fill="#FFFFFF"/><text font-family="Arial,Arial_MSFontService,sans-serif" font-weight="400" font-size="19" transform="translate(298.62 406)">Ciphering</text><rect x="244.5" y="333.5" width="189" height="32" stroke="#000000" stroke-width="1.33333" stroke-miterlimit="8" fill="#FFFFFF"/><text font-family="Arial,Arial_MSFontService,sans-serif" font-weight="400" font-size="19" transform="translate(261.953 356)">Integrity protection</text><path d="M472.167 267.5 472.167 409.802 470.833 409.802 470.833 267.5ZM475.5 408.468 471.5 416.468 467.5 408.468Z"/><path d="M332.167 267.5 332.167 319.552 330.833 319.552 330.833 267.5ZM335.5 318.218 331.5 326.218 327.5 318.219Z"/><text font-family="Arial,Arial_MSFontService,sans-serif" font-weight="400" font-size="19" transform="translate(253.644 291)">Packets associated <tspan font-size="19" x="14.0067" y="23">to a PDCP SDU</tspan></text><text font-family="Arial,Arial_MSFontService,sans-serif" font-weight="400" font-size="19" transform="matrix(6.12323e-17 1 -1 6.12323e-17 499.312 299)">Packets not <tspan font-size="19" x="-14" y="23">associated to a </tspan><tspan font-size="19" x="-2.75546e-15" y="45">PDCP SDU</tspan></text><rect x="682.5" y="482.5" width="285" height="33" stroke="#000000" stroke-width="1.33333" stroke-miterlimit="8" fill="#FFFFFF"/><text font-family="Arial,Arial_MSFontService,sans-serif" font-weight="400" font-size="19" transform="translate(728.535 505)">Remove PDCP Header</text><rect x="682.5" y="437.5" width="203" height="32" stroke="#000000" stroke-width="1.33333" stroke-miterlimit="8" fill="#FFFFFF"/><text font-family="Arial,Arial_MSFontService,sans-serif" font-weight="400" font-size="19" transform="translate(733.729 460)">Deciphering</text><rect x="682.5" y="389.5" width="203" height="33" stroke="#000000" stroke-width="1.33333" stroke-miterlimit="8" fill="#FFFFFF"/><text font-family="Arial,Arial_MSFontService,sans-serif" font-weight="400" font-size="19" transform="translate(702.159 412)">Integrity Verification</text><rect x="682.5" y="303.5" width="203" height="77" stroke="#000000" stroke-width="1.33333" stroke-miterlimit="8" fill="#FFFFFF"/><text font-family="Arial,Arial_MSFontService,sans-serif" font-weight="400" font-size="19" transform="translate(712.729 325)">Reception buffer:<tspan font-size="19" x="24.6667" y="23">Reordering</tspan><tspan font-size="19" x="-13.1667" y="45">Duplicate discardin</tspan><tspan font-size="19" x="144.167" y="45">g</tspan><tspan font-size="19" x="-10.0989" y="-84">Packets associated </tspan><tspan font-size="19" x="3.90784" y="-61">to a PDCP SDU</tspan></text><text font-family="Arial,Arial_MSFontService,sans-serif" font-weight="400" font-size="19" transform="matrix(6.12323e-17 1 -1 6.12323e-17 960.34 294)">Packets not <tspan font-size="19" x="-14" y="23">associated to a </tspan><tspan font-size="19" x="1" y="45">PDCP SDU</tspan></text><path d="M0.666667-8.2074e-07 0.666763 78.6116-0.66657 78.6116-0.666667 8.2074e-07ZM4.00009 77.2782 0.000104987 85.2782-3.9999 77.2782Z" transform="matrix(1 0 0 -1 779.5 296.778)"/><path d="M0.666667-2.88742e-07 0.666769 235.734-0.666565 235.734-0.666667 2.88742e-07ZM4.0001 234.401 0.000104987 242.401-3.9999 234.401Z" transform="matrix(1 0 0 -1 931.5 453.901)"/></g></svg>
doc/guides/prog_guide/index.rst +1 -0
@@ -77,4 +77,5 @@ Programmer's Guide lto profile_app asan + pdcp_lib glossary
doc/guides/prog_guide/pdcp_lib.rst new file +246 -0
246 lines not on this page · raw message
Signature · 1 line
2.25.1
RE: [PATCH v2 11/22] doc: add PDCP library guide
Quoted 44 lines
doc/guides/prog_guide/pdcp_lib.rst new file +14
-0@@ -0,0 +1,246 @@ +.. SPDX-License-Identifier: BSD-3-Clause + Copyright(C) 2023 Marvell. + +PDCP Protocol Processing Library +================================ + +DPDK provides a library for PDCP protocol processing. The library utilizes +other DPDK libraries such as cryptodev, reorder, etc., to provide the +application with a transparent and high performant PDCP protocol processing +library. + +The library abstracts complete PDCP protocol processing conforming to +``ETSI TS 138 323 V17.1.0 (2022-08)``. +https://www.etsi.org/deliver/etsi_ts/138300_138399/138323/17.01.00_60/ts_138323v170100p.pdf
doc/guides/prog_guide/pdcp_lib.rst new file +22
-0+ +PDCP would involve the following operations, + +1. Transfer of user plane data +2. Transfer of control plane data +3. Header compression +4. Uplink data compression +5. Ciphering and integrity protection + +.. _figure_pdcp_functional_overview: + +.. figure:: img/pdcp_functional_overview.* + + PDCP functional overview new + +PDCP library would abstract the protocol offload features of the cryptodev and +would provide a uniform interface and consistent API usage to work with +cryptodev irrespective of the protocol offload features supported. + +PDCP entity API +--------------- +
doc/guides/prog_guide/pdcp_lib.rst line 46
Quoted 10 lines
doc/guides/prog_guide/pdcp_lib.rst new file +10
-0+PDCP library provides following control path APIs that is used to +configure various PDCP entities, + +1. ``rte_pdcp_entity_establish()`` +2. ``rte_pdcp_entity_suspend()`` +3. ``rte_pdcp_entity_release()`` + +A PDCP entity would translate to one ``rte_cryptodev_sym_session`` or +``rte_security_session`` based on the config. The sessions would be created/ +destroyed while corresponding PDCP entity operations are performed.
Please explain the difference between suspend and release here.
Quoted 13 lines
doc/guides/prog_guide/pdcp_lib.rst new file +13
-0+ +PDCP PDU (Protocol Data Unit) +----------------------------- + +PDCP PDUs can be categorized as, + +1. Control PDU +2. Data PDU + +Control PDUs are used for signalling between entities on either end and can be +one of the following, + +1. PDCP status report
doc/guides/prog_guide/pdcp_lib.rst line 69
Quoted 10 lines
doc/guides/prog_guide/pdcp_lib.rst new file +10
-0+2. ROHC feedback +3. EHC feedback + +Control PDUs are not ciphered or authenticated, and so such packets are not +submitted to cryptodev for processing. + +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. +
Please move the PDCP PDU section above PDCP entity API section. So that all APIs are together.
Quoted 174 lines
doc/guides/prog_guide/pdcp_lib.rst new file +18
-0+PDCP packet processing API for data PDU +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +PDCP processing is split into 2 parts. One before cryptodev processing +(``rte_pdcp_pkt_pre_process()``) and one after cryptodev processing +(``rte_pdcp_pkt_post_process()``). Since cryptodev dequeue can return crypto +operations belonging to multiple entities, ``rte_pdcp_pkt_crypto_group()`` +is added to help grouping crypto operations belonging to same PDCP entity. + +Lib PDCP would allow application to use same API sequence while leveraging +protocol offload features enabled by ``rte_security`` library. Lib PDCP would +internally change the handles registered for ``pre_process`` and +``post_process`` based on features enabled in the entity. + +Lib PDCP would create the required sessions on the device provided in entity to +minimize the application requirements. Also, the crypto_op allocation and free +would also be done internally by lib PDCP to allow the library to create +crypto ops as required for the input packets. For example, when control PDUsare
+received, no cryptodev enqueue-dequeue is expected for the same and lib PDCPdoc/guides/prog_guide/pdcp_lib.rst new file +52
-0+is expected to handle it differently. + +Sample API usage +---------------- + +The ``rte_pdcp_entity_conf`` structure is used to pass the configuration +parameters for entity creation. + +.. literalinclude:: ../../../lib/pdcp/rte_pdcp.h + :language: c + :start-after: Structure rte_pdcp_entity_conf 8< + :end-before: >8 End of structure rte_pdcp_entity_conf. + +.. code-block:: c + + struct rte_mbuf **out_mb, *pkts[MAX_BURST_SIZE]; + struct rte_crypto_op *cop[MAX_BURST_SIZE]; + struct rte_pdcp_group grp[MAX_BURST_SIZE]; + struct rte_pdcp_entity *pdcp_entity; + int nb_max_out_mb, ret, nb_grp; + uint16_t nb_ops; + + /* Create PDCP entity */ + pdcp_entity = rte_pdcp_entity_establish(&conf); + + /** + * Allocate buffer for holding mbufs returned during PDCP suspend, + * release & post-process APIs. + */ + + /* Max packets that can be cached in entity + burst size */ + nb_max_out_mb = pdcp_entity->max_pkt_cache + MAX_BURST_SIZE; + out_mb = rte_malloc(NULL, nb_max_out_mb * sizeof(uintptr_t), 0); + if (out_mb == NULL) { + /* Handle error */ + } + + while (1) { + /* Receive packet and form mbuf */ + + /** + * Prepare packets for crypto operation. Following operations + * would be done, + * + * Transmitting entity/UL (only data PDUs): + * - Perform compression + * - Assign sequence number + * - Add PDCP header + * - Create & prepare crypto_op + * - Prepare IV for crypto operation (auth_gen, encrypt) + * - Save original PDCP SDU (during PDCP re-establishment, + * unconfirmed PDCP SDUs need to crypto processed againand
doc/guides/prog_guide/pdcp_lib.rst new file +6
-0+ * transmitted/re-transmitted) + * + * Receiving entity/DL: + * - Any control PDUs received would be processed and + * appropriate actions taken. If data PDU, continue. + * - Determine sequence number (based on HFN & per packetSN)
doc/guides/prog_guide/pdcp_lib.rst new file +10
-0+ * - Prepare crypto_op + * - Prepare IV for crypto operation (decrypt, auth_verify) + */ + nb_success = rte_pdcp_pkt_pre_process(pdcp_entity, pkts, cop, + nb_rx, &nb_err); + if (nb_err != 0) { + /* Handle error packets */ + } + + if ((rte_cryptodev_enqueue_burst(dev_id, qp_id, cop,
nb_success)doc/guides/prog_guide/pdcp_lib.rst new file +60
-0+ != nb_success) { + /* Retry for enqueue failure packets */ + } + + ... + + nb_ops = rte_cryptodev_dequeue_burst(dev_id, qp_id, cop, + MAX_BURST_SIZE); + if (nb_ops == 0) + continue; + + /** + * Received a burst of completed crypto ops from cryptodev. It + * may belong to various entities. Group similar ones together + * for entity specific post-processing. + */ + + /** + * Groups similar entities together. Frees crypto op and based + * on crypto_op status, set mbuf->ol_flags which would be + * checked in rte_pdcp_pkt_post_process(). + */ + nb_grp = rte_pdcp_pkt_crypto_group(cop, pkts, grp, ret); + + for (i = 0; i != nb_grp; i++) { + + /** + * Post process packets after crypto completion. + * Following operations would be done, + * + * Transmitting entity/UL: + * - Check crypto result + * + * Receiving entity/DL: + * - Check crypto operation status + * - Check for duplication (if yes, drop duplicate) + * - Perform decompression + * - Trim PDCP header + * - Hold packet (SDU) for in-order delivery (return + * completed packets as and when sequence is + * completed) + * - If not in sequence, cache the packet and start + * t-Reordering timer. When timer expires, the + * packets need to delivered to upper layers (not + * treated as error packets). + */ + nb_success = rte_pdcp_pkt_post_process(grp[i].id.ptr, + grp[i].m, out_mb, + grp[i].cnt, + &nb_err); + if (nb_err != 0) { + /* Handle error packets */ + } + + /* Perform additional operations */ + + /** + * Transmitting entity/UL + * - If duplication is enabled, duplicate PDCP PDUs + * - When lower layers confirm reception of a PDCPPDU,
doc/guides/prog_guide/pdcp_lib.rst new file +21
-0+ * it should be communicated to PDCP layer so that + * PDCP can drop the corresponding SDU + */ + } + } + + +Supported features +------------------ + +- 12 bit & 18 bit sequence numbers +- Uplink & downlink traffic +- HFN increment +- IV generation as required per algorithm + +Supported ciphering algorithms +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- NULL +- AES-CTR +- SNOW3G-CIPHER
doc/guides/prog_guide/pdcp_lib.rst
Quoted 10 lines
doc/guides/prog_guide/pdcp_lib.rst new file +9
-1+- ZUC-CIPHER + +Supported integrity protection algorithms +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- NULL +- AES-CMAC +- SNOW3G-AUTH +- ZUC-AUTH --
Move Supported features and algos after PDCP PDU explanation. Sample sequence should be in the end.
RE: [PATCH v2 11/22] doc: add PDCP library guide
Hi Akhil,
Please see inline.
Thanks,
Anoob
Quoted 71 lines
-----Original Message-----
From: Akhil Goyal <[email protected]>
Sent: Thursday, May 18, 2023 1:56 PM
To: Anoob Joseph <[email protected]>; Thomas Monjalon <[email protected]>; Jerin Jacob Kollanukkaran <[email protected]>; Konstantin Ananyev <[email protected]>; Bernard Iremonger <[email protected]>
Cc: Hemant Agrawal <[email protected]>; Mattias Rönnblom <[email protected]>; Kiran Kumar Kokkilagadda <[email protected]>; Volodymyr Fialko <[email protected]>; [email protected]; Olivier Matz <[email protected]>
Subject: RE: [PATCH v2 11/22] doc: add PDCP library guideQuoted 31 lines
doc/guides/prog_guide/pdcp_lib.rst new file +15
-0@@ -0,0 +1,246 @@ +.. SPDX-License-Identifier: BSD-3-Clause + Copyright(C) 2023 Marvell. + +PDCP Protocol Processing Library +================================ + +DPDK provides a library for PDCP protocol processing. The library +utilizes other DPDK libraries such as cryptodev, reorder, etc., to +provide the application with a transparent and high performant PDCP +protocol processing library. + +The library abstracts complete PDCP protocol processing conforming to +``ETSI TS 138 323 V17.1.0 (2022-08)``. +https://www.etsi.org/deliver/etsi_ts/138300_138399/138323/17.01.00_60 +/ts_138323v170100p.pdf
doc/guides/prog_guide/pdcp_lib.rst new file +8
-0+ +PDCP would involve the following operations, + +1. Transfer of user plane data +2. Transfer of control plane data +3. Header compression +4. Uplink data compression +5. Ciphering and integrity protectiondoc/guides/prog_guide/pdcp_lib.rst
Quoted 10 lines
doc/guides/prog_guide/pdcp_lib.rst new file +10
-0+ +.. _figure_pdcp_functional_overview: + +.. figure:: img/pdcp_functional_overview.* + + PDCP functional overview new + +PDCP library would abstract the protocol offload features of the +cryptodev and would provide a uniform interface and consistent API +usage to work with cryptodev irrespective of the protocol offloadfeatures supported.
Quoted 4 lines
doc/guides/prog_guide/pdcp_lib.rst new file +4
-0+ +PDCP entity API +--------------- +doc/guides/prog_guide/pdcp_lib.rst
Quoted 10 lines
doc/guides/prog_guide/pdcp_lib.rst new file +10
-0+PDCP library provides following control path APIs that is used to +configure various PDCP entities, + +1. ``rte_pdcp_entity_establish()`` +2. ``rte_pdcp_entity_suspend()`` +3. ``rte_pdcp_entity_release()`` + +A PDCP entity would translate to one ``rte_cryptodev_sym_session`` or +``rte_security_session`` based on the config. The sessions would be +created/ destroyed while corresponding PDCP entity operations areperformed.
Quoted 1 line
Please explain the difference between suspend and release here.
[Anoob] Sure. Will do in next version.
Quoted 18 lines
Quoted 18 lines
doc/guides/prog_guide/pdcp_lib.rst new file +17
-0+ +PDCP PDU (Protocol Data Unit) +----------------------------- + +PDCP PDUs can be categorized as, + +1. Control PDU +2. Data PDU + +Control PDUs are used for signalling between entities on either end +and can be one of the following, + +1. PDCP status report +2. ROHC feedback +3. EHC feedback + +Control PDUs are not ciphered or authenticated, and so such packets
Quoted 8 lines
doc/guides/prog_guide/pdcp_lib.rst
Quoted 6 lines
doc/guides/prog_guide/pdcp_lib.rst new file +6
-0+are not submitted to cryptodev for processing. + +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. +Please move the PDCP PDU section above PDCP entity API section. So that all APIs are together.
[Anoob] PDCP PDU section is also talking about APIs. I'll rename above title from 'PDCP PDU(Protocol Data Unit)' to 'PDCP PDU(Protocol Data Unit) API' to make it more uniform.
Quoted 192 lines
doc/guides/prog_guide/pdcp_lib.rst
Quoted 11 lines
doc/guides/prog_guide/pdcp_lib.rst new file +9
-0+PDCP packet processing API for data PDU +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +PDCP processing is split into 2 parts. One before cryptodev +processing +(``rte_pdcp_pkt_pre_process()``) and one after cryptodev processing +(``rte_pdcp_pkt_post_process()``). Since cryptodev dequeue can return +crypto operations belonging to multiple entities, +``rte_pdcp_pkt_crypto_group()`` is added to help grouping cryptooperations belonging to same PDCP entity.
doc/guides/prog_guide/pdcp_lib.rst
Quoted 5 lines
doc/guides/prog_guide/pdcp_lib.rst new file +5
-0+ +Lib PDCP would allow application to use same API sequence while +leveraging protocol offload features enabled by ``rte_security`` +library. Lib PDCP would internally change the handles registered for +``pre_process`` and ``post_process`` based on features enabled in theentity.
Quoted 32 lines
doc/guides/prog_guide/pdcp_lib.rst new file +6
-0+ +Lib PDCP would create the required sessions on the device provided in +entity to minimize the application requirements. Also, the crypto_op +allocation and free would also be done internally by lib PDCP to +allow the library to create crypto ops as required for the input +packets. For example, when control PDUsare
doc/guides/prog_guide/pdcp_lib.rst new file +2
-0+received, no cryptodev enqueue-dequeue is expected for the same and +libPDCP
doc/guides/prog_guide/pdcp_lib.rst new file +22
-0+is expected to handle it differently. + +Sample API usage +---------------- + +The ``rte_pdcp_entity_conf`` structure is used to pass the +configuration parameters for entity creation. + +.. literalinclude:: ../../../lib/pdcp/rte_pdcp.h + :language: c + :start-after: Structure rte_pdcp_entity_conf 8< + :end-before: >8 End of structure rte_pdcp_entity_conf. + +.. code-block:: c + + struct rte_mbuf **out_mb, *pkts[MAX_BURST_SIZE]; + struct rte_crypto_op *cop[MAX_BURST_SIZE]; + struct rte_pdcp_group grp[MAX_BURST_SIZE]; + struct rte_pdcp_entity *pdcp_entity; + int nb_max_out_mb, ret, nb_grp; + uint16_t nb_ops; +doc/guides/prog_guide/pdcp_lib.rst
Quoted 10 lines
doc/guides/prog_guide/pdcp_lib.rst new file +10
-0+ /* Create PDCP entity */ + pdcp_entity = rte_pdcp_entity_establish(&conf); + + /** + * Allocate buffer for holding mbufs returned during PDCP suspend, + * release & post-process APIs. + */ + + /* Max packets that can be cached in entity + burst size */ + nb_max_out_mb = pdcp_entity->max_pkt_cache +
MAX_BURST_SIZE;Quoted 21 lines
doc/guides/prog_guide/pdcp_lib.rst new file +20
-0+ out_mb = rte_malloc(NULL, nb_max_out_mb * sizeof(uintptr_t), 0); + if (out_mb == NULL) { + /* Handle error */ + } + + while (1) { + /* Receive packet and form mbuf */ + + /** + * Prepare packets for crypto operation. Following operations + * would be done, + * + * Transmitting entity/UL (only data PDUs): + * - Perform compression + * - Assign sequence number + * - Add PDCP header + * - Create & prepare crypto_op + * - Prepare IV for crypto operation (auth_gen, encrypt) + * - Save original PDCP SDU (during PDCP re-establishment, + * unconfirmed PDCP SDUs need to crypto processed againand
doc/guides/prog_guide/pdcp_lib.rst
Quoted 6 lines
doc/guides/prog_guide/pdcp_lib.rst new file +6
-0+ * transmitted/re-transmitted) + * + * Receiving entity/DL: + * - Any control PDUs received would be processed and + * appropriate actions taken. If data PDU, continue. + * - Determine sequence number (based on HFN & perpacket
doc/guides/prog_guide/pdcp_lib.rst
Quoted 5 lines
SN)
doc/guides/prog_guide/pdcp_lib.rst new file +4
-0+ * - Prepare crypto_op + * - Prepare IV for crypto operation (decrypt, auth_verify) + */ + nb_success = rte_pdcp_pkt_pre_process(pdcp_entity, pkts,cop,
Quoted 10 lines
doc/guides/prog_guide/pdcp_lib.rst new file +6
-0+ nb_rx, &nb_err); + if (nb_err != 0) { + /* Handle error packets */ + } + + if ((rte_cryptodev_enqueue_burst(dev_id, qp_id, cop,
nb_success)doc/guides/prog_guide/pdcp_lib.rst new file +3
-0+ != nb_success) { + /* Retry for enqueue failure packets */ + }doc/guides/prog_guide/pdcp_lib.rst
Quoted 10 lines
doc/guides/prog_guide/pdcp_lib.rst new file +10
-0+ + ... + + nb_ops = rte_cryptodev_dequeue_burst(dev_id, qp_id, cop, + MAX_BURST_SIZE); + if (nb_ops == 0) + continue; + + /** + * Received a burst of completed crypto ops from cryptodev.It
doc/guides/prog_guide/pdcp_lib.rst
Quoted 1 line
doc/guides/prog_guide/pdcp_lib.rst new file +1
-0+ * may belong to various entities. Group similar onestogether
doc/guides/prog_guide/pdcp_lib.rst
Quoted 5 lines
doc/guides/prog_guide/pdcp_lib.rst new file +5
-0+ * for entity specific post-processing. + */ + + /** + * Groups similar entities together. Frees crypto op andbased
Quoted 18 lines
doc/guides/prog_guide/pdcp_lib.rst new file +18
-0+ * on crypto_op status, set mbuf->ol_flags which would be + * checked in rte_pdcp_pkt_post_process(). + */ + nb_grp = rte_pdcp_pkt_crypto_group(cop, pkts, grp, ret); + + for (i = 0; i != nb_grp; i++) { + + /** + * Post process packets after crypto completion. + * Following operations would be done, + * + * Transmitting entity/UL: + * - Check crypto result + * + * Receiving entity/DL: + * - Check crypto operation status + * - Check for duplication (if yes, drop duplicate) + * - Perform decompressiondoc/guides/prog_guide/pdcp_lib.rst
Quoted 10 lines
doc/guides/prog_guide/pdcp_lib.rst new file +10
-0+ * - Trim PDCP header + * - Hold packet (SDU) for in-order delivery (return + * completed packets as and when sequence is + * completed) + * - If not in sequence, cache the packet and start + * t-Reordering timer. When timer expires, the + * packets need to delivered to upper layers (not + * treated as error packets). + */ + nb_success =rte_pdcp_pkt_post_process(grp[i].id.ptr,
Quoted 39 lines
doc/guides/prog_guide/pdcp_lib.rst new file +13
-0+ grp[i].m, out_mb, + grp[i].cnt, + &nb_err); + if (nb_err != 0) { + /* Handle error packets */ + } + + /* Perform additional operations */ + + /** + * Transmitting entity/UL + * - If duplication is enabled, duplicate PDCP PDUs + * - When lower layers confirm reception of a PDCPPDU,
doc/guides/prog_guide/pdcp_lib.rst new file +25
-0+ * it should be communicated to PDCP layer so that + * PDCP can drop the corresponding SDU + */ + } + } + + +Supported features +------------------ + +- 12 bit & 18 bit sequence numbers +- Uplink & downlink traffic +- HFN increment +- IV generation as required per algorithm + +Supported ciphering algorithms +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- NULL +- AES-CTR +- SNOW3G-CIPHER +- ZUC-CIPHER + +Supported integrity protection algorithms +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Quoted 8 lines
Quoted 6 lines
+
+- NULL +- AES-CMAC +- SNOW3G-AUTH +- ZUC-AUTH--
Move Supported features and algos after PDCP PDU explanation. Sample sequence should be in the end.
[Anoob] Agreed. Will make this change in next version.
PATCH v2 12/22 pdcp: add control PDU handling
In reply to Anoob JosephAdd control PDU handling and implement status report generation. Status report generation works only when RX_DELIV = RX_NEXT.
--- 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
app/test/test_pdcp.c +1 -0
@@ -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 ;
doc/guides/prog_guide/pdcp_lib.rst +10 -0
@@ -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 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
lib/pdcp/meson.build +2 -0
@@ -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', )
lib/pdcp/pdcp_cnt.c new file +29 -0
@@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2023 Marvell. +*/ + +#include <rte_pdcp.h> + +#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 ; +}
lib/pdcp/pdcp_cnt.h new file +14 -0
@@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2023 Marvell. +*/ + +#ifndef PDCP_CNT_H +#define PDCP_CNT_H + +#include <rte_common.h> + +#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 */
lib/pdcp/pdcp_ctrl_pdu.c new file +46 -0
46 lines not on this page · raw message
lib/pdcp/pdcp_ctrl_pdu.h new file +15 -0
@@ -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 <rte_mbuf.h> + +#include "pdcp_entity.h" + +int +pdcp_ctrl_pdu_status_gen (struct entity_priv *en_priv,struct rte_mbuf *m); + +#endif /* PDCP_CTRL_PDU_H */
lib/pdcp/pdcp_entity.h +13 -2
@@ -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 {
lib/pdcp/pdcp_process.c +13 -0
@@ -1157,6 +1157,19 @@ pdcp_entity_priv_populate(struct entity_priv *en_priv, const struct rte_pdcp_entif (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 *
lib/pdcp/rte_pdcp.c +46 -1
75 lines not on this page · raw message
lib/pdcp/rte_pdcp.h +31 -0
@@ -16,6 +16,7 @@#include <rte_compat.h> #include <rte_common.h> #include <rte_mempool.h> +#include <rte_pdcp_hdr.h> #include <rte_security.h> #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
lib/pdcp/version.map +2 -0
@@ -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;
Signature · 1 line
2.25.1
RE: [PATCH v2 12/22] pdcp: add control PDU handling
Quoted 9 lines
Subject: [PATCH v2 12/22] pdcp: add control PDU handling
Add control PDU handling and implement status report generation. Status report generation works only when
RX_DELIV=RX_NEXT.Signed-off-by Anoob Joseph <[email protected]>Signed-off-by Volodymyr Fialko <[email protected]>--- app/test/test_pdcp.c | 1 +
Separate out test app changes from library changes.
Quoted 45 lines
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.happ/test/test_pdcp.c +1
-0@@ -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 ;app/test/test_pdcp.c +0
-0conf->entity.pdcp_xfrm.remove_duplicates =0 ;doc/guides/prog_guide/pdcp_lib.rst +0
-0@@ -67,6 +67,15 @@ Data PDUs are regular packets submitted by upper layersfor transmission to
other end. Such packets would need to be ciphered and authenticated based on the entity configuration.doc/guides/prog_guide/pdcp_lib.rst +4
-0+PDCP packet processing API for control PDU +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Control PDUs are used in PDCP as a communication channel betweentransmitting
doc/guides/prog_guide/pdcp_lib.rst Data PDUs are regular packets submitted by upper layers for transmission to · line 77
Quoted 4 lines
doc/guides/prog_guide/pdcp_lib.rst +4
-0+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_ctrl_pdu_status_gen() - Is this a user visible API? I believe it is not exposed. How can application request that?
Quoted 17 lines
doc/guides/prog_guide/pdcp_lib.rst +2
-0+ 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 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~lib/pdcp/meson.build +0
-0
lib/pdcp/meson.build if is_windows · line 11
Quoted 4 lines
lib/pdcp/meson.build +1
-0@@ -8,7 +8,9 @@ if is_windows endif sources = files( + 'pdcp_cnt.c',
pdcp_cnt seems to be something related to count.
And it is not related to this patch probably.
Quoted 141 lines
lib/pdcp/meson.build +1
-0'pdcp_crypto.c', + 'pdcp_ctrl_pdu.c', 'pdcp_process.c', 'rte_pdcp.c', )lib/pdcp/pdcp_cnt.c new file +11
-0@@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2023 Marvell. +*/ + +#include <rte_pdcp.h> + +#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)lib/pdcp/pdcp_cnt.c new file +18
-0+{ +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 ; +}lib/pdcp/pdcp_cnt.h new file +12
-0@@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2023 Marvell. +*/ + +#ifndef PDCP_CNT_H +#define PDCP_CNT_H + +#include <rte_common.h> + +#include "pdcp_entity.h" + +int pdcp_cnt_ring_create(struct rte_pdcp_entity *en, const struct
rte_pdcp_entity_conf*conf);lib/pdcp/pdcp_cnt.h new file +2
-0+ +#endif /* PDCP_CNT_H */ lib/pdcp/pdcp_ctrl_pdu.c new file +37
-0@@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: BSD-3-Clause +* Copyright(C) 2023 Marvell. +*/ + +#include <rte_byteorder.h> +#include <rte_mbuf.h> +#include <rte_pdcp_hdr.h> + +#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);lib/pdcp/pdcp_ctrl_pdu.c new file +9
-0+if (pdu_hdr ==NULL ) +return -ENOMEM ; +pdcp_hdr_fill (pdu_hdr, rx_deliv); + +return 0 ; + } + +return -ENOTSUP ; +}lib/pdcp/pdcp_ctrl_pdu.h new file +15
-0@@ -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 <rte_mbuf.h> + +#include "pdcp_entity.h" + +int +pdcp_ctrl_pdu_status_gen (struct entity_priv *en_priv,struct rte_mbuf *m); + +#endif /* PDCP_CTRL_PDU_H */ lib/pdcp/pdcp_entity.h +0
-0
lib/pdcp/pdcp_entity.h union cipher_iv_partial { · line 117
Quoted 9 lines
lib/pdcp/pdcp_entity.h +6
-0@@ -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; +};
This pdcp_cnt_bitmap is not related to control PDU. Right? I believe the patch split is not proper here.
Quoted 111 lines
lib/pdcp/pdcp_entity.h +5
-0+/* * 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. */
lib/pdcp/pdcp_entity.h +0
-1@@ -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. */
lib/pdcp/pdcp_entity.h +1
-1-uint8_t dummy; +/** PDCP would need to track the count values that are already received.*/
lib/pdcp/pdcp_entity.h +1
-0+struct pdcp_cnt_bitmap bitmap; };struct entity_priv_ul_part {lib/pdcp/pdcp_process.c +13
-0@@ -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 ; + } +lib/pdcp/pdcp_process.c +0
-0/** * hdr_sz * lib/pdcp/rte_pdcp.c +3
-1@@ -6,7 +6,9 @@#include <rte_pdcp.h> #include <rte_malloc.h> +#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 ;lib/pdcp/rte_pdcp.c +1
-0return 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 */ lib/pdcp/rte_pdcp.c +4
-0ret =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:lib/pdcp/rte_pdcp.c +1
-0@@ -136,3 +143,41 @@ rte_pdcp_entity_suspend(struct rte_pdcp_entity *pdcp_entity, return 0; } +
lib/pdcp/rte_pdcp.c rte_pdcp_entity_suspend(struct rte_pdcp_entity · line 156
Quoted 10 lines
lib/pdcp/rte_pdcp.c +10
-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 ;
rte_errno should be positive values.
Quoted 40 lines
lib/pdcp/rte_pdcp.c +27
-0+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; +}lib/pdcp/rte_pdcp.h +1
-0@@ -16,6 +16,7 @@#include <rte_compat.h> #include <rte_common.h> #include <rte_mempool.h> +#include <rte_pdcp_hdr.h> #include <rte_security.h> #ifdef __cplusplus
lib/pdcp/rte_pdcp.h struct rte_pdcp_entity_conf { · line 83
Quoted 5 lines
lib/pdcp/rte_pdcp.h +2
-0@@ -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;
Please use same prefix for all control pdu stuff.
I see cnt, ctr, ctrl, control is being used.
I think "control" for top level API and "ctrl" for parameters should be fine.
Quoted 18 lines
lib/pdcp/rte_pdcp.h +0
-0/** * 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.
lib/pdcp/rte_pdcp.h +0
-0@@ -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.*/
lib/pdcp/rte_pdcp.h +4
-0bool 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
lib/pdcp/rte_pdcp.h +1
-0+* may request a receiving PDCP entity to generate a PDCP status report using
lib/pdcp/rte_pdcp.h +1
-0+* ``rte_pdcp_ctrl_pdu_create``. In addition, PDCP status reports may be generated during
lib/pdcp/rte_pdcp.h struct rte_pdcp_entity_conf { · line 105
Quoted 3 lines
lib/pdcp/rte_pdcp.h +3
-0+* operations such as entity re-establishment. +*/ +bool status_report_required;
rte_pdcp_ctrl_pdu_create -> rte_pdcp_control_pdu_create
Please specify that a PDU will be generated for status report. Otherwise, it seems some structure would be returned for status report But there is no mention of that. This will avoid confusion.
Quoted 44 lines
};
/* >8 End of structurerte_pdcp_entity_conf. */lib/pdcp/rte_pdcp.h +19
-0@@ -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 lib/pdcp/version.map +2
-1@@ -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; --2.25.1