|
FD.io VPP
v21.10.1-2-g0a485f517
Vector Packet Processing
|
Go to the documentation of this file.
21 #include <sys/types.h>
23 #include <sys/ioctl.h>
24 #include <sys/socket.h>
28 #include <sys/prctl.h>
34 #include <linux/icmp.h>
35 #include <arpa/inet.h>
37 #include <netinet/if_ether.h>
38 #include <net/if_arp.h>
39 #include <asm/byteorder.h>
42 #include <sys/epoll.h>
51 #define APP_NAME "ICMP_Responder"
52 #define IF_NAME "memif_connection"
56 #define DBG(...) do { \
57 printf (APP_NAME":%s:%d: ", __func__, __LINE__); \
58 printf (__VA_ARGS__); \
65 #define INFO(...) do { \
66 printf ("INFO: "__VA_ARGS__); \
71 #define MAX_MEMIF_BUFS 256
74 #define MAX_THREADS ((MAX_CONNS) * (MAX_QUEUES))
126 printf (
"MEMIF DETAILS\n");
127 printf (
"==============================\n");
132 memset (&md, 0,
sizeof (md));
133 memset (
buf, 0, buflen);
143 printf (
"interface index: %d\n",
i);
145 printf (
"\tinterface ip: %u.%u.%u.%u\n",
146 c->ip_addr[0],
c->ip_addr[1],
c->ip_addr[2],
c->ip_addr[3]);
147 printf (
"\tinterface name: %s\n", (
char *) md.
if_name);
148 printf (
"\tapp name: %s\n", (
char *) md.
inst_name);
149 printf (
"\tremote interface name: %s\n", (
char *) md.
remote_if_name);
151 printf (
"\tid: %u\n", md.
id);
152 printf (
"\tsecret: %s\n", (
char *) md.
secret);
162 printf (
"ethernet\n");
168 printf (
"punt/inject\n");
171 printf (
"unknown\n");
175 printf (
"\trx queues:\n");
184 printf (
"\t\tthread running: ");
190 printf (
"\ttx queues:\n");
211 DBG (
"invalid fd %d", fd);
214 struct epoll_event evt;
215 memset (&evt, 0,
sizeof (evt));
218 if (epoll_ctl (
epfd, EPOLL_CTL_ADD, fd, &evt) < 0)
220 DBG (
"epoll_ctl: %s fd %d", strerror (errno), fd);
223 DBG (
"fd %d added to epoll", fd);
232 DBG (
"invalid fd %d", fd);
235 struct epoll_event evt;
236 memset (&evt, 0,
sizeof (evt));
239 if (epoll_ctl (
epfd, EPOLL_CTL_MOD, fd, &evt) < 0)
241 DBG (
"epoll_ctl: %s fd %d", strerror (errno), fd);
244 DBG (
"fd %d modified on epoll", fd);
253 DBG (
"invalid fd %d", fd);
256 struct epoll_event evt;
257 memset (&evt, 0,
sizeof (evt));
258 if (epoll_ctl (
epfd, EPOLL_CTL_DEL, fd, &evt) < 0)
260 DBG (
"epoll_ctl: %s fd %d", strerror (errno), fd);
263 DBG (
"fd %d removed from epoll", fd);
273 uint16_t rx = 0, tx = 0, fb = 0;
277 data->rx_buf_num = 0;
278 data->tx_buf_num = 0;
281 INFO (
"pthread id %u starts in polling mode",
data->id);
295 data->rx_buf_num += rx;
298 data->rx_buf_num += rx;
304 DBG (
"thread id: %u",
data->id);
306 DBG (
"received %d buffers. %u/%u alloc/free buffers",
311 data->rx_buf_num, &tx, 0);
315 data->tx_buf_num += tx;
318 data->tx_buf_num += tx;
319 DBG (
"allocated %d/%d buffers, %u free buffers",
323 for (
i = 0;
i < rx;
i++)
326 (
data->rx_bufs +
i)->len,
327 (
void *) (
data->tx_bufs +
i)->data,
328 &(
data->tx_bufs +
i)->len,
c->ip_addr);
335 data->rx_buf_num -= fb;
337 DBG (
"freed %d buffers. %u/%u alloc/free buffers",
348 DBG (
"tx: %d/%u", tx,
data->tx_buf_num);
349 data->tx_buf_num -= tx;
353 INFO (
"thread %u error!",
data->id);
360 data->rx_buf_num -= fb;
361 DBG (
"freed %d buffers. %u/%u alloc/free buffers",
366 INFO (
"pthread id %u exit",
data->id);
376 uint16_t rx = 0, tx = 0, fb = 0;
377 struct epoll_event evt;
385 data->rx_buf_num = 0;
386 data->tx_buf_num = 0;
389 INFO (
"pthread id %u starts in interrupt mode",
data->id);
390 int thread_epfd = epoll_create (1);
404 memset (&evt, 0,
sizeof (evt));
405 evt.events = EPOLLIN | EPOLLOUT;
406 sigemptyset (&sigset);
407 en = epoll_pwait (thread_epfd, &evt, 1, -1, &sigset);
412 DBG (
"epoll_pwait: %s", strerror (errno));
424 data->rx_buf_num += rx;
427 data->rx_buf_num += rx;
433 DBG (
"thread id: %u",
data->id);
435 DBG (
"received %d buffers. %u/%u alloc/free buffers",
440 data->rx_buf_num, &tx, 0);
444 data->tx_buf_num += tx;
447 data->tx_buf_num += tx;
448 DBG (
"allocated %d/%d buffers, %u free buffers",
452 for (
i = 0;
i < rx;
i++)
455 (
data->rx_bufs +
i)->len,
456 (
void *) (
data->tx_bufs +
i)->data,
457 &(
data->tx_bufs +
i)->len,
c->ip_addr);
464 data->rx_buf_num -= fb;
466 DBG (
"freed %d buffers. %u/%u alloc/free buffers",
471 data->tx_buf_num, &tx);
477 DBG (
"tx: %d/%u", tx,
data->tx_buf_num);
478 data->tx_buf_num -= tx;
483 INFO (
"thread %u error!",
data->id);
490 data->rx_buf_num -= fb;
491 DBG (
"freed %d buffers. %u/%u alloc/free buffers",
496 INFO (
"pthread id %u exit",
data->id);
506 long index = (*(
long *) private_ctx);
508 INFO (
"memif connected! index %ld",
index);
522 INFO (
"thread id: %d already running!",
ti);
547 long index = (*(
long *) private_ctx);
550 INFO (
"memif disconnected!");
591 INFO (
"connection array overflow");
596 INFO (
"don't even try...");
603 memset (&args, 0,
sizeof (args));
631 c->ip_addr[2] =
c->index + 1;
641 INFO (
"connection array overflow");
646 INFO (
"don't even try...");
662 printf (
"LIBMEMIF EXAMPLE APP: %s",
APP_NAME);
667 printf (
"==============================\n");
674 printf (
"commands:\n");
675 printf (
"\thelp - prints this help\n");
676 printf (
"\texit - exit app\n");
677 printf (
"\tconn <index> - create memif (slave-mode)\n");
678 printf (
"\tdel <index> - delete memif\n");
679 printf (
"\tshow - show connection details\n");
680 printf (
"\tip-set <index> <ip-addr> - set interface ip address\n");
708 INFO (
"connection array overflow");
713 INFO (
"don't even try...");
719 INFO (
"no connection at index %ld",
index);
726 ui = strtok (
ip,
".");
729 tmp[0] = strtol (ui, &
end, 10);
731 ui = strtok (NULL,
".");
734 tmp[1] = strtol (ui, &
end, 10);
736 ui = strtok (NULL,
".");
739 tmp[2] = strtol (ui, &
end, 10);
741 ui = strtok (NULL,
".");
744 tmp[3] = strtol (ui, &
end, 10);
746 c->ip_addr[0] =
tmp[0];
747 c->ip_addr[1] =
tmp[1];
748 c->ip_addr[2] =
tmp[2];
749 c->ip_addr[3] =
tmp[3];
751 INFO (
"memif %ld ip address set to %u.%u.%u.%u",
752 index,
c->ip_addr[0],
c->ip_addr[1],
c->ip_addr[2],
c->ip_addr[3]);
757 INFO (
"invalid ip address");
765 char *in = (
char *)
malloc (256);
766 char *ui = fgets (in, 256, stdin);
770 ui = strtok (in,
" ");
771 if (strncmp (ui,
"exit", 4) == 0)
777 else if (strncmp (ui,
"help", 4) == 0)
782 else if (strncmp (ui,
"conn", 4) == 0)
784 ui = strtok (NULL,
" ");
788 INFO (
"expected id");
791 else if (strncmp (ui,
"del", 3) == 0)
793 ui = strtok (NULL,
" ");
797 INFO (
"expected id");
800 else if (strncmp (ui,
"show", 4) == 0)
805 else if (strncmp (ui,
"ip-set", 6) == 0)
807 ui = strtok (NULL,
" ");
811 INFO (
"expected id");
816 DBG (
"unknown command: %s", ui);
829 struct epoll_event evt;
830 int app_err = 0, memif_err = 0, en = 0;
832 memset (&evt, 0,
sizeof (evt));
833 evt.events = EPOLLIN | EPOLLOUT;
835 sigemptyset (&sigset);
836 en = epoll_pwait (
main_epfd, &evt, 1, timeout, &sigset);
839 DBG (
"epoll_pwait: %s", strerror (errno));
849 if (evt.events & EPOLLIN)
851 if (evt.events & EPOLLOUT)
853 if (evt.events & EPOLLERR)
859 else if (evt.data.fd == 0)
865 DBG (
"unexpected event at memif_epfd. fd %d", evt.data.fd);
869 if ((app_err < 0) || (memif_err < 0))
872 DBG (
"user input handler error");
874 DBG (
"memif control fd handler error");
911 DBG (
"poll_event error!");
#define MEMIF_FD_EVENT_MOD
update events
int icmpr_set_ip(long index, char *ip)
#define MEMIF_FD_EVENT_WRITE
int on_connect(memif_conn_handle_t conn, void *private_ctx)
memif_interface_mode_t mode
int control_fd_update(int fd, uint8_t events, void *ctx)
int icmpr_memif_create(int is_master)
int memif_create(memif_conn_handle_t *c, memif_conn_args_t *args, memif_connection_update_t *on_connect, memif_connection_update_t *on_disconnect, memif_interrupt_t *on_interrupt, void *private_ctx)
Memory interface create function.
pthread_t thread[MAX_CONNS]
Memif connection arguments.
int add_epoll_fd(int fd, uint32_t events)
int memif_get_details(memif_conn_handle_t conn, memif_details_t *md, char *buf, ssize_t buflen)
Memif get details.
memif_queue_details_t * tx_queues
int on_disconnect(memif_conn_handle_t conn, void *private_ctx)
memif_thread_data_t thread_data[MAX_THREADS]
int memif_init(memif_control_fd_update_t *on_control_fd_update, char *app_name, memif_alloc_t *memif_alloc, memif_realloc_t *memif_realloc, memif_free_t *memif_free)
Memif initialization.
void * memif_rx_poll(void *ptr)
static void print_memif_details()
uint16_t memif_get_version()
Memif get version.
int poll_event(int timeout)
struct memif_connection memif_connection_t
f64 end
end of the time range
uint8_t * remote_inst_name
int memif_buffer_alloc(memif_conn_handle_t conn, uint16_t qid, memif_buffer_t *bufs, uint16_t count, uint16_t *count_out, uint16_t size)
Memif buffer alloc.
#define LIBMEMIF_VERSION
Libmemif version.
void * memif_rx_interrupt(void *ptr)
static perfmon_event_t events[]
int memif_set_rx_mode(memif_conn_handle_t c, memif_rx_mode_t rx_mode, uint16_t qid)
Memif set rx mode.
int memif_cleanup()
Memif cleanup.
#define MEMIF_FD_EVENT_ERROR
inform libmemif that error occurred on fd
#define MEMIF_FD_EVENT_DEL
if set, informs that fd is going to be closed (user may want to stop watching for events on this fd)
void * memif_conn_handle_t
Memif connection handle pointer of type void, pointing to internal structure.
int memif_get_queue_efd(memif_conn_handle_t conn, uint16_t qid, int *efd)
Memif get queue event file descriptor.
uint8_t * socket_filename
int main(int argc, char *argv[])
int memif_tx_burst(memif_conn_handle_t conn, uint16_t qid, memif_buffer_t *bufs, uint16_t count, uint16_t *tx)
Memif transmit buffer burst.
int memif_control_fd_handler(int fd, uint8_t events)
Memif control file descriptor handler.
uint8_t interface_name[32]
int memif_delete(memif_conn_handle_t *conn)
Memif delete.
int resolve_packet(void *in_pck, ssize_t in_size, void *out_pck, uint32_t *out_size, uint8_t ip_addr[4])
void user_signal_handler(int sig)
char * memif_strerror(int err_code)
Memif strerror.
void * malloc(size_t size)
memif_queue_details_t * rx_queues
int memif_refill_queue(memif_conn_handle_t conn, uint16_t qid, uint16_t count, uint16_t headroom)
Memif refill queue.
#define MEMIF_FD_EVENT_READ
user needs to set events that occurred on fd and pass them to memif_control_fd_handler
int memif_rx_burst(memif_conn_handle_t conn, uint16_t qid, memif_buffer_t *bufs, uint16_t count, uint16_t *rx)
Memif receive buffer burst.
int mod_epoll_fd(int fd, uint32_t events)