21 #include <vpp/app/version.h> 28 #define foreach_arping_error _ (NONE, "no error") 32 #define _(f, s) ARPING_ERROR_##f, 44 #define foreach_arping \ 45 _ (DROP, "error-drop") \ 46 _ (IO, "interface-output") 50 #define _(sym, str) ARPING_NEXT_##sym, 60 ethernet_arp_ip4_over_ethernet_address_t
reply;
65 #define _(sym, str) ARPING6_NEXT_##sym, 74 }) ethernet_arp_ip6_over_ethernet_address_t;
76 typedef struct arping6_trace_t_
80 ethernet_arp_ip6_over_ethernet_address_t
reply;
105 s =
format (s,
"sw-if-index: %u, type: %u, from %U (%U)", t->sw_if_index,
119 next_index = node->cached_next_index;
123 while (n_left_from > 0)
127 while (n_left_from >= 2 && n_left_to_next >= 2)
129 u32 next0, next1, bi0, bi1;
132 u32 sw_if_index0, sw_if_index1;
135 bi0 = to_next[0] = from[0];
136 bi1 = to_next[1] = from[1];
143 next0 = next1 = ARPING_NEXT_DROP;
158 clib_host_to_net_u16 (ETHERNET_ARP_OPCODE_reply)))
164 aif0->
recv.from4.ip4.as_u32 =
172 clib_host_to_net_u16 (ETHERNET_ARP_OPCODE_reply)))
178 aif1->
recv.from4.ip4.as_u32 =
206 n_left_to_next, bi0, bi1, next0,
210 while (n_left_from > 0 && n_left_to_next > 0)
218 bi0 = to_next[0] = from[0];
224 next0 = ARPING_NEXT_DROP;
234 clib_host_to_net_u16 (ETHERNET_ARP_OPCODE_reply)))
240 aif0->
recv.from4.ip4.as_u32 =
259 n_left_to_next, bi0, next0);
270 .name =
"arping-input",.vector_size =
sizeof (
u32),.format_trace =
272 ARPING_N_ERROR,.error_strings = arping_error_strings,.n_next_nodes =
275 [ARPING_NEXT_DROP] =
"error-drop",[ARPING_NEXT_IO] =
"interface-output",}
280 .node_name =
"arping-input",
291 next_index = node->cached_next_index;
292 n_left_from =
frame->n_vectors;
295 while (n_left_from > 0)
299 while (n_left_from >= 2 && n_left_to_next >= 2)
301 u32 next0, next1, bi0, bi1;
304 u32 sw_if_index0, sw_if_index1;
306 icmp6_neighbor_solicitation_or_advertisement_header_t *sol_adv0,
308 icmp6_neighbor_discovery_ethernet_link_layer_address_option_t
312 bi0 = to_next[0] = from[0];
313 bi1 = to_next[1] = from[1];
320 next0 = next1 = ARPING6_NEXT_DROP;
336 (icmp6_neighbor_discovery_ethernet_link_layer_address_option_t
340 ICMP6_neighbor_advertisement))
344 &sol_adv0->target_address,
349 &sol_adv0->target_address,
350 sizeof (aif0->
recv.from6.ip6));
352 lladdr0->ethernet_address, 6);
359 (icmp6_neighbor_discovery_ethernet_link_layer_address_option_t
363 ICMP6_neighbor_advertisement))
367 &sol_adv1->target_address,
372 &sol_adv1->target_address,
373 sizeof (aif1->
recv.from6.ip6));
375 lladdr1->ethernet_address, 6);
384 t->type = sol_adv0->icmp.type;
386 sizeof (t->reply.ip6));
393 t->type = sol_adv1->icmp.type;
395 sizeof (t->reply.ip6));
400 n_left_to_next, bi0, bi1, next0,
404 while (n_left_from > 0 && n_left_to_next > 0)
411 icmp6_neighbor_solicitation_or_advertisement_header_t *sol_adv0;
412 icmp6_neighbor_discovery_ethernet_link_layer_address_option_t
415 bi0 = to_next[0] = from[0];
421 next0 = ARPING_NEXT_DROP;
432 (icmp6_neighbor_discovery_ethernet_link_layer_address_option_t
435 ICMP6_neighbor_advertisement))
439 &sol_adv0->target_address,
444 &sol_adv0->target_address,
445 sizeof (aif0->
recv.from6.ip6));
447 lladdr0->ethernet_address, 6);
456 t->type = sol_adv0->icmp.type;
458 sizeof (t->reply.ip6));
463 n_left_to_next, bi0, next0);
469 return frame->n_vectors;
474 .name =
"arping6-input",.vector_size =
sizeof (
u32),.format_trace =
476 ARPING_N_ERROR,.error_strings = arping_error_strings,.n_next_nodes =
479 [ARPING6_NEXT_DROP] =
"error-drop",[ARPING6_NEXT_IO] =
"interface-output",}
483 .arc_name =
"ip6-local",
484 .node_name =
"arping6-input",
525 int enable_disable,
void *feature_config,
526 u32 n_feature_config_bytes)
530 enable_disable, feature_config,
531 n_feature_config_bytes);
560 0,
"arping command is in progress for the same interface. " 561 "Please try again later.");
562 args->
rv = VNET_API_ERROR_INVALID_VALUE;
606 while ((aif.
reply_count < send_count) && (wait_count < 10))
615 sizeof (args->
recv.from4));
622 sizeof (args->
recv.from6));
667 "expecting IP4/IP6 address `%U'. Usage: arping [gratuitous] <addr> " 668 "<intf> [repeat <count>] [interval <secs>]",
686 if (!
unformat (input,
"%f", &interval))
689 0,
"expecting interval (floating point number) got `%U'",
695 else if (
unformat (input,
"repeat"))
721 &args.
recv.from4.ip4);
724 vm,
"Received %u ICMP6 neighbor advertisements from %U (%U)",
770 .short_help =
"arping [gratuitous] {addr} {interface}" 771 " [interval {sec}] [repeat {cnt}]",
787 .version = VPP_BUILD_VER,
788 .description =
"Arping (arping)",
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index, VLIB_BUFFER_IS_TRACED: trace this buffer.
arping_intf_t ** interfaces
static clib_error_t * arping_cli_init(vlib_main_t *vm)
u8 * format_ethernet_arp_opcode(u8 *s, va_list *va)
static u8 * format_arping_trace(u8 *s, va_list *args)
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
arping_main_t arping_main
#define ARPING_DEFAULT_INTERVAL
static char * arping_error_strings[]
static u8 * format_arping6_trace(u8 *s, va_list *args)
unformat_function_t unformat_vnet_sw_interface
#define VLIB_NODE_FN(node)
#define vlib_worker_thread_barrier_sync(X)
#define clib_memcpy(d, s, n)
static uword vlib_process_suspend(vlib_main_t *vm, f64 dt)
Suspend a vlib cooperative multi-tasking thread for a period of time.
clib_error_t * arping_plugin_api_hookup(vlib_main_t *vm)
#define VLIB_INIT_FUNCTION(x)
description fragment has unexpected format
static clib_error_t * arping_ip_address(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
#define clib_error_return(e, args...)
vnet_main_t * vnet_get_main(void)
ethernet_arp_ip4_over_ethernet_address_t reply
void ip6_neighbor_advertise(vlib_main_t *vm, vnet_main_t *vnm, u32 sw_if_index, const ip6_address_t *addr)
vl_api_fib_path_type_t type
void ip4_neighbor_probe_dst(u32 sw_if_index, const ip4_address_t *dst)
#define ARPING_DEFAULT_REPEAT
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
int vnet_feature_enable_disable(const char *arc_name, const char *node_name, u32 sw_if_index, int enable_disable, void *feature_config, u32 n_feature_config_bytes)
#define vlib_validate_buffer_enqueue_x2(vm, node, next_index, to_next, n_left_to_next, bi0, bi1, next0, next1)
Finish enqueueing two buffers forward in the graph.
#define vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, bi0, next0)
Finish enqueueing one buffer forward in the graph.
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
Get pointer to next frame vector data by (vlib_node_runtime_t, next_index).
VNET_FEATURE_INIT(arping_feat_node, static)
#define VLIB_REGISTER_NODE(x,...)
static clib_error_t * arping_neighbor_advertisement(vlib_main_t *vm, arping_args_t *args)
typedef CLIB_PACKED(struct { mac_address_t mac;ip6_address_t ip6;})
#define clib_memcmp(s1, s2, m1)
static_always_inline void vnet_feature_next(u32 *next0, vlib_buffer_t *b0)
void ip4_neighbor_advertise(vlib_main_t *vm, vnet_main_t *vnm, u32 sw_if_index, const ip4_address_t *addr)
void ip6_neighbor_probe_dst(u32 sw_if_index, const ip6_address_t *dst)
static void arping_vnet_feature_enable_disable(vlib_main_t *vm, const char *arc_name, const char *node_name, u32 sw_if_index, int enable_disable, void *feature_config, u32 n_feature_config_bytes)
static void * ip6_next_header(ip6_header_t *i)
#define VLIB_CLI_COMMAND(x,...)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
vlib_main_t vlib_node_runtime_t * node
ip_address_family_t version
vlib_put_next_frame(vm, node, next_index, 0)
static_always_inline void * clib_memcpy_fast(void *restrict dst, const void *restrict src, size_t n)
#define VNET_FEATURES(...)
static void arping_vec_validate(vlib_main_t *vm, u32 sw_if_index)
struct arping_trace_t_ arping_trace_t
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
#define foreach_arping_error
VLIB buffer representation.
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
u8 * format_mac_address(u8 *s, va_list *args)
void arping_run_command(vlib_main_t *vm, arping_args_t *args)
void vlib_worker_thread_barrier_release(vlib_main_t *vm)
static clib_error_t * arping_neighbor_probe_dst(vlib_main_t *vm, arping_args_t *args)
void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
vlib_main_t vlib_node_runtime_t vlib_frame_t * frame