diff --git a/clients/common/nm-meta-setting-desc.c b/clients/common/nm-meta-setting-desc.c index 66c1a4f1be..4c96e3aaec 100644 --- a/clients/common/nm-meta-setting-desc.c +++ b/clients/common/nm-meta-setting-desc.c @@ -4939,6 +4939,10 @@ static const NMMetaPropertyInfo *const property_infos_BRIDGE[] = { .prompt = N_("Group forward mask [0]"), .property_type = &_pt_gobject_int, ), + PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_MULTICAST_HASH_MAX, + .property_type = &_pt_gobject_int, + .hide_if_default = TRUE, + ), PROPERTY_INFO_WITH_DESC (NM_SETTING_BRIDGE_MULTICAST_QUERIER, .property_type = &_pt_gobject_bool, .hide_if_default = TRUE, diff --git a/clients/common/settings-docs.h.in b/clients/common/settings-docs.h.in index c9667b47c8..2add72993c 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_HASH_MAX N_("Set maximum size of multicast hash table (value must be a power of 2).") #define DESCRIBE_DOC_NM_SETTING_BRIDGE_MULTICAST_QUERIER N_("Enable or disable sending of multicast queries by the bridge. If not specified the option is disabled.") #define DESCRIBE_DOC_NM_SETTING_BRIDGE_MULTICAST_QUERY_USE_IFADDR N_("If enabled the bridge's own IP address is used as the source address for IGMP queries otherwise the default of 0.0.0.0 is used.") #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'.") diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h index ef9e982bf6..bcf3cb406b 100644 --- a/libnm-core/nm-core-internal.h +++ b/libnm-core/nm-core-internal.h @@ -97,6 +97,9 @@ #define NM_BR_PORT_MAX_PATH_COST 65535 #define NM_BR_PORT_DEF_PATH_COST 100 +#define NM_BR_MIN_MULTICAST_HASH_MAX 1 +#define NM_BR_MAX_MULTICAST_HASH_MAX G_MAXUINT32 + /* NM_SETTING_COMPARE_FLAG_INFERRABLE: check whether a device-generated * connection can be replaced by a already-defined connection. This flag only * takes into account properties marked with the %NM_SETTING_PARAM_INFERRABLE diff --git a/libnm-core/nm-setting-bridge.c b/libnm-core/nm-setting-bridge.c index 957520f4a6..7739dd2afd 100644 --- a/libnm-core/nm-setting-bridge.c +++ b/libnm-core/nm-setting-bridge.c @@ -26,6 +26,7 @@ #define BRIDGE_FORWARD_DELAY_DEFAULT 15 #define BRIDGE_HELLO_TIME_DEFAULT 2 #define BRIDGE_MAX_AGE_DEFAULT 20 +#define BRIDGE_MULTICAST_HASH_MAX_DEFAULT 4096 #define BRIDGE_MULTICAST_QUERIER_DEFAULT FALSE #define BRIDGE_MULTICAST_QUERY_USE_IFADDR_DEFAULT FALSE #define BRIDGE_MULTICAST_SNOOPING_DEFAULT TRUE @@ -46,6 +47,7 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMSettingBridge, PROP_AGEING_TIME, PROP_GROUP_ADDRESS, PROP_GROUP_FORWARD_MASK, + PROP_MULTICAST_HASH_MAX, PROP_MULTICAST_ROUTER, PROP_MULTICAST_QUERIER, PROP_MULTICAST_QUERY_USE_IFADDR, @@ -64,6 +66,7 @@ typedef struct { char * group_address; char * vlan_protocol; guint32 ageing_time; + guint32 multicast_hash_max; guint16 priority; guint16 forward_delay; guint16 hello_time; @@ -1010,6 +1013,22 @@ nm_setting_bridge_get_multicast_querier (const NMSettingBridge *setting) return NM_SETTING_BRIDGE_GET_PRIVATE (setting)->multicast_querier; } +/** + * nm_setting_bridge_get_multicast_hash_max: + * @setting: the #NMSettingBridge + * + * Returns: the #NMSettingBridge:multicast-hash-max property of the setting + * + * Since 1.26 + **/ +guint32 +nm_setting_bridge_get_multicast_hash_max (const NMSettingBridge *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_BRIDGE (setting), 0); + + return NM_SETTING_BRIDGE_GET_PRIVATE (setting)->multicast_hash_max; +} + /*****************************************************************************/ static gboolean @@ -1149,6 +1168,16 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) } } + if (!nm_utils_is_power_of_two (priv->multicast_hash_max)) { + g_set_error (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("'%s' option must be a power of 2"), + NM_SETTING_BRIDGE_MULTICAST_HASH_MAX); + g_prefix_error (error, "%s.%s: ", NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_BRIDGE_MULTICAST_HASH_MAX); + return FALSE; + } + /* Failures from here on are NORMALIZABLE... */ if (!_nm_utils_bridge_vlan_verify_list (priv->vlans, @@ -1235,6 +1264,9 @@ get_property (GObject *object, guint prop_id, case PROP_GROUP_FORWARD_MASK: g_value_set_uint (value, priv->group_forward_mask); break; + case PROP_MULTICAST_HASH_MAX: + g_value_set_uint (value, priv->multicast_hash_max); + break; case PROP_MULTICAST_SNOOPING: g_value_set_boolean (value, priv->multicast_snooping); break; @@ -1308,6 +1340,9 @@ set_property (GObject *object, guint prop_id, case PROP_GROUP_FORWARD_MASK: priv->group_forward_mask = (guint16) g_value_get_uint (value); break; + case PROP_MULTICAST_HASH_MAX: + priv->multicast_hash_max = g_value_get_uint (value); + break; case PROP_MULTICAST_SNOOPING: priv->multicast_snooping = g_value_get_boolean (value); break; @@ -1359,6 +1394,7 @@ nm_setting_bridge_init (NMSettingBridge *setting) priv->forward_delay = BRIDGE_FORWARD_DELAY_DEFAULT; priv->hello_time = BRIDGE_HELLO_TIME_DEFAULT; priv->max_age = BRIDGE_MAX_AGE_DEFAULT; + priv->multicast_hash_max = BRIDGE_MULTICAST_HASH_MAX_DEFAULT; priv->multicast_snooping = BRIDGE_MULTICAST_SNOOPING_DEFAULT; priv->priority = BRIDGE_PRIORITY_DEFAULT; priv->stp = BRIDGE_STP_DEFAULT; @@ -1843,6 +1879,27 @@ nm_setting_bridge_class_init (NMSettingBridgeClass *klass) NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); + /** + * NMSettingBridge:multicast-hash-max: + * + * Set maximum size of multicast hash table (value must be a power of 2). + **/ + /* ---ifcfg-rh--- + * property: multicast-hash-max + * variable: BRIDGING_OPTS: multicast_hash_max= + * default: 4096 + * example: BRIDGING_OPTS="multicast_hash_max=8192" + * ---end--- + * + * Since: 1.26 + */ + obj_properties[PROP_MULTICAST_HASH_MAX] = + g_param_spec_uint (NM_SETTING_BRIDGE_MULTICAST_HASH_MAX, "", "", + NM_BR_MIN_MULTICAST_HASH_MAX, NM_BR_MAX_MULTICAST_HASH_MAX, BRIDGE_MULTICAST_HASH_MAX_DEFAULT, + 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 6bd5100f26..696346ac74 100644 --- a/libnm-core/nm-setting-bridge.h +++ b/libnm-core/nm-setting-bridge.h @@ -31,6 +31,7 @@ G_BEGIN_DECLS #define NM_SETTING_BRIDGE_MAX_AGE "max-age" #define NM_SETTING_BRIDGE_AGEING_TIME "ageing-time" #define NM_SETTING_BRIDGE_GROUP_FORWARD_MASK "group-forward-mask" +#define NM_SETTING_BRIDGE_MULTICAST_HASH_MAX "multicast-hash-max" #define NM_SETTING_BRIDGE_MULTICAST_SNOOPING "multicast-snooping" #define NM_SETTING_BRIDGE_MULTICAST_ROUTER "multicast-router" #define NM_SETTING_BRIDGE_MULTICAST_QUERIER "multicast-querier" @@ -140,6 +141,9 @@ gboolean nm_setting_bridge_get_multicast_query_use_ifaddr (const NMSettingBridge NM_AVAILABLE_IN_1_24 gboolean nm_setting_bridge_get_multicast_querier (const NMSettingBridge *setting); +NM_AVAILABLE_IN_1_26 +guint32 nm_setting_bridge_get_multicast_hash_max (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 cb8f41fb03..f77ba9fd17 100644 --- a/libnm-core/tests/test-setting.c +++ b/libnm-core/tests/test-setting.c @@ -1998,6 +1998,13 @@ test_bridge_verify (void) test_verify_options_bridge (TRUE, "multicast-snooping", "yes", "multicast-router", "disabled"); + /* multicast-hash-max */ + test_verify_options_bridge (TRUE, + "multicast-hash-max", "1024"); + test_verify_options_bridge (TRUE, + "multicast-hash-max", "8192"); + test_verify_options_bridge (FALSE, + "multicast-hash-max", "3"); } /*****************************************************************************/ diff --git a/libnm/libnm.ver b/libnm/libnm.ver index b4af766a42..71d68b5219 100644 --- a/libnm/libnm.ver +++ b/libnm/libnm.ver @@ -1698,5 +1698,6 @@ global: libnm_1_26_0 { global: + nm_setting_bridge_get_multicast_hash_max; nm_setting_connection_get_mud_url; } libnm_1_24_0; diff --git a/src/devices/nm-device-bridge.c b/src/devices/nm-device-bridge.c index c6c54344f6..0d10cd17c2 100644 --- a/src/devices/nm-device-bridge.c +++ b/src/devices/nm-device-bridge.c @@ -274,6 +274,10 @@ static const Option master_options[] = { NULL, NULL, 0, 0xFFFF, 0, TRUE, FALSE, FALSE }, + { NM_SETTING_BRIDGE_MULTICAST_HASH_MAX, "hash_max", + NULL, NULL, + NM_BR_MIN_MULTICAST_HASH_MAX, NM_BR_MAX_MULTICAST_HASH_MAX, 4096, + FALSE, FALSE, FALSE }, { NM_SETTING_BRIDGE_MULTICAST_QUERIER, "multicast_querier", NULL, NULL, 0, 1, 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 db9d0d4c76..0ede5aac22 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c @@ -5162,6 +5162,7 @@ handle_bridge_option (NMSetting *setting, { "hello_time", NM_SETTING_BRIDGE_HELLO_TIME, BRIDGE_OPT_TYPE_OPTION, .only_with_stp = TRUE }, { "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_hash_max", NM_SETTING_BRIDGE_MULTICAST_HASH_MAX, BRIDGE_OPT_TYPE_OPTION }, { "multicast_querier", NM_SETTING_BRIDGE_MULTICAST_QUERIER, BRIDGE_OPT_TYPE_OPTION }, { "multicast_query_use_ifaddr", NM_SETTING_BRIDGE_MULTICAST_QUERY_USE_IFADDR, BRIDGE_OPT_TYPE_OPTION }, { "multicast_snooping", NM_SETTING_BRIDGE_MULTICAST_SNOOPING, 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 52d59ec33f..0e82d105d2 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c @@ -1501,6 +1501,13 @@ write_bridge_setting (NMConnection *connection, shvarFile *ifcfg, gboolean *wire g_string_append_printf (opts, "group_fwd_mask=%u", i); } + i = nm_setting_bridge_get_multicast_hash_max (s_bridge); + if (i != get_setting_default_uint (NM_SETTING (s_bridge), NM_SETTING_BRIDGE_MULTICAST_HASH_MAX)) { + if (opts->len) + g_string_append_c (opts, ' '); + g_string_append_printf (opts, "multicast_hash_max=%u", i); + } + b = nm_setting_bridge_get_multicast_querier (s_bridge); if (b != get_setting_default_boolean (NM_SETTING (s_bridge), NM_SETTING_BRIDGE_MULTICAST_QUERIER)) { if (opts->len)