FD.io VPP  v21.06-3-gbb25fbf28
Vector Packet Processing
arp.c
Go to the documentation of this file.
1 /*
2  * ethernet/arp.c: IP v4 ARP node
3  *
4  * Copyright (c) 2010 Cisco and/or its affiliates.
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include <vnet/arp/arp.h>
19 #include <vnet/arp/arp_packet.h>
20 
21 #include <vnet/fib/ip4_fib.h>
22 #include <vnet/fib/fib_entry_src.h>
23 #include <vnet/adj/adj_nbr.h>
24 #include <vnet/adj/adj_mcast.h>
25 
28 
29 #include <vlibmemory/api.h>
30 
31 /**
32  * @file
33  * @brief IPv4 ARP.
34  *
35  * This file contains code to manage the IPv4 ARP tables (IP Address
36  * to MAC Address lookup).
37  */
38 
39 /**
40  * @brief Per-interface ARP configuration and state
41  */
43 {
44  /**
45  * Is ARP enabled on this interface
46  */
49 
50 typedef struct
51 {
52  /* Hash tables mapping name to opcode. */
54 
55  /** Per interface state */
57 
58  /* ARP feature arc index */
61 
63 
64 static const u8 vrrp_prefix[] = { 0x00, 0x00, 0x5E, 0x00, 0x01 };
65 
66 static uword
68  va_list * args)
69 {
70  int *result = va_arg (*args, int *);
72  int x, i;
73 
74  /* Numeric opcode. */
75  if (unformat (input, "0x%x", &x) || unformat (input, "%d", &x))
76  {
77  if (x >= (1 << 16))
78  return 0;
79  *result = x;
80  return 1;
81  }
82 
83  /* Named type. */
85  am->opcode_by_name, &i))
86  {
87  *result = i;
88  return 1;
89  }
90 
91  return 0;
92 }
93 
94 static uword
96  va_list * args)
97 {
98  int *result = va_arg (*args, int *);
99  if (!unformat_user
101  return 0;
102 
103  *result = clib_host_to_net_u16 ((u16) * result);
104  return 1;
105 }
106 
107 typedef struct
108 {
109  u8 packet_data[64];
111 
112 static u8 *
114 {
115  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*va, vlib_main_t *);
116  CLIB_UNUSED (vlib_node_t * node) = va_arg (*va, vlib_node_t *);
118 
119  s = format (s, "%U",
121  t->packet_data, sizeof (t->packet_data));
122 
123  return s;
124 }
125 
126 static int
128 {
129  if (vec_len (am->ethernet_arp_by_sw_if_index) <= sw_if_index)
130  return 0;
131 
132  return (am->ethernet_arp_by_sw_if_index[sw_if_index].enabled);
133 }
134 
135 static void
137 {
139  return;
140 
141  vec_validate (am->ethernet_arp_by_sw_if_index, sw_if_index);
142 
143  am->ethernet_arp_by_sw_if_index[sw_if_index].enabled = 1;
144 
145  vnet_feature_enable_disable ("arp", "arp-reply", sw_if_index, 1, NULL, 0);
146  vnet_feature_enable_disable ("arp", "arp-disabled", sw_if_index, 0, NULL,
147  0);
148 }
149 
150 static void
152 {
153  if (!arp_is_enabled (am, sw_if_index))
154  return;
155 
156  vnet_feature_enable_disable ("arp", "arp-disabled", sw_if_index, 1, NULL,
157  0);
158  vnet_feature_enable_disable ("arp", "arp-reply", sw_if_index, 0, NULL, 0);
159 
160  am->ethernet_arp_by_sw_if_index[sw_if_index].enabled = 0;
161 }
162 
163 static int
165  u32 input_sw_if_index, u32 conn_sw_if_index)
166 {
167  vnet_main_t *vnm = vnet_get_main ();
170 
171  /* verify that the input interface is unnumbered to the connected.
172  * the connected interface is the interface on which the subnet is
173  * configured */
174  si = &vim->sw_interfaces[input_sw_if_index];
175 
177  (si->unnumbered_sw_if_index == conn_sw_if_index)))
178  {
179  /* the input interface is not unnumbered to the interface on which
180  * the sub-net is configured that covers the ARP request.
181  * So this is not the case for unnumbered.. */
182  return 0;
183  }
184 
185  return !0;
186 }
187 
190  const ethernet_arp_ip4_over_ethernet_address_t * addr)
191 {
192  /* *INDENT-OFF* */
193  ip_neighbor_learn_t l = {
194  .ip = {
195  .ip.ip4 = addr->ip4,
196  .version = AF_IP4,
197  },
198  .mac = addr->mac,
199  .sw_if_index = sw_if_index,
200  };
201  /* *INDENT-ON* */
202 
204 
205  return (ETHERNET_ARP_ERROR_l3_src_address_learned);
206 }
207 
208 typedef enum arp_input_next_t_
209 {
214 
215 static uword
217 {
218  u32 n_left_from, next_index, *from, *to_next, n_left_to_next;
220 
222  n_left_from = frame->n_vectors;
223  next_index = node->cached_next_index;
224 
225  if (node->flags & VLIB_NODE_FLAG_TRACE)
227  /* stride */ 1,
228  sizeof (ethernet_arp_input_trace_t));
229 
230  while (n_left_from > 0)
231  {
232  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
233 
234  while (n_left_from > 0 && n_left_to_next > 0)
235  {
236  const ethernet_arp_header_t *arp0;
237  arp_input_next_t next0;
238  vlib_buffer_t *p0;
239  u32 pi0, error0;
240 
241  pi0 = to_next[0] = from[0];
242  from += 1;
243  to_next += 1;
244  n_left_from -= 1;
245  n_left_to_next -= 1;
246 
247  p0 = vlib_get_buffer (vm, pi0);
248  arp0 = vlib_buffer_get_current (p0);
249 
250  error0 = ETHERNET_ARP_ERROR_replies_sent;
251  next0 = ARP_INPUT_NEXT_DROP;
252 
253  error0 =
254  (arp0->l2_type !=
255  clib_net_to_host_u16 (ETHERNET_ARP_HARDWARE_TYPE_ethernet) ?
256  ETHERNET_ARP_ERROR_l2_type_not_ethernet : error0);
257  error0 =
258  (arp0->l3_type !=
259  clib_net_to_host_u16 (ETHERNET_TYPE_IP4) ?
260  ETHERNET_ARP_ERROR_l3_type_not_ip4 : error0);
261  error0 =
262  (0 == arp0->ip4_over_ethernet[0].ip4.as_u32 ?
263  ETHERNET_ARP_ERROR_l3_dst_address_unset : error0);
264 
265  if (ETHERNET_ARP_ERROR_replies_sent == error0)
266  {
267  next0 = ARP_INPUT_NEXT_DISABLED;
268  vnet_feature_arc_start (am->feature_arc_index,
270  &next0, p0);
271  }
272  else
273  p0->error = node->errors[error0];
274 
276  n_left_to_next, pi0, next0);
277  }
278 
279  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
280  }
281 
282  return frame->n_vectors;
283 }
284 
286 {
290 
291 #define foreach_arp_disabled_error \
292  _ (DISABLED, "ARP Disabled on this interface") \
293 
294 typedef enum
295 {
296 #define _(sym,string) ARP_DISABLED_ERROR_##sym,
298 #undef _
301 
302 static char *arp_disabled_error_strings[] = {
303 #define _(sym,string) string,
305 #undef _
306 };
307 
308 static uword
311 {
312  u32 n_left_from, next_index, *from, *to_next, n_left_to_next;
313 
315  n_left_from = frame->n_vectors;
316  next_index = node->cached_next_index;
317 
318  if (node->flags & VLIB_NODE_FLAG_TRACE)
320  /* stride */ 1,
321  sizeof (ethernet_arp_input_trace_t));
322 
323  while (n_left_from > 0)
324  {
325  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
326 
327  while (n_left_from > 0 && n_left_to_next > 0)
328  {
330  vlib_buffer_t *p0;
331  u32 pi0, error0;
332 
333  next0 = ARP_DISABLED_NEXT_DROP;
334  error0 = ARP_DISABLED_ERROR_DISABLED;
335 
336  pi0 = to_next[0] = from[0];
337  from += 1;
338  to_next += 1;
339  n_left_from -= 1;
340  n_left_to_next -= 1;
341 
342  p0 = vlib_get_buffer (vm, pi0);
343  p0->error = node->errors[error0];
344 
346  n_left_to_next, pi0, next0);
347  }
348 
349  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
350  }
351 
352  return frame->n_vectors;
353 }
354 
356 {
360 };
361 
362 /*
363  * we're looking for FIB sources that indicate the destination
364  * is attached. There may be interposed DPO prior to the one
365  * we are looking for
366  */
367 static enum arp_dst_fib_type
369 {
370  const fib_entry_t *entry = fib_entry_get (fei);
371  const fib_entry_src_t *entry_src;
373  /* *INDENT-OFF* */
374  FOR_EACH_SRC_ADDED(entry, entry_src, src,
375  ({
378  return ARP_DST_FIB_ADJ;
379  else if (FIB_ENTRY_FLAG_CONNECTED & *flags)
380  return ARP_DST_FIB_CONN;
381  }))
382  /* *INDENT-ON* */
383 
384  return ARP_DST_FIB_NONE;
385 }
386 
387 static uword
389 {
390  vnet_main_t *vnm = vnet_get_main ();
391  u32 n_left_from, next_index, *from, *to_next;
392  u32 n_replies_sent = 0;
393 
395  n_left_from = frame->n_vectors;
396  next_index = node->cached_next_index;
397 
398  if (node->flags & VLIB_NODE_FLAG_TRACE)
400  /* stride */ 1,
401  sizeof (ethernet_arp_input_trace_t));
402 
403  while (n_left_from > 0)
404  {
405  u32 n_left_to_next;
406 
407  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
408 
409  while (n_left_from > 0 && n_left_to_next > 0)
410  {
411  vlib_buffer_t *p0;
412  ethernet_arp_header_t *arp0;
413  ethernet_header_t *eth_rx;
414  const ip4_address_t *if_addr0;
415  u32 pi0, error0, next0, sw_if_index0, conn_sw_if_index0, fib_index0;
416  u8 dst_is_local0, is_vrrp_reply0;
417  fib_node_index_t dst_fei, src_fei;
418  const fib_prefix_t *pfx0;
419  fib_entry_flag_t src_flags, dst_flags;
420 
421  pi0 = from[0];
422  to_next[0] = pi0;
423  from += 1;
424  to_next += 1;
425  n_left_from -= 1;
426  n_left_to_next -= 1;
427 
428  p0 = vlib_get_buffer (vm, pi0);
429  arp0 = vlib_buffer_get_current (p0);
430  /* Fill in ethernet header. */
431  eth_rx = ethernet_buffer_get_header (p0);
432 
433  next0 = ARP_REPLY_NEXT_DROP;
434  error0 = ETHERNET_ARP_ERROR_replies_sent;
435  sw_if_index0 = vnet_buffer (p0)->sw_if_index[VLIB_RX];
436 
437  /* Check that IP address is local and matches incoming interface. */
438  fib_index0 = ip4_fib_table_get_index_for_sw_if_index (sw_if_index0);
439  if (~0 == fib_index0)
440  {
441  error0 = ETHERNET_ARP_ERROR_interface_no_table;
442  goto drop;
443 
444  }
445 
446  {
447  /*
448  * we're looking for FIB entries that indicate the source
449  * is attached. There may be more specific non-attached
450  * routes that match the source, but these do not influence
451  * whether we respond to an ARP request, i.e. they do not
452  * influence whether we are the correct way for the sender
453  * to reach us, they only affect how we reach the sender.
454  */
455  fib_entry_t *src_fib_entry;
456  const fib_prefix_t *pfx;
458  fib_source_t source;
459  int attached;
460  int mask;
461 
462  mask = 32;
463  attached = 0;
464 
465  do
466  {
467  src_fei = ip4_fib_table_lookup (ip4_fib_get (fib_index0),
468  &arp0->
469  ip4_over_ethernet[0].ip4,
470  mask);
471  src_fib_entry = fib_entry_get (src_fei);
472 
473  /*
474  * It's possible that the source that provides the
475  * flags we need, or the flags we must not have,
476  * is not the best source, so check then all.
477  */
478  /* *INDENT-OFF* */
479  FOR_EACH_SRC_ADDED(src_fib_entry, src, source,
480  ({
481  src_flags = fib_entry_get_flags_for_source (src_fei, source);
482 
483  /* Reject requests/replies with our local interface
484  address. */
485  if (FIB_ENTRY_FLAG_LOCAL & src_flags)
486  {
487  error0 = ETHERNET_ARP_ERROR_l3_src_address_is_local;
488  /*
489  * When VPP has an interface whose address is also
490  * applied to a TAP interface on the host, then VPP's
491  * TAP interface will be unnumbered to the 'real'
492  * interface and do proxy ARP from the host.
493  * The curious aspect of this setup is that ARP requests
494  * from the host will come from the VPP's own address.
495  * So don't drop immediately here, instead go see if this
496  * is a proxy ARP case.
497  */
498  goto next_feature;
499  }
500  /* A Source must also be local to subnet of matching
501  * interface address. */
502  if ((FIB_ENTRY_FLAG_ATTACHED & src_flags) ||
503  (FIB_ENTRY_FLAG_CONNECTED & src_flags))
504  {
505  attached = 1;
506  break;
507  }
508  /*
509  * else
510  * The packet was sent from an address that is not
511  * connected nor attached i.e. it is not from an
512  * address that is covered by a link's sub-net,
513  * nor is it a already learned host resp.
514  */
515  }));
516  /* *INDENT-ON* */
517 
518  /*
519  * shorter mask lookup for the next iteration.
520  */
521  pfx = fib_entry_get_prefix (src_fei);
522  mask = pfx->fp_len - 1;
523 
524  /*
525  * continue until we hit the default route or we find
526  * the attached we are looking for. The most likely
527  * outcome is we find the attached with the first source
528  * on the first lookup.
529  */
530  }
531  while (!attached &&
533 
534  if (!attached)
535  {
536  /*
537  * the matching route is a not attached, i.e. it was
538  * added as a result of routing, rather than interface/ARP
539  * configuration. If the matching route is not a host route
540  * (i.e. a /32)
541  */
542  error0 = ETHERNET_ARP_ERROR_l3_src_address_not_local;
543  goto drop;
544  }
545  }
546 
547  dst_fei = ip4_fib_table_lookup (ip4_fib_get (fib_index0),
548  &arp0->ip4_over_ethernet[1].ip4,
549  32);
550  conn_sw_if_index0 = fib_entry_get_any_resolving_interface (dst_fei);
551 
552  switch (arp_dst_fib_check (dst_fei, &dst_flags))
553  {
554  case ARP_DST_FIB_ADJ:
555  /*
556  * We matched an adj-fib on ths source subnet (a /32 previously
557  * added as a result of ARP). If this request is a gratuitous
558  * ARP, then learn from it.
559  * The check for matching an adj-fib, is to prevent hosts
560  * from spamming us with gratuitous ARPS that might otherwise
561  * blow our ARP cache
562  */
563  if (conn_sw_if_index0 != sw_if_index0)
564  error0 = ETHERNET_ARP_ERROR_l3_dst_address_not_local;
565  else if (arp0->ip4_over_ethernet[0].ip4.as_u32 ==
566  arp0->ip4_over_ethernet[1].ip4.as_u32)
567  error0 = arp_learn (sw_if_index0,
568  &arp0->ip4_over_ethernet[0]);
569  goto drop;
570  case ARP_DST_FIB_CONN:
571  /* destination is connected, continue to process */
572  break;
573  case ARP_DST_FIB_NONE:
574  /* destination is not connected, stop here */
575  error0 = ETHERNET_ARP_ERROR_l3_dst_address_not_local;
576  goto next_feature;
577  }
578 
579  dst_is_local0 = (FIB_ENTRY_FLAG_LOCAL & dst_flags);
580  pfx0 = fib_entry_get_prefix (dst_fei);
581  if_addr0 = &pfx0->fp_addr.ip4;
582 
583  is_vrrp_reply0 =
584  ((arp0->opcode ==
585  clib_host_to_net_u16 (ETHERNET_ARP_OPCODE_reply))
586  &&
587  (!memcmp
588  (arp0->ip4_over_ethernet[0].mac.bytes, vrrp_prefix,
589  sizeof (vrrp_prefix))));
590 
591  /* Trash ARP packets whose ARP-level source addresses do not
592  match their L2-frame-level source addresses, unless it's
593  a reply from a VRRP virtual router */
595  (eth_rx->src_address,
596  arp0->ip4_over_ethernet[0].mac.bytes) && !is_vrrp_reply0)
597  {
598  error0 = ETHERNET_ARP_ERROR_l2_address_mismatch;
599  goto drop;
600  }
601 
602  /* Learn or update sender's mapping only for replies to addresses
603  * that are local to the subnet */
604  if (arp0->opcode ==
605  clib_host_to_net_u16 (ETHERNET_ARP_OPCODE_reply))
606  {
607  if (dst_is_local0)
608  error0 =
609  arp_learn (sw_if_index0, &arp0->ip4_over_ethernet[0]);
610  else
611  /* a reply for a non-local destination could be a GARP.
612  * GARPs for hosts we know were handled above, so this one
613  * we drop */
614  error0 = ETHERNET_ARP_ERROR_l3_dst_address_not_local;
615 
616  goto next_feature;
617  }
618  else if (arp0->opcode ==
619  clib_host_to_net_u16 (ETHERNET_ARP_OPCODE_request) &&
620  (dst_is_local0 == 0))
621  {
622  goto next_feature;
623  }
624 
625  /* Honor unnumbered interface, if any */
626  if (sw_if_index0 != conn_sw_if_index0 ||
627  sw_if_index0 != fib_entry_get_resolving_interface (src_fei))
628  {
629  /*
630  * The interface the ARP is sent to or was received on is not the
631  * interface on which the covering prefix is configured.
632  * Maybe this is a case for unnumbered.
633  */
634  if (!arp_unnumbered (p0, sw_if_index0, conn_sw_if_index0))
635  {
636  error0 = ETHERNET_ARP_ERROR_unnumbered_mismatch;
637  goto drop;
638  }
639  }
640  if (arp0->ip4_over_ethernet[0].ip4.as_u32 ==
641  arp0->ip4_over_ethernet[1].ip4.as_u32)
642  {
643  error0 = ETHERNET_ARP_ERROR_gratuitous_arp;
644  goto drop;
645  }
646 
647  next0 = arp_mk_reply (vnm, p0, sw_if_index0,
648  if_addr0, arp0, eth_rx);
649 
650  /* We are going to reply to this request, so, in the absence of
651  errors, learn the sender */
652  if (!error0)
653  error0 = arp_learn (sw_if_index0, &arp0->ip4_over_ethernet[1]);
654 
655  n_replies_sent += 1;
656  goto enqueue;
657 
658  next_feature:
659  vnet_feature_next (&next0, p0);
660  goto enqueue;
661 
662  drop:
663  p0->error = node->errors[error0];
664 
665  enqueue:
667  n_left_to_next, pi0, next0);
668  }
669 
670  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
671  }
672 
673  vlib_error_count (vm, node->node_index,
674  ETHERNET_ARP_ERROR_replies_sent, n_replies_sent);
675 
676  return frame->n_vectors;
677 }
678 
679 
680 static char *ethernet_arp_error_strings[] = {
681 #define _(sym,string) string,
683 #undef _
684 };
685 
686 /* *INDENT-OFF* */
687 
689 {
690  .function = arp_input,
691  .name = "arp-input",
692  .vector_size = sizeof (u32),
693  .n_errors = ETHERNET_ARP_N_ERROR,
694  .error_strings = ethernet_arp_error_strings,
695  .n_next_nodes = ARP_INPUT_N_NEXT,
696  .next_nodes = {
697  [ARP_INPUT_NEXT_DROP] = "error-drop",
698  [ARP_INPUT_NEXT_DISABLED] = "arp-disabled",
699  },
700  .format_buffer = format_ethernet_arp_header,
701  .format_trace = format_ethernet_arp_input_trace,
702 };
703 
705 {
706  .function = arp_disabled,
707  .name = "arp-disabled",
708  .vector_size = sizeof (u32),
709  .n_errors = ARP_DISABLED_N_ERROR,
710  .error_strings = arp_disabled_error_strings,
711  .n_next_nodes = ARP_DISABLED_N_NEXT,
712  .next_nodes = {
713  [ARP_INPUT_NEXT_DROP] = "error-drop",
714  },
715  .format_buffer = format_ethernet_arp_header,
716  .format_trace = format_ethernet_arp_input_trace,
717 };
718 
720 {
721  .function = arp_reply,
722  .name = "arp-reply",
723  .vector_size = sizeof (u32),
724  .n_errors = ETHERNET_ARP_N_ERROR,
725  .error_strings = ethernet_arp_error_strings,
726  .n_next_nodes = ARP_REPLY_N_NEXT,
727  .next_nodes = {
728  [ARP_REPLY_NEXT_DROP] = "error-drop",
729  [ARP_REPLY_NEXT_REPLY_TX] = "interface-output",
730  },
731  .format_buffer = format_ethernet_arp_header,
732  .format_trace = format_ethernet_arp_input_trace,
733 };
734 
735 /* Built-in ARP rx feature path definition */
736 VNET_FEATURE_ARC_INIT (arp_feat, static) =
737 {
738  .arc_name = "arp",
739  .start_nodes = VNET_FEATURES ("arp-input"),
740  .last_in_arc = "error-drop",
741  .arc_index_ptr = &ethernet_arp_main.feature_arc_index,
742 };
743 
744 VNET_FEATURE_INIT (arp_reply_feat_node, static) =
745 {
746  .arc_name = "arp",
747  .node_name = "arp-reply",
748  .runs_before = VNET_FEATURES ("arp-disabled"),
749 };
750 
751 VNET_FEATURE_INIT (arp_proxy_feat_node, static) =
752 {
753  .arc_name = "arp",
754  .node_name = "arp-proxy",
755  .runs_after = VNET_FEATURES ("arp-reply"),
756  .runs_before = VNET_FEATURES ("arp-disabled"),
757 };
758 
759 VNET_FEATURE_INIT (arp_disabled_feat_node, static) =
760 {
761  .arc_name = "arp",
762  .node_name = "arp-disabled",
763  .runs_before = VNET_FEATURES ("error-drop"),
764 };
765 
766 VNET_FEATURE_INIT (arp_drop_feat_node, static) =
767 {
768  .arc_name = "arp",
769  .node_name = "error-drop",
770  .runs_before = 0, /* last feature */
771 };
772 
773 /* *INDENT-ON* */
774 
775 typedef struct
776 {
777  pg_edit_t l2_type, l3_type;
778  pg_edit_t n_l2_address_bytes, n_l3_address_bytes;
780  struct
781  {
784  } ip4_over_ethernet[2];
786 
787 static inline void
789 {
790  /* Initialize fields that are not bit fields in the IP header. */
791 #define _(f) pg_edit_init (&p->f, ethernet_arp_header_t, f);
792  _(l2_type);
793  _(l3_type);
794  _(n_l2_address_bytes);
795  _(n_l3_address_bytes);
796  _(opcode);
797  _(ip4_over_ethernet[0].mac);
798  _(ip4_over_ethernet[0].ip4);
799  _(ip4_over_ethernet[1].mac);
800  _(ip4_over_ethernet[1].ip4);
801 #undef _
802 }
803 
804 uword
805 unformat_pg_arp_header (unformat_input_t * input, va_list * args)
806 {
807  pg_stream_t *s = va_arg (*args, pg_stream_t *);
809  u32 group_index;
810 
811  p = pg_create_edit_group (s, sizeof (p[0]), sizeof (ethernet_arp_header_t),
812  &group_index);
814 
815  /* Defaults. */
816  pg_edit_set_fixed (&p->l2_type, ETHERNET_ARP_HARDWARE_TYPE_ethernet);
817  pg_edit_set_fixed (&p->l3_type, ETHERNET_TYPE_IP4);
820 
821  if (!unformat (input, "%U: %U/%U -> %U/%U",
832  {
833  /* Free up any edits we may have added. */
834  pg_free_edit_group (s);
835  return 0;
836  }
837  return 1;
838 }
839 
840 /*
841  * callback when an interface address is added or deleted
842  */
843 static void
845  uword opaque, u32 sw_if_index, u32 is_enable)
846 {
848 
849  if (is_enable)
851  else
853 }
854 
855 /*
856  * Remove any arp entries associated with the specified interface
857  */
858 static clib_error_t *
860 {
862  if (is_add)
864  return (NULL);
865 }
866 
868 
869 const static ip_neighbor_vft_t arp_vft = {
871  .inv_proxy4_del = arp_proxy_del,
872  .inv_proxy4_enable = arp_proxy_disable,
873  .inv_proxy4_disable = arp_proxy_disable,
874 };
875 
876 static clib_error_t *
878 {
880  ip4_main_t *im = &ip4_main;
881  pg_node_t *pn;
882 
883  ethernet_register_input_type (vm, ETHERNET_TYPE_ARP, arp_input_node.index);
884 
885  pn = pg_get_node (arp_input_node.index);
887 
888  am->opcode_by_name = hash_create_string (0, sizeof (uword));
889 #define _(o) hash_set_mem (am->opcode_by_name, #o, ETHERNET_ARP_OPCODE_##o);
891 #undef _
892 
893  /* don't trace ARP error packets */
894  {
897 
898 #define _(a,b) \
899  vnet_pcap_drop_trace_filter_add_del \
900  (rt->errors[ETHERNET_ARP_ERROR_##a], \
901  1 /* is_add */);
903 #undef _
904  }
905 
906  {
909  };
910  vec_add1 (im->enable_disable_interface_callbacks, cb);
911  }
912 
914 
915  return 0;
916 }
917 
918 /* *INDENT-OFF* */
920 {
921  .runs_after = VLIB_INITS("ethernet_init",
922  "ip_neighbor_init"),
923 };
924 /* *INDENT-ON* */
925 
926 /*
927  * fd.io coding-style-patch-verification: ON
928  *
929  * Local Variables:
930  * eval: (c-set-style "gnu")
931  * End:
932  */
arp_reply_node
static vlib_node_registration_t arp_reply_node
(constructor) VLIB_REGISTER_NODE (arp_reply_node)
Definition: arp.c:719
ethernet_arp_main_t
Definition: arp.c:50
im
vnet_interface_main_t * im
Definition: interface_output.c:395
api.h
ARP_DST_FIB_ADJ
@ ARP_DST_FIB_ADJ
Definition: arp.c:358
pg_edit_set_fixed
static void pg_edit_set_fixed(pg_edit_t *e, u64 value)
Definition: edit.h:153
ethernet_arp_header_t::opcode
u16 opcode
Definition: arp_packet.h:139
arp_proxy_add
int arp_proxy_add(u32 fib_index, const ip4_address_t *lo_addr, const ip4_address_t *hi_addr)
Definition: arp_proxy.c:127
mac
vl_api_mac_address_t mac
Definition: l2.api:559
unformat_user
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:989
vnet_sw_interface_t
Definition: interface.h:868
frame
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame
Definition: nat44_ei.c:3048
pg_ethernet_arp_header_t::l2_type
pg_edit_t l2_type
Definition: arp.c:777
fib_entry_get_prefix
const fib_prefix_t * fib_entry_get_prefix(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1728
arp_proxy_del
int arp_proxy_del(u32 fib_index, const ip4_address_t *lo_addr, const ip4_address_t *hi_addr)
Definition: arp_proxy.c:134
ip4
vl_api_ip4_address_t ip4
Definition: one.api:376
ip_neighbor_vft_t_
Virtual function Table for neighbor protocol implementations to register.
Definition: ip_neighbor.h:101
next_index
nat44_ei_hairpin_src_next_t next_index
Definition: nat44_ei_hairpinning.c:412
fib_entry_t_
An entry in a FIB table.
Definition: fib_entry.h:305
ip4_main
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:1105
ethernet_arp_interface_t_
Per-interface ARP configuration and state.
Definition: arp.c:42
ip_neighbor_vft_t_::inv_proxy4_add
ip4_neighbor_proxy_addr_t inv_proxy4_add
Definition: ip_neighbor.h:105
vlib_get_buffer
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:111
arp_input_next_t
enum arp_input_next_t_ arp_input_next_t
VNET_FEATURE_ARC_INIT
VNET_FEATURE_ARC_INIT(arp_feat, static)
VNET_FEATURE_INIT
VNET_FEATURE_INIT(arp_reply_feat_node, static)
ethernet_header_t::src_address
u8 src_address[6]
Definition: packet.h:56
vlib_trace_frame_buffers_only
void vlib_trace_frame_buffers_only(vlib_main_t *vm, vlib_node_runtime_t *node, u32 *buffers, uword n_buffers, uword next_buffer_stride, uword n_buffer_data_bytes_in_trace)
Definition: trace.c:48
ethernet_arp_main_t::feature_arc_index
u8 feature_arc_index
Definition: arp.c:59
node
vlib_main_t vlib_node_runtime_t * node
Definition: nat44_ei.c:3047
arp_disable
static void arp_disable(ethernet_arp_main_t *am, u32 sw_if_index)
Definition: arp.c:151
adj_mcast.h
FIB_ENTRY_FLAG_ATTACHED
@ FIB_ENTRY_FLAG_ATTACHED
Definition: fib_entry.h:114
ethernet_arp_main
static ethernet_arp_main_t ethernet_arp_main
Definition: arp.c:62
fib_entry_src_t_
Information related to the source of a FIB entry.
Definition: fib_entry.h:197
vnet_interface_main_t
Definition: interface.h:989
ethernet_arp_header_t::ip4_over_ethernet
ethernet_arp_ip4_over_ethernet_address_t ip4_over_ethernet[2]
Definition: arp_packet.h:142
arp_input
static uword arp_input(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: arp.c:216
ip4_fib_table_get_index_for_sw_if_index
u32 ip4_fib_table_get_index_for_sw_if_index(u32 sw_if_index)
Definition: pnat_test_stubs.h:21
u16
unsigned short u16
Definition: types.h:57
am
app_main_t * am
Definition: application.c:489
fib_prefix_t_::fp_len
u16 fp_len
The mask length.
Definition: fib_types.h:206
unformat_pg_arp_header
uword unformat_pg_arp_header(unformat_input_t *input, va_list *args)
Definition: arp.c:805
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
arp_input_next_t_
arp_input_next_t_
Definition: arp.c:208
pg_ethernet_arp_header_t
Definition: arp.c:775
AF_IP4
@ AF_IP4
Definition: ip_types.h:23
ip_neighbor_learn_t_
Definition: ip_neighbor_types.h:97
hash_create_string
#define hash_create_string(elts, value_bytes)
Definition: hash.h:689
VLIB_RX
@ VLIB_RX
Definition: defs.h:46
arp_dst_fib_check
static enum arp_dst_fib_type arp_dst_fib_check(const fib_node_index_t fei, fib_entry_flag_t *flags)
Definition: arp.c:368
unformat_input_t
struct _unformat_input_t unformat_input_t
addr
vhost_vring_addr_t addr
Definition: vhost_user.h:130
pg_ethernet_arp_header_t::l3_type
pg_edit_t l3_type
Definition: arp.c:777
vlib_error_count
static void vlib_error_count(vlib_main_t *vm, uword node_index, uword counter, uword increment)
Definition: error_funcs.h:57
vlib_frame_t
Definition: node.h:372
ARP_REPLY_NEXT_DROP
@ ARP_REPLY_NEXT_DROP
Definition: arp_packet.h:26
arp_packet.h
foreach_ethernet_arp_error
#define foreach_ethernet_arp_error
Definition: arp.h:23
ARP_DISABLED_N_NEXT
@ ARP_DISABLED_N_NEXT
Definition: arp.c:288
VNET_SW_INTERFACE_ADD_DEL_FUNCTION
VNET_SW_INTERFACE_ADD_DEL_FUNCTION(vnet_arp_add_del_sw_interface)
vnet_sw_interface_t::flags
vnet_sw_interface_flags_t flags
Definition: interface.h:872
ethernet_arp_input_trace_t::packet_data
u8 packet_data[64]
Definition: arp.c:109
pg_node_t
Definition: pg.h:324
unformat
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
ethernet_mac_address_equal
static int ethernet_mac_address_equal(const u8 *a, const u8 *b)
Definition: mac_address.h:85
pg_ethernet_arp_header_t::ip4
pg_edit_t ip4
Definition: arp.c:783
ethernet_arp_header_t
Definition: arp_packet.h:133
unformat_ethernet_arp_opcode_host_byte_order
static uword unformat_ethernet_arp_opcode_host_byte_order(unformat_input_t *input, va_list *args)
Definition: arp.c:67
ethernet_arp_main_t::opcode_by_name
uword * opcode_by_name
Definition: arp.c:53
ARP_DISABLED_N_ERROR
@ ARP_DISABLED_N_ERROR
Definition: arp.c:299
FIB_SOURCE_ADJ
@ FIB_SOURCE_ADJ
Adjacency source.
Definition: fib_source.h:105
fib_entry_src.h
arp_vft
const static ip_neighbor_vft_t arp_vft
Definition: arp.c:869
fib_entry_flag_t
enum fib_entry_flag_t_ fib_entry_flag_t
vec_len
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
Definition: vec_bootstrap.h:142
vlib_buffer_t::error
vlib_error_t error
Error code for buffers to be enqueued to error handler.
Definition: buffer.h:145
vec_add1
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:606
pg_node_t::unformat_edit
unformat_function_t * unformat_edit
Definition: pg.h:327
CLIB_UNUSED
#define CLIB_UNUSED(x)
Definition: clib.h:90
vnet_buffer
#define vnet_buffer(b)
Definition: buffer.h:437
pg_ethernet_arp_header_t::n_l3_address_bytes
pg_edit_t n_l3_address_bytes
Definition: arp.c:778
vnet_get_main
vnet_main_t * vnet_get_main(void)
Definition: pnat_test_stubs.h:56
ARP_INPUT_NEXT_DROP
@ ARP_INPUT_NEXT_DROP
Definition: arp.c:210
VLIB_NODE_FLAG_TRACE
#define VLIB_NODE_FLAG_TRACE
Definition: node.h:291
ip_neighbor_learn_t_::ip
ip_address_t ip
Definition: ip_neighbor_types.h:99
arp_proxy_disable
int arp_proxy_disable(u32 sw_if_index)
Definition: arp_proxy.c:55
ip_neighbor_register
void ip_neighbor_register(ip_address_family_t af, const ip_neighbor_vft_t *vft)
Definition: ip_neighbor.c:1009
ethernet_arp_input_trace_t
Definition: arp.c:107
vnet_feature_next
static_always_inline void vnet_feature_next(u32 *next0, vlib_buffer_t *b0)
Definition: feature.h:322
vlib_frame_vector_args
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
Definition: node_funcs.h:301
pg_ethernet_arp_header_t::n_l2_address_bytes
pg_edit_t n_l2_address_bytes
Definition: arp.c:778
arp_dst_fib_type
arp_dst_fib_type
Definition: arp.c:355
ethernet_arp_main_t::ethernet_arp_by_sw_if_index
ethernet_arp_interface_t * ethernet_arp_by_sw_if_index
Per interface state.
Definition: arp.c:56
fib_node_index_t
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:29
uword
u64 uword
Definition: types.h:112
pg_get_node
static pg_node_t * pg_get_node(uword node_index)
Definition: pg.h:381
ethernet_header_t
Definition: packet.h:52
pg_ethernet_arp_header_t::mac
pg_edit_t mac
Definition: arp.c:782
arp_disabled_error_strings
static char * arp_disabled_error_strings[]
Definition: arp.c:302
ip4_enable_disable_interface_callback_t
Definition: ip4.h:82
arp_disabled
static uword arp_disabled(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: arp.c:309
ethernet_arp_init
static clib_error_t * ethernet_arp_init(vlib_main_t *vm)
Definition: arp.c:877
ip4_fib_table_lookup
fib_node_index_t ip4_fib_table_lookup(const ip4_fib_t *fib, const ip4_address_t *addr, u32 len)
Definition: ip4_fib.c:294
i
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:261
format_ethernet_arp_input_trace
static u8 * format_ethernet_arp_input_trace(u8 *s, va_list *va)
Definition: arp.c:113
mask
vl_api_pnat_mask_t mask
Definition: pnat.api:45
ip4_fib_get
static ip4_fib_t * ip4_fib_get(u32 index)
Get the FIB at the given index.
Definition: ip4_fib.h:113
vec_validate
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment)
Definition: vec.h:523
fib_entry_get_flags_for_source
fib_entry_flag_t fib_entry_get_flags_for_source(fib_node_index_t fib_entry_index, fib_source_t source)
Definition: fib_entry_src.c:1877
VNET_SW_INTERFACE_FLAG_UNNUMBERED
@ VNET_SW_INTERFACE_FLAG_UNNUMBERED
Definition: interface.h:850
src
vl_api_address_t src
Definition: gre.api:54
ip4_address_t
Definition: ip4_packet.h:50
ARP_REPLY_N_NEXT
@ ARP_REPLY_N_NEXT
Definition: arp_packet.h:28
fib_entry_get_resolving_interface
u32 fib_entry_get_resolving_interface(fib_node_index_t entry_index)
Definition: fib_entry.c:1474
pg_free_edit_group
static void pg_free_edit_group(pg_stream_t *s)
Definition: pg.h:292
FIB_ENTRY_FLAG_LOCAL
@ FIB_ENTRY_FLAG_LOCAL
Definition: fib_entry.h:117
vlib_node_registration_t
struct _vlib_node_registration vlib_node_registration_t
vnet_interface_main_t::sw_interfaces
vnet_sw_interface_t * sw_interfaces
Definition: interface.h:1014
unformat_pg_edit
uword unformat_pg_edit(unformat_input_t *input, va_list *args)
Definition: edit.c:106
fib_prefix_t_::fp_addr
ip46_address_t fp_addr
The address type is not deriveable from the fp_addr member.
Definition: fib_types.h:225
ARP_REPLY_NEXT_REPLY_TX
@ ARP_REPLY_NEXT_REPLY_TX
Definition: arp_packet.h:27
pg_ethernet_arp_header_init
static void pg_ethernet_arp_header_init(pg_ethernet_arp_header_t *p)
Definition: arp.c:788
arp_reply
static uword arp_reply(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: arp.c:388
vnet_sw_interface_t::unnumbered_sw_if_index
u32 unnumbered_sw_if_index
Definition: interface.h:883
ethernet_arp_error_strings
static char * ethernet_arp_error_strings[]
Definition: arp.c:680
vnet_main_t
Definition: vnet.h:76
vlib_validate_buffer_enqueue_x1
#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:224
always_inline
#define always_inline
Definition: rdma_mlx5dv.h:23
arp_unnumbered
static int arp_unnumbered(vlib_buffer_t *p0, u32 input_sw_if_index, u32 conn_sw_if_index)
Definition: arp.c:164
ip4_enable_disable_interface_callback_t::function
ip4_enable_disable_interface_function_t * function
Definition: ip4.h:84
foreach_ethernet_arp_opcode
#define foreach_ethernet_arp_opcode
Definition: arp_packet.h:64
ip_neighbor.h
fib_entry_get
fib_entry_t * fib_entry_get(fib_node_index_t index)
Definition: fib_entry.c:51
FIB_ENTRY_FLAG_CONNECTED
@ FIB_ENTRY_FLAG_CONNECTED
Definition: fib_entry.h:113
ETHERNET_ARP_N_ERROR
@ ETHERNET_ARP_N_ERROR
Definition: arp.h:46
ARP_DISABLED_NEXT_DROP
@ ARP_DISABLED_NEXT_DROP
Definition: arp.c:287
fib_entry_is_sourced
int fib_entry_is_sourced(fib_node_index_t fib_entry_index, fib_source_t source)
Definition: fib_entry_src.c:139
format
description fragment has unexpected format
Definition: map.api:433
pg_create_edit_group
static void * pg_create_edit_group(pg_stream_t *s, int n_edit_bytes, int n_packet_bytes, u32 *group_index)
Definition: pg.h:239
FIB_SOURCE_DEFAULT_ROUTE
@ FIB_SOURCE_DEFAULT_ROUTE
The default route source.
Definition: fib_source.h:134
unformat_mac_address_t
uword unformat_mac_address_t(unformat_input_t *input, va_list *args)
Definition: mac_address.c:37
fib_entry_get_any_resolving_interface
u32 fib_entry_get_any_resolving_interface(fib_node_index_t entry_index)
Definition: fib_entry.c:1484
vlib_put_next_frame
vlib_put_next_frame(vm, node, next_index, 0)
ip_neighbor_learn_dp
void ip_neighbor_learn_dp(const ip_neighbor_learn_t *l)
APIs invoked by neighbor implementation (i.s.
Definition: ip_neighbor_dp.c:28
u32
unsigned int u32
Definition: types.h:88
ethernet_arp_interface_t_::enabled
u32 enabled
Is ARP enabled on this interface.
Definition: arp.c:47
VLIB_INIT_FUNCTION
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:172
arp_disabled_next_t_
arp_disabled_next_t_
Definition: arp.c:285
FOR_EACH_SRC_ADDED
#define FOR_EACH_SRC_ADDED(_entry, _src, _source, action)
Definition: fib_entry_src.h:218
pg_ethernet_arp_header_t::opcode
pg_edit_t opcode
Definition: arp.c:779
si
vnet_sw_interface_t * si
Definition: interface_output.c:398
arp_disabled_next_t
enum arp_disabled_next_t_ arp_disabled_next_t
arp_is_enabled
static int arp_is_enabled(ethernet_arp_main_t *am, u32 sw_if_index)
Definition: arp.c:127
arp_input_node
static vlib_node_registration_t arp_input_node
(constructor) VLIB_REGISTER_NODE (arp_input_node)
Definition: arp.c:688
vlib_node_get_runtime
static vlib_node_runtime_t * vlib_node_get_runtime(vlib_main_t *vm, u32 node_index)
Get node runtime by node index.
Definition: node_funcs.h:116
ethernet_arp_header_t::l3_type
u16 l3_type
Definition: arp_packet.h:136
arp_mk_reply
static_always_inline u32 arp_mk_reply(vnet_main_t *vnm, vlib_buffer_t *p0, u32 sw_if_index0, const ip4_address_t *if_addr0, ethernet_arp_header_t *arp0, ethernet_header_t *eth_rx)
Definition: arp_packet.h:32
vnet_feature_enable_disable
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: pnat_test_stubs.h:50
ip4_fib.h
unformat_ethernet_arp_opcode_net_byte_order
static uword unformat_ethernet_arp_opcode_net_byte_order(unformat_input_t *input, va_list *args)
Definition: arp.c:95
ethernet_arp_header_t::l2_type
u16 l2_type
Definition: arp_packet.h:135
adj_nbr.h
ARP_INPUT_N_NEXT
@ ARP_INPUT_N_NEXT
Definition: arp.c:212
vlib_main_t
Definition: main.h:102
vlib_node_t
Definition: node.h:247
arp_disabled_node
static vlib_node_registration_t arp_disabled_node
(constructor) VLIB_REGISTER_NODE (arp_disabled_node)
Definition: arp.c:704
pg_ethernet_arp_header_t::ip4_over_ethernet
struct pg_ethernet_arp_header_t::@148 ip4_over_ethernet[2]
VLIB_INITS
#define VLIB_INITS(...)
Definition: init.h:352
VNET_FEATURES
#define VNET_FEATURES(...)
Definition: feature.h:470
u8
unsigned char u8
Definition: types.h:56
clib_error_t
Definition: clib_error.h:21
vlib_buffer_get_current
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:257
rt
vnet_interface_output_runtime_t * rt
Definition: interface_output.c:399
vlib_init_function_t
clib_error_t *() vlib_init_function_t(struct vlib_main_t *vm)
Definition: init.h:51
ip_neighbor_dp.h
ethernet_buffer_get_header
static ethernet_header_t * ethernet_buffer_get_header(vlib_buffer_t *b)
Definition: ethernet.h:419
ARP_INPUT_NEXT_DISABLED
@ ARP_INPUT_NEXT_DISABLED
Definition: arp.c:211
vnet_feature_arc_start
static_always_inline void vnet_feature_arc_start(u8 arc, u32 sw_if_index, u32 *next0, vlib_buffer_t *b0)
Definition: feature.h:302
vrrp_prefix
static const u8 vrrp_prefix[]
Definition: arp.c:64
ip_address::ip
ip46_address_t ip
Definition: ip_types.h:81
pg_edit_t
Definition: edit.h:64
fib_source_t
enum fib_source_t_ fib_source_t
The different sources that can create a route.
ethernet_arp_interface_t
struct ethernet_arp_interface_t_ ethernet_arp_interface_t
Per-interface ARP configuration and state.
pg_stream_t
Definition: pg.h:96
unformat_ip4_address
unformat_function_t unformat_ip4_address
Definition: format.h:68
vnet_arp_add_del_sw_interface
static clib_error_t * vnet_arp_add_del_sw_interface(vnet_main_t *vnm, u32 sw_if_index, u32 is_add)
Definition: arp.c:859
ARP_DST_FIB_NONE
@ ARP_DST_FIB_NONE
Definition: arp.c:357
vlib_node_runtime_t
Definition: node.h:454
arp_disabled_error_t
arp_disabled_error_t
Definition: arp.c:294
from
from
Definition: nat44_ei_hairpinning.c:415
ip4_main_t
IPv4 main type.
Definition: ip4.h:107
unformat_vlib_number_by_name
uword unformat_vlib_number_by_name(unformat_input_t *input, va_list *args)
Definition: format.c:157
arp_learn
static u32 arp_learn(u32 sw_if_index, const ethernet_arp_ip4_over_ethernet_address_t *addr)
Definition: arp.c:189
sw_if_index
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:34
vlib_get_next_frame
#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:395
format_ethernet_arp_header
u8 * format_ethernet_arp_header(u8 *s, va_list *va)
Definition: arp_packet.c:59
arp.h
n_left_from
n_left_from
Definition: nat44_ei_hairpinning.c:416
fib_prefix_t_
Aggregate type for a prefix.
Definition: fib_types.h:202
ARP_DST_FIB_CONN
@ ARP_DST_FIB_CONN
Definition: arp.c:359
ethernet_register_input_type
void ethernet_register_input_type(vlib_main_t *vm, ethernet_type_t type, u32 node_index)
Definition: node.c:2263
vnet_main_t::interface_main
vnet_interface_main_t interface_main
Definition: vnet.h:81
arp_enable
static void arp_enable(ethernet_arp_main_t *am, u32 sw_if_index)
Definition: arp.c:136
foreach_arp_disabled_error
#define foreach_arp_disabled_error
Definition: arp.c:291
vlib_buffer_t
VLIB buffer representation.
Definition: buffer.h:111
VLIB_REGISTER_NODE
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
arp_enable_disable_interface
static void arp_enable_disable_interface(ip4_main_t *im, uword opaque, u32 sw_if_index, u32 is_enable)
Definition: arp.c:844
flags
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:105