199a2dd95SBruce Richardson /* SPDX-License-Identifier: BSD-3-Clause 299a2dd95SBruce Richardson * Copyright(c) 2010-2014 Intel Corporation 399a2dd95SBruce Richardson * Copyright(c) 2020 Arm Limited 499a2dd95SBruce Richardson */ 599a2dd95SBruce Richardson 699a2dd95SBruce Richardson #ifndef _RTE_LPM_H_ 799a2dd95SBruce Richardson #define _RTE_LPM_H_ 899a2dd95SBruce Richardson 999a2dd95SBruce Richardson /** 1099a2dd95SBruce Richardson * @file 1199a2dd95SBruce Richardson * RTE Longest Prefix Match (LPM) 1299a2dd95SBruce Richardson */ 1399a2dd95SBruce Richardson 1499a2dd95SBruce Richardson #include <errno.h> 1599a2dd95SBruce Richardson #include <stdint.h> 161094dd94SDavid Marchand #include <rte_compat.h> 1799a2dd95SBruce Richardson #include <rte_branch_prediction.h> 1899a2dd95SBruce Richardson #include <rte_byteorder.h> 1999a2dd95SBruce Richardson #include <rte_common.h> 2099a2dd95SBruce Richardson #include <rte_vect.h> 2199a2dd95SBruce Richardson #include <rte_rcu_qsbr.h> 2299a2dd95SBruce Richardson 2399a2dd95SBruce Richardson #ifdef __cplusplus 2499a2dd95SBruce Richardson extern "C" { 2599a2dd95SBruce Richardson #endif 2699a2dd95SBruce Richardson 2799a2dd95SBruce Richardson /** Max number of characters in LPM name. */ 2899a2dd95SBruce Richardson #define RTE_LPM_NAMESIZE 32 2999a2dd95SBruce Richardson 3099a2dd95SBruce Richardson /** Maximum depth value possible for IPv4 LPM. */ 3199a2dd95SBruce Richardson #define RTE_LPM_MAX_DEPTH 32 3299a2dd95SBruce Richardson 3399a2dd95SBruce Richardson /** @internal Total number of tbl24 entries. */ 3499a2dd95SBruce Richardson #define RTE_LPM_TBL24_NUM_ENTRIES (1 << 24) 3599a2dd95SBruce Richardson 3699a2dd95SBruce Richardson /** @internal Number of entries in a tbl8 group. */ 3799a2dd95SBruce Richardson #define RTE_LPM_TBL8_GROUP_NUM_ENTRIES 256 3899a2dd95SBruce Richardson 3999a2dd95SBruce Richardson /** @internal Max number of tbl8 groups in the tbl8. */ 4099a2dd95SBruce Richardson #define RTE_LPM_MAX_TBL8_NUM_GROUPS (1 << 24) 4199a2dd95SBruce Richardson 4299a2dd95SBruce Richardson /** @internal Total number of tbl8 groups in the tbl8. */ 4399a2dd95SBruce Richardson #define RTE_LPM_TBL8_NUM_GROUPS 256 4499a2dd95SBruce Richardson 4599a2dd95SBruce Richardson /** @internal Total number of tbl8 entries. */ 4699a2dd95SBruce Richardson #define RTE_LPM_TBL8_NUM_ENTRIES (RTE_LPM_TBL8_NUM_GROUPS * \ 4799a2dd95SBruce Richardson RTE_LPM_TBL8_GROUP_NUM_ENTRIES) 4899a2dd95SBruce Richardson 4999a2dd95SBruce Richardson /** @internal Macro to enable/disable run-time checks. */ 5099a2dd95SBruce Richardson #if defined(RTE_LIBRTE_LPM_DEBUG) 5199a2dd95SBruce Richardson #define RTE_LPM_RETURN_IF_TRUE(cond, retval) do { \ 5299a2dd95SBruce Richardson if (cond) return (retval); \ 5399a2dd95SBruce Richardson } while (0) 5499a2dd95SBruce Richardson #else 5599a2dd95SBruce Richardson #define RTE_LPM_RETURN_IF_TRUE(cond, retval) 5699a2dd95SBruce Richardson #endif 5799a2dd95SBruce Richardson 5899a2dd95SBruce Richardson /** @internal bitmask with valid and valid_group fields set */ 5999a2dd95SBruce Richardson #define RTE_LPM_VALID_EXT_ENTRY_BITMASK 0x03000000 6099a2dd95SBruce Richardson 6199a2dd95SBruce Richardson /** Bitmask used to indicate successful lookup */ 6299a2dd95SBruce Richardson #define RTE_LPM_LOOKUP_SUCCESS 0x01000000 6399a2dd95SBruce Richardson 6499a2dd95SBruce Richardson /** @internal Default RCU defer queue entries to reclaim in one go. */ 6599a2dd95SBruce Richardson #define RTE_LPM_RCU_DQ_RECLAIM_MAX 16 6699a2dd95SBruce Richardson 6799a2dd95SBruce Richardson /** RCU reclamation modes */ 6899a2dd95SBruce Richardson enum rte_lpm_qsbr_mode { 6999a2dd95SBruce Richardson /** Create defer queue for reclaim. */ 7099a2dd95SBruce Richardson RTE_LPM_QSBR_MODE_DQ = 0, 7199a2dd95SBruce Richardson /** Use blocking mode reclaim. No defer queue created. */ 7299a2dd95SBruce Richardson RTE_LPM_QSBR_MODE_SYNC 7399a2dd95SBruce Richardson }; 7499a2dd95SBruce Richardson 7599a2dd95SBruce Richardson #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN 7699a2dd95SBruce Richardson /** @internal Tbl24 entry structure. */ 7799a2dd95SBruce Richardson __extension__ 7899a2dd95SBruce Richardson struct rte_lpm_tbl_entry { 7999a2dd95SBruce Richardson /** 8099a2dd95SBruce Richardson * Stores Next hop (tbl8 or tbl24 when valid_group is not set) or 8199a2dd95SBruce Richardson * a group index pointing to a tbl8 structure (tbl24 only, when 8299a2dd95SBruce Richardson * valid_group is set) 8399a2dd95SBruce Richardson */ 8499a2dd95SBruce Richardson uint32_t next_hop :24; 8599a2dd95SBruce Richardson /* Using single uint8_t to store 3 values. */ 8699a2dd95SBruce Richardson uint32_t valid :1; /**< Validation flag. */ 8799a2dd95SBruce Richardson /** 8899a2dd95SBruce Richardson * For tbl24: 8999a2dd95SBruce Richardson * - valid_group == 0: entry stores a next hop 9099a2dd95SBruce Richardson * - valid_group == 1: entry stores a group_index pointing to a tbl8 9199a2dd95SBruce Richardson * For tbl8: 9299a2dd95SBruce Richardson * - valid_group indicates whether the current tbl8 is in use or not 9399a2dd95SBruce Richardson */ 9499a2dd95SBruce Richardson uint32_t valid_group :1; 9599a2dd95SBruce Richardson uint32_t depth :6; /**< Rule depth. */ 9699a2dd95SBruce Richardson }; 9799a2dd95SBruce Richardson 9899a2dd95SBruce Richardson #else 9999a2dd95SBruce Richardson 10099a2dd95SBruce Richardson __extension__ 10199a2dd95SBruce Richardson struct rte_lpm_tbl_entry { 10299a2dd95SBruce Richardson uint32_t depth :6; 10399a2dd95SBruce Richardson uint32_t valid_group :1; 10499a2dd95SBruce Richardson uint32_t valid :1; 10599a2dd95SBruce Richardson uint32_t next_hop :24; 10699a2dd95SBruce Richardson 10799a2dd95SBruce Richardson }; 10899a2dd95SBruce Richardson 10999a2dd95SBruce Richardson #endif 11099a2dd95SBruce Richardson 11199a2dd95SBruce Richardson /** LPM configuration structure. */ 11299a2dd95SBruce Richardson struct rte_lpm_config { 11399a2dd95SBruce Richardson uint32_t max_rules; /**< Max number of rules. */ 11499a2dd95SBruce Richardson uint32_t number_tbl8s; /**< Number of tbl8s to allocate. */ 11599a2dd95SBruce Richardson int flags; /**< This field is currently unused. */ 11699a2dd95SBruce Richardson }; 11799a2dd95SBruce Richardson 11899a2dd95SBruce Richardson /** @internal LPM structure. */ 11999a2dd95SBruce Richardson struct rte_lpm { 12099a2dd95SBruce Richardson /* LPM Tables. */ 12199a2dd95SBruce Richardson struct rte_lpm_tbl_entry tbl24[RTE_LPM_TBL24_NUM_ENTRIES] 12299a2dd95SBruce Richardson __rte_cache_aligned; /**< LPM tbl24 table. */ 12399a2dd95SBruce Richardson struct rte_lpm_tbl_entry *tbl8; /**< LPM tbl8 table. */ 12499a2dd95SBruce Richardson }; 12599a2dd95SBruce Richardson 12699a2dd95SBruce Richardson /** LPM RCU QSBR configuration structure. */ 12799a2dd95SBruce Richardson struct rte_lpm_rcu_config { 12899a2dd95SBruce Richardson struct rte_rcu_qsbr *v; /* RCU QSBR variable. */ 12999a2dd95SBruce Richardson /* Mode of RCU QSBR. RTE_LPM_QSBR_MODE_xxx 13099a2dd95SBruce Richardson * '0' for default: create defer queue for reclaim. 13199a2dd95SBruce Richardson */ 13299a2dd95SBruce Richardson enum rte_lpm_qsbr_mode mode; 13399a2dd95SBruce Richardson uint32_t dq_size; /* RCU defer queue size. 13499a2dd95SBruce Richardson * default: lpm->number_tbl8s. 13599a2dd95SBruce Richardson */ 13699a2dd95SBruce Richardson uint32_t reclaim_thd; /* Threshold to trigger auto reclaim. */ 13799a2dd95SBruce Richardson uint32_t reclaim_max; /* Max entries to reclaim in one go. 13899a2dd95SBruce Richardson * default: RTE_LPM_RCU_DQ_RECLAIM_MAX. 13999a2dd95SBruce Richardson */ 14099a2dd95SBruce Richardson }; 14199a2dd95SBruce Richardson 14299a2dd95SBruce Richardson /** 14399a2dd95SBruce Richardson * Create an LPM object. 14499a2dd95SBruce Richardson * 14599a2dd95SBruce Richardson * @param name 14699a2dd95SBruce Richardson * LPM object name 14799a2dd95SBruce Richardson * @param socket_id 14899a2dd95SBruce Richardson * NUMA socket ID for LPM table memory allocation 14999a2dd95SBruce Richardson * @param config 15099a2dd95SBruce Richardson * Structure containing the configuration 15199a2dd95SBruce Richardson * @return 15299a2dd95SBruce Richardson * Handle to LPM object on success, NULL otherwise with rte_errno set 15399a2dd95SBruce Richardson * to an appropriate values. Possible rte_errno values include: 15499a2dd95SBruce Richardson * - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure 15599a2dd95SBruce Richardson * - E_RTE_SECONDARY - function was called from a secondary process instance 15699a2dd95SBruce Richardson * - EINVAL - invalid parameter passed to function 15799a2dd95SBruce Richardson * - ENOSPC - the maximum number of memzones has already been allocated 15899a2dd95SBruce Richardson * - EEXIST - a memzone with the same name already exists 15999a2dd95SBruce Richardson * - ENOMEM - no appropriate memory area found in which to create memzone 16099a2dd95SBruce Richardson */ 16199a2dd95SBruce Richardson struct rte_lpm * 16299a2dd95SBruce Richardson rte_lpm_create(const char *name, int socket_id, 16399a2dd95SBruce Richardson const struct rte_lpm_config *config); 16499a2dd95SBruce Richardson 16599a2dd95SBruce Richardson /** 16699a2dd95SBruce Richardson * Find an existing LPM object and return a pointer to it. 16799a2dd95SBruce Richardson * 16899a2dd95SBruce Richardson * @param name 16999a2dd95SBruce Richardson * Name of the lpm object as passed to rte_lpm_create() 17099a2dd95SBruce Richardson * @return 17199a2dd95SBruce Richardson * Pointer to lpm object or NULL if object not found with rte_errno 17299a2dd95SBruce Richardson * set appropriately. Possible rte_errno values include: 17399a2dd95SBruce Richardson * - ENOENT - required entry not available to return. 17499a2dd95SBruce Richardson */ 17599a2dd95SBruce Richardson struct rte_lpm * 17699a2dd95SBruce Richardson rte_lpm_find_existing(const char *name); 17799a2dd95SBruce Richardson 17899a2dd95SBruce Richardson /** 17999a2dd95SBruce Richardson * Free an LPM object. 18099a2dd95SBruce Richardson * 18199a2dd95SBruce Richardson * @param lpm 18299a2dd95SBruce Richardson * LPM object handle 183448e01f1SStephen Hemminger * If lpm is NULL, no operation is performed. 18499a2dd95SBruce Richardson */ 18599a2dd95SBruce Richardson void 18699a2dd95SBruce Richardson rte_lpm_free(struct rte_lpm *lpm); 18799a2dd95SBruce Richardson 18899a2dd95SBruce Richardson /** 18999a2dd95SBruce Richardson * @warning 19099a2dd95SBruce Richardson * @b EXPERIMENTAL: this API may change without prior notice 19199a2dd95SBruce Richardson * 19299a2dd95SBruce Richardson * Associate RCU QSBR variable with an LPM object. 19399a2dd95SBruce Richardson * 19499a2dd95SBruce Richardson * @param lpm 19599a2dd95SBruce Richardson * the lpm object to add RCU QSBR 19699a2dd95SBruce Richardson * @param cfg 19799a2dd95SBruce Richardson * RCU QSBR configuration 19899a2dd95SBruce Richardson * @return 19999a2dd95SBruce Richardson * On success - 0 20099a2dd95SBruce Richardson * On error - 1 with error code set in rte_errno. 20199a2dd95SBruce Richardson * Possible rte_errno codes are: 20299a2dd95SBruce Richardson * - EINVAL - invalid pointer 20399a2dd95SBruce Richardson * - EEXIST - already added QSBR 20499a2dd95SBruce Richardson * - ENOMEM - memory allocation failure 20599a2dd95SBruce Richardson */ 20699a2dd95SBruce Richardson __rte_experimental 20799a2dd95SBruce Richardson int rte_lpm_rcu_qsbr_add(struct rte_lpm *lpm, struct rte_lpm_rcu_config *cfg); 20899a2dd95SBruce Richardson 20999a2dd95SBruce Richardson /** 21099a2dd95SBruce Richardson * Add a rule to the LPM table. 21199a2dd95SBruce Richardson * 21299a2dd95SBruce Richardson * @param lpm 21399a2dd95SBruce Richardson * LPM object handle 21499a2dd95SBruce Richardson * @param ip 21599a2dd95SBruce Richardson * IP of the rule to be added to the LPM table 21699a2dd95SBruce Richardson * @param depth 21799a2dd95SBruce Richardson * Depth of the rule to be added to the LPM table 21899a2dd95SBruce Richardson * @param next_hop 21999a2dd95SBruce Richardson * Next hop of the rule to be added to the LPM table 22099a2dd95SBruce Richardson * @return 22199a2dd95SBruce Richardson * 0 on success, negative value otherwise 22299a2dd95SBruce Richardson */ 22399a2dd95SBruce Richardson int 22499a2dd95SBruce Richardson rte_lpm_add(struct rte_lpm *lpm, uint32_t ip, uint8_t depth, uint32_t next_hop); 22599a2dd95SBruce Richardson 22699a2dd95SBruce Richardson /** 22799a2dd95SBruce Richardson * Check if a rule is present in the LPM table, 22899a2dd95SBruce Richardson * and provide its next hop if it is. 22999a2dd95SBruce Richardson * 23099a2dd95SBruce Richardson * @param lpm 23199a2dd95SBruce Richardson * LPM object handle 23299a2dd95SBruce Richardson * @param ip 23399a2dd95SBruce Richardson * IP of the rule to be searched 23499a2dd95SBruce Richardson * @param depth 23599a2dd95SBruce Richardson * Depth of the rule to searched 23699a2dd95SBruce Richardson * @param next_hop 23799a2dd95SBruce Richardson * Next hop of the rule (valid only if it is found) 23899a2dd95SBruce Richardson * @return 23999a2dd95SBruce Richardson * 1 if the rule exists, 0 if it does not, a negative value on failure 24099a2dd95SBruce Richardson */ 24199a2dd95SBruce Richardson int 24299a2dd95SBruce Richardson rte_lpm_is_rule_present(struct rte_lpm *lpm, uint32_t ip, uint8_t depth, 24399a2dd95SBruce Richardson uint32_t *next_hop); 24499a2dd95SBruce Richardson 24599a2dd95SBruce Richardson /** 24699a2dd95SBruce Richardson * Delete a rule from the LPM table. 24799a2dd95SBruce Richardson * 24899a2dd95SBruce Richardson * @param lpm 24999a2dd95SBruce Richardson * LPM object handle 25099a2dd95SBruce Richardson * @param ip 25199a2dd95SBruce Richardson * IP of the rule to be deleted from the LPM table 25299a2dd95SBruce Richardson * @param depth 25399a2dd95SBruce Richardson * Depth of the rule to be deleted from the LPM table 25499a2dd95SBruce Richardson * @return 25599a2dd95SBruce Richardson * 0 on success, negative value otherwise 25699a2dd95SBruce Richardson */ 25799a2dd95SBruce Richardson int 25899a2dd95SBruce Richardson rte_lpm_delete(struct rte_lpm *lpm, uint32_t ip, uint8_t depth); 25999a2dd95SBruce Richardson 26099a2dd95SBruce Richardson /** 26199a2dd95SBruce Richardson * Delete all rules from the LPM table. 26299a2dd95SBruce Richardson * 26399a2dd95SBruce Richardson * @param lpm 26499a2dd95SBruce Richardson * LPM object handle 26599a2dd95SBruce Richardson */ 26699a2dd95SBruce Richardson void 26799a2dd95SBruce Richardson rte_lpm_delete_all(struct rte_lpm *lpm); 26899a2dd95SBruce Richardson 26999a2dd95SBruce Richardson /** 27099a2dd95SBruce Richardson * Lookup an IP into the LPM table. 27199a2dd95SBruce Richardson * 27299a2dd95SBruce Richardson * @param lpm 27399a2dd95SBruce Richardson * LPM object handle 27499a2dd95SBruce Richardson * @param ip 27599a2dd95SBruce Richardson * IP to be looked up in the LPM table 27699a2dd95SBruce Richardson * @param next_hop 27799a2dd95SBruce Richardson * Next hop of the most specific rule found for IP (valid on lookup hit only) 27899a2dd95SBruce Richardson * @return 27999a2dd95SBruce Richardson * -EINVAL for incorrect arguments, -ENOENT on lookup miss, 0 on lookup hit 28099a2dd95SBruce Richardson */ 28199a2dd95SBruce Richardson static inline int 2824036de27SStanislaw Kardach rte_lpm_lookup(const struct rte_lpm *lpm, uint32_t ip, uint32_t *next_hop) 28399a2dd95SBruce Richardson { 28499a2dd95SBruce Richardson unsigned tbl24_index = (ip >> 8); 28599a2dd95SBruce Richardson uint32_t tbl_entry; 28699a2dd95SBruce Richardson const uint32_t *ptbl; 28799a2dd95SBruce Richardson 28899a2dd95SBruce Richardson /* DEBUG: Check user input arguments. */ 28999a2dd95SBruce Richardson RTE_LPM_RETURN_IF_TRUE(((lpm == NULL) || (next_hop == NULL)), -EINVAL); 29099a2dd95SBruce Richardson 29199a2dd95SBruce Richardson /* Copy tbl24 entry */ 29299a2dd95SBruce Richardson ptbl = (const uint32_t *)(&lpm->tbl24[tbl24_index]); 29399a2dd95SBruce Richardson tbl_entry = *ptbl; 29499a2dd95SBruce Richardson 29599a2dd95SBruce Richardson /* Memory ordering is not required in lookup. Because dataflow 29699a2dd95SBruce Richardson * dependency exists, compiler or HW won't be able to re-order 29799a2dd95SBruce Richardson * the operations. 29899a2dd95SBruce Richardson */ 29999a2dd95SBruce Richardson /* Copy tbl8 entry (only if needed) */ 30099a2dd95SBruce Richardson if (unlikely((tbl_entry & RTE_LPM_VALID_EXT_ENTRY_BITMASK) == 30199a2dd95SBruce Richardson RTE_LPM_VALID_EXT_ENTRY_BITMASK)) { 30299a2dd95SBruce Richardson 30399a2dd95SBruce Richardson unsigned tbl8_index = (uint8_t)ip + 30499a2dd95SBruce Richardson (((uint32_t)tbl_entry & 0x00FFFFFF) * 30599a2dd95SBruce Richardson RTE_LPM_TBL8_GROUP_NUM_ENTRIES); 30699a2dd95SBruce Richardson 30799a2dd95SBruce Richardson ptbl = (const uint32_t *)&lpm->tbl8[tbl8_index]; 30899a2dd95SBruce Richardson tbl_entry = *ptbl; 30999a2dd95SBruce Richardson } 31099a2dd95SBruce Richardson 31199a2dd95SBruce Richardson *next_hop = ((uint32_t)tbl_entry & 0x00FFFFFF); 31299a2dd95SBruce Richardson return (tbl_entry & RTE_LPM_LOOKUP_SUCCESS) ? 0 : -ENOENT; 31399a2dd95SBruce Richardson } 31499a2dd95SBruce Richardson 31599a2dd95SBruce Richardson /** 31699a2dd95SBruce Richardson * Lookup multiple IP addresses in an LPM table. This may be implemented as a 31799a2dd95SBruce Richardson * macro, so the address of the function should not be used. 31899a2dd95SBruce Richardson * 31999a2dd95SBruce Richardson * @param lpm 32099a2dd95SBruce Richardson * LPM object handle 32199a2dd95SBruce Richardson * @param ips 32299a2dd95SBruce Richardson * Array of IPs to be looked up in the LPM table 32399a2dd95SBruce Richardson * @param next_hops 32499a2dd95SBruce Richardson * Next hop of the most specific rule found for IP (valid on lookup hit only). 32599a2dd95SBruce Richardson * This is an array of two byte values. The most significant byte in each 32699a2dd95SBruce Richardson * value says whether the lookup was successful (bitmask 32799a2dd95SBruce Richardson * RTE_LPM_LOOKUP_SUCCESS is set). The least significant byte is the 32899a2dd95SBruce Richardson * actual next hop. 32999a2dd95SBruce Richardson * @param n 33099a2dd95SBruce Richardson * Number of elements in ips (and next_hops) array to lookup. This should be a 33199a2dd95SBruce Richardson * compile time constant, and divisible by 8 for best performance. 33299a2dd95SBruce Richardson * @return 33399a2dd95SBruce Richardson * -EINVAL for incorrect arguments, otherwise 0 33499a2dd95SBruce Richardson */ 33599a2dd95SBruce Richardson #define rte_lpm_lookup_bulk(lpm, ips, next_hops, n) \ 33699a2dd95SBruce Richardson rte_lpm_lookup_bulk_func(lpm, ips, next_hops, n) 33799a2dd95SBruce Richardson 33899a2dd95SBruce Richardson static inline int 33999a2dd95SBruce Richardson rte_lpm_lookup_bulk_func(const struct rte_lpm *lpm, const uint32_t *ips, 34099a2dd95SBruce Richardson uint32_t *next_hops, const unsigned n) 34199a2dd95SBruce Richardson { 34299a2dd95SBruce Richardson unsigned i; 34399a2dd95SBruce Richardson unsigned tbl24_indexes[n]; 34499a2dd95SBruce Richardson const uint32_t *ptbl; 34599a2dd95SBruce Richardson 34699a2dd95SBruce Richardson /* DEBUG: Check user input arguments. */ 34799a2dd95SBruce Richardson RTE_LPM_RETURN_IF_TRUE(((lpm == NULL) || (ips == NULL) || 34899a2dd95SBruce Richardson (next_hops == NULL)), -EINVAL); 34999a2dd95SBruce Richardson 35099a2dd95SBruce Richardson for (i = 0; i < n; i++) { 35199a2dd95SBruce Richardson tbl24_indexes[i] = ips[i] >> 8; 35299a2dd95SBruce Richardson } 35399a2dd95SBruce Richardson 35499a2dd95SBruce Richardson for (i = 0; i < n; i++) { 35599a2dd95SBruce Richardson /* Simply copy tbl24 entry to output */ 35699a2dd95SBruce Richardson ptbl = (const uint32_t *)&lpm->tbl24[tbl24_indexes[i]]; 35799a2dd95SBruce Richardson next_hops[i] = *ptbl; 35899a2dd95SBruce Richardson 35999a2dd95SBruce Richardson /* Overwrite output with tbl8 entry if needed */ 36099a2dd95SBruce Richardson if (unlikely((next_hops[i] & RTE_LPM_VALID_EXT_ENTRY_BITMASK) == 36199a2dd95SBruce Richardson RTE_LPM_VALID_EXT_ENTRY_BITMASK)) { 36299a2dd95SBruce Richardson 36399a2dd95SBruce Richardson unsigned tbl8_index = (uint8_t)ips[i] + 36499a2dd95SBruce Richardson (((uint32_t)next_hops[i] & 0x00FFFFFF) * 36599a2dd95SBruce Richardson RTE_LPM_TBL8_GROUP_NUM_ENTRIES); 36699a2dd95SBruce Richardson 36799a2dd95SBruce Richardson ptbl = (const uint32_t *)&lpm->tbl8[tbl8_index]; 36899a2dd95SBruce Richardson next_hops[i] = *ptbl; 36999a2dd95SBruce Richardson } 37099a2dd95SBruce Richardson } 37199a2dd95SBruce Richardson return 0; 37299a2dd95SBruce Richardson } 37399a2dd95SBruce Richardson 37499a2dd95SBruce Richardson /* Mask four results. */ 37599a2dd95SBruce Richardson #define RTE_LPM_MASKX4_RES UINT64_C(0x00ffffff00ffffff) 37699a2dd95SBruce Richardson 37799a2dd95SBruce Richardson /** 37899a2dd95SBruce Richardson * Lookup four IP addresses in an LPM table. 37999a2dd95SBruce Richardson * 38099a2dd95SBruce Richardson * @param lpm 38199a2dd95SBruce Richardson * LPM object handle 38299a2dd95SBruce Richardson * @param ip 38399a2dd95SBruce Richardson * Four IPs to be looked up in the LPM table 38499a2dd95SBruce Richardson * @param hop 38599a2dd95SBruce Richardson * Next hop of the most specific rule found for IP (valid on lookup hit only). 38699a2dd95SBruce Richardson * This is an 4 elements array of two byte values. 38799a2dd95SBruce Richardson * If the lookup was successful for the given IP, then least significant byte 38899a2dd95SBruce Richardson * of the corresponding element is the actual next hop and the most 38999a2dd95SBruce Richardson * significant byte is zero. 39099a2dd95SBruce Richardson * If the lookup for the given IP failed, then corresponding element would 39199a2dd95SBruce Richardson * contain default value, see description of then next parameter. 39299a2dd95SBruce Richardson * @param defv 39399a2dd95SBruce Richardson * Default value to populate into corresponding element of hop[] array, 39499a2dd95SBruce Richardson * if lookup would fail. 39599a2dd95SBruce Richardson */ 39699a2dd95SBruce Richardson static inline void 39799a2dd95SBruce Richardson rte_lpm_lookupx4(const struct rte_lpm *lpm, xmm_t ip, uint32_t hop[4], 39899a2dd95SBruce Richardson uint32_t defv); 39999a2dd95SBruce Richardson 40099a2dd95SBruce Richardson #if defined(RTE_ARCH_ARM) 4015aa9189dSChengwen Feng #ifdef RTE_HAS_SVE_ACLE 40299a2dd95SBruce Richardson #include "rte_lpm_sve.h" 403*b29ccbeaSRuifeng Wang #undef rte_lpm_lookup_bulk 404*b29ccbeaSRuifeng Wang #define rte_lpm_lookup_bulk(lpm, ips, next_hops, n) \ 405*b29ccbeaSRuifeng Wang __rte_lpm_lookup_vec(lpm, ips, next_hops, n) 40699a2dd95SBruce Richardson #endif 407*b29ccbeaSRuifeng Wang #include "rte_lpm_neon.h" 40899a2dd95SBruce Richardson #elif defined(RTE_ARCH_PPC_64) 40999a2dd95SBruce Richardson #include "rte_lpm_altivec.h" 410406937f8SMichal Mazurek #elif defined(RTE_ARCH_X86) 41199a2dd95SBruce Richardson #include "rte_lpm_sse.h" 412406937f8SMichal Mazurek #else 413406937f8SMichal Mazurek #include "rte_lpm_scalar.h" 41499a2dd95SBruce Richardson #endif 41599a2dd95SBruce Richardson 41699a2dd95SBruce Richardson #ifdef __cplusplus 41799a2dd95SBruce Richardson } 41899a2dd95SBruce Richardson #endif 41999a2dd95SBruce Richardson 42099a2dd95SBruce Richardson #endif /* _RTE_LPM_H_ */ 421