1 /* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */ 2 /* Copyright (c) 2018 Mellanox Technologies. */ 3 4 #ifndef __MLX5_EN_TC_CT_H__ 5 #define __MLX5_EN_TC_CT_H__ 6 7 #include <net/pkt_cls.h> 8 #include <linux/mlx5/fs.h> 9 #include <net/tc_act/tc_ct.h> 10 11 #include "en.h" 12 13 struct mlx5_flow_attr; 14 struct mlx5e_tc_mod_hdr_acts; 15 struct mlx5_rep_uplink_priv; 16 struct mlx5e_tc_flow; 17 struct mlx5e_priv; 18 19 struct mlx5_fs_chains; 20 struct mlx5_tc_ct_priv; 21 struct mlx5_ct_flow; 22 23 struct nf_flowtable; 24 25 struct mlx5_ct_attr { 26 u16 zone; 27 u16 ct_action; 28 struct mlx5_ct_flow *ct_flow; 29 struct nf_flowtable *nf_ft; 30 u32 ct_labels_id; 31 u32 act_miss_mapping; 32 u64 act_miss_cookie; 33 }; 34 35 #define zone_to_reg_ct {\ 36 .mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_C_2,\ 37 .moffset = 0,\ 38 .mlen = 16,\ 39 .soffset = MLX5_BYTE_OFF(fte_match_param,\ 40 misc_parameters_2.metadata_reg_c_2),\ 41 } 42 43 #define ctstate_to_reg_ct {\ 44 .mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_C_2,\ 45 .moffset = 16,\ 46 .mlen = 16,\ 47 .soffset = MLX5_BYTE_OFF(fte_match_param,\ 48 misc_parameters_2.metadata_reg_c_2),\ 49 } 50 51 #define mark_to_reg_ct {\ 52 .mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_C_3,\ 53 .moffset = 0,\ 54 .mlen = 32,\ 55 .soffset = MLX5_BYTE_OFF(fte_match_param,\ 56 misc_parameters_2.metadata_reg_c_3),\ 57 } 58 59 #define labels_to_reg_ct {\ 60 .mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_C_4,\ 61 .moffset = 0,\ 62 .mlen = 32,\ 63 .soffset = MLX5_BYTE_OFF(fte_match_param,\ 64 misc_parameters_2.metadata_reg_c_4),\ 65 } 66 67 /* 8 LSB of metadata C5 are reserved for packet color */ 68 #define fteid_to_reg_ct {\ 69 .mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_C_5,\ 70 .moffset = 8,\ 71 .mlen = 24,\ 72 .soffset = MLX5_BYTE_OFF(fte_match_param,\ 73 misc_parameters_2.metadata_reg_c_5),\ 74 } 75 76 #define zone_restore_to_reg_ct {\ 77 .mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_C_1,\ 78 .moffset = 0,\ 79 .mlen = ESW_ZONE_ID_BITS,\ 80 .soffset = MLX5_BYTE_OFF(fte_match_param,\ 81 misc_parameters_2.metadata_reg_c_1),\ 82 } 83 84 #define nic_zone_restore_to_reg_ct {\ 85 .mfield = MLX5_ACTION_IN_FIELD_METADATA_REG_B,\ 86 .moffset = 16,\ 87 .mlen = ESW_ZONE_ID_BITS,\ 88 } 89 90 #define MLX5_CT_ZONE_BITS MLX5_REG_MAPPING_MBITS(ZONE_TO_REG) 91 #define MLX5_CT_ZONE_MASK MLX5_REG_MAPPING_MASK(ZONE_TO_REG) 92 93 #if IS_ENABLED(CONFIG_MLX5_TC_CT) 94 95 struct mlx5_tc_ct_priv * 96 mlx5_tc_ct_init(struct mlx5e_priv *priv, struct mlx5_fs_chains *chains, 97 struct mod_hdr_tbl *mod_hdr, 98 enum mlx5_flow_namespace_type ns_type, 99 struct mlx5e_post_act *post_act); 100 void 101 mlx5_tc_ct_clean(struct mlx5_tc_ct_priv *ct_priv); 102 103 void 104 mlx5_tc_ct_match_del(struct mlx5_tc_ct_priv *priv, struct mlx5_ct_attr *ct_attr); 105 106 int 107 mlx5_tc_ct_match_add(struct mlx5_tc_ct_priv *priv, 108 struct mlx5_flow_spec *spec, 109 struct flow_cls_offload *f, 110 struct mlx5_ct_attr *ct_attr, 111 struct netlink_ext_ack *extack); 112 int mlx5_tc_ct_add_no_trk_match(struct mlx5_flow_spec *spec); 113 int 114 mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv, 115 struct mlx5_flow_attr *attr, 116 struct mlx5e_tc_mod_hdr_acts *mod_acts, 117 const struct flow_action_entry *act, 118 struct netlink_ext_ack *extack); 119 120 struct mlx5_flow_handle * 121 mlx5_tc_ct_flow_offload(struct mlx5_tc_ct_priv *priv, 122 struct mlx5_flow_spec *spec, 123 struct mlx5_flow_attr *attr, 124 struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts); 125 void 126 mlx5_tc_ct_delete_flow(struct mlx5_tc_ct_priv *priv, 127 struct mlx5_flow_attr *attr); 128 129 bool 130 mlx5e_tc_ct_restore_flow(struct mlx5_tc_ct_priv *ct_priv, 131 struct sk_buff *skb, u8 zone_restore_id); 132 133 int 134 mlx5_tc_ct_set_ct_clear_regs(struct mlx5_tc_ct_priv *priv, 135 struct mlx5e_tc_mod_hdr_acts *mod_acts); 136 137 #else /* CONFIG_MLX5_TC_CT */ 138 139 static inline struct mlx5_tc_ct_priv * 140 mlx5_tc_ct_init(struct mlx5e_priv *priv, struct mlx5_fs_chains *chains, 141 struct mod_hdr_tbl *mod_hdr, 142 enum mlx5_flow_namespace_type ns_type, 143 struct mlx5e_post_act *post_act) 144 { 145 return NULL; 146 } 147 148 static inline void 149 mlx5_tc_ct_clean(struct mlx5_tc_ct_priv *ct_priv) 150 { 151 } 152 153 static inline void 154 mlx5_tc_ct_match_del(struct mlx5_tc_ct_priv *priv, struct mlx5_ct_attr *ct_attr) {} 155 156 static inline int 157 mlx5_tc_ct_match_add(struct mlx5_tc_ct_priv *priv, 158 struct mlx5_flow_spec *spec, 159 struct flow_cls_offload *f, 160 struct mlx5_ct_attr *ct_attr, 161 struct netlink_ext_ack *extack) 162 { 163 struct flow_rule *rule = flow_cls_offload_flow_rule(f); 164 165 if (!flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CT)) 166 return 0; 167 168 NL_SET_ERR_MSG_MOD(extack, "mlx5 tc ct offload isn't enabled."); 169 return -EOPNOTSUPP; 170 } 171 172 static inline int 173 mlx5_tc_ct_add_no_trk_match(struct mlx5_flow_spec *spec) 174 { 175 return 0; 176 } 177 178 static inline int 179 mlx5_tc_ct_set_ct_clear_regs(struct mlx5_tc_ct_priv *priv, 180 struct mlx5e_tc_mod_hdr_acts *mod_acts) 181 { 182 return -EOPNOTSUPP; 183 } 184 185 static inline int 186 mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv, 187 struct mlx5_flow_attr *attr, 188 struct mlx5e_tc_mod_hdr_acts *mod_acts, 189 const struct flow_action_entry *act, 190 struct netlink_ext_ack *extack) 191 { 192 NL_SET_ERR_MSG_MOD(extack, "mlx5 tc ct offload isn't enabled."); 193 return -EOPNOTSUPP; 194 } 195 196 static inline struct mlx5_flow_handle * 197 mlx5_tc_ct_flow_offload(struct mlx5_tc_ct_priv *priv, 198 struct mlx5_flow_spec *spec, 199 struct mlx5_flow_attr *attr, 200 struct mlx5e_tc_mod_hdr_acts *mod_hdr_acts) 201 { 202 return ERR_PTR(-EOPNOTSUPP); 203 } 204 205 static inline void 206 mlx5_tc_ct_delete_flow(struct mlx5_tc_ct_priv *priv, 207 struct mlx5_flow_attr *attr) 208 { 209 } 210 211 static inline bool 212 mlx5e_tc_ct_restore_flow(struct mlx5_tc_ct_priv *ct_priv, 213 struct sk_buff *skb, u8 zone_restore_id) 214 { 215 if (!zone_restore_id) 216 return true; 217 218 return false; 219 } 220 221 #endif /* !IS_ENABLED(CONFIG_MLX5_TC_CT) */ 222 #endif /* __MLX5_EN_TC_CT_H__ */ 223