#include <nat/nat_ipfix_logging.h>
#include <nat/nat_det.h>
#include <nat/nat64.h>
+#include <nat/nat66.h>
#include <nat/dslite.h>
#include <nat/nat_reass.h>
#include <vnet/fib/fib_table.h>
VNET_FEATURE_INIT (ip4_snat_in2out, static) = {
.arc_name = "ip4-unicast",
.node_name = "nat44-in2out",
- .runs_before = VNET_FEATURES ("nat44-out2in"),
+ .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa"),
};
VNET_FEATURE_INIT (ip4_snat_out2in, static) = {
.arc_name = "ip4-unicast",
.node_name = "nat44-out2in",
- .runs_before = VNET_FEATURES ("ip4-lookup"),
+ .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa"),
};
VNET_FEATURE_INIT (ip4_nat_classify, static) = {
.arc_name = "ip4-unicast",
.node_name = "nat44-classify",
- .runs_before = VNET_FEATURES ("ip4-lookup"),
+ .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa"),
};
VNET_FEATURE_INIT (ip4_snat_det_in2out, static) = {
.arc_name = "ip4-unicast",
.node_name = "nat44-det-in2out",
- .runs_before = VNET_FEATURES ("nat44-det-out2in"),
+ .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa"),
};
VNET_FEATURE_INIT (ip4_snat_det_out2in, static) = {
.arc_name = "ip4-unicast",
.node_name = "nat44-det-out2in",
- .runs_before = VNET_FEATURES ("ip4-lookup"),
+ .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa"),
};
VNET_FEATURE_INIT (ip4_nat_det_classify, static) = {
.arc_name = "ip4-unicast",
.node_name = "nat44-det-classify",
- .runs_before = VNET_FEATURES ("ip4-lookup"),
+ .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa"),
};
VNET_FEATURE_INIT (ip4_snat_in2out_worker_handoff, static) = {
.arc_name = "ip4-unicast",
.node_name = "nat44-in2out-worker-handoff",
- .runs_before = VNET_FEATURES ("nat44-out2in-worker-handoff"),
+ .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa"),
};
VNET_FEATURE_INIT (ip4_snat_out2in_worker_handoff, static) = {
.arc_name = "ip4-unicast",
.node_name = "nat44-out2in-worker-handoff",
- .runs_before = VNET_FEATURES ("ip4-lookup"),
+ .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa"),
};
VNET_FEATURE_INIT (ip4_nat_handoff_classify, static) = {
.arc_name = "ip4-unicast",
.node_name = "nat44-handoff-classify",
- .runs_before = VNET_FEATURES ("ip4-lookup"),
+ .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa"),
};
VNET_FEATURE_INIT (ip4_snat_in2out_fast, static) = {
.arc_name = "ip4-unicast",
.node_name = "nat44-in2out-fast",
- .runs_before = VNET_FEATURES ("nat44-out2in-fast"),
+ .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa"),
};
VNET_FEATURE_INIT (ip4_snat_out2in_fast, static) = {
.arc_name = "ip4-unicast",
.node_name = "nat44-out2in-fast",
- .runs_before = VNET_FEATURES ("ip4-lookup"),
+ .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa"),
};
VNET_FEATURE_INIT (ip4_snat_hairpin_dst, static) = {
.arc_name = "ip4-unicast",
.node_name = "nat44-hairpin-dst",
- .runs_before = VNET_FEATURES ("ip4-lookup"),
+ .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa"),
};
/* Hook up output features */
VNET_FEATURE_INIT (ip4_snat_in2out_output, static) = {
.arc_name = "ip4-output",
.node_name = "nat44-in2out-output",
- .runs_before = VNET_FEATURES ("interface-output"),
+ .runs_after = VNET_FEATURES ("acl-plugin-out-ip4-fa"),
};
VNET_FEATURE_INIT (ip4_snat_in2out_output_worker_handoff, static) = {
.arc_name = "ip4-output",
.node_name = "nat44-in2out-output-worker-handoff",
- .runs_before = VNET_FEATURES ("interface-output"),
+ .runs_after = VNET_FEATURES ("acl-plugin-out-ip4-fa"),
};
VNET_FEATURE_INIT (ip4_snat_hairpin_src, static) = {
.arc_name = "ip4-output",
.node_name = "nat44-hairpin-src",
- .runs_before = VNET_FEATURES ("interface-output"),
+ .runs_after = VNET_FEATURES ("acl-plugin-out-ip4-fa"),
};
/* Hook up ip4-local features */
snat_interface_t *interface;
int i;
snat_main_per_thread_data_t *tsm;
+ snat_user_key_t u_key;
+ snat_user_t *u;
+ dlist_elt_t * head, * elt;
+ u32 elt_index, head_index;
+ u32 ses_index;
+ u64 user_index;
+ snat_session_t * s;
/* If the external address is a specific interface address */
if (sw_if_index != ~0)
}
}
/* External address must be allocated */
- if (!a)
+ if (!a && (l_addr.as_u32 != e_addr.as_u32))
return VNET_API_ERROR_NO_SUCH_ENTRY;
}
clib_warning ("out2in key add failed");
}
+ /* Delete dynamic sessions matching local address (+ local port) */
+ if (!(sm->static_mapping_only))
+ {
+ u_key.addr = m->local_addr;
+ u_key.fib_index = m->fib_index;
+ kv.key = u_key.as_u64;
+ if (!clib_bihash_search_8_8 (&tsm->user_hash, &kv, &value))
+ {
+ user_index = value.value;
+ u = pool_elt_at_index (tsm->users, user_index);
+ if (u->nsessions)
+ {
+ head_index = u->sessions_per_user_list_head_index;
+ head = pool_elt_at_index (tsm->list_pool, head_index);
+ elt_index = head->next;
+ elt = pool_elt_at_index (tsm->list_pool, elt_index);
+ ses_index = elt->value;
+ while (ses_index != ~0)
+ {
+ s = pool_elt_at_index (tsm->sessions, ses_index);
+ elt = pool_elt_at_index (tsm->list_pool, elt->next);
+ ses_index = elt->value;
+
+ if (snat_is_session_static (s))
+ continue;
+
+ if (!addr_only)
+ {
+ if ((s->out2in.addr.as_u32 != e_addr.as_u32) &&
+ (clib_net_to_host_u16 (s->out2in.port) != e_port))
+ continue;
+ }
+
+ nat_free_session_data (sm, s, tsm - sm->per_thread_data);
+ clib_dlist_remove (tsm->list_pool, s->per_user_index);
+ pool_put_index (tsm->list_pool, s->per_user_index);
+ pool_put (tsm->sessions, s);
+ u->nsessions--;
+
+ if (!addr_only)
+ break;
+ }
+ }
+ }
+ }
}
else
{
if (!(sm->static_mapping_only) ||
(sm->static_mapping_only && sm->static_mapping_connection_tracking))
{
- snat_user_key_t u_key;
- snat_user_t *u;
- dlist_elt_t * head, * elt;
- u32 elt_index, head_index;
- u32 ses_index;
- u64 user_index;
- snat_session_t * s;
-
u_key.addr = m->local_addr;
u_key.fib_index = m->fib_index;
kv.key = u_key.as_u64;
if (sm->out2in_dpo && !is_inside)
return VNET_API_ERROR_UNSUPPORTED;
+ pool_foreach (i, sm->output_feature_interfaces,
+ ({
+ if (i->sw_if_index == sw_if_index)
+ return VNET_API_ERROR_VALUE_EXIST;
+ }));
+
if (sm->static_mapping_only && !(sm->static_mapping_connection_tracking))
feature_name = is_inside ? "nat44-in2out-fast" : "nat44-out2in-fast";
else
(sm->static_mapping_only && !(sm->static_mapping_connection_tracking)))
return VNET_API_ERROR_UNSUPPORTED;
+ pool_foreach (i, sm->interfaces,
+ ({
+ if (i->sw_if_index == sw_if_index)
+ return VNET_API_ERROR_VALUE_EXIST;
+ }));
+
if (is_inside)
{
vnet_feature_enable_disable ("ip4-unicast", "nat44-hairpin-dst",
dslite_init(vm);
+ nat66_init();
+
/* Init virtual fragmenentation reassembly */
return nat_reass_init(vm);
}
if (m->addr_only)
s = format (s, "local %U external %U vrf %d",
format_ip4_address, &m->l_addr,
- format_vnet_sw_interface_name, vnm,
- vnet_get_sw_interface (vnm, m->sw_if_index),
+ format_vnet_sw_if_index_name, vnm, m->sw_if_index,
m->vrf_id);
else
s = format (s, "%U local %U:%d external %U:%d vrf %d",
format_snat_protocol, m->proto,
format_ip4_address, &m->l_addr, m->l_port,
- format_vnet_sw_interface_name, vnm,
- vnet_get_sw_interface (vnm, m->sw_if_index), m->e_port,
- m->vrf_id);
+ format_vnet_sw_if_index_name, vnm, m->sw_if_index,
+ m->e_port, m->vrf_id);
return s;
}