From: Razvan Becheriu Date: Thu, 18 Mar 2021 19:58:03 +0000 (+0200) Subject: [#1621] add disable-dhcp-on-db-loss parameter to configure network state effect X-Git-Tag: Kea-1.9.6~23 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bb87d031475fc9976fbde383189c178265f2da30;p=thirdparty%2Fkea.git [#1621] add disable-dhcp-on-db-loss parameter to configure network state effect --- diff --git a/doc/examples/kea4/all-keys.json b/doc/examples/kea4/all-keys.json index f134e8a55d..e73799e731 100644 --- a/doc/examples/kea4/all-keys.json +++ b/doc/examples/kea4/all-keys.json @@ -367,6 +367,9 @@ // 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, diff --git a/doc/examples/kea4/mysql-reservations.json b/doc/examples/kea4/mysql-reservations.json index a03eb077da..1dddc654e8 100644 --- a/doc/examples/kea4/mysql-reservations.json +++ b/doc/examples/kea4/mysql-reservations.json @@ -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", diff --git a/doc/examples/kea4/pgsql-reservations.json b/doc/examples/kea4/pgsql-reservations.json index 36d9f3ea93..8efd49043d 100644 --- a/doc/examples/kea4/pgsql-reservations.json +++ b/doc/examples/kea4/pgsql-reservations.json @@ -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", diff --git a/doc/examples/kea6/all-keys.json b/doc/examples/kea6/all-keys.json index 5108320eed..c89697c76c 100644 --- a/doc/examples/kea6/all-keys.json +++ b/doc/examples/kea6/all-keys.json @@ -309,6 +309,9 @@ // 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, diff --git a/doc/examples/kea6/mysql-reservations.json b/doc/examples/kea6/mysql-reservations.json index 96ad40a3cf..430308b44b 100644 --- a/doc/examples/kea6/mysql-reservations.json +++ b/doc/examples/kea6/mysql-reservations.json @@ -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", diff --git a/doc/examples/kea6/pgsql-reservations.json b/doc/examples/kea6/pgsql-reservations.json index 83a430e04e..c0d323bb8f 100644 --- a/doc/examples/kea6/pgsql-reservations.json +++ b/doc/examples/kea6/pgsql-reservations.json @@ -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", diff --git a/doc/sphinx/arm/dhcp4-srv.rst b/doc/sphinx/arm/dhcp4-srv.rst index 5f457d6005..95fb595ad0 100644 --- a/doc/sphinx/arm/dhcp4-srv.rst +++ b/doc/sphinx/arm/dhcp4-srv.rst @@ -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 diff --git a/doc/sphinx/arm/dhcp6-srv.rst b/doc/sphinx/arm/dhcp6-srv.rst index 212ef64749..861b91ffb0 100644 --- a/doc/sphinx/arm/dhcp6-srv.rst +++ b/doc/sphinx/arm/dhcp6-srv.rst @@ -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 diff --git a/src/bin/dhcp4/ctrl_dhcp4_srv.cc b/src/bin/dhcp4/ctrl_dhcp4_srv.cc index 77519831db..10951e3fd1 100644 --- a/src/bin/dhcp4/ctrl_dhcp4_srv.cc +++ b/src/bin/dhcp4/ctrl_dhcp4_srv.cc @@ -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); diff --git a/src/bin/dhcp4/dhcp4_lexer.ll b/src/bin/dhcp4/dhcp4_lexer.ll index 42972645d5..90c0f9dc31 100644 --- a/src/bin/dhcp4/dhcp4_lexer.ll +++ b/src/bin/dhcp4/dhcp4_lexer.ll @@ -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: diff --git a/src/bin/dhcp4/dhcp4_parser.yy b/src/bin/dhcp4/dhcp4_parser.yy index 8659427704..87f10783b7 100644 --- a/src/bin/dhcp4/dhcp4_parser.yy +++ b/src/bin/dhcp4/dhcp4_parser.yy @@ -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))); diff --git a/src/bin/dhcp6/ctrl_dhcp6_srv.cc b/src/bin/dhcp6/ctrl_dhcp6_srv.cc index 15bf8f3c35..1366e663d5 100644 --- a/src/bin/dhcp6/ctrl_dhcp6_srv.cc +++ b/src/bin/dhcp6/ctrl_dhcp6_srv.cc @@ -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); diff --git a/src/bin/dhcp6/dhcp6_lexer.ll b/src/bin/dhcp6/dhcp6_lexer.ll index bec1b90aee..16a39b4c93 100644 --- a/src/bin/dhcp6/dhcp6_lexer.ll +++ b/src/bin/dhcp6/dhcp6_lexer.ll @@ -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: diff --git a/src/bin/dhcp6/dhcp6_parser.yy b/src/bin/dhcp6/dhcp6_parser.yy index 825503586f..11e9ad4568 100644 --- a/src/bin/dhcp6/dhcp6_parser.yy +++ b/src/bin/dhcp6/dhcp6_parser.yy @@ -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))); diff --git a/src/lib/database/database_connection.cc b/src/lib/database/database_connection.cc index 6ce1f8504a..38ca41b25f 100644 --- a/src/lib/database/database_connection.cc +++ b/src/lib/database/database_connection.cc @@ -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(parm_str); + } catch (...) { + // Wasn't specified so we'll use default of true; + } + reconnect_ctl_ = boost::make_shared(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") { diff --git a/src/lib/database/database_connection.h b/src/lib/database/database_connection.h index 1dd6eb7c4f..5ae2b2209d 100644 --- a/src/lib/database/database_connection.h +++ b/src/lib/database/database_connection.h @@ -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 diff --git a/src/lib/database/dbaccess_parser.cc b/src/lib/database/dbaccess_parser.cc index 694858349e..c4b442a16e 100644 --- a/src/lib/database/dbaccess_parser.cc +++ b/src/lib/database/dbaccess_parser.cc @@ -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::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::max())) {