bridge: change the signature for nm_platform_link_set_bridge_vlans()

Currently, nm_platform_link_set_bridge_vlans() accepts an array of
pointers to vlan objects; to avoid multiple allocations,
setting_vlans_to_platform() creates the array by piggybacking the
actual data after the pointers array.

In the next commits, the array will need to be manipulated and
extended, which is difficult with the current structure. Instead, pass
separately an array of objects and its size.
This commit is contained in:
Beniamino Galvani
2024-07-25 09:49:18 +02:00
committed by Íñigo Huguet
parent 7d3bfb101f
commit e00c81b153
4 changed files with 70 additions and 63 deletions

View File

@@ -419,20 +419,18 @@ static const Option controller_options[] = {
0,
}};
static const NMPlatformBridgeVlan **
setting_vlans_to_platform(GPtrArray *array)
static NMPlatformBridgeVlan *
setting_vlans_to_platform(GPtrArray *array, guint *out_len)
{
NMPlatformBridgeVlan **arr;
NMPlatformBridgeVlan *p_data;
NMPlatformBridgeVlan *arr;
guint i;
if (!array || !array->len)
if (!array || !array->len) {
*out_len = 0;
return NULL;
}
G_STATIC_ASSERT_EXPR(_nm_alignof(NMPlatformBridgeVlan *) >= _nm_alignof(NMPlatformBridgeVlan));
arr = g_malloc((sizeof(NMPlatformBridgeVlan *) * (array->len + 1))
+ (sizeof(NMPlatformBridgeVlan) * (array->len)));
p_data = (NMPlatformBridgeVlan *) &arr[array->len + 1];
arr = g_new(NMPlatformBridgeVlan, array->len);
for (i = 0; i < array->len; i++) {
NMBridgeVlan *vlan = array->pdata[i];
@@ -440,16 +438,16 @@ setting_vlans_to_platform(GPtrArray *array)
nm_bridge_vlan_get_vid_range(vlan, &vid_start, &vid_end);
p_data[i] = (NMPlatformBridgeVlan){
arr[i] = (NMPlatformBridgeVlan){
.vid_start = vid_start,
.vid_end = vid_end,
.pvid = nm_bridge_vlan_is_pvid(vlan),
.untagged = nm_bridge_vlan_is_untagged(vlan),
};
arr[i] = &p_data[i];
}
arr[i] = NULL;
return (const NMPlatformBridgeVlan **) arr;
*out_len = array->len;
return arr;
}
static void
@@ -647,7 +645,8 @@ bridge_set_vlan_options(NMDevice *device, NMSettingBridge *s_bridge, gboolean is
NMPlatform *plat;
int ifindex;
gs_unref_ptrarray GPtrArray *vlans = NULL;
gs_free const NMPlatformBridgeVlan **plat_vlans = NULL;
gs_free NMPlatformBridgeVlan *plat_vlans = NULL;
guint num_vlans;
if (self->vlan_configured)
return TRUE;
@@ -664,7 +663,7 @@ bridge_set_vlan_options(NMDevice *device, NMSettingBridge *s_bridge, gboolean is
.vlan_filtering_val = FALSE,
.vlan_default_pvid_has = TRUE,
.vlan_default_pvid_val = 1}));
nm_platform_link_set_bridge_vlans(plat, ifindex, FALSE, NULL);
nm_platform_link_set_bridge_vlans(plat, ifindex, FALSE, NULL, 0);
return TRUE;
}
@@ -696,7 +695,7 @@ bridge_set_vlan_options(NMDevice *device, NMSettingBridge *s_bridge, gboolean is
.vlan_default_pvid_val = 0}));
/* Clear all existing VLANs */
if (!nm_platform_link_set_bridge_vlans(plat, ifindex, FALSE, NULL))
if (!nm_platform_link_set_bridge_vlans(plat, ifindex, FALSE, NULL, 0))
return FALSE;
/* Now set the default PVID. After this point the kernel creates
@@ -714,8 +713,9 @@ bridge_set_vlan_options(NMDevice *device, NMSettingBridge *s_bridge, gboolean is
/* Create VLANs only after setting the default PVID, so that
* any PVID VLAN overrides the bridge's default PVID. */
g_object_get(s_bridge, NM_SETTING_BRIDGE_VLANS, &vlans, NULL);
plat_vlans = setting_vlans_to_platform(vlans);
if (plat_vlans && !nm_platform_link_set_bridge_vlans(plat, ifindex, FALSE, plat_vlans))
plat_vlans = setting_vlans_to_platform(vlans, &num_vlans);
if (plat_vlans
&& !nm_platform_link_set_bridge_vlans(plat, ifindex, FALSE, plat_vlans, num_vlans))
return FALSE;
nm_platform_link_set_bridge_info(plat,
@@ -937,13 +937,14 @@ attach_port(NMDevice *device,
bridge_set_vlan_options(device, s_bridge, FALSE);
if (nm_setting_bridge_get_vlan_filtering(s_bridge)) {
gs_free const NMPlatformBridgeVlan **plat_vlans = NULL;
gs_free NMPlatformBridgeVlan *plat_vlans = NULL;
gs_unref_ptrarray GPtrArray *vlans = NULL;
guint num_vlans;
if (s_port)
g_object_get(s_port, NM_SETTING_BRIDGE_PORT_VLANS, &vlans, NULL);
plat_vlans = setting_vlans_to_platform(vlans);
plat_vlans = setting_vlans_to_platform(vlans, &num_vlans);
/* Since the link was just enportd, there are no existing VLANs
* (except for the default one) and so there's no need to flush. */
@@ -952,7 +953,8 @@ attach_port(NMDevice *device,
&& !nm_platform_link_set_bridge_vlans(nm_device_get_platform(port),
nm_device_get_ifindex(port),
TRUE,
plat_vlans))
plat_vlans,
num_vlans))
return FALSE;
}

