FD.io VPP  v18.10-32-g1161dda
Vector Packet Processing
adj_midchain.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 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 <vnet/adj/adj_nbr.h>
17 #include <vnet/adj/adj_internal.h>
18 #include <vnet/adj/adj_l2.h>
19 #include <vnet/adj/adj_nsh.h>
20 #include <vnet/adj/adj_midchain.h>
22 #include <vnet/dpo/drop_dpo.h>
23 #include <vnet/fib/fib_walk.h>
24 
25 /**
26  * The two midchain tx feature node indices
27  */
30 
31 /**
32  * @brief Trace data for packets traversing the midchain tx node
33  */
35 {
36  /**
37  * @brief the midchain adj we are traversing
38  */
41 
44  vlib_node_runtime_t * node,
45  vlib_frame_t * frame,
46  int interface_count)
47 {
48  u32 * from, * to_next, n_left_from, n_left_to_next;
49  u32 next_index;
50  vnet_main_t *vnm = vnet_get_main ();
52  u32 thread_index = vm->thread_index;
53 
54  /* Vector of buffer / pkt indices we're supposed to process */
55  from = vlib_frame_vector_args (frame);
56 
57  /* Number of buffers / pkts */
58  n_left_from = frame->n_vectors;
59 
60  /* Speculatively send the first buffer to the last disposition we used */
61  next_index = node->cached_next_index;
62 
63  while (n_left_from > 0)
64  {
65  /* set up to enqueue to our disposition with index = next_index */
66  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
67 
68  while (n_left_from >= 8 && n_left_to_next > 4)
69  {
70  u32 bi0, adj_index0, next0;
71  const ip_adjacency_t * adj0;
72  const dpo_id_t *dpo0;
73  vlib_buffer_t * b0;
74  u32 bi1, adj_index1, next1;
75  const ip_adjacency_t * adj1;
76  const dpo_id_t *dpo1;
77  vlib_buffer_t * b1;
78  u32 bi2, adj_index2, next2;
79  const ip_adjacency_t * adj2;
80  const dpo_id_t *dpo2;
81  vlib_buffer_t * b2;
82  u32 bi3, adj_index3, next3;
83  const ip_adjacency_t * adj3;
84  const dpo_id_t *dpo3;
85  vlib_buffer_t * b3;
86 
87  /* Prefetch next iteration. */
88  {
89  vlib_buffer_t * p4, * p5;
90  vlib_buffer_t * p6, * p7;
91 
92  p4 = vlib_get_buffer (vm, from[4]);
93  p5 = vlib_get_buffer (vm, from[5]);
94  p6 = vlib_get_buffer (vm, from[6]);
95  p7 = vlib_get_buffer (vm, from[7]);
96 
97  vlib_prefetch_buffer_header (p4, LOAD);
98  vlib_prefetch_buffer_header (p5, LOAD);
99  vlib_prefetch_buffer_header (p6, LOAD);
100  vlib_prefetch_buffer_header (p7, LOAD);
101  }
102 
103  bi0 = from[0];
104  to_next[0] = bi0;
105  bi1 = from[1];
106  to_next[1] = bi1;
107  bi2 = from[2];
108  to_next[2] = bi2;
109  bi3 = from[3];
110  to_next[3] = bi3;
111 
112  from += 4;
113  to_next += 4;
114  n_left_from -= 4;
115  n_left_to_next -= 4;
116 
117  b0 = vlib_get_buffer(vm, bi0);
118  b1 = vlib_get_buffer(vm, bi1);
119  b2 = vlib_get_buffer(vm, bi2);
120  b3 = vlib_get_buffer(vm, bi3);
121 
122  /* Follow the DPO on which the midchain is stacked */
123  adj_index0 = vnet_buffer(b0)->ip.adj_index[VLIB_TX];
124  adj_index1 = vnet_buffer(b1)->ip.adj_index[VLIB_TX];
125  adj_index2 = vnet_buffer(b2)->ip.adj_index[VLIB_TX];
126  adj_index3 = vnet_buffer(b3)->ip.adj_index[VLIB_TX];
127 
128  adj0 = adj_get(adj_index0);
129  adj1 = adj_get(adj_index1);
130  adj2 = adj_get(adj_index2);
131  adj3 = adj_get(adj_index3);
132 
133  dpo0 = &adj0->sub_type.midchain.next_dpo;
134  dpo1 = &adj1->sub_type.midchain.next_dpo;
135  dpo2 = &adj2->sub_type.midchain.next_dpo;
136  dpo3 = &adj3->sub_type.midchain.next_dpo;
137 
138  next0 = dpo0->dpoi_next_node;
139  next1 = dpo1->dpoi_next_node;
140  next2 = dpo2->dpoi_next_node;
141  next3 = dpo3->dpoi_next_node;
142 
143  vnet_buffer(b1)->ip.adj_index[VLIB_TX] = dpo1->dpoi_index;
144  vnet_buffer(b0)->ip.adj_index[VLIB_TX] = dpo0->dpoi_index;
145  vnet_buffer(b2)->ip.adj_index[VLIB_TX] = dpo2->dpoi_index;
146  vnet_buffer(b3)->ip.adj_index[VLIB_TX] = dpo3->dpoi_index;
147 
148  if (interface_count)
149  {
152  thread_index,
153  adj0->rewrite_header.sw_if_index,
154  1,
155  vlib_buffer_length_in_chain (vm, b0));
158  thread_index,
159  adj1->rewrite_header.sw_if_index,
160  1,
161  vlib_buffer_length_in_chain (vm, b1));
164  thread_index,
165  adj2->rewrite_header.sw_if_index,
166  1,
167  vlib_buffer_length_in_chain (vm, b2));
170  thread_index,
171  adj3->rewrite_header.sw_if_index,
172  1,
173  vlib_buffer_length_in_chain (vm, b3));
174  }
175 
176  if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED))
177  {
178  adj_midchain_tx_trace_t *tr = vlib_add_trace (vm, node,
179  b0, sizeof (*tr));
180  tr->ai = adj_index0;
181  }
182  if (PREDICT_FALSE(b1->flags & VLIB_BUFFER_IS_TRACED))
183  {
184  adj_midchain_tx_trace_t *tr = vlib_add_trace (vm, node,
185  b1, sizeof (*tr));
186  tr->ai = adj_index1;
187  }
188  if (PREDICT_FALSE(b2->flags & VLIB_BUFFER_IS_TRACED))
189  {
190  adj_midchain_tx_trace_t *tr = vlib_add_trace (vm, node,
191  b2, sizeof (*tr));
192  tr->ai = adj_index2;
193  }
194  if (PREDICT_FALSE(b3->flags & VLIB_BUFFER_IS_TRACED))
195  {
196  adj_midchain_tx_trace_t *tr = vlib_add_trace (vm, node,
197  b3, sizeof (*tr));
198  tr->ai = adj_index3;
199  }
200 
201  vlib_validate_buffer_enqueue_x4 (vm, node, next_index,
202  to_next, n_left_to_next,
203  bi0, bi1, bi2, bi3,
204  next0, next1, next2, next3);
205  }
206  while (n_left_from > 0 && n_left_to_next > 0)
207  {
208  u32 bi0, adj_index0, next0;
209  const ip_adjacency_t * adj0;
210  const dpo_id_t *dpo0;
211  vlib_buffer_t * b0;
212 
213  bi0 = from[0];
214  to_next[0] = bi0;
215  from += 1;
216  to_next += 1;
217  n_left_from -= 1;
218  n_left_to_next -= 1;
219 
220  b0 = vlib_get_buffer(vm, bi0);
221 
222  /* Follow the DPO on which the midchain is stacked */
223  adj_index0 = vnet_buffer(b0)->ip.adj_index[VLIB_TX];
224  adj0 = adj_get(adj_index0);
225  dpo0 = &adj0->sub_type.midchain.next_dpo;
226  next0 = dpo0->dpoi_next_node;
227  vnet_buffer(b0)->ip.adj_index[VLIB_TX] = dpo0->dpoi_index;
228 
229  if (interface_count)
230  {
233  thread_index,
234  adj0->rewrite_header.sw_if_index,
235  1,
236  vlib_buffer_length_in_chain (vm, b0));
237  }
238 
239  if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED))
240  {
241  adj_midchain_tx_trace_t *tr = vlib_add_trace (vm, node,
242  b0, sizeof (*tr));
243  tr->ai = adj_index0;
244  }
245 
246  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
247  to_next, n_left_to_next,
248  bi0, next0);
249  }
250 
251  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
252  }
253 
254  return frame->n_vectors;
255 }
256 
257 static u8 *
258 format_adj_midchain_tx_trace (u8 * s, va_list * args)
259 {
260  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
261  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
262  adj_midchain_tx_trace_t *tr = va_arg (*args, adj_midchain_tx_trace_t*);
263 
264  s = format(s, "adj-midchain:[%d]:%U", tr->ai,
265  format_ip_adjacency, tr->ai,
267 
268  return (s);
269 }
270 
271 static uword
273  vlib_node_runtime_t * node,
274  vlib_frame_t * frame)
275 {
276  return (adj_midchain_tx_inline(vm, node, frame, 1));
277 }
278 
280  .function = adj_midchain_tx,
281  .name = "adj-midchain-tx",
282  .vector_size = sizeof (u32),
283 
284  .format_trace = format_adj_midchain_tx_trace,
285 
286  .n_next_nodes = 1,
287  .next_nodes = {
288  [0] = "error-drop",
289  },
290 };
291 
292 static uword
294  vlib_node_runtime_t * node,
295  vlib_frame_t * frame)
296 {
297  return (adj_midchain_tx_inline(vm, node, frame, 0));
298 }
299 
301  .function = adj_midchain_tx_no_count,
302  .name = "adj-midchain-tx-no-count",
303  .vector_size = sizeof (u32),
304 
305  .format_trace = format_adj_midchain_tx_trace,
306 
307  .n_next_nodes = 1,
308  .next_nodes = {
309  [0] = "error-drop",
310  },
311 };
312 
313 VNET_FEATURE_INIT (adj_midchain_tx_ip4, static) = {
314  .arc_name = "ip4-output",
315  .node_name = "adj-midchain-tx",
316  .runs_before = VNET_FEATURES ("interface-output"),
317  .feature_index_ptr = &adj_midchain_tx_feature_node[VNET_LINK_IP4],
318 };
319 VNET_FEATURE_INIT (adj_midchain_tx_no_count_ip4, static) = {
320  .arc_name = "ip4-output",
321  .node_name = "adj-midchain-tx-no-count",
322  .runs_before = VNET_FEATURES ("interface-output"),
324 };
325 VNET_FEATURE_INIT (adj_midchain_tx_ip6, static) = {
326  .arc_name = "ip6-output",
327  .node_name = "adj-midchain-tx",
328  .runs_before = VNET_FEATURES ("interface-output"),
329  .feature_index_ptr = &adj_midchain_tx_feature_node[VNET_LINK_IP6],
330 };
331 VNET_FEATURE_INIT (adj_midchain_tx_no_count_ip6, static) = {
332  .arc_name = "ip6-output",
333  .node_name = "adj-midchain-tx-no-count",
334  .runs_before = VNET_FEATURES ("interface-output"),
336 };
337 VNET_FEATURE_INIT (adj_midchain_tx_mpls, static) = {
338  .arc_name = "mpls-output",
339  .node_name = "adj-midchain-tx",
340  .runs_before = VNET_FEATURES ("interface-output"),
341  .feature_index_ptr = &adj_midchain_tx_feature_node[VNET_LINK_MPLS],
342 };
343 VNET_FEATURE_INIT (adj_midchain_tx_no_count_mpls, static) = {
344  .arc_name = "mpls-output",
345  .node_name = "adj-midchain-tx-no-count",
346  .runs_before = VNET_FEATURES ("interface-output"),
348 };
349 VNET_FEATURE_INIT (adj_midchain_tx_ethernet, static) = {
350  .arc_name = "ethernet-output",
351  .node_name = "adj-midchain-tx",
352  .runs_before = VNET_FEATURES ("error-drop"),
353  .feature_index_ptr = &adj_midchain_tx_feature_node[VNET_LINK_ETHERNET],
354 };
355 VNET_FEATURE_INIT (adj_midchain_tx_no_count_ethernet, static) = {
356  .arc_name = "ethernet-output",
357  .node_name = "adj-midchain-tx-no-count",
358  .runs_before = VNET_FEATURES ("error-drop"),
360 };
361 VNET_FEATURE_INIT (adj_midchain_tx_nsh, static) = {
362  .arc_name = "nsh-output",
363  .node_name = "adj-midchain-tx",
364  .runs_before = VNET_FEATURES ("error-drop"),
365  .feature_index_ptr = &adj_midchain_tx_feature_node[VNET_LINK_NSH],
366 };
367 VNET_FEATURE_INIT (adj_midchain_tx_no_count_nsh, static) = {
368  .arc_name = "nsh-output",
369  .node_name = "adj-midchain-tx-no-count",
370  .runs_before = VNET_FEATURES ("error-drop"),
372 };
373 
374 static inline u32
376 {
377  switch (link) {
378  case VNET_LINK_IP4:
379  return (ip4_midchain_node.index);
380  case VNET_LINK_IP6:
381  return (ip6_midchain_node.index);
382  case VNET_LINK_MPLS:
383  return (mpls_midchain_node.index);
384  case VNET_LINK_ETHERNET:
385  return (adj_l2_midchain_node.index);
386  case VNET_LINK_NSH:
387  return (adj_nsh_midchain_node.index);
388  case VNET_LINK_ARP:
389  break;
390  }
391  ASSERT(0);
392  return (0);
393 }
394 
395 static u8
397 {
398  u8 arc = (u8) ~0;
399  switch (adj->ia_link)
400  {
401  case VNET_LINK_IP4:
402  {
404  break;
405  }
406  case VNET_LINK_IP6:
407  {
409  break;
410  }
411  case VNET_LINK_MPLS:
412  {
414  break;
415  }
416  case VNET_LINK_ETHERNET:
417  {
419  break;
420  }
421  case VNET_LINK_NSH:
422  {
423  arc = nsh_main_dummy.output_feature_arc_index;
424  break;
425  }
426  case VNET_LINK_ARP:
427  ASSERT(0);
428  break;
429  }
430 
431  ASSERT (arc != (u8) ~0);
432 
433  return (arc);
434 }
435 
436 static u32
438 {
439  return ((adj->ia_flags & ADJ_FLAG_MIDCHAIN_NO_COUNT) ?
441  adj_midchain_tx_node.index);
442 }
443 
444 static u32
446 {
448  {
450  }
451 
452  return (adj_midchain_tx_feature_node[adj->ia_link]);
453 }
454 
455 /**
456  * adj_midchain_setup
457  *
458  * Setup the adj as a mid-chain
459  */
460 void
462  adj_midchain_fixup_t fixup,
463  const void *data,
465 {
466  u32 feature_index, tx_node;
467  ip_adjacency_t *adj;
468  u8 arc_index;
469 
470  ASSERT(ADJ_INDEX_INVALID != adj_index);
471 
472  adj = adj_get(adj_index);
473 
474  adj->sub_type.midchain.fixup_func = fixup;
475  adj->sub_type.midchain.fixup_data = data;
476  adj->ia_flags |= flags;
477 
479  feature_index = adj_nbr_midchain_get_feature_node(adj);
480  tx_node = adj_nbr_midchain_get_tx_node(adj);
481 
482  vnet_feature_enable_disable_with_index (arc_index, feature_index,
483  adj->rewrite_header.sw_if_index,
484  1 /* enable */, 0, 0);
485 
486  /*
487  * stack the midchain on the drop so it's ready to forward in the adj-midchain-tx.
488  * The graph arc used/created here is from the midchain-tx node to the
489  * child's registered node. This is because post adj processing the next
490  * node are any output features, then the midchain-tx. from there we
491  * need to get to the stacked child's node.
492  */
493  dpo_stack_from_node(tx_node,
494  &adj->sub_type.midchain.next_dpo,
496 }
497 
498 /**
499  * adj_nbr_midchain_update_rewrite
500  *
501  * Update the adjacency's rewrite string. A NULL string implies the
502  * rewrite is reset (i.e. when ARP/ND etnry is gone).
503  * NB: the adj being updated may be handling traffic in the DP.
504  */
505 void
507  adj_midchain_fixup_t fixup,
508  const void *fixup_data,
510  u8 *rewrite)
511 {
512  ip_adjacency_t *adj;
513 
514  ASSERT(ADJ_INDEX_INVALID != adj_index);
515 
516  adj = adj_get(adj_index);
517 
518  /*
519  * one time only update. since we don't support chainging the tunnel
520  * src,dst, this is all we need.
521  */
525 
526  /*
527  * tunnels can always provide a rewrite.
528  */
529  ASSERT(NULL != rewrite);
530 
531  adj_midchain_setup(adj_index, fixup, fixup_data, flags);
532 
533  /*
534  * update the rewirte with the workers paused.
535  */
540  rewrite);
541 }
542 
543 /**
544  * adj_nbr_midchain_unstack
545  *
546  * Unstack the adj. stack it on drop
547  */
548 void
550 {
551  ip_adjacency_t *adj;
552 
553  ASSERT(ADJ_INDEX_INVALID != adj_index);
554 
555  adj = adj_get(adj_index);
556 
557  /*
558  * stack on the drop
559  */
562  &adj->sub_type.midchain.next_dpo,
565 }
566 
567 /**
568  * adj_nbr_midchain_stack
569  */
570 void
572  const dpo_id_t *next)
573 {
574  ip_adjacency_t *adj;
575 
576  ASSERT(ADJ_INDEX_INVALID != adj_index);
577 
578  adj = adj_get(adj_index);
579 
582 
584  &adj->sub_type.midchain.next_dpo,
585  next);
586 }
587 
588 u8*
589 format_adj_midchain (u8* s, va_list *ap)
590 {
591  index_t index = va_arg(*ap, index_t);
592  u32 indent = va_arg(*ap, u32);
593  ip_adjacency_t * adj = adj_get(index);
594 
595  s = format (s, "%U", format_vnet_link, adj->ia_link);
596  s = format (s, " via %U",
597  format_ip46_address, &adj->sub_type.nbr.next_hop,
599  s = format (s, " %U",
601  &adj->rewrite_header, sizeof (adj->rewrite_data), indent);
602  s = format (s, "\n%Ustacked-on:\n%U%U",
603  format_white_space, indent,
604  format_white_space, indent+2,
605  format_dpo_id, &adj->sub_type.midchain.next_dpo, indent+2);
606 
607  return (s);
608 }
609 
610 static void
612 {
613  adj_lock(dpo->dpoi_index);
614 }
615 static void
617 {
618  adj_unlock(dpo->dpoi_index);
619 }
620 
621 const static dpo_vft_t adj_midchain_dpo_vft = {
623  .dv_unlock = adj_dpo_unlock,
624  .dv_format = format_adj_midchain,
625  .dv_get_urpf = adj_dpo_get_urpf,
626 };
627 
628 /**
629  * @brief The per-protocol VLIB graph nodes that are assigned to a midchain
630  * object.
631  *
632  * this means that these graph nodes are ones from which a midchain is the
633  * parent object in the DPO-graph.
634  */
635 const static char* const midchain_ip4_nodes[] =
636 {
637  "ip4-midchain",
638  NULL,
639 };
640 const static char* const midchain_ip6_nodes[] =
641 {
642  "ip6-midchain",
643  NULL,
644 };
645 const static char* const midchain_mpls_nodes[] =
646 {
647  "mpls-midchain",
648  NULL,
649 };
650 const static char* const midchain_ethernet_nodes[] =
651 {
652  "adj-l2-midchain",
653  NULL,
654 };
655 const static char* const midchain_nsh_nodes[] =
656 {
657  "adj-nsh-midchain",
658  NULL,
659 };
660 
661 const static char* const * const midchain_nodes[DPO_PROTO_NUM] =
662 {
668 };
669 
670 void
672 {
673  dpo_register(DPO_ADJACENCY_MIDCHAIN, &adj_midchain_dpo_vft, midchain_nodes);
674 }
static uword adj_midchain_tx(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: adj_midchain.c:272
static const char *const midchain_nsh_nodes[]
Definition: adj_midchain.c:655
static const char *const midchain_ip6_nodes[]
Definition: adj_midchain.c:640
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
dpo_lock_fn_t dv_lock
A reference counting lock function.
Definition: dpo.h:404
#define VNET_LINK_NUM
Number of link types.
Definition: interface.h:366
static u32 adj_midchain_tx_no_count_feature_node[VNET_LINK_NUM]
Definition: adj_midchain.c:29
adj_flags_t ia_flags
Flags on the adjacency 1-bytes.
Definition: adj.h:219
vlib_node_registration_t ip6_midchain_node
(constructor) VLIB_REGISTER_NODE (ip6_midchain_node)
Definition: ip6_forward.c:1989
struct ip_adjacency_t_::@45::@47 midchain
IP_LOOKUP_NEXT_MIDCHAIN.
#define CLIB_UNUSED(x)
Definition: clib.h:81
A virtual function table regisitered for a DPO type.
Definition: dpo.h:399
static vlib_node_registration_t adj_midchain_tx_node
(constructor) VLIB_REGISTER_NODE (adj_midchain_tx_node)
Definition: adj_midchain.c:279
static void vlib_increment_combined_counter(vlib_combined_counter_main_t *cm, u32 thread_index, u32 index, u64 n_packets, u64 n_bytes)
Increment a combined counter.
Definition: counter.h:204
void adj_lock(adj_index_t adj_index)
Take a reference counting lock on the adjacency.
Definition: adj.c:235
vnet_main_t * vnet_get_main(void)
Definition: misc.c:47
static uword adj_midchain_tx_no_count(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: adj_midchain.c:293
vnet_interface_main_t interface_main
Definition: vnet.h:56
struct ip_adjacency_t_::@45::@46 nbr
IP_LOOKUP_NEXT_ARP/IP_LOOKUP_NEXT_REWRITE.
static const char *const midchain_ip4_nodes[]
The per-protocol VLIB graph nodes that are assigned to a midchain object.
Definition: adj_midchain.c:635
#define NULL
Definition: clib.h:57
Broadcasr Adjacency.
Definition: adj.h:85
IP unicast adjacency.
Definition: adj.h:185
union ip_adjacency_t_::@45 sub_type
vlib_node_registration_t ip4_midchain_node
(constructor) VLIB_REGISTER_NODE (ip4_midchain_node)
Definition: ip4_forward.c:2590
u32 thread_index
Definition: main.h:179
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 vlib_validate_buffer_enqueue_x4(vm, node, next_index, to_next, n_left_to_next, bi0, bi1, bi2, bi3, next0, next1, next2, next3)
Finish enqueueing four buffers forward in the graph.
Definition: buffer_node.h:138
format_function_t format_ip46_address
Definition: format.h:61
ip_lookup_main_t lookup_main
Definition: ip4.h:98
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
void adj_nbr_update_rewrite_internal(ip_adjacency_t *adj, ip_lookup_next_t adj_next_index, u32 complete_next_index, u32 next_index, u8 *rewrite)
adj_nbr_update_rewrite_internal
Definition: adj_nbr.c:338
static uword vlib_buffer_length_in_chain(vlib_main_t *vm, vlib_buffer_t *b)
Get length in bytes of the buffer chain.
Definition: buffer_funcs.h:263
u32 adj_dpo_get_urpf(const dpo_id_t *dpo)
Definition: adj.c:225
unsigned char u8
Definition: types.h:56
vnet_link_t ia_link
link/ether-type 1 bytes
Definition: adj.h:206
const dpo_id_t * drop_dpo_get(dpo_proto_t proto)
Definition: drop_dpo.c:25
u8 output_feature_arc_index
Definition: lookup.h:138
ethernet_main_t ethernet_main
Definition: init.c:45
static ip_adjacency_t * adj_get(adj_index_t adj_index)
Get a pointer to an adjacency object from its index.
Definition: adj.h:380
enum ip_adjacency_flags_t_ adj_flags_t
Flags on an IP adjacency.
void dpo_register(dpo_type_t type, const dpo_vft_t *vft, const char *const *const *nodes)
For a given DPO type Register:
Definition: dpo.c:321
vlib_node_registration_t adj_nsh_midchain_node
(constructor) VLIB_REGISTER_NODE (adj_nsh_midchain_node)
Definition: adj_nsh.c:183
dpo_proto_t vnet_link_to_dpo_proto(vnet_link_t linkt)
Definition: dpo.c:95
format_function_t format_ip_adjacency
Definition: format.h:58
#define always_inline
Definition: clib.h:94
vlib_combined_counter_main_t * combined_sw_if_counters
Definition: interface.h:855
u8 * format_white_space(u8 *s, va_list *va)
Definition: std-formats.c:113
int vnet_feature_enable_disable_with_index(u8 arc_index, u32 feature_index, u32 sw_if_index, int enable_disable, void *feature_config, u32 n_feature_config_bytes)
Definition: feature.c:181
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
Definition: buffer.h:187
static const char *const *const midchain_nodes[DPO_PROTO_NUM]
Definition: adj_midchain.c:661
u8 output_feature_arc_index
Definition: ethernet.h:314
void adj_unlock(adj_index_t adj_index)
Release a reference counting lock on the adjacency.
Definition: adj.c:252
vlib_node_registration_t mpls_midchain_node
(constructor) VLIB_REGISTER_NODE (mpls_midchain_node)
Definition: mpls_output.c:352
unsigned int u32
Definition: types.h:88
format_function_t format_vnet_rewrite
Definition: rewrite.h:331
static uword adj_midchain_tx_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, int interface_count)
Definition: adj_midchain.c:43
u8 output_feature_arc_index
Definition: mpls.h:57
vlib_node_registration_t adj_l2_midchain_node
(constructor) VLIB_REGISTER_NODE (adj_l2_midchain_node)
Definition: adj_l2.c:186
static const char *const midchain_mpls_nodes[]
Definition: adj_midchain.c:645
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 ADJ_INDEX_INVALID
Invalid ADJ index - used when no adj is known likewise blazoned capitals INVALID speak volumes where ...
Definition: adj_types.h:36
static u32 adj_get_midchain_node(vnet_link_t link)
Definition: adj_midchain.c:375
Trace data for packets traversing the midchain tx node.
Definition: adj_midchain.c:34
void adj_midchain_module_init(void)
Module initialisation.
Definition: adj_midchain.c:671
adj_index_t ai
the midchain adj we are traversing
Definition: adj_midchain.c:39
#define PREDICT_FALSE(x)
Definition: clib.h:107
This packet matches an "interface route" and packets need to be passed to ARP to find rewrite string ...
Definition: adj.h:68
static u8 adj_midchain_get_feature_arc_index_for_link_type(const ip_adjacency_t *adj)
Definition: adj_midchain.c:396
static vlib_node_registration_t adj_midchain_tx_no_count_node
(constructor) VLIB_REGISTER_NODE (adj_midchain_tx_no_count_node)
Definition: adj_midchain.c:300
#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
u32 flags
Definition: vhost_user.h:115
This packet matches an "incomplete adjacency" and packets need to be passed to ARP to find rewrite st...
Definition: adj.h:63
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:155
u16 n_vectors
Definition: node.h:401
mpls_main_t mpls_main
Definition: mpls.c:25
vlib_main_t * vm
Definition: buffer.c:294
static void adj_dpo_unlock(dpo_id_t *dpo)
Definition: adj_midchain.c:616
Multicast Midchain Adjacency.
Definition: adj.h:89
static u8 * format_adj_midchain_tx_trace(u8 *s, va_list *args)
Definition: adj_midchain.c:258
void adj_nbr_midchain_update_rewrite(adj_index_t adj_index, adj_midchain_fixup_t fixup, const void *fixup_data, adj_flags_t flags, u8 *rewrite)
adj_nbr_midchain_update_rewrite
Definition: adj_midchain.c:506
Packets TX through the midchain do not increment the interface counters.
Definition: adj.h:176
void(* adj_midchain_fixup_t)(vlib_main_t *vm, struct ip_adjacency_t_ *adj, vlib_buffer_t *b0, const void *data)
A function type for post-rewrite fixups on midchain adjacency.
Definition: adj.h:152
u32 adj_index_t
An index for adjacencies.
Definition: adj_types.h:30
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
u8 * format_adj_midchain(u8 *s, va_list *ap)
Format a midchain adjacency.
Definition: adj_midchain.c:589
This packets follow a mid-chain adjacency.
Definition: adj.h:76
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
Definition: node.h:513
static u32 adj_nbr_midchain_get_tx_node(ip_adjacency_t *adj)
Definition: adj_midchain.c:437
#define ASSERT(truth)
void adj_nbr_midchain_stack(adj_index_t adj_index, const dpo_id_t *next)
adj_nbr_midchain_stack
Definition: adj_midchain.c:571
ip6_main_t ip6_main
Definition: ip6_forward.c:2590
ip_lookup_main_t lookup_main
Definition: ip6.h:161
enum vnet_link_t_ vnet_link_t
Link Type: A description of the protocol of packets on the link.
void adj_nbr_midchain_unstack(adj_index_t adj_index)
adj_nbr_midchain_unstack
Definition: adj_midchain.c:549
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:386
static void adj_dpo_lock(dpo_id_t *dpo)
Definition: adj_midchain.c:611
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
fib_protocol_t ia_nh_proto
The protocol of the neighbor/peer.
Definition: adj.h:213
Definition: defs.h:47
#define DPO_PROTO_NUM
Definition: dpo.h:70
index_t dpoi_index
the index of objects of that type
Definition: dpo.h:184
ip_lookup_next_t lookup_next_index
Next hop after ip4-lookup.
Definition: adj.h:200
void adj_midchain_setup(adj_index_t adj_index, adj_midchain_fixup_t fixup, const void *data, adj_flags_t flags)
adj_midchain_setup
Definition: adj_midchain.c:461
nsh_main_dummy_t nsh_main_dummy
Definition: adj_nsh.c:20
u64 uword
Definition: types.h:112
struct adj_midchain_tx_trace_t_ adj_midchain_tx_trace_t
Trace data for packets traversing the midchain tx node.
static u32 adj_midchain_tx_feature_node[VNET_LINK_NUM]
The two midchain tx feature node indices.
Definition: adj_midchain.c:28
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:267
#define vnet_buffer(b)
Definition: buffer.h:344
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:900
#define CLIB_MEMORY_BARRIER()
Definition: clib.h:111
u8 * format_vnet_link(u8 *s, va_list *ap)
Definition: fib_types.c:40
u16 dpoi_next_node
The next VLIB node to follow.
Definition: dpo.h:180
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 const char *const midchain_ethernet_nodes[]
Definition: adj_midchain.c:650
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
VNET_FEATURE_INIT(adj_midchain_tx_ip4, static)
static u32 adj_nbr_midchain_get_feature_node(ip_adjacency_t *adj)
Definition: adj_midchain.c:445
static ip46_type_t adj_proto_to_46(fib_protocol_t proto)
Definition: adj_internal.h:82
void dpo_stack(dpo_type_t child_type, dpo_proto_t child_proto, 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:515