FD.io VPP  v18.07.1-19-g511ce25
Vector Packet Processing
nat64_cli.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 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  * @file
17  * @brief NAT64 CLI
18  */
19 
20 #include <nat/nat64.h>
21 #include <nat/nat.h>
22 #include <nat/nat_inlines.h>
23 #include <vnet/fib/fib_table.h>
24 
25 static clib_error_t *
27  unformat_input_t * input,
28  vlib_cli_command_t * cmd)
29 {
30  unformat_input_t _line_input, *line_input = &_line_input;
31  ip4_address_t start_addr, end_addr, this_addr;
32  u32 start_host_order, end_host_order;
33  int i, count, rv;
34  u32 vrf_id = ~0;
35  u8 is_add = 1;
36  clib_error_t *error = 0;
37 
38  /* Get a line of input. */
39  if (!unformat_user (input, unformat_line_input, line_input))
40  return 0;
41 
42  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
43  {
44  if (unformat (line_input, "%U - %U",
45  unformat_ip4_address, &start_addr,
46  unformat_ip4_address, &end_addr))
47  ;
48  else if (unformat (line_input, "tenant-vrf %u", &vrf_id))
49  ;
50  else if (unformat (line_input, "%U", unformat_ip4_address, &start_addr))
51  end_addr = start_addr;
52  else if (unformat (line_input, "del"))
53  is_add = 0;
54  else
55  {
56  error = clib_error_return (0, "unknown input '%U'",
57  format_unformat_error, line_input);
58  goto done;
59  }
60  }
61 
62  start_host_order = clib_host_to_net_u32 (start_addr.as_u32);
63  end_host_order = clib_host_to_net_u32 (end_addr.as_u32);
64 
65  if (end_host_order < start_host_order)
66  {
67  error = clib_error_return (0, "end address less than start address");
68  goto done;
69  }
70 
71  count = (end_host_order - start_host_order) + 1;
72  this_addr = start_addr;
73 
74  for (i = 0; i < count; i++)
75  {
76  rv = nat64_add_del_pool_addr (&this_addr, vrf_id, is_add);
77 
78  switch (rv)
79  {
80  case VNET_API_ERROR_NO_SUCH_ENTRY:
81  error =
82  clib_error_return (0, "NAT64 pool address %U not exist.",
83  format_ip4_address, &this_addr);
84  goto done;
85  case VNET_API_ERROR_VALUE_EXIST:
86  error =
87  clib_error_return (0, "NAT64 pool address %U exist.",
88  format_ip4_address, &this_addr);
89  goto done;
90  default:
91  break;
92 
93  }
94  increment_v4_address (&this_addr);
95  }
96 
97 done:
98  unformat_free (line_input);
99 
100  return error;
101 }
102 
103 static int
105 {
106  vlib_main_t *vm = ctx;
107 
108  if (ap->fib_index != ~0)
109  {
110  fib_table_t *fib;
112  if (!fib)
113  return -1;
114  vlib_cli_output (vm, " %U tenant VRF: %u", format_ip4_address,
115  &ap->addr, fib->ft_table_id);
116  }
117  else
118  vlib_cli_output (vm, " %U", format_ip4_address, &ap->addr);
119 
120 #define _(N, i, n, s) \
121  vlib_cli_output (vm, " %d busy %s ports", ap->busy_##n##_ports, s);
123 #undef _
124  return 0;
125 }
126 
127 static clib_error_t *
129  unformat_input_t * input,
130  vlib_cli_command_t * cmd)
131 {
132  vlib_cli_output (vm, "NAT64 pool:");
134 
135  return 0;
136 }
137 
138 static clib_error_t *
141  input, vlib_cli_command_t * cmd)
142 {
143  unformat_input_t _line_input, *line_input = &_line_input;
144  vnet_main_t *vnm = vnet_get_main ();
145  clib_error_t *error = 0;
146  u32 sw_if_index;
147  u32 *inside_sw_if_indices = 0;
148  u32 *outside_sw_if_indices = 0;
149  u8 is_add = 1;
150  int i, rv;
151 
152  /* Get a line of input. */
153  if (!unformat_user (input, unformat_line_input, line_input))
154  return 0;
155 
156  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
157  {
158  if (unformat (line_input, "in %U", unformat_vnet_sw_interface,
159  vnm, &sw_if_index))
160  vec_add1 (inside_sw_if_indices, sw_if_index);
161  else if (unformat (line_input, "out %U", unformat_vnet_sw_interface,
162  vnm, &sw_if_index))
163  vec_add1 (outside_sw_if_indices, sw_if_index);
164  else if (unformat (line_input, "del"))
165  is_add = 0;
166  else
167  {
168  error = clib_error_return (0, "unknown input '%U'",
169  format_unformat_error, line_input);
170  goto done;
171  }
172  }
173 
174  if (vec_len (inside_sw_if_indices))
175  {
176  for (i = 0; i < vec_len (inside_sw_if_indices); i++)
177  {
178  sw_if_index = inside_sw_if_indices[i];
179  rv = nat64_add_del_interface (sw_if_index, 1, is_add);
180  switch (rv)
181  {
182  case VNET_API_ERROR_NO_SUCH_ENTRY:
183  error =
184  clib_error_return (0, "%U NAT64 feature not enabled.",
186  sw_if_index);
187  goto done;
188  case VNET_API_ERROR_VALUE_EXIST:
189  error =
190  clib_error_return (0, "%U NAT64 feature already enabled.",
192  vnm, sw_if_index);
193  goto done;
194  case VNET_API_ERROR_INVALID_VALUE:
195  case VNET_API_ERROR_INVALID_VALUE_2:
196  error =
198  "%U NAT64 feature enable/disable failed.",
200  sw_if_index);
201  goto done;
202  default:
203  break;
204 
205  }
206  }
207  }
208 
209  if (vec_len (outside_sw_if_indices))
210  {
211  for (i = 0; i < vec_len (outside_sw_if_indices); i++)
212  {
213  sw_if_index = outside_sw_if_indices[i];
214  rv = nat64_add_del_interface (sw_if_index, 0, is_add);
215  switch (rv)
216  {
217  case VNET_API_ERROR_NO_SUCH_ENTRY:
218  error =
219  clib_error_return (0, "%U NAT64 feature not enabled.",
221  sw_if_index);
222  goto done;
223  case VNET_API_ERROR_VALUE_EXIST:
224  error =
225  clib_error_return (0, "%U NAT64 feature already enabled.",
227  sw_if_index);
228  goto done;
229  case VNET_API_ERROR_INVALID_VALUE:
230  case VNET_API_ERROR_INVALID_VALUE_2:
231  error =
233  "%U NAT64 feature enable/disable failed.",
235  sw_if_index);
236  goto done;
237  default:
238  break;
239 
240  }
241  }
242  }
243 
244 done:
245  unformat_free (line_input);
246  vec_free (inside_sw_if_indices);
247  vec_free (outside_sw_if_indices);
248 
249  return error;
250 }
251 
252 static int
254 {
255  vlib_main_t *vm = ctx;
256  vnet_main_t *vnm = vnet_get_main ();
257 
258  vlib_cli_output (vm, " %U %s", format_vnet_sw_if_index_name, vnm,
259  i->sw_if_index,
261  && nat_interface_is_outside (i)) ? "in out" :
262  nat_interface_is_inside (i) ? "in" : "out");
263  return 0;
264 }
265 
266 static clib_error_t *
269  input, vlib_cli_command_t * cmd)
270 {
271  vlib_cli_output (vm, "NAT64 interfaces:");
273 
274  return 0;
275 }
276 
277 static clib_error_t *
279  vm,
281  * input, vlib_cli_command_t * cmd)
282 {
283  unformat_input_t _line_input, *line_input = &_line_input;
284  clib_error_t *error = 0;
285  u8 is_add = 1;
286  ip6_address_t in_addr;
287  ip4_address_t out_addr;
288  u32 in_port = 0;
289  u32 out_port = 0;
290  u32 vrf_id = 0, protocol;
291  snat_protocol_t proto = 0;
292  u8 p = 0;
293  int rv;
294 
295  if (!unformat_user (input, unformat_line_input, line_input))
296  return 0;
297 
298  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
299  {
300  if (unformat (line_input, "%U %u", unformat_ip6_address,
301  &in_addr, &in_port))
302  ;
303  else if (unformat (line_input, "%U %u", unformat_ip4_address,
304  &out_addr, &out_port))
305  ;
306  else if (unformat (line_input, "vrf %u", &vrf_id))
307  ;
308  else if (unformat (line_input, "%U", unformat_snat_protocol, &proto))
309  ;
310  else
311  if (unformat
312  (line_input, "%U %U %u", unformat_ip6_address, &in_addr,
313  unformat_ip4_address, &out_addr, &protocol))
314  p = (u8) protocol;
315  else if (unformat (line_input, "del"))
316  is_add = 0;
317  else
318  {
319  error = clib_error_return (0, "unknown input: '%U'",
320  format_unformat_error, line_input);
321  goto done;
322  }
323  }
324 
325  if (!p)
326  {
327  if (!in_port)
328  {
329  error =
330  clib_error_return (0, "inside port and address must be set");
331  goto done;
332  }
333 
334  if (!out_port)
335  {
336  error =
337  clib_error_return (0, "outside port and address must be set");
338  goto done;
339  }
340 
341  p = snat_proto_to_ip_proto (proto);
342  }
343 
344  rv =
345  nat64_add_del_static_bib_entry (&in_addr, &out_addr, (u16) in_port,
346  (u16) out_port, p, vrf_id, is_add);
347 
348  switch (rv)
349  {
350  case VNET_API_ERROR_NO_SUCH_ENTRY:
351  error = clib_error_return (0, "NAT64 BIB entry not exist.");
352  goto done;
353  case VNET_API_ERROR_VALUE_EXIST:
354  error = clib_error_return (0, "NAT64 BIB entry exist.");
355  goto done;
356  case VNET_API_ERROR_UNSPECIFIED:
357  error = clib_error_return (0, "Crerate NAT64 BIB entry failed.");
358  goto done;
359  case VNET_API_ERROR_INVALID_VALUE:
360  error =
361  clib_error_return (0, "Outside addres %U and port %u already in use.",
362  format_ip4_address, &out_addr, out_port);
363  goto done;
364  case VNET_API_ERROR_INVALID_VALUE_2:
365  error = clib_error_return (0, "Invalid outside port.");
366  default:
367  break;
368  }
369 
370 done:
371  unformat_free (line_input);
372 
373  return error;
374 }
375 
376 static int
377 nat64_cli_bib_walk (nat64_db_bib_entry_t * bibe, void *ctx)
378 {
379  vlib_main_t *vm = ctx;
380  fib_table_t *fib;
381 
382  fib = fib_table_get (bibe->fib_index, FIB_PROTOCOL_IP6);
383  if (!fib)
384  return -1;
385 
386  switch (bibe->proto)
387  {
388  case IP_PROTOCOL_ICMP:
389  case IP_PROTOCOL_TCP:
390  case IP_PROTOCOL_UDP:
391  vlib_cli_output (vm, " %U %u %U %u protocol %U vrf %u %s %u sessions",
392  format_ip6_address, &bibe->in_addr,
393  clib_net_to_host_u16 (bibe->in_port),
394  format_ip4_address, &bibe->out_addr,
395  clib_net_to_host_u16 (bibe->out_port),
397  ip_proto_to_snat_proto (bibe->proto), fib->ft_table_id,
398  bibe->is_static ? "static" : "dynamic", bibe->ses_num);
399  break;
400  default:
401  vlib_cli_output (vm, " %U %U protocol %u vrf %u %s %u sessions",
402  format_ip6_address, &bibe->in_addr,
403  format_ip4_address, &bibe->out_addr,
404  bibe->proto, fib->ft_table_id,
405  bibe->is_static ? "static" : "dynamic", bibe->ses_num);
406  }
407  return 0;
408 }
409 
410 static clib_error_t *
412  unformat_input_t * input, vlib_cli_command_t * cmd)
413 {
414  nat64_main_t *nm = &nat64_main;
415  unformat_input_t _line_input, *line_input = &_line_input;
416  clib_error_t *error = 0;
417  u32 proto = ~0;
418  u8 p = 255;
419  nat64_db_t *db;
420 
421  if (!unformat_user (input, unformat_line_input, line_input))
422  return 0;
423 
424  if (unformat (line_input, "%U", unformat_snat_protocol, &proto))
425  p = snat_proto_to_ip_proto (proto);
426  else if (unformat (line_input, "unknown"))
427  p = 0;
428  else if (unformat (line_input, "all"))
429  ;
430  else
431  {
432  error = clib_error_return (0, "unknown input: '%U'",
433  format_unformat_error, line_input);
434  goto done;
435  }
436 
437  if (p == 255)
438  vlib_cli_output (vm, "NAT64 BIB entries:");
439  else
440  vlib_cli_output (vm, "NAT64 %U BIB entries:", format_snat_protocol,
441  proto);
442 
443  /* *INDENT-OFF* */
444  vec_foreach (db, nm->db)
446  /* *INDENT-ON* */
447 
448 done:
449  unformat_free (line_input);
450 
451  return error;
452 }
453 
454 static clib_error_t *
456  vlib_cli_command_t * cmd)
457 {
458  unformat_input_t _line_input, *line_input = &_line_input;
459  clib_error_t *error = 0;
460  u32 timeout, tcp_trans, tcp_est, tcp_incoming_syn;
461 
462  tcp_trans = nat64_get_tcp_trans_timeout ();
463  tcp_est = nat64_get_tcp_est_timeout ();
464  tcp_incoming_syn = nat64_get_tcp_incoming_syn_timeout ();
465 
466  if (!unformat_user (input, unformat_line_input, line_input))
467  return 0;
468 
469  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
470  {
471  if (unformat (line_input, "udp %u", &timeout))
472  {
473  if (nat64_set_udp_timeout (timeout))
474  {
475  error = clib_error_return (0, "Invalid UDP timeout value");
476  goto done;
477  }
478  }
479  else if (unformat (line_input, "icmp %u", &timeout))
480  {
481  if (nat64_set_icmp_timeout (timeout))
482  {
483  error = clib_error_return (0, "Invalid ICMP timeout value");
484  goto done;
485  }
486  }
487  else if (unformat (line_input, "tcp-trans %u", &tcp_trans))
488  {
489  if (nat64_set_tcp_timeouts (tcp_trans, tcp_est, tcp_incoming_syn))
490  {
491  error =
493  "Invalid TCP transitory timeouts value");
494  goto done;
495  }
496  }
497  else if (unformat (line_input, "tcp-est %u", &tcp_est))
498  {
499  if (nat64_set_tcp_timeouts (tcp_trans, tcp_est, tcp_incoming_syn))
500  {
501  error =
503  "Invalid TCP established timeouts value");
504  goto done;
505  }
506  }
507  else
508  if (unformat (line_input, "tcp-incoming-syn %u", &tcp_incoming_syn))
509  {
510  if (nat64_set_tcp_timeouts (tcp_trans, tcp_est, tcp_incoming_syn))
511  {
512  error =
514  "Invalid TCP incoming SYN timeouts value");
515  goto done;
516  }
517  }
518  else if (unformat (line_input, "reset"))
519  {
522  nat64_set_tcp_timeouts (0, 0, 0);
523  }
524  else
525  {
526  error = clib_error_return (0, "unknown input '%U'",
527  format_unformat_error, line_input);
528  goto done;
529  }
530  }
531 
532 done:
533  unformat_free (line_input);
534 
535  return error;
536 }
537 
538 static clib_error_t *
540  vlib_cli_command_t * cmd)
541 {
542  vlib_cli_output (vm, "NAT64 session timeouts:");
543  vlib_cli_output (vm, " UDP %usec", nat64_get_udp_timeout ());
544  vlib_cli_output (vm, " ICMP %usec", nat64_get_icmp_timeout ());
545  vlib_cli_output (vm, " TCP transitory %usec",
547  vlib_cli_output (vm, " TCP established %usec",
549  vlib_cli_output (vm, " TCP incoming SYN %usec",
551 
552  return 0;
553 }
554 
556 {
560 
561 static int
562 nat64_cli_st_walk (nat64_db_st_entry_t * ste, void *arg)
563 {
565  vlib_main_t *vm = ctx->vm;
566  nat64_db_bib_entry_t *bibe;
567  fib_table_t *fib;
568 
569  bibe = nat64_db_bib_entry_by_index (ctx->db, ste->proto, ste->bibe_index);
570  if (!bibe)
571  return -1;
572 
573  fib = fib_table_get (bibe->fib_index, FIB_PROTOCOL_IP6);
574  if (!fib)
575  return -1;
576 
577  u32 vrf_id = fib->ft_table_id;
578 
579  if (ste->proto == IP_PROTOCOL_ICMP)
580  vlib_cli_output (vm, " %U %U %u %U %U %u protocol %U vrf %u",
581  format_ip6_address, &bibe->in_addr,
582  format_ip6_address, &ste->in_r_addr,
583  clib_net_to_host_u16 (bibe->in_port),
584  format_ip4_address, &bibe->out_addr,
585  format_ip4_address, &ste->out_r_addr,
586  clib_net_to_host_u16 (bibe->out_port),
588  ip_proto_to_snat_proto (bibe->proto), vrf_id);
589  else if (ste->proto == IP_PROTOCOL_TCP || ste->proto == IP_PROTOCOL_UDP)
590  vlib_cli_output (vm, " %U %u %U %u %U %u %U %u protcol %U vrf %u",
591  format_ip6_address, &bibe->in_addr,
592  clib_net_to_host_u16 (bibe->in_port),
593  format_ip6_address, &ste->in_r_addr,
594  clib_net_to_host_u16 (ste->r_port),
595  format_ip4_address, &bibe->out_addr,
596  clib_net_to_host_u16 (bibe->out_port),
597  format_ip4_address, &ste->out_r_addr,
598  clib_net_to_host_u16 (ste->r_port),
600  ip_proto_to_snat_proto (bibe->proto), vrf_id);
601  else
602  vlib_cli_output (vm, " %U %U %U %U protocol %u vrf %u",
603  format_ip6_address, &bibe->in_addr,
604  format_ip6_address, &ste->in_r_addr,
605  format_ip4_address, &bibe->out_addr,
606  format_ip4_address, &ste->out_r_addr,
607  bibe->proto, vrf_id);
608 
609  return 0;
610 }
611 
612 static clib_error_t *
614  unformat_input_t * input, vlib_cli_command_t * cmd)
615 {
616  nat64_main_t *nm = &nat64_main;
617  unformat_input_t _line_input, *line_input = &_line_input;
618  clib_error_t *error = 0;
619  u32 proto = ~0;
620  u8 p = 255;
621  nat64_db_t *db;
623  .vm = vm,
624  };
625 
626  if (!unformat_user (input, unformat_line_input, line_input))
627  return 0;
628 
629  if (unformat (line_input, "%U", unformat_snat_protocol, &proto))
630  p = snat_proto_to_ip_proto (proto);
631  else if (unformat (line_input, "unknown"))
632  p = 0;
633  else if (unformat (line_input, "all"))
634  ;
635  else
636  {
637  error = clib_error_return (0, "unknown input: '%U'",
638  format_unformat_error, line_input);
639  goto done;
640  }
641 
642  if (p == 255)
643  vlib_cli_output (vm, "NAT64 sessions:");
644  else
645  vlib_cli_output (vm, "NAT64 %U sessions:", format_snat_protocol, proto);
646  /* *INDENT-OFF* */
647  vec_foreach (db, nm->db)
648  {
649  ctx.db = db;
650  nat64_db_st_walk (db, p, nat64_cli_st_walk, &ctx);
651  }
652  /* *INDENT-ON* */
653 
654 done:
655  unformat_free (line_input);
656 
657  return error;
658 }
659 
660 static clib_error_t *
662  vlib_cli_command_t * cmd)
663 {
664  vnet_main_t *vnm = vnet_get_main ();
665  clib_error_t *error = 0;
666  unformat_input_t _line_input, *line_input = &_line_input;
667  u8 is_add = 1;
668  u32 vrf_id = 0, sw_if_index = ~0;
670  u32 plen = 0;
671  int rv;
672 
673  if (!unformat_user (input, unformat_line_input, line_input))
674  return 0;
675 
676  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
677  {
678  if (unformat
679  (line_input, "%U/%u", unformat_ip6_address, &prefix, &plen))
680  ;
681  else if (unformat (line_input, "tenant-vrf %u", &vrf_id))
682  ;
683  else if (unformat (line_input, "del"))
684  is_add = 0;
685  else
686  if (unformat
687  (line_input, "interface %U", unformat_vnet_sw_interface, vnm,
688  &sw_if_index))
689  ;
690  else
691  {
692  error = clib_error_return (0, "unknown input: '%U'",
693  format_unformat_error, line_input);
694  goto done;
695  }
696  }
697 
698  if (!plen)
699  {
700  error = clib_error_return (0, "NAT64 prefix must be set.");
701  goto done;
702  }
703 
704  rv = nat64_add_del_prefix (&prefix, (u8) plen, vrf_id, is_add);
705 
706  switch (rv)
707  {
708  case VNET_API_ERROR_NO_SUCH_ENTRY:
709  error = clib_error_return (0, "NAT64 prefix not exist.");
710  goto done;
711  case VNET_API_ERROR_INVALID_VALUE:
712  error = clib_error_return (0, "Invalid prefix length.");
713  goto done;
714  default:
715  break;
716  }
717 
718  /*
719  * Add RX interface route, whenNAT isn't running on the real input
720  * interface
721  */
722  if (sw_if_index != ~0)
723  {
724  u32 fib_index;
725  fib_prefix_t fibpfx = {
726  .fp_len = plen,
727  .fp_proto = FIB_PROTOCOL_IP6,
728  .fp_addr = {
729  .ip6 = prefix}
730  };
731 
732  if (is_add)
733  {
734  fib_index =
736  vrf_id, FIB_SOURCE_PLUGIN_HI);
737  fib_table_entry_update_one_path (fib_index, &fibpfx,
741  sw_if_index, ~0, 0,
743  }
744  else
745  {
746  fib_index = fib_table_find (FIB_PROTOCOL_IP6, vrf_id);
747  fib_table_entry_path_remove (fib_index, &fibpfx,
750  sw_if_index, ~0, 1,
754  }
755  }
756 
757 done:
758  unformat_free (line_input);
759 
760  return error;
761 }
762 
763 static int
765 {
766  vlib_main_t *vm = ctx;
767 
768  vlib_cli_output (vm, " %U/%u tenant-vrf %u",
769  format_ip6_address, &p->prefix, p->plen, p->vrf_id);
770 
771  return 0;
772 }
773 
774 static clib_error_t *
776  unformat_input_t * input,
777  vlib_cli_command_t * cmd)
778 {
779  vlib_cli_output (vm, "NAT64 prefix:");
781 
782  return 0;
783 }
784 
785 static clib_error_t *
787  unformat_input_t * input,
788  vlib_cli_command_t * cmd)
789 {
790  vnet_main_t *vnm = vnet_get_main ();
791  unformat_input_t _line_input, *line_input = &_line_input;
792  u32 sw_if_index;
793  int rv;
794  int is_add = 1;
795  clib_error_t *error = 0;
796 
797  /* Get a line of input. */
798  if (!unformat_user (input, unformat_line_input, line_input))
799  return 0;
800 
801  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
802  {
803  if (unformat
804  (line_input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index));
805  else if (unformat (line_input, "del"))
806  is_add = 0;
807  else
808  {
809  error = clib_error_return (0, "unknown input '%U'",
810  format_unformat_error, line_input);
811  goto done;
812  }
813  }
814 
815  rv = nat64_add_interface_address (sw_if_index, is_add);
816 
817  switch (rv)
818  {
819  case VNET_API_ERROR_NO_SUCH_ENTRY:
820  error = clib_error_return (0, "entry not exist");
821  break;
822  case VNET_API_ERROR_VALUE_EXIST:
823  error = clib_error_return (0, "entry exist");
824  break;
825  default:
826  break;
827  }
828 
829 done:
830  unformat_free (line_input);
831 
832  return error;
833 }
834 
835 /* *INDENT-OFF* */
836 
837 /*?
838  * @cliexpar
839  * @cliexstart{nat64 add pool address}
840  * Add/delete NAT64 pool address.
841  * To add single NAT64 pool address use:
842  * vpp# nat64 add pool address 10.1.1.10
843  * To add NAT64 pool address range use:
844  * vpp# nat64 add pool address 10.1.1.2 - 10.1.1.5
845  * To add NAT64 pool address for specific tenant use:
846  * vpp# nat64 add pool address 10.1.1.100 tenant-vrf 100
847  * @cliexend
848 ?*/
849 VLIB_CLI_COMMAND (nat64_add_pool_address_command, static) = {
850  .path = "nat64 add pool address",
851  .short_help = "nat64 add pool address <ip4-range-start> [- <ip4-range-end>] "
852  "[tenant-vrf <vrf-id>] [del]",
854 };
855 
856 /*?
857  * @cliexpar
858  * @cliexstart{show nat64 pool}
859  * Show NAT64 pool.
860  * vpp# show nat64 pool
861  * NAT64 pool:
862  * 10.1.1.3 tenant VRF: 0
863  * 10.1.1.10 tenant VRF: 10
864  * @cliexend
865 ?*/
866 VLIB_CLI_COMMAND (show_nat64_pool_command, static) = {
867  .path = "show nat64 pool",
868  .short_help = "show nat64 pool",
869  .function = nat64_show_pool_command_fn,
870 };
871 
872 /*?
873  * @cliexpar
874  * @cliexstart{set interface nat64}
875  * Enable/disable NAT64 feature on the interface.
876  * To enable NAT64 feature with local (IPv6) network interface
877  * GigabitEthernet0/8/0 and external (IPv4) network interface
878  * GigabitEthernet0/a/0 use:
879  * vpp# set interface nat64 in GigabitEthernet0/8/0 out GigabitEthernet0/a/0
880  * @cliexend
881 ?*/
882 VLIB_CLI_COMMAND (set_interface_nat64_command, static) = {
883  .path = "set interface nat64",
884  .short_help = "set interface nat64 in|out <intfc> [del]",
886 };
887 
888 /*?
889  * @cliexpar
890  * @cliexstart{show nat64 interfaces}
891  * Show interfaces with NAT64 feature.
892  * To show interfaces with NAT64 feature use:
893  * vpp# show nat64 interfaces
894  * NAT64 interfaces:
895  * GigabitEthernet0/8/0 in
896  * GigabitEthernet0/a/0 out
897  * @cliexend
898 ?*/
899 VLIB_CLI_COMMAND (show_nat64_interfaces_command, static) = {
900  .path = "show nat64 interfaces",
901  .short_help = "show nat64 interfaces",
903 };
904 
905 /*?
906  * @cliexpar
907  * @cliexstart{nat64 add static bib}
908  * Add/delete NAT64 static BIB entry.
909  * To create NAT64 satatic BIB entry use:
910  * vpp# nat64 add static bib 2001:db8:c000:221:: 1234 10.1.1.3 5678 tcp
911  * vpp# nat64 add static bib 2001:db8:c000:221:: 1234 10.1.1.3 5678 udp vrf 10
912  * @cliexend
913 ?*/
914 VLIB_CLI_COMMAND (nat64_add_del_static_bib_command, static) = {
915  .path = "nat64 add static bib",
916  .short_help = "nat64 add static bib <ip6-addr> <port> <ip4-addr> <port> "
917  "tcp|udp|icmp [vfr <table-id>] [del]",
919 };
920 
921 /*?
922  * @cliexpar
923  * @cliexstart{show nat64 bib}
924  * Show NAT64 BIB entries.
925  * To show NAT64 TCP BIB entries use:
926  * vpp# show nat64 bib tcp
927  * NAT64 tcp BIB:
928  * fd01:1::2 6303 10.0.0.3 62303 tcp vrf 0 dynamic 1 sessions
929  * 2001:db8:c000:221:: 1234 10.1.1.3 5678 tcp vrf 0 static 2 sessions
930  * To show NAT64 UDP BIB entries use:
931  * vpp# show nat64 bib udp
932  * NAT64 udp BIB:
933  * fd01:1::2 6304 10.0.0.3 10546 udp vrf 0 dynamic 10 sessions
934  * 2001:db8:c000:221:: 1234 10.1.1.3 5678 udp vrf 10 static 0 sessions
935  * To show NAT64 ICMP BIB entries use:
936  * vpp# show nat64 bib icmp
937  * NAT64 icmp BIB:
938  * fd01:1::2 6305 10.0.0.3 63209 icmp vrf 10 dynamic 1 sessions
939  * @cliexend
940 ?*/
941 VLIB_CLI_COMMAND (show_nat64_bib_command, static) = {
942  .path = "show nat64 bib",
943  .short_help = "show nat64 bib all|tcp|udp|icmp|unknown",
944  .function = nat64_show_bib_command_fn,
945 };
946 
947 /*?
948  * @cliexpar
949  * @cliexstart{set nat64 timeouts}
950  * Set NAT64 session timeouts (in seconds).
951  * To set NAT64 session timeoutes use use:
952  * vpp# set nat64 timeouts udp 200 icmp 30 tcp-trans 250 tcp-est 7450
953  * To reset NAT64 session timeoutes to default values use:
954  * vpp# set nat64 timeouts reset
955  * @cliexend
956 ?*/
957 VLIB_CLI_COMMAND (set_nat64_timeouts_command, static) = {
958  .path = "set nat64 timeouts",
959  .short_help = "set nat64 timeouts udp <sec> icmp <sec> tcp-trans <sec> "
960  "tcp-est <sec> tcp-incoming-syn <sec> | reset",
961  .function = nat64_set_timeouts_command_fn,
962 };
963 
964 /*?
965  * @cliexpar
966  * @cliexstart{show nat64 timeoutss}
967  * Show NAT64 session timeouts:
968  * vpp# show nat64 timeouts
969  * NAT64 session timeouts:
970  * UDP 300sec
971  * ICMP 60sec
972  * TCP transitory 240sec
973  * TCP established 7440sec
974  * TCP incoming SYN 6sec
975  * @cliexend
976 ?*/
977 VLIB_CLI_COMMAND (show_nat64_timeouts_command, static) = {
978  .path = "show nat64 timeouts",
979  .short_help = "show nat64 timeouts",
980  .function = nat64_show_timeouts_command_fn,
981 };
982 
983 /*?
984  * @cliexpar
985  * @cliexstart{show nat64 session table}
986  * Show NAT64 session table.
987  * To show NAT64 TCP session table use:
988  * vpp# show nat64 session table tcp
989  * NAT64 tcp session table:
990  * fd01:1::2 6303 64:ff9b::ac10:202 20 10.0.0.3 62303 172.16.2.2 20 tcp vrf 0
991  * fd01:3::2 6303 64:ff9b::ac10:202 20 10.0.10.3 21300 172.16.2.2 20 tcp vrf 10
992  * To show NAT64 UDP session table use:
993  * #vpp show nat64 session table udp
994  * NAT64 udp session table:
995  * fd01:1::2 6304 64:ff9b::ac10:202 20 10.0.0.3 10546 172.16.2.2 20 udp vrf 0
996  * fd01:3::2 6304 64:ff9b::ac10:202 20 10.0.10.3 58627 172.16.2.2 20 udp vrf 10
997  * fd01:1::2 1235 64:ff9b::a00:3 4023 10.0.0.3 24488 10.0.0.3 4023 udp vrf 0
998  * fd01:1::3 23 64:ff9b::a00:3 24488 10.0.0.3 4023 10.0.0.3 24488 udp vrf 0
999  * To show NAT64 ICMP session table use:
1000  * #vpp show nat64 session table icmp
1001  * NAT64 icmp session table:
1002  * fd01:1::2 64:ff9b::ac10:202 6305 10.0.0.3 172.16.2.2 63209 icmp vrf 0
1003  * @cliexend
1004 ?*/
1005 VLIB_CLI_COMMAND (show_nat64_st_command, static) = {
1006  .path = "show nat64 session table",
1007  .short_help = "show nat64 session table all|tcp|udp|icmp|unknown",
1008  .function = nat64_show_st_command_fn,
1009 };
1010 
1011 /*?
1012  * @cliexpar
1013  * @cliexstart{nat64 add prefix}
1014  * Set NAT64 prefix for generating IPv6 representations of IPv4 addresses.
1015  * To set NAT64 global prefix use:
1016  * vpp# nat64 add prefix 2001:db8::/32
1017  * To set NAT64 prefix for specific tenant use:
1018  * vpp# nat64 add prefix 2001:db8:122:300::/56 tenant-vrf 10
1019  * @cliexend
1020 ?*/
1021 VLIB_CLI_COMMAND (nat64_add_del_prefix_command, static) = {
1022  .path = "nat64 add prefix",
1023  .short_help = "nat64 add prefix <ip6-prefix>/<plen> [tenant-vrf <vrf-id>] "
1024  "[del] [interface <interface]",
1025  .function = nat64_add_del_prefix_command_fn,
1026 };
1027 
1028 /*?
1029  * @cliexpar
1030  * @cliexstart{show nat64 prefix}
1031  * Show NAT64 prefix.
1032  * To show NAT64 prefix use:
1033  * vpp# show nat64 prefix
1034  * NAT64 prefix:
1035  * 2001:db8::/32 tenant-vrf 0
1036  * 2001:db8:122:300::/56 tenant-vrf 10
1037  * @cliexend
1038 ?*/
1039 VLIB_CLI_COMMAND (show_nat64_prefix_command, static) = {
1040  .path = "show nat64 prefix",
1041  .short_help = "show nat64 prefix",
1042  .function = nat64_show_prefix_command_fn,
1043 };
1044 
1045 /*?
1046  * @cliexpar
1047  * @cliexstart{nat64 add interface address}
1048  * Add/delete NAT64 pool address from specific (DHCP addressed) interface.
1049  * To add NAT64 pool address from specific interface use:
1050  * vpp# nat64 add interface address GigabitEthernet0/8/0
1051  * @cliexend
1052 ?*/
1053 VLIB_CLI_COMMAND (nat64_add_interface_address_command, static) = {
1054  .path = "nat64 add interface address",
1055  .short_help = "nat64 add interface address <interface> [del]",
1057 };
1058 /* *INDENT-ON* */
1059 
1060 /*
1061  * fd.io coding-style-patch-verification: ON
1062  *
1063  * Local Variables:
1064  * eval: (c-set-style "gnu")
1065  * End:
1066  */
u32 nat64_get_icmp_timeout(void)
Get ICMP session timeout.
Definition: nat64.c:790
static clib_error_t * nat64_show_bib_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat64_cli.c:411
nat64_db_t * db
BIB and session DB per thread.
Definition: nat64.h:83
int nat64_set_udp_timeout(u32 timeout)
Set UDP session timeout.
Definition: nat64.c:754
static clib_error_t * nat64_show_timeouts_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat64_cli.c:539
static int nat64_cli_pool_walk(snat_address_t *ap, void *ctx)
Definition: nat64_cli.c:104
u8 * format_snat_protocol(u8 *s, va_list *args)
Definition: nat.c:2439
ip6_address_t prefix
Definition: nat64.h:49
vnet_main_t * vnet_get_main(void)
Definition: misc.c:47
static int nat64_cli_interface_walk(snat_interface_t *i, void *ctx)
Definition: nat64_cli.c:253
int nat64_add_del_interface(u32 sw_if_index, u8 is_inside, u8 is_add)
Enable/disable NAT64 feature on the interface.
Definition: nat64.c:404
#define NULL
Definition: clib.h:55
int nat64_add_del_pool_addr(ip4_address_t *addr, u32 vrf_id, u8 is_add)
Add/delete address to NAT64 pool.
Definition: nat64.c:274
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:523
int i
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:983
unformat_function_t unformat_vnet_sw_interface
A path that result in received traffic being recieved/recirculated so that it appears to have arrived...
Definition: fib_types.h:339
int nat64_add_interface_address(u32 sw_if_index, int is_add)
NAT64 pool address from specific (DHCP addressed) interface.
Definition: nat64.c:363
int nat64_set_tcp_timeouts(u32 trans, u32 est, u32 incoming_syn)
Set TCP session timeouts.
Definition: nat64.c:798
format_function_t format_vnet_sw_if_index_name
unsigned char u8
Definition: types.h:56
#define nat_interface_is_outside(i)
Definition: nat.h:523
fib_node_index_t fib_table_entry_update_one_path(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags, dpo_proto_t next_hop_proto, const ip46_address_t *next_hop, u32 next_hop_sw_if_index, u32 next_hop_fib_index, u32 next_hop_weight, fib_mpls_label_t *next_hop_labels, fib_route_path_flags_t path_flags)
Update the entry to have just one path.
Definition: fib_table.c:772
static clib_error_t * nat64_add_del_pool_addr_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat64_cli.c:26
format_function_t format_ip4_address
Definition: format.h:81
unformat_function_t unformat_ip4_address
Definition: format.h:76
int nat64_set_icmp_timeout(u32 timeout)
Set ICMP session timeout.
Definition: nat64.c:777
A high priority source a plugin can use.
Definition: fib_entry.h:62
Aggregrate type for a prefix.
Definition: fib_types.h:193
#define clib_error_return(e, args...)
Definition: error.h:99
static int nat64_cli_bib_walk(nat64_db_bib_entry_t *bibe, void *ctx)
Definition: nat64_cli.c:377
unsigned int u32
Definition: types.h:88
static clib_error_t * nat64_add_interface_address_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat64_cli.c:786
u32 fib_table_find(fib_protocol_t proto, u32 table_id)
Get the index of the FIB for a Table-ID.
Definition: fib_table.c:1056
u16 fp_len
The mask length.
Definition: fib_types.h:197
Definition: fib_entry.h:275
unformat_function_t unformat_line_input
Definition: format.h:282
static clib_error_t * nat64_show_pool_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat64_cli.c:128
u32 nat64_get_udp_timeout(void)
Get UDP session timeout.
Definition: nat64.c:769
struct _unformat_input_t unformat_input_t
unsigned short u16
Definition: types.h:57
#define nat_interface_is_inside(i)
Definition: nat.h:522
void fib_table_unlock(u32 fib_index, fib_protocol_t proto, fib_source_t source)
Take a reference counting lock on the table.
Definition: fib_table.c:1228
unformat_function_t unformat_ip6_address
Definition: format.h:97
u32 nat64_get_tcp_est_timeout(void)
Get TCP established timeout.
Definition: nat64.c:829
struct nat64_cli_st_walk_ctx_t_ nat64_cli_st_walk_ctx_t
#define UNFORMAT_END_OF_INPUT
Definition: format.h:144
static u8 snat_proto_to_ip_proto(snat_protocol_t snat_proto)
Definition: nat_inlines.h:40
void nat64_pool_addr_walk(nat64_pool_addr_walk_fn_t fn, void *ctx)
Walk NAT64 pool.
Definition: nat64.c:348
u32 ft_table_id
Table ID (hash key) for this FIB.
Definition: fib_table.h:89
format_function_t format_ip6_address
Definition: format.h:99
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:339
int nat64_add_del_prefix(ip6_address_t *prefix, u8 plen, u32 vrf_id, u8 is_add)
Add/delete NAT64 prefix.
Definition: nat64.c:951
static clib_error_t * nat64_add_del_static_bib_command_fn(vlib_main_t *vm, unformat_input_t()*input, vlib_cli_command_t *cmd)
Definition: nat64_cli.c:278
u32 sw_if_index
Definition: nat.h:259
nat64_main_t nat64_main
Definition: nat64.c:28
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
u32 vrf_id
Definition: nat64.h:51
void nat64_db_st_walk(nat64_db_t *db, u8 proto, nat64_db_st_walk_fn_t fn, void *ctx)
Walk NAT64 session table.
Definition: nat64_db.c:321
u32 nat64_get_tcp_incoming_syn_timeout(void)
Get TCP incoming SYN timeout.
Definition: nat64.c:837
long ctx[MAX_CONNS]
Definition: main.c:126
u32 fib_table_find_or_create_and_lock(fib_protocol_t proto, u32 table_id, fib_source_t src)
Get the index of the FIB for a Table-ID.
Definition: fib_table.c:1115
nat64_db_bib_entry_t * nat64_db_bib_entry_by_index(nat64_db_t *db, u8 proto, u32 bibe_index)
Get BIB entry by index and protocol.
Definition: nat64_db.c:298
size_t count
Definition: vapi.c:46
void fib_table_entry_path_remove(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, dpo_proto_t next_hop_proto, const ip46_address_t *next_hop, u32 next_hop_sw_if_index, u32 next_hop_fib_index, u32 next_hop_weight, fib_route_path_flags_t path_flags)
remove one path to an entry (aka route) in the FIB.
Definition: fib_table.c:682
ip4_address_t addr
Definition: nat.h:195
void nat64_prefix_walk(nat64_prefix_walk_fn_t fn, void *ctx)
Walk NAT64 prefixes.
Definition: nat64.c:999
void nat64_interfaces_walk(nat64_interface_walk_fn_t fn, void *ctx)
Walk NAT64 interfaces.
Definition: nat64.c:488
static clib_error_t * nat64_interface_feature_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat64_cli.c:139
NAT64 global declarations.
void increment_v4_address(ip4_address_t *a)
Definition: nat.c:730
static u32 ip_proto_to_snat_proto(u8 ip_proto)
The NAT inline functions.
Definition: nat_inlines.h:25
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static void unformat_free(unformat_input_t *i)
Definition: format.h:162
static int nat64_cli_st_walk(nat64_db_st_entry_t *ste, void *arg)
Definition: nat64_cli.c:562
snat_protocol_t
Definition: nat.h:107
fib_table_t * fib_table_get(fib_node_index_t index, fib_protocol_t proto)
Get a pointer to a FIB table.
Definition: fib_table.c:27
typedef prefix
Definition: ip_types.api:40
uword unformat_snat_protocol(unformat_input_t *input, va_list *args)
Definition: nat.c:2425
static clib_error_t * nat64_show_st_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat64_cli.c:613
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
#define vec_foreach(var, vec)
Vector iterator.
static clib_error_t * nat64_add_del_prefix_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat64_cli.c:661
static clib_error_t * nat64_set_timeouts_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat64_cli.c:455
static int nat64_cli_prefix_walk(nat64_prefix_t *p, void *ctx)
Definition: nat64_cli.c:764
static clib_error_t * nat64_show_prefix_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat64_cli.c:775
void nat64_db_bib_walk(nat64_db_t *db, u8 proto, nat64_db_bib_walk_fn_t fn, void *ctx)
Walk NAT64 BIB.
Definition: nat64_db.c:247
int nat64_add_del_static_bib_entry(ip6_address_t *in_addr, ip4_address_t *out_addr, u16 in_port, u16 out_port, u8 proto, u32 vrf_id, u8 is_add)
Add/delete static NAT64 BIB entry.
Definition: nat64.c:625
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:681
u32 fib_index
Definition: nat.h:196
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
u32 nat64_get_tcp_trans_timeout(void)
Get TCP transitory timeout.
Definition: nat64.c:821
static clib_error_t * nat64_show_interfaces_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat64_cli.c:267
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:170
A protocol Independent FIB table.
Definition: fib_table.h:69