FD.io VPP  v20.05-21-gb1500e9ff
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/nat44/inlines.h>
26 #include <nat/nat_affinity.h>
27 #include <vnet/fib/fib_table.h>
28 #include <nat/nat_ha.h>
29 
30 
31 #define UNSUPPORTED_IN_DET_OR_ED_MODE_STR \
32  "This command is unsupported in deterministic or endpoint dependent mode"
33 #define UNSUPPORTED_IN_DET_OR_NON_ED_MODE_STR \
34  "This command is unsupported in deterministic or non endpoint dependent mode"
35 #define UNSUPPORTED_IN_DET_MODE_STR \
36  "This command is unsupported in deterministic mode"
37 #define SUPPORTED_ONLY_IN_ED_MODE_STR \
38  "This command is supported only in endpoint dependent mode"
39 #define SUPPORTED_ONLY_IN_DET_MODE_STR \
40  "This command is supported only in deterministic mode"
41 
42 static clib_error_t *
44  unformat_input_t * input, vlib_cli_command_t * cmd)
45 {
46  unformat_input_t _line_input, *line_input = &_line_input;
47  snat_main_t *sm = &snat_main;
48  uword *bitmap = 0;
49  int rv = 0;
50  clib_error_t *error = 0;
51 
52  if (sm->deterministic)
54 
55  /* Get a line of input. */
56  if (!unformat_user (input, unformat_line_input, line_input))
57  return 0;
58 
59  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
60  {
61  if (unformat (line_input, "%U", unformat_bitmap_list, &bitmap))
62  ;
63  else
64  {
65  error = clib_error_return (0, "unknown input '%U'",
66  format_unformat_error, line_input);
67  goto done;
68  }
69  }
70 
71  if (bitmap == 0)
72  {
73  error = clib_error_return (0, "List of workers must be specified.");
74  goto done;
75  }
76 
77  rv = snat_set_workers (bitmap);
78 
79  clib_bitmap_free (bitmap);
80 
81  switch (rv)
82  {
83  case VNET_API_ERROR_INVALID_WORKER:
84  error = clib_error_return (0, "Invalid worker(s).");
85  goto done;
86  case VNET_API_ERROR_FEATURE_DISABLED:
87  error = clib_error_return (0,
88  "Supported only if 2 or more workes available.");
89  goto done;
90  default:
91  break;
92  }
93 
94 done:
95  unformat_free (line_input);
96 
97  return error;
98 }
99 
100 static clib_error_t *
102  vlib_cli_command_t * cmd)
103 {
104  snat_main_t *sm = &snat_main;
105  u32 *worker;
106 
107  if (sm->deterministic)
109 
110  if (sm->num_workers > 1)
111  {
112  vlib_cli_output (vm, "%d workers", vec_len (sm->workers));
113  /* *INDENT-OFF* */
114  vec_foreach (worker, sm->workers)
115  {
117  vlib_worker_threads + *worker + sm->first_worker_index;
118  vlib_cli_output (vm, " %s", w->name);
119  }
120  /* *INDENT-ON* */
121  }
122 
123  return 0;
124 }
125 
126 static clib_error_t *
128  unformat_input_t * input,
129  vlib_cli_command_t * cmd)
130 {
131  unformat_input_t _line_input, *line_input = &_line_input;
132  snat_main_t *sm = &snat_main;
133  u8 log_level = SNAT_LOG_NONE;
134  clib_error_t *error = 0;
135 
136  /* Get a line of input. */
137  if (!unformat_user (input, unformat_line_input, line_input))
138  return 0;
139 
140  if (!unformat (line_input, "%d", &log_level))
141  {
142  error = clib_error_return (0, "unknown input '%U'",
143  format_unformat_error, line_input);
144  goto done;
145  }
146  if (log_level > SNAT_LOG_DEBUG)
147  {
148  error = clib_error_return (0, "unknown logging level '%d'", log_level);
149  goto done;
150  }
151  sm->log_level = log_level;
152 
153 done:
154  unformat_free (line_input);
155 
156  return error;
157 }
158 
159 static clib_error_t *
161  unformat_input_t * input,
162  vlib_cli_command_t * cmd)
163 {
164  unformat_input_t _line_input, *line_input = &_line_input;
165  u32 domain_id = 0;
166  u32 src_port = 0;
167  u8 enable = 1;
168  int rv = 0;
169  clib_error_t *error = 0;
170 
171  /* Get a line of input. */
172  if (!unformat_user (input, unformat_line_input, line_input))
173  {
174  rv = snat_ipfix_logging_enable_disable (enable, domain_id,
175  (u16) src_port);
176  if (rv)
177  return clib_error_return (0, "ipfix logging enable failed");
178  return 0;
179  }
180 
181  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
182  {
183  if (unformat (line_input, "domain %d", &domain_id))
184  ;
185  else if (unformat (line_input, "src-port %d", &src_port))
186  ;
187  else if (unformat (line_input, "disable"))
188  enable = 0;
189  else
190  {
191  error = clib_error_return (0, "unknown input '%U'",
192  format_unformat_error, line_input);
193  goto done;
194  }
195  }
196 
197  rv = snat_ipfix_logging_enable_disable (enable, domain_id, (u16) src_port);
198 
199  if (rv)
200  {
201  error = clib_error_return (0, "ipfix logging enable failed");
202  goto done;
203  }
204 
205 done:
206  unformat_free (line_input);
207 
208  return error;
209 }
210 
211 static clib_error_t *
213  vlib_cli_command_t * cmd)
214 {
215  snat_main_t *sm = &snat_main;
218  int i;
219  int verbose = 0;
220 
221  if (unformat (input, "detail"))
222  verbose = 1;
223  else if (unformat (input, "verbose"))
224  verbose = 2;
225 
226  vlib_cli_output (vm, "%U", format_bihash_8_8, &sm->static_mapping_by_local,
227  verbose);
228  vlib_cli_output (vm, "%U",
229  format_bihash_8_8, &sm->static_mapping_by_external,
230  verbose);
232  {
233  tsm = vec_elt_at_index (sm->per_thread_data, i);
234  vlib_cli_output (vm, "-------- thread %d %s --------\n",
235  i, vlib_worker_threads[i].name);
236  if (sm->endpoint_dependent)
237  {
238  vlib_cli_output (vm, "%U", format_bihash_16_8, &tsm->in2out_ed,
239  verbose);
240  vlib_cli_output (vm, "%U", format_bihash_16_8, &tsm->out2in_ed,
241  verbose);
242  }
243  else
244  {
245  vlib_cli_output (vm, "%U", format_bihash_8_8, &tsm->in2out, verbose);
246  vlib_cli_output (vm, "%U", format_bihash_8_8, &tsm->out2in, verbose);
247  }
248  vlib_cli_output (vm, "%U", format_bihash_8_8, &tsm->user_hash, verbose);
249  }
250 
251  if (sm->endpoint_dependent)
252  {
253  vlib_cli_output (vm, "%U", format_bihash_16_8, &nam->affinity_hash,
254  verbose);
255  }
256  return 0;
257 }
258 
259 static clib_error_t *
261  unformat_input_t * input,
262  vlib_cli_command_t * cmd)
263 {
264  unformat_input_t _line_input, *line_input = &_line_input;
265  snat_main_t *sm = &snat_main;
266  clib_error_t *error = 0;
267  u32 psid, psid_offset, psid_length, port_start, port_end;
268 
269  if (sm->deterministic)
271 
272  /* Get a line of input. */
273  if (!unformat_user (input, unformat_line_input, line_input))
274  return 0;
275 
276  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
277  {
278  if (unformat (line_input, "default"))
280  else
281  if (unformat
282  (line_input, "map-e psid %d psid-offset %d psid-len %d", &psid,
283  &psid_offset, &psid_length))
284  nat_set_alloc_addr_and_port_mape ((u16) psid, (u16) psid_offset,
285  (u16) psid_length);
286  else
287  if (unformat
288  (line_input, "port-range %d - %d", &port_start, &port_end))
289  {
290  if (port_end <= port_start)
291  {
292  error =
294  "The end-port must be greater than start-port");
295  goto done;
296  }
298  (u16) port_end);
299  }
300  else
301  {
302  error = clib_error_return (0, "unknown input '%U'",
303  format_unformat_error, line_input);
304  goto done;
305  }
306  }
307 
308 done:
309  unformat_free (line_input);
310 
311  return error;
312 };
313 
314 static clib_error_t *
316  unformat_input_t * input,
317  vlib_cli_command_t * cmd)
318 {
319  snat_main_t *sm = &snat_main;
320 
321  if (sm->deterministic)
323 
324  vlib_cli_output (vm, "NAT address and port: %U",
327  switch (sm->addr_and_port_alloc_alg)
328  {
329  case NAT_ADDR_AND_PORT_ALLOC_ALG_MAPE:
330  vlib_cli_output (vm, " psid %d psid-offset %d psid-len %d", sm->psid,
331  sm->psid_offset, sm->psid_length);
332  break;
333  case NAT_ADDR_AND_PORT_ALLOC_ALG_RANGE:
334  vlib_cli_output (vm, " start-port %d end-port %d", sm->start_port,
335  sm->end_port);
336  break;
337  default:
338  break;
339  }
340 
341  return 0;
342 }
343 
344 static clib_error_t *
346  vlib_cli_command_t * cmd)
347 {
348  unformat_input_t _line_input, *line_input = &_line_input;
349  snat_main_t *sm = &snat_main;
350  clib_error_t *error = 0;
351  u32 mss;
352 
353  /* Get a line of input. */
354  if (!unformat_user (input, unformat_line_input, line_input))
355  return 0;
356 
357  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
358  {
359  if (unformat (line_input, "disable"))
360  sm->mss_clamping = 0;
361  else if (unformat (line_input, "%d", &mss))
362  {
363  sm->mss_clamping = (u16) mss;
364  sm->mss_value_net = clib_host_to_net_u16 (sm->mss_clamping);
365  }
366  else
367  {
368  error = clib_error_return (0, "unknown input '%U'",
369  format_unformat_error, line_input);
370  goto done;
371  }
372  }
373 
374 done:
375  unformat_free (line_input);
376 
377  return error;
378 }
379 
380 static clib_error_t *
382  vlib_cli_command_t * cmd)
383 {
384  snat_main_t *sm = &snat_main;
385 
386  if (sm->mss_clamping)
387  vlib_cli_output (vm, "mss-clamping %d", sm->mss_clamping);
388  else
389  vlib_cli_output (vm, "mss-clamping disabled");
390 
391  return 0;
392 }
393 
394 static clib_error_t *
396  vlib_cli_command_t * cmd)
397 {
398  unformat_input_t _line_input, *line_input = &_line_input;
400  u32 port, session_refresh_interval = 10;
401  int rv;
402  clib_error_t *error = 0;
403 
404  /* Get a line of input. */
405  if (!unformat_user (input, unformat_line_input, line_input))
406  return 0;
407 
408  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
409  {
410  if (unformat (line_input, "%U:%u", unformat_ip4_address, &addr, &port))
411  ;
412  else
413  if (unformat
414  (line_input, "refresh-interval %u", &session_refresh_interval))
415  ;
416  else
417  {
418  error = clib_error_return (0, "unknown input '%U'",
419  format_unformat_error, line_input);
420  goto done;
421  }
422  }
423 
424  rv = nat_ha_set_failover (&addr, (u16) port, session_refresh_interval);
425  if (rv)
426  error = clib_error_return (0, "set HA failover failed");
427 
428 done:
429  unformat_free (line_input);
430 
431  return error;
432 }
433 
434 static clib_error_t *
436  vlib_cli_command_t * cmd)
437 {
438  unformat_input_t _line_input, *line_input = &_line_input;
440  u32 port, path_mtu = 512;
441  int rv;
442  clib_error_t *error = 0;
443 
444  /* Get a line of input. */
445  if (!unformat_user (input, unformat_line_input, line_input))
446  return 0;
447 
448  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
449  {
450  if (unformat (line_input, "%U:%u", unformat_ip4_address, &addr, &port))
451  ;
452  else if (unformat (line_input, "path-mtu %u", &path_mtu))
453  ;
454  else
455  {
456  error = clib_error_return (0, "unknown input '%U'",
457  format_unformat_error, line_input);
458  goto done;
459  }
460  }
461 
462  rv = nat_ha_set_listener (&addr, (u16) port, path_mtu);
463  if (rv)
464  error = clib_error_return (0, "set HA listener failed");
465 
466 done:
467  unformat_free (line_input);
468 
469  return error;
470 }
471 
472 static clib_error_t *
474  vlib_cli_command_t * cmd)
475 {
477  u16 port;
478  u32 path_mtu, session_refresh_interval, resync_ack_missed;
479  u8 in_resync;
480 
481  nat_ha_get_listener (&addr, &port, &path_mtu);
482  if (!port)
483  {
484  vlib_cli_output (vm, "NAT HA disabled\n");
485  return 0;
486  }
487 
488  vlib_cli_output (vm, "LISTENER:\n");
489  vlib_cli_output (vm, " %U:%u path-mtu %u\n",
490  format_ip4_address, &addr, port, path_mtu);
491 
492  nat_ha_get_failover (&addr, &port, &session_refresh_interval);
493  vlib_cli_output (vm, "FAILOVER:\n");
494  if (port)
495  vlib_cli_output (vm, " %U:%u refresh-interval %usec\n",
496  format_ip4_address, &addr, port,
497  session_refresh_interval);
498  else
499  vlib_cli_output (vm, " NA\n");
500 
501  nat_ha_get_resync_status (&in_resync, &resync_ack_missed);
502  vlib_cli_output (vm, "RESYNC:\n");
503  if (in_resync)
504  vlib_cli_output (vm, " in progress\n");
505  else
506  vlib_cli_output (vm, " completed (%d ACK missed)\n", resync_ack_missed);
507 
508  return 0;
509 }
510 
511 static clib_error_t *
513  vlib_cli_command_t * cmd)
514 {
515  nat_ha_flush (0);
516  return 0;
517 }
518 
519 static clib_error_t *
521  vlib_cli_command_t * cmd)
522 {
523  clib_error_t *error = 0;
524 
525  if (nat_ha_resync (0, 0, 0))
526  error = clib_error_return (0, "NAT HA resync already running");
527 
528  return error;
529 }
530 
531 static clib_error_t *
533  unformat_input_t * input, vlib_cli_command_t * cmd)
534 {
535  unformat_input_t _line_input, *line_input = &_line_input;
536  snat_main_t *sm = &snat_main;
537  ip4_address_t start_addr, end_addr, this_addr;
538  u32 start_host_order, end_host_order;
539  u32 vrf_id = ~0;
540  int i, count;
541  int is_add = 1;
542  int rv = 0;
543  clib_error_t *error = 0;
544  u8 twice_nat = 0;
545 
546  if (sm->deterministic)
548 
549  /* Get a line of input. */
550  if (!unformat_user (input, unformat_line_input, line_input))
551  return 0;
552 
553  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
554  {
555  if (unformat (line_input, "%U - %U",
556  unformat_ip4_address, &start_addr,
557  unformat_ip4_address, &end_addr))
558  ;
559  else if (unformat (line_input, "tenant-vrf %u", &vrf_id))
560  ;
561  else if (unformat (line_input, "%U", unformat_ip4_address, &start_addr))
562  end_addr = start_addr;
563  else if (unformat (line_input, "twice-nat"))
564  twice_nat = 1;
565  else if (unformat (line_input, "del"))
566  is_add = 0;
567  else
568  {
569  error = clib_error_return (0, "unknown input '%U'",
570  format_unformat_error, line_input);
571  goto done;
572  }
573  }
574 
575  if (sm->static_mapping_only)
576  {
577  error = clib_error_return (0, "static mapping only mode");
578  goto done;
579  }
580 
581  start_host_order = clib_host_to_net_u32 (start_addr.as_u32);
582  end_host_order = clib_host_to_net_u32 (end_addr.as_u32);
583 
584  if (end_host_order < start_host_order)
585  {
586  error = clib_error_return (0, "end address less than start address");
587  goto done;
588  }
589 
590  count = (end_host_order - start_host_order) + 1;
591 
592  if (count > 1024)
593  nat_log_info ("%U - %U, %d addresses...",
594  format_ip4_address, &start_addr,
595  format_ip4_address, &end_addr, count);
596 
597  this_addr = start_addr;
598 
599  for (i = 0; i < count; i++)
600  {
601  if (is_add)
602  rv = snat_add_address (sm, &this_addr, vrf_id, twice_nat);
603  else
604  rv = snat_del_address (sm, this_addr, 0, twice_nat);
605 
606  switch (rv)
607  {
608  case VNET_API_ERROR_VALUE_EXIST:
609  error = clib_error_return (0, "NAT address already in use.");
610  goto done;
611  case VNET_API_ERROR_NO_SUCH_ENTRY:
612  error = clib_error_return (0, "NAT address not exist.");
613  goto done;
614  case VNET_API_ERROR_UNSPECIFIED:
615  error =
616  clib_error_return (0, "NAT address used in static mapping.");
617  goto done;
618  case VNET_API_ERROR_FEATURE_DISABLED:
619  error =
621  "twice NAT available only for endpoint-dependent mode.");
622  goto done;
623  default:
624  break;
625  }
626 
627  if (sm->out2in_dpo)
628  nat44_add_del_address_dpo (this_addr, is_add);
629 
630  increment_v4_address (&this_addr);
631  }
632 
633 done:
634  unformat_free (line_input);
635 
636  return error;
637 }
638 
639 static clib_error_t *
641  vlib_cli_command_t * cmd)
642 {
644  snat_main_t *sm = &snat_main;
645  snat_session_t *s;
646 
647  if (sm->deterministic || !sm->endpoint_dependent)
649 
650  // print session configuration values
651  vlib_cli_output (vm, "max translations: %u", sm->max_translations);
652  vlib_cli_output (vm, "max translations per user: %u",
654 
655  u32 count = 0;
656 
657  u64 now = vlib_time_now (vm);
658  u64 sess_timeout_time;
659 
660  u32 udp_sessions = 0;
661  u32 tcp_sessions = 0;
662  u32 icmp_sessions = 0;
663 
664  u32 timed_out = 0;
665  u32 transitory = 0;
666  u32 transitory_wait_closed = 0;
667  u32 transitory_closed = 0;
668  u32 established = 0;
669 
670  if (sm->num_workers > 1)
671  {
672  /* *INDENT-OFF* */
673  vec_foreach (tsm, sm->per_thread_data)
674  {
675  pool_foreach (s, tsm->sessions,
676  ({
677  sess_timeout_time = s->last_heard +
678  (f64) nat44_session_get_timeout (sm, s);
679  if (now >= sess_timeout_time)
680  timed_out++;
681 
682  switch (s->in2out.protocol)
683  {
684  case NAT_PROTOCOL_ICMP:
685  icmp_sessions++;
686  break;
687  case NAT_PROTOCOL_TCP:
688  tcp_sessions++;
689  if (s->state)
690  {
691  if (s->tcp_closed_timestamp)
692  {
693  if (now >= s->tcp_closed_timestamp)
694  {
695  ++transitory_closed;
696  }
697  else
698  {
699  ++transitory_wait_closed;
700  }
701  }
702  transitory++;
703  }
704  else
705  established++;
706  break;
707  case NAT_PROTOCOL_UDP:
708  default:
709  udp_sessions++;
710  break;
711  }
712  }));
713  count += pool_elts (tsm->sessions);
714  }
715  /* *INDENT-ON* */
716  }
717  else
718  {
719  tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
720  /* *INDENT-OFF* */
721  pool_foreach (s, tsm->sessions,
722  ({
723  sess_timeout_time = s->last_heard +
724  (f64) nat44_session_get_timeout (sm, s);
725  if (now >= sess_timeout_time)
726  timed_out++;
727 
728  switch (s->in2out.protocol)
729  {
730  case NAT_PROTOCOL_ICMP:
731  icmp_sessions++;
732  break;
733  case NAT_PROTOCOL_TCP:
734  tcp_sessions++;
735  if (s->state)
736  {
737  if (s->tcp_closed_timestamp)
738  {
739  if (now >= s->tcp_closed_timestamp)
740  {
741  ++transitory_closed;
742  }
743  else
744  {
745  ++transitory_wait_closed;
746  }
747  }
748  transitory++;
749  }
750  else
751  established++;
752  break;
753  case NAT_PROTOCOL_UDP:
754  default:
755  udp_sessions++;
756  break;
757  }
758  }));
759  /* *INDENT-ON* */
760  count = pool_elts (tsm->sessions);
761  if (sm->endpoint_dependent)
762  {
763  dlist_elt_t *oldest_elt;
764  u32 oldest_index;
765 #define _(n, d) \
766  oldest_index = \
767  clib_dlist_remove_head (tsm->lru_pool, tsm->n##_lru_head_index); \
768  if (~0 != oldest_index) \
769  { \
770  oldest_elt = pool_elt_at_index (tsm->lru_pool, oldest_index); \
771  s = pool_elt_at_index (tsm->sessions, oldest_elt->value); \
772  sess_timeout_time = \
773  s->last_heard + (f64)nat44_session_get_timeout (sm, s); \
774  vlib_cli_output (vm, d " LRU min session timeout %llu (now %llu)", \
775  sess_timeout_time, now); \
776  clib_dlist_addhead (tsm->lru_pool, tsm->n##_lru_head_index, \
777  oldest_index); \
778  }
779  _(tcp_estab, "established tcp");
780  _(tcp_trans, "transitory tcp");
781  _(udp, "udp");
782  _(unk_proto, "unknown protocol");
783  _(icmp, "icmp");
784 #undef _
785  }
786  }
787 
788  vlib_cli_output (vm, "total timed out sessions: %u", timed_out);
789  vlib_cli_output (vm, "total sessions: %u", count);
790  vlib_cli_output (vm, "total tcp sessions: %u", tcp_sessions);
791  vlib_cli_output (vm, "total tcp established sessions: %u", established);
792  vlib_cli_output (vm, "total tcp transitory sessions: %u", transitory);
793  vlib_cli_output (vm, "total tcp transitory (WAIT-CLOSED) sessions: %u",
794  transitory_wait_closed);
795  vlib_cli_output (vm, "total tcp transitory (CLOSED) sessions: %u",
796  transitory_closed);
797  vlib_cli_output (vm, "total udp sessions: %u", udp_sessions);
798  vlib_cli_output (vm, "total icmp sessions: %u", icmp_sessions);
799  return 0;
800 }
801 
802 static clib_error_t *
804  vlib_cli_command_t * cmd)
805 {
806  snat_main_t *sm = &snat_main;
807  snat_address_t *ap;
808 
809  if (sm->deterministic)
811 
812  vlib_cli_output (vm, "NAT44 pool addresses:");
813  /* *INDENT-OFF* */
814  vec_foreach (ap, sm->addresses)
815  {
816  vlib_cli_output (vm, "%U", format_ip4_address, &ap->addr);
817  if (ap->fib_index != ~0)
818  vlib_cli_output (vm, " tenant VRF: %u",
820  else
821  vlib_cli_output (vm, " tenant VRF independent");
822  #define _(N, i, n, s) \
823  vlib_cli_output (vm, " %d busy %s ports", ap->busy_##n##_ports, s);
825  #undef _
826  }
827  vlib_cli_output (vm, "NAT44 twice-nat pool addresses:");
829  {
830  vlib_cli_output (vm, "%U", format_ip4_address, &ap->addr);
831  if (ap->fib_index != ~0)
832  vlib_cli_output (vm, " tenant VRF: %u",
834  else
835  vlib_cli_output (vm, " tenant VRF independent");
836  #define _(N, i, n, s) \
837  vlib_cli_output (vm, " %d busy %s ports", ap->busy_##n##_ports, s);
839  #undef _
840  }
841  /* *INDENT-ON* */
842  return 0;
843 }
844 
845 static clib_error_t *
847  unformat_input_t * input, vlib_cli_command_t * cmd)
848 {
849  unformat_input_t _line_input, *line_input = &_line_input;
850  vnet_main_t *vnm = vnet_get_main ();
851  clib_error_t *error = 0;
853  u32 *inside_sw_if_indices = 0;
854  u32 *outside_sw_if_indices = 0;
855  u8 is_output_feature = 0;
856  int is_del = 0;
857  int i;
858 
859  sw_if_index = ~0;
860 
861  /* Get a line of input. */
862  if (!unformat_user (input, unformat_line_input, line_input))
863  return 0;
864 
865  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
866  {
867  if (unformat (line_input, "in %U", unformat_vnet_sw_interface,
868  vnm, &sw_if_index))
869  vec_add1 (inside_sw_if_indices, sw_if_index);
870  else if (unformat (line_input, "out %U", unformat_vnet_sw_interface,
871  vnm, &sw_if_index))
872  vec_add1 (outside_sw_if_indices, sw_if_index);
873  else if (unformat (line_input, "output-feature"))
874  is_output_feature = 1;
875  else if (unformat (line_input, "del"))
876  is_del = 1;
877  else
878  {
879  error = clib_error_return (0, "unknown input '%U'",
880  format_unformat_error, line_input);
881  goto done;
882  }
883  }
884 
885  if (vec_len (inside_sw_if_indices))
886  {
887  for (i = 0; i < vec_len (inside_sw_if_indices); i++)
888  {
889  sw_if_index = inside_sw_if_indices[i];
890  if (is_output_feature)
891  {
893  (sw_if_index, 1, is_del))
894  {
895  error = clib_error_return (0, "%s %U failed",
896  is_del ? "del" : "add",
898  vnm, sw_if_index);
899  goto done;
900  }
901  }
902  else
903  {
904  if (snat_interface_add_del (sw_if_index, 1, is_del))
905  {
906  error = clib_error_return (0, "%s %U failed",
907  is_del ? "del" : "add",
909  vnm, sw_if_index);
910  goto done;
911  }
912  }
913  }
914  }
915 
916  if (vec_len (outside_sw_if_indices))
917  {
918  for (i = 0; i < vec_len (outside_sw_if_indices); i++)
919  {
920  sw_if_index = outside_sw_if_indices[i];
921  if (is_output_feature)
922  {
924  (sw_if_index, 0, is_del))
925  {
926  error = clib_error_return (0, "%s %U failed",
927  is_del ? "del" : "add",
929  vnm, sw_if_index);
930  goto done;
931  }
932  }
933  else
934  {
935  if (snat_interface_add_del (sw_if_index, 0, is_del))
936  {
937  error = clib_error_return (0, "%s %U failed",
938  is_del ? "del" : "add",
940  vnm, sw_if_index);
941  goto done;
942  }
943  }
944  }
945  }
946 
947 done:
948  unformat_free (line_input);
949  vec_free (inside_sw_if_indices);
950  vec_free (outside_sw_if_indices);
951 
952  return error;
953 }
954 
955 static clib_error_t *
957  vlib_cli_command_t * cmd)
958 {
959  snat_main_t *sm = &snat_main;
961  vnet_main_t *vnm = vnet_get_main ();
962 
963  vlib_cli_output (vm, "NAT44 interfaces:");
964  /* *INDENT-OFF* */
965  pool_foreach (i, sm->interfaces,
966  ({
967  vlib_cli_output (vm, " %U %s", format_vnet_sw_if_index_name, vnm,
968  i->sw_if_index,
969  (nat_interface_is_inside(i) &&
970  nat_interface_is_outside(i)) ? "in out" :
971  (nat_interface_is_inside(i) ? "in" : "out"));
972  }));
973 
975  ({
976  vlib_cli_output (vm, " %U output-feature %s",
977  format_vnet_sw_if_index_name, vnm,
978  i->sw_if_index,
979  (nat_interface_is_inside(i) &&
980  nat_interface_is_outside(i)) ? "in out" :
981  (nat_interface_is_inside(i) ? "in" : "out"));
982  }));
983  /* *INDENT-ON* */
984 
985  return 0;
986 }
987 
988 static clib_error_t *
990  unformat_input_t * input,
991  vlib_cli_command_t * cmd)
992 {
993  unformat_input_t _line_input, *line_input = &_line_input;
994  snat_main_t *sm = &snat_main;
995  clib_error_t *error = 0;
996  ip4_address_t l_addr, e_addr;
997  u32 l_port = 0, e_port = 0, vrf_id = ~0;
998  int is_add = 1;
999  int addr_only = 1;
1000  u32 sw_if_index = ~0;
1001  vnet_main_t *vnm = vnet_get_main ();
1002  int rv;
1003  nat_protocol_t proto = NAT_PROTOCOL_OTHER;
1004  u8 proto_set = 0;
1006  u8 out2in_only = 0;
1007 
1008  if (sm->deterministic)
1010 
1011  /* Get a line of input. */
1012  if (!unformat_user (input, unformat_line_input, line_input))
1013  return 0;
1014 
1015  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1016  {
1017  if (unformat (line_input, "local %U %u", unformat_ip4_address, &l_addr,
1018  &l_port))
1019  addr_only = 0;
1020  else
1021  if (unformat (line_input, "local %U", unformat_ip4_address, &l_addr))
1022  ;
1023  else if (unformat (line_input, "external %U %u", unformat_ip4_address,
1024  &e_addr, &e_port))
1025  addr_only = 0;
1026  else if (unformat (line_input, "external %U", unformat_ip4_address,
1027  &e_addr))
1028  ;
1029  else if (unformat (line_input, "external %U %u",
1030  unformat_vnet_sw_interface, vnm, &sw_if_index,
1031  &e_port))
1032  addr_only = 0;
1033 
1034  else if (unformat (line_input, "external %U",
1035  unformat_vnet_sw_interface, vnm, &sw_if_index))
1036  ;
1037  else if (unformat (line_input, "vrf %u", &vrf_id))
1038  ;
1039  else if (unformat (line_input, "%U", unformat_nat_protocol, &proto))
1040  proto_set = 1;
1041  else if (unformat (line_input, "twice-nat"))
1042  twice_nat = TWICE_NAT;
1043  else if (unformat (line_input, "self-twice-nat"))
1044  twice_nat = TWICE_NAT_SELF;
1045  else if (unformat (line_input, "out2in-only"))
1046  out2in_only = 1;
1047  else if (unformat (line_input, "del"))
1048  is_add = 0;
1049  else
1050  {
1051  error = clib_error_return (0, "unknown input: '%U'",
1052  format_unformat_error, line_input);
1053  goto done;
1054  }
1055  }
1056 
1057  if (twice_nat && addr_only)
1058  {
1059  error = clib_error_return (0, "twice NAT only for 1:1 NAPT");
1060  goto done;
1061  }
1062 
1063  if (!addr_only && !proto_set)
1064  {
1065  error = clib_error_return (0, "missing protocol");
1066  goto done;
1067  }
1068 
1069  rv = snat_add_static_mapping (l_addr, e_addr, (u16) l_port, (u16) e_port,
1070  vrf_id, addr_only, sw_if_index, proto, is_add,
1071  twice_nat, out2in_only, 0, 0);
1072 
1073  switch (rv)
1074  {
1075  case VNET_API_ERROR_INVALID_VALUE:
1076  error = clib_error_return (0, "External port already in use.");
1077  goto done;
1078  case VNET_API_ERROR_NO_SUCH_ENTRY:
1079  if (is_add)
1080  error = clib_error_return (0, "External address must be allocated.");
1081  else
1082  error = clib_error_return (0, "Mapping not exist.");
1083  goto done;
1084  case VNET_API_ERROR_NO_SUCH_FIB:
1085  error = clib_error_return (0, "No such VRF id.");
1086  goto done;
1087  case VNET_API_ERROR_VALUE_EXIST:
1088  error = clib_error_return (0, "Mapping already exist.");
1089  goto done;
1090  case VNET_API_ERROR_FEATURE_DISABLED:
1091  error =
1092  clib_error_return (0,
1093  "twice-nat/out2in-only available only for endpoint-dependent mode.");
1094  goto done;
1095  default:
1096  break;
1097  }
1098 
1099 done:
1100  unformat_free (line_input);
1101 
1102  return error;
1103 }
1104 
1105 static clib_error_t *
1107  unformat_input_t * input,
1108  vlib_cli_command_t * cmd)
1109 {
1110  unformat_input_t _line_input, *line_input = &_line_input;
1111  snat_main_t *sm = &snat_main;
1112  clib_error_t *error = 0;
1114  u32 port = 0, vrf_id = ~0;
1115  int is_add = 1;
1116  int addr_only = 1;
1117  u32 sw_if_index = ~0;
1118  vnet_main_t *vnm = vnet_get_main ();
1119  int rv;
1121 
1122  if (sm->deterministic)
1124 
1125  addr.as_u32 = 0;
1126 
1127  /* Get a line of input. */
1128  if (!unformat_user (input, unformat_line_input, line_input))
1129  return 0;
1130 
1131  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1132  {
1133  if (unformat (line_input, "%U", unformat_ip4_address, &addr))
1134  ;
1135  else if (unformat (line_input, "external %U",
1136  unformat_vnet_sw_interface, vnm, &sw_if_index))
1137  ;
1138  else if (unformat (line_input, "vrf %u", &vrf_id))
1139  ;
1140  else if (unformat (line_input, "%U %u", unformat_nat_protocol, &proto,
1141  &port))
1142  addr_only = 0;
1143  else if (unformat (line_input, "del"))
1144  is_add = 0;
1145  else
1146  {
1147  error = clib_error_return (0, "unknown input: '%U'",
1148  format_unformat_error, line_input);
1149  goto done;
1150  }
1151  }
1152 
1153  rv = snat_add_static_mapping (addr, addr, (u16) port, (u16) port,
1154  vrf_id, addr_only, sw_if_index, proto, is_add,
1155  0, 0, 0, 1);
1156 
1157  switch (rv)
1158  {
1159  case VNET_API_ERROR_INVALID_VALUE:
1160  error = clib_error_return (0, "External port already in use.");
1161  goto done;
1162  case VNET_API_ERROR_NO_SUCH_ENTRY:
1163  if (is_add)
1164  error = clib_error_return (0, "External address must be allocated.");
1165  else
1166  error = clib_error_return (0, "Mapping not exist.");
1167  goto done;
1168  case VNET_API_ERROR_NO_SUCH_FIB:
1169  error = clib_error_return (0, "No such VRF id.");
1170  goto done;
1171  case VNET_API_ERROR_VALUE_EXIST:
1172  error = clib_error_return (0, "Mapping already exist.");
1173  goto done;
1174  default:
1175  break;
1176  }
1177 
1178 done:
1179  unformat_free (line_input);
1180 
1181  return error;
1182 }
1183 
1184 static clib_error_t *
1186  unformat_input_t * input,
1187  vlib_cli_command_t * cmd)
1188 {
1189  unformat_input_t _line_input, *line_input = &_line_input;
1190  snat_main_t *sm = &snat_main;
1191  clib_error_t *error = 0;
1192  ip4_address_t l_addr, e_addr;
1193  u32 l_port = 0, e_port = 0, vrf_id = 0, probability = 0, affinity = 0;
1194  int is_add = 1;
1195  int rv;
1197  u8 proto_set = 0;
1198  nat44_lb_addr_port_t *locals = 0, local;
1200  u8 out2in_only = 0;
1201 
1202  if (sm->deterministic)
1204 
1205  /* Get a line of input. */
1206  if (!unformat_user (input, unformat_line_input, line_input))
1207  return 0;
1208 
1209  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1210  {
1211  if (unformat (line_input, "local %U:%u probability %u",
1212  unformat_ip4_address, &l_addr, &l_port, &probability))
1213  {
1214  clib_memset (&local, 0, sizeof (local));
1215  local.addr = l_addr;
1216  local.port = (u16) l_port;
1217  local.probability = (u8) probability;
1218  vec_add1 (locals, local);
1219  }
1220  else if (unformat (line_input, "local %U:%u vrf %u probability %u",
1221  unformat_ip4_address, &l_addr, &l_port, &vrf_id,
1222  &probability))
1223  {
1224  clib_memset (&local, 0, sizeof (local));
1225  local.addr = l_addr;
1226  local.port = (u16) l_port;
1227  local.probability = (u8) probability;
1228  local.vrf_id = vrf_id;
1229  vec_add1 (locals, local);
1230  }
1231  else if (unformat (line_input, "external %U:%u", unformat_ip4_address,
1232  &e_addr, &e_port))
1233  ;
1234  else if (unformat (line_input, "protocol %U", unformat_nat_protocol,
1235  &proto))
1236  proto_set = 1;
1237  else if (unformat (line_input, "twice-nat"))
1238  twice_nat = TWICE_NAT;
1239  else if (unformat (line_input, "self-twice-nat"))
1240  twice_nat = TWICE_NAT_SELF;
1241  else if (unformat (line_input, "out2in-only"))
1242  out2in_only = 1;
1243  else if (unformat (line_input, "del"))
1244  is_add = 0;
1245  else if (unformat (line_input, "affinity %u", &affinity))
1246  ;
1247  else
1248  {
1249  error = clib_error_return (0, "unknown input: '%U'",
1250  format_unformat_error, line_input);
1251  goto done;
1252  }
1253  }
1254 
1255  if (vec_len (locals) < 2)
1256  {
1257  error = clib_error_return (0, "at least two local must be set");
1258  goto done;
1259  }
1260 
1261  if (!proto_set)
1262  {
1263  error = clib_error_return (0, "missing protocol");
1264  goto done;
1265  }
1266 
1267  rv = nat44_add_del_lb_static_mapping (e_addr, (u16) e_port, proto, locals,
1268  is_add, twice_nat, out2in_only, 0,
1269  affinity);
1270 
1271  switch (rv)
1272  {
1273  case VNET_API_ERROR_INVALID_VALUE:
1274  error = clib_error_return (0, "External port already in use.");
1275  goto done;
1276  case VNET_API_ERROR_NO_SUCH_ENTRY:
1277  if (is_add)
1278  error = clib_error_return (0, "External address must be allocated.");
1279  else
1280  error = clib_error_return (0, "Mapping not exist.");
1281  goto done;
1282  case VNET_API_ERROR_VALUE_EXIST:
1283  error = clib_error_return (0, "Mapping already exist.");
1284  goto done;
1285  case VNET_API_ERROR_FEATURE_DISABLED:
1286  error =
1287  clib_error_return (0, "Available only for endpoint-dependent mode.");
1288  goto done;
1289  default:
1290  break;
1291  }
1292 
1293 done:
1294  unformat_free (line_input);
1295  vec_free (locals);
1296 
1297  return error;
1298 }
1299 
1300 static clib_error_t *
1302  unformat_input_t * input, vlib_cli_command_t * cmd)
1303 {
1304  unformat_input_t _line_input, *line_input = &_line_input;
1305  snat_main_t *sm = &snat_main;
1306  clib_error_t *error = 0;
1307  ip4_address_t l_addr, e_addr;
1308  u32 l_port = 0, e_port = 0, vrf_id = 0, probability = 0;
1309  int is_add = 1;
1310  int rv;
1312  u8 proto_set = 0;
1313 
1314  if (sm->deterministic)
1316 
1317  /* Get a line of input. */
1318  if (!unformat_user (input, unformat_line_input, line_input))
1319  return 0;
1320 
1321  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1322  {
1323  if (unformat (line_input, "local %U:%u probability %u",
1324  unformat_ip4_address, &l_addr, &l_port, &probability))
1325  ;
1326  else if (unformat (line_input, "local %U:%u vrf %u probability %u",
1327  unformat_ip4_address, &l_addr, &l_port, &vrf_id,
1328  &probability))
1329  ;
1330  else if (unformat (line_input, "external %U:%u", unformat_ip4_address,
1331  &e_addr, &e_port))
1332  ;
1333  else if (unformat (line_input, "protocol %U", unformat_nat_protocol,
1334  &proto))
1335  proto_set = 1;
1336  else if (unformat (line_input, "del"))
1337  is_add = 0;
1338  else
1339  {
1340  error = clib_error_return (0, "unknown input: '%U'",
1341  format_unformat_error, line_input);
1342  goto done;
1343  }
1344  }
1345 
1346  if (!l_port || !e_port)
1347  {
1348  error = clib_error_return (0, "local or external must be set");
1349  goto done;
1350  }
1351 
1352  if (!proto_set)
1353  {
1354  error = clib_error_return (0, "missing protocol");
1355  goto done;
1356  }
1357 
1358  rv =
1359  nat44_lb_static_mapping_add_del_local (e_addr, (u16) e_port, l_addr,
1360  l_port, proto, vrf_id, probability,
1361  is_add);
1362 
1363  switch (rv)
1364  {
1365  case VNET_API_ERROR_INVALID_VALUE:
1366  error = clib_error_return (0, "External is not load-balancing static "
1367  "mapping.");
1368  goto done;
1369  case VNET_API_ERROR_NO_SUCH_ENTRY:
1370  error = clib_error_return (0, "Mapping or back-end not exist.");
1371  goto done;
1372  case VNET_API_ERROR_VALUE_EXIST:
1373  error = clib_error_return (0, "Back-end already exist.");
1374  goto done;
1375  case VNET_API_ERROR_FEATURE_DISABLED:
1376  error =
1377  clib_error_return (0, "Available only for endpoint-dependent mode.");
1378  goto done;
1379  case VNET_API_ERROR_UNSPECIFIED:
1380  error = clib_error_return (0, "At least two back-ends must remain");
1381  goto done;
1382  default:
1383  break;
1384  }
1385 
1386 done:
1387  unformat_free (line_input);
1388 
1389  return error;
1390 }
1391 
1392 static clib_error_t *
1394  unformat_input_t * input,
1395  vlib_cli_command_t * cmd)
1396 {
1397  snat_main_t *sm = &snat_main;
1400 
1401  if (sm->deterministic)
1403 
1404  vlib_cli_output (vm, "NAT44 static mappings:");
1405  /* *INDENT-OFF* */
1406  pool_foreach (m, sm->static_mappings,
1407  ({
1408  vlib_cli_output (vm, " %U", format_snat_static_mapping, m);
1409  }));
1410  vec_foreach (rp, sm->to_resolve)
1412  /* *INDENT-ON* */
1413 
1414  return 0;
1415 }
1416 
1417 static clib_error_t *
1419  unformat_input_t * input,
1420  vlib_cli_command_t * cmd)
1421 {
1422  snat_main_t *sm = &snat_main;
1423  unformat_input_t _line_input, *line_input = &_line_input;
1424  u32 sw_if_index;
1425  int rv;
1426  int is_del = 0;
1427  clib_error_t *error = 0;
1428  u8 twice_nat = 0;
1429 
1430  if (sm->deterministic)
1432 
1433  /* Get a line of input. */
1434  if (!unformat_user (input, unformat_line_input, line_input))
1435  return 0;
1436 
1437  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1438  {
1439  if (unformat (line_input, "%U", unformat_vnet_sw_interface,
1440  sm->vnet_main, &sw_if_index))
1441  ;
1442  else if (unformat (line_input, "twice-nat"))
1443  twice_nat = 1;
1444  else if (unformat (line_input, "del"))
1445  is_del = 1;
1446  else
1447  {
1448  error = clib_error_return (0, "unknown input '%U'",
1449  format_unformat_error, line_input);
1450  goto done;
1451  }
1452  }
1453 
1454  rv = snat_add_interface_address (sm, sw_if_index, is_del, twice_nat);
1455 
1456  switch (rv)
1457  {
1458  case 0:
1459  break;
1460 
1461  default:
1462  error = clib_error_return (0, "snat_add_interface_address returned %d",
1463  rv);
1464  goto done;
1465  }
1466 
1467 done:
1468  unformat_free (line_input);
1469 
1470  return error;
1471 }
1472 
1473 static clib_error_t *
1475  unformat_input_t * input,
1476  vlib_cli_command_t * cmd)
1477 {
1478  snat_main_t *sm = &snat_main;
1479  vnet_main_t *vnm = vnet_get_main ();
1480  u32 *sw_if_index;
1481 
1482  if (sm->deterministic)
1484 
1485  /* *INDENT-OFF* */
1486  vlib_cli_output (vm, "NAT44 pool address interfaces:");
1487  vec_foreach (sw_if_index, sm->auto_add_sw_if_indices)
1488  {
1490  *sw_if_index);
1491  }
1492  vlib_cli_output (vm, "NAT44 twice-nat pool address interfaces:");
1494  {
1496  *sw_if_index);
1497  }
1498  /* *INDENT-ON* */
1499 
1500  return 0;
1501 }
1502 
1503 static clib_error_t *
1505  vlib_cli_command_t * cmd)
1506 {
1507  unformat_input_t _line_input, *line_input = &_line_input;
1508  clib_error_t *error = 0;
1509 
1511  snat_main_t *sm = &snat_main;
1512 
1513  int detail = 0;
1514  int i = 0;
1515 
1516  if (sm->deterministic)
1518 
1519  if (!unformat_user (input, unformat_line_input, line_input))
1520  goto print;
1521 
1522  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1523  {
1524  if (unformat (line_input, "detail"))
1525  detail = 1;
1526  else
1527  {
1528  error = clib_error_return (0, "unknown input '%U'",
1529  format_unformat_error, line_input);
1530  break;
1531  }
1532  }
1533  unformat_free (line_input);
1534 
1535 print:
1536  if (!sm->endpoint_dependent)
1537  vlib_cli_output (vm, "NAT44 sessions:");
1538  else
1539  vlib_cli_output (vm, "NAT44 ED sessions:");
1540 
1541  /* *INDENT-OFF* */
1543  {
1544  tsm = vec_elt_at_index (sm->per_thread_data, i);
1545 
1546  vlib_cli_output (vm, "-------- thread %d %s: %d sessions --------\n",
1547  i, vlib_worker_threads[i].name,
1548  pool_elts (tsm->sessions));
1549 
1550  if (!sm->endpoint_dependent)
1551  {
1552  snat_user_t *u;
1553  pool_foreach (u, tsm->users,
1554  ({
1555  vlib_cli_output (vm, " %U", format_snat_user, tsm, u, detail);
1556  }));
1557  }
1558  else
1559  {
1560  snat_session_t *s;
1561  pool_foreach (s, tsm->sessions,
1562  ({
1563  vlib_cli_output (vm, " %U\n", format_snat_session, tsm, s);
1564  }));
1565  }
1566  }
1567  /* *INDENT-ON* */
1568  return error;
1569 }
1570 
1571 static clib_error_t *
1573  unformat_input_t * input,
1574  vlib_cli_command_t * cmd)
1575 {
1576  snat_main_t *sm = &snat_main;
1577  unformat_input_t _line_input, *line_input = &_line_input;
1578  clib_error_t *error = 0;
1579 
1580  u32 session_limit = 0, vrf_id = 0;
1581 
1582  if (sm->deterministic)
1584 
1585  /* Get a line of input. */
1586  if (!unformat_user (input, unformat_line_input, line_input))
1587  return 0;
1588 
1589  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1590  {
1591  if (unformat (line_input, "%u", &session_limit))
1592  ;
1593  else if (unformat (line_input, "vrf %u", &vrf_id))
1594  ;
1595  else
1596  {
1597  error = clib_error_return (0, "unknown input '%U'",
1598  format_unformat_error, line_input);
1599  goto done;
1600  }
1601  }
1602 
1603  if (!session_limit)
1604  error = clib_error_return (0, "missing value of session limit");
1605  else if (nat44_set_session_limit (session_limit, vrf_id))
1606  error = clib_error_return (0, "nat44_set_session_limit failed");
1607 
1608 done:
1609  unformat_free (line_input);
1610 
1611  return error;
1612 }
1613 
1614 static clib_error_t *
1616  unformat_input_t * input, vlib_cli_command_t * cmd)
1617 {
1618  snat_main_t *sm = &snat_main;
1619  unformat_input_t _line_input, *line_input = &_line_input;
1620  clib_error_t *error = 0;
1622  u32 fib_index = 0;
1623  int rv;
1624 
1625  if (sm->deterministic || sm->endpoint_dependent)
1627 
1628  /* Get a line of input. */
1629  if (!unformat_user (input, unformat_line_input, line_input))
1630  return 0;
1631 
1632  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1633  {
1634  if (unformat (line_input, "%U", unformat_ip4_address, &addr))
1635  ;
1636  else if (unformat (line_input, "fib %u", &fib_index))
1637  ;
1638  else
1639  {
1640  error = clib_error_return (0, "unknown input '%U'",
1641  format_unformat_error, line_input);
1642  goto done;
1643  }
1644  }
1645 
1646  rv = nat44_user_del (&addr, fib_index);
1647 
1648  if (!rv)
1649  {
1650  error = clib_error_return (0, "nat44_user_del returned %d", rv);
1651  }
1652 
1653 done:
1654  unformat_free (line_input);
1655 
1656  return error;
1657 }
1658 
1659 static clib_error_t *
1661  unformat_input_t * input,
1662  vlib_cli_command_t * cmd)
1663 {
1664  snat_main_t *sm = &snat_main;
1665  clib_error_t *error = 0;
1666 
1667  if (sm->deterministic)
1669 
1671  return error;
1672 }
1673 
1674 static clib_error_t *
1676  unformat_input_t * input,
1677  vlib_cli_command_t * cmd)
1678 {
1679  snat_main_t *sm = &snat_main;
1680  unformat_input_t _line_input, *line_input = &_line_input;
1681  int is_in = 0, is_ed = 0;
1682  clib_error_t *error = 0;
1683  ip4_address_t addr, eh_addr;
1684  u32 port = 0, eh_port = 0, vrf_id = sm->outside_vrf_id;
1686  int rv;
1687 
1688  if (sm->deterministic)
1690 
1691  /* Get a line of input. */
1692  if (!unformat_user (input, unformat_line_input, line_input))
1693  return 0;
1694 
1695  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1696  {
1697  if (unformat
1698  (line_input, "%U:%u %U", unformat_ip4_address, &addr, &port,
1699  unformat_nat_protocol, &proto))
1700  ;
1701  else if (unformat (line_input, "in"))
1702  {
1703  is_in = 1;
1704  vrf_id = sm->inside_vrf_id;
1705  }
1706  else if (unformat (line_input, "out"))
1707  {
1708  is_in = 0;
1709  vrf_id = sm->outside_vrf_id;
1710  }
1711  else if (unformat (line_input, "vrf %u", &vrf_id))
1712  ;
1713  else
1714  if (unformat
1715  (line_input, "external-host %U:%u", unformat_ip4_address,
1716  &eh_addr, &eh_port))
1717  is_ed = 1;
1718  else
1719  {
1720  error = clib_error_return (0, "unknown input '%U'",
1721  format_unformat_error, line_input);
1722  goto done;
1723  }
1724  }
1725 
1726  if (is_ed)
1727  rv =
1728  nat44_del_ed_session (sm, &addr, port, &eh_addr, eh_port,
1729  nat_proto_to_ip_proto (proto), vrf_id, is_in);
1730  else
1731  rv = nat44_del_session (sm, &addr, port, proto, vrf_id, is_in);
1732 
1733  switch (rv)
1734  {
1735  case 0:
1736  break;
1737 
1738  default:
1739  error = clib_error_return (0, "nat44_del_session returned %d", rv);
1740  goto done;
1741  }
1742 
1743 done:
1744  unformat_free (line_input);
1745 
1746  return error;
1747 }
1748 
1749 static clib_error_t *
1751  unformat_input_t * input,
1752  vlib_cli_command_t * cmd)
1753 {
1754  snat_main_t *sm = &snat_main;
1755  unformat_input_t _line_input, *line_input = &_line_input;
1756  u8 forwarding_enable;
1757  u8 forwarding_enable_set = 0;
1758  clib_error_t *error = 0;
1759 
1760  if (sm->deterministic)
1762 
1763  /* Get a line of input. */
1764  if (!unformat_user (input, unformat_line_input, line_input))
1765  return clib_error_return (0, "'enable' or 'disable' expected");
1766 
1767  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1768  {
1769  if (!forwarding_enable_set && unformat (line_input, "enable"))
1770  {
1771  forwarding_enable = 1;
1772  forwarding_enable_set = 1;
1773  }
1774  else if (!forwarding_enable_set && unformat (line_input, "disable"))
1775  {
1776  forwarding_enable = 0;
1777  forwarding_enable_set = 1;
1778  }
1779  else
1780  {
1781  error = clib_error_return (0, "unknown input '%U'",
1782  format_unformat_error, line_input);
1783  goto done;
1784  }
1785  }
1786 
1787  if (!forwarding_enable_set)
1788  {
1789  error = clib_error_return (0, "'enable' or 'disable' expected");
1790  goto done;
1791  }
1792 
1793  sm->forwarding_enabled = forwarding_enable;
1794 
1795 done:
1796  unformat_free (line_input);
1797 
1798  return error;
1799 }
1800 
1801 static clib_error_t *
1803  unformat_input_t * input, vlib_cli_command_t * cmd)
1804 {
1805  snat_main_t *sm = &snat_main;
1806  unformat_input_t _line_input, *line_input = &_line_input;
1807  ip4_address_t in_addr, out_addr;
1808  u32 in_plen, out_plen;
1809  int is_add = 1, rv;
1810  clib_error_t *error = 0;
1811 
1812  if (!sm->deterministic)
1814 
1815  /* Get a line of input. */
1816  if (!unformat_user (input, unformat_line_input, line_input))
1817  return 0;
1818 
1819  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1820  {
1821  if (unformat
1822  (line_input, "in %U/%u", unformat_ip4_address, &in_addr, &in_plen))
1823  ;
1824  else
1825  if (unformat
1826  (line_input, "out %U/%u", unformat_ip4_address, &out_addr,
1827  &out_plen))
1828  ;
1829  else if (unformat (line_input, "del"))
1830  is_add = 0;
1831  else
1832  {
1833  error = clib_error_return (0, "unknown input '%U'",
1834  format_unformat_error, line_input);
1835  goto done;
1836  }
1837  }
1838 
1839  rv = snat_det_add_map (sm, &in_addr, (u8) in_plen, &out_addr, (u8) out_plen,
1840  is_add);
1841 
1842  if (rv)
1843  {
1844  error = clib_error_return (0, "snat_det_add_map return %d", rv);
1845  goto done;
1846  }
1847 
1848 done:
1849  unformat_free (line_input);
1850 
1851  return error;
1852 }
1853 
1854 static clib_error_t *
1856  unformat_input_t * input,
1857  vlib_cli_command_t * cmd)
1858 {
1859  snat_main_t *sm = &snat_main;
1860  snat_det_map_t *dm;
1861 
1862  if (!sm->deterministic)
1864 
1865  vlib_cli_output (vm, "NAT44 deterministic mappings:");
1866  /* *INDENT-OFF* */
1867  pool_foreach (dm, sm->det_maps,
1868  ({
1869  vlib_cli_output (vm, " in %U/%d out %U/%d\n",
1870  format_ip4_address, &dm->in_addr, dm->in_plen,
1871  format_ip4_address, &dm->out_addr, dm->out_plen);
1872  vlib_cli_output (vm, " outside address sharing ratio: %d\n",
1873  dm->sharing_ratio);
1874  vlib_cli_output (vm, " number of ports per inside host: %d\n",
1875  dm->ports_per_host);
1876  vlib_cli_output (vm, " sessions number: %d\n", dm->ses_num);
1877  }));
1878  /* *INDENT-ON* */
1879 
1880  return 0;
1881 }
1882 
1883 static clib_error_t *
1885  unformat_input_t * input,
1886  vlib_cli_command_t * cmd)
1887 {
1888  snat_main_t *sm = &snat_main;
1889  unformat_input_t _line_input, *line_input = &_line_input;
1890  ip4_address_t in_addr, out_addr;
1891  u16 lo_port;
1892  snat_det_map_t *dm;
1893  clib_error_t *error = 0;
1894 
1895  if (!sm->deterministic)
1897 
1898  /* Get a line of input. */
1899  if (!unformat_user (input, unformat_line_input, line_input))
1900  return 0;
1901 
1902  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1903  {
1904  if (unformat (line_input, "%U", unformat_ip4_address, &in_addr))
1905  ;
1906  else
1907  {
1908  error = clib_error_return (0, "unknown input '%U'",
1909  format_unformat_error, line_input);
1910  goto done;
1911  }
1912  }
1913 
1914  dm = snat_det_map_by_user (sm, &in_addr);
1915  if (!dm)
1916  vlib_cli_output (vm, "no match");
1917  else
1918  {
1919  snat_det_forward (dm, &in_addr, &out_addr, &lo_port);
1920  vlib_cli_output (vm, "%U:<%d-%d>", format_ip4_address, &out_addr,
1921  lo_port, lo_port + dm->ports_per_host - 1);
1922  }
1923 
1924 done:
1925  unformat_free (line_input);
1926 
1927  return error;
1928 }
1929 
1930 static clib_error_t *
1932  unformat_input_t * input,
1933  vlib_cli_command_t * cmd)
1934 {
1935  snat_main_t *sm = &snat_main;
1936  unformat_input_t _line_input, *line_input = &_line_input;
1937  ip4_address_t in_addr, out_addr;
1938  u32 out_port;
1939  snat_det_map_t *dm;
1940  clib_error_t *error = 0;
1941 
1942  if (!sm->deterministic)
1944 
1945  /* Get a line of input. */
1946  if (!unformat_user (input, unformat_line_input, line_input))
1947  return 0;
1948 
1949  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1950  {
1951  if (unformat
1952  (line_input, "%U:%d", unformat_ip4_address, &out_addr, &out_port))
1953  ;
1954  else
1955  {
1956  error = clib_error_return (0, "unknown input '%U'",
1957  format_unformat_error, line_input);
1958  goto done;
1959  }
1960  }
1961 
1962  if (out_port < 1024 || out_port > 65535)
1963  {
1964  error = clib_error_return (0, "wrong port, must be <1024-65535>");
1965  goto done;
1966  }
1967 
1968  dm = snat_det_map_by_out (sm, &out_addr);
1969  if (!dm)
1970  vlib_cli_output (vm, "no match");
1971  else
1972  {
1973  snat_det_reverse (dm, &out_addr, (u16) out_port, &in_addr);
1974  vlib_cli_output (vm, "%U", format_ip4_address, &in_addr);
1975  }
1976 
1977 done:
1978  unformat_free (line_input);
1979 
1980  return error;
1981 }
1982 
1983 static clib_error_t *
1985  unformat_input_t * input, vlib_cli_command_t * cmd)
1986 {
1987  snat_main_t *sm = &snat_main;
1988  unformat_input_t _line_input, *line_input = &_line_input;
1989  clib_error_t *error = 0;
1990 
1991  /* Get a line of input. */
1992  if (!unformat_user (input, unformat_line_input, line_input))
1993  return 0;
1994 
1995  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1996  {
1997  if (unformat (line_input, "udp %u", &sm->udp_timeout))
1998  {
2000  {
2001  error = clib_error_return (0, "Invalid UDP timeout value");
2002  goto done;
2003  }
2004  }
2005  else if (unformat (line_input, "tcp-established %u",
2007  {
2010  {
2011  error =
2012  clib_error_return (0,
2013  "Invalid TCP established timeouts value");
2014  goto done;
2015  }
2016  }
2017  else if (unformat (line_input, "tcp-transitory %u",
2018  &sm->tcp_transitory_timeout))
2019  {
2022  {
2023  error =
2024  clib_error_return (0,
2025  "Invalid TCP transitory timeouts value");
2026  goto done;
2027  }
2028  }
2029  else if (unformat (line_input, "icmp %u", &sm->icmp_timeout))
2030  {
2032  {
2033  error = clib_error_return (0, "Invalid ICMP timeout value");
2034  goto done;
2035  }
2036  }
2037  else if (unformat (line_input, "reset"))
2038  {
2045  nat64_set_tcp_timeouts (0, 0);
2046  }
2047  else
2048  {
2049  error = clib_error_return (0, "unknown input '%U'",
2050  format_unformat_error, line_input);
2051  goto done;
2052  }
2053  }
2054 done:
2055  unformat_free (line_input);
2056  return error;
2057 }
2058 
2059 static clib_error_t *
2061  unformat_input_t * input,
2062  vlib_cli_command_t * cmd)
2063 {
2064  snat_main_t *sm = &snat_main;
2065 
2066  vlib_cli_output (vm, "udp timeout: %dsec", sm->udp_timeout);
2067  vlib_cli_output (vm, "tcp-established timeout: %dsec",
2069  vlib_cli_output (vm, "tcp-transitory timeout: %dsec",
2071  vlib_cli_output (vm, "icmp timeout: %dsec", sm->icmp_timeout);
2072 
2073  return 0;
2074 }
2075 
2076 static clib_error_t *
2078  unformat_input_t * input,
2079  vlib_cli_command_t * cmd)
2080 {
2081  snat_main_t *sm = &snat_main;
2082  snat_det_map_t *dm;
2083  snat_det_session_t *ses;
2084  int i;
2085 
2086  if (!sm->deterministic)
2088 
2089  vlib_cli_output (vm, "NAT44 deterministic sessions:");
2090  /* *INDENT-OFF* */
2091  pool_foreach (dm, sm->det_maps,
2092  ({
2093  vec_foreach_index (i, dm->sessions)
2094  {
2095  ses = vec_elt_at_index (dm->sessions, i);
2096  if (ses->in_port)
2097  vlib_cli_output (vm, " %U", format_det_map_ses, dm, ses, &i);
2098  }
2099  }));
2100  /* *INDENT-ON* */
2101  return 0;
2102 }
2103 
2104 static clib_error_t *
2106  unformat_input_t * input,
2107  vlib_cli_command_t * cmd)
2108 {
2109  snat_main_t *sm = &snat_main;
2110  unformat_input_t _line_input, *line_input = &_line_input;
2111  ip4_address_t out_addr, ext_addr, in_addr;
2112  u32 out_port, ext_port;
2113  snat_det_map_t *dm;
2114  snat_det_session_t *ses;
2116  clib_error_t *error = 0;
2117 
2118  if (!sm->deterministic)
2120 
2121  /* Get a line of input. */
2122  if (!unformat_user (input, unformat_line_input, line_input))
2123  return 0;
2124 
2125  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
2126  {
2127  if (unformat (line_input, "%U:%d %U:%d",
2128  unformat_ip4_address, &out_addr, &out_port,
2129  unformat_ip4_address, &ext_addr, &ext_port))
2130  ;
2131  else
2132  {
2133  error = clib_error_return (0, "unknown input '%U'",
2134  format_unformat_error, line_input);
2135  goto done;
2136  }
2137  }
2138 
2139  unformat_free (line_input);
2140 
2141  dm = snat_det_map_by_out (sm, &out_addr);
2142  if (!dm)
2143  vlib_cli_output (vm, "no match");
2144  else
2145  {
2146  snat_det_reverse (dm, &ext_addr, (u16) out_port, &in_addr);
2147  key.ext_host_addr = out_addr;
2148  key.ext_host_port = ntohs ((u16) ext_port);
2149  key.out_port = ntohs ((u16) out_port);
2150  ses = snat_det_get_ses_by_out (dm, &out_addr, key.as_u64);
2151  if (!ses)
2152  vlib_cli_output (vm, "no match");
2153  else
2154  snat_det_ses_close (dm, ses);
2155  }
2156 
2157 done:
2158  unformat_free (line_input);
2159 
2160  return error;
2161 }
2162 
2163 static clib_error_t *
2165  unformat_input_t * input,
2166  vlib_cli_command_t * cmd)
2167 {
2168  snat_main_t *sm = &snat_main;
2169  unformat_input_t _line_input, *line_input = &_line_input;
2170  ip4_address_t in_addr, ext_addr;
2171  u32 in_port, ext_port;
2172  snat_det_map_t *dm;
2173  snat_det_session_t *ses;
2175  clib_error_t *error = 0;
2176 
2177  if (!sm->deterministic)
2179 
2180  /* Get a line of input. */
2181  if (!unformat_user (input, unformat_line_input, line_input))
2182  return 0;
2183 
2184  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
2185  {
2186  if (unformat (line_input, "%U:%d %U:%d",
2187  unformat_ip4_address, &in_addr, &in_port,
2188  unformat_ip4_address, &ext_addr, &ext_port))
2189  ;
2190  else
2191  {
2192  error = clib_error_return (0, "unknown input '%U'",
2193  format_unformat_error, line_input);
2194  goto done;
2195  }
2196  }
2197 
2198  unformat_free (line_input);
2199 
2200  dm = snat_det_map_by_user (sm, &in_addr);
2201  if (!dm)
2202  vlib_cli_output (vm, "no match");
2203  else
2204  {
2205  key.ext_host_addr = ext_addr;
2206  key.ext_host_port = ntohs ((u16) ext_port);
2207  ses =
2208  snat_det_find_ses_by_in (dm, &in_addr, ntohs ((u16) in_port), key);
2209  if (!ses)
2210  vlib_cli_output (vm, "no match");
2211  else
2212  snat_det_ses_close (dm, ses);
2213  }
2214 
2215 done:
2216  unformat_free (line_input);
2217 
2218  return error;
2219 }
2220 /* *INDENT-OFF* */
2221 
2222 /*?
2223  * @cliexpar
2224  * @cliexstart{set snat workers}
2225  * Set NAT workers if 2 or more workers available, use:
2226  * vpp# set snat workers 0-2,5
2227  * @cliexend
2228 ?*/
2229 VLIB_CLI_COMMAND (set_workers_command, static) = {
2230  .path = "set nat workers",
2231  .function = set_workers_command_fn,
2232  .short_help = "set nat workers <workers-list>",
2233 };
2234 
2235 /*?
2236  * @cliexpar
2237  * @cliexstart{show nat workers}
2238  * Show NAT workers.
2239  * vpp# show nat workers:
2240  * 2 workers
2241  * vpp_wk_0
2242  * vpp_wk_1
2243  * @cliexend
2244 ?*/
2245 VLIB_CLI_COMMAND (nat_show_workers_command, static) = {
2246  .path = "show nat workers",
2247  .short_help = "show nat workers",
2248  .function = nat_show_workers_commnad_fn,
2249 };
2250 
2251 /*?
2252  * @cliexpar
2253  * @cliexstart{set nat timeout}
2254  * Set values of timeouts for NAT sessions (in seconds), use:
2255  * vpp# set nat timeout udp 120 tcp-established 7500 tcp-transitory 250 icmp 90
2256  * To reset default values use:
2257  * vpp# set nat44 deterministic timeout reset
2258  * @cliexend
2259 ?*/
2260 VLIB_CLI_COMMAND (set_timeout_command, static) = {
2261  .path = "set nat timeout",
2262  .function = set_timeout_command_fn,
2263  .short_help =
2264  "set nat timeout [udp <sec> | tcp-established <sec> "
2265  "tcp-transitory <sec> | icmp <sec> | reset]",
2266 };
2267 
2268 /*?
2269  * @cliexpar
2270  * @cliexstart{show nat timeouts}
2271  * Show values of timeouts for NAT sessions.
2272  * vpp# show nat timeouts
2273  * udp timeout: 300sec
2274  * tcp-established timeout: 7440sec
2275  * tcp-transitory timeout: 240sec
2276  * icmp timeout: 60sec
2277  * @cliexend
2278 ?*/
2279 VLIB_CLI_COMMAND (nat_show_timeouts_command, static) = {
2280  .path = "show nat timeouts",
2281  .short_help = "show nat timeouts",
2282  .function = nat_show_timeouts_command_fn,
2283 };
2284 
2285 /*?
2286  * @cliexpar
2287  * @cliexstart{nat set logging level}
2288  * To set NAT logging level use:
2289  * Set nat logging level
2290  * @cliexend
2291 ?*/
2292 VLIB_CLI_COMMAND (snat_set_log_level_command, static) = {
2293  .path = "nat set logging level",
2294  .function = snat_set_log_level_command_fn,
2295  .short_help = "nat set logging level <level>",
2296 };
2297 
2298 /*?
2299  * @cliexpar
2300  * @cliexstart{snat ipfix logging}
2301  * To enable NAT IPFIX logging use:
2302  * vpp# nat ipfix logging
2303  * To set IPFIX exporter use:
2304  * vpp# set ipfix exporter collector 10.10.10.3 src 10.10.10.1
2305  * @cliexend
2306 ?*/
2307 VLIB_CLI_COMMAND (snat_ipfix_logging_enable_disable_command, static) = {
2308  .path = "nat ipfix logging",
2310  .short_help = "nat ipfix logging [domain <domain-id>] [src-port <port>] [disable]",
2311 };
2312 
2313 /*?
2314  * @cliexpar
2315  * @cliexstart{nat addr-port-assignment-alg}
2316  * Set address and port assignment algorithm
2317  * For the MAP-E CE limit port choice based on PSID use:
2318  * vpp# nat addr-port-assignment-alg map-e psid 10 psid-offset 6 psid-len 6
2319  * For port range use:
2320  * vpp# nat addr-port-assignment-alg port-range <start-port> - <end-port>
2321  * To set standard (default) address and port assignment algorithm use:
2322  * vpp# nat addr-port-assignment-alg default
2323  * @cliexend
2324 ?*/
2325 VLIB_CLI_COMMAND (nat44_set_alloc_addr_and_port_alg_command, static) = {
2326  .path = "nat addr-port-assignment-alg",
2327  .short_help = "nat addr-port-assignment-alg <alg-name> [<alg-params>]",
2329 };
2330 
2331 /*?
2332  * @cliexpar
2333  * @cliexstart{show nat addr-port-assignment-alg}
2334  * Show address and port assignment algorithm
2335  * @cliexend
2336 ?*/
2337 VLIB_CLI_COMMAND (nat44_show_alloc_addr_and_port_alg_command, static) = {
2338  .path = "show nat addr-port-assignment-alg",
2339  .short_help = "show nat addr-port-assignment-alg",
2341 };
2342 
2343 /*?
2344  * @cliexpar
2345  * @cliexstart{nat mss-clamping}
2346  * Set TCP MSS rewriting configuration
2347  * To enable TCP MSS rewriting use:
2348  * vpp# nat mss-clamping 1452
2349  * To disbale TCP MSS rewriting use:
2350  * vpp# nat mss-clamping disable
2351  * @cliexend
2352 ?*/
2353 VLIB_CLI_COMMAND (nat_set_mss_clamping_command, static) = {
2354  .path = "nat mss-clamping",
2355  .short_help = "nat mss-clamping <mss-value>|disable",
2356  .function = nat_set_mss_clamping_command_fn,
2357 };
2358 
2359 /*?
2360  * @cliexpar
2361  * @cliexstart{show nat mss-clamping}
2362  * Show TCP MSS rewriting configuration
2363  * @cliexend
2364 ?*/
2365 VLIB_CLI_COMMAND (nat_show_mss_clamping_command, static) = {
2366  .path = "show nat mss-clamping",
2367  .short_help = "show nat mss-clamping",
2369 };
2370 
2371 /*?
2372  * @cliexpar
2373  * @cliexstart{nat ha failover}
2374  * Set HA failover (remote settings)
2375  * @cliexend
2376 ?*/
2377 VLIB_CLI_COMMAND (nat_ha_failover_command, static) = {
2378  .path = "nat ha failover",
2379  .short_help = "nat ha failover <ip4-address>:<port> [refresh-interval <sec>]",
2380  .function = nat_ha_failover_command_fn,
2381 };
2382 
2383 /*?
2384  * @cliexpar
2385  * @cliexstart{nat ha listener}
2386  * Set HA listener (local settings)
2387  * @cliexend
2388 ?*/
2389 VLIB_CLI_COMMAND (nat_ha_listener_command, static) = {
2390  .path = "nat ha listener",
2391  .short_help = "nat ha listener <ip4-address>:<port> [path-mtu <path-mtu>]",
2392  .function = nat_ha_listener_command_fn,
2393 };
2394 
2395 /*?
2396  * @cliexpar
2397  * @cliexstart{show nat ha}
2398  * Show HA configuration/status
2399  * @cliexend
2400 ?*/
2401 VLIB_CLI_COMMAND (nat_show_ha_command, static) = {
2402  .path = "show nat ha",
2403  .short_help = "show nat ha",
2404  .function = nat_show_ha_command_fn,
2405 };
2406 
2407 /*?
2408  * @cliexpar
2409  * @cliexstart{nat ha flush}
2410  * Flush the current HA data (for testing)
2411  * @cliexend
2412 ?*/
2413 VLIB_CLI_COMMAND (nat_ha_flush_command, static) = {
2414  .path = "nat ha flush",
2415  .short_help = "nat ha flush",
2416  .function = nat_ha_flush_command_fn,
2417 };
2418 
2419 /*?
2420  * @cliexpar
2421  * @cliexstart{nat ha resync}
2422  * Resync HA (resend existing sessions to new failover)
2423  * @cliexend
2424 ?*/
2425 VLIB_CLI_COMMAND (nat_ha_resync_command, static) = {
2426  .path = "nat ha resync",
2427  .short_help = "nat ha resync",
2428  .function = nat_ha_resync_command_fn,
2429 };
2430 
2431 /*?
2432  * @cliexpar
2433  * @cliexstart{show nat44 hash tables}
2434  * Show NAT44 hash tables
2435  * @cliexend
2436 ?*/
2437 VLIB_CLI_COMMAND (nat44_show_hash, static) = {
2438  .path = "show nat44 hash tables",
2439  .short_help = "show nat44 hash tables [detail|verbose]",
2440  .function = nat44_show_hash_commnad_fn,
2441 };
2442 
2443 /*?
2444  * @cliexpar
2445  * @cliexstart{nat44 add address}
2446  * Add/delete NAT44 pool address.
2447  * To add NAT44 pool address use:
2448  * vpp# nat44 add address 172.16.1.3
2449  * vpp# nat44 add address 172.16.2.2 - 172.16.2.24
2450  * To add NAT44 pool address for specific tenant (identified by VRF id) use:
2451  * vpp# nat44 add address 172.16.1.3 tenant-vrf 10
2452  * @cliexend
2453 ?*/
2454 VLIB_CLI_COMMAND (add_address_command, static) = {
2455  .path = "nat44 add address",
2456  .short_help = "nat44 add address <ip4-range-start> [- <ip4-range-end>] "
2457  "[tenant-vrf <vrf-id>] [twice-nat] [del]",
2458  .function = add_address_command_fn,
2459 };
2460 
2461 /*?
2462  * @cliexpar
2463  * @cliexstart{show nat44 summary}
2464  * Show NAT44 summary
2465  * vpp# show nat44 summary
2466  * @cliexend
2467 ?*/
2468 VLIB_CLI_COMMAND (nat44_show_summary_command, static) = {
2469  .path = "show nat44 summary",
2470  .short_help = "show nat44 summary",
2471  .function = nat44_show_summary_command_fn,
2472 };
2473 
2474 /*?
2475  * @cliexpar
2476  * @cliexstart{show nat44 addresses}
2477  * Show NAT44 pool addresses.
2478  * vpp# show nat44 addresses
2479  * NAT44 pool addresses:
2480  * 172.16.2.2
2481  * tenant VRF independent
2482  * 10 busy udp ports
2483  * 0 busy tcp ports
2484  * 0 busy icmp ports
2485  * 172.16.1.3
2486  * tenant VRF: 10
2487  * 0 busy udp ports
2488  * 2 busy tcp ports
2489  * 0 busy icmp ports
2490  * NAT44 twice-nat pool addresses:
2491  * 10.20.30.72
2492  * tenant VRF independent
2493  * 0 busy udp ports
2494  * 0 busy tcp ports
2495  * 0 busy icmp ports
2496  * @cliexend
2497 ?*/
2498 VLIB_CLI_COMMAND (nat44_show_addresses_command, static) = {
2499  .path = "show nat44 addresses",
2500  .short_help = "show nat44 addresses",
2501  .function = nat44_show_addresses_command_fn,
2502 };
2503 
2504 /*?
2505  * @cliexpar
2506  * @cliexstart{set interface nat44}
2507  * Enable/disable NAT44 feature on the interface.
2508  * To enable NAT44 feature with local network interface use:
2509  * vpp# set interface nat44 in GigabitEthernet0/8/0
2510  * To enable NAT44 feature with external network interface use:
2511  * vpp# set interface nat44 out GigabitEthernet0/a/0
2512  * @cliexend
2513 ?*/
2514 VLIB_CLI_COMMAND (set_interface_snat_command, static) = {
2515  .path = "set interface nat44",
2516  .function = snat_feature_command_fn,
2517  .short_help = "set interface nat44 in <intfc> out <intfc> [output-feature] "
2518  "[del]",
2519 };
2520 
2521 /*?
2522  * @cliexpar
2523  * @cliexstart{show nat44 interfaces}
2524  * Show interfaces with NAT44 feature.
2525  * vpp# show nat44 interfaces
2526  * NAT44 interfaces:
2527  * GigabitEthernet0/8/0 in
2528  * GigabitEthernet0/a/0 out
2529  * @cliexend
2530 ?*/
2531 VLIB_CLI_COMMAND (nat44_show_interfaces_command, static) = {
2532  .path = "show nat44 interfaces",
2533  .short_help = "show nat44 interfaces",
2535 };
2536 
2537 /*?
2538  * @cliexpar
2539  * @cliexstart{nat44 add static mapping}
2540  * Static mapping allows hosts on the external network to initiate connection
2541  * to to the local network host.
2542  * To create static mapping between local host address 10.0.0.3 port 6303 and
2543  * external address 4.4.4.4 port 3606 for TCP protocol use:
2544  * vpp# nat44 add static mapping tcp local 10.0.0.3 6303 external 4.4.4.4 3606
2545  * If not runnig "static mapping only" NAT plugin mode use before:
2546  * vpp# nat44 add address 4.4.4.4
2547  * To create static mapping between local and external address use:
2548  * vpp# nat44 add static mapping local 10.0.0.3 external 4.4.4.4
2549  * @cliexend
2550 ?*/
2551 VLIB_CLI_COMMAND (add_static_mapping_command, static) = {
2552  .path = "nat44 add static mapping",
2553  .function = add_static_mapping_command_fn,
2554  .short_help =
2555  "nat44 add static mapping tcp|udp|icmp local <addr> [<port>] "
2556  "external <addr> [<port>] [vrf <table-id>] [twice-nat|self-twice-nat] "
2557  "[out2in-only] [del]",
2558 };
2559 
2560 /*?
2561  * @cliexpar
2562  * @cliexstart{nat44 add identity mapping}
2563  * Identity mapping translate an IP address to itself.
2564  * To create identity mapping for address 10.0.0.3 port 6303 for TCP protocol
2565  * use:
2566  * vpp# nat44 add identity mapping 10.0.0.3 tcp 6303
2567  * To create identity mapping for address 10.0.0.3 use:
2568  * vpp# nat44 add identity mapping 10.0.0.3
2569  * To create identity mapping for DHCP addressed interface use:
2570  * vpp# nat44 add identity mapping external GigabitEthernet0/a/0 tcp 3606
2571  * @cliexend
2572 ?*/
2573 VLIB_CLI_COMMAND (add_identity_mapping_command, static) = {
2574  .path = "nat44 add identity mapping",
2575  .function = add_identity_mapping_command_fn,
2576  .short_help = "nat44 add identity mapping <ip4-addr>|external <interface> "
2577  "[<protocol> <port>] [vrf <table-id>] [del]",
2578 };
2579 
2580 /*?
2581  * @cliexpar
2582  * @cliexstart{nat44 add load-balancing static mapping}
2583  * Service load balancing using NAT44
2584  * To add static mapping with load balancing for service with external IP
2585  * address 1.2.3.4 and TCP port 80 and mapped to 2 local servers
2586  * 10.100.10.10:8080 and 10.100.10.20:8080 with probability 80% resp. 20% use:
2587  * 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
2588  * @cliexend
2589 ?*/
2590 VLIB_CLI_COMMAND (add_lb_static_mapping_command, static) = {
2591  .path = "nat44 add load-balancing static mapping",
2593  .short_help =
2594  "nat44 add load-balancing static mapping protocol tcp|udp "
2595  "external <addr>:<port> local <addr>:<port> [vrf <table-id>] "
2596  "probability <n> [twice-nat|self-twice-nat] [out2in-only] "
2597  "[affinity <timeout-seconds>] [del]",
2598 };
2599 
2600 /*?
2601  * @cliexpar
2602  * @cliexstart{nat44 add load-balancing static mapping}
2603  * Modify service load balancing using NAT44
2604  * To add new back-end server 10.100.10.30:8080 for service load balancing
2605  * static mapping with external IP address 1.2.3.4 and TCP port 80 use:
2606  * vpp# nat44 add load-balancing back-end protocol tcp external 1.2.3.4:80 local 10.100.10.30:8080 probability 25
2607  * @cliexend
2608 ?*/
2609 VLIB_CLI_COMMAND (add_lb_backend_command, static) = {
2610  .path = "nat44 add load-balancing back-end",
2611  .function = add_lb_backend_command_fn,
2612  .short_help =
2613  "nat44 add load-balancing back-end protocol tcp|udp "
2614  "external <addr>:<port> local <addr>:<port> [vrf <table-id>] "
2615  "probability <n> [del]",
2616 };
2617 
2618 /*?
2619  * @cliexpar
2620  * @cliexstart{show nat44 static mappings}
2621  * Show NAT44 static mappings.
2622  * vpp# show nat44 static mappings
2623  * NAT44 static mappings:
2624  * local 10.0.0.3 external 4.4.4.4 vrf 0
2625  * tcp local 192.168.0.4:6303 external 4.4.4.3:3606 vrf 0
2626  * tcp vrf 0 external 1.2.3.4:80 out2in-only
2627  * local 10.100.10.10:8080 probability 80
2628  * local 10.100.10.20:8080 probability 20
2629  * tcp local 10.100.3.8:8080 external 169.10.10.1:80 vrf 0 twice-nat
2630  * tcp local 10.0.0.10:3603 external GigabitEthernet0/a/0:6306 vrf 10
2631  * @cliexend
2632 ?*/
2633 VLIB_CLI_COMMAND (nat44_show_static_mappings_command, static) = {
2634  .path = "show nat44 static mappings",
2635  .short_help = "show nat44 static mappings",
2637 };
2638 
2639 /*?
2640  * @cliexpar
2641  * @cliexstart{nat44 add interface address}
2642  * Use NAT44 pool address from specific interfce
2643  * To add NAT44 pool address from specific interface use:
2644  * vpp# nat44 add interface address GigabitEthernet0/8/0
2645  * @cliexend
2646 ?*/
2647 VLIB_CLI_COMMAND (snat_add_interface_address_command, static) = {
2648  .path = "nat44 add interface address",
2649  .short_help = "nat44 add interface address <interface> [twice-nat] [del]",
2651 };
2652 
2653 /*?
2654  * @cliexpar
2655  * @cliexstart{show nat44 interface address}
2656  * Show NAT44 pool address interfaces
2657  * vpp# show nat44 interface address
2658  * NAT44 pool address interfaces:
2659  * GigabitEthernet0/a/0
2660  * NAT44 twice-nat pool address interfaces:
2661  * GigabitEthernet0/8/0
2662  * @cliexend
2663 ?*/
2664 VLIB_CLI_COMMAND (nat44_show_interface_address_command, static) = {
2665  .path = "show nat44 interface address",
2666  .short_help = "show nat44 interface address",
2668 };
2669 
2670 /*?
2671  * @cliexpar
2672  * @cliexstart{show nat44 sessions}
2673  * Show NAT44 sessions.
2674  * @cliexend
2675 ?*/
2676 VLIB_CLI_COMMAND (nat44_show_sessions_command, static) = {
2677  .path = "show nat44 sessions",
2678  .short_help = "show nat44 sessions [detail|metrics]",
2679  .function = nat44_show_sessions_command_fn,
2680 };
2681 
2682 /*?
2683  * @cliexpar
2684  * @cliexstart{set nat44 session limit}
2685  * Set NAT44 session limit.
2686  * @cliexend
2687 ?*/
2688 VLIB_CLI_COMMAND (nat44_set_session_limit_command, static) = {
2689  .path = "set nat44 session limit",
2690  .short_help = "set nat44 session limit <limit> [vrf <table-id>]",
2692 };
2693 
2694 /*?
2695  * @cliexpar
2696  * @cliexstart{nat44 del user}
2697  * To delete all NAT44 user sessions:
2698  * vpp# nat44 del user 10.0.0.3
2699  * @cliexend
2700 ?*/
2701 VLIB_CLI_COMMAND (nat44_del_user_command, static) = {
2702  .path = "nat44 del user",
2703  .short_help = "nat44 del user <addr> [fib <index>]",
2704  .function = nat44_del_user_command_fn,
2705 };
2706 
2707 /*?
2708  * @cliexpar
2709  * @cliexstart{clear nat44 sessions}
2710  * To clear all NAT44 sessions
2711  * vpp# clear nat44 sessions
2712  * @cliexend
2713 ?*/
2714 VLIB_CLI_COMMAND (nat44_clear_sessions_command, static) = {
2715  .path = "clear nat44 sessions",
2716  .short_help = "clear nat44 sessions",
2717  .function = nat44_clear_sessions_command_fn,
2718 };
2719 
2720 /*?
2721  * @cliexpar
2722  * @cliexstart{nat44 del session}
2723  * To administratively delete NAT44 session by inside address and port use:
2724  * vpp# nat44 del session in 10.0.0.3:6303 tcp
2725  * To administratively delete NAT44 session by outside address and port use:
2726  * vpp# nat44 del session out 1.0.0.3:6033 udp
2727  * @cliexend
2728 ?*/
2729 VLIB_CLI_COMMAND (nat44_del_session_command, static) = {
2730  .path = "nat44 del session",
2731  .short_help = "nat44 del session in|out <addr>:<port> tcp|udp|icmp [vrf <id>] [external-host <addr>:<port>]",
2732  .function = nat44_del_session_command_fn,
2733 };
2734 
2735 /*?
2736  * @cliexpar
2737  * @cliexstart{nat44 forwarding}
2738  * Enable or disable forwarding
2739  * Forward packets which don't match existing translation
2740  * or static mapping instead of dropping them.
2741  * To enable forwarding, use:
2742  * vpp# nat44 forwarding enable
2743  * To disable forwarding, use:
2744  * vpp# nat44 forwarding disable
2745  * @cliexend
2746 ?*/
2747 VLIB_CLI_COMMAND (snat_forwarding_set_command, static) = {
2748  .path = "nat44 forwarding",
2749  .short_help = "nat44 forwarding enable|disable",
2750  .function = snat_forwarding_set_command_fn,
2751 };
2752 
2753 /*?
2754  * @cliexpar
2755  * @cliexstart{nat44 deterministic add}
2756  * Create bijective mapping of inside address to outside address and port range
2757  * pairs, with the purpose of enabling deterministic NAT to reduce logging in
2758  * CGN deployments.
2759  * To create deterministic mapping between inside network 10.0.0.0/18 and
2760  * outside network 1.1.1.0/30 use:
2761  * # vpp# nat44 deterministic add in 10.0.0.0/18 out 1.1.1.0/30
2762  * @cliexend
2763 ?*/
2764 VLIB_CLI_COMMAND (snat_det_map_command, static) = {
2765  .path = "nat44 deterministic add",
2766  .short_help = "nat44 deterministic add in <addr>/<plen> out <addr>/<plen> [del]",
2767  .function = snat_det_map_command_fn,
2768 };
2769 
2770 /*?
2771  * @cliexpar
2772  * @cliexpstart{show nat44 deterministic mappings}
2773  * Show NAT44 deterministic mappings
2774  * vpp# show nat44 deterministic mappings
2775  * NAT44 deterministic mappings:
2776  * in 10.0.0.0/24 out 1.1.1.1/32
2777  * outside address sharing ratio: 256
2778  * number of ports per inside host: 252
2779  * sessions number: 0
2780  * @cliexend
2781 ?*/
2782 VLIB_CLI_COMMAND (nat44_det_show_mappings_command, static) = {
2783  .path = "show nat44 deterministic mappings",
2784  .short_help = "show nat44 deterministic mappings",
2786 };
2787 
2788 /*?
2789  * @cliexpar
2790  * @cliexstart{nat44 deterministic forward}
2791  * Return outside address and port range from inside address for deterministic
2792  * NAT.
2793  * To obtain outside address and port of inside host use:
2794  * vpp# nat44 deterministic forward 10.0.0.2
2795  * 1.1.1.0:<1054-1068>
2796  * @cliexend
2797 ?*/
2798 VLIB_CLI_COMMAND (snat_det_forward_command, static) = {
2799  .path = "nat44 deterministic forward",
2800  .short_help = "nat44 deterministic forward <addr>",
2801  .function = snat_det_forward_command_fn,
2802 };
2803 
2804 /*?
2805  * @cliexpar
2806  * @cliexstart{nat44 deterministic reverse}
2807  * Return inside address from outside address and port for deterministic NAT.
2808  * To obtain inside host address from outside address and port use:
2809  * #vpp nat44 deterministic reverse 1.1.1.1:1276
2810  * 10.0.16.16
2811  * @cliexend
2812 ?*/
2813 VLIB_CLI_COMMAND (snat_det_reverse_command, static) = {
2814  .path = "nat44 deterministic reverse",
2815  .short_help = "nat44 deterministic reverse <addr>:<port>",
2816  .function = snat_det_reverse_command_fn,
2817 };
2818 
2819 /*?
2820  * @cliexpar
2821  * @cliexstart{show nat44 deterministic sessions}
2822  * Show NAT44 deterministic sessions.
2823  * vpp# show nat44 deterministic sessions
2824  * NAT44 deterministic sessions:
2825  * in 10.0.0.3:3005 out 1.1.1.2:1146 external host 172.16.1.2:3006 state: udp-active expire: 306
2826  * in 10.0.0.3:3000 out 1.1.1.2:1141 external host 172.16.1.2:3001 state: udp-active expire: 306
2827  * in 10.0.0.4:3005 out 1.1.1.2:1177 external host 172.16.1.2:3006 state: udp-active expire: 306
2828  * @cliexend
2829 ?*/
2830 VLIB_CLI_COMMAND (nat44_det_show_sessions_command, static) = {
2831  .path = "show nat44 deterministic sessions",
2832  .short_help = "show nat44 deterministic sessions",
2834 };
2835 
2836 /*?
2837  * @cliexpar
2838  * @cliexstart{nat44 deterministic close session out}
2839  * Close session using outside ip address and port
2840  * and external ip address and port, use:
2841  * vpp# nat44 deterministic close session out 1.1.1.1:1276 2.2.2.2:2387
2842  * @cliexend
2843 ?*/
2844 VLIB_CLI_COMMAND (snat_det_close_sesion_out_command, static) = {
2845  .path = "nat44 deterministic close session out",
2846  .short_help = "nat44 deterministic close session out "
2847  "<out_addr>:<out_port> <ext_addr>:<ext_port>",
2848  .function = snat_det_close_session_out_fn,
2849 };
2850 
2851 /*?
2852  * @cliexpar
2853  * @cliexstart{nat44 deterministic close session in}
2854  * Close session using inside ip address and port
2855  * and external ip address and port, use:
2856  * vpp# nat44 deterministic close session in 3.3.3.3:3487 2.2.2.2:2387
2857  * @cliexend
2858 ?*/
2859 VLIB_CLI_COMMAND (snat_det_close_session_in_command, static) = {
2860  .path = "nat44 deterministic close session in",
2861  .short_help = "nat44 deterministic close session in "
2862  "<in_addr>:<in_port> <ext_addr>:<ext_port>",
2863  .function = snat_det_close_session_in_fn,
2864 };
2865 
2866 /* *INDENT-ON* */
2867 
2868 /*
2869  * fd.io coding-style-patch-verification: ON
2870  *
2871  * Local Variables:
2872  * eval: (c-set-style "gnu")
2873  * End:
2874  */
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:532
u8 count
Definition: dhcp.api:208
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:1931
#define nat_log_info(...)
Definition: nat.h:825
#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:1504
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:1740
int nat64_set_udp_timeout(u32 timeout)
Set UDP session timeout.
Definition: nat64.c:792
u16 ext_host_port
Definition: nat.h:94
u16 out_port
Definition: nat.h:95
nat_affinity_main_t nat_affinity_main
Definition: nat_affinity.c:23
u32 icmp_timeout
Definition: nat.h:652
int nat44_del_session(snat_main_t *sm, ip4_address_t *addr, u16 port, nat_protocol_t proto, u32 vrf_id, int is_in)
Delete NAT44 session.
Definition: nat.c:4392
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
u16 start_port
Definition: nat.h:562
#define SNAT_TCP_ESTABLISHED_TIMEOUT
Definition: nat.h:42
unsigned long u64
Definition: types.h:89
static clib_error_t * nat44_set_session_limit_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:1572
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:291
static clib_error_t * nat_ha_resync_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:520
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:590
static void snat_det_ses_close(snat_det_map_t *dm, snat_det_session_t *ses)
Definition: nat_det.h:182
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:989
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:4435
unformat_function_t unformat_vnet_sw_interface
nat_protocol_t
Definition: lib.h:41
snat_det_map_t * det_maps
Definition: nat.h:621
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:1106
void nat_ha_get_resync_status(u8 *in_resync, u32 *resync_ack_missed)
Get resync status.
Definition: nat_ha.c:824
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:254
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:2105
static clib_error_t * nat44_show_summary_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:640
format_function_t format_vnet_sw_if_index_name
unsigned char u8
Definition: types.h:56
u8 deterministic
Definition: nat.h:629
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:1861
static clib_error_t * nat_show_ha_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:473
clib_bihash_8_8_t user_hash
Definition: nat.h:461
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:212
u32 max_translations_per_user
Definition: nat.h:640
u16 src_port
Definition: udp.api:41
clib_bihash_8_8_t in2out
Definition: nat.h:454
log_level
Definition: vpe_types.api:32
format_function_t format_ip4_address
Definition: format.h:73
int nat_ha_resync(u32 client_index, u32 pid, nat_ha_resync_event_cb_t event_callback)
Resync HA (resend existing sessions to new failover)
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:513
unformat_function_t unformat_ip4_address
Definition: format.h:68
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:1802
vl_api_interface_index_t sw_if_index
Definition: gre.api:53
ip4_address_t ext_host_addr
Definition: nat.h:93
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:636
int nat64_set_icmp_timeout(u32 timeout)
Set ICMP session timeout.
Definition: nat64.c:813
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:2164
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:1884
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
u8 probability
Definition: nat.api:855
#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.
#define UNSUPPORTED_IN_DET_OR_ED_MODE_STR
Definition: nat44_cli.c:31
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:260
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:345
unformat_function_t unformat_line_input
Definition: format.h:283
int nat44_set_session_limit(u32 session_limit, u32 vrf_id)
Set NAT44 session limit (session limit, vrf id)
Definition: nat.c:333
u32 max_translations
Definition: nat.h:635
u32 * auto_add_sw_if_indices_twice_nat
Definition: nat.h:573
vlib_worker_thread_t * vlib_worker_threads
Definition: threads.c:34
static_always_inline int nat44_user_del(ip4_address_t *addr, u32 fib_index)
Definition: inlines.h:115
u16 mss_value_net
Definition: nat.h:656
nat_addr_and_port_alloc_alg_t addr_and_port_alloc_alg
Definition: nat.h:556
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:803
clib_bihash_16_8_t out2in_ed
Definition: nat.h:457
vl_api_ip_proto_t proto
Definition: acl_types.api:50
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:655
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:1750
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:2077
u8 out2in_dpo
Definition: nat.h:630
#define SNAT_UDP_TIMEOUT
Definition: nat.h:40
snat_static_mapping_t * static_mappings
Definition: nat.h:545
u32 udp_timeout
Definition: nat.h:649
u8 static_mapping_only
Definition: nat.h:627
static clib_error_t * nat44_del_user_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:1615
void nat_ha_get_listener(ip4_address_t *addr, u16 *port, u32 *path_mtu)
Get HA listener/local configuration.
Definition: nat_ha.c:385
void nat_ha_flush(u8 is_resync)
Flush the current HA data (for testing)
Definition: nat_ha.c:682
clib_bihash_8_8_t static_mapping_by_external
Definition: nat.h:542
u8 psid_offset
Definition: nat.h:558
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:846
void nat_set_alloc_addr_and_port_default(void)
Set address and port assignment algorithm to default/standard.
Definition: nat.c:4497
vlib_main_t * vm
Definition: in2out_ed.c:1599
u8 psid_length
Definition: nat.h:559
vnet_main_t * vnet_main
Definition: nat.h:671
u32 inside_vrf_id
Definition: nat.h:644
u8 log_level
Definition: nat.h:668
snat_interface_t * output_feature_interfaces
Definition: nat.h:549
static clib_error_t * snat_set_log_level_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:127
snat_main_t snat_main
Definition: nat.c:41
snat_user_t * users
Definition: nat.h:464
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:1185
#define UNFORMAT_END_OF_INPUT
Definition: format.h:145
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:160
clib_bihash_8_8_t out2in
Definition: nat.h:453
u32 ft_table_id
Table ID (hash key) for this FIB.
Definition: fib_table.h:92
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:101
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:956
u32 outside_vrf_id
Definition: nat.h:642
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:3099
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
u16 end_port
Definition: nat.h:563
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:380
deterministic NAT definitions
format_function_t format_snat_static_map_to_resolve
Definition: nat.h:714
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:2126
u16 psid
Definition: nat.h:560
format_function_t format_nat_addr_and_port_alloc_alg
Definition: nat.h:720
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:1984
string name[64]
Definition: ip.api:44
u32 tcp_transitory_timeout
Definition: nat.h:650
int nat_ha_set_listener(ip4_address_t *addr, u16 port, u32 path_mtu)
Set HA listener (local settings)
Definition: nat_ha.c:352
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
static clib_error_t * nat_ha_failover_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:395
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:152
u32 * auto_add_sw_if_indices
Definition: nat.h:572
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:381
static snat_det_map_t * snat_det_map_by_user(snat_main_t *sm, ip4_address_t *user_addr)
Definition: nat_det.h:45
unformat_function_t unformat_nat_protocol
Definition: nat.h:722
static clib_error_t * nat_ha_flush_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:512
u32 num_workers
Definition: nat.h:527
static clib_error_t * nat_ha_listener_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:435
Definition: nat.h:381
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:689
int nat_ha_set_failover(ip4_address_t *addr, u16 port, u32 session_refresh_interval)
Set HA failover (remote settings)
Definition: nat_ha.c:395
u32 first_worker_index
Definition: nat.h:528
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:4486
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:989
#define clib_bitmap_free(v)
Free a bitmap.
Definition: bitmap.h:92
ip4_address_t addr
Definition: nat.h:314
snat_address_t * twice_nat_addresses
Definition: nat.h:569
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:1675
typedef key
Definition: ipsec_types.api:85
NAT64 global declarations.
int nat64_set_tcp_timeouts(u32 trans, u32 est)
Set TCP session timeouts.
Definition: nat64.c:834
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:2060
static_always_inline void nat44_sessions_clear()
Definition: inlines.h:68
int nat44_lb_static_mapping_add_del_local(ip4_address_t e_addr, u16 e_port, ip4_address_t l_addr, u16 l_port, nat_protocol_t proto, u32 vrf_id, u8 probability, u8 is_add)
Definition: nat.c:1578
twice_nat_type_t
Definition: nat.h:376
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
#define UNSUPPORTED_IN_DET_MODE_STR
Definition: nat44_cli.c:35
static_always_inline u8 nat_proto_to_ip_proto(nat_protocol_t nat_proto)
Definition: inlines.h:35
u16 ports_per_host
Definition: nat.h:355
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:1418
u32 * workers
Definition: nat.h:529
u64 uword
Definition: types.h:112
snat_main_per_thread_data_t * per_thread_data
Definition: nat.h:536
static void unformat_free(unformat_input_t *i)
Definition: format.h:163
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:29
snat_address_t * addresses
Definition: nat.h:552
u16 port
Definition: lb_types.api:72
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:315
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 interface.
Definition: nat.c:4324
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:1474
void nat_ha_get_failover(ip4_address_t *addr, u16 *port, u32 *session_refresh_interval)
Get HA failover/remote settings.
Definition: nat_ha.c:410
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:1393
#define UNSUPPORTED_IN_DET_OR_NON_ED_MODE_STR
Definition: nat44_cli.c:33
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:1301
#define SNAT_ICMP_TIMEOUT
Definition: nat.h:43
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:576
static clib_error_t * nat44_clear_sessions_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: nat44_cli.c:1660
static void increment_v4_address(ip4_address_t *a)
Definition: nat_inlines.h:755
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
#define SUPPORTED_ONLY_IN_DET_MODE_STR
Definition: nat44_cli.c:39
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, nat_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:862
u8 forwarding_enabled
Definition: nat.h:624
#define vec_foreach(var, vec)
Vector iterator.
int nat44_add_del_lb_static_mapping(ip4_address_t e_addr, u16 e_port, nat_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:1325
int snat_set_workers(uword *bitmap)
Set NAT plugin workers.
Definition: nat.c:2324
clib_bihash_16_8_t in2out_ed
Definition: nat.h:458
u32 vrf_id
Definition: nat.api:856
u8 endpoint_dependent
Definition: nat.h:631
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:4474
NAT plugin client-IP based session affinity for load-balancing.
#define SNAT_TCP_TRANSITORY_TIMEOUT
Definition: nat.h:41
snat_session_t * sessions
Definition: nat.h:467
clib_bihash_8_8_t static_mapping_by_local
Definition: nat.h:539
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:1855
u32 fib_index
Definition: nat.h:315
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:43
snat_interface_t * interfaces
Definition: nat.h:548
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
NAT active-passive HA.
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:171
u32 tcp_established_timeout
Definition: nat.h:651
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:128