aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/ip-neighbor
diff options
context:
space:
mode:
Diffstat (limited to 'src/vnet/ip-neighbor')
-rw-r--r--src/vnet/ip-neighbor/ip4_neighbor.c14
-rw-r--r--src/vnet/ip-neighbor/ip6_neighbor.c9
-rw-r--r--src/vnet/ip-neighbor/ip_neighbor.api36
-rw-r--r--src/vnet/ip-neighbor/ip_neighbor.c119
-rw-r--r--src/vnet/ip-neighbor/ip_neighbor.h2
-rw-r--r--src/vnet/ip-neighbor/ip_neighbor_api.c28
-rw-r--r--src/vnet/ip-neighbor/ip_neighbor_types.c15
-rw-r--r--src/vnet/ip-neighbor/ip_neighbor_watch.c10
8 files changed, 139 insertions, 94 deletions
diff --git a/src/vnet/ip-neighbor/ip4_neighbor.c b/src/vnet/ip-neighbor/ip4_neighbor.c
index 5a6e8dd154c..61b9e768fe5 100644
--- a/src/vnet/ip-neighbor/ip4_neighbor.c
+++ b/src/vnet/ip-neighbor/ip4_neighbor.c
@@ -187,12 +187,16 @@ ip4_arp_inline (vlib_main_t * vm,
/* resolve the packet's destination */
ip4_header_t *ip0 = vlib_buffer_get_current (p0);
resolve0 = ip0->dst_address;
- src0 = adj0->sub_type.glean.rx_pfx.fp_addr.ip4;
}
else
+ /* resolve the incomplete adj */
+ resolve0 = adj0->sub_type.nbr.next_hop.ip4;
+
+ if (is_glean && adj0->sub_type.glean.rx_pfx.fp_len)
+ /* the glean is for a connected, local prefix */
+ src0 = adj0->sub_type.glean.rx_pfx.fp_addr.ip4;
+ else
{
- /* resolve the incomplete adj */
- resolve0 = adj0->sub_type.nbr.next_hop.ip4;
/* Src IP address in ARP header. */
if (!fib_sas4_get (sw_if_index0, &resolve0, &src0) &&
!ip4_sas_by_sw_if_index (sw_if_index0, &resolve0, &src0))
@@ -270,7 +274,6 @@ VLIB_NODE_FN (ip4_glean_node) (vlib_main_t * vm, vlib_node_runtime_t * node,
return (ip4_arp_inline (vm, node, frame, 1));
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (ip4_arp_node) =
{
.name = "ip4-arp",
@@ -296,7 +299,6 @@ VLIB_REGISTER_NODE (ip4_glean_node) =
[IP4_ARP_NEXT_DROP] = "ip4-drop",
},
};
-/* *INDENT-ON* */
#define foreach_notrace_ip4_arp_error \
_(THROTTLED) \
@@ -328,7 +330,7 @@ ip4_neighbor_main_loop_enter (vlib_main_t * vm)
vlib_thread_main_t *tm = &vlib_thread_main;
u32 n_vlib_mains = tm->n_vlib_mains;
- throttle_init (&arp_throttle, n_vlib_mains, 1e-3);
+ throttle_init (&arp_throttle, n_vlib_mains, THROTTLE_BITS, 1e-3);
return (NULL);
}
diff --git a/src/vnet/ip-neighbor/ip6_neighbor.c b/src/vnet/ip-neighbor/ip6_neighbor.c
index 576ae570c0f..ca8aed3d4ca 100644
--- a/src/vnet/ip-neighbor/ip6_neighbor.c
+++ b/src/vnet/ip-neighbor/ip6_neighbor.c
@@ -217,13 +217,14 @@ ip6_discover_neighbor_inline (vlib_main_t * vm,
* Choose source address based on destination lookup
* adjacency.
*/
- if (!fib_sas6_get (sw_if_index0, &ip0->dst_address, &src) ||
- !ip6_sas_by_sw_if_index (sw_if_index0, &ip0->dst_address, &src))
+ const ip6_address_t *ll = ip6_get_link_local_address (sw_if_index0);
+ if (!ll)
{
/* There is no address on the interface */
p0->error = node->errors[IP6_NEIGHBOR_ERROR_NO_SOURCE_ADDRESS];
continue;
}
+ ip6_address_copy (&src, ll);
b0 = ip6_neighbor_probe (vm, vnm, sw_if_index0, thread_index, &src,
&ip0->dst_address);
@@ -263,7 +264,6 @@ ip6_glean (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
return (ip6_discover_neighbor_inline (vm, node, frame, 1));
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (ip6_glean_node) =
{
.function = ip6_glean,
@@ -294,7 +294,6 @@ VLIB_REGISTER_NODE (ip6_discover_neighbor_node) =
[IP6_NBR_NEXT_REPLY_TX] = "ip6-rewrite-mcast",
},
};
-/* *INDENT-ON* */
/* Template used to generate IP6 neighbor solicitation packets. */
vlib_packet_template_t ip6_neighbor_packet_template;
@@ -338,7 +337,7 @@ ip6_nd_main_loop_enter (vlib_main_t * vm)
{
vlib_thread_main_t *tm = &vlib_thread_main;
- throttle_init (&nd_throttle, tm->n_vlib_mains, 1e-3);
+ throttle_init (&nd_throttle, tm->n_vlib_mains, THROTTLE_BITS, 1e-3);
return 0;
}
diff --git a/src/vnet/ip-neighbor/ip_neighbor.api b/src/vnet/ip-neighbor/ip_neighbor.api
index a04fcbc569e..24cddd42fab 100644
--- a/src/vnet/ip-neighbor/ip_neighbor.api
+++ b/src/vnet/ip-neighbor/ip_neighbor.api
@@ -20,7 +20,7 @@
called through a shared memory interface.
*/
-option version = "1.0.0";
+option version = "1.0.1";
import "vnet/ip/ip_types.api";
import "vnet/ethernet/ethernet_types.api";
@@ -126,6 +126,40 @@ autoreply define ip_neighbor_config
bool recycle;
};
+/** \brief Get neighbor database configuration per AF
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param af - Address family (v4/v6)
+*/
+define ip_neighbor_config_get
+{
+ option in_progress;
+ u32 client_index;
+ u32 context;
+ vl_api_address_family_t af;
+};
+
+/** \brief Neighbor database configuration reply
+ @param context - sender context, to match reply w/ request
+ @param retval - error (0 is "no error")
+ @param af - Address family (v4/v6)
+ @param max_number - The maximum number of neighbours that will be created
+ @param max_age - The maximum age (in seconds) before an inactive neighbour
+ is flushed
+ @param recycle - If max_number of neighbours is reached and new ones need
+ to be created, should the oldest neighbour be 'recycled'
+*/
+define ip_neighbor_config_get_reply
+{
+ option in_progress;
+ u32 context;
+ i32 retval;
+ vl_api_address_family_t af;
+ u32 max_number;
+ u32 max_age;
+ bool recycle;
+};
+
/** \brief IP neighbour replace begin
The use-case is that, for some unspecified reason, the control plane
diff --git a/src/vnet/ip-neighbor/ip_neighbor.c b/src/vnet/ip-neighbor/ip_neighbor.c
index b33ca8a3538..614b78489cd 100644
--- a/src/vnet/ip-neighbor/ip_neighbor.c
+++ b/src/vnet/ip-neighbor/ip_neighbor.c
@@ -130,7 +130,6 @@ typedef struct ip_neighbor_db_t_
static vlib_log_class_t ipn_logger;
/* DBs of neighbours one per AF */
-/* *INDENT-OFF* */
static ip_neighbor_db_t ip_neighbor_db[N_AF] = {
[AF_IP4] = {
.ipndb_limit = 50000,
@@ -145,7 +144,6 @@ static ip_neighbor_db_t ip_neighbor_db[N_AF] = {
.ipndb_recycle = false,
}
};
-/* *INDENT-ON* */
#define IP_NEIGHBOR_DBG(...) \
vlib_log_debug (ipn_logger, __VA_ARGS__);
@@ -462,6 +460,7 @@ ip_neighbor_destroy (ip_neighbor_t * ipn)
af = ip_neighbor_get_af (ipn);
IP_NEIGHBOR_DBG ("free: %U", format_ip_neighbor,
+ vlib_time_now (vlib_get_main ()),
ip_neighbor_get_index (ipn));
ip_neighbor_publish (ip_neighbor_get_index (ipn),
@@ -797,7 +796,7 @@ ip_neighbor_cmd (vlib_main_t * vm,
vnet_main_t *vnm = vnet_get_main ();
ip_neighbor_flags_t flags;
u32 sw_if_index = ~0;
- int is_add = 1;
+ int is_add = 1, is_flush = 0;
int count = 1;
flags = IP_NEIGHBOR_FLAG_DYNAMIC;
@@ -811,6 +810,8 @@ ip_neighbor_cmd (vlib_main_t * vm,
;
else if (unformat (input, "delete") || unformat (input, "del"))
is_add = 0;
+ else if (unformat (input, "flush"))
+ is_flush = 1;
else if (unformat (input, "static"))
{
flags |= IP_NEIGHBOR_FLAG_STATIC;
@@ -824,6 +825,13 @@ ip_neighbor_cmd (vlib_main_t * vm,
break;
}
+ if (is_flush)
+ {
+ ip_neighbor_del_all (AF_IP4, sw_if_index);
+ ip_neighbor_del_all (AF_IP6, sw_if_index);
+ return NULL;
+ }
+
if (sw_if_index == ~0 ||
ip_address_is_zero (&ip) || mac_address_is_zero (&mac))
return clib_error_return (0,
@@ -846,11 +854,10 @@ ip_neighbor_cmd (vlib_main_t * vm,
return NULL;
}
-/* *INDENT-OFF* */
/*?
* Add or delete IPv4 ARP cache entries.
*
- * @note 'set ip neighbor' options (e.g. delete, static, 'fib-id <id>',
+ * @note 'set ip neighbor' options (e.g. delete, static,
* 'count <number>', 'interface ip4_addr mac_addr') can be added in
* any order and combination.
*
@@ -859,35 +866,39 @@ ip_neighbor_cmd (vlib_main_t * vm,
* Add or delete IPv4 ARP cache entries as follows. MAC Address can be in
* either aa:bb:cc:dd:ee:ff format or aabb.ccdd.eeff format.
* @cliexcmd{set ip neighbor GigabitEthernet2/0/0 6.0.0.3 dead.beef.babe}
- * @cliexcmd{set ip neighbor delete GigabitEthernet2/0/0 6.0.0.3 de:ad:be:ef:ba:be}
+ * @cliexcmd{set ip neighbor delete GigabitEthernet2/0/0 6.0.0.3
+ * de:ad:be:ef:ba:be}
*
- * To add or delete an IPv4 ARP cache entry to or from a specific fib
+ * To add or delete an IPv4 ARP cache entry
* table:
- * @cliexcmd{set ip neighbor fib-id 1 GigabitEthernet2/0/0 6.0.0.3 dead.beef.babe}
- * @cliexcmd{set ip neighbor fib-id 1 delete GigabitEthernet2/0/0 6.0.0.3 dead.beef.babe}
+ * @cliexcmd{set ip neighbor GigabitEthernet2/0/0 6.0.0.3 dead.beef.babe}
+ * @cliexcmd{set ip neighbor delete GigabitEthernet2/0/0 6.0.0.3
+ * dead.beef.babe}
*
* Add or delete IPv4 static ARP cache entries as follows:
- * @cliexcmd{set ip neighbor static GigabitEthernet2/0/0 6.0.0.3 dead.beef.babe}
- * @cliexcmd{set ip neighbor static delete GigabitEthernet2/0/0 6.0.0.3 dead.beef.babe}
+ * @cliexcmd{set ip neighbor static GigabitEthernet2/0/0 6.0.0.3
+ * dead.beef.babe}
+ * @cliexcmd{set ip neighbor static delete GigabitEthernet2/0/0 6.0.0.3
+ * dead.beef.babe}
*
* For testing / debugging purposes, the 'set ip neighbor' command can add or
* delete multiple entries. Supply the 'count N' parameter:
- * @cliexcmd{set ip neighbor count 10 GigabitEthernet2/0/0 6.0.0.3 dead.beef.babe}
+ * @cliexcmd{set ip neighbor count 10 GigabitEthernet2/0/0 6.0.0.3
+ * dead.beef.babe}
* @endparblock
?*/
VLIB_CLI_COMMAND (ip_neighbor_command, static) = {
.path = "set ip neighbor",
- .short_help =
- "set ip neighbor [del] <intfc> <ip-address> <mac-address> [static] [no-fib-entry] [count <count>] [fib-id <fib-id>] [proxy <lo-addr> - <hi-addr>]",
+ .short_help = "set ip neighbor [del] <intfc> <ip-address> <mac-address> "
+ "[static] [no-fib-entry] [count <count>]",
.function = ip_neighbor_cmd,
};
VLIB_CLI_COMMAND (ip_neighbor_command2, static) = {
.path = "ip neighbor",
- .short_help =
- "ip neighbor [del] <intfc> <ip-address> <mac-address> [static] [no-fib-entry] [count <count>] [fib-id <fib-id>] [proxy <lo-addr> - <hi-addr>]",
+ .short_help = "ip neighbor [del] [flush] <intfc> <ip-address> <mac-address> "
+ "[static] [no-fib-entry] [count <count>]",
.function = ip_neighbor_cmd,
};
-/* *INDENT-ON* */
static int
ip_neighbor_sort (void *a1, void *a2)
@@ -913,7 +924,6 @@ ip_neighbor_entries (u32 sw_if_index, ip_address_family_t af)
index_t *ipnis = NULL;
ip_neighbor_t *ipn;
- /* *INDENT-OFF* */
pool_foreach (ipn, ip_neighbor_pool)
{
if ((sw_if_index == ~0 ||
@@ -923,7 +933,6 @@ ip_neighbor_entries (u32 sw_if_index, ip_address_family_t af)
vec_add1 (ipnis, ip_neighbor_get_index(ipn));
}
- /* *INDENT-ON* */
if (ipnis)
vec_sort_with_function (ipnis, ip_neighbor_sort);
@@ -936,22 +945,20 @@ ip_neighbor_show_sorted_i (vlib_main_t * vm,
vlib_cli_command_t * cmd, ip_address_family_t af)
{
ip_neighbor_elt_t *elt, *head;
+ f64 now;
head = pool_elt_at_index (ip_neighbor_elt_pool, ip_neighbor_list_head[af]);
+ now = vlib_time_now (vm);
+ vlib_cli_output (vm, "%=12s%=40s%=6s%=20s%=24s", "Age", "IP", "Flags",
+ "Ethernet", "Interface");
- vlib_cli_output (vm, "%=12s%=40s%=6s%=20s%=24s", "Time", "IP",
- "Flags", "Ethernet", "Interface");
-
- /* *INDENT-OFF*/
/* the list is time sorted, newest first, so start from the back
* and work forwards. Stop when we get to one that is alive */
- clib_llist_foreach_reverse(ip_neighbor_elt_pool,
- ipne_anchor, head, elt,
- ({
- vlib_cli_output (vm, "%U", format_ip_neighbor, elt->ipne_index);
- }));
- /* *INDENT-ON*/
+ clib_llist_foreach_reverse (ip_neighbor_elt_pool, ipne_anchor, head, elt, ({
+ vlib_cli_output (vm, "%U", format_ip_neighbor,
+ now, elt->ipne_index);
+ }));
return (NULL);
}
@@ -963,6 +970,7 @@ ip_neighbor_show_i (vlib_main_t * vm,
{
index_t *ipni, *ipnis = NULL;
u32 sw_if_index;
+ f64 now;
/* Filter entries by interface if given. */
sw_if_index = ~0;
@@ -970,14 +978,15 @@ ip_neighbor_show_i (vlib_main_t * vm,
&sw_if_index);
ipnis = ip_neighbor_entries (sw_if_index, af);
+ now = vlib_time_now (vm);
if (ipnis)
- vlib_cli_output (vm, "%=12s%=40s%=6s%=20s%=24s", "Time", "IP",
- "Flags", "Ethernet", "Interface");
+ vlib_cli_output (vm, "%=12s%=40s%=6s%=20s%=24s", "Age", "IP", "Flags",
+ "Ethernet", "Interface");
vec_foreach (ipni, ipnis)
{
- vlib_cli_output (vm, "%U", format_ip_neighbor, *ipni);
+ vlib_cli_output (vm, "%U", format_ip_neighbor, now, *ipni);
}
vec_free (ipnis);
@@ -1033,7 +1042,6 @@ ip4_neighbor_show_sorted (vlib_main_t * vm,
* Fib_index 0 6.0.0.1 - 6.0.0.11
* @cliexend
?*/
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (show_ip_neighbors_cmd_node, static) = {
.path = "show ip neighbors",
.function = ip_neighbor_show,
@@ -1074,7 +1082,6 @@ VLIB_CLI_COMMAND (show_ip6_neighbor_sorted_cmd_node, static) = {
.function = ip6_neighbor_show_sorted,
.short_help = "show ip6 neighbor-sorted",
};
-/* *INDENT-ON* */
static ip_neighbor_vft_t ip_nbr_vfts[N_AF];
@@ -1124,13 +1131,11 @@ ip_neighbor_walk (ip_address_family_t af,
vec_foreach (hash, ip_neighbor_db[af].ipndb_hash)
{
- /* *INDENT-OFF* */
hash_foreach (key, ipni, *hash,
({
if (WALK_STOP == cb (ipni, ctx))
break;
}));
- /* *INDENT-ON* */
}
}
else
@@ -1141,13 +1146,11 @@ ip_neighbor_walk (ip_address_family_t af,
return;
hash = ip_neighbor_db[af].ipndb_hash[sw_if_index];
- /* *INDENT-OFF* */
hash_foreach (key, ipni, hash,
({
if (WALK_STOP == cb (ipni, ctx))
break;
}));
- /* *INDENT-ON* */
}
}
@@ -1226,14 +1229,12 @@ ip_neighbor_populate (ip_address_family_t af, u32 sw_if_index)
format_vnet_sw_if_index_name, vnet_get_main (),
sw_if_index, format_ip_address_family, af);
- /* *INDENT-OFF* */
pool_foreach (ipn, ip_neighbor_pool)
{
if (ip_neighbor_get_af(ipn) == af &&
ipn->ipn_key->ipnk_sw_if_index == sw_if_index)
vec_add1 (ipnis, ipn - ip_neighbor_pool);
}
- /* *INDENT-ON* */
vec_foreach (ipni, ipnis)
{
@@ -1259,7 +1260,6 @@ ip_neighbor_flush (ip_address_family_t af, u32 sw_if_index)
format_vnet_sw_if_index_name, vnet_get_main (),
sw_if_index, format_ip_address_family, af);
- /* *INDENT-OFF* */
pool_foreach (ipn, ip_neighbor_pool)
{
if (ip_neighbor_get_af(ipn) == af &&
@@ -1267,7 +1267,6 @@ ip_neighbor_flush (ip_address_family_t af, u32 sw_if_index)
ip_neighbor_is_dynamic (ipn))
vec_add1 (ipnis, ipn - ip_neighbor_pool);
}
- /* *INDENT-ON* */
vec_foreach (ipni, ipnis) ip_neighbor_destroy (ip_neighbor_get (*ipni));
vec_free (ipnis);
@@ -1447,7 +1446,6 @@ ip_neighbor_add_del_interface_address_v4 (ip4_main_t * im,
if (is_del)
{
- /* *INDENT-OFF* */
ip_neighbor_walk_covered_ctx_t ctx = {
.addr = {
.ip.ip4 = *address,
@@ -1455,7 +1453,6 @@ ip_neighbor_add_del_interface_address_v4 (ip4_main_t * im,
},
.length = address_length,
};
- /* *INDENT-ON* */
index_t *ipni;
ip_neighbor_walk (AF_IP4, sw_if_index, ip_neighbor_walk_covered, &ctx);
@@ -1489,7 +1486,6 @@ ip_neighbor_add_del_interface_address_v6 (ip6_main_t * im,
if (is_del)
{
- /* *INDENT-OFF* */
ip_neighbor_walk_covered_ctx_t ctx = {
.addr = {
.ip.ip6 = *address,
@@ -1497,7 +1493,6 @@ ip_neighbor_add_del_interface_address_v6 (ip6_main_t * im,
},
.length = address_length,
};
- /* *INDENT-ON* */
index_t *ipni;
ip_neighbor_walk (AF_IP6, sw_if_index, ip_neighbor_walk_covered, &ctx);
@@ -1581,20 +1576,19 @@ ip_neighbour_age_out (index_t ipni, f64 now, f64 * wait)
if (ttl > ipndb_age)
{
- IP_NEIGHBOR_DBG ("aged: %U @%f - %f > %d",
- format_ip_neighbor, ipni, now,
- ipn->ipn_time_last_updated, ipndb_age);
+ IP_NEIGHBOR_DBG ("aged: %U @%f - %f > %d", format_ip_neighbor, now, ipni,
+ now, ipn->ipn_time_last_updated, ipndb_age);
if (ipn->ipn_n_probes > 2)
{
/* 3 strikes and yea-re out */
- IP_NEIGHBOR_DBG ("dead: %U", format_ip_neighbor, ipni);
+ IP_NEIGHBOR_DBG ("dead: %U", format_ip_neighbor, now, ipni);
*wait = 1;
return (IP_NEIGHBOR_AGE_DEAD);
}
else
{
- ip_neighbor_probe_dst (ip_neighbor_get_sw_if_index (ipn), af,
- vlib_get_thread_index (),
+ ip_neighbor_probe_dst (ip_neighbor_get_sw_if_index (ipn),
+ vlib_get_thread_index (), af,
&ip_addr_46 (&ipn->ipn_key->ipnk_ip));
ipn->ipn_n_probes++;
@@ -1653,7 +1647,6 @@ ip_neighbor_age_loop (vlib_main_t * vm,
head = pool_elt_at_index (ip_neighbor_elt_pool,
ip_neighbor_list_head[af]);
- /* *INDENT-OFF*/
/* the list is time sorted, newest first, so start from the back
* and work forwards. Stop when we get to one that is alive */
restart:
@@ -1678,7 +1671,6 @@ ip_neighbor_age_loop (vlib_main_t * vm,
timeout = clib_min (wait, timeout);
}));
- /* *INDENT-ON* */
break;
}
case IP_NEIGHBOR_AGE_PROCESS_WAKEUP:
@@ -1725,7 +1717,6 @@ ip6_neighbor_age_process (vlib_main_t * vm,
return (ip_neighbor_age_loop (vm, rt, f, AF_IP6));
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (ip4_neighbor_age_process_node,static) = {
.function = ip4_neighbor_age_process,
.type = VLIB_NODE_TYPE_PROCESS,
@@ -1736,7 +1727,6 @@ VLIB_REGISTER_NODE (ip6_neighbor_age_process_node,static) = {
.type = VLIB_NODE_TYPE_PROCESS,
.name = "ip6-neighbor-age-process",
};
-/* *INDENT-ON* */
int
ip_neighbor_config (ip_address_family_t af, u32 limit, u32 age, bool recycle)
@@ -1754,13 +1744,23 @@ ip_neighbor_config (ip_address_family_t af, u32 limit, u32 age, bool recycle)
return (0);
}
+int
+ip_neighbor_get_config (ip_address_family_t af, u32 *limit, u32 *age,
+ bool *recycle)
+{
+ *limit = ip_neighbor_db[af].ipndb_limit;
+ *age = ip_neighbor_db[af].ipndb_age;
+ *recycle = ip_neighbor_db[af].ipndb_recycle;
+
+ return (0);
+}
+
static clib_error_t *
ip_neighbor_config_show (vlib_main_t * vm,
unformat_input_t * input, vlib_cli_command_t * cmd)
{
ip_address_family_t af;
- /* *INDENT-OFF* */
FOR_EACH_IP_ADDRESS_FAMILY(af) {
vlib_cli_output (vm, "%U:", format_ip_address_family, af);
vlib_cli_output (vm, " limit:%d, age:%d, recycle:%d",
@@ -1769,7 +1769,6 @@ ip_neighbor_config_show (vlib_main_t * vm,
ip_neighbor_db[af].ipndb_recycle);
}
- /* *INDENT-ON* */
return (NULL);
}
@@ -1861,7 +1860,6 @@ ip_neighbor_stats_show (vlib_main_t *vm, unformat_input_t *input,
return (NULL);
}
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (show_ip_neighbor_cfg_cmd_node, static) = {
.path = "show ip neighbor-config",
.function = ip_neighbor_config_show,
@@ -1878,7 +1876,6 @@ VLIB_CLI_COMMAND (show_ip_neighbor_stats_cmd_node, static) = {
.function = ip_neighbor_stats_show,
.short_help = "show ip neighbor-stats [interface]",
};
-/* *INDENT-ON* */
static clib_error_t *
ip_neighbor_init (vlib_main_t * vm)
@@ -1918,12 +1915,10 @@ ip_neighbor_init (vlib_main_t * vm)
return (NULL);
}
-/* *INDENT-OFF* */
VLIB_INIT_FUNCTION (ip_neighbor_init) =
{
.runs_after = VLIB_INITS("ip_main_init"),
};
-/* *INDENT-ON* */
/*
* fd.io coding-style-patch-verification: ON
diff --git a/src/vnet/ip-neighbor/ip_neighbor.h b/src/vnet/ip-neighbor/ip_neighbor.h
index 8c07df86ba8..cc888ba2054 100644
--- a/src/vnet/ip-neighbor/ip_neighbor.h
+++ b/src/vnet/ip-neighbor/ip_neighbor.h
@@ -36,6 +36,8 @@ extern int ip_neighbor_del (const ip_address_t * ip, u32 sw_if_index);
extern int ip_neighbor_config (ip_address_family_t af,
u32 limit, u32 age, bool recycle);
+extern int ip_neighbor_get_config (ip_address_family_t af, u32 *limit,
+ u32 *age, bool *recycle);
extern void ip_neighbor_del_all (ip_address_family_t af, u32 sw_if_index);
diff --git a/src/vnet/ip-neighbor/ip_neighbor_api.c b/src/vnet/ip-neighbor/ip_neighbor_api.c
index 81af86211de..2297546f111 100644
--- a/src/vnet/ip-neighbor/ip_neighbor_api.c
+++ b/src/vnet/ip-neighbor/ip_neighbor_api.c
@@ -234,12 +234,10 @@ vl_api_ip_neighbor_add_del_t_handler (vl_api_ip_neighbor_add_del_t * mp,
BAD_SW_IF_INDEX_LABEL;
- /* *INDENT-OFF* */
REPLY_MACRO2 (VL_API_IP_NEIGHBOR_ADD_DEL_REPLY,
({
rmp->stats_index = htonl (stats_index);
}));
- /* *INDENT-ON* */
}
static void
@@ -314,6 +312,32 @@ vl_api_ip_neighbor_config_t_handler (vl_api_ip_neighbor_config_t * mp)
}
static void
+vl_api_ip_neighbor_config_get_t_handler (vl_api_ip_neighbor_config_get_t *mp)
+{
+ vl_api_ip_neighbor_config_get_reply_t *rmp;
+ int rv;
+ ip_address_family_t af = AF_IP4;
+ u32 max_number = ~0;
+ u32 max_age = ~0;
+ bool recycle = false;
+
+ rv = ip_address_family_decode (mp->af, &af);
+
+ if (!rv)
+ rv = ip_neighbor_get_config (af, &max_number, &max_age, &recycle);
+
+ // clang-format off
+ REPLY_MACRO2 (VL_API_IP_NEIGHBOR_CONFIG_GET_REPLY,
+ ({
+ rmp->af = ip_address_family_encode (af);
+ rmp->max_number = htonl (max_number);
+ rmp->max_age = htonl (max_age);
+ rmp->recycle = recycle;
+ }));
+ // clang-format on
+}
+
+static void
vl_api_ip_neighbor_replace_begin_t_handler (vl_api_ip_neighbor_replace_begin_t
* mp)
{
diff --git a/src/vnet/ip-neighbor/ip_neighbor_types.c b/src/vnet/ip-neighbor/ip_neighbor_types.c
index 39039a48249..a6f3c26d42f 100644
--- a/src/vnet/ip-neighbor/ip_neighbor_types.c
+++ b/src/vnet/ip-neighbor/ip_neighbor_types.c
@@ -68,19 +68,18 @@ format_ip_neighbor_watcher (u8 * s, va_list * va)
u8 *
format_ip_neighbor (u8 * s, va_list * va)
{
+ f64 now = va_arg (*va, f64);
index_t ipni = va_arg (*va, index_t);
ip_neighbor_t *ipn;
ipn = ip_neighbor_get (ipni);
- return (format (s, "%=12U%=40U%=6U%=20U%U",
- format_vlib_time, vlib_get_main (),
- ipn->ipn_time_last_updated,
- format_ip_address, &ipn->ipn_key->ipnk_ip,
- format_ip_neighbor_flags, ipn->ipn_flags,
- format_mac_address_t, &ipn->ipn_mac,
- format_vnet_sw_if_index_name, vnet_get_main (),
- ipn->ipn_key->ipnk_sw_if_index));
+ return (
+ format (s, "%=12U%=40U%=6U%=20U%U", format_vlib_time, vlib_get_main (),
+ now - ipn->ipn_time_last_updated, format_ip_address,
+ &ipn->ipn_key->ipnk_ip, format_ip_neighbor_flags, ipn->ipn_flags,
+ format_mac_address_t, &ipn->ipn_mac, format_vnet_sw_if_index_name,
+ vnet_get_main (), ipn->ipn_key->ipnk_sw_if_index));
}
static void
diff --git a/src/vnet/ip-neighbor/ip_neighbor_watch.c b/src/vnet/ip-neighbor/ip_neighbor_watch.c
index 72908f4e613..74f450114e1 100644
--- a/src/vnet/ip-neighbor/ip_neighbor_watch.c
+++ b/src/vnet/ip-neighbor/ip_neighbor_watch.c
@@ -66,13 +66,11 @@ ip_neighbor_event_process (vlib_main_t * vm,
return 0;
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (ip_neighbor_event_process_node) = {
.function = ip_neighbor_event_process,
.type = VLIB_NODE_TYPE_PROCESS,
.name = "ip-neighbor-event",
};
-/* *INDENT-ON* */
static clib_error_t *
@@ -84,7 +82,6 @@ want_ip_neighbor_events_reaper (u32 client_index)
i32 pos;
/* walk the entire IP neighbour DB and removes the client's registrations */
- /* *INDENT-OFF* */
mhash_foreach(key, v, &ipnw_db.ipnwdb_hash,
({
watchers = (ip_neighbor_watcher_t*) *v;
@@ -97,7 +94,6 @@ want_ip_neighbor_events_reaper (u32 client_index)
if (vec_len(watchers) == 0)
vec_add1 (empty_keys, *key);
}));
- /* *INDENT-OFF* */
vec_foreach (key, empty_keys)
mhash_unset (&ipnw_db.ipnwdb_hash, key, NULL);
@@ -236,7 +232,6 @@ ip_neighbor_watchers_show (vlib_main_t * vm,
ip_neighbor_key_t *key;
uword *v;
- /* *INDENT-OFF* */
mhash_foreach(key, v, &ipnw_db.ipnwdb_hash,
({
watchers = (ip_neighbor_watcher_t*) *v;
@@ -247,17 +242,14 @@ ip_neighbor_watchers_show (vlib_main_t * vm,
vec_foreach (watcher, watchers)
vlib_cli_output (vm, " %U", format_ip_neighbor_watcher, watcher);
}));
- /* *INDENT-ON* */
return (NULL);
}
-/* *INDENT-OFF* */
VLIB_CLI_COMMAND (show_ip_neighbor_watchers_cmd_node, static) = {
.path = "show ip neighbor-watcher",
.function = ip_neighbor_watchers_show,
.short_help = "show ip neighbors-watcher",
};
-/* *INDENT-ON* */
static clib_error_t *
ip_neighbor_watch_init (vlib_main_t * vm)
@@ -267,12 +259,10 @@ ip_neighbor_watch_init (vlib_main_t * vm)
return (NULL);
}
-/* *INDENT-OFF* */
VLIB_INIT_FUNCTION (ip_neighbor_watch_init) =
{
.runs_after = VLIB_INITS("ip_neighbor_init"),
};
-/* *INDENT-ON* */
/*