summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2023-10-09 12:27:00 +0000
committerBeniamino Galvani <bgalvani@redhat.com>2023-10-09 12:27:00 +0000
commit8ed1b8daec5ea902ac9aff79773721caa89b2328 (patch)
treef6dc3b9f741427b5b85cec83cf23f96a1b3fa743
parent6fa4a45470e95c1ab0794476cc9da1604be0e97f (diff)
parentb38e8c053bf53ff98fb4e522b3ea769a926f0181 (diff)
merge: branch 'bridge-netlink'ih/test-jira
platform: add netlink support for bridge port options https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1685
-rw-r--r--src/core/devices/nm-device-bond.c1
-rw-r--r--src/core/devices/nm-device-bridge.c173
-rw-r--r--src/core/devices/nm-device.c3
-rw-r--r--src/core/platform/nm-fake-platform.c8
-rw-r--r--src/core/platform/tests/test-link.c41
-rw-r--r--src/libnm-glib-aux/nm-shared-utils.h1
-rw-r--r--src/libnm-platform/nm-linux-platform.c43
-rw-r--r--src/libnm-platform/nm-platform.c59
-rw-r--r--src/libnm-platform/nm-platform.h13
9 files changed, 189 insertions, 153 deletions
diff --git a/src/core/devices/nm-device-bond.c b/src/core/devices/nm-device-bond.c
index 10fe809204..bc5d3bfcae 100644
--- a/src/core/devices/nm-device-bond.c
+++ b/src/core/devices/nm-device-bond.c
@@ -683,6 +683,7 @@ commit_port_options(NMDevice *bond_device, NMDevice *port, NMSettingBondPort *s_
.prio = prio_has ? prio : 0,
.prio_has = prio_has,
}),
+ NULL,
0);
}
diff --git a/src/core/devices/nm-device-bridge.c b/src/core/devices/nm-device-bridge.c
index 9a45dbf3fc..4fffcc0502 100644
--- a/src/core/devices/nm-device-bridge.c
+++ b/src/core/devices/nm-device-bridge.c
@@ -421,22 +421,6 @@ static const Option master_options[] = {
0,
}};
-static const Option slave_options[] = {
- OPTION(NM_SETTING_BRIDGE_PORT_PRIORITY,
- "priority",
- OPTION_TYPE_INT(NM_BRIDGE_PORT_PRIORITY_MIN,
- NM_BRIDGE_PORT_PRIORITY_MAX,
- NM_BRIDGE_PORT_PRIORITY_DEF),
- .default_if_zero = TRUE, ),
- OPTION(NM_SETTING_BRIDGE_PORT_PATH_COST,
- "path_cost",
- OPTION_TYPE_INT(NM_BRIDGE_PORT_PATH_COST_MIN,
- NM_BRIDGE_PORT_PATH_COST_MAX,
- NM_BRIDGE_PORT_PATH_COST_DEF),
- .default_if_zero = TRUE, ),
- OPTION(NM_SETTING_BRIDGE_PORT_HAIRPIN_MODE, "hairpin_mode", OPTION_TYPE_BOOL(FALSE), ),
- {0}};
-
static const NMPlatformBridgeVlan **
setting_vlans_to_platform(GPtrArray *array)
{
@@ -473,90 +457,26 @@ setting_vlans_to_platform(GPtrArray *array)
static void
commit_port_options(NMDevice *device, NMSettingBridgePort *setting)
{
- const Option *option;
- NMSetting *s;
- gs_unref_object NMSetting *s_clear = NULL;
- int ifindex = nm_device_get_ifindex(device);
-
- if (setting)
- s = NM_SETTING(setting);
- else
- s = s_clear = nm_setting_bridge_port_new();
-
- for (option = slave_options; option->name; option++) {
- nm_auto_unset_gvalue GValue val = G_VALUE_INIT;
- GParamSpec *pspec;
- const char *value;
- char value_buf[100];
-
- pspec = g_object_class_find_property(G_OBJECT_GET_CLASS(s), option->name);
- nm_assert(pspec);
-
- g_value_init(&val, G_PARAM_SPEC_VALUE_TYPE(pspec));
- g_object_get_property((GObject *) s, option->name, &val);
-
- if (option->to_sysfs) {
- value = option->to_sysfs(&val);
- goto out;
- }
-
- switch (pspec->value_type) {
- case G_TYPE_BOOLEAN:
- value = g_value_get_boolean(&val) ? "1" : "0";
- break;
- case G_TYPE_UINT64:
- case G_TYPE_UINT:
- {
- guint64 uval;
-
- if (pspec->value_type == G_TYPE_UINT64)
- uval = g_value_get_uint64(&val);
- else
- uval = (guint) g_value_get_uint(&val);
-
- /* zero means "unspecified" for some NM properties but isn't in the
- * allowed kernel range, so reset the property to the default value.
- */
- if (option->default_if_zero && uval == 0) {
- if (pspec->value_type == G_TYPE_UINT64)
- uval = NM_G_PARAM_SPEC_GET_DEFAULT_UINT64(pspec);
- else
- uval = NM_G_PARAM_SPEC_GET_DEFAULT_UINT(pspec);
- }
-
- /* Linux kernel bridge interfaces use 'centiseconds' for time-based values.
- * In reality it's not centiseconds, but depends on HZ and USER_HZ, which
- * is almost always works out to be a multiplier of 100, so we can assume
- * centiseconds. See clock_t_to_jiffies().
- */
- if (option->user_hz_compensate)
- uval *= 100;
-
- if (pspec->value_type == G_TYPE_UINT64)
- nm_sprintf_buf(value_buf, "%" G_GUINT64_FORMAT, uval);
- else
- nm_sprintf_buf(value_buf, "%u", (guint) uval);
-
- value = value_buf;
- } break;
- case G_TYPE_STRING:
- value = g_value_get_string(&val);
- break;
- default:
- nm_assert_not_reached();
- value = NULL;
- break;
- }
-
-out:
- if (!value)
- return;
-
- nm_platform_sysctl_slave_set_option(nm_device_get_platform(device),
- ifindex,
- option->sysname,
- value);
- }
+ guint32 path_cost, priority;
+
+ path_cost = nm_setting_bridge_port_get_path_cost(setting);
+ if (path_cost == 0)
+ path_cost = NM_BRIDGE_PORT_PATH_COST_DEF;
+
+ priority = nm_setting_bridge_port_get_priority(setting);
+ if (priority == 0)
+ priority = NM_BRIDGE_PORT_PRIORITY_DEF;
+
+ nm_platform_link_change(nm_device_get_platform(device),
+ nm_device_get_ifindex(device),
+ NULL,
+ NULL,
+ &((NMPlatformLinkBridgePort){
+ .path_cost = path_cost,
+ .priority = priority,
+ .hairpin = nm_setting_bridge_port_get_hairpin_mode(setting),
+ }),
+ 0);
}
static void
@@ -662,44 +582,31 @@ master_update_slave_connection(NMDevice *device,
NMConnection *connection,
GError **error)
{
- NMDeviceBridge *self = NM_DEVICE_BRIDGE(device);
- NMSettingConnection *s_con;
- NMSettingBridgePort *s_port;
- int ifindex_slave = nm_device_get_ifindex(slave);
- NMConnection *applied_connection = nm_device_get_applied_connection(device);
-
- const Option *option;
+ NMSettingConnection *s_con;
+ NMSettingBridgePort *s_port;
+ int ifindex_slave = nm_device_get_ifindex(slave);
+ NMConnection *applied_connection = nm_device_get_applied_connection(device);
+ const NMPlatformLink *pllink;
g_return_val_if_fail(ifindex_slave > 0, FALSE);
s_con = nm_connection_get_setting_connection(connection);
s_port = _nm_connection_ensure_setting(connection, NM_TYPE_SETTING_BRIDGE_PORT);
-
- for (option = slave_options; option->name; option++) {
- gs_free char *str = nm_platform_sysctl_slave_get_option(nm_device_get_platform(device),
- ifindex_slave,
- option->sysname);
- uint value;
-
- if (str) {
- /* See comments in set_sysfs_uint() about centiseconds. */
- if (option->user_hz_compensate) {
- value = _nm_utils_ascii_str_to_int64(str,
- 10,
- option->nm_min * 100,
- option->nm_max * 100,
- option->nm_default * 100);
- value /= 100;
- } else {
- value = _nm_utils_ascii_str_to_int64(str,
- 10,
- option->nm_min,
- option->nm_max,
- option->nm_default);
- }
- g_object_set(s_port, option->name, value, NULL);
- } else
- _LOGW(LOGD_BRIDGE, "failed to read bridge port setting '%s'", option->sysname);
+ pllink = nm_platform_link_get(nm_device_get_platform(slave), ifindex_slave);
+
+ if (pllink && pllink->port_kind == NM_PORT_KIND_BRIDGE) {
+ g_object_set(s_port,
+ NM_SETTING_BRIDGE_PORT_PATH_COST,
+ pllink->port_data.bridge.path_cost,
+ NULL);
+ g_object_set(s_port,
+ NM_SETTING_BRIDGE_PORT_PRIORITY,
+ pllink->port_data.bridge.priority,
+ NULL);
+ g_object_set(s_port,
+ NM_SETTING_BRIDGE_PORT_HAIRPIN_MODE,
+ pllink->port_data.bridge.hairpin,
+ NULL);
}
g_object_set(s_con,
diff --git a/src/core/devices/nm-device.c b/src/core/devices/nm-device.c
index fb8169376c..4f4715b06d 100644
--- a/src/core/devices/nm-device.c
+++ b/src/core/devices/nm-device.c
@@ -2863,7 +2863,7 @@ nm_device_link_properties_set(NMDevice *self, gboolean reapply)
_RESET(NM_PLATFORM_LINK_CHANGE_GSO_MAX_SEGMENTS, gso_max_segments);
_RESET(NM_PLATFORM_LINK_CHANGE_GRO_MAX_SIZE, gro_max_size);
- if (nm_platform_link_change(platform, ifindex, &props, NULL, flags)) {
+ if (nm_platform_link_change(platform, ifindex, &props, NULL, NULL, flags)) {
_LOGD(LOGD_DEVICE, "link properties successfully set");
} else {
_LOGW(LOGD_DEVICE, "failure setting link properties");
@@ -2891,6 +2891,7 @@ link_properties_reset(NMDevice *self)
ifindex,
&priv->link_props_state.props,
NULL,
+ NULL,
priv->link_props_state.flags)) {
_LOGD(LOGD_DEVICE, "link properties successfully reset");
} else {
diff --git a/src/core/platform/nm-fake-platform.c b/src/core/platform/nm-fake-platform.c
index f6f377d470..74bbe4fb58 100644
--- a/src/core/platform/nm-fake-platform.c
+++ b/src/core/platform/nm-fake-platform.c
@@ -720,6 +720,14 @@ link_change(NMPlatform *platform,
obj_tmp->link.port_data.bond.prio = port_data->bond.prio;
link_set_obj(platform, device, obj_tmp);
return TRUE;
+ case NM_PORT_KIND_BRIDGE:
+ obj_tmp = nmp_object_clone(device->obj, FALSE);
+ obj_tmp->link.port_kind = NM_PORT_KIND_BRIDGE;
+ obj_tmp->link.port_data.bridge.path_cost = port_data->bridge.path_cost;
+ obj_tmp->link.port_data.bridge.priority = port_data->bridge.priority;
+ obj_tmp->link.port_data.bridge.hairpin = port_data->bridge.hairpin;
+ link_set_obj(platform, device, obj_tmp);
+ return TRUE;
case NM_PORT_KIND_NONE:
return TRUE;
}
diff --git a/src/core/platform/tests/test-link.c b/src/core/platform/tests/test-link.c
index 8a54ac4853..c931605baa 100644
--- a/src/core/platform/tests/test-link.c
+++ b/src/core/platform/tests/test-link.c
@@ -230,7 +230,6 @@ test_port(int controller, int port_type, SignalData *controller_changed)
link_callback,
SLAVE_NAME);
SignalData *link_changed, *link_removed;
- char *value;
NMLinkType controller_type = nm_platform_link_get_type(NM_PLATFORM_GET, controller);
gboolean test_link_changed_signal_arg1;
gboolean test_link_changed_signal_arg2;
@@ -296,7 +295,7 @@ test_port(int controller, int port_type, SignalData *controller_changed)
.prio = prio_has ? 6 : 0,
};
- g_assert(nm_platform_link_change(NM_PLATFORM_GET, ifindex_port, NULL, &bond_port, 0));
+ g_assert(nm_platform_link_change(NM_PLATFORM_GET, ifindex_port, NULL, &bond_port, NULL, 0));
accept_signals(link_changed, 1, 3);
link = nmtstp_link_get(NM_PLATFORM_GET, ifindex_port, SLAVE_NAME);
@@ -306,13 +305,35 @@ test_port(int controller, int port_type, SignalData *controller_changed)
} else if (controller_type == NM_LINK_TYPE_BRIDGE) {
/* Skip this part for nm-fake-platform */
if (nmtstp_is_root_test() && nmtstp_is_sysfs_writable()) {
- g_assert(nm_platform_sysctl_slave_set_option(NM_PLATFORM_GET,
- ifindex_port,
- "priority",
- "614"));
- value = nm_platform_sysctl_slave_get_option(NM_PLATFORM_GET, ifindex_port, "priority");
- g_assert_cmpstr(value, ==, "614");
- g_free(value);
+ NMPlatformLinkBridgePort bridge_port;
+ const NMPlatformLink *link;
+ const NMPlatformLnkBridge *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_bridge(NM_PLATFORM_GET, controller, NULL);
+ g_assert(lnk);
+
+ bridge_port = (NMPlatformLinkBridgePort){
+ .path_cost = 100,
+ .priority = 614,
+ .hairpin = 0,
+ };
+
+ g_assert(nm_platform_link_change(NM_PLATFORM_GET,
+ ifindex_port,
+ NULL,
+ NULL,
+ &bridge_port,
+ 0));
+ accept_signals(link_changed, 1, 3);
+
+ link = nmtstp_link_get(NM_PLATFORM_GET, ifindex_port, SLAVE_NAME);
+ g_assert(link);
+ g_assert_cmpint(link->port_data.bridge.path_cost, ==, 100);
+ g_assert_cmpint(link->port_data.bridge.priority, ==, 614);
+ g_assert_cmpint(link->port_data.bridge.hairpin, ==, 0);
}
}
@@ -2692,7 +2713,7 @@ test_link_set_properties(void)
| NM_PLATFORM_LINK_CHANGE_GSO_MAX_SEGMENTS;
ifindex = nmtstp_link_dummy_add(NM_PLATFORM_GET, FALSE, "dummy1")->ifindex;
- g_assert(nm_platform_link_change(NM_PLATFORM_GET, ifindex, &props, NULL, flags));
+ g_assert(nm_platform_link_change(NM_PLATFORM_GET, ifindex, &props, NULL, NULL, flags));
link = nmtstp_link_get(NM_PLATFORM_GET, ifindex, "dummy1");
g_assert(link);
diff --git a/src/libnm-glib-aux/nm-shared-utils.h b/src/libnm-glib-aux/nm-shared-utils.h
index e37cf5e654..2a2312fb90 100644
--- a/src/libnm-glib-aux/nm-shared-utils.h
+++ b/src/libnm-glib-aux/nm-shared-utils.h
@@ -97,6 +97,7 @@ typedef enum _nm_packed {
/* No type, empty value */
NM_PORT_KIND_NONE,
NM_PORT_KIND_BOND,
+ NM_PORT_KIND_BRIDGE,
} NMPortKind;
/*****************************************************************************/
diff --git a/src/libnm-platform/nm-linux-platform.c b/src/libnm-platform/nm-linux-platform.c
index c23667dffa..0880e91977 100644
--- a/src/libnm-platform/nm-linux-platform.c
+++ b/src/libnm-platform/nm-linux-platform.c
@@ -3408,6 +3408,8 @@ _new_from_nl_link(NMPlatform *platform,
if (nm_streq(s, "bond"))
obj->link.port_kind = NM_PORT_KIND_BOND;
+ else if (nm_streq(s, "bridge"))
+ obj->link.port_kind = NM_PORT_KIND_BRIDGE;
}
if (li[IFLA_INFO_SLAVE_DATA]) {
@@ -3415,7 +3417,13 @@ _new_from_nl_link(NMPlatform *platform,
[IFLA_BOND_SLAVE_QUEUE_ID] = {.type = NLA_U16},
[IFLA_BOND_SLAVE_PRIO] = {.type = NLA_S32},
};
- struct nlattr *bp[G_N_ELEMENTS(policy_bond_port)];
+ struct nlattr *bp[G_N_ELEMENTS(policy_bond_port)];
+ static const struct nla_policy policy_bridge_port[] = {
+ [IFLA_BRPORT_COST] = {.type = NLA_U32},
+ [IFLA_BRPORT_PRIORITY] = {.type = NLA_U16},
+ [IFLA_BRPORT_MODE] = {.type = NLA_U8},
+ };
+ struct nlattr *brp[G_N_ELEMENTS(policy_bridge_port)];
switch (obj->link.port_kind) {
case NM_PORT_KIND_BOND:
@@ -3441,6 +3449,19 @@ _new_from_nl_link(NMPlatform *platform,
}
}
break;
+ case NM_PORT_KIND_BRIDGE:
+ if (nla_parse_nested_arr(brp, li[IFLA_INFO_SLAVE_DATA], policy_bridge_port) < 0)
+ return NULL;
+
+ if (brp[IFLA_BRPORT_COST])
+ obj->link.port_data.bridge.path_cost = nla_get_u32(brp[IFLA_BRPORT_COST]);
+
+ if (brp[IFLA_BRPORT_PRIORITY])
+ obj->link.port_data.bridge.priority = nla_get_u16(brp[IFLA_BRPORT_PRIORITY]);
+
+ if (brp[IFLA_BRPORT_MODE])
+ obj->link.port_data.bridge.hairpin = nla_get_u8(brp[IFLA_BRPORT_MODE]);
+ break;
case NM_PORT_KIND_NONE:
break;
}
@@ -8533,6 +8554,26 @@ link_change(NMPlatform *platform,
nla_nest_end(nlmsg, nl_port_data);
nla_nest_end(nlmsg, nl_info);
break;
+ case NM_PORT_KIND_BRIDGE:
+
+ nm_assert(port_data);
+
+ if (!(nl_info = nla_nest_start(nlmsg, IFLA_LINKINFO)))
+ goto nla_put_failure;
+
+ nm_assert(nm_streq0("bridge", nm_link_type_to_rtnl_type_string(NM_LINK_TYPE_BRIDGE)));
+ NLA_PUT_STRING(nlmsg, IFLA_INFO_SLAVE_KIND, "bridge");
+
+ if (!(nl_port_data = nla_nest_start(nlmsg, IFLA_INFO_SLAVE_DATA)))
+ goto nla_put_failure;
+
+ NLA_PUT_U32(nlmsg, IFLA_BRPORT_COST, port_data->bridge.path_cost);
+ NLA_PUT_U16(nlmsg, IFLA_BRPORT_PRIORITY, port_data->bridge.priority);
+ NLA_PUT_U8(nlmsg, IFLA_BRPORT_MODE, port_data->bridge.hairpin);
+
+ nla_nest_end(nlmsg, nl_port_data);
+ nla_nest_end(nlmsg, nl_info);
+ break;
case NM_PORT_KIND_NONE:
break;
}
diff --git a/src/libnm-platform/nm-platform.c b/src/libnm-platform/nm-platform.c
index 3c8dfc2f5f..7bd9de4121 100644
--- a/src/libnm-platform/nm-platform.c
+++ b/src/libnm-platform/nm-platform.c
@@ -88,6 +88,14 @@ _nmp_link_port_data_to_string(NMPortKind port_kind,
port_data->bond.prio)
: "");
goto out;
+ case NM_PORT_KIND_BRIDGE:
+ nm_strbuf_append(&sbuf,
+ &sbuf_len,
+ "port bridge path_cost %u priority %u hairpin %s",
+ port_data->bridge.path_cost,
+ port_data->bridge.priority,
+ port_data->bridge.hairpin ? "true" : "false");
+ goto out;
}
nm_strbuf_append(&sbuf, &sbuf_len, "invalid-port-type %d", (int) port_kind);
@@ -2173,9 +2181,12 @@ nm_platform_link_change(NMPlatform *self,
int ifindex,
NMPlatformLinkProps *props,
NMPlatformLinkBondPort *bond_port,
+ NMPlatformLinkBridgePort *bridge_port,
NMPlatformLinkChangeFlags flags)
{
- char sbuf_prio[100];
+ NMPortKind port_kind = NM_PORT_KIND_NONE;
+ NMPlatformLinkPortData port_data;
+ char sbuf_prio[100];
_CHECK_SELF(self, klass, FALSE);
@@ -2187,6 +2198,7 @@ nm_platform_link_change(NMPlatform *self,
| NM_PLATFORM_LINK_CHANGE_GSO_MAX_SEGMENTS
| NM_PLATFORM_LINK_CHANGE_GRO_MAX_SIZE)
|| props);
+ nm_assert((!!bond_port + !!bridge_port) <= 1);
if (_LOGD_ENABLED()) {
nm_auto_free_gstring GString *str = g_string_new("");
@@ -2210,6 +2222,12 @@ nm_platform_link_change(NMPlatform *self,
!bond_port->prio_has ? "?" : "",
bond_port->prio)
: "");
+ } else if (bridge_port) {
+ g_string_append_printf(str,
+ "bridge-port path_cost %u priority %u hairpin %s",
+ bridge_port->path_cost,
+ bridge_port->priority,
+ bridge_port->hairpin ? "true" : "false");
}
if (str->len > 0 && str->str[str->len - 1] == ' ')
@@ -2218,12 +2236,15 @@ nm_platform_link_change(NMPlatform *self,
_LOG3D("link: change: %s", str->str);
}
- return klass->link_change(self,
- ifindex,
- props,
- bond_port ? NM_PORT_KIND_BOND : NM_PORT_KIND_NONE,
- (const NMPlatformLinkPortData *) bond_port,
- flags);
+ if (bond_port) {
+ port_data.bond = *bond_port;
+ port_kind = NM_PORT_KIND_BOND;
+ } else if (bridge_port) {
+ port_data.bridge = *bridge_port;
+ port_kind = NM_PORT_KIND_BRIDGE;
+ }
+
+ return klass->link_change(self, ifindex, props, port_kind, &port_data, flags);
}
/**
@@ -7879,6 +7900,9 @@ nm_platform_link_hash_update(const NMPlatformLink *obj, NMHashState *h)
case NM_PORT_KIND_BOND:
nm_platform_link_bond_port_hash_update(&obj->port_data.bond, h);
break;
+ case NM_PORT_KIND_BRIDGE:
+ nm_platform_link_bridge_port_hash_update(&obj->port_data.bridge, h);
+ break;
}
}
@@ -7888,6 +7912,12 @@ nm_platform_link_bond_port_hash_update(const NMPlatformLinkBondPort *obj, NMHash
nm_hash_update_vals(h, obj->prio, obj->queue_id, NM_HASH_COMBINE_BOOLS(guint8, obj->prio_has));
}
+void
+nm_platform_link_bridge_port_hash_update(const NMPlatformLinkBridgePort *obj, NMHashState *h)
+{
+ nm_hash_update_vals(h, obj->path_cost, obj->priority, obj->hairpin);
+}
+
int
nm_platform_link_cmp(const NMPlatformLink *a, const NMPlatformLink *b)
{
@@ -7926,6 +7956,9 @@ nm_platform_link_cmp(const NMPlatformLink *a, const NMPlatformLink *b)
case NM_PORT_KIND_BOND:
NM_CMP_RETURN(nm_platform_link_bond_port_cmp(&a->port_data.bond, &b->port_data.bond));
break;
+ case NM_PORT_KIND_BRIDGE:
+ NM_CMP_RETURN(nm_platform_link_bridge_port_cmp(&a->port_data.bridge, &b->port_data.bridge));
+ break;
}
NM_CMP_FIELD(a, b, rx_packets);
NM_CMP_FIELD(a, b, rx_bytes);
@@ -8023,6 +8056,18 @@ nm_platform_link_bond_port_cmp(const NMPlatformLinkBondPort *a, const NMPlatform
}
int
+nm_platform_link_bridge_port_cmp(const NMPlatformLinkBridgePort *a,
+ const NMPlatformLinkBridgePort *b)
+{
+ NM_CMP_SELF(a, b);
+ NM_CMP_FIELD(a, b, path_cost);
+ NM_CMP_FIELD(a, b, priority);
+ NM_CMP_FIELD(a, b, hairpin);
+
+ return 0;
+}
+
+int
nm_platform_lnk_bond_cmp(const NMPlatformLnkBond *a, const NMPlatformLnkBond *b)
{
NM_CMP_SELF(a, b);
diff --git a/src/libnm-platform/nm-platform.h b/src/libnm-platform/nm-platform.h
index 76f8860d14..6ad0d15bd0 100644
--- a/src/libnm-platform/nm-platform.h
+++ b/src/libnm-platform/nm-platform.h
@@ -175,8 +175,15 @@ typedef struct {
bool prio_has : 1;
} NMPlatformLinkBondPort;
+typedef struct {
+ guint32 path_cost;
+ guint16 priority;
+ bool hairpin;
+} NMPlatformLinkBridgePort;
+
typedef union {
- NMPlatformLinkBondPort bond;
+ NMPlatformLinkBondPort bond;
+ NMPlatformLinkBridgePort bridge;
} NMPlatformLinkPortData;
struct _NMPlatformLink {
@@ -1971,6 +1978,7 @@ gboolean nm_platform_link_change(NMPlatform *self,
int ifindex,
NMPlatformLinkProps *props,
NMPlatformLinkBondPort *bond_port,
+ NMPlatformLinkBridgePort *bridge_port,
NMPlatformLinkChangeFlags flags);
gboolean nm_platform_link_get_udev_property(NMPlatform *self,
@@ -2468,8 +2476,11 @@ int nm_platform_mptcp_addr_cmp(const NMPlatformMptcpAddr *a, const NMPlatformMpt
void nm_platform_link_hash_update(const NMPlatformLink *obj, NMHashState *h);
void nm_platform_link_bond_port_hash_update(const NMPlatformLinkBondPort *obj, NMHashState *h);
+void nm_platform_link_bridge_port_hash_update(const NMPlatformLinkBridgePort *obj, NMHashState *h);
int nm_platform_link_bond_port_cmp(const NMPlatformLinkBondPort *a,
const NMPlatformLinkBondPort *b);
+int nm_platform_link_bridge_port_cmp(const NMPlatformLinkBridgePort *a,
+ const NMPlatformLinkBridgePort *b);
void nm_platform_ip4_route_hash_update(const NMPlatformIP4Route *obj,
NMPlatformIPRouteCmpType cmp_type,
NMHashState *h);