File: ipsec_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 (346 lines) | stat: -rw-r--r-- 10,488 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
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
..  SPDX-License-Identifier: BSD-3-Clause
    Copyright(c) 2018-2020 Intel Corporation.

IPsec Packet Processing Library
===============================

DPDK provides a library for IPsec data-path processing.
The library utilizes the existing DPDK crypto-dev and
security API to provide the application with a transparent and
high performant IPsec packet processing API.
The library is concentrated on data-path protocols processing
(ESP and AH), IKE protocol(s) implementation is out of scope
for this library.

SA level API
------------

This API operates on the IPsec Security Association (SA) level.
It provides functionality that allows user for given SA to process
inbound and outbound IPsec packets.

To be more specific:

*  for inbound ESP/AH packets perform decryption, authentication, integrity checking, remove ESP/AH related headers
*  for outbound packets perform payload encryption, attach ICV, update/add IP headers, add ESP/AH headers/trailers,
*  setup related mbuf fields (ol_flags, tx_offloads, etc.).
*  initialize/un-initialize given SA based on user provided parameters.

The SA level API is based on top of crypto-dev/security API and relies on
them to perform actual cipher and integrity checking.

Due to the nature of the crypto-dev API (enqueue/dequeue model) the library
introduces an asynchronous API for IPsec packets destined to be processed by
the crypto-device.

The expected API call sequence for data-path processing would be:

.. code-block:: c

    /* enqueue for processing by crypto-device */
    rte_ipsec_pkt_crypto_prepare(...);
    rte_cryptodev_enqueue_burst(...);
    /* dequeue from crypto-device and do final processing (if any) */
    rte_cryptodev_dequeue_burst(...);
    rte_ipsec_pkt_crypto_group(...); /* optional */
    rte_ipsec_pkt_process(...);

For packets destined for inline processing no extra overhead
is required and the synchronous API call: rte_ipsec_pkt_process()
is sufficient for that case.

.. note::

    For more details about the IPsec API, please refer to the *DPDK API Reference*.

The current implementation supports all four currently defined
rte_security types:

RTE_SECURITY_ACTION_TYPE_NONE
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In that mode the library functions perform

* for inbound packets:

  - check SQN
  - prepare *rte_crypto_op* structure for each input packet
  - verify that integrity check and decryption performed by crypto device
    completed successfully
  - check padding data
  - remove outer IP header (tunnel mode) / update IP header (transport mode)
  - remove ESP header and trailer, padding, IV and ICV data
  - update SA replay window

* for outbound packets:

  - generate SQN and IV
  - add outer IP header (tunnel mode) / update IP header (transport mode)
  - add ESP header and trailer, padding and IV data
  - prepare *rte_crypto_op* structure for each input packet
  - verify that crypto device operations (encryption, ICV generation)
    were completed successfully

RTE_SECURITY_ACTION_TYPE_CPU_CRYPTO
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In that mode the library functions perform same operations as in
``RTE_SECURITY_ACTION_TYPE_NONE``. The only difference is that crypto operations
are performed with CPU crypto synchronous API.


RTE_SECURITY_ACTION_TYPE_INLINE_CRYPTO
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In that mode the library functions perform

* for inbound packets:

  - verify that integrity check and decryption performed by *rte_security*
    device completed successfully
  - check SQN
  - check padding data
  - remove outer IP header (tunnel mode) / update IP header (transport mode)
  - remove ESP header and trailer, padding, IV and ICV data
  - update SA replay window

* for outbound packets:

  - generate SQN and IV
  - add outer IP header (tunnel mode) / update IP header (transport mode)
  - add ESP header and trailer, padding and IV data
  - update *ol_flags* inside *struct  rte_mbuf* to indicate that
    inline-crypto processing has to be performed by HW on this packet
  - invoke *rte_security* device specific *set_pkt_metadata()* to associate
    security device specific data with the packet

RTE_SECURITY_ACTION_TYPE_INLINE_PROTOCOL
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In that mode the library functions perform

* for inbound packets:

  - verify that integrity check and decryption performed by *rte_security*
    device completed successfully

* for outbound packets:

  - update *ol_flags* inside *struct  rte_mbuf* to indicate that
    inline-crypto processing has to be performed by HW on this packet
  - invoke *rte_security* device specific *set_pkt_metadata()* to associate
    security device specific data with the packet

RTE_SECURITY_ACTION_TYPE_LOOKASIDE_PROTOCOL
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In that mode the library functions perform

* for inbound packets:

  - prepare *rte_crypto_op* structure for each input packet
  - verify that integrity check and decryption performed by crypto device
    completed successfully

* for outbound packets:

  - prepare *rte_crypto_op* structure for each input packet
  - verify that crypto device operations (encryption, ICV generation)
    were completed successfully

To accommodate future custom implementations function pointers
model is used for both *crypto_prepare* and *process* implementations.

SA database API
----------------

SA database(SAD) is a table with <key, value> pairs.

Value is an opaque user provided pointer to the user defined SA data structure.

According to RFC4301 each SA can be uniquely identified by a key
which is either:

  - security parameter index(SPI)
  - or SPI and destination IP(DIP)
  - or SPI, DIP and source IP(SIP)

In case of multiple matches, longest matching key will be returned.

Create/destroy
~~~~~~~~~~~~~~

librte_ipsec SAD implementation provides ability to create/destroy SAD tables.

To create SAD table user has to specify how many entries of each key type is
required and IP protocol type (IPv4/IPv6).
As an example:


