Commit graph

34432 commits

Author SHA1 Message Date
Beniamino Galvani
a4e30ee849 clat: print translation statistics during deactivation
Print some statistics about the translation when the connection goes
down:

  clat: stats: egress (v4 to v6): tcp 1275, udp 191, icmp 9, other 0, dropped 2; ingress (v6 to v4): tcp 1669, udp 272, icmp 0, other 0, fragment 136, dropped 0

Those counters can be used to better understand what's going wrong in
case of problems; for example, if the packets are being dropped in the
ingress path or in the egress one.
2026-02-06 17:47:33 +01:00
Beniamino Galvani
112190d09a clat: support layer3 interfaces
When running the CLAT over an interface that doesn't use the Ethernet
header, like an IP tunnel, there are some changes needed. The BPF
program must compute offsets differently. Also, the DAD packet should
not include an Ethernet header.
2026-02-06 17:47:30 +01:00
Beniamino Galvani
d7edc806b6 core: clat: add the "nm" prefix to ebpf program names
The program names are displayed in the "bpftool prog" output. It is
easier to recognize NM programs if they have the "nm" prefix.
2026-02-06 10:38:07 +01:00
Beniamino Galvani
f9b2083394 l3cd: rename "clat" to "clat_config"
The member indicates if CLAT is enabled in the configuration. Use a
clearer name.
2026-02-06 10:38:06 +01:00
Beniamino Galvani
e2cdd5c4dc build: don't require libndp >= 1.9 if CLAT is disabled
libndp >= 1.9 is only required to parse the PREF64 option needed for
CLAT. When building NM in an enviroment with an older libndp, still
allow building without CLAT support.
2026-02-06 10:38:05 +01:00
Beniamino Galvani
c86d234516 nmcli: show the CLAT state
It is useful to show that the CLAT is enabled and which addresses and
prefix it is using. Add this information to the overview and to the
device/connection output. Example:

$ nmcli
  veth0: connected to clat
          "veth0"
          ethernet (veth), 4A:37:01:56:9D:AE, sw, mtu 1500
          ip4 default
          inet4 192.0.0.5/32
          route4 default metric 101
          inet6 2002:aaaa::64d4:2932:3585:7c89/64
          inet6 fe80::c060:8caf:f69b:e41a/64
          route6 fe80::/64 metric 1024
          route6 2002:aaaa::/64 metric 101
          route6 default via fe80::871:7ff:fe14:b7b9 metric 101
          clat inet4 192.0.0.5 inet6 2002:aaaa::2c0d:1e71:ef87:fac7 pref64 64:ff9b::/96

$ nmcli connection show clat
   ...
  IP4.ADDRESS[1]:                         192.0.0.5/32
  IP4.GATEWAY:                            0.0.0.0
  IP4.ROUTE[1]:                           dst = 0.0.0.0/0, nh = 0.0.0.0, mt = 101
  IP4.CLAT-ADDRESS:                       192.0.0.5
  IP6.ADDRESS[1]:                         2002:aaaa::64d4:2932:3585:7c89/64
  IP6.ADDRESS[2]:                         fe80::c060:8caf:f69b:e41a/64
  IP6.GATEWAY:                            fe80::871:7ff:fe14:b7b9
  IP6.ROUTE[1]:                           dst = fe80::/64, nh = ::, mt = 1024
  IP6.ROUTE[2]:                           dst = 2002:aaaa::/64, nh = ::, mt = 101
  IP6.ROUTE[3]:                           dst = ::/0, nh = fe80::871:7ff:fe14:b7b9, mt = 101
  IP6.CLAT-ADDRESS:                       2002:aaaa::2c0d:1e71:ef87:fac7
  IP6.CLAT-PREF64:                        64:ff9b::/96

