diff options
author | Thomas Haller <thaller@redhat.com> | 2019-02-08 17:28:58 +0100 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2019-02-08 17:28:58 +0100 |
commit | aacb3c4f5b59e1728f01ede6cddc0d9267611e86 (patch) | |
tree | 2f64cca015bf679214683182d89238e916d51939 | |
parent | bba33ba20c6d3bdbbafe6184903e0437f11c9c28 (diff) | |
parent | 983b430075f1da5ca47ee7bdc5863eb0218a9bd1 (diff) | |
download | NetworkManager-aacb3c4f5b59e1728f01ede6cddc0d9267611e86.tar.gz |
connectivity: merge branch 'th/connectivity-rp-filter'
-rw-r--r-- | contrib/fedora/rpm/20-connectivity-fedora.conf | 5 | ||||
-rw-r--r-- | contrib/fedora/rpm/20-connectivity-redhat.conf | 5 | ||||
-rw-r--r-- | man/NetworkManager.conf.xml | 8 | ||||
-rw-r--r-- | src/devices/nm-device.c | 36 |
4 files changed, 54 insertions, 0 deletions
diff --git a/contrib/fedora/rpm/20-connectivity-fedora.conf b/contrib/fedora/rpm/20-connectivity-fedora.conf index 945bea6f29..4c398c3ec9 100644 --- a/contrib/fedora/rpm/20-connectivity-fedora.conf +++ b/contrib/fedora/rpm/20-connectivity-fedora.conf @@ -1,3 +1,8 @@ +# Enable connectivity checking for NetworkManager. +# See `man NetworkManager.conf`. +# +# Note that connectivity checking works badly with rp_filter set to +# strict. Check "/proc/sys/net/ipv4/conf/*/rp_filter". [connectivity] uri=http://fedoraproject.org/static/hotspot.txt response=OK diff --git a/contrib/fedora/rpm/20-connectivity-redhat.conf b/contrib/fedora/rpm/20-connectivity-redhat.conf index e556fd6235..94783b3557 100644 --- a/contrib/fedora/rpm/20-connectivity-redhat.conf +++ b/contrib/fedora/rpm/20-connectivity-redhat.conf @@ -1,3 +1,8 @@ +# Enable connectivity checking for NetworkManager. +# See `man NetworkManager.conf`. +# +# Note that connectivity checking works badly with rp_filter set to +# strict. Check "/proc/sys/net/ipv4/conf/*/rp_filter". [connectivity] uri=http://static.redhat.com/test/rhel-networkmanager.txt response=OK diff --git a/man/NetworkManager.conf.xml b/man/NetworkManager.conf.xml index 4d6fe12df7..b6577aed50 100644 --- a/man/NetworkManager.conf.xml +++ b/man/NetworkManager.conf.xml @@ -1056,10 +1056,12 @@ managed=1 <refsect1> <title><literal>connectivity</literal> section</title> + <para>This section controls NetworkManager's optional connectivity checking functionality. This allows NetworkManager to detect whether or not the system can actually access the internet or whether it is behind a captive portal.</para> + <para>Connectivity checking serves two purposes. For one, it exposes a connectivity state on D-Bus, which other applications may use. For example, Gnome's portal helper uses this as signal to show a captive portal login @@ -1070,6 +1072,12 @@ managed=1 when being connected to WWAN and to a Wi-Fi network which is behind a captive portal, WWAN still gets preferred until login.</para> + <para>Note that your distribution might set <literal>/proc/sys/net/ipv4/conf/*/rp_filter</literal> to + strict filtering. That works badly with per-device connectivity checking, + which uses SO_BINDDEVICE to send requests on all devices. A strict rp_filter + setting will reject any response and the connectivity check on all but the + best route will fail.</para> + <para> <variablelist> <varlistentry> diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index fcdc75d754..bff35ddd43 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -397,6 +397,8 @@ typedef struct _NMDevicePrivate { bool ndisc_started:1; bool device_link_changed_down:1; + bool concheck_rp_filter_checked:1; + /* Generic DHCP stuff */ char * dhcp_anycast_address; @@ -3042,6 +3044,7 @@ concheck_start (NMDevice *self, static guint64 seq_counter = 0; NMDevicePrivate *priv; NMDeviceConnectivityHandle *handle; + const char *ifname; g_return_val_if_fail (NM_IS_DEVICE (self), NULL); @@ -3064,6 +3067,39 @@ concheck_start (NMDevice *self, (long long unsigned) handle->seq, is_periodic ? ", periodic-check" : ""); + if ( addr_family == AF_INET + && !priv->concheck_rp_filter_checked) { + + if ((ifname = nm_device_get_ip_iface_from_platform (self))) { + int val, val_all; + + val = nm_platform_sysctl_ip_conf_get_int_checked (nm_device_get_platform (self), + AF_INET, + ifname, + "rp_filter", + 10, 0, 2, 3); + if (val < 2) { + val_all = nm_platform_sysctl_ip_conf_get_int_checked (nm_device_get_platform (self), + AF_INET, + "all", + "rp_filter", + 10, 0, 2, val); + if (val_all > val) { + val = val_all; + ifname = "all"; + } + } + + if (val == 1) { + _LOGW (LOGD_CONCHECK, "connectivity: \"/proc/sys/net/ipv4/conf/%s/rp_filter\" is set to \"1\". " + "This might break connectivity checking for IPv4 on this device", ifname); + } + } + + /* we only check once per device. It's a warning after all. */ + priv->concheck_rp_filter_checked = TRUE; + } + handle->c_handle = nm_connectivity_check_start (concheck_get_mgr (self), handle->addr_family, nm_device_get_ip_ifindex (self), |