FD.io VPP  v20.01-48-g3e0dafb74
Vector Packet Processing
node.c
Go to the documentation of this file.
1 /*
2  *------------------------------------------------------------------
3  * Copyright (c) 2017 Cisco and/or its affiliates.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *------------------------------------------------------------------
16  */
17 
18 #define _GNU_SOURCE
19 #include <stdint.h>
20 #include <vnet/llc/llc.h>
21 #include <vnet/snap/snap.h>
22 #include <vnet/bonding/node.h>
23 
24 #ifndef CLIB_MARCH_VARIANT
26 #endif /* CLIB_MARCH_VARIANT */
27 
28 #define foreach_bond_input_error \
29  _(NONE, "no error") \
30  _(IF_DOWN, "interface down") \
31  _(PASSIVE_IF, "traffic received on passive interface") \
32  _(PASS_THRU, "pass through (CDP, LLDP, slow protocols)")
33 
34 typedef enum
35 {
36 #define _(f,s) BOND_INPUT_ERROR_##f,
38 #undef _
41 
42 static char *bond_input_error_strings[] = {
43 #define _(n,s) s,
45 #undef _
46 };
47 
48 static u8 *
49 format_bond_input_trace (u8 * s, va_list * args)
50 {
51  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
52  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
53  bond_packet_trace_t *t = va_arg (*args, bond_packet_trace_t *);
54 
55  s = format (s, "src %U, dst %U, %U -> %U",
59  t->sw_if_index,
61  t->bond_sw_if_index);
62 
63  return s;
64 }
65 
66 typedef enum
67 {
71 
74 {
75  llc_header_t *llc;
76  snap_header_t *snap;
77 
78  llc = (llc_header_t *) (eth + 1);
79  snap = (snap_header_t *) (llc + 1);
80 
81  return ((eth->type == htons (ETHERNET_TYPE_CDP)) ||
82  ((llc->src_sap == 0xAA) && (llc->control == 0x03) &&
83  (snap->protocol == htons (0x2000)) &&
84  (snap->oui[0] == 0) && (snap->oui[1] == 0) &&
85  (snap->oui[2] == 0x0C)));
86 }
87 
88 static inline void
90  vlib_buffer_t * b, u32 bond_sw_if_index,
91  u32 * n_rx_packets, u32 * n_rx_bytes)
92 {
93  u16 *ethertype_p, ethertype;
96 
97  (*n_rx_packets)++;
98  *n_rx_bytes += b->current_length;
99  ethertype = clib_mem_unaligned (&eth->type, u16);
100  if (!ethernet_frame_is_tagged (ntohs (ethertype)))
101  {
102  // Let some layer2 packets pass through.
103  if (PREDICT_TRUE ((ethertype != htons (ETHERNET_TYPE_SLOW_PROTOCOLS))
104  && !packet_is_cdp (eth)
105  && (ethertype != htons (ETHERNET_TYPE_802_1_LLDP))))
106  {
107  /* Change the physical interface to bond interface */
108  vnet_buffer (b)->sw_if_index[VLIB_RX] = bond_sw_if_index;
109  return;
110  }
111  }
112  else
113  {
114  vlan = (void *) (eth + 1);
115  ethertype_p = &vlan->type;
116  ethertype = clib_mem_unaligned (ethertype_p, u16);
117  if (ethertype == ntohs (ETHERNET_TYPE_VLAN))
118  {
119  vlan++;
120  ethertype_p = &vlan->type;
121  }
122  ethertype = clib_mem_unaligned (ethertype_p, u16);
123  if (PREDICT_TRUE ((ethertype != htons (ETHERNET_TYPE_SLOW_PROTOCOLS))
124  && (ethertype != htons (ETHERNET_TYPE_CDP))
125  && (ethertype != htons (ETHERNET_TYPE_802_1_LLDP))))
126  {
127  /* Change the physical interface to bond interface */
128  vnet_buffer (b)->sw_if_index[VLIB_RX] = bond_sw_if_index;
129  return;
130  }
131  }
132 
133  vlib_error_count (vm, node->node_index, BOND_INPUT_ERROR_PASS_THRU, 1);
134  return;
135 }
136 
137 static inline void
139  u32 * last_slave_sw_if_index, u32 slave_sw_if_index,
140  u32 * bond_sw_if_index, vlib_buffer_t * b,
141  u32 * next_index, vlib_error_t * error)
142 {
143  slave_if_t *sif;
144  bond_if_t *bif;
145 
146  *next_index = BOND_INPUT_NEXT_DROP;
147  *error = 0;
148 
149  if (PREDICT_TRUE (*last_slave_sw_if_index == slave_sw_if_index))
150  goto next;
151 
152  *last_slave_sw_if_index = slave_sw_if_index;
153 
154  sif = bond_get_slave_by_sw_if_index (slave_sw_if_index);
155  ASSERT (sif);
156 
158 
159  ASSERT (bif);
160  ASSERT (vec_len (bif->slaves));
161 
162  if (PREDICT_FALSE (bif->admin_up == 0))
163  {
164  *bond_sw_if_index = slave_sw_if_index;
165  *error = node->errors[BOND_INPUT_ERROR_IF_DOWN];
166  }
167 
168  if (PREDICT_FALSE ((bif->mode == BOND_MODE_ACTIVE_BACKUP) &&
169  vec_len (bif->active_slaves) &&
170  (slave_sw_if_index != bif->active_slaves[0])))
171  {
172  *bond_sw_if_index = slave_sw_if_index;
173  *error = node->errors[BOND_INPUT_ERROR_PASSIVE_IF];
174  return;
175  }
176 
177  *bond_sw_if_index = bif->sw_if_index;
178 
179 next:
180  vnet_feature_next (next_index, b);
181 }
182 
185  vlib_buffer_t * b2, vlib_buffer_t * b3)
186 {
187  u32 tmp0, tmp1, tmp2, tmp3;
188 
189  tmp0 = tmp1 = tmp2 = tmp3 = BOND_INPUT_NEXT_DROP;
190  vnet_feature_next (&tmp0, b0);
191  vnet_feature_next (&tmp1, b1);
192  vnet_feature_next (&tmp2, b2);
193  vnet_feature_next (&tmp3, b3);
194 }
195 
199 {
200  u16 thread_index = vm->thread_index;
201  u32 *from, n_left;
202  vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b;
203  u32 sw_if_indices[VLIB_FRAME_SIZE], *sw_if_index;
204  u16 nexts[VLIB_FRAME_SIZE], *next;
205  u32 last_slave_sw_if_index = ~0;
206  u32 bond_sw_if_index = 0;
207  vlib_error_t error = 0;
208  u32 next_index = 0;
209  u32 n_rx_bytes = 0, n_rx_packets = 0;
210 
211  /* Vector of buffer / pkt indices we're supposed to process */
212  from = vlib_frame_vector_args (frame);
213 
214  /* Number of buffers / pkts */
215  n_left = frame->n_vectors;
216 
217  vlib_get_buffers (vm, from, bufs, n_left);
218 
219  b = bufs;
220  next = nexts;
221  sw_if_index = sw_if_indices;
222 
223  while (n_left >= 4)
224  {
225  u32 x = 0;
226  /* Prefetch next iteration */
227  if (PREDICT_TRUE (n_left >= 16))
228  {
229  vlib_prefetch_buffer_data (b[8], LOAD);
230  vlib_prefetch_buffer_data (b[9], LOAD);
231  vlib_prefetch_buffer_data (b[10], LOAD);
232  vlib_prefetch_buffer_data (b[11], LOAD);
233 
234  vlib_prefetch_buffer_header (b[12], LOAD);
235  vlib_prefetch_buffer_header (b[13], LOAD);
236  vlib_prefetch_buffer_header (b[14], LOAD);
237  vlib_prefetch_buffer_header (b[15], LOAD);
238  }
239 
240  sw_if_index[0] = vnet_buffer (b[0])->sw_if_index[VLIB_RX];
241  sw_if_index[1] = vnet_buffer (b[1])->sw_if_index[VLIB_RX];
242  sw_if_index[2] = vnet_buffer (b[2])->sw_if_index[VLIB_RX];
243  sw_if_index[3] = vnet_buffer (b[3])->sw_if_index[VLIB_RX];
244 
245  x |= sw_if_index[0] ^ last_slave_sw_if_index;
246  x |= sw_if_index[1] ^ last_slave_sw_if_index;
247  x |= sw_if_index[2] ^ last_slave_sw_if_index;
248  x |= sw_if_index[3] ^ last_slave_sw_if_index;
249 
250  if (PREDICT_TRUE (x == 0))
251  {
252  /*
253  * Optimize to call update_next only if there is a feature arc
254  * after bond-input. Test feature count greater than 1 because
255  * bond-input itself is a feature arc for this slave interface.
256  */
257  ASSERT ((vnet_buffer (b[0])->feature_arc_index ==
258  vnet_buffer (b[1])->feature_arc_index) &&
259  (vnet_buffer (b[0])->feature_arc_index ==
260  vnet_buffer (b[2])->feature_arc_index) &&
261  (vnet_buffer (b[0])->feature_arc_index ==
262  vnet_buffer (b[3])->feature_arc_index));
264  (vnet_buffer (b[0])->feature_arc_index,
265  last_slave_sw_if_index) > 1))
266  bond_update_next_x4 (b[0], b[1], b[2], b[3]);
267 
268  next[0] = next[1] = next[2] = next[3] = next_index;
269  if (next_index == BOND_INPUT_NEXT_DROP)
270  {
271  b[0]->error = error;
272  b[1]->error = error;
273  b[2]->error = error;
274  b[3]->error = error;
275  }
276  else
277  {
278  bond_sw_if_idx_rewrite (vm, node, b[0], bond_sw_if_index,
279  &n_rx_packets, &n_rx_bytes);
280  bond_sw_if_idx_rewrite (vm, node, b[1], bond_sw_if_index,
281  &n_rx_packets, &n_rx_bytes);
282  bond_sw_if_idx_rewrite (vm, node, b[2], bond_sw_if_index,
283  &n_rx_packets, &n_rx_bytes);
284  bond_sw_if_idx_rewrite (vm, node, b[3], bond_sw_if_index,
285  &n_rx_packets, &n_rx_bytes);
286  }
287  }
288  else
289  {
290  bond_update_next (vm, node, &last_slave_sw_if_index, sw_if_index[0],
291  &bond_sw_if_index, b[0], &next_index, &error);
292  next[0] = next_index;
293  if (next_index == BOND_INPUT_NEXT_DROP)
294  b[0]->error = error;
295  else
296  bond_sw_if_idx_rewrite (vm, node, b[0], bond_sw_if_index,
297  &n_rx_packets, &n_rx_bytes);
298 
299  bond_update_next (vm, node, &last_slave_sw_if_index, sw_if_index[1],
300  &bond_sw_if_index, b[1], &next_index, &error);
301  next[1] = next_index;
302  if (next_index == BOND_INPUT_NEXT_DROP)
303  b[1]->error = error;
304  else
305  bond_sw_if_idx_rewrite (vm, node, b[1], bond_sw_if_index,
306  &n_rx_packets, &n_rx_bytes);
307 
308  bond_update_next (vm, node, &last_slave_sw_if_index, sw_if_index[2],
309  &bond_sw_if_index, b[2], &next_index, &error);
310  next[2] = next_index;
311  if (next_index == BOND_INPUT_NEXT_DROP)
312  b[2]->error = error;
313  else
314  bond_sw_if_idx_rewrite (vm, node, b[2], bond_sw_if_index,
315  &n_rx_packets, &n_rx_bytes);
316 
317  bond_update_next (vm, node, &last_slave_sw_if_index, sw_if_index[3],
318  &bond_sw_if_index, b[3], &next_index, &error);
319  next[3] = next_index;
320  if (next_index == BOND_INPUT_NEXT_DROP)
321  b[3]->error = error;
322  else
323  bond_sw_if_idx_rewrite (vm, node, b[3], bond_sw_if_index,
324  &n_rx_packets, &n_rx_bytes);
325  }
326 
331 
332  /* next */
333  n_left -= 4;
334  b += 4;
335  sw_if_index += 4;
336  next += 4;
337  }
338 
339  while (n_left)
340  {
341  sw_if_index[0] = vnet_buffer (b[0])->sw_if_index[VLIB_RX];
342  bond_update_next (vm, node, &last_slave_sw_if_index, sw_if_index[0],
343  &bond_sw_if_index, b[0], &next_index, &error);
344  next[0] = next_index;
345  if (next_index == BOND_INPUT_NEXT_DROP)
346  b[0]->error = error;
347  else
348  bond_sw_if_idx_rewrite (vm, node, b[0], bond_sw_if_index,
349  &n_rx_packets, &n_rx_bytes);
350 
352 
353  /* next */
354  n_left -= 1;
355  b += 1;
356  sw_if_index += 1;
357  next += 1;
358  }
359 
360  if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)))
361  {
362  n_left = frame->n_vectors; /* number of packets to process */
363  b = bufs;
364  sw_if_index = sw_if_indices;
366 
367  while (n_left)
368  {
369  if (PREDICT_FALSE (b[0]->flags & VLIB_BUFFER_IS_TRACED))
370  {
371  t0 = vlib_add_trace (vm, node, b[0], sizeof (*t0));
372  t0->sw_if_index = sw_if_index[0];
374  sizeof (ethernet_header_t));
375  t0->bond_sw_if_index = vnet_buffer (b[0])->sw_if_index[VLIB_RX];
376  }
377  /* next */
378  n_left--;
379  b++;
380  sw_if_index++;
381  }
382  }
383 
384  /* increase rx counters */
387  VNET_INTERFACE_COUNTER_RX, thread_index, bond_sw_if_index, n_rx_packets,
388  n_rx_bytes);
389 
390  vlib_buffer_enqueue_to_next (vm, node, from, nexts, frame->n_vectors);
392  BOND_INPUT_ERROR_NONE, frame->n_vectors);
393 
394  return frame->n_vectors;
395 }
396 
397 static clib_error_t *
399 {
400  return 0;
401 }
402 
403 /* *INDENT-OFF* */
405  .name = "bond-input",
406  .vector_size = sizeof (u32),
407  .format_buffer = format_ethernet_header_with_length,
408  .format_trace = format_bond_input_trace,
410  .n_errors = BOND_INPUT_N_ERROR,
411  .error_strings = bond_input_error_strings,
412  .n_next_nodes = BOND_INPUT_N_NEXT,
413  .next_nodes =
414  {
415  [BOND_INPUT_NEXT_DROP] = "error-drop"
416  }
417 };
418 
420 
421 VNET_FEATURE_INIT (bond_input, static) =
422 {
423  .arc_name = "device-input",
424  .node_name = "bond-input",
425  .runs_before = VNET_FEATURES ("ethernet-input"),
426 };
427 /* *INDENT-ON* */
428 
429 static clib_error_t *
431 {
432  bond_main_t *bm = &bond_main;
433  slave_if_t *sif;
434  vlib_main_t *vm = bm->vlib_main;
435 
436  sif = bond_get_slave_by_sw_if_index (sw_if_index);
437  if (sif)
438  {
439  if (sif->lacp_enabled)
440  return 0;
441 
442  /* port_enabled is both admin up and hw link up */
443  sif->port_enabled = ((flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) &&
444  vnet_sw_interface_is_link_up (vnm, sw_if_index));
445  if (sif->port_enabled == 0)
447  else
449  }
450 
451  return 0;
452 }
453 
455 
456 static clib_error_t *
458 {
459  bond_main_t *bm = &bond_main;
460  slave_if_t *sif;
462  vlib_main_t *vm = bm->vlib_main;
463 
464  sw = vnet_get_hw_sw_interface (vnm, hw_if_index);
466  if (sif)
467  {
468  if (sif->lacp_enabled)
469  return 0;
470 
471  /* port_enabled is both admin up and hw link up */
472  sif->port_enabled = ((flags & VNET_HW_INTERFACE_FLAG_LINK_UP) &&
474  sw->sw_if_index));
475  if (sif->port_enabled == 0)
477  else
479  }
480 
481  return 0;
482 }
483 
485 
486 /*
487  * fd.io coding-style-patch-verification: ON
488  *
489  * Local Variables:
490  * eval: (c-set-style "gnu")
491  * End:
492  */
#define foreach_bond_input_error
Definition: node.c:28
VNET_SW_INTERFACE_ADMIN_UP_DOWN_FUNCTION(bond_sw_interface_up_down)
#define CLIB_UNUSED(x)
Definition: clib.h:82
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:220
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
VNET_FEATURE_INIT(lb_nat4_in2out_node_fn, static)
static clib_error_t * bond_input_init(vlib_main_t *vm)
Definition: node.c:398
vnet_interface_main_t interface_main
Definition: vnet.h:56
#define PREDICT_TRUE(x)
Definition: clib.h:112
static void vlib_error_count(vlib_main_t *vm, uword node_index, uword counter, uword increment)
Definition: error_funcs.h:57
#define clib_memcpy_fast(a, b, c)
Definition: string.h:81
u8 src_address[6]
Definition: packet.h:56
u32 thread_index
Definition: main.h:218
u8 src_sap
Definition: llc.h:82
u16 current_length
Nbytes between current data and the end of this buffer.
Definition: buffer.h:113
u16 vlib_error_t
Definition: error.h:43
bond_main_t bond_main
Definition: node.c:25
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
static_always_inline u32 vnet_get_feature_count(u8 arc, u32 sw_if_index)
Definition: feature.h:223
#define VLIB_NODE_FN(node)
Definition: node.h:202
bond_input_error_t
Definition: node.c:34
vlib_error_t * errors
Vector of errors for this node.
Definition: node.h:470
void bond_enable_collecting_distributing(vlib_main_t *vm, slave_if_t *sif)
Definition: cli.c:134
format_function_t format_vnet_sw_if_index_name
static uword vnet_sw_interface_is_link_up(vnet_main_t *vnm, u32 sw_if_index)
unsigned char u8
Definition: types.h:56
static vnet_sw_interface_t * vnet_get_hw_sw_interface(vnet_main_t *vnm, u32 hw_if_index)
VNET_HW_INTERFACE_LINK_UP_DOWN_FUNCTION(bond_hw_interface_up_down)
vlib_node_registration_t bond_input_node
(constructor) VLIB_REGISTER_NODE (bond_input_node)
Definition: node.c:404
#define static_always_inline
Definition: clib.h:99
u8 * format_ethernet_address(u8 *s, va_list *args)
Definition: format.c:44
static void bond_update_next(vlib_main_t *vm, vlib_node_runtime_t *node, u32 *last_slave_sw_if_index, u32 slave_sw_if_index, u32 *bond_sw_if_index, vlib_buffer_t *b, u32 *next_index, vlib_error_t *error)
Definition: node.c:138
vl_api_interface_index_t sw_if_index
Definition: gre.api:59
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
vlib_combined_counter_main_t * combined_sw_if_counters
Definition: interface.h:863
u8 dst_address[6]
Definition: packet.h:55
u32 sw_if_index
Definition: node.h:184
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
Definition: buffer.h:203
bond_output_next_t
Definition: node.c:66
vlib_main_t * vlib_main
Definition: node.h:376
static_always_inline void bond_update_next_x4(vlib_buffer_t *b0, vlib_buffer_t *b1, vlib_buffer_t *b2, vlib_buffer_t *b3)
Definition: node.c:184
unsigned int u32
Definition: types.h:88
#define VLIB_FRAME_SIZE
Definition: node.h:378
static clib_error_t * bond_sw_interface_up_down(vnet_main_t *vnm, u32 sw_if_index, u32 flags)
Definition: node.c:430
static void bond_sw_if_idx_rewrite(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_buffer_t *b, u32 bond_sw_if_index, u32 *n_rx_packets, u32 *n_rx_bytes)
Definition: node.c:89
vl_api_fib_path_type_t type
Definition: fib_types.api:123
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:136
u8 admin_up
Definition: node.h:170
unsigned short u16
Definition: types.h:57
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:229
#define PREDICT_FALSE(x)
Definition: clib.h:111
vnet_main_t vnet_main
Definition: misc.c:43
u32 node_index
Node index.
Definition: node.h:496
static u8 * format_bond_input_trace(u8 *s, va_list *args)
Definition: node.c:49
vlib_main_t * vm
Definition: in2out_ed.c:1810
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
Definition: node_funcs.h:1150
u8 * format_ethernet_header_with_length(u8 *s, va_list *args)
Definition: format.c:97
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
u32 flags
Definition: vhost_user.h:141
u32 * slaves
Definition: node.h:187
u8 mode
Definition: node.h:171
static_always_inline void vlib_buffer_enqueue_to_next(vlib_main_t *vm, vlib_node_runtime_t *node, u32 *buffers, u16 *nexts, uword count)
Definition: buffer_node.h:332
static_always_inline void vnet_feature_next(u32 *next0, vlib_buffer_t *b0)
Definition: feature.h:302
ethernet_header_t ethernet
Definition: node.h:394
void bond_disable_collecting_distributing(vlib_main_t *vm, slave_if_t *sif)
Definition: cli.c:26
#define vlib_prefetch_buffer_data(b, type)
Definition: buffer.h:204
vlib_main_t vlib_node_runtime_t * node
Definition: in2out_ed.c:1810
#define ASSERT(truth)
static_always_inline u8 packet_is_cdp(ethernet_header_t *eth)
Definition: node.c:73
static bond_if_t * bond_get_master_by_dev_instance(u32 dev_instance)
Definition: node.h:516
u32 bif_dev_instance
Definition: node.h:323
static_always_inline int ethernet_frame_is_tagged(u16 type)
Definition: ethernet.h:78
u32 * active_slaves
Definition: node.h:190
#define clib_mem_unaligned(pointer, type)
Definition: types.h:155
u8 control
Definition: llc.h:87
static char * bond_input_error_strings[]
Definition: node.c:42
#define VNET_FEATURES(...)
Definition: feature.h:442
static uword vnet_sw_interface_is_admin_up(vnet_main_t *vnm, u32 sw_if_index)
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
u8 lacp_enabled
Definition: node.h:271
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
#define VLIB_BUFFER_TRACE_TRAJECTORY_INIT(b)
Definition: buffer.h:492
VLIB buffer representation.
Definition: buffer.h:102
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:244
static clib_error_t * bond_hw_interface_up_down(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
Definition: node.c:457
#define vnet_buffer(b)
Definition: buffer.h:408
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
Definition: in2out_ed.c:1811
u8 port_enabled
Definition: node.h:265
static slave_if_t * bond_get_slave_by_sw_if_index(u32 sw_if_index)
Definition: node.h:524
static_always_inline void vlib_get_buffers(vlib_main_t *vm, u32 *bi, vlib_buffer_t **b, int count)
Translate array of buffer indices into buffer pointers.
Definition: buffer_funcs.h:244
#define VLIB_NODE_FLAG_TRACE
Definition: node.h:302
u32 bond_sw_if_index
Definition: node.h:396
Definition: defs.h:46