mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-07-22 10:46:59 +00:00
platform: add VRF support
Add support for creating and parsing VRF links.
This commit is contained in:
parent
89d387f782
commit
7c73c6a038
|
@ -160,6 +160,7 @@ typedef enum {
|
|||
NM_LINK_TYPE_TUN,
|
||||
NM_LINK_TYPE_VETH,
|
||||
NM_LINK_TYPE_VLAN,
|
||||
NM_LINK_TYPE_VRF,
|
||||
NM_LINK_TYPE_VXLAN,
|
||||
NM_LINK_TYPE_WIREGUARD,
|
||||
|
||||
|
@ -197,6 +198,7 @@ typedef enum {
|
|||
NMP_OBJECT_TYPE_LNK_SIT,
|
||||
NMP_OBJECT_TYPE_LNK_TUN,
|
||||
NMP_OBJECT_TYPE_LNK_VLAN,
|
||||
NMP_OBJECT_TYPE_LNK_VRF,
|
||||
NMP_OBJECT_TYPE_LNK_VXLAN,
|
||||
NMP_OBJECT_TYPE_LNK_WIREGUARD,
|
||||
|
||||
|
|
|
@ -656,6 +656,7 @@ static const LinkDesc linktypes[] = {
|
|||
{ NM_LINK_TYPE_TUN, "tun", "tun", NULL },
|
||||
{ NM_LINK_TYPE_VETH, "veth", "veth", NULL },
|
||||
{ NM_LINK_TYPE_VLAN, "vlan", "vlan", "vlan" },
|
||||
{ NM_LINK_TYPE_VRF, "vrf", "vrf", "vrf" },
|
||||
{ NM_LINK_TYPE_VXLAN, "vxlan", "vxlan", "vxlan" },
|
||||
{ NM_LINK_TYPE_WIREGUARD, "wireguard", "wireguard", "wireguard" },
|
||||
|
||||
|
@ -1754,6 +1755,8 @@ _parse_lnk_vlan (const char *kind, struct nlattr *info_data)
|
|||
#undef IFLA_VXLAN_MAX
|
||||
#define IFLA_VXLAN_MAX IFLA_VXLAN_LOCAL6
|
||||
|
||||
#define IFLA_VRF_TABLE 1
|
||||
|
||||
/* older kernel header might not contain 'struct ifla_vxlan_port_range'.
|
||||
* Redefine it. */
|
||||
struct nm_ifla_vxlan_port_range {
|
||||
|
@ -1848,6 +1851,33 @@ _parse_lnk_vxlan (const char *kind, struct nlattr *info_data)
|
|||
return obj;
|
||||
}
|
||||
|
||||
static NMPObject *
|
||||
_parse_lnk_vrf (const char *kind, struct nlattr *info_data)
|
||||
{
|
||||
static const struct nla_policy policy[] = {
|
||||
[IFLA_VRF_TABLE] = { .type = NLA_U32 },
|
||||
};
|
||||
NMPlatformLnkVrf *props;
|
||||
struct nlattr *tb[G_N_ELEMENTS (policy)];
|
||||
NMPObject *obj;
|
||||
|
||||
if ( !info_data
|
||||
|| !nm_streq0 (kind, "vrf"))
|
||||
return NULL;
|
||||
|
||||
if (nla_parse_nested_arr (tb, info_data, policy) < 0)
|
||||
return NULL;
|
||||
|
||||
obj = nmp_object_new (NMP_OBJECT_TYPE_LNK_VRF, NULL);
|
||||
|
||||
props = &obj->lnk_vrf;
|
||||
|
||||
if (tb[IFLA_VRF_TABLE])
|
||||
props->table = nla_get_u32 (tb[IFLA_VRF_TABLE]);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static gboolean
|
||||
|
@ -2798,6 +2828,9 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr
|
|||
case NM_LINK_TYPE_VLAN:
|
||||
lnk_data = _parse_lnk_vlan (nl_info_kind, nl_info_data);
|
||||
break;
|
||||
case NM_LINK_TYPE_VRF:
|
||||
lnk_data = _parse_lnk_vrf (nl_info_kind, nl_info_data);
|
||||
break;
|
||||
case NM_LINK_TYPE_VXLAN:
|
||||
lnk_data = _parse_lnk_vxlan (nl_info_kind, nl_info_data);
|
||||
break;
|
||||
|
@ -3728,6 +3761,17 @@ _nl_msg_new_link_set_linkinfo (struct nl_msg *msg,
|
|||
}
|
||||
break;
|
||||
}
|
||||
case NM_LINK_TYPE_VRF: {
|
||||
const NMPlatformLnkVrf *props = extra_data;
|
||||
|
||||
nm_assert (extra_data);
|
||||
|
||||
if (!(data = nla_nest_start (msg, IFLA_INFO_DATA)))
|
||||
goto nla_put_failure;
|
||||
|
||||
NLA_PUT_U32 (msg, IFLA_VRF_TABLE, props->table);
|
||||
break;
|
||||
}
|
||||
case NM_LINK_TYPE_VXLAN: {
|
||||
const NMPlatformLnkVxlan *props = extra_data;
|
||||
|
||||
|
|
|
@ -1218,6 +1218,10 @@ nm_platform_link_add (NMPlatform *self,
|
|||
nm_utils_strbuf_append_str (&buf_p, &buf_len, ", ");
|
||||
nm_platform_lnk_vlan_to_string ((const NMPlatformLnkVlan *) extra_data, buf_p, buf_len);
|
||||
break;
|
||||
case NM_LINK_TYPE_VRF:
|
||||
nm_utils_strbuf_append_str (&buf_p, &buf_len, ", ");
|
||||
nm_platform_lnk_vrf_to_string ((const NMPlatformLnkVrf *) extra_data, buf_p, buf_len);
|
||||
break;
|
||||
case NM_LINK_TYPE_VXLAN:
|
||||
nm_utils_strbuf_append_str (&buf_p, &buf_len, ", ");
|
||||
nm_platform_lnk_vxlan_to_string ((const NMPlatformLnkVxlan *) extra_data, buf_p, buf_len);
|
||||
|
@ -2252,6 +2256,12 @@ nm_platform_link_get_lnk_vlan (NMPlatform *self, int ifindex, const NMPlatformLi
|
|||
return _link_get_lnk (self, ifindex, NM_LINK_TYPE_VLAN, out_link);
|
||||
}
|
||||
|
||||
const NMPlatformLnkVrf *
|
||||
nm_platform_link_get_lnk_vrf (NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
|
||||
{
|
||||
return _link_get_lnk (self, ifindex, NM_LINK_TYPE_VRF, out_link);
|
||||
}
|
||||
|
||||
const NMPlatformLnkVxlan *
|
||||
nm_platform_link_get_lnk_vxlan (NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
|
||||
{
|
||||
|
@ -5484,6 +5494,20 @@ nm_platform_lnk_vlan_to_string (const NMPlatformLnkVlan *lnk, char *buf, gsize l
|
|||
return buf;
|
||||
}
|
||||
|
||||
const char *
|
||||
nm_platform_lnk_vrf_to_string (const NMPlatformLnkVrf *lnk, char *buf, gsize len)
|
||||
{
|
||||
char *b;
|
||||
|
||||
if (!nm_utils_to_string_buffer_init_null (lnk, &buf, &len))
|
||||
return buf;
|
||||
|
||||
b = buf;
|
||||
|
||||
nm_utils_strbuf_append (&b, &len, "table %u", lnk->table);
|
||||
return buf;
|
||||
}
|
||||
|
||||
const char *
|
||||
nm_platform_lnk_vxlan_to_string (const NMPlatformLnkVxlan *lnk, char *buf, gsize len)
|
||||
{
|
||||
|
@ -6850,6 +6874,21 @@ nm_platform_lnk_vlan_cmp (const NMPlatformLnkVlan *a, const NMPlatformLnkVlan *b
|
|||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
nm_platform_lnk_vrf_hash_update (const NMPlatformLnkVrf *obj, NMHashState *h)
|
||||
{
|
||||
nm_hash_update_vals (h,
|
||||
obj->table);
|
||||
}
|
||||
|
||||
int
|
||||
nm_platform_lnk_vrf_cmp (const NMPlatformLnkVrf *a, const NMPlatformLnkVrf *b)
|
||||
{
|
||||
NM_CMP_SELF (a, b);
|
||||
NM_CMP_FIELD (a, b, table);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
nm_platform_lnk_vxlan_hash_update (const NMPlatformLnkVxlan *obj, NMHashState *h)
|
||||
{
|
||||
|
|
|
@ -827,6 +827,10 @@ typedef struct {
|
|||
NMVlanFlags flags;
|
||||
} NMPlatformLnkVlan;
|
||||
|
||||
typedef struct {
|
||||
guint32 table;
|
||||
} NMPlatformLnkVrf;
|
||||
|
||||
typedef struct {
|
||||
struct in6_addr group6;
|
||||
struct in6_addr local6;
|
||||
|
@ -1430,6 +1434,15 @@ nm_platform_link_vlan_add (NMPlatform *self,
|
|||
out_link);
|
||||
}
|
||||
|
||||
static inline int
|
||||
nm_platform_link_vrf_add (NMPlatform *self,
|
||||
const char *name,
|
||||
const NMPlatformLnkVrf *props,
|
||||
const NMPlatformLink **out_link)
|
||||
{
|
||||
return nm_platform_link_add (self, NM_LINK_TYPE_VRF, name, 0, NULL, 0, props, out_link);
|
||||
}
|
||||
|
||||
static inline int
|
||||
nm_platform_link_vxlan_add (NMPlatform *self,
|
||||
const char *name,
|
||||
|
@ -1621,6 +1634,7 @@ const NMPlatformLnkMacvlan *nm_platform_link_get_lnk_macvtap (NMPlatform *self,
|
|||
const NMPlatformLnkSit *nm_platform_link_get_lnk_sit (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
|
||||
const NMPlatformLnkTun *nm_platform_link_get_lnk_tun (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
|
||||
const NMPlatformLnkVlan *nm_platform_link_get_lnk_vlan (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
|
||||
const NMPlatformLnkVrf *nm_platform_link_get_lnk_vrf (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
|
||||
const NMPlatformLnkVxlan *nm_platform_link_get_lnk_vxlan (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
|
||||
const NMPlatformLnkWireGuard *nm_platform_link_get_lnk_wireguard (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
|
||||
|
||||
|
@ -1792,6 +1806,7 @@ const char *nm_platform_lnk_macvlan_to_string (const NMPlatformLnkMacvlan *lnk,
|
|||
const char *nm_platform_lnk_sit_to_string (const NMPlatformLnkSit *lnk, char *buf, gsize len);
|
||||
const char *nm_platform_lnk_tun_to_string (const NMPlatformLnkTun *lnk, char *buf, gsize len);
|
||||
const char *nm_platform_lnk_vlan_to_string (const NMPlatformLnkVlan *lnk, char *buf, gsize len);
|
||||
const char *nm_platform_lnk_vrf_to_string (const NMPlatformLnkVrf *lnk, char *buf, gsize len);
|
||||
const char *nm_platform_lnk_vxlan_to_string (const NMPlatformLnkVxlan *lnk, char *buf, gsize len);
|
||||
const char *nm_platform_lnk_wireguard_to_string (const NMPlatformLnkWireGuard *lnk, char *buf, gsize len);
|
||||
const char *nm_platform_ip4_address_to_string (const NMPlatformIP4Address *address, char *buf, gsize len);
|
||||
|
@ -1824,6 +1839,7 @@ int nm_platform_lnk_macvlan_cmp (const NMPlatformLnkMacvlan *a, const NMPlatform
|
|||
int nm_platform_lnk_sit_cmp (const NMPlatformLnkSit *a, const NMPlatformLnkSit *b);
|
||||
int nm_platform_lnk_tun_cmp (const NMPlatformLnkTun *a, const NMPlatformLnkTun *b);
|
||||
int nm_platform_lnk_vlan_cmp (const NMPlatformLnkVlan *a, const NMPlatformLnkVlan *b);
|
||||
int nm_platform_lnk_vrf_cmp (const NMPlatformLnkVrf *a, const NMPlatformLnkVrf *b);
|
||||
int nm_platform_lnk_vxlan_cmp (const NMPlatformLnkVxlan *a, const NMPlatformLnkVxlan *b);
|
||||
int nm_platform_lnk_wireguard_cmp (const NMPlatformLnkWireGuard *a, const NMPlatformLnkWireGuard *b);
|
||||
int nm_platform_ip4_address_cmp (const NMPlatformIP4Address *a, const NMPlatformIP4Address *b);
|
||||
|
@ -1870,6 +1886,7 @@ void nm_platform_lnk_macvlan_hash_update (const NMPlatformLnkMacvlan *obj, NMHas
|
|||
void nm_platform_lnk_sit_hash_update (const NMPlatformLnkSit *obj, NMHashState *h);
|
||||
void nm_platform_lnk_tun_hash_update (const NMPlatformLnkTun *obj, NMHashState *h);
|
||||
void nm_platform_lnk_vlan_hash_update (const NMPlatformLnkVlan *obj, NMHashState *h);
|
||||
void nm_platform_lnk_vrf_hash_update (const NMPlatformLnkVrf *obj, NMHashState *h);
|
||||
void nm_platform_lnk_vxlan_hash_update (const NMPlatformLnkVxlan *obj, NMHashState *h);
|
||||
void nm_platform_lnk_wireguard_hash_update (const NMPlatformLnkWireGuard *obj, NMHashState *h);
|
||||
|
||||
|
|
|
@ -3336,6 +3336,18 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = {
|
|||
.cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_vlan_hash_update,
|
||||
.cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_vlan_cmp,
|
||||
},
|
||||
[NMP_OBJECT_TYPE_LNK_VRF - 1] = {
|
||||
.parent = DEDUP_MULTI_OBJ_CLASS_INIT(),
|
||||
.obj_type = NMP_OBJECT_TYPE_LNK_VRF,
|
||||
.sizeof_data = sizeof (NMPObjectLnkVrf),
|
||||
.sizeof_public = sizeof (NMPlatformLnkVrf),
|
||||
.obj_type_name = "vrf",
|
||||
.lnk_link_type = NM_LINK_TYPE_VRF,
|
||||
.cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_vrf_to_string,
|
||||
.cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_vrf_hash_update,
|
||||
.cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_vrf_cmp,
|
||||
},
|
||||
|
||||
[NMP_OBJECT_TYPE_LNK_VXLAN - 1] = {
|
||||
.parent = DEDUP_MULTI_OBJ_CLASS_INIT(),
|
||||
.obj_type = NMP_OBJECT_TYPE_LNK_VXLAN,
|
||||
|
|
|
@ -286,6 +286,10 @@ typedef struct {
|
|||
const NMVlanQosMapping *egress_qos_map;
|
||||
} NMPObjectLnkVlan;
|
||||
|
||||
typedef struct {
|
||||
NMPlatformLnkVrf _public;
|
||||
} NMPObjectLnkVrf;
|
||||
|
||||
typedef struct {
|
||||
NMPlatformLnkVxlan _public;
|
||||
} NMPObjectLnkVxlan;
|
||||
|
@ -366,6 +370,9 @@ struct _NMPObject {
|
|||
NMPlatformLnkVlan lnk_vlan;
|
||||
NMPObjectLnkVlan _lnk_vlan;
|
||||
|
||||
NMPlatformLnkVrf lnk_vrf;
|
||||
NMPObjectLnkVrf _lnk_vrf;
|
||||
|
||||
NMPlatformLnkVxlan lnk_vxlan;
|
||||
NMPObjectLnkVxlan _lnk_vxlan;
|
||||
|
||||
|
|
|
@ -1585,6 +1585,39 @@ nmtstp_link_tun_add (NMPlatform *platform,
|
|||
return pllink;
|
||||
}
|
||||
|
||||
const NMPlatformLink *
|
||||
nmtstp_link_vrf_add (NMPlatform *platform,
|
||||
gboolean external_command,
|
||||
const char *name,
|
||||
const NMPlatformLnkVrf *lnk)
|
||||
{
|
||||
const NMPlatformLink *pllink = NULL;
|
||||
int err;
|
||||
int r;
|
||||
|
||||
g_assert (nm_utils_is_valid_iface_name (name, NULL));
|
||||
|
||||
external_command = nmtstp_run_command_check_external (external_command);
|
||||
|
||||
_init_platform (&platform, external_command);
|
||||
|
||||
if (external_command) {
|
||||
err = nmtstp_run_command ("ip link add %s type vrf table %u",
|
||||
name,
|
||||
lnk->table);
|
||||
if (err == 0)
|
||||
pllink = nmtstp_assert_wait_for_link (platform, name, NM_LINK_TYPE_VRF, 100);
|
||||
} else {
|
||||
r = nm_platform_link_vrf_add (platform, name, lnk, &pllink);
|
||||
g_assert (NMTST_NM_ERR_SUCCESS (r));
|
||||
g_assert (pllink);
|
||||
}
|
||||
|
||||
g_assert_cmpint (pllink->type, ==, NM_LINK_TYPE_VRF);
|
||||
g_assert_cmpstr (pllink->name, ==, name);
|
||||
return pllink;
|
||||
}
|
||||
|
||||
const NMPlatformLink *
|
||||
nmtstp_link_vxlan_add (NMPlatform *platform,
|
||||
gboolean external_command,
|
||||
|
|
|
@ -360,6 +360,10 @@ const NMPlatformLink *nmtstp_link_tun_add (NMPlatform *platform,
|
|||
const char *name,
|
||||
const NMPlatformLnkTun *lnk,
|
||||
int *out_fd);
|
||||
const NMPlatformLink *nmtstp_link_vrf_add (NMPlatform *platform,
|
||||
gboolean external_command,
|
||||
const char *name,
|
||||
const NMPlatformLnkVrf *lnk);
|
||||
const NMPlatformLink *nmtstp_link_vxlan_add (NMPlatform *platform,
|
||||
gboolean external_command,
|
||||
const char *name,
|
||||
|
|
|
@ -1182,6 +1182,14 @@ test_software_detect (gconstpointer user_data)
|
|||
case NM_LINK_TYPE_VLAN:
|
||||
nmtstp_run_command_check ("ip link add name %s link %s type vlan id 1242", DEVICE_NAME, PARENT_NAME);
|
||||
break;
|
||||
case NM_LINK_TYPE_VRF: {
|
||||
NMPlatformLnkVrf lnk_vrf = { };
|
||||
|
||||
lnk_vrf.table = 9876;
|
||||
|
||||
nmtstp_link_vrf_add (NULL, ext, DEVICE_NAME, &lnk_vrf);
|
||||
break;
|
||||
}
|
||||
case NM_LINK_TYPE_VXLAN: {
|
||||
NMPlatformLnkVxlan lnk_vxlan = { };
|
||||
|
||||
|
@ -1444,6 +1452,13 @@ test_software_detect (gconstpointer user_data)
|
|||
g_assert_cmpint (plnk->id, ==, 1242);
|
||||
break;
|
||||
}
|
||||
case NM_LINK_TYPE_VRF: {
|
||||
const NMPlatformLnkVrf *plnk = &lnk->lnk_vrf;
|
||||
|
||||
g_assert (plnk == nm_platform_link_get_lnk_vrf (NM_PLATFORM_GET, ifindex, NULL));
|
||||
g_assert_cmpint (plnk->table, ==, 9876);
|
||||
break;
|
||||
}
|
||||
case NM_LINK_TYPE_VXLAN: {
|
||||
const NMPlatformLnkVxlan *plnk = &lnk->lnk_vxlan;
|
||||
|
||||
|
@ -3313,6 +3328,7 @@ _nmtstp_setup_tests (void)
|
|||
test_software_detect_add ("/link/software/detect/sit", NM_LINK_TYPE_SIT, 0);
|
||||
test_software_detect_add ("/link/software/detect/tun", NM_LINK_TYPE_TUN, 0);
|
||||
test_software_detect_add ("/link/software/detect/vlan", NM_LINK_TYPE_VLAN, 0);
|
||||
test_software_detect_add ("/link/software/detect/vrf", NM_LINK_TYPE_VRF, 0);
|
||||
test_software_detect_add ("/link/software/detect/vxlan/0", NM_LINK_TYPE_VXLAN, 0);
|
||||
test_software_detect_add ("/link/software/detect/vxlan/1", NM_LINK_TYPE_VXLAN, 1);
|
||||
test_software_detect_add ("/link/software/detect/wireguard/0", NM_LINK_TYPE_WIREGUARD, 0);
|
||||
|
|
Loading…
Reference in a new issue