bridge: set vlan_filtering and vlan_default_pvid via netlink

This commit changes setting values of said attributes from writing string to
sysfs to sending Netlink message.

https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1499
This commit is contained in:
Vladislav Tsisyk 2023-01-22 21:37:46 +07:00 committed by Thomas Haller
parent 336b46d1c2
commit 6de0bb6a86
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
4 changed files with 106 additions and 16 deletions

View file

@ -746,8 +746,13 @@ bridge_set_vlan_options(NMDevice *device, NMSettingBridge *s_bridge)
enabled = nm_setting_bridge_get_vlan_filtering(s_bridge);
if (!enabled) {
nm_platform_sysctl_master_set_option(plat, ifindex, "vlan_filtering", "0");
nm_platform_sysctl_master_set_option(plat, ifindex, "default_pvid", "1");
nm_platform_link_set_bridge_info(
plat,
ifindex,
&((NMPlatformLinkSetBridgeInfoData){.vlan_filtering_has = TRUE,
.vlan_filtering_val = FALSE,
.vlan_default_pvid_has = TRUE,
.vlan_default_pvid_val = 1}));
nm_platform_link_set_bridge_vlans(plat, ifindex, FALSE, NULL);
return TRUE;
}
@ -762,14 +767,17 @@ bridge_set_vlan_options(NMDevice *device, NMSettingBridge *s_bridge)
self->vlan_configured = TRUE;
/* Filtering must be disabled to change the default PVID */
if (!nm_platform_sysctl_master_set_option(plat, ifindex, "vlan_filtering", "0"))
return FALSE;
/* Clear the default PVID so that we later can force the re-creation of
/* Filtering must be disabled to change the default PVID.
* Clear the default PVID so that we later can force the re-creation of
* default PVID VLANs by writing the option again. */
if (!nm_platform_sysctl_master_set_option(plat, ifindex, "default_pvid", "0"))
return FALSE;
nm_platform_link_set_bridge_info(
plat,
ifindex,
&((NMPlatformLinkSetBridgeInfoData){.vlan_filtering_has = TRUE,
.vlan_filtering_val = FALSE,
.vlan_default_pvid_has = TRUE,
.vlan_default_pvid_val = 0}));
/* Clear all existing VLANs */
if (!nm_platform_link_set_bridge_vlans(plat, ifindex, FALSE, NULL))
@ -779,11 +787,11 @@ bridge_set_vlan_options(NMDevice *device, NMSettingBridge *s_bridge)
* a PVID VLAN on each port, including the bridge itself. */
pvid = nm_setting_bridge_get_vlan_default_pvid(s_bridge);
if (pvid) {
char value[32];
nm_sprintf_buf(value, "%u", pvid);
if (!nm_platform_sysctl_master_set_option(plat, ifindex, "default_pvid", value))
return FALSE;
nm_platform_link_set_bridge_info(
plat,
ifindex,
&((NMPlatformLinkSetBridgeInfoData){.vlan_default_pvid_has = TRUE,
.vlan_default_pvid_val = pvid}));
}
/* Create VLANs only after setting the default PVID, so that
@ -793,8 +801,12 @@ bridge_set_vlan_options(NMDevice *device, NMSettingBridge *s_bridge)
if (plat_vlans && !nm_platform_link_set_bridge_vlans(plat, ifindex, FALSE, plat_vlans))
return FALSE;
if (!nm_platform_sysctl_master_set_option(plat, ifindex, "vlan_filtering", "1"))
return FALSE;
nm_platform_link_set_bridge_info(plat,
ifindex,
&((NMPlatformLinkSetBridgeInfoData){
.vlan_filtering_has = TRUE,
.vlan_filtering_val = TRUE,
}));
return TRUE;
}

View file

@ -8864,6 +8864,47 @@ nla_put_failure:
g_return_val_if_reached(FALSE);
}
static gboolean
link_set_bridge_info(NMPlatform *platform,
int ifindex,
const NMPlatformLinkSetBridgeInfoData *bridge_info)
{
nm_auto_nlmsg struct nl_msg *nlmsg = NULL;
struct nlattr *info;
struct nlattr *data;
const char *kind;
nlmsg = _nl_msg_new_link(RTM_NEWLINK, 0, ifindex, NULL);
if (!nlmsg)
g_return_val_if_reached(-NME_BUG);
if (!(info = nla_nest_start(nlmsg, IFLA_LINKINFO)))
goto nla_put_failure;
kind = nm_link_type_to_rtnl_type_string(NM_LINK_TYPE_BRIDGE);
if (!kind)
goto nla_put_failure;
NLA_PUT_STRING(nlmsg, IFLA_INFO_KIND, kind);
if (!(data = nla_nest_start(nlmsg, IFLA_INFO_DATA)))
goto nla_put_failure;
if (bridge_info->vlan_filtering_has)
NLA_PUT_U8(nlmsg, IFLA_BR_VLAN_FILTERING, bridge_info->vlan_filtering_val);
if (bridge_info->vlan_default_pvid_has)
NLA_PUT_U16(nlmsg, IFLA_BR_VLAN_DEFAULT_PVID, bridge_info->vlan_default_pvid_val);
nla_nest_end(nlmsg, data);
nla_nest_end(nlmsg, info);
return (do_change_link(platform, CHANGE_LINK_TYPE_UNSPEC, ifindex, nlmsg, NULL) >= 0);
nla_put_failure:
g_return_val_if_reached(FALSE);
}
static char *
link_get_physical_port_id(NMPlatform *platform, int ifindex)
{
@ -11145,6 +11186,7 @@ nm_linux_platform_class_init(NMLinuxPlatformClass *klass)
platform_class->link_set_sriov_params_async = link_set_sriov_params_async;
platform_class->link_set_sriov_vfs = link_set_sriov_vfs;
platform_class->link_set_bridge_vlans = link_set_bridge_vlans;
platform_class->link_set_bridge_info = link_set_bridge_info;
platform_class->link_get_physical_port_id = link_get_physical_port_id;
platform_class->link_get_dev_id = link_get_dev_id;

View file

@ -2022,6 +2022,29 @@ nm_platform_link_set_bridge_vlans(NMPlatform *self,
return klass->link_set_bridge_vlans(self, ifindex, on_master, vlans);
}
gboolean
nm_platform_link_set_bridge_info(NMPlatform *self,
int ifindex,
const NMPlatformLinkSetBridgeInfoData *bridge_info)
{
_CHECK_SELF(self, klass, FALSE);
g_return_val_if_fail(ifindex > 0, FALSE);
if (_LOGD_ENABLED()) {
if (bridge_info->vlan_filtering_has) {
_LOG3D("link: setting bridge vlan-filtering %s",
bridge_info->vlan_filtering_val ? "on" : "off");
}
if (bridge_info->vlan_default_pvid_has) {
_LOG3D("link: setting bridge vlan-default-pvid %d", bridge_info->vlan_default_pvid_val);
}
}
return klass->link_set_bridge_info(self, ifindex, bridge_info);
}
/**
* nm_platform_link_change_flags_full:
* @self: platform instance

View file

@ -708,6 +708,13 @@ typedef struct {
bool pvid : 1;
} NMPlatformBridgeVlan;
typedef struct {
guint16 vlan_default_pvid_val;
bool vlan_filtering_val : 1;
bool vlan_default_pvid_has : 1;
bool vlan_filtering_has : 1;
} NMPlatformLinkSetBridgeInfoData;
typedef struct {
guint64 mcast_last_member_interval;
guint64 mcast_membership_interval;
@ -1118,6 +1125,9 @@ typedef struct {
int ifindex,
gboolean on_master,
const NMPlatformBridgeVlan *const *vlans);
gboolean (*link_set_bridge_info)(NMPlatform *self,
int ifindex,
const NMPlatformLinkSetBridgeInfoData *bridge_info);
char *(*link_get_physical_port_id)(NMPlatform *self, int ifindex);
guint (*link_get_dev_id)(NMPlatform *self, int ifindex);
@ -1954,6 +1964,9 @@ gboolean nm_platform_link_set_bridge_vlans(NMPlatform *se
int ifindex,
gboolean on_master,
const NMPlatformBridgeVlan *const *vlans);
gboolean nm_platform_link_set_bridge_info(NMPlatform *self,
int ifindex,
const NMPlatformLinkSetBridgeInfoData *bridge_info);
char *nm_platform_link_get_physical_port_id(NMPlatform *self, int ifindex);
guint nm_platform_link_get_dev_id(NMPlatform *self, int ifindex);