FILE
ipsec_fs.c
File preview with syntax highlighting.
linux-6.19.14/drivers/net/ethernet/mellanox/mlx5/core/esw/ipsec_fs.c
1// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB 2// Copyright (c) 2023, NVIDIA CORPORATION & AFFILIATES. All rights reserved. 3 4#include "fs_core.h" 5#include "eswitch.h" 6#include "en_accel/ipsec.h" 7#include "esw/ipsec_fs.h" 8#if IS_ENABLED(CONFIG_MLX5_CLS_ACT) 9#include "en/tc_priv.h" 10#endif 11 12enum { 13 MLX5_ESW_IPSEC_RX_ESP_FT_LEVEL, 14 MLX5_ESW_IPSEC_RX_ESP_FT_CHK_LEVEL, 15 MLX5_ESW_IPSEC_RX_POL_FT_LEVEL, 16}; 17 18enum { 19 MLX5_ESW_IPSEC_TX_POL_FT_LEVEL, 20 MLX5_ESW_IPSEC_TX_ESP_FT_LEVEL, 21 MLX5_ESW_IPSEC_TX_ESP_FT_CNT_LEVEL, 22}; 23 24void mlx5_esw_ipsec_rx_create_attr_set(struct mlx5e_ipsec *ipsec, 25 struct mlx5e_ipsec_rx_create_attr *attr) 26{ 27 attr->prio = FDB_CRYPTO_INGRESS; 28 attr->pol_level = MLX5_ESW_IPSEC_RX_POL_FT_LEVEL; 29 attr->sa_level = MLX5_ESW_IPSEC_RX_ESP_FT_LEVEL; 30 attr->status_level = MLX5_ESW_IPSEC_RX_ESP_FT_CHK_LEVEL; 31 attr->chains_ns = MLX5_FLOW_NAMESPACE_FDB; 32} 33 34int mlx5_esw_ipsec_rx_status_pass_dest_get(struct mlx5e_ipsec *ipsec, 35 struct mlx5_flow_destination *dest) 36{ 37 dest->type = MLX5_FLOW_DESTINATION_TYPE_FLOW_TABLE; 38 dest->ft = mlx5_chains_get_table(esw_chains(ipsec->mdev->priv.eswitch), 0, 1, 0); 39 40 return 0; 41} 42 43int mlx5_esw_ipsec_rx_setup_modify_header(struct mlx5e_ipsec_sa_entry *sa_entry, 44 struct mlx5_flow_act *flow_act) 45{ 46 u8 action[MLX5_UN_SZ_BYTES(set_add_copy_action_in_auto)] = {}; 47 struct mlx5e_ipsec *ipsec = sa_entry->ipsec; 48 struct mlx5_core_dev *mdev = ipsec->mdev; 49 struct mlx5_modify_hdr *modify_hdr; 50 u32 mapped_id; 51 int err; 52 53 err = xa_alloc_bh(&ipsec->ipsec_obj_id_map, &mapped_id, 54 xa_mk_value(sa_entry->ipsec_obj_id), 55 XA_LIMIT(1, ESW_IPSEC_RX_MAPPED_ID_MASK), 0); 56 if (err) 57 return err; 58 59 /* reuse tunnel bits for ipsec, 60 * tun_id is always 0 and tun_opts is mapped to ipsec_obj_id. 61 */ 62 MLX5_SET(set_action_in, action, action_type, MLX5_ACTION_TYPE_SET); 63 MLX5_SET(set_action_in, action, field, 64 MLX5_ACTION_IN_FIELD_METADATA_REG_C_1); 65 MLX5_SET(set_action_in, action, offset, ESW_ZONE_ID_BITS); 66 MLX5_SET(set_action_in, action, length, 67 ESW_TUN_ID_BITS + ESW_TUN_OPTS_BITS); 68 MLX5_SET(set_action_in, action, data, mapped_id); 69 70 modify_hdr = mlx5_modify_header_alloc(mdev, MLX5_FLOW_NAMESPACE_FDB, 71 1, action); 72 if (IS_ERR(modify_hdr)) { 73 err = PTR_ERR(modify_hdr); 74 goto err_header_alloc; 75 } 76 77 sa_entry->rx_mapped_id = mapped_id; 78 flow_act->modify_hdr = modify_hdr; 79 flow_act->action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR; 80 81 return 0; 82 83err_header_alloc: 84 xa_erase_bh(&ipsec->ipsec_obj_id_map, mapped_id); 85 return err; 86} 87 88void mlx5_esw_ipsec_rx_rule_add_match_obj(struct mlx5e_ipsec_sa_entry *sa_entry, 89 struct mlx5_flow_spec *spec) 90{ 91 MLX5_SET(fte_match_param, spec->match_criteria, 92 misc_parameters_2.metadata_reg_c_1, 93 ESW_IPSEC_RX_MAPPED_ID_MATCH_MASK); 94 MLX5_SET(fte_match_param, spec->match_value, 95 misc_parameters_2.metadata_reg_c_1, 96 sa_entry->rx_mapped_id << ESW_ZONE_ID_BITS); 97 98 spec->match_criteria_enable |= MLX5_MATCH_MISC_PARAMETERS_2; 99} 100 101void mlx5_esw_ipsec_rx_id_mapping_remove(struct mlx5e_ipsec_sa_entry *sa_entry) 102{ 103 struct mlx5e_ipsec *ipsec = sa_entry->ipsec; 104 105 if (sa_entry->rx_mapped_id) 106 xa_erase_bh(&ipsec->ipsec_obj_id_map, 107 sa_entry->rx_mapped_id); 108} 109 110int mlx5_esw_ipsec_rx_ipsec_obj_id_search(struct mlx5e_priv *priv, u32 id, 111 u32 *ipsec_obj_id) 112{ 113 struct mlx5e_ipsec *ipsec = priv->ipsec; 114 void *val; 115 116 val = xa_load(&ipsec->ipsec_obj_id_map, id); 117 if (!val) 118 return -ENOENT; 119 120 *ipsec_obj_id = xa_to_value(val); 121 122 return 0; 123} 124 125void mlx5_esw_ipsec_tx_create_attr_set(struct mlx5e_ipsec *ipsec, 126 struct mlx5e_ipsec_tx_create_attr *attr) 127{ 128 attr->prio = FDB_CRYPTO_EGRESS; 129 attr->pol_level = MLX5_ESW_IPSEC_TX_POL_FT_LEVEL; 130 attr->sa_level = MLX5_ESW_IPSEC_TX_ESP_FT_LEVEL; 131 attr->cnt_level = MLX5_ESW_IPSEC_TX_ESP_FT_CNT_LEVEL; 132 attr->chains_ns = MLX5_FLOW_NAMESPACE_FDB; 133} 134 135#if IS_ENABLED(CONFIG_MLX5_CLS_ACT) 136static int mlx5_esw_ipsec_modify_flow_dests(struct mlx5_eswitch *esw, 137 struct mlx5e_tc_flow *flow) 138{ 139 struct mlx5_esw_flow_attr *esw_attr; 140 struct mlx5_flow_attr *attr; 141 int err; 142 143 attr = flow->attr; 144 esw_attr = attr->esw_attr; 145 if (esw_attr->out_count - esw_attr->split_count > 1) 146 return 0; 147 148 err = mlx5_eswitch_restore_ipsec_rule(esw, flow->rule[0], esw_attr, 149 esw_attr->out_count - 1); 150 151 return err; 152} 153#endif 154 155void mlx5_esw_ipsec_restore_dest_uplink(struct mlx5_core_dev *mdev) 156{ 157#if IS_ENABLED(CONFIG_MLX5_CLS_ACT) 158 struct mlx5_eswitch *esw = mdev->priv.eswitch; 159 struct mlx5_eswitch_rep *rep; 160 struct mlx5e_rep_priv *rpriv; 161 struct rhashtable_iter iter; 162 struct mlx5e_tc_flow *flow; 163 unsigned long i; 164 int err; 165 166 mlx5_esw_for_each_rep(esw, i, rep) { 167 if (atomic_read(&rep->rep_data[REP_ETH].state) != REP_LOADED) 168 continue; 169 170 rpriv = rep->rep_data[REP_ETH].priv; 171 rhashtable_walk_enter(&rpriv->tc_ht, &iter); 172 rhashtable_walk_start(&iter); 173 while ((flow = rhashtable_walk_next(&iter)) != NULL) { 174 if (IS_ERR(flow)) 175 continue; 176 177 err = mlx5_esw_ipsec_modify_flow_dests(esw, flow); 178 if (err) 179 mlx5_core_warn_once(mdev, 180 "Failed to modify flow dests for IPsec"); 181 } 182 rhashtable_walk_stop(&iter); 183 rhashtable_walk_exit(&iter); 184 } 185#endif 186}
~/
Read-only file preview.