diff options
Diffstat (limited to 'src/vnet/ip-neighbor')
-rw-r--r-- | src/vnet/ip-neighbor/ip4_neighbor.c | 14 | ||||
-rw-r--r-- | src/vnet/ip-neighbor/ip6_neighbor.c | 9 | ||||
-rw-r--r-- | src/vnet/ip-neighbor/ip_neighbor.api | 36 | ||||
-rw-r--r-- | src/vnet/ip-neighbor/ip_neighbor.c | 119 | ||||
-rw-r--r-- | src/vnet/ip-neighbor/ip_neighbor.h | 2 | ||||
-rw-r--r-- | src/vnet/ip-neighbor/ip_neighbor_api.c | 28 | ||||
-rw-r--r-- | src/vnet/ip-neighbor/ip_neighbor_types.c | 15 | ||||
-rw-r--r-- | src/vnet/ip-neighbor/ip_neighbor_watch.c | 10 |
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* */ /* |