summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladislav Tsisyk <vlad@tsisyk.com>2023-01-22 21:37:46 +0700
committerThomas Haller <thaller@redhat.com>2023-03-01 11:39:01 +0100
commit6de0bb6a86bc53d170e9e95587e19107968cd708 (patch)
tree5ca0bfe77f929a8b0498d607de48cb463a0781e6
parent336b46d1c2e867796f8ec9708c34fc253fee100f (diff)
downloadNetworkManager-6de0bb6a86bc53d170e9e95587e19107968cd708.tar.gz
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
-rw-r--r--src/core/devices/nm-device-bridge.c44
-rw-r--r--src/libnm-platform/nm-linux-platform.c42
-rw-r--r--src/libnm-platform/nm-platform.c23
-rw-r--r--src/libnm-platform/nm-platform.h13
4 files changed, 106 insertions, 16 deletions
diff --git a/src/core/devices/nm-device-bridge.c b/src/core/devices/nm-device-bridge.c
index c5ce34c255..ca201eb877 100644
--- a/src/core/devices/nm-device-bridge.c
+++ b/src/core/devices/nm-device-bridge.c
@@ -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;
}
diff --git a/src/libnm-platform/nm-linux-platform.c b/src/libnm-platform/nm-linux-platform.c
index cf47fb35ee..78d6e704bb 100644
--- a/src/libnm-platform/nm-linux-platform.c
+++ b/src/libnm-platform/nm-linux-platform.c
@@ -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;
diff --git a/src/libnm-platform/nm-platform.c b/src/libnm-platform/nm-platform.c
index b1ac3132c0..64d0fd8efd 100644
--- a/src/libnm-platform/nm-platform.c
+++ b/src/libnm-platform/nm-platform.c
@@ -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
diff --git a/src/libnm-platform/nm-platform.h b/src/libnm-platform/nm-platform.h
index 39f8edabd8..447ef3aa8f 100644
--- a/src/libnm-platform/nm-platform.h
+++ b/src/libnm-platform/nm-platform.h
@@ -709,6 +709,13 @@ typedef struct {
} 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;
guint64 mcast_querier_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);