FD.io VPP  v20.01-48-g3e0dafb74
Vector Packet Processing
svs.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/svs/svs.h>
17 
18 #include <vlib/vlib.h>
19 #include <vnet/plugin/plugin.h>
20 #include <vnet/fib/fib_table.h>
21 #include <vnet/fib/ip6_fib.h>
22 #include <vnet/fib/ip4_fib.h>
23 #include <vnet/dpo/lookup_dpo.h>
24 #include <vnet/dpo/load_balance.h>
26 
28 
30 
31 int
33 {
35 
36  return (0);
37 }
38 
39 int
41 {
42  u32 fib_index, ii;
43 
44  fib_index = fib_table_find (fproto, table_id);
45 
46  vec_foreach_index (ii, svs_itf_db[fproto])
47  {
48  if (svs_itf_db[fproto][ii] == fib_index)
49  return VNET_API_ERROR_INSTANCE_IN_USE;
50  }
51 
52  if (~0 == fib_index)
53  return VNET_API_ERROR_NO_SUCH_FIB;
54 
55  fib_table_unlock (fib_index, fproto, svs_fib_src);
56 
57  return (0);
58 }
59 
60 static int
61 svs_route_add_i (u32 fib_index, const fib_prefix_t * pfx, u32 src_fib_index)
62 {
63  dpo_id_t dpo = DPO_INVALID;
64 
65 
71 
72  fib_table_entry_special_dpo_add (fib_index, pfx,
75 
76  dpo_unlock (&dpo);
77 
78  return (0);
79 }
80 
81 int
82 svs_route_add (u32 table_id, const fib_prefix_t * pfx, u32 source_table_id)
83 {
84  u32 fib_index, src_fib_index;
85  int rv;
86 
87  fib_index = fib_table_find (pfx->fp_proto, table_id);
88 
89  if (~0 == fib_index)
90  return VNET_API_ERROR_NO_SUCH_FIB;
91 
92  src_fib_index = fib_table_find (pfx->fp_proto, source_table_id);
93 
94  if (~0 == src_fib_index)
95  return (VNET_API_ERROR_NO_SUCH_FIB);
96 
97  rv = svs_route_add_i (fib_index, pfx, src_fib_index);
98 
99  return (rv);
100 }
101 
102 int
104 {
105  u32 fib_index;
106 
107  fib_index = fib_table_find (pfx->fp_proto, table_id);
108 
109  if (~0 == fib_index)
110  return VNET_API_ERROR_NO_SUCH_FIB;
111 
113 
114  return (0);
115 }
116 
117 int
119 {
120  fib_prefix_t pfx = {
121  .fp_proto = fproto,
122  };
123  u32 fib_index;
124 
125  fib_index = fib_table_find (fproto, table_id);
126 
127  if (~0 == fib_index)
128  return VNET_API_ERROR_NO_SUCH_FIB;
129 
130  /*
131  * now we know which interface the table will serve, we can add the default
132  * route to use the table that the interface is bound to.
133  */
134  svs_route_add_i (fib_index, &pfx,
135  fib_table_get_index_for_sw_if_index (fproto, sw_if_index));
136 
137  vec_validate_init_empty (svs_itf_db[fproto], sw_if_index, ~0);
138 
139  svs_itf_db[fproto][sw_if_index] = fib_index;
140 
142  "ip4-unicast" :
143  "ip6-unicast"),
144  (FIB_PROTOCOL_IP4 == fproto ?
145  "svs-ip4" :
146  "svs-ip6"), sw_if_index, 1, NULL, 0);
147 
148  return (0);
149 }
150 
151 static void
153 {
154  /*
155  * update the default route to use the interface's newly bound FIB
156  */
157  u32 svs_fib_index;
158 
159  if (sw_if_index >= vec_len (svs_itf_db[FIB_PROTOCOL_IP6]))
160  return;
161 
162  svs_fib_index = svs_itf_db[FIB_PROTOCOL_IP6][sw_if_index];
163 
164  if (~0 != svs_fib_index)
165  {
166  fib_prefix_t pfx = {
167  .fp_proto = fproto,
168  };
169 
170  svs_route_add (svs_fib_index, &pfx, itf_fib_index);
171  }
172  /*
173  * else
174  * no SVS enable on this interface
175  */
176 }
177 
178 static void
180  uword opaque,
181  u32 sw_if_index, u32 new_fib_index, u32 old_fib_index)
182 {
183  svs_table_bind (FIB_PROTOCOL_IP6, sw_if_index, new_fib_index);
184 }
185 
186 static void
188  uword opaque,
189  u32 sw_if_index, u32 new_fib_index, u32 old_fib_index)
190 {
191  svs_table_bind (FIB_PROTOCOL_IP4, sw_if_index, new_fib_index);
192 }
193 
194 int
196 {
197  fib_prefix_t pfx = {
198  .fp_proto = fproto,
199  };
200  u32 fib_index;
201 
202  fib_index = fib_table_find (fproto, table_id);
203 
204  if (~0 == fib_index)
205  return VNET_API_ERROR_NO_SUCH_FIB;
206 
207  if (sw_if_index >= vec_len (svs_itf_db[fproto]))
208  return VNET_API_ERROR_INVALID_SW_IF_INDEX;
209 
210  svs_itf_db[fproto][sw_if_index] = ~0;
211 
213  "ip4-unicast" :
214  "ip6-unicast"),
215  (FIB_PROTOCOL_IP4 == fproto ?
216  "svs-ip4" :
217  "svs-ip6"), sw_if_index, 0, NULL, 0);
218 
219  fib_table_entry_special_remove (fib_index, &pfx, svs_fib_src);
220 
221  return (0);
222 }
223 
224 void
226 {
227  fib_protocol_t fproto;
228  u32 ii, fib_index;
229 
230  FOR_EACH_FIB_IP_PROTOCOL (fproto)
231  {
232  vec_foreach_index (ii, svs_itf_db[fproto])
233  {
234  fib_index = svs_itf_db[fproto][ii];
235 
236  if (~0 != fib_index)
237  {
238  if (WALK_CONTINUE != fn (fproto,
239  fib_table_get_table_id (fib_index, fproto),
240  ii, ctx))
241  return;
242  }
243  }
244  }
245 }
246 
247 typedef enum svs_next_t_
248 {
251 } svs_next_t;
252 
253 typedef struct svs_input_trace_t_
254 {
257 
262 {
263  u32 n_left_from, *from, *to_next, next_index;
264 
265  from = vlib_frame_vector_args (frame);
266  n_left_from = frame->n_vectors;
267  next_index = node->cached_next_index;
268 
269  while (n_left_from > 0)
270  {
271  u32 n_left_to_next;
272 
273  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
274 
275  while (n_left_from > 0 && n_left_to_next > 0)
276  {
277  const load_balance_t *lb0;
278  const lookup_dpo_t *lk0;
279  u32 bi0, sw_if_index0;
280  const dpo_id_t *dpo0;
281  vlib_buffer_t *b0;
282  svs_next_t next0;
283  index_t lbi0;
284 
285  bi0 = from[0];
286  to_next[0] = bi0;
287  from += 1;
288  to_next += 1;
289  n_left_from -= 1;
290  n_left_to_next -= 1;
291 
292  b0 = vlib_get_buffer (vm, bi0);
293  sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
294 
295  if (FIB_PROTOCOL_IP4 == fproto)
296  {
297  ip4_header_t *ip0;
298 
299  ip0 = vlib_buffer_get_current (b0);
300  lbi0 =
301  ip4_fib_forwarding_lookup (svs_itf_db[fproto][sw_if_index0],
302  &ip0->src_address);
303  }
304  else
305  {
306  ip6_header_t *ip0;
307 
308  ip0 = vlib_buffer_get_current (b0);
310  [sw_if_index0],
311  &ip0->src_address);
312  }
313  lb0 = load_balance_get (lbi0);
314  dpo0 = load_balance_get_fwd_bucket (lb0, 0);
315  lk0 = lookup_dpo_get (dpo0->dpoi_index);
316 
317  vnet_buffer (b0)->sw_if_index[VLIB_TX] = lk0->lkd_fib_index;
318 
319  vnet_feature_next (&next0, b0);
320 
321  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
322  {
323  svs_input_trace_t *tr;
324 
325  tr = vlib_add_trace (vm, node, b0, sizeof (*tr));
326  tr->fib_index = vnet_buffer (b0)->sw_if_index[VLIB_TX];
327  }
328 
329  /* verify speculative enqueue, maybe switch current next frame */
330  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
331  to_next, n_left_to_next, bi0,
332  next0);
333  }
334 
335  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
336  }
337 
338  return frame->n_vectors;
339 }
340 
341 static uword
344 {
345  return svs_input_inline (vm, node, frame, FIB_PROTOCOL_IP4);
346 }
347 
348 static uword
351 {
352  return svs_input_inline (vm, node, frame, FIB_PROTOCOL_IP6);
353 }
354 
355 static u8 *
356 format_svs_input_trace (u8 * s, va_list * args)
357 {
358  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
359  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
360  svs_input_trace_t *t = va_arg (*args, svs_input_trace_t *);
361 
362  s = format (s, " fib_index %d", t->fib_index);
363  return s;
364 }
365 
366 /* *INDENT-OFF* */
368 {
369  .function = svs_input_ip4,
370  .name = "svs-ip4",
371  .vector_size = sizeof (u32),
372  .format_trace = format_svs_input_trace,
374  .n_next_nodes = SVS_N_NEXT,
375  .next_nodes =
376  {
377  [SVS_NEXT_DROP] = "error-drop",
378  }
379 };
380 
382 {
383  .function = svs_input_ip6,
384  .name = "svs-ip6",
385  .vector_size = sizeof (u32),
386  .format_trace = format_svs_input_trace,
388  .next_nodes =
389  {
390  [SVS_NEXT_DROP] = "error-drop",
391  }
392 };
393 
394 VNET_FEATURE_INIT (svs_ip4_feat, static) =
395 {
396  .arc_name = "ip4-unicast",
397  .node_name = "svs-ip4",
398 };
399 
400 VNET_FEATURE_INIT (svs_ip6_feat, static) =
401 {
402  .arc_name = "ip6-unicast",
403  .node_name = "svs-ip6",
404 };
405 /* *INDENT-ON* */
406 
407 static clib_error_t *
409  unformat_input_t * input, vlib_cli_command_t * cmd)
410 {
411  fib_protocol_t fproto;
412  u32 table_id;
413  u8 add;
414 
415  fproto = FIB_PROTOCOL_IP4;
416  table_id = ~0;
417  add = 1;
418 
420  {
421  if (unformat (input, "add"))
422  add = 1;
423  else if (unformat (input, "del"))
424  add = 0;
425  else if (unformat (input, "ip4"))
426  fproto = FIB_PROTOCOL_IP4;
427  else if (unformat (input, "ip6"))
428  fproto = FIB_PROTOCOL_IP6;
429  else if (unformat (input, "table-id %d", &table_id))
430  ;
431  else
432  break;
433  }
434 
435  if (~0 == table_id)
436  return clib_error_return (0, "table-id must be specified");
437 
438  if (add)
439  svs_table_add (fproto, table_id);
440  else
441  svs_table_delete (fproto, table_id);
442 
443  return (NULL);
444 }
445 
446 /* *INDENT-OFF* */
447 VLIB_CLI_COMMAND (svs_table_cmd_cli, static) = {
448  .path = "svs table",
449  .short_help = "Source VRF select table [add|delete] [ip4|ip6] table-id X",
450  .function = svs_table_cli,
451 };
452 /* *INDENT-ON* */
453 
454 static clib_error_t *
456  unformat_input_t * input, vlib_cli_command_t * cmd)
457 {
459  fib_protocol_t fproto;
460  vnet_main_t *vnm;
461  u8 enable;
462 
463  vnm = vnet_get_main ();
464  sw_if_index = table_id = ~0;
465  fproto = FIB_PROTOCOL_IP4;
466  enable = 1;
467 
469  {
470  if (unformat (input, "%U", unformat_vnet_sw_interface,
471  vnm, &sw_if_index))
472  ;
473  else if (unformat (input, "enable"))
474  enable = 1;
475  else if (unformat (input, "disable"))
476  enable = 0;
477  else if (unformat (input, "ip4"))
478  fproto = FIB_PROTOCOL_IP4;
479  else if (unformat (input, "ip6"))
480  fproto = FIB_PROTOCOL_IP6;
481  else if (unformat (input, "table-id %d", &table_id))
482  ;
483  else
484  break;
485  }
486 
487  if (~0 == sw_if_index)
488  return clib_error_return (0, "interface must be specified");
489  if (~0 == table_id)
490  return clib_error_return (0, "table-id must be specified");
491 
492  if (enable)
493  svs_enable (fproto, table_id, sw_if_index);
494  else
495  svs_disable (fproto, table_id, sw_if_index);
496 
497  return (NULL);
498 }
499 
500 /* *INDENT-OFF* */
501 VLIB_CLI_COMMAND (svs_enable_cli_cmd, static) = {
502  .path = "svs enable",
503  .short_help = "Source VRF select [enable|disable] [ip4|ip6] <table-id> X <interface>",
504  .function = svs_enable_cli,
505 };
506 /* *INDENT-ON* */
507 
508 static clib_error_t *
510  unformat_input_t * input, vlib_cli_command_t * cmd)
511 {
512  u32 table_id, src_table_id;
513  fib_prefix_t pfx;
514  int rv;
515  u8 add;
516 
517  src_table_id = table_id = ~0;
518  add = 1;
519 
521  {
522  if (unformat (input, "add"))
523  add = 1;
524  else if (unformat (input, "del"))
525  add = 0;
526  else if (unformat (input, "table-id %d", &table_id))
527  ;
528  else if (unformat (input, "src-table-id %d", &src_table_id))
529  ;
530  else if (unformat (input, "%U/%d",
531  unformat_ip4_address, &pfx.fp_addr.ip4, &pfx.fp_len))
532  {
534  }
535  else if (unformat (input, "%U/%d",
536  unformat_ip6_address, &pfx.fp_addr.ip6, &pfx.fp_len))
537  {
539  }
540  else
541  break;
542  }
543 
544  if (~0 == table_id)
545  return clib_error_return (0, "table-id must be specified");
546  if (~0 == src_table_id)
547  return clib_error_return (0, "src-table-id must be specified");
548 
549  if (add)
550  rv = svs_route_add (table_id, &pfx, src_table_id);
551  else
552  rv = svs_route_delete (table_id, &pfx);
553 
554  if (rv != 0)
555  return clib_error_return (0,
556  "failed, rv=%d:%U",
557  (int) rv, format_vnet_api_errno, rv);
558 
559  return (NULL);
560 }
561 
562 /* *INDENT-OFF* */
563 VLIB_CLI_COMMAND (svs_route_cmd_cli, static) = {
564  .path = "svs route",
565  .short_help = "Source VRF select route [add|delete] <table-id> <prefix> <src-table-id>",
566  .function = svs_route_cli,
567 };
568 /* *INDENT-ON* */
569 
570 static clib_error_t *
572  unformat_input_t * input, vlib_cli_command_t * cmd)
573 {
574  fib_protocol_t fproto;
575  u32 ii;
576 
577  vlib_cli_output (vm, "Source VRF select interface to fib-index mappings:");
578  FOR_EACH_FIB_IP_PROTOCOL (fproto)
579  {
580  vlib_cli_output (vm, " %U", format_fib_protocol, fproto);
581  vec_foreach_index (ii, svs_itf_db[fproto])
582  {
583  if (~0 != svs_itf_db[fproto][ii])
585  vnet_get_main (), ii, svs_itf_db[fproto][ii]);
586  }
587  }
588  return (NULL);
589 }
590 
591 /* *INDENT-OFF* */
592 VLIB_CLI_COMMAND (svs_show_cli_cmd, static) = {
593  .path = "show svs",
594  .short_help = "Source VRF select show",
595  .function = svs_show_cli,
596 };
597 /* *INDENT-ON* */
598 
599 static clib_error_t *
601 {
604  };
606 
609  };
611 
615 
616  return (NULL);
617 }
618 
620 
621 /*
622  * fd.io coding-style-patch-verification: ON
623  *
624  * Local Variables:
625  * eval: (c-set-style "gnu")
626  * End:
627  */
void dpo_unlock(dpo_id_t *dpo)
Release a reference counting lock on the DPO.
Definition: dpo.c:373
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index, VLIB_BUFFER_IS_TRACED: trace this buffer.
Definition: buffer.h:124
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:212
enum fib_source_t_ fib_source_t
The different sources that can create a route.
#define vec_foreach_index(var, v)
Iterate over vector indices.
A representation of an MPLS label for imposition in the data-path.
Definition: lookup_dpo.h:65
ip4_table_bind_function_t * function
Definition: ip4.h:92
#define CLIB_UNUSED(x)
Definition: clib.h:82
static u32 ip6_fib_table_fwding_lookup(u32 fib_index, const ip6_address_t *dst)
Definition: ip6_fib.h:67
static uword svs_input_ip4(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: svs.c:342
VNET_FEATURE_INIT(svs_ip4_feat, static)
ip4_address_t src_address
Definition: ip4_packet.h:170
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
int svs_route_delete(u32 table_id, const fib_prefix_t *pfx)
Definition: svs.c:103
static clib_error_t * svs_table_cli(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: svs.c:408
#define NULL
Definition: clib.h:58
u32 fib_table_get_index_for_sw_if_index(fib_protocol_t proto, u32 sw_if_index)
Get the index of the FIB bound to the interface.
Definition: fib_table.c:989
static const dpo_id_t * load_balance_get_fwd_bucket(const load_balance_t *lb, u16 bucket)
#define FIB_PROTOCOL_IP_MAX
Definition outside of enum so it does not need to be included in non-defaulted switch statements...
Definition: fib_types.h:58
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
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:523
int svs_disable(fib_protocol_t fproto, u32 table_id, u32 sw_if_index)
Definition: svs.c:195
svs_next_t_
Definition: svs.c:247
static void svs_ip6_table_bind(ip6_main_t *im, uword opaque, u32 sw_if_index, u32 new_fib_index, u32 old_fib_index)
Definition: svs.c:179
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
unformat_function_t unformat_vnet_sw_interface
static u8 * format_svs_input_trace(u8 *s, va_list *args)
Definition: svs.c:356
ip6_address_t src_address
Definition: ip6_packet.h:307
format_function_t format_vnet_sw_if_index_name
unsigned char u8
Definition: types.h:56
u8 * format_fib_protocol(u8 *s, va_list *ap)
Definition: fib_types.c:33
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
static uword svs_input_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, fib_protocol_t fproto)
Definition: svs.c:259
unformat_function_t unformat_ip4_address
Definition: format.h:68
vl_api_interface_index_t sw_if_index
Definition: gre.api:59
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
static clib_error_t * svs_enable_cli(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: svs.c:455
void fib_table_entry_special_remove(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source)
Remove a &#39;special&#39; entry from the FIB.
Definition: fib_table.c:424
Aggregate type for a prefix.
Definition: fib_types.h:203
#define clib_error_return(e, args...)
Definition: error.h:99
static void svs_table_bind(fib_protocol_t fproto, u32 sw_if_index, u32 itf_fib_index)
Definition: svs.c:152
enum svs_next_t_ svs_next_t
unsigned int u32
Definition: types.h:88
static fib_source_t svs_fib_src
Definition: svs.c:29
int svs_enable(fib_protocol_t fproto, u32 table_id, u32 sw_if_index)
Definition: svs.c:118
u32 fib_table_find(fib_protocol_t proto, u32 table_id)
Get the index of the FIB for a Table-ID.
Definition: fib_table.c:1097
u16 fp_len
The mask length.
Definition: fib_types.h:207
fib_source_t fib_source_allocate(const char *name, fib_source_priority_t prio, fib_source_behaviour_t bh)
Definition: fib_source.c:118
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
Definition: fib_entry.h:116
static lookup_dpo_t * lookup_dpo_get(index_t index)
Definition: lookup_dpo.h:127
ip46_address_t fp_addr
The address type is not deriveable from the fp_addr member.
Definition: fib_types.h:226
long ctx[MAX_CONNS]
Definition: main.c:144
struct _unformat_input_t unformat_input_t
int svs_table_delete(fib_protocol_t fproto, u32 table_id)
Definition: svs.c:40
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:229
static int svs_route_add_i(u32 fib_index, const fib_prefix_t *pfx, u32 src_fib_index)
Definition: svs.c:61
The FIB DPO provieds;.
Definition: load_balance.h:106
ip6_table_bind_callback_t * table_bind_callbacks
Functions to call when interface to table biding changes.
Definition: ip6.h:219
#define PREDICT_FALSE(x)
Definition: clib.h:111
#define always_inline
Definition: ipsec.h:28
ip6_main_t ip6_main
Definition: ip6_forward.c:2703
void lookup_dpo_add_or_lock_w_fib_index(fib_node_index_t fib_index, dpo_proto_t proto, lookup_cast_t cast, lookup_input_t input, lookup_table_t table_config, dpo_id_t *dpo)
Definition: lookup_dpo.c:133
static u8 * format_vnet_api_errno(u8 *s, va_list *args)
Definition: api_errno.h:168
#define vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, bi0, next0)
Finish enqueueing one buffer forward in the graph.
Definition: buffer_node.h:218
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
Get pointer to next frame vector data by (vlib_node_runtime_t, next_index).
Definition: node_funcs.h:338
void fib_table_unlock(u32 fib_index, fib_protocol_t proto, fib_source_t source)
Take a reference counting lock on the table.
Definition: fib_table.c:1291
vlib_main_t * vm
Definition: in2out_ed.c:1810
static clib_error_t * svs_show_cli(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: svs.c:571
unformat_function_t unformat_ip6_address
Definition: format.h:89
static void svs_ip4_table_bind(ip4_main_t *im, uword opaque, u32 sw_if_index, u32 new_fib_index, u32 old_fib_index)
Definition: svs.c:187
walk_rc_t(* svs_walk_fn_t)(fib_protocol_t fproto, u32 table_id, u32 sw_if_index, void *ctx)
Definition: svs.h:40
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
#define UNFORMAT_END_OF_INPUT
Definition: format.h:145
u16 n_vectors
Definition: node.h:397
static_always_inline void vnet_feature_next(u32 *next0, vlib_buffer_t *b0)
Definition: feature.h:302
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Release pointer to next frame vector data.
Definition: main.c:456
static clib_error_t * svs_init(vlib_main_t *vm)
Definition: svs.c:600
vlib_main_t vlib_node_runtime_t * node
Definition: in2out_ed.c:1810
#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
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
Definition: node.h:515
u32 * svs_itf_db[FIB_PROTOCOL_IP_MAX]
Definition: svs.c:27
static uword svs_input_ip6(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: svs.c:349
static load_balance_t * load_balance_get(index_t lbi)
Definition: load_balance.h:220
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
IPv4 main type.
Definition: ip4.h:105
u32 fib_table_find_or_create_and_lock(fib_protocol_t proto, u32 table_id, fib_source_t src)
Get the index of the FIB for a Table-ID.
Definition: fib_table.c:1156
static index_t ip4_fib_forwarding_lookup(u32 fib_index, const ip4_address_t *addr)
Definition: ip4_fib.h:160
dpo_proto_t fib_proto_to_dpo(fib_protocol_t fib_proto)
Definition: fib_types.c:260
void svs_walk(svs_walk_fn_t fn, void *ctx)
Definition: svs.c:225
#define FIB_SOURCE_PRIORITY_LOW
Definition: fib_source.h:274
vlib_node_registration_t svs_ip4_node
(constructor) VLIB_REGISTER_NODE (svs_ip4_node)
Definition: svs.c:367
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace_funcs.h:55
struct svs_input_trace_t_ svs_input_trace_t
ip4_table_bind_callback_t * table_bind_callbacks
Functions to call when interface to table biding changes.
Definition: ip4.h:146
Definition: defs.h:47
int svs_table_add(fib_protocol_t fproto, u32 table_id)
Definition: svs.c:32
index_t dpoi_index
the index of objects of that type
Definition: dpo.h:186
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
VLIB buffer representation.
Definition: buffer.h:102
u64 uword
Definition: types.h:112
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:244
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
Definition: dpo.h:197
ip6_table_bind_function_t * function
Definition: ip6.h:115
#define FOR_EACH_FIB_IP_PROTOCOL(_item)
Definition: fib_types.h:70
#define vnet_buffer(b)
Definition: buffer.h:408
int svs_route_add(u32 table_id, const fib_prefix_t *pfx, u32 source_table_id)
Definition: svs.c:82
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:1079
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
Definition: in2out_ed.c:1811
vlib_node_registration_t svs_ip6_node
(constructor) VLIB_REGISTER_NODE (svs_ip6_node)
Definition: svs.c:381
u32 table_id
Definition: fib_types.api:118
#define vec_validate_init_empty(V, I, INIT)
Make sure vector is long enough for given index and initialize empty space (no header, unspecified alignment)
Definition: vec.h:487
static clib_error_t * svs_route_cli(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: svs.c:509
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:689
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:85
fib_node_index_t lkd_fib_index
The FIB, or interface from which to get a FIB, in which to perform the next lookup;.
Definition: lookup_dpo.h:77
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
Definition: defs.h:46
int vnet_feature_enable_disable(const char *arc_name, const char *node_name, u32 sw_if_index, int enable_disable, void *feature_config, u32 n_feature_config_bytes)
Definition: feature.c:304
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:171