From 5ae454312c2ffccf47e4b8c430c81f1a3d067e67 Mon Sep 17 00:00:00 2001 From: Filip Varga Date: Mon, 26 Jul 2021 20:59:21 +0200 Subject: [PATCH] nat: NAT44ED configuration refactor Refactoring and cleaning up address allocation functions & ip table update callbacks. Type: refactor Change-Id: I9a11700a5f335b64d0d84e04d8e16d040624e01b Signed-off-by: Filip Varga --- src/plugins/nat/nat44-ed/nat44_ed.c | 560 +++++++++++++++++--------------- src/plugins/nat/nat44-ed/nat44_ed.h | 93 ++---- src/plugins/nat/nat44-ed/nat44_ed_api.c | 42 ++- src/plugins/nat/nat44-ed/nat44_ed_cli.c | 48 +-- 4 files changed, 365 insertions(+), 378 deletions(-) diff --git a/src/plugins/nat/nat44-ed/nat44_ed.c b/src/plugins/nat/nat44-ed/nat44_ed.c index 1a5bdb58073..ad78dc2dd1f 100644 --- a/src/plugins/nat/nat44-ed/nat44_ed.c +++ b/src/plugins/nat/nat44-ed/nat44_ed.c @@ -316,21 +316,38 @@ snat_add_del_addr_to_fib (ip4_address_t * addr, u8 p_len, u32 sw_if_index, fib_table_entry_delete (fib_index, &prefix, sm->fib_src_low); } +static int +is_snat_address_used_in_static_mapping (snat_main_t *sm, ip4_address_t addr) +{ + snat_static_mapping_t *m; + pool_foreach (m, sm->static_mappings) + { + if (is_sm_addr_only (m->flags) || is_sm_out2in_only (m->flags) || + is_sm_identity_nat (m->flags)) + continue; + if (m->external_addr.as_u32 == addr.as_u32) + return 1; + } + return 0; +} + int -snat_add_address (snat_main_t * sm, ip4_address_t * addr, u32 vrf_id, - u8 twice_nat) +nat44_ed_add_address (ip4_address_t *addr, u32 vrf_id, u8 twice_nat) { - snat_address_t *ap; - snat_interface_t *i; + snat_main_t *sm = &snat_main; vlib_thread_main_t *tm = vlib_get_thread_main (); + snat_address_t *ap, *addresses; + snat_interface_t *i; + + addresses = twice_nat ? sm->twice_nat_addresses : sm->addresses; if (!sm->enabled) { return VNET_API_ERROR_UNSUPPORTED; } - /* Check if address already exists */ - vec_foreach (ap, twice_nat ? sm->twice_nat_addresses : sm->addresses) + // check if address already exists + vec_foreach (ap, addresses) { if (ap->addr.as_u32 == addr->as_u32) { @@ -340,62 +357,160 @@ snat_add_address (snat_main_t * sm, ip4_address_t * addr, u32 vrf_id, } if (twice_nat) - vec_add2 (sm->twice_nat_addresses, ap, 1); + { + vec_add2 (sm->twice_nat_addresses, ap, 1); + } else - vec_add2 (sm->addresses, ap, 1); + { + vec_add2 (sm->addresses, ap, 1); + } + ap->fib_index = ~0; ap->addr = *addr; - if (vrf_id != ~0) - ap->fib_index = - fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, vrf_id, - sm->fib_src_low); - else - ap->fib_index = ~0; - - #define _(N, i, n, s) \ - clib_memset(ap->busy_##n##_port_refcounts, 0, sizeof(ap->busy_##n##_port_refcounts));\ - ap->busy_##n##_ports = 0; \ - ap->busy_##n##_ports_per_thread = 0;\ - vec_validate_init_empty (ap->busy_##n##_ports_per_thread, tm->n_vlib_mains - 1, 0); - foreach_nat_protocol - #undef _ - - if (twice_nat) - return 0; - /* Add external address to FIB */ - pool_foreach (i, sm->interfaces) - { - if (nat_interface_is_inside (i)) - continue; + if (vrf_id != ~0) + { + ap->fib_index = fib_table_find_or_create_and_lock ( + FIB_PROTOCOL_IP4, vrf_id, sm->fib_src_low); + } - snat_add_del_addr_to_fib (addr, 32, i->sw_if_index, 1); - break; - } - pool_foreach (i, sm->output_feature_interfaces) - { - if (nat_interface_is_inside (i)) - continue; +#define _(N, i, n, s) \ + clib_memset (ap->busy_##n##_port_refcounts, 0, \ + sizeof (ap->busy_##n##_port_refcounts)); \ + ap->busy_##n##_ports = 0; \ + ap->busy_##n##_ports_per_thread = 0; \ + vec_validate_init_empty (ap->busy_##n##_ports_per_thread, \ + tm->n_vlib_mains - 1, 0); + foreach_nat_protocol +#undef _ - snat_add_del_addr_to_fib (addr, 32, i->sw_if_index, 1); - break; + if (!twice_nat) + { + pool_foreach (i, sm->interfaces) + { + if (!nat_interface_is_inside (i)) + { + snat_add_del_addr_to_fib (addr, 32, i->sw_if_index, 1); + break; + } + } + pool_foreach (i, sm->output_feature_interfaces) + { + if (!nat_interface_is_inside (i)) + { + snat_add_del_addr_to_fib (addr, 32, i->sw_if_index, 1); + break; + } + } } - return 0; } -static int -is_snat_address_used_in_static_mapping (snat_main_t * sm, ip4_address_t addr) +int +nat44_ed_del_address (ip4_address_t addr, u8 delete_sm, u8 twice_nat) { + snat_main_t *sm = &snat_main; + snat_address_t *a = 0, *addresses; + snat_session_t *ses; + u32 *ses_to_be_removed = 0, *ses_index; + snat_main_per_thread_data_t *tsm; snat_static_mapping_t *m; - pool_foreach (m, sm->static_mappings) - { - if (is_sm_addr_only (m->flags) || is_sm_out2in_only (m->flags) || - is_sm_identity_nat (m->flags)) - continue; - if (m->external_addr.as_u32 == addr.as_u32) - return 1; + snat_interface_t *i; + int j; + + addresses = twice_nat ? sm->twice_nat_addresses : sm->addresses; + + for (j = 0; j < vec_len (addresses); j++) + { + if (addresses[j].addr.as_u32 == addr.as_u32) + { + a = addresses + j; + break; + } + } + if (!a) + { + nat_log_err ("no such address"); + return VNET_API_ERROR_NO_SUCH_ENTRY; + } + + if (delete_sm) + { + pool_foreach (m, sm->static_mappings) + { + if (m->external_addr.as_u32 == addr.as_u32) + { + nat44_ed_del_static_mapping (m->local_addr, m->external_addr, + m->local_port, m->external_port, + m->proto, m->vrf_id, ~0, m->flags); + } + } + } + else + { + // TODO: why ? + // check if address is used in some static mapping + if (is_snat_address_used_in_static_mapping (sm, addr)) + { + nat_log_err ("address used in static mapping"); + return VNET_API_ERROR_UNSPECIFIED; + } + } + + if (a->fib_index != ~0) + { + fib_table_unlock (a->fib_index, FIB_PROTOCOL_IP4, sm->fib_src_low); + } + + // delete sessions using address + if (a->busy_tcp_ports || a->busy_udp_ports || a->busy_icmp_ports) + { + vec_foreach (tsm, sm->per_thread_data) + { + pool_foreach (ses, tsm->sessions) + { + if (ses->out2in.addr.as_u32 == addr.as_u32) + { + nat_free_session_data (sm, ses, tsm - sm->per_thread_data, + 0); + vec_add1 (ses_to_be_removed, ses - tsm->sessions); + } + } + vec_foreach (ses_index, ses_to_be_removed) + { + ses = pool_elt_at_index (tsm->sessions, ses_index[0]); + nat_ed_session_delete (sm, ses, tsm - sm->per_thread_data, 1); + } + vec_free (ses_to_be_removed); + } + } + +#define _(N, i, n, s) vec_free (a->busy_##n##_ports_per_thread); + foreach_nat_protocol +#undef _ + + if (!twice_nat) + { + vec_del1 (sm->addresses, j); + // delete external address from FIB + pool_foreach (i, sm->interfaces) + { + if (!nat_interface_is_inside (i)) + { + snat_add_del_addr_to_fib (&addr, 32, i->sw_if_index, 0); + break; + } + } + pool_foreach (i, sm->output_feature_interfaces) + { + if (!nat_interface_is_inside (i)) + { + snat_add_del_addr_to_fib (&addr, 32, i->sw_if_index, 0); + break; + } + } } + else { vec_del1 (sm->twice_nat_addresses, j); } return 0; } @@ -1426,122 +1541,6 @@ nat44_ed_add_del_lb_static_mapping_local (ip4_address_t e_addr, u16 e_port, return 0; } -int -snat_del_address (snat_main_t * sm, ip4_address_t addr, u8 delete_sm, - u8 twice_nat) -{ - snat_address_t *a = 0; - snat_session_t *ses; - u32 *ses_to_be_removed = 0, *ses_index; - snat_main_per_thread_data_t *tsm; - snat_static_mapping_t *m; - snat_interface_t *interface; - snat_address_t *addresses; - int i; - - if (!sm->enabled) - { - return VNET_API_ERROR_UNSUPPORTED; - } - - addresses = twice_nat ? sm->twice_nat_addresses : sm->addresses; - - /* Find SNAT address */ - for (i = 0; i < vec_len (addresses); i++) - { - if (addresses[i].addr.as_u32 == addr.as_u32) - { - a = addresses + i; - break; - } - } - if (!a) - { - nat_log_err ("no such address"); - return VNET_API_ERROR_NO_SUCH_ENTRY; - } - - if (delete_sm) - { - pool_foreach (m, sm->static_mappings) - { - if (m->external_addr.as_u32 == addr.as_u32) - { - nat44_ed_del_static_mapping (m->local_addr, m->external_addr, - m->local_port, m->external_port, - m->proto, m->vrf_id, ~0, m->flags); - } - } - } - else - { - /* Check if address is used in some static mapping */ - if (is_snat_address_used_in_static_mapping (sm, addr)) - { - nat_log_err ("address used in static mapping"); - return VNET_API_ERROR_UNSPECIFIED; - } - } - - if (a->fib_index != ~0) - fib_table_unlock (a->fib_index, FIB_PROTOCOL_IP4, sm->fib_src_low); - - /* Delete sessions using address */ - if (a->busy_tcp_ports || a->busy_udp_ports || a->busy_icmp_ports) - { - vec_foreach (tsm, sm->per_thread_data) - { - pool_foreach (ses, tsm->sessions) { - if (ses->out2in.addr.as_u32 == addr.as_u32) - { - nat_free_session_data (sm, ses, tsm - sm->per_thread_data, 0); - vec_add1 (ses_to_be_removed, ses - tsm->sessions); - } - } - - vec_foreach (ses_index, ses_to_be_removed) - { - ses = pool_elt_at_index (tsm->sessions, ses_index[0]); - nat_ed_session_delete (sm, ses, tsm - sm->per_thread_data, 1); - } - - vec_free (ses_to_be_removed); - } - } - -#define _(N, i, n, s) \ - vec_free (a->busy_##n##_ports_per_thread); - foreach_nat_protocol -#undef _ - - if (twice_nat) - { - vec_del1 (sm->twice_nat_addresses, i); - return 0; - } - else vec_del1 (sm->addresses, i); - - /* Delete external address from FIB */ - pool_foreach (interface, sm->interfaces) - { - if (nat_interface_is_inside (interface)) - continue; - - snat_add_del_addr_to_fib (&addr, 32, interface->sw_if_index, 0); - break; - } - pool_foreach (interface, sm->output_feature_interfaces) - { - if (nat_interface_is_inside (interface)) - continue; - - snat_add_del_addr_to_fib (&addr, 32, interface->sw_if_index, 0); - break; - } - - return 0; -} - void expire_per_vrf_sessions (u32 fib_index) { @@ -2115,9 +2114,8 @@ nat44_ed_set_frame_queue_nelts (u32 frame_queue_nelts) } static void -snat_update_outside_fib (ip4_main_t * im, uword opaque, - u32 sw_if_index, u32 new_fib_index, - u32 old_fib_index) +nat44_ed_update_outside_fib_cb (ip4_main_t *im, uword opaque, u32 sw_if_index, + u32 new_fib_index, u32 old_fib_index) { snat_main_t *sm = &snat_main; nat_outside_fib_t *outside_fib; @@ -2183,26 +2181,17 @@ snat_update_outside_fib (ip4_main_t * im, uword opaque, } } -static void -snat_update_outside_fib (ip4_main_t * im, uword opaque, - u32 sw_if_index, u32 new_fib_index, - u32 old_fib_index); +static void nat44_ed_update_outside_fib_cb (ip4_main_t *im, uword opaque, + u32 sw_if_index, u32 new_fib_index, + u32 old_fib_index); -static void -snat_ip4_add_del_interface_address_cb (ip4_main_t * im, - uword opaque, - u32 sw_if_index, - ip4_address_t * address, - u32 address_length, - u32 if_address_index, u32 is_delete); +static void nat44_ed_add_del_interface_address_cb ( + ip4_main_t *im, uword opaque, u32 sw_if_index, ip4_address_t *address, + u32 address_length, u32 if_address_index, u32 is_delete); -static void -nat_ip4_add_del_addr_only_sm_cb (ip4_main_t * im, - uword opaque, - u32 sw_if_index, - ip4_address_t * address, - u32 address_length, - u32 if_address_index, u32 is_delete); +static void nat44_ed_add_del_sm_addr_only_cb ( + ip4_main_t *im, uword opaque, u32 sw_if_index, ip4_address_t *address, + u32 address_length, u32 if_address_index, u32 is_delete); void test_key_calc_split () @@ -2397,13 +2386,13 @@ nat_init (vlib_main_t * vm) } /* callbacks to call when interface address changes. */ - cbi.function = snat_ip4_add_del_interface_address_cb; + cbi.function = nat44_ed_add_del_interface_address_cb; vec_add1 (sm->ip4_main->add_del_interface_address_callbacks, cbi); - cbi.function = nat_ip4_add_del_addr_only_sm_cb; + cbi.function = nat44_ed_add_del_sm_addr_only_cb; vec_add1 (sm->ip4_main->add_del_interface_address_callbacks, cbi); /* callbacks to call when interface to table biding changes */ - cbt.function = snat_update_outside_fib; + cbt.function = nat44_ed_update_outside_fib_cb; vec_add1 (sm->ip4_main->table_bind_callbacks, cbt); sm->fib_src_low = @@ -3242,19 +3231,17 @@ nat44_ed_sessions_clear () } static void -nat_ip4_add_del_addr_only_sm_cb (ip4_main_t * im, - uword opaque, - u32 sw_if_index, - ip4_address_t * address, - u32 address_length, - u32 if_address_index, u32 is_delete) +nat44_ed_add_del_sm_addr_only_cb (ip4_main_t *im, uword opaque, + u32 sw_if_index, ip4_address_t *address, + u32 address_length, u32 if_address_index, + u32 is_delete) { - snat_main_t *sm = &snat_main; + clib_bihash_kv_8_8_t kv, value; snat_static_map_resolve_t *rp; + snat_main_t *sm = &snat_main; snat_static_mapping_t *m; - clib_bihash_kv_8_8_t kv, value; ip4_address_t l_addr; - int i, rv; + int i, rv = 0; if (!sm->enabled) return; @@ -3262,63 +3249,65 @@ nat_ip4_add_del_addr_only_sm_cb (ip4_main_t * im, for (i = 0; i < vec_len (sm->to_resolve); i++) { rp = sm->to_resolve + i; - if (rp->addr_only == 0) - continue; - if (rp->sw_if_index == sw_if_index) - goto match; + if (rp->addr_only && rp->sw_if_index == sw_if_index) + { + goto match; + } } - return; match: init_nat_k (&kv, *address, rp->addr_only ? 0 : rp->e_port, sm->outside_fib_index, rp->addr_only ? 0 : rp->proto); - if (clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value)) - m = 0; - else - m = pool_elt_at_index (sm->static_mappings, value.value); - if (!is_delete) + if (clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value)) { - /* Don't trip over lease renewal, static config */ - if (m) - return; + m = 0; } else { - if (!m) - return; + m = pool_elt_at_index (sm->static_mappings, value.value); } - /* Indetity mapping? */ + // Indetity mapping if (rp->l_addr.as_u32 == 0) - l_addr.as_u32 = address[0].as_u32; + { + l_addr.as_u32 = address[0].as_u32; + } else - l_addr.as_u32 = rp->l_addr.as_u32; + { + l_addr.as_u32 = rp->l_addr.as_u32; + } if (is_delete) { - rv = nat44_ed_del_static_mapping (l_addr, address[0], rp->l_port, - rp->e_port, rp->proto, rp->vrf_id, ~0, - rp->flags); + if (m) + { + rv = nat44_ed_del_static_mapping (l_addr, address[0], rp->l_port, + rp->e_port, rp->proto, rp->vrf_id, + ~0, rp->flags); + } } else { - rv = nat44_ed_add_static_mapping (l_addr, address[0], rp->l_port, - rp->e_port, rp->proto, rp->vrf_id, ~0, - rp->flags, rp->pool_addr, rp->tag); + if (!m) + { + rv = nat44_ed_add_static_mapping ( + l_addr, address[0], rp->l_port, rp->e_port, rp->proto, rp->vrf_id, + ~0, rp->flags, rp->pool_addr, rp->tag); + } + // else don't trip over lease renewal, static config } if (rv) { - nat_elog_notice_X1 (sm, "add_static_mapping returned %d", "i4", rv); + nat_elog_notice_X1 (sm, "nat44_ed_del_static_mapping returned %d", "i4", + rv); } } static void -snat_ip4_add_del_interface_address_cb (ip4_main_t * im, - uword opaque, - u32 sw_if_index, - ip4_address_t * address, +nat44_ed_add_del_interface_address_cb (ip4_main_t *im, uword opaque, + u32 sw_if_index, ip4_address_t *address, u32 address_length, u32 if_address_index, u32 is_delete) { @@ -3331,7 +3320,9 @@ snat_ip4_add_del_interface_address_cb (ip4_main_t * im, snat_address_t *addresses = sm->addresses; if (!sm->enabled) - return; + { + return; + } for (i = 0; i < vec_len (sm->auto_add_sw_if_indices); i++) { @@ -3357,7 +3348,7 @@ match: if (addresses[j].addr.as_u32 == address->as_u32) return; - (void) snat_add_address (sm, address, ~0, twice_nat); + (void) nat44_ed_add_address (address, ~0, twice_nat); /* Scan static map resolution vector */ for (j = 0; j < vec_len (sm->to_resolve); j++) { @@ -3367,7 +3358,6 @@ match: /* On this interface? */ if (rp->sw_if_index == sw_if_index) { - // TODO: remove if not needed (handled by function) /* Indetity mapping? */ if (rp->l_addr.as_u32 == 0) @@ -3390,15 +3380,54 @@ match: } else { - (void) snat_del_address (sm, address[0], 1, twice_nat); - return; + // remove all static mapping records + (void) nat44_ed_del_address (address[0], 1, twice_nat); } } int -snat_add_interface_address (snat_main_t * sm, u32 sw_if_index, int is_del, - u8 twice_nat) +nat44_ed_add_interface_address (u32 sw_if_index, u8 twice_nat) { + snat_main_t *sm = &snat_main; + ip4_main_t *ip4_main = sm->ip4_main; + ip4_address_t *first_int_addr; + u32 *auto_add_sw_if_indices = twice_nat ? + sm->auto_add_sw_if_indices_twice_nat : + sm->auto_add_sw_if_indices; + int i; + + for (i = 0; i < vec_len (auto_add_sw_if_indices); i++) + { + if (auto_add_sw_if_indices[i] == sw_if_index) + { + return VNET_API_ERROR_VALUE_EXIST; + } + } + + // add to the auto-address list + if (twice_nat) + { + vec_add1 (sm->auto_add_sw_if_indices_twice_nat, sw_if_index); + } + else + { + vec_add1 (sm->auto_add_sw_if_indices, sw_if_index); + } + + // if the address is already bound - or static - add it now + first_int_addr = ip4_interface_first_address (ip4_main, sw_if_index, 0); + if (first_int_addr) + { + (void) nat44_ed_add_address (first_int_addr, ~0, twice_nat); + } + + return 0; +} + +int +nat44_ed_del_interface_address (u32 sw_if_index, u8 twice_nat) +{ + snat_main_t *sm = &snat_main; ip4_main_t *ip4_main = sm->ip4_main; ip4_address_t *first_int_addr; snat_static_map_resolve_t *rp; @@ -3414,58 +3443,49 @@ snat_add_interface_address (snat_main_t * sm, u32 sw_if_index, int is_del, auto_add_sw_if_indices = twice_nat ? sm->auto_add_sw_if_indices_twice_nat : sm->auto_add_sw_if_indices; - first_int_addr = ip4_interface_first_address (ip4_main, sw_if_index, 0); - for (i = 0; i < vec_len (auto_add_sw_if_indices); i++) { if (auto_add_sw_if_indices[i] == sw_if_index) { - if (is_del) + first_int_addr = + ip4_interface_first_address (ip4_main, sw_if_index, 0); + if (first_int_addr) { - /* if have address remove it */ - if (first_int_addr) - (void) snat_del_address (sm, first_int_addr[0], 1, twice_nat); - else + // remove all static mapping records + (void) nat44_ed_del_address (first_int_addr[0], 1, twice_nat); + } + else + { + for (j = 0; j < vec_len (sm->to_resolve); j++) { - for (j = 0; j < vec_len (sm->to_resolve); j++) + rp = sm->to_resolve + j; + if (rp->sw_if_index == sw_if_index) { - rp = sm->to_resolve + j; - if (rp->sw_if_index == sw_if_index) - vec_add1 (indices_to_delete, j); + vec_add1 (indices_to_delete, j); } - if (vec_len (indices_to_delete)) + } + if (vec_len (indices_to_delete)) + { + for (j = vec_len (indices_to_delete) - 1; j >= 0; j--) { - for (j = vec_len (indices_to_delete) - 1; j >= 0; j--) - vec_del1 (sm->to_resolve, j); - vec_free (indices_to_delete); + vec_del1 (sm->to_resolve, j); } + vec_free (indices_to_delete); } - if (twice_nat) - vec_del1 (sm->auto_add_sw_if_indices_twice_nat, i); - else - vec_del1 (sm->auto_add_sw_if_indices, i); } - else - return VNET_API_ERROR_VALUE_EXIST; + if (twice_nat) + { + vec_del1 (sm->auto_add_sw_if_indices_twice_nat, i); + } + else + { + vec_del1 (sm->auto_add_sw_if_indices, i); + } return 0; } } - - if (is_del) - return VNET_API_ERROR_NO_SUCH_ENTRY; - - /* add to the auto-address list */ - if (twice_nat) - vec_add1 (sm->auto_add_sw_if_indices_twice_nat, sw_if_index); - else - vec_add1 (sm->auto_add_sw_if_indices, sw_if_index); - - /* If the address is already bound - or static - add it now */ - if (first_int_addr) - (void) snat_add_address (sm, first_int_addr, ~0, twice_nat); - - return 0; + return VNET_API_ERROR_NO_SUCH_ENTRY; } int diff --git a/src/plugins/nat/nat44-ed/nat44_ed.h b/src/plugins/nat/nat44-ed/nat44_ed.h index ef4b546a488..ee3f71aaceb 100644 --- a/src/plugins/nat/nat44-ed/nat44_ed.h +++ b/src/plugins/nat/nat44-ed/nat44_ed.h @@ -772,19 +772,19 @@ unformat_function_t unformat_nat_protocol; @param i NAT interface @return 1 if inside interface */ -#define nat_interface_is_inside(i) i->flags & NAT_INTERFACE_FLAG_IS_INSIDE +#define nat_interface_is_inside(i) (i->flags & NAT_INTERFACE_FLAG_IS_INSIDE) /** \brief Check if NAT interface is outside. @param i NAT interface @return 1 if outside interface */ -#define nat_interface_is_outside(i) i->flags & NAT_INTERFACE_FLAG_IS_OUTSIDE +#define nat_interface_is_outside(i) (i->flags & NAT_INTERFACE_FLAG_IS_OUTSIDE) /** \brief Check if NAT44 endpoint-dependent TCP session is closed. @param s NAT session @return 1 if session is closed */ -#define nat44_is_ses_closed(s) s->state == 0xf +#define nat44_is_ses_closed(s) (s->state == 0xf) /** \brief Check if client initiating TCP connection (received SYN from client) @param t TCP header @@ -856,6 +856,23 @@ is_sm_switch_address (u32 f) #define nat_log_debug(...)\ vlib_log(VLIB_LOG_LEVEL_DEBUG, snat_main.log_class, __VA_ARGS__) +clib_error_t *nat44_api_hookup (vlib_main_t *vm); + +int snat_set_workers (uword *bitmap); + +int nat44_plugin_enable (nat44_config_t c); +int nat44_plugin_disable (); + +int nat44_ed_add_interface (u32 sw_if_index, u8 is_inside); +int nat44_ed_del_interface (u32 sw_if_index, u8 is_inside); +int nat44_ed_add_output_interface (u32 sw_if_index); +int nat44_ed_del_output_interface (u32 sw_if_index); + +int nat44_ed_add_address (ip4_address_t *addr, u32 vrf_id, u8 twice_nat); +int nat44_ed_del_address (ip4_address_t addr, u8 delete_sm, u8 twice_nat); +int nat44_ed_add_interface_address (u32 sw_if_index, u8 twice_nat); +int nat44_ed_del_interface_address (u32 sw_if_index, u8 twice_nat); + int nat44_ed_add_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr, u16 l_port, u16 e_port, nat_protocol_t proto, u32 vrf_id, u32 sw_if_index, u32 flags, @@ -878,76 +895,6 @@ int nat44_ed_add_del_lb_static_mapping_local (ip4_address_t e_addr, u16 e_port, nat_protocol_t proto, u32 vrf_id, u8 probability, u8 is_add); -/** - * @brief Enable NAT44 plugin - * - * @param c nat44_config_t - * - * @return 0 on success, non-zero value otherwise - */ -int nat44_plugin_enable (nat44_config_t c); - -/** - * @brief Disable NAT44 plugin - * - * @return 0 on success, non-zero value otherwise - */ -int nat44_plugin_disable (); - -/** - * @brief Add external address to NAT44 pool - * - * @param sm snat global configuration data - * @param addr IPv4 address - * @param vrf_id VRF id of tenant, ~0 means independent of VRF - * @param twice_nat 1 if twice NAT address - * - * @return 0 on success, non-zero value otherwise - */ -int snat_add_address (snat_main_t * sm, ip4_address_t * addr, u32 vrf_id, - u8 twice_nat); - -/** - * @brief Delete external address from NAT44 pool - * - * @param sm snat global configuration data - * @param addr IPv4 address - * @param delete_sm 1 if delete static mapping using address - * @param twice_nat 1 if twice NAT address - * - * @return 0 on success, non-zero value otherwise - */ -int snat_del_address (snat_main_t * sm, ip4_address_t addr, u8 delete_sm, - u8 twice_nat); - -clib_error_t *nat44_api_hookup (vlib_main_t * vm); - -/** - * @brief Set NAT plugin workers - * - * @param bitmap NAT workers bitmap - * - * @return 0 on success, non-zero value otherwise - */ -int snat_set_workers (uword * bitmap); - -int nat44_ed_add_interface (u32 sw_if_index, u8 is_inside); -int nat44_ed_del_interface (u32 sw_if_index, u8 is_inside); -int nat44_ed_add_output_interface (u32 sw_if_index); -int nat44_ed_del_output_interface (u32 sw_if_index); - -/** - * @brief Add/delete NAT44 pool address from specific interface - * - * @param sw_if_index software index of the interface - * @param is_del 1 = delete, 0 = add - * @param twice_nat 1 = twice NAT address for external hosts - * - * @return 0 on success, non-zero value otherwise - */ -int snat_add_interface_address (snat_main_t * sm, u32 sw_if_index, int is_del, - u8 twice_nat); - /** * @brief Delete NAT44 endpoint-dependent session * diff --git a/src/plugins/nat/nat44-ed/nat44_ed_api.c b/src/plugins/nat/nat44-ed/nat44_ed_api.c index 36f96827d24..c0af5e99e8f 100644 --- a/src/plugins/nat/nat44-ed/nat44_ed_api.c +++ b/src/plugins/nat/nat44-ed/nat44_ed_api.c @@ -303,9 +303,13 @@ static void for (i = 0; i < count; i++) { if (is_add) - rv = snat_add_address (sm, &this_addr, vrf_id, twice_nat); + { + rv = nat44_ed_add_address (&this_addr, vrf_id, twice_nat); + } else - rv = snat_del_address (sm, this_addr, 0, twice_nat); + { + rv = nat44_ed_del_address (this_addr, 0, twice_nat); + } if (rv) goto send_reply; @@ -890,15 +894,15 @@ static void return; pool_foreach (m, sm->static_mappings) - { - if (is_sm_identity_nat (m->flags) && !is_sm_lb (m->flags)) - { - pool_foreach_index (j, m->locals) - { - send_nat44_identity_mapping_details (m, j, reg, mp->context); - } - } - } + { + if (is_sm_identity_nat (m->flags) && !is_sm_lb (m->flags)) + { + pool_foreach_index (j, m->locals) + { + send_nat44_identity_mapping_details (m, j, reg, mp->context); + } + } + } for (j = 0; j < vec_len (sm->to_resolve); j++) { @@ -915,8 +919,8 @@ static void snat_main_t *sm = &snat_main; vl_api_nat44_add_del_interface_addr_reply_t *rmp; u32 sw_if_index = ntohl (mp->sw_if_index); + u8 twice_nat; int rv = 0; - u8 is_del; if (sm->static_mapping_only) { @@ -924,12 +928,18 @@ static void goto send_reply; } - is_del = !mp->is_add; - VALIDATE_SW_IF_INDEX (mp); - rv = snat_add_interface_address (sm, sw_if_index, is_del, - mp->flags & NAT_API_IS_TWICE_NAT); + twice_nat = mp->flags & NAT_API_IS_TWICE_NAT; + + if (mp->is_add) + { + rv = nat44_ed_add_interface_address (sw_if_index, twice_nat); + } + else + { + rv = nat44_ed_del_interface_address (sw_if_index, twice_nat); + } BAD_SW_IF_INDEX_LABEL; diff --git a/src/plugins/nat/nat44-ed/nat44_ed_cli.c b/src/plugins/nat/nat44-ed/nat44_ed_cli.c index 9b3480cb9e4..af8ae8e6bd9 100644 --- a/src/plugins/nat/nat44-ed/nat44_ed_cli.c +++ b/src/plugins/nat/nat44-ed/nat44_ed_cli.c @@ -419,9 +419,13 @@ add_address_command_fn (vlib_main_t * vm, for (i = 0; i < count; i++) { if (is_add) - rv = snat_add_address (sm, &this_addr, vrf_id, twice_nat); + { + rv = nat44_ed_add_address (&this_addr, vrf_id, twice_nat); + } else - rv = snat_del_address (sm, this_addr, 0, twice_nat); + { + rv = nat44_ed_del_address (this_addr, 0, twice_nat); + } switch (rv) { @@ -1294,15 +1298,13 @@ snat_add_interface_address_command_fn (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { - snat_main_t *sm = &snat_main; unformat_input_t _line_input, *line_input = &_line_input; - u32 sw_if_index; - int rv; - int is_del = 0; + snat_main_t *sm = &snat_main; clib_error_t *error = 0; + int rv, is_del = 0; u8 twice_nat = 0; + u32 sw_if_index; - /* Get a line of input. */ if (!unformat_user (input, unformat_line_input, line_input)) return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT); @@ -1312,9 +1314,13 @@ snat_add_interface_address_command_fn (vlib_main_t * vm, sm->vnet_main, &sw_if_index)) ; else if (unformat (line_input, "twice-nat")) - twice_nat = 1; + { + twice_nat = 1; + } else if (unformat (line_input, "del")) - is_del = 1; + { + is_del = 1; + } else { error = clib_error_return (0, "unknown input '%U'", @@ -1323,17 +1329,21 @@ snat_add_interface_address_command_fn (vlib_main_t * vm, } } - rv = snat_add_interface_address (sm, sw_if_index, is_del, twice_nat); - - switch (rv) + if (!is_del) { - case 0: - break; - - default: - error = clib_error_return (0, "snat_add_interface_address returned %d", - rv); - goto done; + rv = nat44_ed_add_interface_address (sw_if_index, twice_nat); + if (rv) + { + error = clib_error_return (0, "add address returned %d", rv); + } + } + else + { + rv = nat44_ed_del_interface_address (sw_if_index, twice_nat); + if (rv) + { + error = clib_error_return (0, "del address returned %d", rv); + } } done: -- 2.16.6