xref: /freebsd/sys/dev/mlx5/mlx5_accel/ipsec.h (revision 205263ac250aadd84931d2b77475bc931c3afeff)
1e9dcd831SSlava Shwartsman /*-
2e23731dbSKonstantin Belousov  * Copyright (c) 2023 NVIDIA corporation & affiliates.
3e9dcd831SSlava Shwartsman  *
4e23731dbSKonstantin Belousov  * Redistribution and use in source and binary forms, with or without
5e23731dbSKonstantin Belousov  * modification, are permitted provided that the following conditions
6e23731dbSKonstantin Belousov  * are met:
7e23731dbSKonstantin Belousov  * 1. Redistributions of source code must retain the above copyright
8e23731dbSKonstantin Belousov  *    notice, this list of conditions and the following disclaimer.
9e23731dbSKonstantin Belousov  * 2. Redistributions in binary form must reproduce the above copyright
10e23731dbSKonstantin Belousov  *    notice, this list of conditions and the following disclaimer in the
11e23731dbSKonstantin Belousov  *    documentation and/or other materials provided with the distribution.
12e9dcd831SSlava Shwartsman  *
13e23731dbSKonstantin Belousov  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `AS IS' AND
14e23731dbSKonstantin Belousov  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15e23731dbSKonstantin Belousov  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16e23731dbSKonstantin Belousov  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
17e23731dbSKonstantin Belousov  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18e23731dbSKonstantin Belousov  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19e23731dbSKonstantin Belousov  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20e23731dbSKonstantin Belousov  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21e23731dbSKonstantin Belousov  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22e23731dbSKonstantin Belousov  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23e23731dbSKonstantin Belousov  * SUCH DAMAGE.
24e9dcd831SSlava Shwartsman  *
25e9dcd831SSlava Shwartsman  */
26e9dcd831SSlava Shwartsman 
27e9dcd831SSlava Shwartsman #ifndef __MLX5_ACCEL_IPSEC_H__
28e9dcd831SSlava Shwartsman #define __MLX5_ACCEL_IPSEC_H__
29e9dcd831SSlava Shwartsman 
30e23731dbSKonstantin Belousov #include <sys/mbuf.h>
31e9dcd831SSlava Shwartsman #include <dev/mlx5/driver.h>
32e23731dbSKonstantin Belousov #include <dev/mlx5/qp.h>
33e23731dbSKonstantin Belousov #include <dev/mlx5/mlx5_core/mlx5_core.h>
34e23731dbSKonstantin Belousov #include <dev/mlx5/mlx5_en/en.h>
35e23731dbSKonstantin Belousov #include <dev/mlx5/mlx5_lib/aso.h>
36e9dcd831SSlava Shwartsman 
37e23731dbSKonstantin Belousov #define MLX5E_IPSEC_SADB_RX_BITS 10
38e23731dbSKonstantin Belousov #define MLX5_IPSEC_METADATA_MARKER(ipsec_metadata) ((ipsec_metadata >> 31) & 0x1)
39e23731dbSKonstantin Belousov 
40*205263acSAriel Ehrenberg #define VLAN_NONE 0xfff
41*205263acSAriel Ehrenberg 
42e23731dbSKonstantin Belousov struct mlx5e_priv;
43e23731dbSKonstantin Belousov struct mlx5e_tx_wqe;
44e23731dbSKonstantin Belousov struct mlx5e_ipsec_tx;
45e23731dbSKonstantin Belousov struct mlx5e_ipsec_rx;
46e23731dbSKonstantin Belousov 
47e23731dbSKonstantin Belousov struct aes_gcm_keymat {
48e23731dbSKonstantin Belousov 	u64   seq_iv;
49e23731dbSKonstantin Belousov 
50e23731dbSKonstantin Belousov 	u32   salt;
51e23731dbSKonstantin Belousov 	u32   icv_len;
52e23731dbSKonstantin Belousov 
53e23731dbSKonstantin Belousov 	u32   key_len;
54e23731dbSKonstantin Belousov 	u32   aes_key[256 / 32];
55e9dcd831SSlava Shwartsman };
56e9dcd831SSlava Shwartsman 
57e23731dbSKonstantin Belousov struct mlx5e_ipsec_priv_bothdir {
58e23731dbSKonstantin Belousov 	struct mlx5e_ipsec_sa_entry *priv_in;
59e23731dbSKonstantin Belousov 	struct mlx5e_ipsec_sa_entry *priv_out;
60e9dcd831SSlava Shwartsman };
61e9dcd831SSlava Shwartsman 
62e23731dbSKonstantin Belousov struct mlx5e_ipsec_work {
63e23731dbSKonstantin Belousov         struct work_struct work;
64e23731dbSKonstantin Belousov         struct mlx5e_ipsec_sa_entry *sa_entry;
65e23731dbSKonstantin Belousov         void *data;
66e9dcd831SSlava Shwartsman };
67e9dcd831SSlava Shwartsman 
68e23731dbSKonstantin Belousov struct mlx5e_ipsec_dwork {
69e23731dbSKonstantin Belousov 	struct delayed_work dwork;
70e23731dbSKonstantin Belousov 	struct mlx5e_ipsec_sa_entry *sa_entry;
71e23731dbSKonstantin Belousov 	struct mlx5e_ipsec_priv_bothdir *pb;
72e23731dbSKonstantin Belousov };
73e9dcd831SSlava Shwartsman 
74e23731dbSKonstantin Belousov struct mlx5e_ipsec_aso {
75e23731dbSKonstantin Belousov         u8 __aligned(64) ctx[MLX5_ST_SZ_BYTES(ipsec_aso)];
76e23731dbSKonstantin Belousov         dma_addr_t dma_addr;
77e23731dbSKonstantin Belousov         struct mlx5_aso *aso;
78e23731dbSKonstantin Belousov         /* Protect ASO WQ access, as it is global to whole IPsec */
79e23731dbSKonstantin Belousov         spinlock_t lock;
80e23731dbSKonstantin Belousov };
81e23731dbSKonstantin Belousov 
82e23731dbSKonstantin Belousov struct mlx5_replay_esn {
83e23731dbSKonstantin Belousov 	u32 replay_window;
84e23731dbSKonstantin Belousov 	u32 esn;
85e23731dbSKonstantin Belousov 	u32 esn_msb;
86e23731dbSKonstantin Belousov 	u8 overlap : 1;
87e23731dbSKonstantin Belousov 	u8 trigger : 1;
88e23731dbSKonstantin Belousov };
89e23731dbSKonstantin Belousov 
90e23731dbSKonstantin Belousov struct mlx5_accel_esp_xfrm_attrs {
91e23731dbSKonstantin Belousov 	u32   spi;
92e23731dbSKonstantin Belousov 	struct aes_gcm_keymat aes_gcm;
93e23731dbSKonstantin Belousov 
94e9dcd831SSlava Shwartsman 	union {
95e23731dbSKonstantin Belousov 		__be32 a4;
96e23731dbSKonstantin Belousov 		__be32 a6[4];
97e23731dbSKonstantin Belousov 	} saddr;
98e23731dbSKonstantin Belousov 
99e23731dbSKonstantin Belousov 	union {
100e23731dbSKonstantin Belousov 		__be32 a4;
101e23731dbSKonstantin Belousov 		__be32 a6[4];
102e23731dbSKonstantin Belousov 	} daddr;
103e23731dbSKonstantin Belousov 
104e23731dbSKonstantin Belousov 	u8 dir : 2;
105e23731dbSKonstantin Belousov 	u8 encap : 1;
106e23731dbSKonstantin Belousov 	u8 drop : 1;
107e23731dbSKonstantin Belousov 	u8 family;
108e23731dbSKonstantin Belousov 	struct mlx5_replay_esn replay_esn;
109e23731dbSKonstantin Belousov 	u32 authsize;
110e23731dbSKonstantin Belousov 	u32 reqid;
111e23731dbSKonstantin Belousov 	u16 sport;
112e23731dbSKonstantin Belousov 	u16 dport;
113e9dcd831SSlava Shwartsman };
114e9dcd831SSlava Shwartsman 
115e23731dbSKonstantin Belousov enum mlx5_ipsec_cap {
116e23731dbSKonstantin Belousov 	MLX5_IPSEC_CAP_CRYPTO		= 1 << 0,
117e23731dbSKonstantin Belousov 	MLX5_IPSEC_CAP_ESN		= 1 << 1,
118e23731dbSKonstantin Belousov 	MLX5_IPSEC_CAP_PACKET_OFFLOAD	= 1 << 2,
119e23731dbSKonstantin Belousov 	MLX5_IPSEC_CAP_ROCE             = 1 << 3,
120e23731dbSKonstantin Belousov 	MLX5_IPSEC_CAP_PRIO             = 1 << 4,
121e23731dbSKonstantin Belousov 	MLX5_IPSEC_CAP_TUNNEL           = 1 << 5,
122e23731dbSKonstantin Belousov 	MLX5_IPSEC_CAP_ESPINUDP         = 1 << 6,
123e23731dbSKonstantin Belousov };
124e9dcd831SSlava Shwartsman 
125e23731dbSKonstantin Belousov struct mlx5e_ipsec {
126e23731dbSKonstantin Belousov 	struct mlx5_core_dev *mdev;
127e23731dbSKonstantin Belousov 	struct workqueue_struct *wq;
128e23731dbSKonstantin Belousov 	struct mlx5e_ipsec_tx *tx;
129e23731dbSKonstantin Belousov 	struct mlx5e_ipsec_rx *rx_ipv4;
130e23731dbSKonstantin Belousov 	struct mlx5e_ipsec_rx *rx_ipv6;
131e23731dbSKonstantin Belousov 	struct mlx5e_ipsec_aso *aso;
132e23731dbSKonstantin Belousov 	u32 pdn;
133e23731dbSKonstantin Belousov 	u32 mkey;
134e23731dbSKonstantin Belousov };
135e9dcd831SSlava Shwartsman 
136e23731dbSKonstantin Belousov struct mlx5e_ipsec_rule {
137e23731dbSKonstantin Belousov 	struct mlx5_flow_handle *rule;
138e23731dbSKonstantin Belousov 	struct mlx5_flow_handle *kspi_rule;
139e23731dbSKonstantin Belousov 	struct mlx5_flow_handle *reqid_rule;
140*205263acSAriel Ehrenberg 	struct mlx5_flow_handle *vid_zero_rule;
141e23731dbSKonstantin Belousov 	struct mlx5_modify_hdr *modify_hdr;
142e23731dbSKonstantin Belousov 	struct mlx5_pkt_reformat *pkt_reformat;
143e23731dbSKonstantin Belousov 	struct mlx5_fc *fc;
144e23731dbSKonstantin Belousov };
145e9dcd831SSlava Shwartsman 
146e23731dbSKonstantin Belousov struct mlx5e_ipsec_esn_state {
147e23731dbSKonstantin Belousov 	u32 esn;
148e23731dbSKonstantin Belousov 	u32 esn_msb;
149e23731dbSKonstantin Belousov 	u8 overlap: 1;
150e23731dbSKonstantin Belousov };
151e9dcd831SSlava Shwartsman 
152e23731dbSKonstantin Belousov struct mlx5e_ipsec_sa_entry {
153e23731dbSKonstantin Belousov 	struct secasvar *savp;
154e23731dbSKonstantin Belousov 	if_t ifp;
155*205263acSAriel Ehrenberg 	if_t ifpo;
156e23731dbSKonstantin Belousov 	struct mlx5e_ipsec *ipsec;
157e23731dbSKonstantin Belousov 	struct mlx5_accel_esp_xfrm_attrs attrs;
158e23731dbSKonstantin Belousov 	struct mlx5e_ipsec_rule ipsec_rule;
159e23731dbSKonstantin Belousov 	struct mlx5e_ipsec_dwork *dwork;
160e23731dbSKonstantin Belousov 	struct mlx5e_ipsec_work *work;
161e23731dbSKonstantin Belousov 	u32 ipsec_obj_id;
162e23731dbSKonstantin Belousov 	u32 enc_key_id;
163e23731dbSKonstantin Belousov 	u16 kspi; /* Stack allocated unique SA identifier */
164e23731dbSKonstantin Belousov 	struct mlx5e_ipsec_esn_state esn_state;
165*205263acSAriel Ehrenberg 	u16 vid;
166e23731dbSKonstantin Belousov };
167e9dcd831SSlava Shwartsman 
168e23731dbSKonstantin Belousov struct upspec {
169e23731dbSKonstantin Belousov         u16 dport;
170e23731dbSKonstantin Belousov         u16 sport;
171e23731dbSKonstantin Belousov         u8 proto;
172e23731dbSKonstantin Belousov };
173e9dcd831SSlava Shwartsman 
174e23731dbSKonstantin Belousov struct mlx5_accel_pol_xfrm_attrs {
175e23731dbSKonstantin Belousov         union {
176e23731dbSKonstantin Belousov                 __be32 a4;
177e23731dbSKonstantin Belousov                 __be32 a6[4];
178e23731dbSKonstantin Belousov         } saddr;
179e9dcd831SSlava Shwartsman 
180e23731dbSKonstantin Belousov         union {
181e23731dbSKonstantin Belousov                 __be32 a4;
182e23731dbSKonstantin Belousov                 __be32 a6[4];
183e23731dbSKonstantin Belousov         } daddr;
184e23731dbSKonstantin Belousov 
185e23731dbSKonstantin Belousov 	struct upspec upspec;
186e23731dbSKonstantin Belousov 
187e23731dbSKonstantin Belousov         u8 family;
188e23731dbSKonstantin Belousov         u8 action;
189e23731dbSKonstantin Belousov         u8 dir : 2;
190e23731dbSKonstantin Belousov         u32 reqid;
191e23731dbSKonstantin Belousov         u32 prio;
192*205263acSAriel Ehrenberg         u16 vid;
193e23731dbSKonstantin Belousov };
194e23731dbSKonstantin Belousov 
195e23731dbSKonstantin Belousov struct mlx5e_ipsec_pol_entry {
196e23731dbSKonstantin Belousov 	struct secpolicy *sp;
197e23731dbSKonstantin Belousov 	struct mlx5e_ipsec *ipsec;
198e23731dbSKonstantin Belousov 	struct mlx5e_ipsec_rule ipsec_rule;
199e23731dbSKonstantin Belousov 	struct mlx5_accel_pol_xfrm_attrs attrs;
200e23731dbSKonstantin Belousov };
201e23731dbSKonstantin Belousov 
202e23731dbSKonstantin Belousov /* This function doesn't really belong here, but let's put it here for now */
203e23731dbSKonstantin Belousov void mlx5_object_change_event(struct mlx5_core_dev *dev, struct mlx5_eqe *eqe);
204e23731dbSKonstantin Belousov 
205e23731dbSKonstantin Belousov int mlx5e_ipsec_init(struct mlx5e_priv *priv);
206e23731dbSKonstantin Belousov void mlx5e_ipsec_cleanup(struct mlx5e_priv *priv);
207e23731dbSKonstantin Belousov 
208e23731dbSKonstantin Belousov int mlx5e_ipsec_aso_init(struct mlx5e_ipsec *ipsec);
209e23731dbSKonstantin Belousov void mlx5e_ipsec_aso_cleanup(struct mlx5e_ipsec *ipsec);
210e23731dbSKonstantin Belousov 
211e23731dbSKonstantin Belousov int mlx5_ipsec_create_sa_ctx(struct mlx5e_ipsec_sa_entry *sa_entry);
212e23731dbSKonstantin Belousov void mlx5_ipsec_free_sa_ctx(struct mlx5e_ipsec_sa_entry *sa_entry);
213e23731dbSKonstantin Belousov 
214e23731dbSKonstantin Belousov u32 mlx5_ipsec_device_caps(struct mlx5_core_dev *mdev);
215e23731dbSKonstantin Belousov 
216e23731dbSKonstantin Belousov static inline struct mlx5_core_dev *
mlx5e_ipsec_sa2dev(struct mlx5e_ipsec_sa_entry * sa_entry)217e23731dbSKonstantin Belousov mlx5e_ipsec_sa2dev(struct mlx5e_ipsec_sa_entry *sa_entry)
218e9dcd831SSlava Shwartsman {
219e23731dbSKonstantin Belousov 	return sa_entry->ipsec->mdev;
220e9dcd831SSlava Shwartsman }
221e9dcd831SSlava Shwartsman 
222e23731dbSKonstantin Belousov static inline struct mlx5_core_dev *
mlx5e_ipsec_pol2dev(struct mlx5e_ipsec_pol_entry * pol_entry)223e23731dbSKonstantin Belousov mlx5e_ipsec_pol2dev(struct mlx5e_ipsec_pol_entry *pol_entry)
224e9dcd831SSlava Shwartsman {
225e23731dbSKonstantin Belousov 	return pol_entry->ipsec->mdev;
226e9dcd831SSlava Shwartsman }
227e9dcd831SSlava Shwartsman 
228e23731dbSKonstantin Belousov void mlx5e_ipsec_build_accel_xfrm_attrs(struct mlx5e_ipsec_sa_entry *sa_entry,
229e23731dbSKonstantin Belousov 					struct mlx5_accel_esp_xfrm_attrs *attrs,
230e23731dbSKonstantin Belousov 					u8 dir);
231e9dcd831SSlava Shwartsman 
232e23731dbSKonstantin Belousov int mlx5e_accel_ipsec_fs_init(struct mlx5e_ipsec *ipsec);
233e23731dbSKonstantin Belousov void mlx5e_accel_ipsec_fs_cleanup(struct mlx5e_ipsec *ipsec);
234e23731dbSKonstantin Belousov int mlx5e_accel_ipsec_fs_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry);
235e23731dbSKonstantin Belousov void mlx5e_accel_ipsec_fs_del_rule(struct mlx5e_ipsec_sa_entry *sa_entry);
236e23731dbSKonstantin Belousov void mlx5e_accel_ipsec_fs_modify(struct mlx5e_ipsec_sa_entry *sa_entry);
237e23731dbSKonstantin Belousov struct ipsec_accel_out_tag;
238e23731dbSKonstantin Belousov void mlx5e_accel_ipsec_handle_tx_wqe(struct mbuf *mb, struct mlx5e_tx_wqe *wqe,
239e23731dbSKonstantin Belousov     struct ipsec_accel_out_tag *tag);
240e23731dbSKonstantin Belousov int mlx5e_accel_ipsec_fs_add_pol(struct mlx5e_ipsec_pol_entry *pol_entry);
241e23731dbSKonstantin Belousov void mlx5e_accel_ipsec_fs_del_pol(struct mlx5e_ipsec_pol_entry *pol_entry);
mlx5e_accel_ipsec_get_metadata(unsigned int id)242e23731dbSKonstantin Belousov static inline int mlx5e_accel_ipsec_get_metadata(unsigned int id)
243e23731dbSKonstantin Belousov {
244e23731dbSKonstantin Belousov 	return MLX5_ETH_WQE_FT_META_IPSEC << 23 |  id;
245e23731dbSKonstantin Belousov }
246e23731dbSKonstantin Belousov static inline void
mlx5e_accel_ipsec_handle_tx(struct mbuf * mb,struct mlx5e_tx_wqe * wqe)247e23731dbSKonstantin Belousov mlx5e_accel_ipsec_handle_tx(struct mbuf *mb, struct mlx5e_tx_wqe *wqe)
248e23731dbSKonstantin Belousov {
249e23731dbSKonstantin Belousov 	struct ipsec_accel_out_tag *tag;
250e23731dbSKonstantin Belousov 
251e23731dbSKonstantin Belousov 	tag = (struct ipsec_accel_out_tag *)m_tag_find(mb,
252e23731dbSKonstantin Belousov 	    PACKET_TAG_IPSEC_ACCEL_OUT, NULL);
253e23731dbSKonstantin Belousov 	if (tag != NULL)
254e23731dbSKonstantin Belousov 		mlx5e_accel_ipsec_handle_tx_wqe(mb, wqe, tag);
255e23731dbSKonstantin Belousov }
256e23731dbSKonstantin Belousov void mlx5e_accel_ipsec_fs_rx_tables_destroy(struct mlx5e_priv *priv);
257e23731dbSKonstantin Belousov int mlx5e_accel_ipsec_fs_rx_tables_create(struct mlx5e_priv *priv);
258e23731dbSKonstantin Belousov void mlx5e_accel_ipsec_fs_rx_catchall_rules_destroy(struct mlx5e_priv *priv);
259e23731dbSKonstantin Belousov int mlx5e_accel_ipsec_fs_rx_catchall_rules(struct mlx5e_priv *priv);
260d00f3505SKonstantin Belousov int mlx5_accel_ipsec_rx_tag_add(if_t ifp, struct mlx5e_rq_mbuf *mr);
261d00f3505SKonstantin Belousov void mlx5e_accel_ipsec_handle_rx_cqe(struct mbuf *mb, struct mlx5_cqe64 *cqe,
262d00f3505SKonstantin Belousov     struct mlx5e_rq_mbuf *mr);
263d00f3505SKonstantin Belousov 
mlx5e_accel_ipsec_flow(struct mlx5_cqe64 * cqe)264e23731dbSKonstantin Belousov static inline int mlx5e_accel_ipsec_flow(struct mlx5_cqe64 *cqe)
265e23731dbSKonstantin Belousov {
266e23731dbSKonstantin Belousov 	return MLX5_IPSEC_METADATA_MARKER(be32_to_cpu(cqe->ft_metadata));
267e23731dbSKonstantin Belousov }
268e23731dbSKonstantin Belousov 
269d00f3505SKonstantin Belousov static inline void
mlx5e_accel_ipsec_handle_rx(struct mbuf * mb,struct mlx5_cqe64 * cqe,struct mlx5e_rq_mbuf * mr)270d00f3505SKonstantin Belousov mlx5e_accel_ipsec_handle_rx(struct mbuf *mb, struct mlx5_cqe64 *cqe,
271d00f3505SKonstantin Belousov     struct mlx5e_rq_mbuf *mr)
272e23731dbSKonstantin Belousov {
273e23731dbSKonstantin Belousov 	u32 ipsec_meta_data = be32_to_cpu(cqe->ft_metadata);
274e23731dbSKonstantin Belousov 
275d00f3505SKonstantin Belousov 	if (MLX5_IPSEC_METADATA_MARKER(ipsec_meta_data))
276d00f3505SKonstantin Belousov 		mlx5e_accel_ipsec_handle_rx_cqe(mb, cqe, mr);
277e23731dbSKonstantin Belousov }
278e9dcd831SSlava Shwartsman #endif	/* __MLX5_ACCEL_IPSEC_H__ */
279