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:
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
16 #include <vnet/bier/bier_disp_table.h>
17 #include <vnet/bier/bier_disp_entry.h>
20 * memory pool for disposition tables
22 bier_disp_table_t *bier_disp_table_pool;
25 * Hash table to map client table IDs to VPP index
27 static uword *bier_disp_table_id_to_index;
30 bier_disp_table_get_index (const bier_disp_table_t *bdt)
32 return (bdt - bier_disp_table_pool);
36 bier_disp_table_lock_i (bier_disp_table_t *bdt)
42 bier_disp_table_find(u32 table_id)
46 p = hash_get(bier_disp_table_id_to_index, table_id);
53 return (INDEX_INVALID);
57 bier_disp_table_add_or_lock (u32 table_id)
59 bier_disp_table_t *bdt;
62 bdti = bier_disp_table_find(table_id);
64 if (INDEX_INVALID == bdti)
66 pool_get_aligned(bier_disp_table_pool, bdt,
67 CLIB_CACHE_LINE_BYTES);
69 bdt->bdt_table_id = table_id;
72 hash_set(bier_disp_table_id_to_index, table_id,
73 bier_disp_table_get_index(bdt));
76 * Set the result for each entry in the DB to be invalid
78 memset(bdt->bdt_db, 0xff, sizeof(bdt->bdt_db));
82 bdt = pool_elt_at_index(bier_disp_table_pool, bdti);
85 bier_disp_table_lock_i(bdt);
87 return (bier_disp_table_get_index(bdt));
91 bier_disp_table_unlock_w_table_id (u32 table_id)
95 bdti = bier_disp_table_find(table_id);
97 if (INDEX_INVALID != bdti)
99 bier_disp_table_unlock(bdti);
104 bier_disp_table_unlock (index_t bdti)
106 bier_disp_table_t *bdt;
108 bdt = bier_disp_table_get(bdti);
112 if (0 == bdt->bdt_locks)
116 for (ii = 0; ii < BIER_BP_MAX; ii++)
118 bier_disp_entry_unlock(bdt->bdt_db[ii]);
120 hash_unset(bier_disp_table_id_to_index, bdt->bdt_table_id);
121 pool_put(bier_disp_table_pool, bdt);
126 bier_disp_table_lock (index_t bdti)
128 bier_disp_table_lock_i(bier_disp_table_get(bdti));
132 bier_disp_table_contribute_forwarding (index_t bdti,
143 format_bier_disp_table (u8* s, va_list *ap)
145 index_t bdti = va_arg(*ap, index_t);
146 u32 indent = va_arg(*ap, u32);
147 bier_show_flags_t flags = va_arg(*ap, bier_show_flags_t);
148 bier_disp_table_t *bdt;
150 bdt = bier_disp_table_get(bdti);
152 s = format(s, "bier-disp-table:[%d]; table-id:%d locks:%d",
153 bdti, bdt->bdt_table_id, bdt->bdt_locks);
155 if (flags & BIER_SHOW_DETAIL)
159 for (ii = 0; ii < BIER_BP_MAX; ii++)
161 if (INDEX_INVALID != bdt->bdt_db[ii])
164 s = format(s, "\n%Usrc:%d", format_white_space, indent,
165 clib_host_to_net_u16(src));
166 s = format(s, "\n%U%U", format_white_space, indent+2,
167 format_bier_disp_entry, bdt->bdt_db[ii],
168 indent+4, BIER_SHOW_BRIEF);
176 format_bier_disp_table_dpo (u8* s, va_list *ap)
178 index_t bdti = va_arg(*ap, index_t);
179 u32 indent = va_arg(*ap, u32);
181 return (format(s, "%U",
182 format_bier_disp_table, bdti, indent,
187 bier_disp_table_entry_insert (index_t bdti,
191 bier_disp_table_t *bdt;
193 bdt = bier_disp_table_get(bdti);
194 bdt->bdt_db[clib_host_to_net_u16(src)] = bdei;
198 bier_disp_table_entry_remove (index_t bdti,
201 bier_disp_table_t *bdt;
203 bdt = bier_disp_table_get(bdti);
204 bdt->bdt_db[clib_host_to_net_u16(src)] = INDEX_INVALID;
208 bier_disp_table_lookup_hton(index_t bdti,
211 return (bier_disp_table_lookup(bdti, clib_host_to_net_u16(src)));
215 bier_disp_table_entry_path_add (u32 table_id,
217 bier_hdr_proto_id_t payload_proto,
218 const fib_route_path_t *rpaths)
222 bdti = bier_disp_table_find(table_id);
224 if (INDEX_INVALID == bdti)
229 bdei = bier_disp_table_lookup_hton(bdti, src);
231 if (INDEX_INVALID == bdei)
233 bdei = bier_disp_entry_add_or_lock();
234 bier_disp_table_entry_insert(bdti, src, bdei);
237 bier_disp_entry_path_add(bdei, payload_proto, rpaths);
241 bier_disp_table_entry_path_remove (u32 table_id,
243 bier_hdr_proto_id_t payload_proto,
244 const fib_route_path_t *rpath)
248 bdti = bier_disp_table_find(table_id);
250 if (INDEX_INVALID == bdti)
255 bdei = bier_disp_table_lookup_hton(bdti, src);
257 if (INDEX_INVALID != bdei)
261 remove = bier_disp_entry_path_remove(bdei, payload_proto, rpath);
265 bier_disp_table_entry_remove(bdti, src);
266 bier_disp_entry_unlock(bdei);
272 bier_disp_table_walk (u32 table_id,
273 bier_disp_table_walk_fn_t fn,
276 const bier_disp_table_t *bdt;
277 const bier_disp_entry_t *bde;
281 bdti = bier_disp_table_find(table_id);
283 if (INDEX_INVALID != bdti)
285 bdt = bier_disp_table_get(bdti);
287 for (ii = 0; ii < BIER_BP_MAX; ii++)
289 if (INDEX_INVALID != bdt->bdt_db[ii])
293 bde = bier_disp_entry_get(bdt->bdt_db[ii]);
295 fn(bdt, bde, clib_host_to_net_u16(src), ctx);
302 bier_disp_table_dpo_lock (dpo_id_t *dpo)
304 bier_disp_table_lock(dpo->dpoi_index);
308 bier_disp_table_dpo_unlock (dpo_id_t *dpo)
310 bier_disp_table_unlock(dpo->dpoi_index);
314 bier_disp_table_dpo_mem_show (void)
316 fib_show_memory_usage("BIER disposition table",
317 pool_elts(bier_disp_table_pool),
318 pool_len(bier_disp_table_pool),
319 sizeof(bier_disp_table_t));
322 const static dpo_vft_t bier_disp_table_dpo_vft = {
323 .dv_lock = bier_disp_table_dpo_lock,
324 .dv_unlock = bier_disp_table_dpo_unlock,
325 .dv_mem_show = bier_disp_table_dpo_mem_show,
326 .dv_format = format_bier_disp_table_dpo,
329 const static char *const bier_disp_table_bier_nodes[] =
334 const static char * const * const bier_disp_table_nodes[DPO_PROTO_NUM] =
336 [DPO_PROTO_BIER] = bier_disp_table_bier_nodes,
340 bier_disp_table_module_init (vlib_main_t *vm)
342 dpo_register(DPO_BIER_DISP_TABLE,
343 &bier_disp_table_dpo_vft,
344 bier_disp_table_nodes);
346 bier_disp_table_id_to_index = hash_create(0, sizeof(index_t));
351 VLIB_INIT_FUNCTION (bier_disp_table_module_init);
353 static clib_error_t *
354 show_bier_disp_table (vlib_main_t * vm,
355 unformat_input_t * input,
356 vlib_cli_command_t * cmd)
358 bier_disp_table_t *bdt;
361 bdti = INDEX_INVALID;
363 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
364 if (unformat (input, "%d", &bdti))
366 else if (unformat (input, "%d", &bdti))
374 if (INDEX_INVALID == bdti)
376 pool_foreach(bdt, bier_disp_table_pool,
378 vlib_cli_output(vm, "%U", format_bier_disp_table,
379 bier_disp_table_get_index(bdt),
386 vlib_cli_output(vm, "%U", format_bier_disp_table, bdti, 1,
392 VLIB_CLI_COMMAND (show_bier_disp_table_node, static) = {
393 .path = "show bier disp table",
394 .short_help = "show bier disp table [index]",
395 .function = show_bier_disp_table,