FD.io VPP  v18.01.2-1-g9b554f3
Vector Packet Processing
bier_disp_entry.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 /**
16  * bier_dispositon : The BIER dispositon object
17  *
18  * A BIER dispositon object is present in the IP mcast output list
19  * and represents the dispositon of a BIER bitmask. After BIER header
20  * dispositon the packet is forward within the appropriate/specifid
21  * BIER table
22  */
23 
26 #include <vnet/fib/fib_path_list.h>
27 #include <vnet/dpo/drop_dpo.h>
28 
29 /**
30  * The memory pool of all imp objects
31  */
33 
34 /**
35  * When constructing the BIER imp ID from an index and BSL, shift
36  * the BSL this far
37  */
38 #define BIER_DISP_ENTRY_ID_HLEN_SHIFT 24
39 
40 static void
42 {
43  bde->bde_locks++;
44 }
45 
46 void
48 {
50 }
51 
52 static index_t
54 {
55  return (bde - bier_disp_entry_pool);
56 }
57 
58 index_t
60 {
61  dpo_id_t invalid = DPO_INVALID;
62  bier_hdr_proto_id_t pproto;
63  bier_disp_entry_t *bde;
64 
65  pool_get_aligned(bier_disp_entry_pool, bde, CLIB_CACHE_LINE_BYTES);
66 
67  bde->bde_locks = 0;
68 
70  {
71  bde->bde_fwd[pproto].bde_dpo = invalid;
72  bde->bde_fwd[pproto].bde_rpf_id = ~0;
73  bde->bde_pl[pproto] = FIB_NODE_INDEX_INVALID;
74  }
75 
77  return (bier_disp_entry_get_index(bde));
78 }
79 
80 void
82 {
83  bier_disp_entry_t *bde;
84 
85  if (INDEX_INVALID == bdei)
86  {
87  return;
88  }
89 
90  bde = bier_disp_entry_get(bdei);
91 
92  bde->bde_locks--;
93 
94  if (0 == bde->bde_locks)
95  {
96  bier_hdr_proto_id_t pproto;
97 
99  {
100  dpo_unlock(&bde->bde_fwd[pproto].bde_dpo);
101  bde->bde_fwd[pproto].bde_rpf_id = ~0;
102  fib_path_list_unlock(bde->bde_pl[pproto]);
103  }
104  pool_put(bier_disp_entry_pool, bde);
105  }
106 }
107 
109 {
112 
115  fib_node_index_t path_index,
116  void *arg)
117 {
119 
120  ctx->bdew_rpf_id = fib_path_get_rpf_id(path_index);
121 
122  if (~0 != ctx->bdew_rpf_id)
123  {
124  return (FIB_PATH_LIST_WALK_STOP);
125  }
127 }
128 
129 static void
131  bier_hdr_proto_id_t pproto)
132 {
133  dpo_id_t via_dpo = DPO_INVALID;
134  fib_node_index_t pli;
135 
136  pli = bde->bde_pl[pproto];
137 
138  if (FIB_NODE_INDEX_INVALID == pli)
139  {
140  dpo_copy(&via_dpo,
142  }
143  else
144  {
147  bier_hdr_proto_to_dpo(pproto)),
149  &via_dpo);
150 
152  .bdew_rpf_id = ~0,
153  };
154 
156  bde->bde_fwd[pproto].bde_rpf_id = ctx.bdew_rpf_id;
157  }
158 
161  &bde->bde_fwd[pproto].bde_dpo,
162  &via_dpo);
163 }
164 
165 void
167  bier_hdr_proto_id_t pproto,
168  const fib_route_path_t *rpaths)
169 {
170  fib_node_index_t *pli, old_pli;
171  bier_disp_entry_t *bde;
172 
173  bde = bier_disp_entry_get(bdei);
174  pli = &bde->bde_pl[pproto];
175  old_pli = *pli;
176 
177  /*
178  * create a new or update the exisitng path-list for this
179  * payload protocol
180  */
181  if (FIB_NODE_INDEX_INVALID == *pli)
182  {
185  rpaths);
186  }
187  else
188  {
189  *pli = fib_path_list_copy_and_path_add(old_pli,
192  rpaths);
193  }
194 
195  fib_path_list_lock(*pli);
196  fib_path_list_unlock(old_pli);
197 
198  bier_disp_entry_restack(bde, pproto);
199 }
200 
201 int
203  bier_hdr_proto_id_t pproto,
204  const fib_route_path_t *rpaths)
205 {
206  fib_node_index_t *pli, old_pli;
207  bier_disp_entry_t *bde;
208 
209  bde = bier_disp_entry_get(bdei);
210  pli = &bde->bde_pl[pproto];
211  old_pli = *pli;
212 
213  /*
214  * update the exisitng path-list for this payload protocol
215  */
216  if (FIB_NODE_INDEX_INVALID != *pli)
217  {
218  *pli = fib_path_list_copy_and_path_remove(old_pli,
221  rpaths);
222 
223  fib_path_list_lock(*pli);
224  fib_path_list_unlock(old_pli);
225 
226  bier_disp_entry_restack(bde, pproto);
227  }
228 
229  /*
230  * if there are no path-list defined for any payload protocol
231  * then this entry is OK for removal
232  */
233  int remove = 1;
234 
236  {
237  if (FIB_NODE_INDEX_INVALID != bde->bde_pl[pproto])
238  {
239  remove = 0;
240  break;
241  }
242  }
243 
244  return (remove);
245 }
246 
247 u8*
248 format_bier_disp_entry (u8* s, va_list *args)
249 {
250  index_t bdei = va_arg (*args, index_t);
251  u32 indent = va_arg(*args, u32);
252  bier_show_flags_t flags = va_arg(*args, bier_show_flags_t);
253  bier_hdr_proto_id_t pproto;
254  bier_disp_entry_t *bde;
255 
256  bde = bier_disp_entry_get(bdei);
257 
258  s = format(s, "%Ubier-disp:[%d]", format_white_space, indent, bdei);
259 
261  {
262  if (INDEX_INVALID != bde->bde_pl[pproto])
263  {
264  s = format(s, "\n%U%U\n",
265  format_white_space, indent+2,
266  format_bier_hdr_proto, pproto);
267  s = format(s, "%U", format_fib_path_list, bde->bde_pl[pproto], indent+4);
268 
269  if (flags & BIER_SHOW_DETAIL)
270  {
271  s = format(s, "\n%UForwarding:",
272  format_white_space, indent+4);
273  s = format(s, "\n%Urpf-id:%d",
274  format_white_space, indent+6,
275  bde->bde_fwd[pproto].bde_rpf_id);
276  s = format(s, "\n%U%U",
277  format_white_space, indent+6,
278  format_dpo_id, &bde->bde_fwd[pproto].bde_dpo, indent+2);
279  }
280  }
281  }
282  return (s);
283 }
284 
285 void
287  dpo_id_t *dpo)
288 {
290 }
291 
292 const static char* const bier_disp_entry_bier_nodes[] =
293 {
294  "bier-disp-dispatch",
295  NULL,
296 };
297 
298 const static char* const * const bier_disp_entry_nodes[DPO_PROTO_NUM] =
299 {
301 };
302 
303 static void
305 {
307 }
308 
309 static void
311 {
313 }
314 
315 static void
317 {
318  fib_show_memory_usage("BIER dispositon",
319  pool_elts(bier_disp_entry_pool),
320  pool_len(bier_disp_entry_pool),
321  sizeof(bier_disp_entry_t));
322 }
323 
324 static u8*
326 {
327  index_t index = va_arg(*ap, index_t);
328  u32 indent = va_arg(*ap, u32);
329 
330  s = format(s, "%U", format_bier_disp_entry, index, indent, BIER_SHOW_DETAIL);
331 
332  return (s);
333 }
334 
335 const static dpo_vft_t bier_disp_entry_vft = {
337  .dv_unlock = bier_disp_entry_dpo_unlock,
338  .dv_format = format_bier_disp_entry_dpo,
339  .dv_mem_show = bier_disp_entry_dpo_mem_show,
340 };
341 
342 clib_error_t *
344 {
346  &bier_disp_entry_vft,
348 
349  return (NULL);
350 }
351 
353 
354 static clib_error_t *
356  unformat_input_t * input,
357  vlib_cli_command_t * cmd)
358 {
359  index_t bdei;
360 
361  bdei = INDEX_INVALID;
362 
363  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) {
364  if (unformat (input, "%d", &bdei))
365  ;
366  else
367  {
368  break;
369  }
370  }
371 
372  if (INDEX_INVALID == bdei)
373  {
374  return (NULL);
375  }
376  else
377  {
378  vlib_cli_output(vm, "%U", format_bier_disp_entry, bdei, 1,
380  }
381  return (NULL);
382 }
383 
384 VLIB_CLI_COMMAND (show_bier_disp_entry_node, static) = {
385  .path = "show bier disp entry",
386  .short_help = "show bier disp entry index",
387  .function = show_bier_disp_entry,
388 };
void dpo_unlock(dpo_id_t *dpo)
Release a reference counting lock on the DPO.
Definition: dpo.c:342
u32 bde_locks
number of locks
dpo_lock_fn_t dv_lock
A reference counting lock function.
Definition: dpo.h:382
static void bier_disp_entry_dpo_unlock(dpo_id_t *dpo)
A virtual function table regisitered for a DPO type.
Definition: dpo.h:377
fib_node_index_t bde_pl[BIER_HDR_N_PROTO]
The path-lists used by per-payload protocol parents.
A representation of a path as described by a route producer.
Definition: fib_types.h:377
dpo_proto_t bier_hdr_proto_to_dpo(bier_hdr_proto_id_t bproto)
Convert from BIER next-hop proto to DPO proto.
Definition: bier_types.c:139
enum bier_show_flags_t_ bier_show_flags_t
Flags to control show output.
u32 bde_rpf_id
u8 * format_fib_path_list(u8 *s, va_list *args)
#define NULL
Definition: clib.h:55
static void bier_disp_entry_dpo_mem_show(void)
void dpo_copy(dpo_id_t *dst, const dpo_id_t *src)
atomic copy a data-plane object.
Definition: dpo.c:258
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
void bier_disp_entry_lock(index_t bdei)
void fib_path_list_walk(fib_node_index_t path_list_index, fib_path_list_walk_fn_t func, void *ctx)
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
static void bier_disp_entry_lock_i(bier_disp_entry_t *bde)
bier_dispositon : The BIER dispositon object
#define pool_len(p)
Number of elements in pool vector.
Definition: pool.h:140
void bier_disp_entry_unlock(index_t bdei)
const dpo_id_t * drop_dpo_get(dpo_proto_t proto)
Definition: drop_dpo.c:25
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:306
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
clib_error_t * bier_disp_entry_db_module_init(vlib_main_t *vm)
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 void bier_disp_entry_dpo_lock(dpo_id_t *dpo)
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
fib_node_index_t fib_path_list_copy_and_path_add(fib_node_index_t orig_path_list_index, fib_path_list_flags_t flags, const fib_route_path_t *rpaths)
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
Definition: dpo.h:166
static clib_error_t * show_bier_disp_entry(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
static fib_path_list_walk_rc_t bier_disp_entry_path_list_walk(fib_node_index_t pl_index, fib_node_index_t path_index, void *arg)
fib_node_index_t fib_path_list_create(fib_path_list_flags_t flags, const fib_route_path_t *rpaths)
static const char *const bier_disp_entry_bier_nodes[]
struct _unformat_input_t unformat_input_t
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:271
void fib_path_list_lock(fib_node_index_t path_list_index)
static bier_disp_entry_t * bier_disp_entry_get(index_t bdi)
void bier_disp_entry_path_add(index_t bdei, bier_hdr_proto_id_t pproto, const fib_route_path_t *rpaths)
#define pool_get_aligned(P, E, A)
Allocate an object E from a pool P (general version).
Definition: pool.h:188
fib_node_index_t fib_path_list_copy_and_path_remove(fib_node_index_t orig_path_list_index, fib_path_list_flags_t flags, const fib_route_path_t *rpaths)
struct bier_disp_entry_path_list_walk_ctx_t_ bier_disp_entry_path_list_walk_ctx_t
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
vlib_main_t * vm
Definition: buffer.c:283
u8 * format_bier_disp_entry(u8 *s, va_list *args)
static u8 * format_bier_disp_entry_dpo(u8 *s, va_list *ap)
dpo_id_t bde_dpo
u32 fib_path_get_rpf_id(fib_node_index_t path_index)
Definition: fib_path.c:2118
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:29
enum bier_hdr_proto_id_t_ bier_hdr_proto_id_t
BIER header protocol payload types.
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:182
void fib_path_list_unlock(fib_node_index_t path_list_index)
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
unsigned int u32
Definition: types.h:88
long ctx[MAX_CONNS]
Definition: main.c:122
#define FOR_EACH_BIER_HDR_PROTO(_proto)
Definition: bier_types.h:201
static void bier_disp_entry_restack(bier_disp_entry_t *bde, bier_hdr_proto_id_t pproto)
u8 * format_dpo_id(u8 *s, va_list *args)
Format a DPO_id_t oject
Definition: dpo.c:146
#define DPO_PROTO_NUM
Definition: dpo.h:70
enum fib_path_list_walk_rc_t_ fib_path_list_walk_rc_t
return code to control pat-hlist walk
struct bier_disp_entry_t_::@50 bde_fwd[BIER_HDR_N_PROTO]
The DPO contirubted from the per-payload protocol parents on cachline 1.
index_t dpoi_index
the index of objects of that type
Definition: dpo.h:182
#define FIB_NODE_INDEX_INVALID
Definition: fib_types.h:30
unsigned char u8
Definition: types.h:56
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
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
Definition: dpo.h:193
void fib_path_list_contribute_forwarding(fib_node_index_t path_list_index, fib_forward_chain_type_t fct, fib_path_list_fwd_flags_t flags, dpo_id_t *dpo)
u32 bdew_rpf_id
void bier_disp_entry_contribute_forwarding(index_t bdei, dpo_id_t *dpo)
bier_disp_entry_t * bier_disp_entry_pool
bier_dispositon : The BIER dispositon object
u32 flags
Definition: vhost-user.h:77
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:67
static index_t bier_disp_entry_get_index(bier_disp_entry_t *bde)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:680
fib_forward_chain_type_t fib_forw_chain_type_from_dpo_proto(dpo_proto_t proto)
Convert from a payload-protocol to a chain type.
Definition: fib_types.c:261
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
static const char *const *const bier_disp_entry_nodes[DPO_PROTO_NUM]
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169
u8 * format_bier_hdr_proto(u8 *s, va_list *ap)
Format the header length field.
Definition: bier_types.c:104
void dpo_stack(dpo_type_t child_type, dpo_proto_t child_proto, dpo_id_t *dpo, const dpo_id_t *parent)
Stack one DPO object on another, and thus establish a child-parent relationship.
Definition: dpo.c:470
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:128