cnat: Disable default scanner process 27/29027/2
authorNathan Skrzypczak <nathan.skrzypczak@gmail.com>
Wed, 23 Sep 2020 08:43:16 +0000 (10:43 +0200)
committerOle Tr�an <otroan@employees.org>
Wed, 23 Sep 2020 12:02:12 +0000 (12:02 +0000)
Type: feature

Change-Id: Iba9d9f384eaa35c5522e828e3cbe4516416294db
Signed-off-by: Nathan Skrzypczak <nathan.skrzypczak@gmail.com>
src/plugins/cnat/cnat_api.c
src/plugins/cnat/cnat_scanner.c
src/plugins/cnat/cnat_scanner.h [new file with mode: 0644]
src/plugins/cnat/cnat_snat.c
src/plugins/cnat/cnat_translation.c
src/plugins/cnat/cnat_types.c
src/plugins/cnat/cnat_types.h
src/plugins/cnat/test/test_cnat.py

index 014f75c..2049d44 100644 (file)
@@ -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);
 
index f5af327..d0ed5e3 100644 (file)
 #include <cnat/cnat_session.h>
 #include <cnat/cnat_client.h>
 
-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 (file)
index 0000000..54dbf9c
--- /dev/null
@@ -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 <vnet/ip/ip.h>
+
+/* 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
index f3951cb..86fac12 100644 (file)
@@ -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;
index f680a16..e453b8a 100644 (file)
@@ -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);
index 1f2287e..ae485a4 100644 (file)
@@ -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))
index d81548d..ab59aaf 100644 (file)
@@ -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
 */
index 7a5dc7f..518d733 100644 (file)
@@ -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)