.runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa",
"ip4-sv-reassembly-feature"),
};
+VNET_FEATURE_INIT (ip4_nat_handoff_classify, static) = {
+ .arc_name = "ip4-unicast",
+ .node_name = "nat44-ei-handoff-classify",
+ .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa",
+ "ip4-sv-reassembly-feature"),
+};
VNET_FEATURE_INIT (ip4_nat44_ei_in2out, static) = {
.arc_name = "ip4-unicast",
.node_name = "nat44-ei-in2out",
if (!c.sessions)
c.sessions = 10 * 1024;
+ if (!c.user_sessions)
+ c.user_sessions = c.sessions;
+
nm->rconfig = c;
if (!nm->frame_queue_nelts)
nm->max_users_per_thread = c.users;
nm->max_translations_per_thread = c.sessions;
- nm->max_translations_per_user =
- c.user_sessions ? c.user_sessions : nm->max_translations_per_thread;
+ nm->max_translations_per_user = c.user_sessions;
nm->inside_vrf_id = c.inside_vrf;
nm->inside_fib_index = fib_table_find_or_create_and_lock (
if (nm->num_workers > 1)
{
- del_feature_name = "nat44-handoff-classify";
+ del_feature_name = "nat44-ei-handoff-classify";
+ clib_warning (
+ "del_feature_name = nat44-ei-handoff-classify");
feature_name = !is_inside ?
"nat44-ei-in2out-worker-handoff" :
"nat44-ei-out2in-worker-handoff";
else
{
del_feature_name = "nat44-ei-classify";
+ clib_warning ("del_feature_name = nat44-ei-classify");
feature_name =
!is_inside ? "nat44-ei-in2out" : "nat44-ei-out2in";
}
ip4_sv_reass_enable_disable_with_refcnt (sw_if_index, 0);
if (rv)
return rv;
- vnet_feature_enable_disable ("ip4-unicast", del_feature_name,
- sw_if_index, 0, 0, 0);
- vnet_feature_enable_disable ("ip4-unicast", feature_name,
- sw_if_index, 1, 0, 0);
+ rv = vnet_feature_enable_disable (
+ "ip4-unicast", del_feature_name, sw_if_index, 0, 0, 0);
+ if (rv)
+ return rv;
+ rv = vnet_feature_enable_disable (
+ "ip4-unicast", feature_name, sw_if_index, 1, 0, 0);
+ if (rv)
+ return rv;
if (!is_inside)
{
- vnet_feature_enable_disable ("ip4-local",
- "nat44-ei-hairpinning",
- sw_if_index, 1, 0, 0);
+ rv = vnet_feature_enable_disable ("ip4-local",
+ "nat44-ei-hairpinning",
+ sw_if_index, 1, 0, 0);
+ if (rv)
+ return rv;
}
}
else
ip4_sv_reass_enable_disable_with_refcnt (sw_if_index, 0);
if (rv)
return rv;
- vnet_feature_enable_disable ("ip4-unicast", feature_name,
- sw_if_index, 0, 0, 0);
+ rv = vnet_feature_enable_disable (
+ "ip4-unicast", feature_name, sw_if_index, 0, 0, 0);
+ if (rv)
+ return rv;
pool_put (nm->interfaces, i);
if (is_inside)
{
- vnet_feature_enable_disable ("ip4-local",
- "nat44-ei-hairpinning",
- sw_if_index, 0, 0, 0);
+ rv = vnet_feature_enable_disable ("ip4-local",
+ "nat44-ei-hairpinning",
+ sw_if_index, 0, 0, 0);
+ if (rv)
+ return rv;
}
}
}
del_feature_name = !is_inside ?
"nat44-ei-in2out-worker-handoff" :
"nat44-ei-out2in-worker-handoff";
- feature_name = "nat44-handoff-classify";
+ feature_name = "nat44-ei-handoff-classify";
+ clib_warning ("feature_name = nat44-ei-handoff-classify");
}
else
{
del_feature_name =
!is_inside ? "nat44-ei-in2out" : "nat44-ei-out2in";
feature_name = "nat44-ei-classify";
+ clib_warning ("feature_name = nat44-ei-classify");
}
int rv =
ip4_sv_reass_enable_disable_with_refcnt (sw_if_index, 1);
if (rv)
return rv;
- vnet_feature_enable_disable ("ip4-unicast", del_feature_name,
- sw_if_index, 0, 0, 0);
- vnet_feature_enable_disable ("ip4-unicast", feature_name,
- sw_if_index, 1, 0, 0);
+ rv = vnet_feature_enable_disable (
+ "ip4-unicast", del_feature_name, sw_if_index, 0, 0, 0);
+ if (rv)
+ return rv;
+ rv = vnet_feature_enable_disable ("ip4-unicast", feature_name,
+ sw_if_index, 1, 0, 0);
+ if (rv)
+ return rv;
if (!is_inside)
{
- vnet_feature_enable_disable (
+ rv = vnet_feature_enable_disable (
"ip4-local", "nat44-ei-hairpinning", sw_if_index, 0, 0, 0);
+ if (rv)
+ return rv;
}
goto set_flags;
}
i->flags = 0;
nat_validate_interface_counters (nm, sw_if_index);
- vnet_feature_enable_disable ("ip4-unicast", feature_name, sw_if_index, 1, 0,
- 0);
+ int rv = vnet_feature_enable_disable ("ip4-unicast", feature_name,
+ sw_if_index, 1, 0, 0);
+ if (rv)
+ return rv;
- int rv = ip4_sv_reass_enable_disable_with_refcnt (sw_if_index, 1);
+ rv = ip4_sv_reass_enable_disable_with_refcnt (sw_if_index, 1);
if (rv)
return rv;
if (is_inside && !nm->out2in_dpo)
{
- vnet_feature_enable_disable ("ip4-local", "nat44-ei-hairpinning",
- sw_if_index, 1, 0, 0);
+ rv = vnet_feature_enable_disable ("ip4-local", "nat44-ei-hairpinning",
+ sw_if_index, 1, 0, 0);
+ if (rv)
+ return rv;
}
set_flags:
ip4_sv_reass_output_enable_disable_with_refcnt (sw_if_index, !is_del);
if (rv)
return rv;
- vnet_feature_enable_disable ("ip4-unicast", "nat44-ei-hairpin-dst",
- sw_if_index, !is_del, 0, 0);
- vnet_feature_enable_disable ("ip4-output", "nat44-ei-hairpin-src",
- sw_if_index, !is_del, 0, 0);
+ rv = vnet_feature_enable_disable ("ip4-unicast", "nat44-ei-hairpin-dst",
+ sw_if_index, !is_del, 0, 0);
+ if (rv)
+ return rv;
+ rv = vnet_feature_enable_disable ("ip4-output", "nat44-ei-hairpin-src",
+ sw_if_index, !is_del, 0, 0);
+ if (rv)
+ return rv;
goto fq;
}
ip4_sv_reass_output_enable_disable_with_refcnt (sw_if_index, !is_del);
if (rv)
return rv;
- vnet_feature_enable_disable ("ip4-unicast",
- "nat44-ei-out2in-worker-handoff",
- sw_if_index, !is_del, 0, 0);
- vnet_feature_enable_disable ("ip4-output",
- "nat44-ei-in2out-output-worker-handoff",
- sw_if_index, !is_del, 0, 0);
+ rv = vnet_feature_enable_disable ("ip4-unicast",
+ "nat44-ei-out2in-worker-handoff",
+ sw_if_index, !is_del, 0, 0);
+ if (rv)
+ return rv;
+ rv = vnet_feature_enable_disable (
+ "ip4-output", "nat44-ei-in2out-output-worker-handoff", sw_if_index,
+ !is_del, 0, 0);
+ if (rv)
+ return rv;
}
else
{
ip4_sv_reass_output_enable_disable_with_refcnt (sw_if_index, !is_del);
if (rv)
return rv;
- vnet_feature_enable_disable ("ip4-unicast", "nat44-ei-out2in",
- sw_if_index, !is_del, 0, 0);
- vnet_feature_enable_disable ("ip4-output", "nat44-ei-in2out-output",
- sw_if_index, !is_del, 0, 0);
+ rv = vnet_feature_enable_disable ("ip4-unicast", "nat44-ei-out2in",
+ sw_if_index, !is_del, 0, 0);
+ if (rv)
+ return rv;
+ rv = vnet_feature_enable_disable ("ip4-output", "nat44-ei-in2out-output",
+ sw_if_index, !is_del, 0, 0);
+ if (rv)
+ return rv;
}
fq:
nat44_ei_plugin_disable ()
{
nat44_ei_main_t *nm = &nat44_ei_main;
- nat44_ei_interface_t *i, *vec;
+ nat44_ei_interface_t *i, *pool;
int error = 0;
// first unregister all nodes from interfaces
- vec = vec_dup (nm->interfaces);
- vec_foreach (i, vec)
+ pool = pool_dup (nm->interfaces);
+ pool_foreach (i, pool)
{
if (nat44_ei_interface_is_inside (i))
error = nat44_ei_interface_add_del (i->sw_if_index, 1, 1);
i->sw_if_index);
}
}
- vec_free (vec);
- nm->interfaces = 0;
+ pool_free (pool);
+ pool_free (nm->interfaces);
- vec = vec_dup (nm->output_feature_interfaces);
- vec_foreach (i, vec)
+ pool = pool_dup (nm->output_feature_interfaces);
+ pool_foreach (i, pool)
{
if (nat44_ei_interface_is_inside (i))
error =
i->sw_if_index);
}
}
- vec_free (vec);
- nm->output_feature_interfaces = 0;
+ pool_free (pool);
+ pool_free (nm->output_feature_interfaces);
nat_ha_disable ();
nat44_ei_db_free ();
nm->enabled = 0;
clib_memset (&nm->rconfig, 0, sizeof (nm->rconfig));
- return error;
+ return 0;
}
int
/* log NAT event */
nat_ipfix_logging_nat44_ses_delete (
thread_index, s->in2out.addr.as_u32, s->out2in.addr.as_u32,
- s->nat_proto, s->in2out.port, s->out2in.port, s->in2out.fib_index);
+ nat_proto_to_ip_proto (s->nat_proto), s->in2out.port, s->out2in.port,
+ s->in2out.fib_index);
nat_ha_sdel (&s->out2in.addr, s->out2in.port, &s->ext_host_addr,
s->ext_host_port, s->nat_proto, s->out2in.fib_index,
nat_ipfix_logging_nat44_ses_delete (
thread_index, s->in2out.addr.as_u32, s->out2in.addr.as_u32,
- s->nat_proto, s->in2out.port, s->out2in.port, s->in2out.fib_index);
+ nat_proto_to_ip_proto (s->nat_proto), s->in2out.port, s->out2in.port,
+ s->in2out.fib_index);
nat_ha_sdel (&s->out2in.addr, s->out2in.port, &s->ext_host_addr,
s->ext_host_port, s->nat_proto, s->out2in.fib_index,
{
nat44_ei_main_per_thread_data_t *tnm;
clib_bihash_kv_8_8_t kv, value;
- ip4_header_t ip;
u32 fib_index = fib_table_find (FIB_PROTOCOL_IP4, vrf_id);
nat44_ei_session_t *s;
clib_bihash_8_8_t *t;
- ip.dst_address.as_u32 = ip.src_address.as_u32 = addr->as_u32;
- if (nm->num_workers > 1)
- tnm =
- vec_elt_at_index (nm->per_thread_data,
- nat44_ei_get_in2out_worker_index (&ip, fib_index, 0));
- else
- tnm = vec_elt_at_index (nm->per_thread_data, nm->num_workers);
-
init_nat_k (&kv, *addr, port, fib_index, proto);
t = is_in ? &nm->in2out : &nm->out2in;
if (!clib_bihash_search_8_8 (t, &kv, &value))
{
- if (pool_is_free_index (tnm->sessions, value.value))
+ // this is called from API/CLI, so the world is stopped here
+ // it's safe to manipulate arbitrary per-thread data
+ u32 thread_index = nat_value_get_thread_index (&value);
+ tnm = vec_elt_at_index (nm->per_thread_data, thread_index);
+ u32 session_index = nat_value_get_session_index (&value);
+ if (pool_is_free_index (tnm->sessions, session_index))
return VNET_API_ERROR_UNSPECIFIED;
- s = pool_elt_at_index (tnm->sessions, value.value);
+ s = pool_elt_at_index (tnm->sessions, session_index);
nat44_ei_free_session_data_v2 (nm, s, tnm - nm->per_thread_data, 0);
nat44_ei_delete_session (nm, s, tnm - nm->per_thread_data);
return 0;
{
clib_bihash_kv_8_8_t *v = va_arg (*args, clib_bihash_kv_8_8_t *);
- s =
- format (s, "%U session-index %llu", format_nat44_ei_key, v->key, v->value);
+ s = format (s, "%U thread-index %llu session-index %llu",
+ format_nat44_ei_key, v->key, nat_value_get_thread_index (v),
+ nat_value_get_session_index (v));
return s;
}
"i4", rv);
}
-VLIB_NODE_FN (nat44_ei_classify_node)
-(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
+static_always_inline uword
+nat44_ei_classify_inline_fn (vlib_main_t *vm, vlib_node_runtime_t *node,
+ vlib_frame_t *frame)
{
u32 n_left_from, *from, *to_next;
nat44_ei_classify_next_t next_index;
return frame->n_vectors;
}
+VLIB_NODE_FN (nat44_ei_classify_node)
+(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
+{
+ return nat44_ei_classify_inline_fn (vm, node, frame);
+}
+
VLIB_REGISTER_NODE (nat44_ei_classify_node) = {
.name = "nat44-ei-classify",
.vector_size = sizeof (u32),
},
};
+VLIB_NODE_FN (nat44_ei_handoff_classify_node)
+(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
+{
+ return nat44_ei_classify_inline_fn (vm, node, frame);
+}
+
+VLIB_REGISTER_NODE (nat44_ei_handoff_classify_node) = {
+ .name = "nat44-ei-handoff-classify",
+ .vector_size = sizeof (u32),
+ .format_trace = format_nat44_ei_classify_trace,
+ .type = VLIB_NODE_TYPE_INTERNAL,
+ .n_errors = ARRAY_LEN(nat44_ei_classify_error_strings),
+ .error_strings = nat44_ei_classify_error_strings,
+ .n_next_nodes = NAT44_EI_CLASSIFY_N_NEXT,
+ .next_nodes = {
+ [NAT44_EI_CLASSIFY_NEXT_IN2OUT] = "nat44-ei-in2out-worker-handoff",
+ [NAT44_EI_CLASSIFY_NEXT_OUT2IN] = "nat44-ei-out2in-worker-handoff",
+ [NAT44_EI_CLASSIFY_NEXT_DROP] = "error-drop",
+ },
+};
+
/*
* fd.io coding-style-patch-verification: ON
*