aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/plugins/nat/CMakeLists.txt59
-rw-r--r--src/plugins/nat/FEATURE.yaml15
-rw-r--r--src/plugins/nat/det44/det44.api2
-rw-r--r--src/plugins/nat/dslite/dslite_cli.c19
-rw-r--r--src/plugins/nat/lib/lib.c59
-rw-r--r--src/plugins/nat/lib/lib.h47
-rw-r--r--src/plugins/nat/lib/log.h214
-rw-r--r--src/plugins/nat/lib/nat_inlines.h14
-rw-r--r--src/plugins/nat/lib/nat_types.api (renamed from src/plugins/nat/nat_types.api)0
-rw-r--r--src/plugins/nat/nat44-ed/nat44_ed.api (renamed from src/plugins/nat/nat44.api)74
-rw-r--r--src/plugins/nat/nat44-ed/nat44_ed.c (renamed from src/plugins/nat/nat.c)1080
-rw-r--r--src/plugins/nat/nat44-ed/nat44_ed.h (renamed from src/plugins/nat/nat.h)395
-rw-r--r--src/plugins/nat/nat44-ed/nat44_ed_affinity.c (renamed from src/plugins/nat/nat_affinity.c)20
-rw-r--r--src/plugins/nat/nat44-ed/nat44_ed_affinity.h (renamed from src/plugins/nat/nat_affinity.h)6
-rw-r--r--src/plugins/nat/nat44-ed/nat44_ed_api.c (renamed from src/plugins/nat/nat44_api.c)533
-rw-r--r--src/plugins/nat/nat44-ed/nat44_ed_classify.c (renamed from src/plugins/nat/nat44_classify.c)152
-rw-r--r--src/plugins/nat/nat44-ed/nat44_ed_cli.c (renamed from src/plugins/nat/nat44_cli.c)608
-rw-r--r--src/plugins/nat/nat44-ed/nat44_ed_format.c (renamed from src/plugins/nat/nat_format.c)47
-rw-r--r--src/plugins/nat/nat44-ed/nat44_ed_handoff.c (renamed from src/plugins/nat/nat44_handoff.c)5
-rw-r--r--src/plugins/nat/nat44-ed/nat44_ed_in2out.c (renamed from src/plugins/nat/in2out_ed.c)158
-rw-r--r--src/plugins/nat/nat44-ed/nat44_ed_inlines.h869
-rw-r--r--src/plugins/nat/nat44-ed/nat44_ed_out2in.c (renamed from src/plugins/nat/out2in_ed.c)95
-rw-r--r--src/plugins/nat/nat44-ei/nat44_ei.api862
-rw-r--r--src/plugins/nat/nat44-ei/nat44_ei.c2429
-rw-r--r--src/plugins/nat/nat44-ei/nat44_ei.h549
-rw-r--r--src/plugins/nat/nat44-ei/nat44_ei_api.c1199
-rw-r--r--src/plugins/nat/nat44-ei/nat44_ei_cli.c2025
-rw-r--r--src/plugins/nat/nat44-ei/nat44_ei_dpo.c (renamed from src/plugins/nat/nat_dpo.c)14
-rw-r--r--src/plugins/nat/nat44-ei/nat44_ei_dpo.h (renamed from src/plugins/nat/nat_dpo.h)4
-rw-r--r--src/plugins/nat/nat44-ei/nat44_ei_ha.c165
-rw-r--r--src/plugins/nat/nat44-ei/nat44_ei_ha.h2
-rw-r--r--src/plugins/nat/nat44-ei/nat44_ei_hairpinning.c (renamed from src/plugins/nat/nat44_hairpinning.c)546
-rw-r--r--src/plugins/nat/nat44-ei/nat44_ei_hairpinning.h (renamed from src/plugins/nat/nat44_hairpinning.h)42
-rw-r--r--src/plugins/nat/nat44-ei/nat44_ei_handoff.c326
-rw-r--r--src/plugins/nat/nat44-ei/nat44_ei_in2out.c1151
-rw-r--r--src/plugins/nat/nat44-ei/nat44_ei_inlines.h178
-rw-r--r--src/plugins/nat/nat44-ei/nat44_ei_out2in.c607
-rw-r--r--src/plugins/nat/nat44/ed_inlines.h361
-rw-r--r--src/plugins/nat/nat44/inlines.h44
-rw-r--r--src/plugins/nat/nat64/nat64.api2
-rw-r--r--src/plugins/nat/nat66/nat66.api2
-rw-r--r--src/plugins/nat/nat_inlines.h686
-rw-r--r--src/plugins/nat/test/test_nat44_ed.py94
-rw-r--r--src/plugins/nat/test/test_nat44_ei.py782
44 files changed, 10760 insertions, 5781 deletions
diff --git a/src/plugins/nat/CMakeLists.txt b/src/plugins/nat/CMakeLists.txt
index 8fefadf0dd1..623c92ace69 100644
--- a/src/plugins/nat/CMakeLists.txt
+++ b/src/plugins/nat/CMakeLists.txt
@@ -18,43 +18,60 @@ add_vpp_library(nat
lib/ipfix_logging.c
lib/nat_syslog.c
lib/alloc.c
+ lib/lib.c
INSTALL_HEADERS
lib/ipfix_logging.h
lib/nat_syslog.h
lib/alloc.h
+ lib/lib.h
)
add_vpp_plugin(nat
SOURCES
- nat.c
- nat44_api.c
- in2out_ed.c
- out2in_ed.c
- nat_dpo.c
- nat44_cli.c
- nat44_handoff.c
- nat44_hairpinning.c
- nat44_classify.c
- nat_affinity.c
- nat_format.c
+ nat44-ed/nat44_ed.c
+ nat44-ed/nat44_ed_api.c
+ nat44-ed/nat44_ed_in2out.c
+ nat44-ed/nat44_ed_out2in.c
+ nat44-ed/nat44_ed_cli.c
+ nat44-ed/nat44_ed_format.c
+ nat44-ed/nat44_ed_affinity.c
+ nat44-ed/nat44_ed_handoff.c
+ nat44-ed/nat44_ed_classify.c
+
+ MULTIARCH_SOURCES
+ nat44-ed/nat44_ed_in2out.c
+ nat44-ed/nat44_ed_out2in.c
+ nat44-ed/nat44_ed_handoff.c
+ nat44-ed/nat44_ed_classify.c
+
+ API_FILES
+ nat44-ed/nat44_ed.api
+ lib/nat_types.api
+
+ LINK_LIBRARIES nat
+)
+
+add_vpp_plugin(nat44_ei
+ SOURCES
nat44-ei/nat44_ei.c
nat44-ei/nat44_ei_ha.c
+ nat44-ei/nat44_ei_cli.c
+ nat44-ei/nat44_ei_api.c
+ nat44-ei/nat44_ei_dpo.c
nat44-ei/nat44_ei_in2out.c
nat44-ei/nat44_ei_out2in.c
+ nat44-ei/nat44_ei_handoff.c
+ nat44-ei/nat44_ei_hairpinning.c
MULTIARCH_SOURCES
- in2out_ed.c
- out2in_ed.c
- nat44_classify.c
- nat44_hairpinning.c
- nat44_handoff.c
nat44-ei/nat44_ei_in2out.c
nat44-ei/nat44_ei_out2in.c
+ nat44-ei/nat44_ei_hairpinning.c
API_FILES
- nat44.api
- nat_types.api
+ nat44-ei/nat44_ei.api
+ lib/nat_types.api
LINK_LIBRARIES nat
)
@@ -96,7 +113,7 @@ add_vpp_plugin(nat66
API_FILES
nat66/nat66.api
- nat_types.api
+ lib/nat_types.api
LINK_LIBRARIES nat
)
@@ -115,7 +132,7 @@ add_vpp_plugin(det44
API_FILES
det44/det44.api
- nat_types.api
+ lib/nat_types.api
LINK_LIBRARIES nat
)
@@ -135,7 +152,7 @@ add_vpp_plugin(nat64
API_FILES
nat64/nat64.api
- nat_types.api
+ lib/nat_types.api
LINK_LIBRARIES nat
)
diff --git a/src/plugins/nat/FEATURE.yaml b/src/plugins/nat/FEATURE.yaml
index 175d2c8b1dd..bbb8586390e 100644
--- a/src/plugins/nat/FEATURE.yaml
+++ b/src/plugins/nat/FEATURE.yaml
@@ -4,7 +4,17 @@ maintainer:
- Ole Troan <ot@cisco.com>
- Filip Varga <fivarga@cisco.com>
features:
- - NAT44:
+ - NAT44-EI - IPv4 Endpoint Independent NAT
+ - 1:1 NAT
+ - 1:1 NAT with ports
+ - VRF awareness
+ - Multiple inside interfaces
+ - Hairpinning
+ - IPFIX
+ - Syslog
+ - TCP MSS clamping
+ - Local bypass (DHCP)
+ - NAT44-ED - IPv4 Endpoint Dependent NAT
- 1:1 NAT
- 1:1 NAT with ports
- VRF awareness
@@ -12,13 +22,12 @@ features:
- Hairpinning
- IPFIX
- Syslog
- - Endpoint dependent NAT
- TCP MSS clamping
- Local bypass (DHCP)
- DET44 - deterministic NAT (CGN)
- NAT64
- NAT66
- - DS-lite
+ - DSLITE
- 464XLAT
description: "The Network Address Translation (NAT) plugin offers a multiple address
translation functions. These can be used in a raft of different
diff --git a/src/plugins/nat/det44/det44.api b/src/plugins/nat/det44/det44.api
index 9b71b9c8c6d..7b6aef70883 100644
--- a/src/plugins/nat/det44/det44.api
+++ b/src/plugins/nat/det44/det44.api
@@ -16,7 +16,7 @@
option version = "1.0.0";
import "vnet/ip/ip_types.api";
import "vnet/interface_types.api";
-import "plugins/nat/nat_types.api";
+import "plugins/nat/lib/nat_types.api";
/**
* @file det44.api
diff --git a/src/plugins/nat/dslite/dslite_cli.c b/src/plugins/nat/dslite/dslite_cli.c
index 25fcd01d523..0537957930c 100644
--- a/src/plugins/nat/dslite/dslite_cli.c
+++ b/src/plugins/nat/dslite/dslite_cli.c
@@ -204,25 +204,6 @@ dslite_show_b4_ip6_addr_command_fn (vlib_main_t * vm,
}
static u8 *
-format_nat_protocol (u8 * s, va_list * args)
-{
- u32 i = va_arg (*args, u32);
- u8 *t = 0;
-
- switch (i)
- {
-#define _(N, j, n, str) case NAT_PROTOCOL_##N: t = (u8 *) str; break;
- foreach_nat_protocol
-#undef _
- default:
- s = format (s, "unknown");
- return s;
- }
- s = format (s, "%s", t);
- return s;
-}
-
-static u8 *
format_dslite_session (u8 * s, va_list * args)
{
dslite_session_t *session = va_arg (*args, dslite_session_t *);
diff --git a/src/plugins/nat/lib/lib.c b/src/plugins/nat/lib/lib.c
new file mode 100644
index 00000000000..d2def2cc480
--- /dev/null
+++ b/src/plugins/nat/lib/lib.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2020 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <nat/lib/lib.h>
+
+uword
+unformat_nat_protocol (unformat_input_t *input, va_list *args)
+{
+ u32 *r = va_arg (*args, u32 *);
+
+ if (0)
+ ;
+#define _(N, i, n, s) else if (unformat (input, s)) *r = NAT_PROTOCOL_##N;
+ foreach_nat_protocol
+#undef _
+ else return 0;
+ return 1;
+}
+
+u8 *
+format_nat_protocol (u8 *s, va_list *args)
+{
+ u32 i = va_arg (*args, u32);
+ u8 *t = 0;
+
+ switch (i)
+ {
+#define _(N, j, n, str) \
+ case NAT_PROTOCOL_##N: \
+ t = (u8 *) str; \
+ break;
+ foreach_nat_protocol
+#undef _
+ default : s = format (s, "unknown");
+ return s;
+ }
+ s = format (s, "%s", t);
+ return s;
+}
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/src/plugins/nat/lib/lib.h b/src/plugins/nat/lib/lib.h
index 04bad5c74f7..b0b5229b337 100644
--- a/src/plugins/nat/lib/lib.h
+++ b/src/plugins/nat/lib/lib.h
@@ -95,7 +95,52 @@ nat_reset_timeouts (nat_timeouts_t * timeouts)
timeouts->icmp = NAT_ICMP_TIMEOUT;
}
-// TODO: move common formating definitions here
+static_always_inline u32
+nat_session_get_timeout (nat_timeouts_t *timeouts, nat_protocol_t proto,
+ u8 state)
+{
+ switch (proto)
+ {
+ case NAT_PROTOCOL_ICMP:
+ return timeouts->icmp;
+ case NAT_PROTOCOL_UDP:
+ return timeouts->udp;
+ case NAT_PROTOCOL_TCP:
+ {
+ if (state)
+ return timeouts->tcp.transitory;
+ else
+ return timeouts->tcp.established;
+ }
+ default:
+ return timeouts->udp;
+ }
+ return 0;
+}
+
+static_always_inline u32
+nat_calc_bihash_buckets (u32 n_elts)
+{
+ n_elts = n_elts / 2.5;
+ u64 lower_pow2 = 1;
+ while (lower_pow2 * 2 < n_elts)
+ {
+ lower_pow2 = 2 * lower_pow2;
+ }
+ u64 upper_pow2 = 2 * lower_pow2;
+ if ((upper_pow2 - n_elts) < (n_elts - lower_pow2))
+ {
+ if (upper_pow2 <= UINT32_MAX)
+ {
+ return upper_pow2;
+ }
+ }
+ return lower_pow2;
+}
+
+u8 *format_nat_protocol (u8 *s, va_list *args);
+
+uword unformat_nat_protocol (unformat_input_t *input, va_list *args);
#endif /* included_nat_lib_h__ */
/*
diff --git a/src/plugins/nat/lib/log.h b/src/plugins/nat/lib/log.h
new file mode 100644
index 00000000000..26bd93f2589
--- /dev/null
+++ b/src/plugins/nat/lib/log.h
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2020 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @file
+ * @brief NAT port/address allocation lib
+ */
+#ifndef included_nat_log_h__
+#define included_nat_log_h__
+
+#include <vppinfra/elog.h>
+
+#define foreach_nat_log_level \
+ _ (0x00, LOG_NONE) \
+ _ (0x01, LOG_ERROR) \
+ _ (0x02, LOG_WARNING) \
+ _ (0x03, LOG_NOTICE) \
+ _ (0x04, LOG_INFO) \
+ _ (0x05, LOG_DEBUG)
+
+typedef enum nat_log_level_t_
+{
+#define _(n, f) NAT_##f = n,
+ foreach_nat_log_level
+#undef _
+} nat_log_level_t;
+
+#define nat_elog(_pm, _level, _str) \
+ do \
+ { \
+ if (PREDICT_FALSE (_pm->log_level >= _level)) \
+ { \
+ ELOG_TYPE_DECLARE (e) = { \
+ .format = "nat-msg " _str, \
+ .format_args = "", \
+ }; \
+ ELOG_DATA (&vlib_global_main.elog_main, e); \
+ } \
+ } \
+ while (0);
+
+#define nat_elog_addr(_pm, _level, _str, _addr) \
+ do \
+ { \
+ if (PREDICT_FALSE (_pm->log_level >= _level)) \
+ { \
+ ELOG_TYPE_DECLARE (e) = { \
+ .format = "nat-msg " _str " %d.%d.%d.%d", \
+ .format_args = "i1i1i1i1", \
+ }; \
+ CLIB_PACKED (struct { \
+ u8 oct1; \
+ u8 oct2; \
+ u8 oct3; \
+ u8 oct4; \
+ }) * \
+ ed; \
+ ed = ELOG_DATA (&vlib_global_main.elog_main, e); \
+ ed->oct4 = _addr >> 24; \
+ ed->oct3 = _addr >> 16; \
+ ed->oct2 = _addr >> 8; \
+ ed->oct1 = _addr; \
+ } \
+ } \
+ while (0);
+
+#define nat_elog_debug_handoff(_pm, _str, _tid, _fib, _src, _dst) \
+ do \
+ { \
+ if (PREDICT_FALSE (_pm->log_level >= NAT_LOG_DEBUG)) \
+ { \
+ ELOG_TYPE_DECLARE (e) = { \
+ .format = "nat-msg " _str " ip src: %d.%d.%d.%d dst: %d.%d.%d.%d" \
+ " tid from: %d to: %d fib: %d", \
+ .format_args = "i1i1i1i1i1i1i1i1i4i4i4", \
+ }; \
+ CLIB_PACKED (struct { \
+ u8 src_oct1; \
+ u8 src_oct2; \
+ u8 src_oct3; \
+ u8 src_oct4; \
+ u8 dst_oct1; \
+ u8 dst_oct2; \
+ u8 dst_oct3; \
+ u8 dst_oct4; \
+ u32 ftid; \
+ u32 ttid; \
+ u32 fib; \
+ }) * \
+ ed; \
+ ed = ELOG_DATA (&vlib_global_main.elog_main, e); \
+ ed->src_oct1 = _src >> 24; \
+ ed->src_oct2 = _src >> 16; \
+ ed->src_oct3 = _src >> 8; \
+ ed->src_oct4 = _src; \
+ ed->dst_oct1 = _dst >> 24; \
+ ed->dst_oct2 = _dst >> 16; \
+ ed->dst_oct3 = _dst >> 8; \
+ ed->dst_oct4 = _dst; \
+ ed->ftid = vlib_get_thread_index (); \
+ ed->ttid = _tid; \
+ ed->fib = _fib; \
+ } \
+ } \
+ while (0);
+
+#define nat_elog_debug_handoff_v2(_pm, _str, _prt, _fib, _src, _dst) \
+ do \
+ { \
+ if (PREDICT_FALSE (_pm->log_level >= NAT_LOG_DEBUG)) \
+ { \
+ ELOG_TYPE_DECLARE (e) = { \
+ .format = \
+ "nat-msg " _str " ip_src:%d.%d.%d.%d ip_dst:%d.%d.%d.%d" \
+ " tid:%d prt:%d fib:%d", \
+ .format_args = "i1i1i1i1i1i1i1i1i4i4i4", \
+ }; \
+ CLIB_PACKED (struct { \
+ u8 src_oct1; \
+ u8 src_oct2; \
+ u8 src_oct3; \
+ u8 src_oct4; \
+ u8 dst_oct1; \
+ u8 dst_oct2; \
+ u8 dst_oct3; \
+ u8 dst_oct4; \
+ u32 tid; \
+ u32 prt; \
+ u32 fib; \
+ }) * \
+ ed; \
+ ed = ELOG_DATA (&vlib_global_main.elog_main, e); \
+ ed->src_oct1 = _src >> 24; \
+ ed->src_oct2 = _src >> 16; \
+ ed->src_oct3 = _src >> 8; \
+ ed->src_oct4 = _src; \
+ ed->dst_oct1 = _dst >> 24; \
+ ed->dst_oct2 = _dst >> 16; \
+ ed->dst_oct3 = _dst >> 8; \
+ ed->dst_oct4 = _dst; \
+ ed->tid = vlib_get_thread_index (); \
+ ed->prt = _prt; \
+ ed->fib = _fib; \
+ } \
+ } \
+ while (0);
+
+#define nat_elog_X1(_pm, _level, _fmt, _arg, _val1) \
+ do \
+ { \
+ if (PREDICT_FALSE (_pm->log_level >= _level)) \
+ { \
+ ELOG_TYPE_DECLARE (e) = { \
+ .format = "nat-msg " _fmt, \
+ .format_args = _arg, \
+ }; \
+ CLIB_PACKED (struct { typeof (_val1) val1; }) * ed; \
+ ed = ELOG_DATA (&vlib_global_main.elog_main, e); \
+ ed->val1 = _val1; \
+ } \
+ } \
+ while (0);
+
+#define nat_elog_notice(_pm, nat_elog_str) \
+ nat_elog (_pm, NAT_LOG_INFO, "[notice] " nat_elog_str)
+#define nat_elog_warn(_pm, nat_elog_str) \
+ nat_elog (_pm, NAT_LOG_WARNING, "[warning] " nat_elog_str)
+#define nat_elog_err(_pm, nat_elog_str) \
+ nat_elog (_pm, NAT_LOG_ERROR, "[error] " nat_elog_str)
+#define nat_elog_debug(_pm, nat_elog_str) \
+ nat_elog (_pm, NAT_LOG_DEBUG, "[debug] " nat_elog_str)
+#define nat_elog_info(_pm, nat_elog_str) \
+ nat_elog (_pm, NAT_LOG_INFO, "[info] " nat_elog_str)
+
+#define nat_elog_notice_X1(_pm, nat_elog_fmt_str, nat_elog_fmt_arg, \
+ nat_elog_val1) \
+ nat_elog_X1 (_pm, NAT_LOG_NOTICE, "[notice] " nat_elog_fmt_str, \
+ nat_elog_fmt_arg, nat_elog_val1)
+#define nat_elog_warn_X1(_pm, nat_elog_fmt_str, nat_elog_fmt_arg, \
+ nat_elog_val1) \
+ nat_elog_X1 (_pm, NAT_LOG_WARNING, "[warning] " nat_elog_fmt_str, \
+ nat_elog_fmt_arg, nat_elog_val1)
+#define nat_elog_err_X1(_pm, nat_elog_fmt_str, nat_elog_fmt_arg, \
+ nat_elog_val1) \
+ nat_elog_X1 (_pm, NAT_LOG_ERROR, "[error] " nat_elog_fmt_str, \
+ nat_elog_fmt_arg, nat_elog_val1)
+#define nat_elog_debug_X1(_pm, nat_elog_fmt_str, nat_elog_fmt_arg, \
+ nat_elog_val1) \
+ nat_elog_X1 (_pm, NAT_LOG_DEBUG, "[debug] " nat_elog_fmt_str, \
+ nat_elog_fmt_arg, nat_elog_val1)
+#define nat_elog_info_X1(_pm, nat_elog_fmt_str, nat_elog_fmt_arg, \
+ nat_elog_val1) \
+ nat_elog_X1 (_pm, NAT_LOG_INFO, "[info] " nat_elog_fmt_str, \
+ nat_elog_fmt_arg, nat_elog_val1)
+
+#endif /* included_nat_lib_h__ */
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/src/plugins/nat/lib/nat_inlines.h b/src/plugins/nat/lib/nat_inlines.h
index c75b8043cc1..0bd7993ac04 100644
--- a/src/plugins/nat/lib/nat_inlines.h
+++ b/src/plugins/nat/lib/nat_inlines.h
@@ -77,6 +77,20 @@ mss_clamping (u16 mss_clamping, tcp_header_t * tcp, ip_csum_t * sum)
}
}
+static_always_inline u16
+nat_random_port (u32 *random_seed, u16 min, u16 max)
+{
+ u32 rwide;
+ u16 r;
+
+ rwide = random_u32 (random_seed);
+ r = rwide & 0xFFFF;
+ if (r >= min && r <= max)
+ return r;
+
+ return min + (rwide % (max - min + 1));
+}
+
#endif /* __included_lib_nat_inlines_h__ */
/*
diff --git a/src/plugins/nat/nat_types.api b/src/plugins/nat/lib/nat_types.api
index ad4ee9faba0..ad4ee9faba0 100644
--- a/src/plugins/nat/nat_types.api
+++ b/src/plugins/nat/lib/nat_types.api
diff --git a/src/plugins/nat/nat44.api b/src/plugins/nat/nat44-ed/nat44_ed.api
index f7fe7fd0fac..6a2d44a6b9c 100644
--- a/src/plugins/nat/nat44.api
+++ b/src/plugins/nat/nat44-ed/nat44_ed.api
@@ -16,7 +16,7 @@
option version = "5.2.0";
import "vnet/ip/ip_types.api";
import "vnet/interface_types.api";
-import "plugins/nat/nat_types.api";
+import "plugins/nat/lib/nat_types.api";
/**
* @file nat44.api
@@ -390,42 +390,6 @@ define nat_get_timeouts_reply {
u32 icmp;
};
-/** \brief Set NAT handoff frame queue options
- @param client_index - opaque cookie to identify the sender
- @param context - sender context, to match reply w/ request
- @param frame_queue_nelts - number of worker handoff frame queue elements
-*/
-autoreply define nat_set_fq_options {
- option in_progress;
- u32 client_index;
- u32 context;
- u32 frame_queue_nelts;
-};
-
-/** \brief Show NAT handoff frame queue options
- @param client_index - opaque cookie to identify the sender
- @param context - sender context, to match reply w/ request
-*/
-define nat_show_fq_options
-{
- option in_progress;
- u32 client_index;
- u32 context;
-};
-
-/** \brief Show NAT handoff frame queue options reply
- @param context - sender context, to match reply w/ request
- @param retval - return code for the request
- @param frame_queue_nelts - number of worker handoff frame queue elements
-*/
-define nat_show_fq_options_reply
-{
- option in_progress;
- u32 context;
- i32 retval;
- u32 frame_queue_nelts;
-};
-
/** \brief Set address and port assignment algorithm
@param client_index - opaque cookie to identify the sender
@param context - sender context, to match reply w/ request
@@ -1212,3 +1176,39 @@ define nat44_forwarding_is_enabled_reply {
u32 context;
bool enabled;
};
+
+/** \brief Set NAT handoff frame queue options
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param frame_queue_nelts - number of worker handoff frame queue elements
+*/
+autoreply define nat44_ed_set_fq_options {
+ option in_progress;
+ u32 client_index;
+ u32 context;
+ u32 frame_queue_nelts;
+};
+
+/** \brief Show NAT handoff frame queue options
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+*/
+define nat44_ed_show_fq_options
+{
+ option in_progress;
+ u32 client_index;
+ u32 context;
+};
+
+/** \brief Show NAT handoff frame queue options reply
+ @param context - sender context, to match reply w/ request
+ @param retval - return code for the request
+ @param frame_queue_nelts - number of worker handoff frame queue elements
+*/
+define nat44_ed_show_fq_options_reply
+{
+ option in_progress;
+ u32 context;
+ i32 retval;
+ u32 frame_queue_nelts;
+};
diff --git a/src/plugins/nat/nat.c b/src/plugins/nat/nat44-ed/nat44_ed.c
index 85d4775c8fe..d9d35fc55bc 100644
--- a/src/plugins/nat/nat.c
+++ b/src/plugins/nat/nat44-ed/nat44_ed.c
@@ -15,32 +15,32 @@
* limitations under the License.
*/
+#include <vpp/app/version.h>
+
#include <vnet/vnet.h>
#include <vnet/ip/ip.h>
#include <vnet/ip/ip4.h>
-#include <vnet/plugin/plugin.h>
-#include <nat/nat.h>
-#include <nat/nat_dpo.h>
-#include <nat/lib/ipfix_logging.h>
-#include <nat/lib/nat_syslog.h>
-#include <nat/nat_inlines.h>
-#include <nat/nat44/inlines.h>
-#include <nat/nat_affinity.h>
+#include <vnet/ip/ip_table.h>
+#include <vnet/ip/reass/ip4_sv_reass.h>
#include <vnet/fib/fib_table.h>
#include <vnet/fib/ip4_fib.h>
-#include <vnet/ip/reass/ip4_sv_reass.h>
+#include <vnet/plugin/plugin.h>
#include <vppinfra/bihash_16_8.h>
-#include <nat/nat44/ed_inlines.h>
-#include <vnet/ip/ip_table.h>
-#include <nat/nat44-ei/nat44_ei_ha.h>
-#include <nat/nat44-ei/nat44_ei.h>
-
-#include <vpp/app/version.h>
+#include <nat/lib/log.h>
+#include <nat/lib/nat_syslog.h>
#include <nat/lib/nat_inlines.h>
+#include <nat/lib/ipfix_logging.h>
+
+#include <nat/nat44-ed/nat44_ed.h>
+#include <nat/nat44-ed/nat44_ed_affinity.h>
+#include <nat/nat44-ed/nat44_ed_inlines.h>
snat_main_t snat_main;
+static_always_inline void nat_validate_interface_counters (snat_main_t *sm,
+ u32 sw_if_index);
+
#define skip_if_disabled() \
do \
{ \
@@ -111,11 +111,6 @@ VNET_FEATURE_INIT (ip4_snat_out2in, static) = {
.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","ip4-sv-reassembly-feature"),
-};
VNET_FEATURE_INIT (ip4_nat44_ed_in2out, static) = {
.arc_name = "ip4-unicast",
.node_name = "nat44-ed-in2out",
@@ -148,11 +143,6 @@ VNET_FEATURE_INIT (ip4_snat_out2in_fast, static) = {
.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","ip4-sv-reassembly-feature"),
-};
/* Hook up output features */
VNET_FEATURE_INIT (ip4_snat_in2out_output, static) = {
@@ -165,11 +155,6 @@ VNET_FEATURE_INIT (ip4_snat_in2out_output_worker_handoff, static) = {
.node_name = "nat44-in2out-output-worker-handoff",
.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","ip4-sv-reassembly-output-feature"),
-};
VNET_FEATURE_INIT (nat_pre_in2out_output, static) = {
.arc_name = "ip4-output",
.node_name = "nat-pre-in2out-output",
@@ -183,22 +168,13 @@ VNET_FEATURE_INIT (ip4_nat44_ed_in2out_output, static) = {
.runs_before = VNET_FEATURES ("acl-plugin-out-ip4-fa"),
};
-/* Hook up ip4-local features */
-VNET_FEATURE_INIT (ip4_nat_hairpinning, static) =
-{
- .arc_name = "ip4-local",
- .node_name = "nat44-hairpinning",
- .runs_before = VNET_FEATURES("ip4-local-end-of-arc"),
-};
-
VLIB_PLUGIN_REGISTER () = {
.version = VPP_BUILD_VER,
.description = "Network Address Translation (NAT)",
};
/* *INDENT-ON* */
-static void nat44_ed_db_init (u32 translations, u32 translation_buckets,
- u32 user_buckets);
+static void nat44_ed_db_init (u32 translations, u32 translation_buckets);
static void nat44_ed_db_free ();
@@ -236,20 +212,6 @@ format_static_mapping_kvp (u8 * s, va_list * args)
}
u8 *
-format_user_kvp (u8 * s, va_list * args)
-{
- clib_bihash_kv_8_8_t *v = va_arg (*args, clib_bihash_kv_8_8_t *);
- snat_user_key_t k;
-
- k.as_u64 = v->key;
-
- s = format (s, "%U fib %d user-index %llu", format_ip4_address, &k.addr,
- k.fib_index, v->value);
-
- return s;
-}
-
-u8 *
format_ed_session_kvp (u8 * s, va_list * args)
{
clib_bihash_kv_16_8_t *v = va_arg (*args, clib_bihash_kv_16_8_t *);
@@ -275,54 +237,29 @@ void
nat_free_session_data (snat_main_t * sm, snat_session_t * s, u32 thread_index,
u8 is_ha)
{
- clib_bihash_kv_8_8_t kv;
-
- if (is_ed_session (s))
- {
per_vrf_sessions_unregister_session (s, thread_index);
if (nat_ed_ses_i2o_flow_hash_add_del (sm, thread_index, s, 0))
- nat_elog_warn ("flow hash del failed");
+ nat_elog_warn (sm, "flow hash del failed");
if (nat_ed_ses_o2i_flow_hash_add_del (sm, thread_index, s, 0))
- nat_elog_warn ("flow hash del failed");
- }
+ nat_elog_warn (sm, "flow hash del failed");
if (is_fwd_bypass_session (s))
{
return;
}
- /* session lookup tables */
- if (is_ed_session (s))
- {
if (is_affinity_sessions (s))
nat_affinity_unlock (s->ext_host_addr, s->out2in.addr,
s->nat_proto, s->out2in.port);
if (!is_ha)
- nat_syslog_nat44_sdel (s->user_index, s->in2out.fib_index,
- &s->in2out.addr, s->in2out.port,
- &s->ext_host_nat_addr, s->ext_host_nat_port,
- &s->out2in.addr, s->out2in.port,
- &s->ext_host_addr, s->ext_host_port,
- s->nat_proto, is_twice_nat_session (s));
- }
- else
- {
- init_nat_i2o_k (&kv, s);
- if (clib_bihash_add_del_8_8 (&sm->in2out, &kv, 0))
- nat_elog_warn ("in2out key del failed");
- init_nat_o2i_k (&kv, s);
- if (clib_bihash_add_del_8_8 (&sm->out2in, &kv, 0))
- nat_elog_warn ("out2in key del failed");
-
- if (!is_ha)
- nat_syslog_nat44_apmdel (s->user_index, s->in2out.fib_index,
- &s->in2out.addr, s->in2out.port,
- &s->out2in.addr, s->out2in.port,
- s->nat_proto);
- }
+ nat_syslog_nat44_sdel (
+ 0, s->in2out.fib_index, &s->in2out.addr, s->in2out.port,
+ &s->ext_host_nat_addr, s->ext_host_nat_port, &s->out2in.addr,
+ s->out2in.port, &s->ext_host_addr, s->ext_host_port, s->nat_proto,
+ is_twice_nat_session (s));
if (snat_is_unk_proto_session (s))
return;
@@ -337,10 +274,6 @@ nat_free_session_data (snat_main_t * sm, snat_session_t * s, u32 thread_index,
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,
- thread_index);
}
/* Twice NAT address and port for external host */
@@ -360,143 +293,6 @@ nat_free_session_data (snat_main_t * sm, snat_session_t * s, u32 thread_index,
s->nat_proto);
}
-snat_user_t *
-nat_user_get_or_create (snat_main_t * sm, ip4_address_t * addr, u32 fib_index,
- u32 thread_index)
-{
- snat_user_t *u = 0;
- snat_user_key_t user_key;
- clib_bihash_kv_8_8_t kv, value;
- snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
- dlist_elt_t *per_user_list_head_elt;
-
- user_key.addr.as_u32 = addr->as_u32;
- user_key.fib_index = fib_index;
- kv.key = user_key.as_u64;
-
- /* Ever heard of the "user" = src ip4 address before? */
- if (clib_bihash_search_8_8 (&tsm->user_hash, &kv, &value))
- {
- if (pool_elts (tsm->users) >= sm->max_users_per_thread)
- {
- vlib_increment_simple_counter (&sm->user_limit_reached,
- thread_index, 0, 1);
- nat_elog_warn ("maximum user limit reached");
- return NULL;
- }
- /* no, make a new one */
- pool_get (tsm->users, u);
- clib_memset (u, 0, sizeof (*u));
-
- u->addr.as_u32 = addr->as_u32;
- u->fib_index = fib_index;
-
- pool_get (tsm->list_pool, per_user_list_head_elt);
-
- u->sessions_per_user_list_head_index = per_user_list_head_elt -
- tsm->list_pool;
-
- clib_dlist_init (tsm->list_pool, u->sessions_per_user_list_head_index);
-
- kv.value = u - tsm->users;
-
- /* add user */
- if (clib_bihash_add_del_8_8 (&tsm->user_hash, &kv, 1))
- {
- nat_elog_warn ("user_hash key add failed");
- nat44_delete_user_with_no_session (sm, u, thread_index);
- return NULL;
- }
-
- vlib_set_simple_counter (&sm->total_users, thread_index, 0,
- pool_elts (tsm->users));
- }
- else
- {
- u = pool_elt_at_index (tsm->users, value.value);
- }
-
- return u;
-}
-
-// only NAT EI
-snat_session_t *
-nat_session_alloc_or_recycle (snat_main_t * sm, snat_user_t * u,
- u32 thread_index, f64 now)
-{
- snat_session_t *s;
- snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
- u32 oldest_per_user_translation_list_index, session_index;
- dlist_elt_t *oldest_per_user_translation_list_elt;
- dlist_elt_t *per_user_translation_list_elt;
-
- /* Over quota? Recycle the least recently used translation */
- if ((u->nsessions + u->nstaticsessions) >= sm->max_translations_per_user)
- {
- oldest_per_user_translation_list_index =
- clib_dlist_remove_head (tsm->list_pool,
- u->sessions_per_user_list_head_index);
-
- ASSERT (oldest_per_user_translation_list_index != ~0);
-
- /* Add it back to the end of the LRU list */
- clib_dlist_addtail (tsm->list_pool,
- u->sessions_per_user_list_head_index,
- oldest_per_user_translation_list_index);
- /* Get the list element */
- oldest_per_user_translation_list_elt =
- pool_elt_at_index (tsm->list_pool,
- oldest_per_user_translation_list_index);
-
- /* Get the session index from the list element */
- session_index = oldest_per_user_translation_list_elt->value;
-
- /* Get the session */
- s = pool_elt_at_index (tsm->sessions, session_index);
-
- // TODO: ONLY EI version should be called
- nat_free_session_data (sm, s, thread_index, 0);
- if (snat_is_session_static (s))
- u->nstaticsessions--;
- else
- u->nsessions--;
- s->flags = 0;
- s->total_bytes = 0;
- s->total_pkts = 0;
- s->state = 0;
- s->ext_host_addr.as_u32 = 0;
- s->ext_host_port = 0;
- s->ext_host_nat_addr.as_u32 = 0;
- s->ext_host_nat_port = 0;
- }
- else
- {
- pool_get (tsm->sessions, s);
- clib_memset (s, 0, sizeof (*s));
-
- /* Create list elts */
- pool_get (tsm->list_pool, per_user_translation_list_elt);
- clib_dlist_init (tsm->list_pool,
- per_user_translation_list_elt - tsm->list_pool);
-
- per_user_translation_list_elt->value = s - tsm->sessions;
- s->per_user_index = per_user_translation_list_elt - tsm->list_pool;
- s->per_user_list_head_index = u->sessions_per_user_list_head_index;
-
- clib_dlist_addtail (tsm->list_pool,
- s->per_user_list_head_index,
- per_user_translation_list_elt - tsm->list_pool);
-
- s->user_index = u - tsm->users;
- vlib_set_simple_counter (&sm->total_sessions, thread_index, 0,
- pool_elts (tsm->sessions));
- }
-
- s->ha_last_refreshed = now;
-
- return s;
-}
-
void
snat_add_del_addr_to_fib (ip4_address_t * addr, u8 p_len, u32 sw_if_index,
int is_add)
@@ -534,12 +330,6 @@ snat_add_address (snat_main_t * sm, ip4_address_t * addr, u32 vrf_id,
snat_interface_t *i;
vlib_thread_main_t *tm = vlib_get_thread_main ();
- if (twice_nat && !sm->endpoint_dependent)
- {
- nat_log_err ("unsupported");
- return VNET_API_ERROR_UNSUPPORTED;
- }
-
/* Check if address already exists */
/* *INDENT-OFF* */
vec_foreach (ap, twice_nat ? sm->twice_nat_addresses : sm->addresses)
@@ -582,19 +372,19 @@ snat_add_address (snat_main_t * sm, ip4_address_t * addr, u32 vrf_id,
/* *INDENT-OFF* */
pool_foreach (i, sm->interfaces)
{
- if (nat_interface_is_inside(i) || sm->out2in_dpo)
- continue;
+ if (nat_interface_is_inside (i))
+ continue;
- snat_add_del_addr_to_fib(addr, 32, i->sw_if_index, 1);
- break;
+ snat_add_del_addr_to_fib (addr, 32, i->sw_if_index, 1);
+ break;
}
pool_foreach (i, sm->output_feature_interfaces)
{
- if (nat_interface_is_inside(i) || sm->out2in_dpo)
- continue;
+ if (nat_interface_is_inside (i))
+ continue;
- snat_add_del_addr_to_fib(addr, 32, i->sw_if_index, 1);
- break;
+ snat_add_del_addr_to_fib (addr, 32, i->sw_if_index, 1);
+ break;
}
/* *INDENT-ON* */
@@ -706,14 +496,12 @@ nat_ed_static_mapping_del_sessions (snat_main_t * sm,
vec_free (indexes_to_free);
}
-static_always_inline int
-nat44_ed_add_del_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)
+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)
{
snat_main_t *sm = &snat_main;
snat_static_mapping_t *m;
@@ -721,24 +509,11 @@ nat44_ed_add_del_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
snat_address_t *a = 0;
u32 fib_index = ~0;
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;
snat_static_map_resolve_t *rp, *rp_match = 0;
nat44_lb_addr_port_t *local;
u32 find = ~0;
-
- if (!sm->endpoint_dependent)
- {
- if (twice_nat || out2in_only)
- return VNET_API_ERROR_UNSUPPORTED;
- }
+ int i;
/* If the external address is a specific interface address */
if (sw_if_index != ~0)
@@ -892,8 +667,7 @@ nat44_ed_add_del_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
break;
foreach_nat_protocol
#undef _
- default:
- nat_elog_info ("unknown protocol");
+ default : nat_elog_info (sm, "unknown protocol");
return VNET_API_ERROR_INVALID_VALUE_2;
}
break;
@@ -980,47 +754,6 @@ nat44_ed_add_del_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
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);
-
- /* Delete dynamic sessions matching local address (+ local port) */
- // TODO: based on type of NAT EI/ED
- 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 && s->in2out.port != m->local_port)
- continue;
-
- nat_free_session_data (sm, s,
- tsm - sm->per_thread_data, 0);
- nat44_delete_session (sm, s, tsm - sm->per_thread_data);
-
- if (!addr_only && !sm->endpoint_dependent)
- break;
- }
- }
- }
- }
}
else
{
@@ -1075,8 +808,7 @@ nat44_ed_add_del_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
break;
foreach_nat_protocol
#undef _
- default:
- nat_elog_info ("unknown protocol");
+ default : nat_elog_info (sm, "unknown protocol");
return VNET_API_ERROR_INVALID_VALUE_2;
}
break;
@@ -1097,21 +829,9 @@ nat44_ed_add_del_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
if (!(sm->static_mapping_only) ||
(sm->static_mapping_only && sm->static_mapping_connection_tracking))
{
- if (sm->endpoint_dependent)
- {
- nat_ed_static_mapping_del_sessions (sm, tsm, m->local_addr,
- m->local_port, m->proto,
- fib_index, addr_only,
- e_addr, e_port);
- }
- else
- {
- u_key.addr = m->local_addr;
- u_key.fib_index = fib_index;
- kv.key = u_key.as_u64;
- nat44_ei_static_mapping_del_sessions (sm, tsm, u_key, addr_only,
- e_addr, e_port);
- }
+ 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);
@@ -1134,19 +854,19 @@ nat44_ed_add_del_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
/* *INDENT-OFF* */
pool_foreach (interface, sm->interfaces)
{
- if (nat_interface_is_inside(interface) || sm->out2in_dpo)
- 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, is_add);
+ break;
}
pool_foreach (interface, sm->output_feature_interfaces)
{
- if (nat_interface_is_inside(interface) || sm->out2in_dpo)
- 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, is_add);
+ break;
}
/* *INDENT-ON* */
@@ -1154,31 +874,6 @@ nat44_ed_add_del_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
}
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)
-{
- snat_main_t *sm = &snat_main;
- int rv;
-
- if (sm->endpoint_dependent)
- {
- rv = nat44_ed_add_del_static_mapping (
- l_addr, e_addr, l_port, e_port, vrf_id, addr_only, sw_if_index, proto,
- is_add, twice_nat, out2in_only, tag, identity_nat, pool_addr, exact);
- }
- else
- {
- rv = nat44_ei_add_del_static_mapping (
- l_addr, e_addr, l_port, e_port, proto, sw_if_index, vrf_id, addr_only,
- identity_nat, tag, is_add);
- }
- return rv;
-}
-
-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,
@@ -1195,9 +890,6 @@ nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port,
snat_session_t *s;
uword *bitmap = 0;
- if (!sm->endpoint_dependent)
- return VNET_API_ERROR_UNSUPPORTED;
-
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;
@@ -1237,8 +929,7 @@ nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port,
break;
foreach_nat_protocol
#undef _
- default:
- nat_elog_info ("unknown protocol");
+ default : nat_elog_info (sm, "unknown protocol");
return VNET_API_ERROR_INVALID_VALUE_2;
}
break;
@@ -1271,7 +962,7 @@ nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port,
m - sm->static_mappings);
if (clib_bihash_add_del_8_8 (&sm->static_mapping_by_external, &kv, 1))
{
- nat_elog_err ("static_mapping_by_external key add failed");
+ nat_elog_err (sm, "static_mapping_by_external key add failed");
return VNET_API_ERROR_UNSPECIFIED;
}
@@ -1344,8 +1035,7 @@ nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port,
break;
foreach_nat_protocol
#undef _
- default:
- nat_elog_info ("unknown protocol");
+ default : nat_elog_info (sm, "unknown protocol");
return VNET_API_ERROR_INVALID_VALUE_2;
}
break;
@@ -1356,7 +1046,7 @@ nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port,
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 ("static_mapping_by_external key del failed");
+ nat_elog_err (sm, "static_mapping_by_external key del failed");
return VNET_API_ERROR_UNSPECIFIED;
}
@@ -1370,34 +1060,36 @@ nat44_add_del_lb_static_mapping (ip4_address_t e_addr, u16 e_port,
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 ("static_mapping_by_local key del failed");
- return VNET_API_ERROR_UNSPECIFIED;
- }
- }
+ nat_elog_err (sm, "static_mapping_by_local key del failed");
+ return VNET_API_ERROR_UNSPECIFIED;
+ }
+ }
- if (sm->num_workers > 1)
- {
- ip4_header_t ip = {
- .src_address = local->addr,
- };
- tsm = vec_elt_at_index (sm->per_thread_data,
- sm->worker_in2out_cb (&ip, m->fib_index, 0));
- }
- else
- tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
+ if (sm->num_workers > 1)
+ {
+ ip4_header_t ip = {
+ .src_address = local->addr,
+ };
+ tsm =
+ vec_elt_at_index (sm->per_thread_data,
+ sm->worker_in2out_cb (&ip, m->fib_index, 0));
+ }
+ 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;
+ /* Delete sessions */
+ pool_foreach (s, tsm->sessions)
+ {
+ if (!(is_lb_session (s)))
+ continue;
- if ((s->in2out.addr.as_u32 != local->addr.as_u32) ||
- s->in2out.port != local->port)
- continue;
+ if ((s->in2out.addr.as_u32 != local->addr.as_u32) ||
+ s->in2out.port != local->port)
+ 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);
- }
+ nat_free_session_data (sm, s, tsm - sm->per_thread_data, 0);
+ nat_ed_session_delete (sm, s, tsm - sm->per_thread_data, 1);
+ }
}
/* *INDENT-ON* */
if (m->affinity)
@@ -1428,9 +1120,6 @@ nat44_lb_static_mapping_add_del_local (ip4_address_t e_addr, u16 e_port,
uword *bitmap = 0;
int i;
- if (!sm->endpoint_dependent)
- return VNET_API_ERROR_FEATURE_DISABLED;
-
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);
@@ -1473,7 +1162,7 @@ nat44_lb_static_mapping_add_del_local (ip4_address_t e_addr, u16 e_port,
init_nat_kv (&kv, l_addr, l_port, local->fib_index, proto, 0,
m - sm->static_mappings);
if (clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv, 1))
- nat_elog_err ("static_mapping_by_local key add failed");
+ nat_elog_err (sm, "static_mapping_by_local key add failed");
}
}
else
@@ -1491,7 +1180,7 @@ nat44_lb_static_mapping_add_del_local (ip4_address_t e_addr, u16 e_port,
{
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))
- nat_elog_err ("static_mapping_by_local key del failed");
+ nat_elog_err (sm, "static_mapping_by_local key del failed");
}
if (sm->num_workers > 1)
@@ -1630,7 +1319,6 @@ snat_del_address (snat_main_t * sm, ip4_address_t addr, u8 delete_sm,
{
vec_foreach (tsm, sm->per_thread_data)
{
- /* *INDENT-OFF* */
pool_foreach (ses, tsm->sessions) {
if (ses->out2in.addr.as_u32 == addr.as_u32)
{
@@ -1638,24 +1326,12 @@ snat_del_address (snat_main_t * sm, ip4_address_t addr, u8 delete_sm,
vec_add1 (ses_to_be_removed, ses - tsm->sessions);
}
}
- /* *INDENT-ON* */
- if (sm->endpoint_dependent)
- {
vec_foreach (ses_index, ses_to_be_removed)
{
ses = pool_elt_at_index (tsm->sessions, ses_index[0]);
nat_ed_session_delete (sm, ses, tsm - sm->per_thread_data, 1);
}
- }
- else
- {
- vec_foreach (ses_index, ses_to_be_removed)
- {
- ses = pool_elt_at_index (tsm->sessions, ses_index[0]);
- nat44_delete_session (sm, ses, tsm - sm->per_thread_data);
- }
- }
vec_free (ses_to_be_removed);
}
@@ -1676,59 +1352,24 @@ snat_del_address (snat_main_t * sm, ip4_address_t addr, u8 delete_sm,
/* Delete external address from FIB */
pool_foreach (interface, sm->interfaces)
{
- if (nat_interface_is_inside (interface) || sm->out2in_dpo)
+ if (nat_interface_is_inside (interface))
continue;
snat_add_del_addr_to_fib (&addr, 32, interface->sw_if_index, 0);
break;
}
-
pool_foreach (interface, sm->output_feature_interfaces)
{
- if (nat_interface_is_inside(interface) || sm->out2in_dpo)
- continue;
+ if (nat_interface_is_inside (interface))
+ continue;
- snat_add_del_addr_to_fib(&addr, 32, interface->sw_if_index, 0);
- break;
+ snat_add_del_addr_to_fib (&addr, 32, interface->sw_if_index, 0);
+ break;
}
return 0;
}
-static void
-nat_validate_counters (snat_main_t * sm, u32 sw_if_index)
-{
-#define _(x) \
- vlib_validate_simple_counter (&sm->counters.fastpath.in2out.x, \
- sw_if_index); \
- vlib_zero_simple_counter (&sm->counters.fastpath.in2out.x, sw_if_index); \
- vlib_validate_simple_counter (&sm->counters.fastpath.out2in.x, \
- sw_if_index); \
- vlib_zero_simple_counter (&sm->counters.fastpath.out2in.x, sw_if_index); \
- vlib_validate_simple_counter (&sm->counters.slowpath.in2out.x, \
- sw_if_index); \
- vlib_zero_simple_counter (&sm->counters.slowpath.in2out.x, sw_if_index); \
- vlib_validate_simple_counter (&sm->counters.slowpath.out2in.x, \
- sw_if_index); \
- vlib_zero_simple_counter (&sm->counters.slowpath.out2in.x, sw_if_index); \
- vlib_validate_simple_counter (&sm->counters.fastpath.in2out_ed.x, \
- sw_if_index); \
- vlib_zero_simple_counter (&sm->counters.fastpath.in2out_ed.x, sw_if_index); \
- vlib_validate_simple_counter (&sm->counters.fastpath.out2in_ed.x, \
- sw_if_index); \
- vlib_zero_simple_counter (&sm->counters.fastpath.out2in_ed.x, sw_if_index); \
- vlib_validate_simple_counter (&sm->counters.slowpath.in2out_ed.x, \
- sw_if_index); \
- vlib_zero_simple_counter (&sm->counters.slowpath.in2out_ed.x, sw_if_index); \
- vlib_validate_simple_counter (&sm->counters.slowpath.out2in_ed.x, \
- sw_if_index); \
- vlib_zero_simple_counter (&sm->counters.slowpath.out2in_ed.x, sw_if_index);
- foreach_nat_counter;
-#undef _
- vlib_validate_simple_counter (&sm->counters.hairpinning, sw_if_index);
- vlib_zero_simple_counter (&sm->counters.hairpinning, sw_if_index);
-}
-
void
expire_per_vrf_sessions (u32 fib_index)
{
@@ -1806,12 +1447,6 @@ snat_interface_add_del (u32 sw_if_index, u8 is_inside, int is_del)
return VNET_API_ERROR_UNSUPPORTED;
}
- if (sm->out2in_dpo && !is_inside)
- {
- nat_log_err ("error unsupported");
- return VNET_API_ERROR_UNSUPPORTED;
- }
-
/* *INDENT-OFF* */
pool_foreach (i, sm->output_feature_interfaces)
{
@@ -1831,12 +1466,8 @@ snat_interface_add_del (u32 sw_if_index, u8 is_inside, int is_del)
feature_name =
is_inside ? "nat44-in2out-worker-handoff" :
"nat44-out2in-worker-handoff";
- else if (sm->endpoint_dependent)
- {
- feature_name = is_inside ? "nat-pre-in2out" : "nat-pre-out2in";
- }
else
- feature_name = is_inside ? "nat44-in2out" : "nat44-out2in";
+ feature_name = is_inside ? "nat-pre-in2out" : "nat-pre-out2in";
}
ASSERT (sm->frame_queue_nelts > 0);
@@ -1849,8 +1480,7 @@ snat_interface_add_del (u32 sw_if_index, u8 is_inside, int is_del)
sm->fq_out2in_index = vlib_frame_queue_main_init (sm->out2in_node_index,
sm->frame_queue_nelts);
- if (sm->endpoint_dependent)
- update_per_vrf_sessions_vec (fib_index, is_del);
+ update_per_vrf_sessions_vec (fib_index, is_del);
if (!is_inside)
{
@@ -1900,17 +1530,12 @@ feature_set:
feature_name = !is_inside ? "nat44-in2out-worker-handoff" :
"nat44-out2in-worker-handoff";
}
- else if (sm->endpoint_dependent)
- {
- del_feature_name = "nat44-ed-classify";
- feature_name = !is_inside ? "nat-pre-in2out" :
- "nat-pre-out2in";
- }
- else
- {
- del_feature_name = "nat44-classify";
- feature_name = !is_inside ? "nat44-in2out" : "nat44-out2in";
- }
+ else
+ {
+ del_feature_name = "nat44-ed-classify";
+ feature_name =
+ !is_inside ? "nat-pre-in2out" : "nat-pre-out2in";
+ }
int rv = ip4_sv_reass_enable_disable_with_refcnt (sw_if_index, 0);
if (rv)
@@ -1919,13 +1544,6 @@ feature_set:
sw_if_index, 0, 0, 0);
vnet_feature_enable_disable ("ip4-unicast", feature_name,
sw_if_index, 1, 0, 0);
- if (!is_inside)
- {
- if (!sm->endpoint_dependent)
- vnet_feature_enable_disable ("ip4-local",
- "nat44-hairpinning",
- sw_if_index, 1, 0, 0);
- }
}
else
{
@@ -1935,13 +1553,6 @@ feature_set:
vnet_feature_enable_disable ("ip4-unicast", feature_name,
sw_if_index, 0, 0, 0);
pool_put (sm->interfaces, i);
- if (is_inside)
- {
- if (!sm->endpoint_dependent)
- vnet_feature_enable_disable ("ip4-local",
- "nat44-hairpinning",
- sw_if_index, 0, 0, 0);
- }
}
}
else
@@ -1956,19 +1567,13 @@ feature_set:
"nat44-out2in-worker-handoff";
feature_name = "nat44-handoff-classify";
}
- else if (sm->endpoint_dependent)
+ else
{
del_feature_name =
!is_inside ? "nat-pre-in2out" : "nat-pre-out2in";
feature_name = "nat44-ed-classify";
}
- else
- {
- del_feature_name =
- !is_inside ? "nat44-in2out" : "nat44-out2in";
- feature_name = "nat44-classify";
- }
int rv = ip4_sv_reass_enable_disable_with_refcnt (sw_if_index, 1);
if (rv)
@@ -1977,12 +1582,6 @@ feature_set:
sw_if_index, 0, 0, 0);
vnet_feature_enable_disable ("ip4-unicast", feature_name,
sw_if_index, 1, 0, 0);
- if (!is_inside)
- {
- if (!sm->endpoint_dependent)
- vnet_feature_enable_disable (
- "ip4-local", "nat44-hairpinning", sw_if_index, 0, 0, 0);
- }
goto set_flags;
}
@@ -2000,7 +1599,7 @@ feature_set:
pool_get (sm->interfaces, i);
i->sw_if_index = sw_if_index;
i->flags = 0;
- nat_validate_counters (sm, sw_if_index);
+ nat_validate_interface_counters (sm, sw_if_index);
vnet_feature_enable_disable ("ip4-unicast", feature_name, sw_if_index, 1, 0,
0);
@@ -2009,13 +1608,6 @@ feature_set:
if (rv)
return rv;
- if (is_inside && !sm->out2in_dpo)
- {
- if (!sm->endpoint_dependent)
- vnet_feature_enable_disable ("ip4-local", "nat44-hairpinning",
- sw_if_index, 1, 0, 0);
- }
-
set_flags:
if (is_inside)
{
@@ -2078,8 +1670,7 @@ snat_interface_add_del_output_feature (u32 sw_if_index,
}
/* *INDENT-ON* */
- if (sm->endpoint_dependent)
- update_per_vrf_sessions_vec (fib_index, is_del);
+ update_per_vrf_sessions_vec (fib_index, is_del);
if (!is_inside)
{
@@ -2111,20 +1702,6 @@ snat_interface_add_del_output_feature (u32 sw_if_index,
feature_set:
if (is_inside)
{
- 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;
- }
- else
- {
int rv =
ip4_sv_reass_enable_disable_with_refcnt (sw_if_index, !is_del);
if (rv)
@@ -2134,11 +1711,6 @@ feature_set:
!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",
- sw_if_index, !is_del, 0, 0);
- }
goto fq;
}
@@ -2160,8 +1732,6 @@ feature_set:
}
else
{
- if (sm->endpoint_dependent)
- {
int rv =
ip4_sv_reass_enable_disable_with_refcnt (sw_if_index, !is_del);
if (rv)
@@ -2175,23 +1745,6 @@ feature_set:
sw_if_index, !is_del, 0, 0);
vnet_feature_enable_disable ("ip4-output", "nat-pre-in2out-output",
sw_if_index, !is_del, 0, 0);
- }
- 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",
- sw_if_index, !is_del, 0, 0);
- }
}
fq:
@@ -2227,7 +1780,7 @@ fq:
pool_get (sm->output_feature_interfaces, i);
i->sw_if_index = sw_if_index;
i->flags = 0;
- nat_validate_counters (sm, sw_if_index);
+ nat_validate_interface_counters (sm, sw_if_index);
if (is_inside)
i->flags |= NAT_INTERFACE_FLAG_IS_INSIDE;
else
@@ -2283,7 +1836,7 @@ snat_set_workers (uword * bitmap)
}
int
-snat_set_frame_queue_nelts (u32 frame_queue_nelts)
+nat44_ed_set_frame_queue_nelts (u32 frame_queue_nelts)
{
fail_if_enabled ();
snat_main_t *sm = &snat_main;
@@ -2438,11 +1991,8 @@ test_key_calc_split ()
static clib_error_t *
nat_ip_table_add_del (vnet_main_t * vnm, u32 table_id, u32 is_add)
{
- snat_main_t *sm = &snat_main;
u32 fib_index;
- if (sm->endpoint_dependent)
- {
// TODO: consider removing all NAT interfaces
if (!is_add)
{
@@ -2450,7 +2000,6 @@ nat_ip_table_add_del (vnet_main_t * vnm, u32 table_id, u32 is_add)
if (fib_index != ~0)
expire_per_vrf_sessions (fib_index);
}
- }
return 0;
}
@@ -2461,65 +2010,45 @@ nat44_set_node_indexes (snat_main_t * sm, vlib_main_t * vm)
{
vlib_node_t *node;
- node = vlib_get_node_by_name (vm, (u8 *) "nat44-out2in");
- sm->ei_out2in_node_index = node->index;
- node = vlib_get_node_by_name (vm, (u8 *) "nat44-in2out");
- sm->ei_in2out_node_index = node->index;
- node = vlib_get_node_by_name (vm, (u8 *) "nat44-in2out-output");
- sm->ei_in2out_output_node_index = node->index;
-
node = vlib_get_node_by_name (vm, (u8 *) "nat44-ed-out2in");
- sm->ed_out2in_node_index = node->index;
+ sm->in2out_node_index = node->index;
+
node = vlib_get_node_by_name (vm, (u8 *) "nat44-ed-in2out");
- sm->ed_in2out_node_index = node->index;
+ sm->out2in_node_index = node->index;
+
node = vlib_get_node_by_name (vm, (u8 *) "nat44-ed-in2out-output");
- sm->ed_in2out_output_node_index = node->index;
-
- node = vlib_get_node_by_name (vm, (u8 *) "error-drop");
- sm->error_node_index = node->index;
- node = vlib_get_node_by_name (vm, (u8 *) "nat-pre-in2out");
- sm->pre_in2out_node_index = node->index;
- node = vlib_get_node_by_name (vm, (u8 *) "nat-pre-out2in");
- sm->pre_out2in_node_index = node->index;
- node = vlib_get_node_by_name (vm, (u8 *) "nat-pre-in2out");
- sm->pre_in2out_node_index = node->index;
- node = vlib_get_node_by_name (vm, (u8 *) "nat-pre-out2in");
- sm->pre_out2in_node_index = node->index;
- node = vlib_get_node_by_name (vm, (u8 *) "nat44-in2out-fast");
- sm->in2out_fast_node_index = node->index;
- node = vlib_get_node_by_name (vm, (u8 *) "nat44-in2out-slowpath");
- 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-ed-in2out-slowpath");
- sm->ed_in2out_slowpath_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-ed-out2in-slowpath");
- sm->ed_out2in_slowpath_node_index = node->index;
- node = vlib_get_node_by_name (vm, (u8 *) "nat44-hairpinning");
- sm->hairpinning_node_index = node->index;
- node = vlib_get_node_by_name (vm, (u8 *) "nat44-hairpin-dst");
- sm->hairpin_dst_node_index = node->index;
- node = vlib_get_node_by_name (vm, (u8 *) "nat44-hairpin-src");
- sm->hairpin_src_node_index = node->index;
+ sm->in2out_output_node_index = node->index;
}
-#define nat_init_simple_counter(c, n, sn) \
-do \
- { \
- c.name = n; \
- c.stat_segment_name = sn; \
- vlib_validate_simple_counter (&c, 0); \
- vlib_zero_simple_counter (&c, 0); \
- } while (0);
-
-extern vlib_node_registration_t nat44_hairpinning_node;
-extern vlib_node_registration_t snat_hairpin_dst_node;
-extern vlib_node_registration_t
- nat44_in2out_hairpinning_finish_ip4_lookup_node;
-extern vlib_node_registration_t
- nat44_in2out_hairpinning_finish_interface_output_node;
+#define nat_validate_simple_counter(c, i) \
+ do \
+ { \
+ vlib_validate_simple_counter (&c, i); \
+ vlib_zero_simple_counter (&c, i); \
+ } \
+ while (0);
+
+#define nat_init_simple_counter(c, n, sn) \
+ do \
+ { \
+ c.name = n; \
+ c.stat_segment_name = sn; \
+ nat_validate_simple_counter (c, 0); \
+ } \
+ while (0);
+
+static_always_inline void
+nat_validate_interface_counters (snat_main_t *sm, u32 sw_if_index)
+{
+#define _(x) \
+ nat_validate_simple_counter (sm->counters.fastpath.in2out.x, sw_if_index); \
+ nat_validate_simple_counter (sm->counters.fastpath.out2in.x, sw_if_index); \
+ nat_validate_simple_counter (sm->counters.slowpath.in2out.x, sw_if_index); \
+ nat_validate_simple_counter (sm->counters.slowpath.out2in.x, sw_if_index);
+ foreach_nat_counter;
+#undef _
+ nat_validate_simple_counter (sm->counters.hairpinning, sw_if_index);
+}
static clib_error_t *
nat_init (vlib_main_t * vm)
@@ -2546,48 +2075,28 @@ nat_init (vlib_main_t * vm)
sm->fq_in2out_index = ~0;
sm->fq_in2out_output_index = ~0;
- sm->log_level = SNAT_LOG_ERROR;
+ sm->log_level = NAT_LOG_ERROR;
nat44_set_node_indexes (sm, vm);
sm->log_class = vlib_log_register_class ("nat", 0);
nat_ipfix_logging_init (vm);
- nat_init_simple_counter (sm->total_users, "total-users",
- "/nat44/total-users");
nat_init_simple_counter (sm->total_sessions, "total-sessions",
- "/nat44/total-sessions");
- nat_init_simple_counter (sm->user_limit_reached, "user-limit-reached",
- "/nat44/user-limit-reached");
-
-#define _(x) \
- sm->counters.fastpath.in2out.x.name = #x; \
- sm->counters.fastpath.in2out.x.stat_segment_name = \
- "/nat44/in2out/fastpath/" #x; \
- sm->counters.slowpath.in2out.x.name = #x; \
- sm->counters.slowpath.in2out.x.stat_segment_name = \
- "/nat44/in2out/slowpath/" #x; \
- sm->counters.fastpath.out2in.x.name = #x; \
- sm->counters.fastpath.out2in.x.stat_segment_name = \
- "/nat44/out2in/fastpath/" #x; \
- sm->counters.slowpath.out2in.x.name = #x; \
- sm->counters.slowpath.out2in.x.stat_segment_name = \
- "/nat44/out2in/slowpath/" #x; \
- sm->counters.fastpath.in2out_ed.x.name = #x; \
- sm->counters.fastpath.in2out_ed.x.stat_segment_name = \
- "/nat44/ed/in2out/fastpath/" #x; \
- sm->counters.slowpath.in2out_ed.x.name = #x; \
- sm->counters.slowpath.in2out_ed.x.stat_segment_name = \
- "/nat44/ed/in2out/slowpath/" #x; \
- sm->counters.fastpath.out2in_ed.x.name = #x; \
- sm->counters.fastpath.out2in_ed.x.stat_segment_name = \
- "/nat44/ed/out2in/fastpath/" #x; \
- sm->counters.slowpath.out2in_ed.x.name = #x; \
- sm->counters.slowpath.out2in_ed.x.stat_segment_name = \
- "/nat44/ed/out2in/slowpath/" #x;
+ "/nat44-ed/total-sessions");
+
+#define _(x) \
+ nat_init_simple_counter (sm->counters.fastpath.in2out.x, #x, \
+ "/nat44-ed/in2out/fastpath/" #x); \
+ nat_init_simple_counter (sm->counters.fastpath.out2in.x, #x, \
+ "/nat44-ed/out2in/fastpath/" #x); \
+ nat_init_simple_counter (sm->counters.slowpath.in2out.x, #x, \
+ "/nat44-ed/in2out/slowpath/" #x); \
+ nat_init_simple_counter (sm->counters.slowpath.out2in.x, #x, \
+ "/nat44-ed/out2in/slowpath/" #x);
foreach_nat_counter;
#undef _
- sm->counters.hairpinning.name = "hairpinning";
- sm->counters.hairpinning.stat_segment_name = "/nat44/hairpinning";
+ nat_init_simple_counter (sm->counters.hairpinning, "hairpinning",
+ "/nat44-ed/hairpinning");
p = hash_get_mem (tm->thread_registrations_by_name, "workers");
if (p)
@@ -2632,34 +2141,27 @@ nat_init (vlib_main_t * vm)
fib_source_allocate ("nat-hi", FIB_SOURCE_PRIORITY_HI,
FIB_SOURCE_BH_SIMPLE);
- /* used only by out2in-dpo feature */
- nat_dpo_module_init ();
-
nat_affinity_init (vm);
- nat_ha_init (vm, sm->num_workers, num_threads);
-
test_key_calc_split ();
- sm->nat44_hairpinning_fq_index =
- vlib_frame_queue_main_init (nat44_hairpinning_node.index, 0);
- sm->snat_hairpin_dst_fq_index =
- vlib_frame_queue_main_init (snat_hairpin_dst_node.index, 0);
- sm->nat44_in2out_hairpinning_finish_ip4_lookup_node_fq_index =
- vlib_frame_queue_main_init (
- nat44_in2out_hairpinning_finish_ip4_lookup_node.index, 0);
- sm->nat44_in2out_hairpinning_finish_interface_output_node_fq_index =
- vlib_frame_queue_main_init (
- nat44_in2out_hairpinning_finish_interface_output_node.index, 0);
return nat44_api_hookup (vm);
}
VLIB_INIT_FUNCTION (nat_init);
-static int
-nat44_ed_plugin_enable (nat44_config_t c)
+int
+nat44_plugin_enable (nat44_config_t c)
{
snat_main_t *sm = &snat_main;
+ fail_if_enabled ();
+
+ // UPDATE based on these appropriate API/CLI
+ // c.static_mapping_only + c.connection_tracking
+ // - supported in NAT EI & NAT ED
+ // c.out2in_dpo, c.static_mapping_only
+ // - supported in NAT EI
+
if (c.static_mapping_only && !c.connection_tracking)
{
nat_log_err ("unsupported combination of configuration");
@@ -2667,25 +2169,14 @@ nat44_ed_plugin_enable (nat44_config_t c)
}
// nat44 feature configuration
- sm->endpoint_dependent = c.endpoint_dependent;
sm->static_mapping_only = c.static_mapping_only;
sm->static_mapping_connection_tracking = c.connection_tracking;
- // EI only feature (could break ED)
- sm->out2in_dpo = c.out2in_dpo;
-
sm->forwarding_enabled = 0;
sm->mss_clamping = 0;
sm->pat = (!c.static_mapping_only ||
(c.static_mapping_only && c.connection_tracking));
- if (!c.users)
- c.users = 1024;
-
- // EI only feature (could break ED)
- sm->max_users_per_thread = c.users;
- sm->user_buckets = nat_calc_bihash_buckets (c.users);
-
if (!c.sessions)
c.sessions = 63 * 1024;
@@ -2695,10 +2186,6 @@ nat44_ed_plugin_enable (nat44_config_t c)
// ED only feature
vec_add1 (sm->max_translations_per_fib, sm->max_translations_per_thread);
- // EI only feature (could break ED)
- sm->max_translations_per_user
- = c.user_sessions ? c.user_sessions : sm->max_translations_per_thread;
-
sm->inside_vrf_id = c.inside_vrf;
sm->inside_fib_index =
fib_table_find_or_create_and_lock
@@ -2711,33 +2198,13 @@ nat44_ed_plugin_enable (nat44_config_t c)
sm->worker_in2out_cb = nat44_ed_get_worker_in2out_cb;
sm->worker_out2in_cb = nat44_ed_get_worker_out2in_cb;
- sm->in2out_node_index = sm->ed_in2out_node_index;
- sm->out2in_node_index = sm->ed_out2in_node_index;
-
- sm->in2out_output_node_index = sm->ed_in2out_output_node_index;
-
- if (sm->pat)
- {
- sm->icmp_match_in2out_cb = NULL;
- sm->icmp_match_out2in_cb = NULL;
- }
- else
- {
- sm->icmp_match_in2out_cb = icmp_match_in2out_fast;
- sm->icmp_match_out2in_cb = icmp_match_out2in_fast;
- }
-
- nat44_ed_db_init (sm->max_translations_per_thread, sm->translation_buckets,
- sm->user_buckets);
+ nat44_ed_db_init (sm->max_translations_per_thread, sm->translation_buckets);
nat_affinity_enable ();
nat_reset_timeouts (&sm->timeouts);
- // TODO: function for reset counters
- vlib_zero_simple_counter (&sm->total_users, 0);
vlib_zero_simple_counter (&sm->total_sessions, 0);
- vlib_zero_simple_counter (&sm->user_limit_reached, 0);
if (!sm->frame_queue_nelts)
sm->frame_queue_nelts = NAT_FQ_NELTS_DEFAULT;
@@ -2748,48 +2215,10 @@ nat44_ed_plugin_enable (nat44_config_t c)
return 0;
}
-int
-nat44_plugin_enable (nat44_config_t c)
-{
- fail_if_enabled ();
-
- // c.static_mapping_only + c.connection_tracking
- // - supported in NAT EI & NAT ED
- // c.out2in_dpo, c.static_mapping_only
- // - supported in NAT EI
-
- if (c.endpoint_dependent)
- {
- if (c.out2in_dpo || c.users || c.user_sessions)
- {
- nat_log_err ("unsupported combination of configuration");
- return 1;
- }
- return nat44_ed_plugin_enable (c);
- }
-
- // separation:
- // for now just copy variables
-
- nat44_ei_config_t ei_c = {
- .inside_vrf = c.inside_vrf,
- .outside_vrf = c.outside_vrf,
- .users = c.users,
- .sessions = c.sessions,
- .user_sessions = c.user_sessions,
- .out2in_dpo = c.out2in_dpo,
- .static_mapping_only = c.static_mapping_only,
- .connection_tracking = c.connection_tracking,
- };
-
- return nat44_ei_plugin_enable (ei_c);
-}
-
void
nat44_addresses_free (snat_address_t ** addresses)
{
snat_address_t *ap;
- /* *INDENT-OFF* */
vec_foreach (ap, *addresses)
{
#define _(N, i, n, s) \
@@ -2797,21 +2226,21 @@ nat44_addresses_free (snat_address_t ** addresses)
foreach_nat_protocol
#undef _
}
- /* *INDENT-ON* */
vec_free (*addresses);
*addresses = 0;
}
-static int
-nat44_ed_plugin_disable ()
+int
+nat44_plugin_disable ()
{
snat_main_t *sm = &snat_main;
snat_interface_t *i, *vec;
int error = 0;
+ fail_if_disabled ();
+
// first unregister all nodes from interfaces
vec = vec_dup (sm->interfaces);
- /* *INDENT-OFF* */
vec_foreach (i, vec)
{
if (nat_interface_is_inside(i))
@@ -2825,12 +2254,10 @@ nat44_ed_plugin_disable ()
i->sw_if_index);
}
}
- /* *INDENT-ON* */
vec_free (vec);
sm->interfaces = 0;
vec = vec_dup (sm->output_feature_interfaces);
- /* *INDENT-OFF* */
vec_foreach (i, vec)
{
if (nat_interface_is_inside(i))
@@ -2844,7 +2271,6 @@ nat44_ed_plugin_disable ()
i->sw_if_index);
}
}
- /* *INDENT-ON* */
vec_free (vec);
sm->output_feature_interfaces = 0;
@@ -2855,7 +2281,6 @@ nat44_ed_plugin_disable ()
nat44_addresses_free (&sm->addresses);
nat44_addresses_free (&sm->twice_nat_addresses);
-
vec_free (sm->to_resolve);
vec_free (sm->auto_add_sw_if_indices);
vec_free (sm->auto_add_sw_if_indices_twice_nat);
@@ -2872,16 +2297,38 @@ nat44_ed_plugin_disable ()
return 0;
}
-int
-nat44_plugin_disable ()
+void
+nat44_ed_forwarding_enable_disable (u8 is_enable)
{
+ snat_main_per_thread_data_t *tsm;
snat_main_t *sm = &snat_main;
+ snat_session_t *s;
- fail_if_disabled ();
+ u32 *ses_to_be_removed = 0, *ses_index;
+
+ sm->forwarding_enabled = is_enable != 0;
+
+ if (is_enable)
+ return;
+
+ vec_foreach (tsm, sm->per_thread_data)
+ {
+ pool_foreach (s, tsm->sessions)
+ {
+ if (is_fwd_bypass_session (s))
+ {
+ vec_add1 (ses_to_be_removed, s - tsm->sessions);
+ }
+ }
+ vec_foreach (ses_index, ses_to_be_removed)
+ {
+ s = pool_elt_at_index (tsm->sessions, ses_index[0]);
+ 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 (sm->endpoint_dependent)
- return nat44_ed_plugin_disable ();
- return nat44_ei_plugin_disable ();
+ vec_free (ses_to_be_removed);
+ }
}
void
@@ -2889,6 +2336,7 @@ snat_free_outside_address_and_port (snat_address_t *addresses,
u32 thread_index, ip4_address_t *addr,
u16 port, nat_protocol_t protocol)
{
+ snat_main_t *sm = &snat_main;
snat_address_t *a;
u32 address_index;
u16 port_host_byte_order = clib_net_to_host_u16 (port);
@@ -2915,8 +2363,7 @@ snat_free_outside_address_and_port (snat_address_t *addresses,
break;
foreach_nat_protocol
#undef _
- default:
- nat_elog_info ("unknown protocol");
+ default : nat_elog_info (sm, "unknown protocol");
return;
}
}
@@ -2926,6 +2373,7 @@ nat_set_outside_address_and_port (snat_address_t *addresses, u32 thread_index,
ip4_address_t addr, u16 port,
nat_protocol_t protocol)
{
+ snat_main_t *sm = &snat_main;
snat_address_t *a = 0;
u32 address_index;
u16 port_host_byte_order = clib_net_to_host_u16 (port);
@@ -2949,8 +2397,7 @@ nat_set_outside_address_and_port (snat_address_t *addresses, u32 thread_index,
return 0;
foreach_nat_protocol
#undef _
- default:
- nat_elog_info ("unknown protocol");
+ default : nat_elog_info (sm, "unknown protocol");
return 1;
}
}
@@ -3030,7 +2477,6 @@ snat_static_mapping_match (snat_main_t * sm,
if (PREDICT_FALSE (sm->num_workers > 1))
{
u32 thread_index = vlib_get_thread_index ();
- /* *INDENT-OFF* */
pool_foreach_index (i, m->locals)
{
local = pool_elt_at_index (m->locals, i);
@@ -3045,17 +2491,14 @@ snat_static_mapping_match (snat_main_t * sm,
vec_add1 (tmp, i);
}
}
- /* *INDENT-ON* */
ASSERT (vec_len (tmp) != 0);
}
else
{
- /* *INDENT-OFF* */
pool_foreach_index (i, m->locals)
{
vec_add1 (tmp, i);
}
- /* *INDENT-ON* */
}
hi = vec_len (tmp) - 1;
local = pool_elt_at_index (m->locals, tmp[hi]);
@@ -3078,7 +2521,7 @@ snat_static_mapping_match (snat_main_t * sm,
match_protocol, match_port,
tmp[lo], m->affinity,
m->affinity_per_service_list_head_index))
- nat_elog_info ("create affinity record failed");
+ nat_elog_info (sm, "create affinity record failed");
}
vec_free (tmp);
}
@@ -3118,30 +2561,6 @@ end:
return 0;
}
-void
-nat44_add_del_address_dpo (ip4_address_t addr, u8 is_add)
-{
- snat_main_t *sm = &snat_main;
- dpo_id_t dpo_v4 = DPO_INVALID;
- fib_prefix_t pfx = {
- .fp_proto = FIB_PROTOCOL_IP4,
- .fp_len = 32,
- .fp_addr.ip4.as_u32 = addr.as_u32,
- };
-
- if (is_add)
- {
- nat_dpo_create (DPO_PROTO_IP4, 0, &dpo_v4);
- fib_table_entry_special_dpo_add (0, &pfx, sm->fib_src_hi,
- FIB_ENTRY_FLAG_EXCLUSIVE, &dpo_v4);
- dpo_reset (&dpo_v4);
- }
- else
- {
- fib_table_entry_special_remove (0, &pfx, sm->fib_src_hi);
- }
-}
-
static u32
nat44_ed_get_worker_in2out_cb (ip4_header_t *ip, u32 rx_fib_index,
u8 is_output)
@@ -3207,12 +2626,10 @@ nat44_ed_get_worker_in2out_cb (ip4_header_t *ip, u32 rx_fib_index,
ed_value_get_thread_index (&value16));
next_worker_index += tsm->thread_index;
- nat_elog_debug_handoff ("HANDOFF IN2OUT-OUTPUT-FEATURE (session)",
- next_worker_index, fib_index,
- clib_net_to_host_u32 (ip->
- src_address.as_u32),
- clib_net_to_host_u32 (ip->
- dst_address.as_u32));
+ nat_elog_debug_handoff (
+ sm, "HANDOFF IN2OUT-OUTPUT-FEATURE (session)", next_worker_index,
+ fib_index, clib_net_to_host_u32 (ip->src_address.as_u32),
+ clib_net_to_host_u32 (ip->dst_address.as_u32));
return next_worker_index;
}
@@ -3228,14 +2645,14 @@ nat44_ed_get_worker_in2out_cb (ip4_header_t *ip, u32 rx_fib_index,
if (PREDICT_TRUE (!is_output))
{
- nat_elog_debug_handoff ("HANDOFF IN2OUT",
- next_worker_index, rx_fib_index,
+ nat_elog_debug_handoff (sm, "HANDOFF IN2OUT", next_worker_index,
+ rx_fib_index,
clib_net_to_host_u32 (ip->src_address.as_u32),
clib_net_to_host_u32 (ip->dst_address.as_u32));
}
else
{
- nat_elog_debug_handoff ("HANDOFF IN2OUT-OUTPUT-FEATURE",
+ nat_elog_debug_handoff (sm, "HANDOFF IN2OUT-OUTPUT-FEATURE",
next_worker_index, rx_fib_index,
clib_net_to_host_u32 (ip->src_address.as_u32),
clib_net_to_host_u32 (ip->dst_address.as_u32));
@@ -3277,12 +2694,10 @@ nat44_ed_get_worker_out2in_cb (vlib_buffer_t * b, ip4_header_t * ip,
vnet_buffer2 (b)->nat.cached_session_index =
ed_value_get_session_index (&value16);
next_worker_index = sm->first_worker_index + tsm->thread_index;
- nat_elog_debug_handoff ("HANDOFF OUT2IN (session)",
- next_worker_index, rx_fib_index,
- clib_net_to_host_u32 (ip->
- src_address.as_u32),
- clib_net_to_host_u32 (ip->
- dst_address.as_u32));
+ nat_elog_debug_handoff (
+ sm, "HANDOFF OUT2IN (session)", next_worker_index, rx_fib_index,
+ clib_net_to_host_u32 (ip->src_address.as_u32),
+ clib_net_to_host_u32 (ip->dst_address.as_u32));
return next_worker_index;
}
}
@@ -3304,12 +2719,10 @@ nat44_ed_get_worker_out2in_cb (vlib_buffer_t * b, ip4_header_t * ip,
vec_elt_at_index (sm->per_thread_data,
ed_value_get_thread_index (&value16));
next_worker_index = sm->first_worker_index + tsm->thread_index;
- nat_elog_debug_handoff ("HANDOFF OUT2IN (session)",
- next_worker_index, rx_fib_index,
- clib_net_to_host_u32 (ip->
- src_address.as_u32),
- clib_net_to_host_u32 (ip->
- dst_address.as_u32));
+ nat_elog_debug_handoff (
+ sm, "HANDOFF OUT2IN (session)", next_worker_index,
+ rx_fib_index, clib_net_to_host_u32 (ip->src_address.as_u32),
+ clib_net_to_host_u32 (ip->dst_address.as_u32));
return next_worker_index;
}
}
@@ -3402,33 +2815,14 @@ nat44_ed_get_worker_out2in_cb (vlib_buffer_t * b, ip4_header_t * ip,
sm->workers[(clib_net_to_host_u16 (port) - 1024) / sm->port_per_thread];
done:
- nat_elog_debug_handoff ("HANDOFF OUT2IN", next_worker_index, rx_fib_index,
+ nat_elog_debug_handoff (sm, "HANDOFF OUT2IN", next_worker_index,
+ rx_fib_index,
clib_net_to_host_u32 (ip->src_address.as_u32),
clib_net_to_host_u32 (ip->dst_address.as_u32));
return next_worker_index;
}
u32
-nat_calc_bihash_buckets (u32 n_elts)
-{
- n_elts = n_elts / 2.5;
- u64 lower_pow2 = 1;
- while (lower_pow2 * 2 < n_elts)
- {
- lower_pow2 = 2 * lower_pow2;
- }
- u64 upper_pow2 = 2 * lower_pow2;
- if ((upper_pow2 - n_elts) < (n_elts - lower_pow2))
- {
- if (upper_pow2 <= UINT32_MAX)
- {
- return upper_pow2;
- }
- }
- return lower_pow2;
-}
-
-u32
nat44_get_max_session_limit ()
{
snat_main_t *sm = &snat_main;
@@ -3473,13 +2867,13 @@ nat44_update_session_limit (u32 session_limit, u32 vrf_id)
sm->translation_buckets =
nat_calc_bihash_buckets (sm->max_translations_per_thread);
- nat44_sessions_clear ();
+ nat44_ed_sessions_clear ();
return 0;
}
static void
nat44_ed_worker_db_init (snat_main_per_thread_data_t *tsm, u32 translations,
- u32 translation_buckets, u32 user_buckets)
+ u32 translation_buckets)
{
dlist_elt_t *head;
@@ -3505,12 +2899,6 @@ nat44_ed_worker_db_init (snat_main_per_thread_data_t *tsm, u32 translations,
pool_get (tsm->lru_pool, head);
tsm->unk_proto_lru_head_index = head - tsm->lru_pool;
clib_dlist_init (tsm->lru_pool, tsm->unk_proto_lru_head_index);
-
- // TODO: ED nat is not using these
- // before removal large refactor required
- pool_alloc (tsm->list_pool, translations);
- clib_bihash_init_8_8 (&tsm->user_hash, "users", user_buckets, 0);
- clib_bihash_set_kvp_format_fn_8_8 (&tsm->user_hash, format_user_kvp);
}
static void
@@ -3525,7 +2913,7 @@ reinit_ed_flow_hash ()
}
static void
-nat44_ed_db_init (u32 translations, u32 translation_buckets, u32 user_buckets)
+nat44_ed_db_init (u32 translations, u32 translation_buckets)
{
snat_main_t *sm = &snat_main;
snat_main_per_thread_data_t *tsm;
@@ -3551,7 +2939,7 @@ nat44_ed_db_init (u32 translations, u32 translation_buckets, u32 user_buckets)
vec_foreach (tsm, sm->per_thread_data)
{
nat44_ed_worker_db_init (tsm, sm->max_translations_per_thread,
- sm->translation_buckets, sm->user_buckets);
+ sm->translation_buckets);
}
}
}
@@ -3559,15 +2947,9 @@ nat44_ed_db_init (u32 translations, u32 translation_buckets, u32 user_buckets)
static void
nat44_ed_worker_db_free (snat_main_per_thread_data_t *tsm)
{
- pool_free (tsm->sessions);
pool_free (tsm->lru_pool);
-
+ pool_free (tsm->sessions);
vec_free (tsm->per_vrf_sessions_vec);
-
- // TODO: resolve static mappings (put only to !ED)
- pool_free (tsm->list_pool);
- pool_free (tsm->users);
- clib_bihash_free_8_8 (&tsm->user_hash);
}
static void
@@ -3605,25 +2987,10 @@ nat44_ed_sessions_clear ()
nat44_ed_worker_db_free (tsm);
nat44_ed_worker_db_init (tsm, sm->max_translations_per_thread,
- sm->translation_buckets, sm->user_buckets);
+ sm->translation_buckets);
}
}
-
- // TODO: function for reset counters
- vlib_zero_simple_counter (&sm->total_users, 0);
vlib_zero_simple_counter (&sm->total_sessions, 0);
- vlib_zero_simple_counter (&sm->user_limit_reached, 0);
-}
-
-void
-nat44_sessions_clear ()
-{
- snat_main_t *sm = &snat_main;
-
- if (sm->endpoint_dependent)
- nat44_ed_sessions_clear ();
- else
- nat44_ei_sessions_clear ();
}
static void
@@ -3691,7 +3058,7 @@ match:
rp->out2in_only, rp->tag, rp->identity_nat,
rp->pool_addr, rp->exact);
if (rv)
- nat_elog_notice_X1 ("snat_add_static_mapping returned %d", "i4", rv);
+ nat_elog_notice_X1 (sm, "snat_add_static_mapping returned %d", "i4", rv);
}
static void
@@ -3759,7 +3126,7 @@ match:
rp->twice_nat, rp->out2in_only, rp->tag, rp->identity_nat,
rp->pool_addr, rp->exact);
if (rv)
- nat_elog_notice_X1 ("snat_add_static_mapping returned %d",
+ nat_elog_notice_X1 (sm, "snat_add_static_mapping returned %d",
"i4", rv);
}
}
@@ -3851,9 +3218,6 @@ nat44_del_ed_session (snat_main_t * sm, ip4_address_t * addr, u16 port,
snat_session_t *s;
snat_main_per_thread_data_t *tsm;
- if (!sm->endpoint_dependent)
- return VNET_API_ERROR_FEATURE_DISABLED;
-
ip.dst_address.as_u32 = ip.src_address.as_u32 = addr->as_u32;
if (sm->num_workers > 1)
tsm =
diff --git a/src/plugins/nat/nat.h b/src/plugins/nat/nat44-ed/nat44_ed.h
index c1dc31e8710..10d1207fec8 100644
--- a/src/plugins/nat/nat.h
+++ b/src/plugins/nat/nat44-ed/nat44_ed.h
@@ -16,8 +16,8 @@
* @file nat.c
* NAT plugin global declarations
*/
-#ifndef __included_nat_h__
-#define __included_nat_h__
+#ifndef __included_nat44_ed_h__
+#define __included_nat44_ed_h__
#include <vnet/vnet.h>
#include <vnet/ip/ip.h>
@@ -31,8 +31,7 @@
#include <vppinfra/dlist.h>
#include <vppinfra/error.h>
#include <vlibapi/api.h>
-#include <vlib/log.h>
-#include <vppinfra/bihash_16_8.h>
+
#include <nat/lib/lib.h>
#include <nat/lib/inlines.h>
@@ -62,20 +61,13 @@ typedef struct
/* nat44 plugin features */
u8 static_mapping_only;
u8 connection_tracking;
- u8 endpoint_dependent;
- u8 out2in_dpo;
u32 inside_vrf;
u32 outside_vrf;
- /* maximum number of users */
- u32 users;
-
/* maximum number of sessions */
u32 sessions;
- /* maximum number of ssessions per user */
- u32 user_sessions;
} nat44_config_t;
typedef enum
@@ -99,20 +91,6 @@ typedef struct
u32 arc_next_index;
} nat_pre_trace_t;
-/* user (internal host) key */
-typedef struct
-{
- union
- {
- struct
- {
- ip4_address_t addr;
- u32 fib_index;
- };
- u64 as_u64;
- };
-} snat_user_key_t;
-
/* External address and port allocation modes */
#define foreach_nat_addr_and_port_alloc_alg \
_(0, DEFAULT, "default") \
@@ -168,8 +146,6 @@ typedef enum
_ (BAD_ICMP_TYPE, "unsupported ICMP type") \
_ (NO_TRANSLATION, "no translation") \
_ (MAX_SESSIONS_EXCEEDED, "maximum sessions exceeded") \
- _ (MAX_USER_SESS_EXCEEDED, "max user sessions exceeded") \
- _ (CANNOT_CREATE_USER, "cannot create NAT user") \
_ (NON_SYN, "non-SYN packet try to create session") \
_ (TCP_CLOSED, "drops due to TCP in transitory timeout") \
_ (HASH_ADD_FAILED, "hash table add failed")
@@ -252,6 +228,8 @@ typedef struct
uword l4_csum_delta;
} nat_6t_flow_t;
+void nat44_ed_forwarding_enable_disable (u8 is_enable);
+
always_inline void
nat_6t_flow_saddr_rewrite_set (nat_6t_flow_t *f, u32 saddr)
{
@@ -321,10 +299,6 @@ typedef CLIB_PACKED(struct
/* Flags */
u32 flags;
- /* Per-user translations */
- u32 per_user_index;
- u32 per_user_list_head_index;
-
/* head of LRU list in which this session is tracked */
u32 lru_head_index;
/* index in global LRU list */
@@ -355,9 +329,6 @@ typedef CLIB_PACKED(struct
u32 o2i_fin_seq;
u64 tcp_closed_timestamp;
- /* user index */
- u32 user_index;
-
/* per vrf sessions index */
u32 per_vrf_sessions_index;
@@ -368,15 +339,6 @@ typedef struct
{
ip4_address_t addr;
u32 fib_index;
- u32 sessions_per_user_list_head_index;
- u32 nsessions;
- u32 nstaticsessions;
-} snat_user_t;
-
-typedef struct
-{
- ip4_address_t addr;
- u32 fib_index;
/* *INDENT-OFF* */
#define _(N, i, n, s) \
u32 busy_##n##_ports; \
@@ -492,12 +454,6 @@ typedef struct
typedef struct
{
- /* Find-a-user => src address lookup */
- clib_bihash_8_8_t user_hash;
-
- /* User pool */
- snat_user_t *users;
-
/* Session pool */
snat_session_t *sessions;
@@ -524,13 +480,6 @@ typedef struct
struct snat_main_s;
-/* ICMP session match function */
-typedef u32 (snat_icmp_match_function_t) (
- struct snat_main_s *sm, vlib_node_runtime_t *node, u32 thread_index,
- vlib_buffer_t *b0, ip4_header_t *ip0, ip4_address_t *addr, u16 *port,
- u32 *fib_index, nat_protocol_t *proto, snat_session_t **s_out,
- u8 *dont_translate);
-
/* Return worker thread index for given packet */
typedef u32 (snat_get_worker_in2out_function_t) (ip4_header_t * ip,
u32 rx_fib_index,
@@ -552,14 +501,8 @@ typedef int (nat_alloc_out_addr_and_port_function_t) (snat_address_t *
u16 port_per_thread,
u32 snat_thread_index);
-#define foreach_nat_counter _ (tcp) _ (udp) _ (icmp) _ (other) _ (drops)
-
typedef struct snat_main_s
{
- /* ICMP session match functions */
- snat_icmp_match_function_t *icmp_match_in2out_cb;
- snat_icmp_match_function_t *icmp_match_out2in_cb;
-
/* Thread settings */
u32 num_workers;
u32 first_worker_index;
@@ -629,52 +572,16 @@ typedef struct snat_main_s
u32 fq_in2out_output_index;
u32 fq_out2in_index;
- /* node indexes */
- u32 error_node_index;
-
- /* handoff fq nodes */
- u32 handoff_out2in_index;
- u32 handoff_in2out_index;
- u32 handoff_in2out_output_index;
-
- /* respect feature arc nodes */
- u32 pre_out2in_node_index;
- u32 pre_in2out_node_index;
-
u32 out2in_node_index;
u32 in2out_node_index;
u32 in2out_output_node_index;
- u32 in2out_fast_node_index;
- u32 in2out_slowpath_node_index;
- u32 in2out_slowpath_output_node_index;
- u32 out2in_fast_node_index;
-
- u32 ei_out2in_node_index;
- u32 ei_in2out_node_index;
- u32 ei_in2out_output_node_index;
-
- u32 ed_out2in_node_index;
- u32 ed_in2out_node_index;
- u32 ed_in2out_output_node_index;
-
- u32 ed_in2out_slowpath_node_index;
- u32 ed_out2in_slowpath_node_index;
-
- u32 hairpinning_node_index;
- u32 hairpin_dst_node_index;
- u32 hairpin_src_node_index;
-
nat44_config_t rconfig;
//nat44_config_t cconfig;
/* If forwarding is enabled */
u8 forwarding_enabled;
- /* Config parameters */
- u8 endpoint_dependent;
-
- u8 out2in_dpo;
/* static mapping config */
u8 static_mapping_only;
u8 static_mapping_connection_tracking;
@@ -685,9 +592,6 @@ typedef struct snat_main_s
u32 translation_buckets;
u32 max_translations_per_thread;
u32 *max_translations_per_fib;
- u32 max_users_per_thread;
- u32 user_buckets;
- u32 max_translations_per_user;
u32 outside_vrf_id;
u32 outside_fib_index;
@@ -700,9 +604,7 @@ typedef struct snat_main_s
u16 mss_clamping;
/* counters */
- vlib_simple_counter_main_t total_users;
vlib_simple_counter_main_t total_sessions;
- vlib_simple_counter_main_t user_limit_reached;
#define _(x) vlib_simple_counter_main_t x;
struct
@@ -718,16 +620,6 @@ typedef struct snat_main_s
{
foreach_nat_counter;
} out2in;
-
- struct
- {
- foreach_nat_counter;
- } in2out_ed;
-
- struct
- {
- foreach_nat_counter;
- } out2in_ed;
} fastpath;
struct
@@ -741,16 +633,6 @@ typedef struct snat_main_s
{
foreach_nat_counter;
} out2in;
-
- struct
- {
- foreach_nat_counter;
- } in2out_ed;
-
- struct
- {
- foreach_nat_counter;
- } out2in_ed;
} slowpath;
vlib_simple_counter_main_t hairpinning;
@@ -784,10 +666,6 @@ typedef struct snat_main_s
vnet_main_t *vnet_main;
- u32 nat44_in2out_hairpinning_finish_ip4_lookup_node_fq_index;
- u32 nat44_in2out_hairpinning_finish_interface_output_node_fq_index;
- u32 nat44_hairpinning_fq_index;
- u32 snat_hairpin_dst_fq_index;
} snat_main_t;
typedef struct
@@ -823,7 +701,6 @@ extern fib_source_t nat_fib_src_hi;
extern fib_source_t nat_fib_src_low;
/* format functions */
-format_function_t format_snat_user;
format_function_t format_snat_static_mapping;
format_function_t format_snat_static_map_to_resolve;
format_function_t format_snat_session;
@@ -952,225 +829,6 @@ tcp_flags_is_init (u8 f)
#define nat_log_debug(...)\
vlib_log(VLIB_LOG_LEVEL_DEBUG, snat_main.log_class, __VA_ARGS__)
-/* NAT API Logging Levels */
-#define foreach_nat_log_level \
- _(0x00, LOG_NONE) \
- _(0x01, LOG_ERROR) \
- _(0x02, LOG_WARNING) \
- _(0x03, LOG_NOTICE) \
- _(0x04, LOG_INFO) \
- _(0x05, LOG_DEBUG)
-
-typedef enum nat_log_level_t_
-{
-#define _(n,f) SNAT_##f = n,
- foreach_nat_log_level
-#undef _
-} nat_log_level_t;
-
-#define nat_elog(_level, _str) \
-do \
- { \
- snat_main_t *sm = &snat_main; \
- if (PREDICT_FALSE (sm->log_level >= _level)) \
- { \
- ELOG_TYPE_DECLARE (e) = \
- { \
- .format = "nat-msg " _str, \
- .format_args = "", \
- }; \
- ELOG_DATA (&vlib_global_main.elog_main, e); \
- } \
- } while (0);
-
-#define nat_elog_addr(_level, _str, _addr) \
-do \
- { \
- if (PREDICT_FALSE (sm->log_level >= _level)) \
- { \
- ELOG_TYPE_DECLARE (e) = \
- { \
- .format = "nat-msg " _str " %d.%d.%d.%d", \
- .format_args = "i1i1i1i1", \
- }; \
- CLIB_PACKED(struct \
- { \
- u8 oct1; \
- u8 oct2; \
- u8 oct3; \
- u8 oct4; \
- }) *ed; \
- ed = ELOG_DATA (&vlib_global_main.elog_main, e); \
- ed->oct4 = _addr >> 24; \
- ed->oct3 = _addr >> 16; \
- ed->oct2 = _addr >> 8; \
- ed->oct1 = _addr; \
- } \
- } while (0);
-
-#define nat_elog_debug_handoff(_str, _tid, _fib, _src, _dst) \
-do \
- { \
- if (PREDICT_FALSE (sm->log_level >= SNAT_LOG_DEBUG)) \
- { \
- ELOG_TYPE_DECLARE (e) = \
- { \
- .format = "nat-msg " _str " ip src: %d.%d.%d.%d dst: %d.%d.%d.%d" \
- " tid from: %d to: %d fib: %d", \
- .format_args = "i1i1i1i1i1i1i1i1i4i4i4", \
- }; \
- CLIB_PACKED(struct \
- { \
- u8 src_oct1; \
- u8 src_oct2; \
- u8 src_oct3; \
- u8 src_oct4; \
- u8 dst_oct1; \
- u8 dst_oct2; \
- u8 dst_oct3; \
- u8 dst_oct4; \
- u32 ftid; \
- u32 ttid; \
- u32 fib; \
- }) *ed; \
- ed = ELOG_DATA (&vlib_global_main.elog_main, e); \
- ed->src_oct1 = _src >> 24; \
- ed->src_oct2 = _src >> 16; \
- ed->src_oct3 = _src >> 8; \
- ed->src_oct4 = _src; \
- ed->dst_oct1 = _dst >> 24; \
- ed->dst_oct2 = _dst >> 16; \
- ed->dst_oct3 = _dst >> 8; \
- ed->dst_oct4 = _dst; \
- ed->ftid = vlib_get_thread_index (); \
- ed->ttid = _tid; \
- ed->fib = _fib; \
- } \
- } while (0);
-
-#define nat_elog_debug_handoff_v2(_str, _prt, _fib, _src, _dst) \
-do \
- { \
- if (PREDICT_FALSE (sm->log_level >= SNAT_LOG_DEBUG)) \
- { \
- ELOG_TYPE_DECLARE (e) = \
- { \
- .format = "nat-msg " _str " ip_src:%d.%d.%d.%d ip_dst:%d.%d.%d.%d" \
- " tid:%d prt:%d fib:%d", \
- .format_args = "i1i1i1i1i1i1i1i1i4i4i4", \
- }; \
- CLIB_PACKED(struct \
- { \
- u8 src_oct1; \
- u8 src_oct2; \
- u8 src_oct3; \
- u8 src_oct4; \
- u8 dst_oct1; \
- u8 dst_oct2; \
- u8 dst_oct3; \
- u8 dst_oct4; \
- u32 tid; \
- u32 prt; \
- u32 fib; \
- }) *ed; \
- ed = ELOG_DATA (&vlib_global_main.elog_main, e); \
- ed->src_oct1 = _src >> 24; \
- ed->src_oct2 = _src >> 16; \
- ed->src_oct3 = _src >> 8; \
- ed->src_oct4 = _src; \
- ed->dst_oct1 = _dst >> 24; \
- ed->dst_oct2 = _dst >> 16; \
- ed->dst_oct3 = _dst >> 8; \
- ed->dst_oct4 = _dst; \
- ed->tid = vlib_get_thread_index (); \
- ed->prt = _prt; \
- ed->fib = _fib; \
- } \
- } while (0);
-
-#define nat_elog_X1(_level, _fmt, _arg, _val1) \
-do \
- { \
- snat_main_t *sm = &snat_main; \
- if (PREDICT_FALSE (sm->log_level >= _level)) \
- { \
- ELOG_TYPE_DECLARE (e) = \
- { \
- .format = "nat-msg " _fmt, \
- .format_args = _arg, \
- }; \
- CLIB_PACKED(struct \
- { \
- typeof (_val1) val1; \
- }) *ed; \
- ed = ELOG_DATA (&vlib_global_main.elog_main, e); \
- ed->val1 = _val1; \
- } \
- } while (0);
-
-#define nat_elog_notice(nat_elog_str) \
- nat_elog(SNAT_LOG_INFO, "[notice] " nat_elog_str)
-#define nat_elog_warn(nat_elog_str) \
- nat_elog(SNAT_LOG_WARNING, "[warning] " nat_elog_str)
-#define nat_elog_err(nat_elog_str) \
- nat_elog(SNAT_LOG_ERROR, "[error] " nat_elog_str)
-#define nat_elog_debug(nat_elog_str) \
- nat_elog(SNAT_LOG_DEBUG, "[debug] " nat_elog_str)
-#define nat_elog_info(nat_elog_str) \
- nat_elog(SNAT_LOG_INFO, "[info] " nat_elog_str)
-
-#define nat_elog_notice_X1(nat_elog_fmt_str, nat_elog_fmt_arg, nat_elog_val1) \
- nat_elog_X1(SNAT_LOG_NOTICE, "[notice] " nat_elog_fmt_str, nat_elog_fmt_arg, nat_elog_val1)
-#define nat_elog_warn_X1(nat_elog_fmt_str, nat_elog_fmt_arg, nat_elog_val1) \
- nat_elog_X1(SNAT_LOG_WARNING, "[warning] " nat_elog_fmt_str, nat_elog_fmt_arg, nat_elog_val1)
-#define nat_elog_err_X1(nat_elog_fmt_str, nat_elog_fmt_arg, nat_elog_val1) \
- nat_elog_X1(SNAT_LOG_ERROR, "[error] " nat_elog_fmt_str, nat_elog_fmt_arg, nat_elog_val1)
-#define nat_elog_debug_X1(nat_elog_fmt_str, nat_elog_fmt_arg, nat_elog_val1) \
- nat_elog_X1(SNAT_LOG_DEBUG, "[debug] " nat_elog_fmt_str, nat_elog_fmt_arg, nat_elog_val1)
-#define nat_elog_info_X1(nat_elog_fmt_str, nat_elog_fmt_arg, nat_elog_val1) \
- nat_elog_X1(SNAT_LOG_INFO, "[info] " nat_elog_fmt_str, nat_elog_fmt_arg, nat_elog_val1)
-
-/* ICMP session match functions */
-u32 icmp_match_in2out_fast (snat_main_t *sm, vlib_node_runtime_t *node,
- u32 thread_index, vlib_buffer_t *b0,
- ip4_header_t *ip0, ip4_address_t *addr, u16 *port,
- u32 *fib_index, nat_protocol_t *proto,
- snat_session_t **s0, u8 *dont_translate);
-u32 icmp_match_in2out_slow (snat_main_t *sm, vlib_node_runtime_t *node,
- u32 thread_index, vlib_buffer_t *b0,
- ip4_header_t *ip0, ip4_address_t *addr, u16 *port,
- u32 *fib_index, nat_protocol_t *proto,
- snat_session_t **s0, u8 *dont_translate);
-u32 icmp_match_out2in_fast (snat_main_t *sm, vlib_node_runtime_t *node,
- u32 thread_index, vlib_buffer_t *b0,
- ip4_header_t *ip0, ip4_address_t *addr, u16 *port,
- u32 *fib_index, nat_protocol_t *proto,
- snat_session_t **s0, u8 *dont_translate);
-u32 icmp_match_out2in_slow (snat_main_t *sm, vlib_node_runtime_t *node,
- u32 thread_index, vlib_buffer_t *b0,
- ip4_header_t *ip0, ip4_address_t *addr, u16 *port,
- u32 *fib_index, nat_protocol_t *proto,
- snat_session_t **s0, u8 *dont_translate);
-
-/* hairpinning functions */
-u32 snat_icmp_hairpinning (snat_main_t *sm, vlib_buffer_t *b0,
- u32 thread_index, ip4_header_t *ip0,
- icmp46_header_t *icmp0, u32 *required_thread_index);
-
-void nat_hairpinning_sm_unknown_proto (snat_main_t * sm, vlib_buffer_t * b,
- ip4_header_t * ip);
-
-int snat_hairpinning (vlib_main_t *vm, vlib_node_runtime_t *node,
- snat_main_t *sm, u32 thread_index, vlib_buffer_t *b0,
- ip4_header_t *ip0, udp_header_t *udp0,
- tcp_header_t *tcp0, u32 proto0, int do_trace,
- u32 *required_thread_index);
-
-/* Call back functions for clib_bihash_add_or_overwrite_stale */
-int nat44_i2o_is_idle_session_cb (clib_bihash_kv_8_8_t * kv, void *arg);
-int nat44_o2i_is_idle_session_cb (clib_bihash_kv_8_8_t * kv, void *arg);
-
-
/**
* @brief Enable NAT44 plugin
*
@@ -1379,39 +1037,6 @@ int nat44_set_session_limit (u32 session_limit, u32 vrf_id);
int nat44_update_session_limit (u32 session_limit, u32 vrf_id);
/**
- * @brief Free all NAT44 sessions
- */
-void nat44_sessions_clear ();
-
-/**
- * @brief Find or create NAT user
- *
- * @param sm snat global configuration data
- * @param addr IPv4 address
- * @param fib_index FIB table index
- * @param thread_index thread index
- *
- * @return NAT user data structure on success otherwise zero value
- */
-snat_user_t *nat_user_get_or_create (snat_main_t * sm,
- ip4_address_t * addr, u32 fib_index,
- u32 thread_index);
-
-/**
- * @brief Allocate new NAT session or recycle last used
- *
- * @param sm snat global configuration data
- * @param u NAT user
- * @param thread_index thread index
- * @param now time now
- *
- * @return session data structure on success otherwise zero value
- */
-snat_session_t *nat_session_alloc_or_recycle (snat_main_t * sm,
- snat_user_t * u,
- u32 thread_index, f64 now);
-
-/**
* @brief Free outside address and port pair
*
* @param addresses vector of outside addresses
@@ -1516,20 +1141,20 @@ typedef struct
u16 src_port, dst_port;
} tcp_udp_header_t;
-u8 *format_user_kvp (u8 * s, va_list * args);
-
u32 get_thread_idx_by_port (u16 e_port);
u8 *format_static_mapping_kvp (u8 *s, va_list *args);
u8 *format_session_kvp (u8 *s, va_list *args);
-u8 *format_user_kvp (u8 *s, va_list *args);
-
u32 nat_calc_bihash_buckets (u32 n_elts);
void nat44_addresses_free (snat_address_t **addresses);
+void nat44_ed_sessions_clear ();
+
+int nat44_ed_set_frame_queue_nelts (u32 frame_queue_nelts);
+
typedef enum
{
NAT_ED_TRNSL_ERR_SUCCESS = 0,
@@ -1548,7 +1173,7 @@ format_function_t format_nat_ed_translation_error;
format_function_t format_nat_6t_flow;
format_function_t format_ed_session_kvp;
-#endif /* __included_nat_h__ */
+#endif /* __included_nat44_ed_h__ */
/*
* fd.io coding-style-patch-verification: ON
*
diff --git a/src/plugins/nat/nat_affinity.c b/src/plugins/nat/nat44-ed/nat44_ed_affinity.c
index e7a7354c18d..6debe401292 100644
--- a/src/plugins/nat/nat_affinity.c
+++ b/src/plugins/nat/nat44-ed/nat44_ed_affinity.c
@@ -17,8 +17,10 @@
* @brief NAT plugin client-IP based session affinity for load-balancing
*/
-#include <nat/nat_affinity.h>
-#include <nat/nat.h>
+#include <nat/lib/log.h>
+
+#include <nat/nat44-ed/nat44_ed.h>
+#include <nat/nat44-ed/nat44_ed_affinity.h>
nat_affinity_main_t nat_affinity_main;
@@ -109,6 +111,7 @@ nat_affinity_get_per_service_list_head_index (void)
void
nat_affinity_flush_service (u32 affinity_per_service_list_head_index)
{
+ snat_main_t *sm = &snat_main;
nat_affinity_main_t *nam = &nat_affinity_main;
u32 elt_index;
dlist_elt_t *elt;
@@ -128,7 +131,7 @@ nat_affinity_flush_service (u32 affinity_per_service_list_head_index)
kv.key[1] = a->key.as_u64[1];
pool_put_index (nam->affinity_pool, elt->value);
if (clib_bihash_add_del_16_8 (&nam->affinity_hash, &kv, 0))
- nat_elog_warn ("affinity key del failed");
+ nat_elog_warn (sm, "affinity key del failed");
pool_put_index (nam->list_pool, elt_index);
}
pool_put_index (nam->list_pool, affinity_per_service_list_head_index);
@@ -141,6 +144,7 @@ nat_affinity_find_and_lock (ip4_address_t client_addr,
ip4_address_t service_addr, u8 proto,
u16 service_port, u8 * backend_index)
{
+ snat_main_t *sm = &snat_main;
nat_affinity_main_t *nam = &nat_affinity_main;
clib_bihash_kv_16_8_t kv, value;
nat_affinity_t *a;
@@ -164,7 +168,7 @@ nat_affinity_find_and_lock (ip4_address_t client_addr,
pool_put_index (nam->list_pool, a->per_service_index);
pool_put_index (nam->affinity_pool, value.value);
if (clib_bihash_add_del_16_8 (&nam->affinity_hash, &kv, 0))
- nat_elog_warn ("affinity key del failed");
+ nat_elog_warn (sm, "affinity key del failed");
rv = 1;
goto unlock;
}
@@ -180,6 +184,7 @@ unlock:
static int
affinity_is_expired_cb (clib_bihash_kv_16_8_t * kv, void *arg)
{
+ snat_main_t *sm = &snat_main;
nat_affinity_main_t *nam = &nat_affinity_main;
nat_affinity_t *a;
@@ -192,7 +197,7 @@ affinity_is_expired_cb (clib_bihash_kv_16_8_t * kv, void *arg)
pool_put_index (nam->list_pool, a->per_service_index);
pool_put_index (nam->affinity_pool, kv->value);
if (clib_bihash_add_del_16_8 (&nam->affinity_hash, kv, 0))
- nat_elog_warn ("affinity key del failed");
+ nat_elog_warn (sm, "affinity key del failed");
return 1;
}
}
@@ -207,6 +212,7 @@ nat_affinity_create_and_lock (ip4_address_t client_addr,
u32 sticky_time,
u32 affinity_per_service_list_head_index)
{
+ snat_main_t *sm = &snat_main;
nat_affinity_main_t *nam = &nat_affinity_main;
clib_bihash_kv_16_8_t kv, value;
nat_affinity_t *a;
@@ -218,7 +224,7 @@ nat_affinity_create_and_lock (ip4_address_t client_addr,
if (!clib_bihash_search_16_8 (&nam->affinity_hash, &kv, &value))
{
rv = 1;
- nat_elog_notice ("affinity key already exist");
+ nat_elog_notice (sm, "affinity key already exist");
goto unlock;
}
@@ -229,7 +235,7 @@ nat_affinity_create_and_lock (ip4_address_t client_addr,
affinity_is_expired_cb, NULL);
if (rv)
{
- nat_elog_notice ("affinity key add failed");
+ nat_elog_notice (sm, "affinity key add failed");
pool_put (nam->affinity_pool, a);
goto unlock;
}
diff --git a/src/plugins/nat/nat_affinity.h b/src/plugins/nat/nat44-ed/nat44_ed_affinity.h
index d6bda6a8ee1..2cfa9d29eb0 100644
--- a/src/plugins/nat/nat_affinity.h
+++ b/src/plugins/nat/nat44-ed/nat44_ed_affinity.h
@@ -17,8 +17,8 @@
* @brief NAT plugin client-IP based session affinity for load-balancing
*/
-#ifndef __included_nat_affinity_h__
-#define __included_nat_affinity_h__
+#ifndef __included_nat44_ed_affinity_h__
+#define __included_nat44_ed_affinity_h__
#include <vnet/ip/ip.h>
#include <vppinfra/bihash_16_8.h>
@@ -141,7 +141,7 @@ void nat_affinity_unlock (ip4_address_t client_addr,
ip4_address_t service_addr, u8 proto,
u16 service_port);
-#endif /* __included_nat_affinity_h__ */
+#endif /* __included_nat44_ed_affinity_h__ */
/*
* fd.io coding-style-patch-verification: ON
diff --git a/src/plugins/nat/nat44_api.c b/src/plugins/nat/nat44-ed/nat44_ed_api.c
index a5e29198c64..ea812da9633 100644
--- a/src/plugins/nat/nat44_api.c
+++ b/src/plugins/nat/nat44-ed/nat44_ed_api.c
@@ -26,17 +26,10 @@
#include <nat/lib/nat_inlines.h>
#include <nat/lib/ipfix_logging.h>
-#include <nat/nat.h>
+#include <nat/nat44-ed/nat44_ed.h>
-#include <nat/nat44.api_enum.h>
-#include <nat/nat44.api_types.h>
-
-#include <nat/nat44-ei/nat44_ei_ha.h>
-#include <nat/nat44-ei/nat44_ei.h>
-#include <nat/nat_inlines.h>
-
-#include <nat/nat44/inlines.h>
-#include <nat/nat44/ed_inlines.h>
+#include <nat/nat44-ed/nat44_ed.api_enum.h>
+#include <nat/nat44-ed/nat44_ed.api_types.h>
#define REPLY_MSG_ID_BASE sm->msg_id_base
#include <vlibapi/api_helper_macros.h>
@@ -48,12 +41,10 @@ vl_api_nat_control_ping_t_handler (vl_api_nat_control_ping_t * mp)
snat_main_t *sm = &snat_main;
int rv = 0;
- /* *INDENT-OFF* */
REPLY_MACRO2 (VL_API_NAT_CONTROL_PING_REPLY,
({
rmp->vpe_pid = ntohl (getpid ());
}));
- /* *INDENT-ON* */
}
static void
@@ -63,21 +54,19 @@ vl_api_nat_show_config_t_handler (vl_api_nat_show_config_t * mp)
snat_main_t *sm = &snat_main;
int rv = 0;
- /* *INDENT-OFF* */
REPLY_MACRO2_ZERO (VL_API_NAT_SHOW_CONFIG_REPLY,
({
rmp->translation_buckets = htonl (sm->translation_buckets);
- rmp->user_buckets = htonl (sm->user_buckets);
- rmp->max_translations_per_user = htonl (sm->max_translations_per_user);
+ rmp->user_buckets = 0;
+ rmp->max_translations_per_user = 0;
rmp->outside_vrf_id = htonl (sm->outside_vrf_id);
rmp->inside_vrf_id = htonl (sm->inside_vrf_id);
rmp->static_mapping_only = sm->static_mapping_only;
rmp->static_mapping_connection_tracking =
sm->static_mapping_connection_tracking;
- rmp->endpoint_dependent = sm->endpoint_dependent;
- rmp->out2in_dpo = sm->out2in_dpo;
+ rmp->endpoint_dependent = 1;
+ rmp->out2in_dpo = 0;
}));
- /* *INDENT-ON* */
}
static void
@@ -87,23 +76,22 @@ vl_api_nat_show_config_2_t_handler (vl_api_nat_show_config_2_t * mp)
snat_main_t *sm = &snat_main;
int rv = 0;
- /* *INDENT-OFF* */
REPLY_MACRO2_ZERO (VL_API_NAT_SHOW_CONFIG_2_REPLY,
({
rmp->translation_buckets = htonl (sm->translation_buckets);
- rmp->user_buckets = htonl (sm->user_buckets);
- rmp->max_translations_per_user = htonl (sm->max_translations_per_user);
+ rmp->user_buckets = 0;
+ rmp->max_translations_per_user = 0;
rmp->outside_vrf_id = htonl (sm->outside_vrf_id);
rmp->inside_vrf_id = htonl (sm->inside_vrf_id);
rmp->static_mapping_only = sm->static_mapping_only;
rmp->static_mapping_connection_tracking =
sm->static_mapping_connection_tracking;
- rmp->endpoint_dependent = sm->endpoint_dependent;
- rmp->out2in_dpo = sm->out2in_dpo;
- rmp->max_translations_per_thread = clib_net_to_host_u32(sm->max_translations_per_thread);
- rmp->max_users_per_thread = clib_net_to_host_u32(sm->max_users_per_thread);
+ rmp->endpoint_dependent = 1;
+ rmp->out2in_dpo = 0;
+ rmp->max_translations_per_thread =
+ clib_net_to_host_u32 (sm->max_translations_per_thread);
+ rmp->max_users_per_thread = 0;
}));
- /* *INDENT-ON* */
}
static void
@@ -115,18 +103,19 @@ vl_api_nat44_show_running_config_t_handler (vl_api_nat44_show_running_config_t
nat44_config_t *rc = &sm->rconfig;
int rv = 0;
- /* *INDENT-OFF* */
REPLY_MACRO2_ZERO (VL_API_NAT44_SHOW_RUNNING_CONFIG_REPLY,
({
rmp->inside_vrf = htonl (rc->inside_vrf);
rmp->outside_vrf = htonl (rc->outside_vrf);
- rmp->users = htonl (rc->users);
- rmp->sessions = htonl (rc->sessions);
- rmp->user_sessions = htonl (rc->user_sessions);
- rmp->user_buckets = htonl (sm->user_buckets);
+ rmp->sessions = htonl (rc->sessions);
rmp->translation_buckets = htonl (sm->translation_buckets);
+ // OBSOLETE
+ rmp->users = 0;
+ rmp->user_buckets = 0;
+ rmp->user_sessions = 0;
+
rmp->timeouts.udp = htonl (sm->timeouts.udp);
rmp->timeouts.tcp_established = htonl (sm->timeouts.tcp.established);
rmp->timeouts.tcp_transitory = htonl (sm->timeouts.tcp.transitory);
@@ -135,20 +124,12 @@ vl_api_nat44_show_running_config_t_handler (vl_api_nat44_show_running_config_t
rmp->forwarding_enabled = sm->forwarding_enabled == 1;
// consider how to split functionality between subplugins
rmp->ipfix_logging_enabled = nat_ipfix_logging_enabled ();
-
- if (rc->endpoint_dependent)
- rmp->flags |= NAT44_IS_ENDPOINT_DEPENDENT;
- else
- rmp->flags |= NAT44_IS_ENDPOINT_INDEPENDENT;
-
+ rmp->flags |= NAT44_IS_ENDPOINT_DEPENDENT;
if (rc->static_mapping_only)
rmp->flags |= NAT44_IS_STATIC_MAPPING_ONLY;
if (rc->connection_tracking)
rmp->flags |= NAT44_IS_CONNECTION_TRACKING;
- if (rc->out2in_dpo)
- rmp->flags |= NAT44_IS_OUT2IN_DPO;
}));
- /* *INDENT-ON* */
}
static void
@@ -207,10 +188,10 @@ vl_api_nat_worker_dump_t_handler (vl_api_nat_worker_dump_t * mp)
if (!reg)
return;
- /* *INDENT-OFF* */
vec_foreach (worker_index, sm->workers)
- send_nat_worker_details(*worker_index, reg, mp->context);
- /* *INDENT-ON* */
+ {
+ send_nat_worker_details (*worker_index, reg, mp->context);
+ }
}
static void
@@ -218,7 +199,7 @@ vl_api_nat44_session_cleanup_t_handler (vl_api_nat44_session_cleanup_t * mp)
{
snat_main_t *sm = &snat_main;
vl_api_nat44_session_cleanup_reply_t *rmp;
- int rv = 0;
+ int rv = VNET_API_ERROR_UNSUPPORTED;
REPLY_MACRO (VL_API_NAT44_SESSION_CLEANUP_REPLY);
}
@@ -262,24 +243,28 @@ static void
if (mp->enable)
{
- c.endpoint_dependent = mp->flags & NAT44_API_IS_ENDPOINT_DEPENDENT;
- c.static_mapping_only = mp->flags & NAT44_API_IS_STATIC_MAPPING_ONLY;
- c.connection_tracking = mp->flags & NAT44_API_IS_CONNECTION_TRACKING;
- c.out2in_dpo = mp->flags & NAT44_API_IS_OUT2IN_DPO;
-
- c.inside_vrf = ntohl (mp->inside_vrf);
- c.outside_vrf = ntohl (mp->outside_vrf);
-
- c.users = ntohl (mp->users);
+ if (mp->flags & NAT44_API_IS_OUT2IN_DPO || mp->users ||
+ mp->user_sessions)
+ {
+ rv = VNET_API_ERROR_UNSUPPORTED;
+ }
+ else
+ {
+ c.static_mapping_only = mp->flags & NAT44_API_IS_STATIC_MAPPING_ONLY;
+ c.connection_tracking = mp->flags & NAT44_API_IS_CONNECTION_TRACKING;
- c.sessions = ntohl (mp->sessions);
+ c.inside_vrf = ntohl (mp->inside_vrf);
+ c.outside_vrf = ntohl (mp->outside_vrf);
- c.user_sessions = ntohl (mp->user_sessions);
+ c.sessions = ntohl (mp->sessions);
- rv = nat44_plugin_enable (c);
+ rv = nat44_plugin_enable (c);
+ }
}
else
- rv = nat44_plugin_disable ();
+ {
+ rv = nat44_plugin_disable ();
+ }
REPLY_MACRO (VL_API_NAT44_PLUGIN_ENABLE_DISABLE_REPLY);
}
@@ -322,7 +307,6 @@ vl_api_nat_get_timeouts_t_handler (vl_api_nat_get_timeouts_t * mp)
vl_api_nat_get_timeouts_reply_t *rmp;
int rv = 0;
- /* *INDENT-OFF* */
REPLY_MACRO2 (VL_API_NAT_GET_TIMEOUTS_REPLY,
({
rmp->udp = htonl (sm->timeouts.udp);
@@ -330,32 +314,6 @@ vl_api_nat_get_timeouts_t_handler (vl_api_nat_get_timeouts_t * mp)
rmp->tcp_transitory = htonl (sm->timeouts.tcp.transitory);
rmp->icmp = htonl (sm->timeouts.icmp);
}))
- /* *INDENT-ON* */
-}
-
-static void
-vl_api_nat_set_fq_options_t_handler (vl_api_nat_set_fq_options_t *mp)
-{
- snat_main_t *sm = &snat_main;
- vl_api_nat_set_fq_options_reply_t *rmp;
- int rv = 0;
- u32 frame_queue_nelts = ntohl (mp->frame_queue_nelts);
- rv = snat_set_frame_queue_nelts (frame_queue_nelts);
- REPLY_MACRO (VL_API_NAT_SET_FQ_OPTIONS_REPLY);
-}
-
-static void
-vl_api_nat_show_fq_options_t_handler (vl_api_nat_show_fq_options_t *mp)
-{
- vl_api_nat_show_fq_options_reply_t *rmp;
- snat_main_t *sm = &snat_main;
- int rv = 0;
- /* clang-format off */
- REPLY_MACRO2_ZERO (VL_API_NAT_SHOW_FQ_OPTIONS_REPLY,
- ({
- rmp->frame_queue_nelts = htonl (sm->frame_queue_nelts);
- }));
- /* clang-format on */
}
static void
@@ -364,40 +322,7 @@ static void
{
snat_main_t *sm = &snat_main;
vl_api_nat_set_addr_and_port_alloc_alg_reply_t *rmp;
- int rv = 0;
- u16 port_start, port_end;
-
- if (sm->endpoint_dependent)
- {
- rv = VNET_API_ERROR_UNSUPPORTED;
- goto send_reply;
- }
-
- switch (mp->alg)
- {
- case NAT_ADDR_AND_PORT_ALLOC_ALG_DEFAULT:
- nat44_ei_set_alloc_default ();
- break;
- case NAT_ADDR_AND_PORT_ALLOC_ALG_MAPE:
- nat44_ei_set_alloc_mape (ntohs (mp->psid), mp->psid_offset,
- mp->psid_length);
- break;
- case NAT_ADDR_AND_PORT_ALLOC_ALG_RANGE:
- port_start = ntohs (mp->start_port);
- port_end = ntohs (mp->end_port);
- if (port_end <= port_start)
- {
- rv = VNET_API_ERROR_INVALID_VALUE;
- goto send_reply;
- }
- nat44_ei_set_alloc_range (port_start, port_end);
- break;
- default:
- rv = VNET_API_ERROR_INVALID_VALUE;
- break;
- }
-
-send_reply:
+ int rv = VNET_API_ERROR_UNSUPPORTED;
REPLY_MACRO (VL_API_NAT_SET_ADDR_AND_PORT_ALLOC_ALG_REPLY);
}
@@ -407,19 +332,8 @@ static void
{
snat_main_t *sm = &snat_main;
vl_api_nat_get_addr_and_port_alloc_alg_reply_t *rmp;
- int rv = 0;
-
- /* *INDENT-OFF* */
- REPLY_MACRO2 (VL_API_NAT_GET_ADDR_AND_PORT_ALLOC_ALG_REPLY,
- ({
- rmp->alg = sm->addr_and_port_alloc_alg;
- rmp->psid_offset = sm->psid_offset;
- rmp->psid_length = sm->psid_length;
- rmp->psid = htons (sm->psid);
- rmp->start_port = htons (sm->start_port);
- rmp->end_port = htons (sm->end_port);
- }))
- /* *INDENT-ON* */
+ int rv = VNET_API_ERROR_UNSUPPORTED;
+ REPLY_MACRO (VL_API_NAT_GET_ADDR_AND_PORT_ALLOC_ALG_REPLY);
}
static void
@@ -444,13 +358,11 @@ vl_api_nat_get_mss_clamping_t_handler (vl_api_nat_get_mss_clamping_t * mp)
vl_api_nat_get_mss_clamping_reply_t *rmp;
int rv = 0;
- /* *INDENT-OFF* */
REPLY_MACRO2 (VL_API_NAT_GET_MSS_CLAMPING_REPLY,
({
rmp->enable = sm->mss_clamping ? 1 : 0;
rmp->mss_value = htons (sm->mss_clamping);
}))
- /* *INDENT-ON* */
}
static void
@@ -458,14 +370,7 @@ vl_api_nat_ha_set_listener_t_handler (vl_api_nat_ha_set_listener_t * mp)
{
snat_main_t *sm = &snat_main;
vl_api_nat_ha_set_listener_reply_t *rmp;
- ip4_address_t addr;
- int rv;
-
- memcpy (&addr, &mp->ip_address, sizeof (addr));
- rv =
- nat_ha_set_listener (&addr, clib_net_to_host_u16 (mp->port),
- clib_net_to_host_u32 (mp->path_mtu));
-
+ int rv = VNET_API_ERROR_UNSUPPORTED;
REPLY_MACRO (VL_API_NAT_HA_SET_LISTENER_REPLY);
}
@@ -474,21 +379,8 @@ vl_api_nat_ha_get_listener_t_handler (vl_api_nat_ha_get_listener_t * mp)
{
snat_main_t *sm = &snat_main;
vl_api_nat_ha_get_listener_reply_t *rmp;
- int rv = 0;
- ip4_address_t addr;
- u16 port;
- u32 path_mtu;
-
- nat_ha_get_listener (&addr, &port, &path_mtu);
-
- /* *INDENT-OFF* */
- REPLY_MACRO2 (VL_API_NAT_HA_GET_LISTENER_REPLY,
- ({
- clib_memcpy (rmp->ip_address, &addr, sizeof (ip4_address_t));
- rmp->port = clib_host_to_net_u16 (port);
- rmp->path_mtu = clib_host_to_net_u32 (path_mtu);
- }))
- /* *INDENT-ON* */
+ int rv = VNET_API_ERROR_UNSUPPORTED;
+ REPLY_MACRO (VL_API_NAT_HA_GET_LISTENER_REPLY);
}
static void
@@ -496,14 +388,7 @@ vl_api_nat_ha_set_failover_t_handler (vl_api_nat_ha_set_failover_t * mp)
{
snat_main_t *sm = &snat_main;
vl_api_nat_ha_set_failover_reply_t *rmp;
- ip4_address_t addr;
- int rv;
-
- memcpy (&addr, &mp->ip_address, sizeof (addr));
- rv =
- nat_ha_set_failover (&addr, clib_net_to_host_u16 (mp->port),
- clib_net_to_host_u32 (mp->session_refresh_interval));
-
+ int rv = VNET_API_ERROR_UNSUPPORTED;
REPLY_MACRO (VL_API_NAT_HA_SET_FAILOVER_REPLY);
}
@@ -512,21 +397,8 @@ vl_api_nat_ha_get_failover_t_handler (vl_api_nat_ha_get_failover_t * mp)
{
snat_main_t *sm = &snat_main;
vl_api_nat_ha_get_failover_reply_t *rmp;
- int rv = 0;
- ip4_address_t addr;
- u16 port;
- u32 session_refresh_interval;
-
- nat_ha_get_failover (&addr, &port, &session_refresh_interval);
-
- /* *INDENT-OFF* */
- REPLY_MACRO2 (VL_API_NAT_HA_GET_FAILOVER_REPLY,
- ({
- clib_memcpy (rmp->ip_address, &addr, sizeof (ip4_address_t));
- rmp->port = clib_host_to_net_u16 (port);
- rmp->session_refresh_interval = clib_host_to_net_u32 (session_refresh_interval);
- }))
- /* *INDENT-ON* */
+ int rv = VNET_API_ERROR_UNSUPPORTED;
+ REPLY_MACRO (VL_API_NAT_HA_GET_FAILOVER_REPLY);
}
static void
@@ -534,47 +406,16 @@ vl_api_nat_ha_flush_t_handler (vl_api_nat_ha_flush_t * mp)
{
snat_main_t *sm = &snat_main;
vl_api_nat_ha_flush_reply_t *rmp;
- int rv = 0;
-
- nat_ha_flush (0);
-
+ int rv = VNET_API_ERROR_UNSUPPORTED;
REPLY_MACRO (VL_API_NAT_HA_FLUSH_REPLY);
}
static void
-nat_ha_resync_completed_event_cb (u32 client_index, u32 pid, u32 missed_count)
-{
- snat_main_t *sm = &snat_main;
- vl_api_registration_t *reg;
- vl_api_nat_ha_resync_completed_event_t *mp;
-
- reg = vl_api_client_index_to_registration (client_index);
- if (!reg)
- return;
-
- mp = vl_msg_api_alloc (sizeof (*mp));
- clib_memset (mp, 0, sizeof (*mp));
- mp->client_index = client_index;
- mp->pid = pid;
- mp->missed_count = clib_host_to_net_u32 (missed_count);
- mp->_vl_msg_id =
- ntohs (VL_API_NAT_HA_RESYNC_COMPLETED_EVENT + sm->msg_id_base);
-
- vl_api_send_msg (reg, (u8 *) mp);
-}
-
-static void
vl_api_nat_ha_resync_t_handler (vl_api_nat_ha_resync_t * mp)
{
snat_main_t *sm = &snat_main;
vl_api_nat_ha_resync_reply_t *rmp;
- int rv;
-
- rv =
- nat_ha_resync (mp->client_index, mp->pid,
- mp->want_resync_event ? nat_ha_resync_completed_event_cb :
- NULL);
-
+ int rv = VNET_API_ERROR_UNSUPPORTED;
REPLY_MACRO (VL_API_NAT_HA_RESYNC_REPLY);
}
@@ -583,10 +424,7 @@ vl_api_nat44_del_user_t_handler (vl_api_nat44_del_user_t * mp)
{
snat_main_t *sm = &snat_main;
vl_api_nat44_del_user_reply_t *rmp;
- ip4_address_t addr;
- int rv;
- memcpy (&addr.as_u8, mp->ip_address, 4);
- rv = nat44_ei_user_del (&addr, ntohl (mp->fib_index));
+ int rv = VNET_API_ERROR_UNSUPPORTED;
REPLY_MACRO (VL_API_NAT44_DEL_USER_REPLY);
}
@@ -639,9 +477,6 @@ static void
if (rv)
goto send_reply;
- if (sm->out2in_dpo)
- nat44_add_del_address_dpo (this_addr, is_add);
-
increment_v4_address (&this_addr);
}
@@ -686,12 +521,10 @@ vl_api_nat44_address_dump_t_handler (vl_api_nat44_address_dump_t * mp)
if (!reg)
return;
- /* *INDENT-OFF* */
vec_foreach (a, sm->addresses)
send_nat44_address_details (a, reg, mp->context, 0);
vec_foreach (a, sm->twice_nat_addresses)
send_nat44_address_details (a, reg, mp->context, 1);
- /* *INDENT-ON* */
}
static void
@@ -750,12 +583,10 @@ vl_api_nat44_interface_dump_t_handler (vl_api_nat44_interface_dump_t * mp)
if (!reg)
return;
- /* *INDENT-OFF* */
pool_foreach (i, sm->interfaces)
{
send_nat44_interface_details(i, reg, mp->context);
}
- /* *INDENT-ON* */
}
static void
@@ -810,12 +641,10 @@ static void
if (!reg)
return;
- /* *INDENT-OFF* */
pool_foreach (i, sm->output_feature_interfaces)
{
- send_nat44_interface_output_feature_details(i, reg, mp->context);
+ send_nat44_interface_output_feature_details (i, reg, mp->context);
}
- /* *INDENT-ON* */
}
static void
@@ -1004,13 +833,11 @@ vl_api_nat44_static_mapping_dump_t_handler (vl_api_nat44_static_mapping_dump_t
if (!reg)
return;
- /* *INDENT-OFF* */
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);
}
- /* *INDENT-ON* */
for (j = 0; j < vec_len (sm->to_resolve); j++)
{
@@ -1126,7 +953,6 @@ static void
if (!reg)
return;
- /* *INDENT-OFF* */
pool_foreach (m, sm->static_mappings)
{
if (is_identity_static_mapping(m) && !is_lb_static_mapping (m))
@@ -1137,7 +963,6 @@ static void
}
}
}
- /* *INDENT-ON* */
for (j = 0; j < vec_len (sm->to_resolve); j++)
{
@@ -1209,14 +1034,45 @@ vl_api_nat44_interface_addr_dump_t_handler (vl_api_nat44_interface_addr_dump_t
if (!reg)
return;
- /* *INDENT-OFF* */
vec_foreach (i, sm->auto_add_sw_if_indices)
- send_nat44_interface_addr_details(*i, reg, mp->context, 0);
+ {
+ send_nat44_interface_addr_details (*i, reg, mp->context, 0);
+ }
vec_foreach (i, sm->auto_add_sw_if_indices_twice_nat)
- send_nat44_interface_addr_details(*i, reg, mp->context, 1);
- /* *INDENT-ON* */
+ {
+ send_nat44_interface_addr_details (*i, reg, mp->context, 1);
+ }
}
+/* user (internal host) key */
+typedef struct
+{
+ union
+ {
+ struct
+ {
+ ip4_address_t addr;
+ u32 fib_index;
+ };
+ u64 as_u64;
+ };
+} snat_user_key_t;
+
+typedef struct
+{
+ ip4_address_t addr;
+ u32 fib_index;
+ u32 nsessions;
+ u32 nstaticsessions;
+} snat_user_t;
+
+typedef struct
+{
+ u32 user_buckets;
+ snat_user_t *users;
+ clib_bihash_8_8_t user_hash;
+} user_create_helper_t;
+
static void
send_nat44_user_details (snat_user_t * u, vl_api_registration_t * reg,
u32 context)
@@ -1244,8 +1100,7 @@ send_nat44_user_details (snat_user_t * u, vl_api_registration_t * reg,
}
static void
-nat_ed_user_create_helper (snat_main_per_thread_data_t * tsm,
- snat_session_t * s)
+nat_ed_user_create_helper (user_create_helper_t *uch, snat_session_t *s)
{
snat_user_key_t k;
k.addr = s->in2out.addr;
@@ -1253,19 +1108,20 @@ nat_ed_user_create_helper (snat_main_per_thread_data_t * tsm,
clib_bihash_kv_8_8_t key, value;
key.key = k.as_u64;
snat_user_t *u;
- if (clib_bihash_search_8_8 (&tsm->user_hash, &key, &value))
+
+ if (clib_bihash_search_8_8 (&uch->user_hash, &key, &value))
{
- pool_get (tsm->users, u);
+ pool_get (uch->users, u);
u->addr = k.addr;
u->fib_index = k.fib_index;
u->nsessions = 0;
u->nstaticsessions = 0;
- key.value = u - tsm->users;
- clib_bihash_add_del_8_8 (&tsm->user_hash, &key, 1);
+ key.value = u - uch->users;
+ clib_bihash_add_del_8_8 (&uch->user_hash, &key, 1);
}
else
{
- u = pool_elt_at_index (tsm->users, value.value);
+ u = pool_elt_at_index (uch->users, value.value);
}
if (snat_is_session_static (s))
{
@@ -1277,56 +1133,63 @@ nat_ed_user_create_helper (snat_main_per_thread_data_t * tsm,
}
}
+u8 *
+format_user_kvp (u8 *s, va_list *args)
+{
+ clib_bihash_kv_8_8_t *v = va_arg (*args, clib_bihash_kv_8_8_t *);
+ snat_user_key_t k;
+ k.as_u64 = v->key;
+ s = format (s, "%U fib %d user-index %llu", format_ip4_address, &k.addr,
+ k.fib_index, v->value);
+ return s;
+}
+
static void
-nat_ed_users_create (snat_main_per_thread_data_t * tsm)
+nat_ed_users_create (snat_main_per_thread_data_t *tsm,
+ user_create_helper_t *uch)
{
snat_session_t *s;
- /* *INDENT-OFF* */
- pool_foreach (s, tsm->sessions) { nat_ed_user_create_helper (tsm, s); }
- /* *INDENT-ON* */
+ clib_bihash_init_8_8 (&uch->user_hash, "users", uch->user_buckets, 0);
+ clib_bihash_set_kvp_format_fn_8_8 (&uch->user_hash, format_user_kvp);
+ pool_foreach (s, tsm->sessions)
+ {
+ nat_ed_user_create_helper (uch, s);
+ }
}
static void
-nat_ed_users_destroy (snat_main_per_thread_data_t * tsm)
+nat_ed_users_destroy (user_create_helper_t *uch)
{
- snat_user_t *u;
- /* *INDENT-OFF* */
- pool_flush (u, tsm->users, { });
- /* *INDENT-ON* */
- clib_bihash_free_8_8 (&tsm->user_hash);
- clib_bihash_init_8_8 (&tsm->user_hash, "users", snat_main.user_buckets, 0);
- clib_bihash_set_kvp_format_fn_8_8 (&tsm->user_hash, format_user_kvp);
+ pool_free (uch->users);
+ clib_bihash_free_8_8 (&uch->user_hash);
}
static void
vl_api_nat44_user_dump_t_handler (vl_api_nat44_user_dump_t * mp)
{
+ user_create_helper_t uch;
vl_api_registration_t *reg;
snat_main_t *sm = &snat_main;
snat_main_per_thread_data_t *tsm;
snat_user_t *u;
+ clib_memset (&uch, 0, sizeof (uch));
+
+ uch.user_buckets = nat_calc_bihash_buckets (1024);
+
reg = vl_api_client_index_to_registration (mp->client_index);
if (!reg)
return;
- /* *INDENT-OFF* */
vec_foreach (tsm, sm->per_thread_data)
{
- if (sm->endpoint_dependent)
- {
- nat_ed_users_create (tsm);
- }
- pool_foreach (u, tsm->users)
- {
- send_nat44_user_details (u, reg, mp->context);
- }
- if (sm->endpoint_dependent)
+ nat_ed_users_create (tsm, &uch);
+ pool_foreach (u, uch.users)
{
- nat_ed_users_destroy (tsm);
+ send_nat44_user_details (u, reg, mp->context);
}
+ nat_ed_users_destroy (&uch);
}
- /* *INDENT-ON* */
}
static void
@@ -1386,15 +1249,11 @@ static void
vl_api_nat44_user_session_dump_t_handler (vl_api_nat44_user_session_dump_t *
mp)
{
- vl_api_registration_t *reg;
- snat_main_t *sm = &snat_main;
snat_main_per_thread_data_t *tsm;
- snat_session_t *s;
- clib_bihash_kv_8_8_t key, value;
+ snat_main_t *sm = &snat_main;
+ vl_api_registration_t *reg;
snat_user_key_t ukey;
- snat_user_t *u;
- u32 session_index, head_index, elt_index;
- dlist_elt_t *head, *elt;
+ snat_session_t *s;
ip4_header_t ip;
reg = vl_api_client_index_to_registration (mp->client_index);
@@ -1404,48 +1263,19 @@ vl_api_nat44_user_session_dump_t_handler (vl_api_nat44_user_session_dump_t *
clib_memcpy (&ukey.addr, mp->ip_address, 4);
ip.src_address.as_u32 = ukey.addr.as_u32;
ukey.fib_index = fib_table_find (FIB_PROTOCOL_IP4, ntohl (mp->vrf_id));
- key.key = ukey.as_u64;
if (sm->num_workers > 1)
tsm =
vec_elt_at_index (sm->per_thread_data,
sm->worker_in2out_cb (&ip, ukey.fib_index, 0));
else
tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
- if (!sm->endpoint_dependent)
- {
- if (clib_bihash_search_8_8 (&tsm->user_hash, &key, &value))
- return;
- u = pool_elt_at_index (tsm->users, value.value);
- if (!u->nsessions && !u->nstaticsessions)
- return;
-
- 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);
- session_index = elt->value;
- while (session_index != ~0)
- {
- s = pool_elt_at_index (tsm->sessions, session_index);
- send_nat44_user_session_details (s, reg, mp->context);
-
- elt_index = elt->next;
- elt = pool_elt_at_index (tsm->list_pool, elt_index);
- session_index = elt->value;
- }
- }
- else
- {
- /* *INDENT-OFF* */
pool_foreach (s, tsm->sessions) {
if (s->in2out.addr.as_u32 == ukey.addr.as_u32)
{
send_nat44_user_session_details (s, reg, mp->context);
}
}
- /* *INDENT-ON* */
- }
}
static nat44_lb_addr_port_t *
@@ -1483,12 +1313,6 @@ static void
nat_protocol_t proto;
u8 *tag = 0;
- if (!sm->endpoint_dependent)
- {
- rv = VNET_API_ERROR_UNSUPPORTED;
- goto send_reply;
- }
-
locals =
unformat_nat44_lb_addr_port (mp->locals,
clib_net_to_host_u32 (mp->local_num));
@@ -1513,8 +1337,6 @@ static void
vec_free (locals);
vec_free (tag);
-
-send_reply:
REPLY_MACRO (VL_API_NAT44_ADD_DEL_LB_STATIC_MAPPING_REPLY);
}
@@ -1528,12 +1350,6 @@ static void
ip4_address_t e_addr, l_addr;
nat_protocol_t proto;
- if (!sm->endpoint_dependent)
- {
- rv = VNET_API_ERROR_UNSUPPORTED;
- goto send_reply;
- }
-
clib_memcpy (&e_addr, mp->external_addr, 4);
clib_memcpy (&l_addr, mp->local.addr, 4);
proto = ip_proto_to_nat_proto (mp->protocol);
@@ -1548,7 +1364,6 @@ static void
local.vrf_id),
mp->local.probability, mp->is_add);
-send_reply:
REPLY_MACRO (VL_API_NAT44_LB_STATIC_MAPPING_ADD_DEL_LOCAL_REPLY);
}
@@ -1586,7 +1401,6 @@ send_nat44_lb_static_mapping_details (snat_static_mapping_t * m,
strncpy ((char *) rmp->tag, (char *) m->tag, vec_len (m->tag));
locals = (vl_api_nat44_lb_addr_port_t *) rmp->locals;
- /* *INDENT-OFF* */
pool_foreach (ap, m->locals)
{
clib_memcpy (locals->addr, &(ap->addr), 4);
@@ -1596,7 +1410,6 @@ send_nat44_lb_static_mapping_details (snat_static_mapping_t * m,
locals++;
local_num++;
}
- /* *INDENT-ON* */
rmp->local_num = ntohl (local_num);
vl_api_send_msg (reg, (u8 *) rmp);
@@ -1610,20 +1423,15 @@ static void
snat_main_t *sm = &snat_main;
snat_static_mapping_t *m;
- if (!sm->endpoint_dependent)
- return;
-
reg = vl_api_client_index_to_registration (mp->client_index);
if (!reg)
return;
- /* *INDENT-OFF* */
pool_foreach (m, sm->static_mappings)
{
if (is_lb_static_mapping(m))
send_nat44_lb_static_mapping_details (m, reg, mp->context);
}
- /* *INDENT-ON* */
}
static void
@@ -1636,23 +1444,17 @@ vl_api_nat44_del_session_t_handler (vl_api_nat44_del_session_t * mp)
u32 vrf_id;
int rv = 0;
u8 is_in;
- nat_protocol_t proto;
memcpy (&addr.as_u8, mp->address, 4);
port = mp->port;
vrf_id = clib_net_to_host_u32 (mp->vrf_id);
- proto = ip_proto_to_nat_proto (mp->protocol);
memcpy (&eh_addr.as_u8, mp->ext_host_address, 4);
eh_port = mp->ext_host_port;
is_in = mp->flags & NAT_API_IS_INSIDE;
- if (mp->flags & NAT_API_IS_EXT_HOST_VALID)
- rv =
- nat44_del_ed_session (sm, &addr, port, &eh_addr, eh_port, mp->protocol,
- vrf_id, is_in);
- else
- rv = nat44_ei_del_session (sm, &addr, port, proto, vrf_id, is_in);
+ rv = nat44_del_ed_session (sm, &addr, port, &eh_addr, eh_port, mp->protocol,
+ vrf_id, is_in);
REPLY_MACRO (VL_API_NAT44_DEL_SESSION_REPLY);
}
@@ -1661,47 +1463,10 @@ static void
vl_api_nat44_forwarding_enable_disable_t_handler
(vl_api_nat44_forwarding_enable_disable_t * mp)
{
- snat_main_t *sm = &snat_main;
vl_api_nat44_forwarding_enable_disable_reply_t *rmp;
+ snat_main_t *sm = &snat_main;
int rv = 0;
- u32 *ses_to_be_removed = 0, *ses_index;
- snat_main_per_thread_data_t *tsm;
- snat_session_t *s;
-
- sm->forwarding_enabled = mp->enable != 0;
-
- if (mp->enable == 0)
- {
- /* *INDENT-OFF* */
- vec_foreach (tsm, sm->per_thread_data)
- {
- pool_foreach (s, tsm->sessions)
- {
- if (is_fwd_bypass_session(s))
- {
- vec_add1 (ses_to_be_removed, s - tsm->sessions);
- }
- }
- if(sm->endpoint_dependent){
- vec_foreach (ses_index, ses_to_be_removed)
- {
- s = pool_elt_at_index(tsm->sessions, ses_index[0]);
- nat_free_session_data (sm, s, tsm - sm->per_thread_data, 0);
- nat_ed_session_delete (sm, s, tsm - sm->per_thread_data, 1);
- }
- }else{
- vec_foreach (ses_index, ses_to_be_removed)
- {
- s = pool_elt_at_index(tsm->sessions, ses_index[0]);
- nat_free_session_data (sm, s, tsm - sm->per_thread_data, 0);
- nat44_delete_session (sm, s, tsm - sm->per_thread_data);
- }
- }
- vec_free (ses_to_be_removed);
- }
- /* *INDENT-ON* */
- }
-
+ nat44_ed_forwarding_enable_disable (mp->enable);
REPLY_MACRO (VL_API_NAT44_FORWARDING_ENABLE_DISABLE_REPLY);
}
@@ -1728,9 +1493,35 @@ static void
vl_api_send_msg (reg, (u8 *) rmp);
}
+static void
+vl_api_nat44_ed_set_fq_options_t_handler (vl_api_nat44_ed_set_fq_options_t *mp)
+{
+ snat_main_t *sm = &snat_main;
+ vl_api_nat44_ed_set_fq_options_reply_t *rmp;
+ int rv = 0;
+ u32 frame_queue_nelts = ntohl (mp->frame_queue_nelts);
+ rv = nat44_ed_set_frame_queue_nelts (frame_queue_nelts);
+ REPLY_MACRO (VL_API_NAT44_ED_SET_FQ_OPTIONS_REPLY);
+}
+
+static void
+vl_api_nat44_ed_show_fq_options_t_handler (
+ vl_api_nat44_ed_show_fq_options_t *mp)
+{
+ snat_main_t *sm = &snat_main;
+ vl_api_nat44_ed_show_fq_options_reply_t *rmp;
+ int rv = 0;
+ /* clang-format off */
+ REPLY_MACRO2_ZERO (VL_API_NAT44_ED_SHOW_FQ_OPTIONS_REPLY,
+ ({
+ rmp->frame_queue_nelts = htonl (sm->frame_queue_nelts);
+ }));
+ /* clang-format on */
+}
+
/* API definitions */
#include <vnet/format_fns.h>
-#include <nat/nat44.api.c>
+#include <nat/nat44-ed/nat44_ed.api.c>
/* Set up the API message handling tables */
clib_error_t *
diff --git a/src/plugins/nat/nat44_classify.c b/src/plugins/nat/nat44-ed/nat44_ed_classify.c
index 85f8c64afd5..5a9f4e42657 100644
--- a/src/plugins/nat/nat44_classify.c
+++ b/src/plugins/nat/nat44-ed/nat44_ed_classify.c
@@ -20,9 +20,9 @@
#include <vlib/vlib.h>
#include <vnet/vnet.h>
#include <vnet/fib/ip4_fib.h>
-#include <nat/nat.h>
-#include <nat/nat_inlines.h>
-#include <nat/nat44/ed_inlines.h>
+
+#include <nat/nat44-ed/nat44_ed.h>
+#include <nat/nat44-ed/nat44_ed_inlines.h>
#define foreach_nat44_classify_error \
_(NEXT_IN2OUT, "next in2out") \
@@ -37,12 +37,6 @@ typedef enum
NAT44_CLASSIFY_N_ERROR,
} nat44_classify_error_t;
-static char *nat44_classify_error_strings[] = {
-#define _(sym,string) string,
- foreach_nat44_classify_error
-#undef _
-};
-
typedef enum
{
NAT44_CLASSIFY_NEXT_IN2OUT,
@@ -69,7 +63,7 @@ format_nat44_classify_trace (u8 * s, va_list * args)
s = format (s, "nat44-classify: fragment cached");
else
{
- next = t->next_in2out ? "nat44-in2out" : "nat44-out2in";
+ next = t->next_in2out ? "nat44-ed-in2out" : "nat44-ed-out2in";
s = format (s, "nat44-classify: next %s", next);
}
@@ -77,111 +71,6 @@ format_nat44_classify_trace (u8 * s, va_list * args)
}
static inline uword
-nat44_classify_node_fn_inline (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
-{
- u32 n_left_from, *from, *to_next;
- nat44_classify_next_t next_index;
- snat_main_t *sm = &snat_main;
- snat_static_mapping_t *m;
- u32 next_in2out = 0, next_out2in = 0;
-
- from = vlib_frame_vector_args (frame);
- n_left_from = frame->n_vectors;
- next_index = node->cached_next_index;
-
- while (n_left_from > 0)
- {
- u32 n_left_to_next;
-
- vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
-
- while (n_left_from > 0 && n_left_to_next > 0)
- {
- u32 bi0;
- vlib_buffer_t *b0;
- u32 next0 = NAT44_CLASSIFY_NEXT_IN2OUT;
- ip4_header_t *ip0;
- snat_address_t *ap;
- clib_bihash_kv_8_8_t kv0, value0;
-
- /* speculatively enqueue b0 to the current next frame */
- bi0 = from[0];
- to_next[0] = bi0;
- from += 1;
- to_next += 1;
- n_left_from -= 1;
- n_left_to_next -= 1;
-
- b0 = vlib_get_buffer (vm, bi0);
- ip0 = vlib_buffer_get_current (b0);
-
- /* *INDENT-OFF* */
- vec_foreach (ap, sm->addresses)
- {
- if (ip0->dst_address.as_u32 == ap->addr.as_u32)
- {
- next0 = NAT44_CLASSIFY_NEXT_OUT2IN;
- goto enqueue0;
- }
- }
- /* *INDENT-ON* */
-
- if (PREDICT_FALSE (pool_elts (sm->static_mappings)))
- {
- init_nat_k (&kv0, ip0->dst_address, 0, 0, 0);
- /* try to classify the fragment based on IP header alone */
- if (!clib_bihash_search_8_8 (&sm->static_mapping_by_external,
- &kv0, &value0))
- {
- m = pool_elt_at_index (sm->static_mappings, value0.value);
- if (m->local_addr.as_u32 != m->external_addr.as_u32)
- next0 = NAT44_CLASSIFY_NEXT_OUT2IN;
- goto enqueue0;
- }
- init_nat_k (&kv0, ip0->dst_address,
- vnet_buffer (b0)->ip.reass.l4_dst_port, 0,
- ip_proto_to_nat_proto (ip0->protocol));
- if (!clib_bihash_search_8_8
- (&sm->static_mapping_by_external, &kv0, &value0))
- {
- m = pool_elt_at_index (sm->static_mappings, value0.value);
- if (m->local_addr.as_u32 != m->external_addr.as_u32)
- next0 = NAT44_CLASSIFY_NEXT_OUT2IN;
- }
- }
-
- enqueue0:
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)
- && (b0->flags & VLIB_BUFFER_IS_TRACED)))
- {
- nat44_classify_trace_t *t =
- vlib_add_trace (vm, node, b0, sizeof (*t));
- t->cached = 0;
- t->next_in2out = next0 == NAT44_CLASSIFY_NEXT_IN2OUT ? 1 : 0;
- }
-
- next_in2out += next0 == NAT44_CLASSIFY_NEXT_IN2OUT;
- next_out2in += next0 == NAT44_CLASSIFY_NEXT_OUT2IN;
-
- /* verify speculative enqueue, maybe switch current next frame */
- vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
- to_next, n_left_to_next,
- bi0, next0);
- }
-
- vlib_put_next_frame (vm, node, next_index, n_left_to_next);
- }
-
- vlib_node_increment_counter (vm, node->node_index,
- NAT44_CLASSIFY_ERROR_NEXT_IN2OUT, next_in2out);
- vlib_node_increment_counter (vm, node->node_index,
- NAT44_CLASSIFY_ERROR_NEXT_OUT2IN, next_out2in);
- return frame->n_vectors;
-}
-
-static inline uword
nat44_handoff_classify_node_fn_inline (vlib_main_t * vm,
vlib_node_runtime_t * node,
vlib_frame_t * frame)
@@ -222,7 +111,6 @@ nat44_handoff_classify_node_fn_inline (vlib_main_t * vm,
b0 = vlib_get_buffer (vm, bi0);
ip0 = vlib_buffer_get_current (b0);
- /* *INDENT-OFF* */
vec_foreach (ap, sm->addresses)
{
if (ip0->dst_address.as_u32 == ap->addr.as_u32)
@@ -231,7 +119,6 @@ nat44_handoff_classify_node_fn_inline (vlib_main_t * vm,
goto enqueue0;
}
}
- /* *INDENT-ON* */
if (PREDICT_FALSE (pool_elts (sm->static_mappings)))
{
@@ -374,7 +261,6 @@ nat44_ed_classify_node_fn_inline (vlib_main_t * vm,
/* session doesn't exist so continue in code */
}
- /* *INDENT-OFF* */
vec_foreach (ap, sm->addresses)
{
if (ip0->dst_address.as_u32 == ap->addr.as_u32)
@@ -383,7 +269,6 @@ nat44_ed_classify_node_fn_inline (vlib_main_t * vm,
goto enqueue0;
}
}
- /* *INDENT-ON* */
if (PREDICT_FALSE (pool_elts (sm->static_mappings)))
{
@@ -438,30 +323,6 @@ nat44_ed_classify_node_fn_inline (vlib_main_t * vm,
return frame->n_vectors;
}
-VLIB_NODE_FN (nat44_classify_node) (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
-{
- return nat44_classify_node_fn_inline (vm, node, frame);
-}
-
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (nat44_classify_node) = {
- .name = "nat44-classify",
- .vector_size = sizeof (u32),
- .format_trace = format_nat44_classify_trace,
- .type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN(nat44_classify_error_strings),
- .error_strings = nat44_classify_error_strings,
- .n_next_nodes = NAT44_CLASSIFY_N_NEXT,
- .next_nodes = {
- [NAT44_CLASSIFY_NEXT_IN2OUT] = "nat44-in2out",
- [NAT44_CLASSIFY_NEXT_OUT2IN] = "nat44-out2in",
- [NAT44_CLASSIFY_NEXT_DROP] = "error-drop",
- },
-};
-/* *INDENT-ON* */
-
VLIB_NODE_FN (nat44_ed_classify_node) (vlib_main_t * vm,
vlib_node_runtime_t * node,
vlib_frame_t * frame)
@@ -469,7 +330,6 @@ VLIB_NODE_FN (nat44_ed_classify_node) (vlib_main_t * vm,
return nat44_ed_classify_node_fn_inline (vm, node, frame);
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (nat44_ed_classify_node) = {
.name = "nat44-ed-classify",
.vector_size = sizeof (u32),
@@ -477,7 +337,6 @@ VLIB_REGISTER_NODE (nat44_ed_classify_node) = {
.format_trace = format_nat44_classify_trace,
.type = VLIB_NODE_TYPE_INTERNAL,
};
-/* *INDENT-ON* */
VLIB_NODE_FN (nat44_handoff_classify_node) (vlib_main_t * vm,
vlib_node_runtime_t * node,
@@ -486,7 +345,6 @@ VLIB_NODE_FN (nat44_handoff_classify_node) (vlib_main_t * vm,
return nat44_handoff_classify_node_fn_inline (vm, node, frame);
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (nat44_handoff_classify_node) = {
.name = "nat44-handoff-classify",
.vector_size = sizeof (u32),
@@ -495,8 +353,6 @@ VLIB_REGISTER_NODE (nat44_handoff_classify_node) = {
.type = VLIB_NODE_TYPE_INTERNAL,
};
-/* *INDENT-ON* */
-
/*
* fd.io coding-style-patch-verification: ON
*
diff --git a/src/plugins/nat/nat44_cli.c b/src/plugins/nat/nat44-ed/nat44_ed_cli.c
index 68c53d05389..714b410bbd3 100644
--- a/src/plugins/nat/nat44_cli.c
+++ b/src/plugins/nat/nat44-ed/nat44_ed_cli.c
@@ -17,21 +17,15 @@
* @brief NAT44 CLI
*/
-#include <nat/nat.h>
-#include <nat/lib/ipfix_logging.h>
-#include <nat/lib/nat_inlines.h>
-#include <nat/nat_inlines.h>
-#include <nat/nat44/inlines.h>
-#include <nat/nat_affinity.h>
#include <vnet/fib/fib_table.h>
-#include <nat/nat44-ei/nat44_ei_ha.h>
-#include <nat/nat44-ei/nat44_ei.h>
+#include <nat/lib/log.h>
+#include <nat/lib/nat_inlines.h>
+#include <nat/lib/ipfix_logging.h>
-#define UNSUPPORTED_IN_ED_MODE_STR \
- "This command is unsupported in endpoint dependent mode"
-#define SUPPORTED_ONLY_IN_ED_MODE_STR \
- "This command is supported only in endpoint dependent mode"
+#include <nat/nat44-ed/nat44_ed.h>
+#include <nat/nat44-ed/nat44_ed_inlines.h>
+#include <nat/nat44-ed/nat44_ed_affinity.h>
static clib_error_t *
nat44_enable_command_fn (vlib_main_t * vm,
@@ -66,21 +60,9 @@ nat44_enable_command_fn (vlib_main_t * vm,
c.connection_tracking = 1;
}
}
- else if (!mode_set && unformat (line_input, "out2in-dpo"))
- {
- mode_set = 1;
- c.out2in_dpo = 1;
- }
- else if (!mode_set && unformat (line_input, "endpoint-dependent"))
- {
- mode_set = 1;
- c.endpoint_dependent = 1;
- }
else if (unformat (line_input, "inside-vrf %u", &c.inside_vrf));
else if (unformat (line_input, "outside-vrf %u", &c.outside_vrf));
- else if (unformat (line_input, "users %u", &c.users));
else if (unformat (line_input, "sessions %u", &c.sessions));
- else if (unformat (line_input, "user-sessions %u", &c.user_sessions));
else
{
error = clib_error_return (0, "unknown input '%U'",
@@ -182,14 +164,12 @@ nat_show_workers_commnad_fn (vlib_main_t * vm, unformat_input_t * input,
if (sm->num_workers > 1)
{
vlib_cli_output (vm, "%d workers", vec_len (sm->workers));
- /* *INDENT-OFF* */
vec_foreach (worker, sm->workers)
{
vlib_worker_thread_t *w =
vlib_worker_threads + *worker + sm->first_worker_index;
vlib_cli_output (vm, " %s", w->name);
}
- /* *INDENT-ON* */
}
return 0;
@@ -202,7 +182,7 @@ snat_set_log_level_command_fn (vlib_main_t * vm,
{
unformat_input_t _line_input, *line_input = &_line_input;
snat_main_t *sm = &snat_main;
- u8 log_level = SNAT_LOG_NONE;
+ u8 log_level = NAT_LOG_NONE;
clib_error_t *error = 0;
/* Get a line of input. */
@@ -215,7 +195,7 @@ snat_set_log_level_command_fn (vlib_main_t * vm,
format_unformat_error, line_input);
goto done;
}
- if (log_level > SNAT_LOG_DEBUG)
+ if (log_level > NAT_LOG_DEBUG)
{
error = clib_error_return (0, "unknown logging level '%d'", log_level);
goto done;
@@ -285,7 +265,6 @@ nat44_show_hash_command_fn (vlib_main_t * vm, unformat_input_t * input,
vlib_cli_command_t * cmd)
{
snat_main_t *sm = &snat_main;
- snat_main_per_thread_data_t *tsm;
nat_affinity_main_t *nam = &nat_affinity_main;
int i;
int verbose = 0;
@@ -300,116 +279,19 @@ nat44_show_hash_command_fn (vlib_main_t * vm, unformat_input_t * input,
vlib_cli_output (vm, "%U",
format_bihash_8_8, &sm->static_mapping_by_external,
verbose);
- if (sm->endpoint_dependent)
- {
vlib_cli_output (vm, "%U", format_bihash_16_8, &sm->flow_hash, verbose);
- }
- else
- {
- vlib_cli_output (vm, "%U", format_bihash_8_8, &sm->in2out, verbose);
- vlib_cli_output (vm, "%U", format_bihash_8_8, &sm->out2in, verbose);
- }
vec_foreach_index (i, sm->per_thread_data)
{
- tsm = vec_elt_at_index (sm->per_thread_data, i);
vlib_cli_output (vm, "-------- thread %d %s --------\n",
i, vlib_worker_threads[i].name);
- vlib_cli_output (vm, "%U", format_bihash_8_8, &tsm->user_hash, verbose);
+ vlib_cli_output (vm, "%U", format_bihash_16_8, &sm->flow_hash, verbose);
}
- if (sm->endpoint_dependent)
- {
vlib_cli_output (vm, "%U", format_bihash_16_8, &nam->affinity_hash,
verbose);
- }
vlib_cli_output (vm, "-------- hash table parameters --------\n");
vlib_cli_output (vm, "translation buckets: %u", sm->translation_buckets);
- if (!sm->endpoint_dependent)
- {
- vlib_cli_output (vm, "user buckets: %u", sm->user_buckets);
- }
- return 0;
-}
-
-static clib_error_t *
-nat44_set_alloc_addr_and_port_alg_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;
- u32 psid, psid_offset, psid_length, port_start, port_end;
- snat_main_t *sm = &snat_main;
-
- if (sm->endpoint_dependent)
- return clib_error_return (0, UNSUPPORTED_IN_ED_MODE_STR);
-
- /* Get a line of input. */
- if (!unformat_user (input, unformat_line_input, line_input))
- return 0;
-
- while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (line_input, "default"))
- nat44_ei_set_alloc_default ();
- else
- if (unformat
- (line_input, "map-e psid %d psid-offset %d psid-len %d", &psid,
- &psid_offset, &psid_length))
- nat44_ei_set_alloc_mape ((u16) psid, (u16) psid_offset,
- (u16) psid_length);
- else
- if (unformat
- (line_input, "port-range %d - %d", &port_start, &port_end))
- {
- if (port_end <= port_start)
- {
- error =
- clib_error_return (0,
- "The end-port must be greater than start-port");
- goto done;
- }
- nat44_ei_set_alloc_range ((u16) port_start, (u16) port_end);
- }
- else
- {
- error = clib_error_return (0, "unknown input '%U'",
- format_unformat_error, line_input);
- goto done;
- }
- }
-
-done:
- unformat_free (line_input);
-
- return error;
-};
-
-static clib_error_t *
-nat44_show_alloc_addr_and_port_alg_command_fn (vlib_main_t * vm,
- unformat_input_t * input,
- vlib_cli_command_t * cmd)
-{
- snat_main_t *sm = &snat_main;
-
- vlib_cli_output (vm, "NAT address and port: %U",
- format_nat_addr_and_port_alloc_alg,
- sm->addr_and_port_alloc_alg);
- switch (sm->addr_and_port_alloc_alg)
- {
- case NAT_ADDR_AND_PORT_ALLOC_ALG_MAPE:
- vlib_cli_output (vm, " psid %d psid-offset %d psid-len %d", sm->psid,
- sm->psid_offset, sm->psid_length);
- break;
- case NAT_ADDR_AND_PORT_ALLOC_ALG_RANGE:
- vlib_cli_output (vm, " start-port %d end-port %d", sm->start_port,
- sm->end_port);
- break;
- default:
- break;
- }
-
return 0;
}
@@ -461,143 +343,6 @@ nat_show_mss_clamping_command_fn (vlib_main_t * vm, unformat_input_t * input,
}
static clib_error_t *
-nat_ha_failover_command_fn (vlib_main_t * vm, unformat_input_t * input,
- vlib_cli_command_t * cmd)
-{
- unformat_input_t _line_input, *line_input = &_line_input;
- ip4_address_t addr;
- u32 port, session_refresh_interval = 10;
- int rv;
- clib_error_t *error = 0;
-
- /* Get a line of input. */
- if (!unformat_user (input, unformat_line_input, line_input))
- return 0;
-
- while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (line_input, "%U:%u", unformat_ip4_address, &addr, &port))
- ;
- else
- if (unformat
- (line_input, "refresh-interval %u", &session_refresh_interval))
- ;
- else
- {
- error = clib_error_return (0, "unknown input '%U'",
- format_unformat_error, line_input);
- goto done;
- }
- }
-
- rv = nat_ha_set_failover (&addr, (u16) port, session_refresh_interval);
- if (rv)
- error = clib_error_return (0, "set HA failover failed");
-
-done:
- unformat_free (line_input);
-
- return error;
-}
-
-static clib_error_t *
-nat_ha_listener_command_fn (vlib_main_t * vm, unformat_input_t * input,
- vlib_cli_command_t * cmd)
-{
- unformat_input_t _line_input, *line_input = &_line_input;
- ip4_address_t addr;
- u32 port, path_mtu = 512;
- int rv;
- clib_error_t *error = 0;
-
- /* Get a line of input. */
- if (!unformat_user (input, unformat_line_input, line_input))
- return 0;
-
- while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (line_input, "%U:%u", unformat_ip4_address, &addr, &port))
- ;
- else if (unformat (line_input, "path-mtu %u", &path_mtu))
- ;
- else
- {
- error = clib_error_return (0, "unknown input '%U'",
- format_unformat_error, line_input);
- goto done;
- }
- }
-
- rv = nat_ha_set_listener (&addr, (u16) port, path_mtu);
- if (rv)
- error = clib_error_return (0, "set HA listener failed");
-
-done:
- unformat_free (line_input);
-
- return error;
-}
-
-static clib_error_t *
-nat_show_ha_command_fn (vlib_main_t * vm, unformat_input_t * input,
- vlib_cli_command_t * cmd)
-{
- ip4_address_t addr;
- u16 port;
- u32 path_mtu, session_refresh_interval, resync_ack_missed;
- u8 in_resync;
-
- nat_ha_get_listener (&addr, &port, &path_mtu);
- if (!port)
- {
- vlib_cli_output (vm, "NAT HA disabled\n");
- return 0;
- }
-
- vlib_cli_output (vm, "LISTENER:\n");
- vlib_cli_output (vm, " %U:%u path-mtu %u\n",
- format_ip4_address, &addr, port, path_mtu);
-
- nat_ha_get_failover (&addr, &port, &session_refresh_interval);
- vlib_cli_output (vm, "FAILOVER:\n");
- if (port)
- vlib_cli_output (vm, " %U:%u refresh-interval %usec\n",
- format_ip4_address, &addr, port,
- session_refresh_interval);
- else
- vlib_cli_output (vm, " NA\n");
-
- nat_ha_get_resync_status (&in_resync, &resync_ack_missed);
- vlib_cli_output (vm, "RESYNC:\n");
- if (in_resync)
- vlib_cli_output (vm, " in progress\n");
- else
- vlib_cli_output (vm, " completed (%d ACK missed)\n", resync_ack_missed);
-
- return 0;
-}
-
-static clib_error_t *
-nat_ha_flush_command_fn (vlib_main_t * vm, unformat_input_t * input,
- vlib_cli_command_t * cmd)
-{
- nat_ha_flush (0);
- return 0;
-}
-
-static clib_error_t *
-nat_ha_resync_command_fn (vlib_main_t * vm, unformat_input_t * input,
- vlib_cli_command_t * cmd)
-{
- clib_error_t *error = 0;
-
- if (nat_ha_resync (0, 0, 0))
- error = clib_error_return (0, "NAT HA resync already running");
-
- return error;
-}
-
-static clib_error_t *
add_address_command_fn (vlib_main_t * vm,
unformat_input_t * input, vlib_cli_command_t * cmd)
{
@@ -681,18 +426,10 @@ add_address_command_fn (vlib_main_t * vm,
error =
clib_error_return (0, "NAT address used in static mapping.");
goto done;
- case VNET_API_ERROR_FEATURE_DISABLED:
- error =
- clib_error_return (0,
- "twice NAT available only for endpoint-dependent mode.");
- goto done;
default:
break;
}
- if (sm->out2in_dpo)
- nat44_add_del_address_dpo (this_addr, is_add);
-
increment_v4_address (&this_addr);
}
@@ -741,9 +478,6 @@ nat44_show_summary_command_fn (vlib_main_t * vm, unformat_input_t * input,
snat_main_t *sm = &snat_main;
snat_session_t *s;
- if (!sm->endpoint_dependent)
- return clib_error_return (0, SUPPORTED_ONLY_IN_ED_MODE_STR);
-
u32 count = 0;
u64 now = vlib_time_now (vm);
@@ -767,7 +501,6 @@ nat44_show_summary_command_fn (vlib_main_t * vm, unformat_input_t * input,
if (sm->num_workers > 1)
{
- /* *INDENT-OFF* */
vec_foreach (tsm, sm->per_thread_data)
{
pool_foreach (s, tsm->sessions)
@@ -811,12 +544,10 @@ nat44_show_summary_command_fn (vlib_main_t * vm, unformat_input_t * input,
nat44_show_lru_summary (vm, tsm, now, sess_timeout_time);
count += pool_elts (tsm->sessions);
}
- /* *INDENT-ON* */
}
else
{
tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
- /* *INDENT-OFF* */
pool_foreach (s, tsm->sessions)
{
sess_timeout_time = s->last_heard +
@@ -855,7 +586,6 @@ nat44_show_summary_command_fn (vlib_main_t * vm, unformat_input_t * input,
break;
}
}
- /* *INDENT-ON* */
nat44_show_lru_summary (vm, tsm, now, sess_timeout_time);
count = pool_elts (tsm->sessions);
}
@@ -882,7 +612,6 @@ nat44_show_addresses_command_fn (vlib_main_t * vm, unformat_input_t * input,
snat_address_t *ap;
vlib_cli_output (vm, "NAT44 pool addresses:");
- /* *INDENT-OFF* */
vec_foreach (ap, sm->addresses)
{
vlib_cli_output (vm, "%U", format_ip4_address, &ap->addr);
@@ -910,7 +639,6 @@ nat44_show_addresses_command_fn (vlib_main_t * vm, unformat_input_t * input,
foreach_nat_protocol
#undef _
}
- /* *INDENT-ON* */
return 0;
}
@@ -1033,7 +761,6 @@ nat44_show_interfaces_command_fn (vlib_main_t * vm, unformat_input_t * input,
vnet_main_t *vnm = vnet_get_main ();
vlib_cli_output (vm, "NAT44 interfaces:");
- /* *INDENT-OFF* */
pool_foreach (i, sm->interfaces)
{
vlib_cli_output (vm, " %U %s", format_vnet_sw_if_index_name, vnm,
@@ -1052,7 +779,6 @@ nat44_show_interfaces_command_fn (vlib_main_t * vm, unformat_input_t * input,
nat_interface_is_outside(i)) ? "in out" :
(nat_interface_is_inside(i) ? "in" : "out"));
}
- /* *INDENT-ON* */
return 0;
}
@@ -1166,11 +892,6 @@ add_static_mapping_command_fn (vlib_main_t * vm,
case VNET_API_ERROR_VALUE_EXIST:
error = clib_error_return (0, "Mapping already exist.");
goto done;
- case VNET_API_ERROR_FEATURE_DISABLED:
- error =
- clib_error_return (0,
- "twice-nat/out2in-only available only for endpoint-dependent mode.");
- goto done;
default:
break;
}
@@ -1353,10 +1074,6 @@ add_lb_static_mapping_command_fn (vlib_main_t * vm,
case VNET_API_ERROR_VALUE_EXIST:
error = clib_error_return (0, "Mapping already exist.");
goto done;
- case VNET_API_ERROR_FEATURE_DISABLED:
- error =
- clib_error_return (0, "Available only for endpoint-dependent mode.");
- goto done;
default:
break;
}
@@ -1439,10 +1156,6 @@ add_lb_backend_command_fn (vlib_main_t * vm,
case VNET_API_ERROR_VALUE_EXIST:
error = clib_error_return (0, "Back-end already exist.");
goto done;
- case VNET_API_ERROR_FEATURE_DISABLED:
- error =
- clib_error_return (0, "Available only for endpoint-dependent mode.");
- goto done;
case VNET_API_ERROR_UNSPECIFIED:
error = clib_error_return (0, "At least two back-ends must remain");
goto done;
@@ -1466,14 +1179,12 @@ nat44_show_static_mappings_command_fn (vlib_main_t * vm,
snat_static_map_resolve_t *rp;
vlib_cli_output (vm, "NAT44 static mappings:");
- /* *INDENT-OFF* */
pool_foreach (m, sm->static_mappings)
{
vlib_cli_output (vm, " %U", format_snat_static_mapping, m);
}
vec_foreach (rp, sm->to_resolve)
vlib_cli_output (vm, " %U", format_snat_static_map_to_resolve, rp);
- /* *INDENT-ON* */
return 0;
}
@@ -1540,7 +1251,6 @@ nat44_show_interface_address_command_fn (vlib_main_t * vm,
vnet_main_t *vnm = vnet_get_main ();
u32 *sw_if_index;
- /* *INDENT-OFF* */
vlib_cli_output (vm, "NAT44 pool address interfaces:");
vec_foreach (sw_if_index, sm->auto_add_sw_if_indices)
{
@@ -1553,7 +1263,6 @@ nat44_show_interface_address_command_fn (vlib_main_t * vm,
vlib_cli_output (vm, " %U", format_vnet_sw_if_index_name, vnm,
*sw_if_index);
}
- /* *INDENT-ON* */
return 0;
}
@@ -1564,11 +1273,9 @@ nat44_show_sessions_command_fn (vlib_main_t * vm, unformat_input_t * input,
{
unformat_input_t _line_input, *line_input = &_line_input;
clib_error_t *error = 0;
-
snat_main_per_thread_data_t *tsm;
snat_main_t *sm = &snat_main;
- int detail = 0;
int i = 0;
if (!unformat_user (input, unformat_line_input, line_input))
@@ -1576,24 +1283,15 @@ nat44_show_sessions_command_fn (vlib_main_t * vm, unformat_input_t * input,
while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
{
- if (unformat (line_input, "detail"))
- detail = 1;
- else
- {
- error = clib_error_return (0, "unknown input '%U'",
- format_unformat_error, line_input);
- break;
- }
+ error = clib_error_return (0, "unknown input '%U'",
+ format_unformat_error, line_input);
+ break;
}
unformat_free (line_input);
print:
- if (!sm->endpoint_dependent)
- vlib_cli_output (vm, "NAT44 sessions:");
- else
vlib_cli_output (vm, "NAT44 ED sessions:");
- /* *INDENT-OFF* */
vec_foreach_index (i, sm->per_thread_data)
{
tsm = vec_elt_at_index (sm->per_thread_data, i);
@@ -1602,24 +1300,12 @@ print:
i, vlib_worker_threads[i].name,
pool_elts (tsm->sessions));
- if (!sm->endpoint_dependent)
- {
- snat_user_t *u;
- pool_foreach (u, tsm->users)
- {
- vlib_cli_output (vm, " %U", format_snat_user, tsm, u, detail);
- }
- }
- else
- {
snat_session_t *s;
pool_foreach (s, tsm->sessions)
{
vlib_cli_output (vm, " %U\n", format_snat_session, tsm, s);
}
- }
}
- /* *INDENT-ON* */
return error;
}
@@ -1663,72 +1349,17 @@ done:
}
static clib_error_t *
-nat44_del_user_command_fn (vlib_main_t * vm,
- unformat_input_t * input, vlib_cli_command_t * cmd)
-{
- snat_main_t *sm = &snat_main;
- unformat_input_t _line_input, *line_input = &_line_input;
- clib_error_t *error = 0;
- ip4_address_t addr;
- u32 fib_index = 0;
- int rv;
-
- if (sm->endpoint_dependent)
- return clib_error_return (0, UNSUPPORTED_IN_ED_MODE_STR);
-
- /* Get a line of input. */
- if (!unformat_user (input, unformat_line_input, line_input))
- return 0;
-
- while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (line_input, "%U", unformat_ip4_address, &addr))
- ;
- else if (unformat (line_input, "fib %u", &fib_index))
- ;
- else
- {
- error = clib_error_return (0, "unknown input '%U'",
- format_unformat_error, line_input);
- goto done;
- }
- }
-
- rv = nat44_ei_user_del (&addr, fib_index);
-
- if (!rv)
- {
- error = clib_error_return (0, "nat44_ei_user_del returned %d", rv);
- }
-
-done:
- unformat_free (line_input);
-
- return error;
-}
-
-static clib_error_t *
-nat44_clear_sessions_command_fn (vlib_main_t * vm,
- unformat_input_t * input,
- vlib_cli_command_t * cmd)
-{
- clib_error_t *error = 0;
- nat44_sessions_clear ();
- return error;
-}
-
-static clib_error_t *
nat44_del_session_command_fn (vlib_main_t * vm,
unformat_input_t * input,
vlib_cli_command_t * cmd)
{
snat_main_t *sm = &snat_main;
unformat_input_t _line_input, *line_input = &_line_input;
- int is_in = 0, is_ed = 0;
+ u32 port = 0, eh_port = 0, vrf_id = sm->outside_vrf_id;
clib_error_t *error = 0;
ip4_address_t addr, eh_addr;
- u32 port = 0, eh_port = 0, vrf_id = sm->outside_vrf_id;
nat_protocol_t proto;
+ int is_in = 0;
int rv;
/* Get a line of input. */
@@ -1753,11 +1384,9 @@ nat44_del_session_command_fn (vlib_main_t * vm,
}
else if (unformat (line_input, "vrf %u", &vrf_id))
;
- else
- if (unformat
- (line_input, "external-host %U:%u", unformat_ip4_address,
- &eh_addr, &eh_port))
- is_ed = 1;
+ else if (unformat (line_input, "external-host %U:%u",
+ unformat_ip4_address, &eh_addr, &eh_port))
+ ;
else
{
error = clib_error_return (0, "unknown input '%U'",
@@ -1766,14 +1395,10 @@ nat44_del_session_command_fn (vlib_main_t * vm,
}
}
- if (is_ed)
rv =
nat44_del_ed_session (sm, &addr, clib_host_to_net_u16 (port), &eh_addr,
clib_host_to_net_u16 (eh_port),
nat_proto_to_ip_proto (proto), vrf_id, is_in);
- else
- rv = nat44_ei_del_session (sm, &addr, clib_host_to_net_u16 (port), proto,
- vrf_id, is_in);
switch (rv)
{
@@ -1927,79 +1552,6 @@ done:
return error;
}
-static clib_error_t *
-nat44_debug_fib_expire_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;
- u32 fib = ~0;
-
- /* Get a line of input. */
- if (!unformat_user (input, unformat_line_input, line_input))
- return 0;
-
- while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (line_input, "%u", &fib))
- ;
- else
- {
- error = clib_error_return (0, "unknown input '%U'",
- format_unformat_error, line_input);
- goto done;
- }
- }
- expire_per_vrf_sessions (fib);
-done:
- unformat_free (line_input);
- return error;
-}
-
-static clib_error_t *
-nat44_debug_fib_registration_command_fn (vlib_main_t * vm,
- unformat_input_t * input,
- vlib_cli_command_t * cmd)
-{
- snat_main_t *sm = &snat_main;
- snat_main_per_thread_data_t *tsm;
- per_vrf_sessions_t *per_vrf_sessions;
-
- vlib_cli_output (vm, "VRF registration debug:");
- vec_foreach (tsm, sm->per_thread_data)
- {
- vlib_cli_output (vm, "thread %u:", tsm->thread_index);
- vec_foreach (per_vrf_sessions, tsm->per_vrf_sessions_vec)
- {
- vlib_cli_output (vm, "rx fib %u tx fib %u ses count %u %s",
- per_vrf_sessions->rx_fib_index,
- per_vrf_sessions->tx_fib_index,
- per_vrf_sessions->ses_count,
- per_vrf_sessions->expired ? "expired" : "");
- }
- }
- return 0;
-}
-
-/* *INDENT-OFF* */
-
-/*?
-?*/
-VLIB_CLI_COMMAND (nat44_debug_fib_expire_command, static) = {
- .path = "debug nat44 fib expire",
- .short_help = "debug nat44 fib expire <fib-index>",
- .function = nat44_debug_fib_expire_command_fn,
-};
-
-/*?
-?*/
-VLIB_CLI_COMMAND (nat44_debug_fib_registration_command, static) = {
- .path = "debug nat44 fib registration",
- .short_help = "debug nat44 fib registration",
- .function = nat44_debug_fib_registration_command_fn,
-};
-
/*?
* @cliexpar
* @cliexstart{nat44 enable}
@@ -2010,17 +1562,15 @@ VLIB_CLI_COMMAND (nat44_debug_fib_registration_command, static) = {
* vpp# nat44 enable sessions <n> static-mapping
* To enable nat44 static mapping with connection tracking, use:
* vpp# nat44 enable sessions <n> static-mapping connection-tracking
- * To enable nat44 out2in dpo, use:
- * vpp# nat44 enable sessions <n> out2in-dpo
- * To enable nat44 endpoint-dependent, use:
- * vpp# nat44 enable sessions <n> endpoint-dependent
* To set inside-vrf outside-vrf, use:
* vpp# nat44 enable sessions <n> inside-vrf <id> outside-vrf <id>
* @cliexend
?*/
VLIB_CLI_COMMAND (nat44_enable_command, static) = {
.path = "nat44 enable",
- .short_help = "nat44 enable sessions <max-number> [users <max-number>] [static-mappig-only [connection-tracking]|out2in-dpo|endpoint-dependent] [inside-vrf <vrf-id>] [outside-vrf <vrf-id>] [user-sessions <max-number>]",
+ .short_help =
+ "nat44 enable sessions <max-number> [static-mappig-only "
+ "[connection-tracking]] [inside-vrf <vrf-id>] [outside-vrf <vrf-id>]",
.function = nat44_enable_command_fn,
};
@@ -2143,36 +1693,6 @@ VLIB_CLI_COMMAND (snat_ipfix_logging_enable_disable_command, static) = {
/*?
* @cliexpar
- * @cliexstart{nat addr-port-assignment-alg}
- * Set address and port assignment algorithm
- * For the MAP-E CE limit port choice based on PSID use:
- * vpp# nat addr-port-assignment-alg map-e psid 10 psid-offset 6 psid-len 6
- * For port range use:
- * vpp# nat addr-port-assignment-alg port-range <start-port> - <end-port>
- * To set standard (default) address and port assignment algorithm use:
- * vpp# nat addr-port-assignment-alg default
- * @cliexend
-?*/
-VLIB_CLI_COMMAND (nat44_set_alloc_addr_and_port_alg_command, static) = {
- .path = "nat addr-port-assignment-alg",
- .short_help = "nat addr-port-assignment-alg <alg-name> [<alg-params>]",
- .function = nat44_set_alloc_addr_and_port_alg_command_fn,
-};
-
-/*?
- * @cliexpar
- * @cliexstart{show nat addr-port-assignment-alg}
- * Show address and port assignment algorithm
- * @cliexend
-?*/
-VLIB_CLI_COMMAND (nat44_show_alloc_addr_and_port_alg_command, static) = {
- .path = "show nat addr-port-assignment-alg",
- .short_help = "show nat addr-port-assignment-alg",
- .function = nat44_show_alloc_addr_and_port_alg_command_fn,
-};
-
-/*?
- * @cliexpar
* @cliexstart{nat mss-clamping}
* Set TCP MSS rewriting configuration
* To enable TCP MSS rewriting use:
@@ -2201,66 +1721,6 @@ VLIB_CLI_COMMAND (nat_show_mss_clamping_command, static) = {
/*?
* @cliexpar
- * @cliexstart{nat ha failover}
- * Set HA failover (remote settings)
- * @cliexend
-?*/
-VLIB_CLI_COMMAND (nat_ha_failover_command, static) = {
- .path = "nat ha failover",
- .short_help = "nat ha failover <ip4-address>:<port> [refresh-interval <sec>]",
- .function = nat_ha_failover_command_fn,
-};
-
-/*?
- * @cliexpar
- * @cliexstart{nat ha listener}
- * Set HA listener (local settings)
- * @cliexend
-?*/
-VLIB_CLI_COMMAND (nat_ha_listener_command, static) = {
- .path = "nat ha listener",
- .short_help = "nat ha listener <ip4-address>:<port> [path-mtu <path-mtu>]",
- .function = nat_ha_listener_command_fn,
-};
-
-/*?
- * @cliexpar
- * @cliexstart{show nat ha}
- * Show HA configuration/status
- * @cliexend
-?*/
-VLIB_CLI_COMMAND (nat_show_ha_command, static) = {
- .path = "show nat ha",
- .short_help = "show nat ha",
- .function = nat_show_ha_command_fn,
-};
-
-/*?
- * @cliexpar
- * @cliexstart{nat ha flush}
- * Flush the current HA data (for testing)
- * @cliexend
-?*/
-VLIB_CLI_COMMAND (nat_ha_flush_command, static) = {
- .path = "nat ha flush",
- .short_help = "nat ha flush",
- .function = nat_ha_flush_command_fn,
-};
-
-/*?
- * @cliexpar
- * @cliexstart{nat ha resync}
- * Resync HA (resend existing sessions to new failover)
- * @cliexend
-?*/
-VLIB_CLI_COMMAND (nat_ha_resync_command, static) = {
- .path = "nat ha resync",
- .short_help = "nat ha resync",
- .function = nat_ha_resync_command_fn,
-};
-
-/*?
- * @cliexpar
* @cliexstart{show nat44 hash tables}
* Show NAT44 hash tables
* @cliexend
@@ -2529,32 +1989,6 @@ VLIB_CLI_COMMAND (nat44_set_session_limit_command, static) = {
/*?
* @cliexpar
- * @cliexstart{nat44 del user}
- * To delete all NAT44 user sessions:
- * vpp# nat44 del user 10.0.0.3
- * @cliexend
-?*/
-VLIB_CLI_COMMAND (nat44_del_user_command, static) = {
- .path = "nat44 del user",
- .short_help = "nat44 del user <addr> [fib <index>]",
- .function = nat44_del_user_command_fn,
-};
-
-/*?
- * @cliexpar
- * @cliexstart{clear nat44 sessions}
- * To clear all NAT44 sessions
- * vpp# clear nat44 sessions
- * @cliexend
-?*/
-VLIB_CLI_COMMAND (nat44_clear_sessions_command, static) = {
- .path = "clear nat44 sessions",
- .short_help = "clear nat44 sessions",
- .function = nat44_clear_sessions_command_fn,
-};
-
-/*?
- * @cliexpar
* @cliexstart{nat44 del session}
* To administratively delete NAT44 session by inside address and port use:
* vpp# nat44 del session in 10.0.0.3:6303 tcp
@@ -2586,8 +2020,6 @@ VLIB_CLI_COMMAND (snat_forwarding_set_command, static) = {
.function = snat_forwarding_set_command_fn,
};
-/* *INDENT-ON* */
-
/*
* fd.io coding-style-patch-verification: ON
*
diff --git a/src/plugins/nat/nat_format.c b/src/plugins/nat/nat44-ed/nat44_ed_format.c
index 2fbd7498f49..29fd1129f32 100644
--- a/src/plugins/nat/nat_format.c
+++ b/src/plugins/nat/nat44-ed/nat44_ed_format.c
@@ -17,8 +17,8 @@
* @brief NAT formatting
*/
-#include <nat/nat.h>
-#include <nat/nat_inlines.h>
+#include <nat/nat44-ed/nat44_ed.h>
+#include <nat/nat44-ed/nat44_ed_inlines.h>
uword
unformat_nat_protocol (unformat_input_t * input, va_list * args)
@@ -171,49 +171,6 @@ format_snat_session (u8 * s, va_list * args)
s = format (s, " load-balancing\n");
if (is_twice_nat_session (sess))
s = format (s, " twice-nat\n");
-
- return s;
-}
-
-u8 *
-format_snat_user (u8 * s, va_list * args)
-{
- snat_main_per_thread_data_t *tsm =
- va_arg (*args, snat_main_per_thread_data_t *);
- snat_user_t *u = va_arg (*args, snat_user_t *);
- int verbose = va_arg (*args, int);
- dlist_elt_t *head, *elt;
- u32 elt_index, head_index;
- u32 session_index;
- snat_session_t *sess;
-
- s = format (s, "%U: %d dynamic translations, %d static translations\n",
- format_ip4_address, &u->addr, u->nsessions, u->nstaticsessions);
-
- if (verbose == 0)
- return s;
-
- if (u->nsessions || u->nstaticsessions)
- {
- 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);
- session_index = elt->value;
-
- while (session_index != ~0)
- {
- sess = pool_elt_at_index (tsm->sessions, session_index);
-
- s = format (s, " %U\n", format_snat_session, tsm, sess);
-
- elt_index = elt->next;
- elt = pool_elt_at_index (tsm->list_pool, elt_index);
- session_index = elt->value;
- }
- }
-
return s;
}
diff --git a/src/plugins/nat/nat44_handoff.c b/src/plugins/nat/nat44-ed/nat44_ed_handoff.c
index 8c1b967c020..6715ce2f2c4 100644
--- a/src/plugins/nat/nat44_handoff.c
+++ b/src/plugins/nat/nat44-ed/nat44_ed_handoff.c
@@ -22,8 +22,9 @@
#include <vnet/handoff.h>
#include <vnet/fib/ip4_fib.h>
#include <vppinfra/error.h>
-#include <nat/nat.h>
-#include <nat/nat_inlines.h>
+
+#include <nat/nat44-ed/nat44_ed.h>
+#include <nat/nat44-ed/nat44_ed_inlines.h>
typedef struct
{
diff --git a/src/plugins/nat/in2out_ed.c b/src/plugins/nat/nat44-ed/nat44_ed_in2out.c
index 9dc68576fd4..784dea0faf6 100644
--- a/src/plugins/nat/in2out_ed.c
+++ b/src/plugins/nat/nat44-ed/nat44_ed_in2out.c
@@ -24,13 +24,13 @@
#include <vnet/fib/ip4_fib.h>
#include <vnet/udp/udp_local.h>
#include <vppinfra/error.h>
-#include <nat/nat.h>
-#include <nat/lib/ipfix_logging.h>
-#include <nat/nat_inlines.h>
-#include <nat/nat44/inlines.h>
+
#include <nat/lib/nat_syslog.h>
-#include <nat/nat44/ed_inlines.h>
#include <nat/lib/nat_inlines.h>
+#include <nat/lib/ipfix_logging.h>
+
+#include <nat/nat44-ed/nat44_ed.h>
+#include <nat/nat44-ed/nat44_ed_inlines.h>
/* number of attempts to get a port for ED overloading algorithm, if rolling
* a dice this many times doesn't produce a free port, it's treated
@@ -95,6 +95,75 @@ format_nat_in2out_ed_trace (u8 * s, va_list * args)
return s;
}
+/**
+ * @brief Check if packet should be translated
+ *
+ * Packets aimed at outside interface and external address with active session
+ * should be translated.
+ *
+ * @param sm NAT main
+ * @param rt NAT runtime data
+ * @param sw_if_index0 index of the inside interface
+ * @param ip0 IPv4 header
+ * @param proto0 NAT protocol
+ * @param rx_fib_index0 RX FIB index
+ *
+ * @returns 0 if packet should be translated otherwise 1
+ */
+static inline int
+snat_not_translate_fast (snat_main_t *sm, vlib_node_runtime_t *node,
+ u32 sw_if_index0, ip4_header_t *ip0, u32 proto0,
+ u32 rx_fib_index0)
+{
+ fib_node_index_t fei = FIB_NODE_INDEX_INVALID;
+ nat_outside_fib_t *outside_fib;
+ fib_prefix_t pfx = {
+ .fp_proto = FIB_PROTOCOL_IP4,
+ .fp_len = 32,
+ .fp_addr = {
+ .ip4.as_u32 = ip0->dst_address.as_u32,
+ }
+ ,
+ };
+
+ /* Don't NAT packet aimed at the intfc address */
+ if (PREDICT_FALSE (
+ is_interface_addr (sm, node, sw_if_index0, ip0->dst_address.as_u32)))
+ return 1;
+
+ fei = fib_table_lookup (rx_fib_index0, &pfx);
+ if (FIB_NODE_INDEX_INVALID != fei)
+ {
+ u32 sw_if_index = fib_entry_get_resolving_interface (fei);
+ if (sw_if_index == ~0)
+ {
+ vec_foreach (outside_fib, sm->outside_fibs)
+ {
+ fei = fib_table_lookup (outside_fib->fib_index, &pfx);
+ if (FIB_NODE_INDEX_INVALID != fei)
+ {
+ sw_if_index = fib_entry_get_resolving_interface (fei);
+ if (sw_if_index != ~0)
+ break;
+ }
+ }
+ }
+ if (sw_if_index == ~0)
+ return 1;
+
+ snat_interface_t *i;
+ pool_foreach (i, sm->interfaces)
+ {
+ /* NAT packet aimed at outside interface */
+ if ((nat_interface_is_outside (i)) &&
+ (sw_if_index == i->sw_if_index))
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
static int
nat_ed_alloc_addr_and_port (snat_main_t *sm, u32 rx_fib_index, u32 nat_proto,
u32 thread_index, ip4_address_t r_addr, u16 r_port,
@@ -160,7 +229,7 @@ nat_ed_alloc_addr_and_port (snat_main_t *sm, u32 rx_fib_index, u32 nat_proto,
foreach_nat_protocol;
default:
- nat_elog_info ("unknown protocol");
+ nat_elog_info (sm, "unknown protocol");
return 1;
}
}
@@ -174,7 +243,7 @@ nat_ed_alloc_addr_and_port (snat_main_t *sm, u32 rx_fib_index, u32 nat_proto,
{
foreach_nat_protocol;
default:
- nat_elog_info ("unknown protocol");
+ nat_elog_info (sm, "unknown protocol");
return 1;
}
}
@@ -198,7 +267,6 @@ nat_outside_fib_index_lookup (snat_main_t * sm, ip4_address_t addr)
,
};
// TODO: multiple vrfs none can resolve addr
- /* *INDENT-OFF* */
vec_foreach (outside_fib, sm->outside_fibs)
{
fei = fib_table_lookup (outside_fib->fib_index, &pfx);
@@ -210,7 +278,6 @@ nat_outside_fib_index_lookup (snat_main_t * sm, ip4_address_t addr)
}
}
}
- /* *INDENT-ON* */
return ~0;
}
@@ -279,7 +346,7 @@ slow_path_ed (snat_main_t *sm, vlib_buffer_t *b, ip4_address_t l_addr,
b->error = node->errors[NAT_IN2OUT_ED_ERROR_MAX_SESSIONS_EXCEEDED];
nat_ipfix_logging_max_sessions (thread_index,
sm->max_translations_per_thread);
- nat_elog_notice ("maximum sessions exceeded");
+ nat_elog_notice (sm, "maximum sessions exceeded");
return NAT_NEXT_DROP;
}
}
@@ -360,7 +427,7 @@ slow_path_ed (snat_main_t *sm, vlib_buffer_t *b, ip4_address_t l_addr,
sm->port_per_thread, tsm->snat_thread_index, s, &outside_addr,
&outside_port))
{
- nat_elog_notice ("addresses exhausted");
+ nat_elog_notice (sm, "addresses exhausted");
b->error = node->errors[NAT_IN2OUT_ED_ERROR_OUT_OF_PORTS];
nat_ed_session_delete (sm, s, thread_index, 1);
return NAT_NEXT_DROP;
@@ -401,7 +468,7 @@ slow_path_ed (snat_main_t *sm, vlib_buffer_t *b, ip4_address_t l_addr,
nat_6t_flow_txfib_rewrite_set (&s->o2i, rx_fib_index);
if (nat_ed_ses_o2i_flow_hash_add_del (sm, thread_index, s, 2))
{
- nat_elog_notice ("out2in key add failed");
+ nat_elog_notice (sm, "out2in key add failed");
goto error;
}
}
@@ -429,7 +496,7 @@ slow_path_ed (snat_main_t *sm, vlib_buffer_t *b, ip4_address_t l_addr,
if (nat_ed_ses_i2o_flow_hash_add_del (sm, thread_index, s, 1))
{
- nat_elog_notice ("in2out key add failed");
+ nat_elog_notice (sm, "in2out key add failed");
goto error;
}
@@ -441,12 +508,10 @@ slow_path_ed (snat_main_t *sm, vlib_buffer_t *b, ip4_address_t l_addr,
s->in2out.port,
s->out2in.port, s->in2out.fib_index);
- nat_syslog_nat44_sadd (s->user_index, s->in2out.fib_index,
- &s->in2out.addr, s->in2out.port,
- &s->ext_host_nat_addr, s->ext_host_nat_port,
- &s->out2in.addr, s->out2in.port,
- &s->ext_host_addr, s->ext_host_port, s->nat_proto,
- 0);
+ nat_syslog_nat44_sadd (0, s->in2out.fib_index, &s->in2out.addr,
+ s->in2out.port, &s->ext_host_nat_addr,
+ s->ext_host_nat_port, &s->out2in.addr, s->out2in.port,
+ &s->ext_host_addr, s->ext_host_port, s->nat_proto, 0);
per_vrf_sessions_register_session (s, thread_index);
@@ -610,13 +675,11 @@ nat44_ed_not_translate_output_feature (snat_main_t * sm, ip4_header_t * ip,
return 0;
/* hairpinning */
- /* *INDENT-OFF* */
pool_foreach (i, sm->output_feature_interfaces)
{
if ((nat_interface_is_inside (i)) && (rx_sw_if_index == i->sw_if_index))
return 0;
}
- /* *INDENT-ON* */
return 1;
}
@@ -729,7 +792,7 @@ nat44_ed_in2out_slowpath_unknown_proto (snat_main_t *sm, vlib_buffer_t *b,
b->error = node->errors[NAT_IN2OUT_ED_ERROR_MAX_SESSIONS_EXCEEDED];
nat_ipfix_logging_max_sessions (thread_index,
sm->max_translations_per_thread);
- nat_elog_notice ("maximum sessions exceeded");
+ nat_elog_notice (sm, "maximum sessions exceeded");
return 0;
}
@@ -794,7 +857,7 @@ nat44_ed_in2out_slowpath_unknown_proto (snat_main_t *sm, vlib_buffer_t *b,
if (!s)
{
b->error = node->errors[NAT_IN2OUT_ED_ERROR_MAX_SESSIONS_EXCEEDED];
- nat_elog_warn ("create NAT session failed");
+ nat_elog_warn (sm, "create NAT session failed");
return 0;
}
@@ -831,14 +894,14 @@ nat44_ed_in2out_slowpath_unknown_proto (snat_main_t *sm, vlib_buffer_t *b,
if (nat_ed_ses_i2o_flow_hash_add_del (sm, thread_index, s, 1))
{
- nat_elog_notice ("in2out flow hash add failed");
+ nat_elog_notice (sm, "in2out flow hash add failed");
nat_ed_session_delete (sm, s, thread_index, 1);
return NULL;
}
if (nat_ed_ses_o2i_flow_hash_add_del (sm, thread_index, s, 1))
{
- nat_elog_notice ("out2in flow hash add failed");
+ nat_elog_notice (sm, "out2in flow hash add failed");
nat_ed_session_delete (sm, s, thread_index, 1);
return NULL;
}
@@ -1089,22 +1152,21 @@ nat44_ed_in2out_fast_path_node_fn_inline (vlib_main_t * vm,
switch (proto0)
{
case NAT_PROTOCOL_TCP:
- vlib_increment_simple_counter (&sm->counters.fastpath.in2out_ed.tcp,
+ vlib_increment_simple_counter (&sm->counters.fastpath.in2out.tcp,
thread_index, sw_if_index0, 1);
nat44_set_tcp_session_state_i2o (sm, now, s0, b0, thread_index);
break;
case NAT_PROTOCOL_UDP:
- vlib_increment_simple_counter (&sm->counters.fastpath.in2out_ed.udp,
+ vlib_increment_simple_counter (&sm->counters.fastpath.in2out.udp,
thread_index, sw_if_index0, 1);
break;
case NAT_PROTOCOL_ICMP:
- vlib_increment_simple_counter (&sm->counters.fastpath.in2out_ed.icmp,
+ vlib_increment_simple_counter (&sm->counters.fastpath.in2out.icmp,
thread_index, sw_if_index0, 1);
break;
case NAT_PROTOCOL_OTHER:
- vlib_increment_simple_counter (
- &sm->counters.fastpath.in2out_ed.other, thread_index, sw_if_index0,
- 1);
+ vlib_increment_simple_counter (&sm->counters.fastpath.in2out.other,
+ thread_index, sw_if_index0, 1);
break;
}
@@ -1144,9 +1206,8 @@ nat44_ed_in2out_fast_path_node_fn_inline (vlib_main_t * vm,
if (next[0] == NAT_NEXT_DROP)
{
- vlib_increment_simple_counter (&sm->counters.fastpath.
- in2out_ed.drops, thread_index,
- sw_if_index0, 1);
+ vlib_increment_simple_counter (&sm->counters.fastpath.in2out.drops,
+ thread_index, sw_if_index0, 1);
}
n_left_from--;
@@ -1231,9 +1292,8 @@ nat44_ed_in2out_slow_path_node_fn_inline (vlib_main_t * vm,
goto trace0;
}
- vlib_increment_simple_counter (&sm->counters.slowpath.
- in2out_ed.other, thread_index,
- sw_if_index0, 1);
+ vlib_increment_simple_counter (&sm->counters.slowpath.in2out.other,
+ thread_index, sw_if_index0, 1);
goto trace0;
}
@@ -1250,9 +1310,8 @@ nat44_ed_in2out_slow_path_node_fn_inline (vlib_main_t * vm,
goto trace0;
}
- vlib_increment_simple_counter (&sm->counters.slowpath.
- in2out_ed.icmp, thread_index,
- sw_if_index0, 1);
+ vlib_increment_simple_counter (&sm->counters.slowpath.in2out.icmp,
+ thread_index, sw_if_index0, 1);
goto trace0;
}
@@ -1336,13 +1395,13 @@ nat44_ed_in2out_slow_path_node_fn_inline (vlib_main_t * vm,
if (PREDICT_TRUE (proto0 == NAT_PROTOCOL_TCP))
{
- vlib_increment_simple_counter (&sm->counters.slowpath.in2out_ed.tcp,
+ vlib_increment_simple_counter (&sm->counters.slowpath.in2out.tcp,
thread_index, sw_if_index0, 1);
nat44_set_tcp_session_state_i2o (sm, now, s0, b0, thread_index);
}
else
{
- vlib_increment_simple_counter (&sm->counters.slowpath.in2out_ed.udp,
+ vlib_increment_simple_counter (&sm->counters.slowpath.in2out.udp,
thread_index, sw_if_index0, 1);
}
@@ -1381,9 +1440,8 @@ nat44_ed_in2out_slow_path_node_fn_inline (vlib_main_t * vm,
if (next[0] == NAT_NEXT_DROP)
{
- vlib_increment_simple_counter (&sm->counters.slowpath.
- in2out_ed.drops, thread_index,
- sw_if_index0, 1);
+ vlib_increment_simple_counter (&sm->counters.slowpath.in2out.drops,
+ thread_index, sw_if_index0, 1);
}
n_left_from--;
@@ -1404,7 +1462,6 @@ VLIB_NODE_FN (nat44_ed_in2out_node) (vlib_main_t * vm,
return nat44_ed_in2out_fast_path_node_fn_inline (vm, node, frame, 0);
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (nat44_ed_in2out_node) = {
.name = "nat44-ed-in2out",
.vector_size = sizeof (u32),
@@ -1415,7 +1472,6 @@ VLIB_REGISTER_NODE (nat44_ed_in2out_node) = {
.error_strings = nat_in2out_ed_error_strings,
.runtime_data_bytes = sizeof (snat_runtime_t),
};
-/* *INDENT-ON* */
VLIB_NODE_FN (nat44_ed_in2out_output_node) (vlib_main_t * vm,
vlib_node_runtime_t * node,
@@ -1424,7 +1480,6 @@ VLIB_NODE_FN (nat44_ed_in2out_output_node) (vlib_main_t * vm,
return nat44_ed_in2out_fast_path_node_fn_inline (vm, node, frame, 1);
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (nat44_ed_in2out_output_node) = {
.name = "nat44-ed-in2out-output",
.vector_size = sizeof (u32),
@@ -1435,7 +1490,6 @@ VLIB_REGISTER_NODE (nat44_ed_in2out_output_node) = {
.error_strings = nat_in2out_ed_error_strings,
.runtime_data_bytes = sizeof (snat_runtime_t),
};
-/* *INDENT-ON* */
VLIB_NODE_FN (nat44_ed_in2out_slowpath_node) (vlib_main_t * vm,
vlib_node_runtime_t *
@@ -1444,7 +1498,6 @@ VLIB_NODE_FN (nat44_ed_in2out_slowpath_node) (vlib_main_t * vm,
return nat44_ed_in2out_slow_path_node_fn_inline (vm, node, frame, 0);
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (nat44_ed_in2out_slowpath_node) = {
.name = "nat44-ed-in2out-slowpath",
.vector_size = sizeof (u32),
@@ -1455,7 +1508,6 @@ VLIB_REGISTER_NODE (nat44_ed_in2out_slowpath_node) = {
.error_strings = nat_in2out_ed_error_strings,
.runtime_data_bytes = sizeof (snat_runtime_t),
};
-/* *INDENT-ON* */
VLIB_NODE_FN (nat44_ed_in2out_output_slowpath_node) (vlib_main_t * vm,
vlib_node_runtime_t
@@ -1465,7 +1517,6 @@ VLIB_NODE_FN (nat44_ed_in2out_output_slowpath_node) (vlib_main_t * vm,
return nat44_ed_in2out_slow_path_node_fn_inline (vm, node, frame, 1);
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (nat44_ed_in2out_output_slowpath_node) = {
.name = "nat44-ed-in2out-output-slowpath",
.vector_size = sizeof (u32),
@@ -1476,7 +1527,6 @@ VLIB_REGISTER_NODE (nat44_ed_in2out_output_slowpath_node) = {
.error_strings = nat_in2out_ed_error_strings,
.runtime_data_bytes = sizeof (snat_runtime_t),
};
-/* *INDENT-ON* */
static u8 *
format_nat_pre_trace (u8 * s, va_list * args)
@@ -1502,7 +1552,6 @@ VLIB_NODE_FN (nat_pre_in2out_output_node)
NAT_NEXT_IN2OUT_ED_OUTPUT_FAST_PATH);
}
-/* *INDENT-OFF* */
VLIB_REGISTER_NODE (nat_pre_in2out_node) = {
.name = "nat-pre-in2out",
.vector_size = sizeof (u32),
@@ -1520,7 +1569,6 @@ VLIB_REGISTER_NODE (nat_pre_in2out_output_node) = {
.type = VLIB_NODE_TYPE_INTERNAL,
.n_errors = 0,
};
-/* *INDENT-ON* */
/*
* fd.io coding-style-patch-verification: ON
diff --git a/src/plugins/nat/nat44-ed/nat44_ed_inlines.h b/src/plugins/nat/nat44-ed/nat44_ed_inlines.h
new file mode 100644
index 00000000000..0623940cb6d
--- /dev/null
+++ b/src/plugins/nat/nat44-ed/nat44_ed_inlines.h
@@ -0,0 +1,869 @@
+/*
+ * Copyright (c) 2018 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @brief The NAT inline functions
+ */
+
+#ifndef __included_nat44_ed_inlines_h__
+#define __included_nat44_ed_inlines_h__
+
+#include <float.h>
+#include <vppinfra/clib.h>
+#include <vnet/fib/ip4_fib.h>
+
+#include <nat/lib/log.h>
+#include <nat/nat44-ed/nat44_ed.h>
+
+always_inline u64
+calc_nat_key (ip4_address_t addr, u16 port, u32 fib_index, u8 proto)
+{
+ ASSERT (fib_index <= (1 << 14) - 1);
+ ASSERT (proto <= (1 << 3) - 1);
+ return (u64) addr.as_u32 << 32 | (u64) port << 16 | fib_index << 3 |
+ (proto & 0x7);
+}
+
+always_inline void
+split_nat_key (u64 key, ip4_address_t *addr, u16 *port, u32 *fib_index,
+ nat_protocol_t *proto)
+{
+ if (addr)
+ {
+ addr->as_u32 = key >> 32;
+ }
+ if (port)
+ {
+ *port = (key >> 16) & (u16) ~0;
+ }
+ if (fib_index)
+ {
+ *fib_index = key >> 3 & ((1 << 13) - 1);
+ }
+ if (proto)
+ {
+ *proto = key & 0x7;
+ }
+}
+
+always_inline void
+init_nat_k (clib_bihash_kv_8_8_t *kv, ip4_address_t addr, u16 port,
+ u32 fib_index, nat_protocol_t proto)
+{
+ kv->key = calc_nat_key (addr, port, fib_index, proto);
+ kv->value = ~0ULL;
+}
+
+always_inline void
+init_nat_kv (clib_bihash_kv_8_8_t *kv, ip4_address_t addr, u16 port,
+ u32 fib_index, nat_protocol_t proto, u32 thread_index,
+ u32 session_index)
+{
+ init_nat_k (kv, addr, port, fib_index, proto);
+ kv->value = (u64) thread_index << 32 | session_index;
+}
+
+always_inline void
+init_nat_i2o_k (clib_bihash_kv_8_8_t *kv, snat_session_t *s)
+{
+ return init_nat_k (kv, s->in2out.addr, s->in2out.port, s->in2out.fib_index,
+ s->nat_proto);
+}
+
+always_inline void
+init_nat_i2o_kv (clib_bihash_kv_8_8_t *kv, snat_session_t *s, u32 thread_index,
+ u32 session_index)
+{
+ init_nat_k (kv, s->in2out.addr, s->in2out.port, s->in2out.fib_index,
+ s->nat_proto);
+ kv->value = (u64) thread_index << 32 | session_index;
+}
+
+always_inline void
+init_nat_o2i_k (clib_bihash_kv_8_8_t *kv, snat_session_t *s)
+{
+ return init_nat_k (kv, s->out2in.addr, s->out2in.port, s->out2in.fib_index,
+ s->nat_proto);
+}
+
+always_inline void
+init_nat_o2i_kv (clib_bihash_kv_8_8_t *kv, snat_session_t *s, u32 thread_index,
+ u32 session_index)
+{
+ init_nat_k (kv, s->out2in.addr, s->out2in.port, s->out2in.fib_index,
+ s->nat_proto);
+ kv->value = (u64) thread_index << 32 | session_index;
+}
+
+always_inline u32
+nat_value_get_thread_index (clib_bihash_kv_8_8_t *value)
+{
+ return value->value >> 32;
+}
+
+always_inline u32
+nat_value_get_session_index (clib_bihash_kv_8_8_t *value)
+{
+ return value->value & ~(u32) 0;
+}
+
+always_inline void
+init_ed_k (clib_bihash_kv_16_8_t *kv, ip4_address_t l_addr, u16 l_port,
+ ip4_address_t r_addr, u16 r_port, u32 fib_index, u8 proto)
+{
+ kv->key[0] = (u64) r_addr.as_u32 << 32 | l_addr.as_u32;
+ kv->key[1] =
+ (u64) r_port << 48 | (u64) l_port << 32 | fib_index << 8 | proto;
+}
+
+always_inline void
+init_ed_kv (clib_bihash_kv_16_8_t *kv, ip4_address_t l_addr, u16 l_port,
+ ip4_address_t r_addr, u16 r_port, u32 fib_index, u8 proto,
+ u32 thread_index, u32 session_index)
+{
+ init_ed_k (kv, l_addr, l_port, r_addr, r_port, fib_index, proto);
+ kv->value = (u64) thread_index << 32 | session_index;
+}
+
+always_inline u32
+ed_value_get_thread_index (clib_bihash_kv_16_8_t *value)
+{
+ return value->value >> 32;
+}
+
+always_inline u32
+ed_value_get_session_index (clib_bihash_kv_16_8_t *value)
+{
+ return value->value & ~(u32) 0;
+}
+
+always_inline void
+split_ed_kv (clib_bihash_kv_16_8_t *kv, ip4_address_t *l_addr,
+ ip4_address_t *r_addr, u8 *proto, u32 *fib_index, u16 *l_port,
+ u16 *r_port)
+{
+ if (l_addr)
+ {
+ l_addr->as_u32 = kv->key[0] & (u32) ~0;
+ }
+ if (r_addr)
+ {
+ r_addr->as_u32 = kv->key[0] >> 32;
+ }
+ if (r_port)
+ {
+ *r_port = kv->key[1] >> 48;
+ }
+ if (l_port)
+ {
+ *l_port = (kv->key[1] >> 32) & (u16) ~0;
+ }
+ if (fib_index)
+ {
+ *fib_index = (kv->key[1] >> 8) & ((1 << 24) - 1);
+ }
+ if (proto)
+ {
+ *proto = kv->key[1] & (u8) ~0;
+ }
+}
+
+static_always_inline int
+nat_get_icmp_session_lookup_values (vlib_buffer_t *b, ip4_header_t *ip0,
+ ip4_address_t *lookup_saddr,
+ u16 *lookup_sport,
+ ip4_address_t *lookup_daddr,
+ u16 *lookup_dport, u8 *lookup_protocol)
+{
+ icmp46_header_t *icmp0;
+ icmp_echo_header_t *echo0, *inner_echo0 = 0;
+ ip4_header_t *inner_ip0 = 0;
+ void *l4_header = 0;
+ icmp46_header_t *inner_icmp0;
+
+ icmp0 = (icmp46_header_t *) ip4_next_header (ip0);
+ echo0 = (icmp_echo_header_t *) (icmp0 + 1);
+
+ // avoid warning about unused variables in caller by setting to bogus values
+ *lookup_sport = 0;
+ *lookup_dport = 0;
+
+ if (!icmp_type_is_error_message (
+ vnet_buffer (b)->ip.reass.icmp_type_or_tcp_flags))
+ {
+ *lookup_protocol = IP_PROTOCOL_ICMP;
+ lookup_saddr->as_u32 = ip0->src_address.as_u32;
+ *lookup_sport = vnet_buffer (b)->ip.reass.l4_src_port;
+ lookup_daddr->as_u32 = ip0->dst_address.as_u32;
+ *lookup_dport = vnet_buffer (b)->ip.reass.l4_dst_port;
+ }
+ else
+ {
+ inner_ip0 = (ip4_header_t *) (echo0 + 1);
+ l4_header = ip4_next_header (inner_ip0);
+ *lookup_protocol = inner_ip0->protocol;
+ lookup_saddr->as_u32 = inner_ip0->dst_address.as_u32;
+ lookup_daddr->as_u32 = inner_ip0->src_address.as_u32;
+ switch (ip_proto_to_nat_proto (inner_ip0->protocol))
+ {
+ case NAT_PROTOCOL_ICMP:
+ inner_icmp0 = (icmp46_header_t *) l4_header;
+ inner_echo0 = (icmp_echo_header_t *) (inner_icmp0 + 1);
+ *lookup_sport = inner_echo0->identifier;
+ *lookup_dport = inner_echo0->identifier;
+ break;
+ case NAT_PROTOCOL_UDP:
+ case NAT_PROTOCOL_TCP:
+ *lookup_sport = ((tcp_udp_header_t *) l4_header)->dst_port;
+ *lookup_dport = ((tcp_udp_header_t *) l4_header)->src_port;
+ break;
+ default:
+ return NAT_IN2OUT_ED_ERROR_UNSUPPORTED_PROTOCOL;
+ }
+ }
+ return 0;
+}
+
+always_inline u32
+nat44_session_get_timeout (snat_main_t *sm, snat_session_t *s)
+{
+ switch (s->nat_proto)
+ {
+ case NAT_PROTOCOL_ICMP:
+ return sm->timeouts.icmp;
+ case NAT_PROTOCOL_UDP:
+ return sm->timeouts.udp;
+ case NAT_PROTOCOL_TCP:
+ {
+ if (s->state)
+ return sm->timeouts.tcp.transitory;
+ else
+ return sm->timeouts.tcp.established;
+ }
+ default:
+ return sm->timeouts.udp;
+ }
+
+ return 0;
+}
+
+static_always_inline u8
+nat44_ed_maximum_sessions_exceeded (snat_main_t *sm, u32 fib_index,
+ u32 thread_index)
+{
+ u32 translations;
+ translations = pool_elts (sm->per_thread_data[thread_index].sessions);
+ if (vec_len (sm->max_translations_per_fib) <= fib_index)
+ fib_index = 0;
+ return translations >= sm->max_translations_per_fib[fib_index];
+}
+
+static_always_inline int
+nat_ed_lru_insert (snat_main_per_thread_data_t *tsm, snat_session_t *s,
+ f64 now, u8 proto)
+{
+ dlist_elt_t *lru_list_elt;
+ pool_get (tsm->lru_pool, lru_list_elt);
+ s->lru_index = lru_list_elt - tsm->lru_pool;
+ switch (proto)
+ {
+ case IP_PROTOCOL_UDP:
+ s->lru_head_index = tsm->udp_lru_head_index;
+ break;
+ case IP_PROTOCOL_TCP:
+ s->lru_head_index = tsm->tcp_trans_lru_head_index;
+ break;
+ case IP_PROTOCOL_ICMP:
+ s->lru_head_index = tsm->icmp_lru_head_index;
+ break;
+ default:
+ s->lru_head_index = tsm->unk_proto_lru_head_index;
+ break;
+ }
+ clib_dlist_addtail (tsm->lru_pool, s->lru_head_index, s->lru_index);
+ lru_list_elt->value = s - tsm->sessions;
+ s->last_lru_update = now;
+ return 1;
+}
+
+static_always_inline void
+nat_6t_flow_to_ed_k (clib_bihash_kv_16_8_t *kv, nat_6t_flow_t *f)
+{
+ init_ed_k (kv, f->match.saddr, f->match.sport, f->match.daddr,
+ f->match.dport, f->match.fib_index, f->match.proto);
+}
+
+static_always_inline void
+nat_6t_flow_to_ed_kv (clib_bihash_kv_16_8_t *kv, nat_6t_flow_t *f,
+ u32 thread_idx, u32 session_idx)
+{
+ init_ed_kv (kv, f->match.saddr, f->match.sport, f->match.daddr,
+ f->match.dport, f->match.fib_index, f->match.proto, thread_idx,
+ session_idx);
+}
+
+static_always_inline int
+nat_ed_ses_i2o_flow_hash_add_del (snat_main_t *sm, u32 thread_idx,
+ snat_session_t *s, int is_add)
+{
+ snat_main_per_thread_data_t *tsm =
+ vec_elt_at_index (sm->per_thread_data, thread_idx);
+ clib_bihash_kv_16_8_t kv;
+ if (0 == is_add)
+ {
+ nat_6t_flow_to_ed_k (&kv, &s->i2o);
+ }
+ else
+ {
+ nat_6t_flow_to_ed_kv (&kv, &s->i2o, thread_idx, s - tsm->sessions);
+ nat_6t_l3_l4_csum_calc (&s->i2o);
+ }
+ return clib_bihash_add_del_16_8 (&sm->flow_hash, &kv, is_add);
+}
+
+static_always_inline int
+nat_ed_ses_o2i_flow_hash_add_del (snat_main_t *sm, u32 thread_idx,
+ snat_session_t *s, int is_add)
+{
+ snat_main_per_thread_data_t *tsm =
+ vec_elt_at_index (sm->per_thread_data, thread_idx);
+ clib_bihash_kv_16_8_t kv;
+ if (0 == is_add)
+ {
+ nat_6t_flow_to_ed_k (&kv, &s->o2i);
+ }
+ else
+ {
+ nat_6t_flow_to_ed_kv (&kv, &s->o2i, thread_idx, s - tsm->sessions);
+ nat_6t_l3_l4_csum_calc (&s->o2i);
+ }
+ return clib_bihash_add_del_16_8 (&sm->flow_hash, &kv, is_add);
+}
+
+always_inline void
+nat_ed_session_delete (snat_main_t *sm, snat_session_t *ses, u32 thread_index,
+ int lru_delete
+ /* delete from global LRU list */)
+{
+ snat_main_per_thread_data_t *tsm =
+ vec_elt_at_index (sm->per_thread_data, thread_index);
+
+ if (lru_delete)
+ {
+ clib_dlist_remove (tsm->lru_pool, ses->lru_index);
+ }
+ pool_put_index (tsm->lru_pool, ses->lru_index);
+ if (nat_ed_ses_i2o_flow_hash_add_del (sm, thread_index, ses, 0))
+ nat_elog_warn (sm, "flow hash del failed");
+ if (nat_ed_ses_o2i_flow_hash_add_del (sm, thread_index, ses, 0))
+ nat_elog_warn (sm, "flow hash del failed");
+ pool_put (tsm->sessions, ses);
+ vlib_set_simple_counter (&sm->total_sessions, thread_index, 0,
+ pool_elts (tsm->sessions));
+}
+
+static_always_inline int
+nat_lru_free_one_with_head (snat_main_t *sm, int thread_index, f64 now,
+ u32 head_index)
+{
+ snat_session_t *s = NULL;
+ dlist_elt_t *oldest_elt;
+ f64 sess_timeout_time;
+ u32 oldest_index;
+ snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
+ oldest_index = clib_dlist_remove_head (tsm->lru_pool, head_index);
+ if (~0 != oldest_index)
+ {
+ oldest_elt = pool_elt_at_index (tsm->lru_pool, oldest_index);
+ s = pool_elt_at_index (tsm->sessions, oldest_elt->value);
+
+ sess_timeout_time =
+ s->last_heard + (f64) nat44_session_get_timeout (sm, s);
+ if (now >= sess_timeout_time ||
+ (s->tcp_closed_timestamp && now >= s->tcp_closed_timestamp))
+ {
+ nat_free_session_data (sm, s, thread_index, 0);
+ nat_ed_session_delete (sm, s, thread_index, 0);
+ return 1;
+ }
+ else
+ {
+ clib_dlist_addhead (tsm->lru_pool, head_index, oldest_index);
+ }
+ }
+ return 0;
+}
+
+static_always_inline int
+nat_lru_free_one (snat_main_t *sm, int thread_index, f64 now)
+{
+ snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
+ int rc = 0;
+#define _(p) \
+ if ((rc = nat_lru_free_one_with_head (sm, thread_index, now, \
+ tsm->p##_lru_head_index))) \
+ { \
+ return rc; \
+ }
+ _ (tcp_trans);
+ _ (udp);
+ _ (unk_proto);
+ _ (icmp);
+ _ (tcp_estab);
+#undef _
+ return 0;
+}
+
+static_always_inline snat_session_t *
+nat_ed_session_alloc (snat_main_t *sm, u32 thread_index, f64 now, u8 proto)
+{
+ snat_session_t *s;
+ snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
+
+ nat_lru_free_one (sm, thread_index, now);
+
+ pool_get (tsm->sessions, s);
+ clib_memset (s, 0, sizeof (*s));
+
+ nat_ed_lru_insert (tsm, s, now, proto);
+
+ s->ha_last_refreshed = now;
+ vlib_set_simple_counter (&sm->total_sessions, thread_index, 0,
+ pool_elts (tsm->sessions));
+ return s;
+}
+
+// slow path
+static_always_inline void
+per_vrf_sessions_cleanup (u32 thread_index)
+{
+ snat_main_t *sm = &snat_main;
+ snat_main_per_thread_data_t *tsm =
+ vec_elt_at_index (sm->per_thread_data, thread_index);
+ per_vrf_sessions_t *per_vrf_sessions;
+ u32 *to_free = 0, *i;
+
+ vec_foreach (per_vrf_sessions, tsm->per_vrf_sessions_vec)
+ {
+ if (per_vrf_sessions->expired)
+ {
+ if (per_vrf_sessions->ses_count == 0)
+ {
+ vec_add1 (to_free, per_vrf_sessions - tsm->per_vrf_sessions_vec);
+ }
+ }
+ }
+
+ if (vec_len (to_free))
+ {
+ vec_foreach (i, to_free)
+ {
+ vec_del1 (tsm->per_vrf_sessions_vec, *i);
+ }
+ }
+
+ vec_free (to_free);
+}
+
+// slow path
+static_always_inline void
+per_vrf_sessions_register_session (snat_session_t *s, u32 thread_index)
+{
+ snat_main_t *sm = &snat_main;
+ snat_main_per_thread_data_t *tsm =
+ vec_elt_at_index (sm->per_thread_data, thread_index);
+ per_vrf_sessions_t *per_vrf_sessions;
+
+ per_vrf_sessions_cleanup (thread_index);
+
+ // s->per_vrf_sessions_index == ~0 ... reuse of old session
+
+ vec_foreach (per_vrf_sessions, tsm->per_vrf_sessions_vec)
+ {
+ // ignore already expired registrations
+ if (per_vrf_sessions->expired)
+ continue;
+
+ if ((s->in2out.fib_index == per_vrf_sessions->rx_fib_index) &&
+ (s->out2in.fib_index == per_vrf_sessions->tx_fib_index))
+ {
+ goto done;
+ }
+ if ((s->in2out.fib_index == per_vrf_sessions->tx_fib_index) &&
+ (s->out2in.fib_index == per_vrf_sessions->rx_fib_index))
+ {
+ goto done;
+ }
+ }
+
+ // create a new registration
+ vec_add2 (tsm->per_vrf_sessions_vec, per_vrf_sessions, 1);
+ clib_memset (per_vrf_sessions, 0, sizeof (*per_vrf_sessions));
+
+ per_vrf_sessions->rx_fib_index = s->in2out.fib_index;
+ per_vrf_sessions->tx_fib_index = s->out2in.fib_index;
+
+done:
+ s->per_vrf_sessions_index = per_vrf_sessions - tsm->per_vrf_sessions_vec;
+ per_vrf_sessions->ses_count++;
+}
+
+// fast path
+static_always_inline void
+per_vrf_sessions_unregister_session (snat_session_t *s, u32 thread_index)
+{
+ snat_main_t *sm = &snat_main;
+ snat_main_per_thread_data_t *tsm;
+ per_vrf_sessions_t *per_vrf_sessions;
+
+ ASSERT (s->per_vrf_sessions_index != ~0);
+
+ tsm = vec_elt_at_index (sm->per_thread_data, thread_index);
+ per_vrf_sessions =
+ vec_elt_at_index (tsm->per_vrf_sessions_vec, s->per_vrf_sessions_index);
+
+ ASSERT (per_vrf_sessions->ses_count != 0);
+
+ per_vrf_sessions->ses_count--;
+ s->per_vrf_sessions_index = ~0;
+}
+
+// fast path
+static_always_inline u8
+per_vrf_sessions_is_expired (snat_session_t *s, u32 thread_index)
+{
+ snat_main_t *sm = &snat_main;
+ snat_main_per_thread_data_t *tsm;
+ per_vrf_sessions_t *per_vrf_sessions;
+
+ ASSERT (s->per_vrf_sessions_index != ~0);
+
+ tsm = vec_elt_at_index (sm->per_thread_data, thread_index);
+ per_vrf_sessions =
+ vec_elt_at_index (tsm->per_vrf_sessions_vec, s->per_vrf_sessions_index);
+ return per_vrf_sessions->expired;
+}
+
+static_always_inline void
+nat_6t_flow_init (nat_6t_flow_t *f, u32 thread_idx, ip4_address_t saddr,
+ u16 sport, ip4_address_t daddr, u16 dport, u32 fib_index,
+ u8 proto, u32 session_idx)
+{
+ clib_memset (f, 0, sizeof (*f));
+ f->match.saddr = saddr;
+ f->match.sport = sport;
+ f->match.daddr = daddr;
+ f->match.dport = dport;
+ f->match.proto = proto;
+ f->match.fib_index = fib_index;
+}
+
+static_always_inline void
+nat_6t_i2o_flow_init (snat_main_t *sm, u32 thread_idx, snat_session_t *s,
+ ip4_address_t saddr, u16 sport, ip4_address_t daddr,
+ u16 dport, u32 fib_index, u8 proto)
+{
+ snat_main_per_thread_data_t *tsm =
+ vec_elt_at_index (sm->per_thread_data, thread_idx);
+ nat_6t_flow_init (&s->i2o, thread_idx, saddr, sport, daddr, dport, fib_index,
+ proto, s - tsm->sessions);
+}
+
+static_always_inline void
+nat_6t_o2i_flow_init (snat_main_t *sm, u32 thread_idx, snat_session_t *s,
+ ip4_address_t saddr, u16 sport, ip4_address_t daddr,
+ u16 dport, u32 fib_index, u8 proto)
+{
+ snat_main_per_thread_data_t *tsm =
+ vec_elt_at_index (sm->per_thread_data, thread_idx);
+ nat_6t_flow_init (&s->o2i, thread_idx, saddr, sport, daddr, dport, fib_index,
+ proto, s - tsm->sessions);
+}
+
+static_always_inline int
+nat_6t_flow_match (nat_6t_flow_t *f, vlib_buffer_t *b, ip4_address_t saddr,
+ u16 sport, ip4_address_t daddr, u16 dport, u8 protocol,
+ u32 fib_index)
+{
+ return f->match.daddr.as_u32 == daddr.as_u32 &&
+ f->match.dport == vnet_buffer (b)->ip.reass.l4_dst_port &&
+ f->match.proto == protocol && f->match.fib_index == fib_index &&
+ f->match.saddr.as_u32 == saddr.as_u32 &&
+ f->match.sport == vnet_buffer (b)->ip.reass.l4_src_port;
+}
+
+static inline uword
+nat_pre_node_fn_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
+ vlib_frame_t *frame, u32 def_next)
+{
+ u32 n_left_from, *from;
+
+ from = vlib_frame_vector_args (frame);
+ n_left_from = frame->n_vectors;
+
+ vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b = bufs;
+ u16 nexts[VLIB_FRAME_SIZE], *next = nexts;
+ vlib_get_buffers (vm, from, b, n_left_from);
+
+ while (n_left_from >= 2)
+ {
+ u32 next0, next1;
+ u32 arc_next0, arc_next1;
+ vlib_buffer_t *b0, *b1;
+
+ b0 = *b;
+ b++;
+ b1 = *b;
+ b++;
+
+ /* Prefetch next iteration. */
+ if (PREDICT_TRUE (n_left_from >= 4))
+ {
+ vlib_buffer_t *p2, *p3;
+
+ p2 = *b;
+ p3 = *(b + 1);
+
+ vlib_prefetch_buffer_header (p2, LOAD);
+ vlib_prefetch_buffer_header (p3, LOAD);
+
+ CLIB_PREFETCH (p2->data, CLIB_CACHE_LINE_BYTES, LOAD);
+ CLIB_PREFETCH (p3->data, CLIB_CACHE_LINE_BYTES, LOAD);
+ }
+
+ next0 = def_next;
+ next1 = def_next;
+
+ vnet_feature_next (&arc_next0, b0);
+ vnet_feature_next (&arc_next1, b1);
+
+ vnet_buffer2 (b0)->nat.arc_next = arc_next0;
+ vnet_buffer2 (b1)->nat.arc_next = arc_next1;
+
+ if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)))
+ {
+ if (b0->flags & VLIB_BUFFER_IS_TRACED)
+ {
+ nat_pre_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t));
+ t->next_index = next0;
+ t->arc_next_index = arc_next0;
+ }
+ if (b1->flags & VLIB_BUFFER_IS_TRACED)
+ {
+ nat_pre_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t));
+ t->next_index = next1;
+ t->arc_next_index = arc_next1;
+ }
+ }
+
+ n_left_from -= 2;
+ next[0] = next0;
+ next[1] = next1;
+ next += 2;
+ }
+
+ while (n_left_from > 0)
+ {
+ u32 next0;
+ u32 arc_next0;
+ vlib_buffer_t *b0;
+
+ b0 = *b;
+ b++;
+
+ next0 = def_next;
+ vnet_feature_next (&arc_next0, b0);
+ vnet_buffer2 (b0)->nat.arc_next = arc_next0;
+
+ if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) &&
+ (b0->flags & VLIB_BUFFER_IS_TRACED)))
+ {
+ nat_pre_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t));
+ t->next_index = next0;
+ t->arc_next_index = arc_next0;
+ }
+
+ n_left_from--;
+ next[0] = next0;
+ next++;
+ }
+ vlib_buffer_enqueue_to_next (vm, node, from, (u16 *) nexts,
+ frame->n_vectors);
+
+ return frame->n_vectors;
+}
+
+static_always_inline u16
+snat_random_port (u16 min, u16 max)
+{
+ snat_main_t *sm = &snat_main;
+ u32 rwide;
+ u16 r;
+
+ rwide = random_u32 (&sm->random_seed);
+ r = rwide & 0xFFFF;
+ if (r >= min && r <= max)
+ return r;
+
+ return min + (rwide % (max - min + 1));
+}
+
+always_inline u8
+is_interface_addr (snat_main_t *sm, vlib_node_runtime_t *node,
+ u32 sw_if_index0, u32 ip4_addr)
+{
+ snat_runtime_t *rt = (snat_runtime_t *) node->runtime_data;
+ ip4_address_t *first_int_addr;
+
+ if (PREDICT_FALSE (rt->cached_sw_if_index != sw_if_index0))
+ {
+ first_int_addr = ip4_interface_first_address (
+ sm->ip4_main, sw_if_index0, 0 /* just want the address */);
+ rt->cached_sw_if_index = sw_if_index0;
+ if (first_int_addr)
+ rt->cached_ip4_address = first_int_addr->as_u32;
+ else
+ rt->cached_ip4_address = 0;
+ }
+
+ if (PREDICT_FALSE (ip4_addr == rt->cached_ip4_address))
+ return 1;
+ else
+ return 0;
+}
+
+always_inline void
+nat44_set_tcp_session_state_i2o (snat_main_t *sm, f64 now, snat_session_t *ses,
+ vlib_buffer_t *b, u32 thread_index)
+{
+ snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
+ u8 tcp_flags = vnet_buffer (b)->ip.reass.icmp_type_or_tcp_flags;
+ u32 tcp_ack_number = vnet_buffer (b)->ip.reass.tcp_ack_number;
+ u32 tcp_seq_number = vnet_buffer (b)->ip.reass.tcp_seq_number;
+ if ((ses->state == 0) && (tcp_flags & TCP_FLAG_RST))
+ ses->state = NAT44_SES_RST;
+ if ((ses->state == NAT44_SES_RST) && !(tcp_flags & TCP_FLAG_RST))
+ ses->state = 0;
+ if ((tcp_flags & TCP_FLAG_ACK) && (ses->state & NAT44_SES_I2O_SYN) &&
+ (ses->state & NAT44_SES_O2I_SYN))
+ ses->state = 0;
+ if (tcp_flags & TCP_FLAG_SYN)
+ ses->state |= NAT44_SES_I2O_SYN;
+ if (tcp_flags & TCP_FLAG_FIN)
+ {
+ ses->i2o_fin_seq = clib_net_to_host_u32 (tcp_seq_number);
+ ses->state |= NAT44_SES_I2O_FIN;
+ }
+ if ((tcp_flags & TCP_FLAG_ACK) && (ses->state & NAT44_SES_O2I_FIN))
+ {
+ if (clib_net_to_host_u32 (tcp_ack_number) > ses->o2i_fin_seq)
+ {
+ ses->state |= NAT44_SES_O2I_FIN_ACK;
+ if (nat44_is_ses_closed (ses))
+ { // if session is now closed, save the timestamp
+ ses->tcp_closed_timestamp = now + sm->timeouts.tcp.transitory;
+ ses->last_lru_update = now;
+ }
+ }
+ }
+
+ // move the session to proper LRU
+ if (ses->state)
+ {
+ ses->lru_head_index = tsm->tcp_trans_lru_head_index;
+ }
+ else
+ {
+ ses->lru_head_index = tsm->tcp_estab_lru_head_index;
+ }
+ clib_dlist_remove (tsm->lru_pool, ses->lru_index);
+ clib_dlist_addtail (tsm->lru_pool, ses->lru_head_index, ses->lru_index);
+}
+
+always_inline void
+nat44_set_tcp_session_state_o2i (snat_main_t *sm, f64 now, snat_session_t *ses,
+ u8 tcp_flags, u32 tcp_ack_number,
+ u32 tcp_seq_number, u32 thread_index)
+{
+ snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
+ if ((ses->state == 0) && (tcp_flags & TCP_FLAG_RST))
+ ses->state = NAT44_SES_RST;
+ if ((ses->state == NAT44_SES_RST) && !(tcp_flags & TCP_FLAG_RST))
+ ses->state = 0;
+ if ((tcp_flags & TCP_FLAG_ACK) && (ses->state & NAT44_SES_I2O_SYN) &&
+ (ses->state & NAT44_SES_O2I_SYN))
+ ses->state = 0;
+ if (tcp_flags & TCP_FLAG_SYN)
+ ses->state |= NAT44_SES_O2I_SYN;
+ if (tcp_flags & TCP_FLAG_FIN)
+ {
+ ses->o2i_fin_seq = clib_net_to_host_u32 (tcp_seq_number);
+ ses->state |= NAT44_SES_O2I_FIN;
+ }
+ if ((tcp_flags & TCP_FLAG_ACK) && (ses->state & NAT44_SES_I2O_FIN))
+ {
+ if (clib_net_to_host_u32 (tcp_ack_number) > ses->i2o_fin_seq)
+ ses->state |= NAT44_SES_I2O_FIN_ACK;
+ if (nat44_is_ses_closed (ses))
+ { // if session is now closed, save the timestamp
+ ses->tcp_closed_timestamp = now + sm->timeouts.tcp.transitory;
+ ses->last_lru_update = now;
+ }
+ }
+ // move the session to proper LRU
+ if (ses->state)
+ {
+ ses->lru_head_index = tsm->tcp_trans_lru_head_index;
+ }
+ else
+ {
+ ses->lru_head_index = tsm->tcp_estab_lru_head_index;
+ }
+ clib_dlist_remove (tsm->lru_pool, ses->lru_index);
+ clib_dlist_addtail (tsm->lru_pool, ses->lru_head_index, ses->lru_index);
+}
+
+always_inline void
+nat44_session_update_counters (snat_session_t *s, f64 now, uword bytes,
+ u32 thread_index)
+{
+ s->last_heard = now;
+ s->total_pkts++;
+ s->total_bytes += bytes;
+}
+
+/** \brief Per-user LRU list maintenance */
+always_inline void
+nat44_session_update_lru (snat_main_t *sm, snat_session_t *s, u32 thread_index)
+{
+ /* don't update too often - timeout is in magnitude of seconds anyway */
+ if (s->last_heard > s->last_lru_update + 1)
+ {
+ clib_dlist_remove (sm->per_thread_data[thread_index].lru_pool,
+ s->lru_index);
+ clib_dlist_addtail (sm->per_thread_data[thread_index].lru_pool,
+ s->lru_head_index, s->lru_index);
+ s->last_lru_update = s->last_heard;
+ }
+}
+
+#endif /* __included_nat44_ed_inlines_h__ */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/src/plugins/nat/out2in_ed.c b/src/plugins/nat/nat44-ed/nat44_ed_out2in.c
index d6beadc61bc..4d354d3e8ec 100644
--- a/src/plugins/nat/out2in_ed.c
+++ b/src/plugins/nat/nat44-ed/nat44_ed_out2in.c
@@ -24,12 +24,12 @@
#include <vnet/fib/ip4_fib.h>
#include <vnet/udp/udp_local.h>
#include <vppinfra/error.h>
-#include <nat/nat.h>
-#include <nat/lib/ipfix_logging.h>
-#include <nat/nat_inlines.h>
-#include <nat/nat44/inlines.h>
+
#include <nat/lib/nat_syslog.h>
-#include <nat/nat44/ed_inlines.h>
+#include <nat/lib/ipfix_logging.h>
+
+#include <nat/nat44-ed/nat44_ed.h>
+#include <nat/nat44-ed/nat44_ed_inlines.h>
static char *nat_out2in_ed_error_strings[] = {
#define _(sym,string) string,
@@ -243,6 +243,7 @@ nat_alloc_addr_and_port_exact (snat_address_t * a,
u16 * port,
u16 port_per_thread, u32 snat_thread_index)
{
+ snat_main_t *sm = &snat_main;
u32 portnum;
switch (proto)
@@ -269,8 +270,7 @@ nat_alloc_addr_and_port_exact (snat_address_t * a,
break;
foreach_nat_protocol
#undef _
- default:
- nat_elog_info ("unknown protocol");
+ default : nat_elog_info (sm, "unknown protocol");
return 1;
}
@@ -286,9 +286,10 @@ nat44_ed_alloc_outside_addr_and_port (snat_address_t *addresses, u32 fib_index,
u16 port_per_thread,
u32 snat_thread_index)
{
- int i;
+ snat_main_t *sm = &snat_main;
snat_address_t *a, *ga = 0;
u32 portnum;
+ int i;
for (i = 0; i < vec_len (addresses); i++)
{
@@ -323,7 +324,7 @@ nat44_ed_alloc_outside_addr_and_port (snat_address_t *addresses, u32 fib_index,
break;
foreach_nat_protocol
#undef _
- default : nat_elog_info ("unknown protocol");
+ default : nat_elog_info (sm, "unknown protocol");
return 1;
}
}
@@ -351,7 +352,7 @@ nat44_ed_alloc_outside_addr_and_port (snat_address_t *addresses, u32 fib_index,
break;
foreach_nat_protocol
#undef _
- default : nat_elog_info ("unknown protocol");
+ default : nat_elog_info (sm, "unknown protocol");
return 1;
}
}
@@ -378,15 +379,15 @@ create_session_for_static_mapping_ed (
(nat44_ed_maximum_sessions_exceeded (sm, rx_fib_index, thread_index)))
{
b->error = node->errors[NAT_OUT2IN_ED_ERROR_MAX_SESSIONS_EXCEEDED];
- nat_elog_notice ("maximum sessions exceeded");
+ nat_elog_notice (sm, "maximum sessions exceeded");
return 0;
}
s = nat_ed_session_alloc (sm, thread_index, now, nat_proto);
if (!s)
{
- b->error = node->errors[NAT_OUT2IN_ED_ERROR_MAX_USER_SESS_EXCEEDED];
- nat_elog_warn ("create NAT session failed");
+ b->error = node->errors[NAT_OUT2IN_ED_ERROR_MAX_SESSIONS_EXCEEDED];
+ nat_elog_warn (sm, "create NAT session failed");
return 0;
}
@@ -429,7 +430,7 @@ create_session_for_static_mapping_ed (
{
b->error = node->errors[NAT_OUT2IN_ED_ERROR_HASH_ADD_FAILED];
nat_ed_session_delete (sm, s, thread_index, 1);
- nat_elog_warn ("out2in flow hash add failed");
+ nat_elog_warn (sm, "out2in flow hash add failed");
return 0;
}
@@ -477,7 +478,7 @@ create_session_for_static_mapping_ed (
b->error = node->errors[NAT_OUT2IN_ED_ERROR_OUT_OF_PORTS];
if (nat_ed_ses_o2i_flow_hash_add_del (sm, thread_index, s, 0))
{
- nat_elog_warn ("out2in flow hash del failed");
+ nat_elog_warn (sm, "out2in flow hash del failed");
}
snat_free_outside_address_and_port (
sm->twice_nat_addresses, thread_index, &s->ext_host_nat_addr,
@@ -541,10 +542,10 @@ create_session_for_static_mapping_ed (
if (nat_ed_ses_i2o_flow_hash_add_del (sm, thread_index, s, 1))
{
- nat_elog_notice ("in2out flow hash add failed");
+ nat_elog_notice (sm, "in2out flow hash add failed");
if (nat_ed_ses_o2i_flow_hash_add_del (sm, thread_index, s, 0))
{
- nat_elog_warn ("out2in flow hash del failed");
+ nat_elog_warn (sm, "out2in flow hash del failed");
}
nat_ed_session_delete (sm, s, thread_index, 1);
return 0;
@@ -557,12 +558,11 @@ create_session_for_static_mapping_ed (
s->in2out.port,
s->out2in.port, s->in2out.fib_index);
- nat_syslog_nat44_sadd (s->user_index, s->in2out.fib_index,
- &s->in2out.addr, s->in2out.port,
- &s->ext_host_nat_addr, s->ext_host_nat_port,
- &s->out2in.addr, s->out2in.port,
- &s->ext_host_addr, s->ext_host_port,
- s->nat_proto, is_twice_nat_session (s));
+ nat_syslog_nat44_sadd (0, s->in2out.fib_index, &s->in2out.addr,
+ s->in2out.port, &s->ext_host_nat_addr,
+ s->ext_host_nat_port, &s->out2in.addr, s->out2in.port,
+ &s->ext_host_addr, s->ext_host_port, s->nat_proto,
+ is_twice_nat_session (s));
per_vrf_sessions_register_session (s, thread_index);
@@ -635,7 +635,7 @@ create_bypass_for_fwd (snat_main_t *sm, vlib_buffer_t *b, snat_session_t *s,
s = nat_ed_session_alloc (sm, thread_index, now, ip->protocol);
if (!s)
{
- nat_elog_warn ("create NAT session failed");
+ nat_elog_warn (sm, "create NAT session failed");
return;
}
@@ -663,7 +663,7 @@ create_bypass_for_fwd (snat_main_t *sm, vlib_buffer_t *b, snat_session_t *s,
nat_6t_flow_txfib_rewrite_set (&s->i2o, rx_fib_index);
if (nat_ed_ses_i2o_flow_hash_add_del (sm, thread_index, s, 1))
{
- nat_elog_notice ("in2out flow add failed");
+ nat_elog_notice (sm, "in2out flow add failed");
nat_ed_session_delete (sm, s, thread_index, 1);
return;
}
@@ -700,7 +700,7 @@ nat44_ed_out2in_slowpath_unknown_proto (snat_main_t *sm, vlib_buffer_t *b,
nat44_ed_maximum_sessions_exceeded (sm, rx_fib_index, thread_index)))
{
b->error = node->errors[NAT_OUT2IN_ED_ERROR_MAX_SESSIONS_EXCEEDED];
- nat_elog_notice ("maximum sessions exceeded");
+ nat_elog_notice (sm, "maximum sessions exceeded");
return 0;
}
@@ -717,8 +717,8 @@ nat44_ed_out2in_slowpath_unknown_proto (snat_main_t *sm, vlib_buffer_t *b,
s = nat_ed_session_alloc (sm, thread_index, now, ip->protocol);
if (!s)
{
- b->error = node->errors[NAT_OUT2IN_ED_ERROR_MAX_USER_SESS_EXCEEDED];
- nat_elog_warn ("create NAT session failed");
+ b->error = node->errors[NAT_OUT2IN_ED_ERROR_MAX_SESSIONS_EXCEEDED];
+ nat_elog_warn (sm, "create NAT session failed");
return 0;
}
@@ -737,7 +737,7 @@ nat44_ed_out2in_slowpath_unknown_proto (snat_main_t *sm, vlib_buffer_t *b,
nat_6t_flow_saddr_rewrite_set (&s->i2o, ip->dst_address.as_u32);
if (nat_ed_ses_i2o_flow_hash_add_del (sm, thread_index, s, 1))
{
- nat_elog_notice ("in2out key add failed");
+ nat_elog_notice (sm, "in2out key add failed");
nat_ed_session_delete (sm, s, thread_index, 1);
return NULL;
}
@@ -748,7 +748,7 @@ nat44_ed_out2in_slowpath_unknown_proto (snat_main_t *sm, vlib_buffer_t *b,
nat_6t_flow_txfib_rewrite_set (&s->o2i, m->fib_index);
if (nat_ed_ses_o2i_flow_hash_add_del (sm, thread_index, s, 1))
{
- nat_elog_notice ("out2in flow hash add failed");
+ nat_elog_notice (sm, "out2in flow hash add failed");
nat_ed_session_delete (sm, s, thread_index, 1);
return NULL;
}
@@ -1010,7 +1010,7 @@ nat44_ed_out2in_fast_path_node_fn_inline (vlib_main_t * vm,
switch (proto0)
{
case NAT_PROTOCOL_TCP:
- vlib_increment_simple_counter (&sm->counters.fastpath.out2in_ed.tcp,
+ vlib_increment_simple_counter (&sm->counters.fastpath.out2in.tcp,
thread_index, sw_if_index0, 1);
nat44_set_tcp_session_state_o2i (sm, now, s0,
vnet_buffer (b0)->ip.
@@ -1022,17 +1022,16 @@ nat44_ed_out2in_fast_path_node_fn_inline (vlib_main_t * vm,
thread_index);
break;
case NAT_PROTOCOL_UDP:
- vlib_increment_simple_counter (&sm->counters.fastpath.out2in_ed.udp,
+ vlib_increment_simple_counter (&sm->counters.fastpath.out2in.udp,
thread_index, sw_if_index0, 1);
break;
case NAT_PROTOCOL_ICMP:
- vlib_increment_simple_counter (&sm->counters.fastpath.out2in_ed.icmp,
+ vlib_increment_simple_counter (&sm->counters.fastpath.out2in.icmp,
thread_index, sw_if_index0, 1);
break;
case NAT_PROTOCOL_OTHER:
- vlib_increment_simple_counter (
- &sm->counters.fastpath.out2in_ed.other, thread_index, sw_if_index0,
- 1);
+ vlib_increment_simple_counter (&sm->counters.fastpath.out2in.other,
+ thread_index, sw_if_index0, 1);
break;
}
@@ -1071,9 +1070,8 @@ nat44_ed_out2in_fast_path_node_fn_inline (vlib_main_t * vm,
if (next[0] == NAT_NEXT_DROP)
{
- vlib_increment_simple_counter (&sm->counters.fastpath.
- out2in_ed.drops, thread_index,
- sw_if_index0, 1);
+ vlib_increment_simple_counter (&sm->counters.fastpath.out2in.drops,
+ thread_index, sw_if_index0, 1);
}
n_left_from--;
@@ -1163,9 +1161,8 @@ nat44_ed_out2in_slow_path_node_fn_inline (vlib_main_t * vm,
goto trace0;
}
- vlib_increment_simple_counter (&sm->counters.slowpath.
- out2in_ed.other, thread_index,
- sw_if_index0, 1);
+ vlib_increment_simple_counter (&sm->counters.slowpath.out2in.other,
+ thread_index, sw_if_index0, 1);
goto trace0;
}
@@ -1183,9 +1180,8 @@ nat44_ed_out2in_slow_path_node_fn_inline (vlib_main_t * vm,
goto trace0;
}
- vlib_increment_simple_counter (&sm->counters.slowpath.
- out2in_ed.icmp, thread_index,
- sw_if_index0, 1);
+ vlib_increment_simple_counter (&sm->counters.slowpath.out2in.icmp,
+ thread_index, sw_if_index0, 1);
goto trace0;
}
@@ -1297,7 +1293,7 @@ nat44_ed_out2in_slow_path_node_fn_inline (vlib_main_t * vm,
if (PREDICT_TRUE (proto0 == NAT_PROTOCOL_TCP))
{
- vlib_increment_simple_counter (&sm->counters.slowpath.out2in_ed.tcp,
+ vlib_increment_simple_counter (&sm->counters.slowpath.out2in.tcp,
thread_index, sw_if_index0, 1);
nat44_set_tcp_session_state_o2i (sm, now, s0,
vnet_buffer (b0)->ip.
@@ -1310,7 +1306,7 @@ nat44_ed_out2in_slow_path_node_fn_inline (vlib_main_t * vm,
}
else
{
- vlib_increment_simple_counter (&sm->counters.slowpath.out2in_ed.udp,
+ vlib_increment_simple_counter (&sm->counters.slowpath.out2in.udp,
thread_index, sw_if_index0, 1);
}
@@ -1347,9 +1343,8 @@ nat44_ed_out2in_slow_path_node_fn_inline (vlib_main_t * vm,
if (next[0] == NAT_NEXT_DROP)
{
- vlib_increment_simple_counter (&sm->counters.slowpath.
- out2in_ed.drops, thread_index,
- sw_if_index0, 1);
+ vlib_increment_simple_counter (&sm->counters.slowpath.out2in.drops,
+ thread_index, sw_if_index0, 1);
}
n_left_from--;
diff --git a/src/plugins/nat/nat44-ei/nat44_ei.api b/src/plugins/nat/nat44-ei/nat44_ei.api
new file mode 100644
index 00000000000..708c20aaadd
--- /dev/null
+++ b/src/plugins/nat/nat44-ei/nat44_ei.api
@@ -0,0 +1,862 @@
+/*
+ * Copyright (c) 2020 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+option version = "1.0.0";
+import "vnet/ip/ip_types.api";
+import "vnet/interface_types.api";
+import "plugins/nat/lib/nat_types.api";
+
+enum nat44_ei_config_flags : u8
+{
+ NAT44_EI_NONE = 0x00,
+ NAT44_EI_STATIC_MAPPING_ONLY = 0x01,
+ NAT44_EI_CONNECTION_TRACKING = 0x02,
+ NAT44_EI_OUT2IN_DPO = 0x04,
+ NAT44_EI_ADDR_ONLY_MAPPING = 0x08,
+ NAT44_EI_IF_INSIDE = 0x10,
+ NAT44_EI_IF_OUTSIDE = 0x20,
+ NAT44_EI_STATIC_MAPPING = 0x40,
+};
+
+/** \brief Enable/disable NAT44 plugin
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param inside_vrf - inside vrf id
+ @param outside_vrf - outside vrf id
+ @param users - maximum number of users per thread
+ @param user_memory - overwrite hash allocation parameter
+ @param sessions - maximum number of sessions per thread
+ @param session_memory - overwrite hash allocation parameter
+ @param user_sessions - maximum number of sessions per user
+ @param enable - true if enable, false if disable
+ @param flags - flag NAT44_EI_IS_STATIC_MAPPING_ONLY,
+ NAT44_EI_IS_CONNECTION_TRACKING,
+ NAT44_EI_IS_OUT2IN_DPO
+*/
+autoreply define nat44_ei_plugin_enable_disable {
+ option in_progress;
+ u32 client_index;
+ u32 context;
+ u32 inside_vrf;
+ u32 outside_vrf;
+ u32 users;
+ u32 user_memory;
+ u32 sessions;
+ u32 session_memory;
+ u32 user_sessions;
+ bool enable;
+ vl_api_nat44_ei_config_flags_t flags;
+};
+
+/** \brief Show NAT44 plugin running config
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+*/
+define nat44_ei_show_running_config
+{
+ option in_progress;
+ u32 client_index;
+ u32 context;
+};
+
+/** \brief Show NAT44 plugin running config reply
+ @param context - sender context, to match reply w/ request
+ @param retval - return code for the request
+ @param inside_vrf - default inside VRF id
+ @param outside_vrf - outside VRF id
+ @param users - maximum number of users per worker thread
+ @param sessions - maximum number of sessions per worker thread
+ @param user_sessions - maximum number of sessions per user
+ @param user_buckets - number of user hash buckets
+ @param translation_buckets - number of translation hash buckets
+ @param flags - flag NAT44_EI_IS_STATIC_MAPPING_ONLY,
+ NAT44_EI_IS_CONNECTION_TRACKING,
+ NAT44_EI_IS_OUT2IN_DPO
+*/
+define nat44_ei_show_running_config_reply
+{
+ option in_progress;
+ u32 context;
+ i32 retval;
+ u32 inside_vrf;
+ u32 outside_vrf;
+ u32 users;
+ u32 sessions;
+ u32 user_sessions;
+ u32 user_buckets;
+ u32 translation_buckets;
+ bool forwarding_enabled;
+ bool ipfix_logging_enabled;
+ vl_api_nat_timeouts_t timeouts;
+ vl_api_nat_log_level_t log_level;
+ vl_api_nat44_ei_config_flags_t flags;
+};
+
+/** \brief Set NAT44 logging level
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param log_level - logging level
+*/
+autoreply define nat44_ei_set_log_level {
+ option deprecated;
+ u32 client_index;
+ u32 context;
+ vl_api_nat_log_level_t log_level;
+};
+
+/** \brief Set NAT workers
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param worker_mask - NAT workers mask
+*/
+autoreply define nat44_ei_set_workers {
+ option in_progress;
+ u32 client_index;
+ u32 context;
+ u64 worker_mask;
+};
+
+/** \brief Dump NAT workers
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+*/
+define nat44_ei_worker_dump {
+ option in_progress;
+ u32 client_index;
+ u32 context;
+};
+
+/** \brief NAT workers details response
+ @param context - sender context, to match reply w/ request
+ @param worker_index - worker index
+ @param lcore_id - lcore ID
+ @param name - worker name
+*/
+define nat44_ei_worker_details {
+ option in_progress;
+ u32 context;
+ u32 worker_index;
+ u32 lcore_id;
+ string name[64];
+};
+
+/** \brief Enable/disable NAT IPFIX logging
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param domain_id - observation domain ID
+ @param src_port - source port number
+ @param enable - true if enable, false if disable
+*/
+autoreply define nat44_ei_ipfix_enable_disable {
+ option in_progress;
+ u32 client_index;
+ u32 context;
+ u32 domain_id;
+ u16 src_port;
+ bool enable;
+};
+
+/** \brief Set values of timeouts for NAT sessions (seconds)
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param udp - UDP timeout (default 300sec)
+ @param tcp_established - TCP established timeout (default 7440sec)
+ @param tcp_transitory - TCP transitory timeout (default 240sec)
+ @param icmp - ICMP timeout (default 60sec)
+*/
+autoreply define nat44_ei_set_timeouts {
+ option in_progress;
+ u32 client_index;
+ u32 context;
+ u32 udp;
+ u32 tcp_established;
+ u32 tcp_transitory;
+ u32 icmp;
+};
+
+/** \brief Set address and port assignment algorithm
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param alg - address and port assignment algorithm:
+ 0 - default, 1 - MAP-E, 2 - port range
+ (see nat44_ei_addr_and_port_alloc_alg_t in nat.h)
+ @param psid_offset - number of offset bits (valid only for MAP-E alg)
+ @param psid_length - length of PSID (valid only for MAP-E alg)
+ @param psid - Port Set Identifier (PSID) value (valid only for MAP-E alg)
+ @param start_port - beginning of the port range
+ @param end_port - end of the port range
+*/
+autoreply define nat44_ei_set_addr_and_port_alloc_alg {
+ option in_progress;
+ u32 client_index;
+ u32 context;
+ u8 alg;
+ u8 psid_offset;
+ u8 psid_length;
+ u16 psid;
+ u16 start_port;
+ u16 end_port;
+};
+
+/** \brief Get address and port assignment algorithm
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+*/
+define nat44_ei_get_addr_and_port_alloc_alg {
+ option deprecated;
+ u32 client_index;
+ u32 context;
+};
+
+/** \brief Get address and port assignment algorithm reply
+ @param context - sender context, to match reply w/ request
+ @param retval - return code
+ @param alg - address and port assignment algorithm:
+ 0 - default, 1 - MAP-E, 2 - port range
+ (see nat44_ei_addr_and_port_alloc_alg_t in nat.h)
+ @param psid_offset - number of offset bits (valid only for MAP-E alg)
+ @param psid_length - length of PSID (valid only for MAP-E alg)
+ @param psid - Port Set Identifier (PSID) value (valid only for MAP-E alg)
+ @param start_port - beginning of the port range
+ @param end_port - end of the port range
+*/
+define nat44_ei_get_addr_and_port_alloc_alg_reply {
+ option deprecated;
+ u32 context;
+ i32 retval;
+ u8 alg;
+ u8 psid_offset;
+ u8 psid_length;
+ u16 psid;
+ u16 start_port;
+ u16 end_port;
+};
+
+/** \brief Set TCP MSS rewriting configuration
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param mss_value - MSS value to be used for MSS rewriting
+ @param enable - if true enable MSS rewriting feature else disable
+*/
+autoreply define nat44_ei_set_mss_clamping {
+ option in_progress;
+ u32 client_index;
+ u32 context;
+ u16 mss_value;
+ bool enable;
+};
+
+/** \brief Get TCP MSS rewriting configuration
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+*/
+define nat44_ei_get_mss_clamping {
+ option deprecated;
+ u32 client_index;
+ u32 context;
+};
+
+/** \brief Get TCP MSS rewriting configuration reply
+ @param context - sender context, to match reply w/ request
+ @param retval - return code
+ @param mss_value - MSS value to be used for MSS rewriting
+ @param enable - if true enable MSS rewriting feature else disable
+*/
+define nat44_ei_get_mss_clamping_reply {
+ option deprecated;
+ u32 context;
+ i32 retval;
+ u16 mss_value;
+ bool enable;
+};
+
+/** \brief Set HA listener (local settings)
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param ip_address - local IP4 address
+ @param port - local UDP port number
+ @param path_mtu - path MTU between local and failover
+*/
+autoreply define nat44_ei_ha_set_listener {
+ option in_progress;
+ u32 client_index;
+ u32 context;
+ vl_api_ip4_address_t ip_address;
+ u16 port;
+ u32 path_mtu;
+};
+
+/** \brief Set HA failover (remote settings)
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param ip_address - failover IP4 address
+ @param port - failvoer UDP port number
+ @param session_refresh_interval - number of seconds after which to send
+ session counters refresh
+*/
+autoreply define nat44_ei_ha_set_failover {
+ option in_progress;
+ u32 client_index;
+ u32 context;
+ vl_api_ip4_address_t ip_address;
+ u16 port;
+ u32 session_refresh_interval;
+};
+
+/** \brief Get HA listener/local configuration
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+*/
+define nat44_ei_ha_get_listener {
+ option deprecated;
+ u32 client_index;
+ u32 context;
+};
+
+/** \brief Get HA listener/local configuration reply
+ @param context - sender context, to match reply w/ request
+ @param retval - return code
+ @param ip_address - local IP4 address
+ @param port - local UDP port number
+ @param path_mtu - Path MTU between local and failover
+*/
+define nat44_ei_ha_get_listener_reply {
+ option deprecated;
+ u32 context;
+ i32 retval;
+ vl_api_ip4_address_t ip_address;
+ u16 port;
+ u32 path_mtu;
+};
+
+/** \brief Get HA failover/remote settings
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+*/
+define nat44_ei_ha_get_failover {
+ option deprecated;
+ u32 client_index;
+ u32 context;
+};
+
+/** \brief Get HA failover/remote settings reply
+ @param context - sender context, to match reply w/ request
+ @param retval - return code
+ @param ip_address - failover IP4 address
+ @param port - failvoer UDP port number
+ @param session_refresh_interval - number of seconds after which to send
+ session counters refresh
+*/
+define nat44_ei_ha_get_failover_reply {
+ option deprecated;
+ u32 context;
+ i32 retval;
+ vl_api_ip4_address_t ip_address;
+ u16 port;
+ u32 session_refresh_interval;
+};
+
+/** \brief Flush the current HA data (for testing)
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+*/
+autoreply define nat44_ei_ha_flush {
+ option in_progress;
+ u32 client_index;
+ u32 context;
+};
+
+/** \brief Resync HA (resend existing sessions to new failover)
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param want_resync_event - resync completed event sent to the sender via
+ nat44_ei_ha_resync_completed_event API message if
+ non-zero
+ @param pid - sender's pid
+*/
+autoreply define nat44_ei_ha_resync
+{
+ option in_progress;
+ u32 client_index;
+ u32 context;
+ u8 want_resync_event;
+ u32 pid;
+};
+
+/** \brief Tell client about a HA resync completion event
+ @param client_index - opaque cookie to identify the sender
+ @param pid - client pid registered to receive notification
+ @param missed_count - number of missed (not ACKed) messages
+*/
+define nat44_ei_ha_resync_completed_event
+{
+ option in_progress;
+ u32 client_index;
+ u32 pid;
+ u32 missed_count;
+};
+
+service {
+ rpc nat44_ei_ha_resync returns nat44_ei_ha_resync_reply events nat44_ei_ha_resync_completed_event;
+};
+
+/** \brief Del NAT44 user
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param ip_address - IPv4 address
+ @param fib_index - FIB index
+*/
+autoreply define nat44_ei_del_user {
+ option in_progress;
+ u32 client_index;
+ u32 context;
+ vl_api_ip4_address_t ip_address;
+ u32 fib_index;
+};
+
+/** \brief Add/del NAT44 address range
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param first_ip_address - first IPv4 address
+ @param last_ip_address - last IPv4 address
+ @param vrf_id - VRF id of tenant, ~0 means independent of VRF
+ @param is_add - true if add, false if delete
+
+*/
+autoreply define nat44_ei_add_del_address_range {
+ option in_progress;
+ u32 client_index;
+ u32 context;
+ vl_api_ip4_address_t first_ip_address;
+ vl_api_ip4_address_t last_ip_address;
+ u32 vrf_id;
+ bool is_add;
+};
+
+/** \brief Dump NAT44 addresses
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+*/
+define nat44_ei_address_dump {
+ option in_progress;
+ u32 client_index;
+ u32 context;
+};
+
+/** \brief NAT44 address details response
+ @param context - sender context, to match reply w/ request
+ @param ip_address - IPv4 address
+ @param vrf_id - VRF id of tenant, ~0 means independent of VRF
+*/
+define nat44_ei_address_details {
+ option in_progress;
+ u32 context;
+ vl_api_ip4_address_t ip_address;
+ u32 vrf_id;
+};
+
+/** \brief Enable/disable NAT44 feature on the interface
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param is_add - true if add, false if delete
+ @param flags - flag NAT_IS_INSIDE if interface is inside else
+ interface is outside
+ @param sw_if_index - software index of the interface
+*/
+autoreply define nat44_ei_interface_add_del_feature {
+ option in_progress;
+ u32 client_index;
+ u32 context;
+ bool is_add;
+ vl_api_nat44_ei_config_flags_t flags;
+ vl_api_interface_index_t sw_if_index;
+};
+
+/** \brief Dump interfaces with NAT44 feature
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+*/
+define nat44_ei_interface_dump {
+ option in_progress;
+ u32 client_index;
+ u32 context;
+};
+
+/** \brief NAT44 interface details response
+ @param context - sender context, to match reply w/ request
+ @param sw_if_index - software index of the interface
+ @param flags - flag NAT_IS_INSIDE if interface is inside,
+ flag NAT_IS_OUTSIDE if interface is outside
+ and if both flags are set the interface is
+ both inside and outside
+*/
+define nat44_ei_interface_details {
+ option in_progress;
+ u32 context;
+ vl_api_nat44_ei_config_flags_t flags;
+ vl_api_interface_index_t sw_if_index;
+};
+
+/** \brief Enable/disbale NAT44 as an interface output feature (postrouting
+ in2out translation)
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param is_add - true if add, false if delete
+ @param flags - flag NAT_IS_INSIDE if interface is inside else
+ interface is outside
+ @param sw_if_index - software index of the interface
+*/
+autoreply define nat44_ei_interface_add_del_output_feature {
+ option deprecated;
+ u32 client_index;
+ u32 context;
+ bool is_add;
+ vl_api_nat44_ei_config_flags_t flags;
+ vl_api_interface_index_t sw_if_index;
+};
+
+/** \brief Dump interfaces with NAT44 output feature
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+*/
+define nat44_ei_interface_output_feature_dump {
+ option deprecated;
+ u32 client_index;
+ u32 context;
+};
+
+/** \brief NAT44 interface with output feature details response
+ @param context - sender context, to match reply w/ request
+ @param flags - flag NAT_IS_INSIDE if interface is inside else
+ interface is outside
+ @param sw_if_index - software index of the interface
+*/
+define nat44_ei_interface_output_feature_details {
+ option deprecated;
+ u32 context;
+ vl_api_nat44_ei_config_flags_t flags;
+ vl_api_interface_index_t sw_if_index;
+};
+
+/** \brief Add/delete NAT44 static mapping
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param is_add - true if add, false if delete
+ @param flags - flag NAT44_EI_IS_ADDR_ONLY if address only mapping
+ @param local_ip_address - local IPv4 address
+ @param external_ip_address - external IPv4 address
+ @param protocol - IP protocol, used only if addr_only=0
+ @param local_port - local port number, used only if addr_only=0
+ @param external_port - external port number, used only if addr_only=0
+ @param external_sw_if_index - external interface (if set
+ external_ip_address is ignored, ~0 means not
+ used)
+ @param vfr_id - VRF ID
+ @param tag - opaque string tag
+*/
+autoreply define nat44_ei_add_del_static_mapping {
+ option in_progress;
+ u32 client_index;
+ u32 context;
+ bool is_add;
+ vl_api_nat44_ei_config_flags_t flags;
+ vl_api_ip4_address_t local_ip_address;
+ vl_api_ip4_address_t external_ip_address;
+ u8 protocol;
+ u16 local_port;
+ u16 external_port;
+ vl_api_interface_index_t external_sw_if_index;
+ u32 vrf_id;
+ string tag[64];
+};
+
+/** \brief Dump NAT44 static mappings
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+*/
+define nat44_ei_static_mapping_dump {
+ option in_progress;
+ u32 client_index;
+ u32 context;
+};
+
+/** \brief NAT44 static mapping details response
+ @param context - sender context, to match reply w/ request
+ @param flags - flag NAT44_EI_IS_ADDR_ONLY if address only mapping,
+ @param local_ip_address - local IPv4 address
+ @param external_ip_address - external IPv4 address
+ @param protocol - IP protocol, valid only if no NAT_ADDR_ONLY flag
+ @param local_port - local port number, valid only if no NAT_ADDR_ONLY flag
+ @param external_port - external port number, valid only if no NAT_ADDR_ONLY flag
+ @param external_sw_if_index - external interface
+ @param vfr_id - VRF ID
+ @param tag - opaque string tag
+*/
+define nat44_ei_static_mapping_details {
+ option in_progress;
+ u32 context;
+ vl_api_nat44_ei_config_flags_t flags;
+ vl_api_ip4_address_t local_ip_address;
+ vl_api_ip4_address_t external_ip_address;
+ u8 protocol;
+ u16 local_port;
+ u16 external_port;
+ vl_api_interface_index_t external_sw_if_index;
+ u32 vrf_id;
+ string tag[64];
+};
+
+/** \brief Add/delete NAT44 identity mapping
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param is_add - true if add, false if delete
+ @param flags - flag NAT44_EI_IS_ADDR_ONLY if address only mapping
+ @param ip_address - IPv4 address
+ @param protocol - IP protocol
+ @param port - port number
+ @param sw_if_index - interface (if set ip_address is ignored, ~0 means not
+ used)
+ @param vfr_id - VRF ID (if ~0 use default VRF)
+ @param tag - opaque string tag
+*/
+autoreply define nat44_ei_add_del_identity_mapping {
+ option deprecated;
+ u32 client_index;
+ u32 context;
+ bool is_add;
+ vl_api_nat44_ei_config_flags_t flags;
+ vl_api_ip4_address_t ip_address;
+ u8 protocol;
+ u16 port;
+ vl_api_interface_index_t sw_if_index;
+ u32 vrf_id;
+ string tag[64];
+};
+
+/** \brief Dump NAT44 identity mappings
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+*/
+define nat44_ei_identity_mapping_dump {
+ option deprecated;
+ u32 client_index;
+ u32 context;
+};
+
+/** \brief NAT44 identity mapping details response
+ @param context - sender context, to match reply w/ request
+ @param flags - flag NAT44_EI_ADDR_ONLY if address only mapping
+ @param ip_address - IPv4 address
+ @param protocol - IP protocol
+ @param port - port number
+ @param sw_if_index - interface
+ @param vfr_id - VRF ID
+ @param tag - opaque string tag
+*/
+define nat44_ei_identity_mapping_details {
+ option deprecated;
+ u32 context;
+ vl_api_nat44_ei_config_flags_t flags;
+ vl_api_ip4_address_t ip_address;
+ u8 protocol;
+ u16 port;
+ vl_api_interface_index_t sw_if_index;
+ u32 vrf_id;
+ string tag[64];
+};
+
+/** \brief Add/delete NAT44 pool address from specific interfce
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param is_add - true if add, false if delete
+ @param sw_if_index - software index of the interface
+ @param flags - flag NAT_TWICE_NAT if NAT address range for external hosts
+*/
+autoreply define nat44_ei_add_del_interface_addr {
+ option deprecated;
+ u32 client_index;
+ u32 context;
+ bool is_add;
+ vl_api_interface_index_t sw_if_index;
+ vl_api_nat44_ei_config_flags_t flags;
+};
+
+/** \brief Dump NAT44 pool addresses interfaces
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+*/
+define nat44_ei_interface_addr_dump {
+ option deprecated;
+ u32 client_index;
+ u32 context;
+};
+
+/** \brief NAT44 pool addresses interfaces details response
+ @param context - sender context, to match reply w/ request
+ @param sw_if_index - software index of the interface
+
+*/
+define nat44_ei_interface_addr_details {
+ option deprecated;
+ u32 context;
+ vl_api_interface_index_t sw_if_index;
+};
+
+/** \brief Dump NAT44 users
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+*/
+define nat44_ei_user_dump {
+ option in_progress;
+ u32 client_index;
+ u32 context;
+};
+
+/** \brief NAT44 users response
+ @param context - sender context, to match reply w/ request
+ @vrf_id - VRF ID
+ @param ip_address - IPv4 address
+ @param nsessions - number of dynamic sessions
+ @param nstaticsessions - number of static sessions
+*/
+define nat44_ei_user_details {
+ option in_progress;
+ u32 context;
+ u32 vrf_id;
+ vl_api_ip4_address_t ip_address;
+ u32 nsessions;
+ u32 nstaticsessions;
+};
+
+/** \brief NAT44 user's sessions
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param ip_address - IPv4 address of the user to dump
+ @param vrf_id - VRF_ID
+*/
+define nat44_ei_user_session_dump {
+ option in_progress;
+ u32 client_index;
+ u32 context;
+ vl_api_ip4_address_t ip_address;
+ u32 vrf_id;
+};
+
+/** \brief NAT44 user's sessions response
+ @param context - sender context, to match reply w/ request
+ @param outside_ip_address - outside IPv4 address
+ @param outside_port - outside port
+ @param inside_ip_address - inside IPv4 address
+ @param inside_port - inside port
+ @param protocol - protocol
+ @param flags - flag NAT_IS_STATIC if session is static
+ @param last_heard - last heard timer
+ @param total_bytes - count of bytes sent through session
+ @param total_pkts - count of pakets sent through session
+ @param ext_host_address - external host IPv4 address
+ @param ext_host_port - external host port
+*/
+define nat44_ei_user_session_details {
+ option in_progress;
+ u32 context;
+ vl_api_ip4_address_t outside_ip_address;
+ u16 outside_port;
+ vl_api_ip4_address_t inside_ip_address;
+ u16 inside_port;
+ u16 protocol;
+ vl_api_nat44_ei_config_flags_t flags;
+ u64 last_heard;
+ u64 total_bytes;
+ u32 total_pkts;
+ vl_api_ip4_address_t ext_host_address;
+ u16 ext_host_port;
+};
+
+/** \brief Delete NAT44 session
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param ip_address - IPv4 address
+ @param protocol - IP protocol
+ @param port - port number
+ @param vfr_id - VRF ID
+ @param flags - flag NAT_IS_INSIDE if interface is inside or
+ interface is outside,
+ flag NAT_IS_EXT_HOST_VALID if external host address and
+ port are valid
+ @param ext_host_address - external host IPv4 address
+ @param ext_host_port - external host port
+*/
+autoreply define nat44_ei_del_session {
+ option in_progress;
+ u32 client_index;
+ u32 context;
+ vl_api_ip4_address_t address;
+ u8 protocol;
+ u16 port;
+ u32 vrf_id;
+ vl_api_nat44_ei_config_flags_t flags;
+ vl_api_ip4_address_t ext_host_address;
+ u16 ext_host_port;
+};
+
+/** \brief Enable/disable forwarding for NAT44
+ Forward packets which don't match existing translation
+ or static mapping instead of dropping them.
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param enable - true for enable, false for disable
+*/
+autoreply define nat44_ei_forwarding_enable_disable {
+ option in_progress;
+ u32 client_index;
+ u32 context;
+ bool enable;
+};
+
+/** \brief Set NAT handoff frame queue options
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+ @param frame_queue_nelts - number of worker handoff frame queue elements
+*/
+autoreply define nat44_ei_set_fq_options {
+ option in_progress;
+ u32 client_index;
+ u32 context;
+ u32 frame_queue_nelts;
+};
+
+/** \brief Show NAT handoff frame queue options
+ @param client_index - opaque cookie to identify the sender
+ @param context - sender context, to match reply w/ request
+*/
+define nat44_ei_show_fq_options
+{
+ option in_progress;
+ u32 client_index;
+ u32 context;
+};
+
+/** \brief Show NAT handoff frame queue options reply
+ @param context - sender context, to match reply w/ request
+ @param retval - return code for the request
+ @param frame_queue_nelts - number of worker handoff frame queue elements
+*/
+define nat44_ei_show_fq_options_reply
+{
+ option in_progress;
+ u32 context;
+ i32 retval;
+ u32 frame_queue_nelts;
+};
diff --git a/src/plugins/nat/nat44-ei/nat44_ei.c b/src/plugins/nat/nat44-ei/nat44_ei.c
index 02403d0cd99..fdf90708a09 100644
--- a/src/plugins/nat/nat44-ei/nat44_ei.c
+++ b/src/plugins/nat/nat44-ei/nat44_ei.c
@@ -15,42 +15,409 @@
* under the License.
*/
+#include <vnet/plugin/plugin.h>
+#include <vpp/app/version.h>
+
#include <vnet/vnet.h>
#include <vnet/ip/ip.h>
#include <vnet/ip/ip4.h>
-#include <vnet/plugin/plugin.h>
-#include <nat/nat.h>
-#include <nat/nat_dpo.h>
-#include <nat/lib/ipfix_logging.h>
-#include <nat/lib/nat_syslog.h>
-#include <nat/nat_inlines.h>
-#include <nat/nat44/inlines.h>
-#include <nat/nat_affinity.h>
+#include <vnet/ip/ip_table.h>
+#include <vnet/ip/reass/ip4_sv_reass.h>
#include <vnet/fib/fib_table.h>
#include <vnet/fib/ip4_fib.h>
-#include <vnet/ip/reass/ip4_sv_reass.h>
-#include <vppinfra/bihash_16_8.h>
-#include <nat/nat44/ed_inlines.h>
-#include <vnet/ip/ip_table.h>
+#include <vnet/plugin/plugin.h>
+// nat lib
+#include <nat/lib/log.h>
+#include <nat/lib/nat_syslog.h>
+#include <nat/lib/nat_inlines.h>
+#include <nat/lib/ipfix_logging.h>
+
+#include <nat/nat44-ei/nat44_ei_dpo.h>
#include <nat/nat44-ei/nat44_ei_inlines.h>
#include <nat/nat44-ei/nat44_ei.h>
nat44_ei_main_t nat44_ei_main;
+extern vlib_node_registration_t nat44_ei_hairpinning_node;
+extern vlib_node_registration_t nat44_ei_hairpin_dst_node;
+extern vlib_node_registration_t
+ nat44_ei_in2out_hairpinning_finish_ip4_lookup_node;
+extern vlib_node_registration_t
+ nat44_ei_in2out_hairpinning_finish_interface_output_node;
+
+#define skip_if_disabled() \
+ do \
+ { \
+ nat44_ei_main_t *nm = &nat44_ei_main; \
+ if (PREDICT_FALSE (!nm->enabled)) \
+ return; \
+ } \
+ while (0)
+
+#define fail_if_enabled() \
+ do \
+ { \
+ nat44_ei_main_t *nm = &nat44_ei_main; \
+ if (PREDICT_FALSE (nm->enabled)) \
+ { \
+ nat44_ei_log_err ("plugin enabled"); \
+ return 1; \
+ } \
+ } \
+ while (0)
+
+#define fail_if_disabled() \
+ do \
+ { \
+ nat44_ei_main_t *nm = &nat44_ei_main; \
+ if (PREDICT_FALSE (!nm->enabled)) \
+ { \
+ nat44_ei_log_err ("plugin disabled"); \
+ return 1; \
+ } \
+ } \
+ while (0)
+
+/* Hook up input features */
+VNET_FEATURE_INIT (ip4_nat_classify, static) = {
+ .arc_name = "ip4-unicast",
+ .node_name = "nat44-ei-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",
+ .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa",
+ "ip4-sv-reassembly-feature"),
+};
+VNET_FEATURE_INIT (ip4_nat44_ei_out2in, static) = {
+ .arc_name = "ip4-unicast",
+ .node_name = "nat44-ei-out2in",
+ .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa",
+ "ip4-sv-reassembly-feature",
+ "ip4-dhcp-client-detect"),
+};
+VNET_FEATURE_INIT (ip4_nat44_ei_in2out_output, static) = {
+ .arc_name = "ip4-output",
+ .node_name = "nat44-ei-in2out-output",
+ .runs_after = VNET_FEATURES ("acl-plugin-out-ip4-fa",
+ "ip4-sv-reassembly-output-feature"),
+};
+VNET_FEATURE_INIT (ip4_nat44_ei_in2out_fast, static) = {
+ .arc_name = "ip4-unicast",
+ .node_name = "nat44-ei-in2out-fast",
+ .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa",
+ "ip4-sv-reassembly-feature"),
+};
+VNET_FEATURE_INIT (ip4_nat44_ei_out2in_fast, static) = {
+ .arc_name = "ip4-unicast",
+ .node_name = "nat44-ei-out2in-fast",
+ .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa",
+ "ip4-sv-reassembly-feature",
+ "ip4-dhcp-client-detect"),
+};
+VNET_FEATURE_INIT (ip4_nat44_ei_hairpin_dst, static) = {
+ .arc_name = "ip4-unicast",
+ .node_name = "nat44-ei-hairpin-dst",
+ .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa",
+ "ip4-sv-reassembly-feature"),
+};
+VNET_FEATURE_INIT (ip4_nat44_ei_hairpin_src, static) = {
+ .arc_name = "ip4-output",
+ .node_name = "nat44-ei-hairpin-src",
+ .runs_after = VNET_FEATURES ("acl-plugin-out-ip4-fa",
+ "ip4-sv-reassembly-output-feature"),
+};
+VNET_FEATURE_INIT (ip4_nat44_ei_hairpinning, static) = {
+ .arc_name = "ip4-local",
+ .node_name = "nat44-ei-hairpinning",
+ .runs_before = VNET_FEATURES ("ip4-local-end-of-arc"),
+};
+VNET_FEATURE_INIT (ip4_nat44_ei_in2out_worker_handoff, static) = {
+ .arc_name = "ip4-unicast",
+ .node_name = "nat44-ei-in2out-worker-handoff",
+ .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa"),
+};
+VNET_FEATURE_INIT (ip4_nat44_ei_out2in_worker_handoff, static) = {
+ .arc_name = "ip4-unicast",
+ .node_name = "nat44-ei-out2in-worker-handoff",
+ .runs_after = VNET_FEATURES ("acl-plugin-in-ip4-fa",
+ "ip4-dhcp-client-detect"),
+};
+VNET_FEATURE_INIT (ip4_nat44_ei_in2out_output_worker_handoff, static) = {
+ .arc_name = "ip4-output",
+ .node_name = "nat44-ei-in2out-output-worker-handoff",
+ .runs_after = VNET_FEATURES ("acl-plugin-out-ip4-fa",
+ "ip4-sv-reassembly-output-feature"),
+};
+
+VLIB_PLUGIN_REGISTER () = {
+ .version = VPP_BUILD_VER,
+ .description = "IPv4 Endpoint-Independent NAT (NAT44 EI)",
+};
+
+#define foreach_nat44_ei_classify_error \
+ _ (NEXT_IN2OUT, "next in2out") \
+ _ (NEXT_OUT2IN, "next out2in") \
+ _ (FRAG_CACHED, "fragment cached")
+
+typedef enum
+{
+#define _(sym, str) NAT44_EI_CLASSIFY_ERROR_##sym,
+ foreach_nat44_ei_classify_error
+#undef _
+ NAT44_EI_CLASSIFY_N_ERROR,
+} nat44_ei_classify_error_t;
+
+static char *nat44_ei_classify_error_strings[] = {
+#define _(sym, string) string,
+ foreach_nat44_ei_classify_error
+#undef _
+};
+
+typedef enum
+{
+ NAT44_EI_CLASSIFY_NEXT_IN2OUT,
+ NAT44_EI_CLASSIFY_NEXT_OUT2IN,
+ NAT44_EI_CLASSIFY_NEXT_DROP,
+ NAT44_EI_CLASSIFY_N_NEXT,
+} nat44_ei_classify_next_t;
+
+typedef struct
+{
+ u8 next_in2out;
+ u8 cached;
+} nat44_ei_classify_trace_t;
+
+void nat44_ei_add_del_addr_to_fib (ip4_address_t *addr, u8 p_len,
+ u32 sw_if_index, int is_add);
+
+static u8 *
+format_nat44_ei_classify_trace (u8 *s, va_list *args)
+{
+ CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
+ CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
+ nat44_ei_classify_trace_t *t = va_arg (*args, nat44_ei_classify_trace_t *);
+ char *next;
+
+ if (t->cached)
+ s = format (s, "nat44-ei-classify: fragment cached");
+ else
+ {
+ next = t->next_in2out ? "nat44-ei-in2out" : "nat44-ei-out2in";
+ s = format (s, "nat44-ei-classify: next %s", next);
+ }
+
+ return s;
+}
+
static void nat44_ei_db_free ();
static void nat44_ei_db_init (u32 translations, u32 translation_buckets,
u32 user_buckets);
+static void nat44_ei_ip4_add_del_interface_address_cb (
+ ip4_main_t *im, uword opaque, u32 sw_if_index, ip4_address_t *address,
+ u32 address_length, u32 if_address_index, u32 is_delete);
+
+static void nat44_ei_ip4_add_del_addr_only_sm_cb (
+ ip4_main_t *im, uword opaque, u32 sw_if_index, ip4_address_t *address,
+ u32 address_length, u32 if_address_index, u32 is_delete);
+
+static void nat44_ei_update_outside_fib (ip4_main_t *im, uword opaque,
+ u32 sw_if_index, u32 new_fib_index,
+ u32 old_fib_index);
+
+void
+nat44_ei_set_node_indexes (nat44_ei_main_t *nm, vlib_main_t *vm)
+{
+ vlib_node_t *node;
+ node = vlib_get_node_by_name (vm, (u8 *) "nat44-ei-out2in");
+ nm->out2in_node_index = node->index;
+ node = vlib_get_node_by_name (vm, (u8 *) "nat44-ei-in2out");
+ nm->in2out_node_index = node->index;
+ node = vlib_get_node_by_name (vm, (u8 *) "nat44-ei-in2out-output");
+ nm->in2out_output_node_index = node->index;
+}
+
int
-nat44_ei_plugin_enable (nat44_ei_config_t c)
+nat44_ei_set_workers (uword *bitmap)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ int i, j = 0;
+
+ if (nm->num_workers < 2)
+ return VNET_API_ERROR_FEATURE_DISABLED;
+
+ if (clib_bitmap_last_set (bitmap) >= nm->num_workers)
+ return VNET_API_ERROR_INVALID_WORKER;
+
+ vec_free (nm->workers);
+ clib_bitmap_foreach (i, bitmap)
+ {
+ vec_add1 (nm->workers, i);
+ nm->per_thread_data[nm->first_worker_index + i].snat_thread_index = j;
+ nm->per_thread_data[nm->first_worker_index + i].thread_index = i;
+ j++;
+ }
+
+ nm->port_per_thread = (0xffff - 1024) / _vec_len (nm->workers);
+
+ return 0;
+}
+
+#define nat_validate_simple_counter(c, i) \
+ do \
+ { \
+ vlib_validate_simple_counter (&c, i); \
+ vlib_zero_simple_counter (&c, i); \
+ } \
+ while (0);
+
+#define nat_init_simple_counter(c, n, sn) \
+ do \
+ { \
+ c.name = n; \
+ c.stat_segment_name = sn; \
+ nat_validate_simple_counter (c, 0); \
+ } \
+ while (0);
+
+static_always_inline void
+nat_validate_interface_counters (nat44_ei_main_t *nm, u32 sw_if_index)
+{
+#define _(x) \
+ nat_validate_simple_counter (nm->counters.fastpath.in2out.x, sw_if_index); \
+ nat_validate_simple_counter (nm->counters.fastpath.out2in.x, sw_if_index); \
+ nat_validate_simple_counter (nm->counters.slowpath.in2out.x, sw_if_index); \
+ nat_validate_simple_counter (nm->counters.slowpath.out2in.x, sw_if_index);
+ foreach_nat_counter;
+#undef _
+ nat_validate_simple_counter (nm->counters.hairpinning, sw_if_index);
+}
+
+clib_error_t *
+nat44_ei_init (vlib_main_t *vm)
{
nat44_ei_main_t *nm = &nat44_ei_main;
- snat_main_t *sm = &snat_main;
+ vlib_thread_main_t *tm = vlib_get_thread_main ();
+ vlib_thread_registration_t *tr;
+ ip4_add_del_interface_address_callback_t cbi = { 0 };
+ ip4_table_bind_callback_t cbt = { 0 };
+ u32 i, num_threads = 0;
+ uword *p, *bitmap = 0;
clib_memset (nm, 0, sizeof (*nm));
+ // required
+ nm->vnet_main = vnet_get_main ();
+ // convenience
+ nm->ip4_main = &ip4_main;
+ nm->api_main = vlibapi_get_main ();
+ nm->ip4_lookup_main = &ip4_main.lookup_main;
+
+ // handoff stuff
+ nm->fq_out2in_index = ~0;
+ nm->fq_in2out_index = ~0;
+ nm->fq_in2out_output_index = ~0;
+ nm->worker_in2out_cb = nat44_ei_get_in2out_worker_index;
+ nm->worker_out2in_cb = nat44_ei_get_out2in_worker_index;
+
+ nm->log_level = NAT_LOG_ERROR;
+
+ nat44_ei_set_node_indexes (nm, vm);
+ nm->log_class = vlib_log_register_class ("nat44-ei", 0);
+
+ nat_init_simple_counter (nm->total_users, "total-users",
+ "/nat44-ei/total-users");
+ nat_init_simple_counter (nm->total_sessions, "total-sessions",
+ "/nat44-ei/total-sessions");
+ nat_init_simple_counter (nm->user_limit_reached, "user-limit-reached",
+ "/nat44-ei/user-limit-reached");
+
+#define _(x) \
+ nat_init_simple_counter (nm->counters.fastpath.in2out.x, #x, \
+ "/nat44-ei/in2out/fastpath/" #x); \
+ nat_init_simple_counter (nm->counters.fastpath.out2in.x, #x, \
+ "/nat44-ei/out2in/fastpath/" #x); \
+ nat_init_simple_counter (nm->counters.slowpath.in2out.x, #x, \
+ "/nat44-ei/in2out/slowpath/" #x); \
+ nat_init_simple_counter (nm->counters.slowpath.out2in.x, #x, \
+ "/nat44-ei/out2in/slowpath/" #x);
+ foreach_nat_counter;
+#undef _
+ nat_init_simple_counter (nm->counters.hairpinning, "hairpinning",
+ "/nat44-ei/hairpinning");
+
+ p = hash_get_mem (tm->thread_registrations_by_name, "workers");
+ if (p)
+ {
+ tr = (vlib_thread_registration_t *) p[0];
+ if (tr)
+ {
+ nm->num_workers = tr->count;
+ nm->first_worker_index = tr->first_index;
+ }
+ }
+ num_threads = tm->n_vlib_mains - 1;
+ nm->port_per_thread = 0xffff - 1024;
+ vec_validate (nm->per_thread_data, num_threads);
+
+ /* Use all available workers by default */
+ if (nm->num_workers > 1)
+ {
+
+ for (i = 0; i < nm->num_workers; i++)
+ bitmap = clib_bitmap_set (bitmap, i, 1);
+ nat44_ei_set_workers (bitmap);
+ clib_bitmap_free (bitmap);
+ }
+ else
+ nm->per_thread_data[0].snat_thread_index = 0;
+
+ /* callbacks to call when interface address changes. */
+ cbi.function = nat44_ei_ip4_add_del_interface_address_cb;
+ vec_add1 (nm->ip4_main->add_del_interface_address_callbacks, cbi);
+ cbi.function = nat44_ei_ip4_add_del_addr_only_sm_cb;
+ vec_add1 (nm->ip4_main->add_del_interface_address_callbacks, cbi);
+
+ /* callbacks to call when interface to table biding changes */
+ cbt.function = nat44_ei_update_outside_fib;
+ vec_add1 (nm->ip4_main->table_bind_callbacks, cbt);
+
+ nm->fib_src_low = fib_source_allocate (
+ "nat44-ei-low", FIB_SOURCE_PRIORITY_LOW, FIB_SOURCE_BH_SIMPLE);
+ nm->fib_src_hi = fib_source_allocate ("nat44-ei-hi", FIB_SOURCE_PRIORITY_HI,
+ FIB_SOURCE_BH_SIMPLE);
+
+ // used only by out2in-dpo feature
+ nat_dpo_module_init ();
+ nat_ha_init (vm, nm->num_workers, num_threads);
+
+ nm->hairpinning_fq_index =
+ vlib_frame_queue_main_init (nat44_ei_hairpinning_node.index, 0);
+ nm->hairpin_dst_fq_index =
+ vlib_frame_queue_main_init (nat44_ei_hairpin_dst_node.index, 0);
+ nm->in2out_hairpinning_finish_ip4_lookup_node_fq_index =
+ vlib_frame_queue_main_init (
+ nat44_ei_in2out_hairpinning_finish_ip4_lookup_node.index, 0);
+ nm->in2out_hairpinning_finish_interface_output_node_fq_index =
+ vlib_frame_queue_main_init (
+ nat44_ei_in2out_hairpinning_finish_interface_output_node.index, 0);
+ return nat44_ei_api_hookup (vm);
+}
+
+VLIB_INIT_FUNCTION (nat44_ei_init);
+
+int
+nat44_ei_plugin_enable (nat44_ei_config_t c)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+
+ fail_if_enabled ();
+
if (!c.users)
c.users = 1024;
@@ -59,68 +426,449 @@ nat44_ei_plugin_enable (nat44_ei_config_t c)
nm->rconfig = c;
+ if (!nm->frame_queue_nelts)
+ nm->frame_queue_nelts = NAT_FQ_NELTS_DEFAULT;
+
nm->translations = c.sessions;
nm->translation_buckets = nat_calc_bihash_buckets (c.sessions);
nm->user_buckets = nat_calc_bihash_buckets (c.users);
- // OBSOLETE
-
- sm->static_mapping_only = c.static_mapping_only;
- sm->static_mapping_connection_tracking = c.connection_tracking;
- sm->out2in_dpo = c.out2in_dpo;
- sm->forwarding_enabled = 0;
- sm->mss_clamping = 0;
- sm->pat = (!c.static_mapping_only ||
+ nm->pat = (!c.static_mapping_only ||
(c.static_mapping_only && c.connection_tracking));
- sm->max_users_per_thread = c.users;
- sm->max_translations_per_thread = c.sessions;
- sm->translation_buckets = nat_calc_bihash_buckets (c.sessions);
- sm->max_translations_per_user =
- c.user_sessions ? c.user_sessions : sm->max_translations_per_thread;
+ nm->static_mapping_only = c.static_mapping_only;
+ nm->static_mapping_connection_tracking = c.connection_tracking;
+ nm->out2in_dpo = c.out2in_dpo;
+ nm->forwarding_enabled = 0;
+ nm->mss_clamping = 0;
- sm->inside_vrf_id = c.inside_vrf;
- sm->inside_fib_index = fib_table_find_or_create_and_lock (
- FIB_PROTOCOL_IP4, c.inside_vrf, sm->fib_src_hi);
+ 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;
- sm->outside_vrf_id = c.outside_vrf;
- sm->outside_fib_index = fib_table_find_or_create_and_lock (
- FIB_PROTOCOL_IP4, c.outside_vrf, sm->fib_src_hi);
+ nm->inside_vrf_id = c.inside_vrf;
+ nm->inside_fib_index = fib_table_find_or_create_and_lock (
+ FIB_PROTOCOL_IP4, c.inside_vrf, nm->fib_src_hi);
- sm->worker_in2out_cb = nat44_ei_get_in2out_worker_index;
- sm->worker_out2in_cb = nat44_ei_get_out2in_worker_index;
+ nm->outside_vrf_id = c.outside_vrf;
+ nm->outside_fib_index = fib_table_find_or_create_and_lock (
+ FIB_PROTOCOL_IP4, c.outside_vrf, nm->fib_src_hi);
- sm->in2out_node_index = sm->ei_in2out_node_index;
- sm->out2in_node_index = sm->ei_out2in_node_index;
+ nat_reset_timeouts (&nm->timeouts);
+ nat44_ei_db_init (nm->translations, nm->translation_buckets,
+ nm->user_buckets);
+ nat44_ei_set_alloc_default ();
- sm->in2out_output_node_index = sm->ei_in2out_output_node_index;
+ // TODO: zero simple counter for all counters missing
- if (sm->pat)
+ vlib_zero_simple_counter (&nm->total_users, 0);
+ vlib_zero_simple_counter (&nm->total_sessions, 0);
+ vlib_zero_simple_counter (&nm->user_limit_reached, 0);
+
+ nat_ha_enable ();
+ nm->enabled = 1;
+
+ return 0;
+}
+
+void
+nat44_ei_addresses_free (nat44_ei_address_t **addresses)
+{
+ nat44_ei_address_t *ap;
+ vec_foreach (ap, *addresses)
{
- sm->icmp_match_in2out_cb = icmp_match_in2out_slow;
- sm->icmp_match_out2in_cb = icmp_match_out2in_slow;
+#define _(N, i, n, s) vec_free (ap->busy_##n##_ports_per_thread);
+ foreach_nat_protocol
+#undef _
+ }
+ vec_free (*addresses);
+ *addresses = 0;
+}
+
+int
+nat44_ei_interface_add_del (u32 sw_if_index, u8 is_inside, int is_del)
+{
+ const char *feature_name, *del_feature_name;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nat44_ei_interface_t *i;
+ nat44_ei_address_t *ap;
+ nat44_ei_static_mapping_t *m;
+ nat44_ei_outside_fib_t *outside_fib;
+ u32 fib_index =
+ fib_table_get_index_for_sw_if_index (FIB_PROTOCOL_IP4, sw_if_index);
+
+ fail_if_disabled ();
+
+ if (nm->out2in_dpo && !is_inside)
+ {
+ nat44_ei_log_err ("error unsupported");
+ return VNET_API_ERROR_UNSUPPORTED;
+ }
+
+ pool_foreach (i, nm->output_feature_interfaces)
+ {
+ if (i->sw_if_index == sw_if_index)
+ {
+ nat44_ei_log_err ("error interface already configured");
+ return VNET_API_ERROR_VALUE_EXIST;
+ }
}
+
+ if (nm->static_mapping_only && !(nm->static_mapping_connection_tracking))
+ feature_name = is_inside ? "nat44-ei-in2out-fast" : "nat44-ei-out2in-fast";
else
{
- sm->icmp_match_in2out_cb = icmp_match_in2out_fast;
- sm->icmp_match_out2in_cb = icmp_match_out2in_fast;
+ if (nm->num_workers > 1)
+ feature_name = is_inside ? "nat44-ei-in2out-worker-handoff" :
+ "nat44-ei-out2in-worker-handoff";
+ else
+ feature_name = is_inside ? "nat44-ei-in2out" : "nat44-ei-out2in";
}
- nat_reset_timeouts (&sm->timeouts);
- nat44_ei_db_init (nm->translations, nm->translation_buckets,
- nm->user_buckets);
- nat44_ei_set_alloc_default ();
- nat_ha_enable ();
+ if (nm->fq_in2out_index == ~0 && nm->num_workers > 1)
+ nm->fq_in2out_index = vlib_frame_queue_main_init (nm->in2out_node_index,
+ nm->frame_queue_nelts);
- // TODO: function for reset counters
- vlib_zero_simple_counter (&sm->total_users, 0);
- vlib_zero_simple_counter (&sm->total_sessions, 0);
- vlib_zero_simple_counter (&sm->user_limit_reached, 0);
+ if (nm->fq_out2in_index == ~0 && nm->num_workers > 1)
+ nm->fq_out2in_index = vlib_frame_queue_main_init (nm->out2in_node_index,
+ nm->frame_queue_nelts);
- if (!sm->frame_queue_nelts)
- sm->frame_queue_nelts = NAT_FQ_NELTS_DEFAULT;
+ if (!is_inside)
+ {
+ vec_foreach (outside_fib, nm->outside_fibs)
+ {
+ if (outside_fib->fib_index == fib_index)
+ {
+ if (is_del)
+ {
+ outside_fib->refcount--;
+ if (!outside_fib->refcount)
+ vec_del1 (nm->outside_fibs,
+ outside_fib - nm->outside_fibs);
+ }
+ else
+ outside_fib->refcount++;
+ goto feature_set;
+ }
+ }
+ if (!is_del)
+ {
+ vec_add2 (nm->outside_fibs, outside_fib, 1);
+ outside_fib->refcount = 1;
+ outside_fib->fib_index = fib_index;
+ }
+ }
- sm->enabled = 1;
+feature_set:
+ pool_foreach (i, nm->interfaces)
+ {
+ if (i->sw_if_index == sw_if_index)
+ {
+ if (is_del)
+ {
+ if (nat44_ei_interface_is_inside (i) &&
+ nat44_ei_interface_is_outside (i))
+ {
+ if (is_inside)
+ i->flags &= ~NAT44_EI_INTERFACE_FLAG_IS_INSIDE;
+ else
+ i->flags &= ~NAT44_EI_INTERFACE_FLAG_IS_OUTSIDE;
+
+ if (nm->num_workers > 1)
+ {
+ del_feature_name = "nat44-handoff-classify";
+ feature_name = !is_inside ?
+ "nat44-ei-in2out-worker-handoff" :
+ "nat44-ei-out2in-worker-handoff";
+ }
+ else
+ {
+ del_feature_name = "nat44-ei-classify";
+ feature_name =
+ !is_inside ? "nat44-ei-in2out" : "nat44-ei-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,
+ sw_if_index, 1, 0, 0);
+ if (!is_inside)
+ {
+ vnet_feature_enable_disable ("ip4-local",
+ "nat44-ei-hairpinning",
+ sw_if_index, 1, 0, 0);
+ }
+ }
+ 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 (nm->interfaces, i);
+ if (is_inside)
+ {
+ vnet_feature_enable_disable ("ip4-local",
+ "nat44-ei-hairpinning",
+ sw_if_index, 0, 0, 0);
+ }
+ }
+ }
+ else
+ {
+ if ((nat44_ei_interface_is_inside (i) && is_inside) ||
+ (nat44_ei_interface_is_outside (i) && !is_inside))
+ return 0;
+
+ if (nm->num_workers > 1)
+ {
+ del_feature_name = !is_inside ?
+ "nat44-ei-in2out-worker-handoff" :
+ "nat44-ei-out2in-worker-handoff";
+ feature_name = "nat44-handoff-classify";
+ }
+ else
+ {
+ del_feature_name =
+ !is_inside ? "nat44-ei-in2out" : "nat44-ei-out2in";
+ 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);
+ if (!is_inside)
+ {
+ vnet_feature_enable_disable (
+ "ip4-local", "nat44-ei-hairpinning", sw_if_index, 0, 0, 0);
+ }
+ goto set_flags;
+ }
+
+ goto fib;
+ }
+ }
+
+ if (is_del)
+ {
+ nat44_ei_log_err ("error interface couldn't be found");
+ return VNET_API_ERROR_NO_SUCH_ENTRY;
+ }
+
+ pool_get (nm->interfaces, i);
+ i->sw_if_index = sw_if_index;
+ 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 = 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);
+ }
+
+set_flags:
+ if (is_inside)
+ {
+ i->flags |= NAT44_EI_INTERFACE_FLAG_IS_INSIDE;
+ return 0;
+ }
+ else
+ i->flags |= NAT44_EI_INTERFACE_FLAG_IS_OUTSIDE;
+
+ /* Add/delete external addresses to FIB */
+fib:
+ vec_foreach (ap, nm->addresses)
+ nat44_ei_add_del_addr_to_fib (&ap->addr, 32, sw_if_index, !is_del);
+
+ pool_foreach (m, nm->static_mappings)
+ {
+ if (!(nat44_ei_is_addr_only_static_mapping (m)) ||
+ (m->local_addr.as_u32 == m->external_addr.as_u32))
+ continue;
+
+ nat44_ei_add_del_addr_to_fib (&m->external_addr, 32, sw_if_index,
+ !is_del);
+ }
+
+ return 0;
+}
+
+int
+nat44_ei_interface_add_del_output_feature (u32 sw_if_index, u8 is_inside,
+ int is_del)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nat44_ei_interface_t *i;
+ nat44_ei_address_t *ap;
+ nat44_ei_static_mapping_t *m;
+ nat44_ei_outside_fib_t *outside_fib;
+ u32 fib_index =
+ fib_table_get_index_for_sw_if_index (FIB_PROTOCOL_IP4, sw_if_index);
+
+ fail_if_disabled ();
+
+ if (nm->static_mapping_only && !(nm->static_mapping_connection_tracking))
+ {
+ nat44_ei_log_err ("error unsupported");
+ return VNET_API_ERROR_UNSUPPORTED;
+ }
+
+ pool_foreach (i, nm->interfaces)
+ {
+ if (i->sw_if_index == sw_if_index)
+ {
+ nat44_ei_log_err ("error interface already configured");
+ return VNET_API_ERROR_VALUE_EXIST;
+ }
+ }
+
+ if (!is_inside)
+ {
+ vec_foreach (outside_fib, nm->outside_fibs)
+ {
+ if (outside_fib->fib_index == fib_index)
+ {
+ if (is_del)
+ {
+ outside_fib->refcount--;
+ if (!outside_fib->refcount)
+ vec_del1 (nm->outside_fibs,
+ outside_fib - nm->outside_fibs);
+ }
+ else
+ outside_fib->refcount++;
+ goto feature_set;
+ }
+ }
+ if (!is_del)
+ {
+ vec_add2 (nm->outside_fibs, outside_fib, 1);
+ outside_fib->refcount = 1;
+ outside_fib->fib_index = fib_index;
+ }
+ }
+
+feature_set:
+ if (is_inside)
+ {
+ 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-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);
+ goto fq;
+ }
+
+ if (nm->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-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);
+ }
+ 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-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);
+ }
+
+fq:
+ if (nm->fq_in2out_output_index == ~0 && nm->num_workers > 1)
+ nm->fq_in2out_output_index =
+ vlib_frame_queue_main_init (nm->in2out_output_node_index, 0);
+
+ if (nm->fq_out2in_index == ~0 && nm->num_workers > 1)
+ nm->fq_out2in_index =
+ vlib_frame_queue_main_init (nm->out2in_node_index, 0);
+
+ pool_foreach (i, nm->output_feature_interfaces)
+ {
+ if (i->sw_if_index == sw_if_index)
+ {
+ if (is_del)
+ pool_put (nm->output_feature_interfaces, i);
+ else
+ return VNET_API_ERROR_VALUE_EXIST;
+
+ goto fib;
+ }
+ }
+
+ if (is_del)
+ {
+ nat44_ei_log_err ("error interface couldn't be found");
+ return VNET_API_ERROR_NO_SUCH_ENTRY;
+ }
+
+ pool_get (nm->output_feature_interfaces, i);
+ i->sw_if_index = sw_if_index;
+ i->flags = 0;
+ nat_validate_interface_counters (nm, sw_if_index);
+ if (is_inside)
+ i->flags |= NAT44_EI_INTERFACE_FLAG_IS_INSIDE;
+ else
+ i->flags |= NAT44_EI_INTERFACE_FLAG_IS_OUTSIDE;
+
+ /* Add/delete external addresses to FIB */
+fib:
+ if (is_inside)
+ return 0;
+
+ vec_foreach (ap, nm->addresses)
+ nat44_ei_add_del_addr_to_fib (&ap->addr, 32, sw_if_index, !is_del);
+
+ pool_foreach (m, nm->static_mappings)
+ {
+ if (!((nat44_ei_is_addr_only_static_mapping (m))) ||
+ (m->local_addr.as_u32 == m->external_addr.as_u32))
+ continue;
+
+ nat44_ei_add_del_addr_to_fib (&m->external_addr, 32, sw_if_index,
+ !is_del);
+ }
return 0;
}
@@ -129,81 +877,347 @@ int
nat44_ei_plugin_disable ()
{
nat44_ei_main_t *nm = &nat44_ei_main;
- snat_main_t *sm = &snat_main;
- snat_interface_t *i, *vec;
+ nat44_ei_interface_t *i, *vec;
int error = 0;
// first unregister all nodes from interfaces
- vec = vec_dup (sm->interfaces);
+ vec = vec_dup (nm->interfaces);
vec_foreach (i, vec)
{
- if (nat_interface_is_inside (i))
- error = snat_interface_add_del (i->sw_if_index, 1, 1);
- if (nat_interface_is_outside (i))
- error = snat_interface_add_del (i->sw_if_index, 0, 1);
+ if (nat44_ei_interface_is_inside (i))
+ error = nat44_ei_interface_add_del (i->sw_if_index, 1, 1);
+ if (nat44_ei_interface_is_outside (i))
+ error = nat44_ei_interface_add_del (i->sw_if_index, 0, 1);
if (error)
{
- nat_log_err ("error occurred while removing interface %u",
- i->sw_if_index);
+ nat44_ei_log_err ("error occurred while removing interface %u",
+ i->sw_if_index);
}
}
vec_free (vec);
- sm->interfaces = 0;
+ nm->interfaces = 0;
- vec = vec_dup (sm->output_feature_interfaces);
+ vec = vec_dup (nm->output_feature_interfaces);
vec_foreach (i, vec)
{
- if (nat_interface_is_inside (i))
- error = snat_interface_add_del_output_feature (i->sw_if_index, 1, 1);
- if (nat_interface_is_outside (i))
- error = snat_interface_add_del_output_feature (i->sw_if_index, 0, 1);
+ if (nat44_ei_interface_is_inside (i))
+ error =
+ nat44_ei_interface_add_del_output_feature (i->sw_if_index, 1, 1);
+ if (nat44_ei_interface_is_outside (i))
+ error =
+ nat44_ei_interface_add_del_output_feature (i->sw_if_index, 0, 1);
if (error)
{
- nat_log_err ("error occurred while removing interface %u",
- i->sw_if_index);
+ nat44_ei_log_err ("error occurred while removing interface %u",
+ i->sw_if_index);
}
}
vec_free (vec);
- sm->output_feature_interfaces = 0;
+ nm->output_feature_interfaces = 0;
nat_ha_disable ();
nat44_ei_db_free ();
- nat44_addresses_free (&sm->addresses);
- nat44_addresses_free (&sm->twice_nat_addresses);
+ nat44_ei_addresses_free (&nm->addresses);
- vec_free (sm->to_resolve);
- vec_free (sm->auto_add_sw_if_indices);
- vec_free (sm->auto_add_sw_if_indices_twice_nat);
+ vec_free (nm->to_resolve);
+ vec_free (nm->auto_add_sw_if_indices);
- sm->to_resolve = 0;
- sm->auto_add_sw_if_indices = 0;
- sm->auto_add_sw_if_indices_twice_nat = 0;
+ nm->to_resolve = 0;
+ nm->auto_add_sw_if_indices = 0;
- sm->forwarding_enabled = 0;
+ nm->forwarding_enabled = 0;
- sm->enabled = 0;
+ nm->enabled = 0;
clib_memset (&nm->rconfig, 0, sizeof (nm->rconfig));
- clib_memset (&sm->rconfig, 0, sizeof (sm->rconfig));
return error;
}
+int
+nat44_ei_set_outside_address_and_port (nat44_ei_address_t *addresses,
+ u32 thread_index, ip4_address_t addr,
+ u16 port, nat_protocol_t protocol)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nat44_ei_address_t *a = 0;
+ u32 address_index;
+ u16 port_host_byte_order = clib_net_to_host_u16 (port);
+
+ for (address_index = 0; address_index < vec_len (addresses); address_index++)
+ {
+ if (addresses[address_index].addr.as_u32 != addr.as_u32)
+ continue;
+
+ a = addresses + address_index;
+ switch (protocol)
+ {
+#define _(N, j, n, s) \
+ case NAT_PROTOCOL_##N: \
+ if (a->busy_##n##_port_refcounts[port_host_byte_order]) \
+ return VNET_API_ERROR_INSTANCE_IN_USE; \
+ ++a->busy_##n##_port_refcounts[port_host_byte_order]; \
+ a->busy_##n##_ports_per_thread[thread_index]++; \
+ a->busy_##n##_ports++; \
+ return 0;
+ foreach_nat_protocol
+#undef _
+ default : nat_elog_info (nm, "unknown protocol");
+ return 1;
+ }
+ }
+
+ return VNET_API_ERROR_NO_SUCH_ENTRY;
+}
+
+void
+nat44_ei_add_del_address_dpo (ip4_address_t addr, u8 is_add)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ dpo_id_t dpo_v4 = DPO_INVALID;
+ fib_prefix_t pfx = {
+ .fp_proto = FIB_PROTOCOL_IP4,
+ .fp_len = 32,
+ .fp_addr.ip4.as_u32 = addr.as_u32,
+ };
+
+ if (is_add)
+ {
+ nat_dpo_create (DPO_PROTO_IP4, 0, &dpo_v4);
+ fib_table_entry_special_dpo_add (0, &pfx, nm->fib_src_hi,
+ FIB_ENTRY_FLAG_EXCLUSIVE, &dpo_v4);
+ dpo_reset (&dpo_v4);
+ }
+ else
+ {
+ fib_table_entry_special_remove (0, &pfx, nm->fib_src_hi);
+ }
+}
+
+void
+nat44_ei_free_outside_address_and_port (nat44_ei_address_t *addresses,
+ u32 thread_index, ip4_address_t *addr,
+ u16 port, nat_protocol_t protocol)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nat44_ei_address_t *a;
+ u32 address_index;
+ u16 port_host_byte_order = clib_net_to_host_u16 (port);
+
+ for (address_index = 0; address_index < vec_len (addresses); address_index++)
+ {
+ if (addresses[address_index].addr.as_u32 == addr->as_u32)
+ break;
+ }
+
+ ASSERT (address_index < vec_len (addresses));
+
+ a = addresses + address_index;
+
+ switch (protocol)
+ {
+#define _(N, i, n, s) \
+ case NAT_PROTOCOL_##N: \
+ ASSERT (a->busy_##n##_port_refcounts[port_host_byte_order] >= 1); \
+ --a->busy_##n##_port_refcounts[port_host_byte_order]; \
+ a->busy_##n##_ports--; \
+ a->busy_##n##_ports_per_thread[thread_index]--; \
+ break;
+ foreach_nat_protocol
+#undef _
+ default : nat_elog_info (nm, "unknown protocol");
+ return;
+ }
+}
+
+void
+nat44_ei_free_session_data_v2 (nat44_ei_main_t *nm, nat44_ei_session_t *s,
+ u32 thread_index, u8 is_ha)
+{
+ clib_bihash_kv_8_8_t kv;
+
+ /* session lookup tables */
+ init_nat_i2o_k (&kv, s);
+ if (clib_bihash_add_del_8_8 (&nm->in2out, &kv, 0))
+ nat_elog_warn (nm, "in2out key del failed");
+ init_nat_o2i_k (&kv, s);
+ if (clib_bihash_add_del_8_8 (&nm->out2in, &kv, 0))
+ nat_elog_warn (nm, "out2in key del failed");
+
+ if (!is_ha)
+ nat_syslog_nat44_apmdel (s->user_index, s->in2out.fib_index,
+ &s->in2out.addr, s->in2out.port, &s->out2in.addr,
+ s->out2in.port, s->nat_proto);
+
+ if (nat44_ei_is_unk_proto_session (s))
+ return;
+
+ if (!is_ha)
+ {
+ /* 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_ha_sdel (&s->out2in.addr, s->out2in.port, &s->ext_host_addr,
+ s->ext_host_port, s->nat_proto, s->out2in.fib_index,
+ thread_index);
+ }
+
+ if (nat44_ei_is_session_static (s))
+ return;
+
+ nat44_ei_free_outside_address_and_port (nm->addresses, thread_index,
+ &s->out2in.addr, s->out2in.port,
+ s->nat_proto);
+}
+
+nat44_ei_user_t *
+nat44_ei_user_get_or_create (nat44_ei_main_t *nm, ip4_address_t *addr,
+ u32 fib_index, u32 thread_index)
+{
+ nat44_ei_user_t *u = 0;
+ nat44_ei_user_key_t user_key;
+ clib_bihash_kv_8_8_t kv, value;
+ nat44_ei_main_per_thread_data_t *tnm = &nm->per_thread_data[thread_index];
+ dlist_elt_t *per_user_list_head_elt;
+
+ user_key.addr.as_u32 = addr->as_u32;
+ user_key.fib_index = fib_index;
+ kv.key = user_key.as_u64;
+
+ /* Ever heard of the "user" = src ip4 address before? */
+ if (clib_bihash_search_8_8 (&tnm->user_hash, &kv, &value))
+ {
+ if (pool_elts (tnm->users) >= nm->max_users_per_thread)
+ {
+ vlib_increment_simple_counter (&nm->user_limit_reached, thread_index,
+ 0, 1);
+ nat_elog_warn (nm, "maximum user limit reached");
+ return NULL;
+ }
+ /* no, make a new one */
+ pool_get (tnm->users, u);
+ clib_memset (u, 0, sizeof (*u));
+
+ u->addr.as_u32 = addr->as_u32;
+ u->fib_index = fib_index;
+
+ pool_get (tnm->list_pool, per_user_list_head_elt);
+
+ u->sessions_per_user_list_head_index =
+ per_user_list_head_elt - tnm->list_pool;
+
+ clib_dlist_init (tnm->list_pool, u->sessions_per_user_list_head_index);
+
+ kv.value = u - tnm->users;
+
+ /* add user */
+ if (clib_bihash_add_del_8_8 (&tnm->user_hash, &kv, 1))
+ {
+ nat_elog_warn (nm, "user_hash key add failed");
+ nat44_ei_delete_user_with_no_session (nm, u, thread_index);
+ return NULL;
+ }
+
+ vlib_set_simple_counter (&nm->total_users, thread_index, 0,
+ pool_elts (tnm->users));
+ }
+ else
+ {
+ u = pool_elt_at_index (tnm->users, value.value);
+ }
+
+ return u;
+}
+
+nat44_ei_session_t *
+nat44_ei_session_alloc_or_recycle (nat44_ei_main_t *nm, nat44_ei_user_t *u,
+ u32 thread_index, f64 now)
+{
+ nat44_ei_session_t *s;
+ nat44_ei_main_per_thread_data_t *tnm = &nm->per_thread_data[thread_index];
+ u32 oldest_per_user_translation_list_index, session_index;
+ dlist_elt_t *oldest_per_user_translation_list_elt;
+ dlist_elt_t *per_user_translation_list_elt;
+
+ /* Over quota? Recycle the least recently used translation */
+ if ((u->nsessions + u->nstaticsessions) >= nm->max_translations_per_user)
+ {
+ oldest_per_user_translation_list_index = clib_dlist_remove_head (
+ tnm->list_pool, u->sessions_per_user_list_head_index);
+
+ ASSERT (oldest_per_user_translation_list_index != ~0);
+
+ /* Add it back to the end of the LRU list */
+ clib_dlist_addtail (tnm->list_pool, u->sessions_per_user_list_head_index,
+ oldest_per_user_translation_list_index);
+ /* Get the list element */
+ oldest_per_user_translation_list_elt = pool_elt_at_index (
+ tnm->list_pool, oldest_per_user_translation_list_index);
+
+ /* Get the session index from the list element */
+ session_index = oldest_per_user_translation_list_elt->value;
+
+ /* Get the session */
+ s = pool_elt_at_index (tnm->sessions, session_index);
+
+ nat44_ei_free_session_data_v2 (nm, s, thread_index, 0);
+ if (nat44_ei_is_session_static (s))
+ u->nstaticsessions--;
+ else
+ u->nsessions--;
+ s->flags = 0;
+ s->total_bytes = 0;
+ s->total_pkts = 0;
+ s->state = 0;
+ s->ext_host_addr.as_u32 = 0;
+ s->ext_host_port = 0;
+ s->ext_host_nat_addr.as_u32 = 0;
+ s->ext_host_nat_port = 0;
+ }
+ else
+ {
+ pool_get (tnm->sessions, s);
+ clib_memset (s, 0, sizeof (*s));
+
+ /* Create list elts */
+ pool_get (tnm->list_pool, per_user_translation_list_elt);
+ clib_dlist_init (tnm->list_pool,
+ per_user_translation_list_elt - tnm->list_pool);
+
+ per_user_translation_list_elt->value = s - tnm->sessions;
+ s->per_user_index = per_user_translation_list_elt - tnm->list_pool;
+ s->per_user_list_head_index = u->sessions_per_user_list_head_index;
+
+ clib_dlist_addtail (tnm->list_pool, s->per_user_list_head_index,
+ per_user_translation_list_elt - tnm->list_pool);
+
+ s->user_index = u - tnm->users;
+ vlib_set_simple_counter (&nm->total_sessions, thread_index, 0,
+ pool_elts (tnm->sessions));
+ }
+
+ s->ha_last_refreshed = now;
+
+ return s;
+}
+
void
-nat44_ei_free_session_data (snat_main_t *sm, snat_session_t *s,
+nat44_ei_free_session_data (nat44_ei_main_t *nm, nat44_ei_session_t *s,
u32 thread_index, u8 is_ha)
{
clib_bihash_kv_8_8_t kv;
init_nat_i2o_k (&kv, s);
- if (clib_bihash_add_del_8_8 (&sm->in2out, &kv, 0))
- nat_elog_warn ("in2out key del failed");
+ if (clib_bihash_add_del_8_8 (&nm->in2out, &kv, 0))
+ nat_elog_warn (nm, "in2out key del failed");
init_nat_o2i_k (&kv, s);
- if (clib_bihash_add_del_8_8 (&sm->out2in, &kv, 0))
- nat_elog_warn ("out2in key del failed");
+ if (clib_bihash_add_del_8_8 (&nm->out2in, &kv, 0))
+ nat_elog_warn (nm, "out2in key del failed");
if (!is_ha)
{
@@ -220,36 +1234,36 @@ nat44_ei_free_session_data (snat_main_t *sm, snat_session_t *s,
thread_index);
}
- if (snat_is_session_static (s))
+ if (nat44_ei_is_session_static (s))
return;
- snat_free_outside_address_and_port (sm->addresses, thread_index,
- &s->out2in.addr, s->out2in.port,
- s->nat_proto);
+ nat44_ei_free_outside_address_and_port (nm->addresses, thread_index,
+ &s->out2in.addr, s->out2in.port,
+ s->nat_proto);
}
static_always_inline void
-nat44_ei_user_del_sessions (snat_user_t *u, u32 thread_index)
+nat44_ei_user_del_sessions (nat44_ei_user_t *u, u32 thread_index)
{
dlist_elt_t *elt;
- snat_session_t *s;
+ nat44_ei_session_t *s;
- snat_main_t *sm = &snat_main;
- snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nat44_ei_main_per_thread_data_t *tnm = &nm->per_thread_data[thread_index];
// get head
elt =
- pool_elt_at_index (tsm->list_pool, u->sessions_per_user_list_head_index);
+ pool_elt_at_index (tnm->list_pool, u->sessions_per_user_list_head_index);
// get first element
- elt = pool_elt_at_index (tsm->list_pool, elt->next);
+ elt = pool_elt_at_index (tnm->list_pool, elt->next);
while (elt->value != ~0)
{
- s = pool_elt_at_index (tsm->sessions, elt->value);
- elt = pool_elt_at_index (tsm->list_pool, elt->next);
+ s = pool_elt_at_index (tnm->sessions, elt->value);
+ elt = pool_elt_at_index (tnm->list_pool, elt->next);
- nat44_ei_free_session_data (sm, s, thread_index, 0);
- nat44_delete_session (sm, s, thread_index);
+ nat44_ei_free_session_data (nm, s, thread_index, 0);
+ nat44_ei_delete_session (nm, s, thread_index);
}
}
@@ -258,28 +1272,25 @@ nat44_ei_user_del (ip4_address_t *addr, u32 fib_index)
{
int rv = 1;
- snat_main_t *sm = &snat_main;
- snat_main_per_thread_data_t *tsm;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nat44_ei_main_per_thread_data_t *tnm;
- snat_user_key_t user_key;
+ nat44_ei_user_key_t user_key;
clib_bihash_kv_8_8_t kv, value;
- if (sm->endpoint_dependent)
- return rv;
-
user_key.addr.as_u32 = addr->as_u32;
user_key.fib_index = fib_index;
kv.key = user_key.as_u64;
- if (sm->num_workers > 1)
+ if (nm->num_workers > 1)
{
- vec_foreach (tsm, sm->per_thread_data)
+ vec_foreach (tnm, nm->per_thread_data)
{
- if (!clib_bihash_search_8_8 (&tsm->user_hash, &kv, &value))
+ if (!clib_bihash_search_8_8 (&tnm->user_hash, &kv, &value))
{
nat44_ei_user_del_sessions (
- pool_elt_at_index (tsm->users, value.value),
- tsm->thread_index);
+ pool_elt_at_index (tnm->users, value.value),
+ tnm->thread_index);
rv = 0;
break;
}
@@ -287,11 +1298,11 @@ nat44_ei_user_del (ip4_address_t *addr, u32 fib_index)
}
else
{
- tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
- if (!clib_bihash_search_8_8 (&tsm->user_hash, &kv, &value))
+ tnm = vec_elt_at_index (nm->per_thread_data, nm->num_workers);
+ if (!clib_bihash_search_8_8 (&tnm->user_hash, &kv, &value))
{
nat44_ei_user_del_sessions (
- pool_elt_at_index (tsm->users, value.value), tsm->thread_index);
+ pool_elt_at_index (tnm->users, value.value), tnm->thread_index);
rv = 0;
}
}
@@ -299,34 +1310,34 @@ nat44_ei_user_del (ip4_address_t *addr, u32 fib_index)
}
void
-nat44_ei_static_mapping_del_sessions (snat_main_t *sm,
- snat_main_per_thread_data_t *tsm,
- snat_user_key_t u_key, int addr_only,
+nat44_ei_static_mapping_del_sessions (nat44_ei_main_t *nm,
+ nat44_ei_main_per_thread_data_t *tnm,
+ nat44_ei_user_key_t u_key, int addr_only,
ip4_address_t e_addr, u16 e_port)
{
clib_bihash_kv_8_8_t kv, value;
kv.key = u_key.as_u64;
u64 user_index;
dlist_elt_t *head, *elt;
- snat_user_t *u;
- snat_session_t *s;
+ nat44_ei_user_t *u;
+ nat44_ei_session_t *s;
u32 elt_index, head_index, ses_index;
- if (!clib_bihash_search_8_8 (&tsm->user_hash, &kv, &value))
+ if (!clib_bihash_search_8_8 (&tnm->user_hash, &kv, &value))
{
user_index = value.value;
- u = pool_elt_at_index (tsm->users, user_index);
+ u = pool_elt_at_index (tnm->users, user_index);
if (u->nstaticsessions)
{
head_index = u->sessions_per_user_list_head_index;
- head = pool_elt_at_index (tsm->list_pool, head_index);
+ head = pool_elt_at_index (tnm->list_pool, head_index);
elt_index = head->next;
- elt = pool_elt_at_index (tsm->list_pool, elt_index);
+ elt = pool_elt_at_index (tnm->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);
+ s = pool_elt_at_index (tnm->sessions, ses_index);
+ elt = pool_elt_at_index (tnm->list_pool, elt->next);
ses_index = elt->value;
if (!addr_only)
@@ -336,14 +1347,12 @@ nat44_ei_static_mapping_del_sessions (snat_main_t *sm,
continue;
}
- if (is_lb_session (s))
+ if (!nat44_ei_is_session_static (s))
continue;
- if (!snat_is_session_static (s))
- continue;
-
- nat_free_session_data (sm, s, tsm - sm->per_thread_data, 0);
- nat44_delete_session (sm, s, tsm - sm->per_thread_data);
+ 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);
if (!addr_only)
break;
@@ -356,18 +1365,18 @@ u32
nat44_ei_get_in2out_worker_index (ip4_header_t *ip0, u32 rx_fib_index0,
u8 is_output)
{
- snat_main_t *sm = &snat_main;
+ nat44_ei_main_t *nm = &nat44_ei_main;
u32 next_worker_index = 0;
u32 hash;
- next_worker_index = sm->first_worker_index;
+ next_worker_index = nm->first_worker_index;
hash = ip0->src_address.as_u32 + (ip0->src_address.as_u32 >> 8) +
(ip0->src_address.as_u32 >> 16) + (ip0->src_address.as_u32 >> 24);
- if (PREDICT_TRUE (is_pow2 (_vec_len (sm->workers))))
- next_worker_index += sm->workers[hash & (_vec_len (sm->workers) - 1)];
+ if (PREDICT_TRUE (is_pow2 (_vec_len (nm->workers))))
+ next_worker_index += nm->workers[hash & (_vec_len (nm->workers) - 1)];
else
- next_worker_index += sm->workers[hash % _vec_len (sm->workers)];
+ next_worker_index += nm->workers[hash % _vec_len (nm->workers)];
return next_worker_index;
}
@@ -376,22 +1385,22 @@ u32
nat44_ei_get_out2in_worker_index (vlib_buffer_t *b, ip4_header_t *ip0,
u32 rx_fib_index0, u8 is_output)
{
- snat_main_t *sm = &snat_main;
+ nat44_ei_main_t *nm = &nat44_ei_main;
udp_header_t *udp;
u16 port;
clib_bihash_kv_8_8_t kv, value;
- snat_static_mapping_t *m;
+ nat44_ei_static_mapping_t *m;
u32 proto;
u32 next_worker_index = 0;
/* first try static mappings without port */
- if (PREDICT_FALSE (pool_elts (sm->static_mappings)))
+ if (PREDICT_FALSE (pool_elts (nm->static_mappings)))
{
init_nat_k (&kv, ip0->dst_address, 0, rx_fib_index0, 0);
- if (!clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv,
+ if (!clib_bihash_search_8_8 (&nm->static_mapping_by_external, &kv,
&value))
{
- m = pool_elt_at_index (sm->static_mappings, value.value);
+ m = pool_elt_at_index (nm->static_mappings, value.value);
return m->workers[0];
}
}
@@ -438,33 +1447,34 @@ nat44_ei_get_out2in_worker_index (vlib_buffer_t *b, ip4_header_t *ip0,
}
/* try static mappings with port */
- if (PREDICT_FALSE (pool_elts (sm->static_mappings)))
+ if (PREDICT_FALSE (pool_elts (nm->static_mappings)))
{
init_nat_k (&kv, ip0->dst_address, port, rx_fib_index0, proto);
- if (!clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv,
+ if (!clib_bihash_search_8_8 (&nm->static_mapping_by_external, &kv,
&value))
{
- m = pool_elt_at_index (sm->static_mappings, value.value);
+ m = pool_elt_at_index (nm->static_mappings, value.value);
return m->workers[0];
}
}
/* worker by outside port */
- next_worker_index = sm->first_worker_index;
+ next_worker_index = nm->first_worker_index;
next_worker_index +=
- sm->workers[(clib_net_to_host_u16 (port) - 1024) / sm->port_per_thread];
+ nm->workers[(clib_net_to_host_u16 (port) - 1024) / nm->port_per_thread];
return next_worker_index;
}
static int
-nat44_ei_alloc_default_cb (snat_address_t *addresses, u32 fib_index,
+nat44_ei_alloc_default_cb (nat44_ei_address_t *addresses, u32 fib_index,
u32 thread_index, nat_protocol_t proto,
ip4_address_t *addr, u16 *port, u16 port_per_thread,
u32 snat_thread_index)
{
- int i;
- snat_address_t *a, *ga = 0;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nat44_ei_address_t *a, *ga = 0;
u32 portnum;
+ int i;
for (i = 0; i < vec_len (addresses); i++)
{
@@ -480,7 +1490,9 @@ nat44_ei_alloc_default_cb (snat_address_t *addresses, u32 fib_index,
while (1) \
{ \
portnum = (port_per_thread * snat_thread_index) + \
- snat_random_port (0, port_per_thread - 1) + 1024; \
+ nat_random_port (&nm->random_seed, 0, \
+ port_per_thread - 1) + \
+ 1024; \
if (a->busy_##n##_port_refcounts[portnum]) \
continue; \
--a->busy_##n##_port_refcounts[portnum]; \
@@ -499,7 +1511,7 @@ nat44_ei_alloc_default_cb (snat_address_t *addresses, u32 fib_index,
break;
foreach_nat_protocol
#undef _
- default : nat_elog_info ("unknown protocol");
+ default : nat_elog_info (nm, "unknown protocol");
return 1;
}
}
@@ -513,8 +1525,9 @@ nat44_ei_alloc_default_cb (snat_address_t *addresses, u32 fib_index,
case NAT_PROTOCOL_##N: \
while (1) \
{ \
- portnum = (port_per_thread * snat_thread_index) + \
- snat_random_port (0, port_per_thread - 1) + 1024; \
+ portnum = \
+ (port_per_thread * snat_thread_index) + \
+ nat_random_port (&nm->random_seed, 0, port_per_thread - 1) + 1024; \
if (a->busy_##n##_port_refcounts[portnum]) \
continue; \
++a->busy_##n##_port_refcounts[portnum]; \
@@ -527,7 +1540,7 @@ nat44_ei_alloc_default_cb (snat_address_t *addresses, u32 fib_index,
break;
foreach_nat_protocol
#undef _
- default : nat_elog_info ("unknown protocol");
+ default : nat_elog_info (nm, "unknown protocol");
return 1;
}
}
@@ -538,16 +1551,16 @@ nat44_ei_alloc_default_cb (snat_address_t *addresses, u32 fib_index,
}
static int
-nat44_ei_alloc_range_cb (snat_address_t *addresses, u32 fib_index,
+nat44_ei_alloc_range_cb (nat44_ei_address_t *addresses, u32 fib_index,
u32 thread_index, nat_protocol_t proto,
ip4_address_t *addr, u16 *port, u16 port_per_thread,
u32 snat_thread_index)
{
- snat_main_t *sm = &snat_main;
- snat_address_t *a = addresses;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nat44_ei_address_t *a = addresses;
u16 portnum, ports;
- ports = sm->end_port - sm->start_port + 1;
+ ports = nm->end_port - nm->start_port + 1;
if (!vec_len (addresses))
goto exhausted;
@@ -560,7 +1573,8 @@ nat44_ei_alloc_range_cb (snat_address_t *addresses, u32 fib_index,
{ \
while (1) \
{ \
- portnum = snat_random_port (sm->start_port, sm->end_port); \
+ portnum = nat_random_port (&nm->random_seed, nm->start_port, \
+ nm->end_port); \
if (a->busy_##n##_port_refcounts[portnum]) \
continue; \
++a->busy_##n##_port_refcounts[portnum]; \
@@ -573,7 +1587,7 @@ nat44_ei_alloc_range_cb (snat_address_t *addresses, u32 fib_index,
break;
foreach_nat_protocol
#undef _
- default : nat_elog_info ("unknown protocol");
+ default : nat_elog_info (nm, "unknown protocol");
return 1;
}
@@ -584,16 +1598,16 @@ exhausted:
}
static int
-nat44_ei_alloc_mape_cb (snat_address_t *addresses, u32 fib_index,
+nat44_ei_alloc_mape_cb (nat44_ei_address_t *addresses, u32 fib_index,
u32 thread_index, nat_protocol_t proto,
ip4_address_t *addr, u16 *port, u16 port_per_thread,
u32 snat_thread_index)
{
- snat_main_t *sm = &snat_main;
- snat_address_t *a = addresses;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nat44_ei_address_t *a = addresses;
u16 m, ports, portnum, A, j;
- m = 16 - (sm->psid_offset + sm->psid_length);
- ports = (1 << (16 - sm->psid_length)) - (1 << m);
+ m = 16 - (nm->psid_offset + nm->psid_length);
+ ports = (1 << (16 - nm->psid_length)) - (1 << m);
if (!vec_len (addresses))
goto exhausted;
@@ -606,9 +1620,10 @@ nat44_ei_alloc_mape_cb (snat_address_t *addresses, u32 fib_index,
{ \
while (1) \
{ \
- A = snat_random_port (1, pow2_mask (sm->psid_offset)); \
- j = snat_random_port (0, pow2_mask (m)); \
- portnum = A | (sm->psid << sm->psid_offset) | (j << (16 - m)); \
+ A = nat_random_port (&nm->random_seed, 1, \
+ pow2_mask (nm->psid_offset)); \
+ j = nat_random_port (&nm->random_seed, 0, pow2_mask (m)); \
+ portnum = A | (nm->psid << nm->psid_offset) | (j << (16 - m)); \
if (a->busy_##n##_port_refcounts[portnum]) \
continue; \
++a->busy_##n##_port_refcounts[portnum]; \
@@ -621,7 +1636,7 @@ nat44_ei_alloc_mape_cb (snat_address_t *addresses, u32 fib_index,
break;
foreach_nat_protocol
#undef _
- default : nat_elog_info ("unknown protocol");
+ default : nat_elog_info (nm, "unknown protocol");
return 1;
}
@@ -634,33 +1649,33 @@ exhausted:
void
nat44_ei_set_alloc_default ()
{
- snat_main_t *sm = &snat_main;
+ nat44_ei_main_t *nm = &nat44_ei_main;
- sm->addr_and_port_alloc_alg = NAT_ADDR_AND_PORT_ALLOC_ALG_DEFAULT;
- sm->alloc_addr_and_port = nat44_ei_alloc_default_cb;
+ nm->addr_and_port_alloc_alg = NAT44_EI_ADDR_AND_PORT_ALLOC_ALG_DEFAULT;
+ nm->alloc_addr_and_port = nat44_ei_alloc_default_cb;
}
void
nat44_ei_set_alloc_range (u16 start_port, u16 end_port)
{
- snat_main_t *sm = &snat_main;
+ nat44_ei_main_t *nm = &nat44_ei_main;
- sm->addr_and_port_alloc_alg = NAT_ADDR_AND_PORT_ALLOC_ALG_RANGE;
- sm->alloc_addr_and_port = nat44_ei_alloc_range_cb;
- sm->start_port = start_port;
- sm->end_port = end_port;
+ nm->addr_and_port_alloc_alg = NAT44_EI_ADDR_AND_PORT_ALLOC_ALG_RANGE;
+ nm->alloc_addr_and_port = nat44_ei_alloc_range_cb;
+ nm->start_port = start_port;
+ nm->end_port = end_port;
}
void
nat44_ei_set_alloc_mape (u16 psid, u16 psid_offset, u16 psid_length)
{
- snat_main_t *sm = &snat_main;
+ nat44_ei_main_t *nm = &nat44_ei_main;
- sm->addr_and_port_alloc_alg = NAT_ADDR_AND_PORT_ALLOC_ALG_MAPE;
- sm->alloc_addr_and_port = nat44_ei_alloc_mape_cb;
- sm->psid = psid;
- sm->psid_offset = psid_offset;
- sm->psid_length = psid_length;
+ nm->addr_and_port_alloc_alg = NAT44_EI_ADDR_AND_PORT_ALLOC_ALG_MAPE;
+ nm->alloc_addr_and_port = nat44_ei_alloc_mape_cb;
+ nm->psid = psid;
+ nm->psid_offset = psid_offset;
+ nm->psid_length = psid_length;
}
static void
@@ -670,10 +1685,10 @@ nat44_ei_add_static_mapping_when_resolved (ip4_address_t l_addr, u16 l_port,
int addr_only, int identity_nat,
u8 *tag)
{
- snat_main_t *sm = &snat_main;
- snat_static_map_resolve_t *rp;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nat44_ei_static_map_resolve_t *rp;
- vec_add2 (sm->to_resolve, rp, 1);
+ vec_add2 (nm->to_resolve, rp, 1);
clib_memset (rp, 0, sizeof (*rp));
rp->l_addr.as_u32 = l_addr.as_u32;
@@ -687,65 +1702,131 @@ nat44_ei_add_static_mapping_when_resolved (ip4_address_t l_addr, u16 l_port,
rp->tag = vec_dup (tag);
}
+void
+nat44_ei_delete_session (nat44_ei_main_t *nm, nat44_ei_session_t *ses,
+ u32 thread_index)
+{
+ nat44_ei_main_per_thread_data_t *tnm =
+ vec_elt_at_index (nm->per_thread_data, thread_index);
+ clib_bihash_kv_8_8_t kv, value;
+ nat44_ei_user_t *u;
+ const nat44_ei_user_key_t u_key = { .addr = ses->in2out.addr,
+ .fib_index = ses->in2out.fib_index };
+ const u8 u_static = nat44_ei_is_session_static (ses);
+
+ clib_dlist_remove (tnm->list_pool, ses->per_user_index);
+ pool_put_index (tnm->list_pool, ses->per_user_index);
+
+ pool_put (tnm->sessions, ses);
+ vlib_set_simple_counter (&nm->total_sessions, thread_index, 0,
+ pool_elts (tnm->sessions));
+
+ kv.key = u_key.as_u64;
+ if (!clib_bihash_search_8_8 (&tnm->user_hash, &kv, &value))
+ {
+ u = pool_elt_at_index (tnm->users, value.value);
+ if (u_static)
+ u->nstaticsessions--;
+ else
+ u->nsessions--;
+
+ nat44_ei_delete_user_with_no_session (nm, u, thread_index);
+ }
+}
+
int
-nat44_ei_del_session (snat_main_t *sm, ip4_address_t *addr, u16 port,
+nat44_ei_del_session (nat44_ei_main_t *nm, ip4_address_t *addr, u16 port,
nat_protocol_t proto, u32 vrf_id, int is_in)
{
- snat_main_per_thread_data_t *tsm;
+ 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);
- snat_session_t *s;
+ nat44_ei_session_t *s;
clib_bihash_8_8_t *t;
- if (sm->endpoint_dependent)
- return VNET_API_ERROR_UNSUPPORTED;
-
ip.dst_address.as_u32 = ip.src_address.as_u32 = addr->as_u32;
- if (sm->num_workers > 1)
- tsm = vec_elt_at_index (sm->per_thread_data,
- sm->worker_in2out_cb (&ip, fib_index, 0));
+ if (nm->num_workers > 1)
+ tnm = vec_elt_at_index (nm->per_thread_data,
+ nm->worker_in2out_cb (&ip, fib_index, 0));
else
- tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
+ tnm = vec_elt_at_index (nm->per_thread_data, nm->num_workers);
init_nat_k (&kv, *addr, port, fib_index, proto);
- t = is_in ? &sm->in2out : &sm->out2in;
+ t = is_in ? &nm->in2out : &nm->out2in;
if (!clib_bihash_search_8_8 (t, &kv, &value))
{
- if (pool_is_free_index (tsm->sessions, value.value))
+ if (pool_is_free_index (tnm->sessions, value.value))
return VNET_API_ERROR_UNSPECIFIED;
- s = pool_elt_at_index (tsm->sessions, value.value);
- nat_free_session_data (sm, s, tsm - sm->per_thread_data, 0);
- nat44_delete_session (sm, s, tsm - sm->per_thread_data);
+ s = pool_elt_at_index (tnm->sessions, value.value);
+ 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;
}
return VNET_API_ERROR_NO_SUCH_ENTRY;
}
+u32
+nat44_ei_get_thread_idx_by_port (u16 e_port)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ u32 thread_idx = nm->num_workers;
+ if (nm->num_workers > 1)
+ {
+ thread_idx = nm->first_worker_index +
+ nm->workers[(e_port - 1024) / nm->port_per_thread];
+ }
+ return thread_idx;
+}
+
+void
+nat44_ei_add_del_addr_to_fib (ip4_address_t *addr, u8 p_len, u32 sw_if_index,
+ int is_add)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ fib_prefix_t prefix = {
+ .fp_len = p_len,
+ .fp_proto = FIB_PROTOCOL_IP4,
+ .fp_addr = {
+ .ip4.as_u32 = addr->as_u32,
+ },
+ };
+ u32 fib_index = ip4_fib_table_get_index_for_sw_if_index (sw_if_index);
+
+ if (is_add)
+ fib_table_entry_update_one_path (
+ fib_index, &prefix, nm->fib_src_low,
+ (FIB_ENTRY_FLAG_CONNECTED | FIB_ENTRY_FLAG_LOCAL |
+ FIB_ENTRY_FLAG_EXCLUSIVE),
+ DPO_PROTO_IP4, NULL, sw_if_index, ~0, 1, NULL, FIB_ROUTE_PATH_FLAG_NONE);
+ else
+ fib_table_entry_delete (fib_index, &prefix, nm->fib_src_low);
+}
+
int
nat44_ei_add_del_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
u16 l_port, u16 e_port, nat_protocol_t proto,
u32 sw_if_index, u32 vrf_id, u8 addr_only,
u8 identity_nat, u8 *tag, u8 is_add)
{
- snat_main_t *sm = &snat_main;
- snat_static_mapping_t *m = 0;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nat44_ei_static_mapping_t *m = 0;
clib_bihash_kv_8_8_t kv, value;
- snat_address_t *a = 0;
+ nat44_ei_address_t *a = 0;
u32 fib_index = ~0;
- snat_interface_t *interface;
- snat_main_per_thread_data_t *tsm;
- snat_user_key_t u_key;
- snat_user_t *u;
+ nat44_ei_interface_t *interface;
+ nat44_ei_main_per_thread_data_t *tnm;
+ nat44_ei_user_key_t u_key;
+ nat44_ei_user_t *u;
dlist_elt_t *head, *elt;
u32 elt_index, head_index;
u32 ses_index;
u64 user_index;
- snat_session_t *s;
- snat_static_map_resolve_t *rp, *rp_match = 0;
- nat44_lb_addr_port_t *local;
+ nat44_ei_session_t *s;
+ nat44_ei_static_map_resolve_t *rp, *rp_match = 0;
+ nat44_ei_lb_addr_port_t *local;
u32 find = ~0;
int i;
@@ -753,9 +1834,9 @@ nat44_ei_add_del_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
{
ip4_address_t *first_int_addr;
- for (i = 0; i < vec_len (sm->to_resolve); i++)
+ for (i = 0; i < vec_len (nm->to_resolve); i++)
{
- rp = sm->to_resolve + i;
+ rp = nm->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)
@@ -774,7 +1855,7 @@ nat44_ei_add_del_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
/* Might be already set... */
first_int_addr = ip4_interface_first_address (
- sm->ip4_main, sw_if_index, 0 /* just want the address */);
+ nm->ip4_main, sw_if_index, 0 /* just want the address */);
if (is_add)
{
@@ -799,7 +1880,7 @@ nat44_ei_add_del_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
if (!rp_match)
return VNET_API_ERROR_NO_SUCH_ENTRY;
- vec_del1 (sm->to_resolve, i);
+ vec_del1 (nm->to_resolve, i);
if (!first_int_addr)
return 0;
@@ -812,15 +1893,15 @@ nat44_ei_add_del_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
}
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 = pool_elt_at_index (sm->static_mappings, value.value);
+ if (!clib_bihash_search_8_8 (&nm->static_mapping_by_external, &kv, &value))
+ m = pool_elt_at_index (nm->static_mappings, value.value);
if (is_add)
{
if (m)
{
// identity mapping for second vrf
- if (is_identity_static_mapping (m))
+ if (nat44_ei_is_identity_static_mapping (m))
{
pool_foreach (local, m->locals)
{
@@ -830,10 +1911,10 @@ nat44_ei_add_del_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
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);
+ FIB_PROTOCOL_IP4, vrf_id, nm->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);
+ m->proto, 0, m - nm->static_mappings);
+ clib_bihash_add_del_8_8 (&nm->static_mapping_by_local, &kv, 1);
return 0;
}
return VNET_API_ERROR_VALUE_EXIST;
@@ -843,34 +1924,34 @@ nat44_ei_add_del_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
if (vrf_id != ~0)
{
fib_index = fib_table_find_or_create_and_lock (
- FIB_PROTOCOL_IP4, vrf_id, sm->fib_src_low);
+ FIB_PROTOCOL_IP4, vrf_id, nm->fib_src_low);
}
/* If not specified use inside VRF id from NAT44 plugin 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);
+ fib_index = nm->inside_fib_index;
+ vrf_id = nm->inside_vrf_id;
+ fib_table_lock (fib_index, FIB_PROTOCOL_IP4, nm->fib_src_low);
}
if (!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,
+ if (!clib_bihash_search_8_8 (&nm->static_mapping_by_local, &kv,
&value))
return VNET_API_ERROR_VALUE_EXIST;
}
/* 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))
+ if (!(addr_only || nm->static_mapping_only))
{
- for (i = 0; i < vec_len (sm->addresses); i++)
+ for (i = 0; i < vec_len (nm->addresses); i++)
{
- if (sm->addresses[i].addr.as_u32 == e_addr.as_u32)
+ if (nm->addresses[i].addr.as_u32 == e_addr.as_u32)
{
- a = sm->addresses + i;
+ a = nm->addresses + i;
/* External port must be unused */
switch (proto)
{
@@ -882,12 +1963,13 @@ nat44_ei_add_del_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
if (e_port > 1024) \
{ \
a->busy_##n##_ports++; \
- a->busy_##n##_ports_per_thread[get_thread_idx_by_port (e_port)]++; \
+ a->busy_##n##_ports_per_thread[nat44_ei_get_thread_idx_by_port ( \
+ e_port)]++; \
} \
break;
foreach_nat_protocol
#undef _
- default : nat_elog_info ("unknown protocol");
+ default : nat_elog_info (nm, "unknown protocol");
return VNET_API_ERROR_INVALID_VALUE_2;
}
break;
@@ -898,9 +1980,9 @@ nat44_ei_add_del_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
{
if (sw_if_index != ~0)
{
- for (i = 0; i < vec_len (sm->to_resolve); i++)
+ for (i = 0; i < vec_len (nm->to_resolve); i++)
{
- rp = sm->to_resolve + i;
+ rp = nm->to_resolve + i;
if (rp->addr_only)
continue;
if (rp->sw_if_index != sw_if_index &&
@@ -909,7 +1991,7 @@ nat44_ei_add_del_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
rp->e_port != e_port && rp->proto != proto)
continue;
- vec_del1 (sm->to_resolve, i);
+ vec_del1 (nm->to_resolve, i);
break;
}
}
@@ -917,14 +1999,14 @@ nat44_ei_add_del_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
}
}
- pool_get (sm->static_mappings, m);
+ pool_get (nm->static_mappings, m);
clib_memset (m, 0, sizeof (*m));
m->tag = vec_dup (tag);
m->local_addr = l_addr;
m->external_addr = e_addr;
if (addr_only)
- m->flags |= NAT_STATIC_MAPPING_FLAG_ADDR_ONLY;
+ m->flags |= NAT44_EI_STATIC_MAPPING_FLAG_ADDR_ONLY;
else
{
m->local_port = l_port;
@@ -934,7 +2016,7 @@ nat44_ei_add_del_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
if (identity_nat)
{
- m->flags |= NAT_STATIC_MAPPING_FLAG_IDENTITY_NAT;
+ m->flags |= NAT44_EI_STATIC_MAPPING_FLAG_IDENTITY_NAT;
pool_get (m->locals, local);
local->vrf_id = vrf_id;
local->fib_index = fib_index;
@@ -945,58 +2027,59 @@ nat44_ei_add_del_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
m->fib_index = fib_index;
}
- if (sm->num_workers > 1)
+ if (nm->num_workers > 1)
{
ip4_header_t ip = {
.src_address = m->local_addr,
};
- vec_add1 (m->workers, sm->worker_in2out_cb (&ip, m->fib_index, 0));
- tsm = vec_elt_at_index (sm->per_thread_data, m->workers[0]);
+ vec_add1 (m->workers, nm->worker_in2out_cb (&ip, m->fib_index, 0));
+ tnm = vec_elt_at_index (nm->per_thread_data, m->workers[0]);
}
else
- tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
+ tnm = vec_elt_at_index (nm->per_thread_data, nm->num_workers);
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);
+ m - nm->static_mappings);
+ clib_bihash_add_del_8_8 (&nm->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);
+ m - nm->static_mappings);
+ clib_bihash_add_del_8_8 (&nm->static_mapping_by_external, &kv, 1);
/* Delete dynamic sessions matching local address (+ local port) */
// TODO: based on type of NAT EI/ED
- if (!(sm->static_mapping_only))
+ if (!(nm->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))
+ if (!clib_bihash_search_8_8 (&tnm->user_hash, &kv, &value))
{
user_index = value.value;
- u = pool_elt_at_index (tsm->users, user_index);
+ u = pool_elt_at_index (tnm->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);
+ head = pool_elt_at_index (tnm->list_pool, head_index);
elt_index = head->next;
- elt = pool_elt_at_index (tsm->list_pool, elt_index);
+ elt = pool_elt_at_index (tnm->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);
+ s = pool_elt_at_index (tnm->sessions, ses_index);
+ elt = pool_elt_at_index (tnm->list_pool, elt->next);
ses_index = elt->value;
- if (snat_is_session_static (s))
+ if (nat44_ei_is_session_static (s))
continue;
if (!addr_only && s->in2out.port != m->local_port)
continue;
- nat_free_session_data (sm, s, tsm - sm->per_thread_data,
- 0);
- nat44_delete_session (sm, s, tsm - sm->per_thread_data);
+ 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);
if (!addr_only)
break;
@@ -1018,7 +2101,7 @@ nat44_ei_add_del_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
if (identity_nat)
{
if (vrf_id == ~0)
- vrf_id = sm->inside_vrf_id;
+ vrf_id = nm->inside_vrf_id;
pool_foreach (local, m->locals)
{
@@ -1036,13 +2119,13 @@ nat44_ei_add_del_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
fib_index = m->fib_index;
/* Free external address port */
- if (!(addr_only || sm->static_mapping_only))
+ if (!(addr_only || nm->static_mapping_only))
{
- for (i = 0; i < vec_len (sm->addresses); i++)
+ for (i = 0; i < vec_len (nm->addresses); i++)
{
- if (sm->addresses[i].addr.as_u32 == e_addr.as_u32)
+ if (nm->addresses[i].addr.as_u32 == e_addr.as_u32)
{
- a = sm->addresses + i;
+ a = nm->addresses + i;
switch (proto)
{
#define _(N, j, n, s) \
@@ -1051,7 +2134,8 @@ nat44_ei_add_del_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
if (e_port > 1024) \
{ \
a->busy_##n##_ports--; \
- a->busy_##n##_ports_per_thread[get_thread_idx_by_port (e_port)]--; \
+ a->busy_##n##_ports_per_thread[nat44_ei_get_thread_idx_by_port ( \
+ e_port)]--; \
} \
break;
foreach_nat_protocol
@@ -1063,56 +2147,58 @@ nat44_ei_add_del_static_mapping (ip4_address_t l_addr, ip4_address_t e_addr,
}
}
- if (sm->num_workers > 1)
- tsm = vec_elt_at_index (sm->per_thread_data, m->workers[0]);
+ if (nm->num_workers > 1)
+ tnm = vec_elt_at_index (nm->per_thread_data, m->workers[0]);
else
- tsm = vec_elt_at_index (sm->per_thread_data, sm->num_workers);
+ tnm = vec_elt_at_index (nm->per_thread_data, nm->num_workers);
init_nat_k (&kv, m->local_addr, m->local_port, fib_index, m->proto);
- clib_bihash_add_del_8_8 (&sm->static_mapping_by_local, &kv, 0);
+ clib_bihash_add_del_8_8 (&nm->static_mapping_by_local, &kv, 0);
/* Delete session(s) for static mapping if exist */
- if (!(sm->static_mapping_only) ||
- (sm->static_mapping_only && sm->static_mapping_connection_tracking))
+ if (!(nm->static_mapping_only) ||
+ (nm->static_mapping_only && nm->static_mapping_connection_tracking))
{
u_key.addr = m->local_addr;
u_key.fib_index = fib_index;
kv.key = u_key.as_u64;
- nat44_ei_static_mapping_del_sessions (sm, tsm, u_key, addr_only,
+ nat44_ei_static_mapping_del_sessions (nm, tnm, u_key, 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, nm->fib_src_low);
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);
+ clib_bihash_add_del_8_8 (&nm->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);
+ pool_put (nm->static_mappings, m);
}
if (!addr_only || (l_addr.as_u32 == e_addr.as_u32))
return 0;
/* Add/delete external address to FIB */
- pool_foreach (interface, sm->interfaces)
+ pool_foreach (interface, nm->interfaces)
{
- if (nat_interface_is_inside (interface) || sm->out2in_dpo)
+ if (nat44_ei_interface_is_inside (interface) || nm->out2in_dpo)
continue;
- snat_add_del_addr_to_fib (&e_addr, 32, interface->sw_if_index, is_add);
+ nat44_ei_add_del_addr_to_fib (&e_addr, 32, interface->sw_if_index,
+ is_add);
break;
}
- pool_foreach (interface, sm->output_feature_interfaces)
+ pool_foreach (interface, nm->output_feature_interfaces)
{
- if (nat_interface_is_inside (interface) || sm->out2in_dpo)
+ if (nat44_ei_interface_is_inside (interface) || nm->out2in_dpo)
continue;
- snat_add_del_addr_to_fib (&e_addr, 32, interface->sw_if_index, is_add);
+ nat44_ei_add_del_addr_to_fib (&e_addr, 32, interface->sw_if_index,
+ is_add);
break;
}
return 0;
@@ -1126,24 +2212,24 @@ nat44_ei_static_mapping_match (ip4_address_t match_addr, u16 match_port,
u32 *mapping_fib_index, u8 by_external,
u8 *is_addr_only, u8 *is_identity_nat)
{
- snat_main_t *sm = &snat_main;
+ nat44_ei_main_t *nm = &nat44_ei_main;
clib_bihash_kv_8_8_t kv, value;
- snat_static_mapping_t *m;
+ nat44_ei_static_mapping_t *m;
u16 port;
if (by_external)
{
init_nat_k (&kv, match_addr, match_port, 0, match_protocol);
- if (clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv,
+ if (clib_bihash_search_8_8 (&nm->static_mapping_by_external, &kv,
&value))
{
/* Try address only mapping */
init_nat_k (&kv, match_addr, 0, 0, 0);
- if (clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv,
+ if (clib_bihash_search_8_8 (&nm->static_mapping_by_external, &kv,
&value))
return 1;
}
- m = pool_elt_at_index (sm->static_mappings, value.value);
+ m = pool_elt_at_index (nm->static_mappings, value.value);
*mapping_fib_index = m->fib_index;
*mapping_addr = m->local_addr;
@@ -1153,99 +2239,155 @@ nat44_ei_static_mapping_match (ip4_address_t match_addr, u16 match_port,
{
init_nat_k (&kv, match_addr, match_port, match_fib_index,
match_protocol);
- if (clib_bihash_search_8_8 (&sm->static_mapping_by_local, &kv, &value))
+ if (clib_bihash_search_8_8 (&nm->static_mapping_by_local, &kv, &value))
{
/* Try address only mapping */
init_nat_k (&kv, match_addr, 0, match_fib_index, 0);
- if (clib_bihash_search_8_8 (&sm->static_mapping_by_local, &kv,
+ if (clib_bihash_search_8_8 (&nm->static_mapping_by_local, &kv,
&value))
return 1;
}
- m = pool_elt_at_index (sm->static_mappings, value.value);
+ m = pool_elt_at_index (nm->static_mappings, value.value);
- *mapping_fib_index = sm->outside_fib_index;
+ *mapping_fib_index = nm->outside_fib_index;
*mapping_addr = m->external_addr;
port = m->external_port;
}
/* Address only mapping doesn't change port */
- if (is_addr_only_static_mapping (m))
+ if (nat44_ei_is_addr_only_static_mapping (m))
*mapping_port = match_port;
else
*mapping_port = port;
if (PREDICT_FALSE (is_addr_only != 0))
- *is_addr_only = is_addr_only_static_mapping (m);
+ *is_addr_only = nat44_ei_is_addr_only_static_mapping (m);
if (PREDICT_FALSE (is_identity_nat != 0))
- *is_identity_nat = is_identity_static_mapping (m);
+ *is_identity_nat = nat44_ei_is_identity_static_mapping (m);
return 0;
}
static void
-nat44_ei_worker_db_free (snat_main_per_thread_data_t *tsm)
+nat44_ei_worker_db_free (nat44_ei_main_per_thread_data_t *tnm)
+{
+ pool_free (tnm->list_pool);
+ pool_free (tnm->lru_pool);
+ pool_free (tnm->sessions);
+ pool_free (tnm->users);
+
+ clib_bihash_free_8_8 (&tnm->user_hash);
+}
+
+u8 *
+format_nat44_ei_key (u8 *s, va_list *args)
{
- pool_free (tsm->list_pool);
- pool_free (tsm->lru_pool);
- pool_free (tsm->sessions);
- pool_free (tsm->users);
+ u64 key = va_arg (*args, u64);
- clib_bihash_free_8_8 (&tsm->user_hash);
+ ip4_address_t addr;
+ u16 port;
+ nat_protocol_t protocol;
+ u32 fib_index;
+
+ split_nat_key (key, &addr, &port, &fib_index, &protocol);
+
+ s = format (s, "%U proto %U port %d fib %d", format_ip4_address, &addr,
+ format_nat_protocol, protocol, clib_net_to_host_u16 (port),
+ fib_index);
+ return s;
+}
+
+u8 *
+format_nat44_ei_user_kvp (u8 *s, va_list *args)
+{
+ clib_bihash_kv_8_8_t *v = va_arg (*args, clib_bihash_kv_8_8_t *);
+ nat44_ei_user_key_t k;
+
+ k.as_u64 = v->key;
+
+ s = format (s, "%U fib %d user-index %llu", format_ip4_address, &k.addr,
+ k.fib_index, v->value);
+
+ return s;
+}
+
+u8 *
+format_nat44_ei_session_kvp (u8 *s, va_list *args)
+{
+ 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);
+
+ return s;
+}
+
+u8 *
+format_nat44_ei_static_mapping_kvp (u8 *s, va_list *args)
+{
+ clib_bihash_kv_8_8_t *v = va_arg (*args, clib_bihash_kv_8_8_t *);
+
+ s = format (s, "%U static-mapping-index %llu", format_nat44_ei_key, v->key,
+ v->value);
+
+ return s;
}
static void
-nat44_ei_worker_db_init (snat_main_per_thread_data_t *tsm, u32 translations,
- u32 translation_buckets, u32 user_buckets)
+nat44_ei_worker_db_init (nat44_ei_main_per_thread_data_t *tnm,
+ u32 translations, u32 translation_buckets,
+ u32 user_buckets)
{
dlist_elt_t *head;
- pool_alloc (tsm->list_pool, translations);
- pool_alloc (tsm->lru_pool, translations);
- pool_alloc (tsm->sessions, translations);
+ pool_alloc (tnm->list_pool, translations);
+ pool_alloc (tnm->lru_pool, translations);
+ pool_alloc (tnm->sessions, translations);
- clib_bihash_init_8_8 (&tsm->user_hash, "users", user_buckets, 0);
+ clib_bihash_init_8_8 (&tnm->user_hash, "users", user_buckets, 0);
- clib_bihash_set_kvp_format_fn_8_8 (&tsm->user_hash, format_user_kvp);
+ clib_bihash_set_kvp_format_fn_8_8 (&tnm->user_hash,
+ format_nat44_ei_user_kvp);
- pool_get (tsm->lru_pool, head);
- tsm->tcp_trans_lru_head_index = head - tsm->lru_pool;
- clib_dlist_init (tsm->lru_pool, tsm->tcp_trans_lru_head_index);
+ pool_get (tnm->lru_pool, head);
+ tnm->tcp_trans_lru_head_index = head - tnm->lru_pool;
+ clib_dlist_init (tnm->lru_pool, tnm->tcp_trans_lru_head_index);
- pool_get (tsm->lru_pool, head);
- tsm->tcp_estab_lru_head_index = head - tsm->lru_pool;
- clib_dlist_init (tsm->lru_pool, tsm->tcp_estab_lru_head_index);
+ pool_get (tnm->lru_pool, head);
+ tnm->tcp_estab_lru_head_index = head - tnm->lru_pool;
+ clib_dlist_init (tnm->lru_pool, tnm->tcp_estab_lru_head_index);
- pool_get (tsm->lru_pool, head);
- tsm->udp_lru_head_index = head - tsm->lru_pool;
- clib_dlist_init (tsm->lru_pool, tsm->udp_lru_head_index);
+ pool_get (tnm->lru_pool, head);
+ tnm->udp_lru_head_index = head - tnm->lru_pool;
+ clib_dlist_init (tnm->lru_pool, tnm->udp_lru_head_index);
- pool_get (tsm->lru_pool, head);
- tsm->icmp_lru_head_index = head - tsm->lru_pool;
- clib_dlist_init (tsm->lru_pool, tsm->icmp_lru_head_index);
+ pool_get (tnm->lru_pool, head);
+ tnm->icmp_lru_head_index = head - tnm->lru_pool;
+ clib_dlist_init (tnm->lru_pool, tnm->icmp_lru_head_index);
- pool_get (tsm->lru_pool, head);
- tsm->unk_proto_lru_head_index = head - tsm->lru_pool;
- clib_dlist_init (tsm->lru_pool, tsm->unk_proto_lru_head_index);
+ pool_get (tnm->lru_pool, head);
+ tnm->unk_proto_lru_head_index = head - tnm->lru_pool;
+ clib_dlist_init (tnm->lru_pool, tnm->unk_proto_lru_head_index);
}
static void
nat44_ei_db_free ()
{
- snat_main_t *sm = &snat_main;
- snat_main_per_thread_data_t *tsm;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nat44_ei_main_per_thread_data_t *tnm;
- pool_free (sm->static_mappings);
- clib_bihash_free_8_8 (&sm->static_mapping_by_local);
- clib_bihash_free_8_8 (&sm->static_mapping_by_external);
+ pool_free (nm->static_mappings);
+ clib_bihash_free_8_8 (&nm->static_mapping_by_local);
+ clib_bihash_free_8_8 (&nm->static_mapping_by_external);
- if (sm->pat)
+ if (nm->pat)
{
- clib_bihash_free_8_8 (&sm->in2out);
- clib_bihash_free_8_8 (&sm->out2in);
- vec_foreach (tsm, sm->per_thread_data)
+ clib_bihash_free_8_8 (&nm->in2out);
+ clib_bihash_free_8_8 (&nm->out2in);
+ vec_foreach (tnm, nm->per_thread_data)
{
- nat44_ei_worker_db_free (tsm);
+ nat44_ei_worker_db_free (tnm);
}
}
}
@@ -1253,32 +2395,34 @@ nat44_ei_db_free ()
static void
nat44_ei_db_init (u32 translations, u32 translation_buckets, u32 user_buckets)
{
- snat_main_t *sm = &snat_main;
- snat_main_per_thread_data_t *tsm;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nat44_ei_main_per_thread_data_t *tnm;
u32 static_mapping_buckets = 1024;
u32 static_mapping_memory_size = 64 << 20;
- clib_bihash_init_8_8 (&sm->static_mapping_by_local,
+ clib_bihash_init_8_8 (&nm->static_mapping_by_local,
"static_mapping_by_local", static_mapping_buckets,
static_mapping_memory_size);
- clib_bihash_init_8_8 (&sm->static_mapping_by_external,
+ clib_bihash_init_8_8 (&nm->static_mapping_by_external,
"static_mapping_by_external", static_mapping_buckets,
static_mapping_memory_size);
- clib_bihash_set_kvp_format_fn_8_8 (&sm->static_mapping_by_local,
- format_static_mapping_kvp);
- clib_bihash_set_kvp_format_fn_8_8 (&sm->static_mapping_by_external,
- format_static_mapping_kvp);
-
- if (sm->pat)
- {
- clib_bihash_init_8_8 (&sm->in2out, "in2out", translation_buckets, 0);
- clib_bihash_init_8_8 (&sm->out2in, "out2in", translation_buckets, 0);
- clib_bihash_set_kvp_format_fn_8_8 (&sm->in2out, format_session_kvp);
- clib_bihash_set_kvp_format_fn_8_8 (&sm->out2in, format_session_kvp);
- vec_foreach (tsm, sm->per_thread_data)
+ clib_bihash_set_kvp_format_fn_8_8 (&nm->static_mapping_by_local,
+ format_nat44_ei_static_mapping_kvp);
+ clib_bihash_set_kvp_format_fn_8_8 (&nm->static_mapping_by_external,
+ format_nat44_ei_static_mapping_kvp);
+
+ if (nm->pat)
+ {
+ clib_bihash_init_8_8 (&nm->in2out, "in2out", translation_buckets, 0);
+ clib_bihash_init_8_8 (&nm->out2in, "out2in", translation_buckets, 0);
+ clib_bihash_set_kvp_format_fn_8_8 (&nm->in2out,
+ format_nat44_ei_session_kvp);
+ clib_bihash_set_kvp_format_fn_8_8 (&nm->out2in,
+ format_nat44_ei_session_kvp);
+ vec_foreach (tnm, nm->per_thread_data)
{
- nat44_ei_worker_db_init (tsm, translations, translation_buckets,
+ nat44_ei_worker_db_init (tnm, translations, translation_buckets,
user_buckets);
}
}
@@ -1288,32 +2432,585 @@ void
nat44_ei_sessions_clear ()
{
nat44_ei_main_t *nm = &nat44_ei_main;
+ nat44_ei_main_per_thread_data_t *tnm;
- snat_main_per_thread_data_t *tsm;
- snat_main_t *sm = &snat_main;
-
- if (sm->pat)
+ if (nm->pat)
{
- clib_bihash_free_8_8 (&sm->in2out);
- clib_bihash_free_8_8 (&sm->out2in);
- clib_bihash_init_8_8 (&sm->in2out, "in2out", nm->translation_buckets, 0);
- clib_bihash_init_8_8 (&sm->out2in, "out2in", nm->translation_buckets, 0);
- clib_bihash_set_kvp_format_fn_8_8 (&sm->in2out, format_session_kvp);
- clib_bihash_set_kvp_format_fn_8_8 (&sm->out2in, format_session_kvp);
- vec_foreach (tsm, sm->per_thread_data)
+ clib_bihash_free_8_8 (&nm->in2out);
+ clib_bihash_free_8_8 (&nm->out2in);
+ clib_bihash_init_8_8 (&nm->in2out, "in2out", nm->translation_buckets, 0);
+ clib_bihash_init_8_8 (&nm->out2in, "out2in", nm->translation_buckets, 0);
+ clib_bihash_set_kvp_format_fn_8_8 (&nm->in2out,
+ format_nat44_ei_session_kvp);
+ clib_bihash_set_kvp_format_fn_8_8 (&nm->out2in,
+ format_nat44_ei_session_kvp);
+ vec_foreach (tnm, nm->per_thread_data)
{
- nat44_ei_worker_db_free (tsm);
- nat44_ei_worker_db_init (tsm, nm->translations,
+ nat44_ei_worker_db_free (tnm);
+ nat44_ei_worker_db_init (tnm, nm->translations,
nm->translation_buckets, nm->user_buckets);
}
}
- // TODO: function for reset counters
- vlib_zero_simple_counter (&sm->total_users, 0);
- vlib_zero_simple_counter (&sm->total_sessions, 0);
- vlib_zero_simple_counter (&sm->user_limit_reached, 0);
+ vlib_zero_simple_counter (&nm->total_users, 0);
+ vlib_zero_simple_counter (&nm->total_sessions, 0);
+ vlib_zero_simple_counter (&nm->user_limit_reached, 0);
}
+static void
+nat44_ei_update_outside_fib (ip4_main_t *im, uword opaque, u32 sw_if_index,
+ u32 new_fib_index, u32 old_fib_index)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nat44_ei_outside_fib_t *outside_fib;
+ nat44_ei_interface_t *i;
+ u8 is_add = 1;
+ u8 match = 0;
+
+ if (!nm->enabled || (new_fib_index == old_fib_index) ||
+ (!vec_len (nm->outside_fibs)))
+ {
+ return;
+ }
+
+ pool_foreach (i, nm->interfaces)
+ {
+ if (i->sw_if_index == sw_if_index)
+ {
+ if (!(nat44_ei_interface_is_outside (i)))
+ return;
+ match = 1;
+ }
+ }
+
+ pool_foreach (i, nm->output_feature_interfaces)
+ {
+ if (i->sw_if_index == sw_if_index)
+ {
+ if (!(nat44_ei_interface_is_outside (i)))
+ return;
+ match = 1;
+ }
+ }
+
+ if (!match)
+ return;
+
+ vec_foreach (outside_fib, nm->outside_fibs)
+ {
+ if (outside_fib->fib_index == old_fib_index)
+ {
+ outside_fib->refcount--;
+ if (!outside_fib->refcount)
+ vec_del1 (nm->outside_fibs, outside_fib - nm->outside_fibs);
+ break;
+ }
+ }
+
+ vec_foreach (outside_fib, nm->outside_fibs)
+ {
+ if (outside_fib->fib_index == new_fib_index)
+ {
+ outside_fib->refcount++;
+ is_add = 0;
+ break;
+ }
+ }
+
+ if (is_add)
+ {
+ vec_add2 (nm->outside_fibs, outside_fib, 1);
+ outside_fib->refcount = 1;
+ outside_fib->fib_index = new_fib_index;
+ }
+}
+
+int
+nat44_ei_add_address (nat44_ei_main_t *nm, ip4_address_t *addr, u32 vrf_id)
+{
+ nat44_ei_address_t *ap;
+ nat44_ei_interface_t *i;
+ vlib_thread_main_t *tm = vlib_get_thread_main ();
+
+ /* Check if address already exists */
+ vec_foreach (ap, nm->addresses)
+ {
+ if (ap->addr.as_u32 == addr->as_u32)
+ {
+ nat44_ei_log_err ("address exist");
+ return VNET_API_ERROR_VALUE_EXIST;
+ }
+ }
+
+ vec_add2 (nm->addresses, ap, 1);
+
+ ap->addr = *addr;
+ if (vrf_id != ~0)
+ ap->fib_index = fib_table_find_or_create_and_lock (
+ FIB_PROTOCOL_IP4, vrf_id, nm->fib_src_low);
+ else
+ ap->fib_index = ~0;
+
+#define _(N, i, n, s) \
+ clib_memset (ap->busy_##n##_port_refcounts, 0, \
+ sizeof (ap->busy_##n##_port_refcounts)); \
+ ap->busy_##n##_ports = 0; \
+ ap->busy_##n##_ports_per_thread = 0; \
+ vec_validate_init_empty (ap->busy_##n##_ports_per_thread, \
+ tm->n_vlib_mains - 1, 0);
+ foreach_nat_protocol
+#undef _
+
+ /* Add external address to FIB */
+ pool_foreach (i, nm->interfaces)
+ {
+ if (nat44_ei_interface_is_inside (i) || nm->out2in_dpo)
+ continue;
+
+ nat44_ei_add_del_addr_to_fib (addr, 32, i->sw_if_index, 1);
+ break;
+ }
+ pool_foreach (i, nm->output_feature_interfaces)
+ {
+ if (nat44_ei_interface_is_inside (i) || nm->out2in_dpo)
+ continue;
+
+ nat44_ei_add_del_addr_to_fib (addr, 32, i->sw_if_index, 1);
+ break;
+ }
+
+ return 0;
+}
+
+int
+nat44_ei_add_interface_address (nat44_ei_main_t *nm, u32 sw_if_index,
+ int is_del)
+{
+ ip4_main_t *ip4_main = nm->ip4_main;
+ ip4_address_t *first_int_addr;
+ nat44_ei_static_map_resolve_t *rp;
+ u32 *indices_to_delete = 0;
+ int i, j;
+ u32 *auto_add_sw_if_indices = nm->auto_add_sw_if_indices;
+
+ first_int_addr = ip4_interface_first_address (ip4_main, sw_if_index,
+ 0 /* just want the address */);
+
+ for (i = 0; i < vec_len (auto_add_sw_if_indices); i++)
+ {
+ if (auto_add_sw_if_indices[i] == sw_if_index)
+ {
+ if (is_del)
+ {
+ /* if have address remove it */
+ if (first_int_addr)
+ (void) nat44_ei_del_address (nm, first_int_addr[0], 1);
+ else
+ {
+ for (j = 0; j < vec_len (nm->to_resolve); j++)
+ {
+ rp = nm->to_resolve + j;
+ if (rp->sw_if_index == sw_if_index)
+ vec_add1 (indices_to_delete, j);
+ }
+ if (vec_len (indices_to_delete))
+ {
+ for (j = vec_len (indices_to_delete) - 1; j >= 0; j--)
+ vec_del1 (nm->to_resolve, j);
+ vec_free (indices_to_delete);
+ }
+ }
+ vec_del1 (nm->auto_add_sw_if_indices, i);
+ }
+ else
+ return VNET_API_ERROR_VALUE_EXIST;
+
+ return 0;
+ }
+ }
+
+ if (is_del)
+ return VNET_API_ERROR_NO_SUCH_ENTRY;
+
+ /* add to the auto-address list */
+ vec_add1 (nm->auto_add_sw_if_indices, sw_if_index);
+
+ /* If the address is already bound - or static - add it now */
+ if (first_int_addr)
+ (void) nat44_ei_add_address (nm, first_int_addr, ~0);
+
+ return 0;
+}
+
+static int
+nat44_ei_is_address_used_in_static_mapping (ip4_address_t addr)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nat44_ei_static_mapping_t *m;
+ pool_foreach (m, nm->static_mappings)
+ {
+ if (nat44_ei_is_addr_only_static_mapping (m) ||
+ nat44_ei_is_identity_static_mapping (m))
+ continue;
+ if (m->external_addr.as_u32 == addr.as_u32)
+ return 1;
+ }
+ return 0;
+}
+
+int
+nat44_ei_del_address (nat44_ei_main_t *nm, ip4_address_t addr, u8 delete_sm)
+{
+ nat44_ei_address_t *a = 0;
+ nat44_ei_session_t *ses;
+ u32 *ses_to_be_removed = 0, *ses_index;
+ nat44_ei_main_per_thread_data_t *tnm;
+ nat44_ei_interface_t *interface;
+ nat44_ei_static_mapping_t *m;
+ int i;
+
+ /* Find SNAT address */
+ for (i = 0; i < vec_len (nm->addresses); i++)
+ {
+ if (nm->addresses[i].addr.as_u32 == addr.as_u32)
+ {
+ a = nm->addresses + i;
+ break;
+ }
+ }
+ if (!a)
+ {
+ nat44_ei_log_err ("no such address");
+ return VNET_API_ERROR_NO_SUCH_ENTRY;
+ }
+
+ if (delete_sm)
+ {
+ pool_foreach (m, nm->static_mappings)
+ {
+ if (m->external_addr.as_u32 == addr.as_u32)
+ (void) nat44_ei_add_del_static_mapping (
+ m->local_addr, m->external_addr, m->local_port, m->external_port,
+ m->proto, ~0 /* sw_if_index */, m->vrf_id,
+ nat44_ei_is_addr_only_static_mapping (m),
+ nat44_ei_is_identity_static_mapping (m), m->tag, 0);
+ }
+ }
+ else
+ {
+ /* Check if address is used in some static mapping */
+ if (nat44_ei_is_address_used_in_static_mapping (addr))
+ {
+ nat44_ei_log_err ("address used in static mapping");
+ return VNET_API_ERROR_UNSPECIFIED;
+ }
+ }
+
+ if (a->fib_index != ~0)
+ fib_table_unlock (a->fib_index, FIB_PROTOCOL_IP4, nm->fib_src_low);
+
+ /* Delete sessions using address */
+ if (a->busy_tcp_ports || a->busy_udp_ports || a->busy_icmp_ports)
+ {
+ vec_foreach (tnm, nm->per_thread_data)
+ {
+ pool_foreach (ses, tnm->sessions)
+ {
+ if (ses->out2in.addr.as_u32 == addr.as_u32)
+ {
+ nat44_ei_free_session_data (nm, ses,
+ tnm - nm->per_thread_data, 0);
+ vec_add1 (ses_to_be_removed, ses - tnm->sessions);
+ }
+ }
+ vec_foreach (ses_index, ses_to_be_removed)
+ {
+ ses = pool_elt_at_index (tnm->sessions, ses_index[0]);
+ nat44_ei_delete_session (nm, ses, tnm - nm->per_thread_data);
+ }
+ vec_free (ses_to_be_removed);
+ }
+ }
+
+#define _(N, i, n, s) vec_free (a->busy_##n##_ports_per_thread);
+ foreach_nat_protocol
+#undef _
+ vec_del1 (nm->addresses, i);
+
+ /* Delete external address from FIB */
+ pool_foreach (interface, nm->interfaces)
+ {
+ if (nat44_ei_interface_is_inside (interface) || nm->out2in_dpo)
+ continue;
+ nat44_ei_add_del_addr_to_fib (&addr, 32, interface->sw_if_index, 0);
+ break;
+ }
+
+ pool_foreach (interface, nm->output_feature_interfaces)
+ {
+ if (nat44_ei_interface_is_inside (interface) || nm->out2in_dpo)
+ continue;
+ nat44_ei_add_del_addr_to_fib (&addr, 32, interface->sw_if_index, 0);
+ break;
+ }
+
+ return 0;
+}
+
+static void
+nat44_ei_ip4_add_del_interface_address_cb (ip4_main_t *im, uword opaque,
+ u32 sw_if_index,
+ ip4_address_t *address,
+ u32 address_length,
+ u32 if_address_index, u32 is_delete)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nat44_ei_static_map_resolve_t *rp;
+ ip4_address_t l_addr;
+ int i, j;
+ int rv;
+ nat44_ei_address_t *addresses = nm->addresses;
+
+ if (!nm->enabled)
+ return;
+
+ for (i = 0; i < vec_len (nm->auto_add_sw_if_indices); i++)
+ {
+ if (sw_if_index == nm->auto_add_sw_if_indices[i])
+ goto match;
+ }
+
+ return;
+
+match:
+ if (!is_delete)
+ {
+ /* Don't trip over lease renewal, static config */
+ for (j = 0; j < vec_len (addresses); j++)
+ if (addresses[j].addr.as_u32 == address->as_u32)
+ return;
+
+ (void) nat44_ei_add_address (nm, address, ~0);
+ /* Scan static map resolution vector */
+ for (j = 0; j < vec_len (nm->to_resolve); j++)
+ {
+ rp = nm->to_resolve + j;
+ if (rp->addr_only)
+ continue;
+ /* On this interface? */
+ if (rp->sw_if_index == sw_if_index)
+ {
+ /* 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 = nat44_ei_add_del_static_mapping (
+ l_addr, address[0], rp->l_port, rp->e_port, rp->proto,
+ ~0 /* sw_if_index */, rp->vrf_id, rp->addr_only,
+ rp->identity_nat, rp->tag, 1);
+ if (rv)
+ nat_elog_notice_X1 (
+ nm, "nat44_ei_add_del_static_mapping returned %d", "i4", rv);
+ }
+ }
+ return;
+ }
+ else
+ {
+ (void) nat44_ei_del_address (nm, address[0], 1);
+ return;
+ }
+}
+
+int
+nat44_ei_set_frame_queue_nelts (u32 frame_queue_nelts)
+{
+ fail_if_enabled ();
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nm->frame_queue_nelts = frame_queue_nelts;
+ return 0;
+}
+
+static void
+nat44_ei_ip4_add_del_addr_only_sm_cb (ip4_main_t *im, uword opaque,
+ u32 sw_if_index, ip4_address_t *address,
+ u32 address_length, u32 if_address_index,
+ u32 is_delete)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nat44_ei_static_map_resolve_t *rp;
+ nat44_ei_static_mapping_t *m;
+ clib_bihash_kv_8_8_t kv, value;
+ int i, rv;
+ ip4_address_t l_addr;
+
+ if (!nm->enabled)
+ return;
+
+ for (i = 0; i < vec_len (nm->to_resolve); i++)
+ {
+ rp = nm->to_resolve + i;
+ if (rp->addr_only == 0)
+ continue;
+ if (rp->sw_if_index == sw_if_index)
+ goto match;
+ }
+
+ return;
+
+match:
+ init_nat_k (&kv, *address, rp->addr_only ? 0 : rp->e_port,
+ nm->outside_fib_index, rp->addr_only ? 0 : rp->proto);
+ if (clib_bihash_search_8_8 (&nm->static_mapping_by_external, &kv, &value))
+ m = 0;
+ else
+ m = pool_elt_at_index (nm->static_mappings, value.value);
+
+ if (!is_delete)
+ {
+ /* Don't trip over lease renewal, static config */
+ if (m)
+ return;
+ }
+ else
+ {
+ if (!m)
+ return;
+ }
+
+ /* 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 = nat44_ei_add_del_static_mapping (
+ l_addr, address[0], rp->l_port, rp->e_port, rp->proto,
+ ~0 /* sw_if_index */, rp->vrf_id, rp->addr_only, rp->identity_nat, rp->tag,
+ !is_delete);
+ if (rv)
+ nat_elog_notice_X1 (nm, "nat44_ei_add_del_static_mapping returned %d",
+ "i4", rv);
+}
+
+VLIB_NODE_FN (nat44_ei_classify_node)
+(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;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nat44_ei_static_mapping_t *m;
+ u32 next_in2out = 0, next_out2in = 0;
+
+ from = vlib_frame_vector_args (frame);
+ n_left_from = frame->n_vectors;
+ next_index = node->cached_next_index;
+
+ while (n_left_from > 0)
+ {
+ u32 n_left_to_next;
+
+ vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
+
+ while (n_left_from > 0 && n_left_to_next > 0)
+ {
+ u32 bi0;
+ vlib_buffer_t *b0;
+ u32 next0 = NAT44_EI_CLASSIFY_NEXT_IN2OUT;
+ ip4_header_t *ip0;
+ nat44_ei_address_t *ap;
+ clib_bihash_kv_8_8_t kv0, value0;
+
+ /* speculatively enqueue b0 to the current next frame */
+ bi0 = from[0];
+ to_next[0] = bi0;
+ from += 1;
+ to_next += 1;
+ n_left_from -= 1;
+ n_left_to_next -= 1;
+
+ b0 = vlib_get_buffer (vm, bi0);
+ ip0 = vlib_buffer_get_current (b0);
+
+ vec_foreach (ap, nm->addresses)
+ {
+ if (ip0->dst_address.as_u32 == ap->addr.as_u32)
+ {
+ next0 = NAT44_EI_CLASSIFY_NEXT_OUT2IN;
+ goto enqueue0;
+ }
+ }
+
+ if (PREDICT_FALSE (pool_elts (nm->static_mappings)))
+ {
+ init_nat_k (&kv0, ip0->dst_address, 0, 0, 0);
+ /* try to classify the fragment based on IP header alone */
+ if (!clib_bihash_search_8_8 (&nm->static_mapping_by_external,
+ &kv0, &value0))
+ {
+ m = pool_elt_at_index (nm->static_mappings, value0.value);
+ if (m->local_addr.as_u32 != m->external_addr.as_u32)
+ next0 = NAT44_EI_CLASSIFY_NEXT_OUT2IN;
+ goto enqueue0;
+ }
+ init_nat_k (&kv0, ip0->dst_address,
+ vnet_buffer (b0)->ip.reass.l4_dst_port, 0,
+ ip_proto_to_nat_proto (ip0->protocol));
+ if (!clib_bihash_search_8_8 (&nm->static_mapping_by_external,
+ &kv0, &value0))
+ {
+ m = pool_elt_at_index (nm->static_mappings, value0.value);
+ if (m->local_addr.as_u32 != m->external_addr.as_u32)
+ next0 = NAT44_EI_CLASSIFY_NEXT_OUT2IN;
+ }
+ }
+
+ enqueue0:
+ if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) &&
+ (b0->flags & VLIB_BUFFER_IS_TRACED)))
+ {
+ nat44_ei_classify_trace_t *t =
+ vlib_add_trace (vm, node, b0, sizeof (*t));
+ t->cached = 0;
+ t->next_in2out = next0 == NAT44_EI_CLASSIFY_NEXT_IN2OUT ? 1 : 0;
+ }
+
+ next_in2out += next0 == NAT44_EI_CLASSIFY_NEXT_IN2OUT;
+ next_out2in += next0 == NAT44_EI_CLASSIFY_NEXT_OUT2IN;
+
+ /* verify speculative enqueue, maybe switch current next frame */
+ vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
+ n_left_to_next, bi0, next0);
+ }
+
+ vlib_put_next_frame (vm, node, next_index, n_left_to_next);
+ }
+
+ vlib_node_increment_counter (
+ vm, node->node_index, NAT44_EI_CLASSIFY_ERROR_NEXT_IN2OUT, next_in2out);
+ vlib_node_increment_counter (
+ vm, node->node_index, NAT44_EI_CLASSIFY_ERROR_NEXT_OUT2IN, next_out2in);
+ return frame->n_vectors;
+}
+
+VLIB_REGISTER_NODE (nat44_ei_classify_node) = {
+ .name = "nat44-ei-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",
+ [NAT44_EI_CLASSIFY_NEXT_OUT2IN] = "nat44-ei-out2in",
+ [NAT44_EI_CLASSIFY_NEXT_DROP] = "error-drop",
+ },
+};
+
/*
* fd.io coding-style-patch-verification: ON
*
diff --git a/src/plugins/nat/nat44-ei/nat44_ei.h b/src/plugins/nat/nat44-ei/nat44_ei.h
index 510e73de59a..b9212df44bd 100644
--- a/src/plugins/nat/nat44-ei/nat44_ei.h
+++ b/src/plugins/nat/nat44-ei/nat44_ei.h
@@ -19,6 +19,95 @@
#ifndef __included_nat44_ei_h__
#define __included_nat44_ei_h__
+#include <vlib/log.h>
+#include <vlibapi/api.h>
+
+#include <vnet/vnet.h>
+#include <vnet/ip/ip.h>
+#include <vnet/ethernet/ethernet.h>
+#include <vnet/ip/icmp46_packet.h>
+#include <vnet/api_errno.h>
+#include <vnet/fib/fib_source.h>
+
+#include <vppinfra/dlist.h>
+#include <vppinfra/error.h>
+#include <vppinfra/bihash_8_8.h>
+
+#include <nat/lib/lib.h>
+#include <nat/lib/inlines.h>
+
+/* default number of worker handoff frame queue elements */
+#define NAT_FQ_NELTS_DEFAULT 64
+
+/* External address and port allocation modes */
+#define foreach_nat44_ei_addr_and_port_alloc_alg \
+ _ (0, DEFAULT, "default") \
+ _ (1, MAPE, "map-e") \
+ _ (2, RANGE, "port-range")
+
+typedef enum
+{
+#define _(v, N, s) NAT44_EI_ADDR_AND_PORT_ALLOC_ALG_##N = v,
+ foreach_nat44_ei_addr_and_port_alloc_alg
+#undef _
+} nat44_ei_addr_and_port_alloc_alg_t;
+
+/* Interface flags */
+#define NAT44_EI_INTERFACE_FLAG_IS_INSIDE (1 << 0)
+#define NAT44_EI_INTERFACE_FLAG_IS_OUTSIDE (1 << 1)
+
+/* Session flags */
+#define NAT44_EI_SESSION_FLAG_STATIC_MAPPING (1 << 0)
+#define NAT44_EI_SESSION_FLAG_UNKNOWN_PROTO (1 << 1)
+
+/* Static mapping flags */
+#define NAT44_EI_STATIC_MAPPING_FLAG_ADDR_ONLY (1 << 0)
+#define NAT44_EI_STATIC_MAPPING_FLAG_IDENTITY_NAT (1 << 1)
+
+typedef struct
+{
+ ip4_address_t addr;
+ u32 fib_index;
+#define _(N, i, n, s) \
+ u32 busy_##n##_ports; \
+ u32 *busy_##n##_ports_per_thread; \
+ u32 busy_##n##_port_refcounts[65535];
+ foreach_nat_protocol
+#undef _
+} nat44_ei_address_t;
+
+clib_error_t *nat44_ei_api_hookup (vlib_main_t *vm);
+
+/* NAT address and port allocation function */
+typedef int (nat44_ei_alloc_out_addr_and_port_function_t) (
+ nat44_ei_address_t *addresses, u32 fib_index, u32 thread_index,
+ nat_protocol_t proto, ip4_address_t *addr, u16 *port, u16 port_per_thread,
+ u32 snat_thread_index);
+
+typedef struct
+{
+ u16 identifier;
+ u16 sequence;
+} icmp_echo_header_t;
+
+typedef struct
+{
+ u16 src_port, dst_port;
+} tcp_udp_header_t;
+
+typedef struct
+{
+ union
+ {
+ struct
+ {
+ ip4_address_t addr;
+ u32 fib_index;
+ };
+ u64 as_u64;
+ };
+} nat44_ei_user_key_t;
+
typedef struct
{
/* maximum number of users */
@@ -40,14 +129,370 @@ typedef struct
typedef struct
{
+ ip4_address_t l_addr;
+ ip4_address_t pool_addr;
+ u16 l_port;
+ u16 e_port;
+ u32 sw_if_index;
+ u32 vrf_id;
+ u32 flags;
+ nat_protocol_t proto;
+ u8 addr_only;
+ u8 identity_nat;
+ u8 exact;
+ u8 *tag;
+} nat44_ei_static_map_resolve_t;
+
+// TODO: cleanup/redo (there is no lb in EI nat)
+typedef struct
+{
+ /* backend IP address */
+ ip4_address_t addr;
+ /* backend port number */
+ u16 port;
+ /* probability of the backend to be randomly matched */
+ u8 probability;
+ u8 prefix;
+ /* backend FIB table */
+ u32 vrf_id;
+ u32 fib_index;
+} nat44_ei_lb_addr_port_t;
+
+typedef struct
+{
+ /* prefered pool address */
+ ip4_address_t pool_addr;
+ /* local IP address */
+ ip4_address_t local_addr;
+ /* external IP address */
+ ip4_address_t external_addr;
+ /* local port */
+ u16 local_port;
+ /* external port */
+ u16 external_port;
+ /* local FIB table */
+ u32 vrf_id;
+ u32 fib_index;
+ /* protocol */
+ nat_protocol_t proto;
+ /* worker threads used by backends/local host */
+ u32 *workers;
+ /* opaque string tag */
+ u8 *tag;
+ /* backends for load-balancing mode */
+ nat44_ei_lb_addr_port_t *locals;
+ /* flags */
+ u32 flags;
+} nat44_ei_static_mapping_t;
+
+typedef struct
+{
+ u32 sw_if_index;
+ u8 flags;
+} nat44_ei_interface_t;
+
+typedef struct
+{
+ u32 fib_index;
+ u32 ref_count;
+} nat44_ei_fib_t;
+
+typedef struct
+{
+ u32 fib_index;
+ u32 refcount;
+} nat44_ei_outside_fib_t;
+
+typedef CLIB_PACKED (struct {
+ /* Outside network tuple */
+ struct
+ {
+ ip4_address_t addr;
+ u32 fib_index;
+ u16 port;
+ } out2in;
+
+ /* Inside network tuple */
+ struct
+ {
+ ip4_address_t addr;
+ u32 fib_index;
+ u16 port;
+ } in2out;
+
+ nat_protocol_t nat_proto;
+
+ /* Flags */
+ u32 flags;
+
+ /* Per-user translations */
+ u32 per_user_index;
+ u32 per_user_list_head_index;
+
+ /* head of LRU list in which this session is tracked */
+ u32 lru_head_index;
+ /* index in global LRU list */
+ u32 lru_index;
+ f64 last_lru_update;
+
+ /* Last heard timer */
+ f64 last_heard;
+
+ /* Last HA refresh */
+ f64 ha_last_refreshed;
+
+ /* Counters */
+ u64 total_bytes;
+ u32 total_pkts;
+
+ /* External host address and port */
+ ip4_address_t ext_host_addr;
+ u16 ext_host_port;
+
+ /* External host address and port after translation */
+ ip4_address_t ext_host_nat_addr;
+ u16 ext_host_nat_port;
+
+ /* TCP session state */
+ u8 state;
+ u32 i2o_fin_seq;
+ u32 o2i_fin_seq;
+ u64 tcp_closed_timestamp;
+
+ /* user index */
+ u32 user_index;
+}) nat44_ei_session_t;
+
+typedef CLIB_PACKED (struct {
+ ip4_address_t addr;
+ u32 fib_index;
+ u32 sessions_per_user_list_head_index;
+ u32 nsessions;
+ u32 nstaticsessions;
+}) nat44_ei_user_t;
+
+typedef struct
+{
+ /* Find-a-user => src address lookup */
+ clib_bihash_8_8_t user_hash;
+
+ /* User pool */
+ nat44_ei_user_t *users;
+
+ /* Session pool */
+ nat44_ei_session_t *sessions;
+
+ /* Pool of doubly-linked list elements */
+ dlist_elt_t *list_pool;
+
+ /* LRU session list - head is stale, tail is fresh */
+ dlist_elt_t *lru_pool;
+ u32 tcp_trans_lru_head_index;
+ u32 tcp_estab_lru_head_index;
+ u32 udp_lru_head_index;
+ u32 icmp_lru_head_index;
+ u32 unk_proto_lru_head_index;
+
+ /* NAT thread index */
+ u32 snat_thread_index;
+
+ /* real thread index */
+ u32 thread_index;
+
+} nat44_ei_main_per_thread_data_t;
+
+/* Return worker thread index for given packet */
+typedef u32 (nat44_ei_get_worker_in2out_function_t) (ip4_header_t *ip,
+ u32 rx_fib_index,
+ u8 is_output);
+
+typedef u32 (nat44_ei_get_worker_out2in_function_t) (vlib_buffer_t *b,
+ ip4_header_t *ip,
+ u32 rx_fib_index,
+ u8 is_output);
+
+typedef struct
+{
+ u32 cached_sw_if_index;
+ u32 cached_ip4_address;
+} nat44_ei_runtime_t;
+
+typedef struct
+{
+ u32 thread_index;
+ f64 now;
+} nat44_ei_is_idle_session_ctx_t;
+
+typedef struct nat44_ei_main_s
+{
u32 translations;
u32 translation_buckets;
u32 user_buckets;
+ u8 out2in_dpo;
+ u8 forwarding_enabled;
+ u8 static_mapping_only;
+ u8 static_mapping_connection_tracking;
+
+ u16 mss_clamping;
+
+ /* Find a static mapping by local */
+ clib_bihash_8_8_t static_mapping_by_local;
+
+ /* Find a static mapping by external */
+ clib_bihash_8_8_t static_mapping_by_external;
+
+ /* Static mapping pool */
+ nat44_ei_static_mapping_t *static_mappings;
+
+ /* Interface pool */
+ nat44_ei_interface_t *interfaces;
+ nat44_ei_interface_t *output_feature_interfaces;
+
+ /* Is translation memory size calculated or user defined */
+ u8 translation_memory_size_set;
+
+ u32 max_users_per_thread;
+ u32 max_translations_per_thread;
+ u32 max_translations_per_user;
+
+ u32 inside_vrf_id;
+ u32 inside_fib_index;
+
+ u32 outside_vrf_id;
+ u32 outside_fib_index;
+
+ /* Thread settings */
+ u32 num_workers;
+ u32 first_worker_index;
+ u32 *workers;
+ nat44_ei_get_worker_in2out_function_t *worker_in2out_cb;
+ nat44_ei_get_worker_out2in_function_t *worker_out2in_cb;
+ u16 port_per_thread;
+
+ /* Main lookup tables */
+ clib_bihash_8_8_t out2in;
+ clib_bihash_8_8_t in2out;
+
+ /* Per thread data */
+ nat44_ei_main_per_thread_data_t *per_thread_data;
+
+ /* Vector of outside addresses */
+ nat44_ei_address_t *addresses;
+
+ nat44_ei_alloc_out_addr_and_port_function_t *alloc_addr_and_port;
+ /* Address and port allocation type */
+ nat44_ei_addr_and_port_alloc_alg_t addr_and_port_alloc_alg;
+ /* Port set parameters (MAP-E) */
+ u8 psid_offset;
+ u8 psid_length;
+ u16 psid;
+ /* Port range parameters */
+ u16 start_port;
+ u16 end_port;
+
+ /* vector of fibs */
+ nat44_ei_fib_t *fibs;
+
+ /* vector of outside fibs */
+ nat44_ei_outside_fib_t *outside_fibs;
+
+ /* sw_if_indices whose intfc addresses should be auto-added */
+ u32 *auto_add_sw_if_indices;
+
+ /* vector of interface address static mappings to resolve. */
+ nat44_ei_static_map_resolve_t *to_resolve;
+
+ u32 in2out_node_index;
+ u32 out2in_node_index;
+ u32 in2out_output_node_index;
+
+ u32 fq_in2out_index;
+ u32 fq_in2out_output_index;
+ u32 fq_out2in_index;
+
+ /* Randomize port allocation order */
+ u32 random_seed;
+
+ nat_timeouts_t timeouts;
+
+ /* counters */
+ vlib_simple_counter_main_t total_users;
+ vlib_simple_counter_main_t total_sessions;
+ vlib_simple_counter_main_t user_limit_reached;
+
+#define _(x) vlib_simple_counter_main_t x;
+ struct
+ {
+ struct
+ {
+ struct
+ {
+ foreach_nat_counter;
+ } in2out;
+
+ struct
+ {
+ foreach_nat_counter;
+ } out2in;
+
+ } fastpath;
+
+ struct
+ {
+ struct
+ {
+ foreach_nat_counter;
+ } in2out;
+
+ struct
+ {
+ foreach_nat_counter;
+ } out2in;
+ } slowpath;
+
+ vlib_simple_counter_main_t hairpinning;
+ } counters;
+#undef _
+
+ /* API message ID base */
+ u16 msg_id_base;
+
+ /* log class */
+ vlib_log_class_t log_class;
+ /* logging level */
+ u8 log_level;
+
+ /* convenience */
+ api_main_t *api_main;
+ ip4_main_t *ip4_main;
+ ip_lookup_main_t *ip4_lookup_main;
+
+ fib_source_t fib_src_hi;
+ fib_source_t fib_src_low;
+
+ /* pat (port address translation)
+ * dynamic mapping enabled or conneciton tracking */
+ u8 pat;
+
+ /* number of worker handoff frame queue elements */
+ u32 frame_queue_nelts;
+
+ /* nat44 plugin enabled */
+ u8 enabled;
+
nat44_ei_config_t rconfig;
+ u32 in2out_hairpinning_finish_ip4_lookup_node_fq_index;
+ u32 in2out_hairpinning_finish_interface_output_node_fq_index;
+ u32 hairpinning_fq_index;
+ u32 hairpin_dst_fq_index;
+
+ vnet_main_t *vnet_main;
} nat44_ei_main_t;
+extern nat44_ei_main_t nat44_ei_main;
+
int nat44_ei_plugin_enable (nat44_ei_config_t c);
int nat44_ei_plugin_disable ();
@@ -66,11 +511,9 @@ int nat44_ei_user_del (ip4_address_t *addr, u32 fib_index);
* @param addr IPv4 address
* @param fib_index FIB table index
*/
-void nat44_ei_static_mapping_del_sessions (snat_main_t *sm,
- snat_main_per_thread_data_t *tsm,
- snat_user_key_t u_key,
- int addr_only, ip4_address_t e_addr,
- u16 e_port);
+void nat44_ei_static_mapping_del_sessions (
+ nat44_ei_main_t *nm, nat44_ei_main_per_thread_data_t *tnm,
+ nat44_ei_user_key_t u_key, int addr_only, ip4_address_t e_addr, u16 e_port);
u32 nat44_ei_get_in2out_worker_index (ip4_header_t *ip0, u32 rx_fib_index0,
u8 is_output);
@@ -135,7 +578,7 @@ int nat44_ei_add_del_static_mapping (ip4_address_t l_addr,
*
* @return 0 on success, non-zero value otherwise
*/
-int nat44_ei_del_session (snat_main_t *sm, ip4_address_t *addr, u16 port,
+int nat44_ei_del_session (nat44_ei_main_t *nm, ip4_address_t *addr, u16 port,
nat_protocol_t proto, u32 vrf_id, int is_in);
/**
@@ -165,6 +608,100 @@ int nat44_ei_static_mapping_match (ip4_address_t match_addr, u16 match_port,
*/
void nat44_ei_sessions_clear ();
+nat44_ei_user_t *nat44_ei_user_get_or_create (nat44_ei_main_t *nm,
+ ip4_address_t *addr,
+ u32 fib_index, u32 thread_index);
+
+nat44_ei_session_t *nat44_ei_session_alloc_or_recycle (nat44_ei_main_t *nm,
+ nat44_ei_user_t *u,
+ u32 thread_index,
+ f64 now);
+
+void nat44_ei_free_session_data_v2 (nat44_ei_main_t *nm, nat44_ei_session_t *s,
+ u32 thread_index, u8 is_ha);
+
+void nat44_ei_free_outside_address_and_port (nat44_ei_address_t *addresses,
+ u32 thread_index,
+ ip4_address_t *addr, u16 port,
+ nat_protocol_t protocol);
+
+int nat44_ei_set_outside_address_and_port (nat44_ei_address_t *addresses,
+ u32 thread_index,
+ ip4_address_t addr, u16 port,
+ nat_protocol_t protocol);
+
+int nat44_ei_del_address (nat44_ei_main_t *nm, ip4_address_t addr,
+ u8 delete_sm);
+
+void nat44_ei_free_session_data (nat44_ei_main_t *nm, nat44_ei_session_t *s,
+ u32 thread_index, u8 is_ha);
+
+int nat44_ei_set_workers (uword *bitmap);
+
+void nat44_ei_add_del_address_dpo (ip4_address_t addr, u8 is_add);
+
+int nat44_ei_add_address (nat44_ei_main_t *nm, ip4_address_t *addr,
+ u32 vrf_id);
+
+void nat44_ei_delete_session (nat44_ei_main_t *nm, nat44_ei_session_t *ses,
+ u32 thread_index);
+
+int nat44_ei_interface_add_del (u32 sw_if_index, u8 is_inside, int is_del);
+
+int nat44_ei_interface_add_del_output_feature (u32 sw_if_index, u8 is_inside,
+ int is_del);
+
+int nat44_ei_add_interface_address (nat44_ei_main_t *nm, u32 sw_if_index,
+ int is_del);
+
+/* Call back functions for clib_bihash_add_or_overwrite_stale */
+int nat44_i2o_is_idle_session_cb (clib_bihash_kv_8_8_t *kv, void *arg);
+int nat44_o2i_is_idle_session_cb (clib_bihash_kv_8_8_t *kv, void *arg);
+
+int nat44_ei_hairpinning (vlib_main_t *vm, vlib_node_runtime_t *node,
+ nat44_ei_main_t *nm, u32 thread_index,
+ vlib_buffer_t *b0, ip4_header_t *ip0,
+ udp_header_t *udp0, tcp_header_t *tcp0, u32 proto0,
+ int do_trace, u32 *required_thread_index);
+
+void nat44_ei_hairpinning_sm_unknown_proto (nat44_ei_main_t *nm,
+ vlib_buffer_t *b,
+ ip4_header_t *ip);
+
+u32 nat44_ei_icmp_hairpinning (nat44_ei_main_t *nm, vlib_buffer_t *b0,
+ u32 thread_index, ip4_header_t *ip0,
+ icmp46_header_t *icmp0,
+ u32 *required_thread_index);
+
+int nat44_ei_set_frame_queue_nelts (u32 frame_queue_nelts);
+
+#define nat44_ei_is_session_static(sp) \
+ (sp->flags & NAT44_EI_SESSION_FLAG_STATIC_MAPPING)
+#define nat44_ei_is_unk_proto_session(sp) \
+ (sp->flags & NAT44_EI_SESSION_FLAG_UNKNOWN_PROTO)
+
+#define nat44_ei_interface_is_inside(ip) \
+ (ip->flags & NAT44_EI_INTERFACE_FLAG_IS_INSIDE)
+#define nat44_ei_interface_is_outside(ip) \
+ (ip->flags & NAT44_EI_INTERFACE_FLAG_IS_OUTSIDE)
+
+#define nat44_ei_is_addr_only_static_mapping(mp) \
+ (mp->flags & NAT44_EI_STATIC_MAPPING_FLAG_ADDR_ONLY)
+#define nat44_ei_is_identity_static_mapping(mp) \
+ (mp->flags & NAT44_EI_STATIC_MAPPING_FLAG_IDENTITY_NAT)
+
+/* logging */
+#define nat44_ei_log_err(...) \
+ vlib_log (VLIB_LOG_LEVEL_ERR, nat44_ei_main.log_class, __VA_ARGS__)
+#define nat44_ei_log_warn(...) \
+ vlib_log (VLIB_LOG_LEVEL_WARNING, nat44_ei_main.log_class, __VA_ARGS__)
+#define nat44_ei_log_notice(...) \
+ vlib_log (VLIB_LOG_LEVEL_NOTICE, nat44_ei_main.log_class, __VA_ARGS__)
+#define nat44_ei_log_info(...) \
+ vlib_log (VLIB_LOG_LEVEL_INFO, nat44_ei_main.log_class, __VA_ARGS__)
+#define nat44_ei_log_debug(...) \
+ vlib_log (VLIB_LOG_LEVEL_DEBUG, nat44_ei_main.log_class, __VA_ARGS__)
+
#endif /* __included_nat44_ei_h__ */
/*
* fd.io coding-style-patch-verification: ON
diff --git a/src/plugins/nat/nat44-ei/nat44_ei_api.c b/src/plugins/nat/nat44-ei/nat44_ei_api.c
new file mode 100644
index 00000000000..74e077485cc
--- /dev/null
+++ b/src/plugins/nat/nat44-ei/nat44_ei_api.c
@@ -0,0 +1,1199 @@
+/*
+ * Copyright (c) 2020 Cisco and/or its affiliates.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <vnet/ip/ip_types_api.h>
+#include <vlibmemory/api.h>
+
+#include <vnet/fib/fib_table.h>
+
+#include <nat/lib/nat_inlines.h>
+#include <nat/lib/ipfix_logging.h>
+
+#include <nat/nat44-ei/nat44_ei.api_enum.h>
+#include <nat/nat44-ei/nat44_ei.api_types.h>
+
+#include <nat/nat44-ei/nat44_ei_ha.h>
+#include <nat/nat44-ei/nat44_ei.h>
+
+#define REPLY_MSG_ID_BASE nm->msg_id_base
+#include <vlibapi/api_helper_macros.h>
+
+static void
+vl_api_nat44_ei_show_running_config_t_handler (
+ vl_api_nat44_ei_show_running_config_t *mp)
+{
+ vl_api_nat44_ei_show_running_config_reply_t *rmp;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nat44_ei_config_t *rc = &nm->rconfig;
+ int rv = 0;
+
+ REPLY_MACRO2_ZERO (
+ VL_API_NAT44_EI_SHOW_RUNNING_CONFIG_REPLY, ({
+ rmp->inside_vrf = htonl (rc->inside_vrf);
+ rmp->outside_vrf = htonl (rc->outside_vrf);
+ rmp->users = htonl (rc->users);
+ rmp->sessions = htonl (rc->sessions);
+ rmp->user_sessions = htonl (rc->user_sessions);
+
+ rmp->user_buckets = htonl (nm->user_buckets);
+ rmp->translation_buckets = htonl (nm->translation_buckets);
+
+ rmp->timeouts.udp = htonl (nm->timeouts.udp);
+ rmp->timeouts.tcp_established = htonl (nm->timeouts.tcp.established);
+ rmp->timeouts.tcp_transitory = htonl (nm->timeouts.tcp.transitory);
+ rmp->timeouts.icmp = htonl (nm->timeouts.icmp);
+
+ rmp->forwarding_enabled = nm->forwarding_enabled == 1;
+ // consider how to split functionality between subplugins
+ rmp->ipfix_logging_enabled = nat_ipfix_logging_enabled ();
+
+ if (rc->static_mapping_only)
+ rmp->flags |= NAT44_EI_STATIC_MAPPING_ONLY;
+ if (rc->connection_tracking)
+ rmp->flags |= NAT44_EI_CONNECTION_TRACKING;
+ if (rc->out2in_dpo)
+ rmp->flags |= NAT44_EI_OUT2IN_DPO;
+ }));
+}
+
+static void
+vl_api_nat44_ei_set_workers_t_handler (vl_api_nat44_ei_set_workers_t *mp)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ vl_api_nat44_ei_set_workers_reply_t *rmp;
+ int rv = 0;
+ uword *bitmap = 0;
+ u64 mask;
+
+ mask = clib_net_to_host_u64 (mp->worker_mask);
+
+ if (nm->num_workers < 2)
+ {
+ rv = VNET_API_ERROR_FEATURE_DISABLED;
+ goto send_reply;
+ }
+
+ bitmap = clib_bitmap_set_multiple (bitmap, 0, mask, BITS (mask));
+ rv = nat44_ei_set_workers (bitmap);
+ clib_bitmap_free (bitmap);
+
+send_reply:
+ REPLY_MACRO (VL_API_NAT44_EI_SET_WORKERS_REPLY);
+}
+
+static void
+send_nat_worker_details (u32 worker_index, vl_api_registration_t *reg,
+ u32 context)
+{
+ vl_api_nat44_ei_worker_details_t *rmp;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ vlib_worker_thread_t *w =
+ vlib_worker_threads + worker_index + nm->first_worker_index;
+
+ rmp = vl_msg_api_alloc (sizeof (*rmp));
+ clib_memset (rmp, 0, sizeof (*rmp));
+ rmp->_vl_msg_id = ntohs (VL_API_NAT44_EI_WORKER_DETAILS + nm->msg_id_base);
+ rmp->context = context;
+ rmp->worker_index = htonl (worker_index);
+ rmp->lcore_id = htonl (w->cpu_id);
+ strncpy ((char *) rmp->name, (char *) w->name, ARRAY_LEN (rmp->name) - 1);
+
+ vl_api_send_msg (reg, (u8 *) rmp);
+}
+
+static void
+vl_api_nat44_ei_worker_dump_t_handler (vl_api_nat44_ei_worker_dump_t *mp)
+{
+ vl_api_registration_t *reg;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ u32 *worker_index;
+
+ reg = vl_api_client_index_to_registration (mp->client_index);
+ if (!reg)
+ return;
+
+ vec_foreach (worker_index, nm->workers)
+ {
+ send_nat_worker_details (*worker_index, reg, mp->context);
+ }
+}
+
+static void
+vl_api_nat44_ei_set_log_level_t_handler (vl_api_nat44_ei_set_log_level_t *mp)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ vl_api_nat44_ei_set_log_level_reply_t *rmp;
+ int rv = 0;
+
+ if (nm->log_level > NAT_LOG_DEBUG)
+ rv = VNET_API_ERROR_UNSUPPORTED;
+ else
+ nm->log_level = mp->log_level;
+
+ REPLY_MACRO (VL_API_NAT44_EI_SET_LOG_LEVEL_REPLY);
+}
+
+static void
+vl_api_nat44_ei_plugin_enable_disable_t_handler (
+ vl_api_nat44_ei_plugin_enable_disable_t *mp)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nat44_ei_config_t c = { 0 };
+ vl_api_nat44_ei_plugin_enable_disable_reply_t *rmp;
+ int rv = 0;
+
+ if (mp->enable)
+ {
+ c.static_mapping_only = mp->flags & NAT44_EI_STATIC_MAPPING_ONLY;
+ c.connection_tracking = mp->flags & NAT44_EI_CONNECTION_TRACKING;
+ c.out2in_dpo = mp->flags & NAT44_EI_OUT2IN_DPO;
+
+ c.inside_vrf = ntohl (mp->inside_vrf);
+ c.outside_vrf = ntohl (mp->outside_vrf);
+
+ c.users = ntohl (mp->users);
+
+ c.sessions = ntohl (mp->sessions);
+
+ c.user_sessions = ntohl (mp->user_sessions);
+
+ rv = nat44_ei_plugin_enable (c);
+ }
+ else
+ rv = nat44_ei_plugin_disable ();
+
+ REPLY_MACRO (VL_API_NAT44_EI_PLUGIN_ENABLE_DISABLE_REPLY);
+}
+
+static void
+vl_api_nat44_ei_ipfix_enable_disable_t_handler (
+ vl_api_nat44_ei_ipfix_enable_disable_t *mp)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ vl_api_nat44_ei_ipfix_enable_disable_reply_t *rmp;
+ int rv = 0;
+
+ rv = nat_ipfix_logging_enable_disable (mp->enable,
+ clib_host_to_net_u32 (mp->domain_id),
+ clib_host_to_net_u16 (mp->src_port));
+
+ REPLY_MACRO (VL_API_NAT44_EI_IPFIX_ENABLE_DISABLE_REPLY);
+}
+
+static void
+vl_api_nat44_ei_set_timeouts_t_handler (vl_api_nat44_ei_set_timeouts_t *mp)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ vl_api_nat44_ei_set_timeouts_reply_t *rmp;
+ int rv = 0;
+
+ nm->timeouts.udp = ntohl (mp->udp);
+ nm->timeouts.tcp.established = ntohl (mp->tcp_established);
+ nm->timeouts.tcp.transitory = ntohl (mp->tcp_transitory);
+ nm->timeouts.icmp = ntohl (mp->icmp);
+
+ REPLY_MACRO (VL_API_NAT44_EI_SET_TIMEOUTS_REPLY);
+}
+
+static void
+vl_api_nat44_ei_set_addr_and_port_alloc_alg_t_handler (
+ vl_api_nat44_ei_set_addr_and_port_alloc_alg_t *mp)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ vl_api_nat44_ei_set_addr_and_port_alloc_alg_reply_t *rmp;
+ int rv = 0;
+ u16 port_start, port_end;
+
+ switch (mp->alg)
+ {
+ case NAT44_EI_ADDR_AND_PORT_ALLOC_ALG_DEFAULT:
+ nat44_ei_set_alloc_default ();
+ break;
+ case NAT44_EI_ADDR_AND_PORT_ALLOC_ALG_MAPE:
+ nat44_ei_set_alloc_mape (ntohs (mp->psid), mp->psid_offset,
+ mp->psid_length);
+ break;
+ case NAT44_EI_ADDR_AND_PORT_ALLOC_ALG_RANGE:
+ port_start = ntohs (mp->start_port);
+ port_end = ntohs (mp->end_port);
+ if (port_end <= port_start)
+ {
+ rv = VNET_API_ERROR_INVALID_VALUE;
+ goto send_reply;
+ }
+ nat44_ei_set_alloc_range (port_start, port_end);
+ break;
+ default:
+ rv = VNET_API_ERROR_INVALID_VALUE;
+ break;
+ }
+
+send_reply:
+ REPLY_MACRO (VL_API_NAT44_EI_SET_ADDR_AND_PORT_ALLOC_ALG_REPLY);
+}
+
+static void
+vl_api_nat44_ei_get_addr_and_port_alloc_alg_t_handler (
+ vl_api_nat44_ei_get_addr_and_port_alloc_alg_t *mp)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ vl_api_nat44_ei_get_addr_and_port_alloc_alg_reply_t *rmp;
+ int rv = 0;
+
+ REPLY_MACRO2 (VL_API_NAT44_EI_GET_ADDR_AND_PORT_ALLOC_ALG_REPLY, ({
+ rmp->alg = nm->addr_and_port_alloc_alg;
+ rmp->psid_offset = nm->psid_offset;
+ rmp->psid_length = nm->psid_length;
+ rmp->psid = htons (nm->psid);
+ rmp->start_port = htons (nm->start_port);
+ rmp->end_port = htons (nm->end_port);
+ }))
+}
+
+static void
+vl_api_nat44_ei_set_mss_clamping_t_handler (
+ vl_api_nat44_ei_set_mss_clamping_t *mp)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ vl_api_nat44_ei_set_mss_clamping_reply_t *rmp;
+ int rv = 0;
+
+ if (mp->enable)
+ nm->mss_clamping = ntohs (mp->mss_value);
+ else
+ nm->mss_clamping = 0;
+
+ REPLY_MACRO (VL_API_NAT44_EI_SET_MSS_CLAMPING_REPLY);
+}
+
+static void
+vl_api_nat44_ei_get_mss_clamping_t_handler (
+ vl_api_nat44_ei_get_mss_clamping_t *mp)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ vl_api_nat44_ei_get_mss_clamping_reply_t *rmp;
+ int rv = 0;
+
+ REPLY_MACRO2 (VL_API_NAT44_EI_GET_MSS_CLAMPING_REPLY, ({
+ rmp->enable = nm->mss_clamping ? 1 : 0;
+ rmp->mss_value = htons (nm->mss_clamping);
+ }))
+}
+
+static void
+vl_api_nat44_ei_ha_set_listener_t_handler (
+ vl_api_nat44_ei_ha_set_listener_t *mp)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ vl_api_nat44_ei_ha_set_listener_reply_t *rmp;
+ ip4_address_t addr;
+ int rv;
+
+ memcpy (&addr, &mp->ip_address, sizeof (addr));
+ rv = nat_ha_set_listener (&addr, clib_net_to_host_u16 (mp->port),
+ clib_net_to_host_u32 (mp->path_mtu));
+
+ REPLY_MACRO (VL_API_NAT44_EI_HA_SET_LISTENER_REPLY);
+}
+
+static void
+vl_api_nat44_ei_ha_get_listener_t_handler (
+ vl_api_nat44_ei_ha_get_listener_t *mp)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ vl_api_nat44_ei_ha_get_listener_reply_t *rmp;
+ int rv = 0;
+ ip4_address_t addr;
+ u16 port;
+ u32 path_mtu;
+
+ nat_ha_get_listener (&addr, &port, &path_mtu);
+
+ REPLY_MACRO2 (VL_API_NAT44_EI_HA_GET_LISTENER_REPLY, ({
+ clib_memcpy (rmp->ip_address, &addr, sizeof (ip4_address_t));
+ rmp->port = clib_host_to_net_u16 (port);
+ rmp->path_mtu = clib_host_to_net_u32 (path_mtu);
+ }))
+}
+
+static void
+vl_api_nat44_ei_ha_set_failover_t_handler (
+ vl_api_nat44_ei_ha_set_failover_t *mp)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ vl_api_nat44_ei_ha_set_failover_reply_t *rmp;
+ ip4_address_t addr;
+ int rv;
+
+ memcpy (&addr, &mp->ip_address, sizeof (addr));
+ rv =
+ nat_ha_set_failover (&addr, clib_net_to_host_u16 (mp->port),
+ clib_net_to_host_u32 (mp->session_refresh_interval));
+
+ REPLY_MACRO (VL_API_NAT44_EI_HA_SET_FAILOVER_REPLY);
+}
+
+static void
+vl_api_nat44_ei_ha_get_failover_t_handler (
+ vl_api_nat44_ei_ha_get_failover_t *mp)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ vl_api_nat44_ei_ha_get_failover_reply_t *rmp;
+ int rv = 0;
+ ip4_address_t addr;
+ u16 port;
+ u32 session_refresh_interval;
+
+ nat_ha_get_failover (&addr, &port, &session_refresh_interval);
+
+ REPLY_MACRO2 (VL_API_NAT44_EI_HA_GET_FAILOVER_REPLY, ({
+ clib_memcpy (rmp->ip_address, &addr, sizeof (ip4_address_t));
+ rmp->port = clib_host_to_net_u16 (port);
+ rmp->session_refresh_interval =
+ clib_host_to_net_u32 (session_refresh_interval);
+ }))
+}
+
+static void
+vl_api_nat44_ei_ha_flush_t_handler (vl_api_nat44_ei_ha_flush_t *mp)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ vl_api_nat44_ei_ha_flush_reply_t *rmp;
+ int rv = 0;
+
+ nat_ha_flush (0);
+
+ REPLY_MACRO (VL_API_NAT44_EI_HA_FLUSH_REPLY);
+}
+
+static void
+nat_ha_resync_completed_event_cb (u32 client_index, u32 pid, u32 missed_count)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ vl_api_registration_t *reg;
+ vl_api_nat44_ei_ha_resync_completed_event_t *mp;
+
+ reg = vl_api_client_index_to_registration (client_index);
+ if (!reg)
+ return;
+
+ mp = vl_msg_api_alloc (sizeof (*mp));
+ clib_memset (mp, 0, sizeof (*mp));
+ mp->client_index = client_index;
+ mp->pid = pid;
+ mp->missed_count = clib_host_to_net_u32 (missed_count);
+ mp->_vl_msg_id =
+ ntohs (VL_API_NAT44_EI_HA_RESYNC_COMPLETED_EVENT + nm->msg_id_base);
+
+ vl_api_send_msg (reg, (u8 *) mp);
+}
+
+static void
+vl_api_nat44_ei_ha_resync_t_handler (vl_api_nat44_ei_ha_resync_t *mp)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ vl_api_nat44_ei_ha_resync_reply_t *rmp;
+ int rv;
+
+ rv = nat_ha_resync (
+ mp->client_index, mp->pid,
+ mp->want_resync_event ? nat_ha_resync_completed_event_cb : NULL);
+
+ REPLY_MACRO (VL_API_NAT44_EI_HA_RESYNC_REPLY);
+}
+
+static void
+vl_api_nat44_ei_del_user_t_handler (vl_api_nat44_ei_del_user_t *mp)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ vl_api_nat44_ei_del_user_reply_t *rmp;
+ ip4_address_t addr;
+ int rv;
+ memcpy (&addr.as_u8, mp->ip_address, 4);
+ rv = nat44_ei_user_del (&addr, ntohl (mp->fib_index));
+ REPLY_MACRO (VL_API_NAT44_EI_DEL_USER_REPLY);
+}
+
+static void
+vl_api_nat44_ei_add_del_address_range_t_handler (
+ vl_api_nat44_ei_add_del_address_range_t *mp)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ vl_api_nat44_ei_add_del_address_range_reply_t *rmp;
+ ip4_address_t this_addr;
+ u8 is_add;
+ u32 start_host_order, end_host_order;
+ u32 vrf_id;
+ int i, count;
+ int rv = 0;
+ u32 *tmp;
+
+ if (nm->static_mapping_only)
+ {
+ rv = VNET_API_ERROR_FEATURE_DISABLED;
+ goto send_reply;
+ }
+
+ is_add = mp->is_add;
+
+ tmp = (u32 *) mp->first_ip_address;
+ start_host_order = clib_host_to_net_u32 (tmp[0]);
+ tmp = (u32 *) mp->last_ip_address;
+ end_host_order = clib_host_to_net_u32 (tmp[0]);
+
+ count = (end_host_order - start_host_order) + 1;
+
+ vrf_id = clib_host_to_net_u32 (mp->vrf_id);
+
+ if (count > 1024)
+ nat44_ei_log_info ("%U - %U, %d addresses...", format_ip4_address,
+ mp->first_ip_address, format_ip4_address,
+ mp->last_ip_address, count);
+
+ memcpy (&this_addr.as_u8, mp->first_ip_address, 4);
+
+ for (i = 0; i < count; i++)
+ {
+ if (is_add)
+ rv = nat44_ei_add_address (nm, &this_addr, vrf_id);
+ else
+ rv = nat44_ei_del_address (nm, this_addr, 0);
+
+ if (rv)
+ goto send_reply;
+
+ if (nm->out2in_dpo)
+ nat44_ei_add_del_address_dpo (this_addr, is_add);
+
+ increment_v4_address (&this_addr);
+ }
+
+send_reply:
+ REPLY_MACRO (VL_API_NAT44_EI_ADD_DEL_ADDRESS_RANGE_REPLY);
+}
+
+static void
+send_nat44_ei_address_details (nat44_ei_address_t *a,
+ vl_api_registration_t *reg, u32 context)
+{
+ vl_api_nat44_ei_address_details_t *rmp;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+
+ rmp = vl_msg_api_alloc (sizeof (*rmp));
+ clib_memset (rmp, 0, sizeof (*rmp));
+ rmp->_vl_msg_id = ntohs (VL_API_NAT44_EI_ADDRESS_DETAILS + nm->msg_id_base);
+ clib_memcpy (rmp->ip_address, &(a->addr), 4);
+ if (a->fib_index != ~0)
+ {
+ fib_table_t *fib = fib_table_get (a->fib_index, FIB_PROTOCOL_IP4);
+ rmp->vrf_id = ntohl (fib->ft_table_id);
+ }
+ else
+ rmp->vrf_id = ~0;
+ rmp->context = context;
+
+ vl_api_send_msg (reg, (u8 *) rmp);
+}
+
+static void
+vl_api_nat44_ei_address_dump_t_handler (vl_api_nat44_ei_address_dump_t *mp)
+{
+ vl_api_registration_t *reg;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nat44_ei_address_t *a;
+
+ reg = vl_api_client_index_to_registration (mp->client_index);
+ if (!reg)
+ return;
+
+ vec_foreach (a, nm->addresses)
+ {
+ send_nat44_ei_address_details (a, reg, mp->context);
+ }
+}
+
+static void
+vl_api_nat44_ei_interface_add_del_feature_t_handler (
+ vl_api_nat44_ei_interface_add_del_feature_t *mp)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ vl_api_nat44_ei_interface_add_del_feature_reply_t *rmp;
+ u32 sw_if_index = ntohl (mp->sw_if_index);
+ u8 is_del;
+ int rv = 0;
+
+ is_del = !mp->is_add;
+
+ VALIDATE_SW_IF_INDEX (mp);
+
+ rv = nat44_ei_interface_add_del (sw_if_index, mp->flags & NAT44_EI_IF_INSIDE,
+ is_del);
+
+ BAD_SW_IF_INDEX_LABEL;
+
+ REPLY_MACRO (VL_API_NAT44_EI_INTERFACE_ADD_DEL_FEATURE_REPLY);
+}
+
+static void
+send_nat44_ei_interface_details (nat44_ei_interface_t *i,
+ vl_api_registration_t *reg, u32 context)
+{
+ vl_api_nat44_ei_interface_details_t *rmp;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+
+ rmp = vl_msg_api_alloc (sizeof (*rmp));
+ clib_memset (rmp, 0, sizeof (*rmp));
+ rmp->_vl_msg_id =
+ ntohs (VL_API_NAT44_EI_INTERFACE_DETAILS + nm->msg_id_base);
+ rmp->sw_if_index = ntohl (i->sw_if_index);
+
+ if (nat44_ei_interface_is_inside (i))
+ rmp->flags |= NAT44_EI_IF_INSIDE;
+ if (nat44_ei_interface_is_outside (i))
+ rmp->flags |= NAT44_EI_IF_OUTSIDE;
+
+ rmp->context = context;
+
+ vl_api_send_msg (reg, (u8 *) rmp);
+}
+
+static void
+vl_api_nat44_ei_interface_dump_t_handler (vl_api_nat44_ei_interface_dump_t *mp)
+{
+ vl_api_registration_t *reg;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nat44_ei_interface_t *i;
+
+ reg = vl_api_client_index_to_registration (mp->client_index);
+ if (!reg)
+ return;
+
+ pool_foreach (i, nm->interfaces)
+ {
+ send_nat44_ei_interface_details (i, reg, mp->context);
+ }
+}
+
+static void
+vl_api_nat44_ei_interface_add_del_output_feature_t_handler (
+ vl_api_nat44_ei_interface_add_del_output_feature_t *mp)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ vl_api_nat44_ei_interface_add_del_output_feature_reply_t *rmp;
+ u32 sw_if_index = ntohl (mp->sw_if_index);
+ int rv = 0;
+
+ VALIDATE_SW_IF_INDEX (mp);
+
+ rv = nat44_ei_interface_add_del_output_feature (
+ sw_if_index, mp->flags & NAT44_EI_IF_INSIDE, !mp->is_add);
+
+ BAD_SW_IF_INDEX_LABEL;
+ REPLY_MACRO (VL_API_NAT44_EI_INTERFACE_ADD_DEL_OUTPUT_FEATURE_REPLY);
+}
+
+static void
+send_nat44_ei_interface_output_feature_details (nat44_ei_interface_t *i,
+ vl_api_registration_t *reg,
+ u32 context)
+{
+ vl_api_nat44_ei_interface_output_feature_details_t *rmp;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+
+ rmp = vl_msg_api_alloc (sizeof (*rmp));
+ clib_memset (rmp, 0, sizeof (*rmp));
+ rmp->_vl_msg_id =
+ ntohs (VL_API_NAT44_EI_INTERFACE_OUTPUT_FEATURE_DETAILS + nm->msg_id_base);
+ rmp->sw_if_index = ntohl (i->sw_if_index);
+ rmp->context = context;
+
+ if (nat44_ei_interface_is_inside (i))
+ rmp->flags |= NAT44_EI_IF_INSIDE;
+
+ vl_api_send_msg (reg, (u8 *) rmp);
+}
+
+static void
+vl_api_nat44_ei_interface_output_feature_dump_t_handler (
+ vl_api_nat44_ei_interface_output_feature_dump_t *mp)
+{
+ vl_api_registration_t *reg;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nat44_ei_interface_t *i;
+
+ reg = vl_api_client_index_to_registration (mp->client_index);
+ if (!reg)
+ return;
+
+ pool_foreach (i, nm->output_feature_interfaces)
+ {
+ send_nat44_ei_interface_output_feature_details (i, reg, mp->context);
+ }
+}
+
+static void
+vl_api_nat44_ei_add_del_static_mapping_t_handler (
+ vl_api_nat44_ei_add_del_static_mapping_t *mp)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ vl_api_nat44_ei_add_del_static_mapping_reply_t *rmp;
+ ip4_address_t local_addr, external_addr;
+ u16 local_port = 0, external_port = 0;
+ u32 vrf_id, external_sw_if_index;
+ int rv = 0;
+ nat_protocol_t proto;
+ u8 *tag = 0;
+
+ memcpy (&local_addr.as_u8, mp->local_ip_address, 4);
+ memcpy (&external_addr.as_u8, mp->external_ip_address, 4);
+
+ if (!(mp->flags & NAT44_EI_ADDR_ONLY_MAPPING))
+ {
+ local_port = mp->local_port;
+ external_port = mp->external_port;
+ }
+
+ 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);
+
+ mp->tag[sizeof (mp->tag) - 1] = 0;
+ tag = format (0, "%s", mp->tag);
+ vec_terminate_c_string (tag);
+
+ rv = nat44_ei_add_del_static_mapping (
+ local_addr, external_addr, local_port, external_port, proto,
+ external_sw_if_index, vrf_id, mp->flags & NAT44_EI_ADDR_ONLY_MAPPING, 0,
+ tag, mp->is_add);
+
+ vec_free (tag);
+
+ REPLY_MACRO (VL_API_NAT44_EI_ADD_DEL_STATIC_MAPPING_REPLY);
+}
+
+static void
+send_nat44_ei_static_mapping_details (nat44_ei_static_mapping_t *m,
+ vl_api_registration_t *reg, u32 context)
+{
+ vl_api_nat44_ei_static_mapping_details_t *rmp;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ u32 len = sizeof (*rmp);
+
+ rmp = vl_msg_api_alloc (len);
+ clib_memset (rmp, 0, len);
+ rmp->_vl_msg_id =
+ ntohs (VL_API_NAT44_EI_STATIC_MAPPING_DETAILS + nm->msg_id_base);
+
+ clib_memcpy (rmp->local_ip_address, &(m->local_addr), 4);
+ clib_memcpy (rmp->external_ip_address, &(m->external_addr), 4);
+ rmp->external_sw_if_index = ~0;
+ rmp->vrf_id = htonl (m->vrf_id);
+ rmp->context = context;
+
+ if (nat44_ei_is_addr_only_static_mapping (m))
+ {
+ rmp->flags |= NAT44_EI_ADDR_ONLY_MAPPING;
+ }
+ else
+ {
+ rmp->protocol = nat_proto_to_ip_proto (m->proto);
+ rmp->external_port = m->external_port;
+ rmp->local_port = m->local_port;
+ }
+
+ if (m->tag)
+ strncpy ((char *) rmp->tag, (char *) m->tag, vec_len (m->tag));
+
+ vl_api_send_msg (reg, (u8 *) rmp);
+}
+
+static void
+send_nat44_ei_static_map_resolve_details (nat44_ei_static_map_resolve_t *m,
+ vl_api_registration_t *reg,
+ u32 context)
+{
+ vl_api_nat44_ei_static_mapping_details_t *rmp;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+
+ rmp = vl_msg_api_alloc (sizeof (*rmp));
+ clib_memset (rmp, 0, sizeof (*rmp));
+ rmp->_vl_msg_id =
+ ntohs (VL_API_NAT44_EI_STATIC_MAPPING_DETAILS + nm->msg_id_base);
+ clib_memcpy (rmp->local_ip_address, &(m->l_addr), 4);
+ rmp->external_sw_if_index = htonl (m->sw_if_index);
+ rmp->vrf_id = htonl (m->vrf_id);
+ rmp->context = context;
+
+ if (m->addr_only)
+ {
+ rmp->flags |= NAT44_EI_ADDR_ONLY_MAPPING;
+ }
+ else
+ {
+ rmp->protocol = nat_proto_to_ip_proto (m->proto);
+ rmp->external_port = m->e_port;
+ rmp->local_port = m->l_port;
+ }
+ if (m->tag)
+ strncpy ((char *) rmp->tag, (char *) m->tag, vec_len (m->tag));
+
+ vl_api_send_msg (reg, (u8 *) rmp);
+}
+
+static void
+vl_api_nat44_ei_static_mapping_dump_t_handler (
+ vl_api_nat44_ei_static_mapping_dump_t *mp)
+{
+ vl_api_registration_t *reg;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nat44_ei_static_mapping_t *m;
+ nat44_ei_static_map_resolve_t *rp;
+ int j;
+
+ reg = vl_api_client_index_to_registration (mp->client_index);
+ if (!reg)
+ return;
+
+ pool_foreach (m, nm->static_mappings)
+ {
+ if (!nat44_ei_is_identity_static_mapping (m))
+ send_nat44_ei_static_mapping_details (m, reg, mp->context);
+ }
+
+ for (j = 0; j < vec_len (nm->to_resolve); j++)
+ {
+ rp = nm->to_resolve + j;
+ if (!rp->identity_nat)
+ send_nat44_ei_static_map_resolve_details (rp, reg, mp->context);
+ }
+}
+
+static void
+vl_api_nat44_ei_add_del_identity_mapping_t_handler (
+ vl_api_nat44_ei_add_del_identity_mapping_t *mp)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ vl_api_nat44_ei_add_del_identity_mapping_reply_t *rmp;
+ ip4_address_t addr;
+ 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 & NAT44_EI_ADDR_ONLY_MAPPING))
+ {
+ 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;
+ 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 = nat44_ei_add_del_static_mapping (
+ addr, addr, port, port, proto, sw_if_index, vrf_id,
+ mp->flags & NAT44_EI_ADDR_ONLY_MAPPING, 1, tag, mp->is_add);
+
+ vec_free (tag);
+
+ REPLY_MACRO (VL_API_NAT44_EI_ADD_DEL_IDENTITY_MAPPING_REPLY);
+}
+
+static void
+send_nat44_ei_identity_mapping_details (nat44_ei_static_mapping_t *m,
+ int index, vl_api_registration_t *reg,
+ u32 context)
+{
+ vl_api_nat44_ei_identity_mapping_details_t *rmp;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nat44_ei_lb_addr_port_t *local = pool_elt_at_index (m->locals, index);
+
+ rmp = vl_msg_api_alloc (sizeof (*rmp));
+ clib_memset (rmp, 0, sizeof (*rmp));
+ rmp->_vl_msg_id =
+ ntohs (VL_API_NAT44_EI_IDENTITY_MAPPING_DETAILS + nm->msg_id_base);
+
+ if (nat44_ei_is_addr_only_static_mapping (m))
+ rmp->flags |= NAT44_EI_ADDR_ONLY_MAPPING;
+
+ clib_memcpy (rmp->ip_address, &(m->local_addr), 4);
+ rmp->port = m->local_port;
+ rmp->sw_if_index = ~0;
+ rmp->vrf_id = htonl (local->vrf_id);
+ rmp->protocol = nat_proto_to_ip_proto (m->proto);
+ rmp->context = context;
+ if (m->tag)
+ strncpy ((char *) rmp->tag, (char *) m->tag, vec_len (m->tag));
+
+ vl_api_send_msg (reg, (u8 *) rmp);
+}
+
+static void
+send_nat44_ei_identity_map_resolve_details (nat44_ei_static_map_resolve_t *m,
+ vl_api_registration_t *reg,
+ u32 context)
+{
+ vl_api_nat44_ei_identity_mapping_details_t *rmp;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ rmp = vl_msg_api_alloc (sizeof (*rmp));
+ clib_memset (rmp, 0, sizeof (*rmp));
+ rmp->_vl_msg_id =
+ ntohs (VL_API_NAT44_EI_IDENTITY_MAPPING_DETAILS + nm->msg_id_base);
+
+ if (m->addr_only)
+ rmp->flags = (vl_api_nat44_ei_config_flags_t) NAT44_EI_ADDR_ONLY_MAPPING;
+
+ rmp->port = m->l_port;
+ rmp->sw_if_index = htonl (m->sw_if_index);
+ rmp->vrf_id = htonl (m->vrf_id);
+ rmp->protocol = nat_proto_to_ip_proto (m->proto);
+ rmp->context = context;
+ if (m->tag)
+ strncpy ((char *) rmp->tag, (char *) m->tag, vec_len (m->tag));
+
+ vl_api_send_msg (reg, (u8 *) rmp);
+}
+
+static void
+vl_api_nat44_ei_identity_mapping_dump_t_handler (
+ vl_api_nat44_ei_identity_mapping_dump_t *mp)
+{
+ vl_api_registration_t *reg;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nat44_ei_static_mapping_t *m;
+ nat44_ei_static_map_resolve_t *rp;
+ int j;
+
+ reg = vl_api_client_index_to_registration (mp->client_index);
+ if (!reg)
+ return;
+
+ pool_foreach (m, nm->static_mappings)
+ {
+ if (nat44_ei_is_identity_static_mapping (m))
+ {
+ pool_foreach_index (j, m->locals)
+ {
+ send_nat44_ei_identity_mapping_details (m, j, reg, mp->context);
+ }
+ }
+ }
+
+ for (j = 0; j < vec_len (nm->to_resolve); j++)
+ {
+ rp = nm->to_resolve + j;
+ if (rp->identity_nat)
+ send_nat44_ei_identity_map_resolve_details (rp, reg, mp->context);
+ }
+}
+
+static void
+vl_api_nat44_ei_add_del_interface_addr_t_handler (
+ vl_api_nat44_ei_add_del_interface_addr_t *mp)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ vl_api_nat44_ei_add_del_interface_addr_reply_t *rmp;
+ u32 sw_if_index = ntohl (mp->sw_if_index);
+ int rv = 0;
+ u8 is_del;
+
+ is_del = !mp->is_add;
+
+ VALIDATE_SW_IF_INDEX (mp);
+
+ rv = nat44_ei_add_interface_address (nm, sw_if_index, is_del);
+
+ BAD_SW_IF_INDEX_LABEL;
+ REPLY_MACRO (VL_API_NAT44_EI_ADD_DEL_INTERFACE_ADDR_REPLY);
+}
+
+static void
+send_nat44_ei_interface_addr_details (u32 sw_if_index,
+ vl_api_registration_t *reg, u32 context)
+{
+ vl_api_nat44_ei_interface_addr_details_t *rmp;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+
+ rmp = vl_msg_api_alloc (sizeof (*rmp));
+ clib_memset (rmp, 0, sizeof (*rmp));
+ rmp->_vl_msg_id =
+ ntohs (VL_API_NAT44_EI_INTERFACE_ADDR_DETAILS + nm->msg_id_base);
+ rmp->sw_if_index = ntohl (sw_if_index);
+ rmp->context = context;
+
+ vl_api_send_msg (reg, (u8 *) rmp);
+}
+
+static void
+vl_api_nat44_ei_interface_addr_dump_t_handler (
+ vl_api_nat44_ei_interface_addr_dump_t *mp)
+{
+ vl_api_registration_t *reg;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ u32 *i;
+
+ reg = vl_api_client_index_to_registration (mp->client_index);
+ if (!reg)
+ return;
+
+ vec_foreach (i, nm->auto_add_sw_if_indices)
+ send_nat44_ei_interface_addr_details (*i, reg, mp->context);
+}
+
+static void
+send_nat44_ei_user_details (nat44_ei_user_t *u, vl_api_registration_t *reg,
+ u32 context)
+{
+ vl_api_nat44_ei_user_details_t *rmp;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ ip4_main_t *im = &ip4_main;
+
+ rmp = vl_msg_api_alloc (sizeof (*rmp));
+ clib_memset (rmp, 0, sizeof (*rmp));
+ rmp->_vl_msg_id = ntohs (VL_API_NAT44_EI_USER_DETAILS + nm->msg_id_base);
+
+ if (!pool_is_free_index (im->fibs, u->fib_index))
+ {
+ fib_table_t *fib = fib_table_get (u->fib_index, FIB_PROTOCOL_IP4);
+ rmp->vrf_id = ntohl (fib->ft_table_id);
+ }
+
+ clib_memcpy (rmp->ip_address, &(u->addr), 4);
+ rmp->nsessions = ntohl (u->nsessions);
+ rmp->nstaticsessions = ntohl (u->nstaticsessions);
+ rmp->context = context;
+
+ vl_api_send_msg (reg, (u8 *) rmp);
+}
+
+static void
+vl_api_nat44_ei_user_dump_t_handler (vl_api_nat44_ei_user_dump_t *mp)
+{
+ vl_api_registration_t *reg;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nat44_ei_main_per_thread_data_t *tnm;
+ nat44_ei_user_t *u;
+
+ reg = vl_api_client_index_to_registration (mp->client_index);
+ if (!reg)
+ return;
+
+ vec_foreach (tnm, nm->per_thread_data)
+ {
+ pool_foreach (u, tnm->users)
+ {
+ send_nat44_ei_user_details (u, reg, mp->context);
+ }
+ }
+}
+
+static void
+send_nat44_ei_user_session_details (nat44_ei_session_t *s,
+ vl_api_registration_t *reg, u32 context)
+{
+ vl_api_nat44_ei_user_session_details_t *rmp;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+
+ rmp = vl_msg_api_alloc (sizeof (*rmp));
+ clib_memset (rmp, 0, sizeof (*rmp));
+ rmp->_vl_msg_id =
+ ntohs (VL_API_NAT44_EI_USER_SESSION_DETAILS + nm->msg_id_base);
+ clib_memcpy (rmp->outside_ip_address, (&s->out2in.addr), 4);
+ clib_memcpy (rmp->inside_ip_address, (&s->in2out.addr), 4);
+
+ if (nat44_ei_is_session_static (s))
+ rmp->flags |= NAT44_EI_STATIC_MAPPING;
+
+ rmp->last_heard = clib_host_to_net_u64 ((u64) s->last_heard);
+ rmp->total_bytes = clib_host_to_net_u64 (s->total_bytes);
+ rmp->total_pkts = ntohl (s->total_pkts);
+ rmp->context = context;
+ if (nat44_ei_is_unk_proto_session (s))
+ {
+ rmp->outside_port = 0;
+ rmp->inside_port = 0;
+ rmp->protocol = ntohs (s->in2out.port);
+ }
+ else
+ {
+ rmp->outside_port = s->out2in.port;
+ rmp->inside_port = s->in2out.port;
+ rmp->protocol = ntohs (nat_proto_to_ip_proto (s->nat_proto));
+ }
+ vl_api_send_msg (reg, (u8 *) rmp);
+}
+
+static void
+vl_api_nat44_ei_user_session_dump_t_handler (
+ vl_api_nat44_ei_user_session_dump_t *mp)
+{
+ vl_api_registration_t *reg;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nat44_ei_main_per_thread_data_t *tnm;
+ nat44_ei_session_t *s;
+ clib_bihash_kv_8_8_t key, value;
+ nat44_ei_user_key_t ukey;
+ nat44_ei_user_t *u;
+ u32 session_index, head_index, elt_index;
+ dlist_elt_t *head, *elt;
+ ip4_header_t ip;
+
+ reg = vl_api_client_index_to_registration (mp->client_index);
+ if (!reg)
+ return;
+
+ clib_memcpy (&ukey.addr, mp->ip_address, 4);
+ ip.src_address.as_u32 = ukey.addr.as_u32;
+ ukey.fib_index = fib_table_find (FIB_PROTOCOL_IP4, ntohl (mp->vrf_id));
+ key.key = ukey.as_u64;
+ if (nm->num_workers > 1)
+ tnm = vec_elt_at_index (nm->per_thread_data,
+ nm->worker_in2out_cb (&ip, ukey.fib_index, 0));
+ else
+ tnm = vec_elt_at_index (nm->per_thread_data, nm->num_workers);
+
+ if (clib_bihash_search_8_8 (&tnm->user_hash, &key, &value))
+ return;
+ u = pool_elt_at_index (tnm->users, value.value);
+ if (!u->nsessions && !u->nstaticsessions)
+ return;
+
+ head_index = u->sessions_per_user_list_head_index;
+ head = pool_elt_at_index (tnm->list_pool, head_index);
+ elt_index = head->next;
+ elt = pool_elt_at_index (tnm->list_pool, elt_index);
+ session_index = elt->value;
+ while (session_index != ~0)
+ {
+ s = pool_elt_at_index (tnm->sessions, session_index);
+
+ send_nat44_ei_user_session_details (s, reg, mp->context);
+
+ elt_index = elt->next;
+ elt = pool_elt_at_index (tnm->list_pool, elt_index);
+ session_index = elt->value;
+ }
+}
+
+static void
+vl_api_nat44_ei_del_session_t_handler (vl_api_nat44_ei_del_session_t *mp)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ vl_api_nat44_ei_del_session_reply_t *rmp;
+ ip4_address_t addr, eh_addr;
+ u16 port;
+ u32 vrf_id;
+ int rv = 0;
+ u8 is_in;
+ nat_protocol_t proto;
+
+ memcpy (&addr.as_u8, mp->address, 4);
+ port = mp->port;
+ vrf_id = clib_net_to_host_u32 (mp->vrf_id);
+ proto = ip_proto_to_nat_proto (mp->protocol);
+ memcpy (&eh_addr.as_u8, mp->ext_host_address, 4);
+
+ // is session inside ?
+ is_in = mp->flags & NAT44_EI_IF_INSIDE;
+
+ rv = nat44_ei_del_session (nm, &addr, port, proto, vrf_id, is_in);
+
+ REPLY_MACRO (VL_API_NAT44_EI_DEL_SESSION_REPLY);
+}
+
+static void
+vl_api_nat44_ei_forwarding_enable_disable_t_handler (
+ vl_api_nat44_ei_forwarding_enable_disable_t *mp)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ vl_api_nat44_ei_forwarding_enable_disable_reply_t *rmp;
+ int rv = 0;
+ u32 *ses_to_be_removed = 0, *ses_index;
+ nat44_ei_main_per_thread_data_t *tnm;
+ nat44_ei_session_t *s;
+
+ nm->forwarding_enabled = mp->enable != 0;
+
+ if (mp->enable == 0)
+ {
+ vec_foreach (tnm, nm->per_thread_data)
+ {
+ vec_foreach (ses_index, ses_to_be_removed)
+ {
+ s = pool_elt_at_index (tnm->sessions, ses_index[0]);
+ nat44_ei_free_session_data (nm, s, tnm - nm->per_thread_data, 0);
+ nat44_ei_delete_session (nm, s, tnm - nm->per_thread_data);
+ }
+
+ vec_free (ses_to_be_removed);
+ }
+ }
+
+ REPLY_MACRO (VL_API_NAT44_EI_FORWARDING_ENABLE_DISABLE_REPLY);
+}
+
+static void
+vl_api_nat44_ei_set_fq_options_t_handler (vl_api_nat44_ei_set_fq_options_t *mp)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ vl_api_nat44_ei_set_fq_options_reply_t *rmp;
+ int rv = 0;
+ u32 frame_queue_nelts = ntohl (mp->frame_queue_nelts);
+ rv = nat44_ei_set_frame_queue_nelts (frame_queue_nelts);
+ REPLY_MACRO (VL_API_NAT44_EI_SET_FQ_OPTIONS_REPLY);
+}
+
+static void
+vl_api_nat44_ei_show_fq_options_t_handler (
+ vl_api_nat44_ei_show_fq_options_t *mp)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ vl_api_nat44_ei_show_fq_options_reply_t *rmp;
+ int rv = 0;
+ /* clang-format off */
+ REPLY_MACRO2_ZERO (VL_API_NAT44_EI_SHOW_FQ_OPTIONS_REPLY,
+ ({
+ rmp->frame_queue_nelts = htonl (nm->frame_queue_nelts);
+ }));
+ /* clang-format on */
+}
+
+/* API definitions */
+#include <vnet/format_fns.h>
+#include <nat/nat44-ei/nat44_ei.api.c>
+
+/* Set up the API message handling tables */
+clib_error_t *
+nat44_ei_api_hookup (vlib_main_t *vm)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nm->msg_id_base = setup_message_id_table ();
+ return 0;
+}
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/src/plugins/nat/nat44-ei/nat44_ei_cli.c b/src/plugins/nat/nat44-ei/nat44_ei_cli.c
new file mode 100644
index 00000000000..3aa3a2f0525
--- /dev/null
+++ b/src/plugins/nat/nat44-ei/nat44_ei_cli.c
@@ -0,0 +1,2025 @@
+/*
+ * Copyright (c) 2020 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <vnet/fib/fib_table.h>
+
+#include <nat/lib/log.h>
+#include <nat/lib/nat_inlines.h>
+#include <nat/lib/ipfix_logging.h>
+
+#include <nat/nat44-ei/nat44_ei.h>
+#include <nat/nat44-ei/nat44_ei_ha.h>
+
+u8 *
+format_nat44_ei_session (u8 *s, va_list *args)
+{
+ nat44_ei_main_per_thread_data_t *tnm =
+ va_arg (*args, nat44_ei_main_per_thread_data_t *);
+ nat44_ei_session_t *sess = va_arg (*args, nat44_ei_session_t *);
+
+ if (nat44_ei_is_unk_proto_session (sess))
+ {
+ s =
+ format (s, " i2o %U proto %u fib %u\n", format_ip4_address,
+ &sess->in2out.addr, sess->in2out.port, sess->in2out.fib_index);
+ s =
+ format (s, " o2i %U proto %u fib %u\n", format_ip4_address,
+ &sess->out2in.addr, sess->out2in.port, sess->out2in.fib_index);
+ }
+ else
+ {
+ s = format (s, " i2o %U proto %U port %d fib %d\n", format_ip4_address,
+ &sess->in2out.addr, format_nat_protocol, sess->nat_proto,
+ clib_net_to_host_u16 (sess->in2out.port),
+ sess->in2out.fib_index);
+ s = format (s, " o2i %U proto %U port %d fib %d\n", format_ip4_address,
+ &sess->out2in.addr, format_nat_protocol, sess->nat_proto,
+ clib_net_to_host_u16 (sess->out2in.port),
+ sess->out2in.fib_index);
+ }
+
+ s = format (s, " index %llu\n", sess - tnm->sessions);
+ s = format (s, " last heard %.2f\n", sess->last_heard);
+ s = format (s, " total pkts %d, total bytes %lld\n", sess->total_pkts,
+ sess->total_bytes);
+ if (nat44_ei_is_session_static (sess))
+ s = format (s, " static translation\n");
+ else
+ s = format (s, " dynamic translation\n");
+
+ return s;
+}
+
+u8 *
+format_nat44_ei_user (u8 *s, va_list *args)
+{
+ nat44_ei_main_per_thread_data_t *tnm =
+ va_arg (*args, nat44_ei_main_per_thread_data_t *);
+ nat44_ei_user_t *u = va_arg (*args, nat44_ei_user_t *);
+ int verbose = va_arg (*args, int);
+ dlist_elt_t *head, *elt;
+ u32 elt_index, head_index;
+ u32 session_index;
+ nat44_ei_session_t *sess;
+
+ s = format (s, "%U: %d dynamic translations, %d static translations\n",
+ format_ip4_address, &u->addr, u->nsessions, u->nstaticsessions);
+
+ if (verbose == 0)
+ return s;
+
+ if (u->nsessions || u->nstaticsessions)
+ {
+ head_index = u->sessions_per_user_list_head_index;
+ head = pool_elt_at_index (tnm->list_pool, head_index);
+
+ elt_index = head->next;
+ elt = pool_elt_at_index (tnm->list_pool, elt_index);
+ session_index = elt->value;
+
+ while (session_index != ~0)
+ {
+ sess = pool_elt_at_index (tnm->sessions, session_index);
+
+ s = format (s, " %U\n", format_nat44_ei_session, tnm, sess);
+
+ elt_index = elt->next;
+ elt = pool_elt_at_index (tnm->list_pool, elt_index);
+ session_index = elt->value;
+ }
+ }
+
+ return s;
+}
+
+u8 *
+format_nat44_ei_static_mapping (u8 *s, va_list *args)
+{
+ nat44_ei_static_mapping_t *m = va_arg (*args, nat44_ei_static_mapping_t *);
+ nat44_ei_lb_addr_port_t *local;
+
+ if (nat44_ei_is_identity_static_mapping (m))
+ {
+ if (nat44_ei_is_addr_only_static_mapping (m))
+ s = format (s, "identity mapping %U", format_ip4_address,
+ &m->local_addr);
+ else
+ s = format (s, "identity mapping %U %U:%d", format_nat_protocol,
+ m->proto, format_ip4_address, &m->local_addr,
+ clib_net_to_host_u16 (m->local_port));
+
+ pool_foreach (local, m->locals)
+ {
+ s = format (s, " vrf %d", local->vrf_id);
+ }
+
+ return s;
+ }
+
+ if (nat44_ei_is_addr_only_static_mapping (m))
+ {
+ s = format (s, "local %U external %U vrf %d", format_ip4_address,
+ &m->local_addr, format_ip4_address, &m->external_addr,
+ m->vrf_id);
+ }
+ else
+ {
+ s = format (s, "%U local %U:%d external %U:%d vrf %d",
+ 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);
+ }
+ return s;
+}
+
+u8 *
+format_nat44_ei_static_map_to_resolve (u8 *s, va_list *args)
+{
+ nat44_ei_static_map_resolve_t *m =
+ va_arg (*args, nat44_ei_static_map_resolve_t *);
+ vnet_main_t *vnm = vnet_get_main ();
+
+ if (m->addr_only)
+ s =
+ format (s, "local %U external %U vrf %d", format_ip4_address, &m->l_addr,
+ 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_nat_protocol,
+ m->proto, format_ip4_address, &m->l_addr,
+ clib_net_to_host_u16 (m->l_port), format_vnet_sw_if_index_name,
+ vnm, m->sw_if_index, clib_net_to_host_u16 (m->e_port),
+ m->vrf_id);
+
+ return s;
+}
+
+static clib_error_t *
+nat44_ei_enable_command_fn (vlib_main_t *vm, unformat_input_t *input,
+ vlib_cli_command_t *cmd)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ unformat_input_t _line_input, *line_input = &_line_input;
+ clib_error_t *error = 0;
+
+ nat44_ei_config_t c = { 0 };
+ u8 mode_set = 0;
+
+ if (nm->enabled)
+ return clib_error_return (0, "nat44 ei already enabled");
+
+ /* Get a line of input. */
+ if (!unformat_user (input, unformat_line_input, line_input))
+ {
+ if (nat44_ei_plugin_enable (c) != 0)
+ return clib_error_return (0, "nat44 ei enable failed");
+ return 0;
+ }
+
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (!mode_set && unformat (line_input, "static-mapping-only"))
+ {
+ mode_set = 1;
+ c.static_mapping_only = 1;
+ if (unformat (line_input, "connection-tracking"))
+ {
+ c.connection_tracking = 1;
+ }
+ }
+ else if (!mode_set && unformat (line_input, "out2in-dpo"))
+ {
+ mode_set = 1;
+ c.out2in_dpo = 1;
+ }
+ else if (unformat (line_input, "inside-vrf %u", &c.inside_vrf))
+ ;
+ else if (unformat (line_input, "outside-vrf %u", &c.outside_vrf))
+ ;
+ else if (unformat (line_input, "users %u", &c.users))
+ ;
+ else if (unformat (line_input, "sessions %u", &c.sessions))
+ ;
+ else if (unformat (line_input, "user-sessions %u", &c.user_sessions))
+ ;
+ else
+ {
+ error = clib_error_return (0, "unknown input '%U'",
+ format_unformat_error, line_input);
+ goto done;
+ }
+ }
+
+ if (!c.sessions)
+ {
+ error = clib_error_return (0, "number of sessions is required");
+ goto done;
+ }
+
+ if (nat44_ei_plugin_enable (c) != 0)
+ error = clib_error_return (0, "nat44 ei enable failed");
+done:
+ unformat_free (line_input);
+ return error;
+}
+
+static clib_error_t *
+nat44_ei_disable_command_fn (vlib_main_t *vm, unformat_input_t *input,
+ vlib_cli_command_t *cmd)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ clib_error_t *error = 0;
+
+ if (!nm->enabled)
+ return clib_error_return (0, "nat44 ei already disabled");
+
+ if (nat44_ei_plugin_disable () != 0)
+ error = clib_error_return (0, "nat44 ei disable failed");
+
+ return error;
+}
+
+static clib_error_t *
+set_workers_command_fn (vlib_main_t *vm, unformat_input_t *input,
+ vlib_cli_command_t *cmd)
+{
+ unformat_input_t _line_input, *line_input = &_line_input;
+ uword *bitmap = 0;
+ int rv = 0;
+ clib_error_t *error = 0;
+
+ /* Get a line of input. */
+ if (!unformat_user (input, unformat_line_input, line_input))
+ return 0;
+
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (line_input, "%U", unformat_bitmap_list, &bitmap))
+ ;
+ else
+ {
+ error = clib_error_return (0, "unknown input '%U'",
+ format_unformat_error, line_input);
+ goto done;
+ }
+ }
+
+ if (bitmap == 0)
+ {
+ error = clib_error_return (0, "List of workers must be specified.");
+ goto done;
+ }
+
+ rv = nat44_ei_set_workers (bitmap);
+
+ clib_bitmap_free (bitmap);
+
+ switch (rv)
+ {
+ case VNET_API_ERROR_INVALID_WORKER:
+ error = clib_error_return (0, "Invalid worker(s).");
+ goto done;
+ case VNET_API_ERROR_FEATURE_DISABLED:
+ error =
+ clib_error_return (0, "Supported only if 2 or more workes available.");
+ goto done;
+ default:
+ break;
+ }
+
+done:
+ unformat_free (line_input);
+
+ return error;
+}
+
+static clib_error_t *
+nat_show_workers_commnad_fn (vlib_main_t *vm, unformat_input_t *input,
+ vlib_cli_command_t *cmd)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ u32 *worker;
+
+ if (nm->num_workers > 1)
+ {
+ vlib_cli_output (vm, "%d workers", vec_len (nm->workers));
+ vec_foreach (worker, nm->workers)
+ {
+ vlib_worker_thread_t *w =
+ vlib_worker_threads + *worker + nm->first_worker_index;
+ vlib_cli_output (vm, " %s", w->name);
+ }
+ }
+
+ return 0;
+}
+
+static clib_error_t *
+nat44_ei_set_log_level_command_fn (vlib_main_t *vm, unformat_input_t *input,
+ vlib_cli_command_t *cmd)
+{
+ unformat_input_t _line_input, *line_input = &_line_input;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ u8 log_level = NAT_LOG_NONE;
+ clib_error_t *error = 0;
+
+ /* Get a line of input. */
+ if (!unformat_user (input, unformat_line_input, line_input))
+ return 0;
+
+ if (!unformat (line_input, "%d", &log_level))
+ {
+ error = clib_error_return (0, "unknown input '%U'",
+ format_unformat_error, line_input);
+ goto done;
+ }
+ if (log_level > NAT_LOG_DEBUG)
+ {
+ error = clib_error_return (0, "unknown logging level '%d'", log_level);
+ goto done;
+ }
+ nm->log_level = log_level;
+
+done:
+ unformat_free (line_input);
+
+ return error;
+}
+
+static clib_error_t *
+nat44_ei_ipfix_logging_enable_disable_command_fn (vlib_main_t *vm,
+ unformat_input_t *input,
+ vlib_cli_command_t *cmd)
+{
+ unformat_input_t _line_input, *line_input = &_line_input;
+ u32 domain_id = 0;
+ u32 src_port = 0;
+ u8 enable = 1;
+ int rv = 0;
+ clib_error_t *error = 0;
+
+ /* Get a line of input. */
+ if (!unformat_user (input, unformat_line_input, line_input))
+ {
+ rv =
+ nat_ipfix_logging_enable_disable (enable, domain_id, (u16) src_port);
+ if (rv)
+ return clib_error_return (0, "ipfix logging enable failed");
+ return 0;
+ }
+
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (line_input, "domain %d", &domain_id))
+ ;
+ else if (unformat (line_input, "src-port %d", &src_port))
+ ;
+ else if (unformat (line_input, "disable"))
+ enable = 0;
+ else
+ {
+ error = clib_error_return (0, "unknown input '%U'",
+ format_unformat_error, line_input);
+ goto done;
+ }
+ }
+
+ rv = nat_ipfix_logging_enable_disable (enable, domain_id, (u16) src_port);
+
+ if (rv)
+ {
+ error = clib_error_return (0, "ipfix logging enable failed");
+ goto done;
+ }
+
+done:
+ unformat_free (line_input);
+
+ return error;
+}
+
+static clib_error_t *
+nat44_ei_show_hash_command_fn (vlib_main_t *vm, unformat_input_t *input,
+ vlib_cli_command_t *cmd)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nat44_ei_main_per_thread_data_t *tnm;
+ int i;
+ int verbose = 0;
+
+ if (unformat (input, "detail"))
+ verbose = 1;
+ else if (unformat (input, "verbose"))
+ verbose = 2;
+
+ vlib_cli_output (vm, "%U", format_bihash_8_8, &nm->static_mapping_by_local,
+ verbose);
+ vlib_cli_output (vm, "%U", format_bihash_8_8,
+ &nm->static_mapping_by_external, verbose);
+ vec_foreach_index (i, nm->per_thread_data)
+ {
+ tnm = vec_elt_at_index (nm->per_thread_data, i);
+ vlib_cli_output (vm, "-------- thread %d %s --------\n", i,
+ vlib_worker_threads[i].name);
+
+ vlib_cli_output (vm, "%U", format_bihash_8_8, &nm->in2out, verbose);
+ vlib_cli_output (vm, "%U", format_bihash_8_8, &nm->out2in, verbose);
+ vlib_cli_output (vm, "%U", format_bihash_8_8, &tnm->user_hash, verbose);
+ }
+
+ vlib_cli_output (vm, "-------- hash table parameters --------\n");
+ vlib_cli_output (vm, "translation buckets: %u", nm->translation_buckets);
+ vlib_cli_output (vm, "user buckets: %u", nm->user_buckets);
+ return 0;
+}
+
+static clib_error_t *
+nat44_ei_set_alloc_addr_and_port_alg_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;
+ u32 psid, psid_offset, psid_length, port_start, port_end;
+
+ /* Get a line of input. */
+ if (!unformat_user (input, unformat_line_input, line_input))
+ return 0;
+
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (line_input, "default"))
+ nat44_ei_set_alloc_default ();
+ else if (unformat (line_input,
+ "map-e psid %d psid-offset %d psid-len %d", &psid,
+ &psid_offset, &psid_length))
+ nat44_ei_set_alloc_mape ((u16) psid, (u16) psid_offset,
+ (u16) psid_length);
+ else if (unformat (line_input, "port-range %d - %d", &port_start,
+ &port_end))
+ {
+ if (port_end <= port_start)
+ {
+ error = clib_error_return (
+ 0, "The end-port must be greater than start-port");
+ goto done;
+ }
+ nat44_ei_set_alloc_range ((u16) port_start, (u16) port_end);
+ }
+ else
+ {
+ error = clib_error_return (0, "unknown input '%U'",
+ format_unformat_error, line_input);
+ goto done;
+ }
+ }
+
+done:
+ unformat_free (line_input);
+
+ return error;
+};
+
+u8 *
+format_nat44_ei_addr_and_port_alloc_alg (u8 *s, va_list *args)
+{
+ u32 i = va_arg (*args, u32);
+ u8 *t = 0;
+
+ switch (i)
+ {
+#define _(v, N, s) \
+ case NAT44_EI_ADDR_AND_PORT_ALLOC_ALG_##N: \
+ t = (u8 *) s; \
+ break;
+ foreach_nat44_ei_addr_and_port_alloc_alg
+#undef _
+ default : s = format (s, "unknown");
+ return s;
+ }
+ s = format (s, "%s", t);
+ return s;
+}
+
+static clib_error_t *
+nat44_ei_show_alloc_addr_and_port_alg_command_fn (vlib_main_t *vm,
+ unformat_input_t *input,
+ vlib_cli_command_t *cmd)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+
+ vlib_cli_output (vm, "NAT address and port: %U",
+ format_nat44_ei_addr_and_port_alloc_alg,
+ nm->addr_and_port_alloc_alg);
+ switch (nm->addr_and_port_alloc_alg)
+ {
+ case NAT44_EI_ADDR_AND_PORT_ALLOC_ALG_MAPE:
+ vlib_cli_output (vm, " psid %d psid-offset %d psid-len %d", nm->psid,
+ nm->psid_offset, nm->psid_length);
+ break;
+ case NAT44_EI_ADDR_AND_PORT_ALLOC_ALG_RANGE:
+ vlib_cli_output (vm, " start-port %d end-port %d", nm->start_port,
+ nm->end_port);
+ break;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static clib_error_t *
+nat_set_mss_clamping_command_fn (vlib_main_t *vm, unformat_input_t *input,
+ vlib_cli_command_t *cmd)
+{
+ unformat_input_t _line_input, *line_input = &_line_input;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ clib_error_t *error = 0;
+ u32 mss;
+
+ /* Get a line of input. */
+ if (!unformat_user (input, unformat_line_input, line_input))
+ return 0;
+
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (line_input, "disable"))
+ nm->mss_clamping = 0;
+ else if (unformat (line_input, "%d", &mss))
+ nm->mss_clamping = (u16) mss;
+ else
+ {
+ error = clib_error_return (0, "unknown input '%U'",
+ format_unformat_error, line_input);
+ goto done;
+ }
+ }
+
+done:
+ unformat_free (line_input);
+
+ return error;
+}
+
+static clib_error_t *
+nat_show_mss_clamping_command_fn (vlib_main_t *vm, unformat_input_t *input,
+ vlib_cli_command_t *cmd)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+
+ if (nm->mss_clamping)
+ vlib_cli_output (vm, "mss-clamping %d", nm->mss_clamping);
+ else
+ vlib_cli_output (vm, "mss-clamping disabled");
+
+ return 0;
+}
+
+static clib_error_t *
+nat_ha_failover_command_fn (vlib_main_t *vm, unformat_input_t *input,
+ vlib_cli_command_t *cmd)
+{
+ unformat_input_t _line_input, *line_input = &_line_input;
+ ip4_address_t addr;
+ u32 port, session_refresh_interval = 10;
+ int rv;
+ clib_error_t *error = 0;
+
+ /* Get a line of input. */
+ if (!unformat_user (input, unformat_line_input, line_input))
+ return 0;
+
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (line_input, "%U:%u", unformat_ip4_address, &addr, &port))
+ ;
+ else if (unformat (line_input, "refresh-interval %u",
+ &session_refresh_interval))
+ ;
+ else
+ {
+ error = clib_error_return (0, "unknown input '%U'",
+ format_unformat_error, line_input);
+ goto done;
+ }
+ }
+
+ rv = nat_ha_set_failover (&addr, (u16) port, session_refresh_interval);
+ if (rv)
+ error = clib_error_return (0, "set HA failover failed");
+
+done:
+ unformat_free (line_input);
+
+ return error;
+}
+
+static clib_error_t *
+nat_ha_listener_command_fn (vlib_main_t *vm, unformat_input_t *input,
+ vlib_cli_command_t *cmd)
+{
+ unformat_input_t _line_input, *line_input = &_line_input;
+ ip4_address_t addr;
+ u32 port, path_mtu = 512;
+ int rv;
+ clib_error_t *error = 0;
+
+ /* Get a line of input. */
+ if (!unformat_user (input, unformat_line_input, line_input))
+ return 0;
+
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (line_input, "%U:%u", unformat_ip4_address, &addr, &port))
+ ;
+ else if (unformat (line_input, "path-mtu %u", &path_mtu))
+ ;
+ else
+ {
+ error = clib_error_return (0, "unknown input '%U'",
+ format_unformat_error, line_input);
+ goto done;
+ }
+ }
+
+ rv = nat_ha_set_listener (&addr, (u16) port, path_mtu);
+ if (rv)
+ error = clib_error_return (0, "set HA listener failed");
+
+done:
+ unformat_free (line_input);
+
+ return error;
+}
+
+static clib_error_t *
+nat_show_ha_command_fn (vlib_main_t *vm, unformat_input_t *input,
+ vlib_cli_command_t *cmd)
+{
+ ip4_address_t addr;
+ u16 port;
+ u32 path_mtu, session_refresh_interval, resync_ack_missed;
+ u8 in_resync;
+
+ nat_ha_get_listener (&addr, &port, &path_mtu);
+ if (!port)
+ {
+ vlib_cli_output (vm, "NAT HA disabled\n");
+ return 0;
+ }
+
+ vlib_cli_output (vm, "LISTENER:\n");
+ vlib_cli_output (vm, " %U:%u path-mtu %u\n", format_ip4_address, &addr,
+ port, path_mtu);
+
+ nat_ha_get_failover (&addr, &port, &session_refresh_interval);
+ vlib_cli_output (vm, "FAILOVER:\n");
+ if (port)
+ vlib_cli_output (vm, " %U:%u refresh-interval %usec\n",
+ format_ip4_address, &addr, port,
+ session_refresh_interval);
+ else
+ vlib_cli_output (vm, " NA\n");
+
+ nat_ha_get_resync_status (&in_resync, &resync_ack_missed);
+ vlib_cli_output (vm, "RESYNC:\n");
+ if (in_resync)
+ vlib_cli_output (vm, " in progress\n");
+ else
+ vlib_cli_output (vm, " completed (%d ACK missed)\n", resync_ack_missed);
+
+ return 0;
+}
+
+static clib_error_t *
+nat_ha_flush_command_fn (vlib_main_t *vm, unformat_input_t *input,
+ vlib_cli_command_t *cmd)
+{
+ nat_ha_flush (0);
+ return 0;
+}
+
+static clib_error_t *
+nat_ha_resync_command_fn (vlib_main_t *vm, unformat_input_t *input,
+ vlib_cli_command_t *cmd)
+{
+ clib_error_t *error = 0;
+
+ if (nat_ha_resync (0, 0, 0))
+ error = clib_error_return (0, "NAT HA resync already running");
+
+ return error;
+}
+
+static clib_error_t *
+add_address_command_fn (vlib_main_t *vm, unformat_input_t *input,
+ vlib_cli_command_t *cmd)
+{
+ unformat_input_t _line_input, *line_input = &_line_input;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ ip4_address_t start_addr, end_addr, this_addr;
+ u32 start_host_order, end_host_order;
+ u32 vrf_id = ~0;
+ int i, count;
+ int is_add = 1;
+ int rv = 0;
+ clib_error_t *error = 0;
+
+ /* Get a line of input. */
+ if (!unformat_user (input, unformat_line_input, line_input))
+ return 0;
+
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (line_input, "%U - %U", unformat_ip4_address, &start_addr,
+ unformat_ip4_address, &end_addr))
+ ;
+ else if (unformat (line_input, "tenant-vrf %u", &vrf_id))
+ ;
+ else if (unformat (line_input, "%U", unformat_ip4_address, &start_addr))
+ end_addr = start_addr;
+ else if (unformat (line_input, "del"))
+ is_add = 0;
+ else
+ {
+ error = clib_error_return (0, "unknown input '%U'",
+ format_unformat_error, line_input);
+ goto done;
+ }
+ }
+
+ if (nm->static_mapping_only)
+ {
+ error = clib_error_return (0, "static mapping only mode");
+ goto done;
+ }
+
+ start_host_order = clib_host_to_net_u32 (start_addr.as_u32);
+ end_host_order = clib_host_to_net_u32 (end_addr.as_u32);
+
+ if (end_host_order < start_host_order)
+ {
+ error = clib_error_return (0, "end address less than start address");
+ goto done;
+ }
+
+ count = (end_host_order - start_host_order) + 1;
+
+ if (count > 1024)
+ nat44_ei_log_info ("%U - %U, %d addresses...", format_ip4_address,
+ &start_addr, format_ip4_address, &end_addr, count);
+
+ this_addr = start_addr;
+
+ for (i = 0; i < count; i++)
+ {
+ if (is_add)
+ rv = nat44_ei_add_address (nm, &this_addr, vrf_id);
+ else
+ rv = nat44_ei_del_address (nm, this_addr, 0);
+
+ switch (rv)
+ {
+ case VNET_API_ERROR_VALUE_EXIST:
+ error = clib_error_return (0, "NAT address already in use.");
+ goto done;
+ case VNET_API_ERROR_NO_SUCH_ENTRY:
+ error = clib_error_return (0, "NAT address not exist.");
+ goto done;
+ case VNET_API_ERROR_UNSPECIFIED:
+ error = clib_error_return (0, "NAT address used in static mapping.");
+ goto done;
+ case VNET_API_ERROR_FEATURE_DISABLED:
+ goto done;
+ default:
+ break;
+ }
+
+ if (nm->out2in_dpo)
+ nat44_ei_add_del_address_dpo (this_addr, is_add);
+
+ increment_v4_address (&this_addr);
+ }
+
+done:
+ unformat_free (line_input);
+
+ return error;
+}
+
+static clib_error_t *
+nat44_ei_show_addresses_command_fn (vlib_main_t *vm, unformat_input_t *input,
+ vlib_cli_command_t *cmd)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nat44_ei_address_t *ap;
+
+ vlib_cli_output (vm, "NAT44 pool addresses:");
+ vec_foreach (ap, nm->addresses)
+ {
+ vlib_cli_output (vm, "%U", format_ip4_address, &ap->addr);
+ if (ap->fib_index != ~0)
+ vlib_cli_output (
+ vm, " tenant VRF: %u",
+ fib_table_get (ap->fib_index, FIB_PROTOCOL_IP4)->ft_table_id);
+ else
+ vlib_cli_output (vm, " tenant VRF independent");
+#define _(N, i, n, s) \
+ vlib_cli_output (vm, " %d busy %s ports", ap->busy_##n##_ports, s);
+ foreach_nat_protocol
+#undef _
+ }
+ return 0;
+}
+
+static clib_error_t *
+nat44_ei_feature_command_fn (vlib_main_t *vm, unformat_input_t *input,
+ vlib_cli_command_t *cmd)
+{
+ unformat_input_t _line_input, *line_input = &_line_input;
+ vnet_main_t *vnm = vnet_get_main ();
+ clib_error_t *error = 0;
+ u32 sw_if_index;
+ u32 *inside_sw_if_indices = 0;
+ u32 *outside_sw_if_indices = 0;
+ u8 is_output_feature = 0;
+ int is_del = 0;
+ int i;
+
+ sw_if_index = ~0;
+
+ /* Get a line of input. */
+ if (!unformat_user (input, unformat_line_input, line_input))
+ return 0;
+
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (line_input, "in %U", unformat_vnet_sw_interface, vnm,
+ &sw_if_index))
+ vec_add1 (inside_sw_if_indices, sw_if_index);
+ else if (unformat (line_input, "out %U", unformat_vnet_sw_interface, vnm,
+ &sw_if_index))
+ vec_add1 (outside_sw_if_indices, sw_if_index);
+ else if (unformat (line_input, "output-feature"))
+ is_output_feature = 1;
+ else if (unformat (line_input, "del"))
+ is_del = 1;
+ else
+ {
+ error = clib_error_return (0, "unknown input '%U'",
+ format_unformat_error, line_input);
+ goto done;
+ }
+ }
+
+ if (vec_len (inside_sw_if_indices))
+ {
+ for (i = 0; i < vec_len (inside_sw_if_indices); i++)
+ {
+ sw_if_index = inside_sw_if_indices[i];
+ if (is_output_feature)
+ {
+ if (nat44_ei_interface_add_del_output_feature (sw_if_index, 1,
+ is_del))
+ {
+ error = clib_error_return (
+ 0, "%s %U failed", is_del ? "del" : "add",
+ format_vnet_sw_if_index_name, vnm, sw_if_index);
+ goto done;
+ }
+ }
+ else
+ {
+ if (nat44_ei_interface_add_del (sw_if_index, 1, is_del))
+ {
+ error = clib_error_return (
+ 0, "%s %U failed", is_del ? "del" : "add",
+ format_vnet_sw_if_index_name, vnm, sw_if_index);
+ goto done;
+ }
+ }
+ }
+ }
+
+ if (vec_len (outside_sw_if_indices))
+ {
+ for (i = 0; i < vec_len (outside_sw_if_indices); i++)
+ {
+ sw_if_index = outside_sw_if_indices[i];
+ if (is_output_feature)
+ {
+ if (nat44_ei_interface_add_del_output_feature (sw_if_index, 0,
+ is_del))
+ {
+ error = clib_error_return (
+ 0, "%s %U failed", is_del ? "del" : "add",
+ format_vnet_sw_if_index_name, vnm, sw_if_index);
+ goto done;
+ }
+ }
+ else
+ {
+ if (nat44_ei_interface_add_del (sw_if_index, 0, is_del))
+ {
+ error = clib_error_return (
+ 0, "%s %U failed", is_del ? "del" : "add",
+ format_vnet_sw_if_index_name, vnm, sw_if_index);
+ goto done;
+ }
+ }
+ }
+ }
+
+done:
+ unformat_free (line_input);
+ vec_free (inside_sw_if_indices);
+ vec_free (outside_sw_if_indices);
+
+ return error;
+}
+
+static clib_error_t *
+nat44_ei_show_interfaces_command_fn (vlib_main_t *vm, unformat_input_t *input,
+ vlib_cli_command_t *cmd)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nat44_ei_interface_t *i;
+ vnet_main_t *vnm = vnet_get_main ();
+
+ vlib_cli_output (vm, "NAT44 interfaces:");
+ pool_foreach (i, nm->interfaces)
+ {
+ vlib_cli_output (vm, " %U %s", format_vnet_sw_if_index_name, vnm,
+ i->sw_if_index,
+ (nat44_ei_interface_is_inside (i) &&
+ nat44_ei_interface_is_outside (i)) ?
+ "in out" :
+ (nat44_ei_interface_is_inside (i) ? "in" : "out"));
+ }
+
+ pool_foreach (i, nm->output_feature_interfaces)
+ {
+ vlib_cli_output (vm, " %U output-feature %s",
+ format_vnet_sw_if_index_name, vnm, i->sw_if_index,
+ (nat44_ei_interface_is_inside (i) &&
+ nat44_ei_interface_is_outside (i)) ?
+ "in out" :
+ (nat44_ei_interface_is_inside (i) ? "in" : "out"));
+ }
+
+ return 0;
+}
+
+static clib_error_t *
+add_static_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 l_addr, e_addr;
+ u32 l_port = 0, e_port = 0, vrf_id = ~0;
+ int is_add = 1, addr_only = 1, rv;
+ u32 sw_if_index = ~0;
+ vnet_main_t *vnm = vnet_get_main ();
+ nat_protocol_t proto = NAT_PROTOCOL_OTHER;
+ u8 proto_set = 0;
+
+ /* Get a line of input. */
+ if (!unformat_user (input, unformat_line_input, line_input))
+ return 0;
+
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (line_input, "local %U %u", unformat_ip4_address, &l_addr,
+ &l_port))
+ addr_only = 0;
+ 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;
+ 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;
+ else if (unformat (line_input, "external %U", unformat_vnet_sw_interface,
+ vnm, &sw_if_index))
+ ;
+ 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, "del"))
+ is_add = 0;
+ else
+ {
+ error = clib_error_return (0, "unknown input: '%U'",
+ format_unformat_error, line_input);
+ goto done;
+ }
+ }
+
+ if (addr_only)
+ {
+ if (proto_set)
+ {
+ error = clib_error_return (
+ 0, "address only mapping doesn't support protocol");
+ goto done;
+ }
+ }
+ else if (!proto_set)
+ {
+ error = clib_error_return (0, "protocol is required");
+ goto done;
+ }
+
+ rv = nat44_ei_add_del_static_mapping (
+ l_addr, e_addr, clib_host_to_net_u16 (l_port),
+ clib_host_to_net_u16 (e_port), proto, sw_if_index, vrf_id, addr_only, 0, 0,
+ is_add);
+
+ switch (rv)
+ {
+ case VNET_API_ERROR_INVALID_VALUE:
+ error = clib_error_return (0, "External port already in use.");
+ goto done;
+ case VNET_API_ERROR_NO_SUCH_ENTRY:
+ if (is_add)
+ error = clib_error_return (0, "External address must be allocated.");
+ else
+ error = clib_error_return (0, "Mapping not exist.");
+ goto done;
+ case VNET_API_ERROR_NO_SUCH_FIB:
+ error = clib_error_return (0, "No such VRF id.");
+ goto done;
+ case VNET_API_ERROR_VALUE_EXIST:
+ error = clib_error_return (0, "Mapping already exist.");
+ goto done;
+ case VNET_API_ERROR_FEATURE_DISABLED:
+ goto done;
+ default:
+ break;
+ }
+
+done:
+ unformat_free (line_input);
+
+ return error;
+}
+
+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;
+ u32 port = 0, vrf_id = ~0;
+ ip4_address_t addr;
+ int is_add = 1;
+ int addr_only = 1;
+ u32 sw_if_index = ~0;
+ vnet_main_t *vnm = vnet_get_main ();
+ int rv;
+ nat_protocol_t proto;
+
+ addr.as_u32 = 0;
+
+ /* Get a line of input. */
+ if (!unformat_user (input, unformat_line_input, line_input))
+ return 0;
+
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (line_input, "%U", unformat_ip4_address, &addr))
+ ;
+ else if (unformat (line_input, "external %U", unformat_vnet_sw_interface,
+ vnm, &sw_if_index))
+ ;
+ else if (unformat (line_input, "vrf %u", &vrf_id))
+ ;
+ else if (unformat (line_input, "%U %u", unformat_nat_protocol, &proto,
+ &port))
+ addr_only = 0;
+ else if (unformat (line_input, "del"))
+ is_add = 0;
+ else
+ {
+ error = clib_error_return (0, "unknown input: '%U'",
+ format_unformat_error, line_input);
+ goto done;
+ }
+ }
+
+ rv = nat44_ei_add_del_static_mapping (
+ addr, addr, clib_host_to_net_u16 (port), clib_host_to_net_u16 (port),
+ proto, sw_if_index, vrf_id, addr_only, 1, 0, is_add);
+
+ switch (rv)
+ {
+ case VNET_API_ERROR_INVALID_VALUE:
+ error = clib_error_return (0, "External port already in use.");
+ goto done;
+ case VNET_API_ERROR_NO_SUCH_ENTRY:
+ if (is_add)
+ error = clib_error_return (0, "External address must be allocated.");
+ else
+ error = clib_error_return (0, "Mapping not exist.");
+ goto done;
+ case VNET_API_ERROR_NO_SUCH_FIB:
+ error = clib_error_return (0, "No such VRF id.");
+ goto done;
+ case VNET_API_ERROR_VALUE_EXIST:
+ error = clib_error_return (0, "Mapping already exist.");
+ goto done;
+ default:
+ break;
+ }
+
+done:
+ unformat_free (line_input);
+
+ return error;
+}
+
+static clib_error_t *
+nat44_ei_show_static_mappings_command_fn (vlib_main_t *vm,
+ unformat_input_t *input,
+ vlib_cli_command_t *cmd)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nat44_ei_static_mapping_t *m;
+ nat44_ei_static_map_resolve_t *rp;
+
+ vlib_cli_output (vm, "NAT44 static mappings:");
+ pool_foreach (m, nm->static_mappings)
+ {
+ vlib_cli_output (vm, " %U", format_nat44_ei_static_mapping, m);
+ }
+ vec_foreach (rp, nm->to_resolve)
+ vlib_cli_output (vm, " %U", format_nat44_ei_static_map_to_resolve, rp);
+
+ return 0;
+}
+
+static clib_error_t *
+nat44_ei_add_interface_address_command_fn (vlib_main_t *vm,
+ unformat_input_t *input,
+ vlib_cli_command_t *cmd)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ unformat_input_t _line_input, *line_input = &_line_input;
+ u32 sw_if_index;
+ int rv;
+ int is_del = 0;
+ clib_error_t *error = 0;
+
+ /* Get a line of input. */
+ if (!unformat_user (input, unformat_line_input, line_input))
+ return 0;
+
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (line_input, "%U", unformat_vnet_sw_interface,
+ nm->vnet_main, &sw_if_index))
+ ;
+ else if (unformat (line_input, "del"))
+ is_del = 1;
+ else
+ {
+ error = clib_error_return (0, "unknown input '%U'",
+ format_unformat_error, line_input);
+ goto done;
+ }
+ }
+
+ rv = nat44_ei_add_interface_address (nm, sw_if_index, is_del);
+
+ switch (rv)
+ {
+ case 0:
+ break;
+
+ default:
+ error = clib_error_return (
+ 0, "nat44_ei_add_interface_address returned %d", rv);
+ goto done;
+ }
+
+done:
+ unformat_free (line_input);
+
+ return error;
+}
+
+static clib_error_t *
+nat44_ei_show_interface_address_command_fn (vlib_main_t *vm,
+ unformat_input_t *input,
+ vlib_cli_command_t *cmd)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ vnet_main_t *vnm = vnet_get_main ();
+ u32 *sw_if_index;
+
+ vlib_cli_output (vm, "NAT44 pool address interfaces:");
+ vec_foreach (sw_if_index, nm->auto_add_sw_if_indices)
+ {
+ vlib_cli_output (vm, " %U", format_vnet_sw_if_index_name, vnm,
+ *sw_if_index);
+ }
+ return 0;
+}
+
+static clib_error_t *
+nat44_ei_show_sessions_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;
+
+ nat44_ei_main_per_thread_data_t *tnm;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+
+ int detail = 0;
+ int i = 0;
+
+ if (!unformat_user (input, unformat_line_input, line_input))
+ goto print;
+
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (line_input, "detail"))
+ detail = 1;
+ else
+ {
+ error = clib_error_return (0, "unknown input '%U'",
+ format_unformat_error, line_input);
+ break;
+ }
+ }
+ unformat_free (line_input);
+
+print:
+ vlib_cli_output (vm, "NAT44 sessions:");
+
+ vec_foreach_index (i, nm->per_thread_data)
+ {
+ tnm = vec_elt_at_index (nm->per_thread_data, i);
+
+ vlib_cli_output (vm, "-------- thread %d %s: %d sessions --------\n", i,
+ vlib_worker_threads[i].name, pool_elts (tnm->sessions));
+
+ nat44_ei_user_t *u;
+ pool_foreach (u, tnm->users)
+ {
+ vlib_cli_output (vm, " %U", format_nat44_ei_user, tnm, u, detail);
+ }
+ }
+ return error;
+}
+
+static clib_error_t *
+nat44_ei_del_user_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;
+ u32 fib_index = 0;
+ int rv;
+
+ /* Get a line of input. */
+ if (!unformat_user (input, unformat_line_input, line_input))
+ return 0;
+
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (line_input, "%U", unformat_ip4_address, &addr))
+ ;
+ else if (unformat (line_input, "fib %u", &fib_index))
+ ;
+ else
+ {
+ error = clib_error_return (0, "unknown input '%U'",
+ format_unformat_error, line_input);
+ goto done;
+ }
+ }
+
+ rv = nat44_ei_user_del (&addr, fib_index);
+
+ if (!rv)
+ {
+ error = clib_error_return (0, "nat44_ei_user_del returned %d", rv);
+ }
+
+done:
+ unformat_free (line_input);
+
+ return error;
+}
+
+static clib_error_t *
+nat44_ei_clear_sessions_command_fn (vlib_main_t *vm, unformat_input_t *input,
+ vlib_cli_command_t *cmd)
+{
+ clib_error_t *error = 0;
+ nat44_ei_sessions_clear ();
+ return error;
+}
+
+static clib_error_t *
+nat44_ei_del_session_command_fn (vlib_main_t *vm, unformat_input_t *input,
+ vlib_cli_command_t *cmd)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ unformat_input_t _line_input, *line_input = &_line_input;
+ u32 port = 0, vrf_id = nm->outside_vrf_id;
+ clib_error_t *error = 0;
+ nat_protocol_t proto;
+ ip4_address_t addr;
+ int rv, is_in = 0;
+
+ /* Get a line of input. */
+ if (!unformat_user (input, unformat_line_input, line_input))
+ return 0;
+
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (line_input, "%U:%u %U", unformat_ip4_address, &addr, &port,
+ unformat_nat_protocol, &proto))
+ ;
+ else if (unformat (line_input, "in"))
+ {
+ is_in = 1;
+ vrf_id = nm->inside_vrf_id;
+ }
+ else if (unformat (line_input, "out"))
+ {
+ is_in = 0;
+ vrf_id = nm->outside_vrf_id;
+ }
+ else if (unformat (line_input, "vrf %u", &vrf_id))
+ ;
+ else
+ {
+ error = clib_error_return (0, "unknown input '%U'",
+ format_unformat_error, line_input);
+ goto done;
+ }
+ }
+
+ rv = nat44_ei_del_session (nm, &addr, clib_host_to_net_u16 (port), proto,
+ vrf_id, is_in);
+
+ switch (rv)
+ {
+ case 0:
+ break;
+
+ default:
+ error = clib_error_return (0, "nat44_ei_del_session returned %d", rv);
+ goto done;
+ }
+
+done:
+ unformat_free (line_input);
+
+ return error;
+}
+
+static clib_error_t *
+nat44_ei_forwarding_set_command_fn (vlib_main_t *vm, unformat_input_t *input,
+ vlib_cli_command_t *cmd)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ unformat_input_t _line_input, *line_input = &_line_input;
+ u8 forwarding_enable;
+ u8 forwarding_enable_set = 0;
+ clib_error_t *error = 0;
+
+ /* Get a line of input. */
+ if (!unformat_user (input, unformat_line_input, line_input))
+ return clib_error_return (0, "'enable' or 'disable' expected");
+
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (!forwarding_enable_set && unformat (line_input, "enable"))
+ {
+ forwarding_enable = 1;
+ forwarding_enable_set = 1;
+ }
+ else if (!forwarding_enable_set && unformat (line_input, "disable"))
+ {
+ forwarding_enable = 0;
+ forwarding_enable_set = 1;
+ }
+ else
+ {
+ error = clib_error_return (0, "unknown input '%U'",
+ format_unformat_error, line_input);
+ goto done;
+ }
+ }
+
+ if (!forwarding_enable_set)
+ {
+ error = clib_error_return (0, "'enable' or 'disable' expected");
+ goto done;
+ }
+
+ nm->forwarding_enabled = forwarding_enable;
+
+done:
+ unformat_free (line_input);
+
+ return error;
+}
+
+static clib_error_t *
+set_timeout_command_fn (vlib_main_t *vm, unformat_input_t *input,
+ vlib_cli_command_t *cmd)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ unformat_input_t _line_input, *line_input = &_line_input;
+ clib_error_t *error = 0;
+
+ /* Get a line of input. */
+ if (!unformat_user (input, unformat_line_input, line_input))
+ return 0;
+
+ while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
+ {
+ if (unformat (line_input, "udp %u", &nm->timeouts.udp))
+ ;
+ else if (unformat (line_input, "tcp-established %u",
+ &nm->timeouts.tcp.established))
+ ;
+ else if (unformat (line_input, "tcp-transitory %u",
+ &nm->timeouts.tcp.transitory))
+ ;
+ else if (unformat (line_input, "icmp %u", &nm->timeouts.icmp))
+ ;
+ else if (unformat (line_input, "reset"))
+ nat_reset_timeouts (&nm->timeouts);
+ else
+ {
+ error = clib_error_return (0, "unknown input '%U'",
+ format_unformat_error, line_input);
+ goto done;
+ }
+ }
+done:
+ unformat_free (line_input);
+ return error;
+}
+
+static clib_error_t *
+nat_show_timeouts_command_fn (vlib_main_t *vm, unformat_input_t *input,
+ vlib_cli_command_t *cmd)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+
+ // TODO: make format timeout function
+ vlib_cli_output (vm, "udp timeout: %dsec", nm->timeouts.udp);
+ vlib_cli_output (vm, "tcp-established timeout: %dsec",
+ nm->timeouts.tcp.established);
+ vlib_cli_output (vm, "tcp-transitory timeout: %dsec",
+ nm->timeouts.tcp.transitory);
+ vlib_cli_output (vm, "icmp timeout: %dsec", nm->timeouts.icmp);
+
+ return 0;
+}
+
+/*?
+ * @cliexpar
+ * @cliexstart{nat44 ei enable}
+ * Enable nat44 ei plugin
+ * To enable nat44, use:
+ * vpp# nat44 ei enable sessions <n>
+ * To enable nat44 ei static mapping only, use:
+ * vpp# nat44 ei enable sessions <n> static-mapping
+ * To enable nat44 ei static mapping with connection tracking, use:
+ * vpp# nat44 ei enable sessions <n> static-mapping connection-tracking
+ * To enable nat44 ei out2in dpo, use:
+ * vpp# nat44 ei enable sessions <n> out2in-dpo
+ * To set inside-vrf outside-vrf, use:
+ * vpp# nat44 ei enable sessions <n> inside-vrf <id> outside-vrf <id>
+ * @cliexend
+?*/
+VLIB_CLI_COMMAND (nat44_ei_enable_command, static) = {
+ .path = "nat44 ei enable",
+ .short_help =
+ "nat44 ei enable sessions <max-number> [users <max-number>] "
+ "[static-mappig-only [connection-tracking]|out2in-dpo] [inside-vrf "
+ "<vrf-id>] [outside-vrf <vrf-id>] [user-sessions <max-number>]",
+ .function = nat44_ei_enable_command_fn,
+};
+
+/*?
+ * @cliexpar
+ * @cliexstart{nat44 ei disable}
+ * Disable nat44 ei plugin
+ * To disable nat44, use:
+ * vpp# nat44 ei disable
+ * @cliexend
+?*/
+VLIB_CLI_COMMAND (nat44_ei_disable_command, static) = {
+ .path = "nat44 ei disable",
+ .short_help = "nat44 ei disable",
+ .function = nat44_ei_disable_command_fn,
+};
+
+/*?
+ * @cliexpar
+ * @cliexstart{set snat44 ei workers}
+ * Set NAT workers if 2 or more workers available, use:
+ * vpp# set snat44 ei workers 0-2,5
+ * @cliexend
+?*/
+VLIB_CLI_COMMAND (set_workers_command, static) = {
+ .path = "set nat44 ei workers",
+ .function = set_workers_command_fn,
+ .short_help = "set nat44 ei workers <workers-list>",
+};
+
+/*?
+ * @cliexpar
+ * @cliexstart{show nat44 ei workers}
+ * Show NAT workers.
+ * vpp# show nat44 ei workers:
+ * 2 workers
+ * vpp_wk_0
+ * vpp_wk_1
+ * @cliexend
+?*/
+VLIB_CLI_COMMAND (nat_show_workers_command, static) = {
+ .path = "show nat44 ei workers",
+ .short_help = "show nat44 ei workers",
+ .function = nat_show_workers_commnad_fn,
+};
+
+/*?
+ * @cliexpar
+ * @cliexstart{set nat44 ei timeout}
+ * Set values of timeouts for NAT sessions (in seconds), use:
+ * vpp# set nat44 ei timeout udp 120 tcp-established 7500 tcp-transitory 250
+icmp 90
+ * To reset default values use:
+ * vpp# set nat44 ei timeout reset
+ * @cliexend
+?*/
+VLIB_CLI_COMMAND (set_timeout_command, static) = {
+ .path = "set nat44 ei timeout",
+ .function = set_timeout_command_fn,
+ .short_help = "set nat44 ei timeout [udp <sec> | tcp-established <sec> "
+ "tcp-transitory <sec> | icmp <sec> | reset]",
+};
+
+/*?
+ * @cliexpar
+ * @cliexstart{show nat44 ei timeouts}
+ * Show values of timeouts for NAT sessions.
+ * vpp# show nat44 ei timeouts
+ * udp timeout: 300sec
+ * tcp-established timeout: 7440sec
+ * tcp-transitory timeout: 240sec
+ * icmp timeout: 60sec
+ * @cliexend
+?*/
+VLIB_CLI_COMMAND (nat_show_timeouts_command, static) = {
+ .path = "show nat44 ei timeouts",
+ .short_help = "show nat44 ei timeouts",
+ .function = nat_show_timeouts_command_fn,
+};
+
+/*?
+ * @cliexpar
+ * @cliexstart{nat44 ei set logging level}
+ * To set NAT logging level use:
+ * Set nat44 ei logging level
+ * @cliexend
+?*/
+VLIB_CLI_COMMAND (nat44_ei_set_log_level_command, static) = {
+ .path = "nat44 ei set logging level",
+ .function = nat44_ei_set_log_level_command_fn,
+ .short_help = "nat44 ei set logging level <level>",
+};
+
+/*?
+ * @cliexpar
+ * @cliexstart{snat44 ei ipfix logging}
+ * To enable NAT IPFIX logging use:
+ * vpp# nat44 ei ipfix logging
+ * To set IPFIX exporter use:
+ * vpp# set ipfix exporter collector 10.10.10.3 src 10.10.10.1
+ * @cliexend
+?*/
+VLIB_CLI_COMMAND (nat44_ei_ipfix_logging_enable_disable_command, static) = {
+ .path = "nat44 ei ipfix logging",
+ .function = nat44_ei_ipfix_logging_enable_disable_command_fn,
+ .short_help =
+ "nat44 ei ipfix logging [domain <domain-id>] [src-port <port>] [disable]",
+};
+
+/*?
+ * @cliexpar
+ * @cliexstart{nat44 ei addr-port-assignment-alg}
+ * Set address and port assignment algorithm
+ * For the MAP-E CE limit port choice based on PSID use:
+ * vpp# nat44 ei addr-port-assignment-alg map-e psid 10 psid-offset 6 psid-len
+6
+ * For port range use:
+ * vpp# nat44 ei addr-port-assignment-alg port-range <start-port> - <end-port>
+ * To set standard (default) address and port assignment algorithm use:
+ * vpp# nat44 ei addr-port-assignment-alg default
+ * @cliexend
+?*/
+VLIB_CLI_COMMAND (nat44_ei_set_alloc_addr_and_port_alg_command, static) = {
+ .path = "nat44 ei addr-port-assignment-alg",
+ .short_help = "nat44 ei addr-port-assignment-alg <alg-name> [<alg-params>]",
+ .function = nat44_ei_set_alloc_addr_and_port_alg_command_fn,
+};
+
+/*?
+ * @cliexpar
+ * @cliexstart{show nat44 ei addr-port-assignment-alg}
+ * Show address and port assignment algorithm
+ * @cliexend
+?*/
+VLIB_CLI_COMMAND (nat44_ei_show_alloc_addr_and_port_alg_command, static) = {
+ .path = "show nat44 ei addr-port-assignment-alg",
+ .short_help = "show nat44 ei addr-port-assignment-alg",
+ .function = nat44_ei_show_alloc_addr_and_port_alg_command_fn,
+};
+
+/*?
+ * @cliexpar
+ * @cliexstart{nat44 ei mss-clamping}
+ * Set TCP MSS rewriting configuration
+ * To enable TCP MSS rewriting use:
+ * vpp# nat44 ei mss-clamping 1452
+ * To disbale TCP MSS rewriting use:
+ * vpp# nat44 ei mss-clamping disable
+ * @cliexend
+?*/
+VLIB_CLI_COMMAND (nat_set_mss_clamping_command, static) = {
+ .path = "nat44 ei mss-clamping",
+ .short_help = "nat44 ei mss-clamping <mss-value>|disable",
+ .function = nat_set_mss_clamping_command_fn,
+};
+
+/*?
+ * @cliexpar
+ * @cliexstart{show nat44 ei mss-clamping}
+ * Show TCP MSS rewriting configuration
+ * @cliexend
+?*/
+VLIB_CLI_COMMAND (nat_show_mss_clamping_command, static) = {
+ .path = "show nat44 ei mss-clamping",
+ .short_help = "show nat44 ei mss-clamping",
+ .function = nat_show_mss_clamping_command_fn,
+};
+
+/*?
+ * @cliexpar
+ * @cliexstart{nat44 ei ha failover}
+ * Set HA failover (remote settings)
+ * @cliexend
+?*/
+VLIB_CLI_COMMAND (nat_ha_failover_command, static) = {
+ .path = "nat44 ei ha failover",
+ .short_help =
+ "nat44 ei ha failover <ip4-address>:<port> [refresh-interval <sec>]",
+ .function = nat_ha_failover_command_fn,
+};
+
+/*?
+ * @cliexpar
+ * @cliexstart{nat44 ei ha listener}
+ * Set HA listener (local settings)
+ * @cliexend
+?*/
+VLIB_CLI_COMMAND (nat_ha_listener_command, static) = {
+ .path = "nat44 ei ha listener",
+ .short_help =
+ "nat44 ei ha listener <ip4-address>:<port> [path-mtu <path-mtu>]",
+ .function = nat_ha_listener_command_fn,
+};
+
+/*?
+ * @cliexpar
+ * @cliexstart{show nat44 ei ha}
+ * Show HA configuration/status
+ * @cliexend
+?*/
+VLIB_CLI_COMMAND (nat_show_ha_command, static) = {
+ .path = "show nat44 ei ha",
+ .short_help = "show nat44 ei ha",
+ .function = nat_show_ha_command_fn,
+};
+
+/*?
+ * @cliexpar
+ * @cliexstart{nat44 ei ha flush}
+ * Flush the current HA data (for testing)
+ * @cliexend
+?*/
+VLIB_CLI_COMMAND (nat_ha_flush_command, static) = {
+ .path = "nat44 ei ha flush",
+ .short_help = "nat44 ei ha flush",
+ .function = nat_ha_flush_command_fn,
+};
+
+/*?
+ * @cliexpar
+ * @cliexstart{nat44 ei ha resync}
+ * Resync HA (resend existing sessions to new failover)
+ * @cliexend
+?*/
+VLIB_CLI_COMMAND (nat_ha_resync_command, static) = {
+ .path = "nat44 ei ha resync",
+ .short_help = "nat44 ei ha resync",
+ .function = nat_ha_resync_command_fn,
+};
+
+/*?
+ * @cliexpar
+ * @cliexstart{show nat44 ei hash tables}
+ * Show NAT44 hash tables
+ * @cliexend
+?*/
+VLIB_CLI_COMMAND (nat44_ei_show_hash, static) = {
+ .path = "show nat44 ei hash tables",
+ .short_help = "show nat44 ei hash tables [detail|verbose]",
+ .function = nat44_ei_show_hash_command_fn,
+};
+
+/*?
+ * @cliexpar
+ * @cliexstart{nat44 ei add address}
+ * Add/delete NAT44 pool address.
+ * To add NAT44 pool address use:
+ * vpp# nat44 ei add address 172.16.1.3
+ * vpp# nat44 ei add address 172.16.2.2 - 172.16.2.24
+ * To add NAT44 pool address for specific tenant (identified by VRF id) use:
+ * vpp# nat44 ei add address 172.16.1.3 tenant-vrf 10
+ * @cliexend
+?*/
+VLIB_CLI_COMMAND (add_address_command, static) = {
+ .path = "nat44 ei add address",
+ .short_help = "nat44 ei add address <ip4-range-start> [- <ip4-range-end>] "
+ "[tenant-vrf <vrf-id>] [del]",
+ .function = add_address_command_fn,
+};
+
+/*?
+ * @cliexpar
+ * @cliexstart{show nat44 ei addresses}
+ * Show NAT44 pool addresses.
+ * vpp# show nat44 ei addresses
+ * NAT44 pool addresses:
+ * 172.16.2.2
+ * tenant VRF independent
+ * 10 busy udp ports
+ * 0 busy tcp ports
+ * 0 busy icmp ports
+ * 172.16.1.3
+ * tenant VRF: 10
+ * 0 busy udp ports
+ * 2 busy tcp ports
+ * 0 busy icmp ports
+ * @cliexend
+?*/
+VLIB_CLI_COMMAND (nat44_ei_show_addresses_command, static) = {
+ .path = "show nat44 ei addresses",
+ .short_help = "show nat44 ei addresses",
+ .function = nat44_ei_show_addresses_command_fn,
+};
+
+/*?
+ * @cliexpar
+ * @cliexstart{set interface nat44}
+ * Enable/disable NAT44 feature on the interface.
+ * To enable NAT44 feature with local network interface use:
+ * vpp# set interface nat44 ei in GigabitEthernet0/8/0
+ * To enable NAT44 feature with external network interface use:
+ * vpp# set interface nat44 ei out GigabitEthernet0/a/0
+ * @cliexend
+?*/
+VLIB_CLI_COMMAND (set_interface_nat44_ei_command, static) = {
+ .path = "set interface nat44 ei",
+ .function = nat44_ei_feature_command_fn,
+ .short_help =
+ "set interface nat44 ei in <intfc> out <intfc> [output-feature] "
+ "[del]",
+};
+
+/*?
+ * @cliexpar
+ * @cliexstart{show nat44 ei interfaces}
+ * Show interfaces with NAT44 feature.
+ * vpp# show nat44 ei interfaces
+ * NAT44 interfaces:
+ * GigabitEthernet0/8/0 in
+ * GigabitEthernet0/a/0 out
+ * @cliexend
+?*/
+VLIB_CLI_COMMAND (nat44_ei_show_interfaces_command, static) = {
+ .path = "show nat44 ei interfaces",
+ .short_help = "show nat44 ei interfaces",
+ .function = nat44_ei_show_interfaces_command_fn,
+};
+
+/*?
+ * @cliexpar
+ * @cliexstart{nat44 ei add static mapping}
+ * Static mapping allows hosts on the external network to initiate connection
+ * to to the local network host.
+ * To create static mapping between local host address 10.0.0.3 port 6303 and
+ * external address 4.4.4.4 port 3606 for TCP protocol use:
+ * vpp# nat44 ei add static mapping tcp local 10.0.0.3 6303 external 4.4.4.4
+3606
+ * If not runnig "static mapping only" NAT plugin mode use before:
+ * vpp# nat44 ei add address 4.4.4.4
+ * To create address only static mapping between local and external address
+use:
+ * vpp# nat44 ei add static mapping local 10.0.0.3 external 4.4.4.4
+ * To create ICMP static mapping between local and external with ICMP echo
+ * identifier 10 use:
+ * vpp# nat44 ei add static mapping icmp local 10.0.0.3 10 external 4.4.4.4 10
+ * @cliexend
+?*/
+VLIB_CLI_COMMAND (add_static_mapping_command, static) = {
+ .path = "nat44 ei add static mapping",
+ .function = add_static_mapping_command_fn,
+ .short_help = "nat44 ei add static mapping tcp|udp|icmp local <addr> "
+ "[<port|icmp-echo-id>] "
+ "external <addr> [<port|icmp-echo-id>] [vrf <table-id>] [del]",
+};
+
+/*?
+ * @cliexpar
+ * @cliexstart{nat44 ei add identity mapping}
+ * Identity mapping translate an IP address to itself.
+ * To create identity mapping for address 10.0.0.3 port 6303 for TCP protocol
+ * use:
+ * vpp# nat44 ei add identity mapping 10.0.0.3 tcp 6303
+ * To create identity mapping for address 10.0.0.3 use:
+ * vpp# nat44 ei add identity mapping 10.0.0.3
+ * To create identity mapping for DHCP addressed interface use:
+ * vpp# nat44 ei add identity mapping external GigabitEthernet0/a/0 tcp 3606
+ * @cliexend
+?*/
+VLIB_CLI_COMMAND (add_identity_mapping_command, static) = {
+ .path = "nat44 ei add identity mapping",
+ .function = add_identity_mapping_command_fn,
+ .short_help =
+ "nat44 ei add identity mapping <ip4-addr>|external <interface> "
+ "[<protocol> <port>] [vrf <table-id>] [del]",
+};
+
+/*?
+ * @cliexpar
+ * @cliexstart{show nat44 ei static mappings}
+ * Show NAT44 static mappings.
+ * vpp# show nat44 ei static mappings
+ * NAT44 static mappings:
+ * local 10.0.0.3 external 4.4.4.4 vrf 0
+ * tcp local 192.168.0.4:6303 external 4.4.4.3:3606 vrf 0
+ * tcp vrf 0 external 1.2.3.4:80
+ * local 10.100.10.10:8080 probability 80
+ * local 10.100.10.20:8080 probability 20
+ * tcp local 10.0.0.10:3603 external GigabitEthernet0/a/0:6306 vrf 10
+ * @cliexend
+?*/
+VLIB_CLI_COMMAND (nat44_ei_show_static_mappings_command, static) = {
+ .path = "show nat44 ei static mappings",
+ .short_help = "show nat44 ei static mappings",
+ .function = nat44_ei_show_static_mappings_command_fn,
+};
+
+/*?
+ * @cliexpar
+ * @cliexstart{nat44 ei add interface address}
+ * Use NAT44 pool address from specific interfce
+ * To add NAT44 pool address from specific interface use:
+ * vpp# nat44 ei add interface address GigabitEthernet0/8/0
+ * @cliexend
+?*/
+VLIB_CLI_COMMAND (nat44_ei_add_interface_address_command, static) = {
+ .path = "nat44 ei add interface address",
+ .short_help = "nat44 ei add interface address <interface> [del]",
+ .function = nat44_ei_add_interface_address_command_fn,
+};
+
+/*?
+ * @cliexpar
+ * @cliexstart{show nat44 ei interface address}
+ * Show NAT44 pool address interfaces
+ * vpp# show nat44 ei interface address
+ * NAT44 pool address interfaces:
+ * GigabitEthernet0/a/0
+ * @cliexend
+?*/
+VLIB_CLI_COMMAND (nat44_ei_show_interface_address_command, static) = {
+ .path = "show nat44 ei interface address",
+ .short_help = "show nat44 ei interface address",
+ .function = nat44_ei_show_interface_address_command_fn,
+};
+
+/*?
+ * @cliexpar
+ * @cliexstart{show nat44 ei sessions}
+ * Show NAT44 sessions.
+ * @cliexend
+?*/
+VLIB_CLI_COMMAND (nat44_ei_show_sessions_command, static) = {
+ .path = "show nat44 ei sessions",
+ .short_help = "show nat44 ei sessions [detail|metrics]",
+ .function = nat44_ei_show_sessions_command_fn,
+};
+
+/*?
+ * @cliexpar
+ * @cliexstart{nat44 ei del user}
+ * To delete all NAT44 user sessions:
+ * vpp# nat44 ei del user 10.0.0.3
+ * @cliexend
+?*/
+VLIB_CLI_COMMAND (nat44_ei_del_user_command, static) = {
+ .path = "nat44 ei del user",
+ .short_help = "nat44 ei del user <addr> [fib <index>]",
+ .function = nat44_ei_del_user_command_fn,
+};
+
+/*?
+ * @cliexpar
+ * @cliexstart{clear nat44 ei sessions}
+ * To clear all NAT44 sessions
+ * vpp# clear nat44 ei sessions
+ * @cliexend
+?*/
+VLIB_CLI_COMMAND (nat44_ei_clear_sessions_command, static) = {
+ .path = "clear nat44 ei sessions",
+ .short_help = "clear nat44 ei sessions",
+ .function = nat44_ei_clear_sessions_command_fn,
+};
+
+/*?
+ * @cliexpar
+ * @cliexstart{nat44 ei del session}
+ * To administratively delete NAT44 session by inside address and port use:
+ * vpp# nat44 ei del session in 10.0.0.3:6303 tcp
+ * To administratively delete NAT44 session by outside address and port use:
+ * vpp# nat44 ei del session out 1.0.0.3:6033 udp
+ * @cliexend
+?*/
+VLIB_CLI_COMMAND (nat44_ei_del_session_command, static) = {
+ .path = "nat44 ei del session",
+ .short_help = "nat44 ei del session in|out <addr>:<port> tcp|udp|icmp [vrf "
+ "<id>] [external-host <addr>:<port>]",
+ .function = nat44_ei_del_session_command_fn,
+};
+
+/*?
+ * @cliexpar
+ * @cliexstart{nat44 ei forwarding}
+ * Enable or disable forwarding
+ * Forward packets which don't match existing translation
+ * or static mapping instead of dropping them.
+ * To enable forwarding, use:
+ * vpp# nat44 ei forwarding enable
+ * To disable forwarding, use:
+ * vpp# nat44 ei forwarding disable
+ * @cliexend
+?*/
+VLIB_CLI_COMMAND (nat44_ei_forwarding_set_command, static) = {
+ .path = "nat44 ei forwarding",
+ .short_help = "nat44 ei forwarding enable|disable",
+ .function = nat44_ei_forwarding_set_command_fn,
+};
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/src/plugins/nat/nat_dpo.c b/src/plugins/nat/nat44-ei/nat44_ei_dpo.c
index 46ccda8845e..51016df549f 100644
--- a/src/plugins/nat/nat_dpo.c
+++ b/src/plugins/nat/nat44-ei/nat44_ei_dpo.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017 Cisco and/or its affiliates.
+ * Copyright (c) 2020 Cisco and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
@@ -14,18 +14,18 @@
*/
#include <vnet/ip/ip.h>
-#include <nat/nat_dpo.h>
+#include <nat/nat44-ei/nat44_ei_dpo.h>
dpo_type_t nat_dpo_type;
void
-nat_dpo_create (dpo_proto_t dproto, u32 aftr_index, dpo_id_t * dpo)
+nat_dpo_create (dpo_proto_t dproto, u32 aftr_index, dpo_id_t *dpo)
{
dpo_set (dpo, nat_dpo_type, dproto, aftr_index);
}
u8 *
-format_nat_dpo (u8 * s, va_list * args)
+format_nat_dpo (u8 *s, va_list *args)
{
index_t index = va_arg (*args, index_t);
CLIB_UNUSED (u32 indent) = va_arg (*args, u32);
@@ -34,12 +34,12 @@ format_nat_dpo (u8 * s, va_list * args)
}
static void
-nat_dpo_lock (dpo_id_t * dpo)
+nat_dpo_lock (dpo_id_t *dpo)
{
}
static void
-nat_dpo_unlock (dpo_id_t * dpo)
+nat_dpo_unlock (dpo_id_t *dpo)
{
}
@@ -50,7 +50,7 @@ const static dpo_vft_t nat_dpo_vft = {
};
const static char *const nat_ip4_nodes[] = {
- "nat44-out2in",
+ "nat44-ei-out2in",
NULL,
};
diff --git a/src/plugins/nat/nat_dpo.h b/src/plugins/nat/nat44-ei/nat44_ei_dpo.h
index e85b3e824f3..9a5ce5b7781 100644
--- a/src/plugins/nat/nat_dpo.h
+++ b/src/plugins/nat/nat44-ei/nat44_ei_dpo.h
@@ -19,9 +19,9 @@
#include <vnet/vnet.h>
#include <vnet/dpo/dpo.h>
-void nat_dpo_create (dpo_proto_t dproto, u32 aftr_index, dpo_id_t * dpo);
+void nat_dpo_create (dpo_proto_t dproto, u32 aftr_index, dpo_id_t *dpo);
-u8 *format_nat_dpo (u8 * s, va_list * args);
+u8 *format_nat_dpo (u8 *s, va_list *args);
void nat_dpo_module_init (void);
diff --git a/src/plugins/nat/nat44-ei/nat44_ei_ha.c b/src/plugins/nat/nat44-ei/nat44_ei_ha.c
index aea758af2d4..ca99efcf8ca 100644
--- a/src/plugins/nat/nat44-ei/nat44_ei_ha.c
+++ b/src/plugins/nat/nat44-ei/nat44_ei_ha.c
@@ -13,13 +13,17 @@
* limitations under the License.
*/
-#include <nat/nat_inlines.h>
-#include <nat/nat44/ed_inlines.h>
-#include <nat/nat44-ei/nat44_ei_ha.h>
+//#include <vnet/fib/fib_source.h>
+#include <vnet/fib/fib_table.h>
#include <vnet/udp/udp_local.h>
-#include <nat/nat.h>
#include <vppinfra/atomics.h>
+#include <nat/lib/log.h>
+
+#include <nat/nat44-ei/nat44_ei.h>
+#include <nat/nat44-ei/nat44_ei_ha.h>
+#include <nat/nat44-ei/nat44_ei_inlines.h>
+
/* number of retries */
#define NAT_HA_RETRIES 3
@@ -173,14 +177,14 @@ nat44_ei_ha_sadd (ip4_address_t *in_addr, u16 in_port, ip4_address_t *out_addr,
ip4_address_t *ehn_addr, u16 ehn_port, u8 proto,
u32 fib_index, u16 flags, u32 thread_index)
{
- snat_main_t *sm = &snat_main;
- snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
- snat_user_t *u;
- snat_session_t *s;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nat44_ei_main_per_thread_data_t *tnm = &nm->per_thread_data[thread_index];
+ nat44_ei_user_t *u;
+ nat44_ei_session_t *s;
clib_bihash_kv_8_8_t kv;
vlib_main_t *vm = vlib_get_main ();
f64 now = vlib_time_now (vm);
- nat_outside_fib_t *outside_fib;
+ nat44_ei_outside_fib_t *outside_fib;
fib_node_index_t fei = FIB_NODE_INDEX_INVALID;
fib_prefix_t pfx = {
.fp_proto = FIB_PROTOCOL_IP4,
@@ -190,26 +194,21 @@ nat44_ei_ha_sadd (ip4_address_t *in_addr, u16 in_port, ip4_address_t *out_addr,
},
};
- if (!(flags & SNAT_SESSION_FLAG_STATIC_MAPPING))
+ if (!(flags & NAT44_EI_SESSION_FLAG_STATIC_MAPPING))
{
- if (nat_set_outside_address_and_port (sm->addresses, thread_index,
- *out_addr, out_port, proto))
+ if (nat44_ei_set_outside_address_and_port (nm->addresses, thread_index,
+ *out_addr, out_port, proto))
return;
}
- u = nat_user_get_or_create (sm, in_addr, fib_index, thread_index);
+ u = nat44_ei_user_get_or_create (nm, in_addr, fib_index, thread_index);
if (!u)
return;
- s = nat_session_alloc_or_recycle (sm, u, thread_index, now);
+ s = nat44_ei_session_alloc_or_recycle (nm, u, thread_index, now);
if (!s)
return;
- if (sm->endpoint_dependent)
- {
- nat_ed_lru_insert (tsm, s, now, nat_proto_to_ip_proto (proto));
- }
-
s->out2in.addr.as_u32 = out_addr->as_u32;
s->out2in.port = out_port;
s->nat_proto = proto;
@@ -217,17 +216,17 @@ nat44_ei_ha_sadd (ip4_address_t *in_addr, u16 in_port, ip4_address_t *out_addr,
s->flags = flags;
s->ext_host_addr.as_u32 = eh_addr->as_u32;
s->ext_host_port = eh_port;
- user_session_increment (sm, u, snat_is_session_static (s));
- switch (vec_len (sm->outside_fibs))
+ nat44_ei_user_session_increment (nm, u, nat44_ei_is_session_static (s));
+ switch (vec_len (nm->outside_fibs))
{
case 0:
- s->out2in.fib_index = sm->outside_fib_index;
+ s->out2in.fib_index = nm->outside_fib_index;
break;
case 1:
- s->out2in.fib_index = sm->outside_fibs[0].fib_index;
+ s->out2in.fib_index = nm->outside_fibs[0].fib_index;
break;
default:
- vec_foreach (outside_fib, sm->outside_fibs)
+ vec_foreach (outside_fib, nm->outside_fibs)
{
fei = fib_table_lookup (outside_fib->fib_index, &pfx);
if (FIB_NODE_INDEX_INVALID != fei)
@@ -241,16 +240,16 @@ nat44_ei_ha_sadd (ip4_address_t *in_addr, u16 in_port, ip4_address_t *out_addr,
}
break;
}
- init_nat_o2i_kv (&kv, s, thread_index, s - tsm->sessions);
- if (clib_bihash_add_del_8_8 (&sm->out2in, &kv, 1))
- nat_elog_warn ("out2in key add failed");
+ init_nat_o2i_kv (&kv, s, thread_index, s - tnm->sessions);
+ if (clib_bihash_add_del_8_8 (&nm->out2in, &kv, 1))
+ nat_elog_warn (nm, "out2in key add failed");
s->in2out.addr.as_u32 = in_addr->as_u32;
s->in2out.port = in_port;
s->in2out.fib_index = fib_index;
- init_nat_i2o_kv (&kv, s, thread_index, s - tsm->sessions);
- if (clib_bihash_add_del_8_8 (&sm->in2out, &kv, 1))
- nat_elog_warn ("in2out key add failed");
+ init_nat_i2o_kv (&kv, s, thread_index, s - tnm->sessions);
+ if (clib_bihash_add_del_8_8 (&nm->in2out, &kv, 1))
+ nat_elog_warn (nm, "in2out key add failed");
}
static_always_inline void
@@ -258,27 +257,27 @@ nat44_ei_ha_sdel (ip4_address_t *out_addr, u16 out_port,
ip4_address_t *eh_addr, u16 eh_port, u8 proto, u32 fib_index,
u32 ti)
{
- snat_main_t *sm = &snat_main;
+ nat44_ei_main_t *nm = &nat44_ei_main;
clib_bihash_kv_8_8_t kv, value;
u32 thread_index;
- snat_session_t *s;
- snat_main_per_thread_data_t *tsm;
+ nat44_ei_session_t *s;
+ nat44_ei_main_per_thread_data_t *tnm;
- if (sm->num_workers > 1)
- thread_index = sm->first_worker_index +
- (sm->workers[(clib_net_to_host_u16 (out_port) - 1024) /
- sm->port_per_thread]);
+ if (nm->num_workers > 1)
+ thread_index = nm->first_worker_index +
+ (nm->workers[(clib_net_to_host_u16 (out_port) - 1024) /
+ nm->port_per_thread]);
else
- thread_index = sm->num_workers;
- tsm = vec_elt_at_index (sm->per_thread_data, thread_index);
+ thread_index = nm->num_workers;
+ tnm = vec_elt_at_index (nm->per_thread_data, thread_index);
init_nat_k (&kv, *out_addr, out_port, fib_index, proto);
- if (clib_bihash_search_8_8 (&sm->out2in, &kv, &value))
+ if (clib_bihash_search_8_8 (&nm->out2in, &kv, &value))
return;
- s = pool_elt_at_index (tsm->sessions, nat_value_get_session_index (&value));
- nat_free_session_data (sm, s, thread_index, 1);
- nat44_delete_session (sm, s, thread_index);
+ s = pool_elt_at_index (tnm->sessions, nat_value_get_session_index (&value));
+ nat44_ei_free_session_data_v2 (nm, s, thread_index, 1);
+ nat44_ei_delete_session (nm, s, thread_index);
}
static_always_inline void
@@ -286,18 +285,18 @@ nat44_ei_ha_sref (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)
{
- snat_main_t *sm = &snat_main;
+ nat44_ei_main_t *nm = &nat44_ei_main;
clib_bihash_kv_8_8_t kv, value;
- snat_session_t *s;
- snat_main_per_thread_data_t *tsm;
+ nat44_ei_session_t *s;
+ nat44_ei_main_per_thread_data_t *tnm;
- tsm = vec_elt_at_index (sm->per_thread_data, thread_index);
+ tnm = vec_elt_at_index (nm->per_thread_data, thread_index);
init_nat_k (&kv, *out_addr, out_port, fib_index, proto);
- if (clib_bihash_search_8_8 (&sm->out2in, &kv, &value))
+ if (clib_bihash_search_8_8 (&nm->out2in, &kv, &value))
return;
- s = pool_elt_at_index (tsm->sessions, nat_value_get_session_index (&value));
+ s = pool_elt_at_index (tnm->sessions, nat_value_get_session_index (&value));
s->total_pkts = total_pkts;
s->total_bytes = total_bytes;
}
@@ -305,6 +304,7 @@ nat44_ei_ha_sref (ip4_address_t *out_addr, u16 out_port,
static void
nat_ha_resync_fin (void)
{
+ nat44_ei_main_t *nm = &nat44_ei_main;
nat_ha_main_t *ha = &nat_ha_main;
/* if no more resync ACK remainig we are done */
@@ -314,11 +314,11 @@ nat_ha_resync_fin (void)
ha->in_resync = 0;
if (ha->resync_ack_missed)
{
- nat_elog_info ("resync completed with result FAILED");
+ nat_elog_info (nm, "resync completed with result FAILED");
}
else
{
- nat_elog_info ("resync completed with result SUCCESS");
+ nat_elog_info (nm, "resync completed with result SUCCESS");
}
if (ha->event_callback)
ha->event_callback (ha->client_index, ha->pid, ha->resync_ack_missed);
@@ -347,6 +347,7 @@ nat_ha_resend_queue_add (u32 seq, u8 * data, u8 data_len, u8 is_resync,
static_always_inline void
nat_ha_ack_recv (u32 seq, u32 thread_index)
{
+ nat44_ei_main_t *nm = &nat44_ei_main;
nat_ha_main_t *ha = &nat_ha_main;
nat_ha_per_thread_data_t *td = &ha->per_thread_data[thread_index];
u32 i;
@@ -366,7 +367,7 @@ nat_ha_ack_recv (u32 seq, u32 thread_index)
}
vec_free (td->resend_queue[i].data);
vec_del1 (td->resend_queue, i);
- nat_elog_debug_X1 ("ACK for seq %d received", "i4",
+ nat_elog_debug_X1 (nm, "ACK for seq %d received", "i4",
clib_net_to_host_u32 (seq));
return;
@@ -377,6 +378,7 @@ nat_ha_ack_recv (u32 seq, u32 thread_index)
static void
nat_ha_resend_scan (f64 now, u32 thread_index)
{
+ nat44_ei_main_t *nm = &nat44_ei_main;
nat_ha_main_t *ha = &nat_ha_main;
nat_ha_per_thread_data_t *td = &ha->per_thread_data[thread_index];
u32 i, *del, *to_delete = 0;
@@ -394,7 +396,7 @@ nat_ha_resend_scan (f64 now, u32 thread_index)
/* maximum retry reached delete cached data */
if (td->resend_queue[i].retry_count >= NAT_HA_RETRIES)
{
- nat_elog_notice_X1 ("seq %d missed", "i4",
+ nat_elog_notice_X1 (nm, "seq %d missed", "i4",
clib_net_to_host_u32 (td->resend_queue[i].seq));
if (td->resend_queue[i].is_resync)
{
@@ -410,14 +412,14 @@ nat_ha_resend_scan (f64 now, u32 thread_index)
}
/* retry to send non-ACKed data */
- nat_elog_debug_X1 ("state sync seq %d resend", "i4",
+ nat_elog_debug_X1 (nm, "state sync seq %d resend", "i4",
clib_net_to_host_u32 (td->resend_queue[i].seq));
td->resend_queue[i].retry_count++;
vlib_increment_simple_counter (&ha->counters[NAT_HA_COUNTER_RETRY_COUNT],
thread_index, 0, 1);
if (vlib_buffer_alloc (vm, &bi, 1) != 1)
{
- nat_elog_warn ("HA NAT state sync can't allocate buffer");
+ nat_elog_warn (nm, "HA NAT state sync can't allocate buffer");
return;
}
b = vlib_get_buffer (vm, bi);
@@ -465,13 +467,13 @@ nat_ha_set_node_indexes (nat_ha_main_t *ha, vlib_main_t *vm)
{
vlib_node_t *node;
- node = vlib_get_node_by_name (vm, (u8 *) "nat-ha-handoff");
+ node = vlib_get_node_by_name (vm, (u8 *) "nat44-ei-ha-handoff");
ha->ha_handoff_node_index = node->index;
- node = vlib_get_node_by_name (vm, (u8 *) "nat-ha-process");
+ node = vlib_get_node_by_name (vm, (u8 *) "nat44-ei-ha-process");
ha->ha_process_node_index = node->index;
- node = vlib_get_node_by_name (vm, (u8 *) "nat-ha-worker");
+ node = vlib_get_node_by_name (vm, (u8 *) "nat44-ei-ha-worker");
ha->ha_worker_node_index = node->index;
- node = vlib_get_node_by_name (vm, (u8 *) "nat-ha");
+ node = vlib_get_node_by_name (vm, (u8 *) "nat44-ei-ha");
ha->ha_node_index = node->index;
}
@@ -489,10 +491,11 @@ nat_ha_init (vlib_main_t * vm, u32 num_workers, u32 num_threads)
ha->num_workers = num_workers;
vec_validate (ha->per_thread_data, num_threads);
-#define _(N, s, v) ha->counters[v].name = s; \
- ha->counters[v].stat_segment_name = "/nat44/ha/" s; \
- vlib_validate_simple_counter(&ha->counters[v], 0); \
- vlib_zero_simple_counter(&ha->counters[v], 0);
+#define _(N, s, v) \
+ ha->counters[v].name = s; \
+ ha->counters[v].stat_segment_name = "/nat44-ei/ha/" s; \
+ vlib_validate_simple_counter (&ha->counters[v], 0); \
+ vlib_zero_simple_counter (&ha->counters[v], 0);
foreach_nat_ha_counter
#undef _
}
@@ -500,6 +503,7 @@ nat_ha_init (vlib_main_t * vm, u32 num_workers, u32 num_threads)
int
nat_ha_set_listener (ip4_address_t * addr, u16 port, u32 path_mtu)
{
+ nat44_ei_main_t *nm = &nat44_ei_main;
nat_ha_main_t *ha = &nat_ha_main;
/* unregister previously set UDP port */
@@ -524,7 +528,8 @@ nat_ha_set_listener (ip4_address_t * addr, u16 port, u32 path_mtu)
{
udp_register_dst_port (ha->vlib_main, port, ha->ha_node_index, 1);
}
- nat_elog_info_X1 ("HA listening on port %d for state sync", "i4", port);
+ nat_elog_info_X1 (nm, "HA listening on port %d for state sync", "i4",
+ port);
}
return 0;
@@ -633,6 +638,7 @@ nat_ha_recv_refresh (nat_ha_event_t * event, f64 now, u32 thread_index)
static_always_inline void
nat_ha_event_process (nat_ha_event_t * event, f64 now, u32 thread_index)
{
+ nat44_ei_main_t *nm = &nat44_ei_main;
switch (event->event_type)
{
case NAT_HA_ADD:
@@ -645,7 +651,7 @@ nat_ha_event_process (nat_ha_event_t * event, f64 now, u32 thread_index)
nat_ha_recv_refresh (event, now, thread_index);
break;
default:
- nat_elog_notice_X1 ("Unsupported HA event type %d", "i4",
+ nat_elog_notice_X1 (nm, "Unsupported HA event type %d", "i4",
event->event_type);
break;
}
@@ -728,6 +734,7 @@ static_always_inline void
nat_ha_event_add (nat_ha_event_t * event, u8 do_flush, u32 thread_index,
u8 is_resync)
{
+ nat44_ei_main_t *nm = &nat44_ei_main;
nat_ha_main_t *ha = &nat_ha_main;
nat_ha_per_thread_data_t *td = &ha->per_thread_data[thread_index];
vlib_main_t *vm = vlib_mains[thread_index];
@@ -744,7 +751,7 @@ nat_ha_event_add (nat_ha_event_t * event, u8 do_flush, u32 thread_index,
if (vlib_buffer_alloc (vm, &bi, 1) != 1)
{
- nat_elog_warn ("HA NAT state sync can't allocate buffer");
+ nat_elog_warn (nm, "HA NAT state sync can't allocate buffer");
return;
}
@@ -932,10 +939,10 @@ nat_ha_worker_fn (vlib_main_t * vm, vlib_node_runtime_t * rt,
/* *INDENT-OFF* */
VLIB_REGISTER_NODE (nat_ha_worker_node) = {
- .function = nat_ha_worker_fn,
- .type = VLIB_NODE_TYPE_INPUT,
- .state = VLIB_NODE_STATE_INTERRUPT,
- .name = "nat-ha-worker",
+ .function = nat_ha_worker_fn,
+ .type = VLIB_NODE_TYPE_INPUT,
+ .state = VLIB_NODE_STATE_INTERRUPT,
+ .name = "nat44-ei-ha-worker",
};
/* *INDENT-ON* */
@@ -943,6 +950,7 @@ VLIB_REGISTER_NODE (nat_ha_worker_node) = {
static uword
nat_ha_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f)
{
+ nat44_ei_main_t *nm = &nat44_ei_main;
nat_ha_main_t *ha = &nat_ha_main;
uword event_type;
uword *event_data = 0;
@@ -951,7 +959,7 @@ nat_ha_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f)
vlib_process_wait_for_event (vm);
event_type = vlib_process_get_events (vm, &event_data);
if (event_type)
- nat_elog_info ("nat-ha-process: bogus kickoff event received");
+ nat_elog_info (nm, "nat44-ei-ha-process: bogus kickoff event received");
vec_reset_length (event_data);
while (1)
@@ -974,9 +982,9 @@ nat_ha_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f)
/* *INDENT-OFF* */
VLIB_REGISTER_NODE (nat_ha_process_node) = {
- .function = nat_ha_process,
- .type = VLIB_NODE_TYPE_PROCESS,
- .name = "nat-ha-process",
+ .function = nat_ha_process,
+ .type = VLIB_NODE_TYPE_PROCESS,
+ .name = "nat44-ei-ha-process",
};
/* *INDENT-ON* */
@@ -1002,9 +1010,8 @@ format_nat_ha_trace (u8 * s, va_list * args)
CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
nat_ha_trace_t *t = va_arg (*args, nat_ha_trace_t *);
- s =
- format (s, "nat-ha: %u events from %U", t->event_count,
- format_ip4_address, &t->addr);
+ s = format (s, "nat44-ei-ha: %u events from %U", t->event_count,
+ format_ip4_address, &t->addr);
return s;
}
@@ -1173,7 +1180,7 @@ nat_ha_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
/* *INDENT-OFF* */
VLIB_REGISTER_NODE (nat_ha_node) = {
.function = nat_ha_node_fn,
- .name = "nat-ha",
+ .name = "nat44-ei-ha",
.vector_size = sizeof (u32),
.format_trace = format_nat_ha_trace,
.type = VLIB_NODE_TYPE_INTERNAL,
@@ -1294,7 +1301,7 @@ nat_ha_resync (u32 client_index, u32 pid,
/* *INDENT-OFF* */
VLIB_REGISTER_NODE (nat_ha_handoff_node) = {
.function = nat_ha_handoff_node_fn,
- .name = "nat-ha-handoff",
+ .name = "nat44-ei-ha-handoff",
.vector_size = sizeof (u32),
.format_trace = format_nat_ha_handoff_trace,
.type = VLIB_NODE_TYPE_INTERNAL,
diff --git a/src/plugins/nat/nat44-ei/nat44_ei_ha.h b/src/plugins/nat/nat44-ei/nat44_ei_ha.h
index 5639c8d0239..c466d4c9288 100644
--- a/src/plugins/nat/nat44-ei/nat44_ei_ha.h
+++ b/src/plugins/nat/nat44-ei/nat44_ei_ha.h
@@ -22,7 +22,6 @@
#include <vnet/vnet.h>
#include <vnet/ip/ip.h>
-#include <nat/nat.h>
/* Call back functions for received HA events on passive/failover */
typedef void (*nat_ha_sadd_cb_t) (ip4_address_t * in_addr, u16 in_port,
@@ -31,7 +30,6 @@ typedef void (*nat_ha_sadd_cb_t) (ip4_address_t * in_addr, u16 in_port,
ip4_address_t * ehn_addr, u16 ehn_port,
u8 proto, u32 fib_index, u16 flags,
u32 thread_index);
-
typedef void (*nat_ha_sdel_cb_t) (ip4_address_t * out_addr, u16 out_port,
ip4_address_t * eh_addr, u16 eh_port,
u8 proto, u32 fib_index, u32 thread_index);
diff --git a/src/plugins/nat/nat44_hairpinning.c b/src/plugins/nat/nat44-ei/nat44_ei_hairpinning.c
index a2cb2eb7547..0de2de1faf4 100644
--- a/src/plugins/nat/nat44_hairpinning.c
+++ b/src/plugins/nat/nat44-ei/nat44_ei_hairpinning.c
@@ -1,45 +1,46 @@
/*
- * Copyright (c) 2018 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
+ * nat44_ei.c - nat44 endpoint dependent plugin
+ * * Copyright (c) 2020 Cisco and/or its affiliates. * Licensed under the
+ * Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License
+ * at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/**
- * @file
- * @brief NAT44 hairpinning
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
*/
#include <vlib/vlib.h>
#include <vnet/vnet.h>
#include <vnet/fib/ip4_fib.h>
-#include <nat/nat.h>
-#include <nat/nat_inlines.h>
-#include <nat/nat44_hairpinning.h>
+
+#include <nat/nat44-ei/nat44_ei.h>
+#include <nat/nat44-ei/nat44_ei_inlines.h>
+#include <nat/nat44-ei/nat44_ei_hairpinning.h>
+
+/* NAT buffer flags */
+#define NAT44_EI_FLAG_HAIRPINNING (1 << 0)
typedef enum
{
- SNAT_HAIRPIN_SRC_NEXT_DROP,
- SNAT_HAIRPIN_SRC_NEXT_SNAT_IN2OUT,
- SNAT_HAIRPIN_SRC_NEXT_SNAT_IN2OUT_WH,
- SNAT_HAIRPIN_SRC_NEXT_INTERFACE_OUTPUT,
- SNAT_HAIRPIN_SRC_N_NEXT,
-} snat_hairpin_src_next_t;
+ NAT44_EI_HAIRPIN_SRC_NEXT_DROP,
+ NAT44_EI_HAIRPIN_SRC_NEXT_SNAT_IN2OUT,
+ NAT44_EI_HAIRPIN_SRC_NEXT_SNAT_IN2OUT_WH,
+ NAT44_EI_HAIRPIN_SRC_NEXT_INTERFACE_OUTPUT,
+ NAT44_EI_HAIRPIN_SRC_N_NEXT,
+} nat44_ei_hairpin_src_next_t;
typedef enum
{
- NAT_HAIRPIN_NEXT_LOOKUP,
- NAT_HAIRPIN_NEXT_DROP,
- NAT_HAIRPIN_NEXT_HANDOFF,
- NAT_HAIRPIN_N_NEXT,
-} nat_hairpin_next_t;
+ NAT44_EI_HAIRPIN_NEXT_LOOKUP,
+ NAT44_EI_HAIRPIN_NEXT_DROP,
+ NAT44_EI_HAIRPIN_NEXT_HANDOFF,
+ NAT44_EI_HAIRPIN_N_NEXT,
+} nat44_ei_hairpin_next_t;
typedef struct
{
@@ -47,18 +48,17 @@ typedef struct
u16 port;
u32 fib_index;
u32 session_index;
-} nat_hairpin_trace_t;
+} nat44_ei_hairpin_trace_t;
static u8 *
-format_nat_hairpin_trace (u8 * s, va_list * args)
+format_nat44_ei_hairpin_trace (u8 *s, va_list *args)
{
CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
- nat_hairpin_trace_t *t = va_arg (*args, nat_hairpin_trace_t *);
+ nat44_ei_hairpin_trace_t *t = va_arg (*args, nat44_ei_hairpin_trace_t *);
- s =
- format (s, "new dst addr %U port %u fib-index %u", format_ip4_address,
- &t->addr, clib_net_to_host_u16 (t->port), t->fib_index);
+ s = format (s, "new dst addr %U port %u fib-index %u", format_ip4_address,
+ &t->addr, clib_net_to_host_u16 (t->port), t->fib_index);
if (~0 == t->session_index)
{
s = format (s, " is-static-mapping");
@@ -74,32 +74,60 @@ format_nat_hairpin_trace (u8 * s, va_list * args)
extern vnet_feature_arc_registration_t vnet_feat_arc_ip4_local;
static_always_inline int
-is_hairpinning (snat_main_t * sm, ip4_address_t * dst_addr)
+nat44_ei_is_hairpinning (nat44_ei_main_t *nm, ip4_address_t *dst_addr)
{
- snat_address_t *ap;
+ nat44_ei_address_t *ap;
clib_bihash_kv_8_8_t kv, value;
- vec_foreach (ap, sm->addresses)
+ vec_foreach (ap, nm->addresses)
{
if (ap->addr.as_u32 == dst_addr->as_u32)
- return 1;
+ return 1;
}
init_nat_k (&kv, *dst_addr, 0, 0, 0);
- if (!clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value))
+ if (!clib_bihash_search_8_8 (&nm->static_mapping_by_external, &kv, &value))
return 1;
return 0;
}
#ifndef CLIB_MARCH_VARIANT
+void
+nat44_ei_hairpinning_sm_unknown_proto (nat44_ei_main_t *nm, vlib_buffer_t *b,
+ ip4_header_t *ip)
+{
+ clib_bihash_kv_8_8_t kv, value;
+ nat44_ei_static_mapping_t *m;
+ u32 old_addr, new_addr;
+ ip_csum_t sum;
+
+ init_nat_k (&kv, ip->dst_address, 0, 0, 0);
+ if (clib_bihash_search_8_8 (&nm->static_mapping_by_external, &kv, &value))
+ return;
+
+ m = pool_elt_at_index (nm->static_mappings, value.value);
+
+ old_addr = ip->dst_address.as_u32;
+ new_addr = ip->dst_address.as_u32 = m->local_addr.as_u32;
+ sum = ip->checksum;
+ sum = ip_csum_update (sum, old_addr, new_addr, ip4_header_t, dst_address);
+ ip->checksum = ip_csum_fold (sum);
+
+ if (vnet_buffer (b)->sw_if_index[VLIB_TX] == ~0)
+ vnet_buffer (b)->sw_if_index[VLIB_TX] = m->fib_index;
+}
+#endif
+
+#ifndef CLIB_MARCH_VARIANT
int
-snat_hairpinning (vlib_main_t *vm, vlib_node_runtime_t *node, snat_main_t *sm,
- u32 thread_index, vlib_buffer_t *b0, ip4_header_t *ip0,
- udp_header_t *udp0, tcp_header_t *tcp0, u32 proto0,
- int do_trace, u32 *required_thread_index)
+nat44_ei_hairpinning (vlib_main_t *vm, vlib_node_runtime_t *node,
+ nat44_ei_main_t *nm, u32 thread_index, vlib_buffer_t *b0,
+ ip4_header_t *ip0, udp_header_t *udp0,
+ tcp_header_t *tcp0, u32 proto0, int do_trace,
+ u32 *required_thread_index)
{
- snat_session_t *s0 = NULL;
+ nat44_ei_session_t *s0 = NULL;
clib_bihash_kv_8_8_t kv0, value0;
ip_csum_t sum0;
u32 new_dst_addr0 = 0, old_dst_addr0, si = ~0;
@@ -109,10 +137,11 @@ snat_hairpinning (vlib_main_t *vm, vlib_node_runtime_t *node, snat_main_t *sm,
u16 sm0_port;
u32 sm0_fib_index;
u32 old_sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_TX];
+
/* Check if destination is static mappings */
- if (!snat_static_mapping_match
- (sm, ip0->dst_address, udp0->dst_port, sm->outside_fib_index, proto0,
- &sm0_addr, &sm0_port, &sm0_fib_index, 1, 0, 0, 0, 0, 0, 0))
+ if (!nat44_ei_static_mapping_match (
+ ip0->dst_address, udp0->dst_port, nm->outside_fib_index, proto0,
+ &sm0_addr, &sm0_port, &sm0_fib_index, 1 /* by external */, 0, 0))
{
new_dst_addr0 = sm0_addr.as_u32;
new_dst_port0 = sm0_port;
@@ -122,8 +151,8 @@ snat_hairpinning (vlib_main_t *vm, vlib_node_runtime_t *node, snat_main_t *sm,
else
{
init_nat_k (&kv0, ip0->dst_address, udp0->dst_port,
- sm->outside_fib_index, proto0);
- rv = clib_bihash_search_8_8 (&sm->out2in, &kv0, &value0);
+ nm->outside_fib_index, proto0);
+ rv = clib_bihash_search_8_8 (&nm->out2in, &kv0, &value0);
if (rv)
{
rv = 0;
@@ -137,7 +166,7 @@ snat_hairpinning (vlib_main_t *vm, vlib_node_runtime_t *node, snat_main_t *sm,
}
si = nat_value_get_session_index (&value0);
- s0 = pool_elt_at_index (sm->per_thread_data[thread_index].sessions, si);
+ s0 = pool_elt_at_index (nm->per_thread_data[thread_index].sessions, si);
new_dst_addr0 = s0->in2out.addr.as_u32;
new_dst_port0 = s0->in2out.port;
vnet_buffer (b0)->sw_if_index[VLIB_TX] = s0->in2out.fib_index;
@@ -149,9 +178,8 @@ snat_hairpinning (vlib_main_t *vm, vlib_node_runtime_t *node, snat_main_t *sm,
changed. */
old_dst_addr0 = ip0->dst_address.as_u32;
old_dst_port0 = tcp0->dst;
- if (new_dst_addr0 == old_dst_addr0
- && new_dst_port0 == old_dst_port0
- && vnet_buffer (b0)->sw_if_index[VLIB_TX] == old_sw_if_index)
+ if (new_dst_addr0 == old_dst_addr0 && new_dst_port0 == old_dst_port0 &&
+ vnet_buffer (b0)->sw_if_index[VLIB_TX] == old_sw_if_index)
return 0;
/* Destination is behind the same NAT, use internal address and port */
@@ -160,8 +188,8 @@ snat_hairpinning (vlib_main_t *vm, vlib_node_runtime_t *node, snat_main_t *sm,
old_dst_addr0 = ip0->dst_address.as_u32;
ip0->dst_address.as_u32 = new_dst_addr0;
sum0 = ip0->checksum;
- sum0 = ip_csum_update (sum0, old_dst_addr0, new_dst_addr0,
- ip4_header_t, dst_address);
+ sum0 = ip_csum_update (sum0, old_dst_addr0, new_dst_addr0, ip4_header_t,
+ dst_address);
ip0->checksum = ip_csum_fold (sum0);
old_dst_port0 = tcp0->dst;
@@ -174,7 +202,7 @@ snat_hairpinning (vlib_main_t *vm, vlib_node_runtime_t *node, snat_main_t *sm,
sum0 = ip_csum_update (sum0, old_dst_addr0, new_dst_addr0,
ip4_header_t, dst_address);
sum0 = ip_csum_update (sum0, old_dst_port0, new_dst_port0,
- ip4_header_t /* cheat */ , length);
+ ip4_header_t /* cheat */, length);
tcp0->checksum = ip_csum_fold (sum0);
}
else
@@ -198,10 +226,10 @@ snat_hairpinning (vlib_main_t *vm, vlib_node_runtime_t *node, snat_main_t *sm,
}
rv = 0;
trace:
- if (do_trace && PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)
- && (b0->flags & VLIB_BUFFER_IS_TRACED)))
+ if (do_trace && PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) &&
+ (b0->flags & VLIB_BUFFER_IS_TRACED)))
{
- nat_hairpin_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t));
+ nat44_ei_hairpin_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t));
t->addr.as_u32 = new_dst_addr0;
t->port = new_dst_port0;
t->fib_index = vnet_buffer (b0)->sw_if_index[VLIB_TX];
@@ -220,9 +248,9 @@ trace:
#ifndef CLIB_MARCH_VARIANT
u32
-snat_icmp_hairpinning (snat_main_t *sm, vlib_buffer_t *b0, u32 thread_index,
- ip4_header_t *ip0, icmp46_header_t *icmp0,
- u32 *required_thread_index)
+nat44_ei_icmp_hairpinning (nat44_ei_main_t *nm, vlib_buffer_t *b0,
+ u32 thread_index, ip4_header_t *ip0,
+ icmp46_header_t *icmp0, u32 *required_thread_index)
{
clib_bihash_kv_8_8_t kv0, value0;
u32 old_dst_addr0, new_dst_addr0;
@@ -231,11 +259,11 @@ snat_icmp_hairpinning (snat_main_t *sm, vlib_buffer_t *b0, u32 thread_index,
u16 old_checksum0, new_checksum0;
u32 si, ti = 0;
ip_csum_t sum0;
- snat_session_t *s0;
- snat_static_mapping_t *m0;
+ nat44_ei_session_t *s0;
+ nat44_ei_static_mapping_t *m0;
- if (icmp_type_is_error_message
- (vnet_buffer (b0)->ip.reass.icmp_type_or_tcp_flags))
+ if (icmp_type_is_error_message (
+ vnet_buffer (b0)->ip.reass.icmp_type_or_tcp_flags))
{
ip4_header_t *inner_ip0 = 0;
tcp_udp_header_t *l4_header = 0;
@@ -248,8 +276,8 @@ snat_icmp_hairpinning (snat_main_t *sm, vlib_buffer_t *b0, u32 thread_index,
return 1;
init_nat_k (&kv0, ip0->dst_address, l4_header->src_port,
- sm->outside_fib_index, protocol);
- if (clib_bihash_search_8_8 (&sm->out2in, &kv0, &value0))
+ nm->outside_fib_index, protocol);
+ if (clib_bihash_search_8_8 (&nm->out2in, &kv0, &value0))
return 1;
ti = nat_value_get_thread_index (&value0);
if (ti != thread_index)
@@ -258,7 +286,7 @@ snat_icmp_hairpinning (snat_main_t *sm, vlib_buffer_t *b0, u32 thread_index,
return 1;
}
si = nat_value_get_session_index (&value0);
- s0 = pool_elt_at_index (sm->per_thread_data[ti].sessions, si);
+ s0 = pool_elt_at_index (nm->per_thread_data[ti].sessions, si);
new_dst_addr0 = s0->in2out.addr.as_u32;
vnet_buffer (b0)->sw_if_index[VLIB_TX] = s0->in2out.fib_index;
@@ -267,15 +295,15 @@ snat_icmp_hairpinning (snat_main_t *sm, vlib_buffer_t *b0, u32 thread_index,
inner_ip0->src_address.as_u32 = new_dst_addr0;
new_addr0 = inner_ip0->src_address.as_u32;
sum0 = icmp0->checksum;
- sum0 = ip_csum_update (sum0, old_addr0, new_addr0, ip4_header_t,
- src_address);
+ sum0 =
+ ip_csum_update (sum0, old_addr0, new_addr0, ip4_header_t, src_address);
icmp0->checksum = ip_csum_fold (sum0);
/* update inner IP header checksum */
old_checksum0 = inner_ip0->checksum;
sum0 = inner_ip0->checksum;
- sum0 = ip_csum_update (sum0, old_addr0, new_addr0, ip4_header_t,
- src_address);
+ sum0 =
+ ip_csum_update (sum0, old_addr0, new_addr0, ip4_header_t, src_address);
inner_ip0->checksum = ip_csum_fold (sum0);
new_checksum0 = inner_ip0->checksum;
sum0 = icmp0->checksum;
@@ -294,15 +322,15 @@ snat_icmp_hairpinning (snat_main_t *sm, vlib_buffer_t *b0, u32 thread_index,
}
else
{
- init_nat_k (&kv0, ip0->dst_address, 0, sm->outside_fib_index, 0);
- if (clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv0,
+ init_nat_k (&kv0, ip0->dst_address, 0, nm->outside_fib_index, 0);
+ if (clib_bihash_search_8_8 (&nm->static_mapping_by_external, &kv0,
&value0))
{
icmp_echo_header_t *echo0 = (icmp_echo_header_t *) (icmp0 + 1);
u16 icmp_id0 = echo0->identifier;
- init_nat_k (&kv0, ip0->dst_address, icmp_id0, sm->outside_fib_index,
+ init_nat_k (&kv0, ip0->dst_address, icmp_id0, nm->outside_fib_index,
NAT_PROTOCOL_ICMP);
- int rv = clib_bihash_search_8_8 (&sm->out2in, &kv0, &value0);
+ int rv = clib_bihash_search_8_8 (&nm->out2in, &kv0, &value0);
if (!rv)
{
ti = nat_value_get_thread_index (&value0);
@@ -312,7 +340,7 @@ snat_icmp_hairpinning (snat_main_t *sm, vlib_buffer_t *b0, u32 thread_index,
return 1;
}
si = nat_value_get_session_index (&value0);
- s0 = pool_elt_at_index (sm->per_thread_data[ti].sessions, si);
+ s0 = pool_elt_at_index (nm->per_thread_data[ti].sessions, si);
new_dst_addr0 = s0->in2out.addr.as_u32;
vnet_buffer (b0)->sw_if_index[VLIB_TX] = s0->in2out.fib_index;
echo0->identifier = s0->in2out.port;
@@ -326,7 +354,7 @@ snat_icmp_hairpinning (snat_main_t *sm, vlib_buffer_t *b0, u32 thread_index,
return 1;
}
- m0 = pool_elt_at_index (sm->static_mappings, value0.value);
+ m0 = pool_elt_at_index (nm->static_mappings, value0.value);
new_dst_addr0 = m0->local_addr.as_u32;
if (vnet_buffer (b0)->sw_if_index[VLIB_TX] == ~0)
@@ -339,29 +367,32 @@ change_addr:
old_dst_addr0 = ip0->dst_address.as_u32;
ip0->dst_address.as_u32 = new_dst_addr0;
sum0 = ip0->checksum;
- sum0 = ip_csum_update (sum0, old_dst_addr0, new_dst_addr0,
- ip4_header_t, dst_address);
+ sum0 = ip_csum_update (sum0, old_dst_addr0, new_dst_addr0, ip4_header_t,
+ dst_address);
ip0->checksum = ip_csum_fold (sum0);
}
return 0;
}
#endif
+void nat44_ei_hairpinning_unknown_proto (nat44_ei_main_t *nm, vlib_buffer_t *b,
+ ip4_header_t *ip);
+
#ifndef CLIB_MARCH_VARIANT
void
-nat_hairpinning_sm_unknown_proto (snat_main_t * sm,
- vlib_buffer_t * b, ip4_header_t * ip)
+nat44_ei_hairpinning_unknown_proto (nat44_ei_main_t *nm, vlib_buffer_t *b,
+ ip4_header_t *ip)
{
clib_bihash_kv_8_8_t kv, value;
- snat_static_mapping_t *m;
+ nat44_ei_static_mapping_t *m;
u32 old_addr, new_addr;
ip_csum_t sum;
init_nat_k (&kv, ip->dst_address, 0, 0, 0);
- if (clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value))
+ if (clib_bihash_search_8_8 (&nm->static_mapping_by_external, &kv, &value))
return;
- m = pool_elt_at_index (sm->static_mappings, value.value);
+ m = pool_elt_at_index (nm->static_mappings, value.value);
old_addr = ip->dst_address.as_u32;
new_addr = ip->dst_address.as_u32 = m->local_addr.as_u32;
@@ -374,17 +405,12 @@ nat_hairpinning_sm_unknown_proto (snat_main_t * sm,
}
#endif
-static inline uword
-nat44_hairpinning_fn_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
- vlib_frame_t *frame)
+VLIB_NODE_FN (nat44_ei_hairpin_src_node)
+(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
{
u32 n_left_from, *from, *to_next;
- u32 thread_index = vm->thread_index;
- nat_hairpin_next_t next_index;
- snat_main_t *sm = &snat_main;
- vnet_feature_main_t *fm = &feature_main;
- u8 arc_index = vnet_feat_arc_ip4_local.feature_arc_index;
- vnet_feature_config_main_t *cm = &fm->feature_config_mains[arc_index];
+ nat44_ei_hairpin_src_next_t next_index;
+ nat44_ei_main_t *nm = &nat44_ei_main;
from = vlib_frame_vector_args (frame);
n_left_from = frame->n_vectors;
@@ -401,12 +427,8 @@ nat44_hairpinning_fn_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
u32 bi0;
vlib_buffer_t *b0;
u32 next0;
- ip4_header_t *ip0;
- u32 proto0;
- udp_header_t *udp0;
- tcp_header_t *tcp0;
+ nat44_ei_interface_t *i;
u32 sw_if_index0;
- u32 required_thread_index = thread_index;
/* speculatively enqueue b0 to the current next frame */
bi0 = from[0];
@@ -417,45 +439,36 @@ nat44_hairpinning_fn_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
n_left_to_next -= 1;
b0 = vlib_get_buffer (vm, bi0);
- ip0 = vlib_buffer_get_current (b0);
- udp0 = ip4_next_header (ip0);
- tcp0 = (tcp_header_t *) udp0;
sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
+ vnet_feature_next (&next0, b0);
- proto0 = ip_proto_to_nat_proto (ip0->protocol);
- int next0_resolved = 0;
-
- if (snat_hairpinning (vm, node, sm, thread_index, b0, ip0, udp0,
- tcp0, proto0, 1 /* do_trace */,
- &required_thread_index))
+ pool_foreach (i, nm->output_feature_interfaces)
{
- next0 = NAT_HAIRPIN_NEXT_LOOKUP;
- next0_resolved = 1;
- }
-
- if (thread_index != required_thread_index)
- {
- vnet_buffer (b0)->snat.required_thread_index =
- required_thread_index;
- next0 = NAT_HAIRPIN_NEXT_HANDOFF;
- next0_resolved = 1;
+ /* Only packets from NAT inside interface */
+ if ((nat44_ei_interface_is_inside (i)) &&
+ (sw_if_index0 == i->sw_if_index))
+ {
+ if (PREDICT_FALSE ((vnet_buffer (b0)->snat.flags) &
+ NAT44_EI_FLAG_HAIRPINNING))
+ {
+ if (PREDICT_TRUE (nm->num_workers > 1))
+ next0 = NAT44_EI_HAIRPIN_SRC_NEXT_SNAT_IN2OUT_WH;
+ else
+ next0 = NAT44_EI_HAIRPIN_SRC_NEXT_SNAT_IN2OUT;
+ }
+ break;
+ }
}
- if (!next0_resolved)
- vnet_get_config_data (&cm->config_main, &b0->current_config_index,
- &next0, 0);
-
- if (next0 != NAT_HAIRPIN_NEXT_DROP)
+ if (next0 != NAT44_EI_HAIRPIN_SRC_NEXT_DROP)
{
- vlib_increment_simple_counter (&sm->counters.hairpinning,
- vm->thread_index, sw_if_index0,
- 1);
+ vlib_increment_simple_counter (
+ &nm->counters.hairpinning, vm->thread_index, sw_if_index0, 1);
}
/* verify speculative enqueue, maybe switch current next frame */
- vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
- to_next, n_left_to_next,
- bi0, next0);
+ vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
+ n_left_to_next, bi0, next0);
}
vlib_put_next_frame (vm, node, next_index, n_left_to_next);
@@ -464,55 +477,13 @@ nat44_hairpinning_fn_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
return frame->n_vectors;
}
-VLIB_NODE_FN (nat44_hairpinning_node) (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
-{
- return nat44_hairpinning_fn_inline (vm, node, frame);
-}
-
-VLIB_REGISTER_NODE (nat44_hairpinning_node) = {
- .name = "nat44-hairpinning",
- .vector_size = sizeof (u32),
- .type = VLIB_NODE_TYPE_INTERNAL,
- .format_trace = format_nat_hairpin_trace,
- .n_next_nodes = NAT_HAIRPIN_N_NEXT,
- .next_nodes = {
- [NAT_HAIRPIN_NEXT_DROP] = "error-drop",
- [NAT_HAIRPIN_NEXT_LOOKUP] = "ip4-lookup",
- [NAT_HAIRPIN_NEXT_HANDOFF] = "nat44-hairpinning-handoff",
- },
-};
-
-VLIB_NODE_FN (nat44_hairpinning_handoff_node)
+VLIB_NODE_FN (nat44_ei_hairpin_dst_node)
(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
{
- return nat44_hairpinning_handoff_fn_inline (
- vm, node, frame, snat_main.nat44_hairpinning_fq_index);
-}
-
-VLIB_REGISTER_NODE (nat44_hairpinning_handoff_node) = {
- .name = "nat44-hairpinning-handoff",
- .vector_size = sizeof (u32),
- .n_errors = ARRAY_LEN(nat44_hairpinning_handoff_error_strings),
- .error_strings = nat44_hairpinning_handoff_error_strings,
- .format_trace = format_nat44_hairpinning_handoff_trace,
-
- .n_next_nodes = 1,
-
- .next_nodes = {
- [0] = "error-drop",
- },
-};
-
-static inline uword
-snat_hairpin_dst_fn_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
- vlib_frame_t *frame)
-{
u32 n_left_from, *from, *to_next;
u32 thread_index = vm->thread_index;
- nat_hairpin_next_t next_index;
- snat_main_t *sm = &snat_main;
+ nat44_ei_hairpin_next_t next_index;
+ nat44_ei_main_t *nm = &nat44_ei_main;
from = vlib_frame_vector_args (frame);
n_left_from = frame->n_vectors;
@@ -543,57 +514,55 @@ snat_hairpin_dst_fn_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
n_left_to_next -= 1;
b0 = vlib_get_buffer (vm, bi0);
- next0 = NAT_HAIRPIN_NEXT_LOOKUP;
+ next0 = NAT44_EI_HAIRPIN_NEXT_LOOKUP;
ip0 = vlib_buffer_get_current (b0);
sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
proto0 = ip_proto_to_nat_proto (ip0->protocol);
vnet_buffer (b0)->snat.flags = 0;
- if (PREDICT_FALSE (is_hairpinning (sm, &ip0->dst_address)))
+ if (PREDICT_FALSE (nat44_ei_is_hairpinning (nm, &ip0->dst_address)))
{
if (proto0 == NAT_PROTOCOL_TCP || proto0 == NAT_PROTOCOL_UDP)
{
udp_header_t *udp0 = ip4_next_header (ip0);
tcp_header_t *tcp0 = (tcp_header_t *) udp0;
- snat_hairpinning (vm, node, sm, thread_index, b0, ip0, udp0,
- tcp0, proto0, 1 /* do_trace */,
- &required_thread_index);
+ nat44_ei_hairpinning (vm, node, nm, thread_index, b0, ip0,
+ udp0, tcp0, proto0, 1 /* do_trace */,
+ &required_thread_index);
}
else if (proto0 == NAT_PROTOCOL_ICMP)
{
icmp46_header_t *icmp0 = ip4_next_header (ip0);
- snat_icmp_hairpinning (sm, b0, thread_index, ip0, icmp0,
- &required_thread_index);
+ nat44_ei_icmp_hairpinning (nm, b0, thread_index, ip0, icmp0,
+ &required_thread_index);
}
else
{
- nat_hairpinning_sm_unknown_proto (sm, b0, ip0);
+ nat44_ei_hairpinning_unknown_proto (nm, b0, ip0);
}
- vnet_buffer (b0)->snat.flags = SNAT_FLAG_HAIRPINNING;
+ vnet_buffer (b0)->snat.flags = NAT44_EI_FLAG_HAIRPINNING;
}
if (thread_index != required_thread_index)
{
vnet_buffer (b0)->snat.required_thread_index =
required_thread_index;
- next0 = NAT_HAIRPIN_NEXT_HANDOFF;
+ next0 = NAT44_EI_HAIRPIN_NEXT_HANDOFF;
}
- if (next0 != NAT_HAIRPIN_NEXT_DROP)
+ if (next0 != NAT44_EI_HAIRPIN_NEXT_DROP)
{
- vlib_increment_simple_counter (&sm->counters.hairpinning,
- vm->thread_index, sw_if_index0,
- 1);
+ vlib_increment_simple_counter (
+ &nm->counters.hairpinning, vm->thread_index, sw_if_index0, 1);
}
/* verify speculative enqueue, maybe switch current next frame */
- vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
- to_next, n_left_to_next,
- bi0, next0);
+ vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
+ n_left_to_next, bi0, next0);
}
vlib_put_next_frame (vm, node, next_index, n_left_to_next);
@@ -602,54 +571,16 @@ snat_hairpin_dst_fn_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
return frame->n_vectors;
}
-VLIB_NODE_FN (snat_hairpin_dst_node) (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
-{
- return snat_hairpin_dst_fn_inline (vm, node, frame);
-}
-
-VLIB_REGISTER_NODE (snat_hairpin_dst_node) = {
- .name = "nat44-hairpin-dst",
- .vector_size = sizeof (u32),
- .type = VLIB_NODE_TYPE_INTERNAL,
- .format_trace = format_nat_hairpin_trace,
- .n_next_nodes = NAT_HAIRPIN_N_NEXT,
- .next_nodes = {
- [NAT_HAIRPIN_NEXT_DROP] = "error-drop",
- [NAT_HAIRPIN_NEXT_LOOKUP] = "ip4-lookup",
- [NAT_HAIRPIN_NEXT_HANDOFF] = "nat44-hairpin-dst-handoff",
- },
-};
-
-VLIB_NODE_FN (nat44_hairpinning_dst_handoff_node)
+VLIB_NODE_FN (nat44_ei_hairpinning_node)
(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
{
- return nat44_hairpinning_handoff_fn_inline (
- vm, node, frame, snat_main.snat_hairpin_dst_fq_index);
-}
-
-VLIB_REGISTER_NODE (nat44_hairpinning_dst_handoff_node) = {
- .name = "nat44-hairpin-dst-handoff",
- .vector_size = sizeof (u32),
- .n_errors = ARRAY_LEN(nat44_hairpinning_handoff_error_strings),
- .error_strings = nat44_hairpinning_handoff_error_strings,
- .format_trace = format_nat44_hairpinning_handoff_trace,
-
- .n_next_nodes = 1,
-
- .next_nodes = {
- [0] = "error-drop",
- },
-};
-
-static inline uword
-snat_hairpin_src_fn_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
- vlib_frame_t *frame)
-{
u32 n_left_from, *from, *to_next;
- snat_hairpin_src_next_t next_index;
- snat_main_t *sm = &snat_main;
+ u32 thread_index = vm->thread_index;
+ nat44_ei_hairpin_next_t next_index;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ vnet_feature_main_t *fm = &feature_main;
+ u8 arc_index = vnet_feat_arc_ip4_local.feature_arc_index;
+ vnet_feature_config_main_t *cm = &fm->feature_config_mains[arc_index];
from = vlib_frame_vector_args (frame);
n_left_from = frame->n_vectors;
@@ -666,8 +597,12 @@ snat_hairpin_src_fn_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
u32 bi0;
vlib_buffer_t *b0;
u32 next0;
- snat_interface_t *i;
+ ip4_header_t *ip0;
+ u32 proto0;
+ udp_header_t *udp0;
+ tcp_header_t *tcp0;
u32 sw_if_index0;
+ u32 required_thread_index = thread_index;
/* speculatively enqueue b0 to the current next frame */
bi0 = from[0];
@@ -678,37 +613,43 @@ snat_hairpin_src_fn_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
n_left_to_next -= 1;
b0 = vlib_get_buffer (vm, bi0);
+ ip0 = vlib_buffer_get_current (b0);
+ udp0 = ip4_next_header (ip0);
+ tcp0 = (tcp_header_t *) udp0;
sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
- vnet_feature_next (&next0, b0);
- pool_foreach (i, sm->output_feature_interfaces)
- {
- /* Only packets from NAT inside interface */
- if ((nat_interface_is_inside(i)) && (sw_if_index0 == i->sw_if_index))
- {
- if (PREDICT_FALSE ((vnet_buffer (b0)->snat.flags) &
- SNAT_FLAG_HAIRPINNING))
- {
- if (PREDICT_TRUE (sm->num_workers > 1))
- next0 = SNAT_HAIRPIN_SRC_NEXT_SNAT_IN2OUT_WH;
- else
- next0 = SNAT_HAIRPIN_SRC_NEXT_SNAT_IN2OUT;
- }
- break;
- }
- }
-
- if (next0 != SNAT_HAIRPIN_SRC_NEXT_DROP)
+ proto0 = ip_proto_to_nat_proto (ip0->protocol);
+ int next0_resolved = 0;
+
+ if (nat44_ei_hairpinning (vm, node, nm, thread_index, b0, ip0, udp0,
+ tcp0, proto0, 1 /* do_trace */,
+ &required_thread_index))
+ {
+ next0 = NAT44_EI_HAIRPIN_NEXT_LOOKUP;
+ next0_resolved = 1;
+ }
+
+ if (thread_index != required_thread_index)
+ {
+ vnet_buffer (b0)->snat.required_thread_index =
+ required_thread_index;
+ next0 = NAT44_EI_HAIRPIN_NEXT_HANDOFF;
+ next0_resolved = 1;
+ }
+
+ if (!next0_resolved)
+ vnet_get_config_data (&cm->config_main, &b0->current_config_index,
+ &next0, 0);
+
+ if (next0 != NAT44_EI_HAIRPIN_NEXT_DROP)
{
- vlib_increment_simple_counter (&sm->counters.hairpinning,
- vm->thread_index, sw_if_index0,
- 1);
+ vlib_increment_simple_counter (
+ &nm->counters.hairpinning, vm->thread_index, sw_if_index0, 1);
}
/* verify speculative enqueue, maybe switch current next frame */
- vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
- to_next, n_left_to_next,
- bi0, next0);
+ vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
+ n_left_to_next, bi0, next0);
}
vlib_put_next_frame (vm, node, next_index, n_left_to_next);
@@ -717,23 +658,84 @@ snat_hairpin_src_fn_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
return frame->n_vectors;
}
-VLIB_NODE_FN (snat_hairpin_src_node) (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
+VLIB_NODE_FN (nat44_ei_hairpinning_dst_handoff_node)
+(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
{
- return snat_hairpin_src_fn_inline (vm, node, frame);
+ return nat44_ei_hairpinning_handoff_fn_inline (
+ vm, node, frame, nat44_ei_main.hairpin_dst_fq_index);
}
-VLIB_REGISTER_NODE (snat_hairpin_src_node) = {
- .name = "nat44-hairpin-src",
+VLIB_NODE_FN (nat44_ei_hairpinning_handoff_node)
+(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
+{
+ return nat44_ei_hairpinning_handoff_fn_inline (
+ vm, node, frame, nat44_ei_main.hairpinning_fq_index);
+}
+
+VLIB_REGISTER_NODE (nat44_ei_hairpinning_dst_handoff_node) = {
+ .name = "nat44-ei-hairpin-dst-handoff",
+ .vector_size = sizeof (u32),
+ .n_errors = ARRAY_LEN(nat44_ei_hairpinning_handoff_error_strings),
+ .error_strings = nat44_ei_hairpinning_handoff_error_strings,
+ .format_trace = format_nat44_ei_hairpinning_handoff_trace,
+
+ .n_next_nodes = 1,
+
+ .next_nodes = {
+ [0] = "error-drop",
+ },
+};
+
+VLIB_REGISTER_NODE (nat44_ei_hairpinning_handoff_node) = {
+ .name = "nat44-ei-hairpinning-handoff",
+ .vector_size = sizeof (u32),
+ .n_errors = ARRAY_LEN(nat44_ei_hairpinning_handoff_error_strings),
+ .error_strings = nat44_ei_hairpinning_handoff_error_strings,
+ .format_trace = format_nat44_ei_hairpinning_handoff_trace,
+
+ .n_next_nodes = 1,
+
+ .next_nodes = {
+ [0] = "error-drop",
+ },
+};
+
+VLIB_REGISTER_NODE (nat44_ei_hairpin_src_node) = {
+ .name = "nat44-ei-hairpin-src",
+ .vector_size = sizeof (u32),
+ .type = VLIB_NODE_TYPE_INTERNAL,
+ .n_next_nodes = NAT44_EI_HAIRPIN_SRC_N_NEXT,
+ .next_nodes = {
+ [NAT44_EI_HAIRPIN_SRC_NEXT_DROP] = "error-drop",
+ [NAT44_EI_HAIRPIN_SRC_NEXT_SNAT_IN2OUT] = "nat44-ei-in2out-output",
+ [NAT44_EI_HAIRPIN_SRC_NEXT_INTERFACE_OUTPUT] = "interface-output",
+ [NAT44_EI_HAIRPIN_SRC_NEXT_SNAT_IN2OUT_WH] = "nat44-ei-in2out-output-worker-handoff",
+ },
+};
+
+VLIB_REGISTER_NODE (nat44_ei_hairpin_dst_node) = {
+ .name = "nat44-ei-hairpin-dst",
+ .vector_size = sizeof (u32),
+ .type = VLIB_NODE_TYPE_INTERNAL,
+ .format_trace = format_nat44_ei_hairpin_trace,
+ .n_next_nodes = NAT44_EI_HAIRPIN_N_NEXT,
+ .next_nodes = {
+ [NAT44_EI_HAIRPIN_NEXT_DROP] = "error-drop",
+ [NAT44_EI_HAIRPIN_NEXT_LOOKUP] = "ip4-lookup",
+ [NAT44_EI_HAIRPIN_NEXT_HANDOFF] = "nat44-ei-hairpin-dst-handoff",
+ },
+};
+
+VLIB_REGISTER_NODE (nat44_ei_hairpinning_node) = {
+ .name = "nat44-ei-hairpinning",
.vector_size = sizeof (u32),
.type = VLIB_NODE_TYPE_INTERNAL,
- .n_next_nodes = SNAT_HAIRPIN_SRC_N_NEXT,
+ .format_trace = format_nat44_ei_hairpin_trace,
+ .n_next_nodes = NAT44_EI_HAIRPIN_N_NEXT,
.next_nodes = {
- [SNAT_HAIRPIN_SRC_NEXT_DROP] = "error-drop",
- [SNAT_HAIRPIN_SRC_NEXT_SNAT_IN2OUT] = "nat44-in2out-output",
- [SNAT_HAIRPIN_SRC_NEXT_INTERFACE_OUTPUT] = "interface-output",
- [SNAT_HAIRPIN_SRC_NEXT_SNAT_IN2OUT_WH] = "nat44-in2out-output-worker-handoff",
+ [NAT44_EI_HAIRPIN_NEXT_DROP] = "error-drop",
+ [NAT44_EI_HAIRPIN_NEXT_LOOKUP] = "ip4-lookup",
+ [NAT44_EI_HAIRPIN_NEXT_HANDOFF] = "nat44-ei-hairpinning-handoff",
},
};
diff --git a/src/plugins/nat/nat44_hairpinning.h b/src/plugins/nat/nat44-ei/nat44_ei_hairpinning.h
index 2a8b73db6ab..bdd2d210200 100644
--- a/src/plugins/nat/nat44_hairpinning.h
+++ b/src/plugins/nat/nat44-ei/nat44_ei_hairpinning.h
@@ -1,48 +1,48 @@
-#ifndef __included_nat44_hairpinning_h__
-#define __included_nat44_hairpinning_h__
+#ifndef __included_nat44_ei_hairpinning_h__
+#define __included_nat44_ei_hairpinning_h__
-#include <nat/nat.h>
+#include <nat/nat44-ei/nat44_ei.h>
-#define foreach_nat44_hairpinning_handoff_error \
+#define foreach_nat44_ei_hairpinning_handoff_error \
_ (CONGESTION_DROP, "congestion drop")
typedef enum
{
-#define _(sym, str) NAT44_HAIRPINNING_HANDOFF_ERROR_##sym,
- foreach_nat44_hairpinning_handoff_error
+#define _(sym, str) NAT44_EI_HAIRPINNING_HANDOFF_ERROR_##sym,
+ foreach_nat44_ei_hairpinning_handoff_error
#undef _
- NAT44_HAIRPINNING_HANDOFF_N_ERROR,
-} nat44_hairpinning_handoff_error_t;
+ NAT44_EI_HAIRPINNING_HANDOFF_N_ERROR,
+} nat44_ei_hairpinning_handoff_error_t;
-static char *nat44_hairpinning_handoff_error_strings[] = {
+static char *nat44_ei_hairpinning_handoff_error_strings[] = {
#define _(sym, string) string,
- foreach_nat44_hairpinning_handoff_error
+ foreach_nat44_ei_hairpinning_handoff_error
#undef _
};
typedef struct
{
u32 next_worker_index;
-} nat44_hairpinning_handoff_trace_t;
+} nat44_ei_hairpinning_handoff_trace_t;
static u8 *
-format_nat44_hairpinning_handoff_trace (u8 *s, va_list *args)
+format_nat44_ei_hairpinning_handoff_trace (u8 *s, va_list *args)
{
CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
- nat44_hairpinning_handoff_trace_t *t =
- va_arg (*args, nat44_hairpinning_handoff_trace_t *);
+ nat44_ei_hairpinning_handoff_trace_t *t =
+ va_arg (*args, nat44_ei_hairpinning_handoff_trace_t *);
- s = format (s, "nat-hairpinning-handoff: next-worker %d",
+ s = format (s, "nat44-ei-hairpinning-handoff: next-worker %d",
t->next_worker_index);
return s;
}
always_inline uword
-nat44_hairpinning_handoff_fn_inline (vlib_main_t *vm,
- vlib_node_runtime_t *node,
- vlib_frame_t *frame, u32 fq_index)
+nat44_ei_hairpinning_handoff_fn_inline (vlib_main_t *vm,
+ vlib_node_runtime_t *node,
+ vlib_frame_t *frame, u32 fq_index)
{
vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b;
u32 n_enq, n_left_from, *from;
@@ -62,7 +62,7 @@ nat44_hairpinning_handoff_fn_inline (vlib_main_t *vm,
if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) &&
(b[0]->flags & VLIB_BUFFER_IS_TRACED)))
{
- nat44_hairpinning_handoff_trace_t *t =
+ nat44_ei_hairpinning_handoff_trace_t *t =
vlib_add_trace (vm, node, b[0], sizeof (*t));
t->next_worker_index = ti[0];
}
@@ -76,12 +76,12 @@ nat44_hairpinning_handoff_fn_inline (vlib_main_t *vm,
if (n_enq < frame->n_vectors)
vlib_node_increment_counter (
- vm, node->node_index, NAT44_HAIRPINNING_HANDOFF_ERROR_CONGESTION_DROP,
+ vm, node->node_index, NAT44_EI_HAIRPINNING_HANDOFF_ERROR_CONGESTION_DROP,
frame->n_vectors - n_enq);
return frame->n_vectors;
}
-#endif // __included_nat44_hairpinning_h__
+#endif // __included_nat44_ei_hairpinning_h__
/*
* fd.io coding-style-patch-verification: ON
diff --git a/src/plugins/nat/nat44-ei/nat44_ei_handoff.c b/src/plugins/nat/nat44-ei/nat44_ei_handoff.c
new file mode 100644
index 00000000000..6b8db37d414
--- /dev/null
+++ b/src/plugins/nat/nat44-ei/nat44_ei_handoff.c
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) 2020 Cisco and/or its affiliates.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <vlib/vlib.h>
+#include <vnet/vnet.h>
+#include <vnet/handoff.h>
+#include <vnet/fib/ip4_fib.h>
+#include <vppinfra/error.h>
+
+#include <nat/nat44-ei/nat44_ei.h>
+
+typedef struct
+{
+ u32 next_worker_index;
+ u32 trace_index;
+ u8 in2out;
+ u8 output;
+} nat44_ei_handoff_trace_t;
+
+#define foreach_nat44_ei_handoff_error \
+ _ (CONGESTION_DROP, "congestion drop") \
+ _ (SAME_WORKER, "same worker") \
+ _ (DO_HANDOFF, "do handoff")
+
+typedef enum
+{
+#define _(sym, str) NAT44_EI_HANDOFF_ERROR_##sym,
+ foreach_nat44_ei_handoff_error
+#undef _
+ NAT44_EI_HANDOFF_N_ERROR,
+} nat44_ei_handoff_error_t;
+
+static char *nat44_ei_handoff_error_strings[] = {
+#define _(sym, string) string,
+ foreach_nat44_ei_handoff_error
+#undef _
+};
+
+static u8 *
+format_nat44_ei_handoff_trace (u8 *s, va_list *args)
+{
+ CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
+ CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
+ nat44_ei_handoff_trace_t *t = va_arg (*args, nat44_ei_handoff_trace_t *);
+ char *tag, *output;
+
+ tag = t->in2out ? "IN2OUT" : "OUT2IN";
+ output = t->output ? "OUTPUT-FEATURE" : "";
+ s =
+ format (s, "NAT44_EI_%s_WORKER_HANDOFF %s: next-worker %d trace index %d",
+ tag, output, t->next_worker_index, t->trace_index);
+
+ return s;
+}
+
+static inline uword
+nat44_ei_worker_handoff_fn_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
+ vlib_frame_t *frame, u8 is_output,
+ u8 is_in2out)
+{
+ u32 n_enq, n_left_from, *from, do_handoff = 0, same_worker = 0;
+
+ u16 thread_indices[VLIB_FRAME_SIZE], *ti = thread_indices;
+ vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b = bufs;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+
+ u32 fq_index, thread_index = vm->thread_index;
+
+ from = vlib_frame_vector_args (frame);
+ n_left_from = frame->n_vectors;
+
+ vlib_get_buffers (vm, from, b, n_left_from);
+
+ // TODO: move to nm
+ // TODO: remove callbacks and use inlines that should be moved here
+ if (is_in2out)
+ {
+ fq_index = is_output ? nm->fq_in2out_output_index : nm->fq_in2out_index;
+ }
+ else
+ {
+ fq_index = nm->fq_out2in_index;
+ }
+
+ while (n_left_from >= 4)
+ {
+ u32 arc_next0, arc_next1, arc_next2, arc_next3;
+ u32 sw_if_index0, sw_if_index1, sw_if_index2, sw_if_index3;
+ u32 rx_fib_index0, rx_fib_index1, rx_fib_index2, rx_fib_index3;
+ u32 iph_offset0 = 0, iph_offset1 = 0, iph_offset2 = 0, iph_offset3 = 0;
+ ip4_header_t *ip0, *ip1, *ip2, *ip3;
+
+ if (PREDICT_TRUE (n_left_from >= 8))
+ {
+ vlib_prefetch_buffer_header (b[4], LOAD);
+ vlib_prefetch_buffer_header (b[5], LOAD);
+ vlib_prefetch_buffer_header (b[6], LOAD);
+ vlib_prefetch_buffer_header (b[7], LOAD);
+ CLIB_PREFETCH (&b[4]->data, CLIB_CACHE_LINE_BYTES, LOAD);
+ CLIB_PREFETCH (&b[5]->data, CLIB_CACHE_LINE_BYTES, LOAD);
+ CLIB_PREFETCH (&b[6]->data, CLIB_CACHE_LINE_BYTES, LOAD);
+ CLIB_PREFETCH (&b[7]->data, CLIB_CACHE_LINE_BYTES, LOAD);
+ }
+
+ if (is_output)
+ {
+ iph_offset0 = vnet_buffer (b[0])->ip.save_rewrite_length;
+ iph_offset1 = vnet_buffer (b[1])->ip.save_rewrite_length;
+ iph_offset2 = vnet_buffer (b[2])->ip.save_rewrite_length;
+ iph_offset3 = vnet_buffer (b[3])->ip.save_rewrite_length;
+ }
+
+ ip0 =
+ (ip4_header_t *) ((u8 *) vlib_buffer_get_current (b[0]) + iph_offset0);
+ ip1 =
+ (ip4_header_t *) ((u8 *) vlib_buffer_get_current (b[1]) + iph_offset1);
+ ip2 =
+ (ip4_header_t *) ((u8 *) vlib_buffer_get_current (b[2]) + iph_offset2);
+ ip3 =
+ (ip4_header_t *) ((u8 *) vlib_buffer_get_current (b[3]) + iph_offset3);
+
+ vnet_feature_next (&arc_next0, b[0]);
+ vnet_feature_next (&arc_next1, b[1]);
+ vnet_feature_next (&arc_next2, b[2]);
+ vnet_feature_next (&arc_next3, b[3]);
+
+ vnet_buffer2 (b[0])->nat.arc_next = arc_next0;
+ vnet_buffer2 (b[1])->nat.arc_next = arc_next1;
+ vnet_buffer2 (b[2])->nat.arc_next = arc_next2;
+ vnet_buffer2 (b[3])->nat.arc_next = arc_next3;
+
+ sw_if_index0 = vnet_buffer (b[0])->sw_if_index[VLIB_RX];
+ sw_if_index1 = vnet_buffer (b[1])->sw_if_index[VLIB_RX];
+ sw_if_index2 = vnet_buffer (b[2])->sw_if_index[VLIB_RX];
+ sw_if_index3 = vnet_buffer (b[3])->sw_if_index[VLIB_RX];
+
+ rx_fib_index0 = ip4_fib_table_get_index_for_sw_if_index (sw_if_index0);
+ rx_fib_index1 = ip4_fib_table_get_index_for_sw_if_index (sw_if_index1);
+ rx_fib_index2 = ip4_fib_table_get_index_for_sw_if_index (sw_if_index2);
+ rx_fib_index3 = ip4_fib_table_get_index_for_sw_if_index (sw_if_index3);
+
+ if (is_in2out)
+ {
+ ti[0] = nm->worker_in2out_cb (ip0, rx_fib_index0, is_output);
+ ti[1] = nm->worker_in2out_cb (ip1, rx_fib_index1, is_output);
+ ti[2] = nm->worker_in2out_cb (ip2, rx_fib_index2, is_output);
+ ti[3] = nm->worker_in2out_cb (ip3, rx_fib_index3, is_output);
+ }
+ else
+ {
+ ti[0] = nm->worker_out2in_cb (b[0], ip0, rx_fib_index0, is_output);
+ ti[1] = nm->worker_out2in_cb (b[1], ip1, rx_fib_index1, is_output);
+ ti[2] = nm->worker_out2in_cb (b[2], ip2, rx_fib_index2, is_output);
+ ti[3] = nm->worker_out2in_cb (b[3], ip3, rx_fib_index3, is_output);
+ }
+
+ if (ti[0] == thread_index)
+ same_worker++;
+ else
+ do_handoff++;
+
+ if (ti[1] == thread_index)
+ same_worker++;
+ else
+ do_handoff++;
+
+ if (ti[2] == thread_index)
+ same_worker++;
+ else
+ do_handoff++;
+
+ if (ti[3] == thread_index)
+ same_worker++;
+ else
+ do_handoff++;
+
+ b += 4;
+ ti += 4;
+ n_left_from -= 4;
+ }
+
+ while (n_left_from > 0)
+ {
+ u32 arc_next0;
+ u32 sw_if_index0;
+ u32 rx_fib_index0;
+ u32 iph_offset0 = 0;
+ ip4_header_t *ip0;
+
+ if (is_output)
+ iph_offset0 = vnet_buffer (b[0])->ip.save_rewrite_length;
+
+ ip0 =
+ (ip4_header_t *) ((u8 *) vlib_buffer_get_current (b[0]) + iph_offset0);
+
+ vnet_feature_next (&arc_next0, b[0]);
+ vnet_buffer2 (b[0])->nat.arc_next = arc_next0;
+
+ sw_if_index0 = vnet_buffer (b[0])->sw_if_index[VLIB_RX];
+ rx_fib_index0 = ip4_fib_table_get_index_for_sw_if_index (sw_if_index0);
+
+ if (is_in2out)
+ {
+ ti[0] = nm->worker_in2out_cb (ip0, rx_fib_index0, is_output);
+ }
+ else
+ {
+ ti[0] = nm->worker_out2in_cb (b[0], ip0, rx_fib_index0, is_output);
+ }
+
+ if (ti[0] == thread_index)
+ same_worker++;
+ else
+ do_handoff++;
+
+ b += 1;
+ ti += 1;
+ n_left_from -= 1;
+ }
+
+ if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)))
+ {
+ u32 i;
+ b = bufs;
+ ti = thread_indices;
+
+ for (i = 0; i < frame->n_vectors; i++)
+ {
+ if (b[0]->flags & VLIB_BUFFER_IS_TRACED)
+ {
+ nat44_ei_handoff_trace_t *t =
+ vlib_add_trace (vm, node, b[0], sizeof (*t));
+ t->next_worker_index = ti[0];
+ t->trace_index = vlib_buffer_get_trace_index (b[0]);
+ t->in2out = is_in2out;
+ t->output = is_output;
+
+ b += 1;
+ ti += 1;
+ }
+ else
+ break;
+ }
+ }
+
+ n_enq = vlib_buffer_enqueue_to_thread (vm, fq_index, from, thread_indices,
+ frame->n_vectors, 1);
+
+ if (n_enq < frame->n_vectors)
+ {
+ vlib_node_increment_counter (vm, node->node_index,
+ NAT44_EI_HANDOFF_ERROR_CONGESTION_DROP,
+ frame->n_vectors - n_enq);
+ }
+
+ vlib_node_increment_counter (
+ vm, node->node_index, NAT44_EI_HANDOFF_ERROR_SAME_WORKER, same_worker);
+ vlib_node_increment_counter (vm, node->node_index,
+ NAT44_EI_HANDOFF_ERROR_DO_HANDOFF, do_handoff);
+ return frame->n_vectors;
+}
+
+VLIB_NODE_FN (nat44_ei_in2out_worker_handoff_node)
+(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
+{
+ return nat44_ei_worker_handoff_fn_inline (vm, node, frame, 0, 1);
+}
+
+VLIB_NODE_FN (nat44_ei_in2out_output_worker_handoff_node)
+(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
+{
+ return nat44_ei_worker_handoff_fn_inline (vm, node, frame, 1, 1);
+}
+
+VLIB_NODE_FN (nat44_ei_out2in_worker_handoff_node)
+(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
+{
+ return nat44_ei_worker_handoff_fn_inline (vm, node, frame, 0, 0);
+}
+
+VLIB_REGISTER_NODE (nat44_ei_in2out_output_worker_handoff_node) = {
+ .name = "nat44-ei-in2out-output-worker-handoff",
+ .vector_size = sizeof (u32),
+ .format_trace = format_nat44_ei_handoff_trace,
+ .type = VLIB_NODE_TYPE_INTERNAL,
+ .n_errors = ARRAY_LEN (nat44_ei_handoff_error_strings),
+ .error_strings = nat44_ei_handoff_error_strings,
+};
+
+VLIB_REGISTER_NODE (nat44_ei_in2out_worker_handoff_node) = {
+ .name = "nat44-ei-in2out-worker-handoff",
+ .vector_size = sizeof (u32),
+ .format_trace = format_nat44_ei_handoff_trace,
+ .type = VLIB_NODE_TYPE_INTERNAL,
+ .n_errors = ARRAY_LEN (nat44_ei_handoff_error_strings),
+ .error_strings = nat44_ei_handoff_error_strings,
+};
+
+VLIB_REGISTER_NODE (nat44_ei_out2in_worker_handoff_node) = {
+ .name = "nat44-ei-out2in-worker-handoff",
+ .vector_size = sizeof (u32),
+ .format_trace = format_nat44_ei_handoff_trace,
+ .type = VLIB_NODE_TYPE_INTERNAL,
+ .n_errors = ARRAY_LEN (nat44_ei_handoff_error_strings),
+ .error_strings = nat44_ei_handoff_error_strings,
+};
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */
diff --git a/src/plugins/nat/nat44-ei/nat44_ei_in2out.c b/src/plugins/nat/nat44-ei/nat44_ei_in2out.c
index 54ed1a92e8b..80beb7a49eb 100644
--- a/src/plugins/nat/nat44-ei/nat44_ei_in2out.c
+++ b/src/plugins/nat/nat44-ei/nat44_ei_in2out.c
@@ -14,28 +14,27 @@
*/
/**
* @file
- * @brief NAT44 inside to outside network translation
+ * @brief NAT44 EI inside to outside network translation
*/
#include <vlib/vlib.h>
-#include <vnet/vnet.h>
+#include <vnet/vnet.h>
#include <vnet/ip/ip.h>
#include <vnet/ethernet/ethernet.h>
-#include <vnet/fib/ip4_fib.h>
#include <vnet/udp/udp_local.h>
-#include <nat/nat.h>
-#include <nat/lib/ipfix_logging.h>
-#include <nat/nat_inlines.h>
-#include <nat/lib/nat_syslog.h>
-#include <nat/nat44-ei/nat44_ei_inlines.h>
-#include <nat/nat44-ei/nat44_ei.h>
+#include <vnet/fib/ip4_fib.h>
#include <vppinfra/hash.h>
#include <vppinfra/error.h>
-#include <vppinfra/elog.h>
+
+#include <nat/lib/log.h>
+#include <nat/lib/nat_syslog.h>
+#include <nat/lib/ipfix_logging.h>
#include <nat/lib/nat_inlines.h>
-#include <nat/nat44_hairpinning.h>
+#include <nat/nat44-ei/nat44_ei_inlines.h>
+#include <nat/nat44-ei/nat44_ei.h>
+#include <nat/nat44-ei/nat44_ei_hairpinning.h>
typedef struct
{
@@ -44,15 +43,15 @@ typedef struct
u32 session_index;
u32 is_slow_path;
u32 is_hairpinning;
-} snat_in2out_trace_t;
+} nat44_ei_in2out_trace_t;
/* packet trace format function */
static u8 *
-format_snat_in2out_trace (u8 * s, va_list * args)
+format_nat44_ei_in2out_trace (u8 *s, va_list *args)
{
CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
- snat_in2out_trace_t *t = va_arg (*args, snat_in2out_trace_t *);
+ nat44_ei_in2out_trace_t *t = va_arg (*args, nat44_ei_in2out_trace_t *);
char *tag;
tag = t->is_slow_path ? "NAT44_IN2OUT_SLOW_PATH" : "NAT44_IN2OUT_FAST_PATH";
@@ -68,11 +67,11 @@ format_snat_in2out_trace (u8 * s, va_list * args)
}
static u8 *
-format_snat_in2out_fast_trace (u8 * s, va_list * args)
+format_nat44_ei_in2out_fast_trace (u8 *s, va_list *args)
{
CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
- snat_in2out_trace_t *t = va_arg (*args, snat_in2out_trace_t *);
+ nat44_ei_in2out_trace_t *t = va_arg (*args, nat44_ei_in2out_trace_t *);
s = format (s, "NAT44_IN2OUT_FAST: sw_if_index %d, next index %d",
t->sw_if_index, t->next_index);
@@ -80,67 +79,125 @@ format_snat_in2out_fast_trace (u8 * s, va_list * args)
return s;
}
-#define foreach_snat_in2out_error \
-_(UNSUPPORTED_PROTOCOL, "unsupported protocol") \
-_(OUT_OF_PORTS, "out of ports") \
-_(BAD_OUTSIDE_FIB, "outside VRF ID not found") \
-_(BAD_ICMP_TYPE, "unsupported ICMP type") \
-_(NO_TRANSLATION, "no translation") \
-_(MAX_SESSIONS_EXCEEDED, "maximum sessions exceeded") \
-_(CANNOT_CREATE_USER, "cannot create NAT user")
+#define foreach_nat44_ei_in2out_error \
+ _ (UNSUPPORTED_PROTOCOL, "unsupported protocol") \
+ _ (OUT_OF_PORTS, "out of ports") \
+ _ (BAD_OUTSIDE_FIB, "outside VRF ID not found") \
+ _ (BAD_ICMP_TYPE, "unsupported ICMP type") \
+ _ (NO_TRANSLATION, "no translation") \
+ _ (MAX_SESSIONS_EXCEEDED, "maximum sessions exceeded") \
+ _ (CANNOT_CREATE_USER, "cannot create NAT user")
typedef enum
{
-#define _(sym,str) SNAT_IN2OUT_ERROR_##sym,
- foreach_snat_in2out_error
+#define _(sym, str) NAT44_EI_IN2OUT_ERROR_##sym,
+ foreach_nat44_ei_in2out_error
#undef _
- SNAT_IN2OUT_N_ERROR,
-} snat_in2out_error_t;
+ NAT44_EI_IN2OUT_N_ERROR,
+} nat44_ei_in2out_error_t;
-static char *snat_in2out_error_strings[] = {
+static char *nat44_ei_in2out_error_strings[] = {
#define _(sym,string) string,
- foreach_snat_in2out_error
+ foreach_nat44_ei_in2out_error
#undef _
};
typedef enum
{
- SNAT_IN2OUT_NEXT_LOOKUP,
- SNAT_IN2OUT_NEXT_DROP,
- SNAT_IN2OUT_NEXT_ICMP_ERROR,
- SNAT_IN2OUT_NEXT_SLOW_PATH,
- SNAT_IN2OUT_NEXT_HAIRPINNING_HANDOFF,
- SNAT_IN2OUT_N_NEXT,
-} snat_in2out_next_t;
+ NAT44_EI_IN2OUT_NEXT_LOOKUP,
+ NAT44_EI_IN2OUT_NEXT_DROP,
+ NAT44_EI_IN2OUT_NEXT_ICMP_ERROR,
+ NAT44_EI_IN2OUT_NEXT_SLOW_PATH,
+ NAT44_EI_IN2OUT_NEXT_HAIRPINNING_HANDOFF,
+ NAT44_EI_IN2OUT_N_NEXT,
+} nat44_ei_in2out_next_t;
typedef enum
{
- NAT44_IN2OUT_HAIRPINNING_FINISH_NEXT_DROP,
- NAT44_IN2OUT_HAIRPINNING_FINISH_NEXT_LOOKUP,
- NAT44_IN2OUT_HAIRPINNING_FINISH_N_NEXT,
-} nat44_in2out_hairpinnig_finish_next_t;
+ NAT44_EI_IN2OUT_HAIRPINNING_FINISH_NEXT_DROP,
+ NAT44_EI_IN2OUT_HAIRPINNING_FINISH_NEXT_LOOKUP,
+ NAT44_EI_IN2OUT_HAIRPINNING_FINISH_N_NEXT,
+} nat44_ei_in2out_hairpinnig_finish_next_t;
+
+static inline int
+nat44_ei_not_translate_fast (vlib_node_runtime_t *node, u32 sw_if_index0,
+ ip4_header_t *ip0, u32 proto0, u32 rx_fib_index0)
+{
+ nat44_ei_main_t *nm = &nat44_ei_main;
+
+ if (nm->out2in_dpo)
+ return 0;
+
+ fib_node_index_t fei = FIB_NODE_INDEX_INVALID;
+ nat44_ei_outside_fib_t *outside_fib;
+ fib_prefix_t pfx = {
+ .fp_proto = FIB_PROTOCOL_IP4,
+ .fp_len = 32,
+ .fp_addr = {
+ .ip4.as_u32 = ip0->dst_address.as_u32,
+ }
+ ,
+ };
+
+ /* Don't NAT packet aimed at the intfc address */
+ if (PREDICT_FALSE (nat44_ei_is_interface_addr (
+ nm->ip4_main, node, sw_if_index0, ip0->dst_address.as_u32)))
+ return 1;
+
+ fei = fib_table_lookup (rx_fib_index0, &pfx);
+ if (FIB_NODE_INDEX_INVALID != fei)
+ {
+ u32 sw_if_index = fib_entry_get_resolving_interface (fei);
+ if (sw_if_index == ~0)
+ {
+ vec_foreach (outside_fib, nm->outside_fibs)
+ {
+ fei = fib_table_lookup (outside_fib->fib_index, &pfx);
+ if (FIB_NODE_INDEX_INVALID != fei)
+ {
+ sw_if_index = fib_entry_get_resolving_interface (fei);
+ if (sw_if_index != ~0)
+ break;
+ }
+ }
+ }
+ if (sw_if_index == ~0)
+ return 1;
+
+ nat44_ei_interface_t *i;
+ pool_foreach (i, nm->interfaces)
+ {
+ /* NAT packet aimed at outside interface */
+ if ((nat44_ei_interface_is_outside (i)) &&
+ (sw_if_index == i->sw_if_index))
+ return 0;
+ }
+ }
+
+ return 1;
+}
static inline int
-snat_not_translate (snat_main_t * sm, vlib_node_runtime_t * node,
- u32 sw_if_index0, ip4_header_t * ip0, u32 proto0,
- u32 rx_fib_index0, u32 thread_index)
+nat44_ei_not_translate (nat44_ei_main_t *nm, vlib_node_runtime_t *node,
+ u32 sw_if_index0, ip4_header_t *ip0, u32 proto0,
+ u32 rx_fib_index0, u32 thread_index)
{
udp_header_t *udp0 = ip4_next_header (ip0);
clib_bihash_kv_8_8_t kv0, value0;
- init_nat_k (&kv0, ip0->dst_address, udp0->dst_port, sm->outside_fib_index,
+ init_nat_k (&kv0, ip0->dst_address, udp0->dst_port, nm->outside_fib_index,
proto0);
/* NAT packet aimed at external address if */
/* has active sessions */
- if (clib_bihash_search_8_8 (&sm->out2in, &kv0, &value0))
+ if (clib_bihash_search_8_8 (&nm->out2in, &kv0, &value0))
{
/* or is static mappings */
ip4_address_t placeholder_addr;
u16 placeholder_port;
u32 placeholder_fib_index;
if (!nat44_ei_static_mapping_match (ip0->dst_address, udp0->dst_port,
- sm->outside_fib_index, proto0,
+ nm->outside_fib_index, proto0,
&placeholder_addr, &placeholder_port,
&placeholder_fib_index, 1, 0, 0))
return 0;
@@ -148,37 +205,38 @@ snat_not_translate (snat_main_t * sm, vlib_node_runtime_t * node,
else
return 0;
- if (sm->forwarding_enabled)
+ if (nm->forwarding_enabled)
return 1;
- return snat_not_translate_fast (sm, node, sw_if_index0, ip0, proto0,
- rx_fib_index0);
+ return nat44_ei_not_translate_fast (node, sw_if_index0, ip0, proto0,
+ rx_fib_index0);
}
static inline int
-nat_not_translate_output_feature (snat_main_t * sm, ip4_header_t * ip0,
- u32 proto0, u16 src_port, u16 dst_port,
- u32 thread_index, u32 sw_if_index)
+nat44_ei_not_translate_output_feature (nat44_ei_main_t *nm, ip4_header_t *ip0,
+ u32 proto0, u16 src_port, u16 dst_port,
+ u32 thread_index, u32 sw_if_index)
{
clib_bihash_kv_8_8_t kv0, value0;
- snat_interface_t *i;
+ nat44_ei_interface_t *i;
/* src NAT check */
init_nat_k (&kv0, ip0->src_address, src_port,
ip4_fib_table_get_index_for_sw_if_index (sw_if_index), proto0);
- if (!clib_bihash_search_8_8 (&sm->out2in, &kv0, &value0))
+ if (!clib_bihash_search_8_8 (&nm->out2in, &kv0, &value0))
return 1;
/* dst NAT check */
init_nat_k (&kv0, ip0->dst_address, dst_port,
ip4_fib_table_get_index_for_sw_if_index (sw_if_index), proto0);
- if (!clib_bihash_search_8_8 (&sm->in2out, &kv0, &value0))
+ if (!clib_bihash_search_8_8 (&nm->in2out, &kv0, &value0))
{
/* hairpinning */
- pool_foreach (i, sm->output_feature_interfaces)
+ pool_foreach (i, nm->output_feature_interfaces)
{
- if ((nat_interface_is_inside (i)) && (sw_if_index == i->sw_if_index))
+ if ((nat44_ei_interface_is_inside (i)) &&
+ (sw_if_index == i->sw_if_index))
return 0;
}
return 1;
@@ -191,21 +249,22 @@ nat_not_translate_output_feature (snat_main_t * sm, ip4_header_t * ip0,
int
nat44_i2o_is_idle_session_cb (clib_bihash_kv_8_8_t * kv, void *arg)
{
- snat_main_t *sm = &snat_main;
- nat44_is_idle_session_ctx_t *ctx = arg;
- snat_session_t *s;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nat44_ei_is_idle_session_ctx_t *ctx = arg;
+ nat44_ei_session_t *s;
u64 sess_timeout_time;
- snat_main_per_thread_data_t *tsm = vec_elt_at_index (sm->per_thread_data,
- ctx->thread_index);
+ nat44_ei_main_per_thread_data_t *tnm =
+ vec_elt_at_index (nm->per_thread_data, ctx->thread_index);
clib_bihash_kv_8_8_t s_kv;
- s = pool_elt_at_index (tsm->sessions, kv->value);
- sess_timeout_time = s->last_heard + (f64) nat44_session_get_timeout (sm, s);
+ s = pool_elt_at_index (tnm->sessions, kv->value);
+ sess_timeout_time = s->last_heard + (f64) nat_session_get_timeout (
+ &nm->timeouts, s->nat_proto, s->state);
if (ctx->now >= sess_timeout_time)
{
init_nat_o2i_k (&s_kv, s);
- if (clib_bihash_add_del_8_8 (&sm->out2in, &s_kv, 0))
- nat_elog_warn ("out2in key del failed");
+ if (clib_bihash_add_del_8_8 (&nm->out2in, &s_kv, 0))
+ nat_elog_warn (nm, "out2in key del failed");
nat_ipfix_logging_nat44_ses_delete (ctx->thread_index,
s->in2out.addr.as_u32,
@@ -223,12 +282,12 @@ nat44_i2o_is_idle_session_cb (clib_bihash_kv_8_8_t * kv, void *arg)
s->ext_host_port, s->nat_proto, s->out2in.fib_index,
ctx->thread_index);
- if (!snat_is_session_static (s))
- snat_free_outside_address_and_port (sm->addresses, ctx->thread_index,
- &s->out2in.addr,
- s->out2in.port, s->nat_proto);
+ if (!nat44_ei_is_session_static (s))
+ nat44_ei_free_outside_address_and_port (
+ nm->addresses, ctx->thread_index, &s->out2in.addr, s->out2in.port,
+ s->nat_proto);
- nat44_delete_session (sm, s, ctx->thread_index);
+ nat44_ei_delete_session (nm, s, ctx->thread_index);
return 1;
}
@@ -237,20 +296,16 @@ nat44_i2o_is_idle_session_cb (clib_bihash_kv_8_8_t * kv, void *arg)
#endif
static u32
-slow_path (snat_main_t * sm, vlib_buffer_t * b0,
- ip4_header_t * ip0,
- ip4_address_t i2o_addr,
- u16 i2o_port,
- u32 rx_fib_index0,
- nat_protocol_t nat_proto,
- snat_session_t ** sessionp,
- vlib_node_runtime_t * node, u32 next0, u32 thread_index, f64 now)
+slow_path (nat44_ei_main_t *nm, vlib_buffer_t *b0, ip4_header_t *ip0,
+ ip4_address_t i2o_addr, u16 i2o_port, u32 rx_fib_index0,
+ nat_protocol_t nat_proto, nat44_ei_session_t **sessionp,
+ vlib_node_runtime_t *node, u32 next0, u32 thread_index, f64 now)
{
- snat_user_t *u;
- snat_session_t *s = 0;
+ nat44_ei_user_t *u;
+ nat44_ei_session_t *s = 0;
clib_bihash_kv_8_8_t kv0;
u8 is_sm = 0;
- nat_outside_fib_t *outside_fib;
+ nat44_ei_outside_fib_t *outside_fib;
fib_node_index_t fei = FIB_NODE_INDEX_INVALID;
u8 identity_nat;
fib_prefix_t pfx = {
@@ -260,18 +315,18 @@ slow_path (snat_main_t * sm, vlib_buffer_t * b0,
.ip4.as_u32 = ip0->dst_address.as_u32,
},
};
- nat44_is_idle_session_ctx_t ctx0;
+ nat44_ei_is_idle_session_ctx_t ctx0;
ip4_address_t sm_addr;
u16 sm_port;
u32 sm_fib_index;
- if (PREDICT_FALSE (nat44_ei_maximum_sessions_exceeded (sm, thread_index)))
+ if (PREDICT_FALSE (nat44_ei_maximum_sessions_exceeded (nm, thread_index)))
{
- b0->error = node->errors[SNAT_IN2OUT_ERROR_MAX_SESSIONS_EXCEEDED];
+ b0->error = node->errors[NAT44_EI_IN2OUT_ERROR_MAX_SESSIONS_EXCEEDED];
nat_ipfix_logging_max_sessions (thread_index,
- sm->max_translations_per_thread);
- nat_elog_notice ("maximum sessions exceeded");
- return SNAT_IN2OUT_NEXT_DROP;
+ nm->max_translations_per_thread);
+ nat_elog_notice (nm, "maximum sessions exceeded");
+ return NAT44_EI_IN2OUT_NEXT_DROP;
}
/* First try to match static mapping by local address and port */
@@ -280,13 +335,13 @@ slow_path (snat_main_t * sm, vlib_buffer_t * b0,
&sm_fib_index, 0, 0, &identity_nat))
{
/* Try to create dynamic translation */
- if (sm->alloc_addr_and_port (
- sm->addresses, rx_fib_index0, thread_index, nat_proto, &sm_addr,
- &sm_port, sm->port_per_thread,
- sm->per_thread_data[thread_index].snat_thread_index))
+ if (nm->alloc_addr_and_port (
+ nm->addresses, rx_fib_index0, thread_index, nat_proto, &sm_addr,
+ &sm_port, nm->port_per_thread,
+ nm->per_thread_data[thread_index].snat_thread_index))
{
- b0->error = node->errors[SNAT_IN2OUT_ERROR_OUT_OF_PORTS];
- return SNAT_IN2OUT_NEXT_DROP;
+ b0->error = node->errors[NAT44_EI_IN2OUT_ERROR_OUT_OF_PORTS];
+ return NAT44_EI_IN2OUT_NEXT_DROP;
}
}
else
@@ -300,53 +355,53 @@ slow_path (snat_main_t * sm, vlib_buffer_t * b0,
is_sm = 1;
}
- u = nat_user_get_or_create (sm, &ip0->src_address, rx_fib_index0,
- thread_index);
+ u = nat44_ei_user_get_or_create (nm, &ip0->src_address, rx_fib_index0,
+ thread_index);
if (!u)
{
- b0->error = node->errors[SNAT_IN2OUT_ERROR_CANNOT_CREATE_USER];
- return SNAT_IN2OUT_NEXT_DROP;
+ b0->error = node->errors[NAT44_EI_IN2OUT_ERROR_CANNOT_CREATE_USER];
+ return NAT44_EI_IN2OUT_NEXT_DROP;
}
- s = nat_session_alloc_or_recycle (sm, u, thread_index, now);
+ s = nat44_ei_session_alloc_or_recycle (nm, u, thread_index, now);
if (!s)
{
- nat44_delete_user_with_no_session (sm, u, thread_index);
- nat_elog_warn ("create NAT session failed");
- return SNAT_IN2OUT_NEXT_DROP;
+ nat44_ei_delete_user_with_no_session (nm, u, thread_index);
+ nat_elog_warn (nm, "create NAT session failed");
+ return NAT44_EI_IN2OUT_NEXT_DROP;
}
if (is_sm)
- s->flags |= SNAT_SESSION_FLAG_STATIC_MAPPING;
- user_session_increment (sm, u, is_sm);
+ s->flags |= NAT44_EI_SESSION_FLAG_STATIC_MAPPING;
+ nat44_ei_user_session_increment (nm, u, is_sm);
s->in2out.addr = i2o_addr;
s->in2out.port = i2o_port;
s->in2out.fib_index = rx_fib_index0;
s->nat_proto = nat_proto;
s->out2in.addr = sm_addr;
s->out2in.port = sm_port;
- s->out2in.fib_index = sm->outside_fib_index;
- switch (vec_len (sm->outside_fibs))
+ s->out2in.fib_index = nm->outside_fib_index;
+ switch (vec_len (nm->outside_fibs))
{
case 0:
- s->out2in.fib_index = sm->outside_fib_index;
+ s->out2in.fib_index = nm->outside_fib_index;
break;
case 1:
- s->out2in.fib_index = sm->outside_fibs[0].fib_index;
+ s->out2in.fib_index = nm->outside_fibs[0].fib_index;
break;
default:
- vec_foreach (outside_fib, sm->outside_fibs)
- {
- fei = fib_table_lookup (outside_fib->fib_index, &pfx);
- if (FIB_NODE_INDEX_INVALID != fei)
- {
- if (fib_entry_get_resolving_interface (fei) != ~0)
- {
- s->out2in.fib_index = outside_fib->fib_index;
- break;
- }
- }
- }
+ vec_foreach (outside_fib, nm->outside_fibs)
+ {
+ fei = fib_table_lookup (outside_fib->fib_index, &pfx);
+ if (FIB_NODE_INDEX_INVALID != fei)
+ {
+ if (fib_entry_get_resolving_interface (fei) != ~0)
+ {
+ s->out2in.fib_index = outside_fib->fib_index;
+ break;
+ }
+ }
+ }
break;
}
s->ext_host_addr.as_u32 = ip0->dst_address.as_u32;
@@ -357,41 +412,38 @@ slow_path (snat_main_t * sm, vlib_buffer_t * b0,
ctx0.now = now;
ctx0.thread_index = thread_index;
init_nat_i2o_kv (&kv0, s, thread_index,
- s - sm->per_thread_data[thread_index].sessions);
+ s - nm->per_thread_data[thread_index].sessions);
if (clib_bihash_add_or_overwrite_stale_8_8 (
- &sm->in2out, &kv0, nat44_i2o_is_idle_session_cb, &ctx0))
- nat_elog_notice ("in2out key add failed");
+ &nm->in2out, &kv0, nat44_i2o_is_idle_session_cb, &ctx0))
+ nat_elog_notice (nm, "in2out key add failed");
init_nat_o2i_kv (&kv0, s, thread_index,
- s - sm->per_thread_data[thread_index].sessions);
+ s - nm->per_thread_data[thread_index].sessions);
if (clib_bihash_add_or_overwrite_stale_8_8 (
- &sm->out2in, &kv0, nat44_o2i_is_idle_session_cb, &ctx0))
- nat_elog_notice ("out2in key add failed");
+ &nm->out2in, &kv0, nat44_o2i_is_idle_session_cb, &ctx0))
+ nat_elog_notice (nm, "out2in key add failed");
/* log NAT event */
- nat_ipfix_logging_nat44_ses_create (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_ipfix_logging_nat44_ses_create (
+ 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_syslog_nat44_apmadd (s->user_index, s->in2out.fib_index,
- &s->in2out.addr, s->in2out.port, &s->out2in.addr,
- s->out2in.port, s->nat_proto);
+ nat_syslog_nat44_apmadd (s->user_index, s->in2out.fib_index, &s->in2out.addr,
+ s->in2out.port, &s->out2in.addr, s->out2in.port,
+ s->nat_proto);
nat_ha_sadd (&s->in2out.addr, s->in2out.port, &s->out2in.addr,
s->out2in.port, &s->ext_host_addr, s->ext_host_port,
- &s->ext_host_nat_addr, s->ext_host_nat_port,
- s->nat_proto, s->in2out.fib_index, s->flags, thread_index, 0);
+ &s->ext_host_nat_addr, s->ext_host_nat_port, s->nat_proto,
+ s->in2out.fib_index, s->flags, thread_index, 0);
return next0;
}
#ifndef CLIB_MARCH_VARIANT
-static_always_inline snat_in2out_error_t
-icmp_get_key (vlib_buffer_t * b, ip4_header_t * ip0,
- ip4_address_t * addr, u16 * port, nat_protocol_t * nat_proto)
+static_always_inline nat44_ei_in2out_error_t
+icmp_get_key (vlib_buffer_t *b, ip4_header_t *ip0, ip4_address_t *addr,
+ u16 *port, nat_protocol_t *nat_proto)
{
icmp46_header_t *icmp0;
icmp_echo_header_t *echo0, *inner_echo0 = 0;
@@ -427,7 +479,7 @@ icmp_get_key (vlib_buffer_t * b, ip4_header_t * ip0,
*port = ((tcp_udp_header_t *) l4_header)->dst_port;
break;
default:
- return SNAT_IN2OUT_ERROR_UNSUPPORTED_PROTOCOL;
+ return NAT44_EI_IN2OUT_ERROR_UNSUPPORTED_PROTOCOL;
}
}
return -1; /* success */
@@ -437,7 +489,7 @@ icmp_get_key (vlib_buffer_t * b, ip4_header_t * ip0,
* Get address and port values to be used for ICMP packet translation
* and create session if needed
*
- * @param[in,out] sm NAT main
+ * @param[in,out] nm NAT main
* @param[in,out] node NAT node runtime
* @param[in] thread_index thread index
* @param[in,out] b0 buffer containing packet to be translated
@@ -449,15 +501,16 @@ icmp_get_key (vlib_buffer_t * b, ip4_header_t * ip0,
* @param e optional parameter
*/
u32
-icmp_match_in2out_slow (snat_main_t *sm, vlib_node_runtime_t *node,
- u32 thread_index, vlib_buffer_t *b0, ip4_header_t *ip0,
- ip4_address_t *addr, u16 *port, u32 *fib_index,
- nat_protocol_t *proto, snat_session_t **p_s0,
- u8 *dont_translate)
+nat44_ei_icmp_match_in2out_slow (vlib_node_runtime_t *node, u32 thread_index,
+ vlib_buffer_t *b0, ip4_header_t *ip0,
+ ip4_address_t *addr, u16 *port,
+ u32 *fib_index, nat_protocol_t *proto,
+ nat44_ei_session_t **p_s0, u8 *dont_translate)
{
- snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nat44_ei_main_per_thread_data_t *tnm = &nm->per_thread_data[thread_index];
u32 sw_if_index0;
- snat_session_t *s0 = 0;
+ nat44_ei_session_t *s0 = 0;
clib_bihash_kv_8_8_t kv0, value0;
u32 next0 = ~0;
int err;
@@ -471,18 +524,17 @@ icmp_match_in2out_slow (snat_main_t *sm, vlib_node_runtime_t *node,
if (err != -1)
{
b0->error = node->errors[err];
- next0 = SNAT_IN2OUT_NEXT_DROP;
+ next0 = NAT44_EI_IN2OUT_NEXT_DROP;
goto out;
}
init_nat_k (&kv0, *addr, *port, *fib_index, *proto);
- if (clib_bihash_search_8_8 (&sm->in2out, &kv0, &value0))
+ if (clib_bihash_search_8_8 (&nm->in2out, &kv0, &value0))
{
if (vnet_buffer (b0)->sw_if_index[VLIB_TX] != ~0)
{
- if (PREDICT_FALSE
- (nat_not_translate_output_feature
- (sm, ip0, *proto, *port, *port, thread_index, sw_if_index0)))
+ if (PREDICT_FALSE (nat44_ei_not_translate_output_feature (
+ nm, ip0, *proto, *port, *port, thread_index, sw_if_index0)))
{
*dont_translate = 1;
goto out;
@@ -490,9 +542,9 @@ icmp_match_in2out_slow (snat_main_t *sm, vlib_node_runtime_t *node,
}
else
{
- if (PREDICT_FALSE (snat_not_translate (sm, node, sw_if_index0,
- ip0, NAT_PROTOCOL_ICMP,
- *fib_index, thread_index)))
+ if (PREDICT_FALSE (nat44_ei_not_translate (
+ nm, node, sw_if_index0, ip0, NAT_PROTOCOL_ICMP, *fib_index,
+ thread_index)))
{
*dont_translate = 1;
goto out;
@@ -503,16 +555,15 @@ icmp_match_in2out_slow (snat_main_t *sm, vlib_node_runtime_t *node,
(icmp_type_is_error_message
(vnet_buffer (b0)->ip.reass.icmp_type_or_tcp_flags)))
{
- b0->error = node->errors[SNAT_IN2OUT_ERROR_BAD_ICMP_TYPE];
- next0 = SNAT_IN2OUT_NEXT_DROP;
+ b0->error = node->errors[NAT44_EI_IN2OUT_ERROR_BAD_ICMP_TYPE];
+ next0 = NAT44_EI_IN2OUT_NEXT_DROP;
goto out;
}
- next0 =
- slow_path (sm, b0, ip0, *addr, *port, *fib_index, *proto, &s0, node,
- next0, thread_index, vlib_time_now (vm));
+ next0 = slow_path (nm, b0, ip0, *addr, *port, *fib_index, *proto, &s0,
+ node, next0, thread_index, vlib_time_now (vm));
- if (PREDICT_FALSE (next0 == SNAT_IN2OUT_NEXT_DROP))
+ if (PREDICT_FALSE (next0 == NAT44_EI_IN2OUT_NEXT_DROP))
goto out;
if (!s0)
@@ -531,12 +582,12 @@ icmp_match_in2out_slow (snat_main_t *sm, vlib_node_runtime_t *node,
&& !icmp_type_is_error_message (vnet_buffer (b0)->ip.
reass.icmp_type_or_tcp_flags)))
{
- b0->error = node->errors[SNAT_IN2OUT_ERROR_BAD_ICMP_TYPE];
- next0 = SNAT_IN2OUT_NEXT_DROP;
+ b0->error = node->errors[NAT44_EI_IN2OUT_ERROR_BAD_ICMP_TYPE];
+ next0 = NAT44_EI_IN2OUT_NEXT_DROP;
goto out;
}
- s0 = pool_elt_at_index (tsm->sessions,
+ s0 = pool_elt_at_index (tnm->sessions,
nat_value_get_session_index (&value0));
}
@@ -554,26 +605,12 @@ out:
#endif
#ifndef CLIB_MARCH_VARIANT
-/**
- * Get address and port values to be used for ICMP packet translation
- *
- * @param[in] sm NAT main
- * @param[in,out] node NAT node runtime
- * @param[in] thread_index thread index
- * @param[in,out] b0 buffer containing packet to be translated
- * @param[in,out] ip0 ip header
- * @param[out] p_proto protocol used for matching
- * @param[out] p_value address and port after NAT translation
- * @param[out] p_dont_translate if packet should not be translated
- * @param d optional parameter
- * @param e optional parameter
- */
u32
-icmp_match_in2out_fast (snat_main_t *sm, vlib_node_runtime_t *node,
- u32 thread_index, vlib_buffer_t *b0, ip4_header_t *ip0,
- ip4_address_t *addr, u16 *port, u32 *fib_index,
- nat_protocol_t *proto, snat_session_t **s0,
- u8 *dont_translate)
+nat44_ei_icmp_match_in2out_fast (vlib_node_runtime_t *node, u32 thread_index,
+ vlib_buffer_t *b0, ip4_header_t *ip0,
+ ip4_address_t *addr, u16 *port,
+ u32 *fib_index, nat_protocol_t *proto,
+ nat44_ei_session_t **s0, u8 *dont_translate)
{
u32 sw_if_index0;
u8 is_addr_only;
@@ -588,7 +625,7 @@ icmp_match_in2out_fast (snat_main_t *sm, vlib_node_runtime_t *node,
if (err != -1)
{
b0->error = node->errors[err];
- next0 = SNAT_IN2OUT_NEXT_DROP;
+ next0 = NAT44_EI_IN2OUT_NEXT_DROP;
goto out;
}
@@ -600,9 +637,8 @@ icmp_match_in2out_fast (snat_main_t *sm, vlib_node_runtime_t *node,
&sm_addr, &sm_port, &sm_fib_index, 0,
&is_addr_only, 0))
{
- if (PREDICT_FALSE (snat_not_translate_fast (sm, node, sw_if_index0, ip0,
- IP_PROTOCOL_ICMP,
- *fib_index)))
+ if (PREDICT_FALSE (nat44_ei_not_translate_fast (
+ node, sw_if_index0, ip0, IP_PROTOCOL_ICMP, *fib_index)))
{
*dont_translate = 1;
goto out;
@@ -611,12 +647,12 @@ icmp_match_in2out_fast (snat_main_t *sm, vlib_node_runtime_t *node,
if (icmp_type_is_error_message
(vnet_buffer (b0)->ip.reass.icmp_type_or_tcp_flags))
{
- next0 = SNAT_IN2OUT_NEXT_DROP;
+ next0 = NAT44_EI_IN2OUT_NEXT_DROP;
goto out;
}
- b0->error = node->errors[SNAT_IN2OUT_ERROR_NO_TRANSLATION];
- next0 = SNAT_IN2OUT_NEXT_DROP;
+ b0->error = node->errors[NAT44_EI_IN2OUT_ERROR_NO_TRANSLATION];
+ next0 = NAT44_EI_IN2OUT_NEXT_DROP;
goto out;
}
@@ -627,8 +663,8 @@ icmp_match_in2out_fast (snat_main_t *sm, vlib_node_runtime_t *node,
&& !icmp_type_is_error_message (vnet_buffer (b0)->ip.
reass.icmp_type_or_tcp_flags)))
{
- b0->error = node->errors[SNAT_IN2OUT_ERROR_BAD_ICMP_TYPE];
- next0 = SNAT_IN2OUT_NEXT_DROP;
+ b0->error = node->errors[NAT44_EI_IN2OUT_ERROR_BAD_ICMP_TYPE];
+ next0 = NAT44_EI_IN2OUT_NEXT_DROP;
goto out;
}
@@ -637,23 +673,25 @@ out:
}
#endif
-u32 icmp_in2out (snat_main_t *sm, vlib_buffer_t *b0, ip4_header_t *ip0,
- icmp46_header_t *icmp0, u32 sw_if_index0, u32 rx_fib_index0,
- vlib_node_runtime_t *node, u32 next0, u32 thread_index,
- snat_session_t **p_s0);
+u32 nat44_ei_icmp_in2out (vlib_buffer_t *b0, ip4_header_t *ip0,
+ icmp46_header_t *icmp0, u32 sw_if_index0,
+ u32 rx_fib_index0, vlib_node_runtime_t *node,
+ u32 next0, u32 thread_index,
+ nat44_ei_session_t **p_s0);
#ifndef CLIB_MARCH_VARIANT
u32
-icmp_in2out (snat_main_t *sm, vlib_buffer_t *b0, ip4_header_t *ip0,
- icmp46_header_t *icmp0, u32 sw_if_index0, u32 rx_fib_index0,
- vlib_node_runtime_t *node, u32 next0, u32 thread_index,
- snat_session_t **p_s0)
+nat44_ei_icmp_in2out (vlib_buffer_t *b0, ip4_header_t *ip0,
+ icmp46_header_t *icmp0, u32 sw_if_index0,
+ u32 rx_fib_index0, vlib_node_runtime_t *node, u32 next0,
+ u32 thread_index, nat44_ei_session_t **p_s0)
{
+ nat44_ei_main_t *nm = &nat44_ei_main;
vlib_main_t *vm = vlib_get_main ();
ip4_address_t addr;
u16 port;
u32 fib_index;
- nat_protocol_t protocol;
+ nat_protocol_t proto;
icmp_echo_header_t *echo0, *inner_echo0 = 0;
ip4_header_t *inner_ip0;
void *l4_header = 0;
@@ -669,12 +707,22 @@ icmp_in2out (snat_main_t *sm, vlib_buffer_t *b0, ip4_header_t *ip0,
echo0 = (icmp_echo_header_t *) (icmp0 + 1);
- next0_tmp =
- sm->icmp_match_in2out_cb (sm, node, thread_index, b0, ip0, &addr, &port,
- &fib_index, &protocol, p_s0, &dont_translate);
+ if (PREDICT_TRUE (nm->pat))
+ {
+ next0_tmp = nat44_ei_icmp_match_in2out_slow (
+ node, thread_index, b0, ip0, &addr, &port, &fib_index, &proto, p_s0,
+ &dont_translate);
+ }
+ else
+ {
+ next0_tmp = nat44_ei_icmp_match_in2out_fast (
+ node, thread_index, b0, ip0, &addr, &port, &fib_index, &proto, p_s0,
+ &dont_translate);
+ }
+
if (next0_tmp != ~0)
next0 = next0_tmp;
- if (next0 == SNAT_IN2OUT_NEXT_DROP || dont_translate)
+ if (next0 == NAT44_EI_IN2OUT_NEXT_DROP || dont_translate)
goto out;
if (PREDICT_TRUE (!ip4_is_fragment (ip0)))
@@ -688,7 +736,7 @@ icmp_in2out (snat_main_t *sm, vlib_buffer_t *b0, ip4_header_t *ip0,
checksum0 = ~ip_csum_fold (sum0);
if (PREDICT_FALSE (checksum0 != 0 && checksum0 != 0xffff))
{
- next0 = SNAT_IN2OUT_NEXT_DROP;
+ next0 = NAT44_EI_IN2OUT_NEXT_DROP;
goto out;
}
}
@@ -729,7 +777,7 @@ icmp_in2out (snat_main_t *sm, vlib_buffer_t *b0, ip4_header_t *ip0,
if (!ip4_header_checksum_is_valid (inner_ip0))
{
- next0 = SNAT_IN2OUT_NEXT_DROP;
+ next0 = NAT44_EI_IN2OUT_NEXT_DROP;
goto out;
}
@@ -755,7 +803,7 @@ icmp_in2out (snat_main_t *sm, vlib_buffer_t *b0, ip4_header_t *ip0,
checksum);
icmp0->checksum = ip_csum_fold (sum0);
- switch (protocol)
+ switch (proto)
{
case NAT_PROTOCOL_ICMP:
inner_icmp0 = (icmp46_header_t *) l4_header;
@@ -790,13 +838,13 @@ icmp_in2out (snat_main_t *sm, vlib_buffer_t *b0, ip4_header_t *ip0,
if (vnet_buffer (b0)->sw_if_index[VLIB_TX] == ~0)
{
- if (0 != snat_icmp_hairpinning (sm, b0, thread_index, ip0, icmp0,
- &required_thread_index))
+ if (0 != nat44_ei_icmp_hairpinning (nm, b0, thread_index, ip0, icmp0,
+ &required_thread_index))
vnet_buffer (b0)->sw_if_index[VLIB_TX] = fib_index;
if (thread_index != required_thread_index)
{
vnet_buffer (b0)->snat.required_thread_index = required_thread_index;
- next0 = SNAT_IN2OUT_NEXT_HAIRPINNING_HANDOFF;
+ next0 = NAT44_EI_IN2OUT_NEXT_HAIRPINNING_HANDOFF;
}
}
@@ -805,48 +853,43 @@ out:
}
#endif
-static inline u32
-icmp_in2out_slow_path (snat_main_t * sm,
- vlib_buffer_t * b0,
- ip4_header_t * ip0,
- icmp46_header_t * icmp0,
- u32 sw_if_index0,
- u32 rx_fib_index0,
- vlib_node_runtime_t * node,
- u32 next0,
- f64 now, u32 thread_index, snat_session_t ** p_s0)
+static_always_inline u32
+nat44_ei_icmp_in2out_slow_path (nat44_ei_main_t *nm, vlib_buffer_t *b0,
+ ip4_header_t *ip0, icmp46_header_t *icmp0,
+ u32 sw_if_index0, u32 rx_fib_index0,
+ vlib_node_runtime_t *node, u32 next0, f64 now,
+ u32 thread_index, nat44_ei_session_t **p_s0)
{
vlib_main_t *vm = vlib_get_main ();
- next0 = icmp_in2out (sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node,
- next0, thread_index, p_s0);
- snat_session_t *s0 = *p_s0;
- if (PREDICT_TRUE (next0 != SNAT_IN2OUT_NEXT_DROP && s0))
+ next0 = nat44_ei_icmp_in2out (b0, ip0, icmp0, sw_if_index0, rx_fib_index0,
+ node, next0, thread_index, p_s0);
+ nat44_ei_session_t *s0 = *p_s0;
+ if (PREDICT_TRUE (next0 != NAT44_EI_IN2OUT_NEXT_DROP && s0))
{
/* Accounting */
nat44_ei_session_update_counters (
s0, now, vlib_buffer_length_in_chain (vm, b0), thread_index);
/* Per-user LRU list maintenance */
- nat44_session_update_lru (sm, s0, thread_index);
+ nat44_ei_session_update_lru (nm, s0, thread_index);
}
return next0;
}
static int
-nat_in2out_sm_unknown_proto (snat_main_t * sm,
- vlib_buffer_t * b,
- ip4_header_t * ip, u32 rx_fib_index)
+nat_in2out_sm_unknown_proto (nat44_ei_main_t *nm, vlib_buffer_t *b,
+ ip4_header_t *ip, u32 rx_fib_index)
{
clib_bihash_kv_8_8_t kv, value;
- snat_static_mapping_t *m;
+ nat44_ei_static_mapping_t *m;
u32 old_addr, new_addr;
ip_csum_t sum;
init_nat_k (&kv, ip->src_address, 0, rx_fib_index, 0);
- if (clib_bihash_search_8_8 (&sm->static_mapping_by_local, &kv, &value))
+ if (clib_bihash_search_8_8 (&nm->static_mapping_by_local, &kv, &value))
return 1;
- m = pool_elt_at_index (sm->static_mappings, value.value);
+ m = pool_elt_at_index (nm->static_mappings, value.value);
old_addr = ip->src_address.as_u32;
new_addr = ip->src_address.as_u32 = m->external_addr.as_u32;
@@ -859,20 +902,19 @@ nat_in2out_sm_unknown_proto (snat_main_t * sm,
if (vnet_buffer (b)->sw_if_index[VLIB_TX] == ~0)
{
vnet_buffer (b)->sw_if_index[VLIB_TX] = m->fib_index;
- nat_hairpinning_sm_unknown_proto (sm, b, ip);
+ nat44_ei_hairpinning_sm_unknown_proto (nm, b, ip);
}
return 0;
}
static inline uword
-snat_in2out_node_fn_inline (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame, int is_slow_path,
- int is_output_feature)
+nat44_ei_in2out_node_fn_inline (vlib_main_t *vm, vlib_node_runtime_t *node,
+ vlib_frame_t *frame, int is_slow_path,
+ int is_output_feature)
{
u32 n_left_from, *from;
- snat_main_t *sm = &snat_main;
+ nat44_ei_main_t *nm = &nat44_ei_main;
f64 now = vlib_time_now (vm);
u32 thread_index = vm->thread_index;
@@ -897,7 +939,7 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
icmp46_header_t *icmp0, *icmp1;
u32 rx_fib_index0, rx_fib_index1;
u32 proto0, proto1;
- snat_session_t *s0 = 0, *s1 = 0;
+ nat44_ei_session_t *s0 = 0, *s1 = 0;
clib_bihash_kv_8_8_t kv0, value0, kv1, value1;
u32 iph_offset0 = 0, iph_offset1 = 0;
@@ -932,10 +974,10 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
icmp0 = (icmp46_header_t *) udp0;
sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
- rx_fib_index0 = vec_elt (sm->ip4_main->fib_index_by_sw_if_index,
- sw_if_index0);
+ rx_fib_index0 =
+ vec_elt (nm->ip4_main->fib_index_by_sw_if_index, sw_if_index0);
- next0 = next1 = SNAT_IN2OUT_NEXT_LOOKUP;
+ next0 = next1 = NAT44_EI_IN2OUT_NEXT_LOOKUP;
if (PREDICT_FALSE (ip0->ttl == 1))
{
@@ -943,7 +985,7 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
icmp4_error_set_vnet_buffer (b0, ICMP4_time_exceeded,
ICMP4_time_exceeded_ttl_exceeded_in_transit,
0);
- next0 = SNAT_IN2OUT_NEXT_ICMP_ERROR;
+ next0 = NAT44_EI_IN2OUT_NEXT_ICMP_ERROR;
goto trace00;
}
@@ -954,30 +996,28 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
{
if (PREDICT_FALSE (proto0 == NAT_PROTOCOL_OTHER))
{
- if (nat_in2out_sm_unknown_proto (sm, b0, ip0, rx_fib_index0))
+ if (nat_in2out_sm_unknown_proto (nm, b0, ip0, rx_fib_index0))
{
- next0 = SNAT_IN2OUT_NEXT_DROP;
+ next0 = NAT44_EI_IN2OUT_NEXT_DROP;
b0->error =
- node->errors[SNAT_IN2OUT_ERROR_UNSUPPORTED_PROTOCOL];
+ node->errors[NAT44_EI_IN2OUT_ERROR_UNSUPPORTED_PROTOCOL];
}
- vlib_increment_simple_counter (is_slow_path ? &sm->
- counters.slowpath.in2out.
- other : &sm->counters.fastpath.
- in2out.other, thread_index,
- sw_if_index0, 1);
+ vlib_increment_simple_counter (
+ is_slow_path ? &nm->counters.slowpath.in2out.other :
+ &nm->counters.fastpath.in2out.other,
+ thread_index, sw_if_index0, 1);
goto trace00;
}
if (PREDICT_FALSE (proto0 == NAT_PROTOCOL_ICMP))
{
- next0 = icmp_in2out_slow_path
- (sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0,
- node, next0, now, thread_index, &s0);
- vlib_increment_simple_counter (is_slow_path ? &sm->
- counters.slowpath.in2out.
- icmp : &sm->counters.fastpath.
- in2out.icmp, thread_index,
- sw_if_index0, 1);
+ next0 = nat44_ei_icmp_in2out_slow_path (
+ nm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node, next0,
+ now, thread_index, &s0);
+ vlib_increment_simple_counter (
+ is_slow_path ? &nm->counters.slowpath.in2out.icmp :
+ &nm->counters.fastpath.in2out.icmp,
+ thread_index, sw_if_index0, 1);
goto trace00;
}
}
@@ -985,13 +1025,13 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
{
if (PREDICT_FALSE (proto0 == NAT_PROTOCOL_OTHER))
{
- next0 = SNAT_IN2OUT_NEXT_SLOW_PATH;
+ next0 = NAT44_EI_IN2OUT_NEXT_SLOW_PATH;
goto trace00;
}
if (PREDICT_FALSE (proto0 == NAT_PROTOCOL_ICMP))
{
- next0 = SNAT_IN2OUT_NEXT_SLOW_PATH;
+ next0 = NAT44_EI_IN2OUT_NEXT_SLOW_PATH;
goto trace00;
}
}
@@ -999,19 +1039,18 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
init_nat_k (&kv0, ip0->src_address,
vnet_buffer (b0)->ip.reass.l4_src_port, rx_fib_index0,
proto0);
- if (PREDICT_FALSE (clib_bihash_search_8_8 (&sm->in2out, &kv0, &value0) !=
+ if (PREDICT_FALSE (clib_bihash_search_8_8 (&nm->in2out, &kv0, &value0) !=
0))
{
if (is_slow_path)
{
if (is_output_feature)
{
- if (PREDICT_FALSE
- (nat_not_translate_output_feature
- (sm, ip0, proto0,
+ if (PREDICT_FALSE (nat44_ei_not_translate_output_feature (
+ nm, ip0, proto0,
vnet_buffer (b0)->ip.reass.l4_src_port,
- vnet_buffer (b0)->ip.reass.l4_dst_port,
- thread_index, sw_if_index0)))
+ vnet_buffer (b0)->ip.reass.l4_dst_port, thread_index,
+ sw_if_index0)))
goto trace00;
/*
@@ -1028,19 +1067,17 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
}
else
{
- if (PREDICT_FALSE
- (snat_not_translate
- (sm, node, sw_if_index0, ip0, proto0,
- rx_fib_index0, thread_index)))
+ if (PREDICT_FALSE (nat44_ei_not_translate (
+ nm, node, sw_if_index0, ip0, proto0, rx_fib_index0,
+ thread_index)))
goto trace00;
}
- next0 = slow_path (sm, b0, ip0,
- ip0->src_address,
+ next0 = slow_path (nm, b0, ip0, ip0->src_address,
vnet_buffer (b0)->ip.reass.l4_src_port,
- rx_fib_index0,
- proto0, &s0, node, next0, thread_index, now);
- if (PREDICT_FALSE (next0 == SNAT_IN2OUT_NEXT_DROP))
+ rx_fib_index0, proto0, &s0, node, next0,
+ thread_index, now);
+ if (PREDICT_FALSE (next0 == NAT44_EI_IN2OUT_NEXT_DROP))
goto trace00;
if (PREDICT_FALSE (!s0))
@@ -1048,12 +1085,12 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
}
else
{
- next0 = SNAT_IN2OUT_NEXT_SLOW_PATH;
+ next0 = NAT44_EI_IN2OUT_NEXT_SLOW_PATH;
goto trace00;
}
}
else
- s0 = pool_elt_at_index (sm->per_thread_data[thread_index].sessions,
+ s0 = pool_elt_at_index (nm->per_thread_data[thread_index].sessions,
nat_value_get_session_index (&value0));
b0->flags |= VNET_BUFFER_F_IS_NATED;
@@ -1083,12 +1120,12 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
sum0 = ip_csum_update (sum0, old_port0, new_port0,
ip4_header_t /* cheat */ ,
length /* changed member */ );
- mss_clamping (sm->mss_clamping, tcp0, &sum0);
+ mss_clamping (nm->mss_clamping, tcp0, &sum0);
tcp0->checksum = ip_csum_fold (sum0);
}
- vlib_increment_simple_counter (is_slow_path ? &sm->
- counters.slowpath.in2out.tcp : &sm->
- counters.fastpath.in2out.tcp,
+ vlib_increment_simple_counter (is_slow_path ?
+ &nm->counters.slowpath.in2out.tcp :
+ &nm->counters.fastpath.in2out.tcp,
thread_index, sw_if_index0, 1);
}
else
@@ -1110,9 +1147,9 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
udp0->checksum = ip_csum_fold (sum0);
}
}
- vlib_increment_simple_counter (is_slow_path ? &sm->
- counters.slowpath.in2out.udp : &sm->
- counters.fastpath.in2out.udp,
+ vlib_increment_simple_counter (is_slow_path ?
+ &nm->counters.slowpath.in2out.udp :
+ &nm->counters.fastpath.in2out.udp,
thread_index, sw_if_index0, 1);
}
@@ -1120,29 +1157,28 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
nat44_ei_session_update_counters (
s0, now, vlib_buffer_length_in_chain (vm, b0), thread_index);
/* Per-user LRU list maintenance */
- nat44_session_update_lru (sm, s0, thread_index);
+ nat44_ei_session_update_lru (nm, s0, thread_index);
trace00:
if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)
&& (b0->flags & VLIB_BUFFER_IS_TRACED)))
{
- snat_in2out_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t));
+ nat44_ei_in2out_trace_t *t =
+ vlib_add_trace (vm, node, b0, sizeof (*t));
t->is_slow_path = is_slow_path;
t->sw_if_index = sw_if_index0;
t->next_index = next0;
t->session_index = ~0;
if (s0)
- t->session_index =
- s0 - sm->per_thread_data[thread_index].sessions;
+ t->session_index = s0 - nm->per_thread_data[thread_index].sessions;
}
- if (next0 == SNAT_IN2OUT_NEXT_DROP)
+ if (next0 == NAT44_EI_IN2OUT_NEXT_DROP)
{
- vlib_increment_simple_counter (is_slow_path ? &sm->
- counters.slowpath.in2out.
- drops : &sm->counters.fastpath.
- in2out.drops, thread_index,
- sw_if_index0, 1);
+ vlib_increment_simple_counter (
+ is_slow_path ? &nm->counters.slowpath.in2out.drops :
+ &nm->counters.fastpath.in2out.drops,
+ thread_index, sw_if_index0, 1);
}
if (is_output_feature)
@@ -1156,8 +1192,8 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
icmp1 = (icmp46_header_t *) udp1;
sw_if_index1 = vnet_buffer (b1)->sw_if_index[VLIB_RX];
- rx_fib_index1 = vec_elt (sm->ip4_main->fib_index_by_sw_if_index,
- sw_if_index1);
+ rx_fib_index1 =
+ vec_elt (nm->ip4_main->fib_index_by_sw_if_index, sw_if_index1);
if (PREDICT_FALSE (ip1->ttl == 1))
{
@@ -1165,7 +1201,7 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
icmp4_error_set_vnet_buffer (b1, ICMP4_time_exceeded,
ICMP4_time_exceeded_ttl_exceeded_in_transit,
0);
- next1 = SNAT_IN2OUT_NEXT_ICMP_ERROR;
+ next1 = NAT44_EI_IN2OUT_NEXT_ICMP_ERROR;
goto trace01;
}
@@ -1176,30 +1212,28 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
{
if (PREDICT_FALSE (proto1 == NAT_PROTOCOL_OTHER))
{
- if (nat_in2out_sm_unknown_proto (sm, b1, ip1, rx_fib_index1))
+ if (nat_in2out_sm_unknown_proto (nm, b1, ip1, rx_fib_index1))
{
- next1 = SNAT_IN2OUT_NEXT_DROP;
+ next1 = NAT44_EI_IN2OUT_NEXT_DROP;
b1->error =
- node->errors[SNAT_IN2OUT_ERROR_UNSUPPORTED_PROTOCOL];
+ node->errors[NAT44_EI_IN2OUT_ERROR_UNSUPPORTED_PROTOCOL];
}
- vlib_increment_simple_counter (is_slow_path ? &sm->
- counters.slowpath.in2out.
- other : &sm->counters.fastpath.
- in2out.other, thread_index,
- sw_if_index1, 1);
+ vlib_increment_simple_counter (
+ is_slow_path ? &nm->counters.slowpath.in2out.other :
+ &nm->counters.fastpath.in2out.other,
+ thread_index, sw_if_index1, 1);
goto trace01;
}
if (PREDICT_FALSE (proto1 == NAT_PROTOCOL_ICMP))
{
- next1 = icmp_in2out_slow_path
- (sm, b1, ip1, icmp1, sw_if_index1, rx_fib_index1, node,
- next1, now, thread_index, &s1);
- vlib_increment_simple_counter (is_slow_path ? &sm->
- counters.slowpath.in2out.
- icmp : &sm->counters.fastpath.
- in2out.icmp, thread_index,
- sw_if_index1, 1);
+ next1 = nat44_ei_icmp_in2out_slow_path (
+ nm, b1, ip1, icmp1, sw_if_index1, rx_fib_index1, node, next1,
+ now, thread_index, &s1);
+ vlib_increment_simple_counter (
+ is_slow_path ? &nm->counters.slowpath.in2out.icmp :
+ &nm->counters.fastpath.in2out.icmp,
+ thread_index, sw_if_index1, 1);
goto trace01;
}
}
@@ -1207,13 +1241,13 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
{
if (PREDICT_FALSE (proto1 == NAT_PROTOCOL_OTHER))
{
- next1 = SNAT_IN2OUT_NEXT_SLOW_PATH;
+ next1 = NAT44_EI_IN2OUT_NEXT_SLOW_PATH;
goto trace01;
}
if (PREDICT_FALSE (proto1 == NAT_PROTOCOL_ICMP))
{
- next1 = SNAT_IN2OUT_NEXT_SLOW_PATH;
+ next1 = NAT44_EI_IN2OUT_NEXT_SLOW_PATH;
goto trace01;
}
}
@@ -1221,19 +1255,18 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
init_nat_k (&kv1, ip1->src_address,
vnet_buffer (b1)->ip.reass.l4_src_port, rx_fib_index1,
proto1);
- if (PREDICT_FALSE (clib_bihash_search_8_8 (&sm->in2out, &kv1, &value1) !=
+ if (PREDICT_FALSE (clib_bihash_search_8_8 (&nm->in2out, &kv1, &value1) !=
0))
{
if (is_slow_path)
{
if (is_output_feature)
{
- if (PREDICT_FALSE
- (nat_not_translate_output_feature
- (sm, ip1, proto1,
+ if (PREDICT_FALSE (nat44_ei_not_translate_output_feature (
+ nm, ip1, proto1,
vnet_buffer (b1)->ip.reass.l4_src_port,
- vnet_buffer (b1)->ip.reass.l4_dst_port,
- thread_index, sw_if_index1)))
+ vnet_buffer (b1)->ip.reass.l4_dst_port, thread_index,
+ sw_if_index1)))
goto trace01;
/*
@@ -1250,19 +1283,17 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
}
else
{
- if (PREDICT_FALSE
- (snat_not_translate
- (sm, node, sw_if_index1, ip1, proto1,
- rx_fib_index1, thread_index)))
+ if (PREDICT_FALSE (nat44_ei_not_translate (
+ nm, node, sw_if_index1, ip1, proto1, rx_fib_index1,
+ thread_index)))
goto trace01;
}
- next1 =
- slow_path (sm, b1, ip1, ip1->src_address,
- vnet_buffer (b1)->ip.reass.l4_src_port,
- rx_fib_index1, proto1, &s1, node, next1,
- thread_index, now);
- if (PREDICT_FALSE (next1 == SNAT_IN2OUT_NEXT_DROP))
+ next1 = slow_path (nm, b1, ip1, ip1->src_address,
+ vnet_buffer (b1)->ip.reass.l4_src_port,
+ rx_fib_index1, proto1, &s1, node, next1,
+ thread_index, now);
+ if (PREDICT_FALSE (next1 == NAT44_EI_IN2OUT_NEXT_DROP))
goto trace01;
if (PREDICT_FALSE (!s1))
@@ -1270,12 +1301,12 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
}
else
{
- next1 = SNAT_IN2OUT_NEXT_SLOW_PATH;
+ next1 = NAT44_EI_IN2OUT_NEXT_SLOW_PATH;
goto trace01;
}
}
else
- s1 = pool_elt_at_index (sm->per_thread_data[thread_index].sessions,
+ s1 = pool_elt_at_index (nm->per_thread_data[thread_index].sessions,
nat_value_get_session_index (&value1));
b1->flags |= VNET_BUFFER_F_IS_NATED;
@@ -1304,12 +1335,12 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
sum1 = ip_csum_update (sum1, old_port1, new_port1,
ip4_header_t /* cheat */ ,
length /* changed member */ );
- mss_clamping (sm->mss_clamping, tcp1, &sum1);
+ mss_clamping (nm->mss_clamping, tcp1, &sum1);
tcp1->checksum = ip_csum_fold (sum1);
}
- vlib_increment_simple_counter (is_slow_path ? &sm->
- counters.slowpath.in2out.tcp : &sm->
- counters.fastpath.in2out.tcp,
+ vlib_increment_simple_counter (is_slow_path ?
+ &nm->counters.slowpath.in2out.tcp :
+ &nm->counters.fastpath.in2out.tcp,
thread_index, sw_if_index1, 1);
}
else
@@ -1331,9 +1362,9 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
udp1->checksum = ip_csum_fold (sum1);
}
}
- vlib_increment_simple_counter (is_slow_path ? &sm->
- counters.slowpath.in2out.udp : &sm->
- counters.fastpath.in2out.udp,
+ vlib_increment_simple_counter (is_slow_path ?
+ &nm->counters.slowpath.in2out.udp :
+ &nm->counters.fastpath.in2out.udp,
thread_index, sw_if_index1, 1);
}
@@ -1341,28 +1372,27 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
nat44_ei_session_update_counters (
s1, now, vlib_buffer_length_in_chain (vm, b1), thread_index);
/* Per-user LRU list maintenance */
- nat44_session_update_lru (sm, s1, thread_index);
+ nat44_ei_session_update_lru (nm, s1, thread_index);
trace01:
if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)
&& (b1->flags & VLIB_BUFFER_IS_TRACED)))
{
- snat_in2out_trace_t *t = vlib_add_trace (vm, node, b1, sizeof (*t));
+ nat44_ei_in2out_trace_t *t =
+ vlib_add_trace (vm, node, b1, sizeof (*t));
t->sw_if_index = sw_if_index1;
t->next_index = next1;
t->session_index = ~0;
if (s1)
- t->session_index =
- s1 - sm->per_thread_data[thread_index].sessions;
+ t->session_index = s1 - nm->per_thread_data[thread_index].sessions;
}
- if (next1 == SNAT_IN2OUT_NEXT_DROP)
+ if (next1 == NAT44_EI_IN2OUT_NEXT_DROP)
{
- vlib_increment_simple_counter (is_slow_path ? &sm->
- counters.slowpath.in2out.
- drops : &sm->counters.fastpath.
- in2out.drops, thread_index,
- sw_if_index1, 1);
+ vlib_increment_simple_counter (
+ is_slow_path ? &nm->counters.slowpath.in2out.drops :
+ &nm->counters.fastpath.in2out.drops,
+ thread_index, sw_if_index1, 1);
}
n_left_from -= 2;
@@ -1385,13 +1415,13 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
icmp46_header_t *icmp0;
u32 rx_fib_index0;
u32 proto0;
- snat_session_t *s0 = 0;
+ nat44_ei_session_t *s0 = 0;
clib_bihash_kv_8_8_t kv0, value0;
u32 iph_offset0 = 0;
b0 = *b;
b++;
- next0 = SNAT_IN2OUT_NEXT_LOOKUP;
+ next0 = NAT44_EI_IN2OUT_NEXT_LOOKUP;
if (is_output_feature)
iph_offset0 = vnet_buffer (b0)->ip.reass.save_rewrite_length;
@@ -1404,8 +1434,8 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
icmp0 = (icmp46_header_t *) udp0;
sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
- rx_fib_index0 = vec_elt (sm->ip4_main->fib_index_by_sw_if_index,
- sw_if_index0);
+ rx_fib_index0 =
+ vec_elt (nm->ip4_main->fib_index_by_sw_if_index, sw_if_index0);
if (PREDICT_FALSE (ip0->ttl == 1))
{
@@ -1413,7 +1443,7 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
icmp4_error_set_vnet_buffer (b0, ICMP4_time_exceeded,
ICMP4_time_exceeded_ttl_exceeded_in_transit,
0);
- next0 = SNAT_IN2OUT_NEXT_ICMP_ERROR;
+ next0 = NAT44_EI_IN2OUT_NEXT_ICMP_ERROR;
goto trace0;
}
@@ -1424,30 +1454,28 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
{
if (PREDICT_FALSE (proto0 == NAT_PROTOCOL_OTHER))
{
- if (nat_in2out_sm_unknown_proto (sm, b0, ip0, rx_fib_index0))
+ if (nat_in2out_sm_unknown_proto (nm, b0, ip0, rx_fib_index0))
{
- next0 = SNAT_IN2OUT_NEXT_DROP;
+ next0 = NAT44_EI_IN2OUT_NEXT_DROP;
b0->error =
- node->errors[SNAT_IN2OUT_ERROR_UNSUPPORTED_PROTOCOL];
+ node->errors[NAT44_EI_IN2OUT_ERROR_UNSUPPORTED_PROTOCOL];
}
- vlib_increment_simple_counter (is_slow_path ? &sm->
- counters.slowpath.in2out.
- other : &sm->counters.fastpath.
- in2out.other, thread_index,
- sw_if_index0, 1);
+ vlib_increment_simple_counter (
+ is_slow_path ? &nm->counters.slowpath.in2out.other :
+ &nm->counters.fastpath.in2out.other,
+ thread_index, sw_if_index0, 1);
goto trace0;
}
if (PREDICT_FALSE (proto0 == NAT_PROTOCOL_ICMP))
{
- next0 = icmp_in2out_slow_path
- (sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node,
- next0, now, thread_index, &s0);
- vlib_increment_simple_counter (is_slow_path ? &sm->
- counters.slowpath.in2out.
- icmp : &sm->counters.fastpath.
- in2out.icmp, thread_index,
- sw_if_index0, 1);
+ next0 = nat44_ei_icmp_in2out_slow_path (
+ nm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node, next0,
+ now, thread_index, &s0);
+ vlib_increment_simple_counter (
+ is_slow_path ? &nm->counters.slowpath.in2out.icmp :
+ &nm->counters.fastpath.in2out.icmp,
+ thread_index, sw_if_index0, 1);
goto trace0;
}
}
@@ -1455,13 +1483,13 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
{
if (PREDICT_FALSE (proto0 == NAT_PROTOCOL_OTHER))
{
- next0 = SNAT_IN2OUT_NEXT_SLOW_PATH;
+ next0 = NAT44_EI_IN2OUT_NEXT_SLOW_PATH;
goto trace0;
}
if (PREDICT_FALSE (proto0 == NAT_PROTOCOL_ICMP))
{
- next0 = SNAT_IN2OUT_NEXT_SLOW_PATH;
+ next0 = NAT44_EI_IN2OUT_NEXT_SLOW_PATH;
goto trace0;
}
}
@@ -1470,18 +1498,17 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
vnet_buffer (b0)->ip.reass.l4_src_port, rx_fib_index0,
proto0);
- if (clib_bihash_search_8_8 (&sm->in2out, &kv0, &value0))
+ if (clib_bihash_search_8_8 (&nm->in2out, &kv0, &value0))
{
if (is_slow_path)
{
if (is_output_feature)
{
- if (PREDICT_FALSE
- (nat_not_translate_output_feature
- (sm, ip0, proto0,
+ if (PREDICT_FALSE (nat44_ei_not_translate_output_feature (
+ nm, ip0, proto0,
vnet_buffer (b0)->ip.reass.l4_src_port,
- vnet_buffer (b0)->ip.reass.l4_dst_port,
- thread_index, sw_if_index0)))
+ vnet_buffer (b0)->ip.reass.l4_dst_port, thread_index,
+ sw_if_index0)))
goto trace0;
/*
@@ -1498,20 +1525,18 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
}
else
{
- if (PREDICT_FALSE
- (snat_not_translate
- (sm, node, sw_if_index0, ip0, proto0, rx_fib_index0,
+ if (PREDICT_FALSE (nat44_ei_not_translate (
+ nm, node, sw_if_index0, ip0, proto0, rx_fib_index0,
thread_index)))
goto trace0;
}
- next0 =
- slow_path (sm, b0, ip0, ip0->src_address,
- vnet_buffer (b0)->ip.reass.l4_src_port,
- rx_fib_index0, proto0, &s0, node, next0,
- thread_index, now);
+ next0 = slow_path (nm, b0, ip0, ip0->src_address,
+ vnet_buffer (b0)->ip.reass.l4_src_port,
+ rx_fib_index0, proto0, &s0, node, next0,
+ thread_index, now);
- if (PREDICT_FALSE (next0 == SNAT_IN2OUT_NEXT_DROP))
+ if (PREDICT_FALSE (next0 == NAT44_EI_IN2OUT_NEXT_DROP))
goto trace0;
if (PREDICT_FALSE (!s0))
@@ -1519,12 +1544,12 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
}
else
{
- next0 = SNAT_IN2OUT_NEXT_SLOW_PATH;
+ next0 = NAT44_EI_IN2OUT_NEXT_SLOW_PATH;
goto trace0;
}
}
else
- s0 = pool_elt_at_index (sm->per_thread_data[thread_index].sessions,
+ s0 = pool_elt_at_index (nm->per_thread_data[thread_index].sessions,
nat_value_get_session_index (&value0));
b0->flags |= VNET_BUFFER_F_IS_NATED;
@@ -1554,12 +1579,12 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
ip_csum_update (sum0, old_port0, new_port0,
ip4_header_t /* cheat */ ,
length /* changed member */ );
- mss_clamping (sm->mss_clamping, tcp0, &sum0);
+ mss_clamping (nm->mss_clamping, tcp0, &sum0);
tcp0->checksum = ip_csum_fold (sum0);
}
- vlib_increment_simple_counter (is_slow_path ? &sm->
- counters.slowpath.in2out.tcp : &sm->
- counters.fastpath.in2out.tcp,
+ vlib_increment_simple_counter (is_slow_path ?
+ &nm->counters.slowpath.in2out.tcp :
+ &nm->counters.fastpath.in2out.tcp,
thread_index, sw_if_index0, 1);
}
else
@@ -1582,9 +1607,9 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
udp0->checksum = ip_csum_fold (sum0);
}
}
- vlib_increment_simple_counter (is_slow_path ? &sm->
- counters.slowpath.in2out.udp : &sm->
- counters.fastpath.in2out.udp,
+ vlib_increment_simple_counter (is_slow_path ?
+ &nm->counters.slowpath.in2out.udp :
+ &nm->counters.fastpath.in2out.udp,
thread_index, sw_if_index0, 1);
}
@@ -1592,29 +1617,28 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
nat44_ei_session_update_counters (
s0, now, vlib_buffer_length_in_chain (vm, b0), thread_index);
/* Per-user LRU list maintenance */
- nat44_session_update_lru (sm, s0, thread_index);
+ nat44_ei_session_update_lru (nm, s0, thread_index);
trace0:
if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)
&& (b0->flags & VLIB_BUFFER_IS_TRACED)))
{
- snat_in2out_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t));
+ nat44_ei_in2out_trace_t *t =
+ vlib_add_trace (vm, node, b0, sizeof (*t));
t->is_slow_path = is_slow_path;
t->sw_if_index = sw_if_index0;
t->next_index = next0;
t->session_index = ~0;
if (s0)
- t->session_index =
- s0 - sm->per_thread_data[thread_index].sessions;
+ t->session_index = s0 - nm->per_thread_data[thread_index].sessions;
}
- if (next0 == SNAT_IN2OUT_NEXT_DROP)
+ if (next0 == NAT44_EI_IN2OUT_NEXT_DROP)
{
- vlib_increment_simple_counter (is_slow_path ? &sm->
- counters.slowpath.in2out.
- drops : &sm->counters.fastpath.
- in2out.drops, thread_index,
- sw_if_index0, 1);
+ vlib_increment_simple_counter (
+ is_slow_path ? &nm->counters.slowpath.in2out.drops :
+ &nm->counters.fastpath.in2out.drops,
+ thread_index, sw_if_index0, 1);
}
n_left_from--;
@@ -1627,138 +1651,133 @@ snat_in2out_node_fn_inline (vlib_main_t * vm,
return frame->n_vectors;
}
-VLIB_NODE_FN (snat_in2out_node) (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
+VLIB_NODE_FN (nat44_ei_in2out_node)
+(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
{
- return snat_in2out_node_fn_inline (vm, node, frame, 0 /* is_slow_path */ ,
- 0);
+ return nat44_ei_in2out_node_fn_inline (vm, node, frame, 0 /* is_slow_path */,
+ 0);
}
-VLIB_REGISTER_NODE (snat_in2out_node) = {
- .name = "nat44-in2out",
+VLIB_REGISTER_NODE (nat44_ei_in2out_node) = {
+ .name = "nat44-ei-in2out",
.vector_size = sizeof (u32),
- .format_trace = format_snat_in2out_trace,
+ .format_trace = format_nat44_ei_in2out_trace,
.type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN(snat_in2out_error_strings),
- .error_strings = snat_in2out_error_strings,
+ .n_errors = ARRAY_LEN(nat44_ei_in2out_error_strings),
+ .error_strings = nat44_ei_in2out_error_strings,
- .runtime_data_bytes = sizeof (snat_runtime_t),
+ .runtime_data_bytes = sizeof (nat44_ei_runtime_t),
- .n_next_nodes = SNAT_IN2OUT_N_NEXT,
+ .n_next_nodes = NAT44_EI_IN2OUT_N_NEXT,
/* edit / add dispositions here */
.next_nodes = {
- [SNAT_IN2OUT_NEXT_DROP] = "error-drop",
- [SNAT_IN2OUT_NEXT_LOOKUP] = "ip4-lookup",
- [SNAT_IN2OUT_NEXT_SLOW_PATH] = "nat44-in2out-slowpath",
- [SNAT_IN2OUT_NEXT_ICMP_ERROR] = "ip4-icmp-error",
- [SNAT_IN2OUT_NEXT_HAIRPINNING_HANDOFF] = "nat44-in2out-hairpinning-handoff-ip4-lookup",
+ [NAT44_EI_IN2OUT_NEXT_DROP] = "error-drop",
+ [NAT44_EI_IN2OUT_NEXT_LOOKUP] = "ip4-lookup",
+ [NAT44_EI_IN2OUT_NEXT_SLOW_PATH] = "nat44-ei-in2out-slowpath",
+ [NAT44_EI_IN2OUT_NEXT_ICMP_ERROR] = "ip4-icmp-error",
+ [NAT44_EI_IN2OUT_NEXT_HAIRPINNING_HANDOFF] = "nat44-ei-in2out-hairpinning-handoff-ip4-lookup",
},
};
-VLIB_NODE_FN (snat_in2out_output_node) (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
+VLIB_NODE_FN (nat44_ei_in2out_output_node)
+(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
{
- return snat_in2out_node_fn_inline (vm, node, frame, 0 /* is_slow_path */ ,
- 1);
+ return nat44_ei_in2out_node_fn_inline (vm, node, frame, 0 /* is_slow_path */,
+ 1);
}
-VLIB_REGISTER_NODE (snat_in2out_output_node) = {
- .name = "nat44-in2out-output",
+VLIB_REGISTER_NODE (nat44_ei_in2out_output_node) = {
+ .name = "nat44-ei-in2out-output",
.vector_size = sizeof (u32),
- .format_trace = format_snat_in2out_trace,
+ .format_trace = format_nat44_ei_in2out_trace,
.type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN(snat_in2out_error_strings),
- .error_strings = snat_in2out_error_strings,
+ .n_errors = ARRAY_LEN(nat44_ei_in2out_error_strings),
+ .error_strings = nat44_ei_in2out_error_strings,
- .runtime_data_bytes = sizeof (snat_runtime_t),
+ .runtime_data_bytes = sizeof (nat44_ei_runtime_t),
- .n_next_nodes = SNAT_IN2OUT_N_NEXT,
+ .n_next_nodes = NAT44_EI_IN2OUT_N_NEXT,
/* edit / add dispositions here */
.next_nodes = {
- [SNAT_IN2OUT_NEXT_DROP] = "error-drop",
- [SNAT_IN2OUT_NEXT_LOOKUP] = "interface-output",
- [SNAT_IN2OUT_NEXT_SLOW_PATH] = "nat44-in2out-output-slowpath",
- [SNAT_IN2OUT_NEXT_ICMP_ERROR] = "ip4-icmp-error",
- [SNAT_IN2OUT_NEXT_HAIRPINNING_HANDOFF] = "nat44-in2out-hairpinning-handoff-interface-output",
+ [NAT44_EI_IN2OUT_NEXT_DROP] = "error-drop",
+ [NAT44_EI_IN2OUT_NEXT_LOOKUP] = "interface-output",
+ [NAT44_EI_IN2OUT_NEXT_SLOW_PATH] = "nat44-ei-in2out-output-slowpath",
+ [NAT44_EI_IN2OUT_NEXT_ICMP_ERROR] = "ip4-icmp-error",
+ [NAT44_EI_IN2OUT_NEXT_HAIRPINNING_HANDOFF] = "nat44-ei-in2out-hairpinning-handoff-interface-output",
},
};
-VLIB_NODE_FN (snat_in2out_slowpath_node) (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
+VLIB_NODE_FN (nat44_ei_in2out_slowpath_node)
+(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
{
- return snat_in2out_node_fn_inline (vm, node, frame, 1 /* is_slow_path */ ,
- 0);
+ return nat44_ei_in2out_node_fn_inline (vm, node, frame, 1 /* is_slow_path */,
+ 0);
}
-VLIB_REGISTER_NODE (snat_in2out_slowpath_node) = {
- .name = "nat44-in2out-slowpath",
+VLIB_REGISTER_NODE (nat44_ei_in2out_slowpath_node) = {
+ .name = "nat44-ei-in2out-slowpath",
.vector_size = sizeof (u32),
- .format_trace = format_snat_in2out_trace,
+ .format_trace = format_nat44_ei_in2out_trace,
.type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN(snat_in2out_error_strings),
- .error_strings = snat_in2out_error_strings,
+ .n_errors = ARRAY_LEN(nat44_ei_in2out_error_strings),
+ .error_strings = nat44_ei_in2out_error_strings,
- .runtime_data_bytes = sizeof (snat_runtime_t),
+ .runtime_data_bytes = sizeof (nat44_ei_runtime_t),
- .n_next_nodes = SNAT_IN2OUT_N_NEXT,
+ .n_next_nodes = NAT44_EI_IN2OUT_N_NEXT,
/* edit / add dispositions here */
.next_nodes = {
- [SNAT_IN2OUT_NEXT_DROP] = "error-drop",
- [SNAT_IN2OUT_NEXT_LOOKUP] = "ip4-lookup",
- [SNAT_IN2OUT_NEXT_SLOW_PATH] = "nat44-in2out-slowpath",
- [SNAT_IN2OUT_NEXT_ICMP_ERROR] = "ip4-icmp-error",
- [SNAT_IN2OUT_NEXT_HAIRPINNING_HANDOFF] = "nat44-in2out-hairpinning-handoff-ip4-lookup",
+ [NAT44_EI_IN2OUT_NEXT_DROP] = "error-drop",
+ [NAT44_EI_IN2OUT_NEXT_LOOKUP] = "ip4-lookup",
+ [NAT44_EI_IN2OUT_NEXT_SLOW_PATH] = "nat44-ei-in2out-slowpath",
+ [NAT44_EI_IN2OUT_NEXT_ICMP_ERROR] = "ip4-icmp-error",
+ [NAT44_EI_IN2OUT_NEXT_HAIRPINNING_HANDOFF] = "nat44-ei-in2out-hairpinning-handoff-ip4-lookup",
},
};
-VLIB_NODE_FN (snat_in2out_output_slowpath_node) (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
+VLIB_NODE_FN (nat44_ei_in2out_output_slowpath_node)
+(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
{
- return snat_in2out_node_fn_inline (vm, node, frame, 1 /* is_slow_path */ ,
- 1);
+ return nat44_ei_in2out_node_fn_inline (vm, node, frame, 1 /* is_slow_path */,
+ 1);
}
-VLIB_REGISTER_NODE (snat_in2out_output_slowpath_node) = {
- .name = "nat44-in2out-output-slowpath",
+VLIB_REGISTER_NODE (nat44_ei_in2out_output_slowpath_node) = {
+ .name = "nat44-ei-in2out-output-slowpath",
.vector_size = sizeof (u32),
- .format_trace = format_snat_in2out_trace,
+ .format_trace = format_nat44_ei_in2out_trace,
.type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN(snat_in2out_error_strings),
- .error_strings = snat_in2out_error_strings,
+ .n_errors = ARRAY_LEN(nat44_ei_in2out_error_strings),
+ .error_strings = nat44_ei_in2out_error_strings,
- .runtime_data_bytes = sizeof (snat_runtime_t),
+ .runtime_data_bytes = sizeof (nat44_ei_runtime_t),
- .n_next_nodes = SNAT_IN2OUT_N_NEXT,
+ .n_next_nodes = NAT44_EI_IN2OUT_N_NEXT,
/* edit / add dispositions here */
.next_nodes = {
- [SNAT_IN2OUT_NEXT_DROP] = "error-drop",
- [SNAT_IN2OUT_NEXT_LOOKUP] = "interface-output",
- [SNAT_IN2OUT_NEXT_SLOW_PATH] = "nat44-in2out-output-slowpath",
- [SNAT_IN2OUT_NEXT_ICMP_ERROR] = "ip4-icmp-error",
- [SNAT_IN2OUT_NEXT_HAIRPINNING_HANDOFF] = "nat44-in2out-hairpinning-handoff-interface-output",
+ [NAT44_EI_IN2OUT_NEXT_DROP] = "error-drop",
+ [NAT44_EI_IN2OUT_NEXT_LOOKUP] = "interface-output",
+ [NAT44_EI_IN2OUT_NEXT_SLOW_PATH] = "nat44-ei-in2out-output-slowpath",
+ [NAT44_EI_IN2OUT_NEXT_ICMP_ERROR] = "ip4-icmp-error",
+ [NAT44_EI_IN2OUT_NEXT_HAIRPINNING_HANDOFF] = "nat44-ei-in2out-hairpinning-handoff-interface-output",
},
};
-VLIB_NODE_FN (snat_in2out_fast_node) (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
+VLIB_NODE_FN (nat44_ei_in2out_fast_node)
+(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
{
u32 n_left_from, *from, *to_next;
u32 thread_index = vm->thread_index;
- snat_in2out_next_t next_index;
- snat_main_t *sm = &snat_main;
+ nat44_ei_in2out_next_t next_index;
+ nat44_ei_main_t *nm = &nat44_ei_main;
int is_hairpinning = 0;
from = vlib_frame_vector_args (frame);
@@ -1800,7 +1819,7 @@ VLIB_NODE_FN (snat_in2out_fast_node) (vlib_main_t * vm,
n_left_to_next -= 1;
b0 = vlib_get_buffer (vm, bi0);
- next0 = SNAT_IN2OUT_NEXT_LOOKUP;
+ next0 = NAT44_EI_IN2OUT_NEXT_LOOKUP;
ip0 = vlib_buffer_get_current (b0);
udp0 = ip4_next_header (ip0);
@@ -1817,7 +1836,7 @@ VLIB_NODE_FN (snat_in2out_fast_node) (vlib_main_t * vm,
icmp4_error_set_vnet_buffer (b0, ICMP4_time_exceeded,
ICMP4_time_exceeded_ttl_exceeded_in_transit,
0);
- next0 = SNAT_IN2OUT_NEXT_ICMP_ERROR;
+ next0 = NAT44_EI_IN2OUT_NEXT_ICMP_ERROR;
goto trace0;
}
@@ -1828,8 +1847,8 @@ VLIB_NODE_FN (snat_in2out_fast_node) (vlib_main_t * vm,
if (PREDICT_FALSE (proto0 == NAT_PROTOCOL_ICMP))
{
- next0 = icmp_in2out (sm, b0, ip0, icmp0, sw_if_index0,
- rx_fib_index0, node, next0, ~0, 0);
+ next0 = nat44_ei_icmp_in2out (b0, ip0, icmp0, sw_if_index0,
+ rx_fib_index0, node, next0, ~0, 0);
goto trace0;
}
@@ -1837,8 +1856,8 @@ VLIB_NODE_FN (snat_in2out_fast_node) (vlib_main_t * vm,
ip0->src_address, udp0->src_port, rx_fib_index0, proto0,
&sm0_addr, &sm0_port, &sm0_fib_index, 0, 0, 0))
{
- b0->error = node->errors[SNAT_IN2OUT_ERROR_NO_TRANSLATION];
- next0 = SNAT_IN2OUT_NEXT_DROP;
+ b0->error = node->errors[NAT44_EI_IN2OUT_ERROR_NO_TRANSLATION];
+ next0 = NAT44_EI_IN2OUT_NEXT_DROP;
goto trace0;
}
@@ -1868,7 +1887,7 @@ VLIB_NODE_FN (snat_in2out_fast_node) (vlib_main_t * vm,
sum0 = ip_csum_update (sum0, old_port0, new_port0,
ip4_header_t /* cheat */ ,
length /* changed member */ );
- mss_clamping (sm->mss_clamping, tcp0, &sum0);
+ mss_clamping (nm->mss_clamping, tcp0, &sum0);
tcp0->checksum = ip_csum_fold (sum0);
}
else if (udp0->checksum)
@@ -1891,7 +1910,7 @@ VLIB_NODE_FN (snat_in2out_fast_node) (vlib_main_t * vm,
sum0 = ip_csum_update (sum0, old_addr0, new_addr0,
ip4_header_t,
dst_address /* changed member */ );
- mss_clamping (sm->mss_clamping, tcp0, &sum0);
+ mss_clamping (nm->mss_clamping, tcp0, &sum0);
tcp0->checksum = ip_csum_fold (sum0);
}
else if (udp0->checksum)
@@ -1905,34 +1924,34 @@ VLIB_NODE_FN (snat_in2out_fast_node) (vlib_main_t * vm,
}
/* Hairpinning */
- is_hairpinning = snat_hairpinning (
- vm, node, sm, thread_index, b0, ip0, udp0, tcp0, proto0,
+ is_hairpinning = nat44_ei_hairpinning (
+ vm, node, nm, thread_index, b0, ip0, udp0, tcp0, proto0,
0 /* do_trace */, &required_thread_index);
if (thread_index != required_thread_index)
{
vnet_buffer (b0)->snat.required_thread_index =
required_thread_index;
- next0 = SNAT_IN2OUT_NEXT_HAIRPINNING_HANDOFF;
+ next0 = NAT44_EI_IN2OUT_NEXT_HAIRPINNING_HANDOFF;
}
trace0:
if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)
&& (b0->flags & VLIB_BUFFER_IS_TRACED)))
{
- snat_in2out_trace_t *t =
+ nat44_ei_in2out_trace_t *t =
vlib_add_trace (vm, node, b0, sizeof (*t));
t->sw_if_index = sw_if_index0;
t->next_index = next0;
t->is_hairpinning = is_hairpinning;
}
- if (next0 != SNAT_IN2OUT_NEXT_DROP)
+ if (next0 != NAT44_EI_IN2OUT_NEXT_DROP)
{
- vlib_increment_simple_counter (&sm->counters.fastpath.
- in2out.other, sw_if_index0,
- vm->thread_index, 1);
+ vlib_increment_simple_counter (
+ &nm->counters.fastpath.in2out.other, sw_if_index0,
+ vm->thread_index, 1);
}
/* verify speculative enqueue, maybe switch current next frame */
@@ -1947,43 +1966,43 @@ VLIB_NODE_FN (snat_in2out_fast_node) (vlib_main_t * vm,
return frame->n_vectors;
}
-VLIB_REGISTER_NODE (snat_in2out_fast_node) = {
- .name = "nat44-in2out-fast",
+VLIB_REGISTER_NODE (nat44_ei_in2out_fast_node) = {
+ .name = "nat44-ei-in2out-fast",
.vector_size = sizeof (u32),
- .format_trace = format_snat_in2out_fast_trace,
+ .format_trace = format_nat44_ei_in2out_fast_trace,
.type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN(snat_in2out_error_strings),
- .error_strings = snat_in2out_error_strings,
+ .n_errors = ARRAY_LEN(nat44_ei_in2out_error_strings),
+ .error_strings = nat44_ei_in2out_error_strings,
- .runtime_data_bytes = sizeof (snat_runtime_t),
+ .runtime_data_bytes = sizeof (nat44_ei_runtime_t),
- .n_next_nodes = SNAT_IN2OUT_N_NEXT,
+ .n_next_nodes = NAT44_EI_IN2OUT_N_NEXT,
/* edit / add dispositions here */
.next_nodes = {
- [SNAT_IN2OUT_NEXT_DROP] = "error-drop",
- [SNAT_IN2OUT_NEXT_LOOKUP] = "ip4-lookup",
- [SNAT_IN2OUT_NEXT_SLOW_PATH] = "nat44-in2out-slowpath",
- [SNAT_IN2OUT_NEXT_ICMP_ERROR] = "ip4-icmp-error",
- [SNAT_IN2OUT_NEXT_HAIRPINNING_HANDOFF] = "nat44-in2out-hairpinning-handoff-ip4-lookup",
+ [NAT44_EI_IN2OUT_NEXT_DROP] = "error-drop",
+ [NAT44_EI_IN2OUT_NEXT_LOOKUP] = "ip4-lookup",
+ [NAT44_EI_IN2OUT_NEXT_SLOW_PATH] = "nat44-ei-in2out-slowpath",
+ [NAT44_EI_IN2OUT_NEXT_ICMP_ERROR] = "ip4-icmp-error",
+ [NAT44_EI_IN2OUT_NEXT_HAIRPINNING_HANDOFF] = "nat44-ei-in2out-hairpinning-handoff-ip4-lookup",
},
};
-VLIB_NODE_FN (nat44_in2out_hairpinning_handoff_ip4_lookup_node)
+VLIB_NODE_FN (nat44_ei_in2out_hairpinning_handoff_ip4_lookup_node)
(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
{
- return nat44_hairpinning_handoff_fn_inline (
+ return nat44_ei_hairpinning_handoff_fn_inline (
vm, node, frame,
- snat_main.nat44_in2out_hairpinning_finish_ip4_lookup_node_fq_index);
+ nat44_ei_main.in2out_hairpinning_finish_ip4_lookup_node_fq_index);
}
-VLIB_REGISTER_NODE (nat44_in2out_hairpinning_handoff_ip4_lookup_node) = {
- .name = "nat44-in2out-hairpinning-handoff-ip4-lookup",
+VLIB_REGISTER_NODE (nat44_ei_in2out_hairpinning_handoff_ip4_lookup_node) = {
+ .name = "nat44-ei-in2out-hairpinning-handoff-ip4-lookup",
.vector_size = sizeof (u32),
- .n_errors = ARRAY_LEN(nat44_hairpinning_handoff_error_strings),
- .error_strings = nat44_hairpinning_handoff_error_strings,
- .format_trace = format_nat44_hairpinning_handoff_trace,
+ .n_errors = ARRAY_LEN(nat44_ei_hairpinning_handoff_error_strings),
+ .error_strings = nat44_ei_hairpinning_handoff_error_strings,
+ .format_trace = format_nat44_ei_hairpinning_handoff_trace,
.n_next_nodes = 1,
@@ -1992,20 +2011,20 @@ VLIB_REGISTER_NODE (nat44_in2out_hairpinning_handoff_ip4_lookup_node) = {
},
};
-VLIB_NODE_FN (nat44_in2out_hairpinning_handoff_interface_output_node)
+VLIB_NODE_FN (nat44_ei_in2out_hairpinning_handoff_interface_output_node)
(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
{
- return nat44_hairpinning_handoff_fn_inline (
+ return nat44_ei_hairpinning_handoff_fn_inline (
vm, node, frame,
- snat_main.nat44_in2out_hairpinning_finish_interface_output_node_fq_index);
+ nat44_ei_main.in2out_hairpinning_finish_interface_output_node_fq_index);
}
-VLIB_REGISTER_NODE (nat44_in2out_hairpinning_handoff_interface_output_node) = {
- .name = "nat44-in2out-hairpinning-handoff-interface-output",
+VLIB_REGISTER_NODE (nat44_ei_in2out_hairpinning_handoff_interface_output_node) = {
+ .name = "nat44-ei-in2out-hairpinning-handoff-interface-output",
.vector_size = sizeof (u32),
- .n_errors = ARRAY_LEN(nat44_hairpinning_handoff_error_strings),
- .error_strings = nat44_hairpinning_handoff_error_strings,
- .format_trace = format_nat44_hairpinning_handoff_trace,
+ .n_errors = ARRAY_LEN(nat44_ei_hairpinning_handoff_error_strings),
+ .error_strings = nat44_ei_hairpinning_handoff_error_strings,
+ .format_trace = format_nat44_ei_hairpinning_handoff_trace,
.n_next_nodes = 1,
@@ -2015,14 +2034,14 @@ VLIB_REGISTER_NODE (nat44_in2out_hairpinning_handoff_interface_output_node) = {
};
static_always_inline int
-nat44_in2out_hairpinning_finish_inline (vlib_main_t *vm,
- vlib_node_runtime_t *node,
- vlib_frame_t *frame)
+nat44_ei_in2out_hairpinning_finish_inline (vlib_main_t *vm,
+ vlib_node_runtime_t *node,
+ vlib_frame_t *frame)
{
u32 n_left_from, *from, *to_next;
u32 thread_index = vm->thread_index;
- snat_in2out_next_t next_index;
- snat_main_t *sm = &snat_main;
+ nat44_ei_in2out_next_t next_index;
+ nat44_ei_main_t *nm = &nat44_ei_main;
int is_hairpinning = 0;
from = vlib_frame_vector_args (frame);
@@ -2057,7 +2076,7 @@ nat44_in2out_hairpinning_finish_inline (vlib_main_t *vm,
n_left_to_next -= 1;
b0 = vlib_get_buffer (vm, bi0);
- next0 = NAT44_IN2OUT_HAIRPINNING_FINISH_NEXT_LOOKUP;
+ next0 = NAT44_EI_IN2OUT_HAIRPINNING_FINISH_NEXT_LOOKUP;
ip0 = vlib_buffer_get_current (b0);
udp0 = ip4_next_header (ip0);
@@ -2072,41 +2091,41 @@ nat44_in2out_hairpinning_finish_inline (vlib_main_t *vm,
case NAT_PROTOCOL_TCP:
// fallthrough
case NAT_PROTOCOL_UDP:
- is_hairpinning = snat_hairpinning (
- vm, node, sm, thread_index, b0, ip0, udp0, tcp0, proto0,
+ is_hairpinning = nat44_ei_hairpinning (
+ vm, node, nm, thread_index, b0, ip0, udp0, tcp0, proto0,
0 /* do_trace */, &required_thread_index);
break;
case NAT_PROTOCOL_ICMP:
- is_hairpinning =
- (0 == snat_icmp_hairpinning (sm, b0, thread_index, ip0, icmp0,
- &required_thread_index));
+ is_hairpinning = (0 == nat44_ei_icmp_hairpinning (
+ nm, b0, thread_index, ip0, icmp0,
+ &required_thread_index));
break;
case NAT_PROTOCOL_OTHER:
// this should never happen
- next0 = NAT44_IN2OUT_HAIRPINNING_FINISH_NEXT_DROP;
+ next0 = NAT44_EI_IN2OUT_HAIRPINNING_FINISH_NEXT_DROP;
break;
}
if (thread_index != required_thread_index)
{
// but we already did a handoff ...
- next0 = NAT44_IN2OUT_HAIRPINNING_FINISH_NEXT_DROP;
+ next0 = NAT44_EI_IN2OUT_HAIRPINNING_FINISH_NEXT_DROP;
}
if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE) &&
(b0->flags & VLIB_BUFFER_IS_TRACED)))
{
- snat_in2out_trace_t *t =
+ nat44_ei_in2out_trace_t *t =
vlib_add_trace (vm, node, b0, sizeof (*t));
t->sw_if_index = sw_if_index0;
t->next_index = next0;
t->is_hairpinning = is_hairpinning;
}
- if (next0 != NAT44_IN2OUT_HAIRPINNING_FINISH_NEXT_DROP)
+ if (next0 != NAT44_EI_IN2OUT_HAIRPINNING_FINISH_NEXT_DROP)
{
vlib_increment_simple_counter (
- &sm->counters.fastpath.in2out.other, sw_if_index0,
+ &nm->counters.fastpath.in2out.other, sw_if_index0,
vm->thread_index, 1);
}
@@ -2121,55 +2140,55 @@ nat44_in2out_hairpinning_finish_inline (vlib_main_t *vm,
return frame->n_vectors;
}
-VLIB_NODE_FN (nat44_in2out_hairpinning_finish_ip4_lookup_node)
+VLIB_NODE_FN (nat44_ei_in2out_hairpinning_finish_ip4_lookup_node)
(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
{
- return nat44_in2out_hairpinning_finish_inline (vm, node, frame);
+ return nat44_ei_in2out_hairpinning_finish_inline (vm, node, frame);
}
-VLIB_REGISTER_NODE (nat44_in2out_hairpinning_finish_ip4_lookup_node) = {
- .name = "nat44-in2out-hairpinning-finish-ip4-lookup",
+VLIB_REGISTER_NODE (nat44_ei_in2out_hairpinning_finish_ip4_lookup_node) = {
+ .name = "nat44-ei-in2out-hairpinning-finish-ip4-lookup",
.vector_size = sizeof (u32),
- .format_trace = format_snat_in2out_fast_trace,
+ .format_trace = format_nat44_ei_in2out_fast_trace,
.type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN(snat_in2out_error_strings),
- .error_strings = snat_in2out_error_strings,
+ .n_errors = ARRAY_LEN(nat44_ei_in2out_error_strings),
+ .error_strings = nat44_ei_in2out_error_strings,
- .runtime_data_bytes = sizeof (snat_runtime_t),
+ .runtime_data_bytes = sizeof (nat44_ei_runtime_t),
- .n_next_nodes = NAT44_IN2OUT_HAIRPINNING_FINISH_N_NEXT,
+ .n_next_nodes = NAT44_EI_IN2OUT_HAIRPINNING_FINISH_N_NEXT,
/* edit / add dispositions here */
.next_nodes = {
- [NAT44_IN2OUT_HAIRPINNING_FINISH_NEXT_DROP] = "error-drop",
- [NAT44_IN2OUT_HAIRPINNING_FINISH_NEXT_LOOKUP] = "ip4-lookup",
+ [NAT44_EI_IN2OUT_HAIRPINNING_FINISH_NEXT_DROP] = "error-drop",
+ [NAT44_EI_IN2OUT_HAIRPINNING_FINISH_NEXT_LOOKUP] = "ip4-lookup",
},
};
-VLIB_NODE_FN (nat44_in2out_hairpinning_finish_interface_output_node)
+VLIB_NODE_FN (nat44_ei_in2out_hairpinning_finish_interface_output_node)
(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
{
- return nat44_in2out_hairpinning_finish_inline (vm, node, frame);
+ return nat44_ei_in2out_hairpinning_finish_inline (vm, node, frame);
}
-VLIB_REGISTER_NODE (nat44_in2out_hairpinning_finish_interface_output_node) = {
- .name = "nat44-in2out-hairpinning-finish-interface-output",
+VLIB_REGISTER_NODE (nat44_ei_in2out_hairpinning_finish_interface_output_node) = {
+ .name = "nat44-ei-in2out-hairpinning-finish-interface-output",
.vector_size = sizeof (u32),
- .format_trace = format_snat_in2out_fast_trace,
+ .format_trace = format_nat44_ei_in2out_fast_trace,
.type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN(snat_in2out_error_strings),
- .error_strings = snat_in2out_error_strings,
+ .n_errors = ARRAY_LEN(nat44_ei_in2out_error_strings),
+ .error_strings = nat44_ei_in2out_error_strings,
- .runtime_data_bytes = sizeof (snat_runtime_t),
+ .runtime_data_bytes = sizeof (nat44_ei_runtime_t),
- .n_next_nodes = NAT44_IN2OUT_HAIRPINNING_FINISH_N_NEXT,
+ .n_next_nodes = NAT44_EI_IN2OUT_HAIRPINNING_FINISH_N_NEXT,
/* edit / add dispositions here */
.next_nodes = {
- [NAT44_IN2OUT_HAIRPINNING_FINISH_NEXT_DROP] = "error-drop",
- [NAT44_IN2OUT_HAIRPINNING_FINISH_NEXT_LOOKUP] = "interface-output",
+ [NAT44_EI_IN2OUT_HAIRPINNING_FINISH_NEXT_DROP] = "error-drop",
+ [NAT44_EI_IN2OUT_HAIRPINNING_FINISH_NEXT_LOOKUP] = "interface-output",
},
};
diff --git a/src/plugins/nat/nat44-ei/nat44_ei_inlines.h b/src/plugins/nat/nat44-ei/nat44_ei_inlines.h
index f7089ea0c21..30935884ce7 100644
--- a/src/plugins/nat/nat44-ei/nat44_ei_inlines.h
+++ b/src/plugins/nat/nat44-ei/nat44_ei_inlines.h
@@ -16,19 +16,189 @@
#ifndef __included_nat44_ei_inlines_h__
#define __included_nat44_ei_inlines_h__
+#include <vppinfra/clib.h>
+
+#include <nat/nat44-ei/nat44_ei.h>
#include <nat/nat44-ei/nat44_ei_ha.h>
+always_inline u64
+calc_nat_key (ip4_address_t addr, u16 port, u32 fib_index, u8 proto)
+{
+ ASSERT (fib_index <= (1 << 14) - 1);
+ ASSERT (proto <= (1 << 3) - 1);
+ return (u64) addr.as_u32 << 32 | (u64) port << 16 | fib_index << 3 |
+ (proto & 0x7);
+}
+
+always_inline void
+split_nat_key (u64 key, ip4_address_t *addr, u16 *port, u32 *fib_index,
+ nat_protocol_t *proto)
+{
+ if (addr)
+ {
+ addr->as_u32 = key >> 32;
+ }
+ if (port)
+ {
+ *port = (key >> 16) & (u16) ~0;
+ }
+ if (fib_index)
+ {
+ *fib_index = key >> 3 & ((1 << 13) - 1);
+ }
+ if (proto)
+ {
+ *proto = key & 0x7;
+ }
+}
+
+always_inline void
+init_nat_k (clib_bihash_kv_8_8_t *kv, ip4_address_t addr, u16 port,
+ u32 fib_index, nat_protocol_t proto)
+{
+ kv->key = calc_nat_key (addr, port, fib_index, proto);
+ kv->value = ~0ULL;
+}
+
+always_inline void
+init_nat_kv (clib_bihash_kv_8_8_t *kv, ip4_address_t addr, u16 port,
+ u32 fib_index, nat_protocol_t proto, u32 thread_index,
+ u32 session_index)
+{
+ init_nat_k (kv, addr, port, fib_index, proto);
+ kv->value = (u64) thread_index << 32 | session_index;
+}
+
+always_inline void
+init_nat_i2o_k (clib_bihash_kv_8_8_t *kv, nat44_ei_session_t *s)
+{
+ return init_nat_k (kv, s->in2out.addr, s->in2out.port, s->in2out.fib_index,
+ s->nat_proto);
+}
+
+always_inline void
+init_nat_i2o_kv (clib_bihash_kv_8_8_t *kv, nat44_ei_session_t *s,
+ u32 thread_index, u32 session_index)
+{
+ init_nat_k (kv, s->in2out.addr, s->in2out.port, s->in2out.fib_index,
+ s->nat_proto);
+ kv->value = (u64) thread_index << 32 | session_index;
+}
+
+always_inline void
+init_nat_o2i_k (clib_bihash_kv_8_8_t *kv, nat44_ei_session_t *s)
+{
+ return init_nat_k (kv, s->out2in.addr, s->out2in.port, s->out2in.fib_index,
+ s->nat_proto);
+}
+
+always_inline void
+init_nat_o2i_kv (clib_bihash_kv_8_8_t *kv, nat44_ei_session_t *s,
+ u32 thread_index, u32 session_index)
+{
+ init_nat_k (kv, s->out2in.addr, s->out2in.port, s->out2in.fib_index,
+ s->nat_proto);
+ kv->value = (u64) thread_index << 32 | session_index;
+}
+
+always_inline u32
+nat_value_get_thread_index (clib_bihash_kv_8_8_t *value)
+{
+ return value->value >> 32;
+}
+
+always_inline u32
+nat_value_get_session_index (clib_bihash_kv_8_8_t *value)
+{
+ return value->value & ~(u32) 0;
+}
+
+always_inline u8
+nat44_ei_is_interface_addr (ip4_main_t *im, vlib_node_runtime_t *node,
+ u32 sw_if_index0, u32 ip4_addr)
+{
+ nat44_ei_runtime_t *rt = (nat44_ei_runtime_t *) node->runtime_data;
+ ip4_address_t *first_int_addr;
+
+ if (PREDICT_FALSE (rt->cached_sw_if_index != sw_if_index0))
+ {
+ first_int_addr = ip4_interface_first_address (
+ im, sw_if_index0, 0 /* just want the address */);
+ rt->cached_sw_if_index = sw_if_index0;
+ if (first_int_addr)
+ rt->cached_ip4_address = first_int_addr->as_u32;
+ else
+ rt->cached_ip4_address = 0;
+ }
+
+ if (PREDICT_FALSE (ip4_addr == rt->cached_ip4_address))
+ return 1;
+ else
+ return 0;
+}
+
+/** \brief Per-user LRU list maintenance */
+always_inline void
+nat44_ei_session_update_lru (nat44_ei_main_t *nm, nat44_ei_session_t *s,
+ u32 thread_index)
+{
+ /* don't update too often - timeout is in magnitude of seconds anyway */
+ if (s->last_heard > s->last_lru_update + 1)
+ {
+ clib_dlist_remove (nm->per_thread_data[thread_index].list_pool,
+ s->per_user_index);
+ clib_dlist_addtail (nm->per_thread_data[thread_index].list_pool,
+ s->per_user_list_head_index, s->per_user_index);
+ s->last_lru_update = s->last_heard;
+ }
+}
+
+always_inline void
+nat44_ei_user_session_increment (nat44_ei_main_t *nm, nat44_ei_user_t *u,
+ u8 is_static)
+{
+ if (u->nsessions + u->nstaticsessions < nm->max_translations_per_user)
+ {
+ if (is_static)
+ u->nstaticsessions++;
+ else
+ u->nsessions++;
+ }
+}
+
+always_inline void
+nat44_ei_delete_user_with_no_session (nat44_ei_main_t *nm, nat44_ei_user_t *u,
+ u32 thread_index)
+{
+ clib_bihash_kv_8_8_t kv;
+ nat44_ei_user_key_t u_key;
+ nat44_ei_main_per_thread_data_t *tnm =
+ vec_elt_at_index (nm->per_thread_data, thread_index);
+
+ if (u->nstaticsessions == 0 && u->nsessions == 0)
+ {
+ u_key.addr.as_u32 = u->addr.as_u32;
+ u_key.fib_index = u->fib_index;
+ kv.key = u_key.as_u64;
+ pool_put_index (tnm->list_pool, u->sessions_per_user_list_head_index);
+ pool_put (tnm->users, u);
+ clib_bihash_add_del_8_8 (&tnm->user_hash, &kv, 0);
+ vlib_set_simple_counter (&nm->total_users, thread_index, 0,
+ pool_elts (tnm->users));
+ }
+}
+
static_always_inline u8
-nat44_ei_maximum_sessions_exceeded (snat_main_t *sm, u32 thread_index)
+nat44_ei_maximum_sessions_exceeded (nat44_ei_main_t *nm, u32 thread_index)
{
- if (pool_elts (sm->per_thread_data[thread_index].sessions) >=
- sm->max_translations_per_thread)
+ if (pool_elts (nm->per_thread_data[thread_index].sessions) >=
+ nm->max_translations_per_thread)
return 1;
return 0;
}
always_inline void
-nat44_ei_session_update_counters (snat_session_t *s, f64 now, uword bytes,
+nat44_ei_session_update_counters (nat44_ei_session_t *s, f64 now, uword bytes,
u32 thread_index)
{
s->last_heard = now;
diff --git a/src/plugins/nat/nat44-ei/nat44_ei_out2in.c b/src/plugins/nat/nat44-ei/nat44_ei_out2in.c
index ca3c272a26c..1d5ebd33cd5 100644
--- a/src/plugins/nat/nat44-ei/nat44_ei_out2in.c
+++ b/src/plugins/nat/nat44-ei/nat44_ei_out2in.c
@@ -14,41 +14,40 @@
*/
/**
* @file
- * @brief NAT44 endpoint-dependent outside to inside network translation
+ * @brief NAT44 EI outside to inside network translation
*/
#include <vlib/vlib.h>
-#include <vnet/vnet.h>
+#include <vnet/vnet.h>
#include <vnet/ip/ip.h>
-#include <vnet/udp/udp_local.h>
#include <vnet/ethernet/ethernet.h>
+#include <vnet/udp/udp_local.h>
#include <vnet/fib/ip4_fib.h>
-#include <nat/nat.h>
-#include <nat/lib/ipfix_logging.h>
-#include <nat/nat_inlines.h>
-#include <nat/lib/nat_syslog.h>
-#include <nat/nat44-ei/nat44_ei_inlines.h>
-#include <nat/nat44-ei/nat44_ei.h>
#include <vppinfra/hash.h>
#include <vppinfra/error.h>
-#include <vppinfra/elog.h>
+
+#include <nat/lib/log.h>
+#include <nat/lib/nat_syslog.h>
+#include <nat/lib/ipfix_logging.h>
+#include <nat/nat44-ei/nat44_ei_inlines.h>
+#include <nat/nat44-ei/nat44_ei.h>
typedef struct
{
u32 sw_if_index;
u32 next_index;
u32 session_index;
-} snat_out2in_trace_t;
+} nat44_ei_out2in_trace_t;
/* packet trace format function */
static u8 *
-format_snat_out2in_trace (u8 * s, va_list * args)
+format_nat44_ei_out2in_trace (u8 *s, va_list *args)
{
CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
- snat_out2in_trace_t *t = va_arg (*args, snat_out2in_trace_t *);
+ nat44_ei_out2in_trace_t *t = va_arg (*args, nat44_ei_out2in_trace_t *);
s =
format (s,
@@ -58,66 +57,67 @@ format_snat_out2in_trace (u8 * s, va_list * args)
}
static u8 *
-format_snat_out2in_fast_trace (u8 * s, va_list * args)
+format_nat44_ei_out2in_fast_trace (u8 *s, va_list *args)
{
CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
- snat_out2in_trace_t *t = va_arg (*args, snat_out2in_trace_t *);
+ nat44_ei_out2in_trace_t *t = va_arg (*args, nat44_ei_out2in_trace_t *);
s = format (s, "NAT44_OUT2IN_FAST: sw_if_index %d, next index %d",
t->sw_if_index, t->next_index);
return s;
}
-#define foreach_snat_out2in_error \
-_(UNSUPPORTED_PROTOCOL, "unsupported protocol") \
-_(OUT_OF_PORTS, "out of ports") \
-_(BAD_ICMP_TYPE, "unsupported ICMP type") \
-_(NO_TRANSLATION, "no translation") \
-_(MAX_SESSIONS_EXCEEDED, "maximum sessions exceeded") \
-_(CANNOT_CREATE_USER, "cannot create NAT user")
+#define foreach_nat44_ei_out2in_error \
+ _ (UNSUPPORTED_PROTOCOL, "unsupported protocol") \
+ _ (OUT_OF_PORTS, "out of ports") \
+ _ (BAD_ICMP_TYPE, "unsupported ICMP type") \
+ _ (NO_TRANSLATION, "no translation") \
+ _ (MAX_SESSIONS_EXCEEDED, "maximum sessions exceeded") \
+ _ (CANNOT_CREATE_USER, "cannot create NAT user")
typedef enum
{
-#define _(sym,str) SNAT_OUT2IN_ERROR_##sym,
- foreach_snat_out2in_error
+#define _(sym, str) NAT44_EI_OUT2IN_ERROR_##sym,
+ foreach_nat44_ei_out2in_error
#undef _
- SNAT_OUT2IN_N_ERROR,
-} snat_out2in_error_t;
+ NAT44_EI_OUT2IN_N_ERROR,
+} nat44_ei_out2in_error_t;
-static char *snat_out2in_error_strings[] = {
+static char *nat44_ei_out2in_error_strings[] = {
#define _(sym,string) string,
- foreach_snat_out2in_error
+ foreach_nat44_ei_out2in_error
#undef _
};
typedef enum
{
- SNAT_OUT2IN_NEXT_DROP,
- SNAT_OUT2IN_NEXT_LOOKUP,
- SNAT_OUT2IN_NEXT_ICMP_ERROR,
- SNAT_OUT2IN_N_NEXT,
-} snat_out2in_next_t;
+ NAT44_EI_OUT2IN_NEXT_DROP,
+ NAT44_EI_OUT2IN_NEXT_LOOKUP,
+ NAT44_EI_OUT2IN_NEXT_ICMP_ERROR,
+ NAT44_EI_OUT2IN_N_NEXT,
+} nat44_ei_out2in_next_t;
#ifndef CLIB_MARCH_VARIANT
int
nat44_o2i_is_idle_session_cb (clib_bihash_kv_8_8_t * kv, void *arg)
{
- snat_main_t *sm = &snat_main;
- nat44_is_idle_session_ctx_t *ctx = arg;
- snat_session_t *s;
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nat44_ei_is_idle_session_ctx_t *ctx = arg;
+ nat44_ei_session_t *s;
u64 sess_timeout_time;
- snat_main_per_thread_data_t *tsm = vec_elt_at_index (sm->per_thread_data,
- ctx->thread_index);
+ nat44_ei_main_per_thread_data_t *tnm =
+ vec_elt_at_index (nm->per_thread_data, ctx->thread_index);
clib_bihash_kv_8_8_t s_kv;
- s = pool_elt_at_index (tsm->sessions, kv->value);
- sess_timeout_time = s->last_heard + (f64) nat44_session_get_timeout (sm, s);
+ s = pool_elt_at_index (tnm->sessions, kv->value);
+ sess_timeout_time = s->last_heard + (f64) nat_session_get_timeout (
+ &nm->timeouts, s->nat_proto, s->state);
if (ctx->now >= sess_timeout_time)
{
init_nat_i2o_k (&s_kv, s);
- if (clib_bihash_add_del_8_8 (&sm->in2out, &s_kv, 0))
- nat_elog_warn ("out2in key del failed");
+ if (clib_bihash_add_del_8_8 (&nm->in2out, &s_kv, 0))
+ nat_elog_warn (nm, "out2in key del failed");
nat_ipfix_logging_nat44_ses_delete (ctx->thread_index,
s->in2out.addr.as_u32,
@@ -135,12 +135,12 @@ nat44_o2i_is_idle_session_cb (clib_bihash_kv_8_8_t * kv, void *arg)
s->ext_host_port, s->nat_proto, s->out2in.fib_index,
ctx->thread_index);
- if (!snat_is_session_static (s))
- snat_free_outside_address_and_port (sm->addresses, ctx->thread_index,
- &s->out2in.addr, s->out2in.port,
- s->nat_proto);
+ if (!nat44_ei_is_session_static (s))
+ nat44_ei_free_outside_address_and_port (
+ nm->addresses, ctx->thread_index, &s->out2in.addr, s->out2in.port,
+ s->nat_proto);
- nat44_delete_session (sm, s, ctx->thread_index);
+ nat44_ei_delete_session (nm, s, ctx->thread_index);
return 1;
}
@@ -154,63 +154,56 @@ nat44_o2i_is_idle_session_cb (clib_bihash_kv_8_8_t * kv, void *arg)
* Create NAT session initiated by host from external network with static
* mapping.
*
- * @param sm NAT main.
+ * @param nm NAT main.
* @param b0 Vlib buffer.
* @param in2out In2out NAT44 session key.
* @param out2in Out2in NAT44 session key.
* @param node Vlib node.
*
- * @returns SNAT session if successfully created otherwise 0.
+ * @returns NAT44_EI session if successfully created otherwise 0.
*/
-static inline snat_session_t *
-create_session_for_static_mapping (snat_main_t * sm,
- vlib_buffer_t * b0,
- ip4_address_t i2o_addr,
- u16 i2o_port,
- u32 i2o_fib_index,
- ip4_address_t o2i_addr,
- u16 o2i_port,
- u32 o2i_fib_index,
- nat_protocol_t proto,
- vlib_node_runtime_t * node,
- u32 thread_index, f64 now)
+static inline nat44_ei_session_t *
+create_session_for_static_mapping (
+ nat44_ei_main_t *nm, vlib_buffer_t *b0, ip4_address_t i2o_addr, u16 i2o_port,
+ u32 i2o_fib_index, ip4_address_t o2i_addr, u16 o2i_port, u32 o2i_fib_index,
+ nat_protocol_t proto, vlib_node_runtime_t *node, u32 thread_index, f64 now)
{
- snat_user_t *u;
- snat_session_t *s;
+ nat44_ei_user_t *u;
+ nat44_ei_session_t *s;
clib_bihash_kv_8_8_t kv0;
ip4_header_t *ip0;
udp_header_t *udp0;
- nat44_is_idle_session_ctx_t ctx0;
+ nat44_ei_is_idle_session_ctx_t ctx0;
- if (PREDICT_FALSE (nat44_ei_maximum_sessions_exceeded (sm, thread_index)))
+ if (PREDICT_FALSE (nat44_ei_maximum_sessions_exceeded (nm, thread_index)))
{
- b0->error = node->errors[SNAT_OUT2IN_ERROR_MAX_SESSIONS_EXCEEDED];
- nat_elog_notice ("maximum sessions exceeded");
+ b0->error = node->errors[NAT44_EI_OUT2IN_ERROR_MAX_SESSIONS_EXCEEDED];
+ nat_elog_notice (nm, "maximum sessions exceeded");
return 0;
}
ip0 = vlib_buffer_get_current (b0);
udp0 = ip4_next_header (ip0);
- u = nat_user_get_or_create (sm, &i2o_addr, i2o_fib_index, thread_index);
+ u = nat44_ei_user_get_or_create (nm, &i2o_addr, i2o_fib_index, thread_index);
if (!u)
{
- b0->error = node->errors[SNAT_OUT2IN_ERROR_CANNOT_CREATE_USER];
+ b0->error = node->errors[NAT44_EI_OUT2IN_ERROR_CANNOT_CREATE_USER];
return 0;
}
- s = nat_session_alloc_or_recycle (sm, u, thread_index, now);
+ s = nat44_ei_session_alloc_or_recycle (nm, u, thread_index, now);
if (!s)
{
- nat44_delete_user_with_no_session (sm, u, thread_index);
- nat_elog_warn ("create NAT session failed");
+ nat44_ei_delete_user_with_no_session (nm, u, thread_index);
+ nat_elog_warn (nm, "create NAT session failed");
return 0;
}
- s->flags |= SNAT_SESSION_FLAG_STATIC_MAPPING;
+ s->flags |= NAT44_EI_SESSION_FLAG_STATIC_MAPPING;
s->ext_host_addr.as_u32 = ip0->src_address.as_u32;
s->ext_host_port = udp0->src_port;
- user_session_increment (sm, u, 1 /* static */ );
+ nat44_ei_user_session_increment (nm, u, 1 /* static */);
s->in2out.addr = i2o_addr;
s->in2out.port = i2o_port;
s->in2out.fib_index = i2o_fib_index;
@@ -223,16 +216,16 @@ create_session_for_static_mapping (snat_main_t * sm,
ctx0.now = now;
ctx0.thread_index = thread_index;
init_nat_i2o_kv (&kv0, s, thread_index,
- s - sm->per_thread_data[thread_index].sessions);
+ s - nm->per_thread_data[thread_index].sessions);
if (clib_bihash_add_or_overwrite_stale_8_8 (
- &sm->in2out, &kv0, nat44_i2o_is_idle_session_cb, &ctx0))
- nat_elog_notice ("in2out key add failed");
+ &nm->in2out, &kv0, nat44_i2o_is_idle_session_cb, &ctx0))
+ nat_elog_notice (nm, "in2out key add failed");
init_nat_o2i_kv (&kv0, s, thread_index,
- s - sm->per_thread_data[thread_index].sessions);
+ s - nm->per_thread_data[thread_index].sessions);
if (clib_bihash_add_or_overwrite_stale_8_8 (
- &sm->out2in, &kv0, nat44_o2i_is_idle_session_cb, &ctx0))
- nat_elog_notice ("out2in key add failed");
+ &nm->out2in, &kv0, nat44_o2i_is_idle_session_cb, &ctx0))
+ nat_elog_notice (nm, "out2in key add failed");
/* log NAT event */
nat_ipfix_logging_nat44_ses_create (thread_index,
@@ -255,9 +248,9 @@ create_session_for_static_mapping (snat_main_t * sm,
}
#ifndef CLIB_MARCH_VARIANT
-static_always_inline snat_out2in_error_t
-icmp_get_key (vlib_buffer_t * b, ip4_header_t * ip0,
- ip4_address_t * addr, u16 * port, nat_protocol_t * nat_proto)
+static_always_inline nat44_ei_out2in_error_t
+icmp_get_key (vlib_buffer_t *b, ip4_header_t *ip0, ip4_address_t *addr,
+ u16 *port, nat_protocol_t *nat_proto)
{
icmp46_header_t *icmp0;
icmp_echo_header_t *echo0, *inner_echo0 = 0;
@@ -293,7 +286,7 @@ icmp_get_key (vlib_buffer_t * b, ip4_header_t * ip0,
*port = ((tcp_udp_header_t *) l4_header)->src_port;
break;
default:
- return SNAT_OUT2IN_ERROR_UNSUPPORTED_PROTOCOL;
+ return NAT44_EI_OUT2IN_ERROR_UNSUPPORTED_PROTOCOL;
}
}
return -1; /* success */
@@ -303,7 +296,7 @@ icmp_get_key (vlib_buffer_t * b, ip4_header_t * ip0,
* Get address and port values to be used for ICMP packet translation
* and create session if needed
*
- * @param[in,out] sm NAT main
+ * @param[in,out] nm NAT main
* @param[in,out] node NAT node runtime
* @param[in] thread_index thread index
* @param[in,out] b0 buffer containing packet to be translated
@@ -315,15 +308,16 @@ icmp_get_key (vlib_buffer_t * b, ip4_header_t * ip0,
* @param e optional parameter
*/
u32
-icmp_match_out2in_slow (snat_main_t *sm, vlib_node_runtime_t *node,
- u32 thread_index, vlib_buffer_t *b0, ip4_header_t *ip0,
- ip4_address_t *addr, u16 *port, u32 *fib_index,
- nat_protocol_t *proto, snat_session_t **p_s0,
- u8 *dont_translate)
+nat44_ei_icmp_match_out2in_slow (vlib_node_runtime_t *node, u32 thread_index,
+ vlib_buffer_t *b0, ip4_header_t *ip0,
+ ip4_address_t *addr, u16 *port,
+ u32 *fib_index, nat_protocol_t *proto,
+ nat44_ei_session_t **p_s0, u8 *dont_translate)
{
- snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
+ nat44_ei_main_t *nm = &nat44_ei_main;
+ nat44_ei_main_per_thread_data_t *tnm = &nm->per_thread_data[thread_index];
u32 sw_if_index0;
- snat_session_t *s0 = 0;
+ nat44_ei_session_t *s0 = 0;
clib_bihash_kv_8_8_t kv0, value0;
u8 is_addr_only;
u32 next0 = ~0;
@@ -340,8 +334,8 @@ icmp_match_out2in_slow (snat_main_t *sm, vlib_node_runtime_t *node,
err = icmp_get_key (b0, ip0, addr, port, proto);
if (err != -1)
{
- b0->error = node->errors[SNAT_OUT2IN_ERROR_UNSUPPORTED_PROTOCOL];
- next0 = SNAT_OUT2IN_NEXT_DROP;
+ b0->error = node->errors[NAT44_EI_OUT2IN_ERROR_UNSUPPORTED_PROTOCOL];
+ next0 = NAT44_EI_OUT2IN_NEXT_DROP;
goto out;
}
@@ -350,7 +344,7 @@ icmp_match_out2in_slow (snat_main_t *sm, vlib_node_runtime_t *node,
u32 mapping_fib_index;
init_nat_k (&kv0, *addr, *port, *fib_index, *proto);
- if (clib_bihash_search_8_8 (&sm->out2in, &kv0, &value0))
+ if (clib_bihash_search_8_8 (&nm->out2in, &kv0, &value0))
{
/* Try to match static mapping by external address and port,
destination address and port in packet */
@@ -358,17 +352,18 @@ icmp_match_out2in_slow (snat_main_t *sm, vlib_node_runtime_t *node,
*addr, *port, *fib_index, *proto, &mapping_addr, &mapping_port,
&mapping_fib_index, 1, &is_addr_only, &identity_nat))
{
- if (!sm->forwarding_enabled)
+ if (!nm->forwarding_enabled)
{
/* Don't NAT packet aimed at the intfc address */
- if (PREDICT_FALSE (is_interface_addr (sm, node, sw_if_index0,
- ip0->dst_address.as_u32)))
+ if (PREDICT_FALSE (nat44_ei_is_interface_addr (
+ nm->ip4_main, node, sw_if_index0,
+ ip0->dst_address.as_u32)))
{
*dont_translate = 1;
goto out;
}
- b0->error = node->errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
- next0 = SNAT_OUT2IN_NEXT_DROP;
+ b0->error = node->errors[NAT44_EI_OUT2IN_ERROR_NO_TRANSLATION];
+ next0 = NAT44_EI_OUT2IN_NEXT_DROP;
goto out;
}
else
@@ -384,8 +379,8 @@ icmp_match_out2in_slow (snat_main_t *sm, vlib_node_runtime_t *node,
&& (vnet_buffer (b0)->ip.reass.icmp_type_or_tcp_flags !=
ICMP4_echo_request || !is_addr_only)))
{
- b0->error = node->errors[SNAT_OUT2IN_ERROR_BAD_ICMP_TYPE];
- next0 = SNAT_OUT2IN_NEXT_DROP;
+ b0->error = node->errors[NAT44_EI_OUT2IN_ERROR_BAD_ICMP_TYPE];
+ next0 = NAT44_EI_OUT2IN_NEXT_DROP;
goto out;
}
@@ -395,15 +390,13 @@ icmp_match_out2in_slow (snat_main_t *sm, vlib_node_runtime_t *node,
goto out;
}
/* Create session initiated by host from external network */
- s0 =
- create_session_for_static_mapping (sm, b0, mapping_addr, mapping_port,
- mapping_fib_index, *addr, *port,
- *fib_index, *proto, node,
- thread_index, vlib_time_now (vm));
+ s0 = create_session_for_static_mapping (
+ nm, b0, mapping_addr, mapping_port, mapping_fib_index, *addr, *port,
+ *fib_index, *proto, node, thread_index, vlib_time_now (vm));
if (!s0)
{
- next0 = SNAT_OUT2IN_NEXT_DROP;
+ next0 = NAT44_EI_OUT2IN_NEXT_DROP;
goto out;
}
}
@@ -417,12 +410,12 @@ icmp_match_out2in_slow (snat_main_t *sm, vlib_node_runtime_t *node,
&& !icmp_type_is_error_message (vnet_buffer (b0)->ip.
reass.icmp_type_or_tcp_flags)))
{
- b0->error = node->errors[SNAT_OUT2IN_ERROR_BAD_ICMP_TYPE];
- next0 = SNAT_OUT2IN_NEXT_DROP;
+ b0->error = node->errors[NAT44_EI_OUT2IN_ERROR_BAD_ICMP_TYPE];
+ next0 = NAT44_EI_OUT2IN_NEXT_DROP;
goto out;
}
- s0 = pool_elt_at_index (tsm->sessions,
+ s0 = pool_elt_at_index (tnm->sessions,
nat_value_get_session_index (&value0));
}
@@ -440,27 +433,15 @@ out:
#endif
#ifndef CLIB_MARCH_VARIANT
-/**
- * Get address and port values to be used for ICMP packet translation
- *
- * @param[in] sm NAT main
- * @param[in,out] node NAT node runtime
- * @param[in] thread_index thread index
- * @param[in,out] b0 buffer containing packet to be translated
- * @param[in,out] ip0 ip header
- * @param[out] p_proto protocol used for matching
- * @param[out] p_value address and port after NAT translation
- * @param[out] p_dont_translate if packet should not be translated
- * @param d optional parameter
- * @param e optional parameter
- */
u32
-icmp_match_out2in_fast (snat_main_t *sm, vlib_node_runtime_t *node,
- u32 thread_index, vlib_buffer_t *b0, ip4_header_t *ip0,
- ip4_address_t *mapping_addr, u16 *mapping_port,
- u32 *mapping_fib_index, nat_protocol_t *proto,
- snat_session_t **p_s0, u8 *dont_translate)
+nat44_ei_icmp_match_out2in_fast (vlib_node_runtime_t *node, u32 thread_index,
+ vlib_buffer_t *b0, ip4_header_t *ip0,
+ ip4_address_t *mapping_addr,
+ u16 *mapping_port, u32 *mapping_fib_index,
+ nat_protocol_t *proto,
+ nat44_ei_session_t **p_s0, u8 *dont_translate)
{
+ nat44_ei_main_t *nm = &nat44_ei_main;
u32 sw_if_index0;
u32 rx_fib_index0;
u8 is_addr_only;
@@ -477,7 +458,7 @@ icmp_match_out2in_fast (snat_main_t *sm, vlib_node_runtime_t *node,
if (err != -1)
{
b0->error = node->errors[err];
- next0 = SNAT_OUT2IN_NEXT_DROP;
+ next0 = NAT44_EI_OUT2IN_NEXT_DROP;
goto out;
}
if (nat44_ei_static_mapping_match (addr, port, rx_fib_index0, *proto,
@@ -485,13 +466,14 @@ icmp_match_out2in_fast (snat_main_t *sm, vlib_node_runtime_t *node,
mapping_fib_index, 1, &is_addr_only, 0))
{
/* Don't NAT packet aimed at the intfc address */
- if (is_interface_addr (sm, node, sw_if_index0, ip0->dst_address.as_u32))
+ if (nat44_ei_is_interface_addr (nm->ip4_main, node, sw_if_index0,
+ ip0->dst_address.as_u32))
{
*dont_translate = 1;
goto out;
}
- b0->error = node->errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
- next0 = SNAT_OUT2IN_NEXT_DROP;
+ b0->error = node->errors[NAT44_EI_OUT2IN_ERROR_NO_TRANSLATION];
+ next0 = NAT44_EI_OUT2IN_NEXT_DROP;
goto out;
}
@@ -502,8 +484,8 @@ icmp_match_out2in_fast (snat_main_t *sm, vlib_node_runtime_t *node,
&& !icmp_type_is_error_message (vnet_buffer (b0)->ip.
reass.icmp_type_or_tcp_flags)))
{
- b0->error = node->errors[SNAT_OUT2IN_ERROR_BAD_ICMP_TYPE];
- next0 = SNAT_OUT2IN_NEXT_DROP;
+ b0->error = node->errors[NAT44_EI_OUT2IN_ERROR_BAD_ICMP_TYPE];
+ next0 = NAT44_EI_OUT2IN_NEXT_DROP;
goto out;
}
@@ -512,18 +494,20 @@ out:
}
#endif
-u32 icmp_out2in (snat_main_t *sm, vlib_buffer_t *b0, ip4_header_t *ip0,
- icmp46_header_t *icmp0, u32 sw_if_index0, u32 rx_fib_index0,
- vlib_node_runtime_t *node, u32 next0, u32 thread_index,
- snat_session_t **p_s0);
+u32 nat44_ei_icmp_out2in (vlib_buffer_t *b0, ip4_header_t *ip0,
+ icmp46_header_t *icmp0, u32 sw_if_index0,
+ u32 rx_fib_index0, vlib_node_runtime_t *node,
+ u32 next0, u32 thread_index,
+ nat44_ei_session_t **p_s0);
#ifndef CLIB_MARCH_VARIANT
u32
-icmp_out2in (snat_main_t *sm, vlib_buffer_t *b0, ip4_header_t *ip0,
- icmp46_header_t *icmp0, u32 sw_if_index0, u32 rx_fib_index0,
- vlib_node_runtime_t *node, u32 next0, u32 thread_index,
- snat_session_t **p_s0)
+nat44_ei_icmp_out2in (vlib_buffer_t *b0, ip4_header_t *ip0,
+ icmp46_header_t *icmp0, u32 sw_if_index0,
+ u32 rx_fib_index0, vlib_node_runtime_t *node, u32 next0,
+ u32 thread_index, nat44_ei_session_t **p_s0)
{
+ nat44_ei_main_t *nm = &nat44_ei_main;
icmp_echo_header_t *echo0, *inner_echo0 = 0;
ip4_header_t *inner_ip0 = 0;
void *l4_header = 0;
@@ -542,12 +526,22 @@ icmp_out2in (snat_main_t *sm, vlib_buffer_t *b0, ip4_header_t *ip0,
echo0 = (icmp_echo_header_t *) (icmp0 + 1);
- next0_tmp =
- sm->icmp_match_out2in_cb (sm, node, thread_index, b0, ip0, &addr, &port,
- &fib_index, &proto, p_s0, &dont_translate);
+ if (PREDICT_TRUE (nm->pat))
+ {
+ next0_tmp = nat44_ei_icmp_match_out2in_slow (
+ node, thread_index, b0, ip0, &addr, &port, &fib_index, &proto, p_s0,
+ &dont_translate);
+ }
+ else
+ {
+ next0_tmp = nat44_ei_icmp_match_out2in_fast (
+ node, thread_index, b0, ip0, &addr, &port, &fib_index, &proto, p_s0,
+ &dont_translate);
+ }
+
if (next0_tmp != ~0)
next0 = next0_tmp;
- if (next0 == SNAT_OUT2IN_NEXT_DROP || dont_translate)
+ if (next0 == NAT44_EI_OUT2IN_NEXT_DROP || dont_translate)
goto out;
if (PREDICT_TRUE (!ip4_is_fragment (ip0)))
@@ -561,7 +555,7 @@ icmp_out2in (snat_main_t *sm, vlib_buffer_t *b0, ip4_header_t *ip0,
checksum0 = ~ip_csum_fold (sum0);
if (checksum0 != 0 && checksum0 != 0xffff)
{
- next0 = SNAT_OUT2IN_NEXT_DROP;
+ next0 = NAT44_EI_OUT2IN_NEXT_DROP;
goto out;
}
}
@@ -604,7 +598,7 @@ icmp_out2in (snat_main_t *sm, vlib_buffer_t *b0, ip4_header_t *ip0,
if (!ip4_header_checksum_is_valid (inner_ip0))
{
- next0 = SNAT_OUT2IN_NEXT_DROP;
+ next0 = NAT44_EI_OUT2IN_NEXT_DROP;
goto out;
}
@@ -656,47 +650,42 @@ out:
#endif
static inline u32
-icmp_out2in_slow_path (snat_main_t * sm,
- vlib_buffer_t * b0,
- ip4_header_t * ip0,
- icmp46_header_t * icmp0,
- u32 sw_if_index0,
- u32 rx_fib_index0,
- vlib_node_runtime_t * node,
- u32 next0, f64 now,
- u32 thread_index, snat_session_t ** p_s0)
+nat44_ei_icmp_out2in_slow_path (nat44_ei_main_t *nm, vlib_buffer_t *b0,
+ ip4_header_t *ip0, icmp46_header_t *icmp0,
+ u32 sw_if_index0, u32 rx_fib_index0,
+ vlib_node_runtime_t *node, u32 next0, f64 now,
+ u32 thread_index, nat44_ei_session_t **p_s0)
{
vlib_main_t *vm = vlib_get_main ();
- next0 = icmp_out2in (sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node,
- next0, thread_index, p_s0);
- snat_session_t *s0 = *p_s0;
- if (PREDICT_TRUE (next0 != SNAT_OUT2IN_NEXT_DROP && s0))
+ next0 = nat44_ei_icmp_out2in (b0, ip0, icmp0, sw_if_index0, rx_fib_index0,
+ node, next0, thread_index, p_s0);
+ nat44_ei_session_t *s0 = *p_s0;
+ if (PREDICT_TRUE (next0 != NAT44_EI_OUT2IN_NEXT_DROP && s0))
{
/* Accounting */
nat44_ei_session_update_counters (
s0, now, vlib_buffer_length_in_chain (vm, b0), thread_index);
/* Per-user LRU list maintenance */
- nat44_session_update_lru (sm, s0, thread_index);
+ nat44_ei_session_update_lru (nm, s0, thread_index);
}
return next0;
}
static int
-nat_out2in_sm_unknown_proto (snat_main_t * sm,
- vlib_buffer_t * b,
- ip4_header_t * ip, u32 rx_fib_index)
+nat_out2in_sm_unknown_proto (nat44_ei_main_t *nm, vlib_buffer_t *b,
+ ip4_header_t *ip, u32 rx_fib_index)
{
clib_bihash_kv_8_8_t kv, value;
- snat_static_mapping_t *m;
+ nat44_ei_static_mapping_t *m;
u32 old_addr, new_addr;
ip_csum_t sum;
init_nat_k (&kv, ip->dst_address, 0, 0, 0);
- if (clib_bihash_search_8_8 (&sm->static_mapping_by_external, &kv, &value))
+ if (clib_bihash_search_8_8 (&nm->static_mapping_by_external, &kv, &value))
return 1;
- m = pool_elt_at_index (sm->static_mappings, value.value);
+ m = pool_elt_at_index (nm->static_mappings, value.value);
old_addr = ip->dst_address.as_u32;
new_addr = ip->dst_address.as_u32 = m->local_addr.as_u32;
@@ -708,15 +697,14 @@ nat_out2in_sm_unknown_proto (snat_main_t * sm,
return 0;
}
-VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
+VLIB_NODE_FN (nat44_ei_out2in_node)
+(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
{
u32 n_left_from, *from;
- snat_main_t *sm = &snat_main;
+ nat44_ei_main_t *nm = &nat44_ei_main;
f64 now = vlib_time_now (vm);
u32 thread_index = vm->thread_index;
- snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
+ nat44_ei_main_per_thread_data_t *tnm = &nm->per_thread_data[thread_index];
from = vlib_frame_vector_args (frame);
n_left_from = frame->n_vectors;
@@ -728,8 +716,8 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
while (n_left_from >= 2)
{
vlib_buffer_t *b0, *b1;
- u32 next0 = SNAT_OUT2IN_NEXT_LOOKUP;
- u32 next1 = SNAT_OUT2IN_NEXT_LOOKUP;
+ u32 next0 = NAT44_EI_OUT2IN_NEXT_LOOKUP;
+ u32 next1 = NAT44_EI_OUT2IN_NEXT_LOOKUP;
u32 sw_if_index0, sw_if_index1;
ip4_header_t *ip0, *ip1;
ip_csum_t sum0, sum1;
@@ -742,7 +730,7 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
icmp46_header_t *icmp0, *icmp1;
u32 rx_fib_index0, rx_fib_index1;
u32 proto0, proto1;
- snat_session_t *s0 = 0, *s1 = 0;
+ nat44_ei_session_t *s0 = 0, *s1 = 0;
clib_bihash_kv_8_8_t kv0, kv1, value0, value1;
u8 identity_nat0, identity_nat1;
ip4_address_t sm_addr0, sm_addr1;
@@ -778,8 +766,8 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
icmp0 = (icmp46_header_t *) udp0;
sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
- rx_fib_index0 = vec_elt (sm->ip4_main->fib_index_by_sw_if_index,
- sw_if_index0);
+ rx_fib_index0 =
+ vec_elt (nm->ip4_main->fib_index_by_sw_if_index, sw_if_index0);
if (PREDICT_FALSE (ip0->ttl == 1))
{
@@ -787,7 +775,7 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
icmp4_error_set_vnet_buffer (b0, ICMP4_time_exceeded,
ICMP4_time_exceeded_ttl_exceeded_in_transit,
0);
- next0 = SNAT_OUT2IN_NEXT_ICMP_ERROR;
+ next0 = NAT44_EI_OUT2IN_NEXT_ICMP_ERROR;
goto trace0;
}
@@ -795,16 +783,16 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
if (PREDICT_FALSE (proto0 == NAT_PROTOCOL_OTHER))
{
- if (nat_out2in_sm_unknown_proto (sm, b0, ip0, rx_fib_index0))
+ if (nat_out2in_sm_unknown_proto (nm, b0, ip0, rx_fib_index0))
{
- if (!sm->forwarding_enabled)
+ if (!nm->forwarding_enabled)
{
b0->error =
- node->errors[SNAT_OUT2IN_ERROR_UNSUPPORTED_PROTOCOL];
- next0 = SNAT_OUT2IN_NEXT_DROP;
+ node->errors[NAT44_EI_OUT2IN_ERROR_UNSUPPORTED_PROTOCOL];
+ next0 = NAT44_EI_OUT2IN_NEXT_DROP;
}
}
- vlib_increment_simple_counter (&sm->counters.slowpath.out2in.other,
+ vlib_increment_simple_counter (&nm->counters.slowpath.out2in.other,
thread_index, sw_if_index0, 1);
goto trace0;
@@ -812,10 +800,10 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
if (PREDICT_FALSE (proto0 == NAT_PROTOCOL_ICMP))
{
- next0 = icmp_out2in_slow_path
- (sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node,
- next0, now, thread_index, &s0);
- vlib_increment_simple_counter (&sm->counters.slowpath.out2in.icmp,
+ next0 = nat44_ei_icmp_out2in_slow_path (
+ nm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node, next0, now,
+ thread_index, &s0);
+ vlib_increment_simple_counter (&nm->counters.slowpath.out2in.icmp,
thread_index, sw_if_index0, 1);
goto trace0;
}
@@ -823,7 +811,7 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
init_nat_k (&kv0, ip0->dst_address,
vnet_buffer (b0)->ip.reass.l4_dst_port, rx_fib_index0,
proto0);
- if (clib_bihash_search_8_8 (&sm->out2in, &kv0, &value0))
+ if (clib_bihash_search_8_8 (&nm->out2in, &kv0, &value0))
{
/* Try to match static mapping by external address and port,
destination address and port in packet */
@@ -845,10 +833,11 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
goto trace0;
}
- if (!sm->forwarding_enabled)
+ if (!nm->forwarding_enabled)
{
- b0->error = node->errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
- next0 = SNAT_OUT2IN_NEXT_DROP;
+ b0->error =
+ node->errors[NAT44_EI_OUT2IN_ERROR_NO_TRANSLATION];
+ next0 = NAT44_EI_OUT2IN_NEXT_DROP;
}
goto trace0;
}
@@ -857,22 +846,18 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
goto trace0;
/* Create session initiated by host from external network */
- s0 = create_session_for_static_mapping (sm, b0,
- sm_addr0, sm_port0,
- sm_fib_index0,
- ip0->dst_address,
- vnet_buffer (b0)->ip.
- reass.l4_dst_port,
- rx_fib_index0, proto0, node,
- thread_index, now);
+ s0 = create_session_for_static_mapping (
+ nm, b0, sm_addr0, sm_port0, sm_fib_index0, ip0->dst_address,
+ vnet_buffer (b0)->ip.reass.l4_dst_port, rx_fib_index0, proto0,
+ node, thread_index, now);
if (!s0)
{
- next0 = SNAT_OUT2IN_NEXT_DROP;
+ next0 = NAT44_EI_OUT2IN_NEXT_DROP;
goto trace0;
}
}
else
- s0 = pool_elt_at_index (tsm->sessions,
+ s0 = pool_elt_at_index (tnm->sessions,
nat_value_get_session_index (&value0));
old_addr0 = ip0->dst_address.as_u32;
@@ -901,7 +886,7 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
length /* changed member */ );
tcp0->checksum = ip_csum_fold (sum0);
}
- vlib_increment_simple_counter (&sm->counters.slowpath.out2in.tcp,
+ vlib_increment_simple_counter (&nm->counters.slowpath.out2in.tcp,
thread_index, sw_if_index0, 1);
}
else
@@ -922,7 +907,7 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
udp0->checksum = ip_csum_fold (sum0);
}
}
- vlib_increment_simple_counter (&sm->counters.slowpath.out2in.udp,
+ vlib_increment_simple_counter (&nm->counters.slowpath.out2in.udp,
thread_index, sw_if_index0, 1);
}
@@ -930,24 +915,24 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
nat44_ei_session_update_counters (
s0, now, vlib_buffer_length_in_chain (vm, b0), thread_index);
/* Per-user LRU list maintenance */
- nat44_session_update_lru (sm, s0, thread_index);
+ nat44_ei_session_update_lru (nm, s0, thread_index);
trace0:
if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)
&& (b0->flags & VLIB_BUFFER_IS_TRACED)))
{
- snat_out2in_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t));
+ nat44_ei_out2in_trace_t *t =
+ vlib_add_trace (vm, node, b0, sizeof (*t));
t->sw_if_index = sw_if_index0;
t->next_index = next0;
t->session_index = ~0;
if (s0)
- t->session_index =
- s0 - sm->per_thread_data[thread_index].sessions;
+ t->session_index = s0 - nm->per_thread_data[thread_index].sessions;
}
- if (next0 == SNAT_OUT2IN_NEXT_DROP)
+ if (next0 == NAT44_EI_OUT2IN_NEXT_DROP)
{
- vlib_increment_simple_counter (&sm->counters.slowpath.out2in.drops,
+ vlib_increment_simple_counter (&nm->counters.slowpath.out2in.drops,
thread_index, sw_if_index0, 1);
}
@@ -958,8 +943,8 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
icmp1 = (icmp46_header_t *) udp1;
sw_if_index1 = vnet_buffer (b1)->sw_if_index[VLIB_RX];
- rx_fib_index1 = vec_elt (sm->ip4_main->fib_index_by_sw_if_index,
- sw_if_index1);
+ rx_fib_index1 =
+ vec_elt (nm->ip4_main->fib_index_by_sw_if_index, sw_if_index1);
if (PREDICT_FALSE (ip1->ttl == 1))
{
@@ -967,7 +952,7 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
icmp4_error_set_vnet_buffer (b1, ICMP4_time_exceeded,
ICMP4_time_exceeded_ttl_exceeded_in_transit,
0);
- next1 = SNAT_OUT2IN_NEXT_ICMP_ERROR;
+ next1 = NAT44_EI_OUT2IN_NEXT_ICMP_ERROR;
goto trace1;
}
@@ -975,26 +960,26 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
if (PREDICT_FALSE (proto1 == NAT_PROTOCOL_OTHER))
{
- if (nat_out2in_sm_unknown_proto (sm, b1, ip1, rx_fib_index1))
+ if (nat_out2in_sm_unknown_proto (nm, b1, ip1, rx_fib_index1))
{
- if (!sm->forwarding_enabled)
+ if (!nm->forwarding_enabled)
{
b1->error =
- node->errors[SNAT_OUT2IN_ERROR_UNSUPPORTED_PROTOCOL];
- next1 = SNAT_OUT2IN_NEXT_DROP;
+ node->errors[NAT44_EI_OUT2IN_ERROR_UNSUPPORTED_PROTOCOL];
+ next1 = NAT44_EI_OUT2IN_NEXT_DROP;
}
}
- vlib_increment_simple_counter (&sm->counters.slowpath.out2in.other,
+ vlib_increment_simple_counter (&nm->counters.slowpath.out2in.other,
thread_index, sw_if_index1, 1);
goto trace1;
}
if (PREDICT_FALSE (proto1 == NAT_PROTOCOL_ICMP))
{
- next1 = icmp_out2in_slow_path
- (sm, b1, ip1, icmp1, sw_if_index1, rx_fib_index1, node,
- next1, now, thread_index, &s1);
- vlib_increment_simple_counter (&sm->counters.slowpath.out2in.icmp,
+ next1 = nat44_ei_icmp_out2in_slow_path (
+ nm, b1, ip1, icmp1, sw_if_index1, rx_fib_index1, node, next1, now,
+ thread_index, &s1);
+ vlib_increment_simple_counter (&nm->counters.slowpath.out2in.icmp,
thread_index, sw_if_index1, 1);
goto trace1;
}
@@ -1002,7 +987,7 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
init_nat_k (&kv1, ip1->dst_address,
vnet_buffer (b1)->ip.reass.l4_dst_port, rx_fib_index1,
proto1);
- if (clib_bihash_search_8_8 (&sm->out2in, &kv1, &value1))
+ if (clib_bihash_search_8_8 (&nm->out2in, &kv1, &value1))
{
/* Try to match static mapping by external address and port,
destination address and port in packet */
@@ -1024,10 +1009,11 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
goto trace1;
}
- if (!sm->forwarding_enabled)
+ if (!nm->forwarding_enabled)
{
- b1->error = node->errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
- next1 = SNAT_OUT2IN_NEXT_DROP;
+ b1->error =
+ node->errors[NAT44_EI_OUT2IN_ERROR_NO_TRANSLATION];
+ next1 = NAT44_EI_OUT2IN_NEXT_DROP;
}
goto trace1;
}
@@ -1036,22 +1022,18 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
goto trace1;
/* Create session initiated by host from external network */
- s1 =
- create_session_for_static_mapping (sm, b1, sm_addr1, sm_port1,
- sm_fib_index1,
- ip1->dst_address,
- vnet_buffer (b1)->ip.
- reass.l4_dst_port,
- rx_fib_index1, proto1, node,
- thread_index, now);
+ s1 = create_session_for_static_mapping (
+ nm, b1, sm_addr1, sm_port1, sm_fib_index1, ip1->dst_address,
+ vnet_buffer (b1)->ip.reass.l4_dst_port, rx_fib_index1, proto1,
+ node, thread_index, now);
if (!s1)
{
- next1 = SNAT_OUT2IN_NEXT_DROP;
+ next1 = NAT44_EI_OUT2IN_NEXT_DROP;
goto trace1;
}
}
else
- s1 = pool_elt_at_index (sm->per_thread_data[thread_index].sessions,
+ s1 = pool_elt_at_index (nm->per_thread_data[thread_index].sessions,
nat_value_get_session_index (&value1));
old_addr1 = ip1->dst_address.as_u32;
@@ -1081,7 +1063,7 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
length /* changed member */ );
tcp1->checksum = ip_csum_fold (sum1);
}
- vlib_increment_simple_counter (&sm->counters.slowpath.out2in.tcp,
+ vlib_increment_simple_counter (&nm->counters.slowpath.out2in.tcp,
thread_index, sw_if_index1, 1);
}
else
@@ -1105,7 +1087,7 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
udp1->checksum = ip_csum_fold (sum1);
}
}
- vlib_increment_simple_counter (&sm->counters.slowpath.out2in.udp,
+ vlib_increment_simple_counter (&nm->counters.slowpath.out2in.udp,
thread_index, sw_if_index1, 1);
}
@@ -1113,24 +1095,24 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
nat44_ei_session_update_counters (
s1, now, vlib_buffer_length_in_chain (vm, b1), thread_index);
/* Per-user LRU list maintenance */
- nat44_session_update_lru (sm, s1, thread_index);
+ nat44_ei_session_update_lru (nm, s1, thread_index);
trace1:
if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)
&& (b1->flags & VLIB_BUFFER_IS_TRACED)))
{
- snat_out2in_trace_t *t = vlib_add_trace (vm, node, b1, sizeof (*t));
+ nat44_ei_out2in_trace_t *t =
+ vlib_add_trace (vm, node, b1, sizeof (*t));
t->sw_if_index = sw_if_index1;
t->next_index = next1;
t->session_index = ~0;
if (s1)
- t->session_index =
- s1 - sm->per_thread_data[thread_index].sessions;
+ t->session_index = s1 - nm->per_thread_data[thread_index].sessions;
}
- if (next1 == SNAT_OUT2IN_NEXT_DROP)
+ if (next1 == NAT44_EI_OUT2IN_NEXT_DROP)
{
- vlib_increment_simple_counter (&sm->counters.slowpath.out2in.drops,
+ vlib_increment_simple_counter (&nm->counters.slowpath.out2in.drops,
thread_index, sw_if_index1, 1);
}
@@ -1143,7 +1125,7 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
while (n_left_from > 0)
{
vlib_buffer_t *b0;
- u32 next0 = SNAT_OUT2IN_NEXT_LOOKUP;
+ u32 next0 = NAT44_EI_OUT2IN_NEXT_LOOKUP;
u32 sw_if_index0;
ip4_header_t *ip0;
ip_csum_t sum0;
@@ -1154,7 +1136,7 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
icmp46_header_t *icmp0;
u32 rx_fib_index0;
u32 proto0;
- snat_session_t *s0 = 0;
+ nat44_ei_session_t *s0 = 0;
clib_bihash_kv_8_8_t kv0, value0;
u8 identity_nat0;
ip4_address_t sm_addr0;
@@ -1172,23 +1154,23 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
icmp0 = (icmp46_header_t *) udp0;
sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
- rx_fib_index0 = vec_elt (sm->ip4_main->fib_index_by_sw_if_index,
- sw_if_index0);
+ rx_fib_index0 =
+ vec_elt (nm->ip4_main->fib_index_by_sw_if_index, sw_if_index0);
proto0 = ip_proto_to_nat_proto (ip0->protocol);
if (PREDICT_FALSE (proto0 == NAT_PROTOCOL_OTHER))
{
- if (nat_out2in_sm_unknown_proto (sm, b0, ip0, rx_fib_index0))
+ if (nat_out2in_sm_unknown_proto (nm, b0, ip0, rx_fib_index0))
{
- if (!sm->forwarding_enabled)
+ if (!nm->forwarding_enabled)
{
b0->error =
- node->errors[SNAT_OUT2IN_ERROR_UNSUPPORTED_PROTOCOL];
- next0 = SNAT_OUT2IN_NEXT_DROP;
+ node->errors[NAT44_EI_OUT2IN_ERROR_UNSUPPORTED_PROTOCOL];
+ next0 = NAT44_EI_OUT2IN_NEXT_DROP;
}
}
- vlib_increment_simple_counter (&sm->counters.slowpath.out2in.other,
+ vlib_increment_simple_counter (&nm->counters.slowpath.out2in.other,
thread_index, sw_if_index0, 1);
goto trace00;
}
@@ -1199,16 +1181,16 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
icmp4_error_set_vnet_buffer (b0, ICMP4_time_exceeded,
ICMP4_time_exceeded_ttl_exceeded_in_transit,
0);
- next0 = SNAT_OUT2IN_NEXT_ICMP_ERROR;
+ next0 = NAT44_EI_OUT2IN_NEXT_ICMP_ERROR;
goto trace00;
}
if (PREDICT_FALSE (proto0 == NAT_PROTOCOL_ICMP))
{
- next0 = icmp_out2in_slow_path
- (sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node,
- next0, now, thread_index, &s0);
- vlib_increment_simple_counter (&sm->counters.slowpath.out2in.icmp,
+ next0 = nat44_ei_icmp_out2in_slow_path (
+ nm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0, node, next0, now,
+ thread_index, &s0);
+ vlib_increment_simple_counter (&nm->counters.slowpath.out2in.icmp,
thread_index, sw_if_index0, 1);
goto trace00;
}
@@ -1217,7 +1199,7 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
vnet_buffer (b0)->ip.reass.l4_dst_port, rx_fib_index0,
proto0);
- if (clib_bihash_search_8_8 (&sm->out2in, &kv0, &value0))
+ if (clib_bihash_search_8_8 (&nm->out2in, &kv0, &value0))
{
/* Try to match static mapping by external address and port,
destination address and port in packet */
@@ -1239,10 +1221,11 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
goto trace00;
}
- if (!sm->forwarding_enabled)
+ if (!nm->forwarding_enabled)
{
- b0->error = node->errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
- next0 = SNAT_OUT2IN_NEXT_DROP;
+ b0->error =
+ node->errors[NAT44_EI_OUT2IN_ERROR_NO_TRANSLATION];
+ next0 = NAT44_EI_OUT2IN_NEXT_DROP;
}
goto trace00;
}
@@ -1251,22 +1234,18 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
goto trace00;
/* Create session initiated by host from external network */
- s0 = create_session_for_static_mapping (sm, b0,
- sm_addr0, sm_port0,
- sm_fib_index0,
- ip0->dst_address,
- vnet_buffer (b0)->ip.
- reass.l4_dst_port,
- rx_fib_index0, proto0, node,
- thread_index, now);
+ s0 = create_session_for_static_mapping (
+ nm, b0, sm_addr0, sm_port0, sm_fib_index0, ip0->dst_address,
+ vnet_buffer (b0)->ip.reass.l4_dst_port, rx_fib_index0, proto0,
+ node, thread_index, now);
if (!s0)
{
- next0 = SNAT_OUT2IN_NEXT_DROP;
+ next0 = NAT44_EI_OUT2IN_NEXT_DROP;
goto trace00;
}
}
else
- s0 = pool_elt_at_index (sm->per_thread_data[thread_index].sessions,
+ s0 = pool_elt_at_index (nm->per_thread_data[thread_index].sessions,
nat_value_get_session_index (&value0));
old_addr0 = ip0->dst_address.as_u32;
@@ -1296,7 +1275,7 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
length /* changed member */ );
tcp0->checksum = ip_csum_fold (sum0);
}
- vlib_increment_simple_counter (&sm->counters.slowpath.out2in.tcp,
+ vlib_increment_simple_counter (&nm->counters.slowpath.out2in.tcp,
thread_index, sw_if_index0, 1);
}
else
@@ -1317,7 +1296,7 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
udp0->checksum = ip_csum_fold (sum0);
}
}
- vlib_increment_simple_counter (&sm->counters.slowpath.out2in.udp,
+ vlib_increment_simple_counter (&nm->counters.slowpath.out2in.udp,
thread_index, sw_if_index0, 1);
}
@@ -1325,24 +1304,24 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
nat44_ei_session_update_counters (
s0, now, vlib_buffer_length_in_chain (vm, b0), thread_index);
/* Per-user LRU list maintenance */
- nat44_session_update_lru (sm, s0, thread_index);
+ nat44_ei_session_update_lru (nm, s0, thread_index);
trace00:
if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)
&& (b0->flags & VLIB_BUFFER_IS_TRACED)))
{
- snat_out2in_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t));
+ nat44_ei_out2in_trace_t *t =
+ vlib_add_trace (vm, node, b0, sizeof (*t));
t->sw_if_index = sw_if_index0;
t->next_index = next0;
t->session_index = ~0;
if (s0)
- t->session_index =
- s0 - sm->per_thread_data[thread_index].sessions;
+ t->session_index = s0 - nm->per_thread_data[thread_index].sessions;
}
- if (next0 == SNAT_OUT2IN_NEXT_DROP)
+ if (next0 == NAT44_EI_OUT2IN_NEXT_DROP)
{
- vlib_increment_simple_counter (&sm->counters.slowpath.out2in.drops,
+ vlib_increment_simple_counter (&nm->counters.slowpath.out2in.drops,
thread_index, sw_if_index0, 1);
}
@@ -1358,34 +1337,33 @@ VLIB_NODE_FN (snat_out2in_node) (vlib_main_t * vm,
}
/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (snat_out2in_node) = {
- .name = "nat44-out2in",
+VLIB_REGISTER_NODE (nat44_ei_out2in_node) = {
+ .name = "nat44-ei-out2in",
.vector_size = sizeof (u32),
- .format_trace = format_snat_out2in_trace,
+ .format_trace = format_nat44_ei_out2in_trace,
.type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN(snat_out2in_error_strings),
- .error_strings = snat_out2in_error_strings,
+ .n_errors = ARRAY_LEN(nat44_ei_out2in_error_strings),
+ .error_strings = nat44_ei_out2in_error_strings,
- .runtime_data_bytes = sizeof (snat_runtime_t),
+ .runtime_data_bytes = sizeof (nat44_ei_runtime_t),
- .n_next_nodes = SNAT_OUT2IN_N_NEXT,
+ .n_next_nodes = NAT44_EI_OUT2IN_N_NEXT,
/* edit / add dispositions here */
.next_nodes = {
- [SNAT_OUT2IN_NEXT_DROP] = "error-drop",
- [SNAT_OUT2IN_NEXT_LOOKUP] = "ip4-lookup",
- [SNAT_OUT2IN_NEXT_ICMP_ERROR] = "ip4-icmp-error",
+ [NAT44_EI_OUT2IN_NEXT_DROP] = "error-drop",
+ [NAT44_EI_OUT2IN_NEXT_LOOKUP] = "ip4-lookup",
+ [NAT44_EI_OUT2IN_NEXT_ICMP_ERROR] = "ip4-icmp-error",
},
};
/* *INDENT-ON* */
-VLIB_NODE_FN (snat_out2in_fast_node) (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
+VLIB_NODE_FN (nat44_ei_out2in_fast_node)
+(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
{
u32 n_left_from, *from;
- snat_main_t *sm = &snat_main;
+ nat44_ei_main_t *nm = &nat44_ei_main;
from = vlib_frame_vector_args (frame);
n_left_from = frame->n_vectors;
@@ -1396,7 +1374,7 @@ VLIB_NODE_FN (snat_out2in_fast_node) (vlib_main_t * vm,
while (n_left_from > 0)
{
vlib_buffer_t *b0;
- u32 next0 = SNAT_OUT2IN_NEXT_DROP;
+ u32 next0 = NAT44_EI_OUT2IN_NEXT_DROP;
u32 sw_if_index0;
ip4_header_t *ip0;
ip_csum_t sum0;
@@ -1430,7 +1408,7 @@ VLIB_NODE_FN (snat_out2in_fast_node) (vlib_main_t * vm,
icmp4_error_set_vnet_buffer (b0, ICMP4_time_exceeded,
ICMP4_time_exceeded_ttl_exceeded_in_transit,
0);
- next0 = SNAT_OUT2IN_NEXT_ICMP_ERROR;
+ next0 = NAT44_EI_OUT2IN_NEXT_ICMP_ERROR;
goto trace00;
}
@@ -1441,8 +1419,8 @@ VLIB_NODE_FN (snat_out2in_fast_node) (vlib_main_t * vm,
if (PREDICT_FALSE (proto0 == NAT_PROTOCOL_ICMP))
{
- next0 = icmp_out2in (sm, b0, ip0, icmp0, sw_if_index0, rx_fib_index0,
- node, next0, ~0, 0);
+ next0 = nat44_ei_icmp_out2in (b0, ip0, icmp0, sw_if_index0,
+ rx_fib_index0, node, next0, ~0, 0);
goto trace00;
}
@@ -1450,7 +1428,7 @@ VLIB_NODE_FN (snat_out2in_fast_node) (vlib_main_t * vm,
rx_fib_index0, proto0, &sm_addr0,
&sm_port0, &sm_fib_index0, 1, 0, 0))
{
- b0->error = node->errors[SNAT_OUT2IN_ERROR_NO_TRANSLATION];
+ b0->error = node->errors[NAT44_EI_OUT2IN_ERROR_NO_TRANSLATION];
goto trace00;
}
@@ -1518,14 +1496,15 @@ VLIB_NODE_FN (snat_out2in_fast_node) (vlib_main_t * vm,
if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)
&& (b0->flags & VLIB_BUFFER_IS_TRACED)))
{
- snat_out2in_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t));
+ nat44_ei_out2in_trace_t *t =
+ vlib_add_trace (vm, node, b0, sizeof (*t));
t->sw_if_index = sw_if_index0;
t->next_index = next0;
}
- if (next0 == SNAT_OUT2IN_NEXT_DROP)
+ if (next0 == NAT44_EI_OUT2IN_NEXT_DROP)
{
- vlib_increment_simple_counter (&sm->counters.fastpath.out2in.drops,
+ vlib_increment_simple_counter (&nm->counters.fastpath.out2in.drops,
vm->thread_index, sw_if_index0, 1);
}
@@ -1541,24 +1520,24 @@ VLIB_NODE_FN (snat_out2in_fast_node) (vlib_main_t * vm,
}
/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (snat_out2in_fast_node) = {
- .name = "nat44-out2in-fast",
+VLIB_REGISTER_NODE (nat44_ei_out2in_fast_node) = {
+ .name = "nat44-ei-out2in-fast",
.vector_size = sizeof (u32),
- .format_trace = format_snat_out2in_fast_trace,
+ .format_trace = format_nat44_ei_out2in_fast_trace,
.type = VLIB_NODE_TYPE_INTERNAL,
- .n_errors = ARRAY_LEN(snat_out2in_error_strings),
- .error_strings = snat_out2in_error_strings,
+ .n_errors = ARRAY_LEN(nat44_ei_out2in_error_strings),
+ .error_strings = nat44_ei_out2in_error_strings,
- .runtime_data_bytes = sizeof (snat_runtime_t),
+ .runtime_data_bytes = sizeof (nat44_ei_runtime_t),
- .n_next_nodes = SNAT_OUT2IN_N_NEXT,
+ .n_next_nodes = NAT44_EI_OUT2IN_N_NEXT,
/* edit / add dispositions here */
.next_nodes = {
- [SNAT_OUT2IN_NEXT_LOOKUP] = "ip4-lookup",
- [SNAT_OUT2IN_NEXT_DROP] = "error-drop",
- [SNAT_OUT2IN_NEXT_ICMP_ERROR] = "ip4-icmp-error",
+ [NAT44_EI_OUT2IN_NEXT_LOOKUP] = "ip4-lookup",
+ [NAT44_EI_OUT2IN_NEXT_DROP] = "error-drop",
+ [NAT44_EI_OUT2IN_NEXT_ICMP_ERROR] = "ip4-icmp-error",
},
};
/* *INDENT-ON* */
diff --git a/src/plugins/nat/nat44/ed_inlines.h b/src/plugins/nat/nat44/ed_inlines.h
deleted file mode 100644
index 87de25e990b..00000000000
--- a/src/plugins/nat/nat44/ed_inlines.h
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * simple nat plugin
- *
- * Copyright (c) 2020 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef __included_ed_inlines_h__
-#define __included_ed_inlines_h__
-
-#include <float.h>
-#include <vppinfra/clib.h>
-#include <nat/nat.h>
-#include <nat/nat_inlines.h>
-
-static_always_inline int
-nat_ed_lru_insert (snat_main_per_thread_data_t * tsm,
- snat_session_t * s, f64 now, u8 proto)
-{
- dlist_elt_t *lru_list_elt;
- pool_get (tsm->lru_pool, lru_list_elt);
- s->lru_index = lru_list_elt - tsm->lru_pool;
- switch (proto)
- {
- case IP_PROTOCOL_UDP:
- s->lru_head_index = tsm->udp_lru_head_index;
- break;
- case IP_PROTOCOL_TCP:
- s->lru_head_index = tsm->tcp_trans_lru_head_index;
- break;
- case IP_PROTOCOL_ICMP:
- s->lru_head_index = tsm->icmp_lru_head_index;
- break;
- default:
- s->lru_head_index = tsm->unk_proto_lru_head_index;
- break;
- }
- clib_dlist_addtail (tsm->lru_pool, s->lru_head_index, s->lru_index);
- lru_list_elt->value = s - tsm->sessions;
- s->last_lru_update = now;
- return 1;
-}
-
-static_always_inline void
-nat_6t_flow_to_ed_k (clib_bihash_kv_16_8_t *kv, nat_6t_flow_t *f)
-{
- init_ed_k (kv, f->match.saddr, f->match.sport, f->match.daddr,
- f->match.dport, f->match.fib_index, f->match.proto);
-}
-
-static_always_inline void
-nat_6t_flow_to_ed_kv (clib_bihash_kv_16_8_t *kv, nat_6t_flow_t *f,
- u32 thread_idx, u32 session_idx)
-{
- init_ed_kv (kv, f->match.saddr, f->match.sport, f->match.daddr,
- f->match.dport, f->match.fib_index, f->match.proto, thread_idx,
- session_idx);
-}
-
-static_always_inline int
-nat_ed_ses_i2o_flow_hash_add_del (snat_main_t *sm, u32 thread_idx,
- snat_session_t *s, int is_add)
-{
- snat_main_per_thread_data_t *tsm =
- vec_elt_at_index (sm->per_thread_data, thread_idx);
- clib_bihash_kv_16_8_t kv;
- if (0 == is_add)
- {
- nat_6t_flow_to_ed_k (&kv, &s->i2o);
- }
- else
- {
- nat_6t_flow_to_ed_kv (&kv, &s->i2o, thread_idx, s - tsm->sessions);
- nat_6t_l3_l4_csum_calc (&s->i2o);
- }
- return clib_bihash_add_del_16_8 (&sm->flow_hash, &kv, is_add);
-}
-
-static_always_inline int
-nat_ed_ses_o2i_flow_hash_add_del (snat_main_t *sm, u32 thread_idx,
- snat_session_t *s, int is_add)
-{
- snat_main_per_thread_data_t *tsm =
- vec_elt_at_index (sm->per_thread_data, thread_idx);
- clib_bihash_kv_16_8_t kv;
- if (0 == is_add)
- {
- nat_6t_flow_to_ed_k (&kv, &s->o2i);
- }
- else
- {
- nat_6t_flow_to_ed_kv (&kv, &s->o2i, thread_idx, s - tsm->sessions);
- nat_6t_l3_l4_csum_calc (&s->o2i);
- }
- return clib_bihash_add_del_16_8 (&sm->flow_hash, &kv, is_add);
-}
-
-always_inline void
-nat_ed_session_delete (snat_main_t * sm, snat_session_t * ses,
- u32 thread_index, int lru_delete
- /* delete from global LRU list */ )
-{
- snat_main_per_thread_data_t *tsm = vec_elt_at_index (sm->per_thread_data,
- thread_index);
-
- if (lru_delete)
- {
- clib_dlist_remove (tsm->lru_pool, ses->lru_index);
- }
- pool_put_index (tsm->lru_pool, ses->lru_index);
- if (nat_ed_ses_i2o_flow_hash_add_del (sm, thread_index, ses, 0))
- nat_elog_warn ("flow hash del failed");
- if (nat_ed_ses_o2i_flow_hash_add_del (sm, thread_index, ses, 0))
- nat_elog_warn ("flow hash del failed");
- pool_put (tsm->sessions, ses);
- vlib_set_simple_counter (&sm->total_sessions, thread_index, 0,
- pool_elts (tsm->sessions));
-
-}
-
-static_always_inline int
-nat_lru_free_one_with_head (snat_main_t * sm, int thread_index,
- f64 now, u32 head_index)
-{
- snat_session_t *s = NULL;
- dlist_elt_t *oldest_elt;
- f64 sess_timeout_time;
- u32 oldest_index;
- snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
- oldest_index = clib_dlist_remove_head (tsm->lru_pool, head_index);
- if (~0 != oldest_index)
- {
- oldest_elt = pool_elt_at_index (tsm->lru_pool, oldest_index);
- s = pool_elt_at_index (tsm->sessions, oldest_elt->value);
-
- sess_timeout_time =
- s->last_heard + (f64) nat44_session_get_timeout (sm, s);
- if (now >= sess_timeout_time
- || (s->tcp_closed_timestamp && now >= s->tcp_closed_timestamp))
- {
- nat_free_session_data (sm, s, thread_index, 0);
- nat_ed_session_delete (sm, s, thread_index, 0);
- return 1;
- }
- else
- {
- clib_dlist_addhead (tsm->lru_pool, head_index, oldest_index);
- }
- }
- return 0;
-}
-
-static_always_inline int
-nat_lru_free_one (snat_main_t * sm, int thread_index, f64 now)
-{
- snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
- int rc = 0;
-#define _(p) \
- if ((rc = nat_lru_free_one_with_head (sm, thread_index, now, \
- tsm->p##_lru_head_index))) \
- { \
- return rc; \
- }
- _(tcp_trans);
- _(udp);
- _(unk_proto);
- _(icmp);
- _(tcp_estab);
-#undef _
- return 0;
-}
-
-static_always_inline snat_session_t *
-nat_ed_session_alloc (snat_main_t * sm, u32 thread_index, f64 now, u8 proto)
-{
- snat_session_t *s;
- snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
-
- nat_lru_free_one (sm, thread_index, now);
-
- pool_get (tsm->sessions, s);
- clib_memset (s, 0, sizeof (*s));
-
- nat_ed_lru_insert (tsm, s, now, proto);
-
- s->ha_last_refreshed = now;
- vlib_set_simple_counter (&sm->total_sessions, thread_index, 0,
- pool_elts (tsm->sessions));
- return s;
-}
-
-// slow path
-static_always_inline void
-per_vrf_sessions_cleanup (u32 thread_index)
-{
- snat_main_t *sm = &snat_main;
- snat_main_per_thread_data_t *tsm =
- vec_elt_at_index (sm->per_thread_data, thread_index);
- per_vrf_sessions_t *per_vrf_sessions;
- u32 *to_free = 0, *i;
-
- vec_foreach (per_vrf_sessions, tsm->per_vrf_sessions_vec)
- {
- if (per_vrf_sessions->expired)
- {
- if (per_vrf_sessions->ses_count == 0)
- {
- vec_add1 (to_free, per_vrf_sessions - tsm->per_vrf_sessions_vec);
- }
- }
- }
-
- if (vec_len (to_free))
- {
- vec_foreach (i, to_free)
- {
- vec_del1 (tsm->per_vrf_sessions_vec, *i);
- }
- }
-
- vec_free (to_free);
-}
-
-// slow path
-static_always_inline void
-per_vrf_sessions_register_session (snat_session_t * s, u32 thread_index)
-{
- snat_main_t *sm = &snat_main;
- snat_main_per_thread_data_t *tsm =
- vec_elt_at_index (sm->per_thread_data, thread_index);
- per_vrf_sessions_t *per_vrf_sessions;
-
- per_vrf_sessions_cleanup (thread_index);
-
- // s->per_vrf_sessions_index == ~0 ... reuse of old session
-
- vec_foreach (per_vrf_sessions, tsm->per_vrf_sessions_vec)
- {
- // ignore already expired registrations
- if (per_vrf_sessions->expired)
- continue;
-
- if ((s->in2out.fib_index == per_vrf_sessions->rx_fib_index) &&
- (s->out2in.fib_index == per_vrf_sessions->tx_fib_index))
- {
- goto done;
- }
- if ((s->in2out.fib_index == per_vrf_sessions->tx_fib_index) &&
- (s->out2in.fib_index == per_vrf_sessions->rx_fib_index))
- {
- goto done;
- }
- }
-
- // create a new registration
- vec_add2 (tsm->per_vrf_sessions_vec, per_vrf_sessions, 1);
- clib_memset (per_vrf_sessions, 0, sizeof (*per_vrf_sessions));
-
- per_vrf_sessions->rx_fib_index = s->in2out.fib_index;
- per_vrf_sessions->tx_fib_index = s->out2in.fib_index;
-
-done:
- s->per_vrf_sessions_index = per_vrf_sessions - tsm->per_vrf_sessions_vec;
- per_vrf_sessions->ses_count++;
-}
-
-// fast path
-static_always_inline void
-per_vrf_sessions_unregister_session (snat_session_t * s, u32 thread_index)
-{
- snat_main_t *sm = &snat_main;
- snat_main_per_thread_data_t *tsm;
- per_vrf_sessions_t *per_vrf_sessions;
-
- ASSERT (s->per_vrf_sessions_index != ~0);
-
- tsm = vec_elt_at_index (sm->per_thread_data, thread_index);
- per_vrf_sessions =
- vec_elt_at_index (tsm->per_vrf_sessions_vec, s->per_vrf_sessions_index);
-
- ASSERT (per_vrf_sessions->ses_count != 0);
-
- per_vrf_sessions->ses_count--;
- s->per_vrf_sessions_index = ~0;
-}
-
-// fast path
-static_always_inline u8
-per_vrf_sessions_is_expired (snat_session_t * s, u32 thread_index)
-{
- snat_main_t *sm = &snat_main;
- snat_main_per_thread_data_t *tsm;
- per_vrf_sessions_t *per_vrf_sessions;
-
- ASSERT (s->per_vrf_sessions_index != ~0);
-
- tsm = vec_elt_at_index (sm->per_thread_data, thread_index);
- per_vrf_sessions =
- vec_elt_at_index (tsm->per_vrf_sessions_vec, s->per_vrf_sessions_index);
- return per_vrf_sessions->expired;
-}
-
-static_always_inline void
-nat_6t_flow_init (nat_6t_flow_t *f, u32 thread_idx, ip4_address_t saddr,
- u16 sport, ip4_address_t daddr, u16 dport, u32 fib_index,
- u8 proto, u32 session_idx)
-{
- clib_memset (f, 0, sizeof (*f));
- f->match.saddr = saddr;
- f->match.sport = sport;
- f->match.daddr = daddr;
- f->match.dport = dport;
- f->match.proto = proto;
- f->match.fib_index = fib_index;
-}
-
-static_always_inline void
-nat_6t_i2o_flow_init (snat_main_t *sm, u32 thread_idx, snat_session_t *s,
- ip4_address_t saddr, u16 sport, ip4_address_t daddr,
- u16 dport, u32 fib_index, u8 proto)
-{
- snat_main_per_thread_data_t *tsm =
- vec_elt_at_index (sm->per_thread_data, thread_idx);
- nat_6t_flow_init (&s->i2o, thread_idx, saddr, sport, daddr, dport, fib_index,
- proto, s - tsm->sessions);
-}
-
-static_always_inline void
-nat_6t_o2i_flow_init (snat_main_t *sm, u32 thread_idx, snat_session_t *s,
- ip4_address_t saddr, u16 sport, ip4_address_t daddr,
- u16 dport, u32 fib_index, u8 proto)
-{
- snat_main_per_thread_data_t *tsm =
- vec_elt_at_index (sm->per_thread_data, thread_idx);
- nat_6t_flow_init (&s->o2i, thread_idx, saddr, sport, daddr, dport, fib_index,
- proto, s - tsm->sessions);
-}
-
-static_always_inline int
-nat_6t_flow_match (nat_6t_flow_t *f, vlib_buffer_t *b, ip4_address_t saddr,
- u16 sport, ip4_address_t daddr, u16 dport, u8 protocol,
- u32 fib_index)
-{
- return f->match.daddr.as_u32 == daddr.as_u32 &&
- f->match.dport == vnet_buffer (b)->ip.reass.l4_dst_port &&
- f->match.proto == protocol && f->match.fib_index == fib_index &&
- f->match.saddr.as_u32 == saddr.as_u32 &&
- f->match.sport == vnet_buffer (b)->ip.reass.l4_src_port;
-}
-
-#endif
diff --git a/src/plugins/nat/nat44/inlines.h b/src/plugins/nat/nat44/inlines.h
deleted file mode 100644
index fde228e8b5e..00000000000
--- a/src/plugins/nat/nat44/inlines.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (c) 2020 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/**
- * @brief The NAT44 inline functions
- */
-
-#ifndef included_nat44_inlines_h__
-#define included_nat44_inlines_h__
-
-#include <vnet/fib/ip4_fib.h>
-#include <nat/nat.h>
-
-static_always_inline u8
-nat44_ed_maximum_sessions_exceeded (snat_main_t * sm,
- u32 fib_index, u32 thread_index)
-{
- u32 translations;
- translations = pool_elts (sm->per_thread_data[thread_index].sessions);
- if (vec_len (sm->max_translations_per_fib) <= fib_index)
- fib_index = 0;
- return translations >= sm->max_translations_per_fib[fib_index];
-}
-
-#endif /* included_nat44_inlines_h__ */
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/plugins/nat/nat64/nat64.api b/src/plugins/nat/nat64/nat64.api
index 5fc4129d041..21d35923148 100644
--- a/src/plugins/nat/nat64/nat64.api
+++ b/src/plugins/nat/nat64/nat64.api
@@ -16,7 +16,7 @@
option version = "1.0.0";
import "vnet/ip/ip_types.api";
import "vnet/interface_types.api";
-import "plugins/nat/nat_types.api";
+import "plugins/nat/lib/nat_types.api";
/**
* @file nat64.api
diff --git a/src/plugins/nat/nat66/nat66.api b/src/plugins/nat/nat66/nat66.api
index 6906e41f539..bbadf07184a 100644
--- a/src/plugins/nat/nat66/nat66.api
+++ b/src/plugins/nat/nat66/nat66.api
@@ -16,7 +16,7 @@
option version = "1.0.0";
import "vnet/ip/ip_types.api";
import "vnet/interface_types.api";
-import "plugins/nat/nat_types.api";
+import "plugins/nat/lib/nat_types.api";
/** \brief Enable/disable NAT66 feature on the interface
@param client_index - opaque cookie to identify the sender
diff --git a/src/plugins/nat/nat_inlines.h b/src/plugins/nat/nat_inlines.h
deleted file mode 100644
index d53e2453607..00000000000
--- a/src/plugins/nat/nat_inlines.h
+++ /dev/null
@@ -1,686 +0,0 @@
-/*
- * Copyright (c) 2018 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/**
- * @brief The NAT inline functions
- */
-
-#ifndef __included_nat_inlines_h__
-#define __included_nat_inlines_h__
-
-#include <vnet/fib/ip4_fib.h>
-#include <nat/nat.h>
-//#include <nat/nat44-ei/nat44_ei_ha.h>
-
-always_inline u64
-calc_nat_key (ip4_address_t addr, u16 port, u32 fib_index, u8 proto)
-{
- ASSERT (fib_index <= (1 << 14) - 1);
- ASSERT (proto <= (1 << 3) - 1);
- return (u64) addr.as_u32 << 32 | (u64) port << 16 | fib_index << 3 |
- (proto & 0x7);
-}
-
-always_inline void
-split_nat_key (u64 key, ip4_address_t * addr, u16 * port,
- u32 * fib_index, nat_protocol_t * proto)
-{
- if (addr)
- {
- addr->as_u32 = key >> 32;
- }
- if (port)
- {
- *port = (key >> 16) & (u16) ~ 0;
- }
- if (fib_index)
- {
- *fib_index = key >> 3 & ((1 << 13) - 1);
- }
- if (proto)
- {
- *proto = key & 0x7;
- }
-}
-
-always_inline void
-init_nat_k (clib_bihash_kv_8_8_t * kv, ip4_address_t addr, u16 port,
- u32 fib_index, nat_protocol_t proto)
-{
- kv->key = calc_nat_key (addr, port, fib_index, proto);
- kv->value = ~0ULL;
-}
-
-always_inline void
-init_nat_kv (clib_bihash_kv_8_8_t *kv, ip4_address_t addr, u16 port,
- u32 fib_index, nat_protocol_t proto, u32 thread_index,
- u32 session_index)
-{
- init_nat_k (kv, addr, port, fib_index, proto);
- kv->value = (u64) thread_index << 32 | session_index;
-}
-
-always_inline void
-init_nat_i2o_k (clib_bihash_kv_8_8_t * kv, snat_session_t * s)
-{
- return init_nat_k (kv, s->in2out.addr, s->in2out.port, s->in2out.fib_index,
- s->nat_proto);
-}
-
-always_inline void
-init_nat_i2o_kv (clib_bihash_kv_8_8_t *kv, snat_session_t *s, u32 thread_index,
- u32 session_index)
-{
- init_nat_k (kv, s->in2out.addr, s->in2out.port, s->in2out.fib_index,
- s->nat_proto);
- kv->value = (u64) thread_index << 32 | session_index;
-}
-
-always_inline void
-init_nat_o2i_k (clib_bihash_kv_8_8_t * kv, snat_session_t * s)
-{
- return init_nat_k (kv, s->out2in.addr, s->out2in.port, s->out2in.fib_index,
- s->nat_proto);
-}
-
-always_inline void
-init_nat_o2i_kv (clib_bihash_kv_8_8_t *kv, snat_session_t *s, u32 thread_index,
- u32 session_index)
-{
- init_nat_k (kv, s->out2in.addr, s->out2in.port, s->out2in.fib_index,
- s->nat_proto);
- kv->value = (u64) thread_index << 32 | session_index;
-}
-
-always_inline u32
-nat_value_get_thread_index (clib_bihash_kv_8_8_t *value)
-{
- return value->value >> 32;
-}
-
-always_inline u32
-nat_value_get_session_index (clib_bihash_kv_8_8_t *value)
-{
- return value->value & ~(u32) 0;
-}
-
-static inline uword
-nat_pre_node_fn_inline (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame, u32 def_next)
-{
- u32 n_left_from, *from;
-
- from = vlib_frame_vector_args (frame);
- n_left_from = frame->n_vectors;
-
- vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b = bufs;
- u16 nexts[VLIB_FRAME_SIZE], *next = nexts;
- vlib_get_buffers (vm, from, b, n_left_from);
-
- while (n_left_from >= 2)
- {
- u32 next0, next1;
- u32 arc_next0, arc_next1;
- vlib_buffer_t *b0, *b1;
-
- b0 = *b;
- b++;
- b1 = *b;
- b++;
-
- /* Prefetch next iteration. */
- if (PREDICT_TRUE (n_left_from >= 4))
- {
- vlib_buffer_t *p2, *p3;
-
- p2 = *b;
- p3 = *(b + 1);
-
- vlib_prefetch_buffer_header (p2, LOAD);
- vlib_prefetch_buffer_header (p3, LOAD);
-
- CLIB_PREFETCH (p2->data, CLIB_CACHE_LINE_BYTES, LOAD);
- CLIB_PREFETCH (p3->data, CLIB_CACHE_LINE_BYTES, LOAD);
- }
-
- next0 = def_next;
- next1 = def_next;
-
- vnet_feature_next (&arc_next0, b0);
- vnet_feature_next (&arc_next1, b1);
-
- vnet_buffer2 (b0)->nat.arc_next = arc_next0;
- vnet_buffer2 (b1)->nat.arc_next = arc_next1;
-
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)))
- {
- if (b0->flags & VLIB_BUFFER_IS_TRACED)
- {
- nat_pre_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t));
- t->next_index = next0;
- t->arc_next_index = arc_next0;
- }
- if (b1->flags & VLIB_BUFFER_IS_TRACED)
- {
- nat_pre_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t));
- t->next_index = next1;
- t->arc_next_index = arc_next1;
- }
- }
-
- n_left_from -= 2;
- next[0] = next0;
- next[1] = next1;
- next += 2;
- }
-
- while (n_left_from > 0)
- {
- u32 next0;
- u32 arc_next0;
- vlib_buffer_t *b0;
-
- b0 = *b;
- b++;
-
- next0 = def_next;
- vnet_feature_next (&arc_next0, b0);
- vnet_buffer2 (b0)->nat.arc_next = arc_next0;
-
- if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)
- && (b0->flags & VLIB_BUFFER_IS_TRACED)))
- {
- nat_pre_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t));
- t->next_index = next0;
- t->arc_next_index = arc_next0;
- }
-
- n_left_from--;
- next[0] = next0;
- next++;
- }
- vlib_buffer_enqueue_to_next (vm, node, from, (u16 *) nexts,
- frame->n_vectors);
-
- return frame->n_vectors;
-}
-
-always_inline u8
-is_interface_addr (snat_main_t * sm, vlib_node_runtime_t * node,
- u32 sw_if_index0, u32 ip4_addr)
-{
- snat_runtime_t *rt = (snat_runtime_t *) node->runtime_data;
- ip4_address_t *first_int_addr;
-
- if (PREDICT_FALSE (rt->cached_sw_if_index != sw_if_index0))
- {
- first_int_addr =
- ip4_interface_first_address (sm->ip4_main, sw_if_index0,
- 0 /* just want the address */ );
- rt->cached_sw_if_index = sw_if_index0;
- if (first_int_addr)
- rt->cached_ip4_address = first_int_addr->as_u32;
- else
- rt->cached_ip4_address = 0;
- }
-
- if (PREDICT_FALSE (ip4_addr == rt->cached_ip4_address))
- return 1;
- else
- return 0;
-}
-
-always_inline void
-user_session_increment (snat_main_t * sm, snat_user_t * u, u8 is_static)
-{
- if (u->nsessions + u->nstaticsessions < sm->max_translations_per_user)
- {
- if (is_static)
- u->nstaticsessions++;
- else
- u->nsessions++;
- }
-}
-
-always_inline void
-nat44_delete_user_with_no_session (snat_main_t * sm, snat_user_t * u,
- u32 thread_index)
-{
- clib_bihash_kv_8_8_t kv;
- snat_user_key_t u_key;
- snat_main_per_thread_data_t *tsm = vec_elt_at_index (sm->per_thread_data,
- thread_index);
-
- if (u->nstaticsessions == 0 && u->nsessions == 0)
- {
- u_key.addr.as_u32 = u->addr.as_u32;
- u_key.fib_index = u->fib_index;
- kv.key = u_key.as_u64;
- pool_put_index (tsm->list_pool, u->sessions_per_user_list_head_index);
- pool_put (tsm->users, u);
- clib_bihash_add_del_8_8 (&tsm->user_hash, &kv, 0);
- vlib_set_simple_counter (&sm->total_users, thread_index, 0,
- pool_elts (tsm->users));
- }
-}
-
-always_inline void
-nat44_delete_session (snat_main_t * sm, snat_session_t * ses,
- u32 thread_index)
-{
- snat_main_per_thread_data_t *tsm = vec_elt_at_index (sm->per_thread_data,
- thread_index);
- clib_bihash_kv_8_8_t kv, value;
- snat_user_t *u;
- const snat_user_key_t u_key = {
- .addr = ses->in2out.addr,
- .fib_index = ses->in2out.fib_index
- };
- const u8 u_static = snat_is_session_static (ses);
-
- clib_dlist_remove (tsm->list_pool, ses->per_user_index);
- pool_put_index (tsm->list_pool, ses->per_user_index);
- if (sm->endpoint_dependent)
- {
- clib_dlist_remove (tsm->lru_pool, ses->lru_index);
- pool_put_index (tsm->lru_pool, ses->lru_index);
- }
- pool_put (tsm->sessions, ses);
- vlib_set_simple_counter (&sm->total_sessions, thread_index, 0,
- pool_elts (tsm->sessions));
-
- kv.key = u_key.as_u64;
- if (!clib_bihash_search_8_8 (&tsm->user_hash, &kv, &value))
- {
- u = pool_elt_at_index (tsm->users, value.value);
- if (u_static)
- u->nstaticsessions--;
- else
- u->nsessions--;
-
- nat44_delete_user_with_no_session (sm, u, thread_index);
- }
-}
-
-always_inline void
-nat44_set_tcp_session_state_i2o (snat_main_t * sm, f64 now,
- snat_session_t * ses, vlib_buffer_t * b,
- u32 thread_index)
-{
- snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
- u8 tcp_flags = vnet_buffer (b)->ip.reass.icmp_type_or_tcp_flags;
- u32 tcp_ack_number = vnet_buffer (b)->ip.reass.tcp_ack_number;
- u32 tcp_seq_number = vnet_buffer (b)->ip.reass.tcp_seq_number;
- if ((ses->state == 0) && (tcp_flags & TCP_FLAG_RST))
- ses->state = NAT44_SES_RST;
- if ((ses->state == NAT44_SES_RST) && !(tcp_flags & TCP_FLAG_RST))
- ses->state = 0;
- if ((tcp_flags & TCP_FLAG_ACK) && (ses->state & NAT44_SES_I2O_SYN) &&
- (ses->state & NAT44_SES_O2I_SYN))
- ses->state = 0;
- if (tcp_flags & TCP_FLAG_SYN)
- ses->state |= NAT44_SES_I2O_SYN;
- if (tcp_flags & TCP_FLAG_FIN)
- {
- ses->i2o_fin_seq = clib_net_to_host_u32 (tcp_seq_number);
- ses->state |= NAT44_SES_I2O_FIN;
- }
- if ((tcp_flags & TCP_FLAG_ACK) && (ses->state & NAT44_SES_O2I_FIN))
- {
- if (clib_net_to_host_u32 (tcp_ack_number) > ses->o2i_fin_seq)
- {
- ses->state |= NAT44_SES_O2I_FIN_ACK;
- if (nat44_is_ses_closed (ses))
- { // if session is now closed, save the timestamp
- ses->tcp_closed_timestamp = now + sm->timeouts.tcp.transitory;
- ses->last_lru_update = now;
- }
- }
- }
-
- // move the session to proper LRU
- if (ses->state)
- {
- ses->lru_head_index = tsm->tcp_trans_lru_head_index;
- }
- else
- {
- ses->lru_head_index = tsm->tcp_estab_lru_head_index;
- }
- clib_dlist_remove (tsm->lru_pool, ses->lru_index);
- clib_dlist_addtail (tsm->lru_pool, ses->lru_head_index, ses->lru_index);
-}
-
-always_inline void
-nat44_set_tcp_session_state_o2i (snat_main_t * sm, f64 now,
- snat_session_t * ses, u8 tcp_flags,
- u32 tcp_ack_number, u32 tcp_seq_number,
- u32 thread_index)
-{
- snat_main_per_thread_data_t *tsm = &sm->per_thread_data[thread_index];
- if ((ses->state == 0) && (tcp_flags & TCP_FLAG_RST))
- ses->state = NAT44_SES_RST;
- if ((ses->state == NAT44_SES_RST) && !(tcp_flags & TCP_FLAG_RST))
- ses->state = 0;
- if ((tcp_flags & TCP_FLAG_ACK) && (ses->state & NAT44_SES_I2O_SYN) &&
- (ses->state & NAT44_SES_O2I_SYN))
- ses->state = 0;
- if (tcp_flags & TCP_FLAG_SYN)
- ses->state |= NAT44_SES_O2I_SYN;
- if (tcp_flags & TCP_FLAG_FIN)
- {
- ses->o2i_fin_seq = clib_net_to_host_u32 (tcp_seq_number);
- ses->state |= NAT44_SES_O2I_FIN;
- }
- if ((tcp_flags & TCP_FLAG_ACK) && (ses->state & NAT44_SES_I2O_FIN))
- {
- if (clib_net_to_host_u32 (tcp_ack_number) > ses->i2o_fin_seq)
- ses->state |= NAT44_SES_I2O_FIN_ACK;
- if (nat44_is_ses_closed (ses))
- { // if session is now closed, save the timestamp
- ses->tcp_closed_timestamp = now + sm->timeouts.tcp.transitory;
- ses->last_lru_update = now;
- }
- }
- // move the session to proper LRU
- if (ses->state)
- {
- ses->lru_head_index = tsm->tcp_trans_lru_head_index;
- }
- else
- {
- ses->lru_head_index = tsm->tcp_estab_lru_head_index;
- }
- clib_dlist_remove (tsm->lru_pool, ses->lru_index);
- clib_dlist_addtail (tsm->lru_pool, ses->lru_head_index, ses->lru_index);
-}
-
-always_inline u32
-nat44_session_get_timeout (snat_main_t * sm, snat_session_t * s)
-{
- switch (s->nat_proto)
- {
- case NAT_PROTOCOL_ICMP:
- return sm->timeouts.icmp;
- case NAT_PROTOCOL_UDP:
- return sm->timeouts.udp;
- case NAT_PROTOCOL_TCP:
- {
- if (s->state)
- return sm->timeouts.tcp.transitory;
- else
- return sm->timeouts.tcp.established;
- }
- default:
- return sm->timeouts.udp;
- }
-
- return 0;
-}
-
-always_inline void
-nat44_session_update_counters (snat_session_t * s, f64 now, uword bytes,
- u32 thread_index)
-{
- s->last_heard = now;
- s->total_pkts++;
- s->total_bytes += bytes;
-#if 0
- nat_ha_sref (&s->out2in.addr, s->out2in.port, &s->ext_host_addr,
- s->ext_host_port, s->nat_proto, s->out2in.fib_index,
- s->total_pkts, s->total_bytes, thread_index,
- &s->ha_last_refreshed, now);
-#endif
-}
-
-/** \brief Per-user LRU list maintenance */
-always_inline void
-nat44_session_update_lru (snat_main_t * sm, snat_session_t * s,
- u32 thread_index)
-{
- /* don't update too often - timeout is in magnitude of seconds anyway */
- if (s->last_heard > s->last_lru_update + 1)
- {
- if (!sm->endpoint_dependent)
- {
- clib_dlist_remove (sm->per_thread_data[thread_index].list_pool,
- s->per_user_index);
- clib_dlist_addtail (sm->per_thread_data[thread_index].list_pool,
- s->per_user_list_head_index, s->per_user_index);
- }
- else
- {
- clib_dlist_remove (sm->per_thread_data[thread_index].lru_pool,
- s->lru_index);
- clib_dlist_addtail (sm->per_thread_data[thread_index].lru_pool,
- s->lru_head_index, s->lru_index);
- }
- s->last_lru_update = s->last_heard;
- }
-}
-
-always_inline void
-init_ed_k (clib_bihash_kv_16_8_t * kv, ip4_address_t l_addr, u16 l_port,
- ip4_address_t r_addr, u16 r_port, u32 fib_index, u8 proto)
-{
- kv->key[0] = (u64) r_addr.as_u32 << 32 | l_addr.as_u32;
- kv->key[1] =
- (u64) r_port << 48 | (u64) l_port << 32 | fib_index << 8 | proto;
-}
-
-always_inline void
-init_ed_kv (clib_bihash_kv_16_8_t * kv, ip4_address_t l_addr, u16 l_port,
- ip4_address_t r_addr, u16 r_port, u32 fib_index, u8 proto,
- u32 thread_index, u32 session_index)
-{
- init_ed_k (kv, l_addr, l_port, r_addr, r_port, fib_index, proto);
- kv->value = (u64) thread_index << 32 | session_index;
-}
-
-always_inline u32
-ed_value_get_thread_index (clib_bihash_kv_16_8_t * value)
-{
- return value->value >> 32;
-}
-
-always_inline u32
-ed_value_get_session_index (clib_bihash_kv_16_8_t * value)
-{
- return value->value & ~(u32) 0;
-}
-
-always_inline void
-split_ed_kv (clib_bihash_kv_16_8_t * kv,
- ip4_address_t * l_addr, ip4_address_t * r_addr, u8 * proto,
- u32 * fib_index, u16 * l_port, u16 * r_port)
-{
- if (l_addr)
- {
- l_addr->as_u32 = kv->key[0] & (u32) ~ 0;
- }
- if (r_addr)
- {
- r_addr->as_u32 = kv->key[0] >> 32;
- }
- if (r_port)
- {
- *r_port = kv->key[1] >> 48;
- }
- if (l_port)
- {
- *l_port = (kv->key[1] >> 32) & (u16) ~ 0;
- }
- if (fib_index)
- {
- *fib_index = (kv->key[1] >> 8) & ((1 << 24) - 1);
- }
- if (proto)
- {
- *proto = kv->key[1] & (u8) ~ 0;
- }
-}
-
-static_always_inline int
-nat_get_icmp_session_lookup_values (vlib_buffer_t *b, ip4_header_t *ip0,
- ip4_address_t *lookup_saddr,
- u16 *lookup_sport,
- ip4_address_t *lookup_daddr,
- u16 *lookup_dport, u8 *lookup_protocol)
-{
- icmp46_header_t *icmp0;
- icmp_echo_header_t *echo0, *inner_echo0 = 0;
- ip4_header_t *inner_ip0 = 0;
- void *l4_header = 0;
- icmp46_header_t *inner_icmp0;
-
- icmp0 = (icmp46_header_t *) ip4_next_header (ip0);
- echo0 = (icmp_echo_header_t *) (icmp0 + 1);
-
- // avoid warning about unused variables in caller by setting to bogus values
- *lookup_sport = 0;
- *lookup_dport = 0;
-
- if (!icmp_type_is_error_message
- (vnet_buffer (b)->ip.reass.icmp_type_or_tcp_flags))
- {
- *lookup_protocol = IP_PROTOCOL_ICMP;
- lookup_saddr->as_u32 = ip0->src_address.as_u32;
- *lookup_sport = vnet_buffer (b)->ip.reass.l4_src_port;
- lookup_daddr->as_u32 = ip0->dst_address.as_u32;
- *lookup_dport = vnet_buffer (b)->ip.reass.l4_dst_port;
- }
- else
- {
- inner_ip0 = (ip4_header_t *) (echo0 + 1);
- l4_header = ip4_next_header (inner_ip0);
- *lookup_protocol = inner_ip0->protocol;
- lookup_saddr->as_u32 = inner_ip0->dst_address.as_u32;
- lookup_daddr->as_u32 = inner_ip0->src_address.as_u32;
- switch (ip_proto_to_nat_proto (inner_ip0->protocol))
- {
- case NAT_PROTOCOL_ICMP:
- inner_icmp0 = (icmp46_header_t *) l4_header;
- inner_echo0 = (icmp_echo_header_t *) (inner_icmp0 + 1);
- *lookup_sport = inner_echo0->identifier;
- *lookup_dport = inner_echo0->identifier;
- break;
- case NAT_PROTOCOL_UDP:
- case NAT_PROTOCOL_TCP:
- *lookup_sport = ((tcp_udp_header_t *) l4_header)->dst_port;
- *lookup_dport = ((tcp_udp_header_t *) l4_header)->src_port;
- break;
- default:
- return NAT_IN2OUT_ED_ERROR_UNSUPPORTED_PROTOCOL;
- }
- }
- return 0;
-}
-
-/**
- * @brief Check if packet should be translated
- *
- * Packets aimed at outside interface and external address with active session
- * should be translated.
- *
- * @param sm NAT main
- * @param rt NAT runtime data
- * @param sw_if_index0 index of the inside interface
- * @param ip0 IPv4 header
- * @param proto0 NAT protocol
- * @param rx_fib_index0 RX FIB index
- *
- * @returns 0 if packet should be translated otherwise 1
- */
-static inline int
-snat_not_translate_fast (snat_main_t * sm, vlib_node_runtime_t * node,
- u32 sw_if_index0, ip4_header_t * ip0, u32 proto0,
- u32 rx_fib_index0)
-{
- if (sm->out2in_dpo)
- return 0;
-
- fib_node_index_t fei = FIB_NODE_INDEX_INVALID;
- nat_outside_fib_t *outside_fib;
- fib_prefix_t pfx = {
- .fp_proto = FIB_PROTOCOL_IP4,
- .fp_len = 32,
- .fp_addr = {
- .ip4.as_u32 = ip0->dst_address.as_u32,
- }
- ,
- };
-
- /* Don't NAT packet aimed at the intfc address */
- if (PREDICT_FALSE (is_interface_addr (sm, node, sw_if_index0,
- ip0->dst_address.as_u32)))
- return 1;
-
- fei = fib_table_lookup (rx_fib_index0, &pfx);
- if (FIB_NODE_INDEX_INVALID != fei)
- {
- u32 sw_if_index = fib_entry_get_resolving_interface (fei);
- if (sw_if_index == ~0)
- {
- vec_foreach (outside_fib, sm->outside_fibs)
- {
- fei = fib_table_lookup (outside_fib->fib_index, &pfx);
- if (FIB_NODE_INDEX_INVALID != fei)
- {
- sw_if_index = fib_entry_get_resolving_interface (fei);
- if (sw_if_index != ~0)
- break;
- }
- }
- }
- if (sw_if_index == ~0)
- return 1;
-
- snat_interface_t *i;
- /* *INDENT-OFF* */
- pool_foreach (i, sm->interfaces) {
- /* NAT packet aimed at outside interface */
- if ((nat_interface_is_outside (i)) && (sw_if_index == i->sw_if_index))
- return 0;
- }
- /* *INDENT-ON* */
- }
-
- return 1;
-}
-
-static_always_inline u16
-snat_random_port (u16 min, u16 max)
-{
- snat_main_t *sm = &snat_main;
- u32 rwide;
- u16 r;
-
- rwide = random_u32 (&sm->random_seed);
- r = rwide & 0xFFFF;
- if (r >= min && r <= max)
- return r;
-
- return min + (rwide % (max - min + 1));
-}
-
-#endif /* __included_nat_inlines_h__ */
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/plugins/nat/test/test_nat44_ed.py b/src/plugins/nat/test/test_nat44_ed.py
index 5133ae3c8ea..3980f69c5bb 100644
--- a/src/plugins/nat/test/test_nat44_ed.py
+++ b/src/plugins/nat/test/test_nat44_ed.py
@@ -48,7 +48,6 @@ class NAT44EDTestCase(VppTestCase):
def plugin_enable(self):
self.vapi.nat44_plugin_enable_disable(
- flags=self.nat44_config_flags.NAT44_IS_ENDPOINT_DEPENDENT,
sessions=self.max_sessions, enable=1)
def plugin_disable(self):
@@ -150,7 +149,6 @@ class NAT44EDTestCase(VppTestCase):
@classmethod
def setUpClass(cls):
super(NAT44EDTestCase, cls).setUpClass()
- cls.vapi.cli("set log class nat level debug")
cls.create_pg_interfaces(range(12))
cls.interfaces = list(cls.pg_interfaces[:4])
@@ -874,7 +872,7 @@ class NAT44EDTestCase(VppTestCase):
self.config_flags.NAT_IS_EXT_HOST_VALID)
self.assertTrue(sessions[0].flags &
self.config_flags.NAT_IS_TWICE_NAT)
- self.logger.info(self.vapi.cli("show nat44 sessions detail"))
+ self.logger.info(self.vapi.cli("show nat44 sessions"))
self.vapi.nat44_del_session(
address=sessions[0].inside_ip_address,
port=sessions[0].inside_port,
@@ -1978,10 +1976,10 @@ class TestNAT44EDMW(TestNAT44ED):
self.nat_add_outside_interface(self.pg1)
# in2out
- tc1 = self.get_stats_counter('/nat44/ed/in2out/slowpath/tcp')
- uc1 = self.get_stats_counter('/nat44/ed/in2out/slowpath/udp')
- ic1 = self.get_stats_counter('/nat44/ed/in2out/slowpath/icmp')
- dc1 = self.get_stats_counter('/nat44/ed/in2out/slowpath/drops')
+ tc1 = self.get_stats_counter('/nat44-ed/in2out/slowpath/tcp')
+ uc1 = self.get_stats_counter('/nat44-ed/in2out/slowpath/udp')
+ ic1 = self.get_stats_counter('/nat44-ed/in2out/slowpath/icmp')
+ dc1 = self.get_stats_counter('/nat44-ed/in2out/slowpath/drops')
pkts = self.create_stream_in(self.pg0, self.pg1)
# TODO: specify worker=idx, also stats have to
@@ -1993,10 +1991,10 @@ class TestNAT44EDMW(TestNAT44ED):
self.verify_capture_out(capture, ignore_port=True)
if_idx = self.pg0.sw_if_index
- tc2 = self.get_stats_counter('/nat44/ed/in2out/slowpath/tcp')
- uc2 = self.get_stats_counter('/nat44/ed/in2out/slowpath/udp')
- ic2 = self.get_stats_counter('/nat44/ed/in2out/slowpath/icmp')
- dc2 = self.get_stats_counter('/nat44/ed/in2out/slowpath/drops')
+ tc2 = self.get_stats_counter('/nat44-ed/in2out/slowpath/tcp')
+ uc2 = self.get_stats_counter('/nat44-ed/in2out/slowpath/udp')
+ ic2 = self.get_stats_counter('/nat44-ed/in2out/slowpath/icmp')
+ dc2 = self.get_stats_counter('/nat44-ed/in2out/slowpath/drops')
self.assertEqual(tc2[if_idx] - tc1[if_idx], 2)
self.assertEqual(uc2[if_idx] - uc1[if_idx], 1)
@@ -2004,10 +2002,10 @@ class TestNAT44EDMW(TestNAT44ED):
self.assertEqual(dc2[if_idx] - dc1[if_idx], 0)
# out2in
- tc1 = self.get_stats_counter('/nat44/ed/out2in/fastpath/tcp')
- uc1 = self.get_stats_counter('/nat44/ed/out2in/fastpath/udp')
- ic1 = self.get_stats_counter('/nat44/ed/out2in/fastpath/icmp')
- dc1 = self.get_stats_counter('/nat44/ed/out2in/fastpath/drops')
+ tc1 = self.get_stats_counter('/nat44-ed/out2in/fastpath/tcp')
+ uc1 = self.get_stats_counter('/nat44-ed/out2in/fastpath/udp')
+ ic1 = self.get_stats_counter('/nat44-ed/out2in/fastpath/icmp')
+ dc1 = self.get_stats_counter('/nat44-ed/out2in/fastpath/drops')
pkts = self.create_stream_out(self.pg1)
self.pg1.add_stream(pkts)
@@ -2017,17 +2015,17 @@ class TestNAT44EDMW(TestNAT44ED):
self.verify_capture_in(capture, self.pg0)
if_idx = self.pg1.sw_if_index
- tc2 = self.get_stats_counter('/nat44/ed/out2in/fastpath/tcp')
- uc2 = self.get_stats_counter('/nat44/ed/out2in/fastpath/udp')
- ic2 = self.get_stats_counter('/nat44/ed/out2in/fastpath/icmp')
- dc2 = self.get_stats_counter('/nat44/ed/out2in/fastpath/drops')
+ tc2 = self.get_stats_counter('/nat44-ed/out2in/fastpath/tcp')
+ uc2 = self.get_stats_counter('/nat44-ed/out2in/fastpath/udp')
+ ic2 = self.get_stats_counter('/nat44-ed/out2in/fastpath/icmp')
+ dc2 = self.get_stats_counter('/nat44-ed/out2in/fastpath/drops')
self.assertEqual(tc2[if_idx] - tc1[if_idx], 2)
self.assertEqual(uc2[if_idx] - uc1[if_idx], 1)
self.assertEqual(ic2[if_idx] - ic1[if_idx], 1)
self.assertEqual(dc2[if_idx] - dc1[if_idx], 0)
- sc = self.get_stats_counter('/nat44/total-sessions')
+ sc = self.get_stats_counter('/nat44-ed/total-sessions')
self.assertEqual(sc[0], 3)
def test_frag_in_order(self):
@@ -2221,28 +2219,6 @@ class TestNAT44EDMW(TestNAT44ED):
capture = outside.get_capture(len(stream))
- def test_clear_sessions(self):
- """ NAT44ED session clearing test """
-
- self.nat_add_address(self.nat_addr)
- self.nat_add_inside_interface(self.pg0)
- self.nat_add_outside_interface(self.pg1)
-
- pkts = self.create_stream_in(self.pg0, self.pg1)
- self.pg0.add_stream(pkts)
- self.pg_enable_capture(self.pg_interfaces)
- self.pg_start()
- capture = self.pg1.get_capture(len(pkts))
- self.verify_capture_out(capture, ignore_port=True)
-
- sessions = self.get_stats_counter('/nat44/total-sessions')
- self.assertTrue(sessions[0] > 0)
-
- self.vapi.cli("clear nat44 sessions")
-
- sessions = self.get_stats_counter('/nat44/total-sessions')
- self.assertEqual(sessions[0], 0)
-
def test_show_max_translations(self):
""" NAT44ED API test - max translations per thread """
nat_config = self.vapi.nat_show_config_2()
@@ -3331,13 +3307,13 @@ class TestNAT44EDMW(TestNAT44ED):
# in2out
tcpn = self.get_stats_counter(
- '/nat44/ed/in2out/slowpath/tcp')
+ '/nat44-ed/in2out/slowpath/tcp')
udpn = self.get_stats_counter(
- '/nat44/ed/in2out/slowpath/udp')
+ '/nat44-ed/in2out/slowpath/udp')
icmpn = self.get_stats_counter(
- '/nat44/ed/in2out/slowpath/icmp')
+ '/nat44-ed/in2out/slowpath/icmp')
drops = self.get_stats_counter(
- '/nat44/ed/in2out/slowpath/drops')
+ '/nat44-ed/in2out/slowpath/drops')
pkts = self.create_stream_in(self.pg7, self.pg8)
self.pg7.add_stream(pkts)
@@ -3348,27 +3324,27 @@ class TestNAT44EDMW(TestNAT44ED):
if_idx = self.pg7.sw_if_index
cnt = self.get_stats_counter(
- '/nat44/ed/in2out/slowpath/tcp')
+ '/nat44-ed/in2out/slowpath/tcp')
self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
cnt = self.get_stats_counter(
- '/nat44/ed/in2out/slowpath/udp')
+ '/nat44-ed/in2out/slowpath/udp')
self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
cnt = self.get_stats_counter(
- '/nat44/ed/in2out/slowpath/icmp')
+ '/nat44-ed/in2out/slowpath/icmp')
self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
cnt = self.get_stats_counter(
- '/nat44/ed/in2out/slowpath/drops')
+ '/nat44-ed/in2out/slowpath/drops')
self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
# out2in
tcpn = self.get_stats_counter(
- '/nat44/ed/out2in/fastpath/tcp')
+ '/nat44-ed/out2in/fastpath/tcp')
udpn = self.get_stats_counter(
- '/nat44/ed/out2in/fastpath/udp')
+ '/nat44-ed/out2in/fastpath/udp')
icmpn = self.get_stats_counter(
- '/nat44/ed/out2in/fastpath/icmp')
+ '/nat44-ed/out2in/fastpath/icmp')
drops = self.get_stats_counter(
- '/nat44/ed/out2in/fastpath/drops')
+ '/nat44-ed/out2in/fastpath/drops')
pkts = self.create_stream_out(self.pg8)
self.pg8.add_stream(pkts)
@@ -3379,19 +3355,19 @@ class TestNAT44EDMW(TestNAT44ED):
if_idx = self.pg8.sw_if_index
cnt = self.get_stats_counter(
- '/nat44/ed/out2in/fastpath/tcp')
+ '/nat44-ed/out2in/fastpath/tcp')
self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
cnt = self.get_stats_counter(
- '/nat44/ed/out2in/fastpath/udp')
+ '/nat44-ed/out2in/fastpath/udp')
self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
cnt = self.get_stats_counter(
- '/nat44/ed/out2in/fastpath/icmp')
+ '/nat44-ed/out2in/fastpath/icmp')
self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
cnt = self.get_stats_counter(
- '/nat44/ed/out2in/fastpath/drops')
+ '/nat44-ed/out2in/fastpath/drops')
self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
- sessions = self.get_stats_counter('/nat44/total-sessions')
+ sessions = self.get_stats_counter('/nat44-ed/total-sessions')
self.assertEqual(sessions[0], 3)
finally:
diff --git a/src/plugins/nat/test/test_nat44_ei.py b/src/plugins/nat/test/test_nat44_ei.py
index 999f91ecda8..da6ca4293c0 100644
--- a/src/plugins/nat/test/test_nat44_ei.py
+++ b/src/plugins/nat/test/test_nat44_ei.py
@@ -70,11 +70,7 @@ class MethodHolder(VppTestCase):
@property
def config_flags(self):
- return VppEnum.vl_api_nat_config_flags_t
-
- @property
- def nat44_config_flags(self):
- return VppEnum.vl_api_nat44_config_flags_t
+ return VppEnum.vl_api_nat44_ei_config_flags_t
@property
def SYSLOG_SEVERITY(self):
@@ -100,9 +96,9 @@ class MethodHolder(VppTestCase):
"""
if not (local_port and external_port):
- flags |= self.config_flags.NAT_IS_ADDR_ONLY
+ flags |= self.config_flags.NAT44_EI_ADDR_ONLY_MAPPING
- self.vapi.nat44_add_del_static_mapping(
+ self.vapi.nat44_ei_add_del_static_mapping(
is_add=is_add,
local_ip_address=local_ip,
external_ip_address=external_ip,
@@ -113,20 +109,17 @@ class MethodHolder(VppTestCase):
flags=flags,
tag=tag)
- def nat44_add_address(self, ip, is_add=1, vrf_id=0xFFFFFFFF, twice_nat=0):
+ def nat44_add_address(self, ip, is_add=1, vrf_id=0xFFFFFFFF):
"""
Add/delete NAT44EI address
:param ip: IP address
:param is_add: 1 if add, 0 if delete (Default add)
- :param twice_nat: twice NAT address for external hosts
"""
- flags = self.config_flags.NAT_IS_TWICE_NAT if twice_nat else 0
- self.vapi.nat44_add_del_address_range(first_ip_address=ip,
- last_ip_address=ip,
- vrf_id=vrf_id,
- is_add=is_add,
- flags=flags)
+ self.vapi.nat44_ei_add_del_address_range(first_ip_address=ip,
+ last_ip_address=ip,
+ vrf_id=vrf_id,
+ is_add=is_add)
def create_routes_and_neigbors(self):
r1 = VppIpRoute(self, self.pg7.remote_ip4, 32,
@@ -637,11 +630,11 @@ class MethodHolder(VppTestCase):
def verify_no_nat44_user(self):
""" Verify that there is no NAT44EI user """
- users = self.vapi.nat44_user_dump()
+ users = self.vapi.nat44_ei_user_dump()
self.assertEqual(len(users), 0)
- users = self.statistics.get_counter('/nat44/total-users')
+ users = self.statistics.get_counter('/nat44-ei/total-users')
self.assertEqual(users[0][0], 0)
- sessions = self.statistics.get_counter('/nat44/total-sessions')
+ sessions = self.statistics.get_counter('/nat44-ei/total-sessions')
self.assertEqual(sessions[0][0], 0)
def verify_syslog_apmap(self, data, is_add=True):
@@ -859,33 +852,6 @@ class MethodHolder(VppTestCase):
self.assertEqual(data, p[Raw].load)
-class TestNAT44EIAPI(MethodHolder):
- """ NAT44EI API Test Cases """
-
- fq_nelts = 512
-
- def setUp(self):
- super(TestNAT44EIAPI, self).setUp()
- self.vapi.nat_set_fq_options(frame_queue_nelts=self.fq_nelts)
- self.vapi.nat44_plugin_enable_disable(enable=1)
-
- def tearDown(self):
- super(TestNAT44EIAPI, self).tearDown()
- if not self.vpp_dead:
- self.vapi.nat44_plugin_enable_disable(enable=0)
- self.vapi.cli("clear logging")
-
- def test_show_frame_queue_nelts(self):
- """ API test - worker handoff frame queue elements """
- nat_config = self.vapi.nat_show_fq_options()
- self.assertEqual(self.fq_nelts, nat_config.frame_queue_nelts)
- self.vapi.nat44_plugin_enable_disable(enable=0)
- self.vapi.cli("set nat frame-queue-nelts 256")
- self.vapi.nat44_plugin_enable_disable(enable=1)
- nat_config = self.vapi.nat_show_fq_options()
- self.assertEqual(256, nat_config.frame_queue_nelts)
-
-
@tag_fixme_vpp_workers
class TestNAT44EI(MethodHolder):
""" NAT44EI Test Cases """
@@ -896,7 +862,7 @@ class TestNAT44EI(MethodHolder):
@classmethod
def setUpClass(cls):
super(TestNAT44EI, cls).setUpClass()
- cls.vapi.cli("set log class nat level debug")
+ cls.vapi.cli("set log class nat44-ei level debug")
cls.tcp_port_in = 6303
cls.tcp_port_out = 6303
@@ -957,39 +923,39 @@ class TestNAT44EI(MethodHolder):
cls.pg4._remote_ip4 = cls.pg9._remote_hosts[0]._ip4 = "10.0.0.2"
cls.pg9.resolve_arp()
- def setUp(self):
- super(TestNAT44EI, self).setUp()
- self.vapi.nat44_plugin_enable_disable(
+ def plugin_enable(self):
+ self.vapi.nat44_ei_plugin_enable_disable(
sessions=self.max_translations,
users=self.max_users, enable=1)
+ def setUp(self):
+ super(TestNAT44EI, self).setUp()
+ self.plugin_enable()
+
def tearDown(self):
super(TestNAT44EI, self).tearDown()
if not self.vpp_dead:
- self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
- src_port=self.ipfix_src_port,
- enable=0)
+ self.vapi.nat44_ei_ipfix_enable_disable(
+ domain_id=self.ipfix_domain_id, src_port=self.ipfix_src_port,
+ enable=0)
self.ipfix_src_port = 4739
self.ipfix_domain_id = 1
- self.vapi.nat44_plugin_enable_disable(enable=0)
+ self.vapi.nat44_ei_plugin_enable_disable(enable=0)
self.vapi.cli("clear logging")
def test_clear_sessions(self):
""" NAT44EI session clearing test """
self.nat44_add_address(self.nat_addr)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
- nat_config = self.vapi.nat_show_config()
- self.assertEqual(0, nat_config.endpoint_dependent)
-
pkts = self.create_stream_in(self.pg0, self.pg1)
self.pg0.add_stream(pkts)
self.pg_enable_capture(self.pg_interfaces)
@@ -997,32 +963,34 @@ class TestNAT44EI(MethodHolder):
capture = self.pg1.get_capture(len(pkts))
self.verify_capture_out(capture)
- sessions = self.statistics.get_counter('/nat44/total-sessions')
+ sessions = self.statistics.get_counter('/nat44-ei/total-sessions')
self.assertTrue(sessions[0][0] > 0)
self.logger.info("sessions before clearing: %s" % sessions[0][0])
- self.vapi.cli("clear nat44 sessions")
+ self.vapi.cli("clear nat44 ei sessions")
- sessions = self.statistics.get_counter('/nat44/total-sessions')
+ sessions = self.statistics.get_counter('/nat44-ei/total-sessions')
self.assertEqual(sessions[0][0], 0)
self.logger.info("sessions after clearing: %s" % sessions[0][0])
def test_dynamic(self):
""" NAT44EI dynamic translation test """
self.nat44_add_address(self.nat_addr)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
# in2out
- tcpn = self.statistics.get_counter('/nat44/in2out/slowpath/tcp')[0]
- udpn = self.statistics.get_counter('/nat44/in2out/slowpath/udp')[0]
- icmpn = self.statistics.get_counter('/nat44/in2out/slowpath/icmp')[0]
- drops = self.statistics.get_counter('/nat44/in2out/slowpath/drops')[0]
+ tcpn = self.statistics.get_counter('/nat44-ei/in2out/slowpath/tcp')[0]
+ udpn = self.statistics.get_counter('/nat44-ei/in2out/slowpath/udp')[0]
+ icmpn = self.statistics.get_counter(
+ '/nat44-ei/in2out/slowpath/icmp')[0]
+ drops = self.statistics.get_counter(
+ '/nat44-ei/in2out/slowpath/drops')[0]
pkts = self.create_stream_in(self.pg0, self.pg1)
self.pg0.add_stream(pkts)
@@ -1032,20 +1000,22 @@ class TestNAT44EI(MethodHolder):
self.verify_capture_out(capture)
if_idx = self.pg0.sw_if_index
- cnt = self.statistics.get_counter('/nat44/in2out/slowpath/tcp')[0]
+ cnt = self.statistics.get_counter('/nat44-ei/in2out/slowpath/tcp')[0]
self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
- cnt = self.statistics.get_counter('/nat44/in2out/slowpath/udp')[0]
+ cnt = self.statistics.get_counter('/nat44-ei/in2out/slowpath/udp')[0]
self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
- cnt = self.statistics.get_counter('/nat44/in2out/slowpath/icmp')[0]
+ cnt = self.statistics.get_counter('/nat44-ei/in2out/slowpath/icmp')[0]
self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
- cnt = self.statistics.get_counter('/nat44/in2out/slowpath/drops')[0]
+ cnt = self.statistics.get_counter('/nat44-ei/in2out/slowpath/drops')[0]
self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
# out2in
- tcpn = self.statistics.get_counter('/nat44/out2in/slowpath/tcp')[0]
- udpn = self.statistics.get_counter('/nat44/out2in/slowpath/udp')[0]
- icmpn = self.statistics.get_counter('/nat44/out2in/slowpath/icmp')[0]
- drops = self.statistics.get_counter('/nat44/out2in/slowpath/drops')[0]
+ tcpn = self.statistics.get_counter('/nat44-ei/out2in/slowpath/tcp')[0]
+ udpn = self.statistics.get_counter('/nat44-ei/out2in/slowpath/udp')[0]
+ icmpn = self.statistics.get_counter(
+ '/nat44-ei/out2in/slowpath/icmp')[0]
+ drops = self.statistics.get_counter(
+ '/nat44-ei/out2in/slowpath/drops')[0]
pkts = self.create_stream_out(self.pg1)
self.pg1.add_stream(pkts)
@@ -1055,29 +1025,29 @@ class TestNAT44EI(MethodHolder):
self.verify_capture_in(capture, self.pg0)
if_idx = self.pg1.sw_if_index
- cnt = self.statistics.get_counter('/nat44/out2in/slowpath/tcp')[0]
+ cnt = self.statistics.get_counter('/nat44-ei/out2in/slowpath/tcp')[0]
self.assertEqual(cnt[if_idx] - tcpn[if_idx], 2)
- cnt = self.statistics.get_counter('/nat44/out2in/slowpath/udp')[0]
+ cnt = self.statistics.get_counter('/nat44-ei/out2in/slowpath/udp')[0]
self.assertEqual(cnt[if_idx] - udpn[if_idx], 1)
- cnt = self.statistics.get_counter('/nat44/out2in/slowpath/icmp')[0]
+ cnt = self.statistics.get_counter('/nat44-ei/out2in/slowpath/icmp')[0]
self.assertEqual(cnt[if_idx] - icmpn[if_idx], 1)
- cnt = self.statistics.get_counter('/nat44/out2in/slowpath/drops')[0]
+ cnt = self.statistics.get_counter('/nat44-ei/out2in/slowpath/drops')[0]
self.assertEqual(cnt[if_idx] - drops[if_idx], 0)
- users = self.statistics.get_counter('/nat44/total-users')
+ users = self.statistics.get_counter('/nat44-ei/total-users')
self.assertEqual(users[0][0], 1)
- sessions = self.statistics.get_counter('/nat44/total-sessions')
+ sessions = self.statistics.get_counter('/nat44-ei/total-sessions')
self.assertEqual(sessions[0][0], 3)
def test_dynamic_icmp_errors_in2out_ttl_1(self):
""" NAT44EI handling of client packets with TTL=1 """
self.nat44_add_address(self.nat_addr)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
@@ -1095,11 +1065,11 @@ class TestNAT44EI(MethodHolder):
""" NAT44EI handling of server packets with TTL=1 """
self.nat44_add_address(self.nat_addr)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
@@ -1127,11 +1097,11 @@ class TestNAT44EI(MethodHolder):
"""
self.nat44_add_address(self.nat_addr)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
@@ -1159,11 +1129,11 @@ class TestNAT44EI(MethodHolder):
"""
self.nat44_add_address(self.nat_addr)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
@@ -1198,11 +1168,11 @@ class TestNAT44EI(MethodHolder):
""" NAT44EI ping out interface from outside network """
self.nat44_add_address(self.nat_addr)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
@@ -1229,11 +1199,11 @@ class TestNAT44EI(MethodHolder):
""" NAT44EI ping internal host from outside network """
self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
@@ -1262,23 +1232,23 @@ class TestNAT44EI(MethodHolder):
def test_forwarding(self):
""" NAT44EI forwarding test """
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
- self.vapi.nat44_forwarding_enable_disable(enable=1)
+ self.vapi.nat44_ei_forwarding_enable_disable(enable=1)
real_ip = self.pg0.remote_ip4
alias_ip = self.nat_addr
- flags = self.config_flags.NAT_IS_ADDR_ONLY
- self.vapi.nat44_add_del_static_mapping(is_add=1,
- local_ip_address=real_ip,
- external_ip_address=alias_ip,
- external_sw_if_index=0xFFFFFFFF,
- flags=flags)
+ flags = self.config_flags.NAT44_EI_ADDR_ONLY_MAPPING
+ self.vapi.nat44_ei_add_del_static_mapping(
+ is_add=1, local_ip_address=real_ip,
+ external_ip_address=alias_ip,
+ external_sw_if_index=0xFFFFFFFF,
+ flags=flags)
try:
# static mapping match
@@ -1322,9 +1292,9 @@ class TestNAT44EI(MethodHolder):
self.pg0.remote_hosts[0] = host0
finally:
- self.vapi.nat44_forwarding_enable_disable(enable=0)
- flags = self.config_flags.NAT_IS_ADDR_ONLY
- self.vapi.nat44_add_del_static_mapping(
+ self.vapi.nat44_ei_forwarding_enable_disable(enable=0)
+ flags = self.config_flags.NAT44_EI_ADDR_ONLY_MAPPING
+ self.vapi.nat44_ei_add_del_static_mapping(
is_add=0,
local_ip_address=real_ip,
external_ip_address=alias_ip,
@@ -1340,14 +1310,14 @@ class TestNAT44EI(MethodHolder):
self.icmp_id_out = 6305
self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
- sm = self.vapi.nat44_static_mapping_dump()
+ sm = self.vapi.nat44_ei_static_mapping_dump()
self.assertEqual(len(sm), 1)
self.assertEqual(sm[0].tag, '')
self.assertEqual(sm[0].protocol, 0)
@@ -1380,14 +1350,14 @@ class TestNAT44EI(MethodHolder):
tag = "testTAG"
self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip, tag=tag)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
- sm = self.vapi.nat44_static_mapping_dump()
+ sm = self.vapi.nat44_ei_static_mapping_dump()
self.assertEqual(len(sm), 1)
self.assertEqual(sm[0].tag, tag)
@@ -1424,11 +1394,11 @@ class TestNAT44EI(MethodHolder):
self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
self.icmp_id_in, self.icmp_id_out,
proto=IP_PROTOS.icmp)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
@@ -1465,11 +1435,11 @@ class TestNAT44EI(MethodHolder):
self.nat44_add_static_mapping(self.pg0.remote_ip4, self.nat_addr,
self.icmp_id_in, self.icmp_id_out,
proto=IP_PROTOS.icmp)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
@@ -1502,14 +1472,14 @@ class TestNAT44EI(MethodHolder):
vrf_id=10)
self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip2,
vrf_id=10)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg3.sw_if_index,
is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg4.sw_if_index,
flags=flags, is_add=1)
@@ -1537,11 +1507,11 @@ class TestNAT44EI(MethodHolder):
self.icmp_id_out = 6305
self.nat44_add_address(self.nat_addr)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
@@ -1555,7 +1525,7 @@ class TestNAT44EI(MethodHolder):
# 1:1NAT
self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
- sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
+ sessions = self.vapi.nat44_ei_user_session_dump(self.pg0.remote_ip4, 0)
self.assertEqual(len(sessions), 0)
pkts = self.create_stream_in(self.pg0, self.pg1)
self.pg0.add_stream(pkts)
@@ -1566,15 +1536,15 @@ class TestNAT44EI(MethodHolder):
def test_identity_nat(self):
""" NAT44EI Identity NAT """
- flags = self.config_flags.NAT_IS_ADDR_ONLY
- self.vapi.nat44_add_del_identity_mapping(
+ flags = self.config_flags.NAT44_EI_ADDR_ONLY_MAPPING
+ self.vapi.nat44_ei_add_del_identity_mapping(
ip_address=self.pg0.remote_ip4, sw_if_index=0xFFFFFFFF,
flags=flags, is_add=1)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
@@ -1598,13 +1568,13 @@ class TestNAT44EI(MethodHolder):
self.logger.error(ppp("Unexpected or invalid packet:", p))
raise
- sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
+ sessions = self.vapi.nat44_ei_user_session_dump(self.pg0.remote_ip4, 0)
self.assertEqual(len(sessions), 0)
- flags = self.config_flags.NAT_IS_ADDR_ONLY
- self.vapi.nat44_add_del_identity_mapping(
+ flags = self.config_flags.NAT44_EI_ADDR_ONLY_MAPPING
+ self.vapi.nat44_ei_add_del_identity_mapping(
ip_address=self.pg0.remote_ip4, sw_if_index=0xFFFFFFFF,
flags=flags, vrf_id=1, is_add=1)
- identity_mappings = self.vapi.nat44_identity_mapping_dump()
+ identity_mappings = self.vapi.nat44_ei_identity_mapping_dump()
self.assertEqual(len(identity_mappings), 2)
def test_multiple_inside_interfaces(self):
@@ -1612,14 +1582,14 @@ class TestNAT44EI(MethodHolder):
"""
self.nat44_add_address(self.nat_addr)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg3.sw_if_index,
is_add=1)
@@ -1677,17 +1647,17 @@ class TestNAT44EI(MethodHolder):
static_nat_ip = "10.0.0.10"
self.nat44_add_address(self.nat_addr)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg3.sw_if_index,
is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg4.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg5.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg6.sw_if_index,
flags=flags, is_add=1)
self.nat44_add_static_mapping(self.pg6.remote_ip4, static_nat_ip,
@@ -1754,12 +1724,14 @@ class TestNAT44EI(MethodHolder):
self.verify_capture_in(capture, self.pg5)
# pg5 session dump
- addresses = self.vapi.nat44_address_dump()
+ addresses = self.vapi.nat44_ei_address_dump()
self.assertEqual(len(addresses), 1)
- sessions = self.vapi.nat44_user_session_dump(self.pg5.remote_ip4, 10)
+ sessions = self.vapi.nat44_ei_user_session_dump(
+ self.pg5.remote_ip4, 10)
self.assertEqual(len(sessions), 3)
for session in sessions:
- self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
+ self.assertFalse(session.flags &
+ self.config_flags.NAT44_EI_STATIC_MAPPING)
self.assertEqual(str(session.inside_ip_address),
self.pg5.remote_ip4)
self.assertEqual(session.outside_ip_address,
@@ -1791,37 +1763,39 @@ class TestNAT44EI(MethodHolder):
self.verify_capture_in(capture, self.pg6)
# general user and session dump verifications
- users = self.vapi.nat44_user_dump()
+ users = self.vapi.nat44_ei_user_dump()
self.assertGreaterEqual(len(users), 3)
- addresses = self.vapi.nat44_address_dump()
+ addresses = self.vapi.nat44_ei_address_dump()
self.assertEqual(len(addresses), 1)
for user in users:
- sessions = self.vapi.nat44_user_session_dump(user.ip_address,
- user.vrf_id)
+ sessions = self.vapi.nat44_ei_user_session_dump(user.ip_address,
+ user.vrf_id)
for session in sessions:
self.assertEqual(user.ip_address, session.inside_ip_address)
self.assertTrue(session.total_bytes > session.total_pkts > 0)
self.assertTrue(session.protocol in
[IP_PROTOS.tcp, IP_PROTOS.udp,
IP_PROTOS.icmp])
- self.assertFalse(session.flags &
- self.config_flags.NAT_IS_EXT_HOST_VALID)
# pg4 session dump
- sessions = self.vapi.nat44_user_session_dump(self.pg4.remote_ip4, 10)
+ sessions = self.vapi.nat44_ei_user_session_dump(
+ self.pg4.remote_ip4, 10)
self.assertGreaterEqual(len(sessions), 4)
for session in sessions:
- self.assertFalse(session.flags & self.config_flags.NAT_IS_STATIC)
+ self.assertFalse(
+ session.flags & self.config_flags.NAT44_EI_STATIC_MAPPING)
self.assertEqual(str(session.inside_ip_address),
self.pg4.remote_ip4)
self.assertEqual(session.outside_ip_address,
addresses[0].ip_address)
# pg6 session dump
- sessions = self.vapi.nat44_user_session_dump(self.pg6.remote_ip4, 20)
+ sessions = self.vapi.nat44_ei_user_session_dump(
+ self.pg6.remote_ip4, 20)
self.assertGreaterEqual(len(sessions), 3)
for session in sessions:
- self.assertTrue(session.flags & self.config_flags.NAT_IS_STATIC)
+ self.assertTrue(
+ session.flags & self.config_flags.NAT44_EI_STATIC_MAPPING)
self.assertEqual(str(session.inside_ip_address),
self.pg6.remote_ip4)
self.assertEqual(str(session.outside_ip_address),
@@ -1841,11 +1815,11 @@ class TestNAT44EI(MethodHolder):
server_out_port = 8765
self.nat44_add_address(self.nat_addr)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
@@ -1854,7 +1828,7 @@ class TestNAT44EI(MethodHolder):
server_in_port, server_out_port,
proto=IP_PROTOS.tcp)
- cnt = self.statistics.get_counter('/nat44/hairpinning')[0]
+ cnt = self.statistics.get_counter('/nat44-ei/hairpinning')[0]
# send packet from host to server
p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
IP(src=host.ip4, dst=self.nat_addr) /
@@ -1877,7 +1851,7 @@ class TestNAT44EI(MethodHolder):
self.logger.error(ppp("Unexpected or invalid packet:", p))
raise
- after = self.statistics.get_counter('/nat44/hairpinning')[0]
+ after = self.statistics.get_counter('/nat44-ei/hairpinning')[0]
if_idx = self.pg0.sw_if_index
self.assertEqual(after[if_idx] - cnt[if_idx], 1)
@@ -1902,7 +1876,7 @@ class TestNAT44EI(MethodHolder):
self.logger.error(ppp("Unexpected or invalid packet:", p))
raise
- after = self.statistics.get_counter('/nat44/hairpinning')[0]
+ after = self.statistics.get_counter('/nat44-ei/hairpinning')[0]
if_idx = self.pg0.sw_if_index
self.assertEqual(after[if_idx] - cnt[if_idx], 2)
@@ -1918,11 +1892,11 @@ class TestNAT44EI(MethodHolder):
server_udp_port = 20
self.nat44_add_address(self.nat_addr)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
@@ -2077,7 +2051,7 @@ class TestNAT44EI(MethodHolder):
raise
def test_hairpinning_avoid_inf_loop(self):
- """ NAT44 hairpinning - 1:1 NAPT avoid infinite loop """
+ """ NAT44EI hairpinning - 1:1 NAPT avoid infinite loop """
host = self.pg0.remote_hosts[0]
server = self.pg0.remote_hosts[1]
@@ -2087,11 +2061,11 @@ class TestNAT44EI(MethodHolder):
server_out_port = 8765
self.nat44_add_address(self.nat_addr)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
@@ -2112,7 +2086,7 @@ class TestNAT44EI(MethodHolder):
self.pg_start()
# Here VPP used to crash due to an infinite loop
- cnt = self.statistics.get_counter('/nat44/hairpinning')[0]
+ cnt = self.statistics.get_counter('/nat44-ei/hairpinning')[0]
# send packet from host to server
p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
IP(src=host.ip4, dst=self.nat_addr) /
@@ -2135,7 +2109,7 @@ class TestNAT44EI(MethodHolder):
self.logger.error(ppp("Unexpected or invalid packet:", p))
raise
- after = self.statistics.get_counter('/nat44/hairpinning')[0]
+ after = self.statistics.get_counter('/nat44-ei/hairpinning')[0]
if_idx = self.pg0.sw_if_index
self.assertEqual(after[if_idx] - cnt[if_idx], 1)
@@ -2160,36 +2134,36 @@ class TestNAT44EI(MethodHolder):
self.logger.error(ppp("Unexpected or invalid packet:", p))
raise
- after = self.statistics.get_counter('/nat44/hairpinning')[0]
+ after = self.statistics.get_counter('/nat44-ei/hairpinning')[0]
if_idx = self.pg0.sw_if_index
self.assertEqual(after[if_idx] - cnt[if_idx], 2)
def test_interface_addr(self):
""" NAT44EI acquire addresses from interface """
- self.vapi.nat44_add_del_interface_addr(
+ self.vapi.nat44_ei_add_del_interface_addr(
is_add=1,
sw_if_index=self.pg7.sw_if_index)
# no address in NAT pool
- addresses = self.vapi.nat44_address_dump()
+ addresses = self.vapi.nat44_ei_address_dump()
self.assertEqual(0, len(addresses))
# configure interface address and check NAT address pool
self.pg7.config_ip4()
- addresses = self.vapi.nat44_address_dump()
+ addresses = self.vapi.nat44_ei_address_dump()
self.assertEqual(1, len(addresses))
self.assertEqual(str(addresses[0].ip_address), self.pg7.local_ip4)
# remove interface address and check NAT address pool
self.pg7.unconfig_ip4()
- addresses = self.vapi.nat44_address_dump()
+ addresses = self.vapi.nat44_ei_address_dump()
self.assertEqual(0, len(addresses))
def test_interface_addr_static_mapping(self):
""" NAT44EI Static mapping with addresses from interface """
tag = "testTAG"
- self.vapi.nat44_add_del_interface_addr(
+ self.vapi.nat44_ei_add_del_interface_addr(
is_add=1,
sw_if_index=self.pg7.sw_if_index)
self.nat44_add_static_mapping(
@@ -2198,7 +2172,7 @@ class TestNAT44EI(MethodHolder):
tag=tag)
# static mappings with external interface
- static_mappings = self.vapi.nat44_static_mapping_dump()
+ static_mappings = self.vapi.nat44_ei_static_mapping_dump()
self.assertEqual(1, len(static_mappings))
self.assertEqual(self.pg7.sw_if_index,
static_mappings[0].external_sw_if_index)
@@ -2206,7 +2180,7 @@ class TestNAT44EI(MethodHolder):
# configure interface address and check static mappings
self.pg7.config_ip4()
- static_mappings = self.vapi.nat44_static_mapping_dump()
+ static_mappings = self.vapi.nat44_ei_static_mapping_dump()
self.assertEqual(2, len(static_mappings))
resolved = False
for sm in static_mappings:
@@ -2219,7 +2193,7 @@ class TestNAT44EI(MethodHolder):
# remove interface address and check static mappings
self.pg7.unconfig_ip4()
- static_mappings = self.vapi.nat44_static_mapping_dump()
+ static_mappings = self.vapi.nat44_ei_static_mapping_dump()
self.assertEqual(1, len(static_mappings))
self.assertEqual(self.pg7.sw_if_index,
static_mappings[0].external_sw_if_index)
@@ -2227,7 +2201,7 @@ class TestNAT44EI(MethodHolder):
# configure interface address again and check static mappings
self.pg7.config_ip4()
- static_mappings = self.vapi.nat44_static_mapping_dump()
+ static_mappings = self.vapi.nat44_ei_static_mapping_dump()
self.assertEqual(2, len(static_mappings))
resolved = False
for sm in static_mappings:
@@ -2244,17 +2218,17 @@ class TestNAT44EI(MethodHolder):
external_sw_if_index=self.pg7.sw_if_index,
tag=tag,
is_add=0)
- static_mappings = self.vapi.nat44_static_mapping_dump()
+ static_mappings = self.vapi.nat44_ei_static_mapping_dump()
self.assertEqual(0, len(static_mappings))
def test_interface_addr_identity_nat(self):
""" NAT44EI Identity NAT with addresses from interface """
port = 53053
- self.vapi.nat44_add_del_interface_addr(
+ self.vapi.nat44_ei_add_del_interface_addr(
is_add=1,
sw_if_index=self.pg7.sw_if_index)
- self.vapi.nat44_add_del_identity_mapping(
+ self.vapi.nat44_ei_add_del_identity_mapping(
ip_address=b'0',
sw_if_index=self.pg7.sw_if_index,
port=port,
@@ -2262,14 +2236,14 @@ class TestNAT44EI(MethodHolder):
is_add=1)
# identity mappings with external interface
- identity_mappings = self.vapi.nat44_identity_mapping_dump()
+ identity_mappings = self.vapi.nat44_ei_identity_mapping_dump()
self.assertEqual(1, len(identity_mappings))
self.assertEqual(self.pg7.sw_if_index,
identity_mappings[0].sw_if_index)
# configure interface address and check identity mappings
self.pg7.config_ip4()
- identity_mappings = self.vapi.nat44_identity_mapping_dump()
+ identity_mappings = self.vapi.nat44_ei_identity_mapping_dump()
resolved = False
self.assertEqual(2, len(identity_mappings))
for sm in identity_mappings:
@@ -2283,7 +2257,7 @@ class TestNAT44EI(MethodHolder):
# remove interface address and check identity mappings
self.pg7.unconfig_ip4()
- identity_mappings = self.vapi.nat44_identity_mapping_dump()
+ identity_mappings = self.vapi.nat44_ei_identity_mapping_dump()
self.assertEqual(1, len(identity_mappings))
self.assertEqual(self.pg7.sw_if_index,
identity_mappings[0].sw_if_index)
@@ -2295,11 +2269,11 @@ class TestNAT44EI(MethodHolder):
collector_port = 30303
bind_layers(UDP, IPFIX, dport=30303)
self.nat44_add_address(self.nat_addr)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
@@ -2307,9 +2281,9 @@ class TestNAT44EI(MethodHolder):
path_mtu=512,
template_interval=10,
collector_port=collector_port)
- self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
- src_port=self.ipfix_src_port,
- enable=1)
+ self.vapi.nat44_ei_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
+ src_port=self.ipfix_src_port,
+ enable=1)
pkts = self.create_stream_in(self.pg0, self.pg1)
self.pg0.add_stream(pkts)
@@ -2340,20 +2314,20 @@ class TestNAT44EI(MethodHolder):
def test_ipfix_addr_exhausted(self):
""" NAT44EI IPFIX logging NAT addresses exhausted """
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
self.vapi.set_ipfix_exporter(collector_address=self.pg3.remote_ip4,
src_address=self.pg3.local_ip4,
path_mtu=512,
template_interval=10)
- self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
- src_port=self.ipfix_src_port,
- enable=1)
+ self.vapi.nat44_ei_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
+ src_port=self.ipfix_src_port,
+ enable=1)
p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
@@ -2386,11 +2360,11 @@ class TestNAT44EI(MethodHolder):
def test_ipfix_max_sessions(self):
""" NAT44EI IPFIX logging maximum session entries exceeded """
self.nat44_add_address(self.nat_addr)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
@@ -2412,9 +2386,9 @@ class TestNAT44EI(MethodHolder):
src_address=self.pg3.local_ip4,
path_mtu=512,
template_interval=10)
- self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
- src_port=self.ipfix_src_port,
- enable=1)
+ self.vapi.nat44_ei_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
+ src_port=self.ipfix_src_port,
+ enable=1)
p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
@@ -2450,11 +2424,11 @@ class TestNAT44EI(MethodHolder):
self.SYSLOG_SEVERITY.SYSLOG_API_SEVERITY_INFO)
self.vapi.syslog_set_sender(self.pg3.local_ip4, self.pg3.remote_ip4)
self.nat44_add_address(self.nat_addr)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
@@ -2479,11 +2453,11 @@ class TestNAT44EI(MethodHolder):
""" NAT44EI add pool addresses to FIB """
static_addr = '10.0.0.10'
self.nat44_add_address(self.nat_addr)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
self.nat44_add_static_mapping(self.pg0.remote_ip4, static_addr)
@@ -2561,14 +2535,14 @@ class TestNAT44EI(MethodHolder):
self.nat44_add_address(nat_ip1, vrf_id=vrf_id1)
self.nat44_add_address(nat_ip2, vrf_id=vrf_id2)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg2.sw_if_index,
is_add=1)
@@ -2609,14 +2583,14 @@ class TestNAT44EI(MethodHolder):
self.nat44_add_address(nat_ip1)
self.nat44_add_address(nat_ip2, vrf_id=99)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg2.sw_if_index,
is_add=1)
@@ -2640,11 +2614,11 @@ class TestNAT44EI(MethodHolder):
""" NAT44EI interfaces without configured IP address """
self.create_routes_and_neigbors()
self.nat44_add_address(self.nat_addr)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg7.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg8.sw_if_index,
is_add=1)
@@ -2669,11 +2643,11 @@ class TestNAT44EI(MethodHolder):
self.create_routes_and_neigbors()
self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg7.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg8.sw_if_index,
is_add=1)
@@ -2711,11 +2685,11 @@ class TestNAT44EI(MethodHolder):
self.nat44_add_static_mapping(self.pg7.remote_ip4, self.nat_addr,
self.icmp_id_in, self.icmp_id_out,
proto=IP_PROTOS.icmp)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg7.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg8.sw_if_index,
is_add=1)
@@ -2739,11 +2713,11 @@ class TestNAT44EI(MethodHolder):
""" NAT44EI 1:1 translate packet with unknown protocol """
nat_ip = "10.0.0.10"
self.nat44_add_static_mapping(self.pg0.remote_ip4, nat_ip)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
@@ -2799,11 +2773,11 @@ class TestNAT44EI(MethodHolder):
self.nat44_add_static_mapping(host.ip4, host_nat_ip)
self.nat44_add_static_mapping(server.ip4, server_nat_ip)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
@@ -2850,14 +2824,14 @@ class TestNAT44EI(MethodHolder):
def test_output_feature(self):
""" NAT44EI output feature (in2out postrouting) """
self.nat44_add_address(self.nat_addr)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_output_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_output_feature(
is_add=1, flags=flags,
sw_if_index=self.pg0.sw_if_index)
- self.vapi.nat44_interface_add_del_output_feature(
+ self.vapi.nat44_ei_interface_add_del_output_feature(
is_add=1, flags=flags,
sw_if_index=self.pg1.sw_if_index)
- self.vapi.nat44_interface_add_del_output_feature(
+ self.vapi.nat44_ei_interface_add_del_output_feature(
is_add=1,
sw_if_index=self.pg3.sw_if_index)
@@ -2903,14 +2877,14 @@ class TestNAT44EI(MethodHolder):
self.nat44_add_address(nat_ip_vrf10, vrf_id=10)
self.nat44_add_address(nat_ip_vrf20, vrf_id=20)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_output_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_output_feature(
is_add=1, flags=flags,
sw_if_index=self.pg4.sw_if_index)
- self.vapi.nat44_interface_add_del_output_feature(
+ self.vapi.nat44_ei_interface_add_del_output_feature(
is_add=1, flags=flags,
sw_if_index=self.pg6.sw_if_index)
- self.vapi.nat44_interface_add_del_output_feature(
+ self.vapi.nat44_ei_interface_add_del_output_feature(
is_add=1,
sw_if_index=self.pg3.sw_if_index)
@@ -2956,11 +2930,11 @@ class TestNAT44EI(MethodHolder):
server_out_port = 8765
self.nat44_add_address(self.nat_addr)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_output_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_output_feature(
is_add=1, flags=flags,
sw_if_index=self.pg0.sw_if_index)
- self.vapi.nat44_interface_add_del_output_feature(
+ self.vapi.nat44_ei_interface_add_del_output_feature(
is_add=1,
sw_if_index=self.pg1.sw_if_index)
@@ -3019,11 +2993,11 @@ class TestNAT44EI(MethodHolder):
external_port = 0
self.nat44_add_address(self.nat_addr)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg9.sw_if_index,
is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg9.sw_if_index,
flags=flags, is_add=1)
@@ -3071,20 +3045,20 @@ class TestNAT44EI(MethodHolder):
raise
err = self.statistics.get_err_counter(
- '/err/nat44-classify/next in2out')
+ '/err/nat44-ei-classify/next in2out')
self.assertEqual(err, 1)
err = self.statistics.get_err_counter(
- '/err/nat44-classify/next out2in')
+ '/err/nat44-ei-classify/next out2in')
self.assertEqual(err, 1)
def test_del_session(self):
""" NAT44EI delete session """
self.nat44_add_address(self.nat_addr)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
@@ -3094,24 +3068,28 @@ class TestNAT44EI(MethodHolder):
self.pg_start()
self.pg1.get_capture(len(pkts))
- sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
+ sessions = self.vapi.nat44_ei_user_session_dump(self.pg0.remote_ip4, 0)
nsessions = len(sessions)
- self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
- port=sessions[0].inside_port,
- protocol=sessions[0].protocol,
- flags=self.config_flags.NAT_IS_INSIDE)
- self.vapi.nat44_del_session(address=sessions[1].outside_ip_address,
- port=sessions[1].outside_port,
- protocol=sessions[1].protocol)
+ self.vapi.nat44_ei_del_session(
+ address=sessions[0].inside_ip_address,
+ port=sessions[0].inside_port,
+ protocol=sessions[0].protocol,
+ flags=self.config_flags.NAT44_EI_IF_INSIDE)
- sessions = self.vapi.nat44_user_session_dump(self.pg0.remote_ip4, 0)
+ self.vapi.nat44_ei_del_session(
+ address=sessions[1].outside_ip_address,
+ port=sessions[1].outside_port,
+ protocol=sessions[1].protocol)
+
+ sessions = self.vapi.nat44_ei_user_session_dump(self.pg0.remote_ip4, 0)
self.assertEqual(nsessions - len(sessions), 2)
- self.vapi.nat44_del_session(address=sessions[0].inside_ip_address,
- port=sessions[0].inside_port,
- protocol=sessions[0].protocol,
- flags=self.config_flags.NAT_IS_INSIDE)
+ self.vapi.nat44_ei_del_session(
+ address=sessions[0].inside_ip_address,
+ port=sessions[0].inside_port,
+ protocol=sessions[0].protocol,
+ flags=self.config_flags.NAT44_EI_IF_INSIDE)
self.verify_no_nat44_user()
@@ -3119,11 +3097,11 @@ class TestNAT44EI(MethodHolder):
""" NAT44EI translate fragments arriving in order """
self.nat44_add_address(self.nat_addr)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
@@ -3133,17 +3111,17 @@ class TestNAT44EI(MethodHolder):
def test_frag_forwarding(self):
""" NAT44EI forwarding fragment test """
- self.vapi.nat44_add_del_interface_addr(
+ self.vapi.nat44_ei_add_del_interface_addr(
is_add=1,
sw_if_index=self.pg1.sw_if_index)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
- self.vapi.nat44_forwarding_enable_disable(enable=1)
+ self.vapi.nat44_ei_forwarding_enable_disable(enable=1)
data = b"A" * 16 + b"B" * 16 + b"C" * 3
pkts = self.create_stream_frag(self.pg1,
@@ -3172,11 +3150,11 @@ class TestNAT44EI(MethodHolder):
server_out_port = random.randint(1025, 65535)
self.nat44_add_address(self.nat_addr)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
# add static mapping for server
@@ -3201,11 +3179,11 @@ class TestNAT44EI(MethodHolder):
""" NAT44EI translate fragments arriving out of order """
self.nat44_add_address(self.nat_addr)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
@@ -3216,17 +3194,17 @@ class TestNAT44EI(MethodHolder):
def test_port_restricted(self):
""" NAT44EI Port restricted NAT44EI (MAP-E CE) """
self.nat44_add_address(self.nat_addr)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
- self.vapi.nat_set_addr_and_port_alloc_alg(alg=1,
- psid_offset=6,
- psid_length=6,
- psid=10)
+ self.vapi.nat44_ei_set_addr_and_port_alloc_alg(alg=1,
+ psid_offset=6,
+ psid_length=6,
+ psid=10)
p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
@@ -3252,16 +3230,16 @@ class TestNAT44EI(MethodHolder):
def test_port_range(self):
""" NAT44EI External address port range """
self.nat44_add_address(self.nat_addr)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
- self.vapi.nat_set_addr_and_port_alloc_alg(alg=2,
- start_port=1025,
- end_port=1027)
+ self.vapi.nat44_ei_set_addr_and_port_alloc_alg(alg=2,
+ start_port=1025,
+ end_port=1027)
pkts = []
for port in range(0, 5):
@@ -3295,14 +3273,14 @@ class TestNAT44EI(MethodHolder):
self.pg2.resolve_arp()
self.nat44_add_address(self.nat_addr)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg2.sw_if_index,
is_add=1)
@@ -3355,11 +3333,11 @@ class TestNAT44EI(MethodHolder):
def test_mss_clamping(self):
""" NAT44EI TCP MSS clamping """
self.nat44_add_address(self.nat_addr)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
@@ -3368,7 +3346,7 @@ class TestNAT44EI(MethodHolder):
TCP(sport=self.tcp_port_in, dport=self.tcp_external_port,
flags="S", options=[('MSS', 1400)]))
- self.vapi.nat_set_mss_clamping(enable=1, mss_value=1000)
+ self.vapi.nat44_ei_set_mss_clamping(enable=1, mss_value=1000)
self.pg0.add_stream(p)
self.pg_enable_capture(self.pg_interfaces)
self.pg_start()
@@ -3376,7 +3354,7 @@ class TestNAT44EI(MethodHolder):
# Negotiated MSS value greater than configured - changed
self.verify_mss_value(capture[0], 1000)
- self.vapi.nat_set_mss_clamping(enable=0, mss_value=1500)
+ self.vapi.nat44_ei_set_mss_clamping(enable=0, mss_value=1500)
self.pg0.add_stream(p)
self.pg_enable_capture(self.pg_interfaces)
self.pg_start()
@@ -3384,7 +3362,7 @@ class TestNAT44EI(MethodHolder):
# MSS clamping disabled - negotiated MSS unchanged
self.verify_mss_value(capture[0], 1400)
- self.vapi.nat_set_mss_clamping(enable=1, mss_value=1500)
+ self.vapi.nat44_ei_set_mss_clamping(enable=1, mss_value=1500)
self.pg0.add_stream(p)
self.pg_enable_capture(self.pg_interfaces)
self.pg_start()
@@ -3394,20 +3372,20 @@ class TestNAT44EI(MethodHolder):
def test_ha_send(self):
""" NAT44EI Send HA session synchronization events (active) """
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
self.nat44_add_address(self.nat_addr)
- self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
- port=12345,
- path_mtu=512)
- self.vapi.nat_ha_set_failover(ip_address=self.pg3.remote_ip4,
- port=12346, session_refresh_interval=10)
+ self.vapi.nat44_ei_ha_set_listener(
+ ip_address=self.pg3.local_ip4, port=12345, path_mtu=512)
+ self.vapi.nat44_ei_ha_set_failover(
+ ip_address=self.pg3.remote_ip4, port=12346,
+ session_refresh_interval=10)
bind_layers(UDP, HANATStateSync, sport=12345)
# create sessions
@@ -3418,8 +3396,8 @@ class TestNAT44EI(MethodHolder):
capture = self.pg1.get_capture(len(pkts))
self.verify_capture_out(capture)
# active send HA events
- self.vapi.nat_ha_flush()
- stats = self.statistics.get_counter('/nat44/ha/add-event-send')
+ self.vapi.nat44_ei_ha_flush()
+ stats = self.statistics.get_counter('/nat44-ei/ha/add-event-send')
self.assertEqual(stats[0][0], 3)
capture = self.pg3.get_capture(1)
p = capture[0]
@@ -3453,17 +3431,16 @@ class TestNAT44EI(MethodHolder):
HANATStateSync(sequence_number=seq, flags='ACK'))
self.pg3.add_stream(ack)
self.pg_start()
- stats = self.statistics.get_counter('/nat44/ha/ack-recv')
+ stats = self.statistics.get_counter('/nat44-ei/ha/ack-recv')
self.assertEqual(stats[0][0], 1)
# delete one session
self.pg_enable_capture(self.pg_interfaces)
- self.vapi.nat44_del_session(address=self.pg0.remote_ip4,
- port=self.tcp_port_in,
- protocol=IP_PROTOS.tcp,
- flags=self.config_flags.NAT_IS_INSIDE)
- self.vapi.nat_ha_flush()
- stats = self.statistics.get_counter('/nat44/ha/del-event-send')
+ self.vapi.nat44_ei_del_session(
+ address=self.pg0.remote_ip4, port=self.tcp_port_in,
+ protocol=IP_PROTOS.tcp, flags=self.config_flags.NAT44_EI_IF_INSIDE)
+ self.vapi.nat44_ei_ha_flush()
+ stats = self.statistics.get_counter('/nat44-ei/ha/del-event-send')
self.assertEqual(stats[0][0], 1)
capture = self.pg3.get_capture(1)
p = capture[0]
@@ -3478,9 +3455,9 @@ class TestNAT44EI(MethodHolder):
# do not send ACK, active retry send HA event again
self.pg_enable_capture(self.pg_interfaces)
sleep(12)
- stats = self.statistics.get_counter('/nat44/ha/retry-count')
+ stats = self.statistics.get_counter('/nat44-ei/ha/retry-count')
self.assertEqual(stats[0][0], 3)
- stats = self.statistics.get_counter('/nat44/ha/missed-count')
+ stats = self.statistics.get_counter('/nat44-ei/ha/missed-count')
self.assertEqual(stats[0][0], 1)
capture = self.pg3.get_capture(3)
for packet in capture:
@@ -3492,8 +3469,8 @@ class TestNAT44EI(MethodHolder):
self.pg_enable_capture(self.pg_interfaces)
self.pg_start()
self.pg0.get_capture(2)
- self.vapi.nat_ha_flush()
- stats = self.statistics.get_counter('/nat44/ha/refresh-event-send')
+ self.vapi.nat44_ei_ha_flush()
+ stats = self.statistics.get_counter('/nat44-ei/ha/refresh-event-send')
self.assertEqual(stats[0][0], 2)
capture = self.pg3.get_capture(1)
p = capture[0]
@@ -3526,22 +3503,21 @@ class TestNAT44EI(MethodHolder):
HANATStateSync(sequence_number=seq, flags='ACK'))
self.pg3.add_stream(ack)
self.pg_start()
- stats = self.statistics.get_counter('/nat44/ha/ack-recv')
+ stats = self.statistics.get_counter('/nat44-ei/ha/ack-recv')
self.assertEqual(stats[0][0], 2)
def test_ha_recv(self):
""" NAT44EI Receive HA session synchronization events (passive) """
self.nat44_add_address(self.nat_addr)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
- self.vapi.nat_ha_set_listener(ip_address=self.pg3.local_ip4,
- port=12345,
- path_mtu=512)
+ self.vapi.nat44_ei_ha_set_listener(ip_address=self.pg3.local_ip4,
+ port=12345, path_mtu=512)
bind_layers(UDP, HANATStateSync, sport=12345)
self.tcp_port_out = random.randint(1025, 65535)
@@ -3583,21 +3559,21 @@ class TestNAT44EI(MethodHolder):
self.assertEqual(hanat.flags, 'ACK')
self.assertEqual(hanat.version, 1)
self.assertEqual(hanat.thread_index, 0)
- stats = self.statistics.get_counter('/nat44/ha/ack-send')
+ stats = self.statistics.get_counter('/nat44-ei/ha/ack-send')
self.assertEqual(stats[0][0], 1)
- stats = self.statistics.get_counter('/nat44/ha/add-event-recv')
+ stats = self.statistics.get_counter('/nat44-ei/ha/add-event-recv')
self.assertEqual(stats[0][0], 2)
- users = self.statistics.get_counter('/nat44/total-users')
+ users = self.statistics.get_counter('/nat44-ei/total-users')
self.assertEqual(users[0][0], 1)
- sessions = self.statistics.get_counter('/nat44/total-sessions')
+ sessions = self.statistics.get_counter('/nat44-ei/total-sessions')
self.assertEqual(sessions[0][0], 2)
- users = self.vapi.nat44_user_dump()
+ users = self.vapi.nat44_ei_user_dump()
self.assertEqual(len(users), 1)
self.assertEqual(str(users[0].ip_address),
self.pg0.remote_ip4)
# there should be 2 sessions created by HA
- sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
- users[0].vrf_id)
+ sessions = self.vapi.nat44_ei_user_session_dump(
+ users[0].ip_address, users[0].vrf_id)
self.assertEqual(len(sessions), 2)
for session in sessions:
self.assertEqual(str(session.inside_ip_address),
@@ -3638,18 +3614,19 @@ class TestNAT44EI(MethodHolder):
self.assertEqual(hanat.sequence_number, 2)
self.assertEqual(hanat.flags, 'ACK')
self.assertEqual(hanat.version, 1)
- users = self.vapi.nat44_user_dump()
+ users = self.vapi.nat44_ei_user_dump()
self.assertEqual(len(users), 1)
self.assertEqual(str(users[0].ip_address),
self.pg0.remote_ip4)
# now we should have only 1 session, 1 deleted by HA
- sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
- users[0].vrf_id)
+ sessions = self.vapi.nat44_ei_user_session_dump(users[0].ip_address,
+ users[0].vrf_id)
self.assertEqual(len(sessions), 1)
- stats = self.statistics.get_counter('/nat44/ha/del-event-recv')
+ stats = self.statistics.get_counter('/nat44-ei/ha/del-event-recv')
self.assertEqual(stats[0][0], 1)
- stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
+ stats = self.statistics.get_err_counter(
+ '/err/nat44-ei-ha/pkts-processed')
self.assertEqual(stats, 2)
# send HA session refresh event to failover/passive
@@ -3680,20 +3657,22 @@ class TestNAT44EI(MethodHolder):
self.assertEqual(hanat.sequence_number, 3)
self.assertEqual(hanat.flags, 'ACK')
self.assertEqual(hanat.version, 1)
- users = self.vapi.nat44_user_dump()
+ users = self.vapi.nat44_ei_user_dump()
self.assertEqual(len(users), 1)
self.assertEqual(str(users[0].ip_address),
self.pg0.remote_ip4)
- sessions = self.vapi.nat44_user_session_dump(users[0].ip_address,
- users[0].vrf_id)
+ sessions = self.vapi.nat44_ei_user_session_dump(
+ users[0].ip_address, users[0].vrf_id)
self.assertEqual(len(sessions), 1)
session = sessions[0]
self.assertEqual(session.total_bytes, 1024)
self.assertEqual(session.total_pkts, 2)
- stats = self.statistics.get_counter('/nat44/ha/refresh-event-recv')
+ stats = self.statistics.get_counter(
+ '/nat44-ei/ha/refresh-event-recv')
self.assertEqual(stats[0][0], 1)
- stats = self.statistics.get_err_counter('/err/nat-ha/pkts-processed')
+ stats = self.statistics.get_err_counter(
+ '/err/nat44-ei-ha/pkts-processed')
self.assertEqual(stats, 3)
# send packet to test session created by HA
@@ -3717,17 +3696,28 @@ class TestNAT44EI(MethodHolder):
self.assertEqual(tcp.sport, self.tcp_external_port)
self.assertEqual(tcp.dport, self.tcp_port_in)
+ def reconfigure_frame_queue_nelts(self, frame_queue_nelts):
+ self.vapi.nat44_ei_plugin_enable_disable(enable=0)
+ self.vapi.nat44_ei_set_fq_options(frame_queue_nelts=frame_queue_nelts)
+ # keep plugin configuration persistent
+ self.plugin_enable()
+ return self.vapi.nat44_ei_show_fq_options().frame_queue_nelts
+
+ def test_set_frame_queue_nelts(self):
+ """ NAT44 EI API test - worker handoff frame queue elements """
+ self.assertEqual(self.reconfigure_frame_queue_nelts(512), 512)
+
def show_commands_at_teardown(self):
- self.logger.info(self.vapi.cli("show nat44 addresses"))
- self.logger.info(self.vapi.cli("show nat44 interfaces"))
- self.logger.info(self.vapi.cli("show nat44 static mappings"))
- self.logger.info(self.vapi.cli("show nat44 interface address"))
- self.logger.info(self.vapi.cli("show nat44 sessions detail"))
- self.logger.info(self.vapi.cli("show nat44 hash tables detail"))
- self.logger.info(self.vapi.cli("show nat timeouts"))
+ self.logger.info(self.vapi.cli("show nat44 ei timeouts"))
+ self.logger.info(self.vapi.cli("show nat44 ei addresses"))
+ self.logger.info(self.vapi.cli("show nat44 ei interfaces"))
+ self.logger.info(self.vapi.cli("show nat44 ei static mappings"))
+ self.logger.info(self.vapi.cli("show nat44 ei interface address"))
+ self.logger.info(self.vapi.cli("show nat44 ei sessions detail"))
+ self.logger.info(self.vapi.cli("show nat44 ei hash tables detail"))
+ self.logger.info(self.vapi.cli("show nat44 ei ha"))
self.logger.info(
- self.vapi.cli("show nat addr-port-assignment-alg"))
- self.logger.info(self.vapi.cli("show nat ha"))
+ self.vapi.cli("show nat44 ei addr-port-assignment-alg"))
class TestNAT44Out2InDPO(MethodHolder):
@@ -3736,7 +3726,7 @@ class TestNAT44Out2InDPO(MethodHolder):
@classmethod
def setUpClass(cls):
super(TestNAT44Out2InDPO, cls).setUpClass()
- cls.vapi.cli("set log class nat level debug")
+ cls.vapi.cli("set log class nat44-ei level debug")
cls.tcp_port_in = 6303
cls.tcp_port_out = 6303
@@ -3765,13 +3755,13 @@ class TestNAT44Out2InDPO(MethodHolder):
def setUp(self):
super(TestNAT44Out2InDPO, self).setUp()
- flags = self.nat44_config_flags.NAT44_API_IS_OUT2IN_DPO
- self.vapi.nat44_plugin_enable_disable(enable=1, flags=flags)
+ flags = self.config_flags.NAT44_EI_OUT2IN_DPO
+ self.vapi.nat44_ei_plugin_enable_disable(enable=1, flags=flags)
def tearDown(self):
super(TestNAT44Out2InDPO, self).tearDown()
if not self.vpp_dead:
- self.vapi.nat44_plugin_enable_disable(enable=0)
+ self.vapi.nat44_ei_plugin_enable_disable(enable=0)
self.vapi.cli("clear logging")
def configure_xlat(self):
@@ -3791,18 +3781,16 @@ class TestNAT44Out2InDPO(MethodHolder):
def test_464xlat_ce(self):
""" Test 464XLAT CE with NAT44EI """
- nat_config = self.vapi.nat_show_config()
- self.assertEqual(1, nat_config.out2in_dpo)
-
self.configure_xlat()
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_add_del_address_range(first_ip_address=self.nat_addr_n,
- last_ip_address=self.nat_addr_n,
- vrf_id=0xFFFFFFFF, is_add=1)
+ self.vapi.nat44_ei_add_del_address_range(
+ first_ip_address=self.nat_addr_n,
+ last_ip_address=self.nat_addr_n,
+ vrf_id=0xFFFFFFFF, is_add=1)
out_src_ip6 = self.compose_ip6(self.dst_ip4, self.dst_ip6_pfx,
self.dst_ip6_pfx_len)
@@ -3826,10 +3814,10 @@ class TestNAT44Out2InDPO(MethodHolder):
capture = self.pg0.get_capture(len(pkts))
self.verify_capture_in(capture, self.pg0)
finally:
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags)
- self.vapi.nat44_add_del_address_range(
+ self.vapi.nat44_ei_add_del_address_range(
first_ip_address=self.nat_addr_n,
last_ip_address=self.nat_addr_n,
vrf_id=0xFFFFFFFF)
@@ -3935,20 +3923,21 @@ class TestNAT44EIMW(MethodHolder):
def setUp(self):
super(TestNAT44EIMW, self).setUp()
- self.vapi.nat44_plugin_enable_disable(
+ self.vapi.nat44_ei_plugin_enable_disable(
sessions=self.max_translations,
users=self.max_users, enable=1)
def tearDown(self):
super(TestNAT44EIMW, self).tearDown()
if not self.vpp_dead:
- self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
- src_port=self.ipfix_src_port,
- enable=0)
+ self.vapi.nat44_ei_ipfix_enable_disable(
+ domain_id=self.ipfix_domain_id,
+ src_port=self.ipfix_src_port,
+ enable=0)
self.ipfix_src_port = 4739
self.ipfix_domain_id = 1
- self.vapi.nat44_plugin_enable_disable(enable=0)
+ self.vapi.nat44_ei_plugin_enable_disable(enable=0)
self.vapi.cli("clear logging")
def test_hairpinning(self):
@@ -3964,11 +3953,11 @@ class TestNAT44EIMW(MethodHolder):
worker_2 = 2
self.nat44_add_address(self.nat_addr)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
@@ -3977,7 +3966,7 @@ class TestNAT44EIMW(MethodHolder):
server_in_port, server_out_port,
proto=IP_PROTOS.tcp)
- cnt = self.statistics.get_counter('/nat44/hairpinning')
+ cnt = self.statistics.get_counter('/nat44-ei/hairpinning')
# send packet from host to server
p = (Ether(src=host.mac, dst=self.pg0.local_mac) /
IP(src=host.ip4, dst=self.nat_addr) /
@@ -4000,7 +3989,7 @@ class TestNAT44EIMW(MethodHolder):
self.logger.error(ppp("Unexpected or invalid packet:", p))
raise
- after = self.statistics.get_counter('/nat44/hairpinning')
+ after = self.statistics.get_counter('/nat44-ei/hairpinning')
if_idx = self.pg0.sw_if_index
self.assertEqual(after[worker_2][if_idx] - cnt[worker_1][if_idx], 1)
@@ -4026,7 +4015,7 @@ class TestNAT44EIMW(MethodHolder):
self.logger.error(ppp("Unexpected or invalid packet:", p))
raise
- after = self.statistics.get_counter('/nat44/hairpinning')
+ after = self.statistics.get_counter('/nat44-ei/hairpinning')
if_idx = self.pg0.sw_if_index
self.assertEqual(after[worker_1][if_idx] - cnt[worker_1][if_idx], 1)
self.assertEqual(after[worker_2][if_idx] - cnt[worker_2][if_idx], 2)
@@ -4043,11 +4032,11 @@ class TestNAT44EIMW(MethodHolder):
server_udp_port = 20
self.nat44_add_address(self.nat_addr)
- flags = self.config_flags.NAT_IS_INSIDE
- self.vapi.nat44_interface_add_del_feature(
+ flags = self.config_flags.NAT44_EI_IF_INSIDE
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg0.sw_if_index,
flags=flags, is_add=1)
- self.vapi.nat44_interface_add_del_feature(
+ self.vapi.nat44_ei_interface_add_del_feature(
sw_if_index=self.pg1.sw_if_index,
is_add=1)
@@ -4201,5 +4190,6 @@ class TestNAT44EIMW(MethodHolder):
self.logger.error(ppp("Unexpected or invalid packet:", packet))
raise
+
if __name__ == '__main__':
unittest.main(testRunner=VppTestRunner)