mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-01-13 19:00:28 +01:00
libnm-core: add vlans property to bridge setting
This commit is contained in:
parent
1e5b0788bc
commit
a680bedf94
6 changed files with 321 additions and 4 deletions
|
|
@ -120,6 +120,7 @@
|
|||
#define DESCRIBE_DOC_NM_SETTING_BRIDGE_STP N_("Controls whether Spanning Tree Protocol (STP) is enabled for this bridge.")
|
||||
#define DESCRIBE_DOC_NM_SETTING_BRIDGE_VLAN_DEFAULT_PVID N_("The default PVID for the ports of the bridge, that is the VLAN id assigned to incoming untagged frames.")
|
||||
#define DESCRIBE_DOC_NM_SETTING_BRIDGE_VLAN_FILTERING N_("Control whether VLAN filtering is enabled on the bridge.")
|
||||
#define DESCRIBE_DOC_NM_SETTING_BRIDGE_VLANS N_("Array of bridge VLAN objects. In addition to the VLANs specified here, the bridge will also have the default-pvid VLAN configured by the bridge.vlan-default-pvid property. In nmcli the VLAN list can be specified with the following syntax: $vid [pvid] [untagged] [, $vid [pvid] [untagged]]...")
|
||||
#define DESCRIBE_DOC_NM_SETTING_BRIDGE_PORT_HAIRPIN_MODE N_("Enables or disables \"hairpin mode\" for the port, which allows frames to be sent back out through the port the frame was received on.")
|
||||
#define DESCRIBE_DOC_NM_SETTING_BRIDGE_PORT_PATH_COST N_("The Spanning Tree Protocol (STP) port cost for destinations via this port.")
|
||||
#define DESCRIBE_DOC_NM_SETTING_BRIDGE_PORT_PRIORITY N_("The Spanning Tree Protocol (STP) priority of this bridge port.")
|
||||
|
|
|
|||
|
|
@ -1297,6 +1297,18 @@ _normalize_sriov_vf_order (NMConnection *self, GHashTable *parameters)
|
|||
return _nm_setting_sriov_sort_vfs (s_sriov);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_normalize_bridge_vlan_order (NMConnection *self, GHashTable *parameters)
|
||||
{
|
||||
NMSettingBridge *s_bridge;
|
||||
|
||||
s_bridge = nm_connection_get_setting_bridge (self);
|
||||
if (!s_bridge)
|
||||
return FALSE;
|
||||
|
||||
return _nm_setting_bridge_sort_vlans (s_bridge);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_normalize_bridge_port_vlan_order (NMConnection *self, GHashTable *parameters)
|
||||
{
|
||||
|
|
@ -1657,6 +1669,7 @@ nm_connection_normalize (NMConnection *connection,
|
|||
was_modified |= _normalize_ovs_interface_type (connection, parameters);
|
||||
was_modified |= _normalize_ip_tunnel_wired_setting (connection, parameters);
|
||||
was_modified |= _normalize_sriov_vf_order (connection, parameters);
|
||||
was_modified |= _normalize_bridge_vlan_order (connection, parameters);
|
||||
was_modified |= _normalize_bridge_port_vlan_order (connection, parameters);
|
||||
|
||||
/* Verify anew. */
|
||||
|
|
|
|||
|
|
@ -579,6 +579,7 @@ gboolean _nm_utils_dhcp_duid_valid (const char *duid, GBytes **out_duid_bin);
|
|||
|
||||
gboolean _nm_setting_sriov_sort_vfs (NMSettingSriov *setting);
|
||||
gboolean _nm_setting_bridge_port_sort_vlans (NMSettingBridgePort *setting);
|
||||
gboolean _nm_setting_bridge_sort_vlans (NMSettingBridge *setting);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
NM_GOBJECT_PROPERTIES_DEFINE_BASE (
|
||||
NM_GOBJECT_PROPERTIES_DEFINE (NMSettingBridge,
|
||||
PROP_MAC_ADDRESS,
|
||||
PROP_STP,
|
||||
PROP_PRIORITY,
|
||||
|
|
@ -52,6 +52,7 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE (
|
|||
PROP_MULTICAST_SNOOPING,
|
||||
PROP_VLAN_FILTERING,
|
||||
PROP_VLAN_DEFAULT_PVID,
|
||||
PROP_VLANS,
|
||||
);
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -66,6 +67,7 @@ typedef struct {
|
|||
gboolean multicast_snooping;
|
||||
gboolean vlan_filtering;
|
||||
guint16 vlan_default_pvid;
|
||||
GPtrArray *vlans;
|
||||
} NMSettingBridgePrivate;
|
||||
|
||||
G_DEFINE_TYPE (NMSettingBridge, nm_setting_bridge, NM_TYPE_SETTING)
|
||||
|
|
@ -358,6 +360,43 @@ nm_bridge_vlan_new_clone (const NMBridgeVlan *vlan)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static int
|
||||
vlan_ptr_cmp (gconstpointer a, gconstpointer b)
|
||||
{
|
||||
const NMBridgeVlan *vlan_a = *(const NMBridgeVlan **) a;
|
||||
const NMBridgeVlan *vlan_b = *(const NMBridgeVlan **) b;
|
||||
|
||||
return nm_bridge_vlan_cmp (vlan_a, vlan_b);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_nm_setting_bridge_sort_vlans (NMSettingBridge *setting)
|
||||
{
|
||||
NMSettingBridgePrivate *priv;
|
||||
gboolean need_sort = FALSE;
|
||||
guint i;
|
||||
|
||||
priv = NM_SETTING_BRIDGE_GET_PRIVATE (setting);
|
||||
|
||||
for (i = 1; i < priv->vlans->len; i++) {
|
||||
NMBridgeVlan *vlan_prev = priv->vlans->pdata[i - 1];
|
||||
NMBridgeVlan *vlan = priv->vlans->pdata[i];
|
||||
|
||||
if (nm_bridge_vlan_cmp (vlan_prev, vlan) > 0) {
|
||||
need_sort = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (need_sort) {
|
||||
g_ptr_array_sort (priv->vlans, vlan_ptr_cmp);
|
||||
_notify (setting, PROP_VLANS);
|
||||
}
|
||||
|
||||
return need_sort;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* nm_setting_bridge_get_mac_address:
|
||||
|
|
@ -521,6 +560,153 @@ nm_setting_bridge_get_vlan_default_pvid (NMSettingBridge *setting)
|
|||
return NM_SETTING_BRIDGE_GET_PRIVATE (setting)->vlan_default_pvid;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_bridge_add_vlan:
|
||||
* @setting: the #NMSettingBridge
|
||||
* @vlan: the vlan to add
|
||||
*
|
||||
* Appends a new vlan and associated information to the setting. The
|
||||
* given vlan gets sealed and a reference to it is added.
|
||||
*
|
||||
* Since: 1.18
|
||||
**/
|
||||
void
|
||||
nm_setting_bridge_add_vlan (NMSettingBridge *setting,
|
||||
NMBridgeVlan *vlan)
|
||||
{
|
||||
NMSettingBridgePrivate *priv;
|
||||
|
||||
g_return_if_fail (NM_IS_SETTING_BRIDGE (setting));
|
||||
g_return_if_fail (vlan);
|
||||
|
||||
priv = NM_SETTING_BRIDGE_GET_PRIVATE (setting);
|
||||
|
||||
nm_bridge_vlan_seal (vlan);
|
||||
nm_bridge_vlan_ref (vlan);
|
||||
|
||||
g_ptr_array_add (priv->vlans, vlan);
|
||||
_notify (setting, PROP_VLANS);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_bridge_get_num_vlans:
|
||||
* @setting: the #NMSettingBridge
|
||||
*
|
||||
* Returns: the number of VLANs
|
||||
*
|
||||
* Since: 1.18
|
||||
**/
|
||||
guint
|
||||
nm_setting_bridge_get_num_vlans (NMSettingBridge *setting)
|
||||
{
|
||||
NMSettingBridgePrivate *priv;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTING_BRIDGE (setting), 0);
|
||||
priv = NM_SETTING_BRIDGE_GET_PRIVATE (setting);
|
||||
|
||||
return priv->vlans->len;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_bridge_get_vlan:
|
||||
* @setting: the #NMSettingBridge
|
||||
* @idx: index number of the VLAN to return
|
||||
*
|
||||
* Returns: (transfer none): the VLAN at index @idx
|
||||
*
|
||||
* Since: 1.18
|
||||
**/
|
||||
NMBridgeVlan *
|
||||
nm_setting_bridge_get_vlan (NMSettingBridge *setting, guint idx)
|
||||
{
|
||||
NMSettingBridgePrivate *priv;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTING_BRIDGE (setting), NULL);
|
||||
priv = NM_SETTING_BRIDGE_GET_PRIVATE (setting);
|
||||
|
||||
g_return_val_if_fail (idx < priv->vlans->len, NULL);
|
||||
|
||||
return priv->vlans->pdata[idx];
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_bridge_remove_vlan:
|
||||
* @setting: the #NMSettingBridge
|
||||
* @idx: index number of the VLAN.
|
||||
*
|
||||
* Removes the vlan at index @idx.
|
||||
*
|
||||
* Since: 1.18
|
||||
**/
|
||||
void
|
||||
nm_setting_bridge_remove_vlan (NMSettingBridge *setting, guint idx)
|
||||
{
|
||||
NMSettingBridgePrivate *priv;
|
||||
|
||||
g_return_if_fail (NM_IS_SETTING_BRIDGE (setting));
|
||||
priv = NM_SETTING_BRIDGE_GET_PRIVATE (setting);
|
||||
|
||||
g_return_if_fail (idx < priv->vlans->len);
|
||||
|
||||
g_ptr_array_remove_index (priv->vlans, idx);
|
||||
_notify (setting, PROP_VLANS);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_bridge_remove_vlan_by_vid:
|
||||
* @setting: the #NMSettingBridge
|
||||
* @vid: the vlan index of the vlan to remove
|
||||
*
|
||||
* Removes the vlan vith id @vid.
|
||||
*
|
||||
* Returns: %TRUE if the vlan was found and removed; %FALSE otherwise
|
||||
*
|
||||
* Since: 1.18
|
||||
**/
|
||||
gboolean
|
||||
nm_setting_bridge_remove_vlan_by_vid (NMSettingBridge *setting,
|
||||
guint16 vid)
|
||||
{
|
||||
NMSettingBridgePrivate *priv;
|
||||
guint i;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTING_BRIDGE (setting), FALSE);
|
||||
priv = NM_SETTING_BRIDGE_GET_PRIVATE (setting);
|
||||
|
||||
for (i = 0; i < priv->vlans->len; i++) {
|
||||
if (nm_bridge_vlan_get_vid (priv->vlans->pdata[i]) == vid) {
|
||||
g_ptr_array_remove_index (priv->vlans, i);
|
||||
_notify (setting, PROP_VLANS);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_bridge_clear_vlans:
|
||||
* @setting: the #NMSettingBridge
|
||||
*
|
||||
* Removes all configured VLANs.
|
||||
*
|
||||
* Since: 1.18
|
||||
**/
|
||||
void
|
||||
nm_setting_bridge_clear_vlans (NMSettingBridge *setting)
|
||||
{
|
||||
NMSettingBridgePrivate *priv;
|
||||
|
||||
g_return_if_fail (NM_IS_SETTING_BRIDGE (setting));
|
||||
priv = NM_SETTING_BRIDGE_GET_PRIVATE (setting);
|
||||
|
||||
if (priv->vlans->len != 0) {
|
||||
g_ptr_array_set_size (priv->vlans, 0);
|
||||
_notify (setting, PROP_VLANS);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static gboolean
|
||||
check_range (guint32 val,
|
||||
guint32 min,
|
||||
|
|
@ -599,7 +785,59 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
return _nm_connection_verify_required_interface_name (connection, error);
|
||||
if (!_nm_connection_verify_required_interface_name (connection, error))
|
||||
return FALSE;
|
||||
|
||||
if (!_nm_utils_bridge_vlan_verify_list (priv->vlans,
|
||||
FALSE,
|
||||
error,
|
||||
NM_SETTING_BRIDGE_SETTING_NAME,
|
||||
NM_SETTING_BRIDGE_VLANS))
|
||||
return FALSE;
|
||||
|
||||
/* Failures from here on are NORMALIZABLE... */
|
||||
|
||||
if (!_nm_utils_bridge_vlan_verify_list (priv->vlans,
|
||||
TRUE,
|
||||
error,
|
||||
NM_SETTING_BRIDGE_SETTING_NAME,
|
||||
NM_SETTING_BRIDGE_VLANS))
|
||||
return NM_SETTING_VERIFY_NORMALIZABLE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static NMTernary
|
||||
compare_property (const NMSettInfoSetting *sett_info,
|
||||
guint property_idx,
|
||||
NMSetting *setting,
|
||||
NMSetting *other,
|
||||
NMSettingCompareFlags flags)
|
||||
{
|
||||
NMSettingBridgePrivate *priv_a;
|
||||
NMSettingBridgePrivate *priv_b;
|
||||
guint i;
|
||||
|
||||
if (nm_streq (sett_info->property_infos[property_idx].name, NM_SETTING_BRIDGE_VLANS)) {
|
||||
if (other) {
|
||||
priv_a = NM_SETTING_BRIDGE_GET_PRIVATE (setting);
|
||||
priv_b = NM_SETTING_BRIDGE_GET_PRIVATE (other);
|
||||
|
||||
if (priv_a->vlans->len != priv_b->vlans->len)
|
||||
return FALSE;
|
||||
for (i = 0; i < priv_a->vlans->len; i++) {
|
||||
if (nm_bridge_vlan_cmp (priv_a->vlans->pdata[i], priv_b->vlans->pdata[i]))
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return NM_SETTING_CLASS (nm_setting_bridge_parent_class)->compare_property (sett_info,
|
||||
property_idx,
|
||||
setting,
|
||||
other,
|
||||
flags);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -645,6 +883,11 @@ get_property (GObject *object, guint prop_id,
|
|||
case PROP_VLAN_DEFAULT_PVID:
|
||||
g_value_set_uint (value, priv->vlan_default_pvid);
|
||||
break;
|
||||
case PROP_VLANS:
|
||||
g_value_take_boxed (value, _nm_utils_copy_array (priv->vlans,
|
||||
(NMUtilsCopyFunc) nm_bridge_vlan_ref,
|
||||
(GDestroyNotify) nm_bridge_vlan_unref));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
|
@ -693,6 +936,12 @@ set_property (GObject *object, guint prop_id,
|
|||
case PROP_VLAN_DEFAULT_PVID:
|
||||
priv->vlan_default_pvid = g_value_get_uint (value);
|
||||
break;
|
||||
case PROP_VLANS:
|
||||
g_ptr_array_unref (priv->vlans);
|
||||
priv->vlans = _nm_utils_copy_array (g_value_get_boxed (value),
|
||||
(NMUtilsCopyFunc) _nm_bridge_vlan_dup_and_seal,
|
||||
(GDestroyNotify) nm_bridge_vlan_unref);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
|
@ -704,6 +953,9 @@ set_property (GObject *object, guint prop_id,
|
|||
static void
|
||||
nm_setting_bridge_init (NMSettingBridge *setting)
|
||||
{
|
||||
NMSettingBridgePrivate *priv = NM_SETTING_BRIDGE_GET_PRIVATE (setting);
|
||||
|
||||
priv->vlans = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_bridge_vlan_unref);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -725,6 +977,7 @@ finalize (GObject *object)
|
|||
NMSettingBridgePrivate *priv = NM_SETTING_BRIDGE_GET_PRIVATE (object);
|
||||
|
||||
g_free (priv->mac_address);
|
||||
g_ptr_array_unref (priv->vlans);
|
||||
|
||||
G_OBJECT_CLASS (nm_setting_bridge_parent_class)->finalize (object);
|
||||
}
|
||||
|
|
@ -742,6 +995,7 @@ nm_setting_bridge_class_init (NMSettingBridgeClass *klass)
|
|||
object_class->set_property = set_property;
|
||||
object_class->finalize = finalize;
|
||||
|
||||
setting_class->compare_property = compare_property;
|
||||
setting_class->verify = verify;
|
||||
|
||||
/**
|
||||
|
|
@ -1007,6 +1261,34 @@ nm_setting_bridge_class_init (NMSettingBridgeClass *klass)
|
|||
NM_SETTING_PARAM_INFERRABLE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* NMSettingBridge:vlans: (type GPtrArray(NMBridgeVlan))
|
||||
*
|
||||
* Array of bridge VLAN objects. In addition to the VLANs
|
||||
* specified here, the bridge will also have the default-pvid
|
||||
* VLAN configured by the bridge.vlan-default-pvid property.
|
||||
*
|
||||
* In nmcli the VLAN list can be specified with the following
|
||||
* syntax:
|
||||
*
|
||||
* $vid [pvid] [untagged] [, $vid [pvid] [untagged]]...
|
||||
*
|
||||
* Since: 1.18
|
||||
**/
|
||||
obj_properties[PROP_VLANS] =
|
||||
g_param_spec_boxed (NM_SETTING_BRIDGE_VLANS, "", "",
|
||||
G_TYPE_PTR_ARRAY,
|
||||
G_PARAM_READWRITE |
|
||||
NM_SETTING_PARAM_INFERRABLE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
_properties_override_add_override (properties_override,
|
||||
obj_properties[PROP_VLANS],
|
||||
G_VARIANT_TYPE ("aa{sv}"),
|
||||
_nm_utils_bridge_vlans_to_dbus,
|
||||
_nm_utils_bridge_vlans_from_dbus,
|
||||
NULL);
|
||||
|
||||
/* ---dbus---
|
||||
* property: interface-name
|
||||
* format: string
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ G_BEGIN_DECLS
|
|||
#define NM_SETTING_BRIDGE_MULTICAST_SNOOPING "multicast-snooping"
|
||||
#define NM_SETTING_BRIDGE_VLAN_FILTERING "vlan-filtering"
|
||||
#define NM_SETTING_BRIDGE_VLAN_DEFAULT_PVID "vlan-default-pvid"
|
||||
#define NM_SETTING_BRIDGE_VLANS "vlans"
|
||||
|
||||
#define NM_BRIDGE_VLAN_VID_MIN 1
|
||||
#define NM_BRIDGE_VLAN_VID_MAX 4094
|
||||
|
|
@ -70,6 +71,8 @@ typedef struct {
|
|||
gpointer padding[4];
|
||||
} NMSettingBridgeClass;
|
||||
|
||||
typedef struct _NMBridgeVlan NMBridgeVlan;
|
||||
|
||||
GType nm_setting_bridge_get_type (void);
|
||||
|
||||
NMSetting * nm_setting_bridge_new (void);
|
||||
|
|
@ -95,8 +98,19 @@ NM_AVAILABLE_IN_1_18
|
|||
gboolean nm_setting_bridge_get_vlan_filtering (NMSettingBridge *setting);
|
||||
NM_AVAILABLE_IN_1_18
|
||||
guint16 nm_setting_bridge_get_vlan_default_pvid (NMSettingBridge *setting);
|
||||
|
||||
typedef struct _NMBridgeVlan NMBridgeVlan;
|
||||
NM_AVAILABLE_IN_1_18
|
||||
void nm_setting_bridge_add_vlan (NMSettingBridge *setting,
|
||||
NMBridgeVlan *vlan);
|
||||
NM_AVAILABLE_IN_1_18
|
||||
guint nm_setting_bridge_get_num_vlans (NMSettingBridge *setting);
|
||||
NM_AVAILABLE_IN_1_18
|
||||
NMBridgeVlan *nm_setting_bridge_get_vlan (NMSettingBridge *setting, guint idx);
|
||||
NM_AVAILABLE_IN_1_18
|
||||
void nm_setting_bridge_remove_vlan (NMSettingBridge *setting, guint idx);
|
||||
NM_AVAILABLE_IN_1_18
|
||||
gboolean nm_setting_bridge_remove_vlan_by_vid (NMSettingBridge *setting, guint16 vid);
|
||||
NM_AVAILABLE_IN_1_18
|
||||
void nm_setting_bridge_clear_vlans (NMSettingBridge *setting);
|
||||
|
||||
NM_AVAILABLE_IN_1_18
|
||||
GType nm_bridge_vlan_get_type (void);
|
||||
|
|
|
|||
|
|
@ -1534,6 +1534,10 @@ global:
|
|||
nm_bridge_vlan_set_pvid;
|
||||
nm_bridge_vlan_set_untagged;
|
||||
nm_bridge_vlan_unref;
|
||||
nm_setting_bridge_add_vlan;
|
||||
nm_setting_bridge_clear_vlans;
|
||||
nm_setting_bridge_get_num_vlans;
|
||||
nm_setting_bridge_get_vlan;
|
||||
nm_setting_bridge_get_vlan_filtering;
|
||||
nm_setting_bridge_get_vlan_default_pvid;
|
||||
nm_setting_bridge_port_add_vlan;
|
||||
|
|
@ -1542,4 +1546,6 @@ global:
|
|||
nm_setting_bridge_port_get_vlan;
|
||||
nm_setting_bridge_port_remove_vlan;
|
||||
nm_setting_bridge_port_remove_vlan_by_vid;
|
||||
nm_setting_bridge_remove_vlan;
|
||||
nm_setting_bridge_remove_vlan_by_vid;
|
||||
} libnm_1_16_0;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue