NetworkManager/src/libnm-platform/nmp-base.h
Rahul Rajesh 4f3333bdea platform: add support for GENEVE tunnels
GENEVE (Generic Network Virtualization Encapsulation) is a network
tunneling protocol that provides a flexible encapsulation format for
overlay networks. It uses UDP as the transport protocol and supports
variable-length metadata in the tunnel header.

This patch adds GENEVE tunnel to NM's platform layer:

- Add platform API functions (nm_platform_link_geneve_add,
  nm_platform_link_get_lnk_geneve)

- Netlink message parsing for the following attributes:
  * IFLA_GENEVE_ID - VNI (Virtual Network Identifier)
  IPv4 and IPv6 remote
  * IFLA_GENEVE_REMOTE
  * IFLA_GENEVE_REMOTE6
  TTL, TOS, and DF flags
  * IFLA_GENEVE_TTL
  * IFLA_GENEVE_TOS
  * IFLA_GENEVE_DF
  UDP destination port
  * IFLA_GENEVE_PORT

- Add test cases for GENEVE tunnel creation and detection with two test
  modes covering IPv4 and IPv6.

The implementation tries to follow the same patterns as other tunnel
types (GRE, VXLAN, etc.) and integrates with the existing platform
abstraction layer.

(cherry picked from commit 29c8bbe21a)
2026-05-07 14:09:16 +02:00

243 lines
7.7 KiB
C

