CNDP  22.08.0
cnet_fib_info.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright (c) 2016-2022 Intel Corporation
3  */
4 
5 #ifndef __CNET_FIB_INFO_H
6 #define __CNET_FIB_INFO_H
7 
13 #include <stddef.h> // for NULL
14 #include <stdint.h> // for uint8_t, uint32_t
15 #include <sys/queue.h> // for TAILQ_HEAD
16 #include <bsd/sys/queue.h> // for TAILQ_HEAD
17 
18 #include <cne_rwlock.h>
19 #include <cne_fib.h>
20 
21 struct rt4_entry;
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25 
26 typedef struct fib_info {
27  struct cne_fib *fib;
28  void **idx2obj;
29  cne_rwlock_t lock;
30  uint32_t objcnt;
31  uint32_t mask;
32  uint32_t index_shift;
33  uint32_t index;
34 } fib_info_t;
35 
46 static inline uint32_t
47 fi_obj_index(fib_info_t *fi, uint32_t idx)
48 {
49  uint32_t obj_idx = UINT32_MAX;
50 
51  if (fi)
52  obj_idx = (idx & ((1UL << fi->index_shift) - 1));
53 
54  return obj_idx;
55 }
56 
68 static inline int
69 fib_info_alloc(fib_info_t *fi, void *obj)
70 {
71  uint32_t idx, prev_idx;
72 
73  cne_rwlock_write_lock(&fi->lock);
74  idx = prev_idx = fi->index;
75 
76  prev_idx--;
77  prev_idx = (prev_idx & fi->mask);
78  while (fi->idx2obj[idx] && (idx != prev_idx)) {
79  idx++;
80  idx = (idx & fi->mask);
81  }
82 
83  if (idx == prev_idx) {
84  cne_rwlock_write_unlock(&fi->lock);
85  return -1;
86  }
87 
88  fi->idx2obj[idx] = obj;
89  fi->index = idx;
90  cne_rwlock_write_unlock(&fi->lock);
91 
92  return idx;
93 }
94 
105 static inline void *
106 fib_info_free(fib_info_t *fi, uint32_t idx)
107 {
108  void *obj = NULL;
109 
110  cne_rwlock_write_lock(&fi->lock);
111 
112  idx = fi_obj_index(fi, idx);
113 
114  if (idx < fi->objcnt) {
115  obj = fi->idx2obj[idx];
116 
117  fi->idx2obj[idx] = NULL;
118  }
119  cne_rwlock_write_unlock(&fi->lock);
120  return obj;
121 }
122 
129 static inline void
130 fib_info_destroy(fib_info_t *fi)
131 {
132  if (fi) {
133  if (fi->idx2obj)
134  free(fi->idx2obj);
135  if (fi->fib)
136  cne_fib_free(fi->fib);
137  free(fi);
138  }
139 }
140 
156 static inline fib_info_t *
157 fib_info_create(struct cne_fib *fib, uint32_t objcnt, uint32_t index_shift)
158 {
159  fib_info_t *fi;
160 
161  if (!fib || objcnt == 0 || index_shift == 0)
162  return NULL;
163 
164  fi = calloc(1, sizeof(fib_info_t));
165  if (fi) {
166  fi->fib = fib;
167  fi->objcnt = cne_align32pow2(objcnt);
168  fi->mask = fi->objcnt - 1;
169  fi->index_shift = index_shift;
170  cne_rwlock_init(&fi->lock);
171 
172  fi->idx2obj = calloc(fi->objcnt, sizeof(void *));
173  if (!fi->idx2obj) {
174  fib_info_destroy(fi);
175  return NULL;
176  }
177  }
178 
179  return fi;
180 }
181 
192 static inline void *
193 fib_info_object_get(fib_info_t *fi, uint32_t idx)
194 {
195  if (!fi)
196  return NULL;
197 
198  idx = fi_obj_index(fi, idx);
199 
200  if (idx >= fi->objcnt)
201  return NULL;
202 
203  return fi->idx2obj[idx];
204 }
205 
216 static inline int
217 fib_info_index_valid(fib_info_t *fi, uint32_t idx)
218 {
219  idx = fi_obj_index(fi, idx);
220 
221  if (fi && (idx < fi->objcnt))
222  return 1;
223 
224  return 0;
225 }
226 
235 static inline struct cne_fib *
236 fib_info_get_fib(fib_info_t *fi)
237 {
238  return (fi) ? fi->fib : NULL;
239 }
240 
241 typedef int (*fib_func_t)(void *obj, void *arg);
242 
255 static inline int
256 fib_info_foreach(fib_info_t *fi, fib_func_t func, void *arg)
257 {
258  if (fi) {
259  for (uint32_t i = 0; i < fi->objcnt; i++) {
260  void *obj = fib_info_object_get(fi, i);
261 
262  if (obj && (func(obj, arg) < 0))
263  return -1;
264  }
265  }
266  return 0;
267 }
268 
283 static inline int
284 fib_info_get(fib_info_t *fi, uint64_t *idxs, void **objs, int n)
285 {
286  void *objects[n];
287  int i, k;
288 
289  if (!fi || !idxs)
290  return -1;
291 
292  if (!objs)
293  objs = objects;
294 
295  memset(objs, 0, sizeof(void *) * n);
296 
297  for (i = 0, k = 0; i < n; i++) {
298  objs[i] = fib_info_object_get(fi, (uint32_t)idxs[i]);
299 
300  if (objs[i])
301  k++;
302  }
303  return k;
304 }
305 
320 static inline int
321 fib_info_lookup(fib_info_t *fi, uint32_t *ip, void **objs, int n)
322 {
323  if (fi && ip) {
324  uint64_t nh[n];
325 
326  if (cne_fib_lookup_bulk(fi->fib, ip, nh, n) == 0)
327  return fib_info_get(fi, nh, objs, n);
328  }
329  return 0;
330 }
331 
346 static inline int
347 fib_info_lookup_index(fib_info_t *fi, uint32_t *ip, uint64_t *idxs, int n)
348 {
349  if (!fi || !ip || !idxs)
350  return -1;
351  return cne_fib_lookup_bulk(fi->fib, ip, idxs, n) == 0;
352 }
353 
354 #ifdef __cplusplus
355 }
356 #endif
357 
358 #endif /* __CNET_FIB_INFO_H */
static uint32_t cne_align32pow2(uint32_t x)
Definition: cne_common.h:485
int cne_fib_lookup_bulk(struct cne_fib *fib, uint32_t *ips, uint64_t *next_hops, int n)
void cne_fib_free(struct cne_fib *fib)
static void cne_rwlock_write_unlock(cne_rwlock_t *rwl)
Definition: cne_rwlock.h:176
static void cne_rwlock_init(cne_rwlock_t *rwl)
Definition: cne_rwlock.h:53
static void cne_rwlock_write_lock(cne_rwlock_t *rwl)
Definition: cne_rwlock.h:152
static int fib_info_get(fib_info_t *fi, uint64_t *idxs, void **objs, int n)
static void * fib_info_object_get(fib_info_t *fi, uint32_t idx)
static int fib_info_alloc(fib_info_t *fi, void *obj)
Definition: cnet_fib_info.h:69
static int fib_info_foreach(fib_info_t *fi, fib_func_t func, void *arg)
static void * fib_info_free(fib_info_t *fi, uint32_t idx)
static fib_info_t * fib_info_create(struct cne_fib *fib, uint32_t objcnt, uint32_t index_shift)
static uint32_t fi_obj_index(fib_info_t *fi, uint32_t idx)
Definition: cnet_fib_info.h:47
static int fib_info_index_valid(fib_info_t *fi, uint32_t idx)
static int fib_info_lookup(fib_info_t *fi, uint32_t *ip, void **objs, int n)
static struct cne_fib * fib_info_get_fib(fib_info_t *fi)
static void fib_info_destroy(fib_info_t *fi)
static int fib_info_lookup_index(fib_info_t *fi, uint32_t *ip, uint64_t *idxs, int n)