ping: move the echo responder into the ping plugin
Type: feature Change-Id: I246346b82858e73b16d727e2106350bc0fc3c6f2 Signed-off-by: Neale Ranns <nranns@cisco.com>
This commit is contained in:
@ -364,6 +364,214 @@ VLIB_REGISTER_NODE (ip4_icmp_echo_reply_node, static) =
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
static uword
|
||||
ip4_icmp_echo_request (vlib_main_t * vm,
|
||||
vlib_node_runtime_t * node, vlib_frame_t * frame)
|
||||
{
|
||||
uword n_packets = frame->n_vectors;
|
||||
u32 *from, *to_next;
|
||||
u32 n_left_from, n_left_to_next, next;
|
||||
ip4_main_t *i4m = &ip4_main;
|
||||
u16 *fragment_ids, *fid;
|
||||
u8 host_config_ttl = i4m->host_config.ttl;
|
||||
|
||||
from = vlib_frame_vector_args (frame);
|
||||
n_left_from = n_packets;
|
||||
next = node->cached_next_index;
|
||||
|
||||
if (node->flags & VLIB_NODE_FLAG_TRACE)
|
||||
vlib_trace_frame_buffers_only (vm, node, from, frame->n_vectors,
|
||||
/* stride */ 1,
|
||||
sizeof (icmp_input_trace_t));
|
||||
|
||||
/* Get random fragment IDs for replies. */
|
||||
fid = fragment_ids = clib_random_buffer_get_data (&vm->random_buffer,
|
||||
n_packets *
|
||||
sizeof (fragment_ids[0]));
|
||||
|
||||
while (n_left_from > 0)
|
||||
{
|
||||
vlib_get_next_frame (vm, node, next, to_next, n_left_to_next);
|
||||
|
||||
while (n_left_from > 2 && n_left_to_next > 2)
|
||||
{
|
||||
vlib_buffer_t *p0, *p1;
|
||||
ip4_header_t *ip0, *ip1;
|
||||
icmp46_header_t *icmp0, *icmp1;
|
||||
u32 bi0, src0, dst0;
|
||||
u32 bi1, src1, dst1;
|
||||
ip_csum_t sum0, sum1;
|
||||
|
||||
bi0 = to_next[0] = from[0];
|
||||
bi1 = to_next[1] = from[1];
|
||||
|
||||
from += 2;
|
||||
n_left_from -= 2;
|
||||
to_next += 2;
|
||||
n_left_to_next -= 2;
|
||||
|
||||
p0 = vlib_get_buffer (vm, bi0);
|
||||
p1 = vlib_get_buffer (vm, bi1);
|
||||
ip0 = vlib_buffer_get_current (p0);
|
||||
ip1 = vlib_buffer_get_current (p1);
|
||||
icmp0 = ip4_next_header (ip0);
|
||||
icmp1 = ip4_next_header (ip1);
|
||||
|
||||
vnet_buffer (p0)->sw_if_index[VLIB_RX] =
|
||||
vnet_main.local_interface_sw_if_index;
|
||||
vnet_buffer (p1)->sw_if_index[VLIB_RX] =
|
||||
vnet_main.local_interface_sw_if_index;
|
||||
|
||||
/* Update ICMP checksum. */
|
||||
sum0 = icmp0->checksum;
|
||||
sum1 = icmp1->checksum;
|
||||
|
||||
ASSERT (icmp0->type == ICMP4_echo_request);
|
||||
ASSERT (icmp1->type == ICMP4_echo_request);
|
||||
sum0 = ip_csum_update (sum0, ICMP4_echo_request, ICMP4_echo_reply,
|
||||
icmp46_header_t, type);
|
||||
sum1 = ip_csum_update (sum1, ICMP4_echo_request, ICMP4_echo_reply,
|
||||
icmp46_header_t, type);
|
||||
icmp0->type = ICMP4_echo_reply;
|
||||
icmp1->type = ICMP4_echo_reply;
|
||||
|
||||
icmp0->checksum = ip_csum_fold (sum0);
|
||||
icmp1->checksum = ip_csum_fold (sum1);
|
||||
|
||||
src0 = ip0->src_address.data_u32;
|
||||
src1 = ip1->src_address.data_u32;
|
||||
dst0 = ip0->dst_address.data_u32;
|
||||
dst1 = ip1->dst_address.data_u32;
|
||||
|
||||
/* Swap source and destination address.
|
||||
Does not change checksum. */
|
||||
ip0->src_address.data_u32 = dst0;
|
||||
ip1->src_address.data_u32 = dst1;
|
||||
ip0->dst_address.data_u32 = src0;
|
||||
ip1->dst_address.data_u32 = src1;
|
||||
|
||||
/* Update IP checksum. */
|
||||
sum0 = ip0->checksum;
|
||||
sum1 = ip1->checksum;
|
||||
|
||||
sum0 = ip_csum_update (sum0, ip0->ttl, host_config_ttl,
|
||||
ip4_header_t, ttl);
|
||||
sum1 = ip_csum_update (sum1, ip1->ttl, host_config_ttl,
|
||||
ip4_header_t, ttl);
|
||||
ip0->ttl = host_config_ttl;
|
||||
ip1->ttl = host_config_ttl;
|
||||
|
||||
/* New fragment id. */
|
||||
sum0 = ip_csum_update (sum0, ip0->fragment_id, fid[0],
|
||||
ip4_header_t, fragment_id);
|
||||
sum1 = ip_csum_update (sum1, ip1->fragment_id, fid[1],
|
||||
ip4_header_t, fragment_id);
|
||||
ip0->fragment_id = fid[0];
|
||||
ip1->fragment_id = fid[1];
|
||||
fid += 2;
|
||||
|
||||
ip0->checksum = ip_csum_fold (sum0);
|
||||
ip1->checksum = ip_csum_fold (sum1);
|
||||
|
||||
ASSERT (ip0->checksum == ip4_header_checksum (ip0));
|
||||
ASSERT (ip1->checksum == ip4_header_checksum (ip1));
|
||||
|
||||
p0->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
|
||||
p1->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
|
||||
}
|
||||
|
||||
while (n_left_from > 0 && n_left_to_next > 0)
|
||||
{
|
||||
vlib_buffer_t *p0;
|
||||
ip4_header_t *ip0;
|
||||
icmp46_header_t *icmp0;
|
||||
u32 bi0, src0, dst0;
|
||||
ip_csum_t sum0;
|
||||
|
||||
bi0 = to_next[0] = from[0];
|
||||
|
||||
from += 1;
|
||||
n_left_from -= 1;
|
||||
to_next += 1;
|
||||
n_left_to_next -= 1;
|
||||
|
||||
p0 = vlib_get_buffer (vm, bi0);
|
||||
ip0 = vlib_buffer_get_current (p0);
|
||||
icmp0 = ip4_next_header (ip0);
|
||||
|
||||
vnet_buffer (p0)->sw_if_index[VLIB_RX] =
|
||||
vnet_main.local_interface_sw_if_index;
|
||||
|
||||
/* Update ICMP checksum. */
|
||||
sum0 = icmp0->checksum;
|
||||
|
||||
ASSERT (icmp0->type == ICMP4_echo_request);
|
||||
sum0 = ip_csum_update (sum0, ICMP4_echo_request, ICMP4_echo_reply,
|
||||
icmp46_header_t, type);
|
||||
icmp0->type = ICMP4_echo_reply;
|
||||
icmp0->checksum = ip_csum_fold (sum0);
|
||||
|
||||
src0 = ip0->src_address.data_u32;
|
||||
dst0 = ip0->dst_address.data_u32;
|
||||
ip0->src_address.data_u32 = dst0;
|
||||
ip0->dst_address.data_u32 = src0;
|
||||
|
||||
/* Update IP checksum. */
|
||||
sum0 = ip0->checksum;
|
||||
|
||||
sum0 = ip_csum_update (sum0, ip0->ttl, host_config_ttl,
|
||||
ip4_header_t, ttl);
|
||||
ip0->ttl = host_config_ttl;
|
||||
|
||||
sum0 = ip_csum_update (sum0, ip0->fragment_id, fid[0],
|
||||
ip4_header_t, fragment_id);
|
||||
ip0->fragment_id = fid[0];
|
||||
fid += 1;
|
||||
|
||||
ip0->checksum = ip_csum_fold (sum0);
|
||||
|
||||
ASSERT (ip0->checksum == ip4_header_checksum (ip0));
|
||||
|
||||
p0->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
|
||||
}
|
||||
|
||||
vlib_put_next_frame (vm, node, next, n_left_to_next);
|
||||
}
|
||||
|
||||
vlib_error_count (vm, ip4_icmp_input_node.index,
|
||||
ICMP4_ERROR_ECHO_REPLIES_SENT, frame->n_vectors);
|
||||
|
||||
return frame->n_vectors;
|
||||
}
|
||||
|
||||
static u8 *
|
||||
format_icmp_input_trace (u8 * s, va_list * va)
|
||||
{
|
||||
CLIB_UNUSED (vlib_main_t * vm) = va_arg (*va, vlib_main_t *);
|
||||
CLIB_UNUSED (vlib_node_t * node) = va_arg (*va, vlib_node_t *);
|
||||
icmp_input_trace_t *t = va_arg (*va, icmp_input_trace_t *);
|
||||
|
||||
s = format (s, "%U",
|
||||
format_ip4_header, t->packet_data, sizeof (t->packet_data));
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
VLIB_REGISTER_NODE (ip4_icmp_echo_request_node,static) = {
|
||||
.function = ip4_icmp_echo_request,
|
||||
.name = "ip4-icmp-echo-request",
|
||||
|
||||
.vector_size = sizeof (u32),
|
||||
|
||||
.format_trace = format_icmp_input_trace,
|
||||
|
||||
.n_next_nodes = 1,
|
||||
.next_nodes = {
|
||||
[0] = "ip4-load-balance",
|
||||
},
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
/*
|
||||
* A swarm of address-family agnostic helper functions
|
||||
@ -1252,6 +1460,10 @@ ping_cli_init (vlib_main_t * vm)
|
||||
ip4_icmp_echo_reply_node.index);
|
||||
if (tm->n_vlib_mains > 1)
|
||||
clib_spinlock_init (&pm->ping_run_check_lock);
|
||||
|
||||
ip4_icmp_register_type (vm, ICMP4_echo_request,
|
||||
ip4_icmp_echo_request_node.index);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -200,7 +200,7 @@ ip4_icmp_input (vlib_main_t * vm,
|
||||
}
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
VLIB_REGISTER_NODE (ip4_icmp_input_node,static) = {
|
||||
VLIB_REGISTER_NODE (ip4_icmp_input_node) = {
|
||||
.function = ip4_icmp_input,
|
||||
.name = "ip4-icmp-input",
|
||||
|
||||
@ -218,202 +218,6 @@ VLIB_REGISTER_NODE (ip4_icmp_input_node,static) = {
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
static uword
|
||||
ip4_icmp_echo_request (vlib_main_t * vm,
|
||||
vlib_node_runtime_t * node, vlib_frame_t * frame)
|
||||
{
|
||||
uword n_packets = frame->n_vectors;
|
||||
u32 *from, *to_next;
|
||||
u32 n_left_from, n_left_to_next, next;
|
||||
ip4_main_t *i4m = &ip4_main;
|
||||
u16 *fragment_ids, *fid;
|
||||
u8 host_config_ttl = i4m->host_config.ttl;
|
||||
|
||||
from = vlib_frame_vector_args (frame);
|
||||
n_left_from = n_packets;
|
||||
next = node->cached_next_index;
|
||||
|
||||
if (node->flags & VLIB_NODE_FLAG_TRACE)
|
||||
vlib_trace_frame_buffers_only (vm, node, from, frame->n_vectors,
|
||||
/* stride */ 1,
|
||||
sizeof (icmp_input_trace_t));
|
||||
|
||||
/* Get random fragment IDs for replies. */
|
||||
fid = fragment_ids = clib_random_buffer_get_data (&vm->random_buffer,
|
||||
n_packets *
|
||||
sizeof (fragment_ids[0]));
|
||||
|
||||
while (n_left_from > 0)
|
||||
{
|
||||
vlib_get_next_frame (vm, node, next, to_next, n_left_to_next);
|
||||
|
||||
while (n_left_from > 2 && n_left_to_next > 2)
|
||||
{
|
||||
vlib_buffer_t *p0, *p1;
|
||||
ip4_header_t *ip0, *ip1;
|
||||
icmp46_header_t *icmp0, *icmp1;
|
||||
u32 bi0, src0, dst0;
|
||||
u32 bi1, src1, dst1;
|
||||
ip_csum_t sum0, sum1;
|
||||
|
||||
bi0 = to_next[0] = from[0];
|
||||
bi1 = to_next[1] = from[1];
|
||||
|
||||
from += 2;
|
||||
n_left_from -= 2;
|
||||
to_next += 2;
|
||||
n_left_to_next -= 2;
|
||||
|
||||
p0 = vlib_get_buffer (vm, bi0);
|
||||
p1 = vlib_get_buffer (vm, bi1);
|
||||
ip0 = vlib_buffer_get_current (p0);
|
||||
ip1 = vlib_buffer_get_current (p1);
|
||||
icmp0 = ip4_next_header (ip0);
|
||||
icmp1 = ip4_next_header (ip1);
|
||||
|
||||
vnet_buffer (p0)->sw_if_index[VLIB_RX] =
|
||||
vnet_main.local_interface_sw_if_index;
|
||||
vnet_buffer (p1)->sw_if_index[VLIB_RX] =
|
||||
vnet_main.local_interface_sw_if_index;
|
||||
|
||||
/* Update ICMP checksum. */
|
||||
sum0 = icmp0->checksum;
|
||||
sum1 = icmp1->checksum;
|
||||
|
||||
ASSERT (icmp0->type == ICMP4_echo_request);
|
||||
ASSERT (icmp1->type == ICMP4_echo_request);
|
||||
sum0 = ip_csum_update (sum0, ICMP4_echo_request, ICMP4_echo_reply,
|
||||
icmp46_header_t, type);
|
||||
sum1 = ip_csum_update (sum1, ICMP4_echo_request, ICMP4_echo_reply,
|
||||
icmp46_header_t, type);
|
||||
icmp0->type = ICMP4_echo_reply;
|
||||
icmp1->type = ICMP4_echo_reply;
|
||||
|
||||
icmp0->checksum = ip_csum_fold (sum0);
|
||||
icmp1->checksum = ip_csum_fold (sum1);
|
||||
|
||||
src0 = ip0->src_address.data_u32;
|
||||
src1 = ip1->src_address.data_u32;
|
||||
dst0 = ip0->dst_address.data_u32;
|
||||
dst1 = ip1->dst_address.data_u32;
|
||||
|
||||
/* Swap source and destination address.
|
||||
Does not change checksum. */
|
||||
ip0->src_address.data_u32 = dst0;
|
||||
ip1->src_address.data_u32 = dst1;
|
||||
ip0->dst_address.data_u32 = src0;
|
||||
ip1->dst_address.data_u32 = src1;
|
||||
|
||||
/* Update IP checksum. */
|
||||
sum0 = ip0->checksum;
|
||||
sum1 = ip1->checksum;
|
||||
|
||||
sum0 = ip_csum_update (sum0, ip0->ttl, host_config_ttl,
|
||||
ip4_header_t, ttl);
|
||||
sum1 = ip_csum_update (sum1, ip1->ttl, host_config_ttl,
|
||||
ip4_header_t, ttl);
|
||||
ip0->ttl = host_config_ttl;
|
||||
ip1->ttl = host_config_ttl;
|
||||
|
||||
/* New fragment id. */
|
||||
sum0 = ip_csum_update (sum0, ip0->fragment_id, fid[0],
|
||||
ip4_header_t, fragment_id);
|
||||
sum1 = ip_csum_update (sum1, ip1->fragment_id, fid[1],
|
||||
ip4_header_t, fragment_id);
|
||||
ip0->fragment_id = fid[0];
|
||||
ip1->fragment_id = fid[1];
|
||||
fid += 2;
|
||||
|
||||
ip0->checksum = ip_csum_fold (sum0);
|
||||
ip1->checksum = ip_csum_fold (sum1);
|
||||
|
||||
ASSERT (ip0->checksum == ip4_header_checksum (ip0));
|
||||
ASSERT (ip1->checksum == ip4_header_checksum (ip1));
|
||||
|
||||
p0->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
|
||||
p1->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
|
||||
}
|
||||
|
||||
while (n_left_from > 0 && n_left_to_next > 0)
|
||||
{
|
||||
vlib_buffer_t *p0;
|
||||
ip4_header_t *ip0;
|
||||
icmp46_header_t *icmp0;
|
||||
u32 bi0, src0, dst0;
|
||||
ip_csum_t sum0;
|
||||
|
||||
bi0 = to_next[0] = from[0];
|
||||
|
||||
from += 1;
|
||||
n_left_from -= 1;
|
||||
to_next += 1;
|
||||
n_left_to_next -= 1;
|
||||
|
||||
p0 = vlib_get_buffer (vm, bi0);
|
||||
ip0 = vlib_buffer_get_current (p0);
|
||||
icmp0 = ip4_next_header (ip0);
|
||||
|
||||
vnet_buffer (p0)->sw_if_index[VLIB_RX] =
|
||||
vnet_main.local_interface_sw_if_index;
|
||||
|
||||
/* Update ICMP checksum. */
|
||||
sum0 = icmp0->checksum;
|
||||
|
||||
ASSERT (icmp0->type == ICMP4_echo_request);
|
||||
sum0 = ip_csum_update (sum0, ICMP4_echo_request, ICMP4_echo_reply,
|
||||
icmp46_header_t, type);
|
||||
icmp0->type = ICMP4_echo_reply;
|
||||
icmp0->checksum = ip_csum_fold (sum0);
|
||||
|
||||
src0 = ip0->src_address.data_u32;
|
||||
dst0 = ip0->dst_address.data_u32;
|
||||
ip0->src_address.data_u32 = dst0;
|
||||
ip0->dst_address.data_u32 = src0;
|
||||
|
||||
/* Update IP checksum. */
|
||||
sum0 = ip0->checksum;
|
||||
|
||||
sum0 = ip_csum_update (sum0, ip0->ttl, host_config_ttl,
|
||||
ip4_header_t, ttl);
|
||||
ip0->ttl = host_config_ttl;
|
||||
|
||||
sum0 = ip_csum_update (sum0, ip0->fragment_id, fid[0],
|
||||
ip4_header_t, fragment_id);
|
||||
ip0->fragment_id = fid[0];
|
||||
fid += 1;
|
||||
|
||||
ip0->checksum = ip_csum_fold (sum0);
|
||||
|
||||
ASSERT (ip0->checksum == ip4_header_checksum (ip0));
|
||||
|
||||
p0->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
|
||||
}
|
||||
|
||||
vlib_put_next_frame (vm, node, next, n_left_to_next);
|
||||
}
|
||||
|
||||
vlib_error_count (vm, ip4_icmp_input_node.index,
|
||||
ICMP4_ERROR_ECHO_REPLIES_SENT, frame->n_vectors);
|
||||
|
||||
return frame->n_vectors;
|
||||
}
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
VLIB_REGISTER_NODE (ip4_icmp_echo_request_node,static) = {
|
||||
.function = ip4_icmp_echo_request,
|
||||
.name = "ip4-icmp-echo-request",
|
||||
|
||||
.vector_size = sizeof (u32),
|
||||
|
||||
.format_trace = format_icmp_input_trace,
|
||||
|
||||
.n_next_nodes = 1,
|
||||
.next_nodes = {
|
||||
[0] = "ip4-load-balance",
|
||||
},
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
typedef enum
|
||||
{
|
||||
IP4_ICMP_ERROR_NEXT_DROP,
|
||||
@ -772,9 +576,6 @@ icmp4_init (vlib_main_t * vm)
|
||||
ICMP_INPUT_NEXT_ERROR,
|
||||
sizeof (cm->ip4_input_next_index_by_type));
|
||||
|
||||
ip4_icmp_register_type (vm, ICMP4_echo_request,
|
||||
ip4_icmp_echo_request_node.index);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -55,6 +55,8 @@ icmp4_error_set_vnet_buffer (vlib_buffer_t * b, u8 type, u8 code, u32 data)
|
||||
vnet_buffer (b)->ip.icmp.data = data;
|
||||
}
|
||||
|
||||
extern vlib_node_registration_t ip4_icmp_input_node;
|
||||
|
||||
#endif /* included_vnet_icmp4_h */
|
||||
|
||||
/*
|
||||
|
Reference in New Issue
Block a user