nm-setting-bridge: add 'multicast-router' bridge option

Also add related unit test.

https://bugzilla.redhat.com/show_bug.cgi?id=1755768
This commit is contained in:
Antonio Cardace
2020-03-26 18:38:04 +01:00
parent bd30491f42
commit e01d3b4c2b
9 changed files with 155 additions and 0 deletions

View File

@@ -4905,6 +4905,14 @@ static const NMMetaPropertyInfo *const property_infos_BRIDGE[] = {
.prompt = N_("Enable IGMP snooping [no]"),
.property_type = &_pt_gobject_bool,
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_MULTICAST_ROUTER,
.property_type = &_pt_gobject_string,
.property_typ_data = DEFINE_PROPERTY_TYP_DATA (
.values_static = NM_MAKE_STRV ("auto",
"disabled",
"enabled"),
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_VLAN_FILTERING,
.property_type = &_pt_gobject_bool,
),

View File

@@ -119,6 +119,7 @@
#define DESCRIBE_DOC_NM_SETTING_BRIDGE_HELLO_TIME N_("The Spanning Tree Protocol (STP) hello time, in seconds.")
#define DESCRIBE_DOC_NM_SETTING_BRIDGE_MAC_ADDRESS N_("If specified, the MAC address of bridge. When creating a new bridge, this MAC address will be set. If this field is left unspecified, the \"ethernet.cloned-mac-address\" is referred instead to generate the initial MAC address. Note that setting \"ethernet.cloned-mac-address\" anyway overwrites the MAC address of the bridge later while activating the bridge. Hence, this property is deprecated. Deprecated: 1")
#define DESCRIBE_DOC_NM_SETTING_BRIDGE_MAX_AGE N_("The Spanning Tree Protocol (STP) maximum message age, in seconds.")
#define DESCRIBE_DOC_NM_SETTING_BRIDGE_MULTICAST_ROUTER N_("Sets bridge's multicast router. multicast-snooping must be enabled for this option to work. Supported values are: 'auto', 'disabled', 'enabled'. If not specified the default value is 'auto'.")
#define DESCRIBE_DOC_NM_SETTING_BRIDGE_MULTICAST_SNOOPING N_("Controls whether IGMP snooping is enabled for this bridge. Note that if snooping was automatically disabled due to hash collisions, the system may refuse to enable the feature until the collisions are resolved.")
#define DESCRIBE_DOC_NM_SETTING_BRIDGE_PRIORITY N_("Sets the Spanning Tree Protocol (STP) priority for this bridge. Lower values are \"better\"; the lowest priority bridge will be elected the root bridge.")
#define DESCRIBE_DOC_NM_SETTING_BRIDGE_STP N_("Controls whether Spanning Tree Protocol (STP) is enabled for this bridge.")

View File

@@ -44,6 +44,7 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMSettingBridge,
PROP_AGEING_TIME,
PROP_GROUP_ADDRESS,
PROP_GROUP_FORWARD_MASK,
PROP_MULTICAST_ROUTER,
PROP_MULTICAST_SNOOPING,
PROP_VLAN_FILTERING,
PROP_VLAN_DEFAULT_PVID,
@@ -55,6 +56,7 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMSettingBridge,
typedef struct {
GPtrArray *vlans;
char * mac_address;
char * multicast_router;
char * group_address;
char * vlan_protocol;
guint32 ageing_time;
@@ -954,6 +956,21 @@ nm_setting_bridge_get_vlan_stats_enabled (const NMSettingBridge *setting)
return NM_SETTING_BRIDGE_GET_PRIVATE (setting)->vlan_stats_enabled;
}
/**
* nm_setting_bridge_get_multicast_router:
* @setting: the #NMSettingBridge
*
* Returns: the #NMSettingBridge:multicast-router property of the setting
*
* Since 1.24
**/
const char *
nm_setting_bridge_get_multicast_router (const NMSettingBridge *setting)
{
g_return_val_if_fail (NM_IS_SETTING_BRIDGE (setting), NULL);
return NM_SETTING_BRIDGE_GET_PRIVATE (setting)->multicast_router;
}
/*****************************************************************************/
static gboolean
@@ -1066,6 +1083,33 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
return FALSE;
}
if (priv->multicast_router) {
if (!NM_IN_STRSET (priv->multicast_router,
"auto",
"enabled",
"disabled")) {
g_set_error_literal (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("is not a valid option"));
g_prefix_error (error, "%s.%s: ", NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_BRIDGE_MULTICAST_ROUTER);
return FALSE;
}
if ( NM_IN_STRSET (priv->multicast_router,
"auto",
"enabled")
&& !priv->multicast_snooping) {
g_set_error (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("'%s' option requires '%s' option to be enabled"),
NM_SETTING_BRIDGE_MULTICAST_ROUTER, NM_SETTING_BRIDGE_MULTICAST_SNOOPING);
g_prefix_error (error, "%s.%s: ", NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_BRIDGE_MULTICAST_ROUTER);
return FALSE;
}
}
/* Failures from here on are NORMALIZABLE... */
if (!_nm_utils_bridge_vlan_verify_list (priv->vlans,
@@ -1155,6 +1199,9 @@ get_property (GObject *object, guint prop_id,
case PROP_MULTICAST_SNOOPING:
g_value_set_boolean (value, priv->multicast_snooping);
break;
case PROP_MULTICAST_ROUTER:
g_value_set_string (value, priv->multicast_router);
break;
case PROP_VLAN_FILTERING:
g_value_set_boolean (value, priv->vlan_filtering);
break;
@@ -1219,6 +1266,10 @@ set_property (GObject *object, guint prop_id,
case PROP_MULTICAST_SNOOPING:
priv->multicast_snooping = g_value_get_boolean (value);
break;
case PROP_MULTICAST_ROUTER:
g_free (priv->multicast_router);
priv->multicast_router = g_value_dup_string (value);
break;
case PROP_VLAN_FILTERING:
priv->vlan_filtering = g_value_get_boolean (value);
break;
@@ -1283,6 +1334,7 @@ finalize (GObject *object)
NMSettingBridgePrivate *priv = NM_SETTING_BRIDGE_GET_PRIVATE (object);
g_free (priv->mac_address);
g_free (priv->multicast_router);
g_free (priv->group_address);
g_free (priv->vlan_protocol);
g_ptr_array_unref (priv->vlans);
@@ -1663,6 +1715,30 @@ nm_setting_bridge_class_init (NMSettingBridgeClass *klass)
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS);
/**
* NMSettingBridge:multicast-router:
*
* Sets bridge's multicast router.
* multicast-snooping must be enabled for this option to work.
*
* Supported values are: 'auto', 'disabled', 'enabled'.
* If not specified the default value is 'auto'.
**/
/* ---ifcfg-rh---
* property: multicast-router
* variable: BRIDGING_OPTS: multicast_router=
* values: auto, enabled, disabled
* default: auto
* example: BRIDGING_OPTS="multicast_router=enabled"
* ---end---
*/
obj_properties[PROP_MULTICAST_ROUTER] =
g_param_spec_string (NM_SETTING_BRIDGE_MULTICAST_ROUTER, "", "",
NULL,
G_PARAM_READWRITE |
NM_SETTING_PARAM_INFERRABLE |
G_PARAM_STATIC_STRINGS);
g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
_nm_setting_class_commit_full (setting_class, NM_META_SETTING_TYPE_BRIDGE,

View File

@@ -32,6 +32,7 @@ G_BEGIN_DECLS
#define NM_SETTING_BRIDGE_AGEING_TIME "ageing-time"
#define NM_SETTING_BRIDGE_GROUP_FORWARD_MASK "group-forward-mask"
#define NM_SETTING_BRIDGE_MULTICAST_SNOOPING "multicast-snooping"
#define NM_SETTING_BRIDGE_MULTICAST_ROUTER "multicast-router"
#define NM_SETTING_BRIDGE_VLAN_FILTERING "vlan-filtering"
#define NM_SETTING_BRIDGE_VLAN_DEFAULT_PVID "vlan-default-pvid"
#define NM_SETTING_BRIDGE_VLANS "vlans"
@@ -128,6 +129,9 @@ const char * nm_setting_bridge_get_vlan_protocol (const NMSettingBridge *setti
NM_AVAILABLE_IN_1_24
gboolean nm_setting_bridge_get_vlan_stats_enabled (const NMSettingBridge *setting);
NM_AVAILABLE_IN_1_24
const char * nm_setting_bridge_get_multicast_router (const NMSettingBridge *setting);
G_END_DECLS
#endif /* __NM_SETTING_BRIDGE_H__ */

View File

@@ -1977,6 +1977,27 @@ test_bridge_verify (void)
"vlan-protocol", "802.1Q");
test_verify_options_bridge (TRUE,
"vlan-protocol", "802.1ad");
/* multicast-router */
test_verify_options_bridge (FALSE,
"multicast-router", "nonsense");
test_verify_options_bridge (FALSE,
"multicast-snooping", "no",
"multicast-router", "auto");
test_verify_options_bridge (FALSE,
"multicast-snooping", "no",
"multicast-router", "enabled");
test_verify_options_bridge (TRUE,
"multicast-snooping", "no",
"multicast-router", "disabled");
test_verify_options_bridge (TRUE,
"multicast-snooping", "yes",
"multicast-router", "enabled");
test_verify_options_bridge (TRUE,
"multicast-snooping", "yes",
"multicast-router", "auto");
test_verify_options_bridge (TRUE,
"multicast-snooping", "yes",
"multicast-router", "disabled");
}
/*****************************************************************************/

View File

@@ -1686,6 +1686,7 @@ global:
nm_setting_802_1x_get_phase2_domain_match;
nm_setting_bond_get_option_normalized;
nm_setting_bridge_get_group_address;
nm_setting_bridge_get_multicast_router;
nm_setting_bridge_get_vlan_protocol;
nm_setting_bridge_get_vlan_stats_enabled;
nm_setting_vrf_get_table;

View File

@@ -198,6 +198,38 @@ to_sysfs_vlan_protocol (GValue *value)
return "0x8100";
}
static const char *
to_sysfs_multicast_router (GValue *value)
{
const char *str = g_value_get_string (value);
if (nm_streq0 (str, "disabled"))
return "0";
if (nm_streq0 (str, "auto"))
return "1";
if (nm_streq0 (str, "enabled"))
return "2";
return "1";
}
static void
from_sysfs_multicast_router (const char *value, GValue *out)
{
switch (_nm_utils_ascii_str_to_uint64 (value, 10, 0, G_MAXUINT, -1)) {
case 0:
g_value_set_string (out, "disabled");
break;
case 2:
g_value_set_string (out, "enabled");
break;
case 1:
default:
/* default value */
break;
}
}
/*****************************************************************************/
typedef struct {
@@ -246,6 +278,10 @@ static const Option master_options[] = {
NULL, NULL,
0, 1, 1,
FALSE, FALSE, FALSE },
{ NM_SETTING_BRIDGE_MULTICAST_ROUTER, "multicast_router",
to_sysfs_multicast_router, from_sysfs_multicast_router,
0, 0, 0,
FALSE, FALSE, FALSE },
{ NM_SETTING_BRIDGE_GROUP_ADDRESS, "group_addr",
to_sysfs_group_address, from_sysfs_group_address,
0, 0, 0,

View File

@@ -5158,6 +5158,7 @@ handle_bridge_option (NMSetting *setting,
{ "max_age", NM_SETTING_BRIDGE_MAX_AGE, BRIDGE_OPT_TYPE_OPTION, .only_with_stp = TRUE },
{ "ageing_time", NM_SETTING_BRIDGE_AGEING_TIME, BRIDGE_OPT_TYPE_OPTION },
{ "multicast_snooping", NM_SETTING_BRIDGE_MULTICAST_SNOOPING, BRIDGE_OPT_TYPE_OPTION },
{ "multicast_router", NM_SETTING_BRIDGE_MULTICAST_ROUTER, BRIDGE_OPT_TYPE_OPTION },
{ "vlan_filtering", NM_SETTING_BRIDGE_VLAN_FILTERING, BRIDGE_OPT_TYPE_OPTION },
{ "default_pvid", NM_SETTING_BRIDGE_VLAN_DEFAULT_PVID, BRIDGE_OPT_TYPE_OPTION },
{ "group_address", NM_SETTING_BRIDGE_GROUP_ADDRESS, BRIDGE_OPT_TYPE_OPTION },

View File

@@ -1508,6 +1508,13 @@ write_bridge_setting (NMConnection *connection, shvarFile *ifcfg, gboolean *wire
g_string_append_printf (opts, "multicast_snooping=%u", (guint32) b);
}
s = nm_setting_bridge_get_multicast_router (s_bridge);
if (s) {
if (opts->len)
g_string_append_c (opts, ' ');
g_string_append_printf (opts, "multicast_router=%s", s);
}
b = nm_setting_bridge_get_vlan_filtering (s_bridge);
if (b != get_setting_default_boolean (NM_SETTING (s_bridge), NM_SETTING_BRIDGE_VLAN_FILTERING)) {
if (opts->len)