From d63f73b8393b086d21a5197d1e02fac243867a93 Mon Sep 17 00:00:00 2001 From: Nathan Skrzypczak Date: Wed, 23 Sep 2020 10:43:16 +0200 Subject: [PATCH] cnat: Disable default scanner process Type: feature Change-Id: Iba9d9f384eaa35c5522e828e3cbe4516416294db Signed-off-by: Nathan Skrzypczak --- src/plugins/cnat/cnat_api.c | 2 ++ src/plugins/cnat/cnat_scanner.c | 22 +++++++++++++--------- src/plugins/cnat/cnat_scanner.h | 33 +++++++++++++++++++++++++++++++++ src/plugins/cnat/cnat_snat.c | 2 ++ src/plugins/cnat/cnat_translation.c | 2 ++ src/plugins/cnat/cnat_types.c | 23 +++++++++++++++++++++++ src/plugins/cnat/cnat_types.h | 26 ++++++++++++++++++++++++++ src/plugins/cnat/test/test_cnat.py | 34 +++++++++++++++++++--------------- 8 files changed, 120 insertions(+), 24 deletions(-) create mode 100644 src/plugins/cnat/cnat_scanner.h diff --git a/src/plugins/cnat/cnat_api.c b/src/plugins/cnat/cnat_api.c index 014f75c8682..2049d440d46 100644 --- a/src/plugins/cnat/cnat_api.c +++ b/src/plugins/cnat/cnat_api.c @@ -265,6 +265,8 @@ vl_api_cnat_set_snat_addresses_t_handler (vl_api_cnat_set_snat_addresses_t vl_api_cnat_set_snat_addresses_reply_t *rmp; int rv = 0; + cnat_lazy_init (); + ip4_address_decode (mp->snat_ip4, &cnat_main.snat_ip4); ip6_address_decode (mp->snat_ip6, &cnat_main.snat_ip6); diff --git a/src/plugins/cnat/cnat_scanner.c b/src/plugins/cnat/cnat_scanner.c index f5af327bffe..d0ed5e318a3 100644 --- a/src/plugins/cnat/cnat_scanner.c +++ b/src/plugins/cnat/cnat_scanner.c @@ -16,12 +16,6 @@ #include #include -typedef enum cnat_scanner_cmd_t_ -{ - CNAT_SCANNER_OFF, - CNAT_SCANNER_ON, -} cnat_scanner_cmd_t; - static uword cnat_scanner_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f) @@ -29,7 +23,7 @@ cnat_scanner_process (vlib_main_t * vm, uword event_type, *event_data = 0; cnat_main_t *cm = &cnat_main; f64 start_time; - int enabled = 1, i = 0; + int enabled = 0, i = 0; while (1) { @@ -90,8 +84,7 @@ cnat_scanner_cmd (vlib_main_t * vm, return (clib_error_return (0, "unknown input '%U'", format_unformat_error, input)); } - - vlib_process_signal_event (vm, cnat_scanner_process_node.index, cmd, 0); + cnat_enable_disable_scanner (cmd); return (NULL); } @@ -104,6 +97,17 @@ VLIB_CLI_COMMAND (cnat_scanner_cmd_node, static) = { }; /* *INDENT-ON* */ +static clib_error_t * +cnat_scanner_init (vlib_main_t * vm) +{ + cnat_main_t *cm = &cnat_main; + cm->scanner_node_index = cnat_scanner_process_node.index; + + return (NULL); +} + +VLIB_INIT_FUNCTION (cnat_scanner_init); + /* * fd.io coding-style-patch-verification: ON * diff --git a/src/plugins/cnat/cnat_scanner.h b/src/plugins/cnat/cnat_scanner.h new file mode 100644 index 00000000000..54dbf9cca05 --- /dev/null +++ b/src/plugins/cnat/cnat_scanner.h @@ -0,0 +1,33 @@ +/* + * 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 __CNAT_SCANNER_H__ +#define __CNAT_SCANNER_H__ + +#include + +/* delay in seconds between two scans of session/clients tables */ +extern f64 cnat_scanner_timeout; + + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ + +#endif diff --git a/src/plugins/cnat/cnat_snat.c b/src/plugins/cnat/cnat_snat.c index f3951cb7244..86fac126226 100644 --- a/src/plugins/cnat/cnat_snat.c +++ b/src/plugins/cnat/cnat_snat.c @@ -123,6 +123,8 @@ cnat_set_snat (vlib_main_t * vm, clib_error_t *e = 0; ip_address_t addr; + cnat_lazy_init (); + /* Get a line of input. */ if (!unformat_user (input, unformat_line_input, line_input)) return 0; diff --git a/src/plugins/cnat/cnat_translation.c b/src/plugins/cnat/cnat_translation.c index f680a162ec8..e453b8a0fda 100644 --- a/src/plugins/cnat/cnat_translation.c +++ b/src/plugins/cnat/cnat_translation.c @@ -147,6 +147,8 @@ cnat_translation_update (const cnat_endpoint_t * vip, cnat_ep_trk_t *trk; index_t cci; + cnat_lazy_init (); + /* do we know of this ep's vip */ cci = cnat_client_add (&vip->ce_ip, flags); cc = cnat_client_get (cci); diff --git a/src/plugins/cnat/cnat_types.c b/src/plugins/cnat/cnat_types.c index 1f2287e1de3..ae485a48d79 100644 --- a/src/plugins/cnat/cnat_types.c +++ b/src/plugins/cnat/cnat_types.c @@ -88,6 +88,23 @@ cnat_types_init (vlib_main_t * vm) return (NULL); } +void +cnat_enable_disable_scanner (cnat_scanner_cmd_t event_type) +{ + vlib_main_t *vm = vlib_get_main (); + vlib_process_signal_event (vm, cnat_main.scanner_node_index, event_type, 0); +} + +void +cnat_lazy_init () +{ + cnat_main_t *cm = &cnat_main; + if (cm->lazy_init_done) + return; + cnat_enable_disable_scanner (cm->default_scanner_state); + cm->lazy_init_done = 1; +} + static clib_error_t * cnat_config (vlib_main_t * vm, unformat_input_t * input) { @@ -102,6 +119,8 @@ cnat_config (vlib_main_t * vm, unformat_input_t * input) cm->scanner_timeout = CNAT_DEFAULT_SCANNER_TIMEOUT; cm->session_max_age = CNAT_DEFAULT_SESSION_MAX_AGE; cm->tcp_max_age = CNAT_DEFAULT_TCP_MAX_AGE; + cm->default_scanner_state = CNAT_SCANNER_ON; + cm->lazy_init_done = 0; while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { @@ -125,6 +144,10 @@ cnat_config (vlib_main_t * vm, unformat_input_t * input) else if (unformat (input, "session-cleanup-timeout %f", &cm->scanner_timeout)) ; + else if (unformat (input, "scanner off")) + cm->default_scanner_state = CNAT_SCANNER_OFF; + else if (unformat (input, "scanner on")) + cm->default_scanner_state = CNAT_SCANNER_ON; else if (unformat (input, "session-max-age %u", &cm->session_max_age)) ; else if (unformat (input, "tcp-max-age %u", &cm->tcp_max_age)) diff --git a/src/plugins/cnat/cnat_types.h b/src/plugins/cnat/cnat_types.h index d81548d0c30..ab59aaf2f37 100644 --- a/src/plugins/cnat/cnat_types.h +++ b/src/plugins/cnat/cnat_types.h @@ -127,6 +127,15 @@ typedef struct cnat_main_ /* Longest prefix Match table for source NATing */ cnat_snat_pfx_table_t snat_pfx_table; + + /* Index of the scanner process node */ + uword scanner_node_index; + + /* Did we do lazy init ? */ + u8 lazy_init_done; + + /* Enable or Disable the scanner on startup */ + u8 default_scanner_state; } cnat_main_t; typedef struct cnat_timestamp_t_ @@ -167,6 +176,23 @@ typedef enum CNAT_N_ERROR, } cnat_error_t; +typedef enum cnat_scanner_cmd_t_ +{ + CNAT_SCANNER_OFF, + CNAT_SCANNER_ON, +} cnat_scanner_cmd_t; + +/** + * Lazy initialization when first adding a translation + * or using snat + */ +extern void cnat_lazy_init (); + +/** + * Enable/Disable session cleanup + */ +extern void cnat_enable_disable_scanner (cnat_scanner_cmd_t event_type); + /* Dataplane functions */ diff --git a/src/plugins/cnat/test/test_cnat.py b/src/plugins/cnat/test/test_cnat.py index 7a5dc7ff517..518d7335edc 100644 --- a/src/plugins/cnat/test/test_cnat.py +++ b/src/plugins/cnat/test/test_cnat.py @@ -135,7 +135,7 @@ class VppCNATSourceNat(VppObject): def cnat_exclude_subnet(self, exclude_subnet, isAdd=True): add = 1 if isAdd else 0 self._test.vapi.cnat_add_del_snat_prefix( - prefix=exclude_subnet, is_add=add) + prefix=exclude_subnet, is_add=add) def query_vpp_config(self): return False @@ -147,8 +147,11 @@ class VppCNATSourceNat(VppObject): class TestCNatTranslation(VppTestCase): """ CNat Translation """ extra_vpp_punt_config = ["cnat", "{", + "session-db-buckets", "64", + "session-cleanup-timeout", "0.1", "session-max-age", "1", - "tcp-max-age", "1", "}"] + "tcp-max-age", "1", + "scanner", "off", "}"] @classmethod def setUpClass(cls): @@ -358,7 +361,7 @@ class TestCNatTranslation(VppTestCase): self.logger.info(self.vapi.cli("sh cnat session verbose")) # - # turn the scanner back on and wait untill the sessions + # turn the scanner back on and wait until the sessions # all disapper # self.vapi.cli("test cnat scanner on") @@ -502,9 +505,9 @@ class TestCNatSourceNAT(VppTestCase): Raw()) rxs = self.send_and_expect( - self.pg0, - p1 * N_PKTS, - self.pg1) + self.pg0, + p1 * N_PKTS, + self.pg1) for rx in rxs: self.assert_packet_checksums_valid(rx) self.assertEqual( @@ -526,9 +529,9 @@ class TestCNatSourceNAT(VppTestCase): Raw()) rxs = self.send_and_expect( - self.pg1, - p2 * N_PKTS, - self.pg0) + self.pg1, + p2 * N_PKTS, + self.pg0) for rx in rxs: self.assert_packet_checksums_valid(rx) @@ -550,9 +553,9 @@ class TestCNatSourceNAT(VppTestCase): self.vapi.cnat_session_purge() rxs = self.send_and_expect( - self.pg0, - p1 * N_PKTS, - self.pg1) + self.pg0, + p1 * N_PKTS, + self.pg1) for rx in rxs: self.assert_packet_checksums_valid(rx) self.assertEqual( @@ -568,9 +571,9 @@ class TestCNatSourceNAT(VppTestCase): self.vapi.cnat_session_purge() rxs = self.send_and_expect( - self.pg0, - p1 * N_PKTS, - self.pg1) + self.pg0, + p1 * N_PKTS, + self.pg1) for rx in rxs: self.assert_packet_checksums_valid(rx) @@ -592,5 +595,6 @@ class TestCNatSourceNAT(VppTestCase): self.cnat_test_sourcenat(self.pg2.remote_hosts[0].ip4, TCP) self.cnat_test_sourcenat(self.pg2.remote_hosts[0].ip4, UDP) + if __name__ == '__main__': unittest.main(testRunner=VppTestRunner) -- 2.16.6