Note how the IPv4 CLAT address is displayed both in IP4.ADDRESS and
IP4.CLAT-ADDRESS. That's because it is also configured in kernel. The
IPv6 CLAT address is not displayed in IP6.ADDRESS because it's not
configured in kernel.
2026-02-06 10:38:04 +01:00
Beniamino Galvani
d1598a10ec libnm: support the CLAT state
Make available the CLAT state in the NMIPConfig libnm objects.
2026-02-06 10:38:03 +01:00
Beniamino Galvani
f00030d79a core: export the CLAT state over D-Bus
Export over D-Bus the CLAT state: the IPv4 and IPv6 CLAT addresses and
the NAT64 prefix.
2026-02-06 10:38:02 +01:00
Beniamino Galvani
72cb5839fc core: l3cd: store the CLAT state
In the l3cd we already stored the CLAT administrative state (whether
we want to enable it or not) and the selected PREF64. Also store the
other current CLAT parameters, so that we can export them to clients
via D-Bus.
2026-02-06 10:38:00 +01:00
Beniamino Galvani
5c041cb891 l3cfg: send DAD solicitation for the IPv6 CLAT address
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.

 5ae193ae36/clatd/main.c (363)
2026-02-06 10:37:59 +01:00
Beniamino Galvani
6d44237ed3 ndisc: track multiple PREF64 options
Previously the NMNDisc instance always used the last received NAT64
prefix. If a network advertises multiple NAT64 prefixes,
NetworkManager would constantly flip between them.  Change this and
keep a list of valid PREF64. Most importantly, stick with the same
PREF64 unless a new one appears from a router with higher priority, or
the current PREF64 expires.
2026-02-06 10:37:58 +01:00
Beniamino Galvani
fbfb5afec0 build: move the CLAT line in the meson summary
Move the CLAT line from the Miscellaneous section to the Features one.
2026-02-06 10:37:58 +01:00
Beniamino Galvani
aeeb52ab66 core: log message if CLAT is enabled but not supported
If CLAT is not supported (disabled at build time) and the
configuration enables it, log a message.
2026-02-06 10:37:57 +01:00
Beniamino Galvani
de42acd3fd core: print whether CLAT support is compiled in
At startup, print whether CLAT support is compiled in; it is useful
when debugging.
2026-02-06 10:37:57 +01:00
Beniamino Galvani
f2ced1e115 l3cfg: split updating CLAT config to a separate function
Split the CLAT code from _l3cfg_update_combined_config() so that the
function can be followed more easily.
2026-02-06 10:37:57 +01:00
Beniamino Galvani
cb09291635 nmcli: fix hiding default values
A property should be hidden when it has the default value and one of the
following conditions is met:

 - nmcli is called in "overview" mode (with flag -o)
 - the property has the HIDE flag

Previously, properties with the HIDE flag were always hidden. Fix
that.
2026-02-06 10:37:56 +01:00
Beniamino Galvani
0aab6ef1c0 merge: branch 'wifi-use-auth-retries'
wifi: respect connection.auth-retry for WPA connections

Closes #1316

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/2308
2026-02-05 10:34:03 +00:00
Jan Fooken
a01000d811
NEWS: WPA connections now respect connection.auth-retry 2026-01-28 15:46:32 +01:00
Jan Fooken
b4fc8550f5
man: wifi: Document connection.auth-retry for WPA connections
Remove the mentioned limitation of limiting authentication retires to
802.1X connections and add information about the introduced secret
prompting behaviour.
2026-01-28 15:46:32 +01:00
Jan Fooken
746a5902ad
wifi: use authentication retry mechanism
While NetworkManager tries it's best to determine whether a new PSK is
needed, it can still run into edge cases.  One of these edge cases is that
a device can leave the range of an access point and therefore fail a 4-way
handshake.  Because these cases can't be confidently detected, a device
which was previously connected, should try to exhaust it's authentication
retries before requesting new secrets.  This leads to less user-facing
prompts while increasing the time from PSK change to prompt.
2026-01-28 15:46:26 +01:00
Jan Fooken
6dc51ddf01
device: add public method nm_device_auth_retries_has_next
Devices don't know whether they have authentication retries left,
so they can only make decisions ad-hoc after calling
nm_device_auth_retries_try_next.

