FD.io VPP  v18.10-34-gcce845e
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  u32 fib_index;
196 
197  fib_index = fib_table_find (fproto, table_id);
198 
199  if (~0 == fib_index)
200  return VNET_API_ERROR_NO_SUCH_FIB;
201 
202  if (sw_if_index >= vec_len (svs_itf_db[fproto]))
203  return VNET_API_ERROR_INVALID_SW_IF_INDEX;
204 
205  svs_itf_db[fproto][sw_if_index] = ~0;
206 
208  "ip4-unicast" :
209  "ip6-unicast"),
210  (FIB_PROTOCOL_IP4 == fproto ?
211  "svs-ip4" :
212  "svs-ip6"), sw_if_index, 0, NULL, 0);
213 
214  return (0);
215 }
216 
217 void
219 {
220  fib_protocol_t fproto;
221  u32 ii, fib_index;
222 
223  FOR_EACH_FIB_IP_PROTOCOL (fproto)
224  {
225  vec_foreach_index (ii, svs_itf_db[fproto])
226  {
227  fib_index = svs_itf_db[fproto][ii];
228 
229  if (~0 != fib_index)
230  {
231  if (WALK_CONTINUE != fn (fproto,
232  fib_table_get_table_id (fib_index, fproto),
233  ii, ctx))
234  return;
235  }
236  }
237  }
238 }
239 
240 typedef enum svs_next_t_
241 {
244 } svs_next_t;
245 
246 typedef struct svs_input_trace_t_
247 {
250 
253  vlib_node_runtime_t * node,
254  vlib_frame_t * frame, fib_protocol_t fproto)
255 {
256  u32 n_left_from, *from, *to_next, next_index;
257 
258  from = vlib_frame_vector_args (frame);
259  n_left_from = frame->n_vectors;
260  next_index = node->cached_next_index;
261 
262  while (n_left_from > 0)
263  {
264  u32 n_left_to_next;
265 
266  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
267 
268  while (n_left_from > 0 && n_left_to_next > 0)
269  {
270  const load_balance_t *lb0;
271  const lookup_dpo_t *lk0;
272  u32 bi0, sw_if_index0;
273  const dpo_id_t *dpo0;
274  vlib_buffer_t *b0;
275  svs_next_t next0;
276  index_t lbi0;
277 
278  bi0 = from[0];
279  to_next[0] = bi0;
280  from += 1;
281  to_next += 1;
282  n_left_from -= 1;
283  n_left_to_next -= 1;
284 
285  b0 = vlib_get_buffer (vm, bi0);
286  sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
287 
288  if (FIB_PROTOCOL_IP4 == fproto)
289  {
290  ip4_header_t *ip0;
291 
292  ip0 = vlib_buffer_get_current (b0);
293  lbi0 =
294  ip4_fib_forwarding_lookup (svs_itf_db[fproto][sw_if_index0],
295  &ip0->src_address);
296  }
297  else
298  {
299  ip6_header_t *ip0;
300 
301  ip0 = vlib_buffer_get_current (b0);
303  svs_itf_db[fproto]
304  [sw_if_index0],
305  &ip0->src_address);
306  }
307  lb0 = load_balance_get (lbi0);
308  dpo0 = load_balance_get_fwd_bucket (lb0, 0);
309  lk0 = lookup_dpo_get (dpo0->dpoi_index);
310 
311  vnet_buffer (b0)->sw_if_index[VLIB_TX] = lk0->lkd_fib_index;
312 
313  vnet_feature_next (&next0, b0);
314 
315  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
316  {
317  svs_input_trace_t *tr;
318 
319  tr = vlib_add_trace (vm, node, b0, sizeof (*tr));
320  tr->fib_index = vnet_buffer (b0)->sw_if_index[VLIB_TX];
321  }
322 
323  /* verify speculative enqueue, maybe switch current next frame */
324  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
325  to_next, n_left_to_next, bi0,
326  next0);
327  }
328 
329  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
330  }
331 
332  return frame->n_vectors;
333 }
334 
335 static uword
337  vlib_node_runtime_t * node, vlib_frame_t * frame)
338 {
339  return svs_input_inline (vm, node, frame, FIB_PROTOCOL_IP4);
340 }
341 
342 static uword
344  vlib_node_runtime_t * node, vlib_frame_t * frame)
345 {
346  return svs_input_inline (vm, node, frame, FIB_PROTOCOL_IP6);
347 }
348 
349 static u8 *
350 format_svs_input_trace (u8 * s, va_list * args)
351 {
352  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
353  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
354  svs_input_trace_t *t = va_arg (*args, svs_input_trace_t *);
355 
356  s = format (s, " fib_index %d", t->fib_index);
357  return s;
358 }
359 
360 /* *INDENT-OFF* */
362 {
363  .function = svs_input_ip4,
364  .name = "svs-ip4",
365  .vector_size = sizeof (u32),
366  .format_trace = format_svs_input_trace,
367  .type = VLIB_NODE_TYPE_INTERNAL,
368  .n_next_nodes = SVS_N_NEXT,
369  .next_nodes =
370  {
371  [SVS_NEXT_DROP] = "error-drop",
372  }
373 };
374 
376 {
377  .function = svs_input_ip6,
378  .name = "svs-ip6",
379  .vector_size = sizeof (u32),
380  .format_trace = format_svs_input_trace,
381  .type = VLIB_NODE_TYPE_INTERNAL,
382  .next_nodes =
383  {
384  [SVS_NEXT_DROP] = "error-drop",
385  }
386 };
387 
388 VNET_FEATURE_INIT (svs_ip4_feat, static) =
389 {
390  .arc_name = "ip4-unicast",
391  .node_name = "svs-ip4",
392 };
393 
394 VNET_FEATURE_INIT (svs_ip6_feat, static) =
395 {
396  .arc_name = "ip6-unicast",
397  .node_name = "svs-ip6",
398 };
399 /* *INDENT-ON* */
400 
401 static clib_error_t *
403  unformat_input_t * input, vlib_cli_command_t * cmd)
404 {
405  fib_protocol_t fproto;
406  u32 table_id;
407  u8 add;
408 
409  fproto = FIB_PROTOCOL_IP4;
410  table_id = ~0;
411  add = 1;
412 
414  {
415  if (unformat (input, "add"))
416  add = 1;
417  else if (unformat (input, "del"))
418  add = 0;
419  else if (unformat (input, "ip4"))
420  fproto = FIB_PROTOCOL_IP4;
421  else if (unformat (input, "ip6"))
422  fproto = FIB_PROTOCOL_IP6;
423  else if (unformat (input, "table-id %d", &table_id))
424  ;
425  else
426  break;
427  }
428 
429  if (~0 == table_id)
430  return clib_error_return (0, "table-id must be specified");
431 
432  if (add)
433  svs_table_add (fproto, table_id);
434  else
435  svs_table_delete (fproto, table_id);
436 
437  return (NULL);
438 }
439 
440 /* *INDENT-OFF* */
441 VLIB_CLI_COMMAND (svs_table_cmd_cli, static) = {
442  .path = "svs table",
443  .short_help = "Source VRF select table [add|delete] [ip4|ip6] table-id X",
444  .function = svs_table_cli,
445 };
446 /* *INDENT-ON* */
447 
448 static clib_error_t *
450  unformat_input_t * input, vlib_cli_command_t * cmd)
451 {
452  u32 sw_if_index, table_id;
453  fib_protocol_t fproto;
454  vnet_main_t *vnm;
455  u8 enable;
456 
457  vnm = vnet_get_main ();
458  sw_if_index = table_id = ~0;
459  fproto = FIB_PROTOCOL_IP4;
460  enable = 1;
461 
463  {
464  if (unformat (input, "%U", unformat_vnet_sw_interface,
465  vnm, &sw_if_index))
466  ;
467  else if (unformat (input, "enable"))
468  enable = 1;
469  else if (unformat (input, "disable"))
470  enable = 0;
471  else if (unformat (input, "ip4"))
472  fproto = FIB_PROTOCOL_IP4;
473  else if (unformat (input, "ip6"))
474  fproto = FIB_PROTOCOL_IP6;
475  else if (unformat (input, "table-id %d", &table_id))
476  ;
477  else
478  break;
479  }
480 
481  if (~0 == sw_if_index)
482  return clib_error_return (0, "interface must be specified");
483  if (~0 == table_id)
484  return clib_error_return (0, "table-id must be specified");
485 
486  if (enable)
487  svs_enable (fproto, table_id, sw_if_index);
488  else
489  svs_disable (fproto, table_id, sw_if_index);
490 
491  return (NULL);
492 }
493 
494 /* *INDENT-OFF* */
495 VLIB_CLI_COMMAND (svs_enable_cli_cmd, static) = {
496  .path = "svs enable",
497  .short_help = "Source VRF select [enable|disable] [ip4|ip6] <table-id> X <interface>",
498  .function = svs_enable_cli,
499 };
500 /* *INDENT-ON* */
501 
502 static clib_error_t *
504  unformat_input_t * input, vlib_cli_command_t * cmd)
505 {
506  u32 table_id, src_table_id;
507  fib_prefix_t pfx;
508  int rv;
509  u8 add;
510 
511  src_table_id = table_id = ~0;
512  add = 1;
513 
515  {
516  if (unformat (input, "add"))
517  add = 1;
518  else if (unformat (input, "del"))
519  add = 0;
520  else if (unformat (input, "table-id %d", &table_id))
521  ;
522  else if (unformat (input, "src-table-id %d", &src_table_id))
523  ;
524  else if (unformat (input, "%U/%d",
525  unformat_ip4_address, &pfx.fp_addr.ip4, &pfx.fp_len))
526  {
528  }
529  else if (unformat (input, "%U/%d",
530  unformat_ip6_address, &pfx.fp_addr.ip6, &pfx.fp_len))
531  {
533  }
534  else
535  break;
536  }
537 
538  if (~0 == table_id)
539  return clib_error_return (0, "table-id must be specified");
540  if (~0 == src_table_id)
541  return clib_error_return (0, "src-table-id must be specified");
542 
543  if (add)
544  rv = svs_route_add (table_id, &pfx, src_table_id);
545  else
546  rv = svs_route_delete (table_id, &pfx);
547 
548  if (rv != 0)
549  return clib_error_return (0,
550  "failed, rv=%d:%U",
551  (int) rv, format_vnet_api_errno, rv);
552 
553  return (NULL);
554 }
555 
556 /* *INDENT-OFF* */
557 VLIB_CLI_COMMAND (svs_route_cmd_cli, static) = {
558  .path = "svs route",
559  .short_help = "Source VRF select route [add|delete] <table-id> <prefix> <src-table-id>",
560  .function = svs_route_cli,
561 };
562 /* *INDENT-ON* */
563 
564 static clib_error_t *
566  unformat_input_t * input, vlib_cli_command_t * cmd)
567 {
568  fib_protocol_t fproto;
569  u32 ii;
570 
571  vlib_cli_output (vm, "Source VRF select interface to fib-index mappings:");
572  FOR_EACH_FIB_IP_PROTOCOL (fproto)
573  {
574  vlib_cli_output (vm, " %U", format_fib_protocol, fproto);
575  vec_foreach_index (ii, svs_itf_db[fproto])
576  {
577  if (~0 != svs_itf_db[fproto][ii])
579  vnet_get_main (), ii, svs_itf_db[fproto][ii]);
580  }
581  }
582  return (NULL);
583 }
584 
585 /* *INDENT-OFF* */
586 VLIB_CLI_COMMAND (svs_show_cli_cmd, static) = {
587  .path = "show svs",
588  .short_help = "Source VRF select show",
589  .function = svs_show_cli,
590 };
591 /* *INDENT-ON* */
592 
593 static clib_error_t *
595 {
598  };
600 
603  };
605 
606  return (NULL);
607 }
608 
610 
611 /*
612  * fd.io coding-style-patch-verification: ON
613  *
614  * Local Variables:
615  * eval: (c-set-style "gnu")
616  * End:
617  */
void dpo_unlock(dpo_id_t *dpo)
Release a reference counting lock on the DPO.
Definition: dpo.c:372
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:81
static uword svs_input_ip4(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: svs.c:336
VNET_FEATURE_INIT(svs_ip4_feat, static)
ip4_address_t src_address
Definition: ip4_packet.h:169
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:402
#define NULL
Definition: clib.h:57
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:523
int svs_disable(fib_protocol_t fproto, u32 table_id, u32 sw_if_index)
Definition: svs.c:193
svs_next_t_
Definition: svs.c:240
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:419
unformat_function_t unformat_vnet_sw_interface
static u8 * format_svs_input_trace(u8 *s, va_list *args)
Definition: svs.c:350
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:378
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:252
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:449
u32 sw_if_index
Definition: vxlan_gbp.api:39
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:94
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:205
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:84
ip6_table_bind_callback_t * table_bind_callbacks
Functions to call when interface to table biding changes.
Definition: ip6.h:200
#define PREDICT_FALSE(x)
Definition: clib.h:107
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:160
#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:364
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:1236
static clib_error_t * svs_show_cli(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: svs.c:565
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:155
#define UNFORMAT_END_OF_INPUT
Definition: format.h:144
u16 n_vectors
Definition: node.h:401
vlib_main_t * vm
Definition: buffer.c:294
static_always_inline void vnet_feature_next(u32 *next0, vlib_buffer_t *b0)
Definition: feature.h:246
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:455
static clib_error_t * svs_init(vlib_main_t *vm)
Definition: svs.c:594
#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:513
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:343
ip6_main_t ip6_main
Definition: ip6_forward.c:2590
static load_balance_t * load_balance_get(index_t lbi)
Definition: load_balance.h:200
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:218
vlib_node_registration_t svs_ip4_node
(constructor) VLIB_REGISTER_NODE (svs_ip4_node)
Definition: svs.c:361
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)
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:267
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
Definition: dpo.h:195
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:344
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:900
vlib_node_registration_t svs_ip6_node
(constructor) VLIB_REGISTER_NODE (svs_ip6_node)
Definition: svs.c:375
#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
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:116
static clib_error_t * svs_route_cli(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: svs.c:503
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:725
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:58
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:233
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:170