1 /* 2 * Copyright (c) 2017 Mellanox Technologies. All rights reserved. 3 * 4 * This software is available to you under a choice of one of two 5 * licenses. You may choose to be licensed under the terms of the GNU 6 * General Public License (GPL) Version 2, available from the file 7 * COPYING in the main directory of this source tree, or the 8 * OpenIB.org BSD license below: 9 * 10 * Redistribution and use in source and binary forms, with or 11 * without modification, are permitted provided that the following 12 * conditions are met: 13 * 14 * - Redistributions of source code must retain the above 15 * copyright notice, this list of conditions and the following 16 * disclaimer. 17 * 18 * - Redistributions in binary form must reproduce the above 19 * copyright notice, this list of conditions and the following 20 * disclaimer in the documentation and/or other materials 21 * provided with the distribution. 22 * 23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30 * SOFTWARE. 31 * 32 */ 33 34 #ifndef __MLX5E_IPSEC_H__ 35 #define __MLX5E_IPSEC_H__ 36 37 #include <linux/mlx5/device.h> 38 #include <net/xfrm.h> 39 #include <linux/idr.h> 40 #include "lib/aso.h" 41 42 #define MLX5E_IPSEC_SADB_RX_BITS 10 43 #define MLX5E_IPSEC_ESN_SCOPE_MID 0x80000000L 44 45 struct aes_gcm_keymat { 46 u64 seq_iv; 47 48 u32 salt; 49 u32 icv_len; 50 51 u32 key_len; 52 u32 aes_key[256 / 32]; 53 }; 54 55 struct mlx5_accel_esp_xfrm_attrs { 56 u32 esn; 57 u32 spi; 58 u32 flags; 59 struct aes_gcm_keymat aes_gcm; 60 61 union { 62 __be32 a4; 63 __be32 a6[4]; 64 } saddr; 65 66 union { 67 __be32 a4; 68 __be32 a6[4]; 69 } daddr; 70 71 u8 dir : 2; 72 u8 esn_overlap : 1; 73 u8 esn_trigger : 1; 74 u8 type : 2; 75 u8 family; 76 u32 replay_window; 77 u32 authsize; 78 u32 reqid; 79 u64 hard_packet_limit; 80 u64 soft_packet_limit; 81 }; 82 83 enum mlx5_ipsec_cap { 84 MLX5_IPSEC_CAP_CRYPTO = 1 << 0, 85 MLX5_IPSEC_CAP_ESN = 1 << 1, 86 MLX5_IPSEC_CAP_PACKET_OFFLOAD = 1 << 2, 87 }; 88 89 struct mlx5e_priv; 90 91 struct mlx5e_ipsec_hw_stats { 92 u64 ipsec_rx_pkts; 93 u64 ipsec_rx_bytes; 94 u64 ipsec_rx_drop_pkts; 95 u64 ipsec_rx_drop_bytes; 96 u64 ipsec_tx_pkts; 97 u64 ipsec_tx_bytes; 98 u64 ipsec_tx_drop_pkts; 99 u64 ipsec_tx_drop_bytes; 100 }; 101 102 struct mlx5e_ipsec_sw_stats { 103 atomic64_t ipsec_rx_drop_sp_alloc; 104 atomic64_t ipsec_rx_drop_sadb_miss; 105 atomic64_t ipsec_rx_drop_syndrome; 106 atomic64_t ipsec_tx_drop_bundle; 107 atomic64_t ipsec_tx_drop_no_state; 108 atomic64_t ipsec_tx_drop_not_ip; 109 atomic64_t ipsec_tx_drop_trailer; 110 }; 111 112 struct mlx5e_ipsec_rx; 113 struct mlx5e_ipsec_tx; 114 115 struct mlx5e_ipsec_work { 116 struct work_struct work; 117 struct mlx5e_ipsec *ipsec; 118 u32 id; 119 }; 120 121 struct mlx5e_ipsec_aso { 122 u8 ctx[MLX5_ST_SZ_BYTES(ipsec_aso)]; 123 dma_addr_t dma_addr; 124 struct mlx5_aso *aso; 125 /* IPsec ASO caches data on every query call, 126 * so in nested calls, we can use this boolean to save 127 * recursive calls to mlx5e_ipsec_aso_query() 128 */ 129 u8 use_cache : 1; 130 }; 131 132 struct mlx5e_ipsec { 133 struct mlx5_core_dev *mdev; 134 struct xarray sadb; 135 struct mlx5e_ipsec_sw_stats sw_stats; 136 struct mlx5e_ipsec_hw_stats hw_stats; 137 struct workqueue_struct *wq; 138 struct mlx5e_flow_steering *fs; 139 struct mlx5e_ipsec_rx *rx_ipv4; 140 struct mlx5e_ipsec_rx *rx_ipv6; 141 struct mlx5e_ipsec_tx *tx; 142 struct mlx5e_ipsec_aso *aso; 143 struct notifier_block nb; 144 }; 145 146 struct mlx5e_ipsec_esn_state { 147 u32 esn; 148 u8 trigger: 1; 149 u8 overlap: 1; 150 }; 151 152 struct mlx5e_ipsec_rule { 153 struct mlx5_flow_handle *rule; 154 struct mlx5_modify_hdr *modify_hdr; 155 struct mlx5_pkt_reformat *pkt_reformat; 156 }; 157 158 struct mlx5e_ipsec_modify_state_work { 159 struct work_struct work; 160 struct mlx5_accel_esp_xfrm_attrs attrs; 161 }; 162 163 struct mlx5e_ipsec_sa_entry { 164 struct mlx5e_ipsec_esn_state esn_state; 165 struct xfrm_state *x; 166 struct mlx5e_ipsec *ipsec; 167 struct mlx5_accel_esp_xfrm_attrs attrs; 168 void (*set_iv_op)(struct sk_buff *skb, struct xfrm_state *x, 169 struct xfrm_offload *xo); 170 u32 ipsec_obj_id; 171 u32 enc_key_id; 172 struct mlx5e_ipsec_rule ipsec_rule; 173 struct mlx5e_ipsec_modify_state_work modify_work; 174 }; 175 176 struct mlx5_accel_pol_xfrm_attrs { 177 union { 178 __be32 a4; 179 __be32 a6[4]; 180 } saddr; 181 182 union { 183 __be32 a4; 184 __be32 a6[4]; 185 } daddr; 186 187 u8 family; 188 u8 action; 189 u8 type : 2; 190 u8 dir : 2; 191 u32 reqid; 192 }; 193 194 struct mlx5e_ipsec_pol_entry { 195 struct xfrm_policy *x; 196 struct mlx5e_ipsec *ipsec; 197 struct mlx5e_ipsec_rule ipsec_rule; 198 struct mlx5_accel_pol_xfrm_attrs attrs; 199 }; 200 201 #ifdef CONFIG_MLX5_EN_IPSEC 202 203 void mlx5e_ipsec_init(struct mlx5e_priv *priv); 204 void mlx5e_ipsec_cleanup(struct mlx5e_priv *priv); 205 void mlx5e_ipsec_build_netdev(struct mlx5e_priv *priv); 206 207 void mlx5e_accel_ipsec_fs_cleanup(struct mlx5e_ipsec *ipsec); 208 int mlx5e_accel_ipsec_fs_init(struct mlx5e_ipsec *ipsec); 209 int mlx5e_accel_ipsec_fs_add_rule(struct mlx5e_ipsec_sa_entry *sa_entry); 210 void mlx5e_accel_ipsec_fs_del_rule(struct mlx5e_ipsec_sa_entry *sa_entry); 211 int mlx5e_accel_ipsec_fs_add_pol(struct mlx5e_ipsec_pol_entry *pol_entry); 212 void mlx5e_accel_ipsec_fs_del_pol(struct mlx5e_ipsec_pol_entry *pol_entry); 213 214 int mlx5_ipsec_create_sa_ctx(struct mlx5e_ipsec_sa_entry *sa_entry); 215 void mlx5_ipsec_free_sa_ctx(struct mlx5e_ipsec_sa_entry *sa_entry); 216 217 u32 mlx5_ipsec_device_caps(struct mlx5_core_dev *mdev); 218 219 void mlx5_accel_esp_modify_xfrm(struct mlx5e_ipsec_sa_entry *sa_entry, 220 const struct mlx5_accel_esp_xfrm_attrs *attrs); 221 222 int mlx5e_ipsec_aso_init(struct mlx5e_ipsec *ipsec); 223 void mlx5e_ipsec_aso_cleanup(struct mlx5e_ipsec *ipsec); 224 225 int mlx5e_ipsec_aso_query(struct mlx5e_ipsec_sa_entry *sa_entry, 226 struct mlx5_wqe_aso_ctrl_seg *data); 227 void mlx5e_ipsec_aso_update_curlft(struct mlx5e_ipsec_sa_entry *sa_entry, 228 u64 *packets); 229 230 void mlx5e_accel_ipsec_fs_read_stats(struct mlx5e_priv *priv, 231 void *ipsec_stats); 232 233 void mlx5e_ipsec_build_accel_xfrm_attrs(struct mlx5e_ipsec_sa_entry *sa_entry, 234 struct mlx5_accel_esp_xfrm_attrs *attrs); 235 static inline struct mlx5_core_dev * 236 mlx5e_ipsec_sa2dev(struct mlx5e_ipsec_sa_entry *sa_entry) 237 { 238 return sa_entry->ipsec->mdev; 239 } 240 241 static inline struct mlx5_core_dev * 242 mlx5e_ipsec_pol2dev(struct mlx5e_ipsec_pol_entry *pol_entry) 243 { 244 return pol_entry->ipsec->mdev; 245 } 246 #else 247 static inline void mlx5e_ipsec_init(struct mlx5e_priv *priv) 248 { 249 } 250 251 static inline void mlx5e_ipsec_cleanup(struct mlx5e_priv *priv) 252 { 253 } 254 255 static inline void mlx5e_ipsec_build_netdev(struct mlx5e_priv *priv) 256 { 257 } 258 259 static inline u32 mlx5_ipsec_device_caps(struct mlx5_core_dev *mdev) 260 { 261 return 0; 262 } 263 #endif 264 265 #endif /* __MLX5E_IPSEC_H__ */ 266