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