examples/ipsec-secgw: implement inbound SAD
[dpdk.git] / examples / ipsec-secgw / sad.h
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2019 Intel Corporation
3  */
4
5 #ifndef __SAD_H__
6 #define __SAD_H__
7
8 #include <rte_ipsec_sad.h>
9
10 struct ipsec_sad {
11         struct rte_ipsec_sad *sad_v4;
12         struct rte_ipsec_sad *sad_v6;
13 };
14
15 int ipsec_sad_create(const char *name, struct ipsec_sad *sad,
16         int socket_id, struct ipsec_sa_cnt *sa_cnt);
17
18 int ipsec_sad_add(struct ipsec_sad *sad, struct ipsec_sa *sa);
19
20 static inline void
21 sad_lookup(const struct ipsec_sad *sad, struct rte_mbuf *pkts[],
22         void *sa[], uint16_t nb_pkts)
23 {
24         uint32_t i;
25         uint32_t nb_v4 = 0, nb_v6 = 0;
26         struct rte_esp_hdr *esp;
27         struct rte_ipv4_hdr *ipv4;
28         struct rte_ipv6_hdr *ipv6;
29         struct rte_ipsec_sadv4_key      v4[nb_pkts];
30         struct rte_ipsec_sadv6_key      v6[nb_pkts];
31         int v4_idxes[nb_pkts];
32         int v6_idxes[nb_pkts];
33         const union rte_ipsec_sad_key   *keys_v4[nb_pkts];
34         const union rte_ipsec_sad_key   *keys_v6[nb_pkts];
35         void *v4_res[nb_pkts];
36         void *v6_res[nb_pkts];
37
38         /* split received packets by address family into two arrays */
39         for (i = 0; i < nb_pkts; i++) {
40                 ipv4 = rte_pktmbuf_mtod(pkts[i], struct rte_ipv4_hdr *);
41                 esp = rte_pktmbuf_mtod_offset(pkts[i], struct rte_esp_hdr *,
42                                 pkts[i]->l3_len);
43                 if ((ipv4->version_ihl >> 4) == IPVERSION) {
44                         v4[nb_v4].spi = esp->spi;
45                         v4[nb_v4].dip = ipv4->dst_addr;
46                         v4[nb_v4].sip = ipv4->src_addr;
47                         keys_v4[nb_v4] = (const union rte_ipsec_sad_key *)
48                                                 &v4[nb_v4];
49                         v4_idxes[nb_v4++] = i;
50                 } else {
51                         ipv6 = rte_pktmbuf_mtod(pkts[i], struct rte_ipv6_hdr *);
52                         v6[nb_v6].spi = esp->spi;
53                         memcpy(v6[nb_v6].dip, ipv6->dst_addr,
54                                         sizeof(ipv6->dst_addr));
55                         memcpy(v6[nb_v6].sip, ipv6->src_addr,
56                                         sizeof(ipv6->src_addr));
57                         keys_v6[nb_v6] = (const union rte_ipsec_sad_key *)
58                                                 &v6[nb_v6];
59                         v6_idxes[nb_v6++] = i;
60                 }
61         }
62
63         if (nb_v4 != 0)
64                 rte_ipsec_sad_lookup(sad->sad_v4, keys_v4, v4_res, nb_v4);
65         if (nb_v6 != 0)
66                 rte_ipsec_sad_lookup(sad->sad_v6, keys_v6, v6_res, nb_v6);
67
68         for (i = 0; i < nb_v4; i++)
69                 sa[v4_idxes[i]] = v4_res[i];
70
71         for (i = 0; i < nb_v6; i++)
72                 sa[v6_idxes[i]] = v6_res[i];
73 }
74
75 #endif /* __SAD_H__ */