From bf3c53e8cfc37a68168433a693d64e6a312d5088 Mon Sep 17 00:00:00 2001 From: Fernando Fernandez Mancera Date: Mon, 15 May 2023 16:43:27 +0200 Subject: [PATCH] add support to bond port prio property In addition: team: don't try to connect to teamd in update_connection() Resolves: #1920398 #2182029 --- 1003-suppport-bond-port-prio-rh1920398.patch | 1531 +++++++++++++++++ ...to-teamd-in-update_connect-rh2182029.patch | 52 + NetworkManager.spec | 8 +- 3 files changed, 1590 insertions(+), 1 deletion(-) create mode 100644 1003-suppport-bond-port-prio-rh1920398.patch create mode 100644 1004-team-don-t-try-to-connect-to-teamd-in-update_connect-rh2182029.patch diff --git a/1003-suppport-bond-port-prio-rh1920398.patch b/1003-suppport-bond-port-prio-rh1920398.patch new file mode 100644 index 0000000..af026e8 --- /dev/null +++ b/1003-suppport-bond-port-prio-rh1920398.patch @@ -0,0 +1,1531 @@ +From 334096f5e0cc7c210c6ddb730d0eb983ed08a48c Mon Sep 17 00:00:00 2001 +From: Fernando Fernandez Mancera +Date: Fri, 17 Mar 2023 15:59:27 +0100 +Subject: [PATCH 1/8] libnm: fix ifcfg variable documentation at queue-id + property + +The correct variable for queue-id in ifcfg is BOND_PORT_QUEUE_ID. + +(cherry picked from commit 762cd06ffa4ff56b096128c26c931843429dc8c5) +(cherry picked from commit 87316737f36202902df76e5da6ba130e7bec4dfe) +(cherry picked from commit 40c523cd78ff322954f7b696afee8baee37da810) +--- + src/libnm-core-impl/nm-setting-bond-port.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/libnm-core-impl/nm-setting-bond-port.c b/src/libnm-core-impl/nm-setting-bond-port.c +index 7ea82a763e..d1656a31ac 100644 +--- a/src/libnm-core-impl/nm-setting-bond-port.c ++++ b/src/libnm-core-impl/nm-setting-bond-port.c +@@ -148,7 +148,7 @@ nm_setting_bond_port_class_init(NMSettingBondPortClass *klass) + **/ + /* ---ifcfg-rh--- + * property: queue-id +- * variable: BONDING_OPTS: queue-id= ++ * variable: BOND_PORT_QUEUE_ID(+) + * values: 0 - 65535 + * default: 0 + * description: Queue ID. +-- +2.40.1 + + +From 495f3f1918bcde6105b74482613c51fd3b9185b0 Mon Sep 17 00:00:00 2001 +From: Beniamino Galvani +Date: Mon, 27 Feb 2023 10:55:29 +0100 +Subject: [PATCH 2/8] platform: rename link_change() to link_change_extra() + +There are many functions to replace properties of a link +(link_set_address, link_set_mtu, link_set_name, link_change, +etc.). Eventually, they will be replaced by a function that does +everything and removes all the code duplication. + +That function will be named link_change(); rename the current +link_change() to link_change_extra(). + +(cherry picked from commit babe2bacd3e23e03d5066b82ac0bb57c60b9db6f) +(cherry picked from commit 9ae85f6541505300ac811dff4671fe56a6d11ab7) +(cherry picked from commit 0a158141d3423173df0ba6983caed5d3aea8a9c8) +--- + src/libnm-platform/nm-linux-platform.c | 8 ++++---- + src/libnm-platform/nm-platform.c | 7 +++++-- + src/libnm-platform/nm-platform.h | 17 ++++++++++------- + 3 files changed, 19 insertions(+), 13 deletions(-) + +diff --git a/src/libnm-platform/nm-linux-platform.c b/src/libnm-platform/nm-linux-platform.c +index b798d12d2a..527d509498 100644 +--- a/src/libnm-platform/nm-linux-platform.c ++++ b/src/libnm-platform/nm-linux-platform.c +@@ -7984,7 +7984,7 @@ out: + } + + static int +-link_change(NMPlatform *platform, NMLinkType type, int ifindex, gconstpointer extra_data) ++link_change_extra(NMPlatform *platform, NMLinkType type, int ifindex, gconstpointer extra_data) + { + nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + +@@ -10824,9 +10824,9 @@ nm_linux_platform_class_init(NMLinuxPlatformClass *klass) + platform_class->sysctl_set_async = sysctl_set_async; + platform_class->sysctl_get = sysctl_get; + +- platform_class->link_add = link_add; +- platform_class->link_change = link_change; +- platform_class->link_delete = link_delete; ++ platform_class->link_add = link_add; ++ platform_class->link_change_extra = link_change_extra; ++ platform_class->link_delete = link_delete; + + platform_class->link_refresh = link_refresh; + +diff --git a/src/libnm-platform/nm-platform.c b/src/libnm-platform/nm-platform.c +index 198e5f0afb..ab98491b45 100644 +--- a/src/libnm-platform/nm-platform.c ++++ b/src/libnm-platform/nm-platform.c +@@ -1388,7 +1388,10 @@ nm_platform_link_add(NMPlatform *self, + } + + int +-nm_platform_link_change(NMPlatform *self, NMLinkType type, int ifindex, gconstpointer extra_data) ++nm_platform_link_change_extra(NMPlatform *self, ++ NMLinkType type, ++ int ifindex, ++ gconstpointer extra_data) + { + char buf[512]; + const char *name = nm_platform_link_get_name(self, ifindex); +@@ -1429,7 +1432,7 @@ nm_platform_link_change(NMPlatform *self, NMLinkType type, int ifindex, gconstpo + buf; + })); + +- return klass->link_change(self, type, ifindex, extra_data); ++ return klass->link_change_extra(self, type, ifindex, extra_data); + } + + /** +diff --git a/src/libnm-platform/nm-platform.h b/src/libnm-platform/nm-platform.h +index 30d0b5067c..d87eba3a63 100644 +--- a/src/libnm-platform/nm-platform.h ++++ b/src/libnm-platform/nm-platform.h +@@ -1222,9 +1222,10 @@ typedef struct { + guint32 mtu, + gconstpointer extra_data, + const NMPlatformLink **out_link); +- +- int (*link_change)(NMPlatform *self, NMLinkType type, int ifindex, gconstpointer extra_data); +- ++ int (*link_change_extra)(NMPlatform *self, ++ NMLinkType type, ++ int ifindex, ++ gconstpointer extra_data); + gboolean (*link_delete)(NMPlatform *self, int ifindex); + gboolean (*link_refresh)(NMPlatform *self, int ifindex); + gboolean (*link_set_netns)(NMPlatform *self, int ifindex, int netns_fd); +@@ -1749,8 +1750,10 @@ int nm_platform_link_add(NMPlatform *self, + gconstpointer extra_data, + const NMPlatformLink **out_link); + +-int +-nm_platform_link_change(NMPlatform *self, NMLinkType type, int ifindex, gconstpointer extra_data); ++int nm_platform_link_change_extra(NMPlatform *self, ++ NMLinkType type, ++ int ifindex, ++ gconstpointer extra_data); + + static inline int + nm_platform_link_veth_add(NMPlatform *self, +@@ -1790,13 +1793,13 @@ nm_platform_link_bridge_add(NMPlatform *self, + static inline int + nm_platform_link_bridge_change(NMPlatform *self, int ifindex, const NMPlatformLnkBridge *props) + { +- return nm_platform_link_change(self, NM_LINK_TYPE_BRIDGE, ifindex, props); ++ return nm_platform_link_change_extra(self, NM_LINK_TYPE_BRIDGE, ifindex, props); + } + + static inline int + nm_platform_link_bond_change(NMPlatform *self, int ifindex, const NMPlatformLnkBond *props) + { +- return nm_platform_link_change(self, NM_LINK_TYPE_BOND, ifindex, props); ++ return nm_platform_link_change_extra(self, NM_LINK_TYPE_BOND, ifindex, props); + } + + static inline int +-- +2.40.1 + + +From b58c3ee56f67c6e6e1e4fe0358d95df57537e6b0 Mon Sep 17 00:00:00 2001 +From: Lubomir Rintel +Date: Fri, 30 Sep 2022 22:40:03 +0200 +Subject: [PATCH 3/8] bond,bridge,team: use uuid for con.master when generating + connection + +If we're generating a connection for an externally configured slave, +refer the master by the UUID instead of the device name. + +This doesn't matter most of the time. However, on a checkpoint restore +we need to make sure that a connection that is unambiguously the original +master is up. + +Otherwise it could happen that a different connection was activated on the +same master device and the slaves being restored don't agree on which master +connection to bring up. + +I can't think of any thing that would rely on this but I've been wrong +about more serious things before. + +Fixes-test: @libnm_snapshot_reattach_unmanaged_ports_to_bridge + +https://bugzilla.redhat.com/show_bug.cgi?id=2125615 +(cherry picked from commit dc254f90e2b306700a0b81f7194e9b0438c62f4c) +(cherry picked from commit 836d7511e8b7d9660b18ee9876c635b8512f6966) +--- + src/core/devices/nm-device-bond.c | 9 +++++---- + src/core/devices/nm-device-bridge.c | 9 +++++---- + src/core/devices/team/nm-device-team.c | 9 +++++---- + 3 files changed, 15 insertions(+), 12 deletions(-) + +diff --git a/src/core/devices/nm-device-bond.c b/src/core/devices/nm-device-bond.c +index 10765b609c..9556c57321 100644 +--- a/src/core/devices/nm-device-bond.c ++++ b/src/core/devices/nm-device-bond.c +@@ -224,9 +224,10 @@ controller_update_port_connection(NMDevice *self, + GError **error) + { + NMSettingBondPort *s_port; +- int ifindex_port = nm_device_get_ifindex(port); +- uint queue_id = NM_BOND_PORT_QUEUE_ID_DEF; +- gs_free char *queue_id_str = NULL; ++ int ifindex_port = nm_device_get_ifindex(port); ++ NMConnection *applied_connection = nm_device_get_applied_connection(self); ++ uint queue_id = NM_BOND_PORT_QUEUE_ID_DEF; ++ gs_free char *queue_id_str = NULL; + + g_return_val_if_fail(ifindex_port > 0, FALSE); + +@@ -243,7 +244,7 @@ controller_update_port_connection(NMDevice *self, + + g_object_set(nm_connection_get_setting_connection(connection), + NM_SETTING_CONNECTION_MASTER, +- nm_device_get_iface(self), ++ nm_connection_get_uuid(applied_connection), + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_BOND_SETTING_NAME, + NULL); +diff --git a/src/core/devices/nm-device-bridge.c b/src/core/devices/nm-device-bridge.c +index 31cf361e8e..d8f1337058 100644 +--- a/src/core/devices/nm-device-bridge.c ++++ b/src/core/devices/nm-device-bridge.c +@@ -679,9 +679,10 @@ master_update_slave_connection(NMDevice *device, + NMDeviceBridge *self = NM_DEVICE_BRIDGE(device); + NMSettingConnection *s_con; + NMSettingBridgePort *s_port; +- int ifindex_slave = nm_device_get_ifindex(slave); +- const char *iface = nm_device_get_iface(device); +- const Option *option; ++ int ifindex_slave = nm_device_get_ifindex(slave); ++ NMConnection *applied_connection = nm_device_get_applied_connection(device); ++ ++ const Option *option; + + g_return_val_if_fail(ifindex_slave > 0, FALSE); + +@@ -717,7 +718,7 @@ master_update_slave_connection(NMDevice *device, + + g_object_set(s_con, + NM_SETTING_CONNECTION_MASTER, +- iface, ++ nm_connection_get_uuid(applied_connection), + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_BRIDGE_SETTING_NAME, + NULL); +diff --git a/src/core/devices/team/nm-device-team.c b/src/core/devices/team/nm-device-team.c +index 9eca008a10..b745158ef8 100644 +--- a/src/core/devices/team/nm-device-team.c ++++ b/src/core/devices/team/nm-device-team.c +@@ -258,9 +258,10 @@ master_update_slave_connection(NMDevice *device, + gs_free_error GError *connect_error = NULL; + int err = 0; + struct teamdctl *tdc; +- const char *team_port_config = NULL; +- const char *iface = nm_device_get_iface(device); +- const char *iface_slave = nm_device_get_iface(slave); ++ const char *team_port_config = NULL; ++ const char *iface = nm_device_get_iface(device); ++ const char *iface_slave = nm_device_get_iface(slave); ++ NMConnection *applied_connection = nm_device_get_applied_connection(device); + + tdc = _tdc_connect_new(self, iface, &connect_error); + if (!tdc) { +@@ -299,7 +300,7 @@ master_update_slave_connection(NMDevice *device, + + g_object_set(nm_connection_get_setting_connection(connection), + NM_SETTING_CONNECTION_MASTER, +- iface, ++ nm_connection_get_uuid(applied_connection), + NM_SETTING_CONNECTION_SLAVE_TYPE, + NM_SETTING_TEAM_SETTING_NAME, + NULL); +-- +2.40.1 + + +From 8a02a950e1e23f584e5f3750ceb8a69efd7b3328 Mon Sep 17 00:00:00 2001 +From: Fernando Fernandez Mancera +Date: Fri, 3 Mar 2023 16:36:23 +0100 +Subject: [PATCH 4/8] platform: add netlink support for bond port options + +sysfs is deprecated and kernel will not add new bond port options to +sysfs. Netlink is a stable API and therefore is the right method to +communicate with kernel in order to set the link options. + +(cherry picked from commit bb435674b56e876084d4c31138ea95cb3174759f) +(cherry picked from commit 1bce7f0dec6c558fff8c6689d79cb7839eb925fe) +(cherry picked from commit ee592c02dd42ccf6bd45b8927716df5715fa45f8) +--- + src/core/devices/nm-device-bond.c | 42 ++++-------- + src/core/platform/nm-fake-platform.c | 24 +++++++ + src/core/platform/tests/test-link.c | 15 +++++ + src/libnm-glib-aux/nm-shared-utils.h | 8 +++ + src/libnm-platform/nm-linux-platform.c | 79 +++++++++++++++++++++- + src/libnm-platform/nm-platform.c | 90 ++++++++++++++++++++++++++ + src/libnm-platform/nm-platform.h | 25 +++++++ + 7 files changed, 250 insertions(+), 33 deletions(-) + +diff --git a/src/core/devices/nm-device-bond.c b/src/core/devices/nm-device-bond.c +index 9556c57321..0485689d10 100644 +--- a/src/core/devices/nm-device-bond.c ++++ b/src/core/devices/nm-device-bond.c +@@ -223,24 +223,18 @@ controller_update_port_connection(NMDevice *self, + NMConnection *connection, + GError **error) + { +- NMSettingBondPort *s_port; +- int ifindex_port = nm_device_get_ifindex(port); +- NMConnection *applied_connection = nm_device_get_applied_connection(self); +- uint queue_id = NM_BOND_PORT_QUEUE_ID_DEF; +- gs_free char *queue_id_str = NULL; ++ NMSettingBondPort *s_port; ++ int ifindex_port = nm_device_get_ifindex(port); ++ NMConnection *applied_connection = nm_device_get_applied_connection(self); ++ const NMPlatformLink *pllink; + + g_return_val_if_fail(ifindex_port > 0, FALSE); + + s_port = _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_BOND_PORT); ++ pllink = nm_platform_link_get(nm_device_get_platform(port), ifindex_port); + +- queue_id_str = +- nm_platform_sysctl_slave_get_option(nm_device_get_platform(self), ifindex_port, "queue_id"); +- if (queue_id_str) { +- queue_id = +- _nm_utils_ascii_str_to_int64(queue_id_str, 10, 0, 65535, NM_BOND_PORT_QUEUE_ID_DEF); +- g_object_set(s_port, NM_SETTING_BOND_PORT_QUEUE_ID, queue_id, NULL); +- } else +- _LOGW(LOGD_BOND, "failed to read bond port setting '%s'", NM_SETTING_BOND_PORT_QUEUE_ID); ++ if (pllink && pllink->port_kind == NM_PORT_KIND_BOND) ++ g_object_set(s_port, NM_SETTING_BOND_PORT_QUEUE_ID, pllink->port_data.bond.queue_id, NULL); + + g_object_set(nm_connection_get_setting_connection(connection), + NM_SETTING_CONNECTION_MASTER, +@@ -501,23 +495,11 @@ act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason) + static void + commit_port_options(NMDevice *bond_device, NMDevice *port, NMSettingBondPort *s_port) + { +- char queue_id_str[IFNAMSIZ + NM_STRLEN(":") + 5 + 100]; +- +- /* +- * The queue-id of bond port is read only, we should modify bond interface using: +- * echo "eth1:2" > /sys/class/net/bond0/bonding/queue_id +- * Kernel allows parital editing, so no need to care about other bond ports. +- */ +- g_snprintf(queue_id_str, +- sizeof(queue_id_str), +- "%s:%" G_GUINT32_FORMAT, +- nm_device_get_iface(port), +- s_port ? nm_setting_bond_port_get_queue_id(s_port) : NM_BOND_PORT_QUEUE_ID_DEF); +- +- nm_platform_sysctl_master_set_option(nm_device_get_platform(bond_device), +- nm_device_get_ifindex(bond_device), +- "queue_id", +- queue_id_str); ++ nm_platform_link_change( ++ nm_device_get_platform(port), ++ nm_device_get_ifindex(port), ++ &((NMPlatformLinkBondPort){.queue_id = s_port ? nm_setting_bond_port_get_queue_id(s_port) ++ : NM_BOND_PORT_QUEUE_ID_DEF})); + } + + static NMTernary +diff --git a/src/core/platform/nm-fake-platform.c b/src/core/platform/nm-fake-platform.c +index a1ca5434cb..c39c45e586 100644 +--- a/src/core/platform/nm-fake-platform.c ++++ b/src/core/platform/nm-fake-platform.c +@@ -667,6 +667,29 @@ link_supports_sriov(NMPlatform *platform, int ifindex) + } + } + ++static gboolean ++link_change(NMPlatform *platform, ++ int ifindex, ++ NMPortKind port_kind, ++ const NMPlatformLinkPortData *port_data) ++{ ++ NMFakePlatformLink *device = link_get(platform, ifindex); ++ nm_auto_nmpobj NMPObject *obj_tmp = NULL; ++ ++ switch (port_kind) { ++ case NM_PORT_KIND_BOND: ++ 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; ++ link_set_obj(platform, device, obj_tmp); ++ return TRUE; ++ case NM_PORT_KIND_NONE: ++ return TRUE; ++ } ++ ++ return nm_assert_unreachable_val(TRUE); ++} ++ + static gboolean + link_enslave(NMPlatform *platform, int master, int slave) + { +@@ -1322,6 +1345,7 @@ nm_fake_platform_class_init(NMFakePlatformClass *klass) + platform_class->link_set_address = link_set_address; + platform_class->link_set_mtu = link_set_mtu; + ++ platform_class->link_change = link_change; + platform_class->link_change_flags = link_change_flags; + + platform_class->link_get_driver_info = link_get_driver_info; +diff --git a/src/core/platform/tests/test-link.c b/src/core/platform/tests/test-link.c +index b72bcb65b2..bdbfbea34f 100644 +--- a/src/core/platform/tests/test-link.c ++++ b/src/core/platform/tests/test-link.c +@@ -257,6 +257,21 @@ test_slave(int master, int type, SignalData *master_changed) + else + 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; ++ ++ bond_port = (NMPlatformLinkBondPort){ ++ .queue_id = 5, ++ }; ++ g_assert(nm_platform_link_change(NM_PLATFORM_GET, ifindex, &bond_port)); ++ 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); ++ } ++ + test_link_changed_signal_arg1 = FALSE; + test_link_changed_signal_arg2 = FALSE; + g_signal_connect(NM_PLATFORM_GET, +diff --git a/src/libnm-glib-aux/nm-shared-utils.h b/src/libnm-glib-aux/nm-shared-utils.h +index 53cf7f3e57..b6cbf95504 100644 +--- a/src/libnm-glib-aux/nm-shared-utils.h ++++ b/src/libnm-glib-aux/nm-shared-utils.h +@@ -93,6 +93,14 @@ G_STATIC_ASSERT(sizeof(int) == sizeof(gint32)); + + /*****************************************************************************/ + ++typedef enum _nm_packed { ++ /* No type, empty value */ ++ NM_PORT_KIND_NONE, ++ NM_PORT_KIND_BOND, ++} NMPortKind; ++ ++/*****************************************************************************/ ++ + typedef enum { + + /* No type, used as error value */ +diff --git a/src/libnm-platform/nm-linux-platform.c b/src/libnm-platform/nm-linux-platform.c +index 527d509498..8158f364d2 100644 +--- a/src/libnm-platform/nm-linux-platform.c ++++ b/src/libnm-platform/nm-linux-platform.c +@@ -3241,9 +3241,11 @@ _new_from_nl_link(NMPlatform *platform, + + if (tb[IFLA_LINKINFO]) { + static const struct nla_policy policy_link_info[] = { +- [IFLA_INFO_KIND] = {.type = NLA_STRING}, +- [IFLA_INFO_DATA] = {.type = NLA_NESTED}, +- [IFLA_INFO_XSTATS] = {.type = NLA_NESTED}, ++ [IFLA_INFO_KIND] = {.type = NLA_STRING}, ++ [IFLA_INFO_DATA] = {.type = NLA_NESTED}, ++ [IFLA_INFO_XSTATS] = {.type = NLA_NESTED}, ++ [IFLA_INFO_SLAVE_KIND] = {.type = NLA_STRING}, ++ [IFLA_INFO_SLAVE_DATA] = {.type = NLA_NESTED}, + }; + struct nlattr *li[G_N_ELEMENTS(policy_link_info)]; + +@@ -3254,6 +3256,33 @@ _new_from_nl_link(NMPlatform *platform, + nl_info_kind = nla_get_string(li[IFLA_INFO_KIND]); + + nl_info_data = li[IFLA_INFO_DATA]; ++ ++ if (li[IFLA_INFO_SLAVE_KIND]) { ++ const char *s = nla_get_string(li[IFLA_INFO_SLAVE_KIND]); ++ ++ if (nm_streq(s, "bond")) ++ obj->link.port_kind = NM_PORT_KIND_BOND; ++ } ++ ++ if (li[IFLA_INFO_SLAVE_DATA]) { ++ static const struct nla_policy policy_bond_port[] = { ++ [IFLA_BOND_SLAVE_QUEUE_ID] = {.type = NLA_U16}, ++ }; ++ struct nlattr *bp[G_N_ELEMENTS(policy_bond_port)]; ++ ++ switch (obj->link.port_kind) { ++ case NM_PORT_KIND_BOND: ++ if (nla_parse_nested_arr(bp, li[IFLA_INFO_SLAVE_DATA], policy_bond_port) < 0) ++ return NULL; ++ ++ if (bp[IFLA_BOND_SLAVE_QUEUE_ID]) ++ obj->link.port_data.bond.queue_id = nla_get_u16(bp[IFLA_BOND_SLAVE_QUEUE_ID]); ++ ++ break; ++ case NM_PORT_KIND_NONE: ++ break; ++ } ++ } + } + + if (tb[IFLA_STATS64]) { +@@ -8061,6 +8090,48 @@ link_delete(NMPlatform *platform, int ifindex) + return do_delete_object(platform, &obj_id, nlmsg); + } + ++static gboolean ++link_change(NMPlatform *platform, ++ int ifindex, ++ NMPortKind port_kind, ++ const NMPlatformLinkPortData *port_data) ++{ ++ nm_auto_nlmsg struct nl_msg *nlmsg = NULL; ++ struct nlattr *nl_info; ++ struct nlattr *nl_port_data; ++ ++ nlmsg = _nl_msg_new_link(RTM_NEWLINK, 0, ifindex, NULL); ++ if (!nlmsg) ++ return FALSE; ++ ++ switch (port_kind) { ++ case NM_PORT_KIND_BOND: ++ ++ nm_assert(port_data); ++ ++ if (!(nl_info = nla_nest_start(nlmsg, IFLA_LINKINFO))) ++ goto nla_put_failure; ++ ++ nm_assert(nm_streq0("bond", nm_link_type_to_rtnl_type_string(NM_LINK_TYPE_BOND))); ++ NLA_PUT_STRING(nlmsg, IFLA_INFO_SLAVE_KIND, "bond"); ++ ++ if (!(nl_port_data = nla_nest_start(nlmsg, IFLA_INFO_SLAVE_DATA))) ++ goto nla_put_failure; ++ ++ NLA_PUT_U16(nlmsg, IFLA_BOND_SLAVE_QUEUE_ID, port_data->bond.queue_id); ++ ++ nla_nest_end(nlmsg, nl_port_data); ++ nla_nest_end(nlmsg, nl_info); ++ break; ++ case NM_PORT_KIND_NONE: ++ break; ++ } ++ ++ return do_change_link(platform, CHANGE_LINK_TYPE_UNSPEC, ifindex, nlmsg, NULL) == 0; ++nla_put_failure: ++ g_return_val_if_reached(FALSE); ++} ++ + static gboolean + link_refresh(NMPlatform *platform, int ifindex) + { +@@ -10828,6 +10899,8 @@ nm_linux_platform_class_init(NMLinuxPlatformClass *klass) + platform_class->link_change_extra = link_change_extra; + platform_class->link_delete = link_delete; + ++ platform_class->link_change = link_change; ++ + platform_class->link_refresh = link_refresh; + + platform_class->link_set_netns = link_set_netns; +diff --git a/src/libnm-platform/nm-platform.c b/src/libnm-platform/nm-platform.c +index ab98491b45..01568243a3 100644 +--- a/src/libnm-platform/nm-platform.c ++++ b/src/libnm-platform/nm-platform.c +@@ -61,6 +61,31 @@ G_STATIC_ASSERT(sizeof(((NMPlatformLink *) NULL)->l_address.data) == _NM_UTILS_H + G_STATIC_ASSERT(sizeof(((NMPlatformLink *) NULL)->l_perm_address.data) == _NM_UTILS_HWADDR_LEN_MAX); + G_STATIC_ASSERT(sizeof(((NMPlatformLink *) NULL)->l_broadcast.data) == _NM_UTILS_HWADDR_LEN_MAX); + ++static const char * ++_nmp_link_port_data_to_string(NMPortKind port_kind, ++ const NMPlatformLinkPortData *port_data, ++ char *sbuf, ++ gsize sbuf_len) ++{ ++ const char *sbuf0 = sbuf; ++ ++ nm_assert(port_data); ++ ++ switch (port_kind) { ++ case NM_PORT_KIND_NONE: ++ 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); ++ goto out; ++ } ++ ++ nm_strbuf_append(&sbuf, &sbuf_len, "invalid-port-type %d", (int) port_kind); ++ ++out: ++ return sbuf0; ++} ++ + static const char * + _nmp_link_address_to_string(const NMPLinkAddress *addr, + char buf[static(_NM_UTILS_HWADDR_LEN_MAX * 3)]) +@@ -2092,6 +2117,31 @@ nm_platform_link_set_name(NMPlatform *self, int ifindex, const char *name) + return klass->link_set_name(self, ifindex, name); + } + ++gboolean ++nm_platform_link_change(NMPlatform *self, int ifindex, NMPlatformLinkBondPort *bond_port) ++{ ++ _CHECK_SELF(self, klass, FALSE); ++ ++ g_return_val_if_fail(ifindex >= 0, FALSE); ++ ++ if (_LOGD_ENABLED()) { ++ nm_auto_free_gstring GString *str = g_string_new(""); ++ ++ if (bond_port) ++ g_string_append_printf(str, "bond-port queue-id %d", bond_port->queue_id); ++ ++ if (str->len > 0 && str->str[str->len - 1] == ' ') ++ g_string_truncate(str, str->len - 1); ++ ++ _LOG3D("link: change: %s", str->str); ++ } ++ ++ return klass->link_change(self, ++ ifindex, ++ bond_port ? NM_PORT_KIND_BOND : NM_PORT_KIND_NONE, ++ (const NMPlatformLinkPortData *) bond_port); ++} ++ + /** + * nm_platform_link_get_physical_port_id: + * @self: platform instance +@@ -5893,6 +5943,7 @@ nm_platform_link_to_string(const NMPlatformLink *link, char *buf, gsize len) + char *s; + gsize l; + char str_addrmode[30]; ++ char str_port_data[200]; + char str_address[_NM_UTILS_HWADDR_LEN_MAX * 3]; + char str_perm_address[_NM_UTILS_HWADDR_LEN_MAX * 3]; + char str_broadcast[_NM_UTILS_HWADDR_LEN_MAX * 3]; +@@ -5936,6 +5987,11 @@ nm_platform_link_to_string(const NMPlatformLink *link, char *buf, gsize len) + _nmp_link_address_to_string(&link->l_perm_address, str_perm_address); + _nmp_link_address_to_string(&link->l_broadcast, str_broadcast); + ++ _nmp_link_port_data_to_string(link->port_kind, ++ &link->port_data, ++ str_port_data, ++ sizeof(str_port_data)); ++ + str_link_type = nm_link_type_to_string(link->type); + + g_snprintf( +@@ -5957,6 +6013,7 @@ nm_platform_link_to_string(const NMPlatformLink *link, char *buf, gsize len) + "%s%s" /* l_broadcast */ + "%s%s" /* inet6_token */ + "%s%s" /* driver */ ++ "%s%s" /* port_data */ + " rx:%" G_GUINT64_FORMAT ",%" G_GUINT64_FORMAT " tx:%" G_GUINT64_FORMAT + ",%" G_GUINT64_FORMAT, + link->ifindex, +@@ -5989,6 +6046,7 @@ nm_platform_link_to_string(const NMPlatformLink *link, char *buf, gsize len) + : "", + link->driver ? " driver " : "", + link->driver ?: "", ++ NM_PRINT_FMT_QUOTED2(str_port_data[0] != '\0', " ", str_port_data, ""), + link->rx_packets, + link->rx_bytes, + link->tx_packets, +@@ -7927,6 +7985,7 @@ nm_platform_link_hash_update(const NMPlatformLink *obj, NMHashState *h) + obj->arptype, + obj->inet6_addr_gen_mode_inv, + obj->inet6_token, ++ obj->port_kind, + obj->rx_packets, + obj->rx_bytes, + obj->tx_packets, +@@ -7945,6 +8004,20 @@ nm_platform_link_hash_update(const NMPlatformLink *obj, NMHashState *h) + nm_hash_update_mem(h, + obj->l_broadcast.data, + NM_MIN(obj->l_broadcast.len, sizeof(obj->l_broadcast.data))); ++ ++ switch (obj->port_kind) { ++ case NM_PORT_KIND_NONE: ++ break; ++ case NM_PORT_KIND_BOND: ++ nm_platform_link_bond_port_hash_update(&obj->port_data.bond, h); ++ break; ++ } ++} ++ ++void ++nm_platform_link_bond_port_hash_update(const NMPlatformLinkBondPort *obj, NMHashState *h) ++{ ++ nm_hash_update_vals(h, obj->queue_id); + } + + int +@@ -7974,6 +8047,14 @@ nm_platform_link_cmp(const NMPlatformLink *a, const NMPlatformLink *b) + if (a->l_broadcast.len) + NM_CMP_FIELD_MEMCMP_LEN(a, b, l_broadcast.data, a->l_broadcast.len); + NM_CMP_FIELD_MEMCMP(a, b, inet6_token); ++ NM_CMP_FIELD(a, b, port_kind); ++ switch (a->port_kind) { ++ case NM_PORT_KIND_NONE: ++ break; ++ case NM_PORT_KIND_BOND: ++ NM_CMP_RETURN(nm_platform_link_bond_port_cmp(&a->port_data.bond, &b->port_data.bond)); ++ break; ++ } + NM_CMP_FIELD(a, b, rx_packets); + NM_CMP_FIELD(a, b, rx_bytes); + NM_CMP_FIELD(a, b, tx_packets); +@@ -8053,6 +8134,15 @@ nm_platform_lnk_bond_hash_update(const NMPlatformLnkBond *obj, NMHashState *h) + nm_hash_update(h, obj->arp_ip_target, obj->arp_ip_targets_num * sizeof(obj->arp_ip_target[0])); + } + ++int ++nm_platform_link_bond_port_cmp(const NMPlatformLinkBondPort *a, const NMPlatformLinkBondPort *b) ++{ ++ NM_CMP_SELF(a, b); ++ NM_CMP_FIELD(a, b, queue_id); ++ ++ return 0; ++} ++ + int + nm_platform_lnk_bond_cmp(const NMPlatformLnkBond *a, const NMPlatformLnkBond *b) + { +diff --git a/src/libnm-platform/nm-platform.h b/src/libnm-platform/nm-platform.h +index d87eba3a63..f48662d900 100644 +--- a/src/libnm-platform/nm-platform.h ++++ b/src/libnm-platform/nm-platform.h +@@ -216,6 +216,14 @@ struct _NMPlatformObjWithIfindex { + __NMPlatformObjWithIfindex_COMMON; + }; + ++typedef struct { ++ guint16 queue_id; ++} NMPlatformLinkBondPort; ++ ++typedef union { ++ NMPlatformLinkBondPort bond; ++} NMPlatformLinkPortData; ++ + struct _NMPlatformLink { + __NMPlatformObjWithIfindex_COMMON; + char name[NMP_IFNAMSIZ]; +@@ -266,6 +274,12 @@ struct _NMPlatformLink { + guint64 tx_packets; + guint64 tx_bytes; + ++ /* IFLA_INFO_SLAVE_KIND */ ++ NMPortKind port_kind; ++ ++ /* an interface can only hold IFLA_INFO_SLAVE_DATA for one link type */ ++ NMPlatformLinkPortData port_data; ++ + /* @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; +@@ -1226,6 +1240,10 @@ typedef struct { + NMLinkType type, + int ifindex, + gconstpointer extra_data); ++ gboolean (*link_change)(NMPlatform *self, ++ int ifindex, ++ NMPortKind port_kind, ++ const NMPlatformLinkPortData *port_data); + gboolean (*link_delete)(NMPlatform *self, int ifindex); + gboolean (*link_refresh)(NMPlatform *self, int ifindex); + gboolean (*link_set_netns)(NMPlatform *self, int ifindex, int netns_fd); +@@ -2073,6 +2091,8 @@ nm_platform_link_change_flags(NMPlatform *self, int ifindex, unsigned value, gbo + return nm_platform_link_change_flags_full(self, ifindex, value, set ? value : 0u); + } + ++gboolean nm_platform_link_change(NMPlatform *self, int ifindex, NMPlatformLinkBondPort *bond_port); ++ + gboolean nm_platform_link_get_udev_property(NMPlatform *self, + int ifindex, + const char *name, +@@ -2563,6 +2583,11 @@ int nm_platform_tfilter_cmp(const NMPlatformTfilter *a, const NMPlatformTfilter + int nm_platform_mptcp_addr_cmp(const NMPlatformMptcpAddr *a, const NMPlatformMptcpAddr *b); + + void nm_platform_link_hash_update(const NMPlatformLink *obj, NMHashState *h); ++ ++void nm_platform_link_bond_port_hash_update(const NMPlatformLinkBondPort *obj, NMHashState *h); ++int nm_platform_link_bond_port_cmp(const NMPlatformLinkBondPort *a, ++ const NMPlatformLinkBondPort *b); ++ + void nm_platform_ip4_address_hash_update(const NMPlatformIP4Address *obj, NMHashState *h); + void nm_platform_ip6_address_hash_update(const NMPlatformIP6Address *obj, NMHashState *h); + void nm_platform_ip4_route_hash_update(const NMPlatformIP4Route *obj, +-- +2.40.1 + + +From 2ed620bce381b612cff7a14871b8939b48fdaca3 Mon Sep 17 00:00:00 2001 +From: Fernando Fernandez Mancera +Date: Thu, 9 Mar 2023 12:18:14 +0100 +Subject: [PATCH 5/8] platform: add support to prio property in bond ports + +(cherry picked from commit e200b162914d3bda4c03a19652124330a99bb3ae) +(cherry picked from commit 84f17a2fbb73d592a29645003d7d76a9e8b332ca) +(cherry picked from commit c787d22fc8194dc6d07c6b842b5a8a5944f42dc7) +--- + 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 | 32 ++++++++++++++++++++++---- + src/libnm-platform/nm-platform.h | 10 +++++--- + 5 files changed, 78 insertions(+), 10 deletions(-) + +diff --git a/src/core/platform/nm-fake-platform.c b/src/core/platform/nm-fake-platform.c +index c39c45e586..46f374d95c 100644 +--- a/src/core/platform/nm-fake-platform.c ++++ b/src/core/platform/nm-fake-platform.c +@@ -681,6 +681,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 bdbfbea34f..ac1f0d6ff6 100644 +--- a/src/core/platform/tests/test-link.c ++++ b/src/core/platform/tests/test-link.c +@@ -112,7 +112,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); +@@ -258,18 +258,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, &bond_port)); + 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 8158f364d2..19ccb09a86 100644 +--- a/src/libnm-platform/nm-linux-platform.c ++++ b/src/libnm-platform/nm-linux-platform.c +@@ -177,6 +177,8 @@ G_STATIC_ASSERT(RTA_MAX == (__RTA_MAX - 1)); + + /*****************************************************************************/ + ++#define IFLA_BOND_SLAVE_PRIO 9 ++ + #define IFLA_BOND_PEER_NOTIF_DELAY 28 + + #undef IFLA_BOND_MAX +@@ -3267,6 +3269,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)]; + +@@ -3278,6 +3281,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; +@@ -8120,6 +8138,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 01568243a3..d64c85674a 100644 +--- a/src/libnm-platform/nm-platform.c ++++ b/src/libnm-platform/nm-platform.c +@@ -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; + } + +@@ -2120,6 +2130,8 @@ nm_platform_link_set_name(NMPlatform *self, int ifindex, const char *name) + gboolean + nm_platform_link_change(NMPlatform *self, int ifindex, NMPlatformLinkBondPort *bond_port) + { ++ char sbuf_prio[100]; ++ + _CHECK_SELF(self, klass, FALSE); + + g_return_val_if_fail(ifindex >= 0, FALSE); +@@ -2127,8 +2139,18 @@ nm_platform_link_change(NMPlatform *self, int ifindex, NMPlatformLinkBondPort *b + if (_LOGD_ENABLED()) { + nm_auto_free_gstring GString *str = g_string_new(""); + +- 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); +@@ -8017,7 +8039,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 +@@ -8139,6 +8161,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 f48662d900..611f50f901 100644 +--- a/src/libnm-platform/nm-platform.h ++++ b/src/libnm-platform/nm-platform.h +@@ -217,7 +217,9 @@ struct _NMPlatformObjWithIfindex { + }; + + typedef struct { ++ gint32 prio; + guint16 queue_id; ++ bool prio_has : 1; + } NMPlatformLinkBondPort; + + typedef union { +@@ -274,12 +276,12 @@ struct _NMPlatformLink { + guint64 tx_packets; + guint64 tx_bytes; + +- /* 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; +@@ -1140,6 +1142,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; + +-- +2.40.1 + + +From 17badd932a2422a1d493ec3ad962d811f3854136 Mon Sep 17 00:00:00 2001 +From: Fernando Fernandez Mancera +Date: Tue, 9 May 2023 12:46:09 +0200 +Subject: [PATCH 6/8] libnm: add NM_VERSION_1_40_20 + +(cherry picked from commit 4fd186bbf6cf9f791c7166a04c9ef4b7ec101a80) +--- + src/libnm-core-public/nm-version-macros.h.in | 1 + + src/libnm-core-public/nm-version.h | 6 ++++++ + 2 files changed, 7 insertions(+) + +diff --git a/src/libnm-core-public/nm-version-macros.h.in b/src/libnm-core-public/nm-version-macros.h.in +index fc854aef86..cb3350f19c 100644 +--- a/src/libnm-core-public/nm-version-macros.h.in ++++ b/src/libnm-core-public/nm-version-macros.h.in +@@ -73,6 +73,7 @@ + #define NM_VERSION_1_38 (NM_ENCODE_VERSION (1, 38, 0)) + #define NM_VERSION_1_40 (NM_ENCODE_VERSION (1, 40, 0)) + #define NM_VERSION_1_40_4 (NM_ENCODE_VERSION (1, 40, 4)) ++#define NM_VERSION_1_40_20 (NM_ENCODE_VERSION (1, 40, 20)) + + /* For releases, NM_API_VERSION is equal to NM_VERSION. + * +diff --git a/src/libnm-core-public/nm-version.h b/src/libnm-core-public/nm-version.h +index d9f9a12121..5b924ce620 100644 +--- a/src/libnm-core-public/nm-version.h ++++ b/src/libnm-core-public/nm-version.h +@@ -347,6 +347,12 @@ + #define NM_AVAILABLE_IN_1_40_4 + #endif + ++#if NM_VERSION_MAX_ALLOWED < NM_VERSION_1_40_20 ++#define NM_AVAILABLE_IN_1_40_20 G_UNAVAILABLE(1, 40.20) ++#else ++#define NM_AVAILABLE_IN_1_40_20 ++#endif ++ + /* + * Synchronous API for calling D-Bus in libnm is deprecated. See + * https://networkmanager.dev/docs/libnm/latest/usage.html#sync-api +-- +2.40.1 + + +From 7f3f3f50cf7d71c16c532dd73e0d4a2d6ffc129f Mon Sep 17 00:00:00 2001 +From: Fernando Fernandez Mancera +Date: Thu, 9 Mar 2023 12:18:14 +0100 +Subject: [PATCH 7/8] bonding: add support to prio property in bond ports + +Add per port priority support for bond active port re-selection during +failover. A higher number means a higher priority in selection. The +primary port still has the highest priority. This option is only +compatible with active-backup, balance-tlb and balance-alb modes. + +(cherry picked from commit 2f0571f1930ff2c11de4f48b4433ca5fe6c897a0) +(cherry picked from commit 748f6388aa0217b2c1c8bf879697ce48bcba8317) +(cherry picked from commit d36620e654b20146e49209c191b7230936cc1596) +--- + src/core/devices/nm-device-bond.c | 58 +++++++++++++++++-- + .../plugins/ifcfg-rh/nms-ifcfg-rh-reader.c | 23 ++++++-- + .../plugins/ifcfg-rh/nms-ifcfg-rh-utils.c | 1 + + .../plugins/ifcfg-rh/nms-ifcfg-rh-utils.h | 2 +- + .../plugins/ifcfg-rh/nms-ifcfg-rh-writer.c | 4 +- + .../plugins/ifcfg-rh/tests/test-ifcfg-rh.c | 1 + + src/libnm-base/nm-base.h | 1 + + src/libnm-client-impl/libnm.ver | 5 ++ + src/libnm-client-impl/tests/test-gir.py | 4 +- + src/libnm-core-impl/nm-setting-bond-port.c | 48 ++++++++++++++- + src/libnm-core-public/nm-setting-bond-port.h | 4 ++ + src/libnmc-setting/nm-meta-setting-desc.c | 6 ++ + src/libnmc-setting/settings-docs.h.in | 1 + + .../generate-docs-nm-settings-nmcli.xml.in | 3 + + 14 files changed, 146 insertions(+), 15 deletions(-) + +diff --git a/src/core/devices/nm-device-bond.c b/src/core/devices/nm-device-bond.c +index 0485689d10..9ecb2ac7ae 100644 +--- a/src/core/devices/nm-device-bond.c ++++ b/src/core/devices/nm-device-bond.c +@@ -234,7 +234,12 @@ controller_update_port_connection(NMDevice *self, + pllink = nm_platform_link_get(nm_device_get_platform(port), ifindex_port); + + if (pllink && pllink->port_kind == NM_PORT_KIND_BOND) +- g_object_set(s_port, NM_SETTING_BOND_PORT_QUEUE_ID, pllink->port_data.bond.queue_id, NULL); ++ g_object_set(s_port, ++ NM_SETTING_BOND_PORT_QUEUE_ID, ++ pllink->port_data.bond.queue_id, ++ NM_SETTING_BOND_PORT_PRIO, ++ pllink->port_data.bond.prio, ++ NULL); + + g_object_set(nm_connection_get_setting_connection(connection), + NM_SETTING_CONNECTION_MASTER, +@@ -495,11 +500,52 @@ act_stage1_prepare(NMDevice *device, NMDeviceStateReason *out_failure_reason) + static void + commit_port_options(NMDevice *bond_device, NMDevice *port, NMSettingBondPort *s_port) + { +- nm_platform_link_change( +- nm_device_get_platform(port), +- nm_device_get_ifindex(port), +- &((NMPlatformLinkBondPort){.queue_id = s_port ? nm_setting_bond_port_get_queue_id(s_port) +- : NM_BOND_PORT_QUEUE_ID_DEF})); ++ NMBondMode mode = NM_BOND_MODE_UNKNOWN; ++ const char *value; ++ NMSettingBond *s_bond; ++ gint32 prio; ++ gboolean prio_has; ++ ++ s_bond = nm_device_get_applied_setting(bond_device, NM_TYPE_SETTING_BOND); ++ if (s_bond) { ++ value = nm_setting_bond_get_option_normalized(s_bond, NM_SETTING_BOND_OPTION_MODE); ++ mode = _nm_setting_bond_mode_from_string(value); ++ } ++ ++ prio = s_port ? nm_setting_bond_port_get_prio(s_port) : NM_BOND_PORT_PRIO_DEF; ++ ++ if (prio != 0) { ++ /* The profile explicitly sets the priority. No matter what, we try to set it ++ * in netlink. */ ++ prio_has = TRUE; ++ } else if (!NM_IN_SET(mode, NM_BOND_MODE_ACTIVEBACKUP, NM_BOND_MODE_TLB, NM_BOND_MODE_ALB)) { ++ /* The priority only is configurable with certain modes. If we don't have ++ * one of those modes, don't try to set the priority explicitly to zero. */ ++ prio_has = FALSE; ++ } else if (nm_platform_kernel_support_get_full( ++ NM_PLATFORM_KERNEL_SUPPORT_TYPE_IFLA_BOND_SLAVE_PRIO, ++ FALSE) ++ == NM_OPTION_BOOL_TRUE) { ++ /* We can only detect support if we have it. We cannot detect lack of support if ++ * we don't have it. ++ * ++ * But we did explicitly detect support, so explicitly set the prio to zero. */ ++ prio_has = TRUE; ++ } else { ++ /* We either have an unsuitable mode or didn't detect kernel support for the ++ * priority. Don't explicitly set priority to zero. It is already the default, ++ * so it shouldn't be necessary. */ ++ prio_has = FALSE; ++ } ++ ++ nm_platform_link_change(nm_device_get_platform(port), ++ nm_device_get_ifindex(port), ++ &((NMPlatformLinkBondPort){ ++ .queue_id = s_port ? nm_setting_bond_port_get_queue_id(s_port) ++ : NM_BOND_PORT_QUEUE_ID_DEF, ++ .prio = prio_has ? prio : 0, ++ .prio_has = prio_has, ++ })); + } + + static NMTernary +diff --git a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c +index 4d8e7bd69b..02ba843201 100644 +--- a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c ++++ b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c +@@ -5557,6 +5557,7 @@ make_bond_port_setting(shvarFile *ifcfg) + gs_free char *value_to_free = NULL; + const char *value; + guint queue_id; ++ gint32 prio; + + g_return_val_if_fail(ifcfg != NULL, FALSE); + +@@ -5565,11 +5566,23 @@ make_bond_port_setting(shvarFile *ifcfg) + s_port = nm_setting_bond_port_new(); + queue_id = + _nm_utils_ascii_str_to_uint64(value, 10, 0, G_MAXUINT16, NM_BOND_PORT_QUEUE_ID_DEF); +- if (errno != 0) { +- PARSE_WARNING("Invalid bond port queue_id value '%s'", value); +- return s_port; +- } +- g_object_set(G_OBJECT(s_port), NM_SETTING_BOND_PORT_QUEUE_ID, queue_id, NULL); ++ if (errno != 0) ++ PARSE_WARNING("Invalid bond port queue_id value BOND_PORT_QUEUE_ID '%s'", value); ++ else ++ g_object_set(G_OBJECT(s_port), NM_SETTING_BOND_PORT_QUEUE_ID, queue_id, NULL); ++ } ++ ++ nm_clear_g_free(&value_to_free); ++ value = svGetValue(ifcfg, "BOND_PORT_PRIO", &value_to_free); ++ if (value) { ++ if (!s_port) ++ s_port = nm_setting_bond_port_new(); ++ prio = ++ _nm_utils_ascii_str_to_int64(value, 10, G_MININT32, G_MAXINT32, NM_BOND_PORT_PRIO_DEF); ++ if (errno != 0) ++ PARSE_WARNING("Invalid bond port prio value BOND_PORT_PRIO '%s'", value); ++ else ++ g_object_set(G_OBJECT(s_port), NM_SETTING_BOND_PORT_PRIO, prio, NULL); + } + + return s_port; +diff --git a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c +index e1ef817478..ef4276da73 100644 +--- a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c ++++ b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.c +@@ -827,6 +827,7 @@ const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[] = { + _KEY_TYPE("BAND", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("BONDING_MASTER", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("BONDING_OPTS", NMS_IFCFG_KEY_TYPE_IS_PLAIN), ++ _KEY_TYPE("BOND_PORT_PRIO", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("BOND_PORT_QUEUE_ID", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("BOOTPROTO", NMS_IFCFG_KEY_TYPE_IS_PLAIN), + _KEY_TYPE("BRIDGE", NMS_IFCFG_KEY_TYPE_IS_PLAIN), +diff --git a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h +index d1f8dbad9c..e3d3d87321 100644 +--- a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h ++++ b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-utils.h +@@ -33,7 +33,7 @@ typedef struct { + NMSIfcfgKeyTypeFlags key_flags; + } NMSIfcfgKeyTypeInfo; + +-extern const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[256]; ++extern const NMSIfcfgKeyTypeInfo nms_ifcfg_well_known_keys[257]; + + const NMSIfcfgKeyTypeInfo *nms_ifcfg_well_known_key_find_info(const char *key, gssize *out_idx); + +diff --git a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c +index e8948c3dd0..e340c9fe13 100644 +--- a/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c ++++ b/src/core/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c +@@ -1910,8 +1910,10 @@ write_bond_port_setting(NMConnection *connection, shvarFile *ifcfg) + NMSettingBondPort *s_port; + + s_port = _nm_connection_get_setting(connection, NM_TYPE_SETTING_BOND_PORT); +- if (s_port) ++ if (s_port) { + svSetValueInt64(ifcfg, "BOND_PORT_QUEUE_ID", nm_setting_bond_port_get_queue_id(s_port)); ++ svSetValueInt64(ifcfg, "BOND_PORT_PRIO", nm_setting_bond_port_get_prio(s_port)); ++ } + } + + static gboolean +diff --git a/src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c b/src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +index 886a605fb2..d2ac2b29db 100644 +--- a/src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c ++++ b/src/core/settings/plugins/ifcfg-rh/tests/test-ifcfg-rh.c +@@ -8325,6 +8325,7 @@ test_write_bond_port(void) + + s_bond_port = _nm_connection_new_setting(connection, NM_TYPE_SETTING_BOND_PORT); + g_object_set(s_bond_port, NM_SETTING_BOND_PORT_QUEUE_ID, 1, NULL); ++ g_object_set(s_bond_port, NM_SETTING_BOND_PORT_PRIO, 10, NULL); + + nmtst_assert_connection_verifies(connection); + +diff --git a/src/libnm-base/nm-base.h b/src/libnm-base/nm-base.h +index 28feb48429..b9161c7680 100644 +--- a/src/libnm-base/nm-base.h ++++ b/src/libnm-base/nm-base.h +@@ -392,6 +392,7 @@ typedef struct { + /****************************************************************************/ + + #define NM_BOND_PORT_QUEUE_ID_DEF 0 ++#define NM_BOND_PORT_PRIO_DEF 0 + + /*****************************************************************************/ + +diff --git a/src/libnm-client-impl/libnm.ver b/src/libnm-client-impl/libnm.ver +index 2478defa34..7c98646253 100644 +--- a/src/libnm-client-impl/libnm.ver ++++ b/src/libnm-client-impl/libnm.ver +@@ -1878,3 +1878,8 @@ global: + nm_utils_ip_routes_to_variant; + nm_vpn_plugin_info_supports_multiple; + } libnm_1_40_0; ++ ++libnm_1_40_20_bondp { ++global: ++ nm_setting_bond_port_get_prio; ++} libnm_1_40_0; +diff --git a/src/libnm-client-impl/tests/test-gir.py b/src/libnm-client-impl/tests/test-gir.py +index d91849b8fe..84919dd533 100755 +--- a/src/libnm-client-impl/tests/test-gir.py ++++ b/src/libnm-client-impl/tests/test-gir.py +@@ -97,8 +97,10 @@ def syms_from_ver(verfile): + ): + c_syms[str_removesuffix(line, ";")] = version + +- # This one is... messy. ++ # These are exceptions and we cannot know the version for the symbol so we ++ # harcode it. + c_syms["nm_ethtool_optname_is_feature"] = "1.20" ++ c_syms["nm_setting_bond_port_get_prio"] = "1.44" + + return c_syms + +diff --git a/src/libnm-core-impl/nm-setting-bond-port.c b/src/libnm-core-impl/nm-setting-bond-port.c +index d1656a31ac..a6daad8b19 100644 +--- a/src/libnm-core-impl/nm-setting-bond-port.c ++++ b/src/libnm-core-impl/nm-setting-bond-port.c +@@ -22,9 +22,10 @@ + + /*****************************************************************************/ + +-NM_GOBJECT_PROPERTIES_DEFINE(NMSettingBondPort, PROP_QUEUE_ID, ); ++NM_GOBJECT_PROPERTIES_DEFINE(NMSettingBondPort, PROP_QUEUE_ID, PROP_PRIO, ); + + typedef struct { ++ gint32 prio; + guint32 queue_id; + } NMSettingBondPortPrivate; + +@@ -65,6 +66,22 @@ nm_setting_bond_port_get_queue_id(NMSettingBondPort *setting) + return NM_SETTING_BOND_PORT_GET_PRIVATE(setting)->queue_id; + } + ++/** ++ * nm_setting_bond_port_get_prio: ++ * @setting: the #NMSettingBondPort ++ * ++ * Returns: the #NMSettingBondPort:prio property of the setting ++ * ++ * Since: 1.44, 1.42.8, 1.40.20, rhel-8.9 ++ **/ ++gint32 ++nm_setting_bond_port_get_prio(NMSettingBondPort *setting) ++{ ++ g_return_val_if_fail(NM_IS_SETTING_BOND_PORT(setting), 0); ++ ++ return NM_SETTING_BOND_PORT_GET_PRIVATE(setting)->prio; ++} ++ + /*****************************************************************************/ + + static gboolean +@@ -165,6 +182,35 @@ nm_setting_bond_port_class_init(NMSettingBondPortClass *klass) + NMSettingBondPort, + _priv.queue_id); + ++ /** ++ * NMSettingBondPort:prio: ++ * ++ * The port priority for bond active port re-selection during failover. A ++ * higher number means a higher priority in selection. The primary port has ++ * the highest priority. This option is only compatible with active-backup, ++ * balance-tlb and balance-alb modes. ++ * ++ * Since: 1.44, 1.42.8, 1.40.20, rhel-8.9 ++ **/ ++ /* ---ifcfg-rh--- ++ * property: prio ++ * variable: BOND_PORT_PRIO(+) ++ * values: -2147483648 - 2147483647 ++ * default: 0 ++ * description: Port priority. ++ * ---end--- ++ */ ++ _nm_setting_property_define_direct_int32(properties_override, ++ obj_properties, ++ NM_SETTING_BOND_PORT_PRIO, ++ PROP_PRIO, ++ G_MININT32, ++ G_MAXINT32, ++ NM_BOND_PORT_PRIO_DEF, ++ NM_SETTING_PARAM_INFERRABLE, ++ NMSettingBondPort, ++ _priv.prio); ++ + g_object_class_install_properties(object_class, _PROPERTY_ENUMS_LAST, obj_properties); + + _nm_setting_class_commit(setting_class, +diff --git a/src/libnm-core-public/nm-setting-bond-port.h b/src/libnm-core-public/nm-setting-bond-port.h +index 0b20e4a8cb..abaedfcd6d 100644 +--- a/src/libnm-core-public/nm-setting-bond-port.h ++++ b/src/libnm-core-public/nm-setting-bond-port.h +@@ -29,6 +29,7 @@ G_BEGIN_DECLS + #define NM_SETTING_BOND_PORT_SETTING_NAME "bond-port" + + #define NM_SETTING_BOND_PORT_QUEUE_ID "queue-id" ++#define NM_SETTING_BOND_PORT_PRIO "prio" + + typedef struct _NMSettingBondPortClass NMSettingBondPortClass; + +@@ -41,6 +42,9 @@ NMSetting *nm_setting_bond_port_new(void); + NM_AVAILABLE_IN_1_34 + guint32 nm_setting_bond_port_get_queue_id(NMSettingBondPort *setting); + ++NM_AVAILABLE_IN_1_40_20 ++gint32 nm_setting_bond_port_get_prio(NMSettingBondPort *setting); ++ + G_END_DECLS + + #endif /* __NM_SETTING_BOND_PORT_H__ */ +diff --git a/src/libnmc-setting/nm-meta-setting-desc.c b/src/libnmc-setting/nm-meta-setting-desc.c +index 31beb65ef9..5714722de2 100644 +--- a/src/libnmc-setting/nm-meta-setting-desc.c ++++ b/src/libnmc-setting/nm-meta-setting-desc.c +@@ -5154,6 +5154,12 @@ static const NMMetaPropertyInfo *const property_infos_BOND_PORT[] = { + .prompt = N_("Queue ID"), + .property_type = &_pt_gobject_int, + ), ++ PROPERTY_INFO_WITH_DESC (NM_SETTING_BOND_PORT_PRIO, ++ .is_cli_option = TRUE, ++ .property_alias = "prio", ++ .prompt = N_("Port Priority"), ++ .property_type= &_pt_gobject_int, ++ ), + NULL + }; + +diff --git a/src/libnmc-setting/settings-docs.h.in b/src/libnmc-setting/settings-docs.h.in +index 62edc77f6b..6a5f416348 100644 +--- a/src/libnmc-setting/settings-docs.h.in ++++ b/src/libnmc-setting/settings-docs.h.in +@@ -426,6 +426,7 @@ + #define DESCRIBE_DOC_NM_SETTING_WPAN_PAGE N_("IEEE 802.15.4 channel page. A positive integer or -1, meaning \"do not set, use whatever the device is already set to\".") + #define DESCRIBE_DOC_NM_SETTING_WPAN_PAN_ID N_("IEEE 802.15.4 Personal Area Network (PAN) identifier.") + #define DESCRIBE_DOC_NM_SETTING_WPAN_SHORT_ADDRESS N_("Short IEEE 802.15.4 address to be used within a restricted environment.") ++#define DESCRIBE_DOC_NM_SETTING_BOND_PORT_PRIO N_("The port priority for bond active port re-selection during failover. A higher number means a higher priority in selection. The primary port has the highest priority. This option is only compatible with active-backup, balance-tlb and balance-alb modes.") + #define DESCRIBE_DOC_NM_SETTING_BOND_PORT_QUEUE_ID N_("The queue ID of this bond port. The maximum value of queue ID is the number of TX queues currently active in device.") + #define DESCRIBE_DOC_NM_SETTING_HOSTNAME_FROM_DHCP N_("Whether the system hostname can be determined from DHCP on this connection. When set to NM_TERNARY_DEFAULT (-1), the value from global configuration is used. If the property doesn't have a value in the global configuration, NetworkManager assumes the value to be NM_TERNARY_TRUE (1).") + #define DESCRIBE_DOC_NM_SETTING_HOSTNAME_FROM_DNS_LOOKUP N_("Whether the system hostname can be determined from reverse DNS lookup of addresses on this device. When set to NM_TERNARY_DEFAULT (-1), the value from global configuration is used. If the property doesn't have a value in the global configuration, NetworkManager assumes the value to be NM_TERNARY_TRUE (1).") +diff --git a/src/nmcli/generate-docs-nm-settings-nmcli.xml.in b/src/nmcli/generate-docs-nm-settings-nmcli.xml.in +index 03e6c0b54b..adf7895f0d 100644 +--- a/src/nmcli/generate-docs-nm-settings-nmcli.xml.in ++++ b/src/nmcli/generate-docs-nm-settings-nmcli.xml.in +@@ -271,6 +271,9 @@ + ++ + + + +Date: Wed, 10 May 2023 18:18:18 +0200 +Subject: [PATCH 8/8] tests: adjust test-gir.py to allow extra elements in + section name + +(cherry picked from commit 9b8220c9fa6c26257fe809171355b29219efe26a) +(cherry picked from commit 56e19bdf685ebc152eaf0cc8d2571387b8ea669b) +(cherry picked from commit ca41be98a075e03e61dc7e898d772792c0a65619) +--- + src/libnm-client-impl/tests/test-gir.py | 18 +++++------------- + 1 file changed, 5 insertions(+), 13 deletions(-) + +diff --git a/src/libnm-client-impl/tests/test-gir.py b/src/libnm-client-impl/tests/test-gir.py +index 84919dd533..50b2fade6b 100755 +--- a/src/libnm-client-impl/tests/test-gir.py ++++ b/src/libnm-client-impl/tests/test-gir.py +@@ -7,6 +7,7 @@ + from __future__ import print_function + import xml.etree.ElementTree as ET + import argparse ++import re + import sys + + C_NS = "http://www.gtk.org/introspection/c/1.0" +@@ -60,17 +61,6 @@ def str_removesuffix(string, suffix): + return string + + +-# Older Python doesn't have str.removeprefix() +-def str_removeprefix(string, prefix): +- try: +- return string.removeprefix(prefix) +- except AttributeError: +- if string.startswith(prefix): +- return string[len(prefix) :] +- else: +- return string +- +- + def syms_from_ver(verfile): + c_syms = {} + for line in open(verfile).readlines(): +@@ -78,8 +68,10 @@ def syms_from_ver(verfile): + + if line.endswith("{"): + line = str_removesuffix(line, " {") +- line = str_removeprefix(line, "libnm_") +- (major, minor, micro) = line.split("_") ++ m = re.search(r"^libnm_([0-9]+)_([0-9]+)_([0-9]+)$", line) ++ if not m: ++ continue ++ (major, minor, micro) = m.groups() + if int(major) > 1 or int(minor) > 0: + if int(micro) > 0: + # Snap to next major version. Perhaps not +-- +2.40.1 + diff --git a/1004-team-don-t-try-to-connect-to-teamd-in-update_connect-rh2182029.patch b/1004-team-don-t-try-to-connect-to-teamd-in-update_connect-rh2182029.patch new file mode 100644 index 0000000..48a3c92 --- /dev/null +++ b/1004-team-don-t-try-to-connect-to-teamd-in-update_connect-rh2182029.patch @@ -0,0 +1,52 @@ +From 4a9d5b23ab513f0ee0b8f490e522f60d4ef3e4cd Mon Sep 17 00:00:00 2001 +From: Beniamino Galvani +Date: Thu, 4 May 2023 15:11:49 +0200 +Subject: [PATCH] team: don't try to connect to teamd in update_connection() + +In constructed(), NMDevice starts watching the D-Bus name owner or +monitoring the unix socket, and so it is always aware if teamd is +running. When it is, NMDevice connects to it and initializes +priv->tdc. + +It is not useful to try to connect to teamd in update_connection() +because warnings will be generated by NM and by libteam if teamd is +not running. As explained above the connection is always initialized +when teamd is available, and so we can just check priv->tdc. + +Fixes: ab586236e36b ('core: implement update_connection() for Team') + +https://bugzilla.redhat.com/show_bug.cgi?id=2182029 +https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1631 +(cherry picked from commit 93430627c245a0b33b873edca329fa716ccfb7d6) +(cherry picked from commit b60f0dd0a20db232c7edc01faa4562ce510ed107) +(cherry picked from commit f6f1a44559990765a5cbc940a74f54df5d8a30d0) +--- + src/core/devices/team/nm-device-team.c | 9 +-------- + 1 file changed, 1 insertion(+), 8 deletions(-) + +diff --git a/src/core/devices/team/nm-device-team.c b/src/core/devices/team/nm-device-team.c +index b745158ef8..1d2beb5e8a 100644 +--- a/src/core/devices/team/nm-device-team.c ++++ b/src/core/devices/team/nm-device-team.c +@@ -228,17 +228,10 @@ update_connection(NMDevice *device, NMConnection *connection) + NMDeviceTeam *self = NM_DEVICE_TEAM(device); + NMSettingTeam *s_team = _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_TEAM); + NMDeviceTeamPrivate *priv = NM_DEVICE_TEAM_GET_PRIVATE(self); +- struct teamdctl *tdc = priv->tdc; + + /* Read the configuration only if not already set */ +- if (!priv->config && ensure_teamd_connection(device)) ++ if (!priv->config && priv->tdc) { + teamd_read_config(self); +- +- /* Restore previous tdc state */ +- if (priv->tdc && !tdc) { +- teamdctl_disconnect(priv->tdc); +- teamdctl_free(priv->tdc); +- priv->tdc = NULL; + } + + g_object_set(G_OBJECT(s_team), NM_SETTING_TEAM_CONFIG, _get_config(self), NULL); +-- +2.40.1 + diff --git a/NetworkManager.spec b/NetworkManager.spec index 7872caa..e3d4b35 100644 --- a/NetworkManager.spec +++ b/NetworkManager.spec @@ -6,7 +6,7 @@ %global epoch_version 1 %global real_version 1.40.16 %global rpm_version %{real_version} -%global release_version 4 +%global release_version 5 %global snapshot %{nil} %global git_sha %{nil} %global bcond_default_debug 0 @@ -198,6 +198,8 @@ Patch3: 0003-order-ipv6-addresses.patch # Patch1001: 1001-some.patch Patch1001: 1001-cloud-setup-IMDSv2-rh2151987.patch Patch1002: 1002-dns-add-support-to-no-aaaa-option-rh2144521.patch +Patch1003: 1003-suppport-bond-port-prio-rh1920398.patch +Patch1004: 1004-team-don-t-try-to-connect-to-teamd-in-update_connect-rh2182029.patch Requires(post): systemd %if 0%{?fedora} || 0%{?rhel} >= 8 @@ -1233,6 +1235,10 @@ fi %changelog +* Wed May 17 2023 Fernando Fernandez Mancera - 1:1.40.16-5 +- support bond port prio property (rh #1920398) +- team: don't try to connect to teamd in update_connection() (rh #2182029) + * Wed Apr 19 2023 Beniamino Galvani - 1:1.40.16-4 - support the "no-aaaa" resolv.conf option (rh #2144521)