/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef __NMP_FWD_H__
#define __NMP_FWD_H__
#include "libnm-base/nm-base.h"
/*****************************************************************************/
#define NM_PLATFORM_LIFETIME_PERMANENT G_MAXUINT32
/*****************************************************************************/
/* Define of the IN6_ADDR_GEN_MODE_* values to workaround old kernel headers
* that don't define it. */
#define NM_IN6_ADDR_GEN_MODE_UNKNOWN 255 /* no corresponding value. */
#define NM_IN6_ADDR_GEN_MODE_EUI64 0 /* IN6_ADDR_GEN_MODE_EUI64 */
#define NM_IN6_ADDR_GEN_MODE_NONE 1 /* IN6_ADDR_GEN_MODE_NONE */
#define NM_IN6_ADDR_GEN_MODE_STABLE_PRIVACY 2 /* IN6_ADDR_GEN_MODE_STABLE_PRIVACY */
#define NM_IN6_ADDR_GEN_MODE_RANDOM 3 /* IN6_ADDR_GEN_MODE_RANDOM */
/*****************************************************************************/
typedef enum {
NM_PLATFORM_SIGNAL_NONE,
NM_PLATFORM_SIGNAL_ADDED,
NM_PLATFORM_SIGNAL_CHANGED,
NM_PLATFORM_SIGNAL_REMOVED,
} NMPlatformSignalChangeType;
/*****************************************************************************/
typedef enum {
NM_PLATFORM_LINK_DUPLEX_UNKNOWN,
NM_PLATFORM_LINK_DUPLEX_HALF,
NM_PLATFORM_LINK_DUPLEX_FULL,
} NMPlatformLinkDuplexType;
/*****************************************************************************/
typedef struct {
guint16 vid_start;
guint16 vid_end;
bool untagged : 1;
bool pvid : 1;
} NMPlatformBridgeVlan;
/*****************************************************************************/
typedef struct {
/* We don't want to include <linux/ethtool.h> in header files,
* thus create a ABI compatible version of struct ethtool_drvinfo.*/
guint32 _private_cmd;
char driver[32];
char version[32];
char fw_version[32];
char _private_bus_info[32];
char _private_erom_version[32];
char _private_reserved2[12];
guint32 _private_n_priv_flags;
guint32 _private_n_stats;
guint32 _private_testinfo_len;
guint32 _private_eedump_len;
guint32 _private_regdump_len;
} NMPUtilsEthtoolDriverInfo;
typedef struct {
NMEthtoolID ethtool_id;
guint8 n_kernel_names;
/* one NMEthtoolID refers to one or more kernel_names. The reason for supporting this complexity
* (where one NMSettingEthtool option refers to multiple kernel features) is to follow what
* ethtool does, where "tx" is an alias for multiple features. */
const char *const *kernel_names;
} NMEthtoolFeatureInfo;
typedef struct {
const NMEthtoolFeatureInfo *info;
guint idx_ss_features;
/* one NMEthtoolFeatureInfo references one or more kernel_names. This is the index
* of the matching info->kernel_names */
guint8 idx_kernel_name;
bool available : 1;
bool requested : 1;
bool active : 1;
bool never_changed : 1;
} NMEthtoolFeatureState;
typedef struct {
guint n_states;
guint n_ss_features;
/* indexed by NMEthtoolID - _NM_ETHTOOL_ID_FEATURE_FIRST */
const NMEthtoolFeatureState *const *states_indexed[_NM_ETHTOOL_ID_FEATURE_NUM];
/* the same content, here as a list of n_states entries. */
const NMEthtoolFeatureState states_list[];
} NMEthtoolFeatureStates;
typedef struct {
guint32
s[_NM_ETHTOOL_ID_COALESCE_NUM /* indexed by (NMEthtoolID - _NM_ETHTOOL_ID_COALESCE_FIRST) */
];
} NMEthtoolCoalesceState;
typedef struct {
guint32 rx_pending;
guint32 rx_mini_pending;
guint32 rx_jumbo_pending;
guint32 tx_pending;
} NMEthtoolRingState;
typedef struct {
bool autoneg : 1;
bool rx : 1;
bool tx : 1;
} NMEthtoolPauseState;
typedef struct {
guint32 rx;
guint32 tx;
guint32 other;
guint32 combined;
} NMEthtoolChannelsState;
typedef struct {
bool enabled : 1;
} NMEthtoolEEEState;
/*****************************************************************************/
typedef struct _NMPNetns NMPNetns;
typedef struct _NMPlatform NMPlatform;
typedef struct _NMPlatformObject NMPlatformObject;
typedef struct _NMPlatformObjWithIfindex NMPlatformObjWithIfindex;
typedef struct _NMPlatformIP4Address NMPlatformIP4Address;
typedef struct _NMPlatformIP4Route NMPlatformIP4Route;
typedef struct _NMPlatformIP6Address NMPlatformIP6Address;
typedef struct _NMPlatformIP6Route NMPlatformIP6Route;
typedef struct _NMPlatformLink NMPlatformLink;
typedef struct _NMPObject NMPObject;
typedef enum _nm_packed {
NMP_OBJECT_TYPE_UNKNOWN,
NMP_OBJECT_TYPE_LINK,
#define NMP_OBJECT_TYPE_IP_ADDRESS(is_ipv4) \
((is_ipv4) ? NMP_OBJECT_TYPE_IP4_ADDRESS : NMP_OBJECT_TYPE_IP6_ADDRESS)
NMP_OBJECT_TYPE_IP4_ADDRESS,
NMP_OBJECT_TYPE_IP6_ADDRESS,
#define NMP_OBJECT_TYPE_IP_ROUTE(is_ipv4) \
((is_ipv4) ? NMP_OBJECT_TYPE_IP4_ROUTE : NMP_OBJECT_TYPE_IP6_ROUTE)
NMP_OBJECT_TYPE_IP4_ROUTE,
NMP_OBJECT_TYPE_IP6_ROUTE,
NMP_OBJECT_TYPE_ROUTING_RULE,
NMP_OBJECT_TYPE_QDISC,
NMP_OBJECT_TYPE_TFILTER,
NMP_OBJECT_TYPE_LNK_BRIDGE,
NMP_OBJECT_TYPE_LNK_GENEVE,
NMP_OBJECT_TYPE_LNK_GRE,
NMP_OBJECT_TYPE_LNK_GRETAP,
NMP_OBJECT_TYPE_LNK_HSR,
NMP_OBJECT_TYPE_LNK_INFINIBAND,
NMP_OBJECT_TYPE_LNK_IP6TNL,
NMP_OBJECT_TYPE_LNK_IP6GRE,
NMP_OBJECT_TYPE_LNK_IP6GRETAP,
NMP_OBJECT_TYPE_LNK_IPIP,
NMP_OBJECT_TYPE_LNK_IPVLAN,
NMP_OBJECT_TYPE_LNK_MACSEC,
NMP_OBJECT_TYPE_LNK_MACVLAN,
NMP_OBJECT_TYPE_LNK_MACVTAP,
NMP_OBJECT_TYPE_LNK_SIT,
NMP_OBJECT_TYPE_LNK_TUN,
NMP_OBJECT_TYPE_LNK_VLAN,
NMP_OBJECT_TYPE_LNK_VRF,
NMP_OBJECT_TYPE_LNK_VTI,
NMP_OBJECT_TYPE_LNK_VTI6,
NMP_OBJECT_TYPE_LNK_VXLAN,
NMP_OBJECT_TYPE_LNK_WIREGUARD,
NMP_OBJECT_TYPE_LNK_BOND,
NMP_OBJECT_TYPE_MPTCP_ADDR,
__NMP_OBJECT_TYPE_LAST,
NMP_OBJECT_TYPE_MAX = __NMP_OBJECT_TYPE_LAST - 1,
} NMPObjectType;
static inline guint64
nmp_object_type_to_flags(NMPObjectType obj_type)
{
G_STATIC_ASSERT_EXPR(NMP_OBJECT_TYPE_MAX < 64);
nm_assert(_NM_INT_NOT_NEGATIVE(obj_type));
nm_assert(obj_type < NMP_OBJECT_TYPE_MAX);
return ((guint64) 1u) << obj_type;
}
/*****************************************************************************/
/**
* NMIPRouteTableSyncMode:
* @NM_IP_ROUTE_TABLE_SYNC_MODE_NONE: indicate an invalid setting.
* @NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN: only the main table is synced. For all
* other tables, NM won't delete any extra routes.
* @NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN_AND_NM_ROUTES: only the main table is synced,
* plus individual routes in other tables added by NM, leaving routes that
* were not added by NM untouched.
* @NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_EXCEPT_LOCAL: NM will sync all tables, except
* the local table (255).
* @NM_IP_ROUTE_TABLE_SYNC_MODE_ALL: NM will sync all tables, including the
* local table (255).
* @NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_PRUNE: NM will sync all tables (including
* the local table). It will thereby remove all addresses, that is during
* deactivation.
*/
typedef enum {
NM_IP_ROUTE_TABLE_SYNC_MODE_NONE,
NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN,
NM_IP_ROUTE_TABLE_SYNC_MODE_MAIN_AND_NM_ROUTES,
NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_EXCEPT_LOCAL,
NM_IP_ROUTE_TABLE_SYNC_MODE_ALL,
NM_IP_ROUTE_TABLE_SYNC_MODE_ALL_PRUNE,
} NMIPRouteTableSyncMode;
/*****************************************************************************/
const char *nm_platform_link_flags2str(unsigned flags, char *buf, gsize len);
const char *nm_platform_link_inet6_addrgenmode2str(guint8 mode, char *buf, gsize len);
const char *nm_platform_addr_flags2str(unsigned flags, char *buf, gsize len);
const char *nm_platform_route_scope2str(int scope, char *buf, gsize len);
#endif /* __NMP_FWD_H__ */