FD.io VPP  v19.04.2-12-g66b1689
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 
29 int
30 svs_table_add (fib_protocol_t fproto, u32 table_id)
31 {
33 
34  return (0);
35 }
36 
37 int
39 {
40  u32 fib_index, ii;
41 
42  fib_index = fib_table_find (fproto, table_id);
43 
44  vec_foreach_index (ii, svs_itf_db[fproto])
45  {
46  if (svs_itf_db[fproto][ii] == fib_index)
47  return VNET_API_ERROR_INSTANCE_IN_USE;
48  }
49 
50  if (~0 == fib_index)
51  return VNET_API_ERROR_NO_SUCH_FIB;
52 
53  fib_table_unlock (fib_index, fproto, FIB_SOURCE_PLUGIN_LOW);
54 
55  return (0);
56 }
57 
58 static int
59 svs_route_add_i (u32 fib_index, const fib_prefix_t * pfx, u32 src_fib_index)
60 {
61  dpo_id_t dpo = DPO_INVALID;
62 
63 
69 
70  fib_table_entry_special_dpo_add (fib_index, pfx,
73 
74  dpo_unlock (&dpo);
75 
76  return (0);
77 }
78 
79 int
80 svs_route_add (u32 table_id, const fib_prefix_t * pfx, u32 source_table_id)
81 {
82  u32 fib_index, src_fib_index;
83  int rv;
84 
85  fib_index = fib_table_find (pfx->fp_proto, table_id);
86 
87  if (~0 == fib_index)
88  return VNET_API_ERROR_NO_SUCH_FIB;
89 
90  src_fib_index = fib_table_find (pfx->fp_proto, source_table_id);
91 
92  if (~0 == src_fib_index)
93  return (VNET_API_ERROR_NO_SUCH_FIB);
94 
95  rv = svs_route_add_i (fib_index, pfx, src_fib_index);
96 
97  return (rv);
98 }
99 
100 int
101 svs_route_delete (u32 table_id, const fib_prefix_t * pfx)
102 {
103  u32 fib_index;
104 
105  fib_index = fib_table_find (pfx->fp_proto, table_id);
106 
107  if (~0 == fib_index)
108  return VNET_API_ERROR_NO_SUCH_FIB;
109 
111 
112  return (0);
113 }
114 
115 int
117 {
118  fib_prefix_t pfx = {
119  .fp_proto = fproto,
120  };
121  u32 fib_index;
122 
123  fib_index = fib_table_find (fproto, table_id);
124 
125  if (~0 == fib_index)
126  return VNET_API_ERROR_NO_SUCH_FIB;
127 
128  /*
129  * now we know which interface the table will serve, we can add the default
130  * route to use the table that the interface is bound to.
131  */
132  svs_route_add_i (fib_index, &pfx,
133  fib_table_get_index_for_sw_if_index (fproto, sw_if_index));
134 
135  vec_validate_init_empty (svs_itf_db[fproto], sw_if_index, ~0);
136 
137  svs_itf_db[fproto][sw_if_index] = fib_index;
138 
140  "ip4-unicast" :
141  "ip6-unicast"),
142  (FIB_PROTOCOL_IP4 == fproto ?
143  "svs-ip4" :
144  "svs-ip6"), sw_if_index, 1, NULL, 0);
145 
146  return (0);
147 }
148 
149 static void
151 {
152  /*
153  * update the default route to use the interface's newly bound FIB
154  */
155  u32 svs_fib_index;
156 
157  if (sw_if_index >= vec_len (svs_itf_db[FIB_PROTOCOL_IP6]))
158  return;
159 
160  svs_fib_index = svs_itf_db[FIB_PROTOCOL_IP6][sw_if_index];
161 
162  if (~0 != svs_fib_index)
163  {
164  fib_prefix_t pfx = {
165  .fp_proto = fproto,
166  };
167 
168  svs_route_add (svs_fib_index, &pfx, itf_fib_index);
169  }
170  /*
171  * else
172  * no SVS enable on this interface
173  */
174 }
175 
176 static void
178  uword opaque,
179  u32 sw_if_index, u32 new_fib_index, u32 old_fib_index)
180 {
181  svs_table_bind (FIB_PROTOCOL_IP6, sw_if_index, new_fib_index);
182 }
183 
184 static void
186  uword opaque,
187  u32 sw_if_index, u32 new_fib_index, u32 old_fib_index)
188 {
189  svs_table_bind (FIB_PROTOCOL_IP4, sw_if_index, new_fib_index);
190 }
191 
192 int
194 {
195  fib_prefix_t pfx = {
196  .fp_proto = fproto,
197  };
198  u32 fib_index;
199 
200  fib_index = fib_table_find (fproto, table_id);
201 
202  if (~0 == fib_index)
203  return VNET_API_ERROR_NO_SUCH_FIB;
204 
205  if (sw_if_index >= vec_len (svs_itf_db[fproto]))
206  return VNET_API_ERROR_INVALID_SW_IF_INDEX;
207 
208  svs_itf_db[fproto][sw_if_index] = ~0;
209 
211  "ip4-unicast" :
212  "ip6-unicast"),
213  (FIB_PROTOCOL_IP4 == fproto ?
214  "svs-ip4" :
215  "svs-ip6"), sw_if_index, 0, NULL, 0);
216 
218 
219  return (0);
220 }
221 
222 void
224 {
225  fib_protocol_t fproto;
226  u32 ii, fib_index;
227 
228  FOR_EACH_FIB_IP_PROTOCOL (fproto)
229  {
230  vec_foreach_index (ii, svs_itf_db[fproto])
231  {
232  fib_index = svs_itf_db[fproto][ii];
233 
234  if (~0 != fib_index)
235  {
236  if (WALK_CONTINUE != fn (fproto,
237  fib_table_get_table_id (fib_index, fproto),
238  ii, ctx))
239  return;
240  }
241  }
242  }
243 }
244 
245 typedef enum svs_next_t_
246 {
249 } svs_next_t;
250 
251 typedef struct svs_input_trace_t_
252 {
255 
258  vlib_node_runtime_t * node,
259  vlib_frame_t * frame, fib_protocol_t fproto)
260 {
261  u32 n_left_from, *from, *to_next, next_index;
262 
263  from = vlib_frame_vector_args (frame);
264  n_left_from = frame->n_vectors;
265  next_index = node->cached_next_index;
266 
267  while (n_left_from > 0)
268  {
269  u32 n_left_to_next;
270 
271  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
272 
273  while (n_left_from > 0 && n_left_to_next > 0)
274  {
275  const load_balance_t *lb0;
276  const lookup_dpo_t *lk0;
277  u32 bi0, sw_if_index0;
278  const dpo_id_t *dpo0;
279  vlib_buffer_t *b0;
280  svs_next_t next0;
281  index_t lbi0;
282 
283  bi0 = from[0];
284  to_next[0] = bi0;
285  from += 1;
286  to_next += 1;
287  n_left_from -= 1;
288  n_left_to_next -= 1;
289 
290  b0 = vlib_get_buffer (vm, bi0);
291  sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
292 
293  if (FIB_PROTOCOL_IP4 == fproto)
294  {
295  ip4_header_t *ip0;
296 
297  ip0 = vlib_buffer_get_current (b0);
298  lbi0 =
299  ip4_fib_forwarding_lookup (svs_itf_db[fproto][sw_if_index0],
300  &ip0->src_address);
301  }
302  else
303  {
304  ip6_header_t *ip0;
305 
306  ip0 = vlib_buffer_get_current (b0);
308  svs_itf_db[fproto]
309  [sw_if_index0],
310  &ip0->src_address);
311  }
312  lb0 = load_balance_get (lbi0);
313  dpo0 = load_balance_get_fwd_bucket (lb0, 0);
314  lk0 = lookup_dpo_get (dpo0->dpoi_index);
315 
316  vnet_buffer (b0)->sw_if_index[VLIB_TX] = lk0->lkd_fib_index;
317 
318  vnet_feature_next (&next0, b0);
319 
320  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
321  {
322  svs_input_trace_t *tr;
323 
324  tr = vlib_add_trace (vm, node, b0, sizeof (*tr));
325  tr->fib_index = vnet_buffer (b0)->sw_if_index[VLIB_TX];
326  }
327 
328  /* verify speculative enqueue, maybe switch current next frame */
329  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
330  to_next, n_left_to_next, bi0,
331  next0);
332  }
333 
334  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
335  }
336 
337  return frame->n_vectors;
338 }
339 
340 static uword
342  vlib_node_runtime_t * node, vlib_frame_t * frame)
343 {
344  return svs_input_inline (vm, node, frame, FIB_PROTOCOL_IP4);
345 }
346 
347 static uword
349  vlib_node_runtime_t * node, vlib_frame_t * frame)
350 {
351  return svs_input_inline (vm, node, frame, FIB_PROTOCOL_IP6);
352 }
353 
354 static u8 *
355 format_svs_input_trace (u8 * s, va_list * args)
356 {
357  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
358  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
359  svs_input_trace_t *t = va_arg (*args, svs_input_trace_t *);
360 
361  s = format (s, " fib_index %d", t->fib_index);
362  return s;
363 }
364 
365 /* *INDENT-OFF* */
367 {
368  .function = svs_input_ip4,
369  .name = "svs-ip4",
370  .vector_size = sizeof (u32),
371  .format_trace = format_svs_input_trace,
372  .type = VLIB_NODE_TYPE_INTERNAL,
373  .n_next_nodes = SVS_N_NEXT,
374  .next_nodes =
375  {
376  [SVS_NEXT_DROP] = "error-drop",
377  }
378 };
379 
381 {
382  .function = svs_input_ip6,
383  .name = "svs-ip6",
384  .vector_size = sizeof (u32),
385  .format_trace = format_svs_input_trace,
386  .type = VLIB_NODE_TYPE_INTERNAL,
387  .next_nodes =
388  {
389  [SVS_NEXT_DROP] = "error-drop",
390  }
391 };
392 
393 VNET_FEATURE_INIT (svs_ip4_feat, static) =
394 {
395  .arc_name = "ip4-unicast",
396  .node_name = "svs-ip4",
397 };
398 
399 VNET_FEATURE_INIT (svs_ip6_feat, static) =
400 {
401  .arc_name = "ip6-unicast",
402  .node_name = "svs-ip6",
403 };
404 /* *INDENT-ON* */
405 
406 static clib_error_t *
408  unformat_input_t * input, vlib_cli_command_t * cmd)
409 {
410  fib_protocol_t fproto;
411  u32 table_id;
412  u8 add;
413 
414  fproto = FIB_PROTOCOL_IP4;
415  table_id = ~0;
416  add = 1;
417 
419  {
420  if (unformat (input, "add"))
421  add = 1;
422  else if (unformat (input, "del"))
423  add = 0;
424  else if (unformat (input, "ip4"))
425  fproto = FIB_PROTOCOL_IP4;
426  else if (unformat (input, "ip6"))
427  fproto = FIB_PROTOCOL_IP6;
428  else if (unformat (input, "table-id %d", &table_id))
429  ;
430  else
431  break;
432  }
433 
434  if (~0 == table_id)
435  return clib_error_return (0, "table-id must be specified");
436 
437  if (add)
438  svs_table_add (fproto, table_id);
439  else
440  svs_table_delete (fproto, table_id);
441 
442  return (NULL);
443 }
444 
445 /* *INDENT-OFF* */
446 VLIB_CLI_COMMAND (svs_table_cmd_cli, static) = {
447  .path = "svs table",
448  .short_help = "Source VRF select table [add|delete] [ip4|ip6] table-id X",
449  .function = svs_table_cli,
450 };
451 /* *INDENT-ON* */
452 
453 static clib_error_t *
455  unformat_input_t * input, vlib_cli_command_t * cmd)
456 {
457  u32 sw_if_index, table_id;
458  fib_protocol_t fproto;
459  vnet_main_t *vnm;
460  u8 enable;
461 
462  vnm = vnet_get_main ();
463  sw_if_index = table_id = ~0;
464  fproto = FIB_PROTOCOL_IP4;
465  enable = 1;
466 
468  {
469  if (unformat (input, "%U", unformat_vnet_sw_interface,
470  vnm, &sw_if_index))
471  ;
472  else if (unformat (input, "enable"))
473  enable = 1;
474  else if (unformat (input, "disable"))
475  enable = 0;
476  else if (unformat (input, "ip4"))
477  fproto = FIB_PROTOCOL_IP4;
478  else if (unformat (input, "ip6"))
479  fproto = FIB_PROTOCOL_IP6;
480  else if (unformat (input, "table-id %d", &table_id))
481  ;
482  else
483  break;
484  }
485 
486  if (~0 == sw_if_index)
487  return clib_error_return (0, "interface must be specified");
488  if (~0 == table_id)
489  return clib_error_return (0, "table-id must be specified");
490 
491  if (enable)
492  svs_enable (fproto, table_id, sw_if_index);
493  else
494  svs_disable (fproto, table_id, sw_if_index);
495 
496  return (NULL);
497 }
498 
499 /* *INDENT-OFF* */
500 VLIB_CLI_COMMAND (svs_enable_cli_cmd, static) = {
501  .path = "svs enable",
502  .short_help = "Source VRF select [enable|disable] [ip4|ip6] <table-id> X <interface>",
503  .function = svs_enable_cli,
504 };
505 /* *INDENT-ON* */
506 
507 static clib_error_t *
509  unformat_input_t * input, vlib_cli_command_t * cmd)
510 {
511  u32 table_id, src_table_id;
512  fib_prefix_t pfx;
513  int rv;
514  u8 add;
515 
516  src_table_id = table_id = ~0;
517  add = 1;
518 
520  {
521  if (unformat (input, "add"))
522  add = 1;
523  else if (unformat (input, "del"))
524  add = 0;
525  else if (unformat (input, "table-id %d", &table_id))
526  ;
527  else if (unformat (input, "src-table-id %d", &src_table_id))
528  ;
529  else if (unformat (input, "%U/%d",
530  unformat_ip4_address, &pfx.fp_addr.ip4, &pfx.fp_len))
531  {
533  }
534  else if (unformat (input, "%U/%d",
535  unformat_ip6_address, &pfx.fp_addr.ip6, &pfx.fp_len))
536  {
538  }
539  else
540  break;
541  }
542 
543  if (~0 == table_id)
544  return clib_error_return (0, "table-id must be specified");
545  if (~0 == src_table_id)
546  return clib_error_return (0, "src-table-id must be specified");
547 
548  if (add)
549  rv = svs_route_add (table_id, &pfx, src_table_id);
550  else
551  rv = svs_route_delete (table_id, &pfx);
552 
553  if (rv != 0)
554  return clib_error_return (0,
555  "failed, rv=%d:%U",
556  (int) rv, format_vnet_api_errno, rv);
557 
558  return (NULL);
559 }
560 
561 /* *INDENT-OFF* */
562 VLIB_CLI_COMMAND (svs_route_cmd_cli, static) = {
563  .path = "svs route",
564  .short_help = "Source VRF select route [add|delete] <table-id> <prefix> <src-table-id>",
565  .function = svs_route_cli,
566 };
567 /* *INDENT-ON* */
568 
569 static clib_error_t *
571  unformat_input_t * input, vlib_cli_command_t * cmd)
572 {
573  fib_protocol_t fproto;
574  u32 ii;
575 
576  vlib_cli_output (vm, "Source VRF select interface to fib-index mappings:");
577  FOR_EACH_FIB_IP_PROTOCOL (fproto)
578  {
579  vlib_cli_output (vm, " %U", format_fib_protocol, fproto);
580  vec_foreach_index (ii, svs_itf_db[fproto])
581  {
582  if (~0 != svs_itf_db[fproto][ii])
584  vnet_get_main (), ii, svs_itf_db[fproto][ii]);
585  }
586  }
587  return (NULL);
588 }
589 
590 /* *INDENT-OFF* */
591 VLIB_CLI_COMMAND (svs_show_cli_cmd, static) = {
592  .path = "show svs",
593  .short_help = "Source VRF select show",
594  .function = svs_show_cli,
595 };
596 /* *INDENT-ON* */
597 
598 static clib_error_t *
600 {
603  };
605 
608  };
610 
611  return (NULL);
612 }
613 
615 
616 /*
617  * fd.io coding-style-patch-verification: ON
618  *
619  * Local Variables:
620  * eval: (c-set-style "gnu")
621  * End:
622  */
void dpo_unlock(dpo_id_t *dpo)
Release a reference counting lock on the DPO.
Definition: dpo.c:372
u32 sw_if_index
Definition: ipsec_gre.api:37
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
#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:83
#define CLIB_UNUSED(x)
Definition: clib.h:82
static uword svs_input_ip4(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: svs.c:341
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:47
int svs_route_delete(u32 table_id, const fib_prefix_t *pfx)
Definition: svs.c:101
static clib_error_t * svs_table_cli(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: svs.c:407
#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:956
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
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:522
int svs_disable(fib_protocol_t fproto, u32 table_id, u32 sw_if_index)
Definition: svs.c:193
svs_next_t_
Definition: svs.c:245
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:177
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:355
static u32 ip6_fib_table_fwding_lookup(ip6_main_t *im, u32 fib_index, const ip6_address_t *dst)
Definition: ip6_fib.h:67
ip6_address_t src_address
Definition: ip6_packet.h:385
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:32
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:257
unformat_function_t unformat_ip4_address
Definition: format.h:70
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:163
static clib_error_t * svs_enable_cli(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: svs.c:454
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:407
#define always_inline
Definition: clib.h:98
Aggregrate 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:150
enum svs_next_t_ svs_next_t
unsigned int u32
Definition: types.h:88
int svs_enable(fib_protocol_t fproto, u32 table_id, u32 sw_if_index)
Definition: svs.c:116
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:1064
u16 fp_len
The mask length.
Definition: fib_types.h:207
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
Definition: fib_entry.h:279
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:38
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:59
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:218
#define PREDICT_FALSE(x)
Definition: clib.h:111
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:163
#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:368
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:1237
static clib_error_t * svs_show_cli(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: svs.c:570
unformat_function_t unformat_ip6_address
Definition: format.h:91
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:185
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:144
u16 n_vectors
Definition: node.h:395
vlib_main_t * vm
Definition: buffer.c:312
static_always_inline void vnet_feature_next(u32 *next0, vlib_buffer_t *b0)
Definition: feature.h:295
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:465
static clib_error_t * svs_init(vlib_main_t *vm)
Definition: svs.c:599
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:155
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:307
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
Definition: node.h:514
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:348
ip6_main_t ip6_main
Definition: ip6_forward.c:2688
static load_balance_t * load_balance_get(index_t lbi)
Definition: load_balance.h:219
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:1053
IPv4 main type.
Definition: ip4.h:96
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:1123
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:237
void svs_walk(svs_walk_fn_t fn, void *ctx)
Definition: svs.c:223
vlib_node_registration_t svs_ip4_node
(constructor) VLIB_REGISTER_NODE (svs_ip4_node)
Definition: svs.c:366
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:57
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:133
Definition: defs.h:47
int svs_table_add(fib_protocol_t fproto, u32 table_id)
Definition: svs.c:30
index_t dpoi_index
the index of objects of that type
Definition: dpo.h:184
#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:274
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
Definition: dpo.h:195
ip6_table_bind_function_t * function
Definition: ip6.h:114
#define FOR_EACH_FIB_IP_PROTOCOL(_item)
Definition: fib_types.h:70
#define vnet_buffer(b)
Definition: buffer.h:369
int svs_route_add(u32 table_id, const fib_prefix_t *pfx, u32 source_table_id)
Definition: svs.c:80
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:905
vlib_node_registration_t svs_ip6_node
(constructor) VLIB_REGISTER_NODE (svs_ip6_node)
Definition: svs.c:380
#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:486
static clib_error_t * svs_route_cli(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: svs.c:508
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:762
A low (below routing) priority source a plugin can use.
Definition: fib_entry.h:82
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:972
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:274
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:170