mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-17 01:10:22 +01:00
Add support for CLAT to l3cfg (fixes)
This commit is contained in:
parent
79a2b5599f
commit
b31d3e1eae
4 changed files with 126 additions and 103 deletions
|
|
@ -304,6 +304,7 @@ 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)
|
||||
|
|
|
|||
|
|
@ -2001,12 +2001,11 @@ nm_l3_config_data_set_pref64_valid(NML3ConfigData *self, gboolean val)
|
|||
}
|
||||
|
||||
gboolean
|
||||
nm_l3_config_data_get_pref64_valid(const NML3ConfigData *self, gboolean *out_val)
|
||||
nm_l3_config_data_get_pref64_valid(const NML3ConfigData *self)
|
||||
{
|
||||
nm_assert(_NM_IS_L3_CONFIG_DATA(self, TRUE));
|
||||
|
||||
NM_SET_OUT(out_val, self->pref64_valid);
|
||||
return TRUE;
|
||||
return self->pref64_valid;
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
|
|
|||
|
|
@ -500,7 +500,7 @@ const char *nm_l3_config_data_get_network_id(const NML3ConfigData *self);
|
|||
|
||||
gboolean nm_l3_config_data_set_pref64_valid(NML3ConfigData *self, gboolean val);
|
||||
|
||||
gboolean nm_l3_config_data_get_pref64_valid(const NML3ConfigData *self, gboolean *out_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,
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
#include <linux/if_ether.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/fib_rules.h>
|
||||
#ifdef HAVE_CLAT
|
||||
#if HAVE_CLAT
|
||||
#include <bpf/libbpf.h>
|
||||
#include <bpf/bpf.h>
|
||||
#endif /* HAVE_CLAT */
|
||||
|
|
@ -27,7 +27,7 @@
|
|||
#include "nm-l3-ipv4ll.h"
|
||||
#include "nm-ip-config.h"
|
||||
#include "nm-core-utils.h"
|
||||
#ifdef HAVE_CLAT
|
||||
#if HAVE_CLAT
|
||||
#include "bpf/clat.h"
|
||||
NM_PRAGMA_WARNING_DISABLE("-Wcast-align")
|
||||
#include "bpf/clat.skel.h"
|
||||
|
|
@ -300,12 +300,19 @@ typedef struct _NML3CfgPrivate {
|
|||
NMIPConfig *ipconfig_x[2];
|
||||
};
|
||||
|
||||
#ifdef HAVE_CLAT
|
||||
NMNetnsIPRange *clat_address_4_commited;
|
||||
NMPlatformIP6Address clat_address_6_commited;
|
||||
NMNetnsIPRange *clat_address_4;
|
||||
#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;
|
||||
struct in6_addr clat_pref64;
|
||||
|
||||
/* The same addresses as above, but already committed previously */
|
||||
NMNetnsIPReservation *clat_address_4_committed;
|
||||
NMPlatformIP6Address clat_address_6_committed;
|
||||
|
||||
/* The NAT64 prefix discovered via RA */
|
||||
struct in6_addr clat_pref64;
|
||||
|
||||
/* If NULL, the BPF program hasn't been loaded or attached */
|
||||
struct clat_bpf *clat_bpf;
|
||||
int clat_socket;
|
||||
|
|
@ -379,7 +386,7 @@ typedef struct _NML3CfgPrivate {
|
|||
bool rp_filter_set : 1;
|
||||
|
||||
bool clat_address_6_valid : 1;
|
||||
bool clat_address_6_commited_valid : 1;
|
||||
bool clat_address_6_committed_valid : 1;
|
||||
bool clat_pref64_valid : 1;
|
||||
} NML3CfgPrivate;
|
||||
|
||||
|
|
@ -4151,9 +4158,10 @@ _l3cfg_update_combined_config(NML3Cfg *self,
|
|||
guint i;
|
||||
gboolean merged_changed = FALSE;
|
||||
gboolean commited_changed = FALSE;
|
||||
gboolean pref64_valid = FALSE;
|
||||
struct in6_addr pref64;
|
||||
guint32 pref64_plen;
|
||||
#if HAVE_CLAT
|
||||
struct in6_addr pref64;
|
||||
guint32 pref64_plen;
|
||||
#endif
|
||||
|
||||
nm_assert(NM_IS_L3CFG(self));
|
||||
nm_assert(!out_old || !*out_old);
|
||||
|
|
@ -4252,32 +4260,42 @@ _l3cfg_update_combined_config(NML3Cfg *self,
|
|||
}
|
||||
|
||||
#if HAVE_CLAT
|
||||
nm_assert(nm_l3_config_data_get_pref64_valid(l3cd, &pref64_valid));
|
||||
if (pref64_valid) {
|
||||
nm_assert(nm_l3_config_data_get_pref64(l3cd, &pref64, &pref64_plen));
|
||||
}
|
||||
|
||||
if (pref64_valid) {
|
||||
NMPlatformIPXRoute rx;
|
||||
NMIPAddrTyped best_v6_gateway;
|
||||
struct in6_addr ip6;
|
||||
NMDedupMultiIter iter;
|
||||
|
||||
if (nm_l3_config_data_get_pref64_valid(l3cd)) {
|
||||
NMPlatformIPXRoute rx;
|
||||
NMIPAddrTyped best_v6_gateway;
|
||||
NMDedupMultiIter iter;
|
||||
const NMPlatformIP6Route *best_v6_route;
|
||||
const NMPlatformIP6Address *ip6_entry;
|
||||
struct in6_addr ip6;
|
||||
const char *network_id;
|
||||
char buf[512];
|
||||
|
||||
/* We need to assign an additional v6 /64 address for ourselves, according
|
||||
to the spec: https://www.rfc-editor.org/rfc/rfc6877#section-6.3 */
|
||||
if (!self->priv.p->clat_address_6_valid) {
|
||||
/* 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_RANDOM,
|
||||
nm_utils_ipv6_addr_set_stable_privacy(NM_UTILS_STABLE_TYPE_CLAT,
|
||||
&ip6,
|
||||
nm_l3cfg_get_ifname(self, TRUE),
|
||||
"TODO: Mary fixme",
|
||||
network_id,
|
||||
0);
|
||||
self->priv.p->clat_address_6 = (NMPlatformIP6Address) {
|
||||
.ifindex = self->priv.ifindex,
|
||||
|
|
@ -4286,6 +4304,9 @@ _l3cfg_update_combined_config(NML3Cfg *self,
|
|||
.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;
|
||||
}
|
||||
|
|
@ -4296,16 +4317,18 @@ _l3cfg_update_combined_config(NML3Cfg *self,
|
|||
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 commited one */
|
||||
if (self->priv.p->clat_address_4 != self->priv.p->clat_address_4_commited) {
|
||||
nm_clear_pointer(&self->priv.p->clat_address_4, nm_netns_ip_range_release);
|
||||
/* 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_range_allocate(self->priv.netns, NM_NETNS_IP_RANGE_TYPE_CLAT);
|
||||
nm_netns_ip_reservation_get(self->priv.netns,
|
||||
NM_NETNS_IP_RESERVATION_TYPE_CLAT);
|
||||
}
|
||||
|
||||
if (self->priv.p->clat_address_4) {
|
||||
|
|
@ -4357,6 +4380,10 @@ _l3cfg_update_combined_config(NML3Cfg *self,
|
|||
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!");
|
||||
|
|
@ -4425,15 +4452,17 @@ _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_commited) {
|
||||
nm_clear_pointer(&self->priv.p->clat_address_4, nm_netns_ip_range_release);
|
||||
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));
|
||||
|
|
@ -5534,14 +5563,14 @@ _l3_commit_one(NML3Cfg *self,
|
|||
_failedobj_handle_routes(self, addr_family, routes_failed);
|
||||
}
|
||||
|
||||
#ifdef HAVE_CLAT
|
||||
#if HAVE_CLAT
|
||||
static void
|
||||
_l3_get_pref64_config(NML3Cfg *self,
|
||||
struct clat_v4_config_key *v4_key,
|
||||
struct clat_v4_config_value *v4_value,
|
||||
struct clat_v6_config_key *v6_key,
|
||||
struct clat_v6_config_value *v6_value,
|
||||
gboolean commited)
|
||||
gboolean committed)
|
||||
{
|
||||
const NML3ConfigData *l3cd = self->priv.p->combined_l3cd_commited;
|
||||
struct in6_addr pref64;
|
||||
|
|
@ -5554,13 +5583,13 @@ _l3_get_pref64_config(NML3Cfg *self,
|
|||
|
||||
v4_key->ifindex = v6_key->ifindex = self->priv.ifindex;
|
||||
|
||||
if (commited) {
|
||||
if (self->priv.p->clat_address_4_commited) {
|
||||
if (committed) {
|
||||
if (self->priv.p->clat_address_4_committed) {
|
||||
v6_value->local_v4.s_addr = v4_key->local_v4.s_addr =
|
||||
self->priv.p->clat_address_4_commited->addr;
|
||||
self->priv.p->clat_address_4_committed->addr;
|
||||
}
|
||||
if (self->priv.p->clat_address_6_commited_valid) {
|
||||
v4_value->local_v6 = v6_key->local_v6 = self->priv.p->clat_address_6_commited.address;
|
||||
if (self->priv.p->clat_address_6_committed_valid) {
|
||||
v4_value->local_v6 = v6_key->local_v6 = self->priv.p->clat_address_6_committed.address;
|
||||
}
|
||||
if (self->priv.p->clat_pref64_valid) {
|
||||
v6_key->pref64 = v4_value->pref64 = self->priv.p->clat_pref64;
|
||||
|
|
@ -5605,6 +5634,9 @@ _l3_clat_destroy(NML3Cfg *self)
|
|||
libbpf_strerror(err, buf, sizeof(buf));
|
||||
_LOGW("failed to tear down CLAT BPF egress hook: %s", buf);
|
||||
}
|
||||
|
||||
bpf_tc_hook_destroy(&hook);
|
||||
|
||||
nm_clear_pointer(&self->priv.p->clat_bpf, clat_bpf__destroy);
|
||||
}
|
||||
|
||||
|
|
@ -5617,10 +5649,10 @@ _l3_commit_pref64(NML3Cfg *self, NML3CfgCommitType commit_type)
|
|||
const struct in6_addr *l3cd_pref64 = NULL;
|
||||
guint32 l3cd_pref64_plen;
|
||||
char buf[100];
|
||||
struct clat_v6_config_key v6_key_commited, v6_key_new;
|
||||
struct clat_v4_config_key v4_key_commited, v4_key_new;
|
||||
struct clat_v6_config_value v6_value_commited, v6_value_new;
|
||||
struct clat_v4_config_value v4_value_commited, v4_value_new;
|
||||
struct clat_v6_config_key v6_key_committed, v6_key_new;
|
||||
struct clat_v4_config_key v4_key_committed, v4_key_new;
|
||||
struct clat_v6_config_value v6_value_committed, v6_value_new;
|
||||
struct clat_v4_config_value v4_value_committed, v4_value_new;
|
||||
gboolean v6_changed;
|
||||
DECLARE_LIBBPF_OPTS(bpf_tc_hook,
|
||||
hook,
|
||||
|
|
@ -5635,12 +5667,12 @@ _l3_commit_pref64(NML3Cfg *self, NML3CfgCommitType commit_type)
|
|||
|
||||
if (l3cd_pref64 && self->priv.p->clat_address_4 && self->priv.p->clat_address_6_valid) {
|
||||
if (!self->priv.p->clat_bpf) {
|
||||
/* Bring up the CLAT */
|
||||
_LOGT("clat: attaching the BPF program");
|
||||
self->priv.p->clat_bpf = clat_bpf__open();
|
||||
err = libbpf_get_error(self->priv.p->clat_bpf);
|
||||
if (err) {
|
||||
libbpf_strerror(err, buf, sizeof(buf));
|
||||
_LOGW("failed to load CLAT BPF: %s", buf);
|
||||
_LOGW("clat: failed to open the BPF program: %s", buf);
|
||||
clat_bpf__destroy(self->priv.p->clat_bpf);
|
||||
self->priv.p->clat_bpf = NULL;
|
||||
return;
|
||||
|
|
@ -5653,7 +5685,7 @@ _l3_commit_pref64(NML3Cfg *self, NML3CfgCommitType commit_type)
|
|||
err = clat_bpf__load(self->priv.p->clat_bpf);
|
||||
if (err) {
|
||||
libbpf_strerror(err, buf, sizeof(buf));
|
||||
_LOGW("failed to open CLAT BPF: %s", buf);
|
||||
_LOGW("clat: failed to load the BPF program: %s", buf);
|
||||
clat_bpf__destroy(self->priv.p->clat_bpf);
|
||||
self->priv.p->clat_bpf = NULL;
|
||||
return;
|
||||
|
|
@ -5662,7 +5694,7 @@ _l3_commit_pref64(NML3Cfg *self, NML3CfgCommitType commit_type)
|
|||
err = bpf_tc_hook_create(&hook);
|
||||
if (err && err != -EEXIST) {
|
||||
libbpf_strerror(err, buf, sizeof(buf));
|
||||
_LOGW("failed to create CLAT BPF hook: %s", buf);
|
||||
_LOGW("clat: failed to create the BPF hook: %s", buf);
|
||||
clat_bpf__destroy(self->priv.p->clat_bpf);
|
||||
self->priv.p->clat_bpf = NULL;
|
||||
return;
|
||||
|
|
@ -5670,7 +5702,7 @@ _l3_commit_pref64(NML3Cfg *self, NML3CfgCommitType commit_type)
|
|||
|
||||
attach_ingress.prog_fd = bpf_program__fd(self->priv.p->clat_bpf->progs.clat_ingress);
|
||||
if (attach_ingress.prog_fd < 0) {
|
||||
_LOGW("couldn't find CLAT BPF ingress!");
|
||||
_LOGW("clat: couldn't find the BPF ingress");
|
||||
clat_bpf__destroy(self->priv.p->clat_bpf);
|
||||
self->priv.p->clat_bpf = NULL;
|
||||
return;
|
||||
|
|
@ -5678,7 +5710,7 @@ _l3_commit_pref64(NML3Cfg *self, NML3CfgCommitType commit_type)
|
|||
|
||||
attach_egress.prog_fd = bpf_program__fd(self->priv.p->clat_bpf->progs.clat_egress);
|
||||
if (attach_egress.prog_fd < 0) {
|
||||
_LOGW("couldn't find CLAT BPF egress!");
|
||||
_LOGW("clat: couldn't find the BPF egress");
|
||||
clat_bpf__destroy(self->priv.p->clat_bpf);
|
||||
self->priv.p->clat_bpf = NULL;
|
||||
return;
|
||||
|
|
@ -5688,7 +5720,7 @@ _l3_commit_pref64(NML3Cfg *self, NML3CfgCommitType commit_type)
|
|||
err = bpf_tc_attach(&hook, &attach_ingress);
|
||||
if (err) {
|
||||
libbpf_strerror(err, buf, sizeof(buf));
|
||||
_LOGW("failed to attach ingress to CLAT BPF hook: %s", buf);
|
||||
_LOGW("clat: failed to attach ingress to BPF hook: %s", buf);
|
||||
clat_bpf__destroy(self->priv.p->clat_bpf);
|
||||
self->priv.p->clat_bpf = NULL;
|
||||
return;
|
||||
|
|
@ -5699,7 +5731,7 @@ _l3_commit_pref64(NML3Cfg *self, NML3CfgCommitType commit_type)
|
|||
err = bpf_tc_attach(&hook, &attach_egress);
|
||||
if (err) {
|
||||
libbpf_strerror(err, buf, sizeof(buf));
|
||||
_LOGW("failed to attach ingress to CLAT BPF hook: %s", buf);
|
||||
_LOGW("clat: failed to attach ingress to BPF hook: %s", buf);
|
||||
clat_bpf__destroy(self->priv.p->clat_bpf);
|
||||
self->priv.p->clat_bpf = NULL;
|
||||
return;
|
||||
|
|
@ -5708,28 +5740,28 @@ _l3_commit_pref64(NML3Cfg *self, NML3CfgCommitType commit_type)
|
|||
}
|
||||
|
||||
_l3_get_pref64_config(self,
|
||||
&v4_key_commited,
|
||||
&v4_value_commited,
|
||||
&v6_key_commited,
|
||||
&v6_value_commited,
|
||||
&v4_key_committed,
|
||||
&v4_value_committed,
|
||||
&v6_key_committed,
|
||||
&v6_value_committed,
|
||||
TRUE);
|
||||
_l3_get_pref64_config(self, &v4_key_new, &v4_value_new, &v6_key_new, &v6_value_new, FALSE);
|
||||
|
||||
if (memcmp(&v4_key_commited, &v4_key_new, sizeof(v4_key_new))) {
|
||||
if (memcmp(&v4_key_committed, &v4_key_new, sizeof(v4_key_new))) {
|
||||
bpf_map_delete_elem(bpf_map__fd(self->priv.p->clat_bpf->maps.v4_config_map),
|
||||
&v4_key_commited);
|
||||
&v4_key_committed);
|
||||
}
|
||||
if (memcmp(&v6_key_commited, &v6_key_new, sizeof(v6_key_new))) {
|
||||
if (memcmp(&v6_key_committed, &v6_key_new, sizeof(v6_key_new))) {
|
||||
bpf_map_delete_elem(bpf_map__fd(self->priv.p->clat_bpf->maps.v6_config_map),
|
||||
&v6_key_commited);
|
||||
&v6_key_committed);
|
||||
}
|
||||
if (memcmp(&v4_value_commited, &v4_value_new, sizeof(v4_value_new))) {
|
||||
if (memcmp(&v4_value_committed, &v4_value_new, sizeof(v4_value_new))) {
|
||||
bpf_map_update_elem(bpf_map__fd(self->priv.p->clat_bpf->maps.v4_config_map),
|
||||
&v4_key_new,
|
||||
&v4_value_new,
|
||||
BPF_ANY);
|
||||
}
|
||||
if (memcmp(&v6_value_commited, &v6_value_new, sizeof(v6_value_new))) {
|
||||
if (memcmp(&v6_value_committed, &v6_value_new, sizeof(v6_value_new))) {
|
||||
bpf_map_update_elem(bpf_map__fd(self->priv.p->clat_bpf->maps.v6_config_map),
|
||||
&v6_key_new,
|
||||
&v6_value_new,
|
||||
|
|
@ -5746,9 +5778,7 @@ _l3_commit_pref64(NML3Cfg *self, NML3CfgCommitType commit_type)
|
|||
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("Couldn't create CLAT socket for %d! %s",
|
||||
self->priv.ifindex,
|
||||
nm_strerror_native(errno));
|
||||
_LOGW("clat: couldn't create the socket: %s", nm_strerror_native(errno));
|
||||
}
|
||||
}
|
||||
if (self->priv.p->clat_socket >= 0) {
|
||||
|
|
@ -5757,35 +5787,31 @@ _l3_commit_pref64(NML3Cfg *self, NML3CfgCommitType commit_type)
|
|||
SO_BINDTOIFINDEX,
|
||||
&self->priv.ifindex,
|
||||
sizeof(self->priv.ifindex));
|
||||
if (err) {
|
||||
_LOGW("Couldn't bind CLAT socket to interface %d! %s",
|
||||
self->priv.ifindex,
|
||||
nm_strerror_native(errno));
|
||||
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_commited_valid)
|
||||
|| (self->priv.p->clat_address_6_valid && self->priv.p->clat_address_6_commited_valid
|
||||
(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_commited.address,
|
||||
sizeof(self->priv.p->clat_address_6_commited.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_commited_valid) {
|
||||
mreq.ipv6mr_multiaddr = self->priv.p->clat_address_6_commited.address;
|
||||
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) {
|
||||
_LOGW("Couldn't leave CLAT anycast group on interface %d! %s",
|
||||
self->priv.ifindex,
|
||||
nm_strerror_native(errno));
|
||||
if (err < 0) {
|
||||
_LOGW("clat: couldn't leave the anycast group: %s", nm_strerror_native(errno));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -5797,10 +5823,8 @@ _l3_commit_pref64(NML3Cfg *self, NML3CfgCommitType commit_type)
|
|||
IPV6_JOIN_ANYCAST,
|
||||
&mreq,
|
||||
sizeof(mreq));
|
||||
if (err) {
|
||||
_LOGW("Couldn't join CLAT anycast group on interface %d! %s",
|
||||
self->priv.ifindex,
|
||||
nm_strerror_native(errno));
|
||||
if (err < 0) {
|
||||
_LOGW("clat: couldn't join the anycast group: %s", nm_strerror_native(errno));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5809,27 +5833,27 @@ _l3_commit_pref64(NML3Cfg *self, NML3CfgCommitType commit_type)
|
|||
_l3_clat_destroy(self);
|
||||
}
|
||||
|
||||
/* Commited will get cleaned up below */
|
||||
/* 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. Commited address will get cleaned up below,
|
||||
/* 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_commited) {
|
||||
nm_clear_pointer(&self->priv.p->clat_address_4, nm_netns_ip_range_release);
|
||||
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_commited != self->priv.p->clat_address_4) {
|
||||
nm_clear_pointer(&self->priv.p->clat_address_4_commited, nm_netns_ip_range_release);
|
||||
self->priv.p->clat_address_4_commited = self->priv.p->clat_address_4;
|
||||
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_commited = self->priv.p->clat_address_6;
|
||||
self->priv.p->clat_address_6_commited_valid = self->priv.p->clat_address_6_valid;
|
||||
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 */
|
||||
|
||||
|
|
@ -5915,7 +5939,7 @@ _l3_commit(NML3Cfg *self, NML3CfgCommitType commit_type, gboolean is_idle)
|
|||
|
||||
_l3_acd_data_process_changes(self);
|
||||
|
||||
#ifdef HAVE_CLAT
|
||||
#if HAVE_CLAT
|
||||
_l3_commit_pref64(self, commit_type);
|
||||
#endif /* HAVE_CLAT */
|
||||
|
||||
|
|
@ -6300,7 +6324,9 @@ 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);
|
||||
|
|
@ -6356,9 +6382,6 @@ finalize(GObject *object)
|
|||
{
|
||||
NML3Cfg *self = NM_L3CFG(object);
|
||||
gboolean changed;
|
||||
#ifdef HAVE_CLAT
|
||||
DECLARE_LIBBPF_OPTS(bpf_tc_hook, hook, .attach_point = BPF_TC_INGRESS | BPF_TC_EGRESS);
|
||||
#endif /* HAVE_CLAT */
|
||||
|
||||
if (self->priv.netns) {
|
||||
nm_netns_watcher_remove_all(self->priv.netns, _NETNS_WATCHER_IP_ADDR_TAG(self, AF_INET));
|
||||
|
|
@ -6413,9 +6436,9 @@ finalize(GObject *object)
|
|||
if (changed)
|
||||
nmp_global_tracker_sync_mptcp_addrs(self->priv.global_tracker, FALSE);
|
||||
|
||||
#ifdef HAVE_CLAT
|
||||
self->priv.p->clat_address_4_commited = NULL;
|
||||
nm_clear_pointer(&self->priv.p->clat_address_4, nm_netns_ip_range_release);
|
||||
#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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue