FD.io VPP  v21.10.1-2-g0a485f517
Vector Packet Processing
ip_neighbor.c
Go to the documentation of this file.
1 /*
2  * src/vnet/ip/ip_neighboor.c: ip neighbor generic handling
3  *
4  * Copyright (c) 2018 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 <vppinfra/llist.h>
19 
24 
25 #include <vnet/ip/ip6_ll_table.h>
26 #include <vnet/ip/ip46_address.h>
27 #include <vnet/fib/fib_table.h>
28 #include <vnet/adj/adj_mcast.h>
29 
30 /** Pool for All IP neighbors */
32 
33 /** protocol specific lists of time sorted neighbors */
35 
36 typedef struct ip_neighbor_elt_t_
37 {
41 
42 /** Pool of linked list elemeents */
44 
45 typedef struct ip_neighbor_db_t_
46 {
47  /** per interface hash */
49  /** per-protocol limit - max number of neighbors*/
51  /** max age of a neighbor before it's forcibly evicted */
53  /** when the limit is reached and new neighbors are created, should
54  * we recycle an old one */
56  /** per-protocol number of elements */
58  /** per-protocol number of elements per-fib-index*/
61 
63 
64 /* DBs of neighbours one per AF */
65 /* *INDENT-OFF* */
67  [AF_IP4] = {
68  .ipndb_limit = 50000,
69  /* Default to not aging and not recycling */
70  .ipndb_age = 0,
71  .ipndb_recycle = false,
72  },
73  [AF_IP6] = {
74  .ipndb_limit = 50000,
75  /* Default to not aging and not recycling */
76  .ipndb_age = 0,
77  .ipndb_recycle = false,
78  }
79 };
80 /* *INDENT-ON* */
81 
82 #define IP_NEIGHBOR_DBG(...) \
83  vlib_log_debug (ipn_logger, __VA_ARGS__);
84 
85 #define IP_NEIGHBOR_INFO(...) \
86  vlib_log_notice (ipn_logger, __VA_ARGS__);
87 
90 {
92  return (NULL);
93 
94  return (pool_elt_at_index (ip_neighbor_pool, ipni));
95 }
96 
97 static index_t
99 {
100  return (ipn - ip_neighbor_pool);
101 }
102 
103 static void
105 {
106  ipn->ipn_flags &= ~IP_NEIGHBOR_FLAG_STALE;
107 }
108 
109 static bool
111 {
112  return (ipn->ipn_flags & IP_NEIGHBOR_FLAG_DYNAMIC);
113 }
114 
115 const ip_address_t *
117 {
118  return (&ipn->ipn_key->ipnk_ip);
119 }
120 
123 {
124  return (ip_addr_version (&ipn->ipn_key->ipnk_ip));
125 }
126 
127 const mac_address_t *
129 {
130  return (&ipn->ipn_mac);
131 }
132 
133 const u32
135 {
136  return (ipn->ipn_key->ipnk_sw_if_index);
137 }
138 
139 static void
141 {
142  /* new neighbours, are added to the head of the list, since the
143  * list is time sorted, newest first */
145 
146  if (~0 != ipn->ipn_elt)
147  {
149 
151 
152  ipn->ipn_elt = ~0;
153  }
154 }
155 
156 static void
158 {
159  /* new neighbours, are added to the head of the list, since the
160  * list is time sorted, newest first */
161  ip_neighbor_elt_t *elt, *head;
162 
163  ip_neighbor_touch (ipn);
165  ipn->ipn_n_probes = 0;
166 
167  if (ip_neighbor_is_dynamic (ipn))
168  {
169  if (~0 == ipn->ipn_elt)
170  /* first time insertion */
172  else
173  {
174  /* already inserted - extract first */
176 
178  }
181  (ipn)]);
182 
183  elt->ipne_index = ip_neighbor_get_index (ipn);
184  clib_llist_add (ip_neighbor_elt_pool, ipne_anchor, elt, head);
186  }
187 }
188 
189 static void
191 {
194 
195  af = ip_neighbor_get_af (ipn);
197 
198  vec_validate (ip_neighbor_db[af].ipndb_hash, sw_if_index);
199 
200  if (!ip_neighbor_db[af].ipndb_hash[sw_if_index])
202  = hash_create_mem (0, sizeof (ip_neighbor_key_t), sizeof (index_t));
203 
205  ipn->ipn_key, ip_neighbor_get_index (ipn));
206 
208 }
209 
210 static void
212 {
215 
216  af = ip_neighbor_get_af (ipn);
218 
219  vec_validate (ip_neighbor_db[af].ipndb_hash, sw_if_index);
220 
221  hash_unset_mem (ip_neighbor_db[af].ipndb_hash[sw_if_index], ipn->ipn_key);
222 
224 }
225 
226 static ip_neighbor_t *
228 {
230  uword *p;
231 
232  af = ip_addr_version (&key->ipnk_ip);
233 
234  if (key->ipnk_sw_if_index >= vec_len (ip_neighbor_db[af].ipndb_hash))
235  return NULL;
236 
237  p = hash_get_mem (ip_neighbor_db[af].ipndb_hash
238  [key->ipnk_sw_if_index], key);
239 
240  if (p)
241  return ip_neighbor_get (p[0]);
242 
243  return (NULL);
244 }
245 
246 static u8
248 {
249  return (type == AF_IP4 ? 32 : 128);
250 }
251 
252 static void
254 {
256 
257  af = ip_neighbor_get_af (ipn);
258 
259  if (af == AF_IP6 &&
261  (&ipn->ipn_key->ipnk_ip)))
262  {
263  ip6_ll_prefix_t pfx = {
264  .ilp_addr = ip_addr_v6 (&ipn->ipn_key->ipnk_ip),
265  .ilp_sw_if_index = ipn->ipn_key->ipnk_sw_if_index,
266  };
267  ipn->ipn_fib_entry_index =
269  }
270  else
271  {
272  fib_protocol_t fproto;
273 
275 
276  fib_prefix_t pfx = {
278  .fp_proto = fproto,
279  .fp_addr = ip_addr_46 (&ipn->ipn_key->ipnk_ip),
280  };
281 
282  ipn->ipn_fib_entry_index =
283  fib_table_entry_path_add (fib_index, &pfx, FIB_SOURCE_ADJ,
285  fib_proto_to_dpo (fproto),
286  &pfx.fp_addr,
288  ~0, 1, NULL, FIB_ROUTE_PATH_FLAG_NONE);
289 
290  vec_validate (ip_neighbor_db[af].ipndb_n_elts_per_fib, fib_index);
291 
292  ip_neighbor_db[af].ipndb_n_elts_per_fib[fib_index]++;
293 
294  if (1 == ip_neighbor_db[af].ipndb_n_elts_per_fib[fib_index])
295  fib_table_lock (fib_index, fproto, FIB_SOURCE_ADJ);
296  }
297 }
298 
299 static void
301 {
303 
304  af = ip_neighbor_get_af (ipn);
305 
307  {
308  if (AF_IP6 == af &&
310  (&ipn->ipn_key->ipnk_ip)))
311  {
312  ip6_ll_prefix_t pfx = {
313  .ilp_addr = ip_addr_v6 (&ipn->ipn_key->ipnk_ip),
314  .ilp_sw_if_index = ipn->ipn_key->ipnk_sw_if_index,
315  };
317  }
318  else
319  {
320  fib_protocol_t fproto;
321 
323 
324  fib_prefix_t pfx = {
326  .fp_proto = fproto,
327  .fp_addr = ip_addr_46 (&ipn->ipn_key->ipnk_ip),
328  };
329 
330  fib_table_entry_path_remove (fib_index,
331  &pfx,
333  fib_proto_to_dpo (fproto),
334  &pfx.fp_addr,
336  ~0, 1, FIB_ROUTE_PATH_FLAG_NONE);
337 
338  ip_neighbor_db[af].ipndb_n_elts_per_fib[fib_index]--;
339 
340  if (0 == ip_neighbor_db[af].ipndb_n_elts_per_fib[fib_index])
341  fib_table_unlock (fib_index, fproto, FIB_SOURCE_ADJ);
342  }
343  }
344 }
345 
346 static void
348 {
351  ipn->
352  ipn_key->ipnk_sw_if_index,
353  adj_get_link_type (ai),
354  ipn->ipn_mac.bytes));
355 }
356 
357 static void
359 {
360  ip_adjacency_t *adj = adj_get (ai);
361 
365  adj->
366  rewrite_header.sw_if_index,
369 }
370 
371 static adj_walk_rc_t
373 {
374  ip_neighbor_t *ipn = ctx;
375 
376  ip_neighbor_mk_complete (ai, ipn);
377 
378  return (ADJ_WALK_RC_CONTINUE);
379 }
380 
381 static adj_walk_rc_t
383 {
385 
386  return (ADJ_WALK_RC_CONTINUE);
387 }
388 
389 static void
391 {
393 
394  af = ip_neighbor_get_af (ipn);
395 
396  IP_NEIGHBOR_DBG ("free: %U", format_ip_neighbor,
397  ip_neighbor_get_index (ipn));
398 
401 
404  &ip_addr_46 (&ipn->ipn_key->ipnk_ip),
407  (ipn,
410 
412  ip_neighbor_db_remove (ipn);
413  clib_mem_free (ipn->ipn_key);
414 
415  pool_put (ip_neighbor_pool, ipn);
416 }
417 
418 static bool
420 {
421  if (!ip_neighbor_db[af].ipndb_recycle)
422  return false;
423 
424  /* pluck the oldest entry, which is the one from the end of the list */
425  ip_neighbor_elt_t *elt, *head;
426 
428 
429  if (clib_llist_is_empty (ip_neighbor_elt_pool, ipne_anchor, head))
430  return (false);
431 
432  elt = clib_llist_prev (ip_neighbor_elt_pool, ipne_anchor, head);
433  ip_neighbor_destroy (ip_neighbor_get (elt->ipne_index));
434 
435  return (true);
436 }
437 
438 static ip_neighbor_t *
441 {
443  ip_neighbor_t *ipn;
444 
445  af = ip_addr_version (&key->ipnk_ip);
446 
447  if (ip_neighbor_db[af].ipndb_limit &&
448  (ip_neighbor_db[af].ipndb_n_elts >= ip_neighbor_db[af].ipndb_limit))
449  {
451  return (NULL);
452  }
453 
455 
456  ipn->ipn_key = clib_mem_alloc (sizeof (*ipn->ipn_key));
457  clib_memcpy (ipn->ipn_key, key, sizeof (*ipn->ipn_key));
458 
460  ipn->ipn_flags = flags;
461  ipn->ipn_elt = ~0;
462 
463  mac_address_copy (&ipn->ipn_mac, mac);
464 
465  ip_neighbor_db_add (ipn);
466 
467  /* create the adj-fib. the entry in the FIB table for the peer's interface */
468  if (!(ipn->ipn_flags & IP_NEIGHBOR_FLAG_NO_FIB_ENTRY))
472 
473  return (ipn);
474 }
475 
476 int
478  const mac_address_t * mac,
481 {
482  fib_protocol_t fproto;
483  ip_neighbor_t *ipn;
484 
485  /* main thread only */
486  ASSERT (0 == vlib_get_thread_index ());
487 
489 
490  const ip_neighbor_key_t key = {
491  .ipnk_ip = *ip,
492  .ipnk_sw_if_index = sw_if_index,
493  };
494 
495  ipn = ip_neighbor_db_find (&key);
496 
497  if (ipn)
498  {
499  IP_NEIGHBOR_DBG ("update: %U, %U",
503  mac);
504 
505  ip_neighbor_touch (ipn);
506 
507  /* Refuse to over-write static neighbor entry. */
508  if (!(flags & IP_NEIGHBOR_FLAG_STATIC) &&
509  (ipn->ipn_flags & IP_NEIGHBOR_FLAG_STATIC))
510  {
511  /* if MAC address match, still check to send event */
512  if (0 == mac_address_cmp (&ipn->ipn_mac, mac))
513  goto check_customers;
514  return -2;
515  }
516 
517  /* A dynamic entry can become static, but not vice-versa.
518  * i.e. since if it was programmed by the CP then it must
519  * be removed by the CP */
520  if ((flags & IP_NEIGHBOR_FLAG_STATIC) &&
521  !(ipn->ipn_flags & IP_NEIGHBOR_FLAG_STATIC))
522  {
524  ipn->ipn_flags |= IP_NEIGHBOR_FLAG_STATIC;
525  ipn->ipn_flags &= ~IP_NEIGHBOR_FLAG_DYNAMIC;
526  }
527 
528  /*
529  * prevent a DoS attack from the data-plane that
530  * spams us with no-op updates to the MAC address
531  */
532  if (0 == mac_address_cmp (&ipn->ipn_mac, mac))
533  {
534  ip_neighbor_refresh (ipn);
535  goto check_customers;
536  }
537 
538  mac_address_copy (&ipn->ipn_mac, mac);
539  }
540  else
541  {
542  IP_NEIGHBOR_INFO ("add: %U, %U",
546  mac);
547 
548  ipn = ip_neighbor_alloc (&key, mac, flags);
549 
550  if (NULL == ipn)
551  return VNET_API_ERROR_LIMIT_EXCEEDED;
552  }
553 
554  /* Update time stamp and flags. */
555  ip_neighbor_refresh (ipn);
556 
558  fproto, &ip_addr_46 (&ipn->ipn_key->ipnk_ip),
560 
561 check_customers:
562  /* Customer(s) requesting event for this address? */
564 
565  if (stats_index)
566  *stats_index = adj_nbr_find (fproto,
567  fib_proto_to_link (fproto),
568  &ip_addr_46 (&ipn->ipn_key->ipnk_ip),
569  ipn->ipn_key->ipnk_sw_if_index);
570  return 0;
571 }
572 
573 int
575 {
576  ip_neighbor_t *ipn;
577 
578  /* main thread only */
579  ASSERT (0 == vlib_get_thread_index ());
580 
581  IP_NEIGHBOR_INFO ("delete: %U, %U",
584 
585  const ip_neighbor_key_t key = {
586  .ipnk_ip = *ip,
587  .ipnk_sw_if_index = sw_if_index,
588  };
589 
590  ipn = ip_neighbor_db_find (&key);
591 
592  if (NULL == ipn)
593  return (VNET_API_ERROR_NO_SUCH_ENTRY);
594 
595  ip_neighbor_destroy (ipn);
596 
597  return (0);
598 }
599 
601 {
604 
605 static walk_rc_t
607 {
609 
610  vec_add1 (ctx->ipn_del, ipni);
611 
612  return (WALK_CONTINUE);
613 }
614 
615 void
617 {
618  IP_NEIGHBOR_INFO ("delete-all: %U, %U",
621  sw_if_index);
622 
624  .ipn_del = NULL,
625  };
626  index_t *ipni;
627 
629 
630  vec_foreach (ipni,
631  ctx.ipn_del) ip_neighbor_destroy (ip_neighbor_get (*ipni));
632  vec_free (ctx.ipn_del);
633 }
634 
635 void
637 {
638  ip_neighbor_t *ipn;
639  ip_adjacency_t *adj;
640 
641  adj = adj_get (ai);
642 
644  .ipnk_sw_if_index = adj->rewrite_header.sw_if_index,
645  };
646 
647  ip_address_from_46 (&adj->sub_type.nbr.next_hop,
648  adj->ia_nh_proto, &key.ipnk_ip);
649 
650  ipn = ip_neighbor_db_find (&key);
651 
652  switch (adj->lookup_next_index)
653  {
654  case IP_LOOKUP_NEXT_ARP:
655  if (NULL != ipn)
656  {
657  adj_nbr_walk_nh (adj->rewrite_header.sw_if_index,
658  adj->ia_nh_proto,
659  &adj->sub_type.nbr.next_hop,
661  }
662  else
663  {
664  /*
665  * no matching ARP entry.
666  * construct the rewrite required to for an ARP packet, and stick
667  * that in the adj's pipe to smoke.
668  */
670  (ai,
673  (vnm,
674  adj->rewrite_header.sw_if_index,
677 
678  /*
679  * since the FIB has added this adj for a route, it makes sense it
680  * may want to forward traffic sometime soon. Let's send a
681  * speculative ARP. just one. If we were to do periodically that
682  * wouldn't be bad either, but that's more code than i'm prepared to
683  * write at this time for relatively little reward.
684  */
685  /*
686  * adj_nbr_update_rewrite may actually call fib_walk_sync.
687  * fib_walk_sync may allocate a new adjacency and potentially cause
688  * a realloc for adj_pool. When that happens, adj pointer is no
689  * longer valid here.x We refresh adj pointer accordingly.
690  */
691  adj = adj_get (ai);
692  ip_neighbor_probe (adj);
693  }
694  break;
696  /* Update of an existing rewrite adjacency happens e.g. when the
697  * interface's MAC address changes */
698  if (NULL != ipn)
699  ip_neighbor_mk_complete (ai, ipn);
700  break;
704  case IP_LOOKUP_NEXT_DROP:
705  case IP_LOOKUP_NEXT_PUNT:
710  case IP_LOOKUP_N_NEXT:
711  ASSERT (0);
712  break;
713  }
714 }
715 
716 void
718 {
719  ip_neighbor_add (&l->ip, &l->mac, l->sw_if_index,
720  IP_NEIGHBOR_FLAG_DYNAMIC, NULL);
721 }
722 
723 static clib_error_t *
725  unformat_input_t * input, vlib_cli_command_t * cmd)
726 {
729  vnet_main_t *vnm = vnet_get_main ();
731  u32 sw_if_index = ~0;
732  int is_add = 1;
733  int count = 1;
734 
735  flags = IP_NEIGHBOR_FLAG_DYNAMIC;
736 
738  {
739  /* set ip arp TenGigE1/1/0/1 1.2.3.4 aa:bb:... or aabb.ccdd... */
740  if (unformat (input, "%U %U %U",
743  ;
744  else if (unformat (input, "delete") || unformat (input, "del"))
745  is_add = 0;
746  else if (unformat (input, "static"))
747  {
748  flags |= IP_NEIGHBOR_FLAG_STATIC;
749  flags &= ~IP_NEIGHBOR_FLAG_DYNAMIC;
750  }
751  else if (unformat (input, "no-fib-entry"))
752  flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
753  else if (unformat (input, "count %d", &count))
754  ;
755  else
756  break;
757  }
758 
759  if (sw_if_index == ~0 ||
761  return clib_error_return (0,
762  "specify interface, IP address and MAC: `%U'",
763  format_unformat_error, input);
764 
765  while (count)
766  {
767  if (is_add)
768  ip_neighbor_add (&ip, &mac, sw_if_index, flags, NULL);
769  else
771 
774 
775  --count;
776  }
777 
778  return NULL;
779 }
780 
781 /* *INDENT-OFF* */
782 /*?
783  * Add or delete IPv4 ARP cache entries.
784  *
785  * @note 'set ip neighbor' options (e.g. delete, static, 'fib-id <id>',
786  * 'count <number>', 'interface ip4_addr mac_addr') can be added in
787  * any order and combination.
788  *
789  * @cliexpar
790  * @parblock
791  * Add or delete IPv4 ARP cache entries as follows. MAC Address can be in
792  * either aa:bb:cc:dd:ee:ff format or aabb.ccdd.eeff format.
793  * @cliexcmd{set ip neighbor GigabitEthernet2/0/0 6.0.0.3 dead.beef.babe}
794  * @cliexcmd{set ip neighbor delete GigabitEthernet2/0/0 6.0.0.3 de:ad:be:ef:ba:be}
795  *
796  * To add or delete an IPv4 ARP cache entry to or from a specific fib
797  * table:
798  * @cliexcmd{set ip neighbor fib-id 1 GigabitEthernet2/0/0 6.0.0.3 dead.beef.babe}
799  * @cliexcmd{set ip neighbor fib-id 1 delete GigabitEthernet2/0/0 6.0.0.3 dead.beef.babe}
800  *
801  * Add or delete IPv4 static ARP cache entries as follows:
802  * @cliexcmd{set ip neighbor static GigabitEthernet2/0/0 6.0.0.3 dead.beef.babe}
803  * @cliexcmd{set ip neighbor static delete GigabitEthernet2/0/0 6.0.0.3 dead.beef.babe}
804  *
805  * For testing / debugging purposes, the 'set ip neighbor' command can add or
806  * delete multiple entries. Supply the 'count N' parameter:
807  * @cliexcmd{set ip neighbor count 10 GigabitEthernet2/0/0 6.0.0.3 dead.beef.babe}
808  * @endparblock
809  ?*/
811  .path = "set ip neighbor",
812  .short_help =
813  "set ip neighbor [del] <intfc> <ip-address> <mac-address> [static] [no-fib-entry] [count <count>] [fib-id <fib-id>] [proxy <lo-addr> - <hi-addr>]",
814  .function = ip_neighbor_cmd,
815 };
817  .path = "ip neighbor",
818  .short_help =
819  "ip neighbor [del] <intfc> <ip-address> <mac-address> [static] [no-fib-entry] [count <count>] [fib-id <fib-id>] [proxy <lo-addr> - <hi-addr>]",
820  .function = ip_neighbor_cmd,
821 };
822 /* *INDENT-ON* */
823 
824 static int
825 ip_neighbor_sort (void *a1, void *a2)
826 {
827  index_t *ipni1 = a1, *ipni2 = a2;
828  ip_neighbor_t *ipn1, *ipn2;
829  int cmp;
830 
831  ipn1 = ip_neighbor_get (*ipni1);
832  ipn2 = ip_neighbor_get (*ipni2);
833 
835  ipn1->ipn_key->ipnk_sw_if_index,
836  ipn2->ipn_key->ipnk_sw_if_index);
837  if (!cmp)
838  cmp = ip_address_cmp (&ipn1->ipn_key->ipnk_ip, &ipn2->ipn_key->ipnk_ip);
839  return cmp;
840 }
841 
842 static index_t *
844 {
845  index_t *ipnis = NULL;
846  ip_neighbor_t *ipn;
847 
848  /* *INDENT-OFF* */
850  {
851  if ((sw_if_index == ~0 ||
853  (N_AF == af ||
854  ip_neighbor_get_af(ipn) == af))
855  vec_add1 (ipnis, ip_neighbor_get_index(ipn));
856  }
857 
858  /* *INDENT-ON* */
859 
860  if (ipnis)
862  return ipnis;
863 }
864 
865 static clib_error_t *
867  unformat_input_t * input,
869 {
870  ip_neighbor_elt_t *elt, *head;
871 
873 
874 
875  vlib_cli_output (vm, "%=12s%=40s%=6s%=20s%=24s", "Time", "IP",
876  "Flags", "Ethernet", "Interface");
877 
878  /* *INDENT-OFF*/
879  /* the list is time sorted, newest first, so start from the back
880  * and work forwards. Stop when we get to one that is alive */
882  ipne_anchor, head, elt,
883  ({
884  vlib_cli_output (vm, "%U", format_ip_neighbor, elt->ipne_index);
885  }));
886  /* *INDENT-ON*/
887 
888  return (NULL);
889 }
890 
891 static clib_error_t *
893  unformat_input_t * input,
895 {
896  index_t *ipni, *ipnis = NULL;
898 
899  /* Filter entries by interface if given. */
900  sw_if_index = ~0;
902  &sw_if_index);
903 
905 
906  if (ipnis)
907  vlib_cli_output (vm, "%=12s%=40s%=6s%=20s%=24s", "Time", "IP",
908  "Flags", "Ethernet", "Interface");
909 
910  vec_foreach (ipni, ipnis)
911  {
912  vlib_cli_output (vm, "%U", format_ip_neighbor, *ipni);
913  }
914  vec_free (ipnis);
915 
916  return (NULL);
917 }
918 
919 static clib_error_t *
921  unformat_input_t * input, vlib_cli_command_t * cmd)
922 {
923  return (ip_neighbor_show_i (vm, input, cmd, N_AF));
924 }
925 
926 static clib_error_t *
928  unformat_input_t * input, vlib_cli_command_t * cmd)
929 {
930  return (ip_neighbor_show_i (vm, input, cmd, AF_IP6));
931 }
932 
933 static clib_error_t *
935  unformat_input_t * input, vlib_cli_command_t * cmd)
936 {
937  return (ip_neighbor_show_i (vm, input, cmd, AF_IP4));
938 }
939 
940 static clib_error_t *
942  unformat_input_t * input, vlib_cli_command_t * cmd)
943 {
944  return (ip_neighbor_show_sorted_i (vm, input, cmd, AF_IP6));
945 }
946 
947 static clib_error_t *
949  unformat_input_t * input, vlib_cli_command_t * cmd)
950 {
951  return (ip_neighbor_show_sorted_i (vm, input, cmd, AF_IP4));
952 }
953 
954 /*?
955  * Display all the IP neighbor entries.
956  *
957  * @cliexpar
958  * Example of how to display the IPv4 ARP table:
959  * @cliexstart{show ip neighbor}
960  * Time FIB IP4 Flags Ethernet Interface
961  * 346.3028 0 6.1.1.3 de:ad:be:ef:ba:be GigabitEthernet2/0/0
962  * 3077.4271 0 6.1.1.4 S de:ad:be:ef:ff:ff GigabitEthernet2/0/0
963  * 2998.6409 1 6.2.2.3 de:ad:be:ef:00:01 GigabitEthernet2/0/0
964  * Proxy arps enabled for:
965  * Fib_index 0 6.0.0.1 - 6.0.0.11
966  * @cliexend
967  ?*/
968 /* *INDENT-OFF* */
970  .path = "show ip neighbors",
971  .function = ip_neighbor_show,
972  .short_help = "show ip neighbors [interface]",
973 };
975  .path = "show ip4 neighbors",
976  .function = ip4_neighbor_show,
977  .short_help = "show ip4 neighbors [interface]",
978 };
980  .path = "show ip6 neighbors",
981  .function = ip6_neighbor_show,
982  .short_help = "show ip6 neighbors [interface]",
983 };
985  .path = "show ip neighbor",
986  .function = ip_neighbor_show,
987  .short_help = "show ip neighbor [interface]",
988 };
990  .path = "show ip4 neighbor",
991  .function = ip4_neighbor_show,
992  .short_help = "show ip4 neighbor [interface]",
993 };
995  .path = "show ip6 neighbor",
996  .function = ip6_neighbor_show,
997  .short_help = "show ip6 neighbor [interface]",
998 };
1000  .path = "show ip4 neighbor-sorted",
1001  .function = ip4_neighbor_show_sorted,
1002  .short_help = "show ip4 neighbor-sorted",
1003 };
1005  .path = "show ip6 neighbor-sorted",
1006  .function = ip6_neighbor_show_sorted,
1007  .short_help = "show ip6 neighbor-sorted",
1008 };
1009 /* *INDENT-ON* */
1010 
1012 
1013 void
1015 {
1016  ip_nbr_vfts[af] = *vft;
1017 }
1018 
1019 void
1021  ip_address_family_t af, const ip46_address_t * dst)
1022 {
1024  return;
1025 
1026  switch (af)
1027  {
1028  case AF_IP6:
1030  break;
1031  case AF_IP4:
1033  break;
1034  }
1035 }
1036 
1037 void
1039 {
1040  ip_neighbor_probe_dst (adj->rewrite_header.sw_if_index,
1042  &adj->sub_type.nbr.next_hop);
1043 }
1044 
1045 void
1048 {
1050  index_t ipni;
1051 
1052  if (~0 == sw_if_index)
1053  {
1054  uword **hash;
1055 
1056  vec_foreach (hash, ip_neighbor_db[af].ipndb_hash)
1057  {
1058  /* *INDENT-OFF* */
1059  hash_foreach (key, ipni, *hash,
1060  ({
1061  if (WALK_STOP == cb (ipni, ctx))
1062  break;
1063  }));
1064  /* *INDENT-ON* */
1065  }
1066  }
1067  else
1068  {
1069  uword *hash;
1070 
1071  if (vec_len (ip_neighbor_db[af].ipndb_hash) <= sw_if_index)
1072  return;
1074 
1075  /* *INDENT-OFF* */
1076  hash_foreach (key, ipni, hash,
1077  ({
1078  if (WALK_STOP == cb (ipni, ctx))
1079  break;
1080  }));
1081  /* *INDENT-ON* */
1082  }
1083 }
1084 
1085 int
1087  const ip4_address_t * start,
1088  const ip4_address_t * end)
1089 {
1090  if (ip_nbr_vfts[AF_IP4].inv_proxy4_add)
1091  {
1092  return (ip_nbr_vfts[AF_IP4].inv_proxy4_add (fib_index, start, end));
1093  }
1094 
1095  return (-1);
1096 }
1097 
1098 int
1100  const ip4_address_t * start,
1101  const ip4_address_t * end)
1102 {
1103  if (ip_nbr_vfts[AF_IP4].inv_proxy4_del)
1104  {
1105  return (ip_nbr_vfts[AF_IP4].inv_proxy4_del (fib_index, start, end));
1106  }
1107  return -1;
1108 }
1109 
1110 int
1112 {
1113  if (ip_nbr_vfts[AF_IP4].inv_proxy4_enable)
1114  {
1115  return (ip_nbr_vfts[AF_IP4].inv_proxy4_enable (sw_if_index));
1116  }
1117  return -1;
1118 }
1119 
1120 int
1122 {
1123  if (ip_nbr_vfts[AF_IP4].inv_proxy4_disable)
1124  {
1125  return (ip_nbr_vfts[AF_IP4].inv_proxy4_disable (sw_if_index));
1126  }
1127  return -1;
1128 }
1129 
1130 int
1131 ip6_neighbor_proxy_add (u32 sw_if_index, const ip6_address_t * addr)
1132 {
1133  if (ip_nbr_vfts[AF_IP6].inv_proxy6_add)
1134  {
1135  return (ip_nbr_vfts[AF_IP6].inv_proxy6_add (sw_if_index, addr));
1136  }
1137  return -1;
1138 }
1139 
1140 int
1141 ip6_neighbor_proxy_del (u32 sw_if_index, const ip6_address_t * addr)
1142 {
1143  if (ip_nbr_vfts[AF_IP6].inv_proxy6_del)
1144  {
1145  return (ip_nbr_vfts[AF_IP6].inv_proxy6_del (sw_if_index, addr));
1146  }
1147  return -1;
1148 }
1149 
1150 void
1152 {
1153  index_t *ipnis = NULL, *ipni;
1154  ip_neighbor_t *ipn;
1155 
1156  IP_NEIGHBOR_DBG ("populate: %U %U",
1159 
1160  /* *INDENT-OFF* */
1162  {
1163  if (ip_neighbor_get_af(ipn) == af &&
1165  vec_add1 (ipnis, ipn - ip_neighbor_pool);
1166  }
1167  /* *INDENT-ON* */
1168 
1169  vec_foreach (ipni, ipnis)
1170  {
1171  ipn = ip_neighbor_get (*ipni);
1172 
1175  (ipn)),
1176  &ip_addr_46 (&ipn->ipn_key->ipnk_ip),
1178  }
1179  vec_free (ipnis);
1180 }
1181 
1182 void
1184 {
1185  index_t *ipnis = NULL, *ipni;
1186  ip_neighbor_t *ipn;
1187 
1188 
1189  IP_NEIGHBOR_DBG ("flush: %U %U",
1192 
1193  /* *INDENT-OFF* */
1195  {
1196  if (ip_neighbor_get_af(ipn) == af &&
1198  ip_neighbor_is_dynamic (ipn))
1199  vec_add1 (ipnis, ipn - ip_neighbor_pool);
1200  }
1201  /* *INDENT-ON* */
1202 
1203  vec_foreach (ipni, ipnis) ip_neighbor_destroy (ip_neighbor_get (*ipni));
1204  vec_free (ipnis);
1205 }
1206 
1207 static walk_rc_t
1209 {
1210  ip_neighbor_t *ipn;
1211 
1212  ipn = ip_neighbor_get (ipni);
1213 
1214  ipn->ipn_flags |= IP_NEIGHBOR_FLAG_STALE;
1215 
1216  return (WALK_CONTINUE);
1217 }
1218 
1219 void
1221 {
1223 }
1224 
1226 {
1229 
1230 static walk_rc_t
1232 {
1234  ip_neighbor_t *ipn;
1235 
1236  ipn = ip_neighbor_get (ipni);
1237 
1238  if (ipn->ipn_flags & IP_NEIGHBOR_FLAG_STALE)
1239  {
1240  vec_add1 (ctx->ipnsc_stale, ipni);
1241  }
1242 
1243  return (WALK_CONTINUE);
1244 }
1245 
1246 void
1248 {
1250  index_t *ipni;
1251 
1253 
1254  vec_foreach (ipni, ctx.ipnsc_stale)
1255  {
1257  }
1258  vec_free (ctx.ipnsc_stale);
1259 }
1260 
1261 /*
1262  * Remove any arp entries associated with the specified interface
1263  */
1264 static clib_error_t *
1267 {
1269 
1270  IP_NEIGHBOR_DBG ("interface-admin: %U %s",
1272  sw_if_index,
1273  (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP ? "up" : "down"));
1274 
1276  {
1278  }
1279  else
1280  {
1281  /* admin down, flush all neighbours */
1283  }
1284 
1285  return (NULL);
1286 }
1287 
1289 
1290 /*
1291  * Remove any arp entries associated with the specified interface
1292  */
1293 static clib_error_t *
1295  u32 sw_if_index, u32 is_add)
1296 {
1297  IP_NEIGHBOR_DBG ("interface-change: %U %s",
1299  sw_if_index, (is_add ? "add" : "del"));
1300 
1301  if (!is_add && sw_if_index != ~0)
1302  {
1304 
1306  }
1307 
1308  return (NULL);
1309 }
1310 
1312 
1314 {
1319 
1320 static walk_rc_t
1322 {
1324  ip_neighbor_t *ipn;
1325 
1326  ipn = ip_neighbor_get (ipni);
1327 
1328  if (AF_IP4 == ip_addr_version (&ctx->addr))
1329  {
1331  &ip_addr_v4 (&ipn->ipn_key->ipnk_ip),
1332  &ip_addr_v4 (&ctx->addr),
1333  ctx->length) &&
1334  ip_neighbor_is_dynamic (ipn))
1335  {
1336  vec_add1 (ctx->ipnis, ip_neighbor_get_index (ipn));
1337  }
1338  }
1339  else if (AF_IP6 == ip_addr_version (&ctx->addr))
1340  {
1342  &ip_addr_v6 (&ipn->ipn_key->ipnk_ip),
1343  &ip_addr_v6 (&ctx->addr),
1344  ctx->length) &&
1345  ip_neighbor_is_dynamic (ipn))
1346  {
1347  vec_add1 (ctx->ipnis, ip_neighbor_get_index (ipn));
1348  }
1349  }
1350  return (WALK_CONTINUE);
1351 }
1352 
1353 
1354 /*
1355  * callback when an interface address is added or deleted
1356  */
1357 static void
1359  uword opaque,
1360  u32 sw_if_index,
1362  u32 address_length,
1363  u32 if_address_index, u32 is_del)
1364 {
1365  /*
1366  * Flush the ARP cache of all entries covered by the address
1367  * that is being removed.
1368  */
1369  IP_NEIGHBOR_DBG ("addr-%d: %U, %U/%d",
1370  (is_del ? "del" : "add"),
1372  sw_if_index, format_ip4_address, address, address_length);
1373 
1374  if (is_del)
1375  {
1376  /* *INDENT-OFF* */
1378  .addr = {
1379  .ip.ip4 = *address,
1380  .version = AF_IP4,
1381  },
1382  .length = address_length,
1383  };
1384  /* *INDENT-ON* */
1385  index_t *ipni;
1386 
1388 
1389  vec_foreach (ipni, ctx.ipnis)
1391 
1392  vec_free (ctx.ipnis);
1393  }
1394 }
1395 
1396 /*
1397  * callback when an interface address is added or deleted
1398  */
1399 static void
1401  uword opaque,
1402  u32 sw_if_index,
1403  ip6_address_t * address,
1404  u32 address_length,
1405  u32 if_address_index, u32 is_del)
1406 {
1407  /*
1408  * Flush the ARP cache of all entries covered by the address
1409  * that is being removed.
1410  */
1411  IP_NEIGHBOR_DBG ("addr-change: %U, %U/%d %s",
1413  sw_if_index, format_ip6_address, address, address_length,
1414  (is_del ? "del" : "add"));
1415 
1416  if (is_del)
1417  {
1418  /* *INDENT-OFF* */
1420  .addr = {
1421  .ip.ip6 = *address,
1422  .version = AF_IP6,
1423  },
1424  .length = address_length,
1425  };
1426  /* *INDENT-ON* */
1427  index_t *ipni;
1428 
1430 
1431  vec_foreach (ipni, ctx.ipnis)
1433 
1434  vec_free (ctx.ipnis);
1435  }
1436 }
1437 
1439 {
1443 
1444 static walk_rc_t
1446 {
1448  ip_neighbor_t *ipn;
1449 
1450  ipn = ip_neighbor_get (ipni);
1451  ip_neighbor_adj_fib_remove (ipn, ctx->old_fib_index);
1452  ip_neighbor_adj_fib_add (ipn, ctx->new_fib_index);
1453 
1454  return (WALK_CONTINUE);
1455 }
1456 
1457 static void
1459  uword opaque,
1460  u32 sw_if_index,
1461  u32 new_fib_index, u32 old_fib_index)
1462 {
1464  .old_fib_index = old_fib_index,
1465  .new_fib_index = new_fib_index,
1466  };
1467 
1469 }
1470 
1471 static void
1473  uword opaque,
1474  u32 sw_if_index,
1475  u32 new_fib_index, u32 old_fib_index)
1476 {
1478  .old_fib_index = old_fib_index,
1479  .new_fib_index = new_fib_index,
1480  };
1481 
1483 }
1484 
1486 {
1491 
1492 #define IP_NEIGHBOR_PROCESS_SLEEP_LONG (0)
1493 
1496 {
1498  ip_neighbor_t *ipn;
1499  u32 ipndb_age;
1500  u32 ttl;
1501 
1502  ipn = ip_neighbor_get (ipni);
1503  af = ip_neighbor_get_af (ipn);
1504  ipndb_age = ip_neighbor_db[af].ipndb_age;
1505  ttl = now - ipn->ipn_time_last_updated;
1506  *wait = ipndb_age;
1507 
1508  if (ttl > ipndb_age)
1509  {
1510  IP_NEIGHBOR_DBG ("aged: %U @%f - %f > %d",
1511  format_ip_neighbor, ipni, now,
1512  ipn->ipn_time_last_updated, ipndb_age);
1513  if (ipn->ipn_n_probes > 2)
1514  {
1515  /* 3 strikes and yea-re out */
1516  IP_NEIGHBOR_DBG ("dead: %U", format_ip_neighbor, ipni);
1517  *wait = 1;
1518  return (IP_NEIGHBOR_AGE_DEAD);
1519  }
1520  else
1521  {
1523  af, &ip_addr_46 (&ipn->ipn_key->ipnk_ip));
1524 
1525  ipn->ipn_n_probes++;
1526  *wait = 1;
1527  }
1528  }
1529  else
1530  {
1531  /* here we are sure that ttl <= ipndb_age */
1532  *wait = ipndb_age - ttl + 1;
1533  return (IP_NEIGHBOR_AGE_ALIVE);
1534  }
1535 
1536  return (IP_NEIGHBOR_AGE_PROBE);
1537 }
1538 
1540 {
1543 
1544 static uword
1548 {
1549  uword event_type, *event_data = NULL;
1550  f64 timeout;
1551 
1552  /* Set the timeout to an effectively infinite value when the process starts */
1554 
1555  while (1)
1556  {
1557  f64 now;
1558 
1559  if (!timeout)
1561  else
1563 
1564  event_type = vlib_process_get_events (vm, &event_data);
1565  vec_reset_length (event_data);
1566 
1567  now = vlib_time_now (vm);
1568 
1569  switch (event_type)
1570  {
1571  case ~0:
1572  {
1573  /* timer expired */
1574  ip_neighbor_elt_t *elt, *head;
1575  f64 wait;
1576 
1577  timeout = ip_neighbor_db[af].ipndb_age;
1580 
1581  /* *INDENT-OFF*/
1582  /* the list is time sorted, newest first, so start from the back
1583  * and work forwards. Stop when we get to one that is alive */
1584  restart:
1586  ipne_anchor, head, elt,
1587  ({
1589 
1590  res = ip_neighbour_age_out(elt->ipne_index, now, &wait);
1591 
1592  if (IP_NEIGHBOR_AGE_ALIVE == res) {
1593  /* the oldest neighbor has not yet expired, go back to sleep */
1594  timeout = clib_min (wait, timeout);
1595  break;
1596  }
1597  else if (IP_NEIGHBOR_AGE_DEAD == res) {
1598  /* the oldest neighbor is dead, pop it, then restart the walk
1599  * again from the back */
1600  ip_neighbor_destroy (ip_neighbor_get(elt->ipne_index));
1601  goto restart;
1602  }
1603 
1604  timeout = clib_min (wait, timeout);
1605  }));
1606  /* *INDENT-ON* */
1607  break;
1608  }
1610  {
1611 
1612  if (!ip_neighbor_db[af].ipndb_age)
1613  {
1614  /* aging has been disabled */
1615  timeout = 0;
1616  break;
1617  }
1618  ip_neighbor_elt_t *elt, *head;
1619 
1622  /* no neighbors yet */
1623  if (clib_llist_is_empty (ip_neighbor_elt_pool, ipne_anchor, head))
1624  {
1625  timeout = ip_neighbor_db[af].ipndb_age;
1626  break;
1627  }
1628 
1629  /* poke the oldset neighbour for aging, which returns how long we sleep for */
1630  elt = clib_llist_prev (ip_neighbor_elt_pool, ipne_anchor, head);
1631  ip_neighbour_age_out (elt->ipne_index, now, &timeout);
1632  break;
1633  }
1634  }
1635  }
1636  return 0;
1637 }
1638 
1639 static uword
1642 {
1643  return (ip_neighbor_age_loop (vm, rt, f, AF_IP4));
1644 }
1645 
1646 static uword
1649 {
1650  return (ip_neighbor_age_loop (vm, rt, f, AF_IP6));
1651 }
1652 
1653 /* *INDENT-OFF* */
1655  .function = ip4_neighbor_age_process,
1656  .type = VLIB_NODE_TYPE_PROCESS,
1657  .name = "ip4-neighbor-age-process",
1658 };
1660  .function = ip6_neighbor_age_process,
1661  .type = VLIB_NODE_TYPE_PROCESS,
1662  .name = "ip6-neighbor-age-process",
1663 };
1664 /* *INDENT-ON* */
1665 
1666 int
1667 ip_neighbor_config (ip_address_family_t af, u32 limit, u32 age, bool recycle)
1668 {
1669  ip_neighbor_db[af].ipndb_limit = limit;
1670  ip_neighbor_db[af].ipndb_recycle = recycle;
1671  ip_neighbor_db[af].ipndb_age = age;
1672 
1674  (AF_IP4 == af ?
1678 
1679  return (0);
1680 }
1681 
1682 static clib_error_t *
1684  unformat_input_t * input, vlib_cli_command_t * cmd)
1685 {
1687 
1688  /* *INDENT-OFF* */
1691  vlib_cli_output (vm, " limit:%d, age:%d, recycle:%d",
1692  ip_neighbor_db[af].ipndb_limit,
1693  ip_neighbor_db[af].ipndb_age,
1694  ip_neighbor_db[af].ipndb_recycle);
1695  }
1696 
1697  /* *INDENT-ON* */
1698  return (NULL);
1699 }
1700 
1701 static clib_error_t *
1703  vlib_cli_command_t *cmd)
1704 {
1705  unformat_input_t _line_input, *line_input = &_line_input;
1706  clib_error_t *error = NULL;
1708  u32 limit, age;
1709  bool recycle;
1710 
1711  if (!unformat_user (input, unformat_line_input, line_input))
1712  return 0;
1713 
1714  if (!unformat (line_input, "%U", unformat_ip_address_family, &af))
1715  {
1716  error = unformat_parse_error (line_input);
1717  goto done;
1718  }
1719 
1720  limit = ip_neighbor_db[af].ipndb_limit;
1721  age = ip_neighbor_db[af].ipndb_age;
1722  recycle = ip_neighbor_db[af].ipndb_recycle;
1723 
1724  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1725  {
1726  if (unformat (line_input, "limit %u", &limit))
1727  ;
1728  else if (unformat (line_input, "age %u", &age))
1729  ;
1730  else if (unformat (line_input, "recycle"))
1731  recycle = true;
1732  else if (unformat (line_input, "norecycle"))
1733  recycle = false;
1734  else
1735  {
1736  error = unformat_parse_error (line_input);
1737  goto done;
1738  }
1739  }
1740 
1741  ip_neighbor_config (af, limit, age, recycle);
1742 
1743 done:
1744  unformat_free (line_input);
1745  return error;
1746 }
1747 
1748 /* *INDENT-OFF* */
1750  .path = "show ip neighbor-config",
1751  .function = ip_neighbor_config_show,
1752  .short_help = "show ip neighbor-config",
1753 };
1755  .path = "set ip neighbor-config",
1756  .function = ip_neighbor_config_set,
1757  .short_help = "set ip neighbor-config ip4|ip6 [limit <limit>] [age <age>] "
1758  "[recycle|norecycle]",
1759 };
1760 /* *INDENT-ON* */
1761 
1762 static clib_error_t *
1764 {
1765  {
1768  };
1770  }
1771  {
1774  };
1776  }
1777  {
1780  };
1782  }
1783  {
1786  };
1788  }
1789  ipn_logger = vlib_log_register_class ("ip", "neighbor");
1790 
1792 
1796 
1797  return (NULL);
1798 }
1799 
1800 /* *INDENT-OFF* */
1802 {
1803  .runs_after = VLIB_INITS("ip_main_init"),
1804 };
1805 /* *INDENT-ON* */
1806 
1807 /*
1808  * fd.io coding-style-patch-verification: ON
1809  *
1810  * Local Variables:
1811  * eval: (c-set-style "gnu")
1812  * End:
1813  */
ip_neighbor_t_
A representation of an IP neighbour/peer.
Definition: ip_neighbor_types.h:59
vec_reset_length
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
Definition: vec_bootstrap.h:194
ADJ_NBR_REWRITE_FLAG_INCOMPLETE
@ ADJ_NBR_REWRITE_FLAG_INCOMPLETE
An indication that the rewrite is incomplete, i.e.
Definition: adj_nbr.h:97
stats_index
u32 stats_index
Definition: ip.api:174
ip_neighbor_get_af
ip_address_family_t ip_neighbor_get_af(const ip_neighbor_t *ipn)
Definition: ip_neighbor.c:122
ip_address
Definition: ip_types.h:79
ip_neighbor_alloc
static ip_neighbor_t * ip_neighbor_alloc(const ip_neighbor_key_t *key, const mac_address_t *mac, ip_neighbor_flags_t flags)
Definition: ip_neighbor.c:439
ip_neighbor_sweep_ctx_t_
Definition: ip_neighbor.c:1225
ip6_address_is_link_local_unicast
static uword ip6_address_is_link_local_unicast(const ip6_address_t *a)
Definition: ip6_packet.h:253
ip_neighbor_db_t_::ipndb_n_elts
u32 ipndb_n_elts
per-protocol number of elements
Definition: ip_neighbor.c:57
fib_table_entry_path_add
fib_node_index_t fib_table_entry_path_add(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags, dpo_proto_t next_hop_proto, const ip46_address_t *next_hop, u32 next_hop_sw_if_index, u32 next_hop_fib_index, u32 next_hop_weight, fib_mpls_label_t *next_hop_labels, fib_route_path_flags_t path_flags)
Add one path to an entry (aka route) in the FIB.
Definition: fib_table.c:563
ip_neighbor_mk_complete_walk
static adj_walk_rc_t ip_neighbor_mk_complete_walk(adj_index_t ai, void *ctx)
Definition: ip_neighbor.c:372
im
vnet_interface_main_t * im
Definition: interface_output.c:415
ip_addr_46
#define ip_addr_46(_a)
Definition: ip_types.h:90
ip_adjacency_t_::ia_nh_proto
fib_protocol_t ia_nh_proto
The protocol of the neighbor/peer.
Definition: adj.h:350
ip_neighbor_db_t_::ipndb_recycle
bool ipndb_recycle
when the limit is reached and new neighbors are created, should we recycle an old one
Definition: ip_neighbor.c:55
IP_LOOKUP_NEXT_ARP
@ IP_LOOKUP_NEXT_ARP
This packet matches an "incomplete adjacency" and packets need to be passed to ARP to find rewrite st...
Definition: adj.h:63
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
ip_neighbor_t_::ipn_fib_entry_index
fib_node_index_t ipn_fib_entry_index
The index of the adj fib created for this neighbour.
Definition: ip_neighbor_types.h:88
VNET_REWRITE_FOR_SW_INTERFACE_ADDRESS_BROADCAST
#define VNET_REWRITE_FOR_SW_INTERFACE_ADDRESS_BROADCAST
Definition: rewrite.h:241
ethernet_build_rewrite
u8 * ethernet_build_rewrite(vnet_main_t *vnm, u32 sw_if_index, vnet_link_t link_type, const void *dst_address)
build a rewrite string to use for sending packets of type 'link_type' to 'dst_address'
Definition: interface.c:83
ip_neighbor_db_t_
Definition: ip_neighbor.c:45
WALK_CONTINUE
@ WALK_CONTINUE
Definition: interface_funcs.h:174
clib_llist_remove
#define clib_llist_remove(LP, name, E)
Remove entry from list.
Definition: llist.h:231
ip_neighbor_show
static clib_error_t * ip_neighbor_show(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ip_neighbor.c:920
ip_neighbor_elt_t_
Definition: ip_neighbor.c:36
ip_neighbor_get_ip
const ip_address_t * ip_neighbor_get_ip(const ip_neighbor_t *ipn)
Definition: ip_neighbor.c:116
ip_neighbor_walk_covered_ctx_t_::ipnis
index_t * ipnis
Definition: ip_neighbor.c:1317
ip4_neighbor.h
format_ip4_address
format_function_t format_ip4_address
Definition: format.h:73
ip6_neighbor_show_sorted
static clib_error_t * ip6_neighbor_show_sorted(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ip_neighbor.c:941
clib_memcpy
#define clib_memcpy(d, s, n)
Definition: string.h:197
ip_neighbor_vft_t_
Virtual function Table for neighbor protocol implementations to register.
Definition: ip_neighbor.h:101
ip4_neighbor_age_process
static uword ip4_neighbor_age_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
Definition: ip_neighbor.c:1640
ip4_main_t::table_bind_callbacks
ip4_table_bind_callback_t * table_bind_callbacks
Functions to call when interface to table biding changes.
Definition: ip4.h:145
ip4_main
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:1104
show_ip6_neighbor_sorted_cmd_node
static vlib_cli_command_t show_ip6_neighbor_sorted_cmd_node
(constructor) VLIB_CLI_COMMAND (show_ip6_neighbor_sorted_cmd_node)
Definition: ip_neighbor.c:1004
IP_NEIGHBOR_AGE_DEAD
@ IP_NEIGHBOR_AGE_DEAD
Definition: ip_neighbor.c:1489
vlib_process_wait_for_event
static uword * vlib_process_wait_for_event(vlib_main_t *vm)
Definition: node_funcs.h:660
ip_neighbor_adj_fib_remove
static void ip_neighbor_adj_fib_remove(ip_neighbor_t *ipn, u32 fib_index)
Definition: ip_neighbor.c:300
f
vlib_frame_t * f
Definition: interface_output.c:1098
ip_neighbor_t_::ipn_n_probes
u8 ipn_n_probes
Definition: ip_neighbor_types.h:82
ip_neighbor_age_loop
static uword ip_neighbor_age_loop(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f, ip_address_family_t af)
Definition: ip_neighbor.c:1545
ip_neighbor_config
int ip_neighbor_config(ip_address_family_t af, u32 limit, u32 age, bool recycle)
Definition: ip_neighbor.c:1667
unformat_line_input
unformat_function_t unformat_line_input
Definition: format.h:275
pool_elt_at_index
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:549
vlib_log_class_t
u32 vlib_log_class_t
Definition: vlib.h:52
ip4_add_del_interface_address_callback_t
Definition: ip4.h:73
ip_neighbor_sweep_ctx_t
struct ip_neighbor_sweep_ctx_t_ ip_neighbor_sweep_ctx_t
ip_neighbor_db_t
struct ip_neighbor_db_t_ ip_neighbor_db_t
ip_neighbor_get
ip_neighbor_t * ip_neighbor_get(index_t ipni)
Definition: ip_neighbor.c:89
ttl
u8 ttl
Definition: fib_types.api:26
clib_llist_add
#define clib_llist_add(LP, name, E, H)
Add entry after head.
Definition: llist.h:210
clib_llist_anchor
Definition: llist.h:29
vlib_log_register_class
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
Definition: log.c:339
ip_neighbor_walk_covered_ctx_t_::length
u32 length
Definition: ip_neighbor.c:1316
clib_mem_free
static void clib_mem_free(void *p)
Definition: mem.h:314
ip_neighbor_db_find
static ip_neighbor_t * ip_neighbor_db_find(const ip_neighbor_key_t *key)
Definition: ip_neighbor.c:227
adj_walk_rc_t
enum adj_walk_rc_t_ adj_walk_rc_t
return codes from a adjacency walker callback function
IP_LOOKUP_NEXT_GLEAN
@ IP_LOOKUP_NEXT_GLEAN
This packet matches an "interface route" and packets need to be passed to ARP to find rewrite string ...
Definition: adj.h:68
adj_mcast.h
FIB_ENTRY_FLAG_ATTACHED
@ FIB_ENTRY_FLAG_ATTACHED
Definition: fib_entry.h:114
clib_error_return
#define clib_error_return(e, args...)
Definition: error.h:99
ip_neighbor_force_reuse
static bool ip_neighbor_force_reuse(ip_address_family_t af)
Definition: ip_neighbor.c:419
show_ip4_neighbor_sorted_cmd_node
static vlib_cli_command_t show_ip4_neighbor_sorted_cmd_node
(constructor) VLIB_CLI_COMMAND (show_ip4_neighbor_sorted_cmd_node)
Definition: ip_neighbor.c:999
ip_neighbor_config_show
static clib_error_t * ip_neighbor_config_show(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ip_neighbor.c:1683
ip_neighbor_process_event_t_
ip_neighbor_process_event_t_
Definition: ip_neighbor.c:1539
VNET_SW_INTERFACE_ADD_DEL_FUNCTION
VNET_SW_INTERFACE_ADD_DEL_FUNCTION(ip_neighbor_delete_sw_interface)
vlib_cli_command_t::path
char * path
Definition: cli.h:96
IP_NEIGHBOR_AGE_PROCESS_WAKEUP
@ IP_NEIGHBOR_AGE_PROCESS_WAKEUP
Definition: ip_neighbor.c:1541
ip_neighbor_db_t_::ipndb_age
u32 ipndb_age
max age of a neighbor before it's forcibly evicted
Definition: ip_neighbor.c:52
FIB_NODE_INDEX_INVALID
#define FIB_NODE_INDEX_INVALID
Definition: fib_types.h:30
hash_foreach
#define hash_foreach(key_var, value_var, h, body)
Definition: hash.h:441
fib_table.h
show_ip_neighbor_cmd_node
static vlib_cli_command_t show_ip_neighbor_cmd_node
(constructor) VLIB_CLI_COMMAND (show_ip_neighbor_cmd_node)
Definition: ip_neighbor.c:984
clib_llist_is_empty
#define clib_llist_is_empty(LP, name, H)
Check is list is empty.
Definition: llist.h:159
show_ip4_neighbors_cmd_node
static vlib_cli_command_t show_ip4_neighbors_cmd_node
(constructor) VLIB_CLI_COMMAND (show_ip4_neighbors_cmd_node)
Definition: ip_neighbor.c:974
ip_neighbor_del_all_ctx_t_
Definition: ip_neighbor.c:600
IP_LOOKUP_NEXT_LOCAL
@ IP_LOOKUP_NEXT_LOCAL
This packet is for one of our own IP addresses.
Definition: adj.h:58
FOR_EACH_IP_ADDRESS_FAMILY
#define FOR_EACH_IP_ADDRESS_FAMILY(_af)
Definition: ip_types.h:33
hash_set_mem
#define hash_set_mem(h, key, value)
Definition: hash.h:275
ip_neighbor_elt_t_::ipne_index
index_t ipne_index
Definition: ip_neighbor.c:39
ADJ_NBR_REWRITE_FLAG_COMPLETE
@ ADJ_NBR_REWRITE_FLAG_COMPLETE
An indication that the rewrite is complete, i.e.
Definition: adj_nbr.h:105
fib_prefix_t_::fp_len
u16 fp_len
The mask length.
Definition: fib_types.h:206
VNET_SW_INTERFACE_FLAG_ADMIN_UP
@ VNET_SW_INTERFACE_FLAG_ADMIN_UP
Definition: interface.h:844
pool_put
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:305
ip_neighbor_elt_pool
ip_neighbor_elt_t * ip_neighbor_elt_pool
Pool of linked list elemeents.
Definition: ip_neighbor.c:43
IP_LOOKUP_NEXT_MIDCHAIN
@ IP_LOOKUP_NEXT_MIDCHAIN
This packets follow a mid-chain adjacency.
Definition: adj.h:76
unformat_parse_error
#define unformat_parse_error(input)
Definition: format.h:261
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
AF_IP4
@ AF_IP4
Definition: ip_types.h:23
ip_neighbor_walk_cb_t
walk_rc_t(* ip_neighbor_walk_cb_t)(index_t ipni, void *ctx)
Definition: ip_neighbor.h:42
ZERO_MAC_ADDRESS
const mac_address_t ZERO_MAC_ADDRESS
Definition: mac_address.c:19
ip_neighbor_learn_t_
Definition: ip_neighbor_types.h:97
unformat_ip_address_family
uword unformat_ip_address_family(unformat_input_t *input, va_list *args)
Definition: ip.c:231
VNET_LINK_ARP
@ VNET_LINK_ARP
Definition: interface.h:351
ip_neighbor_age_state_t
enum ip_neighbor_age_state_t_ ip_neighbor_age_state_t
ip_nbr_vfts
static ip_neighbor_vft_t ip_nbr_vfts[N_AF]
Definition: ip_neighbor.c:1011
ip_neighbor_config_set
static clib_error_t * ip_neighbor_config_set(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ip_neighbor.c:1702
ip_neighbor_learn
void ip_neighbor_learn(const ip_neighbor_learn_t *l)
Definition: ip_neighbor.c:717
ip_neighbor_db_t_::ipndb_n_elts_per_fib
u32 * ipndb_n_elts_per_fib
per-protocol number of elements per-fib-index
Definition: ip_neighbor.c:59
format_ip_neighbor
u8 * format_ip_neighbor(u8 *s, va_list *va)
Definition: ip_neighbor_types.c:69
ip6_ll_table_entry_delete
void ip6_ll_table_entry_delete(const ip6_ll_prefix_t *ilp)
Delete a IP6 link-local entry.
Definition: ip6_ll_table.c:140
ip6_ll_table_entry_update
fib_node_index_t ip6_ll_table_entry_update(const ip6_ll_prefix_t *ilp, fib_route_path_flags_t flags)
Update an entry in the table.
Definition: ip6_ll_table.c:106
unformat_input_t
struct _unformat_input_t unformat_input_t
set_ip_neighbor_cfg_cmd_node
static vlib_cli_command_t set_ip_neighbor_cfg_cmd_node
(constructor) VLIB_CLI_COMMAND (set_ip_neighbor_cfg_cmd_node)
Definition: ip_neighbor.c:1754
addr
vhost_vring_addr_t addr
Definition: vhost_user.h:130
mac_address_cmp
static_always_inline int mac_address_cmp(const mac_address_t *a, const mac_address_t *b)
Definition: mac_address.h:134
vlib_frame_t
Definition: node.h:372
ip6_ll_table.h
vlib_process_signal_event
static void vlib_process_signal_event(vlib_main_t *vm, uword node_index, uword type_opaque, uword data)
Definition: node_funcs.h:1019
ip_neighbor_del_all_ctx_t_::ipn_del
index_t * ipn_del
Definition: ip_neighbor.c:602
ip_neighbor_elt_t_::ipne_anchor
clib_llist_anchor_t ipne_anchor
Definition: ip_neighbor.c:38
error
Definition: cJSON.c:88
ip_address_from_46
void ip_address_from_46(const ip46_address_t *nh, fib_protocol_t fproto, ip_address_t *ip)
Definition: ip_types.c:259
vnet_sw_interface_compare
word vnet_sw_interface_compare(vnet_main_t *vnm, uword sw_if_index0, uword sw_if_index1)
Definition: interface.c:1287
ip6_table_bind_callback_t::function
ip6_table_bind_function_t * function
Definition: ip6.h:106
key
typedef key
Definition: ipsec_types.api:91
ip_neighbor_command2
static vlib_cli_command_t ip_neighbor_command2
(constructor) VLIB_CLI_COMMAND (ip_neighbor_command2)
Definition: ip_neighbor.c:816
unformat
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
pool_is_free_index
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:302
ip6_destination_matches_route
static uword ip6_destination_matches_route(const ip6_main_t *im, const ip6_address_t *key, const ip6_address_t *dest, uword dest_length)
Definition: ip6.h:189
ip_neighbor_learn_t_::sw_if_index
u32 sw_if_index
Definition: ip_neighbor_types.h:101
ip_neighbor_t_::ipn_flags
ip_neighbor_flags_t ipn_flags
Falgs for this object.
Definition: ip_neighbor_types.h:74
ip_neighbor_table_bind_ctx_t_::old_fib_index
u32 old_fib_index
Definition: ip_neighbor.c:1441
FIB_SOURCE_ADJ
@ FIB_SOURCE_ADJ
Adjacency source.
Definition: fib_source.h:105
vlib_process_get_events
static uword vlib_process_get_events(vlib_main_t *vm, uword **data_vector)
Return the first event type which has occurred and a vector of per-event data of that type,...
Definition: node_funcs.h:583
IP_LOOKUP_NEXT_MCAST_MIDCHAIN
@ IP_LOOKUP_NEXT_MCAST_MIDCHAIN
Multicast Midchain Adjacency.
Definition: adj.h:89
ip_addr_version
#define ip_addr_version(_a)
Definition: ip_types.h:93
pool_foreach
#define pool_foreach(VAR, POOL)
Iterate through pool.
Definition: pool.h:534
unformat_ip_address
uword unformat_ip_address(unformat_input_t *input, va_list *args)
Definition: ip_types.c:41
mac_address_copy
static_always_inline void mac_address_copy(mac_address_t *dst, const mac_address_t *src)
Definition: mac_address.h:128
ip_af_type_pfx_len
static u8 ip_af_type_pfx_len(ip_address_family_t type)
Definition: ip_neighbor.c:247
ip_neighbor_sweep_one
static walk_rc_t ip_neighbor_sweep_one(index_t ipni, void *arg)
Definition: ip_neighbor.c:1231
ip_neighbor_mark_one
static walk_rc_t ip_neighbor_mark_one(index_t ipni, void *ctx)
Definition: ip_neighbor.c:1208
IP_NEIGHBOR_EVENT_REMOVED
@ IP_NEIGHBOR_EVENT_REMOVED
Definition: ip_neighbor_types.h:108
count
u8 count
Definition: dhcp.api:208
clib_llist_foreach_reverse
#define clib_llist_foreach_reverse(LP, name, H, E, body)
Walk list starting at head in reverse order.
Definition: llist.h:335
hash_create_mem
#define hash_create_mem(elts, key_bytes, value_bytes)
Definition: hash.h:660
ip_neighbor_table_bind_ctx_t_::new_fib_index
u32 new_fib_index
Definition: ip_neighbor.c:1440
ip_neighbor_walk_covered
static walk_rc_t ip_neighbor_walk_covered(index_t ipni, void *arg)
Definition: ip_neighbor.c:1321
vec_len
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
Definition: vec_bootstrap.h:142
ip_neighbor_show_i
static clib_error_t * ip_neighbor_show_i(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd, ip_address_family_t af)
Definition: ip_neighbor.c:892
ip4_neighbor_show
static clib_error_t * ip4_neighbor_show(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ip_neighbor.c:934
unformat_free
static void unformat_free(unformat_input_t *i)
Definition: format.h:155
ip6_neighbor.h
ip_neighbor_list_remove
static void ip_neighbor_list_remove(ip_neighbor_t *ipn)
Definition: ip_neighbor.c:140
IP_LOOKUP_NEXT_DROP
@ IP_LOOKUP_NEXT_DROP
Adjacency to drop this packet.
Definition: adj.h:53
vec_add1
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:606
fib_table_entry_path_remove
void fib_table_entry_path_remove(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, dpo_proto_t next_hop_proto, const ip46_address_t *next_hop, u32 next_hop_sw_if_index, u32 next_hop_fib_index, u32 next_hop_weight, fib_route_path_flags_t path_flags)
remove one path to an entry (aka route) in the FIB.
Definition: fib_table.c:736
format_ip_address_family
u8 * format_ip_address_family(u8 *s, va_list *args)
Definition: ip.c:215
ip_neighbor_key_t_
Definition: ip_neighbor_types.h:49
ip_adjacency_t_::lookup_next_index
ip_lookup_next_t lookup_next_index
Next hop after ip4-lookup.
Definition: adj.h:337
ip_neighbor_add_del_interface_address_v6
static void ip_neighbor_add_del_interface_address_v6(ip6_main_t *im, uword opaque, u32 sw_if_index, ip6_address_t *address, u32 address_length, u32 if_address_index, u32 is_del)
Definition: ip_neighbor.c:1400
hash_unset_mem
#define hash_unset_mem(h, key)
Definition: hash.h:291
ip_neighbor_add_del_interface_address_v4
static void ip_neighbor_add_del_interface_address_v4(ip4_main_t *im, uword opaque, u32 sw_if_index, ip4_address_t *address, u32 address_length, u32 if_address_index, u32 is_del)
Definition: ip_neighbor.c:1358
ip_neighbor_db
static ip_neighbor_db_t ip_neighbor_db[N_AF]
Definition: ip_neighbor.c:66
ip_neighbor_t_::ipn_key
ip_neighbor_key_t * ipn_key
The idempotent key.
Definition: ip_neighbor_types.h:64
vnet_get_main
vnet_main_t * vnet_get_main(void)
Definition: pnat_test_stubs.h:56
ip4_neighbor_proxy_enable
int ip4_neighbor_proxy_enable(u32 sw_if_index)
Definition: ip_neighbor.c:1111
ip_addr_v6
#define ip_addr_v6(_a)
Definition: ip_types.h:92
ip_neighbor_learn_t_::ip
ip_address_t ip
Definition: ip_neighbor_types.h:99
ip6_add_del_interface_address_callback_t
Definition: ip6.h:94
ip_neighbor_register
void ip_neighbor_register(ip_address_family_t af, const ip_neighbor_vft_t *vft)
Definition: ip_neighbor.c:1014
vlib_get_thread_index
static_always_inline uword vlib_get_thread_index(void)
Definition: threads.h:187
ip_neighbor_refresh
static void ip_neighbor_refresh(ip_neighbor_t *ipn)
Definition: ip_neighbor.c:157
format_mac_address_t
u8 * format_mac_address_t(u8 *s, va_list *args)
Definition: mac_address.c:27
unformat_check_input
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:163
ip6_main_t::add_del_interface_address_callbacks
ip6_add_del_interface_address_callback_t * add_del_interface_address_callbacks
Definition: ip6.h:148
end
f64 end
end of the time range
Definition: mactime.api:44
index_t
u32 index_t
A Data-Path Object is an object that represents actions that are applied to packets are they are swit...
Definition: dpo.h:43
ip_neighbor_touch
static void ip_neighbor_touch(ip_neighbor_t *ipn)
Definition: ip_neighbor.c:104
ip_neighbor_destroy
static void ip_neighbor_destroy(ip_neighbor_t *ipn)
Definition: ip_neighbor.c:390
ip_neighbor_table_bind_ctx_t
struct ip_neighbor_table_bind_ctx_t_ ip_neighbor_table_bind_ctx_t
ip_neighbor_learn_t_::mac
mac_address_t mac
Definition: ip_neighbor_types.h:100
format_ip_address
u8 * format_ip_address(u8 *s, va_list *args)
Definition: ip_types.c:21
mac_address_is_zero
static_always_inline int mac_address_is_zero(const mac_address_t *mac)
Definition: mac_address.h:106
uword
u64 uword
Definition: types.h:112
IP_ADDRESS_V6_ALL_0S
#define IP_ADDRESS_V6_ALL_0S
Definition: ip_types.h:87
show_ip6_neighbors_cmd_node
static vlib_cli_command_t show_ip6_neighbors_cmd_node
(constructor) VLIB_CLI_COMMAND (show_ip6_neighbors_cmd_node)
Definition: ip_neighbor.c:979
ip_neighbor_list_head
index_t ip_neighbor_list_head[N_AF]
protocol specific lists of time sorted neighbors
Definition: ip_neighbor.c:34
IP_LOOKUP_NEXT_REWRITE
@ IP_LOOKUP_NEXT_REWRITE
This packet is to be rewritten and forwarded to the next processing node.
Definition: adj.h:73
IP_NEIGHBOR_AGE_ALIVE
@ IP_NEIGHBOR_AGE_ALIVE
Definition: ip_neighbor.c:1487
ip_addr_v4
#define ip_addr_v4(_a)
Definition: ip_types.h:91
ip6_main_t::table_bind_callbacks
ip6_table_bind_callback_t * table_bind_callbacks
Functions to call when interface to table biding changes.
Definition: ip6.h:151
ip_neighbor_add
int ip_neighbor_add(const ip_address_t *ip, const mac_address_t *mac, u32 sw_if_index, ip_neighbor_flags_t flags, u32 *stats_index)
Definition: ip_neighbor.c:477
ip_neighbor_cmd
static clib_error_t * ip_neighbor_cmd(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ip_neighbor.c:724
ip_neighbor_get_mac
const mac_address_t * ip_neighbor_get_mac(const ip_neighbor_t *ipn)
Definition: ip_neighbor.c:128
ip_neighbor_del_all_ctx_t
struct ip_neighbor_del_all_ctx_t_ ip_neighbor_del_all_ctx_t
ip_neighbor_t_::ipn_elt
index_t ipn_elt
Definition: ip_neighbor_types.h:83
ip_neighbor_key_t_::ipnk_ip
ip_address_t ipnk_ip
Definition: ip_neighbor_types.h:51
ip_neighbor_walk
void ip_neighbor_walk(ip_address_family_t af, u32 sw_if_index, ip_neighbor_walk_cb_t cb, void *ctx)
Definition: ip_neighbor.c:1046
ip4_neighbor_probe_dst
void ip4_neighbor_probe_dst(u32 sw_if_index, const ip4_address_t *dst)
Definition: ip4_neighbor.c:57
fib_proto_to_link
vnet_link_t fib_proto_to_link(fib_protocol_t proto)
Convert from a protocol to a link type.
Definition: fib_types.c:377
ip_neighbor_mk_incomplete_walk
static adj_walk_rc_t ip_neighbor_mk_incomplete_walk(adj_index_t ai, void *ctx)
Definition: ip_neighbor.c:382
f64
double f64
Definition: types.h:142
IP_LOOKUP_NEXT_PUNT
@ IP_LOOKUP_NEXT_PUNT
Adjacency to punt this packet.
Definition: adj.h:55
ip_neighbor_publish
void ip_neighbor_publish(index_t ipni, ip_neighbor_event_flags_t flags)
Definition: ip_neighbor_watch.c:197
format_unformat_error
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
ip4_neighbor_show_sorted
static clib_error_t * ip4_neighbor_show_sorted(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ip_neighbor.c:948
ip_neighbor_age_state_t_
ip_neighbor_age_state_t_
Definition: ip_neighbor.c:1485
vec_validate
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment)
Definition: vec.h:523
mac_address_t_::bytes
u8 bytes[6]
Definition: mac_address.h:25
ip_neighbor_watch.h
address
manual_print typedef address
Definition: ip_types.api:96
VLIB_CLI_COMMAND
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:163
IP_NEIGHBOR_AGE_PROBE
@ IP_NEIGHBOR_AGE_PROBE
Definition: ip_neighbor.c:1488
fib_protocol_t
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
ip_neighbor_delete_sw_interface
static clib_error_t * ip_neighbor_delete_sw_interface(vnet_main_t *vnm, u32 sw_if_index, u32 is_add)
Definition: ip_neighbor.c:1294
IP_LOOKUP_NEXT_BCAST
@ IP_LOOKUP_NEXT_BCAST
Broadcast Adjacency.
Definition: adj.h:85
ip6_neighbor_proxy_add
int ip6_neighbor_proxy_add(u32 sw_if_index, const ip6_address_t *addr)
Definition: ip_neighbor.c:1131
ip4_address_t
Definition: ip4_packet.h:50
ip6_ll_prefix_t_
Aggregate type for a prefix in the IPv6 Link-local table.
Definition: ip6_ll_types.h:24
ip6_neighbor_proxy_del
int ip6_neighbor_proxy_del(u32 sw_if_index, const ip6_address_t *addr)
Definition: ip_neighbor.c:1141
ip_adjacency_t_
IP unicast adjacency.
Definition: adj.h:235
clib_min
#define clib_min(x, y)
Definition: clib.h:342
ip_neighbor_t_::ipn_time_last_updated
f64 ipn_time_last_updated
Aging related data.
Definition: ip_neighbor_types.h:81
llist.h
vlib_node_registration_t
struct _vlib_node_registration vlib_node_registration_t
vlib_cli_output
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:716
N_AF
#define N_AF
Definition: ip_types.h:27
ip6_table_bind_callback_t
Definition: ip6.h:104
ip4_table_bind_callback_t
Definition: ip4.h:92
fib_proto_to_dpo
dpo_proto_t fib_proto_to_dpo(fib_protocol_t fib_proto)
Definition: fib_types.c:343
ip_neighbor_entries
static index_t * ip_neighbor_entries(u32 sw_if_index, ip_address_family_t af)
Definition: ip_neighbor.c:843
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
mac_address_increment
void mac_address_increment(mac_address_t *mac)
Definition: mac_address.c:65
vnet_sw_interface_is_admin_up
static uword vnet_sw_interface_is_admin_up(vnet_main_t *vnm, u32 sw_if_index)
Definition: interface_funcs.h:265
ip46_address.h
ip_neighbor_show_sorted_i
static clib_error_t * ip_neighbor_show_sorted_i(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd, ip_address_family_t af)
Definition: ip_neighbor.c:866
ip_neighbor_del
int ip_neighbor_del(const ip_address_t *ip, u32 sw_if_index)
Definition: ip_neighbor.c:574
ip_address_family_to_fib_proto
fib_protocol_t ip_address_family_to_fib_proto(ip_address_family_t af)
Definition: ip_types.c:223
ip_neighbor_adj_fib_add
static void ip_neighbor_adj_fib_add(ip_neighbor_t *ipn, u32 fib_index)
Definition: ip_neighbor.c:253
IP_LOOKUP_NEXT_ICMP_ERROR
@ IP_LOOKUP_NEXT_ICMP_ERROR
This packets needs to go to ICMP error.
Definition: adj.h:79
ip6_main
ip6_main_t ip6_main
Definition: ip6_forward.c:2785
ip_neighbor_pool
static ip_neighbor_t * ip_neighbor_pool
Pool for All IP neighbors.
Definition: ip_neighbor.c:31
ip4_destination_matches_route
static uword ip4_destination_matches_route(const ip4_main_t *im, const ip4_address_t *key, const ip4_address_t *dest, uword dest_length)
Definition: ip4.h:187
ip_address_is_zero
bool ip_address_is_zero(const ip_address_t *ip)
Definition: ip_types.c:102
ip4_main_t::add_del_interface_address_callbacks
ip4_add_del_interface_address_callback_t * add_del_interface_address_callbacks
Functions to call when interface address changes.
Definition: ip4.h:138
ip_neighbor_mk_complete
static void ip_neighbor_mk_complete(adj_index_t ai, ip_neighbor_t *ipn)
Definition: ip_neighbor.c:347
ip_neighbour_age_out
static ip_neighbor_age_state_t ip_neighbour_age_out(index_t ipni, f64 now, f64 *wait)
Definition: ip_neighbor.c:1495
hash_get_mem
#define hash_get_mem(h, key)
Definition: hash.h:269
ip4_add_del_interface_address_callback_t::function
ip4_add_del_interface_address_function_t * function
Definition: ip4.h:75
ip_neighbor_del_all
void ip_neighbor_del_all(ip_address_family_t af, u32 sw_if_index)
Definition: ip_neighbor.c:616
vnet_main_t
Definition: vnet.h:76
vec_free
#define vec_free(V)
Free vector's memory (no header).
Definition: vec.h:395
IP_NEIGHBOR_INFO
#define IP_NEIGHBOR_INFO(...)
Definition: ip_neighbor.c:85
ip_adjacency_t_::sub_type
union ip_adjacency_t_::@144 sub_type
IP_NEIGHBOR_EVENT_ADDED
@ IP_NEIGHBOR_EVENT_ADDED
Definition: ip_neighbor_types.h:107
ip4_neighbor_proxy_add
int ip4_neighbor_proxy_add(u32 fib_index, const ip4_address_t *start, const ip4_address_t *end)
The set of function that vnet requires from the IP neighbour module.
Definition: ip_neighbor.c:1086
ip6_add_del_interface_address_callback_t::function
ip6_add_del_interface_address_function_t * function
Definition: ip6.h:96
ip_neighbor_probe
void ip_neighbor_probe(const ip_adjacency_t *adj)
Definition: ip_neighbor.c:1038
ip_neighbor_populate
void ip_neighbor_populate(ip_address_family_t af, u32 sw_if_index)
Definition: ip_neighbor.c:1151
ip_neighbor.h
ip_neighbor_walk_table_bind
static walk_rc_t ip_neighbor_walk_table_bind(index_t ipni, void *arg)
Definition: ip_neighbor.c:1445
ip_neighbor_get_index
static index_t ip_neighbor_get_index(const ip_neighbor_t *ipn)
Definition: ip_neighbor.c:98
ip_neighbor_db_remove
static void ip_neighbor_db_remove(const ip_neighbor_t *ipn)
Definition: ip_neighbor.c:211
format_vnet_sw_if_index_name
format_function_t format_vnet_sw_if_index_name
Definition: interface_funcs.h:458
ip_neighbor_flags_t
enum ip_neighbor_flags_t_ ip_neighbor_flags_t
ip_neighbor_table_bind_ctx_t_
Definition: ip_neighbor.c:1438
unformat_vnet_sw_interface
unformat_function_t unformat_vnet_sw_interface
Definition: interface_funcs.h:462
vlib_process_wait_for_event_or_clock
static f64 vlib_process_wait_for_event_or_clock(vlib_main_t *vm, f64 dt)
Suspend a cooperative multi-tasking thread Waits for an event, or for the indicated number of seconds...
Definition: node_funcs.h:755
ASSERT
#define ASSERT(truth)
Definition: error_bootstrap.h:69
unformat_mac_address_t
uword unformat_mac_address_t(unformat_input_t *input, va_list *args)
Definition: mac_address.c:37
fib_table_get_index_for_sw_if_index
u32 fib_table_get_index_for_sw_if_index(fib_protocol_t proto, u32 sw_if_index)
Get the index of the FIB bound to the interface.
Definition: fib_table.c:1003
FIB_ROUTE_PATH_FLAG_NONE
@ FIB_ROUTE_PATH_FLAG_NONE
Definition: fib_types.h:332
fib_table_lock
void fib_table_lock(u32 fib_index, fib_protocol_t proto, fib_source_t source)
Release a reference counting lock on the table.
Definition: fib_table.c:1361
adj_get_link_type
vnet_link_t adj_get_link_type(adj_index_t ai)
Return the link type of the adjacency.
Definition: adj.c:530
u32
unsigned int u32
Definition: types.h:88
VLIB_INIT_FUNCTION
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:172
af
vl_api_address_family_t af
Definition: ip.api:619
ip6_neighbor_probe_dst
void ip6_neighbor_probe_dst(u32 sw_if_index, const ip6_address_t *dst)
Definition: ip6_neighbor.c:33
ip_neighbor_mk_incomplete
static void ip_neighbor_mk_incomplete(adj_index_t ai)
Definition: ip_neighbor.c:358
ip_neighbor_db_t_::ipndb_limit
u32 ipndb_limit
per-protocol limit - max number of neighbors
Definition: ip_neighbor.c:50
dst
vl_api_ip4_address_t dst
Definition: pnat.api:41
ctx
long ctx[MAX_CONNS]
Definition: main.c:144
ip_neighbor_init
static clib_error_t * ip_neighbor_init(vlib_main_t *vm)
Definition: ip_neighbor.c:1763
ip_neighbor_db_t_::ipndb_hash
uword ** ipndb_hash
per interface hash
Definition: ip_neighbor.c:48
ip_neighbor_get_sw_if_index
const u32 ip_neighbor_get_sw_if_index(const ip_neighbor_t *ipn)
Definition: ip_neighbor.c:134
vec_foreach
#define vec_foreach(var, vec)
Vector iterator.
Definition: vec_bootstrap.h:213
show_ip6_neighbor_cmd_node
static vlib_cli_command_t show_ip6_neighbor_cmd_node
(constructor) VLIB_CLI_COMMAND (show_ip6_neighbor_cmd_node)
Definition: ip_neighbor.c:994
VLIB_NODE_TYPE_PROCESS
@ VLIB_NODE_TYPE_PROCESS
Definition: node.h:84
ip_neighbor_sweep
void ip_neighbor_sweep(ip_address_family_t af)
Definition: ip_neighbor.c:1247
AF_IP6
@ AF_IP6
Definition: ip_types.h:24
ip4_table_bind_callback_t::function
ip4_table_bind_function_t * function
Definition: ip4.h:94
ip_neighbor_walk_covered_ctx_t
struct ip_neighbor_walk_covered_ctx_t_ ip_neighbor_walk_covered_ctx_t
elt
app_rx_mq_elt_t * elt
Definition: application.c:488
ip6_main_t
Definition: ip6.h:110
format_ip_neighbor_flags
u8 * format_ip_neighbor_flags(u8 *s, va_list *args)
Definition: ip_neighbor_types.c:36
mac_address_t_
Definition: mac_address.h:21
ip4_neighbor_proxy_delete
int ip4_neighbor_proxy_delete(u32 fib_index, const ip4_address_t *start, const ip4_address_t *end)
Definition: ip_neighbor.c:1099
now
f64 now
Definition: nat44_ei_out2in.c:710
ip_neighbor_elt_t
struct ip_neighbor_elt_t_ ip_neighbor_elt_t
ip_neighbor_probe_dst
void ip_neighbor_probe_dst(u32 sw_if_index, ip_address_family_t af, const ip46_address_t *dst)
Definition: ip_neighbor.c:1020
vec_sort_with_function
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
Definition: vec.h:1097
adj_index_t
u32 adj_index_t
An index for adjacencies.
Definition: adj_types.h:30
IP_NEIGHBOR_DBG
#define IP_NEIGHBOR_DBG(...)
Definition: ip_neighbor.c:82
adj_nbr_find
adj_index_t adj_nbr_find(fib_protocol_t nh_proto, vnet_link_t link_type, const ip46_address_t *nh_addr, u32 sw_if_index)
Lookup neighbor adjancency.
Definition: adj_nbr.c:109
ipn_logger
static vlib_log_class_t ipn_logger
Definition: ip_neighbor.c:62
vlib_main_t
Definition: main.h:102
adj_nbr_update_rewrite
void adj_nbr_update_rewrite(adj_index_t adj_index, adj_nbr_rewrite_flag_t flags, u8 *rewrite)
adj_nbr_update_rewrite
Definition: adj_nbr.c:340
show_ip_neighbor_cfg_cmd_node
static vlib_cli_command_t show_ip_neighbor_cfg_cmd_node
(constructor) VLIB_CLI_COMMAND (show_ip_neighbor_cfg_cmd_node)
Definition: ip_neighbor.c:1749
VNET_SW_INTERFACE_ADMIN_UP_DOWN_FUNCTION
VNET_SW_INTERFACE_ADMIN_UP_DOWN_FUNCTION(ip_neighbor_interface_admin_change)
IP_LOOKUP_N_NEXT
@ IP_LOOKUP_N_NEXT
Definition: adj.h:91
ip_neighbor_is_dynamic
static bool ip_neighbor_is_dynamic(const ip_neighbor_t *ipn)
Definition: ip_neighbor.c:110
VLIB_INITS
#define VLIB_INITS(...)
Definition: init.h:352
ip_address_increment
void ip_address_increment(ip_address_t *ip)
Definition: ip_types.c:291
vlib_get_main
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:38
pool_get_zero
#define pool_get_zero(P, E)
Allocate an object E from a pool P and zero it.
Definition: pool.h:258
u8
unsigned char u8
Definition: types.h:56
clib_error_t
Definition: clib_error.h:21
rt
vnet_interface_output_runtime_t * rt
Definition: interface_output.c:419
ip_neighbor_update
void ip_neighbor_update(vnet_main_t *vnm, adj_index_t ai)
Definition: ip_neighbor.c:636
ip_neighbor_table_bind_v4
static void ip_neighbor_table_bind_v4(ip4_main_t *im, uword opaque, u32 sw_if_index, u32 new_fib_index, u32 old_fib_index)
Definition: ip_neighbor.c:1458
ip
vl_api_address_t ip
Definition: l2.api:558
ip_neighbor_db_add
static void ip_neighbor_db_add(const ip_neighbor_t *ipn)
Definition: ip_neighbor.c:190
ip_neighbor_walk_covered_ctx_t_
Definition: ip_neighbor.c:1313
adj_nbr_walk_nh
void adj_nbr_walk_nh(u32 sw_if_index, fib_protocol_t adj_nh_proto, const ip46_address_t *nh, adj_walk_cb_t cb, void *ctx)
Walk adjacencies on a link with a given next-hop.
Definition: adj_nbr.c:684
vlib_init_function_t
clib_error_t *() vlib_init_function_t(struct vlib_main_t *vm)
Definition: init.h:51
format_ip6_address
format_function_t format_ip6_address
Definition: format.h:91
ip_neighbor_sweep_ctx_t_::ipnsc_stale
index_t * ipnsc_stale
Definition: ip_neighbor.c:1227
ip_neighbor_mark
void ip_neighbor_mark(ip_address_family_t af)
Definition: ip_neighbor.c:1220
ip_neighbor_table_bind_v6
static void ip_neighbor_table_bind_v6(ip6_main_t *im, uword opaque, u32 sw_if_index, u32 new_fib_index, u32 old_fib_index)
Definition: ip_neighbor.c:1472
fib_table_unlock
void fib_table_unlock(u32 fib_index, fib_protocol_t proto, fib_source_t source)
Take a reference counting lock on the table.
Definition: fib_table.c:1342
IP_LOOKUP_NEXT_MCAST
@ IP_LOOKUP_NEXT_MCAST
Multicast Adjacency.
Definition: adj.h:82
ip_neighbor_key_t_::ipnk_sw_if_index
u32 ipnk_sw_if_index
Definition: ip_neighbor_types.h:53
ADJ_WALK_RC_CONTINUE
@ ADJ_WALK_RC_CONTINUE
Definition: adj_types.h:44
ip_adjacency_t_::nbr
struct ip_adjacency_t_::@144::@145 nbr
IP_LOOKUP_NEXT_ARP/IP_LOOKUP_NEXT_REWRITE.
ip6_ll_prefix_t_::ilp_addr
ip6_address_t ilp_addr
the IP6 address
Definition: ip6_ll_types.h:34
ip_address_family_from_fib_proto
ip_address_family_t ip_address_family_from_fib_proto(fib_protocol_t fp)
Definition: ip_types.c:237
ip_neighbor_del_all_walk_cb
static walk_rc_t ip_neighbor_del_all_walk_cb(index_t ipni, void *arg)
Definition: ip_neighbor.c:606
clib_llist_prev
#define clib_llist_prev(LP, name, E)
Get previous pool entry.
Definition: llist.h:125
ip_address_cmp
int ip_address_cmp(const ip_address_t *ip1, const ip_address_t *ip2)
Definition: ip_types.c:117
vlib_time_now
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:327
show_ip_neighbors_cmd_node
static vlib_cli_command_t show_ip_neighbors_cmd_node
(constructor) VLIB_CLI_COMMAND (show_ip_neighbors_cmd_node)
Definition: ip_neighbor.c:969
IP_NEIGHBOR_PROCESS_SLEEP_LONG
#define IP_NEIGHBOR_PROCESS_SLEEP_LONG
Definition: ip_neighbor.c:1492
vlib_node_runtime_t
Definition: node.h:454
ip_neighbor_walk_covered_ctx_t_::addr
ip_address_t addr
Definition: ip_neighbor.c:1315
vlib_cli_command_t
Definition: cli.h:92
ip_neighbor_sort
static int ip_neighbor_sort(void *a1, void *a2)
Definition: ip_neighbor.c:825
ip4_main_t
IPv4 main type.
Definition: ip4.h:107
sw_if_index
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:34
ip_neighbor_t_::ipn_mac
mac_address_t ipn_mac
The learned MAC address of the neighbour.
Definition: ip_neighbor_types.h:69
show_ip4_neighbor_cmd_node
static vlib_cli_command_t show_ip4_neighbor_cmd_node
(constructor) VLIB_CLI_COMMAND (show_ip4_neighbor_cmd_node)
Definition: ip_neighbor.c:989
ip_neighbor_command
static vlib_cli_command_t ip_neighbor_command
(constructor) VLIB_CLI_COMMAND (ip_neighbor_command)
Definition: ip_neighbor.c:810
walk_rc_t
enum walk_rc_t_ walk_rc_t
Walk return code.
ip_neighbor_process_event_t
enum ip_neighbor_process_event_t_ ip_neighbor_process_event_t
adj_get
static ip_adjacency_t * adj_get(adj_index_t adj_index)
Get a pointer to an adjacency object from its index.
Definition: adj.h:470
clib_mem_alloc
static void * clib_mem_alloc(uword size)
Definition: mem.h:256
ip6_neighbor_show
static clib_error_t * ip6_neighbor_show(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ip_neighbor.c:927
WALK_STOP
@ WALK_STOP
Definition: interface_funcs.h:173
fib_prefix_t_
Aggregate type for a prefix.
Definition: fib_types.h:202
ip6_neighbor_age_process
static uword ip6_neighbor_age_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
Definition: ip_neighbor.c:1647
ip4_neighbor_age_process_node
static vlib_node_registration_t ip4_neighbor_age_process_node
(constructor) VLIB_REGISTER_NODE (ip4_neighbor_age_process_node)
Definition: ip_neighbor.c:1654
ip_neighbor_interface_admin_change
static clib_error_t * ip_neighbor_interface_admin_change(vnet_main_t *vnm, u32 sw_if_index, u32 flags)
Definition: ip_neighbor.c:1265
type
vl_api_fib_path_type_t type
Definition: fib_types.api:123
clib_llist_make_head
#define clib_llist_make_head(LP, name)
Initialize llist head.
Definition: llist.h:144
ip6_neighbor_age_process_node
static vlib_node_registration_t ip6_neighbor_age_process_node
(constructor) VLIB_REGISTER_NODE (ip6_neighbor_age_process_node)
Definition: ip_neighbor.c:1659
UNFORMAT_END_OF_INPUT
#define UNFORMAT_END_OF_INPUT
Definition: format.h:137
ip_address_family_t
enum ip_address_family_t_ ip_address_family_t
VLIB_REGISTER_NODE
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
ip_neighbor_flush
void ip_neighbor_flush(ip_address_family_t af, u32 sw_if_index)
Definition: ip_neighbor.c:1183
ip4_neighbor_proxy_disable
int ip4_neighbor_proxy_disable(u32 sw_if_index)
Definition: ip_neighbor.c:1121
flags
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:105