diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2019-12-05 10:35:25 +0100 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2020-01-14 09:49:01 +0100 |
commit | 7c73c6a038a15687bfc9d831b97e01596ec3fe9d (patch) | |
tree | e6c389fd9111d4272df49baa6817962ce3ecb182 | |
parent | 89d387f782fb4402c7cc32ef524b741c9cbb90cc (diff) | |
download | NetworkManager-7c73c6a038a15687bfc9d831b97e01596ec3fe9d.tar.gz |
platform: add VRF support
Add support for creating and parsing VRF links.
-rw-r--r-- | src/nm-types.h | 2 | ||||
-rw-r--r-- | src/platform/nm-linux-platform.c | 44 | ||||
-rw-r--r-- | src/platform/nm-platform.c | 39 | ||||
-rw-r--r-- | src/platform/nm-platform.h | 17 | ||||
-rw-r--r-- | src/platform/nmp-object.c | 12 | ||||
-rw-r--r-- | src/platform/nmp-object.h | 7 | ||||
-rw-r--r-- | src/platform/tests/test-common.c | 33 | ||||
-rw-r--r-- | src/platform/tests/test-common.h | 4 | ||||
-rw-r--r-- | src/platform/tests/test-link.c | 16 |
9 files changed, 174 insertions, 0 deletions
diff --git a/src/nm-types.h b/src/nm-types.h index 2f1ac2dcd5..43b931dad3 100644 --- a/src/nm-types.h +++ b/src/nm-types.h @@ -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, diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 4fc4a16f21..020db21ecd 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -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; diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index fbb5e7e2fa..2065b1818e 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -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) { @@ -5485,6 +5495,20 @@ nm_platform_lnk_vlan_to_string (const NMPlatformLnkVlan *lnk, char *buf, gsize l } 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) { char str_group[100]; @@ -6851,6 +6875,21 @@ nm_platform_lnk_vlan_cmp (const NMPlatformLnkVlan *a, const NMPlatformLnkVlan *b } 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) { nm_hash_update_vals (h, diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index 8d1a3d3865..d18208081a 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -828,6 +828,10 @@ typedef struct { } NMPlatformLnkVlan; typedef struct { + guint32 table; +} NMPlatformLnkVrf; + +typedef struct { struct in6_addr group6; struct in6_addr local6; in_addr_t group; @@ -1431,6 +1435,15 @@ nm_platform_link_vlan_add (NMPlatform *self, } 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, const NMPlatformLnkVxlan *props, @@ -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); diff --git a/src/platform/nmp-object.c b/src/platform/nmp-object.c index 240c1e7d8a..12f90aee1c 100644 --- a/src/platform/nmp-object.c +++ b/src/platform/nmp-object.c @@ -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, diff --git a/src/platform/nmp-object.h b/src/platform/nmp-object.h index d52cc132d2..1cafc3abf8 100644 --- a/src/platform/nmp-object.h +++ b/src/platform/nmp-object.h @@ -287,6 +287,10 @@ typedef struct { } 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; diff --git a/src/platform/tests/test-common.c b/src/platform/tests/test-common.c index 906deeada6..2fbfb90d4c 100644 --- a/src/platform/tests/test-common.c +++ b/src/platform/tests/test-common.c @@ -1586,6 +1586,39 @@ nmtstp_link_tun_add (NMPlatform *platform, } 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, const char *name, diff --git a/src/platform/tests/test-common.h b/src/platform/tests/test-common.h index 6f5a6cf62b..f392413eca 100644 --- a/src/platform/tests/test-common.h +++ b/src/platform/tests/test-common.h @@ -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, diff --git a/src/platform/tests/test-link.c b/src/platform/tests/test-link.c index 4a54af2a19..2f7a503cee 100644 --- a/src/platform/tests/test-link.c +++ b/src/platform/tests/test-link.c @@ -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); |