mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-03 11:40:18 +01:00
platform: merge branch 'th/platform-genl-4'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1304
This commit is contained in:
commit
571f3c57bd
12 changed files with 490 additions and 66 deletions
|
|
@ -590,8 +590,9 @@ src_libnm_platform_libnm_platform_la_CPPFLAGS = \
|
|||
src_libnm_platform_libnm_platform_la_SOURCES = \
|
||||
\
|
||||
src/linux-headers/ethtool.h \
|
||||
src/linux-headers/nl802154.h \
|
||||
src/linux-headers/mptcp.h \
|
||||
src/linux-headers/nl80211-vnd-intel.h \
|
||||
src/linux-headers/nl802154.h \
|
||||
\
|
||||
src/libnm-platform/nm-linux-platform.c \
|
||||
src/libnm-platform/nm-linux-platform.h \
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ nm_hash_update_bool(NMHashState *state, bool val)
|
|||
#define NM_HASH_COMBINE_VALS(var, ...) \
|
||||
const struct _nm_packed { \
|
||||
NM_VA_ARGS_FOREACH(, , , _NM_HASH_COMBINE_VALS_TYPE_OP, __VA_ARGS__) \
|
||||
} var _nm_alignas(guint64) = { \
|
||||
} var _nm_alignas(max_align_t) = { \
|
||||
NM_VA_ARGS_FOREACH(, , , _NM_HASH_COMBINE_VALS_INIT_OP, __VA_ARGS__)}
|
||||
|
||||
/* nm_hash_update_vals() is faster then nm_hash_update_val() as it combines multiple
|
||||
|
|
|
|||
|
|
@ -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. */
|
||||
|
||||
|
|
@ -4780,7 +4789,7 @@ _nl_msg_new_address(uint16_t nlmsg_type,
|
|||
guint8 plen,
|
||||
gconstpointer peer_address,
|
||||
guint32 flags,
|
||||
int scope,
|
||||
guint8 scope,
|
||||
guint32 lifetime,
|
||||
guint32 preferred,
|
||||
in_addr_t ip4_broadcast_address,
|
||||
|
|
@ -4792,6 +4801,7 @@ _nl_msg_new_address(uint16_t nlmsg_type,
|
|||
.ifa_index = ifindex,
|
||||
.ifa_prefixlen = plen,
|
||||
.ifa_flags = flags,
|
||||
.ifa_scope = scope,
|
||||
};
|
||||
gsize addr_len;
|
||||
|
||||
|
|
@ -4800,15 +4810,6 @@ _nl_msg_new_address(uint16_t nlmsg_type,
|
|||
|
||||
msg = nlmsg_alloc_simple(nlmsg_type, nlmsg_flags);
|
||||
|
||||
if (scope == -1) {
|
||||
/* Allow having scope unset, and detect the scope (including IPv4 compatibility hack). */
|
||||
if (family == AF_INET && address && *((char *) address) == 127)
|
||||
scope = RT_SCOPE_HOST;
|
||||
else
|
||||
scope = RT_SCOPE_UNIVERSE;
|
||||
}
|
||||
am.ifa_scope = scope,
|
||||
|
||||
addr_len = family == AF_INET ? sizeof(in_addr_t) : sizeof(struct in6_addr);
|
||||
|
||||
if (nlmsg_append_struct(msg, &am) < 0)
|
||||
|
|
|
|||
|
|
@ -619,6 +619,7 @@ nla_nest_end(struct nl_msg *msg, struct nlattr *start)
|
|||
static const uint8_t nla_attr_minlen[NLA_TYPE_MAX + 1] = {
|
||||
[NLA_U8] = sizeof(uint8_t),
|
||||
[NLA_U16] = sizeof(uint16_t),
|
||||
[NLA_S32] = sizeof(int32_t),
|
||||
[NLA_U32] = sizeof(uint32_t),
|
||||
[NLA_U64] = sizeof(uint64_t),
|
||||
[NLA_STRING] = 1,
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ enum {
|
|||
NLA_UNSPEC, /* Unspecified type, binary data chunk */
|
||||
NLA_U8, /* 8 bit integer */
|
||||
NLA_U16, /* 16 bit integer */
|
||||
NLA_S32, /* 32 bit integer */
|
||||
NLA_U32, /* 32 bit integer */
|
||||
NLA_U64, /* 64 bit integer */
|
||||
NLA_STRING, /* NUL terminated character string */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -20,25 +20,26 @@
|
|||
/*****************************************************************************/
|
||||
|
||||
#define _NMLOG_DOMAIN LOGD_PLATFORM
|
||||
#define _NMLOG(level, obj, ...) \
|
||||
G_STMT_START \
|
||||
{ \
|
||||
const NMLogLevel __level = (level); \
|
||||
\
|
||||
if (nm_logging_enabled(__level, _NMLOG_DOMAIN)) { \
|
||||
const NMPObject *const __obj = (obj); \
|
||||
\
|
||||
_nm_log(__level, \
|
||||
_NMLOG_DOMAIN, \
|
||||
0, \
|
||||
NULL, \
|
||||
NULL, \
|
||||
"nmp-object[%p/%s]: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \
|
||||
__obj, \
|
||||
(__obj ? NMP_OBJECT_GET_CLASS(__obj)->obj_type_name \
|
||||
: "???") _NM_UTILS_MACRO_REST(__VA_ARGS__)); \
|
||||
} \
|
||||
} \
|
||||
#define _NMLOG(level, obj, ...) \
|
||||
G_STMT_START \
|
||||
{ \
|
||||
const NMLogLevel __level = (level); \
|
||||
\
|
||||
if (nm_logging_enabled(__level, _NMLOG_DOMAIN)) { \
|
||||
const NMPObject *const __obj = (obj); \
|
||||
\
|
||||
_nm_log(__level, \
|
||||
_NMLOG_DOMAIN, \
|
||||
0, \
|
||||
NULL, \
|
||||
NULL, \
|
||||
"nmp-object[" NM_HASH_OBFUSCATE_PTR_FMT "" \
|
||||
"/%s]: " _NM_UTILS_MACRO_FIRST(__VA_ARGS__), \
|
||||
NM_HASH_OBFUSCATE_PTR(__obj), \
|
||||
(__obj ? NMP_OBJECT_GET_CLASS(__obj)->obj_type_name \
|
||||
: "???") _NM_UTILS_MACRO_REST(__VA_ARGS__)); \
|
||||
} \
|
||||
} \
|
||||
G_STMT_END
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -380,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);
|
||||
|
|
@ -840,6 +842,17 @@ nmp_object_stackinit_id(NMPObject *obj, const NMPObject *src)
|
|||
_nmp_object_stackinit_from_class(obj, klass);
|
||||
if (klass->cmd_plobj_id_copy)
|
||||
klass->cmd_plobj_id_copy(&obj->object, &src->object);
|
||||
else {
|
||||
/* This object must not implement cmd_obj_copy().
|
||||
* If it would, it would mean that we require a deep copy
|
||||
* of the data. As @obj is stack-allocated, it cannot track
|
||||
* ownership. The caller must not use nmp_object_stackinit_id()
|
||||
* with an object of such a type. */
|
||||
nm_assert(!klass->cmd_obj_copy);
|
||||
|
||||
/* plain memcpy of the public part suffices. */
|
||||
memcpy(&obj->object, &src->object, klass->sizeof_data);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
|
@ -900,7 +913,7 @@ nmp_object_to_string(const NMPObject *obj,
|
|||
switch (to_string_mode) {
|
||||
case NMP_OBJECT_TO_STRING_ID:
|
||||
if (!klass->cmd_plobj_to_string_id) {
|
||||
g_snprintf(buf, buf_size, "%p", obj);
|
||||
g_snprintf(buf, buf_size, NM_HASH_OBFUSCATE_PTR_FMT, NM_HASH_OBFUSCATE_PTR(obj));
|
||||
return buf;
|
||||
}
|
||||
return klass->cmd_plobj_to_string_id(&obj->object, buf, buf_size);
|
||||
|
|
@ -908,9 +921,9 @@ nmp_object_to_string(const NMPObject *obj,
|
|||
g_snprintf(
|
||||
buf,
|
||||
buf_size,
|
||||
"[%s,%p,%u,%calive,%cvisible; %s]",
|
||||
"[%s," NM_HASH_OBFUSCATE_PTR_FMT ",%u,%calive,%cvisible; %s]",
|
||||
klass->obj_type_name,
|
||||
obj,
|
||||
NM_HASH_OBFUSCATE_PTR(obj),
|
||||
obj->parent._ref_count,
|
||||
nmp_object_is_alive(obj) ? '+' : '-',
|
||||
nmp_object_is_visible(obj) ? '+' : '-',
|
||||
|
|
@ -939,14 +952,15 @@ _vt_cmd_obj_to_string_link(const NMPObject *obj,
|
|||
case NMP_OBJECT_TO_STRING_ALL:
|
||||
nm_strbuf_append(&b,
|
||||
&buf_size,
|
||||
"[%s,%p,%u,%calive,%cvisible,%cin-nl,%p; ",
|
||||
"[%s," NM_HASH_OBFUSCATE_PTR_FMT
|
||||
",%u,%calive,%cvisible,%cin-nl," NM_HASH_OBFUSCATE_PTR_FMT "; ",
|
||||
klass->obj_type_name,
|
||||
obj,
|
||||
NM_HASH_OBFUSCATE_PTR(obj),
|
||||
obj->parent._ref_count,
|
||||
nmp_object_is_alive(obj) ? '+' : '-',
|
||||
nmp_object_is_visible(obj) ? '+' : '-',
|
||||
obj->_link.netlink.is_in_netlink ? '+' : '-',
|
||||
obj->_link.udev.device);
|
||||
NM_HASH_OBFUSCATE_PTR(obj->_link.udev.device));
|
||||
NMP_OBJECT_GET_CLASS(obj)->cmd_plobj_to_string(&obj->object, b, buf_size);
|
||||
nm_strbuf_seek_end(&b, &buf_size);
|
||||
if (obj->_link.netlink.lnk) {
|
||||
|
|
@ -984,15 +998,15 @@ _vt_cmd_obj_to_string_lnk_vlan(const NMPObject *obj,
|
|||
|
||||
switch (to_string_mode) {
|
||||
case NMP_OBJECT_TO_STRING_ID:
|
||||
g_snprintf(buf, buf_size, "%p", obj);
|
||||
g_snprintf(buf, buf_size, NM_HASH_OBFUSCATE_PTR_FMT, NM_HASH_OBFUSCATE_PTR(obj));
|
||||
return buf;
|
||||
case NMP_OBJECT_TO_STRING_ALL:
|
||||
|
||||
g_snprintf(buf,
|
||||
buf_size,
|
||||
"[%s,%p,%u,%calive,%cvisible; %s]",
|
||||
"[%s," NM_HASH_OBFUSCATE_PTR_FMT ",%u,%calive,%cvisible; %s]",
|
||||
klass->obj_type_name,
|
||||
obj,
|
||||
NM_HASH_OBFUSCATE_PTR(obj),
|
||||
obj->parent._ref_count,
|
||||
nmp_object_is_alive(obj) ? '+' : '-',
|
||||
nmp_object_is_visible(obj) ? '+' : '-',
|
||||
|
|
@ -1048,17 +1062,17 @@ _vt_cmd_obj_to_string_lnk_wireguard(const NMPObject *obj,
|
|||
|
||||
switch (to_string_mode) {
|
||||
case NMP_OBJECT_TO_STRING_ID:
|
||||
g_snprintf(buf, buf_size, "%p", obj);
|
||||
g_snprintf(buf, buf_size, NM_HASH_OBFUSCATE_PTR_FMT, NM_HASH_OBFUSCATE_PTR(obj));
|
||||
return buf;
|
||||
case NMP_OBJECT_TO_STRING_ALL:
|
||||
b = buf;
|
||||
|
||||
nm_strbuf_append(&b,
|
||||
&buf_size,
|
||||
"[%s,%p,%u,%calive,%cvisible; %s"
|
||||
"[%s," NM_HASH_OBFUSCATE_PTR_FMT ",%u,%calive,%cvisible; %s"
|
||||
"%s",
|
||||
klass->obj_type_name,
|
||||
obj,
|
||||
NM_HASH_OBFUSCATE_PTR(obj),
|
||||
obj->parent._ref_count,
|
||||
nmp_object_is_alive(obj) ? '+' : '-',
|
||||
nmp_object_is_visible(obj) ? '+' : '-',
|
||||
|
|
@ -1420,21 +1434,6 @@ _vt_cmd_plobj_id_copy(ip6_address, NMPlatformIP6Address, {
|
|||
dst->address = src->address;
|
||||
});
|
||||
|
||||
_vt_cmd_plobj_id_copy(ip4_route, NMPlatformIP4Route, {
|
||||
*dst = *src;
|
||||
nm_assert(nm_platform_ip4_route_cmp(dst, src, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) == 0);
|
||||
});
|
||||
|
||||
_vt_cmd_plobj_id_copy(ip6_route, NMPlatformIP6Route, {
|
||||
*dst = *src;
|
||||
nm_assert(nm_platform_ip6_route_cmp(dst, src, NM_PLATFORM_IP_ROUTE_CMP_TYPE_ID) == 0);
|
||||
});
|
||||
|
||||
_vt_cmd_plobj_id_copy(routing_rule, NMPlatformRoutingRule, {
|
||||
*dst = *src;
|
||||
nm_assert(nm_platform_routing_rule_cmp(dst, src, NM_PLATFORM_ROUTING_RULE_CMP_TYPE_ID) == 0);
|
||||
});
|
||||
|
||||
/* Uses internally nmp_object_copy(), hence it also violates the const
|
||||
* promise for @obj.
|
||||
* */
|
||||
|
|
@ -1553,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)
|
||||
{
|
||||
|
|
@ -1638,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)
|
||||
{
|
||||
|
|
@ -1746,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)
|
||||
{
|
||||
|
|
@ -2091,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);
|
||||
|
|
@ -2125,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)));
|
||||
|
|
@ -3166,7 +3198,6 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = {
|
|||
.signal_type = NM_PLATFORM_SIGNAL_IP4_ROUTE_CHANGED,
|
||||
.supported_cache_ids = _supported_cache_ids_ipx_route,
|
||||
.cmd_obj_is_alive = _vt_cmd_obj_is_alive_ipx_route,
|
||||
.cmd_plobj_id_copy = _vt_cmd_plobj_id_copy_ip4_route,
|
||||
.cmd_plobj_id_cmp = _vt_cmd_plobj_id_cmp_ip4_route,
|
||||
.cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_ip4_route,
|
||||
.cmd_plobj_to_string_id = (CmdPlobjToStringIdFunc) nm_platform_ip4_route_to_string,
|
||||
|
|
@ -3187,7 +3218,6 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = {
|
|||
.signal_type = NM_PLATFORM_SIGNAL_IP6_ROUTE_CHANGED,
|
||||
.supported_cache_ids = _supported_cache_ids_ipx_route,
|
||||
.cmd_obj_is_alive = _vt_cmd_obj_is_alive_ipx_route,
|
||||
.cmd_plobj_id_copy = _vt_cmd_plobj_id_copy_ip6_route,
|
||||
.cmd_plobj_id_cmp = _vt_cmd_plobj_id_cmp_ip6_route,
|
||||
.cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_ip6_route,
|
||||
.cmd_plobj_to_string_id = (CmdPlobjToStringIdFunc) nm_platform_ip6_route_to_string,
|
||||
|
|
@ -3207,7 +3237,6 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = {
|
|||
.signal_type = NM_PLATFORM_SIGNAL_ROUTING_RULE_CHANGED,
|
||||
.supported_cache_ids = _supported_cache_ids_routing_rules,
|
||||
.cmd_obj_is_alive = _vt_cmd_obj_is_alive_routing_rule,
|
||||
.cmd_plobj_id_copy = _vt_cmd_plobj_id_copy_routing_rule,
|
||||
.cmd_plobj_id_cmp = _vt_cmd_plobj_id_cmp_routing_rule,
|
||||
.cmd_plobj_id_hash_update = _vt_cmd_plobj_id_hash_update_routing_rule,
|
||||
.cmd_plobj_to_string_id = (CmdPlobjToStringIdFunc) nm_platform_routing_rule_to_string,
|
||||
|
|
@ -3468,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)
|
||||
|
|
|
|||
|
|
@ -487,6 +487,17 @@ nm_streq0(const char *s1, const char *s2)
|
|||
return (s1 == s2) || (s1 && s2 && strcmp(s1, s2) == 0);
|
||||
}
|
||||
|
||||
static inline int
|
||||
nm_memcmp(const void *s1, const void *s2, size_t n)
|
||||
{
|
||||
/* Workaround undefined behavior in memcmp() with NULL pointers. */
|
||||
if (n == 0)
|
||||
return 0;
|
||||
nm_assert(s1);
|
||||
nm_assert(s2);
|
||||
return memcmp(s1, s2, n);
|
||||
}
|
||||
|
||||
/*
|
||||
* Very similar to g_str_has_prefix() with the obvious meaning.
|
||||
* Differences:
|
||||
|
|
@ -1163,7 +1174,7 @@ nm_ptr_to_uintptr(const void *p)
|
|||
|
||||
#define NM_CMP_DIRECT_BOOL(a, b) NM_CMP_DIRECT(!!(a), !!(b))
|
||||
|
||||
#define NM_CMP_DIRECT_MEMCMP(a, b, size) NM_CMP_RETURN(memcmp((a), (b), (size)))
|
||||
#define NM_CMP_DIRECT_MEMCMP(a, b, size) NM_CMP_RETURN(nm_memcmp((a), (b), (size)))
|
||||
|
||||
#define NM_CMP_DIRECT_STRCMP(a, b) NM_CMP_RETURN_DIRECT(strcmp((a), (b)))
|
||||
|
||||
|
|
|
|||
232
src/linux-headers/mptcp.h
Normal file
232
src/linux-headers/mptcp.h
Normal file
|
|
@ -0,0 +1,232 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
|
||||
#ifndef _MPTCP_H
|
||||
#define _MPTCP_H
|
||||
|
||||
#include <linux/const.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/in.h> /* for sockaddr_in */
|
||||
#include <linux/in6.h> /* for sockaddr_in6 */
|
||||
#include <linux/socket.h> /* for sockaddr_storage and sa_family */
|
||||
|
||||
#include <sys/socket.h> /* for struct sockaddr */
|
||||
|
||||
#define MPTCP_SUBFLOW_FLAG_MCAP_REM _BITUL(0)
|
||||
#define MPTCP_SUBFLOW_FLAG_MCAP_LOC _BITUL(1)
|
||||
#define MPTCP_SUBFLOW_FLAG_JOIN_REM _BITUL(2)
|
||||
#define MPTCP_SUBFLOW_FLAG_JOIN_LOC _BITUL(3)
|
||||
#define MPTCP_SUBFLOW_FLAG_BKUP_REM _BITUL(4)
|
||||
#define MPTCP_SUBFLOW_FLAG_BKUP_LOC _BITUL(5)
|
||||
#define MPTCP_SUBFLOW_FLAG_FULLY_ESTABLISHED _BITUL(6)
|
||||
#define MPTCP_SUBFLOW_FLAG_CONNECTED _BITUL(7)
|
||||
#define MPTCP_SUBFLOW_FLAG_MAPVALID _BITUL(8)
|
||||
|
||||
enum {
|
||||
MPTCP_SUBFLOW_ATTR_UNSPEC,
|
||||
MPTCP_SUBFLOW_ATTR_TOKEN_REM,
|
||||
MPTCP_SUBFLOW_ATTR_TOKEN_LOC,
|
||||
MPTCP_SUBFLOW_ATTR_RELWRITE_SEQ,
|
||||
MPTCP_SUBFLOW_ATTR_MAP_SEQ,
|
||||
MPTCP_SUBFLOW_ATTR_MAP_SFSEQ,
|
||||
MPTCP_SUBFLOW_ATTR_SSN_OFFSET,
|
||||
MPTCP_SUBFLOW_ATTR_MAP_DATALEN,
|
||||
MPTCP_SUBFLOW_ATTR_FLAGS,
|
||||
MPTCP_SUBFLOW_ATTR_ID_REM,
|
||||
MPTCP_SUBFLOW_ATTR_ID_LOC,
|
||||
MPTCP_SUBFLOW_ATTR_PAD,
|
||||
__MPTCP_SUBFLOW_ATTR_MAX
|
||||
};
|
||||
|
||||
#define MPTCP_SUBFLOW_ATTR_MAX (__MPTCP_SUBFLOW_ATTR_MAX - 1)
|
||||
|
||||
/* netlink interface */
|
||||
#define MPTCP_PM_NAME "mptcp_pm"
|
||||
#define MPTCP_PM_CMD_GRP_NAME "mptcp_pm_cmds"
|
||||
#define MPTCP_PM_EV_GRP_NAME "mptcp_pm_events"
|
||||
#define MPTCP_PM_VER 0x1
|
||||
|
||||
/*
|
||||
* ATTR types defined for MPTCP
|
||||
*/
|
||||
enum {
|
||||
MPTCP_PM_ATTR_UNSPEC,
|
||||
|
||||
MPTCP_PM_ATTR_ADDR, /* nested address */
|
||||
MPTCP_PM_ATTR_RCV_ADD_ADDRS, /* u32 */
|
||||
MPTCP_PM_ATTR_SUBFLOWS, /* u32 */
|
||||
|
||||
__MPTCP_PM_ATTR_MAX
|
||||
};
|
||||
|
||||
#define MPTCP_PM_ATTR_MAX (__MPTCP_PM_ATTR_MAX - 1)
|
||||
|
||||
enum {
|
||||
MPTCP_PM_ADDR_ATTR_UNSPEC,
|
||||
|
||||
MPTCP_PM_ADDR_ATTR_FAMILY, /* u16 */
|
||||
MPTCP_PM_ADDR_ATTR_ID, /* u8 */
|
||||
MPTCP_PM_ADDR_ATTR_ADDR4, /* struct in_addr */
|
||||
MPTCP_PM_ADDR_ATTR_ADDR6, /* struct in6_addr */
|
||||
MPTCP_PM_ADDR_ATTR_PORT, /* u16 */
|
||||
MPTCP_PM_ADDR_ATTR_FLAGS, /* u32 */
|
||||
MPTCP_PM_ADDR_ATTR_IF_IDX, /* s32 */
|
||||
|
||||
__MPTCP_PM_ADDR_ATTR_MAX
|
||||
};
|
||||
|
||||
#define MPTCP_PM_ADDR_ATTR_MAX (__MPTCP_PM_ADDR_ATTR_MAX - 1)
|
||||
|
||||
#define MPTCP_PM_ADDR_FLAG_SIGNAL (1 << 0)
|
||||
#define MPTCP_PM_ADDR_FLAG_SUBFLOW (1 << 1)
|
||||
#define MPTCP_PM_ADDR_FLAG_BACKUP (1 << 2)
|
||||
#define MPTCP_PM_ADDR_FLAG_FULLMESH (1 << 3)
|
||||
#define MPTCP_PM_ADDR_FLAG_IMPLICIT (1 << 4)
|
||||
|
||||
enum {
|
||||
MPTCP_PM_CMD_UNSPEC,
|
||||
|
||||
MPTCP_PM_CMD_ADD_ADDR,
|
||||
MPTCP_PM_CMD_DEL_ADDR,
|
||||
MPTCP_PM_CMD_GET_ADDR,
|
||||
MPTCP_PM_CMD_FLUSH_ADDRS,
|
||||
MPTCP_PM_CMD_SET_LIMITS,
|
||||
MPTCP_PM_CMD_GET_LIMITS,
|
||||
MPTCP_PM_CMD_SET_FLAGS,
|
||||
|
||||
__MPTCP_PM_CMD_AFTER_LAST
|
||||
};
|
||||
|
||||
#define MPTCP_INFO_FLAG_FALLBACK _BITUL(0)
|
||||
#define MPTCP_INFO_FLAG_REMOTE_KEY_RECEIVED _BITUL(1)
|
||||
|
||||
struct mptcp_info {
|
||||
__u8 mptcpi_subflows;
|
||||
__u8 mptcpi_add_addr_signal;
|
||||
__u8 mptcpi_add_addr_accepted;
|
||||
__u8 mptcpi_subflows_max;
|
||||
__u8 mptcpi_add_addr_signal_max;
|
||||
__u8 mptcpi_add_addr_accepted_max;
|
||||
__u32 mptcpi_flags;
|
||||
__u32 mptcpi_token;
|
||||
__u64 mptcpi_write_seq;
|
||||
__u64 mptcpi_snd_una;
|
||||
__u64 mptcpi_rcv_nxt;
|
||||
__u8 mptcpi_local_addr_used;
|
||||
__u8 mptcpi_local_addr_max;
|
||||
__u8 mptcpi_csum_enabled;
|
||||
};
|
||||
|
||||
/*
|
||||
* MPTCP_EVENT_CREATED: token, family, saddr4 | saddr6, daddr4 | daddr6,
|
||||
* sport, dport
|
||||
* A new MPTCP connection has been created. It is the good time to allocate
|
||||
* memory and send ADD_ADDR if needed. Depending on the traffic-patterns
|
||||
* it can take a long time until the MPTCP_EVENT_ESTABLISHED is sent.
|
||||
*
|
||||
* MPTCP_EVENT_ESTABLISHED: token, family, saddr4 | saddr6, daddr4 | daddr6,
|
||||
* sport, dport
|
||||
* A MPTCP connection is established (can start new subflows).
|
||||
*
|
||||
* MPTCP_EVENT_CLOSED: token
|
||||
* A MPTCP connection has stopped.
|
||||
*
|
||||
* MPTCP_EVENT_ANNOUNCED: token, rem_id, family, daddr4 | daddr6 [, dport]
|
||||
* A new address has been announced by the peer.
|
||||
*
|
||||
* MPTCP_EVENT_REMOVED: token, rem_id
|
||||
* An address has been lost by the peer.
|
||||
*
|
||||
* MPTCP_EVENT_SUB_ESTABLISHED: token, family, loc_id, rem_id,
|
||||
* saddr4 | saddr6, daddr4 | daddr6, sport,
|
||||
* dport, backup, if_idx [, error]
|
||||
* A new subflow has been established. 'error' should not be set.
|
||||
*
|
||||
* MPTCP_EVENT_SUB_CLOSED: token, family, loc_id, rem_id, saddr4 | saddr6,
|
||||
* daddr4 | daddr6, sport, dport, backup, if_idx
|
||||
* [, error]
|
||||
* A subflow has been closed. An error (copy of sk_err) could be set if an
|
||||
* error has been detected for this subflow.
|
||||
*
|
||||
* MPTCP_EVENT_SUB_PRIORITY: token, family, loc_id, rem_id, saddr4 | saddr6,
|
||||
* daddr4 | daddr6, sport, dport, backup, if_idx
|
||||
* [, error]
|
||||
* The priority of a subflow has changed. 'error' should not be set.
|
||||
*/
|
||||
enum mptcp_event_type {
|
||||
MPTCP_EVENT_UNSPEC = 0,
|
||||
MPTCP_EVENT_CREATED = 1,
|
||||
MPTCP_EVENT_ESTABLISHED = 2,
|
||||
MPTCP_EVENT_CLOSED = 3,
|
||||
|
||||
MPTCP_EVENT_ANNOUNCED = 6,
|
||||
MPTCP_EVENT_REMOVED = 7,
|
||||
|
||||
MPTCP_EVENT_SUB_ESTABLISHED = 10,
|
||||
MPTCP_EVENT_SUB_CLOSED = 11,
|
||||
|
||||
MPTCP_EVENT_SUB_PRIORITY = 13,
|
||||
};
|
||||
|
||||
enum mptcp_event_attr {
|
||||
MPTCP_ATTR_UNSPEC = 0,
|
||||
|
||||
MPTCP_ATTR_TOKEN, /* u32 */
|
||||
MPTCP_ATTR_FAMILY, /* u16 */
|
||||
MPTCP_ATTR_LOC_ID, /* u8 */
|
||||
MPTCP_ATTR_REM_ID, /* u8 */
|
||||
MPTCP_ATTR_SADDR4, /* be32 */
|
||||
MPTCP_ATTR_SADDR6, /* struct in6_addr */
|
||||
MPTCP_ATTR_DADDR4, /* be32 */
|
||||
MPTCP_ATTR_DADDR6, /* struct in6_addr */
|
||||
MPTCP_ATTR_SPORT, /* be16 */
|
||||
MPTCP_ATTR_DPORT, /* be16 */
|
||||
MPTCP_ATTR_BACKUP, /* u8 */
|
||||
MPTCP_ATTR_ERROR, /* u8 */
|
||||
MPTCP_ATTR_FLAGS, /* u16 */
|
||||
MPTCP_ATTR_TIMEOUT, /* u32 */
|
||||
MPTCP_ATTR_IF_IDX, /* s32 */
|
||||
MPTCP_ATTR_RESET_REASON,/* u32 */
|
||||
MPTCP_ATTR_RESET_FLAGS, /* u32 */
|
||||
|
||||
__MPTCP_ATTR_AFTER_LAST
|
||||
};
|
||||
|
||||
#define MPTCP_ATTR_MAX (__MPTCP_ATTR_AFTER_LAST - 1)
|
||||
|
||||
/* MPTCP Reset reason codes, rfc8684 */
|
||||
#define MPTCP_RST_EUNSPEC 0
|
||||
#define MPTCP_RST_EMPTCP 1
|
||||
#define MPTCP_RST_ERESOURCE 2
|
||||
#define MPTCP_RST_EPROHIBIT 3
|
||||
#define MPTCP_RST_EWQ2BIG 4
|
||||
#define MPTCP_RST_EBADPERF 5
|
||||
#define MPTCP_RST_EMIDDLEBOX 6
|
||||
|
||||
struct mptcp_subflow_data {
|
||||
__u32 size_subflow_data; /* size of this structure in userspace */
|
||||
__u32 num_subflows; /* must be 0, set by kernel */
|
||||
__u32 size_kernel; /* must be 0, set by kernel */
|
||||
__u32 size_user; /* size of one element in data[] */
|
||||
} __attribute__((aligned(8)));
|
||||
|
||||
struct mptcp_subflow_addrs {
|
||||
union {
|
||||
__kernel_sa_family_t sa_family;
|
||||
struct sockaddr sa_local;
|
||||
struct sockaddr_in sin_local;
|
||||
struct sockaddr_in6 sin6_local;
|
||||
struct __kernel_sockaddr_storage ss_local;
|
||||
};
|
||||
union {
|
||||
struct sockaddr sa_remote;
|
||||
struct sockaddr_in sin_remote;
|
||||
struct sockaddr_in6 sin6_remote;
|
||||
struct __kernel_sockaddr_storage ss_remote;
|
||||
};
|
||||
};
|
||||
|
||||
/* MPTCP socket options */
|
||||
#define MPTCP_INFO 1
|
||||
#define MPTCP_TCPINFO 2
|
||||
#define MPTCP_SUBFLOW_ADDRS 3
|
||||
|
||||
#endif /* _MPTCP_H */
|
||||
Loading…
Add table
Reference in a new issue