|
FD.io VPP
v21.10.1-2-g0a485f517
Vector Packet Processing
|
Go to the documentation of this file.
21 #include <sys/ioctl.h>
22 #include <netinet/tcp.h>
28 u64 peer_id_as_u64 = va_arg (*args,
u64);
30 peer_id.as_u64 = peer_id_as_u64;
44 u32 buffer_index,
u32 handler_frees_buffer,
void *_h)
51 h (mcm, the_msg, buffer_index);
52 if (!handler_frees_buffer)
58 u32 buffer_index,
struct iovec **iovs_return)
62 u32 bi = buffer_index;
72 if (!(
b->
flags & VLIB_BUFFER_NEXT_PRESENT))
82 int socket,
struct sockaddr_in *tx_addr,
u32 buffer_index)
90 h.msg_namelen =
sizeof (tx_addr[0]);
93 _vec_len (msm->
iovecs) = 0;
96 ASSERT (n_bytes <= msm->mc_main.transport.max_packet_size);
104 while ((n_bytes_tx = sendmsg (socket, &
h, 0)) !=
n_bytes
116 .format =
"sendmsg-helper: %d retries",.format_args =
"i4",};
123 ed->retries = n_retries;
136 if (
type != MC_TRANSPORT_USER_REQUEST_TO_RELAY)
142 tx_ack (
void *transport, mc_peer_id_t dest_peer_id,
u32 buffer_index)
144 struct sockaddr_in tx_addr;
150 tx_addr.sin_family = AF_INET;
162 struct sockaddr_in *rx_addr,
163 u32 * buffer_index,
u32 drop_message)
176 uword max_alloc = 8 * n_mtu;
189 for (
i = 0;
i < n_mtu;
i++)
193 msm->
iovecs[
i].iov_len = buffer_size;
195 _vec_len (msm->
iovecs) = n_mtu;
203 h.msg_name = rx_addr;
204 h.msg_namelen =
sizeof (rx_addr[0]);
209 n_bytes_left = recvmsg (socket, &
h, 0);
210 if (n_bytes_left < 0)
228 n_bytes_left < buffer_size ? n_bytes_left : buffer_size;
230 n_bytes_left -= buffer_size;
232 if (n_bytes_left <= 0)
236 b->
flags |= VLIB_BUFFER_NEXT_PRESENT;
249 mc_main_t *mcm = &msm->
mc_main;
260 mc_msg_master_assert_handler);
269 mc_main_t *mcm = &msm->
mc_main;
277 u32 is_master = mcm->relay_state == MC_RELAY_STATE_MASTER;
284 if (!
error && is_master)
288 mp->global_sequence = clib_host_to_net_u32 (mcm->relay_global_sequence);
289 mcm->relay_global_sequence++;
291 sendmsg_helper (msm, ms_from_relay->socket, &ms_from_relay->tx_addr,
303 mc_main_t *mcm = &msm->
mc_main;
314 mc_msg_user_request_handler);
323 mc_main_t *mcm = &msm->
mc_main;
336 switch (clib_host_to_net_u32 (mp->type))
338 case MC_MSG_TYPE_join_or_leave_request:
340 mc_msg_join_or_leave_request_handler);
343 case MC_MSG_TYPE_join_reply:
345 mc_msg_join_reply_handler);
360 mc_main_t *mcm = &msm->
mc_main;
368 mc_msg_user_ack_handler);
398 mc_main_t *mcm = &msm->
mc_main;
421 _vec_len (
c->input_vector) = l + n;
423 if (is_eof &&
vec_len (
c->input_vector) > 0)
427 mc_msg_catchup_request_handler (mcm, (
void *)
c->input_vector,
429 _vec_len (
c->input_vector) = 0;
433 mc_msg_catchup_reply_handler (mcm, (
void *)
c->input_vector,
452 if (MC_EVENT_LOGGING)
457 ELOG_TYPE (e,
"catchup_client_read_ready");
458 ELOG (&
vm->elog_main, e, 0);
473 if (
c->connect_in_progress)
477 c->connect_in_progress = 0;
479 if (getsockopt (
c->socket, SOL_SOCKET, SO_ERROR, &
value, &
len) < 0)
502 if (n_this_write <= 0)
508 c->output_vector +
c->output_vector_n_written,
511 while (n < 0 && errno == EAGAIN);
518 c->output_vector_n_written += n;
521 if (
c->output_vector_n_written >=
vec_len (
c->output_vector))
567 struct sockaddr_in client_addr;
575 client_len =
sizeof (client_addr);
578 c->socket = accept (uf->file_descriptor,
579 (
struct sockaddr *) &client_addr,
580 (socklen_t *) & client_len);
588 if (MC_EVENT_LOGGING)
590 mc_main_t *mcm = &msm->mc_main;
595 .format =
"catchup accepted from 0x%lx",.format_args =
"i4",};
602 ed->addr = ntohl (client_addr.sin_addr.s_addr);
608 if ((setsockopt (
c->socket, IPPROTO_TCP,
609 TCP_NODELAY, (
void *) &one, sizeof (one))) < 0)
618 template.file_descriptor =
c->socket;
619 template.description =
format (0,
"multicast catchup socket");
622 hash_set (msm->catchup_index_by_file_descriptor,
c->socket,
634 struct sockaddr_in
a;
638 a.sin_family = PF_INET;
639 a.sin_addr.s_addr = INADDR_ANY;
640 a.sin_port = htons (
port);
642 if (bind (sock, (
struct sockaddr *) &
a,
sizeof (
a)) >= 0)
655 struct ip_mreq mcast_req;
661 if ((ms->
socket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
667 if ((setsockopt (ms->
socket, IPPROTO_IP,
668 IP_MULTICAST_TTL, (
void *) &
ttl, sizeof (
ttl))) < 0)
672 if (setsockopt (ms->
socket, SOL_SOCKET, SO_REUSEADDR, &one, sizeof (one)) <
677 ms->
tx_addr.sin_family = AF_INET;
680 ms->
tx_addr.sin_port = htons (udp_port);
687 mcast_req.imr_multiaddr.s_addr =
691 if ((setsockopt (ms->
socket, IPPROTO_IP,
692 IP_ADD_MEMBERSHIP, (
void *) &mcast_req,
693 sizeof (mcast_req))) < 0)
697 if (ioctl (ms->
socket, FIONBIO, &one) < 0)
703 socklen_t sl =
sizeof (
len);
704 if (setsockopt (ms->
socket, SOL_SOCKET, SO_SNDBUF, &
len, sl) < 0)
720 0xffff - ((MC_N_TRANSPORT_TYPE + 2 )
727 [MC_TRANSPORT_MASTERSHIP],
"mastership",
740 [MC_TRANSPORT_USER_REQUEST_TO_RELAY],
747 [MC_TRANSPORT_USER_REQUEST_FROM_RELAY],
748 "from relay",
port++);
753 msm->
ack_socket = socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP);
759 if (ioctl (msm->
ack_socket, FIONBIO, &one) < 0)
780 template.file_descriptor =
782 template.private_data = (
uword) msm;
787 template.file_descriptor =
789 template.private_data = (
uword) msm;
790 template.description =
format (0,
"multicast to_relay socket");
795 template.file_descriptor =
797 template.private_data = (
uword) msm;
798 template.description =
format (0,
"multicast from_relay socket");
802 template.file_descriptor =
804 template.private_data = (
uword) msm;
805 template.description =
format (0,
"multicast join socket");
811 template.private_data = (
uword) msm;
812 template.description =
format (0,
"multicast ack rx socket");
818 template.private_data = (
uword) msm;
819 template.description =
format (0,
"multicast tcp catchup socket");
828 u8 * set_output_vector)
834 if (set_output_vector)
835 c->output_vector = set_output_vector;
850 u32 stream_index, mc_peer_id_t catchup_peer_id)
853 mc_main_t *mcm = &msm->
mc_main;
856 struct sockaddr_in
addr;
863 c->socket = socket (AF_INET, SOCK_STREAM, 0);
870 if (ioctl (
c->socket, FIONBIO, &one) < 0)
877 addr.sin_family = AF_INET;
881 c->connect_in_progress = 1;
883 if (MC_EVENT_LOGGING)
887 .format =
"connecting to peer 0x%Lx",.format_args =
"i8",};
893 ed->peer = catchup_peer_id.as_u64;
896 if (connect (
c->socket, (
const void *) &
addr, sizeof (
addr))
897 < 0 && errno != EINPROGRESS)
910 template.file_descriptor =
c->socket;
911 template.private_data = (
uword) msm;
912 template.description =
format (0,
"multicast socket");
920 mc_msg_catchup_request_t *mp;
923 mp->peer_id = msm->
mc_main.transport.our_catchup_peer_id;
924 mp->stream_index = stream_index;
925 mc_byte_swap_msg_catchup_request (mp);
944 struct sockaddr_in *sa;
947 fd = socket (PF_INET, AF_INET, 0);
954 ifr.ifr_addr.sa_family = AF_INET;
955 strncpy (ifr.ifr_name, if_name, sizeof (ifr.ifr_name) - 1);
956 if (ioctl (fd, SIOCGIFADDR, &ifr) < 0)
963 sa = (
void *) &ifr.ifr_addr;
966 if (ioctl (fd, SIOCGIFMTU, &ifr) < 0)
972 *mtu = ifr.ifr_mtu - ( 20 + 8);
981 int n_intfcs_to_probe)
1005 for (
i = 0;
i < n_intfcs_to_probe;
i++)
1030 mcm->transport.our_ack_peer_id =
1034 mcm->transport.our_catchup_peer_id =
1039 mcm->transport.tx_ack =
tx_ack;
1043 mcm->transport.opaque = msm;
1044 mcm->transport.max_packet_size = mtu;
1046 mc_main_init (mcm,
"socket");
static word find_and_bind_to_free_port(word sock, word port)
u32 next_buffer
Next buffer for this linked-list of buffers.
static clib_error_t * to_relay_socket_read_ready(clib_file_t *uf)
clib_file_main_t file_main
#define hash_set(h, key, value)
char * multicast_interface_name
static clib_error_t * ack_socket_read_ready(clib_file_t *uf)
static clib_error_t * catchup_socket_write_ready(clib_file_t *uf, int is_server)
#define clib_memcpy(d, s, n)
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
static clib_error_t * tx_ack(void *transport, mc_peer_id_t dest_peer_id, u32 buffer_index)
static uword pointer_to_uword(const void *p)
static void catchup_send_fun(void *transport_main, uword opaque, u8 *data)
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
void() mc_msg_handler_t(mc_main_t *mcm, void *msg, u32 buffer_index)
static clib_error_t * catchup_socket_error_ready(clib_file_t *uf)
static clib_error_t * tx_buffer(void *transport, mc_transport_type_t type, u32 buffer_index)
#define clib_error_return(e, args...)
clib_file_function_t * read_function
#define pool_put(P, E)
Free an object E in pool P.
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
#define ELOG_TYPE(f, fmt)
static int find_interface_ip4_address(char *if_name, u32 *ip4_address, u32 *mtu)
static clib_error_t * catchup_client_read_ready(clib_file_t *uf)
static clib_error_t * catchup_server_read_ready(clib_file_t *uf)
static clib_error_t * catchup_server_write_ready(clib_file_t *uf)
#define clib_unix_warning(format, args...)
static clib_error_t * join_socket_read_ready(clib_file_t *uf)
#define hash_unset(h, key)
static clib_error_t * catchup_client_write_ready(clib_file_t *uf)
struct sockaddr_in tx_addr
static uword catchup_request_fun(void *transport_main, u32 stream_index, mc_peer_id_t catchup_peer_id)
int catchup_server_socket
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
#define clib_error_return_code(e, code, flags, args...)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static clib_error_t * setup_mutlicast_socket(mc_socket_main_t *msm, mc_multicast_socket_t *ms, char *type, uword udp_port)
#define ELOG_TYPE_DECLARE(f)
#define UNIX_FILE_DATA_AVAILABLE_TO_WRITE
#define vec_add2(V, P, N)
Add N elements to end of vector V, return pointer to new elements in P.
uword * catchup_index_by_file_descriptor
static __clib_warn_unused_result u32 vlib_buffer_alloc(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Allocate buffers into supplied array.
static mc_socket_catchup_t * find_catchup_from_file_descriptor(mc_socket_main_t *msm, int file_descriptor)
#define clib_unix_error(format, args...)
static_always_inline mc_peer_id_t mc_socket_set_peer_id(u32 address_net_byte_order, u32 port_host_byte_order)
static clib_error_t * catchup_listen_read_ready(clib_file_t *uf)
static uword append_buffer_index_to_iovec(vlib_main_t *vm, u32 buffer_index, struct iovec **iovs_return)
#define ELOG(em, f, data)
static clib_error_t * from_relay_socket_read_ready(clib_file_t *uf)
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment)
u32 base_multicast_udp_port_host_byte_order
mc_multicast_socket_t multicast_sockets[MC_N_TRANSPORT_TYPE]
clib_error_t * mc_socket_main_init(mc_socket_main_t *msm, char **intfc_probe_list, int n_intfcs_to_probe)
u32 multicast_tx_ip4_address_host_byte_order
u16 current_length
Nbytes between current data and the end of this buffer.
static void msg_handler(mc_main_t *mcm, u32 buffer_index, u32 handler_frees_buffer, void *_h)
#define vec_free(V)
Free vector's memory (no header).
static u32 mc_socket_peer_id_get_address(mc_peer_id_t i)
mc_socket_catchup_t * catchups
static u32 mc_socket_peer_id_get_port(mc_peer_id_t i)
description fragment has unexpected format
static void clib_file_del(clib_file_main_t *um, clib_file_t *f)
static_always_inline u32 vlib_buffer_get_default_data_size(vlib_main_t *vm)
static void * catchup_add_pending_output(mc_socket_catchup_t *c, uword n_bytes, u8 *set_output_vector)
static clib_error_t * socket_setup(mc_socket_main_t *msm)
manual_print typedef u8 ip4_address[4]
static clib_error_t * recvmsg_helper(mc_socket_main_t *msm, int socket, struct sockaddr_in *rx_addr, u32 *buffer_index, u32 drop_message)
@ UNIX_FILE_UPDATE_MODIFY
#define clib_error_return_unix(e, args...)
static uword clib_file_add(clib_file_main_t *um, clib_file_t *template)
#define vec_resize(V, N)
Resize a vector (no header, unspecified alignment) Add N elements to end of given vector V,...
static void catchup_cleanup(mc_socket_main_t *msm, mc_socket_catchup_t *c, clib_file_main_t *um, clib_file_t *uf)
static clib_error_t * mastership_socket_read_ready(clib_file_t *uf)
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
#define clib_error(format, args...)
static void vlib_buffer_free_one(vlib_main_t *vm, u32 buffer_index)
Free one buffer Shorthand to free a single buffer chain.
static clib_error_t * catchup_socket_read_ready(clib_file_t *uf, int is_server)
static u8 * format_socket_peer_id(u8 *s, va_list *args)
static clib_error_t * sendmsg_helper(mc_socket_main_t *msm, int socket, struct sockaddr_in *tx_addr, u32 buffer_index)
u32 if_ip4_address_net_byte_order
vl_api_fib_path_type_t type
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index,...
VLIB buffer representation.
void(* file_update)(clib_file_t *file, clib_file_update_type_t update_type)