File: pdcp_lib.rst

package info (click to toggle)
dpdk 24.11.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 121,148 kB
  • sloc: ansic: 2,206,055; python: 11,866; sh: 4,627; makefile: 2,025; awk: 70
file content (299 lines) | stat: -rw-r--r-- 10,013 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
..  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>`_

PDCP would involve the following operations:

#. Transfer of user plane data
#. Transfer of control plane data
#. Header compression
#. Uplink data compression
#. Ciphering and integrity protection

.. _figure_pdcp_functional_overview:

.. figure:: img/pdcp_functional_overview.*

   PDCP functional overview

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
---------------

PDCP library provides following control path API that is used to
configure various PDCP entities:

- ``rte_pdcp_entity_establish()``
- ``rte_pdcp_entity_suspend()``
- ``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.

When upper layers request a PDCP entity suspend (``rte_pdcp_entity_suspend()``),
it would result in flushing out of all cached packets and
internal state variables are updated as described in 5.1.4.

When upper layers request a PDCP entity release (``rte_pdcp_entity_release()``),
it would result in flushing out of all cached packets
and releasing of all memory associated with the entity.
It would internally free any crypto/security sessions created.
All procedures mentioned in 5.1.3 would be performed.

PDCP PDU (Protocol Data Unit) API
---------------------------------

PDCP PDUs can be categorized as:

- Control PDU
- Data PDU

Control PDUs are used for signalling between entities on either end
and can be one of the following:

- PDCP status report
- ROHC feedback
- 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.

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 as re-establishment,
receiving PDCP entity need to prepare a status report
and send it to the other end.
The API ``rte_pdcp_control_pdu_create()`` allows application to request the same.

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 ``rte_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.

Supported features
------------------

- 12-bit & 18-bit sequence numbers
- Uplink & downlink traffic
- HFN increment
- IV generation as required per algorithm

Supported ciphering algorithms
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

- ``RTE_CRYPTO_CIPHER_NULL``
- ``RTE_CRYPTO_CIPHER_AES_CTR``
- ``RTE_CRYPTO_CIPHER_SNOW3G_UEA2``
- ``RTE_CRYPTO_CIPHER_ZUC_EEA3``

Supported integrity protection algorithms
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

- ``RTE_CRYPTO_AUTH_NULL``
- ``RTE_CRYPTO_AUTH_AES_CMAC``
- ``RTE_CRYPTO_AUTH_SNOW3G_UIA2``
- ``RTE_CRYPTO_AUTH_ZUC_EIA3``

Timers
------

PDCP utilizes a reception window mechanism to limit the bits of ``COUNT`` value
transmitted in the packet.
It utilizes state variables such as ``RX_REORD``, ``RX_DELIV``
to define the window and uses ``RX_DELIV`` as the lower pivot point of the window.

``RX_DELIV`` would be updated only when packets are received in-order.
Any missing packet would mean ``RX_DELIV`` won't be updated.
A timer, ``t-Reordering``, helps PDCP to slide the window
if the missing packet is not received in a specified time duration.

While starting and stopping the timer will be done by lib PDCP,
application could register its own timer implementation.
This is to make sure application can choose between timers
such as ``rte_timer`` and ``rte_event`` based timers.
Starting and stopping of timer would happen during pre & post process API.

When the ``t-Reordering`` timer expires, application would receive the expiry event.
To perform the PDCP handling of the expiry event,
``rte_pdcp_t_reordering_expiry_handle`` can be used.
Expiry handling would involve sliding the window by updating state variables
and passing the expired packets to the application.

.. literalinclude:: ../../../lib/pdcp/rte_pdcp.h
   :language: c
   :start-after: Structure rte_pdcp_t_reordering 8<
   :end-before: >8 End of structure rte_pdcp_t_reordering.

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 be 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 */
		}

		...

		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 PDCP PDU,
			 *   it should be communicated to PDCP layer so that
			 *   PDCP can drop the corresponding SDU
			 */
		}
	}