36 #include <sys/socket.h> 42 #define foreach_punt_next \ 43 _ (PUNT4, "ip4-punt") \ 48 #define _(s,n) PUNT_NEXT_##s, 62 #define punt_next_punt(is_ip4) (is_ip4 ? PUNT_NEXT_PUNT4 : PUNT_NEXT_PUNT6) 94 u32 n_left_from, *from, *to_next;
106 while (n_left_from > 0)
113 while (n_left_from > 0 && n_left_to_next > 0)
137 #define punt_error(n,s) s, 201 .name =
"ip4-udp-punt",
203 .vector_size =
sizeof (
u32),
210 #define _(s,n) [PUNT_NEXT_##s] = n, 220 .name =
"ip6-udp-punt",
222 .vector_size =
sizeof (
u32),
229 #define _(s,n) [PUNT_NEXT_##s] = n, 253 static struct sockaddr_un *
265 char *client_pathname)
272 memset (&c, 0,
sizeof (c));
273 memcpy (c.
caddr.sun_path, client_pathname, sizeof (c.
caddr.sun_path));
274 c.
caddr.sun_family = AF_UNIX;
316 struct iovec *iovecs = 0;
323 for (i = 0; i < n_packets; i++)
355 struct sockaddr_un *caddr;
360 PUNT_ERROR_SOCKET_TX_ERROR, 1);
375 _vec_len (iovecs) = 0;
381 iov->iov_base = &packetdesc;
382 iov->iov_len =
sizeof (packetdesc);
416 struct msghdr msg = {
418 .msg_namelen =
sizeof (*caddr),
420 .msg_iovlen =
vec_len (iovecs),
423 if (sendmsg (pm->
socket_fd, &msg, 0) < (ssize_t) l)
425 PUNT_ERROR_SOCKET_TX_ERROR, 1);
452 .name =
"ip4-udp-punt-socket",
456 .vector_size =
sizeof (
u32),
462 .name =
"ip6-udp-punt-socket",
465 .vector_size =
sizeof (
u32),
495 u32 n_left_to_next, next_index;
497 u32 error = PUNT_ERROR_NONE;
510 error = PUNT_ERROR_NOBUFFER;
515 io[0].iov_base = &packetdesc;
516 io[0].iov_len =
sizeof (packetdesc);
517 io[1].iov_base = b->
data;
518 io[1].iov_len = buffer_size;
520 size = readv (fd, io, 2);
522 if (size <= (
int) (
sizeof (packetdesc) +
sizeof (
ip4_header_t)))
525 error = PUNT_ERROR_READV;
529 b->
flags = VNET_BUFFER_F_LOCALLY_ORIGINATED;
534 switch (packetdesc.
action)
554 error = PUNT_ERROR_ACTION;
626 bool is_ip4,
u8 protocol,
u16 port,
627 char *client_pathname)
638 if (protocol != IP_PROTOCOL_UDP)
640 "only UDP protocol (%d) is supported, got %d",
641 IP_PROTOCOL_UDP, protocol);
643 if (port == (
u16) ~ 0)
693 if (protocol != IP_PROTOCOL_UDP && protocol != IP_PROTOCOL_TCP)
695 "only UDP (%d) and TCP (%d) protocols are supported, got %d",
696 IP_PROTOCOL_UDP, IP_PROTOCOL_TCP, protocol);
698 if (ipv != (
u8) ~ 0 && ipv != 4 && ipv != 6)
701 if (port == (
u16) ~ 0)
703 if ((ipv == 4) || (ipv == (
u8) ~ 0))
705 if (protocol == IP_PROTOCOL_UDP)
707 else if (protocol == IP_PROTOCOL_TCP)
711 if ((ipv == 6) || (ipv == (
u8) ~ 0))
713 if (protocol == IP_PROTOCOL_UDP)
715 else if (protocol == IP_PROTOCOL_TCP)
724 if (protocol == IP_PROTOCOL_TCP)
727 if (ipv == 4 || ipv == (
u8) ~ 0)
730 if (ipv == 6 || ipv == (
u8) ~ 0)
762 else if (
unformat (input,
"%d", &port))
773 protocol = IP_PROTOCOL_UDP;
775 protocol = IP_PROTOCOL_TCP;
810 .short_help =
"set punt [udp|tcp] [del] <all | port-num1 [port-num2 ...]>",
840 char *socket_path = 0;
844 if (
unformat (input,
"socket %s", &socket_path))
845 strncpy (pm->
sun_path, socket_path, 108 - 1);
851 if (socket_path == 0)
855 struct sockaddr_un addr;
856 if ((pm->
socket_fd = socket (AF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK, 0)) == -1)
861 memset (&addr, 0,
sizeof (addr));
862 addr.sun_family = AF_UNIX;
863 if (*socket_path ==
'\0')
865 *addr.sun_path =
'\0';
866 strncpy (addr.sun_path + 1, socket_path + 1,
867 sizeof (addr.sun_path) - 2);
871 strncpy (addr.sun_path, socket_path, sizeof (addr.sun_path) - 1);
872 unlink (socket_path);
875 if (bind (pm->
socket_fd, (
struct sockaddr *) &addr, sizeof (addr)) == -1)
884 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
#define punt_next_punt(is_ip4)
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)
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)
#define VLIB_BUFFER_IS_TRACED
static void punt_socket_register(bool is_ip4, u8 protocol, u16 port, char *client_pathname)
#define clib_memcpy(a, b, c)
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
u8 * format_udp_punt_trace(u8 *s, va_list *args)
#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