37 #include <sys/socket.h> 43 #define foreach_punt_next \ 44 _ (PUNT4, "ip4-punt") \ 49 #define _(s,n) PUNT_NEXT_##s, 63 #define punt_next_punt(is_ip4) (is_ip4 ? PUNT_NEXT_PUNT4 : PUNT_NEXT_PUNT6) 95 u32 n_left_from, *from, *to_next;
107 while (n_left_from > 0)
114 while (n_left_from > 0 && n_left_to_next > 0)
138 #define punt_error(n,s) s, 202 .name =
"ip4-udp-punt",
204 .vector_size =
sizeof (
u32),
211 #define _(s,n) [PUNT_NEXT_##s] = n, 221 .name =
"ip6-udp-punt",
223 .vector_size =
sizeof (
u32),
230 #define _(s,n) [PUNT_NEXT_##s] = n, 254 static struct sockaddr_un *
266 char *client_pathname)
273 memset (&c, 0,
sizeof (c));
274 memcpy (c.
caddr.sun_path, client_pathname, sizeof (c.
caddr.sun_path));
275 c.
caddr.sun_family = AF_UNIX;
317 struct iovec *iovecs = 0;
324 for (i = 0; i < n_packets; i++)
356 struct sockaddr_un *caddr;
361 PUNT_ERROR_SOCKET_TX_ERROR, 1);
376 _vec_len (iovecs) = 0;
382 iov->iov_base = &packetdesc;
383 iov->iov_len =
sizeof (packetdesc);
414 while (b->
flags & VLIB_BUFFER_NEXT_PRESENT);
417 struct msghdr msg = {
419 .msg_namelen =
sizeof (*caddr),
421 .msg_iovlen =
vec_len (iovecs),
424 if (sendmsg (pm->
socket_fd, &msg, 0) < (ssize_t) l)
426 PUNT_ERROR_SOCKET_TX_ERROR, 1);
453 .name =
"ip4-udp-punt-socket",
457 .vector_size =
sizeof (
u32),
463 .name =
"ip6-udp-punt-socket",
466 .vector_size =
sizeof (
u32),
496 u32 n_left_to_next, next_index;
498 u32 error = PUNT_ERROR_NONE;
511 error = PUNT_ERROR_NOBUFFER;
516 io[0].iov_base = &packetdesc;
517 io[0].iov_len =
sizeof (packetdesc);
518 io[1].iov_base = b->
data;
519 io[1].iov_len = buffer_size;
521 size = readv (fd, io, 2);
523 if (size <= (
int) (
sizeof (packetdesc) +
sizeof (
ip4_header_t)))
526 error = PUNT_ERROR_READV;
530 b->
flags = VNET_BUFFER_F_LOCALLY_ORIGINATED;
535 switch (packetdesc.
action)
555 error = PUNT_ERROR_ACTION;
627 bool is_ip4,
u8 protocol,
u16 port,
628 char *client_pathname)
639 if (protocol != IP_PROTOCOL_UDP)
641 "only UDP protocol (%d) is supported, got %d",
642 IP_PROTOCOL_UDP, protocol);
644 if (port == (
u16) ~ 0)
694 if (protocol != IP_PROTOCOL_UDP &&
697 "only UDP (%d), TCP (%d) and SCTP (%d) protocols are supported, got %d",
698 IP_PROTOCOL_UDP, IP_PROTOCOL_TCP,
701 if (ipv != (
u8) ~ 0 && ipv != 4 && ipv != 6)
704 if (port == (
u16) ~ 0)
706 if ((ipv == 4) || (ipv == (
u8) ~ 0))
708 if (protocol == IP_PROTOCOL_UDP)
710 else if (protocol == IP_PROTOCOL_TCP)
716 if ((ipv == 6) || (ipv == (
u8) ~ 0))
718 if (protocol == IP_PROTOCOL_UDP)
720 else if (protocol == IP_PROTOCOL_TCP)
733 "punt TCP/SCTP ports is not supported yet");
735 if (ipv == 4 || ipv == (
u8) ~ 0)
738 if (ipv == 6 || ipv == (
u8) ~ 0)
770 else if (
unformat (input,
"%d", &port))
781 protocol = IP_PROTOCOL_UDP;
783 protocol = IP_PROTOCOL_TCP;
818 .short_help =
"set punt [udp|tcp] [del] <all | port-num1 [port-num2 ...]>",
848 char *socket_path = 0;
852 if (
unformat (input,
"socket %s", &socket_path))
853 strncpy (pm->
sun_path, socket_path, 108 - 1);
859 if (socket_path == 0)
863 struct sockaddr_un addr;
864 if ((pm->
socket_fd = socket (AF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK, 0)) == -1)
869 memset (&addr, 0,
sizeof (addr));
870 addr.sun_family = AF_UNIX;
871 if (*socket_path ==
'\0')
873 *addr.sun_path =
'\0';
874 strncpy (addr.sun_path + 1, socket_path + 1,
875 sizeof (addr.sun_path) - 2);
879 strncpy (addr.sun_path, socket_path, sizeof (addr.sun_path) - 1);
880 unlink (socket_path);
883 if (bind (pm->
socket_fd, (
struct sockaddr *) &addr, sizeof (addr)) == -1)
892 template.file_descriptor = pm->
socket_fd;
893 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 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)
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)
memset(h->entries, 0, sizeof(h->entries[0])*entries)
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)
#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.
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 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.
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)
#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.
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