summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSayed Shah <sayshah@redhat.com>2020-08-05 13:46:28 -0400
committerThomas Haller <thaller@redhat.com>2020-08-07 13:20:54 +0200
commitadf04202583ed649327e24991c885374e335f9c2 (patch)
tree748c9dd7bf001b3142d72b2c16aefb767a355d3c
parentec582d788c9f05874cedc080da038675d1196b99 (diff)
downloadNetworkManager-adf04202583ed649327e24991c885374e335f9c2.tar.gz
platform: add support for configuring bridge settings via netlink
NMDeviceBridge is currently using sysfs. The plan is to use netlink in in the future
-rw-r--r--libnm-core/nm-core-internal.h4
-rw-r--r--src/devices/nm-device-bridge.c9
-rw-r--r--src/nm-types.h1
-rw-r--r--src/platform/nm-fake-platform.c8
-rw-r--r--src/platform/nm-linux-platform.c55
-rw-r--r--src/platform/nm-platform.c57
-rw-r--r--src/platform/nm-platform.h16
-rw-r--r--src/platform/nmp-object.c11
-rw-r--r--src/platform/nmp-object.h8
-rw-r--r--src/platform/tests/test-common.c36
-rw-r--r--src/platform/tests/test-common.h5
-rw-r--r--src/platform/tests/test-link.c50
12 files changed, 256 insertions, 4 deletions
diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h
index 76eed31f05..b06ba78286 100644
--- a/libnm-core/nm-core-internal.h
+++ b/libnm-core/nm-core-internal.h
@@ -81,19 +81,23 @@
#define NM_BRIDGE_HELLO_TIME_MIN 1u
#define NM_BRIDGE_HELLO_TIME_DEF 2u
#define NM_BRIDGE_HELLO_TIME_MAX 10u
+#define NM_BRIDGE_HELLO_TIME_DEF_SYS (NM_BRIDGE_HELLO_TIME_DEF * 100u)
#define NM_BRIDGE_FORWARD_DELAY_MIN 2u
#define NM_BRIDGE_FORWARD_DELAY_DEF 15u
#define NM_BRIDGE_FORWARD_DELAY_MAX 30u
+#define NM_BRIDGE_FORWARD_DELAY_DEF_SYS (NM_BRIDGE_FORWARD_DELAY_DEF * 100u)
#define NM_BRIDGE_MAX_AGE_MIN 6u
#define NM_BRIDGE_MAX_AGE_DEF 20u
#define NM_BRIDGE_MAX_AGE_MAX 40u
+#define NM_BRIDGE_MAX_AGE_DEF_SYS (NM_BRIDGE_MAX_AGE_DEF * 100u)
/* IEEE 802.1D-1998 Table 7.4 */
#define NM_BRIDGE_AGEING_TIME_MIN 0u
#define NM_BRIDGE_AGEING_TIME_DEF 300u
#define NM_BRIDGE_AGEING_TIME_MAX 1000000u
+#define NM_BRIDGE_AGEING_TIME_DEF_SYS (NM_BRIDGE_AGEING_TIME_DEF * 100u)
#define NM_BRIDGE_PORT_PRIORITY_MIN 0u
#define NM_BRIDGE_PORT_PRIORITY_DEF 32u
diff --git a/src/devices/nm-device-bridge.c b/src/devices/nm-device-bridge.c
index 544e66140c..dd41a0590a 100644
--- a/src/devices/nm-device-bridge.c
+++ b/src/devices/nm-device-bridge.c
@@ -988,6 +988,7 @@ create_and_realize (NMDevice *device,
const char *hwaddr;
gs_free char *hwaddr_cloned = NULL;
guint8 mac_address[NM_UTILS_HWADDR_LEN_MAX];
+ NMPlatformLnkBridge props;
int r;
nm_assert (iface);
@@ -1016,10 +1017,18 @@ create_and_realize (NMDevice *device,
}
}
+ props = (NMPlatformLnkBridge) {
+ .forward_delay = nm_setting_bridge_get_forward_delay (s_bridge) * 100u,
+ .hello_time = nm_setting_bridge_get_hello_time (s_bridge) * 100u,
+ .max_age = nm_setting_bridge_get_max_age (s_bridge) * 100u,
+ .ageing_time = nm_setting_bridge_get_ageing_time (s_bridge) * 100u,
+ };
+
r = nm_platform_link_bridge_add (nm_device_get_platform (device),
iface,
hwaddr ? mac_address : NULL,
hwaddr ? ETH_ALEN : 0,
+ &props,
out_plink);
if (r < 0) {
g_set_error (error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_CREATION_FAILED,
diff --git a/src/nm-types.h b/src/nm-types.h
index b3530f5bfb..f91bc2d0e0 100644
--- a/src/nm-types.h
+++ b/src/nm-types.h
@@ -221,6 +221,7 @@ typedef enum {
NMP_OBJECT_TYPE_TFILTER,
+ NMP_OBJECT_TYPE_LNK_BRIDGE,
NMP_OBJECT_TYPE_LNK_GRE,
NMP_OBJECT_TYPE_LNK_GRETAP,
NMP_OBJECT_TYPE_LNK_INFINIBAND,
diff --git a/src/platform/nm-fake-platform.c b/src/platform/nm-fake-platform.c
index d9cf2de542..908d3bdb2a 100644
--- a/src/platform/nm-fake-platform.c
+++ b/src/platform/nm-fake-platform.c
@@ -309,6 +309,14 @@ link_add (NMPlatform *platform,
g_assert ((parent != 0) == NM_IN_SET (type, NM_LINK_TYPE_VLAN));
switch (type) {
+ case NM_LINK_TYPE_BRIDGE: {
+ const NMPlatformLnkBridge *props = extra_data;
+
+ g_assert (props);
+
+ dev_lnk = nmp_object_new (NMP_OBJECT_TYPE_LNK_BRIDGE, props);
+ break;
+ }
case NM_LINK_TYPE_VETH:
veth_peer = extra_data;
g_assert (veth_peer);
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
index ddb4794361..d1d2ef905e 100644
--- a/src/platform/nm-linux-platform.c
+++ b/src/platform/nm-linux-platform.c
@@ -1298,6 +1298,44 @@ _parse_af_inet6 (NMPlatform *platform,
/*****************************************************************************/
static NMPObject *
+_parse_lnk_bridge (const char *kind, struct nlattr *info_data)
+{
+ static const struct nla_policy policy[] = {
+ [IFLA_BR_FORWARD_DELAY] = { .type = NLA_U32 },
+ [IFLA_BR_HELLO_TIME] = { .type = NLA_U32 },
+ [IFLA_BR_MAX_AGE] = { .type = NLA_U32 },
+ [IFLA_BR_AGEING_TIME] = { .type = NLA_U32 },
+ };
+ NMPlatformLnkBridge *props;
+ struct nlattr *tb[G_N_ELEMENTS (policy)];
+ NMPObject *obj;
+
+ if ( !info_data
+ || !nm_streq0 (kind, "bridge"))
+ return NULL;
+
+ if (nla_parse_nested_arr (tb, info_data, policy) < 0)
+ return NULL;
+
+ obj = nmp_object_new (NMP_OBJECT_TYPE_LNK_BRIDGE, NULL);
+
+ props = &obj->lnk_bridge;
+
+ if (tb[IFLA_BR_FORWARD_DELAY])
+ props->forward_delay = nla_get_u32 (tb[IFLA_BR_FORWARD_DELAY]);
+ if (tb[IFLA_BR_HELLO_TIME])
+ props->hello_time = nla_get_u32 (tb[IFLA_BR_HELLO_TIME]);
+ if (tb[IFLA_BR_MAX_AGE])
+ props->max_age = nla_get_u32 (tb[IFLA_BR_MAX_AGE]);
+ if (tb[IFLA_BR_AGEING_TIME])
+ props->ageing_time = nla_get_u32 (tb[IFLA_BR_AGEING_TIME]);
+
+ return obj;
+}
+
+/***********************************************************************************/
+
+static NMPObject *
_parse_lnk_gre (const char *kind, struct nlattr *info_data)
{
static const struct nla_policy policy[] = {
@@ -2933,6 +2971,9 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr
}
switch (obj->link.type) {
+ case NM_LINK_TYPE_BRIDGE:
+ lnk_data = _parse_lnk_bridge (nl_info_kind, nl_info_data);
+ break;
case NM_LINK_TYPE_GRE:
case NM_LINK_TYPE_GRETAP:
lnk_data = _parse_lnk_gre (nl_info_kind, nl_info_data);
@@ -3954,6 +3995,20 @@ _nl_msg_new_link_set_linkinfo (struct nl_msg *msg,
NLA_PUT_STRING (msg, IFLA_INFO_KIND, kind);
switch (link_type) {
+ case NM_LINK_TYPE_BRIDGE: {
+ const NMPlatformLnkBridge *props = extra_data;
+
+ nm_assert (extra_data);
+
+ if (!(data = nla_nest_start (msg, IFLA_INFO_DATA)))
+ goto nla_put_failure;
+
+ NLA_PUT_U32 (msg, IFLA_BR_FORWARD_DELAY, props->forward_delay);
+ NLA_PUT_U32 (msg, IFLA_BR_HELLO_TIME, props->hello_time);
+ NLA_PUT_U32 (msg, IFLA_BR_MAX_AGE, props->max_age);
+ NLA_PUT_U32 (msg, IFLA_BR_AGEING_TIME, props->ageing_time);
+ break;
+ }
case NM_LINK_TYPE_VLAN: {
const NMPlatformLnkVlan *props = extra_data;
diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c
index 90dbc94b7b..f42bb9bc64 100644
--- a/src/platform/nm-platform.c
+++ b/src/platform/nm-platform.c
@@ -1224,6 +1224,10 @@ nm_platform_link_add (NMPlatform *self,
buf[0] = '\0';
switch (type) {
+ case NM_LINK_TYPE_BRIDGE:
+ nm_utils_strbuf_append_str (&buf_p, &buf_len, ", ");
+ nm_platform_lnk_bridge_to_string ((const NMPlatformLnkBridge *) extra_data, buf_p, buf_len);
+ break;
case NM_LINK_TYPE_VLAN:
nm_utils_strbuf_append_str (&buf_p, &buf_len, ", ");
nm_platform_lnk_vlan_to_string ((const NMPlatformLnkVlan *) extra_data, buf_p, buf_len);
@@ -2203,6 +2207,12 @@ _link_get_lnk (NMPlatform *self, int ifindex, NMLinkType link_type, const NMPlat
return lnk ? &lnk->object : NULL;
}
+const NMPlatformLnkBridge *
+nm_platform_link_get_lnk_bridge (NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
+{
+ return _link_get_lnk (self, ifindex, NM_LINK_TYPE_BRIDGE, out_link);
+}
+
const NMPlatformLnkGre *
nm_platform_link_get_lnk_gre (NMPlatform *self, int ifindex, const NMPlatformLink **out_link)
{
@@ -5372,6 +5382,32 @@ nm_platform_link_to_string (const NMPlatformLink *link, char *buf, gsize len)
return buf;
}
+const NMPlatformLnkBridge nm_platform_lnk_bridge_default = {
+ .forward_delay = NM_BRIDGE_FORWARD_DELAY_DEF_SYS,
+ .hello_time = NM_BRIDGE_HELLO_TIME_DEF_SYS,
+ .max_age = NM_BRIDGE_MAX_AGE_DEF_SYS,
+ .ageing_time = NM_BRIDGE_AGEING_TIME_DEF_SYS,
+};
+
+const char *
+nm_platform_lnk_bridge_to_string (const NMPlatformLnkBridge *lnk, char *buf, gsize len)
+{
+ if (!nm_utils_to_string_buffer_init_null (lnk, &buf, &len))
+ return buf;
+
+ g_snprintf (buf, len,
+ "forward_delay %u"
+ " hello_time %u"
+ " max_age %u"
+ " ageing_time %u"
+ "",
+ lnk->forward_delay,
+ lnk->hello_time,
+ lnk->max_age,
+ lnk->ageing_time);
+ return buf;
+}
+
const char *
nm_platform_lnk_gre_to_string (const NMPlatformLnkGre *lnk, char *buf, gsize len)
{
@@ -6862,6 +6898,27 @@ nm_platform_link_cmp (const NMPlatformLink *a, const NMPlatformLink *b)
}
void
+nm_platform_lnk_bridge_hash_update (const NMPlatformLnkBridge *obj, NMHashState *h)
+{
+ nm_hash_update_vals (h,
+ obj->forward_delay,
+ obj->hello_time,
+ obj->max_age,
+ obj->ageing_time);
+}
+
+int
+nm_platform_lnk_bridge_cmp (const NMPlatformLnkBridge *a, const NMPlatformLnkBridge *b)
+{
+ NM_CMP_SELF (a, b);
+ NM_CMP_FIELD (a, b, forward_delay);
+ NM_CMP_FIELD (a, b, hello_time);
+ NM_CMP_FIELD (a, b, max_age);
+ NM_CMP_FIELD (a, b, ageing_time);
+ return 0;
+}
+
+void
nm_platform_lnk_gre_hash_update (const NMPlatformLnkGre *obj, NMHashState *h)
{
nm_hash_update_vals (h,
diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h
index 84dcfbb4aa..eb4379cbc2 100644
--- a/src/platform/nm-platform.h
+++ b/src/platform/nm-platform.h
@@ -763,6 +763,15 @@ typedef struct {
} NMPlatformBridgeVlan;
typedef struct {
+ guint32 forward_delay;
+ guint32 hello_time;
+ guint32 max_age;
+ guint32 ageing_time;
+} NMPlatformLnkBridge;
+
+extern const NMPlatformLnkBridge nm_platform_lnk_bridge_default;
+
+typedef struct {
in_addr_t local;
in_addr_t remote;
int parent_ifindex;
@@ -1453,9 +1462,10 @@ nm_platform_link_bridge_add (NMPlatform *self,
const char *name,
const void *address,
size_t address_len,
+ const NMPlatformLnkBridge *props,
const NMPlatformLink **out_link)
{
- return nm_platform_link_add (self, NM_LINK_TYPE_BRIDGE, name, 0, address, address_len, NULL, out_link);
+ return nm_platform_link_add (self, NM_LINK_TYPE_BRIDGE, name, 0, address, address_len, props, out_link);
}
static inline int
@@ -1717,6 +1727,7 @@ gboolean nm_platform_sysctl_slave_set_option (NMPlatform *self, int ifindex, con
char *nm_platform_sysctl_slave_get_option (NMPlatform *self, int ifindex, const char *option);
const NMPObject *nm_platform_link_get_lnk (NMPlatform *self, int ifindex, NMLinkType link_type, const NMPlatformLink **out_link);
+const NMPlatformLnkBridge *nm_platform_link_get_lnk_bridge (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
const NMPlatformLnkGre *nm_platform_link_get_lnk_gre (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
const NMPlatformLnkGre *nm_platform_link_get_lnk_gretap (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
const NMPlatformLnkIp6Tnl *nm_platform_link_get_lnk_ip6tnl (NMPlatform *self, int ifindex, const NMPlatformLink **out_link);
@@ -1941,6 +1952,7 @@ gboolean nm_platform_tfilter_sync (NMPlatform *self,
GPtrArray *known_tfilters);
const char *nm_platform_link_to_string (const NMPlatformLink *link, char *buf, gsize len);
+const char *nm_platform_lnk_bridge_to_string (const NMPlatformLnkBridge *lnk, char *buf, gsize len);
const char *nm_platform_lnk_gre_to_string (const NMPlatformLnkGre *lnk, char *buf, gsize len);
const char *nm_platform_lnk_infiniband_to_string (const NMPlatformLnkInfiniband *lnk, char *buf, gsize len);
const char *nm_platform_lnk_ip6tnl_to_string (const NMPlatformLnkIp6Tnl *lnk, char *buf, gsize len);
@@ -1974,6 +1986,7 @@ const char *nm_platform_wireguard_peer_to_string (const struct _NMPWireGuardPeer
gsize len);
int nm_platform_link_cmp (const NMPlatformLink *a, const NMPlatformLink *b);
+int nm_platform_lnk_bridge_cmp (const NMPlatformLnkBridge *a, const NMPlatformLnkBridge *b);
int nm_platform_lnk_gre_cmp (const NMPlatformLnkGre *a, const NMPlatformLnkGre *b);
int nm_platform_lnk_infiniband_cmp (const NMPlatformLnkInfiniband *a, const NMPlatformLnkInfiniband *b);
int nm_platform_lnk_ip6tnl_cmp (const NMPlatformLnkIp6Tnl *a, const NMPlatformLnkIp6Tnl *b);
@@ -2031,6 +2044,7 @@ void nm_platform_ip6_address_hash_update (const NMPlatformIP6Address *obj, NMHas
void nm_platform_ip4_route_hash_update (const NMPlatformIP4Route *obj, NMPlatformIPRouteCmpType cmp_type, NMHashState *h);
void nm_platform_ip6_route_hash_update (const NMPlatformIP6Route *obj, NMPlatformIPRouteCmpType cmp_type, NMHashState *h);
void nm_platform_routing_rule_hash_update (const NMPlatformRoutingRule *obj, NMPlatformRoutingRuleCmpType cmp_type, NMHashState *h);
+void nm_platform_lnk_bridge_hash_update (const NMPlatformLnkBridge *obj, NMHashState *h);
void nm_platform_lnk_gre_hash_update (const NMPlatformLnkGre *obj, NMHashState *h);
void nm_platform_lnk_infiniband_hash_update (const NMPlatformLnkInfiniband *obj, NMHashState *h);
void nm_platform_lnk_ip6tnl_hash_update (const NMPlatformLnkIp6Tnl *obj, NMHashState *h);
diff --git a/src/platform/nmp-object.c b/src/platform/nmp-object.c
index 2bc7bf6f66..80b522da61 100644
--- a/src/platform/nmp-object.c
+++ b/src/platform/nmp-object.c
@@ -3210,6 +3210,17 @@ const NMPClass _nmp_classes[NMP_OBJECT_TYPE_MAX] = {
.cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_tfilter_hash_update,
.cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_tfilter_cmp,
},
+ [NMP_OBJECT_TYPE_LNK_BRIDGE - 1] = {
+ .parent = DEDUP_MULTI_OBJ_CLASS_INIT (),
+ .obj_type = NMP_OBJECT_TYPE_LNK_BRIDGE,
+ .sizeof_data = sizeof (NMPObjectLnkBridge),
+ .sizeof_public = sizeof (NMPlatformLnkBridge),
+ .obj_type_name = "bridge",
+ .lnk_link_type = NM_LINK_TYPE_BRIDGE,
+ .cmd_plobj_to_string = (const char *(*) (const NMPlatformObject *obj, char *buf, gsize len)) nm_platform_lnk_bridge_to_string,
+ .cmd_plobj_hash_update = (void (*) (const NMPlatformObject *obj, NMHashState *h)) nm_platform_lnk_bridge_hash_update,
+ .cmd_plobj_cmp = (int (*) (const NMPlatformObject *obj1, const NMPlatformObject *obj2)) nm_platform_lnk_bridge_cmp,
+ },
[NMP_OBJECT_TYPE_LNK_GRE - 1] = {
.parent = DEDUP_MULTI_OBJ_CLASS_INIT (),
.obj_type = NMP_OBJECT_TYPE_LNK_GRE,
diff --git a/src/platform/nmp-object.h b/src/platform/nmp-object.h
index bf4ff42379..6b37c16133 100644
--- a/src/platform/nmp-object.h
+++ b/src/platform/nmp-object.h
@@ -244,6 +244,10 @@ typedef struct {
} NMPObjectLink;
typedef struct {
+ NMPlatformLnkBridge _public;
+} NMPObjectLnkBridge;
+
+typedef struct {
NMPlatformLnkGre _public;
} NMPObjectLnkGre;
@@ -343,6 +347,9 @@ struct _NMPObject {
NMPlatformLink link;
NMPObjectLink _link;
+ NMPlatformLnkBridge lnk_bridge;
+ NMPObjectLnkBridge _lnk_bridge;
+
NMPlatformLnkGre lnk_gre;
NMPObjectLnkGre _lnk_gre;
@@ -487,6 +494,7 @@ _NMP_OBJECT_TYPE_IS_OBJ_WITH_IFINDEX (NMPObjectType obj_type)
case NMP_OBJECT_TYPE_TFILTER:
+ case NMP_OBJECT_TYPE_LNK_BRIDGE:
case NMP_OBJECT_TYPE_LNK_GRE:
case NMP_OBJECT_TYPE_LNK_GRETAP:
case NMP_OBJECT_TYPE_LNK_INFINIBAND:
diff --git a/src/platform/tests/test-common.c b/src/platform/tests/test-common.c
index 9f6a29bc99..13e93e7c92 100644
--- a/src/platform/tests/test-common.c
+++ b/src/platform/tests/test-common.c
@@ -1173,6 +1173,42 @@ nmtstp_ip6_address_del (NMPlatform *platform,
} G_STMT_END
const NMPlatformLink *
+nmtstp_link_bridge_add (NMPlatform *platform,
+ gboolean external_command,
+ const char *name,
+ const NMPlatformLnkBridge *lnk,
+ gboolean *out_not_supported)
+{
+ const NMPlatformLink *pllink = NULL;
+ int r = 0;
+
+ g_assert (nm_utils_ifname_valid_kernel (name, NULL));
+
+ NM_SET_OUT (out_not_supported, FALSE);
+ external_command = nmtstp_run_command_check_external (external_command);
+
+ _init_platform (&platform, external_command);
+
+ if (external_command) {
+ r = nmtstp_run_command ("ip link add %s type bridge forward_delay %u hello_time %u max_age %u ageing_time %u",
+ name,
+ lnk->forward_delay,
+ lnk->hello_time,
+ lnk->max_age,
+ lnk->ageing_time);
+ g_assert_cmpint (r, ==, 0);
+ pllink = nmtstp_assert_wait_for_link (platform, name, NM_LINK_TYPE_BRIDGE, 100);
+ }
+
+ if (!pllink) {
+ r = nm_platform_link_bridge_add (platform, name, NULL, 0, lnk, &pllink);
+ }
+
+ _assert_pllink (platform, r == 0, pllink, name, NM_LINK_TYPE_BRIDGE);
+
+ return pllink;
+}
+const NMPlatformLink *
nmtstp_link_veth_add (NMPlatform *platform,
gboolean external_command,
const char *name,
diff --git a/src/platform/tests/test-common.h b/src/platform/tests/test-common.h
index 522c3756d3..38083ae9ea 100644
--- a/src/platform/tests/test-common.h
+++ b/src/platform/tests/test-common.h
@@ -323,6 +323,11 @@ void nmtstp_link_set_updown (NMPlatform *platform,
int ifindex,
gboolean up);
+const NMPlatformLink *nmtstp_link_bridge_add (NMPlatform *platform,
+ gboolean external_command,
+ const char *name,
+ const NMPlatformLnkBridge *lnk,
+ gboolean *out_not_supported);
const NMPlatformLink *nmtstp_link_veth_add (NMPlatform *platform,
gboolean external_command,
const char *name,
diff --git a/src/platform/tests/test-link.c b/src/platform/tests/test-link.c
index d7285c836a..6ce025e878 100644
--- a/src/platform/tests/test-link.c
+++ b/src/platform/tests/test-link.c
@@ -95,7 +95,12 @@ software_add (NMLinkType link_type, const char *name)
case NM_LINK_TYPE_DUMMY:
return NMTST_NM_ERR_SUCCESS (nm_platform_link_dummy_add (NM_PLATFORM_GET, name, NULL));
case NM_LINK_TYPE_BRIDGE:
- return NMTST_NM_ERR_SUCCESS (nm_platform_link_bridge_add (NM_PLATFORM_GET, name, NULL, 0, NULL));
+ return NMTST_NM_ERR_SUCCESS (nm_platform_link_bridge_add (NM_PLATFORM_GET,
+ name,
+ NULL,
+ 0,
+ &nm_platform_lnk_bridge_default,
+ NULL));
case NM_LINK_TYPE_BOND:
{
gboolean bond0_exists = !!nm_platform_link_get_by_ifname (NM_PLATFORM_GET, "bond0");
@@ -116,7 +121,12 @@ software_add (NMLinkType link_type, const char *name)
/* Don't call link_callback for the bridge interface */
parent_added = add_signal_ifname (NM_PLATFORM_SIGNAL_LINK_CHANGED, NM_PLATFORM_SIGNAL_ADDED, link_callback, PARENT_NAME);
- if (NMTST_NM_ERR_SUCCESS (nm_platform_link_bridge_add (NM_PLATFORM_GET, PARENT_NAME, NULL, 0, NULL)))
+ if (NMTST_NM_ERR_SUCCESS (nm_platform_link_bridge_add (NM_PLATFORM_GET,
+ PARENT_NAME,
+ NULL,
+ 0,
+ &nm_platform_lnk_bridge_default,
+ NULL)))
accept_signal (parent_added);
free_signal (parent_added);
@@ -510,7 +520,12 @@ test_bridge_addr (void)
nm_utils_hwaddr_aton ("de:ad:be:ef:00:11", addr, sizeof (addr));
- g_assert (NMTST_NM_ERR_SUCCESS (nm_platform_link_bridge_add (NM_PLATFORM_GET, DEVICE_NAME, addr, sizeof (addr), &plink)));
+ g_assert (NMTST_NM_ERR_SUCCESS (nm_platform_link_bridge_add (NM_PLATFORM_GET,
+ DEVICE_NAME,
+ addr,
+ sizeof (addr),
+ &nm_platform_lnk_bridge_default,
+ &plink)));
g_assert (plink);
link = *plink;
g_assert_cmpstr (link.name, ==, DEVICE_NAME);
@@ -946,6 +961,24 @@ test_software_detect (gconstpointer user_data)
ifindex_parent = nmtstp_assert_wait_for_link (NM_PLATFORM_GET, PARENT_NAME, NM_LINK_TYPE_DUMMY, 100)->ifindex;
switch (test_data->link_type) {
+ case NM_LINK_TYPE_BRIDGE: {
+ NMPlatformLnkBridge lnk_bridge = { };
+ gboolean not_supported;
+
+ lnk_bridge.forward_delay = 1560;
+ lnk_bridge.hello_time = 150;
+ lnk_bridge.max_age = 2100;
+ lnk_bridge.ageing_time = 2200;
+
+ if (!nmtstp_link_bridge_add (NULL, ext, DEVICE_NAME, &lnk_bridge, &not_supported)) {
+ if (not_supported) {
+ g_test_skip ("Cannot create Bridge interface because of missing kernel support");
+ goto out_delete_parent;
+ }
+ g_error ("Failed adding Bridge interface");
+ }
+ break;
+ }
case NM_LINK_TYPE_GRE: {
gboolean gracefully_skip = FALSE;
@@ -1311,6 +1344,16 @@ test_software_detect (gconstpointer user_data)
g_assert (lnk);
switch (test_data->link_type) {
+ case NM_LINK_TYPE_BRIDGE: {
+ const NMPlatformLnkBridge *plnk = &lnk->lnk_bridge;
+
+ g_assert (plnk == nm_platform_link_get_lnk_bridge (NM_PLATFORM_GET, ifindex, NULL));
+ g_assert_cmpint (plnk->forward_delay, ==, 1560);
+ g_assert_cmpint (plnk->hello_time , ==, 150);
+ g_assert_cmpint (plnk->max_age , ==, 2100);
+ g_assert_cmpint (plnk->ageing_time , ==, 2200);
+ break;
+ }
case NM_LINK_TYPE_GRE: {
const NMPlatformLnkGre *plnk = &lnk->lnk_gre;
@@ -3352,6 +3395,7 @@ _nmtstp_setup_tests (void)
if (nmtstp_is_root_test ()) {
g_test_add_func ("/link/external", test_external);
+ test_software_detect_add ("/link/software/detect/bridge", NM_LINK_TYPE_BRIDGE, 0);
test_software_detect_add ("/link/software/detect/gre", NM_LINK_TYPE_GRE, 0);
test_software_detect_add ("/link/software/detect/gretap", NM_LINK_TYPE_GRETAP, 0);
test_software_detect_add ("/link/software/detect/ip6tnl/0", NM_LINK_TYPE_IP6TNL, 0);