1 /* SPDX-License-Identifier: BSD-3-Clause 2 * 3 * Copyright(c) 2019-2021 Xilinx, Inc. 4 * Copyright(c) 2019 Solarflare Communications Inc. 5 * 6 * This software was jointly developed between OKTET Labs (under contract 7 * for Solarflare) and Solarflare Communications, Inc. 8 */ 9 10 #ifndef _SFC_MAE_H 11 #define _SFC_MAE_H 12 13 #include <stdbool.h> 14 15 #include <rte_spinlock.h> 16 17 #include "efx.h" 18 19 #ifdef __cplusplus 20 extern "C" { 21 #endif 22 23 /** FW-allocatable resource context */ 24 struct sfc_mae_fw_rsrc { 25 unsigned int refcnt; 26 RTE_STD_C11 27 union { 28 efx_mae_aset_id_t aset_id; 29 efx_mae_rule_id_t rule_id; 30 efx_mae_eh_id_t eh_id; 31 }; 32 }; 33 34 /** Outer rule registry entry */ 35 struct sfc_mae_outer_rule { 36 TAILQ_ENTRY(sfc_mae_outer_rule) entries; 37 unsigned int refcnt; 38 efx_mae_match_spec_t *match_spec; 39 efx_tunnel_protocol_t encap_type; 40 struct sfc_mae_fw_rsrc fw_rsrc; 41 }; 42 43 TAILQ_HEAD(sfc_mae_outer_rules, sfc_mae_outer_rule); 44 45 /** Encap. header registry entry */ 46 struct sfc_mae_encap_header { 47 TAILQ_ENTRY(sfc_mae_encap_header) entries; 48 unsigned int refcnt; 49 uint8_t *buf; 50 size_t size; 51 efx_tunnel_protocol_t type; 52 struct sfc_mae_fw_rsrc fw_rsrc; 53 }; 54 55 TAILQ_HEAD(sfc_mae_encap_headers, sfc_mae_encap_header); 56 57 /** Action set registry entry */ 58 struct sfc_mae_action_set { 59 TAILQ_ENTRY(sfc_mae_action_set) entries; 60 unsigned int refcnt; 61 efx_mae_actions_t *spec; 62 struct sfc_mae_encap_header *encap_header; 63 struct sfc_mae_fw_rsrc fw_rsrc; 64 }; 65 66 TAILQ_HEAD(sfc_mae_action_sets, sfc_mae_action_set); 67 68 /** Options for MAE support status */ 69 enum sfc_mae_status { 70 SFC_MAE_STATUS_UNKNOWN = 0, 71 SFC_MAE_STATUS_UNSUPPORTED, 72 SFC_MAE_STATUS_SUPPORTED 73 }; 74 75 /* 76 * Encap. header bounce buffer. It is used to store header data 77 * when parsing the header definition in the action VXLAN_ENCAP. 78 */ 79 struct sfc_mae_bounce_eh { 80 uint8_t *buf; 81 size_t buf_size; 82 size_t size; 83 efx_tunnel_protocol_t type; 84 }; 85 86 struct sfc_mae { 87 /** Assigned switch domain identifier */ 88 uint16_t switch_domain_id; 89 /** Assigned switch port identifier */ 90 uint16_t switch_port_id; 91 /** NIC support for MAE status */ 92 enum sfc_mae_status status; 93 /** Priority level limit for MAE outer rules */ 94 unsigned int nb_outer_rule_prios_max; 95 /** Priority level limit for MAE action rules */ 96 unsigned int nb_action_rule_prios_max; 97 /** Encapsulation support status */ 98 uint32_t encap_types_supported; 99 /** Outer rule registry */ 100 struct sfc_mae_outer_rules outer_rules; 101 /** Encap. header registry */ 102 struct sfc_mae_encap_headers encap_headers; 103 /** Action set registry */ 104 struct sfc_mae_action_sets action_sets; 105 /** Encap. header bounce buffer */ 106 struct sfc_mae_bounce_eh bounce_eh; 107 }; 108 109 struct sfc_adapter; 110 struct sfc_flow_spec; 111 112 /** This implementation supports double-tagging */ 113 #define SFC_MAE_MATCH_VLAN_MAX_NTAGS (2) 114 115 /** It is possible to keep track of one item ETH and two items VLAN */ 116 #define SFC_MAE_L2_MAX_NITEMS (SFC_MAE_MATCH_VLAN_MAX_NTAGS + 1) 117 118 /** Auxiliary entry format to keep track of L2 "type" ("inner_type") */ 119 struct sfc_mae_ethertype { 120 rte_be16_t value; 121 rte_be16_t mask; 122 }; 123 124 struct sfc_mae_pattern_data { 125 /** 126 * Keeps track of "type" ("inner_type") mask and value for each 127 * parsed L2 item in a pattern. These values/masks get filled 128 * in MAE match specification at the end of parsing. Also, this 129 * information is used to conduct consistency checks: 130 * 131 * - If an item ETH is followed by a single item VLAN, 132 * the former must have "type" set to one of supported 133 * TPID values (0x8100, 0x88a8, 0x9100, 0x9200, 0x9300), 134 * or 0x0000/0x0000. 135 * 136 * - If an item ETH is followed by two items VLAN, the 137 * item ETH must have "type" set to one of supported TPID 138 * values (0x88a8, 0x9100, 0x9200, 0x9300), or 0x0000/0x0000, 139 * and the outermost VLAN item must have "inner_type" set 140 * to TPID value 0x8100, or 0x0000/0x0000 141 * 142 * - If a L2 item is followed by a L3 one, the former must 143 * indicate "type" ("inner_type") which corresponds to 144 * the protocol used in the L3 item, or 0x0000/0x0000. 145 * 146 * In turn, mapping between RTE convention (above requirements) and 147 * MAE fields is non-trivial. The following scheme indicates 148 * which item EtherTypes go to which MAE fields in the case 149 * of single tag: 150 * 151 * ETH (0x8100) --> VLAN0_PROTO_BE 152 * VLAN (L3 EtherType) --> ETHER_TYPE_BE 153 * 154 * Similarly, in the case of double tagging: 155 * 156 * ETH (0x88a8) --> VLAN0_PROTO_BE 157 * VLAN (0x8100) --> VLAN1_PROTO_BE 158 * VLAN (L3 EtherType) --> ETHER_TYPE_BE 159 */ 160 struct sfc_mae_ethertype ethertypes[SFC_MAE_L2_MAX_NITEMS]; 161 162 rte_be16_t tci_masks[SFC_MAE_MATCH_VLAN_MAX_NTAGS]; 163 164 unsigned int nb_vlan_tags; 165 166 /** 167 * L3 requirement for the innermost L2 item's "type" ("inner_type"). 168 * This contains one of: 169 * - 0x0800/0xffff: IPV4 170 * - 0x86dd/0xffff: IPV6 171 * - 0x0000/0x0000: no L3 item 172 */ 173 struct sfc_mae_ethertype innermost_ethertype_restriction; 174 175 /** 176 * The following two fields keep track of L3 "proto" mask and value. 177 * The corresponding fields get filled in MAE match specification 178 * at the end of parsing. Also, the information is used by a 179 * post-check to enforce consistency requirements: 180 * 181 * - If a L3 item is followed by an item TCP, the former has 182 * its "proto" set to either 0x06/0xff or 0x00/0x00. 183 * 184 * - If a L3 item is followed by an item UDP, the former has 185 * its "proto" set to either 0x11/0xff or 0x00/0x00. 186 */ 187 uint8_t l3_next_proto_value; 188 uint8_t l3_next_proto_mask; 189 190 /* 191 * L4 requirement for L3 item's "proto". 192 * This contains one of: 193 * - 0x06/0xff: TCP 194 * - 0x11/0xff: UDP 195 * - 0x00/0x00: no L4 item 196 */ 197 uint8_t l3_next_proto_restriction_value; 198 uint8_t l3_next_proto_restriction_mask; 199 200 /* Projected state of EFX_MAE_FIELD_HAS_OVLAN match bit */ 201 bool has_ovlan_value; 202 bool has_ovlan_mask; 203 204 /* Projected state of EFX_MAE_FIELD_HAS_IVLAN match bit */ 205 bool has_ivlan_value; 206 bool has_ivlan_mask; 207 }; 208 209 struct sfc_mae_parse_ctx { 210 struct sfc_adapter *sa; 211 efx_mae_match_spec_t *match_spec_action; 212 efx_mae_match_spec_t *match_spec_outer; 213 /* 214 * This points to either of the above two specifications depending 215 * on which part of the pattern is being parsed (outer / inner). 216 */ 217 efx_mae_match_spec_t *match_spec; 218 /* 219 * This points to either "field_ids_remap_to_encap" 220 * or "field_ids_no_remap" (see sfc_mae.c) depending on 221 * which part of the pattern is being parsed. 222 */ 223 const efx_mae_field_id_t *field_ids_remap; 224 /* These two fields correspond to the tunnel-specific default mask. */ 225 size_t tunnel_def_mask_size; 226 const void *tunnel_def_mask; 227 bool match_mport_set; 228 struct sfc_mae_pattern_data pattern_data; 229 efx_tunnel_protocol_t encap_type; 230 unsigned int priority; 231 }; 232 233 int sfc_mae_attach(struct sfc_adapter *sa); 234 void sfc_mae_detach(struct sfc_adapter *sa); 235 sfc_flow_cleanup_cb_t sfc_mae_flow_cleanup; 236 int sfc_mae_rule_parse_pattern(struct sfc_adapter *sa, 237 const struct rte_flow_item pattern[], 238 struct sfc_flow_spec_mae *spec, 239 struct rte_flow_error *error); 240 int sfc_mae_rule_parse_actions(struct sfc_adapter *sa, 241 const struct rte_flow_action actions[], 242 struct sfc_flow_spec_mae *spec_mae, 243 struct rte_flow_error *error); 244 sfc_flow_verify_cb_t sfc_mae_flow_verify; 245 sfc_flow_insert_cb_t sfc_mae_flow_insert; 246 sfc_flow_remove_cb_t sfc_mae_flow_remove; 247 248 #ifdef __cplusplus 249 } 250 #endif 251 #endif /* _SFC_MAE_H */ 252