View File

@@ -9508,14 +9508,17 @@ static gboolean
link_set_bridge_vlans(NMPlatform *platform,
int ifindex,
gboolean on_controller,
const NMPlatformBridgeVlan *const *vlans)
const NMPlatformBridgeVlan *vlans,
guint num_vlans)
{
nm_auto_nlmsg struct nl_msg *nlmsg = NULL;
struct nlattr *list;
struct bridge_vlan_info vinfo = {};
guint i;
nlmsg = _nl_msg_new_link_full(vlans ? RTM_SETLINK : RTM_DELLINK,
nm_assert(num_vlans == 0 || vlans);
nlmsg = _nl_msg_new_link_full(num_vlans > 0 ? RTM_SETLINK : RTM_DELLINK,
0,
ifindex,
NULL,
@@ -9533,10 +9536,10 @@ link_set_bridge_vlans(NMPlatform *platform,
IFLA_BRIDGE_FLAGS,
on_controller ? BRIDGE_FLAGS_CONTROLLER : BRIDGE_FLAGS_SELF);
if (vlans) {
if (num_vlans > 0) {
/* Add VLANs */
for (i = 0; vlans[i]; i++) {
const NMPlatformBridgeVlan *vlan = vlans[i];
for (i = 0; i < num_vlans; i++) {
const NMPlatformBridgeVlan *vlan = &vlans[i];
gboolean is_range = vlan->vid_start != vlan->vid_end;
vinfo.vid = vlan->vid_start;

View File

@@ -2073,7 +2073,8 @@ gboolean
nm_platform_link_set_bridge_vlans(NMPlatform *self,
int ifindex,
gboolean on_controller,
const NMPlatformBridgeVlan *const *vlans)
const NMPlatformBridgeVlan *vlans,
guint num_vlans)
{
guint i;
_CHECK_SELF(self, klass, FALSE);
@@ -2085,9 +2086,9 @@ nm_platform_link_set_bridge_vlans(NMPlatform *self,
vlans ? "setting" : "clearing",
on_controller ? "controller" : "self");
if (vlans) {
for (i = 0; vlans[i]; i++) {
for (i = 0; i < num_vlans; i++) {
char sbuf[NM_UTILS_TO_STRING_BUFFER_SIZE];
const NMPlatformBridgeVlan *vlan = vlans[i];
const NMPlatformBridgeVlan *vlan = &vlans[i];
_LOG3D("link: bridge VLAN %s",
nm_platform_bridge_vlan_to_string(vlan, sbuf, sizeof(sbuf)));
@@ -2095,7 +2096,7 @@ nm_platform_link_set_bridge_vlans(NMPlatform *self,
}
}
return klass->link_set_bridge_vlans(self, ifindex, on_controller, vlans);
return klass->link_set_bridge_vlans(self, ifindex, on_controller, vlans, num_vlans);
}
gboolean
@@ -7386,8 +7387,7 @@ nm_platform_ip6_route_to_string(const NMPlatformIP6Route *route, char *buf, gsiz
route->lock_mtu ? "lock " : "",
route->mtu)
: "",
route->rt_pref
? nm_sprintf_buf(
route->rt_pref ? nm_sprintf_buf(
str_pref,
" pref %s",
nm_icmpv6_router_pref_to_string(route->rt_pref, str_pref2, sizeof(str_pref2)))

View File

@@ -1188,7 +1188,8 @@ typedef struct {
gboolean (*link_set_bridge_vlans)(NMPlatform *self,
int ifindex,
gboolean on_controller,
const NMPlatformBridgeVlan *const *vlans);
const NMPlatformBridgeVlan *vlans,
guint num_vlans);
gboolean (*link_set_bridge_info)(NMPlatform *self,
int ifindex,
const NMPlatformLinkSetBridgeInfoData *bridge_info);
@@ -2052,7 +2053,8 @@ nm_platform_link_set_sriov_vfs(NMPlatform *self, int ifindex, const NMPlatformVF
gboolean nm_platform_link_set_bridge_vlans(NMPlatform *self,
int ifindex,
gboolean on_controller,
const NMPlatformBridgeVlan *const *vlans);
const NMPlatformBridgeVlan *vlans,
guint num_vlans);
gboolean nm_platform_link_set_bridge_info(NMPlatform *self,
int ifindex,
const NMPlatformLinkSetBridgeInfoData *bridge_info);