From cdd2de2692789ea26703b7f8b35ff1b5c21fdb4d Mon Sep 17 00:00:00 2001 From: Fernando Fernandez Mancera Date: Thu, 9 Mar 2023 12:18:14 +0100 Subject: [PATCH] platform: add support to prio property in bond ports --- src/core/platform/nm-fake-platform.c | 2 ++ src/core/platform/tests/test-link.c | 23 +++++++++++++++++++--- src/libnm-platform/nm-linux-platform.c | 21 ++++++++++++++++++++ src/libnm-platform/nm-platform.c | 27 ++++++++++++++++++++++---- src/libnm-platform/nm-platform.h | 4 ++++ 5 files changed, 70 insertions(+), 7 deletions(-) diff --git a/src/core/platform/nm-fake-platform.c b/src/core/platform/nm-fake-platform.c index cd9c316902..0c1790e797 100644 --- a/src/core/platform/nm-fake-platform.c +++ b/src/core/platform/nm-fake-platform.c @@ -716,6 +716,8 @@ link_change(NMPlatform *platform, obj_tmp = nmp_object_clone(device->obj, FALSE); obj_tmp->link.port_kind = NM_PORT_KIND_BOND; obj_tmp->link.port_data.bond.queue_id = port_data->bond.queue_id; + obj_tmp->link.port_data.bond.prio_has = port_data->bond.prio_has; + obj_tmp->link.port_data.bond.prio = port_data->bond.prio; link_set_obj(platform, device, obj_tmp); return TRUE; case NM_PORT_KIND_NONE: diff --git a/src/core/platform/tests/test-link.c b/src/core/platform/tests/test-link.c index b7002e128c..5bec6082b7 100644 --- a/src/core/platform/tests/test-link.c +++ b/src/core/platform/tests/test-link.c @@ -122,7 +122,7 @@ software_add(NMLinkType link_type, const char *name) gboolean bond0_exists = !!nm_platform_link_get_by_ifname(NM_PLATFORM_GET, "bond0"); int r; const NMPlatformLnkBond nm_platform_lnk_bond_default = { - .mode = 3, + .mode = nmtst_rand_select(3, 1), }; r = nm_platform_link_bond_add(NM_PLATFORM_GET, name, &nm_platform_lnk_bond_default, NULL); @@ -274,18 +274,35 @@ test_slave(int master, int type, SignalData *master_changed) g_assert(!nm_platform_link_is_up(NM_PLATFORM_GET, ifindex)); if (NM_IN_SET(link_type, NM_LINK_TYPE_BOND)) { - const NMPlatformLink *link; - NMPlatformLinkBondPort bond_port; + NMPlatformLinkBondPort bond_port; + gboolean prio_has; + gboolean prio_supported; + const NMPlatformLink *link; + const NMPlatformLnkBond *lnk; + + link = nmtstp_link_get_typed(NM_PLATFORM_GET, 0, SLAVE_NAME, NM_LINK_TYPE_DUMMY); + g_assert(link); + + lnk = nm_platform_link_get_lnk_bond(NM_PLATFORM_GET, master, NULL); + g_assert(lnk); + + g_assert(NM_IN_SET(lnk->mode, 3, 1)); + prio_supported = (lnk->mode == 1); + prio_has = nmtst_get_rand_bool() && prio_supported; bond_port = (NMPlatformLinkBondPort){ .queue_id = 5, + .prio_has = prio_has, + .prio = prio_has ? 6 : 0, }; + g_assert(nm_platform_link_change(NM_PLATFORM_GET, ifindex, NULL, &bond_port, 0)); accept_signals(link_changed, 1, 3); link = nmtstp_link_get(NM_PLATFORM_GET, ifindex, SLAVE_NAME); g_assert(link); g_assert_cmpint(link->port_data.bond.queue_id, ==, 5); + g_assert(link->port_data.bond.prio_has || link->port_data.bond.prio == 0); } test_link_changed_signal_arg1 = FALSE; diff --git a/src/libnm-platform/nm-linux-platform.c b/src/libnm-platform/nm-linux-platform.c index c51ccdebe9..d0a61832e7 100644 --- a/src/libnm-platform/nm-linux-platform.c +++ b/src/libnm-platform/nm-linux-platform.c @@ -179,6 +179,8 @@ G_STATIC_ASSERT(RTA_MAX == (__RTA_MAX - 1)); /*****************************************************************************/ +#define IFLA_BOND_SLAVE_PRIO 9 + #define IFLA_BOND_PEER_NOTIF_DELAY 28 #define IFLA_BOND_AD_LACP_ACTIVE 29 #define IFLA_BOND_MISSED_MAX 30 @@ -3411,6 +3413,7 @@ _new_from_nl_link(NMPlatform *platform, if (li[IFLA_INFO_SLAVE_DATA]) { static const struct nla_policy policy_bond_port[] = { [IFLA_BOND_SLAVE_QUEUE_ID] = {.type = NLA_U16}, + [IFLA_BOND_SLAVE_PRIO] = {.type = NLA_S32}, }; struct nlattr *bp[G_N_ELEMENTS(policy_bond_port)]; @@ -3422,6 +3425,21 @@ _new_from_nl_link(NMPlatform *platform, if (bp[IFLA_BOND_SLAVE_QUEUE_ID]) obj->link.port_data.bond.queue_id = nla_get_u16(bp[IFLA_BOND_SLAVE_QUEUE_ID]); + if (bp[IFLA_BOND_SLAVE_PRIO]) { + obj->link.port_data.bond.prio = nla_get_s32(bp[IFLA_BOND_SLAVE_PRIO]); + obj->link.port_data.bond.prio_has = TRUE; + if (!_nm_platform_kernel_support_detected( + NM_PLATFORM_KERNEL_SUPPORT_TYPE_IFLA_BOND_SLAVE_PRIO)) { + /* support for IFLA_BOND_SLAVE_PRIO was added in 0a2ff7cc8ad48a86939a91bd3457f38e59e741a1, + * kernel 6.0, 2 October 2022. + * + * We can only detect support if the attribute is present. A missing attribute + * is not conclusive. */ + _nm_platform_kernel_support_init( + NM_PLATFORM_KERNEL_SUPPORT_TYPE_IFLA_BOND_SLAVE_PRIO, + 1); + } + } break; case NM_PORT_KIND_NONE: break; @@ -8509,6 +8527,9 @@ link_change(NMPlatform *platform, NLA_PUT_U16(nlmsg, IFLA_BOND_SLAVE_QUEUE_ID, port_data->bond.queue_id); + if (port_data->bond.prio_has) + NLA_PUT_S32(nlmsg, IFLA_BOND_SLAVE_PRIO, port_data->bond.prio); + nla_nest_end(nlmsg, nl_port_data); nla_nest_end(nlmsg, nl_info); break; diff --git a/src/libnm-platform/nm-platform.c b/src/libnm-platform/nm-platform.c index 20ee23efb4..d0c9b4eac7 100644 --- a/src/libnm-platform/nm-platform.c +++ b/src/libnm-platform/nm-platform.c @@ -76,7 +76,12 @@ _nmp_link_port_data_to_string(NMPortKind port_kind, nm_strbuf_append_c(&sbuf, &sbuf_len, '\0'); goto out; case NM_PORT_KIND_BOND: - nm_strbuf_append(&sbuf, &sbuf_len, "port bond queue-id %u", port_data->bond.queue_id); + nm_strbuf_append(&sbuf, + &sbuf_len, + "port bond queue-id %u prio%s %" G_GINT32_FORMAT, + port_data->bond.queue_id, + !port_data->bond.prio_has ? "?" : "", + port_data->bond.prio); goto out; } @@ -2165,6 +2170,8 @@ nm_platform_link_change(NMPlatform *self, NMPlatformLinkBondPort *bond_port, NMPlatformLinkChangeFlags flags) { + char sbuf_prio[100]; + _CHECK_SELF(self, klass, FALSE); g_return_val_if_fail(ifindex >= 0, FALSE); @@ -2187,8 +2194,18 @@ nm_platform_link_change(NMPlatform *self, g_string_append_printf(str, "gso_max_segments %u ", props->gso_max_segments); if (flags & NM_PLATFORM_LINK_CHANGE_GRO_MAX_SIZE) g_string_append_printf(str, "gro_max_size %u ", props->gro_max_size); - if (bond_port) - g_string_append_printf(str, "bond-port queue-id %d", bond_port->queue_id); + if (bond_port) { + nm_assert(bond_port->prio_has || bond_port->prio == 0); + g_string_append_printf(str, + "bond-port queue-id %d %s", + bond_port->queue_id, + bond_port->prio_has || bond_port->prio != 0 + ? nm_sprintf_buf(sbuf_prio, + "prio%s %" G_GINT32_FORMAT, + !bond_port->prio_has ? "?" : "", + bond_port->prio) + : ""); + } if (str->len > 0 && str->str[str->len - 1] == ' ') g_string_truncate(str, str->len - 1); @@ -7883,7 +7900,7 @@ nm_platform_link_hash_update(const NMPlatformLink *obj, NMHashState *h) void nm_platform_link_bond_port_hash_update(const NMPlatformLinkBondPort *obj, NMHashState *h) { - nm_hash_update_vals(h, obj->queue_id); + nm_hash_update_vals(h, obj->prio, obj->queue_id, NM_HASH_COMBINE_BOOLS(guint8, obj->prio_has)); } int @@ -8014,6 +8031,8 @@ nm_platform_link_bond_port_cmp(const NMPlatformLinkBondPort *a, const NMPlatform { NM_CMP_SELF(a, b); NM_CMP_FIELD(a, b, queue_id); + NM_CMP_FIELD(a, b, prio); + NM_CMP_FIELD_BOOL(a, b, prio_has); return 0; } diff --git a/src/libnm-platform/nm-platform.h b/src/libnm-platform/nm-platform.h index e850cde392..ae8c3581da 100644 --- a/src/libnm-platform/nm-platform.h +++ b/src/libnm-platform/nm-platform.h @@ -170,7 +170,9 @@ struct _NMPlatformObjWithIfindex { } _nm_alignas(NMPlatformObject); typedef struct { + gint32 prio; guint16 queue_id; + bool prio_has : 1; } NMPlatformLinkBondPort; typedef union { @@ -1026,6 +1028,8 @@ typedef enum { * were added at the same time. */ NM_PLATFORM_KERNEL_SUPPORT_TYPE_FRA_IP_PROTO, + NM_PLATFORM_KERNEL_SUPPORT_TYPE_IFLA_BOND_SLAVE_PRIO, + _NM_PLATFORM_KERNEL_SUPPORT_NUM, } NMPlatformKernelSupportType;