aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugins/nat/nat44-ed/nat44_ed.c806
-rw-r--r--src/plugins/nat/nat44-ed/nat44_ed.h40
-rw-r--r--src/plugins/nat/nat44-ed/nat44_ed_api.c93
-rw-r--r--src/plugins/nat/nat44-ed/nat44_ed_cli.c47
-rw-r--r--src/plugins/nat/nat44-ed/nat44_ed_format.c3
-rw-r--r--src/plugins/nat/nat44-ed/nat44_ed_in2out.c2
6 files changed, 436 insertions, 555 deletions
diff --git a/src/plugins/nat/nat44-ed/nat44_ed.c b/src/plugins/nat/nat44-ed/nat44_ed.c
index 7907d8ffa6b..d3ef3d54f89 100644
--- a/src/plugins/nat/nat44-ed/nat44_ed.c
+++ b/src/plugins/nat/nat44-ed/nat44_ed.c
@@ -185,9 +185,11 @@ static int nat44_ed_add_static_mapping_internal (
ip4_address_t l_addr, ip4_address_t e_addr, u16 l_port, u16 e_port,
ip_protocol_t proto, u32 vrf_id, u32 sw_if_index, u32 flags,
ip4_address_t pool_addr, u8 *tag);
-static int nat44_ed_del_static_mapping_internal (
- ip4_address_t l_addr, ip4_address_t e_addr, u16 l_port, u16 e_port,
- ip_protocol_t proto, u32 vrf_id, u32 sw_if_index, u32 flags);
+static int nat44_ed_del_static_mapping_internal (ip4_address_t l_addr,
+ ip4_address_t e_addr,
+ u16 l_port, u16 e_port,
+ ip_protocol_t proto,
+ u32 vrf_id, u32 flags);
u32 nat_calc_bihash_buckets (u32 n_elts);
@@ -290,25 +292,6 @@ nat44_ed_free_session_data (snat_main_t *sm, snat_session_t *s,
}
}
-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;
-}
-
static ip_interface_address_t *
nat44_ed_get_ip_interface_address (u32 sw_if_index, ip4_address_t addr)
{
@@ -415,41 +398,91 @@ nat44_ed_bind_if_addr_to_nat_addr (u32 sw_if_index)
}
}
+static_always_inline snat_fib_entry_reg_t *
+nat44_ed_get_fib_entry_reg (ip4_address_t addr, u32 sw_if_index, int *out_idx)
+{
+ snat_main_t *sm = &snat_main;
+ snat_fib_entry_reg_t *fe;
+ int i;
+
+ for (i = 0; i < vec_len (sm->fib_entry_reg); i++)
+ {
+ fe = sm->fib_entry_reg + i;
+ if ((addr.as_u32 == fe->addr.as_u32) && (sw_if_index == fe->sw_if_index))
+ {
+ if (out_idx)
+ {
+ *out_idx = i;
+ }
+ return fe;
+ }
+ }
+ return NULL;
+}
+
static void
-nat44_ed_add_del_addr_to_fib (ip4_address_t *addr, u8 p_len, u32 sw_if_index,
- int is_add)
+nat44_ed_add_fib_entry_reg (ip4_address_t addr, u32 sw_if_index)
{
// Add the external NAT address to the FIB as receive entries. This ensures
// that VPP will reply to ARP for this address and we don't need to enable
// proxy ARP on the outside interface.
-
snat_main_t *sm = &snat_main;
- fib_prefix_t prefix = {
- .fp_len = p_len,
- .fp_proto = FIB_PROTOCOL_IP4,
- .fp_addr = {
- .ip4.as_u32 = addr->as_u32,
- },
- };
- u32 fib_index = ip4_fib_table_get_index_for_sw_if_index (sw_if_index);
+ snat_fib_entry_reg_t *fe;
- if (is_add)
+ if (!(fe = nat44_ed_get_fib_entry_reg (addr, sw_if_index, 0)))
{
+ fib_prefix_t prefix = {
+ .fp_len = 32,
+ .fp_proto = FIB_PROTOCOL_IP4,
+ .fp_addr = {
+ .ip4.as_u32 = addr.as_u32,
+ },
+ };
+ u32 fib_index = ip4_fib_table_get_index_for_sw_if_index (sw_if_index);
fib_table_entry_update_one_path (fib_index, &prefix, sm->fib_src_low,
(FIB_ENTRY_FLAG_CONNECTED |
FIB_ENTRY_FLAG_LOCAL |
FIB_ENTRY_FLAG_EXCLUSIVE),
DPO_PROTO_IP4, NULL, sw_if_index, ~0, 1,
NULL, FIB_ROUTE_PATH_FLAG_NONE);
+
+ vec_add2 (sm->fib_entry_reg, fe, 1);
+ clib_memset (fe, 0, sizeof (*fe));
+ fe->addr.as_u32 = addr.as_u32;
+ fe->sw_if_index = sw_if_index;
}
- else
+ fe->count++;
+}
+
+static void
+nat44_ed_del_fib_entry_reg (ip4_address_t addr, u32 sw_if_index)
+{
+ snat_main_t *sm = &snat_main;
+ snat_fib_entry_reg_t *fe;
+ int i;
+
+ if ((fe = nat44_ed_get_fib_entry_reg (addr, sw_if_index, &i)))
{
- fib_table_entry_delete (fib_index, &prefix, sm->fib_src_low);
+ fe->count--;
+ if (0 == fe->count)
+ {
+ fib_prefix_t prefix = {
+ .fp_len = 32,
+ .fp_proto = FIB_PROTOCOL_IP4,
+ .fp_addr = {
+ .ip4.as_u32 = addr.as_u32,
+ },
+ };
+ u32 fib_index =
+ ip4_fib_table_get_index_for_sw_if_index (sw_if_index);
+ fib_table_entry_delete (fib_index, &prefix, sm->fib_src_low);
+ vec_del1 (sm->fib_entry_reg, i);
+ }
}
}
static void
-nat44_ed_add_del_addr_to_fib_foreach_out_if (ip4_address_t *addr, u8 is_add)
+nat44_ed_add_del_interface_fib_reg_entries (ip4_address_t addr, u8 is_add)
{
snat_main_t *sm = &snat_main;
snat_interface_t *i;
@@ -458,42 +491,66 @@ nat44_ed_add_del_addr_to_fib_foreach_out_if (ip4_address_t *addr, u8 is_add)
{
if (nat44_ed_is_interface_outside (i))
{
- nat44_ed_add_del_addr_to_fib (addr, 32, i->sw_if_index, is_add);
+ if (is_add)
+ {
+ nat44_ed_add_fib_entry_reg (addr, i->sw_if_index);
+ }
+ else
+ {
+ nat44_ed_del_fib_entry_reg (addr, i->sw_if_index);
+ }
}
}
pool_foreach (i, sm->output_feature_interfaces)
{
if (nat44_ed_is_interface_outside (i))
{
- nat44_ed_add_del_addr_to_fib (addr, 32, i->sw_if_index, is_add);
+ if (is_add)
+ {
+ nat44_ed_add_fib_entry_reg (addr, i->sw_if_index);
+ }
+ else
+ {
+ nat44_ed_del_fib_entry_reg (addr, i->sw_if_index);
+ }
}
}
}
static_always_inline void
-nat44_ed_add_del_addr_to_fib_foreach_addr (u32 sw_if_index, u8 is_add)
+nat44_ed_add_del_nat_addr_fib_reg_entries (u32 sw_if_index, u8 is_add)
{
snat_main_t *sm = &snat_main;
snat_address_t *ap;
vec_foreach (ap, sm->addresses)
{
- nat44_ed_add_del_addr_to_fib (&ap->addr, 32, sw_if_index, is_add);
+ if (is_add)
+ {
+ nat44_ed_add_fib_entry_reg (ap->addr, sw_if_index);
+ }
+ else
+ {
+ nat44_ed_del_fib_entry_reg (ap->addr, sw_if_index);
+ }
}
}
static_always_inline void
-nat44_ed_add_del_addr_to_fib_foreach_addr_only_sm (u32 sw_if_index, u8 is_add)
+nat44_ed_add_del_sm_fib_reg_entries (u32 sw_if_index, u8 is_add)
{
snat_main_t *sm = &snat_main;
snat_static_mapping_t *m;
pool_foreach (m, sm->static_mappings)
{
- if (is_sm_addr_only (m->flags) && !is_sm_identity_nat (m->flags))
+ if (is_add)
{
- nat44_ed_add_del_addr_to_fib (&m->external_addr, 32, sw_if_index,
- is_add);
+ nat44_ed_add_fib_entry_reg (m->external_addr, sw_if_index);
+ }
+ else
+ {
+ nat44_ed_del_fib_entry_reg (m->external_addr, sw_if_index);
}
}
}
@@ -544,21 +601,20 @@ nat44_ed_add_address (ip4_address_t *addr, u32 vrf_id, u8 twice_nat)
{
// if we don't have enabled interface we don't add address
// to fib
- nat44_ed_add_del_addr_to_fib_foreach_out_if (addr, 1);
+ nat44_ed_add_del_interface_fib_reg_entries (*addr, 1);
nat44_ed_update_outside_if_addresses (ap);
}
return 0;
}
int
-nat44_ed_del_address (ip4_address_t addr, u8 delete_sm, u8 twice_nat)
+nat44_ed_del_address (ip4_address_t addr, 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;
int j;
addresses = twice_nat ? sm->twice_nat_addresses : sm->addresses;
@@ -577,33 +633,15 @@ nat44_ed_del_address (ip4_address_t addr, u8 delete_sm, u8 twice_nat)
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_internal (
- m->local_addr, m->external_addr, m->local_port,
- m->external_port, ip_proto_to_nat_proto (m->proto), m->vrf_id,
- ~0, m->flags);
- }
- }
- }
- else
- {
- if (is_snat_address_used_in_static_mapping (sm, addr))
- {
- nat_log_err ("address used in static mapping");
- return VNET_API_ERROR_UNSPECIFIED;
- }
- }
-
- // delete sessions using address
+ // delete dynamic sessions only
vec_foreach (tsm, sm->per_thread_data)
{
pool_foreach (ses, tsm->sessions)
{
+ if (ses->flags & SNAT_SESSION_FLAG_STATIC_MAPPING)
+ {
+ continue;
+ }
if (ses->out2in.addr.as_u32 == addr.as_u32)
{
nat44_ed_free_session_data (sm, ses, tsm - sm->per_thread_data,
@@ -621,7 +659,7 @@ nat44_ed_del_address (ip4_address_t addr, u8 delete_sm, u8 twice_nat)
if (!twice_nat)
{
- nat44_ed_add_del_addr_to_fib_foreach_out_if (&addr, 0);
+ nat44_ed_add_del_interface_fib_reg_entries (addr, 0);
}
if (a->fib_index != ~0)
@@ -730,38 +768,18 @@ nat44_ed_sm_i2o_lookup (snat_main_t *sm, ip4_address_t addr, u16 port,
return nat44_ed_sm_lookup (sm, &kv);
}
-void
-nat44_ed_add_resolve_record (ip4_address_t l_addr, u16 l_port, u16 e_port,
- ip_protocol_t proto, u32 vrf_id, u32 sw_if_index,
- u32 flags, ip4_address_t pool_addr, u8 *tag)
-{
- snat_static_map_resolve_t *rp;
- snat_main_t *sm = &snat_main;
-
- vec_add2 (sm->to_resolve, rp, 1);
- rp->l_addr.as_u32 = l_addr.as_u32;
- rp->l_port = l_port;
- rp->e_port = e_port;
- rp->sw_if_index = sw_if_index;
- rp->vrf_id = vrf_id;
- rp->proto = proto;
- rp->flags = flags;
- rp->pool_addr = pool_addr;
- rp->tag = vec_dup (tag);
-}
-
-int
+static snat_static_mapping_resolve_t *
nat44_ed_get_resolve_record (ip4_address_t l_addr, u16 l_port, u16 e_port,
ip_protocol_t proto, u32 vrf_id, u32 sw_if_index,
- u32 flags, int *out)
+ u32 flags, int *out_idx)
{
- snat_static_map_resolve_t *rp;
+ snat_static_mapping_resolve_t *rp;
snat_main_t *sm = &snat_main;
int i;
- for (i = 0; i < vec_len (sm->to_resolve); i++)
+ for (i = 0; i < vec_len (sm->sm_to_resolve); i++)
{
- rp = sm->to_resolve + i;
+ rp = sm->sm_to_resolve + i;
if (rp->sw_if_index == sw_if_index && rp->vrf_id == vrf_id)
{
@@ -790,27 +808,27 @@ nat44_ed_get_resolve_record (ip4_address_t l_addr, u16 l_port, u16 e_port,
{
continue;
}
- if (out)
+ if (out_idx)
{
- *out = i;
+ *out_idx = i;
}
- return 0;
+ return rp;
}
}
- return 1;
+ return NULL;
}
-int
+static int
nat44_ed_del_resolve_record (ip4_address_t l_addr, u16 l_port, u16 e_port,
ip_protocol_t proto, u32 vrf_id, u32 sw_if_index,
u32 flags)
{
snat_main_t *sm = &snat_main;
int i;
- if (!nat44_ed_get_resolve_record (l_addr, l_port, e_port, proto, vrf_id,
- sw_if_index, flags, &i))
+ if (nat44_ed_get_resolve_record (l_addr, l_port, e_port, proto, vrf_id,
+ sw_if_index, flags, &i))
{
- vec_del1 (sm->to_resolve, i);
+ vec_del1 (sm->sm_to_resolve, i);
return 0;
}
return 1;
@@ -835,50 +853,69 @@ nat44_ed_validate_sm_input (u32 flags)
return 0;
}
-snat_address_t *
-nat44_ed_addr_lookup (snat_main_t *sm, u32 addr)
-{
- for (int i = 0; i < vec_len (sm->addresses); ++i)
- {
- if (sm->addresses[i].addr.as_u32 == addr)
- return &sm->addresses[i];
- }
- return NULL;
-}
-
int
nat44_ed_add_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
u16 l_port, u16 e_port, ip_protocol_t proto,
u32 vrf_id, u32 sw_if_index, u32 flags,
ip4_address_t pool_addr, u8 *tag)
{
+ snat_static_mapping_resolve_t *rp;
snat_main_t *sm = &snat_main;
+ int rv;
+
+ if (!sm->enabled)
+ {
+ return VNET_API_ERROR_UNSUPPORTED;
+ }
+
+ rv = nat44_ed_validate_sm_input (flags);
+ if (rv != 0)
+ {
+ return rv;
+ }
// interface bound mapping
if (is_sm_switch_address (flags))
{
- if (!nat44_ed_get_resolve_record (l_addr, l_port, e_port, proto, vrf_id,
- sw_if_index, flags, 0))
+ if (nat44_ed_get_resolve_record (l_addr, l_port, e_port, proto, vrf_id,
+ sw_if_index, flags, 0))
{
return VNET_API_ERROR_VALUE_EXIST;
}
- nat44_ed_add_resolve_record (l_addr, l_port, e_port, proto, vrf_id,
- sw_if_index, flags, pool_addr, tag);
+ vec_add2 (sm->sm_to_resolve, rp, 1);
+ rp->l_addr.as_u32 = l_addr.as_u32;
+ rp->l_port = l_port;
+ rp->e_port = e_port;
+ rp->sw_if_index = sw_if_index;
+ rp->vrf_id = vrf_id;
+ rp->proto = proto;
+ rp->flags = flags;
+ rp->pool_addr = pool_addr;
+ rp->tag = vec_dup (tag);
+ rp->is_resolved = 0;
+
ip4_address_t *first_int_addr =
ip4_interface_first_address (sm->ip4_main, sw_if_index, 0);
if (!first_int_addr)
{
- // dhcp resolution required
return 0;
}
e_addr.as_u32 = first_int_addr->as_u32;
+ rp->is_resolved = 1;
+ }
+
+ rv = nat44_ed_add_static_mapping_internal (l_addr, e_addr, l_port, e_port,
+ proto, vrf_id, sw_if_index, flags,
+ pool_addr, tag);
+ if ((0 != rv) && is_sm_switch_address (flags))
+ {
+ nat44_ed_del_resolve_record (l_addr, l_port, e_port, proto, vrf_id,
+ sw_if_index, flags);
}
- return nat44_ed_add_static_mapping_internal (l_addr, e_addr, l_port, e_port,
- proto, vrf_id, sw_if_index,
- flags, pool_addr, tag);
+ return rv;
}
int
@@ -886,8 +923,19 @@ nat44_ed_del_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
u16 l_port, u16 e_port, ip_protocol_t proto,
u32 vrf_id, u32 sw_if_index, u32 flags)
{
-
snat_main_t *sm = &snat_main;
+ int rv;
+
+ if (!sm->enabled)
+ {
+ return VNET_API_ERROR_UNSUPPORTED;
+ }
+
+ rv = nat44_ed_validate_sm_input (flags);
+ if (rv != 0)
+ {
+ return rv;
+ }
// interface bound mapping
if (is_sm_switch_address (flags))
@@ -909,8 +957,8 @@ nat44_ed_del_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
e_addr.as_u32 = first_int_addr->as_u32;
}
- return nat44_ed_del_static_mapping_internal (
- l_addr, e_addr, l_port, e_port, proto, vrf_id, sw_if_index, flags);
+ return nat44_ed_del_static_mapping_internal (l_addr, e_addr, l_port, e_port,
+ proto, vrf_id, flags);
}
static int
@@ -924,18 +972,6 @@ nat44_ed_add_static_mapping_internal (ip4_address_t l_addr,
nat44_lb_addr_port_t *local;
snat_static_mapping_t *m;
u32 fib_index = ~0;
- int rv;
-
- if (!sm->enabled)
- {
- return VNET_API_ERROR_UNSUPPORTED;
- }
-
- rv = nat44_ed_validate_sm_input (flags);
- if (rv != 0)
- {
- return rv;
- }
if (is_sm_addr_only (flags))
{
@@ -951,13 +987,14 @@ nat44_ed_add_static_mapping_internal (ip4_address_t l_addr,
m = nat44_ed_sm_o2i_lookup (sm, e_addr, e_port, 0, proto);
if (m)
{
+ // case:
+ // adding local identity nat record for different vrf table
+
if (!is_sm_identity_nat (m->flags))
{
return VNET_API_ERROR_VALUE_EXIST;
}
- // case:
- // adding local identity nat record for different vrf table
pool_foreach (local, m->locals)
{
if (local->vrf_id == vrf_id)
@@ -1001,21 +1038,6 @@ nat44_ed_add_static_mapping_internal (ip4_address_t l_addr,
}
}
- if (!(is_sm_out2in_only (flags) || is_sm_addr_only (flags) ||
- sm->static_mapping_only))
- {
- if (!nat44_ed_addr_lookup (sm, e_addr.as_u32))
- {
- // remove resolve record
- if (is_sm_switch_address (flags) && !is_sm_identity_nat (flags))
- {
- nat44_ed_del_resolve_record (l_addr, l_port, e_port, proto,
- vrf_id, sw_if_index, flags);
- }
- return VNET_API_ERROR_NO_SUCH_ENTRY;
- }
- }
-
pool_get (sm->static_mappings, m);
clib_memset (m, 0, sizeof (*m));
@@ -1023,13 +1045,9 @@ nat44_ed_add_static_mapping_internal (ip4_address_t l_addr,
m->local_addr = l_addr;
m->external_addr = e_addr;
+ m->pool_addr = pool_addr;
m->tag = vec_dup (tag);
- if (is_sm_exact_address (flags) && is_sm_twice_nat (flags))
- {
- m->pool_addr = pool_addr;
- }
-
if (!is_sm_addr_only (flags))
{
m->local_port = l_port;
@@ -1048,12 +1066,6 @@ nat44_ed_add_static_mapping_internal (ip4_address_t l_addr,
{
m->vrf_id = vrf_id;
m->fib_index = fib_index;
-
- // not identity && addr only
- if (is_sm_addr_only (flags))
- {
- nat44_ed_add_del_addr_to_fib_foreach_out_if (&e_addr, 1);
- }
}
if (!is_sm_out2in_only (flags))
@@ -1076,6 +1088,8 @@ nat44_ed_add_static_mapping_internal (ip4_address_t l_addr,
vec_add1 (m->workers, worker_index);
}
+ nat44_ed_add_del_interface_fib_reg_entries (e_addr, 1);
+
return 0;
}
@@ -1083,7 +1097,7 @@ static int
nat44_ed_del_static_mapping_internal (ip4_address_t l_addr,
ip4_address_t e_addr, u16 l_port,
u16 e_port, ip_protocol_t proto,
- u32 vrf_id, u32 sw_if_index, u32 flags)
+ u32 vrf_id, u32 flags)
{
snat_main_per_thread_data_t *tsm;
snat_main_t *sm = &snat_main;
@@ -1091,18 +1105,6 @@ nat44_ed_del_static_mapping_internal (ip4_address_t l_addr,
nat44_lb_addr_port_t *local;
snat_static_mapping_t *m;
u32 fib_index = ~0;
- int rv;
-
- if (!sm->enabled)
- {
- return VNET_API_ERROR_UNSUPPORTED;
- }
-
- rv = nat44_ed_validate_sm_input (flags);
- if (rv != 0)
- {
- return rv;
- }
if (is_sm_addr_only (flags))
{
@@ -1117,13 +1119,8 @@ nat44_ed_del_static_mapping_internal (ip4_address_t l_addr,
// fib index 0
m = nat44_ed_sm_o2i_lookup (sm, e_addr, e_port, 0, proto);
-
if (!m)
{
- if (is_sm_switch_address (flags))
- {
- return 0;
- }
return VNET_API_ERROR_NO_SUCH_ENTRY;
}
@@ -1157,33 +1154,25 @@ nat44_ed_del_static_mapping_internal (ip4_address_t l_addr,
fib_index = m->fib_index;
}
- if (!(is_sm_out2in_only (flags) || is_sm_addr_only (flags) ||
- sm->static_mapping_only))
- {
- if (!nat44_ed_addr_lookup (sm, e_addr.as_u32))
- {
- return VNET_API_ERROR_INVALID_VALUE;
- }
- }
-
if (!is_sm_out2in_only (flags))
{
nat44_ed_sm_i2o_del (sm, l_addr, l_port, fib_index, proto);
}
- if (!sm->static_mapping_only || sm->static_mapping_connection_tracking)
+ // delete sessions for static mapping
+ if (sm->num_workers > 1)
{
- // delete sessions for static mapping
- if (sm->num_workers > 1)
- tsm = vec_elt_at_index (sm->per_thread_data, m->workers[0]);
- else
- tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
-
- nat_ed_static_mapping_del_sessions (
- sm, tsm, m->local_addr, m->local_port, m->proto, fib_index,
- is_sm_addr_only (flags), e_addr, e_port);
+ tsm = vec_elt_at_index (sm->per_thread_data, m->workers[0]);
+ }
+ else
+ {
+ tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
}
+ nat_ed_static_mapping_del_sessions (sm, tsm, m->local_addr, m->local_port,
+ m->proto, fib_index,
+ is_sm_addr_only (flags), e_addr, e_port);
+
fib_table_unlock (fib_index, FIB_PROTOCOL_IP4, sm->fib_src_low);
if (!pool_elts (m->locals))
@@ -1196,10 +1185,7 @@ nat44_ed_del_static_mapping_internal (ip4_address_t l_addr,
vec_free (m->workers);
pool_put (sm->static_mappings, m);
- if (is_sm_addr_only (flags) && !is_sm_identity_nat (flags))
- {
- nat44_ed_add_del_addr_to_fib_foreach_out_if (&e_addr, 0);
- }
+ nat44_ed_add_del_interface_fib_reg_entries (e_addr, 0);
}
return 0;
@@ -1238,7 +1224,7 @@ nat44_ed_add_lb_static_mapping (ip4_address_t e_addr, u16 e_port,
return VNET_API_ERROR_INVALID_VALUE;
}
- if (!(sm->static_mapping_only || is_sm_out2in_only (flags)))
+ if (!is_sm_out2in_only (flags))
{
/* Find external address in allocated addresses and reserve port for
address and port pair mapping when dynamic translations enabled */
@@ -1282,7 +1268,7 @@ nat44_ed_add_lb_static_mapping (ip4_address_t e_addr, u16 e_port,
if (nat44_ed_sm_o2i_add (sm, m, m->external_addr, m->external_port, 0,
m->proto))
{
- nat_elog_err (sm, "sm o2i key add failed");
+ nat_log_err ("sm o2i key add failed");
return VNET_API_ERROR_UNSPECIFIED;
}
@@ -1294,7 +1280,7 @@ nat44_ed_add_lb_static_mapping (ip4_address_t e_addr, u16 e_port,
{
if (nat44_ed_sm_o2i_add (sm, m, e_addr, e_port, 0, proto))
{
- nat_elog_err (sm, "sm o2i key add failed");
+ nat_log_err ("sm o2i key add failed");
rc = VNET_API_ERROR_UNSPECIFIED;
// here we continue with add operation so that it can be safely
// reversed in delete path - otherwise we'd have to track what
@@ -1357,7 +1343,7 @@ nat44_ed_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port,
if (nat44_ed_sm_o2i_del (sm, m->external_addr, m->external_port, 0,
m->proto))
{
- nat_elog_err (sm, "sm o2i key del failed");
+ nat_log_err ("sm o2i key del failed");
return VNET_API_ERROR_UNSPECIFIED;
}
@@ -1369,7 +1355,7 @@ nat44_ed_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port,
if (nat44_ed_sm_i2o_del (sm, local->addr, local->port,
local->fib_index, m->proto))
{
- nat_elog_err (sm, "sm i2o key del failed");
+ nat_log_err ("sm i2o key del failed");
return VNET_API_ERROR_UNSPECIFIED;
}
}
@@ -1478,7 +1464,7 @@ nat44_ed_add_del_lb_static_mapping_local (ip4_address_t e_addr, u16 e_port,
if (nat44_ed_sm_i2o_add (sm, m, l_addr, l_port, local->fib_index,
proto))
{
- nat_elog_err (sm, "sm i2o key add failed");
+ nat_log_err ("sm i2o key add failed");
pool_put (m->locals, local);
return VNET_API_ERROR_UNSPECIFIED;
}
@@ -1499,7 +1485,7 @@ nat44_ed_add_del_lb_static_mapping_local (ip4_address_t e_addr, u16 e_port,
{
if (nat44_ed_sm_i2o_del (sm, l_addr, l_port, match_local->fib_index,
proto))
- nat_elog_err (sm, "sm i2o key del failed");
+ nat_log_err ("sm i2o key del failed");
}
if (sm->num_workers > 1)
@@ -1747,8 +1733,8 @@ nat44_ed_add_interface (u32 sw_if_index, u8 is_inside)
outside_fib->refcount = 1;
}
- nat44_ed_add_del_addr_to_fib_foreach_addr (sw_if_index, 1);
- nat44_ed_add_del_addr_to_fib_foreach_addr_only_sm (sw_if_index, 1);
+ nat44_ed_add_del_nat_addr_fib_reg_entries (sw_if_index, 1);
+ nat44_ed_add_del_sm_fib_reg_entries (sw_if_index, 1);
nat44_ed_bind_if_addr_to_nat_addr (sw_if_index);
}
@@ -1858,8 +1844,8 @@ nat44_ed_del_interface (u32 sw_if_index, u8 is_inside)
}
}
- nat44_ed_add_del_addr_to_fib_foreach_addr (sw_if_index, 0);
- nat44_ed_add_del_addr_to_fib_foreach_addr_only_sm (sw_if_index, 0);
+ nat44_ed_add_del_nat_addr_fib_reg_entries (sw_if_index, 0);
+ nat44_ed_add_del_sm_fib_reg_entries (sw_if_index, 0);
}
return 0;
@@ -1957,8 +1943,8 @@ nat44_ed_add_output_interface (u32 sw_if_index)
outside_fib->refcount = 1;
}
- nat44_ed_add_del_addr_to_fib_foreach_addr (sw_if_index, 1);
- nat44_ed_add_del_addr_to_fib_foreach_addr_only_sm (sw_if_index, 1);
+ nat44_ed_add_del_nat_addr_fib_reg_entries (sw_if_index, 1);
+ nat44_ed_add_del_sm_fib_reg_entries (sw_if_index, 1);
nat44_ed_bind_if_addr_to_nat_addr (sw_if_index);
@@ -2045,8 +2031,8 @@ nat44_ed_del_output_interface (u32 sw_if_index)
}
}
- nat44_ed_add_del_addr_to_fib_foreach_addr (sw_if_index, 0);
- nat44_ed_add_del_addr_to_fib_foreach_addr_only_sm (sw_if_index, 0);
+ nat44_ed_add_del_nat_addr_fib_reg_entries (sw_if_index, 0);
+ nat44_ed_add_del_sm_fib_reg_entries (sw_if_index, 0);
return 0;
}
@@ -2103,7 +2089,7 @@ nat44_ed_update_outside_fib_cb (ip4_main_t *im, uword opaque, u32 sw_if_index,
}
pool_foreach (i, sm->interfaces)
- {
+ {
if (i->sw_if_index == sw_if_index)
{
if (!(nat44_ed_is_interface_outside (i)))
@@ -2113,7 +2099,7 @@ nat44_ed_update_outside_fib_cb (ip4_main_t *im, uword opaque, u32 sw_if_index,
}
pool_foreach (i, sm->output_feature_interfaces)
- {
+ {
if (i->sw_if_index == sw_if_index)
{
if (!(nat44_ed_is_interface_outside (i)))
@@ -2126,25 +2112,25 @@ nat44_ed_update_outside_fib_cb (ip4_main_t *im, uword opaque, u32 sw_if_index,
return;
vec_foreach (outside_fib, sm->outside_fibs)
- {
- if (outside_fib->fib_index == old_fib_index)
- {
- outside_fib->refcount--;
- if (!outside_fib->refcount)
- vec_del1 (sm->outside_fibs, outside_fib - sm->outside_fibs);
- break;
- }
- }
+ {
+ if (outside_fib->fib_index == old_fib_index)
+ {
+ outside_fib->refcount--;
+ if (!outside_fib->refcount)
+ vec_del1 (sm->outside_fibs, outside_fib - sm->outside_fibs);
+ break;
+ }
+ }
vec_foreach (outside_fib, sm->outside_fibs)
- {
- if (outside_fib->fib_index == new_fib_index)
- {
- outside_fib->refcount++;
- is_add = 0;
- break;
- }
- }
+ {
+ if (outside_fib->fib_index == new_fib_index)
+ {
+ outside_fib->refcount++;
+ is_add = 0;
+ break;
+ }
+ }
if (is_add)
{
@@ -2162,7 +2148,7 @@ 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 nat44_ed_add_del_static_mapping_addr_only_cb (
+static void nat44_ed_add_del_static_mapping_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);
@@ -2351,7 +2337,7 @@ nat_init (vlib_main_t * vm)
/* callbacks to call when interface address changes. */
cbi.function = nat44_ed_add_del_interface_address_cb;
vec_add1 (sm->ip4_main->add_del_interface_address_callbacks, cbi);
- cbi.function = nat44_ed_add_del_static_mapping_addr_only_cb;
+ cbi.function = nat44_ed_add_del_static_mapping_cb;
vec_add1 (sm->ip4_main->add_del_interface_address_callbacks, cbi);
/* callbacks to call when interface to table biding changes */
@@ -2380,19 +2366,8 @@ nat44_plugin_enable (nat44_config_t c)
fail_if_enabled ();
- if (c.static_mapping_only && !c.connection_tracking)
- {
- nat_log_err ("unsupported combination of configuration");
- return 1;
- }
-
- sm->static_mapping_only = c.static_mapping_only;
- sm->static_mapping_connection_tracking = c.connection_tracking;
-
sm->forwarding_enabled = 0;
sm->mss_clamping = 0;
- sm->pat = (!c.static_mapping_only ||
- (c.static_mapping_only && c.connection_tracking));
if (!c.sessions)
c.sessions = 63 * 1024;
@@ -2461,7 +2436,7 @@ nat44_ed_del_addresses ()
vec = vec_dup (sm->addresses);
vec_foreach (a, vec)
{
- error = nat44_ed_del_address (a->addr, 0, 0);
+ error = nat44_ed_del_address (a->addr, 0);
if (error)
{
nat_log_err ("error occurred while removing adderess");
@@ -2474,7 +2449,7 @@ nat44_ed_del_addresses ()
vec = vec_dup (sm->twice_nat_addresses);
vec_foreach (a, vec)
{
- error = nat44_ed_del_address (a->addr, 0, 1);
+ error = nat44_ed_del_address (a->addr, 1);
if (error)
{
nat_log_err ("error occurred while removing adderess");
@@ -2484,11 +2459,8 @@ nat44_ed_del_addresses ()
vec_free (sm->twice_nat_addresses);
sm->twice_nat_addresses = 0;
- vec_free (sm->auto_add_sw_if_indices_twice_nat);
- sm->auto_add_sw_if_indices_twice_nat = 0;
-
- vec_free (sm->auto_add_sw_if_indices);
- sm->auto_add_sw_if_indices = 0;
+ vec_free (sm->addr_to_resolve);
+ sm->addr_to_resolve = 0;
return error;
}
@@ -2557,7 +2529,7 @@ nat44_ed_del_static_mappings ()
{
error = nat44_ed_del_static_mapping_internal (
m->local_addr, m->external_addr, m->local_port, m->external_port,
- m->proto, m->vrf_id, ~0, m->flags);
+ m->proto, m->vrf_id, m->flags);
if (error)
{
nat_log_err ("error occurred while removing mapping");
@@ -2567,8 +2539,8 @@ nat44_ed_del_static_mappings ()
pool_free (sm->static_mappings);
sm->static_mappings = 0;
- vec_free (sm->to_resolve);
- sm->to_resolve = 0;
+ vec_free (sm->sm_to_resolve);
+ sm->sm_to_resolve = 0;
return error;
}
@@ -2603,12 +2575,9 @@ nat44_plugin_disable ()
clib_bihash_free_16_8 (&sm->flow_hash);
- if (sm->pat)
+ vec_foreach (tsm, sm->per_thread_data)
{
- vec_foreach (tsm, sm->per_thread_data)
- {
- nat44_ed_worker_db_free (tsm);
- }
+ nat44_ed_worker_db_free (tsm);
}
clib_memset (&sm->rconfig, 0, sizeof (sm->rconfig));
@@ -3231,13 +3200,10 @@ nat44_ed_db_init (u32 translations, u32 translation_buckets)
reinit_ed_flow_hash ();
- if (sm->pat)
+ vec_foreach (tsm, sm->per_thread_data)
{
- vec_foreach (tsm, sm->per_thread_data)
- {
- nat44_ed_worker_db_init (tsm, sm->max_translations_per_thread,
- sm->translation_buckets);
- }
+ nat44_ed_worker_db_init (tsm, sm->max_translations_per_thread,
+ sm->translation_buckets);
}
}
@@ -3257,95 +3223,105 @@ nat44_ed_sessions_clear ()
reinit_ed_flow_hash ();
- if (sm->pat)
+ vec_foreach (tsm, sm->per_thread_data)
{
- vec_foreach (tsm, sm->per_thread_data)
- {
-
- nat44_ed_worker_db_free (tsm);
- nat44_ed_worker_db_init (tsm, sm->max_translations_per_thread,
- sm->translation_buckets);
- }
+ nat44_ed_worker_db_free (tsm);
+ nat44_ed_worker_db_init (tsm, sm->max_translations_per_thread,
+ sm->translation_buckets);
}
vlib_zero_simple_counter (&sm->total_sessions, 0);
}
static void
-nat44_ed_add_del_static_mapping_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)
+nat44_ed_add_del_static_mapping_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_static_map_resolve_t *rp;
+ snat_static_mapping_resolve_t *rp;
snat_main_t *sm = &snat_main;
- snat_static_mapping_t *m;
- int i, rv = 0, match = 0;
+ int rv = 0;
if (!sm->enabled)
{
return;
}
- // find first addr_only resolve record by sw_if_index
- for (i = 0; i < vec_len (sm->to_resolve); i++)
+ vec_foreach (rp, sm->sm_to_resolve)
{
- rp = sm->to_resolve + i;
- if (is_sm_addr_only (rp->flags) && rp->sw_if_index == sw_if_index)
+ if (sw_if_index == rp->sw_if_index)
{
- match = 1;
- break;
+ if (is_delete)
+ {
+ if (rp->is_resolved)
+ {
+ rv = nat44_ed_del_static_mapping_internal (
+ rp->l_addr, address[0], rp->l_port, rp->e_port, rp->proto,
+ rp->vrf_id, rp->flags);
+ if (rv)
+ {
+ nat_log_err ("ed del static mapping failed");
+ }
+ else
+ {
+ rp->is_resolved = 0;
+ }
+ }
+ }
+ else
+ {
+ if (!rp->is_resolved)
+ {
+ rv = nat44_ed_add_static_mapping_internal (
+ rp->l_addr, address[0], rp->l_port, rp->e_port, rp->proto,
+ rp->vrf_id, ~0, rp->flags, rp->pool_addr, rp->tag);
+ if (rv)
+ {
+ nat_log_err ("ed add static mapping failed");
+ }
+ else
+ {
+ rp->is_resolved = 1;
+ }
+ }
+ }
}
}
- if (!match)
- {
- return;
- }
+}
- m = nat44_ed_sm_o2i_lookup (
- sm, *address, is_sm_addr_only (rp->flags) ? 0 : rp->e_port, 0, rp->proto);
+static int
+nat44_ed_get_addr_resolve_record (u32 sw_if_index, u8 twice_nat, int *out)
+{
+ snat_main_t *sm = &snat_main;
+ snat_address_resolve_t *rp;
+ int i;
- if (is_delete)
- {
- if (m)
- {
- rv = nat44_ed_del_static_mapping_internal (
- rp->l_addr, address[0], rp->l_port, rp->e_port, rp->proto,
- rp->vrf_id, ~0, rp->flags);
- }
- if (rv)
- {
- nat_elog_notice_X1 (sm, "nat44_ed_del_static_mapping returned %d",
- "i4", rv);
- }
- }
- else
+ for (i = 0; i < vec_len (sm->addr_to_resolve); i++)
{
- if (!m)
- {
- rv = nat44_ed_add_static_mapping_internal (
- rp->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)
+ rp = sm->addr_to_resolve + i;
+
+ if ((rp->sw_if_index == sw_if_index) && (rp->is_twice_nat == twice_nat))
{
- nat_elog_notice_X1 (sm, "nat44_ed_add_static_mapping returned %d",
- "i4", rv);
+ if (out)
+ {
+ *out = i;
+ }
+ return 0;
}
}
+ return 1;
}
-
-static_always_inline int
-is_sw_if_index_reg_for_auto_resolve (u32 *sw_if_indices, u32 sw_if_index)
+static int
+nat44_ed_del_addr_resolve_record (u32 sw_if_index, u8 twice_nat)
{
- u32 *i;
- vec_foreach (i, sw_if_indices)
+ snat_main_t *sm = &snat_main;
+ int i;
+ if (!nat44_ed_get_addr_resolve_record (sw_if_index, twice_nat, &i))
{
- if (*i == sw_if_index)
- {
- return 1;
- }
+ vec_del1 (sm->addr_to_resolve, i);
+ return 0;
}
- return 0;
+ return 1;
}
static void
@@ -3355,23 +3331,21 @@ nat44_ed_add_del_interface_address_cb (ip4_main_t *im, uword opaque,
u32 if_address_index, u32 is_delete)
{
snat_main_t *sm = &snat_main;
- snat_static_map_resolve_t *rp;
- snat_address_t *ap, *addresses = sm->addresses;
+ snat_address_resolve_t *arp;
+ snat_address_t *ap;
u8 twice_nat = 0;
- int rv, i;
+ int i, rv;
if (!sm->enabled)
{
return;
}
- if (!is_sw_if_index_reg_for_auto_resolve (sm->auto_add_sw_if_indices,
- sw_if_index))
+ if (nat44_ed_get_addr_resolve_record (sw_if_index, twice_nat, &i))
{
- if (!is_sw_if_index_reg_for_auto_resolve (
- sm->auto_add_sw_if_indices_twice_nat, sw_if_index))
+ twice_nat = 1;
+ if (nat44_ed_get_addr_resolve_record (sw_if_index, twice_nat, &i))
{
- // interface resolve
u32 fib_index =
ip4_fib_table_get_index_for_sw_if_index (sw_if_index);
vec_foreach (ap, sm->addresses)
@@ -3400,51 +3374,35 @@ nat44_ed_add_del_interface_address_cb (ip4_main_t *im, uword opaque,
}
return;
}
- else
- {
- addresses = sm->twice_nat_addresses;
- twice_nat = 1;
- }
}
+ arp = sm->addr_to_resolve + i;
+
if (!is_delete)
{
- // don't trip over lease renewal, static config
- for (i = 0; i < vec_len (addresses); i++)
+ if (arp->is_resolved)
{
- if (addresses[i].addr.as_u32 == address->as_u32)
- {
- return;
- }
+ return;
}
- (void) nat44_ed_add_address (address, ~0, twice_nat);
-
- // scan static mapping switch address resolution record vector
- for (i = 0; i < vec_len (sm->to_resolve); i++)
+ rv = nat44_ed_add_address (address, ~0, arp->is_twice_nat);
+ if (0 == rv)
{
- rp = sm->to_resolve + i;
- if (is_sm_addr_only (rp->flags))
- {
- continue;
- }
- if (rp->sw_if_index == sw_if_index)
- {
- rv = nat44_ed_add_static_mapping_internal (
- rp->l_addr, address[0], rp->l_port, rp->e_port, rp->proto,
- rp->vrf_id, sw_if_index, rp->flags, rp->pool_addr, rp->tag);
- if (rv)
- {
- nat_elog_notice_X1 (
- sm, "add_static_mapping_internal returned %d", "i4", rv);
- }
- }
+ arp->is_resolved = 1;
}
}
else
{
- // remove all static mapping records
- (void) nat44_ed_del_address (address[0], 1, twice_nat);
+ if (!arp->is_resolved)
+ {
+ return;
+ }
+
+ rv = nat44_ed_del_address (address[0], arp->is_twice_nat);
+ if (0 == rv)
+ {
+ arp->is_resolved = 0;
+ }
}
}
@@ -3454,34 +3412,34 @@ 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;
+ snat_address_resolve_t *ap;
+ int rv;
- for (i = 0; i < vec_len (auto_add_sw_if_indices); i++)
+ if (!sm->enabled)
{
- if (auto_add_sw_if_indices[i] == sw_if_index)
- {
- return VNET_API_ERROR_VALUE_EXIST;
- }
+ return VNET_API_ERROR_UNSUPPORTED;
}
- // add to the auto-address list
- if (twice_nat)
- {
- vec_add1 (sm->auto_add_sw_if_indices_twice_nat, sw_if_index);
- }
- else
+ if (!nat44_ed_get_addr_resolve_record (sw_if_index, twice_nat, 0))
{
- vec_add1 (sm->auto_add_sw_if_indices, sw_if_index);
+ return VNET_API_ERROR_VALUE_EXIST;
}
- // if the address is already bound - or static - add it now
+ vec_add2 (sm->addr_to_resolve, ap, 1);
+ ap->sw_if_index = sw_if_index;
+ ap->is_twice_nat = twice_nat;
+ ap->is_resolved = 0;
+
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);
+ rv = nat44_ed_add_address (first_int_addr, ~0, twice_nat);
+ if (0 != rv)
+ {
+ nat44_ed_del_addr_resolve_record (sw_if_index, twice_nat);
+ return rv;
+ }
+ ap->is_resolved = 1;
}
return 0;
@@ -3493,62 +3451,24 @@ 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;
- u32 *indices_to_delete = 0;
- int i, j;
- u32 *auto_add_sw_if_indices;
if (!sm->enabled)
{
return VNET_API_ERROR_UNSUPPORTED;
}
- auto_add_sw_if_indices = twice_nat ? sm->auto_add_sw_if_indices_twice_nat :
- sm->auto_add_sw_if_indices;
-
- for (i = 0; i < vec_len (auto_add_sw_if_indices); i++)
+ if (nat44_ed_del_addr_resolve_record (sw_if_index, twice_nat))
{
- if (auto_add_sw_if_indices[i] == sw_if_index)
- {
- first_int_addr =
- ip4_interface_first_address (ip4_main, sw_if_index, 0);
- if (first_int_addr)
- {
- // 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++)
- {
- rp = sm->to_resolve + j;
- if (rp->sw_if_index == sw_if_index)
- {
- vec_add1 (indices_to_delete, j);
- }
- }
- if (vec_len (indices_to_delete))
- {
- for (j = vec_len (indices_to_delete) - 1; j >= 0; j--)
- {
- vec_del1 (sm->to_resolve, j);
- }
- vec_free (indices_to_delete);
- }
- }
+ return VNET_API_ERROR_NO_SUCH_ENTRY;
+ }
- 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;
- }
+ first_int_addr = ip4_interface_first_address (ip4_main, sw_if_index, 0);
+ if (first_int_addr)
+ {
+ return nat44_ed_del_address (first_int_addr[0], twice_nat);
}
- return VNET_API_ERROR_NO_SUCH_ENTRY;
+
+ return 0;
}
int
diff --git a/src/plugins/nat/nat44-ed/nat44_ed.h b/src/plugins/nat/nat44-ed/nat44_ed.h
index d8cc0d3aece..9772f1ec79a 100644
--- a/src/plugins/nat/nat44-ed/nat44_ed.h
+++ b/src/plugins/nat/nat44-ed/nat44_ed.h
@@ -63,10 +63,6 @@ typedef enum nat44_config_flags_t_
typedef struct
{
- /* nat44 plugin features */
- u8 static_mapping_only;
- u8 connection_tracking;
-
u32 inside_vrf;
u32 outside_vrf;
@@ -450,6 +446,7 @@ typedef struct
typedef struct
{
+ u8 is_resolved;
ip4_address_t l_addr;
ip4_address_t pool_addr;
u16 l_port;
@@ -459,7 +456,21 @@ typedef struct
ip_protocol_t proto;
u32 flags;
u8 *tag;
-} snat_static_map_resolve_t;
+} snat_static_mapping_resolve_t;
+
+typedef struct
+{
+ u8 is_resolved;
+ u8 is_twice_nat;
+ u32 sw_if_index;
+} snat_address_resolve_t;
+
+typedef struct
+{
+ u32 count;
+ u32 sw_if_index;
+ ip4_address_t addr;
+} snat_fib_entry_reg_t;
typedef struct
{
@@ -533,9 +544,8 @@ typedef struct snat_main_s
/* Vector of twice NAT addresses for external hosts */
snat_address_t *twice_nat_addresses;
- /* sw_if_indices whose intfc addresses should be auto-added */
- u32 *auto_add_sw_if_indices;
- u32 *auto_add_sw_if_indices_twice_nat;
+ /* first interface address should be auto-added */
+ snat_address_resolve_t *addr_to_resolve;
/* Address and port allocation function */
nat_alloc_out_addr_and_port_function_t *alloc_addr_and_port;
@@ -555,8 +565,11 @@ typedef struct snat_main_s
/* vector of outside fibs */
nat_outside_fib_t *outside_fibs;
+ /* vector of fib entries */
+ snat_fib_entry_reg_t *fib_entry_reg;
+
/* vector of interface address static mappings to resolve. */
- snat_static_map_resolve_t *to_resolve;
+ snat_static_mapping_resolve_t *sm_to_resolve;
/* Randomize port allocation order */
u32 random_seed;
@@ -576,10 +589,6 @@ typedef struct snat_main_s
/* If forwarding is enabled */
u8 forwarding_enabled;
- /* static mapping config */
- u8 static_mapping_only;
- u8 static_mapping_connection_tracking;
-
/* Is translation memory size calculated or user defined */
u8 translation_memory_size_set;
@@ -651,9 +660,6 @@ typedef struct snat_main_s
fib_source_t fib_src_hi;
fib_source_t fib_src_low;
- /* pat - dynamic mapping enabled or conneciton tracking */
- u8 pat;
-
/* number of worker handoff frame queue elements */
u32 frame_queue_nelts;
@@ -876,7 +882,7 @@ 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_del_address (ip4_address_t addr, 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);
diff --git a/src/plugins/nat/nat44-ed/nat44_ed_api.c b/src/plugins/nat/nat44-ed/nat44_ed_api.c
index 6b769672135..4664fabfec5 100644
--- a/src/plugins/nat/nat44-ed/nat44_ed_api.c
+++ b/src/plugins/nat/nat44-ed/nat44_ed_api.c
@@ -47,15 +47,19 @@ vl_api_nat44_ed_plugin_enable_disable_t_handler (
if (mp->enable)
{
- c.static_mapping_only = mp->flags & NAT44_API_IS_STATIC_MAPPING_ONLY;
- c.connection_tracking = mp->flags & NAT44_API_IS_CONNECTION_TRACKING;
-
- c.inside_vrf = ntohl (mp->inside_vrf);
- c.outside_vrf = ntohl (mp->outside_vrf);
-
- c.sessions = ntohl (mp->sessions);
+ if ((mp->flags & NAT44_API_IS_STATIC_MAPPING_ONLY) ||
+ (mp->flags & NAT44_API_IS_CONNECTION_TRACKING))
+ {
+ rv = VNET_API_ERROR_UNSUPPORTED;
+ }
+ else
+ {
+ c.sessions = ntohl (mp->sessions);
+ c.inside_vrf = ntohl (mp->inside_vrf);
+ c.outside_vrf = ntohl (mp->outside_vrf);
- rv = nat44_plugin_enable (c);
+ rv = nat44_plugin_enable (c);
+ }
}
else
{
@@ -275,12 +279,6 @@ static void
int rv = 0;
u32 *tmp;
- if (sm->static_mapping_only)
- {
- rv = VNET_API_ERROR_FEATURE_DISABLED;
- goto send_reply;
- }
-
is_add = mp->is_add;
twice_nat = mp->flags & NAT_API_IS_TWICE_NAT;
@@ -308,7 +306,7 @@ static void
}
else
{
- rv = nat44_ed_del_address (this_addr, 0, twice_nat);
+ rv = nat44_ed_del_address (this_addr, twice_nat);
}
if (rv)
@@ -821,9 +819,8 @@ send_nat44_static_mapping_details (snat_static_mapping_t * m,
}
static void
-send_nat44_static_map_resolve_details (snat_static_map_resolve_t * m,
- vl_api_registration_t * reg,
- u32 context)
+send_nat44_static_map_resolve_details (snat_static_mapping_resolve_t *m,
+ vl_api_registration_t *reg, u32 context)
{
vl_api_nat44_static_mapping_details_t *rmp;
snat_main_t *sm = &snat_main;
@@ -866,7 +863,7 @@ vl_api_nat44_static_mapping_dump_t_handler (vl_api_nat44_static_mapping_dump_t
vl_api_registration_t *reg;
snat_main_t *sm = &snat_main;
snat_static_mapping_t *m;
- snat_static_map_resolve_t *rp;
+ snat_static_mapping_resolve_t *rp;
int j;
reg = vl_api_client_index_to_registration (mp->client_index);
@@ -879,9 +876,9 @@ vl_api_nat44_static_mapping_dump_t_handler (vl_api_nat44_static_mapping_dump_t
send_nat44_static_mapping_details (m, reg, mp->context);
}
- for (j = 0; j < vec_len (sm->to_resolve); j++)
+ for (j = 0; j < vec_len (sm->sm_to_resolve); j++)
{
- rp = sm->to_resolve + j;
+ rp = sm->sm_to_resolve + j;
if (!is_sm_identity_nat (rp->flags))
send_nat44_static_map_resolve_details (rp, reg, mp->context);
}
@@ -973,8 +970,8 @@ send_nat44_identity_mapping_details (snat_static_mapping_t * m, int index,
}
static void
-send_nat44_identity_map_resolve_details (snat_static_map_resolve_t * m,
- vl_api_registration_t * reg,
+send_nat44_identity_map_resolve_details (snat_static_mapping_resolve_t *m,
+ vl_api_registration_t *reg,
u32 context)
{
vl_api_nat44_identity_mapping_details_t *rmp;
@@ -1006,7 +1003,7 @@ static void
vl_api_registration_t *reg;
snat_main_t *sm = &snat_main;
snat_static_mapping_t *m;
- snat_static_map_resolve_t *rp;
+ snat_static_mapping_resolve_t *rp;
int j;
reg = vl_api_client_index_to_registration (mp->client_index);
@@ -1024,9 +1021,9 @@ static void
}
}
- for (j = 0; j < vec_len (sm->to_resolve); j++)
+ for (j = 0; j < vec_len (sm->sm_to_resolve); j++)
{
- rp = sm->to_resolve + j;
+ rp = sm->sm_to_resolve + j;
if (is_sm_identity_nat (rp->flags))
send_nat44_identity_map_resolve_details (rp, reg, mp->context);
}
@@ -1042,12 +1039,6 @@ static void
u8 twice_nat;
int rv = 0;
- if (sm->static_mapping_only)
- {
- rv = VNET_API_ERROR_FEATURE_DISABLED;
- goto send_reply;
- }
-
VALIDATE_SW_IF_INDEX (mp);
twice_nat = mp->flags & NAT_API_IS_TWICE_NAT;
@@ -1063,7 +1054,6 @@ static void
BAD_SW_IF_INDEX_LABEL;
-send_reply:
REPLY_MACRO (VL_API_NAT44_ADD_DEL_INTERFACE_ADDR_REPLY);
}
@@ -1092,21 +1082,18 @@ static void
vl_api_nat44_interface_addr_dump_t_handler (vl_api_nat44_interface_addr_dump_t
* mp)
{
- vl_api_registration_t *reg;
snat_main_t *sm = &snat_main;
- u32 *i;
+ vl_api_registration_t *reg;
+ snat_address_resolve_t *ap;
reg = vl_api_client_index_to_registration (mp->client_index);
if (!reg)
return;
- vec_foreach (i, sm->auto_add_sw_if_indices)
- {
- send_nat44_interface_addr_details (*i, reg, mp->context, 0);
- }
- vec_foreach (i, sm->auto_add_sw_if_indices_twice_nat)
+ vec_foreach (ap, sm->addr_to_resolve)
{
- send_nat44_interface_addr_details (*i, reg, mp->context, 1);
+ send_nat44_interface_addr_details (ap->sw_if_index, reg, mp->context,
+ ap->is_twice_nat);
}
}
@@ -1446,20 +1433,18 @@ vl_api_nat44_plugin_enable_disable_t_handler (
if (mp->enable)
{
- if (mp->users || mp->user_sessions)
+ if ((mp->flags & NAT44_API_IS_STATIC_MAPPING_ONLY) ||
+ (mp->flags & NAT44_API_IS_CONNECTION_TRACKING) || mp->users ||
+ mp->user_sessions)
{
rv = VNET_API_ERROR_UNSUPPORTED;
}
else
{
- c.static_mapping_only = mp->flags & NAT44_API_IS_STATIC_MAPPING_ONLY;
- c.connection_tracking = mp->flags & NAT44_API_IS_CONNECTION_TRACKING;
-
+ c.sessions = ntohl (mp->sessions);
c.inside_vrf = ntohl (mp->inside_vrf);
c.outside_vrf = ntohl (mp->outside_vrf);
- c.sessions = ntohl (mp->sessions);
-
rv = nat44_plugin_enable (c);
}
}
@@ -1496,9 +1481,8 @@ vl_api_nat_show_config_t_handler (vl_api_nat_show_config_t *mp)
rmp->max_translations_per_user = 0;
rmp->outside_vrf_id = htonl (sm->outside_vrf_id);
rmp->inside_vrf_id = htonl (sm->inside_vrf_id);
- rmp->static_mapping_only = sm->static_mapping_only;
- rmp->static_mapping_connection_tracking =
- sm->static_mapping_connection_tracking;
+ rmp->static_mapping_only = 0;
+ rmp->static_mapping_connection_tracking = 0;
rmp->endpoint_dependent = 1;
rmp->out2in_dpo = 0;
}));
@@ -1518,9 +1502,8 @@ vl_api_nat_show_config_2_t_handler (vl_api_nat_show_config_2_t *mp)
rmp->max_translations_per_user = 0;
rmp->outside_vrf_id = htonl (sm->outside_vrf_id);
rmp->inside_vrf_id = htonl (sm->inside_vrf_id);
- rmp->static_mapping_only = sm->static_mapping_only;
- rmp->static_mapping_connection_tracking =
- sm->static_mapping_connection_tracking;
+ rmp->static_mapping_only = 0;
+ rmp->static_mapping_connection_tracking = 0;
rmp->endpoint_dependent = 1;
rmp->out2in_dpo = 0;
rmp->max_translations_per_thread =
@@ -1560,10 +1543,6 @@ vl_api_nat44_show_running_config_t_handler (
// consider how to split functionality between subplugins
rmp->ipfix_logging_enabled = nat_ipfix_logging_enabled ();
rmp->flags |= NAT44_IS_ENDPOINT_DEPENDENT;
- if (rc->static_mapping_only)
- rmp->flags |= NAT44_IS_STATIC_MAPPING_ONLY;
- if (rc->connection_tracking)
- rmp->flags |= NAT44_IS_CONNECTION_TRACKING;
}));
}
diff --git a/src/plugins/nat/nat44-ed/nat44_ed_cli.c b/src/plugins/nat/nat44-ed/nat44_ed_cli.c
index 9743ce6e6ea..cfd36278674 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)
@@ -350,7 +342,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;
@@ -386,12 +377,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);
@@ -418,7 +403,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)
@@ -1279,14 +1264,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;
@@ -1358,21 +1343,14 @@ nat44_show_interface_address_command_fn (vlib_main_t * vm,
{
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)
+ 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" : "");
}
- vlib_cli_output (vm, "NAT44 twice-nat pool address interfaces:");
- vec_foreach (sw_if_index, sm->auto_add_sw_if_indices_twice_nat)
- {
- vlib_cli_output (vm, " %U", format_vnet_sw_if_index_name, vnm,
- *sw_if_index);
- }
-
return 0;
}
@@ -1737,16 +1715,13 @@ done:
* vpp# nat44 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
* To set inside-vrf outside-vrf, use:
* vpp# nat44 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>] "
+ .short_help = "nat44 <enable [sessions <max-number>] [inside-vrf <vrf-id>] "
"[outside-vrf <vrf-id>]>|disable",
.function = nat44_ed_enable_disable_command_fn,
};
diff --git a/src/plugins/nat/nat44-ed/nat44_ed_format.c b/src/plugins/nat/nat44-ed/nat44_ed_format.c
index 81e743fd276..a6f63026897 100644
--- a/src/plugins/nat/nat44-ed/nat44_ed_format.c
+++ b/src/plugins/nat/nat44-ed/nat44_ed_format.c
@@ -188,7 +188,8 @@ format_snat_static_mapping (u8 * s, va_list * args)
u8 *
format_snat_static_map_to_resolve (u8 * s, va_list * args)
{
- snat_static_map_resolve_t *m = va_arg (*args, snat_static_map_resolve_t *);
+ snat_static_mapping_resolve_t *m =
+ va_arg (*args, snat_static_mapping_resolve_t *);
vnet_main_t *vnm = vnet_get_main ();
if (is_sm_addr_only (m->flags))
diff --git a/src/plugins/nat/nat44-ed/nat44_ed_in2out.c b/src/plugins/nat/nat44-ed/nat44_ed_in2out.c
index e93198a8079..23e0957dabe 100644
--- a/src/plugins/nat/nat44-ed/nat44_ed_in2out.c
+++ b/src/plugins/nat/nat44-ed/nat44_ed_in2out.c
@@ -278,7 +278,7 @@ nat_ed_alloc_addr_and_port (snat_main_t *sm, u32 rx_fib_index,
}
else
{
- // frist try nat pool addresses to sw interface addreses mappings
+ // first try nat pool addresses to sw interface addreses mappings
for (i = s_addr_offset; i < vec_len (sm->addresses); ++i)
{
a = sm->addresses + i;