*/
#include <vnet/ip/ip.h>
+#include <vnet/ethernet/ethernet.h>
#include <vlib/vlib.h>
-#include <vnet/pg/pg.h>
-#include <vnet/udp/udp.h>
-#include <vnet/tcp/tcp.h>
#include <vnet/ip/punt.h>
#include <vlib/unix/unix.h>
return udp46_punt_inline (vm, node, from_frame, 0 /* is_ip4 */ );
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (udp4_punt_node) = {
.name = "ip4-udp-punt",
/* Takes a vector of packets. */
#undef _
},
};
-/* *INDENT-ON* */
typedef struct
{
punt_client_t client;
u8 is_midchain;
+ u8 packet_data[64];
} udp_punt_trace_t;
static u8 *
s = format (s, "\n%U(buffer is part of chain)", format_white_space,
indent);
}
+ s = format (s, "\n%U%U", format_white_space, indent,
+ format_hex_bytes, t->packet_data, sizeof (t->packet_data));
+
return s;
}
always_inline uword
-punt_socket_inline (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame,
- punt_type_t pt, ip_address_family_t af)
+punt_socket_inline2 (vlib_main_t *vm, vlib_node_runtime_t *node,
+ vlib_frame_t *frame, punt_type_t pt,
+ ip_address_family_t af, ip_protocol_t protocol)
{
u32 *buffers = vlib_frame_vector_args (frame);
+ u32 thread_index = vm->thread_index;
uword n_packets = frame->n_vectors;
- struct iovec *iovecs = 0;
punt_main_t *pm = &punt_main;
int i;
- u32 node_index = AF_IP4 == af ? udp4_punt_socket_node.index :
- udp6_punt_socket_node.index;
+ punt_thread_data_t *ptd = &pm->thread_data[thread_index];
+ u32 node_index = (AF_IP4 == af ?
+ udp4_punt_socket_node.index :
+ udp6_punt_socket_node.index);
for (i = 0; i < n_packets; i++)
{
uword l;
punt_packetdesc_t packetdesc;
punt_client_t *c;
-
+ u16 port = 0;
b = vlib_get_buffer (vm, buffers[i]);
if (PUNT_TYPE_L4 == pt)
{
- /* Reverse UDP Punt advance */
- udp_header_t *udp;
- if (AF_IP4 == af)
+ if (protocol == IP_PROTOCOL_UDP)
{
- vlib_buffer_advance (b, -(sizeof (ip4_header_t) +
- sizeof (udp_header_t)));
- ip4_header_t *ip = vlib_buffer_get_current (b);
- udp = (udp_header_t *) (ip + 1);
+ /* Reverse UDP Punt advance */
+ udp_header_t *udp;
+ if (AF_IP4 == af)
+ {
+ vlib_buffer_advance (
+ b, -(sizeof (ip4_header_t) + sizeof (udp_header_t)));
+ ip4_header_t *ip = vlib_buffer_get_current (b);
+ udp = (udp_header_t *) (ip + 1);
+ }
+ else
+ {
+ vlib_buffer_advance (
+ b, -(sizeof (ip6_header_t) + sizeof (udp_header_t)));
+ ip6_header_t *ip = vlib_buffer_get_current (b);
+ udp = (udp_header_t *) (ip + 1);
+ }
+ port = clib_net_to_host_u16 (udp->dst_port);
}
- else
+ else if (protocol == IP_PROTOCOL_ICMP6)
{
- vlib_buffer_advance (b, -(sizeof (ip6_header_t) +
- sizeof (udp_header_t)));
ip6_header_t *ip = vlib_buffer_get_current (b);
- udp = (udp_header_t *) (ip + 1);
+ icmp46_header_t *icmp = ip6_next_header (ip);
+ port = icmp->type;
}
-
/*
* Find registerered client
* If no registered client, drop packet and count
*/
- c = punt_client_l4_get (af, clib_net_to_host_u16 (udp->dst_port));
+ c = punt_client_l4_get (af, port);
}
else if (PUNT_TYPE_IP_PROTO == pt)
{
struct sockaddr_un *caddr = &c->caddr;
- if (PREDICT_FALSE (b->flags & VLIB_BUFFER_IS_TRACED))
- {
- udp_punt_trace_t *t;
- t = vlib_add_trace (vm, node, b, sizeof (t[0]));
- clib_memcpy_fast (&t->client, c, sizeof (t->client));
- }
-
- /* Re-set iovecs if present. */
- if (iovecs)
- _vec_len (iovecs) = 0;
+ /* Re-set iovecs */
+ vec_reset_length (ptd->iovecs);
/* Add packet descriptor */
packetdesc.sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_RX];
packetdesc.action = 0;
- vec_add2 (iovecs, iov, 1);
+ vec_add2 (ptd->iovecs, iov, 1);
iov->iov_base = &packetdesc;
iov->iov_len = sizeof (packetdesc);
/** VLIB buffer chain -> Unix iovec(s). */
- vlib_buffer_advance (b, -(sizeof (ethernet_header_t)));
- vec_add2 (iovecs, iov, 1);
+ vlib_buffer_advance (b, -ethernet_buffer_header_size (b));
+ vec_add2 (ptd->iovecs, iov, 1);
iov->iov_base = b->data + b->current_data;
iov->iov_len = l = b->current_length;
+ if (PREDICT_FALSE (b->flags & VLIB_BUFFER_IS_TRACED))
+ {
+ udp_punt_trace_t *t;
+ t = vlib_add_trace (vm, node, b, sizeof (t[0]));
+ clib_memcpy_fast (&t->client, c, sizeof (t->client));
+ clib_memcpy_fast (t->packet_data,
+ vlib_buffer_get_current (b),
+ sizeof (t->packet_data));
+ }
+
if (PREDICT_FALSE (b->flags & VLIB_BUFFER_NEXT_PRESENT))
{
do
t->is_midchain = 1;
}
- vec_add2 (iovecs, iov, 1);
+ vec_add2 (ptd->iovecs, iov, 1);
iov->iov_base = b->data + b->current_data;
iov->iov_len = b->current_length;
struct msghdr msg = {
.msg_name = caddr,
.msg_namelen = sizeof (*caddr),
- .msg_iov = iovecs,
- .msg_iovlen = vec_len (iovecs),
+ .msg_iov = ptd->iovecs,
+ .msg_iovlen = vec_len (ptd->iovecs),
};
if (sendmsg (pm->socket_fd, &msg, 0) < (ssize_t) l)
return n_packets;
}
+always_inline uword
+punt_socket_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
+ vlib_frame_t *frame, punt_type_t pt,
+ ip_address_family_t af)
+{
+ return punt_socket_inline2 (vm, node, frame, pt, af, IP_PROTOCOL_UDP);
+}
+
static uword
udp4_punt_socket (vlib_main_t * vm,
vlib_node_runtime_t * node, vlib_frame_t * from_frame)
PUNT_TYPE_IP_PROTO, AF_IP6);
}
+static uword
+icmp6_punt_socket (vlib_main_t *vm, vlib_node_runtime_t *node,
+ vlib_frame_t *from_frame)
+{
+ return punt_socket_inline2 (vm, node, from_frame, PUNT_TYPE_L4, AF_IP6,
+ IP_PROTOCOL_ICMP6);
+}
+
static uword
exception_punt_socket (vlib_main_t * vm,
vlib_node_runtime_t * node, vlib_frame_t * from_frame)
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (udp4_punt_socket_node) = {
.function = udp4_punt_socket,
.name = "ip4-udp-punt-socket",
.n_errors = PUNT_N_ERROR,
.error_strings = punt_error_strings,
};
-/* *INDENT-ON* */
+VLIB_REGISTER_NODE (icmp6_punt_socket_node) = {
+ .function = icmp6_punt_socket,
+ .name = "ip6-icmp-punt-socket",
+ .format_trace = format_udp_punt_trace,
+ .flags = VLIB_NODE_FLAG_IS_DROP,
+ .vector_size = sizeof (u32),
+ .n_errors = PUNT_N_ERROR,
+ .error_strings = punt_error_strings,
+};
+
typedef struct
{
b->flags = VNET_BUFFER_F_LOCALLY_ORIGINATED;
b->current_length = size - sizeof (packetdesc);
- VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b);
-
switch (packetdesc.action)
{
case PUNT_L2:
goto error;
}
- if (PREDICT_FALSE (n_trace > 0))
+ if (PREDICT_FALSE
+ (n_trace > 0
+ && vlib_trace_buffer (vm, node, next_index, b, 1 /* follow_chain */ )))
{
punt_trace_t *t;
- vlib_trace_buffer (vm, node, next_index, b, 1 /* follow_chain */ );
vlib_set_trace_count (vm, node, --n_trace);
t = vlib_add_trace (vm, node, b, sizeof (*t));
t->sw_if_index = packetdesc.sw_if_index;
vlib_validate_buffer_enqueue_x1 (vm, node, next, to_next, n_left_to_next,
bi, next_index);
vlib_put_next_frame (vm, node, next, n_left_to_next);
+
return 1;
error:
+ vlib_put_next_frame (vm, node, next, n_left_to_next);
vlib_node_increment_counter (vm, punt_socket_rx_node.index, error, 1);
return 0;
}
return total_count;
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (punt_socket_rx_node) =
{
.function = punt_socket_rx,
.name = "punt-socket-rx",
+ .flags = VLIB_NODE_FLAG_TRACE_SUPPORTED,
.type = VLIB_NODE_TYPE_INPUT,
.state = VLIB_NODE_STATE_INTERRUPT,
.vector_size = 1,
},
.format_trace = format_punt_trace,
};
-/* *INDENT-ON* */
/*
* fd.io coding-style-patch-verification: ON