api: clean up use of deprecated flag
[vpp.git] / src / plugins / nat / nat64_cli.c
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 *
26 nat64_add_del_pool_addr_command_fn (vlib_main_t * vm,
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 (0, &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
104 nat64_cli_pool_walk (snat_address_t * ap, void *ctx)
105 {
106   vlib_main_t *vm = ctx;
107
108   if (ap->fib_index != ~0)
109     {
110       fib_table_t *fib;
111       fib = fib_table_get (ap->fib_index, FIB_PROTOCOL_IP6);
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);
122   foreach_nat_protocol
123 #undef _
124     return 0;
125 }
126
127 static clib_error_t *
128 nat64_show_pool_command_fn (vlib_main_t * vm,
129                             unformat_input_t * input,
130                             vlib_cli_command_t * cmd)
131 {
132   vlib_cli_output (vm, "NAT64 pool:");
133   nat64_pool_addr_walk (nat64_cli_pool_walk, vm);
134
135   return 0;
136 }
137
138 static clib_error_t *
139 nat64_interface_feature_command_fn (vlib_main_t * vm,
140                                     unformat_input_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.",
185                                    format_vnet_sw_if_index_name, vnm,
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.",
191                                    format_vnet_sw_if_index_name, vnm,
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 =
197                 clib_error_return (0,
198                                    "%U NAT64 feature enable/disable failed.",
199                                    format_vnet_sw_if_index_name, vnm,
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.",
220                                    format_vnet_sw_if_index_name, vnm,
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.",
226                                    format_vnet_sw_if_index_name, vnm,
227                                    sw_if_index);
228               goto done;
229             case VNET_API_ERROR_INVALID_VALUE:
230             case VNET_API_ERROR_INVALID_VALUE_2:
231               error =
232                 clib_error_return (0,
233                                    "%U NAT64 feature enable/disable failed.",
234                                    format_vnet_sw_if_index_name, vnm,
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
253 nat64_cli_interface_walk (snat_interface_t * i, void *ctx)
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,
260                    (nat_interface_is_inside (i)
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 *
267 nat64_show_interfaces_command_fn (vlib_main_t * vm,
268                                   unformat_input_t *
269                                   input, vlib_cli_command_t * cmd)
270 {
271   vlib_cli_output (vm, "NAT64 interfaces:");
272   nat64_interfaces_walk (nat64_cli_interface_walk, vm);
273
274   return 0;
275 }
276
277 static clib_error_t *
278 nat64_add_del_static_bib_command_fn (vlib_main_t *
279                                      vm,
280                                      unformat_input_t
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   nat_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_nat_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 = nat_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,
362                            "Outside address %U and port %u already in use.",
363                            format_ip4_address, &out_addr, out_port);
364       goto done;
365     case VNET_API_ERROR_INVALID_VALUE_2:
366       error = clib_error_return (0, "Invalid outside port.");
367     default:
368       break;
369     }
370
371 done:
372   unformat_free (line_input);
373
374   return error;
375 }
376
377 static int
378 nat64_cli_bib_walk (nat64_db_bib_entry_t * bibe, void *ctx)
379 {
380   vlib_main_t *vm = ctx;
381   fib_table_t *fib;
382
383   fib = fib_table_get (bibe->fib_index, FIB_PROTOCOL_IP6);
384   if (!fib)
385     return -1;
386
387   switch (bibe->proto)
388     {
389     case IP_PROTOCOL_ICMP:
390     case IP_PROTOCOL_TCP:
391     case IP_PROTOCOL_UDP:
392       vlib_cli_output (vm, " %U %u %U %u protocol %U vrf %u %s %u sessions",
393                        format_ip6_address, &bibe->in_addr,
394                        clib_net_to_host_u16 (bibe->in_port),
395                        format_ip4_address, &bibe->out_addr,
396                        clib_net_to_host_u16 (bibe->out_port),
397                        format_nat_protocol,
398                        ip_proto_to_nat_proto (bibe->proto), fib->ft_table_id,
399                        bibe->is_static ? "static" : "dynamic", bibe->ses_num);
400       break;
401     default:
402       vlib_cli_output (vm, " %U %U protocol %u vrf %u %s %u sessions",
403                        format_ip6_address, &bibe->in_addr,
404                        format_ip4_address, &bibe->out_addr,
405                        bibe->proto, fib->ft_table_id,
406                        bibe->is_static ? "static" : "dynamic", bibe->ses_num);
407     }
408   return 0;
409 }
410
411 static clib_error_t *
412 nat64_show_bib_command_fn (vlib_main_t * vm,
413                            unformat_input_t * input, vlib_cli_command_t * cmd)
414 {
415   nat64_main_t *nm = &nat64_main;
416   unformat_input_t _line_input, *line_input = &_line_input;
417   clib_error_t *error = 0;
418   u32 proto = NAT_PROTOCOL_OTHER;
419   u8 p = 255;
420   nat64_db_t *db;
421
422   if (!unformat_user (input, unformat_line_input, line_input))
423     return 0;
424
425   if (unformat (line_input, "%U", unformat_nat_protocol, &proto))
426     p = nat_proto_to_ip_proto (proto);
427   else if (unformat (line_input, "unknown"))
428     p = 0;
429   else if (unformat (line_input, "all"))
430     ;
431   else
432     {
433       error = clib_error_return (0, "unknown input: '%U'",
434                                  format_unformat_error, line_input);
435       goto done;
436     }
437
438   if (p == 255)
439     vlib_cli_output (vm, "NAT64 BIB entries:");
440   else
441     vlib_cli_output (vm, "NAT64 %U BIB entries:", format_nat_protocol, proto);
442
443   /* *INDENT-OFF* */
444   vec_foreach (db, nm->db)
445     nat64_db_bib_walk (db, p, nat64_cli_bib_walk, vm);
446   /* *INDENT-ON* */
447
448 done:
449   unformat_free (line_input);
450
451   return error;
452 }
453
454 typedef struct nat64_cli_st_walk_ctx_t_
455 {
456   vlib_main_t *vm;
457   nat64_db_t *db;
458 } nat64_cli_st_walk_ctx_t;
459
460 static int
461 nat64_cli_st_walk (nat64_db_st_entry_t * ste, void *arg)
462 {
463   nat64_cli_st_walk_ctx_t *ctx = arg;
464   vlib_main_t *vm = ctx->vm;
465   nat64_db_bib_entry_t *bibe;
466   fib_table_t *fib;
467
468   bibe = nat64_db_bib_entry_by_index (ctx->db, ste->proto, ste->bibe_index);
469   if (!bibe)
470     return -1;
471
472   fib = fib_table_get (bibe->fib_index, FIB_PROTOCOL_IP6);
473   if (!fib)
474     return -1;
475
476   u32 vrf_id = fib->ft_table_id;
477
478   if (ste->proto == IP_PROTOCOL_ICMP)
479     vlib_cli_output (vm, " %U %U %u %U %U %u protocol %U vrf %u",
480                      format_ip6_address, &bibe->in_addr,
481                      format_ip6_address, &ste->in_r_addr,
482                      clib_net_to_host_u16 (bibe->in_port),
483                      format_ip4_address, &bibe->out_addr,
484                      format_ip4_address, &ste->out_r_addr,
485                      clib_net_to_host_u16 (bibe->out_port),
486                      format_nat_protocol,
487                      ip_proto_to_nat_proto (bibe->proto), vrf_id);
488   else if (ste->proto == IP_PROTOCOL_TCP || ste->proto == IP_PROTOCOL_UDP)
489     vlib_cli_output (vm, " %U %u %U %u %U %u %U %u protcol %U vrf %u",
490                      format_ip6_address, &bibe->in_addr,
491                      clib_net_to_host_u16 (bibe->in_port),
492                      format_ip6_address, &ste->in_r_addr,
493                      clib_net_to_host_u16 (ste->r_port),
494                      format_ip4_address, &bibe->out_addr,
495                      clib_net_to_host_u16 (bibe->out_port),
496                      format_ip4_address, &ste->out_r_addr,
497                      clib_net_to_host_u16 (ste->r_port),
498                      format_nat_protocol,
499                      ip_proto_to_nat_proto (bibe->proto), vrf_id);
500   else
501     vlib_cli_output (vm, " %U %U %U %U protocol %u vrf %u",
502                      format_ip6_address, &bibe->in_addr,
503                      format_ip6_address, &ste->in_r_addr,
504                      format_ip4_address, &bibe->out_addr,
505                      format_ip4_address, &ste->out_r_addr,
506                      bibe->proto, vrf_id);
507
508   return 0;
509 }
510
511 static clib_error_t *
512 nat64_show_st_command_fn (vlib_main_t * vm,
513                           unformat_input_t * input, vlib_cli_command_t * cmd)
514 {
515   nat64_main_t *nm = &nat64_main;
516   unformat_input_t _line_input, *line_input = &_line_input;
517   clib_error_t *error = 0;
518   u32 proto = NAT_PROTOCOL_OTHER;
519   u8 p = 255;
520   nat64_db_t *db;
521   nat64_cli_st_walk_ctx_t ctx = {
522     .vm = vm,
523   };
524
525   if (!unformat_user (input, unformat_line_input, line_input))
526     return 0;
527
528   if (unformat (line_input, "%U", unformat_nat_protocol, &proto))
529     p = nat_proto_to_ip_proto (proto);
530   else if (unformat (line_input, "unknown"))
531     p = 0;
532   else if (unformat (line_input, "all"))
533     ;
534   else
535     {
536       error = clib_error_return (0, "unknown input: '%U'",
537                                  format_unformat_error, line_input);
538       goto done;
539     }
540
541   if (p == 255)
542     vlib_cli_output (vm, "NAT64 sessions:");
543   else
544     vlib_cli_output (vm, "NAT64 %U sessions:", format_nat_protocol, proto);
545   /* *INDENT-OFF* */
546   vec_foreach (db, nm->db)
547     {
548       ctx.db = db;
549       nat64_db_st_walk (db, p, nat64_cli_st_walk, &ctx);
550     }
551   /* *INDENT-ON* */
552
553 done:
554   unformat_free (line_input);
555
556   return error;
557 }
558
559 static clib_error_t *
560 nat64_add_del_prefix_command_fn (vlib_main_t * vm, unformat_input_t * input,
561                                  vlib_cli_command_t * cmd)
562 {
563   vnet_main_t *vnm = vnet_get_main ();
564   clib_error_t *error = 0;
565   unformat_input_t _line_input, *line_input = &_line_input;
566   u8 is_add = 1;
567   u32 vrf_id = 0, sw_if_index = ~0;
568   ip6_address_t prefix;
569   u32 plen = 0;
570   int rv;
571
572   if (!unformat_user (input, unformat_line_input, line_input))
573     return 0;
574
575   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
576     {
577       if (unformat
578           (line_input, "%U/%u", unformat_ip6_address, &prefix, &plen))
579         ;
580       else if (unformat (line_input, "tenant-vrf %u", &vrf_id))
581         ;
582       else if (unformat (line_input, "del"))
583         is_add = 0;
584       else
585         if (unformat
586             (line_input, "interface %U", unformat_vnet_sw_interface, vnm,
587              &sw_if_index))
588         ;
589       else
590         {
591           error = clib_error_return (0, "unknown input: '%U'",
592                                      format_unformat_error, line_input);
593           goto done;
594         }
595     }
596
597   if (!plen)
598     {
599       error = clib_error_return (0, "NAT64 prefix must be set.");
600       goto done;
601     }
602
603   rv = nat64_add_del_prefix (&prefix, (u8) plen, vrf_id, is_add);
604
605   switch (rv)
606     {
607     case VNET_API_ERROR_NO_SUCH_ENTRY:
608       error = clib_error_return (0, "NAT64 prefix not exist.");
609       goto done;
610     case VNET_API_ERROR_INVALID_VALUE:
611       error = clib_error_return (0, "Invalid prefix length.");
612       goto done;
613     default:
614       break;
615     }
616
617   /*
618    * Add RX interface route, whenNAT isn't running on the real input
619    * interface
620    */
621   if (sw_if_index != ~0)
622     {
623       u32 fib_index;
624       fib_prefix_t fibpfx = {
625         .fp_len = plen,
626         .fp_proto = FIB_PROTOCOL_IP6,
627         .fp_addr = {
628                     .ip6 = prefix}
629       };
630
631       if (is_add)
632         {
633           fib_index =
634             fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6,
635                                                vrf_id, nat_fib_src_hi);
636           fib_table_entry_update_one_path (fib_index, &fibpfx,
637                                            nat_fib_src_hi,
638                                            FIB_ENTRY_FLAG_NONE,
639                                            DPO_PROTO_IP6, NULL,
640                                            sw_if_index, ~0, 0,
641                                            NULL, FIB_ROUTE_PATH_INTF_RX);
642         }
643       else
644         {
645           fib_index = fib_table_find (FIB_PROTOCOL_IP6, vrf_id);
646           fib_table_entry_path_remove (fib_index, &fibpfx,
647                                        nat_fib_src_hi,
648                                        DPO_PROTO_IP6, NULL,
649                                        sw_if_index, ~0, 1,
650                                        FIB_ROUTE_PATH_INTF_RX);
651           fib_table_unlock (fib_index, FIB_PROTOCOL_IP6, nat_fib_src_hi);
652         }
653     }
654
655 done:
656   unformat_free (line_input);
657
658   return error;
659 }
660
661 static int
662 nat64_cli_prefix_walk (nat64_prefix_t * p, void *ctx)
663 {
664   vlib_main_t *vm = ctx;
665
666   vlib_cli_output (vm, " %U/%u tenant-vrf %u",
667                    format_ip6_address, &p->prefix, p->plen, p->vrf_id);
668
669   return 0;
670 }
671
672 static clib_error_t *
673 nat64_show_prefix_command_fn (vlib_main_t * vm,
674                               unformat_input_t * input,
675                               vlib_cli_command_t * cmd)
676 {
677   vlib_cli_output (vm, "NAT64 prefix:");
678   nat64_prefix_walk (nat64_cli_prefix_walk, vm);
679
680   return 0;
681 }
682
683 static clib_error_t *
684 nat64_add_interface_address_command_fn (vlib_main_t * vm,
685                                         unformat_input_t * input,
686                                         vlib_cli_command_t * cmd)
687 {
688   vnet_main_t *vnm = vnet_get_main ();
689   unformat_input_t _line_input, *line_input = &_line_input;
690   u32 sw_if_index;
691   int rv;
692   int is_add = 1;
693   clib_error_t *error = 0;
694
695   /* Get a line of input. */
696   if (!unformat_user (input, unformat_line_input, line_input))
697     return 0;
698
699   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
700     {
701       if (unformat
702           (line_input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index));
703       else if (unformat (line_input, "del"))
704         is_add = 0;
705       else
706         {
707           error = clib_error_return (0, "unknown input '%U'",
708                                      format_unformat_error, line_input);
709           goto done;
710         }
711     }
712
713   rv = nat64_add_interface_address (sw_if_index, is_add);
714
715   switch (rv)
716     {
717     case VNET_API_ERROR_NO_SUCH_ENTRY:
718       error = clib_error_return (0, "entry not exist");
719       break;
720     case VNET_API_ERROR_VALUE_EXIST:
721       error = clib_error_return (0, "entry exist");
722       break;
723     default:
724       break;
725     }
726
727 done:
728   unformat_free (line_input);
729
730   return error;
731 }
732
733 /* *INDENT-OFF* */
734
735 /*?
736  * @cliexpar
737  * @cliexstart{nat64 add pool address}
738  * Add/delete NAT64 pool address.
739  * To add single NAT64 pool address use:
740  *  vpp# nat64 add pool address 10.1.1.10
741  * To add NAT64 pool address range use:
742  *  vpp# nat64 add pool address 10.1.1.2 - 10.1.1.5
743  * To add NAT64 pool address for specific tenant use:
744  *  vpp# nat64 add pool address 10.1.1.100 tenant-vrf 100
745  * @cliexend
746 ?*/
747 VLIB_CLI_COMMAND (nat64_add_pool_address_command, static) = {
748   .path = "nat64 add pool address",
749   .short_help = "nat64 add pool address <ip4-range-start> [- <ip4-range-end>] "
750                 "[tenant-vrf <vrf-id>] [del]",
751   .function = nat64_add_del_pool_addr_command_fn,
752 };
753
754 /*?
755  * @cliexpar
756  * @cliexstart{show nat64 pool}
757  * Show NAT64 pool.
758  *  vpp# show nat64 pool
759  *  NAT64 pool:
760  *   10.1.1.3 tenant VRF: 0
761  *   10.1.1.10 tenant VRF: 10
762  * @cliexend
763 ?*/
764 VLIB_CLI_COMMAND (show_nat64_pool_command, static) = {
765   .path = "show nat64 pool",
766   .short_help = "show nat64 pool",
767   .function = nat64_show_pool_command_fn,
768 };
769
770 /*?
771  * @cliexpar
772  * @cliexstart{set interface nat64}
773  * Enable/disable NAT64 feature on the interface.
774  * To enable NAT64 feature with local (IPv6) network interface
775  * GigabitEthernet0/8/0 and external (IPv4) network interface
776  * GigabitEthernet0/a/0 use:
777  *  vpp# set interface nat64 in GigabitEthernet0/8/0 out GigabitEthernet0/a/0
778  * @cliexend
779 ?*/
780 VLIB_CLI_COMMAND (set_interface_nat64_command, static) = {
781   .path = "set interface nat64",
782   .short_help = "set interface nat64 in|out <intfc> [del]",
783   .function = nat64_interface_feature_command_fn,
784 };
785
786 /*?
787  * @cliexpar
788  * @cliexstart{show nat64 interfaces}
789  * Show interfaces with NAT64 feature.
790  * To show interfaces with NAT64 feature use:
791  *  vpp# show nat64 interfaces
792  *  NAT64 interfaces:
793  *   GigabitEthernet0/8/0 in
794  *   GigabitEthernet0/a/0 out
795  * @cliexend
796 ?*/
797 VLIB_CLI_COMMAND (show_nat64_interfaces_command, static) = {
798   .path = "show nat64 interfaces",
799   .short_help = "show nat64 interfaces",
800   .function = nat64_show_interfaces_command_fn,
801 };
802
803 /*?
804  * @cliexpar
805  * @cliexstart{nat64 add static bib}
806  * Add/delete NAT64 static BIB entry.
807  * To create NAT64 satatic BIB entry use:
808  *  vpp# nat64 add static bib 2001:db8:c000:221:: 1234 10.1.1.3 5678 tcp
809  *  vpp# nat64 add static bib 2001:db8:c000:221:: 1234 10.1.1.3 5678 udp vrf 10
810  * @cliexend
811 ?*/
812 VLIB_CLI_COMMAND (nat64_add_del_static_bib_command, static) = {
813   .path = "nat64 add static bib",
814   .short_help = "nat64 add static bib <ip6-addr> <port> <ip4-addr> <port> "
815                 "tcp|udp|icmp [vfr <table-id>] [del]",
816   .function = nat64_add_del_static_bib_command_fn,
817 };
818
819 /*?
820  * @cliexpar
821  * @cliexstart{show nat64 bib}
822  * Show NAT64 BIB entries.
823  * To show NAT64 TCP BIB entries use:
824  *  vpp# show nat64 bib tcp
825  *  NAT64 tcp BIB:
826  *   fd01:1::2 6303 10.0.0.3 62303 tcp vrf 0 dynamic 1 sessions
827  *   2001:db8:c000:221:: 1234 10.1.1.3 5678 tcp vrf 0 static 2 sessions
828  * To show NAT64 UDP BIB entries use:
829  *  vpp# show nat64 bib udp
830  *  NAT64 udp BIB:
831  *   fd01:1::2 6304 10.0.0.3 10546 udp vrf 0 dynamic 10 sessions
832  *   2001:db8:c000:221:: 1234 10.1.1.3 5678 udp vrf 10 static 0 sessions
833  * To show NAT64 ICMP BIB entries use:
834  *  vpp# show nat64 bib icmp
835  *  NAT64 icmp BIB:
836  *   fd01:1::2 6305 10.0.0.3 63209 icmp vrf 10 dynamic 1 sessions
837  * @cliexend
838 ?*/
839 VLIB_CLI_COMMAND (show_nat64_bib_command, static) = {
840   .path = "show nat64 bib",
841   .short_help = "show nat64 bib all|tcp|udp|icmp|unknown",
842   .function = nat64_show_bib_command_fn,
843 };
844
845 /*?
846  * @cliexpar
847  * @cliexstart{show nat64 session table}
848  * Show NAT64 session table.
849  * To show NAT64 TCP session table use:
850  *  vpp# show nat64 session table tcp
851  *  NAT64 tcp session table:
852  *   fd01:1::2 6303 64:ff9b::ac10:202 20 10.0.0.3 62303 172.16.2.2 20 tcp vrf 0
853  *   fd01:3::2 6303 64:ff9b::ac10:202 20 10.0.10.3 21300 172.16.2.2 20 tcp vrf 10
854  * To show NAT64 UDP session table use:
855  * #vpp show nat64 session table udp
856  * NAT64 udp session table:
857  *  fd01:1::2 6304 64:ff9b::ac10:202 20 10.0.0.3 10546 172.16.2.2 20 udp vrf 0
858  *  fd01:3::2 6304 64:ff9b::ac10:202 20 10.0.10.3 58627 172.16.2.2 20 udp vrf 10
859  *  fd01:1::2 1235 64:ff9b::a00:3 4023 10.0.0.3 24488 10.0.0.3 4023 udp vrf 0
860  *  fd01:1::3 23 64:ff9b::a00:3 24488 10.0.0.3 4023 10.0.0.3 24488 udp vrf 0
861  * To show NAT64 ICMP session table use:
862  * #vpp show nat64 session table icmp
863  * NAT64 icmp session table:
864  *  fd01:1::2 64:ff9b::ac10:202 6305 10.0.0.3 172.16.2.2 63209 icmp vrf 0
865  * @cliexend
866 ?*/
867 VLIB_CLI_COMMAND (show_nat64_st_command, static) = {
868   .path = "show nat64 session table",
869   .short_help = "show nat64 session table all|tcp|udp|icmp|unknown",
870   .function = nat64_show_st_command_fn,
871 };
872
873 /*?
874  * @cliexpar
875  * @cliexstart{nat64 add prefix}
876  * Set NAT64 prefix for generating IPv6 representations of IPv4 addresses.
877  * To set NAT64 global prefix use:
878  *  vpp# nat64 add prefix 2001:db8::/32
879  * To set NAT64 prefix for specific tenant use:
880  *  vpp# nat64 add prefix 2001:db8:122:300::/56 tenant-vrf 10
881  * @cliexend
882 ?*/
883 VLIB_CLI_COMMAND (nat64_add_del_prefix_command, static) = {
884   .path = "nat64 add prefix",
885   .short_help = "nat64 add prefix <ip6-prefix>/<plen> [tenant-vrf <vrf-id>] "
886                 "[del] [interface <interface]",
887   .function = nat64_add_del_prefix_command_fn,
888 };
889
890 /*?
891  * @cliexpar
892  * @cliexstart{show nat64 prefix}
893  * Show NAT64 prefix.
894  * To show NAT64 prefix use:
895  *  vpp# show nat64 prefix
896  *  NAT64 prefix:
897  *   2001:db8::/32 tenant-vrf 0
898  *   2001:db8:122:300::/56 tenant-vrf 10
899  * @cliexend
900 ?*/
901 VLIB_CLI_COMMAND (show_nat64_prefix_command, static) = {
902   .path = "show nat64 prefix",
903   .short_help = "show nat64 prefix",
904   .function = nat64_show_prefix_command_fn,
905 };
906
907 /*?
908  * @cliexpar
909  * @cliexstart{nat64 add interface address}
910  * Add/delete NAT64 pool address from specific (DHCP addressed) interface.
911  * To add NAT64 pool address from specific interface use:
912  *  vpp# nat64 add interface address GigabitEthernet0/8/0
913  * @cliexend
914 ?*/
915 VLIB_CLI_COMMAND (nat64_add_interface_address_command, static) = {
916     .path = "nat64 add interface address",
917     .short_help = "nat64 add interface address <interface> [del]",
918     .function = nat64_add_interface_address_command_fn,
919 };
920 /* *INDENT-ON* */
921
922 /*
923  * fd.io coding-style-patch-verification: ON
924  *
925  * Local Variables:
926  * eval: (c-set-style "gnu")
927  * End:
928  */