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:
7 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 #include <nat/lib/ipfix_logging.h>
22 #include <nat/lib/nat_inlines.h>
23 #include <nat/nat_inlines.h>
24 #include <nat/nat44/inlines.h>
25 #include <nat/nat_affinity.h>
26 #include <vnet/fib/fib_table.h>
27 #include <nat/nat_ha.h>
29 #define UNSUPPORTED_IN_ED_MODE_STR \
30 "This command is unsupported in endpoint dependent mode"
31 #define SUPPORTED_ONLY_IN_ED_MODE_STR \
32 "This command is supported only in endpoint dependent mode"
35 nat44_enable_command_fn (vlib_main_t * vm,
36 unformat_input_t * input, vlib_cli_command_t * cmd)
38 snat_main_t *sm = &snat_main;
39 unformat_input_t _line_input, *line_input = &_line_input;
40 clib_error_t *error = 0;
42 nat44_config_t c = { 0 };
45 // TODO: check this also inside the function so it can be
46 // safely called from anyplace, also sanity checking required
48 return clib_error_return (0, "nat44 already enabled");
50 /* Get a line of input. */
51 if (!unformat_user (input, unformat_line_input, line_input))
53 if (nat44_plugin_enable (c) != 0)
54 return clib_error_return (0, "nat44 enable failed");
58 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
60 if (!mode_set && unformat (line_input, "static-mapping-only"))
63 c.static_mapping_only = 1;
64 if (unformat (line_input, "connection-tracking"))
66 c.connection_tracking = 1;
69 else if (!mode_set && unformat (line_input, "out2in-dpo"))
74 else if (!mode_set && unformat (line_input, "endpoint-dependent"))
77 c.endpoint_dependent = 1;
79 else if (unformat (input, "inside-vrf %u", &c.inside_vrf));
80 else if (unformat (input, "outside-vrf %u", &c.outside_vrf));
81 else if (unformat (input, "users %u", &c.users));
82 else if (unformat (input, "user-memory %u", &c.user_memory));
83 else if (unformat (input, "sessions %u", &c.sessions));
84 else if (unformat (input, "session-memory %u", &c.session_memory));
85 else if (unformat (input, "user-sessions %u", &c.user_sessions));
88 error = clib_error_return (0, "unknown input '%U'",
89 format_unformat_error, line_input);
94 if (!(c.sessions && c.session_memory))
98 "either number of sessions or size of the memory is required");
102 if (nat44_plugin_enable (c) != 0)
103 error = clib_error_return (0, "nat44 enable failed");
105 unformat_free (line_input);
109 static clib_error_t *
110 nat44_disable_command_fn (vlib_main_t * vm,
111 unformat_input_t * input, vlib_cli_command_t * cmd)
113 snat_main_t *sm = &snat_main;
114 clib_error_t *error = 0;
117 return clib_error_return (0, "nat44 already disabled");
119 if (nat44_plugin_disable () != 0)
120 error = clib_error_return (0, "nat44 disable failed");
125 static clib_error_t *
126 set_workers_command_fn (vlib_main_t * vm,
127 unformat_input_t * input, vlib_cli_command_t * cmd)
129 unformat_input_t _line_input, *line_input = &_line_input;
132 clib_error_t *error = 0;
134 /* Get a line of input. */
135 if (!unformat_user (input, unformat_line_input, line_input))
138 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
140 if (unformat (line_input, "%U", unformat_bitmap_list, &bitmap))
144 error = clib_error_return (0, "unknown input '%U'",
145 format_unformat_error, line_input);
152 error = clib_error_return (0, "List of workers must be specified.");
156 rv = snat_set_workers (bitmap);
158 clib_bitmap_free (bitmap);
162 case VNET_API_ERROR_INVALID_WORKER:
163 error = clib_error_return (0, "Invalid worker(s).");
165 case VNET_API_ERROR_FEATURE_DISABLED:
166 error = clib_error_return (0,
167 "Supported only if 2 or more workes available.");
174 unformat_free (line_input);
179 static clib_error_t *
180 nat_show_workers_commnad_fn (vlib_main_t * vm, unformat_input_t * input,
181 vlib_cli_command_t * cmd)
183 snat_main_t *sm = &snat_main;
186 if (sm->num_workers > 1)
188 vlib_cli_output (vm, "%d workers", vec_len (sm->workers));
190 vec_foreach (worker, sm->workers)
192 vlib_worker_thread_t *w =
193 vlib_worker_threads + *worker + sm->first_worker_index;
194 vlib_cli_output (vm, " %s", w->name);
202 static clib_error_t *
203 snat_set_log_level_command_fn (vlib_main_t * vm,
204 unformat_input_t * input,
205 vlib_cli_command_t * cmd)
207 unformat_input_t _line_input, *line_input = &_line_input;
208 snat_main_t *sm = &snat_main;
209 u8 log_level = SNAT_LOG_NONE;
210 clib_error_t *error = 0;
212 /* Get a line of input. */
213 if (!unformat_user (input, unformat_line_input, line_input))
216 if (!unformat (line_input, "%d", &log_level))
218 error = clib_error_return (0, "unknown input '%U'",
219 format_unformat_error, line_input);
222 if (log_level > SNAT_LOG_DEBUG)
224 error = clib_error_return (0, "unknown logging level '%d'", log_level);
227 sm->log_level = log_level;
230 unformat_free (line_input);
235 static clib_error_t *
236 snat_ipfix_logging_enable_disable_command_fn (vlib_main_t * vm,
237 unformat_input_t * input,
238 vlib_cli_command_t * cmd)
240 unformat_input_t _line_input, *line_input = &_line_input;
245 clib_error_t *error = 0;
247 /* Get a line of input. */
248 if (!unformat_user (input, unformat_line_input, line_input))
250 rv = nat_ipfix_logging_enable_disable (enable, domain_id,
253 return clib_error_return (0, "ipfix logging enable failed");
257 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
259 if (unformat (line_input, "domain %d", &domain_id))
261 else if (unformat (line_input, "src-port %d", &src_port))
263 else if (unformat (line_input, "disable"))
267 error = clib_error_return (0, "unknown input '%U'",
268 format_unformat_error, line_input);
273 rv = nat_ipfix_logging_enable_disable (enable, domain_id, (u16) src_port);
277 error = clib_error_return (0, "ipfix logging enable failed");
282 unformat_free (line_input);
287 static clib_error_t *
288 nat44_show_hash_command_fn (vlib_main_t * vm, unformat_input_t * input,
289 vlib_cli_command_t * cmd)
291 snat_main_t *sm = &snat_main;
292 snat_main_per_thread_data_t *tsm;
293 nat_affinity_main_t *nam = &nat_affinity_main;
297 if (unformat (input, "detail"))
299 else if (unformat (input, "verbose"))
302 vlib_cli_output (vm, "%U", format_bihash_8_8, &sm->static_mapping_by_local,
304 vlib_cli_output (vm, "%U",
305 format_bihash_8_8, &sm->static_mapping_by_external,
307 vlib_cli_output (vm, "%U", format_bihash_16_8, &sm->out2in_ed, verbose);
308 vec_foreach_index (i, sm->per_thread_data)
310 tsm = vec_elt_at_index (sm->per_thread_data, i);
311 vlib_cli_output (vm, "-------- thread %d %s --------\n",
312 i, vlib_worker_threads[i].name);
313 if (sm->endpoint_dependent)
315 vlib_cli_output (vm, "%U", format_bihash_16_8, &tsm->in2out_ed,
320 vlib_cli_output (vm, "%U", format_bihash_8_8, &tsm->in2out, verbose);
321 vlib_cli_output (vm, "%U", format_bihash_8_8, &tsm->out2in, verbose);
323 vlib_cli_output (vm, "%U", format_bihash_8_8, &tsm->user_hash, verbose);
326 if (sm->endpoint_dependent)
328 vlib_cli_output (vm, "%U", format_bihash_16_8, &nam->affinity_hash,
332 vlib_cli_output (vm, "-------- hash table parameters --------\n");
333 vlib_cli_output (vm, "translation buckets: %u", sm->translation_buckets);
334 vlib_cli_output (vm, "translation memory size: %U",
335 format_memory_size, sm->translation_memory_size);
336 if (!sm->endpoint_dependent)
338 vlib_cli_output (vm, "user buckets: %u", sm->user_buckets);
339 vlib_cli_output (vm, "user memory size: %U",
340 format_memory_size, sm->user_memory_size);
345 static clib_error_t *
346 nat44_set_alloc_addr_and_port_alg_command_fn (vlib_main_t * vm,
347 unformat_input_t * input,
348 vlib_cli_command_t * cmd)
350 unformat_input_t _line_input, *line_input = &_line_input;
351 clib_error_t *error = 0;
352 u32 psid, psid_offset, psid_length, port_start, port_end;
354 /* Get a line of input. */
355 if (!unformat_user (input, unformat_line_input, line_input))
358 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
360 if (unformat (line_input, "default"))
361 nat_set_alloc_addr_and_port_default ();
364 (line_input, "map-e psid %d psid-offset %d psid-len %d", &psid,
365 &psid_offset, &psid_length))
366 nat_set_alloc_addr_and_port_mape ((u16) psid, (u16) psid_offset,
370 (line_input, "port-range %d - %d", &port_start, &port_end))
372 if (port_end <= port_start)
375 clib_error_return (0,
376 "The end-port must be greater than start-port");
379 nat_set_alloc_addr_and_port_range ((u16) port_start,
384 error = clib_error_return (0, "unknown input '%U'",
385 format_unformat_error, line_input);
391 unformat_free (line_input);
396 static clib_error_t *
397 nat44_show_alloc_addr_and_port_alg_command_fn (vlib_main_t * vm,
398 unformat_input_t * input,
399 vlib_cli_command_t * cmd)
401 snat_main_t *sm = &snat_main;
403 vlib_cli_output (vm, "NAT address and port: %U",
404 format_nat_addr_and_port_alloc_alg,
405 sm->addr_and_port_alloc_alg);
406 switch (sm->addr_and_port_alloc_alg)
408 case NAT_ADDR_AND_PORT_ALLOC_ALG_MAPE:
409 vlib_cli_output (vm, " psid %d psid-offset %d psid-len %d", sm->psid,
410 sm->psid_offset, sm->psid_length);
412 case NAT_ADDR_AND_PORT_ALLOC_ALG_RANGE:
413 vlib_cli_output (vm, " start-port %d end-port %d", sm->start_port,
423 static clib_error_t *
424 nat_set_mss_clamping_command_fn (vlib_main_t * vm, unformat_input_t * input,
425 vlib_cli_command_t * cmd)
427 unformat_input_t _line_input, *line_input = &_line_input;
428 snat_main_t *sm = &snat_main;
429 clib_error_t *error = 0;
432 /* Get a line of input. */
433 if (!unformat_user (input, unformat_line_input, line_input))
436 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
438 if (unformat (line_input, "disable"))
439 sm->mss_clamping = 0;
440 else if (unformat (line_input, "%d", &mss))
441 sm->mss_clamping = (u16) mss;
444 error = clib_error_return (0, "unknown input '%U'",
445 format_unformat_error, line_input);
451 unformat_free (line_input);
456 static clib_error_t *
457 nat_show_mss_clamping_command_fn (vlib_main_t * vm, unformat_input_t * input,
458 vlib_cli_command_t * cmd)
460 snat_main_t *sm = &snat_main;
462 if (sm->mss_clamping)
463 vlib_cli_output (vm, "mss-clamping %d", sm->mss_clamping);
465 vlib_cli_output (vm, "mss-clamping disabled");
470 static clib_error_t *
471 nat_ha_failover_command_fn (vlib_main_t * vm, unformat_input_t * input,
472 vlib_cli_command_t * cmd)
474 unformat_input_t _line_input, *line_input = &_line_input;
476 u32 port, session_refresh_interval = 10;
478 clib_error_t *error = 0;
480 /* Get a line of input. */
481 if (!unformat_user (input, unformat_line_input, line_input))
484 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
486 if (unformat (line_input, "%U:%u", unformat_ip4_address, &addr, &port))
490 (line_input, "refresh-interval %u", &session_refresh_interval))
494 error = clib_error_return (0, "unknown input '%U'",
495 format_unformat_error, line_input);
500 rv = nat_ha_set_failover (&addr, (u16) port, session_refresh_interval);
502 error = clib_error_return (0, "set HA failover failed");
505 unformat_free (line_input);
510 static clib_error_t *
511 nat_ha_listener_command_fn (vlib_main_t * vm, unformat_input_t * input,
512 vlib_cli_command_t * cmd)
514 unformat_input_t _line_input, *line_input = &_line_input;
516 u32 port, path_mtu = 512;
518 clib_error_t *error = 0;
520 /* Get a line of input. */
521 if (!unformat_user (input, unformat_line_input, line_input))
524 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
526 if (unformat (line_input, "%U:%u", unformat_ip4_address, &addr, &port))
528 else if (unformat (line_input, "path-mtu %u", &path_mtu))
532 error = clib_error_return (0, "unknown input '%U'",
533 format_unformat_error, line_input);
538 rv = nat_ha_set_listener (&addr, (u16) port, path_mtu);
540 error = clib_error_return (0, "set HA listener failed");
543 unformat_free (line_input);
548 static clib_error_t *
549 nat_show_ha_command_fn (vlib_main_t * vm, unformat_input_t * input,
550 vlib_cli_command_t * cmd)
554 u32 path_mtu, session_refresh_interval, resync_ack_missed;
557 nat_ha_get_listener (&addr, &port, &path_mtu);
560 vlib_cli_output (vm, "NAT HA disabled\n");
564 vlib_cli_output (vm, "LISTENER:\n");
565 vlib_cli_output (vm, " %U:%u path-mtu %u\n",
566 format_ip4_address, &addr, port, path_mtu);
568 nat_ha_get_failover (&addr, &port, &session_refresh_interval);
569 vlib_cli_output (vm, "FAILOVER:\n");
571 vlib_cli_output (vm, " %U:%u refresh-interval %usec\n",
572 format_ip4_address, &addr, port,
573 session_refresh_interval);
575 vlib_cli_output (vm, " NA\n");
577 nat_ha_get_resync_status (&in_resync, &resync_ack_missed);
578 vlib_cli_output (vm, "RESYNC:\n");
580 vlib_cli_output (vm, " in progress\n");
582 vlib_cli_output (vm, " completed (%d ACK missed)\n", resync_ack_missed);
587 static clib_error_t *
588 nat_ha_flush_command_fn (vlib_main_t * vm, unformat_input_t * input,
589 vlib_cli_command_t * cmd)
595 static clib_error_t *
596 nat_ha_resync_command_fn (vlib_main_t * vm, unformat_input_t * input,
597 vlib_cli_command_t * cmd)
599 clib_error_t *error = 0;
601 if (nat_ha_resync (0, 0, 0))
602 error = clib_error_return (0, "NAT HA resync already running");
607 static clib_error_t *
608 add_address_command_fn (vlib_main_t * vm,
609 unformat_input_t * input, vlib_cli_command_t * cmd)
611 unformat_input_t _line_input, *line_input = &_line_input;
612 snat_main_t *sm = &snat_main;
613 ip4_address_t start_addr, end_addr, this_addr;
614 u32 start_host_order, end_host_order;
619 clib_error_t *error = 0;
622 /* Get a line of input. */
623 if (!unformat_user (input, unformat_line_input, line_input))
626 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
628 if (unformat (line_input, "%U - %U",
629 unformat_ip4_address, &start_addr,
630 unformat_ip4_address, &end_addr))
632 else if (unformat (line_input, "tenant-vrf %u", &vrf_id))
634 else if (unformat (line_input, "%U", unformat_ip4_address, &start_addr))
635 end_addr = start_addr;
636 else if (unformat (line_input, "twice-nat"))
638 else if (unformat (line_input, "del"))
642 error = clib_error_return (0, "unknown input '%U'",
643 format_unformat_error, line_input);
648 if (sm->static_mapping_only)
650 error = clib_error_return (0, "static mapping only mode");
654 start_host_order = clib_host_to_net_u32 (start_addr.as_u32);
655 end_host_order = clib_host_to_net_u32 (end_addr.as_u32);
657 if (end_host_order < start_host_order)
659 error = clib_error_return (0, "end address less than start address");
663 count = (end_host_order - start_host_order) + 1;
666 nat_log_info ("%U - %U, %d addresses...",
667 format_ip4_address, &start_addr,
668 format_ip4_address, &end_addr, count);
670 this_addr = start_addr;
672 for (i = 0; i < count; i++)
675 rv = snat_add_address (sm, &this_addr, vrf_id, twice_nat);
677 rv = snat_del_address (sm, this_addr, 0, twice_nat);
681 case VNET_API_ERROR_VALUE_EXIST:
682 error = clib_error_return (0, "NAT address already in use.");
684 case VNET_API_ERROR_NO_SUCH_ENTRY:
685 error = clib_error_return (0, "NAT address not exist.");
687 case VNET_API_ERROR_UNSPECIFIED:
689 clib_error_return (0, "NAT address used in static mapping.");
691 case VNET_API_ERROR_FEATURE_DISABLED:
693 clib_error_return (0,
694 "twice NAT available only for endpoint-dependent mode.");
701 nat44_add_del_address_dpo (this_addr, is_add);
703 increment_v4_address (&this_addr);
707 unformat_free (line_input);
713 nat44_show_lru_summary (vlib_main_t * vm, snat_main_per_thread_data_t * tsm,
714 u64 now, u64 sess_timeout_time)
716 snat_main_t *sm = &snat_main;
717 dlist_elt_t *oldest_elt;
723 clib_dlist_remove_head (tsm->lru_pool, tsm->n##_lru_head_index); \
724 if (~0 != oldest_index) \
726 oldest_elt = pool_elt_at_index (tsm->lru_pool, oldest_index); \
727 s = pool_elt_at_index (tsm->sessions, oldest_elt->value); \
728 sess_timeout_time = \
729 s->last_heard + (f64)nat44_session_get_timeout (sm, s); \
730 vlib_cli_output (vm, d " LRU min session timeout %llu (now %llu)", \
731 sess_timeout_time, now); \
732 clib_dlist_addhead (tsm->lru_pool, tsm->n##_lru_head_index, \
735 _(tcp_estab, "established tcp");
736 _(tcp_trans, "transitory tcp");
738 _(unk_proto, "unknown protocol");
743 static clib_error_t *
744 nat44_show_summary_command_fn (vlib_main_t * vm, unformat_input_t * input,
745 vlib_cli_command_t * cmd)
747 snat_main_per_thread_data_t *tsm;
748 snat_main_t *sm = &snat_main;
751 if (!sm->endpoint_dependent)
752 return clib_error_return (0, SUPPORTED_ONLY_IN_ED_MODE_STR);
756 u64 now = vlib_time_now (vm);
757 u64 sess_timeout_time;
759 u32 udp_sessions = 0;
760 u32 tcp_sessions = 0;
761 u32 icmp_sessions = 0;
765 u32 transitory_wait_closed = 0;
766 u32 transitory_closed = 0;
771 for (fib = 0; fib < vec_len (sm->max_translations_per_fib); fib++)
772 vlib_cli_output (vm, "max translations per thread: %u fib %u",
773 sm->max_translations_per_fib[fib], fib);
775 if (sm->num_workers > 1)
778 vec_foreach (tsm, sm->per_thread_data)
780 pool_foreach (s, tsm->sessions,
782 sess_timeout_time = s->last_heard +
783 (f64) nat44_session_get_timeout (sm, s);
784 if (now >= sess_timeout_time)
787 switch (s->nat_proto)
789 case NAT_PROTOCOL_ICMP:
792 case NAT_PROTOCOL_TCP:
796 if (s->tcp_closed_timestamp)
798 if (now >= s->tcp_closed_timestamp)
804 ++transitory_wait_closed;
812 case NAT_PROTOCOL_UDP:
818 nat44_show_lru_summary (vm, tsm, now, sess_timeout_time);
819 count += pool_elts (tsm->sessions);
825 tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
827 pool_foreach (s, tsm->sessions,
829 sess_timeout_time = s->last_heard +
830 (f64) nat44_session_get_timeout (sm, s);
831 if (now >= sess_timeout_time)
834 switch (s->nat_proto)
836 case NAT_PROTOCOL_ICMP:
839 case NAT_PROTOCOL_TCP:
843 if (s->tcp_closed_timestamp)
845 if (now >= s->tcp_closed_timestamp)
851 ++transitory_wait_closed;
859 case NAT_PROTOCOL_UDP:
866 nat44_show_lru_summary (vm, tsm, now, sess_timeout_time);
867 count = pool_elts (tsm->sessions);
870 vlib_cli_output (vm, "total timed out sessions: %u", timed_out);
871 vlib_cli_output (vm, "total sessions: %u", count);
872 vlib_cli_output (vm, "total tcp sessions: %u", tcp_sessions);
873 vlib_cli_output (vm, "total tcp established sessions: %u", established);
874 vlib_cli_output (vm, "total tcp transitory sessions: %u", transitory);
875 vlib_cli_output (vm, "total tcp transitory (WAIT-CLOSED) sessions: %u",
876 transitory_wait_closed);
877 vlib_cli_output (vm, "total tcp transitory (CLOSED) sessions: %u",
879 vlib_cli_output (vm, "total udp sessions: %u", udp_sessions);
880 vlib_cli_output (vm, "total icmp sessions: %u", icmp_sessions);
884 static clib_error_t *
885 nat44_show_addresses_command_fn (vlib_main_t * vm, unformat_input_t * input,
886 vlib_cli_command_t * cmd)
888 snat_main_t *sm = &snat_main;
891 vlib_cli_output (vm, "NAT44 pool addresses:");
893 vec_foreach (ap, sm->addresses)
895 vlib_cli_output (vm, "%U", format_ip4_address, &ap->addr);
896 if (ap->fib_index != ~0)
897 vlib_cli_output (vm, " tenant VRF: %u",
898 fib_table_get(ap->fib_index, FIB_PROTOCOL_IP4)->ft_table_id);
900 vlib_cli_output (vm, " tenant VRF independent");
901 #define _(N, i, n, s) \
902 vlib_cli_output (vm, " %d busy %s ports", ap->busy_##n##_ports, s);
906 vlib_cli_output (vm, "NAT44 twice-nat pool addresses:");
907 vec_foreach (ap, sm->twice_nat_addresses)
909 vlib_cli_output (vm, "%U", format_ip4_address, &ap->addr);
910 if (ap->fib_index != ~0)
911 vlib_cli_output (vm, " tenant VRF: %u",
912 fib_table_get(ap->fib_index, FIB_PROTOCOL_IP4)->ft_table_id);
914 vlib_cli_output (vm, " tenant VRF independent");
915 #define _(N, i, n, s) \
916 vlib_cli_output (vm, " %d busy %s ports", ap->busy_##n##_ports, s);
924 static clib_error_t *
925 snat_feature_command_fn (vlib_main_t * vm,
926 unformat_input_t * input, vlib_cli_command_t * cmd)
928 unformat_input_t _line_input, *line_input = &_line_input;
929 vnet_main_t *vnm = vnet_get_main ();
930 clib_error_t *error = 0;
932 u32 *inside_sw_if_indices = 0;
933 u32 *outside_sw_if_indices = 0;
934 u8 is_output_feature = 0;
940 /* Get a line of input. */
941 if (!unformat_user (input, unformat_line_input, line_input))
944 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
946 if (unformat (line_input, "in %U", unformat_vnet_sw_interface,
948 vec_add1 (inside_sw_if_indices, sw_if_index);
949 else if (unformat (line_input, "out %U", unformat_vnet_sw_interface,
951 vec_add1 (outside_sw_if_indices, sw_if_index);
952 else if (unformat (line_input, "output-feature"))
953 is_output_feature = 1;
954 else if (unformat (line_input, "del"))
958 error = clib_error_return (0, "unknown input '%U'",
959 format_unformat_error, line_input);
964 if (vec_len (inside_sw_if_indices))
966 for (i = 0; i < vec_len (inside_sw_if_indices); i++)
968 sw_if_index = inside_sw_if_indices[i];
969 if (is_output_feature)
971 if (snat_interface_add_del_output_feature
972 (sw_if_index, 1, is_del))
974 error = clib_error_return (0, "%s %U failed",
975 is_del ? "del" : "add",
976 format_vnet_sw_if_index_name,
983 if (snat_interface_add_del (sw_if_index, 1, is_del))
985 error = clib_error_return (0, "%s %U failed",
986 is_del ? "del" : "add",
987 format_vnet_sw_if_index_name,
995 if (vec_len (outside_sw_if_indices))
997 for (i = 0; i < vec_len (outside_sw_if_indices); i++)
999 sw_if_index = outside_sw_if_indices[i];
1000 if (is_output_feature)
1002 if (snat_interface_add_del_output_feature
1003 (sw_if_index, 0, is_del))
1005 error = clib_error_return (0, "%s %U failed",
1006 is_del ? "del" : "add",
1007 format_vnet_sw_if_index_name,
1014 if (snat_interface_add_del (sw_if_index, 0, is_del))
1016 error = clib_error_return (0, "%s %U failed",
1017 is_del ? "del" : "add",
1018 format_vnet_sw_if_index_name,
1027 unformat_free (line_input);
1028 vec_free (inside_sw_if_indices);
1029 vec_free (outside_sw_if_indices);
1034 static clib_error_t *
1035 nat44_show_interfaces_command_fn (vlib_main_t * vm, unformat_input_t * input,
1036 vlib_cli_command_t * cmd)
1038 snat_main_t *sm = &snat_main;
1039 snat_interface_t *i;
1040 vnet_main_t *vnm = vnet_get_main ();
1042 vlib_cli_output (vm, "NAT44 interfaces:");
1044 pool_foreach (i, sm->interfaces,
1046 vlib_cli_output (vm, " %U %s", format_vnet_sw_if_index_name, vnm,
1048 (nat_interface_is_inside(i) &&
1049 nat_interface_is_outside(i)) ? "in out" :
1050 (nat_interface_is_inside(i) ? "in" : "out"));
1053 pool_foreach (i, sm->output_feature_interfaces,
1055 vlib_cli_output (vm, " %U output-feature %s",
1056 format_vnet_sw_if_index_name, vnm,
1058 (nat_interface_is_inside(i) &&
1059 nat_interface_is_outside(i)) ? "in out" :
1060 (nat_interface_is_inside(i) ? "in" : "out"));
1067 static clib_error_t *
1068 add_static_mapping_command_fn (vlib_main_t * vm,
1069 unformat_input_t * input,
1070 vlib_cli_command_t * cmd)
1072 unformat_input_t _line_input, *line_input = &_line_input;
1073 clib_error_t *error = 0;
1074 ip4_address_t l_addr, e_addr, exact_addr;
1075 u32 l_port = 0, e_port = 0, vrf_id = ~0;
1076 int is_add = 1, addr_only = 1, rv, exact = 0;
1077 u32 sw_if_index = ~0;
1078 vnet_main_t *vnm = vnet_get_main ();
1079 nat_protocol_t proto = NAT_PROTOCOL_OTHER;
1081 twice_nat_type_t twice_nat = TWICE_NAT_DISABLED;
1084 /* Get a line of input. */
1085 if (!unformat_user (input, unformat_line_input, line_input))
1088 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1090 if (unformat (line_input, "local %U %u", unformat_ip4_address, &l_addr,
1094 if (unformat (line_input, "local %U", unformat_ip4_address, &l_addr))
1096 else if (unformat (line_input, "external %U %u", unformat_ip4_address,
1099 else if (unformat (line_input, "external %U", unformat_ip4_address,
1102 else if (unformat (line_input, "external %U %u",
1103 unformat_vnet_sw_interface, vnm, &sw_if_index,
1106 else if (unformat (line_input, "external %U",
1107 unformat_vnet_sw_interface, vnm, &sw_if_index))
1109 else if (unformat (line_input, "exact %U", unformat_ip4_address,
1112 else if (unformat (line_input, "vrf %u", &vrf_id))
1114 else if (unformat (line_input, "%U", unformat_nat_protocol, &proto))
1116 else if (unformat (line_input, "twice-nat"))
1117 twice_nat = TWICE_NAT;
1118 else if (unformat (line_input, "self-twice-nat"))
1119 twice_nat = TWICE_NAT_SELF;
1120 else if (unformat (line_input, "out2in-only"))
1122 else if (unformat (line_input, "del"))
1126 error = clib_error_return (0, "unknown input: '%U'",
1127 format_unformat_error, line_input);
1132 if (twice_nat && addr_only)
1134 error = clib_error_return (0, "twice NAT only for 1:1 NAPT");
1143 clib_error_return (0,
1144 "address only mapping doesn't support protocol");
1148 else if (!proto_set)
1150 error = clib_error_return (0, "protocol is required");
1154 rv = snat_add_static_mapping (l_addr, e_addr, clib_host_to_net_u16 (l_port),
1155 clib_host_to_net_u16 (e_port),
1156 vrf_id, addr_only, sw_if_index, proto, is_add,
1157 twice_nat, out2in_only, 0, 0, exact_addr,
1162 case VNET_API_ERROR_INVALID_VALUE:
1163 error = clib_error_return (0, "External port already in use.");
1165 case VNET_API_ERROR_NO_SUCH_ENTRY:
1167 error = clib_error_return (0, "External address must be allocated.");
1169 error = clib_error_return (0, "Mapping not exist.");
1171 case VNET_API_ERROR_NO_SUCH_FIB:
1172 error = clib_error_return (0, "No such VRF id.");
1174 case VNET_API_ERROR_VALUE_EXIST:
1175 error = clib_error_return (0, "Mapping already exist.");
1177 case VNET_API_ERROR_FEATURE_DISABLED:
1179 clib_error_return (0,
1180 "twice-nat/out2in-only available only for endpoint-dependent mode.");
1187 unformat_free (line_input);
1192 static clib_error_t *
1193 add_identity_mapping_command_fn (vlib_main_t * vm,
1194 unformat_input_t * input,
1195 vlib_cli_command_t * cmd)
1197 unformat_input_t _line_input, *line_input = &_line_input;
1198 clib_error_t *error = 0;
1199 ip4_address_t addr, pool_addr = { 0 };
1200 u32 port = 0, vrf_id = ~0;
1203 u32 sw_if_index = ~0;
1204 vnet_main_t *vnm = vnet_get_main ();
1206 nat_protocol_t proto;
1210 /* Get a line of input. */
1211 if (!unformat_user (input, unformat_line_input, line_input))
1214 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1216 if (unformat (line_input, "%U", unformat_ip4_address, &addr))
1218 else if (unformat (line_input, "external %U",
1219 unformat_vnet_sw_interface, vnm, &sw_if_index))
1221 else if (unformat (line_input, "vrf %u", &vrf_id))
1223 else if (unformat (line_input, "%U %u", unformat_nat_protocol, &proto,
1226 else if (unformat (line_input, "del"))
1230 error = clib_error_return (0, "unknown input: '%U'",
1231 format_unformat_error, line_input);
1237 snat_add_static_mapping (addr, addr, clib_host_to_net_u16 (port),
1238 clib_host_to_net_u16 (port), vrf_id, addr_only,
1239 sw_if_index, proto, is_add, 0, 0, 0, 1,
1244 case VNET_API_ERROR_INVALID_VALUE:
1245 error = clib_error_return (0, "External port already in use.");
1247 case VNET_API_ERROR_NO_SUCH_ENTRY:
1249 error = clib_error_return (0, "External address must be allocated.");
1251 error = clib_error_return (0, "Mapping not exist.");
1253 case VNET_API_ERROR_NO_SUCH_FIB:
1254 error = clib_error_return (0, "No such VRF id.");
1256 case VNET_API_ERROR_VALUE_EXIST:
1257 error = clib_error_return (0, "Mapping already exist.");
1264 unformat_free (line_input);
1269 static clib_error_t *
1270 add_lb_static_mapping_command_fn (vlib_main_t * vm,
1271 unformat_input_t * input,
1272 vlib_cli_command_t * cmd)
1274 unformat_input_t _line_input, *line_input = &_line_input;
1275 clib_error_t *error = 0;
1276 ip4_address_t l_addr, e_addr;
1277 u32 l_port = 0, e_port = 0, vrf_id = 0, probability = 0, affinity = 0;
1280 nat_protocol_t proto;
1282 nat44_lb_addr_port_t *locals = 0, local;
1283 twice_nat_type_t twice_nat = TWICE_NAT_DISABLED;
1286 /* Get a line of input. */
1287 if (!unformat_user (input, unformat_line_input, line_input))
1290 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1292 if (unformat (line_input, "local %U:%u probability %u",
1293 unformat_ip4_address, &l_addr, &l_port, &probability))
1295 clib_memset (&local, 0, sizeof (local));
1296 local.addr = l_addr;
1297 local.port = (u16) l_port;
1298 local.probability = (u8) probability;
1299 vec_add1 (locals, local);
1301 else if (unformat (line_input, "local %U:%u vrf %u probability %u",
1302 unformat_ip4_address, &l_addr, &l_port, &vrf_id,
1305 clib_memset (&local, 0, sizeof (local));
1306 local.addr = l_addr;
1307 local.port = (u16) l_port;
1308 local.probability = (u8) probability;
1309 local.vrf_id = vrf_id;
1310 vec_add1 (locals, local);
1312 else if (unformat (line_input, "external %U:%u", unformat_ip4_address,
1315 else if (unformat (line_input, "protocol %U", unformat_nat_protocol,
1318 else if (unformat (line_input, "twice-nat"))
1319 twice_nat = TWICE_NAT;
1320 else if (unformat (line_input, "self-twice-nat"))
1321 twice_nat = TWICE_NAT_SELF;
1322 else if (unformat (line_input, "out2in-only"))
1324 else if (unformat (line_input, "del"))
1326 else if (unformat (line_input, "affinity %u", &affinity))
1330 error = clib_error_return (0, "unknown input: '%U'",
1331 format_unformat_error, line_input);
1336 if (vec_len (locals) < 2)
1338 error = clib_error_return (0, "at least two local must be set");
1344 error = clib_error_return (0, "missing protocol");
1348 rv = nat44_add_del_lb_static_mapping (e_addr, (u16) e_port, proto, locals,
1349 is_add, twice_nat, out2in_only, 0,
1354 case VNET_API_ERROR_INVALID_VALUE:
1355 error = clib_error_return (0, "External port already in use.");
1357 case VNET_API_ERROR_NO_SUCH_ENTRY:
1359 error = clib_error_return (0, "External address must be allocated.");
1361 error = clib_error_return (0, "Mapping not exist.");
1363 case VNET_API_ERROR_VALUE_EXIST:
1364 error = clib_error_return (0, "Mapping already exist.");
1366 case VNET_API_ERROR_FEATURE_DISABLED:
1368 clib_error_return (0, "Available only for endpoint-dependent mode.");
1375 unformat_free (line_input);
1381 static clib_error_t *
1382 add_lb_backend_command_fn (vlib_main_t * vm,
1383 unformat_input_t * input, vlib_cli_command_t * cmd)
1385 unformat_input_t _line_input, *line_input = &_line_input;
1386 clib_error_t *error = 0;
1387 ip4_address_t l_addr, e_addr;
1388 u32 l_port = 0, e_port = 0, vrf_id = 0, probability = 0;
1391 nat_protocol_t proto;
1394 /* Get a line of input. */
1395 if (!unformat_user (input, unformat_line_input, line_input))
1398 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1400 if (unformat (line_input, "local %U:%u probability %u",
1401 unformat_ip4_address, &l_addr, &l_port, &probability))
1403 else if (unformat (line_input, "local %U:%u vrf %u probability %u",
1404 unformat_ip4_address, &l_addr, &l_port, &vrf_id,
1407 else if (unformat (line_input, "external %U:%u", unformat_ip4_address,
1410 else if (unformat (line_input, "protocol %U", unformat_nat_protocol,
1413 else if (unformat (line_input, "del"))
1417 error = clib_error_return (0, "unknown input: '%U'",
1418 format_unformat_error, line_input);
1423 if (!l_port || !e_port)
1425 error = clib_error_return (0, "local or external must be set");
1431 error = clib_error_return (0, "missing protocol");
1436 nat44_lb_static_mapping_add_del_local (e_addr, (u16) e_port, l_addr,
1437 l_port, proto, vrf_id, probability,
1442 case VNET_API_ERROR_INVALID_VALUE:
1443 error = clib_error_return (0, "External is not load-balancing static "
1446 case VNET_API_ERROR_NO_SUCH_ENTRY:
1447 error = clib_error_return (0, "Mapping or back-end not exist.");
1449 case VNET_API_ERROR_VALUE_EXIST:
1450 error = clib_error_return (0, "Back-end already exist.");
1452 case VNET_API_ERROR_FEATURE_DISABLED:
1454 clib_error_return (0, "Available only for endpoint-dependent mode.");
1456 case VNET_API_ERROR_UNSPECIFIED:
1457 error = clib_error_return (0, "At least two back-ends must remain");
1464 unformat_free (line_input);
1469 static clib_error_t *
1470 nat44_show_static_mappings_command_fn (vlib_main_t * vm,
1471 unformat_input_t * input,
1472 vlib_cli_command_t * cmd)
1474 snat_main_t *sm = &snat_main;
1475 snat_static_mapping_t *m;
1476 snat_static_map_resolve_t *rp;
1478 vlib_cli_output (vm, "NAT44 static mappings:");
1480 pool_foreach (m, sm->static_mappings,
1482 vlib_cli_output (vm, " %U", format_snat_static_mapping, m);
1484 vec_foreach (rp, sm->to_resolve)
1485 vlib_cli_output (vm, " %U", format_snat_static_map_to_resolve, rp);
1491 static clib_error_t *
1492 snat_add_interface_address_command_fn (vlib_main_t * vm,
1493 unformat_input_t * input,
1494 vlib_cli_command_t * cmd)
1496 snat_main_t *sm = &snat_main;
1497 unformat_input_t _line_input, *line_input = &_line_input;
1501 clib_error_t *error = 0;
1504 /* Get a line of input. */
1505 if (!unformat_user (input, unformat_line_input, line_input))
1508 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1510 if (unformat (line_input, "%U", unformat_vnet_sw_interface,
1511 sm->vnet_main, &sw_if_index))
1513 else if (unformat (line_input, "twice-nat"))
1515 else if (unformat (line_input, "del"))
1519 error = clib_error_return (0, "unknown input '%U'",
1520 format_unformat_error, line_input);
1525 rv = snat_add_interface_address (sm, sw_if_index, is_del, twice_nat);
1533 error = clib_error_return (0, "snat_add_interface_address returned %d",
1539 unformat_free (line_input);
1544 static clib_error_t *
1545 nat44_show_interface_address_command_fn (vlib_main_t * vm,
1546 unformat_input_t * input,
1547 vlib_cli_command_t * cmd)
1549 snat_main_t *sm = &snat_main;
1550 vnet_main_t *vnm = vnet_get_main ();
1554 vlib_cli_output (vm, "NAT44 pool address interfaces:");
1555 vec_foreach (sw_if_index, sm->auto_add_sw_if_indices)
1557 vlib_cli_output (vm, " %U", format_vnet_sw_if_index_name, vnm,
1560 vlib_cli_output (vm, "NAT44 twice-nat pool address interfaces:");
1561 vec_foreach (sw_if_index, sm->auto_add_sw_if_indices_twice_nat)
1563 vlib_cli_output (vm, " %U", format_vnet_sw_if_index_name, vnm,
1571 static clib_error_t *
1572 nat44_show_sessions_command_fn (vlib_main_t * vm, unformat_input_t * input,
1573 vlib_cli_command_t * cmd)
1575 unformat_input_t _line_input, *line_input = &_line_input;
1576 clib_error_t *error = 0;
1578 snat_main_per_thread_data_t *tsm;
1579 snat_main_t *sm = &snat_main;
1584 if (!unformat_user (input, unformat_line_input, line_input))
1587 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1589 if (unformat (line_input, "detail"))
1593 error = clib_error_return (0, "unknown input '%U'",
1594 format_unformat_error, line_input);
1598 unformat_free (line_input);
1601 if (!sm->endpoint_dependent)
1602 vlib_cli_output (vm, "NAT44 sessions:");
1604 vlib_cli_output (vm, "NAT44 ED sessions:");
1607 vec_foreach_index (i, sm->per_thread_data)
1609 tsm = vec_elt_at_index (sm->per_thread_data, i);
1611 vlib_cli_output (vm, "-------- thread %d %s: %d sessions --------\n",
1612 i, vlib_worker_threads[i].name,
1613 pool_elts (tsm->sessions));
1615 if (!sm->endpoint_dependent)
1618 pool_foreach (u, tsm->users,
1620 vlib_cli_output (vm, " %U", format_snat_user, tsm, u, detail);
1626 pool_foreach (s, tsm->sessions,
1628 vlib_cli_output (vm, " %U\n", format_snat_session, tsm, s);
1636 static clib_error_t *
1637 nat44_set_session_limit_command_fn (vlib_main_t * vm,
1638 unformat_input_t * input,
1639 vlib_cli_command_t * cmd)
1641 unformat_input_t _line_input, *line_input = &_line_input;
1642 clib_error_t *error = 0;
1644 u32 session_limit = 0, vrf_id = 0;
1646 /* Get a line of input. */
1647 if (!unformat_user (input, unformat_line_input, line_input))
1650 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1652 if (unformat (line_input, "%u", &session_limit))
1654 else if (unformat (line_input, "vrf %u", &vrf_id))
1658 error = clib_error_return (0, "unknown input '%U'",
1659 format_unformat_error, line_input);
1665 error = clib_error_return (0, "missing value of session limit");
1666 else if (nat44_update_session_limit (session_limit, vrf_id))
1667 error = clib_error_return (0, "nat44_set_session_limit failed");
1670 unformat_free (line_input);
1675 static clib_error_t *
1676 nat44_del_user_command_fn (vlib_main_t * vm,
1677 unformat_input_t * input, vlib_cli_command_t * cmd)
1679 snat_main_t *sm = &snat_main;
1680 unformat_input_t _line_input, *line_input = &_line_input;
1681 clib_error_t *error = 0;
1686 if (sm->endpoint_dependent)
1687 return clib_error_return (0, UNSUPPORTED_IN_ED_MODE_STR);
1689 /* Get a line of input. */
1690 if (!unformat_user (input, unformat_line_input, line_input))
1693 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1695 if (unformat (line_input, "%U", unformat_ip4_address, &addr))
1697 else if (unformat (line_input, "fib %u", &fib_index))
1701 error = clib_error_return (0, "unknown input '%U'",
1702 format_unformat_error, line_input);
1707 rv = nat44_user_del (&addr, fib_index);
1711 error = clib_error_return (0, "nat44_user_del returned %d", rv);
1715 unformat_free (line_input);
1720 static clib_error_t *
1721 nat44_clear_sessions_command_fn (vlib_main_t * vm,
1722 unformat_input_t * input,
1723 vlib_cli_command_t * cmd)
1725 clib_error_t *error = 0;
1726 nat44_sessions_clear ();
1730 static clib_error_t *
1731 nat44_del_session_command_fn (vlib_main_t * vm,
1732 unformat_input_t * input,
1733 vlib_cli_command_t * cmd)
1735 snat_main_t *sm = &snat_main;
1736 unformat_input_t _line_input, *line_input = &_line_input;
1737 int is_in = 0, is_ed = 0;
1738 clib_error_t *error = 0;
1739 ip4_address_t addr, eh_addr;
1740 u32 port = 0, eh_port = 0, vrf_id = sm->outside_vrf_id;
1741 nat_protocol_t proto;
1744 /* Get a line of input. */
1745 if (!unformat_user (input, unformat_line_input, line_input))
1748 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1751 (line_input, "%U:%u %U", unformat_ip4_address, &addr, &port,
1752 unformat_nat_protocol, &proto))
1754 else if (unformat (line_input, "in"))
1757 vrf_id = sm->inside_vrf_id;
1759 else if (unformat (line_input, "out"))
1762 vrf_id = sm->outside_vrf_id;
1764 else if (unformat (line_input, "vrf %u", &vrf_id))
1768 (line_input, "external-host %U:%u", unformat_ip4_address,
1769 &eh_addr, &eh_port))
1773 error = clib_error_return (0, "unknown input '%U'",
1774 format_unformat_error, line_input);
1781 nat44_del_ed_session (sm, &addr, clib_host_to_net_u16 (port), &eh_addr,
1782 clib_host_to_net_u16 (eh_port),
1783 nat_proto_to_ip_proto (proto), vrf_id, is_in);
1786 nat44_del_session (sm, &addr, clib_host_to_net_u16 (port), proto,
1795 error = clib_error_return (0, "nat44_del_session returned %d", rv);
1800 unformat_free (line_input);
1805 static clib_error_t *
1806 snat_forwarding_set_command_fn (vlib_main_t * vm,
1807 unformat_input_t * input,
1808 vlib_cli_command_t * cmd)
1810 snat_main_t *sm = &snat_main;
1811 unformat_input_t _line_input, *line_input = &_line_input;
1812 u8 forwarding_enable;
1813 u8 forwarding_enable_set = 0;
1814 clib_error_t *error = 0;
1816 /* Get a line of input. */
1817 if (!unformat_user (input, unformat_line_input, line_input))
1818 return clib_error_return (0, "'enable' or 'disable' expected");
1820 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1822 if (!forwarding_enable_set && unformat (line_input, "enable"))
1824 forwarding_enable = 1;
1825 forwarding_enable_set = 1;
1827 else if (!forwarding_enable_set && unformat (line_input, "disable"))
1829 forwarding_enable = 0;
1830 forwarding_enable_set = 1;
1834 error = clib_error_return (0, "unknown input '%U'",
1835 format_unformat_error, line_input);
1840 if (!forwarding_enable_set)
1842 error = clib_error_return (0, "'enable' or 'disable' expected");
1846 sm->forwarding_enabled = forwarding_enable;
1849 unformat_free (line_input);
1854 static clib_error_t *
1855 set_timeout_command_fn (vlib_main_t * vm,
1856 unformat_input_t * input, vlib_cli_command_t * cmd)
1858 snat_main_t *sm = &snat_main;
1859 unformat_input_t _line_input, *line_input = &_line_input;
1860 clib_error_t *error = 0;
1862 /* Get a line of input. */
1863 if (!unformat_user (input, unformat_line_input, line_input))
1866 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1868 if (unformat (line_input, "udp %u", &sm->udp_timeout));
1869 else if (unformat (line_input, "tcp-established %u",
1870 &sm->tcp_established_timeout));
1871 else if (unformat (line_input, "tcp-transitory %u",
1872 &sm->tcp_transitory_timeout));
1873 else if (unformat (line_input, "icmp %u", &sm->icmp_timeout));
1874 else if (unformat (line_input, "reset"))
1876 sm->udp_timeout = SNAT_UDP_TIMEOUT;
1877 sm->tcp_established_timeout = SNAT_TCP_ESTABLISHED_TIMEOUT;
1878 sm->tcp_transitory_timeout = SNAT_TCP_TRANSITORY_TIMEOUT;
1879 sm->icmp_timeout = SNAT_ICMP_TIMEOUT;
1883 error = clib_error_return (0, "unknown input '%U'",
1884 format_unformat_error, line_input);
1889 unformat_free (line_input);
1893 static clib_error_t *
1894 nat_show_timeouts_command_fn (vlib_main_t * vm,
1895 unformat_input_t * input,
1896 vlib_cli_command_t * cmd)
1898 snat_main_t *sm = &snat_main;
1900 vlib_cli_output (vm, "udp timeout: %dsec", sm->udp_timeout);
1901 vlib_cli_output (vm, "tcp-established timeout: %dsec",
1902 sm->tcp_established_timeout);
1903 vlib_cli_output (vm, "tcp-transitory timeout: %dsec",
1904 sm->tcp_transitory_timeout);
1905 vlib_cli_output (vm, "icmp timeout: %dsec", sm->icmp_timeout);
1910 static clib_error_t *
1911 nat44_debug_fib_expire_command_fn (vlib_main_t * vm,
1912 unformat_input_t * input,
1913 vlib_cli_command_t * cmd)
1915 unformat_input_t _line_input, *line_input = &_line_input;
1916 clib_error_t *error = 0;
1919 /* Get a line of input. */
1920 if (!unformat_user (input, unformat_line_input, line_input))
1923 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1925 if (unformat (line_input, "%u", &fib))
1929 error = clib_error_return (0, "unknown input '%U'",
1930 format_unformat_error, line_input);
1934 expire_per_vrf_sessions (fib);
1936 unformat_free (line_input);
1940 static clib_error_t *
1941 nat44_debug_fib_registration_command_fn (vlib_main_t * vm,
1942 unformat_input_t * input,
1943 vlib_cli_command_t * cmd)
1945 snat_main_t *sm = &snat_main;
1946 snat_main_per_thread_data_t *tsm;
1947 per_vrf_sessions_t *per_vrf_sessions;
1949 vlib_cli_output (vm, "VRF registration debug:");
1950 vec_foreach (tsm, sm->per_thread_data)
1952 vlib_cli_output (vm, "thread %u:", tsm->thread_index);
1953 vec_foreach (per_vrf_sessions, tsm->per_vrf_sessions_vec)
1955 vlib_cli_output (vm, "rx fib %u tx fib %u ses count %u %s",
1956 per_vrf_sessions->rx_fib_index,
1957 per_vrf_sessions->tx_fib_index,
1958 per_vrf_sessions->ses_count,
1959 per_vrf_sessions->expired ? "expired" : "");
1969 VLIB_CLI_COMMAND (nat44_debug_fib_expire_command, static) = {
1970 .path = "debug nat44 fib expire",
1971 .short_help = "debug nat44 fib expire <fib-index>",
1972 .function = nat44_debug_fib_expire_command_fn,
1977 VLIB_CLI_COMMAND (nat44_debug_fib_registration_command, static) = {
1978 .path = "debug nat44 fib registration",
1979 .short_help = "debug nat44 fib registration",
1980 .function = nat44_debug_fib_registration_command_fn,
1985 * @cliexstart{nat44 enable}
1986 * Enable nat44 plugin
1987 * To enable nat44, use:
1988 * vpp# nat44 enable sessions <n>
1989 * To enable nat44 static mapping only, use:
1990 * vpp# nat44 enable sessions <n> static-mapping
1991 * To enable nat44 static mapping with connection tracking, use:
1992 * vpp# nat44 enable sessions <n> static-mapping connection-tracking
1993 * To enable nat44 out2in dpo, use:
1994 * vpp# nat44 enable sessions <n> out2in-dpo
1995 * To enable nat44 endpoint-dependent, use:
1996 * vpp# nat44 enable sessions <n> endpoint-dependent
1997 * To overwrite user hash configuration, use:
1998 * vpp# nat44 enable sessions <n> user-memory <n>
1999 * To overwrite session hash configuration, use:
2000 * vpp# nat44 enable session-memory <n>
2001 * To set inside-vrf outside-vrf, use:
2002 * vpp# nat44 enable sessions <n> inside-vrf <id> outside-vrf <id>
2005 VLIB_CLI_COMMAND (nat44_enable_command, static) = {
2006 .path = "nat44 enable",
2007 .short_help = "nat44 enable sessions <max-number> [users <max-number>] [static-mappig-only [connection-tracking]|out2in-dpo|endpoint-dependent] [inside-vrf <vrf-id>] [outside-vrf <vrf-id>] [user-memory <number>] [session-memory <number>] [user-sessions <max-number>]",
2008 .function = nat44_enable_command_fn,
2013 * @cliexstart{nat44 disable}
2014 * Disable nat44 plugin
2015 * To disable nat44, use:
2016 * vpp# nat44 disable
2019 VLIB_CLI_COMMAND (nat44_disable_command, static) = {
2020 .path = "nat44 disable",
2021 .short_help = "nat44 disable",
2022 .function = nat44_disable_command_fn,
2027 * @cliexstart{set snat workers}
2028 * Set NAT workers if 2 or more workers available, use:
2029 * vpp# set snat workers 0-2,5
2032 VLIB_CLI_COMMAND (set_workers_command, static) = {
2033 .path = "set nat workers",
2034 .function = set_workers_command_fn,
2035 .short_help = "set nat workers <workers-list>",
2040 * @cliexstart{show nat workers}
2042 * vpp# show nat workers:
2048 VLIB_CLI_COMMAND (nat_show_workers_command, static) = {
2049 .path = "show nat workers",
2050 .short_help = "show nat workers",
2051 .function = nat_show_workers_commnad_fn,
2056 * @cliexstart{set nat timeout}
2057 * Set values of timeouts for NAT sessions (in seconds), use:
2058 * vpp# set nat timeout udp 120 tcp-established 7500 tcp-transitory 250 icmp 90
2059 * To reset default values use:
2060 * vpp# set nat timeout reset
2063 VLIB_CLI_COMMAND (set_timeout_command, static) = {
2064 .path = "set nat timeout",
2065 .function = set_timeout_command_fn,
2067 "set nat timeout [udp <sec> | tcp-established <sec> "
2068 "tcp-transitory <sec> | icmp <sec> | reset]",
2073 * @cliexstart{show nat timeouts}
2074 * Show values of timeouts for NAT sessions.
2075 * vpp# show nat timeouts
2076 * udp timeout: 300sec
2077 * tcp-established timeout: 7440sec
2078 * tcp-transitory timeout: 240sec
2079 * icmp timeout: 60sec
2082 VLIB_CLI_COMMAND (nat_show_timeouts_command, static) = {
2083 .path = "show nat timeouts",
2084 .short_help = "show nat timeouts",
2085 .function = nat_show_timeouts_command_fn,
2090 * @cliexstart{nat set logging level}
2091 * To set NAT logging level use:
2092 * Set nat logging level
2095 VLIB_CLI_COMMAND (snat_set_log_level_command, static) = {
2096 .path = "nat set logging level",
2097 .function = snat_set_log_level_command_fn,
2098 .short_help = "nat set logging level <level>",
2103 * @cliexstart{snat ipfix logging}
2104 * To enable NAT IPFIX logging use:
2105 * vpp# nat ipfix logging
2106 * To set IPFIX exporter use:
2107 * vpp# set ipfix exporter collector 10.10.10.3 src 10.10.10.1
2110 VLIB_CLI_COMMAND (snat_ipfix_logging_enable_disable_command, static) = {
2111 .path = "nat ipfix logging",
2112 .function = snat_ipfix_logging_enable_disable_command_fn,
2113 .short_help = "nat ipfix logging [domain <domain-id>] [src-port <port>] [disable]",
2118 * @cliexstart{nat addr-port-assignment-alg}
2119 * Set address and port assignment algorithm
2120 * For the MAP-E CE limit port choice based on PSID use:
2121 * vpp# nat addr-port-assignment-alg map-e psid 10 psid-offset 6 psid-len 6
2122 * For port range use:
2123 * vpp# nat addr-port-assignment-alg port-range <start-port> - <end-port>
2124 * To set standard (default) address and port assignment algorithm use:
2125 * vpp# nat addr-port-assignment-alg default
2128 VLIB_CLI_COMMAND (nat44_set_alloc_addr_and_port_alg_command, static) = {
2129 .path = "nat addr-port-assignment-alg",
2130 .short_help = "nat addr-port-assignment-alg <alg-name> [<alg-params>]",
2131 .function = nat44_set_alloc_addr_and_port_alg_command_fn,
2136 * @cliexstart{show nat addr-port-assignment-alg}
2137 * Show address and port assignment algorithm
2140 VLIB_CLI_COMMAND (nat44_show_alloc_addr_and_port_alg_command, static) = {
2141 .path = "show nat addr-port-assignment-alg",
2142 .short_help = "show nat addr-port-assignment-alg",
2143 .function = nat44_show_alloc_addr_and_port_alg_command_fn,
2148 * @cliexstart{nat mss-clamping}
2149 * Set TCP MSS rewriting configuration
2150 * To enable TCP MSS rewriting use:
2151 * vpp# nat mss-clamping 1452
2152 * To disbale TCP MSS rewriting use:
2153 * vpp# nat mss-clamping disable
2156 VLIB_CLI_COMMAND (nat_set_mss_clamping_command, static) = {
2157 .path = "nat mss-clamping",
2158 .short_help = "nat mss-clamping <mss-value>|disable",
2159 .function = nat_set_mss_clamping_command_fn,
2164 * @cliexstart{show nat mss-clamping}
2165 * Show TCP MSS rewriting configuration
2168 VLIB_CLI_COMMAND (nat_show_mss_clamping_command, static) = {
2169 .path = "show nat mss-clamping",
2170 .short_help = "show nat mss-clamping",
2171 .function = nat_show_mss_clamping_command_fn,
2176 * @cliexstart{nat ha failover}
2177 * Set HA failover (remote settings)
2180 VLIB_CLI_COMMAND (nat_ha_failover_command, static) = {
2181 .path = "nat ha failover",
2182 .short_help = "nat ha failover <ip4-address>:<port> [refresh-interval <sec>]",
2183 .function = nat_ha_failover_command_fn,
2188 * @cliexstart{nat ha listener}
2189 * Set HA listener (local settings)
2192 VLIB_CLI_COMMAND (nat_ha_listener_command, static) = {
2193 .path = "nat ha listener",
2194 .short_help = "nat ha listener <ip4-address>:<port> [path-mtu <path-mtu>]",
2195 .function = nat_ha_listener_command_fn,
2200 * @cliexstart{show nat ha}
2201 * Show HA configuration/status
2204 VLIB_CLI_COMMAND (nat_show_ha_command, static) = {
2205 .path = "show nat ha",
2206 .short_help = "show nat ha",
2207 .function = nat_show_ha_command_fn,
2212 * @cliexstart{nat ha flush}
2213 * Flush the current HA data (for testing)
2216 VLIB_CLI_COMMAND (nat_ha_flush_command, static) = {
2217 .path = "nat ha flush",
2218 .short_help = "nat ha flush",
2219 .function = nat_ha_flush_command_fn,
2224 * @cliexstart{nat ha resync}
2225 * Resync HA (resend existing sessions to new failover)
2228 VLIB_CLI_COMMAND (nat_ha_resync_command, static) = {
2229 .path = "nat ha resync",
2230 .short_help = "nat ha resync",
2231 .function = nat_ha_resync_command_fn,
2236 * @cliexstart{show nat44 hash tables}
2237 * Show NAT44 hash tables
2240 VLIB_CLI_COMMAND (nat44_show_hash, static) = {
2241 .path = "show nat44 hash tables",
2242 .short_help = "show nat44 hash tables [detail|verbose]",
2243 .function = nat44_show_hash_command_fn,
2248 * @cliexstart{nat44 add address}
2249 * Add/delete NAT44 pool address.
2250 * To add NAT44 pool address use:
2251 * vpp# nat44 add address 172.16.1.3
2252 * vpp# nat44 add address 172.16.2.2 - 172.16.2.24
2253 * To add NAT44 pool address for specific tenant (identified by VRF id) use:
2254 * vpp# nat44 add address 172.16.1.3 tenant-vrf 10
2257 VLIB_CLI_COMMAND (add_address_command, static) = {
2258 .path = "nat44 add address",
2259 .short_help = "nat44 add address <ip4-range-start> [- <ip4-range-end>] "
2260 "[tenant-vrf <vrf-id>] [twice-nat] [del]",
2261 .function = add_address_command_fn,
2266 * @cliexstart{show nat44 summary}
2267 * Show NAT44 summary
2268 * vpp# show nat44 summary
2271 VLIB_CLI_COMMAND (nat44_show_summary_command, static) = {
2272 .path = "show nat44 summary",
2273 .short_help = "show nat44 summary",
2274 .function = nat44_show_summary_command_fn,
2279 * @cliexstart{show nat44 addresses}
2280 * Show NAT44 pool addresses.
2281 * vpp# show nat44 addresses
2282 * NAT44 pool addresses:
2284 * tenant VRF independent
2293 * NAT44 twice-nat pool addresses:
2295 * tenant VRF independent
2301 VLIB_CLI_COMMAND (nat44_show_addresses_command, static) = {
2302 .path = "show nat44 addresses",
2303 .short_help = "show nat44 addresses",
2304 .function = nat44_show_addresses_command_fn,
2309 * @cliexstart{set interface nat44}
2310 * Enable/disable NAT44 feature on the interface.
2311 * To enable NAT44 feature with local network interface use:
2312 * vpp# set interface nat44 in GigabitEthernet0/8/0
2313 * To enable NAT44 feature with external network interface use:
2314 * vpp# set interface nat44 out GigabitEthernet0/a/0
2317 VLIB_CLI_COMMAND (set_interface_snat_command, static) = {
2318 .path = "set interface nat44",
2319 .function = snat_feature_command_fn,
2320 .short_help = "set interface nat44 in <intfc> out <intfc> [output-feature] "
2326 * @cliexstart{show nat44 interfaces}
2327 * Show interfaces with NAT44 feature.
2328 * vpp# show nat44 interfaces
2330 * GigabitEthernet0/8/0 in
2331 * GigabitEthernet0/a/0 out
2334 VLIB_CLI_COMMAND (nat44_show_interfaces_command, static) = {
2335 .path = "show nat44 interfaces",
2336 .short_help = "show nat44 interfaces",
2337 .function = nat44_show_interfaces_command_fn,
2342 * @cliexstart{nat44 add static mapping}
2343 * Static mapping allows hosts on the external network to initiate connection
2344 * to to the local network host.
2345 * To create static mapping between local host address 10.0.0.3 port 6303 and
2346 * external address 4.4.4.4 port 3606 for TCP protocol use:
2347 * vpp# nat44 add static mapping tcp local 10.0.0.3 6303 external 4.4.4.4 3606
2348 * If not runnig "static mapping only" NAT plugin mode use before:
2349 * vpp# nat44 add address 4.4.4.4
2350 * To create address only static mapping between local and external address use:
2351 * vpp# nat44 add static mapping local 10.0.0.3 external 4.4.4.4
2352 * To create ICMP static mapping between local and external with ICMP echo
2353 * identifier 10 use:
2354 * vpp# nat44 add static mapping icmp local 10.0.0.3 10 external 4.4.4.4 10
2355 * To force use of specific pool address, vrf independent
2356 * vpp# nat44 add static mapping local 10.0.0.2 1234 external 10.0.2.2 1234 twice-nat exact 10.0.1.2
2359 VLIB_CLI_COMMAND (add_static_mapping_command, static) = {
2360 .path = "nat44 add static mapping",
2361 .function = add_static_mapping_command_fn,
2363 "nat44 add static mapping tcp|udp|icmp local <addr> [<port|icmp-echo-id>] "
2364 "external <addr> [<port|icmp-echo-id>] [vrf <table-id>] [twice-nat|self-twice-nat] "
2365 "[out2in-only] [exact <pool-addr>] [del]",
2370 * @cliexstart{nat44 add identity mapping}
2371 * Identity mapping translate an IP address to itself.
2372 * To create identity mapping for address 10.0.0.3 port 6303 for TCP protocol
2374 * vpp# nat44 add identity mapping 10.0.0.3 tcp 6303
2375 * To create identity mapping for address 10.0.0.3 use:
2376 * vpp# nat44 add identity mapping 10.0.0.3
2377 * To create identity mapping for DHCP addressed interface use:
2378 * vpp# nat44 add identity mapping external GigabitEthernet0/a/0 tcp 3606
2381 VLIB_CLI_COMMAND (add_identity_mapping_command, static) = {
2382 .path = "nat44 add identity mapping",
2383 .function = add_identity_mapping_command_fn,
2384 .short_help = "nat44 add identity mapping <ip4-addr>|external <interface> "
2385 "[<protocol> <port>] [vrf <table-id>] [del]",
2390 * @cliexstart{nat44 add load-balancing static mapping}
2391 * Service load balancing using NAT44
2392 * To add static mapping with load balancing for service with external IP
2393 * address 1.2.3.4 and TCP port 80 and mapped to 2 local servers
2394 * 10.100.10.10:8080 and 10.100.10.20:8080 with probability 80% resp. 20% use:
2395 * 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
2398 VLIB_CLI_COMMAND (add_lb_static_mapping_command, static) = {
2399 .path = "nat44 add load-balancing static mapping",
2400 .function = add_lb_static_mapping_command_fn,
2402 "nat44 add load-balancing static mapping protocol tcp|udp "
2403 "external <addr>:<port> local <addr>:<port> [vrf <table-id>] "
2404 "probability <n> [twice-nat|self-twice-nat] [out2in-only] "
2405 "[affinity <timeout-seconds>] [del]",
2410 * @cliexstart{nat44 add load-balancing static mapping}
2411 * Modify service load balancing using NAT44
2412 * To add new back-end server 10.100.10.30:8080 for service load balancing
2413 * static mapping with external IP address 1.2.3.4 and TCP port 80 use:
2414 * vpp# nat44 add load-balancing back-end protocol tcp external 1.2.3.4:80 local 10.100.10.30:8080 probability 25
2417 VLIB_CLI_COMMAND (add_lb_backend_command, static) = {
2418 .path = "nat44 add load-balancing back-end",
2419 .function = add_lb_backend_command_fn,
2421 "nat44 add load-balancing back-end protocol tcp|udp "
2422 "external <addr>:<port> local <addr>:<port> [vrf <table-id>] "
2423 "probability <n> [del]",
2428 * @cliexstart{show nat44 static mappings}
2429 * Show NAT44 static mappings.
2430 * vpp# show nat44 static mappings
2431 * NAT44 static mappings:
2432 * local 10.0.0.3 external 4.4.4.4 vrf 0
2433 * tcp local 192.168.0.4:6303 external 4.4.4.3:3606 vrf 0
2434 * tcp vrf 0 external 1.2.3.4:80 out2in-only
2435 * local 10.100.10.10:8080 probability 80
2436 * local 10.100.10.20:8080 probability 20
2437 * tcp local 10.100.3.8:8080 external 169.10.10.1:80 vrf 0 twice-nat
2438 * tcp local 10.0.0.10:3603 external GigabitEthernet0/a/0:6306 vrf 10
2441 VLIB_CLI_COMMAND (nat44_show_static_mappings_command, static) = {
2442 .path = "show nat44 static mappings",
2443 .short_help = "show nat44 static mappings",
2444 .function = nat44_show_static_mappings_command_fn,
2449 * @cliexstart{nat44 add interface address}
2450 * Use NAT44 pool address from specific interfce
2451 * To add NAT44 pool address from specific interface use:
2452 * vpp# nat44 add interface address GigabitEthernet0/8/0
2455 VLIB_CLI_COMMAND (snat_add_interface_address_command, static) = {
2456 .path = "nat44 add interface address",
2457 .short_help = "nat44 add interface address <interface> [twice-nat] [del]",
2458 .function = snat_add_interface_address_command_fn,
2463 * @cliexstart{show nat44 interface address}
2464 * Show NAT44 pool address interfaces
2465 * vpp# show nat44 interface address
2466 * NAT44 pool address interfaces:
2467 * GigabitEthernet0/a/0
2468 * NAT44 twice-nat pool address interfaces:
2469 * GigabitEthernet0/8/0
2472 VLIB_CLI_COMMAND (nat44_show_interface_address_command, static) = {
2473 .path = "show nat44 interface address",
2474 .short_help = "show nat44 interface address",
2475 .function = nat44_show_interface_address_command_fn,
2480 * @cliexstart{show nat44 sessions}
2481 * Show NAT44 sessions.
2484 VLIB_CLI_COMMAND (nat44_show_sessions_command, static) = {
2485 .path = "show nat44 sessions",
2486 .short_help = "show nat44 sessions [detail|metrics]",
2487 .function = nat44_show_sessions_command_fn,
2492 * @cliexstart{set nat44 session limit}
2493 * Set NAT44 session limit.
2496 VLIB_CLI_COMMAND (nat44_set_session_limit_command, static) = {
2497 .path = "set nat44 session limit",
2498 .short_help = "set nat44 session limit <limit> [vrf <table-id>]",
2499 .function = nat44_set_session_limit_command_fn,
2504 * @cliexstart{nat44 del user}
2505 * To delete all NAT44 user sessions:
2506 * vpp# nat44 del user 10.0.0.3
2509 VLIB_CLI_COMMAND (nat44_del_user_command, static) = {
2510 .path = "nat44 del user",
2511 .short_help = "nat44 del user <addr> [fib <index>]",
2512 .function = nat44_del_user_command_fn,
2517 * @cliexstart{clear nat44 sessions}
2518 * To clear all NAT44 sessions
2519 * vpp# clear nat44 sessions
2522 VLIB_CLI_COMMAND (nat44_clear_sessions_command, static) = {
2523 .path = "clear nat44 sessions",
2524 .short_help = "clear nat44 sessions",
2525 .function = nat44_clear_sessions_command_fn,
2530 * @cliexstart{nat44 del session}
2531 * To administratively delete NAT44 session by inside address and port use:
2532 * vpp# nat44 del session in 10.0.0.3:6303 tcp
2533 * To administratively delete NAT44 session by outside address and port use:
2534 * vpp# nat44 del session out 1.0.0.3:6033 udp
2537 VLIB_CLI_COMMAND (nat44_del_session_command, static) = {
2538 .path = "nat44 del session",
2539 .short_help = "nat44 del session in|out <addr>:<port> tcp|udp|icmp [vrf <id>] [external-host <addr>:<port>]",
2540 .function = nat44_del_session_command_fn,
2545 * @cliexstart{nat44 forwarding}
2546 * Enable or disable forwarding
2547 * Forward packets which don't match existing translation
2548 * or static mapping instead of dropping them.
2549 * To enable forwarding, use:
2550 * vpp# nat44 forwarding enable
2551 * To disable forwarding, use:
2552 * vpp# nat44 forwarding disable
2555 VLIB_CLI_COMMAND (snat_forwarding_set_command, static) = {
2556 .path = "nat44 forwarding",
2557 .short_help = "nat44 forwarding enable|disable",
2558 .function = snat_forwarding_set_command_fn,
2564 * fd.io coding-style-patch-verification: ON
2567 * eval: (c-set-style "gnu")