From ed2ee5e57b0f65ac4a94aac84cb6c27468878ea4 Mon Sep 17 00:00:00 2001 From: Filip Varga Date: Tue, 23 Mar 2021 12:57:58 +0100 Subject: nat: NAT66 plugin enable&disable calls update Type: improvement Adding support for enable&disable calls (dynamic plugin configuration). API (nat66_plugin_enable_disable) and CLI (nat66 plugin enable/nat66 plugin disable) with support for outside_vrf id configuration. Change-Id: I5637ff1621d6662adc3b7c6f7f8176d84a4b492b Signed-off-by: Filip Varga --- src/plugins/gbp/test/test_gbp.py | 31 ++------ src/plugins/nat/nat66/nat66.api | 14 ++++ src/plugins/nat/nat66/nat66.c | 140 +++++++++++++++++++++++++------------ src/plugins/nat/nat66/nat66.h | 10 ++- src/plugins/nat/nat66/nat66_api.c | 30 ++++++-- src/plugins/nat/nat66/nat66_cli.c | 102 ++++++++++++++++++++++++++- src/plugins/nat/test/test_nat66.py | 55 +++++---------- 7 files changed, 263 insertions(+), 119 deletions(-) diff --git a/src/plugins/gbp/test/test_gbp.py b/src/plugins/gbp/test/test_gbp.py index 2f55c0876b1..342e5de6c45 100644 --- a/src/plugins/gbp/test/test_gbp.py +++ b/src/plugins/gbp/test/test_gbp.py @@ -833,6 +833,7 @@ class TestGBP(VppTestCase): "2001:10:2::1", "3001::4")] self.vapi.nat44_ed_plugin_enable_disable(enable=1) + self.vapi.nat66_plugin_enable_disable(enable=1) # # Config related to each of the EPGs @@ -852,8 +853,8 @@ class TestGBP(VppTestCase): sw_if_index=epg.bvi.sw_if_index, flags=flags, is_add=1) self.vapi.nat66_add_del_interface( - is_add=1, flags=flags, - sw_if_index=epg.bvi.sw_if_index) + sw_if_index=epg.bvi.sw_if_index, + flags=flags, is_add=1) if_ip4 = VppIpInterfaceAddress(self, epg.bvi, epg.bvi_ip4, 32, @@ -889,8 +890,7 @@ class TestGBP(VppTestCase): self.vapi.nat44_interface_add_del_feature( sw_if_index=recirc.recirc.sw_if_index, is_add=1) self.vapi.nat66_add_del_interface( - is_add=1, - sw_if_index=recirc.recirc.sw_if_index) + sw_if_index=recirc.recirc.sw_if_index, is_add=1) recirc.add_vpp_config() @@ -1282,7 +1282,6 @@ class TestGBP(VppTestCase): pkt_inter_epg_220_to_222 * NUM_PKTS, eps[3].itf, str(self.router_mac)) - # # remove both contracts, traffic stops in both directions # @@ -1397,7 +1396,6 @@ class TestGBP(VppTestCase): pkt_inter_epg_220_to_global * NUM_PKTS, self.pg7, eps[0].fip6) - # # From a global address to an EP: OUT2IN # @@ -1477,26 +1475,7 @@ class TestGBP(VppTestCase): # cleanup # self.vapi.nat44_ed_plugin_enable_disable(enable=0) - - for ep in eps: - # del static mappings for each EP from the 10/8 to 11/8 network - flags = self.nat_config_flags.NAT_IS_ADDR_ONLY - self.vapi.nat66_add_del_static_mapping( - local_ip_address=ep.ip6, - external_ip_address=ep.fip6, - vrf_id=0, is_add=0) - - for epg in epgs: - # IP config on the BVI interfaces - if epg != epgs[0] and epg != epgs[3]: - flags = self.nat_config_flags.NAT_IS_INSIDE - self.vapi.nat66_add_del_interface( - sw_if_index=epg.bvi.sw_if_index, - flags=flags, is_add=0) - - for recirc in recircs: - self.vapi.nat66_add_del_interface( - sw_if_index=recirc.recirc.sw_if_index, is_add=0) + self.vapi.nat66_plugin_enable_disable(enable=0) def wait_for_ep_timeout(self, sw_if_index=None, ip=None, mac=None, tep=None, n_tries=100, s_time=1): diff --git a/src/plugins/nat/nat66/nat66.api b/src/plugins/nat/nat66/nat66.api index bbadf07184a..29425c09ce5 100644 --- a/src/plugins/nat/nat66/nat66.api +++ b/src/plugins/nat/nat66/nat66.api @@ -18,6 +18,20 @@ import "vnet/ip/ip_types.api"; import "vnet/interface_types.api"; import "plugins/nat/lib/nat_types.api"; + +/** \brief Enable/disable NAT66 plugin + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param outside_vrf - outside vrf id + @param enable - true if enable, false if disable +*/ +autoreply define nat66_plugin_enable_disable { + u32 client_index; + u32 context; + u32 outside_vrf; + bool enable; +}; + /** \brief Enable/disable NAT66 feature on the interface @param client_index - opaque cookie to identify the sender @param context - sender context, to match reply w/ request diff --git a/src/plugins/nat/nat66/nat66.c b/src/plugins/nat/nat66/nat66.c index a8de3f6e0fa..ff8cace615d 100644 --- a/src/plugins/nat/nat66/nat66.c +++ b/src/plugins/nat/nat66/nat66.c @@ -17,16 +17,12 @@ * @brief NAT66 implementation */ +#include #include #include -#include -#include #include nat66_main_t nat66_main; -fib_source_t nat_fib_src_hi; - -/* *INDENT-OFF* */ /* Hook up input features */ VNET_FEATURE_INIT (nat66_in2out, static) = { @@ -42,39 +38,109 @@ VNET_FEATURE_INIT (nat66_out2in, static) = { .runs_after = VNET_FEATURES ("ip6-sv-reassembly-feature"), }; -/* *INDENT-ON* */ - clib_error_t *nat66_plugin_api_hookup (vlib_main_t * vm); + +#define fail_if_enabled() \ + do \ + { \ + nat66_main_t *nm = &nat66_main; \ + if (PREDICT_FALSE (nm->enabled)) \ + { \ + nat66_elog_warn ("plugin enabled"); \ + return 1; \ + } \ + } \ + while (0) + +#define fail_if_disabled() \ + do \ + { \ + nat66_main_t *nm = &nat66_main; \ + if (PREDICT_FALSE (!nm->enabled)) \ + { \ + nat66_elog_warn ("plugin disabled"); \ + return 1; \ + } \ + } \ + while (0) + static clib_error_t * nat66_init (vlib_main_t * vm) { nat66_main_t *nm = &nat66_main; - vlib_node_t *node; + + clib_memset (nm, 0, sizeof (*nm)); + + nm->session_counters.name = "session counters"; + nm->in2out_packets.name = "in2out"; + nm->in2out_packets.stat_segment_name = "/nat64/in2out"; + nm->out2in_packets.name = "out2in"; + nm->out2in_packets.stat_segment_name = "/nat64/out2in"; + + nm->nat_fib_src_hi = fib_source_allocate ("nat66-hi", FIB_SOURCE_PRIORITY_HI, + FIB_SOURCE_BH_SIMPLE); + return nat66_plugin_api_hookup (vm); +} + +int +nat66_plugin_enable (u32 outside_vrf) +{ + nat66_main_t *nm = &nat66_main; + u32 static_mapping_buckets = 1024; uword static_mapping_memory_size = 64 << 20; - node = vlib_get_node_by_name (vm, (u8 *) "nat66-in2out"); - nm->in2out_node_index = node->index; - - node = vlib_get_node_by_name (vm, (u8 *) "nat66-out2in"); - nm->out2in_node_index = node->index; + fail_if_enabled (); clib_bihash_init_24_8 (&nm->sm_l, "nat66-static-map-by-local", static_mapping_buckets, static_mapping_memory_size); clib_bihash_init_24_8 (&nm->sm_e, "nat66-static-map-by-external", static_mapping_buckets, static_mapping_memory_size); - nm->session_counters.name = "session counters"; + nm->outside_vrf_id = outside_vrf; + nm->outside_fib_index = fib_table_find_or_create_and_lock ( + FIB_PROTOCOL_IP6, outside_vrf, nm->nat_fib_src_hi); + nm->enabled = 1; + return 0; +} - nat_fib_src_hi = fib_source_allocate ("nat66-hi", - FIB_SOURCE_PRIORITY_HI, - FIB_SOURCE_BH_SIMPLE); +int +nat66_plugin_disable () +{ + nat66_main_t *nm = &nat66_main; + nat66_interface_t *i, *temp; + int error = 0; - nm->in2out_packets.name = "in2out"; - nm->in2out_packets.stat_segment_name = "/nat64/in2out"; - nm->out2in_packets.name = "out2in"; - nm->out2in_packets.stat_segment_name = "/nat64/out2in"; - return nat66_plugin_api_hookup (vm); + temp = pool_dup (nm->interfaces); + pool_foreach (i, temp) + { + if (nat66_interface_is_inside (i)) + error = nat66_interface_add_del (i->sw_if_index, 1, 0); + + if (nat66_interface_is_outside (i)) + error = nat66_interface_add_del (i->sw_if_index, 0, 0); + + if (error) + { + nat66_elog_warn ("error occurred while removing interface"); + } + } + pool_free (temp); + pool_free (nm->interfaces); + + pool_free (nm->sm); + clib_bihash_free_24_8 (&nm->sm_l); + clib_bihash_free_24_8 (&nm->sm_e); + + nm->interfaces = 0; + nm->sm = 0; + + vlib_clear_combined_counters (&nm->session_counters); + vlib_clear_simple_counters (&nm->in2out_packets); + vlib_clear_simple_counters (&nm->out2in_packets); + + nm->enabled = 0; + return error; } static void @@ -93,7 +159,8 @@ nat66_interface_add_del (u32 sw_if_index, u8 is_inside, u8 is_add) nat66_interface_t *interface = 0, *i; const char *feature_name; - /* *INDENT-OFF* */ + fail_if_disabled (); + pool_foreach (i, nm->interfaces) { if (i->sw_if_index == sw_if_index) @@ -102,7 +169,6 @@ nat66_interface_add_del (u32 sw_if_index, u8 is_inside, u8 is_add) break; } } - /* *INDENT-ON* */ if (is_add) { @@ -138,13 +204,11 @@ nat66_interfaces_walk (nat66_interface_walk_fn_t fn, void *ctx) nat66_main_t *nm = &nat66_main; nat66_interface_t *i = 0; - /* *INDENT-OFF* */ pool_foreach (i, nm->interfaces) { if (fn (i, ctx)) break; } - /* *INDENT-ON* */ } nat66_static_mapping_t * @@ -182,6 +246,8 @@ nat66_static_mapping_add_del (ip6_address_t * l_addr, ip6_address_t * e_addr, clib_bihash_kv_24_8_t kv, value; u32 fib_index = fib_table_find (FIB_PROTOCOL_IP6, vrf_id); + fail_if_disabled (); + sm_key.addr.as_u64[0] = l_addr->as_u64[0]; sm_key.addr.as_u64[1] = l_addr->as_u64[1]; sm_key.fib_index = fib_index; @@ -199,7 +265,7 @@ nat66_static_mapping_add_del (ip6_address_t * l_addr, ip6_address_t * e_addr, return VNET_API_ERROR_VALUE_EXIST; fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6, vrf_id, - nat_fib_src_hi); + nm->nat_fib_src_hi); pool_get (nm->sm, sm); clib_memset (sm, 0, sizeof (*sm)); sm->l_addr.as_u64[0] = l_addr->as_u64[0]; @@ -243,7 +309,7 @@ nat66_static_mapping_add_del (ip6_address_t * l_addr, ip6_address_t * e_addr, kv.key[2] = sm_key.as_u64[2]; if (clib_bihash_add_del_24_8 (&nm->sm_e, &kv, 0)) nat66_elog_warn ("nat66-static-map-by-external delete key failed"); - fib_table_unlock (sm->fib_index, FIB_PROTOCOL_IP6, nat_fib_src_hi); + fib_table_unlock (sm->fib_index, FIB_PROTOCOL_IP6, nm->nat_fib_src_hi); pool_put (nm->sm, sm); } @@ -256,29 +322,13 @@ nat66_static_mappings_walk (nat66_static_mapping_walk_fn_t fn, void *ctx) nat66_main_t *nm = &nat66_main; nat66_static_mapping_t *sm = 0; - /* *INDENT-OFF* */ pool_foreach (sm, nm->sm) { if (fn (sm, ctx)) break; } - /* *INDENT-ON* */ -} - -/*static*/ void -nat66_config (void) -{ - nat66_main_t *nm = &nat66_main; - u32 outside_ip6_vrf_id = 0; - - nm->outside_vrf_id = outside_ip6_vrf_id; - nm->outside_fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6, - outside_ip6_vrf_id, - nat_fib_src_hi); - } -/* *INDENT-OFF* */ VLIB_PLUGIN_REGISTER () = { .version = VPP_BUILD_VER, @@ -287,8 +337,6 @@ VLIB_PLUGIN_REGISTER () = VLIB_INIT_FUNCTION (nat66_init); -/* *INDENT-ON* */ - /* * fd.io coding-style-patch-verification: ON * diff --git a/src/plugins/nat/nat66/nat66.h b/src/plugins/nat/nat66/nat66.h index 42dd7ca0eb2..17a69234b44 100644 --- a/src/plugins/nat/nat66/nat66.h +++ b/src/plugins/nat/nat66/nat66.h @@ -20,6 +20,7 @@ #define __included_nat66_h__ #include +#include #include typedef struct @@ -48,6 +49,7 @@ typedef struct u32 sw_if_index; u8 flags; } nat66_interface_t; + #define NAT66_INTERFACE_FLAG_IS_INSIDE 1 #define NAT66_INTERFACE_FLAG_IS_OUTSIDE 2 #define nat66_interface_is_inside(i) i->flags & NAT66_INTERFACE_FLAG_IS_INSIDE @@ -65,16 +67,16 @@ typedef struct clib_bihash_24_8_t sm_e; /** Session counters */ vlib_combined_counter_main_t session_counters; - /** node index **/ - u32 in2out_node_index; - u32 out2in_node_index; u32 outside_vrf_id; u32 outside_fib_index; + fib_source_t nat_fib_src_hi; u16 msg_id_base; u8 log_level; + u8 enabled; + vlib_simple_counter_main_t in2out_packets; vlib_simple_counter_main_t out2in_packets;; } nat66_main_t; @@ -114,6 +116,8 @@ nat66_static_mapping_t *nat66_static_mapping_get (ip6_address_t * addr, int nat66_static_mapping_add_del (ip6_address_t * l_addr, ip6_address_t * e_addr, u32 vrf_id, u8 is_add); +int nat66_plugin_enable (u32 outside_vrf); +int nat66_plugin_disable (); #endif /* __included_nat66_h__ */ diff --git a/src/plugins/nat/nat66/nat66_api.c b/src/plugins/nat/nat66/nat66_api.c index 2a2b3cc07ad..470c1fe48fa 100644 --- a/src/plugins/nat/nat66/nat66_api.c +++ b/src/plugins/nat/nat66/nat66_api.c @@ -23,9 +23,23 @@ #define REPLY_MSG_ID_BASE nm->msg_id_base #include -/*************/ -/*** NAT66 ***/ -/*************/ +static void +vl_api_nat66_plugin_enable_disable_t_handler ( + vl_api_nat66_plugin_enable_disable_t *mp) +{ + nat66_main_t *nm = &nat66_main; + vl_api_nat66_plugin_enable_disable_reply_t *rmp; + int rv = 0; + + if (mp->enable) + { + rv = nat66_plugin_enable (ntohl (mp->outside_vrf)); + } + else + rv = nat66_plugin_disable (); + + REPLY_MACRO (VL_API_NAT66_PLUGIN_ENABLE_DISABLE_REPLY); +} static void vl_api_nat66_add_del_interface_t_handler (vl_api_nat66_add_del_interface_t * @@ -96,6 +110,10 @@ static void vl_api_nat66_interface_dump_t_handler (vl_api_nat66_interface_dump_t * mp) { vl_api_registration_t *rp; + nat66_main_t *nm = &nat66_main; + + if (PREDICT_FALSE (!nm->enabled)) + return; rp = vl_api_client_index_to_registration (mp->client_index); if (rp == 0) @@ -145,6 +163,10 @@ vl_api_nat66_static_mapping_dump_t_handler (vl_api_nat66_static_mapping_dump_t * mp) { vl_api_registration_t *rp; + nat66_main_t *nm = &nat66_main; + + if (PREDICT_FALSE (!nm->enabled)) + return; rp = vl_api_client_index_to_registration (mp->client_index); if (rp == 0) @@ -167,8 +189,6 @@ clib_error_t * nat66_plugin_api_hookup (vlib_main_t * vm) { nat66_main_t *nm = &nat66_main; - nm->msg_id_base = setup_message_id_table (); - return 0; } diff --git a/src/plugins/nat/nat66/nat66_cli.c b/src/plugins/nat/nat66/nat66_cli.c index da963877c8a..4ba46cb0b75 100644 --- a/src/plugins/nat/nat66/nat66_cli.c +++ b/src/plugins/nat/nat66/nat66_cli.c @@ -20,6 +20,61 @@ #include #include +static clib_error_t * +nat66_enable_command_fn (vlib_main_t *vm, unformat_input_t *input, + vlib_cli_command_t *cmd) +{ + nat66_main_t *nm = &nat66_main; + unformat_input_t _line_input, *line_input = &_line_input; + clib_error_t *error = 0; + u32 outside_vrf = 0; + + if (nm->enabled) + return clib_error_return (0, "nat66 already enabled"); + + /* Get a line of input. */ + if (!unformat_user (input, unformat_line_input, line_input)) + { + if (nat66_plugin_enable (outside_vrf) != 0) + return clib_error_return (0, "nat66 enable failed"); + return 0; + } + + while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT) + { + if (unformat (line_input, "outside-vrf %u", &outside_vrf)) + ; + else + { + error = clib_error_return (0, "unknown input '%U'", + format_unformat_error, line_input); + goto done; + } + } + + if (nat66_plugin_enable (outside_vrf) != 0) + error = clib_error_return (0, "nat66 enable failed"); +done: + unformat_free (line_input); + return error; +} + +static clib_error_t * +nat66_disable_command_fn (vlib_main_t *vm, unformat_input_t *input, + vlib_cli_command_t *cmd) +{ + nat66_main_t *nm = &nat66_main; + clib_error_t *error = 0; + + if (!nm->enabled) + return clib_error_return (0, "nat66 already disabled"); + + if (nat66_plugin_disable () != 0) + error = clib_error_return (0, "nat66 disable failed"); + + return error; +} + static clib_error_t * nat66_interface_feature_command_fn (vlib_main_t * vm, unformat_input_t * input, @@ -27,6 +82,7 @@ nat66_interface_feature_command_fn (vlib_main_t * vm, { unformat_input_t _line_input, *line_input = &_line_input; vnet_main_t *vnm = vnet_get_main (); + nat66_main_t *nm = &nat66_main; clib_error_t *error = 0; u32 sw_if_index; u32 *inside_sw_if_indices = 0; @@ -34,6 +90,9 @@ nat66_interface_feature_command_fn (vlib_main_t * vm, u8 is_add = 1; int i, rv; + if (!nm->enabled) + return clib_error_return (0, "nat66 disabled"); + /* Get a line of input. */ if (!unformat_user (input, unformat_line_input, line_input)) return 0; @@ -139,7 +198,6 @@ nat66_cli_interface_walk (nat66_interface_t * i, void *ctx) { vlib_main_t *vm = ctx; vnet_main_t *vnm = vnet_get_main (); - vlib_cli_output (vm, " %U %s", format_vnet_sw_interface_name, vnm, vnet_get_sw_interface (vnm, i->sw_if_index), nat66_interface_is_inside (i) ? "in" : "out"); @@ -150,9 +208,11 @@ static clib_error_t * nat66_show_interfaces_command_fn (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { + nat66_main_t *nm = &nat66_main; + if (!nm->enabled) + return clib_error_return (0, "nat66 disabled"); vlib_cli_output (vm, "NAT66 interfaces:"); nat66_interfaces_walk (nat66_cli_interface_walk, vm); - return 0; } @@ -161,6 +221,7 @@ nat66_add_del_static_mapping_command_fn (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { + nat66_main_t *nm = &nat66_main; unformat_input_t _line_input, *line_input = &_line_input; clib_error_t *error = 0; u8 is_add = 1; @@ -168,6 +229,9 @@ nat66_add_del_static_mapping_command_fn (vlib_main_t * vm, u32 vrf_id = 0; int rv; + if (!nm->enabled) + return clib_error_return (0, "nat66 disabled"); + /* Get a line of input. */ if (!unformat_user (input, unformat_line_input, line_input)) return 0; @@ -238,12 +302,44 @@ nat66_show_static_mappings_command_fn (vlib_main_t * vm, unformat_input_t * input, vlib_cli_command_t * cmd) { + nat66_main_t *nm = &nat66_main; + if (!nm->enabled) + return clib_error_return (0, "nat66 disabled"); vlib_cli_output (vm, "NAT66 static mappings:"); nat66_static_mappings_walk (nat66_cli_static_mapping_walk, vm); return 0; } -/* *INDENT-OFF* */ +/*? + * @cliexpar + * @cliexstart{nat66 enable} + * Enable NAT66 plugin + * To enable NAT66 plugin + * vpp# nat66 enable + * To enable NAT66 plugin with outside-vrf id 10 + * vpp# nat66 enable outside-vrf 10 + * @cliexend +?*/ +VLIB_CLI_COMMAND (nat66_enable_command, static) = { + .path = "nat66 enable", + .short_help = "nat66 enable [outside-vrf ]", + .function = nat66_enable_command_fn, +}; + +/*? + * @cliexpar + * @cliexstart{nat66 disable} + * Disable NAT66 plugin + * To disable NAT66 plugin + * vpp# nat66 disable + * @cliexend +?*/ +VLIB_CLI_COMMAND (nat66_disable_command, static) = { + .path = "nat66 disable", + .short_help = "nat66 disable", + .function = nat66_disable_command_fn, +}; + /*? * @cliexpar * @cliexstart{set interface nat66} diff --git a/src/plugins/nat/test/test_nat66.py b/src/plugins/nat/test/test_nat66.py index bd1b50b9ee2..acda72bcdf6 100644 --- a/src/plugins/nat/test/test_nat66.py +++ b/src/plugins/nat/test/test_nat66.py @@ -32,14 +32,7 @@ from vpp_neighbor import VppNeighbor from vpp_papi import VppEnum -class MethodHolder(VppTestCase): - """ NAT create capture and verify method holder """ - @property - def config_flags(self): - return VppEnum.vl_api_nat_config_flags_t - - -class TestNAT66(MethodHolder): +class TestNAT66(VppTestCase): """ NAT66 Test Cases """ @classmethod @@ -47,7 +40,6 @@ class TestNAT66(MethodHolder): super(TestNAT66, cls).setUpClass() cls.nat_addr = 'fd01:ff::2' - cls.create_pg_interfaces(range(2)) cls.interfaces = list(cls.pg_interfaces) @@ -56,9 +48,24 @@ class TestNAT66(MethodHolder): i.config_ip6() i.configure_ipv6_neighbors() - @classmethod - def tearDownClass(cls): - super(TestNAT66, cls).tearDownClass() + @property + def config_flags(self): + return VppEnum.vl_api_nat_config_flags_t + + def plugin_enable(self): + self.vapi.nat66_plugin_enable_disable(enable=1) + + def plugin_disable(self): + self.vapi.nat66_plugin_enable_disable(enable=0) + + def setUp(self): + super(TestNAT66, self).setUp() + self.plugin_enable() + + def tearDown(self): + super(TestNAT66, self).tearDown() + if not self.vpp_dead: + self.plugin_disable() def test_static(self): """ 1:1 NAT66 test """ @@ -167,30 +174,6 @@ class TestNAT66(MethodHolder): self.logger.error(ppp("Unexpected or invalid packet:", packet)) raise - def clear_nat66(self): - """ - Clear NAT66 configuration. - """ - interfaces = self.vapi.nat66_interface_dump() - for intf in interfaces: - self.vapi.nat66_add_del_interface(is_add=0, flags=intf.flags, - sw_if_index=intf.sw_if_index) - - static_mappings = self.vapi.nat66_static_mapping_dump() - for sm in static_mappings: - self.vapi.nat66_add_del_static_mapping( - local_ip_address=sm.local_ip_address, - external_ip_address=sm.external_ip_address, vrf_id=sm.vrf_id, - is_add=0) - - def tearDown(self): - super(TestNAT66, self).tearDown() - self.clear_nat66() - - def show_commands_at_teardown(self): - self.logger.info(self.vapi.cli("show nat66 interfaces")) - self.logger.info(self.vapi.cli("show nat66 static mappings")) - if __name__ == '__main__': unittest.main(testRunner=VppTestRunner) -- cgit 1.2.3-korg