FD.io VPP  v17.10-9-gd594711
Vector Packet Processing
main.c
Go to the documentation of this file.
1 /*
2  *------------------------------------------------------------------
3  * Copyright (c) 2017 Cisco and/or its affiliates.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *------------------------------------------------------------------
16  */
17 
18 #include <stdlib.h>
19 #include <stdint.h>
20 #include <net/if.h>
21 #include <sys/types.h>
22 #include <fcntl.h>
23 #include <sys/ioctl.h>
24 #include <sys/socket.h>
25 #include <sys/un.h>
26 #include <sys/uio.h>
27 #include <sys/mman.h>
28 #include <sys/prctl.h>
29 #include <inttypes.h>
30 #include <string.h>
31 #include <stdio.h>
32 #include <netdb.h>
33 #include <linux/ip.h>
34 #include <linux/icmp.h>
35 #include <arpa/inet.h>
36 #include <stdlib.h>
37 #include <netinet/if_ether.h>
38 #include <net/if_arp.h>
39 #include <asm/byteorder.h>
40 #include <byteswap.h>
41 #include <string.h>
42 #include <sys/epoll.h>
43 #include <errno.h>
44 #include <unistd.h>
45 #include <signal.h>
46 
47 #include <libmemif.h>
48 #include <icmp_proto.h>
49 
50 #define APP_NAME "ICMP_Responder"
51 #define IF_NAME "memif_connection"
52 
53 
54 #ifdef ICMP_DBG
55 #define DBG(...) do { \
56  printf (APP_NAME":%s:%d: ", __func__, __LINE__); \
57  printf (__VA_ARGS__); \
58  printf ("\n"); \
59  } while (0)
60 #else
61 #define DBG(...)
62 #endif
63 
64 #define INFO(...) do { \
65  printf ("INFO: "__VA_ARGS__); \
66  printf ("\n"); \
67  } while (0)
68 
69 /* maximum tx/rx memif buffers */
70 #define MAX_MEMIF_BUFS 256
71 #define MAX_CONNS 50
72 
73 int epfd;
74 
75 typedef struct
76 {
77  uint16_t index;
78  /* memif conenction handle */
80  /* tx buffers */
81  memif_buffer_t *tx_bufs;
82  /* allocated tx buffers counter */
83  /* number of tx buffers pointing to shared memory */
84  uint16_t tx_buf_num;
85  /* rx buffers */
86  memif_buffer_t *rx_bufs;
87  /* allcoated rx buffers counter */
88  /* number of rx buffers pointing to shared memory */
89  uint16_t rx_buf_num;
90  /* interface ip address */
91  uint8_t ip_addr[4];
93 
94 memif_connection_t memif_connection[MAX_CONNS];
95 long ctx[MAX_CONNS];
96 
97 /* print details for all memif connections */
98 static void
100 {
101  memif_details_t md;
102  ssize_t buflen;
103  char *buf;
104  int err, i, e;
105  buflen = 2048;
106  buf = malloc (buflen);
107  printf ("MEMIF DETAILS\n");
108  printf ("==============================\n");
109  for (i = 0; i < MAX_CONNS; i++)
110  {
111  memif_connection_t *c = &memif_connection[i];
112 
113  memset (&md, 0, sizeof (md));
114  memset (buf, 0, buflen);
115 
116  err = memif_get_details (c->conn, &md, buf, buflen);
117  if (err != MEMIF_ERR_SUCCESS)
118  {
119  if (err != MEMIF_ERR_NOCONN)
120  INFO ("%s", memif_strerror (err));
121  continue;
122  }
123 
124  printf ("interface index: %d\n", i);
125 
126  printf ("\tinterface ip: %u.%u.%u.%u\n",
127  c->ip_addr[0], c->ip_addr[1], c->ip_addr[2], c->ip_addr[3]);
128  printf ("\tinterface name: %s\n", (char *) md.if_name);
129  printf ("\tapp name: %s\n", (char *) md.inst_name);
130  printf ("\tremote interface name: %s\n", (char *) md.remote_if_name);
131  printf ("\tremote app name: %s\n", (char *) md.remote_inst_name);
132  printf ("\tid: %u\n", md.id);
133  printf ("\tsecret: %s\n", (char *) md.secret);
134  printf ("\trole: ");
135  if (md.role)
136  printf ("slave\n");
137  else
138  printf ("master\n");
139  printf ("\tmode: ");
140  switch (md.mode)
141  {
142  case 0:
143  printf ("ethernet\n");
144  break;
145  case 1:
146  printf ("ip\n");
147  break;
148  case 2:
149  printf ("punt/inject\n");
150  break;
151  default:
152  printf ("unknown\n");
153  break;
154  }
155  printf ("\tsocket filename: %s\n", (char *) md.socket_filename);
156  printf ("\trx queues:\n");
157  for (e = 0; e < md.rx_queues_num; e++)
158  {
159  printf ("\t\tqueue id: %u\n", md.rx_queues[e].qid);
160  printf ("\t\tring size: %u\n", md.rx_queues[e].ring_size);
161  printf ("\t\tbuffer size: %u\n", md.rx_queues[e].buffer_size);
162  }
163  printf ("\ttx queues:\n");
164  for (e = 0; e < md.tx_queues_num; e++)
165  {
166  printf ("\t\tqueue id: %u\n", md.tx_queues[e].qid);
167  printf ("\t\tring size: %u\n", md.tx_queues[e].ring_size);
168  printf ("\t\tbuffer size: %u\n", md.tx_queues[e].buffer_size);
169  }
170  printf ("\tlink: ");
171  if (md.link_up_down)
172  printf ("up\n");
173  else
174  printf ("down\n");
175  }
176  free (buf);
177 }
178 
179 int
180 add_epoll_fd (int fd, uint32_t events)
181 {
182  if (fd < 0)
183  {
184  DBG ("invalid fd %d", fd);
185  return -1;
186  }
187  struct epoll_event evt;
188  memset (&evt, 0, sizeof (evt));
189  evt.events = events;
190  evt.data.fd = fd;
191  if (epoll_ctl (epfd, EPOLL_CTL_ADD, fd, &evt) < 0)
192  {
193  DBG ("epoll_ctl: %s fd %d", strerror (errno), fd);
194  return -1;
195  }
196  DBG ("fd %d added to epoll", fd);
197  return 0;
198 }
199 
200 int
201 mod_epoll_fd (int fd, uint32_t events)
202 {
203  if (fd < 0)
204  {
205  DBG ("invalid fd %d", fd);
206  return -1;
207  }
208  struct epoll_event evt;
209  memset (&evt, 0, sizeof (evt));
210  evt.events = events;
211  evt.data.fd = fd;
212  if (epoll_ctl (epfd, EPOLL_CTL_MOD, fd, &evt) < 0)
213  {
214  DBG ("epoll_ctl: %s fd %d", strerror (errno), fd);
215  return -1;
216  }
217  DBG ("fd %d moddified on epoll", fd);
218  return 0;
219 }
220 
221 int
222 del_epoll_fd (int fd)
223 {
224  if (fd < 0)
225  {
226  DBG ("invalid fd %d", fd);
227  return -1;
228  }
229  struct epoll_event evt;
230  memset (&evt, 0, sizeof (evt));
231  if (epoll_ctl (epfd, EPOLL_CTL_DEL, fd, &evt) < 0)
232  {
233  DBG ("epoll_ctl: %s fd %d", strerror (errno), fd);
234  return -1;
235  }
236  DBG ("fd %d removed from epoll", fd);
237  return 0;
238 }
239 
240 /* informs user about connected status. private_ctx is used by user to identify connection
241  (multiple connections WIP) */
242 int
243 on_connect (memif_conn_handle_t conn, void *private_ctx)
244 {
245  INFO ("memif connected!");
246  return 0;
247 }
248 
249 /* informs user about disconnected status. private_ctx is used by user to identify connection
250  (multiple connections WIP) */
251 int
252 on_disconnect (memif_conn_handle_t conn, void *private_ctx)
253 {
254  INFO ("memif disconnected!");
255  return 0;
256 }
257 
258 /* user needs to watch new fd or stop watching fd that is about to be closed.
259  control fd will be modified during connection establishment to minimize CPU usage */
260 int
261 control_fd_update (int fd, uint8_t events)
262 {
263  /* convert memif event definitions to epoll events */
264  if (events & MEMIF_FD_EVENT_DEL)
265  return del_epoll_fd (fd);
266 
267  uint32_t evt = 0;
268  if (events & MEMIF_FD_EVENT_READ)
269  evt |= EPOLLIN;
270  if (events & MEMIF_FD_EVENT_WRITE)
271  evt |= EPOLLOUT;
272 
273  if (events & MEMIF_FD_EVENT_MOD)
274  return mod_epoll_fd (fd, evt);
275 
276  return add_epoll_fd (fd, evt);
277 }
278 
279 int
280 icmpr_buffer_alloc (long index, long n, uint16_t qid)
281 {
282  memif_connection_t *c = &memif_connection[index];
283  int err;
284  uint16_t r;
285  /* set data pointer to shared memory and set buffer_len to shared mmeory buffer len */
286  err = memif_buffer_alloc (c->conn, qid, c->tx_bufs, n, &r, 0);
287  if (err != MEMIF_ERR_SUCCESS)
288  {
289  INFO ("memif_buffer_alloc: %s", memif_strerror (err));
290  c->tx_buf_num += r;
291  return -1;
292  }
293  c->tx_buf_num += r;
294  DBG ("allocated %d/%ld buffers, %u free buffers", r, n,
296  return 0;
297 }
298 
299 int
300 icmpr_tx_burst (long index, uint16_t qid)
301 {
302  memif_connection_t *c = &memif_connection[index];
303  int err;
304  uint16_t r;
305  /* inform peer memif interface about data in shared memory buffers */
306  /* mark memif buffers as free */
307  err = memif_tx_burst (c->conn, qid, c->tx_bufs, c->tx_buf_num, &r);
308  if (err != MEMIF_ERR_SUCCESS)
309  INFO ("memif_tx_burst: %s", memif_strerror (err));
310  DBG ("tx: %d/%u", r, c->tx_buf_num);
311  c->tx_buf_num -= r;
312  return 0;
313 }
314 
315 /* called when event is polled on interrupt file descriptor.
316  there are packets in shared memory ready to be received */
317 int
318 on_interrupt (memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
319 {
320  long index = *((long *) private_ctx);
321  memif_connection_t *c = &memif_connection[index];
322  if (c->index != index)
323  {
324  INFO ("invalid context: %ld/%u", index, c->index);
325  return 0;
326  }
327  int err;
328  uint16_t rx;
329  uint16_t fb;
330  /* receive data from shared memory buffers */
331  err = memif_rx_burst (c->conn, qid, c->rx_bufs, MAX_MEMIF_BUFS, &rx);
332  if (err != MEMIF_ERR_SUCCESS)
333  {
334  INFO ("memif_rx_burst: %s", memif_strerror (err));
335  c->rx_buf_num += rx;
336  goto error;
337  }
338  c->rx_buf_num += rx;
339 
340  DBG ("received %d buffers. %u/%u alloc/free buffers",
341  rx, c->rx_buf_num, MAX_MEMIF_BUFS - c->rx_buf_num);
342 
343  if (icmpr_buffer_alloc (index, rx, qid) < 0)
344  {
345  INFO ("buffer_alloc error");
346  goto error;
347  }
348  int i;
349  for (i = 0; i < rx; i++)
350  {
351  resolve_packet ((void *) (c->rx_bufs + i)->data,
352  (c->rx_bufs + i)->data_len,
353  (void *) (c->tx_bufs + i)->data,
354  &(c->tx_bufs + i)->data_len, c->ip_addr);
355  }
356 
357  /* mark memif buffers and shared memory buffers as free */
358  err = memif_buffer_free (c->conn, qid, c->rx_bufs, rx, &fb);
359  if (err != MEMIF_ERR_SUCCESS)
360  INFO ("memif_buffer_free: %s", memif_strerror (err));
361  c->rx_buf_num -= fb;
362 
363  DBG ("freed %d buffers. %u/%u alloc/free buffers",
364  fb, c->rx_buf_num, MAX_MEMIF_BUFS - c->rx_buf_num);
365 
366  icmpr_tx_burst (index, qid);
367 
368  return 0;
369 
370 error:
371  err = memif_buffer_free (c->conn, qid, c->rx_bufs, rx, &fb);
372  if (err != MEMIF_ERR_SUCCESS)
373  INFO ("memif_buffer_free: %s", memif_strerror (err));
374  c->rx_buf_num -= fb;
375  DBG ("freed %d buffers. %u/%u alloc/free buffers",
376  fb, c->rx_buf_num, MAX_MEMIF_BUFS - c->rx_buf_num);
377  return 0;
378 }
379 
380 int
381 icmpr_memif_create (long index, long mode)
382 {
383  if (index >= MAX_CONNS)
384  {
385  INFO ("connection array overflow");
386  return 0;
387  }
388  if (index < 0)
389  {
390  INFO ("don't even try...");
391  return 0;
392  }
393  memif_connection_t *c = &memif_connection[index];
394 
395  /* setting memif connection arguments */
396  memif_conn_args_t args;
397  int fd = -1;
398  memset (&args, 0, sizeof (args));
399  args.is_master = mode;
400  args.log2_ring_size = 10;
401  args.buffer_size = 2048;
402  args.num_s2m_rings = 2;
403  args.num_m2s_rings = 2;
404  strncpy ((char *) args.interface_name, IF_NAME, strlen (IF_NAME));
405  strncpy ((char *) args.instance_name, APP_NAME, strlen (APP_NAME));
406  args.mode = 0;
407  /* socket filename is not specified, because this app is supposed to
408  connect to VPP over memif. so default socket filename will be used */
409  /* default socketfile = /run/vpp/memif.sock */
410 
411  args.interface_id = index;
412  /* last argument for memif_create (void * private_ctx) is used by user
413  to identify connection. this context is returned with callbacks */
414  int err = memif_create (&c->conn,
416  &ctx[index]);
417  if (err != MEMIF_ERR_SUCCESS)
418  {
419  INFO ("memif_create: %s", memif_strerror (err));
420  return 0;
421  }
422 
423  c->index = index;
424  /* alloc memif buffers */
425  c->rx_buf_num = 0;
426  c->rx_bufs =
427  (memif_buffer_t *) malloc (sizeof (memif_buffer_t) * MAX_MEMIF_BUFS);
428  c->tx_buf_num = 0;
429  c->tx_bufs =
430  (memif_buffer_t *) malloc (sizeof (memif_buffer_t) * MAX_MEMIF_BUFS);
431 
432  c->ip_addr[0] = 192;
433  c->ip_addr[1] = 168;
434  c->ip_addr[2] = c->index + 1;
435  c->ip_addr[3] = 2;
436  return 0;
437 }
438 
439 int
440 icmpr_memif_delete (long index)
441 {
442  if (index >= MAX_CONNS)
443  {
444  INFO ("connection array overflow");
445  return 0;
446  }
447  if (index < 0)
448  {
449  INFO ("don't even try...");
450  return 0;
451  }
452  memif_connection_t *c = &memif_connection[index];
453 
454  if (c->rx_bufs)
455  free (c->rx_bufs);
456  c->rx_bufs = NULL;
457  c->rx_buf_num = 0;
458  if (c->tx_bufs)
459  free (c->tx_bufs);
460  c->tx_bufs = NULL;
461  c->tx_buf_num = 0;
462 
463  int err;
464  /* disconenct then delete memif connection */
465  err = memif_delete (&c->conn);
466  if (err != MEMIF_ERR_SUCCESS)
467  INFO ("memif_delete: %s", memif_strerror (err));
468  if (c->conn != NULL)
469  INFO ("memif delete fail");
470  return 0;
471 }
472 
473 void
475 {
476  printf ("LIBMEMIF EXAMPLE APP: %s", APP_NAME);
477 #ifdef ICMP_DBG
478  printf (" (debug)");
479 #endif
480  printf ("\n");
481  printf ("==============================\n");
482  printf ("libmemif version: %s", LIBMEMIF_VERSION);
483 #ifdef MEMIF_DBG
484  printf (" (debug)");
485 #endif
486  printf ("\n");
487  printf ("memif version: %d\n", MEMIF_VERSION);
488  printf ("commands:\n");
489  printf ("\thelp - prints this help\n");
490  printf ("\texit - exit app\n");
491  printf
492  ("\tconn <index> <mode> - create memif. index is also used as interface id, mode 0 = slave 1 = master\n");
493  printf ("\tdel <index> - delete memif\n");
494  printf ("\tshow - show connection details\n");
495  printf ("\tip-set <index> <ip-addr> - set interface ip address\n");
496  printf
497  ("\trx-mode <index> <qid> <polling|interrupt> - set queue rx mode\n");
498 }
499 
500 int
502 {
503  /* application cleanup */
504  int err;
505  long i;
506  for (i = 0; i < MAX_CONNS; i++)
507  {
508  memif_connection_t *c = &memif_connection[i];
509  if (c->conn)
510  icmpr_memif_delete (i);
511  }
512 
513  err = memif_cleanup ();
514  if (err != MEMIF_ERR_SUCCESS)
515  INFO ("memif_delete: %s", memif_strerror (err));
516 
517  return 0;
518 }
519 
520 int
521 icmpr_set_ip (long index, char *ip)
522 {
523  if (index >= MAX_CONNS)
524  {
525  INFO ("connection array overflow");
526  return 0;
527  }
528  if (index < 0)
529  {
530  INFO ("don't even try...");
531  return 0;
532  }
533  memif_connection_t *c = &memif_connection[index];
534  if (c->conn == NULL)
535  {
536  INFO ("no connection at index %ld", index);
537  return 0;
538  }
539 
540  char *end;
541  char *ui;
542  uint8_t tmp[4];
543  ui = strtok (ip, ".");
544  if (ui == NULL)
545  goto error;
546  tmp[0] = strtol (ui, &end, 10);
547 
548  ui = strtok (NULL, ".");
549  if (ui == NULL)
550  goto error;
551  tmp[1] = strtol (ui, &end, 10);
552 
553  ui = strtok (NULL, ".");
554  if (ui == NULL)
555  goto error;
556  tmp[2] = strtol (ui, &end, 10);
557 
558  ui = strtok (NULL, ".");
559  if (ui == NULL)
560  goto error;
561  tmp[3] = strtol (ui, &end, 10);
562 
563  c->ip_addr[0] = tmp[0];
564  c->ip_addr[1] = tmp[1];
565  c->ip_addr[2] = tmp[2];
566  c->ip_addr[3] = tmp[3];
567 
568  INFO ("memif %ld ip address set to %u.%u.%u.%u",
569  index, c->ip_addr[0], c->ip_addr[1], c->ip_addr[2], c->ip_addr[3]);
570 
571  return 0;
572 
573 error:
574  INFO ("invalid ip address");
575  return 0;
576 }
577 
578 int
579 icmpr_set_rx_mode (long index, long qid, char *mode)
580 {
581  if (index >= MAX_CONNS)
582  {
583  INFO ("connection array overflow");
584  return 0;
585  }
586  if (index < 0)
587  {
588  INFO ("don't even try...");
589  return 0;
590  }
591  memif_connection_t *c = &memif_connection[index];
592 
593  if (c->conn == NULL)
594  {
595  INFO ("no connection at index %ld", index);
596  return 0;
597  }
598 
599  if (strncmp (mode, "interrupt", 9) == 0)
600  {
602  }
603 
604  else if (strncmp (mode, "polling", 7) == 0)
605  {
607  }
608  else
609  INFO ("expected rx mode <interrupt|polling>");
610  return 0;
611 }
612 
613 int
615 {
616  int i;
617  char *in = (char *) malloc (256);
618  char *ui = fgets (in, 256, stdin);
619  char *end;
620  long a;
621  if (in[0] == '\n')
622  goto done;
623  ui = strtok (in, " ");
624  if (strncmp (ui, "exit", 4) == 0)
625  {
626  free (in);
627  icmpr_free ();
628  exit (EXIT_SUCCESS);
629  }
630  else if (strncmp (ui, "help", 4) == 0)
631  {
632  print_help ();
633  goto done;
634  }
635  else if (strncmp (ui, "conn", 4) == 0)
636  {
637  ui = strtok (NULL, " ");
638  if (ui != NULL)
639  a = strtol (ui, &end, 10);
640  else
641  {
642  INFO ("expected id");
643  goto done;
644  }
645  ui = strtok (NULL, " ");
646  if (ui != NULL)
647  icmpr_memif_create (a, strtol (ui, &end, 10));
648  else
649  INFO ("expected mode <0|1>");
650  goto done;
651  }
652  else if (strncmp (ui, "del", 3) == 0)
653  {
654  ui = strtok (NULL, " ");
655  if (ui != NULL)
656  icmpr_memif_delete (strtol (ui, &end, 10));
657  else
658  INFO ("expected id");
659  goto done;
660  }
661  else if (strncmp (ui, "show", 4) == 0)
662  {
664  goto done;
665  }
666  else if (strncmp (ui, "ip-set", 6) == 0)
667  {
668  ui = strtok (NULL, " ");
669  if (ui != NULL)
670  icmpr_set_ip (strtol (ui, &end, 10), strtok (NULL, " "));
671  else
672  INFO ("expected id");
673  goto done;
674  }
675  else if (strncmp (ui, "rx-mode", 7) == 0)
676  {
677  ui = strtok (NULL, " ");
678  if (ui != NULL)
679  a = strtol (ui, &end, 10);
680  else
681  {
682  INFO ("expected id");
683  goto done;
684  }
685  ui = strtok (NULL, " ");
686  if (ui != NULL)
687  icmpr_set_rx_mode (a, strtol (ui, &end, 10), strtok (NULL, " "));
688  else
689  INFO ("expected qid");
690  goto done;
691  }
692  else
693  {
694  DBG ("unknown command: %s", ui);
695  goto done;
696  }
697 
698  return 0;
699 done:
700  free (in);
701  return 0;
702 }
703 
704 int
705 poll_event (int timeout)
706 {
707  struct epoll_event evt, *e;
708  int app_err = 0, memif_err = 0, en = 0;
709  int tmp, nfd;
710  uint32_t events = 0;
711  memset (&evt, 0, sizeof (evt));
712  evt.events = EPOLLIN | EPOLLOUT;
713  sigset_t sigset;
714  sigemptyset (&sigset);
715  en = epoll_pwait (epfd, &evt, 1, timeout, &sigset);
716  if (en < 0)
717  {
718  DBG ("epoll_pwait: %s", strerror (errno));
719  return -1;
720  }
721  if (en > 0)
722  {
723  /* this app does not use any other file descriptors than stds and memif control fds */
724  if (evt.data.fd > 2)
725  {
726  /* event of memif control fd */
727  /* convert epolle events to memif events */
728  if (evt.events & EPOLLIN)
729  events |= MEMIF_FD_EVENT_READ;
730  if (evt.events & EPOLLOUT)
731  events |= MEMIF_FD_EVENT_WRITE;
732  if (evt.events & EPOLLERR)
733  events |= MEMIF_FD_EVENT_ERROR;
734  memif_err = memif_control_fd_handler (evt.data.fd, events);
735  if (memif_err != MEMIF_ERR_SUCCESS)
736  INFO ("memif_control_fd_handler: %s", memif_strerror (memif_err));
737  }
738  else if (evt.data.fd == 0)
739  {
740  app_err = user_input_handler ();
741  }
742  else
743  {
744  DBG ("unexpected event at memif_epfd. fd %d", evt.data.fd);
745  }
746  }
747 
748  if ((app_err < 0) || (memif_err < 0))
749  {
750  if (app_err < 0)
751  DBG ("user input handler error");
752  if (memif_err < 0)
753  DBG ("memif control fd handler error");
754  return -1;
755  }
756 
757  return 0;
758 }
759 
760 int
762 {
763  epfd = epoll_create (1);
764  add_epoll_fd (0, EPOLLIN);
765 
766  /* initialize memory interface */
767  int err, i;
768  /* if valid callback is passed as argument, fd event polling will be done by user
769  all file descriptors and events will be passed to user in this callback */
770  /* if callback is set to NULL libmemif will handle fd event polling */
772  if (err != MEMIF_ERR_SUCCESS)
773  INFO ("memif_init: %s", memif_strerror (err));
774 
775  for (i = 0; i < MAX_CONNS; i++)
776  {
777  memif_connection[i].conn = NULL;
778  ctx[i] = i;
779  }
780 
781  print_help ();
782 
783  /* main loop */
784  while (1)
785  {
786  if (poll_event (-1) < 0)
787  {
788  DBG ("poll_event error!");
789  }
790  }
791 }
#define IF_NAME
Definition: main.c:51
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:337
int icmpr_memif_delete()
Definition: main.c:193
memif_log2_ring_size_t log2_ring_size
Definition: libmemif.h:161
int mod_epoll_fd(int fd, uint32_t events)
Definition: main.c:201
void print_help()
Definition: main.c:204
a
Definition: bitmap.h:516
uint8_t * inst_name
Definition: libmemif.h:230
uint8_t * secret
Definition: libmemif.h:235
int on_disconnect(memif_conn_handle_t conn, void *private_ctx)
Definition: main.c:186
#define MEMIF_FD_EVENT_READ
user needs to set events that occured on fd and pass them to memif_control_fd_handler ...
Definition: libmemif.h:84
uint8_t num_m2s_rings
Definition: libmemif.h:159
int control_fd_update(int fd, uint8_t events)
Definition: main.c:261
#define NULL
Definition: clib.h:55
uint16_t buffer_size
Definition: libmemif.h:160
memif_interface_id_t interface_id
Definition: libmemif.h:164
int icmpr_set_ip(long index, char *ip)
Definition: main.c:521
uint8_t * remote_inst_name
Definition: libmemif.h:232
#define LIBMEMIF_VERSION
Libmemif version.
Definition: libmemif.h:24
int on_connect(memif_conn_handle_t conn, void *private_ctx)
Definition: main.c:177
uint8_t num_s2m_rings
Definition: libmemif.h:158
int icmpr_free()
Definition: main.c:258
int memif_get_details(memif_conn_handle_t conn, memif_details_t *md, char *buf, ssize_t buflen)
Memif get details.
Definition: main.c:1932
int icmpr_set_rx_mode(long index, long qid, char *mode)
Definition: main.c:579
memif_interface_mode_t mode
Definition: libmemif.h:167
int memif_buffer_free(memif_conn_handle_t conn, uint16_t qid, memif_buffer_t *bufs, uint16_t count, uint16_t *count_out)
Memif buffer free.
Definition: main.c:1478
uint8_t mode
Definition: libmemif.h:237
uint8_t link_up_down
Definition: libmemif.h:244
char * memif_strerror(int err_code)
Memif strerror.
Definition: main.c:148
int icmpr_memif_create(int is_master)
Definition: main.c:337
memif_conn_handle_t conn
Definition: main.c:76
#define APP_NAME
Definition: main.c:50
int del_epoll_fd(int fd)
Definition: main.c:222
#define MAX_MEMIF_BUFS
Definition: main.c:70
uint8_t ip_addr[4]
Definition: main.c:90
uint16_t rx_buf_num
Definition: main.c:88
#define MAX_CONNS
Definition: main.c:71
uint8_t interface_name[32]
Definition: libmemif.h:165
int resolve_packet(void *in_pck, ssize_t in_size, void *out_pck, uint32_t *out_size, uint8_t ip_addr[4])
Definition: icmp_proto.c:206
uint16_t buffer_size
Definition: libmemif.h:207
uint8_t * socket_filename
Definition: libmemif.h:238
#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) ...
Definition: libmemif.h:89
int memif_set_rx_mode(memif_conn_handle_t c, memif_rx_mode_t rx_mode, uint16_t qid)
Memif set rx mode.
Definition: main.c:508
struct memif_connection memif_connection_t
uint8_t is_master
Definition: libmemif.h:162
uint8_t rx_queues_num
Definition: libmemif.h:239
#define DBG(...)
Definition: main.c:61
int icmpr_tx_burst(uint16_t qid)
Definition: main.c:242
uint16_t tx_buf_num
Definition: main.c:83
int on_interrupt(memif_conn_handle_t conn, void *private_ctx, uint16_t qid)
Definition: main.c:287
svmdb_client_t * c
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.
Definition: main.c:1547
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.
Definition: main.c:1341
int add_epoll_fd(int fd, uint32_t events)
Definition: main.c:180
memif_queue_details_t * rx_queues
Definition: libmemif.h:241
uint8_t role
Definition: libmemif.h:236
#define INFO(...)
Definition: main.c:64
uint8_t instance_name[32]
Definition: libmemif.h:166
int memif_cleanup()
Memif cleanup.
Definition: main.c:2075
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.
Definition: main.c:526
long ctx[MAX_CONNS]
Definition: main.c:95
#define MEMIF_VERSION
Definition: memif.h:28
int poll_event(int timeout)
Definition: main.c:705
uint8_t tx_queues_num
Definition: libmemif.h:240
void * memif_conn_handle_t
*brief Memif connection handle pointer of type void, pointing to internal structure ...
Definition: libmemif.h:97
int icmpr_buffer_alloc(long n, uint16_t qid)
Definition: main.c:222
int memif_control_fd_handler(int fd, uint8_t events)
Memif control file descriptor handler.
Definition: main.c:770
int epfd
Definition: main.c:94
int memif_init(memif_control_fd_update_t *on_control_fd_update, char *app_name)
Memif initialization.
Definition: main.c:400
uint32_t id
Definition: libmemif.h:234
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.
Definition: main.c:1768
int memif_delete(memif_conn_handle_t *conn)
Memif delete.
Definition: main.c:1072
static void print_memif_details()
Definition: main.c:99
#define MEMIF_FD_EVENT_ERROR
inform libmemif that error occured on fd
Definition: libmemif.h:87
#define MEMIF_FD_EVENT_MOD
update events
Definition: libmemif.h:91
int main(int argc, char *argv[])
Definition: main.c:56
memif_queue_details_t * tx_queues
Definition: libmemif.h:242
uint8_t * if_name
Definition: libmemif.h:229
uint16_t index
Definition: main.c:74
Memif buffer.
Definition: libmemif.h:183
#define MEMIF_FD_EVENT_WRITE
Definition: libmemif.h:85
memif_buffer_t * tx_bufs
Definition: main.c:80
Memif connection arguments.
Definition: libmemif.h:153
int user_input_handler()
Definition: main.c:614
Memif details.
Definition: libmemif.h:227
uint8_t * remote_if_name
Definition: libmemif.h:231
memif_buffer_t * rx_bufs
Definition: main.c:85