diff options
author | Sayed Shah <sayshah@redhat.com> | 2020-08-05 13:46:28 -0400 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2020-08-07 13:20:54 +0200 |
commit | adf04202583ed649327e24991c885374e335f9c2 (patch) | |
tree | 748c9dd7bf001b3142d72b2c16aefb767a355d3c | |
parent | ec582d788c9f05874cedc080da038675d1196b99 (diff) | |
download | NetworkManager-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.h | 4 | ||||
-rw-r--r-- | src/devices/nm-device-bridge.c | 9 | ||||
-rw-r--r-- | src/nm-types.h | 1 | ||||
-rw-r--r-- | src/platform/nm-fake-platform.c | 8 | ||||
-rw-r--r-- | src/platform/nm-linux-platform.c | 55 | ||||
-rw-r--r-- | src/platform/nm-platform.c | 57 | ||||
-rw-r--r-- | src/platform/nm-platform.h | 16 | ||||
-rw-r--r-- | src/platform/nmp-object.c | 11 | ||||
-rw-r--r-- | src/platform/nmp-object.h | 8 | ||||
-rw-r--r-- | src/platform/tests/test-common.c | 36 | ||||
-rw-r--r-- | src/platform/tests/test-common.h | 5 | ||||
-rw-r--r-- | src/platform/tests/test-link.c | 50 |
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, ¬_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); |