Compare commits

..

No commits in common. "main" and "1.56.0" have entirely different histories.
main ... 1.56.0

194 changed files with 18430 additions and 47478 deletions

1
.gitignore vendored
View file

@ -81,6 +81,7 @@ 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

View file

@ -60,11 +60,11 @@ variables:
#
# This is done by running `ci-fairy generate-template` and possibly bumping
# ".default_tag".
ALPINE_TAG: 'tag-8e4bbc59695b'
CENTOS_TAG: 'tag-caf6673db1a7'
DEBIAN_TAG: 'tag-e394e8e726e1'
FEDORA_TAG: 'tag-caf6673db1a7'
UBUNTU_TAG: 'tag-e394e8e726e1'
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'

View file

@ -12,9 +12,9 @@ Please read
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/blob/main/CONTRIBUTING.md
before opening the merge request. In particular, check that:
- [ ] The subject for all commits is concise, explanatory, and includes a prefix indicating the area of code changed (e.g., "nmcli: ", "core: ")
- [ ] The message for all commits explains the reason for the change
- [ ] The source is properly formatted
- [ ] Any relevant documentation is up to date
- [ ] You have added unit tests if applicable
- [ ] The NEWS file is updated when the change deserves to be mentioned, for example for new features, behavior changes, API deprecations, etc.
- [ ] the subject for all commits is concise and explicative
- [ ] the message for all commits explains the reason for the change
- [ ] the source is properly formatted
- [ ] any relevant documentation is up to date
- [ ] you have added unit tests if applicable
- [ ] the NEWS file is updated when the change deserves to be mentioned, for example for new features, behavior changes, API deprecations, etc.

73
NEWS
View file

@ -1,72 +1,12 @@
=============================================
NetworkManager-1.58
Overview of changes since NetworkManager-1.56
=============================================
This is a snapshot of NetworkManager development. The API is
subject to change and not guaranteed to be compatible with
the later release.
USE AT YOUR OWN RISK. NOT RECOMMENDED FOR PRODUCTION USE!
* Unify the versioning to use everywhere the scheme with the -rcX or -dev
suffixes when appropriate. This affects, for example, the URL and filename
of the release tarball and the version reported by nmcli and the daemon.
As an exception, the C API will continue to use the 90+ scheme for RC versions.
* Connection profiles with manual IP addressing and with gateways that are not
directly reachable will generate a warning on activation and when they are
added/modified via nmcli and nmtui. NetworkManager currently adds on-link
routes for them automatically, but this will change in the future. To fix the
warning, users should add addresses or routes whose subnets cover these
gateways. A gateway (either the default gateway or the next-hop of a route) is
considered directly reachable if it falls within the subnet of a direct route
(a route without a next hop) or of a prefix route from a static address.
* 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.
* Use an internal implementation of the ping functionality when the
"connection.gateway-ping-timeout" or "connection.ip-ping-addresses"
properties are set, instead of relying on the "ping" tool.
* The powersave property now functions with the iwd backend.
* The "band" property of Wi-fi connections now accepts the "6GHz"
value.
* Show the Wi-Fi band of APs in the scan results from nmcli.
* New <Select...> button in nmtui that allows users to chose from list of
available devices when creating connection profiles for physical interfaces
(Ethernet, Wi-Fi, etc.).
* Add support for CLAT (464XLAT) using a BPF program.
* Change the default value of the ipv4.dhcp-ipv6-only-preferred property
to a new value "auto" which automatically enables the option when CLAT
is enabled ("yes" or "auto") in the connection profile.
* WIFI connections using wpa-psk respect the setting connection.auth-retry
and only prompt for new secrets during the last authentication attempt before
failing.
* Add support for GENEVE interface.
* The DHCPv4 internal client now ignores option 3 (Router) if the lease
contains option 121 (Classless Static Route), as recommended by RFC 3442.
* Allow persisting the managed state across reboots from nmcli and the D-Bus API.
* Allow changing the device's administrative state in the kernel at the same
time as a change to the managed state from nmcli and the D-Bus API.
=============================================
NetworkManager-1.56
Overview of changes since NetworkManager-1.54
=============================================
* Unify the versioning to use everywhere the scheme with the -rcX or -dev
suffixes when appropriate. This affects, for example, the URL and filename
of the release tarball and the version reported by nmcli and the daemon.
As an exception, the C API will continue to use the 90+ scheme for RC versions.
* nmcli now supports viewing and managing WireGuard peers.
* Support reapplying the "sriov.vfs" property as long as
"sriov.total-vfs" is not changed.
@ -95,6 +35,11 @@ Overview of changes since NetworkManager-1.54
for eBPF is now detected at run time.
* Add new MPTCP 'laminar' endpoint type, and set it by default alongside
the 'subflow' one.
* 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.
=============================================
NetworkManager-1.54

View file

@ -294,6 +294,3 @@
/* Define to 1 if dlvsym() is available */
#mesondefine HAVE_DLVSYM
/* Define to 1 if you want CLAT support. */
#mesondefine HAVE_CLAT

View file

@ -8,7 +8,6 @@ apk add \
'alpine-sdk' \
'autoconf' \
'bash' \
'bpftool' \
'clang' \
'curl-dev' \
'dbus' \
@ -24,7 +23,6 @@ apk add \
'iproute2' \
'iptables' \
'jansson-dev' \
'libbpf-dev' \
'libgudev-dev' \
'libndp-dev' \
'libnvme-dev' \

View file

@ -32,7 +32,6 @@ install_ignore_missing() {
install \
\
bpftool \
clang \
dbus \
dbus-x11 \
@ -44,7 +43,6 @@ install \
iproute2 \
iptables \
libaudit-dev \
libbpf-dev \
libcurl4-gnutls-dev \
libdbus-1-dev \
libgirepository1.0-dev \

View file

@ -49,7 +49,6 @@ install \
ModemManager-glib-devel \
audit-libs-devel \
bluez-libs-devel \
bpftool \
clang \
dbus-devel \
dbus-x11 \
@ -65,7 +64,6 @@ install \
iptables \
jansson-devel \
jq \
libbpf-devel \
libcurl-devel \
libndp-devel \
libnvme-devel \

View file

@ -100,17 +100,7 @@ Release: __RELEASE_VERSION__%{?dist}
%else
%bcond_without iwd
%endif
%if 0%{?fedora} <= 43 || 0%{?rhel} <= 10
%bcond_without polkit_noauth_group
%else
%bcond_with polkit_noauth_group
%endif
%ifarch %{ix86}
# there is no bpftool in i686
%bcond_with clat
%else
%bcond_without clat
%endif
###############################################################################
%global dbus_version 1.9.18
@ -188,9 +178,7 @@ Requires: dbus >= %{dbus_version}
Requires: glib2 >= %{glib2_version}
Requires: %{name}-libnm%{?_isa} = %{epoch}:%{version}-%{release}
%if %{with clat}
Requires: libbpf
%endif
Recommends: iputils
%if 0%{?rhel} == 8
# Older libndp versions use select() (rh#1933041). On well known distros,
@ -239,7 +227,6 @@ Conflicts: NetworkManager-dispatcher-routing-rules <= 1:1.47.5-3
%endif
BuildRequires: gcc
BuildRequires: clang
BuildRequires: pkgconfig
BuildRequires: meson
BuildRequires: gettext-devel >= 0.19.8
@ -294,10 +281,6 @@ BuildRequires: firewalld-filesystem
BuildRequires: iproute
BuildRequires: iproute-tc
BuildRequires: libnvme-devel >= 1.5
%if %{with clat}
BuildRequires: libbpf-devel
BuildRequires: bpftool
%endif
Provides: %{name}-dispatcher%{?_isa} = %{epoch}:%{version}-%{release}
@ -617,20 +600,19 @@ 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
-Diwd=false \
%endif
%if %{with clat}
-Dclat=true \
%else
-Dclat=false \
%endif
%if %{with bluetooth}
-Dbluez5_dun=true \
%else
@ -667,9 +649,7 @@ Preferably use nmcli instead.
-Dselinux=true \
-Dpolkit=true \
-Dconfig_auth_polkit_default=true \
%if %{with polkit_noauth_group}
-Dpolkit_noauth_group=wheel \
%endif
-Dmodify_system=true \
-Dconcheck=true \
%if 0%{?fedora}
-Dlibpsl=true \
@ -679,7 +659,6 @@ Preferably use nmcli instead.
-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 \
@ -752,7 +731,6 @@ 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
@ -918,9 +896,6 @@ 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

View file

@ -173,7 +173,6 @@ 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 +202,7 @@ if [ -z "$P_FEDORA" -a -z "$P_RHEL" ] ; then
P_FEDORA="$x"
P_RHEL=0
else
x="$(grep -q 'ID="rhel"' /etc/os-release && sed -n 's/^VERSION_ID="*\([0-9]*\).*/\1/p' /etc/os-release)"
x="$(grep -q "ID=fedora" /etc/os-release && sed -n 's/VERSION_ID=//p' /etc/os-release)"
if test "$x" -gt 0 ; then
P_FEDORA=0
P_RHEL="$x"
@ -294,14 +293,6 @@ 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
@ -387,7 +378,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=false) \
$(args_enable "$P_WIFI" -Dwifi=true -Dwext="$(bool_true "$P_FEDORA")") \
$(args_enable "$(bool_not_true "$P_WIFI")" -Dwifi=false ) \
-Diwd="$(bool_true "$P_IWD")" \
-Dbluez5_dun="$(bool_true "$P_BLUETOOTH")" \
@ -401,17 +392,17 @@ meson setup\
-Dselinux=true \
-Dpolkit=true \
-Dconfig_auth_polkit_default=true \
-Dmodify_system=true \
-Dconcheck=true \
-Dlibpsl="$(bool_true "$P_FEDORA")" \
-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="$(bool_true "$P_IFCFG_RH")" \
-Difcfg_rh=true \
-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 ) \

View file

@ -55,7 +55,6 @@ _WITH_LIBTEAM="true"
_WITH_DOCS="true"
_WITH_SYSTEMD_LOGIND="true"
_WITH_NBFT="true"
_WITH_CLAT="true"
if [ $IS_ALPINE = 1 ]; then
_WITH_SYSTEMD_LOGIND="false"
fi
@ -64,14 +63,6 @@ if ! pkgconf 'libnvme >= 1.5'; then
_WITH_NBFT="false"
fi
if ! pkgconf 'libndp >= 1.9'; then
_WITH_CLAT="false"
fi
if ! pkgconf 'libbpf >= 1.3'; then
_WITH_CLAT="false"
fi
if [ -z "${NMTST_SEED_RAND+x}" ]; then
NMTST_SEED_RAND="$SRANDOM"
if [ -z "$NMTST_SEED_RAND" ]; then
@ -178,7 +169,6 @@ 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 \
@ -204,7 +194,6 @@ meson setup build \
-D ifupdown=true \
\
-D nbft=$_WITH_NBFT \
-D clat=$_WITH_CLAT \
\
#end

View file

@ -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,3 +22,6 @@ ExecStartPost=/bin/sh -c ' \
fi \
'
RemainAfterExit=yes
[Install]
WantedBy=initrd.target

View file

@ -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,3 +22,11 @@ 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

View file

@ -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,3 +21,6 @@ Type=oneshot
ExecStart=@bindir@/nm-online -s -q
RemainAfterExit=yes
Environment=NM_ONLINE_TIMEOUT=3600
[Install]
WantedBy=initrd.target network-online.target

View file

@ -21,16 +21,8 @@ TimeoutStartSec=600
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
PrivateTmp=true
ProtectClock=true
ProtectControlGroups=true
ProtectHome=read-only
ProtectKernelLogs=true
ProtectSystem=true
RestrictRealtime=true
RestrictSUIDSGID=true
ProtectHome=read-only
# We require file descriptors for DHCP etc. When activating many interfaces,
# the default limit of 1024 is easily reached.

View file

@ -55,22 +55,21 @@ 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: 'org.freedesktop.NetworkManager.policy.in',
input: policy_in,
output: '@BASENAME@',
po_dir: po_dir,
install: true,
install_dir: polkit_policydir,
install_dir: polkit_gobject_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

View file

@ -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>auth_admin_keep</allow_inactive>
<allow_active>auth_admin_keep</allow_active>
<allow_inactive>@NM_MODIFY_SYSTEM_POLICY@</allow_inactive>
<allow_active>@NM_MODIFY_SYSTEM_POLICY@</allow_active>
</defaults>
</action>

View file

@ -1,17 +0,0 @@
// 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;
}
});

View file

@ -183,7 +183,6 @@
<xi:include href="dbus-org.freedesktop.NetworkManager.Device.Bridge.xml"/>
<xi:include href="dbus-org.freedesktop.NetworkManager.Device.Dummy.xml"/>
<xi:include href="dbus-org.freedesktop.NetworkManager.Device.Generic.xml"/>
<xi:include href="dbus-org.freedesktop.NetworkManager.Device.Geneve.xml"/>
<xi:include href="dbus-org.freedesktop.NetworkManager.Device.Hsr.xml"/>
<xi:include href="dbus-org.freedesktop.NetworkManager.Device.IPTunnel.xml"/>
<xi:include href="dbus-org.freedesktop.NetworkManager.Device.Infiniband.xml"/>

View file

@ -317,7 +317,6 @@ print ("NetworkManager version " + client.get_version())]]></programlisting></in
<xi:include href="xml/nm-setting-dummy.xml"/>
<xi:include href="xml/nm-setting-ethtool.xml"/>
<xi:include href="xml/nm-setting-generic.xml"/>
<xi:include href="xml/nm-setting-geneve.xml"/>
<xi:include href="xml/nm-setting-gsm.xml"/>
<xi:include href="xml/nm-setting-hostname.xml"/>
<xi:include href="xml/nm-setting-hsr.xml"/>
@ -378,7 +377,6 @@ print ("NetworkManager version " + client.get_version())]]></programlisting></in
<xi:include href="xml/nm-device-dummy.xml"/>
<xi:include href="xml/nm-device-ethernet.xml"/>
<xi:include href="xml/nm-device-generic.xml"/>
<xi:include href="xml/nm-device-geneve.xml"/>
<xi:include href="xml/nm-device-hsr.xml"/>
<xi:include href="xml/nm-device-infiniband.xml"/>
<xi:include href="xml/nm-device-ip-tunnel.xml"/>

View file

@ -15,7 +15,6 @@ ifaces = [
'org.freedesktop.NetworkManager.Device.Bridge',
'org.freedesktop.NetworkManager.Device.Dummy',
'org.freedesktop.NetworkManager.Device.Generic',
'org.freedesktop.NetworkManager.Device.Geneve',
'org.freedesktop.NetworkManager.Device.Hsr',
'org.freedesktop.NetworkManager.Device.IPTunnel',
'org.freedesktop.NetworkManager.Device.Infiniband',

View file

@ -1,63 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<node name="/">
<!--
org.freedesktop.NetworkManager.Device.Geneve:
@short_description: GENEVE Device.
-->
<interface name="org.freedesktop.NetworkManager.Device.Geneve">
<!--
Id:
@since: 1.58
The GENEVE Virtual Network Identifier (VNI).
-->
<property name="Id" type="u" access="read"/>
<!--
Remote:
@since: 1.58
The IP (v4 or v6) address of the remote endpoint to which GENEVE packets
are sent.
-->
<property name="Remote" type="s" access="read"/>
<!--
Tos:
@since: 1.58
The value to use in the IP ToS field for GENEVE packets sent to the remote
endpoint.
-->
<property name="Tos" type="y" access="read"/>
<!--
Ttl:
@since: 1.58
The value to use in the IP TTL field for GENEVE packets sent to the remote
endpoint.
-->
<property name="Ttl" type="i" access="read"/>
<!--
Df:
@since: 1.58
The Don't Fragment (DF) flag setting for GENEVE packets. 0 means unset,
1 means set, 2 means inherit from the underlying interface.
-->
<property name="Df" type="y" access="read"/>
<!--
DstPort:
@since: 1.58
Destination port for outgoing GENEVE packets.
-->
<property name="DstPort" type="q" access="read"/>
</interface>
</node>

View file

@ -175,9 +175,6 @@
property has a similar effect to configuring the device as unmanaged via
the keyfile.unmanaged-devices setting in NetworkManager.conf. Changes to
this value are not persistent and lost after NetworkManager restart.
DEPRECATED: 1.58: Use the SetManaged method instead, which supports
additional features like persisting the state to disk
-->
<property name="Managed" type="b" access="readwrite"/>
@ -394,20 +391,6 @@
-->
<method name="Delete"/>
<!--
SetManaged:
@managed:(<link linkend="NMDeviceManaged">NMDeviceManaged</link>) Whether the device is managed. Possible values are "no" (0), "yes" (1) and "reset" (2).
@flags: (<link linkend="NMDeviceManagedFlags">NMDeviceManagedFlags</link>) flags.
@since: 1.58
Set the managed state of the device. With the flags argument different
behaviors can be achieved, like storing the new managed state to disk.
-->
<method name="SetManaged">
<arg name="managed" type="u" direction="in"/>
<arg name="flags" type="u" direction="in"/>
</method>
<!--
StateChanged:
@new_state: (<link linkend="NMDeviceState">NMDeviceState</link>) The new state of the device.

View file

@ -62,7 +62,7 @@
<!--
GetSecrets:
@setting_name: Name of the setting to return secrets for (mandatory).
@setting_name: Name of the setting to return secrets for. If empty, all secrets will be returned.
@secrets: Nested settings maps containing secrets.
Get the secrets belonging to this network configuration. Only secrets from

View file

@ -83,11 +83,6 @@
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>
@ -954,10 +949,6 @@ ipv6.ip6-privacy=0
<term><varname>ipv4.forwarding</varname></term>
<listitem><para>Whether to configure IPv4 sysctl interface-specific forwarding. When enabled, the interface will act as a router to forward the IPv4 packet from one interface to another. If left unspecified, "auto" is used, so NetworkManager sets the IPv4 forwarding if any shared connection is active, or it will use the kernel default value otherwise. The "ipv4.forwarding" property is ignored when "ipv4.method" is set to "shared", because forwarding is always enabled in this case. The accepted values are: 0: disabled, 1: enabled, 2: auto, 3: ignored (leave the forwarding unchanged).</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>ipv4.clat</varname></term>
<listitem><para>If left unspecified, defaults to "no".</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>ipv4.routed-dns</varname></term>
</varlistentry>
@ -976,7 +967,7 @@ ipv6.ip6-privacy=0
</varlistentry>
<varlistentry>
<term><varname>ipv4.dhcp-ipv6-only-preferred</varname></term>
<listitem><para>If left unspecified, it defaults to "auto".</para></listitem>
<listitem><para>If left unspecified, the "IPv6-only preferred" DHCPv4 option is disabled.</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>ipv4.dhcp-hostname-flags</varname></term>
@ -1258,13 +1249,12 @@ managed=1
<term><varname>managed</varname></term>
<listitem>
<para>
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.
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.
</para>
</listitem>
</varlistentry>
@ -1333,27 +1323,9 @@ managed=1
</para>
</listitem>
</varlistentry>
<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>
<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
@ -1450,16 +1422,16 @@ managed=1
<term><varname>wifi.iwd.autoconnect</varname></term>
<listitem>
<para>
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.
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>
@ -1518,7 +1490,7 @@ managed=1
<variablelist>
<varlistentry>
<term><varname>enabled</varname></term>
<listitem><para>A boolean indicating whether connectivity check is enabled.
<listitem><para>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.

View file

@ -1436,31 +1436,15 @@
</arg>
<arg>
<option>managed</option>
<group>
<arg choice='plain'>--permanent</arg>
<arg choice='plain'>--permanent-only</arg>
</group>
<group choice='req'>
<arg choice='plain'>yes</arg>
<arg choice='plain'>no</arg>
<arg choice='plain'>up</arg>
<arg choice='plain'>down</arg>
<arg choice='plain'>reset</arg>
</group>
</arg>
</term>
<listitem>
<para>Set device properties.</para>
<para>The <option>managed</option> property accepts a <option>--permanent</option>
option to persist the managed state to disk, and not only in runtime. With
<option>--permanent-only</option> only the permanent managed state is set, and not the
runtime managed state. The special values <option>up</option> and <option>down</option>
can be used to set the administrative state of the device at the same time as the runtime
managed state. The <option>reset</option> value clears the explicit managed setting, and
with <option>--permanent</option> or <option>--permanent-only</option> it also removes
the persisted managed setting.</para>
</listitem>
</varlistentry>
@ -1734,7 +1718,6 @@
<group choice='req'>
<arg choice='plain'>a</arg>
<arg choice='plain'>bg</arg>
<arg choice='plain'>6GHz</arg>
</group>
</arg>
<arg><option>channel</option> <replaceable>channel</replaceable></arg>
@ -1868,9 +1851,9 @@
connections with an option of restoring the network configuration to a
known good state in case of an error.</para>
<para>If a list of interface names is specified, the checkpoint is
taken only on the specified devices. Otherwise a checkpoint is taken for
all devices.</para>
<para>If the a list of interface names is specified, the checkpoint is
taken, the checkpoint is takes only on the specified devices. Otherwise
a checkpoint is taken for all devices.</para>
<para>Currently the timeout defaults to 15 seconds. This may change in
a future version.</para>

View file

@ -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.57.3-dev',
version: '1.56.0',
license: 'GPL2+',
default_options: [
'buildtype=debugoptimized',
@ -358,11 +358,7 @@ 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)
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')
enable_wext = get_option('wext')
config_h.set10('HAVE_WEXT', enable_wext)
# Checks for libdl - on certain platforms its part of libc
@ -412,14 +408,6 @@ 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')
@ -514,16 +502,6 @@ if enable_selinux
endif
config_h.set10('HAVE_SELINUX', enable_selinux)
# CLAT support
enable_clat = get_option('clat')
if enable_clat
libbpf = dependency('libbpf', version: '>= 1.3.0', required: false)
assert(libbpf.found(), 'You must have libbpf >= 1.3.0 installed to build. Use -Dclat=false to disable use of it')
libndp_dep = dependency('libndp', version: '>= 1.9', required: false)
assert(libndp_dep.found(), 'You must have libndp >= 1.9 installed to build with CLAT support. Use -Dclat=false to disable it')
endif
config_h.set10('HAVE_CLAT', enable_clat)
# libaudit support
libaudit = get_option('libaudit')
enable_libaudit = libaudit.contains('yes')
@ -548,8 +526,7 @@ config_h.set10('WITH_TEAMDCTL', enable_teamdctl)
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_policydir = dependency('polkit-gobject-1').get_variable(pkgconfig: 'policydir', pkgconfig_define: ['prefix', nm_prefix])
polkit_rulesdir = join_paths(fs.parent(polkit_policydir), 'rules.d')
polkit_gobject_policydir = dependency('polkit-gobject-1').get_variable(pkgconfig: 'policydir', pkgconfig_define: ['prefix', nm_prefix])
endif
config_auth_polkit_default = get_option('config_auth_polkit_default')
@ -559,12 +536,6 @@ 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',
@ -997,6 +968,7 @@ 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)
@ -1112,7 +1084,6 @@ 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'
@ -1127,7 +1098,17 @@ 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 + ', noauth_group: "' + polkit_noauth_group + '")\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 += ' 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'
@ -1155,7 +1136,6 @@ output += ' ofono: ' + enable_ofono.to_string() + '\n'
output += ' concheck: ' + enable_concheck.to_string() + '\n'
output += ' libteamdctl: ' + enable_teamdctl.to_string() + '\n'
output += ' ovs: ' + enable_ovs.to_string() + '\n'
output += ' clat: ' + enable_clat.to_string() + '\n'
output += ' nmcli: ' + enable_nmcli.to_string() + '\n'
output += ' nmtui: ' + enable_nmtui.to_string() + '\n'
output += ' nm-cloud-setup: ' + enable_nm_cloud_setup.to_string() + '\n'

View file

