FD.io VPP  v19.04-6-g6f05f72
Vector Packet Processing
bier_disp_table.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
18 
19 /**
20  * memory pool for disposition tables
21  */
23 
24 /**
25  * Hash table to map client table IDs to VPP index
26  */
28 
29 static index_t
31 {
32  return (bdt - bier_disp_table_pool);
33 }
34 
35 static void
37 {
38  bdt->bdt_locks++;
39 }
40 
41 index_t
43 {
44  uword *p;
45 
47 
48  if (NULL != p)
49  {
50  return (p[0]);
51  }
52 
53  return (INDEX_INVALID);
54 }
55 
56 index_t
58 {
59  bier_disp_table_t *bdt;
60  index_t bdti;
61 
62  bdti = bier_disp_table_find(table_id);
63 
64  if (INDEX_INVALID == bdti)
65  {
66  pool_get_aligned(bier_disp_table_pool, bdt,
68 
69  bdt->bdt_table_id = table_id;
70  bdt->bdt_locks = 0;
71 
74 
75  /**
76  * Set the result for each entry in the DB to be invalid
77  */
78  clib_memset(bdt->bdt_db, 0xff, sizeof(bdt->bdt_db));
79  }
80  else
81  {
82  bdt = pool_elt_at_index(bier_disp_table_pool, bdti);
83  }
84 
86 
87  return (bier_disp_table_get_index(bdt));
88 }
89 
90 void
92 {
93  index_t bdti;
94 
95  bdti = bier_disp_table_find(table_id);
96 
97  if (INDEX_INVALID != bdti)
98  {
100  }
101 }
102 
103 void
105 {
106  bier_disp_table_t *bdt;
107 
108  bdt = bier_disp_table_get(bdti);
109 
110  bdt->bdt_locks--;
111 
112  if (0 == bdt->bdt_locks)
113  {
114  u32 ii;
115 
116  for (ii = 0; ii < BIER_BP_MAX; ii++)
117  {
118  bier_disp_entry_unlock(bdt->bdt_db[ii]);
119  }
121  pool_put(bier_disp_table_pool, bdt);
122  }
123 }
124 
125 void
127 {
129 }
130 
131 void
133  dpo_id_t *dpo)
134 {
135  dpo_set(dpo,
138  bdti);
139 }
140 
141 
142 u8*
143 format_bier_disp_table (u8* s, va_list *ap)
144 {
145  index_t bdti = va_arg(*ap, index_t);
146  u32 indent = va_arg(*ap, u32);
148  bier_disp_table_t *bdt;
149 
150  bdt = bier_disp_table_get(bdti);
151 
152  s = format(s, "bier-disp-table:[%d]; table-id:%d locks:%d",
153  bdti, bdt->bdt_table_id, bdt->bdt_locks);
154 
155  if (flags & BIER_SHOW_DETAIL)
156  {
157  u32 ii;
158 
159  for (ii = 0; ii < BIER_BP_MAX; ii++)
160  {
161  if (INDEX_INVALID != bdt->bdt_db[ii])
162  {
163  u16 src = ii;
164  s = format(s, "\n%Usrc:%d", format_white_space, indent+1,
165  clib_host_to_net_u16(src));
166  s = format(s, "\n%U",
167  format_bier_disp_entry, bdt->bdt_db[ii],
168  indent+4, BIER_SHOW_BRIEF);
169  }
170  }
171  }
172  return (s);
173 }
174 
175 static u8*
177 {
178  index_t bdti = va_arg(*ap, index_t);
179  u32 indent = va_arg(*ap, u32);
180 
181  return (format(s, "%U",
182  format_bier_disp_table, bdti, indent,
183  BIER_SHOW_BRIEF));
184 }
185 
186 static void
188  bier_bp_t src,
189  index_t bdei)
190 {
191  bier_disp_table_t *bdt;
192 
193  bdt = bier_disp_table_get(bdti);
194  bdt->bdt_db[clib_host_to_net_u16(src)] = bdei;
195 }
196 
197 static void
199  bier_bp_t src)
200 {
201  bier_disp_table_t *bdt;
202 
203  bdt = bier_disp_table_get(bdti);
204  bdt->bdt_db[clib_host_to_net_u16(src)] = INDEX_INVALID;
205 }
206 
207 static index_t
209  bier_bp_t bp)
210 {
211  bier_hdr_src_id_t src = bp;
212 
213  return (bier_disp_table_lookup(bdti, clib_host_to_net_u16(src)));
214 }
215 
216 void
218  bier_bp_t src,
219  bier_hdr_proto_id_t payload_proto,
220  const fib_route_path_t *rpaths)
221 {
222  index_t bdti, bdei;
223 
224  bdti = bier_disp_table_find(table_id);
225 
226  if (INDEX_INVALID == bdti)
227  {
228  return;
229  }
230 
231  bdei = bier_disp_table_lookup_hton(bdti, src);
232 
233  if (INDEX_INVALID == bdei)
234  {
236  bier_disp_table_entry_insert(bdti, src, bdei);
237  }
238 
239  bier_disp_entry_path_add(bdei, payload_proto, rpaths);
240 }
241 
242 void
244  bier_bp_t src,
245  bier_hdr_proto_id_t payload_proto,
246  const fib_route_path_t *rpath)
247 {
248  index_t bdti, bdei;
249 
250  bdti = bier_disp_table_find(table_id);
251 
252  if (INDEX_INVALID == bdti)
253  {
254  return;
255  }
256 
257  bdei = bier_disp_table_lookup_hton(bdti, src);
258 
259  if (INDEX_INVALID != bdei)
260  {
261  int remove;
262 
263  remove = bier_disp_entry_path_remove(bdei, payload_proto, rpath);
264 
265  if (remove)
266  {
267  bier_disp_table_entry_remove(bdti, src);
269  }
270  }
271 }
272 
273 void
276  void *ctx)
277 {
278  const bier_disp_table_t *bdt;
279  const bier_disp_entry_t *bde;
280  index_t bdti;
281  u32 ii;
282 
283  bdti = bier_disp_table_find(table_id);
284 
285  if (INDEX_INVALID != bdti)
286  {
287  bdt = bier_disp_table_get(bdti);
288 
289  for (ii = 0; ii < BIER_BP_MAX; ii++)
290  {
291  if (INDEX_INVALID != bdt->bdt_db[ii])
292  {
293  u16 src = ii;
294 
295  bde = bier_disp_entry_get(bdt->bdt_db[ii]);
296 
297  fn(bdt, bde, clib_host_to_net_u16(src), ctx);
298  }
299  }
300  }
301 }
302 
303 static void
305 {
307 }
308 
309 static void
311 {
313 }
314 
315 static void
317 {
318  fib_show_memory_usage("BIER disposition table",
319  pool_elts(bier_disp_table_pool),
320  pool_len(bier_disp_table_pool),
321  sizeof(bier_disp_table_t));
322 }
323 
324 const static dpo_vft_t bier_disp_table_dpo_vft = {
326  .dv_unlock = bier_disp_table_dpo_unlock,
327  .dv_mem_show = bier_disp_table_dpo_mem_show,
328  .dv_format = format_bier_disp_table_dpo,
329 };
330 
331 const static char *const bier_disp_table_bier_nodes[] =
332 {
333  "bier-disp-lookup",
334  NULL
335 };
336 
337 const static char * const * const bier_disp_table_nodes[DPO_PROTO_NUM] =
338 {
340 };
341 
342 clib_error_t *
344 {
346  &bier_disp_table_dpo_vft,
348 
350 
351  return (NULL);
352 }
353 
355 
356 static clib_error_t *
358  unformat_input_t * input,
359  vlib_cli_command_t * cmd)
360 {
361  bier_disp_table_t *bdt;
362  index_t bdti;
363 
364  bdti = INDEX_INVALID;
365 
366  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
367  if (unformat (input, "%d", &bdti))
368  ;
369  else if (unformat (input, "%d", &bdti))
370  ;
371  else
372  {
373  break;
374  }
375  }
376 
377  if (INDEX_INVALID == bdti)
378  {
379  pool_foreach(bdt, bier_disp_table_pool,
380  ({
383  0, BIER_SHOW_BRIEF);
384  }));
385  }
386  else
387  {
388  if (pool_is_free_index(bier_disp_table_pool, bdti))
389  {
390  vlib_cli_output(vm, "No such BIER disp table: %d", bdti);
391  }
392  else
393  {
394  vlib_cli_output(vm, "%U", format_bier_disp_table, bdti, 0,
396  }
397  }
398  return (NULL);
399 }
400 
401 VLIB_CLI_COMMAND (show_bier_disp_table_node, static) = {
402  .path = "show bier disp table",
403  .short_help = "show bier disp table [index]",
404  .function = show_bier_disp_table,
405 };
dpo_lock_fn_t dv_lock
A reference counting lock function.
Definition: dpo.h:404
static const char *const *const bier_disp_table_nodes[DPO_PROTO_NUM]
static void bier_disp_table_entry_insert(index_t bdti, bier_bp_t src, index_t bdei)
#define hash_set(h, key, value)
Definition: hash.h:255
u32 flags
Definition: vhost_user.h:115
A virtual function table regisitered for a DPO type.
Definition: dpo.h:399
#define hash_unset(h, key)
Definition: hash.h:261
A representation of a path as described by a route producer.
Definition: fib_types.h:470
index_t bdt_db[BIER_BP_MAX]
The lookup DB based on sender BP.
static uword * bier_disp_table_id_to_index
Hash table to map client table IDs to VPP index.
enum bier_show_flags_t_ bier_show_flags_t
Flags to control show output.
#define NULL
Definition: clib.h:58
bier_disp_table_t * bier_disp_table_pool
memory pool for disposition tables
u32 index_t
A Data-Path Object is an object that represents actions that are applied to packets are they are swit...
Definition: dpo.h:41
clib_memset(h->entries, 0, sizeof(h->entries[0])*entries)
void bier_disp_table_entry_path_remove(u32 table_id, bier_bp_t src, bier_hdr_proto_id_t payload_proto, const fib_route_path_t *rpath)
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
void bier_disp_table_entry_path_add(u32 table_id, bier_bp_t src, bier_hdr_proto_id_t payload_proto, const fib_route_path_t *rpaths)
u8 * format_bier_disp_table(u8 *s, va_list *ap)
Format the description/name of the table.
bier_disposition : The BIER disposition object
unsigned char u8
Definition: types.h:56
#define pool_len(p)
Number of elements in pool vector.
Definition: pool.h:140
void bier_disp_entry_unlock(index_t bdei)
void dpo_register(dpo_type_t type, const dpo_vft_t *vft, const char *const *const *nodes)
For a given DPO type Register:
Definition: dpo.c:321
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:493
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:163
u8 * format_white_space(u8 *s, va_list *va)
Definition: std-formats.c:113
int bier_disp_entry_path_remove(index_t bdei, bier_hdr_proto_id_t pproto, const fib_route_path_t *rpaths)
static const char *const bier_disp_table_bier_nodes[]
void fib_show_memory_usage(const char *name, u32 in_use_elts, u32 allocd_elts, size_t size_elt)
Show the memory usage for a type.
Definition: fib_node.c:220
unsigned int u32
Definition: types.h:88
u16 bdt_locks
number of locks on the table
u32 bier_bp_t
A bit positon as assigned to egress PEs.
Definition: bier_types.h:294
static void bier_disp_table_dpo_unlock(dpo_id_t *dpo)
void bier_disp_table_contribute_forwarding(index_t bdti, dpo_id_t *dpo)
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
Definition: dpo.h:168
#define hash_get(h, key)
Definition: hash.h:249
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:514
static void bier_disp_table_lock_i(bier_disp_table_t *bdt)
long ctx[MAX_CONNS]
Definition: main.c:144
static index_t bier_disp_table_get_index(const bier_disp_table_t *bdt)
struct _unformat_input_t unformat_input_t
unsigned short u16
Definition: types.h:57
u16 bier_hdr_src_id_t
An identifier of the sender of BIER packets this is the source of the &#39;tree&#39; - the BFIR...
Definition: bier_types.h:307
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:286
static u8 * format_bier_disp_table_dpo(u8 *s, va_list *ap)
static bier_disp_entry_t * bier_disp_entry_get(index_t bdi)
vl_api_ip4_address_t src
Definition: ipsec_gre.api:38
void bier_disp_entry_path_add(index_t bdei, bier_hdr_proto_id_t pproto, const fib_route_path_t *rpaths)
void bier_disp_table_lock(index_t bdti)
#define pool_get_aligned(P, E, A)
Allocate an object E from a pool P with alignment A.
Definition: pool.h:230
#define UNFORMAT_END_OF_INPUT
Definition: format.h:144
vlib_main_t * vm
Definition: buffer.c:312
u8 * format_bier_disp_entry(u8 *s, va_list *args)
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:283
enum bier_hdr_proto_id_t_ bier_hdr_proto_id_t
BIER header protocol payload types.
index_t bier_disp_table_find(u32 table_id)
static index_t bier_disp_table_lookup_hton(index_t bdti, bier_bp_t bp)
void dpo_set(dpo_id_t *dpo, dpo_type_t type, dpo_proto_t proto, index_t index)
Set/create a DPO ID The DPO will be locked.
Definition: dpo.c:185
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:155
static index_t bier_disp_table_lookup(index_t bdti, bier_hdr_src_id_t src)
#define hash_create(elts, value_bytes)
Definition: hash.h:696
void(* bier_disp_table_walk_fn_t)(const bier_disp_table_t *bdt, const bier_disp_entry_t *bde, u16 bp, void *ctx)
Types and functions to walk all the entries in one BIER Table.
clib_error_t * bier_disp_table_module_init(vlib_main_t *vm)
#define BIER_BP_MAX
The maximum BP that can be assigned.
Definition: bier_types.h:301
#define DPO_PROTO_NUM
Definition: dpo.h:70
index_t dpoi_index
the index of objects of that type
Definition: dpo.h:184
void bier_disp_table_unlock_w_table_id(u32 table_id)
index_t bier_disp_entry_add_or_lock(void)
#define INDEX_INVALID
Invalid index - used when no index is known blazoned capitals INVALID speak volumes where ~0 does not...
Definition: dpo.h:47
static void bier_disp_table_dpo_lock(dpo_id_t *dpo)
u64 uword
Definition: types.h:112
static void bier_disp_table_dpo_mem_show(void)
A protocol Independent IP multicast FIB table.
static clib_error_t * show_bier_disp_table(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
static void bier_disp_table_entry_remove(index_t bdti, bier_bp_t src)
void bier_disp_table_walk(u32 table_id, bier_disp_table_walk_fn_t fn, void *ctx)
static bier_disp_table_t * bier_disp_table_get(index_t bdti)
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:725
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:170
u32 bdt_table_id
Table ID (hash key) for this FIB.
void bier_disp_table_unlock(index_t bdti)
index_t bier_disp_table_add_or_lock(u32 table_id)
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:128