aboutsummaryrefslogtreecommitdiff
path: root/include/odp/api/spec/ipsec.h
blob: 6e28e7fb4cc72576e52cf1fe030d2b74cdd1c989 (plain)
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
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
/* Copyright (c) 2016-2018, Linaro Limited
 * Copyright (c) 2021, Nokia
 * All rights reserved.
 *
 * SPDX-License-Identifier:     BSD-3-Clause
 */

/**
 * @file
 *
 * ODP IPSEC API
 */

#ifndef ODP_API_SPEC_IPSEC_H_
#define ODP_API_SPEC_IPSEC_H_
#include <odp/visibility_begin.h>

#ifdef __cplusplus
extern "C" {
#endif

#include <odp/api/crypto.h>
#include <odp/api/std_types.h>
#include <odp/api/packet_io.h>
#include <odp/api/protocols.h>
#include <odp/api/classification.h>
#include <odp/api/traffic_mngr.h>

/** @defgroup odp_ipsec ODP IPSEC
 *  IPSEC protocol offload.
 *  @{
 */

/**
 * @typedef odp_ipsec_sa_t
 * IPSEC Security Association (SA)
 */

 /**
 * @def ODP_IPSEC_SA_INVALID
 * Invalid IPSEC SA
 */

/**
 * IPSEC operation mode
 */
typedef enum odp_ipsec_op_mode_t {
	/** Synchronous IPSEC operation
	  *
	  * Application uses synchronous IPSEC operations,
	  * which output all results on function return.
	  */
	ODP_IPSEC_OP_MODE_SYNC = 0,

	/** Asynchronous IPSEC operation
	  *
	  * Application uses asynchronous IPSEC operations,
	  * which return results via events.
	  */
	ODP_IPSEC_OP_MODE_ASYNC,

	/** Inline IPSEC operation
	  *
	  * Packet input/output is connected directly to IPSEC inbound/outbound
	  * processing. Application uses asynchronous or inline IPSEC
	  * operations.
	  *
	  * Inline processed inbound packets are delivered to the application
	  * in the same way as packets processed by odp_ipsec_in_enq().
	  */
	ODP_IPSEC_OP_MODE_INLINE,

	/** IPSEC is disabled in inbound / outbound direction */
	ODP_IPSEC_OP_MODE_DISABLED

} odp_ipsec_op_mode_t;

/**
 * IPSEC TEST SA operation
 */
typedef enum odp_ipsec_test_sa_operation_t {
	/** Update next sequence number
	 *
	 * The seq_num parameter is an outbound SA specific parameter.
	 * Invoking the odp_ipsec_test_sa_update() API to update this
	 * field on an inbound SA will cause the API to return failure.
	 */
	ODP_IPSEC_TEST_SA_UPDATE_SEQ_NUM = 0,

	/** Update highest authenticated sequence number
	 *
	 * The antireplay_window_top parameter is inbound SA specific.
	 * Invoking the odp_ipsec_test_sa_update() API to update this
	 * field on an outbound SA will cause the API to return failure.
	 */
	ODP_IPSEC_TEST_SA_UPDATE_ANTIREPLAY_WINDOW_TOP

} odp_ipsec_test_sa_operation_t;

/**
 * IPSEC TEST SA parameter
 */
typedef union odp_ipsec_test_sa_param_t {
	/** Next sequence number
	 *
	 * @see ODP_IPSEC_TEST_SA_UPDATE_SEQ_NUM
	 */
	uint64_t seq_num;

	/** Highest authenticated sequence number
	 *
	 * @see ODP_IPSEC_TEST_SA_UPDATE_ANTIREPLAY_WINDOW_TOP
	 */
	uint64_t antireplay_window_top;

} odp_ipsec_test_sa_param_t;

/**
 * Configuration options for IPSEC inbound processing
 */
typedef struct odp_ipsec_inbound_config_t {
	/** Default destination queue for IPSEC events
	 *
	 *  When inbound SA lookup fails in the asynchronous mode,
	 *  resulting IPSEC events are enqueued into this queue.
	 */
	odp_queue_t default_queue;

	/** Constraints for SPI values used with inbound SA lookup. Minimal
	 *  SPI range and unique values may improve performance. */
	struct {
		/** Minimum SPI value for SA lookup. Default value is 0. */
		uint32_t min_spi;

		/** Maximum SPI value for SA lookup. Default value is
		 *  UINT32_MAX. */
		uint32_t max_spi;

		/** Select if SPI values for SA lookup are unique or may contain
		 *  the same SPI value multiple times. The default value is 0.
		 *
		 *  0: All SAs in SA lookup have unique SPI value
		 *  1: The same SPI value may be used for multiple SAs
		 */
		odp_bool_t spi_overlap;

	} lookup;

	/** Retain outer headers
	 *
	 *  Select up to which protocol layer (at least) outer headers are
	 *  retained in inbound inline processing. Default value is
	 *  ODP_PROTO_LAYER_NONE.
	 *
	 *  ODP_PROTO_LAYER_NONE: Application does not require any outer
	 *                        headers to be retained.
	 *
	 *  ODP_PROTO_LAYER_L2:   Retain headers up to layer 2.
	 *
	 *  ODP_PROTO_LAYER_L3:   Retain headers up to layer 3, otherwise the
	 *                        same as ODP_PROTO_LAYER_ALL.
	 *
	 *  ODP_PROTO_LAYER_L4:   Retain headers up to layer 4, otherwise the
	 *                        same as ODP_PROTO_LAYER_ALL.
	 *
	 *  ODP_PROTO_LAYER_ALL:  In tunnel mode, all headers before IPSEC are
	 *                        retained. In transport mode, all headers
	 *                        before IP (carrying IPSEC) are retained.
	 *
	 */
	odp_proto_layer_t retain_outer;

	/** Parse packet headers after IPSEC transformation
	 *
	 *  Select header parsing level after inbound processing. Headers of the
	 *  resulting packet must be checked (at least) up to this level.
	 *  Parsing starts from IP (layer 3). Packet metadata from IP to this
	 *  layer is set. In addition, offset (and pointer) to the next layer
	 *  is set. Other layer/protocol specific metadata have undefined
	 *  values.
	 *
	 *  Each successfully transformed packet has a valid value for L3 offset
	 *  regardless of the parse configuration. Default value is
	 *  ODP_PROTO_LAYER_NONE. ODP_PROTO_LAYER_L2 is not a valid value.
	 */
	odp_proto_layer_t parse_level;

	/** Flags to control IPSEC payload data checks up to the selected parse
	 *  level. Checksum checking status can be queried for each packet with
	 *  odp_packet_l3_chksum_status() and odp_packet_l4_chksum_status().
	 *  Default value for all bits is 0 (skip all checksum checks).
	 */
	odp_proto_chksums_t chksums;

	/** Post-IPsec reassembly configuration
	 *
	 *  This field provides global IPsec configuration parameters for
	 *  fragment reassembly. The enable flag does not turn on reassembly
	 *  but tells if reassembly may be enabled in SA parameters.
	 *
	 *  The enable flag may be set only if retain_outer is
	 *  ODP_PROTO_LAYER_NONE.
	 */
	odp_reass_config_t reassembly;

	/** Attempt reassembly after inbound IPsec processing in
	 *  odp_ipsec_in_enq(). Default value is false.
	 */
	odp_bool_t reass_async;

	/** Attempt reassembly after inline inbound IPsec processing.
	 *  Default value is false.
	 **/
	odp_bool_t reass_inline;

} odp_ipsec_inbound_config_t;

/**
 * Configuration options for IPSEC outbound processing
 */
typedef struct odp_ipsec_outbound_config_t {
	/** Flags to control L3/L4 checksum insertion as part of outbound
	 *  packet processing. These flags control checksum insertion (for the
	 *  payload packet) in the same way as the checksum flags in
	 *  odp_pktout_config_opt_t control checksum insertion when sending
	 *  packets out through a pktio interface. Also packet checksum override
	 *  functions (e.g. odp_packet_l4_chksum_insert()) can be used in
	 *  the same way.
	 */
	union {
		/** Mapping for individual bits */
		struct {
			/** Insert IPv4 header checksum on the payload packet
			 *  before IPSEC transformation. Default value is 0. */
			uint32_t inner_ipv4   : 1;

			/** Insert UDP header checksum on the payload packet
			 *  before IPSEC transformation. Default value is 0. */
			uint32_t inner_udp    : 1;

			/** Insert TCP header checksum on the payload packet
			 *  before IPSEC transformation. Default value is 0. */
			uint32_t inner_tcp    : 1;

			/** Insert SCTP header checksum on the payload packet
			 *  before IPSEC transformation. Default value is 0. */
			uint32_t inner_sctp   : 1;

		} chksum;

		/** All bits of the bit field structure
		  *
		  * This field can be used to set/clear all flags, or bitwise
		  * operations over the entire structure. */
		uint32_t all_chksum;
	};

} odp_ipsec_outbound_config_t;

/**
 * IPSEC TEST capability
 */
typedef struct odp_ipsec_test_capability_t {
	/** Parameters supported for sa_update */
	struct {
		/** Next sequence number value
		 *
		 * @see ODP_IPSEC_TEST_SA_UPDATE_SEQ_NUM
		 */
		odp_bool_t seq_num;

		/** Highest authenticated sequence number
		 *
		 * @see ODP_IPSEC_TEST_SA_UPDATE_ANTIREPLAY_WINDOW_TOP
		 */
		odp_bool_t antireplay_window_top;

	} sa_operations;

} odp_ipsec_test_capability_t;

/**
 * IPSEC capability
 */
typedef struct odp_ipsec_capability_t {
	/** Maximum number of IPSEC SAs */
	uint32_t max_num_sa;

	/** Synchronous IPSEC operation mode (ODP_IPSEC_OP_MODE_SYNC) support */
	odp_support_t op_mode_sync;

	/**
	 * Asynchronous IPSEC operation mode (ODP_IPSEC_OP_MODE_ASYNC) support
	 */
	odp_support_t op_mode_async;

	/**
	 * Inline inbound IPSEC operation mode (ODP_IPSEC_OP_MODE_INLINE)
	 * support
	 */
	odp_support_t op_mode_inline_in;

	/**
	 * Inline outgoing IPSEC operation mode (ODP_IPSEC_OP_MODE_INLINE)
	 * support
	 */
	odp_support_t op_mode_inline_out;

	/** IP Authenticated Header (ODP_IPSEC_AH) support */
	odp_support_t proto_ah;

	/** Fragment after IPsec support */
	odp_support_t frag_after;

	/** Fragment before IPsec support */
	odp_support_t frag_before;

	/**
	 * Support of pipelined classification (ODP_IPSEC_PIPELINE_CLS) of
	 *  resulting inbound packets
	 */
	odp_support_t pipeline_cls;

	/**
	 * Support of retaining outer headers (retain_outer) in inbound inline
	 * processed packets
	 */
	odp_support_t retain_header;

	/**
	 * Inner packet checksum check offload support in inbound direction.
	 */
	odp_proto_chksums_t chksums_in;

	/** Maximum number of different destination CoSes in classification
	 *  pipelining. The same CoS may be used for many SAs. This is equal or
	 *  less than 'max_cos' capability in classifier API.
	 */
	uint32_t max_cls_cos;

	/**
	 * Scheduled queue support
	 *
	 * 0: Scheduled queues are not supported either as IPsec SA destination
	 *    queues or as IPsec default queue
	 * 1: Scheduled queues are supported as both IPsec SA destination queues
	 *    and IPsec default queue
	 * @see odp_ipsec_sa_param_t
	 */
	odp_bool_t queue_type_sched;

	/**
	 * Plain queue support
	 *
	 * 0: Plain queues are not supported either as IPsec SA destination
	 *    queues or as IPsec default queue
	 * 1: Plain queues are supported as both IPsec SA destination queues and
	 *    IPsec default queue
	 * @see odp_ipsec_sa_param_t
	 */
	odp_bool_t queue_type_plain;

	/** Maximum number of different destination queues. The same queue may
	 *  be used for many SAs. */
	uint32_t max_queues;

	/** Maximum anti-replay window size. */
	uint32_t max_antireplay_ws;

	/** Supported cipher algorithms */
	odp_crypto_cipher_algos_t ciphers;

	/** Supported authentication algorithms */
	odp_crypto_auth_algos_t   auths;

	/** Support of traffic manager (TM) after inline outbound IPSEC
	 *  processing. On unsupported platforms, application is not allowed
	 *  to use a TM enabled pktio (ODP_PKTOUT_MODE_TM) with outbound
	 *  inline IPSEC.
	 *
	 *  @see odp_pktio_open(), odp_pktio_param_t
	 */
	odp_support_t inline_ipsec_tm;

	/** IPSEC TEST capabilities
	 *
	 * @see odp_ipsec_test_sa_update()
	 */
	odp_ipsec_test_capability_t test;

	/** Post-IPsec reassembly capability */
	odp_reass_capability_t reassembly;

	/** Support of reassembly after inbound processing in odp_ipsec_in_enq() */
	odp_bool_t reass_async;

	/** Support of reassembly after inline inbound IPsec processing */
	odp_bool_t reass_inline;

} odp_ipsec_capability_t;

/**
 * Cipher algorithm capabilities
 */
typedef struct odp_ipsec_cipher_capability_t {
	/** Key length in bytes */
	uint32_t key_len;

} odp_ipsec_cipher_capability_t;

/**
 * Authentication algorithm capabilities
 */
typedef struct odp_ipsec_auth_capability_t {
	/** Key length in bytes */
	uint32_t key_len;

	/** ICV length in bytes */
	uint32_t icv_len;
} odp_ipsec_auth_capability_t;

/**
 * IPSEC configuration options
 */
typedef struct odp_ipsec_config_t {
	/** Inbound IPSEC operation mode. Application selects which mode
	 *  will be used for inbound IPSEC operations.
	 *
	 *  @see odp_ipsec_in(), odp_ipsec_in_enq()
	 */
	odp_ipsec_op_mode_t inbound_mode;

	/** Outbound IPSEC operation mode. Application selects which mode
	 *  will be used for outbound IPSEC operations.
	 *
	 *  @see odp_ipsec_out(), odp_ipsec_out_enq(), odp_ipsec_out_inline()
	 */
	odp_ipsec_op_mode_t outbound_mode;

	/** Maximum number of IPSEC SAs that application will use
	 * simultaneously */
	uint32_t max_num_sa;

	/** IPSEC inbound processing configuration */
	odp_ipsec_inbound_config_t inbound;

	/** IPSEC outbound processing configuration */
	odp_ipsec_outbound_config_t outbound;

	/** Enable stats collection
	 *
	 *  Default value is false (stats collection disabled).
	 *
	 *  @see odp_ipsec_stats(), odp_ipsec_stats_multi()
	 */
	odp_bool_t stats_en;

} odp_ipsec_config_t;

/**
 * IPSEC SA direction
 */
typedef enum odp_ipsec_dir_t {
	/** Inbound IPSEC SA */
	ODP_IPSEC_DIR_INBOUND = 0,

	/** Outbound IPSEC SA */
	ODP_IPSEC_DIR_OUTBOUND

} odp_ipsec_dir_t;

/**
 * IPSEC protocol mode
 */
typedef enum odp_ipsec_mode_t {
	/** IPSEC tunnel mode */
	ODP_IPSEC_MODE_TUNNEL = 0,

	/** IPSEC transport mode */
	ODP_IPSEC_MODE_TRANSPORT

} odp_ipsec_mode_t;

/**
 * IPSEC protocol
 */
typedef enum odp_ipsec_protocol_t {
	/** ESP protocol */
	ODP_IPSEC_ESP = 0,

	/** AH protocol */
	ODP_IPSEC_AH

} odp_ipsec_protocol_t;

/**
 * IPSEC tunnel type
 */
typedef enum odp_ipsec_tunnel_type_t {
	/** Outer header is IPv4 */
	ODP_IPSEC_TUNNEL_IPV4 = 0,

	/** Outer header is IPv6 */
	ODP_IPSEC_TUNNEL_IPV6

} odp_ipsec_tunnel_type_t;

/**
 * IPSEC crypto parameters
 */
typedef struct odp_ipsec_crypto_param_t {
	/** Cipher algorithm
	 *
	 *  Select cipher algorithm to be used. ODP_CIPHER_ALG_NULL indicates
	 *  that ciphering is disabled. See 'ciphers' field of
	 *  odp_ipsec_capability_t for supported cipher algorithms. Algorithm
	 *  descriptions can be found from odp_cipher_alg_t documentation. Note
	 *  that some algorithms restrict choice of the pairing authentication
	 *  algorithm. When ciphering is enabled, cipher key and potential extra
	 *  key material (cipher_key_extra) need to be set. The default value
	 *  is ODP_CIPHER_ALG_NULL.
	 */
	odp_cipher_alg_t cipher_alg;

	/** Cipher key */
	odp_crypto_key_t cipher_key;

	/** Extra keying material for cipher algorithm
	 *
	 *  Additional data used as salt or nonce if the algorithm requires it,
	 *  other algorithms ignore this field. These algorithms require this
	 *  field to be set:
	 *  - ODP_CIPHER_ALG_AES_CTR: 4 bytes of nonce
	 *  - ODP_CIPHER_ALG_AES_GCM: 4 bytes of salt
	 *  - ODP_CIPHER_ALG_AES_CCM: 3 bytes of salt
	 *  - ODP_CIPHER_ALG_CHACHA20_POLY1305: 4 bytes of salt
	 */
	odp_crypto_key_t cipher_key_extra;

	/** Authentication algorithm
	 *
	 *  Select authentication algorithm to be used. ODP_AUTH_ALG_NULL
	 *  indicates that authentication is disabled. See 'auths' field of
	 *  odp_ipsec_capability_t for supported authentication algorithms.
	 *  Algorithm descriptions can be found from odp_auth_alg_t
	 *  documentation. Note that some algorithms restrict choice of the
	 *  pairing cipher algorithm. When single algorithm provides both
	 *  ciphering and authentication (i.e. Authenticated Encryption),
	 *  authentication side key information ('auth_key' and
	 *  'auth_key_extra') is ignored, and cipher side values are
	 *  used instead. These algorithms ignore authentication side key
	 *  information: ODP_AUTH_ALG_AES_GCM, ODP_AUTH_ALG_AES_CCM and
	 *  ODP_AUTH_ALG_CHACHA20_POLY1305. Otherwise, authentication side
	 *  parameters must be set when authentication is enabled. The default
	 *  value is ODP_AUTH_ALG_NULL.
	 */
	odp_auth_alg_t auth_alg;

	/** Authentication key */
	odp_crypto_key_t auth_key;

	/** Extra keying material for authentication algorithm
	 *
	 *  Additional data used as salt or nonce if the algorithm requires it,
	 *  other algorithms ignore this field. These algorithms require this
	 *  field to be set:
	 *  - ODP_AUTH_ALG_AES_GMAC: 4 bytes of salt
	 */
	odp_crypto_key_t auth_key_extra;

	/**
	 * Length of integrity check value (ICV) in bytes.
	 *
	 * Some algorithms support multiple ICV lengths when used with IPsec.
	 * This field can be used to select a non-default ICV length.
	 *
	 * Zero value indicates that the default ICV length shall be used.
	 * The default length depends on the selected algorithm as follows:
	 *
	 * Algorithm                       Default length     Other lengths
	 * ----------------------------------------------------------------
	 * ODP_AUTH_ALG_NULL               0
	 * ODP_AUTH_ALG_MD5_HMAC           12
	 * ODP_AUTH_ALG_SHA1_HMAC          12
	 * ODP_AUTH_ALG_SHA256_HMAC        16
	 * ODP_AUTH_ALG_SHA384_HMAC        24
	 * ODP_AUTH_ALG_SHA512_HMAC        32
	 * ODP_AUTH_ALG_AES_GCM            16                 8, 12
	 * ODP_AUTH_ALG_AES_GMAC           16
	 * ODP_AUTH_ALG_AES_CCM            16                 8, 12
	 * ODP_AUTH_ALG_AES_CMAC           12
	 * ODP_AUTH_ALG_AES_XCBC_MAC       12
	 * ODP_AUTH_ALG_CHACHA20_POLY1305  16
	 *
	 * The requested ICV length must be supported for the selected
	 * algorithm as indicated by odp_ipsec_auth_capability().
	 *
	 * The default value is 0.
	 */
	uint32_t icv_len;

} odp_ipsec_crypto_param_t;

/** IPv4 header parameters */
typedef struct odp_ipsec_ipv4_param_t {
	/** IPv4 source address (NETWORK ENDIAN) */
	void *src_addr;

	/** IPv4 destination address (NETWORK ENDIAN) */
	void *dst_addr;

	/** IPv4 Differentiated Services Code Point. The default value is 0. */
	uint8_t dscp;

	/** IPv4 Don't Fragment bit. The default value is 0. */
	uint8_t df;

	/** IPv4 Time To Live. The default value is 255. */
	uint8_t ttl;

} odp_ipsec_ipv4_param_t;

/** IPv6 header parameters */
typedef struct odp_ipsec_ipv6_param_t {
	/** IPv6 source address (NETWORK ENDIAN) */
	void *src_addr;

	/** IPv6 destination address (NETWORK ENDIAN) */
	void *dst_addr;

	/** IPv6 flow label. The default value is 0. */
	uint32_t flabel;

	/** IPv6 Differentiated Services Code Point. The default value is 0. */
	uint8_t dscp;

	/** IPv6 hop limit. The default value is 255. */
	uint8_t hlimit;

} odp_ipsec_ipv6_param_t;

/**
 * IPSEC tunnel parameters
 *
 * These parameters are used to build outbound tunnel headers. All values are
 * passed in CPU native byte / bit order if not specified otherwise.
 * IP addresses must be in NETWORK byte order as those are passed in with
 * pointers and copied byte-by-byte from memory to the packet.
 */
typedef struct odp_ipsec_tunnel_param_t {
	/** Tunnel type: IPv4 or IPv6. The default is IPv4. */
	odp_ipsec_tunnel_type_t type;

	/** Tunnel type specific parameters */
	struct {
		/** IPv4 header parameters */
		odp_ipsec_ipv4_param_t ipv4;

		/** IPv6 header parameters */
		odp_ipsec_ipv6_param_t ipv6;
	};
} odp_ipsec_tunnel_param_t;

/**
 * IPSEC SA option flags
 */
typedef struct odp_ipsec_sa_opt_t {
	/** Extended Sequence Numbers (ESN)
	  *
	  * * 1: Use extended (64 bit) sequence numbers
	  * * 0: Use normal sequence numbers (the default value)
	  */
	uint32_t esn : 1;

	/** UDP encapsulation
	  *
	  * * 1: Do UDP encapsulation/decapsulation so that IPSEC packets can
	  *      traverse through NAT boxes.
	  * * 0: No UDP encapsulation (the default value)
	  */
	uint32_t udp_encap : 1;

	/** Copy DSCP bits
	  *
	  * * 1: Copy IPv4 or IPv6 DSCP bits from inner IP header to
	  *      the outer IP header in encapsulation, and vice versa in
	  *      decapsulation.
	  * * 0: Use values from odp_ipsec_tunnel_param_t in encapsulation and
	  *      do not change DSCP field in decapsulation (the default value).
	  */
	uint32_t copy_dscp : 1;

	/** Copy IPv6 Flow Label
	  *
	  * * 1: Copy IPv6 flow label from inner IPv6 header to the
	  *      outer IPv6 header.
	  * * 0: Use value from odp_ipsec_tunnel_param_t (the default value)
	  */
	uint32_t copy_flabel : 1;

	/** Copy IPv4 Don't Fragment bit
	  *
	  * * 1: Copy the DF bit from the inner IPv4 header to the outer
	  *      IPv4 header.
	  * * 0: Use value from odp_ipsec_tunnel_param_t (the default value)
	  */
	uint32_t copy_df : 1;

	/** Decrement inner packet Time To Live (TTL) field
	  *
	  * * 1: In tunnel mode, decrement inner packet IPv4 TTL or
	  *      IPv6 Hop Limit after tunnel decapsulation, or before tunnel
	  *      encapsulation.
	  * * 0: Inner packet is not modified (the default value)
	  */
	uint32_t dec_ttl : 1;

} odp_ipsec_sa_opt_t;

/**
 * IPSEC SA lifetime limits
 *
 * These limits are used for setting up SA lifetime. IPSEC operations check
 * against the limits and output a status code (e.g. soft_exp_bytes) when
 * a limit is crossed. It's implementation defined how many times soft
 * lifetime expiration is reported: only once, first N or all packets following
 * the limit crossing. Any number of limits may be used simultaneously.
 * Use zero when there is no limit.
 *
 * The default value is zero (i.e. no limit) for all the limits.
 */
typedef struct odp_ipsec_lifetime_t {
	/** Soft expiry limits for the session */
	struct {
		/** Limit in bytes */
		uint64_t bytes;

		/** Limit in packet */
		uint64_t packets;
	} soft_limit;

	/** Hard expiry limits for the session */
	struct {
		/** Limit in bytes */
		uint64_t bytes;

		/** Limit in packet */
		uint64_t packets;
	} hard_limit;
} odp_ipsec_lifetime_t;

/**
 * Fragmentation mode
 *
 * These options control outbound IP packet fragmentation offload. When offload
 * is enabled, IPSEC operation will determine if fragmentation is needed and
 * does it according to the mode.
 */
typedef enum odp_ipsec_frag_mode_t {
	/** Do not fragment IP packets */
	ODP_IPSEC_FRAG_DISABLED = 0,

	/** Fragment IP packet before IPSEC operation */
	ODP_IPSEC_FRAG_BEFORE,

	/** Fragment IP packet after IPSEC operation */
	ODP_IPSEC_FRAG_AFTER,

	/** Only check if IP fragmentation is needed,
	  * do not fragment packets. */
	ODP_IPSEC_FRAG_CHECK
} odp_ipsec_frag_mode_t;

/**
 * Packet lookup mode
 *
 * Lookup mode controls how an SA participates in SA lookup offload.
 * Inbound operations perform SA lookup if application does not provide a SA as
 * a parameter. In inline mode, a lookup miss directs the packet back to normal
 * packet input interface processing. SA lookup failure status
 * (status.error.sa_lookup) is reported through odp_ipsec_packet_result_t.
 */
typedef enum odp_ipsec_lookup_mode_t {
	/** Inbound SA lookup is disabled for the SA. */
	ODP_IPSEC_LOOKUP_DISABLED = 0,

	/** Inbound SA lookup is enabled. Lookup matches only SPI value. */
	ODP_IPSEC_LOOKUP_SPI,

	/** Inbound SA lookup is enabled. Lookup matches both SPI value and
	  * destination IP address. Functionality is otherwise identical to
	  * ODP_IPSEC_LOOKUP_SPI. */
	ODP_IPSEC_LOOKUP_DSTADDR_SPI

} odp_ipsec_lookup_mode_t;

/**
 * IPSEC pipeline configuration
 */
typedef enum odp_ipsec_pipeline_t {
	/** Do not pipeline. Send all resulting events to the application. */
	ODP_IPSEC_PIPELINE_NONE = 0,

	/** Send resulting packets to the classifier
	 *
	 *  IPSEC capability 'pipeline_cls' determines if pipelined
	 *  classification is supported. */
	ODP_IPSEC_PIPELINE_CLS

} odp_ipsec_pipeline_t;

/**
 * IPSEC header type
 */
typedef enum odp_ipsec_ip_version_t {
	/** Header is IPv4 */
	ODP_IPSEC_IPV4 = 4,

	/** Header is IPv6 */
	ODP_IPSEC_IPV6 = 6

} odp_ipsec_ip_version_t;

/**
 * IPSEC Security Association (SA) parameters
 */
typedef struct odp_ipsec_sa_param_t {
	/** IPSEC SA direction: inbound or outbound */
	odp_ipsec_dir_t dir;

	/** IPSEC protocol: ESP or AH. The default value is ODP_IPSEC_ESP. */
	odp_ipsec_protocol_t proto;

	/** IPSEC protocol mode: transport or tunnel */
	odp_ipsec_mode_t mode;

	/** Parameters for crypto and authentication algorithms */
	odp_ipsec_crypto_param_t crypto;

	/** Various SA option flags */
	odp_ipsec_sa_opt_t opt;

	/** SA lifetime parameters */
	odp_ipsec_lifetime_t lifetime;

	/** SPI value */
	uint32_t spi;

	/** Destination queue for IPSEC events
	 *
	 *  Operations in asynchronous or inline mode enqueue resulting events
	 *  into this queue. The default queue ('default_queue') is used when
	 *  SA is not known.
	 */
	odp_queue_t dest_queue;

	/** User defined SA context pointer
	 *
	 *  User defined context pointer associated with the SA.
	 *  The implementation may prefetch the context data. Default value
	 *  of the pointer is NULL.
	 */
	void *context;

	/** Context data length
	 *
	 *  User defined context data length in bytes for prefetching.
	 *  The implementation may use this value as a hint for the number of
	 *  context data bytes to prefetch. Default value is zero (no hint).
	 */
	uint32_t context_len;

	/** IPSEC SA direction dependent parameters */
	struct {
		/** Inbound specific parameters */
		struct {
			/** SA lookup mode
			 *  The default value is ODP_IPSEC_LOOKUP_DISABLED.
			 */
			odp_ipsec_lookup_mode_t lookup_mode;

			/** Additional SA lookup parameters. Values are
			 *  considered only in ODP_IPSEC_LOOKUP_DSTADDR_SPI
			 *  lookup mode. */
			struct {
				/** Select IP version */
				odp_ipsec_ip_version_t ip_version;

				/** IP destination address (NETWORK ENDIAN) to
				 *  be matched in addition to SPI value. */
				void *dst_addr;

			} lookup_param;

			/** Minimum anti-replay window size. Use 0 to disable
			 *  anti-replay service. The default value is 0.
			 */
			uint32_t antireplay_ws;

			/** Select pipelined destination for resulting events
			 *
			 * Asynchronous and inline modes generate events.
			 * Select where those events are sent. Inbound SAs may
			 * choose to use pipelined classification. The default
			 * value is ODP_IPSEC_PIPELINE_NONE.
			 */
			odp_ipsec_pipeline_t pipeline;

			/** Classifier destination CoS for resulting packets
			 *
			 *  Successfully decapsulated packets are sent to
			 *  classification through this CoS. Other resulting
			 *  events are sent to 'dest_queue'. This field is
			 *  considered only when 'pipeline' is
			 *  ODP_IPSEC_PIPELINE_CLS. The CoS must not be shared
			 *  between any pktio interface default CoS. The maximum
			 *  number of different CoS supported is defined by
			 *  IPSEC capability max_cls_cos.
			 */
			odp_cos_t dest_cos;

			/** Enable reassembly of IPsec tunneled fragments
			 *
			 *  Attempt reassembly of fragments after IPsec tunnel
			 *  decapsulation.
			 *
			 *  Reassembly is attempted for inline or asynchronously
			 *  processed packets, not for packets processed using
			 *  the synchronous API function.
			 *
			 *  Fragments received through different SAs will not be
			 *  reassembled into the same packet.
			 *
			 *  IPsec statistics reflect IPsec processing before
			 *  reassembly and thus count all individual fragments.
			 *
			 *  Reassembly may be enabled for an SA only if
			 *  reassembly was enabled in the global IPsec
			 *  configuration.
			 *
			 *  Default value is false.
			 *
			 *  @see odp_ipsec_config()
			 *
			 */
			odp_bool_t reassembly_en;

		} inbound;

		/** Outbound specific parameters */
		struct {
			/** Parameters for tunnel mode */
			odp_ipsec_tunnel_param_t tunnel;

			/** Fragmentation mode
			 *  The default value is ODP_IPSEC_FRAG_DISABLED.
			 */
			odp_ipsec_frag_mode_t frag_mode;

			/** MTU for outbound IP fragmentation offload
			 *
			 *  This is the maximum length of IP packets that
			 *  outbound IPSEC operations may produce. The value may
			 *  be updated later with odp_ipsec_sa_mtu_update().
			 */
			uint32_t mtu;

		} outbound;
	};

} odp_ipsec_sa_param_t;

/**
 * IPSEC stats content
 */
typedef struct odp_ipsec_stats_t {
	/** Number of packets processed successfully */
	uint64_t success;

	/** Number of packets with protocol errors */
	uint64_t proto_err;

	/** Number of packets with authentication errors */
	uint64_t auth_err;

	/** Number of packets with antireplay check failures */
	uint64_t antireplay_err;

	/** Number of packets with algorithm errors */
	uint64_t alg_err;

	/** Number of packes with MTU errors */
	uint64_t mtu_err;

	/** Number of packets with hard lifetime(bytes) expired */
	uint64_t hard_exp_bytes_err;

	/** Number of packets with hard lifetime(packets) expired */
	uint64_t hard_exp_pkts_err;

	/** Total bytes of packet data processed by IPsec SA in success cases
	 *
	 * The range of packet bytes included in the success_bytes count is
	 * implementation defined but includes at least the bytes input for
	 * encryption or bytes output after decryption in ESP or the bytes
	 * authenticated in AH.
	 */
	uint64_t success_bytes;
} odp_ipsec_stats_t;

/**
 * IPSEC SA information
 */
typedef struct odp_ipsec_sa_info_t {
	/** IPsec SA parameters
	 *
	 * This is not necessarily an exact copy of the actual parameter
	 * structure used in SA creation. The fields that were relevant
	 * for the SA in the creation phase will have the same values,
	 * but other fields, such as tunnel parameters for a transport
	 * mode SA, will have undefined values.
	 */
	odp_ipsec_sa_param_t param;

	/** IPSEC SA direction dependent parameters */
	union {
		/** Inbound specific parameters */
		struct {
			/** Additional SA lookup parameters. */
			struct {
				/** IP destination address (NETWORK ENDIAN) to
				 *  be matched in addition to SPI value. */
				uint8_t dst_addr[ODP_IPV6_ADDR_SIZE];
			} lookup_param;

			/** Antireplay window size
			 *
			 * Antireplay window size configured for the SA.
			 * This value can be different from what application
			 * had requested.
			 */
			uint32_t antireplay_ws;

			/** Antireplay window top
			 *
			 * Sequence number representing a recent top of the
			 * anti-replay window. There may be a delay before the
			 * SA state is reflected in the value. The value will be
			 * zero if no packets have been processed or if the
			 * anti-replay service is not enabled.
			 */
			uint64_t antireplay_window_top;
		} inbound;

		/** Outbound specific parameters */
		struct {
			/** Sequence number
			 *
			 * Sequence number used for a recently processed packet.
			 * There may be a delay before the SA state is reflected
			 * in the value. When no packets have been processed,
			 * the value will be zero.
			 */
			uint64_t seq_num;

			/** Tunnel IP address */
			union {
				/** IPv4 */
				struct {
					/** IPv4 source address */
					uint8_t src_addr[ODP_IPV4_ADDR_SIZE];
					/** IPv4 destination address */
					uint8_t dst_addr[ODP_IPV4_ADDR_SIZE];
				} ipv4;

				/** IPv6 */
				struct {
					/** IPv6 source address */
					uint8_t src_addr[ODP_IPV6_ADDR_SIZE];
					/** IPv6 destination address */
					uint8_t dst_addr[ODP_IPV6_ADDR_SIZE];
				} ipv6;
			} tunnel;
		} outbound;
	};
} odp_ipsec_sa_info_t;

/**
 * Query IPSEC capabilities
 *
 * Outputs IPSEC capabilities on success.
 *
 * @param[out] capa   Pointer to capability structure for output
 *
 * @retval 0 on success
 * @retval <0 on failure
 */
int odp_ipsec_capability(odp_ipsec_capability_t *capa);

/**
 * Query supported IPSEC cipher algorithm capabilities
 *
 * Outputs all supported configuration options for the algorithm. Output is
 * sorted (from the smallest to the largest) first by key length, then by IV
 * length. Use this information to select key lengths, etc cipher algorithm
 * options for SA creation (odp_ipsec_crypto_param_t).
 *
 * @param      cipher       Cipher algorithm
 * @param[out] capa         Array of capability structures for output
 * @param      num          Maximum number of capability structures to output
 *
 * @return Number of capability structures for the algorithm. If this is larger
 *         than 'num', only 'num' first structures were output and application
 *         may call the function again with a larger value of 'num'.
 * @retval <0 on failure
 */
int odp_ipsec_cipher_capability(odp_cipher_alg_t cipher,
				odp_ipsec_cipher_capability_t capa[], int num);

/**
 * Query supported IPSEC authentication algorithm capabilities
 *
 * Outputs all supported configuration options for the algorithm. Output is
 * sorted (from the smallest to the largest) first by ICV length, then by key
 * length. Use this information to select key lengths, etc authentication
 * algorithm options for SA creation (odp_ipsec_crypto_param_t).
 *
 * @param      auth         Authentication algorithm
 * @param[out] capa         Array of capability structures for output
 * @param      num          Maximum number of capability structures to output
 *
 * @return Number of capability structures for the algorithm. If this is larger
 *         than 'num', only 'num' first structures were output and application
 *         may call the function again with a larger value of 'num'.
 * @retval <0 on failure
 */
int odp_ipsec_auth_capability(odp_auth_alg_t auth,
			      odp_ipsec_auth_capability_t capa[], int num);

/**
 * Initialize IPSEC configuration options
 *
 * Initialize an odp_ipsec_config_t to its default values.
 *
 * @param[out] config  Pointer to IPSEC configuration structure
 */
void odp_ipsec_config_init(odp_ipsec_config_t *config);

/**
 * Global IPSEC configuration
 *
 * Initialize and configure IPSEC offload with global configuration options.
 * This must be called before any SAs are created. Use odp_ipsec_capability()
 * to examine which features and modes are supported. This function must be
 * called before creating the first SA with odp_ipsec_sa_create(). Calling this
 * function multiple times results in undefined behaviour.
 *
 * @param config   Pointer to IPSEC configuration structure
 *
 * @retval 0 on success
 * @retval <0 on failure
 *
 * @see odp_ipsec_capability(), odp_ipsec_config_init()
 */
int odp_ipsec_config(const odp_ipsec_config_t *config);

/**
 * Initialize IPSEC SA parameters
 *
 * Initialize an odp_ipsec_sa_param_t to its default values for all fields.
 *
 * @param param   Pointer to the parameter structure
 */
void odp_ipsec_sa_param_init(odp_ipsec_sa_param_t *param);

/**
 * Create IPSEC SA
 *
 * Create a new IPSEC SA according to the parameters.
 *
 * @param param   IPSEC SA parameters
 *
 * @return IPSEC SA handle
 * @retval ODP_IPSEC_SA_INVALID on failure
 *
 * @see odp_ipsec_sa_param_init()
 */
odp_ipsec_sa_t odp_ipsec_sa_create(const odp_ipsec_sa_param_t *param);

/**
 * Disable IPSEC SA
 *
 * Application must use this call to disable a SA before destroying it. The call
 * marks the SA disabled, so that IPSEC implementation stops using it. For
 * example, inbound SPI lookups will not match any more. Application must
 * stop providing the SA as parameter to new IPSEC input/output operations
 * before calling disable. Packets in progress during the call may still match
 * the SA and be processed successfully.
 *
 * When in synchronous operation mode, the call will return when it's possible
 * to destroy the SA. In asynchronous mode, the same is indicated by an
 * ODP_EVENT_IPSEC_STATUS event sent to the queue specified for the SA. The
 * status event is guaranteed to be the last event for the SA, i.e. all
 * in-progress operations have completed and resulting events (including status
 * events) have been enqueued before it.
 *
 * @param sa      IPSEC SA to be disabled
 *
 * @retval 0      On success
 * @retval <0     On failure
 *
 * @see odp_ipsec_sa_destroy()
 */
int odp_ipsec_sa_disable(odp_ipsec_sa_t sa);

/**
 * Destroy IPSEC SA
 *
 * Destroy an unused IPSEC SA. Result is undefined if the SA is being used
 * (i.e. asynchronous operation is in progress).
 *
 * @param sa      IPSEC SA to be destroyed
 *
 * @retval 0      On success
 * @retval <0     On failure
 *
 * @see odp_ipsec_sa_create()
 */
int odp_ipsec_sa_destroy(odp_ipsec_sa_t sa);

/**
 * Printable format of odp_ipsec_sa_t
 *
 * @param sa      IPSEC SA handle
 *
 * @return uint64_t value that can be used to print/display this handle
 */
uint64_t odp_ipsec_sa_to_u64(odp_ipsec_sa_t sa);

/** IPSEC operation status has no errors */
#define ODP_IPSEC_OK 0

/** IPSEC errors */
typedef struct odp_ipsec_error_t {
	/** IPSEC errors */
	union {
		/** Error bits */
		struct {
			/** Protocol error. Not a valid ESP or AH packet,
			 *  packet data length error, etc. */
			uint32_t proto            : 1;

			/** SA lookup failed */
			uint32_t sa_lookup        : 1;

			/** Authentication failed */
			uint32_t auth             : 1;

			/** Anti-replay check failed */
			uint32_t antireplay       : 1;

			/** Other algorithm error */
			uint32_t alg              : 1;

			/** Packet does not fit into the given MTU size */
			uint32_t mtu              : 1;

			/** Hard lifetime expired: bytes */
			uint32_t hard_exp_bytes   : 1;

			/** Hard lifetime expired: packets */
			uint32_t hard_exp_packets : 1;
		};

		/** All error bits
		 *
		 *  This field can be used to set, clear or compare
		 *  multiple bits. For example, 'status.error.all != 0'
		 *  checks if there are any errors.
		 */
		uint32_t all;
	};

} odp_ipsec_error_t;

/** IPSEC warnings */
typedef struct odp_ipsec_warn_t {
	/** IPSEC warnings */
	union {
		/** Warning bits */
		struct {
			/** Soft lifetime expired: bytes */
			uint32_t soft_exp_bytes   : 1;

			/** Soft lifetime expired: packets */
			uint32_t soft_exp_packets : 1;
		};

		/** All warnings bits */
		uint32_t all;
	};

} odp_ipsec_warn_t;

/** IPSEC operation status */
typedef struct odp_ipsec_op_status_t {
	/** IPSEC status bits */
	union {
		/** IPSEC errors and warnings */
		struct {
			/** IPSEC errors */
			odp_ipsec_error_t error;

			/** IPSEC warnings */
			odp_ipsec_warn_t warn;
		};

		/** All status bits. Combines all error and warning bits.
		 *  For example, 'status.all != ODP_IPSEC_OK' checks if there
		 *  are any errors or warnings. */
		uint64_t all;

	};

} odp_ipsec_op_status_t;

/** IPSEC operation flags */
typedef struct odp_ipsec_op_flag_t {
	/** IPSEC operations flags */
	union {
		/** Operation flags */
		struct {
			/** Packet was processed in inline mode */
			uint32_t inline_mode      : 1;

		};

		/** All flag bits */
		uint32_t all;
	};

} odp_ipsec_op_flag_t;

/**
 * IPSEC outbound operation options
 *
 * These may be used to override some SA level options
 */
typedef struct odp_ipsec_out_opt_t {
	/** Union of all flag bits */
	union {
		/** Option flags. Set flag for those options that are
		 *  used, all other options are ignored. */
		struct {
			/** Use fragmentation mode option */
			uint32_t frag_mode: 1;

			/** Use TFC padding length option */
			uint32_t tfc_pad:   1;

			/** Tunnel mode TFC dummy packet. This can be used only
			 *  in tunnel mode. When the flag is set, packet length
			 *  and content is ignored and instead a TFC dummy
			 *  packet is created during IPSEC operation. The dummy
			 *  packet length is defined by 'tfc_pad_len' option.
			 *  If the SA is configured to copy IP header fields
			 *  from inner IP packet, those fields must be passed
			 *  with IP parameters option. */
			uint32_t tfc_dummy: 1;

			/** Use IP parameters option */
			uint32_t ip_param:  1;

		} flag;

		/** All flag bits */
		uint32_t all_flags;
	};

	/** Fragmentation mode */
	odp_ipsec_frag_mode_t frag_mode;

	/** TFC padding length
	 *
	 *  Number of TFC padding bytes added to the packet during IPSEC
	 *  processing. Resulting packet should not exceed the maximum packet
	 *  length of the pool, otherwise IPSEC operation may fail.
	 *  Implementation guarantees that the padding does not contain any
	 *  confidential information. */
	uint32_t tfc_pad_len;

	/** Union of IP parameters */
	union {
		/** Override IPv4 parameters in outer header creation.
		 *  IP addresses are ignored. */
		odp_ipsec_ipv4_param_t ipv4;

		/** Override IPv6 parameters in outer header creation.
		 *  IP addresses are ignored. */
		odp_ipsec_ipv6_param_t ipv6;
	};

} odp_ipsec_out_opt_t;

/**
 * IPSEC outbound operation parameters
 */
typedef struct odp_ipsec_out_param_t {
	/** Number of SAs
	 *
	 *  Outbound IPSEC operation needs SA from application. Use either
	 *  single SA for all packets, or a SA per packet.
	 *
	 *  Valid values are:
	 *  - 1:  Single SA for all packets
	 *  - N:  A SA per packet. N must match the number of packets.
	 */
	int num_sa;

	/** Number of outbound operation options
	 *
	 *  Valid values are:
	 *  - 0:  No options
	 *  - 1:  Single option for all packets
	 *  - N:  An option per packet. N must match the number of packets.
	 */
	int num_opt;

	/** Pointer to an array of IPSEC SAs */
	const odp_ipsec_sa_t *sa;

	/** Pointer to an array of outbound operation options
	 *
	 *  May be NULL when num_opt is zero.
	 */
	const odp_ipsec_out_opt_t *opt;

} odp_ipsec_out_param_t;

/**
 * IPSEC inbound operation parameters
 */
typedef struct odp_ipsec_in_param_t {
	/** Number of SAs
	 *
	 *  Inbound IPSEC operation processes a packet using the SA provided by
	 *  the application. If the application does not provide an SA, the
	 *  operation searches for the SA by matching the input packet with all
	 *  inbound SAs according to the lookup mode (odp_ipsec_lookup_mode_t)
	 *  configured in each SA. When passing SAs, use either single SA for
	 *  all packets, or a SA per packet.
	 *
	 *  Valid values are:
	 *  - 0:  No SAs. SA lookup is done for all packets.
	 *  - 1:  Single SA for all packets
	 *  - N:  A SA per packet. N must match the number of packets.
	 */
	int num_sa;

	/** Pointer to an array of IPSEC SAs
	 *
	 *  May be NULL when num_sa is zero.
	 */
	const odp_ipsec_sa_t *sa;

} odp_ipsec_in_param_t;

/**
 * Outbound inline IPSEC operation parameters
 */
typedef struct odp_ipsec_out_inline_param_t {
	/** Packet output interface for inline outbound operation without TM
	 *
	 *  Outbound inline IPSEC operation uses this packet IO interface to
	 *  output the packet after a successful IPSEC transformation. The pktio
	 *  must have been configured to operate in inline IPSEC mode.
	 *
	 *  The pktio must not have been configured with ODP_PKTOUT_MODE_TM.
	 *  For IPSEC inline output to TM enabled interfaces set this field
	 *  to ODP_PKTIO_INVALID and specify the TM queue to be used through
	 *  the tm_queue parameter. Inline IPSEC output through TM can be
	 *  done only if the platform has inline_ipsec_tm capability.
	 */
	odp_pktio_t pktio;

	/** TM queue for inline outbound operation
	 *
	 *  TM queue to be used for inline IPSEC output when pktio field
	 *  is ODP_PKTIO_INVALID, indicating use of TM. Otherwise ignored.
	 *
	 *  @see odp_ipsec_capability()
	 */
	odp_tm_queue_t tm_queue;

	/** Outer headers for inline output operation
	 *
	 *  Outbound inline IPSEC operation uses this information to prepend
	 *  outer headers to the IPSEC packet before sending it out.
	 */
	struct {
		/** Points to first byte of outer headers to be copied in
		 *  front of the outgoing IPSEC packet. Implementation copies
		 *  the headers during odp_ipsec_out_inline() call.
		 *
		 *  Null value indicates that the outer headers are in the
		 *  packet data, starting at L2 offset and ending at the byte
		 *  before L3 offset. In this case, value of 'len' field must
		 *  be greater than zero and set to L3 offset minus L2 offset.
		 */
		const uint8_t *ptr;

		/** Outer header length in bytes */
		uint32_t len;
	} outer_hdr;

} odp_ipsec_out_inline_param_t;

/**
 * IPSEC operation result for a packet
 */
typedef struct odp_ipsec_packet_result_t {
	/** IPSEC operation status. Use this to check if IPSEC operation
	 *  reported any errors or warnings (e.g. status.all != ODP_IPSEC_OK).
	 */
	odp_ipsec_op_status_t status;

	/** IPSEC operation flags */
	odp_ipsec_op_flag_t flag;

	/** IPSEC SA that was used to create the packet
	 *
	 *  Operation updates this SA handle value, when SA look up is performed
	 *  as part of the operation and the look up is successful. Operation
	 *  status code indicates if the look up failed. Otherwise, the SA
	 *  provided by the application is copied here.
	 */
	odp_ipsec_sa_t sa;

	/** Packet outer header status before inbound inline processing.
	 *  This is valid only when outer headers are retained
	 *  (see odp_ipsec_inbound_config_t) and flag.inline_mode is set.
	 */
	struct {
		/** Points to the first byte of retained outer headers. These
		 *  headers are stored in a contiquous, per packet,
		 *  implementation specific memory space. Since the memory space
		 *  may overlap with e.g. packet head/tailroom, the content
		 *  becomes invalid if packet data storage is modified in
		 *  any way. The memory space may not be shareable to other
		 *  threads. */
		uint8_t *ptr;

		/** Outer header length in bytes */
		uint32_t len;
	} outer_hdr;

	/** Total IP length of the original ESP or AH packet before IPsec
	 *  decapsulation. This is valid only for inbound inline and async
	 *  processed packets. Zero value means that the length information
	 *  is not available.
	 *
	 *  If the result packet was reassembled from multiple IPsec
	 *  protected packets, this is the sum of the lengths of all the
	 *  involved IPsec packets.
	 */
	uint32_t orig_ip_len;

} odp_ipsec_packet_result_t;

/**
 * IPSEC status ID
 */
typedef enum odp_ipsec_status_id_t {
	/** Response to SA disable command
	 *
	 *  Following status event (odp_ipsec_status_t) fields have valid
	 *  content, other fields must be ignored:
	 *  - sa:       The SA that was requested to be disabled
	 *  - result:   Operation result
	 */
	ODP_IPSEC_STATUS_SA_DISABLE = 0,

	/** Warning from inline IPSEC processing
	 *
	 *  Following status event (odp_ipsec_status_t) fields have valid
	 *  content, other fields must be ignored:
	 *  - sa:       The SA that caused the warning
	 *  - warn:     The warning(s) reported by this event
	 *
	 *  This status event is generated only for outbound SAs in
	 *  ODP_IPSEC_OP_MODE_INLINE mode.
	 */
	ODP_IPSEC_STATUS_WARN

} odp_ipsec_status_id_t;

/**
 * IPSEC status content
 */
typedef struct odp_ipsec_status_t {
	/** IPSEC status ID */
	odp_ipsec_status_id_t id;

	/** IPSEC SA that was target of the operation */
	odp_ipsec_sa_t sa;

	/** Result of the operation
	 *
	 *   0:    Success
	 *  <0:    Failure
	 */
	int result;

	/** Warnings of an ODP_IPSEC_STATUS_WARN status event */
	odp_ipsec_warn_t warn;

} odp_ipsec_status_t;

/**
 * Inbound synchronous IPSEC operation
 *
 * This operation does inbound IPSEC processing in synchronous mode
 * (ODP_IPSEC_OP_MODE_SYNC). A successful operation returns the number of
 * packets consumed and outputs a new packet handle for each outputted packet.
 * Outputted packets contain IPSEC result metadata (odp_ipsec_packet_result_t),
 * which should be checked for transformation errors, etc. Outputted packets
 * with error status have undefined content, except that in case of sa_lookup
 * error the original input packet data is returned. The operation does not
 * modify packets that it does not consume. It cannot consume all input
 * packets if 'num_out' is smaller than 'num_in'.
 *
 * Packet context pointer and user area content are copied from input to output
 * packets. Output packets are allocated from the same pool(s) as input packets.
 *
 * When 'param.num_sa' is zero, this operation performs SA look up for each
 * packet. Otherwise, application must provide the SA(s) as part of operation
 * input parameters (odp_ipsec_in_param_t). The operation outputs used SA(s) as
 * part of per packet results (odp_ipsec_packet_result_t), or an error
 * status if a SA was not found.
 *
 * Each input packet must have a valid value for these metadata (other metadata
 * is ignored):
 * - L3 offset: Offset to the first byte of the (outmost) IP header
 * - L4 offset: When udp_encap is enabled, offset to the first byte of the
 *              encapsulating UDP header
 *
 * Additionally, implementation checks input IP packet length (odp_packet_len()
 * minus odp_packet_l3_offset()) against protocol headers and reports an error
 * (status.error.proto) if packet data length is less than protocol headers
 * indicate.
 *
 * Packets are processed in the input order. Packet order is maintained from
 * input 'pkt' array to output 'pkt' array. Packet order is not guaranteed
 * between calling threads.
 *
 * Input packets must not be IP fragments.
 *
 * The operation does packet transformation according to IPSEC standards (see
 * e.g. RFC 4302 and 4303). Resulting packets are well formed, reconstructed
 * original IP packets, with IPSEC headers removed and valid header field values
 * restored. The amount and content of packet data before the IP header is
 * undefined. Some amount of TFC padding may follow the IP packet payload,
 * in which case packet length is larger than protocol headers indicate.
 * TFC dummy packets have l3_type set to ODP_PROTO_L3_TYPE_NONE in tunnel mode
 * or l4_type set to ODP_PROTO_L4_TYPE_NO_NEXT in transport mode. Dummy
 * packets contain implementation specific amount of (dummy) data. Furthermore,
 * inline IPSEC processing may drop dummy packets.
 *
 * Each successfully transformed packet has a valid value for these metadata
 * regardless of the inner packet parse configuration
 * (odp_ipsec_inbound_config_t):
 * - l3_offset: Offset to the first byte of the original IP packet. The value
 *              is implementation specific for tunnel mode TFC dummy packets.
 * - l3_type:   Specifies if the original packet is IPv4 or IPv6. For tunnel
 *              mode TFC dummy packets set to ODP_PROTO_L3_TYPE_NONE.
 * - l4_type:   Always set to ODP_PROTO_L4_TYPE_NO_NEXT for transport mode dummy
 *              packets. Otherwise, depends on parse configuration. Default
 *              value is ODP_PROTO_L4_TYPE_NONE.
 * - pktio:     For inline IPSEC processed packets, original packet input
 *              interface
 *
 * Other metadata for parse results and error checks depend on configuration
 * (selected parse and error check levels).
 *
 * @param          pkt_in   Packets to be processed
 * @param          num_in   Number of packets to be processed
 * @param[out]     pkt_out  Packet handle array for resulting packets
 * @param[in, out] num_out  Number of resulting packets. Application sets this
 *                          to 'pkt_out' array size. A successful operation sets
 *                          this to the number of outputted packets
 *                          (1 ... num_out).
 * @param          param    Inbound operation parameters
 *
 * @return Number of input packets consumed (0 ... num_in)
 * @retval <0     On failure
 *
 * @see odp_packet_user_ptr(), odp_packet_user_area(), odp_packet_l3_offset(),
 * odp_packet_l4_offset()
 */
int odp_ipsec_in(const odp_packet_t pkt_in[], int num_in,
		 odp_packet_t pkt_out[], int *num_out,
		 const odp_ipsec_in_param_t *param);

/**
 * Outbound synchronous IPSEC operation
 *
 * This operation does outbound IPSEC processing in synchronous mode
 * (ODP_IPSEC_OP_MODE_SYNC). A successful operation returns the number of
 * packets consumed and outputs a new packet handle for each outputted packet.
 * Outputted packets contain IPSEC result metadata (odp_ipsec_packet_result_t),
 * which should be checked for transformation errors, etc. Outputted packets
 * with error status have undefined content, except that in case of MTU error
 * the original input packet data is returned. The operation does not modify
 * packets that it does not consume. It cannot consume all input packets if
 * 'num_out' is smaller than 'num_in'.
 *
 * Packet context pointer and user area content are copied from input to output
 * packets. Output packets are allocated from the same pool(s) as input packets.
 *
 * When outbound IP fragmentation offload is enabled, the number of outputted
 * packets may be greater than the number of input packets.
 *
 * Each input packet must have a valid value for these metadata (other metadata
 * is ignored):
 * - L3 offset: Offset to the first byte of the (outmost) IP header
 * - L4 offset: Offset to the L4 header if L4 checksum offload is requested
 *
 * Additionally, input IP packet length (odp_packet_len() minus
 * odp_packet_l3_offset()) must match values in protocol headers. Otherwise
 * results are undefined.
 *
 * Packets are processed in the input order. Packet order is maintained from
 * input 'pkt' array to output 'pkt' array. Packet order is not guaranteed
 * between calling threads.
 *
 * The operation does packet transformation according to IPSEC standards (see
 * e.g. RFC 4302 and 4303). Resulting packets are well formed IP packets
 * with IPSEC, etc headers constructed according to the standards. The amount
 * and content of packet data before the IP header is undefined. Use outbound
 * operation parameters to specify the amount of TFC padding appended to
 * the packet during IPSEC transformation. Options can be used also to create
 * TFC dummy packets. Packet data content is ignored in tunnel mode TFC dummy
 * packet creation as tfc_pad_len option defines solely the packet length.
 * In all other cases, payload length for the IPSEC transformation is specified
 * by odp_packet_len() minus odp_packet_l3_offset() plus tfc_pad_len option.
 *
 * Each successfully transformed packet has a valid value for these metadata:
 * - L3 offset: Offset to the first byte of the (outmost) IP header
 *
 * @param          pkt_in   Packets to be processed
 * @param          num_in   Number of packets to be processed
 * @param[out]     pkt_out  Packet handle array for resulting packets
 * @param[in, out] num_out  Number of resulting packets. Application sets this
 *                          to 'pkt_out' array size. A successful operation sets
 *                          this to the number of outputted packets
 *                          (1 ... num_out).
 * @param          param    Outbound operation parameters
 *
 * @return Number of input packets consumed (0 ... num_in)
 * @retval <0     On failure
 *
 * @see odp_packet_user_ptr(), odp_packet_user_area(), odp_packet_l3_offset()
 */
int odp_ipsec_out(const odp_packet_t pkt_in[], int num_in,
		  odp_packet_t pkt_out[], int *num_out,
		  const odp_ipsec_out_param_t *param);

/**
 * Inbound asynchronous IPSEC operation
 *
 * This operation does inbound IPSEC processing in asynchronous mode. It
 * processes packets otherwise identically to odp_ipsec_in(), but outputs
 * resulting packets as ODP_EVENT_PACKET events (with ODP_EVENT_PACKET_IPSEC
 * subtype). The following ordering considerations apply to the events.
 *
 * Asynchronous mode maintains packet order per SA when application calls the
 * operation within an ordered or atomic scheduler context of the same queue.
 * Resulting events for the same SA are enqueued in order. Packet order per SA
 * at a destination queue is the same as if application would have enqueued
 * packets there with odp_queue_enq_multi().
 *
 * Packet order is also maintained when application otherwise guarantees
 * (e.g. using locks) that the operation is not called simultaneously from
 * multiple threads for the same SA(s).
 *
 * Logically, packet processing (e.g. sequence number check) happens in the
 * output order as defined above.
 *
 * The function may be used also in inline processing mode, e.g. for IPSEC
 * packets for which inline processing is not possible. Packets for the same SA
 * may be processed simultaneously in both modes (initiated by this function
 * and inline operation).
 *
 * Post-processing may be required after the reception of an IPsec packet
 * event to complete IPsec processing for the packet. The post-processing
 * happens in the odp_ipsec_result() function that must be called at least
 * once before packet data or metadata (other than packet type and subtype)
 * may be accessed.
 *
 * If reassembly is attempted but fails, the result packet delivered to the
 * application will have reassembly status as ODP_PACKET_REASS_INCOMPLETE and
 * will not have ODP_EVENT_PACKET_IPSEC subtype. In that case, the application
 * can call odp_packet_reass_partial_state() to get fragments of the packet. The
 * fragments will have subtype as ODP_EVENT_PACKET_IPSEC and the application
 * must call odp_ipsec_result() for such a fragment before accessing its packet
 * data.
 *
 * @param          pkt      Packets to be processed
 * @param          num      Number of packets to be processed
 * @param          param    Inbound operation parameters
 *
 * @return Number of input packets consumed (0 ... num)
 * @retval <0     On failure
 *
 * @see odp_ipsec_in(), odp_ipsec_result()
 */
int odp_ipsec_in_enq(const odp_packet_t pkt[], int num,
		     const odp_ipsec_in_param_t *param);

/**
 * Outbound asynchronous IPSEC operation
 *
 * This operation does outbound IPSEC processing in asynchronous mode. It
 * processes packets otherwise identically to odp_ipsec_out(), but outputs
 * resulting packets as ODP_EVENT_PACKET events (with ODP_EVENT_PACKET_IPSEC
 * subtype). The following ordering considerations apply to the events.
 *
 * Asynchronous mode maintains packet order per SA when application calls the
 * operation within an ordered or atomic scheduler context of the same queue.
 * Resulting events for the same SA are enqueued in order. Packet order per SA
 * at a destination queue is the same as if application would have enqueued
 * packets there with odp_queue_enq_multi().
 *
 * Packet order is also maintained when application otherwise guarantees
 * (e.g. using locks) that the operation is not called simultaneously from
 * multiple threads for the same SA(s).
 *
 * Logically, packet processing (e.g. sequence number assignment) happens in the
 * output order as defined above.
 *
 * The function may be used also in inline processing mode, e.g. for IPSEC
 * packets for which inline processing is not possible.
 *
 * Post-processing may be required after the reception of an IPsec packet
 * event to complete IPsec processing for the packet. The post-processing
 * happens in the odp_ipsec_result() function that must be called at least
 * once before packet data or metadata (other than packet type and subtype)
 * may be accessed.
 *
 * @param          pkt      Packets to be processed
 * @param          num      Number of packets to be processed
 * @param          param    Outbound operation parameters
 *
 * @return Number of input packets consumed (0 ... num)
 * @retval <0     On failure
 *
 * @see odp_ipsec_out(), odp_ipsec_result()
 */
int odp_ipsec_out_enq(const odp_packet_t pkt[], int num,
		      const odp_ipsec_out_param_t *param);

/**
 * Outbound inline IPSEC operation
 *
 * This operation does outbound inline IPSEC processing for the packets. It's
 * otherwise identical to odp_ipsec_out_enq(), but outputs all successfully
 * transformed packets to the specified output interface (or tm_queue), instead of
 * generating events for those.
 *
 * Inline operation parameters are defined per packet. The array of parameters
 * must have 'num' elements and is pointed to by 'inline_param'.
 *
 * @param          pkt           Packets to be processed
 * @param          num           Number of packets to be processed
 * @param          param         Outbound operation parameters
 * @param          inline_param  Outbound inline operation specific parameters
 *
 * @return Number of packets consumed (0 ... num)
 * @retval <0     On failure
 *
 * @see odp_ipsec_out_enq()
 */
int odp_ipsec_out_inline(const odp_packet_t pkt[], int num,
			 const odp_ipsec_out_param_t *param,
			 const odp_ipsec_out_inline_param_t *inline_param);

/**
 * Convert IPSEC processed packet event to packet handle
 *
 * Get packet handle to an IPSEC processed packet event. Event subtype must be
 * ODP_EVENT_IPSEC_PACKET. IPSEC operation results can be examined with
 * odp_ipsec_result().
 *
 * @param ev       Event handle
 *
 * @return Packet handle
 *
 * @see odp_event_subtype(), odp_ipsec_result()
 */
odp_packet_t odp_ipsec_packet_from_event(odp_event_t ev);

/**
 * Convert IPSEC processed packet handle to event
 *
 * The packet handle must be an output of an IPSEC operation.
 *
 * @param pkt      Packet handle from IPSEC operation
 *
 * @return Event handle
 */
odp_event_t odp_ipsec_packet_to_event(odp_packet_t pkt);

/**
 * Get IPSEC operation results from an IPSEC processed packet
 *
 * Successful IPSEC operations of all types (SYNC, ASYNC and INLINE) produce
 * packets which contain IPSEC result metadata. This function copies the
 * operation results from an IPSEC processed packet. Event subtype of this kind
 * of packet is ODP_EVENT_PACKET_IPSEC. Results are undefined if a non-IPSEC
 * processed packet is passed as input.
 *
 * Some packet API operations output a new packet handle
 * (e.g. odp_packet_concat()). IPSEC metadata remain valid as long as the packet
 * handle is not changed from the original (output of e.g. odp_ipsec_in() or
 * odp_ipsec_packet_from_event() call) IPSEC processed packet handle.
 *
 * @param[out]    result  Pointer to operation result for output
 * @param         packet  An IPSEC processed packet (ODP_EVENT_PACKET_IPSEC)
 *
 * @retval  0     On success
 * @retval <0     On failure
 *
 * @see odp_ipsec_in(), odp_ipsec_in_enq(), odp_ipsec_out(),
 *      odp_ipsec_out_enq(), odp_ipsec_packet_from_event()
 */
int odp_ipsec_result(odp_ipsec_packet_result_t *result, odp_packet_t packet);

/**
 * Get IPSEC status information from an ODP_EVENT_IPSEC_STATUS event
 *
 * Copies IPSEC status information from an event. The event must be of
 * type ODP_EVENT_IPSEC_STATUS.
 *
 * @param[out]    status  Pointer to status information structure for output.
 * @param         event   An ODP_EVENT_IPSEC_STATUS event
 *
 * @retval  0     On success
 * @retval <0     On failure
 *
 * @see odp_ipsec_sa_disable()
 */
int odp_ipsec_status(odp_ipsec_status_t *status, odp_event_t event);

/**
 * IPSEC test API for modifying internal state of an SA.
 *
 * This function is not meant to be used by normal applications but by special
 * test applications that test or debug the operation of the underlying ODP
 * implementation. Calling this function may degrade the performance of the
 * calling thread, other threads or the IPSEC implementation in general.
 *
 * Calling this function for an SA at the same time when the SA is used for
 * processing traffic or when the SA is being modified through other parts
 * of IPSEC API may result in undefined behaviour.
 *
 * SA state update through this function may not be supported by all ODP
 * implementations, ODP instances or SA instances or at every moment. This
 * function may return failure for unspecified reasons even when the capability
 * call indicated support for updating a particular parameter and previous
 * similar calls succeeded.
 *
 * @param          sa            IPSEC SA to be updated
 * @param          op            Specifies operation to be performed
 * @param          param         Pointer to IPSEC TEST SA param structure to be
 *                               used for the operation
 *
 * @return 0      On success
 * @retval <0     On failure
 */
int odp_ipsec_test_sa_update(odp_ipsec_sa_t sa,
			     odp_ipsec_test_sa_operation_t op,
			     const odp_ipsec_test_sa_param_t *param);

/**
 * Update MTU for outbound IP fragmentation
 *
 * When IP fragmentation offload is enabled, the SA is created with an MTU.
 * This call may be used to update MTU at any time. MTU updates are not
 * expected to happen very frequently.
 *
 * @param sa      IPSEC SA to be updated
 * @param mtu     The new MTU value
 *
 * @retval 0      On success
 * @retval <0     On failure
 */
int odp_ipsec_sa_mtu_update(odp_ipsec_sa_t sa, uint32_t mtu);

/**
 * Get user defined SA context pointer
 *
 * @param sa      IPSEC SA handle
 *
 * @return User defined SA context pointer value
 * @retval NULL   On failure
 */
void *odp_ipsec_sa_context(odp_ipsec_sa_t sa);

/**
 * Print global IPSEC configuration info
 *
 * Print implementation-defined information about the global IPSEC
 * configuration.
 */
void odp_ipsec_print(void);

/**
 * Print IPSEC SA info
 *
 * @param sa      SA handle
 *
 * Print implementation-defined IPSEC SA debug information to the ODP log.
 */
void odp_ipsec_sa_print(odp_ipsec_sa_t sa);

/**
 * Get IPSEC stats for the IPSEC SA handle
 *
 * @param          sa       IPSEC SA handle
 * @param[out]     stats    Stats output
 *
 * @retval 0 on success
 * @retval <0 on failure
 */
int odp_ipsec_stats(odp_ipsec_sa_t sa, odp_ipsec_stats_t *stats);

/**
 * Get IPSEC stats for multiple IPSEC SA handles
 *
 * @param          sa       Array of IPSEC SA handles
 * @param[out]     stats    Stats array for output
 * @param          num      Number of SA handles
 *
 * @retval 0 on success
 * @retval <0 on failure
 */
int odp_ipsec_stats_multi(odp_ipsec_sa_t sa[], odp_ipsec_stats_t stats[], int num);

/**
 * Retrieve information about an IPSEC SA
 *
 * The cipher and auth key data(including key extra) will not be exposed and
 * the corresponding pointers will be set to NULL. The IP address pointers
 * will point to the corresponding buffers available in the SA info structure.
 *
 * The user defined SA context pointer is an opaque field and hence the value
 * provided during the SA creation will be returned.
 *
 * @param      sa       The IPSEC SA for which to retrieve information
 * @param[out] sa_info  Pointer to caller allocated SA info structure to be
 *                      filled in
 *
 * @retval 0            On success
 * @retval <0           On failure
 **/
int odp_ipsec_sa_info(odp_ipsec_sa_t sa, odp_ipsec_sa_info_t *sa_info);

/**
 * @}
 */

#ifdef __cplusplus
}
#endif

#include <odp/visibility_end.h>
#endif