diff --git a/CHANGES b/CHANGES index 87a1cbaa63..edd4233b05 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,8 @@ +5894. [func] Avoid periodic interface re-scans on Linux by + default, where a reliable event-based mechanism for + detecting interface state changes is available. + [GL #3064] + 5893. [func] Add TLS session resumption support to the client-side TLS code. [GL !6274] diff --git a/bin/named/server.c b/bin/named/server.c index 7d6840f4ca..49ec7cb4f6 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -8981,13 +8981,18 @@ load_configuration(const char *filename, named_server_t *server, result = named_config_get(maps, "interface-interval", &obj); INSIST(result == ISC_R_SUCCESS); interface_interval = cfg_obj_asduration(obj); - if (interface_interval == 0) { - CHECK(isc_timer_reset(server->interface_timer, - isc_timertype_inactive, NULL, true)); - } else if (server->interface_interval != interface_interval) { - isc_interval_set(&interval, interface_interval, 0); - CHECK(isc_timer_reset(server->interface_timer, - isc_timertype_ticker, &interval, false)); + + if (server->interface_timer != NULL) { + if (interface_interval == 0) { + CHECK(isc_timer_reset(server->interface_timer, + isc_timertype_inactive, NULL, + true)); + } else if (server->interface_interval != interface_interval) { + isc_interval_set(&interval, interface_interval, 0); + CHECK(isc_timer_reset(server->interface_timer, + isc_timertype_ticker, &interval, + false)); + } } server->interface_interval = interface_interval; @@ -9824,8 +9829,23 @@ run_server(isc_task_t *task, isc_event_t *event) { &server->interfacemgr), "creating interface manager"); - isc_timer_create(named_g_timermgr, server->task, interface_timer_tick, - server, &server->interface_timer); + /* + * In some cases the user might expect a certain behaviour from + * the rescan timer, let's try to deduce that from the + * configuration options. + */ + if ((ns_interfacemgr_dynamic_updates_are_reliable() && + server->interface_auto) || + (server->interface_interval == 0)) + { + isc_log_write(named_g_lctx, NAMED_LOGCATEGORY_GENERAL, + NAMED_LOGMODULE_SERVER, ISC_LOG_INFO, + "Disabling periodic interface re-scans timer"); + } else { + isc_timer_create(named_g_timermgr, server->task, + interface_timer_tick, server, + &server->interface_timer); + } isc_timer_create(named_g_timermgr, server->task, heartbeat_timer_tick, server, &server->heartbeat_timer); @@ -9926,7 +9946,9 @@ shutdown_server(isc_task_t *task, isc_event_t *event) { isc_mem_put(server->mctx, nsc, sizeof(*nsc)); } - isc_timer_destroy(&server->interface_timer); + if (server->interface_timer != NULL) { + isc_timer_destroy(&server->interface_timer); + } isc_timer_destroy(&server->heartbeat_timer); isc_timer_destroy(&server->pps_timer); isc_timer_destroy(&server->tat_timer); diff --git a/lib/ns/include/ns/interfacemgr.h b/lib/ns/include/ns/interfacemgr.h index 8bd9610103..dac165da65 100644 --- a/lib/ns/include/ns/interfacemgr.h +++ b/lib/ns/include/ns/interfacemgr.h @@ -190,3 +190,11 @@ ns_interfacemgr_getclientmgr(ns_interfacemgr_t *mgr); * Returns the client manager for the current worker thread. * (This cannot be run from outside a network manager thread.) */ + +bool +ns_interfacemgr_dynamic_updates_are_reliable(void); +/*%< + * Returns 'true' if periodic interface re-scans timer should be + * disabled. That is the case on the platforms where kernel-based + * mechanisms for tracking networking interface states is reliable enough. + */ diff --git a/lib/ns/interfacemgr.c b/lib/ns/interfacemgr.c index 7b5093e13b..90268e94e4 100644 --- a/lib/ns/interfacemgr.c +++ b/lib/ns/interfacemgr.c @@ -1379,3 +1379,17 @@ ns_interfacemgr_getclientmgr(ns_interfacemgr_t *mgr) { return (mgr->clientmgrs[tid]); } + +bool +ns_interfacemgr_dynamic_updates_are_reliable(void) { +#if defined(LINUX_NETLINK_AVAILABLE) + /* + * Let's disable periodic interface rescans on Linux, as there a + * reliable kernel-based mechanism for tracking interface state + * changes is available. + */ + return (true); +#else + return (false); +#endif /* LINUX_NETLINK_AVAILABLE */ +}