xref: /dpdk/doc/guides/prog_guide/pdcp_lib.rst (revision f381ac0f35944c997784753d43eebc8cdf4ddc50)
1..  SPDX-License-Identifier: BSD-3-Clause
2    Copyright(C) 2023 Marvell.
3
4PDCP Protocol Processing Library
5================================
6
7DPDK provides a library for PDCP protocol processing.
8The library utilizes other DPDK libraries such as cryptodev, reorder, etc.,
9to provide the application with a transparent and
10high performant PDCP protocol processing library.
11
12The library abstracts complete PDCP protocol processing conforming to
13`ETSI TS 138 323 V17.1.0 (2022-08)
14<https://www.etsi.org/deliver/etsi_ts/138300_138399/138323/17.01.00_60/ts_138323v170100p.pdf>`_
15
16PDCP would involve the following operations:
17
18#. Transfer of user plane data
19#. Transfer of control plane data
20#. Header compression
21#. Uplink data compression
22#. Ciphering and integrity protection
23
24.. _figure_pdcp_functional_overview:
25
26.. figure:: img/pdcp_functional_overview.*
27
28   PDCP functional overview
29
30PDCP library would abstract the protocol offload features of the cryptodev and
31would provide a uniform interface and consistent API usage
32to work with cryptodev irrespective of the protocol offload features supported.
33
34PDCP entity API
35---------------
36
37PDCP library provides following control path API that is used to
38configure various PDCP entities:
39
40- ``rte_pdcp_entity_establish()``
41- ``rte_pdcp_entity_suspend()``
42- ``rte_pdcp_entity_release()``
43
44A PDCP entity would translate to one ``rte_cryptodev_sym_session`` or
45``rte_security_session`` based on the config.
46The sessions would be created/destroyed
47while corresponding PDCP entity operations are performed.
48
49When upper layers request a PDCP entity suspend (``rte_pdcp_entity_suspend()``),
50it would result in flushing out of all cached packets and
51internal state variables are updated as described in 5.1.4.
52
53When upper layers request a PDCP entity release (``rte_pdcp_entity_release()``),
54it would result in flushing out of all cached packets
55and releasing of all memory associated with the entity.
56It would internally free any crypto/security sessions created.
57All procedures mentioned in 5.1.3 would be performed.
58
59PDCP PDU (Protocol Data Unit) API
60---------------------------------
61
62PDCP PDUs can be categorized as:
63
64- Control PDU
65- Data PDU
66
67Control PDUs are used for signalling between entities on either end
68and can be one of the following:
69
70- PDCP status report
71- ROHC feedback
72- EHC feedback
73
74Control PDUs are not ciphered or authenticated,
75and so such packets are not submitted to cryptodev for processing.
76
77Data PDUs are regular packets submitted by upper layers
78for transmission to other end.
79Such packets would need to be ciphered and authenticated
80based on the entity configuration.
81
82PDCP packet processing API for control PDU
83~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
84
85Control PDUs are used in PDCP as a communication channel
86between transmitting and receiving entities.
87When upper layer request for operations such as re-establishment,
88receiving PDCP entity need to prepare a status report
89and send it to the other end.
90The API ``rte_pdcp_control_pdu_create()`` allows application to request the same.
91
92PDCP packet processing API for data PDU
93~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
94
95PDCP processing is split into 2 parts.
96One before cryptodev processing (``rte_pdcp_pkt_pre_process()``)
97and one after cryptodev processing (``rte_pdcp_pkt_post_process()``).
98Since cryptodev dequeue can return crypto operations
99belonging to multiple entities, ``rte_pdcp_pkt_crypto_group()``
100is added to help grouping crypto operations belonging to same PDCP entity.
101
102Lib PDCP would allow application to use same API sequence
103while leveraging protocol offload features enabled by ``rte_security`` library.
104
105Lib PDCP would internally change the handles registered
106for ``pre_process`` and ``post_process`` based on features enabled in the entity.
107
108Lib PDCP would create the required sessions on the device
109provided in entity to minimize the application requirements.
110Also, the ``rte_crypto_op`` allocation and free would also be done internally
111by lib PDCP to allow the library to create crypto ops as required for the input packets.
112For example, when control PDUs are received, no cryptodev enqueue-dequeue is expected
113for the same and lib PDCP is expected to handle it differently.
114
115Supported features
116------------------
117
118- 12-bit & 18-bit sequence numbers
119- Uplink & downlink traffic
120- HFN increment
121- IV generation as required per algorithm
122
123Supported ciphering algorithms
124~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
125
126- ``RTE_CRYPTO_CIPHER_NULL``
127- ``RTE_CRYPTO_CIPHER_AES_CTR``
128- ``RTE_CRYPTO_CIPHER_SNOW3G_UEA2``
129- ``RTE_CRYPTO_CIPHER_ZUC_EEA3``
130
131Supported integrity protection algorithms
132~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
133
134- ``RTE_CRYPTO_AUTH_NULL``
135- ``RTE_CRYPTO_AUTH_AES_CMAC``
136- ``RTE_CRYPTO_AUTH_SNOW3G_UIA2``
137- ``RTE_CRYPTO_AUTH_ZUC_EIA3``
138
139Timers
140------
141
142PDCP utilizes a reception window mechanism to limit the bits of ``COUNT`` value
143transmitted in the packet.
144It utilizes state variables such as ``RX_REORD``, ``RX_DELIV``
145to define the window and uses ``RX_DELIV`` as the lower pivot point of the window.
146
147``RX_DELIV`` would be updated only when packets are received in-order.
148Any missing packet would mean ``RX_DELIV`` won't be updated.
149A timer, ``t-Reordering``, helps PDCP to slide the window
150if the missing packet is not received in a specified time duration.
151
152While starting and stopping the timer will be done by lib PDCP,
153application could register its own timer implementation.
154This is to make sure application can choose between timers
155such as ``rte_timer`` and ``rte_event`` based timers.
156Starting and stopping of timer would happen during pre & post process API.
157
158When the ``t-Reordering`` timer expires, application would receive the expiry event.
159To perform the PDCP handling of the expiry event,
160``rte_pdcp_t_reordering_expiry_handle`` can be used.
161Expiry handling would involve sliding the window by updating state variables
162and passing the expired packets to the application.
163
164.. literalinclude:: ../../../lib/pdcp/rte_pdcp.h
165   :language: c
166   :start-after: Structure rte_pdcp_t_reordering 8<
167   :end-before: >8 End of structure rte_pdcp_t_reordering.
168
169Sample API usage
170----------------
171
172The ``rte_pdcp_entity_conf`` structure is used to pass
173the configuration parameters for entity creation.
174
175.. literalinclude:: ../../../lib/pdcp/rte_pdcp.h
176   :language: c
177   :start-after: Structure rte_pdcp_entity_conf 8<
178   :end-before: >8 End of structure rte_pdcp_entity_conf.
179
180.. code-block:: c
181
182	struct rte_mbuf **out_mb, *pkts[MAX_BURST_SIZE];
183	struct rte_crypto_op *cop[MAX_BURST_SIZE];
184	struct rte_pdcp_group grp[MAX_BURST_SIZE];
185	struct rte_pdcp_entity *pdcp_entity;
186	int nb_max_out_mb, ret, nb_grp;
187	uint16_t nb_ops;
188
189	/* Create PDCP entity */
190	pdcp_entity = rte_pdcp_entity_establish(&conf);
191
192	/**
193	 * Allocate buffer for holding mbufs returned during PDCP suspend,
194	 * release & post-process APIs.
195	 */
196
197	/* Max packets that can be cached in entity + burst size */
198	nb_max_out_mb = pdcp_entity->max_pkt_cache + MAX_BURST_SIZE;
199	out_mb = rte_malloc(NULL, nb_max_out_mb * sizeof(uintptr_t), 0);
200	if (out_mb == NULL) {
201		/* Handle error */
202	}
203
204	while (1) {
205		/* Receive packet and form mbuf */
206
207		/**
208		 * Prepare packets for crypto operation.
209		 * Following operations would be done,
210		 *
211		 * Transmitting entity/UL (only data PDUs):
212		 *  - Perform compression
213		 *  - Assign sequence number
214		 *  - Add PDCP header
215		 *  - Create & prepare crypto_op
216		 *  - Prepare IV for crypto operation (auth_gen, encrypt)
217		 *  - Save original PDCP SDU (during PDCP re-establishment,
218		 *    unconfirmed PDCP SDUs need to be crypto processed again and
219		 *    transmitted/re-transmitted)
220		 *
221		 *  Receiving entity/DL:
222		 *  - Any control PDUs received would be processed and
223		 *    appropriate actions taken. If data PDU, continue.
224		 *  - Determine sequence number (based on HFN & per packet SN)
225		 *  - Prepare crypto_op
226		 *  - Prepare IV for crypto operation (decrypt, auth_verify)
227		 */
228		nb_success = rte_pdcp_pkt_pre_process(pdcp_entity, pkts, cop,
229						      nb_rx, &nb_err);
230		if (nb_err != 0) {
231			/* Handle error packets */
232		}
233
234		if ((rte_cryptodev_enqueue_burst(dev_id, qp_id, cop, nb_success)
235				!= nb_success) {
236			/* Retry for enqueue failure packets */
237		}
238
239		...
240
241		nb_ops = rte_cryptodev_dequeue_burst(dev_id, qp_id, cop,
242						  MAX_BURST_SIZE);
243		if (nb_ops == 0)
244			continue;
245
246		/**
247		 * Received a burst of completed crypto ops from cryptodev. It
248		 * may belong to various entities. Group similar ones together
249		 * for entity specific post-processing.
250		 */
251
252		/**
253		 * Groups similar entities together. Frees crypto op and based
254		 * on crypto_op status, set mbuf->ol_flags which would be
255		 * checked in rte_pdcp_pkt_post_process().
256		 */
257		nb_grp = rte_pdcp_pkt_crypto_group(cop, pkts, grp, ret);
258
259		for (i = 0; i != nb_grp; i++) {
260
261			/**
262			 * Post process packets after crypto completion.
263			 * Following operations would be done,
264			 *
265			 *  Transmitting entity/UL:
266			 *  - Check crypto result
267			 *
268			 *  Receiving entity/DL:
269			 *  - Check crypto operation status
270			 *  - Check for duplication (if yes, drop duplicate)
271			 *  - Perform decompression
272			 *  - Trim PDCP header
273			 *  - Hold packet (SDU) for in-order delivery (return
274			 *    completed packets as and when sequence is
275			 *    completed)
276			 *  - If not in sequence, cache the packet and start
277			 *    t-Reordering timer. When timer expires, the
278			 *    packets need to delivered to upper layers (not
279			 *    treated as error packets).
280			 */
281			nb_success = rte_pdcp_pkt_post_process(grp[i].id.ptr,
282							       grp[i].m, out_mb,
283							       grp[i].cnt,
284							       &nb_err);
285			if (nb_err != 0) {
286				/* Handle error packets */
287			}
288
289			/* Perform additional operations */
290
291			/**
292			 * Transmitting entity/UL
293			 * - If duplication is enabled, duplicate PDCP PDUs
294			 * - When lower layers confirm reception of a PDCP PDU,
295			 *   it should be communicated to PDCP layer so that
296			 *   PDCP can drop the corresponding SDU
297			 */
298		}
299	}
300