diff --git a/man/NetworkManager-dispatcher.xml b/man/NetworkManager-dispatcher.xml index 036b3c8dcc..e87226d05e 100644 --- a/man/NetworkManager-dispatcher.xml +++ b/man/NetworkManager-dispatcher.xml @@ -68,8 +68,9 @@ device an operation just happened on, and second the action. For device actions, the interface is the name of the kernel interface suitable for IP configuration. Thus it is either VPN_IP_IFACE, DEVICE_IP_IFACE, or DEVICE_IFACE, as applicable. - For the hostname action the device name is always "none" - and for connectivity-change it is empty. + For the hostname action the device name is always "none". + For connectivity-change it is empty. + For dns-change it is empty. The actions are: @@ -170,6 +171,16 @@ The connection was reapplied on the device. + + dns-change + + The DNS configuration has changed. This action is raised even if + NetworkManager is configured to not manage resolv.conf (for example, + via dns=none). In such case, the dispatch script can discover the + DNS configuration provided by currently active connections by + looking at file /run/NetworkManager/resolv.conf + + The environment contains more information about the interface and the connection. diff --git a/src/core/nm-dispatcher.c b/src/core/nm-dispatcher.c index cdc07dd60e..9aa4194e83 100644 --- a/src/core/nm-dispatcher.c +++ b/src/core/nm-dispatcher.c @@ -50,6 +50,8 @@ } \ G_STMT_END +static gboolean nm_dispatcher_need_device(NMDispatcherAction action); + /*****************************************************************************/ struct NMDispatcherCallId { @@ -469,7 +471,8 @@ static const char *action_table[] = {[NM_DISPATCHER_ACTION_HOSTNAME] = NMD_ [NM_DISPATCHER_ACTION_DHCP_CHANGE_6] = NMD_ACTION_DHCP6_CHANGE, [NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE] = NMD_ACTION_CONNECTIVITY_CHANGE, - [NM_DISPATCHER_ACTION_REAPPLY] = NMD_ACTION_REAPPLY}; + [NM_DISPATCHER_ACTION_REAPPLY] = NMD_ACTION_REAPPLY, + [NM_DISPATCHER_ACTION_DNS_CHANGE] = NMD_ACTION_DNS_CHANGE}; static const char * action_to_string(NMDispatcherAction action) @@ -530,9 +533,7 @@ _dispatcher_call(NMDispatcherAction action, if (G_UNLIKELY(!request_id)) request_id = ++gl.request_id_counter; - /* All actions except 'hostname' and 'connectivity-change' require a device */ - if (action == NM_DISPATCHER_ACTION_HOSTNAME - || action == NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE) { + if (!nm_dispatcher_need_device(action)) { _LOG2D(request_id, log_ifname, log_con_uuid, @@ -592,9 +593,8 @@ _dispatcher_call(NMDispatcherAction action, g_variant_builder_init(&vpn_ip4_props, G_VARIANT_TYPE_VARDICT); g_variant_builder_init(&vpn_ip6_props, G_VARIANT_TYPE_VARDICT); - /* hostname and connectivity-change actions don't send device data */ - if (action != NM_DISPATCHER_ACTION_HOSTNAME - && action != NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE) { + /* hostname, DNS and connectivity-change actions don't send device data */ + if (nm_dispatcher_need_device(action)) { fill_device_props(device, &device_props, &device_proxy_props, @@ -925,6 +925,30 @@ nm_dispatcher_call_connectivity(NMConnectivityState connectivity_state, out_call_id); } +/** + * nm_dispatcher_call_dns_change(): + * + * This method does not block the caller. + * + * Returns: %TRUE if the action was dispatched, %FALSE on failure + */ +gboolean +nm_dispatcher_call_dns_change(void) +{ + return _dispatcher_call(NM_DISPATCHER_ACTION_DNS_CHANGE, + FALSE, + NULL, + NULL, + NULL, + FALSE, + NM_CONNECTIVITY_UNKNOWN, + NULL, + NULL, + NULL, + NULL, + NULL); +} + void nm_dispatcher_call_cancel(NMDispatcherCallId *call_id) { @@ -937,3 +961,16 @@ nm_dispatcher_call_cancel(NMDispatcherCallId *call_id) _LOG3D(call_id, "cancelling dispatcher callback action"); call_id->callback = NULL; } + +/* All actions except 'hostname', 'connectivity-change' and 'dns-change' require + * a device */ +static gboolean +nm_dispatcher_need_device(NMDispatcherAction action) +{ + if (action == NM_DISPATCHER_ACTION_HOSTNAME + || action == NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE + || action == NM_DISPATCHER_ACTION_DNS_CHANGE) { + return FALSE; + } + return TRUE; +} diff --git a/src/core/nm-dispatcher.h b/src/core/nm-dispatcher.h index 3071639922..a1cb96b798 100644 --- a/src/core/nm-dispatcher.h +++ b/src/core/nm-dispatcher.h @@ -23,6 +23,7 @@ typedef enum { NM_DISPATCHER_ACTION_DHCP_CHANGE_6, NM_DISPATCHER_ACTION_CONNECTIVITY_CHANGE, NM_DISPATCHER_ACTION_REAPPLY, + NM_DISPATCHER_ACTION_DNS_CHANGE, } NMDispatcherAction; #define NM_DISPATCHER_ACTION_DHCP_CHANGE_X(IS_IPv4) \ @@ -69,6 +70,8 @@ gboolean nm_dispatcher_call_connectivity(NMConnectivityState state, gpointer user_data, NMDispatcherCallId **out_call_id); +gboolean nm_dispatcher_call_dns_change(void); + void nm_dispatcher_call_cancel(NMDispatcherCallId *call_id); #endif /* __NM_DISPATCHER_H__ */ diff --git a/src/core/nm-policy.c b/src/core/nm-policy.c index 1cf6b3398d..2873847df3 100644 --- a/src/core/nm-policy.c +++ b/src/core/nm-policy.c @@ -2642,6 +2642,8 @@ dns_config_changed(NMDnsManager *dns_manager, gpointer user_data) update_system_hostname(self, "DNS configuration changed"); } + + nm_dispatcher_call_dns_change(); } static void diff --git a/src/libnm-core-aux-extern/nm-dispatcher-api.h b/src/libnm-core-aux-extern/nm-dispatcher-api.h index 56da5fba7a..7cb370a92e 100644 --- a/src/libnm-core-aux-extern/nm-dispatcher-api.h +++ b/src/libnm-core-aux-extern/nm-dispatcher-api.h @@ -34,6 +34,7 @@ #define NMD_ACTION_DHCP6_CHANGE "dhcp6-change" #define NMD_ACTION_CONNECTIVITY_CHANGE "connectivity-change" #define NMD_ACTION_REAPPLY "reapply" +#define NMD_ACTION_DNS_CHANGE "dns-change" typedef enum { DISPATCH_RESULT_UNKNOWN = 0, diff --git a/src/nm-dispatcher/nm-dispatcher-utils.c b/src/nm-dispatcher/nm-dispatcher-utils.c index 74ea4e4001..f8a4c28000 100644 --- a/src/nm-dispatcher/nm-dispatcher-utils.c +++ b/src/nm-dispatcher/nm-dispatcher-utils.c @@ -453,8 +453,12 @@ nm_dispatcher_utils_construct_envp(const char *action, items = g_ptr_array_new_with_free_func(g_free); - /* Hostname and connectivity changes don't require a device nor contain a connection */ - if (NM_IN_STRSET(action, NMD_ACTION_HOSTNAME, NMD_ACTION_CONNECTIVITY_CHANGE)) + /* Hostname, dns and connectivity changes don't require a device nor contain + * a connection */ + if (NM_IN_STRSET(action, + NMD_ACTION_HOSTNAME, + NMD_ACTION_CONNECTIVITY_CHANGE, + NMD_ACTION_DNS_CHANGE)) goto done; /* Connection properties */