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