dns: merge branch 'th/dns-resolved-default-route'

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/694

(cherry picked from commit bb9dcde97f)
This commit is contained in:
Thomas Haller
2020-11-27 10:47:05 +01:00

View File

@@ -34,6 +34,9 @@
#define SYSTEMD_RESOLVED_MANAGER_IFACE "org.freedesktop.resolve1.Manager" #define SYSTEMD_RESOLVED_MANAGER_IFACE "org.freedesktop.resolve1.Manager"
#define SYSTEMD_RESOLVED_DBUS_PATH "/org/freedesktop/resolve1" #define SYSTEMD_RESOLVED_DBUS_PATH "/org/freedesktop/resolve1"
/* define a variable, so that we can compare the operation with pointer equality. */
static const char *const DBUS_OP_SET_LINK_DEFAULT_ROUTE = "SetLinkDefaultRoute";
/*****************************************************************************/ /*****************************************************************************/
typedef struct { typedef struct {
@@ -43,8 +46,10 @@ typedef struct {
typedef struct { typedef struct {
CList request_queue_lst; CList request_queue_lst;
const char *operation; const char * operation;
GVariant * argument; GVariant * argument;
NMDnsSystemdResolved *self;
int ifindex;
} RequestItem; } RequestItem;
/*****************************************************************************/ /*****************************************************************************/
@@ -59,6 +64,8 @@ typedef struct {
bool try_start_blocked : 1; bool try_start_blocked : 1;
bool dbus_has_owner : 1; bool dbus_has_owner : 1;
bool dbus_initied : 1; bool dbus_initied : 1;
bool request_queue_to_send : 1;
NMTernary has_link_default_route : 3;
} NMDnsSystemdResolvedPrivate; } NMDnsSystemdResolvedPrivate;
struct _NMDnsSystemdResolved { struct _NMDnsSystemdResolved {
@@ -88,18 +95,26 @@ _request_item_free(RequestItem *request_item)
{ {
c_list_unlink_stale(&request_item->request_queue_lst); c_list_unlink_stale(&request_item->request_queue_lst);
g_variant_unref(request_item->argument); g_variant_unref(request_item->argument);
g_slice_free(RequestItem, request_item); nm_g_slice_free(request_item);
} }
static void static void
_request_item_append(CList *request_queue_lst_head, const char *operation, GVariant *argument) _request_item_append(NMDnsSystemdResolved *self,
const char * operation,
int ifindex,
GVariant * argument)
{ {
RequestItem *request_item; NMDnsSystemdResolvedPrivate *priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE(self);
RequestItem * request_item;
request_item = g_slice_new(RequestItem); request_item = g_slice_new(RequestItem);
request_item->operation = operation; *request_item = (RequestItem){
request_item->argument = g_variant_ref_sink(argument); .operation = operation,
c_list_link_tail(request_queue_lst_head, &request_item->request_queue_lst); .argument = g_variant_ref_sink(argument),
.self = self,
.ifindex = ifindex,
};
c_list_link_tail(&priv->request_queue_lst_head, &request_item->request_queue_lst);
} }
/*****************************************************************************/ /*****************************************************************************/
@@ -116,23 +131,48 @@ call_done(GObject *source, GAsyncResult *r, gpointer user_data)
{ {
gs_unref_variant GVariant *v = NULL; gs_unref_variant GVariant *v = NULL;
gs_free_error GError * error = NULL; gs_free_error GError * error = NULL;
NMDnsSystemdResolved * self = (NMDnsSystemdResolved *) user_data; NMDnsSystemdResolved * self;
NMDnsSystemdResolvedPrivate *priv; NMDnsSystemdResolvedPrivate *priv;
RequestItem * request_item;
NMLogLevel log_level;
v = g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), r, &error); v = g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), r, &error);
if (!v && g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) if (nm_utils_error_is_cancelled(error))
return; return;
request_item = user_data;
self = request_item->self;
priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE(self); priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE(self);
if (!v) { if (v) {
if (request_item->operation == DBUS_OP_SET_LINK_DEFAULT_ROUTE
&& priv->has_link_default_route == NM_TERNARY_DEFAULT) {
priv->has_link_default_route = NM_TERNARY_TRUE;
_LOGD("systemd-resolved support for SetLinkDefaultRoute(): API supported");
}
priv->send_updates_warn_ratelimited = FALSE;
return;
}
if (request_item->operation == DBUS_OP_SET_LINK_DEFAULT_ROUTE
&& nm_g_error_matches(error, G_DBUS_ERROR, G_DBUS_ERROR_UNKNOWN_METHOD)) {
if (priv->has_link_default_route == NM_TERNARY_DEFAULT) {
priv->has_link_default_route = NM_TERNARY_FALSE;
_LOGD("systemd-resolved support for SetLinkDefaultRoute(): API not supported");
}
return;
}
log_level = LOGL_DEBUG;
if (!priv->send_updates_warn_ratelimited) { if (!priv->send_updates_warn_ratelimited) {
priv->send_updates_warn_ratelimited = TRUE; priv->send_updates_warn_ratelimited = TRUE;
_LOGW("send-updates failed to update systemd-resolved: %s", error->message); log_level = LOGL_WARN;
} else }
_LOGD("send-updates failed: %s", error->message); _NMLOG(log_level,
} else "send-updates %s@%d failed: %s",
priv->send_updates_warn_ratelimited = FALSE; request_item->operation,
request_item->ifindex,
error->message);
} }
static gboolean static gboolean
@@ -198,8 +238,8 @@ free_pending_updates(NMDnsSystemdResolved *self)
static gboolean static gboolean
prepare_one_interface(NMDnsSystemdResolved *self, InterfaceConfig *ic) prepare_one_interface(NMDnsSystemdResolved *self, InterfaceConfig *ic)
{ {
NMDnsSystemdResolvedPrivate *priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE(self); GVariantBuilder dns;
GVariantBuilder dns, domains; GVariantBuilder domains;
NMCListElem * elem; NMCListElem * elem;
NMSettingConnectionMdns mdns = NM_SETTING_CONNECTION_MDNS_DEFAULT; NMSettingConnectionMdns mdns = NM_SETTING_CONNECTION_MDNS_DEFAULT;
NMSettingConnectionLlmnr llmnr = NM_SETTING_CONNECTION_LLMNR_DEFAULT; NMSettingConnectionLlmnr llmnr = NM_SETTING_CONNECTION_LLMNR_DEFAULT;
@@ -268,19 +308,20 @@ prepare_one_interface(NMDnsSystemdResolved *self, InterfaceConfig *ic)
if (!nm_str_is_empty(mdns_arg) || !nm_str_is_empty(llmnr_arg)) if (!nm_str_is_empty(mdns_arg) || !nm_str_is_empty(llmnr_arg))
has_config = TRUE; has_config = TRUE;
_request_item_append(&priv->request_queue_lst_head, _request_item_append(self, "SetLinkDomains", ic->ifindex, g_variant_builder_end(&domains));
"SetLinkDomains", _request_item_append(self,
g_variant_builder_end(&domains)); DBUS_OP_SET_LINK_DEFAULT_ROUTE,
_request_item_append(&priv->request_queue_lst_head, ic->ifindex,
"SetLinkDefaultRoute",
g_variant_new("(ib)", ic->ifindex, has_default_route)); g_variant_new("(ib)", ic->ifindex, has_default_route));
_request_item_append(&priv->request_queue_lst_head, _request_item_append(self,
"SetLinkMulticastDNS", "SetLinkMulticastDNS",
ic->ifindex,
g_variant_new("(is)", ic->ifindex, mdns_arg ?: "")); g_variant_new("(is)", ic->ifindex, mdns_arg ?: ""));
_request_item_append(&priv->request_queue_lst_head, _request_item_append(self,
"SetLinkLLMNR", "SetLinkLLMNR",
ic->ifindex,
g_variant_new("(is)", ic->ifindex, llmnr_arg ?: "")); g_variant_new("(is)", ic->ifindex, llmnr_arg ?: ""));
_request_item_append(&priv->request_queue_lst_head, "SetLinkDNS", g_variant_builder_end(&dns)); _request_item_append(self, "SetLinkDNS", ic->ifindex, g_variant_builder_end(&dns));
return has_config; return has_config;
} }
@@ -291,7 +332,7 @@ send_updates(NMDnsSystemdResolved *self)
NMDnsSystemdResolvedPrivate *priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE(self); NMDnsSystemdResolvedPrivate *priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE(self);
RequestItem * request_item; RequestItem * request_item;
if (c_list_is_empty(&priv->request_queue_lst_head)) { if (!priv->request_queue_to_send) {
/* nothing to do. */ /* nothing to do. */
return; return;
} }
@@ -321,15 +362,30 @@ send_updates(NMDnsSystemdResolved *self)
return; return;
} }
_LOGT("send-updates: start %lu requests", c_list_length(&priv->request_queue_lst_head));
nm_clear_g_cancellable(&priv->cancellable); nm_clear_g_cancellable(&priv->cancellable);
if (c_list_is_empty(&priv->request_queue_lst_head)) {
_LOGT("send-updates: no requests to send");
priv->request_queue_to_send = FALSE;
return;
}
_LOGT("send-updates: start %lu requests", c_list_length(&priv->request_queue_lst_head));
priv->cancellable = g_cancellable_new(); priv->cancellable = g_cancellable_new();
while ( priv->request_queue_to_send = FALSE;
(request_item =
c_list_first_entry(&priv->request_queue_lst_head, RequestItem, request_queue_lst))) { c_list_for_each_entry (request_item, &priv->request_queue_lst_head, request_queue_lst) {
if (request_item->operation == DBUS_OP_SET_LINK_DEFAULT_ROUTE
&& priv->has_link_default_route == NM_TERNARY_FALSE) {
/* The "SetLinkDefaultRoute" API is only supported since v240.
* We detected that it is not supported, and skip the call. There
* is no special workaround, because in this case we rely on systemd-resolved
* to do the right thing automatically. */
continue;
}
/* Above we explicitly call "StartServiceByName" trying to avoid D-Bus activating systmd-resolved /* Above we explicitly call "StartServiceByName" trying to avoid D-Bus activating systmd-resolved
* multiple times. There is still a race, were we might hit this line although actually * multiple times. There is still a race, were we might hit this line although actually
* the service just quit this very moment. In that case, we would try to D-Bus activate the * the service just quit this very moment. In that case, we would try to D-Bus activate the
@@ -349,8 +405,7 @@ send_updates(NMDnsSystemdResolved *self)
-1, -1,
priv->cancellable, priv->cancellable,
call_done, call_done,
self); request_item);
_request_item_free(request_item);
} }
} }
@@ -422,8 +477,8 @@ update(NMDnsPlugin * plugin,
} }
} }
priv->request_queue_to_send = TRUE;
send_updates(self); send_updates(self);
return TRUE; return TRUE;
} }
@@ -442,8 +497,11 @@ name_owner_changed(NMDnsSystemdResolved *self, const char *owner)
_LOGT("D-Bus name for systemd-resolved has owner %s", owner); _LOGT("D-Bus name for systemd-resolved has owner %s", owner);
priv->dbus_has_owner = !!owner; priv->dbus_has_owner = !!owner;
if (owner) if (owner) {
priv->try_start_blocked = FALSE; priv->try_start_blocked = FALSE;
priv->request_queue_to_send = TRUE;
} else
priv->has_link_default_route = NM_TERNARY_DEFAULT;
send_updates(self); send_updates(self);
} }
@@ -516,6 +574,8 @@ nm_dns_systemd_resolved_init(NMDnsSystemdResolved *self)
{ {
NMDnsSystemdResolvedPrivate *priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE(self); NMDnsSystemdResolvedPrivate *priv = NM_DNS_SYSTEMD_RESOLVED_GET_PRIVATE(self);
priv->has_link_default_route = NM_TERNARY_DEFAULT;
c_list_init(&priv->request_queue_lst_head); c_list_init(&priv->request_queue_lst_head);
priv->dirty_interfaces = g_hash_table_new(nm_direct_hash, NULL); priv->dirty_interfaces = g_hash_table_new(nm_direct_hash, NULL);