Giving devices a way to determine whether the current attempt is their
last attempt, allows them to make decisions before failing a connection.
2026-01-28 15:42:20 +01:00
Jan Fooken
a3267aaf7b
device: add private getter for property auth-retries 2026-01-28 15:42:20 +01:00
Íñigo Huguet
871da67916 merge: branch 'ih/fix-api-version'
Bump version just after release, fix NM_API_VERSION on stable branches

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/2337
2026-01-26 06:44:38 +00:00
Íñigo Huguet
f849163e82 nm-version: allow to define NM_VERSION_MAX_ALLOWED alone
Previously, if NM_VERSION_MIN_REQUIRED was not defined, it defaulted to
NM_VERSION. As a consequence, if NM_VERSION_MAX_ALLOWED was defined we
got a compilation error because MAX_ALLOWED < MIN_REQUIRED.

MAX_ALLOWED is used to get compilation warnings if you unintentionally
use a libnm's symbol introduced in a newer version. MIN_REQUIRED is used
to get rid of warnings about symbol deprecations.

Libnm users may want to use MAX_ALLOWED alone, because using a too new
symbol would fail to compile with older libnm. But they might want to
get deprecation warnings as soon as possible, so they want to leave
MIN_REQUIRED empty.
2026-01-26 06:44:00 +00:00
Íñigo Huguet
36275bc51c nm-version.h: use the right value of NM_API_VERSION
After the changes in release.sh in previous commits, during development
the value of NM_VERSION will always be the next version, not the latest
released one. As a consequence, we don't need to set MICRO+1 in
NM_API_VERSION, which was a temporary workaround.
2026-01-26 06:44:00 +00:00
Íñigo Huguet
c0fe80ff87 release: (manually) bump version to 1.57.2-dev
After the previous commits, release.sh bumps the version after tagging
the release, and not before. Therefore, it expects that the version is
already the next one when doing the release.

Manually bump the version this time so release.sh sees the right value
the next time it's executed after these changes.
2026-01-26 06:44:00 +00:00
Íñigo Huguet
9a3462af99 release.sh: fix a few small bugs and typos
Fix typo freedestkop -> freedesktop.

Removed unused argument of check_news (additionally, it was incorrectly
using @ instead of $).

Fixed incorrect use of `$? = 0` that was always successful.
2026-01-26 06:44:00 +00:00
Íñigo Huguet
5666407f15 release.sh: bump version after release
After tagging a release, create a commit bumping to the next version.
This effectively ends the change in the logic initiated in the previous
commit, from "bump version, then release" to "release, then bump
version".

The purpose of this is to have the right version set in nm_version.h and
nm_version_macros.h between two releases. Without this change, when we
introduced a new symbol, thus using the NM_AVAILABLE_IN_1_XX annotations,
we got compilation warnings until we did the next release (making the CI
to be red when configured the compilation to fail on warnings).
2026-01-26 06:44:00 +00:00
Íñigo Huguet
3a3a8ea59d release.sh: assume that the version is already the right one
Don't bump the version before tagging the release. Instead, assume that
it's already correctly set. This is in preparation for the next commit
where we will bump the version after the release, not before.

But don't assume that in the case of rc1 and major releases. For rc1 we
switch from devel releases to RC releases, and in major we switch from
RC releases to stable releases. For example, when we are going to
release 1.58-rc1, the current version will be 1.57.X-dev, so we need to
bump to 1.58-rc1. When we're going to release 1.58.0, the current
version will be 1.58-rcX, so we need to bump to 1.58.0.
2026-01-26 06:44:00 +00:00
Íñigo Huguet
d56cd26aea release.sh: add comments 2026-01-26 06:44:00 +00:00
Beniamino Galvani
e311df0c75 merge: branch 'feature/mstrodl/clat'
Add support for CLAT using a BPF program

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/2107
2026-01-24 09:32:53 +00:00
Beniamino Galvani
c32f0fb71f l3cfg: fix the metric of the CLAT default route
Previously the metric of the CLAT default route was set to the IPv6
route metric plus 50. Instead:

 - If there is another non-CLAT default route on the device, use the
   same metric plus 1, so that native connectivity is always
   preferred.

 - Otherwise, use the metric from the "ipv4.route-metric" property of
   the connection profile.
