FD.io VPP  v21.06-3-gbb25fbf28
Vector Packet Processing
punt.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 /**
17  * @file
18  * @brief Local TCP/IP stack punt infrastructure.
19  *
20  * Provides a set of VPP nodes together with the relevant APIs and CLI
21  * commands in order to adjust and dispatch packets from the VPP data plane
22  * to the local TCP/IP stack
23  */
24 
25 #include <vnet/ip/ip.h>
26 #include <vlib/vlib.h>
27 #include <vnet/udp/udp.h>
28 #include <vnet/tcp/tcp.h>
29 #include <vnet/ip/punt.h>
30 #include <vlib/unix/unix.h>
31 
32 #include <stdio.h>
33 #include <unistd.h>
34 #include <sys/socket.h>
35 #include <sys/uio.h>
36 #include <stdlib.h>
37 
39 
40 char *
42 {
43  punt_main_t *pm = &punt_main;
44  return pm->sun_path;
45 }
46 
47 static void
49 {
50  punt_main_t *pm = &punt_main;
51 
54  index);
55 }
56 
57 static u32
59 {
60  punt_main_t *pm = &punt_main;
61  u32 key, index = ~0;
62  uword *p;
63 
65  p = hash_get (pm->db.clients_by_l4_port, key);
66 
67  if (p)
68  index = p[0];
69 
71 
72  return (index);
73 }
74 
75 static void
78 {
79  punt_main_t *pm = &punt_main;
80 
83  proto),
84  index);
85 }
86 
87 static u32
89 {
90  punt_main_t *pm = &punt_main;
91  u32 key, index = ~0;
92  uword *p;
93 
96 
97  if (p)
98  index = p[0];
99 
101 
102  return (index);
103 }
104 
105 static void
107 {
108  punt_main_t *pm = &punt_main;
109 
111 
112  pm->db.clients_by_exception[reason] = pci;
113 }
114 
115 static u32
117 {
118  punt_main_t *pm = &punt_main;
119  u32 pci = ~0;
120 
121  if (punt_client_exception_get (reason))
122  {
123  pci = pm->db.clients_by_exception[reason];
124  pm->db.clients_by_exception[reason] = ~0;
125  }
126 
127  return pci;
128 }
129 
130 static clib_error_t *
132 {
134  punt_main_t *pm = &punt_main;
135 
136  /** Schedule the rx node */
139 
140  return 0;
141 }
142 
143 static clib_error_t *
146  u8 protocol, u16 port, char *client_pathname)
147 {
148  punt_main_t *pm = &punt_main;
149  punt_client_t *c;
150 
151  /* For now we only support UDP punt */
152  if (protocol != IP_PROTOCOL_UDP)
153  return clib_error_return (0,
154  "only UDP protocol (%d) is supported, got %d",
155  IP_PROTOCOL_UDP, protocol);
156 
157  if (port == (u16) ~ 0)
158  return clib_error_return (0, "UDP port number required");
159 
160  c = punt_client_l4_get (af, port);
161 
162  if (NULL == c)
163  {
166  }
167 
168  memcpy (c->caddr.sun_path, client_pathname, sizeof (c->caddr.sun_path));
169  c->caddr.sun_family = AF_UNIX;
170  c->reg.type = PUNT_TYPE_L4;
171  c->reg.punt.l4.port = port;
172  c->reg.punt.l4.protocol = protocol;
173  c->reg.punt.l4.af = af;
174 
175  u32 node_index = (af == AF_IP4 ?
176  udp4_punt_socket_node.index :
177  udp6_punt_socket_node.index);
178 
180 
181  return (NULL);
182 }
183 
184 static clib_error_t *
187  ip_protocol_t proto, char *client_pathname)
188 {
189  punt_main_t *pm = &punt_main;
190  punt_client_t *c;
191 
193 
194  if (NULL == c)
195  {
198  }
199 
200  memcpy (c->caddr.sun_path, client_pathname, sizeof (c->caddr.sun_path));
201  c->caddr.sun_family = AF_UNIX;
202  c->reg.type = PUNT_TYPE_IP_PROTO;
203  c->reg.punt.ip_proto.protocol = proto;
204  c->reg.punt.ip_proto.af = af;
205 
206  if (af == AF_IP4)
208  else
210 
211  return (NULL);
212 }
213 
214 static clib_error_t *
216  vlib_punt_reason_t reason,
217  char *client_pathname)
218 {
219  punt_main_t *pm = &punt_main;
220  punt_client_t *pc;
221 
222  pc = punt_client_exception_get (reason);
223 
224  if (NULL == pc)
225  {
228  }
229 
230  memcpy (pc->caddr.sun_path, client_pathname, sizeof (pc->caddr.sun_path));
231  pc->caddr.sun_family = AF_UNIX;
232  pc->reg.type = PUNT_TYPE_EXCEPTION;
233  pc->reg.punt.exception.reason = reason;
234 
235  vlib_punt_register (pm->hdl,
236  pc->reg.punt.exception.reason, "exception-punt-socket");
237 
238  return (NULL);
239 }
240 
241 static clib_error_t *
244 {
245  u32 pci;
246 
248 
249  pci = punt_client_l4_db_remove (af, port);
250 
251  if (~0 != pci)
253 
254  return (NULL);
255 }
256 
257 static clib_error_t *
259 {
260  u32 pci;
261 
262  if (af == AF_IP4)
264  else
266 
268 
269  if (~0 != pci)
271 
272  return (NULL);
273 }
274 
275 static clib_error_t *
277 {
278  u32 pci;
279 
280  pci = punt_client_exception_db_remove (reason);
281 
282  if (~0 != pci)
284 
285  return (NULL);
286 }
287 
288 clib_error_t *
290  const punt_reg_t * pr, char *client_pathname)
291 {
292  punt_main_t *pm = &punt_main;
293 
294  if (!pm->is_configured)
295  return clib_error_return (0, "socket is not configured");
296 
297  if (header_version != PUNT_PACKETDESC_VERSION)
298  return clib_error_return (0, "Invalid packet descriptor version");
299 
300  if (strncmp (client_pathname, vnet_punt_get_server_pathname (),
301  UNIX_PATH_MAX) == 0)
302  return clib_error_return (0,
303  "Punt socket: Invalid client path: %s",
304  client_pathname);
305 
306  /* Register client */
307  switch (pr->type)
308  {
309  case PUNT_TYPE_L4:
310  return (punt_socket_register_l4 (vm,
311  pr->punt.l4.af,
312  pr->punt.l4.protocol,
313  pr->punt.l4.port, client_pathname));
314  case PUNT_TYPE_IP_PROTO:
316  pr->punt.ip_proto.af,
317  pr->punt.ip_proto.protocol,
318  client_pathname));
319  case PUNT_TYPE_EXCEPTION:
321  pr->punt.exception.reason,
322  client_pathname));
323  }
324 
325  return 0;
326 }
327 
328 clib_error_t *
330 {
331  punt_main_t *pm = &punt_main;
332 
333  if (!pm->is_configured)
334  return clib_error_return (0, "socket is not configured");
335 
336  switch (pr->type)
337  {
338  case PUNT_TYPE_L4:
339  return (punt_socket_unregister_l4 (pr->punt.l4.af,
340  pr->punt.l4.protocol,
341  pr->punt.l4.port));
342  case PUNT_TYPE_IP_PROTO:
344  pr->punt.ip_proto.protocol));
345  case PUNT_TYPE_EXCEPTION:
347  }
348 
349  return 0;
350 }
351 
352 /**
353  * @brief Request IP L4 traffic punt to the local TCP/IP stack.
354  *
355  * @em Note
356  * - UDP is the only protocol supported in the current implementation
357  *
358  * @param vm vlib_main_t corresponding to the current thread
359  * @param af IP address family.
360  * @param protocol 8-bits L4 protocol value
361  * UDP is 17
362  * TCP is 1
363  * @param port 16-bits L4 (TCP/IP) port number when applicable (UDP only)
364  *
365  * @returns 0 on success, non-zero value otherwise
366  */
367 static clib_error_t *
370  ip_protocol_t protocol, u16 port, bool is_add)
371 {
372  /* For now we only support TCP and UDP punt */
373  if (protocol != IP_PROTOCOL_UDP && protocol != IP_PROTOCOL_TCP)
374  return clib_error_return (0,
375  "only UDP (%d) and TCP (%d) protocols are supported, got %d",
376  IP_PROTOCOL_UDP, IP_PROTOCOL_TCP, protocol);
377 
378  if (port == (u16) ~ 0)
379  {
380  if (protocol == IP_PROTOCOL_UDP)
381  udp_punt_unknown (vm, af == AF_IP4, is_add);
382  else if (protocol == IP_PROTOCOL_TCP)
383  tcp_punt_unknown (vm, af == AF_IP4, is_add);
384 
385  return 0;
386  }
387 
388  else if (is_add)
389  {
390  if (protocol == IP_PROTOCOL_TCP)
391  return clib_error_return (0, "punt TCP ports is not supported yet");
392 
394 
395  return 0;
396  }
397  else
398  {
399  if (protocol == IP_PROTOCOL_TCP)
400  return clib_error_return (0, "punt TCP ports is not supported yet");
401 
403 
404  return 0;
405  }
406 }
407 
408 /**
409  * @brief Request exception traffic punt.
410  *
411  * @param reason Punting reason
412  *
413  * @returns 0 on success, non-zero value otherwise
414  */
415 static clib_error_t *
417 {
418  punt_main_t *pm = &punt_main;
419  int rv = 0;
421  const char *node_name =
422  vnet_punt_reason_flag_is_IP6_PACKET (flag) ? "ip6-punt" : "ip4-punt";
423  if (is_add)
424  rv = vlib_punt_register (pm->hdl, reason, node_name);
425  else
426  rv = vlib_punt_unregister (pm->hdl, reason, node_name);
427  if (!rv)
428  return 0;
429  else
430  return clib_error_return (0, is_add ? "Existing punting registration..." :
431  "Punting registration not found...");
432 }
433 
434 clib_error_t *
435 vnet_punt_add_del (vlib_main_t * vm, const punt_reg_t * pr, bool is_add)
436 {
437  switch (pr->type)
438  {
439  case PUNT_TYPE_L4:
440  return (punt_l4_add_del (vm, pr->punt.l4.af, pr->punt.l4.protocol,
441  pr->punt.l4.port, is_add));
442  case PUNT_TYPE_EXCEPTION:
443  return punt_exception_add_del (pr->punt.exception.reason, is_add);
444  case PUNT_TYPE_IP_PROTO:
445  break;
446  }
447 
448  return (clib_error_return (0, "Unsupported punt type: %d", pr->type));
449 }
450 
451 static clib_error_t *
453  unformat_input_t * input__, vlib_cli_command_t * cmd)
454 {
455  unformat_input_t line_input, *input = &line_input;
456  clib_error_t *error = NULL;
457  bool is_add = true;
458  /* *INDENT-OFF* */
459  punt_reg_t pr = {
460  .punt = {
461  .l4 = {
462  .af = AF_IP4,
463  .port = ~0,
464  .protocol = IP_PROTOCOL_UDP,
465  },
466  },
467  .type = PUNT_TYPE_L4,
468  };
469  u32 port;
470  /* *INDENT-ON* */
471 
472  if (!unformat_user (input__, unformat_line_input, input))
473  return 0;
474 
476  {
477  if (unformat (input, "del"))
478  is_add = false;
479  else if (unformat (input, "reason %U", unformat_punt_reason,
480  &pr.punt.exception.reason))
481  pr.type = PUNT_TYPE_EXCEPTION;
482  else if (unformat (input, "ipv4"))
483  pr.punt.l4.af = AF_IP4;
484  else if (unformat (input, "ipv6"))
485  pr.punt.l4.af = AF_IP6;
486  else if (unformat (input, "ip6"))
487  pr.punt.l4.af = AF_IP6;
488  else if (unformat (input, "%d", &port))
489  pr.punt.l4.port = port;
490  else if (unformat (input, "all"))
491  pr.punt.l4.port = ~0;
492  else if (unformat (input, "udp"))
493  pr.punt.l4.protocol = IP_PROTOCOL_UDP;
494  else if (unformat (input, "tcp"))
495  pr.punt.l4.protocol = IP_PROTOCOL_TCP;
496  else
497  {
498  error = clib_error_return (0, "parse error: '%U'",
499  format_unformat_error, input);
500  goto done;
501  }
502  }
503 
504  /* punt both IPv6 and IPv4 when used in CLI */
505  error = vnet_punt_add_del (vm, &pr, is_add);
506  if (error)
507  {
509  }
510 
511 done:
512  unformat_free (input);
513  return error;
514 }
515 
516 /*?
517  * The set of '<em>set punt</em>' commands allows specific IP traffic to
518  * be punted to the host TCP/IP stack
519  *
520  * @em Note
521  * - UDP is the only protocol supported in the current implementation
522  * - All TCP traffic is currently punted to the host by default
523  *
524  * @cliexpar
525  * @parblock
526  * Example of how to request NTP traffic to be punted
527  * @cliexcmd{set punt udp 125}
528  *
529  * Example of how to request all 'unknown' UDP traffic to be punted
530  * @cliexcmd{set punt udp all}
531  *
532  * Example of how to stop all 'unknown' UDP traffic to be punted
533  * @cliexcmd{set punt udp del all}
534  * @endparblock
535 ?*/
536 /* *INDENT-OFF* */
538  .path = "set punt",
539  .short_help = "set punt [IPV4|ip6|ipv6] [UDP|tcp] [del] [ALL|<port-num>]",
540  .function = punt_cli,
541 };
542 /* *INDENT-ON* */
543 
544 static clib_error_t *
546  unformat_input_t * input__,
547  vlib_cli_command_t * cmd)
548 {
549  unformat_input_t line_input, *input = &line_input;
550  u8 *socket_name = 0;
551  clib_error_t *error = NULL;
552  /* *INDENT-OFF* */
553  punt_reg_t pr = {
554  .punt = {
555  .l4 = {
556  .af = AF_IP4,
557  .port = ~0,
558  .protocol = IP_PROTOCOL_UDP,
559  },
560  },
561  .type = PUNT_TYPE_L4,
562  };
563  /* *INDENT-ON* */
564 
565  if (!unformat_user (input__, unformat_line_input, input))
566  return 0;
567 
569  {
570  if (unformat (input, "ipv4"))
571  pr.punt.l4.af = AF_IP4;
572  else if (unformat (input, "ipv6"))
573  pr.punt.l4.af = AF_IP6;
574  else if (unformat (input, "udp"))
575  pr.punt.l4.protocol = IP_PROTOCOL_UDP;
576  else if (unformat (input, "tcp"))
577  pr.punt.l4.protocol = IP_PROTOCOL_TCP;
578  else if (unformat (input, "%d", &pr.punt.l4.port))
579  ;
580  else if (unformat (input, "all"))
581  pr.punt.l4.port = ~0;
582  else if (unformat (input, "socket %s", &socket_name))
583  ;
584  else if (unformat (input, "reason %U", unformat_punt_reason,
585  &pr.punt.exception.reason))
586  pr.type = PUNT_TYPE_EXCEPTION;
587  else
588  {
589  error = clib_error_return (0, "parse error: '%U'",
590  format_unformat_error, input);
591  goto done;
592  }
593  }
594 
595  if (!socket_name)
596  error = clib_error_return (0, "socket name not specified");
597  else
598  error = vnet_punt_socket_add (vm, 1, &pr, (char *) socket_name);
599 
600 done:
601  unformat_free (input);
602  return error;
603 }
604 
605 /*?
606  *
607  * @cliexpar
608  * @cliexcmd{punt socket register socket punt_l4_foo.sock}
609 
610  ?*/
611 /* *INDENT-OFF* */
613 {
614  .path = "punt socket register",
615  .function = punt_socket_register_cmd,
616  .short_help = "punt socket register [IPV4|ipv6] [UDP|tcp] [ALL|<port-num>] socket <socket>",
617  .is_mp_safe = 1,
618 };
619 /* *INDENT-ON* */
620 
621 static clib_error_t *
623  unformat_input_t * input__,
624  vlib_cli_command_t * cmd)
625 {
626  unformat_input_t line_input, *input = &line_input;
627  clib_error_t *error = NULL;
628  /* *INDENT-OFF* */
629  punt_reg_t pr = {
630  .punt = {
631  .l4 = {
632  .af = AF_IP4,
633  .port = ~0,
634  .protocol = IP_PROTOCOL_UDP,
635  },
636  },
637  .type = PUNT_TYPE_L4,
638  };
639  /* *INDENT-ON* */
640 
641  if (!unformat_user (input__, unformat_line_input, input))
642  return 0;
643 
645  {
646  if (unformat (input, "ipv4"))
647  pr.punt.l4.af = AF_IP4;
648  else if (unformat (input, "ipv6"))
649  pr.punt.l4.af = AF_IP6;
650  else if (unformat (input, "udp"))
651  pr.punt.l4.protocol = IP_PROTOCOL_UDP;
652  else if (unformat (input, "tcp"))
653  pr.punt.l4.protocol = IP_PROTOCOL_TCP;
654  else if (unformat (input, "%d", &pr.punt.l4.port))
655  ;
656  else if (unformat (input, "all"))
657  pr.punt.l4.port = ~0;
658  else if (unformat (input, "reason %U", unformat_punt_reason,
659  &pr.punt.exception.reason))
660  pr.type = PUNT_TYPE_EXCEPTION;
661  else
662  {
663  error = clib_error_return (0, "parse error: '%U'",
664  format_unformat_error, input);
665  goto done;
666  }
667  }
668 
669  error = vnet_punt_socket_del (vm, &pr);
670 done:
671  unformat_free (input);
672  return error;
673 }
674 
675 /*?
676  *
677  * @cliexpar
678  * @cliexcmd{punt socket register}
679  ?*/
680 /* *INDENT-OFF* */
682 {
683  .path = "punt socket deregister",
684  .function = punt_socket_deregister_cmd,
685  .short_help = "punt socket deregister [IPV4|ipv6] [UDP|tcp] [ALL|<port-num>]",
686  .is_mp_safe = 1,
687 };
688 /* *INDENT-ON* */
689 
690 void
692 {
693  punt_main_t *pm = &punt_main;
694 
695  switch (pt)
696  {
697  case PUNT_TYPE_L4:
698  {
699  u32 pci, key;
700 
701  /* *INDENT-OFF* */
703  ({
704  cb (pool_elt_at_index(pm->punt_client_pool, pci), ctx);
705  }));
706  /* *INDENT-ON* */
707  break;
708  }
709  case PUNT_TYPE_IP_PROTO:
710  {
711  u32 pci, key;
712 
713  /* *INDENT-OFF* */
715  ({
716  cb (pool_elt_at_index(pm->punt_client_pool, pci), ctx);
717  }));
718  /* *INDENT-ON* */
719  break;
720  }
721  case PUNT_TYPE_EXCEPTION:
722  {
723  u32 *pci;
724 
726  {
727  if (~0 != *pci)
728  cb (pool_elt_at_index (pm->punt_client_pool, *pci), ctx);
729  }
730 
731  break;
732  }
733  }
734 }
735 
736 static u8 *
737 format_punt_client (u8 * s, va_list * args)
738 {
739  punt_client_t *pc = va_arg (*args, punt_client_t *);
740 
741  s = format (s, " punt ");
742 
743  switch (pc->reg.type)
744  {
745  case PUNT_TYPE_L4:
746  s = format (s, "%U %U port %d",
749  pc->reg.punt.l4.port);
750  break;
751  case PUNT_TYPE_IP_PROTO:
752  s = format (s, "%U %U",
755  break;
756  case PUNT_TYPE_EXCEPTION:
757  s = format (s, " %U", format_vlib_punt_reason,
758  pc->reg.punt.exception.reason);
759  break;
760  }
761 
762  s = format (s, " to socket %s \n", pc->caddr.sun_path);
763 
764  return (s);
765 }
766 
767 static walk_rc_t
769 {
771 
772  return (WALK_CONTINUE);
773 }
774 
775 static clib_error_t *
777  unformat_input_t * input__, vlib_cli_command_t * cmd)
778 {
779  unformat_input_t line_input, *input = &line_input;
780  clib_error_t *error = NULL;
781  punt_type_t pt;
782 
783  pt = PUNT_TYPE_L4;
784 
785  if (!unformat_user (input__, unformat_line_input, input))
786  return 0;
787 
789  {
790  if (unformat (input, "exception"))
791  pt = PUNT_TYPE_EXCEPTION;
792  else if (unformat (input, "l4"))
793  pt = PUNT_TYPE_L4;
794  else if (unformat (input, "ip"))
795  pt = PUNT_TYPE_IP_PROTO;
796  else
797  {
798  error = clib_error_return (0, "parse error: '%U'",
799  format_unformat_error, input);
800  goto done;
801  }
802  }
803 
805 
806 done:
807  unformat_free (input);
808  return (error);
809 }
810 
811 /*?
812  *
813  * @cliexpar
814  * @cliexcmd{show punt socket ipv4}
815  ?*/
816 /* *INDENT-OFF* */
818 {
819  .path = "show punt socket registrations",
820  .function = punt_socket_show_cmd,
821  .short_help = "show punt socket registrations [l4|exception]",
822  .is_mp_safe = 1,
823 };
824 /* *INDENT-ON* */
825 
826 clib_error_t *
828 {
829  clib_error_t *error = NULL;
830  punt_main_t *pm = &punt_main;
832 
833  pm->is_configured = false;
835  vlib_get_node_by_name (vm, (u8 *) "interface-output");
836 
838  return error;
839 
840  pm->hdl = vlib_punt_client_register ("ip-punt");
841 
844 
845  return (error);
846 }
847 
848 u8 *
850 {
851  vnet_punt_reason_flag_t flag = va_arg (*args, int);
852 #define _(pos, len, value, name, str) \
853  if (vnet_punt_reason_flag_is_##name (flag)) \
854  s = format (s, "%s ", str);
855 
857 #undef _
858  return (s);
859 }
860 
862 
863 static clib_error_t *
865 {
866  punt_main_t *pm = &punt_main;
867  char *socket_path = 0;
868 
870  {
871  if (unformat (input, "socket %s", &socket_path))
872  strncpy (pm->sun_path, socket_path, UNIX_PATH_MAX - 1);
873  else
874  return clib_error_return (0, "unknown input `%U'",
875  format_unformat_error, input);
876  }
877 
878  if (socket_path == 0)
879  return 0;
880 
881  /* UNIX domain socket */
882  struct sockaddr_un addr;
883  if ((pm->socket_fd = socket (AF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK, 0)) == -1)
884  {
885  return clib_error_return (0, "socket error");
886  }
887 
888  clib_memset (&addr, 0, sizeof (addr));
889  addr.sun_family = AF_UNIX;
890  if (*socket_path == '\0')
891  {
892  *addr.sun_path = '\0';
893  strncpy (addr.sun_path + 1, socket_path + 1,
894  sizeof (addr.sun_path) - 2);
895  }
896  else
897  {
898  strncpy (addr.sun_path, socket_path, sizeof (addr.sun_path) - 1);
899  unlink (socket_path);
900  }
901 
902  if (bind (pm->socket_fd, (struct sockaddr *) &addr, sizeof (addr)) == -1)
903  {
904  return clib_error_return (0, "bind error");
905  }
906 
907  int n_bytes = 0x10000;
908 
909  if (setsockopt
910  (pm->socket_fd, SOL_SOCKET, SO_SNDBUF, &n_bytes,
911  sizeof (n_bytes)) == -1)
912  {
913  return clib_error_return (0, "setsockopt error");
914  }
915 
916  /* Register socket */
918  clib_file_t template = { 0 };
920  template.file_descriptor = pm->socket_fd;
921  template.description = format (0, "punt socket %s", socket_path);
922  pm->clib_file_index = clib_file_add (fm, &template);
923 
924  pm->is_configured = true;
925 
926  return 0;
927 }
928 
930 
931 /*
932  * fd.io coding-style-patch-verification: ON
933  *
934  * Local Variables:
935  * eval: (c-set-style "gnu")
936  * End:
937  */
punt_socket_register_ip_proto
static clib_error_t * punt_socket_register_ip_proto(vlib_main_t *vm, ip_address_family_t af, ip_protocol_t proto, char *client_pathname)
Definition: punt.c:185
vlib.h
vlib_punt_reason_t
enum vlib_punt_reason_t_ vlib_punt_reason_t
The 'syatem' defined punt reasons.
clib_file::file_descriptor
u32 file_descriptor
Definition: file.h:54
udp_punt_unknown
void udp_punt_unknown(vlib_main_t *vm, u8 is_ip4, u8 is_add)
Definition: udp_local.c:545
ip4_unregister_protocol
void ip4_unregister_protocol(u32 protocolx)
Definition: ip4_forward.c:1907
file_main
clib_file_main_t file_main
Definition: main.c:63
unformat_user
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:989
punt_client_t
Definition: punt.h:133
punt_command
static vlib_cli_command_t punt_command
(constructor) VLIB_CLI_COMMAND (punt_command)
Definition: punt.c:537
punt_exception_add_del
static clib_error_t * punt_exception_add_del(vlib_punt_reason_t reason, bool is_add)
Request exception traffic punt.
Definition: punt.c:416
WALK_CONTINUE
@ WALK_CONTINUE
Definition: interface_funcs.h:174
udp4_punt_node
vlib_node_registration_t udp4_punt_node
(constructor) VLIB_REGISTER_NODE (udp4_punt_node)
Definition: punt_node.c:186
format_vnet_punt_reason_flags
u8 * format_vnet_punt_reason_flags(u8 *s, va_list *args)
Definition: punt.c:849
punt_socket_unregister_exception
static clib_error_t * punt_socket_unregister_exception(vlib_punt_reason_t reason)
Definition: punt.c:276
punt_reg_t_
A registration, by a client, to direct punted traffic to a given node.
Definition: punt.h:96
punt_socket_register_command
static vlib_cli_command_t punt_socket_register_command
(constructor) VLIB_CLI_COMMAND (punt_socket_register_command)
Definition: punt.c:612
punt_main_t::punt_client_pool
punt_client_t * punt_client_pool
Definition: punt.h:156
punt_client_ip_proto_db_remove
static u32 punt_client_ip_proto_db_remove(ip_address_family_t af, ip_protocol_t proto)
Definition: punt.c:88
unformat_line_input
unformat_function_t unformat_line_input
Definition: format.h:275
pool_elt_at_index
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:553
punt_main_t::interface_output_node
vlib_node_t * interface_output_node
Definition: punt.h:159
punt_l4_t_::af
ip_address_family_t af
Definition: punt.h:73
clib_error_return
#define clib_error_return(e, args...)
Definition: error.h:99
punt_ip_proto_t_::protocol
ip_protocol_t protocol
Definition: punt.h:81
vlib_cli_command_t::path
char * path
Definition: cli.h:96
clib_file::read_function
clib_file_function_t * read_function
Definition: file.h:67
punt_client_exception_db_add
static void punt_client_exception_db_add(vlib_punt_reason_t reason, u32 pci)
Definition: punt.c:106
punt_main_t::clib_file_index
u32 clib_file_index
Definition: punt.h:157
punt_socket_register_exception
static clib_error_t * punt_socket_register_exception(vlib_main_t *vm, vlib_punt_reason_t reason, char *client_pathname)
Definition: punt.c:215
u16
unsigned short u16
Definition: types.h:57
vlib_call_init_function
#define vlib_call_init_function(vm, x)
Definition: init.h:259
punt_init
static clib_error_t * punt_init(vlib_main_t *vm)
Definition: punt.c:712
punt_client_exception_get
static_always_inline punt_client_t * punt_client_exception_get(vlib_punt_reason_t reason)
Definition: punt.h:221
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
AF_IP4
@ AF_IP4
Definition: ip_types.h:23
punt_socket_unregister_ip_proto
static clib_error_t * punt_socket_unregister_ip_proto(ip_address_family_t af, ip_protocol_t proto)
Definition: punt.c:258
fm
vnet_feature_main_t * fm
Definition: nat44_ei_hairpinning.c:589
node_index
node node_index
Definition: interface_output.c:420
port
u16 port
Definition: lb_types.api:73
punt_client_db_t_::clients_by_ip_proto
void * clients_by_ip_proto
Definition: punt.h:143
ip4_register_protocol
void ip4_register_protocol(u32 protocol, u32 node_index)
Definition: ip4_forward.c:1895
vlib_punt_reason_get_flags
u32 vlib_punt_reason_get_flags(vlib_punt_reason_t pr)
Definition: punt.c:419
clib_file_main_t
Definition: file.h:85
vlib_punt_register
int vlib_punt_register(vlib_punt_hdl_t client, vlib_punt_reason_t reason, const char *node_name)
Register a node to receive particular punted buffers.
Definition: punt.c:283
punt_client_l4_db_remove
static u32 punt_client_l4_db_remove(ip_address_family_t af, u16 port)
Definition: punt.c:58
clib_error_report
#define clib_error_report(e)
Definition: error.h:113
unformat_input_t
struct _unformat_input_t unformat_input_t
punt_socket_register_l4
static clib_error_t * punt_socket_register_l4(vlib_main_t *vm, ip_address_family_t af, u8 protocol, u16 port, char *client_pathname)
Definition: punt.c:144
punt_client_l4_mk_key
static_always_inline u32 punt_client_l4_mk_key(ip_address_family_t af, u16 port)
Definition: punt.h:179
addr
vhost_vring_addr_t addr
Definition: vhost_user.h:130
vnet_punt_get_server_pathname
char * vnet_punt_get_server_pathname(void)
Definition: punt.c:41
pool_put_index
#define pool_put_index(p, i)
Free pool element with given index.
Definition: pool.h:337
ip_punt_init
clib_error_t * ip_punt_init(vlib_main_t *vm)
Definition: punt.c:827
error
Definition: cJSON.c:88
punt_client_ip_proto_get
static_always_inline punt_client_t * punt_client_ip_proto_get(ip_address_family_t af, ip_protocol_t proto)
Definition: punt.h:205
punt_client_db_t_::clients_by_exception
u32 * clients_by_exception
Definition: punt.h:142
punt_main_t
Definition: punt.h:151
punt_client_l4_db_add
static void punt_client_l4_db_add(ip_address_family_t af, u16 port, u32 index)
Definition: punt.c:48
key
typedef key
Definition: ipsec_types.api:88
show_punt_socket_registration_command
static vlib_cli_command_t show_punt_socket_registration_command
(constructor) VLIB_CLI_COMMAND (show_punt_socket_registration_command)
Definition: punt.c:817
VLIB_CONFIG_FUNCTION
#define VLIB_CONFIG_FUNCTION(x, n,...)
Definition: init.h:181
unformat
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
punt_client_l4_get
static_always_inline punt_client_t * punt_client_l4_get(ip_address_family_t af, u16 port)
Definition: punt.h:185
hash_set
#define hash_set(h, key, value)
Definition: hash.h:255
format_vlib_punt_reason
u8 * format_vlib_punt_reason(u8 *s, va_list *args)
Format a punt reason.
Definition: punt.c:158
punt_config
static clib_error_t * punt_config(vlib_main_t *vm, unformat_input_t *input)
Definition: punt.c:864
vlib_thread_main_t::n_vlib_mains
u32 n_vlib_mains
Definition: threads.h:283
format_punt_client
static u8 * format_punt_client(u8 *s, va_list *args)
Definition: punt.c:737
unformat_free
static void unformat_free(unformat_input_t *i)
Definition: format.h:155
vec_add1
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:606
format_ip_address_family
u8 * format_ip_address_family(u8 *s, va_list *args)
Definition: ip.c:215
punt_union_t_::ip_proto
punt_ip_proto_t ip_proto
Definition: punt.h:93
punt_socket_read_ready
static clib_error_t * punt_socket_read_ready(clib_file_t *uf)
Definition: punt.c:131
punt_union_t_::exception
punt_exception_t exception
Definition: punt.h:91
punt_client_exception_db_remove
static u32 punt_client_exception_db_remove(vlib_punt_reason_t reason)
Definition: punt.c:116
punt_client_db_t_::clients_by_l4_port
void * clients_by_l4_port
Definition: punt.h:141
udp4_punt_socket_node
vlib_node_registration_t udp4_punt_socket_node
(constructor) VLIB_REGISTER_NODE (udp4_punt_socket_node)
Definition: punt_node.c:439
clib_file
Definition: file.h:51
punt_client_t::reg
punt_reg_t reg
Definition: punt.h:135
unformat_check_input
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:163
vlib_config_function_runtime_t
Definition: init.h:68
vec_validate_aligned
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
Definition: vec.h:534
punt_ip_proto_t_::af
ip_address_family_t af
Definition: punt.h:80
c
svmdb_client_t * c
Definition: vpp_get_metrics.c:48
punt_client_walk_cb_t
walk_rc_t(* punt_client_walk_cb_t)(const punt_client_t *pc, void *ctx)
Definition: punt.h:168
uword
u64 uword
Definition: types.h:112
format_ip_protocol
format_function_t format_ip_protocol
Definition: format.h:45
hash_get
#define hash_get(h, key)
Definition: hash.h:249
hash_foreach
#define hash_foreach(key_var, value_var, h, body)
Definition: hash.h:441
punt_client_walk
void punt_client_walk(punt_type_t pt, punt_client_walk_cb_t cb, void *ctx)
Definition: punt.c:691
udp_register_dst_port
void udp_register_dst_port(vlib_main_t *vm, udp_dst_port_t dst_port, u32 node_index, u8 is_ip4)
Definition: udp_local.c:468
udp_unregister_dst_port
void udp_unregister_dst_port(vlib_main_t *vm, udp_dst_port_t dst_port, u8 is_ip4)
Definition: udp_local.c:506
format_unformat_error
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
punt_main_t::db
punt_client_db_t db
Definition: punt.h:155
vnet_punt_socket_del
clib_error_t * vnet_punt_socket_del(vlib_main_t *vm, const punt_reg_t *pr)
Definition: punt.c:329
vlib_punt_unregister
int vlib_punt_unregister(vlib_punt_hdl_t client, vlib_punt_reason_t reason, const char *node_name)
Definition: punt.c:352
VLIB_CLI_COMMAND
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:163
punt_l4_t_::port
u16 port
Definition: punt.h:75
tcp_punt_unknown
void tcp_punt_unknown(vlib_main_t *vm, u8 is_ip4, u8 is_add)
Definition: tcp.c:1556
foreach_vnet_punt_reason_flag
@ foreach_vnet_punt_reason_flag
Definition: punt.h:38
punt_main_t::ready_fds
u32 * ready_fds
Definition: punt.h:160
punt_reg_t_::punt
punt_union_t punt
Definition: punt.h:99
CLIB_CACHE_LINE_BYTES
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
vlib_cli_output
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:716
punt_socket_rx_node
vlib_node_registration_t punt_socket_rx_node
(constructor) VLIB_REGISTER_NODE (punt_socket_rx_node)
Definition: punt_node.c:618
punt_client_ip_proto_mk_key
static_always_inline u32 punt_client_ip_proto_mk_key(ip_address_family_t af, ip_protocol_t proto)
Definition: punt.h:199
punt_socket_unregister_l4
static clib_error_t * punt_socket_unregister_l4(ip_address_family_t af, ip_protocol_t protocol, u16 port)
Definition: punt.c:242
punt_socket_deregister_cmd
static clib_error_t * punt_socket_deregister_cmd(vlib_main_t *vm, unformat_input_t *input__, vlib_cli_command_t *cmd)
Definition: punt.c:622
punt_client_ip_proto_db_add
static void punt_client_ip_proto_db_add(ip_address_family_t af, ip_protocol_t proto, u32 index)
Definition: punt.c:76
punt_client_t::caddr
struct sockaddr_un caddr
Definition: punt.h:136
index
u32 index
Definition: flow_types.api:221
vlib_get_node_by_name
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
Definition: node.c:45
punt.h
Definitions for punt infrastructure.
vnet_punt_add_del
clib_error_t * vnet_punt_add_del(vlib_main_t *vm, const punt_reg_t *pr, bool is_add)
Definition: punt.c:435
unformat_punt_reason
uword unformat_punt_reason(unformat_input_t *input, va_list *args)
Unformat a punt reason.
Definition: punt.c:479
format
description fragment has unexpected format
Definition: map.api:433
ip6_unregister_protocol
void ip6_unregister_protocol(u32 protocol)
Definition: ip6_forward.c:1691
vec_validate_init_empty
#define vec_validate_init_empty(V, I, INIT)
Make sure vector is long enough for given index and initialize empty space (no header,...
Definition: vec.h:570
ip.h
punt_l4_t_::protocol
ip_protocol_t protocol
Definition: punt.h:74
u32
unsigned int u32
Definition: types.h:88
punt_l4_add_del
static clib_error_t * punt_l4_add_del(vlib_main_t *vm, ip_address_family_t af, ip_protocol_t protocol, u16 port, bool is_add)
Request IP L4 traffic punt to the local TCP/IP stack.
Definition: punt.c:368
VLIB_INIT_FUNCTION
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:172
tcp.h
vlib_thread_main_t
Definition: threads.h:264
protocol
vl_api_ip_proto_t protocol
Definition: lb_types.api:72
vlib_node_set_interrupt_pending
static void vlib_node_set_interrupt_pending(vlib_main_t *vm, u32 node_index)
Definition: node_funcs.h:249
punt_cli
static clib_error_t * punt_cli(vlib_main_t *vm, unformat_input_t *input__, vlib_cli_command_t *cmd)
Definition: punt.c:452
n_bytes
u32 n_bytes
Definition: interface_output.c:401
punt_main_t::sun_path
char sun_path[sizeof(struct sockaddr_un)]
Definition: punt.h:154
ctx
long ctx[MAX_CONNS]
Definition: main.c:144
ip6_proto_punt_socket_node
vlib_node_registration_t ip6_proto_punt_socket_node
(constructor) VLIB_REGISTER_NODE (ip6_proto_punt_socket_node)
Definition: punt_node.c:468
udp6_punt_socket_node
vlib_node_registration_t udp6_punt_socket_node
(constructor) VLIB_REGISTER_NODE (udp6_punt_socket_node)
Definition: punt_node.c:449
vec_foreach
#define vec_foreach(var, vec)
Vector iterator.
Definition: vec_bootstrap.h:213
PUNT_PACKETDESC_VERSION
#define PUNT_PACKETDESC_VERSION
Definition: punt.h:123
punt_exception_t_::reason
vlib_punt_reason_t reason
Definition: punt.h:86
AF_IP6
@ AF_IP6
Definition: ip_types.h:24
udp.h
clib_file_add
static uword clib_file_add(clib_file_main_t *um, clib_file_t *template)
Definition: file.h:96
punt_type_t
enum punt_type_t_ punt_type_t
punt_socket_register_cmd
static clib_error_t * punt_socket_register_cmd(vlib_main_t *vm, unformat_input_t *input__, vlib_cli_command_t *cmd)
Definition: punt.c:545
hash_unset
#define hash_unset(h, key)
Definition: hash.h:261
ip_protocol_t
enum ip_protocol ip_protocol_t
vnet_punt_socket_add
clib_error_t * vnet_punt_socket_add(vlib_main_t *vm, u32 header_version, const punt_reg_t *pr, char *client_pathname)
Definition: punt.c:289
clib_memset
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
vlib_main_t
Definition: main.h:102
punt_main_t::socket_fd
int socket_fd
Definition: punt.h:153
vlib_get_main
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:38
pool_get_zero
#define pool_get_zero(P, E)
Allocate an object E from a pool P and zero it.
Definition: pool.h:258
u8
unsigned char u8
Definition: types.h:56
clib_error_t
Definition: clib_error.h:21
unix.h
vlib_init_function_t
clib_error_t *() vlib_init_function_t(struct vlib_main_t *vm)
Definition: init.h:51
ip6_register_protocol
void ip6_register_protocol(u32 protocol, u32 node_index)
Definition: ip6_forward.c:1679
punt_union_t_::l4
punt_l4_t l4
Definition: punt.h:92
rv
int __clib_unused rv
Definition: application.c:491
punt_main_t::thread_data
punt_thread_data_t * thread_data
Definition: punt.h:162
proto
vl_api_ip_proto_t proto
Definition: acl_types.api:51
punt_client_show_one
static walk_rc_t punt_client_show_one(const punt_client_t *pc, void *ctx)
Definition: punt.c:768
vlib_cli_command_t
Definition: cli.h:92
vlib_punt_client_register
vlib_punt_hdl_t vlib_punt_client_register(const char *who)
Register a new clinet.
Definition: punt.c:171
vnet_punt_reason_flag_t
enum vnet_punt_reason_flag_t_ vnet_punt_reason_flag_t
vlib_get_thread_main
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:56
punt_socket_deregister_command
static vlib_cli_command_t punt_socket_deregister_command
(constructor) VLIB_CLI_COMMAND (punt_socket_deregister_command)
Definition: punt.c:681
punt_reg_t_::type
punt_type_t type
Definition: punt.h:98
punt_main_t::is_configured
bool is_configured
Definition: punt.h:158
punt_main_t::hdl
vlib_punt_hdl_t hdl
Definition: punt.h:163
punt_main
punt_main_t punt_main
Definition: punt.c:38
walk_rc_t
enum walk_rc_t_ walk_rc_t
Walk return code.
punt_socket_show_cmd
static clib_error_t * punt_socket_show_cmd(vlib_main_t *vm, unformat_input_t *input__, vlib_cli_command_t *cmd)
Definition: punt.c:776
UNFORMAT_END_OF_INPUT
#define UNFORMAT_END_OF_INPUT
Definition: format.h:137
ip4_proto_punt_socket_node
vlib_node_registration_t ip4_proto_punt_socket_node
(constructor) VLIB_REGISTER_NODE (ip4_proto_punt_socket_node)
Definition: punt_node.c:458
ip_address_family_t
enum ip_address_family_t_ ip_address_family_t