]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[#1621] add disable-dhcp-on-db-loss parameter to configure network state effect
authorRazvan Becheriu <razvan@isc.org>
Thu, 18 Mar 2021 19:58:03 +0000 (21:58 +0200)
committerRazvan Becheriu <razvan@isc.org>
Mon, 29 Mar 2021 18:11:29 +0000 (21:11 +0300)
17 files changed:
doc/examples/kea4/all-keys.json
doc/examples/kea4/mysql-reservations.json
doc/examples/kea4/pgsql-reservations.json
doc/examples/kea6/all-keys.json
doc/examples/kea6/mysql-reservations.json
doc/examples/kea6/pgsql-reservations.json
doc/sphinx/arm/dhcp4-srv.rst
doc/sphinx/arm/dhcp6-srv.rst
src/bin/dhcp4/ctrl_dhcp4_srv.cc
src/bin/dhcp4/dhcp4_lexer.ll
src/bin/dhcp4/dhcp4_parser.yy
src/bin/dhcp6/ctrl_dhcp6_srv.cc
src/bin/dhcp6/dhcp6_lexer.ll
src/bin/dhcp6/dhcp6_parser.yy
src/lib/database/database_connection.cc
src/lib/database/database_connection.h
src/lib/database/dbaccess_parser.cc

index f134e8a55dc695bbfc6a7aeae007a3ae552f9a9d..e73799e7318a64907f365fd16e8ffb7c34d1da22 100644 (file)
                 // Connection maximum reconnect tries.
                 "max-reconnect-tries": 3,
 
+                // Disable DHCP on database connection loss.
+                "disable-dhcp-on-db-loss": true,
+
                 // Connection connect timeout.
                 "connect-timeout": 100,
 
index a03eb077dac95b4119e1caae3e7ddede8fe00ae1..1dddc654e83271de1109d0693a3b3093016020b0 100644 (file)
@@ -59,6 +59,7 @@
     "type": "mysql",
     "reconnect-wait-time": 3000, // expressed in ms
     "max-reconnect-tries": 3,
+    "disable-dhcp-on-db-loss": true,
     "name": "kea",
     "user": "kea",
     "password": "kea",
index 36d9f3ea93a4e525d2afe7321eaebd1bfbd68d75..8efd49043db2fb5862ae61f9107ceaa1c4d424a2 100644 (file)
@@ -61,6 +61,7 @@
        "type": "postgresql",
        "reconnect-wait-time": 3000, // expressed in ms
        "max-reconnect-tries": 3,
+       "disable-dhcp-on-db-loss": true,
        "name": "kea",
        "user": "kea",
        "password": "kea",
index 5108320eed53eafaa895bfc755bd9f3de39bb274..c89697c76c57f35e8681598a48fe780c2659d580 100644 (file)
                 // Connection maximum reconnect tries.
                 "max-reconnect-tries": 3,
 
+                // Disable DHCP on database connection loss.
+                "disable-dhcp-on-db-loss": true,
+
                 // Connection connect timeout.
                 "connect-timeout": 100,
 
index 96ad40a3cf72fa55ab83b56928de1ee9c811ae3a..430308b44becee9be1cc28a5967181632864d0e2 100644 (file)
@@ -46,6 +46,7 @@
     "type": "mysql",
     "reconnect-wait-time": 3000, // expressed in ms
     "max-reconnect-tries": 3,
+    "disable-dhcp-on-db-loss": true,
     "name": "kea",
     "user": "kea",
     "password": "kea",
index 83a430e04e97631447395d9590fe03709f3937fd..c0d323bb8fb3166bc8d2e423a7f07e9bb9f6a2f7 100644 (file)
@@ -48,6 +48,7 @@
        "type": "postgresql",
        "reconnect-wait-time": 3000, // expressed in ms
        "max-reconnect-tries": 3,
+       "disable-dhcp-on-db-loss": true,
        "name": "kea",
        "user": "kea",
        "password": "kea",
index 5f457d6005a982166459e5722b7de2dee4b825bb..95fb595ad0cf3951b95fc94fdb2b40f7bb97a677 100644 (file)
@@ -504,6 +504,13 @@ The default value for MySQL and PostgreSQL is 0, which disables automatic
 recovery and causes the server to exit immediately upon detecting the
 loss of connectivity. The default value for Cassandra is 2000 ms.
 
+::
+
+   "Dhcp4": { "lease-database": { "disable-dhcp-on-db-loss" : true, ... }, ... }
+
+The default value for MySQL and PostgreSQL is true, which disables the dhcp
+service while trying to automatically recover lost connections.
+
 .. note::
 
    Automatic reconnection to database backends is configured
@@ -716,6 +723,11 @@ The default value for MySQL and PostgreSQL is 0, which disables automatic
 recovery and causes the server to exit immediately upon detecting the
 loss of connectivity. The default value for Cassandra is 2000 ms.
 
+   "Dhcp4": { "hosts-database": { "disable-dhcp-on-db-loss" : true, ... }, ... }
+
+The default value for MySQL and PostgreSQL is true, which disables the dhcp
+service while trying to automatically recover lost connections.
+
 .. note::
 
    Automatic reconnection to database backends is configured
index 212ef647497b4269c881fcdb0cbefc3e92b76e86..861b91ffb095bb4f0f306473d7d7122ffa0781ca 100644 (file)
@@ -473,6 +473,11 @@ The default value for MySQL and PostgreSQL is 0, which disables automatic
 recovery and causes the server to exit immediately upon detecting the
 loss of connectivity. The default value for Cassandra is 2000 ms.
 
+   "Dhcp6": { "lease-database": { "disable-dhcp-on-db-loss" : true, ... }, ... }
+
+The default value for MySQL and PostgreSQL is true, which disables the dhcp
+service while trying to automatically recover lost connections.
+
 .. note::
 
    Automatic reconnection to database backends is configured
@@ -635,6 +640,11 @@ The default value for MySQL and PostgreSQL is 0, which disables automatic
 recovery and causes the server to exit immediately upon detecting the
 loss of connectivity. The default value for Cassandra is 2000 ms.
 
+   "Dhcp6": { "hosts-database": { "disable-dhcp-on-db-loss" : true, ... }, ... }
+
+The default value for MySQL and PostgreSQL is true, which disables the dhcp
+service while trying to automatically recover lost connections.
+
 .. note::
 
    Automatic reconnection to database backends is configured
index 77519831db78250c536061415433dcd993ccf305..10951e3fd1671f76cca411ae5d0885e7b3325f20 100644 (file)
@@ -1243,7 +1243,8 @@ ControlledDhcpv4Srv::dbLostCallback(ReconnectCtlPtr db_reconnect_ctl) {
     }
 
     // Disable service until the connection is recovered.
-    if (db_reconnect_ctl->retriesLeft() == db_reconnect_ctl->maxRetries()) {
+    if (db_reconnect_ctl->retriesLeft() == db_reconnect_ctl->maxRetries() &&
+        db_reconnect_ctl->disableDHCP()) {
         network_state_->disableService(NetworkState::Origin::DB_CONNECTION);
     }
 
@@ -1264,17 +1265,19 @@ ControlledDhcpv4Srv::dbLostCallback(ReconnectCtlPtr db_reconnect_ctl) {
 
 bool
 ControlledDhcpv4Srv::dbRecoveredCallback(ReconnectCtlPtr db_reconnect_ctl) {
-    // Enable service after the connection is recovered.
-    network_state_->enableService(NetworkState::Origin::DB_CONNECTION);
-
-    LOG_INFO(dhcp4_logger, DHCP4_DB_RECONNECT_SUCCEEDED);
-
     if (!db_reconnect_ctl) {
         // This should never happen
         LOG_ERROR(dhcp4_logger, DHCP4_DB_RECONNECT_NO_DB_CTL);
         return (false);
     }
 
+    // Enable service after the connection is recovered.
+    if (db_reconnect_ctl->disableDHCP()) {
+        network_state_->enableService(NetworkState::Origin::DB_CONNECTION);
+    }
+
+    LOG_INFO(dhcp4_logger, DHCP4_DB_RECONNECT_SUCCEEDED);
+
     db_reconnect_ctl->resetRetries();
 
     return (true);
index 42972645d529064c4de16b347fee0a7d1c5e40bc..90c0f9dc312a8a335d0646c7b3e16c9dbe076d67 100644 (file)
@@ -527,6 +527,17 @@ ControlCharacterFill            [^"\\]|\\["\\/bfnrtu]
     }
 }
 
+\"disable-dhcp-on-db-loss\" {
+    switch(driver.ctx_) {
+    case isc::dhcp::Parser4Context::LEASE_DATABASE:
+    case isc::dhcp::Parser4Context::HOSTS_DATABASE:
+    case isc::dhcp::Parser4Context::CONFIG_DATABASE:
+        return isc::dhcp::Dhcp4Parser::make_DISABLE_DHCP_ON_DB_LOSS(driver.loc_);
+    default:
+        return isc::dhcp::Dhcp4Parser::make_STRING("disable-dhcp-on-db-loss", driver.loc_);
+    }
+}
+
 \"request-timeout\" {
     switch(driver.ctx_) {
     case isc::dhcp::Parser4Context::LEASE_DATABASE:
index 86594277048e4da7a41e6feb8f8ebf807fcb309e..87f10783b702d652ab845a14d3ad99f8ce1d3bff 100644 (file)
@@ -97,6 +97,7 @@ using namespace std;
   SERIAL_CONSISTENCY "serial-consistency"
   MAX_RECONNECT_TRIES "max-reconnect-tries"
   RECONNECT_WAIT_TIME "reconnect-wait-time"
+  DISABLE_DHCP_ON_DB_LOSS "disable-dhcp-on-db-loss"
   REQUEST_TIMEOUT "request-timeout"
   TCP_KEEPALIVE "tcp-keepalive"
   TCP_NODELAY "tcp-nodelay"
@@ -908,6 +909,7 @@ database_map_param: database_type
                   | contact_points
                   | max_reconnect_tries
                   | reconnect_wait_time
+                  | disable_dhcp_on_db_loss
                   | request_timeout
                   | tcp_keepalive
                   | tcp_nodelay
@@ -1064,6 +1066,12 @@ reconnect_wait_time: RECONNECT_WAIT_TIME COLON INTEGER {
     ctx.stack_.back()->set("reconnect-wait-time", n);
 };
 
+disable_dhcp_on_db_loss: DISABLE_DHCP_ON_DB_LOSS COLON BOOLEAN {
+    ctx.unique("disable-dhcp-on-db-loss", ctx.loc2pos(@1));
+    ElementPtr n(new BoolElement($3, ctx.loc2pos(@3)));
+    ctx.stack_.back()->set("disable-dhcp-on-db-loss", n);
+};
+
 max_row_errors: MAX_ROW_ERRORS COLON INTEGER {
     ctx.unique("max-row-errors", ctx.loc2pos(@1));
     ElementPtr n(new IntElement($3, ctx.loc2pos(@3)));
index 15bf8f3c356d75172afba398869632731c7b4f53..1366e663d5b0ac42f896693d81337128ba4d6290 100644 (file)
@@ -1262,7 +1262,8 @@ ControlledDhcpv6Srv::dbLostCallback(ReconnectCtlPtr db_reconnect_ctl) {
     }
 
     // Disable service until the connection is recovered.
-    if (db_reconnect_ctl->retriesLeft() == db_reconnect_ctl->maxRetries()) {
+    if (db_reconnect_ctl->retriesLeft() == db_reconnect_ctl->maxRetries() &&
+        db_reconnect_ctl->disableDHCP()) {
         network_state_->disableService(NetworkState::Origin::DB_CONNECTION);
     }
 
@@ -1283,17 +1284,19 @@ ControlledDhcpv6Srv::dbLostCallback(ReconnectCtlPtr db_reconnect_ctl) {
 
 bool
 ControlledDhcpv6Srv::dbRecoveredCallback(ReconnectCtlPtr db_reconnect_ctl) {
-    // Enable service after the connection is recovered.
-    network_state_->enableService(NetworkState::Origin::DB_CONNECTION);
-
-    LOG_INFO(dhcp6_logger, DHCP6_DB_RECONNECT_SUCCEEDED);
-
     if (!db_reconnect_ctl) {
         // This should never happen
         LOG_ERROR(dhcp6_logger, DHCP6_DB_RECONNECT_NO_DB_CTL);
         return (false);
     }
 
+    // Enable service after the connection is recovered.
+    if (db_reconnect_ctl->disableDHCP()) {
+        network_state_->enableService(NetworkState::Origin::DB_CONNECTION);
+    }
+
+    LOG_INFO(dhcp6_logger, DHCP6_DB_RECONNECT_SUCCEEDED);
+
     db_reconnect_ctl->resetRetries();
 
     return (true);
index bec1b90aeea2fc2c7a086401569b4fe0bf4ee8c1..16a39b4c939eb39e47016b6962ff7620661d09c6 100644 (file)
@@ -725,6 +725,17 @@ ControlCharacterFill            [^"\\]|\\["\\/bfnrtu]
     }
 }
 
+\"disable-dhcp-on-db-loss\" {
+    switch(driver.ctx_) {
+    case isc::dhcp::Parser6Context::LEASE_DATABASE:
+    case isc::dhcp::Parser6Context::HOSTS_DATABASE:
+    case isc::dhcp::Parser6Context::CONFIG_DATABASE:
+        return isc::dhcp::Dhcp6Parser::make_DISABLE_DHCP_ON_DB_LOSS(driver.loc_);
+    default:
+        return isc::dhcp::Dhcp6Parser::make_STRING("disable-dhcp-on-db-loss", driver.loc_);
+    }
+}
+
 \"request-timeout\" {
     switch(driver.ctx_) {
     case isc::dhcp::Parser6Context::LEASE_DATABASE:
index 825503586f50a6207747bf4d3765b0b86f694bb0..11e9ad4568fedad7c748efe2c2a7c2742cae9a6f 100644 (file)
@@ -79,6 +79,7 @@ using namespace std;
   CONTACT_POINTS "contact-points"
   MAX_RECONNECT_TRIES "max-reconnect-tries"
   RECONNECT_WAIT_TIME "reconnect-wait-time"
+  DISABLE_DHCP_ON_DB_LOSS "disable-dhcp-on-db-loss"
   KEYSPACE "keyspace"
   CONSISTENCY "consistency"
   SERIAL_CONSISTENCY "serial-consistency"
@@ -862,6 +863,7 @@ database_map_param: database_type
                   | contact_points
                   | max_reconnect_tries
                   | reconnect_wait_time
+                  | disable_dhcp_on_db_loss
                   | request_timeout
                   | tcp_keepalive
                   | tcp_nodelay
@@ -958,6 +960,12 @@ reconnect_wait_time: RECONNECT_WAIT_TIME COLON INTEGER {
     ctx.stack_.back()->set("reconnect-wait-time", n);
 };
 
+disable_dhcp_on_db_loss: DISABLE_DHCP_ON_DB_LOSS COLON BOOLEAN {
+    ctx.unique("disable-dhcp-on-db-loss", ctx.loc2pos(@1));
+    ElementPtr n(new BoolElement($3, ctx.loc2pos(@3)));
+    ctx.stack_.back()->set("disable-dhcp-on-db-loss", n);
+};
+
 max_row_errors: MAX_ROW_ERRORS COLON INTEGER {
     ctx.unique("max-row-errors", ctx.loc2pos(@1));
     ElementPtr n(new IntElement($3, ctx.loc2pos(@3)));
index 6ce1f8504a731effeee35d21ba2d8f691be264d5..38ca41b25f48bee532307ec9d380020e3ece0cde 100644 (file)
@@ -175,8 +175,16 @@ DatabaseConnection::makeReconnectCtl(const std::string& timer_name) {
         // Wasn't specified so we'll use default of 0;
     }
 
+    bool disable_dhcp = true;
+    try {
+        parm_str = getParameter("disable-dhcp-on-db-loss");
+        disable_dhcp = boost::lexical_cast<bool>(parm_str);
+    } catch (...) {
+        // Wasn't specified so we'll use default of true;
+    }
+
     reconnect_ctl_ = boost::make_shared<ReconnectCtl>(type, timer_name, retries,
-                                                      interval);
+                                                      interval, disable_dhcp);
 }
 
 bool
@@ -233,7 +241,8 @@ DatabaseConnection::toElement(const ParameterMap& params) {
             }
         } else if ((keyword == "persist") ||
                    (keyword == "tcp-nodelay") ||
-                   (keyword == "readonly")) {
+                   (keyword == "readonly") ||
+                   (keyword == "disable-dhcp-on-db-loss")) {
             if (value == "true") {
                 result->set(keyword, isc::data::Element::create(true));
             } else if (value == "false") {
index 1dd6eb7c4f9b25a52bfb71a5028630cf89962998..5ae2b2209de549aa888aecddd762d63ce037c1bd 100644 (file)
@@ -92,10 +92,11 @@ public:
     /// @param max_retries maximum number of reconnect attempts to make
     /// @param retry_interval amount of time to between reconnect attempts
     ReconnectCtl(const std::string& backend_type, const std::string& timer_name,
-                 unsigned int max_retries, unsigned int retry_interval)
-        : backend_type_(backend_type), timer_name_(timer_name),
-          max_retries_(max_retries), retries_left_(max_retries),
-          retry_interval_(retry_interval) {}
+                 unsigned int max_retries, unsigned int retry_interval,
+                 bool disable_dhcp) : backend_type_(backend_type),
+          timer_name_(timer_name), max_retries_(max_retries),
+          retries_left_(max_retries), retry_interval_(retry_interval),
+          disable_dhcp_(disable_dhcp) {}
 
     /// @brief Returns the type of the caller backend.
     std::string backendType() const {
@@ -137,6 +138,12 @@ public:
         retries_left_ = max_retries_;
     }
 
+    /// @brief Return the flag which indicates if the connection loss should
+    /// disable the dhcp service.
+    bool disableDHCP() {
+        return (disable_dhcp_);
+    }
+
 private:
 
     /// @brief Caller backend type.
@@ -153,6 +160,10 @@ private:
 
     /// @brief The amount of time to wait between reconnect attempts
     unsigned int retry_interval_;
+
+    /// @brief Flag which indicates if the connection loss should disable the
+    /// dhcp service.
+    bool disable_dhcp_;
 };
 
 /// @brief Pointer to an instance of ReconnectCtl
index 694858349e3a4d3760341f2fa00ed9a3bc43e4f3..c4b442a16e9a773a1798e87bdfeac0a42f10752d 100644 (file)
@@ -61,7 +61,8 @@ DbAccessParser::parse(std::string& access_string,
         try {
             if ((param.first == "persist") ||
                 (param.first == "tcp-nodelay") ||
-                (param.first == "readonly")) {
+                (param.first == "readonly") ||
+                (param.first == "disable-dhcp-on-db-loss")) {
                 values_copy[param.first] = (param.second->boolValue() ?
                                             "true" : "false");
 
@@ -217,14 +218,6 @@ DbAccessParser::parse(std::string& access_string,
                   << "(" << value->getPosition() << ")");
     }
 
-    if ((reconnect_wait_time < 0) ||
-        (reconnect_wait_time > std::numeric_limits<uint32_t>::max())) {
-        ConstElementPtr value = database_config->get("reconnect-wait-time");
-        isc_throw(DbConfigError, "reconnect-wait-time " << reconnect_wait_time
-                  << " must be in range 0...MAX_UINT32 (4294967295) "
-                  << "(" << value->getPosition() << ")");
-    }
-
     // Check that tcp_keepalive value makes sense.
     if ((tcp_keepalive < 0) ||
         (tcp_keepalive > std::numeric_limits<uint32_t>::max())) {