mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-20 08:10:06 +01:00
Compare commits
139 commits
1.55.4-dev
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a31a644f8b | ||
|
|
a45163b131 | ||
|
|
de1fcdcc72 | ||
|
|
a2d147366c | ||
|
|
427a7cf257 | ||
|
|
3a4e18e302 | ||
|
|
8e0825f9cd | ||
|
|
df8288de7f | ||
|
|
118475d571 | ||
|
|
599cc1ed1d | ||
|
|
1756ec54e3 | ||
|
|
1a52bbe7c9 | ||
|
|
57eb4a5bc6 | ||
|
|
10db4baeb6 | ||
|
|
8d8edda3f4 | ||
|
|
e85cc46d0b | ||
|
|
a1928b4459 | ||
|
|
9703305122 | ||
|
|
932b85f7e7 | ||
|
|
4e26403c4a | ||
|
|
bd2484d1a9 | ||
|
|
41e28b900f | ||
|
|
6c1e04fc61 | ||
|
|
2739850b78 | ||
|
|
d8f143f601 | ||
|
|
39143f8bdd | ||
|
|
0b75d905e5 | ||
|
|
13bfa44ceb | ||
|
|
dad4da06b1 | ||
|
|
0b61924048 | ||
|
|
d40e88fd02 | ||
|
|
8e72e6b4fb | ||
|
|
9e70f31c8c | ||
|
|
ac427b25fb | ||
|
|
754b87e1c4 | ||
|
|
5f6beb0e57 | ||
|
|
487ca30256 | ||
|
|
a07961cfbe | ||
|
|
4e7e159224 | ||
|
|
ae134ca9f4 | ||
|
|
55f96057c6 | ||
|
|
de0a37b248 | ||
|
|
7315e7e0ee | ||
|
|
bcb96a1b19 | ||
|
|
561fff3c8d | ||
|
|
a9f2c15663 | ||
|
|
8a9b17071b | ||
|
|
c1519bd514 | ||
|
|
8b5a61458b | ||
|
|
9e01443b14 | ||
|
|
78519589b9 | ||
|
|
771f86105e | ||
|
|
b3f9f52505 | ||
|
|
b41a5ec2d4 | ||
|
|
636fb5ef24 | ||
|
|
d006d61aa1 | ||
|
|
6e2de1d2b3 | ||
|
|
4afa00874f | ||
|
|
3ce1da1fd2 | ||
|
|
8caa781270 | ||
|
|
2b03057de0 | ||
|
|
3b10b88290 | ||
|
|
d687768c61 | ||
|
|
239b0fbbc9 | ||
|
|
29d523391a | ||
|
|
f4bf54ca93 | ||
|
|
22631d557a | ||
|
|
ff0c4346fc | ||
|
|
5f85b55f7f | ||
|
|
461c9edfb4 | ||
|
|
306f9c490b | ||
|
|
441e77a44c | ||
|
|
caf156b2ac | ||
|
|
ed43e4b602 | ||
|
|
384dd7d5f2 | ||
|
|
e06aaba1ca | ||
|
|
32cbf4c629 | ||
|
|
8faa33b9d4 | ||
|
|
d58d0a793e | ||
|
|
f2a2e49d07 | ||
|
|
b4e8edbc8a | ||
|
|
6dd07a80e5 | ||
|
|
04ddd72ce9 | ||
|
|
58f46a6d11 | ||
|
|
427137d6da | ||
|
|
b1614ffb90 | ||
|
|
8d33aaa5b6 | ||
|
|
191ebb439a | ||
|
|
2f35c94628 | ||
|
|
3a769bca67 | ||
|
|
0530af60b3 | ||
|
|
a0482a4e35 | ||
|
|
0e121f5658 | ||
|
|
2d438ebef8 | ||
|
|
c312390932 | ||
|
|
d06fd85e57 | ||
|
|
2a63c33712 | ||
|
|
ce26d85ad1 | ||
|
|
1e81aaa153 | ||
|
|
c1baf09bf9 | ||
|
|
247000deed | ||
|
|
e5ae988603 | ||
|
|
03791e8b2d | ||
|
|
965aa81027 | ||
|
|
86b67233bf | ||
|
|
a148232789 | ||
|
|
2bc895c0e9 | ||
|
|
c6a6801b1e | ||
|
|
46306c1be0 | ||
|
|
1dcd63ab5d | ||
|
|
029f8be4c1 | ||
|
|
e6a31264c1 | ||
|
|
86ea2c5963 | ||
|
|
93491d76ec | ||
|
|
b271e0a051 | ||
|
|
f0f4d0dba0 | ||
|
|
4e10b1e6ab | ||
|
|
52d08008b7 | ||
|
|
92aeed1f5c | ||
|
|
018c5722ee | ||
|
|
bf8b38618a | ||
|
|
17efec8b06 | ||
|
|
69d0fb161e | ||
|
|
59c65bc859 | ||
|
|
a46827f899 | ||
|
|
6801ce4927 | ||
|
|
6e32a8e821 | ||
|
|
13d7469ba0 | ||
|
|
820e56c5df | ||
|
|
c27caec33d | ||
|
|
0b99629278 | ||
|
|
9a2395c779 | ||
|
|
ddb31034f9 | ||
|
|
9e0551aefd | ||
|
|
dbec15eb8d | ||
|
|
48fc40e1ca | ||
|
|
f6d6a7e2eb | ||
|
|
3355ba9380 | ||
|
|
c36e0bedeb |
157 changed files with 13260 additions and 9142 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -81,7 +81,6 @@ test-*.trs
|
|||
/data/org.freedesktop.NetworkManager.service
|
||||
/data/server.conf
|
||||
/data/org.freedesktop.NetworkManager.policy
|
||||
/data/org.freedesktop.NetworkManager.policy.in
|
||||
/data/nm-sudo.service
|
||||
/data/nm-priv-helper.service
|
||||
/data/NetworkManager-config-initrd.service
|
||||
|
|
|
|||
|
|
@ -60,11 +60,11 @@ variables:
|
|||
#
|
||||
# This is done by running `ci-fairy generate-template` and possibly bumping
|
||||
# ".default_tag".
|
||||
ALPINE_TAG: 'tag-722dacf5c4be'
|
||||
CENTOS_TAG: 'tag-1387a813d200'
|
||||
DEBIAN_TAG: 'tag-447ddf898453'
|
||||
FEDORA_TAG: 'tag-1387a813d200'
|
||||
UBUNTU_TAG: 'tag-447ddf898453'
|
||||
ALPINE_TAG: 'tag-0c3a6f855fb8'
|
||||
CENTOS_TAG: 'tag-c1c23df75dda'
|
||||
DEBIAN_TAG: 'tag-d4bf5db9e214'
|
||||
FEDORA_TAG: 'tag-c1c23df75dda'
|
||||
UBUNTU_TAG: 'tag-d4bf5db9e214'
|
||||
|
||||
ALPINE_EXEC: 'bash .gitlab-ci/alpine-install.sh'
|
||||
CENTOS_EXEC: 'bash .gitlab-ci/fedora-install.sh'
|
||||
|
|
@ -713,7 +713,7 @@ pages:
|
|||
rules:
|
||||
- if: $CI_PIPELINE_SOURCE == 'schedule'
|
||||
when: never
|
||||
- if: $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME == 'main'
|
||||
- if: $CI_PIPELINE_SOURCE == 'push' && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
|
||||
dependencies:
|
||||
- "t_fedora:42: [meson+gcc+docs+valgrind]"
|
||||
needs:
|
||||
|
|
|
|||
|
|
@ -240,7 +240,7 @@ pages:
|
|||
rules:
|
||||
- if: $CI_PIPELINE_SOURCE == 'schedule'
|
||||
when: never
|
||||
- if: $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME == 'main'
|
||||
- if: $CI_PIPELINE_SOURCE == 'push' && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
|
||||
dependencies:
|
||||
- "t_{{default_distro.name}}:{{default_distro.versions[0]}}: [meson+gcc+docs+valgrind]"
|
||||
needs:
|
||||
|
|
|
|||
|
|
@ -155,12 +155,7 @@ test_subtree() {
|
|||
do_clean
|
||||
pushd ./src/$d
|
||||
|
||||
ARGS=()
|
||||
if [ "$d" = n-acd ]; then
|
||||
ARGS+=('-Debpf=false')
|
||||
fi
|
||||
|
||||
CC="$cc" CFLAGS="-Werror -Wall" meson build "${ARGS[@]}"
|
||||
CC="$cc" CFLAGS="-Werror -Wall" meson build
|
||||
ninja -v -C build test
|
||||
|
||||
popd
|
||||
|
|
|
|||
53
NEWS
53
NEWS
|
|
@ -1,6 +1,6 @@
|
|||
=============================================
|
||||
NetworkManager-1.56
|
||||
Overview of changes since NetworkManager-1.54
|
||||
NetworkManager-1.58
|
||||
Overview of changes since NetworkManager-1.56
|
||||
=============================================
|
||||
|
||||
This is a snapshot of NetworkManager development. The API is
|
||||
|
|
@ -8,9 +8,58 @@ subject to change and not guaranteed to be compatible with
|
|||
the later release.
|
||||
USE AT YOUR OWN RISK. NOT RECOMMENDED FOR PRODUCTION USE!
|
||||
|
||||
* Restrict the connectivity check to use the DNS servers defined on the
|
||||
same link. If the link has no DNS servers, the connectivity check will
|
||||
use any servers available in the system.
|
||||
* Install the systemd units in the initramfs using a systemd generator.
|
||||
* A new "check-connectivity" configuration option is available to disable the
|
||||
connectivity check for selected interfaces.
|
||||
* Remove the modify_system build option that allowed setting up the
|
||||
polkit permissions to allow non-admin users to create system-wide
|
||||
connection. That configuration is discouraged because it can be used
|
||||
to bypass filesystem permissions.
|
||||
* For private connections (the ones that specify a user in the
|
||||
"connection.permissions" property), verify that the user can access
|
||||
the 802.1X certificates and keys set in the connection.
|
||||
* Introduce a libnm function that can be used by VPN plugins to check
|
||||
user permissions on certificate and keys.
|
||||
* The support for Wireless Extensions is deprecated and will be
|
||||
removed in a future release. Wireless Extensions are now disabled by
|
||||
default.
|
||||
|
||||
=============================================
|
||||
NetworkManager-1.56
|
||||
Overview of changes since NetworkManager-1.54
|
||||
=============================================
|
||||
|
||||
* nmcli now supports viewing and managing WireGuard peers.
|
||||
* Support reapplying the "sriov.vfs" property as long as
|
||||
"sriov.total-vfs" is not changed.
|
||||
* Support reapplying "bond-port.vlans".
|
||||
* Accept hostnames longer than 64 characters from DNS lookup.
|
||||
* Make that global-dns configuration overwrites DNS searches and
|
||||
options from connections, instead of merging all together.
|
||||
* Add support for a new rd.net.dhcp.client-id option in
|
||||
nm-initrd-generator.
|
||||
* Add gsm device-uid setting to restrict the devices the connection applies to.
|
||||
* Support configuring the HSR protocol version via the
|
||||
"hsr.protocol-version" property.
|
||||
* Fix a bug that makes broadband connections auto-connect getting
|
||||
blocked if the connection tries to reconnect when modem status is
|
||||
"disconnecting" / "disconnected".
|
||||
* Treat modem connection not having an operator code available
|
||||
as a recoverable error.
|
||||
* Add support for configuring systemd-resolved's DNSSEC option
|
||||
per-connection via the "connection.dnssec" connection property.
|
||||
* Support configuring the HSR interlink port via the
|
||||
"hsr.interlink" property.
|
||||
* Fix some connection properties not being applied to vpn connections
|
||||
(connection.mdns, connection.llmnr, connection.dns-over-tls,
|
||||
connection.mptcp-flags, ipv6.ip6-privacy)
|
||||
* Update n-acd to always compile with eBPF enabled, as support
|
||||
for eBPF is now detected at run time.
|
||||
* Add new MPTCP 'laminar' endpoint type, and set it by default alongside
|
||||
the 'subflow' one.
|
||||
|
||||
=============================================
|
||||
NetworkManager-1.54
|
||||
|
|
|
|||
|
|
@ -239,6 +239,15 @@
|
|||
/* Whether we build with OVS plugin */
|
||||
#mesondefine WITH_OPENVSWITCH
|
||||
|
||||
/* Whether we build with team support */
|
||||
#mesondefine WITH_TEAMDCTL
|
||||
|
||||
/* Whether we build with Wi-Fi support */
|
||||
#mesondefine WITH_WIFI
|
||||
|
||||
/* Whether we build with WWAN support */
|
||||
#mesondefine WITH_WWAN
|
||||
|
||||
/* Define if you have PPP support */
|
||||
#mesondefine WITH_PPP
|
||||
|
||||
|
|
|
|||
|
|
@ -107,6 +107,11 @@
|
|||
%else
|
||||
%bcond_without iwd
|
||||
%endif
|
||||
%if 0%{?fedora} <= 43 || 0%{?rhel} <= 10
|
||||
%bcond_without polkit_noauth_group
|
||||
%else
|
||||
%bcond_with polkit_noauth_group
|
||||
%endif
|
||||
|
||||
###############################################################################
|
||||
|
||||
|
|
@ -154,17 +159,6 @@
|
|||
%bcond_with ifcfg_migrate
|
||||
%endif
|
||||
|
||||
%if 0%{?fedora}
|
||||
# Although eBPF would be available on Fedora's kernel, it seems
|
||||
# we often get SELinux denials (rh#1651654). But even aside them,
|
||||
# bpf(BPF_MAP_CREATE, ...) randomly fails with EPERM. That might
|
||||
# be related to `ulimit -l`. Anyway, this is not usable at the
|
||||
# moment.
|
||||
%global ebpf_enabled "no"
|
||||
%else
|
||||
%global ebpf_enabled "no"
|
||||
%endif
|
||||
|
||||
# Fedora 33 enables LTO by default by setting CFLAGS="-flto -ffat-lto-objects".
|
||||
# However, we also require "-flto -flto-partition=none", so disable Fedora's
|
||||
# default and use our configure option --with-lto instead.
|
||||
|
|
@ -627,14 +621,10 @@ Preferably use nmcli instead.
|
|||
%endif
|
||||
%if %{with wifi}
|
||||
-Dwifi=true \
|
||||
%if 0%{?fedora}
|
||||
-Dwext=true \
|
||||
%else
|
||||
-Dwext=false \
|
||||
%endif
|
||||
%else
|
||||
-Dwifi=false \
|
||||
%endif
|
||||
-Dwext=false \
|
||||
%if %{with iwd}
|
||||
-Diwd=true \
|
||||
%else
|
||||
|
|
@ -676,21 +666,19 @@ Preferably use nmcli instead.
|
|||
-Dselinux=true \
|
||||
-Dpolkit=true \
|
||||
-Dconfig_auth_polkit_default=true \
|
||||
-Dmodify_system=true \
|
||||
%if %{with polkit_noauth_group}
|
||||
-Dpolkit_noauth_group=wheel \
|
||||
%endif
|
||||
-Dconcheck=true \
|
||||
%if 0%{?fedora}
|
||||
-Dlibpsl=true \
|
||||
%else
|
||||
-Dlibpsl=false \
|
||||
%endif
|
||||
%if %{ebpf_enabled} != "yes"
|
||||
-Debpf=false \
|
||||
%else
|
||||
-Debpf=true \
|
||||
%endif
|
||||
-Dsession_tracking=systemd \
|
||||
-Dsuspend_resume=systemd \
|
||||
-Dsystemdsystemunitdir=%{_unitdir} \
|
||||
-Dsystemdsystemgeneratordir=%{_systemdgeneratordir} \
|
||||
-Dsystem_ca_path=/etc/pki/ca-trust/extracted/pem/tls-ca-bundle.pem \
|
||||
-Ddbus_conf_dir=%{dbus_sys_dir} \
|
||||
-Dtests=yes \
|
||||
|
|
@ -763,6 +751,7 @@ rm -f %{buildroot}%{_libdir}/pppd/%{ppp_version}/*.la
|
|||
rm -f %{buildroot}%{nmplugindir}/*.la
|
||||
|
||||
# Don't use the *-initrd.service files yet, wait dracut to support them
|
||||
rm -f %{buildroot}%{_systemdgeneratordir}/nm-initrd-generator.sh
|
||||
rm -f %{buildroot}%{_unitdir}/NetworkManager-config-initrd.service
|
||||
rm -f %{buildroot}%{_unitdir}/NetworkManager-initrd.service
|
||||
rm -f %{buildroot}%{_unitdir}/NetworkManager-wait-online-initrd.service
|
||||
|
|
@ -896,6 +885,7 @@ fi
|
|||
%{_libexecdir}/nm-dispatcher
|
||||
%{_libexecdir}/nm-initrd-generator
|
||||
%{_libexecdir}/nm-daemon-helper
|
||||
%{_libexecdir}/nm-libnm-helper
|
||||
%{_libexecdir}/nm-priv-helper
|
||||
%dir %{_libdir}/%{name}
|
||||
%dir %{nmplugindir}
|
||||
|
|
@ -927,6 +917,9 @@ fi
|
|||
%{_datadir}/dbus-1/system-services/org.freedesktop.nm_dispatcher.service
|
||||
%{_datadir}/dbus-1/system-services/org.freedesktop.nm_priv_helper.service
|
||||
%{_datadir}/polkit-1/actions/*.policy
|
||||
%if %{with polkit_noauth_group}
|
||||
%{_datadir}/polkit-1/rules.d/org.freedesktop.NetworkManager.rules
|
||||
%endif
|
||||
%{_prefix}/lib/udev/rules.d/*.rules
|
||||
%{_prefix}/lib/firewalld/zones/nm-shared.xml
|
||||
# systemd stuff
|
||||
|
|
|
|||
|
|
@ -155,7 +155,6 @@ P_CRYPTO="${CRYPTO-}"
|
|||
P_DBUS_SYS_DIR="${DBUS_SYS_DIR-}"
|
||||
P_DHCP_DEFAULT="${DHCP_DEFAULT-}"
|
||||
P_DNS_RC_MANAGER_DEFAULT="${DNS_RC_MANAGER_DEFAULT-}"
|
||||
P_EBPF_ENABLED="${EBPF_ENABLED-no}"
|
||||
P_FIREWALLD_ZONE="${FIREWALLD_ZONE-}"
|
||||
P_IWD="${IWD-}"
|
||||
P_LOGGING_BACKEND_DEFAULT="${LOGGING_BACKEND_DEFAULT-}"
|
||||
|
|
@ -174,6 +173,7 @@ P_WIFI="${WIFI-1}"
|
|||
P_WWAN="${WWAN-1}"
|
||||
P_TEAM="${TEAM-1}"
|
||||
P_BLUETOOTH="${BLUETOOTH-1}"
|
||||
P_IFCFG_RH="${IFCFG_RH-0}"
|
||||
P_NMTUI="${NMTUI-1}"
|
||||
P_NM_CLOUD_SETUP="${NM_CLOUD_SETUP-1}"
|
||||
P_OVS="${OVS-1}"
|
||||
|
|
@ -203,7 +203,7 @@ if [ -z "$P_FEDORA" -a -z "$P_RHEL" ] ; then
|
|||
P_FEDORA="$x"
|
||||
P_RHEL=0
|
||||
else
|
||||
x="$(grep -q "ID=fedora" /etc/os-release && sed -n 's/VERSION_ID=//p' /etc/os-release)"
|
||||
x="$(grep -q 'ID="rhel"' /etc/os-release && sed -n 's/^VERSION_ID="*\([0-9]*\).*/\1/p' /etc/os-release)"
|
||||
if test "$x" -gt 0 ; then
|
||||
P_FEDORA=0
|
||||
P_RHEL="$x"
|
||||
|
|
@ -294,6 +294,14 @@ if [ -z "$P_MODEM_MANAGER_1" ] ; then
|
|||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$TEAM" ] && [ "${P_RHEL-0}" -ge 10 ] ; then
|
||||
P_TEAM=0
|
||||
fi
|
||||
|
||||
if [ -z "$IFCFG_RH" ] && [ -n "$P_RHEL" ] && [ "$P_RHEL" -le 9 ] ; then
|
||||
P_IFCFG_RH=1
|
||||
fi
|
||||
|
||||
if bool "$P_DEBUG" ; then
|
||||
P_CFLAGS="-g -Og -fexceptions${P_CFLAGS:+ }$P_CFLAGS"
|
||||
else
|
||||
|
|
@ -379,7 +387,7 @@ meson setup\
|
|||
-Db_lto="$(bool_true "$P_LTO")" \
|
||||
-Dlibaudit=yes-disabled-by-default \
|
||||
-Dmodem_manager="$(bool_true "$P_MODEM_MANAGER_1")" \
|
||||
$(args_enable "$P_WIFI" -Dwifi=true -Dwext="$(bool_true "$P_FEDORA")") \
|
||||
$(args_enable "$P_WIFI" -Dwifi=true -Dwext=false) \
|
||||
$(args_enable "$(bool_not_true "$P_WIFI")" -Dwifi=false ) \
|
||||
-Diwd="$(bool_true "$P_IWD")" \
|
||||
-Dbluez5_dun="$(bool_true "$P_BLUETOOTH")" \
|
||||
|
|
@ -393,18 +401,17 @@ meson setup\
|
|||
-Dselinux=true \
|
||||
-Dpolkit=true \
|
||||
-Dconfig_auth_polkit_default=true \
|
||||
-Dmodify_system=true \
|
||||
-Dconcheck=true \
|
||||
-Dlibpsl="$(bool_true "$P_FEDORA")" \
|
||||
-Debpf="$(bool_true "$P_EBPF_ENABLED")" \
|
||||
-Dsession_tracking=systemd \
|
||||
-Dsuspend_resume=systemd \
|
||||
-Dsystemdsystemunitdir=/usr/lib/systemd/system \
|
||||
-Dsystemdsystemgeneratordir=/usr/lib/systemd/system-generators \
|
||||
-Dsystem_ca_path=/etc/pki/tls/cert.pem \
|
||||
-Ddbus_conf_dir="$P_DBUS_SYS_DIR" \
|
||||
-Dtests=yes \
|
||||
-Dvalgrind=no \
|
||||
-Difcfg_rh=true \
|
||||
-Difcfg_rh="$(bool_true "$P_IFCFG_RH")" \
|
||||
-Difupdown=false \
|
||||
$(args_enable "$P_PPP" -Dppp=true -Dpppd="$D_SBINDIR/pppd" -Dpppd_plugin_dir="$D_LIBDIR/pppd/$P_PPP_VERSION") \
|
||||
$(args_enable "$(bool_not_true "$P_PPP")" -Dppp=false ) \
|
||||
|
|
|
|||
|
|
@ -169,6 +169,7 @@ meson setup build \
|
|||
-D ld_gc=false \
|
||||
-D session_tracking=no \
|
||||
-D systemdsystemunitdir=no \
|
||||
-D systemdsystemgeneratordir=no \
|
||||
-D systemd_journal=false \
|
||||
-D selinux=false \
|
||||
-D libaudit=no \
|
||||
|
|
@ -180,8 +181,6 @@ meson setup build \
|
|||
-D crypto=$_WITH_CRYPTO \
|
||||
-D docs=$_WITH_DOCS \
|
||||
\
|
||||
-D ebpf=false \
|
||||
\
|
||||
-D iwd=true \
|
||||
-D ofono=true \
|
||||
-D teamdctl=$_WITH_LIBTEAM \
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
[Unit]
|
||||
Description=NetworkManager Configuration (initrd)
|
||||
AssertPathExists=/etc/initrd-release
|
||||
DefaultDependencies=no
|
||||
Wants=systemd-journald.socket
|
||||
After=systemd-journald.socket
|
||||
Before=systemd-udevd.service systemd-udev-trigger.service
|
||||
ConditionPathExists=/etc/initrd-release
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
|
|
@ -22,6 +22,3 @@ ExecStartPost=/bin/sh -c ' \
|
|||
fi \
|
||||
'
|
||||
RemainAfterExit=yes
|
||||
|
||||
[Install]
|
||||
WantedBy=initrd.target
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
[Unit]
|
||||
Description=NetworkManager (initrd)
|
||||
AssertPathExists=/etc/initrd-release
|
||||
DefaultDependencies=no
|
||||
Wants=systemd-udev-trigger.service network.target
|
||||
After=systemd-udev-trigger.service network-pre.target dbus.service NetworkManager-config-initrd.service
|
||||
Before=network.target
|
||||
BindsTo=dbus.service
|
||||
ConditionPathExists=/etc/initrd-release
|
||||
ConditionPathExists=/run/NetworkManager/initrd/neednet
|
||||
ConditionPathExistsGlob=|/usr/lib/NetworkManager/system-connections/*
|
||||
ConditionPathExistsGlob=|/run/NetworkManager/system-connections/*
|
||||
|
|
@ -22,11 +22,3 @@ Environment=NM_CONFIG_ENABLE_TAG=initrd
|
|||
Restart=on-failure
|
||||
ProtectSystem=true
|
||||
ProtectHome=read-only
|
||||
|
||||
[Install]
|
||||
WantedBy=initrd.target
|
||||
# We want to enable NetworkManager-wait-online-initrd.service whenever this
|
||||
# service is enabled. NetworkManager-wait-online-initrd.service has
|
||||
# WantedBy=network-online.target, so enabling it only has an effect if
|
||||
# network-online.target itself is enabled or pulled in by some other unit.
|
||||
Also=NetworkManager-config-initrd.service NetworkManager-wait-online-initrd.service
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
[Unit]
|
||||
Description=NetworkManager Wait Online (initrd)
|
||||
AssertPathExists=/etc/initrd-release
|
||||
DefaultDependencies=no
|
||||
Requires=NetworkManager-initrd.service
|
||||
After=NetworkManager-initrd.service
|
||||
Before=network-online.target
|
||||
ConditionPathExists=/etc/initrd-release
|
||||
ConditionPathExists=/run/NetworkManager/initrd/neednet
|
||||
|
||||
[Service]
|
||||
|
|
@ -21,6 +21,3 @@ Type=oneshot
|
|||
ExecStart=@bindir@/nm-online -s -q
|
||||
RemainAfterExit=yes
|
||||
Environment=NM_ONLINE_TIMEOUT=3600
|
||||
|
||||
[Install]
|
||||
WantedBy=initrd.target network-online.target
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ KillMode=process
|
|||
# With a huge number of interfaces, starting can take a long time.
|
||||
TimeoutStartSec=600
|
||||
|
||||
CapabilityBoundingSet=CAP_NET_ADMIN CAP_DAC_OVERRIDE CAP_NET_RAW CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_MODULE CAP_AUDIT_WRITE CAP_KILL CAP_SYS_CHROOT
|
||||
CapabilityBoundingSet=CAP_NET_ADMIN CAP_DAC_OVERRIDE CAP_NET_RAW CAP_BPF CAP_NET_BIND_SERVICE CAP_SETGID CAP_SETUID CAP_SYS_MODULE CAP_AUDIT_WRITE CAP_KILL CAP_SYS_CHROOT
|
||||
|
||||
ProtectSystem=true
|
||||
ProtectHome=read-only
|
||||
|
|
|
|||
|
|
@ -55,21 +55,22 @@ if install_udevdir
|
|||
endif
|
||||
|
||||
if enable_polkit
|
||||
policy = 'org.freedesktop.NetworkManager.policy'
|
||||
|
||||
policy_in = configure_file(
|
||||
input: policy + '.in.in',
|
||||
output: '@BASENAME@',
|
||||
configuration: data_conf,
|
||||
)
|
||||
|
||||
i18n.merge_file(
|
||||
input: policy_in,
|
||||
input: 'org.freedesktop.NetworkManager.policy.in',
|
||||
output: '@BASENAME@',
|
||||
po_dir: po_dir,
|
||||
install: true,
|
||||
install_dir: polkit_gobject_policydir,
|
||||
install_dir: polkit_policydir,
|
||||
)
|
||||
|
||||
if polkit_noauth_group != ''
|
||||
configure_file(
|
||||
input: 'org.freedesktop.NetworkManager.rules.in',
|
||||
output: '@BASENAME@',
|
||||
install_dir: polkit_rulesdir,
|
||||
configuration: {'NM_POLKIT_NOAUTH_GROUP': polkit_noauth_group},
|
||||
)
|
||||
endif
|
||||
endif
|
||||
|
||||
if enable_firewalld_zone
|
||||
|
|
|
|||
|
|
@ -117,8 +117,8 @@
|
|||
<message>System policy prevents modification of network settings for all users</message>
|
||||
<defaults>
|
||||
<allow_any>auth_admin_keep</allow_any>
|
||||
<allow_inactive>@NM_MODIFY_SYSTEM_POLICY@</allow_inactive>
|
||||
<allow_active>@NM_MODIFY_SYSTEM_POLICY@</allow_active>
|
||||
<allow_inactive>auth_admin_keep</allow_inactive>
|
||||
<allow_active>auth_admin_keep</allow_active>
|
||||
</defaults>
|
||||
</action>
|
||||
|
||||
17
data/org.freedesktop.NetworkManager.rules.in
Normal file
17
data/org.freedesktop.NetworkManager.rules.in
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
// NetworkManager authorizations/policy for the @NM_POLKIT_NOAUTH_GROUP@ group.
|
||||
//
|
||||
// DO NOT EDIT THIS FILE, it will be overwritten on update.
|
||||
//
|
||||
// Allow users in the @NM_POLKIT_NOAUTH_GROUP@ group to create system-wide connections without being
|
||||
// prompted for a password if they are in a local console.
|
||||
// This is optional and is only recommended to maintain backwards compatibility
|
||||
// in systems where it was already working in this way. It is discouraged
|
||||
// otherwise.
|
||||
|
||||
polkit.addRule(function(action, subject) {
|
||||
if (action.id == "org.freedesktop.NetworkManager.settings.modify.system" &&
|
||||
subject.isInGroup("@NM_POLKIT_NOAUTH_GROUP@") &&
|
||||
subject.local) {
|
||||
return polkit.Result.YES;
|
||||
}
|
||||
});
|
||||
|
|
@ -23,8 +23,8 @@ static const char *
|
|||
nm_state_to_string(NMState state)
|
||||
{
|
||||
switch (state) {
|
||||
case NM_STATE_ASLEEP:
|
||||
return "asleep";
|
||||
case NM_STATE_DISABLED:
|
||||
return "network off";
|
||||
case NM_STATE_CONNECTING:
|
||||
return "connecting";
|
||||
case NM_STATE_CONNECTED_LOCAL:
|
||||
|
|
|
|||
|
|
@ -83,6 +83,11 @@
|
|||
note that your distribution or other packages may drop configuration snippets for NetworkManager, such
|
||||
that they are part of the factory default.
|
||||
</para>
|
||||
<para>
|
||||
The options that are indicated as boolean can be set to one of these values:
|
||||
<literal>yes</literal>, <literal>true</literal>, <literal>on</literal>, <literal>1</literal>,
|
||||
<literal>no</literal>, <literal>false</literal>, <literal>off</literal>, <literal>0</literal>.
|
||||
</para>
|
||||
|
||||
</refsect1>
|
||||
|
||||
|
|
@ -895,11 +900,15 @@ ipv6.ip6-privacy=0
|
|||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>connection.mptcp-flags</varname></term>
|
||||
<listitem><para>If unspecified, the fallback is 0x22 (<literal>"enabled,subflow"</literal>). Note that if sysctl <literal>/proc/sys/net/mptcp/enabled</literal> is disabled, NetworkManager will still not configure endpoints.</para></listitem>
|
||||
<listitem><para>If unspecified, the fallback is 0x122 (<literal>"enabled,subflow,laminar"</literal>). Note that if sysctl <literal>/proc/sys/net/mptcp/enabled</literal> is disabled, NetworkManager will still not configure endpoints.</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>connection.dns-over-tls</varname></term>
|
||||
<listitem><para>If unspecified, the ultimate default values depends on the DNS plugin. With systemd-resolved the default currently is global setting and for all other plugins "no" (0).</para></listitem>
|
||||
<listitem><para>If unspecified, the ultimate default values depends on the DNS plugin. With systemd-resolved the default currently is its global setting and for all other plugins "no" (0).</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>connection.dnssec</varname></term>
|
||||
<listitem><para>If unspecified, the ultimate default values depends on the DNS plugin. With systemd-resolved the default currently is its global setting and for all other plugins "no" (0).</para></listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>connection.stable-id</varname></term>
|
||||
|
|
@ -1245,12 +1254,13 @@ managed=1
|
|||
<term><varname>managed</varname></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Whether the device is managed or not. A device can be
|
||||
marked as managed via udev rules (ENV{NM_UNMANAGED}),
|
||||
or via setting plugins (keyfile.unmanaged-devices).
|
||||
This is yet another way. Note that this configuration
|
||||
can be overruled at runtime via D-Bus. Also, it has
|
||||
higher priority then udev rules.
|
||||
A boolean value specifying whether the device is
|
||||
managed or not. A device can be marked as managed via
|
||||
udev rules (ENV{NM_UNMANAGED}), or via setting plugins
|
||||
(keyfile.unmanaged-devices). This is yet another
|
||||
way. Note that this configuration can be overruled at
|
||||
runtime via D-Bus. Also, it has higher priority than
|
||||
udev rules.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
|
@ -1319,9 +1329,27 @@ managed=1
|
|||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry id="keep-configuration">
|
||||
<term><varname>keep-configuration</varname></term>
|
||||
<varlistentry id="check-connectivity">
|
||||
<term><varname>check-connectivity</varname></term>
|
||||
<listitem>
|
||||
<para>
|
||||
A boolean value specifying whether NetworkManager will perform a connectivity check
|
||||
for this device. Defaults to <literal>yes</literal>.
|
||||
</para>
|
||||
<para>
|
||||
This setting does nothing if the connectivity check has been
|
||||
disabled globally using the
|
||||
<literal>connectivity.enabled</literal> setting.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry id="keep-configuration">
|
||||
<term><varname>keep-configuration</varname></term>
|
||||
<listitem>
|
||||
<para>
|
||||
A boolean value indicating whether the existing device
|
||||
configuration is kept at startup.
|
||||
</para>
|
||||
<para>
|
||||
On startup, NetworkManager tries to not interfere with
|
||||
interfaces that are already configured. It does so by
|
||||
|
|
@ -1418,16 +1446,16 @@ managed=1
|
|||
<term><varname>wifi.iwd.autoconnect</varname></term>
|
||||
<listitem>
|
||||
<para>
|
||||
If <literal>wifi.backend</literal> is <literal>iwd</literal>, setting this to
|
||||
<literal>false</literal> forces IWD's autoconnect mechanism to be disabled for
|
||||
this device and connections will only be initiated by NetworkManager whether
|
||||
commanded by a client or automatically. Leaving it <literal>true</literal> (default)
|
||||
stops NetworkManager from automatically initiating connections and allows
|
||||
IWD to use its network ranking and scanning logic to decide the best networks
|
||||
to autoconnect to next. Connections' <literal>autoconnect-priority</literal>,
|
||||
<literal>autoconnect-retries</literal> settings will be ignored. Other settings
|
||||
like <literal>permissions</literal> or <literal>multi-connect</literal> may interfere
|
||||
with IWD connection attempts.
|
||||
A boolean value. If <literal>wifi.backend</literal> is <literal>iwd</literal>,
|
||||
setting this to <literal>false</literal> forces IWD's autoconnect mechanism to be
|
||||
disabled for this device and connections will only be initiated by NetworkManager
|
||||
whether commanded by a client or automatically. Leaving it <literal>true</literal>
|
||||
(default) stops NetworkManager from automatically initiating connections and allows
|
||||
IWD to use its network ranking and scanning logic to decide the best networks to
|
||||
autoconnect to next. Connections' <literal>autoconnect-priority</literal>,
|
||||
<literal>autoconnect-retries</literal> settings will be ignored. Other settings like
|
||||
<literal>permissions</literal> or <literal>multi-connect</literal> may interfere with
|
||||
IWD connection attempts.
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
|
@ -1486,7 +1514,7 @@ managed=1
|
|||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><varname>enabled</varname></term>
|
||||
<listitem><para>Whether connectivity check is enabled.
|
||||
<listitem><para>A boolean indicating whether connectivity check is enabled.
|
||||
Note that to enable connectivity check, a valid uri must
|
||||
also be configured. The value defaults to true, but since
|
||||
the uri is unset by default, connectivity check may be disabled.
|
||||
|
|
|
|||
|
|
@ -91,6 +91,10 @@
|
|||
NetworkManager inserts the records for Bridges into OVSDB when a Port is
|
||||
attached.
|
||||
</para>
|
||||
|
||||
<para>Known limitation: when the last NetworkManager's owned port is removed,
|
||||
the bridge is removed too, even if there are other externally attached ports.
|
||||
</para>
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
|
|
@ -102,6 +106,10 @@
|
|||
exist. Ports can also be configured to do VLAN tagging or Bonding.
|
||||
NetworkManager inserts the records for Ports into OVSDB when an Interface is
|
||||
attached. Ports must be attached to a Bridge.</para>
|
||||
|
||||
<para>Known limitation: when the last NetworkManager's owned interface is removed,
|
||||
the port is removed too, even if there are other externally attached interfaces.
|
||||
</para>
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
|
|
|
|||
56
meson.build
56
meson.build
|
|
@ -5,7 +5,7 @@ project(
|
|||
# NOTE: When incrementing version also add corresponding
|
||||
# NM_VERSION_x_y_z macros in
|
||||
# "src/libnm-core-public/nm-version-macros.h.in"
|
||||
version: '1.55.4',
|
||||
version: '1.57.1',
|
||||
license: 'GPL2+',
|
||||
default_options: [
|
||||
'buildtype=debugoptimized',
|
||||
|
|
@ -327,12 +327,17 @@ config_h.set10('WITH_CONFIG_PLUGIN_IFUPDOWN', enable_ifupdown)
|
|||
config_h.set_quoted('NM_DIST_VERSION', dist_version)
|
||||
|
||||
enable_wifi = get_option('wifi')
|
||||
config_h.set10('WITH_WIFI', enable_wifi)
|
||||
|
||||
enable_iwd = get_option('iwd')
|
||||
assert((not enable_iwd) or enable_wifi, 'Enabling iwd support requires Wi-Fi support as well')
|
||||
config_h.set10('WITH_IWD', enable_iwd)
|
||||
|
||||
enable_wext = get_option('wext')
|
||||
wext = get_option('wext')
|
||||
if wext == 'true'
|
||||
error('Wireless Extensions support is deprecated and will be removed in the future. Use -Dwext=force to keep using it')
|
||||
endif
|
||||
enable_wext = (wext == 'force')
|
||||
config_h.set10('HAVE_WEXT', enable_wext)
|
||||
|
||||
# Checks for libdl - on certain platforms its part of libc
|
||||
|
|
@ -382,6 +387,14 @@ if install_systemdunitdir and systemd_systemdsystemunitdir == ''
|
|||
systemd_systemdsystemunitdir = systemd_dep.get_variable(pkgconfig: 'systemdsystemunitdir', pkgconfig_define: ['rootprefix', nm_prefix])
|
||||
endif
|
||||
|
||||
systemd_systemdsystemgeneratordir = get_option('systemdsystemgeneratordir')
|
||||
install_systemdgeneratordir = (systemd_systemdsystemgeneratordir != 'no')
|
||||
|
||||
if install_systemdgeneratordir and systemd_systemdsystemgeneratordir == ''
|
||||
assert(systemd_dep.found(), 'systemd required but not found, please provide a valid systemd user generator dir or disable it')
|
||||
systemd_systemdsystemgeneratordir = systemd_dep.get_variable(pkgconfig: 'systemdsystemgeneratordir', pkgconfig_define: ['rootprefix', nm_prefix])
|
||||
endif
|
||||
|
||||
enable_systemd_journal = get_option('systemd_journal')
|
||||
if enable_systemd_journal
|
||||
assert(libsystemd_dep.found(), 'Missing systemd-journald support')
|
||||
|
|
@ -476,19 +489,6 @@ if enable_selinux
|
|||
endif
|
||||
config_h.set10('HAVE_SELINUX', enable_selinux)
|
||||
|
||||
# eBPF support
|
||||
ebpf_opt = get_option('ebpf')
|
||||
# 'auto' means 'false', because there are still issues.
|
||||
if ebpf_opt != 'true'
|
||||
enable_ebpf = false
|
||||
else
|
||||
enable_ebpf = true
|
||||
if not cc.has_header('linux/bpf.h')
|
||||
assert(ebpf_opt != 'true', 'eBPF requires kernel support')
|
||||
enable_ebpf = false
|
||||
endif
|
||||
endif
|
||||
|
||||
# libaudit support
|
||||
libaudit = get_option('libaudit')
|
||||
enable_libaudit = libaudit.contains('yes')
|
||||
|
|
@ -507,12 +507,14 @@ if enable_teamdctl
|
|||
libteamdctl_dep = dependency('libteamdctl', version: '>= 1.9')
|
||||
assert(libteamdctl_dep.found(), 'You must have libteamdctl installed to build. Use -Dteamdctl=false to disable it')
|
||||
endif
|
||||
config_h.set10('WITH_TEAMDCTL', enable_teamdctl)
|
||||
|
||||
# polkit
|
||||
enable_polkit = get_option('polkit')
|
||||
if enable_polkit
|
||||
# FIXME: policydir should be relative to `datadir`, not `prefix`. Fixed in https://gitlab.freedesktop.org/polkit/polkit/merge_requests/2
|
||||
polkit_gobject_policydir = dependency('polkit-gobject-1').get_variable(pkgconfig: 'policydir', pkgconfig_define: ['prefix', nm_prefix])
|
||||
polkit_policydir = dependency('polkit-gobject-1').get_variable(pkgconfig: 'policydir', pkgconfig_define: ['prefix', nm_prefix])
|
||||
polkit_rulesdir = join_paths(fs.parent(polkit_policydir), 'rules.d')
|
||||
endif
|
||||
|
||||
config_auth_polkit_default = get_option('config_auth_polkit_default')
|
||||
|
|
@ -522,6 +524,12 @@ endif
|
|||
config_h.set_quoted('NM_CONFIG_DEFAULT_MAIN_AUTH_POLKIT', config_auth_polkit_default)
|
||||
|
||||
enable_modify_system = get_option('modify_system')
|
||||
if enable_modify_system
|
||||
# FIXME: remove this after everyone has stopped using modify_system
|
||||
error('modify_system=true is no longer allowed due to security reasons')
|
||||
endif
|
||||
|
||||
polkit_noauth_group = get_option('polkit_noauth_group')
|
||||
|
||||
polkit_agent_helper_1_path = get_option('polkit_agent_helper_1')
|
||||
foreach p : [ '/usr/libexec/polkit-agent-helper-1',
|
||||
|
|
@ -616,6 +624,7 @@ if enable_modem_manager
|
|||
endif
|
||||
config_h.set_quoted('MOBILE_BROADBAND_PROVIDER_INFO_DATABASE', mobile_broadband_provider_info_database)
|
||||
endif
|
||||
config_h.set10('WITH_WWAN', enable_modem_manager)
|
||||
|
||||
# Bluez5 DUN support
|
||||
enable_bluez5_dun = get_option('bluez5_dun')
|
||||
|
|
@ -953,7 +962,6 @@ data_conf.set('NM_DHCP_CLIENTS_ENABLED', ', '.join(config_dhcp_c
|
|||
data_conf.set('NM_MAJOR_VERSION', nm_major_version)
|
||||
data_conf.set('NM_MICRO_VERSION', nm_micro_version)
|
||||
data_conf.set('NM_MINOR_VERSION', nm_minor_version)
|
||||
data_conf.set('NM_MODIFY_SYSTEM_POLICY', (enable_modify_system ? 'yes' : 'auth_admin_keep'))
|
||||
data_conf.set('NM_VERSION', nm_version)
|
||||
data_conf.set('VERSION', nm_version)
|
||||
data_conf.set('bindir', nm_bindir)
|
||||
|
|
@ -1069,6 +1077,7 @@ output = '\nSystem paths:\n'
|
|||
output += ' prefix: ' + nm_prefix + '\n'
|
||||
output += ' exec_prefix: ' + nm_prefix + '\n'
|
||||
output += ' systemdunitdir: ' + systemd_systemdsystemunitdir + '\n'
|
||||
output += ' systemdgeneratordir: ' + systemd_systemdsystemgeneratordir + '\n'
|
||||
output += ' udev_dir: ' + udev_udevdir + '\n'
|
||||
output += ' nmbinary: ' + nm_pkgsbindir + '\n'
|
||||
output += ' nmconfdir: ' + nm_pkgconfdir + '\n'
|
||||
|
|
@ -1083,17 +1092,7 @@ output += ' dbus_conf_dir: ' + dbus_conf_dir + '\n'
|
|||
output += '\nPlatform:\n'
|
||||
output += ' session tracking: ' + ','.join(session_trackers) + '\n'
|
||||
output += ' suspend/resume: ' + suspend_resume + '\n'
|
||||
output += ' policykit: ' + enable_polkit.to_string() + ' (default: ' + config_auth_polkit_default + ')'
|
||||
if enable_polkit
|
||||
output += ' ('
|
||||
if enable_modify_system
|
||||
output += 'permissive'
|
||||
else
|
||||
output += 'restrictive'
|
||||
endif
|
||||
output += ' modify.system)'
|
||||
endif
|
||||
output += '\n'
|
||||
output += ' policykit: ' + enable_polkit.to_string() + ' (default: ' + config_auth_polkit_default + ', noauth_group: "' + polkit_noauth_group + '")\n'
|
||||
output += ' polkit-agent-helper-1: ' + polkit_agent_helper_1_path + '\n'
|
||||
output += ' selinux: ' + enable_selinux.to_string() + '\n'
|
||||
output += ' systemd-journald: ' + enable_systemd_journal.to_string() + ' (default: logging.backend=' + config_logging_backend_default + ')\n'
|
||||
|
|
@ -1157,6 +1156,5 @@ output += 'have-nss: ' + crypto_nss_dep.found().to_string() + ')\n'
|
|||
output += ' sanitizers: ' + get_option('b_sanitize') + '\n'
|
||||
output += ' Mozilla Public Suffix List: ' + enable_libpsl.to_string() + '\n'
|
||||
output += ' vapi: ' + enable_vapi.to_string() + '\n'
|
||||
output += ' ebpf: ' + enable_ebpf.to_string() + '\n'
|
||||
output += ' readline: ' + with_readline + '\n'
|
||||
message(output)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
# system paths
|
||||
option('systemdsystemunitdir', type: 'string', value: '', description: 'Directory for systemd service files')
|
||||
option('systemdsystemgeneratordir', type: 'string', value: '', description: 'Directory for systemd generator files')
|
||||
option('system_ca_path', type: 'string', value: '/etc/ssl/certs', description: 'path to system CA certificates')
|
||||
option('udev_dir', type: 'string', value: '', description: 'Absolute path of the udev base directory. Set to \'no\' not to install the udev rule')
|
||||
option('dbus_conf_dir', type: 'string', value: '', description: 'where D-Bus system.d directory is')
|
||||
|
|
@ -18,7 +19,8 @@ option('session_tracking', type: 'combo', choices: ['systemd', 'elogind', 'no'],
|
|||
option('suspend_resume', type: 'combo', choices: ['systemd', 'elogind', 'consolekit', 'auto'], value: 'auto', description: 'Build NetworkManager with specific suspend/resume support')
|
||||
option('polkit', type: 'boolean', value: true, description: 'User auth-polkit configuration option.')
|
||||
option('config_auth_polkit_default', type: 'combo', choices: ['default', 'true', 'false', 'root-only'], value: 'default', description: 'Default value for configuration main.auth-polkit.')
|
||||
option('modify_system', type: 'boolean', value: false, description: 'Allow users to modify system connections')
|
||||
option('modify_system', type: 'boolean', value: false, description: 'Allow users to modify system connections (option no longer supported, don\'t use)')
|
||||
option('polkit_noauth_group', type: 'string', value: '', description: 'Allow users of the selected group, typically sudo or wheel, to modify system connections without introducing a password (discouraged)')
|
||||
option('polkit_agent_helper_1', type: 'string', value: '', description: 'Path name to the polkit-agent-helper-1 binary from polkit')
|
||||
option('selinux', type: 'boolean', value: true, description: 'Build with SELinux')
|
||||
option('systemd_journal', type: 'boolean', value: true, description: 'Use systemd journal for logging')
|
||||
|
|
@ -28,7 +30,7 @@ option('hostname_persist', type: 'combo', choices: ['default', 'suse', 'gentoo',
|
|||
option('libaudit', type: 'combo', choices: ['yes', 'yes-disabled-by-default', 'no'], value: 'yes', description: 'Build with audit daemon support. yes-disabled-by-default enables support, but disables it unless explicitly configured via NetworkManager.conf')
|
||||
|
||||
# features
|
||||
option('wext', type: 'boolean', value: true, description: 'Enable or disable Linux Wireless Extensions')
|
||||
option('wext', type: 'combo', choices: ['true', 'false', 'force' ], value: 'false', description: 'Enable or disable Linux Wireless Extensions (deprecated). wext support will be removed in a future release, don\'t rely on this.')
|
||||
option('wifi', type: 'boolean', value: true, description: 'enable Wi-Fi support')
|
||||
option('iwd', type: 'boolean', value: false, description: 'enable iwd support (experimental)')
|
||||
option('ppp', type: 'boolean', value: true, description: 'enable PPP/PPPoE support')
|
||||
|
|
@ -44,7 +46,7 @@ option('nmcli', type: 'boolean', value: true, description: 'Build nmcli')
|
|||
option('nmtui', type: 'boolean', value: true, description: 'Build nmtui')
|
||||
option('nm_cloud_setup', type: 'boolean', value: true, description: 'Build nm-cloud-setup, a tool for automatically configuring networking in cloud')
|
||||
option('bluez5_dun', type: 'boolean', value: false, description: 'enable Bluez5 DUN support')
|
||||
option('ebpf', type: 'combo', choices: ['auto', 'true', 'false'], description: 'Enable eBPF support')
|
||||
option('ebpf', type: 'combo', choices: ['auto', 'true', 'false'], description: 'Enable eBPF support (deprecated)')
|
||||
option('nbft', type: 'boolean', value: true, description: 'Enable NBFT support in the initrd generator')
|
||||
|
||||
# configuration plugins
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# List of source files containing translatable strings.
|
||||
# Please keep this file sorted alphabetically.
|
||||
data/org.freedesktop.NetworkManager.policy.in.in
|
||||
data/org.freedesktop.NetworkManager.policy.in
|
||||
src/core/NetworkManagerUtils.c
|
||||
src/core/devices/adsl/nm-device-adsl.c
|
||||
src/core/devices/bluetooth/nm-bluez-manager.c
|
||||
|
|
|
|||
97
po/ca.po
97
po/ca.po
|
|
@ -8,14 +8,15 @@
|
|||
# Lubomir Rintel <lkundrak@v3.sk>, 2016. #zanata
|
||||
# Lubomir Rintel <lkundrak@v3.sk>, 2017. #zanata
|
||||
# Thomas Haller <thaller@redhat.com>, 2017. #zanata
|
||||
# Jordi Mas i Hernàndez <jmas@softcatala.org>, 2025
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: NetworkManager\n"
|
||||
"Report-Msgid-Bugs-To: https://gitlab.freedesktop.org/NetworkManager/"
|
||||
"NetworkManager/issues\n"
|
||||
"POT-Creation-Date: 2023-06-16 15:26+0000\n"
|
||||
"PO-Revision-Date: 2023-06-17 00:07+0200\n"
|
||||
"Last-Translator: Copied by Zanata <copied-by-zanata@zanata.org>\n"
|
||||
"PO-Revision-Date: 2025-09-28 00:07+0200\n"
|
||||
"Last-Translator: Jordi Mas i Hernàndez <jmas@softcatala.org>\n"
|
||||
"Language-Team: Catalan <tradgnome@softcatala.org>\n"
|
||||
"Language: ca\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
|
|
@ -355,7 +356,7 @@ msgstr "Connexió WPAN"
|
|||
|
||||
#: src/core/devices/team/nm-device-team.c:131
|
||||
msgid "Team connection"
|
||||
msgstr "Connexió equip"
|
||||
msgstr "Connexió d'equip"
|
||||
|
||||
#: src/core/devices/wifi/nm-device-olpc-mesh.c:112 src/nmcli/devices.c:1400
|
||||
msgid "Mesh"
|
||||
|
|
@ -648,7 +649,7 @@ msgstr "Surt després de la configuració inicial"
|
|||
#: src/core/nm-config.c:639
|
||||
msgid "Don't become a daemon, and log to stderr"
|
||||
msgstr ""
|
||||
"No et converteixis en un dimoni, i envia el registre a la sortida estàndard"
|
||||
"No et converteixis en un dimoni, i envia el registre a la sortida d'error"
|
||||
|
||||
#: src/core/nm-config.c:648
|
||||
msgid "An http(s) address for checking internet connectivity"
|
||||
|
|
@ -795,7 +796,7 @@ msgstr "La connexió no era una connexió Ethernet o PPPoE."
|
|||
|
||||
#: src/libnm-client-impl/nm-device-ethernet.c:206
|
||||
msgid "The connection and device differ in S390 subchannels."
|
||||
msgstr "La connexió i el dispositiu difereixen als subcanals 5930."
|
||||
msgstr "La connexió i el dispositiu difereixen als subcanals S390."
|
||||
|
||||
#: src/libnm-client-impl/nm-device-ethernet.c:223
|
||||
#, c-format
|
||||
|
|
@ -881,7 +882,7 @@ msgstr "La connexió no era una connexió tun."
|
|||
|
||||
#: src/libnm-client-impl/nm-device-team.c:124
|
||||
msgid "The connection was not a team connection."
|
||||
msgstr "La connexió no era una connexió equip."
|
||||
msgstr "La connexió no era una connexió d'equip."
|
||||
|
||||
#: src/libnm-client-impl/nm-device-tun.c:204
|
||||
msgid "The connection was not a tun connection."
|
||||
|
|
@ -1325,27 +1326,27 @@ msgstr ""
|
|||
|
||||
#: src/libnm-core-impl/nm-keyfile.c:333
|
||||
msgid "ignoring missing number"
|
||||
msgstr "s'ignorarà el número faltant"
|
||||
msgstr "s'ignora el número faltant"
|
||||
|
||||
#: src/libnm-core-impl/nm-keyfile.c:345
|
||||
#, c-format
|
||||
msgid "ignoring invalid number '%s'"
|
||||
msgstr "s'ignorarà el número «%s» no vàlid"
|
||||
msgstr "s'ignora el número «%s» no vàlid"
|
||||
|
||||
#: src/libnm-core-impl/nm-keyfile.c:374
|
||||
#, c-format
|
||||
msgid "ignoring invalid %s address: %s"
|
||||
msgstr "s'ignorarà l'adreça %s no vàlida: %s"
|
||||
msgstr "s'ignora l'adreça %s no vàlida: %s"
|
||||
|
||||
#: src/libnm-core-impl/nm-keyfile.c:420
|
||||
#, c-format
|
||||
msgid "ignoring invalid gateway '%s' for %s route"
|
||||
msgstr "s'ignorarà la passarel·la «%s» no vàlida per a la ruta %s"
|
||||
msgstr "s'ignora la passarel·la «%s» no vàlida per a la ruta %s"
|
||||
|
||||
#: src/libnm-core-impl/nm-keyfile.c:442
|
||||
#, c-format
|
||||
msgid "ignoring invalid %s route: %s"
|
||||
msgstr "s'ignorarà la ruta %s no vàlida: %s"
|
||||
msgstr "s'ignora la ruta %s no vàlida: %s"
|
||||
|
||||
#: src/libnm-core-impl/nm-keyfile.c:620
|
||||
#, c-format
|
||||
|
|
@ -1361,7 +1362,7 @@ msgstr "caràcter «%c» inesperat per a %s: «%s» (posició %td)"
|
|||
#, c-format
|
||||
msgid "unexpected character '%c' in prefix length for %s: '%s' (position %td)"
|
||||
msgstr ""
|
||||
"caràcter «%c» inesperat a la longitud de prefix %s: «%s» (posició %td)<"
|
||||
"caràcter «%c» inesperat a la longitud de prefix %s: «%s» (posició %td)"
|
||||
|
||||
#: src/libnm-core-impl/nm-keyfile.c:669
|
||||
#, c-format
|
||||
|
|
@ -1413,11 +1414,11 @@ msgstr "s'ignorarà l'adreça %s no vàlida: %s"
|
|||
|
||||
#: src/libnm-core-impl/nm-keyfile.c:1518
|
||||
msgid "ignoring invalid SSID"
|
||||
msgstr "s'ignorarà l'SSID no vàlida"
|
||||
msgstr "s'ignora l'SSID no vàlida"
|
||||
|
||||
#: src/libnm-core-impl/nm-keyfile.c:1536
|
||||
msgid "ignoring invalid raw password"
|
||||
msgstr "s'ignorarà la contrasenya sense processar no vàlida"
|
||||
msgstr "s'ignora la contrasenya sense processar no vàlida"
|
||||
|
||||
#: src/libnm-core-impl/nm-keyfile.c:1681
|
||||
msgid "invalid key/cert value"
|
||||
|
|
@ -1458,7 +1459,7 @@ msgstr "valor de paritat «%s» no vàlid"
|
|||
#: src/libnm-core-impl/nm-keyfile.c:1958 src/libnm-core-impl/nm-keyfile.c:3540
|
||||
#, c-format
|
||||
msgid "invalid setting: %s"
|
||||
msgstr "el paràmetre no és vàlid: «%s»"
|
||||
msgstr "el paràmetre no és vàlid: %s"
|
||||
|
||||
#: src/libnm-core-impl/nm-keyfile.c:1978
|
||||
#, fuzzy, c-format
|
||||
|
|
@ -1973,7 +1974,7 @@ msgstr "file:// URI no és UTF-8 vàlida"
|
|||
|
||||
#: src/libnm-core-impl/nm-setting-connection.c:1501
|
||||
msgid "invalid permissions not in format \"user:$UNAME[:]\""
|
||||
msgstr "els permisos no són vàlids, no estan en el format «user:$UNANE[:]"
|
||||
msgstr "els permisos no són vàlids, no estan en el format «user:$UNAME[:]"
|
||||
|
||||
#: src/libnm-core-impl/nm-setting-connection.c:1530
|
||||
#, c-format
|
||||
|
|
@ -2086,7 +2087,7 @@ msgstr "«%s» no és un número"
|
|||
|
||||
#: src/libnm-core-impl/nm-setting-gsm.c:479
|
||||
msgid "property is empty or wrong size"
|
||||
msgstr "la propietat és buda o de mida incorrecta"
|
||||
msgstr "la propietat és buida o de mida incorrecta"
|
||||
|
||||
#: src/libnm-core-impl/nm-setting-gsm.c:492
|
||||
msgid "property must contain only digits"
|
||||
|
|
@ -2098,12 +2099,12 @@ msgstr "no es pot activar quan hi ha una configuració manual"
|
|||
|
||||
#: src/libnm-core-impl/nm-setting-infiniband.c:215
|
||||
msgid "Must specify a P_Key if specifying parent"
|
||||
msgstr "S'ha d'especificar una P-Key si s'especifica el pare"
|
||||
msgstr "S'ha d'especificar una P_Key si s'especifica el pare"
|
||||
|
||||
#: src/libnm-core-impl/nm-setting-infiniband.c:226
|
||||
msgid "InfiniBand P_Key connection did not specify parent interface name"
|
||||
msgstr ""
|
||||
"La connexió InfiniBand P_Key no ha especificat el nom de l'interfície pare"
|
||||
"La connexió InfiniBand P_Key no ha especificat el nom de la interfície pare"
|
||||
|
||||
#: src/libnm-core-impl/nm-setting-infiniband.c:234
|
||||
msgid "the values 0 and 0x8000 are not allowed"
|
||||
|
|
@ -2156,12 +2157,12 @@ msgstr "Adreça IPv4 «%s» no és vàlida"
|
|||
#: src/libnm-core-impl/nm-setting-ip-config.c:106
|
||||
#, c-format
|
||||
msgid "Invalid IPv4 address prefix '%u'"
|
||||
msgstr "Prefix «%u» d'adreça IPv4 no vàlida"
|
||||
msgstr "Prefix «%u» d'adreça IPv4 no vàlid"
|
||||
|
||||
#: src/libnm-core-impl/nm-setting-ip-config.c:107
|
||||
#, c-format
|
||||
msgid "Invalid IPv6 address prefix '%u'"
|
||||
msgstr "Prefix «%u» d'adreça IPv6 no vàlida<"
|
||||
msgstr "Prefix «%u» d'adreça IPv6 no vàlid"
|
||||
|
||||
#: src/libnm-core-impl/nm-setting-ip-config.c:124
|
||||
#, c-format
|
||||
|
|
@ -2208,7 +2209,7 @@ msgstr "el prefix %s no és vàlid"
|
|||
#: src/libnm-core-impl/nm-setting-ip-config.c:1423
|
||||
#, c-format
|
||||
msgid "%s is not a valid route type"
|
||||
msgstr "%s no és un nom de ruta vàlid"
|
||||
msgstr "%s no és un tipus de ruta vàlid"
|
||||
|
||||
#: src/libnm-core-impl/nm-setting-ip-config.c:1442
|
||||
#, fuzzy
|
||||
|
|
@ -2432,7 +2433,7 @@ msgstr "La ruta %d. no és vàlida"
|
|||
#: src/libnm-core-impl/nm-setting-ip-config.c:5638
|
||||
#, c-format
|
||||
msgid "invalid attribute: %s"
|
||||
msgstr "atribut no vàlid: «%s»"
|
||||
msgstr "atribut no vàlid: %s"
|
||||
|
||||
#: src/libnm-core-impl/nm-setting-ip-config.c:5658
|
||||
#, c-format
|
||||
|
|
@ -4105,7 +4106,7 @@ msgstr "«%s» no és vàlid; useu [%s] or [%s]"
|
|||
#: src/libnmc-base/nm-client-utils.c:176
|
||||
#, c-format
|
||||
msgid "'%s' is not valid; use [%s], [%s] or [%s]"
|
||||
msgstr "«%s» no és vàld, useu [%s], [%s] o [%s]"
|
||||
msgstr "«%s» no és vàlid, useu [%s], [%s] o [%s]"
|
||||
|
||||
#: src/libnmc-base/nm-client-utils.c:230
|
||||
#, c-format
|
||||
|
|
@ -4676,7 +4677,7 @@ msgstr "clau privada no vàlida"
|
|||
#, fuzzy, c-format
|
||||
msgid "Secrets are required to connect WireGuard VPN '%s'"
|
||||
msgstr ""
|
||||
"Es requereixen contrasenyes o claus d'encriptació per accedir la xarxa sens "
|
||||
"Es requereixen contrasenyes o claus d'encriptació per accedir la xarxa sense "
|
||||
"fil «%s»."
|
||||
|
||||
#: src/libnmc-base/nm-secret-agent-simple.c:620
|
||||
|
|
@ -4698,7 +4699,7 @@ msgid ""
|
|||
"Passwords or encryption keys are required to access the wireless network "
|
||||
"'%s'."
|
||||
msgstr ""
|
||||
"Es requereixen contrasenyes o claus d'encriptació per accedir la xarxa sens "
|
||||
"Es requereixen contrasenyes o claus d'encriptació per accedir la xarxa sense "
|
||||
"fil «%s»."
|
||||
|
||||
#: src/libnmc-base/nm-secret-agent-simple.c:886
|
||||
|
|
@ -4709,7 +4710,7 @@ msgstr "Autenticació 802.1X de xarxa amb fil"
|
|||
#, fuzzy, c-format
|
||||
msgid "Secrets are required to access the wired network '%s'"
|
||||
msgstr ""
|
||||
"Es requereixen contrasenyes o claus d'encriptació per accedir la xarxa sens "
|
||||
"Es requereixen contrasenyes o claus d'encriptació per accedir la xarxa sense "
|
||||
"fil «%s»."
|
||||
|
||||
#: src/libnmc-base/nm-secret-agent-simple.c:893
|
||||
|
|
@ -5418,10 +5419,10 @@ msgid ""
|
|||
msgstr ""
|
||||
"Entreu els bytes com una llista de valors hexadecimals.\n"
|
||||
"S'accepten dos formats:\n"
|
||||
"(a) una cadena de dígits exadecimals, on cada dos dígits representen un "
|
||||
"(a) una cadena de dígits hexadecimals, on cada dos dígits representen un "
|
||||
"byte\n"
|
||||
"(b) una llista separada per espais de bytes escrits com a dígits hexadecimas "
|
||||
"(amb prefix opcional 0x/0X,i un 0 inicial opcional). \n"
|
||||
"(b) una llista separada per espais de bytes escrits com a dígits hexadecimals "
|
||||
"(amb prefix opcional 0x/0X,i un 0 inicial opcional).\n"
|
||||
"\n"
|
||||
"Exemples: ab0455a6ea3a74C2\n"
|
||||
" ab 4 55 0xa6 ea 3a 74 C2\n"
|
||||
|
|
@ -5493,7 +5494,7 @@ msgstr "Demora cap endavant"
|
|||
#: src/libnmc-setting/nm-meta-setting-desc.c:5280
|
||||
#: src/nmtui/nmt-page-bridge.c:134
|
||||
msgid "Hello time"
|
||||
msgstr "Temps de benviguda"
|
||||
msgstr "Temps de benvinguda"
|
||||
|
||||
#: src/libnmc-setting/nm-meta-setting-desc.c:5286
|
||||
#: src/nmtui/nmt-page-bridge.c:148
|
||||
|
|
@ -5567,7 +5568,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Entreu les connexions secundàries que s'haurien d'activar quan s'activa "
|
||||
"aquesta connexió. Les connexions es poden especificar o bé per UUID o per ID "
|
||||
"(nom). L'nmcli tradueix transparentment els noms a UUID. Noteu que el "
|
||||
"(nom). nmcli tradueix transparentment els noms a UUID. Noteu que el "
|
||||
"NetworkManager actualment sols dóna suport els VPN com a connexions "
|
||||
"secundàries.\n"
|
||||
"Els elements es poden separar per comes o espais.\n"
|
||||
|
|
@ -5676,7 +5677,7 @@ msgid ""
|
|||
" priority [prio] [from [src]] [to [dst]], ,...\n"
|
||||
"\n"
|
||||
msgstr ""
|
||||
"Introduïu una llista de regles d'encaminanent IPv4 amb el següent format:\n"
|
||||
"Introduïu una llista de regles d'encaminament IPv4 amb el següent format:\n"
|
||||
" priority [prioritat] [from [origen]] [to [destí]], ,...\n"
|
||||
"\n"
|
||||
"\n"
|
||||
|
|
@ -5696,7 +5697,7 @@ msgstr ""
|
|||
"configuració IPv6 \n"
|
||||
"és «auto» aquests servidors DNS s'annexen als que retorna (si retorna cap) "
|
||||
"la \n"
|
||||
"configuració automatica. Els servidors DNS no es poden usar amb els métodes "
|
||||
"configuració automàtica. Els servidors DNS no es poden usar amb els mètodes "
|
||||
"de \n"
|
||||
"configuracó DNS «shared» o «link-local», atès que no hi una xarxa superior. "
|
||||
"A tots\n"
|
||||
|
|
@ -8151,12 +8152,12 @@ msgstr ""
|
|||
"canonada (|) o un ampersand (&). El primer indica que l'element és opcional "
|
||||
"i el segon significa que és obligatori. Si hi ha algun element opcional, "
|
||||
"llavors la coincidència avalua a cert si almenys un dels elements opcionals "
|
||||
"coincideix (O lògicà). Si hi ha elements obligatoris, llavors tots han de "
|
||||
"coincideix (O lògica). Si hi ha elements obligatoris, llavors tots han de "
|
||||
"coincidir (I lògica). Per defecte, un element és opcional. Això significa "
|
||||
"que un element «foo» es comporta igual que «|foo». Un element també es pot "
|
||||
"invertir amb el símbol d'exclamació (!) entre el símbol de la canonada (o de "
|
||||
"l'ampersand) i abans del patró. Tingueu en compte que «!foo» és una drecera "
|
||||
"per al patró obligatòri «&!foo». Finalment, es pot utilitzar una barra "
|
||||
"per al patró obligatori «&!foo». Finalment, es pot utilitzar una barra "
|
||||
"inversa al començament de l'element (després dels caràcters especials "
|
||||
"opcionals) per no considerar-lo inici del patró. Per exemple, «\\!a» és una "
|
||||
"coincidència obligatòria per literalment «!a»."
|
||||
|
|
@ -10722,7 +10723,7 @@ msgstr "Error: «%s» no és una connexió activa.\n"
|
|||
|
||||
#: src/nmcli/connections.c:3436
|
||||
msgid "Error: not all active connections found."
|
||||
msgstr "Error: No s'han trobar totes les connexions actives."
|
||||
msgstr "Error: No s'han trobat totes les connexions actives."
|
||||
|
||||
#: src/nmcli/connections.c:3444
|
||||
msgid "Error: no active connection provided."
|
||||
|
|
@ -11041,7 +11042,7 @@ msgstr ""
|
|||
"Verifica si el paràmetre o la connexió és vàlida i es pot desar més tard.\n"
|
||||
"Indica valors no vàlids quan hi ha un error. Alguns errors es poden "
|
||||
"corregir\n"
|
||||
"automàticaent amb l'opció «fix».\n"
|
||||
"automàticament amb l'opció «fix».\n"
|
||||
"\n"
|
||||
"Exemples: nmcli> verify\n"
|
||||
" nmcli> verify fix\n"
|
||||
|
|
@ -11063,7 +11064,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"save [persistent|temporary] :: desa la connexió\n"
|
||||
"\n"
|
||||
"Envia el perfil de la connexió al NetworManager que o bé la desarà de forma\n"
|
||||
"Envia el perfil de la connexió al NetworkManager que o bé la desarà de forma\n"
|
||||
"persistent o bé sols la mantindrà a la memòria. «desa» sense cap argument\n"
|
||||
"significa «desa de forma persistent».\n"
|
||||
"Noteu que un cop que deseu el perfile de forma persistent aquestes "
|
||||
|
|
@ -11485,7 +11486,7 @@ msgstr "Opció no vàlida de verificació: %s\n"
|
|||
#: src/nmcli/connections.c:8486
|
||||
#, c-format
|
||||
msgid "Verify setting '%s': %s\n"
|
||||
msgstr "Verifica el paràmere «%s»: %s\n"
|
||||
msgstr "Verifica el paràmetre «%s»: %s\n"
|
||||
|
||||
#: src/nmcli/connections.c:8501
|
||||
#, c-format
|
||||
|
|
@ -11552,12 +11553,12 @@ msgstr "Error: no es pot activar la connexió: %s.\n"
|
|||
#: src/nmcli/connections.c:8679
|
||||
#, c-format
|
||||
msgid "Error: Failed to activate '%s' (%s) connection: %s\n"
|
||||
msgstr "Error: no s'ha pogut desconnectar la connexió «%s» (%s): %s\n"
|
||||
msgstr "Error: no s'ha pogut activar la connexió «%s» (%s): %s\n"
|
||||
|
||||
#: src/nmcli/connections.c:8686
|
||||
msgid "Monitoring connection activation (press any key to continue)\n"
|
||||
msgstr ""
|
||||
"S'està supervisant l'activació de la connexio (premeu qualsevol teclar per "
|
||||
"S'està supervisant l'activació de la connexió (premeu qualsevol tecla per "
|
||||
"continuar)\n"
|
||||
|
||||
#: src/nmcli/connections.c:8721
|
||||
|
|
@ -11582,7 +11583,7 @@ msgstr "Configuració actual del nmcli:\n"
|
|||
#: src/nmcli/connections.c:8753
|
||||
#, c-format
|
||||
msgid "Invalid configuration option '%s'; allowed [%s]\n"
|
||||
msgstr "Opció de configuració no vàida: «%s»; es permet [%s]\n"
|
||||
msgstr "Opció de configuració no vàlida: «%s»; es permet [%s]\n"
|
||||
|
||||
#: src/nmcli/connections.c:8985
|
||||
#, fuzzy
|
||||
|
|
@ -12396,7 +12397,7 @@ msgstr "Error: no s'ha pogut afegir/activar la connexió nova: %s"
|
|||
#: src/nmcli/devices.c:2266
|
||||
#, c-format
|
||||
msgid "Error: Device activation failed: %s"
|
||||
msgstr "Error: no s'ha pogut activar el dispositu: %s"
|
||||
msgstr "Error: no s'ha pogut activar el dispositiu: %s"
|
||||
|
||||
#: src/nmcli/devices.c:2322
|
||||
#, c-format
|
||||
|
|
@ -12603,7 +12604,7 @@ msgstr "Contrasenya: "
|
|||
#: src/nmcli/devices.c:4172
|
||||
#, c-format
|
||||
msgid "'%s' is not valid WPA PSK"
|
||||
msgstr "«%s» no és una WPS PSK vàlida"
|
||||
msgstr "«%s» no és una WPA PSK vàlida"
|
||||
|
||||
#: src/nmcli/devices.c:4193
|
||||
#, c-format
|
||||
|
|
@ -13538,7 +13539,7 @@ msgstr "Error: s'esperava l'argument «%s», però s'ha proporcionat «%s»."
|
|||
#: src/nmcli/utils.c:315
|
||||
#, c-format
|
||||
msgid "Error: Unexpected argument '%s'"
|
||||
msgstr "Error: argument inesperat «%s»."
|
||||
msgstr "Error: argument inesperat «%s»"
|
||||
|
||||
#: src/nmcli/utils.c:702
|
||||
#, fuzzy, c-format
|
||||
|
|
@ -13897,7 +13898,7 @@ msgstr "«%s» <"
|
|||
#. NB: the ordering/numbering here corresponds to NmtPageBondMonitoringMode
|
||||
#: src/nmtui/nmt-page-bond.c:92
|
||||
msgid "MII (recommended)"
|
||||
msgstr "MII (recomendat)"
|
||||
msgstr "MII (recomanat)"
|
||||
|
||||
#: src/nmtui/nmt-page-bond.c:93
|
||||
msgid "ARP"
|
||||
|
|
@ -14543,7 +14544,7 @@ msgstr ""
|
|||
|
||||
#: src/nmtui/nmtui-edit.c:394 src/nmtui/nmtui-edit.c:410
|
||||
msgid "New Connection"
|
||||
msgstr "Connexions nova"
|
||||
msgstr "Connexió nova"
|
||||
|
||||
#: src/nmtui/nmtui-edit.c:452
|
||||
#, c-format
|
||||
|
|
|
|||
9522
po/pt_BR.po
9522
po/pt_BR.po
File diff suppressed because it is too large
Load diff
|
|
@ -629,10 +629,17 @@ build_supplicant_config(NMDeviceEthernet *self, GError **error)
|
|||
mtu = nm_platform_link_get_mtu(nm_device_get_platform(NM_DEVICE(self)),
|
||||
nm_device_get_ifindex(NM_DEVICE(self)));
|
||||
|
||||
config = nm_supplicant_config_new(NM_SUPPL_CAP_MASK_NONE);
|
||||
config = nm_supplicant_config_new(NM_SUPPL_CAP_MASK_NONE,
|
||||
nm_utils_get_connection_first_permissions_user(connection));
|
||||
|
||||
security = nm_connection_get_setting_802_1x(connection);
|
||||
if (!nm_supplicant_config_add_setting_8021x(config, security, con_uuid, mtu, TRUE, error)) {
|
||||
if (!nm_supplicant_config_add_setting_8021x(config,
|
||||
security,
|
||||
con_uuid,
|
||||
mtu,
|
||||
TRUE,
|
||||
nm_device_get_private_files(NM_DEVICE(self)),
|
||||
error)) {
|
||||
g_prefix_error(error, "802-1x-setting: ");
|
||||
g_clear_object(&config);
|
||||
}
|
||||
|
|
@ -700,6 +707,9 @@ supplicant_iface_start(NMDeviceEthernet *self)
|
|||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE(self);
|
||||
gs_unref_object NMSupplicantConfig *config = NULL;
|
||||
gs_free_error GError *error = NULL;
|
||||
NMActRequest *request;
|
||||
NMActiveConnection *controller_ac;
|
||||
NMDevice *controller;
|
||||
|
||||
config = build_supplicant_config(self, &error);
|
||||
if (!config) {
|
||||
|
|
@ -714,6 +724,16 @@ supplicant_iface_start(NMDeviceEthernet *self)
|
|||
}
|
||||
|
||||
nm_supplicant_interface_disconnect(priv->supplicant.iface);
|
||||
|
||||
/* Tell the supplicant in which bridge the interface is */
|
||||
if ((request = nm_device_get_act_request(NM_DEVICE(self)))
|
||||
&& (controller_ac = nm_active_connection_get_controller(NM_ACTIVE_CONNECTION(request)))
|
||||
&& (controller = nm_active_connection_get_device(controller_ac))
|
||||
&& nm_device_get_device_type(controller) == NM_DEVICE_TYPE_BRIDGE) {
|
||||
nm_supplicant_interface_set_bridge(priv->supplicant.iface, nm_device_get_iface(controller));
|
||||
} else
|
||||
nm_supplicant_interface_set_bridge(priv->supplicant.iface, NULL);
|
||||
|
||||
nm_supplicant_interface_assoc(priv->supplicant.iface, config, supplicant_iface_assoc_cb, self);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -116,29 +116,51 @@ create_and_realize(NMDevice *device,
|
|||
const NMPlatformLink **out_plink,
|
||||
GError **error)
|
||||
{
|
||||
const char *iface = nm_device_get_iface(device);
|
||||
NMSettingHsr *s_hsr;
|
||||
NMPlatformLnkHsr lnk = {};
|
||||
int r;
|
||||
const char *iface = nm_device_get_iface(device);
|
||||
nm_auto_free char *err_msg = NULL;
|
||||
NMSettingHsr *s_hsr;
|
||||
NMPlatformLnkHsr lnk = {};
|
||||
int r = 0;
|
||||
|
||||
s_hsr = _nm_connection_get_setting(connection, NM_TYPE_SETTING_HSR);
|
||||
|
||||
nm_assert(s_hsr);
|
||||
|
||||
if (nm_setting_hsr_get_port1(s_hsr) != NULL)
|
||||
lnk.port1 = nm_platform_link_get_ifindex(NM_PLATFORM_GET, nm_setting_hsr_get_port1(s_hsr));
|
||||
if (nm_setting_hsr_get_port2(s_hsr) != NULL)
|
||||
lnk.port2 = nm_platform_link_get_ifindex(NM_PLATFORM_GET, nm_setting_hsr_get_port2(s_hsr));
|
||||
lnk.multicast_spec = nm_setting_hsr_get_multicast_spec(s_hsr);
|
||||
lnk.prp = nm_setting_hsr_get_prp(s_hsr);
|
||||
if (nm_setting_hsr_get_interlink(s_hsr) != NULL) {
|
||||
const char *ifname = nm_setting_hsr_get_interlink(s_hsr);
|
||||
int ifindex = nm_platform_link_get_ifindex(NM_PLATFORM_GET, ifname);
|
||||
|
||||
if (ifindex <= 0) {
|
||||
err_msg = g_strdup_printf("interlink port '%s' does not exist", ifname);
|
||||
goto out;
|
||||
}
|
||||
|
||||
lnk.interlink = ifindex;
|
||||
}
|
||||
|
||||
lnk.multicast_spec = nm_setting_hsr_get_multicast_spec(s_hsr);
|
||||
lnk.prp = nm_setting_hsr_get_prp(s_hsr);
|
||||
lnk.protocol_version = nm_setting_hsr_get_protocol_version(s_hsr);
|
||||
|
||||
r = nm_platform_link_hsr_add(nm_device_get_platform(device), iface, &lnk, out_plink);
|
||||
|
||||
if (r < 0) {
|
||||
err_msg = g_strdup(nm_strerror(r) ?: "unknown");
|
||||
}
|
||||
|
||||
out:
|
||||
if (err_msg) {
|
||||
g_set_error(error,
|
||||
NM_DEVICE_ERROR,
|
||||
NM_DEVICE_ERROR_CREATION_FAILED,
|
||||
"Failed to create HSR interface '%s' for '%s': %s",
|
||||
iface,
|
||||
nm_connection_get_id(connection),
|
||||
nm_strerror(r));
|
||||
err_msg);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -201,7 +201,8 @@ build_supplicant_config(NMDeviceMacsec *self, GError **error)
|
|||
mtu = nm_platform_link_get_mtu(nm_device_get_platform(NM_DEVICE(self)),
|
||||
nm_device_get_ifindex(NM_DEVICE(self)));
|
||||
|
||||
config = nm_supplicant_config_new(NM_SUPPL_CAP_MASK_NONE);
|
||||
config = nm_supplicant_config_new(NM_SUPPL_CAP_MASK_NONE,
|
||||
nm_utils_get_connection_first_permissions_user(connection));
|
||||
|
||||
s_macsec = nm_device_get_applied_setting(NM_DEVICE(self), NM_TYPE_SETTING_MACSEC);
|
||||
|
||||
|
|
@ -227,7 +228,13 @@ build_supplicant_config(NMDeviceMacsec *self, GError **error)
|
|||
|
||||
if (nm_setting_macsec_get_mode(s_macsec) == NM_SETTING_MACSEC_MODE_EAP) {
|
||||
s_8021x = nm_connection_get_setting_802_1x(connection);
|
||||
if (!nm_supplicant_config_add_setting_8021x(config, s_8021x, con_uuid, mtu, TRUE, error)) {
|
||||
if (!nm_supplicant_config_add_setting_8021x(config,
|
||||
s_8021x,
|
||||
con_uuid,
|
||||
mtu,
|
||||
TRUE,
|
||||
nm_device_get_private_files(NM_DEVICE(self)),
|
||||
error)) {
|
||||
g_prefix_error(error, "802-1x-setting: ");
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -433,6 +440,9 @@ supplicant_iface_start(NMDeviceMacsec *self)
|
|||
NMDeviceMacsecPrivate *priv = NM_DEVICE_MACSEC_GET_PRIVATE(self);
|
||||
gs_unref_object NMSupplicantConfig *config = NULL;
|
||||
gs_free_error GError *error = NULL;
|
||||
NMActRequest *request;
|
||||
NMActiveConnection *controller_ac;
|
||||
NMDevice *controller;
|
||||
|
||||
config = build_supplicant_config(self, &error);
|
||||
if (!config) {
|
||||
|
|
@ -445,6 +455,16 @@ supplicant_iface_start(NMDeviceMacsec *self)
|
|||
}
|
||||
|
||||
nm_supplicant_interface_disconnect(priv->supplicant.iface);
|
||||
|
||||
/* Tell the supplicant in which bridge the interface is */
|
||||
if ((request = nm_device_get_act_request(NM_DEVICE(self)))
|
||||
&& (controller_ac = nm_active_connection_get_controller(NM_ACTIVE_CONNECTION(request)))
|
||||
&& (controller = nm_active_connection_get_device(controller_ac))
|
||||
&& nm_device_get_device_type(controller) == NM_DEVICE_TYPE_BRIDGE) {
|
||||
nm_supplicant_interface_set_bridge(priv->supplicant.iface, nm_device_get_iface(controller));
|
||||
} else
|
||||
nm_supplicant_interface_set_bridge(priv->supplicant.iface, NULL);
|
||||
|
||||
nm_supplicant_interface_assoc(priv->supplicant.iface, config, supplicant_iface_assoc_cb, self);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -115,9 +115,6 @@ gboolean nm_device_sysctl_ip_conf_set(NMDevice *self,
|
|||
|
||||
NML3ConfigData *nm_device_create_l3_config_data(NMDevice *self, NMIPConfigSource source);
|
||||
|
||||
NML3ConfigData *nm_device_create_l3_config_data_from_connection(NMDevice *self,
|
||||
NMConnection *connection);
|
||||
|
||||
void nm_device_ip_method_dhcp4_start(NMDevice *self);
|
||||
|
||||
void nm_device_ip_method_autoconf6_start(NMDevice *self);
|
||||
|
|
@ -179,4 +176,6 @@ void nm_device_auth_request(NMDevice *self,
|
|||
|
||||
void nm_device_link_properties_set(NMDevice *self, gboolean reapply);
|
||||
|
||||
GHashTable *nm_device_get_private_files(NMDevice *self);
|
||||
|
||||
#endif /* NM_DEVICE_PRIVATE_H */
|
||||
|
|
|
|||
|
|
@ -135,13 +135,17 @@ NM_UTILS_LOOKUP_STR_DEFINE(
|
|||
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_LINK_NOT_INIT,
|
||||
"unmanaged-link-not-init"),
|
||||
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_QUITTING, "unmanaged-quitting"),
|
||||
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_SLEEPING, "unmanaged-sleeping"),
|
||||
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_MANAGER_DISABLED,
|
||||
"unmanaged-nm-disabled"),
|
||||
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_USER_CONF, "unmanaged-user-conf"),
|
||||
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_USER_EXPLICIT,
|
||||
"unmanaged-user-explicit"),
|
||||
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_USER_SETTINGS,
|
||||
"unmanaged-user-settings"),
|
||||
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_USER_UDEV, "unmanaged-user-udev"), );
|
||||
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_UNMANAGED_USER_UDEV, "unmanaged-user-udev"),
|
||||
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_NETWORKING_OFF, "networking-off"),
|
||||
NM_UTILS_LOOKUP_STR_ITEM(NM_DEVICE_STATE_REASON_MODEM_NO_OPERATOR_CODE,
|
||||
"modem-no-operator-code"), );
|
||||
|
||||
NM_UTILS_LOOKUP_STR_DEFINE(nm_device_mtu_source_to_string,
|
||||
NMDeviceMtuSource,
|
||||
|
|
@ -235,7 +239,7 @@ resolve_addr_helper_cb(GObject *source, GAsyncResult *result, gpointer user_data
|
|||
gs_free_error GError *error = NULL;
|
||||
gs_free char *output = NULL;
|
||||
|
||||
output = nm_utils_spawn_helper_finish(result, &error);
|
||||
output = nm_utils_spawn_helper_finish_string(result, &error);
|
||||
if (nm_utils_error_is_cancelled(error))
|
||||
return;
|
||||
|
||||
|
|
@ -274,6 +278,7 @@ resolve_addr_spawn_helper(ResolveAddrInfo *info, ResolveAddrService services)
|
|||
nm_inet_ntop(info->addr_family, &info->address, addr_str);
|
||||
_LOG2D(info, "start lookup via nm-daemon-helper using services: %s", str);
|
||||
nm_utils_spawn_helper(NM_MAKE_STRV("resolve-address", addr_str, str),
|
||||
FALSE,
|
||||
g_task_get_cancellable(info->task),
|
||||
resolve_addr_helper_cb,
|
||||
info);
|
||||
|
|
|
|||
|
|
@ -113,6 +113,19 @@ typedef enum {
|
|||
RELEASE_PORT_TYPE_CONFIG_FORCE,
|
||||
} ReleasePortType;
|
||||
|
||||
/**
|
||||
* CleanupType:
|
||||
* @CLEANUP_TYPE_KEEP: Cleanup internally but keep the real device's config. This is
|
||||
* often used when moving a partially managed device to "unmanaged" (but not only).
|
||||
* @CLEANUP_TYPE_REMOVED: The device suddently disappeared. Cleanup internally but don't
|
||||
* make any action on the real device at all, as it no longer exists.
|
||||
* @CLEANUP_TYPE_DECONFIGURE: Also deconfigure the real device. This is the typical
|
||||
* action when a connection or device is set to "down", or fully managed devices
|
||||
* moved to "unmanaged".
|
||||
* @CLEANUP_TYPE_KEEP_REAPPLY: Like %CLEANUP_TYPE_KEEP, but indicating that it's a
|
||||
* reapply. Some special actions can be done if we're doing a reapply, like keeping
|
||||
* the existing DHCP lease, for example.
|
||||
*/
|
||||
typedef enum {
|
||||
CLEANUP_TYPE_KEEP,
|
||||
CLEANUP_TYPE_REMOVED,
|
||||
|
|
@ -335,6 +348,12 @@ typedef struct {
|
|||
int addr_family;
|
||||
} HostnameResolver;
|
||||
|
||||
typedef enum {
|
||||
PRIVATE_FILES_STATE_UNKNOWN = 0,
|
||||
PRIVATE_FILES_STATE_READING,
|
||||
PRIVATE_FILES_STATE_DONE,
|
||||
} PrivateFilesState;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
enum {
|
||||
|
|
@ -692,6 +711,8 @@ typedef struct _NMDevicePrivate {
|
|||
|
||||
IPDevStateData ipdev_data_unspec;
|
||||
|
||||
gulong sharing_ipv4_changed_id;
|
||||
|
||||
struct {
|
||||
/* If we set the addrgenmode6, this records the previously set value. */
|
||||
guint8 previous_mode_val;
|
||||
|
|
@ -769,6 +790,13 @@ typedef struct _NMDevicePrivate {
|
|||
guint64 rx_bytes;
|
||||
} stats;
|
||||
|
||||
struct {
|
||||
GHashTable *table;
|
||||
GCancellable *cancellable;
|
||||
char *user;
|
||||
PrivateFilesState state;
|
||||
} private_files;
|
||||
|
||||
bool mtu_force_set_done : 1;
|
||||
|
||||
bool needs_ip6_subnet : 1;
|
||||
|
|
@ -779,7 +807,6 @@ typedef struct _NMDevicePrivate {
|
|||
char *prop_ip_iface; /* IP interface D-Bus property */
|
||||
GList *ping_operations;
|
||||
GSource *ping_timeout;
|
||||
bool refresh_forwarding_done : 1;
|
||||
} NMDevicePrivate;
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE(NMDevice, nm_device, NM_TYPE_DBUS_OBJECT)
|
||||
|
|
@ -867,6 +894,8 @@ static void _dev_ipshared4_spawn_dnsmasq(NMDevice *self);
|
|||
|
||||
static void _dev_ipshared6_start(NMDevice *self);
|
||||
|
||||
static void _dev_ipforwarding4_start(NMDevice *self, int addr_family);
|
||||
|
||||
static void
|
||||
_cleanup_ip_pre(NMDevice *self, int addr_family, CleanupType cleanup_type, gboolean preserve_dhcp);
|
||||
|
||||
|
|
@ -1395,14 +1424,12 @@ _prop_get_ipvx_routed_dns(NMDevice *self, int addr_family)
|
|||
}
|
||||
|
||||
static NMSettingConnectionMdns
|
||||
_prop_get_connection_mdns(NMDevice *self)
|
||||
_prop_get_connection_mdns(NMDevice *self, NMConnection *connection)
|
||||
{
|
||||
NMConnection *connection;
|
||||
NMSettingConnectionMdns mdns = NM_SETTING_CONNECTION_MDNS_DEFAULT;
|
||||
|
||||
g_return_val_if_fail(NM_IS_DEVICE(self), NM_SETTING_CONNECTION_MDNS_DEFAULT);
|
||||
|
||||
connection = nm_device_get_applied_connection(self);
|
||||
if (connection)
|
||||
mdns = nm_setting_connection_get_mdns(nm_connection_get_setting_connection(connection));
|
||||
if (mdns != NM_SETTING_CONNECTION_MDNS_DEFAULT)
|
||||
|
|
@ -1437,14 +1464,12 @@ _prop_get_sriov_preserve_on_down(NMDevice *self, NMSettingSriov *s_sriov)
|
|||
}
|
||||
|
||||
static NMSettingConnectionLlmnr
|
||||
_prop_get_connection_llmnr(NMDevice *self)
|
||||
_prop_get_connection_llmnr(NMDevice *self, NMConnection *connection)
|
||||
{
|
||||
NMConnection *connection;
|
||||
NMSettingConnectionLlmnr llmnr = NM_SETTING_CONNECTION_LLMNR_DEFAULT;
|
||||
|
||||
g_return_val_if_fail(NM_IS_DEVICE(self), NM_SETTING_CONNECTION_LLMNR_DEFAULT);
|
||||
|
||||
connection = nm_device_get_applied_connection(self);
|
||||
if (connection)
|
||||
llmnr = nm_setting_connection_get_llmnr(nm_connection_get_setting_connection(connection));
|
||||
if (llmnr != NM_SETTING_CONNECTION_LLMNR_DEFAULT)
|
||||
|
|
@ -1459,14 +1484,12 @@ _prop_get_connection_llmnr(NMDevice *self)
|
|||
}
|
||||
|
||||
static NMSettingConnectionDnsOverTls
|
||||
_prop_get_connection_dns_over_tls(NMDevice *self)
|
||||
_prop_get_connection_dns_over_tls(NMDevice *self, NMConnection *connection)
|
||||
{
|
||||
NMConnection *connection;
|
||||
NMSettingConnectionDnsOverTls dns_over_tls = NM_SETTING_CONNECTION_DNS_OVER_TLS_DEFAULT;
|
||||
|
||||
g_return_val_if_fail(NM_IS_DEVICE(self), NM_SETTING_CONNECTION_DNS_OVER_TLS_DEFAULT);
|
||||
|
||||
connection = nm_device_get_applied_connection(self);
|
||||
if (connection)
|
||||
dns_over_tls = nm_setting_connection_get_dns_over_tls(
|
||||
nm_connection_get_setting_connection(connection));
|
||||
|
|
@ -1481,15 +1504,33 @@ _prop_get_connection_dns_over_tls(NMDevice *self)
|
|||
NM_SETTING_CONNECTION_DNS_OVER_TLS_DEFAULT);
|
||||
}
|
||||
|
||||
static NMMptcpFlags
|
||||
_prop_get_connection_mptcp_flags(NMDevice *self)
|
||||
static NMSettingConnectionDnssec
|
||||
_prop_get_connection_dnssec(NMDevice *self, NMConnection *connection)
|
||||
{
|
||||
NMConnection *connection;
|
||||
NMMptcpFlags mptcp_flags = NM_MPTCP_FLAGS_NONE;
|
||||
NMSettingConnectionDnssec dnssec = NM_SETTING_CONNECTION_DNSSEC_DEFAULT;
|
||||
|
||||
g_return_val_if_fail(NM_IS_DEVICE(self), NM_SETTING_CONNECTION_DNSSEC_DEFAULT);
|
||||
|
||||
if (connection)
|
||||
dnssec = nm_setting_connection_get_dnssec(nm_connection_get_setting_connection(connection));
|
||||
if (dnssec != NM_SETTING_CONNECTION_DNSSEC_DEFAULT)
|
||||
return dnssec;
|
||||
|
||||
return nm_config_data_get_connection_default_int64(NM_CONFIG_GET_DATA,
|
||||
NM_CON_DEFAULT("connection.dnssec"),
|
||||
self,
|
||||
NM_SETTING_CONNECTION_DNSSEC_NO,
|
||||
NM_SETTING_CONNECTION_DNSSEC_YES,
|
||||
NM_SETTING_CONNECTION_DNSSEC_DEFAULT);
|
||||
}
|
||||
|
||||
static NMMptcpFlags
|
||||
_prop_get_connection_mptcp_flags(NMDevice *self, NMConnection *connection)
|
||||
{
|
||||
NMMptcpFlags mptcp_flags = NM_MPTCP_FLAGS_NONE;
|
||||
|
||||
g_return_val_if_fail(NM_IS_DEVICE(self), NM_MPTCP_FLAGS_DISABLED);
|
||||
|
||||
connection = nm_device_get_applied_connection(self);
|
||||
if (connection) {
|
||||
mptcp_flags =
|
||||
nm_setting_connection_get_mptcp_flags(nm_connection_get_setting_connection(connection));
|
||||
|
|
@ -2131,8 +2172,8 @@ _prop_get_ipvx_dhcp_send_hostname(NMDevice *self, int addr_family)
|
|||
return send_hostname_v2;
|
||||
}
|
||||
|
||||
NMSettingIPConfigForwarding
|
||||
nm_device_get_ipv4_forwarding(NMDevice *self)
|
||||
static NMSettingIPConfigForwarding
|
||||
_prop_get_ipv4_forwarding(NMDevice *self)
|
||||
{
|
||||
NMSettingIPConfig *s_ip;
|
||||
NMSettingIPConfigForwarding forwarding;
|
||||
|
|
@ -2455,16 +2496,14 @@ _prop_get_ipv4_dhcp_vendor_class_identifier(NMDevice *self, NMSettingIP4Config *
|
|||
}
|
||||
|
||||
static NMSettingIP6ConfigPrivacy
|
||||
_prop_get_ipv6_ip6_privacy(NMDevice *self)
|
||||
_prop_get_ipv6_ip6_privacy(NMDevice *self, NMConnection *connection)
|
||||
{
|
||||
NMSettingIP6ConfigPrivacy ip6_privacy;
|
||||
NMConnection *connection;
|
||||
|
||||
g_return_val_if_fail(self, NM_SETTING_IP6_CONFIG_PRIVACY_UNKNOWN);
|
||||
|
||||
/* 1.) First look at the per-connection setting. If it is not -1 (unknown),
|
||||
* use it. */
|
||||
connection = nm_device_get_applied_connection(self);
|
||||
if (connection) {
|
||||
NMSettingIPConfig *s_ip6 = nm_connection_get_setting_ip6_config(connection);
|
||||
|
||||
|
|
@ -3597,11 +3636,12 @@ nm_device_create_l3_config_data_from_connection(NMDevice *self, NMConnection *co
|
|||
|
||||
l3cd =
|
||||
nm_l3_config_data_new_from_connection(nm_device_get_multi_index(self), ifindex, connection);
|
||||
nm_l3_config_data_set_mdns(l3cd, _prop_get_connection_mdns(self));
|
||||
nm_l3_config_data_set_llmnr(l3cd, _prop_get_connection_llmnr(self));
|
||||
nm_l3_config_data_set_dns_over_tls(l3cd, _prop_get_connection_dns_over_tls(self));
|
||||
nm_l3_config_data_set_ip6_privacy(l3cd, _prop_get_ipv6_ip6_privacy(self));
|
||||
nm_l3_config_data_set_mptcp_flags(l3cd, _prop_get_connection_mptcp_flags(self));
|
||||
nm_l3_config_data_set_mdns(l3cd, _prop_get_connection_mdns(self, connection));
|
||||
nm_l3_config_data_set_llmnr(l3cd, _prop_get_connection_llmnr(self, connection));
|
||||
nm_l3_config_data_set_dns_over_tls(l3cd, _prop_get_connection_dns_over_tls(self, connection));
|
||||
nm_l3_config_data_set_dnssec(l3cd, _prop_get_connection_dnssec(self, connection));
|
||||
nm_l3_config_data_set_ip6_privacy(l3cd, _prop_get_ipv6_ip6_privacy(self, connection));
|
||||
nm_l3_config_data_set_mptcp_flags(l3cd, _prop_get_connection_mptcp_flags(self, connection));
|
||||
return l3cd;
|
||||
}
|
||||
|
||||
|
|
@ -3778,7 +3818,7 @@ nm_device_assume_state_reset(NMDevice *self)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
char *
|
||||
static char *
|
||||
nm_device_sysctl_ip_conf_get(NMDevice *self, int addr_family, const char *property)
|
||||
{
|
||||
const char *ifname;
|
||||
|
|
@ -6304,6 +6344,14 @@ concheck_is_possible(NMDevice *self)
|
|||
if (priv->state == NM_DEVICE_STATE_UNKNOWN)
|
||||
return FALSE;
|
||||
|
||||
if (!nm_config_data_get_device_config_boolean_by_device(
|
||||
NM_CONFIG_GET_DATA,
|
||||
NM_CONFIG_KEYFILE_KEY_DEVICE_CHECK_CONNECTIVITY,
|
||||
self,
|
||||
TRUE,
|
||||
TRUE))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -6324,8 +6372,10 @@ concheck_periodic_schedule_do(NMDevice *self, int addr_family, gint64 now_ns)
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (!concheck_is_possible(self))
|
||||
if (!concheck_is_possible(self)) {
|
||||
concheck_update_state(self, addr_family, NM_CONNECTIVITY_UNKNOWN, FALSE);
|
||||
goto out;
|
||||
}
|
||||
|
||||
nm_assert(now_ns > 0);
|
||||
nm_assert(priv->concheck_x[IS_IPv4].p_cur_interval > 0);
|
||||
|
|
@ -6548,7 +6598,11 @@ concheck_update_interval(NMDevice *self, int addr_family, gboolean check_now)
|
|||
concheck_periodic_schedule_do(self, addr_family, 0);
|
||||
|
||||
/* also update the fake connectivity state. */
|
||||
concheck_update_state(self, addr_family, NM_CONNECTIVITY_FAKE, TRUE);
|
||||
if (concheck_is_possible(self))
|
||||
concheck_update_state(self, addr_family, NM_CONNECTIVITY_FAKE, TRUE);
|
||||
else
|
||||
concheck_update_state(self, addr_family, NM_CONNECTIVITY_UNKNOWN, FALSE);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -6577,6 +6631,7 @@ concheck_update_state(NMDevice *self,
|
|||
/* @state is a result of the connectivity check. We only expect a precise
|
||||
* number of possible values. */
|
||||
nm_assert(NM_IN_SET(state,
|
||||
NM_CONNECTIVITY_UNKNOWN,
|
||||
NM_CONNECTIVITY_LIMITED,
|
||||
NM_CONNECTIVITY_PORTAL,
|
||||
NM_CONNECTIVITY_FULL,
|
||||
|
|
@ -6645,7 +6700,7 @@ concheck_update_state(NMDevice *self,
|
|||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
static const char *
|
||||
nm_device_get_effective_ip_config_method(NMDevice *self, int addr_family)
|
||||
{
|
||||
NMDeviceClass *klass;
|
||||
|
|
@ -6900,8 +6955,11 @@ nm_device_check_connectivity(NMDevice *self,
|
|||
NMDeviceConnectivityCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
if (!concheck_is_possible(self))
|
||||
if (!concheck_is_possible(self)) {
|
||||
concheck_update_state(self, AF_INET, NM_CONNECTIVITY_UNKNOWN, FALSE);
|
||||
concheck_update_state(self, AF_INET6, NM_CONNECTIVITY_UNKNOWN, FALSE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
concheck_periodic_schedule_set(self, addr_family, CONCHECK_SCHEDULE_CHECK_EXTERNAL);
|
||||
return concheck_start(self, addr_family, callback, user_data, FALSE);
|
||||
|
|
@ -8289,6 +8347,17 @@ config_changed(NMConfig *config,
|
|||
&& !nm_device_get_applied_setting(self, NM_TYPE_SETTING_SRIOV))
|
||||
device_init_static_sriov_num_vfs(self);
|
||||
}
|
||||
|
||||
if (NM_FLAGS_HAS(changes, NM_CONFIG_CHANGE_VALUES) && concheck_is_possible(self)) {
|
||||
/* restart (periodic) connectivity checks if they were previously disabled */
|
||||
if (!nm_config_data_get_device_config_boolean_by_device(
|
||||
old_data,
|
||||
NM_CONFIG_KEYFILE_KEY_DEVICE_CHECK_CONNECTIVITY,
|
||||
self,
|
||||
TRUE,
|
||||
TRUE))
|
||||
nm_device_check_connectivity_update_interval(self);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -8639,6 +8708,8 @@ nm_device_unrealize(NMDevice *self, gboolean remove_resources, GError **error)
|
|||
|
||||
g_object_thaw_notify(G_OBJECT(self));
|
||||
|
||||
nm_device_managed_type_set(self, NM_DEVICE_MANAGED_TYPE_REMOVED);
|
||||
|
||||
nm_device_set_unmanaged_flags(self, NM_UNMANAGED_PLATFORM_INIT, TRUE);
|
||||
|
||||
nm_device_set_unmanaged_flags(self,
|
||||
|
|
@ -10802,6 +10873,49 @@ tc_commit(NMDevice *self)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
read_private_files_cb(GObject *source_object, GAsyncResult *result, gpointer data)
|
||||
{
|
||||
gs_unref_hashtable GHashTable *table = NULL;
|
||||
gs_free_error GError *error = NULL;
|
||||
NMDevice *self;
|
||||
NMDevicePrivate *priv;
|
||||
|
||||
table = nm_utils_read_private_files_finish(result, &error);
|
||||
if (nm_utils_error_is_cancelled(error))
|
||||
return;
|
||||
|
||||
self = NM_DEVICE(data);
|
||||
priv = NM_DEVICE_GET_PRIVATE(self);
|
||||
|
||||
if (error) {
|
||||
NMConnection *connection = nm_device_get_applied_connection(self);
|
||||
|
||||
_LOGW(LOGD_DEVICE,
|
||||
"could not read files for private connection %s owned by user '%s': %s",
|
||||
connection ? nm_connection_get_uuid(connection) : NULL,
|
||||
priv->private_files.user,
|
||||
error->message);
|
||||
nm_device_state_changed(self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_CONFIG_FAILED);
|
||||
return;
|
||||
}
|
||||
|
||||
_LOGD(LOGD_DEVICE, "private files successfully read");
|
||||
|
||||
priv->private_files.state = PRIVATE_FILES_STATE_DONE;
|
||||
priv->private_files.table = g_steal_pointer(&table);
|
||||
g_clear_pointer(&priv->private_files.user, g_free);
|
||||
g_clear_object(&priv->private_files.cancellable);
|
||||
|
||||
nm_device_activate_schedule_stage2_device_config(self, FALSE);
|
||||
}
|
||||
|
||||
GHashTable *
|
||||
nm_device_get_private_files(NMDevice *self)
|
||||
{
|
||||
return NM_DEVICE_GET_PRIVATE(self)->private_files.table;
|
||||
}
|
||||
|
||||
/*
|
||||
* activate_stage2_device_config
|
||||
*
|
||||
|
|
@ -10814,6 +10928,7 @@ activate_stage2_device_config(NMDevice *self)
|
|||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
|
||||
NMDeviceClass *klass = NM_DEVICE_GET_CLASS(self);
|
||||
NMConnection *applied;
|
||||
NMActStageReturn ret;
|
||||
NMSettingWired *s_wired;
|
||||
gboolean no_firmware = FALSE;
|
||||
|
|
@ -10822,6 +10937,68 @@ activate_stage2_device_config(NMDevice *self)
|
|||
|
||||
nm_device_state_changed(self, NM_DEVICE_STATE_CONFIG, NM_DEVICE_STATE_REASON_NONE);
|
||||
|
||||
applied = nm_device_get_applied_connection(self);
|
||||
|
||||
/* If the connection is private (owned by a specific user), we need to
|
||||
* verify that the user has permission to access any files specified in
|
||||
* the connection, such as certificates and keys. We do that by calling
|
||||
* nm_utils_read_private_files() and saving the file contents in a hash
|
||||
* table that can be accessed later during the activation. It is important
|
||||
* to never access the files again to avoid TOCTOU bugs.
|
||||
*/
|
||||
switch (priv->private_files.state) {
|
||||
case PRIVATE_FILES_STATE_UNKNOWN:
|
||||
{
|
||||
gs_free const char **paths = NULL;
|
||||
NMSettingConnection *s_con;
|
||||
const char *user;
|
||||
|
||||
s_con = nm_connection_get_setting_connection(applied);
|
||||
nm_assert(s_con);
|
||||
user = _nm_setting_connection_get_first_permissions_user(s_con);
|
||||
|
||||
priv->private_files.user = g_strdup(user);
|
||||
if (!priv->private_files.user) {
|
||||
priv->private_files.state = PRIVATE_FILES_STATE_DONE;
|
||||
break;
|
||||
}
|
||||
|
||||
paths = nm_utils_get_connection_private_files_paths(applied);
|
||||
if (!paths) {
|
||||
priv->private_files.state = PRIVATE_FILES_STATE_DONE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (_nm_setting_connection_get_num_permissions_users(s_con) > 1) {
|
||||
_LOGW(LOGD_DEVICE,
|
||||
"private connections with multiple users are not allowed to reference "
|
||||
"certificates and keys on the filesystem. Specify only one user in the "
|
||||
"connection.permissions property.");
|
||||
nm_device_state_changed(self,
|
||||
NM_DEVICE_STATE_FAILED,
|
||||
NM_DEVICE_STATE_REASON_CONFIG_FAILED);
|
||||
return;
|
||||
}
|
||||
|
||||
priv->private_files.state = PRIVATE_FILES_STATE_READING;
|
||||
priv->private_files.cancellable = g_cancellable_new();
|
||||
|
||||
_LOGD(LOGD_DEVICE, "reading private files");
|
||||
nm_utils_read_private_files(paths,
|
||||
priv->private_files.user,
|
||||
priv->private_files.cancellable,
|
||||
read_private_files_cb,
|
||||
self);
|
||||
return;
|
||||
}
|
||||
case PRIVATE_FILES_STATE_READING:
|
||||
/* wait */
|
||||
return;
|
||||
case PRIVATE_FILES_STATE_DONE:
|
||||
/* proceed */
|
||||
break;
|
||||
}
|
||||
|
||||
if (!nm_device_managed_type_is_external(self)) {
|
||||
_ethtool_state_set(self);
|
||||
nm_device_link_properties_set(self, FALSE);
|
||||
|
|
@ -10838,7 +11015,7 @@ activate_stage2_device_config(NMDevice *self)
|
|||
priv->tc_committed = TRUE;
|
||||
}
|
||||
|
||||
nm_routing_rules_sync(nm_device_get_applied_connection(self),
|
||||
nm_routing_rules_sync(applied,
|
||||
NM_TERNARY_TRUE,
|
||||
klass->get_extra_rules,
|
||||
self,
|
||||
|
|
@ -12850,7 +13027,7 @@ _dev_ipac6_start(NMDevice *self)
|
|||
.router_solicitations = router_solicitations,
|
||||
.router_solicitation_interval = router_solicitation_interval,
|
||||
.ra_timeout = ra_timeout,
|
||||
.ip6_privacy = _prop_get_ipv6_ip6_privacy(self),
|
||||
.ip6_privacy = _prop_get_ipv6_ip6_privacy(self, connection),
|
||||
};
|
||||
|
||||
priv->ipac6_data.ndisc = nm_lndp_ndisc_new(&config);
|
||||
|
|
@ -13163,17 +13340,12 @@ activate_stage3_ip_config_for_addr_family(NMDevice *self, int addr_family)
|
|||
goto out_devip;
|
||||
|
||||
if (IS_IPv4) {
|
||||
NMSettingIPConfigForwarding ipv4_forwarding = nm_device_get_ipv4_forwarding(self);
|
||||
|
||||
if (NM_IN_SET(ipv4_forwarding,
|
||||
NM_SETTING_IP_CONFIG_FORWARDING_NO,
|
||||
NM_SETTING_IP_CONFIG_FORWARDING_YES)) {
|
||||
nm_device_sysctl_ip_conf_set(self, AF_INET, "forwarding", ipv4_forwarding ? "1" : "0");
|
||||
}
|
||||
priv->ipll_data_4.v4.mode = _prop_get_ipv4_link_local(self);
|
||||
if (priv->ipll_data_4.v4.mode == NM_SETTING_IP4_LL_ENABLED)
|
||||
_dev_ipll4_start(self);
|
||||
|
||||
_dev_ipforwarding4_start(self, addr_family);
|
||||
|
||||
if (nm_streq(priv->ipv4_method, NM_SETTING_IP4_CONFIG_METHOD_AUTO))
|
||||
_dev_ipdhcpx_start(self, AF_INET);
|
||||
else if (nm_streq(priv->ipv4_method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)) {
|
||||
|
|
@ -13493,15 +13665,21 @@ nm_device_activate_schedule_stage3_ip_config(NMDevice *self, gboolean do_sync)
|
|||
static void
|
||||
_dev_ipsharedx_set_state(NMDevice *self, int addr_family, NMDeviceIPState state)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
|
||||
const int IS_IPv4 = NM_IS_IPv4(addr_family);
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
|
||||
const int IS_IPv4 = NM_IS_IPv4(addr_family);
|
||||
NMDeviceIPState old_state = priv->ipshared_data_x[IS_IPv4].state;
|
||||
|
||||
if (priv->ipshared_data_x[IS_IPv4].state != state) {
|
||||
if (old_state != state) {
|
||||
_LOGD_ipshared(addr_family,
|
||||
"set state %s (was %s)",
|
||||
nm_device_ip_state_to_string(state),
|
||||
nm_device_ip_state_to_string(priv->ipshared_data_x[IS_IPv4].state));
|
||||
nm_device_ip_state_to_string(old_state));
|
||||
priv->ipshared_data_x[IS_IPv4].state = state;
|
||||
|
||||
if (old_state == NM_DEVICE_IP_STATE_READY || state == NM_DEVICE_IP_STATE_READY)
|
||||
nm_manager_update_shared_connection(NM_MANAGER_GET,
|
||||
addr_family,
|
||||
state == NM_DEVICE_IP_STATE_READY);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -13797,6 +13975,106 @@ _dev_ipshared6_start(NMDevice *self)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Set the device's forwarding to the specified value. If %NM_TERNARY_DEFAULT is specified,
|
||||
* it's set to the kernel's default, otherwise it's set to the specific value.
|
||||
*/
|
||||
static void
|
||||
_dev_ipforwarding4_set(NMDevice *self, NMTernary val)
|
||||
{
|
||||
gs_free const char *default_forwarding = NULL;
|
||||
gs_free const char *current_forwarding = NULL;
|
||||
const char *val_str;
|
||||
|
||||
if (val != NM_TERNARY_DEFAULT) {
|
||||
val_str = val ? "1" : "0";
|
||||
} else {
|
||||
default_forwarding = nm_platform_sysctl_get(
|
||||
nm_device_get_platform(self),
|
||||
NMP_SYSCTL_PATHID_ABSOLUTE("/proc/sys/net/ipv4/conf/default/forwarding"));
|
||||
|
||||
if (!default_forwarding) {
|
||||
_LOGW(LOGD_DEVICE,
|
||||
"error setting IPv4 forwarding: can't read default forwarding value: %s",
|
||||
nm_strerror_native(errno));
|
||||
return; /* Non fatal */
|
||||
}
|
||||
|
||||
val_str = default_forwarding;
|
||||
}
|
||||
|
||||
current_forwarding = nm_device_sysctl_ip_conf_get(self, AF_INET, "forwarding");
|
||||
if (nm_streq0(current_forwarding, val_str))
|
||||
return;
|
||||
|
||||
if (!nm_device_sysctl_ip_conf_set(self, AF_INET, "forwarding", val_str))
|
||||
_LOGW(LOGD_DEVICE,
|
||||
"error setting IPv4 forwarding to '%s': %s",
|
||||
val_str,
|
||||
nm_strerror_native(errno));
|
||||
}
|
||||
|
||||
static void
|
||||
_dev_ipforwarding4_auto_cb(NMManager *manager, gboolean sharing_ipv4, gpointer data)
|
||||
{
|
||||
NMDevice *self = NM_DEVICE(data);
|
||||
|
||||
_dev_ipforwarding4_set(self, sharing_ipv4 ? NM_TERNARY_TRUE : NM_TERNARY_DEFAULT);
|
||||
}
|
||||
|
||||
static void
|
||||
_dev_ipforwarding4_start(NMDevice *self, int addr_family)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
|
||||
NMSettingIPConfigForwarding ipv4_forwarding = _prop_get_ipv4_forwarding(self);
|
||||
NMTernary new_forwarding = NM_TERNARY_DEFAULT;
|
||||
|
||||
/* IPv6 per-interface forwarding not supported yet */
|
||||
if (addr_family != AF_INET)
|
||||
return;
|
||||
|
||||
if (nm_streq(priv->ipv4_method, NM_SETTING_IP4_CONFIG_METHOD_SHARED)) {
|
||||
new_forwarding = NM_TERNARY_TRUE;
|
||||
} else if (ipv4_forwarding == NM_SETTING_IP_CONFIG_FORWARDING_YES) {
|
||||
new_forwarding = NM_TERNARY_TRUE;
|
||||
} else if (ipv4_forwarding == NM_SETTING_IP_CONFIG_FORWARDING_NO) {
|
||||
new_forwarding = NM_TERNARY_FALSE;
|
||||
} else if (ipv4_forwarding == NM_SETTING_IP_CONFIG_FORWARDING_AUTO) {
|
||||
if (nm_manager_get_sharing_ipv4(NM_MANAGER_GET))
|
||||
new_forwarding = NM_TERNARY_TRUE;
|
||||
else
|
||||
new_forwarding = NM_TERNARY_DEFAULT;
|
||||
|
||||
if (!priv->sharing_ipv4_changed_id)
|
||||
priv->sharing_ipv4_changed_id = g_signal_connect(NM_MANAGER_GET,
|
||||
NM_MANAGER_SHARING_IPV4_CHANGED,
|
||||
G_CALLBACK(_dev_ipforwarding4_auto_cb),
|
||||
self);
|
||||
} else {
|
||||
nm_assert_not_reached();
|
||||
}
|
||||
|
||||
_dev_ipforwarding4_set(self, new_forwarding);
|
||||
}
|
||||
|
||||
static void
|
||||
_dev_ipforwarding_cleanup(NMDevice *self, int addr_family, CleanupType cleanup_type)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
|
||||
|
||||
if (!NM_IS_IPv4(addr_family))
|
||||
return;
|
||||
|
||||
nm_clear_g_signal_handler(NM_MANAGER_GET, &priv->sharing_ipv4_changed_id);
|
||||
|
||||
if (NM_IN_SET(cleanup_type, CLEANUP_TYPE_DECONFIGURE, CLEANUP_TYPE_KEEP_REAPPLY)) {
|
||||
/* Deconfigure by restoring kernel's default */
|
||||
_dev_ipforwarding4_set(self, NM_TERNARY_DEFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
act_request_set(NMDevice *self, NMActRequest *act_request)
|
||||
{
|
||||
|
|
@ -13909,6 +14187,8 @@ _cleanup_ip_pre(NMDevice *self, int addr_family, CleanupType cleanup_type, gbool
|
|||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
|
||||
gboolean keep_reapply = (cleanup_type == CLEANUP_TYPE_KEEP_REAPPLY);
|
||||
|
||||
_dev_ipforwarding_cleanup(self, addr_family, cleanup_type);
|
||||
|
||||
_dev_ipsharedx_cleanup(self, addr_family);
|
||||
|
||||
_dev_ipdev_cleanup(self, AF_UNSPEC);
|
||||
|
|
@ -14056,6 +14336,7 @@ can_reapply_change(NMDevice *self,
|
|||
NM_SETTING_CONNECTION_MDNS,
|
||||
NM_SETTING_CONNECTION_LLMNR,
|
||||
NM_SETTING_CONNECTION_DNS_OVER_TLS,
|
||||
NM_SETTING_CONNECTION_DNSSEC,
|
||||
NM_SETTING_CONNECTION_MPTCP_FLAGS,
|
||||
NM_SETTING_CONNECTION_WAIT_ACTIVATION_DELAY);
|
||||
}
|
||||
|
|
@ -14314,6 +14595,7 @@ check_and_reapply_connection(NMDevice *self,
|
|||
NM_SETTING_CONNECTION_MDNS,
|
||||
NM_SETTING_CONNECTION_LLMNR,
|
||||
NM_SETTING_CONNECTION_DNS_OVER_TLS,
|
||||
NM_SETTING_CONNECTION_DNSSEC,
|
||||
NM_SETTING_CONNECTION_MPTCP_FLAGS)) {
|
||||
priv->ip_data_4.do_reapply = TRUE;
|
||||
priv->ip_data_6.do_reapply = TRUE;
|
||||
|
|
@ -15665,7 +15947,7 @@ nm_device_get_firmware_missing(NMDevice *self)
|
|||
|
||||
NM_UTILS_FLAGS2STR_DEFINE(nm_unmanaged_flags2str,
|
||||
NMUnmanagedFlags,
|
||||
NM_UTILS_FLAGS2STR(NM_UNMANAGED_SLEEPING, "sleeping"),
|
||||
NM_UTILS_FLAGS2STR(NM_UNMANAGED_MANAGER_DISABLED, "nm-disabled"),
|
||||
NM_UTILS_FLAGS2STR(NM_UNMANAGED_QUITTING, "quitting"),
|
||||
NM_UTILS_FLAGS2STR(NM_UNMANAGED_PLATFORM_INIT, "platform-init"),
|
||||
NM_UTILS_FLAGS2STR(NM_UNMANAGED_USER_EXPLICIT, "user-explicit"),
|
||||
|
|
@ -15729,8 +16011,8 @@ unmanaged_flags_to_reason(NMUnmanagedFlags flags)
|
|||
/* Even if there are multiple flags, we can only return one reason.
|
||||
* Return the most important reason.
|
||||
*/
|
||||
if (NM_FLAGS_HAS(flags, NM_UNMANAGED_SLEEPING))
|
||||
return NM_DEVICE_STATE_REASON_UNMANAGED_SLEEPING;
|
||||
if (NM_FLAGS_HAS(flags, NM_UNMANAGED_MANAGER_DISABLED))
|
||||
return NM_DEVICE_STATE_REASON_UNMANAGED_MANAGER_DISABLED;
|
||||
if (NM_FLAGS_HAS(flags, NM_UNMANAGED_QUITTING))
|
||||
return NM_DEVICE_STATE_REASON_UNMANAGED_QUITTING;
|
||||
if (NM_FLAGS_HAS(flags, NM_UNMANAGED_USER_SETTINGS))
|
||||
|
|
@ -16975,8 +17257,6 @@ _cleanup_generic_post(NMDevice *self, NMDeviceStateReason reason, CleanupType cl
|
|||
priv->v4_route_table_all_sync_before = FALSE;
|
||||
priv->v6_route_table_all_sync_before = FALSE;
|
||||
|
||||
priv->refresh_forwarding_done = FALSE;
|
||||
|
||||
priv->mtu_force_set_done = FALSE;
|
||||
|
||||
priv->needs_ip6_subnet = FALSE;
|
||||
|
|
@ -17022,7 +17302,6 @@ nm_device_cleanup(NMDevice *self, NMDeviceStateReason reason, CleanupType cleanu
|
|||
NMDevicePrivate *priv;
|
||||
NMDeviceClass *klass = NM_DEVICE_GET_CLASS(self);
|
||||
int ifindex;
|
||||
gint32 default_forwarding_v4;
|
||||
|
||||
g_return_if_fail(NM_IS_DEVICE(self));
|
||||
|
||||
|
|
@ -17045,21 +17324,16 @@ nm_device_cleanup(NMDevice *self, NMDeviceStateReason reason, CleanupType cleanu
|
|||
nm_device_sysctl_ip_conf_set(self, AF_INET6, "use_tempaddr", "0");
|
||||
}
|
||||
|
||||
/* Restoring the device's forwarding to the sysctl default is necessary because
|
||||
* `refresh_forwarding()` only updates forwarding on activated devices. */
|
||||
default_forwarding_v4 = nm_platform_sysctl_get_int32(
|
||||
nm_device_get_platform(self),
|
||||
NMP_SYSCTL_PATHID_ABSOLUTE("/proc/sys/net/ipv4/conf/default/forwarding"),
|
||||
0);
|
||||
nm_device_sysctl_ip_conf_set(self,
|
||||
AF_INET,
|
||||
"forwarding",
|
||||
default_forwarding_v4 == 1 ? "1" : "0");
|
||||
|
||||
/* Call device type-specific deactivation */
|
||||
if (klass->deactivate)
|
||||
klass->deactivate(self);
|
||||
|
||||
/* Clean up private files */
|
||||
nm_clear_g_cancellable(&priv->private_files.cancellable);
|
||||
g_clear_pointer(&priv->private_files.table, g_hash_table_unref);
|
||||
g_clear_pointer(&priv->private_files.user, g_free);
|
||||
priv->private_files.state = PRIVATE_FILES_STATE_UNKNOWN;
|
||||
|
||||
ifindex = nm_device_get_ip_ifindex(self);
|
||||
|
||||
if (cleanup_type == CLEANUP_TYPE_DECONFIGURE) {
|
||||
|
|
@ -19009,19 +19283,6 @@ nm_device_get_hostname_from_dns_lookup(NMDevice *self, int addr_family, gboolean
|
|||
return nm_assert_unreachable_val(NULL);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_device_get_refresh_forwarding_done(NMDevice *self)
|
||||
{
|
||||
return NM_DEVICE_GET_PRIVATE(self)->refresh_forwarding_done;
|
||||
}
|
||||
|
||||
void
|
||||
nm_device_set_refresh_forwarding_done(NMDevice *self, gboolean is_refresh_forwarding_done)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE(self);
|
||||
priv->refresh_forwarding_done = is_refresh_forwarding_done;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static const char *
|
||||
|
|
|
|||
|
|
@ -581,7 +581,8 @@ void nm_device_copy_ip6_dns_config(NMDevice *self, NMDevice *from_device);
|
|||
/**
|
||||
* NMUnmanagedFlags:
|
||||
* @NM_UNMANAGED_NONE: placeholder value
|
||||
* @NM_UNMANAGED_SLEEPING: %TRUE when unmanaged because NM is sleeping.
|
||||
* @NM_UNMANAGED_MANAGER_DISABLED: %TRUE when unmanaged because NM is disabled.
|
||||
* Currently, this happens when sleeping or with networking disabled.
|
||||
* @NM_UNMANAGED_QUITTING: %TRUE when unmanaged because NM is shutting down.
|
||||
* @NM_UNMANAGED_PLATFORM_INIT: %TRUE when unmanaged because platform link not
|
||||
* yet initialized. Unrealized device are also unmanaged for this reason.
|
||||
|
|
@ -610,11 +611,11 @@ typedef enum {
|
|||
|
||||
/* these flags are authoritative. If one of them is set,
|
||||
* the device cannot be managed. */
|
||||
NM_UNMANAGED_SLEEPING = (1LL << 0),
|
||||
NM_UNMANAGED_QUITTING = (1LL << 1),
|
||||
NM_UNMANAGED_PLATFORM_INIT = (1LL << 2),
|
||||
NM_UNMANAGED_USER_EXPLICIT = (1LL << 3),
|
||||
NM_UNMANAGED_USER_SETTINGS = (1LL << 4),
|
||||
NM_UNMANAGED_MANAGER_DISABLED = (1LL << 0),
|
||||
NM_UNMANAGED_QUITTING = (1LL << 1),
|
||||
NM_UNMANAGED_PLATFORM_INIT = (1LL << 2),
|
||||
NM_UNMANAGED_USER_EXPLICIT = (1LL << 3),
|
||||
NM_UNMANAGED_USER_SETTINGS = (1LL << 4),
|
||||
|
||||
/* These flags can be non-effective and be overwritten
|
||||
* by other flags. */
|
||||
|
|
@ -852,14 +853,7 @@ void nm_routing_rules_sync(NMConnection *applied_connection,
|
|||
NMDevice *self,
|
||||
NMNetns *netns);
|
||||
|
||||
NMSettingIPConfigForwarding nm_device_get_ipv4_forwarding(NMDevice *self);
|
||||
|
||||
const char *nm_device_get_effective_ip_config_method(NMDevice *self, int addr_family);
|
||||
|
||||
char *nm_device_sysctl_ip_conf_get(NMDevice *self, int addr_family, const char *property);
|
||||
|
||||
gboolean nm_device_get_refresh_forwarding_done(NMDevice *self);
|
||||
|
||||
void nm_device_set_refresh_forwarding_done(NMDevice *self, gboolean is_refresh_forwarding_done);
|
||||
NML3ConfigData *nm_device_create_l3_config_data_from_connection(NMDevice *self,
|
||||
NMConnection *connection);
|
||||
|
||||
#endif /* __NETWORKMANAGER_DEVICE_H__ */
|
||||
|
|
|
|||
|
|
@ -1460,40 +1460,42 @@ _delete_interface(NMOvsdb *self, json_t *params, const char *ifname)
|
|||
json_array_append_new(new_interfaces, json_pack("[s,s]", "uuid", interface_uuid));
|
||||
}
|
||||
|
||||
if (num_nm_interfaces == 0) {
|
||||
/* The port no longer has any NM interface. Don't add it to "new_ports" and set
|
||||
* ports_changed=TRUE, so that it will be deleted. */
|
||||
if (interfaces_changed && num_nm_interfaces == 0) {
|
||||
/* We are deleting the last nm-interface of this port. Don't add it to "new_ports"
|
||||
* and set ports_changed=TRUE, so that it will be deleted. */
|
||||
ports_changed = TRUE;
|
||||
} else {
|
||||
if (interfaces_changed) {
|
||||
/* An interface needs to be deleted from this port */
|
||||
_expect_port_interfaces(params, ovs_port->name, interfaces);
|
||||
_set_port_interfaces(params, ovs_port->name, new_interfaces);
|
||||
}
|
||||
/* The port is still alive */
|
||||
/* Keep this port: it's still alive, or it's unrelated to the deleted interface */
|
||||
json_array_append_new(new_ports, json_pack("[s,s]", "uuid", port_uuid));
|
||||
if (ovs_port->connection_uuid)
|
||||
num_nm_ports++;
|
||||
|
||||
if (interfaces_changed) {
|
||||
/* This port is still alive, but an interface needs to be deleted from it */
|
||||
_expect_port_interfaces(params, ovs_port->name, interfaces);
|
||||
_set_port_interfaces(params, ovs_port->name, new_interfaces);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (num_nm_ports == 0) {
|
||||
/* The bridge no longer has any NM port. Don't add it to "new_bridges" and set
|
||||
* bridges_changed=TRUE, so that it will be deleted. */
|
||||
if (ports_changed && num_nm_ports == 0) {
|
||||
/* We are deleting the last nm-port of this bridge. Don't add it to "new_bridges"
|
||||
* and set bridges_changed=TRUE, so that it will be deleted. */
|
||||
bridges_changed = TRUE;
|
||||
} else {
|
||||
/* Keep this bridge: it's still alive, or it's unrelated to the deleted interface */
|
||||
json_array_append_new(new_bridges, json_pack("[s,s]", "uuid", ovs_bridge->bridge_uuid));
|
||||
|
||||
if (ports_changed) {
|
||||
/* A port needs to be deleted from this bridge */
|
||||
/* This bridge is still alive, but a port needs to be deleted from it */
|
||||
_expect_bridge_ports(params, ovs_bridge->name, ports);
|
||||
_set_bridge_ports(params, ovs_bridge->name, new_ports);
|
||||
}
|
||||
/* The bridge is still alive */
|
||||
json_array_append_new(new_bridges, json_pack("[s,s]", "uuid", ovs_bridge->bridge_uuid));
|
||||
}
|
||||
}
|
||||
|
||||
if (bridges_changed) {
|
||||
/* A port needs to be deleted from this bridge */
|
||||
/* A bridge needs to be deleted */
|
||||
_expect_ovs_bridges(params, priv->db_uuid, bridges);
|
||||
_set_ovs_bridges(params, priv->db_uuid, new_bridges);
|
||||
}
|
||||
|
|
@ -1888,7 +1890,7 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg)
|
|||
== -1) {
|
||||
/* This doesn't really have to be an error; the key might
|
||||
* be missing if there really are no bridges present. */
|
||||
_LOGD("Bad update: %s", json_error.text);
|
||||
_LOGD("monitor: bad update: %s", json_error.text);
|
||||
}
|
||||
|
||||
if (ovs) {
|
||||
|
|
@ -1934,12 +1936,12 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg)
|
|||
&unused))
|
||||
continue;
|
||||
|
||||
_LOGT("obj[iface:%s]: removed an '%s' interface: %s%s%s",
|
||||
key,
|
||||
ovs_interface->type,
|
||||
_LOGT("monitor: %s: interface removed: type=%s, obj[iface:%s]%s%s",
|
||||
ovs_interface->name,
|
||||
ovs_interface->type,
|
||||
key,
|
||||
NM_PRINT_FMT_QUOTED2(ovs_interface->connection_uuid,
|
||||
", ",
|
||||
", connection=",
|
||||
ovs_interface->connection_uuid,
|
||||
""));
|
||||
_signal_emit_device_removed(self,
|
||||
|
|
@ -1987,17 +1989,18 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg)
|
|||
gs_free char *strtmp1 = NULL;
|
||||
gs_free char *strtmp2 = NULL;
|
||||
|
||||
_LOGT("obj[iface:%s]: changed an '%s' interface: %s%s%s, external-ids=%s, "
|
||||
"other-config=%s",
|
||||
key,
|
||||
type,
|
||||
ovs_interface->name,
|
||||
NM_PRINT_FMT_QUOTED2(ovs_interface->connection_uuid,
|
||||
", ",
|
||||
ovs_interface->connection_uuid,
|
||||
""),
|
||||
(strtmp1 = _strdict_to_string(ovs_interface->external_ids)),
|
||||
(strtmp2 = _strdict_to_string(ovs_interface->other_config)));
|
||||
_LOGT(
|
||||
"monitor: %s: interface changed: type=%s, obj[iface:%s]%s%s, external-ids=%s, "
|
||||
"other-config=%s",
|
||||
ovs_interface->name,
|
||||
type,
|
||||
key,
|
||||
NM_PRINT_FMT_QUOTED2(ovs_interface->connection_uuid,
|
||||
", connection=",
|
||||
ovs_interface->connection_uuid,
|
||||
""),
|
||||
(strtmp1 = _strdict_to_string(ovs_interface->external_ids)),
|
||||
(strtmp2 = _strdict_to_string(ovs_interface->other_config)));
|
||||
}
|
||||
} else {
|
||||
gs_free char *strtmp1 = NULL;
|
||||
|
|
@ -2013,17 +2016,17 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg)
|
|||
.other_config = g_steal_pointer(&other_config_arr),
|
||||
};
|
||||
g_hash_table_add(priv->interfaces, ovs_interface);
|
||||
_LOGT(
|
||||
"obj[iface:%s]: added an '%s' interface: %s%s%s, external-ids=%s, other-config=%s",
|
||||
key,
|
||||
ovs_interface->type,
|
||||
ovs_interface->name,
|
||||
NM_PRINT_FMT_QUOTED2(ovs_interface->connection_uuid,
|
||||
", ",
|
||||
ovs_interface->connection_uuid,
|
||||
""),
|
||||
(strtmp1 = _strdict_to_string(ovs_interface->external_ids)),
|
||||
(strtmp2 = _strdict_to_string(ovs_interface->other_config)));
|
||||
_LOGT("monitor: %s: interface added: type=%s, obj[iface:%s]%s%s, external-ids=%s, "
|
||||
"other-config=%s",
|
||||
ovs_interface->name,
|
||||
ovs_interface->type,
|
||||
key,
|
||||
NM_PRINT_FMT_QUOTED2(ovs_interface->connection_uuid,
|
||||
", connection=",
|
||||
ovs_interface->connection_uuid,
|
||||
""),
|
||||
(strtmp1 = _strdict_to_string(ovs_interface->external_ids)),
|
||||
(strtmp2 = _strdict_to_string(ovs_interface->other_config)));
|
||||
_signal_emit_device_added(self,
|
||||
ovs_interface->name,
|
||||
NM_DEVICE_TYPE_OVS_INTERFACE,
|
||||
|
|
@ -2069,11 +2072,11 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg)
|
|||
if (!g_hash_table_steal_extended(priv->ports, &key, (gpointer *) &ovs_port, &unused))
|
||||
continue;
|
||||
|
||||
_LOGT("obj[port:%s]: removed a port: %s%s%s",
|
||||
key,
|
||||
_LOGT("monitor: %s: port removed: obj[port:%s]%s%s",
|
||||
ovs_port->name,
|
||||
key,
|
||||
NM_PRINT_FMT_QUOTED2(ovs_port->connection_uuid,
|
||||
", ",
|
||||
", connection=",
|
||||
ovs_port->connection_uuid,
|
||||
""));
|
||||
_signal_emit_device_removed(self, ovs_port->name, NM_DEVICE_TYPE_OVS_PORT, NULL);
|
||||
|
|
@ -2120,15 +2123,16 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg)
|
|||
gs_free char *strtmp1 = NULL;
|
||||
gs_free char *strtmp2 = NULL;
|
||||
|
||||
_LOGT("obj[port:%s]: changed a port: %s%s%s, external-ids=%s, other-config=%s",
|
||||
key,
|
||||
ovs_port->name,
|
||||
NM_PRINT_FMT_QUOTED2(ovs_port->connection_uuid,
|
||||
", ",
|
||||
ovs_port->connection_uuid,
|
||||
""),
|
||||
(strtmp1 = _strdict_to_string(ovs_port->external_ids)),
|
||||
(strtmp2 = _strdict_to_string(ovs_port->other_config)));
|
||||
_LOGT(
|
||||
"monitor: %s: port changed: obj[port:%s]%s%s, external-ids=%s, other-config=%s",
|
||||
ovs_port->name,
|
||||
key,
|
||||
NM_PRINT_FMT_QUOTED2(ovs_port->connection_uuid,
|
||||
", connection=",
|
||||
ovs_port->connection_uuid,
|
||||
""),
|
||||
(strtmp1 = _strdict_to_string(ovs_port->external_ids)),
|
||||
(strtmp2 = _strdict_to_string(ovs_port->other_config)));
|
||||
}
|
||||
} else {
|
||||
gs_free char *strtmp1 = NULL;
|
||||
|
|
@ -2144,11 +2148,11 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg)
|
|||
.other_config = g_steal_pointer(&other_config_arr),
|
||||
};
|
||||
g_hash_table_add(priv->ports, ovs_port);
|
||||
_LOGT("obj[port:%s]: added a port: %s%s%s, external-ids=%s, other-config=%s",
|
||||
key,
|
||||
_LOGT("monitor: %s: port added: obj[port:%s]%s%s, external-ids=%s, other-config=%s",
|
||||
ovs_port->name,
|
||||
key,
|
||||
NM_PRINT_FMT_QUOTED2(ovs_port->connection_uuid,
|
||||
", ",
|
||||
", connection=",
|
||||
ovs_port->connection_uuid,
|
||||
""),
|
||||
(strtmp1 = _strdict_to_string(ovs_port->external_ids)),
|
||||
|
|
@ -2190,11 +2194,11 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg)
|
|||
&unused))
|
||||
continue;
|
||||
|
||||
_LOGT("obj[bridge:%s]: removed a bridge: %s%s%s",
|
||||
key,
|
||||
_LOGT("monitor: %s: bridge removed: obj[bridge:%s]%s%s",
|
||||
ovs_bridge->name,
|
||||
key,
|
||||
NM_PRINT_FMT_QUOTED2(ovs_bridge->connection_uuid,
|
||||
", ",
|
||||
", connection=",
|
||||
ovs_bridge->connection_uuid,
|
||||
""));
|
||||
_signal_emit_device_removed(self, ovs_bridge->name, NM_DEVICE_TYPE_OVS_BRIDGE, NULL);
|
||||
|
|
@ -2241,11 +2245,12 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg)
|
|||
gs_free char *strtmp1 = NULL;
|
||||
gs_free char *strtmp2 = NULL;
|
||||
|
||||
_LOGT("obj[bridge:%s]: changed a bridge: %s%s%s, external-ids=%s, other-config=%s",
|
||||
key,
|
||||
_LOGT("monitor: %s: bridge changed: obj[bridge:%s]%s%s, external-ids=%s, "
|
||||
"other-config=%s",
|
||||
ovs_bridge->name,
|
||||
key,
|
||||
NM_PRINT_FMT_QUOTED2(ovs_bridge->connection_uuid,
|
||||
", ",
|
||||
", connection=",
|
||||
ovs_bridge->connection_uuid,
|
||||
""),
|
||||
(strtmp1 = _strdict_to_string(ovs_bridge->external_ids)),
|
||||
|
|
@ -2265,11 +2270,11 @@ ovsdb_got_update(NMOvsdb *self, json_t *msg)
|
|||
.other_config = g_steal_pointer(&other_config_arr),
|
||||
};
|
||||
g_hash_table_add(priv->bridges, ovs_bridge);
|
||||
_LOGT("obj[bridge:%s]: added a bridge: %s%s%s, external-ids=%s, other-config=%s",
|
||||
key,
|
||||
_LOGT("monitor: %s: bridge added: obj[bridge:%s]%s%s, external-ids=%s, other-config=%s",
|
||||
ovs_bridge->name,
|
||||
key,
|
||||
NM_PRINT_FMT_QUOTED2(ovs_bridge->connection_uuid,
|
||||
", ",
|
||||
", connection=",
|
||||
ovs_bridge->connection_uuid,
|
||||
""),
|
||||
(strtmp1 = _strdict_to_string(ovs_bridge->external_ids)),
|
||||
|
|
|
|||
|
|
@ -191,6 +191,12 @@ static void supplicant_iface_notify_p2p_available(NMSupplicantInterface *iface,
|
|||
GParamSpec *pspec,
|
||||
NMDeviceWifi *self);
|
||||
|
||||
static void supplicant_iface_notify_wpa_psk_mismatch_cb(NMSupplicantInterface *iface,
|
||||
NMDeviceWifi *self);
|
||||
|
||||
static void supplicant_iface_notify_wpa_sae_mismatch_cb(NMSupplicantInterface *iface,
|
||||
NMDeviceWifi *self);
|
||||
|
||||
static void periodic_update(NMDeviceWifi *self);
|
||||
|
||||
static void ap_add_remove(NMDeviceWifi *self,
|
||||
|
|
@ -624,6 +630,14 @@ supplicant_interface_acquire_cb(NMSupplicantManager *supplicant_manager,
|
|||
"notify::" NM_SUPPLICANT_INTERFACE_P2P_AVAILABLE,
|
||||
G_CALLBACK(supplicant_iface_notify_p2p_available),
|
||||
self);
|
||||
g_signal_connect(priv->sup_iface,
|
||||
NM_SUPPLICANT_INTERFACE_PSK_MISMATCH,
|
||||
G_CALLBACK(supplicant_iface_notify_wpa_psk_mismatch_cb),
|
||||
self);
|
||||
g_signal_connect(priv->sup_iface,
|
||||
NM_SUPPLICANT_INTERFACE_SAE_MISMATCH,
|
||||
G_CALLBACK(supplicant_iface_notify_wpa_sae_mismatch_cb),
|
||||
self);
|
||||
|
||||
_scan_notify_is_scanning(self);
|
||||
|
||||
|
|
@ -2398,6 +2412,9 @@ handle_8021x_or_psk_auth_fail(NMDeviceWifi *self,
|
|||
|
||||
g_return_val_if_fail(new_state == NM_SUPPLICANT_INTERFACE_STATE_DISCONNECTED, FALSE);
|
||||
|
||||
if (nm_device_get_state(device) != NM_DEVICE_STATE_CONFIG)
|
||||
return FALSE;
|
||||
|
||||
req = nm_device_get_act_request(NM_DEVICE(self));
|
||||
g_return_val_if_fail(req != NULL, FALSE);
|
||||
|
||||
|
|
@ -2841,6 +2858,62 @@ handle_auth_or_fail(NMDeviceWifi *self, NMActRequest *req, gboolean new_secrets)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
supplicant_iface_notify_wpa_psk_mismatch_cb(NMSupplicantInterface *iface, NMDeviceWifi *self)
|
||||
{
|
||||
NMDevice *device = NM_DEVICE(self);
|
||||
NMActRequest *req;
|
||||
const char *setting_name = NM_SETTING_WIRELESS_SECURITY_SETTING_NAME;
|
||||
|
||||
if (nm_device_get_state(device) != NM_DEVICE_STATE_CONFIG)
|
||||
return;
|
||||
|
||||
_LOGI(LOGD_DEVICE | LOGD_WIFI,
|
||||
"Activation: (wifi) psk mismatch reported by supplicant, asking for new key");
|
||||
|
||||
req = nm_device_get_act_request(NM_DEVICE(self));
|
||||
g_return_if_fail(req != NULL);
|
||||
|
||||
nm_act_request_clear_secrets(req);
|
||||
|
||||
cleanup_association_attempt(self, TRUE);
|
||||
nm_device_state_changed(device,
|
||||
NM_DEVICE_STATE_NEED_AUTH,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT);
|
||||
wifi_secrets_get_secrets(self,
|
||||
setting_name,
|
||||
NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION
|
||||
| NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW);
|
||||
}
|
||||
|
||||
static void
|
||||
supplicant_iface_notify_wpa_sae_mismatch_cb(NMSupplicantInterface *iface, NMDeviceWifi *self)
|
||||
{
|
||||
NMDevice *device = NM_DEVICE(self);
|
||||
NMActRequest *req;
|
||||
const char *setting_name = NM_SETTING_WIRELESS_SECURITY_SETTING_NAME;
|
||||
|
||||
if (nm_device_get_state(device) != NM_DEVICE_STATE_CONFIG)
|
||||
return;
|
||||
|
||||
_LOGI(LOGD_DEVICE | LOGD_WIFI,
|
||||
"Activation: (wifi) SAE password mismatch reported by supplicant, asking for new key");
|
||||
|
||||
req = nm_device_get_act_request(NM_DEVICE(self));
|
||||
g_return_if_fail(req != NULL);
|
||||
|
||||
nm_act_request_clear_secrets(req);
|
||||
|
||||
cleanup_association_attempt(self, TRUE);
|
||||
nm_device_state_changed(device,
|
||||
NM_DEVICE_STATE_NEED_AUTH,
|
||||
NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT);
|
||||
wifi_secrets_get_secrets(self,
|
||||
setting_name,
|
||||
NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION
|
||||
| NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW);
|
||||
}
|
||||
|
||||
/*
|
||||
* supplicant_connection_timeout_cb
|
||||
*
|
||||
|
|
@ -2946,7 +3019,8 @@ build_supplicant_config(NMDeviceWifi *self,
|
|||
s_wireless = nm_connection_get_setting_wireless(connection);
|
||||
g_return_val_if_fail(s_wireless != NULL, NULL);
|
||||
|
||||
config = nm_supplicant_config_new(nm_supplicant_interface_get_capabilities(priv->sup_iface));
|
||||
config = nm_supplicant_config_new(nm_supplicant_interface_get_capabilities(priv->sup_iface),
|
||||
nm_utils_get_connection_first_permissions_user(connection));
|
||||
|
||||
/* Warn if AP mode may not be supported */
|
||||
if (nm_streq0(nm_setting_wireless_get_mode(s_wireless), NM_SETTING_WIRELESS_MODE_AP)
|
||||
|
|
@ -3022,6 +3096,7 @@ build_supplicant_config(NMDeviceWifi *self,
|
|||
mtu,
|
||||
pmf,
|
||||
fils,
|
||||
nm_device_get_private_files(NM_DEVICE(self)),
|
||||
error)) {
|
||||
g_prefix_error(error, "802-11-wireless-security: ");
|
||||
goto error;
|
||||
|
|
|
|||
|
|
@ -684,7 +684,7 @@ iwd_config_write(GKeyFile *config,
|
|||
* in the last few filename characters -- it cannot end in .open, .psk
|
||||
* or .8021x.
|
||||
*/
|
||||
return nm_utils_file_set_contents(filepath, data, length, 0600, times, NULL, error);
|
||||
return nm_utils_file_set_contents(filepath, data, length, 0600, times, NULL, NULL, error);
|
||||
}
|
||||
|
||||
static const char *
|
||||
|
|
|
|||
|
|
@ -508,8 +508,9 @@ find_gsm_apn_cb(const char *apn,
|
|||
static gboolean
|
||||
try_create_connect_properties(NMModemBroadband *self)
|
||||
{
|
||||
NMModemBroadbandPrivate *priv = NM_MODEM_BROADBAND_GET_PRIVATE(self);
|
||||
ConnectContext *ctx = priv->ctx;
|
||||
NMModemBroadbandPrivate *priv = NM_MODEM_BROADBAND_GET_PRIVATE(self);
|
||||
ConnectContext *ctx = priv->ctx;
|
||||
NMDeviceStateReason fail_reason = NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED;
|
||||
|
||||
if (MODEM_CAPS_3GPP(ctx->caps)) {
|
||||
NMSettingGsm *s_gsm = nm_connection_get_setting_gsm(ctx->connection);
|
||||
|
|
@ -522,7 +523,7 @@ try_create_connect_properties(NMModemBroadband *self)
|
|||
if (s_gsm)
|
||||
network_id = nm_setting_gsm_get_network_id(s_gsm);
|
||||
if (!network_id) {
|
||||
if (mm_modem_get_state(self->_priv.modem_iface) < MM_MODEM_STATE_REGISTERED)
|
||||
if (mm_modem_get_state(self->_priv.modem_iface) != MM_MODEM_STATE_REGISTERED)
|
||||
return FALSE;
|
||||
modem_3gpp = mm_object_get_modem_3gpp(priv->modem_object);
|
||||
network_id = mm_modem_3gpp_get_operator_code(modem_3gpp);
|
||||
|
|
@ -530,6 +531,7 @@ try_create_connect_properties(NMModemBroadband *self)
|
|||
if (!network_id) {
|
||||
_LOGW("failed to connect '%s': unable to determine the network id",
|
||||
nm_connection_get_id(ctx->connection));
|
||||
fail_reason = NM_DEVICE_STATE_REASON_MODEM_NO_OPERATOR_CODE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
|
@ -558,7 +560,7 @@ try_create_connect_properties(NMModemBroadband *self)
|
|||
}
|
||||
|
||||
out:
|
||||
nm_modem_emit_prepare_result(NM_MODEM(self), FALSE, NM_DEVICE_STATE_REASON_MODEM_INIT_FAILED);
|
||||
nm_modem_emit_prepare_result(NM_MODEM(self), FALSE, fail_reason);
|
||||
connect_context_clear(self);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -1649,6 +1651,8 @@ nm_modem_broadband_new(GObject *object, GError **error)
|
|||
driver,
|
||||
NM_MODEM_OPERATOR_CODE,
|
||||
operator_code,
|
||||
NM_MODEM_DEVICE_UID,
|
||||
mm_modem_get_device(modem_iface),
|
||||
NULL);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,8 @@ NM_GOBJECT_PROPERTIES_DEFINE(NMModem,
|
|||
PROP_IP_TYPES,
|
||||
PROP_SIM_OPERATOR_ID,
|
||||
PROP_OPERATOR_CODE,
|
||||
PROP_APN, );
|
||||
PROP_APN,
|
||||
PROP_DEVICE_UID, );
|
||||
|
||||
enum {
|
||||
PPP_STATS,
|
||||
|
|
@ -78,6 +79,7 @@ typedef struct _NMModemPrivate {
|
|||
char *sim_operator_id;
|
||||
char *operator_code;
|
||||
char *apn;
|
||||
char *device_uid;
|
||||
|
||||
NMPPPManager *ppp_manager;
|
||||
NMPppMgr *ppp_mgr;
|
||||
|
|
@ -618,6 +620,12 @@ nm_modem_get_apn(NMModem *self)
|
|||
return NM_MODEM_GET_PRIVATE(self)->apn;
|
||||
}
|
||||
|
||||
const char *
|
||||
nm_modem_get_device_uid(NMModem *self)
|
||||
{
|
||||
return NM_MODEM_GET_PRIVATE(self)->device_uid;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
|
|
@ -1121,6 +1129,22 @@ nm_modem_check_connection_compatible(NMModem *self, NMConnection *connection, GE
|
|||
}
|
||||
}
|
||||
|
||||
str = nm_setting_gsm_get_device_uid(s_gsm);
|
||||
if (str) {
|
||||
if (!priv->device_uid) {
|
||||
nm_utils_error_set_literal(error,
|
||||
NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
|
||||
"GSM profile has device-uid, device does not");
|
||||
return FALSE;
|
||||
}
|
||||
if (!nm_streq(str, priv->device_uid)) {
|
||||
nm_utils_error_set_literal(error,
|
||||
NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
|
||||
"device has differing device-uid than GSM profile");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* SIM properties may not be available before the SIM is unlocked, so
|
||||
* to ensure that autoconnect works, the connection's SIM properties
|
||||
* are only compared if present on the device.
|
||||
|
|
@ -1644,6 +1668,9 @@ get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
|
|||
case PROP_APN:
|
||||
g_value_set_string(value, priv->apn);
|
||||
break;
|
||||
case PROP_DEVICE_UID:
|
||||
g_value_set_string(value, priv->device_uid);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
|
|
@ -1699,6 +1726,10 @@ set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *ps
|
|||
/* construct-only */
|
||||
priv->operator_code = g_value_dup_string(value);
|
||||
break;
|
||||
case PROP_DEVICE_UID:
|
||||
/* construct-only */
|
||||
priv->device_uid = g_value_dup_string(value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
|
||||
break;
|
||||
|
|
@ -1758,6 +1789,7 @@ finalize(GObject *object)
|
|||
g_free(priv->sim_operator_id);
|
||||
g_free(priv->operator_code);
|
||||
g_free(priv->apn);
|
||||
g_free(priv->device_uid);
|
||||
|
||||
G_OBJECT_CLASS(nm_modem_parent_class)->finalize(object);
|
||||
}
|
||||
|
|
@ -1863,6 +1895,13 @@ nm_modem_class_init(NMModemClass *klass)
|
|||
obj_properties[PROP_APN] =
|
||||
g_param_spec_string(NM_MODEM_APN, "", "", NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
obj_properties[PROP_DEVICE_UID] =
|
||||
g_param_spec_string(NM_MODEM_DEVICE_UID,
|
||||
"",
|
||||
"",
|
||||
NULL,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
|
||||
|
||||
g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties);
|
||||
|
||||
signals[PPP_STATS] = g_signal_new(NM_MODEM_PPP_STATS,
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#define NM_MODEM_SIM_OPERATOR_ID "sim-operator-id"
|
||||
#define NM_MODEM_OPERATOR_CODE "operator-code"
|
||||
#define NM_MODEM_APN "apn"
|
||||
#define NM_MODEM_DEVICE_UID "device-uid"
|
||||
|
||||
/* Signals */
|
||||
#define NM_MODEM_PPP_STATS "ppp-stats"
|
||||
|
|
@ -154,6 +155,7 @@ const char *nm_modem_get_sim_id(NMModem *modem);
|
|||
const char *nm_modem_get_sim_operator_id(NMModem *modem);
|
||||
const char *nm_modem_get_operator_code(NMModem *modem);
|
||||
const char *nm_modem_get_apn(NMModem *modem);
|
||||
const char *nm_modem_get_device_uid(NMModem *modem);
|
||||
|
||||
gboolean nm_modem_set_data_port(NMModem *self,
|
||||
NMPlatform *platform,
|
||||
|
|
|
|||
|
|
@ -32,11 +32,11 @@ ip4_process_dhcpcd_rfc3442_routes(const char *iface,
|
|||
in_addr_t address,
|
||||
guint32 *out_gwaddr)
|
||||
{
|
||||
gs_free const char **routes = NULL;
|
||||
const char **r;
|
||||
gboolean have_routes = FALSE;
|
||||
gs_free char **routes = NULL;
|
||||
char **r;
|
||||
gboolean have_routes = FALSE;
|
||||
|
||||
routes = nm_strsplit_set(str, " ");
|
||||
routes = (char **) nm_strsplit_set(str, " ");
|
||||
if (!routes)
|
||||
return FALSE;
|
||||
|
||||
|
|
|
|||
|
|
@ -521,9 +521,10 @@ _gl_pid_spawn_next_step(void)
|
|||
argv[argv_idx++] = "--no-resolv"; /* Use only commandline */
|
||||
argv[argv_idx++] = "--keep-in-foreground";
|
||||
argv[argv_idx++] = "--no-hosts"; /* don't use /etc/hosts to resolve */
|
||||
argv[argv_idx++] = "--bind-interfaces";
|
||||
argv[argv_idx++] = "--bind-dynamic";
|
||||
argv[argv_idx++] = "--pid-file=" PIDFILE;
|
||||
argv[argv_idx++] = "--listen-address=127.0.0.1"; /* Should work for both 4 and 6 */
|
||||
argv[argv_idx++] = "--listen-address=127.0.0.1";
|
||||
argv[argv_idx++] = "--listen-address=::1";
|
||||
argv[argv_idx++] = "--cache-size=400";
|
||||
argv[argv_idx++] = "--clear-on-reload"; /* clear cache when dns server changes */
|
||||
argv[argv_idx++] = "--conf-file=/dev/null"; /* avoid loading /etc/dnsmasq.conf */
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include "libnm-core-intern/nm-core-internal.h"
|
||||
#include "libnm-glib-aux/nm-str-buf.h"
|
||||
#include "libnm-glib-aux/nm-io-utils.h"
|
||||
|
||||
#include "NetworkManagerUtils.h"
|
||||
#include "devices/nm-device.h"
|
||||
|
|
@ -1006,7 +1007,8 @@ _read_link_cached(const char *path, gboolean *is_cached, char **cached)
|
|||
#define MY_RESOLV_CONF_TMP MY_RESOLV_CONF ".tmp"
|
||||
#define RESOLV_CONF_TMP "/etc/.resolv.conf.NetworkManager"
|
||||
|
||||
#define NO_STUB_RESOLV_CONF NMRUNDIR "/no-stub-resolv.conf"
|
||||
#define NO_STUB_RESOLV_CONF NMRUNDIR "/no-stub-resolv.conf"
|
||||
#define NO_STUB_RESOLV_CONF_TMP NMRUNDIR "/no-stub-resolv.conf.tmp"
|
||||
|
||||
static void
|
||||
update_resolv_conf_no_stub(NMDnsManager *self,
|
||||
|
|
@ -1019,7 +1021,14 @@ update_resolv_conf_no_stub(NMDnsManager *self,
|
|||
|
||||
content = create_resolv_conf(searches, nameservers, options);
|
||||
|
||||
if (!g_file_set_contents(NO_STUB_RESOLV_CONF, content, -1, &local)) {
|
||||
if (!nm_utils_file_set_contents(NO_STUB_RESOLV_CONF,
|
||||
content,
|
||||
-1,
|
||||
0644,
|
||||
NULL,
|
||||
NO_STUB_RESOLV_CONF_TMP,
|
||||
NULL,
|
||||
&local)) {
|
||||
_LOGD("update-resolv-no-stub: failure to write file: %s", local->message);
|
||||
g_error_free(local);
|
||||
return;
|
||||
|
|
@ -1501,8 +1510,8 @@ _domain_track_is_shadowed(GHashTable *ht,
|
|||
const char **out_parent,
|
||||
int *out_parent_priority)
|
||||
{
|
||||
char *parent;
|
||||
int parent_priority;
|
||||
const char *parent;
|
||||
int parent_priority;
|
||||
|
||||
if (!ht)
|
||||
return FALSE;
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
static const char *const DBUS_OP_SET_LINK_DEFAULT_ROUTE = "SetLinkDefaultRoute";
|
||||
static const char *const DBUS_OP_SET_LINK_DNS_OVER_TLS = "SetLinkDNSOverTLS";
|
||||
static const char *const DBUS_OP_SET_LINK_DNS_EX = "SetLinkDNSEx";
|
||||
static const char *const DBUS_OP_SET_LINK_DNSSEC = "SetLinkDNSSEC";
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -484,9 +485,11 @@ prepare_one_interface(NMDnsSystemdResolved *self, const InterfaceConfig *ic)
|
|||
NMSettingConnectionMdns mdns = NM_SETTING_CONNECTION_MDNS_DEFAULT;
|
||||
NMSettingConnectionLlmnr llmnr = NM_SETTING_CONNECTION_LLMNR_DEFAULT;
|
||||
NMSettingConnectionDnsOverTls dns_over_tls = NM_SETTING_CONNECTION_DNS_OVER_TLS_DEFAULT;
|
||||
NMSettingConnectionDnssec dnssec = NM_SETTING_CONNECTION_DNSSEC_DEFAULT;
|
||||
const char *mdns_arg = NULL;
|
||||
const char *llmnr_arg = NULL;
|
||||
const char *dns_over_tls_arg = NULL;
|
||||
const char *dnssec_arg = NULL;
|
||||
gboolean has_config = FALSE;
|
||||
gboolean has_default_route = FALSE;
|
||||
guint i;
|
||||
|
|
@ -517,6 +520,7 @@ prepare_one_interface(NMDnsSystemdResolved *self, const InterfaceConfig *ic)
|
|||
llmnr = NM_MAX(llmnr, nm_l3_config_data_get_llmnr(ip_data->l3cd));
|
||||
dns_over_tls =
|
||||
NM_MAX(dns_over_tls, nm_l3_config_data_get_dns_over_tls(ip_data->l3cd));
|
||||
dnssec = NM_MAX(dnssec, nm_l3_config_data_get_dnssec(ip_data->l3cd));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -589,8 +593,24 @@ prepare_one_interface(NMDnsSystemdResolved *self, const InterfaceConfig *ic)
|
|||
}
|
||||
nm_assert(dns_over_tls_arg);
|
||||
|
||||
switch (dnssec) {
|
||||
case NM_SETTING_CONNECTION_DNSSEC_NO:
|
||||
dnssec_arg = "no";
|
||||
break;
|
||||
case NM_SETTING_CONNECTION_DNSSEC_ALLOW_DOWNGRADE:
|
||||
dnssec_arg = "allow-downgrade";
|
||||
break;
|
||||
case NM_SETTING_CONNECTION_DNSSEC_YES:
|
||||
dnssec_arg = "yes";
|
||||
break;
|
||||
case NM_SETTING_CONNECTION_DNSSEC_DEFAULT:
|
||||
dnssec_arg = "";
|
||||
break;
|
||||
}
|
||||
nm_assert(dnssec_arg);
|
||||
|
||||
if (!nm_str_is_empty(mdns_arg) || !nm_str_is_empty(llmnr_arg)
|
||||
|| !nm_str_is_empty(dns_over_tls_arg))
|
||||
|| !nm_str_is_empty(dns_over_tls_arg) || !nm_str_is_empty(dnssec_arg))
|
||||
has_config = TRUE;
|
||||
|
||||
_request_item_append(self, "SetLinkDomains", ic->ifindex, g_variant_builder_end(&domains));
|
||||
|
|
@ -618,6 +638,10 @@ prepare_one_interface(NMDnsSystemdResolved *self, const InterfaceConfig *ic)
|
|||
DBUS_OP_SET_LINK_DNS_OVER_TLS,
|
||||
ic->ifindex,
|
||||
g_variant_new("(is)", ic->ifindex, dns_over_tls_arg ?: ""));
|
||||
_request_item_append(self,
|
||||
DBUS_OP_SET_LINK_DNSSEC,
|
||||
ic->ifindex,
|
||||
g_variant_new("(is)", ic->ifindex, dnssec_arg ?: ""));
|
||||
|
||||
return has_config;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ nm_main_utils_write_pidfile(const char *pidfile)
|
|||
char pid[16];
|
||||
|
||||
nm_sprintf_buf(pid, "%lld", (long long) getpid());
|
||||
if (!nm_utils_file_set_contents(pidfile, pid, -1, 00644, NULL, NULL, &error)) {
|
||||
if (!nm_utils_file_set_contents(pidfile, pid, -1, 00644, NULL, NULL, NULL, &error)) {
|
||||
fprintf(stderr, _("Writing to %s failed: %s\n"), pidfile, error->message);
|
||||
return FALSE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
#include "libnm-systemd-shared/nm-sd-utils-shared.h"
|
||||
#include "nm-l3cfg.h"
|
||||
#include "nm-ndisc-private.h"
|
||||
#include "nm-core-utils.h"
|
||||
|
||||
#define _NMLOG_PREFIX_NAME "ndisc-lndp"
|
||||
|
||||
|
|
@ -27,6 +28,14 @@
|
|||
typedef struct {
|
||||
struct ndp *ndp;
|
||||
GSource *event_source;
|
||||
|
||||
struct {
|
||||
NMRateLimit pio_lft;
|
||||
NMRateLimit mtu;
|
||||
NMRateLimit omit_prefix;
|
||||
NMRateLimit omit_dns;
|
||||
NMRateLimit omit_dnssl;
|
||||
} msg_ratelimit;
|
||||
} NMLndpNDiscPrivate;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -49,6 +58,36 @@ G_DEFINE_TYPE(NMLndpNDisc, nm_lndp_ndisc, NM_TYPE_NDISC)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/*
|
||||
* If we log a message about an invalid RA packet, don't repeat the same message
|
||||
* at every packet received or sent. Rate limit the message to 6 every 12 hours
|
||||
* per type and per ndisc instance.
|
||||
*/
|
||||
|
||||
#define LOG_INV_RA_WINDOW (12 * 3600)
|
||||
#define LOG_INV_RA_BURST 6
|
||||
|
||||
#define _LOG_INVALID_RA(ndisc, rate_limit, ...) \
|
||||
G_STMT_START \
|
||||
{ \
|
||||
NMNDisc *__ndisc = (ndisc); \
|
||||
NMRateLimit *__rl = (rate_limit); \
|
||||
const char *__ifname = nm_ndisc_get_ifname(__ndisc); \
|
||||
\
|
||||
if (__ifname && nm_logging_enabled(LOGL_WARN, LOGD_IP6) \
|
||||
&& nm_rate_limit_check(__rl, LOG_INV_RA_WINDOW, LOG_INV_RA_BURST)) { \
|
||||
nm_log(LOGL_WARN, \
|
||||
LOGD_IP6, \
|
||||
__ifname, \
|
||||
NULL, \
|
||||
"ndisc (%s): " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \
|
||||
__ifname _NM_UTILS_MACRO_REST(__VA_ARGS__)); \
|
||||
} \
|
||||
} \
|
||||
G_STMT_END
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static gboolean
|
||||
send_rs(NMNDisc *ndisc, GError **error)
|
||||
{
|
||||
|
|
@ -113,6 +152,7 @@ static int
|
|||
receive_ra(struct ndp *ndp, struct ndp_msg *msg, gpointer user_data)
|
||||
{
|
||||
NMNDisc *ndisc = (NMNDisc *) user_data;
|
||||
NMLndpNDiscPrivate *priv = NM_LNDP_NDISC_GET_PRIVATE(ndisc);
|
||||
NMNDiscDataInternal *rdata = ndisc->rdata;
|
||||
NMNDiscConfigMap changed = 0;
|
||||
NMNDiscGateway gateway;
|
||||
|
|
@ -229,7 +269,11 @@ receive_ra(struct ndp *ndp, struct ndp_msg *msg, gpointer user_data)
|
|||
* log a system management error in this case.
|
||||
*/
|
||||
if (preferred_time > valid_time) {
|
||||
_LOGW("skipping PIO - preferred lifetime > valid lifetime");
|
||||
_LOG_INVALID_RA(
|
||||
ndisc,
|
||||
&priv->msg_ratelimit.pio_lft,
|
||||
"ignoring Prefix Information Option with invalid lifetimes in received IPv6 "
|
||||
"router advertisement");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -349,7 +393,11 @@ receive_ra(struct ndp *ndp, struct ndp_msg *msg, gpointer user_data)
|
|||
* Kernel would set it, but would flush out all IPv6 addresses away
|
||||
* from the link, even the link-local, and we wouldn't be able to
|
||||
* listen for further RAs that could fix the MTU. */
|
||||
_LOGW("MTU too small for IPv6 ignored: %d", mtu);
|
||||
_LOG_INVALID_RA(ndisc,
|
||||
&priv->msg_ratelimit.mtu,
|
||||
"ignoring too small MTU %u in received IPv6 "
|
||||
"router advertisement",
|
||||
mtu);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -445,8 +493,11 @@ send_ra(NMNDisc *ndisc, GError **error)
|
|||
|
||||
prefix = _ndp_msg_add_option(msg, sizeof(*prefix));
|
||||
if (!prefix) {
|
||||
/* Maybe we could sent separate RAs, but why bother... */
|
||||
_LOGW("The RA is too big, had to omit some some prefixes.");
|
||||
/* Maybe we could send separate RAs, but why bother... */
|
||||
_LOG_INVALID_RA(
|
||||
ndisc,
|
||||
&priv->msg_ratelimit.omit_prefix,
|
||||
"the outgoing IPv6 router advertisement is too big: omitting some prefixes");
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -475,7 +526,10 @@ send_ra(NMNDisc *ndisc, GError **error)
|
|||
|
||||
option = _ndp_msg_add_option(msg, len);
|
||||
if (!option) {
|
||||
_LOGW("The RA is too big, had to omit DNS information.");
|
||||
_LOG_INVALID_RA(
|
||||
ndisc,
|
||||
&priv->msg_ratelimit.omit_dns,
|
||||
"the outgoing IPv6 router advertisement is too big: omitting DNS information");
|
||||
goto dns_servers_done;
|
||||
}
|
||||
|
||||
|
|
@ -553,7 +607,10 @@ dns_servers_done:
|
|||
nm_assert(len / 8u >= 2u);
|
||||
|
||||
if (len / 8u >= 256u || !(option = _ndp_msg_add_option(msg, len))) {
|
||||
_LOGW("The RA is too big, had to omit DNS search list.");
|
||||
_LOG_INVALID_RA(
|
||||
ndisc,
|
||||
&priv->msg_ratelimit.omit_dnssl,
|
||||
"the outgoing IPv6 router advertisement is too big: omitting DNS search list");
|
||||
goto dns_domains_done;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ parse_connection_from_shadowed_file(const char *path, GError **error)
|
|||
{
|
||||
nm_auto_unref_keyfile GKeyFile *keyfile = NULL;
|
||||
gs_free char *base_dir = NULL;
|
||||
char *sep;
|
||||
const char *sep;
|
||||
|
||||
keyfile = g_key_file_new();
|
||||
if (!g_key_file_load_from_file(keyfile, path, G_KEY_FILE_NONE, error))
|
||||
|
|
|
|||
|
|
@ -892,6 +892,7 @@ static const ConfigGroup config_groups[] = {
|
|||
.is_prefix = TRUE,
|
||||
.keys = NM_MAKE_STRV(NM_CONFIG_KEYFILE_KEY_DEVICE_CARRIER_WAIT_TIMEOUT,
|
||||
NM_CONFIG_KEYFILE_KEY_DEVICE_IGNORE_CARRIER,
|
||||
NM_CONFIG_KEYFILE_KEY_DEVICE_CHECK_CONNECTIVITY,
|
||||
NM_CONFIG_KEYFILE_KEY_DEVICE_MANAGED,
|
||||
NM_CONFIG_KEYFILE_KEY_DEVICE_SRIOV_NUM_VFS,
|
||||
NM_CONFIG_KEYFILE_KEY_DEVICE_KEEP_CONFIGURATION,
|
||||
|
|
|
|||
|
|
@ -77,6 +77,8 @@ struct _NMConnectivityCheckHandle {
|
|||
ConConfig *con_config;
|
||||
|
||||
GCancellable *resolve_cancellable;
|
||||
int resolve_ifindex;
|
||||
GDBusConnection *dbus_connection;
|
||||
CURLM *curl_mhandle;
|
||||
CURL *curl_ehandle;
|
||||
struct curl_slist *request_headers;
|
||||
|
|
@ -953,6 +955,113 @@ systemd_resolved_resolve_cb(GObject *object, GAsyncResult *res, gpointer user_da
|
|||
do_curl_request(cb_data, nm_str_buf_get_str(&strbuf_hosts));
|
||||
}
|
||||
|
||||
static void
|
||||
systemd_resolved_resolve(NMConnectivityCheckHandle *cb_data)
|
||||
{
|
||||
_LOG2D("start request to '%s' (try resolving '%s' using systemd-resolved with ifindex %d)",
|
||||
cb_data->concheck.con_config->uri,
|
||||
cb_data->concheck.con_config->host,
|
||||
cb_data->concheck.resolve_ifindex);
|
||||
|
||||
g_dbus_connection_call(cb_data->concheck.dbus_connection,
|
||||
"org.freedesktop.resolve1",
|
||||
"/org/freedesktop/resolve1",
|
||||
"org.freedesktop.resolve1.Manager",
|
||||
"ResolveHostname",
|
||||
g_variant_new("(isit)",
|
||||
(gint32) cb_data->concheck.resolve_ifindex,
|
||||
cb_data->concheck.con_config->host,
|
||||
(gint32) cb_data->addr_family,
|
||||
SD_RESOLVED_DNS),
|
||||
G_VARIANT_TYPE("(a(iiay)st)"),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
cb_data->concheck.resolve_cancellable,
|
||||
systemd_resolved_resolve_cb,
|
||||
cb_data);
|
||||
}
|
||||
|
||||
static void
|
||||
systemd_resolved_link_scopes_cb(GObject *object, GAsyncResult *res, gpointer user_data)
|
||||
{
|
||||
NMConnectivityCheckHandle *cb_data;
|
||||
gs_unref_variant GVariant *result = NULL;
|
||||
gs_unref_variant GVariant *value = NULL;
|
||||
gs_free_error GError *error = NULL;
|
||||
guint64 scope_mask = 0;
|
||||
|
||||
result = g_dbus_connection_call_finish(G_DBUS_CONNECTION(object), res, &error);
|
||||
if (nm_utils_error_is_cancelled(error))
|
||||
return;
|
||||
|
||||
cb_data = user_data;
|
||||
|
||||
if (!result) {
|
||||
_LOG2D("unable to obtain systemd-resolved link ScopesMask for interface %d: %s",
|
||||
cb_data->concheck.resolve_ifindex,
|
||||
error->message);
|
||||
|
||||
cb_data->concheck.resolve_ifindex = 0;
|
||||
systemd_resolved_resolve(cb_data);
|
||||
return;
|
||||
}
|
||||
|
||||
g_variant_get(result, "(v)", &value);
|
||||
g_variant_get(value, "t", &scope_mask);
|
||||
|
||||
if (!(scope_mask & SD_RESOLVED_DNS)) {
|
||||
/* there is no per-link DNS configured / active; query all available /
|
||||
* system DNS resolvers instead of restricting the lookup to just this
|
||||
* one, which would turn up no results. */
|
||||
_LOG2D("no per-link DNS available (scope mask %" G_GUINT64_FORMAT
|
||||
"); falling back to system-wide lookups",
|
||||
scope_mask);
|
||||
cb_data->concheck.resolve_ifindex = 0;
|
||||
}
|
||||
|
||||
systemd_resolved_resolve(cb_data);
|
||||
}
|
||||
|
||||
static void
|
||||
systemd_resolved_get_link_cb(GObject *object, GAsyncResult *res, gpointer user_data)
|
||||
{
|
||||
NMConnectivityCheckHandle *cb_data;
|
||||
gs_unref_variant GVariant *result = NULL;
|
||||
gs_free char *link_path = NULL;
|
||||
gs_free_error GError *error = NULL;
|
||||
|
||||
result = g_dbus_connection_call_finish(G_DBUS_CONNECTION(object), res, &error);
|
||||
if (nm_utils_error_is_cancelled(error))
|
||||
return;
|
||||
|
||||
cb_data = user_data;
|
||||
|
||||
if (!result) {
|
||||
_LOG2D("unable to obtain systemd-resolved link D-Bus object for interface %d: %s",
|
||||
cb_data->concheck.resolve_ifindex,
|
||||
error->message);
|
||||
|
||||
cb_data->concheck.resolve_ifindex = 0;
|
||||
systemd_resolved_resolve(cb_data);
|
||||
return;
|
||||
}
|
||||
|
||||
g_variant_get(result, "(o)", &link_path);
|
||||
|
||||
g_dbus_connection_call(cb_data->concheck.dbus_connection,
|
||||
"org.freedesktop.resolve1",
|
||||
link_path,
|
||||
"org.freedesktop.DBus.Properties",
|
||||
"Get",
|
||||
g_variant_new("(ss)", "org.freedesktop.resolve1.Link", "ScopesMask"),
|
||||
G_VARIANT_TYPE("(v)"),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
cb_data->concheck.resolve_cancellable,
|
||||
systemd_resolved_link_scopes_cb,
|
||||
cb_data);
|
||||
}
|
||||
|
||||
static NMConnectivityState
|
||||
check_platform_config(NMConnectivity *self,
|
||||
NMPlatform *platform,
|
||||
|
|
@ -1067,6 +1176,7 @@ nm_connectivity_check_start(NMConnectivity *self,
|
|||
}
|
||||
|
||||
cb_data->concheck.resolve_cancellable = g_cancellable_new();
|
||||
cb_data->concheck.resolve_ifindex = ifindex;
|
||||
|
||||
/* note that we pick up support for systemd-resolved right away when we need it.
|
||||
* We don't need to remember the setting, because we can (cheaply) check anew
|
||||
|
|
@ -1089,10 +1199,8 @@ nm_connectivity_check_start(NMConnectivity *self,
|
|||
has_systemd_resolved = !!nm_dns_manager_get_systemd_resolved(nm_dns_manager_get());
|
||||
|
||||
if (has_systemd_resolved) {
|
||||
GDBusConnection *dbus_connection;
|
||||
|
||||
dbus_connection = NM_MAIN_DBUS_CONNECTION_GET;
|
||||
if (!dbus_connection) {
|
||||
cb_data->concheck.dbus_connection = NM_MAIN_DBUS_CONNECTION_GET;
|
||||
if (!cb_data->concheck.dbus_connection) {
|
||||
/* we have no D-Bus connection? That might happen in configure and quit mode.
|
||||
*
|
||||
* Anyway, something is very odd, just fail connectivity check. */
|
||||
|
|
@ -1103,25 +1211,19 @@ nm_connectivity_check_start(NMConnectivity *self,
|
|||
return cb_data;
|
||||
}
|
||||
|
||||
g_dbus_connection_call(dbus_connection,
|
||||
/* first check whether there has been a per-link DNS configured */
|
||||
g_dbus_connection_call(cb_data->concheck.dbus_connection,
|
||||
"org.freedesktop.resolve1",
|
||||
"/org/freedesktop/resolve1",
|
||||
"org.freedesktop.resolve1.Manager",
|
||||
"ResolveHostname",
|
||||
g_variant_new("(isit)",
|
||||
0,
|
||||
cb_data->concheck.con_config->host,
|
||||
(gint32) cb_data->addr_family,
|
||||
SD_RESOLVED_DNS),
|
||||
G_VARIANT_TYPE("(a(iiay)st)"),
|
||||
"GetLink",
|
||||
g_variant_new("(i)", ifindex),
|
||||
G_VARIANT_TYPE("(o)"),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
-1,
|
||||
cb_data->concheck.resolve_cancellable,
|
||||
systemd_resolved_resolve_cb,
|
||||
systemd_resolved_get_link_cb,
|
||||
cb_data);
|
||||
_LOG2D("start request to '%s' (try resolving '%s' using systemd-resolved)",
|
||||
cb_data->concheck.con_config->uri,
|
||||
cb_data->concheck.con_config->host);
|
||||
return cb_data;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2865,6 +2865,7 @@ _host_id_read(guint8 **out_host_id, gsize *out_host_id_len)
|
|||
0600,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&error)) {
|
||||
nm_log_warn(
|
||||
LOGD_CORE,
|
||||
|
|
@ -5011,6 +5012,7 @@ typedef struct {
|
|||
int child_stdin;
|
||||
int child_stdout;
|
||||
int child_stderr;
|
||||
gboolean binary_output;
|
||||
GSource *input_source;
|
||||
GSource *output_source;
|
||||
GSource *error_source;
|
||||
|
|
@ -5090,9 +5092,17 @@ helper_complete(HelperInfo *info, GError *error)
|
|||
}
|
||||
|
||||
nm_clear_g_cancellable_disconnect(g_task_get_cancellable(info->task), &info->cancellable_id);
|
||||
g_task_return_pointer(info->task,
|
||||
nm_str_buf_finalize(&info->in_buffer, NULL) ?: g_new0(char, 1),
|
||||
g_free);
|
||||
|
||||
if (info->binary_output) {
|
||||
g_task_return_pointer(
|
||||
info->task,
|
||||
g_bytes_new(nm_str_buf_get_str_unsafe(&info->in_buffer), info->in_buffer.len),
|
||||
(GDestroyNotify) (g_bytes_unref));
|
||||
} else {
|
||||
g_task_return_pointer(info->task,
|
||||
nm_str_buf_finalize(&info->in_buffer, NULL) ?: g_new0(char, 1),
|
||||
g_free);
|
||||
}
|
||||
helper_info_free(info);
|
||||
}
|
||||
|
||||
|
|
@ -5235,6 +5245,7 @@ helper_cancelled(GObject *object, gpointer user_data)
|
|||
|
||||
void
|
||||
nm_utils_spawn_helper(const char *const *args,
|
||||
gboolean binary_output,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer cb_data)
|
||||
|
|
@ -5250,9 +5261,14 @@ nm_utils_spawn_helper(const char *const *args,
|
|||
|
||||
info = g_new(HelperInfo, 1);
|
||||
*info = (HelperInfo) {
|
||||
.task = nm_g_task_new(NULL, cancellable, nm_utils_spawn_helper, callback, cb_data),
|
||||
.task = nm_g_task_new(NULL, cancellable, nm_utils_spawn_helper, callback, cb_data),
|
||||
.binary_output = binary_output,
|
||||
};
|
||||
|
||||
/* Store if the caller requested binary output so that we can check later
|
||||
* that the right result function is called. */
|
||||
g_task_set_task_data(info->task, GINT_TO_POINTER(binary_output), NULL);
|
||||
|
||||
if (!g_spawn_async_with_pipes("/",
|
||||
(char **) NM_MAKE_STRV(LIBEXECDIR "/nm-daemon-helper"),
|
||||
(char **) NM_MAKE_STRV(),
|
||||
|
|
@ -5363,11 +5379,25 @@ nm_utils_spawn_helper(const char *const *args,
|
|||
}
|
||||
|
||||
char *
|
||||
nm_utils_spawn_helper_finish(GAsyncResult *result, GError **error)
|
||||
nm_utils_spawn_helper_finish_string(GAsyncResult *result, GError **error)
|
||||
{
|
||||
GTask *task = G_TASK(result);
|
||||
|
||||
nm_assert(nm_g_task_is_valid(result, NULL, nm_utils_spawn_helper));
|
||||
/* Check binary_output */
|
||||
nm_assert(GPOINTER_TO_INT(g_task_get_task_data(task)) == FALSE);
|
||||
|
||||
return g_task_propagate_pointer(task, error);
|
||||
}
|
||||
|
||||
GBytes *
|
||||
nm_utils_spawn_helper_finish_binary(GAsyncResult *result, GError **error)
|
||||
{
|
||||
GTask *task = G_TASK(result);
|
||||
|
||||
nm_assert(nm_g_task_is_valid(result, NULL, nm_utils_spawn_helper));
|
||||
/* Check binary_output */
|
||||
nm_assert(GPOINTER_TO_INT(g_task_get_task_data(task)) == TRUE);
|
||||
|
||||
return g_task_propagate_pointer(task, error);
|
||||
}
|
||||
|
|
@ -5474,3 +5504,334 @@ nm_utils_shorten_hostname(const char *hostname, char **shortened)
|
|||
*shortened = g_steal_pointer(&s);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_utils_connection_supported:
|
||||
* @connection: the connection
|
||||
* @error: on return, the reason why the connection in not supported
|
||||
*
|
||||
* Returns whether the given connection is supported by this version
|
||||
* of NetworkManager.
|
||||
*/
|
||||
gboolean
|
||||
nm_utils_connection_supported(NMConnection *connection, GError **error)
|
||||
{
|
||||
const char *type;
|
||||
const char *feature = NULL;
|
||||
|
||||
g_return_val_if_fail(connection, FALSE);
|
||||
g_return_val_if_fail(!error || !*error, FALSE);
|
||||
|
||||
type = nm_connection_get_connection_type(connection);
|
||||
|
||||
if (!WITH_TEAMDCTL) {
|
||||
NMSettingConnection *s_con;
|
||||
|
||||
if (nm_streq0(type, NM_SETTING_TEAM_SETTING_NAME)) {
|
||||
feature = "team";
|
||||
goto out_disabled;
|
||||
}
|
||||
|
||||
/* Match team ports */
|
||||
if ((s_con = nm_connection_get_setting_connection(connection))
|
||||
&& nm_streq0(nm_setting_connection_get_port_type(s_con),
|
||||
NM_SETTING_TEAM_SETTING_NAME)) {
|
||||
feature = "team";
|
||||
goto out_disabled;
|
||||
}
|
||||
}
|
||||
|
||||
if (!WITH_OPENVSWITCH) {
|
||||
if (NM_IN_STRSET(type,
|
||||
NM_SETTING_OVS_BRIDGE_SETTING_NAME,
|
||||
NM_SETTING_OVS_PORT_SETTING_NAME,
|
||||
NM_SETTING_OVS_INTERFACE_SETTING_NAME)) {
|
||||
feature = "Open vSwitch";
|
||||
goto out_disabled;
|
||||
}
|
||||
|
||||
/* Match OVS system interfaces */
|
||||
if (nm_connection_get_setting_ovs_interface(connection)) {
|
||||
feature = "Open vSwitch";
|
||||
goto out_disabled;
|
||||
}
|
||||
}
|
||||
|
||||
if (!WITH_WIFI
|
||||
&& NM_IN_STRSET(type,
|
||||
NM_SETTING_WIRELESS_SETTING_NAME,
|
||||
NM_SETTING_OLPC_MESH_SETTING_NAME,
|
||||
NM_SETTING_WIFI_P2P_SETTING_NAME)) {
|
||||
feature = "Wi-Fi";
|
||||
goto out_disabled;
|
||||
}
|
||||
|
||||
if (!WITH_WWAN
|
||||
&& NM_IN_STRSET(type, NM_SETTING_GSM_SETTING_NAME, NM_SETTING_CDMA_SETTING_NAME)) {
|
||||
feature = "WWAN";
|
||||
goto out_disabled;
|
||||
}
|
||||
|
||||
if (nm_streq0(type, NM_SETTING_WIMAX_SETTING_NAME)) {
|
||||
feature = "WiMAX";
|
||||
goto out_removed;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
out_disabled:
|
||||
nm_assert(feature);
|
||||
g_set_error(error,
|
||||
NM_SETTINGS_ERROR,
|
||||
NM_SETTINGS_ERROR_FEATURE_DISABLED,
|
||||
"%s support is disabled in this build",
|
||||
feature);
|
||||
return FALSE;
|
||||
|
||||
out_removed:
|
||||
nm_assert(feature);
|
||||
g_set_error(error,
|
||||
NM_SETTINGS_ERROR,
|
||||
NM_SETTINGS_ERROR_FEATURE_REMOVED,
|
||||
"%s is no longer supported",
|
||||
feature);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* nm_rate_limit_check():
|
||||
* @rate_limit: the NMRateLimit instance
|
||||
* @window_sec: the time window in seconds, between 1 and 864000 (ten days)
|
||||
* @burst: the number of max allowed event occurrences in the given time
|
||||
* window
|
||||
*
|
||||
* The function rate limits an event. Call it multiple times with the
|
||||
* same @window_sec, and @burst values.
|
||||
*
|
||||
* Returns: TRUE if the event is allowed, FALSE if it is rate-limited
|
||||
*/
|
||||
gboolean
|
||||
nm_rate_limit_check(NMRateLimit *rate_limit, gint32 window_sec, gint32 burst)
|
||||
{
|
||||
gint64 now;
|
||||
gint64 old_ts_msec;
|
||||
gint64 window_msec;
|
||||
gint64 capacity;
|
||||
gint64 elapsed;
|
||||
|
||||
nm_assert(window_sec >= 1 && window_sec <= 864000);
|
||||
nm_assert(burst >= 1);
|
||||
|
||||
/* This implements a simple token bucket algorithm. For each millisecond,
|
||||
* refill "burst" tokens. Thus, during a full time window we
|
||||
* refill (window_msec * burst) tokens. Each event consumes @window_msec
|
||||
* tokens. */
|
||||
|
||||
window_msec = (gint64) window_sec * NM_UTILS_MSEC_PER_SEC;
|
||||
capacity = window_msec * (gint64) burst;
|
||||
old_ts_msec = rate_limit->ts_msec;
|
||||
now = nm_utils_get_monotonic_timestamp_msec();
|
||||
rate_limit->ts_msec = now;
|
||||
|
||||
elapsed = now - old_ts_msec;
|
||||
if (old_ts_msec == 0 || elapsed > window_msec) {
|
||||
/* On the first call, or in case a whole window passed, (re)start with
|
||||
* a full budget */
|
||||
rate_limit->tokens = capacity;
|
||||
} else {
|
||||
rate_limit->tokens += elapsed * (gint64) burst;
|
||||
rate_limit->tokens = NM_MIN(rate_limit->tokens, capacity);
|
||||
}
|
||||
|
||||
/* Consume the tokens */
|
||||
if (rate_limit->tokens >= window_msec) {
|
||||
rate_limit->tokens -= window_msec;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
const char *
|
||||
nm_utils_get_connection_first_permissions_user(NMConnection *connection)
|
||||
{
|
||||
NMSettingConnection *s_con;
|
||||
|
||||
s_con = nm_connection_get_setting_connection(connection);
|
||||
nm_assert(s_con);
|
||||
|
||||
return _nm_setting_connection_get_first_permissions_user(s_con);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
const char **
|
||||
nm_utils_get_connection_private_files_paths(NMConnection *connection)
|
||||
{
|
||||
GPtrArray *files;
|
||||
gs_free NMSetting **settings = NULL;
|
||||
guint num_settings;
|
||||
guint i;
|
||||
|
||||
files = g_ptr_array_new();
|
||||
settings = nm_connection_get_settings(connection, &num_settings);
|
||||
for (i = 0; i < num_settings; i++) {
|
||||
_nm_setting_get_private_files(settings[i], files);
|
||||
}
|
||||
g_ptr_array_add(files, NULL);
|
||||
|
||||
return (const char **) g_ptr_array_free(files, files->len == 1);
|
||||
}
|
||||
|
||||
typedef struct _ReadInfo ReadInfo;
|
||||
|
||||
typedef struct {
|
||||
char *path;
|
||||
ReadInfo *read_info;
|
||||
} FileInfo;
|
||||
|
||||
struct _ReadInfo {
|
||||
GTask *task;
|
||||
GHashTable *table;
|
||||
GPtrArray *file_infos; /* of FileInfo */
|
||||
GError *first_error;
|
||||
guint num_pending;
|
||||
};
|
||||
|
||||
static void
|
||||
read_file_helper_cb(GObject *source, GAsyncResult *result, gpointer user_data)
|
||||
{
|
||||
FileInfo *file_info = user_data;
|
||||
ReadInfo *read_info = file_info->read_info;
|
||||
gs_unref_bytes GBytes *output = NULL;
|
||||
gs_free_error GError *error = NULL;
|
||||
|
||||
output = nm_utils_spawn_helper_finish_binary(result, &error);
|
||||
|
||||
nm_assert(read_info->num_pending > 0);
|
||||
read_info->num_pending--;
|
||||
|
||||
if (nm_utils_error_is_cancelled(error)) {
|
||||
/* nop */
|
||||
} else if (error) {
|
||||
nm_log_dbg(LOGD_CORE,
|
||||
"read-private-files: failed to read file '%s': %s",
|
||||
file_info->path,
|
||||
error->message);
|
||||
if (!read_info->first_error) {
|
||||
/* @error just says "helper process exited with status X".
|
||||
* Return a more human-friendly one. */
|
||||
read_info->first_error = g_error_new(NM_UTILS_ERROR,
|
||||
NM_UTILS_ERROR_UNKNOWN,
|
||||
"error reading file '%s'",
|
||||
file_info->path);
|
||||
}
|
||||
} else {
|
||||
nm_log_dbg(LOGD_SUPPLICANT,
|
||||
"read-private-files: successfully read file '%s'",
|
||||
file_info->path);
|
||||
|
||||
/* Store the file contents in the hash table */
|
||||
if (!read_info->table) {
|
||||
read_info->table = g_hash_table_new_full(nm_str_hash,
|
||||
g_str_equal,
|
||||
g_free,
|
||||
(GDestroyNotify) g_bytes_unref);
|
||||
}
|
||||
g_hash_table_insert(read_info->table,
|
||||
g_steal_pointer(&file_info->path),
|
||||
g_steal_pointer(&output));
|
||||
}
|
||||
|
||||
g_clear_pointer(&file_info->path, g_free);
|
||||
|
||||
/* If all operations are completed, return */
|
||||
if (read_info->num_pending == 0) {
|
||||
if (read_info->first_error) {
|
||||
g_task_return_error(read_info->task, g_steal_pointer(&read_info->first_error));
|
||||
} else {
|
||||
g_task_return_pointer(read_info->task,
|
||||
g_steal_pointer(&read_info->table),
|
||||
(GDestroyNotify) g_hash_table_unref);
|
||||
}
|
||||
|
||||
if (read_info->table)
|
||||
g_hash_table_unref(read_info->table);
|
||||
if (read_info->file_infos)
|
||||
g_ptr_array_unref(read_info->file_infos);
|
||||
|
||||
g_object_unref(read_info->task);
|
||||
g_free(read_info);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_utils_read_private_files:
|
||||
* @paths: array of file paths to be read
|
||||
* @user: name of the user to impersonate when reading the files
|
||||
* @cancellable: cancellable to cancel the operation
|
||||
* @callback: callback to invoke on completion
|
||||
* @cb_data: data for @callback
|
||||
*
|
||||
* Reads the given list of files @paths on behalf of user @user. Invokes
|
||||
* @callback asynchronously on completion. The callback must use
|
||||
* nm_utils_read_private_files_finish() to obtain the result.
|
||||
*/
|
||||
void
|
||||
nm_utils_read_private_files(const char *const *paths,
|
||||
const char *user,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer cb_data)
|
||||
{
|
||||
ReadInfo *read_info;
|
||||
FileInfo *file_info;
|
||||
guint i;
|
||||
|
||||
g_return_if_fail(paths && paths[0]);
|
||||
g_return_if_fail(cancellable);
|
||||
g_return_if_fail(callback);
|
||||
g_return_if_fail(cb_data);
|
||||
|
||||
read_info = g_new(ReadInfo, 1);
|
||||
*read_info = (ReadInfo) {
|
||||
.task = nm_g_task_new(NULL, cancellable, nm_utils_read_private_files, callback, cb_data),
|
||||
.file_infos = g_ptr_array_new_with_free_func(g_free),
|
||||
};
|
||||
|
||||
for (i = 0; paths[i]; i++) {
|
||||
file_info = g_new(FileInfo, 1);
|
||||
*file_info = (FileInfo) {
|
||||
.path = g_strdup(paths[i]),
|
||||
.read_info = read_info,
|
||||
};
|
||||
g_ptr_array_add(read_info->file_infos, file_info);
|
||||
read_info->num_pending++;
|
||||
|
||||
nm_utils_spawn_helper(NM_MAKE_STRV("read-file-as-user", user, paths[i]),
|
||||
TRUE,
|
||||
cancellable,
|
||||
read_file_helper_cb,
|
||||
file_info);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_utils_read_private_files_finish:
|
||||
* @result: the GAsyncResult
|
||||
* @error: on return, the error
|
||||
*
|
||||
* Returns the files read by nm_utils_read_private_files(). The return value
|
||||
* is a hash table {char * -> GBytes *}. Free it with g_hash_table_unref().
|
||||
*/
|
||||
GHashTable *
|
||||
nm_utils_read_private_files_finish(GAsyncResult *result, GError **error)
|
||||
{
|
||||
GTask *task = G_TASK(result);
|
||||
|
||||
nm_assert(nm_g_task_is_valid(result, NULL, nm_utils_read_private_files));
|
||||
|
||||
return g_task_propagate_pointer(task, error);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -478,11 +478,13 @@ guint8 nm_wifi_utils_level_to_quality(int val);
|
|||
/*****************************************************************************/
|
||||
|
||||
void nm_utils_spawn_helper(const char *const *args,
|
||||
gboolean binary_output,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer cb_data);
|
||||
|
||||
char *nm_utils_spawn_helper_finish(GAsyncResult *result, GError **error);
|
||||
char *nm_utils_spawn_helper_finish_string(GAsyncResult *result, GError **error);
|
||||
GBytes *nm_utils_spawn_helper_finish_binary(GAsyncResult *result, GError **error);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -490,4 +492,32 @@ uid_t nm_utils_get_nm_uid(void);
|
|||
|
||||
gid_t nm_utils_get_nm_gid(void);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
gboolean nm_utils_connection_supported(NMConnection *connection, GError **error);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
gint64 ts_msec;
|
||||
gint64 tokens;
|
||||
} NMRateLimit;
|
||||
|
||||
gboolean nm_rate_limit_check(NMRateLimit *rate_limit, gint32 window_sec, gint32 burst);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
const char *nm_utils_get_connection_first_permissions_user(NMConnection *connection);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
const char **nm_utils_get_connection_private_files_paths(NMConnection *connection);
|
||||
|
||||
void nm_utils_read_private_files(const char *const *paths,
|
||||
const char *user,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer cb_data);
|
||||
GHashTable *nm_utils_read_private_files_finish(GAsyncResult *result, GError **error);
|
||||
|
||||
#endif /* __NM_CORE_UTILS_H__ */
|
||||
|
|
|
|||
|
|
@ -120,6 +120,7 @@ struct _NML3ConfigData {
|
|||
NMSettingConnectionMdns mdns;
|
||||
NMSettingConnectionLlmnr llmnr;
|
||||
NMSettingConnectionDnsOverTls dns_over_tls;
|
||||
NMSettingConnectionDnssec dnssec;
|
||||
NMUtilsIPv6IfaceId ip6_token;
|
||||
|
||||
NML3ConfigDatFlags flags;
|
||||
|
|
@ -577,6 +578,16 @@ nm_l3_config_data_log(const NML3ConfigData *self,
|
|||
NULL)));
|
||||
}
|
||||
|
||||
if (self->dnssec != NM_SETTING_CONNECTION_DNSSEC_DEFAULT) {
|
||||
gs_free char *s = NULL;
|
||||
|
||||
_L("dnssec: %s",
|
||||
(s = _nm_utils_enum_to_str_full(nm_setting_connection_dnssec_get_type(),
|
||||
self->dnssec,
|
||||
" ",
|
||||
NULL)));
|
||||
}
|
||||
|
||||
if (self->mptcp_flags != NM_MPTCP_FLAGS_NONE) {
|
||||
gs_free char *s = NULL;
|
||||
|
||||
|
|
@ -694,6 +705,7 @@ nm_l3_config_data_new(NMDedupMultiIndex *multi_idx, int ifindex, NMIPConfigSourc
|
|||
.mdns = NM_SETTING_CONNECTION_MDNS_DEFAULT,
|
||||
.llmnr = NM_SETTING_CONNECTION_LLMNR_DEFAULT,
|
||||
.dns_over_tls = NM_SETTING_CONNECTION_DNS_OVER_TLS_DEFAULT,
|
||||
.dnssec = NM_SETTING_CONNECTION_DNSSEC_DEFAULT,
|
||||
.flags = NM_L3_CONFIG_DAT_FLAGS_NONE,
|
||||
.metered = NM_TERNARY_DEFAULT,
|
||||
.proxy_browser_only = NM_TERNARY_DEFAULT,
|
||||
|
|
@ -1767,6 +1779,26 @@ nm_l3_config_data_set_dns_over_tls(NML3ConfigData *self, NMSettingConnectionDnsO
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
NMSettingConnectionDnssec
|
||||
nm_l3_config_data_get_dnssec(const NML3ConfigData *self)
|
||||
{
|
||||
nm_assert(_NM_IS_L3_CONFIG_DATA(self, TRUE));
|
||||
|
||||
return self->dnssec;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_l3_config_data_set_dnssec(NML3ConfigData *self, NMSettingConnectionDnssec dnssec)
|
||||
{
|
||||
nm_assert(_NM_IS_L3_CONFIG_DATA(self, FALSE));
|
||||
|
||||
if (self->dnssec == dnssec)
|
||||
return FALSE;
|
||||
|
||||
self->dnssec = dnssec;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
NMIPRouteTableSyncMode
|
||||
nm_l3_config_data_get_route_table_sync(const NML3ConfigData *self, int addr_family)
|
||||
{
|
||||
|
|
@ -2446,6 +2478,7 @@ nm_l3_config_data_cmp_full(const NML3ConfigData *a,
|
|||
NM_CMP_DIRECT(a->mdns, b->mdns);
|
||||
NM_CMP_DIRECT(a->llmnr, b->llmnr);
|
||||
NM_CMP_DIRECT(a->dns_over_tls, b->dns_over_tls);
|
||||
NM_CMP_DIRECT(a->dnssec, b->dnssec);
|
||||
}
|
||||
|
||||
if (NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_OTHER)) {
|
||||
|
|
@ -3211,6 +3244,12 @@ nm_l3_config_data_hash_dns(const NML3ConfigData *l3cd,
|
|||
empty = FALSE;
|
||||
}
|
||||
|
||||
val = nm_l3_config_data_get_dnssec(l3cd);
|
||||
if (val != NM_SETTING_CONNECTION_DNSSEC_DEFAULT) {
|
||||
g_checksum_update(sum, (const guint8 *) &val, sizeof(val));
|
||||
empty = FALSE;
|
||||
}
|
||||
|
||||
if (!empty) {
|
||||
int prio = 0;
|
||||
|
||||
|
|
@ -3461,6 +3500,9 @@ nm_l3_config_data_merge(NML3ConfigData *self,
|
|||
if (self->dns_over_tls == NM_SETTING_CONNECTION_DNS_OVER_TLS_DEFAULT)
|
||||
self->dns_over_tls = src->dns_over_tls;
|
||||
|
||||
if (self->dnssec == NM_SETTING_CONNECTION_DNSSEC_DEFAULT)
|
||||
self->dnssec = src->dnssec;
|
||||
|
||||
if (self->ip6_token.id == 0)
|
||||
self->ip6_token.id = src->ip6_token.id;
|
||||
|
||||
|
|
|
|||
|
|
@ -458,6 +458,10 @@ NMSettingConnectionDnsOverTls nm_l3_config_data_get_dns_over_tls(const NML3Confi
|
|||
gboolean nm_l3_config_data_set_dns_over_tls(NML3ConfigData *self,
|
||||
NMSettingConnectionDnsOverTls dns_over_tls);
|
||||
|
||||
NMSettingConnectionDnssec nm_l3_config_data_get_dnssec(const NML3ConfigData *self);
|
||||
|
||||
gboolean nm_l3_config_data_set_dnssec(NML3ConfigData *self, NMSettingConnectionDnssec dnssec);
|
||||
|
||||
NMIPRouteTableSyncMode nm_l3_config_data_get_route_table_sync(const NML3ConfigData *self,
|
||||
int addr_family);
|
||||
|
||||
|
|
|
|||
|
|
@ -3056,9 +3056,10 @@ handle_start_probing:
|
|||
}
|
||||
|
||||
_LOGT_acd(acd_data,
|
||||
"%sstart probing (timeout %u msec, %s)",
|
||||
"%sstart probing (timeout %u msec, ebpf %s; %s)",
|
||||
orig_state == NM_L3_ACD_ADDR_STATE_INIT ? "" : "re",
|
||||
acd_data->probing_timeout_msec,
|
||||
n_acd_has_bpf(self->priv.p->nacd) ? "enabled" : "disabled",
|
||||
log_reason);
|
||||
return;
|
||||
}
|
||||
|
|
@ -3153,10 +3154,11 @@ handle_start_defending:
|
|||
}
|
||||
|
||||
_LOGT_acd(acd_data,
|
||||
"start announcing (defend=%s) (probe created)",
|
||||
"start announcing (defend=%s) (probe created with ebpf %s)",
|
||||
_l3_acd_defend_type_to_string(acd_data->acd_defend_type_current,
|
||||
sbuf256,
|
||||
sizeof(sbuf256)));
|
||||
sizeof(sbuf256)),
|
||||
n_acd_has_bpf(self->priv.p->nacd) ? "enabled" : "disabled");
|
||||
acd_data->acd_defend_type_is_active = FALSE;
|
||||
acd_data->nacd_probe = probe;
|
||||
return;
|
||||
|
|
@ -5052,8 +5054,8 @@ _l3_commit_mptcp_af(NML3Cfg *self,
|
|||
(NM_FLAGS_HAS(mptcp_flags, NM_MPTCP_FLAGS_SIGNAL) ? MPTCP_PM_ADDR_FLAG_SIGNAL : 0)
|
||||
| (NM_FLAGS_HAS(mptcp_flags, NM_MPTCP_FLAGS_SUBFLOW) ? MPTCP_PM_ADDR_FLAG_SUBFLOW : 0)
|
||||
| (NM_FLAGS_HAS(mptcp_flags, NM_MPTCP_FLAGS_BACKUP) ? MPTCP_PM_ADDR_FLAG_BACKUP : 0)
|
||||
| (NM_FLAGS_HAS(mptcp_flags, NM_MPTCP_FLAGS_FULLMESH) ? MPTCP_PM_ADDR_FLAG_FULLMESH
|
||||
: 0);
|
||||
| (NM_FLAGS_HAS(mptcp_flags, NM_MPTCP_FLAGS_FULLMESH) ? MPTCP_PM_ADDR_FLAG_FULLMESH : 0)
|
||||
| (NM_FLAGS_HAS(mptcp_flags, NM_MPTCP_FLAGS_LAMINAR) ? MPTCP_PM_ADDR_FLAG_LAMINAR : 0);
|
||||
NMPlatformMptcpAddr a = {
|
||||
.ifindex = self->priv.ifindex,
|
||||
.id = 0,
|
||||
|
|
|
|||
|
|
@ -136,6 +136,7 @@ enum {
|
|||
ACTIVE_CONNECTION_REMOVED,
|
||||
CONFIGURE_QUIT,
|
||||
DEVICE_IFINDEX_CHANGED,
|
||||
SHARING_IPV4_CHANGED,
|
||||
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
|
@ -238,6 +239,8 @@ typedef struct {
|
|||
|
||||
guint8 device_state_prune_ratelimit_count;
|
||||
|
||||
guint shared_connections_ip4_count;
|
||||
|
||||
bool startup : 1;
|
||||
bool devices_inited : 1;
|
||||
|
||||
|
|
@ -1960,7 +1963,7 @@ find_device_by_iface(NMManager *self,
|
|||
}
|
||||
|
||||
static gboolean
|
||||
manager_sleeping(NMManager *self)
|
||||
manager_is_disabled(NMManager *self)
|
||||
{
|
||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE(self);
|
||||
|
||||
|
|
@ -1973,8 +1976,8 @@ static const char *
|
|||
_nm_state_to_string(NMState state)
|
||||
{
|
||||
switch (state) {
|
||||
case NM_STATE_ASLEEP:
|
||||
return "ASLEEP";
|
||||
case NM_STATE_DISABLED:
|
||||
return "DISABLED";
|
||||
case NM_STATE_DISCONNECTED:
|
||||
return "DISCONNECTED";
|
||||
case NM_STATE_DISCONNECTING:
|
||||
|
|
@ -2078,15 +2081,18 @@ nm_manager_update_state(NMManager *self)
|
|||
{
|
||||
NMManagerPrivate *priv;
|
||||
NMState new_state = NM_STATE_DISCONNECTED;
|
||||
const char *detail = "";
|
||||
|
||||
g_return_if_fail(NM_IS_MANAGER(self));
|
||||
|
||||
priv = NM_MANAGER_GET_PRIVATE(self);
|
||||
|
||||
if (manager_sleeping(self))
|
||||
new_state = NM_STATE_ASLEEP;
|
||||
else
|
||||
if (manager_is_disabled(self)) {
|
||||
new_state = NM_STATE_DISABLED;
|
||||
detail = priv->sleeping ? " (ASLEEP)" : " (NETWORKING OFF)";
|
||||
} else {
|
||||
new_state = find_best_device_state(self);
|
||||
}
|
||||
|
||||
if (new_state >= NM_STATE_CONNECTED_LOCAL && priv->connectivity_state == NM_CONNECTIVITY_FULL) {
|
||||
new_state = NM_STATE_CONNECTED_GLOBAL;
|
||||
|
|
@ -2097,7 +2103,7 @@ nm_manager_update_state(NMManager *self)
|
|||
|
||||
priv->state = new_state;
|
||||
|
||||
_LOGI(LOGD_CORE, "NetworkManager state is now %s", _nm_state_to_string(new_state));
|
||||
_LOGI(LOGD_CORE, "NetworkManager state is now %s%s", _nm_state_to_string(new_state), detail);
|
||||
|
||||
_notify(self, PROP_STATE);
|
||||
nm_dbus_object_emit_signal(NM_DBUS_OBJECT(self),
|
||||
|
|
@ -2956,7 +2962,7 @@ _rfkill_update_devices(NMManager *self, NMRfkillType rtype, gboolean enabled)
|
|||
_notify(self, _rfkill_type_desc[rtype].prop_id);
|
||||
|
||||
/* Don't touch devices if asleep/networking disabled */
|
||||
if (manager_sleeping(self))
|
||||
if (manager_is_disabled(self))
|
||||
return;
|
||||
|
||||
/* enable/disable wireless devices as required */
|
||||
|
|
@ -3120,7 +3126,7 @@ _rfkill_update_from_user(NMManager *self, NMRfkillType rtype, gboolean enabled)
|
|||
gboolean old_enabled, new_enabled;
|
||||
|
||||
/* Don't touch devices if asleep/networking disabled */
|
||||
if (manager_sleeping(self))
|
||||
if (manager_is_disabled(self))
|
||||
return;
|
||||
|
||||
_LOGD(LOGD_RFKILL,
|
||||
|
|
@ -4079,7 +4085,7 @@ add_device(NMManager *self, NMDevice *device, GError **error)
|
|||
|
||||
nm_device_set_unmanaged_by_user_settings(device, TRUE);
|
||||
|
||||
nm_device_set_unmanaged_flags(device, NM_UNMANAGED_SLEEPING, manager_sleeping(self));
|
||||
nm_device_set_unmanaged_flags(device, NM_UNMANAGED_MANAGER_DISABLED, manager_is_disabled(self));
|
||||
|
||||
dbus_path = nm_dbus_object_export(NM_DBUS_OBJECT(device));
|
||||
_LOG2I(LOGD_DEVICE, device, "new %s device (%s)", type_desc, dbus_path);
|
||||
|
|
@ -7299,7 +7305,7 @@ device_sleep_cb(NMDevice *device, GParamSpec *pspec, NMManager *self)
|
|||
case NM_DEVICE_STATE_DISCONNECTED:
|
||||
_LOGD(LOGD_SUSPEND, "sleep: unmanaging device %s", nm_device_get_ip_iface(device));
|
||||
nm_device_set_unmanaged_by_flags_queue(device,
|
||||
NM_UNMANAGED_SLEEPING,
|
||||
NM_UNMANAGED_MANAGER_DISABLED,
|
||||
NM_UNMAN_FLAG_OP_SET_UNMANAGED,
|
||||
NM_DEVICE_STATE_REASON_SLEEPING);
|
||||
break;
|
||||
|
|
@ -7321,24 +7327,26 @@ _handle_device_takedown(NMManager *self,
|
|||
gboolean suspending,
|
||||
gboolean is_shutdown)
|
||||
{
|
||||
gboolean is_sleep = suspending || is_shutdown;
|
||||
NMDeviceStateReason reason =
|
||||
is_sleep ? NM_DEVICE_STATE_REASON_SLEEPING : NM_DEVICE_STATE_REASON_NETWORKING_OFF;
|
||||
|
||||
nm_device_notify_sleeping(device);
|
||||
|
||||
if (nm_device_is_activating(device)
|
||||
|| nm_device_get_state(device) == NM_DEVICE_STATE_ACTIVATED) {
|
||||
_LOGD(LOGD_SUSPEND,
|
||||
_LOGD(is_sleep ? LOGD_SUSPEND : LOGD_CORE,
|
||||
"%s: wait disconnection of device %s",
|
||||
is_shutdown ? "shutdown" : "sleep",
|
||||
is_sleep ? (is_shutdown ? "shutdown" : "sleep") : "networking off",
|
||||
nm_device_get_ip_iface(device));
|
||||
|
||||
if (sleep_devices_add(self, device, suspending))
|
||||
nm_device_queue_state(device,
|
||||
NM_DEVICE_STATE_DEACTIVATING,
|
||||
NM_DEVICE_STATE_REASON_SLEEPING);
|
||||
nm_device_queue_state(device, NM_DEVICE_STATE_DEACTIVATING, reason);
|
||||
} else {
|
||||
nm_device_set_unmanaged_by_flags(device,
|
||||
NM_UNMANAGED_SLEEPING,
|
||||
NM_UNMANAGED_MANAGER_DISABLED,
|
||||
NM_UNMAN_FLAG_OP_SET_UNMANAGED,
|
||||
NM_DEVICE_STATE_REASON_SLEEPING);
|
||||
reason);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -7352,8 +7360,10 @@ do_sleep_wake(NMManager *self, gboolean sleeping_changed)
|
|||
suspending = sleeping_changed && priv->sleeping;
|
||||
waking_from_suspend = sleeping_changed && !priv->sleeping;
|
||||
|
||||
if (manager_sleeping(self)) {
|
||||
_LOGD(LOGD_SUSPEND, "sleep: %s...", suspending ? "sleeping" : "disabling");
|
||||
if (manager_is_disabled(self)) {
|
||||
_LOGD(suspending ? LOGD_SUSPEND : LOGD_CORE,
|
||||
"%s...",
|
||||
suspending ? "sleep: sleeping" : "networking: disabling");
|
||||
|
||||
/* FIXME: are there still hardware devices that need to be disabled around
|
||||
* suspend/resume?
|
||||
|
|
@ -7379,7 +7389,9 @@ do_sleep_wake(NMManager *self, gboolean sleeping_changed)
|
|||
_handle_device_takedown(self, device, suspending, FALSE);
|
||||
}
|
||||
} else {
|
||||
_LOGD(LOGD_SUSPEND, "sleep: %s...", waking_from_suspend ? "waking up" : "re-enabling");
|
||||
_LOGD(waking_from_suspend ? LOGD_SUSPEND : LOGD_CORE,
|
||||
"%s...",
|
||||
waking_from_suspend ? "sleep: waking up" : "networking: re-enabling");
|
||||
|
||||
sleep_devices_clear(self);
|
||||
|
||||
|
|
@ -7393,7 +7405,7 @@ do_sleep_wake(NMManager *self, gboolean sleeping_changed)
|
|||
*/
|
||||
if (device_is_wake_on_lan(priv->platform, device))
|
||||
nm_device_set_unmanaged_by_flags(device,
|
||||
NM_UNMANAGED_SLEEPING,
|
||||
NM_UNMANAGED_MANAGER_DISABLED,
|
||||
NM_UNMAN_FLAG_OP_SET_UNMANAGED,
|
||||
NM_DEVICE_STATE_REASON_SLEEPING);
|
||||
|
||||
|
|
@ -7421,10 +7433,12 @@ do_sleep_wake(NMManager *self, gboolean sleeping_changed)
|
|||
guint i;
|
||||
|
||||
if (nm_device_is_software(device)
|
||||
&& !nm_device_get_unmanaged_flags(device, NM_UNMANAGED_SLEEPING)) {
|
||||
&& !nm_device_get_unmanaged_flags(device, NM_UNMANAGED_MANAGER_DISABLED)) {
|
||||
/* DHCP leases of software devices could have gone stale
|
||||
* so we need to renew them. */
|
||||
nm_device_update_dynamic_ip_setup(device, "wake up");
|
||||
nm_device_update_dynamic_ip_setup(device,
|
||||
waking_from_suspend ? "wake up"
|
||||
: "networking on");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -7455,7 +7469,7 @@ do_sleep_wake(NMManager *self, gboolean sleeping_changed)
|
|||
? NM_DEVICE_STATE_REASON_CONNECTION_ASSUMED
|
||||
: NM_DEVICE_STATE_REASON_NOW_MANAGED;
|
||||
nm_device_set_unmanaged_by_flags(device,
|
||||
NM_UNMANAGED_SLEEPING,
|
||||
NM_UNMANAGED_MANAGER_DISABLED,
|
||||
NM_UNMAN_FLAG_OP_SET_MANAGED,
|
||||
reason);
|
||||
}
|
||||
|
|
@ -8818,6 +8832,41 @@ nm_manager_emit_device_ifindex_changed(NMManager *self, NMDevice *device)
|
|||
g_signal_emit(self, signals[DEVICE_IFINDEX_CHANGED], 0, device);
|
||||
}
|
||||
|
||||
void
|
||||
nm_manager_update_shared_connection(NMManager *self, int addr_family, gboolean enabled)
|
||||
{
|
||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE(self);
|
||||
gboolean state_changed, state;
|
||||
|
||||
/* Only IPv4 supported for the moment */
|
||||
if (addr_family != AF_INET)
|
||||
return;
|
||||
|
||||
if (enabled) {
|
||||
g_return_if_fail(priv->shared_connections_ip4_count < G_MAXUINT);
|
||||
priv->shared_connections_ip4_count++;
|
||||
state_changed = priv->shared_connections_ip4_count == 1;
|
||||
} else {
|
||||
g_return_if_fail(priv->shared_connections_ip4_count > 0);
|
||||
priv->shared_connections_ip4_count--;
|
||||
state_changed = priv->shared_connections_ip4_count == 0;
|
||||
}
|
||||
|
||||
if (state_changed) {
|
||||
state = priv->shared_connections_ip4_count > 0;
|
||||
_LOGD(LOGD_SHARING, "sharing-ipv4 state change %d -> %d", !state, state);
|
||||
g_signal_emit(self, signals[SHARING_IPV4_CHANGED], 0, state);
|
||||
}
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_manager_get_sharing_ipv4(NMManager *self)
|
||||
{
|
||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE(self);
|
||||
|
||||
return priv->shared_connections_ip4_count > 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
NM_DEFINE_SINGLETON_REGISTER(NMManager);
|
||||
|
|
@ -9921,6 +9970,17 @@ nm_manager_class_init(NMManagerClass *manager_class)
|
|||
G_TYPE_NONE,
|
||||
1,
|
||||
NM_TYPE_DEVICE);
|
||||
|
||||
signals[SHARING_IPV4_CHANGED] = g_signal_new(NM_MANAGER_SHARING_IPV4_CHANGED,
|
||||
G_OBJECT_CLASS_TYPE(object_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE,
|
||||
1,
|
||||
G_TYPE_BOOLEAN);
|
||||
}
|
||||
|
||||
NMConfig *
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@
|
|||
#define NM_MANAGER_CONFIGURE_QUIT "configure-quit"
|
||||
#define NM_MANAGER_INTERNAL_DEVICE_ADDED "internal-device-added"
|
||||
#define NM_MANAGER_INTERNAL_DEVICE_REMOVED "internal-device-removed"
|
||||
#define NM_MANAGER_SHARING_IPV4_CHANGED "sharing-ipv4-changed"
|
||||
|
||||
GType nm_manager_get_type(void);
|
||||
|
||||
|
|
@ -212,6 +213,9 @@ struct _NMDnsManager;
|
|||
|
||||
struct _NMDnsManager *nm_manager_get_dns_manager(NMManager *self);
|
||||
|
||||
void nm_manager_update_shared_connection(NMManager *self, int addr_family, gboolean enabled);
|
||||
gboolean nm_manager_get_sharing_ipv4(NMManager *self);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
void nm_manager_notify_delete_settings_connections(NMManager *self,
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@
|
|||
#include "NetworkManagerUtils.h"
|
||||
#include "devices/nm-device.h"
|
||||
#include "devices/nm-device-factory.h"
|
||||
#include "devices/nm-device-private.h"
|
||||
#include "dns/nm-dns-manager.h"
|
||||
#include "nm-act-request.h"
|
||||
#include "nm-auth-utils.h"
|
||||
|
|
@ -98,6 +97,7 @@ typedef struct {
|
|||
bool updating_dns : 1;
|
||||
|
||||
GArray *ip6_prefix_delegations; /* pool of ip6 prefixes delegated to all devices */
|
||||
|
||||
} NMPolicyPrivate;
|
||||
|
||||
struct _NMPolicy {
|
||||
|
|
@ -1845,7 +1845,7 @@ nm_policy_device_recheck_auto_activate_schedule(NMPolicy *self, NMDevice *device
|
|||
|
||||
priv = NM_POLICY_GET_PRIVATE(self);
|
||||
|
||||
if (nm_manager_get_state(priv->manager) == NM_STATE_ASLEEP)
|
||||
if (nm_manager_get_state(priv->manager) == NM_STATE_DISABLED)
|
||||
return;
|
||||
|
||||
if (!nm_device_autoconnect_allowed(device))
|
||||
|
|
@ -2083,65 +2083,6 @@ unblock_autoconnect_for_ports_for_sett_conn(NMPolicy *self, NMSettingsConnection
|
|||
unblock_autoconnect_for_ports(self, controller_device, controller_uuid_settings, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
refresh_forwarding(NMPolicy *self, NMDevice *device, gboolean is_activated_shared_device)
|
||||
{
|
||||
NMActiveConnection *ac;
|
||||
NMDevice *tmp_device;
|
||||
NMPolicyPrivate *priv = NM_POLICY_GET_PRIVATE(self);
|
||||
const CList *tmp_lst;
|
||||
gboolean any_shared_active = false;
|
||||
gint32 default_forwarding_v4;
|
||||
const char *new_value = NULL;
|
||||
|
||||
/* FIXME: This implementation is still inefficient because refresh_forwarding()
|
||||
* is called every time a device goes up or down, requiring a full scan of all
|
||||
* active connections to determine if any shared connection is active. */
|
||||
nm_manager_for_each_active_connection (priv->manager, ac, tmp_lst) {
|
||||
NMSettingIPConfig *s_ip;
|
||||
NMDevice *to_device = nm_active_connection_get_device(ac);
|
||||
|
||||
if (to_device) {
|
||||
s_ip = nm_device_get_applied_setting(to_device, NM_TYPE_SETTING_IP4_CONFIG);
|
||||
if (s_ip) {
|
||||
if (nm_streq0(nm_device_get_effective_ip_config_method(to_device, AF_INET),
|
||||
NM_SETTING_IP4_CONFIG_METHOD_SHARED)) {
|
||||
any_shared_active = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
default_forwarding_v4 = nm_platform_sysctl_get_int32(
|
||||
NM_PLATFORM_GET,
|
||||
NMP_SYSCTL_PATHID_ABSOLUTE("/proc/sys/net/ipv4/conf/default/forwarding"),
|
||||
0);
|
||||
|
||||
new_value = any_shared_active ? "1" : (default_forwarding_v4 ? "1" : "0");
|
||||
|
||||
nm_manager_for_each_device (priv->manager, tmp_device, tmp_lst) {
|
||||
NMDeviceState state;
|
||||
NMSettingIPConfigForwarding ipv4_forwarding;
|
||||
|
||||
state = nm_device_get_state(tmp_device);
|
||||
if (state != NM_DEVICE_STATE_ACTIVATED)
|
||||
continue;
|
||||
|
||||
ipv4_forwarding = nm_device_get_ipv4_forwarding(tmp_device);
|
||||
|
||||
if (ipv4_forwarding == NM_SETTING_IP_CONFIG_FORWARDING_AUTO
|
||||
|| (device == tmp_device && is_activated_shared_device)) {
|
||||
gs_free char *sysctl_value = NULL;
|
||||
|
||||
sysctl_value = nm_device_sysctl_ip_conf_get(tmp_device, AF_INET, "forwarding");
|
||||
|
||||
if (!nm_streq0(sysctl_value, new_value))
|
||||
nm_device_sysctl_ip_conf_set(tmp_device, AF_INET, "forwarding", new_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
activate_port_or_children_connections(NMPolicy *self,
|
||||
NMDevice *device,
|
||||
|
|
@ -2286,9 +2227,8 @@ device_state_changed(NMDevice *device,
|
|||
NMPolicyPrivate *priv = user_data;
|
||||
NMPolicy *self = _PRIV_TO_SELF(priv);
|
||||
NMActiveConnection *ac;
|
||||
NMSettingsConnection *sett_conn = nm_device_get_settings_connection(device);
|
||||
NMSettingConnection *s_con = NULL;
|
||||
gboolean is_activated_shared_device = FALSE;
|
||||
NMSettingsConnection *sett_conn = nm_device_get_settings_connection(device);
|
||||
NMSettingConnection *s_con = NULL;
|
||||
|
||||
switch (nm_device_state_reason_check(reason)) {
|
||||
case NM_DEVICE_STATE_REASON_GSM_SIM_PIN_REQUIRED:
|
||||
|
|
@ -2404,10 +2344,6 @@ device_state_changed(NMDevice *device,
|
|||
}
|
||||
}
|
||||
}
|
||||
if (!nm_device_get_refresh_forwarding_done(device)) {
|
||||
refresh_forwarding(self, device, FALSE);
|
||||
nm_device_set_refresh_forwarding_done(device, TRUE);
|
||||
}
|
||||
break;
|
||||
case NM_DEVICE_STATE_ACTIVATED:
|
||||
if (nm_device_get_device_type(device) == NM_DEVICE_TYPE_OVS_INTERFACE) {
|
||||
|
|
@ -2417,7 +2353,10 @@ device_state_changed(NMDevice *device,
|
|||
}
|
||||
if (sett_conn) {
|
||||
/* Reset auto retries back to default since connection was successful */
|
||||
nm_manager_devcon_autoconnect_retries_reset(priv->manager, device, sett_conn);
|
||||
nm_manager_devcon_autoconnect_reset_reconnect_all(priv->manager,
|
||||
device,
|
||||
sett_conn,
|
||||
FALSE);
|
||||
}
|
||||
|
||||
/* Since there is no guarantee that device_l3cd_changed() is called
|
||||
|
|
@ -2440,20 +2379,11 @@ device_state_changed(NMDevice *device,
|
|||
update_system_hostname(self, "routing and dns", TRUE);
|
||||
nm_dns_manager_end_updates(priv->dns_manager, __func__);
|
||||
|
||||
is_activated_shared_device =
|
||||
nm_streq0(nm_device_get_effective_ip_config_method(device, AF_INET),
|
||||
NM_SETTING_IP4_CONFIG_METHOD_SHARED);
|
||||
refresh_forwarding(self, device, is_activated_shared_device);
|
||||
nm_device_set_refresh_forwarding_done(device, FALSE);
|
||||
break;
|
||||
case NM_DEVICE_STATE_UNMANAGED:
|
||||
case NM_DEVICE_STATE_UNAVAILABLE:
|
||||
if (old_state > NM_DEVICE_STATE_DISCONNECTED)
|
||||
update_routing_and_dns(self, FALSE, device);
|
||||
if (!nm_device_get_refresh_forwarding_done(device)) {
|
||||
refresh_forwarding(self, device, FALSE);
|
||||
nm_device_set_refresh_forwarding_done(device, TRUE);
|
||||
}
|
||||
break;
|
||||
case NM_DEVICE_STATE_DEACTIVATING:
|
||||
if (sett_conn) {
|
||||
|
|
@ -2489,10 +2419,6 @@ device_state_changed(NMDevice *device,
|
|||
}
|
||||
}
|
||||
ip6_remove_device_prefix_delegations(self, device);
|
||||
if (!nm_device_get_refresh_forwarding_done(device)) {
|
||||
refresh_forwarding(self, device, FALSE);
|
||||
nm_device_set_refresh_forwarding_done(device, TRUE);
|
||||
}
|
||||
break;
|
||||
case NM_DEVICE_STATE_DISCONNECTED:
|
||||
g_signal_handlers_disconnect_by_func(device, device_dns_lookup_done, self);
|
||||
|
|
@ -2509,10 +2435,6 @@ device_state_changed(NMDevice *device,
|
|||
|
||||
/* Device is now available for auto-activation */
|
||||
nm_policy_device_recheck_auto_activate_schedule(self, device);
|
||||
if (!nm_device_get_refresh_forwarding_done(device)) {
|
||||
refresh_forwarding(self, device, FALSE);
|
||||
nm_device_set_refresh_forwarding_done(device, TRUE);
|
||||
}
|
||||
break;
|
||||
|
||||
case NM_DEVICE_STATE_PREPARE:
|
||||
|
|
@ -2528,10 +2450,6 @@ device_state_changed(NMDevice *device,
|
|||
g_object_weak_unref(G_OBJECT(ac), pending_ac_gone, self);
|
||||
g_object_unref(self);
|
||||
}
|
||||
if (!nm_device_get_refresh_forwarding_done(device)) {
|
||||
refresh_forwarding(self, device, FALSE);
|
||||
nm_device_set_refresh_forwarding_done(device, TRUE);
|
||||
}
|
||||
break;
|
||||
case NM_DEVICE_STATE_IP_CONFIG:
|
||||
/* We must have secrets if we got here. */
|
||||
|
|
@ -2542,10 +2460,6 @@ device_state_changed(NMDevice *device,
|
|||
sett_conn,
|
||||
NM_SETTINGS_AUTOCONNECT_BLOCKED_REASON_FAILED,
|
||||
FALSE);
|
||||
if (!nm_device_get_refresh_forwarding_done(device)) {
|
||||
refresh_forwarding(self, device, FALSE);
|
||||
nm_device_set_refresh_forwarding_done(device, TRUE);
|
||||
}
|
||||
break;
|
||||
case NM_DEVICE_STATE_SECONDARIES:
|
||||
if (sett_conn)
|
||||
|
|
|
|||
|
|
@ -186,6 +186,7 @@ ip_again:
|
|||
00644,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
nm_log_dbg(LOGD_PLATFORM, "dump to file complete");
|
||||
|
|
|
|||
|
|
@ -123,7 +123,8 @@ software_add(NMLinkType link_type, const char *name)
|
|||
gboolean bond0_exists = !!nm_platform_link_get_by_ifname(NM_PLATFORM_GET, "bond0");
|
||||
int r;
|
||||
const NMPlatformLnkBond nm_platform_lnk_bond_default = {
|
||||
.mode = nmtst_rand_select(3, 1),
|
||||
.mode = nmtst_rand_select(3, 1),
|
||||
.use_carrier = 1,
|
||||
};
|
||||
|
||||
r = nm_platform_link_bond_add(NM_PLATFORM_GET, name, &nm_platform_lnk_bond_default, NULL);
|
||||
|
|
|
|||
|
|
@ -27,6 +27,19 @@
|
|||
|
||||
struct _NMSettingsPlugin;
|
||||
|
||||
/**
|
||||
* NMSettingsStorage:
|
||||
* @_plugin: The settings plugin that provides this storage.
|
||||
* @_uuid: UUID of the profile represented by this storage.
|
||||
* @_filename: Backing filename (can be NULL for in-memory or meta-data).
|
||||
* @_storage_lst: Node in the per-plugin storage list.
|
||||
* @_storage_by_uuid_lst: Node in the per-UUID storage list.
|
||||
*
|
||||
* Describes the origin and identity of one profile instance as provided by a
|
||||
* specific settings plugin and (optionally) a backing file. A single UUID may
|
||||
* have multiple storages from different plugins; plugin order determines
|
||||
* priority.
|
||||
*/
|
||||
typedef struct NMSettingsStorage {
|
||||
GObject parent;
|
||||
struct _NMSettingsPlugin *_plugin;
|
||||
|
|
|
|||
|
|
@ -76,6 +76,17 @@ static NM_CACHED_QUARK_FCN("default-wired-connection-blocked",
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* StorageData:
|
||||
* @sd_lst: Node used in per-UUID storage lists.
|
||||
* @storage: Storage provider instance for this UUID.
|
||||
* @connection: Connection object backed by @storage, or NULL for meta-data.
|
||||
* @prioritize: Request to prioritize this storage during merge.
|
||||
*
|
||||
* Per-UUID storage entry used to accumulate and merge updates from plugins.
|
||||
* Items live temporarily in the dirty list and are merged into the current list
|
||||
* with stable priority ordering.
|
||||
*/
|
||||
typedef struct _StorageData {
|
||||
CList sd_lst;
|
||||
NMSettingsStorage *storage;
|
||||
|
|
@ -165,6 +176,20 @@ _storage_data_is_alive(StorageData *sd)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* SettConnEntry:
|
||||
* @uuid: Normalized UUID key for this entry (points to @_uuid_data).
|
||||
* @sett_conn: Current NMSettingsConnection selected for @uuid, or NULL.
|
||||
* @storage: The storage that currently owns @sett_conn, or NULL.
|
||||
* @sd_lst_head: Head of current storages list for @uuid (high to low priority).
|
||||
* @dirty_sd_lst_head: Head of pending storage updates to merge.
|
||||
* @sce_dirty_lst: Node in the global dirty queue.
|
||||
* @_uuid_data: Inline storage backing @uuid.
|
||||
*
|
||||
* Tracks one connection profile across all storages and its dirty state.
|
||||
* It holds the authoritative in-memory connection and the sets of storages
|
||||
* providing or updating it.
|
||||
*/
|
||||
typedef struct {
|
||||
const char *uuid;
|
||||
NMSettingsConnection *sett_conn;
|
||||
|
|
@ -1368,10 +1393,11 @@ _connection_changed_track(NMSettings *self,
|
|||
NMConnection *connection,
|
||||
gboolean prioritize)
|
||||
{
|
||||
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE(self);
|
||||
SettConnEntry *sett_conn_entry;
|
||||
StorageData *sd;
|
||||
const char *uuid;
|
||||
NMSettingsPrivate *priv = NM_SETTINGS_GET_PRIVATE(self);
|
||||
SettConnEntry *sett_conn_entry;
|
||||
StorageData *sd;
|
||||
const char *uuid;
|
||||
gs_free_error GError *error = NULL;
|
||||
|
||||
nm_assert_valid_settings_storage(NULL, storage);
|
||||
|
||||
|
|
@ -1382,6 +1408,17 @@ _connection_changed_track(NMSettings *self,
|
|||
|| (_nm_connection_verify(connection, NULL) == NM_SETTING_VERIFY_SUCCESS));
|
||||
nm_assert(!connection || nm_streq0(uuid, nm_connection_get_uuid(connection)));
|
||||
|
||||
if (connection && !nm_utils_connection_supported(connection, &error)) {
|
||||
_LOGD("storage[%s," NM_SETTINGS_STORAGE_PRINT_FMT
|
||||
"]: ignoring connection \"%s\" from file \"%s\": %s",
|
||||
uuid,
|
||||
NM_SETTINGS_STORAGE_PRINT_ARG(storage),
|
||||
nm_connection_get_id(connection),
|
||||
nm_settings_storage_get_filename(storage),
|
||||
error->message);
|
||||
connection = NULL;
|
||||
}
|
||||
|
||||
nm_assert_connection_unchanging(connection);
|
||||
|
||||
sett_conn_entry =
|
||||
|
|
@ -1851,6 +1888,9 @@ nm_settings_add_connection(NMSettings *self,
|
|||
|
||||
NM_SET_OUT(out_sett_conn, NULL);
|
||||
|
||||
if (!nm_utils_connection_supported(connection, error))
|
||||
return FALSE;
|
||||
|
||||
uuid = nm_connection_get_uuid(connection);
|
||||
|
||||
sett_conn_entry = _sett_conn_entries_get(self, uuid);
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ get_full_file_path(const char *ifcfg_path, const char *file_path)
|
|||
{
|
||||
const char *base = file_path;
|
||||
gs_free char *dirname = NULL;
|
||||
char *p;
|
||||
const char *p;
|
||||
|
||||
g_return_val_if_fail(ifcfg_path != NULL, NULL);
|
||||
g_return_val_if_fail(file_path != NULL, NULL);
|
||||
|
|
|
|||
|
|
@ -320,6 +320,7 @@ write_blobs(GHashTable *blobs, GError **error)
|
|||
0600,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&write_error)) {
|
||||
g_set_error(error,
|
||||
NM_SETTINGS_ERROR,
|
||||
|
|
@ -3626,6 +3627,14 @@ do_write_construct(NMConnection *connection,
|
|||
|
||||
write_ip_routing_rules(connection, ifcfg, route_ignore);
|
||||
|
||||
if (nm_setting_connection_get_dnssec(s_con) != NM_SETTING_CONNECTION_DNSSEC_DEFAULT) {
|
||||
set_error_unsupported(error,
|
||||
connection,
|
||||
NM_SETTING_CONNECTION_SETTING_NAME "." NM_SETTING_CONNECTION_DNSSEC,
|
||||
TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
write_connection_setting(s_con, ifcfg, interface_name);
|
||||
|
||||
NM_SET_OUT(out_ifcfg, g_steal_pointer(&ifcfg));
|
||||
|
|
|
|||
|
|
@ -280,6 +280,7 @@ nms_keyfile_nmmeta_write(const char *dirname,
|
|||
length,
|
||||
0600,
|
||||
NULL,
|
||||
NULL,
|
||||
&errsv,
|
||||
NULL)) {
|
||||
NM_SET_OUT(out_full_filename, g_steal_pointer(&full_filename_tmp));
|
||||
|
|
|
|||
|
|
@ -133,6 +133,7 @@ cert_writer(NMConnection *connection,
|
|||
0600,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&local);
|
||||
if (success) {
|
||||
/* Write the path value to the keyfile.
|
||||
|
|
@ -384,7 +385,14 @@ _internal_write_connection(NMConnection *connection,
|
|||
}
|
||||
}
|
||||
|
||||
nm_utils_file_set_contents(path, kf_content_buf, kf_content_len, 0600, NULL, NULL, &local_err);
|
||||
nm_utils_file_set_contents(path,
|
||||
kf_content_buf,
|
||||
kf_content_len,
|
||||
0600,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
&local_err);
|
||||
if (local_err) {
|
||||
g_set_error(error,
|
||||
NM_SETTINGS_ERROR,
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ timestamp=305415219
|
|||
[gsm]
|
||||
apn=internet2.voicestream.com
|
||||
device-id=da812de91eec16620b06cd0ca5cbc7ea25245222
|
||||
device-uid=MODEM1
|
||||
home-only=true
|
||||
network-id=254098
|
||||
password=parliament2
|
||||
|
|
|
|||
|
|
@ -1408,6 +1408,8 @@ test_write_gsm_connection(void)
|
|||
"89148000000060671234",
|
||||
NM_SETTING_GSM_SIM_OPERATOR_ID,
|
||||
"310260",
|
||||
NM_SETTING_GSM_DEVICE_UID,
|
||||
"MODEM1",
|
||||
NULL);
|
||||
|
||||
write_test_connection_and_reread(connection, TRUE, TEST_KEYFILES_DIR "/Test_Write_GSM");
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ typedef struct {
|
|||
typedef struct {
|
||||
GHashTable *config;
|
||||
GHashTable *blobs;
|
||||
char *private_user;
|
||||
NMSupplCapMask capabilities;
|
||||
guint32 ap_scan;
|
||||
bool fast_required : 1;
|
||||
|
|
@ -60,7 +61,7 @@ _get_capability(NMSupplicantConfigPrivate *priv, NMSupplCapType type)
|
|||
}
|
||||
|
||||
NMSupplicantConfig *
|
||||
nm_supplicant_config_new(NMSupplCapMask capabilities)
|
||||
nm_supplicant_config_new(NMSupplCapMask capabilities, const char *private_user)
|
||||
{
|
||||
NMSupplicantConfigPrivate *priv;
|
||||
NMSupplicantConfig *self;
|
||||
|
|
@ -69,6 +70,7 @@ nm_supplicant_config_new(NMSupplCapMask capabilities)
|
|||
priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE(self);
|
||||
|
||||
priv->capabilities = capabilities;
|
||||
priv->private_user = g_strdup(private_user);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
|
@ -258,19 +260,19 @@ static gboolean
|
|||
nm_supplicant_config_add_blob_for_connection(NMSupplicantConfig *self,
|
||||
GBytes *field,
|
||||
const char *name,
|
||||
const char *con_uid,
|
||||
const char *con_uuid,
|
||||
GError **error)
|
||||
{
|
||||
if (field && g_bytes_get_size(field)) {
|
||||
gs_free char *uid = NULL;
|
||||
gs_free char *blob_id = NULL;
|
||||
char *p;
|
||||
|
||||
uid = g_strdup_printf("%s-%s", con_uid, name);
|
||||
for (p = uid; *p; p++) {
|
||||
blob_id = g_strdup_printf("%s-%s", con_uuid, name);
|
||||
for (p = blob_id; *p; p++) {
|
||||
if (*p == '/')
|
||||
*p = '-';
|
||||
}
|
||||
if (!nm_supplicant_config_add_blob(self, name, field, uid, error))
|
||||
if (!nm_supplicant_config_add_blob(self, name, field, blob_id, error))
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
|
|
@ -283,6 +285,7 @@ nm_supplicant_config_finalize(GObject *object)
|
|||
|
||||
g_hash_table_destroy(priv->config);
|
||||
nm_clear_pointer(&priv->blobs, g_hash_table_destroy);
|
||||
nm_clear_pointer(&priv->private_user, g_free);
|
||||
|
||||
G_OBJECT_CLASS(nm_supplicant_config_parent_class)->finalize(object);
|
||||
}
|
||||
|
|
@ -930,6 +933,7 @@ nm_supplicant_config_add_setting_wireless_security(NMSupplicantConfig
|
|||
guint32 mtu,
|
||||
NMSettingWirelessSecurityPmf pmf,
|
||||
NMSettingWirelessSecurityFils fils,
|
||||
GHashTable *files,
|
||||
GError **error)
|
||||
{
|
||||
NMSupplicantConfigPrivate *priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE(self);
|
||||
|
|
@ -1284,6 +1288,7 @@ nm_supplicant_config_add_setting_wireless_security(NMSupplicantConfig
|
|||
con_uuid,
|
||||
mtu,
|
||||
FALSE,
|
||||
files,
|
||||
error))
|
||||
return FALSE;
|
||||
}
|
||||
|
|
@ -1365,6 +1370,7 @@ nm_supplicant_config_add_setting_8021x(NMSupplicantConfig *self,
|
|||
const char *con_uuid,
|
||||
guint32 mtu,
|
||||
gboolean wired,
|
||||
GHashTable *files,
|
||||
GError **error)
|
||||
{
|
||||
NMSupplicantConfigPrivate *priv;
|
||||
|
|
@ -1594,24 +1600,21 @@ nm_supplicant_config_add_setting_8021x(NMSupplicantConfig *self,
|
|||
}
|
||||
|
||||
/* CA certificate */
|
||||
path = NULL;
|
||||
bytes = NULL;
|
||||
if (ca_cert_override) {
|
||||
if (!add_string_val(self, ca_cert_override, "ca_cert", FALSE, NULL, error))
|
||||
return FALSE;
|
||||
/* This is a build-time-configured system-wide file path, no need to pass
|
||||
* it as a blob */
|
||||
path = ca_cert_override;
|
||||
} else {
|
||||
switch (nm_setting_802_1x_get_ca_cert_scheme(setting)) {
|
||||
case NM_SETTING_802_1X_CK_SCHEME_BLOB:
|
||||
bytes = nm_setting_802_1x_get_ca_cert_blob(setting);
|
||||
if (!nm_supplicant_config_add_blob_for_connection(self,
|
||||
bytes,
|
||||
"ca_cert",
|
||||
con_uuid,
|
||||
error))
|
||||
return FALSE;
|
||||
break;
|
||||
case NM_SETTING_802_1X_CK_SCHEME_PATH:
|
||||
path = nm_setting_802_1x_get_ca_cert_path(setting);
|
||||
if (!add_string_val(self, path, "ca_cert", FALSE, NULL, error))
|
||||
return FALSE;
|
||||
if (priv->private_user)
|
||||
bytes = nm_g_hash_table_lookup(files, path);
|
||||
break;
|
||||
case NM_SETTING_802_1X_CK_SCHEME_PKCS11:
|
||||
if (!add_pkcs11_uri_with_pin(self,
|
||||
|
|
@ -1627,26 +1630,32 @@ nm_supplicant_config_add_setting_8021x(NMSupplicantConfig *self,
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (bytes) {
|
||||
if (!nm_supplicant_config_add_blob_for_connection(self, bytes, "ca_cert", con_uuid, error))
|
||||
return FALSE;
|
||||
} else if (path) {
|
||||
/* Private connections cannot use paths other than the system CA store */
|
||||
g_return_val_if_fail(ca_cert_override || !priv->private_user, FALSE);
|
||||
if (!add_string_val(self, path, "ca_cert", FALSE, NULL, error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Phase 2 CA certificate */
|
||||
path = NULL;
|
||||
bytes = NULL;
|
||||
if (ca_cert_override) {
|
||||
if (!add_string_val(self, ca_cert_override, "ca_cert2", FALSE, NULL, error))
|
||||
return FALSE;
|
||||
/* This is a build-time-configured system-wide file path, no need to pass
|
||||
* it as a blob */
|
||||
path = ca_cert_override;
|
||||
} else {
|
||||
switch (nm_setting_802_1x_get_phase2_ca_cert_scheme(setting)) {
|
||||
case NM_SETTING_802_1X_CK_SCHEME_BLOB:
|
||||
bytes = nm_setting_802_1x_get_phase2_ca_cert_blob(setting);
|
||||
if (!nm_supplicant_config_add_blob_for_connection(self,
|
||||
bytes,
|
||||
"ca_cert2",
|
||||
con_uuid,
|
||||
error))
|
||||
return FALSE;
|
||||
break;
|
||||
case NM_SETTING_802_1X_CK_SCHEME_PATH:
|
||||
path = nm_setting_802_1x_get_phase2_ca_cert_path(setting);
|
||||
if (!add_string_val(self, path, "ca_cert2", FALSE, NULL, error))
|
||||
return FALSE;
|
||||
if (priv->private_user)
|
||||
bytes = nm_g_hash_table_lookup(files, path);
|
||||
break;
|
||||
case NM_SETTING_802_1X_CK_SCHEME_PKCS11:
|
||||
if (!add_pkcs11_uri_with_pin(
|
||||
|
|
@ -1663,6 +1672,15 @@ nm_supplicant_config_add_setting_8021x(NMSupplicantConfig *self,
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (bytes) {
|
||||
if (!nm_supplicant_config_add_blob_for_connection(self, bytes, "ca_cert2", con_uuid, error))
|
||||
return FALSE;
|
||||
} else if (path) {
|
||||
/* Private connections cannot use paths other than the system CA store */
|
||||
g_return_val_if_fail(ca_cert_override || !priv->private_user, FALSE);
|
||||
if (!add_string_val(self, path, "ca_cert2", FALSE, NULL, error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Subject match */
|
||||
value = nm_setting_802_1x_get_subject_match(setting);
|
||||
|
|
@ -1714,21 +1732,17 @@ nm_supplicant_config_add_setting_8021x(NMSupplicantConfig *self,
|
|||
|
||||
/* Private key */
|
||||
added = FALSE;
|
||||
path = NULL;
|
||||
bytes = NULL;
|
||||
switch (nm_setting_802_1x_get_private_key_scheme(setting)) {
|
||||
case NM_SETTING_802_1X_CK_SCHEME_BLOB:
|
||||
bytes = nm_setting_802_1x_get_private_key_blob(setting);
|
||||
if (!nm_supplicant_config_add_blob_for_connection(self,
|
||||
bytes,
|
||||
"private_key",
|
||||
con_uuid,
|
||||
error))
|
||||
return FALSE;
|
||||
added = TRUE;
|
||||
break;
|
||||
case NM_SETTING_802_1X_CK_SCHEME_PATH:
|
||||
path = nm_setting_802_1x_get_private_key_path(setting);
|
||||
if (!add_string_val(self, path, "private_key", FALSE, NULL, error))
|
||||
return FALSE;
|
||||
if (priv->private_user)
|
||||
bytes = nm_g_hash_table_lookup(files, path);
|
||||
added = TRUE;
|
||||
break;
|
||||
case NM_SETTING_802_1X_CK_SCHEME_PKCS11:
|
||||
|
|
@ -1745,6 +1759,19 @@ nm_supplicant_config_add_setting_8021x(NMSupplicantConfig *self,
|
|||
default:
|
||||
break;
|
||||
}
|
||||
if (bytes) {
|
||||
if (!nm_supplicant_config_add_blob_for_connection(self,
|
||||
bytes,
|
||||
"private_key",
|
||||
con_uuid,
|
||||
error))
|
||||
return FALSE;
|
||||
} else if (path) {
|
||||
/* Private connections cannot use paths */
|
||||
g_return_val_if_fail(!priv->private_user, FALSE);
|
||||
if (!add_string_val(self, path, "private_key", FALSE, NULL, error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (added) {
|
||||
NMSetting8021xCKFormat format;
|
||||
|
|
@ -1768,20 +1795,16 @@ nm_supplicant_config_add_setting_8021x(NMSupplicantConfig *self,
|
|||
/* Only add the client cert if the private key is not PKCS#12, as
|
||||
* wpa_supplicant configuration directs us to do.
|
||||
*/
|
||||
path = NULL;
|
||||
bytes = NULL;
|
||||
switch (nm_setting_802_1x_get_client_cert_scheme(setting)) {
|
||||
case NM_SETTING_802_1X_CK_SCHEME_BLOB:
|
||||
bytes = nm_setting_802_1x_get_client_cert_blob(setting);
|
||||
if (!nm_supplicant_config_add_blob_for_connection(self,
|
||||
bytes,
|
||||
"client_cert",
|
||||
con_uuid,
|
||||
error))
|
||||
return FALSE;
|
||||
break;
|
||||
case NM_SETTING_802_1X_CK_SCHEME_PATH:
|
||||
path = nm_setting_802_1x_get_client_cert_path(setting);
|
||||
if (!add_string_val(self, path, "client_cert", FALSE, NULL, error))
|
||||
return FALSE;
|
||||
if (priv->private_user)
|
||||
bytes = nm_g_hash_table_lookup(files, path);
|
||||
break;
|
||||
case NM_SETTING_802_1X_CK_SCHEME_PKCS11:
|
||||
if (!add_pkcs11_uri_with_pin(
|
||||
|
|
@ -1797,26 +1820,35 @@ nm_supplicant_config_add_setting_8021x(NMSupplicantConfig *self,
|
|||
default:
|
||||
break;
|
||||
}
|
||||
if (bytes) {
|
||||
if (!nm_supplicant_config_add_blob_for_connection(self,
|
||||
bytes,
|
||||
"client_cert",
|
||||
con_uuid,
|
||||
error))
|
||||
return FALSE;
|
||||
} else if (path) {
|
||||
/* Private connections cannot use paths */
|
||||
g_return_val_if_fail(!priv->private_user, FALSE);
|
||||
if (!add_string_val(self, path, "client_cert", FALSE, NULL, error))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Phase 2 private key */
|
||||
added = FALSE;
|
||||
path = NULL;
|
||||
bytes = NULL;
|
||||
switch (nm_setting_802_1x_get_phase2_private_key_scheme(setting)) {
|
||||
case NM_SETTING_802_1X_CK_SCHEME_BLOB:
|
||||
bytes = nm_setting_802_1x_get_phase2_private_key_blob(setting);
|
||||
if (!nm_supplicant_config_add_blob_for_connection(self,
|
||||
bytes,
|
||||
"private_key2",
|
||||
con_uuid,
|
||||
error))
|
||||
return FALSE;
|
||||
added = TRUE;
|
||||
break;
|
||||
case NM_SETTING_802_1X_CK_SCHEME_PATH:
|
||||
path = nm_setting_802_1x_get_phase2_private_key_path(setting);
|
||||
if (!add_string_val(self, path, "private_key2", FALSE, NULL, error))
|
||||
return FALSE;
|
||||
if (priv->private_user)
|
||||
bytes = nm_g_hash_table_lookup(files, path);
|
||||
added = TRUE;
|
||||
break;
|
||||
case NM_SETTING_802_1X_CK_SCHEME_PKCS11:
|
||||
|
|
@ -1834,6 +1866,19 @@ nm_supplicant_config_add_setting_8021x(NMSupplicantConfig *self,
|
|||
default:
|
||||
break;
|
||||
}
|
||||
if (bytes) {
|
||||
if (!nm_supplicant_config_add_blob_for_connection(self,
|
||||
bytes,
|
||||
"private_key2",
|
||||
con_uuid,
|
||||
error))
|
||||
return FALSE;
|
||||
} else if (path) {
|
||||
/* Private connections cannot use paths */
|
||||
g_return_val_if_fail(!priv->private_user, FALSE);
|
||||
if (!add_string_val(self, path, "private_key2", FALSE, NULL, error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (added) {
|
||||
NMSetting8021xCKFormat format;
|
||||
|
|
@ -1857,20 +1902,16 @@ nm_supplicant_config_add_setting_8021x(NMSupplicantConfig *self,
|
|||
/* Only add the client cert if the private key is not PKCS#12, as
|
||||
* wpa_supplicant configuration directs us to do.
|
||||
*/
|
||||
path = NULL;
|
||||
bytes = NULL;
|
||||
switch (nm_setting_802_1x_get_phase2_client_cert_scheme(setting)) {
|
||||
case NM_SETTING_802_1X_CK_SCHEME_BLOB:
|
||||
bytes = nm_setting_802_1x_get_phase2_client_cert_blob(setting);
|
||||
if (!nm_supplicant_config_add_blob_for_connection(self,
|
||||
bytes,
|
||||
"client_cert2",
|
||||
con_uuid,
|
||||
error))
|
||||
return FALSE;
|
||||
break;
|
||||
case NM_SETTING_802_1X_CK_SCHEME_PATH:
|
||||
path = nm_setting_802_1x_get_phase2_client_cert_path(setting);
|
||||
if (!add_string_val(self, path, "client_cert2", FALSE, NULL, error))
|
||||
return FALSE;
|
||||
if (priv->private_user)
|
||||
bytes = nm_g_hash_table_lookup(files, path);
|
||||
break;
|
||||
case NM_SETTING_802_1X_CK_SCHEME_PKCS11:
|
||||
if (!add_pkcs11_uri_with_pin(
|
||||
|
|
@ -1886,6 +1927,19 @@ nm_supplicant_config_add_setting_8021x(NMSupplicantConfig *self,
|
|||
default:
|
||||
break;
|
||||
}
|
||||
if (bytes) {
|
||||
if (!nm_supplicant_config_add_blob_for_connection(self,
|
||||
bytes,
|
||||
"client_cert2",
|
||||
con_uuid,
|
||||
error))
|
||||
return FALSE;
|
||||
} else if (path) {
|
||||
/* Private connections cannot use paths */
|
||||
g_return_val_if_fail(!priv->private_user, FALSE);
|
||||
if (!add_string_val(self, path, "client_cert2", FALSE, NULL, error))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ typedef struct _NMSupplicantConfigClass NMSupplicantConfigClass;
|
|||
|
||||
GType nm_supplicant_config_get_type(void);
|
||||
|
||||
NMSupplicantConfig *nm_supplicant_config_new(NMSupplCapMask capabilities);
|
||||
NMSupplicantConfig *nm_supplicant_config_new(NMSupplCapMask capabilities, const char *private_user);
|
||||
|
||||
guint32 nm_supplicant_config_get_ap_scan(NMSupplicantConfig *self);
|
||||
|
||||
|
|
@ -57,6 +57,7 @@ gboolean nm_supplicant_config_add_setting_wireless_security(NMSupplicantConfig
|
|||
guint32 mtu,
|
||||
NMSettingWirelessSecurityPmf pmf,
|
||||
NMSettingWirelessSecurityFils fils,
|
||||
GHashTable *files,
|
||||
GError **error);
|
||||
|
||||
gboolean nm_supplicant_config_add_no_security(NMSupplicantConfig *self, GError **error);
|
||||
|
|
@ -66,6 +67,7 @@ gboolean nm_supplicant_config_add_setting_8021x(NMSupplicantConfig *self,
|
|||
const char *con_uuid,
|
||||
guint32 mtu,
|
||||
gboolean wired,
|
||||
GHashTable *files,
|
||||
GError **error);
|
||||
|
||||
gboolean nm_supplicant_config_add_setting_macsec(NMSupplicantConfig *self,
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ typedef struct {
|
|||
gpointer user_data;
|
||||
guint fail_on_idle_id;
|
||||
guint blobs_left;
|
||||
guint remove_blobs_left;
|
||||
guint calls_left;
|
||||
struct _AddNetworkData *add_network_data;
|
||||
} AssocData;
|
||||
|
|
@ -65,6 +66,8 @@ enum {
|
|||
WPS_CREDENTIALS, /* WPS credentials received */
|
||||
GROUP_STARTED, /* a new Group (interface) was created */
|
||||
GROUP_FINISHED, /* a Group (interface) has been finished */
|
||||
PSK_MISMATCH, /* supplicant reported incorrect PSK */
|
||||
SAE_MISMATCH, /* supplicant reported incorrect SAE Password */
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
|
|
@ -2264,6 +2267,7 @@ assoc_add_blob_cb(GObject *source, GAsyncResult *result, gpointer user_data)
|
|||
return;
|
||||
}
|
||||
|
||||
nm_assert(priv->assoc_data->blobs_left > 0);
|
||||
priv->assoc_data->blobs_left--;
|
||||
_LOGT("assoc[" NM_HASH_OBFUSCATE_PTR_FMT "]: blob added (%u left)",
|
||||
NM_HASH_OBFUSCATE_PTR(priv->assoc_data),
|
||||
|
|
@ -2272,6 +2276,148 @@ assoc_add_blob_cb(GObject *source, GAsyncResult *result, gpointer user_data)
|
|||
assoc_call_select_network(self);
|
||||
}
|
||||
|
||||
static void
|
||||
assoc_add_blobs(NMSupplicantInterface *self)
|
||||
{
|
||||
NMSupplicantInterfacePrivate *priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE(self);
|
||||
GHashTable *blobs;
|
||||
GHashTableIter iter;
|
||||
const char *blob_name;
|
||||
GBytes *blob_data;
|
||||
|
||||
blobs = nm_supplicant_config_get_blobs(priv->assoc_data->cfg);
|
||||
priv->assoc_data->blobs_left = nm_g_hash_table_size(blobs);
|
||||
|
||||
_LOGT("assoc[" NM_HASH_OBFUSCATE_PTR_FMT "]: need to add %u blobs",
|
||||
NM_HASH_OBFUSCATE_PTR(priv->assoc_data),
|
||||
priv->assoc_data->blobs_left);
|
||||
|
||||
if (priv->assoc_data->blobs_left == 0) {
|
||||
assoc_call_select_network(self);
|
||||
return;
|
||||
}
|
||||
|
||||
g_hash_table_iter_init(&iter, blobs);
|
||||
while (g_hash_table_iter_next(&iter, (gpointer) &blob_name, (gpointer) &blob_data)) {
|
||||
_LOGT("assoc[" NM_HASH_OBFUSCATE_PTR_FMT "]: adding blob '%s'",
|
||||
NM_HASH_OBFUSCATE_PTR(priv->assoc_data),
|
||||
blob_name);
|
||||
_dbus_connection_call(
|
||||
self,
|
||||
NM_WPAS_DBUS_IFACE_INTERFACE,
|
||||
"AddBlob",
|
||||
g_variant_new("(s@ay)", blob_name, nm_g_bytes_to_variant_ay(blob_data)),
|
||||
G_VARIANT_TYPE("()"),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
DBUS_TIMEOUT_MSEC,
|
||||
priv->assoc_data->cancellable,
|
||||
assoc_add_blob_cb,
|
||||
self);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
assoc_remove_blob_cb(GObject *source, GAsyncResult *result, gpointer user_data)
|
||||
{
|
||||
NMSupplicantInterface *self;
|
||||
NMSupplicantInterfacePrivate *priv;
|
||||
gs_free_error GError *error = NULL;
|
||||
gs_unref_variant GVariant *res = NULL;
|
||||
|
||||
res = g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), result, &error);
|
||||
if (nm_utils_error_is_cancelled(error))
|
||||
return;
|
||||
|
||||
self = NM_SUPPLICANT_INTERFACE(user_data);
|
||||
priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE(self);
|
||||
|
||||
/* We don't consider a failure fatal. The new association might be able
|
||||
* to proceed even with the existing blobs, if they don't conflict with new
|
||||
* ones. */
|
||||
|
||||
nm_assert(priv->assoc_data->remove_blobs_left > 0);
|
||||
priv->assoc_data->remove_blobs_left--;
|
||||
|
||||
if (error) {
|
||||
g_dbus_error_strip_remote_error(error);
|
||||
_LOGD("assoc[" NM_HASH_OBFUSCATE_PTR_FMT "]: failed to delete blob: %s",
|
||||
NM_HASH_OBFUSCATE_PTR(priv->assoc_data),
|
||||
error->message);
|
||||
} else {
|
||||
_LOGT("assoc[" NM_HASH_OBFUSCATE_PTR_FMT "]: blob removed (%u left)",
|
||||
NM_HASH_OBFUSCATE_PTR(priv->assoc_data),
|
||||
priv->assoc_data->remove_blobs_left);
|
||||
}
|
||||
|
||||
if (priv->assoc_data->remove_blobs_left == 0)
|
||||
assoc_add_blobs(self);
|
||||
}
|
||||
|
||||
static void
|
||||
assoc_get_blobs_cb(GObject *source, GAsyncResult *result, gpointer user_data)
|
||||
{
|
||||
NMSupplicantInterface *self;
|
||||
NMSupplicantInterfacePrivate *priv;
|
||||
gs_free_error GError *error = NULL;
|
||||
gs_unref_variant GVariant *res = NULL;
|
||||
gs_unref_variant GVariant *value = NULL;
|
||||
GVariantIter iter;
|
||||
const char *blob_name;
|
||||
GVariant *blob_data;
|
||||
|
||||
res = g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), result, &error);
|
||||
if (nm_utils_error_is_cancelled(error))
|
||||
return;
|
||||
|
||||
self = NM_SUPPLICANT_INTERFACE(user_data);
|
||||
priv = NM_SUPPLICANT_INTERFACE_GET_PRIVATE(self);
|
||||
|
||||
if (error) {
|
||||
_LOGD("assoc[" NM_HASH_OBFUSCATE_PTR_FMT "]: failed to get blob list: %s",
|
||||
NM_HASH_OBFUSCATE_PTR(priv->assoc_data),
|
||||
error->message);
|
||||
assoc_add_blobs(self);
|
||||
return;
|
||||
}
|
||||
|
||||
g_variant_get(res, "(v)", &value);
|
||||
|
||||
/* While the "Blobs" property is documented as type "as", it is actually "a{say}" */
|
||||
if (!value || !g_variant_is_of_type(value, G_VARIANT_TYPE("a{say}"))) {
|
||||
_LOGD("assoc[" NM_HASH_OBFUSCATE_PTR_FMT "]: failed to get blob list: wrong return type %s",
|
||||
NM_HASH_OBFUSCATE_PTR(priv->assoc_data),
|
||||
value ? g_variant_get_type_string(value) : "NULL");
|
||||
assoc_add_blobs(self);
|
||||
return;
|
||||
}
|
||||
|
||||
g_variant_iter_init(&iter, value);
|
||||
priv->assoc_data->remove_blobs_left = g_variant_iter_n_children(&iter);
|
||||
_LOGT("assoc[" NM_HASH_OBFUSCATE_PTR_FMT "]: need to delete %u blobs",
|
||||
NM_HASH_OBFUSCATE_PTR(priv->assoc_data),
|
||||
priv->assoc_data->remove_blobs_left);
|
||||
|
||||
if (priv->assoc_data->remove_blobs_left == 0) {
|
||||
assoc_add_blobs(self);
|
||||
} else {
|
||||
while (g_variant_iter_loop(&iter, "{&s@ay}", &blob_name, &blob_data)) {
|
||||
_LOGT("assoc[" NM_HASH_OBFUSCATE_PTR_FMT "]: removing blob '%s'",
|
||||
NM_HASH_OBFUSCATE_PTR(priv->assoc_data),
|
||||
blob_name);
|
||||
_dbus_connection_call(self,
|
||||
NM_WPAS_DBUS_IFACE_INTERFACE,
|
||||
"RemoveBlob",
|
||||
g_variant_new("(s)", blob_name),
|
||||
G_VARIANT_TYPE("()"),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
DBUS_TIMEOUT_MSEC,
|
||||
priv->assoc_data->cancellable,
|
||||
assoc_remove_blob_cb,
|
||||
self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
assoc_add_network_cb(GObject *source, GAsyncResult *result, gpointer user_data)
|
||||
{
|
||||
|
|
@ -2279,12 +2425,8 @@ assoc_add_network_cb(GObject *source, GAsyncResult *result, gpointer user_data)
|
|||
AssocData *assoc_data;
|
||||
NMSupplicantInterface *self;
|
||||
NMSupplicantInterfacePrivate *priv;
|
||||
gs_unref_variant GVariant *res = NULL;
|
||||
gs_free_error GError *error = NULL;
|
||||
GHashTable *blobs;
|
||||
GHashTableIter iter;
|
||||
const char *blob_name;
|
||||
GBytes *blob_data;
|
||||
gs_unref_variant GVariant *res = NULL;
|
||||
gs_free_error GError *error = NULL;
|
||||
nm_auto_ref_string NMRefString *name_owner = NULL;
|
||||
nm_auto_ref_string NMRefString *object_path = NULL;
|
||||
|
||||
|
|
@ -2336,34 +2478,21 @@ assoc_add_network_cb(GObject *source, GAsyncResult *result, gpointer user_data)
|
|||
nm_assert(!priv->net_path);
|
||||
g_variant_get(res, "(o)", &priv->net_path);
|
||||
|
||||
/* Send blobs first; otherwise jump to selecting the network */
|
||||
blobs = nm_supplicant_config_get_blobs(priv->assoc_data->cfg);
|
||||
priv->assoc_data->blobs_left = blobs ? g_hash_table_size(blobs) : 0u;
|
||||
|
||||
_LOGT("assoc[" NM_HASH_OBFUSCATE_PTR_FMT "]: network added (%s) (%u blobs left)",
|
||||
_LOGT("assoc[" NM_HASH_OBFUSCATE_PTR_FMT "]: network added (%s)",
|
||||
NM_HASH_OBFUSCATE_PTR(priv->assoc_data),
|
||||
priv->net_path,
|
||||
priv->assoc_data->blobs_left);
|
||||
priv->net_path);
|
||||
|
||||
if (priv->assoc_data->blobs_left == 0) {
|
||||
assoc_call_select_network(self);
|
||||
return;
|
||||
}
|
||||
|
||||
g_hash_table_iter_init(&iter, blobs);
|
||||
while (g_hash_table_iter_next(&iter, (gpointer) &blob_name, (gpointer) &blob_data)) {
|
||||
_dbus_connection_call(
|
||||
self,
|
||||
NM_WPAS_DBUS_IFACE_INTERFACE,
|
||||
"AddBlob",
|
||||
g_variant_new("(s@ay)", blob_name, nm_g_bytes_to_variant_ay(blob_data)),
|
||||
G_VARIANT_TYPE("()"),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
DBUS_TIMEOUT_MSEC,
|
||||
priv->assoc_data->cancellable,
|
||||
assoc_add_blob_cb,
|
||||
self);
|
||||
}
|
||||
/* Delete any existing blobs before adding new ones */
|
||||
_dbus_connection_call(self,
|
||||
DBUS_INTERFACE_PROPERTIES,
|
||||
"Get",
|
||||
g_variant_new("(ss)", NM_WPAS_DBUS_IFACE_INTERFACE, "Blobs"),
|
||||
G_VARIANT_TYPE("(v)"),
|
||||
G_DBUS_CALL_FLAGS_NONE,
|
||||
DBUS_TIMEOUT_MSEC,
|
||||
priv->assoc_data->cancellable,
|
||||
assoc_get_blobs_cb,
|
||||
self);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -3105,6 +3234,15 @@ _signal_handle(NMSupplicantInterface *self,
|
|||
return;
|
||||
}
|
||||
|
||||
if (nm_streq(signal_name, "PskMismatch")) {
|
||||
g_signal_emit(self, signals[PSK_MISMATCH], 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if (nm_streq(signal_name, "SaePasswordMismatch")) {
|
||||
g_signal_emit(self, signals[SAE_MISMATCH], 0);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -3737,4 +3875,23 @@ nm_supplicant_interface_class_init(NMSupplicantInterfaceClass *klass)
|
|||
G_TYPE_NONE,
|
||||
1,
|
||||
G_TYPE_STRING);
|
||||
|
||||
signals[PSK_MISMATCH] = g_signal_new(NM_SUPPLICANT_INTERFACE_PSK_MISMATCH,
|
||||
G_OBJECT_CLASS_TYPE(object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE,
|
||||
0);
|
||||
signals[SAE_MISMATCH] = g_signal_new(NM_SUPPLICANT_INTERFACE_SAE_MISMATCH,
|
||||
G_OBJECT_CLASS_TYPE(object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
0,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
G_TYPE_NONE,
|
||||
0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,6 +86,8 @@ typedef enum {
|
|||
#define NM_SUPPLICANT_INTERFACE_WPS_CREDENTIALS "wps-credentials"
|
||||
#define NM_SUPPLICANT_INTERFACE_GROUP_STARTED "group-started"
|
||||
#define NM_SUPPLICANT_INTERFACE_GROUP_FINISHED "group-finished"
|
||||
#define NM_SUPPLICANT_INTERFACE_PSK_MISMATCH "wpa-psk-mismatch"
|
||||
#define NM_SUPPLICANT_INTERFACE_SAE_MISMATCH "wpa-sae-password-mismatch"
|
||||
|
||||
typedef struct _NMSupplicantInterfaceClass NMSupplicantInterfaceClass;
|
||||
|
||||
|
|
|
|||
|
|
@ -212,18 +212,19 @@ validate_type_utf8(const struct Opt *opt, const char *value, const guint32 len)
|
|||
}
|
||||
|
||||
static gboolean
|
||||
validate_type_keyword(const struct Opt *opt, const char *value, const guint32 len)
|
||||
validate_type_keyword(const struct Opt *opt, const char *value_in, const guint32 len)
|
||||
{
|
||||
gs_free char *value_free = NULL;
|
||||
char *value;
|
||||
|
||||
nm_assert(opt);
|
||||
nm_assert(value);
|
||||
nm_assert(value_in);
|
||||
|
||||
/* Allow everything */
|
||||
if (!opt->str_allowed)
|
||||
return TRUE;
|
||||
|
||||
value = nm_strndup_a(300, value, len, &value_free);
|
||||
value = nm_strndup_a(300, value_in, len, &value_free);
|
||||
|
||||
/* validate each space-separated word in 'value' */
|
||||
|
||||
|
|
|
|||
|
|
@ -98,7 +98,8 @@ build_supplicant_config(NMConnection *connection,
|
|||
NMSetting8021x *s_8021x;
|
||||
gboolean success;
|
||||
|
||||
config = nm_supplicant_config_new(capabilities);
|
||||
config = nm_supplicant_config_new(capabilities,
|
||||
nm_utils_get_connection_first_permissions_user(connection));
|
||||
|
||||
s_wifi = nm_connection_get_setting_wireless(connection);
|
||||
g_assert(s_wifi);
|
||||
|
|
@ -120,6 +121,7 @@ build_supplicant_config(NMConnection *connection,
|
|||
mtu,
|
||||
pmf,
|
||||
fils,
|
||||
NULL,
|
||||
&error);
|
||||
} else {
|
||||
success = nm_supplicant_config_add_no_security(config, &error);
|
||||
|
|
|
|||
|
|
@ -260,6 +260,70 @@ test_shorten_hostname(void)
|
|||
do_test_shorten_hostname(".name1", FALSE, NULL);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
typedef struct {
|
||||
NMRateLimit ratelimit;
|
||||
GMainLoop *loop;
|
||||
GSource *source;
|
||||
guint num;
|
||||
} RateLimitData;
|
||||
|
||||
static int
|
||||
rate_limit_window_expire_cb(gpointer user_data)
|
||||
{
|
||||
RateLimitData *data = user_data;
|
||||
|
||||
g_assert(nm_rate_limit_check(&data->ratelimit, 1, 5));
|
||||
g_assert(nm_rate_limit_check(&data->ratelimit, 1, 5));
|
||||
g_assert(nm_rate_limit_check(&data->ratelimit, 1, 5));
|
||||
g_assert(nm_rate_limit_check(&data->ratelimit, 1, 5));
|
||||
g_assert(nm_rate_limit_check(&data->ratelimit, 1, 5));
|
||||
|
||||
g_assert(!nm_rate_limit_check(&data->ratelimit, 1, 5));
|
||||
g_assert(!nm_rate_limit_check(&data->ratelimit, 1, 5));
|
||||
|
||||
nm_clear_g_source_inst(&data->source);
|
||||
g_main_loop_quit(data->loop);
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static int
|
||||
rate_limit_check_cb(gpointer user_data)
|
||||
{
|
||||
RateLimitData *data = user_data;
|
||||
|
||||
g_assert(nm_rate_limit_check(&data->ratelimit, 1, 5));
|
||||
g_assert(nm_rate_limit_check(&data->ratelimit, 1, 5));
|
||||
g_assert(nm_rate_limit_check(&data->ratelimit, 1, 5));
|
||||
g_assert(nm_rate_limit_check(&data->ratelimit, 1, 5));
|
||||
g_assert(nm_rate_limit_check(&data->ratelimit, 1, 5));
|
||||
|
||||
g_assert(!nm_rate_limit_check(&data->ratelimit, 1, 5));
|
||||
g_assert(!nm_rate_limit_check(&data->ratelimit, 1, 5));
|
||||
|
||||
nm_clear_g_source_inst(&data->source);
|
||||
data->source = nm_g_timeout_add_source(1000, rate_limit_window_expire_cb, data);
|
||||
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
test_rate_limit_check(void)
|
||||
{
|
||||
RateLimitData data;
|
||||
|
||||
data = (RateLimitData) {
|
||||
.loop = g_main_loop_new(NULL, FALSE),
|
||||
.ratelimit = {},
|
||||
.source = nm_g_timeout_add_source(1, rate_limit_check_cb, &data),
|
||||
.num = 0,
|
||||
};
|
||||
|
||||
g_main_loop_run(data.loop);
|
||||
g_main_loop_unref(data.loop);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
NMTST_DEFINE();
|
||||
|
|
@ -272,6 +336,7 @@ main(int argc, char **argv)
|
|||
g_test_add_func("/utils/stable_privacy", test_stable_privacy);
|
||||
g_test_add_func("/utils/hw_addr_gen_stable_eth", test_hw_addr_gen_stable_eth);
|
||||
g_test_add_func("/utils/shorten-hostname", test_shorten_hostname);
|
||||
g_test_add_func("/utils/rate-limit-check", test_rate_limit_check);
|
||||
|
||||
return g_test_run();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,10 +26,12 @@
|
|||
#include "nm-active-connection.h"
|
||||
#include "nm-config.h"
|
||||
#include "nm-dbus-manager.h"
|
||||
#include "devices/nm-device.h"
|
||||
#include "nm-dispatcher.h"
|
||||
#include "nm-firewalld-manager.h"
|
||||
#include "nm-ip-config.h"
|
||||
#include "nm-l3-config-data.h"
|
||||
#include "nm-manager.h"
|
||||
#include "nm-netns.h"
|
||||
#include "nm-pacrunner-manager.h"
|
||||
#include "nm-vpn-manager.h"
|
||||
|
|
@ -1409,9 +1411,11 @@ _check_complete(NMVpnConnection *self, gboolean success)
|
|||
NMVpnConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE(self);
|
||||
nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL;
|
||||
NMConnection *connection;
|
||||
NMDevice *device;
|
||||
NMSettingConnection *s_con;
|
||||
const char *zone;
|
||||
const char *iface;
|
||||
int ifindex;
|
||||
|
||||
if (priv->vpn_state < STATE_IP_CONFIG_GET || priv->vpn_state > STATE_ACTIVATED)
|
||||
return;
|
||||
|
|
@ -1437,10 +1441,23 @@ _check_complete(NMVpnConnection *self, gboolean success)
|
|||
}
|
||||
|
||||
connection = _get_applied_connection(self);
|
||||
|
||||
l3cd = nm_l3_config_data_new_from_connection(nm_netns_get_multi_idx(priv->netns),
|
||||
nm_vpn_connection_get_ip_ifindex(self, TRUE),
|
||||
connection);
|
||||
ifindex = nm_vpn_connection_get_ip_ifindex(self, FALSE);
|
||||
/* Use nm_device_create_l3_config_data_from_connection here if possible. This ensures that
|
||||
* connection properties like mdns, llmnr, dns-over-tls or dnssec are applied to vpn connections
|
||||
* If this vpn connection does not have its own device resort to nm_l3_config_data_new_from_connection
|
||||
* since we can't properly apply these properties anyway
|
||||
*/
|
||||
if (ifindex > 0) {
|
||||
device = nm_manager_get_device_by_ifindex(NM_MANAGER_GET, ifindex);
|
||||
nm_assert(device);
|
||||
l3cd = nm_device_create_l3_config_data_from_connection(device, connection);
|
||||
} else {
|
||||
l3cd = nm_l3_config_data_new_from_connection(nm_netns_get_multi_idx(priv->netns),
|
||||
nm_vpn_connection_get_ip_ifindex(self, TRUE),
|
||||
connection);
|
||||
_LOGD("VPN connection does not have its own device. Some connection properties won't be "
|
||||
"supported.");
|
||||
}
|
||||
|
||||
nm_l3_config_data_set_allow_routes_without_address(l3cd, AF_INET, TRUE);
|
||||
nm_l3_config_data_set_allow_routes_without_address(l3cd, AF_INET6, TRUE);
|
||||
|
|
|
|||
|
|
@ -60,16 +60,21 @@ nm_vpn_manager_activate_connection(NMVpnManager *manager, NMVpnConnection *vpn,
|
|||
{
|
||||
NMVpnManagerPrivate *priv;
|
||||
NMVpnPluginInfo *plugin_info;
|
||||
NMConnection *applied;
|
||||
const char *service_name;
|
||||
NMDevice *device;
|
||||
const char *user;
|
||||
|
||||
g_return_val_if_fail(NM_IS_VPN_MANAGER(manager), FALSE);
|
||||
g_return_val_if_fail(NM_IS_VPN_CONNECTION(vpn), FALSE);
|
||||
g_return_val_if_fail(!error || !*error, FALSE);
|
||||
|
||||
priv = NM_VPN_MANAGER_GET_PRIVATE(manager);
|
||||
device = nm_active_connection_get_device(NM_ACTIVE_CONNECTION(vpn));
|
||||
g_assert(device);
|
||||
priv = NM_VPN_MANAGER_GET_PRIVATE(manager);
|
||||
device = nm_active_connection_get_device(NM_ACTIVE_CONNECTION(vpn));
|
||||
applied = nm_active_connection_get_applied_connection(NM_ACTIVE_CONNECTION(vpn));
|
||||
nm_assert(device);
|
||||
nm_assert(applied);
|
||||
|
||||
if (nm_device_get_state(device) != NM_DEVICE_STATE_ACTIVATED
|
||||
&& nm_device_get_state(device) != NM_DEVICE_STATE_SECONDARIES) {
|
||||
g_set_error_literal(error,
|
||||
|
|
@ -101,6 +106,30 @@ nm_vpn_manager_activate_connection(NMVpnManager *manager, NMVpnConnection *vpn,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
user = nm_utils_get_connection_first_permissions_user(applied);
|
||||
if (user) {
|
||||
NMSettingConnection *s_con;
|
||||
|
||||
s_con = nm_connection_get_setting_connection(applied);
|
||||
nm_assert(s_con);
|
||||
if (_nm_setting_connection_get_num_permissions_users(s_con) > 1) {
|
||||
g_set_error_literal(error,
|
||||
NM_MANAGER_ERROR,
|
||||
NM_MANAGER_ERROR_CONNECTION_NOT_AVAILABLE,
|
||||
"private VPN connections with multiple users are not allowed.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!nm_vpn_plugin_info_supports_safe_private_file_access(plugin_info)) {
|
||||
g_set_error(error,
|
||||
NM_MANAGER_ERROR,
|
||||
NM_MANAGER_ERROR_CONNECTION_NOT_AVAILABLE,
|
||||
"The '%s' plugin doesn't support private connections.",
|
||||
nm_vpn_plugin_info_get_name(plugin_info));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
nm_vpn_connection_activate(vpn, plugin_info);
|
||||
|
||||
if (!nm_vpn_plugin_info_supports_multiple(plugin_info)) {
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@
|
|||
|
||||
#define NM_CONFIG_KEYFILE_KEY_DEVICE_MANAGED "managed"
|
||||
#define NM_CONFIG_KEYFILE_KEY_DEVICE_IGNORE_CARRIER "ignore-carrier"
|
||||
#define NM_CONFIG_KEYFILE_KEY_DEVICE_CHECK_CONNECTIVITY "check-connectivity"
|
||||
#define NM_CONFIG_KEYFILE_KEY_DEVICE_SRIOV_NUM_VFS "sriov-num-vfs"
|
||||
#define NM_CONFIG_KEYFILE_KEY_DEVICE_KEEP_CONFIGURATION "keep-configuration"
|
||||
#define NM_CONFIG_KEYFILE_KEY_DEVICE_ALLOWED_CONNECTIONS "allowed-connections"
|
||||
|
|
|
|||
|
|
@ -2077,7 +2077,19 @@ global:
|
|||
nm_sriov_preserve_on_down_get_type;
|
||||
} libnm_1_52_0;
|
||||
|
||||
libnm_1_54_2 {
|
||||
global:
|
||||
nm_setting_hsr_get_interlink;
|
||||
nm_setting_hsr_get_protocol_version;
|
||||
nm_setting_hsr_protocol_version_get_type;
|
||||
} libnm_1_54_0;
|
||||
|
||||
libnm_1_56_0 {
|
||||
global:
|
||||
nm_dns_server_validate;
|
||||
nm_setting_gsm_get_device_uid;
|
||||
nm_setting_connection_get_dnssec;
|
||||
nm_setting_connection_dnssec_get_type;
|
||||
nm_utils_copy_cert_as_user;
|
||||
nm_vpn_plugin_info_supports_safe_private_file_access;
|
||||
} libnm_1_54_0;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ test_units = [
|
|||
'test-nm-client',
|
||||
'test-remote-settings-client',
|
||||
'test-secret-agent',
|
||||
'test-copy-cert-as-user'
|
||||
]
|
||||
|
||||
foreach test_unit: test_units
|
||||
|
|
@ -37,12 +38,15 @@ foreach test_unit: test_units
|
|||
],
|
||||
)
|
||||
|
||||
test(
|
||||
'src/libnm-client-impl/tests/' + test_unit,
|
||||
test_script,
|
||||
timeout: 90,
|
||||
args: test_args + [exe.full_path()],
|
||||
)
|
||||
# test-copy-cert-as-user is a manual test, don't run it automatically
|
||||
if test_unit != 'test-copy-cert-as-user'
|
||||
test(
|
||||
'src/libnm-client-impl/tests/' + test_unit,
|
||||
test_script,
|
||||
timeout: 90,
|
||||
args: test_args + [exe.full_path()],
|
||||
)
|
||||
endif
|
||||
endforeach
|
||||
|
||||
if enable_introspection
|
||||
|
|
|
|||
32
src/libnm-client-impl/tests/test-copy-cert-as-user.c
Normal file
32
src/libnm-client-impl/tests/test-copy-cert-as-user.c
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
/*
|
||||
* This is a program to manually test the
|
||||
* nm_utils_copy_cert_as_user() libnm function.
|
||||
*/
|
||||
|
||||
#include "libnm-client-impl/nm-default-libnm.h"
|
||||
|
||||
#include "nm-utils.h"
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
gs_free_error GError *error = NULL;
|
||||
gs_free char *filename = NULL;
|
||||
|
||||
if (argc != 3) {
|
||||
g_printerr("Usage: %s <FILE> <USER>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
filename = nm_utils_copy_cert_as_user(argv[1], argv[2], &error);
|
||||
if (!filename) {
|
||||
g_printerr("Error: %s\n", error->message);
|
||||
return 1;
|
||||
}
|
||||
|
||||
g_print("%s\n", filename);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -2756,6 +2756,8 @@ test_types(void)
|
|||
G(nm_setting_connection_lldp_get_type),
|
||||
G(nm_setting_connection_llmnr_get_type),
|
||||
G(nm_setting_connection_mdns_get_type),
|
||||
G(nm_setting_connection_dns_over_tls_get_type),
|
||||
G(nm_setting_connection_dnssec_get_type),
|
||||
G(nm_setting_dcb_flags_get_type),
|
||||
G(nm_setting_dcb_get_type),
|
||||
G(nm_setting_diff_result_get_type),
|
||||
|
|
|
|||
|
|
@ -483,8 +483,8 @@ nm_utils_validate_shared_dhcp_range(const char *shared_dhcp_range,
|
|||
GPtrArray *addresses,
|
||||
GError **error)
|
||||
{
|
||||
char *start_address_str;
|
||||
char *end_address_str;
|
||||
const char *start_address_str;
|
||||
const char *end_address_str;
|
||||
NMIPAddress *interface_address_with_prefix;
|
||||
NMIPAddr interface_address;
|
||||
NMIPAddr start_address;
|
||||
|
|
@ -825,7 +825,7 @@ nm_dns_uri_parse(int addr_family, const char *str, NMDnsServer *dns, GError **er
|
|||
addr = nm_strndup_a(100, addr_port, end - addr_port, &addr_heap);
|
||||
|
||||
/* IPv6 link-local scope-id */
|
||||
perc = strchr(addr, '%');
|
||||
perc = (char *) strchr(addr, '%');
|
||||
if (perc) {
|
||||
*perc = '\0';
|
||||
if (g_strlcpy(dns->interface, perc + 1, sizeof(dns->interface))
|
||||
|
|
|
|||
|
|
@ -300,13 +300,15 @@ gpointer _nm_connection_new_setting(NMConnection *connection, GType gtype);
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define _NM_MPTCP_FLAGS_ALL \
|
||||
((NMMptcpFlags) (NM_MPTCP_FLAGS_DISABLED | NM_MPTCP_FLAGS_ENABLED \
|
||||
| NM_MPTCP_FLAGS_ALSO_WITHOUT_SYSCTL \
|
||||
| NM_MPTCP_FLAGS_ALSO_WITHOUT_DEFAULT_ROUTE | NM_MPTCP_FLAGS_SIGNAL \
|
||||
| NM_MPTCP_FLAGS_SUBFLOW | NM_MPTCP_FLAGS_BACKUP | NM_MPTCP_FLAGS_FULLMESH))
|
||||
#define _NM_MPTCP_FLAGS_ALL \
|
||||
((NMMptcpFlags) (NM_MPTCP_FLAGS_DISABLED | NM_MPTCP_FLAGS_ENABLED \
|
||||
| NM_MPTCP_FLAGS_ALSO_WITHOUT_SYSCTL \
|
||||
| NM_MPTCP_FLAGS_ALSO_WITHOUT_DEFAULT_ROUTE | NM_MPTCP_FLAGS_SIGNAL \
|
||||
| NM_MPTCP_FLAGS_SUBFLOW | NM_MPTCP_FLAGS_BACKUP | NM_MPTCP_FLAGS_FULLMESH \
|
||||
| NM_MPTCP_FLAGS_LAMINAR))
|
||||
|
||||
#define _NM_MPTCP_FLAGS_DEFAULT ((NMMptcpFlags) (NM_MPTCP_FLAGS_ENABLED | NM_MPTCP_FLAGS_SUBFLOW))
|
||||
#define _NM_MPTCP_FLAGS_DEFAULT \
|
||||
((NMMptcpFlags) (NM_MPTCP_FLAGS_ENABLED | NM_MPTCP_FLAGS_SUBFLOW | NM_MPTCP_FLAGS_LAMINAR))
|
||||
|
||||
NMMptcpFlags nm_mptcp_flags_normalize(NMMptcpFlags flags);
|
||||
|
||||
|
|
|
|||
|
|
@ -810,6 +810,10 @@
|
|||
dbus-type="i"
|
||||
gprop-type="gint"
|
||||
/>
|
||||
<property name="dnssec"
|
||||
dbus-type="i"
|
||||
gprop-type="gint"
|
||||
/>
|
||||
<property name="down-on-poweroff"
|
||||
dbus-type="i"
|
||||
gprop-type="gint"
|
||||
|
|
@ -1393,6 +1397,10 @@
|
|||
dbus-type="s"
|
||||
gprop-type="gchararray"
|
||||
/>
|
||||
<property name="device-uid"
|
||||
dbus-type="s"
|
||||
gprop-type="gchararray"
|
||||
/>
|
||||
<property name="home-only"
|
||||
dbus-type="b"
|
||||
gprop-type="gboolean"
|
||||
|
|
@ -1516,6 +1524,10 @@
|
|||
<setting name="hsr"
|
||||
gtype="NMSettingHsr"
|
||||
>
|
||||
<property name="interlink"
|
||||
dbus-type="s"
|
||||
gprop-type="gchararray"
|
||||
/>
|
||||
<property name="multicast-spec"
|
||||
dbus-type="u"
|
||||
gprop-type="guint"
|
||||
|
|
@ -1528,6 +1540,10 @@
|
|||
dbus-type="s"
|
||||
gprop-type="gchararray"
|
||||
/>
|
||||
<property name="protocol-version"
|
||||
dbus-type="i"
|
||||
gprop-type="gint"
|
||||
/>
|
||||
<property name="prp"
|
||||
dbus-type="b"
|
||||
gprop-type="gboolean"
|
||||
|
|
|
|||
|
|
@ -3133,6 +3133,86 @@ need_secrets(NMSetting *setting, gboolean check_rerequest)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
get_private_files(NMSetting *setting, GPtrArray *files)
|
||||
{
|
||||
const struct {
|
||||
const char *property;
|
||||
NMSetting8021xCKScheme (*get_scheme_func)(NMSetting8021x *);
|
||||
const char *(*get_path_func)(NMSetting8021x *);
|
||||
} cert_props[] = {
|
||||
{NM_SETTING_802_1X_CA_CERT,
|
||||
nm_setting_802_1x_get_ca_cert_scheme,
|
||||
nm_setting_802_1x_get_ca_cert_path},
|
||||
{NM_SETTING_802_1X_CLIENT_CERT,
|
||||
nm_setting_802_1x_get_client_cert_scheme,
|
||||
nm_setting_802_1x_get_client_cert_path},
|
||||
{NM_SETTING_802_1X_PRIVATE_KEY,
|
||||
nm_setting_802_1x_get_private_key_scheme,
|
||||
nm_setting_802_1x_get_private_key_path},
|
||||
{NM_SETTING_802_1X_PHASE2_CA_CERT,
|
||||
nm_setting_802_1x_get_phase2_ca_cert_scheme,
|
||||
nm_setting_802_1x_get_phase2_ca_cert_path},
|
||||
{NM_SETTING_802_1X_PHASE2_CLIENT_CERT,
|
||||
nm_setting_802_1x_get_phase2_client_cert_scheme,
|
||||
nm_setting_802_1x_get_phase2_client_cert_path},
|
||||
{NM_SETTING_802_1X_PHASE2_PRIVATE_KEY,
|
||||
nm_setting_802_1x_get_phase2_private_key_scheme,
|
||||
nm_setting_802_1x_get_phase2_private_key_path},
|
||||
};
|
||||
NMSetting8021x *s_8021x = NM_SETTING_802_1X(setting);
|
||||
const char *path;
|
||||
guint i;
|
||||
|
||||
if (NM_MORE_ASSERT_ONCE(5)) {
|
||||
GObjectClass *klass;
|
||||
gs_free GParamSpec **properties = NULL;
|
||||
guint n_properties;
|
||||
gboolean found;
|
||||
guint j;
|
||||
|
||||
/* Check that all the properties in the setting with flag CERT_KEY_FILE
|
||||
* are listed in the table, and vice versa. */
|
||||
|
||||
klass = G_OBJECT_GET_CLASS(setting);
|
||||
|
||||
properties = g_object_class_list_properties(klass, &n_properties);
|
||||
for (i = 0; i < n_properties; i++) {
|
||||
if (!(properties[i]->flags & NM_SETTING_PARAM_CERT_KEY_FILE))
|
||||
continue;
|
||||
|
||||
found = FALSE;
|
||||
for (j = 0; j < G_N_ELEMENTS(cert_props); j++) {
|
||||
if (nm_streq0(properties[i]->name, cert_props[j].property)) {
|
||||
found = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
nm_assert(found);
|
||||
}
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS(cert_props); i++) {
|
||||
GParamSpec *prop;
|
||||
|
||||
prop = g_object_class_find_property(klass, cert_props[i].property);
|
||||
nm_assert(prop);
|
||||
nm_assert(prop->flags & NM_SETTING_PARAM_CERT_KEY_FILE);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS(cert_props); i++) {
|
||||
if (cert_props[i].get_scheme_func(s_8021x) == NM_SETTING_802_1X_CK_SCHEME_PATH) {
|
||||
path = cert_props[i].get_path_func(s_8021x);
|
||||
if (path) {
|
||||
g_ptr_array_add(files, (gpointer) path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
|
|
@ -3223,8 +3303,9 @@ nm_setting_802_1x_class_init(NMSetting8021xClass *klass)
|
|||
object_class->set_property = set_property;
|
||||
object_class->finalize = finalize;
|
||||
|
||||
setting_class->verify = verify;
|
||||
setting_class->need_secrets = need_secrets;
|
||||
setting_class->verify = verify;
|
||||
setting_class->need_secrets = need_secrets;
|
||||
setting_class->get_private_files = get_private_files;
|
||||
|
||||
/**
|
||||
* NMSetting8021x:eap:
|
||||
|
|
@ -3359,7 +3440,7 @@ nm_setting_802_1x_class_init(NMSetting8021xClass *klass)
|
|||
obj_properties,
|
||||
NM_SETTING_802_1X_CA_CERT,
|
||||
PROP_CA_CERT,
|
||||
NM_SETTING_PARAM_NONE,
|
||||
NM_SETTING_PARAM_CERT_KEY_FILE,
|
||||
NMSetting8021xPrivate,
|
||||
ca_cert);
|
||||
|
||||
|
|
@ -3556,7 +3637,7 @@ nm_setting_802_1x_class_init(NMSetting8021xClass *klass)
|
|||
obj_properties,
|
||||
NM_SETTING_802_1X_CLIENT_CERT,
|
||||
PROP_CLIENT_CERT,
|
||||
NM_SETTING_PARAM_NONE,
|
||||
NM_SETTING_PARAM_CERT_KEY_FILE,
|
||||
NMSetting8021xPrivate,
|
||||
client_cert);
|
||||
|
||||
|
|
@ -3803,7 +3884,7 @@ nm_setting_802_1x_class_init(NMSetting8021xClass *klass)
|
|||
obj_properties,
|
||||
NM_SETTING_802_1X_PHASE2_CA_CERT,
|
||||
PROP_PHASE2_CA_CERT,
|
||||
NM_SETTING_PARAM_NONE,
|
||||
NM_SETTING_PARAM_CERT_KEY_FILE,
|
||||
NMSetting8021xPrivate,
|
||||
phase2_ca_cert);
|
||||
|
||||
|
|
@ -4006,7 +4087,7 @@ nm_setting_802_1x_class_init(NMSetting8021xClass *klass)
|
|||
obj_properties,
|
||||
NM_SETTING_802_1X_PHASE2_CLIENT_CERT,
|
||||
PROP_PHASE2_CLIENT_CERT,
|
||||
NM_SETTING_PARAM_NONE,
|
||||
NM_SETTING_PARAM_CERT_KEY_FILE,
|
||||
NMSetting8021xPrivate,
|
||||
phase2_client_cert);
|
||||
|
||||
|
|
@ -4175,7 +4256,7 @@ nm_setting_802_1x_class_init(NMSetting8021xClass *klass)
|
|||
obj_properties,
|
||||
NM_SETTING_802_1X_PRIVATE_KEY,
|
||||
PROP_PRIVATE_KEY,
|
||||
NM_SETTING_PARAM_NONE,
|
||||
NM_SETTING_PARAM_CERT_KEY_FILE,
|
||||
NMSetting8021xPrivate,
|
||||
private_key);
|
||||
|
||||
|
|
@ -4276,7 +4357,7 @@ nm_setting_802_1x_class_init(NMSetting8021xClass *klass)
|
|||
obj_properties,
|
||||
NM_SETTING_802_1X_PHASE2_PRIVATE_KEY,
|
||||
PROP_PHASE2_PRIVATE_KEY,
|
||||
NM_SETTING_PARAM_NONE,
|
||||
NM_SETTING_PARAM_CERT_KEY_FILE,
|
||||
NMSetting8021xPrivate,
|
||||
phase2_private_key);
|
||||
|
||||
|
|
|
|||
|
|
@ -472,17 +472,17 @@ nm_bridge_vlan_to_str(const NMBridgeVlan *vlan, GError **error)
|
|||
NMBridgeVlan *
|
||||
nm_bridge_vlan_from_str(const char *str, GError **error)
|
||||
{
|
||||
NMBridgeVlan *vlan = NULL;
|
||||
gs_free const char **tokens = NULL;
|
||||
guint i, vid_start, vid_end = 0;
|
||||
gboolean pvid = FALSE;
|
||||
gboolean untagged = FALSE;
|
||||
char *c;
|
||||
NMBridgeVlan *vlan = NULL;
|
||||
gs_free char **tokens = NULL;
|
||||
guint i, vid_start, vid_end = 0;
|
||||
gboolean pvid = FALSE;
|
||||
gboolean untagged = FALSE;
|
||||
char *c;
|
||||
|
||||
g_return_val_if_fail(str, NULL);
|
||||
g_return_val_if_fail(!error || !*error, NULL);
|
||||
|
||||
tokens = nm_utils_escaped_tokens_split(str, NM_ASCII_SPACES);
|
||||
tokens = (char **) nm_utils_escaped_tokens_split(str, NM_ASCII_SPACES);
|
||||
if (!tokens || !tokens[0]) {
|
||||
g_set_error_literal(error,
|
||||
NM_CONNECTION_ERROR,
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ NM_GOBJECT_PROPERTIES_DEFINE(NMSettingConnection,
|
|||
PROP_MDNS,
|
||||
PROP_LLMNR,
|
||||
PROP_DNS_OVER_TLS,
|
||||
PROP_DNSSEC,
|
||||
PROP_MPTCP_FLAGS,
|
||||
PROP_STABLE_ID,
|
||||
PROP_AUTH_RETRIES,
|
||||
|
|
@ -103,6 +104,7 @@ typedef struct {
|
|||
gint32 mdns;
|
||||
gint32 llmnr;
|
||||
gint32 dns_over_tls;
|
||||
gint32 dnssec;
|
||||
gint32 wait_device_timeout;
|
||||
gint32 lldp;
|
||||
gint32 wait_activation_delay;
|
||||
|
|
@ -431,6 +433,47 @@ nm_setting_connection_permissions_user_allowed_by_uid(NMSettingConnection *setti
|
|||
return _permissions_user_allowed(setting, NULL, uid);
|
||||
}
|
||||
|
||||
guint
|
||||
_nm_setting_connection_get_num_permissions_users(NMSettingConnection *setting)
|
||||
{
|
||||
NMSettingConnectionPrivate *priv;
|
||||
guint i;
|
||||
guint count = 0;
|
||||
|
||||
nm_assert(NM_IS_SETTING_CONNECTION(setting));
|
||||
priv = NM_SETTING_CONNECTION_GET_PRIVATE(setting);
|
||||
|
||||
for (i = 0; priv->permissions && i < priv->permissions->len; i++) {
|
||||
const Permission *permission = &nm_g_array_index(priv->permissions, Permission, i);
|
||||
|
||||
if (permission->ptype == PERM_TYPE_USER) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
const char *
|
||||
_nm_setting_connection_get_first_permissions_user(NMSettingConnection *setting)
|
||||
{
|
||||
NMSettingConnectionPrivate *priv;
|
||||
guint i;
|
||||
|
||||
nm_assert(NM_IS_SETTING_CONNECTION(setting));
|
||||
priv = NM_SETTING_CONNECTION_GET_PRIVATE(setting);
|
||||
|
||||
for (i = 0; priv->permissions && i < priv->permissions->len; i++) {
|
||||
const Permission *permission = &nm_g_array_index(priv->permissions, Permission, i);
|
||||
|
||||
if (permission->ptype == PERM_TYPE_USER) {
|
||||
return permission->item;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_connection_add_permission:
|
||||
* @setting: the #NMSettingConnection
|
||||
|
|
@ -1293,6 +1336,22 @@ nm_setting_connection_get_dns_over_tls(NMSettingConnection *setting)
|
|||
return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->dns_over_tls;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_connection_get_dnssec:
|
||||
* @setting: the #NMSettingConnection
|
||||
*
|
||||
* Returns: the #NMSettingConnection:dnssec property of the setting.
|
||||
*
|
||||
* Since: 1.56
|
||||
**/
|
||||
NMSettingConnectionDnssec
|
||||
nm_setting_connection_get_dnssec(NMSettingConnection *setting)
|
||||
{
|
||||
g_return_val_if_fail(NM_IS_SETTING_CONNECTION(setting), NM_SETTING_CONNECTION_DNSSEC_DEFAULT);
|
||||
|
||||
return NM_SETTING_CONNECTION_GET_PRIVATE(setting)->dnssec;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_connection_get_mptcp_flags:
|
||||
* @setting: the #NMSettingConnection
|
||||
|
|
@ -3406,6 +3465,33 @@ nm_setting_connection_class_init(NMSettingConnectionClass *klass)
|
|||
NMSettingConnectionPrivate,
|
||||
dns_over_tls);
|
||||
|
||||
/**
|
||||
* NMSettingConnection:dnssec:
|
||||
*
|
||||
* Whether DNSSEC (dnssec) is enabled for the connection.
|
||||
*
|
||||
* The permitted values are: "yes" (2) use DNSSEC and disable fallback,
|
||||
* "allow-downgrade" (1) use DNSSEC but allow fallback if the server does not support it,
|
||||
* "no" (0) don't ever use DNSSEC.
|
||||
* The effect of "default" (-1) depends on the dns plugin used.
|
||||
* Systemd-resolved uses its global setting in this case.
|
||||
*
|
||||
* This feature requires a plugin which supports DNSSEC. Otherwise, the
|
||||
* setting has no effect. One such plugin is systemd-resolved.
|
||||
*
|
||||
* Since: 1.56
|
||||
**/
|
||||
_nm_setting_property_define_direct_enum(properties_override,
|
||||
obj_properties,
|
||||
NM_SETTING_CONNECTION_DNSSEC,
|
||||
PROP_DNSSEC,
|
||||
NM_TYPE_SETTING_CONNECTION_DNSSEC,
|
||||
NM_SETTING_CONNECTION_DNSSEC_DEFAULT,
|
||||
NM_SETTING_PARAM_NONE,
|
||||
NULL,
|
||||
NMSettingConnectionPrivate,
|
||||
dnssec);
|
||||
|
||||
/* Notes about "mptcp-flags":
|
||||
*
|
||||
* It is a bit odd that NMMptcpFlags mixes flags with different purposes:
|
||||
|
|
@ -3413,7 +3499,7 @@ nm_setting_connection_class_init(NMSettingConnectionClass *klass)
|
|||
* - "disabled", "disabled-on-local-iface", "enable": whether MPTCP handling
|
||||
* is enabled. The flag "disabled-on-local-iface" enables it based on whether
|
||||
* the interface has a default route.
|
||||
* - "signal", "subflow", "backup", "fullmesh": the endpoint flags
|
||||
* - "signal", "subflow", "backup", "fullmesh", "laminar": the endpoint flags
|
||||
* that are used.
|
||||
*
|
||||
* The reason is, that it is useful to have one "connection.mptcp-flags"
|
||||
|
|
@ -3473,7 +3559,8 @@ nm_setting_connection_class_init(NMSettingConnectionClass *klass)
|
|||
*
|
||||
* When MPTCP handling is enabled then endpoints are configured with
|
||||
* the specified address flags "signal" (0x10), "subflow" (0x20), "backup" (0x40),
|
||||
* "fullmesh" (0x80). See ip-mptcp(8) manual for additional information about the flags.
|
||||
* "fullmesh" (0x80), "laminar" (0x100). See ip-mptcp(8) manual for
|
||||
* additional information about the flags.
|
||||
*
|
||||
* If the flags are zero (0x0), the global connection default from NetworkManager.conf is
|
||||
* honored. If still unspecified, the fallback is "enabled,subflow".
|
||||
|
|
|
|||
|
|
@ -47,7 +47,8 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE(PROP_AUTO_CONFIG,
|
|||
PROP_INITIAL_EPS_REFUSE_PAP,
|
||||
PROP_INITIAL_EPS_REFUSE_CHAP,
|
||||
PROP_INITIAL_EPS_REFUSE_MSCHAP,
|
||||
PROP_INITIAL_EPS_REFUSE_MSCHAPV2, );
|
||||
PROP_INITIAL_EPS_REFUSE_MSCHAPV2,
|
||||
PROP_DEVICE_UID, );
|
||||
|
||||
typedef struct {
|
||||
char *number;
|
||||
|
|
@ -75,6 +76,7 @@ typedef struct {
|
|||
bool auto_config;
|
||||
bool home_only;
|
||||
bool initial_eps_config;
|
||||
char *device_uid;
|
||||
} NMSettingGsmPrivate;
|
||||
|
||||
/**
|
||||
|
|
@ -465,6 +467,22 @@ nm_setting_gsm_get_initial_eps_refuse_mschapv2(NMSettingGsm *setting)
|
|||
return NM_SETTING_GSM_GET_PRIVATE(setting)->initial_eps_refuse_mschapv2;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_gsm_get_device_uid:
|
||||
* @setting: the #NMSettingGsm
|
||||
*
|
||||
* Returns: the #NMSettingGsm:device-uid property of the setting
|
||||
*
|
||||
* Since: 1.56
|
||||
**/
|
||||
const char *
|
||||
nm_setting_gsm_get_device_uid(NMSettingGsm *setting)
|
||||
{
|
||||
g_return_val_if_fail(NM_IS_SETTING_GSM(setting), NULL);
|
||||
|
||||
return NM_SETTING_GSM_GET_PRIVATE(setting)->device_uid;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_verify_apn(const char *apn, gboolean allow_empty, const char *property_name, GError **error)
|
||||
{
|
||||
|
|
@ -1149,6 +1167,26 @@ nm_setting_gsm_class_init(NMSettingGsmClass *klass)
|
|||
NMSettingGsmPrivate,
|
||||
initial_eps_refuse_mschapv2);
|
||||
|
||||
/**
|
||||
* NMSettingGsm:device-uid:
|
||||
*
|
||||
* The device UID (as given by the WWAN management service) which this
|
||||
* connection applies to. In contrast to #NMSettingGsm:device-id, which is
|
||||
* an inherent property of the connected device, this setting refers to
|
||||
* a property set by a UDEV-rule. Refer to the "Common udev tags" ->
|
||||
* "ID_MM_PHYSDEV_UID" documentation of ModemManager. If given, the
|
||||
* connection will only apply to the specified device.
|
||||
*
|
||||
* Since: 1.56
|
||||
**/
|
||||
_nm_setting_property_define_direct_string(properties_override,
|
||||
obj_properties,
|
||||
NM_SETTING_GSM_DEVICE_UID,
|
||||
PROP_DEVICE_UID,
|
||||
NM_SETTING_PARAM_NONE,
|
||||
NMSettingGsmPrivate,
|
||||
device_uid);
|
||||
|
||||
/* Ignore incoming deprecated properties */
|
||||
_nm_properties_override_dbus(properties_override,
|
||||
"allowed-bands",
|
||||
|
|
|
|||
|
|
@ -23,12 +23,20 @@
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
NM_GOBJECT_PROPERTIES_DEFINE(NMSettingHsr, PROP_PORT1, PROP_PORT2, PROP_MULTICAST_SPEC, PROP_PRP, );
|
||||
NM_GOBJECT_PROPERTIES_DEFINE(NMSettingHsr,
|
||||
PROP_PORT1,
|
||||
PROP_PORT2,
|
||||
PROP_MULTICAST_SPEC,
|
||||
PROP_PRP,
|
||||
PROP_PROTOCOL_VERSION,
|
||||
PROP_INTERLINK, );
|
||||
|
||||
typedef struct {
|
||||
char *port1;
|
||||
char *port2;
|
||||
char *interlink;
|
||||
guint32 multicast_spec;
|
||||
int protocol_version;
|
||||
bool prp;
|
||||
} NMSettingHsrPrivate;
|
||||
|
||||
|
|
@ -117,6 +125,38 @@ nm_setting_hsr_get_prp(NMSettingHsr *setting)
|
|||
return NM_SETTING_HSR_GET_PRIVATE(setting)->prp;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_hsr_get_protocol_version:
|
||||
* @setting: the #NMSettingHsr
|
||||
*
|
||||
* Returns: the #NMSettingHsr:protocol-version property of the setting
|
||||
*
|
||||
* Since: 1.56
|
||||
**/
|
||||
NMSettingHsrProtocolVersion
|
||||
nm_setting_hsr_get_protocol_version(NMSettingHsr *setting)
|
||||
{
|
||||
g_return_val_if_fail(NM_IS_SETTING_HSR(setting), NM_SETTING_HSR_PROTOCOL_VERSION_DEFAULT);
|
||||
|
||||
return NM_SETTING_HSR_GET_PRIVATE(setting)->protocol_version;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_hsr_get_interlink:
|
||||
* @setting: the #NMSettingHsr
|
||||
*
|
||||
* Returns: the #NMSettingHsr:interlink property of the setting
|
||||
*
|
||||
* Since: 1.56
|
||||
**/
|
||||
const char *
|
||||
nm_setting_hsr_get_interlink(NMSettingHsr *setting)
|
||||
{
|
||||
g_return_val_if_fail(NM_IS_SETTING_HSR(setting), NULL);
|
||||
|
||||
return NM_SETTING_HSR_GET_PRIVATE(setting)->interlink;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static gboolean
|
||||
|
|
@ -160,6 +200,18 @@ verify(NMSetting *setting, NMConnection *connection, GError **error)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
if (priv->prp && priv->protocol_version != NM_SETTING_HSR_PROTOCOL_VERSION_DEFAULT) {
|
||||
g_set_error(error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
_("HSR protocol cannot be configured for PRP interfaces"));
|
||||
g_prefix_error(error,
|
||||
"%s.%s: ",
|
||||
NM_SETTING_HSR_SETTING_NAME,
|
||||
NM_SETTING_HSR_PROTOCOL_VERSION);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -260,6 +312,42 @@ nm_setting_hsr_class_init(NMSettingHsrClass *klass)
|
|||
NMSettingHsr,
|
||||
_priv.prp);
|
||||
|
||||
/**
|
||||
* NMSettingHsr:protocol-version:
|
||||
*
|
||||
* Configures the protocol version to be used for the HSR/PRP interface.
|
||||
* %NM_SETTING_HSR_PROTOCOL_VERSION_DEFAULT sets the protocol version to the default version for the protocol.
|
||||
* %NM_SETTING_HSR_PROTOCOL_VERSION_HSR_2010 sets the protocol version to HSRv0 (IEC 62439-3:2010).
|
||||
* %NM_SETTING_HSR_PROTOCOL_VERSION_HSR_2012 sets the protocol version to HSRv1 (IEC 62439-3:2012).
|
||||
*
|
||||
* Since: 1.56
|
||||
**/
|
||||
_nm_setting_property_define_direct_enum(properties_override,
|
||||
obj_properties,
|
||||
NM_SETTING_HSR_PROTOCOL_VERSION,
|
||||
PROP_PROTOCOL_VERSION,
|
||||
NM_TYPE_SETTING_HSR_PROTOCOL_VERSION,
|
||||
NM_SETTING_HSR_PROTOCOL_VERSION_DEFAULT,
|
||||
NM_SETTING_PARAM_NONE,
|
||||
NULL,
|
||||
NMSettingHsr,
|
||||
_priv.protocol_version);
|
||||
|
||||
/**
|
||||
* NMSettingHsr:interlink:
|
||||
*
|
||||
* The optional interlink port name of the HSR interface.
|
||||
*
|
||||
* Since: 1.56
|
||||
**/
|
||||
_nm_setting_property_define_direct_string(properties_override,
|
||||
obj_properties,
|
||||
NM_SETTING_HSR_INTERLINK,
|
||||
PROP_INTERLINK,
|
||||
NM_SETTING_PARAM_INFERRABLE,
|
||||
NMSettingHsr,
|
||||
_priv.interlink);
|
||||
|
||||
g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties);
|
||||
|
||||
_nm_setting_class_commit(setting_class, NM_META_SETTING_TYPE_HSR, NULL, properties_override, 0);
|
||||
|
|
|
|||
|
|
@ -6740,7 +6740,7 @@ nm_setting_ip_config_class_init(NMSettingIPConfigClass *klass)
|
|||
* NMSettingIPConfig:gateway:
|
||||
*
|
||||
* The gateway associated with this configuration. This is only meaningful
|
||||
* if #NMSettingIPConfig:addresses is also set.
|
||||
* if addresses are also set on the device.
|
||||
*
|
||||
* Setting the gateway causes NetworkManager to configure a standard default route
|
||||
* with the gateway as next hop. This is ignored if #NMSettingIPConfig:never-default
|
||||
|
|
|
|||
|
|
@ -154,6 +154,11 @@ struct _NMSettingClass {
|
|||
guint /* NMSettingParseFlags */ parse_flags,
|
||||
GError **error);
|
||||
|
||||
/* returns a list of certificate/key files referenced in the connection.
|
||||
* When the connection is private, we need to verify that the owner of
|
||||
* the connection has access to them. */
|
||||
void (*get_private_files)(NMSetting *setting, GPtrArray *files);
|
||||
|
||||
const struct _NMMetaSettingInfo *setting_info;
|
||||
};
|
||||
|
||||
|
|
@ -334,6 +339,11 @@ struct _NMRange {
|
|||
*/
|
||||
#define NM_SETTING_PARAM_TO_DBUS_IGNORE_FLAGS (1 << (7 + G_PARAM_USER_SHIFT))
|
||||
|
||||
/* The property can refer to a certificate or key stored on disk. As such,
|
||||
* special care is needed when accessing the file for private connections.
|
||||
*/
|
||||
#define NM_SETTING_PARAM_CERT_KEY_FILE (1 << (8 + G_PARAM_USER_SHIFT))
|
||||
|
||||
extern const NMSettInfoPropertType nm_sett_info_propert_type_setting_name;
|
||||
extern const NMSettInfoPropertType nm_sett_info_propert_type_deprecated_interface_name;
|
||||
extern const NMSettInfoPropertType nm_sett_info_propert_type_deprecated_ignore_i;
|
||||
|
|
@ -859,9 +869,10 @@ _nm_properties_override(GArray *properties_override, const NMSettInfoProperty *p
|
|||
{ \
|
||||
GParamSpec *_param_spec; \
|
||||
\
|
||||
G_STATIC_ASSERT(!NM_FLAGS_ANY((param_flags), \
|
||||
~(NM_SETTING_PARAM_SECRET | NM_SETTING_PARAM_INFERRABLE \
|
||||
| NM_SETTING_PARAM_FUZZY_IGNORE))); \
|
||||
G_STATIC_ASSERT( \
|
||||
!NM_FLAGS_ANY((param_flags), \
|
||||
~(NM_SETTING_PARAM_SECRET | NM_SETTING_PARAM_INFERRABLE \
|
||||
| NM_SETTING_PARAM_FUZZY_IGNORE | NM_SETTING_PARAM_CERT_KEY_FILE))); \
|
||||
\
|
||||
_param_spec = g_param_spec_boxed("" prop_name "", \
|
||||
"", \
|
||||
|
|
|
|||
|
|
@ -2262,6 +2262,34 @@ init_from_dbus(NMSetting *setting,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
get_private_files(NMSetting *setting, GPtrArray *files)
|
||||
{
|
||||
if (NM_MORE_ASSERTS) {
|
||||
GParamSpec **properties;
|
||||
guint n_properties;
|
||||
int i;
|
||||
|
||||
properties = g_object_class_list_properties(G_OBJECT_GET_CLASS(setting), &n_properties);
|
||||
for (i = 0; i < n_properties; i++) {
|
||||
if (properties[i]->flags & NM_SETTING_PARAM_CERT_KEY_FILE) {
|
||||
/* Certificates and keys needs special handling, see setting 802.1X */
|
||||
nm_assert_not_reached();
|
||||
}
|
||||
}
|
||||
g_free(properties);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_nm_setting_get_private_files(NMSetting *setting, GPtrArray *files)
|
||||
{
|
||||
g_return_if_fail(NM_IS_SETTING(setting));
|
||||
g_return_if_fail(files);
|
||||
|
||||
NM_SETTING_GET_CLASS(setting)->get_private_files(setting, files);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_get_dbus_property_type:
|
||||
* @setting: an #NMSetting
|
||||
|
|
@ -4495,7 +4523,7 @@ nm_range_from_str(const char *str, GError **error)
|
|||
gs_free char *str_free = NULL;
|
||||
guint64 start;
|
||||
guint64 end = 0;
|
||||
char *c;
|
||||
const char *c;
|
||||
|
||||
g_return_val_if_fail(str, NULL);
|
||||
g_return_val_if_fail(!error || !*error, NULL);
|
||||
|
|
@ -4672,6 +4700,7 @@ nm_setting_class_init(NMSettingClass *setting_class)
|
|||
setting_class->enumerate_values = enumerate_values;
|
||||
setting_class->aggregate = aggregate;
|
||||
setting_class->init_from_dbus = init_from_dbus;
|
||||
setting_class->get_private_files = get_private_files;
|
||||
|
||||
/**
|
||||
* NMSetting:name:
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
#include <linux/pkt_sched.h>
|
||||
#include <linux/if_infiniband.h>
|
||||
|
||||
#include "libnm-glib-aux/nm-io-utils.h"
|
||||
#include "libnm-glib-aux/nm-uuid.h"
|
||||
#include "libnm-glib-aux/nm-json-aux.h"
|
||||
#include "libnm-glib-aux/nm-str-buf.h"
|
||||
|
|
@ -6195,3 +6196,258 @@ nm_utils_ensure_gtypes(void)
|
|||
for (meta_type = 0; meta_type < _NM_META_SETTING_TYPE_NUM; meta_type++)
|
||||
nm_meta_setting_infos[meta_type].get_setting_gtype();
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
GPid pid;
|
||||
GSource *child_watch_source;
|
||||
GMainLoop *loop;
|
||||
GError *error;
|
||||
|
||||
int child_stdout;
|
||||
int child_stderr;
|
||||
|
||||
GSource *output_source;
|
||||
GSource *error_source;
|
||||
|
||||
NMStrBuf output_buffer;
|
||||
NMStrBuf error_buffer;
|
||||
} HelperInfo;
|
||||
|
||||
static void
|
||||
helper_complete(HelperInfo *info, GError *error_take)
|
||||
{
|
||||
if (error_take) {
|
||||
if (!info->error)
|
||||
info->error = error_take;
|
||||
else
|
||||
g_error_free(error_take);
|
||||
}
|
||||
|
||||
if (info->output_source || info->error_source || info->pid != -1) {
|
||||
/* Wait that the pipe is closed and process has terminated */
|
||||
return;
|
||||
}
|
||||
|
||||
if (info->error && info->error_buffer.len > 0) {
|
||||
/* Prefer the message from stderr as it's more informative */
|
||||
g_error_free(info->error);
|
||||
info->error = g_error_new(NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_FAILED,
|
||||
"%s",
|
||||
nm_str_buf_get_str(&info->error_buffer));
|
||||
}
|
||||
|
||||
g_main_loop_quit(info->loop);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
helper_have_err_data(int fd, GIOCondition condition, gpointer user_data)
|
||||
{
|
||||
HelperInfo *info = user_data;
|
||||
gssize n_read;
|
||||
GError *error = NULL;
|
||||
|
||||
n_read = nm_utils_fd_read(fd, &info->error_buffer);
|
||||
|
||||
if (n_read > 0)
|
||||
return G_SOURCE_CONTINUE;
|
||||
|
||||
nm_clear_g_source_inst(&info->error_source);
|
||||
nm_clear_fd(&info->child_stderr);
|
||||
|
||||
if (n_read < 0) {
|
||||
error = g_error_new(NM_UTILS_ERROR,
|
||||
NM_UTILS_ERROR_UNKNOWN,
|
||||
"read from process returned %d (%s)",
|
||||
(int) -n_read,
|
||||
nm_strerror_native((int) -n_read));
|
||||
}
|
||||
|
||||
helper_complete(info, error);
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
helper_have_data(int fd, GIOCondition condition, gpointer user_data)
|
||||
{
|
||||
HelperInfo *info = user_data;
|
||||
gssize n_read;
|
||||
GError *error = NULL;
|
||||
|
||||
n_read = nm_utils_fd_read(fd, &info->output_buffer);
|
||||
|
||||
if (n_read > 0)
|
||||
return G_SOURCE_CONTINUE;
|
||||
|
||||
nm_clear_g_source_inst(&info->output_source);
|
||||
nm_clear_fd(&info->child_stdout);
|
||||
|
||||
if (n_read < 0) {
|
||||
error = g_error_new(NM_UTILS_ERROR,
|
||||
NM_UTILS_ERROR_UNKNOWN,
|
||||
"read from process returned %d (%s)",
|
||||
(int) -n_read,
|
||||
nm_strerror_native((int) -n_read));
|
||||
}
|
||||
|
||||
helper_complete(info, error);
|
||||
return G_SOURCE_CONTINUE;
|
||||
}
|
||||
|
||||
static void
|
||||
helper_child_terminated(GPid pid, int status, gpointer user_data)
|
||||
{
|
||||
HelperInfo *info = user_data;
|
||||
gs_free char *status_desc = NULL;
|
||||
GError *error = NULL;
|
||||
|
||||
info->pid = -1;
|
||||
nm_clear_g_source_inst(&info->child_watch_source);
|
||||
|
||||
if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
|
||||
if (!status_desc)
|
||||
status_desc = nm_utils_get_process_exit_status_desc(status);
|
||||
error =
|
||||
g_error_new(NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, "helper process %s", status_desc);
|
||||
}
|
||||
|
||||
helper_complete(info, error);
|
||||
}
|
||||
|
||||
#define RUN_CERT_DIR NMRUNDIR "/cert"
|
||||
|
||||
/**
|
||||
* nm_utils_copy_cert_as_user:
|
||||
* @filename: the file name of the certificate or key to copy
|
||||
* @user: the user to impersonate when reading the file
|
||||
* @error: (nullable): return location for a #GError, or %NULL
|
||||
*
|
||||
* Reads @filename on behalf of user @user and writes the
|
||||
* content to a new file in /run/NetworkManager/cert/.
|
||||
* The new file has permission 600 and is owned by root.
|
||||
*
|
||||
* This function is useful for VPN plugins that run as root and need
|
||||
* to verify that the user owning the connection (the one listed in the
|
||||
* connection.permissions property) can access the file.
|
||||
*
|
||||
* Returns: (transfer full): the name of the new temporary file. Or %NULL
|
||||
* if an error occurred, including when the given user can't access the
|
||||
* file.
|
||||
*
|
||||
* Since: 1.56
|
||||
*/
|
||||
char *
|
||||
nm_utils_copy_cert_as_user(const char *filename, const char *user, GError **error)
|
||||
{
|
||||
gs_unref_bytes GBytes *bytes = NULL;
|
||||
char dst_path[] = RUN_CERT_DIR "/XXXXXX";
|
||||
HelperInfo info = {
|
||||
.child_stdout = -1,
|
||||
.child_stderr = -1,
|
||||
};
|
||||
GMainContext *context;
|
||||
int fd = -1;
|
||||
|
||||
g_return_val_if_fail(filename, NULL);
|
||||
g_return_val_if_fail(user, NULL);
|
||||
g_return_val_if_fail(!error || !*error, NULL);
|
||||
|
||||
if (geteuid() != 0) {
|
||||
g_set_error_literal(error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
_("This function needs to be called by root"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!g_spawn_async_with_pipes(
|
||||
"/",
|
||||
(char **)
|
||||
NM_MAKE_STRV(LIBEXECDIR "/nm-libnm-helper", "read-file-as-user", filename, user),
|
||||
(char **) NM_MAKE_STRV(),
|
||||
G_SPAWN_CLOEXEC_PIPES | G_SPAWN_DO_NOT_REAP_CHILD,
|
||||
NULL,
|
||||
NULL,
|
||||
&info.pid,
|
||||
NULL,
|
||||
&info.child_stdout,
|
||||
&info.child_stderr,
|
||||
error)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
context = g_main_context_new();
|
||||
info.loop = g_main_loop_new(context, FALSE);
|
||||
|
||||
/* Watch process */
|
||||
info.child_watch_source = nm_g_child_watch_source_new(info.pid,
|
||||
G_PRIORITY_DEFAULT,
|
||||
helper_child_terminated,
|
||||
&info,
|
||||
NULL);
|
||||
g_source_attach(info.child_watch_source, context);
|
||||
|
||||
/* Watch stdout */
|
||||
info.output_buffer = NM_STR_BUF_INIT(0, FALSE);
|
||||
info.output_source = nm_g_unix_fd_source_new(info.child_stdout,
|
||||
G_IO_IN | G_IO_ERR | G_IO_HUP,
|
||||
G_PRIORITY_DEFAULT,
|
||||
helper_have_data,
|
||||
&info,
|
||||
NULL);
|
||||
g_source_attach(info.output_source, context);
|
||||
|
||||
/* Watch stderr */
|
||||
info.error_buffer = NM_STR_BUF_INIT(0, FALSE);
|
||||
info.error_source = nm_g_unix_fd_source_new(info.child_stderr,
|
||||
G_IO_IN | G_IO_ERR | G_IO_HUP,
|
||||
G_PRIORITY_DEFAULT,
|
||||
helper_have_err_data,
|
||||
&info,
|
||||
NULL);
|
||||
g_source_attach(info.error_source, context);
|
||||
|
||||
/* Wait termination */
|
||||
g_main_loop_run(info.loop);
|
||||
g_clear_pointer(&info.loop, g_main_loop_unref);
|
||||
g_clear_pointer(&context, g_main_context_unref);
|
||||
|
||||
if (info.error) {
|
||||
nm_str_buf_destroy(&info.output_buffer);
|
||||
nm_str_buf_destroy(&info.error_buffer);
|
||||
g_propagate_error(error, g_steal_pointer(&info.error));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Write the data to a new file */
|
||||
|
||||
bytes = g_bytes_new(nm_str_buf_get_str_unsafe(&info.output_buffer), info.output_buffer.len);
|
||||
nm_str_buf_destroy(&info.output_buffer);
|
||||
nm_str_buf_destroy(&info.error_buffer);
|
||||
|
||||
mkdir(RUN_CERT_DIR, 0600);
|
||||
fd = mkstemp(dst_path);
|
||||
if (fd < 0) {
|
||||
g_set_error_literal(error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
_("Failure creating the temporary file"));
|
||||
return NULL;
|
||||
}
|
||||
nm_close(fd);
|
||||
|
||||
if (!nm_utils_file_set_contents(dst_path,
|
||||
g_bytes_get_data(bytes, NULL),
|
||||
g_bytes_get_size(bytes),
|
||||
0600,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
error)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return g_strdup(dst_path);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -913,6 +913,29 @@ nm_vpn_plugin_info_supports_multiple(NMVpnPluginInfo *self)
|
|||
return _nm_utils_ascii_str_to_bool(s, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_vpn_plugin_info_supports_safe_private_file_access:
|
||||
* @self: plugin info instance
|
||||
*
|
||||
* Returns: %TRUE if the service supports reading files (certificates, keys) of
|
||||
* private connections in a safe way (i.e. checking user permissions), or
|
||||
if the service doesn't need to read any file from disk.
|
||||
*
|
||||
* Since: 1.56
|
||||
*/
|
||||
gboolean
|
||||
nm_vpn_plugin_info_supports_safe_private_file_access(NMVpnPluginInfo *self)
|
||||
{
|
||||
const char *s;
|
||||
|
||||
g_return_val_if_fail(NM_IS_VPN_PLUGIN_INFO(self), FALSE);
|
||||
|
||||
s = nm_vpn_plugin_info_lookup_property(self,
|
||||
NM_VPN_PLUGIN_INFO_KF_GROUP_CONNECTION,
|
||||
"supports-safe-private-file-access");
|
||||
return _nm_utils_ascii_str_to_bool(s, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_vpn_plugin_info_get_aliases:
|
||||
* @self: plugin info instance
|
||||
|
|
|
|||
|
|
@ -4032,6 +4032,7 @@ test_connection_diff_a_only(void)
|
|||
{NM_SETTING_CONNECTION_MDNS, NM_SETTING_DIFF_RESULT_IN_A},
|
||||
{NM_SETTING_CONNECTION_LLMNR, NM_SETTING_DIFF_RESULT_IN_A},
|
||||
{NM_SETTING_CONNECTION_DNS_OVER_TLS, NM_SETTING_DIFF_RESULT_IN_A},
|
||||
{NM_SETTING_CONNECTION_DNSSEC, NM_SETTING_DIFF_RESULT_IN_A},
|
||||
{NM_SETTING_CONNECTION_MPTCP_FLAGS, NM_SETTING_DIFF_RESULT_IN_A},
|
||||
{NM_SETTING_CONNECTION_MUD_URL, NM_SETTING_DIFF_RESULT_IN_A},
|
||||
{NM_SETTING_CONNECTION_WAIT_DEVICE_TIMEOUT, NM_SETTING_DIFF_RESULT_IN_A},
|
||||
|
|
|
|||
|
|
@ -1187,4 +1187,11 @@ gboolean nm_connection_need_secrets_for_rerequest(NMConnection *connection);
|
|||
|
||||
const GPtrArray *_nm_setting_ovs_port_get_trunks_arr(NMSettingOvsPort *self);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
guint _nm_setting_connection_get_num_permissions_users(NMSettingConnection *setting);
|
||||
const char *_nm_setting_connection_get_first_permissions_user(NMSettingConnection *setting);
|
||||
|
||||
void _nm_setting_get_private_files(NMSetting *setting, GPtrArray *files);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -145,8 +145,10 @@ typedef enum {
|
|||
* and not disable controls that require network access.
|
||||
* The graphical shells may hide the network accessibility indicator altogether
|
||||
* since no meaningful status indication can be provided.
|
||||
* @NM_STATE_ASLEEP: Networking is not enabled, the system is being suspended or
|
||||
* resumed from suspend.
|
||||
* @NM_STATE_ASLEEP: Deprecated: 1.56: Use %NM_STATE_DISABLED instead.
|
||||
* @NM_STATE_DISABLED: NetworkManager is disabled, either because the user requested
|
||||
* to disable networking or because the system is suspended or resuming from suspend.
|
||||
* Since: 1.56.
|
||||
* @NM_STATE_DISCONNECTED: There is no active network connection.
|
||||
* The graphical shell should indicate no network connectivity and the
|
||||
* applications should not attempt to access the network.
|
||||
|
|
@ -170,7 +172,8 @@ typedef enum {
|
|||
**/
|
||||
typedef enum {
|
||||
NM_STATE_UNKNOWN = 0,
|
||||
NM_STATE_ASLEEP = 10,
|
||||
NM_STATE_ASLEEP = 10, /* Deprecated */
|
||||
NM_STATE_DISABLED = 10,
|
||||
NM_STATE_DISCONNECTED = 20,
|
||||
NM_STATE_DISCONNECTING = 30,
|
||||
NM_STATE_CONNECTING = 40,
|
||||
|
|
@ -632,8 +635,10 @@ typedef enum {
|
|||
* not initialized by udev. Since: 1.48
|
||||
* @NM_DEVICE_STATE_REASON_UNMANAGED_QUITTING: The device is unmanaged because NetworkManager is
|
||||
* quitting. Since: 1.48
|
||||
* @NM_DEVICE_STATE_REASON_UNMANAGED_SLEEPING: The device is unmanaged because networking is
|
||||
* disabled or the system is suspended. Since: 1.48
|
||||
* @NM_DEVICE_STATE_REASON_UNMANAGED_SLEEPING: Since: 1.48. Deprecated: 1.56: Use
|
||||
* %NM_DEVICE_STATE_REASON_UNMANAGED_MANAGER_DISABLED instead.
|
||||
* @NM_DEVICE_STATE_REASON_UNMANAGED_MANAGER_DISABLED: The device is unmanaged because networking is
|
||||
* disabled or the system is suspended. Since: 1.56
|
||||
* @NM_DEVICE_STATE_REASON_UNMANAGED_USER_CONF: The device is unmanaged by user decision in
|
||||
* NetworkManager.conf ('unmanaged' in a [device*] section). Since: 1.48
|
||||
* @NM_DEVICE_STATE_REASON_UNMANAGED_USER_EXPLICIT: The device is unmanaged by explicit user
|
||||
|
|
@ -642,7 +647,9 @@ typedef enum {
|
|||
* via settings plugin ('unmanaged-devices' for keyfile or 'NM_CONTROLLED=no' for ifcfg-rh).
|
||||
* Since: 1.48
|
||||
* @NM_DEVICE_STATE_REASON_UNMANAGED_USER_UDEV: The device is unmanaged via udev rule. Since: 1.48
|
||||
|
||||
* @NM_DEVICE_STATE_REASON_NETWORKING_OFF: NetworkManager was disabled (networking off). Since: 1.56
|
||||
* @NM_DEVICE_STATE_REASON_MODEM_NO_OPERATOR_CODE: The modem's operator code wasn't available,
|
||||
* and auto-configuration was requested. Since: 1.56
|
||||
*
|
||||
* Device state change reason codes
|
||||
*/
|
||||
|
|
@ -720,11 +727,14 @@ typedef enum {
|
|||
NM_DEVICE_STATE_REASON_UNMANAGED_EXTERNAL_DOWN = 70,
|
||||
NM_DEVICE_STATE_REASON_UNMANAGED_LINK_NOT_INIT = 71,
|
||||
NM_DEVICE_STATE_REASON_UNMANAGED_QUITTING = 72,
|
||||
NM_DEVICE_STATE_REASON_UNMANAGED_SLEEPING = 73,
|
||||
NM_DEVICE_STATE_REASON_UNMANAGED_SLEEPING = 73, /* Deprecated */
|
||||
NM_DEVICE_STATE_REASON_UNMANAGED_MANAGER_DISABLED = 73,
|
||||
NM_DEVICE_STATE_REASON_UNMANAGED_USER_CONF = 74,
|
||||
NM_DEVICE_STATE_REASON_UNMANAGED_USER_EXPLICIT = 75,
|
||||
NM_DEVICE_STATE_REASON_UNMANAGED_USER_SETTINGS = 76,
|
||||
NM_DEVICE_STATE_REASON_UNMANAGED_USER_UDEV = 77,
|
||||
NM_DEVICE_STATE_REASON_NETWORKING_OFF = 78,
|
||||
NM_DEVICE_STATE_REASON_MODEM_NO_OPERATOR_CODE = 79,
|
||||
} NMDeviceStateReason;
|
||||
|
||||
/**
|
||||
|
|
@ -1450,6 +1460,16 @@ typedef enum /*< flags >*/ {
|
|||
* any additional addresses using the MPTCP ADD_ADDR sub-option, this will behave the same
|
||||
* as a plain subflow endpoint. When the peer does announce addresses, each received ADD_ADDR
|
||||
* sub-option will trigger creation of an additional subflow to generate a full mesh topology.
|
||||
* @NM_MPTCP_FLAGS_LAMINAR: Flag for the MPTCP endpoint. The endpoint will be
|
||||
* used to create new subflows from the associated address to additional
|
||||
* addresses announced by the other peer. This will be done if allowed by the
|
||||
* MPTCP limits, and if the associated address is not already being used by
|
||||
* another subflow from the same MPTCP connection. Note that the 'fullmesh'
|
||||
* flag takes precedence over the 'laminar' one. Without any of these two
|
||||
* flags, the path-manager will create new subflows to additional addresses
|
||||
* announced by the other peer by selecting the source address from the
|
||||
* routing tables, which is harder to configure if the announced address is
|
||||
* not known in advance. Since: 1.56
|
||||
*
|
||||
* Since: 1.40
|
||||
*/
|
||||
|
|
@ -1466,6 +1486,7 @@ typedef enum /*< flags >*/ {
|
|||
NM_MPTCP_FLAGS_SUBFLOW = 0x20,
|
||||
NM_MPTCP_FLAGS_BACKUP = 0x40,
|
||||
NM_MPTCP_FLAGS_FULLMESH = 0x80,
|
||||
NM_MPTCP_FLAGS_LAMINAR = 0x100,
|
||||
} NMMptcpFlags;
|
||||
|
||||
/* For secrets requests, hints starting with "x-vpn-message:" are a message to show, not
|
||||
|
|
|
|||
|
|
@ -256,6 +256,11 @@ GQuark nm_secret_agent_error_quark(void);
|
|||
* @NM_SETTINGS_ERROR_NOT_SUPPORTED_BY_PLUGIN: the requested operation is not
|
||||
* supported by the settings plugin currently in use for the specified object.
|
||||
* Since: 1.44.
|
||||
* @NM_SETTINGS_ERROR_FEATURE_DISABLED: the requested operation failed because it
|
||||
* requires a feature that is disabled in this build of NetworkManager.
|
||||
* Since: 1.56
|
||||
* @NM_SETTINGS_ERROR_FEATURE_REMOVED: the requested operation failed because it
|
||||
* requires a feature that is no longer supported. Since: 1.56
|
||||
*
|
||||
* Errors related to the settings/persistent configuration interface of
|
||||
* NetworkManager.
|
||||
|
|
@ -275,6 +280,8 @@ typedef enum {
|
|||
NM_SETTINGS_ERROR_INVALID_ARGUMENTS, /*< nick=InvalidArguments >*/
|
||||
NM_SETTINGS_ERROR_VERSION_ID_MISMATCH, /*< nick=VersionIdMismatch >*/
|
||||
NM_SETTINGS_ERROR_NOT_SUPPORTED_BY_PLUGIN, /*< nick=NotSupportedByPlugin >*/
|
||||
NM_SETTINGS_ERROR_FEATURE_DISABLED, /*< nick=FeatureDisabled >*/
|
||||
NM_SETTINGS_ERROR_FEATURE_REMOVED, /*< nick=FeatureRemoved >*/
|
||||
} NMSettingsError;
|
||||
|
||||
GQuark nm_settings_error_quark(void);
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ G_BEGIN_DECLS
|
|||
#define NM_SETTING_CONNECTION_MDNS "mdns"
|
||||
#define NM_SETTING_CONNECTION_LLMNR "llmnr"
|
||||
#define NM_SETTING_CONNECTION_DNS_OVER_TLS "dns-over-tls"
|
||||
#define NM_SETTING_CONNECTION_DNSSEC "dnssec"
|
||||
#define NM_SETTING_CONNECTION_MPTCP_FLAGS "mptcp-flags"
|
||||
#define NM_SETTING_CONNECTION_WAIT_DEVICE_TIMEOUT "wait-device-timeout"
|
||||
#define NM_SETTING_CONNECTION_MUD_URL "mud-url"
|
||||
|
|
@ -162,6 +163,24 @@ typedef enum {
|
|||
NM_SETTING_CONNECTION_DNS_OVER_TLS_YES = 2,
|
||||
} NMSettingConnectionDnsOverTls;
|
||||
|
||||
/**
|
||||
* NMSettingConnectionDnssec:
|
||||
* @NM_SETTING_CONNECTION_DNSSEC_DEFAULT: default value
|
||||
* @NM_SETTING_CONNECTION_DNSSEC_NO: disable DNSSEC
|
||||
* @NM_SETTING_CONNECTION_DNSSEC_ALLOW_DOWNGRADE: enable DNSSEC but allow fallback to non-DNSSEC mode
|
||||
* @NM_SETTING_CONNECTION_DNSSEC_YES: force enable DNSSEC
|
||||
*
|
||||
* #NMSettingConnectionDnssec values indicate whether DNSSEC should be enabled.
|
||||
*
|
||||
* Since: 1.56
|
||||
*/
|
||||
typedef enum {
|
||||
NM_SETTING_CONNECTION_DNSSEC_DEFAULT = -1,
|
||||
NM_SETTING_CONNECTION_DNSSEC_NO = 0,
|
||||
NM_SETTING_CONNECTION_DNSSEC_ALLOW_DOWNGRADE = 1,
|
||||
NM_SETTING_CONNECTION_DNSSEC_YES = 2,
|
||||
} NMSettingConnectionDnssec;
|
||||
|
||||
/**
|
||||
* NMSettingConnectionDownOnPoweroff:
|
||||
* @NM_SETTING_CONNECTION_DOWN_ON_POWEROFF_DEFAULT: default value
|
||||
|
|
@ -304,6 +323,9 @@ void nm_setting_connection_clear_ip_ping_addresses(NMSettingConnection *setting)
|
|||
NM_AVAILABLE_IN_1_52
|
||||
NMTernary nm_setting_connection_get_ip_ping_addresses_require_all(NMSettingConnection *setting);
|
||||
|
||||
NM_AVAILABLE_IN_1_56
|
||||
NMSettingConnectionDnssec nm_setting_connection_get_dnssec(NMSettingConnection *setting);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __NM_SETTING_CONNECTION_H__ */
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ G_BEGIN_DECLS
|
|||
#define NM_SETTING_GSM_INITIAL_EPS_BEARER_REFUSE_CHAP "initial-eps-bearer-refuse-chap"
|
||||
#define NM_SETTING_GSM_INITIAL_EPS_BEARER_REFUSE_MSCHAP "initial-eps-bearer-refuse-mschap"
|
||||
#define NM_SETTING_GSM_INITIAL_EPS_BEARER_REFUSE_MSCHAPV2 "initial-eps-bearer-refuse-mschapv2"
|
||||
#define NM_SETTING_GSM_DEVICE_UID "device-uid"
|
||||
|
||||
/* Deprecated */
|
||||
#define NM_SETTING_GSM_NUMBER "number"
|
||||
|
|
@ -99,6 +100,8 @@ gboolean nm_setting_gsm_get_initial_eps_refuse_mschap(NMSettingGsm *setting);
|
|||
NM_AVAILABLE_IN_1_52
|
||||
gboolean nm_setting_gsm_get_initial_eps_refuse_mschapv2(NMSettingGsm *setting);
|
||||
|
||||
const char *nm_setting_gsm_get_device_uid(NMSettingGsm *setting);
|
||||
|
||||
NM_DEPRECATED_IN_1_16
|
||||
const char *nm_setting_gsm_get_number(NMSettingGsm *setting);
|
||||
|
||||
|
|
|
|||
|
|
@ -23,10 +23,28 @@ G_BEGIN_DECLS
|
|||
|
||||
#define NM_SETTING_HSR_SETTING_NAME "hsr"
|
||||
|
||||
#define NM_SETTING_HSR_PORT1 "port1"
|
||||
#define NM_SETTING_HSR_PORT2 "port2"
|
||||
#define NM_SETTING_HSR_MULTICAST_SPEC "multicast-spec"
|
||||
#define NM_SETTING_HSR_PRP "prp"
|
||||
#define NM_SETTING_HSR_PORT1 "port1"
|
||||
#define NM_SETTING_HSR_PORT2 "port2"
|
||||
#define NM_SETTING_HSR_MULTICAST_SPEC "multicast-spec"
|
||||
#define NM_SETTING_HSR_PRP "prp"
|
||||
#define NM_SETTING_HSR_PROTOCOL_VERSION "protocol-version"
|
||||
#define NM_SETTING_HSR_INTERLINK "interlink"
|
||||
|
||||
/**
|
||||
* NMSettingHsrProtocolVersion:
|
||||
* @NM_SETTING_HSR_PROTOCOL_VERSION_DEFAULT: Default version for the protocol
|
||||
* @NM_SETTING_HSR_PROTOCOL_VERSION_HSR_2010: HSRv0, IEC 62439-3:2010
|
||||
* @NM_SETTING_HSR_PROTOCOL_VERSION_HSR_2012: HSRv1, IEC 62439-3:2012
|
||||
*
|
||||
* #NMSettingHsrProtocolVersion values indicate the HSR protocol version.
|
||||
*
|
||||
* Since: 1.56
|
||||
*/
|
||||
typedef enum {
|
||||
NM_SETTING_HSR_PROTOCOL_VERSION_DEFAULT = -1,
|
||||
NM_SETTING_HSR_PROTOCOL_VERSION_HSR_2010 = 0,
|
||||
NM_SETTING_HSR_PROTOCOL_VERSION_HSR_2012 = 1,
|
||||
} NMSettingHsrProtocolVersion;
|
||||
|
||||
typedef struct _NMSettingHsrClass NMSettingHsrClass;
|
||||
|
||||
|
|
@ -43,6 +61,10 @@ NM_AVAILABLE_IN_1_46
|
|||
guint32 nm_setting_hsr_get_multicast_spec(NMSettingHsr *setting);
|
||||
NM_AVAILABLE_IN_1_46
|
||||
gboolean nm_setting_hsr_get_prp(NMSettingHsr *setting);
|
||||
NM_AVAILABLE_IN_1_56
|
||||
NMSettingHsrProtocolVersion nm_setting_hsr_get_protocol_version(NMSettingHsr *setting);
|
||||
NM_AVAILABLE_IN_1_56
|
||||
const char *nm_setting_hsr_get_interlink(NMSettingHsr *setting);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue