numam-dpdk/lib/fib/trie.h
Bruce Richardson 99a2dd955f lib: remove librte_ prefix from directory names
There is no reason for the DPDK libraries to all have 'librte_' prefix on
the directory names. This prefix makes the directory names longer and also
makes it awkward to add features referring to individual libraries in the
build - should the lib names be specified with or without the prefix.
Therefore, we can just remove the library prefix and use the library's
unique name as the directory name, i.e. 'eal' rather than 'librte_eal'

Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
2021-04-21 14:04:09 +02:00

154 lines
3.7 KiB
C

/* SPDX-License-Identifier: BSD-3-Clause
* Copyright(c) 2018 Vladimir Medvedkin <medvedkinv@gmail.com>
* Copyright(c) 2019 Intel Corporation
*/
#ifndef _TRIE_H_
#define _TRIE_H_
/**
* @file
* RTE IPv6 Longest Prefix Match (LPM)
*/
#include <rte_prefetch.h>
#include <rte_branch_prediction.h>
#ifdef __cplusplus
extern "C" {
#endif
/* @internal Total number of tbl24 entries. */
#define TRIE_TBL24_NUM_ENT (1 << 24)
/* Maximum depth value possible for IPv6 LPM. */
#define TRIE_MAX_DEPTH 128
/* @internal Number of entries in a tbl8 group. */
#define TRIE_TBL8_GRP_NUM_ENT 256ULL
/* @internal Total number of tbl8 groups in the tbl8. */
#define TRIE_TBL8_NUM_GROUPS 65536
/* @internal bitmask with valid and valid_group fields set */
#define TRIE_EXT_ENT 1
#define BITMAP_SLAB_BIT_SIZE_LOG2 6
#define BITMAP_SLAB_BIT_SIZE (1ULL << BITMAP_SLAB_BIT_SIZE_LOG2)
#define BITMAP_SLAB_BITMASK (BITMAP_SLAB_BIT_SIZE - 1)
struct rte_trie_tbl {
uint32_t number_tbl8s; /**< Total number of tbl8s */
uint32_t rsvd_tbl8s; /**< Number of reserved tbl8s */
uint32_t cur_tbl8s; /**< Current cumber of tbl8s */
uint64_t def_nh; /**< Default next hop */
enum rte_fib_trie_nh_sz nh_sz; /**< Size of nexthop entry */
uint64_t *tbl8; /**< tbl8 table. */
uint32_t *tbl8_pool; /**< bitmap containing free tbl8 idxes*/
uint32_t tbl8_pool_pos;
/* tbl24 table. */
__extension__ uint64_t tbl24[0] __rte_cache_aligned;
};
static inline uint32_t
get_tbl24_idx(const uint8_t *ip)
{
return ip[0] << 16|ip[1] << 8|ip[2];
}
static inline void *
get_tbl24_p(struct rte_trie_tbl *dp, const uint8_t *ip, uint8_t nh_sz)
{
uint32_t tbl24_idx;
tbl24_idx = get_tbl24_idx(ip);
return (void *)&((uint8_t *)dp->tbl24)[tbl24_idx << nh_sz];
}
static inline uint8_t
bits_in_nh(uint8_t nh_sz)
{
return 8 * (1 << nh_sz);
}
static inline uint64_t
get_max_nh(uint8_t nh_sz)
{
return ((1ULL << (bits_in_nh(nh_sz) - 1)) - 1);
}
static inline uint64_t
lookup_msk(uint8_t nh_sz)
{
return ((1ULL << ((1 << (nh_sz + 3)) - 1)) << 1) - 1;
}
static inline uint8_t
get_psd_idx(uint32_t val, uint8_t nh_sz)
{
return val & ((1 << (3 - nh_sz)) - 1);
}
static inline uint32_t
get_tbl_pos(uint32_t val, uint8_t nh_sz)
{
return val >> (3 - nh_sz);
}
static inline uint64_t
get_tbl_val_by_idx(uint64_t *tbl, uint32_t idx, uint8_t nh_sz)
{
return ((tbl[get_tbl_pos(idx, nh_sz)] >> (get_psd_idx(idx, nh_sz) *
bits_in_nh(nh_sz))) & lookup_msk(nh_sz));
}
static inline void *
get_tbl_p_by_idx(uint64_t *tbl, uint64_t idx, uint8_t nh_sz)
{
return (uint8_t *)tbl + (idx << nh_sz);
}
static inline int
is_entry_extended(uint64_t ent)
{
return (ent & TRIE_EXT_ENT) == TRIE_EXT_ENT;
}
#define LOOKUP_FUNC(suffix, type, nh_sz) \
static inline void rte_trie_lookup_bulk_##suffix(void *p, \
uint8_t ips[][RTE_FIB6_IPV6_ADDR_SIZE], \
uint64_t *next_hops, const unsigned int n) \
{ \
struct rte_trie_tbl *dp = (struct rte_trie_tbl *)p; \
uint64_t tmp; \
uint32_t i, j; \
\
for (i = 0; i < n; i++) { \
tmp = ((type *)dp->tbl24)[get_tbl24_idx(&ips[i][0])]; \
j = 3; \
while (is_entry_extended(tmp)) { \
tmp = ((type *)dp->tbl8)[ips[i][j++] + \
((tmp >> 1) * TRIE_TBL8_GRP_NUM_ENT)]; \
} \
next_hops[i] = tmp >> 1; \
} \
}
LOOKUP_FUNC(2b, uint16_t, 1)
LOOKUP_FUNC(4b, uint32_t, 2)
LOOKUP_FUNC(8b, uint64_t, 3)
void *
trie_create(const char *name, int socket_id, struct rte_fib6_conf *conf);
void
trie_free(void *p);
rte_fib6_lookup_fn_t
trie_get_lookup_fn(void *p, enum rte_fib6_lookup_type type);
int
trie_modify(struct rte_fib6 *fib, const uint8_t ip[RTE_FIB6_IPV6_ADDR_SIZE],
uint8_t depth, uint64_t next_hop, int op);
#ifdef __cplusplus
}
#endif
#endif /* _TRIE_H_ */