FD.io VPP  v17.07.01-10-g3be13f0
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 
69  while (n_left_from >= 4 && n_left_to_next > 2)
70  {
71  u32 bi0, adj_index0, next0;
72  const ip_adjacency_t * adj0;
73  const dpo_id_t *dpo0;
74  vlib_buffer_t * b0;
75  u32 bi1, adj_index1, next1;
76  const ip_adjacency_t * adj1;
77  const dpo_id_t *dpo1;
78  vlib_buffer_t * b1;
79 
80  /* Prefetch next iteration. */
81  {
82  vlib_buffer_t * p2, * p3;
83 
84  p2 = vlib_get_buffer (vm, from[2]);
85  p3 = vlib_get_buffer (vm, from[3]);
86 
87  vlib_prefetch_buffer_header (p2, LOAD);
88  vlib_prefetch_buffer_header (p3, LOAD);
89 
92  }
93 
94  bi0 = from[0];
95  to_next[0] = bi0;
96  bi1 = from[1];
97  to_next[1] = bi1;
98 
99  from += 2;
100  to_next += 2;
101  n_left_from -= 2;
102  n_left_to_next -= 2;
103 
104  b0 = vlib_get_buffer(vm, bi0);
105  b1 = vlib_get_buffer(vm, bi1);
106 
107  /* Follow the DPO on which the midchain is stacked */
108  adj_index0 = vnet_buffer(b0)->ip.adj_index[VLIB_TX];
109  adj_index1 = vnet_buffer(b1)->ip.adj_index[VLIB_TX];
110 
111  adj0 = adj_get(adj_index0);
112  adj1 = adj_get(adj_index1);
113 
114  dpo0 = &adj0->sub_type.midchain.next_dpo;
115  dpo1 = &adj1->sub_type.midchain.next_dpo;
116 
117  next0 = dpo0->dpoi_next_node;
118  next1 = dpo1->dpoi_next_node;
119 
120  vnet_buffer(b1)->ip.adj_index[VLIB_TX] = dpo1->dpoi_index;
121  vnet_buffer(b0)->ip.adj_index[VLIB_TX] = dpo0->dpoi_index;
122 
123  if (interface_count)
124  {
127  thread_index,
128  adj0->rewrite_header.sw_if_index,
129  1,
130  vlib_buffer_length_in_chain (vm, b0));
133  thread_index,
134  adj1->rewrite_header.sw_if_index,
135  1,
136  vlib_buffer_length_in_chain (vm, b1));
137  }
138 
140  {
141  adj_midchain_tx_trace_t *tr = vlib_add_trace (vm, node,
142  b0, sizeof (*tr));
143  tr->ai = adj_index0;
144  }
146  {
147  adj_midchain_tx_trace_t *tr = vlib_add_trace (vm, node,
148  b1, sizeof (*tr));
149  tr->ai = adj_index1;
150  }
151 
152  vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
153  to_next, n_left_to_next,
154  bi0, bi1,
155  next0, next1);
156  }
157  while (n_left_from > 0 && n_left_to_next > 0)
158  {
159  u32 bi0, adj_index0, next0;
160  const ip_adjacency_t * adj0;
161  const dpo_id_t *dpo0;
162  vlib_buffer_t * b0;
163 
164  bi0 = from[0];
165  to_next[0] = bi0;
166  from += 1;
167  to_next += 1;
168  n_left_from -= 1;
169  n_left_to_next -= 1;
170 
171  b0 = vlib_get_buffer(vm, bi0);
172 
173  /* Follow the DPO on which the midchain is stacked */
174  adj_index0 = vnet_buffer(b0)->ip.adj_index[VLIB_TX];
175  adj0 = adj_get(adj_index0);
176  dpo0 = &adj0->sub_type.midchain.next_dpo;
177  next0 = dpo0->dpoi_next_node;
178  vnet_buffer(b0)->ip.adj_index[VLIB_TX] = dpo0->dpoi_index;
179 
180  if (interface_count)
181  {
184  thread_index,
185  adj0->rewrite_header.sw_if_index,
186  1,
187  vlib_buffer_length_in_chain (vm, b0));
188  }
189 
191  {
192  adj_midchain_tx_trace_t *tr = vlib_add_trace (vm, node,
193  b0, sizeof (*tr));
194  tr->ai = adj_index0;
195  }
196 
197  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
198  to_next, n_left_to_next,
199  bi0, next0);
200  }
201 
202  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
203  }
204 
205  return frame->n_vectors;
206 }
207 
208 static u8 *
209 format_adj_midchain_tx_trace (u8 * s, va_list * args)
210 {
211  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
212  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
213  adj_midchain_tx_trace_t *tr = va_arg (*args, adj_midchain_tx_trace_t*);
214 
215  s = format(s, "adj-midchain:[%d]:%U", tr->ai,
216  format_ip_adjacency, tr->ai,
218 
219  return (s);
220 }
221 
222 static uword
224  vlib_node_runtime_t * node,
225  vlib_frame_t * frame)
226 {
227  return (adj_midchain_tx_inline(vm, node, frame, 1));
228 }
229 
231  .function = adj_midchain_tx,
232  .name = "adj-midchain-tx",
233  .vector_size = sizeof (u32),
234 
235  .format_trace = format_adj_midchain_tx_trace,
236 
237  .n_next_nodes = 1,
238  .next_nodes = {
239  [0] = "error-drop",
240  },
241 };
242 
243 static uword
245  vlib_node_runtime_t * node,
246  vlib_frame_t * frame)
247 {
248  return (adj_midchain_tx_inline(vm, node, frame, 0));
249 }
250 
252  .function = adj_midchain_tx_no_count,
253  .name = "adj-midchain-tx-no-count",
254  .vector_size = sizeof (u32),
255 
256  .format_trace = format_adj_midchain_tx_trace,
257 
258  .n_next_nodes = 1,
259  .next_nodes = {
260  [0] = "error-drop",
261  },
262 };
263 
264 VNET_FEATURE_INIT (adj_midchain_tx_ip4, static) = {
265  .arc_name = "ip4-output",
266  .node_name = "adj-midchain-tx",
267  .runs_before = VNET_FEATURES ("interface-output"),
268  .feature_index_ptr = &adj_midchain_tx_feature_node[VNET_LINK_IP4],
269 };
270 VNET_FEATURE_INIT (adj_midchain_tx_no_count_ip4, static) = {
271  .arc_name = "ip4-output",
272  .node_name = "adj-midchain-tx-no-count",
273  .runs_before = VNET_FEATURES ("interface-output"),
275 };
276 VNET_FEATURE_INIT (adj_midchain_tx_ip6, static) = {
277  .arc_name = "ip6-output",
278  .node_name = "adj-midchain-tx",
279  .runs_before = VNET_FEATURES ("interface-output"),
280  .feature_index_ptr = &adj_midchain_tx_feature_node[VNET_LINK_IP6],
281 };
282 VNET_FEATURE_INIT (adj_midchain_tx_no_count_ip6, static) = {
283  .arc_name = "ip6-output",
284  .node_name = "adj-midchain-tx-no-count",
285  .runs_before = VNET_FEATURES ("interface-output"),
287 };
288 VNET_FEATURE_INIT (adj_midchain_tx_mpls, static) = {
289  .arc_name = "mpls-output",
290  .node_name = "adj-midchain-tx",
291  .runs_before = VNET_FEATURES ("interface-output"),
292  .feature_index_ptr = &adj_midchain_tx_feature_node[VNET_LINK_MPLS],
293 };
294 VNET_FEATURE_INIT (adj_midchain_tx_no_count_mpls, static) = {
295  .arc_name = "mpls-output",
296  .node_name = "adj-midchain-tx-no-count",
297  .runs_before = VNET_FEATURES ("interface-output"),
299 };
300 VNET_FEATURE_INIT (adj_midchain_tx_ethernet, static) = {
301  .arc_name = "ethernet-output",
302  .node_name = "adj-midchain-tx",
303  .runs_before = VNET_FEATURES ("error-drop"),
304  .feature_index_ptr = &adj_midchain_tx_feature_node[VNET_LINK_ETHERNET],
305 };
306 VNET_FEATURE_INIT (adj_midchain_tx_no_count_ethernet, static) = {
307  .arc_name = "ethernet-output",
308  .node_name = "adj-midchain-tx-no-count",
309  .runs_before = VNET_FEATURES ("error-drop"),
311 };
312 VNET_FEATURE_INIT (adj_midchain_tx_nsh, static) = {
313  .arc_name = "nsh-output",
314  .node_name = "adj-midchain-tx",
315  .runs_before = VNET_FEATURES ("error-drop"),
316  .feature_index_ptr = &adj_midchain_tx_feature_node[VNET_LINK_NSH],
317 };
318 VNET_FEATURE_INIT (adj_midchain_tx_no_count_nsh, static) = {
319  .arc_name = "nsh-output",
320  .node_name = "adj-midchain-tx-no-count",
321  .runs_before = VNET_FEATURES ("error-drop"),
323 };
324 
325 static inline u32
327 {
328  switch (link) {
329  case VNET_LINK_IP4:
330  return (ip4_midchain_node.index);
331  case VNET_LINK_IP6:
332  return (ip6_midchain_node.index);
333  case VNET_LINK_MPLS:
334  return (mpls_midchain_node.index);
335  case VNET_LINK_ETHERNET:
336  return (adj_l2_midchain_node.index);
337  case VNET_LINK_NSH:
338  return (adj_nsh_midchain_node.index);
339  case VNET_LINK_ARP:
340  break;
341  }
342  ASSERT(0);
343  return (0);
344 }
345 
346 static u8
348 {
349  u8 arc = (u8) ~0;
350  switch (adj->ia_link)
351  {
352  case VNET_LINK_IP4:
353  {
355  break;
356  }
357  case VNET_LINK_IP6:
358  {
360  break;
361  }
362  case VNET_LINK_MPLS:
363  {
365  break;
366  }
367  case VNET_LINK_ETHERNET:
368  {
370  break;
371  }
372  case VNET_LINK_NSH:
373  {
374  arc = nsh_main_dummy.output_feature_arc_index;
375  break;
376  }
377  case VNET_LINK_ARP:
378  ASSERT(0);
379  break;
380  }
381 
382  ASSERT (arc != (u8) ~0);
383 
384  return (arc);
385 }
386 
387 static u32
389 {
390  return ((adj->ia_flags & ADJ_FLAG_MIDCHAIN_NO_COUNT) ?
392  adj_midchain_tx_node.index);
393 }
394 
395 /**
396  * adj_midchain_setup
397  *
398  * Setup the adj as a mid-chain
399  */
400 void
402  adj_midchain_fixup_t fixup,
404 {
405  u32 feature_index, tx_node;
406  ip_adjacency_t *adj;
407  u8 arc_index;
408 
409  ASSERT(ADJ_INDEX_INVALID != adj_index);
410 
411  adj = adj_get(adj_index);
412 
413  adj->sub_type.midchain.fixup_func = fixup;
414  adj->ia_flags |= flags;
415 
417  feature_index = (flags & ADJ_FLAG_MIDCHAIN_NO_COUNT) ?
420 
421  tx_node = adj_nbr_midchain_get_tx_node(adj);
422 
423  vnet_feature_enable_disable_with_index (arc_index, feature_index,
424  adj->rewrite_header.sw_if_index,
425  1 /* enable */, 0, 0);
426 
427  /*
428  * stack the midchain on the drop so it's ready to forward in the adj-midchain-tx.
429  * The graph arc used/created here is from the midchain-tx node to the
430  * child's registered node. This is because post adj processing the next
431  * node are any output features, then the midchain-tx. from there we
432  * need to get to the stacked child's node.
433  */
434  dpo_stack_from_node(tx_node,
435  &adj->sub_type.midchain.next_dpo,
437 }
438 
439 /**
440  * adj_nbr_midchain_update_rewrite
441  *
442  * Update the adjacency's rewrite string. A NULL string implies the
443  * rewrite is reset (i.e. when ARP/ND etnry is gone).
444  * NB: the adj being updated may be handling traffic in the DP.
445  */
446 void
448  adj_midchain_fixup_t fixup,
450  u8 *rewrite)
451 {
452  ip_adjacency_t *adj;
453 
454  ASSERT(ADJ_INDEX_INVALID != adj_index);
455 
456  adj = adj_get(adj_index);
457 
458  /*
459  * one time only update. since we don't support chainging the tunnel
460  * src,dst, this is all we need.
461  */
463  /*
464  * tunnels can always provide a rewrite.
465  */
466  ASSERT(NULL != rewrite);
467 
468  adj_midchain_setup(adj_index, fixup, flags);
469 
470  /*
471  * update the rewirte with the workers paused.
472  */
477  rewrite);
478 }
479 
480 /**
481  * adj_nbr_midchain_unstack
482  *
483  * Unstack the adj. stack it on drop
484  */
485 void
487 {
488  ip_adjacency_t *adj;
489 
490  ASSERT(ADJ_INDEX_INVALID != adj_index);
491 
492  adj = adj_get(adj_index);
493 
494  /*
495  * stack on the drop
496  */
499  &adj->sub_type.midchain.next_dpo,
501 
503 }
504 
505 /**
506  * adj_nbr_midchain_stack
507  */
508 void
510  const dpo_id_t *next)
511 {
512  ip_adjacency_t *adj;
513 
514  ASSERT(ADJ_INDEX_INVALID != adj_index);
515 
516  adj = adj_get(adj_index);
517 
520 
522  &adj->sub_type.midchain.next_dpo,
523  next);
524 }
525 
526 u8*
527 format_adj_midchain (u8* s, va_list *ap)
528 {
529  index_t index = va_arg(*ap, index_t);
530  u32 indent = va_arg(*ap, u32);
531  ip_adjacency_t * adj = adj_get(index);
532 
533  s = format (s, "%U", format_vnet_link, adj->ia_link);
534  s = format (s, " via %U ",
535  format_ip46_address, &adj->sub_type.nbr.next_hop);
536  s = format (s, " %U",
538  &adj->rewrite_header, sizeof (adj->rewrite_data), indent);
539  s = format (s, "\n%Ustacked-on:\n%U%U",
540  format_white_space, indent,
541  format_white_space, indent+2,
542  format_dpo_id, &adj->sub_type.midchain.next_dpo, indent+2);
543 
544  return (s);
545 }
546 
547 static void
549 {
550  adj_lock(dpo->dpoi_index);
551 }
552 static void
554 {
555  adj_unlock(dpo->dpoi_index);
556 }
557 
558 const static dpo_vft_t adj_midchain_dpo_vft = {
560  .dv_unlock = adj_dpo_unlock,
561  .dv_format = format_adj_midchain,
562 };
563 
564 /**
565  * @brief The per-protocol VLIB graph nodes that are assigned to a midchain
566  * object.
567  *
568  * this means that these graph nodes are ones from which a midchain is the
569  * parent object in the DPO-graph.
570  */
571 const static char* const midchain_ip4_nodes[] =
572 {
573  "ip4-midchain",
574  NULL,
575 };
576 const static char* const midchain_ip6_nodes[] =
577 {
578  "ip6-midchain",
579  NULL,
580 };
581 const static char* const midchain_mpls_nodes[] =
582 {
583  "mpls-midchain",
584  NULL,
585 };
586 const static char* const midchain_ethernet_nodes[] =
587 {
588  "adj-l2-midchain",
589  NULL,
590 };
591 const static char* const midchain_nsh_nodes[] =
592 {
593  "adj-nsh-midchain",
594  NULL,
595 };
596 
597 const static char* const * const midchain_nodes[DPO_PROTO_NUM] =
598 {
604 };
605 
606 void
608 {
609  dpo_register(DPO_ADJACENCY_MIDCHAIN, &adj_midchain_dpo_vft, midchain_nodes);
610 }
static uword adj_midchain_tx(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: adj_midchain.c:223
static const char *const midchain_nsh_nodes[]
Definition: adj_midchain.c:591
static const char *const midchain_ip6_nodes[]
Definition: adj_midchain.c:576
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:431
dpo_lock_fn_t dv_lock
A reference counting lock function.
Definition: dpo.h:341
#define VNET_LINK_NUM
Number of link types.
Definition: interface.h:277
void adj_midchain_setup(adj_index_t adj_index, adj_midchain_fixup_t fixup, adj_flags_t flags)
adj_midchain_setup
Definition: adj_midchain.c:401
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:208
vlib_node_registration_t ip6_midchain_node
(constructor) VLIB_REGISTER_NODE (ip6_midchain_node)
Definition: ip6_forward.c:2330
#define CLIB_UNUSED(x)
Definition: clib.h:79
A virtual function table regisitered for a DPO type.
Definition: dpo.h:336
static vlib_node_registration_t adj_midchain_tx_node
(constructor) VLIB_REGISTER_NODE (adj_midchain_tx_node)
Definition: adj_midchain.c:230
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:211
void adj_lock(adj_index_t adj_index)
Take a reference counting lock on the adjacency.
Definition: adj.c:212
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
struct ip_adjacency_t_::@37::@38 nbr
IP_LOOKUP_NEXT_ARP/IP_LOOKUP_NEXT_REWRITE.
static uword adj_midchain_tx_no_count(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: adj_midchain.c:244
vnet_interface_main_t interface_main
Definition: vnet.h:56
static const char *const midchain_ip4_nodes[]
The per-protocol VLIB graph nodes that are assigned to a midchain object.
Definition: adj_midchain.c:571
u8 * format_vnet_link(u8 *s, va_list ap)
Definition: fib_types.c:38
#define NULL
Definition: clib.h:55
IP unicast adjacency.
Definition: adj.h:174
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:459
vlib_node_registration_t ip4_midchain_node
(constructor) VLIB_REGISTER_NODE (ip4_midchain_node)
Definition: ip4_forward.c:2836
u32 thread_index
Definition: main.h:159
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
format_function_t format_ip46_address
Definition: format.h:61
ip_lookup_main_t lookup_main
Definition: ip4.h:85
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
union ip_adjacency_t_::@37 sub_type
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:333
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:100
vnet_link_t ia_link
link/ether-type 1 bytes
Definition: adj.h:195
const dpo_id_t * drop_dpo_get(dpo_proto_t proto)
Definition: drop_dpo.c:25
void adj_nbr_midchain_update_rewrite(adj_index_t adj_index, adj_midchain_fixup_t fixup, adj_flags_t flags, u8 *rewrite)
adj_nbr_midchain_update_rewrite
Definition: adj_midchain.c:447
u8 output_feature_arc_index
Definition: lookup.h:137
ethernet_main_t ethernet_main
Definition: ethernet.h:273
static ip_adjacency_t * adj_get(adj_index_t adj_index)
Get a pointer to an adjacency object from its index.
Definition: adj.h:365
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:260
vlib_node_registration_t adj_nsh_midchain_node
(constructor) VLIB_REGISTER_NODE (adj_nsh_midchain_node)
Definition: adj_nsh.c:181
dpo_proto_t vnet_link_to_dpo_proto(vnet_link_t linkt)
Definition: dpo.c:91
format_function_t format_ip_adjacency
Definition: format.h:58
#define always_inline
Definition: clib.h:84
vlib_combined_counter_main_t * combined_sw_if_counters
Definition: interface.h:653
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:177
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
Definition: buffer.h:164
static const char *const *const midchain_nodes[DPO_PROTO_NUM]
Definition: adj_midchain.c:597
u8 output_feature_arc_index
Definition: ethernet.h:267
void adj_unlock(adj_index_t adj_index)
Release a reference counting lock on the adjacency.
Definition: adj.c:229
vlib_node_registration_t mpls_midchain_node
(constructor) VLIB_REGISTER_NODE (mpls_midchain_node)
Definition: mpls_output.c:357
format_function_t format_vnet_rewrite
Definition: rewrite.h:338
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:55
vlib_node_registration_t adj_l2_midchain_node
(constructor) VLIB_REGISTER_NODE (adj_l2_midchain_node)
Definition: adj_l2.c:179
static const char *const midchain_mpls_nodes[]
Definition: adj_midchain.c:581
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
Definition: dpo.h:152
#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:326
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:607
adj_index_t ai
the midchain adj we are traversing
Definition: adj_midchain.c:39
#define PREDICT_FALSE(x)
Definition: clib.h:97
static u8 adj_midchain_get_feature_arc_index_for_link_type(const ip_adjacency_t *adj)
Definition: adj_midchain.c:347
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:251
struct ip_adjacency_t_::@37::@39 midchain
IP_LOOKUP_NEXT_MIDCHAIN.
#define vlib_validate_buffer_enqueue_x2(vm, node, next_index, to_next, n_left_to_next, bi0, bi1, next0, next1)
Finish enqueueing two buffers forward in the graph.
Definition: buffer_node.h:70
#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:216
#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:366
This packet matches an "incomplete adjacency" and packets need to be passed to ARP to find rewrite st...
Definition: adj.h:63
u16 n_vectors
Definition: node.h:345
mpls_main_t mpls_main
Definition: mpls.c:25
#define CLIB_PREFETCH(addr, size, type)
Definition: cache.h:82
static void adj_dpo_unlock(dpo_id_t *dpo)
Definition: adj_midchain.c:553
Multicast Midchain Adjacency.
Definition: adj.h:86
static u8 * format_adj_midchain_tx_trace(u8 *s, va_list *args)
Definition: adj_midchain.c:209
#define VLIB_BUFFER_IS_TRACED
Definition: buffer.h:85
Packets TX through the midchain do not increment the interface counters.
Definition: adj.h:165
u32 adj_index_t
An index for adjacencies.
Definition: adj_types.h:30
u8 * format_adj_midchain(u8 *s, va_list *ap)
Format a midchain adjacency.
Definition: adj_midchain.c:527
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:460
static u32 adj_nbr_midchain_get_tx_node(ip_adjacency_t *adj)
Definition: adj_midchain.c:388
#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:509
unsigned int u32
Definition: types.h:88
ip6_main_t ip6_main
Definition: ip6_forward.c:2926
ip_lookup_main_t lookup_main
Definition: ip6.h:148
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:486
u8 * format_dpo_id(u8 *s, va_list *args)
Format a DPO_id_t oject
Definition: dpo.c:123
#define VNET_FEATURES(...)
Definition: feature.h:368
static void adj_dpo_lock(dpo_id_t *dpo)
Definition: adj_midchain.c:548
u64 uword
Definition: types.h:112
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
Definition: defs.h:47
#define DPO_PROTO_NUM
Definition: dpo.h:73
index_t dpoi_index
the index of objects of that type
Definition: dpo.h:168
void(* adj_midchain_fixup_t)(vlib_main_t *vm, struct ip_adjacency_t_ *adj, vlib_buffer_t *b0)
A function type for post-rewrite fixups on midchain adjacency.
Definition: adj.h:142
unsigned char u8
Definition: types.h:56
ip_lookup_next_t lookup_next_index
Next hop after ip4-lookup.
Definition: adj.h:189
nsh_main_dummy_t nsh_main_dummy
Definition: adj_nsh.c:20
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:269
#define vnet_buffer(b)
Definition: buffer.h:304
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:144
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:1168
u8 data[0]
Packet data.
Definition: buffer.h:152
#define CLIB_MEMORY_BARRIER()
Definition: clib.h:101
u16 dpoi_next_node
The next VLIB node to follow.
Definition: dpo.h:164
u32 flags
Definition: vhost-user.h:76
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:67
u32 flags
buffer flags: VLIB_BUFFER_IS_TRACED: trace this buffer.
Definition: buffer.h:74
static const char *const midchain_ethernet_nodes[]
Definition: adj_midchain.c:586
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
VNET_FEATURE_INIT(adj_midchain_tx_ip4, static)
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:416