Commit e59c4189f3 for strongswan.org
commit e59c4189f31903e779595df7b34daec6b2a02a54
Author: Tobias Brunner <tobias@strongswan.org>
Date: Thu Sep 17 11:22:01 2026 +0200
kernel-net: Always return global addresses on loopback interfaces
This changes the interface filters in all kernel backends so that global
addresses on loopback interfaces are enumerated. Because Linux and
FreeBSD default to a weak host model, addresses on any interface are
usable. So it's common to install addresses on stable interfaces (e.g.
`lo`) on systems where interfaces and routes change a lot.
This is a particular issue for MOBIKE, where we enumerate local addresses
to send to the peer. While adding `ADDR_TYPE_LOOPBACK` there would be
an option, there really is no reason to have that filter now that we
filter the addresses explicitly (if users want to ignore addresses on
`lo` for specific setups, they can add it to `interfaces_ignore`).
Note that the behavior on FreeBSD can be changed via
`net.inet.ip.rfc1122_strong_es`, and that Windows defaults to the strong
host model since Vista but can explicitly be changed via `netsh` and
the `weakhostreceive|send` option.
The `ADDR_TYPE_LOOPBACK` filter is removed accordingly.
diff --git a/src/libcharon/kernel/kernel_net.h b/src/libcharon/kernel/kernel_net.h
index f24a9510e3..416b60e621 100644
--- a/src/libcharon/kernel/kernel_net.h
+++ b/src/libcharon/kernel/kernel_net.h
@@ -35,18 +35,17 @@ typedef enum kernel_address_type_t kernel_address_type_t;
* Type of addresses (e.g. when enumerating them)
*/
enum kernel_address_type_t {
- /** normal addresses (on regular, up, non-ignored) interfaces */
+ /** addresses on up and non-ignored interfaces, with usable scope and
+ * non-deprecated, includes globals on loopback interfaces */
ADDR_TYPE_REGULAR = (1 << 0),
/** addresses on down interfaces */
ADDR_TYPE_DOWN = (1 << 1),
/** addresses on ignored interfaces */
ADDR_TYPE_IGNORED = (1 << 2),
- /** addresses on loopback interfaces */
- ADDR_TYPE_LOOPBACK = (1 << 3),
/** virtual IP addresses */
- ADDR_TYPE_VIRTUAL = (1 << 4),
+ ADDR_TYPE_VIRTUAL = (1 << 3),
/** to enumerate all available addresses */
- ADDR_TYPE_ALL = (1 << 5) - 1,
+ ADDR_TYPE_ALL = (1 << 4) - 1,
};
/**
diff --git a/src/libcharon/plugins/kernel_iph/kernel_iph_net.c b/src/libcharon/plugins/kernel_iph/kernel_iph_net.c
index fed5b8fa92..52b231d747 100644
--- a/src/libcharon/plugins/kernel_iph/kernel_iph_net.c
+++ b/src/libcharon/plugins/kernel_iph/kernel_iph_net.c
@@ -477,11 +477,6 @@ METHOD(enumerator_t, addr_enumerate, bool,
{
return FALSE;
}
- if (entry->iftype == IF_TYPE_SOFTWARE_LOOPBACK &&
- !(this->which & ADDR_TYPE_LOOPBACK))
- {
- continue;
- }
if (entry->status != IfOperStatusUp &&
!(this->which & ADDR_TYPE_DOWN))
{
diff --git a/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c b/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c
index 17910a3057..926d3d9040 100644
--- a/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c
+++ b/src/libcharon/plugins/kernel_netlink/kernel_netlink_net.c
@@ -1559,10 +1559,6 @@ CALLBACK(filter_interfaces, bool,
{ /* skip interfaces excluded by config */
continue;
}
- if (!(data->which & ADDR_TYPE_LOOPBACK) && (iface->flags & IFF_LOOPBACK))
- { /* ignore loopback devices */
- continue;
- }
if (!(data->which & ADDR_TYPE_DOWN) && !(iface->flags & IFF_UP))
{ /* skip interfaces not up */
continue;
diff --git a/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c b/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c
index 6fe4371599..b0367ae46a 100644
--- a/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c
+++ b/src/libcharon/plugins/kernel_pfroute/kernel_pfroute_net.c
@@ -1169,10 +1169,6 @@ CALLBACK(filter_interfaces, bool,
{ /* skip interfaces excluded by config */
continue;
}
- if (!(data->which & ADDR_TYPE_LOOPBACK) && (iface->flags & IFF_LOOPBACK))
- { /* ignore loopback devices */
- continue;
- }
if (!(data->which & ADDR_TYPE_DOWN) && !(iface->flags & IFF_UP))
{ /* skip interfaces not up */
continue;