summaryrefslogtreecommitdiffstats
path: root/src/plugins/nat/nat.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/nat/nat.c')
-rwxr-xr-xsrc/plugins/nat/nat.c184
1 files changed, 94 insertions, 90 deletions
diff --git a/src/plugins/nat/nat.c b/src/plugins/nat/nat.c
index d85fb267bed..c1a18394aff 100755
--- a/src/plugins/nat/nat.c
+++ b/src/plugins/nat/nat.c
@@ -26,13 +26,13 @@
#include <nat/nat64.h>
#include <nat/nat66.h>
#include <nat/dslite.h>
-#include <nat/nat_reass.h>
#include <nat/nat_inlines.h>
#include <nat/nat_affinity.h>
#include <nat/nat_syslog.h>
#include <nat/nat_ha.h>
#include <vnet/fib/fib_table.h>
#include <vnet/fib/ip4_fib.h>
+#include <vnet/ip/reass/ip4_sv_reass.h>
#include <vpp/app/version.h>
@@ -46,13 +46,15 @@ fib_source_t nat_fib_src_low;
VNET_FEATURE_INIT (nat_pre_in2out, static) = {
.arc_name = "ip4-unicast",
.node_name = "nat-pre-in2out",
- .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa"),
+ .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa",
+ "ip4-sv-reassembly-feature"),
};
VNET_FEATURE_INIT (nat_pre_out2in, static) = {
.arc_name = "ip4-unicast",
.node_name = "nat-pre-out2in",
.runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa",
- "ip4-dhcp-client-detect"),
+ "ip4-dhcp-client-detect",
+ "ip4-sv-reassembly-feature"),
};
VNET_FEATURE_INIT (snat_in2out_worker_handoff, static) = {
.arc_name = "ip4-unicast",
@@ -68,103 +70,103 @@ VNET_FEATURE_INIT (snat_out2in_worker_handoff, static) = {
VNET_FEATURE_INIT (ip4_snat_in2out, static) = {
.arc_name = "ip4-unicast",
.node_name = "nat44-in2out",
- .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa"),
+ .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa","ip4-sv-reassembly-feature"),
};
VNET_FEATURE_INIT (ip4_snat_out2in, static) = {
.arc_name = "ip4-unicast",
.node_name = "nat44-out2in",
- .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa",
+ .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa","ip4-sv-reassembly-feature",
"ip4-dhcp-client-detect"),
};
VNET_FEATURE_INIT (ip4_nat_classify, static) = {
.arc_name = "ip4-unicast",
.node_name = "nat44-classify",
- .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa"),
+ .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa","ip4-sv-reassembly-feature"),
};
VNET_FEATURE_INIT (ip4_snat_det_in2out, static) = {
.arc_name = "ip4-unicast",
.node_name = "nat44-det-in2out",
- .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa"),
+ .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa","ip4-sv-reassembly-feature"),
};
VNET_FEATURE_INIT (ip4_snat_det_out2in, static) = {
.arc_name = "ip4-unicast",
.node_name = "nat44-det-out2in",
- .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa",
+ .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa","ip4-sv-reassembly-feature",
"ip4-dhcp-client-detect"),
};
VNET_FEATURE_INIT (ip4_nat_det_classify, static) = {
.arc_name = "ip4-unicast",
.node_name = "nat44-det-classify",
- .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa"),
+ .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa","ip4-sv-reassembly-feature"),
};
VNET_FEATURE_INIT (ip4_nat44_ed_in2out, static) = {
.arc_name = "ip4-unicast",
.node_name = "nat44-ed-in2out",
- .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa"),
+ .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa","ip4-sv-reassembly-feature"),
};
VNET_FEATURE_INIT (ip4_nat44_ed_out2in, static) = {
.arc_name = "ip4-unicast",
.node_name = "nat44-ed-out2in",
- .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa",
+ .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa","ip4-sv-reassembly-feature",
"ip4-dhcp-client-detect"),
};
VNET_FEATURE_INIT (ip4_nat44_ed_classify, static) = {
.arc_name = "ip4-unicast",
.node_name = "nat44-ed-classify",
- .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa"),
+ .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-handoff-classify",
- .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa"),
+ .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa","ip4-sv-reassembly-feature"),
};
VNET_FEATURE_INIT (ip4_snat_in2out_fast, static) = {
.arc_name = "ip4-unicast",
.node_name = "nat44-in2out-fast",
- .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa"),
+ .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa","ip4-sv-reassembly-feature"),
};
VNET_FEATURE_INIT (ip4_snat_out2in_fast, static) = {
.arc_name = "ip4-unicast",
.node_name = "nat44-out2in-fast",
- .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa",
+ .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa","ip4-sv-reassembly-feature",
"ip4-dhcp-client-detect"),
};
VNET_FEATURE_INIT (ip4_snat_hairpin_dst, static) = {
.arc_name = "ip4-unicast",
.node_name = "nat44-hairpin-dst",
- .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa"),
+ .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa","ip4-sv-reassembly-feature"),
};
VNET_FEATURE_INIT (ip4_nat44_ed_hairpin_dst, static) = {
.arc_name = "ip4-unicast",
.node_name = "nat44-ed-hairpin-dst",
- .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa"),
+ .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa","ip4-sv-reassembly-feature"),
};
/* Hook up output features */
VNET_FEATURE_INIT (ip4_snat_in2out_output, static) = {
.arc_name = "ip4-output",
.node_name = "nat44-in2out-output",
- .runs_after = VNET_FEATURES ("acl-plugin-out-ip4-fa"),
+ .runs_after = VNET_FEATURES ("acl-plugin-out-ip4-fa","ip4-sv-reassembly-output-feature"),
};
VNET_FEATURE_INIT (ip4_snat_in2out_output_worker_handoff, static) = {
.arc_name = "ip4-output",
.node_name = "nat44-in2out-output-worker-handoff",
- .runs_after = VNET_FEATURES ("acl-plugin-out-ip4-fa"),
+ .runs_after = VNET_FEATURES ("acl-plugin-out-ip4-fa","ip4-sv-reassembly-output-feature"),
};
VNET_FEATURE_INIT (ip4_snat_hairpin_src, static) = {
.arc_name = "ip4-output",
.node_name = "nat44-hairpin-src",
- .runs_after = VNET_FEATURES ("acl-plugin-out-ip4-fa"),
+ .runs_after = VNET_FEATURES ("acl-plugin-out-ip4-fa","ip4-sv-reassembly-output-feature"),
};
VNET_FEATURE_INIT (ip4_nat44_ed_in2out_output, static) = {
.arc_name = "ip4-output",
.node_name = "nat44-ed-in2out-output",
- .runs_after = VNET_FEATURES ("acl-plugin-out-ip4-fa"),
+ .runs_after = VNET_FEATURES ("acl-plugin-out-ip4-fa","ip4-sv-reassembly-output-feature"),
};
VNET_FEATURE_INIT (ip4_nat44_ed_hairpin_src, static) = {
.arc_name = "ip4-output",
.node_name = "nat44-ed-hairpin-src",
- .runs_after = VNET_FEATURES ("acl-plugin-out-ip4-fa"),
+ .runs_after = VNET_FEATURES ("acl-plugin-out-ip4-fa","ip4-sv-reassembly-output-feature"),
};
/* Hook up ip4-local features */
@@ -1869,6 +1871,9 @@ feature_set:
feature_name = !is_inside ? "nat44-in2out" : "nat44-out2in";
}
+ int rv = 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,
@@ -1887,6 +1892,9 @@ feature_set:
}
else
{
+ int rv = 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);
pool_put (sm->interfaces, i);
@@ -1934,6 +1942,9 @@ feature_set:
feature_name = "nat44-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,
@@ -1964,6 +1975,10 @@ feature_set:
vnet_feature_enable_disable ("ip4-unicast", feature_name, sw_if_index, 1, 0,
0);
+ int rv = ip4_sv_reass_enable_disable_with_refcnt (sw_if_index, 1);
+ if (rv)
+ return rv;
+
if (is_inside && !sm->out2in_dpo)
{
if (sm->endpoint_dependent)
@@ -2063,6 +2078,15 @@ feature_set:
{
if (sm->endpoint_dependent)
{
+ int rv =
+ ip4_sv_reass_enable_disable_with_refcnt (sw_if_index, !is_del);
+ if (rv)
+ return rv;
+ rv =
+ ip4_sv_reass_output_enable_disable_with_refcnt (sw_if_index,
+ !is_del);
+ if (rv)
+ return rv;
vnet_feature_enable_disable ("ip4-unicast", "nat44-ed-hairpin-dst",
sw_if_index, !is_del, 0, 0);
vnet_feature_enable_disable ("ip4-output", "nat44-ed-hairpin-src",
@@ -2070,6 +2094,15 @@ feature_set:
}
else
{
+ int rv =
+ ip4_sv_reass_enable_disable_with_refcnt (sw_if_index, !is_del);
+ if (rv)
+ return rv;
+ rv =
+ ip4_sv_reass_output_enable_disable_with_refcnt (sw_if_index,
+ !is_del);
+ if (rv)
+ return rv;
vnet_feature_enable_disable ("ip4-unicast", "nat44-hairpin-dst",
sw_if_index, !is_del, 0, 0);
vnet_feature_enable_disable ("ip4-output", "nat44-hairpin-src",
@@ -2080,6 +2113,13 @@ feature_set:
if (sm->num_workers > 1)
{
+ int rv = ip4_sv_reass_enable_disable_with_refcnt (sw_if_index, !is_del);
+ if (rv)
+ return rv;
+ rv =
+ ip4_sv_reass_output_enable_disable_with_refcnt (sw_if_index, !is_del);
+ if (rv)
+ return rv;
vnet_feature_enable_disable ("ip4-unicast",
"nat44-out2in-worker-handoff",
sw_if_index, !is_del, 0, 0);
@@ -2091,6 +2131,15 @@ feature_set:
{
if (sm->endpoint_dependent)
{
+ int rv =
+ ip4_sv_reass_enable_disable_with_refcnt (sw_if_index, !is_del);
+ if (rv)
+ return rv;
+ rv =
+ ip4_sv_reass_output_enable_disable_with_refcnt (sw_if_index,
+ !is_del);
+ if (rv)
+ return rv;
vnet_feature_enable_disable ("ip4-unicast", "nat-pre-out2in",
sw_if_index, !is_del, 0, 0);
vnet_feature_enable_disable ("ip4-output", "nat44-ed-in2out-output",
@@ -2098,6 +2147,15 @@ feature_set:
}
else
{
+ int rv =
+ ip4_sv_reass_enable_disable_with_refcnt (sw_if_index, !is_del);
+ if (rv)
+ return rv;
+ rv =
+ ip4_sv_reass_output_enable_disable_with_refcnt (sw_if_index,
+ !is_del);
+ if (rv)
+ return rv;
vnet_feature_enable_disable ("ip4-unicast", "nat44-out2in",
sw_if_index, !is_del, 0, 0);
vnet_feature_enable_disable ("ip4-output", "nat44-in2out-output",
@@ -2352,29 +2410,21 @@ snat_init (vlib_main_t * vm)
sm->in2out_slowpath_node_index = node->index;
node = vlib_get_node_by_name (vm, (u8 *) "nat44-in2out-output-slowpath");
sm->in2out_slowpath_output_node_index = node->index;
- node = vlib_get_node_by_name (vm, (u8 *) "nat44-in2out-reass");
- sm->in2out_reass_node_index = node->index;
node = vlib_get_node_by_name (vm, (u8 *) "nat44-ed-in2out");
sm->ed_in2out_node_index = node->index;
node = vlib_get_node_by_name (vm, (u8 *) "nat44-ed-in2out-slowpath");
sm->ed_in2out_slowpath_node_index = node->index;
- node = vlib_get_node_by_name (vm, (u8 *) "nat44-ed-in2out-reass");
- sm->ed_in2out_reass_node_index = node->index;
node = vlib_get_node_by_name (vm, (u8 *) "nat44-out2in");
sm->out2in_node_index = node->index;
node = vlib_get_node_by_name (vm, (u8 *) "nat44-out2in-fast");
sm->out2in_fast_node_index = node->index;
- node = vlib_get_node_by_name (vm, (u8 *) "nat44-out2in-reass");
- sm->out2in_reass_node_index = node->index;
node = vlib_get_node_by_name (vm, (u8 *) "nat44-ed-out2in");
sm->ed_out2in_node_index = node->index;
node = vlib_get_node_by_name (vm, (u8 *) "nat44-ed-out2in-slowpath");
sm->ed_out2in_slowpath_node_index = node->index;
- node = vlib_get_node_by_name (vm, (u8 *) "nat44-ed-out2in-reass");
- sm->ed_out2in_reass_node_index = node->index;
node = vlib_get_node_by_name (vm, (u8 *) "nat44-det-in2out");
sm->det_in2out_node_index = node->index;
@@ -2471,8 +2521,7 @@ snat_init (vlib_main_t * vm)
FIB_SOURCE_PRIORITY_LOW,
FIB_SOURCE_BH_SIMPLE);
- /* Init virtual fragmenentation reassembly */
- return nat_reass_init (vm);
+ return error;
}
VLIB_INIT_FUNCTION (snat_init);
@@ -3012,8 +3061,8 @@ snat_get_worker_in2out_cb (ip4_header_t * ip0, u32 rx_fib_index0,
}
static u32
-snat_get_worker_out2in_cb (ip4_header_t * ip0, u32 rx_fib_index0,
- u8 is_output)
+snat_get_worker_out2in_cb (vlib_buffer_t * b, ip4_header_t * ip0,
+ u32 rx_fib_index0, u8 is_output)
{
snat_main_t *sm = &snat_main;
udp_header_t *udp;
@@ -3044,52 +3093,6 @@ snat_get_worker_out2in_cb (ip4_header_t * ip0, u32 rx_fib_index0,
udp = ip4_next_header (ip0);
port = udp->dst_port;
- if (PREDICT_FALSE (ip4_is_fragment (ip0)))
- {
- if (PREDICT_FALSE (nat_reass_is_drop_frag (0)))
- return vlib_get_thread_index ();
-
- nat_reass_ip4_t *reass;
- reass = nat_ip4_reass_find (ip0->src_address, ip0->dst_address,
- ip0->fragment_id, ip0->protocol);
-
- if (reass && (reass->thread_index != (u32) ~ 0))
- return reass->thread_index;
-
- if (ip4_is_first_fragment (ip0))
- {
- reass =
- nat_ip4_reass_create (ip0->src_address, ip0->dst_address,
- ip0->fragment_id, ip0->protocol);
- if (!reass)
- goto no_reass;
-
- if (PREDICT_FALSE (pool_elts (sm->static_mappings)))
- {
- m_key.addr = ip0->dst_address;
- m_key.port = clib_net_to_host_u16 (port);
- m_key.protocol = proto;
- m_key.fib_index = rx_fib_index0;
- kv.key = m_key.as_u64;
- if (!clib_bihash_search_8_8
- (&sm->static_mapping_by_external, &kv, &value))
- {
- m = pool_elt_at_index (sm->static_mappings, value.value);
- reass->thread_index = m->workers[0];
- return reass->thread_index;
- }
- }
- reass->thread_index = sm->first_worker_index;
- reass->thread_index +=
- sm->workers[(clib_net_to_host_u16 (port) - 1024) /
- sm->port_per_thread];
- return reass->thread_index;
- }
- else
- return vlib_get_thread_index ();
- }
-
-no_reass:
/* unknown protocol */
if (PREDICT_FALSE (proto == ~0))
{
@@ -3101,10 +3104,12 @@ no_reass:
{
icmp46_header_t *icmp = (icmp46_header_t *) udp;
icmp_echo_header_t *echo = (icmp_echo_header_t *) (icmp + 1);
- if (!icmp_is_error_message (icmp))
- port = echo->identifier;
+ if (!icmp_type_is_error_message
+ (vnet_buffer (b)->ip.reass.icmp_type_or_tcp_flags))
+ port = vnet_buffer (b)->ip.reass.l4_src_port;
else
{
+ /* if error message, then it's not fragmented and we can access it */
ip4_header_t *inner_ip = (ip4_header_t *) (echo + 1);
proto = ip_proto_to_snat_proto (inner_ip->protocol);
void *l4_header = ip4_next_header (inner_ip);
@@ -3252,8 +3257,8 @@ nat44_ed_get_worker_in2out_cb (ip4_header_t * ip, u32 rx_fib_index,
}
static u32
-nat44_ed_get_worker_out2in_cb (ip4_header_t * ip, u32 rx_fib_index,
- u8 is_output)
+nat44_ed_get_worker_out2in_cb (vlib_buffer_t * b, ip4_header_t * ip,
+ u32 rx_fib_index, u8 is_output)
{
snat_main_t *sm = &snat_main;
clib_bihash_kv_8_8_t kv, value;
@@ -3295,7 +3300,7 @@ nat44_ed_get_worker_out2in_cb (ip4_header_t * ip, u32 rx_fib_index,
{
nat_ed_ses_key_t key;
- if (!get_icmp_o2i_ed_key (ip, &key))
+ if (!get_icmp_o2i_ed_key (b, ip, &key))
{
key.fib_index = rx_fib_index;
@@ -3349,10 +3354,12 @@ nat44_ed_get_worker_out2in_cb (ip4_header_t * ip, u32 rx_fib_index,
{
icmp46_header_t *icmp = (icmp46_header_t *) udp;
icmp_echo_header_t *echo = (icmp_echo_header_t *) (icmp + 1);
- if (!icmp_is_error_message (icmp))
- port = echo->identifier;
+ if (!icmp_type_is_error_message
+ (vnet_buffer (b)->ip.reass.icmp_type_or_tcp_flags))
+ port = vnet_buffer (b)->ip.reass.l4_src_port;
else
{
+ /* if error message, then it's not fragmented and we can access it */
ip4_header_t *inner_ip = (ip4_header_t *) (echo + 1);
proto = ip_proto_to_snat_proto (inner_ip->protocol);
void *l4_header = ip4_next_header (inner_ip);
@@ -4359,11 +4366,8 @@ VLIB_REGISTER_NODE (nat_default_node) = {
[NAT_NEXT_IN2OUT_ED_FAST_PATH] = "nat44-ed-in2out",
[NAT_NEXT_IN2OUT_ED_SLOW_PATH] = "nat44-ed-in2out-slowpath",
[NAT_NEXT_IN2OUT_ED_OUTPUT_SLOW_PATH] = "nat44-ed-in2out-output-slowpath",
- [NAT_NEXT_IN2OUT_ED_REASS] = "nat44-ed-in2out-reass",
- [NAT_NEXT_IN2OUT_ED_OUTPUT_REASS] = "nat44-ed-in2out-reass-output",
[NAT_NEXT_OUT2IN_ED_FAST_PATH] = "nat44-ed-out2in",
[NAT_NEXT_OUT2IN_ED_SLOW_PATH] = "nat44-ed-out2in-slowpath",
- [NAT_NEXT_OUT2IN_ED_REASS] = "nat44-ed-out2in-reass",
},
};
/* *INDENT-ON* */