FD.io VPP  v20.05-21-gb1500e9ff
Vector Packet Processing
gbp_subnet.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018 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 #include <plugins/gbp/gbp.h>
20 
21 #include <vnet/fib/fib_table.h>
22 #include <vnet/dpo/load_balance.h>
23 
24 /**
25  * a key for the DB
26  */
27 typedef struct gbp_subnet_key_t_
28 {
32 
33 /**
34  * Subnet
35  */
36 typedef struct gbp_subnet_t_
37 {
41 
42  union
43  {
44  struct
45  {
48  } gs_stitched_external;
49  struct
50  {
51  sclass_t gs_sclass;
52  } gs_l3_out;
53  };
54 
56 } gbp_subnet_t;
57 
58 /**
59  * A DB of the subnets; key={pfx,fib-index}
60  */
62 
63 /**
64  * pool of subnets
65  */
67 
69 
70 static index_t
71 gbp_subnet_db_find (u32 fib_index, const fib_prefix_t * pfx)
72 {
74  .gsk_pfx = *pfx,
75  .gsk_fib_index = fib_index,
76  };
77  uword *p;
78 
79  p = hash_get_mem (gbp_subnet_db, &key);
80 
81  if (NULL != p)
82  return p[0];
83 
84  return (INDEX_INVALID);
85 }
86 
87 static void
88 gbp_subnet_db_add (u32 fib_index, const fib_prefix_t * pfx, gbp_subnet_t * gs)
89 {
91 
92  key = clib_mem_alloc (sizeof (*key));
93 
94  clib_memcpy (&(key->gsk_pfx), pfx, sizeof (*pfx));
95  key->gsk_fib_index = fib_index;
96 
97  hash_set_mem (gbp_subnet_db, key, (gs - gbp_subnet_pool));
98 
99  gs->gs_key = key;
100 }
101 
102 static void
104 {
106 
107  clib_mem_free (gs->gs_key);
108  gs->gs_key = NULL;
109 }
110 
111 
112 static int
114 {
115  dpo_id_t gfd = DPO_INVALID;
116  gbp_route_domain_t *grd;
117  fib_protocol_t fproto;
118 
119  fproto = gs->gs_key->gsk_pfx.fp_proto;
120  grd = gbp_route_domain_get (gs->gs_rd);
121 
122  if (~0 == grd->grd_uu_sw_if_index[fproto])
123  return (VNET_API_ERROR_INVALID_SW_IF_INDEX);
124 
126  &gs->gs_key->gsk_pfx,
129  fib_proto_to_dpo (fproto),
131  grd->grd_uu_sw_if_index
132  [fproto], ~0, 1, NULL,
134 
135  dpo_reset (&gfd);
136 
137  return (0);
138 }
139 
140 static int
142 {
143  dpo_id_t gfd = DPO_INVALID;
144 
146  &gfd);
147 
149  &gs->gs_key->gsk_pfx,
152  &gfd);
153 
154  dpo_reset (&gfd);
155 
156  return (0);
157 }
158 
159 static int
161 {
162  dpo_id_t gpd = DPO_INVALID;
163 
164  gs->gs_stitched_external.gs_sclass = sclass;
165  gs->gs_stitched_external.gs_sw_if_index = sw_if_index;
166 
169  gs->gs_stitched_external.gs_sclass,
170  gs->gs_stitched_external.gs_sw_if_index, &gpd);
171 
173  &gs->gs_key->gsk_pfx,
177  &gpd);
178 
179  dpo_reset (&gpd);
180 
181  return (0);
182 }
183 
184 static int
186 {
188  dpo_id_t gpd = DPO_INVALID;
189 
190  gs->gs_l3_out.gs_sclass = sclass;
191 
194  gs->gs_l3_out.gs_sclass, ~0, &gpd);
195 
196  flags = FIB_ENTRY_FLAG_INTERPOSE;
197  if (is_anon)
199 
201  &gs->gs_key->gsk_pfx,
203  flags, &gpd);
204 
205  dpo_reset (&gpd);
206 
207  return (0);
208 }
209 
210 static void
212 {
213  gbp_subnet_t *gs;
214 
215  gs = pool_elt_at_index (gbp_subnet_pool, gsi);
216 
218  (GBP_SUBNET_L3_OUT == gs->gs_type
220  gs->gs_type) ? FIB_SOURCE_SPECIAL :
222 
223  gbp_subnet_db_del (gs);
225 
226  pool_put (gbp_subnet_pool, gs);
227 }
228 
229 int
231 {
232  gbp_route_domain_t *grd;
233  index_t gsi, grdi;
234  u32 fib_index;
235 
236  grdi = gbp_route_domain_find (rd_id);
237 
238  if (~0 == grdi)
239  return (VNET_API_ERROR_NO_SUCH_FIB);
240 
241  grd = gbp_route_domain_get (grdi);
242  fib_index = grd->grd_fib_index[pfx->fp_proto];
243 
244  gsi = gbp_subnet_db_find (fib_index, pfx);
245 
246  if (INDEX_INVALID == gsi)
247  return (VNET_API_ERROR_NO_SUCH_ENTRY);
248 
249  gbp_subnet_del_i (gsi);
250 
251  return (0);
252 }
253 
254 int
256  const fib_prefix_t * pfx,
258 {
259  gbp_route_domain_t *grd;
260  index_t grdi, gsi;
261  gbp_subnet_t *gs;
262  u32 fib_index;
263  int rv;
264 
265  switch (type)
266  {
270  case GBP_SUBNET_L3_OUT:
272  break;
273  default:
274  return (VNET_API_ERROR_INCORRECT_ADJACENCY_TYPE);
275  }
276 
277  grdi = gbp_route_domain_find_and_lock (rd_id);
278 
279  if (~0 == grdi)
280  return (VNET_API_ERROR_NO_SUCH_FIB);
281 
282  grd = gbp_route_domain_get (grdi);
283  fib_index = grd->grd_fib_index[pfx->fp_proto];
284 
285  gsi = gbp_subnet_db_find (fib_index, pfx);
286 
287  /*
288  * this is an update if the subnet already exists, so remove the old
289  */
290  if (INDEX_INVALID != gsi)
291  gbp_subnet_del_i (gsi);
292 
293  rv = -2;
294 
295  pool_get (gbp_subnet_pool, gs);
296 
297  gs->gs_type = type;
298  gs->gs_rd = grdi;
299  gbp_subnet_db_add (fib_index, pfx, gs);
300 
301  switch (type)
302  {
304  rv = gbp_subnet_internal_add (gs);
305  break;
307  rv = gbp_subnet_external_add (gs, sw_if_index, sclass);
308  break;
310  rv = gbp_subnet_transport_add (gs);
311  break;
312  case GBP_SUBNET_L3_OUT:
313  rv = gbp_subnet_l3_out_add (gs, sclass, 0 /* is_anon */ );
314  break;
316  rv = gbp_subnet_l3_out_add (gs, sclass, 1 /* is_anon */ );
317  break;
318  }
319 
320  return (rv);
321 }
322 
323 static clib_error_t *
325  unformat_input_t * input, vlib_cli_command_t * cmd)
326 {
327  unformat_input_t _line_input, *line_input = &_line_input;
328  vnet_main_t *vnm = vnet_get_main ();
330  int length;
331  u32 rd_id = ~0;
332  u32 sw_if_index = ~0;
333  gbp_subnet_type_t type = ~0;
334  u32 sclass = ~0;
335  int is_add = 1;
336  int rv;
337 
338  /* Get a line of input. */
339  if (!unformat_user (input, unformat_line_input, line_input))
340  return 0;
341 
342  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
343  {
344  if (unformat (line_input, "del"))
345  is_add = 0;
346  else if (unformat (line_input, "rd %d", &rd_id))
347  ;
348  else
349  if (unformat
350  (line_input, "prefix %U/%d", unformat_ip4_address,
351  &pfx.fp_addr.ip4, &length))
353  else
354  if (unformat
355  (line_input, "prefix %U/%d", unformat_ip6_address,
356  &pfx.fp_addr.ip6, &length))
358  else if (unformat (line_input, "type transport"))
359  type = GBP_SUBNET_TRANSPORT;
360  else if (unformat (line_input, "type stitched-internal"))
362  else if (unformat (line_input, "type stitched-external"))
364  else if (unformat (line_input, "type anon-l3-out"))
365  type = GBP_SUBNET_ANON_L3_OUT;
366  else if (unformat (line_input, "type l3-out"))
367  type = GBP_SUBNET_L3_OUT;
368  else
369  if (unformat_user
370  (line_input, unformat_vnet_sw_interface, vnm, &sw_if_index))
371  ;
372  else if (unformat (line_input, "sclass %u", &sclass))
373  ;
374  else
375  return clib_error_return (0, "unknown input `%U'",
376  format_unformat_error, line_input);
377  }
378  unformat_free (line_input);
379 
380  pfx.fp_len = length;
381 
382  if (is_add)
383  rv = gbp_subnet_add (rd_id, &pfx, type, sw_if_index, sclass);
384  else
385  rv = gbp_subnet_del (rd_id, &pfx);
386 
387  switch (rv)
388  {
389  case 0:
390  return 0;
391  case VNET_API_ERROR_NO_SUCH_FIB:
392  return clib_error_return (0, "no such FIB");
393  }
394 
395  return clib_error_return (0, "unknown error %d", rv);
396 }
397 
398 /*?
399  * Add Group Based Policy Subnets
400  *
401  * @cliexpar
402  * @cliexstart{gbp subnet [del] rd <ID> prefix <prefix> type <type> [<interface>] [sclass <sclass>]}
403  * @cliexend
404  ?*/
405 /* *INDENT-OFF* */
406 VLIB_CLI_COMMAND (gbp_subnet_add_del, static) = {
407  .path = "gbp subnet",
408  .short_help = "gbp subnet [del] rd <ID> prefix <prefix> type <type> [<interface>] [sclass <sclass>]\n",
409  .function = gbp_subnet_add_del_cli,
410 };
411 /* *INDENT-ON* */
412 
413 
414 
415 void
417 {
418  gbp_route_domain_t *grd;
419  gbp_subnet_t *gs;
422 
423  sclass = SCLASS_INVALID;
424  sw_if_index = ~0;
425 
426  /* *INDENT-OFF* */
427  pool_foreach (gs, gbp_subnet_pool,
428  ({
429  grd = gbp_route_domain_get(gs->gs_rd);
430 
431  switch (gs->gs_type)
432  {
435  /* use defaults above */
436  break;
438  sw_if_index = gs->gs_stitched_external.gs_sw_if_index;
439  sclass = gs->gs_stitched_external.gs_sclass;
440  break;
441  case GBP_SUBNET_L3_OUT:
443  sclass = gs->gs_l3_out.gs_sclass;
444  break;
445  }
446 
447  if (WALK_STOP == cb (grd->grd_id, &gs->gs_key->gsk_pfx,
448  gs->gs_type, sw_if_index, sclass, ctx))
449  break;
450  }));
451  /* *INDENT-ON* */
452 }
453 
455 {
459 
460 static u8 *
461 format_gbp_subnet_type (u8 * s, va_list * args)
462 {
463  gbp_subnet_type_t type = va_arg (*args, gbp_subnet_type_t);
464 
465  switch (type)
466  {
468  return (format (s, "stitched-internal"));
470  return (format (s, "stitched-external"));
472  return (format (s, "transport"));
473  case GBP_SUBNET_L3_OUT:
474  return (format (s, "l3-out"));
476  return (format (s, "anon-l3-out"));
477  }
478 
479  return (format (s, "unknown"));
480 }
481 
482 u8 *
483 format_gbp_subnet (u8 * s, va_list * args)
484 {
485  index_t gsi = va_arg (*args, index_t);
487  gbp_subnet_t *gs;
488  u32 table_id;
489 
490  gs = pool_elt_at_index (gbp_subnet_pool, gsi);
491 
493  gs->gs_key->gsk_pfx.fp_proto);
494 
495  s = format (s, "[%d] tbl:%d %U %U", gsi, table_id,
498 
499  switch (gs->gs_type)
500  {
503  break;
505  s = format (s, " {sclass:%d %U}", gs->gs_stitched_external.gs_sclass,
507  vnet_get_main (), gs->gs_stitched_external.gs_sw_if_index);
508  break;
509  case GBP_SUBNET_L3_OUT:
511  s = format (s, " {sclass:%d}", gs->gs_l3_out.gs_sclass);
512  break;
513  }
514 
515  switch (flags)
516  {
518  {
519  s = format (s, "\n %U", format_fib_entry, gs->gs_fei,
521  }
523  break;
524  }
525  return (s);
526 }
527 
528 static clib_error_t *
530  unformat_input_t * input, vlib_cli_command_t * cmd)
531 {
532  u32 gsi;
533 
534  gsi = INDEX_INVALID;
535 
537  {
538  if (unformat (input, "%d", &gsi))
539  ;
540  else
541  break;
542  }
543 
544  if (INDEX_INVALID != gsi)
545  {
546  vlib_cli_output (vm, "%U", format_gbp_subnet, gsi,
548  }
549  else
550  {
551  /* *INDENT-OFF* */
552  pool_foreach_index(gsi, gbp_subnet_pool,
553  ({
554  vlib_cli_output (vm, "%U", format_gbp_subnet, gsi,
556  }));
557  /* *INDENT-ON* */
558  }
559 
560  return (NULL);
561 }
562 
563 /*?
564  * Show Group Based Policy Subnets
565  *
566  * @cliexpar
567  * @cliexstart{show gbp subnet}
568  * @cliexend
569  ?*/
570 /* *INDENT-OFF* */
571 VLIB_CLI_COMMAND (gbp_subnet_show_node, static) = {
572  .path = "show gbp subnet",
573  .short_help = "show gbp subnet\n",
574  .function = gbp_subnet_show,
575 };
576 /* *INDENT-ON* */
577 
578 static clib_error_t *
580 {
582  sizeof (gbp_subnet_key_t), sizeof (u32));
583  gbp_fib_source = fib_source_allocate ("gbp-subnet",
586 
587  return (NULL);
588 }
589 
591 
592 /*
593  * fd.io coding-style-patch-verification: ON
594  *
595  * Local Variables:
596  * eval: (c-set-style "gnu")
597  * End:
598  */
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:212
u8 * format_fib_entry(u8 *s, va_list *args)
Definition: fib_entry.c:130
enum fib_source_t_ fib_source_t
The different sources that can create a route.
a key for the DB
Definition: gbp_subnet.c:27
void gbp_subnet_walk(gbp_subnet_cb_t cb, void *ctx)
Definition: gbp_subnet.c:416
void gbp_route_domain_unlock(index_t index)
u16 sclass_t
Definition: gbp_types.h:25
fib_prefix_t gsk_pfx
Definition: gbp_subnet.c:29
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
gbp_subnet_key_t * gs_key
Definition: gbp_subnet.c:38
static u8 * format_gbp_subnet_type(u8 *s, va_list *args)
Definition: gbp_subnet.c:461
#define FIB_ENTRY_FORMAT_DETAIL
Definition: fib_entry.h:360
Definition: fib_entry.h:123
add paths without path extensions
Definition: fib_source.h:205
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
sclass_t gs_sclass
Definition: gbp_subnet.c:46
static void gbp_subnet_db_del(gbp_subnet_t *gs)
Definition: gbp_subnet.c:103
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:989
u32 rd_id
Definition: gbp.api:35
#define hash_set_mem(h, key, value)
Definition: hash.h:275
index_t gs_rd
Definition: gbp_subnet.c:40
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
unformat_function_t unformat_vnet_sw_interface
static int gbp_subnet_transport_add(gbp_subnet_t *gs)
Definition: gbp_subnet.c:113
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:252
int gbp_subnet_del(u32 rd_id, const fib_prefix_t *pfx)
Definition: gbp_subnet.c:230
format_function_t format_vnet_sw_if_index_name
unsigned char u8
Definition: types.h:56
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
#define clib_memcpy(d, s, n)
Definition: string.h:180
fib_node_index_t fib_table_entry_update_one_path(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags, dpo_proto_t next_hop_proto, const ip46_address_t *next_hop, u32 next_hop_sw_if_index, u32 next_hop_fib_index, u32 next_hop_weight, fib_mpls_label_t *next_hop_labels, fib_route_path_flags_t path_flags)
Update the entry to have just one path.
Definition: fib_table.c:805
static clib_error_t * gbp_subnet_init(vlib_main_t *vm)
Definition: gbp_subnet.c:579
Definition: fib_entry.h:120
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:513
unformat_function_t unformat_ip4_address
Definition: format.h:68
vl_api_interface_index_t sw_if_index
Definition: gre.api:53
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
static int gbp_subnet_internal_add(gbp_subnet_t *gs)
Definition: gbp_subnet.c:141
int gbp_subnet_add(u32 rd_id, const fib_prefix_t *pfx, gbp_subnet_type_t type, u32 sw_if_index, sclass_t sclass)
Definition: gbp_subnet.c:255
u8 * format_fib_prefix(u8 *s, va_list *args)
Definition: fib_types.c:264
Aggregate type for a prefix.
Definition: fib_types.h:203
#define clib_error_return(e, args...)
Definition: error.h:99
enum gsb_subnet_show_flags_t_ gsb_subnet_show_flags_t
walk_rc_t(* gbp_subnet_cb_t)(u32 rd_id, const fib_prefix_t *pfx, gbp_subnet_type_t type, u32 sw_if_index, sclass_t sclass, void *ctx)
Definition: gbp_subnet.h:37
unsigned int u32
Definition: types.h:88
u16 fp_len
The mask length.
Definition: fib_types.h:207
gbp_subnet_t * gbp_subnet_pool
pool of subnets
Definition: gbp_subnet.c:66
static index_t gbp_subnet_db_find(u32 fib_index, const fib_prefix_t *pfx)
Definition: gbp_subnet.c:71
gbp_scope_t gbp_route_domain_get_scope(index_t grdi)
fib_source_t fib_source_allocate(const char *name, fib_source_priority_t prio, fib_source_behaviour_t bh)
Definition: fib_source.c:118
Definition: fib_entry.h:112
unformat_function_t unformat_line_input
Definition: format.h:283
u32 gs_sw_if_index
Definition: gbp_subnet.c:47
vl_api_fib_path_type_t type
Definition: fib_types.api:123
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
Definition: dpo.h:170
#define hash_create_mem(elts, key_bytes, value_bytes)
Definition: hash.h:661
Definition: fib_entry.h:116
gbp_subnet_type_t gs_type
Definition: gbp_subnet.c:39
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:534
#define hash_unset_mem(h, key)
Definition: hash.h:291
#define FIB_SOURCE_PRIORITY_HI
Some priority values that plugins might use when they are not to concerned where in the list they&#39;ll ...
Definition: fib_source.h:273
enum gbp_subnet_type_t_ gbp_subnet_type_t
ip46_address_t fp_addr
The address type is not deriveable from the fp_addr member.
Definition: fib_types.h:226
static void gbp_subnet_del_i(index_t gsi)
Definition: gbp_subnet.c:211
long ctx[MAX_CONNS]
Definition: main.c:144
Subnet.
Definition: gbp_subnet.c:36
struct _unformat_input_t unformat_input_t
void gbp_policy_dpo_add_or_lock(dpo_proto_t dproto, gbp_scope_t scope, sclass_t sclass, u32 sw_if_index, dpo_id_t *dpo)
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:302
u16 sclass
Definition: gbp.api:123
u32 grd_uu_sw_if_index[FIB_PROTOCOL_IP_MAX]
The interfaces on which to send packets to unnknown EPs.
static clib_error_t * gbp_subnet_add_del_cli(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: gbp_subnet.c:324
#define SCLASS_INVALID
Definition: gbp_types.h:26
vlib_main_t * vm
Definition: in2out_ed.c:1599
unformat_function_t unformat_ip6_address
Definition: format.h:89
uword * gbp_subnet_db
A DB of the subnets; key={pfx,fib-index}.
Definition: gbp_subnet.c:61
fib_node_index_t fib_table_entry_special_dpo_update(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags, const dpo_id_t *dpo)
Update a &#39;special&#39; entry to the FIB that links to the DPO passed A special entry is an entry that the...
Definition: fib_table.c:363
#define UNFORMAT_END_OF_INPUT
Definition: format.h:145
u32 flags
Definition: vhost_user.h:248
void fib_table_entry_delete_index(fib_node_index_t fib_entry_index, fib_source_t source)
Delete a FIB entry.
Definition: fib_table.c:910
index_t gbp_route_domain_find(u32 rd_id)
u32 grd_fib_index[FIB_PROTOCOL_IP_MAX]
Definition: fib_entry.h:122
void gbp_fwd_dpo_add_or_lock(dpo_proto_t dproto, dpo_id_t *dpo)
Definition: gbp_fwd_dpo.c:88
static int gbp_subnet_external_add(gbp_subnet_t *gs, u32 sw_if_index, sclass_t sclass)
Definition: gbp_subnet.c:160
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:30
enum fib_entry_flag_t_ fib_entry_flag_t
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:152
fib_node_index_t fib_table_entry_special_dpo_add(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags, const dpo_id_t *dpo)
Add a &#39;special&#39; entry to the FIB that links to the DPO passed A special entry is an entry that the FI...
Definition: fib_table.c:324
fib_node_index_t gs_fei
Definition: gbp_subnet.c:55
gbp_route_domain_t * gbp_route_domain_get(index_t i)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:689
u32 fib_table_get_table_id(u32 fib_index, fib_protocol_t proto)
Get the Table-ID of the FIB from protocol and index.
Definition: fib_table.c:1086
static void clib_mem_free(void *p)
Definition: mem.h:215
u8 * format_gbp_subnet(u8 *s, va_list *args)
Definition: gbp_subnet.c:483
dpo_proto_t fib_proto_to_dpo(fib_protocol_t fib_proto)
Definition: fib_types.c:324
static fib_source_t gbp_fib_source
Definition: gbp_subnet.c:68
static void * clib_mem_alloc(uword size)
Definition: mem.h:157
typedef key
Definition: ipsec_types.api:85
struct gbp_subnet_t_ gbp_subnet_t
Subnet.
struct gbp_subnet_t_::@618::@620 gs_stitched_external
struct gbp_subnet_key_t_ gbp_subnet_key_t
a key for the DB
gsb_subnet_show_flags_t_
Definition: gbp_subnet.c:454
A route Domain Representation.
#define INDEX_INVALID
Invalid index - used when no index is known blazoned capitals INVALID speak volumes where ~0 does not...
Definition: dpo.h:47
u64 uword
Definition: types.h:112
static void unformat_free(unformat_input_t *i)
Definition: format.h:163
static clib_error_t * gbp_subnet_show(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: gbp_subnet.c:529
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
Definition: dpo.h:197
#define hash_get_mem(h, key)
Definition: hash.h:269
static void gbp_subnet_db_add(u32 fib_index, const fib_prefix_t *pfx, gbp_subnet_t *gs)
Definition: gbp_subnet.c:88
u32 grd_id
Route-domain ID.
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
void dpo_reset(dpo_id_t *dpo)
reset a DPO ID The DPO will be unlocked.
Definition: dpo.c:232
Special sources.
Definition: fib_source.h:42
struct gbp_subnet_t_::@618::@621 gs_l3_out
#define pool_foreach_index(i, v, body)
Iterate pool by index.
Definition: pool.h:558
u32 table_id
Definition: fib_types.api:118
const ip46_address_t ADJ_BCAST_ADDR
The special broadcast address (to construct a broadcast adjacency.
Definition: adj.c:41
#define ip46_address_initializer
Definition: ip46_address.h:52
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
index_t gbp_route_domain_find_and_lock(u32 rd_id)
static int gbp_subnet_l3_out_add(gbp_subnet_t *gs, sclass_t sclass, int is_anon)
Definition: gbp_subnet.c:185
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:171