/** @internal Number of entries in a tbl8 group. */
#define RTE_LPM_TBL8_GROUP_NUM_ENTRIES 256
+/** @internal Max number of tbl8 groups in the tbl8. */
+#define RTE_LPM_MAX_TBL8_NUM_GROUPS (1 << 24)
+
/** @internal Total number of tbl8 groups in the tbl8. */
#define RTE_LPM_TBL8_NUM_GROUPS 256
#if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
/** @internal Tbl24 entry structure. */
+__extension__
struct rte_lpm_tbl_entry_v20 {
/**
* Stores Next hop (tbl8 or tbl24 when valid_group is not set) or
* a group index pointing to a tbl8 structure (tbl24 only, when
* valid_group is set)
*/
+ RTE_STD_C11
union {
uint8_t next_hop;
uint8_t group_idx;
uint8_t depth :6; /**< Rule depth. */
};
+__extension__
struct rte_lpm_tbl_entry {
/**
* Stores Next hop (tbl8 or tbl24 when valid_group is not set) or
};
#else
+__extension__
struct rte_lpm_tbl_entry_v20 {
uint8_t depth :6;
uint8_t valid_group :1;
};
};
+__extension__
struct rte_lpm_tbl_entry {
uint32_t depth :6;
uint32_t valid_group :1;
#endif
+/** LPM configuration structure. */
+struct rte_lpm_config {
+ uint32_t max_rules; /**< Max number of rules. */
+ uint32_t number_tbl8s; /**< Number of tbl8s to allocate. */
+ int flags; /**< This field is currently unused. */
+};
+
/** @internal Rule structure. */
struct rte_lpm_rule_v20 {
uint32_t ip; /**< Rule IP address. */
__rte_cache_aligned; /**< LPM tbl24 table. */
struct rte_lpm_tbl_entry_v20 tbl8[RTE_LPM_TBL8_NUM_ENTRIES]
__rte_cache_aligned; /**< LPM tbl8 table. */
- struct rte_lpm_rule_v20 rules_tbl[0] \
+ struct rte_lpm_rule_v20 rules_tbl[]
__rte_cache_aligned; /**< LPM rules. */
};
/* LPM metadata. */
char name[RTE_LPM_NAMESIZE]; /**< Name of the lpm. */
uint32_t max_rules; /**< Max. balanced rules per lpm. */
+ uint32_t number_tbl8s; /**< Number of tbl8s. */
struct rte_lpm_rule_info rule_info[RTE_LPM_MAX_DEPTH]; /**< Rule info table. */
/* LPM Tables. */
struct rte_lpm_tbl_entry tbl24[RTE_LPM_TBL24_NUM_ENTRIES]
__rte_cache_aligned; /**< LPM tbl24 table. */
- struct rte_lpm_tbl_entry tbl8[RTE_LPM_TBL8_NUM_ENTRIES]
- __rte_cache_aligned; /**< LPM tbl8 table. */
- struct rte_lpm_rule rules_tbl[0] \
- __rte_cache_aligned; /**< LPM rules. */
+ struct rte_lpm_tbl_entry *tbl8; /**< LPM tbl8 table. */
+ struct rte_lpm_rule *rules_tbl; /**< LPM rules. */
};
/**
* LPM object name
* @param socket_id
* NUMA socket ID for LPM table memory allocation
- * @param max_rules
- * Maximum number of LPM rules that can be added
- * @param flags
- * This parameter is currently unused
+ * @param config
+ * Structure containing the configuration
* @return
* Handle to LPM object on success, NULL otherwise with rte_errno set
* to an appropriate values. Possible rte_errno values include:
* - ENOMEM - no appropriate memory area found in which to create memzone
*/
struct rte_lpm *
-rte_lpm_create(const char *name, int socket_id, int max_rules, int flags);
+rte_lpm_create(const char *name, int socket_id,
+ const struct rte_lpm_config *config);
struct rte_lpm_v20 *
rte_lpm_create_v20(const char *name, int socket_id, int max_rules, int flags);
struct rte_lpm *
-rte_lpm_create_v1604(const char *name, int socket_id, int max_rules, int flags);
+rte_lpm_create_v1604(const char *name, int socket_id,
+ const struct rte_lpm_config *config);
/**
* Find an existing LPM object and return a pointer to it.
* if lookup would fail.
*/
static inline void
-rte_lpm_lookupx4(const struct rte_lpm *lpm, __m128i ip, uint32_t hop[4],
- uint32_t defv)
-{
- __m128i i24;
- rte_xmm_t i8;
- uint32_t tbl[4];
- uint64_t idx, pt, pt2;
- const uint32_t *ptbl;
-
- const __m128i mask8 =
- _mm_set_epi32(UINT8_MAX, UINT8_MAX, UINT8_MAX, UINT8_MAX);
-
- /*
- * RTE_LPM_VALID_EXT_ENTRY_BITMASK for 2 LPM entries
- * as one 64-bit value (0x0300000003000000).
- */
- const uint64_t mask_xv =
- ((uint64_t)RTE_LPM_VALID_EXT_ENTRY_BITMASK |
- (uint64_t)RTE_LPM_VALID_EXT_ENTRY_BITMASK << 32);
-
- /*
- * RTE_LPM_LOOKUP_SUCCESS for 2 LPM entries
- * as one 64-bit value (0x0100000001000000).
- */
- const uint64_t mask_v =
- ((uint64_t)RTE_LPM_LOOKUP_SUCCESS |
- (uint64_t)RTE_LPM_LOOKUP_SUCCESS << 32);
-
- /* get 4 indexes for tbl24[]. */
- i24 = _mm_srli_epi32(ip, CHAR_BIT);
-
- /* extract values from tbl24[] */
- idx = _mm_cvtsi128_si64(i24);
- i24 = _mm_srli_si128(i24, sizeof(uint64_t));
-
- ptbl = (const uint32_t *)&lpm->tbl24[(uint32_t)idx];
- tbl[0] = *ptbl;
- ptbl = (const uint32_t *)&lpm->tbl24[idx >> 32];
- tbl[1] = *ptbl;
-
- idx = _mm_cvtsi128_si64(i24);
-
- ptbl = (const uint32_t *)&lpm->tbl24[(uint32_t)idx];
- tbl[2] = *ptbl;
- ptbl = (const uint32_t *)&lpm->tbl24[idx >> 32];
- tbl[3] = *ptbl;
-
- /* get 4 indexes for tbl8[]. */
- i8.x = _mm_and_si128(ip, mask8);
-
- pt = (uint64_t)tbl[0] |
- (uint64_t)tbl[1] << 32;
- pt2 = (uint64_t)tbl[2] |
- (uint64_t)tbl[3] << 32;
-
- /* search successfully finished for all 4 IP addresses. */
- if (likely((pt & mask_xv) == mask_v) &&
- likely((pt2 & mask_xv) == mask_v)) {
- *(uint64_t *)hop = pt & RTE_LPM_MASKX4_RES;
- *(uint64_t *)(hop + 2) = pt2 & RTE_LPM_MASKX4_RES;
- return;
- }
+rte_lpm_lookupx4(const struct rte_lpm *lpm, xmm_t ip, uint32_t hop[4],
+ uint32_t defv);
- if (unlikely((pt & RTE_LPM_VALID_EXT_ENTRY_BITMASK) ==
- RTE_LPM_VALID_EXT_ENTRY_BITMASK)) {
- i8.u32[0] = i8.u32[0] +
- (uint8_t)tbl[0] * RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
- ptbl = (const uint32_t *)&lpm->tbl8[i8.u32[0]];
- tbl[0] = *ptbl;
- }
- if (unlikely((pt >> 32 & RTE_LPM_VALID_EXT_ENTRY_BITMASK) ==
- RTE_LPM_VALID_EXT_ENTRY_BITMASK)) {
- i8.u32[1] = i8.u32[1] +
- (uint8_t)tbl[1] * RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
- ptbl = (const uint32_t *)&lpm->tbl8[i8.u32[1]];
- tbl[1] = *ptbl;
- }
- if (unlikely((pt2 & RTE_LPM_VALID_EXT_ENTRY_BITMASK) ==
- RTE_LPM_VALID_EXT_ENTRY_BITMASK)) {
- i8.u32[2] = i8.u32[2] +
- (uint8_t)tbl[2] * RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
- ptbl = (const uint32_t *)&lpm->tbl8[i8.u32[2]];
- tbl[2] = *ptbl;
- }
- if (unlikely((pt2 >> 32 & RTE_LPM_VALID_EXT_ENTRY_BITMASK) ==
- RTE_LPM_VALID_EXT_ENTRY_BITMASK)) {
- i8.u32[3] = i8.u32[3] +
- (uint8_t)tbl[3] * RTE_LPM_TBL8_GROUP_NUM_ENTRIES;
- ptbl = (const uint32_t *)&lpm->tbl8[i8.u32[3]];
- tbl[3] = *ptbl;
- }
-
- hop[0] = (tbl[0] & RTE_LPM_LOOKUP_SUCCESS) ? tbl[0] & 0x00FFFFFF : defv;
- hop[1] = (tbl[1] & RTE_LPM_LOOKUP_SUCCESS) ? tbl[1] & 0x00FFFFFF : defv;
- hop[2] = (tbl[2] & RTE_LPM_LOOKUP_SUCCESS) ? tbl[2] & 0x00FFFFFF : defv;
- hop[3] = (tbl[3] & RTE_LPM_LOOKUP_SUCCESS) ? tbl[3] & 0x00FFFFFF : defv;
-}
+#if defined(RTE_ARCH_ARM) || defined(RTE_ARCH_ARM64)
+#include "rte_lpm_neon.h"
+#elif defined(RTE_ARCH_PPC_64)
+#include "rte_lpm_altivec.h"
+#else
+#include "rte_lpm_sse.h"
+#endif
#ifdef __cplusplus
}