/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301 USA. * * Copyright 2011 - 2017 Red Hat, Inc. */ #include "nm-default.h" #include "nm-setting-bridge.h" #include #include #include "nm-connection-private.h" #include "nm-utils.h" #include "nm-utils-private.h" /** * SECTION:nm-setting-bridge * @short_description: Describes connection properties for bridges * * The #NMSettingBridge object is a #NMSetting subclass that describes properties * necessary for bridging connections. **/ /*****************************************************************************/ NM_GOBJECT_PROPERTIES_DEFINE_BASE ( PROP_MAC_ADDRESS, PROP_STP, PROP_PRIORITY, PROP_FORWARD_DELAY, PROP_HELLO_TIME, PROP_MAX_AGE, PROP_AGEING_TIME, PROP_GROUP_FORWARD_MASK, PROP_MULTICAST_SNOOPING, PROP_VLAN_FILTERING, PROP_VLAN_DEFAULT_PVID, ); typedef struct { char * mac_address; gboolean stp; guint16 priority; guint16 forward_delay; guint16 hello_time; guint16 max_age; guint32 ageing_time; guint16 group_forward_mask; gboolean multicast_snooping; gboolean vlan_filtering; guint16 vlan_default_pvid; } NMSettingBridgePrivate; G_DEFINE_TYPE (NMSettingBridge, nm_setting_bridge, NM_TYPE_SETTING) #define NM_SETTING_BRIDGE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_BRIDGE, NMSettingBridgePrivate)) /*****************************************************************************/ G_DEFINE_BOXED_TYPE (NMBridgeVlan, nm_bridge_vlan, _nm_bridge_vlan_dup, nm_bridge_vlan_unref) struct _NMBridgeVlan { guint refcount; guint16 vid; bool untagged:1; bool pvid:1; bool sealed:1; }; static gboolean NM_IS_BRIDGE_VLAN (const NMBridgeVlan *self, gboolean also_sealed) { return self && self->refcount > 0 && (also_sealed || !self->sealed); } /** * nm_bridge_vlan_new: * @vid: the VLAN id, must be between 1 and 4094. * * Creates a new #NMBridgeVlan object. * * Returns: (transfer full): the new #NMBridgeVlan object. * * Since: 1.18 **/ NMBridgeVlan * nm_bridge_vlan_new (guint16 vid) { NMBridgeVlan *vlan; g_return_val_if_fail (vid >= NM_BRIDGE_VLAN_VID_MIN, NULL); g_return_val_if_fail (vid <= NM_BRIDGE_VLAN_VID_MAX, NULL); vlan = g_slice_new0 (NMBridgeVlan); vlan->refcount = 1; vlan->vid = vid; return vlan; } /** * nm_bridge_vlan_ref: * @vlan: the #NMBridgeVlan * * Increases the reference count of the object. * * Returns: the input argument @vlan object. * * Since: 1.18 **/ NMBridgeVlan * nm_bridge_vlan_ref (NMBridgeVlan *vlan) { g_return_val_if_fail (NM_IS_BRIDGE_VLAN (vlan, TRUE), NULL); nm_assert (vlan->refcount < G_MAXUINT); vlan->refcount++; return vlan; } /** * nm_bridge_vlan_unref: * @vlan: the #NMBridgeVlan * * Decreases the reference count of the object. If the reference count * reaches zero the object will be destroyed. * * Since: 1.18 **/ void nm_bridge_vlan_unref (NMBridgeVlan *vlan) { g_return_if_fail (NM_IS_BRIDGE_VLAN (vlan, TRUE)); if (--vlan->refcount == 0) g_slice_free (NMBridgeVlan, vlan); } /** * nm_bridge_vlan_cmp: * @a: a #NMBridgeVlan * @b: another #NMBridgeVlan * * Compare two bridge VLAN objects. * * Returns: zero of the two instances are equivalent or * a non-zero integer otherwise. This defines a total ordering * over the VLANs. Whether a VLAN is sealed or not does not * affect the comparison. * * Since: 1.18 **/ int nm_bridge_vlan_cmp (const NMBridgeVlan *a, const NMBridgeVlan *b) { g_return_val_if_fail (NM_IS_BRIDGE_VLAN (a, TRUE), 0); g_return_val_if_fail (NM_IS_BRIDGE_VLAN (b, TRUE), 0); NM_CMP_SELF (a, b); NM_CMP_FIELD (a, b, vid); NM_CMP_FIELD_BOOL (a, b, untagged); NM_CMP_FIELD_BOOL (a, b, pvid); return 0; } NMBridgeVlan * _nm_bridge_vlan_dup (const NMBridgeVlan *vlan) { g_return_val_if_fail (NM_IS_BRIDGE_VLAN (vlan, TRUE), NULL); if (vlan->sealed) { nm_bridge_vlan_ref ((NMBridgeVlan *) vlan); return (NMBridgeVlan *) vlan; } return nm_bridge_vlan_new_clone (vlan); } NMBridgeVlan * _nm_bridge_vlan_dup_and_seal (const NMBridgeVlan *vlan) { NMBridgeVlan *new; g_return_val_if_fail (NM_IS_BRIDGE_VLAN (vlan, TRUE), NULL); new = _nm_bridge_vlan_dup (vlan); nm_bridge_vlan_seal (new); return new; } /** * nm_bridge_vlan_get_vid: * @vlan: the #NMBridgeVlan * * Gets the VLAN id of the object. * * Returns: the VLAN id * * Since: 1.18 **/ guint16 nm_bridge_vlan_get_vid (const NMBridgeVlan *vlan) { g_return_val_if_fail (NM_IS_BRIDGE_VLAN (vlan, TRUE), 0); return vlan->vid; } /** * nm_bridge_vlan_is_untagged: * @vlan: the #NMBridgeVlan * * Returns whether the VLAN is untagged. * * Returns: %TRUE if the VLAN is untagged, %FALSE otherwise * * Since: 1.18 **/ gboolean nm_bridge_vlan_is_untagged (const NMBridgeVlan *vlan) { g_return_val_if_fail (NM_IS_BRIDGE_VLAN (vlan, TRUE), FALSE); return vlan->untagged; } /** * nm_bridge_vlan_is_pvid: * @vlan: the #NMBridgeVlan * * Returns whether the VLAN is the PVID for the port. * * Returns: %TRUE if the VLAN is the PVID * * Since: 1.18 **/ gboolean nm_bridge_vlan_is_pvid (const NMBridgeVlan *vlan) { g_return_val_if_fail (NM_IS_BRIDGE_VLAN (vlan, TRUE), FALSE); return vlan->pvid; } /** * nm_bridge_vlan_set_untagged: * @vlan: the #NMBridgeVlan * @value: the new value * * Change the value of the untagged property of the VLAN. * * Since: 1.18 **/ void nm_bridge_vlan_set_untagged (NMBridgeVlan *vlan, gboolean value) { g_return_if_fail (NM_IS_BRIDGE_VLAN (vlan, FALSE)); vlan->untagged = value; } /** * nm_bridge_vlan_set_pvid: * @vlan: the #NMBridgeVlan * @value: the new value * * Change the value of the PVID property of the VLAN. * * Since: 1.18 **/ void nm_bridge_vlan_set_pvid (NMBridgeVlan *vlan, gboolean value) { g_return_if_fail (NM_IS_BRIDGE_VLAN (vlan, FALSE)); vlan->pvid = value; } /** * nm_bridge_vlan_is_sealed: * @vlan: the #NMBridgeVlan instance * * Returns: whether @self is sealed or not. * * Since: 1.18 */ gboolean nm_bridge_vlan_is_sealed (const NMBridgeVlan *vlan) { g_return_val_if_fail (NM_IS_BRIDGE_VLAN (vlan, TRUE), FALSE); return vlan->sealed; } /** * nm_bridge_vlan_seal: * @vlan: the #NMBridgeVlan instance * * Seal the #NMBridgeVlan instance. Afterwards, it is a bug * to call all functions that modify the instance (except ref/unref). * A sealed instance cannot be unsealed again, but you can create * an unsealed copy with nm_bridge_vlan_new_clone(). * * Since: 1.18 */ void nm_bridge_vlan_seal (NMBridgeVlan *vlan) { g_return_if_fail (NM_IS_BRIDGE_VLAN (vlan, TRUE)); vlan->sealed = TRUE; } /** * nm_bridge_vlan_new_clone: * @vlan: the #NMBridgeVlan instance to copy * * Returns: (transfer full): a clone of @vlan. This instance * is always unsealed. * * Since: 1.18 */ NMBridgeVlan * nm_bridge_vlan_new_clone (const NMBridgeVlan *vlan) { NMBridgeVlan *copy; g_return_val_if_fail (NM_IS_BRIDGE_VLAN (vlan, TRUE), NULL); copy = nm_bridge_vlan_new (vlan->vid); copy->untagged = vlan->untagged; copy->pvid = vlan->pvid; return copy; } /*****************************************************************************/ /** * nm_setting_bridge_get_mac_address: * @setting: the #NMSettingBridge * * Returns: the #NMSettingBridge:mac-address property of the setting **/ const char * nm_setting_bridge_get_mac_address (NMSettingBridge *setting) { g_return_val_if_fail (NM_IS_SETTING_BRIDGE (setting), NULL); return NM_SETTING_BRIDGE_GET_PRIVATE (setting)->mac_address; } /** * nm_setting_bridge_get_stp: * @setting: the #NMSettingBridge * * Returns: the #NMSettingBridge:stp property of the setting **/ gboolean nm_setting_bridge_get_stp (NMSettingBridge *setting) { g_return_val_if_fail (NM_IS_SETTING_BRIDGE (setting), FALSE); return NM_SETTING_BRIDGE_GET_PRIVATE (setting)->stp; } /** * nm_setting_bridge_get_priority: * @setting: the #NMSettingBridge * * Returns: the #NMSettingBridge:priority property of the setting **/ guint16 nm_setting_bridge_get_priority (NMSettingBridge *setting) { g_return_val_if_fail (NM_IS_SETTING_BRIDGE (setting), 0); return NM_SETTING_BRIDGE_GET_PRIVATE (setting)->priority; } /** * nm_setting_bridge_get_forward_delay: * @setting: the #NMSettingBridge * * Returns: the #NMSettingBridge:forward-delay property of the setting **/ guint16 nm_setting_bridge_get_forward_delay (NMSettingBridge *setting) { g_return_val_if_fail (NM_IS_SETTING_BRIDGE (setting), 0); return NM_SETTING_BRIDGE_GET_PRIVATE (setting)->forward_delay; } /** * nm_setting_bridge_get_hello_time: * @setting: the #NMSettingBridge * * Returns: the #NMSettingBridge:hello-time property of the setting **/ guint16 nm_setting_bridge_get_hello_time (NMSettingBridge *setting) { g_return_val_if_fail (NM_IS_SETTING_BRIDGE (setting), 0); return NM_SETTING_BRIDGE_GET_PRIVATE (setting)->hello_time; } /** * nm_setting_bridge_get_max_age: * @setting: the #NMSettingBridge * * Returns: the #NMSettingBridge:max-age property of the setting **/ guint16 nm_setting_bridge_get_max_age (NMSettingBridge *setting) { g_return_val_if_fail (NM_IS_SETTING_BRIDGE (setting), 0); return NM_SETTING_BRIDGE_GET_PRIVATE (setting)->max_age; } /** * nm_setting_bridge_get_ageing_time: * @setting: the #NMSettingBridge * * Returns: the #NMSettingBridge:ageing-time property of the setting **/ guint nm_setting_bridge_get_ageing_time (NMSettingBridge *setting) { g_return_val_if_fail (NM_IS_SETTING_BRIDGE (setting), 0); return NM_SETTING_BRIDGE_GET_PRIVATE (setting)->ageing_time; } /** * nm_setting_bridge_get_group_forward_mask: * @setting: the #NMSettingBridge * * Returns: the #NMSettingBridge:group-forward-mask property of the setting * * Since: 1.10 **/ guint16 nm_setting_bridge_get_group_forward_mask (NMSettingBridge *setting) { g_return_val_if_fail (NM_IS_SETTING_BRIDGE (setting), 0); return NM_SETTING_BRIDGE_GET_PRIVATE (setting)->group_forward_mask; } /** * nm_setting_bridge_get_multicast_snooping: * @setting: the #NMSettingBridge * * Returns: the #NMSettingBridge:multicast-snooping property of the setting * * Since: 1.2 **/ gboolean nm_setting_bridge_get_multicast_snooping (NMSettingBridge *setting) { g_return_val_if_fail (NM_IS_SETTING_BRIDGE (setting), FALSE); return NM_SETTING_BRIDGE_GET_PRIVATE (setting)->multicast_snooping; } /** * nm_setting_bridge_get_vlan_filtering: * @setting: the #NMSettingBridge * * Returns: the #NMSettingBridge:vlan-filtering property of the setting * * Since: 1.18 **/ gboolean nm_setting_bridge_get_vlan_filtering (NMSettingBridge *setting) { g_return_val_if_fail (NM_IS_SETTING_BRIDGE (setting), FALSE); return NM_SETTING_BRIDGE_GET_PRIVATE (setting)->vlan_filtering; } /** * nm_setting_bridge_get_vlan_default_pvid: * @setting: the #NMSettingBridge * * Returns: the #NMSettingBridge:vlan-default-pvid property of the setting * * Since: 1.18 **/ guint16 nm_setting_bridge_get_vlan_default_pvid (NMSettingBridge *setting) { g_return_val_if_fail (NM_IS_SETTING_BRIDGE (setting), 1); return NM_SETTING_BRIDGE_GET_PRIVATE (setting)->vlan_default_pvid; } static gboolean check_range (guint32 val, guint32 min, guint32 max, gboolean zero, const char *prop, GError **error) { if (zero && val == 0) return TRUE; if (val < min || val > max) { g_set_error (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("value '%d' is out of range <%d-%d>"), val, min, max); g_prefix_error (error, "%s.%s: ", NM_SETTING_BRIDGE_SETTING_NAME, prop); return FALSE; } return TRUE; } static gboolean verify (NMSetting *setting, NMConnection *connection, GError **error) { NMSettingBridgePrivate *priv = NM_SETTING_BRIDGE_GET_PRIVATE (setting); if (priv->mac_address && !nm_utils_hwaddr_valid (priv->mac_address, ETH_ALEN)) { g_set_error_literal (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("is not a valid MAC address")); g_prefix_error (error, "%s.%s: ", NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_BRIDGE_MAC_ADDRESS); return FALSE; } if (!check_range (priv->forward_delay, NM_BR_MIN_FORWARD_DELAY, NM_BR_MAX_FORWARD_DELAY, !priv->stp, NM_SETTING_BRIDGE_FORWARD_DELAY, error)) return FALSE; if (!check_range (priv->hello_time, NM_BR_MIN_HELLO_TIME, NM_BR_MAX_HELLO_TIME, !priv->stp, NM_SETTING_BRIDGE_HELLO_TIME, error)) return FALSE; if (!check_range (priv->max_age, NM_BR_MIN_MAX_AGE, NM_BR_MAX_MAX_AGE, !priv->stp, NM_SETTING_BRIDGE_MAX_AGE, error)) return FALSE; if (!check_range (priv->ageing_time, NM_BR_MIN_AGEING_TIME, NM_BR_MAX_AGEING_TIME, !priv->stp, NM_SETTING_BRIDGE_AGEING_TIME, error)) return FALSE; if (priv->group_forward_mask & 7) { g_set_error_literal (error, NM_CONNECTION_ERROR, NM_CONNECTION_ERROR_INVALID_PROPERTY, _("the mask can't contain bits 0 (STP), 1 (MAC) or 2 (LACP)")); g_prefix_error (error, "%s.%s: ", NM_SETTING_BRIDGE_SETTING_NAME, NM_SETTING_BRIDGE_GROUP_FORWARD_MASK); return FALSE; } return _nm_connection_verify_required_interface_name (connection, error); } /*****************************************************************************/ static void get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) { NMSettingBridgePrivate *priv = NM_SETTING_BRIDGE_GET_PRIVATE (object); NMSettingBridge *setting = NM_SETTING_BRIDGE (object); switch (prop_id) { case PROP_MAC_ADDRESS: g_value_set_string (value, nm_setting_bridge_get_mac_address (setting)); break; case PROP_STP: g_value_set_boolean (value, priv->stp); break; case PROP_PRIORITY: g_value_set_uint (value, priv->priority); break; case PROP_FORWARD_DELAY: g_value_set_uint (value, priv->forward_delay); break; case PROP_HELLO_TIME: g_value_set_uint (value, priv->hello_time); break; case PROP_MAX_AGE: g_value_set_uint (value, priv->max_age); break; case PROP_AGEING_TIME: g_value_set_uint (value, priv->ageing_time); break; case PROP_GROUP_FORWARD_MASK: g_value_set_uint (value, priv->group_forward_mask); break; case PROP_MULTICAST_SNOOPING: g_value_set_boolean (value, priv->multicast_snooping); break; case PROP_VLAN_FILTERING: g_value_set_boolean (value, priv->vlan_filtering); break; case PROP_VLAN_DEFAULT_PVID: g_value_set_uint (value, priv->vlan_default_pvid); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } static void set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) { NMSettingBridgePrivate *priv = NM_SETTING_BRIDGE_GET_PRIVATE (object); switch (prop_id) { case PROP_MAC_ADDRESS: g_free (priv->mac_address); priv->mac_address = _nm_utils_hwaddr_canonical_or_invalid (g_value_get_string (value), ETH_ALEN); break; case PROP_STP: priv->stp = g_value_get_boolean (value); break; case PROP_PRIORITY: priv->priority = (guint16) g_value_get_uint (value); break; case PROP_FORWARD_DELAY: priv->forward_delay = (guint16) g_value_get_uint (value); break; case PROP_HELLO_TIME: priv->hello_time = (guint16) g_value_get_uint (value); break; case PROP_MAX_AGE: priv->max_age = (guint16) g_value_get_uint (value); break; case PROP_AGEING_TIME: priv->ageing_time = g_value_get_uint (value); break; case PROP_GROUP_FORWARD_MASK: priv->group_forward_mask = (guint16) g_value_get_uint (value); break; case PROP_MULTICAST_SNOOPING: priv->multicast_snooping = g_value_get_boolean (value); break; case PROP_VLAN_FILTERING: priv->vlan_filtering = g_value_get_boolean (value); break; case PROP_VLAN_DEFAULT_PVID: priv->vlan_default_pvid = g_value_get_uint (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } } /*****************************************************************************/ static void nm_setting_bridge_init (NMSettingBridge *setting) { } /** * nm_setting_bridge_new: * * Creates a new #NMSettingBridge object with default values. * * Returns: (transfer full): the new empty #NMSettingBridge object **/ NMSetting * nm_setting_bridge_new (void) { return (NMSetting *) g_object_new (NM_TYPE_SETTING_BRIDGE, NULL); } static void finalize (GObject *object) { NMSettingBridgePrivate *priv = NM_SETTING_BRIDGE_GET_PRIVATE (object); g_free (priv->mac_address); G_OBJECT_CLASS (nm_setting_bridge_parent_class)->finalize (object); } static void nm_setting_bridge_class_init (NMSettingBridgeClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); NMSettingClass *setting_class = NM_SETTING_CLASS (klass); GArray *properties_override = _nm_sett_info_property_override_create_array (); g_type_class_add_private (klass, sizeof (NMSettingBridgePrivate)); object_class->get_property = get_property; object_class->set_property = set_property; object_class->finalize = finalize; setting_class->verify = verify; /** * NMSettingBridge:mac-address: * * 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.12: Use the ethernet.cloned-mac-address property instead. **/ /* ---keyfile--- * property: mac-address * format: usual hex-digits-and-colons notation * description: MAC address in traditional hex-digits-and-colons notation, * or semicolon separated list of 6 decimal bytes (obsolete) * example: mac-address=00:22:68:12:79:A2 * mac-address=0;34;104;18;121;162; * ---end--- * ---ifcfg-rh--- * property: mac-address * variable: BRIDGE_MACADDR(+) * description: MAC address of the bridge. Note that this requires a recent * kernel support, originally introduced in 3.15 upstream kernel) * BRIDGE_MACADDR for bridges is an NM extension. * ---end--- */ obj_properties[PROP_MAC_ADDRESS] = g_param_spec_string (NM_SETTING_BRIDGE_MAC_ADDRESS, "", "", NULL, G_PARAM_READWRITE | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); _properties_override_add_transform (properties_override, obj_properties[PROP_MAC_ADDRESS], G_VARIANT_TYPE_BYTESTRING, _nm_utils_hwaddr_to_dbus, _nm_utils_hwaddr_from_dbus); /** * NMSettingBridge:stp: * * Controls whether Spanning Tree Protocol (STP) is enabled for this bridge. **/ /* ---ifcfg-rh--- * property: stp * variable: STP * default: no * description: Span tree protocol participation. * ---end--- */ obj_properties[PROP_STP] = g_param_spec_boolean (NM_SETTING_BRIDGE_STP, "", "", TRUE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); /** * NMSettingBridge:priority: * * Sets the Spanning Tree Protocol (STP) priority for this bridge. Lower * values are "better"; the lowest priority bridge will be elected the root * bridge. **/ /* ---ifcfg-rh--- * property: priority * variable: BRIDGING_OPTS: priority= * values: 0 - 32768 * default: 32768 * description: STP priority. * ---end--- */ obj_properties[PROP_PRIORITY] = g_param_spec_uint (NM_SETTING_BRIDGE_PRIORITY, "", "", 0, G_MAXUINT16, 0x8000, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); /** * NMSettingBridge:forward-delay: * * The Spanning Tree Protocol (STP) forwarding delay, in seconds. **/ /* ---ifcfg-rh--- * property: forward-delay * variable: DELAY * values: 2 - 30 * default: 15 * description: STP forwarding delay. * ---end--- */ obj_properties[PROP_FORWARD_DELAY] = g_param_spec_uint (NM_SETTING_BRIDGE_FORWARD_DELAY, "", "", 0, NM_BR_MAX_FORWARD_DELAY, 15, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); /** * NMSettingBridge:hello-time: * * The Spanning Tree Protocol (STP) hello time, in seconds. **/ /* ---ifcfg-rh--- * property: hello-time * variable: BRIDGING_OPTS: hello_time= * values: 1 - 10 * default: 2 * description: STP hello time. * ---end--- */ obj_properties[PROP_HELLO_TIME] = g_param_spec_uint (NM_SETTING_BRIDGE_HELLO_TIME, "", "", 0, NM_BR_MAX_HELLO_TIME, 2, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); /** * NMSettingBridge:max-age: * * The Spanning Tree Protocol (STP) maximum message age, in seconds. **/ /* ---ifcfg-rh--- * property: max-age * variable: BRIDGING_OPTS: max_age= * values: 6 - 40 * default: 20 * description: STP maximum message age. * ---end--- */ obj_properties[PROP_MAX_AGE] = g_param_spec_uint (NM_SETTING_BRIDGE_MAX_AGE, "", "", 0, NM_BR_MAX_MAX_AGE, 20, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); /** * NMSettingBridge:ageing-time: * * The Ethernet MAC address aging time, in seconds. **/ /* ---ifcfg-rh--- * property: ageing-time * variable: BRIDGING_OPTS: ageing_time= * values: 0 - 1000000 * default: 300 * description: Ethernet MAC ageing time. * ---end--- */ obj_properties[PROP_AGEING_TIME] = g_param_spec_uint (NM_SETTING_BRIDGE_AGEING_TIME, "", "", NM_BR_MIN_AGEING_TIME, NM_BR_MAX_AGEING_TIME, 300, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); /** * NMSettingBridge:group-forward-mask: * * A mask of group addresses to forward. Usually, group addresses in * the range from 01:80:C2:00:00:00 to 01:80:C2:00:00:0F are not * forwarded according to standards. This property is a mask of 16 bits, * each corresponding to a group address in that range that must be * forwarded. The mask can't have bits 0, 1 or 2 set because they are * used for STP, MAC pause frames and LACP. * * Since: 1.10 **/ obj_properties[PROP_GROUP_FORWARD_MASK] = g_param_spec_uint (NM_SETTING_BRIDGE_GROUP_FORWARD_MASK, "", "", 0, 0xFFFF, 0, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); /** * NMSettingBridge:multicast-snooping: * * 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. * * Since: 1.2 **/ /* ---ifcfg-rh--- * property: multicast-snooping * variable: BRIDGING_OPTS: multicast_snooping= * values: 0 or 1 * default: 1 * description: IGMP snooping support. * ---end--- */ obj_properties[PROP_MULTICAST_SNOOPING] = g_param_spec_boolean (NM_SETTING_BRIDGE_MULTICAST_SNOOPING, "", "", TRUE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); /** * NMSettingBridge:vlan-filtering: * * Control whether VLAN filtering is enabled on the bridge. * * Since: 1.18 **/ /* ---ifcfg-rh--- * property: vlan-filtering * variable: BRIDGING_OPTS: vlan_filtering= * values: 0 or 1 * default: 0 * description: VLAN filtering support. * ---end--- */ obj_properties[PROP_VLAN_FILTERING] = g_param_spec_boolean (NM_SETTING_BRIDGE_VLAN_FILTERING, "", "", FALSE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); /** * NMSettingBridge:vlan-default-pvid: * * The default PVID for the ports of the bridge, that is the VLAN id * assigned to incoming untagged frames. * * Since: 1.18 **/ /* ---ifcfg-rh--- * property: vlan-default-pvid * variable: BRIDGING_OPTS: default_pvid= * values: 0 - 4094 * default: 1 * description: default VLAN PVID. * ---end--- */ obj_properties[PROP_VLAN_DEFAULT_PVID] = g_param_spec_uint (NM_SETTING_BRIDGE_VLAN_DEFAULT_PVID, "", "", 0, NM_BRIDGE_VLAN_VID_MAX, 1, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_INFERRABLE | G_PARAM_STATIC_STRINGS); /* ---dbus--- * property: interface-name * format: string * description: Deprecated in favor of connection.interface-name, but can * be used for backward-compatibility with older daemons, to set the * bridge's interface name. * ---end--- */ _properties_override_add_dbus_only (properties_override, "interface-name", G_VARIANT_TYPE_STRING, _nm_setting_get_deprecated_virtual_interface_name, NULL); g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties); _nm_setting_class_commit_full (setting_class, NM_META_SETTING_TYPE_BRIDGE, NULL, properties_override); }