.. code-block:: c

    struct rte_ipsec_sad *sad;
    struct rte_ipsec_sad_conf conf;

    conf.socket_id = -1;
    conf.max_sa[RTE_IPSEC_SAD_SPI_ONLY] = some_nb_rules_spi_only;
    conf.max_sa[RTE_IPSEC_SAD_SPI_DIP] = some_nb_rules_spi_dip;
    conf.max_sa[RTE_IPSEC_SAD_SPI_DIP_SIP] = some_nb_rules_spi_dip_sip;
    conf.flags = RTE_IPSEC_SAD_FLAG_RW_CONCURRENCY;

    sad = rte_ipsec_sad_create("test", &conf);

.. note::

    for more information please refer to ipsec library API reference

Add/delete rules
~~~~~~~~~~~~~~~~

Library also provides methods to add or delete key/value pairs from the SAD.
To add user has to specify key, key type and a value which is an opaque pointer to SA.
The key type reflects a set of tuple fields that will be used for lookup of the SA.
As mentioned above there are 3 types of a key and the representation of a key type is:

.. code-block:: c

        RTE_IPSEC_SAD_SPI_ONLY,
        RTE_IPSEC_SAD_SPI_DIP,
        RTE_IPSEC_SAD_SPI_DIP_SIP,

As an example, to add new entry into the SAD for IPv4 addresses:

.. code-block:: c

    struct rte_ipsec_sa *sa;
    union rte_ipsec_sad_key key;

    key.v4.spi = rte_cpu_to_be_32(spi_val);
    if (key_type >= RTE_IPSEC_SAD_SPI_DIP) /* DIP is optional*/
        key.v4.dip = rte_cpu_to_be_32(dip_val);
    if (key_type == RTE_IPSEC_SAD_SPI_DIP_SIP) /* SIP is optional*/
        key.v4.sip = rte_cpu_to_be_32(sip_val);

    rte_ipsec_sad_add(sad, &key, key_type, sa);

.. note::

    By performance reason it is better to keep spi/dip/sip in net byte order
    to eliminate byteswap on lookup

To delete user has to specify key and key type.

Delete code would look like:

.. code-block:: c

    union rte_ipsec_sad_key key;

    key.v4.spi = rte_cpu_to_be_32(necessary_spi);
    if (key_type >= RTE_IPSEC_SAD_SPI_DIP) /* DIP is optional*/
        key.v4.dip = rte_cpu_to_be_32(necessary_dip);
    if (key_type == RTE_IPSEC_SAD_SPI_DIP_SIP) /* SIP is optional*/
        key.v4.sip = rte_cpu_to_be_32(necessary_sip);

    rte_ipsec_sad_del(sad, &key, key_type);


Lookup
~~~~~~
Library provides lookup by the given {SPI,DIP,SIP} tuple of
inbound ipsec packet as a key.

The search key is represented by:

.. code-block:: c

    union rte_ipsec_sad_key {
        struct rte_ipsec_sadv4_key  v4;
        struct rte_ipsec_sadv6_key  v6;
    };

where v4 is a tuple for IPv4:

.. code-block:: c

    struct rte_ipsec_sadv4_key {
        uint32_t spi;
        uint32_t dip;
        uint32_t sip;
    };

and v6 is a tuple for IPv6:

.. code-block:: c

    struct rte_ipsec_sadv6_key {
        uint32_t spi;
        struct rte_ipv6_addr dip;
        struct rte_ipv6_addr sip;
    };

As an example, lookup related code could look like that:

.. code-block:: c

    int i;
    union rte_ipsec_sad_key keys[BURST_SZ];
    const union rte_ipsec_sad_key *keys_p[BURST_SZ];
    void *vals[BURST_SZ];

    for (i = 0; i < BURST_SZ_MAX; i++) {
        keys[i].v4.spi = esp_hdr[i]->spi;
        keys[i].v4.dip = ipv4_hdr[i]->dst_addr;
        keys[i].v4.sip = ipv4_hdr[i]->src_addr;
        keys_p[i] = &keys[i];
    }
    rte_ipsec_sad_lookup(sad, keys_p, vals, BURST_SZ);

    for (i = 0; i < BURST_SZ_MAX; i++) {
        if (vals[i] == NULL)
            printf("SA not found for key index %d\n", i);
        else
            printf("SA pointer is %p\n", vals[i]);
    }


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

*  ESP protocol tunnel mode both IPv4/IPv6.

*  ESP protocol transport mode both IPv4/IPv6.

*  ESN and replay window.

*  NAT-T / UDP encapsulated ESP.

*  TSO (only for inline crypto mode)

*  algorithms: 3DES-CBC, AES-CBC, AES-CTR, AES-GCM, AES_CCM, CHACHA20_POLY1305,
   AES_GMAC, HMAC-SHA1, NULL.


Telemetry support
------------------

Telemetry support implements SA details and IPsec packet add data counters
statistics. Per SA telemetry statistics can be enabled using
``rte_ipsec_telemetry_sa_add`` and disabled using
``rte_ipsec_telemetry_sa_del``. Note that these calls are not thread safe.

Stateless IPsec packet processing
---------------------------------

Support for stateless IPsec packet processing allows use of custom
sequence number to be used for IPsec outbound processing.

``rte_ipsec_pkt_stateless_prepare()`` takes as input the state parameter
from the application and prepares the packet for IPsec processing.

Limitations
-----------

The following features are not properly supported in the current version:

*  Hard/soft limit for SA lifetime (time interval/byte count).