FD.io VPP  v19.01.1-17-ge106252
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 <nat/nat64.h>
24 #include <nat/nat_inlines.h>
25 #include <nat/nat_affinity.h>
26 #include <vnet/fib/fib_table.h>
27 
28 #define UNSUPPORTED_IN_DET_MODE_STR \
29  "This command is unsupported in deterministic mode"
30 #define SUPPORTED_ONLY_IN_DET_MODE_STR \
31  "This command is supported only in deterministic mode"
32 
33 static clib_error_t *
35  unformat_input_t * input, vlib_cli_command_t * cmd)
36 {
37  unformat_input_t _line_input, *line_input = &_line_input;
38  snat_main_t *sm = &snat_main;
39  uword *bitmap = 0;
40  int rv = 0;
41  clib_error_t *error = 0;
42 
43  if (sm->deterministic)
45 
46  /* Get a line of input. */
47  if (!unformat_user (input, unformat_line_input, line_input))
48  return 0;
49 
50  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
51  {
52  if (unformat (line_input, "%U", unformat_bitmap_list, &bitmap))
53  ;
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  if (bitmap == 0)
63  {
64  error = clib_error_return (0, "List of workers must be specified.");
65  goto done;
66  }
67 
68  rv = snat_set_workers (bitmap);
69 
70  clib_bitmap_free (bitmap);
71 
72  switch (rv)
73  {
74  case VNET_API_ERROR_INVALID_WORKER:
75  error = clib_error_return (0, "Invalid worker(s).");
76  goto done;
77  case VNET_API_ERROR_FEATURE_DISABLED:
78  error = clib_error_return (0,
79  "Supported only if 2 or more workes available.");
80  goto done;
81  default:
82  break;
83  }
84 
85 done:
86  unformat_free (line_input);
87 
88  return error;
89 }
90 
91 static clib_error_t *
93  vlib_cli_command_t * cmd)
94 {
95  snat_main_t *sm = &snat_main;
96  u32 *worker;
97 
98  if (sm->deterministic)
100 
101  if (sm->num_workers > 1)
102  {
103  vlib_cli_output (vm, "%d workers", vec_len (sm->workers));
104  /* *INDENT-OFF* */
105  vec_foreach (worker, sm->workers)
106  {
108  vlib_worker_threads + *worker + sm->first_worker_index;
109  vlib_cli_output (vm, " %s", w->name);
110  }
111  /* *INDENT-ON* */
112  }
113 
114  return 0;
115 }
116 
117 static clib_error_t *
119  unformat_input_t * input,
120  vlib_cli_command_t * cmd)
121 {
122  unformat_input_t _line_input, *line_input = &_line_input;
123  u32 domain_id = 0;
124  u32 src_port = 0;
125  u8 enable = 1;
126  int rv = 0;
127  clib_error_t *error = 0;
128 
129  /* Get a line of input. */
130  if (!unformat_user (input, unformat_line_input, line_input))
131  return 0;
132 
133  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
134  {
135  if (unformat (line_input, "domain %d", &domain_id))
136  ;
137  else if (unformat (line_input, "src-port %d", &src_port))
138  ;
139  else if (unformat (line_input, "disable"))
140  enable = 0;
141  else
142  {
143  error = clib_error_return (0, "unknown input '%U'",
144  format_unformat_error, line_input);
145  goto done;
146  }
147  }
148 
149  rv = snat_ipfix_logging_enable_disable (enable, domain_id, (u16) src_port);
150 
151  if (rv)
152  {
153  error = clib_error_return (0, "ipfix logging enable failed");
154  goto done;
155  }
156 
157 done:
158  unformat_free (line_input);
159 
160  return error;
161 }
162 
163 static clib_error_t *
165  vlib_cli_command_t * cmd)
166 {
167  snat_main_t *sm = &snat_main;
170  int i;
171  int verbose = 0;
172 
173  if (unformat (input, "detail"))
174  verbose = 1;
175  else if (unformat (input, "verbose"))
176  verbose = 2;
177 
178  vlib_cli_output (vm, "%U", format_bihash_8_8, &sm->static_mapping_by_local,
179  verbose);
180  vlib_cli_output (vm, "%U",
181  format_bihash_8_8, &sm->static_mapping_by_external,
182  verbose);
184  {
185  tsm = vec_elt_at_index (sm->per_thread_data, i);
186  vlib_cli_output (vm, "-------- thread %d %s --------\n",
187  i, vlib_worker_threads[i].name);
188  if (sm->endpoint_dependent)
189  {
190  vlib_cli_output (vm, "%U", format_bihash_16_8, &tsm->in2out_ed,
191  verbose);
192  vlib_cli_output (vm, "%U", format_bihash_16_8, &tsm->out2in_ed,
193  verbose);
194  }
195  else
196  {
197  vlib_cli_output (vm, "%U", format_bihash_8_8, &tsm->in2out, verbose);
198  vlib_cli_output (vm, "%U", format_bihash_8_8, &tsm->out2in, verbose);
199  }
200  vlib_cli_output (vm, "%U", format_bihash_8_8, &tsm->user_hash, verbose);
201  }
202 
203  if (sm->endpoint_dependent)
204  vlib_cli_output (vm, "%U", format_bihash_16_8, &nam->affinity_hash,
205  verbose);
206  return 0;
207 }
208 
209 static clib_error_t *
211  unformat_input_t * input,
212  vlib_cli_command_t * cmd)
213 {
214  unformat_input_t _line_input, *line_input = &_line_input;
215  snat_main_t *sm = &snat_main;
216  clib_error_t *error = 0;
217  u32 psid, psid_offset, psid_length, port_start, port_end;
218 
219  if (sm->deterministic)
221 
222  /* Get a line of input. */
223  if (!unformat_user (input, unformat_line_input, line_input))
224  return 0;
225 
226  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
227  {
228  if (unformat (line_input, "default"))
230  else
231  if (unformat
232  (line_input, "map-e psid %d psid-offset %d psid-len %d", &psid,
233  &psid_offset, &psid_length))
234  nat_set_alloc_addr_and_port_mape ((u16) psid, (u16) psid_offset,
235  (u16) psid_length);
236  else
237  if (unformat
238  (line_input, "port-range %d - %d", &port_start, &port_end))
239  {
240  if (port_end <= port_start)
241  {
242  error =
244  "The end-port must be greater than start-port");
245  goto done;
246  }
248  (u16) port_end);
249  }
250  else
251  {
252  error = clib_error_return (0, "unknown input '%U'",
253  format_unformat_error, line_input);
254  goto done;
255  }
256  }
257 
258 done:
259  unformat_free (line_input);
260 
261  return error;
262 };
263 
264 static clib_error_t *
266  unformat_input_t * input,
267  vlib_cli_command_t * cmd)
268 {
269  snat_main_t *sm = &snat_main;
270 
271  if (sm->deterministic)
273 
274  vlib_cli_output (vm, "NAT address and port: %U",
277  switch (sm->addr_and_port_alloc_alg)
278  {
279  case NAT_ADDR_AND_PORT_ALLOC_ALG_MAPE:
280  vlib_cli_output (vm, " psid %d psid-offset %d psid-len %d", sm->psid,
281  sm->psid_offset, sm->psid_length);
282  break;
283  case NAT_ADDR_AND_PORT_ALLOC_ALG_RANGE:
284  vlib_cli_output (vm, " start-port %d end-port %d", sm->start_port,
285  sm->end_port);
286  break;
287  default:
288  break;
289  }
290 
291  return 0;
292 }
293 
294 static clib_error_t *
296  vlib_cli_command_t * cmd)
297 {
298  unformat_input_t _line_input, *line_input = &_line_input;
299  snat_main_t *sm = &snat_main;
300  clib_error_t *error = 0;
301  u32 mss;
302 
303  /* Get a line of input. */
304  if (!unformat_user (input, unformat_line_input, line_input))
305  return 0;
306 
307  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
308  {
309  if (unformat (line_input, "disable"))
310  sm->mss_clamping = 0;
311  else if (unformat (line_input, "%d", &mss))
312  {
313  sm->mss_clamping = (u16) mss;
314  sm->mss_value_net = clib_host_to_net_u16 (sm->mss_clamping);
315  }
316  else
317  {
318  error = clib_error_return (0, "unknown input '%U'",
319  format_unformat_error, line_input);
320  goto done;
321  }
322  }
323 
324 done:
325  unformat_free (line_input);
326 
327  return error;
328 }
329 
330 static clib_error_t *
332  vlib_cli_command_t * cmd)
333 {
334  snat_main_t *sm = &snat_main;
335 
336  if (sm->mss_clamping)
337  vlib_cli_output (vm, "mss-clamping %d", sm->mss_clamping);
338  else
339  vlib_cli_output (vm, "mss-clamping disabled");
340 
341  return 0;
342 }
343 
344 static clib_error_t *
346  unformat_input_t * input, vlib_cli_command_t * cmd)
347 {
348  unformat_input_t _line_input, *line_input = &_line_input;
349  snat_main_t *sm = &snat_main;
350  ip4_address_t start_addr, end_addr, this_addr;
351  u32 start_host_order, end_host_order;
352  u32 vrf_id = ~0;
353  int i, count;
354  int is_add = 1;
355  int rv = 0;
356  clib_error_t *error = 0;
357  u8 twice_nat = 0;
358 
359  if (sm->deterministic)
361 
362  /* Get a line of input. */
363  if (!unformat_user (input, unformat_line_input, line_input))
364  return 0;
365 
366  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
367  {
368  if (unformat (line_input, "%U - %U",
369  unformat_ip4_address, &start_addr,
370  unformat_ip4_address, &end_addr))
371  ;
372  else if (unformat (line_input, "tenant-vrf %u", &vrf_id))
373  ;
374  else if (unformat (line_input, "%U", unformat_ip4_address, &start_addr))
375  end_addr = start_addr;
376  else if (unformat (line_input, "twice-nat"))
377  twice_nat = 1;
378  else if (unformat (line_input, "del"))
379  is_add = 0;
380  else
381  {
382  error = clib_error_return (0, "unknown input '%U'",
383  format_unformat_error, line_input);
384  goto done;
385  }
386  }
387 
388  if (sm->static_mapping_only)
389  {
390  error = clib_error_return (0, "static mapping only mode");
391  goto done;
392  }
393 
394  start_host_order = clib_host_to_net_u32 (start_addr.as_u32);
395  end_host_order = clib_host_to_net_u32 (end_addr.as_u32);
396 
397  if (end_host_order < start_host_order)
398  {
399  error = clib_error_return (0, "end address less than start address");
400  goto done;
401  }
402 
403  count = (end_host_order - start_host_order) + 1;
404 
405  if (count > 1024)
406  nat_log_info ("%U - %U, %d addresses...",
407  format_ip4_address, &start_addr,
408  format_ip4_address, &end_addr, count);
409 
410  this_addr = start_addr;
411 
412  for (i = 0; i < count; i++)
413  {
414  if (is_add)
415  rv = snat_add_address (sm, &this_addr, vrf_id, twice_nat);
416  else
417  rv = snat_del_address (sm, this_addr, 0, twice_nat);
418 
419  switch (rv)
420  {
421  case VNET_API_ERROR_VALUE_EXIST:
422  error = clib_error_return (0, "NAT address already in use.");
423  goto done;
424  case VNET_API_ERROR_NO_SUCH_ENTRY:
425  error = clib_error_return (0, "NAT address not exist.");
426  goto done;
427  case VNET_API_ERROR_UNSPECIFIED:
428  error =
429  clib_error_return (0, "NAT address used in static mapping.");
430  goto done;
431  case VNET_API_ERROR_FEATURE_DISABLED:
432  error =
434  "twice NAT available only for endpoint-dependent mode.");
435  goto done;
436  default:
437  break;
438  }
439 
440  if (sm->out2in_dpo)
441  nat44_add_del_address_dpo (this_addr, is_add);
442 
443  increment_v4_address (&this_addr);
444  }
445 
446 done:
447  unformat_free (line_input);
448 
449  return error;
450 }
451 
452 static clib_error_t *
454  vlib_cli_command_t * cmd)
455 {
456  snat_main_t *sm = &snat_main;
457  snat_address_t *ap;
458 
459  if (sm->deterministic)
461 
462  vlib_cli_output (vm, "NAT44 pool addresses:");
463  /* *INDENT-OFF* */
464  vec_foreach (ap, sm->addresses)
465  {
466  vlib_cli_output (vm, "%U", format_ip4_address, &ap->addr);
467  if (ap->fib_index != ~0)
468  vlib_cli_output (vm, " tenant VRF: %u",
470  else
471  vlib_cli_output (vm, " tenant VRF independent");
472  #define _(N, i, n, s) \
473  vlib_cli_output (vm, " %d busy %s ports", ap->busy_##n##_ports, s);
475  #undef _
476  }
477  vlib_cli_output (vm, "NAT44 twice-nat pool addresses:");
479  {
480  vlib_cli_output (vm, "%U", format_ip4_address, &ap->addr);
481  if (ap->fib_index != ~0)
482  vlib_cli_output (vm, " tenant VRF: %u",
484  else
485  vlib_cli_output (vm, " tenant VRF independent");
486  #define _(N, i, n, s) \
487  vlib_cli_output (vm, " %d busy %s ports", ap->busy_##n##_ports, s);
489  #undef _
490  }
491  /* *INDENT-ON* */
492  return 0;
493 }
494 
495 static clib_error_t *
497  unformat_input_t * input, vlib_cli_command_t * cmd)
498 {
499  unformat_input_t _line_input, *line_input = &_line_input;
500  vnet_main_t *vnm = vnet_get_main ();
501  clib_error_t *error = 0;
503  u32 *inside_sw_if_indices = 0;
504  u32 *outside_sw_if_indices = 0;
505  u8 is_output_feature = 0;
506  int is_del = 0;
507  int i;
508 
509  sw_if_index = ~0;
510 
511  /* Get a line of input. */
512  if (!unformat_user (input, unformat_line_input, line_input))
513  return 0;
514 
515  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
516  {
517  if (unformat (line_input, "in %U", unformat_vnet_sw_interface,
518  vnm, &sw_if_index))
519  vec_add1 (inside_sw_if_indices, sw_if_index);
520  else if (unformat (line_input, "out %U", unformat_vnet_sw_interface,
521  vnm, &sw_if_index))
522  vec_add1 (outside_sw_if_indices, sw_if_index);
523  else if (unformat (line_input, "output-feature"))
524  is_output_feature = 1;
525  else if (unformat (line_input, "del"))
526  is_del = 1;
527  else
528  {
529  error = clib_error_return (0, "unknown input '%U'",
530  format_unformat_error, line_input);
531  goto done;
532  }
533  }
534 
535  if (vec_len (inside_sw_if_indices))
536  {
537  for (i = 0; i < vec_len (inside_sw_if_indices); i++)
538  {
539  sw_if_index = inside_sw_if_indices[i];
540  if (is_output_feature)
541  {
543  (sw_if_index, 1, is_del))
544  {
545  error = clib_error_return (0, "%s %U failed",
546  is_del ? "del" : "add",
548  vnm, sw_if_index);
549  goto done;
550  }
551  }
552  else
553  {
554  if (snat_interface_add_del (sw_if_index, 1, is_del))
555  {
556  error = clib_error_return (0, "%s %U failed",
557  is_del ? "del" : "add",
559  vnm, sw_if_index);
560  goto done;
561  }
562  }
563  }
564  }
565 
566  if (vec_len (outside_sw_if_indices))
567  {
568  for (i = 0; i < vec_len (outside_sw_if_indices); i++)
569  {
570  sw_if_index = outside_sw_if_indices[i];
571  if (is_output_feature)
572  {
574  (sw_if_index, 0, is_del))
575  {
576  error = clib_error_return (0, "%s %U failed",
577  is_del ? "del" : "add",
579  vnm, sw_if_index);
580  goto done;
581  }
582  }
583  else
584  {
585  if (snat_interface_add_del (sw_if_index, 0, is_del))
586  {
587  error = clib_error_return (0, "%s %U failed",
588  is_del ? "del" : "add",
590  vnm, sw_if_index);
591  goto done;
592  }
593  }
594  }
595  }
596 
597 done:
598  unformat_free (line_input);
599  vec_free (inside_sw_if_indices);
600  vec_free (outside_sw_if_indices);
601 
602  return error;
603 }
604 
605 static clib_error_t *
607  vlib_cli_command_t * cmd)
608 {
609  snat_main_t *sm = &snat_main;
611  vnet_main_t *vnm = vnet_get_main ();
612 
613  vlib_cli_output (vm, "NAT44 interfaces:");
614  /* *INDENT-OFF* */
615  pool_foreach (i, sm->interfaces,
616  ({
617  vlib_cli_output (vm, " %U %s", format_vnet_sw_if_index_name, vnm,
618  i->sw_if_index,
619  (nat_interface_is_inside(i) &&
620  nat_interface_is_outside(i)) ? "in out" :
621  (nat_interface_is_inside(i) ? "in" : "out"));
622  }));
623 
625  ({
626  vlib_cli_output (vm, " %U output-feature %s",
627  format_vnet_sw_if_index_name, vnm,
628  i->sw_if_index,
629  (nat_interface_is_inside(i) &&
630  nat_interface_is_outside(i)) ? "in out" :
631  (nat_interface_is_inside(i) ? "in" : "out"));
632  }));
633  /* *INDENT-ON* */
634 
635  return 0;
636 }
637 
638 static clib_error_t *
640  unformat_input_t * input,
641  vlib_cli_command_t * cmd)
642 {
643  unformat_input_t _line_input, *line_input = &_line_input;
644  snat_main_t *sm = &snat_main;
645  clib_error_t *error = 0;
646  ip4_address_t l_addr, e_addr;
647  u32 l_port = 0, e_port = 0, vrf_id = ~0;
648  int is_add = 1;
649  int addr_only = 1;
650  u32 sw_if_index = ~0;
651  vnet_main_t *vnm = vnet_get_main ();
652  int rv;
653  snat_protocol_t proto = ~0;
654  u8 proto_set = 0;
656  u8 out2in_only = 0;
657 
658  if (sm->deterministic)
660 
661  /* Get a line of input. */
662  if (!unformat_user (input, unformat_line_input, line_input))
663  return 0;
664 
665  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
666  {
667  if (unformat (line_input, "local %U %u", unformat_ip4_address, &l_addr,
668  &l_port))
669  addr_only = 0;
670  else
671  if (unformat (line_input, "local %U", unformat_ip4_address, &l_addr))
672  ;
673  else if (unformat (line_input, "external %U %u", unformat_ip4_address,
674  &e_addr, &e_port))
675  addr_only = 0;
676  else if (unformat (line_input, "external %U", unformat_ip4_address,
677  &e_addr))
678  ;
679  else if (unformat (line_input, "external %U %u",
680  unformat_vnet_sw_interface, vnm, &sw_if_index,
681  &e_port))
682  addr_only = 0;
683 
684  else if (unformat (line_input, "external %U",
685  unformat_vnet_sw_interface, vnm, &sw_if_index))
686  ;
687  else if (unformat (line_input, "vrf %u", &vrf_id))
688  ;
689  else if (unformat (line_input, "%U", unformat_snat_protocol, &proto))
690  proto_set = 1;
691  else if (unformat (line_input, "twice-nat"))
692  twice_nat = TWICE_NAT;
693  else if (unformat (line_input, "self-twice-nat"))
694  twice_nat = TWICE_NAT_SELF;
695  else if (unformat (line_input, "out2in-only"))
696  out2in_only = 1;
697  else if (unformat (line_input, "del"))
698  is_add = 0;
699  else
700  {
701  error = clib_error_return (0, "unknown input: '%U'",
702  format_unformat_error, line_input);
703  goto done;
704  }
705  }
706 
707  if (twice_nat && addr_only)
708  {
709  error = clib_error_return (0, "twice NAT only for 1:1 NAPT");
710  goto done;
711  }
712 
713  if (!addr_only && !proto_set)
714  {
715  error = clib_error_return (0, "missing protocol");
716  goto done;
717  }
718 
719  rv = snat_add_static_mapping (l_addr, e_addr, (u16) l_port, (u16) e_port,
720  vrf_id, addr_only, sw_if_index, proto, is_add,
721  twice_nat, out2in_only, 0, 0);
722 
723  switch (rv)
724  {
725  case VNET_API_ERROR_INVALID_VALUE:
726  error = clib_error_return (0, "External port already in use.");
727  goto done;
728  case VNET_API_ERROR_NO_SUCH_ENTRY:
729  if (is_add)
730  error = clib_error_return (0, "External address must be allocated.");
731  else
732  error = clib_error_return (0, "Mapping not exist.");
733  goto done;
734  case VNET_API_ERROR_NO_SUCH_FIB:
735  error = clib_error_return (0, "No such VRF id.");
736  goto done;
737  case VNET_API_ERROR_VALUE_EXIST:
738  error = clib_error_return (0, "Mapping already exist.");
739  goto done;
740  case VNET_API_ERROR_FEATURE_DISABLED:
741  error =
743  "twice-nat/out2in-only available only for endpoint-dependent mode.");
744  goto done;
745  default:
746  break;
747  }
748 
749 done:
750  unformat_free (line_input);
751 
752  return error;
753 }
754 
755 static clib_error_t *
757  unformat_input_t * input,
758  vlib_cli_command_t * cmd)
759 {
760  unformat_input_t _line_input, *line_input = &_line_input;
761  snat_main_t *sm = &snat_main;
762  clib_error_t *error = 0;
764  u32 port = 0, vrf_id = ~0;
765  int is_add = 1;
766  int addr_only = 1;
767  u32 sw_if_index = ~0;
768  vnet_main_t *vnm = vnet_get_main ();
769  int rv;
770  snat_protocol_t proto;
771 
772  if (sm->deterministic)
774 
775  addr.as_u32 = 0;
776 
777  /* Get a line of input. */
778  if (!unformat_user (input, unformat_line_input, line_input))
779  return 0;
780 
781  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
782  {
783  if (unformat (line_input, "%U", unformat_ip4_address, &addr))
784  ;
785  else if (unformat (line_input, "external %U",
786  unformat_vnet_sw_interface, vnm, &sw_if_index))
787  ;
788  else if (unformat (line_input, "vrf %u", &vrf_id))
789  ;
790  else if (unformat (line_input, "%U %u", unformat_snat_protocol, &proto,
791  &port))
792  addr_only = 0;
793  else if (unformat (line_input, "del"))
794  is_add = 0;
795  else
796  {
797  error = clib_error_return (0, "unknown input: '%U'",
798  format_unformat_error, line_input);
799  goto done;
800  }
801  }
802 
803  rv = snat_add_static_mapping (addr, addr, (u16) port, (u16) port,
804  vrf_id, addr_only, sw_if_index, proto, is_add,
805  0, 0, 0, 1);
806 
807  switch (rv)
808  {
809  case VNET_API_ERROR_INVALID_VALUE:
810  error = clib_error_return (0, "External port already in use.");
811  goto done;
812  case VNET_API_ERROR_NO_SUCH_ENTRY:
813  if (is_add)
814  error = clib_error_return (0, "External address must be allocated.");
815  else
816  error = clib_error_return (0, "Mapping not exist.");
817  goto done;
818  case VNET_API_ERROR_NO_SUCH_FIB:
819  error = clib_error_return (0, "No such VRF id.");
820  goto done;
821  case VNET_API_ERROR_VALUE_EXIST:
822  error = clib_error_return (0, "Mapping already exist.");
823  goto done;
824  default:
825  break;
826  }
827 
828 done:
829  unformat_free (line_input);
830 
831  return error;
832 }
833 
834 static clib_error_t *
836  unformat_input_t * input,
837  vlib_cli_command_t * cmd)
838 {
839  unformat_input_t _line_input, *line_input = &_line_input;
840  snat_main_t *sm = &snat_main;
841  clib_error_t *error = 0;
842  ip4_address_t l_addr, e_addr;
843  u32 l_port = 0, e_port = 0, vrf_id = 0, probability = 0, affinity = 0;
844  int is_add = 1;
845  int rv;
846  snat_protocol_t proto;
847  u8 proto_set = 0;
848  nat44_lb_addr_port_t *locals = 0, local;
850  u8 out2in_only = 0;
851 
852  if (sm->deterministic)
854 
855  /* Get a line of input. */
856  if (!unformat_user (input, unformat_line_input, line_input))
857  return 0;
858 
859  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
860  {
861  if (unformat (line_input, "local %U:%u probability %u",
862  unformat_ip4_address, &l_addr, &l_port, &probability))
863  {
864  clib_memset (&local, 0, sizeof (local));
865  local.addr = l_addr;
866  local.port = (u16) l_port;
867  local.probability = (u8) probability;
868  vec_add1 (locals, local);
869  }
870  else if (unformat (line_input, "local %U:%u vrf %u probability %u",
871  unformat_ip4_address, &l_addr, &l_port, &vrf_id,
872  &probability))
873  {
874  clib_memset (&local, 0, sizeof (local));
875  local.addr = l_addr;
876  local.port = (u16) l_port;
877  local.probability = (u8) probability;
878  local.vrf_id = vrf_id;
879  vec_add1 (locals, local);
880  }
881  else if (unformat (line_input, "external %U:%u", unformat_ip4_address,
882  &e_addr, &e_port))
883  ;
884  else if (unformat (line_input, "protocol %U", unformat_snat_protocol,
885  &proto))
886  proto_set = 1;
887  else if (unformat (line_input, "twice-nat"))
888  twice_nat = TWICE_NAT;
889  else if (unformat (line_input, "self-twice-nat"))
890  twice_nat = TWICE_NAT_SELF;
891  else if (unformat (line_input, "out2in-only"))
892  out2in_only = 1;
893  else if (unformat (line_input, "del"))
894  is_add = 0;
895  else if (unformat (line_input, "affinity %u", &affinity))
896  ;
897  else
898  {
899  error = clib_error_return (0, "unknown input: '%U'",
900  format_unformat_error, line_input);
901  goto done;
902  }
903  }
904 
905  if (vec_len (locals) < 2)
906  {
907  error = clib_error_return (0, "at least two local must be set");
908  goto done;
909  }
910 
911  if (!proto_set)
912  {
913  error = clib_error_return (0, "missing protocol");
914  goto done;
915  }
916 
917  rv = nat44_add_del_lb_static_mapping (e_addr, (u16) e_port, proto, locals,
918  is_add, twice_nat, out2in_only, 0,
919  affinity);
920 
921  switch (rv)
922  {
923  case VNET_API_ERROR_INVALID_VALUE:
924  error = clib_error_return (0, "External port already in use.");
925  goto done;
926  case VNET_API_ERROR_NO_SUCH_ENTRY:
927  if (is_add)
928  error = clib_error_return (0, "External address must be allocated.");
929  else
930  error = clib_error_return (0, "Mapping not exist.");
931  goto done;
932  case VNET_API_ERROR_VALUE_EXIST:
933  error = clib_error_return (0, "Mapping already exist.");
934  goto done;
935  case VNET_API_ERROR_FEATURE_DISABLED:
936  error =
937  clib_error_return (0, "Available only for endpoint-dependent mode.");
938  goto done;
939  default:
940  break;
941  }
942 
943 done:
944  unformat_free (line_input);
945  vec_free (locals);
946 
947  return error;
948 }
949 
950 static clib_error_t *
952  unformat_input_t * input, vlib_cli_command_t * cmd)
953 {
954  unformat_input_t _line_input, *line_input = &_line_input;
955  snat_main_t *sm = &snat_main;
956  clib_error_t *error = 0;
957  ip4_address_t l_addr, e_addr;
958  u32 l_port = 0, e_port = 0, vrf_id = 0, probability = 0;
959  int is_add = 1;
960  int rv;
961  snat_protocol_t proto;
962  u8 proto_set = 0;
963 
964  if (sm->deterministic)
966 
967  /* Get a line of input. */
968  if (!unformat_user (input, unformat_line_input, line_input))
969  return 0;
970 
971  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
972  {
973  if (unformat (line_input, "local %U:%u probability %u",
974  unformat_ip4_address, &l_addr, &l_port, &probability))
975  ;
976  else if (unformat (line_input, "local %U:%u vrf %u probability %u",
977  unformat_ip4_address, &l_addr, &l_port, &vrf_id,
978  &probability))
979  ;
980  else if (unformat (line_input, "external %U:%u", unformat_ip4_address,
981  &e_addr, &e_port))
982  ;
983  else if (unformat (line_input, "protocol %U", unformat_snat_protocol,
984  &proto))
985  proto_set = 1;
986  else if (unformat (line_input, "del"))
987  is_add = 0;
988  else
989  {
990  error = clib_error_return (0, "unknown input: '%U'",
991  format_unformat_error, line_input);
992  goto done;
993  }
994  }
995 
996  if (!l_port || !e_port)
997  {
998  error = clib_error_return (0, "local or external must be set");
999  goto done;
1000  }
1001 
1002  if (!proto_set)
1003  {
1004  error = clib_error_return (0, "missing protocol");
1005  goto done;
1006  }
1007 
1008  rv =
1009  nat44_lb_static_mapping_add_del_local (e_addr, (u16) e_port, l_addr,
1010  l_port, proto, vrf_id, probability,
1011  is_add);
1012 
1013  switch (rv)
1014  {
1015  case VNET_API_ERROR_INVALID_VALUE:
1016  error = clib_error_return (0, "External is not load-balancing static "
1017  "mapping.");
1018  goto done;
1019  case VNET_API_ERROR_NO_SUCH_ENTRY:
1020  error = clib_error_return (0, "Mapping or back-end not exist.");
1021  goto done;
1022  case VNET_API_ERROR_VALUE_EXIST:
1023  error = clib_error_return (0, "Back-end already exist.");
1024  goto done;
1025  case VNET_API_ERROR_FEATURE_DISABLED:
1026  error =
1027  clib_error_return (0, "Available only for endpoint-dependent mode.");
1028  goto done;
1029  case VNET_API_ERROR_UNSPECIFIED:
1030  error = clib_error_return (0, "At least two back-ends must remain");
1031  goto done;
1032  default:
1033  break;
1034  }
1035 
1036 done:
1037  unformat_free (line_input);
1038 
1039  return error;
1040 }
1041 
1042 static clib_error_t *
1044  unformat_input_t * input,
1045  vlib_cli_command_t * cmd)
1046 {
1047  snat_main_t *sm = &snat_main;
1050 
1051  if (sm->deterministic)
1053 
1054  vlib_cli_output (vm, "NAT44 static mappings:");
1055  /* *INDENT-OFF* */
1056  pool_foreach (m, sm->static_mappings,
1057  ({
1058  vlib_cli_output (vm, " %U", format_snat_static_mapping, m);
1059  }));
1060  vec_foreach (rp, sm->to_resolve)
1062  /* *INDENT-ON* */
1063 
1064  return 0;
1065 }
1066 
1067 static clib_error_t *
1069  unformat_input_t * input,
1070  vlib_cli_command_t * cmd)
1071 {
1072  snat_main_t *sm = &snat_main;
1073  unformat_input_t _line_input, *line_input = &_line_input;
1074  u32 sw_if_index;
1075  int rv;
1076  int is_del = 0;
1077  clib_error_t *error = 0;
1078  u8 twice_nat = 0;
1079 
1080  if (sm->deterministic)
1082 
1083  /* Get a line of input. */
1084  if (!unformat_user (input, unformat_line_input, line_input))
1085  return 0;
1086 
1087  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1088  {
1089  if (unformat (line_input, "%U", unformat_vnet_sw_interface,
1090  sm->vnet_main, &sw_if_index))
1091  ;
1092  else if (unformat (line_input, "twice-nat"))
1093  twice_nat = 1;
1094  else if (unformat (line_input, "del"))
1095  is_del = 1;
1096  else
1097  {
1098  error = clib_error_return (0, "unknown input '%U'",
1099  format_unformat_error, line_input);
1100  goto done;
1101  }
1102  }
1103 
1104  rv = snat_add_interface_address (sm, sw_if_index, is_del, twice_nat);
1105 
1106  switch (rv)
1107  {
1108  case 0:
1109  break;
1110 
1111  default:
1112  error = clib_error_return (0, "snat_add_interface_address returned %d",
1113  rv);
1114  goto done;
1115  }
1116 
1117 done:
1118  unformat_free (line_input);
1119 
1120  return error;
1121 }
1122 
1123 static clib_error_t *
1125  unformat_input_t * input,
1126  vlib_cli_command_t * cmd)
1127 {
1128  snat_main_t *sm = &snat_main;
1129  vnet_main_t *vnm = vnet_get_main ();
1130  u32 *sw_if_index;
1131 
1132  if (sm->deterministic)
1134 
1135  /* *INDENT-OFF* */
1136  vlib_cli_output (vm, "NAT44 pool address interfaces:");
1137  vec_foreach (sw_if_index, sm->auto_add_sw_if_indices)
1138  {
1140  *sw_if_index);
1141  }
1142  vlib_cli_output (vm, "NAT44 twice-nat pool address interfaces:");
1144  {
1146  *sw_if_index);
1147  }
1148  /* *INDENT-ON* */
1149 
1150  return 0;
1151 }
1152 
1153 static clib_error_t *
1155  vlib_cli_command_t * cmd)
1156 {
1157  int verbose = 0;
1158  snat_main_t *sm = &snat_main;
1160  snat_user_t *u;
1161  int i = 0;
1162 
1163  if (sm->deterministic)
1165 
1166  if (unformat (input, "detail"))
1167  verbose = 1;
1168 
1169  vlib_cli_output (vm, "NAT44 sessions:");
1170 
1171  /* *INDENT-OFF* */
1173  {
1174  tsm = vec_elt_at_index (sm->per_thread_data, i);
1175 
1176  vlib_cli_output (vm, "-------- thread %d %s: %d sessions --------\n",
1177  i, vlib_worker_threads[i].name,
1178  pool_elts (tsm->sessions));
1179  pool_foreach (u, tsm->users,
1180  ({
1181  vlib_cli_output (vm, " %U", format_snat_user, tsm, u, verbose);
1182  }));
1183  }
1184  /* *INDENT-ON* */
1185 
1186  return 0;
1187 }
1188 
1189 static clib_error_t *
1191  unformat_input_t * input,
1192  vlib_cli_command_t * cmd)
1193 {
1194  snat_main_t *sm = &snat_main;
1195  unformat_input_t _line_input, *line_input = &_line_input;
1196  int is_in = 0, is_ed = 0;
1197  clib_error_t *error = 0;
1198  ip4_address_t addr, eh_addr;
1199  u32 port = 0, eh_port = 0, vrf_id = sm->outside_vrf_id;
1200  snat_protocol_t proto;
1201  int rv;
1202 
1203  if (sm->deterministic)
1205 
1206  /* Get a line of input. */
1207  if (!unformat_user (input, unformat_line_input, line_input))
1208  return 0;
1209 
1210  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1211  {
1212  if (unformat
1213  (line_input, "%U:%u %U", unformat_ip4_address, &addr, &port,
1214  unformat_snat_protocol, &proto))
1215  ;
1216  else if (unformat (line_input, "in"))
1217  {
1218  is_in = 1;
1219  vrf_id = sm->inside_vrf_id;
1220  }
1221  else if (unformat (line_input, "out"))
1222  {
1223  is_in = 0;
1224  vrf_id = sm->outside_vrf_id;
1225  }
1226  else if (unformat (line_input, "vrf %u", &vrf_id))
1227  ;
1228  else
1229  if (unformat
1230  (line_input, "external-host %U:%u", unformat_ip4_address,
1231  &eh_addr, &eh_port))
1232  is_ed = 1;
1233  else
1234  {
1235  error = clib_error_return (0, "unknown input '%U'",
1236  format_unformat_error, line_input);
1237  goto done;
1238  }
1239  }
1240 
1241  if (is_ed)
1242  rv =
1243  nat44_del_ed_session (sm, &addr, port, &eh_addr, eh_port,
1244  snat_proto_to_ip_proto (proto), vrf_id, is_in);
1245  else
1246  rv = nat44_del_session (sm, &addr, port, proto, vrf_id, is_in);
1247 
1248  switch (rv)
1249  {
1250  case 0:
1251  break;
1252 
1253  default:
1254  error = clib_error_return (0, "nat44_del_session returned %d", rv);
1255  goto done;
1256  }
1257 
1258 done:
1259  unformat_free (line_input);
1260 
1261  return error;
1262 }
1263 
1264 static clib_error_t *
1266  unformat_input_t * input,
1267  vlib_cli_command_t * cmd)
1268 {
1269  snat_main_t *sm = &snat_main;
1270  unformat_input_t _line_input, *line_input = &_line_input;
1271  u8 forwarding_enable;
1272  u8 forwarding_enable_set = 0;
1273  clib_error_t *error = 0;
1274 
1275  if (sm->deterministic)
1277 
1278  /* Get a line of input. */
1279  if (!unformat_user (input, unformat_line_input, line_input))
1280  return clib_error_return (0, "'enable' or 'disable' expected");
1281 
1282  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1283  {
1284  if (!forwarding_enable_set && unformat (line_input, "enable"))
1285  {
1286  forwarding_enable = 1;
1287  forwarding_enable_set = 1;
1288  }
1289  else if (!forwarding_enable_set && unformat (line_input, "disable"))
1290  {
1291  forwarding_enable = 0;
1292  forwarding_enable_set = 1;
1293  }
1294  else
1295  {
1296  error = clib_error_return (0, "unknown input '%U'",
1297  format_unformat_error, line_input);
1298  goto done;
1299  }
1300  }
1301 
1302  if (!forwarding_enable_set)
1303  {
1304  error = clib_error_return (0, "'enable' or 'disable' expected");
1305  goto done;
1306  }
1307 
1308  sm->forwarding_enabled = forwarding_enable;
1309 
1310 done:
1311  unformat_free (line_input);
1312 
1313  return error;
1314 }
1315 
1316 static clib_error_t *
1318  unformat_input_t * input, vlib_cli_command_t * cmd)
1319 {
1320  snat_main_t *sm = &snat_main;
1321  unformat_input_t _line_input, *line_input = &_line_input;
1322  ip4_address_t in_addr, out_addr;
1323  u32 in_plen, out_plen;
1324  int is_add = 1, rv;
1325  clib_error_t *error = 0;
1326 
1327  if (!sm->deterministic)
1329 
1330  /* Get a line of input. */
1331  if (!unformat_user (input, unformat_line_input, line_input))
1332  return 0;
1333 
1334  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1335  {
1336  if (unformat
1337  (line_input, "in %U/%u", unformat_ip4_address, &in_addr, &in_plen))
1338  ;
1339  else
1340  if (unformat
1341  (line_input, "out %U/%u", unformat_ip4_address, &out_addr,
1342  &out_plen))
1343  ;
1344  else if (unformat (line_input, "del"))
1345  is_add = 0;
1346  else
1347  {
1348  error = clib_error_return (0, "unknown input '%U'",
1349  format_unformat_error, line_input);
1350  goto done;
1351  }
1352  }
1353 
1354  rv = snat_det_add_map (sm, &in_addr, (u8) in_plen, &out_addr, (u8) out_plen,
1355  is_add);
1356 
1357  if (rv)
1358  {
1359  error = clib_error_return (0, "snat_det_add_map return %d", rv);
1360  goto done;
1361  }
1362 
1363 done:
1364  unformat_free (line_input);
1365 
1366  return error;
1367 }
1368 
1369 static clib_error_t *
1371  unformat_input_t * input,
1372  vlib_cli_command_t * cmd)
1373 {
1374  snat_main_t *sm = &snat_main;
1375  snat_det_map_t *dm;
1376 
1377  if (!sm->deterministic)
1379 
1380  vlib_cli_output (vm, "NAT44 deterministic mappings:");
1381  /* *INDENT-OFF* */
1382  pool_foreach (dm, sm->det_maps,
1383  ({
1384  vlib_cli_output (vm, " in %U/%d out %U/%d\n",
1385  format_ip4_address, &dm->in_addr, dm->in_plen,
1386  format_ip4_address, &dm->out_addr, dm->out_plen);
1387  vlib_cli_output (vm, " outside address sharing ratio: %d\n",
1388  dm->sharing_ratio);
1389  vlib_cli_output (vm, " number of ports per inside host: %d\n",
1390  dm->ports_per_host);
1391  vlib_cli_output (vm, " sessions number: %d\n", dm->ses_num);
1392  }));
1393  /* *INDENT-ON* */
1394 
1395  return 0;
1396 }
1397 
1398 static clib_error_t *
1400  unformat_input_t * input,
1401  vlib_cli_command_t * cmd)
1402 {
1403  snat_main_t *sm = &snat_main;
1404  unformat_input_t _line_input, *line_input = &_line_input;
1405  ip4_address_t in_addr, out_addr;
1406  u16 lo_port;
1407  snat_det_map_t *dm;
1408  clib_error_t *error = 0;
1409 
1410  if (!sm->deterministic)
1412 
1413  /* Get a line of input. */
1414  if (!unformat_user (input, unformat_line_input, line_input))
1415  return 0;
1416 
1417  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1418  {
1419  if (unformat (line_input, "%U", unformat_ip4_address, &in_addr))
1420  ;
1421  else
1422  {
1423  error = clib_error_return (0, "unknown input '%U'",
1424  format_unformat_error, line_input);
1425  goto done;
1426  }
1427  }
1428 
1429  dm = snat_det_map_by_user (sm, &in_addr);
1430  if (!dm)
1431  vlib_cli_output (vm, "no match");
1432  else
1433  {
1434  snat_det_forward (dm, &in_addr, &out_addr, &lo_port);
1435  vlib_cli_output (vm, "%U:<%d-%d>", format_ip4_address, &out_addr,
1436  lo_port, lo_port + dm->ports_per_host - 1);
1437  }
1438 
1439 done:
1440  unformat_free (line_input);
1441 
1442  return error;
1443 }
1444 
1445 static clib_error_t *
1447  unformat_input_t * input,
1448  vlib_cli_command_t * cmd)
1449 {
1450  snat_main_t *sm = &snat_main;
1451  unformat_input_t _line_input, *line_input = &_line_input;
1452  ip4_address_t in_addr, out_addr;
1453  u32 out_port;
1454  snat_det_map_t *dm;
1455  clib_error_t *error = 0;
1456 
1457  if (!sm->deterministic)
1459 
1460  /* Get a line of input. */
1461  if (!unformat_user (input, unformat_line_input, line_input))
1462  return 0;
1463 
1464  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1465  {
1466  if (unformat
1467  (line_input, "%U:%d", unformat_ip4_address, &out_addr, &out_port))
1468  ;
1469  else
1470  {
1471  error = clib_error_return (0, "unknown input '%U'",
1472  format_unformat_error, line_input);
1473  goto done;
1474  }
1475  }
1476 
1477  if (out_port < 1024 || out_port > 65535)
1478  {
1479  error = clib_error_return (0, "wrong port, must be <1024-65535>");
1480  goto done;
1481  }
1482 
1483  dm = snat_det_map_by_out (sm, &out_addr);
1484  if (!dm)
1485  vlib_cli_output (vm, "no match");
1486  else
1487  {
1488  snat_det_reverse (dm, &out_addr, (u16) out_port, &in_addr);
1489  vlib_cli_output (vm, "%U", format_ip4_address, &in_addr);
1490  }
1491 
1492 done:
1493  unformat_free (line_input);
1494 
1495  return error;
1496 }
1497 
1498 static clib_error_t *
1500  unformat_input_t * input, vlib_cli_command_t * cmd)
1501 {
1502  snat_main_t *sm = &snat_main;
1503  unformat_input_t _line_input, *line_input = &_line_input;
1504  clib_error_t *error = 0;
1505 
1506  /* Get a line of input. */
1507  if (!unformat_user (input, unformat_line_input, line_input))
1508  return 0;
1509 
1510  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1511  {
1512  if (unformat (line_input, "udp %u", &sm->udp_timeout))
1513  {
1515  {
1516  error = clib_error_return (0, "Invalid UDP timeout value");
1517  goto done;
1518  }
1519  }
1520  else if (unformat (line_input, "tcp-established %u",
1522  {
1525  {
1526  error =
1527  clib_error_return (0,
1528  "Invalid TCP established timeouts value");
1529  goto done;
1530  }
1531  }
1532  else if (unformat (line_input, "tcp-transitory %u",
1533  &sm->tcp_transitory_timeout))
1534  {
1537  {
1538  error =
1539  clib_error_return (0,
1540  "Invalid TCP transitory timeouts value");
1541  goto done;
1542  }
1543  }
1544  else if (unformat (line_input, "icmp %u", &sm->icmp_timeout))
1545  {
1547  {
1548  error = clib_error_return (0, "Invalid ICMP timeout value");
1549  goto done;
1550  }
1551  }
1552  else if (unformat (line_input, "reset"))
1553  {
1560  nat64_set_tcp_timeouts (0, 0);
1561  }
1562  else
1563  {
1564  error = clib_error_return (0, "unknown input '%U'",
1565  format_unformat_error, line_input);
1566  goto done;
1567  }
1568  }
1569 
1570 done:
1571  unformat_free (line_input);
1572 
1573  return error;
1574 }
1575 
1576 static clib_error_t *
1578  unformat_input_t * input,
1579  vlib_cli_command_t * cmd)
1580 {
1581  snat_main_t *sm = &snat_main;
1582 
1583  vlib_cli_output (vm, "udp timeout: %dsec", sm->udp_timeout);
1584  vlib_cli_output (vm, "tcp-established timeout: %dsec",
1586  vlib_cli_output (vm, "tcp-transitory timeout: %dsec",
1588  vlib_cli_output (vm, "icmp timeout: %dsec", sm->icmp_timeout);
1589 
1590  return 0;
1591 }
1592 
1593 static clib_error_t *
1595  unformat_input_t * input,
1596  vlib_cli_command_t * cmd)
1597 {
1598  snat_main_t *sm = &snat_main;
1599  snat_det_map_t *dm;
1600  snat_det_session_t *ses;
1601  int i;
1602 
1603  if (!sm->deterministic)
1605 
1606  vlib_cli_output (vm, "NAT44 deterministic sessions:");
1607  /* *INDENT-OFF* */
1608  pool_foreach (dm, sm->det_maps,
1609  ({
1610  vec_foreach_index (i, dm->sessions)
1611  {
1612  ses = vec_elt_at_index (dm->sessions, i);
1613  if (ses->in_port)
1614  vlib_cli_output (vm, " %U", format_det_map_ses, dm, ses, &i);
1615  }
1616  }));
1617  /* *INDENT-ON* */
1618  return 0;
1619 }
1620 
1621 static clib_error_t *
1623  unformat_input_t * input,
1624  vlib_cli_command_t * cmd)
1625 {
1626  snat_main_t *sm = &snat_main;
1627  unformat_input_t _line_input, *line_input = &_line_input;
1628  ip4_address_t out_addr, ext_addr, in_addr;
1629  u32 out_port, ext_port;
1630  snat_det_map_t *dm;
1631  snat_det_session_t *ses;
1632  snat_det_out_key_t key;
1633  clib_error_t *error = 0;
1634 
1635  if (!sm->deterministic)
1637 
1638  /* Get a line of input. */
1639  if (!unformat_user (input, unformat_line_input, line_input))
1640  return 0;
1641 
1642  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1643  {
1644  if (unformat (line_input, "%U:%d %U:%d",
1645  unformat_ip4_address, &out_addr, &out_port,
1646  unformat_ip4_address, &ext_addr, &ext_port))
1647  ;
1648  else
1649  {
1650  error = clib_error_return (0, "unknown input '%U'",
1651  format_unformat_error, line_input);
1652  goto done;
1653  }
1654  }
1655 
1656  unformat_free (line_input);
1657 
1658  dm = snat_det_map_by_out (sm, &out_addr);
1659  if (!dm)
1660  vlib_cli_output (vm, "no match");
1661  else
1662  {
1663  snat_det_reverse (dm, &ext_addr, (u16) out_port, &in_addr);
1664  key.ext_host_addr = out_addr;
1665  key.ext_host_port = ntohs ((u16) ext_port);
1666  key.out_port = ntohs ((u16) out_port);
1667  ses = snat_det_get_ses_by_out (dm, &out_addr, key.as_u64);
1668  if (!ses)
1669  vlib_cli_output (vm, "no match");
1670  else
1671  snat_det_ses_close (dm, ses);
1672  }
1673 
1674 done:
1675  unformat_free (line_input);
1676 
1677  return error;
1678 }
1679 
1680 static clib_error_t *
1682  unformat_input_t * input,
1683  vlib_cli_command_t * cmd)
1684 {
1685  snat_main_t *sm = &snat_main;
1686  unformat_input_t _line_input, *line_input = &_line_input;
1687  ip4_address_t in_addr, ext_addr;
1688  u32 in_port, ext_port;
1689  snat_det_map_t *dm;
1690  snat_det_session_t *ses;
1691  snat_det_out_key_t key;
1692  clib_error_t *error = 0;
1693 
1694  if (!sm->deterministic)
1696 
1697  /* Get a line of input. */
1698  if (!unformat_user (input, unformat_line_input, line_input))
1699  return 0;
1700 
1701  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1702  {
1703  if (unformat (line_input, "%U:%d %U:%d",
1704  unformat_ip4_address, &in_addr, &in_port,
1705  unformat_ip4_address, &ext_addr, &ext_port))
1706  ;
1707  else
1708  {
1709  error = clib_error_return (0, "unknown input '%U'",
1710  format_unformat_error, line_input);
1711  goto done;
1712  }
1713  }
1714 
1715  unformat_free (line_input);
1716 
1717  dm = snat_det_map_by_user (sm, &in_addr);
1718  if (!dm)
1719  vlib_cli_output (vm, "no match");
1720  else
1721  {
1722  key.ext_host_addr = ext_addr;
1723  key.ext_host_port = ntohs ((u16) ext_port);
1724  ses =
1725  snat_det_find_ses_by_in (dm, &in_addr, ntohs ((u16) in_port), key);
1726  if (!ses)
1727  vlib_cli_output (vm, "no match");
1728  else
1729  snat_det_ses_close (dm, ses);
1730  }
1731 
1732 done:
1733  unformat_free (line_input);
1734 
1735  return error;
1736 }
1737 /* *INDENT-OFF* */
1738 
1739 /*?
1740  * @cliexpar
1741  * @cliexstart{set snat workers}
1742  * Set NAT workers if 2 or more workers available, use:
1743  * vpp# set snat workers 0-2,5
1744  * @cliexend
1745 ?*/
1746 VLIB_CLI_COMMAND (set_workers_command, static) = {
1747  .path = "set nat workers",
1748  .function = set_workers_command_fn,
1749  .short_help = "set nat workers <workers-list>",
1750 };
1751 
1752 /*?
1753  * @cliexpar
1754  * @cliexstart{show nat workers}
1755  * Show NAT workers.
1756  * vpp# show nat workers:
1757  * 2 workers
1758  * vpp_wk_0
1759  * vpp_wk_1
1760  * @cliexend
1761 ?*/
1762 VLIB_CLI_COMMAND (nat_show_workers_command, static) = {
1763  .path = "show nat workers",
1764  .short_help = "show nat workers",
1765  .function = nat_show_workers_commnad_fn,
1766 };
1767 
1768 /*?
1769  * @cliexpar
1770  * @cliexstart{set nat timeout}
1771  * Set values of timeouts for NAT sessions (in seconds), use:
1772  * vpp# set nat timeout udp 120 tcp-established 7500 tcp-transitory 250 icmp 90
1773  * To reset default values use:
1774  * vpp# set nat44 deterministic timeout reset
1775  * @cliexend
1776 ?*/
1777 VLIB_CLI_COMMAND (set_timeout_command, static) = {
1778  .path = "set nat timeout",
1779  .function = set_timeout_command_fn,
1780  .short_help =
1781  "set nat timeout [udp <sec> | tcp-established <sec> "
1782  "tcp-transitory <sec> | icmp <sec> | reset]",
1783 };
1784 
1785 /*?
1786  * @cliexpar
1787  * @cliexstart{show nat timeouts}
1788  * Show values of timeouts for NAT sessions.
1789  * vpp# show nat timeouts
1790  * udp timeout: 300sec
1791  * tcp-established timeout: 7440sec
1792  * tcp-transitory timeout: 240sec
1793  * icmp timeout: 60sec
1794  * @cliexend
1795 ?*/
1796 VLIB_CLI_COMMAND (nat_show_timeouts_command, static) = {
1797  .path = "show nat timeouts",
1798  .short_help = "show nat timeouts",
1799  .function = nat_show_timeouts_command_fn,
1800 };
1801 
1802 /*?
1803  * @cliexpar
1804  * @cliexstart{snat ipfix logging}
1805  * To enable NAT IPFIX logging use:
1806  * vpp# nat ipfix logging
1807  * To set IPFIX exporter use:
1808  * vpp# set ipfix exporter collector 10.10.10.3 src 10.10.10.1
1809  * @cliexend
1810 ?*/
1811 VLIB_CLI_COMMAND (snat_ipfix_logging_enable_disable_command, static) = {
1812  .path = "nat ipfix logging",
1814  .short_help = "nat ipfix logging [domain <domain-id>] [src-port <port>] [disable]",
1815 };
1816 
1817 /*?
1818  * @cliexpar
1819  * @cliexstart{nat addr-port-assignment-alg}
1820  * Set address and port assignment algorithm
1821  * For the MAP-E CE limit port choice based on PSID use:
1822  * vpp# nat addr-port-assignment-alg map-e psid 10 psid-offset 6 psid-len 6
1823  * For port range use:
1824  * vpp# nat addr-port-assignment-alg port-range <start-port> - <end-port>
1825  * To set standard (default) address and port assignment algorithm use:
1826  * vpp# nat addr-port-assignment-alg default
1827  * @cliexend
1828 ?*/
1829 VLIB_CLI_COMMAND (nat44_set_alloc_addr_and_port_alg_command, static) = {
1830  .path = "nat addr-port-assignment-alg",
1831  .short_help = "nat addr-port-assignment-alg <alg-name> [<alg-params>]",
1833 };
1834 
1835 /*?
1836  * @cliexpar
1837  * @cliexstart{show nat addr-port-assignment-alg}
1838  * Show address and port assignment algorithm
1839  * @cliexend
1840 ?*/
1841 VLIB_CLI_COMMAND (nat44_show_alloc_addr_and_port_alg_command, static) = {
1842  .path = "show nat addr-port-assignment-alg",
1843  .short_help = "show nat addr-port-assignment-alg",
1845 };
1846 
1847 /*?
1848  * @cliexpar
1849  * @cliexstart{nat mss-clamping}
1850  * Set TCP MSS rewriting configuration
1851  * To enable TCP MSS rewriting use:
1852  * vpp# nat mss-clamping 1452
1853  * To disbale TCP MSS rewriting use:
1854  * vpp# nat mss-clamping disable
1855 ?*/
1856 VLIB_CLI_COMMAND (nat_set_mss_clamping_command, static) = {
1857  .path = "nat mss-clamping",
1858  .short_help = "nat mss-clamping <mss-value>|disable",
1859  .function = nat_set_mss_clamping_command_fn,
1860 };
1861 
1862 /*?
1863  * @cliexpar
1864  * @cliexstart{nat mss-clamping}
1865  * Show TCP MSS rewriting configuration
1866 ?*/
1867 VLIB_CLI_COMMAND (nat_show_mss_clamping_command, static) = {
1868  .path = "show nat mss-clamping",
1869  .short_help = "show nat mss-clamping",
1871 };
1872 
1873 /*?
1874  * @cliexpar
1875  * @cliexstart{show nat44 hash tables}
1876  * Show NAT44 hash tables
1877  * @cliexend
1878 ?*/
1879 VLIB_CLI_COMMAND (nat44_show_hash, static) = {
1880  .path = "show nat44 hash tables",
1881  .short_help = "show nat44 hash tables [detail|verbose]",
1882  .function = nat44_show_hash_commnad_fn,
1883 };
1884 
1885 /*?
1886  * @cliexpar
1887  * @cliexstart{nat44 add address}
1888  * Add/delete NAT44 pool address.
1889  * To add NAT44 pool address use:
1890  * vpp# nat44 add address 172.16.1.3
1891  * vpp# nat44 add address 172.16.2.2 - 172.16.2.24
1892  * To add NAT44 pool address for specific tenant (identified by VRF id) use:
1893  * vpp# nat44 add address 172.16.1.3 tenant-vrf 10
1894  * @cliexend
1895 ?*/
1896 VLIB_CLI_COMMAND (add_address_command, static) = {
1897  .path = "nat44 add address",
1898  .short_help = "nat44 add address <ip4-range-start> [- <ip4-range-end>] "
1899  "[tenant-vrf <vrf-id>] [twice-nat] [del]",
1900  .function = add_address_command_fn,
1901 };
1902 
1903 /*?
1904  * @cliexpar
1905  * @cliexstart{show nat44 addresses}
1906  * Show NAT44 pool addresses.
1907  * vpp# show nat44 addresses
1908  * NAT44 pool addresses:
1909  * 172.16.2.2
1910  * tenant VRF independent
1911  * 10 busy udp ports
1912  * 0 busy tcp ports
1913  * 0 busy icmp ports
1914  * 172.16.1.3
1915  * tenant VRF: 10
1916  * 0 busy udp ports
1917  * 2 busy tcp ports
1918  * 0 busy icmp ports
1919  * NAT44 twice-nat pool addresses:
1920  * 10.20.30.72
1921  * tenant VRF independent
1922  * 0 busy udp ports
1923  * 0 busy tcp ports
1924  * 0 busy icmp ports
1925  * @cliexend
1926 ?*/
1927 VLIB_CLI_COMMAND (nat44_show_addresses_command, static) = {
1928  .path = "show nat44 addresses",
1929  .short_help = "show nat44 addresses",
1930  .function = nat44_show_addresses_command_fn,
1931 };
1932 
1933 /*?
1934  * @cliexpar
1935  * @cliexstart{set interface nat44}
1936  * Enable/disable NAT44 feature on the interface.
1937  * To enable NAT44 feature with local network interface use:
1938  * vpp# set interface nat44 in GigabitEthernet0/8/0
1939  * To enable NAT44 feature with external network interface use:
1940  * vpp# set interface nat44 out GigabitEthernet0/a/0
1941  * @cliexend
1942 ?*/
1943 VLIB_CLI_COMMAND (set_interface_snat_command, static) = {
1944  .path = "set interface nat44",
1945  .function = snat_feature_command_fn,
1946  .short_help = "set interface nat44 in <intfc> out <intfc> [output-feature] "
1947  "[del]",
1948 };
1949 
1950 /*?
1951  * @cliexpar
1952  * @cliexstart{show nat44 interfaces}
1953  * Show interfaces with NAT44 feature.
1954  * vpp# show nat44 interfaces
1955  * NAT44 interfaces:
1956  * GigabitEthernet0/8/0 in
1957  * GigabitEthernet0/a/0 out
1958  * @cliexend
1959 ?*/
1960 VLIB_CLI_COMMAND (nat44_show_interfaces_command, static) = {
1961  .path = "show nat44 interfaces",
1962  .short_help = "show nat44 interfaces",
1964 };
1965 
1966 /*?
1967  * @cliexpar
1968  * @cliexstart{nat44 add static mapping}
1969  * Static mapping allows hosts on the external network to initiate connection
1970  * to to the local network host.
1971  * To create static mapping between local host address 10.0.0.3 port 6303 and
1972  * external address 4.4.4.4 port 3606 for TCP protocol use:
1973  * vpp# nat44 add static mapping tcp local 10.0.0.3 6303 external 4.4.4.4 3606
1974  * If not runnig "static mapping only" NAT plugin mode use before:
1975  * vpp# nat44 add address 4.4.4.4
1976  * To create static mapping between local and external address use:
1977  * vpp# nat44 add static mapping local 10.0.0.3 external 4.4.4.4
1978  * @cliexend
1979 ?*/
1980 VLIB_CLI_COMMAND (add_static_mapping_command, static) = {
1981  .path = "nat44 add static mapping",
1982  .function = add_static_mapping_command_fn,
1983  .short_help =
1984  "nat44 add static mapping tcp|udp|icmp local <addr> [<port>] "
1985  "external <addr> [<port>] [vrf <table-id>] [twice-nat|self-twice-nat] "
1986  "[out2in-only] [del]",
1987 };
1988 
1989 /*?
1990  * @cliexpar
1991  * @cliexstart{nat44 add identity mapping}
1992  * Identity mapping translate an IP address to itself.
1993  * To create identity mapping for address 10.0.0.3 port 6303 for TCP protocol
1994  * use:
1995  * vpp# nat44 add identity mapping 10.0.0.3 tcp 6303
1996  * To create identity mapping for address 10.0.0.3 use:
1997  * vpp# nat44 add identity mapping 10.0.0.3
1998  * To create identity mapping for DHCP addressed interface use:
1999  * vpp# nat44 add identity mapping GigabitEthernet0/a/0 tcp 3606
2000  * @cliexend
2001 ?*/
2002 VLIB_CLI_COMMAND (add_identity_mapping_command, static) = {
2003  .path = "nat44 add identity mapping",
2004  .function = add_identity_mapping_command_fn,
2005  .short_help = "nat44 add identity mapping <interface>|<ip4-addr> "
2006  "[<protocol> <port>] [vrf <table-id>] [del]",
2007 };
2008 
2009 /*?
2010  * @cliexpar
2011  * @cliexstart{nat44 add load-balancing static mapping}
2012  * Service load balancing using NAT44
2013  * To add static mapping with load balancing for service with external IP
2014  * address 1.2.3.4 and TCP port 80 and mapped to 2 local servers
2015  * 10.100.10.10:8080 and 10.100.10.20:8080 with probability 80% resp. 20% use:
2016  * 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
2017  * @cliexend
2018 ?*/
2019 VLIB_CLI_COMMAND (add_lb_static_mapping_command, static) = {
2020  .path = "nat44 add load-balancing static mapping",
2022  .short_help =
2023  "nat44 add load-balancing static mapping protocol tcp|udp "
2024  "external <addr>:<port> local <addr>:<port> [vrf <table-id>] "
2025  "probability <n> [twice-nat|self-twice-nat] [out2in-only] "
2026  "[affinity <timeout-seconds>] [del]",
2027 };
2028 
2029 /*?
2030  * @cliexpar
2031  * @cliexstart{nat44 add load-balancing static mapping}
2032  * Modify service load balancing using NAT44
2033  * To add new back-end server 10.100.10.30:8080 for service load balancing
2034  * static mapping with external IP address 1.2.3.4 and TCP port 80 use:
2035  * vpp# nat44 add load-balancing back-end protocol tcp external 1.2.3.4:80 local 10.100.10.30:8080 probability 25
2036  * @cliexend
2037 ?*/
2038 VLIB_CLI_COMMAND (add_lb_backend_command, static) = {
2039  .path = "nat44 add load-balancing back-end",
2040  .function = add_lb_backend_command_fn,
2041  .short_help =
2042  "nat44 add load-balancing back-end protocol tcp|udp "
2043  "external <addr>:<port> local <addr>:<port> [vrf <table-id>] "
2044  "probability <n> [del]",
2045 };
2046 
2047 /*?
2048  * @cliexpar
2049  * @cliexstart{show nat44 static mappings}
2050  * Show NAT44 static mappings.
2051  * vpp# show nat44 static mappings
2052  * NAT44 static mappings:
2053  * local 10.0.0.3 external 4.4.4.4 vrf 0
2054  * tcp local 192.168.0.4:6303 external 4.4.4.3:3606 vrf 0
2055  * tcp vrf 0 external 1.2.3.4:80 out2in-only
2056  * local 10.100.10.10:8080 probability 80
2057  * local 10.100.10.20:8080 probability 20
2058  * tcp local 10.100.3.8:8080 external 169.10.10.1:80 vrf 0 twice-nat
2059  * tcp local 10.0.0.10:3603 external GigabitEthernet0/a/0:6306 vrf 10
2060  * @cliexend
2061 ?*/
2062 VLIB_CLI_COMMAND (nat44_show_static_mappings_command, static) = {
2063  .path = "show nat44 static mappings",
2064  .short_help = "show nat44 static mappings",
2066 };
2067 
2068 /*?
2069  * @cliexpar
2070  * @cliexstart{nat44 add interface address}
2071  * Use NAT44 pool address from specific interfce
2072  * To add NAT44 pool address from specific interface use:
2073  * vpp# nat44 add interface address GigabitEthernet0/8/0
2074  * @cliexend
2075 ?*/
2076 VLIB_CLI_COMMAND (snat_add_interface_address_command, static) = {
2077  .path = "nat44 add interface address",
2078  .short_help = "nat44 add interface address <interface> [twice-nat] [del]",
2080 };
2081 
2082 /*?
2083  * @cliexpar
2084  * @cliexstart{show nat44 interface address}
2085  * Show NAT44 pool address interfaces
2086  * vpp# show nat44 interface address
2087  * NAT44 pool address interfaces:
2088  * GigabitEthernet0/a/0
2089  * NAT44 twice-nat pool address interfaces:
2090  * GigabitEthernet0/8/0
2091  * @cliexend
2092 ?*/
2093 VLIB_CLI_COMMAND (nat44_show_interface_address_command, static) = {
2094  .path = "show nat44 interface address",
2095  .short_help = "show nat44 interface address",
2097 };
2098 
2099 /*?
2100  * @cliexpar
2101  * @cliexstart{show nat44 sessions}
2102  * Show NAT44 sessions.
2103  * @cliexend
2104 ?*/
2105 VLIB_CLI_COMMAND (nat44_show_sessions_command, static) = {
2106  .path = "show nat44 sessions",
2107  .short_help = "show nat44 sessions [detail]",
2108  .function = nat44_show_sessions_command_fn,
2109 };
2110 
2111 /*?
2112  * @cliexpar
2113  * @cliexstart{nat44 del session}
2114  * To administratively delete NAT44 session by inside address and port use:
2115  * vpp# nat44 del session in 10.0.0.3:6303 tcp
2116  * To administratively delete NAT44 session by outside address and port use:
2117  * vpp# nat44 del session out 1.0.0.3:6033 udp
2118  * @cliexend
2119 ?*/
2120 VLIB_CLI_COMMAND (nat44_del_session_command, static) = {
2121  .path = "nat44 del session",
2122  .short_help = "nat44 del session in|out <addr>:<port> tcp|udp|icmp [vrf <id>] [external-host <addr>:<port>]",
2123  .function = nat44_del_session_command_fn,
2124 };
2125 
2126 /*?
2127  * @cliexpar
2128  * @cliexstart{nat44 forwarding}
2129  * Enable or disable forwarding
2130  * Forward packets which don't match existing translation
2131  * or static mapping instead of dropping them.
2132  * To enable forwarding, use:
2133  * vpp# nat44 forwarding enable
2134  * To disable forwarding, use:
2135  * vpp# nat44 forwarding disable
2136  * @cliexend
2137 ?*/
2138 VLIB_CLI_COMMAND (snat_forwarding_set_command, static) = {
2139  .path = "nat44 forwarding",
2140  .short_help = "nat44 forwarding enable|disable",
2141  .function = snat_forwarding_set_command_fn,
2142 };
2143 
2144 /*?
2145  * @cliexpar
2146  * @cliexstart{nat44 deterministic add}
2147  * Create bijective mapping of inside address to outside address and port range
2148  * pairs, with the purpose of enabling deterministic NAT to reduce logging in
2149  * CGN deployments.
2150  * To create deterministic mapping between inside network 10.0.0.0/18 and
2151  * outside network 1.1.1.0/30 use:
2152  * # vpp# nat44 deterministic add in 10.0.0.0/18 out 1.1.1.0/30
2153  * @cliexend
2154 ?*/
2155 VLIB_CLI_COMMAND (snat_det_map_command, static) = {
2156  .path = "nat44 deterministic add",
2157  .short_help = "nat44 deterministic add in <addr>/<plen> out <addr>/<plen> [del]",
2158  .function = snat_det_map_command_fn,
2159 };
2160 
2161 /*?
2162  * @cliexpar
2163  * @cliexpstart{show nat44 deterministic mappings}
2164  * Show NAT44 deterministic mappings
2165  * vpp# show nat44 deterministic mappings
2166  * NAT44 deterministic mappings:
2167  * in 10.0.0.0/24 out 1.1.1.1/32
2168  * outside address sharing ratio: 256
2169  * number of ports per inside host: 252
2170  * sessions number: 0
2171  * @cliexend
2172 ?*/
2173 VLIB_CLI_COMMAND (nat44_det_show_mappings_command, static) = {
2174  .path = "show nat44 deterministic mappings",
2175  .short_help = "show nat44 deterministic mappings",
2177 };
2178 
2179 /*?
2180  * @cliexpar
2181  * @cliexstart{nat44 deterministic forward}
2182  * Return outside address and port range from inside address for deterministic
2183  * NAT.
2184  * To obtain outside address and port of inside host use:
2185  * vpp# nat44 deterministic forward 10.0.0.2
2186  * 1.1.1.0:<1054-1068>
2187  * @cliexend
2188 ?*/
2189 VLIB_CLI_COMMAND (snat_det_forward_command, static) = {
2190  .path = "nat44 deterministic forward",
2191  .short_help = "nat44 deterministic forward <addr>",
2192  .function = snat_det_forward_command_fn,
2193 };
2194 
2195 /*?
2196  * @cliexpar
2197  * @cliexstart{nat44 deterministic reverse}
2198  * Return inside address from outside address and port for deterministic NAT.
2199  * To obtain inside host address from outside address and port use:
2200  * #vpp nat44 deterministic reverse 1.1.1.1:1276
2201  * 10.0.16.16
2202  * @cliexend
2203 ?*/
2204 VLIB_CLI_COMMAND (snat_det_reverse_command, static) = {
2205  .path = "nat44 deterministic reverse",
2206  .short_help = "nat44 deterministic reverse <addr>:<port>",
2207  .function = snat_det_reverse_command_fn,
2208 };
2209 
2210 /*?
2211  * @cliexpar
2212  * @cliexstart{show nat44 deterministic sessions}
2213  * Show NAT44 deterministic sessions.
2214  * vpp# show nat44 deterministic sessions
2215  * NAT44 deterministic sessions:
2216  * in 10.0.0.3:3005 out 1.1.1.2:1146 external host 172.16.1.2:3006 state: udp-active expire: 306
2217  * in 10.0.0.3:3000 out 1.1.1.2:1141 external host 172.16.1.2:3001 state: udp-active expire: 306
2218  * in 10.0.0.4:3005 out 1.1.1.2:1177 external host 172.16.1.2:3006 state: udp-active expire: 306
2219  * @cliexend
2220 ?*/
2221 VLIB_CLI_COMMAND (nat44_det_show_sessions_command, static) = {
2222  .path = "show nat44 deterministic sessions",
2223  .short_help = "show nat44 deterministic sessions",
2225 };
2226 
2227 /*?
2228  * @cliexpar
2229  * @cliexstart{nat44 deterministic close session out}
2230  * Close session using outside ip address and port
2231  * and external ip address and port, use:
2232  * vpp# nat44 deterministic close session out 1.1.1.1:1276 2.2.2.2:2387
2233  * @cliexend
2234 ?*/
2235 VLIB_CLI_COMMAND (snat_det_close_sesion_out_command, static) = {
2236  .path = "nat44 deterministic close session out",
2237  .short_help = "nat44 deterministic close session out "
2238  "<out_addr>:<out_port> <ext_addr>:<ext_port>",
2239  .function = snat_det_close_session_out_fn,
2240 };
2241 
2242 /*?
2243  * @cliexpar
2244  * @cliexstart{nat44 deterministic close session in}
2245  * Close session using inside ip address and port
2246  * and external ip address and port, use:
2247  * vpp# nat44 deterministic close session in 3.3.3.3:3487 2.2.2.2:2387
2248  * @cliexend
2249 ?*/
2250 VLIB_CLI_COMMAND (snat_det_close_session_in_command, static) = {
2251  .path = "nat44 deterministic close session in",
2252  .short_help = "nat44 deterministic close session in "
2253  "<in_addr>:<in_port> <ext_addr>:<ext_port>",
2254  .function = snat_det_close_session_in_fn,
2255 };
2256 
2257 /* *INDENT-ON* */
2258 
2259 /*
2260  * fd.io coding-style-patch-verification: ON
2261  *
2262  * Local Variables:
2263  * eval: (c-set-style "gnu")
2264  * End:
2265  */
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:345
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:1446
#define nat_log_info(...)
Definition: nat.h:698
#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:1154
int snat_del_address(snat_main_t *sm, ip4_address_t addr, u8 delete_sm, u8 twice_nat)
Delete external address from NAT44 pool.
Definition: nat.c:1601
int nat64_set_udp_timeout(u32 timeout)
Set UDP session timeout.
Definition: nat64.c:785
u16 ext_host_port
Definition: nat.h:85
u16 out_port
Definition: nat.h:86
nat_affinity_main_t nat_affinity_main
Definition: nat_affinity.c:23
u32 icmp_timeout
Definition: nat.h:529
vnet_main_t * vnet_get_main(void)
Definition: misc.c:47
u16 start_port
Definition: nat.h:472
#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:525
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
clib_memset(h->entries, 0, sizeof(h->entries[0])*entries)
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
int nat44_del_ed_session(snat_main_t *sm, ip4_address_t *addr, u16 port, ip4_address_t *eh_addr, u16 eh_port, u8 proto, u32 vrf_id, int is_in)
Delete NAT44 endpoint-dependent session.
Definition: nat.c:3409
unformat_function_t unformat_vnet_sw_interface
snat_det_map_t * det_maps
Definition: nat.h:503
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:756
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
vhost_vring_addr_t addr
Definition: vhost_user.h:121
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:1622
format_function_t format_vnet_sw_if_index_name
unsigned char u8
Definition: types.h:56
u8 deterministic
Definition: nat.h:511
int snat_interface_add_del(u32 sw_if_index, u8 is_inside, int is_del)
Enable/disable NAT44 feature on the interface.
Definition: nat.c:1715
clib_bihash_8_8_t user_hash
Definition: nat.h:390
int nat44_add_del_lb_static_mapping(ip4_address_t e_addr, u16 e_port, snat_protocol_t proto, nat44_lb_addr_port_t *locals, u8 is_add, twice_nat_type_t twice_nat, u8 out2in_only, u8 *tag, u32 affinity)
Add/delete static mapping with load-balancing (multiple backends)
Definition: nat.c:1142
static clib_error_t * nat44_show_hash_commnad_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:164
u16 src_port
Definition: udp.api:41
clib_bihash_8_8_t in2out
Definition: nat.h:383
format_function_t format_ip4_address
Definition: format.h:75
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:490
unformat_function_t unformat_ip4_address
Definition: format.h:70
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:1317
ip4_address_t ext_host_addr
Definition: nat.h:84
u32 sw_if_index
Definition: vxlan_gbp.api:37
clib_bihash_16_8_t affinity_hash
Definition: nat_affinity.h:59
int snat_add_address(snat_main_t *sm, ip4_address_t *addr, u32 vrf_id, u8 twice_nat)
Add external address to NAT44 pool.
Definition: nat.c:516
int nat64_set_icmp_timeout(u32 timeout)
Set ICMP session timeout.
Definition: nat64.c:806
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:1681
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:1399
#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.
unsigned int u32
Definition: types.h:88
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:210
static clib_error_t * nat_set_mss_clamping_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:295
unformat_function_t unformat_line_input
Definition: format.h:282
u32 * auto_add_sw_if_indices_twice_nat
Definition: nat.h:483
vlib_worker_thread_t * vlib_worker_threads
Definition: threads.c:36
u16 mss_value_net
Definition: nat.h:533
nat_addr_and_port_alloc_alg_t addr_and_port_alloc_alg
Definition: nat.h:466
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:453
clib_bihash_16_8_t out2in_ed
Definition: nat.h:386
static snat_det_map_t * snat_det_map_by_out(snat_main_t *sm, ip4_address_t *out_addr)
Definition: nat_det.h:60
u16 mss_clamping
Definition: nat.h:532
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:1265
struct _unformat_input_t unformat_input_t
unsigned short u16
Definition: types.h:57
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:1594
u8 out2in_dpo
Definition: nat.h:512
#define SNAT_UDP_TIMEOUT
Definition: nat.h:34
snat_static_mapping_t * static_mappings
Definition: nat.h:455
u32 udp_timeout
Definition: nat.h:526
u8 static_mapping_only
Definition: nat.h:509
clib_bihash_8_8_t static_mapping_by_external
Definition: nat.h:452
u8 psid_offset
Definition: nat.h:468
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:496
void nat_set_alloc_addr_and_port_default(void)
Set address and port assignment algorithm to default/standard.
Definition: nat.c:3476
u8 name[64]
Definition: memclnt.api:152
u8 psid_length
Definition: nat.h:469
vnet_main_t * vnet_main
Definition: nat.h:547
u32 inside_vrf_id
Definition: nat.h:522
snat_interface_t * output_feature_interfaces
Definition: nat.h:459
snat_main_t snat_main
Definition: nat.c:38
snat_user_t * users
Definition: nat.h:393
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:835
#define UNFORMAT_END_OF_INPUT
Definition: format.h:144
static u8 snat_proto_to_ip_proto(snat_protocol_t snat_proto)
Definition: nat_inlines.h:41
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:118
clib_bihash_8_8_t out2in
Definition: nat.h:382
u32 ft_table_id
Table ID (hash key) for this FIB.
Definition: fib_table.h:89
vlib_main_t * vm
Definition: buffer.c:301
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:92
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:606
u32 outside_vrf_id
Definition: nat.h:520
void nat44_add_del_address_dpo(ip4_address_t addr, u8 is_add)
Add/delete external address to FIB DPO (out2in DPO mode)
Definition: nat.c:2631
u16 end_port
Definition: nat.h:473
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:341
deterministic NAT definitions
format_function_t format_snat_static_map_to_resolve
Definition: nat.h:590
int snat_interface_add_del_output_feature(u32 sw_if_index, u8 is_inside, int is_del)
Enable/disable NAT44 output feature on the interface (postrouting NAT)
Definition: nat.c:1964
u16 psid
Definition: nat.h:470
format_function_t format_nat_addr_and_port_alloc_alg
Definition: nat.h:596
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:1499
u32 tcp_transitory_timeout
Definition: nat.h:528
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, twice_nat_type_t twice_nat, u8 out2in_only, u8 *tag, u8 identity_nat)
Add/delete NAT44 static mapping.
Definition: nat.c:652
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:155
u32 * auto_add_sw_if_indices
Definition: nat.h:482
static clib_error_t * nat_show_mss_clamping_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:331
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:437
Definition: nat.h:310
unformat_function_t unformat_snat_protocol
Definition: nat.h:599
u32 first_worker_index
Definition: nat.h:438
void nat_set_alloc_addr_and_port_range(u16 start_port, u16 end_port)
Set address and port assignment algorithm for port range.
Definition: nat.c:3465
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:639
#define clib_bitmap_free(v)
Free a bitmap.
Definition: bitmap.h:92
size_t count
Definition: vapi.c:47
ip4_address_t addr
Definition: nat.h:243
int nat44_del_session(snat_main_t *sm, ip4_address_t *addr, u16 port, snat_protocol_t proto, u32 vrf_id, int is_in)
Delete NAT44 session.
Definition: nat.c:3366
snat_address_t * twice_nat_addresses
Definition: nat.h:479
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:1190
NAT64 global declarations.
int nat64_set_tcp_timeouts(u32 trans, u32 est)
Set TCP session timeouts.
Definition: nat64.c:827
void increment_v4_address(ip4_address_t *a)
Increment IPv4 address.
Definition: nat.c:600
static clib_error_t * nat_show_timeouts_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:1577
twice_nat_type_t
Definition: nat.h:305
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
#define UNSUPPORTED_IN_DET_MODE_STR
Definition: nat44_cli.c:28
u16 ports_per_host
Definition: nat.h:284
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:1068
u32 * workers
Definition: nat.h:439
u64 uword
Definition: types.h:112
snat_main_per_thread_data_t * per_thread_data
Definition: nat.h:446
static void unformat_free(unformat_input_t *i)
Definition: format.h:162
snat_protocol_t
Definition: nat.h:133
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:462
static clib_error_t * nat44_show_alloc_addr_and_port_alg_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:265
int snat_add_interface_address(snat_main_t *sm, u32 sw_if_index, int is_del, u8 twice_nat)
Add/delete NAT44 pool address from specific interfce.
Definition: nat.c:3298
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:1124
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:1043
static clib_error_t * add_lb_backend_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:951
#define SNAT_ICMP_TIMEOUT
Definition: nat.h:37
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:486
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
#define SUPPORTED_ONLY_IN_DET_MODE_STR
Definition: nat44_cli.c:30
u8 forwarding_enabled
Definition: nat.h:506
#define vec_foreach(var, vec)
Vector iterator.
int snat_set_workers(uword *bitmap)
Set NAT plugin workers.
Definition: nat.c:2087
clib_bihash_16_8_t in2out_ed
Definition: nat.h:387
u8 endpoint_dependent
Definition: nat.h:513
void nat_set_alloc_addr_and_port_mape(u16 psid, u16 psid_offset, u16 psid_length)
Set address and port assignment algorithm for MAP-E CE.
Definition: nat.c:3453
NAT plugin client-IP based session affinity for load-balancing.
#define SNAT_TCP_TRANSITORY_TIMEOUT
Definition: nat.h:35
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:725
snat_session_t * sessions
Definition: nat.h:396
clib_bihash_8_8_t static_mapping_by_local
Definition: nat.h:449
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:1370
int nat44_lb_static_mapping_add_del_local(ip4_address_t e_addr, u16 e_port, ip4_address_t l_addr, u16 l_port, snat_protocol_t proto, u32 vrf_id, u8 probability, u8 is_add)
Definition: nat.c:1418
u32 fib_index
Definition: nat.h:244
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:34
snat_interface_t * interfaces
Definition: nat.h:458
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:170
u32 tcp_established_timeout
Definition: nat.h:527
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:128