2026-01-24 09:45:01 +01:00
Beniamino Galvani
2c896713b8 bpf: clat: add macros for header sizes
They make the code more compact and readable.
2026-01-24 09:44:59 +01:00
Beniamino Galvani
29eb48d7f9 bpf: clat: ensure data is pulled for direct packet access
There is no guarantee that the part of the packet we want to read or
write via direct packet access is linear. From the documentation of
bpf_skb_pull_data():

  For direct packet access, testing that offsets to access are within
  packet boundaries (test on skb->data_end) is susceptible to fail if
  offsets are invalid, or if the requested data is in non-linear parts
  of the skb. On failure the program can just bail out, or in the case
  of a non-linear buffer, use a helper to make the data available. The
  bpf_skb_load_bytes() helper is a first solution to access the
  data. Another one consists in using bpf_skb_pull_data to pull in
  once the non-linear parts, then retesting and eventually access the
  data.

See: https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/2107#note_3288979

Reported-by: DasSkelett <dasskelett@dasskelett.dev>
2026-01-24 09:44:57 +01:00
Beniamino Galvani
0731d8f3e0 bpf: clat: drop clat_handler()
Avoid the additional function call and perform the needed checks
directly in clat_handle_v4() and clat_handle_v6(). It will make easier
to check that the packet is linear is the next commit.
2026-01-24 09:44:55 +01:00
Beniamino Galvani
2d41711033 bpf: clat: support the IPv6 fragment header
Convert IPv6 fragments into IPv4.

The PLAT fragments IPv4 packets larger than the IPv6 MTU size into
smaller IPv6 packets. The safest IPv6 MTU value to configure on a PLAT
is the minimum IPv6 MTU, 1280. Therefore, we can expect IPv6 fragments
to be quite common.
2026-01-24 09:44:53 +01:00
Beniamino Galvani
616e18e61b l3cfg: fix CLAT MTU handling
The current code takes the IPv6 MTU value from the IPv6 default
route. However, that value is always zero because NM doesn't set it
usually. Instead, it should use the IPv6 MTU sysctl value. The problem
is that at this point NM hasn't written the sysctl yet, and we need
some logic to find the actual value.

Reported-by: DasSkelett <dasskelett@dasskelett.dev>
2026-01-24 09:44:50 +01:00
Beniamino Galvani
5cbd79a9ba core: introduce separate ipv6 mtu values in l3cd
The current "ip6_mtu" field of a l3cd is the IPv6 MTU received via
RA. Rename it accordingly and introduce another "ip6_mtu_static" field
that contains the value set in the ipv6.mtu connection property. It's
not used yet, but it will be in a following commit.
2026-01-24 09:44:48 +01:00
Beniamino Galvani
3699558106 bpf: clat: use IPv4 dummy address for ICMPv6 messages with native source
When running a traceroute for an IPv4 address, the nodes before the
NAT64 gateway return ICMPv6 Time Exceeded messages with a source IPv6
address not belonging to the NAT64 prefix. Such messages would be
normally dropped by the CLAT because the source address can't be
translated. This behavior complicates troubleshooting.

Follow the recommendation of
draft-ietf-v6ops-icmpext-xlat-v6only-source-01 and translate the
source address to the dummy IPv4 192.0.0.8.
2026-01-24 09:44:46 +01:00
Beniamino Galvani
2888d4c800 bpf: clat: fix redirect for outgoing packets
bpf_redirect_neigh() looks up the next hop in the routing table and
then redirects the packet to the given ifindex. The problem is that
the routing table might contain a default route with lower metric on a
different device; in that case the FIB lookup returns a next hop on
the other device, and the packet can't be delivered.

