15 #include <odp/helper/odph_api.h>
17 #include <odp_l3fwd_lpm.h>
31 #define FIB_IP_WIDTH 32
32 #define FIB_FIRST_STRIDE 16
33 #define FIB_NEXT_STRIDE 4
34 #define FIB_NEXT_SIZE (1 << FIB_NEXT_STRIDE)
35 #define FIB_SUB_COUNT 16384
36 #define DEPTH_TO_MASK(depth) ((1 << (depth)) - 1)
38 typedef struct fib_node_s {
41 struct fib_node_s *next;
48 typedef struct fib_sub_tbl_s {
49 fib_node_t *fib_nodes;
54 static fib_node_t fib_rt_tbl[1 << FIB_FIRST_STRIDE];
55 static fib_sub_tbl_t fib_lpm_cache;
57 static inline fib_node_t *fib_alloc_sub(
void)
59 fib_node_t *sub_tbl = NULL;
63 if (fib_lpm_cache.fib_idx < fib_lpm_cache.fib_count) {
64 nb_entry = (fib_lpm_cache.fib_idx + 1) * FIB_NEXT_SIZE;
65 sub_tbl = &fib_lpm_cache.fib_nodes[nb_entry];
66 fib_lpm_cache.fib_idx++;
67 for (i = 0; i < nb_entry; i++) {
76 static void fib_update_node(fib_node_t *fe,
int port,
int depth)
86 }
else if (fe->depth <= depth) {
94 for (i = 0; i < FIB_NEXT_SIZE; i++) {
97 fib_update_node(p, port, depth);
101 static void fib_insert_node(fib_node_t *fe, uint32_t ip, uint32_t next_hop,
102 int ip_width,
int eat_bits,
int depth)
117 for (i = 0; i < FIB_NEXT_SIZE; i++) {
120 p->depth = fe->depth;
124 if (depth - eat_bits <= FIB_NEXT_STRIDE) {
125 ip_width -= depth - eat_bits;
126 idx = ip >> ip_width;
127 ip &= DEPTH_TO_MASK(ip_width);
129 fib_update_node(p, next_hop, depth);
131 ip_width -= FIB_NEXT_STRIDE;
132 idx = ip >> ip_width;
134 ip &= DEPTH_TO_MASK(ip_width);
135 eat_bits += FIB_NEXT_STRIDE;
136 fib_insert_node(p, ip, next_hop, ip_width, eat_bits, depth);
140 void fib_tbl_init(
void)
147 for (i = 0; i < (1 << FIB_FIRST_STRIDE); i++) {
155 size = FIB_NEXT_SIZE * FIB_SUB_COUNT;
157 lpm_shm =
odp_shm_reserve(
"fib_lpm_sub", size, ODP_CACHE_LINE_SIZE, 0);
159 ODPH_ERR(
"Error: shared mem reserve failed.\n");
165 ODPH_ERR(
"Error: shared mem alloc failed for lpm cache.\n");
169 fib_lpm_cache.fib_nodes = fe;
170 fib_lpm_cache.fib_count = FIB_SUB_COUNT;
171 fib_lpm_cache.fib_idx = 0;
174 void fib_tbl_insert(uint32_t ip,
int port,
int depth)
181 nb_bits = FIB_FIRST_STRIDE;
182 idx = ip >> (FIB_IP_WIDTH - nb_bits);
183 fe = &fib_rt_tbl[idx];
184 if (depth <= nb_bits) {
192 for (i = 0; i < FIB_NEXT_SIZE; i++) {
195 fib_update_node(p, port, depth);
197 for (j = 0; j < FIB_NEXT_SIZE; j++)
198 fib_update_node(&p->next[j], port,
206 ip &= DEPTH_TO_MASK(FIB_IP_WIDTH - nb_bits);
207 fib_insert_node(fe, ip, port, FIB_IP_WIDTH - nb_bits, nb_bits, depth);
210 int fib_tbl_lookup(uint32_t ip,
int *port)
216 nb_bits = FIB_IP_WIDTH - FIB_FIRST_STRIDE;
218 fe = &fib_rt_tbl[idx];
220 ip &= DEPTH_TO_MASK(nb_bits);
222 nb_bits -= FIB_NEXT_STRIDE;
225 ip &= DEPTH_TO_MASK(nb_bits);
227 *port = fe->next_hop;
229 return fe->valid ? 0 : -1;
#define ODP_SHM_INVALID
Invalid shared memory block.
void * odp_shm_addr(odp_shm_t shm)
Shared memory block address.
odp_shm_t odp_shm_reserve(const char *name, uint64_t size, uint64_t align, uint32_t flags)
Reserve a contiguous block of shared memory.