FD.io VPP  v18.04-17-g3a0d853
Vector Packet Processing
nat44_cli.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018 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 NAT44 CLI
18  */
19 
20 #include <nat/nat.h>
21 #include <nat/nat_ipfix_logging.h>
22 #include <nat/nat_det.h>
23 #include <vnet/fib/fib_table.h>
24 
25 static clib_error_t *
27  unformat_input_t * input, vlib_cli_command_t * cmd)
28 {
29  unformat_input_t _line_input, *line_input = &_line_input;
30  uword *bitmap = 0;
31  int rv = 0;
32  clib_error_t *error = 0;
33 
34  /* Get a line of input. */
35  if (!unformat_user (input, unformat_line_input, line_input))
36  return 0;
37 
38  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
39  {
40  if (unformat (line_input, "%U", unformat_bitmap_list, &bitmap))
41  ;
42  else
43  {
44  error = clib_error_return (0, "unknown input '%U'",
45  format_unformat_error, line_input);
46  goto done;
47  }
48  }
49 
50  if (bitmap == 0)
51  {
52  error = clib_error_return (0, "List of workers must be specified.");
53  goto done;
54  }
55 
56  rv = snat_set_workers (bitmap);
57 
58  clib_bitmap_free (bitmap);
59 
60  switch (rv)
61  {
62  case VNET_API_ERROR_INVALID_WORKER:
63  error = clib_error_return (0, "Invalid worker(s).");
64  goto done;
65  case VNET_API_ERROR_FEATURE_DISABLED:
66  error = clib_error_return (0,
67  "Supported only if 2 or more workes available.");
68  goto done;
69  default:
70  break;
71  }
72 
73 done:
74  unformat_free (line_input);
75 
76  return error;
77 }
78 
79 static clib_error_t *
81  vlib_cli_command_t * cmd)
82 {
83  snat_main_t *sm = &snat_main;
84  u32 *worker;
85 
86  if (sm->num_workers > 1)
87  {
88  vlib_cli_output (vm, "%d workers", vec_len (sm->workers));
89  /* *INDENT-OFF* */
90  vec_foreach (worker, sm->workers)
91  {
94  vlib_cli_output (vm, " %s", w->name);
95  }
96  /* *INDENT-ON* */
97  }
98 
99  return 0;
100 }
101 
102 static clib_error_t *
104  unformat_input_t * input,
105  vlib_cli_command_t * cmd)
106 {
107  unformat_input_t _line_input, *line_input = &_line_input;
108  u32 domain_id = 0;
109  u32 src_port = 0;
110  u8 enable = 1;
111  int rv = 0;
112  clib_error_t *error = 0;
113 
114  /* Get a line of input. */
115  if (!unformat_user (input, unformat_line_input, line_input))
116  return 0;
117 
118  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
119  {
120  if (unformat (line_input, "domain %d", &domain_id))
121  ;
122  else if (unformat (line_input, "src-port %d", &src_port))
123  ;
124  else if (unformat (line_input, "disable"))
125  enable = 0;
126  else
127  {
128  error = clib_error_return (0, "unknown input '%U'",
129  format_unformat_error, line_input);
130  goto done;
131  }
132  }
133 
134  rv = snat_ipfix_logging_enable_disable (enable, domain_id, (u16) src_port);
135 
136  if (rv)
137  {
138  error = clib_error_return (0, "ipfix logging enable failed");
139  goto done;
140  }
141 
142 done:
143  unformat_free (line_input);
144 
145  return error;
146 }
147 
148 static clib_error_t *
150  unformat_input_t * input,
151  vlib_cli_command_t * cmd)
152 {
153  unformat_input_t _line_input, *line_input = &_line_input;
154  clib_error_t *error = 0;
155  u32 psid, psid_offset, psid_length;
156 
157  /* Get a line of input. */
158  if (!unformat_user (input, unformat_line_input, line_input))
159  return 0;
160 
161  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
162  {
163  if (unformat (line_input, "default"))
165  else
166  if (unformat
167  (line_input, "map-e psid %d psid-offset %d psid-len %d", &psid,
168  &psid_offset, &psid_length))
169  nat_set_alloc_addr_and_port_mape ((u16) psid, (u16) psid_offset,
170  (u16) psid_length);
171  else
172  {
173  error = clib_error_return (0, "unknown input '%U'",
174  format_unformat_error, line_input);
175  goto done;
176  }
177  }
178 
179 done:
180  unformat_free (line_input);
181 
182  return error;
183 };
184 
185 static clib_error_t *
187  unformat_input_t * input, vlib_cli_command_t * cmd)
188 {
189  unformat_input_t _line_input, *line_input = &_line_input;
190  snat_main_t *sm = &snat_main;
191  ip4_address_t start_addr, end_addr, this_addr;
192  u32 start_host_order, end_host_order;
193  u32 vrf_id = ~0;
194  int i, count;
195  int is_add = 1;
196  int rv = 0;
197  clib_error_t *error = 0;
198  u8 twice_nat = 0;
199 
200  /* Get a line of input. */
201  if (!unformat_user (input, unformat_line_input, line_input))
202  return 0;
203 
204  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
205  {
206  if (unformat (line_input, "%U - %U",
207  unformat_ip4_address, &start_addr,
208  unformat_ip4_address, &end_addr))
209  ;
210  else if (unformat (line_input, "tenant-vrf %u", &vrf_id))
211  ;
212  else if (unformat (line_input, "%U", unformat_ip4_address, &start_addr))
213  end_addr = start_addr;
214  else if (unformat (line_input, "twice-nat"))
215  twice_nat = 1;
216  else if (unformat (line_input, "del"))
217  is_add = 0;
218  else
219  {
220  error = clib_error_return (0, "unknown input '%U'",
221  format_unformat_error, line_input);
222  goto done;
223  }
224  }
225 
226  if (sm->static_mapping_only)
227  {
228  error = clib_error_return (0, "static mapping only mode");
229  goto done;
230  }
231 
232  start_host_order = clib_host_to_net_u32 (start_addr.as_u32);
233  end_host_order = clib_host_to_net_u32 (end_addr.as_u32);
234 
235  if (end_host_order < start_host_order)
236  {
237  error = clib_error_return (0, "end address less than start address");
238  goto done;
239  }
240 
241  count = (end_host_order - start_host_order) + 1;
242 
243  if (count > 1024)
244  clib_warning ("%U - %U, %d addresses...",
245  format_ip4_address, &start_addr,
246  format_ip4_address, &end_addr, count);
247 
248  this_addr = start_addr;
249 
250  for (i = 0; i < count; i++)
251  {
252  if (is_add)
253  snat_add_address (sm, &this_addr, vrf_id, twice_nat);
254  else
255  rv = snat_del_address (sm, this_addr, 0, twice_nat);
256 
257  switch (rv)
258  {
259  case VNET_API_ERROR_NO_SUCH_ENTRY:
260  error = clib_error_return (0, "S-NAT address not exist.");
261  goto done;
262  case VNET_API_ERROR_UNSPECIFIED:
263  error =
264  clib_error_return (0, "S-NAT address used in static mapping.");
265  goto done;
266  default:
267  break;
268  }
269 
270  if (sm->out2in_dpo)
271  nat44_add_del_address_dpo (this_addr, is_add);
272 
273  increment_v4_address (&this_addr);
274  }
275 
276 done:
277  unformat_free (line_input);
278 
279  return error;
280 }
281 
282 static clib_error_t *
284  vlib_cli_command_t * cmd)
285 {
286  snat_main_t *sm = &snat_main;
287  snat_address_t *ap;
288 
289  vlib_cli_output (vm, "NAT44 pool addresses:");
290  /* *INDENT-OFF* */
291  vec_foreach (ap, sm->addresses)
292  {
293  vlib_cli_output (vm, "%U", format_ip4_address, &ap->addr);
294  if (ap->fib_index != ~0)
295  vlib_cli_output (vm, " tenant VRF: %u",
297  else
298  vlib_cli_output (vm, " tenant VRF independent");
299  #define _(N, i, n, s) \
300  vlib_cli_output (vm, " %d busy %s ports", ap->busy_##n##_ports, s);
302  #undef _
303  }
304  vlib_cli_output (vm, "NAT44 twice-nat pool addresses:");
306  {
307  vlib_cli_output (vm, "%U", format_ip4_address, &ap->addr);
308  if (ap->fib_index != ~0)
309  vlib_cli_output (vm, " tenant VRF: %u",
311  else
312  vlib_cli_output (vm, " tenant VRF independent");
313  #define _(N, i, n, s) \
314  vlib_cli_output (vm, " %d busy %s ports", ap->busy_##n##_ports, s);
316  #undef _
317  }
318  /* *INDENT-ON* */
319  return 0;
320 }
321 
322 static clib_error_t *
324  unformat_input_t * input, vlib_cli_command_t * cmd)
325 {
326  unformat_input_t _line_input, *line_input = &_line_input;
327  vnet_main_t *vnm = vnet_get_main ();
328  clib_error_t *error = 0;
329  u32 sw_if_index;
330  u32 *inside_sw_if_indices = 0;
331  u32 *outside_sw_if_indices = 0;
332  u8 is_output_feature = 0;
333  int is_del = 0;
334  int i;
335 
336  sw_if_index = ~0;
337 
338  /* Get a line of input. */
339  if (!unformat_user (input, unformat_line_input, line_input))
340  return 0;
341 
342  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
343  {
344  if (unformat (line_input, "in %U", unformat_vnet_sw_interface,
345  vnm, &sw_if_index))
346  vec_add1 (inside_sw_if_indices, sw_if_index);
347  else if (unformat (line_input, "out %U", unformat_vnet_sw_interface,
348  vnm, &sw_if_index))
349  vec_add1 (outside_sw_if_indices, sw_if_index);
350  else if (unformat (line_input, "output-feature"))
351  is_output_feature = 1;
352  else if (unformat (line_input, "del"))
353  is_del = 1;
354  else
355  {
356  error = clib_error_return (0, "unknown input '%U'",
357  format_unformat_error, line_input);
358  goto done;
359  }
360  }
361 
362  if (vec_len (inside_sw_if_indices))
363  {
364  for (i = 0; i < vec_len (inside_sw_if_indices); i++)
365  {
366  sw_if_index = inside_sw_if_indices[i];
367  if (is_output_feature)
368  {
370  (sw_if_index, 1, is_del))
371  {
372  error = clib_error_return (0, "%s %U failed",
373  is_del ? "del" : "add",
375  vnm, sw_if_index);
376  goto done;
377  }
378  }
379  else
380  {
381  if (snat_interface_add_del (sw_if_index, 1, is_del))
382  {
383  error = clib_error_return (0, "%s %U failed",
384  is_del ? "del" : "add",
386  vnm, sw_if_index);
387  goto done;
388  }
389  }
390  }
391  }
392 
393  if (vec_len (outside_sw_if_indices))
394  {
395  for (i = 0; i < vec_len (outside_sw_if_indices); i++)
396  {
397  sw_if_index = outside_sw_if_indices[i];
398  if (is_output_feature)
399  {
401  (sw_if_index, 0, is_del))
402  {
403  error = clib_error_return (0, "%s %U failed",
404  is_del ? "del" : "add",
406  vnm, sw_if_index);
407  goto done;
408  }
409  }
410  else
411  {
412  if (snat_interface_add_del (sw_if_index, 0, is_del))
413  {
414  error = clib_error_return (0, "%s %U failed",
415  is_del ? "del" : "add",
417  vnm, sw_if_index);
418  goto done;
419  }
420  }
421  }
422  }
423 
424 done:
425  unformat_free (line_input);
426  vec_free (inside_sw_if_indices);
427  vec_free (outside_sw_if_indices);
428 
429  return error;
430 }
431 
432 static clib_error_t *
434  vlib_cli_command_t * cmd)
435 {
436  snat_main_t *sm = &snat_main;
438  vnet_main_t *vnm = vnet_get_main ();
439 
440  vlib_cli_output (vm, "NAT44 interfaces:");
441  /* *INDENT-OFF* */
442  pool_foreach (i, sm->interfaces,
443  ({
444  vlib_cli_output (vm, " %U %s", format_vnet_sw_if_index_name, vnm,
445  i->sw_if_index,
446  (nat_interface_is_inside(i) &&
447  nat_interface_is_outside(i)) ? "in out" :
448  (nat_interface_is_inside(i) ? "in" : "out"));
449  }));
450 
452  ({
453  vlib_cli_output (vm, " %U output-feature %s",
454  format_vnet_sw_if_index_name, vnm,
455  i->sw_if_index,
456  (nat_interface_is_inside(i) &&
457  nat_interface_is_outside(i)) ? "in out" :
458  (nat_interface_is_inside(i) ? "in" : "out"));
459  }));
460  /* *INDENT-ON* */
461 
462  return 0;
463 }
464 
465 static clib_error_t *
467  unformat_input_t * input,
468  vlib_cli_command_t * cmd)
469 {
470  unformat_input_t _line_input, *line_input = &_line_input;
471  clib_error_t *error = 0;
472  ip4_address_t l_addr, e_addr;
473  u32 l_port = 0, e_port = 0, vrf_id = ~0;
474  int is_add = 1;
475  int addr_only = 1;
476  u32 sw_if_index = ~0;
477  vnet_main_t *vnm = vnet_get_main ();
478  int rv;
479  snat_protocol_t proto = ~0;
480  u8 proto_set = 0;
481  u8 twice_nat = 0;
482  u8 out2in_only = 0;
483 
484  /* Get a line of input. */
485  if (!unformat_user (input, unformat_line_input, line_input))
486  return 0;
487 
488  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
489  {
490  if (unformat (line_input, "local %U %u", unformat_ip4_address, &l_addr,
491  &l_port))
492  addr_only = 0;
493  else
494  if (unformat (line_input, "local %U", unformat_ip4_address, &l_addr))
495  ;
496  else if (unformat (line_input, "external %U %u", unformat_ip4_address,
497  &e_addr, &e_port))
498  addr_only = 0;
499  else if (unformat (line_input, "external %U", unformat_ip4_address,
500  &e_addr))
501  ;
502  else if (unformat (line_input, "external %U %u",
503  unformat_vnet_sw_interface, vnm, &sw_if_index,
504  &e_port))
505  addr_only = 0;
506 
507  else if (unformat (line_input, "external %U",
508  unformat_vnet_sw_interface, vnm, &sw_if_index))
509  ;
510  else if (unformat (line_input, "vrf %u", &vrf_id))
511  ;
512  else if (unformat (line_input, "%U", unformat_snat_protocol, &proto))
513  proto_set = 1;
514  else if (unformat (line_input, "twice-nat"))
515  twice_nat = 1;
516  else if (unformat (line_input, "out2in-only"))
517  out2in_only = 1;
518  else if (unformat (line_input, "del"))
519  is_add = 0;
520  else
521  {
522  error = clib_error_return (0, "unknown input: '%U'",
523  format_unformat_error, line_input);
524  goto done;
525  }
526  }
527 
528  if (twice_nat && addr_only)
529  {
530  error = clib_error_return (0, "twice NAT only for 1:1 NAPT");
531  goto done;
532  }
533 
534  if (!addr_only && !proto_set)
535  {
536  error = clib_error_return (0, "missing protocol");
537  goto done;
538  }
539 
540  rv = snat_add_static_mapping (l_addr, e_addr, (u16) l_port, (u16) e_port,
541  vrf_id, addr_only, sw_if_index, proto, is_add,
542  twice_nat, out2in_only, 0);
543 
544  switch (rv)
545  {
546  case VNET_API_ERROR_INVALID_VALUE:
547  error = clib_error_return (0, "External port already in use.");
548  goto done;
549  case VNET_API_ERROR_NO_SUCH_ENTRY:
550  if (is_add)
551  error = clib_error_return (0, "External addres must be allocated.");
552  else
553  error = clib_error_return (0, "Mapping not exist.");
554  goto done;
555  case VNET_API_ERROR_NO_SUCH_FIB:
556  error = clib_error_return (0, "No such VRF id.");
557  goto done;
558  case VNET_API_ERROR_VALUE_EXIST:
559  error = clib_error_return (0, "Mapping already exist.");
560  goto done;
561  default:
562  break;
563  }
564 
565 done:
566  unformat_free (line_input);
567 
568  return error;
569 }
570 
571 static clib_error_t *
573  unformat_input_t * input,
574  vlib_cli_command_t * cmd)
575 {
576  unformat_input_t _line_input, *line_input = &_line_input;
577  clib_error_t *error = 0;
579  u32 port = 0, vrf_id = ~0;
580  int is_add = 1;
581  int addr_only = 1;
582  u32 sw_if_index = ~0;
583  vnet_main_t *vnm = vnet_get_main ();
584  int rv;
585  snat_protocol_t proto;
586 
587  addr.as_u32 = 0;
588 
589  /* Get a line of input. */
590  if (!unformat_user (input, unformat_line_input, line_input))
591  return 0;
592 
593  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
594  {
595  if (unformat (line_input, "%U", unformat_ip4_address, &addr))
596  ;
597  else if (unformat (line_input, "external %U",
598  unformat_vnet_sw_interface, vnm, &sw_if_index))
599  ;
600  else if (unformat (line_input, "vrf %u", &vrf_id))
601  ;
602  else if (unformat (line_input, "%U %u", unformat_snat_protocol, &proto,
603  &port))
604  addr_only = 0;
605  else if (unformat (line_input, "del"))
606  is_add = 0;
607  else
608  {
609  error = clib_error_return (0, "unknown input: '%U'",
610  format_unformat_error, line_input);
611  goto done;
612  }
613  }
614 
615  rv = snat_add_static_mapping (addr, addr, (u16) port, (u16) port,
616  vrf_id, addr_only, sw_if_index, proto, is_add,
617  0, 0, 0);
618 
619  switch (rv)
620  {
621  case VNET_API_ERROR_INVALID_VALUE:
622  error = clib_error_return (0, "External port already in use.");
623  goto done;
624  case VNET_API_ERROR_NO_SUCH_ENTRY:
625  if (is_add)
626  error = clib_error_return (0, "External addres must be allocated.");
627  else
628  error = clib_error_return (0, "Mapping not exist.");
629  goto done;
630  case VNET_API_ERROR_NO_SUCH_FIB:
631  error = clib_error_return (0, "No such VRF id.");
632  goto done;
633  case VNET_API_ERROR_VALUE_EXIST:
634  error = clib_error_return (0, "Mapping already exist.");
635  goto done;
636  default:
637  break;
638  }
639 
640 done:
641  unformat_free (line_input);
642 
643  return error;
644 }
645 
646 static clib_error_t *
648  unformat_input_t * input,
649  vlib_cli_command_t * cmd)
650 {
651  unformat_input_t _line_input, *line_input = &_line_input;
652  clib_error_t *error = 0;
653  ip4_address_t l_addr, e_addr;
654  u32 l_port = 0, e_port = 0, vrf_id = 0, probability = 0;
655  int is_add = 1;
656  int rv;
657  snat_protocol_t proto;
658  u8 proto_set = 0;
659  nat44_lb_addr_port_t *locals = 0, local;
660  u8 twice_nat = 0;
661  u8 out2in_only = 0;
662 
663  /* Get a line of input. */
664  if (!unformat_user (input, unformat_line_input, line_input))
665  return 0;
666 
667  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
668  {
669  if (unformat (line_input, "local %U:%u probability %u",
670  unformat_ip4_address, &l_addr, &l_port, &probability))
671  {
672  memset (&local, 0, sizeof (local));
673  local.addr = l_addr;
674  local.port = (u16) l_port;
675  local.probability = (u8) probability;
676  vec_add1 (locals, local);
677  }
678  else if (unformat (line_input, "external %U:%u", unformat_ip4_address,
679  &e_addr, &e_port))
680  ;
681  else if (unformat (line_input, "vrf %u", &vrf_id))
682  ;
683  else if (unformat (line_input, "protocol %U", unformat_snat_protocol,
684  &proto))
685  proto_set = 1;
686  else if (unformat (line_input, "twice-nat"))
687  twice_nat = 1;
688  else if (unformat (line_input, "out2in-only"))
689  out2in_only = 1;
690  else if (unformat (line_input, "del"))
691  is_add = 0;
692  else
693  {
694  error = clib_error_return (0, "unknown input: '%U'",
695  format_unformat_error, line_input);
696  goto done;
697  }
698  }
699 
700  if (vec_len (locals) < 2)
701  {
702  error = clib_error_return (0, "at least two local must be set");
703  goto done;
704  }
705 
706  if (!proto_set)
707  {
708  error = clib_error_return (0, "missing protocol");
709  goto done;
710  }
711 
712  rv = nat44_add_del_lb_static_mapping (e_addr, (u16) e_port, proto, vrf_id,
713  locals, is_add, twice_nat,
714  out2in_only, 0);
715 
716  switch (rv)
717  {
718  case VNET_API_ERROR_INVALID_VALUE:
719  error = clib_error_return (0, "External port already in use.");
720  goto done;
721  case VNET_API_ERROR_NO_SUCH_ENTRY:
722  if (is_add)
723  error = clib_error_return (0, "External addres must be allocated.");
724  else
725  error = clib_error_return (0, "Mapping not exist.");
726  goto done;
727  case VNET_API_ERROR_VALUE_EXIST:
728  error = clib_error_return (0, "Mapping already exist.");
729  goto done;
730  default:
731  break;
732  }
733 
734 done:
735  unformat_free (line_input);
736  vec_free (locals);
737 
738  return error;
739 }
740 
741 static clib_error_t *
743  unformat_input_t * input,
744  vlib_cli_command_t * cmd)
745 {
746  snat_main_t *sm = &snat_main;
749 
750  vlib_cli_output (vm, "NAT44 static mappings:");
751  /* *INDENT-OFF* */
753  ({
754  vlib_cli_output (vm, " %U", format_snat_static_mapping, m);
755  }));
756  vec_foreach (rp, sm->to_resolve)
758  /* *INDENT-ON* */
759 
760  return 0;
761 }
762 
763 static clib_error_t *
765  unformat_input_t * input,
766  vlib_cli_command_t * cmd)
767 {
768  snat_main_t *sm = &snat_main;
769  unformat_input_t _line_input, *line_input = &_line_input;
770  u32 sw_if_index;
771  int rv;
772  int is_del = 0;
773  clib_error_t *error = 0;
774  u8 twice_nat = 0;
775 
776  /* Get a line of input. */
777  if (!unformat_user (input, unformat_line_input, line_input))
778  return 0;
779 
780  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
781  {
782  if (unformat (line_input, "%U", unformat_vnet_sw_interface,
783  sm->vnet_main, &sw_if_index))
784  ;
785  else if (unformat (line_input, "twice-nat"))
786  twice_nat = 1;
787  else if (unformat (line_input, "del"))
788  is_del = 1;
789  else
790  {
791  error = clib_error_return (0, "unknown input '%U'",
792  format_unformat_error, line_input);
793  goto done;
794  }
795  }
796 
797  rv = snat_add_interface_address (sm, sw_if_index, is_del, twice_nat);
798 
799  switch (rv)
800  {
801  case 0:
802  break;
803 
804  default:
805  error = clib_error_return (0, "snat_add_interface_address returned %d",
806  rv);
807  goto done;
808  }
809 
810 done:
811  unformat_free (line_input);
812 
813  return error;
814 }
815 
816 static clib_error_t *
818  unformat_input_t * input,
819  vlib_cli_command_t * cmd)
820 {
821  snat_main_t *sm = &snat_main;
822  vnet_main_t *vnm = vnet_get_main ();
823  u32 *sw_if_index;
824 
825  /* *INDENT-OFF* */
826  vlib_cli_output (vm, "NAT44 pool address interfaces:");
827  vec_foreach (sw_if_index, sm->auto_add_sw_if_indices)
828  {
830  *sw_if_index);
831  }
832  vlib_cli_output (vm, "NAT44 twice-nat pool address interfaces:");
834  {
836  *sw_if_index);
837  }
838  /* *INDENT-ON* */
839 
840  return 0;
841 }
842 
843 static clib_error_t *
845  vlib_cli_command_t * cmd)
846 {
847  int verbose = 0;
848  snat_main_t *sm = &snat_main;
850  snat_user_t *u;
851  int i = 0;
852 
853  if (unformat (input, "detail"))
854  verbose = 1;
855 
856  vlib_cli_output (vm, "NAT44 sessions:");
857 
858  /* *INDENT-OFF* */
860  {
861  tsm = vec_elt_at_index (sm->per_thread_data, i);
862 
863  pool_foreach (u, tsm->users,
864  ({
865  vlib_cli_output (vm, " %U", format_snat_user, tsm, u, verbose);
866  }));
867  }
868  /* *INDENT-ON* */
869 
870  return 0;
871 }
872 
873 static clib_error_t *
875  unformat_input_t * input,
876  vlib_cli_command_t * cmd)
877 {
878  snat_main_t *sm = &snat_main;
879  unformat_input_t _line_input, *line_input = &_line_input;
880  int is_in = 0;
881  clib_error_t *error = 0;
883  u32 port = 0, vrf_id = sm->outside_vrf_id;
884  snat_protocol_t proto;
885  int rv;
886 
887  /* Get a line of input. */
888  if (!unformat_user (input, unformat_line_input, line_input))
889  return 0;
890 
891  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
892  {
893  if (unformat
894  (line_input, "%U:%u %U", unformat_ip4_address, &addr, &port,
895  unformat_snat_protocol, &proto))
896  ;
897  else if (unformat (line_input, "in"))
898  {
899  is_in = 1;
900  vrf_id = sm->inside_vrf_id;
901  }
902  else if (unformat (line_input, "vrf %u", &vrf_id))
903  ;
904  else
905  {
906  error = clib_error_return (0, "unknown input '%U'",
907  format_unformat_error, line_input);
908  goto done;
909  }
910  }
911 
912  rv = nat44_del_session (sm, &addr, port, proto, vrf_id, is_in);
913 
914  switch (rv)
915  {
916  case 0:
917  break;
918 
919  default:
920  error = clib_error_return (0, "nat44_del_session returned %d", rv);
921  goto done;
922  }
923 
924 done:
925  unformat_free (line_input);
926 
927  return error;
928 }
929 
930 static clib_error_t *
932  unformat_input_t * input,
933  vlib_cli_command_t * cmd)
934 {
935  snat_main_t *sm = &snat_main;
936  unformat_input_t _line_input, *line_input = &_line_input;
937  u8 forwarding_enable;
938  u8 forwarding_enable_set = 0;
939  clib_error_t *error = 0;
940 
941  /* Get a line of input. */
942  if (!unformat_user (input, unformat_line_input, line_input))
943  return clib_error_return (0, "'enable' or 'disable' expected");
944 
945  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
946  {
947  if (!forwarding_enable_set && unformat (line_input, "enable"))
948  {
949  forwarding_enable = 1;
950  forwarding_enable_set = 1;
951  }
952  else if (!forwarding_enable_set && unformat (line_input, "disable"))
953  {
954  forwarding_enable = 0;
955  forwarding_enable_set = 1;
956  }
957  else
958  {
959  error = clib_error_return (0, "unknown input '%U'",
960  format_unformat_error, line_input);
961  goto done;
962  }
963  }
964 
965  if (!forwarding_enable_set)
966  {
967  error = clib_error_return (0, "'enable' or 'disable' expected");
968  goto done;
969  }
970 
971  sm->forwarding_enabled = forwarding_enable;
972 
973 done:
974  unformat_free (line_input);
975 
976  return error;
977 }
978 
979 static clib_error_t *
981  unformat_input_t * input, vlib_cli_command_t * cmd)
982 {
983  snat_main_t *sm = &snat_main;
984  unformat_input_t _line_input, *line_input = &_line_input;
985  ip4_address_t in_addr, out_addr;
986  u32 in_plen, out_plen;
987  int is_add = 1, rv;
988  clib_error_t *error = 0;
989 
990  /* Get a line of input. */
991  if (!unformat_user (input, unformat_line_input, line_input))
992  return 0;
993 
994  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
995  {
996  if (unformat
997  (line_input, "in %U/%u", unformat_ip4_address, &in_addr, &in_plen))
998  ;
999  else
1000  if (unformat
1001  (line_input, "out %U/%u", unformat_ip4_address, &out_addr,
1002  &out_plen))
1003  ;
1004  else if (unformat (line_input, "del"))
1005  is_add = 0;
1006  else
1007  {
1008  error = clib_error_return (0, "unknown input '%U'",
1009  format_unformat_error, line_input);
1010  goto done;
1011  }
1012  }
1013 
1014  rv = snat_det_add_map (sm, &in_addr, (u8) in_plen, &out_addr, (u8) out_plen,
1015  is_add);
1016 
1017  if (rv)
1018  {
1019  error = clib_error_return (0, "snat_det_add_map return %d", rv);
1020  goto done;
1021  }
1022 
1023 done:
1024  unformat_free (line_input);
1025 
1026  return error;
1027 }
1028 
1029 static clib_error_t *
1031  unformat_input_t * input,
1032  vlib_cli_command_t * cmd)
1033 {
1034  snat_main_t *sm = &snat_main;
1035  snat_det_map_t *dm;
1036 
1037  vlib_cli_output (vm, "NAT44 deterministic mappings:");
1038  /* *INDENT-OFF* */
1039  pool_foreach (dm, sm->det_maps,
1040  ({
1041  vlib_cli_output (vm, " in %U/%d out %U/%d\n",
1042  format_ip4_address, &dm->in_addr, dm->in_plen,
1043  format_ip4_address, &dm->out_addr, dm->out_plen);
1044  vlib_cli_output (vm, " outside address sharing ratio: %d\n",
1045  dm->sharing_ratio);
1046  vlib_cli_output (vm, " number of ports per inside host: %d\n",
1047  dm->ports_per_host);
1048  vlib_cli_output (vm, " sessions number: %d\n", dm->ses_num);
1049  }));
1050  /* *INDENT-ON* */
1051 
1052  return 0;
1053 }
1054 
1055 static clib_error_t *
1057  unformat_input_t * input,
1058  vlib_cli_command_t * cmd)
1059 {
1060  snat_main_t *sm = &snat_main;
1061  unformat_input_t _line_input, *line_input = &_line_input;
1062  ip4_address_t in_addr, out_addr;
1063  u16 lo_port;
1064  snat_det_map_t *dm;
1065  clib_error_t *error = 0;
1066 
1067  /* Get a line of input. */
1068  if (!unformat_user (input, unformat_line_input, line_input))
1069  return 0;
1070 
1071  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1072  {
1073  if (unformat (line_input, "%U", unformat_ip4_address, &in_addr))
1074  ;
1075  else
1076  {
1077  error = clib_error_return (0, "unknown input '%U'",
1078  format_unformat_error, line_input);
1079  goto done;
1080  }
1081  }
1082 
1083  dm = snat_det_map_by_user (sm, &in_addr);
1084  if (!dm)
1085  vlib_cli_output (vm, "no match");
1086  else
1087  {
1088  snat_det_forward (dm, &in_addr, &out_addr, &lo_port);
1089  vlib_cli_output (vm, "%U:<%d-%d>", format_ip4_address, &out_addr,
1090  lo_port, lo_port + dm->ports_per_host - 1);
1091  }
1092 
1093 done:
1094  unformat_free (line_input);
1095 
1096  return error;
1097 }
1098 
1099 static clib_error_t *
1101  unformat_input_t * input,
1102  vlib_cli_command_t * cmd)
1103 {
1104  snat_main_t *sm = &snat_main;
1105  unformat_input_t _line_input, *line_input = &_line_input;
1106  ip4_address_t in_addr, out_addr;
1107  u32 out_port;
1108  snat_det_map_t *dm;
1109  clib_error_t *error = 0;
1110 
1111  /* Get a line of input. */
1112  if (!unformat_user (input, unformat_line_input, line_input))
1113  return 0;
1114 
1115  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1116  {
1117  if (unformat
1118  (line_input, "%U:%d", unformat_ip4_address, &out_addr, &out_port))
1119  ;
1120  else
1121  {
1122  error = clib_error_return (0, "unknown input '%U'",
1123  format_unformat_error, line_input);
1124  goto done;
1125  }
1126  }
1127 
1128  if (out_port < 1024 || out_port > 65535)
1129  {
1130  error = clib_error_return (0, "wrong port, must be <1024-65535>");
1131  goto done;
1132  }
1133 
1134  dm = snat_det_map_by_out (sm, &out_addr);
1135  if (!dm)
1136  vlib_cli_output (vm, "no match");
1137  else
1138  {
1139  snat_det_reverse (dm, &out_addr, (u16) out_port, &in_addr);
1140  vlib_cli_output (vm, "%U", format_ip4_address, &in_addr);
1141  }
1142 
1143 done:
1144  unformat_free (line_input);
1145 
1146  return error;
1147 }
1148 
1149 static clib_error_t *
1151  unformat_input_t * input, vlib_cli_command_t * cmd)
1152 {
1153  snat_main_t *sm = &snat_main;
1154  unformat_input_t _line_input, *line_input = &_line_input;
1155  clib_error_t *error = 0;
1156 
1157  /* Get a line of input. */
1158  if (!unformat_user (input, unformat_line_input, line_input))
1159  return 0;
1160 
1161  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1162  {
1163  if (unformat (line_input, "udp %u", &sm->udp_timeout))
1164  ;
1165  else if (unformat (line_input, "tcp-established %u",
1167  ;
1168  else if (unformat (line_input, "tcp-transitory %u",
1169  &sm->tcp_transitory_timeout))
1170  ;
1171  else if (unformat (line_input, "icmp %u", &sm->icmp_timeout))
1172  ;
1173  else if (unformat (line_input, "reset"))
1174  {
1179  }
1180  else
1181  {
1182  error = clib_error_return (0, "unknown input '%U'",
1183  format_unformat_error, line_input);
1184  goto done;
1185  }
1186  }
1187 
1188 done:
1189  unformat_free (line_input);
1190 
1191  return error;
1192 }
1193 
1194 static clib_error_t *
1196  unformat_input_t * input,
1197  vlib_cli_command_t * cmd)
1198 {
1199  snat_main_t *sm = &snat_main;
1200 
1201  vlib_cli_output (vm, "udp timeout: %dsec", sm->udp_timeout);
1202  vlib_cli_output (vm, "tcp-established timeout: %dsec",
1204  vlib_cli_output (vm, "tcp-transitory timeout: %dsec",
1206  vlib_cli_output (vm, "icmp timeout: %dsec", sm->icmp_timeout);
1207 
1208  return 0;
1209 }
1210 
1211 static clib_error_t *
1213  unformat_input_t * input,
1214  vlib_cli_command_t * cmd)
1215 {
1216  snat_main_t *sm = &snat_main;
1217  snat_det_map_t *dm;
1218  snat_det_session_t *ses;
1219  int i;
1220 
1221  vlib_cli_output (vm, "NAT44 deterministic sessions:");
1222  /* *INDENT-OFF* */
1223  pool_foreach (dm, sm->det_maps,
1224  ({
1225  vec_foreach_index (i, dm->sessions)
1226  {
1227  ses = vec_elt_at_index (dm->sessions, i);
1228  if (ses->in_port)
1229  vlib_cli_output (vm, " %U", format_det_map_ses, dm, ses, &i);
1230  }
1231  }));
1232  /* *INDENT-ON* */
1233  return 0;
1234 }
1235 
1236 static clib_error_t *
1238  unformat_input_t * input,
1239  vlib_cli_command_t * cmd)
1240 {
1241  snat_main_t *sm = &snat_main;
1242  unformat_input_t _line_input, *line_input = &_line_input;
1243  ip4_address_t out_addr, ext_addr, in_addr;
1244  u32 out_port, ext_port;
1245  snat_det_map_t *dm;
1246  snat_det_session_t *ses;
1247  snat_det_out_key_t key;
1248  clib_error_t *error = 0;
1249 
1250  /* Get a line of input. */
1251  if (!unformat_user (input, unformat_line_input, line_input))
1252  return 0;
1253 
1254  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1255  {
1256  if (unformat (line_input, "%U:%d %U:%d",
1257  unformat_ip4_address, &out_addr, &out_port,
1258  unformat_ip4_address, &ext_addr, &ext_port))
1259  ;
1260  else
1261  {
1262  error = clib_error_return (0, "unknown input '%U'",
1263  format_unformat_error, line_input);
1264  goto done;
1265  }
1266  }
1267 
1268  unformat_free (line_input);
1269 
1270  dm = snat_det_map_by_out (sm, &out_addr);
1271  if (!dm)
1272  vlib_cli_output (vm, "no match");
1273  else
1274  {
1275  snat_det_reverse (dm, &ext_addr, (u16) out_port, &in_addr);
1276  key.ext_host_addr = out_addr;
1277  key.ext_host_port = ntohs ((u16) ext_port);
1278  key.out_port = ntohs ((u16) out_port);
1279  ses = snat_det_get_ses_by_out (dm, &out_addr, key.as_u64);
1280  if (!ses)
1281  vlib_cli_output (vm, "no match");
1282  else
1283  snat_det_ses_close (dm, ses);
1284  }
1285 
1286 done:
1287  unformat_free (line_input);
1288 
1289  return error;
1290 }
1291 
1292 static clib_error_t *
1294  unformat_input_t * input,
1295  vlib_cli_command_t * cmd)
1296 {
1297  snat_main_t *sm = &snat_main;
1298  unformat_input_t _line_input, *line_input = &_line_input;
1299  ip4_address_t in_addr, ext_addr;
1300  u32 in_port, ext_port;
1301  snat_det_map_t *dm;
1302  snat_det_session_t *ses;
1303  snat_det_out_key_t key;
1304  clib_error_t *error = 0;
1305 
1306  /* Get a line of input. */
1307  if (!unformat_user (input, unformat_line_input, line_input))
1308  return 0;
1309 
1310  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1311  {
1312  if (unformat (line_input, "%U:%d %U:%d",
1313  unformat_ip4_address, &in_addr, &in_port,
1314  unformat_ip4_address, &ext_addr, &ext_port))
1315  ;
1316  else
1317  {
1318  error = clib_error_return (0, "unknown input '%U'",
1319  format_unformat_error, line_input);
1320  goto done;
1321  }
1322  }
1323 
1324  unformat_free (line_input);
1325 
1326  dm = snat_det_map_by_user (sm, &in_addr);
1327  if (!dm)
1328  vlib_cli_output (vm, "no match");
1329  else
1330  {
1331  key.ext_host_addr = ext_addr;
1332  key.ext_host_port = ntohs ((u16) ext_port);
1333  ses =
1334  snat_det_find_ses_by_in (dm, &in_addr, ntohs ((u16) in_port), key);
1335  if (!ses)
1336  vlib_cli_output (vm, "no match");
1337  else
1338  snat_det_ses_close (dm, ses);
1339  }
1340 
1341 done:
1342  unformat_free (line_input);
1343 
1344  return error;
1345 }
1346 /* *INDENT-OFF* */
1347 
1348 /*?
1349  * @cliexpar
1350  * @cliexstart{set snat workers}
1351  * Set NAT workers if 2 or more workers available, use:
1352  * vpp# set snat workers 0-2,5
1353  * @cliexend
1354 ?*/
1355 VLIB_CLI_COMMAND (set_workers_command, static) = {
1356  .path = "set nat workers",
1357  .function = set_workers_command_fn,
1358  .short_help = "set nat workers <workers-list>",
1359 };
1360 
1361 /*?
1362  * @cliexpar
1363  * @cliexstart{show nat workers}
1364  * Show NAT workers.
1365  * vpp# show nat workers:
1366  * 2 workers
1367  * vpp_wk_0
1368  * vpp_wk_1
1369  * @cliexend
1370 ?*/
1371 VLIB_CLI_COMMAND (nat_show_workers_command, static) = {
1372  .path = "show nat workers",
1373  .short_help = "show nat workers",
1374  .function = nat_show_workers_commnad_fn,
1375 };
1376 
1377 /*?
1378  * @cliexpar
1379  * @cliexstart{snat ipfix logging}
1380  * To enable NAT IPFIX logging use:
1381  * vpp# nat ipfix logging
1382  * To set IPFIX exporter use:
1383  * vpp# set ipfix exporter collector 10.10.10.3 src 10.10.10.1
1384  * @cliexend
1385 ?*/
1386 VLIB_CLI_COMMAND (snat_ipfix_logging_enable_disable_command, static) = {
1387  .path = "nat ipfix logging",
1389  .short_help = "nat ipfix logging [domain <domain-id>] [src-port <port>] [disable]",
1390 };
1391 
1392 /*?
1393  * @cliexpar
1394  * @cliexstart{nat addr-port-assignment-alg}
1395  * Set address and port assignment algorithm
1396  * For the MAP-E CE limit port choice based on PSID use:
1397  * vpp# nat addr-port-assignment-alg map-e psid 10 psid-offset 6 psid-len 6
1398  * To set standard (default) address and port assignment algorithm use:
1399  * vpp# nat addr-port-assignment-alg default
1400  * @cliexend
1401 ?*/
1402 VLIB_CLI_COMMAND (nat44_set_alloc_addr_and_port_alg_command, static) = {
1403  .path = "nat addr-port-assignment-alg",
1404  .short_help = "nat addr-port-assignment-alg <alg-name> [<alg-params>]",
1406 };
1407 
1408 /*?
1409  * @cliexpar
1410  * @cliexstart{nat44 add address}
1411  * Add/delete NAT44 pool address.
1412  * To add NAT44 pool address use:
1413  * vpp# nat44 add address 172.16.1.3
1414  * vpp# nat44 add address 172.16.2.2 - 172.16.2.24
1415  * To add NAT44 pool address for specific tenant (identified by VRF id) use:
1416  * vpp# nat44 add address 172.16.1.3 tenant-vrf 10
1417  * @cliexend
1418 ?*/
1419 VLIB_CLI_COMMAND (add_address_command, static) = {
1420  .path = "nat44 add address",
1421  .short_help = "nat44 add address <ip4-range-start> [- <ip4-range-end>] "
1422  "[tenant-vrf <vrf-id>] [twice-nat] [del]",
1423  .function = add_address_command_fn,
1424 };
1425 
1426 /*?
1427  * @cliexpar
1428  * @cliexstart{show nat44 addresses}
1429  * Show NAT44 pool addresses.
1430  * vpp# show nat44 addresses
1431  * NAT44 pool addresses:
1432  * 172.16.2.2
1433  * tenant VRF independent
1434  * 10 busy udp ports
1435  * 0 busy tcp ports
1436  * 0 busy icmp ports
1437  * 172.16.1.3
1438  * tenant VRF: 10
1439  * 0 busy udp ports
1440  * 2 busy tcp ports
1441  * 0 busy icmp ports
1442  * NAT44 twice-nat pool addresses:
1443  * 10.20.30.72
1444  * tenant VRF independent
1445  * 0 busy udp ports
1446  * 0 busy tcp ports
1447  * 0 busy icmp ports
1448  * @cliexend
1449 ?*/
1450 VLIB_CLI_COMMAND (nat44_show_addresses_command, static) = {
1451  .path = "show nat44 addresses",
1452  .short_help = "show nat44 addresses",
1453  .function = nat44_show_addresses_command_fn,
1454 };
1455 
1456 /*?
1457  * @cliexpar
1458  * @cliexstart{set interface nat44}
1459  * Enable/disable NAT44 feature on the interface.
1460  * To enable NAT44 feature with local network interface use:
1461  * vpp# set interface nat44 in GigabitEthernet0/8/0
1462  * To enable NAT44 feature with external network interface use:
1463  * vpp# set interface nat44 out GigabitEthernet0/a/0
1464  * @cliexend
1465 ?*/
1466 VLIB_CLI_COMMAND (set_interface_snat_command, static) = {
1467  .path = "set interface nat44",
1468  .function = snat_feature_command_fn,
1469  .short_help = "set interface nat44 in <intfc> out <intfc> [output-feature] "
1470  "[del]",
1471 };
1472 
1473 /*?
1474  * @cliexpar
1475  * @cliexstart{show nat44 interfaces}
1476  * Show interfaces with NAT44 feature.
1477  * vpp# show nat44 interfaces
1478  * NAT44 interfaces:
1479  * GigabitEthernet0/8/0 in
1480  * GigabitEthernet0/a/0 out
1481  * @cliexend
1482 ?*/
1483 VLIB_CLI_COMMAND (nat44_show_interfaces_command, static) = {
1484  .path = "show nat44 interfaces",
1485  .short_help = "show nat44 interfaces",
1487 };
1488 
1489 /*?
1490  * @cliexpar
1491  * @cliexstart{nat44 add static mapping}
1492  * Static mapping allows hosts on the external network to initiate connection
1493  * to to the local network host.
1494  * To create static mapping between local host address 10.0.0.3 port 6303 and
1495  * external address 4.4.4.4 port 3606 for TCP protocol use:
1496  * vpp# nat44 add static mapping tcp local 10.0.0.3 6303 external 4.4.4.4 3606
1497  * If not runnig "static mapping only" NAT plugin mode use before:
1498  * vpp# nat44 add address 4.4.4.4
1499  * To create static mapping between local and external address use:
1500  * vpp# nat44 add static mapping local 10.0.0.3 external 4.4.4.4
1501  * @cliexend
1502 ?*/
1503 VLIB_CLI_COMMAND (add_static_mapping_command, static) = {
1504  .path = "nat44 add static mapping",
1505  .function = add_static_mapping_command_fn,
1506  .short_help =
1507  "nat44 add static mapping tcp|udp|icmp local <addr> [<port>] "
1508  "external <addr> [<port>] [vrf <table-id>] [twice-nat] [out2in-only] [del]",
1509 };
1510 
1511 /*?
1512  * @cliexpar
1513  * @cliexstart{nat44 add identity mapping}
1514  * Identity mapping translate an IP address to itself.
1515  * To create identity mapping for address 10.0.0.3 port 6303 for TCP protocol
1516  * use:
1517  * vpp# nat44 add identity mapping 10.0.0.3 tcp 6303
1518  * To create identity mapping for address 10.0.0.3 use:
1519  * vpp# nat44 add identity mapping 10.0.0.3
1520  * To create identity mapping for DHCP addressed interface use:
1521  * vpp# nat44 add identity mapping GigabitEthernet0/a/0 tcp 3606
1522  * @cliexend
1523 ?*/
1524 VLIB_CLI_COMMAND (add_identity_mapping_command, static) = {
1525  .path = "nat44 add identity mapping",
1526  .function = add_identity_mapping_command_fn,
1527  .short_help = "nat44 add identity mapping <interface>|<ip4-addr> "
1528  "[<protocol> <port>] [vrf <table-id>] [del]",
1529 };
1530 
1531 /*?
1532  * @cliexpar
1533  * @cliexstart{nat44 add load-balancing static mapping}
1534  * Service load balancing using NAT44
1535  * To add static mapping with load balancing for service with external IP
1536  * address 1.2.3.4 and TCP port 80 and mapped to 2 local servers
1537  * 10.100.10.10:8080 and 10.100.10.20:8080 with probability 80% resp. 20% use:
1538  * vpp# nat44 add load-balancing static mapping protocol tcp external 1.2.3.4:80 local 10.100.10.10:8080 probability 80 local 10.100.10.20:8080 probability 20
1539  * @cliexend
1540 ?*/
1541 VLIB_CLI_COMMAND (add_lb_static_mapping_command, static) = {
1542  .path = "nat44 add load-balancing static mapping",
1544  .short_help =
1545  "nat44 add load-balancing static mapping protocol tcp|udp "
1546  "external <addr>:<port> local <addr>:<port> probability <n> [twice-nat] "
1547  "[vrf <table-id>] [out2in-only] [del]",
1548 };
1549 
1550 /*?
1551  * @cliexpar
1552  * @cliexstart{show nat44 static mappings}
1553  * Show NAT44 static mappings.
1554  * vpp# show nat44 static mappings
1555  * NAT44 static mappings:
1556  * local 10.0.0.3 external 4.4.4.4 vrf 0
1557  * tcp local 192.168.0.4:6303 external 4.4.4.3:3606 vrf 0
1558  * tcp vrf 0 external 1.2.3.4:80 out2in-only
1559  * local 10.100.10.10:8080 probability 80
1560  * local 10.100.10.20:8080 probability 20
1561  * tcp local 10.100.3.8:8080 external 169.10.10.1:80 vrf 0 twice-nat
1562  * tcp local 10.0.0.10:3603 external GigabitEthernet0/a/0:6306 vrf 10
1563  * @cliexend
1564 ?*/
1565 VLIB_CLI_COMMAND (nat44_show_static_mappings_command, static) = {
1566  .path = "show nat44 static mappings",
1567  .short_help = "show nat44 static mappings",
1569 };
1570 
1571 /*?
1572  * @cliexpar
1573  * @cliexstart{nat44 add interface address}
1574  * Use NAT44 pool address from specific interfce
1575  * To add NAT44 pool address from specific interface use:
1576  * vpp# nat44 add interface address GigabitEthernet0/8/0
1577  * @cliexend
1578 ?*/
1579 VLIB_CLI_COMMAND (snat_add_interface_address_command, static) = {
1580  .path = "nat44 add interface address",
1581  .short_help = "nat44 add interface address <interface> [twice-nat] [del]",
1583 };
1584 
1585 /*?
1586  * @cliexpar
1587  * @cliexstart{show nat44 interface address}
1588  * Show NAT44 pool address interfaces
1589  * vpp# show nat44 interface address
1590  * NAT44 pool address interfaces:
1591  * GigabitEthernet0/a/0
1592  * NAT44 twice-nat pool address interfaces:
1593  * GigabitEthernet0/8/0
1594  * @cliexend
1595 ?*/
1596 VLIB_CLI_COMMAND (nat44_show_interface_address_command, static) = {
1597  .path = "show nat44 interface address",
1598  .short_help = "show nat44 interface address",
1600 };
1601 
1602 /*?
1603  * @cliexpar
1604  * @cliexstart{show nat44 sessions}
1605  * Show NAT44 sessions.
1606  * @cliexend
1607 ?*/
1608 VLIB_CLI_COMMAND (nat44_show_sessions_command, static) = {
1609  .path = "show nat44 sessions",
1610  .short_help = "show nat44 sessions [detail]",
1611  .function = nat44_show_sessions_command_fn,
1612 };
1613 
1614 /*?
1615  * @cliexpar
1616  * @cliexstart{nat44 del session}
1617  * To administratively delete NAT44 session by inside address and port use:
1618  * vpp# nat44 del session in 10.0.0.3:6303 tcp
1619  * To administratively delete NAT44 session by outside address and port use:
1620  * vpp# nat44 del session out 1.0.0.3:6033 udp
1621  * @cliexend
1622 ?*/
1623 VLIB_CLI_COMMAND (nat44_del_session_command, static) = {
1624  .path = "nat44 del session",
1625  .short_help = "nat44 del session in|out <addr>:<port> tcp|udp|icmp [vrf <id>]",
1626  .function = nat44_del_session_command_fn,
1627 };
1628 
1629 /*?
1630  * @cliexpar
1631  * @cliexstart{nat44 forwarding}
1632  * Enable or disable forwarding
1633  * Forward packets which don't match existing translation
1634  * or static mapping instead of dropping them.
1635  * To enable forwarding, use:
1636  * vpp# nat44 forwarding enable
1637  * To disable forwarding, use:
1638  * vpp# nat44 forwarding disable
1639  * @cliexend
1640 ?*/
1641 VLIB_CLI_COMMAND (snat_forwarding_set_command, static) = {
1642  .path = "nat44 forwarding",
1643  .short_help = "nat44 forwarding enable|disable",
1644  .function = snat_forwarding_set_command_fn,
1645 };
1646 
1647 /*?
1648  * @cliexpar
1649  * @cliexstart{nat44 deterministic add}
1650  * Create bijective mapping of inside address to outside address and port range
1651  * pairs, with the purpose of enabling deterministic NAT to reduce logging in
1652  * CGN deployments.
1653  * To create deterministic mapping between inside network 10.0.0.0/18 and
1654  * outside network 1.1.1.0/30 use:
1655  * # vpp# nat44 deterministic add in 10.0.0.0/18 out 1.1.1.0/30
1656  * @cliexend
1657 ?*/
1658 VLIB_CLI_COMMAND (snat_det_map_command, static) = {
1659  .path = "nat44 deterministic add",
1660  .short_help = "nat44 deterministic add in <addr>/<plen> out <addr>/<plen> [del]",
1661  .function = snat_det_map_command_fn,
1662 };
1663 
1664 /*?
1665  * @cliexpar
1666  * @cliexpstart{show nat44 deterministic mappings}
1667  * Show NAT44 deterministic mappings
1668  * vpp# show nat44 deterministic mappings
1669  * NAT44 deterministic mappings:
1670  * in 10.0.0.0/24 out 1.1.1.1/32
1671  * outside address sharing ratio: 256
1672  * number of ports per inside host: 252
1673  * sessions number: 0
1674  * @cliexend
1675 ?*/
1676 VLIB_CLI_COMMAND (nat44_det_show_mappings_command, static) = {
1677  .path = "show nat44 deterministic mappings",
1678  .short_help = "show nat44 deterministic mappings",
1680 };
1681 
1682 /*?
1683  * @cliexpar
1684  * @cliexstart{nat44 deterministic forward}
1685  * Return outside address and port range from inside address for deterministic
1686  * NAT.
1687  * To obtain outside address and port of inside host use:
1688  * vpp# nat44 deterministic forward 10.0.0.2
1689  * 1.1.1.0:<1054-1068>
1690  * @cliexend
1691 ?*/
1692 VLIB_CLI_COMMAND (snat_det_forward_command, static) = {
1693  .path = "nat44 deterministic forward",
1694  .short_help = "nat44 deterministic forward <addr>",
1695  .function = snat_det_forward_command_fn,
1696 };
1697 
1698 /*?
1699  * @cliexpar
1700  * @cliexstart{nat44 deterministic reverse}
1701  * Return inside address from outside address and port for deterministic NAT.
1702  * To obtain inside host address from outside address and port use:
1703  * #vpp nat44 deterministic reverse 1.1.1.1:1276
1704  * 10.0.16.16
1705  * @cliexend
1706 ?*/
1707 VLIB_CLI_COMMAND (snat_det_reverse_command, static) = {
1708  .path = "nat44 deterministic reverse",
1709  .short_help = "nat44 deterministic reverse <addr>:<port>",
1710  .function = snat_det_reverse_command_fn,
1711 };
1712 
1713 /*?
1714  * @cliexpar
1715  * @cliexstart{set nat44 deterministic timeout}
1716  * Set values of timeouts for deterministic NAT (in seconds), use:
1717  * vpp# set nat44 deterministic timeout udp 120 tcp-established 7500
1718  * tcp-transitory 250 icmp 90
1719  * To reset default values use:
1720  * vpp# set nat44 deterministic timeout reset
1721  * @cliexend
1722 ?*/
1723 VLIB_CLI_COMMAND (set_timeout_command, static) = {
1724  .path = "set nat44 deterministic timeout",
1725  .function = set_timeout_command_fn,
1726  .short_help =
1727  "set nat44 deterministic timeout [udp <sec> | tcp-established <sec> "
1728  "tcp-transitory <sec> | icmp <sec> | reset]",
1729 };
1730 
1731 /*?
1732  * @cliexpar
1733  * @cliexstart{show nat44 deterministic timeouts}
1734  * Show values of timeouts for deterministic NAT.
1735  * vpp# show nat44 deterministic timeouts
1736  * udp timeout: 300sec
1737  * tcp-established timeout: 7440sec
1738  * tcp-transitory timeout: 240sec
1739  * icmp timeout: 60sec
1740  * @cliexend
1741 ?*/
1742 VLIB_CLI_COMMAND (nat44_det_show_timeouts_command, static) = {
1743  .path = "show nat44 deterministic timeouts",
1744  .short_help = "show nat44 deterministic timeouts",
1746 };
1747 
1748 /*?
1749  * @cliexpar
1750  * @cliexstart{show nat44 deterministic sessions}
1751  * Show NAT44 deterministic sessions.
1752  * vpp# show nat44 deterministic sessions
1753  * NAT44 deterministic sessions:
1754  * in 10.0.0.3:3005 out 1.1.1.2:1146 external host 172.16.1.2:3006 state: udp-active expire: 306
1755  * in 10.0.0.3:3000 out 1.1.1.2:1141 external host 172.16.1.2:3001 state: udp-active expire: 306
1756  * in 10.0.0.4:3005 out 1.1.1.2:1177 external host 172.16.1.2:3006 state: udp-active expire: 306
1757  * @cliexend
1758 ?*/
1759 VLIB_CLI_COMMAND (nat44_det_show_sessions_command, static) = {
1760  .path = "show nat44 deterministic sessions",
1761  .short_help = "show nat44 deterministic sessions",
1763 };
1764 
1765 /*?
1766  * @cliexpar
1767  * @cliexstart{nat44 deterministic close session out}
1768  * Close session using outside ip address and port
1769  * and external ip address and port, use:
1770  * vpp# nat44 deterministic close session out 1.1.1.1:1276 2.2.2.2:2387
1771  * @cliexend
1772 ?*/
1773 VLIB_CLI_COMMAND (snat_det_close_sesion_out_command, static) = {
1774  .path = "nat44 deterministic close session out",
1775  .short_help = "nat44 deterministic close session out "
1776  "<out_addr>:<out_port> <ext_addr>:<ext_port>",
1777  .function = snat_det_close_session_out_fn,
1778 };
1779 
1780 /*?
1781  * @cliexpar
1782  * @cliexstart{nat44 deterministic close session in}
1783  * Close session using inside ip address and port
1784  * and external ip address and port, use:
1785  * vpp# nat44 deterministic close session in 3.3.3.3:3487 2.2.2.2:2387
1786  * @cliexend
1787 ?*/
1788 VLIB_CLI_COMMAND (snat_det_close_session_in_command, static) = {
1789  .path = "nat44 deterministic close session in",
1790  .short_help = "nat44 deterministic close session in "
1791  "<in_addr>:<in_port> <ext_addr>:<ext_port>",
1792  .function = snat_det_close_session_in_fn,
1793 };
1794 
1795 /* *INDENT-ON* */
1796 
1797 /*
1798  * fd.io coding-style-patch-verification: ON
1799  *
1800  * Local Variables:
1801  * eval: (c-set-style "gnu")
1802  * End:
1803  */
static clib_error_t * add_address_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:186
static clib_error_t * snat_det_reverse_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:1100
#define vec_foreach_index(var, v)
Iterate over vector indices.
static clib_error_t * nat44_show_sessions_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:844
int snat_del_address(snat_main_t *sm, ip4_address_t addr, u8 delete_sm, u8 twice_nat)
Definition: nat.c:1414
u16 ext_host_port
Definition: nat.h:79
u16 out_port
Definition: nat.h:80
u32 icmp_timeout
Definition: nat.h:379
vnet_main_t * vnet_get_main(void)
Definition: misc.c:47
#define SNAT_TCP_ESTABLISHED_TIMEOUT
Definition: nat.h:36
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:520
static void snat_det_ses_close(snat_det_map_t *dm, snat_det_session_t *ses)
Definition: nat_det.h:180
int i
static snat_det_session_t * snat_det_find_ses_by_in(snat_det_map_t *dm, ip4_address_t *in_addr, u16 in_port, snat_det_out_key_t out_key)
Definition: nat_det.h:129
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:983
static void snat_det_forward(snat_det_map_t *dm, ip4_address_t *in_addr, ip4_address_t *out_addr, u16 *lo_port)
Definition: nat_det.h:75
unformat_function_t unformat_vnet_sw_interface
snat_det_map_t * det_maps
Definition: nat.h:354
static clib_error_t * add_identity_mapping_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:572
static void snat_det_reverse(snat_det_map_t *dm, ip4_address_t *out_addr, u16 out_port, ip4_address_t *in_addr)
Definition: nat_det.h:90
static clib_error_t * snat_det_close_session_out_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:1237
format_function_t format_vnet_sw_if_index_name
int snat_interface_add_del(u32 sw_if_index, u8 is_inside, int is_del)
Definition: nat.c:1527
int nat44_add_del_lb_static_mapping(ip4_address_t e_addr, u16 e_port, snat_protocol_t proto, u32 vrf_id, nat44_lb_addr_port_t *locals, u8 is_add, u8 twice_nat, u8 out2in_only, u8 *tag)
Definition: nat.c:1141
format_function_t format_ip4_address
Definition: format.h:79
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:440
unformat_function_t unformat_ip4_address
Definition: format.h:76
static clib_error_t * snat_det_map_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:980
ip4_address_t ext_host_addr
Definition: nat.h:78
static clib_error_t * snat_det_close_session_in_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:1293
static clib_error_t * snat_det_forward_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:1056
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
#define clib_error_return(e, args...)
Definition: error.h:99
int snat_ipfix_logging_enable_disable(int enable, u32 domain_id, u16 src_port)
Enable/disable NAT plugin IPFIX logging.
static clib_error_t * nat44_set_alloc_addr_and_port_alg_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:149
unformat_function_t unformat_line_input
Definition: format.h:281
u32 * auto_add_sw_if_indices_twice_nat
Definition: nat.h:335
vlib_worker_thread_t * vlib_worker_threads
Definition: threads.c:35
static clib_error_t * nat44_show_addresses_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:283
static snat_det_map_t * snat_det_map_by_out(snat_main_t *sm, ip4_address_t *out_addr)
Definition: nat_det.h:60
static clib_error_t * snat_forwarding_set_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:931
struct _unformat_input_t unformat_input_t
static clib_error_t * nat44_det_show_sessions_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:1212
u8 out2in_dpo
Definition: nat.h:363
#define SNAT_UDP_TIMEOUT
Definition: nat.h:33
snat_static_mapping_t * static_mappings
Definition: nat.h:317
u32 udp_timeout
Definition: nat.h:376
u8 static_mapping_only
Definition: nat.h:360
static clib_error_t * snat_feature_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:323
int snat_add_static_mapping(ip4_address_t l_addr, ip4_address_t e_addr, u16 l_port, u16 e_port, u32 vrf_id, int addr_only, u32 sw_if_index, snat_protocol_t proto, int is_add, u8 twice_nat, u8 out2in_only, u8 *tag)
Add static mapping.
Definition: nat.c:663
void nat_set_alloc_addr_and_port_default(void)
Definition: nat.c:3076
vnet_main_t * vnet_main
Definition: nat.h:386
u32 inside_vrf_id
Definition: nat.h:372
static clib_error_t * nat44_det_show_timeouts_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:1195
snat_interface_t * output_feature_interfaces
Definition: nat.h:321
snat_main_t snat_main
Definition: nat.c:35
snat_user_t * users
Definition: nat.h:256
static clib_error_t * add_lb_static_mapping_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:647
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
static clib_error_t * snat_ipfix_logging_enable_disable_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:103
u32 ft_table_id
Table ID (hash key) for this FIB.
Definition: fib_table.h:89
vlib_main_t * vm
Definition: buffer.c:294
static clib_error_t * nat_show_workers_commnad_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:80
static clib_error_t * nat44_show_interfaces_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:433
u32 outside_vrf_id
Definition: nat.h:370
void nat44_add_del_address_dpo(ip4_address_t addr, u8 is_add)
Definition: nat.c:2218
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:336
deterministic NAT definitions
format_function_t format_snat_static_map_to_resolve
Definition: nat.h:433
#define clib_warning(format, args...)
Definition: error.h:59
int snat_interface_add_del_output_feature(u32 sw_if_index, u8 is_inside, int is_del)
Definition: nat.c:1683
static clib_error_t * set_timeout_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:1150
u32 tcp_transitory_timeout
Definition: nat.h:378
int snat_det_add_map(snat_main_t *sm, ip4_address_t *in_addr, u8 in_plen, ip4_address_t *out_addr, u8 out_plen, int is_add)
Add/delete deterministic NAT mapping.
Definition: nat_det.c:40
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
u32 * auto_add_sw_if_indices
Definition: nat.h:334
static snat_det_map_t * snat_det_map_by_user(snat_main_t *sm, ip4_address_t *user_addr)
Definition: nat_det.h:45
u32 num_workers
Definition: nat.h:298
unsigned int u32
Definition: types.h:88
u32 first_worker_index
Definition: nat.h:299
static clib_error_t * add_static_mapping_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:466
#define clib_bitmap_free(v)
Free a bitmap.
Definition: bitmap.h:92
size_t count
Definition: vapi.c:42
ip4_address_t addr
Definition: nat.h:177
int nat44_del_session(snat_main_t *sm, ip4_address_t *addr, u16 port, snat_protocol_t proto, u32 vrf_id, int is_in)
Definition: nat.c:3014
snat_address_t * twice_nat_addresses
Definition: nat.h:331
static clib_error_t * nat44_del_session_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:874
u64 uword
Definition: types.h:112
void increment_v4_address(ip4_address_t *a)
Definition: nat.c:610
unsigned short u16
Definition: types.h:57
void snat_add_address(snat_main_t *sm, ip4_address_t *addr, u32 vrf_id, u8 twice_nat)
Definition: nat.c:542
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
unsigned char u8
Definition: types.h:56
u16 ports_per_host
Definition: nat.h:200
static uword unformat_bitmap_list(unformat_input_t *input, va_list *va)
unformat a list of bit ranges into a bitmap (eg "0-3,5-7,11" )
Definition: bitmap.h:693
static clib_error_t * snat_add_interface_address_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:764
u32 * workers
Definition: nat.h:301
snat_main_per_thread_data_t * per_thread_data
Definition: nat.h:308
static void unformat_free(unformat_input_t *i)
Definition: format.h:161
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
snat_address_t * addresses
Definition: nat.h:324
int snat_add_interface_address(snat_main_t *sm, u32 sw_if_index, int is_del, u8 twice_nat)
Definition: nat.c:2947
static clib_error_t * nat44_show_interface_address_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:817
static clib_error_t * nat44_show_static_mappings_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:742
#define SNAT_ICMP_TIMEOUT
Definition: nat.h:38
uword unformat_snat_protocol(unformat_input_t *input, va_list *args)
Definition: nat.c:2241
static snat_det_session_t * snat_det_get_ses_by_out(snat_det_map_t *dm, ip4_address_t *in_addr, u64 out_key)
Definition: nat_det.h:112
snat_static_map_resolve_t * to_resolve
Definition: nat.h:338
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
u8 forwarding_enabled
Definition: nat.h:357
#define vec_foreach(var, vec)
Vector iterator.
int snat_set_workers(uword *bitmap)
Definition: nat.c:1778
vhost_vring_addr_t addr
Definition: vhost-user.h:83
void nat_set_alloc_addr_and_port_mape(u16 psid, u16 psid_offset, u16 psid_length)
Definition: nat.c:3065
#define SNAT_TCP_TRANSITORY_TIMEOUT
Definition: nat.h:35
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:680
static clib_error_t * nat44_det_show_mappings_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:1030
u32 fib_index
Definition: nat.h:178
static clib_error_t * set_workers_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:26
snat_interface_t * interfaces
Definition: nat.h:320
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169
u32 tcp_established_timeout
Definition: nat.h:377