144c0947bSAndrew Rybchenko /* SPDX-License-Identifier: BSD-3-Clause 2244cfa79SAndrew Rybchenko * 398d26ef7SAndrew Rybchenko * Copyright(c) 2019-2021 Xilinx, Inc. 4a0147be5SAndrew Rybchenko * Copyright(c) 2017-2019 Solarflare Communications Inc. 5a9825ccfSRoman Zhukov * 6a9825ccfSRoman Zhukov * This software was jointly developed between OKTET Labs (under contract 7a9825ccfSRoman Zhukov * for Solarflare) and Solarflare Communications, Inc. 8a9825ccfSRoman Zhukov */ 9a9825ccfSRoman Zhukov 10a9825ccfSRoman Zhukov #ifndef _SFC_FLOW_H 11a9825ccfSRoman Zhukov #define _SFC_FLOW_H 12a9825ccfSRoman Zhukov 138cff0013SIvan Malov #include <stdbool.h> 148cff0013SIvan Malov 15a9825ccfSRoman Zhukov #include <rte_tailq.h> 16a9825ccfSRoman Zhukov #include <rte_flow_driver.h> 17a9825ccfSRoman Zhukov 18a9825ccfSRoman Zhukov #include "efx.h" 19a9825ccfSRoman Zhukov 206da67e70SIvan Malov #include "sfc_flow_rss.h" 21c6fa506cSIvan Malov #include "sfc_mae_ct.h" 226da67e70SIvan Malov 23a9825ccfSRoman Zhukov #ifdef __cplusplus 24a9825ccfSRoman Zhukov extern "C" { 25a9825ccfSRoman Zhukov #endif 26a9825ccfSRoman Zhukov 27814260e0SRoman Zhukov /* 28814260e0SRoman Zhukov * The maximum number of fully elaborated hardware filter specifications 29814260e0SRoman Zhukov * which can be produced from a template by means of multiplication, if 30814260e0SRoman Zhukov * missing match flags are needed to be taken into account 31814260e0SRoman Zhukov */ 325448324dSRoman Zhukov #define SF_FLOW_SPEC_NB_FILTERS_MAX 8 33814260e0SRoman Zhukov 34b61e717aSIvan Malov /* Used to guard action masks */ 35b61e717aSIvan Malov #define SFC_BUILD_SET_OVERFLOW(_action, _set) \ 36b61e717aSIvan Malov RTE_BUILD_BUG_ON((_action) >= sizeof(_set) * CHAR_BIT) 37b61e717aSIvan Malov 386f63bf7bSIvan Malov /* Flow engines supported by the implementation */ 396f63bf7bSIvan Malov enum sfc_flow_spec_type { 406f63bf7bSIvan Malov SFC_FLOW_SPEC_FILTER = 0, 4101628fc5SIvan Malov SFC_FLOW_SPEC_MAE, 426f63bf7bSIvan Malov 436f63bf7bSIvan Malov SFC_FLOW_SPEC_NTYPES 446f63bf7bSIvan Malov }; 456f63bf7bSIvan Malov 466f63bf7bSIvan Malov /* VNIC-specific flow specification */ 476f63bf7bSIvan Malov struct sfc_flow_spec_filter { 48814260e0SRoman Zhukov /* partial specification from flow rule */ 49814260e0SRoman Zhukov efx_filter_spec_t template; 50814260e0SRoman Zhukov /* fully elaborated hardware filters specifications */ 51814260e0SRoman Zhukov efx_filter_spec_t filters[SF_FLOW_SPEC_NB_FILTERS_MAX]; 52814260e0SRoman Zhukov /* number of complete specifications */ 53814260e0SRoman Zhukov unsigned int count; 546da67e70SIvan Malov /* RSS context (or NULL) */ 556da67e70SIvan Malov struct sfc_flow_rss_ctx *rss_ctx; 56814260e0SRoman Zhukov }; 57814260e0SRoman Zhukov 5893de39f5SIvan Malov /* Indicates the role of a given flow in tunnel offload */ 59f55fe01fSIvan Malov enum sfc_ft_rule_type { 6093de39f5SIvan Malov /* The flow has nothing to do with tunnel offload */ 6193de39f5SIvan Malov SFC_FT_RULE_NONE = 0, 62f55fe01fSIvan Malov /* The flow is a TUNNEL rule, to match on an outer header */ 63f55fe01fSIvan Malov SFC_FT_RULE_TUNNEL, 64f55fe01fSIvan Malov /* 65f55fe01fSIvan Malov * The flow is a SWITCH rule, to discard the outer header 66f55fe01fSIvan Malov * and dispatch the resulting packets to a vSwitch tenant 67f55fe01fSIvan Malov */ 68f55fe01fSIvan Malov SFC_FT_RULE_SWITCH, 6993de39f5SIvan Malov }; 7093de39f5SIvan Malov 7101628fc5SIvan Malov /* MAE-specific flow specification */ 7201628fc5SIvan Malov struct sfc_flow_spec_mae { 7393de39f5SIvan Malov /* FLow Tunnel (FT) rule type (or NONE) */ 74f55fe01fSIvan Malov enum sfc_ft_rule_type ft_rule_type; 7593de39f5SIvan Malov /* Flow Tunnel (FT) context (or NULL) */ 76f55fe01fSIvan Malov struct sfc_ft_ctx *ft_ctx; 7701628fc5SIvan Malov /* Desired priority level */ 7801628fc5SIvan Malov unsigned int priority; 7973e01736SIvan Malov /* 8073e01736SIvan Malov * Outer rule registry entry (points to below action_rule->outer_rule 8173e01736SIvan Malov * when action_rule is not NULL; self-sufficient entry otherwise) 8273e01736SIvan Malov */ 83dadff137SIvan Malov struct sfc_mae_outer_rule *outer_rule; 8473e01736SIvan Malov /* Action rule registry entry */ 8573e01736SIvan Malov struct sfc_mae_action_rule *action_rule; 86c6fa506cSIvan Malov /* Conntrack (CT) assistance table entry key and response */ 87c6fa506cSIvan Malov sfc_mae_conntrack_response_t ct_resp; 88c6fa506cSIvan Malov sfc_mae_conntrack_key_t ct_key; 891588d135SIvan Malov /* Conntrack (CT) assistance counter */ 901588d135SIvan Malov struct sfc_mae_counter *ct_counter; 9101628fc5SIvan Malov }; 9201628fc5SIvan Malov 936676ae6aSIvan Malov /* PMD-specific definition of the opaque type from rte_flow.h */ 946676ae6aSIvan Malov struct rte_flow_action_handle { 956676ae6aSIvan Malov TAILQ_ENTRY(rte_flow_action_handle) entries; 966676ae6aSIvan Malov 976676ae6aSIvan Malov bool transfer; 986676ae6aSIvan Malov enum rte_flow_action_type type; 996676ae6aSIvan Malov 1006676ae6aSIvan Malov union { 101*59641944SIvan Malov struct sfc_mae_encap_header *encap_header; 1026676ae6aSIvan Malov struct sfc_mae_counter *counter; 1036676ae6aSIvan Malov }; 1046676ae6aSIvan Malov }; 1056676ae6aSIvan Malov 1066676ae6aSIvan Malov TAILQ_HEAD(sfc_flow_indir_actions, rte_flow_action_handle); 1076676ae6aSIvan Malov 1086f63bf7bSIvan Malov /* Flow specification */ 1096f63bf7bSIvan Malov struct sfc_flow_spec { 1106f63bf7bSIvan Malov /* Flow specification type (engine-based) */ 1116f63bf7bSIvan Malov enum sfc_flow_spec_type type; 1126f63bf7bSIvan Malov 1136f63bf7bSIvan Malov union { 1146f63bf7bSIvan Malov /* Filter-based (VNIC level flows) specification */ 1156f63bf7bSIvan Malov struct sfc_flow_spec_filter filter; 11601628fc5SIvan Malov /* MAE-based (lower-level HW switch flows) specification */ 11701628fc5SIvan Malov struct sfc_flow_spec_mae mae; 1186f63bf7bSIvan Malov }; 1196f63bf7bSIvan Malov }; 1206f63bf7bSIvan Malov 121a9825ccfSRoman Zhukov /* PMD-specific definition of the opaque type from rte_flow.h */ 122a9825ccfSRoman Zhukov struct rte_flow { 1236f63bf7bSIvan Malov struct sfc_flow_spec spec; /* flow specification */ 124a9825ccfSRoman Zhukov TAILQ_ENTRY(rte_flow) entries; /* flow list entries */ 1258cff0013SIvan Malov bool internal; /* true for internal rules */ 126a9825ccfSRoman Zhukov }; 127a9825ccfSRoman Zhukov 128a9825ccfSRoman Zhukov TAILQ_HEAD(sfc_flow_list, rte_flow); 129a9825ccfSRoman Zhukov 130a9825ccfSRoman Zhukov extern const struct rte_flow_ops sfc_flow_ops; 131a9825ccfSRoman Zhukov 1322e2e5bdfSIvan Malov enum sfc_flow_item_layers { 1332e2e5bdfSIvan Malov SFC_FLOW_ITEM_ANY_LAYER, 1342e2e5bdfSIvan Malov SFC_FLOW_ITEM_START_LAYER, 1352e2e5bdfSIvan Malov SFC_FLOW_ITEM_L2, 1362e2e5bdfSIvan Malov SFC_FLOW_ITEM_L3, 1372e2e5bdfSIvan Malov SFC_FLOW_ITEM_L4, 1382e2e5bdfSIvan Malov }; 1392e2e5bdfSIvan Malov 1402e2e5bdfSIvan Malov /* Flow parse context types */ 1412e2e5bdfSIvan Malov enum sfc_flow_parse_ctx_type { 1422e2e5bdfSIvan Malov SFC_FLOW_PARSE_CTX_FILTER = 0, 1437a25bc98SIvan Malov SFC_FLOW_PARSE_CTX_MAE, 1442e2e5bdfSIvan Malov 1452e2e5bdfSIvan Malov SFC_FLOW_PARSE_CTX_NTYPES 1462e2e5bdfSIvan Malov }; 1472e2e5bdfSIvan Malov 1482e2e5bdfSIvan Malov /* Flow parse context */ 1492e2e5bdfSIvan Malov struct sfc_flow_parse_ctx { 1502e2e5bdfSIvan Malov enum sfc_flow_parse_ctx_type type; 1512e2e5bdfSIvan Malov 1522e2e5bdfSIvan Malov union { 1532e2e5bdfSIvan Malov /* Context pointer valid for filter-based (VNIC) flows */ 1542e2e5bdfSIvan Malov efx_filter_spec_t *filter; 1557a25bc98SIvan Malov /* Context pointer valid for MAE-based flows */ 1567a25bc98SIvan Malov struct sfc_mae_parse_ctx *mae; 1572e2e5bdfSIvan Malov }; 1582e2e5bdfSIvan Malov }; 1592e2e5bdfSIvan Malov 1602e2e5bdfSIvan Malov typedef int (sfc_flow_item_parse)(const struct rte_flow_item *item, 1612e2e5bdfSIvan Malov struct sfc_flow_parse_ctx *parse_ctx, 1622e2e5bdfSIvan Malov struct rte_flow_error *error); 1632e2e5bdfSIvan Malov 1642e2e5bdfSIvan Malov struct sfc_flow_item { 1652e2e5bdfSIvan Malov enum rte_flow_item_type type; /* Type of item */ 16673b91412SIvan Malov const char *name; /* Item name */ 1672e2e5bdfSIvan Malov enum sfc_flow_item_layers layer; /* Layer of item */ 1682e2e5bdfSIvan Malov enum sfc_flow_item_layers prev_layer; /* Previous layer of item */ 1692e2e5bdfSIvan Malov enum sfc_flow_parse_ctx_type ctx_type; /* Parse context type */ 1702e2e5bdfSIvan Malov sfc_flow_item_parse *parse; /* Parsing function */ 1712e2e5bdfSIvan Malov }; 1722e2e5bdfSIvan Malov 17373b91412SIvan Malov struct sfc_adapter; 17473b91412SIvan Malov 17573b91412SIvan Malov int sfc_flow_parse_pattern(struct sfc_adapter *sa, 17673b91412SIvan Malov const struct sfc_flow_item *flow_items, 1772e2e5bdfSIvan Malov unsigned int nb_flow_items, 1782e2e5bdfSIvan Malov const struct rte_flow_item pattern[], 1792e2e5bdfSIvan Malov struct sfc_flow_parse_ctx *parse_ctx, 1802e2e5bdfSIvan Malov struct rte_flow_error *error); 1812e2e5bdfSIvan Malov 1822e2e5bdfSIvan Malov int sfc_flow_parse_init(const struct rte_flow_item *item, 1832e2e5bdfSIvan Malov const void **spec_ptr, 1842e2e5bdfSIvan Malov const void **mask_ptr, 1852e2e5bdfSIvan Malov const void *supp_mask, 1862e2e5bdfSIvan Malov const void *def_mask, 1872e2e5bdfSIvan Malov unsigned int size, 1882e2e5bdfSIvan Malov struct rte_flow_error *error); 1892e2e5bdfSIvan Malov 190a9825ccfSRoman Zhukov void sfc_flow_init(struct sfc_adapter *sa); 191a9825ccfSRoman Zhukov void sfc_flow_fini(struct sfc_adapter *sa); 192a9825ccfSRoman Zhukov int sfc_flow_start(struct sfc_adapter *sa); 193a9825ccfSRoman Zhukov void sfc_flow_stop(struct sfc_adapter *sa); 194a9825ccfSRoman Zhukov 1955b2b9236SIvan Malov typedef int (sfc_flow_parse_cb_t)(struct rte_eth_dev *dev, 1965b2b9236SIvan Malov const struct rte_flow_item items[], 1975b2b9236SIvan Malov const struct rte_flow_action actions[], 1985b2b9236SIvan Malov struct rte_flow *flow, 1995b2b9236SIvan Malov struct rte_flow_error *error); 2005b2b9236SIvan Malov 2018b61dd99SIvan Malov typedef int (sfc_flow_verify_cb_t)(struct sfc_adapter *sa, 2028b61dd99SIvan Malov struct rte_flow *flow); 2038b61dd99SIvan Malov 2047a25bc98SIvan Malov typedef void (sfc_flow_cleanup_cb_t)(struct sfc_adapter *sa, 2057a25bc98SIvan Malov struct rte_flow *flow); 2067a25bc98SIvan Malov 2074f867ad6SIvan Malov typedef int (sfc_flow_insert_cb_t)(struct sfc_adapter *sa, 2084f867ad6SIvan Malov struct rte_flow *flow); 2094f867ad6SIvan Malov 2104f867ad6SIvan Malov typedef int (sfc_flow_remove_cb_t)(struct sfc_adapter *sa, 2114f867ad6SIvan Malov struct rte_flow *flow); 2124f867ad6SIvan Malov 2135cb47462SIgor Romanov typedef int (sfc_flow_query_cb_t)(struct rte_eth_dev *dev, 2145cb47462SIgor Romanov struct rte_flow *flow, 2155cb47462SIgor Romanov const struct rte_flow_action *action, 2165cb47462SIgor Romanov void *data, 2175cb47462SIgor Romanov struct rte_flow_error *error); 2185cb47462SIgor Romanov 2198cff0013SIvan Malov struct rte_flow *sfc_flow_create_locked(struct sfc_adapter *sa, bool internal, 22005d58ac4SIvan Malov const struct rte_flow_attr *attr, 22105d58ac4SIvan Malov const struct rte_flow_item pattern[], 22205d58ac4SIvan Malov const struct rte_flow_action actions[], 22305d58ac4SIvan Malov struct rte_flow_error *error); 22405d58ac4SIvan Malov 22505d58ac4SIvan Malov int sfc_flow_destroy_locked(struct sfc_adapter *sa, struct rte_flow *flow, 22605d58ac4SIvan Malov struct rte_flow_error *error); 22705d58ac4SIvan Malov 228a9825ccfSRoman Zhukov #ifdef __cplusplus 229a9825ccfSRoman Zhukov } 230a9825ccfSRoman Zhukov #endif 231a9825ccfSRoman Zhukov #endif /* _SFC_FLOW_H */ 232