Use bpf_redirect() instead; the IPv4 already has the right L2
destination because the IPv4 default route points to the IPv6 gateway.

Reported-by: DasSkelett <dasskelett@dasskelett.dev>
2026-01-24 09:44:44 +01:00
Beniamino Galvani
6ac6d4f14e rpm: disable CLAT on i686
There is no bpftool compiled for i686.
2026-01-24 09:44:43 +01:00
Beniamino Galvani
6ec321d21b l3cfg: use the tcx attachment for the clat program
The TCX attachment type was added in kernel 6.6 (October 2023) and it
replaces the Traffic Control (TC) BPF attachment, providing better
usability. Convert the l3cfg code to use it.
2026-01-24 09:44:41 +01:00
Beniamino Galvani
bd67cefaaa ipv4: improve logging for ipv4.dhcp-ipv6-only-preferred 2026-01-24 09:44:40 +01:00
Beniamino Galvani
13cf12dd6e ipv4: enable by default ipv4.dhcp-ipv6-only-preferred when CLAT is on
When CLAT is enabled, we want to also enable and honor by default DHCP
option 108 (IPv6-only preferred), so that the host can avoid
requesting an IPv4 address and go IPv6-only.
2026-01-24 09:44:38 +01:00
Beniamino Galvani
193e37b410 bpf: clat: improve debug messages 2026-01-24 09:44:37 +01:00
Beniamino Galvani
c93ce65467 bpf: clat: translate inner headers of incoming ICMPv6 errors
ICMPv6 error messages contain a copy of the original packet that
caused the error. In a 464XLAT deployment, this inner packet is an
IPv6 packet (as translated by the PLAT), while the local host expects
to see the original IPv4 packet it generated.

Without translation, the local host can't match the error to an active
socket. This breaks functionality like Path MTU Discovery (PMTUD),
traceroute, and error reporting for connected UDP sockets.

This commit implements the translation of the inner headers from IPv6
to IPv4 for incoming ICMPv6 errors.

Some implementation notes:

 - this only handles incoming ICMPv6; outgoing ICMPv4 is not yet
   implemented, but it seems less important.

 - the program uses different functions for rewriting the outer and
   inner header. I tried using recursion but the verifier didn't seem
   to like it.

 - after rewriting the inner headers, the ICMP checksum is
   incrementally updated based on difference of all the individual
   modifications done to the inner headers. This has the advantage
   that all the operations are fixed-size. But probably it would be
   easier and faster to just calculate the checksum from scratch.
2026-01-24 09:44:36 +01:00
Beniamino Galvani
6f29305575 clat: support all pref64 lengths
Support all the prefix lengths defined in RFC 6052.
2026-01-24 09:42:36 +01:00
Beniamino Galvani
8414afd9ae clat: pass the configuration as a BPF global variable
The program only needs to know the local IPv4 address, the local IPv6
address and the PREF64. There is no need to create multiple maps for
that, just pass a global configuration struct containing those 3
fields.
2026-01-24 09:42:35 +01:00
Beniamino Galvani
8c83367a49 bpf: clat: improve the code style and consistency
Improve the code style and consistency of some functions:

- declare only one variable per line
- add "const" keyword to read-only function arguments
- remove unneeded function arguments
- rename variables holding headers on the stack with the "_buf"
  suffix
2026-01-24 09:42:34 +01:00
Beniamino Galvani
183d68dcbe bpf: clat: rework to avoid pointer arithmetic
Avoid using pointer arithmetic in the BPF program, so that it requires
only CAP_BPF and not CAP_PERFMON. In this context "pointer arithmetic"
means adding a variable value to a packet pointer. This means that the
program no longer tries to parse variable-size headers (IPv4 options,
IPv6 extension headers). Those were already not supported before. It
also doesn't parse VLAN tags, but there should be no need for that. If
we use fixed offset, we can avoid using the parsing helpers from
libxdp.
2026-01-24 09:42:33 +01:00