FD.io VPP  v18.07-rc0-415-g6c78436
Vector Packet Processing
abf_itf_attach.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
17 #include <vnet/fib/fib_path_list.h>
18 #include <plugins/acl/exports.h>
19 
20 /**
21  * Forward declarations;
22  */
25 
26 /**
27  * FIB node registered type for the bonds
28  */
30 
31 /**
32  * Pool of ABF interface attachment objects
33  */
35 
36 /**
37  * A per interface vector of attached policies. used in the data-plane
38  */
40 
41 /**
42  * Per interface values of ACL lookup context IDs. used in the data-plane
43  */
45 
46 /**
47  * ABF ACL module user id returned during the initialization
48  */
50 /*
51  * ACL plugin method vtable
52  */
53 
55 
56 /**
57  * A DB of attachments; key={abf_index,sw_if_index}
58  */
60 
61 static u64
62 abf_itf_attach_mk_key (u32 abf_index, u32 sw_if_index)
63 {
64  u64 key;
65 
66  key = abf_index;
67  key = key << 32;
68  key |= sw_if_index;
69 
70  return (key);
71 }
72 
73 static abf_itf_attach_t *
74 abf_itf_attach_db_find (u32 abf_index, u32 sw_if_index)
75 {
76  uword *p;
77  u64 key;
78 
79  key = abf_itf_attach_mk_key (abf_index, sw_if_index);
80 
81  p = hash_get (abf_itf_attach_db, key);
82 
83  if (NULL != p)
84  return (pool_elt_at_index (abf_itf_attach_pool, p[0]));
85 
86  return (NULL);
87 }
88 
89 static void
90 abf_itf_attach_db_add (u32 abf_index, u32 sw_if_index, abf_itf_attach_t * aia)
91 {
92  u64 key;
93 
94  key = abf_itf_attach_mk_key (abf_index, sw_if_index);
95 
96  hash_set (abf_itf_attach_db, key, aia - abf_itf_attach_pool);
97 }
98 
99 static void
100 abf_itf_attach_db_del (u32 abf_index, u32 sw_if_index)
101 {
102  u64 key;
103 
104  key = abf_itf_attach_mk_key (abf_index, sw_if_index);
105 
107 }
108 
109 static void
111 {
112  /*
113  * stack the DPO on the forwarding contributed by the path-list
114  */
115  dpo_id_t via_dpo = DPO_INVALID;
116  abf_policy_t *ap;
117 
118  ap = abf_policy_get (aia->aia_abf);
119 
121  (FIB_PROTOCOL_IP4 == aia->aia_proto ?
125  &via_dpo);
126 
128  abf_ip4_node.index :
129  abf_ip6_node.index), &aia->aia_dpo, &via_dpo);
130  dpo_reset (&via_dpo);
131 }
132 
133 static int
134 abf_cmp_attach_for_sort (void *v1, void *v2)
135 {
136  const abf_itf_attach_t *aia1;
137  const abf_itf_attach_t *aia2;
138 
139  aia1 = abf_itf_attach_get (*(u32 *) v1);
140  aia2 = abf_itf_attach_get (*(u32 *) v2);
141 
142  return (aia1->aia_prio - aia2->aia_prio);
143 }
144 
145 void
146 abf_setup_acl_lc (fib_protocol_t fproto, u32 sw_if_index)
147 {
148  u32 *acl_vec = 0;
149  u32 *aiai;
150  abf_itf_attach_t *aia;
151 
152  if (~0 == abf_alctx_per_itf[fproto][sw_if_index])
153  return;
154 
155  vec_foreach (aiai, abf_per_itf[fproto][sw_if_index])
156  {
157  aia = abf_itf_attach_get (*aiai);
158  vec_add1 (acl_vec, aia->aia_acl);
159  }
160  acl_plugin.set_acl_vec_for_context (abf_alctx_per_itf[fproto][sw_if_index],
161  acl_vec);
162  vec_free (acl_vec);
163 }
164 
165 int
167  u32 policy_id, u32 priority, u32 sw_if_index)
168 {
169  abf_itf_attach_t *aia;
170  abf_policy_t *ap;
171  u32 api, aiai;
172 
173  api = abf_policy_find (policy_id);
174 
175  ASSERT (INDEX_INVALID != api);
176  ap = abf_policy_get (api);
177 
178  /*
179  * check this is not a duplicate
180  */
181  aia = abf_itf_attach_db_find (policy_id, sw_if_index);
182 
183  if (NULL != aia)
184  return (VNET_API_ERROR_ENTRY_ALREADY_EXISTS);
185 
186  /*
187  * construt a new attachemnt object
188  */
189  pool_get (abf_itf_attach_pool, aia);
190 
192  aia->aia_prio = priority;
193  aia->aia_proto = fproto;
194  aia->aia_acl = ap->ap_acl;
195  aia->aia_abf = api;
196  aia->aia_sw_if_index = sw_if_index;
197  aiai = aia - abf_itf_attach_pool;
198  abf_itf_attach_db_add (policy_id, sw_if_index, aia);
199 
200  /*
201  * stack the DPO on the forwarding contributed by the path-list
202  */
203  abf_itf_attach_stack (aia);
204 
205  /*
206  * Insert the policy on the interfaces list.
207  */
208  vec_validate_init_empty (abf_per_itf[fproto], sw_if_index, NULL);
209  vec_add1 (abf_per_itf[fproto][sw_if_index], aia - abf_itf_attach_pool);
210  if (1 == vec_len (abf_per_itf[fproto][sw_if_index]))
211  {
212  /*
213  * when enabling the first ABF polciy on the interface
214  * we need to enable the interface input feature
215  */
217  "ip4-unicast" :
218  "ip6-unicast"),
219  (FIB_PROTOCOL_IP4 == fproto ?
220  "abf-input-ip4" :
221  "abf-input-ip6"),
222  sw_if_index, 1, NULL, 0);
223 
224  /* if this is the first ABF policy, we need to acquire an ACL lookup context */
225  vec_validate_init_empty (abf_alctx_per_itf[fproto], sw_if_index, ~0);
226  abf_alctx_per_itf[fproto][sw_if_index] =
227  acl_plugin.get_lookup_context_index (abf_acl_user_id, sw_if_index, 0);
228  }
229  else
230  {
231  vec_sort_with_function (abf_per_itf[fproto][sw_if_index],
233  }
234 
235  /* Prepare and set the list of ACLs for lookup within the context */
236  abf_setup_acl_lc (fproto, sw_if_index);
237 
238  /*
239  * become a child of the ABF poilcy so we are notified when
240  * its forwarding changes.
241  */
243  api,
245 
246  return (0);
247 }
248 
249 int
250 abf_itf_detach (fib_protocol_t fproto, u32 policy_id, u32 sw_if_index)
251 {
252  abf_itf_attach_t *aia;
253  u32 index;
254 
255  /*
256  * check this is a valid attahment
257  */
258  aia = abf_itf_attach_db_find (policy_id, sw_if_index);
259 
260  if (NULL == aia)
261  return (VNET_API_ERROR_ENTRY_ALREADY_EXISTS);
262 
263  /*
264  * first remove from the interface's vecotr
265  */
266  ASSERT (abf_per_itf[fproto]);
267  ASSERT (abf_per_itf[fproto][sw_if_index]);
268 
269  index = vec_search (abf_per_itf[fproto][sw_if_index],
270  aia - abf_itf_attach_pool);
271 
272  ASSERT (index != ~0);
273  vec_del1 (abf_per_itf[fproto][sw_if_index], index);
274 
275  if (0 == vec_len (abf_per_itf[fproto][sw_if_index]))
276  {
277  /*
278  * when deleting the last ABF polciy on the interface
279  * we need to disable the interface input feature
280  */
282  "ip4-unicast" :
283  "ip6-unicast"),
284  (FIB_PROTOCOL_IP4 == fproto ?
285  "abf-input-ip4" :
286  "abf-input-ip6"),
287  sw_if_index, 0, NULL, 0);
288 
289  /* Return the lookup context, invalidate its id in our records */
290  acl_plugin.put_lookup_context_index (abf_alctx_per_itf[fproto]
291  [sw_if_index]);
292  abf_alctx_per_itf[fproto][sw_if_index] = ~0;
293  }
294  else
295  {
296  vec_sort_with_function (abf_per_itf[fproto][sw_if_index],
298  }
299 
300  /* Prepare and set the list of ACLs for lookup within the context */
301  abf_setup_acl_lc (fproto, sw_if_index);
302 
303  /*
304  * remove the dependency on the policy
305  */
307  aia->aia_abf, aia->aia_sibling);
308 
309  /*
310  * remove the attahcment from the DB
311  */
312  abf_itf_attach_db_del (policy_id, sw_if_index);
313 
314  /*
315  * release our locks on FIB forwarding data
316  */
317  dpo_reset (&aia->aia_dpo);
318 
319  /*
320  * return the object
321  */
322  pool_put (abf_itf_attach_pool, aia);
323 
324  return (0);
325 }
326 
327 static u8 *
328 format_abf_intf_attach (u8 * s, va_list * args)
329 {
330  abf_itf_attach_t *aia = va_arg (*args, abf_itf_attach_t *);
331  abf_policy_t *ap;
332 
333  ap = abf_policy_get (aia->aia_abf);
334  s = format (s, "abf-interface-attach: policy:%d prioity:%d",
335  ap->ap_id, aia->aia_prio);
336  s = format (s, "\n %U", format_dpo_id, &aia->aia_dpo, 2);
337 
338  return (s);
339 }
340 
341 static clib_error_t *
343  unformat_input_t * input, vlib_cli_command_t * cmd)
344 {
345  u32 policy_id, sw_if_index;
346  fib_protocol_t fproto;
347  u32 is_del, priority;
348  vnet_main_t *vnm;
349 
350  is_del = 0;
351  sw_if_index = policy_id = ~0;
352  vnm = vnet_get_main ();
353  fproto = FIB_PROTOCOL_MAX;
354  priority = 0;
355 
357  {
358  if (unformat (input, "del"))
359  is_del = 1;
360  else if (unformat (input, "add"))
361  is_del = 0;
362  else if (unformat (input, "ip4"))
363  fproto = FIB_PROTOCOL_IP4;
364  else if (unformat (input, "ip6"))
365  fproto = FIB_PROTOCOL_IP6;
366  else if (unformat (input, "policy %d", &policy_id))
367  ;
368  else if (unformat (input, "priority %d", &priority))
369  ;
370  else if (unformat (input, "%U",
371  unformat_vnet_sw_interface, vnm, &sw_if_index))
372  ;
373  else
374  return (clib_error_return (0, "unknown input '%U'",
375  format_unformat_error, input));
376  }
377 
378  if (~0 == policy_id)
379  {
380  return (clib_error_return (0, "invalid policy ID:%d", policy_id));
381  }
382  if (~0 == sw_if_index)
383  {
384  return (clib_error_return (0, "invalid interface name"));
385  }
386  if (FIB_PROTOCOL_MAX == fproto)
387  {
388  return (clib_error_return (0, "Specify either ip4 or ip6"));
389  }
390 
391  if (~0 == abf_policy_find (policy_id))
392  return (clib_error_return (0, "invalid policy ID:%d", policy_id));
393 
394  if (is_del)
395  abf_itf_detach (fproto, policy_id, sw_if_index);
396  else
397  abf_itf_attach (fproto, policy_id, priority, sw_if_index);
398 
399  return (NULL);
400 }
401 
402 /* *INDENT-OFF* */
403 /**
404  * Attach an ABF policy to an interface.
405  */
406 VLIB_CLI_COMMAND (abf_itf_attach_cmd_node, static) = {
407  .path = "abf attach",
408  .function = abf_itf_attach_cmd,
409  .short_help = "abf attach <ip4|ip6> [del] policy <value> <interface>",
410  // this is not MP safe
411 };
412 /* *INDENT-ON* */
413 
414 static clib_error_t *
416  unformat_input_t * input, vlib_cli_command_t * cmd)
417 {
418  const abf_itf_attach_t *aia;
419  u32 sw_if_index, *aiai;
420  fib_protocol_t fproto;
421  vnet_main_t *vnm;
422 
423  sw_if_index = ~0;
424  vnm = vnet_get_main ();
425 
427  {
428  if (unformat (input, "%U",
429  unformat_vnet_sw_interface, vnm, &sw_if_index))
430  ;
431  else
432  return (clib_error_return (0, "unknown input '%U'",
433  format_unformat_error, input));
434  }
435 
436  if (~0 == sw_if_index)
437  {
438  vlib_cli_output (vm, "specify an interface");
439  }
440 
441  /* *INDENT-OFF* */
443  {
444  if (sw_if_index < vec_len(abf_per_itf[fproto]))
445  {
446  if (vec_len(abf_per_itf[fproto][sw_if_index]))
447  vlib_cli_output(vm, "%U:", format_fib_protocol, fproto);
448 
449  vec_foreach(aiai, abf_per_itf[fproto][sw_if_index])
450  {
451  aia = pool_elt_at_index(abf_itf_attach_pool, *aiai);
452  vlib_cli_output(vm, " %U", format_abf_intf_attach, aia);
453  }
454  }
455  }
456  /* *INDENT-ON* */
457  return (NULL);
458 }
459 
460 /* *INDENT-OFF* */
461 VLIB_CLI_COMMAND (abf_show_attach_cmd_node, static) = {
462  .path = "show abf attach",
463  .function = abf_show_attach_cmd,
464  .short_help = "show abf attach <interface>",
465  .is_mp_safe = 1,
466 };
467 /* *INDENT-ON* */
468 
469 void
471 {
472  u32 aii;
473 
474  /* *INDENT-OFF* */
475  pool_foreach_index(aii, abf_itf_attach_pool,
476  ({
477  if (!cb(aii, ctx))
478  break;
479  }));
480  /* *INDENT-ON* */
481 }
482 
483 typedef enum abf_next_t_
484 {
487 } abf_next_t;
488 
489 typedef struct abf_input_trace_t_
490 {
494 
495 typedef enum
496 {
497 #define abf_error(n,s) ABF_ERROR_##n,
498 #include "abf_error.def"
499 #undef abf_error
500  ABF_N_ERROR,
501 } abf_error_t;
502 
505  vlib_node_runtime_t * node,
506  vlib_frame_t * frame, fib_protocol_t fproto)
507 {
508  u32 n_left_from, *from, *to_next, next_index, matches;
509 
510  from = vlib_frame_vector_args (frame);
511  n_left_from = frame->n_vectors;
512  next_index = node->cached_next_index;
513  matches = 0;
514 
515  while (n_left_from > 0)
516  {
517  u32 n_left_to_next;
518 
519  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
520 
521  while (n_left_from > 0 && n_left_to_next > 0)
522  {
523  const u32 *attachments0;
524  const abf_itf_attach_t *aia0;
525  abf_next_t next0 = ABF_NEXT_DROP;
526  vlib_buffer_t *b0;
527  u32 bi0, sw_if_index0;
528  fa_5tuple_opaque_t fa_5tuple0;
529  u32 match_acl_index = ~0;
530  u32 match_acl_pos = ~0;
531  u32 match_rule_index = ~0;
532  u32 trace_bitmap = 0;
533  u8 action;
534 
535  bi0 = from[0];
536  to_next[0] = bi0;
537  from += 1;
538  to_next += 1;
539  n_left_from -= 1;
540  n_left_to_next -= 1;
541 
542  b0 = vlib_get_buffer (vm, bi0);
543  sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
544 
545  ASSERT (vec_len (abf_per_itf[fproto]) > sw_if_index0);
546  attachments0 = abf_per_itf[fproto][sw_if_index0];
547 
548  ASSERT (vec_len (abf_alctx_per_itf[fproto]) > sw_if_index0);
549  /*
550  * check if any of the policies attached to this interface matches.
551  */
552  u32 lc_index = abf_alctx_per_itf[fproto][sw_if_index0];
553 
554  /*
555  A non-inline version looks like this:
556 
557  acl_plugin.fill_5tuple (lc_index, b0, (FIB_PROTOCOL_IP6 == fproto),
558  1, 0, &fa_5tuple0);
559  if (acl_plugin.match_5tuple
560  (lc_index, &fa_5tuple0, (FIB_PROTOCOL_IP6 == fproto), &action,
561  &match_acl_pos, &match_acl_index, &match_rule_index,
562  &trace_bitmap))
563  . . .
564  */
565  acl_plugin_fill_5tuple_inline (acl_plugin.p_acl_main, lc_index, b0,
566  (FIB_PROTOCOL_IP6 == fproto), 1, 0,
567  &fa_5tuple0);
568 
570  (acl_plugin.p_acl_main, lc_index, &fa_5tuple0,
571  (FIB_PROTOCOL_IP6 == fproto), &action, &match_acl_pos,
572  &match_acl_index, &match_rule_index, &trace_bitmap))
573  {
574  /*
575  * match:
576  * follow the DPO chain
577  */
578  aia0 = abf_itf_attach_get (attachments0[match_acl_pos]);
579 
580  next0 = aia0->aia_dpo.dpoi_next_node;
581  vnet_buffer (b0)->ip.adj_index[VLIB_TX] =
582  aia0->aia_dpo.dpoi_index;
583  matches++;
584  }
585  else
586  {
587  /*
588  * miss:
589  * move on down the feature arc
590  */
591  vnet_feature_next (sw_if_index0, &next0, b0);
592  }
593 
594  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
595  {
596  abf_input_trace_t *tr;
597 
598  tr = vlib_add_trace (vm, node, b0, sizeof (*tr));
599  tr->next = next0;
600  tr->index = vnet_buffer (b0)->ip.adj_index[VLIB_TX];
601  }
602 
603  /* verify speculative enqueue, maybe switch current next frame */
604  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
605  to_next, n_left_to_next, bi0,
606  next0);
607  }
608 
609  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
610  }
611 
613  (fproto = FIB_PROTOCOL_IP6 ?
614  abf_ip4_node.index :
615  abf_ip6_node.index),
616  ABF_ERROR_MATCHED, matches);
617 
618  return frame->n_vectors;
619 }
620 
621 static uword
623  vlib_node_runtime_t * node, vlib_frame_t * frame)
624 {
625  return abf_input_inline (vm, node, frame, FIB_PROTOCOL_IP4);
626 }
627 
628 static uword
630  vlib_node_runtime_t * node, vlib_frame_t * frame)
631 {
632  return abf_input_inline (vm, node, frame, FIB_PROTOCOL_IP6);
633 }
634 
635 static u8 *
636 format_abf_input_trace (u8 * s, va_list * args)
637 {
638  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
639  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
640  abf_input_trace_t *t = va_arg (*args, abf_input_trace_t *);
641 
642  s = format (s, " next %d index %d", t->next, t->index);
643  return s;
644 }
645 
646 static char *abf_error_strings[] = {
647 #define abf_error(n,s) s,
648 #include "abf_error.def"
649 #undef abf_error
650 };
651 
652 /* *INDENT-OFF* */
654 {
655  .function = abf_input_ip4,
656  .name = "abf-input-ip4",
657  .vector_size = sizeof (u32),
658  .format_trace = format_abf_input_trace,
659  .type = VLIB_NODE_TYPE_INTERNAL,
660  .n_errors = ABF_N_ERROR,
661  .error_strings = abf_error_strings,
662  .n_next_nodes = ABF_N_NEXT,
663  .next_nodes =
664  {
665  [ABF_NEXT_DROP] = "error-drop",
666  }
667 };
668 
670 {
671  .function = abf_input_ip6,
672  .name = "abf-input-ip6",
673  .vector_size = sizeof (u32),
674  .format_trace = format_abf_input_trace,
675  .type = VLIB_NODE_TYPE_INTERNAL,
676  .n_errors = 0,
677  .n_next_nodes = ABF_N_NEXT,
678 
679  .next_nodes =
680  {
681  [ABF_NEXT_DROP] = "error-drop",
682  }
683 };
684 
685 VNET_FEATURE_INIT (abf_ip4_feat, static) =
686 {
687  .arc_name = "ip4-unicast",
688  .node_name = "abf-input-ip4",
689  .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa"),
690 };
691 
692 VNET_FEATURE_INIT (abf_ip6_feat, static) =
693 {
694  .arc_name = "ip6-unicast",
695  .node_name = "abf-input-ip6",
696  .runs_after = VNET_FEATURES ("acl-plugin-in-ip6-fa"),
697 };
698 /* *INDENT-ON* */
699 
700 static fib_node_t *
702 {
703  abf_itf_attach_t *aia = abf_itf_attach_get (index);
704  return (&(aia->aia_node));
705 }
706 
707 static abf_itf_attach_t *
709 {
710  return ((abf_itf_attach_t *) (((char *) node) -
712  aia_node)));
713 }
714 
715 static void
717 {
718  /*
719  * ABF interface attachments are leaves on the graph.
720  * we do not manage locks from children.
721  */
722 }
723 
724 /*
725  * abf_itf_attach_back_walk_notify
726  *
727  * A back walk has reached this BIER fmask
728  */
732 {
733  /*
734  * re-stack the fmask on the n-eos of the via
735  */
737 
738  abf_itf_attach_stack (aia);
739 
741 }
742 
743 /*
744  * The BIER fmask's graph node virtual function table
745  */
746 static const fib_node_vft_t abf_itf_attach_vft = {
748  .fnv_last_lock = abf_itf_attach_last_lock_gone,
749  .fnv_back_walk = abf_itf_attach_back_walk_notify,
750 };
751 
752 static clib_error_t *
754 {
756  fib_node_register_new_type (&abf_itf_attach_vft);
757  clib_error_t *acl_init_res = acl_plugin_exports_init (&acl_plugin);
758  if (acl_init_res)
759  return (acl_init_res);
760 
762  acl_plugin.register_user_module ("abp plugin", "sw_if_index", NULL);
763 
764  return (NULL);
765 }
766 
768 
769 /*
770  * fd.io coding-style-patch-verification: ON
771  *
772  * Local Variables:
773  * eval: (c-set-style "gnu")
774  * End:
775  */
void dpo_stack_from_node(u32 child_node_index, dpo_id_t *dpo, const dpo_id_t *parent)
Stack one DPO object on another, and thus establish a child parent relationship.
Definition: dpo.c:530
fib_protocol_t aia_proto
The protocol for the attachment.
Contribute an object that is to be used to forward IP6 packets.
Definition: fib_types.h:103
#define hash_set(h, key, value)
Definition: hash.h:255
vlib_node_registration_t abf_ip6_node
(constructor) VLIB_REGISTER_NODE (abf_ip6_node)
#define CLIB_UNUSED(x)
Definition: clib.h:79
#define hash_unset(h, key)
Definition: hash.h:261
vnet_main_t * vnet_get_main(void)
Definition: misc.c:47
u32 ap_id
The policy ID - as configured by the client.
Definition: abf_policy.h:58
void fib_node_init(fib_node_t *node, fib_node_type_t type)
Definition: fib_node.c:185
abf_policy_t * abf_policy_get(u32 index)
Get an ABF object from its VPP index.
Definition: abf_policy.c:41
unsigned long u64
Definition: types.h:89
static u32 abf_acl_user_id
ABF ACL module user id returned during the initialization.
#define NULL
Definition: clib.h:55
enum fib_node_back_walk_rc_t_ fib_node_back_walk_rc_t
Return code from a back walk function.
import vnet fib fib_types api
Definition: bier.api:22
int abf_itf_detach(fib_protocol_t fproto, u32 policy_id, u32 sw_if_index)
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
static clib_error_t * abf_itf_bond_init(vlib_main_t *vm)
Contribute an object that is to be used to forward IP4 packets.
Definition: fib_types.h:99
#define STRUCT_OFFSET_OF(t, f)
Definition: clib.h:62
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
unformat_function_t unformat_vnet_sw_interface
fib_node_type_t abf_policy_fib_node_type
FIB node type the attachment is registered.
Definition: abf_policy.c:26
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:227
static u32 * abf_alctx_per_itf[FIB_PROTOCOL_MAX]
Per interface values of ACL lookup context IDs.
unsigned char u8
Definition: types.h:56
static uword * abf_itf_attach_db
A DB of attachments; key={abf_index,sw_if_index}.
fib_node_type_t fib_node_register_new_type(const fib_node_vft_t *vft)
Create a new FIB node type and Register the function table for it.
Definition: fib_node.c:80
static acl_plugin_methods_t acl_plugin
u8 * format_fib_protocol(u8 *s, va_list *ap)
Definition: fib_types.c:31
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
u32 aia_acl
The ACL and DPO are cached for fast DP access.
u32 fib_node_child_add(fib_node_type_t parent_type, fib_node_index_t parent_index, fib_node_type_t type, fib_node_index_t index)
Definition: fib_node.c:98
void abf_setup_acl_lc(fib_protocol_t fproto, u32 sw_if_index)
static abf_itf_attach_t * abf_itf_attach_db_find(u32 abf_index, u32 sw_if_index)
u32 aia_abf
The VPP index of the ABF policy.
static char * abf_error_strings[]
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:156
#define always_inline
Definition: clib.h:92
static abf_itf_attach_t * abf_itf_attach_get(u32 index)
static fib_node_back_walk_rc_t abf_itf_attach_back_walk_notify(fib_node_t *node, fib_node_back_walk_ctx_t *ctx)
#define clib_error_return(e, args...)
Definition: error.h:99
unsigned int u32
Definition: types.h:88
#define vec_search(v, E)
Search a vector for the index of the entry that matches.
Definition: vec.h:942
static void abf_itf_attach_stack(abf_itf_attach_t *aia)
static void acl_plugin_fill_5tuple_inline(void *p_acl_main, u32 lc_index, vlib_buffer_t *b0, int is_ip6, int is_input, int is_l2_path, fa_5tuple_opaque_t *p5tuple_pkt)
u32 abf_policy_find(u32 policy_id)
Find a ABF object from the client&#39;s policy ID.
Definition: abf_policy.c:66
static clib_error_t * abf_itf_attach_cmd(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
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
#define hash_get(h, key)
Definition: hash.h:249
u32 aia_sibling
Sibling index on the policy&#39;s path list.
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:461
static u8 * format_abf_intf_attach(u8 *s, va_list *args)
struct _unformat_input_t unformat_input_t
u32 aia_sw_if_index
The interface for the attachment.
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:273
#define PREDICT_FALSE(x)
Definition: clib.h:105
#define vec_del1(v, i)
Delete the element at index I.
Definition: vec.h:806
struct abf_input_trace_t_ abf_input_trace_t
static_always_inline void vnet_feature_next(u32 sw_if_index, u32 *next0, vlib_buffer_t *b0)
Definition: feature.h:237
#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
An node in the FIB graph.
Definition: fib_node.h:286
#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
int(* abf_itf_attach_walk_cb_t)(index_t aii, void *ctx0)
static u64 abf_itf_attach_mk_key(u32 abf_index, u32 sw_if_index)
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
Definition: node_funcs.h:1168
fib_node_index_t ap_pl
The path-list describing how to forward in case of a match.
Definition: abf_policy.h:48
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:153
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
static u8 * format_abf_input_trace(u8 *s, va_list *args)
u16 n_vectors
Definition: node.h:380
Attachment data for an ABF policy to an interface.
vlib_main_t * vm
Definition: buffer.c:294
abf_error_t
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:339
fib_node_get_t fnv_get
Definition: fib_node.h:274
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:30
static clib_error_t * acl_plugin_exports_init(acl_plugin_methods_t *m)
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:454
static u32 ** abf_per_itf[FIB_PROTOCOL_MAX]
A per interface vector of attached policies.
static int abf_cmp_attach_for_sort(void *v1, void *v2)
Context passed between object during a back walk.
Definition: fib_node.h:199
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
Definition: node.h:492
static fib_node_t * abf_itf_attach_get_node(fib_node_index_t index)
u32 aia_prio
The priority of this policy for attachment.
#define ASSERT(truth)
An ACL based Forwading &#39;policy&#39;.
Definition: abf_policy.h:33
static uword abf_input_ip6(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
long ctx[MAX_CONNS]
Definition: main.c:126
static fib_node_type_t abf_itf_attach_fib_node_type
FIB node registered type for the bonds.
static int acl_plugin_match_5tuple_inline(void *p_acl_main, u32 lc_index, fa_5tuple_opaque_t *pkt_5tuple, int is_ip6, u8 *r_action, u32 *r_acl_pos_p, u32 *r_acl_match_p, u32 *r_rule_match_p, u32 *trace_bitmap)
void abf_itf_attach_walk(abf_itf_attach_walk_cb_t cb, void *ctx)
void fib_node_child_remove(fib_node_type_t parent_type, fib_node_index_t parent_index, fib_node_index_t sibling_index)
Definition: fib_node.c:123
int abf_itf_attach(fib_protocol_t fproto, u32 policy_id, u32 priority, u32 sw_if_index)
static abf_itf_attach_t * abf_itf_attach_get_from_node(fib_node_t *node)
static uword abf_input_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, fib_protocol_t fproto)
u8 * format_dpo_id(u8 *s, va_list *args)
Format a DPO_id_t oject
Definition: dpo.c:147
#define VNET_FEATURES(...)
Definition: feature.h:391
enum abf_next_t_ abf_next_t
u32 ap_acl
ACL index to match.
Definition: abf_policy.h:43
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
dpo_id_t aia_dpo
The DPO actually used for forwarding.
struct _vlib_node_registration vlib_node_registration_t
static void abf_itf_attach_db_add(u32 abf_index, u32 sw_if_index, abf_itf_attach_t *aia)
Definition: defs.h:47
index_t dpoi_index
the index of objects of that type
Definition: dpo.h:184
static void abf_itf_attach_db_del(u32 abf_index, u32 sw_if_index)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
#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
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
Definition: vec.h:961
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
#define FOR_EACH_FIB_IP_PROTOCOL(_item)
Definition: fib_types.h:70
void fib_path_list_contribute_forwarding(fib_node_index_t path_list_index, fib_forward_chain_type_t fct, fib_path_list_fwd_flags_t flags, dpo_id_t *dpo)
abf_next_t_
#define FIB_PROTOCOL_MAX
Definition outside of enum so it does not need to be included in non-defaulted switch statements...
Definition: fib_types.h:52
A FIB graph nodes virtual function table.
Definition: fib_node.h:273
VNET_FEATURE_INIT(abf_ip4_feat, static)
#define vnet_buffer(b)
Definition: buffer.h:360
enum fib_node_type_t_ fib_node_type_t
The types of nodes in a FIB graph.
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
vlib_node_registration_t abf_ip4_node
Forward declarations;.
void dpo_reset(dpo_id_t *dpo)
reset a DPO ID The DPO will be unlocked.
Definition: dpo.c:231
#define vec_foreach(var, vec)
Vector iterator.
static clib_error_t * abf_show_attach_cmd(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
static uword abf_input_ip4(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
static void abf_itf_attach_last_lock_gone(fib_node_t *node)
u16 dpoi_next_node
The next VLIB node to follow.
Definition: dpo.h:180
abf_itf_attach_t * abf_itf_attach_pool
Pool of ABF interface attachment objects.
#define pool_foreach_index(i, v, body)
Iterate pool by index.
Definition: pool.h:485
#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:111
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:681
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:57
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
Definition: defs.h:46
fib_node_t aia_node
Linkage into the FIB graph.
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:169