36 #include <sys/socket.h> 42 #define foreach_punt_next \ 43 _ (PUNT, "error-punt") 47 #define _(s,n) PUNT_NEXT_##s, 91 u32 n_left_from, *from, *to_next;
103 while (n_left_from > 0)
109 while (n_left_from > 0 && n_left_to_next > 0)
133 #define punt_error(n,s) s, 197 .name =
"ip4-udp-punt",
199 .vector_size =
sizeof (
u32),
206 #define _(s,n) [PUNT_NEXT_##s] = n, 216 .name =
"ip6-udp-punt",
218 .vector_size =
sizeof (
u32),
225 #define _(s,n) [PUNT_NEXT_##s] = n, 235 static struct sockaddr_un *
251 char *client_pathname)
258 memset (&c, 0,
sizeof (c));
259 memcpy (c.
caddr.sun_path, client_pathname, sizeof (c.
caddr.sun_path));
260 c.
caddr.sun_family = AF_UNIX;
280 struct iovec *iovecs = 0;
287 for (i = 0; i < n_packets; i++)
319 struct sockaddr_un *caddr;
324 PUNT_ERROR_SOCKET_TX_ERROR, 1);
330 _vec_len (iovecs) = 0;
336 iov->iov_base = &packetdesc;
337 iov->iov_len =
sizeof (packetdesc);
360 struct msghdr msg = {
362 .msg_namelen =
sizeof (*caddr),
364 .msg_iovlen =
vec_len (iovecs),
367 if (sendmsg (pm->
socket_fd, &msg, 0) < l)
369 PUNT_ERROR_SOCKET_TX_ERROR, 1);
396 .name =
"ip4-udp-punt-socket",
399 .vector_size =
sizeof (
u32),
405 .name =
"ip6-udp-punt-socket",
407 .vector_size =
sizeof (
u32),
437 u32 n_left_to_next, next_index;
439 u32 error = PUNT_ERROR_NONE;
452 error = PUNT_ERROR_NOBUFFER;
457 io[0].iov_base = &packetdesc;
458 io[0].iov_len =
sizeof (packetdesc);
459 io[1].iov_base = b->
data;
460 io[1].iov_len = buffer_size;
462 size = readv (fd, io, 2);
464 if (size <= (
int) (
sizeof (packetdesc) +
sizeof (
ip4_header_t)))
467 error = PUNT_ERROR_READV;
471 b->
flags = VNET_BUFFER_F_LOCALLY_ORIGINATED;
476 switch (packetdesc.
action)
496 error = PUNT_ERROR_ACTION;
568 bool is_ip4,
u8 protocol,
u16 port,
569 char *client_pathname)
580 if (protocol != IP_PROTOCOL_UDP)
582 "only UDP protocol (%d) is supported, got %d",
583 IP_PROTOCOL_UDP, protocol);
585 if (port == (
u16) ~ 0)
635 if (protocol != IP_PROTOCOL_UDP && protocol != IP_PROTOCOL_TCP)
637 "only UDP (%d) and TCP (%d) protocols are supported, got %d",
638 IP_PROTOCOL_UDP, IP_PROTOCOL_TCP, protocol);
640 if (ipv != (
u8) ~ 0 && ipv != 4 && ipv != 6)
643 if (port == (
u16) ~ 0)
645 if ((ipv == 4) || (ipv == (
u8) ~ 0))
647 if (protocol == IP_PROTOCOL_UDP)
649 else if (protocol == IP_PROTOCOL_TCP)
653 if ((ipv == 6) || (ipv == (
u8) ~ 0))
655 if (protocol == IP_PROTOCOL_UDP)
657 else if (protocol == IP_PROTOCOL_TCP)
666 if (protocol == IP_PROTOCOL_TCP)
669 if (ipv == 4 || ipv == (
u8) ~ 0)
672 if (ipv == 6 || ipv == (
u8) ~ 0)
701 else if (
unformat (input,
"%d", &port))
709 protocol = IP_PROTOCOL_UDP;
711 protocol = IP_PROTOCOL_TCP;
740 .short_help =
"set punt [udp|tcp] [del] <all | port-num1 [port-num2 ...]>",
770 char *socket_path = 0;
774 if (
unformat (input,
"socket %s", &socket_path))
775 strncpy (pm->
sun_path, socket_path, 108 - 1);
781 if (socket_path == 0)
785 struct sockaddr_un addr;
786 if ((pm->
socket_fd = socket (AF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK, 0)) == -1)
791 memset (&addr, 0,
sizeof (addr));
792 addr.sun_family = AF_UNIX;
793 if (*socket_path ==
'\0')
795 *addr.sun_path =
'\0';
796 strncpy (addr.sun_path + 1, socket_path + 1,
797 sizeof (addr.sun_path) - 2);
801 strncpy (addr.sun_path, socket_path, sizeof (addr.sun_path) - 1);
802 unlink (socket_path);
805 if (bind (pm->
socket_fd, (
struct sockaddr *) &addr, sizeof (addr)) == -1)
814 template.file_descriptor = pm->
socket_fd;
static uword punt_socket_rx(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
vlib_node_t * interface_output_node
static clib_error_t * punt_socket_read_ready(clib_file_t *uf)
static clib_error_t * punt_cli(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
sll srl srl sll sra u16x4 i
static struct sockaddr_un * punt_socket_get(bool is_ip4, u16 port)
static u32 vlib_get_trace_count(vlib_main_t *vm, vlib_node_runtime_t *rt)
static void vlib_buffer_free(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Free buffers Frees the entire buffer chain for each buffer.
vnet_main_t * vnet_get_main(void)
static uword udp6_punt_socket(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
static uword udp4_punt(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
IPv4 UDP punt node.
static void vlib_node_set_interrupt_pending(vlib_main_t *vm, u32 node_index)
static vlib_node_registration_t punt_socket_rx_node
(constructor) VLIB_REGISTER_NODE (punt_socket_rx_node)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
struct _vlib_node_registration vlib_node_registration_t
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
static uword udp46_punt_socket_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, bool is_ip4)
vlib_error_t * errors
Vector of errors for this node.
static uword udp6_punt(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
IPv6 UDP punt node.
format_function_t format_vnet_sw_if_index_name
enum punt_action_e action
clib_file_function_t * read_function
static void vlib_trace_buffer(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, vlib_buffer_t *b, int follow_chain)
#define VLIB_BUFFER_NEXT_PRESENT
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
#define VLIB_INIT_FUNCTION(x)
#define VLIB_NODE_FLAG_IS_DROP
#define sparse_vec_validate(v, i)
vlib_node_registration_t udp4_punt_node
(constructor) VLIB_REGISTER_NODE (udp4_punt_node)
#define clib_error_return(e, args...)
clib_file_main_t file_main
static u8 * format_punt_trace(u8 *s, va_list *va)
punt_client_t * clients_by_dst_port6
u16 current_length
Nbytes between current data and the end of this buffer.
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
#define VLIB_CONFIG_FUNCTION(x, n,...)
#define vec_del1(v, i)
Delete the element at index I.
vlib_node_registration_t udp6_punt_socket_node
(constructor) VLIB_REGISTER_NODE (udp6_punt_socket_node)
#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).
vlib_error_t error
Error code for buffers to be enqueued to error handler.
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
void udp_punt_unknown(vlib_main_t *vm, u8 is_ip4, u8 is_add)
static void vlib_buffer_free_no_next(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Free buffers, does not free the buffer chain for each buffer.
clib_error_t * vnet_punt_socket_add(vlib_main_t *vm, u32 header_version, bool is_ip4, u8 protocol, u16 port, char *client_pathname)
void udp_unregister_dst_port(vlib_main_t *vm, udp_dst_port_t dst_port, u8 is_ip4)
static void punt_socket_register(bool is_ip4, u8 protocol, u16 port, char *client_pathname)
static uword udp4_punt_socket(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definitions for punt infrastructure.
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Release pointer to next frame vector data.
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
char * vnet_punt_get_server_pathname(void)
#define VLIB_BUFFER_DATA_SIZE
enum punt_action_e action
#define VLIB_CLI_COMMAND(x,...)
static uword sparse_vec_index(void *v, uword sparse_index)
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
static uword clib_file_add(clib_file_main_t *um, clib_file_t *template)
clib_error_t * vnet_punt_socket_del(vlib_main_t *vm, bool is_ip4, u8 l4_protocol, u16 port)
VLIB_NODE_FUNCTION_MULTIARCH(udp4_punt_node, udp4_punt)
char sun_path[sizeof(struct sockaddr_un)]
clib_error_t * punt_init(vlib_main_t *vm)
u32 next_buffer
Next buffer for this linked-list of buffers.
#define clib_error_report(e)
static void * vlib_frame_args(vlib_frame_t *f)
Get pointer to frame scalar data.
punt_client_t * clients_by_dst_port4
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
static uword udp46_punt_inline(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame, int is_ip4)
IPv4/IPv6 UDP punt node main loop.
static char * punt_error_strings[]
static uword punt_socket_rx_fd(vlib_main_t *vm, vlib_node_runtime_t *node, u32 fd)
static vlib_main_t * vlib_get_main(void)
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
vlib_node_registration_t udp4_punt_socket_node
(constructor) VLIB_REGISTER_NODE (udp4_punt_socket_node)
#define vec_elt(v, i)
Get vector value at index i.
void tcp_punt_unknown(vlib_main_t *vm, u8 is_ip4, u8 is_add)
#define foreach_punt_next
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
#define VLIB_BUFFER_TRACE_TRAJECTORY_INIT(b)
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
static void punt_socket_unregister(bool is_ip4, u8 protocol, u16 port)
clib_error_t * vnet_punt_add_del(vlib_main_t *vm, u8 ipv, u8 protocol, u16 port, bool is_add)
Request IP traffic punt to the local TCP/IP stack.
#define VLIB_REGISTER_NODE(x,...)
void udp_register_dst_port(vlib_main_t *vm, udp_dst_port_t dst_port, u32 node_index, u8 is_ip4)
static clib_error_t * punt_config(vlib_main_t *vm, unformat_input_t *input)
static void vlib_set_trace_count(vlib_main_t *vm, vlib_node_runtime_t *rt, u32 count)
static void * sparse_vec_new(uword elt_bytes, uword sparse_index_bits)
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index, VLIB_BUFFER_IS_TRACED: trace this buffer.
static u32 vlib_buffer_alloc(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Allocate buffers into supplied array.
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
vlib_node_registration_t udp6_punt_node
(constructor) VLIB_REGISTER_NODE (udp6_punt_node)
#define PUNT_PACKETDESC_VERSION
#define SPARSE_VEC_INVALID_INDEX