FD.io VPP  v21.10.1-2-g0a485f517
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 #include <vnet/pg/pg.h>
26 
29 
30 #include <vlibmemory/api.h>
31 
32 /**
33  * @file
34  * @brief IPv4 ARP.
35  *
36  * This file contains code to manage the IPv4 ARP tables (IP Address
37  * to MAC Address lookup).
38  */
39 
40 /**
41  * @brief Per-interface ARP configuration and state
42  */
44 {
45  /**
46  * Is ARP enabled on this interface
47  */
50 
51 typedef struct
52 {
53  /* Hash tables mapping name to opcode. */
55 
56  /** Per interface state */
58 
59  /* ARP feature arc index */
62 
64 
65 static const u8 vrrp_prefix[] = { 0x00, 0x00, 0x5E, 0x00, 0x01 };
66 
67 static uword
69  va_list * args)
70 {
71  int *result = va_arg (*args, int *);
73  int x, i;
74 
75  /* Numeric opcode. */
76  if (unformat (input, "0x%x", &x) || unformat (input, "%d", &x))
77  {
78  if (x >= (1 << 16))
79  return 0;
80  *result = x;
81  return 1;
82  }
83 
84  /* Named type. */
86  am->opcode_by_name, &i))
87  {
88  *result = i;
89  return 1;
90  }
91 
92  return 0;
93 }
94 
95 static uword
97  va_list * args)
98 {
99  int *result = va_arg (*args, int *);
100  if (!unformat_user
102  return 0;
103 
104  *result = clib_host_to_net_u16 ((u16) * result);
105  return 1;
106 }
107 
108 typedef struct
109 {
110  u8 packet_data[64];
112 
113 static u8 *
115 {
116  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*va, vlib_main_t *);
117  CLIB_UNUSED (vlib_node_t * node) = va_arg (*va, vlib_node_t *);
119 
120  s = format (s, "%U",
122  t->packet_data, sizeof (t->packet_data));
123 
124  return s;
125 }
126 
127 static int
129 {
130  if (vec_len (am->ethernet_arp_by_sw_if_index) <= sw_if_index)
131  return 0;
132 
133  return (am->ethernet_arp_by_sw_if_index[sw_if_index].enabled);
134 }
135 
136 static void
138 {
140  return;
141 
142  vec_validate (am->ethernet_arp_by_sw_if_index, sw_if_index);
143 
144  am->ethernet_arp_by_sw_if_index[sw_if_index].enabled = 1;
145 
146  vnet_feature_enable_disable ("arp", "arp-reply", sw_if_index, 1, NULL, 0);
147  vnet_feature_enable_disable ("arp", "arp-disabled", sw_if_index, 0, NULL,
148  0);
149 }
150 
151 static void
153 {
154  if (!arp_is_enabled (am, sw_if_index))
155  return;
156 
157  vnet_feature_enable_disable ("arp", "arp-disabled", sw_if_index, 1, NULL,
158  0);
159  vnet_feature_enable_disable ("arp", "arp-reply", sw_if_index, 0, NULL, 0);
160 
161  am->ethernet_arp_by_sw_if_index[sw_if_index].enabled = 0;
162 }
163 
164 static int
166  u32 input_sw_if_index, u32 conn_sw_if_index)
167 {
168  vnet_main_t *vnm = vnet_get_main ();
171 
172  /* verify that the input interface is unnumbered to the connected.
173  * the connected interface is the interface on which the subnet is
174  * configured */
175  si = &vim->sw_interfaces[input_sw_if_index];
176 
178  (si->unnumbered_sw_if_index == conn_sw_if_index)))
179  {
180  /* the input interface is not unnumbered to the interface on which
181  * the sub-net is configured that covers the ARP request.
182  * So this is not the case for unnumbered.. */
183  return 0;
184  }
185 
186  return !0;
187 }
188 
191  const ethernet_arp_ip4_over_ethernet_address_t * addr)
192 {
193  /* *INDENT-OFF* */
194  ip_neighbor_learn_t l = {
195  .ip = {
196  .ip.ip4 = addr->ip4,
197  .version = AF_IP4,
198  },
199  .mac = addr->mac,
200  .sw_if_index = sw_if_index,
201  };
202  /* *INDENT-ON* */
203 
205 
206  return (ETHERNET_ARP_ERROR_l3_src_address_learned);
207 }
208 
209 typedef enum arp_input_next_t_
210 {
215 
216 static uword
218 {
219  u32 n_left_from, next_index, *from, *to_next, n_left_to_next;
221 
223  n_left_from = frame->n_vectors;
224  next_index = node->cached_next_index;
225 
226  if (node->flags & VLIB_NODE_FLAG_TRACE)
228  /* stride */ 1,
229  sizeof (ethernet_arp_input_trace_t));
230 
231  while (n_left_from > 0)
232  {
233  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
234 
235  while (n_left_from > 0 && n_left_to_next > 0)
236  {
237  const ethernet_arp_header_t *arp0;
238  arp_input_next_t next0;
239  vlib_buffer_t *p0;
240  u32 pi0, error0;
241 
242  pi0 = to_next[0] = from[0];
243  from += 1;
244  to_next += 1;
245  n_left_from -= 1;
246  n_left_to_next -= 1;
247 
248  p0 = vlib_get_buffer (vm, pi0);
249  arp0 = vlib_buffer_get_current (p0);
250 
251  error0 = ETHERNET_ARP_ERROR_replies_sent;
252  next0 = ARP_INPUT_NEXT_DROP;
253 
254  error0 =
255  (arp0->l2_type !=
256  clib_net_to_host_u16 (ETHERNET_ARP_HARDWARE_TYPE_ethernet) ?
257  ETHERNET_ARP_ERROR_l2_type_not_ethernet : error0);
258  error0 =
259  (arp0->l3_type !=
260  clib_net_to_host_u16 (ETHERNET_TYPE_IP4) ?
261  ETHERNET_ARP_ERROR_l3_type_not_ip4 : error0);
262  error0 =
263  (0 == arp0->ip4_over_ethernet[0].ip4.as_u32 ?
264  ETHERNET_ARP_ERROR_l3_dst_address_unset : error0);
265 
266  if (ETHERNET_ARP_ERROR_replies_sent == error0)
267  {
268  next0 = ARP_INPUT_NEXT_DISABLED;
269  vnet_feature_arc_start (am->feature_arc_index,
271  &next0, p0);
272  }
273  else
274  p0->error = node->errors[error0];
275 
277  n_left_to_next, pi0, next0);
278  }
279 
280  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
281  }
282 
283  return frame->n_vectors;
284 }
285 
287 {
291 
292 #define foreach_arp_disabled_error \
293  _ (DISABLED, "ARP Disabled on this interface") \
294 
295 typedef enum
296 {
297 #define _(sym,string) ARP_DISABLED_ERROR_##sym,
299 #undef _
302 
303 static char *arp_disabled_error_strings[] = {
304 #define _(sym,string) string,
306 #undef _
307 };
308 
309 static uword
312 {
313  u32 n_left_from, next_index, *from, *to_next, n_left_to_next;
314 
316  n_left_from = frame->n_vectors;
317  next_index = node->cached_next_index;
318 
319  if (node->flags & VLIB_NODE_FLAG_TRACE)
321  /* stride */ 1,
322  sizeof (ethernet_arp_input_trace_t));
323 
324  while (n_left_from > 0)
325  {
326  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
327 
328  while (n_left_from > 0 && n_left_to_next > 0)
329  {
331  vlib_buffer_t *p0;
332  u32 pi0, error0;
333 
334  next0 = ARP_DISABLED_NEXT_DROP;
335  error0 = ARP_DISABLED_ERROR_DISABLED;
336 
337  pi0 = to_next[0] = from[0];
338  from += 1;
339  to_next += 1;
340  n_left_from -= 1;
341  n_left_to_next -= 1;
342 
343  p0 = vlib_get_buffer (vm, pi0);
344  p0->error = node->errors[error0];
345 
347  n_left_to_next, pi0, next0);
348  }
349 
350  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
351  }
352 
353  return frame->n_vectors;
354 }
355 
357 {
361 };
362 
363 /*
364  * we're looking for FIB sources that indicate the destination
365  * is attached. There may be interposed DPO prior to the one
366  * we are looking for
367  */
368 static enum arp_dst_fib_type
370 {
371  const fib_entry_t *entry = fib_entry_get (fei);
372  const fib_entry_src_t *entry_src;
374  /* *INDENT-OFF* */
375  FOR_EACH_SRC_ADDED(entry, entry_src, src,
376  ({
379  return ARP_DST_FIB_ADJ;
380  else if (FIB_ENTRY_FLAG_CONNECTED & *flags)
381  return ARP_DST_FIB_CONN;
382  }))
383  /* *INDENT-ON* */
384 
385  return ARP_DST_FIB_NONE;
386 }
387 
388 static uword
390 {
391  vnet_main_t *vnm = vnet_get_main ();
392  u32 n_left_from, next_index, *from, *to_next;
393  u32 n_replies_sent = 0;
394 
396  n_left_from = frame->n_vectors;
397  next_index = node->cached_next_index;
398 
399  if (node->flags & VLIB_NODE_FLAG_TRACE)
401  /* stride */ 1,
402  sizeof (ethernet_arp_input_trace_t));
403 
404  while (n_left_from > 0)
405  {
406  u32 n_left_to_next;
407 
408  vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
409 
410  while (n_left_from > 0 && n_left_to_next > 0)
411  {
412  vlib_buffer_t *p0;
413  ethernet_arp_header_t *arp0;
414  ethernet_header_t *eth_rx;
415  const ip4_address_t *if_addr0;
416  u32 pi0, error0, next0, sw_if_index0, conn_sw_if_index0, fib_index0;
417  u8 dst_is_local0, is_vrrp_reply0;
418  fib_node_index_t dst_fei, src_fei;
419  const fib_prefix_t *pfx0;
420  fib_entry_flag_t src_flags, dst_flags;
421 
422  pi0 = from[0];
423  to_next[0] = pi0;
424  from += 1;
425  to_next += 1;
426  n_left_from -= 1;
427  n_left_to_next -= 1;
428 
429  p0 = vlib_get_buffer (vm, pi0);
430  arp0 = vlib_buffer_get_current (p0);
431  /* Fill in ethernet header. */
432  eth_rx = ethernet_buffer_get_header (p0);
433 
434  next0 = ARP_REPLY_NEXT_DROP;
435  error0 = ETHERNET_ARP_ERROR_replies_sent;
436  sw_if_index0 = vnet_buffer (p0)->sw_if_index[VLIB_RX];
437 
438  /* Check that IP address is local and matches incoming interface. */
439  fib_index0 = ip4_fib_table_get_index_for_sw_if_index (sw_if_index0);
440  if (~0 == fib_index0)
441  {
442  error0 = ETHERNET_ARP_ERROR_interface_no_table;
443  goto drop;
444 
445  }
446 
447  {
448  /*
449  * we're looking for FIB entries that indicate the source
450  * is attached. There may be more specific non-attached
451  * routes that match the source, but these do not influence
452  * whether we respond to an ARP request, i.e. they do not
453  * influence whether we are the correct way for the sender
454  * to reach us, they only affect how we reach the sender.
455  */
456  fib_entry_t *src_fib_entry;
457  const fib_prefix_t *pfx;
459  fib_source_t source;
460  int attached;
461  int mask;
462 
463  mask = 32;
464  attached = 0;
465 
466  do
467  {
468  src_fei = ip4_fib_table_lookup (ip4_fib_get (fib_index0),
469  &arp0->
470  ip4_over_ethernet[0].ip4,
471  mask);
472  src_fib_entry = fib_entry_get (src_fei);
473 
474  /*
475  * It's possible that the source that provides the
476  * flags we need, or the flags we must not have,
477  * is not the best source, so check then all.
478  */
479  /* *INDENT-OFF* */
480  FOR_EACH_SRC_ADDED(src_fib_entry, src, source,
481  ({
482  src_flags = fib_entry_get_flags_for_source (src_fei, source);
483 
484  /* Reject requests/replies with our local interface
485  address. */
486  if (FIB_ENTRY_FLAG_LOCAL & src_flags)
487  {
488  error0 = ETHERNET_ARP_ERROR_l3_src_address_is_local;
489  /*
490  * When VPP has an interface whose address is also
491  * applied to a TAP interface on the host, then VPP's
492  * TAP interface will be unnumbered to the 'real'
493  * interface and do proxy ARP from the host.
494  * The curious aspect of this setup is that ARP requests
495  * from the host will come from the VPP's own address.
496  * So don't drop immediately here, instead go see if this
497  * is a proxy ARP case.
498  */
499  goto next_feature;
500  }
501  /* A Source must also be local to subnet of matching
502  * interface address. */
503  if ((FIB_ENTRY_FLAG_ATTACHED & src_flags) ||
504  (FIB_ENTRY_FLAG_CONNECTED & src_flags))
505  {
506  attached = 1;
507  break;
508  }
509  /*
510  * else
511  * The packet was sent from an address that is not
512  * connected nor attached i.e. it is not from an
513  * address that is covered by a link's sub-net,
514  * nor is it a already learned host resp.
515  */
516  }));
517  /* *INDENT-ON* */
518 
519  /*
520  * shorter mask lookup for the next iteration.
521  */
522  pfx = fib_entry_get_prefix (src_fei);
523  mask = pfx->fp_len - 1;
524 
525  /*
526  * continue until we hit the default route or we find
527  * the attached we are looking for. The most likely
528  * outcome is we find the attached with the first source
529  * on the first lookup.
530  */
531  }
532  while (!attached &&
534 
535  if (!attached)
536  {
537  /*
538  * the matching route is a not attached, i.e. it was
539  * added as a result of routing, rather than interface/ARP
540  * configuration. If the matching route is not a host route
541  * (i.e. a /32)
542  */
543  error0 = ETHERNET_ARP_ERROR_l3_src_address_not_local;
544  goto drop;
545  }
546  }
547 
548  dst_fei = ip4_fib_table_lookup (ip4_fib_get (fib_index0),
549  &arp0->ip4_over_ethernet[1].ip4,
550  32);
551  conn_sw_if_index0 = fib_entry_get_any_resolving_interface (dst_fei);
552 
553  switch (arp_dst_fib_check (dst_fei, &dst_flags))
554  {
555  case ARP_DST_FIB_ADJ:
556  /*
557  * We matched an adj-fib on ths source subnet (a /32 previously
558  * added as a result of ARP). If this request is a gratuitous
559  * ARP, then learn from it.
560  * The check for matching an adj-fib, is to prevent hosts
561  * from spamming us with gratuitous ARPS that might otherwise
562  * blow our ARP cache
563  */
564  if (conn_sw_if_index0 != sw_if_index0)
565  error0 = ETHERNET_ARP_ERROR_l3_dst_address_not_local;
566  else if (arp0->ip4_over_ethernet[0].ip4.as_u32 ==
567  arp0->ip4_over_ethernet[1].ip4.as_u32)
568  error0 = arp_learn (sw_if_index0,
569  &arp0->ip4_over_ethernet[0]);
570  goto drop;
571  case ARP_DST_FIB_CONN:
572  /* destination is connected, continue to process */
573  break;
574  case ARP_DST_FIB_NONE:
575  /* destination is not connected, stop here */
576  error0 = ETHERNET_ARP_ERROR_l3_dst_address_not_local;
577  goto next_feature;
578  }
579 
580  dst_is_local0 = (FIB_ENTRY_FLAG_LOCAL & dst_flags);
581  pfx0 = fib_entry_get_prefix (dst_fei);
582  if_addr0 = &pfx0->fp_addr.ip4;
583 
584  is_vrrp_reply0 =
585  ((arp0->opcode ==
586  clib_host_to_net_u16 (ETHERNET_ARP_OPCODE_reply))
587  &&
588  (!memcmp
589  (arp0->ip4_over_ethernet[0].mac.bytes, vrrp_prefix,
590  sizeof (vrrp_prefix))));
591 
592  /* Trash ARP packets whose ARP-level source addresses do not
593  match their L2-frame-level source addresses, unless it's
594  a reply from a VRRP virtual router */
596  (eth_rx->src_address,
597  arp0->ip4_over_ethernet[0].mac.bytes) && !is_vrrp_reply0)
598  {
599  error0 = ETHERNET_ARP_ERROR_l2_address_mismatch;
600  goto drop;
601  }
602 
603  /* Learn or update sender's mapping only for replies to addresses
604  * that are local to the subnet */
605  if (arp0->opcode ==
606  clib_host_to_net_u16 (ETHERNET_ARP_OPCODE_reply))
607  {
608  if (dst_is_local0)
609  error0 =
610  arp_learn (sw_if_index0, &arp0->ip4_over_ethernet[0]);
611  else
612  /* a reply for a non-local destination could be a GARP.
613  * GARPs for hosts we know were handled above, so this one
614  * we drop */
615  error0 = ETHERNET_ARP_ERROR_l3_dst_address_not_local;
616 
617  goto next_feature;
618  }
619  else if (arp0->opcode ==
620  clib_host_to_net_u16 (ETHERNET_ARP_OPCODE_request) &&
621  (dst_is_local0 == 0))
622  {
623  goto next_feature;
624  }
625 
626  /* Honor unnumbered interface, if any */
627  if (sw_if_index0 != conn_sw_if_index0 ||
628  sw_if_index0 != fib_entry_get_resolving_interface (src_fei))
629  {
630  /*
631  * The interface the ARP is sent to or was received on is not the
632  * interface on which the covering prefix is configured.
633  * Maybe this is a case for unnumbered.
634  */
635  if (!arp_unnumbered (p0, sw_if_index0, conn_sw_if_index0))
636  {
637  error0 = ETHERNET_ARP_ERROR_unnumbered_mismatch;
638  goto drop;
639  }
640  }
641  if (arp0->ip4_over_ethernet[0].ip4.as_u32 ==
642  arp0->ip4_over_ethernet[1].ip4.as_u32)
643  {
644  error0 = ETHERNET_ARP_ERROR_gratuitous_arp;
645  goto drop;
646  }
647 
648  next0 = arp_mk_reply (vnm, p0, sw_if_index0,
649  if_addr0, arp0, eth_rx);
650 
651  /* We are going to reply to this request, so, in the absence of
652  errors, learn the sender */
653  if (!error0)
654  error0 = arp_learn (sw_if_index0, &arp0->ip4_over_ethernet[1]);
655 
656  n_replies_sent += 1;
657  goto enqueue;
658 
659  next_feature:
660  vnet_feature_next (&next0, p0);
661  goto enqueue;
662 
663  drop:
664  p0->error = node->errors[error0];
665 
666  enqueue:
668  n_left_to_next, pi0, next0);
669  }
670 
671  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
672  }
673 
674  vlib_error_count (vm, node->node_index,
675  ETHERNET_ARP_ERROR_replies_sent, n_replies_sent);
676 
677  return frame->n_vectors;
678 }
679 
680 
681 static char *ethernet_arp_error_strings[] = {
682 #define _(sym,string) string,
684 #undef _
685 };
686 
687 /* *INDENT-OFF* */
688 
690 {
691  .function = arp_input,
692  .name = "arp-input",
693  .vector_size = sizeof (u32),
694  .n_errors = ETHERNET_ARP_N_ERROR,
695  .error_strings = ethernet_arp_error_strings,
696  .n_next_nodes = ARP_INPUT_N_NEXT,
697  .next_nodes = {
698  [ARP_INPUT_NEXT_DROP] = "error-drop",
699  [ARP_INPUT_NEXT_DISABLED] = "arp-disabled",
700  },
701  .format_buffer = format_ethernet_arp_header,
702  .format_trace = format_ethernet_arp_input_trace,
703 };
704 
706 {
707  .function = arp_disabled,
708  .name = "arp-disabled",
709  .vector_size = sizeof (u32),
710  .n_errors = ARP_DISABLED_N_ERROR,
711  .error_strings = arp_disabled_error_strings,
712  .n_next_nodes = ARP_DISABLED_N_NEXT,
713  .next_nodes = {
714  [ARP_INPUT_NEXT_DROP] = "error-drop",
715  },
716  .format_buffer = format_ethernet_arp_header,
717  .format_trace = format_ethernet_arp_input_trace,
718 };
719 
721 {
722  .function = arp_reply,
723  .name = "arp-reply",
724  .vector_size = sizeof (u32),
725  .n_errors = ETHERNET_ARP_N_ERROR,
726  .error_strings = ethernet_arp_error_strings,
727  .n_next_nodes = ARP_REPLY_N_NEXT,
728  .next_nodes = {
729  [ARP_REPLY_NEXT_DROP] = "error-drop",
730  [ARP_REPLY_NEXT_REPLY_TX] = "interface-output",
731  },
732  .format_buffer = format_ethernet_arp_header,
733  .format_trace = format_ethernet_arp_input_trace,
734 };
735 
736 /* Built-in ARP rx feature path definition */
737 VNET_FEATURE_ARC_INIT (arp_feat, static) =
738 {
739  .arc_name = "arp",
740  .start_nodes = VNET_FEATURES ("arp-input"),
741  .last_in_arc = "error-drop",
742  .arc_index_ptr = &ethernet_arp_main.feature_arc_index,
743 };
744 
745 VNET_FEATURE_INIT (arp_reply_feat_node, static) =
746 {
747  .arc_name = "arp",
748  .node_name = "arp-reply",
749  .runs_before = VNET_FEATURES ("arp-disabled"),
750 };
751 
752 VNET_FEATURE_INIT (arp_proxy_feat_node, static) =
753 {
754  .arc_name = "arp",
755  .node_name = "arp-proxy",
756  .runs_after = VNET_FEATURES ("arp-reply"),
757  .runs_before = VNET_FEATURES ("arp-disabled"),
758 };
759 
760 VNET_FEATURE_INIT (arp_disabled_feat_node, static) =
761 {
762  .arc_name = "arp",
763  .node_name = "arp-disabled",
764  .runs_before = VNET_FEATURES ("error-drop"),
765 };
766 
767 VNET_FEATURE_INIT (arp_drop_feat_node, static) =
768 {
769  .arc_name = "arp",
770  .node_name = "error-drop",
771  .runs_before = 0, /* last feature */
772 };
773 
774 /* *INDENT-ON* */
775 
776 typedef struct
777 {
778  pg_edit_t l2_type, l3_type;
779  pg_edit_t n_l2_address_bytes, n_l3_address_bytes;
781  struct
782  {
785  } ip4_over_ethernet[2];
787 
788 static inline void
790 {
791  /* Initialize fields that are not bit fields in the IP header. */
792 #define _(f) pg_edit_init (&p->f, ethernet_arp_header_t, f);
793  _(l2_type);
794  _(l3_type);
795  _(n_l2_address_bytes);
796  _(n_l3_address_bytes);
797  _(opcode);
798  _(ip4_over_ethernet[0].mac);
799  _(ip4_over_ethernet[0].ip4);
800  _(ip4_over_ethernet[1].mac);
801  _(ip4_over_ethernet[1].ip4);
802 #undef _
803 }
804 
805 uword
806 unformat_pg_arp_header (unformat_input_t * input, va_list * args)
807 {
808  pg_stream_t *s = va_arg (*args, pg_stream_t *);
810  u32 group_index;
811 
812  p = pg_create_edit_group (s, sizeof (p[0]), sizeof (ethernet_arp_header_t),
813  &group_index);
815 
816  /* Defaults. */
817  pg_edit_set_fixed (&p->l2_type, ETHERNET_ARP_HARDWARE_TYPE_ethernet);
818  pg_edit_set_fixed (&p->l3_type, ETHERNET_TYPE_IP4);
821 
822  if (!unformat (input, "%U: %U/%U -> %U/%U",
833  {
834  /* Free up any edits we may have added. */
835  pg_free_edit_group (s);
836  return 0;
837  }
838  return 1;
839 }
840 
841 /*
842  * callback when an interface address is added or deleted
843  */
844 static void
846  uword opaque, u32 sw_if_index, u32 is_enable)
847 {
849 
850  if (is_enable)
852  else
854 }
855 
856 /*
857  * Remove any arp entries associated with the specified interface
858  */
859 static clib_error_t *
861 {
863  if (is_add)
865  return (NULL);
866 }
867 
869 
870 const static ip_neighbor_vft_t arp_vft = {
872  .inv_proxy4_del = arp_proxy_del,
873  .inv_proxy4_enable = arp_proxy_disable,
874  .inv_proxy4_disable = arp_proxy_disable,
875 };
876 
877 static clib_error_t *
879 {
881  ip4_main_t *im = &ip4_main;
882  pg_node_t *pn;
883 
884  ethernet_register_input_type (vm, ETHERNET_TYPE_ARP, arp_input_node.index);
885 
886  pn = pg_get_node (arp_input_node.index);
888 
889  am->opcode_by_name = hash_create_string (0, sizeof (uword));
890 #define _(o) hash_set_mem (am->opcode_by_name, #o, ETHERNET_ARP_OPCODE_##o);
892 #undef _
893 
894  /* don't trace ARP error packets */
895  {
898 
899 #define _(a,b) \
900  vnet_pcap_drop_trace_filter_add_del \
901  (rt->errors[ETHERNET_ARP_ERROR_##a], \
902  1 /* is_add */);
904 #undef _
905  }
906 
907  {
910  };
911  vec_add1 (im->enable_disable_interface_callbacks, cb);
912  }
913 
915 
916  return 0;
917 }
918 
919 /* *INDENT-OFF* */
921 {
922  .runs_after = VLIB_INITS("ethernet_init",
923  "ip_neighbor_init"),
924 };
925 /* *INDENT-ON* */
926 
927 /*
928  * fd.io coding-style-patch-verification: ON
929  *
930  * Local Variables:
931  * eval: (c-set-style "gnu")
932  * End:
933  */
arp_reply_node
static vlib_node_registration_t arp_reply_node
(constructor) VLIB_REGISTER_NODE (arp_reply_node)
Definition: arp.c:720
ethernet_arp_main_t
Definition: arp.c:51
im
vnet_interface_main_t * im
Definition: interface_output.c:415
api.h
ARP_DST_FIB_ADJ
@ ARP_DST_FIB_ADJ
Definition: arp.c:359
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:869
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:778
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:1104
ethernet_arp_interface_t_
Per-interface ARP configuration and state.
Definition: arp.c:43
ip_neighbor_vft_t_::inv_proxy4_add
ip4_neighbor_proxy_addr_t inv_proxy4_add
Definition: ip_neighbor.h:105
pg.h
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:60
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:152
adj_mcast.h
FIB_ENTRY_FLAG_ATTACHED
@ FIB_ENTRY_FLAG_ATTACHED
Definition: fib_entry.h:114
hash_create_string
#define hash_create_string(elts, value_bytes)
Definition: hash.h:689
ethernet_arp_main
static ethernet_arp_main_t ethernet_arp_main
Definition: arp.c:63
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:990
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:217
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:806
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:209
pg_ethernet_arp_header_t
Definition: arp.c:776
AF_IP4
@ AF_IP4
Definition: ip_types.h:23
ip_neighbor_learn_t_
Definition: ip_neighbor_types.h:97
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:369
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:778
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:289
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:873
ethernet_arp_input_trace_t::packet_data
u8 packet_data[64]
Definition: arp.c:110
pg_node_t
Definition: pg.h:332
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:784
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:68
ethernet_arp_main_t::opcode_by_name
uword * opcode_by_name
Definition: arp.c:54
ARP_DISABLED_N_ERROR
@ ARP_DISABLED_N_ERROR
Definition: arp.c:300
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:870
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:335
CLIB_UNUSED
#define CLIB_UNUSED(x)
Definition: clib.h:90
vnet_buffer
#define vnet_buffer(b)
Definition: buffer.h:441
pg_ethernet_arp_header_t::n_l3_address_bytes
pg_edit_t n_l3_address_bytes
Definition: arp.c:779
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:211
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:1014
ethernet_arp_input_trace_t
Definition: arp.c:108
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:779
arp_dst_fib_type
arp_dst_fib_type
Definition: arp.c:356
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:57
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:391
ethernet_header_t
Definition: packet.h:52
pg_ethernet_arp_header_t::mac
pg_edit_t mac
Definition: arp.c:783
arp_disabled_error_strings
static char * arp_disabled_error_strings[]
Definition: arp.c:303
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:310
ethernet_arp_init
static clib_error_t * ethernet_arp_init(vlib_main_t *vm)
Definition: arp.c:878
format_ethernet_arp_input_trace
static u8 * format_ethernet_arp_input_trace(u8 *s, va_list *va)
Definition: arp.c:114
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:88
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:1859
VNET_SW_INTERFACE_FLAG_UNNUMBERED
@ VNET_SW_INTERFACE_FLAG_UNNUMBERED
Definition: interface.h:851
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:1015
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:789
arp_reply
static uword arp_reply(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
Definition: arp.c:389
vnet_sw_interface_t::unnumbered_sw_if_index
u32 unnumbered_sw_if_index
Definition: interface.h:884
ethernet_arp_error_strings
static char * ethernet_arp_error_strings[]
Definition: arp.c:681
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:165
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:288
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:48
VLIB_INIT_FUNCTION
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:172
arp_disabled_next_t_
arp_disabled_next_t_
Definition: arp.c:286
FOR_EACH_SRC_ADDED
#define FOR_EACH_SRC_ADDED(_entry, _src, _source, action)
Definition: fib_entry_src.h:218
ip4_fib_table_lookup
#define ip4_fib_table_lookup
Definition: ip4_fib.h:68
pg_ethernet_arp_header_t::opcode
pg_edit_t opcode
Definition: arp.c:780
si
vnet_sw_interface_t * si
Definition: interface_output.c:418
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:128
arp_input_node
static vlib_node_registration_t arp_input_node
(constructor) VLIB_REGISTER_NODE (arp_input_node)
Definition: arp.c:689
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:96
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:213
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:705
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:419
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:409
i
int i
Definition: flowhash_template.h:376
ARP_INPUT_NEXT_DISABLED
@ ARP_INPUT_NEXT_DISABLED
Definition: arp.c:212
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:65
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:860
ARP_DST_FIB_NONE
@ ARP_DST_FIB_NONE
Definition: arp.c:358
vlib_node_runtime_t
Definition: node.h:454
arp_disabled_error_t
arp_disabled_error_t
Definition: arp.c:295
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:190
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:360
ethernet_register_input_type
void ethernet_register_input_type(vlib_main_t *vm, ethernet_type_t type, u32 node_index)
Definition: node.c:2274
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:137
foreach_arp_disabled_error
#define foreach_arp_disabled_error
Definition: arp.c:292
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:845
flags
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:105