mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-07 17:10:21 +01:00
merge: branch 'lr/conn-check-af'
https://github.com/NetworkManager/NetworkManager/pull/157
This commit is contained in:
commit
fa6e4c7eb0
21 changed files with 2530 additions and 1363 deletions
|
|
@ -1380,3 +1380,20 @@ nmc_error_get_simple_message (GError *error)
|
|||
else
|
||||
return error->message;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
NM_UTILS_LOOKUP_STR_DEFINE (nm_connectivity_to_string_no_l10n, NMConnectivityState,
|
||||
NM_UTILS_LOOKUP_DEFAULT (N_("unknown")),
|
||||
NM_UTILS_LOOKUP_ITEM (NM_CONNECTIVITY_NONE, N_("none")),
|
||||
NM_UTILS_LOOKUP_ITEM (NM_CONNECTIVITY_PORTAL, N_("portal")),
|
||||
NM_UTILS_LOOKUP_ITEM (NM_CONNECTIVITY_LIMITED, N_("limited")),
|
||||
NM_UTILS_LOOKUP_ITEM (NM_CONNECTIVITY_FULL, N_("full")),
|
||||
NM_UTILS_LOOKUP_ITEM_IGNORE (NM_CONNECTIVITY_UNKNOWN),
|
||||
);
|
||||
|
||||
const char *
|
||||
nm_connectivity_to_string (NMConnectivityState connectivity)
|
||||
{
|
||||
return _(nm_connectivity_to_string_no_l10n (connectivity));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,4 +93,7 @@ extern const NmcMetaGenericInfo *const metagen_ip4_config[];
|
|||
extern const NmcMetaGenericInfo *const metagen_ip6_config[];
|
||||
extern const NmcMetaGenericInfo *const metagen_dhcp_config[];
|
||||
|
||||
const char *nm_connectivity_to_string (NMConnectivityState connectivity);
|
||||
const char *nm_connectivity_to_string_no_l10n (NMConnectivityState connectivity);
|
||||
|
||||
#endif /* NMC_COMMON_H */
|
||||
|
|
|
|||
|
|
@ -116,6 +116,12 @@ _metagen_device_status_get_fcn (NMC_META_GENERIC_INFO_GET_FCN_ARGS)
|
|||
case NMC_GENERIC_INFO_TYPE_DEVICE_STATUS_STATE:
|
||||
return nmc_meta_generic_get_str_i18n (nmc_device_state_to_string (nm_device_get_state (d)),
|
||||
get_type);
|
||||
case NMC_GENERIC_INFO_TYPE_DEVICE_STATUS_IP4_CONNECTIVITY:
|
||||
return nmc_meta_generic_get_str_i18n (nm_connectivity_to_string (nm_device_get_connectivity (d, AF_INET)),
|
||||
get_type);
|
||||
case NMC_GENERIC_INFO_TYPE_DEVICE_STATUS_IP6_CONNECTIVITY:
|
||||
return nmc_meta_generic_get_str_i18n (nm_connectivity_to_string (nm_device_get_connectivity (d, AF_INET6)),
|
||||
get_type);
|
||||
case NMC_GENERIC_INFO_TYPE_DEVICE_STATUS_DBUS_PATH:
|
||||
return nm_object_get_path (NM_OBJECT (d));
|
||||
case NMC_GENERIC_INFO_TYPE_DEVICE_STATUS_CONNECTION:
|
||||
|
|
@ -137,13 +143,15 @@ _metagen_device_status_get_fcn (NMC_META_GENERIC_INFO_GET_FCN_ARGS)
|
|||
const NmcMetaGenericInfo *const metagen_device_status[_NMC_GENERIC_INFO_TYPE_DEVICE_STATUS_NUM + 1] = {
|
||||
#define _METAGEN_DEVICE_STATUS(type, name) \
|
||||
[type] = NMC_META_GENERIC(name, .info_type = type, .get_fcn = _metagen_device_status_get_fcn)
|
||||
_METAGEN_DEVICE_STATUS (NMC_GENERIC_INFO_TYPE_DEVICE_STATUS_DEVICE, "DEVICE"),
|
||||
_METAGEN_DEVICE_STATUS (NMC_GENERIC_INFO_TYPE_DEVICE_STATUS_TYPE, "TYPE"),
|
||||
_METAGEN_DEVICE_STATUS (NMC_GENERIC_INFO_TYPE_DEVICE_STATUS_STATE, "STATE"),
|
||||
_METAGEN_DEVICE_STATUS (NMC_GENERIC_INFO_TYPE_DEVICE_STATUS_DBUS_PATH, "DBUS-PATH"),
|
||||
_METAGEN_DEVICE_STATUS (NMC_GENERIC_INFO_TYPE_DEVICE_STATUS_CONNECTION, "CONNECTION"),
|
||||
_METAGEN_DEVICE_STATUS (NMC_GENERIC_INFO_TYPE_DEVICE_STATUS_CON_UUID, "CON-UUID"),
|
||||
_METAGEN_DEVICE_STATUS (NMC_GENERIC_INFO_TYPE_DEVICE_STATUS_CON_PATH, "CON-PATH"),
|
||||
_METAGEN_DEVICE_STATUS (NMC_GENERIC_INFO_TYPE_DEVICE_STATUS_DEVICE, "DEVICE"),
|
||||
_METAGEN_DEVICE_STATUS (NMC_GENERIC_INFO_TYPE_DEVICE_STATUS_TYPE, "TYPE"),
|
||||
_METAGEN_DEVICE_STATUS (NMC_GENERIC_INFO_TYPE_DEVICE_STATUS_STATE, "STATE"),
|
||||
_METAGEN_DEVICE_STATUS (NMC_GENERIC_INFO_TYPE_DEVICE_STATUS_IP4_CONNECTIVITY, "IP4-CONNECTIVITY"),
|
||||
_METAGEN_DEVICE_STATUS (NMC_GENERIC_INFO_TYPE_DEVICE_STATUS_IP6_CONNECTIVITY, "IP6-CONNECTIVITY"),
|
||||
_METAGEN_DEVICE_STATUS (NMC_GENERIC_INFO_TYPE_DEVICE_STATUS_DBUS_PATH, "DBUS-PATH"),
|
||||
_METAGEN_DEVICE_STATUS (NMC_GENERIC_INFO_TYPE_DEVICE_STATUS_CONNECTION, "CONNECTION"),
|
||||
_METAGEN_DEVICE_STATUS (NMC_GENERIC_INFO_TYPE_DEVICE_STATUS_CON_UUID, "CON-UUID"),
|
||||
_METAGEN_DEVICE_STATUS (NMC_GENERIC_INFO_TYPE_DEVICE_STATUS_CON_PATH, "CON-PATH"),
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -155,6 +163,7 @@ _metagen_device_detail_general_get_fcn (NMC_META_GENERIC_INFO_GET_FCN_ARGS)
|
|||
NMActiveConnection *ac;
|
||||
NMDeviceState state;
|
||||
NMDeviceStateReason state_reason;
|
||||
NMConnectivityState connectivity;
|
||||
const char *s;
|
||||
|
||||
NMC_HANDLE_COLOR (NM_META_COLOR_NONE);
|
||||
|
|
@ -194,6 +203,18 @@ _metagen_device_detail_general_get_fcn (NMC_META_GENERIC_INFO_GET_FCN_ARGS)
|
|||
state_reason,
|
||||
nmc_device_reason_to_string (state_reason),
|
||||
get_type));
|
||||
case NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_IP4_CONNECTIVITY:
|
||||
connectivity = nm_device_get_connectivity (d, AF_INET);
|
||||
return (*out_to_free = nmc_meta_generic_get_enum_with_detail (NMC_META_GENERIC_GET_ENUM_TYPE_PARENTHESES,
|
||||
connectivity,
|
||||
nm_connectivity_to_string (connectivity),
|
||||
get_type));
|
||||
case NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_IP6_CONNECTIVITY:
|
||||
connectivity = nm_device_get_connectivity (d, AF_INET6);
|
||||
return (*out_to_free = nmc_meta_generic_get_enum_with_detail (NMC_META_GENERIC_GET_ENUM_TYPE_PARENTHESES,
|
||||
connectivity,
|
||||
nm_connectivity_to_string (connectivity),
|
||||
get_type));
|
||||
case NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_UDI:
|
||||
return nm_device_get_udi (d);
|
||||
case NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_IP_IFACE:
|
||||
|
|
@ -244,6 +265,8 @@ const NmcMetaGenericInfo *const metagen_device_detail_general[_NMC_GENERIC_INFO_
|
|||
_METAGEN_DEVICE_DETAIL_GENERAL (NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_MTU, "MTU"),
|
||||
_METAGEN_DEVICE_DETAIL_GENERAL (NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_STATE, "STATE"),
|
||||
_METAGEN_DEVICE_DETAIL_GENERAL (NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_REASON, "REASON"),
|
||||
_METAGEN_DEVICE_DETAIL_GENERAL (NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_IP4_CONNECTIVITY, "IP4-CONNECTIVITY"),
|
||||
_METAGEN_DEVICE_DETAIL_GENERAL (NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_IP6_CONNECTIVITY, "IP6-CONNECTIVITY"),
|
||||
_METAGEN_DEVICE_DETAIL_GENERAL (NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_UDI, "UDI"),
|
||||
_METAGEN_DEVICE_DETAIL_GENERAL (NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_IP_IFACE, "IP-IFACE"),
|
||||
_METAGEN_DEVICE_DETAIL_GENERAL (NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_IS_SOFTWARE, "IS-SOFTWARE"),
|
||||
|
|
|
|||
|
|
@ -78,21 +78,6 @@ state_to_color (NMState state)
|
|||
}
|
||||
}
|
||||
|
||||
NM_UTILS_LOOKUP_STR_DEFINE_STATIC (nm_connectivity_to_string_no_l10n, NMConnectivityState,
|
||||
NM_UTILS_LOOKUP_DEFAULT (N_("unknown")),
|
||||
NM_UTILS_LOOKUP_ITEM (NM_CONNECTIVITY_NONE, N_("none")),
|
||||
NM_UTILS_LOOKUP_ITEM (NM_CONNECTIVITY_PORTAL, N_("portal")),
|
||||
NM_UTILS_LOOKUP_ITEM (NM_CONNECTIVITY_LIMITED, N_("limited")),
|
||||
NM_UTILS_LOOKUP_ITEM (NM_CONNECTIVITY_FULL, N_("full")),
|
||||
NM_UTILS_LOOKUP_ITEM_IGNORE (NM_CONNECTIVITY_UNKNOWN),
|
||||
);
|
||||
|
||||
static const char *
|
||||
nm_connectivity_to_string (NMConnectivityState connectivity)
|
||||
{
|
||||
return _(nm_connectivity_to_string_no_l10n (connectivity));
|
||||
}
|
||||
|
||||
static NMMetaColor
|
||||
connectivity_to_color (NMConnectivityState connectivity)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -166,6 +166,8 @@ typedef enum {
|
|||
NMC_GENERIC_INFO_TYPE_DEVICE_STATUS_DEVICE = 0,
|
||||
NMC_GENERIC_INFO_TYPE_DEVICE_STATUS_TYPE,
|
||||
NMC_GENERIC_INFO_TYPE_DEVICE_STATUS_STATE,
|
||||
NMC_GENERIC_INFO_TYPE_DEVICE_STATUS_IP4_CONNECTIVITY,
|
||||
NMC_GENERIC_INFO_TYPE_DEVICE_STATUS_IP6_CONNECTIVITY,
|
||||
NMC_GENERIC_INFO_TYPE_DEVICE_STATUS_DBUS_PATH,
|
||||
NMC_GENERIC_INFO_TYPE_DEVICE_STATUS_CONNECTION,
|
||||
NMC_GENERIC_INFO_TYPE_DEVICE_STATUS_CON_UUID,
|
||||
|
|
@ -184,6 +186,8 @@ typedef enum {
|
|||
NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_MTU,
|
||||
NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_STATE,
|
||||
NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_REASON,
|
||||
NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_IP4_CONNECTIVITY,
|
||||
NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_IP6_CONNECTIVITY,
|
||||
NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_UDI,
|
||||
NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_IP_IFACE,
|
||||
NMC_GENERIC_INFO_TYPE_DEVICE_DETAIL_GENERAL_IS_SOFTWARE,
|
||||
|
|
|
|||
|
|
@ -28,34 +28,34 @@ wlan1 wifi niedostępne --
|
|||
wlan1 wifi niedostępne --
|
||||
|
||||
<<<
|
||||
size: 762
|
||||
size: 978
|
||||
location: clients/tests/test-client.py:844:test_002()/3
|
||||
cmd: $NMCLI -f all d
|
||||
lang: C
|
||||
returncode: 0
|
||||
stdout: 636 bytes
|
||||
stdout: 852 bytes
|
||||
>>>
|
||||
DEVICE TYPE STATE DBUS-PATH CONNECTION CON-UUID CON-PATH
|
||||
eth0 ethernet unavailable /org/freedesktop/NetworkManager/Devices/1 -- -- --
|
||||
eth1 ethernet unavailable /org/freedesktop/NetworkManager/Devices/2 -- -- --
|
||||
wlan0 wifi unavailable /org/freedesktop/NetworkManager/Devices/3 -- -- --
|
||||
wlan1 wifi unavailable /org/freedesktop/NetworkManager/Devices/4 -- -- --
|
||||
wlan1 wifi unavailable /org/freedesktop/NetworkManager/Devices/5 -- -- --
|
||||
DEVICE TYPE STATE IP4-CONNECTIVITY IP6-CONNECTIVITY DBUS-PATH CONNECTION CON-UUID CON-PATH
|
||||
eth0 ethernet unavailable unknown unknown /org/freedesktop/NetworkManager/Devices/1 -- -- --
|
||||
eth1 ethernet unavailable unknown unknown /org/freedesktop/NetworkManager/Devices/2 -- -- --
|
||||
wlan0 wifi unavailable unknown unknown /org/freedesktop/NetworkManager/Devices/3 -- -- --
|
||||
wlan1 wifi unavailable unknown unknown /org/freedesktop/NetworkManager/Devices/4 -- -- --
|
||||
wlan1 wifi unavailable unknown unknown /org/freedesktop/NetworkManager/Devices/5 -- -- --
|
||||
|
||||
<<<
|
||||
size: 777
|
||||
size: 993
|
||||
location: clients/tests/test-client.py:844:test_002()/4
|
||||
cmd: $NMCLI -f all d
|
||||
lang: pl_PL.UTF-8
|
||||
returncode: 0
|
||||
stdout: 641 bytes
|
||||
stdout: 857 bytes
|
||||
>>>
|
||||
DEVICE TYPE STATE DBUS-PATH CONNECTION CON-UUID CON-PATH
|
||||
eth0 ethernet niedostępne /org/freedesktop/NetworkManager/Devices/1 -- -- --
|
||||
eth1 ethernet niedostępne /org/freedesktop/NetworkManager/Devices/2 -- -- --
|
||||
wlan0 wifi niedostępne /org/freedesktop/NetworkManager/Devices/3 -- -- --
|
||||
wlan1 wifi niedostępne /org/freedesktop/NetworkManager/Devices/4 -- -- --
|
||||
wlan1 wifi niedostępne /org/freedesktop/NetworkManager/Devices/5 -- -- --
|
||||
DEVICE TYPE STATE IP4-CONNECTIVITY IP6-CONNECTIVITY DBUS-PATH CONNECTION CON-UUID CON-PATH
|
||||
eth0 ethernet niedostępne nieznane nieznane /org/freedesktop/NetworkManager/Devices/1 -- -- --
|
||||
eth1 ethernet niedostępne nieznane nieznane /org/freedesktop/NetworkManager/Devices/2 -- -- --
|
||||
wlan0 wifi niedostępne nieznane nieznane /org/freedesktop/NetworkManager/Devices/3 -- -- --
|
||||
wlan1 wifi niedostępne nieznane nieznane /org/freedesktop/NetworkManager/Devices/4 -- -- --
|
||||
wlan1 wifi niedostępne nieznane nieznane /org/freedesktop/NetworkManager/Devices/5 -- -- --
|
||||
|
||||
<<<
|
||||
size: 739
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -256,6 +256,28 @@
|
|||
-->
|
||||
<property name="Real" type="b" access="read"/>
|
||||
|
||||
<!--
|
||||
Ip4Connectivity:
|
||||
|
||||
The result of the last IPv4 connectivity check.
|
||||
|
||||
Since: 1.16
|
||||
|
||||
Returns: <link linkend="NMConnectivityState">NMConnectivityState</link>
|
||||
-->
|
||||
<property name="Ip4Connectivity" type="u" access="read"/>
|
||||
|
||||
<!--
|
||||
Ip6Connectivity:
|
||||
|
||||
The result of the last IPv6 connectivity check.
|
||||
|
||||
Since: 1.16
|
||||
|
||||
Returns: <link linkend="NMConnectivityState">NMConnectivityState</link>
|
||||
-->
|
||||
<property name="Ip6Connectivity" type="u" access="read"/>
|
||||
|
||||
<!--
|
||||
Reapply:
|
||||
@connection: The optional connection settings that will be reapplied on the device. If empty, the currently active settings-connection will be used. The connection cannot arbitrarly differ from the current applied-connection otherwise the call will fail. Only certain changes are supported, like adding or removing IP addresses.
|
||||
|
|
|
|||
|
|
@ -1439,3 +1439,8 @@ global:
|
|||
nm_utils_sriov_vf_from_str;
|
||||
nm_utils_sriov_vf_to_str;
|
||||
} libnm_1_12_0;
|
||||
|
||||
libnm_1_16_0 {
|
||||
global:
|
||||
nm_device_get_connectivity;
|
||||
} libnm_1_14_0;
|
||||
|
|
|
|||
|
|
@ -74,6 +74,8 @@ typedef struct {
|
|||
NMDhcpConfig *dhcp4_config;
|
||||
NMIPConfig *ip6_config;
|
||||
NMDhcpConfig *dhcp6_config;
|
||||
NMConnectivityState ip4_connectivity;
|
||||
NMConnectivityState ip6_connectivity;
|
||||
NMDeviceState state;
|
||||
NMDeviceState last_seen_state;
|
||||
NMDeviceStateReason reason;
|
||||
|
|
@ -120,6 +122,8 @@ enum {
|
|||
PROP_MTU,
|
||||
PROP_METERED,
|
||||
PROP_LLDP_NEIGHBORS,
|
||||
PROP_IP4_CONNECTIVITY,
|
||||
PROP_IP6_CONNECTIVITY,
|
||||
|
||||
LAST_PROP
|
||||
};
|
||||
|
|
@ -144,6 +148,8 @@ nm_device_init (NMDevice *device)
|
|||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
|
||||
|
||||
priv->ip4_connectivity = NM_CONNECTIVITY_UNKNOWN;
|
||||
priv->ip6_connectivity = NM_CONNECTIVITY_UNKNOWN;
|
||||
priv->state = NM_DEVICE_STATE_UNKNOWN;
|
||||
priv->reason = NM_DEVICE_STATE_REASON_NONE;
|
||||
priv->lldp_neighbors = g_ptr_array_new ();
|
||||
|
|
@ -216,6 +222,8 @@ init_dbus (NMObject *object)
|
|||
{ NM_DEVICE_DHCP4_CONFIG, &priv->dhcp4_config, NULL, NM_TYPE_DHCP4_CONFIG },
|
||||
{ NM_DEVICE_IP6_CONFIG, &priv->ip6_config, NULL, NM_TYPE_IP6_CONFIG },
|
||||
{ NM_DEVICE_DHCP6_CONFIG, &priv->dhcp6_config, NULL, NM_TYPE_DHCP6_CONFIG },
|
||||
{ NM_DEVICE_IP4_CONNECTIVITY, &priv->ip4_connectivity },
|
||||
{ NM_DEVICE_IP6_CONNECTIVITY, &priv->ip6_connectivity },
|
||||
{ NM_DEVICE_STATE, &priv->state },
|
||||
{ NM_DEVICE_STATE_REASON, &priv->reason, demarshal_state_reason },
|
||||
{ NM_DEVICE_ACTIVE_CONNECTION, &priv->active_connection, NULL, NM_TYPE_ACTIVE_CONNECTION },
|
||||
|
|
@ -428,6 +436,12 @@ get_property (GObject *object,
|
|||
case PROP_LLDP_NEIGHBORS:
|
||||
g_value_set_boxed (value, nm_device_get_lldp_neighbors (device));
|
||||
break;
|
||||
case PROP_IP4_CONNECTIVITY:
|
||||
g_value_set_enum (value, nm_device_get_connectivity (device, AF_INET));
|
||||
break;
|
||||
case PROP_IP6_CONNECTIVITY:
|
||||
g_value_set_enum (value, nm_device_get_connectivity (device, AF_INET6));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
|
@ -700,6 +714,36 @@ nm_device_class_init (NMDeviceClass *device_class)
|
|||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* NMDevice:ip4-connectivity:
|
||||
*
|
||||
* The IPv4 connectivity state of the device.
|
||||
*
|
||||
* Since: 1.16
|
||||
**/
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_IP4_CONNECTIVITY,
|
||||
g_param_spec_enum (NM_DEVICE_IP4_CONNECTIVITY, "", "",
|
||||
NM_TYPE_CONNECTIVITY_STATE,
|
||||
NM_CONNECTIVITY_UNKNOWN,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* NMDevice:ip6-connectivity:
|
||||
*
|
||||
* The IPv6 connectivity state of the device.
|
||||
*
|
||||
* Since: 1.16
|
||||
**/
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_IP6_CONNECTIVITY,
|
||||
g_param_spec_enum (NM_DEVICE_IP6_CONNECTIVITY, "", "",
|
||||
NM_TYPE_CONNECTIVITY_STATE,
|
||||
NM_CONNECTIVITY_UNKNOWN,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* NMDevice:state:
|
||||
*
|
||||
|
|
@ -1230,6 +1274,36 @@ nm_device_get_dhcp6_config (NMDevice *device)
|
|||
return NM_DEVICE_GET_PRIVATE (device)->dhcp6_config;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_device_get_connectivity:
|
||||
* @device: a #NMDevice
|
||||
* @addr_family: network address family
|
||||
*
|
||||
* The connectivity state of the device for given address family.
|
||||
* Supported address families are %AF_INET for IPv4, %AF_INET6
|
||||
* for IPv6 or %AF_UNSPEC for any.
|
||||
*
|
||||
* Returns: the current connectivity state
|
||||
*
|
||||
* Since: 1.16
|
||||
**/
|
||||
NMConnectivityState
|
||||
nm_device_get_connectivity (NMDevice *device, int addr_family)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (device);
|
||||
|
||||
switch (addr_family) {
|
||||
case AF_INET:
|
||||
return priv->ip4_connectivity;
|
||||
case AF_INET6:
|
||||
return priv->ip6_connectivity;
|
||||
case AF_UNSPEC:
|
||||
return NM_MAX (priv->ip4_connectivity, priv->ip6_connectivity);
|
||||
default:
|
||||
g_return_val_if_reached (NM_CONNECTIVITY_UNKNOWN);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_device_get_state:
|
||||
* @device: a #NMDevice
|
||||
|
|
|
|||
|
|
@ -64,6 +64,8 @@ G_BEGIN_DECLS
|
|||
#define NM_DEVICE_MTU "mtu"
|
||||
#define NM_DEVICE_METERED "metered"
|
||||
#define NM_DEVICE_LLDP_NEIGHBORS "lldp-neighbors"
|
||||
#define NM_DEVICE_IP4_CONNECTIVITY "ip4-connectivity"
|
||||
#define NM_DEVICE_IP6_CONNECTIVITY "ip6-connectivity"
|
||||
|
||||
/**
|
||||
* NMDevice:
|
||||
|
|
@ -121,6 +123,8 @@ NMIPConfig * nm_device_get_ip4_config (NMDevice *device);
|
|||
NMDhcpConfig * nm_device_get_dhcp4_config (NMDevice *device);
|
||||
NMIPConfig * nm_device_get_ip6_config (NMDevice *device);
|
||||
NMDhcpConfig * nm_device_get_dhcp6_config (NMDevice *device);
|
||||
NM_AVAILABLE_IN_1_16
|
||||
NMConnectivityState nm_device_get_connectivity (NMDevice *device, int addr_family);
|
||||
NMDeviceState nm_device_get_state (NMDevice *device);
|
||||
NMDeviceStateReason nm_device_get_state_reason (NMDevice *device);
|
||||
NMActiveConnection * nm_device_get_active_connection(NMDevice *device);
|
||||
|
|
|
|||
|
|
@ -387,6 +387,20 @@ no-auto-default=*
|
|||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>systemd-resolved</varname></term>
|
||||
<listitem><para>Send the connection DNS configuration to
|
||||
<literal>systemd-resolved</literal>. Defaults to "<literal>true</literal>".
|
||||
</para>
|
||||
<para>Note that this setting is complementary to the
|
||||
<varname>dns</varname> setting. You can keep this enable while using
|
||||
<varname>dns</varname> set to another DNS plugin alongside
|
||||
<literal>systemd-resolved</literal>, or <varname>dns</varname> set to
|
||||
<literal>systemd-resolved</literal> to configure the system resolver to use
|
||||
<literal>systemd-resolved</literal>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>debug</varname></term>
|
||||
<listitem><para>Comma separated list of options to aid
|
||||
|
|
|
|||
|
|
@ -175,6 +175,7 @@ struct _NMDeviceConnectivityHandle {
|
|||
bool is_periodic:1;
|
||||
bool is_periodic_bump:1;
|
||||
bool is_periodic_bump_on_complete:1;
|
||||
int addr_family;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -196,7 +197,6 @@ enum {
|
|||
REMOVED,
|
||||
RECHECK_AUTO_ACTIVATE,
|
||||
RECHECK_ASSUME,
|
||||
CONNECTIVITY_CHANGED,
|
||||
LAST_SIGNAL,
|
||||
};
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
|
@ -242,7 +242,8 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMDevice,
|
|||
PROP_REFRESH_RATE_MS,
|
||||
PROP_TX_BYTES,
|
||||
PROP_RX_BYTES,
|
||||
PROP_CONNECTIVITY,
|
||||
PROP_IP4_CONNECTIVITY,
|
||||
PROP_IP6_CONNECTIVITY,
|
||||
);
|
||||
|
||||
typedef struct _NMDevicePrivate {
|
||||
|
|
@ -555,24 +556,24 @@ typedef struct _NMDevicePrivate {
|
|||
NMLldpListener *lldp_listener;
|
||||
|
||||
NMConnectivity *concheck_mgr;
|
||||
|
||||
/* if periodic checks are enabled, this is the source id for the next check. */
|
||||
guint concheck_p_cur_id;
|
||||
|
||||
/* the currently configured max periodic interval. */
|
||||
guint concheck_p_max_interval;
|
||||
|
||||
/* the current interval. If we are probing, the interval might be lower
|
||||
* then the configured max interval. */
|
||||
guint concheck_p_cur_interval;
|
||||
|
||||
/* the timestamp, when we last scheduled the timer concheck_p_cur_id with current interval
|
||||
* concheck_p_cur_interval. */
|
||||
gint64 concheck_p_cur_basetime_ns;
|
||||
|
||||
NMConnectivityState connectivity_state;
|
||||
|
||||
CList concheck_lst_head;
|
||||
struct {
|
||||
/* if periodic checks are enabled, this is the source id for the next check. */
|
||||
guint p_cur_id;
|
||||
|
||||
/* the currently configured max periodic interval. */
|
||||
guint p_max_interval;
|
||||
|
||||
/* the current interval. If we are probing, the interval might be lower
|
||||
* then the configured max interval. */
|
||||
guint p_cur_interval;
|
||||
|
||||
/* the timestamp, when we last scheduled the timer p_cur_id with current interval
|
||||
* p_cur_interval. */
|
||||
gint64 p_cur_basetime_ns;
|
||||
|
||||
NMConnectivityState state;
|
||||
} concheck_x[2];
|
||||
|
||||
guint check_delete_unrealized_id;
|
||||
|
||||
|
|
@ -643,7 +644,10 @@ static void _set_mtu (NMDevice *self, guint32 mtu);
|
|||
static void _commit_mtu (NMDevice *self, const NMIP4Config *config);
|
||||
static void _cancel_activation (NMDevice *self);
|
||||
|
||||
static void concheck_update_state (NMDevice *self, NMConnectivityState state, gboolean is_periodic);
|
||||
static void concheck_update_state (NMDevice *self,
|
||||
int addr_family,
|
||||
NMConnectivityState state,
|
||||
gboolean is_periodic);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -2092,13 +2096,14 @@ nm_device_get_route_metric_default (NMDeviceType device_type)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
default_route_metric_penalty_detect (NMDevice *self)
|
||||
default_route_metric_penalty_detect (NMDevice *self, int addr_family)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
const gboolean IS_IPv4 = (addr_family == AF_INET);
|
||||
|
||||
/* currently we don't differentiate between IPv4 and IPv6 when detecting
|
||||
* connectivity. */
|
||||
if ( priv->connectivity_state != NM_CONNECTIVITY_FULL
|
||||
if ( priv->concheck_x[IS_IPv4].state != NM_CONNECTIVITY_FULL
|
||||
&& nm_connectivity_check_enabled (concheck_get_mgr (self)))
|
||||
return TRUE;
|
||||
|
||||
|
|
@ -2448,23 +2453,35 @@ typedef enum {
|
|||
} ConcheckScheduleMode;
|
||||
|
||||
static NMDeviceConnectivityHandle *concheck_start (NMDevice *self,
|
||||
int addr_family,
|
||||
NMDeviceConnectivityCallback callback,
|
||||
gpointer user_data,
|
||||
gboolean is_periodic);
|
||||
|
||||
static void concheck_periodic_schedule_set (NMDevice *self,
|
||||
int addr_family,
|
||||
ConcheckScheduleMode mode);
|
||||
|
||||
static gboolean
|
||||
concheck_periodic_timeout_cb (gpointer user_data)
|
||||
_concheck_periodic_timeout_cb (NMDevice *self, int addr_family)
|
||||
{
|
||||
NMDevice *self = user_data;
|
||||
|
||||
_LOGt (LOGD_CONCHECK, "connectivity: periodic timeout");
|
||||
concheck_periodic_schedule_set (self, CONCHECK_SCHEDULE_CHECK_PERIODIC);
|
||||
concheck_periodic_schedule_set (self, addr_family, CONCHECK_SCHEDULE_CHECK_PERIODIC);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
concheck_ip4_periodic_timeout_cb (gpointer user_data)
|
||||
{
|
||||
return _concheck_periodic_timeout_cb (user_data, AF_INET);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
concheck_ip6_periodic_timeout_cb (gpointer user_data)
|
||||
{
|
||||
return _concheck_periodic_timeout_cb (user_data, AF_INET6);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
concheck_is_possible (NMDevice *self)
|
||||
{
|
||||
|
|
@ -2483,17 +2500,18 @@ concheck_is_possible (NMDevice *self)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
concheck_periodic_schedule_do (NMDevice *self, gint64 now_ns)
|
||||
concheck_periodic_schedule_do (NMDevice *self, int addr_family, gint64 now_ns)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
gboolean periodic_check_disabled = FALSE;
|
||||
gint64 expiry, tdiff;
|
||||
const gboolean IS_IPv4 = (addr_family == AF_INET);
|
||||
|
||||
/* we always cancel whatever was pending. */
|
||||
if (nm_clear_g_source (&priv->concheck_p_cur_id))
|
||||
if (nm_clear_g_source (&priv->concheck_x[IS_IPv4].p_cur_id))
|
||||
periodic_check_disabled = TRUE;
|
||||
|
||||
if (priv->concheck_p_max_interval == 0) {
|
||||
if (priv->concheck_x[IS_IPv4].p_max_interval == 0) {
|
||||
/* periodic checks are disabled */
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -2502,23 +2520,24 @@ concheck_periodic_schedule_do (NMDevice *self, gint64 now_ns)
|
|||
goto out;
|
||||
|
||||
nm_assert (now_ns > 0);
|
||||
nm_assert (priv->concheck_p_cur_interval > 0);
|
||||
nm_assert (priv->concheck_x[IS_IPv4].p_cur_interval > 0);
|
||||
|
||||
/* we schedule the timeout based on our current settings cur-interval and cur-basetime.
|
||||
* Before calling concheck_periodic_schedule_do(), make sure that these properties are
|
||||
* correct. */
|
||||
|
||||
expiry = priv->concheck_p_cur_basetime_ns + (priv->concheck_p_cur_interval * NM_UTILS_NS_PER_SECOND);
|
||||
expiry = priv->concheck_x[IS_IPv4].p_cur_basetime_ns + (priv->concheck_x[IS_IPv4].p_cur_interval * NM_UTILS_NS_PER_SECOND);
|
||||
tdiff = expiry - now_ns;
|
||||
|
||||
_LOGT (LOGD_CONCHECK, "connectivity: periodic-check: %sscheduled in %lld milliseconds (%u seconds interval)",
|
||||
periodic_check_disabled ? "re-" : "",
|
||||
(long long) (tdiff / NM_UTILS_NS_PER_MSEC),
|
||||
priv->concheck_p_cur_interval);
|
||||
priv->concheck_x[IS_IPv4].p_cur_interval);
|
||||
|
||||
priv->concheck_p_cur_id = g_timeout_add (NM_MAX ((gint64) 0, tdiff) / NM_UTILS_NS_PER_MSEC,
|
||||
concheck_periodic_timeout_cb,
|
||||
self);
|
||||
priv->concheck_x[IS_IPv4].p_cur_id =
|
||||
g_timeout_add (NM_MAX ((gint64) 0, tdiff) / NM_UTILS_NS_PER_MSEC,
|
||||
IS_IPv4 ? concheck_ip4_periodic_timeout_cb : concheck_ip6_periodic_timeout_cb,
|
||||
self);
|
||||
return TRUE;
|
||||
out:
|
||||
if (periodic_check_disabled)
|
||||
|
|
@ -2529,19 +2548,19 @@ out:
|
|||
#define CONCHECK_P_PROBE_INTERVAL 1
|
||||
|
||||
static void
|
||||
concheck_periodic_schedule_set (NMDevice *self,
|
||||
ConcheckScheduleMode mode)
|
||||
concheck_periodic_schedule_set (NMDevice *self, int addr_family, ConcheckScheduleMode mode)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
gint64 new_expiry, exp_expiry, cur_expiry, tdiff;
|
||||
gint64 now_ns = 0;
|
||||
const gboolean IS_IPv4 = (addr_family == AF_INET);
|
||||
|
||||
if (priv->concheck_p_max_interval == 0) {
|
||||
if (priv->concheck_x[IS_IPv4].p_max_interval == 0) {
|
||||
/* periodic check is disabled. Nothing to do. */
|
||||
return;
|
||||
}
|
||||
|
||||
if (!priv->concheck_p_cur_id) {
|
||||
if (!priv->concheck_x[IS_IPv4].p_cur_id) {
|
||||
/* we currently don't have a timeout scheduled. No need to reschedule
|
||||
* another one... */
|
||||
if (NM_IN_SET (mode, CONCHECK_SCHEDULE_UPDATE_INTERVAL,
|
||||
|
|
@ -2555,19 +2574,19 @@ concheck_periodic_schedule_set (NMDevice *self,
|
|||
|
||||
switch (mode) {
|
||||
case CONCHECK_SCHEDULE_UPDATE_INTERVAL_RESTART:
|
||||
priv->concheck_p_cur_interval = NM_MIN (priv->concheck_p_max_interval, CONCHECK_P_PROBE_INTERVAL);
|
||||
priv->concheck_p_cur_basetime_ns = nm_utils_get_monotonic_timestamp_ns_cached (&now_ns);
|
||||
if (concheck_periodic_schedule_do (self, now_ns))
|
||||
concheck_start (self, NULL, NULL, TRUE);
|
||||
priv->concheck_x[IS_IPv4].p_cur_interval = NM_MIN (priv->concheck_x[IS_IPv4].p_max_interval, CONCHECK_P_PROBE_INTERVAL);
|
||||
priv->concheck_x[IS_IPv4].p_cur_basetime_ns = nm_utils_get_monotonic_timestamp_ns_cached (&now_ns);
|
||||
if (concheck_periodic_schedule_do (self, addr_family, now_ns))
|
||||
concheck_start (self, addr_family, NULL, NULL, TRUE);
|
||||
return;
|
||||
|
||||
case CONCHECK_SCHEDULE_UPDATE_INTERVAL:
|
||||
/* called with "UPDATE_INTERVAL" and already have a concheck_p_cur_id scheduled. */
|
||||
/* called with "UPDATE_INTERVAL" and already have a p_cur_id scheduled. */
|
||||
|
||||
nm_assert (priv->concheck_p_max_interval > 0);
|
||||
nm_assert (priv->concheck_p_cur_interval > 0);
|
||||
nm_assert (priv->concheck_x[IS_IPv4].p_max_interval > 0);
|
||||
nm_assert (priv->concheck_x[IS_IPv4].p_cur_interval > 0);
|
||||
|
||||
if (priv->concheck_p_cur_interval <= priv->concheck_p_max_interval) {
|
||||
if (priv->concheck_x[IS_IPv4].p_cur_interval <= priv->concheck_x[IS_IPv4].p_max_interval) {
|
||||
/* we currently have a shorter interval set, than what we now have. Either,
|
||||
* because we are probing, or because the previous max interval was shorter.
|
||||
*
|
||||
|
|
@ -2576,17 +2595,17 @@ concheck_periodic_schedule_set (NMDevice *self,
|
|||
return;
|
||||
}
|
||||
|
||||
cur_expiry = priv->concheck_p_cur_basetime_ns + (priv->concheck_p_max_interval * NM_UTILS_NS_PER_SECOND);
|
||||
cur_expiry = priv->concheck_x[IS_IPv4].p_cur_basetime_ns + (priv->concheck_x[IS_IPv4].p_max_interval * NM_UTILS_NS_PER_SECOND);
|
||||
nm_utils_get_monotonic_timestamp_ns_cached (&now_ns);
|
||||
|
||||
priv->concheck_p_cur_interval = priv->concheck_p_max_interval;
|
||||
priv->concheck_x[IS_IPv4].p_cur_interval = priv->concheck_x[IS_IPv4].p_max_interval;
|
||||
if (cur_expiry <= now_ns) {
|
||||
/* Since the last time we scheduled a periodic check, already more than the
|
||||
* new max_interval passed. We need to start a check right away (and
|
||||
* schedule a timeout in cur-interval in the future). */
|
||||
priv->concheck_p_cur_basetime_ns = now_ns;
|
||||
if (concheck_periodic_schedule_do (self, now_ns))
|
||||
concheck_start (self, NULL, NULL, TRUE);
|
||||
priv->concheck_x[IS_IPv4].p_cur_basetime_ns = now_ns;
|
||||
if (concheck_periodic_schedule_do (self, addr_family, now_ns))
|
||||
concheck_start (self, addr_family, NULL, NULL, TRUE);
|
||||
} else {
|
||||
/* we are reducing the max-interval to a shorter interval that we have currently
|
||||
* scheduled (with cur_interval).
|
||||
|
|
@ -2594,24 +2613,26 @@ concheck_periodic_schedule_set (NMDevice *self,
|
|||
* However, since the last time we scheduled the check, not even the new max-interval
|
||||
* expired. All we need to do, is reschedule the timer to expire sooner. The cur_basetime
|
||||
* is unchanged. */
|
||||
concheck_periodic_schedule_do (self, now_ns);
|
||||
concheck_periodic_schedule_do (self, addr_family, now_ns);
|
||||
}
|
||||
return;
|
||||
|
||||
case CONCHECK_SCHEDULE_CHECK_EXTERNAL:
|
||||
/* a external connectivity check delays our periodic check. We reset the counter. */
|
||||
priv->concheck_p_cur_basetime_ns = nm_utils_get_monotonic_timestamp_ns_cached (&now_ns);
|
||||
concheck_periodic_schedule_do (self, now_ns);
|
||||
priv->concheck_x[IS_IPv4].p_cur_basetime_ns = nm_utils_get_monotonic_timestamp_ns_cached (&now_ns);
|
||||
concheck_periodic_schedule_do (self, addr_family, now_ns);
|
||||
return;
|
||||
|
||||
case CONCHECK_SCHEDULE_CHECK_PERIODIC:
|
||||
{
|
||||
gboolean any_periodic_pending;
|
||||
NMDeviceConnectivityHandle *handle;
|
||||
guint old_interval = priv->concheck_p_cur_interval;
|
||||
guint old_interval = priv->concheck_x[IS_IPv4].p_cur_interval;
|
||||
|
||||
any_periodic_pending = FALSE;
|
||||
c_list_for_each_entry (handle, &priv->concheck_lst_head, concheck_lst) {
|
||||
if (handle->addr_family != addr_family)
|
||||
continue;
|
||||
if (handle->is_periodic_bump) {
|
||||
handle->is_periodic_bump = FALSE;
|
||||
handle->is_periodic_bump_on_complete = FALSE;
|
||||
|
|
@ -2622,7 +2643,7 @@ concheck_periodic_schedule_set (NMDevice *self,
|
|||
/* we reached a timeout to schedule a new periodic request, however we still
|
||||
* have period requests pending that didn't complete yet. We need to bump the
|
||||
* interval already. */
|
||||
priv->concheck_p_cur_interval = NM_MIN (old_interval * 2, priv->concheck_p_max_interval);
|
||||
priv->concheck_x[IS_IPv4].p_cur_interval = NM_MIN (old_interval * 2, priv->concheck_x[IS_IPv4].p_max_interval);
|
||||
}
|
||||
|
||||
/* we just reached a timeout. The expected expiry (exp_expiry) should be
|
||||
|
|
@ -2630,13 +2651,13 @@ concheck_periodic_schedule_set (NMDevice *self,
|
|||
*
|
||||
* We want to reschedule the timeout at exp_expiry (aka now) + cur_interval. */
|
||||
nm_utils_get_monotonic_timestamp_ns_cached (&now_ns);
|
||||
exp_expiry = priv->concheck_p_cur_basetime_ns + (old_interval * NM_UTILS_NS_PER_SECOND);
|
||||
new_expiry = exp_expiry + (priv->concheck_p_cur_interval * NM_UTILS_NS_PER_SECOND);
|
||||
exp_expiry = priv->concheck_x[IS_IPv4].p_cur_basetime_ns + (old_interval * NM_UTILS_NS_PER_SECOND);
|
||||
new_expiry = exp_expiry + (priv->concheck_x[IS_IPv4].p_cur_interval * NM_UTILS_NS_PER_SECOND);
|
||||
tdiff = NM_MAX (new_expiry - now_ns, 0);
|
||||
priv->concheck_p_cur_basetime_ns = (now_ns + tdiff) - (priv->concheck_p_cur_interval * NM_UTILS_NS_PER_SECOND);
|
||||
if (concheck_periodic_schedule_do (self, now_ns)) {
|
||||
handle = concheck_start (self, NULL, NULL, TRUE);
|
||||
if (old_interval != priv->concheck_p_cur_interval) {
|
||||
priv->concheck_x[IS_IPv4].p_cur_basetime_ns = (now_ns + tdiff) - (priv->concheck_x[IS_IPv4].p_cur_interval * NM_UTILS_NS_PER_SECOND);
|
||||
if (concheck_periodic_schedule_do (self, addr_family, now_ns)) {
|
||||
handle = concheck_start (self, addr_family, NULL, NULL, TRUE);
|
||||
if (old_interval != priv->concheck_x[IS_IPv4].p_cur_interval) {
|
||||
/* we just bumped the interval already when scheduling this check.
|
||||
* When the handle returns, don't bump a second time.
|
||||
*
|
||||
|
|
@ -2651,13 +2672,13 @@ concheck_periodic_schedule_set (NMDevice *self,
|
|||
/* we just got an event that we lost connectivity (that is, concheck returned). We reset
|
||||
* the interval to min/max or increase the probe interval (bump). */
|
||||
case CONCHECK_SCHEDULE_RETURNED_MIN:
|
||||
priv->concheck_p_cur_interval = NM_MIN (priv->concheck_p_max_interval, CONCHECK_P_PROBE_INTERVAL);
|
||||
priv->concheck_x[IS_IPv4].p_cur_interval = NM_MIN (priv->concheck_x[IS_IPv4].p_max_interval, CONCHECK_P_PROBE_INTERVAL);
|
||||
break;
|
||||
case CONCHECK_SCHEDULE_RETURNED_MAX:
|
||||
priv->concheck_p_cur_interval = priv->concheck_p_max_interval;
|
||||
priv->concheck_x[IS_IPv4].p_cur_interval = priv->concheck_x[IS_IPv4].p_max_interval;
|
||||
break;
|
||||
case CONCHECK_SCHEDULE_RETURNED_BUMP:
|
||||
priv->concheck_p_cur_interval = NM_MIN (priv->concheck_p_cur_interval * 2, priv->concheck_p_max_interval);
|
||||
priv->concheck_x[IS_IPv4].p_cur_interval = NM_MIN (priv->concheck_x[IS_IPv4].p_cur_interval * 2, priv->concheck_x[IS_IPv4].p_max_interval);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -2667,38 +2688,40 @@ concheck_periodic_schedule_set (NMDevice *self,
|
|||
* last check, instead of counting from now. The reason is that we want that the times
|
||||
* when we schedule checks be at precise intervals, without including the time it took for
|
||||
* the connectivity check. */
|
||||
new_expiry = priv->concheck_p_cur_basetime_ns + (priv->concheck_p_cur_interval * NM_UTILS_NS_PER_SECOND);
|
||||
new_expiry = priv->concheck_x[IS_IPv4].p_cur_basetime_ns + (priv->concheck_x[IS_IPv4].p_cur_interval * NM_UTILS_NS_PER_SECOND);
|
||||
tdiff = NM_MAX (new_expiry - nm_utils_get_monotonic_timestamp_ns_cached (&now_ns), 0);
|
||||
priv->concheck_p_cur_basetime_ns = now_ns + tdiff - (priv->concheck_p_cur_interval * NM_UTILS_NS_PER_SECOND);
|
||||
concheck_periodic_schedule_do (self, now_ns);
|
||||
priv->concheck_x[IS_IPv4].p_cur_basetime_ns = now_ns + tdiff - (priv->concheck_x[IS_IPv4].p_cur_interval * NM_UTILS_NS_PER_SECOND);
|
||||
concheck_periodic_schedule_do (self, addr_family, now_ns);
|
||||
}
|
||||
|
||||
static void
|
||||
concheck_update_interval (NMDevice *self, gboolean check_now)
|
||||
concheck_update_interval (NMDevice *self, int addr_family, gboolean check_now)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
guint new_interval;
|
||||
const gboolean IS_IPv4 = (addr_family == AF_INET);
|
||||
|
||||
new_interval = nm_connectivity_get_interval (concheck_get_mgr (self));
|
||||
|
||||
new_interval = NM_MIN (new_interval, 7 *24 * 3600);
|
||||
|
||||
if (new_interval != priv->concheck_p_max_interval) {
|
||||
if (new_interval != priv->concheck_x[IS_IPv4].p_max_interval) {
|
||||
_LOGT (LOGD_CONCHECK, "connectivity: periodic-check: set interval to %u seconds", new_interval);
|
||||
priv->concheck_p_max_interval = new_interval;
|
||||
priv->concheck_x[IS_IPv4].p_max_interval = new_interval;
|
||||
}
|
||||
|
||||
if (!new_interval) {
|
||||
/* this will cancel any potentially pending timeout because max-interval is zero.
|
||||
* But it logs a nice message... */
|
||||
concheck_periodic_schedule_do (self, 0);
|
||||
concheck_periodic_schedule_do (self, addr_family, 0);
|
||||
|
||||
/* also update the fake connectivity state. */
|
||||
concheck_update_state (self, NM_CONNECTIVITY_FAKE, TRUE);
|
||||
concheck_update_state (self, addr_family, NM_CONNECTIVITY_FAKE, TRUE);
|
||||
return;
|
||||
}
|
||||
|
||||
concheck_periodic_schedule_set (self,
|
||||
addr_family,
|
||||
check_now
|
||||
? CONCHECK_SCHEDULE_UPDATE_INTERVAL_RESTART
|
||||
: CONCHECK_SCHEDULE_UPDATE_INTERVAL);
|
||||
|
|
@ -2707,13 +2730,16 @@ concheck_update_interval (NMDevice *self, gboolean check_now)
|
|||
void
|
||||
nm_device_check_connectivity_update_interval (NMDevice *self)
|
||||
{
|
||||
concheck_update_interval (self, FALSE);
|
||||
concheck_update_interval (self, AF_INET, FALSE);
|
||||
concheck_update_interval (self, AF_INET6, FALSE);
|
||||
}
|
||||
|
||||
static void
|
||||
concheck_update_state (NMDevice *self, NMConnectivityState state, gboolean allow_periodic_bump)
|
||||
concheck_update_state (NMDevice *self, int addr_family,
|
||||
NMConnectivityState state, gboolean allow_periodic_bump)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
const gboolean IS_IPv4 = (addr_family == AF_INET);
|
||||
|
||||
/* @state is a result of the connectivity check. We only expect a precise
|
||||
* number of possible values. */
|
||||
|
|
@ -2726,7 +2752,7 @@ concheck_update_state (NMDevice *self, NMConnectivityState state, gboolean allow
|
|||
if (state == NM_CONNECTIVITY_ERROR) {
|
||||
/* on error, we don't change the current connectivity state,
|
||||
* except making UNKNOWN to NONE. */
|
||||
state = priv->connectivity_state;
|
||||
state = priv->concheck_x[IS_IPv4].state;
|
||||
if (state == NM_CONNECTIVITY_UNKNOWN)
|
||||
state = NM_CONNECTIVITY_NONE;
|
||||
} else if (state == NM_CONNECTIVITY_FAKE) {
|
||||
|
|
@ -2745,11 +2771,11 @@ concheck_update_state (NMDevice *self, NMConnectivityState state, gboolean allow
|
|||
state = NM_CONNECTIVITY_NONE;
|
||||
}
|
||||
|
||||
if (priv->connectivity_state == state) {
|
||||
if (priv->concheck_x[IS_IPv4].state == state) {
|
||||
/* we got a connectivty update, but the state didn't change. If we were probing,
|
||||
* we bump the probe frequency. */
|
||||
if (allow_periodic_bump)
|
||||
concheck_periodic_schedule_set (self, CONCHECK_SCHEDULE_RETURNED_BUMP);
|
||||
concheck_periodic_schedule_set (self, addr_family, CONCHECK_SCHEDULE_RETURNED_BUMP);
|
||||
return;
|
||||
}
|
||||
/* we need to update the probe interval before emitting signals. Emitting
|
||||
|
|
@ -2758,23 +2784,22 @@ concheck_update_state (NMDevice *self, NMConnectivityState state, gboolean allow
|
|||
if (state == NM_CONNECTIVITY_FULL) {
|
||||
/* we reached full connectivity state. Stop probing by setting the
|
||||
* interval to the max. */
|
||||
concheck_periodic_schedule_set (self, CONCHECK_SCHEDULE_RETURNED_MAX);
|
||||
} else if (priv->connectivity_state == NM_CONNECTIVITY_FULL) {
|
||||
concheck_periodic_schedule_set (self, addr_family, CONCHECK_SCHEDULE_RETURNED_MAX);
|
||||
} else if (priv->concheck_x[IS_IPv4].state == NM_CONNECTIVITY_FULL) {
|
||||
/* we are about to loose connectivity. (re)start probing by setting
|
||||
* the timeout interval to the min. */
|
||||
concheck_periodic_schedule_set (self, CONCHECK_SCHEDULE_RETURNED_MIN);
|
||||
concheck_periodic_schedule_set (self, addr_family, CONCHECK_SCHEDULE_RETURNED_MIN);
|
||||
} else {
|
||||
if (allow_periodic_bump)
|
||||
concheck_periodic_schedule_set (self, CONCHECK_SCHEDULE_RETURNED_BUMP);
|
||||
concheck_periodic_schedule_set (self, addr_family, CONCHECK_SCHEDULE_RETURNED_BUMP);
|
||||
}
|
||||
|
||||
_LOGD (LOGD_CONCHECK, "connectivity state changed from %s to %s",
|
||||
nm_connectivity_state_to_string (priv->connectivity_state),
|
||||
nm_connectivity_state_to_string (priv->concheck_x[IS_IPv4].state),
|
||||
nm_connectivity_state_to_string (state));
|
||||
priv->connectivity_state = state;
|
||||
priv->concheck_x[IS_IPv4].state = state;
|
||||
|
||||
_notify (self, PROP_CONNECTIVITY);
|
||||
g_signal_emit (self, signals[CONNECTIVITY_CHANGED], 0);
|
||||
_notify (self, IS_IPv4 ? PROP_IP4_CONNECTIVITY : PROP_IP6_CONNECTIVITY);
|
||||
|
||||
if ( priv->state == NM_DEVICE_STATE_ACTIVATED
|
||||
&& !nm_device_sys_iface_state_is_external (self)) {
|
||||
|
|
@ -2788,9 +2813,10 @@ concheck_update_state (NMDevice *self, NMConnectivityState state, gboolean allow
|
|||
}
|
||||
|
||||
static void
|
||||
concheck_handle_complete (NMDeviceConnectivityHandle *handle,
|
||||
GError *error)
|
||||
concheck_handle_complete (NMDeviceConnectivityHandle *handle, GError *error)
|
||||
{
|
||||
const gboolean IS_IPv4 = (handle->addr_family == AF_INET);
|
||||
|
||||
/* The moment we invoke the callback, we unlink it. It signals
|
||||
* that @handle is handled -- as far as the callee of callback
|
||||
* is concerned. */
|
||||
|
|
@ -2802,7 +2828,7 @@ concheck_handle_complete (NMDeviceConnectivityHandle *handle,
|
|||
if (handle->callback) {
|
||||
handle->callback (handle->self,
|
||||
handle,
|
||||
NM_DEVICE_GET_PRIVATE (handle->self)->connectivity_state,
|
||||
NM_DEVICE_GET_PRIVATE (handle->self)->concheck_x[IS_IPv4].state,
|
||||
error,
|
||||
handle->user_data);
|
||||
}
|
||||
|
|
@ -2864,6 +2890,8 @@ concheck_cb (NMConnectivity *connectivity,
|
|||
any_periodic_before = FALSE;
|
||||
any_periodic_after = FALSE;
|
||||
c_list_for_each_entry (other_handle, &priv->concheck_lst_head, concheck_lst) {
|
||||
if (other_handle->addr_family != handle->addr_family)
|
||||
continue;
|
||||
if (other_handle->is_periodic_bump_on_complete) {
|
||||
if (other_handle->seq < seq)
|
||||
any_periodic_before = TRUE;
|
||||
|
|
@ -2890,7 +2918,7 @@ concheck_cb (NMConnectivity *connectivity,
|
|||
}
|
||||
|
||||
/* first update the new state, and emit signals. */
|
||||
concheck_update_state (self, state, allow_periodic_bump);
|
||||
concheck_update_state (self, handle->addr_family, state, allow_periodic_bump);
|
||||
|
||||
handle_is_alive = FALSE;
|
||||
|
||||
|
|
@ -2902,6 +2930,8 @@ concheck_cb (NMConnectivity *connectivity,
|
|||
* @handle, as they are automatically obsoleted. */
|
||||
check_handles:
|
||||
c_list_for_each_entry (other_handle, &priv->concheck_lst_head, concheck_lst) {
|
||||
if (other_handle->addr_family != handle->addr_family)
|
||||
continue;
|
||||
if (other_handle->seq >= seq) {
|
||||
/* it's not guaranteed that @handle is still in the list. It might already
|
||||
* be canceled while invoking callbacks for a previous other_handle.
|
||||
|
|
@ -2939,6 +2969,7 @@ check_handles:
|
|||
|
||||
static NMDeviceConnectivityHandle *
|
||||
concheck_start (NMDevice *self,
|
||||
int addr_family,
|
||||
NMDeviceConnectivityCallback callback,
|
||||
gpointer user_data,
|
||||
gboolean is_periodic)
|
||||
|
|
@ -2959,6 +2990,7 @@ concheck_start (NMDevice *self,
|
|||
handle->is_periodic = is_periodic;
|
||||
handle->is_periodic_bump = is_periodic;
|
||||
handle->is_periodic_bump_on_complete = is_periodic;
|
||||
handle->addr_family = addr_family;
|
||||
|
||||
c_list_link_tail (&priv->concheck_lst_head, &handle->concheck_lst);
|
||||
|
||||
|
|
@ -2967,6 +2999,8 @@ concheck_start (NMDevice *self,
|
|||
is_periodic ? ", periodic-check" : "");
|
||||
|
||||
handle->c_handle = nm_connectivity_check_start (concheck_get_mgr (self),
|
||||
handle->addr_family,
|
||||
nm_device_get_ip_ifindex (self),
|
||||
nm_device_get_ip_iface (self),
|
||||
concheck_cb,
|
||||
handle);
|
||||
|
|
@ -2975,6 +3009,7 @@ concheck_start (NMDevice *self,
|
|||
|
||||
NMDeviceConnectivityHandle *
|
||||
nm_device_check_connectivity (NMDevice *self,
|
||||
int addr_family,
|
||||
NMDeviceConnectivityCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
|
|
@ -2983,8 +3018,8 @@ nm_device_check_connectivity (NMDevice *self,
|
|||
if (!concheck_is_possible (self))
|
||||
return NULL;
|
||||
|
||||
concheck_periodic_schedule_set (self, CONCHECK_SCHEDULE_CHECK_EXTERNAL);
|
||||
handle = concheck_start (self, callback, user_data, FALSE);
|
||||
concheck_periodic_schedule_set (self, addr_family, CONCHECK_SCHEDULE_CHECK_EXTERNAL);
|
||||
handle = concheck_start (self, addr_family, callback, user_data, FALSE);
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
|
@ -3008,9 +3043,13 @@ nm_device_check_connectivity_cancel (NMDeviceConnectivityHandle *handle)
|
|||
NMConnectivityState
|
||||
nm_device_get_connectivity_state (NMDevice *self)
|
||||
{
|
||||
NMDevicePrivate *priv;
|
||||
|
||||
g_return_val_if_fail (NM_IS_DEVICE (self), NM_CONNECTIVITY_UNKNOWN);
|
||||
|
||||
return NM_DEVICE_GET_PRIVATE (self)->connectivity_state;
|
||||
priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
|
||||
return NM_MAX (priv->concheck_x[0].state, priv->concheck_x[1].state);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -7082,7 +7121,7 @@ ip_config_merge_and_apply (NMDevice *self,
|
|||
if (commit) {
|
||||
gboolean v;
|
||||
|
||||
v = default_route_metric_penalty_detect (self);
|
||||
v = default_route_metric_penalty_detect (self, addr_family);
|
||||
if (IS_IPv4)
|
||||
priv->default_route_metric_penalty_ip4_has = v;
|
||||
else
|
||||
|
|
@ -14850,8 +14889,8 @@ _set_state_full (NMDevice *self,
|
|||
if (ip_config_valid (old_state) && !ip_config_valid (state))
|
||||
notify_ip_properties (self);
|
||||
|
||||
concheck_update_interval (self,
|
||||
state == NM_DEVICE_STATE_ACTIVATED);
|
||||
concheck_update_interval (self, AF_INET, state == NM_DEVICE_STATE_ACTIVATED);
|
||||
concheck_update_interval (self, AF_INET6, state == NM_DEVICE_STATE_ACTIVATED);
|
||||
|
||||
/* Dispose of the cached activation request */
|
||||
if (req)
|
||||
|
|
@ -15815,7 +15854,8 @@ nm_device_init (NMDevice *self)
|
|||
c_list_init (&self->devices_lst);
|
||||
c_list_init (&priv->slaves);
|
||||
|
||||
priv->connectivity_state = NM_CONNECTIVITY_UNKNOWN;
|
||||
priv->concheck_x[0].state = NM_CONNECTIVITY_UNKNOWN;
|
||||
priv->concheck_x[1].state = NM_CONNECTIVITY_UNKNOWN;
|
||||
|
||||
nm_dbus_track_obj_path_init (&priv->parent_device, G_OBJECT (self), obj_properties[PROP_PARENT]);
|
||||
nm_dbus_track_obj_path_init (&priv->act_request, G_OBJECT (self), obj_properties[PROP_ACTIVE_CONNECTION]);
|
||||
|
|
@ -16016,7 +16056,8 @@ dispose (GObject *object)
|
|||
g_clear_object (&priv->lldp_listener);
|
||||
}
|
||||
|
||||
nm_clear_g_source (&priv->concheck_p_cur_id);
|
||||
nm_clear_g_source (&priv->concheck_x[0].p_cur_id);
|
||||
nm_clear_g_source (&priv->concheck_x[1].p_cur_id);
|
||||
|
||||
G_OBJECT_CLASS (nm_device_parent_class)->dispose (object);
|
||||
|
||||
|
|
@ -16353,8 +16394,11 @@ get_property (GObject *object, guint prop_id,
|
|||
case PROP_RX_BYTES:
|
||||
g_value_set_uint64 (value, priv->stats.rx_bytes);
|
||||
break;
|
||||
case PROP_CONNECTIVITY:
|
||||
g_value_set_uint (value, priv->connectivity_state);
|
||||
case PROP_IP4_CONNECTIVITY:
|
||||
g_value_set_uint (value, priv->concheck_x[1].state);
|
||||
break;
|
||||
case PROP_IP6_CONNECTIVITY:
|
||||
g_value_set_uint (value, priv->concheck_x[0].state);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
|
|
@ -16442,6 +16486,8 @@ static const NMDBusInterfaceInfoExtended interface_info_device = {
|
|||
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Metered", "u", NM_DEVICE_METERED),
|
||||
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("LldpNeighbors", "aa{sv}", NM_DEVICE_LLDP_NEIGHBORS),
|
||||
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE_L ("Real", "b", NM_DEVICE_REAL),
|
||||
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("Ip4Connectivity", "u", NM_DEVICE_IP4_CONNECTIVITY),
|
||||
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE ("Ip6Connectivity", "u", NM_DEVICE_IP6_CONNECTIVITY),
|
||||
),
|
||||
),
|
||||
};
|
||||
|
|
@ -16718,8 +16764,13 @@ nm_device_class_init (NMDeviceClass *klass)
|
|||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
obj_properties[PROP_CONNECTIVITY] =
|
||||
g_param_spec_uint (NM_DEVICE_CONNECTIVITY, "", "",
|
||||
obj_properties[PROP_IP4_CONNECTIVITY] =
|
||||
g_param_spec_uint (NM_DEVICE_IP4_CONNECTIVITY, "", "",
|
||||
NM_CONNECTIVITY_UNKNOWN, NM_CONNECTIVITY_FULL, NM_CONNECTIVITY_UNKNOWN,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
obj_properties[PROP_IP6_CONNECTIVITY] =
|
||||
g_param_spec_uint (NM_DEVICE_IP6_CONNECTIVITY, "", "",
|
||||
NM_CONNECTIVITY_UNKNOWN, NM_CONNECTIVITY_FULL, NM_CONNECTIVITY_UNKNOWN,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
|
@ -16799,12 +16850,4 @@ nm_device_class_init (NMDeviceClass *klass)
|
|||
G_SIGNAL_RUN_FIRST,
|
||||
0, NULL, NULL, NULL,
|
||||
G_TYPE_NONE, 0);
|
||||
|
||||
signals[CONNECTIVITY_CHANGED] =
|
||||
g_signal_new (NM_DEVICE_CONNECTIVITY_CHANGED,
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0, NULL, NULL,
|
||||
g_cclosure_marshal_VOID__VOID,
|
||||
G_TYPE_NONE, 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -143,13 +143,13 @@ nm_device_state_reason_check (NMDeviceStateReason reason)
|
|||
#define NM_DEVICE_STATE_CHANGED "state-changed"
|
||||
#define NM_DEVICE_LINK_INITIALIZED "link-initialized"
|
||||
#define NM_DEVICE_AUTOCONNECT_ALLOWED "autoconnect-allowed"
|
||||
#define NM_DEVICE_CONNECTIVITY_CHANGED "connectivity-changed"
|
||||
|
||||
#define NM_DEVICE_STATISTICS_REFRESH_RATE_MS "refresh-rate-ms"
|
||||
#define NM_DEVICE_STATISTICS_TX_BYTES "tx-bytes"
|
||||
#define NM_DEVICE_STATISTICS_RX_BYTES "rx-bytes"
|
||||
|
||||
#define NM_DEVICE_CONNECTIVITY "connectivity"
|
||||
#define NM_DEVICE_IP4_CONNECTIVITY "ip4-connectivity"
|
||||
#define NM_DEVICE_IP6_CONNECTIVITY "ip6-connectivity"
|
||||
|
||||
#define NM_TYPE_DEVICE (nm_device_get_type ())
|
||||
#define NM_DEVICE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_DEVICE, NMDevice))
|
||||
|
|
@ -818,6 +818,7 @@ typedef void (*NMDeviceConnectivityCallback) (NMDevice *self,
|
|||
void nm_device_check_connectivity_update_interval (NMDevice *self);
|
||||
|
||||
NMDeviceConnectivityHandle *nm_device_check_connectivity (NMDevice *self,
|
||||
int addr_family,
|
||||
NMDeviceConnectivityCallback callback,
|
||||
gpointer user_data);
|
||||
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@ typedef struct {
|
|||
|
||||
NMDnsManagerResolvConfManager rc_manager;
|
||||
char *mode;
|
||||
NMDnsPlugin *sd_resolve_plugin;
|
||||
NMDnsPlugin *plugin;
|
||||
|
||||
NMConfig *config;
|
||||
|
|
@ -1398,6 +1399,16 @@ update_dns (NMDnsManager *self,
|
|||
&searches, &options, &nameservers,
|
||||
&nis_servers, &nis_domain);
|
||||
|
||||
if (priv->plugin || priv->sd_resolve_plugin)
|
||||
rebuild_domain_lists (self);
|
||||
|
||||
if (priv->sd_resolve_plugin) {
|
||||
nm_dns_plugin_update (priv->sd_resolve_plugin,
|
||||
global_config,
|
||||
_ip_config_lst_head (self),
|
||||
priv->hostname);
|
||||
}
|
||||
|
||||
/* Let any plugins do their thing first */
|
||||
if (priv->plugin) {
|
||||
NMDnsPlugin *plugin = priv->plugin;
|
||||
|
|
@ -1413,7 +1424,6 @@ update_dns (NMDnsManager *self,
|
|||
}
|
||||
|
||||
_LOGD ("update-dns: updating plugin %s", plugin_name);
|
||||
rebuild_domain_lists (self);
|
||||
if (!nm_dns_plugin_update (plugin,
|
||||
global_config,
|
||||
_ip_config_lst_head (self),
|
||||
|
|
@ -1425,15 +1435,17 @@ update_dns (NMDnsManager *self,
|
|||
*/
|
||||
caching = FALSE;
|
||||
}
|
||||
/* Clear the generated search list as it points to
|
||||
* strings owned by IP configurations and we can't
|
||||
* guarantee they stay alive. */
|
||||
clear_domain_lists (self);
|
||||
|
||||
skip:
|
||||
;
|
||||
}
|
||||
|
||||
/* Clear the generated search list as it points to
|
||||
* strings owned by IP configurations and we can't
|
||||
* guarantee they stay alive. */
|
||||
clear_domain_lists (self);
|
||||
clear_domain_lists (self);
|
||||
|
||||
update_resolv_conf_no_stub (self, searches, nameservers, options);
|
||||
|
||||
/* If caching was successful, we only send 127.0.0.1 to /etc/resolv.conf
|
||||
|
|
@ -1932,9 +1944,11 @@ init_resolv_conf_mode (NMDnsManager *self, gboolean force_reload_plugin)
|
|||
NMDnsManagerPrivate *priv = NM_DNS_MANAGER_GET_PRIVATE (self);
|
||||
NMDnsManagerResolvConfManager rc_manager;
|
||||
const char *mode;
|
||||
gboolean systemd_resolved = FALSE;
|
||||
gboolean param_changed = FALSE, plugin_changed = FALSE;
|
||||
|
||||
mode = nm_config_data_get_dns_mode (nm_config_get_data (priv->config));
|
||||
systemd_resolved = nm_config_data_get_systemd_resolved (nm_config_get_data (priv->config));
|
||||
|
||||
if (nm_streq0 (mode, "none"))
|
||||
rc_manager = NM_DNS_MANAGER_RESOLV_CONF_MAN_UNMANAGED;
|
||||
|
|
@ -1980,6 +1994,7 @@ again:
|
|||
plugin_changed = TRUE;
|
||||
}
|
||||
mode = "systemd-resolved";
|
||||
systemd_resolved = FALSE;
|
||||
} else if (nm_streq0 (mode, "dnsmasq")) {
|
||||
if (force_reload_plugin || !NM_IS_DNS_DNSMASQ (priv->plugin)) {
|
||||
_clear_plugin (self);
|
||||
|
|
@ -2002,6 +2017,20 @@ again:
|
|||
plugin_changed = TRUE;
|
||||
}
|
||||
|
||||
/* The systemd-resolved plugin is special. We typically always want to keep
|
||||
* systemd-resolved up to date even if the configured plugin is different. */
|
||||
if (systemd_resolved) {
|
||||
if (!priv->sd_resolve_plugin) {
|
||||
priv->sd_resolve_plugin = nm_dns_systemd_resolved_new ();
|
||||
plugin_changed = TRUE;
|
||||
}
|
||||
} else {
|
||||
if (priv->sd_resolve_plugin) {
|
||||
g_clear_object (&priv->sd_resolve_plugin);
|
||||
plugin_changed = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (plugin_changed && priv->plugin) {
|
||||
g_signal_connect (priv->plugin, NM_DNS_PLUGIN_FAILED, G_CALLBACK (plugin_failed), self);
|
||||
g_signal_connect (priv->plugin, NM_DNS_PLUGIN_CHILD_QUIT, G_CALLBACK (plugin_child_quit), self);
|
||||
|
|
@ -2023,8 +2052,9 @@ again:
|
|||
}
|
||||
|
||||
if (param_changed || plugin_changed) {
|
||||
_LOGI ("init: dns=%s, rc-manager=%s%s%s%s",
|
||||
mode, _rc_manager_to_string (rc_manager),
|
||||
_LOGI ("init: dns=%s%s rc-manager=%s%s%s%s",
|
||||
mode, (systemd_resolved ? ",systemd-resolved" : ""),
|
||||
_rc_manager_to_string (rc_manager),
|
||||
NM_PRINT_FMT_QUOTED (priv->plugin, ", plugin=",
|
||||
nm_dns_plugin_get_name (priv->plugin), "", ""));
|
||||
}
|
||||
|
|
@ -2285,6 +2315,7 @@ dispose (GObject *object)
|
|||
if (priv->config)
|
||||
g_signal_handlers_disconnect_by_func (priv->config, config_changed_cb, self);
|
||||
|
||||
g_clear_object (&priv->sd_resolve_plugin);
|
||||
_clear_plugin (self);
|
||||
|
||||
priv->best_ip_config_4 = NULL;
|
||||
|
|
|
|||
|
|
@ -108,6 +108,7 @@ typedef struct {
|
|||
|
||||
char *dns_mode;
|
||||
char *rc_manager;
|
||||
gboolean systemd_resolved;
|
||||
|
||||
NMGlobalDnsConfig *global_dns;
|
||||
} NMConfigDataPrivate;
|
||||
|
|
@ -322,6 +323,14 @@ nm_config_data_get_rc_manager (const NMConfigData *self)
|
|||
return NM_CONFIG_DATA_GET_PRIVATE (self)->rc_manager;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_config_data_get_systemd_resolved (const NMConfigData *self)
|
||||
{
|
||||
g_return_val_if_fail (self, FALSE);
|
||||
|
||||
return NM_CONFIG_DATA_GET_PRIVATE (self)->systemd_resolved;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_config_data_get_ignore_carrier (const NMConfigData *self, NMDevice *device)
|
||||
{
|
||||
|
|
@ -1654,6 +1663,7 @@ constructed (GObject *object)
|
|||
|
||||
priv->dns_mode = nm_strstrip (g_key_file_get_string (priv->keyfile, NM_CONFIG_KEYFILE_GROUP_MAIN, "dns", NULL));
|
||||
priv->rc_manager = nm_strstrip (g_key_file_get_string (priv->keyfile, NM_CONFIG_KEYFILE_GROUP_MAIN, "rc-manager", NULL));
|
||||
priv->systemd_resolved = nm_config_keyfile_get_boolean (priv->keyfile, NM_CONFIG_KEYFILE_GROUP_MAIN, "systemd-resolved", TRUE);
|
||||
|
||||
priv->ignore_carrier = nm_config_get_match_spec (priv->keyfile, NM_CONFIG_KEYFILE_GROUP_MAIN, "ignore-carrier", NULL);
|
||||
priv->assume_ipv6ll_only = nm_config_get_match_spec (priv->keyfile, NM_CONFIG_KEYFILE_GROUP_MAIN, "assume-ipv6ll-only", NULL);
|
||||
|
|
|
|||
|
|
@ -170,6 +170,7 @@ gboolean nm_config_data_get_no_auto_default_for_device (const NMConfigD
|
|||
|
||||
const char *nm_config_data_get_dns_mode (const NMConfigData *self);
|
||||
const char *nm_config_data_get_rc_manager (const NMConfigData *self);
|
||||
gboolean nm_config_data_get_systemd_resolved (const NMConfigData *self);
|
||||
|
||||
gboolean nm_config_data_get_ignore_carrier (const NMConfigData *self, NMDevice *device);
|
||||
gboolean nm_config_data_get_assume_ipv6ll_only (const NMConfigData *self, NMDevice *device);
|
||||
|
|
|
|||
|
|
@ -17,12 +17,13 @@
|
|||
*
|
||||
* Copyright (C) 2011 Thomas Bechtold <thomasbechtold@jpberlin.de>
|
||||
* Copyright (C) 2011 Dan Williams <dcbw@redhat.com>
|
||||
* Copyright (C) 2016,2017 Red Hat, Inc.
|
||||
* Copyright (C) 2016 - 2018 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include "nm-default.h"
|
||||
|
||||
#include "nm-connectivity.h"
|
||||
#include "nm-dbus-manager.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
|
@ -67,13 +68,19 @@ struct _NMConnectivityCheckHandle {
|
|||
gpointer user_data;
|
||||
|
||||
char *ifspec;
|
||||
int addr_family;
|
||||
|
||||
#if WITH_CONCHECK
|
||||
struct {
|
||||
char *response;
|
||||
|
||||
int ifindex;
|
||||
GCancellable *resolve_cancellable;
|
||||
CURLM *curl_mhandle;
|
||||
guint curl_timer;
|
||||
CURL *curl_ehandle;
|
||||
struct curl_slist *request_headers;
|
||||
struct curl_slist *hosts;
|
||||
|
||||
GString *recv_msg;
|
||||
} concheck;
|
||||
|
|
@ -98,16 +105,12 @@ typedef struct {
|
|||
CList handles_lst_head;
|
||||
CList completed_handles_lst_head;
|
||||
char *uri;
|
||||
char *host;
|
||||
char *port;
|
||||
char *response;
|
||||
gboolean enabled;
|
||||
guint interval;
|
||||
NMConfig *config;
|
||||
#if WITH_CONCHECK
|
||||
struct {
|
||||
CURLM *curl_mhandle;
|
||||
guint curl_timer;
|
||||
} concheck;
|
||||
#endif
|
||||
} NMConnectivityPrivate;
|
||||
|
||||
struct _NMConnectivity {
|
||||
|
|
@ -139,9 +142,10 @@ NM_DEFINE_SINGLETON_GETTER (NMConnectivity, nm_connectivity_get, NM_TYPE_CONNECT
|
|||
_nm_log (__level, _NMLOG2_DOMAIN, 0, \
|
||||
(cb_data->ifspec ? &cb_data->ifspec[3] : NULL), \
|
||||
NULL, \
|
||||
"connectivity: (%s) " \
|
||||
"connectivity: (%s,AF_INET%s) " \
|
||||
_NM_UTILS_MACRO_FIRST (__VA_ARGS__), \
|
||||
(cb_data->ifspec ? &cb_data->ifspec[3] : "") \
|
||||
(cb_data->ifspec ? &cb_data->ifspec[3] : ""), \
|
||||
(cb_data->addr_family == AF_INET6 ? "6" : "") \
|
||||
_NM_UTILS_MACRO_REST (__VA_ARGS__)); \
|
||||
} \
|
||||
} G_STMT_END
|
||||
|
|
@ -171,8 +175,6 @@ cb_data_complete (NMConnectivityCheckHandle *cb_data,
|
|||
|
||||
#if WITH_CONCHECK
|
||||
if (cb_data->concheck.curl_ehandle) {
|
||||
NMConnectivityPrivate *priv;
|
||||
|
||||
/* Contrary to what cURL manual claim it is *not* safe to remove
|
||||
* the easy handle "at any moment"; specifically it's not safe to
|
||||
* remove *any* handle from within a libcurl callback. That is
|
||||
|
|
@ -187,13 +189,16 @@ cb_data_complete (NMConnectivityCheckHandle *cb_data,
|
|||
curl_easy_setopt (cb_data->concheck.curl_ehandle, CURLOPT_PRIVATE, NULL);
|
||||
curl_easy_setopt (cb_data->concheck.curl_ehandle, CURLOPT_HTTPHEADER, NULL);
|
||||
|
||||
priv = NM_CONNECTIVITY_GET_PRIVATE (self);
|
||||
|
||||
curl_multi_remove_handle (priv->concheck.curl_mhandle, cb_data->concheck.curl_ehandle);
|
||||
curl_multi_remove_handle (cb_data->concheck.curl_mhandle,
|
||||
cb_data->concheck.curl_ehandle);
|
||||
curl_easy_cleanup (cb_data->concheck.curl_ehandle);
|
||||
curl_multi_cleanup (cb_data->concheck.curl_mhandle);
|
||||
|
||||
curl_slist_free_all (cb_data->concheck.request_headers);
|
||||
curl_slist_free_all (cb_data->concheck.hosts);
|
||||
}
|
||||
nm_clear_g_source (&cb_data->concheck.curl_timer);
|
||||
nm_clear_g_cancellable (&cb_data->concheck.resolve_cancellable);
|
||||
#endif
|
||||
|
||||
nm_clear_g_source (&cb_data->timeout_id);
|
||||
|
|
@ -285,7 +290,7 @@ _con_curl_check_connectivity (CURLM *mhandle, int sockfd, int ev_bitmask)
|
|||
|
||||
ret = curl_multi_socket_action (mhandle, sockfd, ev_bitmask, &running_handles);
|
||||
if (ret != CURLM_OK) {
|
||||
_LOGD ("connectivity check failed: %d", ret);
|
||||
_LOGD ("connectivity check failed: (%d) %s", ret, curl_easy_strerror (ret));
|
||||
success = FALSE;
|
||||
}
|
||||
|
||||
|
|
@ -297,7 +302,8 @@ _con_curl_check_connectivity (CURLM *mhandle, int sockfd, int ev_bitmask)
|
|||
/* Here we have completed a session. Check easy session result. */
|
||||
eret = curl_easy_getinfo (msg->easy_handle, CURLINFO_PRIVATE, (char **) &cb_data);
|
||||
if (eret != CURLE_OK) {
|
||||
_LOGD ("curl cannot extract cb_data for easy handle, skipping msg");
|
||||
_LOGD ("curl cannot extract cb_data for easy handle, skipping msg: (%d) %s",
|
||||
eret, curl_easy_strerror (eret));
|
||||
success = FALSE;
|
||||
continue;
|
||||
}
|
||||
|
|
@ -314,7 +320,9 @@ _con_curl_check_connectivity (CURLM *mhandle, int sockfd, int ev_bitmask)
|
|||
cb_data_queue_completed (cb_data,
|
||||
NM_CONNECTIVITY_LIMITED,
|
||||
NULL,
|
||||
g_strdup_printf ("check failed with curl status %d", msg->data.result));
|
||||
g_strdup_printf ("check failed: (%d) %s",
|
||||
msg->data.result,
|
||||
curl_easy_strerror (msg->data.result)));
|
||||
} else if ( !((_check_handle_get_response (cb_data))[0])
|
||||
&& (curl_easy_getinfo (msg->easy_handle, CURLINFO_RESPONSE_CODE, &response_code) == CURLE_OK)
|
||||
&& response_code == 204) {
|
||||
|
|
@ -346,29 +354,27 @@ _con_curl_check_connectivity (CURLM *mhandle, int sockfd, int ev_bitmask)
|
|||
static gboolean
|
||||
_con_curl_timeout_cb (gpointer user_data)
|
||||
{
|
||||
gs_unref_object NMConnectivity *self = g_object_ref (NM_CONNECTIVITY (user_data));
|
||||
NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self);
|
||||
NMConnectivityCheckHandle *cb_data = user_data;
|
||||
|
||||
priv->concheck.curl_timer = 0;
|
||||
_con_curl_check_connectivity (priv->concheck.curl_mhandle, CURL_SOCKET_TIMEOUT, 0);
|
||||
_complete_queued (self);
|
||||
cb_data->concheck.curl_timer = 0;
|
||||
_con_curl_check_connectivity (cb_data->concheck.curl_mhandle, CURL_SOCKET_TIMEOUT, 0);
|
||||
_complete_queued (cb_data->self);
|
||||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static int
|
||||
multi_timer_cb (CURLM *multi, long timeout_ms, void *userdata)
|
||||
{
|
||||
NMConnectivity *self = NM_CONNECTIVITY (userdata);
|
||||
NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self);
|
||||
NMConnectivityCheckHandle *cb_data = userdata;
|
||||
|
||||
nm_clear_g_source (&priv->concheck.curl_timer);
|
||||
nm_clear_g_source (&cb_data->concheck.curl_timer);
|
||||
if (timeout_ms != -1)
|
||||
priv->concheck.curl_timer = g_timeout_add (timeout_ms, _con_curl_timeout_cb, self);
|
||||
cb_data->concheck.curl_timer = g_timeout_add (timeout_ms, _con_curl_timeout_cb, cb_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
NMConnectivity *self;
|
||||
NMConnectivityCheckHandle *cb_data;
|
||||
GIOChannel *ch;
|
||||
|
||||
/* this is a very simplistic weak-pointer. If ConCurlSockData gets
|
||||
|
|
@ -385,8 +391,7 @@ static gboolean
|
|||
_con_curl_socketevent_cb (GIOChannel *ch, GIOCondition condition, gpointer user_data)
|
||||
{
|
||||
ConCurlSockData *fdp = user_data;
|
||||
gs_unref_object NMConnectivity *self = g_object_ref (fdp->self);
|
||||
NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self);
|
||||
NMConnectivityCheckHandle *cb_data = fdp->cb_data;
|
||||
int fd = g_io_channel_unix_get_fd (ch);
|
||||
int action = 0;
|
||||
gboolean fdp_destroyed = FALSE;
|
||||
|
|
@ -402,7 +407,7 @@ _con_curl_socketevent_cb (GIOChannel *ch, GIOCondition condition, gpointer user_
|
|||
nm_assert (!fdp->destroy_notify);
|
||||
fdp->destroy_notify = &fdp_destroyed;
|
||||
|
||||
success = _con_curl_check_connectivity (priv->concheck.curl_mhandle, fd, action);
|
||||
success = _con_curl_check_connectivity (cb_data->concheck.curl_mhandle, fd, action);
|
||||
|
||||
if (fdp_destroyed) {
|
||||
/* hups. fdp got invalidated during _con_curl_check_connectivity(). That's fine,
|
||||
|
|
@ -414,7 +419,7 @@ _con_curl_socketevent_cb (GIOChannel *ch, GIOCondition condition, gpointer user_
|
|||
fdp->ev = 0;
|
||||
}
|
||||
|
||||
_complete_queued (self);
|
||||
_complete_queued (cb_data->self);
|
||||
|
||||
return success ? G_SOURCE_CONTINUE : G_SOURCE_REMOVE;
|
||||
}
|
||||
|
|
@ -422,8 +427,7 @@ _con_curl_socketevent_cb (GIOChannel *ch, GIOCondition condition, gpointer user_
|
|||
static int
|
||||
multi_socket_cb (CURL *e_handle, curl_socket_t fd, int what, void *userdata, void *socketp)
|
||||
{
|
||||
NMConnectivity *self = NM_CONNECTIVITY (userdata);
|
||||
NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self);
|
||||
NMConnectivityCheckHandle *cb_data = userdata;
|
||||
ConCurlSockData *fdp = socketp;
|
||||
GIOCondition condition = 0;
|
||||
|
||||
|
|
@ -433,7 +437,7 @@ multi_socket_cb (CURL *e_handle, curl_socket_t fd, int what, void *userdata, voi
|
|||
if (fdp) {
|
||||
if (fdp->destroy_notify)
|
||||
*fdp->destroy_notify = TRUE;
|
||||
curl_multi_assign (priv->concheck.curl_mhandle, fd, NULL);
|
||||
curl_multi_assign (cb_data->concheck.curl_mhandle, fd, NULL);
|
||||
nm_clear_g_source (&fdp->ev);
|
||||
g_io_channel_unref (fdp->ch);
|
||||
g_slice_free (ConCurlSockData, fdp);
|
||||
|
|
@ -441,9 +445,9 @@ multi_socket_cb (CURL *e_handle, curl_socket_t fd, int what, void *userdata, voi
|
|||
} else {
|
||||
if (!fdp) {
|
||||
fdp = g_slice_new0 (ConCurlSockData);
|
||||
fdp->self = self;
|
||||
fdp->cb_data = cb_data;
|
||||
fdp->ch = g_io_channel_unix_new (fd);
|
||||
curl_multi_assign (priv->concheck.curl_mhandle, fd, fdp);
|
||||
curl_multi_assign (cb_data->concheck.curl_mhandle, fd, fdp);
|
||||
} else
|
||||
nm_clear_g_source (&fdp->ev);
|
||||
|
||||
|
|
@ -556,8 +560,171 @@ _idle_cb (gpointer user_data)
|
|||
return G_SOURCE_REMOVE;
|
||||
}
|
||||
|
||||
static void
|
||||
do_curl_request (NMConnectivityCheckHandle *cb_data)
|
||||
{
|
||||
NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (cb_data->self);
|
||||
CURLM *mhandle;
|
||||
CURL *ehandle;
|
||||
long resolve;
|
||||
|
||||
mhandle = curl_multi_init ();
|
||||
if (!mhandle) {
|
||||
cb_data_complete (cb_data, NM_CONNECTIVITY_ERROR, "curl error");
|
||||
return;
|
||||
}
|
||||
|
||||
ehandle = curl_easy_init ();
|
||||
if (!ehandle) {
|
||||
curl_multi_cleanup (mhandle);
|
||||
cb_data_complete (cb_data, NM_CONNECTIVITY_ERROR, "curl error");
|
||||
return;
|
||||
}
|
||||
|
||||
cb_data->concheck.response = g_strdup (priv->response);
|
||||
cb_data->concheck.curl_mhandle = mhandle;
|
||||
cb_data->concheck.curl_ehandle = ehandle;
|
||||
cb_data->concheck.request_headers = curl_slist_append (NULL, "Connection: close");
|
||||
cb_data->timeout_id = g_timeout_add_seconds (20, _timeout_cb, cb_data);
|
||||
|
||||
curl_multi_setopt (mhandle, CURLMOPT_SOCKETFUNCTION, multi_socket_cb);
|
||||
curl_multi_setopt (mhandle, CURLMOPT_SOCKETDATA, cb_data);
|
||||
curl_multi_setopt (mhandle, CURLMOPT_TIMERFUNCTION, multi_timer_cb);
|
||||
curl_multi_setopt (mhandle, CURLMOPT_TIMERDATA, cb_data);
|
||||
curl_multi_setopt (mhandle, CURLOPT_VERBOSE, 1);
|
||||
|
||||
switch (cb_data->addr_family) {
|
||||
case AF_INET:
|
||||
resolve = CURL_IPRESOLVE_V4;
|
||||
break;
|
||||
case AF_INET6:
|
||||
resolve = CURL_IPRESOLVE_V6;
|
||||
break;
|
||||
case AF_UNSPEC:
|
||||
resolve = CURL_IPRESOLVE_WHATEVER;
|
||||
break;
|
||||
default:
|
||||
resolve = CURL_IPRESOLVE_WHATEVER;
|
||||
g_warn_if_reached ();
|
||||
}
|
||||
|
||||
curl_easy_setopt (ehandle, CURLOPT_URL, priv->uri);
|
||||
curl_easy_setopt (ehandle, CURLOPT_WRITEFUNCTION, easy_write_cb);
|
||||
curl_easy_setopt (ehandle, CURLOPT_WRITEDATA, cb_data);
|
||||
curl_easy_setopt (ehandle, CURLOPT_HEADERFUNCTION, easy_header_cb);
|
||||
curl_easy_setopt (ehandle, CURLOPT_HEADERDATA, cb_data);
|
||||
curl_easy_setopt (ehandle, CURLOPT_PRIVATE, cb_data);
|
||||
curl_easy_setopt (ehandle, CURLOPT_HTTPHEADER, cb_data->concheck.request_headers);
|
||||
curl_easy_setopt (ehandle, CURLOPT_INTERFACE, cb_data->ifspec);
|
||||
curl_easy_setopt (ehandle, CURLOPT_RESOLVE, cb_data->concheck.hosts);
|
||||
curl_easy_setopt (ehandle, CURLOPT_IPRESOLVE, resolve);
|
||||
|
||||
curl_multi_add_handle (mhandle, ehandle);
|
||||
}
|
||||
|
||||
static void
|
||||
resolve_cb (GObject *object, GAsyncResult *res, gpointer user_data)
|
||||
{
|
||||
NMConnectivityCheckHandle *cb_data = user_data;
|
||||
NMConnectivity *self;
|
||||
NMConnectivityPrivate *priv;
|
||||
GVariant *result;
|
||||
GVariant *addresses;
|
||||
gsize no_addresses;
|
||||
int ifindex;
|
||||
int addr_family;
|
||||
GVariant *address = NULL;
|
||||
const guchar *address_buf;
|
||||
gsize len = 0;
|
||||
char str[INET6_ADDRSTRLEN + 1] = { 0, };
|
||||
char *host;
|
||||
gsize i;
|
||||
gs_free_error GError *error = NULL;
|
||||
|
||||
result = g_dbus_proxy_call_finish (G_DBUS_PROXY (object), res, &error);
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
return;
|
||||
|
||||
self = cb_data->self;
|
||||
priv = NM_CONNECTIVITY_GET_PRIVATE (self);
|
||||
|
||||
if (!result) {
|
||||
/* Never mind. Just let do curl do its own resolving. */
|
||||
_LOG2D ("can't resolve a name via systemd-resolved: %s", error->message);
|
||||
do_curl_request (cb_data);
|
||||
return;
|
||||
}
|
||||
|
||||
addresses = g_variant_get_child_value (result, 0);
|
||||
no_addresses = g_variant_n_children (addresses);
|
||||
g_variant_unref (result);
|
||||
|
||||
for (i = 0; i < no_addresses; i++) {
|
||||
g_variant_get_child (addresses, i, "(ii@ay)", &ifindex, &addr_family, &address);
|
||||
address_buf = g_variant_get_fixed_array (address, &len, 1);
|
||||
|
||||
if ( (addr_family == AF_INET && len == sizeof (struct in_addr))
|
||||
|| (addr_family == AF_INET6 && len == sizeof (struct in6_addr))) {
|
||||
inet_ntop (addr_family, address_buf, str, sizeof (str));
|
||||
host = g_strdup_printf ("%s:%s:%s", priv->host, priv->port ?: "80", str);
|
||||
cb_data->concheck.hosts = curl_slist_append (cb_data->concheck.hosts, host);
|
||||
_LOG2T ("adding '%s' to curl resolve list", host);
|
||||
g_free (host);
|
||||
}
|
||||
|
||||
g_variant_unref (address);
|
||||
}
|
||||
|
||||
g_variant_unref (addresses);
|
||||
do_curl_request (cb_data);
|
||||
}
|
||||
|
||||
#define SD_RESOLVED_DNS 1
|
||||
|
||||
static void
|
||||
resolved_proxy_created (GObject *object, GAsyncResult *res, gpointer user_data)
|
||||
{
|
||||
NMConnectivityCheckHandle *cb_data = user_data;
|
||||
NMConnectivity *self;
|
||||
NMConnectivityPrivate *priv;
|
||||
gs_free_error GError *error = NULL;
|
||||
GDBusProxy *proxy;
|
||||
|
||||
proxy = g_dbus_proxy_new_for_bus_finish (res, &error);
|
||||
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
|
||||
return;
|
||||
|
||||
self = cb_data->self;
|
||||
priv = NM_CONNECTIVITY_GET_PRIVATE (self);
|
||||
|
||||
if (!proxy) {
|
||||
/* Log a warning, but still proceed without systemd-resolved */
|
||||
_LOG2D ("failed to connect to resolved via DBus: %s", error->message);
|
||||
do_curl_request (cb_data);
|
||||
return;
|
||||
}
|
||||
|
||||
g_dbus_proxy_call (proxy,
|
||||
"ResolveHostname",
|
||||
g_variant_new ("(isit)",
|
||||
cb_data->concheck.ifindex,
|
||||
priv->host,
|
||||
(gint32) cb_data->addr_family,
|
||||
(guint64) SD_RESOLVED_DNS),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
cb_data->concheck.resolve_cancellable,
|
||||
resolve_cb,
|
||||
cb_data);
|
||||
g_object_unref (proxy);
|
||||
|
||||
_LOG2D ("resolving '%s' for '%s' using systemd-resolved", priv->host, priv->uri);
|
||||
}
|
||||
|
||||
NMConnectivityCheckHandle *
|
||||
nm_connectivity_check_start (NMConnectivity *self,
|
||||
int addr_family,
|
||||
int ifindex,
|
||||
const char *iface,
|
||||
NMConnectivityCheckCallback callback,
|
||||
gpointer user_data)
|
||||
|
|
@ -577,40 +744,35 @@ nm_connectivity_check_start (NMConnectivity *self,
|
|||
cb_data->callback = callback;
|
||||
cb_data->user_data = user_data;
|
||||
cb_data->completed_state = NM_CONNECTIVITY_UNKNOWN;
|
||||
cb_data->addr_family = addr_family;
|
||||
|
||||
if (iface)
|
||||
cb_data->ifspec = g_strdup_printf ("if!%s", iface);
|
||||
|
||||
#if WITH_CONCHECK
|
||||
if (iface) {
|
||||
CURL *ehandle;
|
||||
if (iface && ifindex > 0 && priv->enabled && priv->host) {
|
||||
cb_data->concheck.ifindex = ifindex;
|
||||
cb_data->concheck.resolve_cancellable = g_cancellable_new ();
|
||||
|
||||
if ( priv->enabled
|
||||
&& (ehandle = curl_easy_init ())) {
|
||||
g_dbus_proxy_new_for_bus (G_BUS_TYPE_SYSTEM,
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES |
|
||||
G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS,
|
||||
NULL,
|
||||
"org.freedesktop.resolve1",
|
||||
"/org/freedesktop/resolve1",
|
||||
"org.freedesktop.resolve1.Manager",
|
||||
cb_data->concheck.resolve_cancellable,
|
||||
resolved_proxy_created,
|
||||
cb_data);
|
||||
|
||||
cb_data->concheck.response = g_strdup (priv->response);
|
||||
cb_data->concheck.curl_ehandle = ehandle;
|
||||
cb_data->concheck.request_headers = curl_slist_append (NULL, "Connection: close");
|
||||
curl_easy_setopt (ehandle, CURLOPT_URL, priv->uri);
|
||||
curl_easy_setopt (ehandle, CURLOPT_WRITEFUNCTION, easy_write_cb);
|
||||
curl_easy_setopt (ehandle, CURLOPT_WRITEDATA, cb_data);
|
||||
curl_easy_setopt (ehandle, CURLOPT_HEADERFUNCTION, easy_header_cb);
|
||||
curl_easy_setopt (ehandle, CURLOPT_HEADERDATA, cb_data);
|
||||
curl_easy_setopt (ehandle, CURLOPT_PRIVATE, cb_data);
|
||||
curl_easy_setopt (ehandle, CURLOPT_HTTPHEADER, cb_data->concheck.request_headers);
|
||||
curl_easy_setopt (ehandle, CURLOPT_INTERFACE, cb_data->ifspec);
|
||||
curl_multi_add_handle (priv->concheck.curl_mhandle, ehandle);
|
||||
|
||||
cb_data->timeout_id = g_timeout_add_seconds (20, _timeout_cb, cb_data);
|
||||
|
||||
_LOG2D ("start request to '%s'", priv->uri);
|
||||
return cb_data;
|
||||
}
|
||||
_LOG2D ("start request to '%s'", priv->uri);
|
||||
return cb_data;
|
||||
}
|
||||
#endif
|
||||
|
||||
_LOG2D ("start fake request");
|
||||
cb_data->timeout_id = g_idle_add (_idle_cb, cb_data);
|
||||
|
||||
return cb_data;
|
||||
}
|
||||
|
||||
|
|
@ -646,6 +808,54 @@ nm_connectivity_get_interval (NMConnectivity *self)
|
|||
: 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
host_and_port_from_uri (const char *uri, char **host, char **port)
|
||||
{
|
||||
const char *p = uri;
|
||||
const char *host_begin = NULL;
|
||||
size_t host_len = 0;
|
||||
const char *port_begin = NULL;
|
||||
size_t port_len = 0;
|
||||
|
||||
/* scheme */
|
||||
while (*p != ':' && *p != '/') {
|
||||
if (!*p++)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* :// */
|
||||
if (*p++ != ':')
|
||||
return FALSE;
|
||||
if (*p++ != '/')
|
||||
return FALSE;
|
||||
if (*p++ != '/')
|
||||
return FALSE;
|
||||
/* host */
|
||||
if (*p == '[')
|
||||
return FALSE;
|
||||
host_begin = p;
|
||||
while (*p && *p != ':' && *p != '/') {
|
||||
host_len++;
|
||||
p++;
|
||||
}
|
||||
if (host_len == 0)
|
||||
return FALSE;
|
||||
*host = strndup (host_begin, host_len);
|
||||
|
||||
/* port */
|
||||
if (*p++ == ':') {
|
||||
port_begin = p;
|
||||
while (*p && *p != '/') {
|
||||
port_len++;
|
||||
p++;
|
||||
}
|
||||
if (port_len)
|
||||
*port = strndup (port_begin, port_len);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
update_config (NMConnectivity *self, NMConfigData *config_data)
|
||||
{
|
||||
|
|
@ -679,6 +889,10 @@ update_config (NMConnectivity *self, NMConfigData *config_data)
|
|||
if (changed) {
|
||||
g_free (priv->uri);
|
||||
priv->uri = g_strdup (uri);
|
||||
|
||||
g_clear_pointer (&priv->host, g_free);
|
||||
g_clear_pointer (&priv->port, g_free);
|
||||
host_and_port_from_uri (uri, &priv->host, &priv->port);
|
||||
}
|
||||
|
||||
/* Set the interval. */
|
||||
|
|
@ -691,11 +905,8 @@ update_config (NMConnectivity *self, NMConfigData *config_data)
|
|||
|
||||
enabled = FALSE;
|
||||
#if WITH_CONCHECK
|
||||
/* connectivity checking also requires a valid URI, interval and
|
||||
* curl_mhandle */
|
||||
if ( priv->uri
|
||||
&& priv->interval
|
||||
&& priv->concheck.curl_mhandle)
|
||||
&& priv->interval)
|
||||
enabled = nm_config_data_get_connectivity_enabled (config_data);
|
||||
#endif
|
||||
|
||||
|
|
@ -734,6 +945,9 @@ static void
|
|||
nm_connectivity_init (NMConnectivity *self)
|
||||
{
|
||||
NMConnectivityPrivate *priv = NM_CONNECTIVITY_GET_PRIVATE (self);
|
||||
#if WITH_CONCHECK
|
||||
CURLcode ret;
|
||||
#endif
|
||||
|
||||
c_list_init (&priv->handles_lst_head);
|
||||
c_list_init (&priv->completed_handles_lst_head);
|
||||
|
|
@ -745,17 +959,10 @@ nm_connectivity_init (NMConnectivity *self)
|
|||
self);
|
||||
|
||||
#if WITH_CONCHECK
|
||||
if (curl_global_init (CURL_GLOBAL_ALL) == CURLE_OK)
|
||||
priv->concheck.curl_mhandle = curl_multi_init ();
|
||||
|
||||
if (!priv->concheck.curl_mhandle)
|
||||
_LOGE ("unable to init cURL, connectivity check will not work");
|
||||
else {
|
||||
curl_multi_setopt (priv->concheck.curl_mhandle, CURLMOPT_SOCKETFUNCTION, multi_socket_cb);
|
||||
curl_multi_setopt (priv->concheck.curl_mhandle, CURLMOPT_SOCKETDATA, self);
|
||||
curl_multi_setopt (priv->concheck.curl_mhandle, CURLMOPT_TIMERFUNCTION, multi_timer_cb);
|
||||
curl_multi_setopt (priv->concheck.curl_mhandle, CURLMOPT_TIMERDATA, self);
|
||||
curl_multi_setopt (priv->concheck.curl_mhandle, CURLOPT_VERBOSE, 1);
|
||||
ret = curl_global_init (CURL_GLOBAL_ALL);
|
||||
if (!ret == CURLE_OK) {
|
||||
_LOGE ("unable to init cURL, connectivity check will not work: (%d) %s",
|
||||
ret, curl_easy_strerror (ret));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -777,12 +984,11 @@ dispose (GObject *object)
|
|||
cb_data_complete (cb_data, NM_CONNECTIVITY_DISPOSING, "shutting down");
|
||||
|
||||
g_clear_pointer (&priv->uri, g_free);
|
||||
g_clear_pointer (&priv->host, g_free);
|
||||
g_clear_pointer (&priv->port, g_free);
|
||||
g_clear_pointer (&priv->response, g_free);
|
||||
|
||||
#if WITH_CONCHECK
|
||||
nm_clear_g_source (&priv->concheck.curl_timer);
|
||||
|
||||
curl_multi_cleanup (priv->concheck.curl_mhandle);
|
||||
curl_global_cleanup ();
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -58,6 +58,8 @@ typedef void (*NMConnectivityCheckCallback) (NMConnectivity *self,
|
|||
gpointer user_data);
|
||||
|
||||
NMConnectivityCheckHandle *nm_connectivity_check_start (NMConnectivity *self,
|
||||
int family,
|
||||
int ifindex,
|
||||
const char *iface,
|
||||
NMConnectivityCheckCallback callback,
|
||||
gpointer user_data);
|
||||
|
|
|
|||
|
|
@ -2812,6 +2812,7 @@ device_realized (NMDevice *device,
|
|||
|
||||
static void
|
||||
device_connectivity_changed (NMDevice *device,
|
||||
GParamSpec *pspec,
|
||||
NMManager *self)
|
||||
{
|
||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE (self);
|
||||
|
|
@ -2954,7 +2955,10 @@ add_device (NMManager *self, NMDevice *device, GError **error)
|
|||
G_CALLBACK (device_realized),
|
||||
self);
|
||||
|
||||
g_signal_connect (device, NM_DEVICE_CONNECTIVITY_CHANGED,
|
||||
g_signal_connect (device, "notify::" NM_DEVICE_IP4_CONNECTIVITY,
|
||||
G_CALLBACK (device_connectivity_changed),
|
||||
self);
|
||||
g_signal_connect (device, "notify::" NM_DEVICE_IP6_CONNECTIVITY,
|
||||
G_CALLBACK (device_connectivity_changed),
|
||||
self);
|
||||
|
||||
|
|
@ -6041,6 +6045,12 @@ check_connectivity_auth_done_cb (NMAuthChain *chain,
|
|||
|
||||
c_list_for_each_entry (device, &priv->devices_lst_head, devices_lst) {
|
||||
if (nm_device_check_connectivity (device,
|
||||
AF_INET,
|
||||
device_connectivity_done,
|
||||
data))
|
||||
data->remaining++;
|
||||
if (nm_device_check_connectivity (device,
|
||||
AF_INET6,
|
||||
device_connectivity_done,
|
||||
data))
|
||||
data->remaining++;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue