FD.io VPP  v20.05-21-gb1500e9ff
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/pg/pg.h>
28 #include <vnet/udp/udp.h>
29 #include <vnet/tcp/tcp.h>
30 #include <vnet/ip/punt.h>
31 #include <vlib/unix/unix.h>
32 
33 #include <stdio.h>
34 #include <unistd.h>
35 #include <sys/socket.h>
36 #include <sys/uio.h>
37 #include <stdlib.h>
38 
40 
41 char *
43 {
44  punt_main_t *pm = &punt_main;
45  return pm->sun_path;
46 }
47 
48 static void
50 {
51  punt_main_t *pm = &punt_main;
52 
54  punt_client_l4_mk_key (af, port),
55  index);
56 }
57 
58 static u32
60 {
61  punt_main_t *pm = &punt_main;
62  u32 key, index = ~0;
63  uword *p;
64 
65  key = punt_client_l4_mk_key (af, port);
66  p = hash_get (pm->db.clients_by_l4_port, key);
67 
68  if (p)
69  index = p[0];
70 
71  hash_unset (pm->db.clients_by_l4_port, key);
72 
73  return (index);
74 }
75 
76 static void
78  ip_protocol_t proto, u32 index)
79 {
80  punt_main_t *pm = &punt_main;
81 
84  proto),
85  index);
86 }
87 
88 static u32
90 {
91  punt_main_t *pm = &punt_main;
92  u32 key, index = ~0;
93  uword *p;
94 
95  key = punt_client_ip_proto_mk_key (af, proto);
96  p = hash_get (pm->db.clients_by_ip_proto, key);
97 
98  if (p)
99  index = p[0];
100 
101  hash_unset (pm->db.clients_by_ip_proto, key);
102 
103  return (index);
104 }
105 
106 static void
108 {
109  punt_main_t *pm = &punt_main;
110 
112 
113  pm->db.clients_by_exception[reason] = pci;
114 }
115 
116 static u32
118 {
119  punt_main_t *pm = &punt_main;
120  u32 pci = ~0;
121 
122  if (punt_client_exception_get (reason))
123  {
124  pci = pm->db.clients_by_exception[reason];
125  pm->db.clients_by_exception[reason] = ~0;
126  }
127 
128  return pci;
129 }
130 
131 static clib_error_t *
133 {
135  punt_main_t *pm = &punt_main;
136 
137  /** Schedule the rx node */
140 
141  return 0;
142 }
143 
144 static clib_error_t *
147  u8 protocol, u16 port, char *client_pathname)
148 {
149  punt_main_t *pm = &punt_main;
150  punt_client_t *c;
151 
152  /* For now we only support UDP punt */
153  if (protocol != IP_PROTOCOL_UDP)
154  return clib_error_return (0,
155  "only UDP protocol (%d) is supported, got %d",
156  IP_PROTOCOL_UDP, protocol);
157 
158  if (port == (u16) ~ 0)
159  return clib_error_return (0, "UDP port number required");
160 
161  c = punt_client_l4_get (af, port);
162 
163  if (NULL == c)
164  {
166  punt_client_l4_db_add (af, port, c - pm->punt_client_pool);
167  }
168 
169  memcpy (c->caddr.sun_path, client_pathname, sizeof (c->caddr.sun_path));
170  c->caddr.sun_family = AF_UNIX;
171  c->reg.type = PUNT_TYPE_L4;
172  c->reg.punt.l4.port = port;
173  c->reg.punt.l4.protocol = protocol;
174  c->reg.punt.l4.af = af;
175 
176  u32 node_index = (af == AF_IP4 ?
177  udp4_punt_socket_node.index :
178  udp6_punt_socket_node.index);
179 
180  udp_register_dst_port (vm, port, node_index, af == AF_IP4);
181 
182  return (NULL);
183 }
184 
185 static clib_error_t *
188  ip_protocol_t proto, char *client_pathname)
189 {
190  punt_main_t *pm = &punt_main;
191  punt_client_t *c;
192 
193  c = punt_client_ip_proto_get (af, proto);
194 
195  if (NULL == c)
196  {
198  punt_client_ip_proto_db_add (af, proto, c - pm->punt_client_pool);
199  }
200 
201  memcpy (c->caddr.sun_path, client_pathname, sizeof (c->caddr.sun_path));
202  c->caddr.sun_family = AF_UNIX;
203  c->reg.type = PUNT_TYPE_IP_PROTO;
205  c->reg.punt.ip_proto.af = af;
206 
207  if (af == AF_IP4)
209  else
211 
212  return (NULL);
213 }
214 
215 static clib_error_t *
217  vlib_punt_reason_t reason,
218  char *client_pathname)
219 {
220  punt_main_t *pm = &punt_main;
221  punt_client_t *pc;
222 
223  pc = punt_client_exception_get (reason);
224 
225  if (NULL == pc)
226  {
229  }
230 
231  memcpy (pc->caddr.sun_path, client_pathname, sizeof (pc->caddr.sun_path));
232  pc->caddr.sun_family = AF_UNIX;
233  pc->reg.type = PUNT_TYPE_EXCEPTION;
234  pc->reg.punt.exception.reason = reason;
235 
236  vlib_punt_register (pm->hdl,
237  pc->reg.punt.exception.reason, "exception-punt-socket");
238 
239  return (NULL);
240 }
241 
242 static clib_error_t *
245 {
246  u32 pci;
247 
248  udp_unregister_dst_port (vlib_get_main (), port, af == AF_IP4);
249 
250  pci = punt_client_l4_db_remove (af, port);
251 
252  if (~0 != pci)
253  pool_put_index (punt_main.punt_client_pool, pci);
254 
255  return (NULL);
256 }
257 
258 static clib_error_t *
260 {
261  u32 pci;
262 
263  if (af == AF_IP4)
264  ip4_unregister_protocol (proto);
265  else
266  ip6_unregister_protocol (proto);
267 
268  pci = punt_client_ip_proto_db_remove (af, proto);
269 
270  if (~0 != pci)
271  pool_put_index (punt_main.punt_client_pool, pci);
272 
273  return (NULL);
274 }
275 
276 static clib_error_t *
278 {
279  u32 pci;
280 
281  pci = punt_client_exception_db_remove (reason);
282 
283  if (~0 != pci)
284  pool_put_index (punt_main.punt_client_pool, pci);
285 
286  return (NULL);
287 }
288 
289 clib_error_t *
291  const punt_reg_t * pr, char *client_pathname)
292 {
293  punt_main_t *pm = &punt_main;
294 
295  if (!pm->is_configured)
296  return clib_error_return (0, "socket is not configured");
297 
298  if (header_version != PUNT_PACKETDESC_VERSION)
299  return clib_error_return (0, "Invalid packet descriptor version");
300 
301  if (strncmp (client_pathname, vnet_punt_get_server_pathname (),
302  UNIX_PATH_MAX) == 0)
303  return clib_error_return (0,
304  "Punt socket: Invalid client path: %s",
305  client_pathname);
306 
307  /* Register client */
308  switch (pr->type)
309  {
310  case PUNT_TYPE_L4:
311  return (punt_socket_register_l4 (vm,
312  pr->punt.l4.af,
313  pr->punt.l4.protocol,
314  pr->punt.l4.port, client_pathname));
315  case PUNT_TYPE_IP_PROTO:
316  return (punt_socket_register_ip_proto (vm,
317  pr->punt.ip_proto.af,
318  pr->punt.ip_proto.protocol,
319  client_pathname));
320  case PUNT_TYPE_EXCEPTION:
321  return (punt_socket_register_exception (vm,
322  pr->punt.exception.reason,
323  client_pathname));
324  }
325 
326  return 0;
327 }
328 
329 clib_error_t *
331 {
332  punt_main_t *pm = &punt_main;
333 
334  if (!pm->is_configured)
335  return clib_error_return (0, "socket is not configured");
336 
337  switch (pr->type)
338  {
339  case PUNT_TYPE_L4:
340  return (punt_socket_unregister_l4 (pr->punt.l4.af,
341  pr->punt.l4.protocol,
342  pr->punt.l4.port));
343  case PUNT_TYPE_IP_PROTO:
345  pr->punt.ip_proto.protocol));
346  case PUNT_TYPE_EXCEPTION:
348  }
349 
350  return 0;
351 }
352 
353 /**
354  * @brief Request IP L4 traffic punt to the local TCP/IP stack.
355  *
356  * @em Note
357  * - UDP is the only protocol supported in the current implementation
358  *
359  * @param vm vlib_main_t corresponding to the current thread
360  * @param af IP address family.
361  * @param protocol 8-bits L4 protocol value
362  * UDP is 17
363  * TCP is 1
364  * @param port 16-bits L4 (TCP/IP) port number when applicable (UDP only)
365  *
366  * @returns 0 on success, non-zero value otherwise
367  */
368 static clib_error_t *
371  ip_protocol_t protocol, u16 port, bool is_add)
372 {
373  /* For now we only support TCP and UDP punt */
374  if (protocol != IP_PROTOCOL_UDP && protocol != IP_PROTOCOL_TCP)
375  return clib_error_return (0,
376  "only UDP (%d) and TCP (%d) protocols are supported, got %d",
377  IP_PROTOCOL_UDP, IP_PROTOCOL_TCP, protocol);
378 
379  if (port == (u16) ~ 0)
380  {
381  if (protocol == IP_PROTOCOL_UDP)
382  udp_punt_unknown (vm, af == AF_IP4, is_add);
383  else if (protocol == IP_PROTOCOL_TCP)
384  tcp_punt_unknown (vm, af == AF_IP4, is_add);
385 
386  return 0;
387  }
388 
389  else if (is_add)
390  {
391  if (protocol == IP_PROTOCOL_TCP)
392  return clib_error_return (0, "punt TCP ports is not supported yet");
393 
394  udp_register_dst_port (vm, port, udp4_punt_node.index, af == AF_IP4);
395 
396  return 0;
397  }
398  else
399  {
400  if (protocol == IP_PROTOCOL_TCP)
401  return clib_error_return (0, "punt TCP ports is not supported yet");
402 
403  udp_unregister_dst_port (vm, port, af == AF_IP4);
404 
405  return 0;
406  }
407 }
408 
409 clib_error_t *
410 vnet_punt_add_del (vlib_main_t * vm, const punt_reg_t * pr, bool is_add)
411 {
412  switch (pr->type)
413  {
414  case PUNT_TYPE_L4:
415  return (punt_l4_add_del (vm, pr->punt.l4.af, pr->punt.l4.protocol,
416  pr->punt.l4.port, is_add));
417  case PUNT_TYPE_EXCEPTION:
418  case PUNT_TYPE_IP_PROTO:
419  break;
420  }
421 
422  return (clib_error_return (0, "Unsupported punt type: %d", pr->type));
423 }
424 
425 static clib_error_t *
427  unformat_input_t * input, vlib_cli_command_t * cmd)
428 {
429  clib_error_t *error = NULL;
430  bool is_add = true;
431  /* *INDENT-OFF* */
432  punt_reg_t pr = {
433  .punt = {
434  .l4 = {
435  .af = AF_IP4,
436  .port = ~0,
437  .protocol = IP_PROTOCOL_UDP,
438  },
439  },
440  .type = PUNT_TYPE_L4,
441  };
442  u32 port;
443  /* *INDENT-ON* */
444 
446  {
447  if (unformat (input, "del"))
448  is_add = false;
449  else if (unformat (input, "ipv4"))
450  pr.punt.l4.af = AF_IP4;
451  else if (unformat (input, "ipv6"))
452  pr.punt.l4.af = AF_IP6;
453  else if (unformat (input, "ip6"))
454  pr.punt.l4.af = AF_IP6;
455  else if (unformat (input, "%d", &port))
456  pr.punt.l4.port = port;
457  else if (unformat (input, "all"))
458  pr.punt.l4.port = ~0;
459  else if (unformat (input, "udp"))
460  pr.punt.l4.protocol = IP_PROTOCOL_UDP;
461  else if (unformat (input, "tcp"))
462  pr.punt.l4.protocol = IP_PROTOCOL_TCP;
463  else
464  {
465  error = clib_error_return (0, "parse error: '%U'",
466  format_unformat_error, input);
467  goto done;
468  }
469  }
470 
471  /* punt both IPv6 and IPv4 when used in CLI */
472  error = vnet_punt_add_del (vm, &pr, is_add);
473  if (error)
474  {
475  clib_error_report (error);
476  }
477 
478 done:
479  return error;
480 }
481 
482 /*?
483  * The set of '<em>set punt</em>' commands allows specific IP traffic to
484  * be punted to the host TCP/IP stack
485  *
486  * @em Note
487  * - UDP is the only protocol supported in the current implementation
488  * - All TCP traffic is currently punted to the host by default
489  *
490  * @cliexpar
491  * @parblock
492  * Example of how to request NTP traffic to be punted
493  * @cliexcmd{set punt udp 125}
494  *
495  * Example of how to request all 'unknown' UDP traffic to be punted
496  * @cliexcmd{set punt udp all}
497  *
498  * Example of how to stop all 'unknown' UDP traffic to be punted
499  * @cliexcmd{set punt udp del all}
500  * @endparblock
501 ?*/
502 /* *INDENT-OFF* */
503 VLIB_CLI_COMMAND (punt_command, static) = {
504  .path = "set punt",
505  .short_help = "set punt [IPV4|ip6|ipv6] [UDP|tcp] [del] [ALL|<port-num>]",
506  .function = punt_cli,
507 };
508 /* *INDENT-ON* */
509 
510 static clib_error_t *
512  unformat_input_t * input, vlib_cli_command_t * cmd)
513 {
514  u8 *socket_name = 0;
515  clib_error_t *error = NULL;
516  /* *INDENT-OFF* */
517  punt_reg_t pr = {
518  .punt = {
519  .l4 = {
520  .af = AF_IP4,
521  .port = ~0,
522  .protocol = IP_PROTOCOL_UDP,
523  },
524  },
525  .type = PUNT_TYPE_L4,
526  };
527  /* *INDENT-ON* */
528 
530  {
531  if (unformat (input, "ipv4"))
532  pr.punt.l4.af = AF_IP4;
533  else if (unformat (input, "ipv6"))
534  pr.punt.l4.af = AF_IP6;
535  else if (unformat (input, "udp"))
536  pr.punt.l4.protocol = IP_PROTOCOL_UDP;
537  else if (unformat (input, "tcp"))
538  pr.punt.l4.protocol = IP_PROTOCOL_TCP;
539  else if (unformat (input, "%d", &pr.punt.l4.port))
540  ;
541  else if (unformat (input, "all"))
542  pr.punt.l4.port = ~0;
543  else if (unformat (input, "socket %s", &socket_name))
544  ;
545  else
546  {
547  error = clib_error_return (0, "parse error: '%U'",
548  format_unformat_error, input);
549  goto done;
550  }
551  }
552 
553  if (!socket_name)
554  error = clib_error_return (0, "socket name not specified");
555  else
556  error = vnet_punt_socket_add (vm, 1, &pr, (char *) socket_name);
557 
558 done:
559  return error;
560 }
561 
562 /*?
563  *
564  * @cliexpar
565  * @cliexcmd{punt socket register socket punt_l4_foo.sock}
566 
567  ?*/
568 /* *INDENT-OFF* */
569 VLIB_CLI_COMMAND (punt_socket_register_command, static) =
570 {
571  .path = "punt socket register",
572  .function = punt_socket_register_cmd,
573  .short_help = "punt socket register [IPV4|ipv6] [UDP|tcp] [ALL|<port-num>] socket <socket>",
574  .is_mp_safe = 1,
575 };
576 /* *INDENT-ON* */
577 
578 static clib_error_t *
580  unformat_input_t * input,
581  vlib_cli_command_t * cmd)
582 {
583  clib_error_t *error = NULL;
584  /* *INDENT-OFF* */
585  punt_reg_t pr = {
586  .punt = {
587  .l4 = {
588  .af = AF_IP4,
589  .port = ~0,
590  .protocol = IP_PROTOCOL_UDP,
591  },
592  },
593  .type = PUNT_TYPE_L4,
594  };
595  /* *INDENT-ON* */
596 
598  {
599  if (unformat (input, "ipv4"))
600  pr.punt.l4.af = AF_IP4;
601  else if (unformat (input, "ipv6"))
602  pr.punt.l4.af = AF_IP6;
603  else if (unformat (input, "udp"))
604  pr.punt.l4.protocol = IP_PROTOCOL_UDP;
605  else if (unformat (input, "tcp"))
606  pr.punt.l4.protocol = IP_PROTOCOL_TCP;
607  else if (unformat (input, "%d", &pr.punt.l4.port))
608  ;
609  else if (unformat (input, "all"))
610  pr.punt.l4.port = ~0;
611  else
612  {
613  error = clib_error_return (0, "parse error: '%U'",
614  format_unformat_error, input);
615  goto done;
616  }
617  }
618 
619  error = vnet_punt_socket_del (vm, &pr);
620 done:
621  return error;
622 }
623 
624 /*?
625  *
626  * @cliexpar
627  * @cliexcmd{punt socket register}
628  ?*/
629 /* *INDENT-OFF* */
630 VLIB_CLI_COMMAND (punt_socket_deregister_command, static) =
631 {
632  .path = "punt socket deregister",
633  .function = punt_socket_deregister_cmd,
634  .short_help = "punt socket deregister [IPV4|ipv6] [UDP|tcp] [ALL|<port-num>]",
635  .is_mp_safe = 1,
636 };
637 /* *INDENT-ON* */
638 
639 void
641 {
642  punt_main_t *pm = &punt_main;
643 
644  switch (pt)
645  {
646  case PUNT_TYPE_L4:
647  {
648  u32 pci, key;
649 
650  /* *INDENT-OFF* */
651  hash_foreach(key, pci, pm->db.clients_by_l4_port,
652  ({
653  cb (pool_elt_at_index(pm->punt_client_pool, pci), ctx);
654  }));
655  /* *INDENT-ON* */
656  break;
657  }
658  case PUNT_TYPE_IP_PROTO:
659  {
660  u32 pci, key;
661 
662  /* *INDENT-OFF* */
663  hash_foreach(key, pci, pm->db.clients_by_ip_proto,
664  ({
665  cb (pool_elt_at_index(pm->punt_client_pool, pci), ctx);
666  }));
667  /* *INDENT-ON* */
668  break;
669  }
670  case PUNT_TYPE_EXCEPTION:
671  {
672  u32 *pci;
673 
675  {
676  if (~0 != *pci)
677  cb (pool_elt_at_index (pm->punt_client_pool, *pci), ctx);
678  }
679 
680  break;
681  }
682  }
683 }
684 
685 static u8 *
686 format_punt_client (u8 * s, va_list * args)
687 {
688  punt_client_t *pc = va_arg (*args, punt_client_t *);
689 
690  s = format (s, " punt ");
691 
692  switch (pc->reg.type)
693  {
694  case PUNT_TYPE_L4:
695  s = format (s, "%U %U port %d",
698  pc->reg.punt.l4.port);
699  break;
700  case PUNT_TYPE_IP_PROTO:
701  s = format (s, "%U %U",
704  break;
705  case PUNT_TYPE_EXCEPTION:
706  s = format (s, " %U", format_vlib_punt_reason,
707  pc->reg.punt.exception.reason);
708  break;
709  }
710 
711  s = format (s, " to socket %s \n", pc->caddr.sun_path);
712 
713  return (s);
714 }
715 
716 static walk_rc_t
718 {
719  vlib_cli_output (ctx, "%U", format_punt_client, pc);
720 
721  return (WALK_CONTINUE);
722 }
723 
724 static clib_error_t *
726  unformat_input_t * input, vlib_cli_command_t * cmd)
727 {
728  clib_error_t *error = NULL;
729  punt_type_t pt;
730 
731  pt = PUNT_TYPE_L4;
732 
734  {
735  if (unformat (input, "exception"))
736  pt = PUNT_TYPE_EXCEPTION;
737  else if (unformat (input, "l4"))
738  pt = PUNT_TYPE_L4;
739  else if (unformat (input, "ip"))
740  pt = PUNT_TYPE_IP_PROTO;
741  else
742  {
743  error = clib_error_return (0, "parse error: '%U'",
744  format_unformat_error, input);
745  goto done;
746  }
747  }
748 
750 
751 done:
752  return (error);
753 }
754 
755 /*?
756  *
757  * @cliexpar
758  * @cliexcmd{show punt socket ipv4}
759  ?*/
760 /* *INDENT-OFF* */
761 VLIB_CLI_COMMAND (show_punt_socket_registration_command, static) =
762 {
763  .path = "show punt socket registrations",
764  .function = punt_socket_show_cmd,
765  .short_help = "show punt socket registrations [l4|exception]",
766  .is_mp_safe = 1,
767 };
768 /* *INDENT-ON* */
769 
770 clib_error_t *
772 {
773  clib_error_t *error = NULL;
774  punt_main_t *pm = &punt_main;
776 
777  pm->is_configured = false;
779  vlib_get_node_by_name (vm, (u8 *) "interface-output");
780 
781  if ((error = vlib_call_init_function (vm, punt_init)))
782  return error;
783 
784  pm->hdl = vlib_punt_client_register ("ip-punt");
785 
788 
789  return (error);
790 }
791 
793 
794 static clib_error_t *
796 {
797  punt_main_t *pm = &punt_main;
798  char *socket_path = 0;
799 
801  {
802  if (unformat (input, "socket %s", &socket_path))
803  strncpy (pm->sun_path, socket_path, UNIX_PATH_MAX - 1);
804  else
805  return clib_error_return (0, "unknown input `%U'",
806  format_unformat_error, input);
807  }
808 
809  if (socket_path == 0)
810  return 0;
811 
812  /* UNIX domain socket */
813  struct sockaddr_un addr;
814  if ((pm->socket_fd = socket (AF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK, 0)) == -1)
815  {
816  return clib_error_return (0, "socket error");
817  }
818 
819  clib_memset (&addr, 0, sizeof (addr));
820  addr.sun_family = AF_UNIX;
821  if (*socket_path == '\0')
822  {
823  *addr.sun_path = '\0';
824  strncpy (addr.sun_path + 1, socket_path + 1,
825  sizeof (addr.sun_path) - 2);
826  }
827  else
828  {
829  strncpy (addr.sun_path, socket_path, sizeof (addr.sun_path) - 1);
830  unlink (socket_path);
831  }
832 
833  if (bind (pm->socket_fd, (struct sockaddr *) &addr, sizeof (addr)) == -1)
834  {
835  return clib_error_return (0, "bind error");
836  }
837 
838  int n_bytes = 0x10000;
839 
840  if (setsockopt
841  (pm->socket_fd, SOL_SOCKET, SO_SNDBUF, &n_bytes,
842  sizeof (n_bytes)) == -1)
843  {
844  return clib_error_return (0, "setsockopt error");
845  }
846 
847  /* Register socket */
849  clib_file_t template = { 0 };
851  template.file_descriptor = pm->socket_fd;
852  template.description = format (0, "%s", socket_path);
853  pm->clib_file_index = clib_file_add (fm, &template);
854 
855  pm->is_configured = true;
856 
857  return 0;
858 }
859 
861 
862 /*
863  * fd.io coding-style-patch-verification: ON
864  *
865  * Local Variables:
866  * eval: (c-set-style "gnu")
867  * End:
868  */
vlib_node_t * interface_output_node
Definition: punt.h:127
enum punt_type_t_ punt_type_t
format_function_t format_ip_protocol
Definition: format.h:45
static u32 punt_client_exception_db_remove(vlib_punt_reason_t reason)
Definition: punt.c:117
A registration, by a client, to direct punted traffic to a given node.
Definition: punt.h:64
static u8 * format_punt_client(u8 *s, va_list *args)
Definition: punt.c:686
#define hash_set(h, key, value)
Definition: hash.h:255
#define hash_unset(h, key)
Definition: hash.h:261
void ip6_register_protocol(u32 protocol, u32 node_index)
Definition: ip6_forward.c:1664
ip_protocol_t protocol
Definition: punt.h:49
#define pool_get_zero(P, E)
Allocate an object E from a pool P and zero it.
Definition: pool.h:255
void ip6_unregister_protocol(u32 protocol)
Definition: ip6_forward.c:1676
static clib_error_t * punt_config(vlib_main_t *vm, unformat_input_t *input)
Definition: punt.c:795
static_always_inline u32 punt_client_l4_mk_key(ip_address_family_t af, u16 port)
Definition: punt.h:145
static clib_error_t * punt_socket_read_ready(clib_file_t *uf)
Definition: punt.c:132
static void vlib_node_set_interrupt_pending(vlib_main_t *vm, u32 node_index)
Definition: node_funcs.h:197
vlib_node_registration_t ip4_proto_punt_socket_node
(constructor) VLIB_REGISTER_NODE (ip4_proto_punt_socket_node)
Definition: punt_node.c:461
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
u32 * ready_fds
Definition: punt.h:128
u32 clib_file_index
Definition: punt.h:125
u32 file_descriptor
Definition: file.h:54
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:590
punt_reg_t reg
Definition: punt.h:103
punt_type_t type
Definition: punt.h:66
static_always_inline punt_client_t * punt_client_l4_get(ip_address_family_t af, u16 port)
Definition: punt.h:151
vlib_node_registration_t udp4_punt_socket_node
(constructor) VLIB_REGISTER_NODE (udp4_punt_socket_node)
Definition: punt_node.c:442
int socket_fd
Definition: punt.h:121
static walk_rc_t punt_client_show_one(const punt_client_t *pc, void *ctx)
Definition: punt.c:717
clib_error_t * vnet_punt_socket_del(vlib_main_t *vm, const punt_reg_t *pr)
Definition: punt.c:330
static_always_inline punt_client_t * punt_client_ip_proto_get(ip_address_family_t af, ip_protocol_t proto)
Definition: punt.h:171
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
Definition: vec.h:518
void ip4_register_protocol(u32 protocol, u32 node_index)
Definition: ip4_forward.c:1933
unsigned char u8
Definition: types.h:56
punt_thread_data_t * thread_data
Definition: punt.h:130
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:290
clib_file_function_t * read_function
Definition: file.h:67
u8 * format_vlib_punt_reason(u8 *s, va_list *args)
Format a punt reason.
Definition: punt.c:147
#define fm
enum walk_rc_t_ walk_rc_t
Walk return code.
vl_api_ip_proto_t protocol
Definition: lb_types.api:71
static void punt_client_ip_proto_db_add(ip_address_family_t af, ip_protocol_t proto, u32 index)
Definition: punt.c:77
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
punt_client_t * punt_client_pool
Definition: punt.h:124
static clib_error_t * punt_cli(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: punt.c:426
#define hash_foreach(key_var, value_var, h, body)
Definition: hash.h:442
static u32 punt_client_ip_proto_db_remove(ip_address_family_t af, ip_protocol_t proto)
Definition: punt.c:89
#define clib_error_return(e, args...)
Definition: error.h:99
clib_file_main_t file_main
Definition: main.c:63
static_always_inline punt_client_t * punt_client_exception_get(vlib_punt_reason_t reason)
Definition: punt.h:187
unsigned int u32
Definition: types.h:88
#define vlib_call_init_function(vm, x)
Definition: init.h:270
vlib_punt_hdl_t hdl
Definition: punt.h:131
vlib_punt_hdl_t vlib_punt_client_register(const char *who)
Register a new clinet.
Definition: punt.c:155
static_always_inline u32 punt_client_ip_proto_mk_key(ip_address_family_t af, ip_protocol_t proto)
Definition: punt.h:165
enum ip_protocol ip_protocol_t
static void punt_client_exception_db_add(vlib_punt_reason_t reason, u32 pci)
Definition: punt.c:107
#define hash_get(h, key)
Definition: hash.h:249
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:534
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
Definition: node.c:45
punt_ip_proto_t ip_proto
Definition: punt.h:61
vl_api_ip_proto_t proto
Definition: acl_types.api:50
long ctx[MAX_CONNS]
Definition: main.c:144
struct _unformat_input_t unformat_input_t
unsigned short u16
Definition: types.h:57
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:369
ip_address_family_t af
Definition: punt.h:41
#define VLIB_CONFIG_FUNCTION(x, n,...)
Definition: init.h:182
vlib_node_registration_t punt_socket_rx_node
(constructor) VLIB_REGISTER_NODE (punt_socket_rx_node)
Definition: punt_node.c:621
u8 * format_ip_address_family(u8 *s, va_list *args)
Definition: ip.c:100
static clib_error_t * punt_init(vlib_main_t *vm)
Definition: punt.c:662
vlib_main_t * vm
Definition: in2out_ed.c:1599
punt_exception_t exception
Definition: punt.h:59
void udp_punt_unknown(vlib_main_t *vm, u8 is_ip4, u8 is_add)
Definition: udp_local.c:545
vlib_node_registration_t udp6_punt_socket_node
(constructor) VLIB_REGISTER_NODE (udp6_punt_socket_node)
Definition: punt_node.c:452
#define UNFORMAT_END_OF_INPUT
Definition: format.h:145
svmdb_client_t * c
static clib_error_t * punt_socket_unregister_exception(vlib_punt_reason_t reason)
Definition: punt.c:277
void udp_unregister_dst_port(vlib_main_t *vm, udp_dst_port_t dst_port, u8 is_ip4)
Definition: udp_local.c:506
static clib_error_t * punt_socket_register_exception(vlib_main_t *vm, vlib_punt_reason_t reason, char *client_pathname)
Definition: punt.c:216
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:186
static clib_error_t * punt_socket_show_cmd(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: punt.c:725
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:152
static clib_error_t * punt_socket_unregister_ip_proto(ip_address_family_t af, ip_protocol_t proto)
Definition: punt.c:259
#define pool_put_index(p, i)
Free pool element with given index.
Definition: pool.h:331
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:689
ip_address_family_t af
Definition: punt.h:48
walk_rc_t(* punt_client_walk_cb_t)(const punt_client_t *pc, void *ctx)
Definition: punt.h:136
ip_protocol_t protocol
Definition: punt.h:42
static uword clib_file_add(clib_file_main_t *um, clib_file_t *template)
Definition: file.h:96
char sun_path[sizeof(struct sockaddr_un)]
Definition: punt.h:122
punt_main_t punt_main
Definition: punt.c:39
punt_l4_t l4
Definition: punt.h:60
static u32 punt_client_l4_db_remove(ip_address_family_t af, u16 port)
Definition: punt.c:59
#define clib_error_report(e)
Definition: error.h:113
static clib_error_t * punt_socket_deregister_cmd(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: punt.c:579
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
u32 * clients_by_exception
Definition: punt.h:110
enum ip_address_family_t_ ip_address_family_t
typedef key
Definition: ipsec_types.api:85
void tcp_punt_unknown(vlib_main_t *vm, u8 is_ip4, u8 is_add)
Definition: tcp.c:1399
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:267
static void punt_client_l4_db_add(ip_address_family_t af, u16 port, u32 index)
Definition: punt.c:49
void * clients_by_ip_proto
Definition: punt.h:111
bool is_configured
Definition: punt.h:126
punt_union_t punt
Definition: punt.h:67
u64 uword
Definition: types.h:112
vlib_node_registration_t ip6_proto_punt_socket_node
(constructor) VLIB_REGISTER_NODE (ip6_proto_punt_socket_node)
Definition: punt_node.c:471
punt_client_db_t db
Definition: punt.h:123
u16 port
Definition: lb_types.api:72
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:145
#define PUNT_PACKETDESC_VERSION
Definition: punt.h:91
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
static clib_error_t * punt_socket_unregister_l4(ip_address_family_t af, ip_protocol_t protocol, u16 port)
Definition: punt.c:243
static vlib_thread_main_t * vlib_get_thread_main()
Definition: global_funcs.h:32
#define vec_foreach(var, vec)
Vector iterator.
clib_error_t * ip_punt_init(vlib_main_t *vm)
Definition: punt.c:771
Definition: file.h:51
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
static clib_error_t * punt_socket_register_cmd(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: punt.c:511
#define vec_validate_init_empty(V, I, INIT)
Make sure vector is long enough for given index and initialize empty space (no header, unspecified alignment)
Definition: vec.h:554
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
clib_error_t * vnet_punt_add_del(vlib_main_t *vm, const punt_reg_t *pr, bool is_add)
Definition: punt.c:410
vlib_punt_reason_t reason
Definition: punt.h:54
enum vlib_punt_reason_t_ vlib_punt_reason_t
The &#39;syatem&#39; defined punt reasons.
char * vnet_punt_get_server_pathname(void)
Definition: punt.c:42
void * clients_by_l4_port
Definition: punt.h:109
vlib_node_registration_t udp4_punt_node
(constructor) VLIB_REGISTER_NODE (udp4_punt_node)
Definition: punt_node.c:189
void ip4_unregister_protocol(u32 protocolx)
Definition: ip4_forward.c:1945
u16 port
Definition: punt.h:43
void punt_client_walk(punt_type_t pt, punt_client_walk_cb_t cb, void *ctx)
Definition: punt.c:640
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
struct sockaddr_un caddr
Definition: punt.h:104
Definitions for punt infrastructure.
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:171