platform: add support to prio property in bond ports

This commit is contained in:
Fernando Fernandez Mancera 2023-03-09 12:18:14 +01:00
parent bb435674b5
commit e200b16291
5 changed files with 78 additions and 10 deletions

View file

@ -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:

View file

@ -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;

View file

@ -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;

View file

@ -68,6 +68,7 @@ _nmp_link_port_data_to_string(NMPortKind port_kind,
gsize sbuf_len)
{
const char *sbuf0 = sbuf;
char s0[120];
nm_assert(port_data);
@ -76,7 +77,16 @@ _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%s",
port_data->bond.queue_id,
port_data->bond.prio_has || port_data->bond.prio != 0
? nm_sprintf_buf(s0,
" prio%s %u",
port_data->bond.prio_has ? "" : "?",
port_data->bond.prio)
: "");
goto out;
}
@ -2165,6 +2175,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 +2199,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 +7905,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 +8036,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;
}

View file

@ -170,7 +170,9 @@ struct _NMPlatformObjWithIfindex {
} _nm_alignas(NMPlatformObject);
typedef struct {
gint32 prio;
guint16 queue_id;
bool prio_has : 1;
} NMPlatformLinkBondPort;
typedef union {
@ -229,12 +231,12 @@ struct _NMPlatformLink {
NMPlatformLinkProps link_props;
/* IFLA_INFO_SLAVE_KIND */
NMPortKind port_kind;
/* an interface can only hold IFLA_INFO_SLAVE_DATA for one link type */
NMPlatformLinkPortData port_data;
/* IFLA_INFO_SLAVE_KIND */
NMPortKind port_kind;
/* @connected is mostly identical to (@n_ifi_flags & IFF_UP). Except for bridge/bond masters,
* where we coerce the link as disconnect if it has no slaves. */
bool connected : 1;
@ -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;