mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-05 03:20:18 +01:00
platform: support VLAN protocol
Add support for the "protocol" attribute of VLAN links.
This commit is contained in:
parent
8febb15bfe
commit
bd24e0b274
7 changed files with 131 additions and 34 deletions
|
|
@ -8,6 +8,7 @@
|
|||
#include "nm-device-vlan.h"
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <linux/if_ether.h>
|
||||
|
||||
#include "nm-manager.h"
|
||||
#include "nm-utils.h"
|
||||
|
|
@ -230,8 +231,11 @@ create_and_realize(NMDevice *device,
|
|||
r = nm_platform_link_vlan_add(nm_device_get_platform(device),
|
||||
iface,
|
||||
parent_ifindex,
|
||||
vlan_id,
|
||||
nm_setting_vlan_get_flags(s_vlan),
|
||||
&((NMPlatformLnkVlan){
|
||||
.id = vlan_id,
|
||||
.flags = nm_setting_vlan_get_flags(s_vlan),
|
||||
.protocol = ETH_P_8021Q,
|
||||
}),
|
||||
out_plink);
|
||||
if (r < 0) {
|
||||
g_set_error(error,
|
||||
|
|
|
|||
|
|
@ -2073,6 +2073,50 @@ nmtstp_link_tun_add(NMPlatform *platform,
|
|||
return pllink;
|
||||
}
|
||||
|
||||
const NMPlatformLink *
|
||||
nmtstp_link_vlan_add(NMPlatform *platform,
|
||||
int external_command,
|
||||
const char *name,
|
||||
int parent,
|
||||
const NMPlatformLnkVlan *lnk)
|
||||
{
|
||||
const NMPlatformLink *pllink = NULL;
|
||||
gboolean success;
|
||||
|
||||
g_assert(nm_utils_ifname_valid_kernel(name, NULL));
|
||||
|
||||
external_command = nmtstp_run_command_check_external(external_command);
|
||||
|
||||
_init_platform(&platform, external_command);
|
||||
|
||||
if (external_command) {
|
||||
const char *dev;
|
||||
|
||||
dev = nm_platform_link_get_name(platform, parent);
|
||||
g_assert(dev);
|
||||
g_assert(NM_IN_SET(lnk->protocol, ETH_P_8021Q, ETH_P_8021AD));
|
||||
|
||||
success = !nmtstp_run_command(
|
||||
"ip link add name %s link %s type vlan id %hu protocol %s%s%s%s%s",
|
||||
name,
|
||||
dev,
|
||||
lnk->id,
|
||||
lnk->protocol == ETH_P_8021Q ? "802.1Q" : "802.1ad",
|
||||
!(lnk->flags & _NM_VLAN_FLAG_REORDER_HEADERS) ? " reorder_hdr off" : "",
|
||||
(lnk->flags & _NM_VLAN_FLAG_GVRP) ? " gvrp on" : "",
|
||||
(lnk->flags & _NM_VLAN_FLAG_MVRP) ? " mvrp on" : "",
|
||||
(lnk->flags & _NM_VLAN_FLAG_LOOSE_BINDING) ? " loose_binding on" : "");
|
||||
if (success)
|
||||
pllink = nmtstp_assert_wait_for_link(platform, name, NM_LINK_TYPE_VLAN, 100);
|
||||
} else
|
||||
success =
|
||||
NMTST_NM_ERR_SUCCESS(nm_platform_link_vlan_add(platform, name, parent, lnk, &pllink));
|
||||
|
||||
_assert_pllink(platform, success, pllink, name, NM_LINK_TYPE_VLAN);
|
||||
|
||||
return pllink;
|
||||
}
|
||||
|
||||
const NMPlatformLink *
|
||||
nmtstp_link_vrf_add(NMPlatform *platform,
|
||||
int external_command,
|
||||
|
|
|
|||
|
|
@ -499,6 +499,11 @@ const NMPlatformLink *nmtstp_link_tun_add(NMPlatform *platform,
|
|||
const char *name,
|
||||
const NMPlatformLnkTun *lnk,
|
||||
int *out_fd);
|
||||
const NMPlatformLink *nmtstp_link_vlan_add(NMPlatform *platform,
|
||||
int external_command,
|
||||
const char *name,
|
||||
int parent,
|
||||
const NMPlatformLnkVlan *lnk);
|
||||
const NMPlatformLink *nmtstp_link_vrf_add(NMPlatform *platform,
|
||||
int external_command,
|
||||
const char *name,
|
||||
|
|
|
|||
|
|
@ -161,8 +161,14 @@ software_add(NMLinkType link_type, const char *name)
|
|||
accept_signals(parent_changed, 1, 2);
|
||||
free_signal(parent_changed);
|
||||
|
||||
return NMTST_NM_ERR_SUCCESS(
|
||||
nm_platform_link_vlan_add(NM_PLATFORM_GET, name, parent_ifindex, VLAN_ID, 0, NULL));
|
||||
return NMTST_NM_ERR_SUCCESS(nm_platform_link_vlan_add(NM_PLATFORM_GET,
|
||||
name,
|
||||
parent_ifindex,
|
||||
&((NMPlatformLnkVlan){
|
||||
.id = VLAN_ID,
|
||||
.protocol = ETH_P_8021Q,
|
||||
}),
|
||||
NULL));
|
||||
}
|
||||
}
|
||||
default:
|
||||
|
|
@ -1296,7 +1302,7 @@ test_software_detect(gconstpointer user_data)
|
|||
lnk_bridge.ageing_time = 2200;
|
||||
lnk_bridge.stp_state = TRUE;
|
||||
lnk_bridge.priority = 22;
|
||||
lnk_bridge.vlan_protocol = 0x8100;
|
||||
lnk_bridge.vlan_protocol = ETH_P_8021Q;
|
||||
lnk_bridge.vlan_stats_enabled =
|
||||
nmtstp_kernel_support_get(NM_PLATFORM_KERNEL_SUPPORT_TYPE_IFLA_BR_VLAN_STATS_ENABLED)
|
||||
? TRUE
|
||||
|
|
@ -1571,10 +1577,28 @@ test_software_detect(gconstpointer user_data)
|
|||
break;
|
||||
}
|
||||
case NM_LINK_TYPE_VLAN:
|
||||
nmtstp_run_command_check("ip link add name %s link %s type vlan id 1242",
|
||||
DEVICE_NAME,
|
||||
PARENT_NAME);
|
||||
{
|
||||
NMPlatformLnkVlan lnk_vlan = {};
|
||||
|
||||
switch (test_data->test_mode) {
|
||||
case 0:
|
||||
lnk_vlan.id = 1242;
|
||||
lnk_vlan.protocol = ETH_P_8021Q;
|
||||
lnk_vlan.flags = _NM_VLAN_FLAG_REORDER_HEADERS;
|
||||
break;
|
||||
case 1:
|
||||
lnk_vlan.id = 4094;
|
||||
lnk_vlan.protocol = ETH_P_8021AD;
|
||||
lnk_vlan.flags = _NM_VLAN_FLAG_GVRP | _NM_VLAN_FLAG_MVRP;
|
||||
break;
|
||||
default:
|
||||
nm_assert_not_reached();
|
||||
}
|
||||
|
||||
if (!nmtstp_link_vlan_add(NULL, ext, DEVICE_NAME, ifindex_parent, &lnk_vlan))
|
||||
g_error("Failed adding VLAN interface");
|
||||
break;
|
||||
}
|
||||
case NM_LINK_TYPE_VRF:
|
||||
{
|
||||
NMPlatformLnkVrf lnk_vrf = {};
|
||||
|
|
@ -1727,7 +1751,7 @@ test_software_detect(gconstpointer user_data)
|
|||
g_assert_cmpint(plnk->ageing_time, ==, lnk_bridge_norm->ageing_time);
|
||||
g_assert_cmpint(plnk->stp_state, ==, TRUE);
|
||||
g_assert_cmpint(plnk->priority, ==, 22);
|
||||
g_assert_cmpint(plnk->vlan_protocol, ==, 0x8100);
|
||||
g_assert_cmpint(plnk->vlan_protocol, ==, ETH_P_8021Q);
|
||||
g_assert_cmpint(plnk->vlan_stats_enabled, ==, lnk_bridge_norm->vlan_stats_enabled);
|
||||
g_assert_cmpint(plnk->group_fwd_mask, ==, 8);
|
||||
g_assert_cmpint(plnk->mcast_snooping, ==, TRUE);
|
||||
|
|
@ -1910,7 +1934,19 @@ test_software_detect(gconstpointer user_data)
|
|||
const NMPlatformLnkVlan *plnk = &lnk->lnk_vlan;
|
||||
|
||||
g_assert(plnk == nm_platform_link_get_lnk_vlan(NM_PLATFORM_GET, ifindex, NULL));
|
||||
g_assert_cmpint(plnk->id, ==, 1242);
|
||||
|
||||
switch (test_data->test_mode) {
|
||||
case 0:
|
||||
g_assert_cmpint(plnk->id, ==, 1242);
|
||||
g_assert_cmpint(plnk->protocol, ==, ETH_P_8021Q);
|
||||
g_assert_cmpint(plnk->flags, ==, _NM_VLAN_FLAG_REORDER_HEADERS);
|
||||
break;
|
||||
case 1:
|
||||
g_assert_cmpint(plnk->id, ==, 4094);
|
||||
g_assert_cmpint(plnk->protocol, ==, ETH_P_8021AD);
|
||||
g_assert_cmpint(plnk->flags, ==, _NM_VLAN_FLAG_GVRP | _NM_VLAN_FLAG_MVRP);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NM_LINK_TYPE_VRF:
|
||||
|
|
@ -3823,7 +3859,8 @@ _nmtstp_setup_tests(void)
|
|||
test_software_detect_add("/link/software/detect/macvtap", NM_LINK_TYPE_MACVTAP, 0);
|
||||
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/vlan/0", NM_LINK_TYPE_VLAN, 0);
|
||||
test_software_detect_add("/link/software/detect/vlan/1", NM_LINK_TYPE_VLAN, 1);
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -2255,6 +2255,11 @@ _parse_lnk_vlan(const char *kind, struct nlattr *info_data)
|
|||
obj = nmp_object_new(NMP_OBJECT_TYPE_LNK_VLAN, NULL);
|
||||
obj->lnk_vlan.id = nla_get_u16(tb[IFLA_VLAN_ID]);
|
||||
|
||||
if (tb[IFLA_VLAN_PROTOCOL])
|
||||
obj->lnk_vlan.protocol = ntohs(nla_get_u16(tb[IFLA_VLAN_PROTOCOL]));
|
||||
else
|
||||
obj->lnk_vlan.protocol = ETH_P_8021Q;
|
||||
|
||||
if (tb[IFLA_VLAN_FLAGS]) {
|
||||
struct ifla_vlan_flags flags;
|
||||
|
||||
|
|
@ -4658,11 +4663,13 @@ _nl_msg_new_link_set_linkinfo(struct nl_msg *msg, NMLinkType link_type, gconstpo
|
|||
const NMPlatformLnkVlan *props = extra_data;
|
||||
|
||||
nm_assert(extra_data);
|
||||
nm_assert(props->protocol != 0);
|
||||
|
||||
if (!(data = nla_nest_start(msg, IFLA_INFO_DATA)))
|
||||
goto nla_put_failure;
|
||||
|
||||
NLA_PUT_U16(msg, IFLA_VLAN_ID, props->id);
|
||||
NLA_PUT_U16(msg, IFLA_VLAN_PROTOCOL, htons(props->protocol));
|
||||
|
||||
{
|
||||
struct ifla_vlan_flags flags = {
|
||||
|
|
|
|||
|
|
@ -6470,13 +6470,27 @@ const char *
|
|||
nm_platform_lnk_vlan_to_string(const NMPlatformLnkVlan *lnk, char *buf, gsize len)
|
||||
{
|
||||
char *b;
|
||||
char protocol[32];
|
||||
|
||||
if (!nm_utils_to_string_buffer_init_null(lnk, &buf, &len))
|
||||
return buf;
|
||||
|
||||
b = buf;
|
||||
|
||||
switch (lnk->protocol) {
|
||||
case ETH_P_8021AD:
|
||||
nm_sprintf_buf(protocol, "802.1ad");
|
||||
break;
|
||||
case ETH_P_8021Q:
|
||||
nm_sprintf_buf(protocol, "802.1Q");
|
||||
break;
|
||||
default:
|
||||
nm_sprintf_buf(protocol, "0x%04hx", lnk->protocol);
|
||||
break;
|
||||
}
|
||||
|
||||
nm_strbuf_append(&b, &len, "vlan %u", lnk->id);
|
||||
nm_strbuf_append(&b, &len, " protocol %s", protocol);
|
||||
if (lnk->flags)
|
||||
nm_strbuf_append(&b, &len, " flags 0x%x", lnk->flags);
|
||||
return buf;
|
||||
|
|
@ -8146,7 +8160,7 @@ nm_platform_lnk_tun_cmp(const NMPlatformLnkTun *a, const NMPlatformLnkTun *b)
|
|||
void
|
||||
nm_platform_lnk_vlan_hash_update(const NMPlatformLnkVlan *obj, NMHashState *h)
|
||||
{
|
||||
nm_hash_update_vals(h, obj->id, obj->flags);
|
||||
nm_hash_update_vals(h, obj->id, obj->protocol, obj->flags);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
@ -8154,6 +8168,7 @@ nm_platform_lnk_vlan_cmp(const NMPlatformLnkVlan *a, const NMPlatformLnkVlan *b)
|
|||
{
|
||||
NM_CMP_SELF(a, b);
|
||||
NM_CMP_FIELD(a, b, id);
|
||||
NM_CMP_FIELD(a, b, protocol);
|
||||
NM_CMP_FIELD(a, b, flags);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -862,8 +862,8 @@ typedef struct {
|
|||
} _nm_alignas(NMPlatformObject) NMPlatformLnkTun;
|
||||
|
||||
typedef struct {
|
||||
/* rtnl_link_vlan_get_id(), IFLA_VLAN_ID */
|
||||
guint16 id;
|
||||
guint16 protocol;
|
||||
_NMVlanFlags flags;
|
||||
} _nm_alignas(NMPlatformObject) NMPlatformLnkVlan;
|
||||
|
||||
|
|
@ -1660,28 +1660,13 @@ nm_platform_link_sit_add(NMPlatform *self,
|
|||
}
|
||||
|
||||
static inline int
|
||||
nm_platform_link_vlan_add(NMPlatform *self,
|
||||
const char *name,
|
||||
int parent,
|
||||
int vlanid,
|
||||
guint32 vlanflags,
|
||||
const NMPlatformLink **out_link)
|
||||
nm_platform_link_vlan_add(NMPlatform *self,
|
||||
const char *name,
|
||||
int parent,
|
||||
const NMPlatformLnkVlan *props,
|
||||
const NMPlatformLink **out_link)
|
||||
{
|
||||
g_return_val_if_fail(parent >= 0, -NME_BUG);
|
||||
g_return_val_if_fail(vlanid >= 0, -NME_BUG);
|
||||
|
||||
return nm_platform_link_add(self,
|
||||
NM_LINK_TYPE_VLAN,
|
||||
name,
|
||||
parent,
|
||||
NULL,
|
||||
0,
|
||||
0,
|
||||
&((NMPlatformLnkVlan){
|
||||
.id = vlanid,
|
||||
.flags = vlanflags,
|
||||
}),
|
||||
out_link);
|
||||
return nm_platform_link_add(self, NM_LINK_TYPE_VLAN, name, parent, NULL, 0, 0, props, out_link);
|
||||
}
|
||||
|
||||
static inline int
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue