aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/nat
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/nat')
-rw-r--r--src/plugins/nat/nat44-ed/nat44_ed.c1257
-rw-r--r--src/plugins/nat/nat44-ed/nat44_ed.h211
-rw-r--r--src/plugins/nat/nat44-ed/nat44_ed_affinity.h2
-rw-r--r--src/plugins/nat/nat44-ed/nat44_ed_api.c337
-rw-r--r--src/plugins/nat/nat44-ed/nat44_ed_cli.c197
-rw-r--r--src/plugins/nat/nat44-ed/nat44_ed_format.c71
-rw-r--r--src/plugins/nat/nat44-ed/nat44_ed_handoff.c6
-rw-r--r--src/plugins/nat/nat44-ed/nat44_ed_in2out.c2
-rw-r--r--src/plugins/nat/nat44-ed/nat44_ed_out2in.c8
9 files changed, 1195 insertions, 896 deletions
diff --git a/src/plugins/nat/nat44-ed/nat44_ed.c b/src/plugins/nat/nat44-ed/nat44_ed.c
index dcd7ae0a140..4e13907a9d8 100644
--- a/src/plugins/nat/nat44-ed/nat44_ed.c
+++ b/src/plugins/nat/nat44-ed/nat44_ed.c
@@ -385,43 +385,15 @@ 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_addr_only_static_mapping (m) ||
- is_out2in_only_static_mapping (m) ||
- is_identity_static_mapping (m))
- continue;
- if (m->external_addr.as_u32 == addr.as_u32)
- return 1;
+ 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 void
-snat_add_static_mapping_when_resolved (snat_main_t *sm, ip4_address_t l_addr,
- u16 l_port, u32 sw_if_index, u16 e_port,
- u32 vrf_id, nat_protocol_t proto,
- int addr_only, u8 *tag, int twice_nat,
- int out2in_only, int identity_nat,
- ip4_address_t pool_addr, int exact)
-{
- snat_static_map_resolve_t *rp;
-
- vec_add2 (sm->to_resolve, rp, 1);
- rp->l_addr.as_u32 = l_addr.as_u32;
- rp->l_port = l_port;
- rp->sw_if_index = sw_if_index;
- rp->e_port = e_port;
- rp->vrf_id = vrf_id;
- rp->proto = proto;
- rp->addr_only = addr_only;
- rp->twice_nat = twice_nat;
- rp->out2in_only = out2in_only;
- rp->identity_nat = identity_nat;
- rp->tag = vec_dup (tag);
- rp->pool_addr = pool_addr;
- rp->exact = exact;
-}
-
u32
get_thread_idx_by_port (u16 e_port)
{
@@ -481,610 +453,814 @@ nat_ed_static_mapping_del_sessions (snat_main_t * sm,
}
int
-snat_add_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
- u16 l_port, u16 e_port, u32 vrf_id, int addr_only,
- u32 sw_if_index, nat_protocol_t proto, int is_add,
- twice_nat_type_t twice_nat, u8 out2in_only, u8 *tag,
- u8 identity_nat, ip4_address_t pool_addr, int exact)
+nat44_ed_reserve_port (ip4_address_t addr, u16 port, nat_protocol_t proto)
{
+ u32 ti = get_thread_idx_by_port (port);
snat_main_t *sm = &snat_main;
- snat_static_mapping_t *m;
- clib_bihash_kv_8_8_t kv, value;
snat_address_t *a = 0;
- u32 fib_index = ~0;
- snat_interface_t *interface;
- snat_main_per_thread_data_t *tsm;
- snat_static_map_resolve_t *rp, *rp_match = 0;
- nat44_lb_addr_port_t *local;
- u32 find = ~0;
int i;
- /* If the external address is a specific interface address */
- if (sw_if_index != ~0)
+ for (i = 0; i < vec_len (sm->addresses); i++)
{
- ip4_address_t *first_int_addr;
-
- for (i = 0; i < vec_len (sm->to_resolve); i++)
- {
- rp = sm->to_resolve + i;
- if (rp->sw_if_index != sw_if_index ||
- rp->l_addr.as_u32 != l_addr.as_u32 ||
- rp->vrf_id != vrf_id || rp->addr_only != addr_only)
- continue;
+ a = sm->addresses + i;
- if (!addr_only)
- {
- if ((rp->l_port != l_port && rp->e_port != e_port)
- || rp->proto != proto)
- continue;
- }
+ if (a->addr.as_u32 != addr.as_u32)
+ continue;
- rp_match = rp;
- break;
+ switch (proto)
+ {
+#define _(N, j, n, s) \
+ case NAT_PROTOCOL_##N: \
+ if (a->busy_##n##_port_refcounts[port]) \
+ goto done; \
+ ++a->busy_##n##_port_refcounts[port]; \
+ if (port > 1024) \
+ { \
+ a->busy_##n##_ports++; \
+ a->busy_##n##_ports_per_thread[ti]++; \
+ } \
+ break;
+ foreach_nat_protocol
+#undef _
+ default : nat_elog_info (sm, "unknown protocol");
+ goto done;
}
- /* Might be already set... */
- first_int_addr = ip4_interface_first_address
- (sm->ip4_main, sw_if_index, 0 /* just want the address */ );
+ return 0;
+ }
- if (is_add)
- {
- if (rp_match)
- return VNET_API_ERROR_VALUE_EXIST;
+done:
+ return 1;
+}
- snat_add_static_mapping_when_resolved (
- sm, l_addr, l_port, sw_if_index, e_port, vrf_id, proto, addr_only,
- tag, twice_nat, out2in_only, identity_nat, pool_addr, exact);
+int
+nat44_ed_free_port (ip4_address_t addr, u16 port, nat_protocol_t proto)
+{
+ u32 ti = get_thread_idx_by_port (port);
+ snat_main_t *sm = &snat_main;
+ snat_address_t *a = 0;
+ int i;
- /* DHCP resolution required? */
- if (first_int_addr == 0)
- {
- return 0;
- }
- else
- {
- e_addr.as_u32 = first_int_addr->as_u32;
- /* Identity mapping? */
- if (l_addr.as_u32 == 0)
- l_addr.as_u32 = e_addr.as_u32;
- }
- }
- else
- {
- if (!rp_match)
- return VNET_API_ERROR_NO_SUCH_ENTRY;
+ for (i = 0; i < vec_len (sm->addresses); i++)
+ {
+ a = sm->addresses + i;
- vec_del1 (sm->to_resolve, i);
+ if (a->addr.as_u32 != addr.as_u32)
+ continue;
- if (first_int_addr)
- {
- e_addr.as_u32 = first_int_addr->as_u32;
- /* Identity mapping? */
- if (l_addr.as_u32 == 0)
- l_addr.as_u32 = e_addr.as_u32;
- }
- else
- return 0;
+ switch (proto)
+ {
+#define _(N, j, n, s) \
+ case NAT_PROTOCOL_##N: \
+ --a->busy_##n##_port_refcounts[port]; \
+ if (port > 1024) \
+ { \
+ a->busy_##n##_ports--; \
+ a->busy_##n##_ports_per_thread[ti]--; \
+ } \
+ break;
+ foreach_nat_protocol
+#undef _
+ default : nat_elog_info (sm, "unknown protocol");
+ goto done;
}
+
+ return 0;
}
- init_nat_k (&kv, e_addr, addr_only ? 0 : e_port, 0, addr_only ? 0 : 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);
+done:
+ return 1;
+}
- if (is_add)
- {
- if (m)
- {
- if (is_identity_static_mapping (m))
- {
- pool_foreach (local, m->locals)
- {
- if (local->vrf_id == vrf_id)
- return VNET_API_ERROR_VALUE_EXIST;
- }
- pool_get (m->locals, local);
- local->vrf_id = vrf_id;
- local->fib_index =
- fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, vrf_id,
- sm->fib_src_low);
- init_nat_kv (&kv, m->local_addr, m->local_port, local->fib_index,
- m->proto, 0, m - sm->static_mappings);
- clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv, 1);
- return 0;
- }
- else
- return VNET_API_ERROR_VALUE_EXIST;
- }
+void
+nat44_ed_add_resolve_record (ip4_address_t l_addr, u16 l_port, u16 e_port,
+ nat_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;
- if (twice_nat && addr_only)
- return VNET_API_ERROR_UNSUPPORTED;
+ 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);
+}
- /* Convert VRF id to FIB index */
- if (vrf_id != ~0)
- fib_index =
- fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, vrf_id,
- sm->fib_src_low);
- /* If not specified use inside VRF id from SNAT plugin startup config */
- else
- {
- fib_index = sm->inside_fib_index;
- vrf_id = sm->inside_vrf_id;
- fib_table_lock (fib_index, FIB_PROTOCOL_IP4, sm->fib_src_low);
- }
+int
+nat44_ed_get_resolve_record (ip4_address_t l_addr, u16 l_port, u16 e_port,
+ nat_protocol_t proto, u32 vrf_id, u32 sw_if_index,
+ u32 flags, int *out)
+{
+ snat_static_map_resolve_t *rp;
+ snat_main_t *sm = &snat_main;
+ int i;
- if (!(out2in_only || identity_nat))
- {
- init_nat_k (&kv, l_addr, addr_only ? 0 : l_port, fib_index,
- addr_only ? 0 : proto);
- if (!clib_bihash_search_8_8
- (&sm->static_mapping_by_local, &kv, &value))
- return VNET_API_ERROR_VALUE_EXIST;
- }
+ for (i = 0; i < vec_len (sm->to_resolve); i++)
+ {
+ rp = sm->to_resolve + i;
- /* Find external address in allocated addresses and reserve port for
- address and port pair mapping when dynamic translations enabled */
- if (!(addr_only || sm->static_mapping_only || out2in_only))
+ if (rp->sw_if_index == sw_if_index && rp->vrf_id == vrf_id)
{
- for (i = 0; i < vec_len (sm->addresses); i++)
+ if (is_sm_identity_nat (rp->flags) && is_sm_identity_nat (flags))
{
- if (sm->addresses[i].addr.as_u32 == e_addr.as_u32)
+ if (!(is_sm_addr_only (rp->flags) && is_sm_addr_only (flags)))
{
- a = sm->addresses + i;
- /* External port must be unused */
- switch (proto)
+ if (rp->e_port != e_port || rp->proto != proto)
{
-#define _(N, j, n, s) \
- case NAT_PROTOCOL_##N: \
- if (a->busy_##n##_port_refcounts[e_port]) \
- return VNET_API_ERROR_INVALID_VALUE; \
- ++a->busy_##n##_port_refcounts[e_port]; \
- if (e_port > 1024) \
- { \
- a->busy_##n##_ports++; \
- a->busy_##n##_ports_per_thread[get_thread_idx_by_port(e_port)]++; \
- } \
- break;
- foreach_nat_protocol
-#undef _
- default : nat_elog_info (sm, "unknown protocol");
- return VNET_API_ERROR_INVALID_VALUE_2;
+ continue;
}
- break;
}
}
- /* External address must be allocated */
- if (!a && (l_addr.as_u32 != e_addr.as_u32))
+ else if (rp->l_addr.as_u32 == l_addr.as_u32)
{
- if (sw_if_index != ~0)
+ if (!(is_sm_addr_only (rp->flags) && is_sm_addr_only (flags)))
{
- for (i = 0; i < vec_len (sm->to_resolve); i++)
+ if (rp->l_port != l_port || rp->e_port != e_port ||
+ rp->proto != proto)
{
- rp = sm->to_resolve + i;
- if (rp->addr_only)
- continue;
- if (rp->sw_if_index != sw_if_index &&
- rp->l_addr.as_u32 != l_addr.as_u32 &&
- rp->vrf_id != vrf_id && rp->l_port != l_port &&
- rp->e_port != e_port && rp->proto != proto)
- continue;
-
- vec_del1 (sm->to_resolve, i);
- break;
+ continue;
}
}
- return VNET_API_ERROR_NO_SUCH_ENTRY;
}
+ else
+ {
+ continue;
+ }
+ if (out)
+ {
+ *out = i;
+ }
+ return 0;
+ }
+ }
+ return 1;
+}
+
+int
+nat44_ed_del_resolve_record (ip4_address_t l_addr, u16 l_port, u16 e_port,
+ nat_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))
+ {
+ vec_del1 (sm->to_resolve, i);
+ return 0;
+ }
+ return 1;
+}
+
+static_always_inline int
+nat44_ed_validate_sm_input (u32 flags)
+{
+ // identity nat can be initiated only from inside interface
+ if (is_sm_identity_nat (flags) && is_sm_out2in_only (flags))
+ {
+ return VNET_API_ERROR_UNSUPPORTED;
+ }
+
+ if (is_sm_twice_nat (flags) || is_sm_self_twice_nat (flags))
+ {
+ if (is_sm_addr_only (flags) || is_sm_identity_nat (flags))
+ {
+ return VNET_API_ERROR_UNSUPPORTED;
}
+ }
+ return 0;
+}
+
+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,
+ ip4_address_t pool_addr, u8 *tag)
+{
+ snat_main_t *sm = &snat_main;
+ clib_bihash_kv_8_8_t kv, value;
+ snat_interface_t *interface;
+ nat44_lb_addr_port_t *local;
+ snat_static_mapping_t *m;
+ u32 fib_index = ~0;
+ int rv;
+
+ rv = nat44_ed_validate_sm_input (flags);
+ if (rv != 0)
+ {
+ return rv;
+ }
- pool_get (sm->static_mappings, m);
- clib_memset (m, 0, sizeof (*m));
- m->tag = vec_dup (tag);
- m->local_addr = l_addr;
- m->external_addr = e_addr;
- m->twice_nat = twice_nat;
+ if (is_sm_addr_only (flags))
+ {
+ e_port = l_port = proto = 0;
+ }
+
+ if (is_sm_switch_address (flags))
+ {
+ // this mapping is interface bound
+ ip4_address_t *first_int_addr;
- if (twice_nat == TWICE_NAT && exact)
+ // check if this record isn't registered for resolve
+ if (!nat44_ed_get_resolve_record (l_addr, l_port, e_port, proto, vrf_id,
+ sw_if_index, flags, 0))
{
- m->flags |= NAT_STATIC_MAPPING_FLAG_EXACT_ADDRESS;
- m->pool_addr = pool_addr;
+ return VNET_API_ERROR_VALUE_EXIST;
}
+ // register record for resolve
+ nat44_ed_add_resolve_record (l_addr, l_port, e_port, proto, vrf_id,
+ sw_if_index, flags, pool_addr, tag);
- if (out2in_only)
- m->flags |= NAT_STATIC_MAPPING_FLAG_OUT2IN_ONLY;
- if (addr_only)
- m->flags |= NAT_STATIC_MAPPING_FLAG_ADDR_ONLY;
- if (identity_nat)
+ first_int_addr =
+ ip4_interface_first_address (sm->ip4_main, sw_if_index, 0);
+ if (!first_int_addr)
{
- m->flags |= NAT_STATIC_MAPPING_FLAG_IDENTITY_NAT;
- pool_get (m->locals, local);
- local->vrf_id = vrf_id;
- local->fib_index = fib_index;
+ // dhcp resolution required
+ return 0;
}
- else
+
+ e_addr.as_u32 = first_int_addr->as_u32;
+ }
+
+ if (is_sm_identity_nat (flags))
+ {
+ l_port = e_port;
+ l_addr.as_u32 = e_addr.as_u32;
+ }
+
+ // fib index 0
+ init_nat_k (&kv, e_addr, e_port, 0, proto);
+
+ if (!clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value))
+ {
+ m = pool_elt_at_index (sm->static_mappings, value.value);
+ if (!is_sm_identity_nat (m->flags))
{
- m->vrf_id = vrf_id;
- m->fib_index = fib_index;
+ return VNET_API_ERROR_VALUE_EXIST;
}
- if (!addr_only)
+
+ // case:
+ // adding local identity nat record for different vrf table
+ pool_foreach (local, m->locals)
{
- m->local_port = l_port;
- m->external_port = e_port;
- m->proto = proto;
+ if (local->vrf_id == vrf_id)
+ {
+ return VNET_API_ERROR_VALUE_EXIST;
+ }
}
- if (sm->num_workers > 1)
+ pool_get (m->locals, local);
+
+ local->vrf_id = vrf_id;
+ local->fib_index = fib_table_find_or_create_and_lock (
+ FIB_PROTOCOL_IP4, vrf_id, sm->fib_src_low);
+
+ init_nat_kv (&kv, m->local_addr, m->local_port, local->fib_index,
+ m->proto, 0, m - sm->static_mappings);
+ clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv, 1);
+
+ return 0;
+ }
+
+ if (vrf_id != ~0)
+ {
+ fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, vrf_id,
+ sm->fib_src_low);
+ }
+ else
+ {
+ // fallback to default vrf
+ vrf_id = sm->inside_vrf_id;
+ fib_index = sm->inside_fib_index;
+ fib_table_lock (fib_index, FIB_PROTOCOL_IP4, sm->fib_src_low);
+ }
+
+ // test if local mapping record doesn't exist
+ // identity nat supports multiple records in local mapping
+ if (!(is_sm_out2in_only (flags) || is_sm_identity_nat (flags)))
+ {
+ init_nat_k (&kv, l_addr, l_port, fib_index, proto);
+ if (!clib_bihash_search_8_8 (&sm->static_mapping_by_local, &kv, &value))
{
- ip4_header_t ip = {
- .src_address = m->local_addr,
- };
- vec_add1 (m->workers, nat44_ed_get_in2out_worker_index (
- 0, &ip, m->fib_index, 0));
- tsm = vec_elt_at_index (sm->per_thread_data, m->workers[0]);
+ return VNET_API_ERROR_VALUE_EXIST;
}
- else
- tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
+ }
- if (!out2in_only)
+ if (!(is_sm_out2in_only (flags) || is_sm_addr_only (flags) ||
+ sm->static_mapping_only))
+ {
+ if (nat44_ed_reserve_port (e_addr, e_port, proto))
{
- init_nat_kv (&kv, m->local_addr, m->local_port, fib_index, m->proto,
- 0, m - sm->static_mappings);
- clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv, 1);
+ // 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;
}
+ }
- init_nat_kv (&kv, m->external_addr, m->external_port, 0, m->proto, 0,
- m - sm->static_mappings);
- clib_bihash_add_del_8_8 (&sm->static_mapping_by_external, &kv, 1);
+ pool_get (sm->static_mappings, m);
+ clib_memset (m, 0, sizeof (*m));
+
+ m->flags = flags;
+ m->local_addr = l_addr;
+ m->external_addr = e_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;
+ m->external_port = e_port;
+ m->proto = proto;
+ }
+
+ if (is_sm_identity_nat (flags))
+ {
+ pool_get (m->locals, local);
+
+ local->vrf_id = vrf_id;
+ local->fib_index = fib_index;
}
else
{
- if (!m)
+ m->vrf_id = vrf_id;
+ m->fib_index = fib_index;
+ }
+
+ if (!is_sm_out2in_only (flags))
+ {
+ init_nat_kv (&kv, m->local_addr, m->local_port, fib_index, m->proto, 0,
+ m - sm->static_mappings);
+ clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv, 1);
+ }
+
+ init_nat_kv (&kv, m->external_addr, m->external_port, 0, m->proto, 0,
+ m - sm->static_mappings);
+ clib_bihash_add_del_8_8 (&sm->static_mapping_by_external, &kv, 1);
+
+ if (sm->num_workers > 1)
+ {
+ // store worker index for this record
+ ip4_header_t ip = {
+ .src_address = m->local_addr,
+ };
+ u32 worker_index;
+ worker_index =
+ nat44_ed_get_in2out_worker_index (0, &ip, m->fib_index, 0);
+ vec_add1 (m->workers, worker_index);
+ }
+
+ if (is_sm_identity_nat (flags) || !is_sm_addr_only (flags))
+ return 0;
+
+ pool_foreach (interface, sm->interfaces)
+ {
+ if (nat_interface_is_inside (interface))
+ continue;
+
+ snat_add_del_addr_to_fib (&e_addr, 32, interface->sw_if_index, 1);
+ break;
+ }
+
+ pool_foreach (interface, sm->output_feature_interfaces)
+ {
+ if (nat_interface_is_inside (interface))
+ continue;
+
+ snat_add_del_addr_to_fib (&e_addr, 32, interface->sw_if_index, 1);
+ break;
+ }
+
+ return 0;
+}
+
+int
+nat44_ed_del_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)
+{
+ snat_main_per_thread_data_t *tsm;
+ snat_main_t *sm = &snat_main;
+
+ clib_bihash_kv_8_8_t kv, value;
+ snat_interface_t *interface;
+ nat44_lb_addr_port_t *local;
+ snat_static_mapping_t *m;
+ u32 fib_index = ~0;
+ int rv;
+
+ rv = nat44_ed_validate_sm_input (flags);
+ if (rv != 0)
+ {
+ return rv;
+ }
+
+ if (is_sm_addr_only (flags))
+ {
+ e_port = l_port = proto = 0;
+ }
+
+ if (is_sm_switch_address (flags))
+ {
+ // this mapping is interface bound
+ ip4_address_t *first_int_addr;
+
+ // delete record registered for resolve
+ if (nat44_ed_del_resolve_record (l_addr, l_port, e_port, proto, vrf_id,
+ sw_if_index, flags))
{
- if (sw_if_index != ~0)
- return 0;
- else
- return VNET_API_ERROR_NO_SUCH_ENTRY;
+ return VNET_API_ERROR_NO_SUCH_ENTRY;
}
- if (identity_nat)
+ first_int_addr =
+ ip4_interface_first_address (sm->ip4_main, sw_if_index, 0);
+ if (!first_int_addr)
{
- if (vrf_id == ~0)
- vrf_id = sm->inside_vrf_id;
+ // dhcp resolution required
+ return 0;
+ }
- pool_foreach (local, m->locals)
- {
- if (local->vrf_id == vrf_id)
- find = local - m->locals;
- }
- if (find == ~0)
- return VNET_API_ERROR_NO_SUCH_ENTRY;
+ e_addr.as_u32 = first_int_addr->as_u32;
+ }
+
+ if (is_sm_identity_nat (flags))
+ {
+ l_port = e_port;
+ l_addr.as_u32 = e_addr.as_u32;
+ }
+
+ // fib index 0
+ init_nat_k (&kv, e_addr, e_port, 0, proto);
- local = pool_elt_at_index (m->locals, find);
- fib_index = local->fib_index;
- pool_put (m->locals, local);
+ if (clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value))
+ {
+ if (is_sm_switch_address (flags))
+ {
+ return 0;
}
- else
- fib_index = m->fib_index;
+ return VNET_API_ERROR_NO_SUCH_ENTRY;
+ }
+
+ m = pool_elt_at_index (sm->static_mappings, value.value);
- /* Free external address port */
- if (!(addr_only || sm->static_mapping_only || out2in_only))
+ if (is_sm_identity_nat (flags))
+ {
+ u8 failure = 1;
+
+ if (!is_sm_switch_address (flags))
{
- for (i = 0; i < vec_len (sm->addresses); i++)
+ vrf_id = sm->inside_vrf_id;
+ }
+
+ pool_foreach (local, m->locals)
+ {
+ if (local->vrf_id == vrf_id)
{
- if (sm->addresses[i].addr.as_u32 == e_addr.as_u32)
- {
- a = sm->addresses + i;
- switch (proto)
- {
-#define _(N, j, n, s) \
- case NAT_PROTOCOL_##N: \
- --a->busy_##n##_port_refcounts[e_port]; \
- if (e_port > 1024) \
- { \
- a->busy_##n##_ports--; \
- a->busy_##n##_ports_per_thread[get_thread_idx_by_port(e_port)]--; \
- } \
- break;
- foreach_nat_protocol
-#undef _
- default : nat_elog_info (sm, "unknown protocol");
- return VNET_API_ERROR_INVALID_VALUE_2;
- }
- break;
- }
+ local = pool_elt_at_index (m->locals, local - m->locals);
+ fib_index = local->fib_index;
+ pool_put (m->locals, local);
+ failure = 0;
}
}
+ if (failure)
+ {
+ return VNET_API_ERROR_NO_SUCH_ENTRY;
+ }
+ }
+ else
+ {
+ fib_index = m->fib_index;
+ }
+
+ if (!(is_sm_out2in_only (flags) || is_sm_addr_only (flags) ||
+ sm->static_mapping_only))
+ {
+ if (nat44_ed_free_port (e_addr, e_port, proto))
+ {
+ return VNET_API_ERROR_INVALID_VALUE;
+ }
+ }
+
+ if (!is_sm_out2in_only (flags))
+ {
+ init_nat_k (&kv, l_addr, l_port, fib_index, proto);
+ clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv, 0);
+ }
+
+ if (!sm->static_mapping_only || sm->static_mapping_connection_tracking)
+ {
+ // 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);
- init_nat_k (&kv, m->local_addr, m->local_port, fib_index, m->proto);
- if (!out2in_only)
- clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv, 0);
+ 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);
+ }
- /* Delete session(s) for static mapping if exist */
- if (!(sm->static_mapping_only) ||
- (sm->static_mapping_only && sm->static_mapping_connection_tracking))
- {
- nat_ed_static_mapping_del_sessions (
- sm, tsm, m->local_addr, m->local_port, m->proto, fib_index,
- addr_only, e_addr, e_port);
- }
+ fib_table_unlock (fib_index, FIB_PROTOCOL_IP4, sm->fib_src_low);
- fib_table_unlock (fib_index, FIB_PROTOCOL_IP4, sm->fib_src_low);
- if (pool_elts (m->locals))
- return 0;
+ if (pool_elts (m->locals))
+ return 0;
- init_nat_k (&kv, m->external_addr, m->external_port, 0, m->proto);
- clib_bihash_add_del_8_8 (&sm->static_mapping_by_external, &kv, 0);
+ // fib_index 0
+ init_nat_k (&kv, e_addr, e_port, 0, proto);
+ clib_bihash_add_del_8_8 (&sm->static_mapping_by_external, &kv, 0);
- vec_free (m->tag);
- vec_free (m->workers);
- /* Delete static mapping from pool */
- pool_put (sm->static_mappings, m);
- }
+ vec_free (m->tag);
+ vec_free (m->workers);
+ pool_put (sm->static_mappings, m);
- if (!addr_only || (l_addr.as_u32 == e_addr.as_u32))
+ if (is_sm_identity_nat (flags) || !is_sm_addr_only (flags))
return 0;
- /* Add/delete external address to FIB */
pool_foreach (interface, sm->interfaces)
- {
- if (nat_interface_is_inside (interface))
- continue;
+ {
+ if (nat_interface_is_inside (interface))
+ continue;
+
+ snat_add_del_addr_to_fib (&e_addr, 32, interface->sw_if_index, 0);
+ break;
+ }
- snat_add_del_addr_to_fib (&e_addr, 32, interface->sw_if_index, is_add);
- break;
- }
pool_foreach (interface, sm->output_feature_interfaces)
- {
- if (nat_interface_is_inside (interface))
- continue;
+ {
+ if (nat_interface_is_inside (interface))
+ continue;
- snat_add_del_addr_to_fib (&e_addr, 32, interface->sw_if_index, is_add);
- break;
- }
+ snat_add_del_addr_to_fib (&e_addr, 32, interface->sw_if_index, 0);
+ break;
+ }
return 0;
}
int
-nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port,
- nat_protocol_t proto,
- nat44_lb_addr_port_t * locals, u8 is_add,
- twice_nat_type_t twice_nat, u8 out2in_only,
- u8 * tag, u32 affinity)
+nat44_ed_add_lb_static_mapping (ip4_address_t e_addr, u16 e_port,
+ nat_protocol_t proto,
+ nat44_lb_addr_port_t *locals, u32 flags,
+ u8 *tag, u32 affinity)
{
snat_main_t *sm = &snat_main;
snat_static_mapping_t *m;
clib_bihash_kv_8_8_t kv, value;
snat_address_t *a = 0;
- int i;
+
nat44_lb_addr_port_t *local;
- snat_main_per_thread_data_t *tsm;
- snat_session_t *s;
uword *bitmap = 0;
+ int i;
+
init_nat_k (&kv, e_addr, e_port, 0, 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_add)
- {
- if (m)
- return VNET_API_ERROR_VALUE_EXIST;
+ if (m)
+ return VNET_API_ERROR_VALUE_EXIST;
- if (vec_len (locals) < 2)
- return VNET_API_ERROR_INVALID_VALUE;
+ if (vec_len (locals) < 2)
+ return VNET_API_ERROR_INVALID_VALUE;
- /* Find external address in allocated addresses and reserve port for
- address and port pair mapping when dynamic translations enabled */
- if (!(sm->static_mapping_only || out2in_only))
+ /* Find external address in allocated addresses and reserve port for
+ address and port pair mapping when dynamic translations enabled */
+ if (!(sm->static_mapping_only || is_sm_out2in_only (flags)))
+ {
+ for (i = 0; i < vec_len (sm->addresses); i++)
{
- for (i = 0; i < vec_len (sm->addresses); i++)
+ if (sm->addresses[i].addr.as_u32 == e_addr.as_u32)
{
- if (sm->addresses[i].addr.as_u32 == e_addr.as_u32)
+ a = sm->addresses + i;
+ /* External port must be unused */
+ switch (proto)
{
- a = sm->addresses + i;
- /* External port must be unused */
- switch (proto)
- {
-#define _(N, j, n, s) \
- case NAT_PROTOCOL_##N: \
- if (a->busy_##n##_port_refcounts[e_port]) \
- return VNET_API_ERROR_INVALID_VALUE; \
- ++a->busy_##n##_port_refcounts[e_port]; \
- if (e_port > 1024) \
- { \
- a->busy_##n##_ports++; \
- a->busy_##n##_ports_per_thread[get_thread_idx_by_port(e_port)]++; \
- } \
- break;
- foreach_nat_protocol
+#define _(N, j, n, s) \
+ case NAT_PROTOCOL_##N: \
+ if (a->busy_##n##_port_refcounts[e_port]) \
+ return VNET_API_ERROR_INVALID_VALUE; \
+ ++a->busy_##n##_port_refcounts[e_port]; \
+ if (e_port > 1024) \
+ { \
+ a->busy_##n##_ports++; \
+ a->busy_##n##_ports_per_thread[get_thread_idx_by_port (e_port)]++; \
+ } \
+ break;
+ foreach_nat_protocol
#undef _
- default : nat_elog_info (sm, "unknown protocol");
- return VNET_API_ERROR_INVALID_VALUE_2;
- }
- break;
+ default : nat_elog_info (sm, "unknown protocol");
+ return VNET_API_ERROR_INVALID_VALUE_2;
}
+ break;
}
- /* External address must be allocated */
- if (!a)
- return VNET_API_ERROR_NO_SUCH_ENTRY;
}
+ /* External address must be allocated */
+ if (!a)
+ return VNET_API_ERROR_NO_SUCH_ENTRY;
+ }
- pool_get (sm->static_mappings, m);
- clib_memset (m, 0, sizeof (*m));
- m->tag = vec_dup (tag);
- m->external_addr = e_addr;
- m->external_port = e_port;
- m->proto = proto;
- m->twice_nat = twice_nat;
- m->flags |= NAT_STATIC_MAPPING_FLAG_LB;
- if (out2in_only)
- m->flags |= NAT_STATIC_MAPPING_FLAG_OUT2IN_ONLY;
- m->affinity = affinity;
-
- if (affinity)
- m->affinity_per_service_list_head_index =
- nat_affinity_get_per_service_list_head_index ();
- else
- m->affinity_per_service_list_head_index = ~0;
+ pool_get (sm->static_mappings, m);
+ clib_memset (m, 0, sizeof (*m));
+ m->tag = vec_dup (tag);
+ m->external_addr = e_addr;
+ m->external_port = e_port;
+ m->affinity = affinity;
+ m->proto = proto;
- init_nat_kv (&kv, m->external_addr, m->external_port, 0, m->proto, 0,
- m - sm->static_mappings);
- if (clib_bihash_add_del_8_8 (&sm->static_mapping_by_external, &kv, 1))
+ m->flags = flags;
+ m->flags |= NAT_SM_FLAG_LB;
+
+ if (affinity)
+ m->affinity_per_service_list_head_index =
+ nat_affinity_get_per_service_list_head_index ();
+ else
+ m->affinity_per_service_list_head_index = ~0;
+
+ init_nat_kv (&kv, m->external_addr, m->external_port, 0, m->proto, 0,
+ m - sm->static_mappings);
+ if (clib_bihash_add_del_8_8 (&sm->static_mapping_by_external, &kv, 1))
+ {
+ nat_elog_err (sm, "static_mapping_by_external key add failed");
+ return VNET_API_ERROR_UNSPECIFIED;
+ }
+
+ for (i = 0; i < vec_len (locals); i++)
+ {
+ locals[i].fib_index = fib_table_find_or_create_and_lock (
+ FIB_PROTOCOL_IP4, locals[i].vrf_id, sm->fib_src_low);
+ if (!is_sm_out2in_only (flags))
{
- nat_elog_err (sm, "static_mapping_by_external key add failed");
- return VNET_API_ERROR_UNSPECIFIED;
+ init_nat_kv (&kv, locals[i].addr, locals[i].port,
+ locals[i].fib_index, m->proto, 0,
+ m - sm->static_mappings);
+ clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv, 1);
}
-
- for (i = 0; i < vec_len (locals); i++)
+ locals[i].prefix = (i == 0) ?
+ locals[i].probability :
+ (locals[i - 1].prefix + locals[i].probability);
+ pool_get (m->locals, local);
+ *local = locals[i];
+ if (sm->num_workers > 1)
{
- locals[i].fib_index =
- fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4,
- locals[i].vrf_id,
- sm->fib_src_low);
- if (!out2in_only)
- {
- init_nat_kv (&kv, locals[i].addr, locals[i].port,
- locals[i].fib_index, m->proto, 0,
- m - sm->static_mappings);
- clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv, 1);
- }
- locals[i].prefix = (i == 0) ? locals[i].probability :
- (locals[i - 1].prefix + locals[i].probability);
- pool_get (m->locals, local);
- *local = locals[i];
- if (sm->num_workers > 1)
- {
- ip4_header_t ip = {
- .src_address = locals[i].addr,
- };
- bitmap = clib_bitmap_set (
- bitmap,
- nat44_ed_get_in2out_worker_index (0, &ip, m->fib_index, 0), 1);
- }
+ ip4_header_t ip = {
+ .src_address = locals[i].addr,
+ };
+ bitmap = clib_bitmap_set (
+ bitmap, nat44_ed_get_in2out_worker_index (0, &ip, m->fib_index, 0),
+ 1);
}
+ }
- /* Assign workers */
- if (sm->num_workers > 1)
+ /* Assign workers */
+ if (sm->num_workers > 1)
+ {
+ clib_bitmap_foreach (i, bitmap)
{
- clib_bitmap_foreach (i, bitmap)
- {
- vec_add1(m->workers, i);
- }
+ vec_add1 (m->workers, i);
}
}
+
+ return 0;
+}
+
+int
+nat44_ed_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port,
+ nat_protocol_t proto, u32 flags)
+{
+ snat_main_t *sm = &snat_main;
+ snat_static_mapping_t *m;
+ clib_bihash_kv_8_8_t kv, value;
+ snat_address_t *a = 0;
+
+ nat44_lb_addr_port_t *local;
+ snat_main_per_thread_data_t *tsm;
+ snat_session_t *s;
+ int i;
+
+ init_nat_k (&kv, e_addr, e_port, 0, proto);
+ if (clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value))
+ m = 0;
else
- {
- if (!m)
- return VNET_API_ERROR_NO_SUCH_ENTRY;
+ m = pool_elt_at_index (sm->static_mappings, value.value);
- if (!is_lb_static_mapping (m))
- return VNET_API_ERROR_INVALID_VALUE;
+ if (!m)
+ return VNET_API_ERROR_NO_SUCH_ENTRY;
+
+ if (!is_sm_lb (m->flags))
+ return VNET_API_ERROR_INVALID_VALUE;
- /* Free external address port */
- if (!(sm->static_mapping_only || out2in_only))
+ /* Free external address port */
+ if (!(sm->static_mapping_only || is_sm_out2in_only (flags)))
+ {
+ for (i = 0; i < vec_len (sm->addresses); i++)
{
- for (i = 0; i < vec_len (sm->addresses); i++)
+ if (sm->addresses[i].addr.as_u32 == e_addr.as_u32)
{
- if (sm->addresses[i].addr.as_u32 == e_addr.as_u32)
+ a = sm->addresses + i;
+ switch (proto)
{
- a = sm->addresses + i;
- switch (proto)
- {
-#define _(N, j, n, s) \
- case NAT_PROTOCOL_##N: \
- --a->busy_##n##_port_refcounts[e_port]; \
- if (e_port > 1024) \
- { \
- a->busy_##n##_ports--; \
- a->busy_##n##_ports_per_thread[get_thread_idx_by_port(e_port)]--; \
- } \
- break;
- foreach_nat_protocol
+#define _(N, j, n, s) \
+ case NAT_PROTOCOL_##N: \
+ --a->busy_##n##_port_refcounts[e_port]; \
+ if (e_port > 1024) \
+ { \
+ a->busy_##n##_ports--; \
+ a->busy_##n##_ports_per_thread[get_thread_idx_by_port (e_port)]--; \
+ } \
+ break;
+ foreach_nat_protocol
#undef _
- default : nat_elog_info (sm, "unknown protocol");
- return VNET_API_ERROR_INVALID_VALUE_2;
- }
- break;
+ default : nat_elog_info (sm, "unknown protocol");
+ return VNET_API_ERROR_INVALID_VALUE_2;
}
+ break;
}
}
+ }
- init_nat_k (&kv, m->external_addr, m->external_port, 0, m->proto);
- if (clib_bihash_add_del_8_8 (&sm->static_mapping_by_external, &kv, 0))
- {
- nat_elog_err (sm, "static_mapping_by_external key del failed");
- return VNET_API_ERROR_UNSPECIFIED;
- }
-
- pool_foreach (local, m->locals)
- {
- fib_table_unlock (local->fib_index, FIB_PROTOCOL_IP4,
- sm->fib_src_low);
- if (!out2in_only)
- {
- init_nat_k (&kv, local->addr, local->port, local->fib_index,
- m->proto);
- if (clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv,
- 0))
- {
- nat_elog_err (sm, "static_mapping_by_local key del failed");
- return VNET_API_ERROR_UNSPECIFIED;
- }
- }
+ init_nat_k (&kv, m->external_addr, m->external_port, 0, m->proto);
+ if (clib_bihash_add_del_8_8 (&sm->static_mapping_by_external, &kv, 0))
+ {
+ nat_elog_err (sm, "static_mapping_by_external key del failed");
+ return VNET_API_ERROR_UNSPECIFIED;
+ }
- if (sm->num_workers > 1)
+ pool_foreach (local, m->locals)
+ {
+ fib_table_unlock (local->fib_index, FIB_PROTOCOL_IP4, sm->fib_src_low);
+ if (!is_sm_out2in_only (flags))
+ {
+ init_nat_k (&kv, local->addr, local->port, local->fib_index,
+ m->proto);
+ if (clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv, 0))
{
- ip4_header_t ip = {
- .src_address = local->addr,
- };
- tsm = vec_elt_at_index (
- sm->per_thread_data,
- nat44_ed_get_in2out_worker_index (0, &ip, m->fib_index, 0));
+ nat_elog_err (sm, "static_mapping_by_local key del failed");
+ return VNET_API_ERROR_UNSPECIFIED;
}
- else
- tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
+ }
- /* Delete sessions */
- pool_foreach (s, tsm->sessions)
- {
- if (!(is_lb_session (s)))
- continue;
+ if (sm->num_workers > 1)
+ {
+ ip4_header_t ip = {
+ .src_address = local->addr,
+ };
+ tsm = vec_elt_at_index (
+ sm->per_thread_data,
+ nat44_ed_get_in2out_worker_index (0, &ip, m->fib_index, 0));
+ }
+ else
+ tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
- if ((s->in2out.addr.as_u32 != local->addr.as_u32) ||
- s->in2out.port != local->port)
- continue;
+ /* Delete sessions */
+ pool_foreach (s, tsm->sessions)
+ {
+ if (!(is_lb_session (s)))
+ continue;
- nat_free_session_data (sm, s, tsm - sm->per_thread_data, 0);
- nat_ed_session_delete (sm, s, tsm - sm->per_thread_data, 1);
- }
- }
- if (m->affinity)
- nat_affinity_flush_service (m->affinity_per_service_list_head_index);
- pool_free (m->locals);
- vec_free (m->tag);
- vec_free (m->workers);
+ if ((s->in2out.addr.as_u32 != local->addr.as_u32) ||
+ s->in2out.port != local->port)
+ continue;
- pool_put (sm->static_mappings, m);
+ nat_free_session_data (sm, s, tsm - sm->per_thread_data, 0);
+ nat_ed_session_delete (sm, s, tsm - sm->per_thread_data, 1);
+ }
+ }
+
+ if (m->affinity)
+ {
+ nat_affinity_flush_service (m->affinity_per_service_list_head_index);
}
+ pool_free (m->locals);
+ vec_free (m->tag);
+ vec_free (m->workers);
+ pool_put (sm->static_mappings, m);
+
return 0;
}
int
-nat44_lb_static_mapping_add_del_local (ip4_address_t e_addr, u16 e_port,
- ip4_address_t l_addr, u16 l_port,
- nat_protocol_t proto, u32 vrf_id,
- u8 probability, u8 is_add)
+nat44_ed_add_del_lb_static_mapping_local (ip4_address_t e_addr, u16 e_port,
+ ip4_address_t l_addr, u16 l_port,
+ nat_protocol_t proto, u32 vrf_id,
+ u8 probability, u8 is_add)
{
snat_main_t *sm = &snat_main;
snat_static_mapping_t *m = 0;
@@ -1103,7 +1279,7 @@ nat44_lb_static_mapping_add_del_local (ip4_address_t e_addr, u16 e_port,
if (!m)
return VNET_API_ERROR_NO_SUCH_ENTRY;
- if (!is_lb_static_mapping (m))
+ if (!is_sm_lb (m->flags))
return VNET_API_ERROR_INVALID_VALUE;
pool_foreach (local, m->locals)
@@ -1131,7 +1307,7 @@ nat44_lb_static_mapping_add_del_local (ip4_address_t e_addr, u16 e_port,
fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, vrf_id,
sm->fib_src_low);
- if (!is_out2in_only_static_mapping (m))
+ if (!is_sm_out2in_only (m->flags))
{
init_nat_kv (&kv, l_addr, l_port, local->fib_index, proto, 0,
m - sm->static_mappings);
@@ -1150,7 +1326,7 @@ nat44_lb_static_mapping_add_del_local (ip4_address_t e_addr, u16 e_port,
fib_table_unlock (match_local->fib_index, FIB_PROTOCOL_IP4,
sm->fib_src_low);
- if (!is_out2in_only_static_mapping (m))
+ if (!is_sm_out2in_only (m->flags))
{
init_nat_k (&kv, l_addr, l_port, match_local->fib_index, proto);
if (clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv, 0))
@@ -1251,20 +1427,14 @@ snat_del_address (snat_main_t * sm, ip4_address_t addr, u8 delete_sm,
if (delete_sm)
{
- ip4_address_t pool_addr = { 0 };
pool_foreach (m, sm->static_mappings)
{
if (m->external_addr.as_u32 == addr.as_u32)
- (void) snat_add_static_mapping (m->local_addr, m->external_addr,
- m->local_port, m->external_port,
- m->vrf_id,
- is_addr_only_static_mapping(m), ~0,
- m->proto, 0 /* is_add */,
- m->twice_nat,
- is_out2in_only_static_mapping(m),
- m->tag,
- is_identity_static_mapping(m),
- pool_addr, 0);
+ {
+ 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
@@ -1526,7 +1696,7 @@ nat44_ed_add_interface (u32 sw_if_index, u8 is_inside)
}
pool_foreach (m, sm->static_mappings)
{
- if (!(is_addr_only_static_mapping (m)) ||
+ if (!(is_sm_addr_only (m->flags)) ||
(m->local_addr.as_u32 == m->external_addr.as_u32))
{
continue;
@@ -1649,7 +1819,7 @@ nat44_ed_del_interface (u32 sw_if_index, u8 is_inside)
pool_foreach (m, sm->static_mappings)
{
- if (!(is_addr_only_static_mapping (m)) ||
+ if (!(is_sm_addr_only (m->flags)) ||
(m->local_addr.as_u32 == m->external_addr.as_u32))
{
continue;
@@ -1762,7 +1932,7 @@ nat44_ed_add_output_interface (u32 sw_if_index)
pool_foreach (m, sm->static_mappings)
{
- if (!((is_addr_only_static_mapping (m))) ||
+ if (!((is_sm_addr_only (m->flags))) ||
(m->local_addr.as_u32 == m->external_addr.as_u32))
{
continue;
@@ -1862,7 +2032,7 @@ nat44_ed_del_output_interface (u32 sw_if_index)
pool_foreach (m, sm->static_mappings)
{
- if (!((is_addr_only_static_mapping (m))) ||
+ if (!((is_sm_addr_only (m->flags))) ||
(m->local_addr.as_u32 == m->external_addr.as_u32))
{
continue;
@@ -2530,7 +2700,7 @@ snat_static_mapping_match (vlib_main_t *vm, snat_main_t *sm,
if (by_external)
{
- if (is_lb_static_mapping (m))
+ if (is_sm_lb (m->flags))
{
if (PREDICT_FALSE (lb != 0))
*lb = m->affinity ? AFFINITY_LB_NAT : LB_NAT;
@@ -2603,28 +2773,39 @@ snat_static_mapping_match (vlib_main_t *vm, snat_main_t *sm,
*mapping_fib_index = m->fib_index;
*mapping_addr = m->local_addr;
/* Address only mapping doesn't change port */
- *mapping_port = is_addr_only_static_mapping (m) ? match_port
- : m->local_port;
+ *mapping_port =
+ is_sm_addr_only (m->flags) ? match_port : m->local_port;
}
}
else
{
*mapping_addr = m->external_addr;
/* Address only mapping doesn't change port */
- *mapping_port = is_addr_only_static_mapping (m) ? match_port
- : m->external_port;
+ *mapping_port =
+ is_sm_addr_only (m->flags) ? match_port : m->external_port;
*mapping_fib_index = sm->outside_fib_index;
}
end:
if (PREDICT_FALSE (is_addr_only != 0))
- *is_addr_only = is_addr_only_static_mapping (m);
+ *is_addr_only = is_sm_addr_only (m->flags);
if (PREDICT_FALSE (twice_nat != 0))
- *twice_nat = m->twice_nat;
+ {
+ *twice_nat = TWICE_NAT_DISABLED;
+
+ if (is_sm_twice_nat (m->flags))
+ {
+ *twice_nat = TWICE_NAT;
+ }
+ else if (is_sm_self_twice_nat (m->flags))
+ {
+ *twice_nat = TWICE_NAT_SELF;
+ }
+ }
if (PREDICT_FALSE (is_identity_nat != 0))
- *is_identity_nat = is_identity_static_mapping (m);
+ *is_identity_nat = is_sm_identity_nat (m->flags);
if (out != 0)
*out = m;
@@ -2854,7 +3035,7 @@ nat44_ed_get_out2in_worker_index (vlib_buffer_t *b, ip4_header_t *ip,
(&sm->static_mapping_by_external, &kv, &value))
{
m = pool_elt_at_index (sm->static_mappings, value.value);
- if (!is_lb_static_mapping (m))
+ if (!is_sm_lb (m->flags))
{
next_worker_index = m->workers[0];
goto done;
@@ -3071,8 +3252,8 @@ nat_ip4_add_del_addr_only_sm_cb (ip4_main_t * im,
snat_static_map_resolve_t *rp;
snat_static_mapping_t *m;
clib_bihash_kv_8_8_t kv, value;
- int i, rv;
ip4_address_t l_addr;
+ int i, rv;
if (!sm->enabled)
return;
@@ -3113,18 +3294,23 @@ match:
l_addr.as_u32 = address[0].as_u32;
else
l_addr.as_u32 = rp->l_addr.as_u32;
- /* Add the static mapping */
- rv = snat_add_static_mapping (l_addr,
- address[0],
- rp->l_port,
- rp->e_port,
- rp->vrf_id,
- rp->addr_only, ~0 /* sw_if_index */ ,
- rp->proto, !is_delete, rp->twice_nat,
- rp->out2in_only, rp->tag, rp->identity_nat,
- rp->pool_addr, rp->exact);
+
+ 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);
+ }
+ 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 (rv)
- nat_elog_notice_X1 (sm, "snat_add_static_mapping returned %d", "i4", rv);
+ {
+ nat_elog_notice_X1 (sm, "add_static_mapping returned %d", "i4", rv);
+ }
}
static void
@@ -3180,20 +3366,23 @@ 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)
l_addr.as_u32 = address[0].as_u32;
else
l_addr.as_u32 = rp->l_addr.as_u32;
+
/* Add the static mapping */
- rv = snat_add_static_mapping (
- l_addr, address[0], rp->l_port, rp->e_port, rp->vrf_id,
- rp->addr_only, ~0 /* sw_if_index */, rp->proto, 1,
- rp->twice_nat, rp->out2in_only, rp->tag, rp->identity_nat,
- rp->pool_addr, rp->exact);
+ 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 (rv)
- nat_elog_notice_X1 (sm, "snat_add_static_mapping returned %d",
- "i4", rv);
+ {
+ nat_elog_notice_X1 (sm, "add_static_mapping returned %d",
+ "i4", rv);
+ }
}
}
return;
diff --git a/src/plugins/nat/nat44-ed/nat44_ed.h b/src/plugins/nat/nat44-ed/nat44_ed.h
index 6abdbadae43..b74b46f81b7 100644
--- a/src/plugins/nat/nat44-ed/nat44_ed.h
+++ b/src/plugins/nat/nat44-ed/nat44_ed.h
@@ -43,12 +43,11 @@
#define SNAT_FLAG_HAIRPINNING (1 << 0)
/* NAT44 API Configuration flags */
-#define foreach_nat44_config_flag \
- _(0x00, IS_ENDPOINT_INDEPENDENT) \
- _(0x01, IS_ENDPOINT_DEPENDENT) \
- _(0x02, IS_STATIC_MAPPING_ONLY) \
- _(0x04, IS_CONNECTION_TRACKING) \
- _(0x08, IS_OUT2IN_DPO)
+#define foreach_nat44_config_flag \
+ _ (0x00, IS_ENDPOINT_INDEPENDENT) \
+ _ (0x01, IS_ENDPOINT_DEPENDENT) \
+ _ (0x02, IS_STATIC_MAPPING_ONLY) \
+ _ (0x04, IS_CONNECTION_TRACKING)
typedef enum nat44_config_flags_t_
{
@@ -187,11 +186,14 @@ typedef enum
#define NAT_INTERFACE_FLAG_IS_OUTSIDE 2
/* Static mapping flags */
-#define NAT_STATIC_MAPPING_FLAG_ADDR_ONLY 1
-#define NAT_STATIC_MAPPING_FLAG_OUT2IN_ONLY 2
-#define NAT_STATIC_MAPPING_FLAG_IDENTITY_NAT 4
-#define NAT_STATIC_MAPPING_FLAG_LB 8
-#define NAT_STATIC_MAPPING_FLAG_EXACT_ADDRESS 16
+#define NAT_SM_FLAG_SELF_TWICE_NAT (1 << 1)
+#define NAT_SM_FLAG_TWICE_NAT (1 << 2)
+#define NAT_SM_FLAG_IDENTITY_NAT (1 << 3)
+#define NAT_SM_FLAG_ADDR_ONLY (1 << 4)
+#define NAT_SM_FLAG_EXACT_ADDRESS (1 << 5)
+#define NAT_SM_FLAG_OUT2IN_ONLY (1 << 6)
+#define NAT_SM_FLAG_LB (1 << 7)
+#define NAT_SM_FLAG_SWITCH_ADDRESS (1 << 8)
typedef CLIB_PACKED(struct
{
@@ -420,8 +422,6 @@ typedef struct
u16 local_port;
/* external port */
u16 external_port;
- /* is twice-nat */
- twice_nat_type_t twice_nat;
/* local FIB table */
u32 vrf_id;
u32 fib_index;
@@ -786,36 +786,6 @@ unformat_function_t unformat_nat_protocol;
*/
#define nat44_is_ses_closed(s) s->state == 0xf
-/** \brief Check if NAT static mapping is address only (1:1NAT).
- @param sm NAT static mapping
- @return 1 if 1:1NAT, 0 if 1:1NAPT
-*/
-#define is_addr_only_static_mapping(sm) (sm->flags & NAT_STATIC_MAPPING_FLAG_ADDR_ONLY)
-
-/** \brief Check if NAT static mapping match only out2in direction.
- @param sm NAT static mapping
- @return 1 if rule match only out2in direction
-*/
-#define is_out2in_only_static_mapping(sm) (sm->flags & NAT_STATIC_MAPPING_FLAG_OUT2IN_ONLY)
-
-/** \brief Check if NAT static mapping is identity NAT.
- @param sm NAT static mapping
- @return 1 if identity NAT
-*/
-#define is_identity_static_mapping(sm) (sm->flags & NAT_STATIC_MAPPING_FLAG_IDENTITY_NAT)
-
-/** \brief Check if NAT static mapping is load-balancing.
- @param sm NAT static mapping
- @return 1 if load-balancing
-*/
-#define is_lb_static_mapping(sm) (sm->flags & NAT_STATIC_MAPPING_FLAG_LB)
-
-/** \brief Check if exact pool address should be used.
- @param s SNAT session
- @return 1 if exact pool address or 0
-*/
-#define is_exact_address(s) (s->flags & NAT_STATIC_MAPPING_FLAG_EXACT_ADDRESS)
-
/** \brief Check if client initiating TCP connection (received SYN from client)
@param t TCP header
@return 1 if client initiating TCP connection
@@ -826,6 +796,54 @@ tcp_flags_is_init (u8 f)
return (f & TCP_FLAG_SYN) && !(f & TCP_FLAG_ACK);
}
+always_inline bool
+is_sm_addr_only (u32 f)
+{
+ return (f & NAT_SM_FLAG_ADDR_ONLY);
+}
+
+always_inline bool
+is_sm_out2in_only (u32 f)
+{
+ return (f & NAT_SM_FLAG_OUT2IN_ONLY);
+}
+
+always_inline bool
+is_sm_identity_nat (u32 f)
+{
+ return (f & NAT_SM_FLAG_IDENTITY_NAT);
+}
+
+always_inline bool
+is_sm_lb (u32 f)
+{
+ return (f & NAT_SM_FLAG_LB);
+}
+
+always_inline bool
+is_sm_exact_address (u32 f)
+{
+ return (f & NAT_SM_FLAG_EXACT_ADDRESS);
+}
+
+always_inline bool
+is_sm_self_twice_nat (u32 f)
+{
+ return (f & NAT_SM_FLAG_SELF_TWICE_NAT);
+}
+
+always_inline bool
+is_sm_twice_nat (u32 f)
+{
+ return (f & NAT_SM_FLAG_TWICE_NAT);
+}
+
+always_inline bool
+is_sm_switch_address (u32 f)
+{
+ return (f & NAT_SM_FLAG_SWITCH_ADDRESS);
+}
+
/* logging */
#define nat_log_err(...) \
vlib_log(VLIB_LOG_LEVEL_ERR, snat_main.log_class, __VA_ARGS__)
@@ -838,6 +856,28 @@ tcp_flags_is_init (u8 f)
#define nat_log_debug(...)\
vlib_log(VLIB_LOG_LEVEL_DEBUG, snat_main.log_class, __VA_ARGS__)
+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,
+ ip4_address_t pool_addr, u8 *tag);
+
+int nat44_ed_del_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);
+
+int nat44_ed_add_lb_static_mapping (ip4_address_t e_addr, u16 e_port,
+ nat_protocol_t proto,
+ nat44_lb_addr_port_t *locals, u32 flags,
+ u8 *tag, u32 affinity);
+
+int nat44_ed_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port,
+ nat_protocol_t proto, u32 flags);
+
+int nat44_ed_add_del_lb_static_mapping_local (ip4_address_t e_addr, u16 e_port,
+ ip4_address_t l_addr, u16 l_port,
+ nat_protocol_t proto, u32 vrf_id,
+ u8 probability, u8 is_add);
+
/**
* @brief Enable NAT44 plugin
*
@@ -880,71 +920,6 @@ int snat_add_address (snat_main_t * sm, ip4_address_t * addr, u32 vrf_id,
int snat_del_address (snat_main_t * sm, ip4_address_t addr, u8 delete_sm,
u8 twice_nat);
-/**
- * @brief Add/delete external address to FIB DPO (out2in DPO mode)
- *
- * @param addr IPv4 address
- * @param is_add 1 = add, 0 = delete
- *
- * @return 0 on success, non-zero value otherwise
- */
-void nat44_add_del_address_dpo (ip4_address_t addr, u8 is_add);
-
-/**
- * @brief Add/delete NAT44 static mapping
- *
- * @param l_addr local IPv4 address
- * @param e_addr external IPv4 address
- * @param l_port local port number
- * @param e_port external port number
- * @param vrf_id local VRF ID
- * @param addr_only 1 = 1:1NAT, 0 = 1:1NAPT
- * @param sw_if_index use interface address as external IPv4 address
- * @param proto L4 protocol
- * @param is_add 1 = add, 0 = delete
- * @param twice_nat twice-nat mode
- * @param out2in_only if 1 rule match only out2in direction
- * @param tag opaque string tag
- * @param identity_nat identity NAT
- * @param pool_addr pool IPv4 address
- * @param exact 1 = exact pool address
- *
- * @return 0 on success, non-zero value otherwise
- */
-int snat_add_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
- u16 l_port, u16 e_port, u32 vrf_id,
- int addr_only, u32 sw_if_index,
- nat_protocol_t proto, int is_add,
- twice_nat_type_t twice_nat, u8 out2in_only,
- u8 * tag, u8 identity_nat,
- ip4_address_t pool_addr, int exact);
-
-/**
- * @brief Add/delete static mapping with load-balancing (multiple backends)
- *
- * @param e_addr external IPv4 address
- * @param e_port external port number
- * @param proto L4 protocol
- * @param locals list of local backends
- * @param is_add 1 = add, 0 = delete
- * @param twice_nat twice-nat mode
- * @param out2in_only if 1 rule match only out2in direction
- * @param tag opaque string tag
- * @param affinity 0 = disabled, otherwise client IP affinity sticky time
- *
- * @return 0 on success, non-zero value otherwise
- */
-int nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port,
- nat_protocol_t proto,
- nat44_lb_addr_port_t * locals, u8 is_add,
- twice_nat_type_t twice_nat,
- u8 out2in_only, u8 * tag, u32 affinity);
-
-int nat44_lb_static_mapping_add_del_local (ip4_address_t e_addr, u16 e_port,
- ip4_address_t l_addr, u16 l_port,
- nat_protocol_t proto, u32 vrf_id,
- u8 probability, u8 is_add);
-
clib_error_t *nat44_api_hookup (vlib_main_t * vm);
/**
@@ -1074,26 +1049,6 @@ int snat_static_mapping_match (
void snat_add_del_addr_to_fib (ip4_address_t * addr,
u8 p_len, u32 sw_if_index, int is_add);
-#if 0
-void
-nat_ha_sadd_ed_cb (ip4_address_t * in_addr, u16 in_port,
- ip4_address_t * out_addr, u16 out_port,
- ip4_address_t * eh_addr, u16 eh_port,
- ip4_address_t * ehn_addr, u16 ehn_port, u8 proto,
- u32 fib_index, u16 flags, u32 thread_index);
-
-void
-nat_ha_sdel_ed_cb (ip4_address_t * out_addr, u16 out_port,
- ip4_address_t * eh_addr, u16 eh_port, u8 proto,
- u32 fib_index, u32 ti);
-
-void
-nat_ha_sref_ed_cb (ip4_address_t * out_addr, u16 out_port,
- ip4_address_t * eh_addr, u16 eh_port, u8 proto,
- u32 fib_index, u32 total_pkts, u64 total_bytes,
- u32 thread_index);
-#endif
-
int nat_set_outside_address_and_port (snat_address_t *addresses,
u32 thread_index, ip4_address_t addr,
u16 port, nat_protocol_t protocol);
diff --git a/src/plugins/nat/nat44-ed/nat44_ed_affinity.h b/src/plugins/nat/nat44-ed/nat44_ed_affinity.h
index bd9b4d6ae59..a119a5b5b91 100644
--- a/src/plugins/nat/nat44-ed/nat44_ed_affinity.h
+++ b/src/plugins/nat/nat44-ed/nat44_ed_affinity.h
@@ -41,7 +41,6 @@ typedef struct
};
} nat_affinity_key_t;
-/* *INDENT-OFF* */
typedef CLIB_PACKED(struct
{
nat_affinity_key_t key;
@@ -51,7 +50,6 @@ typedef CLIB_PACKED(struct
u8 backend_index;
f64 expire;
}) nat_affinity_t;
-/* *INDENT-ON* */
typedef struct
{
diff --git a/src/plugins/nat/nat44-ed/nat44_ed_api.c b/src/plugins/nat/nat44-ed/nat44_ed_api.c
index f92de51ea44..74d48b2d821 100644
--- a/src/plugins/nat/nat44-ed/nat44_ed_api.c
+++ b/src/plugins/nat/nat44-ed/nat44_ed_api.c
@@ -496,43 +496,73 @@ static void
vl_api_nat44_add_del_static_mapping_t_handler
(vl_api_nat44_add_del_static_mapping_t * mp)
{
- snat_main_t *sm = &snat_main;
vl_api_nat44_add_del_static_mapping_reply_t *rmp;
- ip4_address_t local_addr, external_addr, pool_addr = { 0 };
- u16 local_port = 0, external_port = 0;
- u32 vrf_id, external_sw_if_index;
- twice_nat_type_t twice_nat = TWICE_NAT_DISABLED;
+
+ snat_main_t *sm = &snat_main;
int rv = 0;
- nat_protocol_t proto;
+
+ ip4_address_t l_addr, e_addr, pool_addr = { 0 };
+ u32 sw_if_index, flags = 0, vrf_id;
+ u16 l_port = 0, e_port = 0;
+ nat_protocol_t proto = 0;
u8 *tag = 0;
- memcpy (&local_addr.as_u8, mp->local_ip_address, 4);
- memcpy (&external_addr.as_u8, mp->external_ip_address, 4);
+ memcpy (&l_addr.as_u8, mp->local_ip_address, 4);
- if (!(mp->flags & NAT_API_IS_ADDR_ONLY))
+ if (mp->flags & NAT_API_IS_ADDR_ONLY)
{
- local_port = mp->local_port;
- external_port = mp->external_port;
+ flags |= NAT_SM_FLAG_ADDR_ONLY;
+ }
+ else
+ {
+ l_port = mp->local_port;
+ e_port = mp->external_port;
+ proto = ip_proto_to_nat_proto (mp->protocol);
}
-
- vrf_id = clib_net_to_host_u32 (mp->vrf_id);
- external_sw_if_index = clib_net_to_host_u32 (mp->external_sw_if_index);
- proto = ip_proto_to_nat_proto (mp->protocol);
if (mp->flags & NAT_API_IS_TWICE_NAT)
- twice_nat = TWICE_NAT;
- else if (mp->flags & NAT_API_IS_SELF_TWICE_NAT)
- twice_nat = TWICE_NAT_SELF;
- mp->tag[sizeof (mp->tag) - 1] = 0;
- tag = format (0, "%s", mp->tag);
- vec_terminate_c_string (tag);
-
- rv = snat_add_static_mapping (
- local_addr, external_addr, local_port, external_port, vrf_id,
- mp->flags & NAT_API_IS_ADDR_ONLY, external_sw_if_index, proto, mp->is_add,
- twice_nat, mp->flags & NAT_API_IS_OUT2IN_ONLY, tag, 0, pool_addr, 0);
- vec_free (tag);
+ {
+ flags |= NAT_SM_FLAG_TWICE_NAT;
+ }
+
+ if (mp->flags & NAT_API_IS_SELF_TWICE_NAT)
+ {
+ flags |= NAT_SM_FLAG_SELF_TWICE_NAT;
+ }
+
+ if (mp->flags & NAT_API_IS_OUT2IN_ONLY)
+ {
+ flags |= NAT_SM_FLAG_OUT2IN_ONLY;
+ }
+ sw_if_index = clib_net_to_host_u32 (mp->external_sw_if_index);
+ if (sw_if_index != ~0)
+ {
+ flags |= NAT_SM_FLAG_SWITCH_ADDRESS;
+ }
+ else
+ {
+ memcpy (&e_addr.as_u8, mp->external_ip_address, 4);
+ }
+
+ vrf_id = clib_net_to_host_u32 (mp->vrf_id);
+
+ if (mp->is_add)
+ {
+ mp->tag[sizeof (mp->tag) - 1] = 0;
+ tag = format (0, "%s", mp->tag);
+ vec_terminate_c_string (tag);
+
+ rv = nat44_ed_add_static_mapping (l_addr, e_addr, l_port, e_port, proto,
+ vrf_id, sw_if_index, flags, pool_addr,
+ tag);
+ vec_free (tag);
+ }
+ else
+ {
+ rv = nat44_ed_del_static_mapping (l_addr, e_addr, l_port, e_port, proto,
+ vrf_id, sw_if_index, flags);
+ }
REPLY_MACRO (VL_API_NAT44_ADD_DEL_STATIC_MAPPING_REPLY);
}
@@ -540,47 +570,79 @@ static void
vl_api_nat44_add_del_static_mapping_v2_t_handler
(vl_api_nat44_add_del_static_mapping_v2_t * mp)
{
- snat_main_t *sm = &snat_main;
vl_api_nat44_add_del_static_mapping_v2_reply_t *rmp;
- ip4_address_t local_addr, external_addr, pool_addr;
- u16 local_port = 0, external_port = 0;
- u32 vrf_id, external_sw_if_index;
- twice_nat_type_t twice_nat = TWICE_NAT_DISABLED;
+
+ snat_main_t *sm = &snat_main;
int rv = 0;
+
+ ip4_address_t l_addr, e_addr, pool_addr;
+ u32 sw_if_index, flags = 0, vrf_id;
+ u16 l_port = 0, e_port = 0;
nat_protocol_t proto;
u8 *tag = 0;
+ memcpy (&l_addr.as_u8, mp->local_ip_address, 4);
memcpy (&pool_addr.as_u8, mp->pool_ip_address, 4);
- memcpy (&local_addr.as_u8, mp->local_ip_address, 4);
- memcpy (&external_addr.as_u8, mp->external_ip_address, 4);
- if (!(mp->flags & NAT_API_IS_ADDR_ONLY))
+ if (pool_addr.as_u32 != 0)
{
- local_port = mp->local_port;
- external_port = mp->external_port;
+ flags |= NAT_SM_FLAG_EXACT_ADDRESS;
}
- vrf_id = clib_net_to_host_u32 (mp->vrf_id);
- external_sw_if_index = clib_net_to_host_u32 (mp->external_sw_if_index);
- proto = ip_proto_to_nat_proto (mp->protocol);
+ if (mp->flags & NAT_API_IS_ADDR_ONLY)
+ {
+ flags |= NAT_SM_FLAG_ADDR_ONLY;
+ }
+ else
+ {
+ l_port = mp->local_port;
+ e_port = mp->external_port;
+ }
if (mp->flags & NAT_API_IS_TWICE_NAT)
- twice_nat = TWICE_NAT;
- else if (mp->flags & NAT_API_IS_SELF_TWICE_NAT)
- twice_nat = TWICE_NAT_SELF;
- mp->tag[sizeof (mp->tag) - 1] = 0;
- tag = format (0, "%s", mp->tag);
- vec_terminate_c_string (tag);
-
- rv = snat_add_static_mapping (local_addr, external_addr, local_port,
- external_port, vrf_id,
- mp->flags & NAT_API_IS_ADDR_ONLY,
- external_sw_if_index, proto,
- mp->is_add, twice_nat,
- mp->flags & NAT_API_IS_OUT2IN_ONLY, tag, 0,
- pool_addr, mp->match_pool);
- vec_free (tag);
+ {
+ flags |= NAT_SM_FLAG_TWICE_NAT;
+ }
+ if (mp->flags & NAT_API_IS_SELF_TWICE_NAT)
+ {
+ flags |= NAT_SM_FLAG_SELF_TWICE_NAT;
+ }
+
+ if (mp->flags & NAT_API_IS_OUT2IN_ONLY)
+ {
+ flags |= NAT_SM_FLAG_OUT2IN_ONLY;
+ }
+
+ sw_if_index = clib_net_to_host_u32 (mp->external_sw_if_index);
+ if (sw_if_index)
+ {
+ flags |= NAT_SM_FLAG_SWITCH_ADDRESS;
+ }
+ else
+ {
+ memcpy (&e_addr.as_u8, mp->external_ip_address, 4);
+ }
+
+ proto = ip_proto_to_nat_proto (mp->protocol);
+ vrf_id = clib_net_to_host_u32 (mp->vrf_id);
+
+ if (mp->is_add)
+ {
+ mp->tag[sizeof (mp->tag) - 1] = 0;
+ tag = format (0, "%s", mp->tag);
+ vec_terminate_c_string (tag);
+
+ rv = nat44_ed_add_static_mapping (l_addr, e_addr, l_port, e_port, proto,
+ vrf_id, sw_if_index, flags, pool_addr,
+ tag);
+ vec_free (tag);
+ }
+ else
+ {
+ rv = nat44_ed_del_static_mapping (l_addr, e_addr, l_port, e_port, proto,
+ vrf_id, sw_if_index, flags);
+ }
REPLY_MACRO (VL_API_NAT44_ADD_DEL_STATIC_MAPPING_V2_REPLY);
}
@@ -603,15 +665,24 @@ send_nat44_static_mapping_details (snat_static_mapping_t * m,
rmp->vrf_id = htonl (m->vrf_id);
rmp->context = context;
- if (m->twice_nat == TWICE_NAT)
- rmp->flags |= NAT_API_IS_TWICE_NAT;
- else if (m->twice_nat == TWICE_NAT_SELF)
- rmp->flags |= NAT_API_IS_SELF_TWICE_NAT;
+ // convert these in new api
- if (is_out2in_only_static_mapping (m))
- rmp->flags |= NAT_API_IS_OUT2IN_ONLY;
+ if (is_sm_self_twice_nat (m->flags))
+ {
+ rmp->flags |= NAT_API_IS_SELF_TWICE_NAT;
+ }
- if (is_addr_only_static_mapping (m))
+ if (is_sm_out2in_only (m->flags))
+ {
+ rmp->flags |= NAT_API_IS_OUT2IN_ONLY;
+ }
+
+ if (is_sm_twice_nat (m->flags))
+ {
+ rmp->flags |= NAT_API_IS_TWICE_NAT;
+ }
+
+ if (is_sm_addr_only (m->flags))
{
rmp->flags |= NAT_API_IS_ADDR_ONLY;
}
@@ -680,8 +751,8 @@ vl_api_nat44_static_mapping_dump_t_handler (vl_api_nat44_static_mapping_dump_t
pool_foreach (m, sm->static_mappings)
{
- if (!is_identity_static_mapping(m) && !is_lb_static_mapping (m))
- send_nat44_static_mapping_details (m, reg, mp->context);
+ if (!is_sm_identity_nat (m->flags) && !is_sm_lb (m->flags))
+ send_nat44_static_mapping_details (m, reg, mp->context);
}
for (j = 0; j < vec_len (sm->to_resolve); j++)
@@ -696,36 +767,56 @@ static void
vl_api_nat44_add_del_identity_mapping_t_handler
(vl_api_nat44_add_del_identity_mapping_t * mp)
{
- snat_main_t *sm = &snat_main;
vl_api_nat44_add_del_identity_mapping_reply_t *rmp;
+
+ snat_main_t *sm = &snat_main;
+ int rv = 0;
+
ip4_address_t addr, pool_addr = { 0 };
+ u32 sw_if_index, flags, vrf_id;
+ nat_protocol_t proto = 0;
u16 port = 0;
- u32 vrf_id, sw_if_index;
- int rv = 0;
- nat_protocol_t proto = NAT_PROTOCOL_OTHER;
u8 *tag = 0;
- if (!(mp->flags & NAT_API_IS_ADDR_ONLY))
+ flags = NAT_SM_FLAG_IDENTITY_NAT;
+
+ if (mp->flags & NAT_API_IS_ADDR_ONLY)
+ {
+ flags |= NAT_SM_FLAG_ADDR_ONLY;
+ }
+ else
{
port = mp->port;
proto = ip_proto_to_nat_proto (mp->protocol);
}
- vrf_id = clib_net_to_host_u32 (mp->vrf_id);
+
sw_if_index = clib_net_to_host_u32 (mp->sw_if_index);
if (sw_if_index != ~0)
- addr.as_u32 = 0;
+ {
+ flags |= NAT_SM_FLAG_SWITCH_ADDRESS;
+ }
else
- memcpy (&addr.as_u8, mp->ip_address, 4);
- mp->tag[sizeof (mp->tag) - 1] = 0;
- tag = format (0, "%s", mp->tag);
- vec_terminate_c_string (tag);
-
- rv =
- snat_add_static_mapping (addr, addr, port, port, vrf_id,
- mp->flags & NAT_API_IS_ADDR_ONLY, sw_if_index,
- proto, mp->is_add, 0, 0, tag, 1, pool_addr, 0);
- vec_free (tag);
+ {
+ memcpy (&addr.as_u8, mp->ip_address, 4);
+ }
+
+ vrf_id = clib_net_to_host_u32 (mp->vrf_id);
+ if (mp->is_add)
+ {
+ mp->tag[sizeof (mp->tag) - 1] = 0;
+ tag = format (0, "%s", mp->tag);
+ vec_terminate_c_string (tag);
+
+ rv = nat44_ed_add_static_mapping (addr, addr, port, port, proto, vrf_id,
+ sw_if_index, flags, pool_addr, tag);
+ vec_free (tag);
+ }
+ else
+ {
+ rv = nat44_ed_del_static_mapping (addr, addr, port, port, proto, vrf_id,
+ sw_if_index, flags);
+ }
REPLY_MACRO (VL_API_NAT44_ADD_DEL_IDENTITY_MAPPING_REPLY);
}
@@ -742,7 +833,7 @@ send_nat44_identity_mapping_details (snat_static_mapping_t * m, int index,
rmp->_vl_msg_id =
ntohs (VL_API_NAT44_IDENTITY_MAPPING_DETAILS + sm->msg_id_base);
- if (is_addr_only_static_mapping (m))
+ if (is_sm_addr_only (m->flags))
rmp->flags |= NAT_API_IS_ADDR_ONLY;
clib_memcpy (rmp->ip_address, &(m->local_addr), 4);
@@ -800,13 +891,13 @@ static void
pool_foreach (m, sm->static_mappings)
{
- if (is_identity_static_mapping(m) && !is_lb_static_mapping (m))
- {
- 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++)
@@ -917,12 +1008,12 @@ vl_api_nat44_add_del_lb_static_mapping_t_handler (
{
snat_main_t *sm = &snat_main;
vl_api_nat44_add_del_lb_static_mapping_reply_t *rmp;
- twice_nat_type_t twice_nat = TWICE_NAT_DISABLED;
- int rv = 0;
nat44_lb_addr_port_t *locals = 0;
ip4_address_t e_addr;
nat_protocol_t proto;
+ u32 flags = 0;
u8 *tag = 0;
+ int rv = 0;
locals = unformat_nat44_lb_addr_port (mp->locals,
clib_net_to_host_u32 (mp->local_num));
@@ -930,17 +1021,34 @@ vl_api_nat44_add_del_lb_static_mapping_t_handler (
proto = ip_proto_to_nat_proto (mp->protocol);
if (mp->flags & NAT_API_IS_TWICE_NAT)
- twice_nat = TWICE_NAT;
+ {
+ flags |= NAT_SM_FLAG_TWICE_NAT;
+ }
else if (mp->flags & NAT_API_IS_SELF_TWICE_NAT)
- twice_nat = TWICE_NAT_SELF;
- mp->tag[sizeof (mp->tag) - 1] = 0;
- tag = format (0, "%s", mp->tag);
- vec_terminate_c_string (tag);
+ {
+ flags |= NAT_SM_FLAG_SELF_TWICE_NAT;
+ }
- rv = nat44_add_del_lb_static_mapping (
- e_addr, mp->external_port, proto, locals, mp->is_add, twice_nat,
- mp->flags & NAT_API_IS_OUT2IN_ONLY, tag,
- clib_net_to_host_u32 (mp->affinity));
+ if (mp->flags & NAT_API_IS_OUT2IN_ONLY)
+ {
+ flags |= NAT_SM_FLAG_OUT2IN_ONLY;
+ }
+
+ if (mp->is_add)
+ {
+ mp->tag[sizeof (mp->tag) - 1] = 0;
+ tag = format (0, "%s", mp->tag);
+ vec_terminate_c_string (tag);
+
+ rv = nat44_ed_add_lb_static_mapping (
+ e_addr, mp->external_port, proto, locals, flags, tag,
+ clib_net_to_host_u32 (mp->affinity));
+ }
+ else
+ {
+ rv = nat44_ed_del_lb_static_mapping (e_addr, mp->external_port, proto,
+ flags);
+ }
vec_free (locals);
vec_free (tag);
@@ -961,7 +1069,7 @@ vl_api_nat44_lb_static_mapping_add_del_local_t_handler (
clib_memcpy (&l_addr, mp->local.addr, 4);
proto = ip_proto_to_nat_proto (mp->protocol);
- rv = nat44_lb_static_mapping_add_del_local (
+ rv = nat44_ed_add_del_lb_static_mapping_local (
e_addr, mp->external_port, l_addr, mp->local.port, proto,
clib_net_to_host_u32 (mp->local.vrf_id), mp->local.probability,
mp->is_add);
@@ -990,12 +1098,21 @@ send_nat44_lb_static_mapping_details (snat_static_mapping_t *m,
rmp->protocol = nat_proto_to_ip_proto (m->proto);
rmp->context = context;
- if (m->twice_nat == TWICE_NAT)
- rmp->flags |= NAT_API_IS_TWICE_NAT;
- else if (m->twice_nat == TWICE_NAT_SELF)
- rmp->flags |= NAT_API_IS_SELF_TWICE_NAT;
- if (is_out2in_only_static_mapping (m))
- rmp->flags |= NAT_API_IS_OUT2IN_ONLY;
+ if (is_sm_self_twice_nat (m->flags))
+ {
+ rmp->flags |= NAT_API_IS_SELF_TWICE_NAT;
+ }
+
+ if (is_sm_out2in_only (m->flags))
+ {
+ rmp->flags |= NAT_API_IS_OUT2IN_ONLY;
+ }
+
+ if (is_sm_twice_nat (m->flags))
+ {
+ rmp->flags |= NAT_API_IS_TWICE_NAT;
+ }
+
if (m->tag)
strncpy ((char *) rmp->tag, (char *) m->tag, vec_len (m->tag));
@@ -1028,7 +1145,7 @@ vl_api_nat44_lb_static_mapping_dump_t_handler (
pool_foreach (m, sm->static_mappings)
{
- if (is_lb_static_mapping (m))
+ if (is_sm_lb (m->flags))
send_nat44_lb_static_mapping_details (m, reg, mp->context);
}
}
@@ -1198,9 +1315,7 @@ vl_api_nat44_plugin_enable_disable_t_handler (
if (mp->enable)
{
- if (!(mp->flags & NAT44_API_IS_ENDPOINT_DEPENDENT) ||
- (mp->flags & NAT44_API_IS_OUT2IN_DPO) || mp->users ||
- mp->user_sessions)
+ if (mp->users || mp->user_sessions)
{
rv = VNET_API_ERROR_UNSUPPORTED;
}
diff --git a/src/plugins/nat/nat44-ed/nat44_ed_cli.c b/src/plugins/nat/nat44-ed/nat44_ed_cli.c
index cb0fe9ec12c..acf9069af2b 100644
--- a/src/plugins/nat/nat44-ed/nat44_ed_cli.c
+++ b/src/plugins/nat/nat44-ed/nat44_ed_cli.c
@@ -830,18 +830,17 @@ add_static_mapping_command_fn (vlib_main_t * vm,
vlib_cli_command_t * cmd)
{
unformat_input_t _line_input, *line_input = &_line_input;
- clib_error_t *error = 0;
- ip4_address_t l_addr, e_addr, exact_addr;
- u32 l_port = 0, e_port = 0, vrf_id = ~0;
- int is_add = 1, addr_only = 1, rv, exact = 0;
- u32 sw_if_index = ~0;
vnet_main_t *vnm = vnet_get_main ();
+ clib_error_t *error = 0;
+ int rv;
+
nat_protocol_t proto = NAT_PROTOCOL_OTHER;
- u8 proto_set = 0;
- twice_nat_type_t twice_nat = TWICE_NAT_DISABLED;
- u8 out2in_only = 0;
+ 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;
- /* Get a line of input. */
if (!unformat_user (input, unformat_line_input, line_input))
return clib_error_return (0, NAT44_ED_EXPECTED_ARGUMENT);
@@ -849,38 +848,57 @@ add_static_mapping_command_fn (vlib_main_t * vm,
{
if (unformat (line_input, "local %U %u", unformat_ip4_address, &l_addr,
&l_port))
- addr_only = 0;
+ {
+ l_port_set = 1;
+ }
else
if (unformat (line_input, "local %U", unformat_ip4_address, &l_addr))
;
else if (unformat (line_input, "external %U %u", unformat_ip4_address,
&e_addr, &e_port))
- addr_only = 0;
+ {
+ e_port_set = 1;
+ }
else if (unformat (line_input, "external %U", unformat_ip4_address,
&e_addr))
;
else if (unformat (line_input, "external %U %u",
unformat_vnet_sw_interface, vnm, &sw_if_index,
&e_port))
- addr_only = 0;
+ {
+ flags |= NAT_SM_FLAG_SWITCH_ADDRESS;
+ e_port_set = 1;
+ }
else if (unformat (line_input, "external %U",
unformat_vnet_sw_interface, vnm, &sw_if_index))
- ;
+ {
+ flags |= NAT_SM_FLAG_SWITCH_ADDRESS;
+ }
else if (unformat (line_input, "exact %U", unformat_ip4_address,
- &exact_addr))
- exact = 1;
+ &pool_addr))
+ {
+ flags |= NAT_SM_FLAG_EXACT_ADDRESS;
+ }
else if (unformat (line_input, "vrf %u", &vrf_id))
;
else if (unformat (line_input, "%U", unformat_nat_protocol, &proto))
- proto_set = 1;
- else if (unformat (line_input, "twice-nat"))
- twice_nat = TWICE_NAT;
+ ;
else if (unformat (line_input, "self-twice-nat"))
- twice_nat = TWICE_NAT_SELF;
+ {
+ flags |= NAT_SM_FLAG_SELF_TWICE_NAT;
+ }
+ else if (unformat (line_input, "twice-nat"))
+ {
+ flags |= NAT_SM_FLAG_TWICE_NAT;
+ }
else if (unformat (line_input, "out2in-only"))
- out2in_only = 1;
+ {
+ flags |= NAT_SM_FLAG_OUT2IN_ONLY;
+ }
else if (unformat (line_input, "del"))
- is_add = 0;
+ {
+ is_add = 0;
+ }
else
{
error = clib_error_return (0, "unknown input: '%U'",
@@ -889,32 +907,37 @@ add_static_mapping_command_fn (vlib_main_t * vm,
}
}
- if (twice_nat && addr_only)
+ if (l_port_set != e_port_set)
{
- error = clib_error_return (0, "twice NAT only for 1:1 NAPT");
+ error = clib_error_return (0, "Either both ports are set or none.");
goto done;
}
- if (addr_only)
+ if (!l_port_set)
{
- if (proto_set)
- {
- error =
- clib_error_return (0,
- "address only mapping doesn't support protocol");
- goto done;
- }
+ flags |= NAT_SM_FLAG_ADDR_ONLY;
}
- else if (!proto_set)
+ else
{
- error = clib_error_return (0, "protocol is required");
- goto done;
+ l_port = clib_host_to_net_u16 (l_port);
+ e_port = clib_host_to_net_u16 (e_port);
}
- rv = snat_add_static_mapping (
- l_addr, e_addr, clib_host_to_net_u16 (l_port),
- clib_host_to_net_u16 (e_port), vrf_id, addr_only, sw_if_index, proto,
- is_add, twice_nat, out2in_only, 0, 0, exact_addr, exact);
+ // TODO: specific pool_addr for both pool & twice nat pool ?
+
+ if (is_add)
+ {
+ rv =
+ nat44_ed_add_static_mapping (l_addr, e_addr, l_port, e_port, proto,
+ vrf_id, sw_if_index, flags, pool_addr, 0);
+ }
+ else
+ {
+ rv = nat44_ed_del_static_mapping (l_addr, e_addr, l_port, e_port, proto,
+ vrf_id, sw_if_index, flags);
+ }
+
+ // TODO: fix returns
switch (rv)
{
@@ -943,23 +966,22 @@ 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,
vlib_cli_command_t * cmd)
{
unformat_input_t _line_input, *line_input = &_line_input;
- clib_error_t *error = 0;
- ip4_address_t addr, pool_addr = { 0 };
- u32 port = 0, vrf_id = ~0;
- int is_add = 1;
- int addr_only = 1;
- u32 sw_if_index = ~0;
vnet_main_t *vnm = vnet_get_main ();
- int rv;
+ clib_error_t *error = 0;
+
+ int rv, is_add = 1, port_set = 0;
+ u32 sw_if_index, port, flags, vrf_id = ~0;
nat_protocol_t proto;
+ ip4_address_t addr;
- addr.as_u32 = 0;
+ flags = NAT_SM_FLAG_IDENTITY_NAT;
/* Get a line of input. */
if (!unformat_user (input, unformat_line_input, line_input))
@@ -971,14 +993,20 @@ add_identity_mapping_command_fn (vlib_main_t * vm,
;
else if (unformat (line_input, "external %U",
unformat_vnet_sw_interface, vnm, &sw_if_index))
- ;
+ {
+ flags |= NAT_SM_FLAG_SWITCH_ADDRESS;
+ }
else if (unformat (line_input, "vrf %u", &vrf_id))
;
else if (unformat (line_input, "%U %u", unformat_nat_protocol, &proto,
&port))
- addr_only = 0;
+ {
+ port_set = 1;
+ }
else if (unformat (line_input, "del"))
- is_add = 0;
+ {
+ is_add = 0;
+ }
else
{
error = clib_error_return (0, "unknown input: '%U'",
@@ -987,9 +1015,28 @@ add_identity_mapping_command_fn (vlib_main_t * vm,
}
}
- rv = snat_add_static_mapping (
- addr, addr, clib_host_to_net_u16 (port), clib_host_to_net_u16 (port),
- vrf_id, addr_only, sw_if_index, proto, is_add, 0, 0, 0, 1, pool_addr, 0);
+ if (!port_set)
+ {
+ flags |= NAT_SM_FLAG_ADDR_ONLY;
+ }
+ else
+ {
+ port = clib_host_to_net_u16 (port);
+ }
+
+ if (is_add)
+ {
+
+ rv = nat44_ed_add_static_mapping (addr, addr, port, port, proto, vrf_id,
+ sw_if_index, flags, addr, 0);
+ }
+ else
+ {
+ rv = nat44_ed_del_static_mapping (addr, addr, port, port, proto, vrf_id,
+ sw_if_index, flags);
+ }
+
+ // TODO: fix returns
switch (rv)
{
@@ -1027,13 +1074,11 @@ add_lb_static_mapping_command_fn (vlib_main_t * vm,
clib_error_t *error = 0;
ip4_address_t l_addr, e_addr;
u32 l_port = 0, e_port = 0, vrf_id = 0, probability = 0, affinity = 0;
- int is_add = 1;
- int rv;
- nat_protocol_t proto;
u8 proto_set = 0;
+ nat_protocol_t proto;
nat44_lb_addr_port_t *locals = 0, local;
- twice_nat_type_t twice_nat = TWICE_NAT_DISABLED;
- u8 out2in_only = 0;
+ int rv, is_add = 1;
+ u32 flags = 0;
/* Get a line of input. */
if (!unformat_user (input, unformat_line_input, line_input))
@@ -1066,15 +1111,25 @@ add_lb_static_mapping_command_fn (vlib_main_t * vm,
;
else if (unformat (line_input, "protocol %U", unformat_nat_protocol,
&proto))
- proto_set = 1;
+ {
+ proto_set = 1;
+ }
else if (unformat (line_input, "twice-nat"))
- twice_nat = TWICE_NAT;
+ {
+ flags |= NAT_SM_FLAG_TWICE_NAT;
+ }
else if (unformat (line_input, "self-twice-nat"))
- twice_nat = TWICE_NAT_SELF;
+ {
+ flags |= NAT_SM_FLAG_SELF_TWICE_NAT;
+ }
else if (unformat (line_input, "out2in-only"))
- out2in_only = 1;
+ {
+ flags |= NAT_SM_FLAG_OUT2IN_ONLY;
+ }
else if (unformat (line_input, "del"))
- is_add = 0;
+ {
+ is_add = 0;
+ }
else if (unformat (line_input, "affinity %u", &affinity))
;
else
@@ -1097,9 +1152,15 @@ add_lb_static_mapping_command_fn (vlib_main_t * vm,
goto done;
}
- rv = nat44_add_del_lb_static_mapping (e_addr, (u16) e_port, proto, locals,
- is_add, twice_nat, out2in_only, 0,
- affinity);
+ if (is_add)
+ {
+ rv = nat44_ed_add_lb_static_mapping (e_addr, (u16) e_port, proto, locals,
+ flags, 0, affinity);
+ }
+ else
+ {
+ rv = nat44_ed_del_lb_static_mapping (e_addr, (u16) e_port, proto, flags);
+ }
switch (rv)
{
@@ -1180,10 +1241,8 @@ add_lb_backend_command_fn (vlib_main_t * vm,
goto done;
}
- rv =
- nat44_lb_static_mapping_add_del_local (e_addr, (u16) e_port, l_addr,
- l_port, proto, vrf_id, probability,
- is_add);
+ rv = nat44_ed_add_del_lb_static_mapping_local (
+ e_addr, (u16) e_port, l_addr, l_port, proto, vrf_id, probability, is_add);
switch (rv)
{
diff --git a/src/plugins/nat/nat44-ed/nat44_ed_format.c b/src/plugins/nat/nat44-ed/nat44_ed_format.c
index 29fd1129f32..597bc2b4d0b 100644
--- a/src/plugins/nat/nat44-ed/nat44_ed_format.c
+++ b/src/plugins/nat/nat44-ed/nat44_ed_format.c
@@ -180,9 +180,9 @@ format_snat_static_mapping (u8 * s, va_list * args)
snat_static_mapping_t *m = va_arg (*args, snat_static_mapping_t *);
nat44_lb_addr_port_t *local;
- if (is_identity_static_mapping (m))
+ if (is_sm_identity_nat (m->flags))
{
- if (is_addr_only_static_mapping (m))
+ if (is_sm_addr_only (m->flags))
s = format (s, "identity mapping %U",
format_ip4_address, &m->local_addr);
else
@@ -191,58 +191,53 @@ format_snat_static_mapping (u8 * s, va_list * args)
format_ip4_address, &m->local_addr,
clib_net_to_host_u16 (m->local_port));
- /* *INDENT-OFF* */
pool_foreach (local, m->locals)
{
s = format (s, " vrf %d", local->vrf_id);
}
- /* *INDENT-ON* */
return s;
}
- if (is_addr_only_static_mapping (m))
- s = format (s, "local %U external %U vrf %d %s %s",
- format_ip4_address, &m->local_addr,
- format_ip4_address, &m->external_addr,
- m->vrf_id,
- m->twice_nat == TWICE_NAT ? "twice-nat" :
- m->twice_nat == TWICE_NAT_SELF ? "self-twice-nat" : "",
- is_out2in_only_static_mapping (m) ? "out2in-only" : "");
+ if (is_sm_addr_only (m->flags))
+ s =
+ format (s, "local %U external %U vrf %d %s %s", format_ip4_address,
+ &m->local_addr, format_ip4_address, &m->external_addr, m->vrf_id,
+ is_sm_twice_nat (m->flags) ?
+ "twice-nat" :
+ is_sm_self_twice_nat (m->flags) ? "self-twice-nat" : "",
+ is_sm_out2in_only (m->flags) ? "out2in-only" : "");
else
{
- if (is_lb_static_mapping (m))
+ if (is_sm_lb (m->flags))
{
- s = format (s, "%U external %U:%d %s %s",
- format_nat_protocol, m->proto,
- format_ip4_address, &m->external_addr,
- clib_net_to_host_u16 (m->external_port),
- m->twice_nat == TWICE_NAT ? "twice-nat" :
- m->twice_nat == TWICE_NAT_SELF ? "self-twice-nat" : "",
- is_out2in_only_static_mapping (m) ? "out2in-only" : "");
-
- /* *INDENT-OFF* */
- pool_foreach (local, m->locals)
- {
- s = format (s, "\n local %U:%d vrf %d probability %d\%",
- format_ip4_address, &local->addr,
- clib_net_to_host_u16 (local->port),
- local->vrf_id, local->probability);
- }
- /* *INDENT-ON* */
+ s =
+ format (s, "%U external %U:%d %s %s", format_nat_protocol,
+ m->proto, format_ip4_address, &m->external_addr,
+ clib_net_to_host_u16 (m->external_port),
+ is_sm_twice_nat (m->flags) ?
+ "twice-nat" :
+ is_sm_self_twice_nat (m->flags) ? "self-twice-nat" : "",
+ is_sm_out2in_only (m->flags) ? "out2in-only" : "");
+ pool_foreach (local, m->locals)
+ {
+ s = format (s, "\n local %U:%d vrf %d probability %d\%",
+ format_ip4_address, &local->addr,
+ clib_net_to_host_u16 (local->port), local->vrf_id,
+ local->probability);
+ }
}
else
s = format (s, "%U local %U:%d external %U:%d vrf %d %s %s",
- format_nat_protocol, m->proto,
- format_ip4_address, &m->local_addr,
- clib_net_to_host_u16 (m->local_port),
+ format_nat_protocol, m->proto, format_ip4_address,
+ &m->local_addr, clib_net_to_host_u16 (m->local_port),
format_ip4_address, &m->external_addr,
- clib_net_to_host_u16 (m->external_port),
- m->vrf_id,
- m->twice_nat == TWICE_NAT ? "twice-nat" :
- m->twice_nat == TWICE_NAT_SELF ? "self-twice-nat" : "",
- is_out2in_only_static_mapping (m) ? "out2in-only" : "");
+ clib_net_to_host_u16 (m->external_port), m->vrf_id,
+ is_sm_twice_nat (m->flags) ?
+ "twice-nat" :
+ is_sm_self_twice_nat (m->flags) ? "self-twice-nat" : "",
+ is_sm_out2in_only (m->flags) ? "out2in-only" : "");
}
return s;
}
diff --git a/src/plugins/nat/nat44-ed/nat44_ed_handoff.c b/src/plugins/nat/nat44-ed/nat44_ed_handoff.c
index 918d7728c1d..c5ceff4e454 100644
--- a/src/plugins/nat/nat44-ed/nat44_ed_handoff.c
+++ b/src/plugins/nat/nat44-ed/nat44_ed_handoff.c
@@ -294,7 +294,6 @@ VLIB_NODE_FN (snat_in2out_worker_handoff_node) (vlib_main_t * vm,
return nat44_worker_handoff_fn_inline (vm, node, frame, 0, 1);
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (snat_in2out_worker_handoff_node) = {
.name = "nat44-in2out-worker-handoff",
.vector_size = sizeof (u32),
@@ -304,7 +303,6 @@ VLIB_REGISTER_NODE (snat_in2out_worker_handoff_node) = {
.n_errors = ARRAY_LEN(nat44_handoff_error_strings),
.error_strings = nat44_handoff_error_strings,
};
-/* *INDENT-ON* */
VLIB_NODE_FN (snat_in2out_output_worker_handoff_node) (vlib_main_t * vm,
vlib_node_runtime_t *
@@ -314,7 +312,6 @@ VLIB_NODE_FN (snat_in2out_output_worker_handoff_node) (vlib_main_t * vm,
return nat44_worker_handoff_fn_inline (vm, node, frame, 1, 1);
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (snat_in2out_output_worker_handoff_node) = {
.name = "nat44-in2out-output-worker-handoff",
.vector_size = sizeof (u32),
@@ -324,7 +321,6 @@ VLIB_REGISTER_NODE (snat_in2out_output_worker_handoff_node) = {
.n_errors = ARRAY_LEN(nat44_handoff_error_strings),
.error_strings = nat44_handoff_error_strings,
};
-/* *INDENT-ON* */
VLIB_NODE_FN (snat_out2in_worker_handoff_node) (vlib_main_t * vm,
vlib_node_runtime_t * node,
@@ -333,7 +329,6 @@ VLIB_NODE_FN (snat_out2in_worker_handoff_node) (vlib_main_t * vm,
return nat44_worker_handoff_fn_inline (vm, node, frame, 0, 0);
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (snat_out2in_worker_handoff_node) = {
.name = "nat44-out2in-worker-handoff",
.vector_size = sizeof (u32),
@@ -343,7 +338,6 @@ VLIB_REGISTER_NODE (snat_out2in_worker_handoff_node) = {
.n_errors = ARRAY_LEN(nat44_handoff_error_strings),
.error_strings = nat44_handoff_error_strings,
};
-/* *INDENT-ON* */
/*
* fd.io coding-style-patch-verification: ON
diff --git a/src/plugins/nat/nat44-ed/nat44_ed_in2out.c b/src/plugins/nat/nat44-ed/nat44_ed_in2out.c
index ead5685c6f7..0065d7703b1 100644
--- a/src/plugins/nat/nat44-ed/nat44_ed_in2out.c
+++ b/src/plugins/nat/nat44-ed/nat44_ed_in2out.c
@@ -326,7 +326,7 @@ nat44_ed_external_sm_lookup (snat_main_t *sm, ip4_address_t match_addr,
if (dport)
{
/* Address only mapping doesn't change port */
- *dport = is_addr_only_static_mapping (m) ? match_port : m->local_port;
+ *dport = is_sm_addr_only (m->flags) ? match_port : m->local_port;
}
return 1;
}
diff --git a/src/plugins/nat/nat44-ed/nat44_ed_out2in.c b/src/plugins/nat/nat44-ed/nat44_ed_out2in.c
index 124b64e29f3..186d1d6c004 100644
--- a/src/plugins/nat/nat44-ed/nat44_ed_out2in.c
+++ b/src/plugins/nat/nat44-ed/nat44_ed_out2in.c
@@ -472,7 +472,7 @@ create_session_for_static_mapping_ed (
snat_address_t *filter = 0;
// if exact address is specified use this address
- if (is_exact_address (mapping))
+ if (is_sm_exact_address (mapping->flags))
{
snat_address_t *ap;
vec_foreach (ap, sm->twice_nat_addresses)
@@ -1407,7 +1407,6 @@ VLIB_NODE_FN (nat44_ed_out2in_node) (vlib_main_t * vm,
}
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (nat44_ed_out2in_node) = {
.name = "nat44-ed-out2in",
.vector_size = sizeof (u32),
@@ -1418,7 +1417,6 @@ VLIB_REGISTER_NODE (nat44_ed_out2in_node) = {
.error_strings = nat_out2in_ed_error_strings,
.runtime_data_bytes = sizeof (snat_runtime_t),
};
-/* *INDENT-ON* */
VLIB_NODE_FN (nat44_ed_out2in_slowpath_node) (vlib_main_t * vm,
vlib_node_runtime_t * node,
@@ -1427,7 +1425,6 @@ VLIB_NODE_FN (nat44_ed_out2in_slowpath_node) (vlib_main_t * vm,
return nat44_ed_out2in_slow_path_node_fn_inline (vm, node, frame);
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (nat44_ed_out2in_slowpath_node) = {
.name = "nat44-ed-out2in-slowpath",
.vector_size = sizeof (u32),
@@ -1438,7 +1435,6 @@ VLIB_REGISTER_NODE (nat44_ed_out2in_slowpath_node) = {
.error_strings = nat_out2in_ed_error_strings,
.runtime_data_bytes = sizeof (snat_runtime_t),
};
-/* *INDENT-ON* */
static u8 *
format_nat_pre_trace (u8 * s, va_list * args)
@@ -1458,7 +1454,6 @@ VLIB_NODE_FN (nat_pre_out2in_node) (vlib_main_t * vm,
NAT_NEXT_OUT2IN_ED_FAST_PATH);
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (nat_pre_out2in_node) = {
.name = "nat-pre-out2in",
.vector_size = sizeof (u32),
@@ -1467,7 +1462,6 @@ VLIB_REGISTER_NODE (nat_pre_out2in_node) = {
.type = VLIB_NODE_TYPE_INTERNAL,
.n_errors = 0,
};
-/* *INDENT-ON* */
/*
* fd.io coding-style-patch-verification: ON