@ -1,6 +1,5 @@
# 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')
@ -19,8 +18,7 @@ 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 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('modify_system', type: 'boolean', value: false, description: 'Allow users to modify system connections')
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')
@ -30,7 +28,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: '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('wext', type: 'boolean', value: true, description: 'Enable or disable Linux Wireless Extensions')
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')
@ -48,9 +46,6 @@ option('nm_cloud_setup', type: 'boolean', value: true, description: 'Build nm-cl
option('bluez5_dun', type: 'boolean', value: false, description: 'enable Bluez5 DUN 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')
option('clat', type: 'boolean', value: true, description: 'Build with CLAT support')
option('bpf-compiler', type : 'combo', choices : ['auto', 'clang', 'gcc'],
description : 'compiler used to build BPF programs')
# configuration plugins
option('config_plugins_default', type: 'string', value: '', description: 'Default configuration option for main.plugins setting, used as fallback if the configuration option is unset')

View file

@ -30,7 +30,6 @@ id
it
ja
ka
kk
kn
ko
ku

View file

@ -1,18 +1,16 @@
# List of source files containing translatable strings.
# Please keep this file sorted alphabetically.
data/org.freedesktop.NetworkManager.policy.in
data/org.freedesktop.NetworkManager.policy.in.in
src/core/NetworkManagerUtils.c
src/core/devices/adsl/nm-device-adsl.c
src/core/devices/bluetooth/nm-bluez-manager.c
src/core/devices/bluetooth/nm-device-bt.c
src/core/devices/nm-device.c
src/core/devices/nm-device-6lowpan.c
src/core/devices/nm-device-bond.c
src/core/devices/nm-device-bridge.c
src/core/devices/nm-device-dummy.c
src/core/devices/nm-device-ethernet-utils.c
src/core/devices/nm-device-ethernet.c
src/core/devices/nm-device-geneve.c
src/core/devices/nm-device-infiniband.c
src/core/devices/nm-device-ip-tunnel.c
src/core/devices/nm-device-loopback.c
@ -48,7 +46,6 @@ src/libnm-client-impl/nm-device-bt.c
src/libnm-client-impl/nm-device-dummy.c
src/libnm-client-impl/nm-device-ethernet.c
src/libnm-client-impl/nm-device-generic.c
src/libnm-client-impl/nm-device-geneve.c
src/libnm-client-impl/nm-device-hsr.c
src/libnm-client-impl/nm-device-infiniband.c
src/libnm-client-impl/nm-device-ip-tunnel.c
@ -93,7 +90,6 @@ src/libnm-core-impl/nm-setting-connection.c
src/libnm-core-impl/nm-setting-dcb.c
src/libnm-core-impl/nm-setting-ethtool.c
src/libnm-core-impl/nm-setting-generic.c
src/libnm-core-impl/nm-setting-geneve.c
src/libnm-core-impl/nm-setting-gsm.c
src/libnm-core-impl/nm-setting-hsr.c
src/libnm-core-impl/nm-setting-infiniband.c

9914
po/bg.po

File diff suppressed because it is too large Load diff

16300
po/kk.po

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

5931
po/sl.po

File diff suppressed because it is too large Load diff

5384
po/tr.po

File diff suppressed because it is too large Load diff

View file

@ -1495,10 +1495,11 @@ nm_utils_ip_route_attribute_to_platform(int addr_family,
r4->scope_inv = nm_platform_route_scope_inv(scope);
}
/* For IPv4 routes in kernel, the onlink flag is per-nexthop (rtnh_flags).
* Here we set the flag on r_rtm_flags which represents the first nexthop's
* flags. For ECMP routes, each nexthop carries its own onlink flag, so
* routes with different onlink settings per-nexthop can be merged. */
/* Note that for IPv4 routes in kernel, the onlink flag can be set for
* each next hop separately (rtnh_flags). Not for NetworkManager. We can
* only merge routes as ECMP routes (when setting a weight) if they all
* share the same onlink flag. See NM_PLATFORM_IP_ROUTE_CMP_TYPE_ECMP_ID.
* That simplifies the code. */
GET_ATTR(NM_IP_ROUTE_ATTRIBUTE_ONLINK, onlink, BOOLEAN, boolean, FALSE);
r->r_rtm_flags = ((onlink) ? (unsigned) RTNH_F_ONLINK : 0u);

File diff suppressed because it is too large Load diff

View file

@ -1,30 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __NAT64_H__
#define __NAT64_H__
#include <linux/in6.h>
struct clat_config {
struct in6_addr local_v6;
struct in6_addr pref64;
struct in_addr local_v4;
unsigned pref64_len;
};
struct clat_stats {
/* egress: v4 to v6 */
__u64 egress_tcp;
__u64 egress_udp;
__u64 egress_icmp;
__u64 egress_other;
__u64 egress_dropped;
/* ingress: v6 to v4 */
__u64 ingress_tcp;
__u64 ingress_udp;
__u64 ingress_icmp;
__u64 ingress_other;
__u64 ingress_fragment;
__u64 ingress_dropped;
};
#endif

View file

@ -1,239 +0,0 @@
# SPDX-License-Identifier: LGPL-2.1+
# Ripped from systemd: https://github.com/systemd/systemd/pull/20429
if not enable_clat
subdir_done()
endif
bpf_compiler = get_option('bpf-compiler')
clang_found = false
clang_supports_bpf = false
bpf_gcc_found = false
bpftool_strip = false
if bpf_compiler == 'clang' or bpf_compiler == 'auto'
# Support 'versioned' clang/llvm-strip binaries, as seen on Debian/Ubuntu
# (like clang-10/llvm-strip-10)
if meson.is_cross_build() or cc.get_id() != 'clang' or cc.cmd_array()[0].contains('afl-clang') or cc.cmd_array()[0].contains('hfuzz-clang')
r = find_program('clang',
version : '>= 10.0.0')
clang_found = r.found()
if clang_found
if meson.version().version_compare('>= 0.55')
clang = r.full_path()
else
clang = r.path()
endif
endif
else
clang_found = true
clang = cc.cmd_array()
endif
if clang_found
# Check if 'clang -target bpf' is supported.
clang_supports_bpf = run_command(clang, '-target', 'bpf', '--print-supported-cpus', check : false).returncode() == 0
endif
elif bpf_compiler == 'gcc' or bpf_compiler == 'auto'
bpf_gcc = find_program('bpf-gcc',
'bpf-none-gcc',
'bpf-unknown-none-gcc',
version : '>= 13.1.0')
bpf_gcc_found = bpf_gcc.found()
endif
if bpf_compiler == 'auto'
if clang_supports_bpf and bpf_gcc_found
# Both supported, prefer the one matching our compiler:
if cc.get_id() == 'gcc'
bpf_compiler = 'gcc'
else
# Default to clang if we don't know this compiler
bpf_compiler = 'clang'
endif
elif clang_supports_bpf
bpf_compiler = 'clang'
elif bpf_gcc_found
bpf_compiler = 'clang'
endif
endif
if clang_supports_bpf or bpf_gcc_found
# Debian installs this in /usr/sbin/ which is not in $PATH.
# We check for 'bpftool' first, honouring $PATH, and in /usr/sbin/ for Debian.
# We use 'bpftool gen object' subcommand for bpftool strip, it was added by d80b2fcbe0a023619e0fc73112f2a02c2662f6ab (v5.13).
bpftool = find_program('bpftool',
'/usr/sbin/bpftool',
required : bpf_compiler == 'gcc',
version : bpf_compiler == 'gcc' ? '>= 7.0.0' : '>= 5.13.0')
if bpftool.found()
bpftool_strip = true
elif bpf_compiler == 'clang'
# We require the 'bpftool gen skeleton' subcommand, it was added by 985ead416df39d6fe8e89580cc1db6aa273e0175 (v5.6).
bpftool = find_program('bpftool',
'/usr/sbin/bpftool',
required : true,
version : '>= 5.6.0')
endif
# We use `llvm-strip` as a fallback if `bpftool gen object` strip support is not available.
if not bpftool_strip and bpftool.found() and clang_supports_bpf
if not meson.is_cross_build()
llvm_strip_bin = run_command(clang, '--print-prog-name', 'llvm-strip',
check : true).stdout().strip()
else
llvm_strip_bin = 'llvm-strip'
endif
llvm_strip = find_program(llvm_strip_bin,
required : true,
version : '>= 10.0.0')
endif
else
error('clat support was enabled but couldn\'t find a suitable BPF compiler!')
endif
bpf_clang_flags = [
'-std=gnu17',
'-Wunused',
'-Wimplicit-fallthrough',
'-Wno-compare-distinct-pointer-types',
'-fno-stack-protector',
'-O2',
'-target',
'bpf',
'-g',
'-c',
]
bpf_gcc_flags = [
'-std=gnu17',
'-Wunused',
'-Wimplicit-fallthrough',
'-fno-stack-protector',
'-fno-ssa-phiopt',
'-O2',
'-mcpu=v3',
'-mco-re',
'-gbtf',
'-c',
]
clang_arch_flag = '-D__@0@__'.format(host_machine.cpu_family())
libbpf_include_dir = dependency('libbpf').get_variable(pkgconfig : 'includedir')
# Generate defines that are appropriate to tell the compiler what architecture
# we're compiling for. By default we just map meson's cpu_family to __<cpu_family>__.
# This dictionary contains the exceptions where this doesn't work.
#
# C.f. https://mesonbuild.com/Reference-tables.html#cpu-families
# and src/basic/missing_syscall_def.h.
cpu_arch_defines = {
'ppc' : ['-D__powerpc__', '-D__TARGET_ARCH_powerpc'],
'ppc64' : ['-D__powerpc64__', '-D__TARGET_ARCH_powerpc', '-D_CALL_ELF=2'],
'riscv32' : ['-D__riscv', '-D__riscv_xlen=32', '-D__TARGET_ARCH_riscv'],
'riscv64' : ['-D__riscv', '-D__riscv_xlen=64', '-D__TARGET_ARCH_riscv'],
'x86' : ['-D__i386__', '-D__TARGET_ARCH_x86'],
's390x' : ['-D__s390__', '-D__s390x__', '-D__TARGET_ARCH_s390'],
# For arm, assume hardware fp is available.
'arm' : ['-D__arm__', '-D__ARM_PCS_VFP', '-D__TARGET_ARCH_arm'],
'loongarch64' : ['-D__loongarch__', '-D__loongarch_grlen=64', '-D__TARGET_ARCH_loongarch']
}
bpf_arch_flags = cpu_arch_defines.get(host_machine.cpu_family(),
['-D__@0@__'.format(host_machine.cpu_family())])
if bpf_compiler == 'gcc'
bpf_arch_flags += ['-m' + host_machine.endian() + '-endian']
endif
bpf_o_unstripped_cmd = []
if bpf_compiler == 'clang'
bpf_o_unstripped_cmd += [
clang,
bpf_clang_flags,
bpf_arch_flags,
]
elif bpf_compiler == 'gcc'
bpf_o_unstripped_cmd += [
bpf_gcc,
bpf_gcc_flags,
bpf_arch_flags,
]
endif
bpf_o_unstripped_cmd += ['-I.']
if cc.get_id() == 'gcc' or meson.is_cross_build()
if cc.get_id() != 'gcc'
warning('Cross compiler is not gcc. Guessing the target triplet for bpf likely fails.')
endif
target_triplet_cmd = run_command(cc.cmd_array(), '-print-multiarch', check: false)
else
# clang does not support -print-multiarch (D133170) and its -dump-machine
# does not match multiarch. Query gcc instead.
target_triplet_cmd = run_command('gcc', '-print-multiarch', check: false)
endif
if target_triplet_cmd.returncode() == 0
target_triplet = target_triplet_cmd.stdout().strip()
bpf_o_unstripped_cmd += [
'-isystem',
'/usr/include/@0@'.format(target_triplet)
]
endif
bpf_o_unstripped_cmd += [
'-idirafter',
libbpf_include_dir,
'@INPUT@',
'-o',
'@OUTPUT@'
]
if bpftool_strip
bpf_o_cmd = [
bpftool,
'gen',
'object',
'@OUTPUT@',
'@INPUT@'
]
elif bpf_compiler == 'clang'
bpf_o_cmd = [
llvm_strip,
'-g',
'@INPUT@',
'-o',
'@OUTPUT@'
]
endif
skel_h_cmd = [
bpftool,
'g',
's',
'@INPUT@'
]
clat_bpf_o_unstripped = custom_target(
'clat.bpf.unstripped.o',
input : 'clat.bpf.c',
output : 'clat.bpf.unstripped.o',
command : bpf_o_unstripped_cmd)
clat_bpf_o = custom_target(
'clat.bpf.o',
input : clat_bpf_o_unstripped,
output : 'clat.bpf.o',
command : bpf_o_cmd)
clat_skel_h = custom_target(
'clat.skel.h',
input : clat_bpf_o,
output : 'clat.skel.h',
command : skel_h_cmd,
capture : true)

View file

@ -412,7 +412,6 @@ nm_device_factory_manager_load_factories(NMDeviceFactoryManagerFactoryFunc callb
_ADD_INTERNAL(nm_dummy_device_factory_get_type);
_ADD_INTERNAL(nm_ethernet_device_factory_get_type);
_ADD_INTERNAL(nm_generic_device_factory_get_type);
_ADD_INTERNAL(nm_geneve_device_factory_get_type);
_ADD_INTERNAL(nm_hsr_device_factory_get_type);
_ADD_INTERNAL(nm_infiniband_device_factory_get_type);
_ADD_INTERNAL(nm_ip_tunnel_device_factory_get_type);

View file

@ -1,487 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Copyright (C) 2026 Red Hat, Inc.
*/
#include "src/core/nm-default-daemon.h"
#include "nm-manager.h"
#include "nm-device-geneve.h"
#include "libnm-core-intern/nm-core-internal.h"
#include "nm-act-request.h"
#include "nm-device-private.h"
#include "nm-setting-geneve.h"
#include "libnm-platform/nm-platform.h"
#include "nm-device-factory.h"
#define _NMLOG_DEVICE_TYPE NMDeviceGeneve
#include "nm-device-logging.h"
NM_GOBJECT_PROPERTIES_DEFINE(NMDeviceGeneve,
PROP_ID,
PROP_REMOTE,
PROP_TOS,
PROP_TTL,
PROP_DF,
PROP_DST_PORT, );
typedef struct {
NMPlatformLnkGeneve props;
} NMDeviceGenevePrivate;
struct _NMDeviceGeneve {
NMDevice parent;
NMDeviceGenevePrivate _priv;
};
struct _NMDeviceGeneveClass {
NMDeviceClass parent;
};
G_DEFINE_TYPE(NMDeviceGeneve, nm_device_geneve, NM_TYPE_DEVICE)
#define NM_DEVICE_GENEVE_GET_PRIVATE(self) \
_NM_GET_PRIVATE(self, NMDeviceGeneve, NM_IS_DEVICE_GENEVE, NMDevice)
/*****************************************************************************/
static NMDeviceCapabilities
get_generic_capabilities(NMDevice *dev)
{
return NM_DEVICE_CAP_IS_SOFTWARE;
}
static void
update_properties(NMDevice *device)
{
NMDeviceGeneve *self;
NMDeviceGenevePrivate *priv;
const NMPlatformLink *plink;
const NMPlatformLnkGeneve *props;
int ifindex;
g_return_if_fail(NM_IS_DEVICE_GENEVE(device));
self = NM_DEVICE_GENEVE(device);
priv = NM_DEVICE_GENEVE_GET_PRIVATE(self);
ifindex = nm_device_get_ifindex(device);
g_return_if_fail(ifindex > 0);
props = nm_platform_link_get_lnk_geneve(nm_device_get_platform(device), ifindex, &plink);
if (!props) {
_LOGW(LOGD_PLATFORM, "could not get GENEVE properties");
return;
}
g_object_freeze_notify((GObject *) device);
#define CHECK_PROPERTY_CHANGED(field, prop) \
G_STMT_START \
{ \
if (priv->props.field != props->field) { \
priv->props.field = props->field; \
_notify(self, prop); \
} \
} \
G_STMT_END
#define CHECK_PROPERTY_CHANGED_IN6ADDR(field, prop) \
G_STMT_START \
{ \
if (memcmp(&priv->props.field, &props->field, sizeof(props->field)) != 0) { \
priv->props.field = props->field; \
_notify(self, prop); \
} \
} \
G_STMT_END
CHECK_PROPERTY_CHANGED(id, PROP_ID);
CHECK_PROPERTY_CHANGED(remote, PROP_REMOTE);
CHECK_PROPERTY_CHANGED_IN6ADDR(remote6, PROP_REMOTE);
CHECK_PROPERTY_CHANGED(tos, PROP_TOS);
CHECK_PROPERTY_CHANGED(ttl, PROP_TTL);
CHECK_PROPERTY_CHANGED(df, PROP_DF);
CHECK_PROPERTY_CHANGED(dst_port, PROP_DST_PORT);
g_object_thaw_notify((GObject *) device);
}
static void
link_changed(NMDevice *device, const NMPlatformLink *pllink)
{
NM_DEVICE_CLASS(nm_device_geneve_parent_class)->link_changed(device, pllink);
update_properties(device);
}
static void
unrealize_notify(NMDevice *device)
{
NMDeviceGeneve *self = NM_DEVICE_GENEVE(device);
NMDeviceGenevePrivate *priv = NM_DEVICE_GENEVE_GET_PRIVATE(self);
guint i;
NM_DEVICE_CLASS(nm_device_geneve_parent_class)->unrealize_notify(device);
memset(&priv->props, 0, sizeof(NMPlatformLnkGeneve));
for (i = 1; i < _PROPERTY_ENUMS_LAST; i++)
g_object_notify_by_pspec(G_OBJECT(self), obj_properties[i]);
}
static gboolean
create_and_realize(NMDevice *device,
NMConnection *connection,
NMDevice *parent,
const NMPlatformLink **out_plink,
GError **error)
{
const char *iface = nm_device_get_iface(device);
NMPlatformLnkGeneve props = {};
NMSettingGeneve *s_geneve;
const char *str;
int r;
s_geneve = nm_connection_get_setting_geneve(connection);
g_return_val_if_fail(s_geneve, FALSE);
props.id = nm_setting_geneve_get_id(s_geneve);
str = nm_setting_geneve_get_remote(s_geneve);
if (!nm_inet_parse_bin(AF_INET, str, NULL, &props.remote)
&& !nm_inet_parse_bin(AF_INET6, str, NULL, &props.remote6)) {
return nm_assert_unreachable_val(FALSE);
}
props.tos = nm_setting_geneve_get_tos(s_geneve);
props.ttl = nm_setting_geneve_get_ttl(s_geneve);
props.df = nm_setting_geneve_get_df(s_geneve);
props.dst_port = nm_setting_geneve_get_destination_port(s_geneve);
r = nm_platform_link_geneve_add(nm_device_get_platform(device), iface, &props, out_plink);
if (r < 0) {
g_set_error(error,
NM_DEVICE_ERROR,
NM_DEVICE_ERROR_CREATION_FAILED,
"Failed to create geneve interface '%s' for '%s': %s",
iface,
nm_connection_get_id(connection),
nm_strerror(r));
return FALSE;
}
return TRUE;
}
static gboolean
address_matches(const char *candidate, in_addr_t addr4, struct in6_addr *addr6)
{
NMIPAddr candidate_addr;
int addr_family;
if (!candidate)
return addr4 == 0u && IN6_IS_ADDR_UNSPECIFIED(addr6);
if (!nm_inet_parse_bin(AF_UNSPEC, candidate, &addr_family, &candidate_addr))
return FALSE;
if (!nm_ip_addr_equal(addr_family,
&candidate_addr,
NM_IS_IPv4(addr_family) ? (gpointer) &addr4 : addr6))
return FALSE;
if (NM_IS_IPv4(addr_family))
return IN6_IS_ADDR_UNSPECIFIED(addr6);
else
return addr4 == 0u;
}
static gboolean
check_connection_compatible(NMDevice *device,
NMConnection *connection,
gboolean check_properties,
GError **error)
{
NMDeviceGenevePrivate *priv = NM_DEVICE_GENEVE_GET_PRIVATE(device);
NMSettingGeneve *s_geneve;
if (!NM_DEVICE_CLASS(nm_device_geneve_parent_class)
->check_connection_compatible(device, connection, check_properties, error))
return FALSE;
if (check_properties && nm_device_is_real(device)) {
s_geneve = nm_connection_get_setting_geneve(connection);
if (priv->props.id != nm_setting_geneve_get_id(s_geneve)) {
nm_utils_error_set_literal(error,
NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
"geneve id mismatches");
return FALSE;
}
if (!address_matches(nm_setting_geneve_get_remote(s_geneve),
priv->props.remote,
&priv->props.remote6)) {
nm_utils_error_set_literal(error,
NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
"geneve remote address mismatches");
return FALSE;
}
if (priv->props.dst_port != nm_setting_geneve_get_destination_port(s_geneve)) {
nm_utils_error_set_literal(error,
NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
"geneve destination port mismatches");
return FALSE;
}
if (priv->props.tos != nm_setting_geneve_get_tos(s_geneve)) {
nm_utils_error_set_literal(error,
NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
"geneve TOS mismatches");
return FALSE;
}
if (priv->props.ttl != nm_setting_geneve_get_ttl(s_geneve)) {
nm_utils_error_set_literal(error,
NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
"geneve TTL mismatches");
return FALSE;
}
if (priv->props.df != nm_setting_geneve_get_df(s_geneve)) {
nm_utils_error_set_literal(error,
NM_UTILS_ERROR_CONNECTION_AVAILABLE_TEMPORARY,
"geneve DF mismatches");
return FALSE;
}
}
return TRUE;
}
static gboolean
complete_connection(NMDevice *device,
NMConnection *connection,
const char *specific_object,
NMConnection *const *existing_connections,
GError **error)
{
NMSettingGeneve *s_geneve;
nm_utils_complete_generic(nm_device_get_platform(device),
connection,
NM_SETTING_GENEVE_SETTING_NAME,
existing_connections,
NULL,
_("Geneve connection"),
NULL,
NULL);
s_geneve = nm_connection_get_setting_geneve(connection);
if (!s_geneve) {
g_set_error_literal(error,
NM_DEVICE_ERROR,
NM_DEVICE_ERROR_INVALID_CONNECTION,
"A 'geneve' setting is required.");
return FALSE;
}
return TRUE;
}
static void
update_connection(NMDevice *device, NMConnection *connection)
{
NMDeviceGenevePrivate *priv = NM_DEVICE_GENEVE_GET_PRIVATE(device);
NMSettingGeneve *s_geneve = _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_GENEVE);
char sbuf[NM_INET_ADDRSTRLEN];
if (priv->props.id != nm_setting_geneve_get_id(s_geneve))
g_object_set(G_OBJECT(s_geneve), NM_SETTING_GENEVE_ID, priv->props.id, NULL);
/* Handle remote (IPv4 or IPv6) */
if (priv->props.remote) {
g_object_set(s_geneve,
NM_SETTING_GENEVE_REMOTE,
nm_inet4_ntop(priv->props.remote, sbuf),
NULL);
} else if (memcmp(&priv->props.remote6, &in6addr_any, sizeof(in6addr_any))) {
g_object_set(s_geneve,
NM_SETTING_GENEVE_REMOTE,
nm_inet6_ntop(&priv->props.remote6, sbuf),
NULL);
}
if (priv->props.dst_port != nm_setting_geneve_get_destination_port(s_geneve))
g_object_set(G_OBJECT(s_geneve),
NM_SETTING_GENEVE_DESTINATION_PORT,
priv->props.dst_port,
NULL);
if (priv->props.tos != nm_setting_geneve_get_tos(s_geneve))
g_object_set(G_OBJECT(s_geneve), NM_SETTING_GENEVE_TOS, priv->props.tos, NULL);
if (priv->props.ttl != nm_setting_geneve_get_ttl(s_geneve))
g_object_set(G_OBJECT(s_geneve), NM_SETTING_GENEVE_TTL, priv->props.ttl, NULL);
if (priv->props.df != nm_setting_geneve_get_df(s_geneve))
g_object_set(G_OBJECT(s_geneve), NM_SETTING_GENEVE_DF, priv->props.df, NULL);
}
static void
get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
{
NMDeviceGenevePrivate *priv = NM_DEVICE_GENEVE_GET_PRIVATE(object);
switch (prop_id) {
case PROP_ID:
g_value_set_uint(value, priv->props.id);
break;
case PROP_REMOTE:
if (priv->props.remote)
g_value_take_string(value, nm_inet4_ntop_dup(priv->props.remote));
else if (!IN6_IS_ADDR_UNSPECIFIED(&priv->props.remote6))
g_value_take_string(value, nm_inet6_ntop_dup(&priv->props.remote6));
break;
case PROP_TOS:
g_value_set_uchar(value, priv->props.tos);
break;
case PROP_TTL:
g_value_set_uchar(value, priv->props.ttl);
break;
case PROP_DF:
g_value_set_uint(value, priv->props.df);
break;
case PROP_DST_PORT:
g_value_set_uint(value, priv->props.dst_port);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
}
}
/*****************************************************************************/
static void
nm_device_geneve_init(NMDeviceGeneve *self)
{}
static const NMDBusInterfaceInfoExtended interface_info_device_geneve = {
.parent = NM_DEFINE_GDBUS_INTERFACE_INFO_INIT(
NM_DBUS_INTERFACE_DEVICE_GENEVE,
.properties = NM_DEFINE_GDBUS_PROPERTY_INFOS(
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Id", "u", NM_DEVICE_GENEVE_ID),
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Remote", "s", NM_DEVICE_GENEVE_REMOTE),
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Tos", "y", NM_DEVICE_GENEVE_TOS),
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Ttl", "y", NM_DEVICE_GENEVE_TTL),
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Df", "u", NM_DEVICE_GENEVE_DF),
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("DstPort",
"q",
NM_DEVICE_GENEVE_DST_PORT), ), ),
};
static void
nm_device_geneve_class_init(NMDeviceGeneveClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS(klass);
NMDBusObjectClass *dbus_object_class = NM_DBUS_OBJECT_CLASS(klass);
NMDeviceClass *device_class = NM_DEVICE_CLASS(klass);
object_class->get_property = get_property;
dbus_object_class->interface_infos = NM_DBUS_INTERFACE_INFOS(&interface_info_device_geneve);
device_class->connection_type_supported = NM_SETTING_GENEVE_SETTING_NAME;
device_class->connection_type_check_compatible = NM_SETTING_GENEVE_SETTING_NAME;
device_class->link_types = NM_DEVICE_DEFINE_LINK_TYPES(NM_LINK_TYPE_GENEVE);
device_class->link_changed = link_changed;
device_class->unrealize_notify = unrealize_notify;
device_class->create_and_realize = create_and_realize;
device_class->check_connection_compatible = check_connection_compatible;
device_class->complete_connection = complete_connection;
device_class->get_generic_capabilities = get_generic_capabilities;
device_class->update_connection = update_connection;
obj_properties[PROP_ID] = g_param_spec_uint(NM_DEVICE_GENEVE_ID,
"",
"",
0,
G_MAXUINT32,
0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
obj_properties[PROP_REMOTE] = g_param_spec_string(NM_DEVICE_GENEVE_REMOTE,
"",
"",
NULL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
obj_properties[PROP_TOS] = g_param_spec_uchar(NM_DEVICE_GENEVE_TOS,
"",
"",
0,
255,
0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
obj_properties[PROP_TTL] = g_param_spec_uchar(NM_DEVICE_GENEVE_TTL,
"",
"",
0,
255,
0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
obj_properties[PROP_DF] = g_param_spec_uint(NM_DEVICE_GENEVE_DF,
"",
"",
0,
2,
0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
obj_properties[PROP_DST_PORT] = g_param_spec_uint(NM_DEVICE_GENEVE_DST_PORT,
"",
"",
0,
65535,
0,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties);
}
/*****************************************************************************/
#define NM_TYPE_GENEVE_DEVICE_FACTORY (nm_geneve_device_factory_get_type())
#define NM_GENEVE_DEVICE_FACTORY(obj) \
(_NM_G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_GENEVE_DEVICE_FACTORY, NMGeneveDeviceFactory))
static NMDevice *
create_device(NMDeviceFactory *factory,
const char *iface,
const NMPlatformLink *plink,
NMConnection *connection,
gboolean *out_ignore)
{
return g_object_new(NM_TYPE_DEVICE_GENEVE,
NM_DEVICE_IFACE,
iface,
NM_DEVICE_TYPE_DESC,
"Geneve",
NM_DEVICE_DEVICE_TYPE,
NM_DEVICE_TYPE_GENEVE,
NM_DEVICE_LINK_TYPE,
NM_LINK_TYPE_GENEVE,
NULL);
}
NM_DEVICE_FACTORY_DEFINE_INTERNAL(
GENEVE,
Geneve,
geneve,
NM_DEVICE_FACTORY_DECLARE_LINK_TYPES(NM_LINK_TYPE_GENEVE)
NM_DEVICE_FACTORY_DECLARE_SETTING_TYPES(NM_SETTING_GENEVE_SETTING_NAME),
factory_class->create_device = create_device;);

View file

@ -1,33 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/*
* Copyright (C) 2026 Red Hat, Inc.
*/
#ifndef __NETWORKMANAGER_DEVICE_GENEVE_H__
#define __NETWORKMANAGER_DEVICE_GENEVE_H__
#include "nm-device.h"
#define NM_TYPE_DEVICE_GENEVE (nm_device_geneve_get_type())
#define NM_DEVICE_GENEVE(obj) \
(_NM_G_TYPE_CHECK_INSTANCE_CAST((obj), NM_TYPE_DEVICE_GENEVE, NMDeviceGeneve))
#define NM_DEVICE_GENEVE_CLASS(klass) \
(G_TYPE_CHECK_CLASS_CAST((klass), NM_TYPE_DEVICE_GENEVE, NMDeviceGeneveClass))
#define NM_IS_DEVICE_GENEVE(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NM_TYPE_DEVICE_GENEVE))
#define NM_IS_DEVICE_GENEVE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NM_TYPE_DEVICE_GENEVE))
#define NM_DEVICE_GENEVE_GET_CLASS(obj) \
(G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_DEVICE_GENEVE, NMDeviceGeneveClass))
#define NM_DEVICE_GENEVE_ID "id"
#define NM_DEVICE_GENEVE_REMOTE "remote"
#define NM_DEVICE_GENEVE_TOS "tos"
#define NM_DEVICE_GENEVE_TTL "ttl"
#define NM_DEVICE_GENEVE_DF "df"
#define NM_DEVICE_GENEVE_DST_PORT "dst-port"
typedef struct _NMDeviceGeneve NMDeviceGeneve;
typedef struct _NMDeviceGeneveClass NMDeviceGeneveClass;
GType nm_device_geneve_get_type(void);
#endif /* __NETWORKMANAGER_DEVICE_GENEVE_H__ */

View file

@ -176,14 +176,14 @@ create_and_realize(NMDevice *device,
if (str) {
if (!nm_inet_parse_bin(AF_INET, str, NULL, &props.local)
&& !nm_inet_parse_bin(AF_INET6, str, NULL, &props.local6))
return nm_assert_unreachable_val(FALSE);
return FALSE;
}
str = nm_setting_vxlan_get_remote(s_vxlan);
if (str) {
if (!nm_inet_parse_bin(AF_INET, str, NULL, &props.group)
&& !nm_inet_parse_bin(AF_INET6, str, NULL, &props.group6))
return nm_assert_unreachable_val(FALSE);
return FALSE;
}
props.tos = nm_setting_vxlan_get_tos(s_vxlan);

File diff suppressed because it is too large Load diff

View file

@ -791,7 +791,6 @@ void nm_device_update_permanent_hw_address(NMDevice *self, gboolean force_fr
void nm_device_update_dynamic_ip_setup(NMDevice *self, const char *reason);
guint nm_device_get_supplicant_timeout(NMDevice *self);
gboolean nm_device_auth_retries_has_next(NMDevice *self);
gboolean nm_device_auth_retries_try_next(NMDevice *self);
gboolean nm_device_hw_addr_get_cloned(NMDevice *self,

View file

@ -2270,37 +2270,6 @@ add_new:
return NM_ACT_STAGE_RETURN_SUCCESS;
}
static void
set_powersave(NMDevice *device)
{
NMDeviceIwd *self = NM_DEVICE_IWD(device);
NMSettingWireless *s_wireless;
NMSettingWirelessPowersave val;
s_wireless = nm_device_get_applied_setting(device, NM_TYPE_SETTING_WIRELESS);
g_return_if_fail(s_wireless);
val = nm_setting_wireless_get_powersave(s_wireless);
if (val == NM_SETTING_WIRELESS_POWERSAVE_DEFAULT) {
val = nm_config_data_get_connection_default_int64(NM_CONFIG_GET_DATA,
"wifi.powersave",
device,
NM_SETTING_WIRELESS_POWERSAVE_IGNORE,
NM_SETTING_WIRELESS_POWERSAVE_ENABLE,
NM_SETTING_WIRELESS_POWERSAVE_IGNORE);
}
_LOGT(LOGD_WIFI, "powersave is set to %u", (unsigned) val);
if (val == NM_SETTING_WIRELESS_POWERSAVE_IGNORE)
return;
nm_platform_wifi_set_powersave(nm_device_get_platform(device),
nm_device_get_ifindex(device),
val == NM_SETTING_WIRELESS_POWERSAVE_ENABLE);
}
static NMActStageReturn
act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason)
{
@ -2328,8 +2297,6 @@ act_stage2_config(NMDevice *device, NMDeviceStateReason *out_failure_reason)
goto out_fail;
}
set_powersave(device);
/* With priv->iwd_autoconnect we have to let IWD handle retries for
* infrastructure networks. IWD will not necessarily retry the same
* network after a failure but it will likely go into an autoconnect

View file

@ -194,9 +194,6 @@ static void supplicant_iface_notify_p2p_available(NMSupplicantInterface *iface,
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,
@ -634,10 +631,6 @@ supplicant_interface_acquire_cb(NMSupplicantManager *supplicant_manager,
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);
@ -2251,26 +2244,6 @@ wps_timeout_cb(gpointer user_data)
return G_SOURCE_REMOVE;
}
static gboolean
wifi_connection_is_new(NMDeviceWifi *self)
{
NMDevice *device = NM_DEVICE(self);
NMActRequest *req;
NMSettingsConnection *connection;
guint64 timestamp = 0;
req = nm_device_get_act_request(device);
g_return_val_if_fail(NM_IS_ACT_REQUEST(req), TRUE);
connection = nm_act_request_get_settings_connection(req);
g_return_val_if_fail(NM_IS_SETTINGS_CONNECTION(connection), TRUE);
if (nm_settings_connection_get_timestamp(connection, &timestamp) && timestamp != 0)
return FALSE;
return TRUE;
}
static void
wifi_secrets_get_secrets(NMDeviceWifi *self,
const char *setting_name,
@ -2425,11 +2398,10 @@ handle_8021x_or_psk_auth_fail(NMDeviceWifi *self,
NMSupplicantInterfaceState old_state,
int disconnect_reason)
{
NMDevice *device = NM_DEVICE(self);
NMActRequest *req;
const char *setting_name = NULL;
NMSecretAgentGetSecretsFlags secret_flags = NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION
| NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW;
NMDevice *device = NM_DEVICE(self);
NMActRequest *req;
const char *setting_name = NULL;
gboolean handled = FALSE;
g_return_val_if_fail(new_state == NM_SUPPLICANT_INTERFACE_STATE_DISCONNECTED, FALSE);
@ -2439,7 +2411,8 @@ handle_8021x_or_psk_auth_fail(NMDeviceWifi *self,
req = nm_device_get_act_request(NM_DEVICE(self));
g_return_val_if_fail(req != NULL, FALSE);
if (need_new_8021x_secrets(self, old_state, &setting_name)) {
if (need_new_8021x_secrets(self, old_state, &setting_name)
|| need_new_wpa_psk(self, old_state, disconnect_reason, &setting_name)) {
nm_act_request_clear_secrets(req);
_LOGI(LOGD_DEVICE | LOGD_WIFI,
@ -2449,54 +2422,14 @@ handle_8021x_or_psk_auth_fail(NMDeviceWifi *self,
nm_device_state_changed(device,
NM_DEVICE_STATE_NEED_AUTH,
NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT);
wifi_secrets_get_secrets(self, setting_name, secret_flags);
return TRUE;
wifi_secrets_get_secrets(self,
setting_name,
NM_SECRET_AGENT_GET_SECRETS_FLAG_ALLOW_INTERACTION
| NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW);
handled = TRUE;
}
if (need_new_wpa_psk(self, old_state, disconnect_reason, &setting_name)) {
nm_act_request_clear_secrets(req);
cleanup_association_attempt(self, TRUE);
if (wifi_connection_is_new(self)) {
_LOGI(LOGD_DEVICE | LOGD_WIFI,
"Activation: (wifi) new connection disconnected during association, asking for "
"new key");
nm_device_state_changed(device,
NM_DEVICE_STATE_NEED_AUTH,
NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT);
wifi_secrets_get_secrets(self, setting_name, secret_flags);
return TRUE;
}
if (!nm_device_auth_retries_try_next(device)) {
nm_device_state_changed(device,
NM_DEVICE_STATE_FAILED,
NM_DEVICE_STATE_REASON_NO_SECRETS);
return TRUE;
}
if (nm_device_auth_retries_has_next(device)) {
secret_flags &= ~NM_SECRET_AGENT_GET_SECRETS_FLAG_REQUEST_NEW;
_LOGI(
LOGD_DEVICE | LOGD_WIFI,
"Activation: (wifi) disconnected during association, reauthenticating connection");
} else {
_LOGI(LOGD_DEVICE | LOGD_WIFI,
"Activation: (wifi) disconnected during association, asking for new key");
}
nm_device_state_changed(device,
NM_DEVICE_STATE_NEED_AUTH,
NM_DEVICE_STATE_REASON_SUPPLICANT_DISCONNECT);
wifi_secrets_get_secrets(self, setting_name, secret_flags);
return TRUE;
}
_LOGI(LOGD_DEVICE | LOGD_WIFI,
"Activation: (wifi) disconnected during association, retrying connection");
return FALSE;
return handled;
}
static gboolean
@ -2928,12 +2861,6 @@ supplicant_iface_notify_wpa_psk_mismatch_cb(NMSupplicantInterface *iface, NMDevi
if (nm_device_get_state(device) != NM_DEVICE_STATE_CONFIG)
return;
if (!wifi_connection_is_new(self) && nm_device_auth_retries_has_next(device)) {
_LOGI(LOGD_DEVICE | LOGD_WIFI,
"Activation: (wifi) psk mismatch reported by supplicant, retrying connection");
return;
}
_LOGI(LOGD_DEVICE | LOGD_WIFI,
"Activation: (wifi) psk mismatch reported by supplicant, asking for new key");
@ -2952,34 +2879,6 @@ supplicant_iface_notify_wpa_psk_mismatch_cb(NMSupplicantInterface *iface, NMDevi
| 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
*
@ -3323,19 +3222,8 @@ act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason)
static void
ensure_hotspot_frequency(NMDeviceWifi *self, NMSettingWireless *s_wifi, NMWifiAP *ap)
{
guint32 freqs_a[] = {5180, /* only U-NII-1 channels: non-DFS and available everywhere */
5200,
5220,
5240,
0};
guint32 freqs_bg[] = {2412, 2437, 2462, 2472, 0};
guint32 freqs_6ghz[] = {5975, /* only U-NII-5 PSC channels, for better compatibility */
6055,
6135,
6215,
6295,
6375,
0};
guint32 a_freqs[] = {5180, 5200, 5220, 5745, 5765, 5785, 5805, 0};
guint32 bg_freqs[] = {2412, 2437, 2462, 2472, 0};
guint32 *rnd_freqs;
guint rnd_freqs_len;
NMDevice *device = NM_DEVICE(self);
@ -3346,7 +3234,7 @@ ensure_hotspot_frequency(NMDeviceWifi *self, NMSettingWireless *s_wifi, NMWifiAP
guint l;
nm_assert(ap);
nm_assert(NM_IN_STRSET(band, NULL, "a", "bg", "6GHz"));
nm_assert(NM_IN_STRSET(band, NULL, "a", "bg"));
if (nm_wifi_ap_get_freq(ap))
return;
@ -3380,14 +3268,11 @@ ensure_hotspot_frequency(NMDeviceWifi *self, NMSettingWireless *s_wifi, NMWifiAP
}
if (nm_streq0(band, "a")) {
rnd_freqs = freqs_a;
rnd_freqs_len = G_N_ELEMENTS(freqs_a) - 1;
} else if (nm_streq0(band, "6GHz")) {
rnd_freqs = freqs_6ghz;
rnd_freqs_len = G_N_ELEMENTS(freqs_6ghz) - 1;
rnd_freqs = a_freqs;
rnd_freqs_len = G_N_ELEMENTS(a_freqs) - 1;
} else {
rnd_freqs = freqs_bg;
rnd_freqs_len = G_N_ELEMENTS(freqs_bg) - 1;
rnd_freqs = bg_freqs;
rnd_freqs_len = G_N_ELEMENTS(bg_freqs) - 1;
}
/* shuffle the frequencies (inplace). The idea is to choose

View file

@ -574,6 +574,16 @@ nm_wifi_ap_to_string(const NMWifiAP *self, char *str_buf, gulong buf_len, gint64
return str_buf;
}
static guint
freq_to_band(guint32 freq)
{
if (freq >= 4915 && freq <= 5825)
return 5;
else if (freq >= 2412 && freq <= 2484)
return 2;
return 0;
}
gboolean
nm_wifi_ap_check_compatible(NMWifiAP *self, NMConnection *connection)
{
@ -621,12 +631,12 @@ nm_wifi_ap_check_compatible(NMWifiAP *self, NMConnection *connection)
band = nm_setting_wireless_get_band(s_wireless);
if (band) {
const char *ap_band = nm_wifi_freq_to_band_prop(priv->freq);
guint ap_band = freq_to_band(priv->freq);
if (!nm_streq(band, ap_band))
if (!strcmp(band, "a") && ap_band != 5)
return FALSE;
else if (!strcmp(band, "bg") && ap_band != 2)
return FALSE;
return TRUE;
}
channel = nm_setting_wireless_get_channel(s_wireless);

View file

@ -639,7 +639,7 @@ nm_wifi_utils_complete_connection(GBytes *ap_ssid,
chan_valid = FALSE;
}
band = nm_wifi_freq_to_band_prop(ap_freq);
band = nm_utils_wifi_freq_to_band(ap_freq);
if (band) {
g_object_set(s_wifi, NM_SETTING_WIRELESS_BAND, band, NULL);
} else {
@ -1929,19 +1929,3 @@ nm_wifi_utils_wfd_info_eq(const NMIwdWfdInfo *a, const NMIwdWfdInfo *b)
return a->source == b->source && a->sink == b->sink && a->port == b->port
&& a->has_audio == b->has_audio && a->has_uibc == b->has_uibc && a->has_cp == b->has_cp;
}
const char *
nm_wifi_freq_to_band_prop(guint32 freq)
{
switch (nm_utils_wifi_freq_to_band(freq)) {
case NM_WIFI_BAND_2_4_GHZ:
return "bg";
case NM_WIFI_BAND_5_GHZ:
return "a";
case NM_WIFI_BAND_6_GHZ:
return "6GHz";
default:
case NM_WIFI_BAND_UNKNOWN:
return NULL;
}
}

View file

@ -56,6 +56,4 @@ bool nm_wifi_utils_parse_wfd_ies(GBytes *ies, NMIwdWfdInfo *out_wfd);
GBytes *nm_wifi_utils_build_wfd_ies(const NMIwdWfdInfo *wfd);
bool nm_wifi_utils_wfd_info_eq(const NMIwdWfdInfo *a, const NMIwdWfdInfo *b);
const char *nm_wifi_freq_to_band_prop(guint32 freq);
#endif /* __NM_WIFI_UTILS_H__ */

View file

@ -258,7 +258,16 @@ modm_handle_name_owner_changed(MMManager *modem_manager, GParamSpec *pspec, NMMo
/* Available! */
g_free(name_owner);
modm_manager_available(self);
/* Hack alert: GDBusObjectManagerClient won't signal neither 'object-added'
* nor 'object-removed' if it was created while there was no ModemManager in
* the bus. This hack avoids this issue until we get a GIO with the fix
* included... */
modm_clear_manager(self);
modm_ensure_manager(self);
/* Whenever GDBusObjectManagerClient is fixed, we can just do the following:
* modm_manager_available (self);
*/
}
static void

View file

@ -1460,9 +1460,7 @@ nm_dhcp_client_schedule_ipv6_only_restart(NMDhcpClient *self, guint timeout)
nm_assert(!priv->is_stopped);
timeout = NM_MAX(priv->v4.ipv6_only_min_wait, timeout);
_LOGI("received option \"ipv6-only-preferred\": stopping DHCPv4 for %u seconds. Set "
"ipv4.dhcp-ipv6-only-preferred=no to force the use of IPv4 on this IPv6-mostly network",
timeout);
_LOGI("received option \"ipv6-only-preferred\": stopping DHCPv4 for %u seconds", timeout);
nm_dhcp_client_stop(self, FALSE);
nm_clear_g_source_inst(&priv->no_lease_timeout_source);

View file

@ -418,6 +418,7 @@ lease_parse_routes(NDhcp4ClientLease *lease,
in_addr_t gateway;
uint8_t plen;
guint32 m;
gboolean has_router_from_classless = FALSE;
gboolean has_classless = FALSE;
guint32 default_route_metric_offset = 0;
const guint8 *l_data;
@ -433,7 +434,7 @@ lease_parse_routes(NDhcp4ClientLease *lease,
* We will however also parse one of the options into the "l3cd" for configuring routing.
* Thereby we prefer 121 over 249 over 33.
*
* Preferring 121 over 33 is defined by RFC 3442.
* Preferring 121 over 33 is defined by RFC 3443.
* Preferring 121 over 249 over 33 is made up as it makes sense (the MS docs are not very clear).
*/
for (i = 0; i < 2; i++) {
@ -459,7 +460,8 @@ lease_parse_routes(NDhcp4ClientLease *lease,
if (plen == 0) {
/* if there are multiple default routes, we add them with differing
* metrics. */
m = default_route_metric_offset++;
m = default_route_metric_offset++;
has_router_from_classless = TRUE;
} else
m = 0;
@ -493,7 +495,7 @@ lease_parse_routes(NDhcp4ClientLease *lease,
nm_str_buf_append_printf(sbuf, "%s/%d %s", dest_str, (int) plen, gateway_str);
if (has_classless) {
/* RFC 3442: if the DHCP server returns both a Classless Static Routes
/* RFC 3443: if the DHCP server returns both a Classless Static Routes
* option and a Static Routes option, the DHCP client MUST ignore the
* Static Routes option. */
continue;
@ -537,10 +539,13 @@ lease_parse_routes(NDhcp4ClientLease *lease,
continue;
}
if (has_classless) {
/* RFC 3442: if the DHCP server returns both a Classless Static Routes
* option and a Router option, the DHCP client MUST ignore the Router
* option. */
if (has_router_from_classless) {
/* If the DHCP server returns both a Classless Static Routes option and a
* Router option, the DHCP client MUST ignore the Router option [RFC 3442].
*
* Be more lenient and ignore the Router option only if Classless Static
* Routes contain a default gateway (as other DHCP backends do).
*/
continue;
}

View file

@ -32,11 +32,11 @@ ip4_process_dhcpcd_rfc3442_routes(const char *iface,
in_addr_t address,
guint32 *out_gwaddr)
{
gs_free char **routes = NULL;
char **r;
gboolean have_routes = FALSE;
gs_free const char **routes = NULL;
const char **r;
gboolean have_routes = FALSE;
routes = (char **) nm_strsplit_set(str, " ");
routes = nm_strsplit_set(str, " ");
if (!routes)
return FALSE;

View file

@ -1510,8 +1510,8 @@ _domain_track_is_shadowed(GHashTable *ht,
const char **out_parent,
int *out_parent_priority)
{
const char *parent;
int parent_priority;
char *parent;
int parent_priority;
if (!ht)
return FALSE;

View file

@ -298,6 +298,12 @@ main(int argc, char *argv[])
_nm_utils_is_manager_process = TRUE;
/* Known to cause a possible deadlock upon GDBus initialization:
* https://bugzilla.gnome.org/show_bug.cgi?id=674885 */
g_type_ensure(G_TYPE_SOCKET);
g_type_ensure(G_TYPE_DBUS_CONNECTION);
g_type_ensure(NM_TYPE_DBUS_MANAGER);
/* we determine a first-start (contrary to a restart during the same boot)
* based on the existence of NM_CONFIG_DEVICE_STATE_DIR directory. */
config_cli = nm_config_cmd_line_options_new(
@ -322,12 +328,6 @@ main(int argc, char *argv[])
exit(result);
}
/* Known to cause a possible deadlock upon GDBus initialization:
* https://bugzilla.gnome.org/show_bug.cgi?id=674885 */
g_type_ensure(G_TYPE_SOCKET);
g_type_ensure(G_TYPE_DBUS_CONNECTION);
g_type_ensure(NM_TYPE_DBUS_MANAGER);
nm_main_utils_ensure_not_running_pidfile(global_opt.pidfile);
nm_main_utils_ensure_statedir();
@ -461,8 +461,14 @@ main(int argc, char *argv[])
/* the first access to State causes the file to be read (and possibly print a warning) */
nm_config_state_get(config);
nm_log_dbg(LOGD_CORE, "WEXT support is %s", HAVE_WEXT ? "enabled" : "disabled");
nm_log_dbg(LOGD_CORE, "CLAT support is %s", HAVE_CLAT ? "enabled" : "disabled");
nm_log_dbg(LOGD_CORE,
"WEXT support is %s",
#if HAVE_WEXT
"enabled"
#else
"disabled"
#endif
);
if (!_dbus_manager_init(config))
goto done_no_manager;

View file

@ -32,15 +32,6 @@ install_data(
core_plugins = []
subdir('bpf')
base_sources_addon = []
base_deps_addon = []
if enable_clat
base_sources_addon += [clat_skel_h]
base_deps_addon += [libbpf]
endif
libNetworkManagerBase = static_library(
'NetworkManagerBase',
sources: files(
@ -64,13 +55,13 @@ libNetworkManagerBase = static_library(
'nm-l3cfg.c',
'nm-bond-manager.c',
'nm-ip-config.c',
) + base_sources_addon,
),
dependencies: [
core_default_dep,
libnm_core_public_dep,
libsystemd_dep,
libudev_dep,
] + base_deps_addon,
],
)
nm_deps = [
@ -111,7 +102,6 @@ libNetworkManager = static_library(
'devices/nm-device-ethernet-utils.c',
'devices/nm-device-factory.c',
'devices/nm-device-generic.c',
'devices/nm-device-geneve.c',
'devices/nm-device-hsr.c',
'devices/nm-device-infiniband.c',
'devices/nm-device-ip-tunnel.c',

View file

@ -401,30 +401,6 @@ receive_ra(struct ndp *ndp, struct ndp_msg *msg, gpointer user_data)
}
}
#if HAVE_CLAT
/* PREF64 */
ndp_msg_opt_for_each_offset (offset, msg, NDP_MSG_OPT_PREF64) {
NMNDiscPref64 pref64;
pref64 = (NMNDiscPref64) {
.prefix = *ndp_msg_opt_pref64_prefix(msg, offset),
.plen = ndp_msg_opt_pref64_prefix_length(msg, offset),
.gateway = gateway.address,
.gateway_preference = gateway.preference,
.expiry_msec =
_nm_ndisc_lifetime_to_expiry(now_msec, ndp_msg_opt_pref64_lifetime(msg, offset)),
.gateway_expiry_msec = gateway.expiry_msec,
};
/* libndp should only return lengths defined in RFC 8781 */
nm_assert(NM_IN_SET(pref64.plen, 96, 64, 56, 48, 40, 32));
if (nm_ndisc_add_pref64(ndisc, &pref64, now_msec)) {
changed |= NM_NDISC_CONFIG_PREF64;
}
}
#endif
nm_ndisc_ra_received(ndisc, now_msec, changed);
return 0;
}

View file

@ -14,7 +14,6 @@ struct _NMNDiscDataInternal {
NMNDiscData public;
GArray *gateways;
GArray *addresses;
GArray *pref64;
GArray *routes;
GArray *dns_servers;
GArray *dns_domains;
@ -29,7 +28,6 @@ gboolean nm_ndisc_add_gateway(NMNDisc *ndisc, const NMNDiscGateway *new_item, gi
gboolean
nm_ndisc_complete_and_add_address(NMNDisc *ndisc, const NMNDiscAddress *new_item, gint64 now_msec);
gboolean nm_ndisc_add_route(NMNDisc *ndisc, const NMNDiscRoute *new_item, gint64 now_msec);
gboolean nm_ndisc_add_pref64(NMNDisc *ndisc, const NMNDiscPref64 *new_item, gint64 now_msec);
gboolean nm_ndisc_add_dns_server(NMNDisc *ndisc, const NMNDiscDNSServer *new_item, gint64 now_msec);
gboolean nm_ndisc_add_dns_domain(NMNDisc *ndisc, const NMNDiscDNSDomain *new_item, gint64 now_msec);

View file

@ -34,7 +34,6 @@
#define _SIZE_MAX_ROUTES 1000u
#define _SIZE_MAX_DNS_SERVERS 64u
#define _SIZE_MAX_DNS_DOMAINS 64u
#define _SIZE_MAX_PREF64 8u
/*****************************************************************************/
@ -110,8 +109,7 @@ nm_ndisc_data_to_l3cd(NMDedupMultiIndex *multi_idx,
int ifindex,
const NMNDiscData *rdata,
NMSettingIP6ConfigPrivacy ip6_privacy,
NMUtilsIPv6IfaceId *token,
const char *network_id)
NMUtilsIPv6IfaceId *token)
{
nm_auto_unref_l3cd_init NML3ConfigData *l3cd = NULL;
guint32 ifa_flags;
@ -213,21 +211,13 @@ nm_ndisc_data_to_l3cd(NMDedupMultiIndex *multi_idx,
for (i = 0; i < rdata->dns_domains_n; i++)
nm_l3_config_data_add_search(l3cd, AF_INET6, rdata->dns_domains[i].domain);
if (rdata->pref64_n > 0) {
nm_l3_config_data_set_pref64(l3cd, rdata->pref64[0].prefix, rdata->pref64[0].plen);
} else {
nm_l3_config_data_set_pref64_valid(l3cd, FALSE);
}
nm_l3_config_data_set_ndisc_hop_limit(l3cd, rdata->hop_limit);
nm_l3_config_data_set_ndisc_reachable_time_msec(l3cd, rdata->reachable_time_ms);
nm_l3_config_data_set_ndisc_retrans_timer_msec(l3cd, rdata->retrans_timer_ms);
nm_l3_config_data_set_ip6_mtu_ra(l3cd, rdata->mtu);
nm_l3_config_data_set_ip6_mtu(l3cd, rdata->mtu);
if (token)
nm_l3_config_data_set_ip6_token(l3cd, *token);
if (network_id)
nm_l3_config_data_set_network_id(l3cd, network_id);
return g_steal_pointer(&l3cd);
}
@ -426,7 +416,6 @@ _data_complete(NMNDiscDataInternal *data)
_SET(data, gateways);
_SET(data, addresses);
_SET(data, routes);
_SET(data, pref64);
_SET(data, dns_servers);
_SET(data, dns_domains);
#undef _SET
@ -448,8 +437,7 @@ nm_ndisc_emit_config_change(NMNDisc *self, NMNDiscConfigMap changed)
nm_l3cfg_get_ifindex(priv->config.l3cfg),
rdata,
priv->config.ip6_privacy,
priv->iid_is_token ? &priv->iid : NULL,
priv->config.network_id);
priv->iid_is_token ? &priv->iid : NULL);
l3cd = nm_l3_config_data_seal(l3cd);
if (!nm_l3_config_data_equal(priv->l3cd, l3cd))
@ -772,59 +760,6 @@ nm_ndisc_add_route(NMNDisc *ndisc, const NMNDiscRoute *new_item, gint64 now_msec
return TRUE;
}
gboolean
nm_ndisc_add_pref64(NMNDisc *ndisc, const NMNDiscPref64 *new_item, gint64 now_msec)
{
NMNDiscDataInternal *rdata = &NM_NDISC_GET_PRIVATE(ndisc)->rdata;
guint i;
guint insert_idx = G_MAXUINT;
for (i = 0; i < rdata->pref64->len;) {
NMNDiscPref64 *item = &nm_g_array_index(rdata->pref64, NMNDiscPref64, i);
if (item->plen == new_item->plen && IN6_ARE_ADDR_EQUAL(&item->prefix, &new_item->prefix)
&& IN6_ARE_ADDR_EQUAL(&item->gateway, &new_item->gateway)) {
if (new_item->expiry_msec <= now_msec) {
g_array_remove_index(rdata->pref64, i);
return TRUE;
}
if (item->gateway_preference != new_item->gateway_preference) {
g_array_remove_index(rdata->pref64, i);
continue;
}
item->gateway_expiry_msec = new_item->gateway_expiry_msec;
if (item->expiry_msec == new_item->expiry_msec)
return FALSE;
item->expiry_msec = new_item->expiry_msec;
return TRUE;
}
/* Put before less preferable gateways. */
if (_preference_to_priority(item->gateway_preference)
< _preference_to_priority(new_item->gateway_preference)
&& insert_idx == G_MAXUINT)
insert_idx = i;
i++;
}
if (rdata->pref64->len >= _SIZE_MAX_PREF64)
return FALSE;
if (new_item->expiry_msec <= now_msec)
return FALSE;
g_array_insert_val(rdata->pref64,
insert_idx == G_MAXUINT ? rdata->pref64->len : insert_idx,
*new_item);
return TRUE;
}
gboolean
nm_ndisc_add_dns_server(NMNDisc *ndisc, const NMNDiscDNSServer *new_item, gint64 now_msec)
{
@ -1465,17 +1400,6 @@ _config_changed_log(NMNDisc *ndisc, NMNDiscConfigMap changed)
nm_icmpv6_router_pref_to_string(route->preference, str_pref, sizeof(str_pref)),
get_exp(str_exp, now_msec, route));
}
for (i = 0; i < rdata->pref64->len; i++) {
const NMNDiscPref64 *pref64 = &nm_g_array_index(rdata->pref64, NMNDiscPref64, i);
char addrstr2[NM_INET_ADDRSTRLEN];
_LOGD(" pref64 %s/%u via %s exp %s",
nm_inet6_ntop(&pref64->prefix, addrstr),
pref64->plen,
nm_inet6_ntop(&pref64->gateway, addrstr2),
get_exp(str_exp, now_msec, pref64));
}
for (i = 0; i < rdata->dns_servers->len; i++) {
const NMNDiscDNSServer *dns_server =
&nm_g_array_index(rdata->dns_servers, NMNDiscDNSServer, i);
@ -1600,45 +1524,6 @@ clean_routes(NMNDisc *ndisc, gint64 now_msec, NMNDiscConfigMap *changed, gint64
*changed |= NM_NDISC_CONFIG_ROUTES;
}
static void
clean_pref64(NMNDisc *ndisc, gint64 now_msec, NMNDiscConfigMap *changed, gint64 *next_msec)
{
NMNDiscDataInternal *rdata = &NM_NDISC_GET_PRIVATE(ndisc)->rdata;
NMNDiscPref64 *arr;
guint i;
guint j;
if (rdata->pref64->len == 0)
return;
arr = &nm_g_array_first(rdata->pref64, NMNDiscPref64);
for (i = 0, j = 0; i < rdata->pref64->len; i++) {
if (!expiry_next(now_msec, arr[i].expiry_msec, next_msec)
|| !expiry_next(now_msec,
arr[i].gateway_expiry_msec,
next_msec)) { /* no gateway no party */
if (i == 0) {
/* Emit the changed signal only when the first PREF64 expires,
* because only the first item is exported into the l3cd. Changes
* in other PREF64s are not relevant. */
*changed |= NM_NDISC_CONFIG_PREF64;
}
continue;
}
if (i != j)
arr[j] = arr[i];
j++;
}
if (i != j) {
g_array_set_size(rdata->pref64, j);
}
_array_set_size_max(rdata->pref64, _SIZE_MAX_PREF64);
}
static void
clean_dns_servers(NMNDisc *ndisc, gint64 now_msec, NMNDiscConfigMap *changed, gint64 *next_msec)
{
@ -1715,7 +1600,6 @@ check_timestamps(NMNDisc *ndisc, gint64 now_msec, NMNDiscConfigMap changed)
clean_gateways(ndisc, now_msec, &changed, &next_msec);
clean_addresses(ndisc, now_msec, &changed, &next_msec);
clean_routes(ndisc, now_msec, &changed, &next_msec);
clean_pref64(ndisc, now_msec, &changed, &next_msec);
clean_dns_servers(ndisc, now_msec, &changed, &next_msec);
clean_dns_domains(ndisc, now_msec, &changed, &next_msec);
@ -2035,7 +1919,6 @@ nm_ndisc_init(NMNDisc *ndisc)
rdata->gateways = g_array_new(FALSE, FALSE, sizeof(NMNDiscGateway));
rdata->addresses = g_array_new(FALSE, FALSE, sizeof(NMNDiscAddress));
rdata->routes = g_array_new(FALSE, FALSE, sizeof(NMNDiscRoute));
rdata->pref64 = g_array_new(FALSE, FALSE, sizeof(NMNDiscPref64));
rdata->dns_servers = g_array_new(FALSE, FALSE, sizeof(NMNDiscDNSServer));
rdata->dns_domains = g_array_new(FALSE, FALSE, sizeof(NMNDiscDNSDomain));
g_array_set_clear_func(rdata->dns_domains, dns_domain_free);
@ -2068,7 +1951,6 @@ finalize(GObject *object)
g_array_unref(rdata->gateways);
g_array_unref(rdata->addresses);
g_array_unref(rdata->routes);
g_array_unref(rdata->pref64);
g_array_unref(rdata->dns_servers);
g_array_unref(rdata->dns_domains);

View file

@ -119,15 +119,6 @@ typedef struct _NMNDiscRoute {
bool duplicate : 1;
} NMNDiscRoute;
typedef struct _NMNDiscPref64 {
struct in6_addr prefix;
struct in6_addr gateway;
gint64 expiry_msec;
gint64 gateway_expiry_msec;
NMIcmpv6RouterPref gateway_preference;
guint8 plen;
} NMNDiscPref64;
typedef struct {
struct in6_addr address;
gint64 expiry_msec;
@ -150,7 +141,6 @@ typedef enum {
NM_NDISC_CONFIG_MTU = 1 << 7,
NM_NDISC_CONFIG_REACHABLE_TIME = 1 << 8,
NM_NDISC_CONFIG_RETRANS_TIMER = 1 << 9,
NM_NDISC_CONFIG_PREF64 = 1 << 10,
} NMNDiscConfigMap;
typedef enum {
@ -198,14 +188,12 @@ typedef struct {
guint gateways_n;
guint addresses_n;
guint routes_n;
guint pref64_n;
guint dns_servers_n;
guint dns_domains_n;
const NMNDiscGateway *gateways;
const NMNDiscAddress *addresses;
const NMNDiscRoute *routes;
const NMNDiscPref64 *pref64;
const NMNDiscDNSServer *dns_servers;
const NMNDiscDNSDomain *dns_domains;
} NMNDiscData;
@ -294,7 +282,6 @@ struct _NML3ConfigData *nm_ndisc_data_to_l3cd(NMDedupMultiIndex *multi_id
int ifindex,
const NMNDiscData *rdata,
NMSettingIP6ConfigPrivacy ip6_privacy,
NMUtilsIPv6IfaceId *token,
const char *network_id);
NMUtilsIPv6IfaceId *token);
#endif /* __NETWORKMANAGER_NDISC_H__ */

View file

@ -39,9 +39,7 @@ typedef struct {
bool activation_lifetime_bound_to_profile_visibility : 1;
bool settings_connection_is_unsaved : 1;
bool settings_connection_is_shadowed_owned : 1;
bool permanent_managed_by_mac : 1;
NMUnmanFlagOp unmanaged_explicit;
NMTernary permanent_managed;
NMActivationReason activation_reason;
gulong dev_exported_change_id;
} DeviceCheckpoint;
@ -162,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;
const char *sep;
char *sep;
keyfile = g_key_file_new();
if (!g_key_file_load_from_file(keyfile, path, G_KEY_FILE_NONE, error))
@ -498,19 +496,14 @@ nm_checkpoint_rollback(NMCheckpoint *self)
/* Start rolling-back each device */
g_hash_table_iter_init(&iter, priv->devices);
while (g_hash_table_iter_next(&iter, (gpointer *) &device, (gpointer *) &dev_checkpoint)) {
guint32 result = NM_ROLLBACK_RESULT_OK;
NMTernary perm_managed = NM_TERNARY_DEFAULT;
gboolean perm_managed_by_mac = FALSE;
gboolean force_perm_managed;
guint32 result = NM_ROLLBACK_RESULT_OK;
_LOGD("rollback: restoring device %s (state %d, realized %d, explicitly unmanaged %d, "
"permanently managed %d, connection-unsaved %d, connection-shadowed %d, "
"connection-shadowed-owned %d)",
"connection-unsaved %d, connection-shadowed %d, connection-shadowed-owned %d)",
dev_checkpoint->original_dev_name,
(int) dev_checkpoint->state,
dev_checkpoint->realized,
dev_checkpoint->unmanaged_explicit,
dev_checkpoint->permanent_managed,
dev_checkpoint->settings_connection_is_unsaved,
!!dev_checkpoint->settings_connection_shadowed,
dev_checkpoint->settings_connection_is_shadowed_owned);
@ -548,43 +541,6 @@ nm_checkpoint_rollback(NMCheckpoint *self)
NM_DEVICE_STATE_REASON_NOW_MANAGED);
}
force_perm_managed = !nm_config_get_device_managed(nm_config_get(),
device,
&perm_managed,
&perm_managed_by_mac,
NULL);
if (force_perm_managed || (perm_managed != dev_checkpoint->permanent_managed)
|| (dev_checkpoint->permanent_managed != NM_TERNARY_DEFAULT
&& perm_managed_by_mac != dev_checkpoint->permanent_managed_by_mac)) {
gs_free_error GError *error = NULL;
NMUnmanFlagOp set_op;
_LOGD("rollback: restore permanent managed state");
if (!nm_config_set_device_managed(nm_config_get(),
device,
dev_checkpoint->permanent_managed,
dev_checkpoint->permanent_managed_by_mac,
&error)) {
_LOGE("rollback: failed to restore permanent managed state: %s", error->message);
result = NM_ROLLBACK_RESULT_ERR_FAILED;
/* even if this failed, we try to continue the rollback */
}
if (dev_checkpoint->permanent_managed == NM_TERNARY_TRUE)
set_op = NM_UNMAN_FLAG_OP_SET_MANAGED;
else if (dev_checkpoint->permanent_managed == NM_TERNARY_FALSE)
set_op = NM_UNMAN_FLAG_OP_SET_UNMANAGED;
else
set_op = NM_UNMAN_FLAG_OP_FORGET;
nm_device_set_unmanaged_by_flags_queue(device,
NM_UNMANAGED_USER_CONF,
set_op,
NM_DEVICE_STATE_REASON_NOW_MANAGED);
}
if (dev_checkpoint->state == NM_DEVICE_STATE_UNMANAGED) {
if (nm_device_get_state(device) != NM_DEVICE_STATE_UNMANAGED
|| dev_checkpoint->unmanaged_explicit == NM_UNMAN_FLAG_OP_SET_UNMANAGED) {
@ -747,8 +703,6 @@ device_checkpoint_create(NMCheckpoint *self, NMDevice *device)
NMSettingsConnection *settings_connection;
const char *path;
NMActRequest *act_request;
gboolean perm_managed_by_mac;
gs_free_error GError *error = NULL;
nm_assert(NM_IS_DEVICE(device));
nm_assert(nm_device_is_real(device));
@ -774,26 +728,12 @@ device_checkpoint_create(NMCheckpoint *self, NMDevice *device)
} else
dev_checkpoint->unmanaged_explicit = NM_UNMAN_FLAG_OP_FORGET;
if (nm_config_get_device_managed(nm_config_get(),
device,
&dev_checkpoint->permanent_managed,
&perm_managed_by_mac,
NULL)) {
dev_checkpoint->permanent_managed_by_mac = perm_managed_by_mac;
} else {
dev_checkpoint->permanent_managed = NM_TERNARY_DEFAULT;
dev_checkpoint->permanent_managed_by_mac = FALSE;
_LOGW("error getting permanent managed state for %s: %s",
nm_device_get_iface(device),
error->message);
g_clear_error(&error);
}
act_request = nm_device_get_act_request(device);
if (act_request) {
NMSettingsStorage *storage;
gboolean shadowed_owned = FALSE;
const char *shadowed_file;
NMSettingsStorage *storage;
gboolean shadowed_owned = FALSE;
const char *shadowed_file;
gs_free_error GError *error = NULL;
settings_connection = nm_act_request_get_settings_connection(act_request);
applied_connection = nm_act_request_get_applied_connection(act_request);
@ -824,7 +764,6 @@ device_checkpoint_create(NMCheckpoint *self, NMDevice *device)
_LOGW("error reading shadowed connection file for %s: %s",
nm_device_get_iface(device),
error->message);
g_clear_error(&error);
}
}
}

View file

@ -2058,15 +2058,12 @@ _match_section_infos_construct(GKeyFile *keyfile, gboolean is_device)
{
char **groups;
gsize i, j, ngroups;
char *main_group = NULL;
char *connection_tag = NULL;
MatchSectionInfo *match_section_infos = NULL;
const char *prefix, *prefix_intern;
const char *prefix;
prefix =
is_device ? NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE : NM_CONFIG_KEYFILE_GROUPPREFIX_CONNECTION;
prefix_intern =
is_device ? NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE
: NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN NM_CONFIG_KEYFILE_GROUPPREFIX_CONNECTION;
/* get the list of existing [connection.\+]/[device.\+] sections.
*
@ -2077,36 +2074,27 @@ _match_section_infos_construct(GKeyFile *keyfile, gboolean is_device)
if (!groups)
return NULL;
for (i = 0, j = 0; i < ngroups; i++) {
if (nm_streq0(groups[i], prefix)) {
main_group = groups[i];
} else if (nm_streq0(groups[i], prefix_intern)) {
/* [.intern.connection] and [.intern.device] should not exist */
_nm_log(LOGL_WARN,
LOGD_CORE,
0,
NULL,
NULL,
"Invalid [.intern.*] section 'connection' or 'device' found");
g_free(groups[i]);
continue;
} else if (g_str_has_prefix(groups[i], prefix)) {
groups[j++] = groups[i];
} else if (g_str_has_prefix(groups[i], prefix_intern)) {
/* [.intern.connection-whatever] and [.intern.device-whatever] can exist */
groups[j++] = groups[i];
} else {
g_free(groups[i]);
}
}
ngroups = j;
if (ngroups > 0) {
gsize l = strlen(prefix);
if (ngroups == 0 && !main_group) {
for (i = 0, j = 0; i < ngroups; i++) {
if (g_str_has_prefix(groups[i], prefix)) {
if (groups[i][l] == '\0')
connection_tag = groups[i];
else
groups[j++] = groups[i];
} else
g_free(groups[i]);
}
ngroups = j;
}
if (ngroups == 0 && !connection_tag) {
g_free(groups);
return NULL;
}
match_section_infos = g_new0(MatchSectionInfo, ngroups + 1 + (main_group ? 1 : 0));
match_section_infos = g_new0(MatchSectionInfo, ngroups + 1 + (connection_tag ? 1 : 0));
match_section_infos->is_device = is_device;
for (i = 0; i < ngroups; i++) {
/* pass ownership of @group on... */
@ -2115,9 +2103,9 @@ _match_section_infos_construct(GKeyFile *keyfile, gboolean is_device)
groups[ngroups - i - 1],
is_device);
}
if (main_group) {
/* pass ownership of @main_group on... */
_match_section_info_init(&match_section_infos[i], keyfile, main_group, is_device);
if (connection_tag) {
/* pass ownership of @connection_tag on... */
_match_section_info_init(&match_section_infos[i], keyfile, connection_tag, is_device);
}
g_free(groups);

View file

@ -892,7 +892,6 @@ 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,
@ -2076,210 +2075,6 @@ nm_config_set_connectivity_check_enabled(NMConfig *self, gboolean enabled)
g_key_file_unref(keyfile);
}
/*****************************************************************************/
static gboolean
normalize_hwaddr_for_group_name(const char *hwaddr, char *out, GError **error)
{
guint8 hwaddr_bin[NM_UTILS_HWADDR_LEN_MAX];
gsize hwaddr_bin_len;
if (!_nm_utils_hwaddr_aton(hwaddr, hwaddr_bin, sizeof(hwaddr_bin), &hwaddr_bin_len)) {
g_set_error(error,
NM_DEVICE_ERROR,
NM_DEVICE_ERROR_INVALID_ARGUMENT,
"Invalid MAC address: %s",
hwaddr);
return FALSE;
}
nm_utils_bin2hexstr_full(hwaddr_bin, hwaddr_bin_len, '-', TRUE, out);
return TRUE;
}
/**
* nm_config_get_device_managed:
* @self: the NMConfig instance
* @device: the interface
* @out: (out): the managed state of the device
* @error: return location for a #GError, or %NULL
*
* Returns: TRUE if there were no errors, FALSE otherwise.
*/
gboolean
nm_config_get_device_managed(NMConfig *self,
NMDevice *device,
NMTernary *out_managed,
gboolean *out_by_mac,
GError **error)
{
NMConfigPrivate *priv;
const GKeyFile *keyfile = NULL;
gs_free char *group_by_name = NULL;
gs_free char *group_by_mac = NULL;
const char *ifname = nm_device_get_iface(device);
const char *hwaddr = nm_device_get_permanent_hw_address(device);
char mac_group_name[NM_UTILS_HWADDR_LEN_MAX * 3 + 1];
NMTernary val_by_name, val_by_mac = NM_TERNARY_DEFAULT;
g_return_val_if_fail(NM_IS_CONFIG(self), FALSE);
g_return_val_if_fail(NM_CONFIG_GET_PRIVATE(self)->config_data, FALSE);
g_return_val_if_fail(out_managed, FALSE);
g_return_val_if_fail(ifname, FALSE);
priv = NM_CONFIG_GET_PRIVATE(self);
keyfile = _nm_config_data_get_keyfile_intern(priv->config_data);
if (!keyfile) {
NM_SET_OUT(out_managed, NM_TERNARY_DEFAULT);
NM_SET_OUT(out_by_mac, FALSE);
return TRUE;
}
group_by_name =
g_strdup_printf(NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN_DEVICE "-manage-%s", ifname);
val_by_name = (NMTernary) nm_config_keyfile_get_boolean(keyfile,
group_by_name,
NM_CONFIG_KEYFILE_KEY_DEVICE_MANAGED,
NM_TERNARY_DEFAULT);
/* Devices without a kernel link (i.e. OVS ports) don't have a MAC address */
if (hwaddr) {
if (!normalize_hwaddr_for_group_name(hwaddr, mac_group_name, error))
return FALSE;
group_by_mac = g_strdup_printf(NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN_DEVICE "-manage-%s",
mac_group_name);
val_by_mac = (NMTernary) nm_config_keyfile_get_boolean(keyfile,
group_by_mac,
NM_CONFIG_KEYFILE_KEY_DEVICE_MANAGED,
NM_TERNARY_DEFAULT);
}
if (val_by_name != NM_TERNARY_DEFAULT && val_by_mac == NM_TERNARY_DEFAULT) {
NM_SET_OUT(out_managed, val_by_name);
NM_SET_OUT(out_by_mac, FALSE);
return TRUE;
} else if (val_by_mac != NM_TERNARY_DEFAULT && val_by_name == NM_TERNARY_DEFAULT) {
NM_SET_OUT(out_managed, val_by_mac);
NM_SET_OUT(out_by_mac, TRUE);
return TRUE;
} else if (val_by_name == NM_TERNARY_DEFAULT && val_by_mac == NM_TERNARY_DEFAULT) {
NM_SET_OUT(out_managed, NM_TERNARY_DEFAULT);
NM_SET_OUT(out_by_mac, FALSE);
return TRUE;
} else if (val_by_name == val_by_mac) {
NM_SET_OUT(out_managed, val_by_name);
NM_SET_OUT(out_by_mac, FALSE);
return TRUE;
}
g_set_error(error,
NM_DEVICE_ERROR,
NM_DEVICE_ERROR_FAILED,
"Multiple managed states found for device: %s",
nm_device_get_iface(device));
return FALSE;
}
/**
* nm_config_set_device_managed:
* @self: the NMConfig instance
* @device: the NMDevice instance associated with this config change
* @managed: the managed state to set
* @by_mac: if %TRUE, match by MAC address, otherwise by interface name. This is
* only used when @managed = TRUE.
* @error: return location for a #GError, or %NULL
*
* Sets the managed state of the device to the intern keyfile. Here we store the
* configuration received via the D-Bus API. Configurations from other config
* files are still in place and may have higher precedence.
*
* Prior to setting the new state, the existing configuration is removed. If
* @managed is set to %NM_TERNARY_DEFAULT, we only do the removal of the previous
* configuration.
*/
gboolean
nm_config_set_device_managed(NMConfig *self,
NMDevice *device,
NMTernary managed,
gboolean by_mac,
GError **error)
{
NMConfigPrivate *priv;
g_autoptr(GKeyFile) keyfile = NULL;
char *group;
gs_free char *group_by_name = NULL;
gs_free char *group_by_mac = NULL;
gs_free char *match_value = NULL;
gboolean changed = FALSE;
const char *ifname = nm_device_get_iface(device);
const char *hwaddr = nm_device_get_permanent_hw_address(device);
char mac_group_name[NM_UTILS_HWADDR_LEN_MAX * 3 + 1];
g_return_val_if_fail(NM_IS_CONFIG(self), FALSE);
g_return_val_if_fail(NM_CONFIG_GET_PRIVATE(self)->config_data, FALSE);
g_return_val_if_fail(ifname, FALSE);
if (by_mac && !hwaddr) {
g_set_error(error,
NM_DEVICE_ERROR,
NM_DEVICE_ERROR_INVALID_ARGUMENT,
"the device has no MAC address, but match by MAC was requested");
return FALSE;
}
if (hwaddr && !normalize_hwaddr_for_group_name(hwaddr, mac_group_name, error))
return FALSE;
priv = NM_CONFIG_GET_PRIVATE(self);
keyfile = nm_config_data_clone_keyfile_intern(priv->config_data);
/* Remove existing configs. Search them by group name [.intern.device-manage-*]. In
* the intern file, 'device-manage' sections are only used for this purpose, so we
* won't remove any other device's config. */
group_by_name =
g_strdup_printf(NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN_DEVICE "-manage-%s", ifname);
if (g_key_file_remove_group(keyfile, group_by_name, NULL))
changed = TRUE;
/* Devices without a kernel link (i.e. OVS ports) don't have a MAC address */
if (hwaddr) {
group_by_mac = g_strdup_printf(NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN_DEVICE "-manage-%s",
mac_group_name);
if (g_key_file_remove_group(keyfile, group_by_mac, NULL))
changed = TRUE;
}
/* If the new state is not explicitly TRUE of FALSE, we only remove the configs */
if (managed == NM_TERNARY_DEFAULT)
goto done;
/* Set new values */
if (by_mac) {
group = group_by_mac;
match_value = g_strdup_printf("mac:%s", hwaddr);
} else {
group = group_by_name;
match_value = g_strdup_printf("interface-name:=%s", ifname);
}
g_key_file_set_value(keyfile, group, NM_CONFIG_KEYFILE_KEY_MATCH_DEVICE, match_value);
g_key_file_set_value(keyfile, group, NM_CONFIG_KEYFILE_KEY_DEVICE_MANAGED, managed ? "1" : "0");
changed = TRUE;
done:
if (changed)
nm_config_set_values(self, keyfile, TRUE, FALSE);
return TRUE;
}
/*****************************************************************************/
/**
* nm_config_set_values:
* @self: the NMConfig instance

View file

@ -142,17 +142,6 @@ gboolean nm_config_set_global_dns(NMConfig *self, NMGlobalDnsConfig *global_dns,
void nm_config_set_connectivity_check_enabled(NMConfig *self, gboolean enabled);
gboolean nm_config_get_device_managed(NMConfig *self,
NMDevice *device,
NMTernary *out_managed,
gboolean *out_by_mac,
GError **error);
gboolean nm_config_set_device_managed(NMConfig *self,
NMDevice *device,
NMTernary managed,
gboolean by_mac,
GError **error);
/* internal defines ... */
extern guint _nm_config_match_nm_version;
extern char *_nm_config_match_env;

View file

@ -21,10 +21,6 @@
#include <linux/if_infiniband.h>
#include <net/if_arp.h>
#include <net/ethernet.h>
#include <netinet/ip_icmp.h>
#include <netinet/icmp6.h>
#include <netinet/ip6.h>
#include <linux/if_packet.h>
#include "libnm-glib-aux/nm-uuid.h"
#include "libnm-platform/nmp-base.h"
@ -5006,469 +5002,6 @@ NM_UTILS_LOOKUP_STR_DEFINE(nm_activation_type_to_string,
/*****************************************************************************/
typedef struct {
NMIPAddrTyped address;
char *addr_str;
GTask *task;
GSource *timeout_source;
GSource *retry_source;
GSource *input_source;
gulong cancellable_id;
int ifindex;
int socket;
guint16 seq;
} PingInfo;
#define _NMLOG2_PREFIX_NAME "ping"
#define _NMLOG2_DOMAIN LOGD_CORE
#define _NMLOG2(level, info, ...) \
G_STMT_START \
{ \
if (nm_logging_enabled((level), (_NMLOG2_DOMAIN))) { \
PingInfo *_info = (info); \
\
_nm_log((level), \
(_NMLOG2_DOMAIN), \
0, \
NULL, \
NULL, \
_NMLOG2_PREFIX_NAME "[" NM_HASH_OBFUSCATE_PTR_FMT \
",if=%d,%s]: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \
NM_HASH_OBFUSCATE_PTR(_info), \
_info->ifindex, \
_info->addr_str _NM_UTILS_MACRO_REST(__VA_ARGS__)); \
} \
} \
G_STMT_END
static void
ping_complete(PingInfo *info, GError *error)
{
nm_clear_g_cancellable_disconnect(g_task_get_cancellable(info->task), &info->cancellable_id);
if (error && !nm_utils_error_is_cancelled(error)) {
_LOG2T(info, "terminated with error: %s", error->message);
}
if (error)
g_task_return_error(info->task, error);
else
g_task_return_boolean(info->task, TRUE);
nm_clear_g_source_inst(&info->timeout_source);
nm_clear_g_source_inst(&info->retry_source);
nm_clear_g_source_inst(&info->input_source);
nm_clear_g_free(&info->addr_str);
nm_clear_fd(&info->socket);
g_object_unref(info->task);
g_free(info);
}
static gboolean
ping_socket_data_cb(int fd, GIOCondition condition, gpointer user_data)
{
PingInfo *info = user_data;
ssize_t len;
union {
struct icmphdr icmph;
struct icmp6_hdr icmp6h;
} pkt;
len = recv(fd, &pkt, sizeof(pkt), 0);
if (len < 0)
return G_SOURCE_CONTINUE;
if (info->address.addr_family == AF_INET) {
if (len >= sizeof(struct icmphdr) && pkt.icmph.type == ICMP_ECHOREPLY) {
_LOG2T(info, "received echo-reply with seq %hu", ntohs(pkt.icmph.un.echo.sequence));
ping_complete(info, NULL);
return G_SOURCE_CONTINUE;
}
} else {
if (len >= sizeof(struct icmp6_hdr) && pkt.icmp6h.icmp6_type == ICMP6_ECHO_REPLY) {
_LOG2T(info, "received echo-reply with seq %hu", ntohs(pkt.icmp6h.icmp6_seq));
ping_complete(info, NULL);
return G_SOURCE_CONTINUE;
}
}
return G_SOURCE_CONTINUE;
}
static void
ping_send(PingInfo *info)
{
const bool IS_IPv4 = NM_IS_IPv4(info->address.addr_family);
union {
struct sockaddr_in6 sa6;
struct sockaddr_in sa4;
} sa;
union {
struct icmphdr icmph;
struct icmp6_hdr icmp6h;
} pkt;
socklen_t sa_len;
size_t pkt_len;
nm_be32_t ifindex_be;
int errsv;
info->seq++;
if (info->socket < 0) {
info->socket = socket(info->address.addr_family,
SOCK_DGRAM | SOCK_CLOEXEC,
IS_IPv4 ? IPPROTO_ICMP : IPPROTO_ICMPV6);
if (info->socket < 0) {
errsv = errno;
_LOG2T(info, "socket creation failed: %s", nm_strerror_native(errsv));
/* Try again at the next iteration */
return;
}
memset(&sa, 0, sizeof(sa));
if (IS_IPv4) {
sa.sa4.sin_family = AF_INET;
sa.sa4.sin_addr.s_addr = info->address.addr.addr4;
sa_len = sizeof(struct sockaddr_in);
} else {
sa.sa6.sin6_family = AF_INET6;
sa.sa6.sin6_addr = info->address.addr.addr6;
if (IN6_IS_ADDR_LINKLOCAL(&info->address.addr.addr6))
sa.sa6.sin6_scope_id = info->ifindex;
sa_len = sizeof(struct sockaddr_in6);
}
/* setsockopt(IP*_UNICAST_IF) must be called *before* connecting
* the socket, otherwise it doesn't have any effect */
ifindex_be = htonl(info->ifindex);
if (setsockopt(info->socket,
IS_IPv4 ? IPPROTO_IP : IPPROTO_IPV6,
IS_IPv4 ? IP_UNICAST_IF : IPV6_UNICAST_IF,
&ifindex_be,
sizeof(ifindex_be))) {
errsv = errno;
_LOG2T(info,
"failed to bind the socket to the interface: %s",
nm_strerror_native(errsv));
/* Try again at the next iteration */
nm_clear_fd(&info->socket);
return;
}
/* Connect the socket so that the kernel only delivers us packets
* coming from the given remote address */
if (connect(info->socket, (struct sockaddr *) &sa, sa_len) < 0) {
errsv = errno;
_LOG2T(info, "failed to connect the socket: %s", nm_strerror_native(errsv));
/* try again at the next iteration */
nm_clear_fd(&info->socket);
return;
}
info->input_source = nm_g_unix_fd_source_new(info->socket,
G_IO_IN,
G_PRIORITY_DEFAULT,
ping_socket_data_cb,
info,
NULL);
g_source_attach(info->input_source, g_task_get_context(info->task));
}
if (IS_IPv4) {
memset(&pkt.icmph, 0, sizeof(struct icmphdr));
pkt.icmph.type = ICMP_ECHO;
pkt.icmph.un.echo.sequence = htons(info->seq);
pkt_len = sizeof(struct icmphdr);
} else {
memset(&pkt.icmp6h, 0, sizeof(struct icmp6_hdr));
pkt.icmp6h.icmp6_type = ICMP6_ECHO_REQUEST;
pkt.icmp6h.icmp6_seq = htons(info->seq);
pkt_len = sizeof(struct icmp6_hdr);
}
/* The kernel will automatically set the ID ICMP field and filter
* incoming packets by the same ID */
if (send(info->socket, &pkt, pkt_len, 0) < 0) {
errsv = errno;
_LOG2T(info, "error sending echo-request #%u: %s", info->seq, nm_strerror_native(errsv));
return;
}
_LOG2T(info, "sent echo-request #%u", info->seq);
}
static gboolean
ping_timeout_cb(gpointer user_data)
{
PingInfo *info = user_data;
_LOG2T(info, "timeout");
nm_clear_g_source_inst(&info->timeout_source);
ping_complete(info, g_error_new_literal(NM_UTILS_ERROR, NM_UTILS_ERROR_UNKNOWN, "timeout"));
return G_SOURCE_CONTINUE;
}
static gboolean
ping_retry_cb(gpointer user_data)
{
PingInfo *info = user_data;
ping_send(info);
return G_SOURCE_CONTINUE;
}
static void
ping_cancelled(GObject *object, gpointer user_data)
{
PingInfo *info = user_data;
GError *error = NULL;
nm_clear_g_signal_handler(g_task_get_cancellable(info->task), &info->cancellable_id);
nm_utils_error_set_cancelled(&error, FALSE, NULL);
ping_complete(info, error);
}
void
nm_utils_ping_host(NMIPAddrTyped address,
int ifindex,
guint timeout_sec,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer cb_data)
{
PingInfo *info;
char buf[NM_INET_ADDRSTRLEN];
gulong signal_id;
nm_assert(ifindex > 0);
nm_assert(G_IS_CANCELLABLE(cancellable));
nm_assert(callback);
nm_assert(cb_data);
info = g_new0(PingInfo, 1);
info->address = address;
info->ifindex = ifindex;
info->task = nm_g_task_new(NULL, cancellable, nm_utils_ping_host, callback, cb_data);
info->socket = -1;
nm_inet_ntop(address.addr_family, address.addr.addr_ptr, buf);
info->addr_str = g_strdup(buf);
_LOG2T(info, "started");
if (timeout_sec > 0) {
info->timeout_source = nm_g_timeout_source_new_seconds(timeout_sec,
G_PRIORITY_DEFAULT,
ping_timeout_cb,
info,
NULL);
g_source_attach(info->timeout_source, g_task_get_context(info->task));
}
info->retry_source =
nm_g_timeout_source_new_seconds(1, G_PRIORITY_DEFAULT, ping_retry_cb, info, NULL);
g_source_attach(info->retry_source, g_task_get_context(info->task));
signal_id = g_cancellable_connect(cancellable, G_CALLBACK(ping_cancelled), info, NULL);
if (signal_id == 0) {
/* the callback was invoked synchronously, which destroyed @info.
* We must not touch it anymore. */
return;
}
info->cancellable_id = signal_id;
ping_send(info);
}
gboolean
nm_utils_ping_host_finish(GAsyncResult *result, GError **error)
{
GTask *task = G_TASK(result);
nm_assert(nm_g_task_is_valid(result, NULL, nm_utils_ping_host));
return g_task_propagate_boolean(task, error);
}
/*****************************************************************************/
/*
* nm_utils_icmp6_checksum:
* @ip6_src: pointer to the IPv6 source address
* @data_len: length of the data
* @data: the data on which to compute the checksum
*
* Computes the ICMP6 checksum over @data (with length @data_len) and the IPv6
* pseudo-header. @ip6_src points to the source address in the IPv6 header.
*/
uint16_t
nm_utils_icmp6_checksum(const void *ip6_src, size_t data_len, const void *data)
{
uint32_t sum = 0;
const uint16_t *ptr;
const uint8_t *ptr8;
size_t i;
/* Pseudo-header: source address */
ptr = (const uint16_t *) ip6_src;
for (i = 0; i < 8; i++)
sum += *ptr++;
/* Pseudo-header: destination address */
for (i = 0; i < 8; i++)
sum += *ptr++;
/* Pseudo-header: payload length */
sum += htons(data_len);
/* Pseudo-header: next header */
sum += htons(IPPROTO_ICMPV6);
/* ICMPv6 data */
ptr = (const uint16_t *) data;
for (i = 0; i < data_len / 2; i++)
sum += ptr[i];
/* Handle odd byte */
if (data_len % 2) {
ptr8 = &((const uint8_t *) data)[data_len - 1];
sum += htons((guint16) (*ptr8) << 8);
}
/* Fold 32-bit sum to 16 bits */
while (sum >> 16)
sum = (sum & 0xffff) + (sum >> 16);
return (uint16_t) ~sum;
}
/*
* nm_utils_ipv6_dad_send:
* @addr: the target IPv6 address
* @ifindex: the interface index
* @arptype: the ARP hardware type of the interface (e.g. ARPHRD_ETHER, ARPHRD_NONE)
*
* Send an IPv6 Duplicate Address Detection (DAD) Neighbor Solicitation
* for the given address.
*
* Returns: %TRUE if the packet was sent successfully, %FALSE on error
*/
gboolean
nm_utils_ipv6_dad_send(const struct in6_addr *addr, int ifindex, int arptype)
{
/* DAD packet: IPv6 header + ICMPv6 NS + nonce option (RFC 3971) */
struct _nm_packed {
struct ip6_hdr ip6h;
struct nd_neighbor_solicit ns;
guint8 ns_opt_nr;
guint8 ns_opt_len;
guint8 ns_opt_nonce[6];
} dad_pkt;
nm_auto_close int fd = -1;
int errsv;
char sbuf[NM_INET_ADDRSTRLEN];
nm_assert(addr);
nm_assert(ifindex > 0);
/* IPv6 header */
dad_pkt.ip6h = (struct ip6_hdr) {
.ip6_flow = htonl(6 << 28), /* version 6, tclass 0, flowlabel 0 */
.ip6_plen = htons(sizeof(dad_pkt) - sizeof(struct ip6_hdr)),
.ip6_nxt = IPPROTO_ICMPV6,
.ip6_hlim = 255,
.ip6_src = IN6ADDR_ANY_INIT,
.ip6_dst.s6_addr = {0xff,
0x02,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0x01,
0xff,
addr->s6_addr[13],
addr->s6_addr[14],
addr->s6_addr[15]},
};
/* ICMPv6 Neighbor Solicitation */
dad_pkt.ns = (struct nd_neighbor_solicit) {
.nd_ns_type = ND_NEIGHBOR_SOLICIT,
.nd_ns_target = *addr,
};
/* Nonce option (RFC 3971) */
dad_pkt.ns_opt_nr = 14;
dad_pkt.ns_opt_len = 1; /* in units of 8 bytes */
nm_random_get_bytes(dad_pkt.ns_opt_nonce, sizeof(dad_pkt.ns_opt_nonce));
/* Compute the ICMPv6 checksum */
dad_pkt.ns.nd_ns_cksum = nm_utils_icmp6_checksum(&dad_pkt.ip6h.ip6_src,
sizeof(dad_pkt) - sizeof(struct ip6_hdr),
&dad_pkt.ns);
/* We need a ETH_P_IPV6 socket because we need to use a zero IPv6 source address */
fd = socket(AF_PACKET, SOCK_DGRAM | SOCK_CLOEXEC, htons(ETH_P_IPV6));
if (fd < 0) {
errsv = errno;
nm_log_warn(LOGD_CORE,
"ipv6-dad: failed to create socket for %s: %s",
nm_inet6_ntop(addr, sbuf),
nm_strerror_native(errsv));
return FALSE;
}
/* Build link-layer destination address. For Ethernet, use the solicited-node
* multicast MAC address. For L3-only devices (ARPHRD_NONE, ARPHRD_RAWIP, etc.)
* there is no L2 header, so set sll_halen to 0. */
{
struct sockaddr_ll dst_ll = {
.sll_family = AF_PACKET,
.sll_protocol = htons(ETH_P_IPV6),
.sll_ifindex = ifindex,
};
if (arptype == ARPHRD_ETHER) {
dst_ll.sll_halen = ETH_ALEN;
dst_ll.sll_addr[0] = 0x33;
dst_ll.sll_addr[1] = 0x33;
dst_ll.sll_addr[2] = 0xff;
dst_ll.sll_addr[3] = addr->s6_addr[13];
dst_ll.sll_addr[4] = addr->s6_addr[14];
dst_ll.sll_addr[5] = addr->s6_addr[15];
}
if (sendto(fd, &dad_pkt, sizeof(dad_pkt), 0, (struct sockaddr *) &dst_ll, sizeof(dst_ll))
< 0) {
errsv = errno;
nm_log_warn(LOGD_CORE,
"ipv6-dad: failed to send DAD NS for %s: %s",
nm_inet6_ntop(addr, sbuf),
nm_strerror_native(errsv));
return FALSE;
}
}
nm_log_dbg(LOGD_CORE,
"ipv6-dad: sent DAD NS for %s on ifindex %d",
nm_inet6_ntop(addr, sbuf),
ifindex);
return TRUE;
}
/*****************************************************************************/
typedef struct {
GPid pid;
GTask *task;
@ -5490,9 +5023,6 @@ typedef struct {
gsize out_buffer_offset;
} HelperInfo;
#undef _NMLOG2_PREFIX_NAME
#undef _NMLOG2_DOMAIN
#undef _NMLOG2
#define _NMLOG2_PREFIX_NAME "nm-daemon-helper"
#define _NMLOG2_DOMAIN LOGD_CORE
#define _NMLOG2(level, info, ...) \

View file

@ -304,7 +304,6 @@ typedef enum {
NM_UTILS_STABLE_TYPE_STABLE_ID = 1,
NM_UTILS_STABLE_TYPE_GENERATED = 2,
NM_UTILS_STABLE_TYPE_RANDOM = 3,
NM_UTILS_STABLE_TYPE_CLAT = 4,
} NMUtilsStableType;
#define NM_UTILS_STABLE_TYPE_NONE ((NMUtilsStableType) - 1)
@ -521,19 +520,4 @@ void nm_utils_read_private_files(const char *const *paths,
gpointer cb_data);
GHashTable *nm_utils_read_private_files_finish(GAsyncResult *result, GError **error);
/*****************************************************************************/
void nm_utils_ping_host(NMIPAddrTyped address,
int ifindex,
guint timeout_sec,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer cb_data);
gboolean nm_utils_ping_host_finish(GAsyncResult *result, GError **error);
uint16_t nm_utils_icmp6_checksum(const void *ip6_src, size_t data_len, const void *data);
gboolean nm_utils_ipv6_dad_send(const struct in6_addr *addr, int ifindex, int arptype);
#endif /* __NM_CORE_UTILS_H__ */

View file

@ -26,7 +26,6 @@ GType nm_ip6_config_get_type(void);
/*****************************************************************************/
#define NM_IP_CONFIG_ADDRESS_DATA "address-data"
#define NM_IP_CONFIG_CLAT_ADDRESS "clat-address"
#define NM_IP_CONFIG_DNS_OPTIONS "dns-options"
#define NM_IP_CONFIG_DNS_PRIORITY "dns-priority"
#define NM_IP_CONFIG_DOMAINS "domains"
@ -42,7 +41,6 @@ NM_GOBJECT_PROPERTIES_DEFINE_FULL(_ip,
NMIPConfig,
PROP_IP_L3CFG,
PROP_IP_ADDRESS_DATA,
PROP_IP_CLAT_ADDRESS,
PROP_IP_GATEWAY,
PROP_IP_ROUTE_DATA,
PROP_IP_DOMAINS,
@ -56,7 +54,7 @@ G_DEFINE_ABSTRACT_TYPE(NMIPConfig, nm_ip_config, NM_TYPE_DBUS_OBJECT)
/*****************************************************************************/
static void _handle_platform_change(NMIPConfig *self, guint64 obj_type_flags, gboolean is_init);
static void _handle_platform_change(NMIPConfig *self, guint32 obj_type_flags, gboolean is_init);
static void _handle_l3cd_changed(NMIPConfig *self, const NML3ConfigData *l3cd);
/*****************************************************************************/
@ -77,7 +75,7 @@ static void
_notify_platform_handle(NMIPConfig *self, gint64 now_msec)
{
NMIPConfigPrivate *priv = NM_IP_CONFIG_GET_PRIVATE(self);
guint64 obj_type_flags;
guint32 obj_type_flags;
nm_clear_g_source_inst(&priv->notify_platform_timeout_source);
@ -98,7 +96,7 @@ _notify_platform_cb(gpointer user_data)
}
static void
_notify_platform(NMIPConfig *self, guint64 obj_type_flags)
_notify_platform(NMIPConfig *self, guint32 obj_type_flags)
{
const int addr_family = nm_ip_config_get_addr_family(self);
const int IS_IPv4 = NM_IS_IPv4(addr_family);
@ -166,8 +164,6 @@ get_property_ip(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec
const int addr_family = nm_ip_config_get_addr_family(self);
char **to_free = NULL;
char sbuf_addr[NM_INET_ADDRSTRLEN];
in_addr_t addr4;
struct in6_addr addr6;
const char *const *strv;
guint len;
int v_i;
@ -222,20 +218,6 @@ get_property_ip(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec
strv = nm_l3_config_data_get_dns_options(priv->l3cd, addr_family, &len);
_value_set_variant_as(value, strv, len);
break;
case PROP_IP_CLAT_ADDRESS:
if (nm_l3_config_data_get_clat_state(priv->l3cd, &addr6, NULL, NULL, &addr4)) {
if (addr_family == AF_INET) {
g_value_set_variant(value,
g_variant_new_string(nm_inet_ntop(AF_INET, &addr4, sbuf_addr)));
} else {
g_value_set_variant(
value,
g_variant_new_string(nm_inet_ntop(AF_INET6, &addr6, sbuf_addr)));
}
} else {
g_value_set_variant(value, nm_g_variant_singleton_s_empty());
}
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
break;
@ -354,13 +336,6 @@ nm_ip_config_class_init(NMIPConfigClass *klass)
G_VARIANT_TYPE("aa{sv}"),
NULL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
obj_properties_ip[PROP_IP_CLAT_ADDRESS] =
g_param_spec_variant(NM_IP_CONFIG_CLAT_ADDRESS,
"",
"",
G_VARIANT_TYPE("s"),
NULL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
obj_properties_ip[PROP_IP_GATEWAY] =
g_param_spec_variant(NM_IP_CONFIG_GATEWAY,
"",
@ -537,9 +512,6 @@ static const NMDBusInterfaceInfoExtended interface_info_ip4_config = {
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("AddressData",
"aa{sv}",
NM_IP_CONFIG_ADDRESS_DATA),
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("ClatAddress",
"s",
NM_IP_CONFIG_CLAT_ADDRESS),
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Gateway", "s", NM_IP_CONFIG_GATEWAY),
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE(
"Routes",
@ -642,7 +614,6 @@ nm_ip4_config_class_init(NMIP4ConfigClass *klass)
/*****************************************************************************/
/* public */
#define NM_IP6_CONFIG_CLAT_PREF64 "clat-pref64"
#define NM_IP6_CONFIG_NAMESERVERS "nameservers"
/* deprecated */
@ -654,7 +625,6 @@ typedef struct _NMIP6ConfigClass NMIP6ConfigClass;
NM_GOBJECT_PROPERTIES_DEFINE_FULL(_ip6,
NMIP6Config,
PROP_IP6_CLAT_PREF64,
PROP_IP6_NAMESERVERS,
PROP_IP6_ADDRESSES,
PROP_IP6_ROUTES, );
@ -681,12 +651,6 @@ static const NMDBusInterfaceInfoExtended interface_info_ip6_config = {
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("AddressData",
"aa{sv}",
NM_IP_CONFIG_ADDRESS_DATA),
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("ClatAddress",
"s",
NM_IP_CONFIG_CLAT_ADDRESS),
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("ClatPref64",
"s",
NM_IP6_CONFIG_CLAT_PREF64),
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE("Gateway", "s", NM_IP_CONFIG_GATEWAY),
NM_DEFINE_DBUS_PROPERTY_INFO_EXTENDED_READABLE(
"Routes",
@ -718,24 +682,11 @@ get_property_ip6(GObject *object, guint prop_id, GValue *value, GParamSpec *pspe
guint len;
guint i;
const char *const *strarr;
guint8 plen;
struct in6_addr addr6;
char sbuf[NM_UTILS_INET_ADDRSTRLEN];
switch (prop_id) {
case PROP_IP6_ADDRESSES:
g_value_set_variant(value, priv->v_addresses);
break;
case PROP_IP6_CLAT_PREF64:
if (nm_l3_config_data_get_clat_state(priv->l3cd, NULL, &addr6, &plen, NULL)) {
nm_inet6_ntop(&addr6, sbuf);
g_value_set_variant(value,
g_variant_new_string(
nm_sprintf_bufa(NM_INET_ADDRSTRLEN + 32, "%s/%u", sbuf, plen)));
} else {
g_value_set_variant(value, nm_g_variant_singleton_s_empty());
}
break;
case PROP_IP6_ROUTES:
g_value_set_variant(value, priv->v_routes);
break;
@ -789,13 +740,6 @@ nm_ip6_config_class_init(NMIP6ConfigClass *klass)
G_VARIANT_TYPE("a(ayuay)"),
NULL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
obj_properties_ip6[PROP_IP6_CLAT_PREF64] =
g_param_spec_variant(NM_IP6_CONFIG_CLAT_PREF64,
"",
"",
G_VARIANT_TYPE("s"),
NULL,
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
obj_properties_ip6[PROP_IP6_ROUTES] =
g_param_spec_variant(NM_IP6_CONFIG_ROUTES,
"",
@ -843,7 +787,7 @@ _handle_l3cd_changed(NMIPConfig *self, const NML3ConfigData *l3cd)
const int IS_IPv4 = NM_IS_IPv4(addr_family);
NMIPConfigPrivate *priv = NM_IP_CONFIG_GET_PRIVATE(self);
nm_auto_unref_l3cd const NML3ConfigData *l3cd_old = NULL;
GParamSpec *changed_params[10];
GParamSpec *changed_params[8];
guint n_changed_params = 0;
const char *const *strarr;
const char *const *strarr_old;
@ -896,64 +840,11 @@ _handle_l3cd_changed(NMIPConfig *self, const NML3ConfigData *l3cd)
}
}
/* CLAT state */
{
struct in6_addr clat_ip6;
struct in6_addr clat_pref64;
guint8 clat_pref64_plen;
in_addr_t clat_ip4;
gboolean clat_enabled;
struct in6_addr clat_ip6_old;
struct in6_addr clat_pref64_old;
guint8 clat_pref64_plen_old;
in_addr_t clat_ip4_old;
gboolean clat_enabled_old;
gboolean changed;
clat_enabled_old = nm_l3_config_data_get_clat_state(l3cd_old,
&clat_ip6_old,
&clat_pref64_old,
&clat_pref64_plen_old,
&clat_ip4_old);
clat_enabled = nm_l3_config_data_get_clat_state(priv->l3cd,
&clat_ip6,
&clat_pref64,
&clat_pref64_plen,
&clat_ip4);
/* CLAT address */
if (clat_enabled != clat_enabled_old) {
changed = TRUE;
} else if (!clat_enabled) {
changed = FALSE;
} else if (IS_IPv4) {
changed = (clat_ip4 != clat_ip4_old);
} else {
changed = !IN6_ARE_ADDR_EQUAL(&clat_ip6, &clat_ip6_old);
}
if (changed)
changed_params[n_changed_params++] = obj_properties_ip[PROP_IP_CLAT_ADDRESS];
/* PREF64 */
if (!IS_IPv4) {
if (clat_enabled != clat_enabled_old) {
changed = TRUE;
} else if (!clat_enabled) {
changed = FALSE;
} else {
changed = (clat_pref64_plen != clat_pref64_plen_old)
|| (!IN6_ARE_ADDR_EQUAL(&clat_pref64, &clat_pref64_old));
}
if (changed)
changed_params[n_changed_params++] = obj_properties_ip6[PROP_IP6_CLAT_PREF64];
}
}
_notify_all(self, changed_params, n_changed_params);
}
static void
_handle_platform_change(NMIPConfig *self, guint64 obj_type_flags, gboolean is_init)
_handle_platform_change(NMIPConfig *self, guint32 obj_type_flags, gboolean is_init)
{
const int addr_family = nm_ip_config_get_addr_family(self);
const int IS_IPv4 = NM_IS_IPv4(addr_family);

View file

@ -35,7 +35,7 @@ struct _NMIPConfigPrivate {
GSource *notify_platform_timeout_source;
gint64 notify_platform_rlimited_until_msec;
gulong l3cfg_notify_id;
guint64 notify_platform_obj_type_flags;
guint32 notify_platform_obj_type_flags;
};
struct _NMIPConfig {

View file

@ -50,9 +50,6 @@ struct _NML3ConfigData {
const NMPObject *best_default_route_x[2];
};
struct in6_addr pref64_prefix;
guint32 pref64_plen;
GArray *wins;
GArray *nis_servers;
@ -125,19 +122,6 @@ struct _NML3ConfigData {
NMSettingConnectionDnsOverTls dns_over_tls;
NMSettingConnectionDnssec dnssec;
NMUtilsIPv6IfaceId ip6_token;
NMRefString *network_id;
NMSettingIp4ConfigClat clat_config; /* this indicates the 'administrative' CLAT
* state, i.e. whether CLAT will be started
* once we receive a PREF64 */
/* The runtime CLAT state */
struct {
struct in6_addr ip6;
struct in6_addr pref64;
in_addr_t ip4;
guint8 pref64_plen;
bool enabled;
} clat_state;
NML3ConfigDatFlags flags;
@ -146,8 +130,7 @@ struct _NML3ConfigData {
int ndisc_hop_limit_val;
guint32 mtu;
guint32 ip6_mtu_static; /* IPv6 MTU from the connection profile */
guint32 ip6_mtu_ra; /* IPv6 MTU from Router Advertisement */
guint32 ip6_mtu;
guint32 ndisc_reachable_time_msec_val;
guint32 ndisc_retrans_timer_msec_val;
@ -184,8 +167,6 @@ struct _NML3ConfigData {
bool routed_dns_4 : 1;
bool routed_dns_6 : 1;
bool pref64_valid : 1;
};
/*****************************************************************************/
@ -409,11 +390,8 @@ nm_l3_config_data_log(const NML3ConfigData *self,
: "",
!self->is_sealed ? ", not-sealed" : "");
if (self->mtu != 0 || self->ip6_mtu_static != 0 || self->ip6_mtu_ra != 0) {
_L("mtu: %u, ip6-mtu-static: %u, ip6-mtu-ra %u",
self->mtu,
self->ip6_mtu_static,
self->ip6_mtu_ra);
if (self->mtu != 0 || self->ip6_mtu != 0) {
_L("mtu: %u, ip6-mtu: %u", self->mtu, self->ip6_mtu);
}
for (IS_IPv4 = 1; IS_IPv4 >= 0; IS_IPv4--) {
@ -541,27 +519,6 @@ nm_l3_config_data_log(const NML3ConfigData *self,
_L("nis-domain: %s", self->nis_domain->str);
}
if (!IS_IPv4) {
if (self->clat_config == NM_SETTING_IP4_CONFIG_CLAT_AUTO)
_L("clat-config: auto");
else if (self->clat_config == NM_SETTING_IP4_CONFIG_CLAT_FORCE)
_L("clat-config: force");
if (self->clat_state.enabled) {
_L("clat-state: ip4=%s/32, pref64=%s/%u, ip6=%s/64",
nm_inet4_ntop(self->clat_state.ip4, sbuf + NM_INET_ADDRSTRLEN),
nm_inet6_ntop(&self->clat_state.pref64, sbuf),
self->clat_state.pref64_plen,
nm_inet6_ntop(&self->clat_state.ip6, sbuf_addr));
}
}
if (!IS_IPv4 && self->pref64_valid) {
_L("pref64_prefix: %s/%d",
nm_utils_inet6_ntop(&self->pref64_prefix, sbuf_addr),
self->pref64_plen);
}
if (self->dhcp_lease_x[IS_IPv4]) {
gs_free NMUtilsNamedValue *options_free = NULL;
NMUtilsNamedValue options_buffer[30];
@ -646,10 +603,6 @@ nm_l3_config_data_log(const NML3ConfigData *self,
nm_utils_inet6_interface_identifier_to_token(&self->ip6_token, sbuf_addr));
}
if (self->network_id) {
_L("network-id: %s", self->network_id->str);
}
if (self->metered != NM_TERNARY_DEFAULT)
_L("metered: %s", self->metered ? "yes" : "no");
@ -756,7 +709,6 @@ nm_l3_config_data_new(NMDedupMultiIndex *multi_idx, int ifindex, NMIPConfigSourc
.flags = NM_L3_CONFIG_DAT_FLAGS_NONE,
.metered = NM_TERNARY_DEFAULT,
.proxy_browser_only = NM_TERNARY_DEFAULT,
.clat_config = NM_SETTING_IP4_CONFIG_CLAT_NO,
.proxy_method = NM_PROXY_CONFIG_METHOD_UNKNOWN,
.route_table_sync_4 = NM_IP_ROUTE_TABLE_SYNC_MODE_NONE,
.route_table_sync_6 = NM_IP_ROUTE_TABLE_SYNC_MODE_NONE,
@ -770,7 +722,6 @@ nm_l3_config_data_new(NMDedupMultiIndex *multi_idx, int ifindex, NMIPConfigSourc
.ndisc_retrans_timer_msec_set = FALSE,
.allow_routes_without_address_4 = TRUE,
.allow_routes_without_address_6 = TRUE,
.pref64_valid = FALSE,
};
_idx_type_init(&self->idx_addresses_4, NMP_OBJECT_TYPE_IP4_ADDRESS);
@ -871,7 +822,6 @@ nm_l3_config_data_unref(const NML3ConfigData *self)
nm_ref_string_unref(mutable->nis_domain);
nm_ref_string_unref(mutable->proxy_pac_url);
nm_ref_string_unref(mutable->proxy_pac_script);
nm_ref_string_unref(mutable->network_id);
nm_g_slice_free(mutable);
}
@ -1940,42 +1890,22 @@ nm_l3_config_data_set_mtu(NML3ConfigData *self, guint32 mtu)
}
guint32
nm_l3_config_data_get_ip6_mtu_static(const NML3ConfigData *self)
nm_l3_config_data_get_ip6_mtu(const NML3ConfigData *self)
{
nm_assert(_NM_IS_L3_CONFIG_DATA(self, TRUE));
return self->ip6_mtu_static;
return self->ip6_mtu;
}
gboolean
nm_l3_config_data_set_ip6_mtu_static(NML3ConfigData *self, guint32 ip6_mtu)
nm_l3_config_data_set_ip6_mtu(NML3ConfigData *self, guint32 ip6_mtu)
{
nm_assert(_NM_IS_L3_CONFIG_DATA(self, FALSE));
if (self->ip6_mtu_static == ip6_mtu)
if (self->ip6_mtu == ip6_mtu)
return FALSE;
self->ip6_mtu_static = ip6_mtu;
return TRUE;
}
guint32
nm_l3_config_data_get_ip6_mtu_ra(const NML3ConfigData *self)
{
nm_assert(_NM_IS_L3_CONFIG_DATA(self, TRUE));
return self->ip6_mtu_ra;
}
gboolean
nm_l3_config_data_set_ip6_mtu_ra(NML3ConfigData *self, guint32 ip6_mtu)
{
nm_assert(_NM_IS_L3_CONFIG_DATA(self, FALSE));
if (self->ip6_mtu_ra == ip6_mtu)
return FALSE;
self->ip6_mtu_ra = ip6_mtu;
self->ip6_mtu = ip6_mtu;
return TRUE;
}
@ -2027,132 +1957,6 @@ nm_l3_config_data_set_ip6_token(NML3ConfigData *self, NMUtilsIPv6IfaceId ipv6_to
return TRUE;
}
const char *
nm_l3_config_data_get_network_id(const NML3ConfigData *self)
{
nm_assert(_NM_IS_L3_CONFIG_DATA(self, TRUE));
return nm_ref_string_get_str(self->network_id);
}
gboolean
nm_l3_config_data_set_network_id(NML3ConfigData *self, const char *value)
{
nm_assert(_NM_IS_L3_CONFIG_DATA(self, FALSE));
return nm_ref_string_reset_str(&self->network_id, value);
}
gboolean
nm_l3_config_data_set_clat_config(NML3ConfigData *self, NMSettingIp4ConfigClat val)
{
nm_assert(_NM_IS_L3_CONFIG_DATA(self, FALSE));
nm_assert(NM_IN_SET(val,
NM_SETTING_IP4_CONFIG_CLAT_NO,
NM_SETTING_IP4_CONFIG_CLAT_FORCE,
NM_SETTING_IP4_CONFIG_CLAT_AUTO));
if (self->clat_config == val)
return FALSE;
self->clat_config = val;
return TRUE;
}
NMSettingIp4ConfigClat
nm_l3_config_data_get_clat_config(const NML3ConfigData *self)
{
nm_assert(_NM_IS_L3_CONFIG_DATA(self, TRUE));
return self->clat_config;
}
gboolean
nm_l3_config_data_get_clat_state(const NML3ConfigData *self,
struct in6_addr *out_ip6,
struct in6_addr *out_pref64,
guint8 *out_pref64_plen,
in_addr_t *out_ip4)
{
if (!self || !self->clat_state.enabled)
return FALSE;
NM_SET_OUT(out_ip6, self->clat_state.ip6);
NM_SET_OUT(out_pref64, self->clat_state.pref64);
NM_SET_OUT(out_pref64_plen, self->clat_state.pref64_plen);
NM_SET_OUT(out_ip4, self->clat_state.ip4);
return TRUE;
}
void
nm_l3_config_data_set_clat_state(NML3ConfigData *self,
gboolean enabled,
const struct in6_addr *ip6,
const struct in6_addr *pref64,
guint8 pref64_plen,
in_addr_t ip4)
{
nm_assert(_NM_IS_L3_CONFIG_DATA(self, FALSE));
self->clat_state.enabled = enabled;
if (enabled) {
self->clat_state.ip6 = *ip6;
self->clat_state.pref64 = *pref64;
self->clat_state.pref64_plen = pref64_plen;
self->clat_state.ip4 = ip4;
} else {
self->clat_state.ip6 = in6addr_any;
self->clat_state.pref64 = in6addr_any;
self->clat_state.pref64_plen = 0;
self->clat_state.ip4 = 0;
}
}
gboolean
nm_l3_config_data_set_pref64_valid(NML3ConfigData *self, gboolean val)
{
if (self->pref64_valid == val)
return FALSE;
self->pref64_valid = val;
return TRUE;
}
gboolean
nm_l3_config_data_get_pref64_valid(const NML3ConfigData *self)
{
nm_assert(_NM_IS_L3_CONFIG_DATA(self, TRUE));
return self->pref64_valid;
}
gboolean
nm_l3_config_data_get_pref64(const NML3ConfigData *self,
struct in6_addr *out_prefix,
guint32 *out_plen)
{
nm_assert(_NM_IS_L3_CONFIG_DATA(self, TRUE));
if (!self->pref64_valid)
return FALSE;
NM_SET_OUT(out_prefix, self->pref64_prefix);
NM_SET_OUT(out_plen, self->pref64_plen);
return TRUE;
}
gboolean
nm_l3_config_data_set_pref64(NML3ConfigData *self, struct in6_addr prefix, guint32 plen)
{
if (self->pref64_valid) {
if (self->pref64_plen == plen
&& nm_ip6_addr_same_prefix(&self->pref64_prefix, &prefix, plen)) {
return FALSE;
}
} else {
self->pref64_valid = TRUE;
}
self->pref64_prefix = prefix;
self->pref64_plen = plen;
return TRUE;
}
NMMptcpFlags
nm_l3_config_data_get_mptcp_flags(const NML3ConfigData *self)
{
@ -2680,10 +2484,8 @@ nm_l3_config_data_cmp_full(const NML3ConfigData *a,
if (NM_FLAGS_HAS(flags, NM_L3_CONFIG_CMP_FLAGS_OTHER)) {
NM_CMP_DIRECT(a->flags, b->flags);
NM_CMP_DIRECT(a->ip6_token.id, b->ip6_token.id);
NM_CMP_DIRECT_REF_STRING(a->network_id, b->network_id);
NM_CMP_DIRECT(a->mtu, b->mtu);
NM_CMP_DIRECT(a->ip6_mtu_static, b->ip6_mtu_static);
NM_CMP_DIRECT(a->ip6_mtu_ra, b->ip6_mtu_ra);
NM_CMP_DIRECT(a->ip6_mtu, b->ip6_mtu);
NM_CMP_DIRECT_UNSAFE(a->metered, b->metered);
NM_CMP_DIRECT_UNSAFE(a->proxy_browser_only, b->proxy_browser_only);
NM_CMP_DIRECT_UNSAFE(a->proxy_method, b->proxy_method);
@ -2707,23 +2509,6 @@ nm_l3_config_data_cmp_full(const NML3ConfigData *a,
NM_CMP_DIRECT_UNSAFE(a->routed_dns_4, b->routed_dns_4);
NM_CMP_DIRECT_UNSAFE(a->routed_dns_6, b->routed_dns_6);
NM_CMP_DIRECT_UNSAFE(a->clat_config, b->clat_config);
NM_CMP_DIRECT(!!a->clat_state.enabled, !!b->clat_state.enabled);
if (a->clat_state.enabled) {
NM_CMP_DIRECT_IN6ADDR(&a->clat_state.ip6, &b->clat_state.ip6);
NM_CMP_DIRECT_IN6ADDR(&a->clat_state.pref64, &b->clat_state.pref64);
NM_CMP_DIRECT(a->clat_state.pref64_plen, b->clat_state.pref64_plen);
NM_CMP_DIRECT(a->clat_state.ip4, b->clat_state.ip4);
}
NM_CMP_DIRECT(!!a->pref64_valid, !!b->pref64_valid);
if (a->pref64_valid) {
NM_CMP_DIRECT(a->pref64_plen, b->pref64_plen);
NM_CMP_RETURN_DIRECT(
nm_ip6_addr_same_prefix_cmp(&a->pref64_prefix, &b->pref64_prefix, a->pref64_plen));
}
NM_CMP_FIELD(a, b, source);
}
@ -2739,10 +2524,8 @@ nm_l3_config_data_cmp_full(const NML3ConfigData *a,
/*****************************************************************************/
const NMPObject *
nm_l3_config_data_get_direct_route_for_host(const NML3ConfigData *self,
int addr_family,
gconstpointer host)
static const NMPObject *
_data_get_direct_route_for_host(const NML3ConfigData *self, int addr_family, gconstpointer host)
{
const int IS_IPv4 = NM_IS_IPv4(addr_family);
const NMPObject *best_route_obj = NULL;
@ -2900,7 +2683,7 @@ nm_l3_config_data_add_dependent_onlink_routes(NML3ConfigData *self, int addr_fam
if (NM_FLAGS_HAS(route_src->rx.r_rtm_flags, (unsigned) RTNH_F_ONLINK))
continue;
if (nm_l3_config_data_get_direct_route_for_host(self, addr_family, p_gateway))
if (_data_get_direct_route_for_host(self, addr_family, p_gateway))
continue;
new_route = nmp_object_clone(obj_src, FALSE);
@ -3208,9 +2991,12 @@ _init_from_connection_ip(NML3ConfigData *self, int addr_family, NMConnection *co
* the one we create here (because the "onlink" flag is part of the
* identifier of a route, see nm_platform_ip4_route_cmp()).
*
* The onlink flag is tracked per-nexthop (in NMPlatformIP4RtNextHop.rtnh_flags
* for extra nexthops, and in r_rtm_flags for the first nexthop). ECMP routes
* can be merged regardless of per-nexthop onlink flags. */
* Note however that for ECMP routes we currently can only merge routes
* that agree in their onlink flag. So a route without gateway cannot
* merge with an onlink route that has a gateway. That needs fixing,
* by not treating the onlink flag as for the entire route, but allowing
* to merge ECMP routes with different onlink flag. And first, we need
* to track the onlink flag for the nexthop (NMPlatformIP4RtNextHop). */
r.r4.r_rtm_flags &= ~((unsigned) RTNH_F_ONLINK);
}
@ -3244,9 +3030,6 @@ _init_from_connection_ip(NML3ConfigData *self, int addr_family, NMConnection *co
nm_l3_config_data_set_ip6_privacy(
self,
nm_setting_ip6_config_get_ip6_privacy(NM_SETTING_IP6_CONFIG(s_ip)));
nm_l3_config_data_set_ip6_mtu_static(
self,
nm_setting_ip6_config_get_mtu(NM_SETTING_IP6_CONFIG(s_ip)));
}
}
@ -3723,9 +3506,6 @@ nm_l3_config_data_merge(NML3ConfigData *self,
if (self->ip6_token.id == 0)
self->ip6_token.id = src->ip6_token.id;
if (!self->network_id)
self->network_id = nm_ref_string_ref(src->network_id);
self->metered = NM_MAX((NMTernary) self->metered, (NMTernary) src->metered);
if (self->proxy_method == NM_PROXY_CONFIG_METHOD_UNKNOWN)
@ -3764,11 +3544,8 @@ nm_l3_config_data_merge(NML3ConfigData *self,
if (self->mtu == 0u)
self->mtu = src->mtu;
if (self->ip6_mtu_static == 0u)
self->ip6_mtu_static = src->ip6_mtu_static;
if (self->ip6_mtu_ra == 0u)
self->ip6_mtu_ra = src->ip6_mtu_ra;
if (self->ip6_mtu == 0u)
self->ip6_mtu = src->ip6_mtu;
if (NM_FLAGS_HAS(merge_flags, NM_L3_CONFIG_MERGE_FLAGS_CLONE)) {
_nm_unused nm_auto_unref_dhcplease NMDhcpLease *dhcp_lease_6 =
@ -3790,24 +3567,6 @@ nm_l3_config_data_merge(NML3ConfigData *self,
self->routed_dns_4 = TRUE;
if (src->routed_dns_6)
self->routed_dns_6 = TRUE;
if (self->clat_config == NM_SETTING_IP4_CONFIG_CLAT_NO) {
/* 'no' always loses to 'force' and 'auto' */
self->clat_config = src->clat_config;
} else if (src->clat_config == NM_SETTING_IP4_CONFIG_CLAT_FORCE) {
/* 'force' always takes precedence */
self->clat_config = src->clat_config;
}
if (!self->clat_state.enabled && src->clat_state.enabled) {
self->clat_state = src->clat_state;
}
if (src->pref64_valid) {
self->pref64_prefix = src->pref64_prefix;
self->pref64_plen = src->pref64_plen;
self->pref64_valid = src->pref64_valid;
}
}
NML3ConfigData *

View file

@ -5,7 +5,6 @@
#include "libnm-glib-aux/nm-dedup-multi.h"
#include "nm-setting-connection.h"
#include "nm-setting-ip4-config.h"
#include "nm-setting-ip6-config.h"
#include "libnm-platform/nm-platform.h"
#include "libnm-platform/nmp-object.h"
@ -226,10 +225,6 @@ nm_l3_config_data_equal(const NML3ConfigData *a, const NML3ConfigData *b)
/*****************************************************************************/
const NMPObject *nm_l3_config_data_get_direct_route_for_host(const NML3ConfigData *self,
int addr_family,
gconstpointer host);
const NMDedupMultiIdxType *nm_l3_config_data_lookup_index(const NML3ConfigData *self,
NMPObjectType obj_type);
@ -487,49 +482,14 @@ guint32 nm_l3_config_data_get_mtu(const NML3ConfigData *self);
gboolean nm_l3_config_data_set_mtu(NML3ConfigData *self, guint32 mtu);
guint32 nm_l3_config_data_get_ip6_mtu_static(const NML3ConfigData *self);
guint32 nm_l3_config_data_get_ip6_mtu(const NML3ConfigData *self);
gboolean nm_l3_config_data_set_ip6_mtu_static(NML3ConfigData *self, guint32 ip6_mtu);
guint32 nm_l3_config_data_get_ip6_mtu_ra(const NML3ConfigData *self);
gboolean nm_l3_config_data_set_ip6_mtu_ra(NML3ConfigData *self, guint32 ip6_mtu);
gboolean nm_l3_config_data_set_ip6_mtu(NML3ConfigData *self, guint32 ip6_mtu);
NMUtilsIPv6IfaceId nm_l3_config_data_get_ip6_token(const NML3ConfigData *self);
gboolean nm_l3_config_data_set_ip6_token(NML3ConfigData *self, NMUtilsIPv6IfaceId ipv6_token);
gboolean nm_l3_config_data_set_network_id(NML3ConfigData *self, const char *network_id);
const char *nm_l3_config_data_get_network_id(const NML3ConfigData *self);
gboolean nm_l3_config_data_set_clat_config(NML3ConfigData *self, NMSettingIp4ConfigClat val);
NMSettingIp4ConfigClat nm_l3_config_data_get_clat_config(const NML3ConfigData *self);
gboolean nm_l3_config_data_get_clat_state(const NML3ConfigData *self,
struct in6_addr *out_ip6,
struct in6_addr *out_pref64,
guint8 *out_pref64_plen,
in_addr_t *out_ip4);
void nm_l3_config_data_set_clat_state(NML3ConfigData *self,
gboolean enabled,
const struct in6_addr *ip6,
const struct in6_addr *pref64,
guint8 pref64_plen,
in_addr_t ip4);
gboolean nm_l3_config_data_set_pref64_valid(NML3ConfigData *self, gboolean val);
gboolean nm_l3_config_data_get_pref64_valid(const NML3ConfigData *self);
gboolean nm_l3_config_data_get_pref64(const NML3ConfigData *self,
struct in6_addr *out_prefix,
guint32 *out_plen);
gboolean nm_l3_config_data_set_pref64(NML3ConfigData *self, struct in6_addr prefix, guint32 plen);
NMMptcpFlags nm_l3_config_data_get_mptcp_flags(const NML3ConfigData *self);
gboolean nm_l3_config_data_set_mptcp_flags(NML3ConfigData *self, NMMptcpFlags mptcp_flags);

View file

@ -7,15 +7,10 @@
#include "libnm-std-aux/nm-linux-compat.h"
#include <net/if.h>
#include <net/if_arp.h>
#include "nm-compat-headers/linux/if_addr.h"
#include <linux/if_ether.h>
#include <linux/rtnetlink.h>
#include <linux/fib_rules.h>
#if HAVE_CLAT
#include <bpf/libbpf.h>
#include <bpf/bpf.h>
#endif /* HAVE_CLAT */
#include "libnm-core-aux-intern/nm-libnm-core-utils.h"
#include "libnm-glib-aux/nm-prioq.h"
@ -27,13 +22,6 @@
#include "n-acd/src/n-acd.h"
#include "nm-l3-ipv4ll.h"
#include "nm-ip-config.h"
#include "nm-core-utils.h"
#if HAVE_CLAT
#include "bpf/clat.h"
NM_PRAGMA_WARNING_DISABLE("-Wcast-align")
#include "bpf/clat.skel.h"
NM_PRAGMA_WARNING_REENABLE
#endif /* HAVE_CLAT */
/*****************************************************************************/
@ -301,24 +289,6 @@ typedef struct _NML3CfgPrivate {
NMIPConfig *ipconfig_x[2];
};
#if HAVE_CLAT
/* The reserved IPv4 address for CLAT in the 192.0.0.0/28 range */
NMNetnsIPReservation *clat_address_4;
/* The IPv6 address for sending and receiving translated packets */
NMPlatformIP6Address clat_address_6;
/* The same addresses as above, but already committed previously */
NMNetnsIPReservation *clat_address_4_committed;
NMPlatformIP6Address clat_address_6_committed;
/* If NULL, the BPF program hasn't been loaded or attached */
struct clat_bpf *clat_bpf;
struct bpf_link *clat_ingress_link;
struct bpf_link *clat_egress_link;
int clat_socket;
#endif /* HAVE_CLAT */
/* Whether we earlier configured MPTCP endpoints for the interface. */
union {
struct {
@ -383,9 +353,6 @@ typedef struct _NML3CfgPrivate {
bool rp_filter_handled : 1;
bool rp_filter_set : 1;
bool clat_address_6_valid : 1;
bool clat_address_6_committed_valid : 1;
} NML3CfgPrivate;
struct _NML3CfgClass {
@ -657,7 +624,7 @@ _l3_config_notify_data_to_string(const NML3ConfigNotifyData *notify_data,
case NM_L3_CONFIG_NOTIFY_TYPE_PLATFORM_CHANGE_ON_IDLE:
nm_strbuf_append(&s,
&l,
", obj-type-flags=0x%" G_GINT64_MODIFIER "x",
", obj-type-flags=0x%x",
notify_data->platform_change_on_idle.obj_type_flags);
break;
case NM_L3_CONFIG_NOTIFY_TYPE_IPV4LL_EVENT:
@ -1604,7 +1571,7 @@ _load_link(NML3Cfg *self, gboolean initial)
/*****************************************************************************/
void
_nm_l3cfg_notify_platform_change_on_idle(NML3Cfg *self, guint64 obj_type_flags)
_nm_l3cfg_notify_platform_change_on_idle(NML3Cfg *self, guint32 obj_type_flags)
{
NML3ConfigNotifyData notify_data;
@ -4140,233 +4107,6 @@ update_routes:
}
}
static void
_l3cfg_update_clat_config(NML3Cfg *self,
NML3ConfigData *l3cd,
const L3ConfigData **l3_config_datas_arr,
guint l3_config_datas_len)
{
#if !HAVE_CLAT
return;
#else
struct in6_addr pref64;
guint32 pref64_plen;
gboolean clat_enabled = FALSE;
const NMPlatformIP4Route *ip4_route;
NMDedupMultiIter iter;
switch (nm_l3_config_data_get_clat_config(l3cd)) {
case NM_SETTING_IP4_CONFIG_CLAT_FORCE:
clat_enabled = TRUE;
break;
case NM_SETTING_IP4_CONFIG_CLAT_NO:
clat_enabled = FALSE;
break;
case NM_SETTING_IP4_CONFIG_CLAT_AUTO:
clat_enabled = TRUE;
/* disable if there is a native IPv4 gateway */
nm_l3_config_data_iter_ip4_route_for_each (&iter, l3cd, &ip4_route) {
if (ip4_route->network == INADDR_ANY && ip4_route->plen == 0
&& ip4_route->gateway != INADDR_ANY)
clat_enabled = FALSE;
break;
}
break;
case NM_SETTING_IP4_CONFIG_CLAT_DEFAULT:
nm_assert_not_reached();
clat_enabled = TRUE;
break;
}
if (clat_enabled && nm_l3_config_data_get_pref64_valid(l3cd)) {
NMPlatformIPXRoute rx;
NMIPAddrTyped best_v6_gateway;
const NMPlatformIP6Route *best_v6_route;
const NMPlatformIP6Address *ip6_entry;
struct in6_addr ip6;
const char *network_id;
char buf[512];
guint32 route4_metric = NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP4;
guint i;
/* If we have a valid NAT64 prefix, configure in kernel:
*
* - a CLAT IPv4 address (192.0.0.x)
* - a IPv4 default route via the best IPv6 gateway
*
* We also set clat_address_6 as an additional /64 IPv6 address
* determined according to https://www.rfc-editor.org/rfc/rfc6877#section-6.3 .
* This address is used for sending and receiving translated packets,
* but is not configured in kernel to avoid that it gets used by applications.
* Later in _l3_commit_pref64() we use IPV6_JOIN_ANYCAST to let the kernel
* handle ND for the address.
*/
nm_l3_config_data_get_pref64(l3cd, &pref64, &pref64_plen);
network_id = nm_l3_config_data_get_network_id(l3cd);
if (!self->priv.p->clat_address_6_valid && network_id) {
nm_l3_config_data_iter_ip6_address_for_each (&iter, l3cd, &ip6_entry) {
if (ip6_entry->addr_source == NM_IP_CONFIG_SOURCE_NDISC && ip6_entry->plen == 64) {
ip6 = ip6_entry->address;
nm_utils_ipv6_addr_set_stable_privacy(NM_UTILS_STABLE_TYPE_CLAT,
&ip6,
nm_l3cfg_get_ifname(self, TRUE),
network_id,
0);
self->priv.p->clat_address_6 = (NMPlatformIP6Address) {
.ifindex = self->priv.ifindex,
.address = ip6,
.peer_address = ip6,
.addr_source = NM_IP_CONFIG_SOURCE_CLAT,
.plen = ip6_entry->plen,
};
_LOGT("clat: using IPv6 address %s", nm_inet6_ntop(&ip6, buf));
self->priv.p->clat_address_6_valid = TRUE;
break;
}
}
}
/* Don't get a v4 address if we have no v6 address (otherwise, we could
* potentially create broken v4 connectivity) */
if (!self->priv.p->clat_address_6_valid) {
_LOGW("CLAT is currently only supported when SLAAC is in use.");
/* Deallocate the v4 address unless it's the committed one */
if (self->priv.p->clat_address_4 != self->priv.p->clat_address_4_committed) {
nm_clear_pointer(&self->priv.p->clat_address_4, nm_netns_ip_reservation_release);
} else {
self->priv.p->clat_address_4 = NULL;
}
} else if (!self->priv.p->clat_address_4) {
/* We need a v4 /32 */
self->priv.p->clat_address_4 =
nm_netns_ip_reservation_get(self->priv.netns, NM_NETNS_IP_RESERVATION_TYPE_CLAT);
}
{
const NMPlatformIP4Route *r4;
guint32 metric = 0;
guint32 penalty = 0;
/* Find the IPv4 metric for the CLAT default route.
* If there is another non-CLAT default route on the device, use the
* same metric + 1, so that native connectivity is always preferred.
* Otherwise, use the metric from the connection profile.
*/
r4 = NMP_OBJECT_CAST_IP4_ROUTE(nm_l3_config_data_get_best_default_route(l3cd, AF_INET));
if (r4) {
route4_metric = nm_add_clamped_u32(r4->metric, 1u);
} else {
for (i = 0; i < l3_config_datas_len; i++) {
const L3ConfigData *l3cd_data = l3_config_datas_arr[i];
if (l3cd_data->default_route_metric_4 != NM_PLATFORM_ROUTE_METRIC_DEFAULT_IP4) {
metric = l3cd_data->default_route_metric_4;
}
if (l3cd_data->default_route_penalty_4 != 0) {
penalty = l3cd_data->default_route_penalty_4;
}
}
route4_metric = nm_add_clamped_u32(metric, penalty);
}
}
if (self->priv.p->clat_address_4) {
best_v6_route = NMP_OBJECT_CAST_IP6_ROUTE(
nm_l3_config_data_get_direct_route_for_host(l3cd, AF_INET6, &pref64));
if (!best_v6_route) {
best_v6_route = NMP_OBJECT_CAST_IP6_ROUTE(
nm_l3_config_data_get_best_default_route(l3cd, AF_INET6));
}
if (best_v6_route) {
NMPlatformIP4Address addr = {
.ifindex = self->priv.ifindex,
.address = self->priv.p->clat_address_4->addr,
.peer_address = self->priv.p->clat_address_4->addr,
.addr_source = NM_IP_CONFIG_SOURCE_CLAT,
.plen = 32,
};
const NMPlatformLink *pllink;
guint mtu = 0;
guint val = 0;
best_v6_gateway.addr_family = AF_INET6;
best_v6_gateway.addr.addr6 = best_v6_route->gateway;
/* Determine the IPv6 MTU of the interface. Unfortunately,
* the logic to set the MTU is in NMDevice and here we need
* some duplication to find the actual value.
* TODO: move the MTU handling into l3cfg. */
/* Get the link MTU */
pllink = nm_l3cfg_get_pllink(self, TRUE);
if (pllink)
mtu = pllink->mtu;
if (mtu == 0)
mtu = 1500;
/* Update it with the IPv6 MTU value from the connection
* or from RA */
val = nm_l3_config_data_get_ip6_mtu_static(l3cd);
if (val == 0) {
val = nm_l3_config_data_get_ip6_mtu_ra(l3cd);
}
if (val != 0 && val < mtu) {
mtu = val;
}
if (mtu < 1280)
mtu = 1280;
/* Leave 20 additional bytes for the ipv4 -> ipv6 header translation,
* plus 8 for a potential fragmentation extension header */
mtu -= 28;
rx.r4 = (NMPlatformIP4Route) {
.ifindex = self->priv.ifindex,
.rt_source = NM_IP_CONFIG_SOURCE_CLAT,
.network = 0, /* default route */
.plen = 0,
.table_coerced = nm_platform_route_table_coerce(RT_TABLE_MAIN),
.scope_inv = nm_platform_route_scope_inv(RT_SCOPE_UNIVERSE),
.type_coerced = nm_platform_route_type_coerce(RTN_UNICAST),
.pref_src = self->priv.p->clat_address_4->addr,
.via = best_v6_gateway,
.metric = route4_metric,
.mtu = mtu,
};
nm_platform_ip_route_normalize(AF_INET, &rx.rx);
if (!nm_l3_config_data_lookup_route(l3cd, AF_INET, &rx.rx)) {
nm_l3_config_data_add_route_4(l3cd, &rx.r4);
}
_LOGT("clat: route %s", nm_platform_ip4_route_to_string(&rx.r4, buf, sizeof(buf)));
nm_l3_config_data_add_address_4(l3cd, &addr);
} else {
_LOGW("Couldn't find a good ipv6 route! Unable to set up CLAT!");
}
}
if (self->priv.p->clat_address_4 && self->priv.p->clat_address_6_valid) {
nm_l3_config_data_set_clat_state(l3cd,
TRUE,
&self->priv.p->clat_address_6.address,
&pref64,
pref64_plen,
self->priv.p->clat_address_4->addr);
} else {
nm_l3_config_data_set_clat_state(l3cd, FALSE, NULL, NULL, 0, INADDR_ANY);
}
}
#endif /* HAVE_CLAT */
}
static void
_l3cfg_update_combined_config(NML3Cfg *self,
gboolean to_commit,
@ -4480,8 +4220,6 @@ _l3cfg_update_combined_config(NML3Cfg *self,
&hook_data);
}
_l3cfg_update_clat_config(self, l3cd, l3_config_datas_arr, l3_config_datas_len);
if (self->priv.ifindex == NM_LOOPBACK_IFINDEX) {
NMPlatformIPXAddress ax;
NMPlatformIPXRoute rx;
@ -4542,18 +4280,6 @@ _l3cfg_update_combined_config(NML3Cfg *self,
if (nm_l3_config_data_equal(l3cd, self->priv.p->combined_l3cd_merged))
goto out;
#if HAVE_CLAT
if (!l3cd) {
self->priv.p->clat_address_6_valid = FALSE;
/* Deallocate the v4 address unless it's the commited one */
if (self->priv.p->clat_address_4 != self->priv.p->clat_address_4_committed) {
nm_clear_pointer(&self->priv.p->clat_address_4, nm_netns_ip_reservation_release);
} else {
self->priv.p->clat_address_4 = NULL;
}
}
#endif /* HAVE_CLAT */
l3cd_old = g_steal_pointer(&self->priv.p->combined_l3cd_merged);
self->priv.p->combined_l3cd_merged = nm_l3_config_data_seal(g_steal_pointer(&l3cd));
merged_changed = TRUE;
@ -5653,251 +5379,6 @@ _l3_commit_one(NML3Cfg *self,
_failedobj_handle_routes(self, addr_family, routes_failed);
}
#if HAVE_CLAT
static void
_l3_clat_destroy(NML3Cfg *self)
{
char buf[100];
int err;
if (self->priv.p->clat_bpf) {
const struct clat_stats *s = &self->priv.p->clat_bpf->bss->stats;
_LOGT("clat: stats:"
" egress (v4 to v6): tcp %" G_GUINT64_FORMAT ", udp %" G_GUINT64_FORMAT
", icmp %" G_GUINT64_FORMAT ", other %" G_GUINT64_FORMAT
", dropped %" G_GUINT64_FORMAT "; ingress (v6 to v4): tcp %" G_GUINT64_FORMAT
", udp %" G_GUINT64_FORMAT ", icmp %" G_GUINT64_FORMAT ", other %" G_GUINT64_FORMAT
", fragment %" G_GUINT64_FORMAT ", dropped %" G_GUINT64_FORMAT,
(guint64) s->egress_tcp,
(guint64) s->egress_udp,
(guint64) s->egress_icmp,
(guint64) s->egress_other,
(guint64) s->egress_dropped,
(guint64) s->ingress_tcp,
(guint64) s->ingress_udp,
(guint64) s->ingress_icmp,
(guint64) s->ingress_other,
(guint64) s->ingress_fragment,
(guint64) s->ingress_dropped);
}
if (self->priv.p->clat_ingress_link) {
err = bpf_link__destroy(self->priv.p->clat_ingress_link);
if (err != 0) {
libbpf_strerror(err, buf, sizeof(buf));
_LOGD("clat: failed to destroy the ingress link");
}
self->priv.p->clat_ingress_link = NULL;
}
if (self->priv.p->clat_egress_link) {
err = bpf_link__destroy(self->priv.p->clat_egress_link);
if (err != 0) {
libbpf_strerror(err, buf, sizeof(buf));
_LOGD("clat: failed to destroy the egress link");
}
self->priv.p->clat_egress_link = NULL;
}
nm_clear_pointer(&self->priv.p->clat_bpf, clat_bpf__destroy);
}
static void
_l3_commit_pref64(NML3Cfg *self, NML3CfgCommitType commit_type)
{
int err = 0;
const NML3ConfigData *l3cd = self->priv.p->combined_l3cd_commited;
struct in6_addr _l3cd_pref64_inner;
const struct in6_addr *l3cd_pref64 = NULL;
guint32 l3cd_pref64_plen;
char buf[100];
struct clat_config clat_config;
gboolean v6_changed;
const NMPlatformLink *pllink;
gboolean has_ethernet_header = FALSE;
if (l3cd && nm_l3_config_data_get_pref64(l3cd, &_l3cd_pref64_inner, &l3cd_pref64_plen)) {
l3cd_pref64 = &_l3cd_pref64_inner;
}
if (l3cd_pref64 && self->priv.p->clat_address_4 && self->priv.p->clat_address_6_valid) {
pllink = nm_l3cfg_get_pllink(self, TRUE);
if (!pllink) {
has_ethernet_header = TRUE;
} else {
switch (pllink->arptype) {
case ARPHRD_ETHER:
has_ethernet_header = TRUE;
break;
case ARPHRD_NONE:
case ARPHRD_PPP:
case ARPHRD_RAWIP:
has_ethernet_header = FALSE;
break;
default:
_LOGD("clat: unknown ARP type %u, assuming the interface uses no L2 header",
pllink->arptype);
has_ethernet_header = FALSE;
}
}
if (!self->priv.p->clat_bpf) {
_LOGT("clat: attaching the BPF program");
self->priv.p->clat_bpf = clat_bpf__open();
if (!self->priv.p->clat_bpf) {
libbpf_strerror(errno, buf, sizeof(buf));
_LOGW("clat: failed to open the BPF program: %s", buf);
return;
}
/* Only load the programs for the right L2 type */
bpf_program__set_autoload(self->priv.p->clat_bpf->progs.nm_clat_ingress_eth,
has_ethernet_header);
bpf_program__set_autoload(self->priv.p->clat_bpf->progs.nm_clat_egress_eth,
has_ethernet_header);
bpf_program__set_autoload(self->priv.p->clat_bpf->progs.nm_clat_ingress_rawip,
!has_ethernet_header);
bpf_program__set_autoload(self->priv.p->clat_bpf->progs.nm_clat_egress_rawip,
!has_ethernet_header);
if (clat_bpf__load(self->priv.p->clat_bpf)) {
libbpf_strerror(errno, buf, sizeof(buf));
_LOGW("clat: failed to load the BPF program: %s", buf);
nm_clear_pointer(&self->priv.p->clat_bpf, clat_bpf__destroy);
return;
}
self->priv.p->clat_ingress_link = bpf_program__attach_tcx(
has_ethernet_header ? self->priv.p->clat_bpf->progs.nm_clat_ingress_eth
: self->priv.p->clat_bpf->progs.nm_clat_ingress_rawip,
self->priv.ifindex,
NULL);
if (!self->priv.p->clat_ingress_link) {
libbpf_strerror(errno, buf, sizeof(buf));
_LOGW("clat: failed to attach the ingress program: %s", buf);
return;
}
self->priv.p->clat_egress_link = bpf_program__attach_tcx(
has_ethernet_header ? self->priv.p->clat_bpf->progs.nm_clat_egress_eth
: self->priv.p->clat_bpf->progs.nm_clat_egress_rawip,
self->priv.ifindex,
NULL);
if (!self->priv.p->clat_egress_link) {
libbpf_strerror(errno, buf, sizeof(buf));
_LOGW("clat: failed to attach the egress program: %s", buf);
return;
}
_LOGT("clat: program attached successfully");
}
/* Pass configuration to the BPF program */
memset(&clat_config, 0, sizeof(clat_config));
clat_config.local_v4.s_addr = self->priv.p->clat_address_4->addr;
clat_config.local_v6 = self->priv.p->clat_address_6.address;
clat_config.pref64 = *l3cd_pref64;
clat_config.pref64_len = l3cd_pref64_plen;
self->priv.p->clat_bpf->bss->config = clat_config;
if (self->priv.p->clat_socket < 0) {
self->priv.p->clat_socket = socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
if (self->priv.p->clat_socket < 0) {
_LOGW("clat: couldn't create the socket: %s", nm_strerror_native(errno));
}
}
if (self->priv.p->clat_socket >= 0) {
err = setsockopt(self->priv.p->clat_socket,
SOL_SOCKET,
SO_BINDTOIFINDEX,
&self->priv.ifindex,
sizeof(self->priv.ifindex));
if (err < 0) {
_LOGW("clat: couldn't bind the socket: %s", nm_strerror_native(errno));
}
}
v6_changed =
(self->priv.p->clat_address_6_valid != self->priv.p->clat_address_6_committed_valid)
|| (self->priv.p->clat_address_6_valid && self->priv.p->clat_address_6_committed_valid
&& memcmp(&self->priv.p->clat_address_6.address,
&self->priv.p->clat_address_6_committed.address,
sizeof(self->priv.p->clat_address_6_committed.address)));
if (self->priv.p->clat_socket > 0 && v6_changed) {
struct ipv6_mreq mreq = {.ipv6mr_interface = self->priv.ifindex};
if (self->priv.p->clat_address_6_committed_valid) {
mreq.ipv6mr_multiaddr = self->priv.p->clat_address_6_committed.address;
err = setsockopt(self->priv.p->clat_socket,
SOL_IPV6,
IPV6_LEAVE_ANYCAST,
&mreq,
sizeof(mreq));
if (err < 0) {
_LOGW("clat: couldn't leave the anycast group: %s", nm_strerror_native(errno));
}
}
if (self->priv.p->clat_address_6_valid) {
/* As per draft-ietf-v6ops-claton-14, hosts must perform duplicate
* addresses detection (DAD) on the generated CLAT IPv6 address. This is
* necessary not only to avoid address collisions but also because some
* networks drop traffic from addresses that have not done DAD.
* Since doing true DAD adds complexity, adopt the same approach as
* Android: start DAD by sending a neighbor solicitation and don't wait
* for any reply. This avoids the problem with dropped traffic; it
* doesn't help with collisions, but collisions are anyway very unlikely
* because the interface identifier is a random 64-bit value.
*/
nm_utils_ipv6_dad_send(&self->priv.p->clat_address_6.address,
self->priv.ifindex,
pllink ? pllink->arptype : ARPHRD_ETHER);
mreq.ipv6mr_multiaddr = self->priv.p->clat_address_6.address;
err = setsockopt(self->priv.p->clat_socket,
SOL_IPV6,
IPV6_JOIN_ANYCAST,
&mreq,
sizeof(mreq));
if (err < 0) {
_LOGW("clat: couldn't join the anycast group: %s", nm_strerror_native(errno));
}
}
}
} else {
if (self->priv.p->clat_bpf) {
_l3_clat_destroy(self);
}
/* Committed will get cleaned up below */
self->priv.p->clat_address_6_valid = FALSE;
nm_clear_fd(&self->priv.p->clat_socket);
/* Deallocate the v4 address. Committed address will get cleaned up below,
but we need to make sure there's no double-free */
if (self->priv.p->clat_address_4 != self->priv.p->clat_address_4_committed) {
nm_clear_pointer(&self->priv.p->clat_address_4, nm_netns_ip_reservation_release);
} else {
self->priv.p->clat_address_4 = NULL;
}
}
/* Record the new state */
if (self->priv.p->clat_address_4_committed != self->priv.p->clat_address_4) {
nm_clear_pointer(&self->priv.p->clat_address_4_committed, nm_netns_ip_reservation_release);
self->priv.p->clat_address_4_committed = self->priv.p->clat_address_4;
}
self->priv.p->clat_address_6_committed = self->priv.p->clat_address_6;
self->priv.p->clat_address_6_committed_valid = self->priv.p->clat_address_6_valid;
}
#endif /* HAVE_CLAT */
static void
_l3_commit(NML3Cfg *self, NML3CfgCommitType commit_type, gboolean is_idle)
{
@ -5980,10 +5461,6 @@ _l3_commit(NML3Cfg *self, NML3CfgCommitType commit_type, gboolean is_idle)
_l3_acd_data_process_changes(self);
#if HAVE_CLAT
_l3_commit_pref64(self, commit_type);
#endif /* HAVE_CLAT */
nm_assert(self->priv.p->commit_reentrant_count == 1);
self->priv.p->commit_reentrant_count--;
@ -6365,10 +5842,6 @@ nm_l3cfg_init(NML3Cfg *self)
{
self->priv.p = G_TYPE_INSTANCE_GET_PRIVATE(self, NM_TYPE_L3CFG, NML3CfgPrivate);
#if HAVE_CLAT
self->priv.p->clat_socket = -1;
#endif /* HAVE_CLAT */
c_list_init(&self->priv.p->acd_lst_head);
c_list_init(&self->priv.p->acd_event_notify_lst_head);
c_list_init(&self->priv.p->commit_type_lst_head);
@ -6477,14 +5950,6 @@ finalize(GObject *object)
if (changed)
nmp_global_tracker_sync_mptcp_addrs(self->priv.global_tracker, FALSE);
#if HAVE_CLAT
self->priv.p->clat_address_4_committed = NULL;
nm_clear_pointer(&self->priv.p->clat_address_4, nm_netns_ip_reservation_release);
nm_clear_fd(&self->priv.p->clat_socket);
if (self->priv.p->clat_bpf) {
_l3_clat_destroy(self);
}
#endif
g_clear_object(&self->priv.netns);
g_clear_object(&self->priv.platform);
nm_clear_pointer(&self->priv.global_tracker, nmp_global_tracker_unref);

View file

@ -178,7 +178,7 @@ typedef struct {
} platform_change;
struct {
guint64 obj_type_flags;
guint32 obj_type_flags;
} platform_change_on_idle;
struct {
@ -207,7 +207,7 @@ struct _NML3Cfg {
* NML3Cfg instance. We track some per-l3cfg-data that is only
* relevant to NMNetns here. */
struct {
guint64 signal_pending_obj_type_flags;
guint32 signal_pending_obj_type_flags;
CList signal_pending_lst;
CList ecmp_track_ifindex_lst_head;
} internal_netns;
@ -223,7 +223,7 @@ NML3Cfg *nm_l3cfg_new(NMNetns *netns, int ifindex);
gboolean nm_l3cfg_is_ready(NML3Cfg *self);
void _nm_l3cfg_notify_platform_change_on_idle(NML3Cfg *self, guint64 obj_type_flags);
void _nm_l3cfg_notify_platform_change_on_idle(NML3Cfg *self, guint32 obj_type_flags);
void _nm_l3cfg_notify_platform_change(NML3Cfg *self,
NMPlatformSignalChangeType change_type,

View file

@ -207,7 +207,6 @@ _ecmp_track_sort_lst_cmp(const CList *a, const CList *b, const void *user_data)
NM_CMP_FIELD(route_a, route_b, ifindex);
NM_CMP_FIELD(route_b, route_a, weight);
NM_CMP_DIRECT(htonl(route_a->gateway), htonl(route_b->gateway));
NM_CMP_DIRECT(route_a->r_rtm_flags & RTNH_F_ONLINK, route_b->r_rtm_flags & RTNH_F_ONLINK);
return nm_assert_unreachable_val(
nm_platform_ip4_route_cmp(route_a, route_b, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID));
@ -276,10 +275,9 @@ _ecmp_track_init_merged_obj(EcmpTrackEcmpid *track_ecmpid, const NMPObject **out
NMPlatformIP4RtNextHop *nh = (gpointer) &obj_new->_ip4_route.extra_nexthops[i - 1];
*nh = (NMPlatformIP4RtNextHop) {
.ifindex = r->ifindex,
.gateway = r->gateway,
.weight = r->weight,
.rtnh_flags = r->r_rtm_flags & RTNH_F_ONLINK,
.ifindex = r->ifindex,
.gateway = r->gateway,
.weight = r->weight,
};
}
i++;
@ -576,8 +574,8 @@ notify_watcher:
typedef struct {
const char *name;
guint32 start_addr; /* host byte order */
guint range_plen;
guint addr_plen;
guint prefix_len;
guint num_addrs;
gboolean allow_reuse;
} IPReservationTypeDesc;
@ -585,19 +583,11 @@ static const IPReservationTypeDesc ip_reservation_types[_NM_NETNS_IP_RESERVATION
[NM_NETNS_IP_RESERVATION_TYPE_SHARED4] =
{
.name = "shared-ip4",
.start_addr = 0x0a2a0001, /* 10.42.{0-255}.1/24 */
.range_plen = 16,
.addr_plen = 24,
.start_addr = 0x0a2a0001, /* 10.42.0.1 */
.prefix_len = 24,
.num_addrs = 256,
.allow_reuse = TRUE,
},
[NM_NETNS_IP_RESERVATION_TYPE_CLAT] =
{
.name = "clat",
.start_addr = 0xc0000005, /* 192.0.0.{5-7,0-4}/32 */
.range_plen = 29,
.addr_plen = 32,
.allow_reuse = FALSE,
},
};
NMNetnsIPReservation *
@ -623,23 +613,13 @@ nm_netns_ip_reservation_get(NMNetns *self, NMNetnsIPReservationType type)
g_object_ref(self);
} else {
guint32 count;
guint32 base_network;
guint32 host_mask;
guint32 increment;
nm_assert(g_hash_table_size(*table) > 0);
nm_assert(desc->range_plen < 32);
nm_assert(desc->addr_plen > 0 && desc->addr_plen <= 32);
nm_assert(desc->addr_plen > desc->range_plen);
base_network = desc->start_addr & ~(0xFFFFFFFFu >> desc->range_plen);
host_mask = 0xFFFFFFFFu >> desc->range_plen;
increment = 1 << (32 - desc->addr_plen);
nm_assert(desc->prefix_len > 0 && desc->prefix_len <= 32);
count = 0u;
for (;;) {
addr = htonl(base_network
+ ((base_network + (desc->start_addr + count * increment)) & host_mask));
addr = htonl(desc->start_addr + (count << (32 - desc->prefix_len)));
res = g_hash_table_lookup(*table, &addr);
if (!res)
@ -647,7 +627,7 @@ nm_netns_ip_reservation_get(NMNetns *self, NMNetnsIPReservationType type)
count++;
if (count >= 1 << (desc->addr_plen - desc->range_plen)) {
if (count >= desc->num_addrs) {
if (!desc->allow_reuse) {
_LOGE("%s: ran out of IP addresses", desc->name);
return NULL;
@ -657,12 +637,12 @@ nm_netns_ip_reservation_get(NMNetns *self, NMNetnsIPReservationType type)
_LOGE("%s: ran out of IP addresses. Reuse %s/%u",
desc->name,
nm_inet4_ntop(res->addr, buf),
desc->addr_plen);
desc->prefix_len);
} else {
_LOGD("%s: reserved IP address %s/%u (duplicate)",
desc->name,
nm_inet4_ntop(res->addr, buf),
desc->addr_plen);
desc->prefix_len);
}
res->_ref_count++;
return res;
@ -683,7 +663,7 @@ nm_netns_ip_reservation_get(NMNetns *self, NMNetnsIPReservationType type)
_LOGD("%s: reserved IP address %s/%u",
desc->name,
nm_inet4_ntop(res->addr, buf),
desc->addr_plen);
desc->prefix_len);
return res;
}
@ -715,7 +695,7 @@ nm_netns_ip_reservation_release(NMNetnsIPReservation *res)
_LOGD("%s: release IP address reservation %s/%u (%d more references held)",
desc->name,
nm_inet4_ntop(res->addr, buf),
desc->addr_plen,
desc->prefix_len,
res->_ref_count);
return;
}
@ -726,7 +706,7 @@ nm_netns_ip_reservation_release(NMNetnsIPReservation *res)
_LOGD("%s: release IP address reservation %s/%u",
desc->name,
nm_inet4_ntop(res->addr, buf),
desc->addr_plen);
desc->prefix_len);
if (g_hash_table_size(*table) == 0) {
nm_clear_pointer(table, g_hash_table_unref);

View file

@ -43,7 +43,6 @@ NML3Cfg *nm_netns_l3cfg_acquire(NMNetns *netns, int ifindex);
typedef enum {
NM_NETNS_IP_RESERVATION_TYPE_SHARED4,
NM_NETNS_IP_RESERVATION_TYPE_CLAT,
_NM_NETNS_IP_RESERVATION_TYPE_NUM,
} NMNetnsIPReservationType;

View file

@ -1230,7 +1230,7 @@ out:
}
gboolean
nmtstp_check_platform_full(NMPlatform *platform, guint64 obj_type_flags, gboolean do_assert)
nmtstp_check_platform_full(NMPlatform *platform, guint32 obj_type_flags, gboolean do_assert)
{
static const NMPObjectType obj_types[] = {
NMP_OBJECT_TYPE_IP4_ADDRESS,
@ -1265,7 +1265,7 @@ nmtstp_check_platform_full(NMPlatform *platform, guint64 obj_type_flags, gboolea
for (i_obj_types = 0; i_obj_types < (int) G_N_ELEMENTS(obj_types); i_obj_types++) {
const NMPObjectType obj_type = obj_types[i_obj_types];
const guint64 i_obj_type_flags = nmp_object_type_to_flags(obj_type);
const guint32 i_obj_type_flags = nmp_object_type_to_flags(obj_type);
gs_unref_ptrarray GPtrArray *arr1 = NULL;
gs_unref_ptrarray GPtrArray *arr2 = NULL;
NMPLookup lookup;
@ -1408,7 +1408,7 @@ nmtstp_check_platform_full(NMPlatform *platform, guint64 obj_type_flags, gboolea
}
void
nmtstp_check_platform(NMPlatform *platform, guint64 obj_type_flags)
nmtstp_check_platform(NMPlatform *platform, guint32 obj_type_flags)
{
if (!nmtstp_check_platform_full(platform, obj_type_flags, FALSE)) {
/* It's unclear why this failure sometimes happens. It happens
@ -2393,61 +2393,6 @@ nmtstp_link_dummy_add(NMPlatform *platform, int external_command, const char *na
return pllink;
}
const NMPlatformLink *
nmtstp_link_geneve_add(NMPlatform *platform,
int external_command,
const char *name,
const NMPlatformLnkGeneve *lnk)
{
const NMPlatformLink *pllink = NULL;
int success;
g_assert(nm_utils_ifname_valid_kernel(name, NULL));
g_assert(lnk->remote || !IN6_IS_ADDR_UNSPECIFIED(&lnk->remote6));
external_command = nmtstp_run_command_check_external(external_command);
_init_platform(&platform, external_command);
if (external_command) {
char remote[NM_INET_ADDRSTRLEN];
char remote6[NM_INET_ADDRSTRLEN];
char str_ttl[30];
if (lnk->remote)
nm_inet4_ntop(lnk->remote, remote);
else
remote[0] = '\0';
if (memcmp(&lnk->remote6, &in6addr_any, sizeof(in6addr_any)))
nm_inet6_ntop(&lnk->remote6, remote6);
else
remote6[0] = '\0';
success = !nmtstp_run_command(
"ip link add %s type geneve id %u remote %s %s tos %02x dstport %u%s",
name,
lnk->id,
remote[0] ? remote : remote6,
lnk->ttl > 0 ? nm_sprintf_buf(str_ttl, "ttl %u", lnk->ttl & 0xff)
: lnk->ttl == 0 ? "ttl auto"
: "ttl inherit",
lnk->tos,
lnk->dst_port,
lnk->df == 1 ? " df set "
: lnk->df == 2 ? " df inherit "
: "");
if (success)
pllink = nmtstp_assert_wait_for_link(platform, name, NM_LINK_TYPE_GENEVE, 100);
} else
success = NMTST_NM_ERR_SUCCESS(nm_platform_link_geneve_add(platform, name, lnk, &pllink));
_assert_pllink(platform, success, pllink, name, NM_LINK_TYPE_GENEVE);
return pllink;
}
const NMPlatformLink *
nmtstp_link_gre_add(NMPlatform *platform,
int external_command,
@ -3079,6 +3024,8 @@ nmtstp_link_vxlan_add(NMPlatform *platform,
return pllink;
}
/*****************************************************************************/
const NMPlatformLink *
nmtstp_link_get_typed(NMPlatform *platform, int ifindex, const char *name, NMLinkType link_type)
{

View file

@ -140,9 +140,9 @@ int nmtstp_run_command(const char *format, ...) _nm_printf(1, 2);
/*****************************************************************************/
gboolean
nmtstp_check_platform_full(NMPlatform *platform, guint64 obj_type_flags, gboolean do_assert);
nmtstp_check_platform_full(NMPlatform *platform, guint32 obj_type_flags, gboolean do_assert);
void nmtstp_check_platform(NMPlatform *platform, guint64 obj_type_flags);
void nmtstp_check_platform(NMPlatform *platform, guint32 obj_type_flags);
/*****************************************************************************/
@ -474,10 +474,6 @@ const NMPlatformLink *nmtstp_link_veth_add(NMPlatform *platform,
const char *peer);
const NMPlatformLink *
nmtstp_link_dummy_add(NMPlatform *platform, int external_command, const char *name);
const NMPlatformLink *nmtstp_link_geneve_add(NMPlatform *platform,
int external_command,
const char *name,
const NMPlatformLnkGeneve *lnk);
const NMPlatformLink *nmtstp_link_gre_add(NMPlatform *platform,
int external_command,
const char *name,

View file

@ -1388,11 +1388,10 @@ test_software_detect(gconstpointer user_data)
const gboolean ext = test_data->external_command;
NMPlatformLnkBridge lnk_bridge = {};
NMPlatformLnkTun lnk_tun;
NMPlatformLnkGeneve lnk_geneve = {};
NMPlatformLnkGre lnk_gre = {};
NMPlatformLnkVti lnk_vti = {};
NMPlatformLnkVti6 lnk_vti6 = {};
nm_auto_close int tun_fd = -1;
NMPlatformLnkGre lnk_gre = {};
NMPlatformLnkVti lnk_vti = {};
NMPlatformLnkVti6 lnk_vti6 = {};
nm_auto_close int tun_fd = -1;
gboolean module_loaded;
nmtstp_run_command_check("ip link add %s type dummy", PARENT_NAME);
@ -1435,31 +1434,6 @@ test_software_detect(gconstpointer user_data)
g_error("Failed adding Bridge interface");
break;
case NM_LINK_TYPE_GENEVE:
{
switch (test_data->test_mode) {
case 0:
lnk_geneve.id = 42;
lnk_geneve.remote = nmtst_inet4_from_string("192.168.1.100");
lnk_geneve.ttl = 64;
lnk_geneve.tos = 0;
lnk_geneve.dst_port = 6081;
lnk_geneve.df = 0;
break;
case 1:
lnk_geneve.id = 12345;
lnk_geneve.remote6 = nmtst_inet6_from_string("2001:db8::1");
lnk_geneve.ttl = 128;
lnk_geneve.tos = 16;
lnk_geneve.dst_port = 6082;
lnk_geneve.df = 1;
break;
}
g_assert(nmtstp_link_geneve_add(NULL, ext, DEVICE_NAME, &lnk_geneve));
break;
}
case NM_LINK_TYPE_GRE:
module_loaded = nmtstp_ensure_module("ip_gre");
@ -2234,34 +2208,6 @@ test_software_detect(gconstpointer user_data)
}
break;
}
case NM_LINK_TYPE_GENEVE:
{
const NMPlatformLnkGeneve *plnk = &lnk->lnk_geneve;
g_assert(plnk == nm_platform_link_get_lnk_geneve(NM_PLATFORM_GET, ifindex, NULL));
switch (test_data->test_mode) {
case 0:
g_assert_cmpint(plnk->id, ==, 42);
nmtst_assert_ip4_address(plnk->remote, "192.168.1.100");
nmtst_assert_ip6_address(&plnk->remote6, "::");
g_assert_cmpint(plnk->ttl, ==, 64);
g_assert_cmpint(plnk->tos, ==, 0);
g_assert_cmpint(plnk->dst_port, ==, 6081);
g_assert_cmpint(plnk->df, ==, 0);
break;
case 1:
g_assert_cmpint(plnk->id, ==, 12345);
nmtst_assert_ip4_address(plnk->remote, "0.0.0.0");
nmtst_assert_ip6_address(&plnk->remote6, "2001:db8::1");
g_assert_cmpint(plnk->ttl, ==, 128);
g_assert_cmpint(plnk->tos, ==, 16);
g_assert_cmpint(plnk->dst_port, ==, 6082);
g_assert_cmpint(plnk->df, ==, 1);
break;
}
break;
}
case NM_LINK_TYPE_WIREGUARD:
{
const NMPlatformLnkWireGuard *plnk = &lnk->lnk_wireguard;
@ -4197,8 +4143,6 @@ _nmtstp_setup_tests(void)
g_test_add_func("/link/external", test_external);
test_software_detect_add("/link/software/detect/bridge", NM_LINK_TYPE_BRIDGE, 0);
test_software_detect_add("/link/software/detect/geneve/0", NM_LINK_TYPE_GENEVE, 0);
test_software_detect_add("/link/software/detect/geneve/1", NM_LINK_TYPE_GENEVE, 1);
test_software_detect_add("/link/software/detect/gre", NM_LINK_TYPE_GRE, 0);
test_software_detect_add("/link/software/detect/gretap", NM_LINK_TYPE_GRETAP, 0);
test_software_detect_add("/link/software/detect/ip6tnl/0", NM_LINK_TYPE_IP6TNL, 0);

View file

@ -2460,78 +2460,6 @@ done:
}
}
/*****************************************************************************/
static void
test_ip4_rtnh_onlink(void)
{
/* Extra nexthops that differ only in rtnh_flags ONLINK should
* compare as different. */
NMPlatformIP4RtNextHop nh_a = {
.ifindex = 2,
.gateway = nmtst_inet4_from_string("10.10.10.10"),
.weight = 1,
.rtnh_flags = 0,
};
NMPlatformIP4RtNextHop nh_b = nh_a;
nh_b.rtnh_flags = RTNH_F_ONLINK;
g_assert_cmpint(nm_platform_ip4_rt_nexthop_cmp(&nh_a, &nh_b, TRUE), !=, 0);
g_assert_cmpint(nm_platform_ip4_rt_nexthop_cmp(&nh_a, &nh_b, FALSE), !=, 0);
nh_b.rtnh_flags = 0;
g_assert_cmpint(nm_platform_ip4_rt_nexthop_cmp(&nh_a, &nh_b, TRUE), ==, 0);
g_assert_cmpint(nm_platform_ip4_rt_nexthop_cmp(&nh_a, &nh_b, FALSE), ==, 0);
}
static void
test_ip4_route_onlink_per_nexthop(void)
{
NMPlatformIP4Route r_a = {};
NMPlatformIP4Route r_b;
/* Two single-hop routes that are identical, except for the onlink flag. */
r_a.ifindex = 1;
r_a.rt_source = NM_IP_CONFIG_SOURCE_USER;
r_a.network = nmtst_inet4_from_string("10.10.10.10");
r_a.plen = 24;
r_a.gateway = nmtst_inet4_from_string("10.10.10.1");
r_a.metric = 100;
r_a.n_nexthops = 1;
r_a.type_coerced = nm_platform_route_type_coerce(RTN_UNICAST);
r_a.scope_inv = nm_platform_route_scope_inv(RT_SCOPE_UNIVERSE);
r_b = r_a;
r_b.r_rtm_flags = RTNH_F_ONLINK;
/* Onlink flag should result in the same ECMP_ID but different IDs. */
g_assert_cmpint(nm_platform_ip4_route_cmp(&r_a, &r_b, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ECMP_ID),
==,
0);
g_assert_cmpint(nm_platform_ip4_route_cmp(&r_a, &r_b, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID), !=, 0);
g_assert_cmpint(
nm_platform_ip4_route_cmp(&r_a, &r_b, NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY),
!=,
0);
g_assert_cmpint(nm_platform_ip4_route_cmp(&r_a, &r_b, NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL),
!=,
0);
r_b.r_rtm_flags = 0;
g_assert_cmpint(nm_platform_ip4_route_cmp(&r_a, &r_b, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID), ==, 0);
g_assert_cmpint(nm_platform_ip4_route_cmp(&r_a, &r_b, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ECMP_ID),
==,
0);
g_assert_cmpint(
nm_platform_ip4_route_cmp(&r_a, &r_b, NM_PLATFORM_IP_ROUTE_CMP_TYPE_SEMANTICALLY),
==,
0);
g_assert_cmpint(nm_platform_ip4_route_cmp(&r_a, &r_b, NM_PLATFORM_IP_ROUTE_CMP_TYPE_FULL),
==,
0);
}
/*****************************************************************************/
NMTstpSetupFunc const _nmtstp_setup_platform_func = SETUP;
@ -2552,8 +2480,6 @@ _nmtstp_setup_tests(void)
nmtstp_env1_add_test_func_data(testpath, test_func, arg, 2, TRUE)
add_test_func("/route/ip4", test_ip4_route);
add_test_func("/route/ip4_onlink_per_nexthop", test_ip4_route_onlink_per_nexthop);
add_test_func("/route/ip4_rtnh_onlink", test_ip4_rtnh_onlink);
add_test_func("/route/ip6", test_ip6_route);
add_test_func("/route/ip4_metric0", test_ip4_route_metric0);
add_test_func_data("/route/ip4_options/1", test_ip4_route_options, GINT_TO_POINTER(1));

View file

@ -1083,39 +1083,6 @@ _con_get_request_start_validated(NMAuthChain *chain,
_con_get_request_start_proceed(req, req->con.current_has_modify);
}
static gboolean
_req_has_existing_secrets(Request *req)
{
GVariantIter iter;
const char *setting_name;
GVariant *setting_dict;
gboolean has;
if (!req->con.get.existing_secrets)
return FALSE;
nm_assert(g_variant_is_of_type(req->con.get.existing_secrets, NM_VARIANT_TYPE_CONNECTION));
g_variant_iter_init(&iter, req->con.get.existing_secrets);
while (g_variant_iter_next(&iter, "{&s@a{sv}}", &setting_name, &setting_dict)) {
GVariantIter setting_iter;
GVariant *val;
g_variant_iter_init(&setting_iter, setting_dict);
while (g_variant_iter_next(&setting_iter, "{&sv}", NULL, &val)) {
has = !g_variant_is_container(val) || g_variant_n_children(val) > 0;
g_variant_unref(val);
if (has) {
g_variant_unref(setting_dict);
return TRUE;
}
}
g_variant_unref(setting_dict);
}
return FALSE;
}
static void
_con_get_request_start(Request *req)
{
@ -1136,7 +1103,7 @@ _con_get_request_start(Request *req)
* unprivileged users.
*/
if ((req->con.get.flags != NM_SECRET_AGENT_GET_SECRETS_FLAG_NONE)
&& (_req_has_existing_secrets(req)
&& (req->con.get.existing_secrets
|| _nm_connection_aggregate(req->con.connection,
NM_CONNECTION_AGGREGATE_ANY_SYSTEM_SECRET_FLAGS,
NULL))) {

View file

@ -781,8 +781,7 @@ validate_secret_flags(NMConnection *connection, GVariant *secrets, ForEachSecret
static gboolean
secret_is_system_owned(NMSettingSecretFlags flags, gpointer user_data)
{
return !NM_FLAGS_ANY(flags,
NM_SETTING_SECRET_FLAG_AGENT_OWNED | NM_SETTING_SECRET_FLAG_NOT_SAVED);
return !NM_FLAGS_HAS(flags, NM_SETTING_SECRET_FLAG_AGENT_OWNED);
}
static void

View file

@ -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;
const char *p;
char *p;
g_return_val_if_fail(ifcfg_path != NULL, NULL);
g_return_val_if_fail(file_path != NULL, NULL);
@ -4401,7 +4401,7 @@ make_wireless_setting(shvarFile *ifcfg, GError **error)
NMSettingWireless *s_wireless;
const char *cvalue;
char *value = NULL;
guint64 chan = 0;
gint64 chan = 0;
NMSettingMacRandomization mac_randomization;
NMSettingWirelessPowersave powersave = NM_SETTING_WIRELESS_POWERSAVE_DEFAULT;
NMTernary ternary;
@ -4502,7 +4502,7 @@ make_wireless_setting(shvarFile *ifcfg, GError **error)
value = svGetValueStr_cp(ifcfg, "CHANNEL");
if (value) {
chan = _nm_utils_ascii_str_to_int64(value, 10, 1, _NM_WIFI_CHANNEL_MAX, 0);
chan = _nm_utils_ascii_str_to_int64(value, 10, 1, 196, 0);
if (chan == 0) {
g_set_error(error,
NM_SETTINGS_ERROR,
@ -4518,18 +4518,8 @@ make_wireless_setting(shvarFile *ifcfg, GError **error)
value = svGetValueStr_cp(ifcfg, "BAND");
if (value) {
if (!NM_IN_STRSET(value, "a", "bg", "6GHz")) {
g_set_error(error,
NM_SETTINGS_ERROR,
NM_SETTINGS_ERROR_INVALID_CONNECTION,
"Band '%s' invalid",
value);
g_free(value);
goto error;
}
if (chan) {
if (!nm_utils_wifi_is_channel_valid(chan, value)) {
if (!strcmp(value, "a")) {
if (chan && chan <= 14) {
g_set_error(error,
NM_SETTINGS_ERROR,
NM_SETTINGS_ERROR_INVALID_CONNECTION,
@ -4539,26 +4529,33 @@ make_wireless_setting(shvarFile *ifcfg, GError **error)
g_free(value);
goto error;
}
}
g_object_set(s_wireless, NM_SETTING_WIRELESS_BAND, value, NULL);
g_free(value);
} else if (chan > 0) {
if (chan > _NM_WIFI_CHANNEL_MAX_5GHZ) {
} else if (!strcmp(value, "bg")) {
if (chan && chan > 14) {
g_set_error(error,
NM_SETTINGS_ERROR,
NM_SETTINGS_ERROR_INVALID_CONNECTION,
"Band '%s' invalid for channel %u",
value,
(guint32) chan);
g_free(value);
goto error;
}
} else {
g_set_error(error,
NM_SETTINGS_ERROR,
NM_SETTINGS_ERROR_INVALID_CONNECTION,
"Setting channel without band is ambiguous and deprecated. Not supported "
"for 6GHz.");
"Invalid wireless band '%s'",
value);
g_free(value);
goto error;
} else if (chan > _NM_WIFI_CHANNEL_MAX_2GHZ) {
PARSE_WARNING(
"Setting channel without band is ambiguous and deprecated. Assuming band 'a'.");
g_object_set(s_wireless, NM_SETTING_WIRELESS_BAND, "a", NULL);
} else {
g_object_set(s_wireless, NM_SETTING_WIRELESS_BAND, "bg", NULL);
}
g_object_set(s_wireless, NM_SETTING_WIRELESS_BAND, value, NULL);
g_free(value);
} else if (chan > 0) {
if (chan > 14)
g_object_set(s_wireless, NM_SETTING_WIRELESS_BAND, "a", NULL);
else
g_object_set(s_wireless, NM_SETTING_WIRELESS_BAND, "bg", NULL);
}
value = svGetValueStr_cp(ifcfg, "MTU");

View file

@ -849,7 +849,7 @@ write_wireless_setting(NMConnection *connection,
GBytes *ssid;
const guint8 *ssid_data;
gsize ssid_len;
const char *mode, *bssid, *band;
const char *mode, *bssid;
const char *device_mac, *cloned_mac;
guint32 mtu, chan, i;
gboolean adhoc = FALSE, hex_ssid = FALSE;
@ -968,11 +968,9 @@ write_wireless_setting(NMConnection *connection,
chan = nm_setting_wireless_get_channel(s_wireless);
if (chan) {
svSetValueInt64(ifcfg, "CHANNEL", chan);
}
band = nm_setting_wireless_get_band(s_wireless);
if (band) {
svSetValueStr(ifcfg, "BAND", band);
} else {
/* Band only set if channel is not, since channel implies band */
svSetValueStr(ifcfg, "BAND", nm_setting_wireless_get_band(s_wireless));
}
bssid = nm_setting_wireless_get_bssid(s_wireless);
@ -3600,7 +3598,6 @@ do_write_construct(NMConnection *connection,
} else
route_ignore = FALSE;
/* Unsupported properties */
if ((s_ip4 = nm_connection_get_setting_ip4_config(connection))) {
if (nm_setting_ip_config_get_dhcp_dscp(s_ip4)) {
set_error_unsupported(error,
@ -3619,14 +3616,6 @@ do_write_construct(NMConnection *connection,
FALSE);
return FALSE;
}
if (nm_setting_ip4_config_get_clat(NM_SETTING_IP4_CONFIG(s_ip4))
!= NM_SETTING_IP4_CONFIG_CLAT_DEFAULT) {
set_error_unsupported(error,
connection,
NM_SETTING_IP4_CONFIG_SETTING_NAME "." NM_SETTING_IP4_CONFIG_CLAT,
FALSE);
return FALSE;
}
}
write_ip4_setting(connection,

View file

@ -1,7 +1,6 @@
ESSID=MySSID
MODE=Ap
CHANNEL=52
BAND=a
CHANNEL=196
MAC_ADDRESS_RANDOMIZATION=default
AP_ISOLATION=yes
TYPE=Wireless

View file

@ -1,18 +0,0 @@
ESSID="Test SSID"
MODE=Managed
BAND=6GHz
MAC_ADDRESS_RANDOMIZATION=default
TYPE=Wireless
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=dhcp
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=default
NAME="Test Write Wi-Fi Band 6GHz"
UUID=${UUID}
ONBOOT=yes

View file

@ -13,6 +13,6 @@ IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=default
NAME="Test Write Wi-Fi Band A - 5GHz"
NAME="Test Write Wi-Fi Band A"
UUID=${UUID}
ONBOOT=yes

View file

@ -1,13 +0,0 @@
TYPE=Wireless
DEVICE=eth2
HWADDR=00:16:41:11:22:33
NM_CONTROLLED=yes
BOOTPROTO=dhcp
ESSID=blahblah
BAND=6GHz
MODE=Managed
RATE=auto
ONBOOT=yes
USERCTL=yes
PEERDNS=yes
IPV6INIT=no

View file

@ -1,9 +0,0 @@
TYPE=Wireless
DEVICE=eth2
HWADDR=00:16:41:11:22:33
BOOTPROTO=dhcp
ESSID=blahblah
CHANNEL=14
BAND=6GHz
MODE=Managed

View file

@ -3991,7 +3991,7 @@ test_write_wifi_band_a(void)
s_con = _nm_connection_new_setting(connection, NM_TYPE_SETTING_CONNECTION);
g_object_set(s_con,
NM_SETTING_CONNECTION_ID,
"Test Write Wi-Fi Band A - 5GHz",
"Test Write Wi-Fi Band A",
NM_SETTING_CONNECTION_UUID,
nm_uuid_generate_random_str_a(),
NM_SETTING_CONNECTION_TYPE,
@ -4012,7 +4012,7 @@ test_write_wifi_band_a(void)
_writer_new_connec_exp(connection,
TEST_SCRATCH_DIR,
TEST_IFCFG_DIR "/ifcfg-Test_Write_WiFi_Band_a.cexpected",
TEST_IFCFG_DIR "/ifcfg-Test_Write_WiFi_Band_A.cexpected",
&testfile);
f = _svOpenFile(testfile);
@ -4024,77 +4024,6 @@ test_write_wifi_band_a(void)
nmtst_assert_connection_equals(connection, TRUE, reread, FALSE);
}
static void
test_read_wifi_band_6ghz(void)
{
gs_unref_object NMConnection *connection = NULL;
NMSettingConnection *s_con;
NMSettingWireless *s_wifi;
connection = _connection_from_file(TEST_IFCFG_DIR "/ifcfg-test-wifi-band-6ghz",
NULL,
TYPE_WIRELESS,
NULL);
s_con = nmtst_connection_assert_setting(connection, NM_TYPE_SETTING_CONNECTION);
g_assert_cmpstr(nm_setting_connection_get_connection_type(s_con),
==,
NM_SETTING_WIRELESS_SETTING_NAME);
s_wifi = nmtst_connection_assert_setting(connection, NM_TYPE_SETTING_WIRELESS);
g_assert_cmpstr(nm_setting_wireless_get_band(s_wifi), ==, "6GHz");
}
static void
test_write_wifi_band_6ghz(void)
{
nmtst_auto_unlinkfile char *testfile = NULL;
gs_unref_object NMConnection *connection = NULL;
gs_unref_object NMConnection *reread = NULL;
NMSettingConnection *s_con;
NMSettingWireless *s_wifi;
shvarFile *f;
gs_unref_bytes GBytes *ssid =
nmtst_gbytes_from_arr(0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x53, 0x49, 0x44);
connection = nm_simple_connection_new();
s_con = _nm_connection_new_setting(connection, NM_TYPE_SETTING_CONNECTION);
g_object_set(s_con,
NM_SETTING_CONNECTION_ID,
"Test Write Wi-Fi Band 6GHz",
NM_SETTING_CONNECTION_UUID,
nm_uuid_generate_random_str_a(),
NM_SETTING_CONNECTION_TYPE,
NM_SETTING_WIRELESS_SETTING_NAME,
NULL);
s_wifi = _nm_connection_new_setting(connection, NM_TYPE_SETTING_WIRELESS);
g_object_set(s_wifi,
NM_SETTING_WIRELESS_SSID,
ssid,
NM_SETTING_WIRELESS_MODE,
"infrastructure",
NM_SETTING_WIRELESS_BAND,
"6GHz",
NULL);
nmtst_assert_connection_verifies(connection);
_writer_new_connec_exp(connection,
TEST_SCRATCH_DIR,
TEST_IFCFG_DIR "/ifcfg-Test_Write_WiFi_Band_6ghz.cexpected",
&testfile);
f = _svOpenFile(testfile);
_svGetValue_check(f, "BAND", "6GHz");
svCloseFile(f);
reread = _connection_from_file(testfile, NULL, TYPE_WIRELESS, NULL);
nmtst_assert_connection_equals(connection, TRUE, reread, FALSE);
}
static void
test_write_wifi_ap_mode(void)
{
@ -4126,7 +4055,7 @@ test_write_wifi_ap_mode(void)
NM_SETTING_WIRELESS_BAND,
"a",
NM_SETTING_WIRELESS_CHANNEL,
(guint) 52,
(guint) 196,
NM_SETTING_WIRELESS_AP_ISOLATION,
NM_TERNARY_TRUE,
NULL);
@ -4143,18 +4072,6 @@ test_write_wifi_ap_mode(void)
nmtst_assert_connection_equals(connection, TRUE, reread, FALSE);
}
static void
test_read_wifi_band_6ghz_channel_mismatch(void)
{
gs_free_error GError *error = NULL;
_connection_from_file_fail(TEST_IFCFG_DIR "/ifcfg-test-wifi-band-6ghz-channel-mismatch",
NULL,
TYPE_WIRELESS,
&error);
g_assert_error(error, NM_SETTINGS_ERROR, NM_SETTINGS_ERROR_INVALID_CONNECTION);
}
static void
test_read_wifi_band_a_channel_mismatch(void)
{
@ -10763,9 +10680,6 @@ main(int argc, char **argv)
test_read_wifi_band_a_channel_mismatch);
g_test_add_func(TPATH "wifi/read-band-bg-channel-mismatch",
test_read_wifi_band_bg_channel_mismatch);
g_test_add_func(TPATH "wifi/read-band-6ghz", test_read_wifi_band_6ghz);
g_test_add_func(TPATH "wifi/read-band-6ghz-channel-mismatch",
test_read_wifi_band_6ghz_channel_mismatch);
g_test_add_func(TPATH "wifi/read-hidden", test_read_wifi_hidden);
nmtst_add_test_func(TPATH "wifi/read-mac-random-always",
@ -10938,7 +10852,6 @@ main(int argc, char **argv)
test_write_wifi_wpa_then_wep_with_perms);
g_test_add_func(TPATH "wifi/write-hidden", test_write_wifi_hidden);
g_test_add_func(TPATH "wifi/write-band-a", test_write_wifi_band_a);
g_test_add_func(TPATH "wifi/write-band-6ghz", test_write_wifi_band_6ghz);
g_test_add_func(TPATH "wifi/write-ap-mode", test_write_wifi_ap_mode);
g_test_add_func(TPATH "s390/read-qeth-static", test_read_wired_qeth_static);

View file

@ -373,24 +373,14 @@ nm_supplicant_config_get_blobs(NMSupplicantConfig *self)
}
static const char *
wifi_freqs_to_string(const char *band)
wifi_freqs_to_string(gboolean bg_band)
{
static const char *str_2ghz = NULL;
static const char *str_5ghz = NULL;
static const char *str_6ghz = NULL;
const char **f_p;
const char *f;
if (nm_streq0(band, "a"))
f_p = &str_5ghz;
else if (nm_streq0(band, "bg"))
f_p = &str_2ghz;
else if (nm_streq0(band, "6GHz"))
f_p = &str_6ghz;
else {
nm_assert_not_reached();
return NULL;
}
f_p = bg_band ? &str_2ghz : &str_5ghz;
again:
f = g_atomic_pointer_get(f_p);
@ -400,13 +390,7 @@ again:
const guint *freqs;
int i;
if (f_p == &str_2ghz)
freqs = nm_utils_wifi_2ghz_freqs();
else if (f_p == &str_5ghz)
freqs = nm_utils_wifi_5ghz_freqs();
else
freqs = nm_utils_wifi_6ghz_freqs();
freqs = bg_band ? nm_utils_wifi_2ghz_freqs() : nm_utils_wifi_5ghz_freqs();
for (i = 0; freqs[i]; i++) {
if (i > 0)
nm_str_buf_append_c(&strbuf, ' ');
@ -549,47 +533,38 @@ get_ap_params(guint freq,
guint channel;
guint center_channel = 0;
if (freq < 5000) {
/* the setting is not valid */
nm_assert_not_reached();
return;
}
/* Determine the center channel according to the table at
* https://en.wikipedia.org/wiki/List_of_WLAN_channels */
if (freq > 5950) {
/* 6 GHz */
channel = (freq - 5950) / 5;
channel = ((channel - 1) / 16) * 16 + 7;
channel = (freq - 5000) / 5;
if (channel >= 36 && channel <= 48)
center_channel = 42;
else if (channel >= 52 && channel <= 64)
center_channel = 58;
else if (channel >= 100 && channel <= 112)
center_channel = 106;
else if (channel >= 116 && channel <= 128)
center_channel = 122;
else if (channel >= 132 && channel <= 144)
center_channel = 138;
else if (channel >= 149 && channel <= 161)
center_channel = 155;
else if (channel >= 165 && channel <= 177)
center_channel = 171;
if (center_channel) {
*out_ht40 = 1;
*out_max_oper_chwidth = 1;
*out_center_freq = 5950 + 5 * channel;
} else {
/* 5 GHz */
if (freq < 5000) {
/* the setting is not valid */
nm_assert_not_reached();
return;
}
channel = (freq - 5000) / 5;
if (channel >= 36 && channel <= 48)
center_channel = 42;
else if (channel >= 52 && channel <= 64)
center_channel = 58;
else if (channel >= 100 && channel <= 112)
center_channel = 106;
else if (channel >= 116 && channel <= 128)
center_channel = 122;
else if (channel >= 132 && channel <= 144)
center_channel = 138;
else if (channel >= 149 && channel <= 161)
center_channel = 155;
else if (channel >= 165 && channel <= 177)
center_channel = 171;
if (center_channel) {
*out_ht40 = 1;
*out_max_oper_chwidth = 1;
*out_center_freq = 5000 + 5 * center_channel;
}
*out_center_freq = 5000 + 5 * center_channel;
}
return;
}
@ -736,7 +711,10 @@ nm_supplicant_config_add_setting_wireless(NMSupplicantConfig *self,
} else {
const char *freqs = NULL;
freqs = wifi_freqs_to_string(band);
if (nm_streq(band, "a"))
freqs = wifi_freqs_to_string(FALSE);
else if (nm_streq(band, "bg"))
freqs = wifi_freqs_to_string(TRUE);
if (freqs
&& !nm_supplicant_config_add_option(self,

View file

@ -67,7 +67,6 @@ enum {
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
};
@ -3238,11 +3237,6 @@ _signal_handle(NMSupplicantInterface *self,
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;
}
@ -3885,13 +3879,4 @@ nm_supplicant_interface_class_init(NMSupplicantInterfaceClass *klass)
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);
}

View file

@ -87,7 +87,6 @@ typedef enum {
#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;

View file

@ -6,7 +6,6 @@
#include "src/core/nm-default-daemon.h"
#include "nm-supplicant-settings-verify.h"
#include "libnm-core-aux-intern/nm-libnm-core-utils.h"
#include <stdio.h>
#include <stdlib.h>
@ -72,7 +71,7 @@ static const struct Opt opt_table[] = {
OPT_BYTES("engine_id", 0),
OPT_INT("fragment_size", 1, 2000),
OPT_KEYWORD("freq_list", NULL),
OPT_INT("frequency", _NM_WIFI_FREQ_MIN, _NM_WIFI_FREQ_MAX),
OPT_INT("frequency", 2412, 5825),
OPT_KEYWORD("group", NM_MAKE_STRV("CCMP", "TKIP", "WEP104", "WEP40", "GCMP-256", )),
OPT_INT("ht40", 0, 1),
OPT_BYTES("identity", 0),
@ -213,19 +212,18 @@ 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_in, const guint32 len)
validate_type_keyword(const struct Opt *opt, const char *value, const guint32 len)
{
gs_free char *value_free = NULL;
char *value;
nm_assert(opt);
nm_assert(value_in);
nm_assert(value);
/* Allow everything */
if (!opt->str_allowed)
return TRUE;
value = nm_strndup_a(300, value_in, len, &value_free);
value = nm_strndup_a(300, value, len, &value_free);
/* validate each space-separated word in 'value' */

View file

@ -311,108 +311,6 @@ test_config_override(void)
g_assert_cmpstr(plugins[3], ==, "delta");
}
static void
test_config_managed(void)
{
NMConfig *config;
const char *CONFIG_USER = BUILD_DIR "/test-config-managed.conf";
const char *CONFIG_INTERN = BUILD_DIR "/test-config-managed-intern.conf";
NMDevice *dev;
gs_free char *group_by_name = NULL;
const char *ifname, *group_by_mac;
NMTernary managed;
gboolean by_mac;
GKeyFile *kf = nm_config_create_keyfile();
dev = nm_test_device_new("11:11:11:11:11:11");
ifname = nm_device_get_iface(dev);
group_by_name =
g_strdup_printf(NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN_DEVICE "-manage-%s", ifname);
group_by_mac = NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN_DEVICE "-manage-11-11-11-11-11-11";
g_assert(g_file_set_contents(CONFIG_USER, "", 0, NULL));
g_assert(g_file_set_contents(CONFIG_INTERN, "", 0, NULL));
config = setup_config(NULL, CONFIG_USER, CONFIG_INTERN, NULL, "/no/such/dir", "", NULL);
g_assert(nm_config_get_device_managed(config, dev, &managed, NULL, NULL));
g_assert_cmpint(managed, ==, NM_TERNARY_DEFAULT);
/* Matching by name */
NMTST_EXPECT_NM_INFO("config: signal: *");
g_assert(nm_config_set_device_managed(config, dev, NM_TERNARY_TRUE, FALSE, NULL));
g_assert(nm_config_get_device_managed(config, dev, &managed, &by_mac, NULL));
g_assert_cmpint(managed, ==, NM_TERNARY_TRUE);
g_assert_false(by_mac);
g_key_file_load_from_file(kf, CONFIG_INTERN, G_KEY_FILE_NONE, NULL);
g_assert_false(g_key_file_has_key(kf, group_by_mac, "managed", NULL));
g_assert_true(g_key_file_has_key(kf, group_by_name, "managed", NULL));
g_assert_cmpint(g_key_file_get_integer(kf, group_by_name, "managed", NULL), ==, 1);
NMTST_EXPECT_NM_INFO("config: signal: *");
g_assert(nm_config_set_device_managed(config, dev, NM_TERNARY_FALSE, FALSE, NULL));
g_assert(nm_config_get_device_managed(config, dev, &managed, &by_mac, NULL));
g_assert_cmpint(managed, ==, NM_TERNARY_FALSE);
g_assert_false(by_mac);
g_key_file_load_from_file(kf, CONFIG_INTERN, G_KEY_FILE_NONE, NULL);
g_assert_false(g_key_file_has_key(kf, group_by_mac, "managed", NULL));
g_assert_true(g_key_file_has_key(kf, group_by_name, "managed", NULL));
g_assert_cmpint(g_key_file_get_integer(kf, group_by_name, "managed", NULL), ==, 0);
/* Matching by MAC address */
NMTST_EXPECT_NM_INFO("config: signal: *");
g_assert(nm_config_set_device_managed(config, dev, NM_TERNARY_TRUE, TRUE, NULL));
g_assert(nm_config_get_device_managed(config, dev, &managed, &by_mac, NULL));
g_assert_cmpint(managed, ==, NM_TERNARY_TRUE);
g_assert_true(by_mac);
g_key_file_load_from_file(kf, CONFIG_INTERN, G_KEY_FILE_NONE, NULL);
g_assert_false(g_key_file_has_key(kf, group_by_name, "managed", NULL));
g_assert_true(g_key_file_has_key(kf, group_by_mac, "managed", NULL));
g_assert_cmpint(g_key_file_get_integer(kf, group_by_mac, "managed", NULL), ==, 1);
NMTST_EXPECT_NM_INFO("config: signal: *");
g_assert(nm_config_set_device_managed(config, dev, NM_TERNARY_FALSE, TRUE, NULL));
g_assert(nm_config_get_device_managed(config, dev, &managed, &by_mac, NULL));
g_assert_cmpint(managed, ==, NM_TERNARY_FALSE);
g_assert_true(by_mac);
g_key_file_load_from_file(kf, CONFIG_INTERN, G_KEY_FILE_NONE, NULL);
g_assert_false(g_key_file_has_key(kf, group_by_name, "managed", NULL));
g_assert_true(g_key_file_has_key(kf, group_by_mac, "managed", NULL));
g_assert_cmpint(g_key_file_get_integer(kf, group_by_mac, "managed", NULL), ==, 0);
/* Resetting the managed state */
NMTST_EXPECT_NM_INFO("config: signal: *");
g_assert(nm_config_set_device_managed(config, dev, NM_TERNARY_DEFAULT, FALSE, NULL));
g_assert(nm_config_get_device_managed(config, dev, &managed, NULL, NULL));
g_assert_cmpint(managed, ==, NM_TERNARY_DEFAULT);
g_key_file_load_from_file(kf, CONFIG_INTERN, G_KEY_FILE_NONE, NULL);
g_assert_false(g_key_file_has_key(kf, group_by_name, "managed", NULL));
g_assert_false(g_key_file_has_key(kf, group_by_mac, "managed", NULL));
g_object_unref(config);
/* Both values set in the intern config file, different values */
g_key_file_set_string(kf, group_by_name, "managed", "1");
g_key_file_set_string(kf, group_by_mac, "managed", "0");
g_assert(g_key_file_save_to_file(kf, CONFIG_INTERN, NULL));
config = setup_config(NULL, CONFIG_USER, CONFIG_INTERN, NULL, "/no/such/dir", "", NULL);
g_assert(!nm_config_get_device_managed(config, dev, &managed, NULL, NULL));
g_object_unref(config);
/* Both values set in the intern config file, same values */
g_key_file_set_string(kf, group_by_name, "managed", "1");
g_key_file_set_string(kf, group_by_mac, "managed", "1");
g_assert(g_key_file_save_to_file(kf, CONFIG_INTERN, NULL));
config = setup_config(NULL, CONFIG_USER, CONFIG_INTERN, NULL, "/no/such/dir", "", NULL);
g_assert(nm_config_get_device_managed(config, dev, &managed, NULL, NULL));
g_assert_cmpint(managed, ==, NM_TERNARY_TRUE);
g_key_file_unref(kf);
g_object_unref(dev);
g_object_unref(config);
}
static void
test_config_global_dns(void)
{
@ -1514,7 +1412,6 @@ main(int argc, char **argv)
g_test_add_func("/config/set-values", test_config_set_values);
g_test_add_func("/config/global-dns", test_config_global_dns);
g_test_add_func("/config/managed", test_config_managed);
g_test_add_func("/config/connectivity-check", test_config_connectivity_check);
g_test_add_func("/config/signal", test_config_signal);

View file

@ -7,7 +7,6 @@
#include <net/if.h>
#include <byteswap.h>
#include <netinet/ip6.h>
/* need math.h for isinf() and INFINITY. No need to link with -lm */
#include <math.h>
@ -2771,56 +2770,6 @@ test_nm_firewall_nft_stdio_mlag(void)
"nm-mlag-bond0\012delete table netdev nm-mlag-bond0\012");
}
static void
test_icmp6_checksum(void)
{
struct ip6_hdr ip6h = {};
guint8 *data;
guint16 c;
ip6h.ip6_src = NM_IN6ADDR_INIT(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
ip6h.ip6_dst = NM_IN6ADDR_INIT(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
data = (guint8[]) {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
c = nm_utils_icmp6_checksum(&ip6h.ip6_src, 12, data);
g_assert_cmpint(c, ==, htons(0xffb9));
ip6h.ip6_src = NM_IN6ADDR_INIT(0xfe,
0x80,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0xc0,
0x60,
0x8c,
0xaf,
0xf6,
0x9b,
0xe4,
0x1a);
ip6h.ip6_dst = NM_IN6ADDR_INIT(0x20,
0x02,
0xaa,
0xaa,
0x00,
0x00,
0x00,
0x00,
0x64,
0xd4,
0x29,
0x32,
0x35,
0x85,
0x7c,
0x89);
data = (guint8[]) {0xdc, 0x74, 0x1a, 0xcc, 0xd3, 0x8e, 0xca, 0x34};
c = nm_utils_icmp6_checksum(&ip6h.ip6_src, 8, data);
g_assert_cmpint(c, ==, htons(0x39af));
}
/*****************************************************************************/
NMTST_DEFINE();
@ -2899,7 +2848,5 @@ main(int argc, char **argv)
g_test_add_func("/core/test_nm_firewall_nft_stdio_mlag", test_nm_firewall_nft_stdio_mlag);
g_test_add_func("/core/general/test_icmp6_checksum", test_icmp6_checksum);
return g_test_run();
}

View file

@ -53,44 +53,6 @@ test_ip_reservation_shared4(void)
}
}
static void
test_ip_reservation_clat(void)
{
gs_unref_object NMPlatform *platform = NULL;
gs_unref_object NMNetns *netns = NULL;
NMNetnsIPReservation *res[8];
NMNetnsIPReservation *res1;
char buf[NM_INET_ADDRSTRLEN];
guint i;
platform = g_object_ref(NM_PLATFORM_GET);
netns = nm_netns_new(platform);
/* Allocate addresses 192.0.0.{5,6,7,0,1,2,3,4} */
for (i = 0; i < 8; i++) {
res[i] = nm_netns_ip_reservation_get(netns, NM_NETNS_IP_RESERVATION_TYPE_CLAT);
g_snprintf(buf, sizeof(buf), "192.0.0.%u", (i + 5) % 8);
nmtst_assert_ip4_address(res[i]->addr, buf);
g_assert_cmpint(res[i]->_ref_count, ==, 1);
}
/* Release an address and get it back */
nm_netns_ip_reservation_release(res[2]);
res[2] = nm_netns_ip_reservation_get(netns, NM_NETNS_IP_RESERVATION_TYPE_CLAT);
nmtst_assert_ip4_address(res[2]->addr, "192.0.0.7");
/* No reuse */
NMTST_EXPECT_NM_ERROR("netns[*]: clat: ran out of IP addresses");
res1 = nm_netns_ip_reservation_get(netns, NM_NETNS_IP_RESERVATION_TYPE_CLAT);
g_test_assert_expected_messages();
g_assert_null(res1);
/* Release all */
for (i = 0; i < 8; i++) {
nm_netns_ip_reservation_release(res[i]);
}
}
/*****************************************************************************/
NMTST_DEFINE();
@ -102,7 +64,6 @@ main(int argc, char **argv)
nm_linux_platform_setup();
g_test_add_func("/netns/ip_reservation/shared4", test_ip_reservation_shared4);
g_test_add_func("/netns/ip_reservation/clat", test_ip_reservation_clat);
return g_test_run();
}

View file

@ -2135,20 +2135,16 @@ _dbus_signal_ip_config_cb(NMVpnConnection *self, int addr_family, GVariant *dict
IS_IPv4 ? NM_VPN_PLUGIN_IP4_CONFIG_DOMAIN
: NM_VPN_PLUGIN_IP6_CONFIG_DOMAIN,
"&s",
&v_str)) {
&v_str))
nm_l3_config_data_add_domain(l3cd, addr_family, v_str);
nm_l3_config_data_add_search(l3cd, addr_family, v_str);
}
if (g_variant_lookup(dict,
IS_IPv4 ? NM_VPN_PLUGIN_IP4_CONFIG_DOMAINS
: NM_VPN_PLUGIN_IP6_CONFIG_DOMAINS,
"as",
&var_iter)) {
while (g_variant_iter_next(var_iter, "&s", &v_str)) {
while (g_variant_iter_next(var_iter, "&s", &v_str))
nm_l3_config_data_add_domain(l3cd, addr_family, v_str);
nm_l3_config_data_add_search(l3cd, addr_family, v_str);
}
g_variant_iter_free(var_iter);
}

View file

@ -60,21 +60,16 @@ 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));
applied = nm_active_connection_get_applied_connection(NM_ACTIVE_CONNECTION(vpn));
nm_assert(device);
nm_assert(applied);
priv = NM_VPN_MANAGER_GET_PRIVATE(manager);
device = nm_active_connection_get_device(NM_ACTIVE_CONNECTION(vpn));
g_assert(device);
if (nm_device_get_state(device) != NM_DEVICE_STATE_ACTIVATED
&& nm_device_get_state(device) != NM_DEVICE_STATE_SECONDARIES) {
g_set_error_literal(error,
@ -106,30 +101,6 @@ 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)) {

View file

@ -345,7 +345,6 @@ typedef enum {
NM_IP_CONFIG_SOURCE_VPN,
NM_IP_CONFIG_SOURCE_DHCP,
NM_IP_CONFIG_SOURCE_NDISC,
NM_IP_CONFIG_SOURCE_CLAT,
NM_IP_CONFIG_SOURCE_USER,
} NMIPConfigSource;

View file

@ -65,7 +65,6 @@
#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"
@ -90,7 +89,4 @@
#define NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN_GLOBAL_DNS_DOMAIN \
NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN NM_CONFIG_KEYFILE_GROUPPREFIX_GLOBAL_DNS_DOMAIN
#define NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN_DEVICE \
NM_CONFIG_KEYFILE_GROUPPREFIX_INTERN NM_CONFIG_KEYFILE_GROUPPREFIX_DEVICE
#endif /* __NM_CONFIG_BASE_H__ */

Some files were not shown because too many files have changed in this diff Show more