FD.io VPP  v21.06-3-gbb25fbf28
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 
204  hash_set_mem (ip_neighbor_db[af].ipndb_hash[sw_if_index],
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 
274  fproto = ip_address_family_to_fib_proto (af);
275 
276  fib_prefix_t pfx = {
277  .fp_len = ip_af_type_pfx_len (af),
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 
322  fproto = ip_address_family_to_fib_proto (af);
323 
324  fib_prefix_t pfx = {
325  .fp_len = ip_af_type_pfx_len (af),
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  {
450  if (!ip_neighbor_force_reuse (af))
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;
698  case IP_LOOKUP_NEXT_DROP:
699  case IP_LOOKUP_NEXT_PUNT:
705  case IP_LOOKUP_N_NEXT:
706  ASSERT (0);
707  break;
708  }
709 }
710 
711 void
713 {
714  ip_neighbor_add (&l->ip, &l->mac, l->sw_if_index,
715  IP_NEIGHBOR_FLAG_DYNAMIC, NULL);
716 }
717 
718 static clib_error_t *
720  unformat_input_t * input, vlib_cli_command_t * cmd)
721 {
724  vnet_main_t *vnm = vnet_get_main ();
726  u32 sw_if_index = ~0;
727  int is_add = 1;
728  int count = 1;
729 
730  flags = IP_NEIGHBOR_FLAG_DYNAMIC;
731 
733  {
734  /* set ip arp TenGigE1/1/0/1 1.2.3.4 aa:bb:... or aabb.ccdd... */
735  if (unformat (input, "%U %U %U",
738  ;
739  else if (unformat (input, "delete") || unformat (input, "del"))
740  is_add = 0;
741  else if (unformat (input, "static"))
742  {
743  flags |= IP_NEIGHBOR_FLAG_STATIC;
744  flags &= ~IP_NEIGHBOR_FLAG_DYNAMIC;
745  }
746  else if (unformat (input, "no-fib-entry"))
747  flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
748  else if (unformat (input, "count %d", &count))
749  ;
750  else
751  break;
752  }
753 
754  if (sw_if_index == ~0 ||
756  return clib_error_return (0,
757  "specify interface, IP address and MAC: `%U'",
758  format_unformat_error, input);
759 
760  while (count)
761  {
762  if (is_add)
763  ip_neighbor_add (&ip, &mac, sw_if_index, flags, NULL);
764  else
766 
769 
770  --count;
771  }
772 
773  return NULL;
774 }
775 
776 /* *INDENT-OFF* */
777 /*?
778  * Add or delete IPv4 ARP cache entries.
779  *
780  * @note 'set ip neighbor' options (e.g. delete, static, 'fib-id <id>',
781  * 'count <number>', 'interface ip4_addr mac_addr') can be added in
782  * any order and combination.
783  *
784  * @cliexpar
785  * @parblock
786  * Add or delete IPv4 ARP cache entries as follows. MAC Address can be in
787  * either aa:bb:cc:dd:ee:ff format or aabb.ccdd.eeff format.
788  * @cliexcmd{set ip neighbor GigabitEthernet2/0/0 6.0.0.3 dead.beef.babe}
789  * @cliexcmd{set ip neighbor delete GigabitEthernet2/0/0 6.0.0.3 de:ad:be:ef:ba:be}
790  *
791  * To add or delete an IPv4 ARP cache entry to or from a specific fib
792  * table:
793  * @cliexcmd{set ip neighbor fib-id 1 GigabitEthernet2/0/0 6.0.0.3 dead.beef.babe}
794  * @cliexcmd{set ip neighbor fib-id 1 delete GigabitEthernet2/0/0 6.0.0.3 dead.beef.babe}
795  *
796  * Add or delete IPv4 static ARP cache entries as follows:
797  * @cliexcmd{set ip neighbor static GigabitEthernet2/0/0 6.0.0.3 dead.beef.babe}
798  * @cliexcmd{set ip neighbor static delete GigabitEthernet2/0/0 6.0.0.3 dead.beef.babe}
799  *
800  * For testing / debugging purposes, the 'set ip neighbor' command can add or
801  * delete multiple entries. Supply the 'count N' parameter:
802  * @cliexcmd{set ip neighbor count 10 GigabitEthernet2/0/0 6.0.0.3 dead.beef.babe}
803  * @endparblock
804  ?*/
806  .path = "set ip neighbor",
807  .short_help =
808  "set ip neighbor [del] <intfc> <ip-address> <mac-address> [static] [no-fib-entry] [count <count>] [fib-id <fib-id>] [proxy <lo-addr> - <hi-addr>]",
809  .function = ip_neighbor_cmd,
810 };
812  .path = "ip neighbor",
813  .short_help =
814  "ip neighbor [del] <intfc> <ip-address> <mac-address> [static] [no-fib-entry] [count <count>] [fib-id <fib-id>] [proxy <lo-addr> - <hi-addr>]",
815  .function = ip_neighbor_cmd,
816 };
817 /* *INDENT-ON* */
818 
819 static int
820 ip_neighbor_sort (void *a1, void *a2)
821 {
822  index_t *ipni1 = a1, *ipni2 = a2;
823  ip_neighbor_t *ipn1, *ipn2;
824  int cmp;
825 
826  ipn1 = ip_neighbor_get (*ipni1);
827  ipn2 = ip_neighbor_get (*ipni2);
828 
830  ipn1->ipn_key->ipnk_sw_if_index,
831  ipn2->ipn_key->ipnk_sw_if_index);
832  if (!cmp)
833  cmp = ip_address_cmp (&ipn1->ipn_key->ipnk_ip, &ipn2->ipn_key->ipnk_ip);
834  return cmp;
835 }
836 
837 static index_t *
839 {
840  index_t *ipnis = NULL;
841  ip_neighbor_t *ipn;
842 
843  /* *INDENT-OFF* */
845  {
846  if ((sw_if_index == ~0 ||
848  (N_AF == af ||
849  ip_neighbor_get_af(ipn) == af))
850  vec_add1 (ipnis, ip_neighbor_get_index(ipn));
851  }
852 
853  /* *INDENT-ON* */
854 
855  if (ipnis)
857  return ipnis;
858 }
859 
860 static clib_error_t *
862  unformat_input_t * input,
864 {
865  ip_neighbor_elt_t *elt, *head;
866 
868 
869 
870  vlib_cli_output (vm, "%=12s%=40s%=6s%=20s%=24s", "Time", "IP",
871  "Flags", "Ethernet", "Interface");
872 
873  /* *INDENT-OFF*/
874  /* the list is time sorted, newest first, so start from the back
875  * and work forwards. Stop when we get to one that is alive */
877  ipne_anchor, head, elt,
878  ({
879  vlib_cli_output (vm, "%U", format_ip_neighbor, elt->ipne_index);
880  }));
881  /* *INDENT-ON*/
882 
883  return (NULL);
884 }
885 
886 static clib_error_t *
888  unformat_input_t * input,
890 {
891  index_t *ipni, *ipnis = NULL;
893 
894  /* Filter entries by interface if given. */
895  sw_if_index = ~0;
897  &sw_if_index);
898 
899  ipnis = ip_neighbor_entries (sw_if_index, af);
900 
901  if (ipnis)
902  vlib_cli_output (vm, "%=12s%=40s%=6s%=20s%=24s", "Time", "IP",
903  "Flags", "Ethernet", "Interface");
904 
905  vec_foreach (ipni, ipnis)
906  {
907  vlib_cli_output (vm, "%U", format_ip_neighbor, *ipni);
908  }
909  vec_free (ipnis);
910 
911  return (NULL);
912 }
913 
914 static clib_error_t *
916  unformat_input_t * input, vlib_cli_command_t * cmd)
917 {
918  return (ip_neighbor_show_i (vm, input, cmd, N_AF));
919 }
920 
921 static clib_error_t *
923  unformat_input_t * input, vlib_cli_command_t * cmd)
924 {
925  return (ip_neighbor_show_i (vm, input, cmd, AF_IP6));
926 }
927 
928 static clib_error_t *
930  unformat_input_t * input, vlib_cli_command_t * cmd)
931 {
932  return (ip_neighbor_show_i (vm, input, cmd, AF_IP4));
933 }
934 
935 static clib_error_t *
937  unformat_input_t * input, vlib_cli_command_t * cmd)
938 {
939  return (ip_neighbor_show_sorted_i (vm, input, cmd, AF_IP6));
940 }
941 
942 static clib_error_t *
944  unformat_input_t * input, vlib_cli_command_t * cmd)
945 {
946  return (ip_neighbor_show_sorted_i (vm, input, cmd, AF_IP4));
947 }
948 
949 /*?
950  * Display all the IP neighbor entries.
951  *
952  * @cliexpar
953  * Example of how to display the IPv4 ARP table:
954  * @cliexstart{show ip neighbor}
955  * Time FIB IP4 Flags Ethernet Interface
956  * 346.3028 0 6.1.1.3 de:ad:be:ef:ba:be GigabitEthernet2/0/0
957  * 3077.4271 0 6.1.1.4 S de:ad:be:ef:ff:ff GigabitEthernet2/0/0
958  * 2998.6409 1 6.2.2.3 de:ad:be:ef:00:01 GigabitEthernet2/0/0
959  * Proxy arps enabled for:
960  * Fib_index 0 6.0.0.1 - 6.0.0.11
961  * @cliexend
962  ?*/
963 /* *INDENT-OFF* */
965  .path = "show ip neighbors",
966  .function = ip_neighbor_show,
967  .short_help = "show ip neighbors [interface]",
968 };
970  .path = "show ip4 neighbors",
971  .function = ip4_neighbor_show,
972  .short_help = "show ip4 neighbors [interface]",
973 };
975  .path = "show ip6 neighbors",
976  .function = ip6_neighbor_show,
977  .short_help = "show ip6 neighbors [interface]",
978 };
980  .path = "show ip neighbor",
981  .function = ip_neighbor_show,
982  .short_help = "show ip neighbor [interface]",
983 };
985  .path = "show ip4 neighbor",
986  .function = ip4_neighbor_show,
987  .short_help = "show ip4 neighbor [interface]",
988 };
990  .path = "show ip6 neighbor",
991  .function = ip6_neighbor_show,
992  .short_help = "show ip6 neighbor [interface]",
993 };
995  .path = "show ip4 neighbor-sorted",
996  .function = ip4_neighbor_show_sorted,
997  .short_help = "show ip4 neighbor-sorted",
998 };
1000  .path = "show ip6 neighbor-sorted",
1001  .function = ip6_neighbor_show_sorted,
1002  .short_help = "show ip6 neighbor-sorted",
1003 };
1004 /* *INDENT-ON* */
1005 
1007 
1008 void
1010 {
1011  ip_nbr_vfts[af] = *vft;
1012 }
1013 
1014 void
1016  ip_address_family_t af, const ip46_address_t * dst)
1017 {
1019  return;
1020 
1021  switch (af)
1022  {
1023  case AF_IP6:
1025  break;
1026  case AF_IP4:
1028  break;
1029  }
1030 }
1031 
1032 void
1034 {
1035  ip_neighbor_probe_dst (adj->rewrite_header.sw_if_index,
1037  &adj->sub_type.nbr.next_hop);
1038 }
1039 
1040 void
1043 {
1045  index_t ipni;
1046 
1047  if (~0 == sw_if_index)
1048  {
1049  uword **hash;
1050 
1051  vec_foreach (hash, ip_neighbor_db[af].ipndb_hash)
1052  {
1053  /* *INDENT-OFF* */
1054  hash_foreach (key, ipni, *hash,
1055  ({
1056  if (WALK_STOP == cb (ipni, ctx))
1057  break;
1058  }));
1059  /* *INDENT-ON* */
1060  }
1061  }
1062  else
1063  {
1064  uword *hash;
1065 
1066  if (vec_len (ip_neighbor_db[af].ipndb_hash) <= sw_if_index)
1067  return;
1069 
1070  /* *INDENT-OFF* */
1071  hash_foreach (key, ipni, hash,
1072  ({
1073  if (WALK_STOP == cb (ipni, ctx))
1074  break;
1075  }));
1076  /* *INDENT-ON* */
1077  }
1078 }
1079 
1080 int
1082  const ip4_address_t * start,
1083  const ip4_address_t * end)
1084 {
1085  if (ip_nbr_vfts[AF_IP4].inv_proxy4_add)
1086  {
1087  return (ip_nbr_vfts[AF_IP4].inv_proxy4_add (fib_index, start, end));
1088  }
1089 
1090  return (-1);
1091 }
1092 
1093 int
1095  const ip4_address_t * start,
1096  const ip4_address_t * end)
1097 {
1098  if (ip_nbr_vfts[AF_IP4].inv_proxy4_del)
1099  {
1100  return (ip_nbr_vfts[AF_IP4].inv_proxy4_del (fib_index, start, end));
1101  }
1102  return -1;
1103 }
1104 
1105 int
1107 {
1108  if (ip_nbr_vfts[AF_IP4].inv_proxy4_enable)
1109  {
1110  return (ip_nbr_vfts[AF_IP4].inv_proxy4_enable (sw_if_index));
1111  }
1112  return -1;
1113 }
1114 
1115 int
1117 {
1118  if (ip_nbr_vfts[AF_IP4].inv_proxy4_disable)
1119  {
1120  return (ip_nbr_vfts[AF_IP4].inv_proxy4_disable (sw_if_index));
1121  }
1122  return -1;
1123 }
1124 
1125 int
1126 ip6_neighbor_proxy_add (u32 sw_if_index, const ip6_address_t * addr)
1127 {
1128  if (ip_nbr_vfts[AF_IP6].inv_proxy6_add)
1129  {
1130  return (ip_nbr_vfts[AF_IP6].inv_proxy6_add (sw_if_index, addr));
1131  }
1132  return -1;
1133 }
1134 
1135 int
1136 ip6_neighbor_proxy_del (u32 sw_if_index, const ip6_address_t * addr)
1137 {
1138  if (ip_nbr_vfts[AF_IP6].inv_proxy6_del)
1139  {
1140  return (ip_nbr_vfts[AF_IP6].inv_proxy6_del (sw_if_index, addr));
1141  }
1142  return -1;
1143 }
1144 
1145 static void
1147  u32 sw_if_index, uword opaque)
1148 {
1149  ip_neighbor_t *ipn;
1150 
1151  IP_NEIGHBOR_DBG ("mac-change: %U",
1153  sw_if_index);
1154 
1155  /* *INDENT-OFF* */
1157  {
1158  if (ipn->ipn_key->ipnk_sw_if_index == sw_if_index)
1161  &ip_addr_46(&ipn->ipn_key->ipnk_ip),
1163  ipn);
1164  }
1165  /* *INDENT-ON* */
1166 
1168 }
1169 
1170 void
1172 {
1173  index_t *ipnis = NULL, *ipni;
1174  ip_neighbor_t *ipn;
1175 
1176  IP_NEIGHBOR_DBG ("populate: %U %U",
1179 
1180  /* *INDENT-OFF* */
1182  {
1183  if (ip_neighbor_get_af(ipn) == af &&
1185  vec_add1 (ipnis, ipn - ip_neighbor_pool);
1186  }
1187  /* *INDENT-ON* */
1188 
1189  vec_foreach (ipni, ipnis)
1190  {
1191  ipn = ip_neighbor_get (*ipni);
1192 
1195  (ipn)),
1196  &ip_addr_46 (&ipn->ipn_key->ipnk_ip),
1198  }
1199  vec_free (ipnis);
1200 }
1201 
1202 void
1204 {
1205  index_t *ipnis = NULL, *ipni;
1206  ip_neighbor_t *ipn;
1207 
1208 
1209  IP_NEIGHBOR_DBG ("flush: %U %U",
1212 
1213  /* *INDENT-OFF* */
1215  {
1216  if (ip_neighbor_get_af(ipn) == af &&
1218  ip_neighbor_is_dynamic (ipn))
1219  vec_add1 (ipnis, ipn - ip_neighbor_pool);
1220  }
1221  /* *INDENT-ON* */
1222 
1223  vec_foreach (ipni, ipnis) ip_neighbor_destroy (ip_neighbor_get (*ipni));
1224  vec_free (ipnis);
1225 }
1226 
1227 static walk_rc_t
1229 {
1230  ip_neighbor_t *ipn;
1231 
1232  ipn = ip_neighbor_get (ipni);
1233 
1234  ipn->ipn_flags |= IP_NEIGHBOR_FLAG_STALE;
1235 
1236  return (WALK_CONTINUE);
1237 }
1238 
1239 void
1241 {
1242  ip_neighbor_walk (af, ~0, ip_neighbor_mark_one, NULL);
1243 }
1244 
1246 {
1249 
1250 static walk_rc_t
1252 {
1254  ip_neighbor_t *ipn;
1255 
1256  ipn = ip_neighbor_get (ipni);
1257 
1258  if (ipn->ipn_flags & IP_NEIGHBOR_FLAG_STALE)
1259  {
1260  vec_add1 (ctx->ipnsc_stale, ipni);
1261  }
1262 
1263  return (WALK_CONTINUE);
1264 }
1265 
1266 void
1268 {
1270  index_t *ipni;
1271 
1273 
1274  vec_foreach (ipni, ctx.ipnsc_stale)
1275  {
1277  }
1278  vec_free (ctx.ipnsc_stale);
1279 }
1280 
1281 /*
1282  * Remove any arp entries associated with the specified interface
1283  */
1284 static clib_error_t *
1287 {
1289 
1290  IP_NEIGHBOR_DBG ("interface-admin: %U %s",
1292  sw_if_index,
1293  (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP ? "up" : "down"));
1294 
1296  {
1298  }
1299  else
1300  {
1301  /* admin down, flush all neighbours */
1303  }
1304 
1305  return (NULL);
1306 }
1307 
1309 
1310 /*
1311  * Remove any arp entries associated with the specified interface
1312  */
1313 static clib_error_t *
1315  u32 sw_if_index, u32 is_add)
1316 {
1317  IP_NEIGHBOR_DBG ("interface-change: %U %s",
1319  sw_if_index, (is_add ? "add" : "del"));
1320 
1321  if (!is_add && sw_if_index != ~0)
1322  {
1324 
1326  }
1327 
1328  return (NULL);
1329 }
1330 
1332 
1334 {
1339 
1340 static walk_rc_t
1342 {
1344  ip_neighbor_t *ipn;
1345 
1346  ipn = ip_neighbor_get (ipni);
1347 
1348  if (AF_IP4 == ip_addr_version (&ctx->addr))
1349  {
1351  &ip_addr_v4 (&ipn->ipn_key->ipnk_ip),
1352  &ip_addr_v4 (&ctx->addr),
1353  ctx->length) &&
1354  ip_neighbor_is_dynamic (ipn))
1355  {
1356  vec_add1 (ctx->ipnis, ip_neighbor_get_index (ipn));
1357  }
1358  }
1359  else if (AF_IP6 == ip_addr_version (&ctx->addr))
1360  {
1362  &ip_addr_v6 (&ipn->ipn_key->ipnk_ip),
1363  &ip_addr_v6 (&ctx->addr),
1364  ctx->length) &&
1365  ip_neighbor_is_dynamic (ipn))
1366  {
1367  vec_add1 (ctx->ipnis, ip_neighbor_get_index (ipn));
1368  }
1369  }
1370  return (WALK_CONTINUE);
1371 }
1372 
1373 
1374 /*
1375  * callback when an interface address is added or deleted
1376  */
1377 static void
1379  uword opaque,
1380  u32 sw_if_index,
1382  u32 address_length,
1383  u32 if_address_index, u32 is_del)
1384 {
1385  /*
1386  * Flush the ARP cache of all entries covered by the address
1387  * that is being removed.
1388  */
1389  IP_NEIGHBOR_DBG ("addr-%d: %U, %U/%d",
1390  (is_del ? "del" : "add"),
1392  sw_if_index, format_ip4_address, address, address_length);
1393 
1394  if (is_del)
1395  {
1396  /* *INDENT-OFF* */
1398  .addr = {
1399  .ip.ip4 = *address,
1400  .version = AF_IP4,
1401  },
1402  .length = address_length,
1403  };
1404  /* *INDENT-ON* */
1405  index_t *ipni;
1406 
1408 
1409  vec_foreach (ipni, ctx.ipnis)
1411 
1412  vec_free (ctx.ipnis);
1413  }
1414 }
1415 
1416 /*
1417  * callback when an interface address is added or deleted
1418  */
1419 static void
1421  uword opaque,
1422  u32 sw_if_index,
1423  ip6_address_t * address,
1424  u32 address_length,
1425  u32 if_address_index, u32 is_del)
1426 {
1427  /*
1428  * Flush the ARP cache of all entries covered by the address
1429  * that is being removed.
1430  */
1431  IP_NEIGHBOR_DBG ("addr-change: %U, %U/%d %s",
1433  sw_if_index, format_ip6_address, address, address_length,
1434  (is_del ? "del" : "add"));
1435 
1436  if (is_del)
1437  {
1438  /* *INDENT-OFF* */
1440  .addr = {
1441  .ip.ip6 = *address,
1442  .version = AF_IP6,
1443  },
1444  .length = address_length,
1445  };
1446  /* *INDENT-ON* */
1447  index_t *ipni;
1448 
1450 
1451  vec_foreach (ipni, ctx.ipnis)
1453 
1454  vec_free (ctx.ipnis);
1455  }
1456 }
1457 
1459 {
1463 
1464 static walk_rc_t
1466 {
1468  ip_neighbor_t *ipn;
1469 
1470  ipn = ip_neighbor_get (ipni);
1471  ip_neighbor_adj_fib_remove (ipn, ctx->old_fib_index);
1472  ip_neighbor_adj_fib_add (ipn, ctx->new_fib_index);
1473 
1474  return (WALK_CONTINUE);
1475 }
1476 
1477 static void
1479  uword opaque,
1480  u32 sw_if_index,
1481  u32 new_fib_index, u32 old_fib_index)
1482 {
1484  .old_fib_index = old_fib_index,
1485  .new_fib_index = new_fib_index,
1486  };
1487 
1489 }
1490 
1491 static void
1493  uword opaque,
1494  u32 sw_if_index,
1495  u32 new_fib_index, u32 old_fib_index)
1496 {
1498  .old_fib_index = old_fib_index,
1499  .new_fib_index = new_fib_index,
1500  };
1501 
1503 }
1504 
1506 {
1511 
1512 #define IP_NEIGHBOR_PROCESS_SLEEP_LONG (0)
1513 
1516 {
1518  ip_neighbor_t *ipn;
1519  u32 ipndb_age;
1520  u32 ttl;
1521 
1522  ipn = ip_neighbor_get (ipni);
1523  af = ip_neighbor_get_af (ipn);
1524  ipndb_age = ip_neighbor_db[af].ipndb_age;
1525  ttl = now - ipn->ipn_time_last_updated;
1526  *wait = ipndb_age;
1527 
1528  if (ttl > ipndb_age)
1529  {
1530  IP_NEIGHBOR_DBG ("aged: %U @%f - %f > %d",
1531  format_ip_neighbor, ipni, now,
1532  ipn->ipn_time_last_updated, ipndb_age);
1533  if (ipn->ipn_n_probes > 2)
1534  {
1535  /* 3 strikes and yea-re out */
1536  IP_NEIGHBOR_DBG ("dead: %U", format_ip_neighbor, ipni);
1537  *wait = 1;
1538  return (IP_NEIGHBOR_AGE_DEAD);
1539  }
1540  else
1541  {
1543  af, &ip_addr_46 (&ipn->ipn_key->ipnk_ip));
1544 
1545  ipn->ipn_n_probes++;
1546  *wait = 1;
1547  }
1548  }
1549  else
1550  {
1551  /* here we are sure that ttl <= ipndb_age */
1552  *wait = ipndb_age - ttl + 1;
1553  return (IP_NEIGHBOR_AGE_ALIVE);
1554  }
1555 
1556  return (IP_NEIGHBOR_AGE_PROBE);
1557 }
1558 
1560 {
1563 
1564 static uword
1568 {
1569  uword event_type, *event_data = NULL;
1570  f64 timeout;
1571 
1572  /* Set the timeout to an effectively infinite value when the process starts */
1574 
1575  while (1)
1576  {
1577  f64 now;
1578 
1579  if (!timeout)
1581  else
1583 
1584  event_type = vlib_process_get_events (vm, &event_data);
1585  vec_reset_length (event_data);
1586 
1587  now = vlib_time_now (vm);
1588 
1589  switch (event_type)
1590  {
1591  case ~0:
1592  {
1593  /* timer expired */
1594  ip_neighbor_elt_t *elt, *head;
1595  f64 wait;
1596 
1597  timeout = ip_neighbor_db[af].ipndb_age;
1599  ip_neighbor_list_head[af]);
1600 
1601  /* *INDENT-OFF*/
1602  /* the list is time sorted, newest first, so start from the back
1603  * and work forwards. Stop when we get to one that is alive */
1604  restart:
1606  ipne_anchor, head, elt,
1607  ({
1609 
1610  res = ip_neighbour_age_out(elt->ipne_index, now, &wait);
1611 
1612  if (IP_NEIGHBOR_AGE_ALIVE == res) {
1613  /* the oldest neighbor has not yet expired, go back to sleep */
1614  timeout = clib_min (wait, timeout);
1615  break;
1616  }
1617  else if (IP_NEIGHBOR_AGE_DEAD == res) {
1618  /* the oldest neighbor is dead, pop it, then restart the walk
1619  * again from the back */
1620  ip_neighbor_destroy (ip_neighbor_get(elt->ipne_index));
1621  goto restart;
1622  }
1623 
1624  timeout = clib_min (wait, timeout);
1625  }));
1626  /* *INDENT-ON* */
1627  break;
1628  }
1630  {
1631 
1632  if (!ip_neighbor_db[af].ipndb_age)
1633  {
1634  /* aging has been disabled */
1635  timeout = 0;
1636  break;
1637  }
1638  ip_neighbor_elt_t *elt, *head;
1639 
1641  ip_neighbor_list_head[af]);
1642  /* no neighbors yet */
1643  if (clib_llist_is_empty (ip_neighbor_elt_pool, ipne_anchor, head))
1644  {
1645  timeout = ip_neighbor_db[af].ipndb_age;
1646  break;
1647  }
1648 
1649  /* poke the oldset neighbour for aging, which returns how long we sleep for */
1650  elt = clib_llist_prev (ip_neighbor_elt_pool, ipne_anchor, head);
1651  ip_neighbour_age_out (elt->ipne_index, now, &timeout);
1652  break;
1653  }
1654  }
1655  }
1656  return 0;
1657 }
1658 
1659 static uword
1662 {
1663  return (ip_neighbor_age_loop (vm, rt, f, AF_IP4));
1664 }
1665 
1666 static uword
1669 {
1670  return (ip_neighbor_age_loop (vm, rt, f, AF_IP6));
1671 }
1672 
1673 /* *INDENT-OFF* */
1675  .function = ip4_neighbor_age_process,
1676  .type = VLIB_NODE_TYPE_PROCESS,
1677  .name = "ip4-neighbor-age-process",
1678 };
1680  .function = ip6_neighbor_age_process,
1681  .type = VLIB_NODE_TYPE_PROCESS,
1682  .name = "ip6-neighbor-age-process",
1683 };
1684 /* *INDENT-ON* */
1685 
1686 int
1687 ip_neighbor_config (ip_address_family_t af, u32 limit, u32 age, bool recycle)
1688 {
1689  ip_neighbor_db[af].ipndb_limit = limit;
1690  ip_neighbor_db[af].ipndb_recycle = recycle;
1691  ip_neighbor_db[af].ipndb_age = age;
1692 
1694  (AF_IP4 == af ?
1698 
1699  return (0);
1700 }
1701 
1702 static clib_error_t *
1704  unformat_input_t * input, vlib_cli_command_t * cmd)
1705 {
1707 
1708  /* *INDENT-OFF* */
1711  vlib_cli_output (vm, " limit:%d, age:%d, recycle:%d",
1712  ip_neighbor_db[af].ipndb_limit,
1713  ip_neighbor_db[af].ipndb_age,
1714  ip_neighbor_db[af].ipndb_recycle);
1715  }
1716 
1717  /* *INDENT-ON* */
1718  return (NULL);
1719 }
1720 
1721 static clib_error_t *
1723  vlib_cli_command_t *cmd)
1724 {
1725  unformat_input_t _line_input, *line_input = &_line_input;
1726  clib_error_t *error = NULL;
1728  u32 limit, age;
1729  bool recycle;
1730 
1731  if (!unformat_user (input, unformat_line_input, line_input))
1732  return 0;
1733 
1734  if (!unformat (line_input, "%U", unformat_ip_address_family, &af))
1735  {
1736  error = unformat_parse_error (line_input);
1737  goto done;
1738  }
1739 
1740  limit = ip_neighbor_db[af].ipndb_limit;
1741  age = ip_neighbor_db[af].ipndb_age;
1742  recycle = ip_neighbor_db[af].ipndb_recycle;
1743 
1744  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1745  {
1746  if (unformat (line_input, "limit %u", &limit))
1747  ;
1748  else if (unformat (line_input, "age %u", &age))
1749  ;
1750  else if (unformat (line_input, "recycle"))
1751  recycle = true;
1752  else if (unformat (line_input, "norecycle"))
1753  recycle = false;
1754  else
1755  {
1756  error = unformat_parse_error (line_input);
1757  goto done;
1758  }
1759  }
1760 
1761  ip_neighbor_config (af, limit, age, recycle);
1762 
1763 done:
1764  unformat_free (line_input);
1765  return error;
1766 }
1767 
1768 /* *INDENT-OFF* */
1770  .path = "show ip neighbor-config",
1771  .function = ip_neighbor_config_show,
1772  .short_help = "show ip neighbor-config",
1773 };
1775  .path = "set ip neighbor-config",
1776  .function = ip_neighbor_config_set,
1777  .short_help = "set ip neighbor-config ip4|ip6 [limit <limit>] [age <age>] "
1778  "[recycle|norecycle]",
1779 };
1780 /* *INDENT-ON* */
1781 
1782 static clib_error_t *
1784 {
1785  {
1788  };
1790  }
1791  {
1794  };
1796  }
1797  {
1800  };
1802  }
1803  {
1806  };
1808  }
1809  {
1811  .function = ip_neighbor_ethernet_change_mac,
1812  .function_opaque = 0,
1813  };
1815  }
1816 
1817  ipn_logger = vlib_log_register_class ("ip", "neighbor");
1818 
1820 
1822  ip_neighbor_list_head[af] =
1824 
1825  return (NULL);
1826 }
1827 
1828 /* *INDENT-OFF* */
1830 {
1831  .runs_after = VLIB_INITS("ip_main_init"),
1832 };
1833 /* *INDENT-ON* */
1834 
1835 /*
1836  * fd.io coding-style-patch-verification: ON
1837  *
1838  * Local Variables:
1839  * eval: (c-set-style "gnu")
1840  * End:
1841  */
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:145
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:1245
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:558
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:395
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:915
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:1337
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:936
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
adj_glean_update_rewrite_itf
void adj_glean_update_rewrite_itf(u32 sw_if_index)
Definition: adj_glean.c:190
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:1660
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:148
ip4_main
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:1105
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:999
IP_NEIGHBOR_AGE_DEAD
@ IP_NEIGHBOR_AGE_DEAD
Definition: ip_neighbor.c:1509
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:1080
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:1565
ip_neighbor_config
int ip_neighbor_config(ip_address_family_t af, u32 limit, u32 age, bool recycle)
Definition: ip_neighbor.c:1687
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:553
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:1336
clib_mem_free
static void clib_mem_free(void *p)
Definition: mem.h:311
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:994
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:1703
ip_neighbor_process_event_t_
ip_neighbor_process_event_t_
Definition: ip_neighbor.c:1559
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:1561
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
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:979
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:969
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
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:843
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
ethernet_address_change_ctx_t
Definition: ethernet.h:283
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:1006
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:1722
ip_neighbor_learn
void ip_neighbor_learn(const ip_neighbor_learn_t *l)
Definition: ip_neighbor.c:712
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:1774
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:1288
ip6_table_bind_callback_t::function
ip6_table_bind_function_t * function
Definition: ip6.h:106
key
typedef key
Definition: ipsec_types.api:88
ip_neighbor_command2
static vlib_cli_command_t ip_neighbor_command2
(constructor) VLIB_CLI_COMMAND (ip_neighbor_command2)
Definition: ip_neighbor.c:811
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:1461
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:1251
ip_neighbor_mark_one
static walk_rc_t ip_neighbor_mark_one(index_t ipni, void *ctx)
Definition: ip_neighbor.c:1228
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
ip_neighbor_table_bind_ctx_t_::new_fib_index
u32 new_fib_index
Definition: ip_neighbor.c:1460
ip_neighbor_walk_covered
static walk_rc_t ip_neighbor_walk_covered(index_t ipni, void *arg)
Definition: ip_neighbor.c:1341
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:887
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:929
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:731
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
ethernet_main_t_
Definition: ethernet.h:289
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:1420
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:1378
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:1106
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:1009
vlib_get_thread_index
static_always_inline uword vlib_get_thread_index(void)
Definition: threads.h:208
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:974
ip_neighbor_list_head
index_t ip_neighbor_list_head[N_AF]
protocol specific lists of time sorted neighbors
Definition: ip_neighbor.c:34
hash_create_mem
#define hash_create_mem(elts, key_bytes, value_bytes)
Definition: hash.h:660
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:1507
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
hash_set_mem
#define hash_set_mem(h, key, value)
Definition: hash.h:275
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
hash_foreach
#define hash_foreach(key_var, value_var, h, body)
Definition: hash.h:441
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:719
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:1041
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:943
ip_neighbor_age_state_t_
ip_neighbor_age_state_t_
Definition: ip_neighbor.c:1505
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:1508
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:1314
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:1126
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:1136
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
ethernet_main_t_::address_change_callbacks
ethernet_address_change_ctx_t * address_change_callbacks
Functions to call when interface hw address changes.
Definition: ethernet.h:334
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:838
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:861
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:2787
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:188
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:141
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:1515
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:1081
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:1033
ip_neighbor_populate
void ip_neighbor_populate(ip_address_family_t af, u32 sw_if_index)
Definition: ip_neighbor.c:1171
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:1465
hash_get_mem
#define hash_get_mem(h, key)
Definition: hash.h:269
ip_neighbor_get_index
static index_t ip_neighbor_get_index(const ip_neighbor_t *ipn)
Definition: ip_neighbor.c:98
ethernet_main
ethernet_main_t ethernet_main
Definition: init.c:45
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:455
ip_neighbor_flags_t
enum ip_neighbor_flags_t_ ip_neighbor_flags_t
ip_neighbor_table_bind_ctx_t_
Definition: ip_neighbor.c:1458
unformat_vnet_sw_interface
unformat_function_t unformat_vnet_sw_interface
Definition: interface_funcs.h:459
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:998
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:1355
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
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:1783
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:989
VLIB_NODE_TYPE_PROCESS
@ VLIB_NODE_TYPE_PROCESS
Definition: node.h:84
ip_neighbor_ethernet_change_mac
static void ip_neighbor_ethernet_change_mac(ethernet_main_t *em, u32 sw_if_index, uword opaque)
Definition: ip_neighbor.c:1146
ip_neighbor_sweep
void ip_neighbor_sweep(ip_address_family_t af)
Definition: ip_neighbor.c:1267
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:1094
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:1015
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:1769
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
hash_unset_mem
#define hash_unset_mem(h, key)
Definition: hash.h:291
rt
vnet_interface_output_runtime_t * rt
Definition: interface_output.c:399
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:1478
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:1333
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:1247
ip_neighbor_mark
void ip_neighbor_mark(ip_address_family_t af)
Definition: ip_neighbor.c:1240
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:1492
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:1336
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:325
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:964
IP_NEIGHBOR_PROCESS_SLEEP_LONG
#define IP_NEIGHBOR_PROCESS_SLEEP_LONG
Definition: ip_neighbor.c:1512
vlib_node_runtime_t
Definition: node.h:454
ip_neighbor_walk_covered_ctx_t_::addr
ip_address_t addr
Definition: ip_neighbor.c:1335
vlib_cli_command_t
Definition: cli.h:92
ip_neighbor_sort
static int ip_neighbor_sort(void *a1, void *a2)
Definition: ip_neighbor.c:820
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:984
ip_neighbor_command
static vlib_cli_command_t ip_neighbor_command
(constructor) VLIB_CLI_COMMAND (ip_neighbor_command)
Definition: ip_neighbor.c:805
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:253
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:922
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:1667
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:1674
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:1285
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:1679
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:1203
ip4_neighbor_proxy_disable
int ip4_neighbor_proxy_disable(u32 sw_if_index)
Definition: ip_neighbor.c:1116
flags
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:105