FD.io VPP  v19.08.3-2-gbabecb413
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  unformat_input_t line_input, *input = &line_input;
430  clib_error_t *error = NULL;
431  bool is_add = true;
432  /* *INDENT-OFF* */
433  punt_reg_t pr = {
434  .punt = {
435  .l4 = {
436  .af = AF_IP4,
437  .port = ~0,
438  .protocol = IP_PROTOCOL_UDP,
439  },
440  },
441  .type = PUNT_TYPE_L4,
442  };
443  u32 port;
444  /* *INDENT-ON* */
445 
446  if (!unformat_user (input__, unformat_line_input, input))
447  return 0;
448 
450  {
451  if (unformat (input, "del"))
452  is_add = false;
453  else if (unformat (input, "ipv4"))
454  pr.punt.l4.af = AF_IP4;
455  else if (unformat (input, "ipv6"))
456  pr.punt.l4.af = AF_IP6;
457  else if (unformat (input, "ip6"))
458  pr.punt.l4.af = AF_IP6;
459  else if (unformat (input, "%d", &port))
460  pr.punt.l4.port = port;
461  else if (unformat (input, "all"))
462  pr.punt.l4.port = ~0;
463  else if (unformat (input, "udp"))
464  pr.punt.l4.protocol = IP_PROTOCOL_UDP;
465  else if (unformat (input, "tcp"))
466  pr.punt.l4.protocol = IP_PROTOCOL_TCP;
467  else
468  {
469  error = clib_error_return (0, "parse error: '%U'",
470  format_unformat_error, input);
471  goto done;
472  }
473  }
474 
475  /* punt both IPv6 and IPv4 when used in CLI */
476  error = vnet_punt_add_del (vm, &pr, is_add);
477  if (error)
478  {
479  clib_error_report (error);
480  }
481 
482 done:
483  unformat_free (input);
484  return error;
485 }
486 
487 /*?
488  * The set of '<em>set punt</em>' commands allows specific IP traffic to
489  * be punted to the host TCP/IP stack
490  *
491  * @em Note
492  * - UDP is the only protocol supported in the current implementation
493  * - All TCP traffic is currently punted to the host by default
494  *
495  * @cliexpar
496  * @parblock
497  * Example of how to request NTP traffic to be punted
498  * @cliexcmd{set punt udp 125}
499  *
500  * Example of how to request all 'unknown' UDP traffic to be punted
501  * @cliexcmd{set punt udp all}
502  *
503  * Example of how to stop all 'unknown' UDP traffic to be punted
504  * @cliexcmd{set punt udp del all}
505  * @endparblock
506 ?*/
507 /* *INDENT-OFF* */
508 VLIB_CLI_COMMAND (punt_command, static) = {
509  .path = "set punt",
510  .short_help = "set punt [IPV4|ip6|ipv6] [UDP|tcp] [del] [ALL|<port-num>]",
511  .function = punt_cli,
512 };
513 /* *INDENT-ON* */
514 
515 static clib_error_t *
517  unformat_input_t * input__,
518  vlib_cli_command_t * cmd)
519 {
520  unformat_input_t line_input, *input = &line_input;
521  u8 *socket_name = 0;
522  clib_error_t *error = NULL;
523  /* *INDENT-OFF* */
524  punt_reg_t pr = {
525  .punt = {
526  .l4 = {
527  .af = AF_IP4,
528  .port = ~0,
529  .protocol = IP_PROTOCOL_UDP,
530  },
531  },
532  .type = PUNT_TYPE_L4,
533  };
534  /* *INDENT-ON* */
535 
536  if (!unformat_user (input__, unformat_line_input, input))
537  return 0;
538 
540  {
541  if (unformat (input, "ipv4"))
542  pr.punt.l4.af = AF_IP4;
543  else if (unformat (input, "ipv6"))
544  pr.punt.l4.af = AF_IP6;
545  else if (unformat (input, "udp"))
546  pr.punt.l4.protocol = IP_PROTOCOL_UDP;
547  else if (unformat (input, "tcp"))
548  pr.punt.l4.protocol = IP_PROTOCOL_TCP;
549  else if (unformat (input, "%d", &pr.punt.l4.port))
550  ;
551  else if (unformat (input, "all"))
552  pr.punt.l4.port = ~0;
553  else if (unformat (input, "socket %s", &socket_name))
554  ;
555  else
556  {
557  error = clib_error_return (0, "parse error: '%U'",
558  format_unformat_error, input);
559  goto done;
560  }
561  }
562 
563  if (!socket_name)
564  error = clib_error_return (0, "socket name not specified");
565  else
566  error = vnet_punt_socket_add (vm, 1, &pr, (char *) socket_name);
567 
568 done:
569  unformat_free (input);
570  return error;
571 }
572 
573 /*?
574  *
575  * @cliexpar
576  * @cliexcmd{punt socket register socket punt_l4_foo.sock}
577 
578  ?*/
579 /* *INDENT-OFF* */
580 VLIB_CLI_COMMAND (punt_socket_register_command, static) =
581 {
582  .path = "punt socket register",
583  .function = punt_socket_register_cmd,
584  .short_help = "punt socket register [IPV4|ipv6] [UDP|tcp] [ALL|<port-num>] socket <socket>",
585  .is_mp_safe = 1,
586 };
587 /* *INDENT-ON* */
588 
589 static clib_error_t *
591  unformat_input_t * input__,
592  vlib_cli_command_t * cmd)
593 {
594  unformat_input_t line_input, *input = &line_input;
595  clib_error_t *error = NULL;
596  /* *INDENT-OFF* */
597  punt_reg_t pr = {
598  .punt = {
599  .l4 = {
600  .af = AF_IP4,
601  .port = ~0,
602  .protocol = IP_PROTOCOL_UDP,
603  },
604  },
605  .type = PUNT_TYPE_L4,
606  };
607  /* *INDENT-ON* */
608 
609  if (!unformat_user (input__, unformat_line_input, input))
610  return 0;
611 
613  {
614  if (unformat (input, "ipv4"))
615  pr.punt.l4.af = AF_IP4;
616  else if (unformat (input, "ipv6"))
617  pr.punt.l4.af = AF_IP6;
618  else if (unformat (input, "udp"))
619  pr.punt.l4.protocol = IP_PROTOCOL_UDP;
620  else if (unformat (input, "tcp"))
621  pr.punt.l4.protocol = IP_PROTOCOL_TCP;
622  else if (unformat (input, "%d", &pr.punt.l4.port))
623  ;
624  else if (unformat (input, "all"))
625  pr.punt.l4.port = ~0;
626  else
627  {
628  error = clib_error_return (0, "parse error: '%U'",
629  format_unformat_error, input);
630  goto done;
631  }
632  }
633 
634  error = vnet_punt_socket_del (vm, &pr);
635 done:
636  unformat_free (input);
637  return error;
638 }
639 
640 /*?
641  *
642  * @cliexpar
643  * @cliexcmd{punt socket register}
644  ?*/
645 /* *INDENT-OFF* */
646 VLIB_CLI_COMMAND (punt_socket_deregister_command, static) =
647 {
648  .path = "punt socket deregister",
649  .function = punt_socket_deregister_cmd,
650  .short_help = "punt socket deregister [IPV4|ipv6] [UDP|tcp] [ALL|<port-num>]",
651  .is_mp_safe = 1,
652 };
653 /* *INDENT-ON* */
654 
655 void
657 {
658  punt_main_t *pm = &punt_main;
659 
660  switch (pt)
661  {
662  case PUNT_TYPE_L4:
663  {
664  u32 pci, key;
665 
666  /* *INDENT-OFF* */
667  hash_foreach(key, pci, pm->db.clients_by_l4_port,
668  ({
669  cb (pool_elt_at_index(pm->punt_client_pool, pci), ctx);
670  }));
671  /* *INDENT-ON* */
672  break;
673  }
674  case PUNT_TYPE_IP_PROTO:
675  {
676  u32 pci, key;
677 
678  /* *INDENT-OFF* */
679  hash_foreach(key, pci, pm->db.clients_by_ip_proto,
680  ({
681  cb (pool_elt_at_index(pm->punt_client_pool, pci), ctx);
682  }));
683  /* *INDENT-ON* */
684  break;
685  }
686  case PUNT_TYPE_EXCEPTION:
687  {
688  u32 *pci;
689 
691  {
692  if (~0 != *pci)
693  cb (pool_elt_at_index (pm->punt_client_pool, *pci), ctx);
694  }
695 
696  break;
697  }
698  }
699 }
700 
701 static u8 *
702 format_punt_client (u8 * s, va_list * args)
703 {
704  punt_client_t *pc = va_arg (*args, punt_client_t *);
705 
706  s = format (s, " punt ");
707 
708  switch (pc->reg.type)
709  {
710  case PUNT_TYPE_L4:
711  s = format (s, "%U %U port %d",
714  pc->reg.punt.l4.port);
715  break;
716  case PUNT_TYPE_IP_PROTO:
717  s = format (s, "%U %U",
720  break;
721  case PUNT_TYPE_EXCEPTION:
722  s = format (s, " %U", format_vlib_punt_reason,
723  pc->reg.punt.exception.reason);
724  break;
725  }
726 
727  s = format (s, " to socket %s \n", pc->caddr.sun_path);
728 
729  return (s);
730 }
731 
732 static walk_rc_t
734 {
735  vlib_cli_output (ctx, "%U", format_punt_client, pc);
736 
737  return (WALK_CONTINUE);
738 }
739 
740 static clib_error_t *
742  unformat_input_t * input__, vlib_cli_command_t * cmd)
743 {
744  unformat_input_t line_input, *input = &line_input;
745  clib_error_t *error = NULL;
746  punt_type_t pt;
747 
748  pt = PUNT_TYPE_L4;
749 
750  if (!unformat_user (input__, unformat_line_input, input))
751  return 0;
752 
754  {
755  if (unformat (input, "exception"))
756  pt = PUNT_TYPE_EXCEPTION;
757  else if (unformat (input, "l4"))
758  pt = PUNT_TYPE_L4;
759  else if (unformat (input, "ip"))
760  pt = PUNT_TYPE_IP_PROTO;
761  else
762  {
763  error = clib_error_return (0, "parse error: '%U'",
764  format_unformat_error, input);
765  goto done;
766  }
767  }
768 
770 
771 done:
772  unformat_free (input);
773  return (error);
774 }
775 
776 /*?
777  *
778  * @cliexpar
779  * @cliexcmd{show punt socket ipv4}
780  ?*/
781 /* *INDENT-OFF* */
782 VLIB_CLI_COMMAND (show_punt_socket_registration_command, static) =
783 {
784  .path = "show punt socket registrations",
785  .function = punt_socket_show_cmd,
786  .short_help = "show punt socket registrations [l4|exception]",
787  .is_mp_safe = 1,
788 };
789 /* *INDENT-ON* */
790 
791 clib_error_t *
793 {
794  clib_error_t *error = NULL;
795  punt_main_t *pm = &punt_main;
797 
798  pm->is_configured = false;
800  vlib_get_node_by_name (vm, (u8 *) "interface-output");
801 
802  if ((error = vlib_call_init_function (vm, punt_init)))
803  return error;
804 
805  pm->hdl = vlib_punt_client_register ("ip-punt");
806 
809 
810  return (error);
811 }
812 
814 
815 static clib_error_t *
817 {
818  punt_main_t *pm = &punt_main;
819  char *socket_path = 0;
820 
822  {
823  if (unformat (input, "socket %s", &socket_path))
824  strncpy (pm->sun_path, socket_path, UNIX_PATH_MAX - 1);
825  else
826  return clib_error_return (0, "unknown input `%U'",
827  format_unformat_error, input);
828  }
829 
830  if (socket_path == 0)
831  return 0;
832 
833  /* UNIX domain socket */
834  struct sockaddr_un addr;
835  if ((pm->socket_fd = socket (AF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK, 0)) == -1)
836  {
837  return clib_error_return (0, "socket error");
838  }
839 
840  clib_memset (&addr, 0, sizeof (addr));
841  addr.sun_family = AF_UNIX;
842  if (*socket_path == '\0')
843  {
844  *addr.sun_path = '\0';
845  strncpy (addr.sun_path + 1, socket_path + 1,
846  sizeof (addr.sun_path) - 2);
847  }
848  else
849  {
850  strncpy (addr.sun_path, socket_path, sizeof (addr.sun_path) - 1);
851  unlink (socket_path);
852  }
853 
854  if (bind (pm->socket_fd, (struct sockaddr *) &addr, sizeof (addr)) == -1)
855  {
856  return clib_error_return (0, "bind error");
857  }
858 
859  int n_bytes = 0x10000;
860 
861  if (setsockopt
862  (pm->socket_fd, SOL_SOCKET, SO_SNDBUF, &n_bytes,
863  sizeof (n_bytes)) == -1)
864  {
865  return clib_error_return (0, "setsockopt error");
866  }
867 
868  /* Register socket */
870  clib_file_t template = { 0 };
872  template.file_descriptor = pm->socket_fd;
873  template.description = format (0, "%s", socket_path);
874  pm->clib_file_index = clib_file_add (fm, &template);
875 
876  pm->is_configured = true;
877 
878  return 0;
879 }
880 
882 
883 /*
884  * fd.io coding-style-patch-verification: ON
885  *
886  * Local Variables:
887  * eval: (c-set-style "gnu")
888  * End:
889  */
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
#define hash_unset(h, key)
Definition: hash.h:261
void ip6_register_protocol(u32 protocol, u32 node_index)
Definition: ip6_forward.c:1581
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:1593
static clib_error_t * punt_config(vlib_main_t *vm, unformat_input_t *input)
Definition: punt.c:816
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: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
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:989
static walk_rc_t punt_client_show_one(const punt_client_t *pc, void *ctx)
Definition: punt.c:733
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:1865
enum ip_address_family_t_ ip_address_family_t
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
static clib_error_t * punt_socket_register_cmd(vlib_main_t *vm, unformat_input_t *input__, vlib_cli_command_t *cmd)
Definition: punt.c:516
#define fm
enum walk_rc_t_ walk_rc_t
Walk return code.
static clib_error_t * punt_socket_deregister_cmd(vlib_main_t *vm, unformat_input_t *input__, vlib_cli_command_t *cmd)
Definition: punt.c:590
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
#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
static clib_error_t * punt_cli(vlib_main_t *vm, unformat_input_t *input__, vlib_cli_command_t *cmd)
Definition: punt.c:426
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
unformat_function_t unformat_line_input
Definition: format.h:283
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 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
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:621
u16 port
Definition: punt.api:40
u8 * format_ip_address_family(u8 *s, va_list *args)
Definition: ip.c:289
static clib_error_t * punt_init(vlib_main_t *vm)
Definition: punt.c:634
static clib_error_t * punt_socket_show_cmd(vlib_main_t *vm, unformat_input_t *input__, vlib_cli_command_t *cmd)
Definition: punt.c:741
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
vlib_main_t * vm
Definition: buffer.c:323
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
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
Definition: node.c:45
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:161
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 vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
u32 * clients_by_exception
Definition: punt.h:110
void tcp_punt_unknown(vlib_main_t *vm, u8 is_ip4, u8 is_add)
Definition: tcp.c:1645
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
static void unformat_free(unformat_input_t *i)
Definition: format.h:163
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:247
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:792
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
#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:772
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:1877
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:656
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