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 * 135 * - If an item ETH is followed by two items VLAN, the 136 * item ETH must have "type" set to one of supported TPID 137 * values (0x88a8, 0x9100, 0x9200, 0x9300), and the outermost 138 * VLAN item must have "inner_type" set to TPID value 0x8100. 139 * 140 * - If a L2 item is followed by a L3 one, the former must 141 * indicate "type" ("inner_type") which corresponds to 142 * the protocol used in the L3 item, or 0x0000/0x0000. 143 * 144 * In turn, mapping between RTE convention (above requirements) and 145 * MAE fields is non-trivial. The following scheme indicates 146 * which item EtherTypes go to which MAE fields in the case 147 * of single tag: 148 * 149 * ETH (0x8100) --> VLAN0_PROTO_BE 150 * VLAN (L3 EtherType) --> ETHER_TYPE_BE 151 * 152 * Similarly, in the case of double tagging: 153 * 154 * ETH (0x88a8) --> VLAN0_PROTO_BE 155 * VLAN (0x8100) --> VLAN1_PROTO_BE 156 * VLAN (L3 EtherType) --> ETHER_TYPE_BE 157 */ 158 struct sfc_mae_ethertype ethertypes[SFC_MAE_L2_MAX_NITEMS]; 159 unsigned int nb_vlan_tags; 160 161 /** 162 * L3 requirement for the innermost L2 item's "type" ("inner_type"). 163 * This contains one of: 164 * - 0x0800/0xffff: IPV4 165 * - 0x86dd/0xffff: IPV6 166 * - 0x0000/0x0000: no L3 item 167 */ 168 struct sfc_mae_ethertype innermost_ethertype_restriction; 169 170 /** 171 * The following two fields keep track of L3 "proto" mask and value. 172 * The corresponding fields get filled in MAE match specification 173 * at the end of parsing. Also, the information is used by a 174 * post-check to enforce consistency requirements: 175 * 176 * - If a L3 item is followed by an item TCP, the former has 177 * its "proto" set to either 0x06/0xff or 0x00/0x00. 178 * 179 * - If a L3 item is followed by an item UDP, the former has 180 * its "proto" set to either 0x11/0xff or 0x00/0x00. 181 */ 182 uint8_t l3_next_proto_value; 183 uint8_t l3_next_proto_mask; 184 185 /* 186 * L4 requirement for L3 item's "proto". 187 * This contains one of: 188 * - 0x06/0xff: TCP 189 * - 0x11/0xff: UDP 190 * - 0x00/0x00: no L4 item 191 */ 192 uint8_t l3_next_proto_restriction_value; 193 uint8_t l3_next_proto_restriction_mask; 194 }; 195 196 struct sfc_mae_parse_ctx { 197 struct sfc_adapter *sa; 198 efx_mae_match_spec_t *match_spec_action; 199 efx_mae_match_spec_t *match_spec_outer; 200 /* 201 * This points to either of the above two specifications depending 202 * on which part of the pattern is being parsed (outer / inner). 203 */ 204 efx_mae_match_spec_t *match_spec; 205 /* 206 * This points to either "field_ids_remap_to_encap" 207 * or "field_ids_no_remap" (see sfc_mae.c) depending on 208 * which part of the pattern is being parsed. 209 */ 210 const efx_mae_field_id_t *field_ids_remap; 211 /* These two fields correspond to the tunnel-specific default mask. */ 212 size_t tunnel_def_mask_size; 213 const void *tunnel_def_mask; 214 bool match_mport_set; 215 struct sfc_mae_pattern_data pattern_data; 216 efx_tunnel_protocol_t encap_type; 217 unsigned int priority; 218 }; 219 220 int sfc_mae_attach(struct sfc_adapter *sa); 221 void sfc_mae_detach(struct sfc_adapter *sa); 222 sfc_flow_cleanup_cb_t sfc_mae_flow_cleanup; 223 int sfc_mae_rule_parse_pattern(struct sfc_adapter *sa, 224 const struct rte_flow_item pattern[], 225 struct sfc_flow_spec_mae *spec, 226 struct rte_flow_error *error); 227 int sfc_mae_rule_parse_actions(struct sfc_adapter *sa, 228 const struct rte_flow_action actions[], 229 struct sfc_flow_spec_mae *spec_mae, 230 struct rte_flow_error *error); 231 sfc_flow_verify_cb_t sfc_mae_flow_verify; 232 sfc_flow_insert_cb_t sfc_mae_flow_insert; 233 sfc_flow_remove_cb_t sfc_mae_flow_remove; 234 235 #ifdef __cplusplus 236 } 237 #endif 238 #endif /* _SFC_MAE_H */ 239