37 #include <sys/socket.h> 41 #define foreach_punt_next \ 42 _ (PUNT4, "ip4-punt") \ 47 #define _(s,n) PUNT_NEXT_##s, 61 #define punt_next_punt(is_ip4) (is_ip4 ? PUNT_NEXT_PUNT4 : PUNT_NEXT_PUNT6) 93 u32 n_left_from, *from, *to_next;
105 while (n_left_from > 0)
112 while (n_left_from > 0 && n_left_to_next > 0)
136 #define punt_error(n,s) s, 200 .name =
"ip4-udp-punt",
202 .vector_size =
sizeof (
u32),
209 #define _(s,n) [PUNT_NEXT_##s] = n, 219 .name =
"ip6-udp-punt",
221 .vector_size =
sizeof (
u32),
228 #define _(s,n) [PUNT_NEXT_##s] = n, 252 static struct sockaddr_un *
264 char *client_pathname)
276 memcpy (c.
caddr.sun_path, client_pathname, sizeof (c.
caddr.sun_path));
277 c.
caddr.sun_family = AF_UNIX;
329 for (i = 0; i < n_packets; i++)
361 struct sockaddr_un *caddr;
366 PUNT_ERROR_SOCKET_TX_ERROR, 1);
386 iov->iov_base = &packetdesc;
387 iov->iov_len =
sizeof (packetdesc);
418 while (b->
flags & VLIB_BUFFER_NEXT_PRESENT);
421 struct msghdr msg = {
423 .msg_namelen =
sizeof (*caddr),
428 if (sendmsg (pm->
socket_fd, &msg, 0) < (ssize_t) l)
430 PUNT_ERROR_SOCKET_TX_ERROR, 1);
460 .name =
"ip4-udp-punt-socket",
464 .vector_size =
sizeof (
u32),
470 .name =
"ip6-udp-punt-socket",
473 .vector_size =
sizeof (
u32),
503 u32 n_left_to_next, next_index;
505 u32 error = PUNT_ERROR_NONE;
518 error = PUNT_ERROR_NOBUFFER;
523 io[0].iov_base = &packetdesc;
524 io[0].iov_len =
sizeof (packetdesc);
525 io[1].iov_base = b->
data;
526 io[1].iov_len = buffer_size;
528 size = readv (fd, io, 2);
530 if (size <= (
int) (
sizeof (packetdesc) +
sizeof (
ip4_header_t)))
533 error = PUNT_ERROR_READV;
537 b->
flags = VNET_BUFFER_F_LOCALLY_ORIGINATED;
542 switch (packetdesc.
action)
562 error = PUNT_ERROR_ACTION;
611 .name =
"punt-socket-rx",
613 .state = VLIB_NODE_STATE_INTERRUPT,
642 bool is_ip4,
u8 protocol,
u16 port,
643 char *client_pathname)
654 if (protocol != IP_PROTOCOL_UDP)
656 "only UDP protocol (%d) is supported, got %d",
657 IP_PROTOCOL_UDP, protocol);
659 if (port == (
u16) ~ 0)
665 "Punt socket: Invalid client path: %s",
712 if (protocol != IP_PROTOCOL_UDP &&
715 "only UDP (%d), TCP (%d) and SCTP (%d) protocols are supported, got %d",
716 IP_PROTOCOL_UDP, IP_PROTOCOL_TCP,
719 if (ipv != (
u8) ~ 0 && ipv != 4 && ipv != 6)
722 if (port == (
u16) ~ 0)
724 if ((ipv == 4) || (ipv == (
u8) ~ 0))
726 if (protocol == IP_PROTOCOL_UDP)
728 else if (protocol == IP_PROTOCOL_TCP)
734 if ((ipv == 6) || (ipv == (
u8) ~ 0))
736 if (protocol == IP_PROTOCOL_UDP)
738 else if (protocol == IP_PROTOCOL_TCP)
751 "punt TCP/SCTP ports is not supported yet");
753 if (ipv == 4 || ipv == (
u8) ~ 0)
756 if (ipv == 6 || ipv == (
u8) ~ 0)
765 "punt TCP/SCTP ports is not supported yet");
766 if (ipv == 4 || ipv == (
u8) ~ 0)
769 if (ipv == 6 || ipv == (
u8) ~ 0)
791 else if (
unformat (input,
"%d", &port))
794 protocol = IP_PROTOCOL_UDP;
796 protocol = IP_PROTOCOL_TCP;
840 .short_help =
"set punt [udp|tcp] [del] <all | port-num1 [port-num2 ...]>",
862 protocol = IP_PROTOCOL_UDP;
864 protocol = IP_PROTOCOL_TCP;
865 else if (
unformat (input,
"%d", &port))
867 else if (
unformat (input,
"socket %s", &socket_name))
879 (
char *) socket_name);
896 .path =
"punt socket register",
898 .short_help =
"punt socket register [ipv4|ipv6] [udp|tcp]> <all | port-num1 [port-num2 ...]> <socket>",
920 protocol = IP_PROTOCOL_UDP;
922 protocol = IP_PROTOCOL_TCP;
923 else if (
unformat (input,
"%d", &port))
950 .path =
"punt socket deregister",
952 .short_help =
"punt socket deregister [ipv4|ipv6] [udp|tcp]> <all | port-num1 [port-num2 ...]>",
970 if (pc && pc->
port != 0)
973 if (pc->
protocol == IP_PROTOCOL_UDP)
985 sizeof (pc->
caddr.sun_path));
997 u8 *is_ipv6 = va_arg (*args,
u8 *);
1003 if (pc && pc->
port != 0)
1006 if (pc->
protocol == IP_PROTOCOL_UDP)
1012 s =
format (s,
" punt %s port %d to socket %s \n",
1013 (pc->
protocol == IP_PROTOCOL_UDP) ?
"UDP" :
"TCP",
1060 .path =
"show punt socket registrations",
1062 .short_help =
"show punt socket registrations [ipv4|ipv6]",
1083 "interface-output");
1096 char *socket_path = 0;
1100 if (
unformat (input,
"socket %s", &socket_path))
1101 strncpy (pm->
sun_path, socket_path, UNIX_PATH_MAX - 1);
1107 if (socket_path == 0)
1111 struct sockaddr_un addr;
1112 if ((pm->
socket_fd = socket (AF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK, 0)) == -1)
1118 addr.sun_family = AF_UNIX;
1119 if (*socket_path ==
'\0')
1121 *addr.sun_path =
'\0';
1122 strncpy (addr.sun_path + 1, socket_path + 1,
1123 sizeof (addr.sun_path) - 2);
1127 strncpy (addr.sun_path, socket_path, sizeof (addr.sun_path) - 1);
1128 unlink (socket_path);
1131 if (bind (pm->
socket_fd, (
struct sockaddr *) &addr, sizeof (addr)) == -1)
1140 template.file_descriptor = pm->
socket_fd;
1141 template.description =
format (0,
"%s", socket_path);
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)
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 clib_memcpy_fast(a, b, c)
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
#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)
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
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
static clib_error_t * punt_socket_register_cmd(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
enum punt_action_e action
punt_thread_data_t * thread_data
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
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)
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
#define VLIB_INIT_FUNCTION(x)
#define sparse_vec_validate(v, i)
vlib_node_registration_t udp4_punt_node
(constructor) VLIB_REGISTER_NODE (udp4_punt_node)
static clib_error_t * punt_socket_show_cmd(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
#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
#define punt_next_punt(is_ip4)
void sctp_punt_unknown(vlib_main_t *vm, u8 is_ip4, u8 is_add)
u16 current_length
Nbytes between current data and the end of this buffer.
punt_socket_detail_t * punt_socket_entries(u8 ipv)
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)
#define VLIB_REGISTER_NODE(x,...)
clib_error_t * vnet_punt_socket_add(vlib_main_t *vm, u32 header_version, bool is_ip4, u8 protocol, u16 port, char *client_pathname)
static punt_client_t * punt_client_get(bool is_ip4, u16 port)
void udp_unregister_dst_port(vlib_main_t *vm, udp_dst_port_t dst_port, u8 is_ip4)
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 int punt_socket_register(bool is_ip4, u8 protocol, u16 port, char *client_pathname)
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)
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 clib_error_t * punt_socket_deregister_cmd(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
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.
struct _vlib_node_registration vlib_node_registration_t
void tcp_punt_unknown(vlib_main_t *vm, u8 is_ip4, u8 is_add)
#define foreach_punt_next
u8 * format_udp_punt_trace(u8 *s, va_list *args)
bool udp_is_valid_dst_port(udp_dst_port_t dst_port, u8 is_ip4)
#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)
#define VLIB_NODE_FLAG_IS_DROP
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.
u8 * format_punt_socket(u8 *s, va_list *args)
static vlib_thread_main_t * vlib_get_thread_main()
#define vec_foreach(var, vec)
Vector iterator.
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)
#define CLIB_CACHE_LINE_BYTES
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.
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
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