FD.io VPP  v19.08-24-ge6a5712
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 traffic punt to the local TCP/IP stack.
355  *
356  * @em Note
357  * - UDP and TCP are the only protocols 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 = ~0,
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, "ipv6"))
450  pr.punt.l4.af = AF_IP6;
451  else if (unformat (input, "ip6"))
452  pr.punt.l4.af = AF_IP6;
453  else if (unformat (input, "%d", &port))
454  pr.punt.l4.port = port;
455  else if (unformat (input, "udp"))
456  pr.punt.l4.protocol = IP_PROTOCOL_UDP;
457  else if (unformat (input, "tcp"))
458  pr.punt.l4.protocol = IP_PROTOCOL_TCP;
459  else
460  {
461  error = clib_error_return (0, "parse error: '%U'",
462  format_unformat_error, input);
463  goto done;
464  }
465  }
466 
467  /* punt both IPv6 and IPv4 when used in CLI */
468  error = vnet_punt_add_del (vm, &pr, is_add);
469  if (error)
470  {
471  clib_error_report (error);
472  }
473 
474 done:
475  return error;
476 }
477 
478 /*?
479  * The set of '<em>set punt</em>' commands allows specific IP traffic to
480  * be punted to the host TCP/IP stack
481  *
482  * @em Note
483  * - UDP is the only protocol supported in the current implementation
484  * - All TCP traffic is currently punted to the host by default
485  *
486  * @cliexpar
487  * @parblock
488  * Example of how to request NTP traffic to be punted
489  * @cliexcmd{set punt udp 125}
490  *
491  * Example of how to request all 'unknown' UDP traffic to be punted
492  * @cliexcmd{set punt udp all}
493  *
494  * Example of how to stop all 'unknown' UDP traffic to be punted
495  * @cliexcmd{set punt udp del all}
496  * @endparblock
497 ?*/
498 /* *INDENT-OFF* */
499 VLIB_CLI_COMMAND (punt_command, static) = {
500  .path = "set punt",
501  .short_help = "set punt [udp|tcp] [del] <all | port-num1 [port-num2 ...]>",
502  .function = punt_cli,
503 };
504 /* *INDENT-ON* */
505 
506 static clib_error_t *
508  unformat_input_t * input, vlib_cli_command_t * cmd)
509 {
510  u8 *socket_name = 0;
511  clib_error_t *error = NULL;
512  /* *INDENT-OFF* */
513  punt_reg_t pr = {
514  .punt = {
515  .l4 = {
516  .af = AF_IP4,
517  .port = ~0,
518  .protocol = ~0,
519  },
520  },
521  .type = PUNT_TYPE_L4,
522  };
523  /* *INDENT-ON* */
524 
526  {
527  if (unformat (input, "ipv4"))
528  ;
529  else if (unformat (input, "ipv6"))
530  pr.punt.l4.af = AF_IP6;
531  else if (unformat (input, "udp"))
532  pr.punt.l4.protocol = IP_PROTOCOL_UDP;
533  else if (unformat (input, "tcp"))
534  pr.punt.l4.protocol = IP_PROTOCOL_TCP;
535  else if (unformat (input, "%d", &pr.punt.l4.port))
536  ;
537  else if (unformat (input, "socket %s", &socket_name))
538  ;
539  else
540  {
541  error = clib_error_return (0, "parse error: '%U'",
542  format_unformat_error, input);
543  goto done;
544  }
545  }
546 
547  if (!socket_name)
548  error = clib_error_return (0, "socket name not specified");
549  else
550  error = vnet_punt_socket_add (vm, 1, &pr, (char *) socket_name);
551 
552 done:
553  return error;
554 }
555 
556 /*?
557  *
558  * @cliexpar
559  * @cliexcmd{punt socket register}
560  ?*/
561 /* *INDENT-OFF* */
562 VLIB_CLI_COMMAND (punt_socket_register_command, static) =
563 {
564  .path = "punt socket register",
565  .function = punt_socket_register_cmd,
566  .short_help = "punt socket register [ipv4|ipv6] [udp|tcp]> <all | port-num1 [port-num2 ...]> <socket>",
567  .is_mp_safe = 1,
568 };
569 /* *INDENT-ON* */
570 
571 static clib_error_t *
573  unformat_input_t * input,
574  vlib_cli_command_t * cmd)
575 {
576  clib_error_t *error = NULL;
577  /* *INDENT-OFF* */
578  punt_reg_t pr = {
579  .punt = {
580  .l4 = {
581  .af = AF_IP4,
582  .port = ~0,
583  .protocol = ~0,
584  },
585  },
586  .type = PUNT_TYPE_L4,
587  };
588  /* *INDENT-ON* */
589 
591  {
592  if (unformat (input, "ipv4"))
593  ;
594  else if (unformat (input, "ipv6"))
595  pr.punt.l4.af = AF_IP6;
596  else if (unformat (input, "udp"))
597  pr.punt.l4.protocol = IP_PROTOCOL_UDP;
598  else if (unformat (input, "tcp"))
599  pr.punt.l4.protocol = IP_PROTOCOL_TCP;
600  else if (unformat (input, "%d", &pr.punt.l4.port))
601  ;
602  else
603  {
604  error = clib_error_return (0, "parse error: '%U'",
605  format_unformat_error, input);
606  goto done;
607  }
608  }
609 
610  error = vnet_punt_socket_del (vm, &pr);
611 done:
612  return error;
613 }
614 
615 /*?
616  *
617  * @cliexpar
618  * @cliexcmd{punt socket register}
619  ?*/
620 /* *INDENT-OFF* */
621 VLIB_CLI_COMMAND (punt_socket_deregister_command, static) =
622 {
623  .path = "punt socket deregister",
624  .function = punt_socket_deregister_cmd,
625  .short_help = "punt socket deregister [ipv4|ipv6] [udp|tcp]> <all | port-num1 [port-num2 ...]>",
626  .is_mp_safe = 1,
627 };
628 /* *INDENT-ON* */
629 
630 void
632 {
633  punt_main_t *pm = &punt_main;
634 
635  switch (pt)
636  {
637  case PUNT_TYPE_L4:
638  {
639  u32 pci, key;
640 
641  /* *INDENT-OFF* */
642  hash_foreach(key, pci, pm->db.clients_by_l4_port,
643  ({
644  cb (pool_elt_at_index(pm->punt_client_pool, pci), ctx);
645  }));
646  /* *INDENT-ON* */
647  break;
648  }
649  case PUNT_TYPE_IP_PROTO:
650  {
651  u32 pci, key;
652 
653  /* *INDENT-OFF* */
654  hash_foreach(key, pci, pm->db.clients_by_ip_proto,
655  ({
656  cb (pool_elt_at_index(pm->punt_client_pool, pci), ctx);
657  }));
658  /* *INDENT-ON* */
659  break;
660  }
661  case PUNT_TYPE_EXCEPTION:
662  {
663  u32 *pci;
664 
666  {
667  if (~0 != *pci)
668  cb (pool_elt_at_index (pm->punt_client_pool, *pci), ctx);
669  }
670 
671  break;
672  }
673  }
674 }
675 
676 static u8 *
677 format_punt_client (u8 * s, va_list * args)
678 {
679  punt_client_t *pc = va_arg (*args, punt_client_t *);
680 
681  s = format (s, " punt ");
682 
683  switch (pc->reg.type)
684  {
685  case PUNT_TYPE_L4:
686  s = format (s, "%U %U port %d",
689  pc->reg.punt.l4.port);
690  break;
691  case PUNT_TYPE_IP_PROTO:
692  s = format (s, "%U %U",
695  break;
696  case PUNT_TYPE_EXCEPTION:
697  s = format (s, " %U", format_vlib_punt_reason,
698  pc->reg.punt.exception.reason);
699  break;
700  }
701 
702  s = format (s, " to socket %s \n", pc->caddr.sun_path);
703 
704  return (s);
705 }
706 
707 static walk_rc_t
709 {
710  vlib_cli_output (ctx, "%U", format_punt_client, pc);
711 
712  return (WALK_CONTINUE);
713 }
714 
715 static clib_error_t *
717  unformat_input_t * input, vlib_cli_command_t * cmd)
718 {
719  clib_error_t *error = NULL;
720  punt_type_t pt;
721 
722  pt = PUNT_TYPE_L4;
723 
725  {
726  if (unformat (input, "exception"))
727  pt = PUNT_TYPE_EXCEPTION;
728  else if (unformat (input, "l4"))
729  pt = PUNT_TYPE_L4;
730  else if (unformat (input, "ip"))
731  pt = PUNT_TYPE_IP_PROTO;
732  else
733  {
734  error = clib_error_return (0, "parse error: '%U'",
735  format_unformat_error, input);
736  goto done;
737  }
738  }
739 
741 
742 done:
743  return (error);
744 }
745 
746 /*?
747  *
748  * @cliexpar
749  * @cliexcmd{show punt socket ipv4}
750  ?*/
751 /* *INDENT-OFF* */
752 VLIB_CLI_COMMAND (show_punt_socket_registration_command, static) =
753 {
754  .path = "show punt socket registrations",
755  .function = punt_socket_show_cmd,
756  .short_help = "show punt socket registrations [l4|exception]",
757  .is_mp_safe = 1,
758 };
759 /* *INDENT-ON* */
760 
761 clib_error_t *
763 {
764  clib_error_t *error = NULL;
765  punt_main_t *pm = &punt_main;
767 
768  pm->is_configured = false;
770  vlib_get_node_by_name (vm, (u8 *) "interface-output");
771 
772  if ((error = vlib_call_init_function (vm, punt_init)))
773  return error;
774 
775  pm->hdl = vlib_punt_client_register ("ip-punt");
776 
779 
780  return (error);
781 }
782 
784 
785 static clib_error_t *
787 {
788  punt_main_t *pm = &punt_main;
789  char *socket_path = 0;
790 
792  {
793  if (unformat (input, "socket %s", &socket_path))
794  strncpy (pm->sun_path, socket_path, UNIX_PATH_MAX - 1);
795  else
796  return clib_error_return (0, "unknown input `%U'",
797  format_unformat_error, input);
798  }
799 
800  if (socket_path == 0)
801  return 0;
802 
803  /* UNIX domain socket */
804  struct sockaddr_un addr;
805  if ((pm->socket_fd = socket (AF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK, 0)) == -1)
806  {
807  return clib_error_return (0, "socket error");
808  }
809 
810  clib_memset (&addr, 0, sizeof (addr));
811  addr.sun_family = AF_UNIX;
812  if (*socket_path == '\0')
813  {
814  *addr.sun_path = '\0';
815  strncpy (addr.sun_path + 1, socket_path + 1,
816  sizeof (addr.sun_path) - 2);
817  }
818  else
819  {
820  strncpy (addr.sun_path, socket_path, sizeof (addr.sun_path) - 1);
821  unlink (socket_path);
822  }
823 
824  if (bind (pm->socket_fd, (struct sockaddr *) &addr, sizeof (addr)) == -1)
825  {
826  return clib_error_return (0, "bind error");
827  }
828 
829  int n_bytes = 0x10000;
830 
831  if (setsockopt
832  (pm->socket_fd, SOL_SOCKET, SO_SNDBUF, &n_bytes,
833  sizeof (n_bytes)) == -1)
834  {
835  return clib_error_return (0, "setsockopt error");
836  }
837 
838  /* Register socket */
840  clib_file_t template = { 0 };
842  template.file_descriptor = pm->socket_fd;
843  template.description = format (0, "%s", socket_path);
844  pm->clib_file_index = clib_file_add (fm, &template);
845 
846  pm->is_configured = true;
847 
848  return 0;
849 }
850 
852 
853 /*
854  * fd.io coding-style-patch-verification: ON
855  *
856  * Local Variables:
857  * eval: (c-set-style "gnu")
858  * End:
859  */
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.c:66
#define hash_set(h, key, value)
Definition: hash.h:255
enum ip_address_family_t_ ip_address_family_t
#define hash_unset(h, key)
Definition: hash.h:261
void ip6_register_protocol(u32 protocol, u32 node_index)
Definition: ip6_forward.c:1447
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:239
void ip6_unregister_protocol(u32 protocol)
Definition: ip6_forward.c:1459
static clib_error_t * punt_config(vlib_main_t *vm, unformat_input_t *input)
Definition: punt.c:786
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
#define NULL
Definition: clib.h:58
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:522
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:708
clib_memset(h->entries, 0, sizeof(h->entries[0])*entries)
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:450
void ip4_register_protocol(u32 protocol, u32 node_index)
Definition: ip4_forward.c:1748
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:132
#define fm
enum walk_rc_t_ walk_rc_t
Walk return code.
Definition: ip.h: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:140
static_always_inline u32 punt_client_ip_proto_mk_key(ip_address_family_t af, ip_protocol_t proto)
Definition: punt.h:165
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:514
punt_ip_proto_t ip_proto
Definition: punt.h:61
long ctx[MAX_CONNS]
Definition: main.c:144
vl_api_ip_proto_t protocol
Definition: punt.api:39
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 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
enum ip_protocol ip_protocol_t
vlib_node_registration_t punt_socket_rx_node
(constructor) VLIB_REGISTER_NODE (punt_socket_rx_node)
Definition: punt_node.c:620
u16 port
Definition: punt.api:40
u8 * format_ip_address_family(u8 *s, va_list *args)
Definition: ip.c:283
static clib_error_t * punt_init(vlib_main_t *vm)
Definition: punt.c:634
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:548
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
vlib_main_t * vm
Definition: buffer.c:312
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:509
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
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
Definition: node.c:45
static clib_error_t * punt_socket_show_cmd(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: punt.c:716
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:155
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:311
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
u8 * format_punt_client(u8 *s, va_list *args)
Definition: punt.c:459
static clib_error_t * punt_socket_deregister_cmd(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: punt.c:572
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
u32 * clients_by_exception
Definition: punt.h:110
Definition: ip.h:70
void tcp_punt_unknown(vlib_main_t *vm, u8 is_ip4, u8 is_add)
Definition: tcp.c:1508
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:252
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
typedef key
Definition: ipsec.api:245
punt_client_db_t db
Definition: punt.h:123
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:762
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:471
static clib_error_t * punt_socket_register_cmd(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: punt.c:507
#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:486
#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 vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:768
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:1760
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:631
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.
vl_api_fib_path_nh_proto_t proto
Definition: fib_types.api:125
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:171