diff options
Diffstat (limited to 'src/plugins/nat/nat44-ed/nat44_ed_cli.c')
-rw-r--r-- | src/plugins/nat/nat44-ed/nat44_ed_cli.c | 708 |
1 files changed, 468 insertions, 240 deletions
diff --git a/src/plugins/nat/nat44-ed/nat44_ed_cli.c b/src/plugins/nat/nat44-ed/nat44_ed_cli.c index e9be7eb051f..14313d05a35 100644 --- a/src/plugins/nat/nat44-ed/nat44_ed_cli.c +++ b/src/plugins/nat/nat44-ed/nat44_ed_cli.c @@ -38,23 +38,15 @@ nat44_ed_enable_disable_command_fn (vlib_main_t *vm, unformat_input_t *input, clib_error_t *error = 0; nat44_config_t c = { 0 }; - u8 enable_set = 0, enable = 0, mode_set = 0; + u8 enable_set = 0, enable = 0; if (!unformat_user (input, unformat_line_input, line_input)) return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT); while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) { - if (!mode_set && unformat (line_input, "static-mapping-only")) - { - mode_set = 1; - c.static_mapping_only = 1; - if (unformat (line_input, "connection-tracking")) - { - c.connection_tracking = 1; - } - } - else if (unformat (line_input, "inside-vrf %u", &c.inside_vrf)); + if (unformat (line_input, "inside-vrf %u", &c.inside_vrf)) + ; else if (unformat (line_input, "outside-vrf %u", &c.outside_vrf)); else if (unformat (line_input, "sessions %u", &c.sessions)); else if (!enable_set) @@ -116,7 +108,6 @@ set_workers_command_fn (vlib_main_t * vm, int rv = 0; clib_error_t *error = 0; - /* Get a line of input. */ if (!unformat_user (input, unformat_line_input, line_input)) return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT); @@ -162,8 +153,8 @@ done: } static clib_error_t * -nat_show_workers_commnad_fn (vlib_main_t * vm, unformat_input_t * input, - vlib_cli_command_t * cmd) +nat_show_workers_command_fn (vlib_main_t *vm, unformat_input_t *input, + vlib_cli_command_t *cmd) { snat_main_t *sm = &snat_main; u32 *worker; @@ -189,10 +180,9 @@ snat_set_log_level_command_fn (vlib_main_t * vm, { unformat_input_t _line_input, *line_input = &_line_input; snat_main_t *sm = &snat_main; - u8 log_level = NAT_LOG_NONE; + u32 log_level = NAT_LOG_NONE; clib_error_t *error = 0; - /* Get a line of input. */ if (!unformat_user (input, unformat_line_input, line_input)) return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT); @@ -283,12 +273,7 @@ nat44_show_hash_command_fn (vlib_main_t * vm, unformat_input_t * input, else if (unformat (input, "verbose")) verbose = 2; - vlib_cli_output (vm, "%U", format_bihash_8_8, &sm->static_mapping_by_local, - verbose); - vlib_cli_output (vm, "%U", - format_bihash_8_8, &sm->static_mapping_by_external, - verbose); - vlib_cli_output (vm, "%U", format_bihash_16_8, &sm->flow_hash, verbose); + vlib_cli_output (vm, "%U", format_bihash_16_8, &sm->flow_hash, verbose); vec_foreach_index (i, sm->per_thread_data) { vlib_cli_output (vm, "-------- thread %d %s --------\n", @@ -296,8 +281,7 @@ nat44_show_hash_command_fn (vlib_main_t * vm, unformat_input_t * input, vlib_cli_output (vm, "%U", format_bihash_16_8, &sm->flow_hash, verbose); } - vlib_cli_output (vm, "%U", format_bihash_16_8, &nam->affinity_hash, - verbose); + vlib_cli_output (vm, "%U", format_bihash_16_8, &nam->affinity_hash, verbose); vlib_cli_output (vm, "-------- hash table parameters --------\n"); vlib_cli_output (vm, "translation buckets: %u", sm->translation_buckets); @@ -313,7 +297,6 @@ nat_set_mss_clamping_command_fn (vlib_main_t * vm, unformat_input_t * input, clib_error_t *error = 0; u32 mss; - /* Get a line of input. */ if (!unformat_user (input, unformat_line_input, line_input)) return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT); @@ -356,7 +339,6 @@ add_address_command_fn (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { unformat_input_t _line_input, *line_input = &_line_input; - snat_main_t *sm = &snat_main; ip4_address_t start_addr, end_addr, this_addr; u32 start_host_order, end_host_order; u32 vrf_id = ~0; @@ -366,7 +348,6 @@ add_address_command_fn (vlib_main_t * vm, clib_error_t *error = 0; u8 twice_nat = 0; - /* Get a line of input. */ if (!unformat_user (input, unformat_line_input, line_input)) return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT); @@ -392,12 +373,6 @@ add_address_command_fn (vlib_main_t * vm, } } - if (sm->static_mapping_only) - { - error = clib_error_return (0, "static mapping only mode"); - goto done; - } - start_host_order = clib_host_to_net_u32 (start_addr.as_u32); end_host_order = clib_host_to_net_u32 (end_addr.as_u32); @@ -424,7 +399,7 @@ add_address_command_fn (vlib_main_t * vm, } else { - rv = nat44_ed_del_address (this_addr, 0, twice_nat); + rv = nat44_ed_del_address (this_addr, twice_nat); } switch (rv) @@ -499,15 +474,12 @@ nat44_show_summary_command_fn (vlib_main_t * vm, unformat_input_t * input, u64 now = vlib_time_now (vm); u64 sess_timeout_time = 0; - u32 udp_sessions = 0; - u32 tcp_sessions = 0; - u32 icmp_sessions = 0; - - u32 timed_out = 0; - u32 transitory = 0; - u32 transitory_wait_closed = 0; - u32 transitory_closed = 0; - u32 established = 0; + struct + { + u32 total; + u32 timed_out; + } udp = { 0 }, tcp = { 0 }, tcp_established = { 0 }, tcp_transitory = { 0 }, + icmp = { 0 }, other = { 0 }; u32 fib; @@ -521,45 +493,48 @@ nat44_show_summary_command_fn (vlib_main_t * vm, unformat_input_t * input, { pool_foreach (s, tsm->sessions) { - sess_timeout_time = s->last_heard + - (f64) nat44_session_get_timeout (sm, s); - if (now >= sess_timeout_time) - timed_out++; - - switch (s->nat_proto) - { - case NAT_PROTOCOL_ICMP: - icmp_sessions++; - break; - case NAT_PROTOCOL_TCP: - tcp_sessions++; - if (s->state) - { - if (s->tcp_closed_timestamp) - { - if (now >= s->tcp_closed_timestamp) - { - ++transitory_closed; - } - else - { - ++transitory_wait_closed; - } - } - transitory++; - } - else - established++; - break; - case NAT_PROTOCOL_UDP: - default: - udp_sessions++; - break; - } - } - nat44_show_lru_summary (vm, tsm, now, sess_timeout_time); - count += pool_elts (tsm->sessions); - } + sess_timeout_time = + s->last_heard + (f64) nat44_session_get_timeout (sm, s); + + switch (s->proto) + { + case IP_PROTOCOL_ICMP: + ++icmp.total; + if (now >= sess_timeout_time) + ++icmp.timed_out; + break; + case IP_PROTOCOL_TCP: + ++tcp.total; + if (now >= sess_timeout_time) + ++tcp.timed_out; + if (nat44_ed_tcp_is_established (s->tcp_state)) + { + ++tcp_established.total; + if (now >= sess_timeout_time) + ++tcp_established.timed_out; + } + else + { + ++tcp_transitory.total; + if (now >= sess_timeout_time) + ++tcp_transitory.timed_out; + } + break; + case IP_PROTOCOL_UDP: + ++udp.total; + if (now >= sess_timeout_time) + ++udp.timed_out; + break; + default: + ++other.total; + if (now >= sess_timeout_time) + ++other.timed_out; + break; + } + } + nat44_show_lru_summary (vm, tsm, now, sess_timeout_time); + count += pool_elts (tsm->sessions); + } } else { @@ -568,55 +543,66 @@ nat44_show_summary_command_fn (vlib_main_t * vm, unformat_input_t * input, { sess_timeout_time = s->last_heard + (f64) nat44_session_get_timeout (sm, s); - if (now >= sess_timeout_time) - timed_out++; - - switch (s->nat_proto) - { - case NAT_PROTOCOL_ICMP: - icmp_sessions++; - break; - case NAT_PROTOCOL_TCP: - tcp_sessions++; - if (s->state) - { - if (s->tcp_closed_timestamp) - { - if (now >= s->tcp_closed_timestamp) - { - ++transitory_closed; - } - else - { - ++transitory_wait_closed; - } - } - transitory++; - } - else - established++; - break; - case NAT_PROTOCOL_UDP: - default: - udp_sessions++; - break; - } + + switch (s->proto) + { + case IP_PROTOCOL_ICMP: + ++icmp.total; + if (now >= sess_timeout_time) + ++icmp.timed_out; + break; + case IP_PROTOCOL_TCP: + ++tcp.total; + if (now >= sess_timeout_time) + ++tcp.timed_out; + if (nat44_ed_tcp_is_established (s->tcp_state)) + { + ++tcp_established.total; + if (now >= sess_timeout_time) + ++tcp_established.timed_out; + } + else + { + ++tcp_transitory.total; + if (now >= sess_timeout_time) + ++tcp_transitory.timed_out; + } + break; + case IP_PROTOCOL_UDP: + ++udp.total; + if (now >= sess_timeout_time) + ++udp.timed_out; + break; + default: + ++other.total; + if (now >= sess_timeout_time) + ++other.timed_out; + break; + } } nat44_show_lru_summary (vm, tsm, now, sess_timeout_time); count = pool_elts (tsm->sessions); } - vlib_cli_output (vm, "total timed out sessions: %u", timed_out); - vlib_cli_output (vm, "total sessions: %u", count); - vlib_cli_output (vm, "total tcp sessions: %u", tcp_sessions); - vlib_cli_output (vm, "total tcp established sessions: %u", established); - vlib_cli_output (vm, "total tcp transitory sessions: %u", transitory); - vlib_cli_output (vm, "total tcp transitory (WAIT-CLOSED) sessions: %u", - transitory_wait_closed); - vlib_cli_output (vm, "total tcp transitory (CLOSED) sessions: %u", - transitory_closed); - vlib_cli_output (vm, "total udp sessions: %u", udp_sessions); - vlib_cli_output (vm, "total icmp sessions: %u", icmp_sessions); + u32 timed_out = + tcp.timed_out + icmp.timed_out + udp.timed_out + other.timed_out; + vlib_cli_output (vm, "total sessions: %u (timed out: %u)", count, timed_out); + vlib_cli_output (vm, "tcp sessions:"); + vlib_cli_output (vm, " total: %u (timed out: %u)", tcp.total, + tcp.timed_out); + vlib_cli_output (vm, " established: %u (timed out: %u)", + tcp_established.total, tcp_established.timed_out); + vlib_cli_output (vm, " transitory: %u (timed out: %u)", + tcp_transitory.total, tcp_transitory.timed_out); + vlib_cli_output (vm, "udp sessions:"); + vlib_cli_output (vm, " total: %u (timed out: %u)", udp.total, + udp.timed_out); + vlib_cli_output (vm, "icmp sessions:"); + vlib_cli_output (vm, " total: %u (timed out: %u)", icmp.total, + icmp.timed_out); + vlib_cli_output (vm, "other sessions:"); + vlib_cli_output (vm, " total: %u (timed out: %u)", other.total, + other.timed_out); return 0; } @@ -632,14 +618,14 @@ nat44_show_addresses_command_fn (vlib_main_t * vm, unformat_input_t * input, { vlib_cli_output (vm, "%U", format_ip4_address, &ap->addr); if (ap->fib_index != ~0) - vlib_cli_output (vm, " tenant VRF: %u", - fib_table_get(ap->fib_index, FIB_PROTOCOL_IP4)->ft_table_id); + vlib_cli_output ( + vm, " tenant VRF: %u", + fib_table_get (ap->fib_index, FIB_PROTOCOL_IP4)->ft_table_id); else vlib_cli_output (vm, " tenant VRF independent"); - #define _(N, i, n, s) \ - vlib_cli_output (vm, " %d busy %s ports", ap->busy_##n##_ports, s); - foreach_nat_protocol - #undef _ + + if (ap->addr_len != ~0) + vlib_cli_output (vm, " synced with interface address"); } vlib_cli_output (vm, "NAT44 twice-nat pool addresses:"); vec_foreach (ap, sm->twice_nat_addresses) @@ -650,10 +636,9 @@ nat44_show_addresses_command_fn (vlib_main_t * vm, unformat_input_t * input, fib_table_get(ap->fib_index, FIB_PROTOCOL_IP4)->ft_table_id); else vlib_cli_output (vm, " tenant VRF independent"); - #define _(N, i, n, s) \ - vlib_cli_output (vm, " %d busy %s ports", ap->busy_##n##_ports, s); - foreach_nat_protocol - #undef _ + + if (ap->addr_len != ~0) + vlib_cli_output (vm, " synced with interface address"); } return 0; } @@ -673,7 +658,6 @@ snat_feature_command_fn (vlib_main_t * vm, sw_if_index = ~0; - /* Get a line of input. */ if (!unformat_user (input, unformat_line_input, line_input)) return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT); @@ -837,14 +821,13 @@ add_static_mapping_command_fn (vlib_main_t * vm, unformat_input_t _line_input, *line_input = &_line_input; vnet_main_t *vnm = vnet_get_main (); clib_error_t *error = 0; - int rv; - - nat_protocol_t proto = NAT_PROTOCOL_OTHER; ip4_address_t l_addr, e_addr, pool_addr; u32 l_port = 0, e_port = 0, vrf_id = ~0; u8 l_port_set = 0, e_port_set = 0; - u32 sw_if_index, flags = 0; - int is_add = 1; + int is_add = 1, rv; + u32 flags = 0; + u32 sw_if_index = ~0; + ip_protocol_t proto = 0; if (!unformat_user (input, unformat_line_input, line_input)) return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT); @@ -886,7 +869,7 @@ add_static_mapping_command_fn (vlib_main_t * vm, } else if (unformat (line_input, "vrf %u", &vrf_id)) ; - else if (unformat (line_input, "%U", unformat_nat_protocol, &proto)) + else if (unformat (line_input, "%U", unformat_ip_protocol, &proto)) ; else if (unformat (line_input, "self-twice-nat")) { @@ -928,8 +911,6 @@ add_static_mapping_command_fn (vlib_main_t * vm, e_port = clib_host_to_net_u16 (e_port); } - // TODO: specific pool_addr for both pool & twice nat pool ? - if (is_add) { rv = @@ -942,25 +923,17 @@ add_static_mapping_command_fn (vlib_main_t * vm, vrf_id, sw_if_index, flags); } - // TODO: fix returns - switch (rv) { - case VNET_API_ERROR_INVALID_VALUE: - error = clib_error_return (0, "External port already in use."); - goto done; + case VNET_API_ERROR_UNSUPPORTED: + error = clib_error_return (0, "Plugin disabled."); + break; case VNET_API_ERROR_NO_SUCH_ENTRY: - if (is_add) - error = clib_error_return (0, "External address must be allocated."); - else - error = clib_error_return (0, "Mapping not exist."); - goto done; - case VNET_API_ERROR_NO_SUCH_FIB: - error = clib_error_return (0, "No such VRF id."); - goto done; + error = clib_error_return (0, "Mapping not exist."); + break; case VNET_API_ERROR_VALUE_EXIST: error = clib_error_return (0, "Mapping already exist."); - goto done; + break; default: break; } @@ -971,7 +944,6 @@ done: return error; } -// TODO: either delete this bullshit or update it static clib_error_t * add_identity_mapping_command_fn (vlib_main_t * vm, unformat_input_t * input, @@ -983,12 +955,11 @@ add_identity_mapping_command_fn (vlib_main_t * vm, int rv, is_add = 1, port_set = 0; u32 sw_if_index, port, flags, vrf_id = ~0; - nat_protocol_t proto; + ip_protocol_t proto = 0; ip4_address_t addr; flags = NAT_SM_FLAG_IDENTITY_NAT; - /* Get a line of input. */ if (!unformat_user (input, unformat_line_input, line_input)) return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT); @@ -1003,7 +974,7 @@ add_identity_mapping_command_fn (vlib_main_t * vm, } else if (unformat (line_input, "vrf %u", &vrf_id)) ; - else if (unformat (line_input, "%U %u", unformat_nat_protocol, &proto, + else if (unformat (line_input, "%U %u", unformat_ip_protocol, &proto, &port)) { port_set = 1; @@ -1041,25 +1012,17 @@ add_identity_mapping_command_fn (vlib_main_t * vm, sw_if_index, flags); } - // TODO: fix returns - switch (rv) { - case VNET_API_ERROR_INVALID_VALUE: - error = clib_error_return (0, "External port already in use."); - goto done; + case VNET_API_ERROR_UNSUPPORTED: + error = clib_error_return (0, "Plugin disabled."); + break; case VNET_API_ERROR_NO_SUCH_ENTRY: - if (is_add) - error = clib_error_return (0, "External address must be allocated."); - else - error = clib_error_return (0, "Mapping not exist."); - goto done; - case VNET_API_ERROR_NO_SUCH_FIB: - error = clib_error_return (0, "No such VRF id."); - goto done; + error = clib_error_return (0, "Mapping not exist."); + break; case VNET_API_ERROR_VALUE_EXIST: error = clib_error_return (0, "Mapping already exist."); - goto done; + break; default: break; } @@ -1080,12 +1043,11 @@ add_lb_static_mapping_command_fn (vlib_main_t * vm, ip4_address_t l_addr, e_addr; u32 l_port = 0, e_port = 0, vrf_id = 0, probability = 0, affinity = 0; u8 proto_set = 0; - nat_protocol_t proto; + ip_protocol_t proto; nat44_lb_addr_port_t *locals = 0, local; int rv, is_add = 1; u32 flags = 0; - /* Get a line of input. */ if (!unformat_user (input, unformat_line_input, line_input)) return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT); @@ -1096,6 +1058,7 @@ add_lb_static_mapping_command_fn (vlib_main_t * vm, { clib_memset (&local, 0, sizeof (local)); local.addr = l_addr; + l_port = clib_host_to_net_u16 (l_port); local.port = (u16) l_port; local.probability = (u8) probability; vec_add1 (locals, local); @@ -1106,6 +1069,7 @@ add_lb_static_mapping_command_fn (vlib_main_t * vm, { clib_memset (&local, 0, sizeof (local)); local.addr = l_addr; + l_port = clib_host_to_net_u16 (l_port); local.port = (u16) l_port; local.probability = (u8) probability; local.vrf_id = vrf_id; @@ -1113,8 +1077,10 @@ add_lb_static_mapping_command_fn (vlib_main_t * vm, } else if (unformat (line_input, "external %U:%u", unformat_ip4_address, &e_addr, &e_port)) - ; - else if (unformat (line_input, "protocol %U", unformat_nat_protocol, + { + e_port = clib_host_to_net_u16 (e_port); + } + else if (unformat (line_input, "protocol %U", unformat_ip_protocol, &proto)) { proto_set = 1; @@ -1202,10 +1168,9 @@ add_lb_backend_command_fn (vlib_main_t * vm, u32 l_port = 0, e_port = 0, vrf_id = 0, probability = 0; int is_add = 1; int rv; - nat_protocol_t proto; + ip_protocol_t proto; u8 proto_set = 0; - /* Get a line of input. */ if (!unformat_user (input, unformat_line_input, line_input)) return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT); @@ -1221,7 +1186,7 @@ add_lb_backend_command_fn (vlib_main_t * vm, else if (unformat (line_input, "external %U:%u", unformat_ip4_address, &e_addr, &e_port)) ; - else if (unformat (line_input, "protocol %U", unformat_nat_protocol, + else if (unformat (line_input, "protocol %U", unformat_ip_protocol, &proto)) proto_set = 1; else if (unformat (line_input, "del")) @@ -1281,14 +1246,14 @@ nat44_show_static_mappings_command_fn (vlib_main_t * vm, { snat_main_t *sm = &snat_main; snat_static_mapping_t *m; - snat_static_map_resolve_t *rp; + snat_static_mapping_resolve_t *rp; vlib_cli_output (vm, "NAT44 static mappings:"); pool_foreach (m, sm->static_mappings) { vlib_cli_output (vm, " %U", format_snat_static_mapping, m); } - vec_foreach (rp, sm->to_resolve) + vec_foreach (rp, sm->sm_to_resolve) vlib_cli_output (vm, " %U", format_snat_static_map_to_resolve, rp); return 0; @@ -1300,19 +1265,21 @@ snat_add_interface_address_command_fn (vlib_main_t * vm, vlib_cli_command_t * cmd) { unformat_input_t _line_input, *line_input = &_line_input; - snat_main_t *sm = &snat_main; + vnet_main_t *vnm = vnet_get_main (); clib_error_t *error = 0; int rv, is_del = 0; u8 twice_nat = 0; u32 sw_if_index; + sw_if_index = ~0; + if (!unformat_user (input, unformat_line_input, line_input)) return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT); while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) { - if (unformat (line_input, "%U", unformat_vnet_sw_interface, - sm->vnet_main, &sw_if_index)) + if (unformat (line_input, "%U", unformat_vnet_sw_interface, vnm, + &sw_if_index)) ; else if (unformat (line_input, "twice-nat")) { @@ -1330,21 +1297,149 @@ snat_add_interface_address_command_fn (vlib_main_t * vm, } } - if (!is_del) + if (is_del) + { + rv = nat44_ed_del_interface_address (sw_if_index, twice_nat); + } + else { rv = nat44_ed_add_interface_address (sw_if_index, twice_nat); - if (rv) + } + + if (0 != rv) + { + error = + clib_error_return (0, "%s %U address failed", is_del ? "del" : "add", + format_vnet_sw_if_index_name, vnm, sw_if_index); + goto done; + } + +done: + unformat_free (line_input); + + return error; +} + +static clib_error_t * +nat44_ed_add_del_vrf_table_command_fn (vlib_main_t *vm, + unformat_input_t *input, + vlib_cli_command_t *cmd) +{ + unformat_input_t _line_input, *line_input = &_line_input; + clib_error_t *error = 0; + bool is_add = true, not_set = true; + u32 vrf_id = ~0; + int rv; + + if (!unformat_user (input, unformat_line_input, line_input)) + return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT); + + while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (line_input, "%u", &vrf_id)) + ; + else if (not_set) + { + if (unformat (line_input, "add")) + { + is_add = true; + } + else if (unformat (line_input, "del")) + { + is_add = false; + } + not_set = false; + } + else { - error = clib_error_return (0, "add address returned %d", rv); + error = clib_error_return (0, "unknown input '%U'", + format_unformat_error, line_input); + goto done; } } - else + + if (not_set) { - rv = nat44_ed_del_interface_address (sw_if_index, twice_nat); - if (rv) + error = clib_error_return (0, "missing required parameter"); + goto done; + } + + if (~0 == vrf_id) + { + error = clib_error_return (0, "missing vrf id"); + goto done; + } + + rv = nat44_ed_add_del_vrf_table (vrf_id, is_add); + if (rv) + { + error = clib_error_return (0, "%s vrf table returned %d", + is_add ? "add" : "del", rv); + } + +done: + unformat_free (line_input); + + return error; +} + +static clib_error_t * +nat44_ed_add_del_vrf_route_command_fn (vlib_main_t *vm, + unformat_input_t *input, + vlib_cli_command_t *cmd) +{ + unformat_input_t _line_input, *line_input = &_line_input; + clib_error_t *error = 0; + bool is_add = true, not_set = true; + u32 vrf_id = ~0, table_vrf_id = ~0; + int rv; + + if (!unformat_user (input, unformat_line_input, line_input)) + return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT); + + while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (line_input, "table %u", &table_vrf_id)) + ; + else if (unformat (line_input, "%u", &vrf_id)) + ; + else if (not_set) { - error = clib_error_return (0, "del address returned %d", rv); + if (unformat (line_input, "add")) + { + is_add = true; + } + else if (unformat (line_input, "del")) + { + is_add = false; + } + not_set = false; } + else + { + error = clib_error_return (0, "unknown input '%U'", + format_unformat_error, line_input); + goto done; + } + } + + if (not_set) + { + error = clib_error_return (0, "missing required parameter"); + goto done; + } + + if ((~0 == vrf_id) || (~0 == table_vrf_id)) + { + error = clib_error_return (0, "missing vrf id"); + goto done; + } + + rv = nat44_ed_add_del_vrf_route (table_vrf_id, vrf_id, is_add); + if (rv) + { + error = clib_error_return (0, "%s vrf table returned %d", + is_add ? "add" : "del", rv); } done: @@ -1354,27 +1449,42 @@ done: } static clib_error_t * +nat44_ed_show_vrf_tables_command_fn (vlib_main_t *vm, unformat_input_t *input, + vlib_cli_command_t *cmd) +{ + snat_main_t *sm = &snat_main; + vrf_table_t *t; + vrf_route_t *r; + int i = 0; + + pool_foreach (t, sm->vrf_tables) + { + vlib_cli_output (vm, "table %u:", t->table_vrf_id); + pool_foreach (r, t->routes) + { + vlib_cli_output (vm, "[%u] vrf-id %u", i, r->vrf_id); + i++; + } + } + + return 0; +} + +static clib_error_t * nat44_show_interface_address_command_fn (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { snat_main_t *sm = &snat_main; vnet_main_t *vnm = vnet_get_main (); - u32 *sw_if_index; + snat_address_resolve_t *ap; vlib_cli_output (vm, "NAT44 pool address interfaces:"); - vec_foreach (sw_if_index, sm->auto_add_sw_if_indices) - { - vlib_cli_output (vm, " %U", format_vnet_sw_if_index_name, vnm, - *sw_if_index); - } - vlib_cli_output (vm, "NAT44 twice-nat pool address interfaces:"); - vec_foreach (sw_if_index, sm->auto_add_sw_if_indices_twice_nat) + vec_foreach (ap, sm->addr_to_resolve) { - vlib_cli_output (vm, " %U", format_vnet_sw_if_index_name, vnm, - *sw_if_index); + vlib_cli_output (vm, " %U%s", format_vnet_sw_if_index_name, vnm, + ap->sw_if_index, ap->is_twice_nat ? " twice-nat" : ""); } - return 0; } @@ -1386,22 +1496,61 @@ nat44_show_sessions_command_fn (vlib_main_t * vm, unformat_input_t * input, clib_error_t *error = 0; snat_main_per_thread_data_t *tsm; snat_main_t *sm = &snat_main; - - int i = 0; + ip4_address_t i2o_sa, i2o_da, o2i_sa, o2i_da; + u8 filter_i2o_sa = 0, filter_i2o_da = 0; + u8 filter_o2i_sa = 0, filter_o2i_da = 0; + u16 i2o_sp, i2o_dp, o2i_sp, o2i_dp; + u8 filter_i2o_sp = 0, filter_i2o_dp = 0; + u8 filter_o2i_sp = 0, filter_o2i_dp = 0; + ip_protocol_t proto; + u8 filter_proto = 0; + u8 had_input = 1, filtering = 0; + int i = 0, showed_sessions; if (!unformat_user (input, unformat_line_input, line_input)) - goto print; + { + had_input = 0; + goto print; + } while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) { - error = clib_error_return (0, "unknown input '%U'", - format_unformat_error, line_input); - break; + if (unformat (line_input, "filter i2o saddr %U", unformat_ip4_address, + &i2o_sa)) + filter_i2o_sa = filtering = 1; + else if (unformat (line_input, "filter i2o daddr %U", + unformat_ip4_address, &i2o_da)) + filter_i2o_da = filtering = 1; + else if (unformat (line_input, "filter o2i saddr %U", + unformat_ip4_address, &o2i_sa)) + filter_o2i_sa = filtering = 1; + else if (unformat (line_input, "filter o2i daddr %U", + unformat_ip4_address, &o2i_da)) + filter_o2i_da = filtering = 1; + else if (unformat (line_input, "filter i2o sport %u", &i2o_sp)) + filter_i2o_sp = filtering = 1; + else if (unformat (line_input, "filter i2o dport %u", &i2o_dp)) + filter_i2o_dp = filtering = 1; + else if (unformat (line_input, "filter o2i sport %u", &o2i_sp)) + filter_o2i_sp = filtering = 1; + else if (unformat (line_input, "filter o2i dport %u", &o2i_dp)) + filter_o2i_dp = filtering = 1; + else if (unformat (line_input, "filter i2o proto %U", + unformat_ip_protocol, &proto)) + filter_proto = filtering = 1; + else if (unformat (line_input, "filter o2i proto %U", + unformat_ip_protocol, &proto)) + filter_proto = filtering = 1; + else + { + error = clib_error_return (0, "unknown input '%U'", + format_unformat_error, line_input); + goto done; + } } - unformat_free (line_input); print: - vlib_cli_output (vm, "NAT44 ED sessions:"); + vlib_cli_output (vm, "NAT44 ED sessions:"); vec_foreach_index (i, sm->per_thread_data) { @@ -1411,12 +1560,53 @@ print: i, vlib_worker_threads[i].name, pool_elts (tsm->sessions)); - snat_session_t *s; - pool_foreach (s, tsm->sessions) - { - vlib_cli_output (vm, " %U\n", format_snat_session, tsm, s); - } + showed_sessions = 0; + snat_session_t *s; + pool_foreach (s, tsm->sessions) + { + if (filtering) + { + if (filter_i2o_sa && i2o_sa.as_u32 != s->i2o.match.saddr.as_u32) + continue; + if (filter_i2o_da && i2o_da.as_u32 != s->i2o.match.daddr.as_u32) + continue; + if (filter_o2i_sa && o2i_sa.as_u32 != s->o2i.match.saddr.as_u32) + continue; + if (filter_o2i_da && o2i_da.as_u32 != s->o2i.match.daddr.as_u32) + continue; + if (filter_i2o_sp && + i2o_sp != clib_net_to_host_u16 (s->i2o.match.sport)) + continue; + if (filter_i2o_dp && + i2o_dp != clib_net_to_host_u16 (s->i2o.match.dport)) + continue; + if (filter_o2i_sp && + o2i_sp != clib_net_to_host_u16 (s->o2i.match.sport)) + continue; + if (filter_o2i_dp && + o2i_dp != clib_net_to_host_u16 (s->o2i.match.dport)) + continue; + if (filter_proto && proto != s->proto) + continue; + showed_sessions++; + } + vlib_cli_output (vm, " %U\n", format_snat_session, sm, tsm, s, + vlib_time_now (vm)); + } + if (filtering) + { + vlib_cli_output (vm, + "Showed: %d, Filtered: %d of total %d " + "sessions of thread %d\n\n", + showed_sessions, + pool_elts (tsm->sessions) - showed_sessions, + pool_elts (tsm->sessions), i); + } } + +done: + if (had_input) + unformat_free (line_input); return error; } @@ -1468,7 +1658,7 @@ nat44_del_session_command_fn (vlib_main_t * vm, u32 port = 0, eh_port = 0, vrf_id = sm->outside_vrf_id; clib_error_t *error = 0; ip4_address_t addr, eh_addr; - nat_protocol_t proto; + ip_protocol_t proto; int is_in = 0; int rv; @@ -1477,9 +1667,8 @@ nat44_del_session_command_fn (vlib_main_t * vm, while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) { - if (unformat - (line_input, "%U:%u %U", unformat_ip4_address, &addr, &port, - unformat_nat_protocol, &proto)) + if (unformat (line_input, "%U:%u %U", unformat_ip4_address, &addr, &port, + unformat_ip_protocol, &proto)) ; else if (unformat (line_input, "in")) { @@ -1505,8 +1694,8 @@ nat44_del_session_command_fn (vlib_main_t * vm, } rv = nat44_ed_del_session (sm, &addr, clib_host_to_net_u16 (port), &eh_addr, - clib_host_to_net_u16 (eh_port), - nat_proto_to_ip_proto (proto), vrf_id, is_in); + clib_host_to_net_u16 (eh_port), proto, vrf_id, + is_in); switch (rv) { @@ -1658,21 +1847,19 @@ done: * @cliexstart{nat44} * Enable nat44 plugin * To enable nat44-ed, use: - * vpp# nat44 enable + * vpp# nat44 plugin enable * To disable nat44-ed, use: - * vpp# nat44 disable - * To enable nat44-ed static mapping with connection tracking, use: - * vpp# nat44-ed enable static-mapping connection-tracking + * vpp# nat44 plugin disable * To set inside-vrf outside-vrf, use: - * vpp# nat44 enable inside-vrf <id> outside-vrf <id> + * vpp# nat44 plugin enable inside-vrf <id> outside-vrf <id> * @cliexend ?*/ VLIB_CLI_COMMAND (nat44_ed_enable_disable_command, static) = { - .path = "nat44", - .short_help = "nat44 <enable [sessions <max-number>] [static-mapping-only " - "connection-tracking] [inside-vrf <vrf-id>] " - "[outside-vrf <vrf-id>]>|disable", + .path = "nat44 plugin", .function = nat44_ed_enable_disable_command_fn, + .short_help = + "nat44 plugin <enable [sessions <max-number>] [inside-vrf <vrf-id>] " + "[outside-vrf <vrf-id>]>|disable", }; /*? @@ -1701,7 +1888,7 @@ VLIB_CLI_COMMAND (set_workers_command, static) = { VLIB_CLI_COMMAND (nat_show_workers_command, static) = { .path = "show nat workers", .short_help = "show nat workers", - .function = nat_show_workers_commnad_fn, + .function = nat_show_workers_command_fn, }; /*? @@ -2029,9 +2216,48 @@ VLIB_CLI_COMMAND (nat44_show_static_mappings_command, static) = { * @cliexend ?*/ VLIB_CLI_COMMAND (snat_add_interface_address_command, static) = { - .path = "nat44 add interface address", - .short_help = "nat44 add interface address <interface> [twice-nat] [del]", - .function = snat_add_interface_address_command_fn, + .path = "nat44 add interface address", + .function = snat_add_interface_address_command_fn, + .short_help = "nat44 add interface address <interface> [twice-nat] [del]", +}; + +/*? + * @cliexpar + * @cliexstart{nat44 vrf table} + * Add empty inter VRF routing table + * vpp# nat44 vrf table add 10 + * @cliexend +?*/ +VLIB_CLI_COMMAND (nat44_ed_add_del_vrf_table_command, static) = { + .path = "nat44 vrf table", + .short_help = "nat44 vrf table [add|del] <vrf-id>", + .function = nat44_ed_add_del_vrf_table_command_fn, +}; + +/*? + * @cliexpar + * @cliexstart{nat44 vrf route} + * Add inter VRF route record to VRF routing table + * vpp# nat44 vrf route add table 10 20 + * @cliexend +?*/ +VLIB_CLI_COMMAND (nat44_ed_add_del_vrf_route_command, static) = { + .path = "nat44 vrf route", + .short_help = "nat44 vrf route [add|del] table <vrf-id> <vrf-id>", + .function = nat44_ed_add_del_vrf_route_command_fn, +}; + +/*? + * @cliexpar + * @cliexstart{show nat44 vrf tables} + * Show inter VRF route tables + * vpp# show nat44 vrf tables + * @cliexend +?*/ +VLIB_CLI_COMMAND (nat44_ed_show_vrf_tables_command, static) = { + .path = "show nat44 vrf tables", + .short_help = "show nat44 vrf tables", + .function = nat44_ed_show_vrf_tables_command_fn, }; /*? @@ -2059,7 +2285,9 @@ VLIB_CLI_COMMAND (nat44_show_interface_address_command, static) = { ?*/ VLIB_CLI_COMMAND (nat44_show_sessions_command, static) = { .path = "show nat44 sessions", - .short_help = "show nat44 sessions", + .short_help = "show nat44 sessions [filter {i2o | o2i} {saddr <ip4-addr> " + "| sport <n> | daddr <ip4-addr> | dport <n> | proto <proto>} " + "[filter .. [..]]]", .function = nat44_show_sessions_command_fn, }; |