mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2025-12-26 04:10:14 +01:00
platform: add NMPlatformMptcpAddr object
An NMPObject is hashable, can be compared and printed. That is useful. Make an NMPObject for MPTCP addresses. It will hold the content of MPTCP_PM_ATTR_ADDR netlink attribute. But like other NMPObject types it will also be used to represent the data as NetworkManager tracks it.
This commit is contained in:
parent
be4b775585
commit
1a0c8772b0
6 changed files with 195 additions and 4 deletions
|
|
@ -23,6 +23,7 @@
|
|||
#include <linux/if_vlan.h>
|
||||
#include <linux/ip6_tunnel.h>
|
||||
#include <linux/tc_act/tc_mirred.h>
|
||||
#include <linux-headers/mptcp.h>
|
||||
#include <netinet/icmp6.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if_arp.h>
|
||||
|
|
@ -50,6 +51,14 @@
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
G_STATIC_ASSERT(NM_MPTCP_PM_ADDR_FLAG_SIGNAL == MPTCP_PM_ADDR_FLAG_SIGNAL);
|
||||
G_STATIC_ASSERT(NM_MPTCP_PM_ADDR_FLAG_SUBFLOW == MPTCP_PM_ADDR_FLAG_SUBFLOW);
|
||||
G_STATIC_ASSERT(NM_MPTCP_PM_ADDR_FLAG_BACKUP == MPTCP_PM_ADDR_FLAG_BACKUP);
|
||||
G_STATIC_ASSERT(NM_MPTCP_PM_ADDR_FLAG_FULLMESH == MPTCP_PM_ADDR_FLAG_FULLMESH);
|
||||
G_STATIC_ASSERT(NM_MPTCP_PM_ADDR_FLAG_IMPLICIT == MPTCP_PM_ADDR_FLAG_IMPLICIT);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* re-implement <linux/tc_act/tc_defact.h> to build against kernel
|
||||
* headers that lack this. */
|
||||
|
||||
|
|
|
|||
|
|
@ -7586,6 +7586,93 @@ nm_platform_tfilter_cmp(const NMPlatformTfilter *a, const NMPlatformTfilter *b)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static NM_UTILS_FLAGS2STR_DEFINE(_mptcp_flags_to_string,
|
||||
guint32,
|
||||
NM_UTILS_FLAGS2STR(NM_MPTCP_PM_ADDR_FLAG_SIGNAL, "signal"),
|
||||
NM_UTILS_FLAGS2STR(NM_MPTCP_PM_ADDR_FLAG_SUBFLOW, "subflow"),
|
||||
NM_UTILS_FLAGS2STR(NM_MPTCP_PM_ADDR_FLAG_BACKUP, "backup"),
|
||||
NM_UTILS_FLAGS2STR(NM_MPTCP_PM_ADDR_FLAG_FULLMESH, "fullmesh"));
|
||||
|
||||
const char *
|
||||
nm_platform_mptcp_addr_to_string(const NMPlatformMptcpAddr *mptcp_addr, char *buf, gsize len)
|
||||
{
|
||||
char str_addr[30 + NM_UTILS_INET_ADDRSTRLEN];
|
||||
char str_port[30];
|
||||
char str_id[30];
|
||||
char str_flags[200];
|
||||
char str_flags2[30 + sizeof(str_flags)];
|
||||
char str_ifindex[30];
|
||||
|
||||
if (!nm_utils_to_string_buffer_init_null(mptcp_addr, &buf, &len))
|
||||
return buf;
|
||||
|
||||
if (mptcp_addr->addr_family == 0)
|
||||
nm_sprintf_buf(str_addr, "no-addr");
|
||||
else if (NM_IN_SET(mptcp_addr->addr_family, AF_INET, AF_INET6))
|
||||
nm_utils_inet_ntop(mptcp_addr->addr_family, &mptcp_addr->addr, str_addr);
|
||||
else
|
||||
nm_sprintf_buf(str_addr, "af %d", mptcp_addr->addr_family);
|
||||
|
||||
if (mptcp_addr->flags != 0)
|
||||
_mptcp_flags_to_string(mptcp_addr->flags, str_flags, sizeof(str_flags));
|
||||
else
|
||||
str_flags[0] = '\0';
|
||||
|
||||
g_snprintf(buf,
|
||||
len,
|
||||
"%s" /* in_kernel */
|
||||
"%s" /* address */
|
||||
"%s" /* port */
|
||||
"%s" /* id */
|
||||
"%s" /* flags */
|
||||
"%s" /* ifindex */
|
||||
"",
|
||||
mptcp_addr->in_kernel ? "" : "[nm] ",
|
||||
str_addr,
|
||||
mptcp_addr->port == 0 ? "" : nm_sprintf_buf(str_port, " port %u", mptcp_addr->port),
|
||||
mptcp_addr->id == 0 ? "" : nm_sprintf_buf(str_id, " id %u", mptcp_addr->id),
|
||||
str_flags[0] == '\0' ? "" : nm_sprintf_buf(str_flags2, " flags %s", str_flags),
|
||||
mptcp_addr->ifindex == 0
|
||||
? ""
|
||||
: nm_sprintf_buf(str_ifindex, " ifindex %d", mptcp_addr->ifindex));
|
||||
return buf;
|
||||
}
|
||||
|
||||
void
|
||||
nm_platform_mptcp_addr_hash_update(const NMPlatformMptcpAddr *obj, NMHashState *h)
|
||||
{
|
||||
nm_assert(obj);
|
||||
nm_assert_addr_family_or_unspec(obj->addr_family);
|
||||
|
||||
nm_hash_update_vals(h,
|
||||
obj->id,
|
||||
obj->flags,
|
||||
obj->port,
|
||||
obj->addr_family,
|
||||
(bool) obj->in_kernel,
|
||||
obj->ifindex);
|
||||
if (NM_IN_SET(obj->addr_family, AF_INET, AF_INET6))
|
||||
nm_hash_update(h, &obj->addr, nm_utils_addr_family_to_size(obj->addr_family));
|
||||
}
|
||||
|
||||
int
|
||||
nm_platform_mptcp_addr_cmp(const NMPlatformMptcpAddr *a, const NMPlatformMptcpAddr *b)
|
||||
{
|
||||
NM_CMP_SELF(a, b);
|
||||
|
||||
nm_assert_addr_family_or_unspec(a->addr_family);
|
||||
nm_assert_addr_family_or_unspec(b->addr_family);
|
||||
|
||||
NM_CMP_FIELD(a, b, id);
|
||||
NM_CMP_FIELD_UNSAFE(a, b, in_kernel);
|
||||
NM_CMP_FIELD(a, b, addr_family);
|
||||
if (NM_IN_SET(a->addr_family, AF_INET, AF_INET6))
|
||||
NM_CMP_FIELD_MEMCMP_LEN(a, b, addr, nm_utils_addr_family_to_size(a->addr_family));
|
||||
NM_CMP_FIELD(a, b, ifindex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *
|
||||
nm_platform_vf_to_string(const NMPlatformVF *vf, char *buf, gsize len)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -61,6 +61,12 @@ typedef gboolean (*NMPObjectPredicateFunc)(const NMPObject *obj, gpointer user_d
|
|||
|
||||
#define NM_IFF_MULTI_QUEUE 0x0100 /* IFF_MULTI_QUEUE */
|
||||
|
||||
#define NM_MPTCP_PM_ADDR_FLAG_SIGNAL ((guint32) (1 << 0))
|
||||
#define NM_MPTCP_PM_ADDR_FLAG_SUBFLOW ((guint32) (1 << 1))
|
||||
#define NM_MPTCP_PM_ADDR_FLAG_BACKUP ((guint32) (1 << 2))
|
||||
#define NM_MPTCP_PM_ADDR_FLAG_FULLMESH ((guint32) (1 << 3))
|
||||
#define NM_MPTCP_PM_ADDR_FLAG_IMPLICIT ((guint32) (1 << 4))
|
||||
|
||||
/* Redefine this in host's endianness */
|
||||
#define NM_GRE_KEY 0x2000
|
||||
|
||||
|
|
@ -782,8 +788,6 @@ typedef struct {
|
|||
NMPlatformAction action;
|
||||
} NMPlatformTfilter;
|
||||
|
||||
#undef __NMPlatformObjWithIfindex_COMMON
|
||||
|
||||
typedef struct {
|
||||
bool is_ip4;
|
||||
NMPObjectType obj_type;
|
||||
|
|
@ -1045,6 +1049,27 @@ typedef enum {
|
|||
|
||||
typedef void (*NMPlatformAsyncCallback)(GError *error, gpointer user_data);
|
||||
|
||||
typedef struct {
|
||||
__NMPlatformObjWithIfindex_COMMON;
|
||||
|
||||
guint32 id;
|
||||
guint32 flags;
|
||||
guint16 port;
|
||||
NMIPAddr addr;
|
||||
gint8 addr_family;
|
||||
|
||||
/* If TRUE, then the instance was received by kernel and is inside NMPlatform
|
||||
* cache. In that case, the "id" is set and acts as primary key for the instance.
|
||||
*
|
||||
* If FALSE, this instance is not yet configured in kernel. In this case,
|
||||
* the tuple (id, addr_family, addr) is the primary key of the instance.
|
||||
* This way, we can track mptcp addresses in NetworkManager internally,
|
||||
* before configuring them in kernel. */
|
||||
bool in_kernel : 1;
|
||||
} NMPlatformMptcpAddr;
|
||||
|
||||
#undef __NMPlatformObjWithIfindex_COMMON
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct _NMPlatformCsmeConnInfo {
|
||||
|
|
@ -2355,6 +2380,9 @@ const char *nm_platform_vlan_qos_mapping_to_string(const char *name,
|
|||
const char *
|
||||
nm_platform_wireguard_peer_to_string(const struct _NMPWireGuardPeer *peer, char *buf, gsize len);
|
||||
|
||||
const char *
|
||||
nm_platform_mptcp_addr_to_string(const NMPlatformMptcpAddr *mptcp_addr, char *buf, gsize len);
|
||||
|
||||
int nm_platform_link_cmp(const NMPlatformLink *a, const NMPlatformLink *b);
|
||||
int nm_platform_lnk_bridge_cmp(const NMPlatformLnkBridge *a, const NMPlatformLnkBridge *b);
|
||||
int nm_platform_lnk_gre_cmp(const NMPlatformLnkGre *a, const NMPlatformLnkGre *b);
|
||||
|
|
@ -2433,6 +2461,8 @@ int nm_platform_qdisc_cmp_full(const NMPlatformQdisc *a,
|
|||
gboolean compare_handle);
|
||||
int nm_platform_tfilter_cmp(const NMPlatformTfilter *a, const NMPlatformTfilter *b);
|
||||
|
||||
int nm_platform_mptcp_addr_cmp(const NMPlatformMptcpAddr *a, const NMPlatformMptcpAddr *b);
|
||||
|
||||
void nm_platform_link_hash_update(const NMPlatformLink *obj, NMHashState *h);
|
||||
void nm_platform_ip4_address_hash_update(const NMPlatformIP4Address *obj, NMHashState *h);
|
||||
void nm_platform_ip6_address_hash_update(const NMPlatformIP6Address *obj, NMHashState *h);
|
||||
|
|
@ -2462,6 +2492,8 @@ void nm_platform_lnk_wireguard_hash_update(const NMPlatformLnkWireGuard *obj, NM
|
|||
void nm_platform_qdisc_hash_update(const NMPlatformQdisc *obj, NMHashState *h);
|
||||
void nm_platform_tfilter_hash_update(const NMPlatformTfilter *obj, NMHashState *h);
|
||||
|
||||
void nm_platform_mptcp_addr_hash_update(const NMPlatformMptcpAddr *obj, NMHashState *h);
|
||||
|
||||
#define NM_PLATFORM_LINK_FLAGS2STR_MAX_LEN ((gsize) 162)
|
||||
|
||||
const char *nm_platform_link_flags2str(unsigned flags, char *buf, gsize len);
|
||||
|
|
|
|||
|
|
@ -148,6 +148,8 @@ typedef enum _nm_packed {
|
|||
NMP_OBJECT_TYPE_LNK_VXLAN,
|
||||
NMP_OBJECT_TYPE_LNK_WIREGUARD,
|
||||
|
||||
NMP_OBJECT_TYPE_MPTCP_ADDR,
|
||||
|
||||
__NMP_OBJECT_TYPE_LAST,
|
||||
NMP_OBJECT_TYPE_MAX = __NMP_OBJECT_TYPE_LAST - 1,
|
||||
} NMPObjectType;
|
||||
|
|
|
|||
|
|
@ -381,7 +381,8 @@ _idx_obj_part(const DedupMultiIdxType *idx_type,
|
|||
NMP_OBJECT_TYPE_IP4_ROUTE,
|
||||
NMP_OBJECT_TYPE_IP6_ROUTE,
|
||||
NMP_OBJECT_TYPE_QDISC,
|
||||
NMP_OBJECT_TYPE_TFILTER)
|
||||
NMP_OBJECT_TYPE_TFILTER,
|
||||
NMP_OBJECT_TYPE_MPTCP_ADDR)
|
||||
|| !nmp_object_is_visible(obj_a)) {
|
||||
if (h)
|
||||
nm_hash_update_val(h, obj_a);
|
||||
|
|
@ -1551,6 +1552,21 @@ _vt_cmd_plobj_id_cmp_routing_rule(const NMPlatformObject *obj1, const NMPlatform
|
|||
NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID);
|
||||
}
|
||||
|
||||
_vt_cmd_plobj_id_cmp(mptcp_addr, NMPlatformMptcpAddr, {
|
||||
NM_CMP_FIELD(obj1, obj2, id);
|
||||
NM_CMP_FIELD_UNSAFE(obj1, obj2, in_kernel);
|
||||
if (!obj1->in_kernel) {
|
||||
/* See comment NMPlatformMptcpAddr.in_kernel for why. */
|
||||
NM_CMP_FIELD(obj1, obj2, addr_family);
|
||||
|
||||
/* nm_utils_addr_family_to_size() asserts that addr-family is either AF_INET or AF_INET6.
|
||||
* This means, we cannot compare totally bogus objects. That is in particular fine
|
||||
* for instances which are not "in_kernel". While we might receive unexpected values
|
||||
* from kernel, we should not create them for internal purposes. */
|
||||
NM_CMP_FIELD_MEMCMP_LEN(obj1, obj2, addr, nm_utils_addr_family_to_size(obj1->addr_family));
|
||||
}
|
||||
});
|
||||
|
||||
void
|
||||
nmp_object_id_hash_update(const NMPObject *obj, NMHashState *h)
|
||||
{
|
||||
|
|
@ -1636,6 +1652,16 @@ _vt_cmd_plobj_id_hash_update(tfilter, NMPlatformTfilter, {
|
|||
nm_hash_update_vals(h, obj->ifindex, obj->handle);
|
||||
});
|
||||
|
||||
_vt_cmd_plobj_id_hash_update(mptcp_addr, NMPlatformMptcpAddr, {
|
||||
if (obj->in_kernel) {
|
||||
nm_hash_update_val(h, obj->id);
|
||||
} else {
|
||||
/* _vt_cmd_plobj_id_cmp_mptcp_addr for why. */
|
||||
nm_hash_update_vals(h, obj->id, obj->addr_family);
|
||||
nm_hash_update(h, &obj->addr, nm_utils_addr_family_to_size(obj->addr_family));
|
||||
}
|
||||
});
|
||||
|
||||
static void
|
||||
_vt_cmd_plobj_hash_update_ip4_route(const NMPlatformObject *obj, NMHashState *h)
|
||||
{
|
||||
|
|
@ -1744,6 +1770,12 @@ _vt_cmd_obj_is_alive_tfilter(const NMPObject *obj)
|
|||
return NMP_OBJECT_CAST_TFILTER(obj)->ifindex > 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_vt_cmd_obj_is_alive_mptcp_addr(const NMPObject *obj)
|
||||
{
|
||||
return NM_IN_SET(obj->mptcp_addr.addr_family, AF_INET, AF_INET6);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nmp_object_is_visible(const NMPObject *obj)
|
||||
{
|
||||
|
|
@ -2089,6 +2121,7 @@ nmp_lookup_init_obj_type(NMPLookup *lookup, NMPObjectType obj_type)
|
|||
case NMP_OBJECT_TYPE_ROUTING_RULE:
|
||||
case NMP_OBJECT_TYPE_QDISC:
|
||||
case NMP_OBJECT_TYPE_TFILTER:
|
||||
case NMP_OBJECT_TYPE_MPTCP_ADDR:
|
||||
_nmp_object_stackinit_from_type(&lookup->selector_obj, obj_type);
|
||||
lookup->cache_id_type = NMP_CACHE_ID_TYPE_OBJECT_TYPE;
|
||||
return _L(lookup);
|
||||
|
|
@ -2123,7 +2156,8 @@ nmp_lookup_init_object_by_ifindex(NMPLookup *lookup, NMPObjectType obj_type, int
|
|||
NMP_OBJECT_TYPE_IP4_ROUTE,
|
||||
NMP_OBJECT_TYPE_IP6_ROUTE,
|
||||
NMP_OBJECT_TYPE_QDISC,
|
||||
NMP_OBJECT_TYPE_TFILTER));
|
||||
NMP_OBJECT_TYPE_TFILTER,
|
||||
NMP_OBJECT_TYPE_MPTCP_ADDR));
|
||||
nm_assert(ifindex > 0
|
||||
|| (ifindex == 0
|
||||
&& NM_IN_SET(obj_type, NMP_OBJECT_TYPE_IP4_ROUTE, NMP_OBJECT_TYPE_IP6_ROUTE)));
|
||||
|
|
@ -3463,4 +3497,20 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = {
|
|||
.cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_lnk_wireguard_hash_update,
|
||||
.cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_lnk_wireguard_cmp,
|
||||
},
|
||||
[NMP_OBJECT_TYPE_MPTCP_ADDR - 1] =
|
||||
{
|
||||
.parent = DEDUP_MULTI_OBJ_CLASS_INIT(),
|
||||
.obj_type = NMP_OBJECT_TYPE_MPTCP_ADDR,
|
||||
.sizeof_data = sizeof(NMPObjectMptcpAddr),
|
||||
.sizeof_public = sizeof(NMPlatformMptcpAddr),
|
||||
.obj_type_name = "mptcp-addr",
|
||||
.supported_cache_ids = _supported_cache_ids_object,
|
||||
.cmd_obj_is_alive = _vt_cmd_obj_is_alive_mptcp_addr,
|
||||
.cmd_plobj_id_cmp = _vt_cmd_plobj_id_cmp_mptcp_addr,
|
||||
.cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_mptcp_addr,
|
||||
.cmd_plobj_to_string_id = (CmdPlobjToStringIdFunc) nm_platform_mptcp_addr_to_string,
|
||||
.cmd_plobj_to_string = (CmdPlobjToStringFunc) nm_platform_mptcp_addr_to_string,
|
||||
.cmd_plobj_hash_update = (CmdPlobjHashUpdateFunc) nm_platform_mptcp_addr_hash_update,
|
||||
.cmd_plobj_cmp = (CmdPlobjCmpFunc) nm_platform_mptcp_addr_cmp,
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -331,6 +331,10 @@ typedef struct {
|
|||
NMPlatformTfilter _public;
|
||||
} NMPObjectTfilter;
|
||||
|
||||
typedef struct {
|
||||
NMPlatformMptcpAddr _public;
|
||||
} NMPObjectMptcpAddr;
|
||||
|
||||
struct _NMPObject {
|
||||
union {
|
||||
NMDedupMultiObj parent;
|
||||
|
|
@ -404,6 +408,9 @@ struct _NMPObject {
|
|||
NMPObjectQdisc _qdisc;
|
||||
NMPlatformTfilter tfilter;
|
||||
NMPObjectTfilter _tfilter;
|
||||
|
||||
NMPlatformMptcpAddr mptcp_addr;
|
||||
NMPObjectMptcpAddr _mptcp_addr;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -504,6 +511,8 @@ _NMP_OBJECT_TYPE_IS_OBJ_WITH_IFINDEX(NMPObjectType obj_type)
|
|||
case NMP_OBJECT_TYPE_LNK_VRF:
|
||||
case NMP_OBJECT_TYPE_LNK_VXLAN:
|
||||
case NMP_OBJECT_TYPE_LNK_WIREGUARD:
|
||||
|
||||
case NMP_OBJECT_TYPE_MPTCP_ADDR:
|
||||
return TRUE;
|
||||
|
||||
case NMP_OBJECT_TYPE_ROUTING_RULE:
|
||||
|
|
@ -565,6 +574,8 @@ _NMP_OBJECT_TYPE_IS_OBJ_WITH_IFINDEX(NMPObjectType obj_type)
|
|||
_NMP_OBJECT_CAST(obj, lnk_wireguard, NMP_OBJECT_TYPE_LNK_WIREGUARD)
|
||||
#define NMP_OBJECT_CAST_LNK_BRIDGE(obj) \
|
||||
_NMP_OBJECT_CAST(obj, lnk_bridge, NMP_OBJECT_TYPE_LNK_BRIDGE)
|
||||
#define NMP_OBJECT_CAST_MPTCP_ADDR(obj) \
|
||||
_NMP_OBJECT_CAST(obj, mptcp_addr, NMP_OBJECT_TYPE_MPTCP_ADDR)
|
||||
|
||||
static inline int
|
||||
NMP_OBJECT_TYPE_TO_ADDR_FAMILY(NMPObjectType obj_type)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue