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/nat_ipfix_logging.h>
22 #include <nat/nat_det.h>
23 #include <nat/nat64.h>
24 #include <nat/nat_inlines.h>
25 #include <nat/nat_affinity.h>
26 #include <vnet/fib/fib_table.h>
27 #include <nat/nat_ha.h>
29 #define UNSUPPORTED_IN_DET_MODE_STR \
30 "This command is unsupported in deterministic mode"
31 #define SUPPORTED_ONLY_IN_DET_MODE_STR \
32 "This command is supported only in deterministic mode"
35 set_workers_command_fn (vlib_main_t * vm,
36 unformat_input_t * input, vlib_cli_command_t * cmd)
38 unformat_input_t _line_input, *line_input = &_line_input;
39 snat_main_t *sm = &snat_main;
42 clib_error_t *error = 0;
44 if (sm->deterministic)
45 return clib_error_return (0, UNSUPPORTED_IN_DET_MODE_STR);
47 /* Get a line of input. */
48 if (!unformat_user (input, unformat_line_input, line_input))
51 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
53 if (unformat (line_input, "%U", unformat_bitmap_list, &bitmap))
57 error = clib_error_return (0, "unknown input '%U'",
58 format_unformat_error, line_input);
65 error = clib_error_return (0, "List of workers must be specified.");
69 rv = snat_set_workers (bitmap);
71 clib_bitmap_free (bitmap);
75 case VNET_API_ERROR_INVALID_WORKER:
76 error = clib_error_return (0, "Invalid worker(s).");
78 case VNET_API_ERROR_FEATURE_DISABLED:
79 error = clib_error_return (0,
80 "Supported only if 2 or more workes available.");
87 unformat_free (line_input);
93 nat_show_workers_commnad_fn (vlib_main_t * vm, unformat_input_t * input,
94 vlib_cli_command_t * cmd)
96 snat_main_t *sm = &snat_main;
99 if (sm->deterministic)
100 return clib_error_return (0, UNSUPPORTED_IN_DET_MODE_STR);
102 if (sm->num_workers > 1)
104 vlib_cli_output (vm, "%d workers", vec_len (sm->workers));
106 vec_foreach (worker, sm->workers)
108 vlib_worker_thread_t *w =
109 vlib_worker_threads + *worker + sm->first_worker_index;
110 vlib_cli_output (vm, " %s", w->name);
118 static clib_error_t *
119 snat_set_log_level_command_fn (vlib_main_t * vm,
120 unformat_input_t * input,
121 vlib_cli_command_t * cmd)
123 unformat_input_t _line_input, *line_input = &_line_input;
124 snat_main_t *sm = &snat_main;
125 u8 log_level = SNAT_LOG_NONE;
126 clib_error_t *error = 0;
128 /* Get a line of input. */
129 if (!unformat_user (input, unformat_line_input, line_input))
132 if (!unformat (line_input, "level %d", &log_level))
134 error = clib_error_return (0, "unknown input '%U'",
135 format_unformat_error, line_input);
138 if (log_level > SNAT_LOG_DEBUG)
140 error = clib_error_return (0, "unknown logging level '%d'", log_level);
143 sm->log_level = log_level;
146 unformat_free (line_input);
151 static clib_error_t *
152 snat_ipfix_logging_enable_disable_command_fn (vlib_main_t * vm,
153 unformat_input_t * input,
154 vlib_cli_command_t * cmd)
156 unformat_input_t _line_input, *line_input = &_line_input;
161 clib_error_t *error = 0;
163 /* Get a line of input. */
164 if (!unformat_user (input, unformat_line_input, line_input))
166 rv = snat_ipfix_logging_enable_disable (enable, domain_id,
169 return clib_error_return (0, "ipfix logging enable failed");
173 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
175 if (unformat (line_input, "domain %d", &domain_id))
177 else if (unformat (line_input, "src-port %d", &src_port))
179 else if (unformat (line_input, "disable"))
183 error = clib_error_return (0, "unknown input '%U'",
184 format_unformat_error, line_input);
189 rv = snat_ipfix_logging_enable_disable (enable, domain_id, (u16) src_port);
193 error = clib_error_return (0, "ipfix logging enable failed");
198 unformat_free (line_input);
203 static clib_error_t *
204 nat44_show_hash_commnad_fn (vlib_main_t * vm, unformat_input_t * input,
205 vlib_cli_command_t * cmd)
207 snat_main_t *sm = &snat_main;
208 snat_main_per_thread_data_t *tsm;
209 nat_affinity_main_t *nam = &nat_affinity_main;
213 if (unformat (input, "detail"))
215 else if (unformat (input, "verbose"))
218 vlib_cli_output (vm, "%U", format_bihash_8_8, &sm->static_mapping_by_local,
220 vlib_cli_output (vm, "%U",
221 format_bihash_8_8, &sm->static_mapping_by_external,
223 vec_foreach_index (i, sm->per_thread_data)
225 tsm = vec_elt_at_index (sm->per_thread_data, i);
226 vlib_cli_output (vm, "-------- thread %d %s --------\n",
227 i, vlib_worker_threads[i].name);
228 if (sm->endpoint_dependent)
230 vlib_cli_output (vm, "%U", format_bihash_16_8, &tsm->in2out_ed,
232 vlib_cli_output (vm, "%U", format_bihash_16_8, &tsm->out2in_ed,
237 vlib_cli_output (vm, "%U", format_bihash_8_8, &tsm->in2out, verbose);
238 vlib_cli_output (vm, "%U", format_bihash_8_8, &tsm->out2in, verbose);
240 vlib_cli_output (vm, "%U", format_bihash_8_8, &tsm->user_hash, verbose);
243 if (sm->endpoint_dependent)
244 vlib_cli_output (vm, "%U", format_bihash_16_8, &nam->affinity_hash,
249 static clib_error_t *
250 nat44_set_alloc_addr_and_port_alg_command_fn (vlib_main_t * vm,
251 unformat_input_t * input,
252 vlib_cli_command_t * cmd)
254 unformat_input_t _line_input, *line_input = &_line_input;
255 snat_main_t *sm = &snat_main;
256 clib_error_t *error = 0;
257 u32 psid, psid_offset, psid_length, port_start, port_end;
259 if (sm->deterministic)
260 return clib_error_return (0, UNSUPPORTED_IN_DET_MODE_STR);
262 /* Get a line of input. */
263 if (!unformat_user (input, unformat_line_input, line_input))
266 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
268 if (unformat (line_input, "default"))
269 nat_set_alloc_addr_and_port_default ();
272 (line_input, "map-e psid %d psid-offset %d psid-len %d", &psid,
273 &psid_offset, &psid_length))
274 nat_set_alloc_addr_and_port_mape ((u16) psid, (u16) psid_offset,
278 (line_input, "port-range %d - %d", &port_start, &port_end))
280 if (port_end <= port_start)
283 clib_error_return (0,
284 "The end-port must be greater than start-port");
287 nat_set_alloc_addr_and_port_range ((u16) port_start,
292 error = clib_error_return (0, "unknown input '%U'",
293 format_unformat_error, line_input);
299 unformat_free (line_input);
304 static clib_error_t *
305 nat44_show_alloc_addr_and_port_alg_command_fn (vlib_main_t * vm,
306 unformat_input_t * input,
307 vlib_cli_command_t * cmd)
309 snat_main_t *sm = &snat_main;
311 if (sm->deterministic)
312 return clib_error_return (0, UNSUPPORTED_IN_DET_MODE_STR);
314 vlib_cli_output (vm, "NAT address and port: %U",
315 format_nat_addr_and_port_alloc_alg,
316 sm->addr_and_port_alloc_alg);
317 switch (sm->addr_and_port_alloc_alg)
319 case NAT_ADDR_AND_PORT_ALLOC_ALG_MAPE:
320 vlib_cli_output (vm, " psid %d psid-offset %d psid-len %d", sm->psid,
321 sm->psid_offset, sm->psid_length);
323 case NAT_ADDR_AND_PORT_ALLOC_ALG_RANGE:
324 vlib_cli_output (vm, " start-port %d end-port %d", sm->start_port,
334 static clib_error_t *
335 nat_set_mss_clamping_command_fn (vlib_main_t * vm, unformat_input_t * input,
336 vlib_cli_command_t * cmd)
338 unformat_input_t _line_input, *line_input = &_line_input;
339 snat_main_t *sm = &snat_main;
340 clib_error_t *error = 0;
343 /* Get a line of input. */
344 if (!unformat_user (input, unformat_line_input, line_input))
347 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
349 if (unformat (line_input, "disable"))
350 sm->mss_clamping = 0;
351 else if (unformat (line_input, "%d", &mss))
353 sm->mss_clamping = (u16) mss;
354 sm->mss_value_net = clib_host_to_net_u16 (sm->mss_clamping);
358 error = clib_error_return (0, "unknown input '%U'",
359 format_unformat_error, line_input);
365 unformat_free (line_input);
370 static clib_error_t *
371 nat_show_mss_clamping_command_fn (vlib_main_t * vm, unformat_input_t * input,
372 vlib_cli_command_t * cmd)
374 snat_main_t *sm = &snat_main;
376 if (sm->mss_clamping)
377 vlib_cli_output (vm, "mss-clamping %d", sm->mss_clamping);
379 vlib_cli_output (vm, "mss-clamping disabled");
384 static clib_error_t *
385 nat_ha_failover_command_fn (vlib_main_t * vm, unformat_input_t * input,
386 vlib_cli_command_t * cmd)
388 unformat_input_t _line_input, *line_input = &_line_input;
390 u32 port, session_refresh_interval = 10;
392 clib_error_t *error = 0;
394 /* Get a line of input. */
395 if (!unformat_user (input, unformat_line_input, line_input))
398 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
400 if (unformat (line_input, "%U:%u", unformat_ip4_address, &addr, &port))
404 (line_input, "refresh-interval %u", &session_refresh_interval))
408 error = clib_error_return (0, "unknown input '%U'",
409 format_unformat_error, line_input);
414 rv = nat_ha_set_failover (&addr, (u16) port, session_refresh_interval);
416 error = clib_error_return (0, "set HA failover failed");
419 unformat_free (line_input);
424 static clib_error_t *
425 nat_ha_listener_command_fn (vlib_main_t * vm, unformat_input_t * input,
426 vlib_cli_command_t * cmd)
428 unformat_input_t _line_input, *line_input = &_line_input;
430 u32 port, path_mtu = 512;
432 clib_error_t *error = 0;
434 /* Get a line of input. */
435 if (!unformat_user (input, unformat_line_input, line_input))
438 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
440 if (unformat (line_input, "%U:%u", unformat_ip4_address, &addr, &port))
442 else if (unformat (line_input, "path-mtu %u", &path_mtu))
446 error = clib_error_return (0, "unknown input '%U'",
447 format_unformat_error, line_input);
452 rv = nat_ha_set_listener (&addr, (u16) port, path_mtu);
454 error = clib_error_return (0, "set HA listener failed");
457 unformat_free (line_input);
462 static clib_error_t *
463 nat_show_ha_command_fn (vlib_main_t * vm, unformat_input_t * input,
464 vlib_cli_command_t * cmd)
468 u32 path_mtu, session_refresh_interval, resync_ack_missed;
471 nat_ha_get_listener (&addr, &port, &path_mtu);
474 vlib_cli_output (vm, "NAT HA disabled\n");
478 vlib_cli_output (vm, "LISTENER:\n");
479 vlib_cli_output (vm, " %U:%u path-mtu %u\n",
480 format_ip4_address, &addr, port, path_mtu);
482 nat_ha_get_failover (&addr, &port, &session_refresh_interval);
483 vlib_cli_output (vm, "FAILOVER:\n");
485 vlib_cli_output (vm, " %U:%u refresh-interval %usec\n",
486 format_ip4_address, &addr, port,
487 session_refresh_interval);
489 vlib_cli_output (vm, " NA\n");
491 nat_ha_get_resync_status (&in_resync, &resync_ack_missed);
492 vlib_cli_output (vm, "RESYNC:\n");
494 vlib_cli_output (vm, " in progress\n");
496 vlib_cli_output (vm, " completed (%d ACK missed)\n", resync_ack_missed);
501 static clib_error_t *
502 nat_ha_flush_command_fn (vlib_main_t * vm, unformat_input_t * input,
503 vlib_cli_command_t * cmd)
509 static clib_error_t *
510 nat_ha_resync_command_fn (vlib_main_t * vm, unformat_input_t * input,
511 vlib_cli_command_t * cmd)
513 clib_error_t *error = 0;
515 if (nat_ha_resync (0, 0, 0))
516 error = clib_error_return (0, "NAT HA resync already running");
521 static clib_error_t *
522 add_address_command_fn (vlib_main_t * vm,
523 unformat_input_t * input, vlib_cli_command_t * cmd)
525 unformat_input_t _line_input, *line_input = &_line_input;
526 snat_main_t *sm = &snat_main;
527 ip4_address_t start_addr, end_addr, this_addr;
528 u32 start_host_order, end_host_order;
533 clib_error_t *error = 0;
536 if (sm->deterministic)
537 return clib_error_return (0, UNSUPPORTED_IN_DET_MODE_STR);
539 /* Get a line of input. */
540 if (!unformat_user (input, unformat_line_input, line_input))
543 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
545 if (unformat (line_input, "%U - %U",
546 unformat_ip4_address, &start_addr,
547 unformat_ip4_address, &end_addr))
549 else if (unformat (line_input, "tenant-vrf %u", &vrf_id))
551 else if (unformat (line_input, "%U", unformat_ip4_address, &start_addr))
552 end_addr = start_addr;
553 else if (unformat (line_input, "twice-nat"))
555 else if (unformat (line_input, "del"))
559 error = clib_error_return (0, "unknown input '%U'",
560 format_unformat_error, line_input);
565 if (sm->static_mapping_only)
567 error = clib_error_return (0, "static mapping only mode");
571 start_host_order = clib_host_to_net_u32 (start_addr.as_u32);
572 end_host_order = clib_host_to_net_u32 (end_addr.as_u32);
574 if (end_host_order < start_host_order)
576 error = clib_error_return (0, "end address less than start address");
580 count = (end_host_order - start_host_order) + 1;
583 nat_log_info ("%U - %U, %d addresses...",
584 format_ip4_address, &start_addr,
585 format_ip4_address, &end_addr, count);
587 this_addr = start_addr;
589 for (i = 0; i < count; i++)
592 rv = snat_add_address (sm, &this_addr, vrf_id, twice_nat);
594 rv = snat_del_address (sm, this_addr, 0, twice_nat);
598 case VNET_API_ERROR_VALUE_EXIST:
599 error = clib_error_return (0, "NAT address already in use.");
601 case VNET_API_ERROR_NO_SUCH_ENTRY:
602 error = clib_error_return (0, "NAT address not exist.");
604 case VNET_API_ERROR_UNSPECIFIED:
606 clib_error_return (0, "NAT address used in static mapping.");
608 case VNET_API_ERROR_FEATURE_DISABLED:
610 clib_error_return (0,
611 "twice NAT available only for endpoint-dependent mode.");
618 nat44_add_del_address_dpo (this_addr, is_add);
620 increment_v4_address (&this_addr);
624 unformat_free (line_input);
629 static clib_error_t *
630 nat44_show_addresses_command_fn (vlib_main_t * vm, unformat_input_t * input,
631 vlib_cli_command_t * cmd)
633 snat_main_t *sm = &snat_main;
636 if (sm->deterministic)
637 return clib_error_return (0, UNSUPPORTED_IN_DET_MODE_STR);
639 vlib_cli_output (vm, "NAT44 pool addresses:");
641 vec_foreach (ap, sm->addresses)
643 vlib_cli_output (vm, "%U", format_ip4_address, &ap->addr);
644 if (ap->fib_index != ~0)
645 vlib_cli_output (vm, " tenant VRF: %u",
646 fib_table_get(ap->fib_index, FIB_PROTOCOL_IP4)->ft_table_id);
648 vlib_cli_output (vm, " tenant VRF independent");
649 #define _(N, i, n, s) \
650 vlib_cli_output (vm, " %d busy %s ports", ap->busy_##n##_ports, s);
651 foreach_snat_protocol
654 vlib_cli_output (vm, "NAT44 twice-nat pool addresses:");
655 vec_foreach (ap, sm->twice_nat_addresses)
657 vlib_cli_output (vm, "%U", format_ip4_address, &ap->addr);
658 if (ap->fib_index != ~0)
659 vlib_cli_output (vm, " tenant VRF: %u",
660 fib_table_get(ap->fib_index, FIB_PROTOCOL_IP4)->ft_table_id);
662 vlib_cli_output (vm, " tenant VRF independent");
663 #define _(N, i, n, s) \
664 vlib_cli_output (vm, " %d busy %s ports", ap->busy_##n##_ports, s);
665 foreach_snat_protocol
672 static clib_error_t *
673 snat_feature_command_fn (vlib_main_t * vm,
674 unformat_input_t * input, vlib_cli_command_t * cmd)
676 unformat_input_t _line_input, *line_input = &_line_input;
677 vnet_main_t *vnm = vnet_get_main ();
678 clib_error_t *error = 0;
680 u32 *inside_sw_if_indices = 0;
681 u32 *outside_sw_if_indices = 0;
682 u8 is_output_feature = 0;
688 /* Get a line of input. */
689 if (!unformat_user (input, unformat_line_input, line_input))
692 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
694 if (unformat (line_input, "in %U", unformat_vnet_sw_interface,
696 vec_add1 (inside_sw_if_indices, sw_if_index);
697 else if (unformat (line_input, "out %U", unformat_vnet_sw_interface,
699 vec_add1 (outside_sw_if_indices, sw_if_index);
700 else if (unformat (line_input, "output-feature"))
701 is_output_feature = 1;
702 else if (unformat (line_input, "del"))
706 error = clib_error_return (0, "unknown input '%U'",
707 format_unformat_error, line_input);
712 if (vec_len (inside_sw_if_indices))
714 for (i = 0; i < vec_len (inside_sw_if_indices); i++)
716 sw_if_index = inside_sw_if_indices[i];
717 if (is_output_feature)
719 if (snat_interface_add_del_output_feature
720 (sw_if_index, 1, is_del))
722 error = clib_error_return (0, "%s %U failed",
723 is_del ? "del" : "add",
724 format_vnet_sw_if_index_name,
731 if (snat_interface_add_del (sw_if_index, 1, is_del))
733 error = clib_error_return (0, "%s %U failed",
734 is_del ? "del" : "add",
735 format_vnet_sw_if_index_name,
743 if (vec_len (outside_sw_if_indices))
745 for (i = 0; i < vec_len (outside_sw_if_indices); i++)
747 sw_if_index = outside_sw_if_indices[i];
748 if (is_output_feature)
750 if (snat_interface_add_del_output_feature
751 (sw_if_index, 0, is_del))
753 error = clib_error_return (0, "%s %U failed",
754 is_del ? "del" : "add",
755 format_vnet_sw_if_index_name,
762 if (snat_interface_add_del (sw_if_index, 0, is_del))
764 error = clib_error_return (0, "%s %U failed",
765 is_del ? "del" : "add",
766 format_vnet_sw_if_index_name,
775 unformat_free (line_input);
776 vec_free (inside_sw_if_indices);
777 vec_free (outside_sw_if_indices);
782 static clib_error_t *
783 nat44_show_interfaces_command_fn (vlib_main_t * vm, unformat_input_t * input,
784 vlib_cli_command_t * cmd)
786 snat_main_t *sm = &snat_main;
788 vnet_main_t *vnm = vnet_get_main ();
790 vlib_cli_output (vm, "NAT44 interfaces:");
792 pool_foreach (i, sm->interfaces,
794 vlib_cli_output (vm, " %U %s", format_vnet_sw_if_index_name, vnm,
796 (nat_interface_is_inside(i) &&
797 nat_interface_is_outside(i)) ? "in out" :
798 (nat_interface_is_inside(i) ? "in" : "out"));
801 pool_foreach (i, sm->output_feature_interfaces,
803 vlib_cli_output (vm, " %U output-feature %s",
804 format_vnet_sw_if_index_name, vnm,
806 (nat_interface_is_inside(i) &&
807 nat_interface_is_outside(i)) ? "in out" :
808 (nat_interface_is_inside(i) ? "in" : "out"));
815 static clib_error_t *
816 add_static_mapping_command_fn (vlib_main_t * vm,
817 unformat_input_t * input,
818 vlib_cli_command_t * cmd)
820 unformat_input_t _line_input, *line_input = &_line_input;
821 snat_main_t *sm = &snat_main;
822 clib_error_t *error = 0;
823 ip4_address_t l_addr, e_addr;
824 u32 l_port = 0, e_port = 0, vrf_id = ~0;
827 u32 sw_if_index = ~0;
828 vnet_main_t *vnm = vnet_get_main ();
830 snat_protocol_t proto = ~0;
832 twice_nat_type_t twice_nat = TWICE_NAT_DISABLED;
835 if (sm->deterministic)
836 return clib_error_return (0, UNSUPPORTED_IN_DET_MODE_STR);
838 /* Get a line of input. */
839 if (!unformat_user (input, unformat_line_input, line_input))
842 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
844 if (unformat (line_input, "local %U %u", unformat_ip4_address, &l_addr,
848 if (unformat (line_input, "local %U", unformat_ip4_address, &l_addr))
850 else if (unformat (line_input, "external %U %u", unformat_ip4_address,
853 else if (unformat (line_input, "external %U", unformat_ip4_address,
856 else if (unformat (line_input, "external %U %u",
857 unformat_vnet_sw_interface, vnm, &sw_if_index,
861 else if (unformat (line_input, "external %U",
862 unformat_vnet_sw_interface, vnm, &sw_if_index))
864 else if (unformat (line_input, "vrf %u", &vrf_id))
866 else if (unformat (line_input, "%U", unformat_snat_protocol, &proto))
868 else if (unformat (line_input, "twice-nat"))
869 twice_nat = TWICE_NAT;
870 else if (unformat (line_input, "self-twice-nat"))
871 twice_nat = TWICE_NAT_SELF;
872 else if (unformat (line_input, "out2in-only"))
874 else if (unformat (line_input, "del"))
878 error = clib_error_return (0, "unknown input: '%U'",
879 format_unformat_error, line_input);
884 if (twice_nat && addr_only)
886 error = clib_error_return (0, "twice NAT only for 1:1 NAPT");
890 if (!addr_only && !proto_set)
892 error = clib_error_return (0, "missing protocol");
896 rv = snat_add_static_mapping (l_addr, e_addr, (u16) l_port, (u16) e_port,
897 vrf_id, addr_only, sw_if_index, proto, is_add,
898 twice_nat, out2in_only, 0, 0);
902 case VNET_API_ERROR_INVALID_VALUE:
903 error = clib_error_return (0, "External port already in use.");
905 case VNET_API_ERROR_NO_SUCH_ENTRY:
907 error = clib_error_return (0, "External address must be allocated.");
909 error = clib_error_return (0, "Mapping not exist.");
911 case VNET_API_ERROR_NO_SUCH_FIB:
912 error = clib_error_return (0, "No such VRF id.");
914 case VNET_API_ERROR_VALUE_EXIST:
915 error = clib_error_return (0, "Mapping already exist.");
917 case VNET_API_ERROR_FEATURE_DISABLED:
919 clib_error_return (0,
920 "twice-nat/out2in-only available only for endpoint-dependent mode.");
927 unformat_free (line_input);
932 static clib_error_t *
933 add_identity_mapping_command_fn (vlib_main_t * vm,
934 unformat_input_t * input,
935 vlib_cli_command_t * cmd)
937 unformat_input_t _line_input, *line_input = &_line_input;
938 snat_main_t *sm = &snat_main;
939 clib_error_t *error = 0;
941 u32 port = 0, vrf_id = ~0;
944 u32 sw_if_index = ~0;
945 vnet_main_t *vnm = vnet_get_main ();
947 snat_protocol_t proto;
949 if (sm->deterministic)
950 return clib_error_return (0, UNSUPPORTED_IN_DET_MODE_STR);
954 /* Get a line of input. */
955 if (!unformat_user (input, unformat_line_input, line_input))
958 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
960 if (unformat (line_input, "%U", unformat_ip4_address, &addr))
962 else if (unformat (line_input, "external %U",
963 unformat_vnet_sw_interface, vnm, &sw_if_index))
965 else if (unformat (line_input, "vrf %u", &vrf_id))
967 else if (unformat (line_input, "%U %u", unformat_snat_protocol, &proto,
970 else if (unformat (line_input, "del"))
974 error = clib_error_return (0, "unknown input: '%U'",
975 format_unformat_error, line_input);
980 rv = snat_add_static_mapping (addr, addr, (u16) port, (u16) port,
981 vrf_id, addr_only, sw_if_index, proto, is_add,
986 case VNET_API_ERROR_INVALID_VALUE:
987 error = clib_error_return (0, "External port already in use.");
989 case VNET_API_ERROR_NO_SUCH_ENTRY:
991 error = clib_error_return (0, "External address must be allocated.");
993 error = clib_error_return (0, "Mapping not exist.");
995 case VNET_API_ERROR_NO_SUCH_FIB:
996 error = clib_error_return (0, "No such VRF id.");
998 case VNET_API_ERROR_VALUE_EXIST:
999 error = clib_error_return (0, "Mapping already exist.");
1006 unformat_free (line_input);
1011 static clib_error_t *
1012 add_lb_static_mapping_command_fn (vlib_main_t * vm,
1013 unformat_input_t * input,
1014 vlib_cli_command_t * cmd)
1016 unformat_input_t _line_input, *line_input = &_line_input;
1017 snat_main_t *sm = &snat_main;
1018 clib_error_t *error = 0;
1019 ip4_address_t l_addr, e_addr;
1020 u32 l_port = 0, e_port = 0, vrf_id = 0, probability = 0, affinity = 0;
1023 snat_protocol_t proto;
1025 nat44_lb_addr_port_t *locals = 0, local;
1026 twice_nat_type_t twice_nat = TWICE_NAT_DISABLED;
1029 if (sm->deterministic)
1030 return clib_error_return (0, UNSUPPORTED_IN_DET_MODE_STR);
1032 /* Get a line of input. */
1033 if (!unformat_user (input, unformat_line_input, line_input))
1036 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1038 if (unformat (line_input, "local %U:%u probability %u",
1039 unformat_ip4_address, &l_addr, &l_port, &probability))
1041 clib_memset (&local, 0, sizeof (local));
1042 local.addr = l_addr;
1043 local.port = (u16) l_port;
1044 local.probability = (u8) probability;
1045 vec_add1 (locals, local);
1047 else if (unformat (line_input, "local %U:%u vrf %u probability %u",
1048 unformat_ip4_address, &l_addr, &l_port, &vrf_id,
1051 clib_memset (&local, 0, sizeof (local));
1052 local.addr = l_addr;
1053 local.port = (u16) l_port;
1054 local.probability = (u8) probability;
1055 local.vrf_id = vrf_id;
1056 vec_add1 (locals, local);
1058 else if (unformat (line_input, "external %U:%u", unformat_ip4_address,
1061 else if (unformat (line_input, "protocol %U", unformat_snat_protocol,
1064 else if (unformat (line_input, "twice-nat"))
1065 twice_nat = TWICE_NAT;
1066 else if (unformat (line_input, "self-twice-nat"))
1067 twice_nat = TWICE_NAT_SELF;
1068 else if (unformat (line_input, "out2in-only"))
1070 else if (unformat (line_input, "del"))
1072 else if (unformat (line_input, "affinity %u", &affinity))
1076 error = clib_error_return (0, "unknown input: '%U'",
1077 format_unformat_error, line_input);
1082 if (vec_len (locals) < 2)
1084 error = clib_error_return (0, "at least two local must be set");
1090 error = clib_error_return (0, "missing protocol");
1094 rv = nat44_add_del_lb_static_mapping (e_addr, (u16) e_port, proto, locals,
1095 is_add, twice_nat, out2in_only, 0,
1100 case VNET_API_ERROR_INVALID_VALUE:
1101 error = clib_error_return (0, "External port already in use.");
1103 case VNET_API_ERROR_NO_SUCH_ENTRY:
1105 error = clib_error_return (0, "External address must be allocated.");
1107 error = clib_error_return (0, "Mapping not exist.");
1109 case VNET_API_ERROR_VALUE_EXIST:
1110 error = clib_error_return (0, "Mapping already exist.");
1112 case VNET_API_ERROR_FEATURE_DISABLED:
1114 clib_error_return (0, "Available only for endpoint-dependent mode.");
1121 unformat_free (line_input);
1127 static clib_error_t *
1128 add_lb_backend_command_fn (vlib_main_t * vm,
1129 unformat_input_t * input, vlib_cli_command_t * cmd)
1131 unformat_input_t _line_input, *line_input = &_line_input;
1132 snat_main_t *sm = &snat_main;
1133 clib_error_t *error = 0;
1134 ip4_address_t l_addr, e_addr;
1135 u32 l_port = 0, e_port = 0, vrf_id = 0, probability = 0;
1138 snat_protocol_t proto;
1141 if (sm->deterministic)
1142 return clib_error_return (0, UNSUPPORTED_IN_DET_MODE_STR);
1144 /* Get a line of input. */
1145 if (!unformat_user (input, unformat_line_input, line_input))
1148 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1150 if (unformat (line_input, "local %U:%u probability %u",
1151 unformat_ip4_address, &l_addr, &l_port, &probability))
1153 else if (unformat (line_input, "local %U:%u vrf %u probability %u",
1154 unformat_ip4_address, &l_addr, &l_port, &vrf_id,
1157 else if (unformat (line_input, "external %U:%u", unformat_ip4_address,
1160 else if (unformat (line_input, "protocol %U", unformat_snat_protocol,
1163 else if (unformat (line_input, "del"))
1167 error = clib_error_return (0, "unknown input: '%U'",
1168 format_unformat_error, line_input);
1173 if (!l_port || !e_port)
1175 error = clib_error_return (0, "local or external must be set");
1181 error = clib_error_return (0, "missing protocol");
1186 nat44_lb_static_mapping_add_del_local (e_addr, (u16) e_port, l_addr,
1187 l_port, proto, vrf_id, probability,
1192 case VNET_API_ERROR_INVALID_VALUE:
1193 error = clib_error_return (0, "External is not load-balancing static "
1196 case VNET_API_ERROR_NO_SUCH_ENTRY:
1197 error = clib_error_return (0, "Mapping or back-end not exist.");
1199 case VNET_API_ERROR_VALUE_EXIST:
1200 error = clib_error_return (0, "Back-end already exist.");
1202 case VNET_API_ERROR_FEATURE_DISABLED:
1204 clib_error_return (0, "Available only for endpoint-dependent mode.");
1206 case VNET_API_ERROR_UNSPECIFIED:
1207 error = clib_error_return (0, "At least two back-ends must remain");
1214 unformat_free (line_input);
1219 static clib_error_t *
1220 nat44_show_static_mappings_command_fn (vlib_main_t * vm,
1221 unformat_input_t * input,
1222 vlib_cli_command_t * cmd)
1224 snat_main_t *sm = &snat_main;
1225 snat_static_mapping_t *m;
1226 snat_static_map_resolve_t *rp;
1228 if (sm->deterministic)
1229 return clib_error_return (0, UNSUPPORTED_IN_DET_MODE_STR);
1231 vlib_cli_output (vm, "NAT44 static mappings:");
1233 pool_foreach (m, sm->static_mappings,
1235 vlib_cli_output (vm, " %U", format_snat_static_mapping, m);
1237 vec_foreach (rp, sm->to_resolve)
1238 vlib_cli_output (vm, " %U", format_snat_static_map_to_resolve, rp);
1244 static clib_error_t *
1245 snat_add_interface_address_command_fn (vlib_main_t * vm,
1246 unformat_input_t * input,
1247 vlib_cli_command_t * cmd)
1249 snat_main_t *sm = &snat_main;
1250 unformat_input_t _line_input, *line_input = &_line_input;
1254 clib_error_t *error = 0;
1257 if (sm->deterministic)
1258 return clib_error_return (0, UNSUPPORTED_IN_DET_MODE_STR);
1260 /* Get a line of input. */
1261 if (!unformat_user (input, unformat_line_input, line_input))
1264 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1266 if (unformat (line_input, "%U", unformat_vnet_sw_interface,
1267 sm->vnet_main, &sw_if_index))
1269 else if (unformat (line_input, "twice-nat"))
1271 else if (unformat (line_input, "del"))
1275 error = clib_error_return (0, "unknown input '%U'",
1276 format_unformat_error, line_input);
1281 rv = snat_add_interface_address (sm, sw_if_index, is_del, twice_nat);
1289 error = clib_error_return (0, "snat_add_interface_address returned %d",
1295 unformat_free (line_input);
1300 static clib_error_t *
1301 nat44_show_interface_address_command_fn (vlib_main_t * vm,
1302 unformat_input_t * input,
1303 vlib_cli_command_t * cmd)
1305 snat_main_t *sm = &snat_main;
1306 vnet_main_t *vnm = vnet_get_main ();
1309 if (sm->deterministic)
1310 return clib_error_return (0, UNSUPPORTED_IN_DET_MODE_STR);
1313 vlib_cli_output (vm, "NAT44 pool address interfaces:");
1314 vec_foreach (sw_if_index, sm->auto_add_sw_if_indices)
1316 vlib_cli_output (vm, " %U", format_vnet_sw_if_index_name, vnm,
1319 vlib_cli_output (vm, "NAT44 twice-nat pool address interfaces:");
1320 vec_foreach (sw_if_index, sm->auto_add_sw_if_indices_twice_nat)
1322 vlib_cli_output (vm, " %U", format_vnet_sw_if_index_name, vnm,
1330 static clib_error_t *
1331 nat44_show_sessions_command_fn (vlib_main_t * vm, unformat_input_t * input,
1332 vlib_cli_command_t * cmd)
1335 snat_main_t *sm = &snat_main;
1336 snat_main_per_thread_data_t *tsm;
1340 if (sm->deterministic)
1341 return clib_error_return (0, UNSUPPORTED_IN_DET_MODE_STR);
1343 if (unformat (input, "detail"))
1346 vlib_cli_output (vm, "NAT44 sessions:");
1349 vec_foreach_index (i, sm->per_thread_data)
1351 tsm = vec_elt_at_index (sm->per_thread_data, i);
1353 vlib_cli_output (vm, "-------- thread %d %s: %d sessions --------\n",
1354 i, vlib_worker_threads[i].name,
1355 pool_elts (tsm->sessions));
1356 pool_foreach (u, tsm->users,
1358 vlib_cli_output (vm, " %U", format_snat_user, tsm, u, verbose);
1366 static clib_error_t *
1367 nat44_del_session_command_fn (vlib_main_t * vm,
1368 unformat_input_t * input,
1369 vlib_cli_command_t * cmd)
1371 snat_main_t *sm = &snat_main;
1372 unformat_input_t _line_input, *line_input = &_line_input;
1373 int is_in = 0, is_ed = 0;
1374 clib_error_t *error = 0;
1375 ip4_address_t addr, eh_addr;
1376 u32 port = 0, eh_port = 0, vrf_id = sm->outside_vrf_id;
1377 snat_protocol_t proto;
1380 if (sm->deterministic)
1381 return clib_error_return (0, UNSUPPORTED_IN_DET_MODE_STR);
1383 /* Get a line of input. */
1384 if (!unformat_user (input, unformat_line_input, line_input))
1387 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1390 (line_input, "%U:%u %U", unformat_ip4_address, &addr, &port,
1391 unformat_snat_protocol, &proto))
1393 else if (unformat (line_input, "in"))
1396 vrf_id = sm->inside_vrf_id;
1398 else if (unformat (line_input, "out"))
1401 vrf_id = sm->outside_vrf_id;
1403 else if (unformat (line_input, "vrf %u", &vrf_id))
1407 (line_input, "external-host %U:%u", unformat_ip4_address,
1408 &eh_addr, &eh_port))
1412 error = clib_error_return (0, "unknown input '%U'",
1413 format_unformat_error, line_input);
1420 nat44_del_ed_session (sm, &addr, port, &eh_addr, eh_port,
1421 snat_proto_to_ip_proto (proto), vrf_id, is_in);
1423 rv = nat44_del_session (sm, &addr, port, proto, vrf_id, is_in);
1431 error = clib_error_return (0, "nat44_del_session returned %d", rv);
1436 unformat_free (line_input);
1441 static clib_error_t *
1442 snat_forwarding_set_command_fn (vlib_main_t * vm,
1443 unformat_input_t * input,
1444 vlib_cli_command_t * cmd)
1446 snat_main_t *sm = &snat_main;
1447 unformat_input_t _line_input, *line_input = &_line_input;
1448 u8 forwarding_enable;
1449 u8 forwarding_enable_set = 0;
1450 clib_error_t *error = 0;
1452 if (sm->deterministic)
1453 return clib_error_return (0, UNSUPPORTED_IN_DET_MODE_STR);
1455 /* Get a line of input. */
1456 if (!unformat_user (input, unformat_line_input, line_input))
1457 return clib_error_return (0, "'enable' or 'disable' expected");
1459 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1461 if (!forwarding_enable_set && unformat (line_input, "enable"))
1463 forwarding_enable = 1;
1464 forwarding_enable_set = 1;
1466 else if (!forwarding_enable_set && unformat (line_input, "disable"))
1468 forwarding_enable = 0;
1469 forwarding_enable_set = 1;
1473 error = clib_error_return (0, "unknown input '%U'",
1474 format_unformat_error, line_input);
1479 if (!forwarding_enable_set)
1481 error = clib_error_return (0, "'enable' or 'disable' expected");
1485 sm->forwarding_enabled = forwarding_enable;
1488 unformat_free (line_input);
1493 static clib_error_t *
1494 snat_det_map_command_fn (vlib_main_t * vm,
1495 unformat_input_t * input, vlib_cli_command_t * cmd)
1497 snat_main_t *sm = &snat_main;
1498 unformat_input_t _line_input, *line_input = &_line_input;
1499 ip4_address_t in_addr, out_addr;
1500 u32 in_plen, out_plen;
1502 clib_error_t *error = 0;
1504 if (!sm->deterministic)
1505 return clib_error_return (0, SUPPORTED_ONLY_IN_DET_MODE_STR);
1507 /* Get a line of input. */
1508 if (!unformat_user (input, unformat_line_input, line_input))
1511 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1514 (line_input, "in %U/%u", unformat_ip4_address, &in_addr, &in_plen))
1518 (line_input, "out %U/%u", unformat_ip4_address, &out_addr,
1521 else if (unformat (line_input, "del"))
1525 error = clib_error_return (0, "unknown input '%U'",
1526 format_unformat_error, line_input);
1531 rv = snat_det_add_map (sm, &in_addr, (u8) in_plen, &out_addr, (u8) out_plen,
1536 error = clib_error_return (0, "snat_det_add_map return %d", rv);
1541 unformat_free (line_input);
1546 static clib_error_t *
1547 nat44_det_show_mappings_command_fn (vlib_main_t * vm,
1548 unformat_input_t * input,
1549 vlib_cli_command_t * cmd)
1551 snat_main_t *sm = &snat_main;
1554 if (!sm->deterministic)
1555 return clib_error_return (0, SUPPORTED_ONLY_IN_DET_MODE_STR);
1557 vlib_cli_output (vm, "NAT44 deterministic mappings:");
1559 pool_foreach (dm, sm->det_maps,
1561 vlib_cli_output (vm, " in %U/%d out %U/%d\n",
1562 format_ip4_address, &dm->in_addr, dm->in_plen,
1563 format_ip4_address, &dm->out_addr, dm->out_plen);
1564 vlib_cli_output (vm, " outside address sharing ratio: %d\n",
1566 vlib_cli_output (vm, " number of ports per inside host: %d\n",
1567 dm->ports_per_host);
1568 vlib_cli_output (vm, " sessions number: %d\n", dm->ses_num);
1575 static clib_error_t *
1576 snat_det_forward_command_fn (vlib_main_t * vm,
1577 unformat_input_t * input,
1578 vlib_cli_command_t * cmd)
1580 snat_main_t *sm = &snat_main;
1581 unformat_input_t _line_input, *line_input = &_line_input;
1582 ip4_address_t in_addr, out_addr;
1585 clib_error_t *error = 0;
1587 if (!sm->deterministic)
1588 return clib_error_return (0, SUPPORTED_ONLY_IN_DET_MODE_STR);
1590 /* Get a line of input. */
1591 if (!unformat_user (input, unformat_line_input, line_input))
1594 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1596 if (unformat (line_input, "%U", unformat_ip4_address, &in_addr))
1600 error = clib_error_return (0, "unknown input '%U'",
1601 format_unformat_error, line_input);
1606 dm = snat_det_map_by_user (sm, &in_addr);
1608 vlib_cli_output (vm, "no match");
1611 snat_det_forward (dm, &in_addr, &out_addr, &lo_port);
1612 vlib_cli_output (vm, "%U:<%d-%d>", format_ip4_address, &out_addr,
1613 lo_port, lo_port + dm->ports_per_host - 1);
1617 unformat_free (line_input);
1622 static clib_error_t *
1623 snat_det_reverse_command_fn (vlib_main_t * vm,
1624 unformat_input_t * input,
1625 vlib_cli_command_t * cmd)
1627 snat_main_t *sm = &snat_main;
1628 unformat_input_t _line_input, *line_input = &_line_input;
1629 ip4_address_t in_addr, out_addr;
1632 clib_error_t *error = 0;
1634 if (!sm->deterministic)
1635 return clib_error_return (0, SUPPORTED_ONLY_IN_DET_MODE_STR);
1637 /* Get a line of input. */
1638 if (!unformat_user (input, unformat_line_input, line_input))
1641 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1644 (line_input, "%U:%d", unformat_ip4_address, &out_addr, &out_port))
1648 error = clib_error_return (0, "unknown input '%U'",
1649 format_unformat_error, line_input);
1654 if (out_port < 1024 || out_port > 65535)
1656 error = clib_error_return (0, "wrong port, must be <1024-65535>");
1660 dm = snat_det_map_by_out (sm, &out_addr);
1662 vlib_cli_output (vm, "no match");
1665 snat_det_reverse (dm, &out_addr, (u16) out_port, &in_addr);
1666 vlib_cli_output (vm, "%U", format_ip4_address, &in_addr);
1670 unformat_free (line_input);
1675 static clib_error_t *
1676 set_timeout_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;
1683 /* Get a line of input. */
1684 if (!unformat_user (input, unformat_line_input, line_input))
1687 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1689 if (unformat (line_input, "udp %u", &sm->udp_timeout))
1691 if (nat64_set_udp_timeout (sm->udp_timeout))
1693 error = clib_error_return (0, "Invalid UDP timeout value");
1697 else if (unformat (line_input, "tcp-established %u",
1698 &sm->tcp_established_timeout))
1700 if (nat64_set_tcp_timeouts
1701 (sm->tcp_transitory_timeout, sm->tcp_established_timeout))
1704 clib_error_return (0,
1705 "Invalid TCP established timeouts value");
1709 else if (unformat (line_input, "tcp-transitory %u",
1710 &sm->tcp_transitory_timeout))
1712 if (nat64_set_tcp_timeouts
1713 (sm->tcp_transitory_timeout, sm->tcp_established_timeout))
1716 clib_error_return (0,
1717 "Invalid TCP transitory timeouts value");
1721 else if (unformat (line_input, "icmp %u", &sm->icmp_timeout))
1723 if (nat64_set_icmp_timeout (sm->icmp_timeout))
1725 error = clib_error_return (0, "Invalid ICMP timeout value");
1729 else if (unformat (line_input, "reset"))
1731 sm->udp_timeout = SNAT_UDP_TIMEOUT;
1732 sm->tcp_established_timeout = SNAT_TCP_ESTABLISHED_TIMEOUT;
1733 sm->tcp_transitory_timeout = SNAT_TCP_TRANSITORY_TIMEOUT;
1734 sm->icmp_timeout = SNAT_ICMP_TIMEOUT;
1735 nat64_set_udp_timeout (0);
1736 nat64_set_icmp_timeout (0);
1737 nat64_set_tcp_timeouts (0, 0);
1741 error = clib_error_return (0, "unknown input '%U'",
1742 format_unformat_error, line_input);
1748 unformat_free (line_input);
1753 static clib_error_t *
1754 nat_show_timeouts_command_fn (vlib_main_t * vm,
1755 unformat_input_t * input,
1756 vlib_cli_command_t * cmd)
1758 snat_main_t *sm = &snat_main;
1760 vlib_cli_output (vm, "udp timeout: %dsec", sm->udp_timeout);
1761 vlib_cli_output (vm, "tcp-established timeout: %dsec",
1762 sm->tcp_established_timeout);
1763 vlib_cli_output (vm, "tcp-transitory timeout: %dsec",
1764 sm->tcp_transitory_timeout);
1765 vlib_cli_output (vm, "icmp timeout: %dsec", sm->icmp_timeout);
1770 static clib_error_t *
1771 nat44_det_show_sessions_command_fn (vlib_main_t * vm,
1772 unformat_input_t * input,
1773 vlib_cli_command_t * cmd)
1775 snat_main_t *sm = &snat_main;
1777 snat_det_session_t *ses;
1780 if (!sm->deterministic)
1781 return clib_error_return (0, SUPPORTED_ONLY_IN_DET_MODE_STR);
1783 vlib_cli_output (vm, "NAT44 deterministic sessions:");
1785 pool_foreach (dm, sm->det_maps,
1787 vec_foreach_index (i, dm->sessions)
1789 ses = vec_elt_at_index (dm->sessions, i);
1791 vlib_cli_output (vm, " %U", format_det_map_ses, dm, ses, &i);
1798 static clib_error_t *
1799 snat_det_close_session_out_fn (vlib_main_t * vm,
1800 unformat_input_t * input,
1801 vlib_cli_command_t * cmd)
1803 snat_main_t *sm = &snat_main;
1804 unformat_input_t _line_input, *line_input = &_line_input;
1805 ip4_address_t out_addr, ext_addr, in_addr;
1806 u32 out_port, ext_port;
1808 snat_det_session_t *ses;
1809 snat_det_out_key_t key;
1810 clib_error_t *error = 0;
1812 if (!sm->deterministic)
1813 return clib_error_return (0, SUPPORTED_ONLY_IN_DET_MODE_STR);
1815 /* Get a line of input. */
1816 if (!unformat_user (input, unformat_line_input, line_input))
1819 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1821 if (unformat (line_input, "%U:%d %U:%d",
1822 unformat_ip4_address, &out_addr, &out_port,
1823 unformat_ip4_address, &ext_addr, &ext_port))
1827 error = clib_error_return (0, "unknown input '%U'",
1828 format_unformat_error, line_input);
1833 unformat_free (line_input);
1835 dm = snat_det_map_by_out (sm, &out_addr);
1837 vlib_cli_output (vm, "no match");
1840 snat_det_reverse (dm, &ext_addr, (u16) out_port, &in_addr);
1841 key.ext_host_addr = out_addr;
1842 key.ext_host_port = ntohs ((u16) ext_port);
1843 key.out_port = ntohs ((u16) out_port);
1844 ses = snat_det_get_ses_by_out (dm, &out_addr, key.as_u64);
1846 vlib_cli_output (vm, "no match");
1848 snat_det_ses_close (dm, ses);
1852 unformat_free (line_input);
1857 static clib_error_t *
1858 snat_det_close_session_in_fn (vlib_main_t * vm,
1859 unformat_input_t * input,
1860 vlib_cli_command_t * cmd)
1862 snat_main_t *sm = &snat_main;
1863 unformat_input_t _line_input, *line_input = &_line_input;
1864 ip4_address_t in_addr, ext_addr;
1865 u32 in_port, ext_port;
1867 snat_det_session_t *ses;
1868 snat_det_out_key_t key;
1869 clib_error_t *error = 0;
1871 if (!sm->deterministic)
1872 return clib_error_return (0, SUPPORTED_ONLY_IN_DET_MODE_STR);
1874 /* Get a line of input. */
1875 if (!unformat_user (input, unformat_line_input, line_input))
1878 while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1880 if (unformat (line_input, "%U:%d %U:%d",
1881 unformat_ip4_address, &in_addr, &in_port,
1882 unformat_ip4_address, &ext_addr, &ext_port))
1886 error = clib_error_return (0, "unknown input '%U'",
1887 format_unformat_error, line_input);
1892 unformat_free (line_input);
1894 dm = snat_det_map_by_user (sm, &in_addr);
1896 vlib_cli_output (vm, "no match");
1899 key.ext_host_addr = ext_addr;
1900 key.ext_host_port = ntohs ((u16) ext_port);
1902 snat_det_find_ses_by_in (dm, &in_addr, ntohs ((u16) in_port), key);
1904 vlib_cli_output (vm, "no match");
1906 snat_det_ses_close (dm, ses);
1910 unformat_free (line_input);
1918 * @cliexstart{set snat workers}
1919 * Set NAT workers if 2 or more workers available, use:
1920 * vpp# set snat workers 0-2,5
1923 VLIB_CLI_COMMAND (set_workers_command, static) = {
1924 .path = "set nat workers",
1925 .function = set_workers_command_fn,
1926 .short_help = "set nat workers <workers-list>",
1931 * @cliexstart{show nat workers}
1933 * vpp# show nat workers:
1939 VLIB_CLI_COMMAND (nat_show_workers_command, static) = {
1940 .path = "show nat workers",
1941 .short_help = "show nat workers",
1942 .function = nat_show_workers_commnad_fn,
1947 * @cliexstart{set nat timeout}
1948 * Set values of timeouts for NAT sessions (in seconds), use:
1949 * vpp# set nat timeout udp 120 tcp-established 7500 tcp-transitory 250 icmp 90
1950 * To reset default values use:
1951 * vpp# set nat44 deterministic timeout reset
1954 VLIB_CLI_COMMAND (set_timeout_command, static) = {
1955 .path = "set nat timeout",
1956 .function = set_timeout_command_fn,
1958 "set nat timeout [udp <sec> | tcp-established <sec> "
1959 "tcp-transitory <sec> | icmp <sec> | reset]",
1964 * @cliexstart{show nat timeouts}
1965 * Show values of timeouts for NAT sessions.
1966 * vpp# show nat timeouts
1967 * udp timeout: 300sec
1968 * tcp-established timeout: 7440sec
1969 * tcp-transitory timeout: 240sec
1970 * icmp timeout: 60sec
1973 VLIB_CLI_COMMAND (nat_show_timeouts_command, static) = {
1974 .path = "show nat timeouts",
1975 .short_help = "show nat timeouts",
1976 .function = nat_show_timeouts_command_fn,
1981 * @cliexstart{nat set logging level}
1982 * To set NAT logging level use:
1983 * Set nat logging level
1986 VLIB_CLI_COMMAND (snat_set_log_level_command, static) = {
1987 .path = "nat set logging level",
1988 .function = snat_set_log_level_command_fn,
1989 .short_help = "nat set logging level <level>",
1994 * @cliexstart{snat ipfix logging}
1995 * To enable NAT IPFIX logging use:
1996 * vpp# nat ipfix logging
1997 * To set IPFIX exporter use:
1998 * vpp# set ipfix exporter collector 10.10.10.3 src 10.10.10.1
2001 VLIB_CLI_COMMAND (snat_ipfix_logging_enable_disable_command, static) = {
2002 .path = "nat ipfix logging",
2003 .function = snat_ipfix_logging_enable_disable_command_fn,
2004 .short_help = "nat ipfix logging [domain <domain-id>] [src-port <port>] [disable]",
2009 * @cliexstart{nat addr-port-assignment-alg}
2010 * Set address and port assignment algorithm
2011 * For the MAP-E CE limit port choice based on PSID use:
2012 * vpp# nat addr-port-assignment-alg map-e psid 10 psid-offset 6 psid-len 6
2013 * For port range use:
2014 * vpp# nat addr-port-assignment-alg port-range <start-port> - <end-port>
2015 * To set standard (default) address and port assignment algorithm use:
2016 * vpp# nat addr-port-assignment-alg default
2019 VLIB_CLI_COMMAND (nat44_set_alloc_addr_and_port_alg_command, static) = {
2020 .path = "nat addr-port-assignment-alg",
2021 .short_help = "nat addr-port-assignment-alg <alg-name> [<alg-params>]",
2022 .function = nat44_set_alloc_addr_and_port_alg_command_fn,
2027 * @cliexstart{show nat addr-port-assignment-alg}
2028 * Show address and port assignment algorithm
2031 VLIB_CLI_COMMAND (nat44_show_alloc_addr_and_port_alg_command, static) = {
2032 .path = "show nat addr-port-assignment-alg",
2033 .short_help = "show nat addr-port-assignment-alg",
2034 .function = nat44_show_alloc_addr_and_port_alg_command_fn,
2039 * @cliexstart{nat mss-clamping}
2040 * Set TCP MSS rewriting configuration
2041 * To enable TCP MSS rewriting use:
2042 * vpp# nat mss-clamping 1452
2043 * To disbale TCP MSS rewriting use:
2044 * vpp# nat mss-clamping disable
2047 VLIB_CLI_COMMAND (nat_set_mss_clamping_command, static) = {
2048 .path = "nat mss-clamping",
2049 .short_help = "nat mss-clamping <mss-value>|disable",
2050 .function = nat_set_mss_clamping_command_fn,
2055 * @cliexstart{show nat mss-clamping}
2056 * Show TCP MSS rewriting configuration
2059 VLIB_CLI_COMMAND (nat_show_mss_clamping_command, static) = {
2060 .path = "show nat mss-clamping",
2061 .short_help = "show nat mss-clamping",
2062 .function = nat_show_mss_clamping_command_fn,
2067 * @cliexstart{nat ha failover}
2068 * Set HA failover (remote settings)
2071 VLIB_CLI_COMMAND (nat_ha_failover_command, static) = {
2072 .path = "nat ha failover",
2073 .short_help = "nat ha failover <ip4-address>:<port> [refresh-interval <sec>]",
2074 .function = nat_ha_failover_command_fn,
2079 * @cliexstart{nat ha listener}
2080 * Set HA listener (local settings)
2083 VLIB_CLI_COMMAND (nat_ha_listener_command, static) = {
2084 .path = "nat ha listener",
2085 .short_help = "nat ha listener <ip4-address>:<port> [path-mtu <path-mtu>]",
2086 .function = nat_ha_listener_command_fn,
2091 * @cliexstart{show nat ha}
2092 * Show HA configuration/status
2095 VLIB_CLI_COMMAND (nat_show_ha_command, static) = {
2096 .path = "show nat ha",
2097 .short_help = "show nat ha",
2098 .function = nat_show_ha_command_fn,
2103 * @cliexstart{nat ha flush}
2104 * Flush the current HA data (for testing)
2107 VLIB_CLI_COMMAND (nat_ha_flush_command, static) = {
2108 .path = "nat ha flush",
2109 .short_help = "nat ha flush",
2110 .function = nat_ha_flush_command_fn,
2115 * @cliexstart{nat ha resync}
2116 * Resync HA (resend existing sessions to new failover)
2119 VLIB_CLI_COMMAND (nat_ha_resync_command, static) = {
2120 .path = "nat ha resync",
2121 .short_help = "nat ha resync",
2122 .function = nat_ha_resync_command_fn,
2127 * @cliexstart{show nat44 hash tables}
2128 * Show NAT44 hash tables
2131 VLIB_CLI_COMMAND (nat44_show_hash, static) = {
2132 .path = "show nat44 hash tables",
2133 .short_help = "show nat44 hash tables [detail|verbose]",
2134 .function = nat44_show_hash_commnad_fn,
2139 * @cliexstart{nat44 add address}
2140 * Add/delete NAT44 pool address.
2141 * To add NAT44 pool address use:
2142 * vpp# nat44 add address 172.16.1.3
2143 * vpp# nat44 add address 172.16.2.2 - 172.16.2.24
2144 * To add NAT44 pool address for specific tenant (identified by VRF id) use:
2145 * vpp# nat44 add address 172.16.1.3 tenant-vrf 10
2148 VLIB_CLI_COMMAND (add_address_command, static) = {
2149 .path = "nat44 add address",
2150 .short_help = "nat44 add address <ip4-range-start> [- <ip4-range-end>] "
2151 "[tenant-vrf <vrf-id>] [twice-nat] [del]",
2152 .function = add_address_command_fn,
2157 * @cliexstart{show nat44 addresses}
2158 * Show NAT44 pool addresses.
2159 * vpp# show nat44 addresses
2160 * NAT44 pool addresses:
2162 * tenant VRF independent
2171 * NAT44 twice-nat pool addresses:
2173 * tenant VRF independent
2179 VLIB_CLI_COMMAND (nat44_show_addresses_command, static) = {
2180 .path = "show nat44 addresses",
2181 .short_help = "show nat44 addresses",
2182 .function = nat44_show_addresses_command_fn,
2187 * @cliexstart{set interface nat44}
2188 * Enable/disable NAT44 feature on the interface.
2189 * To enable NAT44 feature with local network interface use:
2190 * vpp# set interface nat44 in GigabitEthernet0/8/0
2191 * To enable NAT44 feature with external network interface use:
2192 * vpp# set interface nat44 out GigabitEthernet0/a/0
2195 VLIB_CLI_COMMAND (set_interface_snat_command, static) = {
2196 .path = "set interface nat44",
2197 .function = snat_feature_command_fn,
2198 .short_help = "set interface nat44 in <intfc> out <intfc> [output-feature] "
2204 * @cliexstart{show nat44 interfaces}
2205 * Show interfaces with NAT44 feature.
2206 * vpp# show nat44 interfaces
2208 * GigabitEthernet0/8/0 in
2209 * GigabitEthernet0/a/0 out
2212 VLIB_CLI_COMMAND (nat44_show_interfaces_command, static) = {
2213 .path = "show nat44 interfaces",
2214 .short_help = "show nat44 interfaces",
2215 .function = nat44_show_interfaces_command_fn,
2220 * @cliexstart{nat44 add static mapping}
2221 * Static mapping allows hosts on the external network to initiate connection
2222 * to to the local network host.
2223 * To create static mapping between local host address 10.0.0.3 port 6303 and
2224 * external address 4.4.4.4 port 3606 for TCP protocol use:
2225 * vpp# nat44 add static mapping tcp local 10.0.0.3 6303 external 4.4.4.4 3606
2226 * If not runnig "static mapping only" NAT plugin mode use before:
2227 * vpp# nat44 add address 4.4.4.4
2228 * To create static mapping between local and external address use:
2229 * vpp# nat44 add static mapping local 10.0.0.3 external 4.4.4.4
2232 VLIB_CLI_COMMAND (add_static_mapping_command, static) = {
2233 .path = "nat44 add static mapping",
2234 .function = add_static_mapping_command_fn,
2236 "nat44 add static mapping tcp|udp|icmp local <addr> [<port>] "
2237 "external <addr> [<port>] [vrf <table-id>] [twice-nat|self-twice-nat] "
2238 "[out2in-only] [del]",
2243 * @cliexstart{nat44 add identity mapping}
2244 * Identity mapping translate an IP address to itself.
2245 * To create identity mapping for address 10.0.0.3 port 6303 for TCP protocol
2247 * vpp# nat44 add identity mapping 10.0.0.3 tcp 6303
2248 * To create identity mapping for address 10.0.0.3 use:
2249 * vpp# nat44 add identity mapping 10.0.0.3
2250 * To create identity mapping for DHCP addressed interface use:
2251 * vpp# nat44 add identity mapping external GigabitEthernet0/a/0 tcp 3606
2254 VLIB_CLI_COMMAND (add_identity_mapping_command, static) = {
2255 .path = "nat44 add identity mapping",
2256 .function = add_identity_mapping_command_fn,
2257 .short_help = "nat44 add identity mapping <ip4-addr>|external <interface> "
2258 "[<protocol> <port>] [vrf <table-id>] [del]",
2263 * @cliexstart{nat44 add load-balancing static mapping}
2264 * Service load balancing using NAT44
2265 * To add static mapping with load balancing for service with external IP
2266 * address 1.2.3.4 and TCP port 80 and mapped to 2 local servers
2267 * 10.100.10.10:8080 and 10.100.10.20:8080 with probability 80% resp. 20% use:
2268 * 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
2271 VLIB_CLI_COMMAND (add_lb_static_mapping_command, static) = {
2272 .path = "nat44 add load-balancing static mapping",
2273 .function = add_lb_static_mapping_command_fn,
2275 "nat44 add load-balancing static mapping protocol tcp|udp "
2276 "external <addr>:<port> local <addr>:<port> [vrf <table-id>] "
2277 "probability <n> [twice-nat|self-twice-nat] [out2in-only] "
2278 "[affinity <timeout-seconds>] [del]",
2283 * @cliexstart{nat44 add load-balancing static mapping}
2284 * Modify service load balancing using NAT44
2285 * To add new back-end server 10.100.10.30:8080 for service load balancing
2286 * static mapping with external IP address 1.2.3.4 and TCP port 80 use:
2287 * vpp# nat44 add load-balancing back-end protocol tcp external 1.2.3.4:80 local 10.100.10.30:8080 probability 25
2290 VLIB_CLI_COMMAND (add_lb_backend_command, static) = {
2291 .path = "nat44 add load-balancing back-end",
2292 .function = add_lb_backend_command_fn,
2294 "nat44 add load-balancing back-end protocol tcp|udp "
2295 "external <addr>:<port> local <addr>:<port> [vrf <table-id>] "
2296 "probability <n> [del]",
2301 * @cliexstart{show nat44 static mappings}
2302 * Show NAT44 static mappings.
2303 * vpp# show nat44 static mappings
2304 * NAT44 static mappings:
2305 * local 10.0.0.3 external 4.4.4.4 vrf 0
2306 * tcp local 192.168.0.4:6303 external 4.4.4.3:3606 vrf 0
2307 * tcp vrf 0 external 1.2.3.4:80 out2in-only
2308 * local 10.100.10.10:8080 probability 80
2309 * local 10.100.10.20:8080 probability 20
2310 * tcp local 10.100.3.8:8080 external 169.10.10.1:80 vrf 0 twice-nat
2311 * tcp local 10.0.0.10:3603 external GigabitEthernet0/a/0:6306 vrf 10
2314 VLIB_CLI_COMMAND (nat44_show_static_mappings_command, static) = {
2315 .path = "show nat44 static mappings",
2316 .short_help = "show nat44 static mappings",
2317 .function = nat44_show_static_mappings_command_fn,
2322 * @cliexstart{nat44 add interface address}
2323 * Use NAT44 pool address from specific interfce
2324 * To add NAT44 pool address from specific interface use:
2325 * vpp# nat44 add interface address GigabitEthernet0/8/0
2328 VLIB_CLI_COMMAND (snat_add_interface_address_command, static) = {
2329 .path = "nat44 add interface address",
2330 .short_help = "nat44 add interface address <interface> [twice-nat] [del]",
2331 .function = snat_add_interface_address_command_fn,
2336 * @cliexstart{show nat44 interface address}
2337 * Show NAT44 pool address interfaces
2338 * vpp# show nat44 interface address
2339 * NAT44 pool address interfaces:
2340 * GigabitEthernet0/a/0
2341 * NAT44 twice-nat pool address interfaces:
2342 * GigabitEthernet0/8/0
2345 VLIB_CLI_COMMAND (nat44_show_interface_address_command, static) = {
2346 .path = "show nat44 interface address",
2347 .short_help = "show nat44 interface address",
2348 .function = nat44_show_interface_address_command_fn,
2353 * @cliexstart{show nat44 sessions}
2354 * Show NAT44 sessions.
2357 VLIB_CLI_COMMAND (nat44_show_sessions_command, static) = {
2358 .path = "show nat44 sessions",
2359 .short_help = "show nat44 sessions [detail]",
2360 .function = nat44_show_sessions_command_fn,
2365 * @cliexstart{nat44 del session}
2366 * To administratively delete NAT44 session by inside address and port use:
2367 * vpp# nat44 del session in 10.0.0.3:6303 tcp
2368 * To administratively delete NAT44 session by outside address and port use:
2369 * vpp# nat44 del session out 1.0.0.3:6033 udp
2372 VLIB_CLI_COMMAND (nat44_del_session_command, static) = {
2373 .path = "nat44 del session",
2374 .short_help = "nat44 del session in|out <addr>:<port> tcp|udp|icmp [vrf <id>] [external-host <addr>:<port>]",
2375 .function = nat44_del_session_command_fn,
2380 * @cliexstart{nat44 forwarding}
2381 * Enable or disable forwarding
2382 * Forward packets which don't match existing translation
2383 * or static mapping instead of dropping them.
2384 * To enable forwarding, use:
2385 * vpp# nat44 forwarding enable
2386 * To disable forwarding, use:
2387 * vpp# nat44 forwarding disable
2390 VLIB_CLI_COMMAND (snat_forwarding_set_command, static) = {
2391 .path = "nat44 forwarding",
2392 .short_help = "nat44 forwarding enable|disable",
2393 .function = snat_forwarding_set_command_fn,
2398 * @cliexstart{nat44 deterministic add}
2399 * Create bijective mapping of inside address to outside address and port range
2400 * pairs, with the purpose of enabling deterministic NAT to reduce logging in
2402 * To create deterministic mapping between inside network 10.0.0.0/18 and
2403 * outside network 1.1.1.0/30 use:
2404 * # vpp# nat44 deterministic add in 10.0.0.0/18 out 1.1.1.0/30
2407 VLIB_CLI_COMMAND (snat_det_map_command, static) = {
2408 .path = "nat44 deterministic add",
2409 .short_help = "nat44 deterministic add in <addr>/<plen> out <addr>/<plen> [del]",
2410 .function = snat_det_map_command_fn,
2415 * @cliexpstart{show nat44 deterministic mappings}
2416 * Show NAT44 deterministic mappings
2417 * vpp# show nat44 deterministic mappings
2418 * NAT44 deterministic mappings:
2419 * in 10.0.0.0/24 out 1.1.1.1/32
2420 * outside address sharing ratio: 256
2421 * number of ports per inside host: 252
2422 * sessions number: 0
2425 VLIB_CLI_COMMAND (nat44_det_show_mappings_command, static) = {
2426 .path = "show nat44 deterministic mappings",
2427 .short_help = "show nat44 deterministic mappings",
2428 .function = nat44_det_show_mappings_command_fn,
2433 * @cliexstart{nat44 deterministic forward}
2434 * Return outside address and port range from inside address for deterministic
2436 * To obtain outside address and port of inside host use:
2437 * vpp# nat44 deterministic forward 10.0.0.2
2438 * 1.1.1.0:<1054-1068>
2441 VLIB_CLI_COMMAND (snat_det_forward_command, static) = {
2442 .path = "nat44 deterministic forward",
2443 .short_help = "nat44 deterministic forward <addr>",
2444 .function = snat_det_forward_command_fn,
2449 * @cliexstart{nat44 deterministic reverse}
2450 * Return inside address from outside address and port for deterministic NAT.
2451 * To obtain inside host address from outside address and port use:
2452 * #vpp nat44 deterministic reverse 1.1.1.1:1276
2456 VLIB_CLI_COMMAND (snat_det_reverse_command, static) = {
2457 .path = "nat44 deterministic reverse",
2458 .short_help = "nat44 deterministic reverse <addr>:<port>",
2459 .function = snat_det_reverse_command_fn,
2464 * @cliexstart{show nat44 deterministic sessions}
2465 * Show NAT44 deterministic sessions.
2466 * vpp# show nat44 deterministic sessions
2467 * NAT44 deterministic sessions:
2468 * in 10.0.0.3:3005 out 1.1.1.2:1146 external host 172.16.1.2:3006 state: udp-active expire: 306
2469 * in 10.0.0.3:3000 out 1.1.1.2:1141 external host 172.16.1.2:3001 state: udp-active expire: 306
2470 * in 10.0.0.4:3005 out 1.1.1.2:1177 external host 172.16.1.2:3006 state: udp-active expire: 306
2473 VLIB_CLI_COMMAND (nat44_det_show_sessions_command, static) = {
2474 .path = "show nat44 deterministic sessions",
2475 .short_help = "show nat44 deterministic sessions",
2476 .function = nat44_det_show_sessions_command_fn,
2481 * @cliexstart{nat44 deterministic close session out}
2482 * Close session using outside ip address and port
2483 * and external ip address and port, use:
2484 * vpp# nat44 deterministic close session out 1.1.1.1:1276 2.2.2.2:2387
2487 VLIB_CLI_COMMAND (snat_det_close_sesion_out_command, static) = {
2488 .path = "nat44 deterministic close session out",
2489 .short_help = "nat44 deterministic close session out "
2490 "<out_addr>:<out_port> <ext_addr>:<ext_port>",
2491 .function = snat_det_close_session_out_fn,
2496 * @cliexstart{nat44 deterministic close session in}
2497 * Close session using inside ip address and port
2498 * and external ip address and port, use:
2499 * vpp# nat44 deterministic close session in 3.3.3.3:3487 2.2.2.2:2387
2502 VLIB_CLI_COMMAND (snat_det_close_session_in_command, static) = {
2503 .path = "nat44 deterministic close session in",
2504 .short_help = "nat44 deterministic close session in "
2505 "<in_addr>:<in_port> <ext_addr>:<ext_port>",
2506 .function = snat_det_close_session_in_fn,
2512 * fd.io coding-style-patch-verification: ON
2515 * eval: (c-set-style "gnu")