summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntonio Cardace <acardace@redhat.com>2020-03-26 18:38:04 +0100
committerAntonio Cardace <acardace@redhat.com>2020-04-06 09:56:11 +0200
commite01d3b4c2b899cc7e72b92f10e5afe6106fe40b2 (patch)
tree1363fcd22b964ff8cf0905cac1594c99168d31b2
parentbd30491f429763b69ca1401ebea1f6d4678605bd (diff)
downloadNetworkManager-e01d3b4c2b899cc7e72b92f10e5afe6106fe40b2.tar.gz
nm-setting-bridge: add 'multicast-router' bridge option
Also add related unit test. https://bugzilla.redhat.com/show_bug.cgi?id=1755768
-rw-r--r--clients/common/nm-meta-setting-desc.c8
-rw-r--r--clients/common/settings-docs.h.in1
-rw-r--r--libnm-core/nm-setting-bridge.c76
-rw-r--r--libnm-core/nm-setting-bridge.h4
-rw-r--r--libnm-core/tests/test-setting.c21
-rw-r--r--libnm/libnm.ver1
-rw-r--r--src/devices/nm-device-bridge.c36
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c1
-rw-r--r--src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c7
9 files changed, 155 insertions, 0 deletions
diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c
index 796ac00217..aefbfd3cdb 100644
--- a/clients/common/nm-meta-setting-desc.c
+++ b/clients/common/nm-meta-setting-desc.c
@@ -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,
),
diff --git a/clients/common/settings-docs.h.in b/clients/common/settings-docs.h.in
index 7b35a05364..eb51af3d54 100644
--- a/clients/common/settings-docs.h.in
+++ b/clients/common/settings-docs.h.in
@@ -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.")
diff --git a/libnm-core/nm-setting-bridge.c b/libnm-core/nm-setting-bridge.c
index 02adcaccc2..9bb4303e50 100644
--- a/libnm-core/nm-setting-bridge.c
+++ b/libnm-core/nm-setting-bridge.c
@@ -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,
diff --git a/libnm-core/nm-setting-bridge.h b/libnm-core/nm-setting-bridge.h
index 5c955fbefe..a1379693d0 100644
--- a/libnm-core/nm-setting-bridge.h
+++ b/libnm-core/nm-setting-bridge.h
@@ -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__ */
diff --git a/libnm-core/tests/test-setting.c b/libnm-core/tests/test-setting.c
index 58e2bd5108..cb8f41fb03 100644
--- a/libnm-core/tests/test-setting.c
+++ b/libnm-core/tests/test-setting.c
@@ -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");
}
/*****************************************************************************/
diff --git a/libnm/libnm.ver b/libnm/libnm.ver
index 839272fefe..9231763adf 100644
--- a/libnm/libnm.ver
+++ b/libnm/libnm.ver
@@ -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;
diff --git a/src/devices/nm-device-bridge.c b/src/devices/nm-device-bridge.c
index 01ef1c4032..4a310650c7 100644
--- a/src/devices/nm-device-bridge.c
+++ b/src/devices/nm-device-bridge.c
@@ -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,
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
index 51d70c127e..35bd47b6e2 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c
@@ -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 },
diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
index fe6f2109e6..1bce74fa99 100644
--- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
+++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c
@@ -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)