diff options
author | Vladislav Tsisyk <vlad@tsisyk.com> | 2023-01-22 21:37:46 +0700 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2023-03-01 11:39:01 +0100 |
commit | 6de0bb6a86bc53d170e9e95587e19107968cd708 (patch) | |
tree | 5ca0bfe77f929a8b0498d607de48cb463a0781e6 | |
parent | 336b46d1c2e867796f8ec9708c34fc253fee100f (diff) | |
download | NetworkManager-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.c | 44 | ||||
-rw-r--r-- | src/libnm-platform/nm-linux-platform.c | 42 | ||||
-rw-r--r-- | src/libnm-platform/nm-platform.c | 23 | ||||
-rw-r--r-- | src/libnm-platform/nm-platform.h | 13 |
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); |