libnm-core: add vlans property to bridge-port setting
This commit is contained in:
@@ -123,6 +123,7 @@
|
||||
#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.")
|
||||
#define DESCRIBE_DOC_NM_SETTING_BRIDGE_PORT_VLANS N_("Array of bridge VLAN objects. In addition to the VLANs specified here, the port will also have the default-pvid VLAN configured on the bridge 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_CDMA_MTU N_("If non-zero, only transmit packets of the specified size or smaller, breaking larger packets up into multiple frames.")
|
||||
#define DESCRIBE_DOC_NM_SETTING_CDMA_NUMBER N_("The number to dial to establish the connection to the CDMA-based mobile broadband network, if any. If not specified, the default number (#777) is used when required.")
|
||||
#define DESCRIBE_DOC_NM_SETTING_CDMA_PASSWORD N_("The password used to authenticate with the network, if required. Many providers do not require a password, or accept any password. But if a password is required, it is specified here.")
|
||||
|
@@ -1297,6 +1297,18 @@ _normalize_sriov_vf_order (NMConnection *self, GHashTable *parameters)
|
||||
return _nm_setting_sriov_sort_vfs (s_sriov);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_normalize_bridge_port_vlan_order (NMConnection *self, GHashTable *parameters)
|
||||
{
|
||||
NMSettingBridgePort *s_port;
|
||||
|
||||
s_port = nm_connection_get_setting_bridge_port (self);
|
||||
if (!s_port)
|
||||
return FALSE;
|
||||
|
||||
return _nm_setting_bridge_port_sort_vlans (s_port);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_normalize_required_settings (NMConnection *self, GHashTable *parameters)
|
||||
{
|
||||
@@ -1645,6 +1657,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_port_vlan_order (connection, parameters);
|
||||
|
||||
/* Verify anew. */
|
||||
success = _nm_connection_verify (connection, error);
|
||||
|
@@ -578,6 +578,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);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
@@ -42,22 +42,60 @@
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
NM_GOBJECT_PROPERTIES_DEFINE_BASE (
|
||||
NM_GOBJECT_PROPERTIES_DEFINE (NMSettingBridgePort,
|
||||
PROP_PRIORITY,
|
||||
PROP_PATH_COST,
|
||||
PROP_HAIRPIN_MODE,
|
||||
PROP_VLANS,
|
||||
);
|
||||
|
||||
typedef struct {
|
||||
guint16 priority;
|
||||
guint16 path_cost;
|
||||
gboolean hairpin_mode;
|
||||
GPtrArray *vlans;
|
||||
} NMSettingBridgePortPrivate;
|
||||
|
||||
G_DEFINE_TYPE (NMSettingBridgePort, nm_setting_bridge_port, NM_TYPE_SETTING)
|
||||
|
||||
#define NM_SETTING_BRIDGE_PORT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_SETTING_BRIDGE_PORT, NMSettingBridgePortPrivate))
|
||||
|
||||
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_port_sort_vlans (NMSettingBridgePort *setting)
|
||||
{
|
||||
NMSettingBridgePortPrivate *priv;
|
||||
gboolean need_sort = FALSE;
|
||||
guint i;
|
||||
|
||||
priv = NM_SETTING_BRIDGE_PORT_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;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
@@ -102,11 +140,160 @@ nm_setting_bridge_port_get_hairpin_mode (NMSettingBridgePort *setting)
|
||||
return NM_SETTING_BRIDGE_PORT_GET_PRIVATE (setting)->hairpin_mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_bridge_port_add_vlan:
|
||||
* @setting: the #NMSettingBridgePort
|
||||
* @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_port_add_vlan (NMSettingBridgePort *setting,
|
||||
NMBridgeVlan *vlan)
|
||||
{
|
||||
NMSettingBridgePortPrivate *priv;
|
||||
|
||||
g_return_if_fail (NM_IS_SETTING_BRIDGE_PORT (setting));
|
||||
g_return_if_fail (vlan);
|
||||
|
||||
priv = NM_SETTING_BRIDGE_PORT_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_port_get_num_vlans:
|
||||
* @setting: the #NMSettingBridgePort
|
||||
*
|
||||
* Returns: the number of VLANs
|
||||
*
|
||||
* Since: 1.18
|
||||
**/
|
||||
guint
|
||||
nm_setting_bridge_port_get_num_vlans (NMSettingBridgePort *setting)
|
||||
{
|
||||
NMSettingBridgePortPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTING_BRIDGE_PORT (setting), 0);
|
||||
priv = NM_SETTING_BRIDGE_PORT_GET_PRIVATE (setting);
|
||||
|
||||
return priv->vlans->len;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_bridge_port_get_vlan:
|
||||
* @setting: the #NMSettingBridgePort
|
||||
* @idx: index number of the VLAN to return
|
||||
*
|
||||
* Returns: (transfer none): the VLAN at index @idx
|
||||
*
|
||||
* Since: 1.18
|
||||
**/
|
||||
NMBridgeVlan *
|
||||
nm_setting_bridge_port_get_vlan (NMSettingBridgePort *setting, guint idx)
|
||||
{
|
||||
NMSettingBridgePortPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTING_BRIDGE_PORT (setting), NULL);
|
||||
priv = NM_SETTING_BRIDGE_PORT_GET_PRIVATE (setting);
|
||||
|
||||
g_return_val_if_fail (idx < priv->vlans->len, NULL);
|
||||
|
||||
return priv->vlans->pdata[idx];
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_setting_bridge_port_remove_vlan:
|
||||
* @setting: the #NMSettingBridgePort
|
||||
* @idx: index number of the VLAN.
|
||||
*
|
||||
* Removes the vlan at index @idx.
|
||||
*
|
||||
* Since: 1.18
|
||||
**/
|
||||
void
|
||||
nm_setting_bridge_port_remove_vlan (NMSettingBridgePort *setting, guint idx)
|
||||
{
|
||||
NMSettingBridgePortPrivate *priv;
|
||||
|
||||
g_return_if_fail (NM_IS_SETTING_BRIDGE_PORT (setting));
|
||||
priv = NM_SETTING_BRIDGE_PORT_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_port_remove_vlan_by_vid:
|
||||
* @setting: the #NMSettingBridgePort
|
||||
* @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_port_remove_vlan_by_vid (NMSettingBridgePort *setting,
|
||||
guint16 vid)
|
||||
{
|
||||
NMSettingBridgePortPrivate *priv;
|
||||
guint i;
|
||||
|
||||
g_return_val_if_fail (NM_IS_SETTING_BRIDGE_PORT (setting), FALSE);
|
||||
priv = NM_SETTING_BRIDGE_PORT_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_port_clear_vlans:
|
||||
* @setting: the #NMSettingBridgePort
|
||||
*
|
||||
* Removes all configured VLANs.
|
||||
*
|
||||
* Since: 1.18
|
||||
**/
|
||||
void
|
||||
nm_setting_bridge_port_clear_vlans (NMSettingBridgePort *setting)
|
||||
{
|
||||
NMSettingBridgePortPrivate *priv;
|
||||
|
||||
g_return_if_fail (NM_IS_SETTING_BRIDGE_PORT (setting));
|
||||
priv = NM_SETTING_BRIDGE_PORT_GET_PRIVATE (setting);
|
||||
|
||||
if (priv->vlans->len != 0) {
|
||||
g_ptr_array_set_size (priv->vlans, 0);
|
||||
_notify (setting, PROP_VLANS);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static gboolean
|
||||
verify (NMSetting *setting, NMConnection *connection, GError **error)
|
||||
{
|
||||
NMSettingBridgePortPrivate *priv;
|
||||
|
||||
priv = NM_SETTING_BRIDGE_PORT_GET_PRIVATE (setting);
|
||||
|
||||
if (connection) {
|
||||
NMSettingConnection *s_con;
|
||||
const char *slave_type;
|
||||
@@ -136,9 +323,58 @@ verify (NMSetting *setting, NMConnection *connection, GError **error)
|
||||
}
|
||||
}
|
||||
|
||||
if (!_nm_utils_bridge_vlan_verify_list (priv->vlans,
|
||||
FALSE,
|
||||
error,
|
||||
NM_SETTING_BRIDGE_PORT_SETTING_NAME,
|
||||
NM_SETTING_BRIDGE_PORT_VLANS))
|
||||
return FALSE;
|
||||
|
||||
/* Failures from here on are NORMALIZABLE... */
|
||||
|
||||
if (!_nm_utils_bridge_vlan_verify_list (priv->vlans,
|
||||
TRUE,
|
||||
error,
|
||||
NM_SETTING_BRIDGE_PORT_SETTING_NAME,
|
||||
NM_SETTING_BRIDGE_PORT_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)
|
||||
{
|
||||
NMSettingBridgePortPrivate *priv_a;
|
||||
NMSettingBridgePortPrivate *priv_b;
|
||||
guint i;
|
||||
|
||||
if (nm_streq (sett_info->property_infos[property_idx].name, NM_SETTING_BRIDGE_PORT_VLANS)) {
|
||||
if (other) {
|
||||
priv_a = NM_SETTING_BRIDGE_PORT_GET_PRIVATE (setting);
|
||||
priv_b = NM_SETTING_BRIDGE_PORT_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_port_parent_class)->compare_property (sett_info,
|
||||
property_idx,
|
||||
setting,
|
||||
other,
|
||||
flags);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
@@ -157,6 +393,11 @@ get_property (GObject *object, guint prop_id,
|
||||
case PROP_HAIRPIN_MODE:
|
||||
g_value_set_boolean (value, priv->hairpin_mode);
|
||||
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;
|
||||
@@ -179,6 +420,12 @@ set_property (GObject *object, guint prop_id,
|
||||
case PROP_HAIRPIN_MODE:
|
||||
priv->hairpin_mode = g_value_get_boolean (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;
|
||||
@@ -190,6 +437,9 @@ set_property (GObject *object, guint prop_id,
|
||||
static void
|
||||
nm_setting_bridge_port_init (NMSettingBridgePort *setting)
|
||||
{
|
||||
NMSettingBridgePortPrivate *priv = NM_SETTING_BRIDGE_PORT_GET_PRIVATE (setting);
|
||||
|
||||
priv->vlans = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_bridge_vlan_unref);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -205,17 +455,30 @@ nm_setting_bridge_port_new (void)
|
||||
return (NMSetting *) g_object_new (NM_TYPE_SETTING_BRIDGE_PORT, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
finalize (GObject *object)
|
||||
{
|
||||
NMSettingBridgePortPrivate *priv = NM_SETTING_BRIDGE_PORT_GET_PRIVATE (object);
|
||||
|
||||
g_ptr_array_unref (priv->vlans);
|
||||
|
||||
G_OBJECT_CLASS (nm_setting_bridge_port_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
nm_setting_bridge_port_class_init (NMSettingBridgePortClass *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 (NMSettingBridgePortPrivate));
|
||||
|
||||
object_class->finalize = finalize;
|
||||
object_class->get_property = get_property;
|
||||
object_class->set_property = set_property;
|
||||
|
||||
setting_class->compare_property = compare_property;
|
||||
setting_class->verify = verify;
|
||||
|
||||
/**
|
||||
@@ -280,7 +543,38 @@ nm_setting_bridge_port_class_init (NMSettingBridgePortClass *klass)
|
||||
NM_SETTING_PARAM_INFERRABLE |
|
||||
G_PARAM_STATIC_STRINGS);
|
||||
|
||||
/**
|
||||
* NMSettingBridgePort:vlans: (type GPtrArray(NMBridgeVlan))
|
||||
*
|
||||
* Array of bridge VLAN objects. In addition to the VLANs
|
||||
* specified here, the port will also have the default-pvid
|
||||
* VLAN configured on the bridge 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_PORT_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);
|
||||
|
||||
g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
|
||||
|
||||
_nm_setting_class_commit (setting_class, NM_META_SETTING_TYPE_BRIDGE_PORT);
|
||||
_nm_setting_class_commit_full (setting_class, NM_META_SETTING_TYPE_BRIDGE_PORT,
|
||||
NULL, properties_override);
|
||||
|
||||
}
|
||||
|
@@ -27,6 +27,7 @@
|
||||
#endif
|
||||
|
||||
#include "nm-setting.h"
|
||||
#include "nm-setting-bridge.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@@ -42,6 +43,7 @@ G_BEGIN_DECLS
|
||||
#define NM_SETTING_BRIDGE_PORT_PRIORITY "priority"
|
||||
#define NM_SETTING_BRIDGE_PORT_PATH_COST "path-cost"
|
||||
#define NM_SETTING_BRIDGE_PORT_HAIRPIN_MODE "hairpin-mode"
|
||||
#define NM_SETTING_BRIDGE_PORT_VLANS "vlans"
|
||||
|
||||
/**
|
||||
* NMSettingBridgePort:
|
||||
@@ -69,6 +71,20 @@ guint16 nm_setting_bridge_port_get_path_cost (NMSettingBridgePort *settin
|
||||
|
||||
gboolean nm_setting_bridge_port_get_hairpin_mode (NMSettingBridgePort *setting);
|
||||
|
||||
NM_AVAILABLE_IN_1_18
|
||||
void nm_setting_bridge_port_add_vlan (NMSettingBridgePort *setting,
|
||||
NMBridgeVlan *vlan);
|
||||
NM_AVAILABLE_IN_1_18
|
||||
guint nm_setting_bridge_port_get_num_vlans (NMSettingBridgePort *setting);
|
||||
NM_AVAILABLE_IN_1_18
|
||||
NMBridgeVlan *nm_setting_bridge_port_get_vlan (NMSettingBridgePort *setting, guint idx);
|
||||
NM_AVAILABLE_IN_1_18
|
||||
void nm_setting_bridge_port_remove_vlan (NMSettingBridgePort *setting, guint idx);
|
||||
NM_AVAILABLE_IN_1_18
|
||||
gboolean nm_setting_bridge_port_remove_vlan_by_vid (NMSettingBridgePort *setting, guint16 vid);
|
||||
NM_AVAILABLE_IN_1_18
|
||||
void nm_setting_bridge_port_clear_vlans (NMSettingBridgePort *setting);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __NM_SETTING_BRIDGE_PORT_H__ */
|
||||
|
@@ -74,6 +74,291 @@ G_DEFINE_TYPE (NMSettingBridge, nm_setting_bridge, NM_TYPE_SETTING)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
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
|
||||
@@ -716,7 +1001,7 @@ nm_setting_bridge_class_init (NMSettingBridgeClass *klass)
|
||||
*/
|
||||
obj_properties[PROP_VLAN_DEFAULT_PVID] =
|
||||
g_param_spec_uint (NM_SETTING_BRIDGE_VLAN_DEFAULT_PVID, "", "",
|
||||
0, 4094, 1,
|
||||
0, NM_BRIDGE_VLAN_VID_MAX, 1,
|
||||
G_PARAM_READWRITE |
|
||||
G_PARAM_CONSTRUCT |
|
||||
NM_SETTING_PARAM_INFERRABLE |
|
||||
|
@@ -51,6 +51,9 @@ G_BEGIN_DECLS
|
||||
#define NM_SETTING_BRIDGE_VLAN_FILTERING "vlan-filtering"
|
||||
#define NM_SETTING_BRIDGE_VLAN_DEFAULT_PVID "vlan-default-pvid"
|
||||
|
||||
#define NM_BRIDGE_VLAN_VID_MIN 1
|
||||
#define NM_BRIDGE_VLAN_VID_MAX 4094
|
||||
|
||||
/**
|
||||
* NMSettingBridge:
|
||||
*
|
||||
@@ -93,6 +96,35 @@ 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
|
||||
GType nm_bridge_vlan_get_type (void);
|
||||
NM_AVAILABLE_IN_1_18
|
||||
NMBridgeVlan * nm_bridge_vlan_new (guint16 vid);
|
||||
NM_AVAILABLE_IN_1_18
|
||||
NMBridgeVlan * nm_bridge_vlan_ref (NMBridgeVlan *vlan);
|
||||
NM_AVAILABLE_IN_1_18
|
||||
void nm_bridge_vlan_unref (NMBridgeVlan *vlan);
|
||||
NM_AVAILABLE_IN_1_18
|
||||
NMBridgeVlan * nm_bridge_vlan_new_clone (const NMBridgeVlan *vlan);
|
||||
NM_AVAILABLE_IN_1_18
|
||||
int nm_bridge_vlan_cmp (const NMBridgeVlan *a, const NMBridgeVlan *b);
|
||||
NM_AVAILABLE_IN_1_18
|
||||
void nm_bridge_vlan_seal (NMBridgeVlan *vlan);
|
||||
NM_AVAILABLE_IN_1_18
|
||||
gboolean nm_bridge_vlan_is_sealed (const NMBridgeVlan *vlan);
|
||||
NM_AVAILABLE_IN_1_18
|
||||
void nm_bridge_vlan_set_untagged (NMBridgeVlan *vlan, gboolean value);
|
||||
NM_AVAILABLE_IN_1_18
|
||||
void nm_bridge_vlan_set_pvid (NMBridgeVlan *vlan, gboolean value);
|
||||
NM_AVAILABLE_IN_1_18
|
||||
guint16 nm_bridge_vlan_get_vid (const NMBridgeVlan *vlan);
|
||||
NM_AVAILABLE_IN_1_18
|
||||
gboolean nm_bridge_vlan_is_untagged (const NMBridgeVlan *vlan);
|
||||
NM_AVAILABLE_IN_1_18
|
||||
gboolean nm_bridge_vlan_is_pvid (const NMBridgeVlan *vlan);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __NM_SETTING_BRIDGE_H__ */
|
||||
|
@@ -26,6 +26,7 @@
|
||||
#endif
|
||||
|
||||
#include "nm-setting.h"
|
||||
#include "nm-setting-bridge.h"
|
||||
#include "nm-connection.h"
|
||||
#include "nm-core-enum-types.h"
|
||||
|
||||
@@ -204,6 +205,9 @@ gboolean _nm_setting_should_compare_secret_property (NMSetting *setting,
|
||||
const char *secret_name,
|
||||
NMSettingCompareFlags flags);
|
||||
|
||||
NMBridgeVlan *_nm_bridge_vlan_dup (const NMBridgeVlan *vlan);
|
||||
NMBridgeVlan *_nm_bridge_vlan_dup_and_seal (const NMBridgeVlan *vlan);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#endif /* NM_SETTING_PRIVATE_H */
|
||||
|
@@ -103,6 +103,19 @@ void _nm_utils_format_variant_attributes_full (GString *str,
|
||||
char key_value_separator);
|
||||
gboolean _nm_sriov_vf_parse_vlans (NMSriovVF *vf, const char *str, GError **error);
|
||||
|
||||
GVariant * _nm_utils_bridge_vlans_to_dbus (NMSetting *setting, const char *property);
|
||||
gboolean _nm_utils_bridge_vlans_from_dbus (NMSetting *setting,
|
||||
GVariant *connection_dict,
|
||||
const char *property,
|
||||
GVariant *value,
|
||||
NMSettingParseFlags parse_flags,
|
||||
GError **error);
|
||||
gboolean _nm_utils_bridge_vlan_verify_list (GPtrArray *vlans,
|
||||
gboolean check_normalizable,
|
||||
GError **error,
|
||||
const char *setting,
|
||||
const char *property);
|
||||
|
||||
/* JSON to GValue conversion macros */
|
||||
|
||||
static inline void
|
||||
|
@@ -46,6 +46,7 @@
|
||||
#include "nm-crypto.h"
|
||||
#include "nm-setting-bond.h"
|
||||
#include "nm-setting-bridge.h"
|
||||
#include "nm-setting-bridge-port.h"
|
||||
#include "nm-setting-infiniband.h"
|
||||
#include "nm-setting-ip6-config.h"
|
||||
#include "nm-setting-team.h"
|
||||
@@ -6710,3 +6711,142 @@ nm_utils_base64secret_normalize (const char *base64_key,
|
||||
nm_explicit_bzero (buf, required_key_len);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
GVariant *
|
||||
_nm_utils_bridge_vlans_to_dbus (NMSetting *setting, const char *property)
|
||||
{
|
||||
gs_unref_ptrarray GPtrArray *vlans = NULL;
|
||||
GVariantBuilder builder;
|
||||
guint i;
|
||||
|
||||
g_object_get (setting, property, &vlans, NULL);
|
||||
g_variant_builder_init (&builder, G_VARIANT_TYPE ("aa{sv}"));
|
||||
|
||||
if (vlans) {
|
||||
for (i = 0; i < vlans->len; i++) {
|
||||
NMBridgeVlan *vlan = vlans->pdata[i];
|
||||
GVariantBuilder vlan_builder;
|
||||
|
||||
g_variant_builder_init (&vlan_builder, G_VARIANT_TYPE_VARDICT);
|
||||
g_variant_builder_add (&vlan_builder, "{sv}", "vid",
|
||||
g_variant_new_uint16 (nm_bridge_vlan_get_vid (vlan)));
|
||||
g_variant_builder_add (&vlan_builder, "{sv}", "pvid",
|
||||
g_variant_new_boolean (nm_bridge_vlan_is_pvid (vlan)));
|
||||
g_variant_builder_add (&vlan_builder, "{sv}", "untagged",
|
||||
g_variant_new_boolean (nm_bridge_vlan_is_untagged (vlan)));
|
||||
g_variant_builder_add (&builder, "a{sv}", &vlan_builder);
|
||||
}
|
||||
}
|
||||
|
||||
return g_variant_builder_end (&builder);
|
||||
}
|
||||
|
||||
gboolean
|
||||
_nm_utils_bridge_vlans_from_dbus (NMSetting *setting,
|
||||
GVariant *connection_dict,
|
||||
const char *property,
|
||||
GVariant *value,
|
||||
NMSettingParseFlags parse_flags,
|
||||
GError **error)
|
||||
{
|
||||
gs_unref_ptrarray GPtrArray *vlans = NULL;
|
||||
GVariantIter vlan_iter;
|
||||
GVariant *vlan_var;
|
||||
|
||||
g_return_val_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE ("aa{sv}")), FALSE);
|
||||
|
||||
vlans = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_bridge_vlan_unref);
|
||||
g_variant_iter_init (&vlan_iter, value);
|
||||
while (g_variant_iter_next (&vlan_iter, "@a{sv}", &vlan_var)) {
|
||||
gs_unref_variant GVariant *var_unref = vlan_var;
|
||||
NMBridgeVlan *vlan;
|
||||
guint16 vid;
|
||||
gboolean pvid = FALSE, untagged = FALSE;
|
||||
|
||||
if (!g_variant_lookup (vlan_var, "vid", "q", &vid))
|
||||
continue;
|
||||
if ( vid < NM_BRIDGE_VLAN_VID_MIN
|
||||
|| vid > NM_BRIDGE_VLAN_VID_MAX)
|
||||
continue;
|
||||
|
||||
g_variant_lookup (vlan_var, "pvid", "b", &pvid);
|
||||
g_variant_lookup (vlan_var, "untagged", "b", &untagged);
|
||||
|
||||
vlan = nm_bridge_vlan_new (vid);
|
||||
nm_bridge_vlan_set_untagged (vlan, untagged);
|
||||
nm_bridge_vlan_set_pvid (vlan, pvid);
|
||||
g_ptr_array_add (vlans, vlan);
|
||||
}
|
||||
|
||||
g_object_set (setting, property, vlans, NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_nm_utils_bridge_vlan_verify_list (GPtrArray *vlans,
|
||||
gboolean check_normalizable,
|
||||
GError **error,
|
||||
const char *setting,
|
||||
const char *property)
|
||||
{
|
||||
guint i;
|
||||
gs_unref_hashtable GHashTable *h = NULL;
|
||||
gboolean pvid_found = FALSE;
|
||||
|
||||
if (!vlans || !vlans->len)
|
||||
return TRUE;
|
||||
|
||||
if (check_normalizable) {
|
||||
for (i = 1; i < vlans->len; i++) {
|
||||
NMBridgeVlan *vlan_prev = vlans->pdata[i - 1];
|
||||
NMBridgeVlan *vlan = vlans->pdata[i];
|
||||
|
||||
if (nm_bridge_vlan_get_vid (vlan_prev) > nm_bridge_vlan_get_vid (vlan)) {
|
||||
g_set_error (error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
_("Bridge VLANs %d and %d are not sorted by ascending vid"),
|
||||
nm_bridge_vlan_get_vid (vlan_prev),
|
||||
nm_bridge_vlan_get_vid (vlan));
|
||||
g_prefix_error (error, "%s.%s: ", setting, property);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
h = g_hash_table_new (nm_direct_hash, NULL);
|
||||
for (i = 0; i < vlans->len; i++) {
|
||||
NMBridgeVlan *vlan = vlans->pdata[i];
|
||||
guint vid;
|
||||
|
||||
vid = nm_bridge_vlan_get_vid (vlan);
|
||||
|
||||
if (g_hash_table_contains (h, GUINT_TO_POINTER (vid))) {
|
||||
g_set_error (error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
_("duplicate bridge VLAN vid %u"), vid);
|
||||
g_prefix_error (error, "%s.%s: ", setting, property);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (nm_bridge_vlan_is_pvid (vlan)) {
|
||||
if (pvid_found) {
|
||||
g_set_error_literal (error,
|
||||
NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_INVALID_PROPERTY,
|
||||
_("only one VLAN can be the PVID"));
|
||||
g_prefix_error (error, "%s.%s: ", setting, property);
|
||||
return FALSE;
|
||||
}
|
||||
pvid_found = TRUE;
|
||||
}
|
||||
|
||||
g_hash_table_add (h, GUINT_TO_POINTER (vid));
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@@ -1521,6 +1521,25 @@ global:
|
||||
|
||||
libnm_1_18_0 {
|
||||
global:
|
||||
nm_bridge_vlan_cmp;
|
||||
nm_bridge_vlan_get_type;
|
||||
nm_bridge_vlan_get_vid;
|
||||
nm_bridge_vlan_is_pvid;
|
||||
nm_bridge_vlan_is_sealed;
|
||||
nm_bridge_vlan_is_untagged;
|
||||
nm_bridge_vlan_new;
|
||||
nm_bridge_vlan_new_clone;
|
||||
nm_bridge_vlan_ref;
|
||||
nm_bridge_vlan_seal;
|
||||
nm_bridge_vlan_set_pvid;
|
||||
nm_bridge_vlan_set_untagged;
|
||||
nm_bridge_vlan_unref;
|
||||
nm_setting_bridge_get_vlan_filtering;
|
||||
nm_setting_bridge_get_vlan_default_pvid;
|
||||
nm_setting_bridge_port_add_vlan;
|
||||
nm_setting_bridge_port_clear_vlans;
|
||||
nm_setting_bridge_port_get_num_vlans;
|
||||
nm_setting_bridge_port_get_vlan;
|
||||
nm_setting_bridge_port_remove_vlan;
|
||||
nm_setting_bridge_port_remove_vlan_by_vid;
|
||||
} libnm_1_16_0;
|
||||
|
@@ -20,6 +20,7 @@
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
#include "nm-setting-bridge.h"
|
||||
#include "nm-setting-connection.h"
|
||||
#include "nm-setting-ip-config.h"
|
||||
#include "nm-setting-ip4-config.h"
|
||||
@@ -46,6 +47,9 @@ NM_AUTO_DEFINE_FCN0 (NMTCQdisc *, _nm_auto_unref_tc_qdisc, nm_tc_qdisc_unref)
|
||||
#define nm_auto_unref_tc_tfilter nm_auto (_nm_auto_unref_tc_tfilter)
|
||||
NM_AUTO_DEFINE_FCN0 (NMTCTfilter *, _nm_auto_unref_tc_tfilter, nm_tc_tfilter_unref)
|
||||
|
||||
#define nm_auto_unref_bridge_vlan nm_auto (_nm_auto_unref_bridge_vlan)
|
||||
NM_AUTO_DEFINE_FCN0 (NMBridgeVlan *, _nm_auto_unref_bridge_vlan, nm_bridge_vlan_unref)
|
||||
|
||||
#define nm_auto_unref_team_link_watcher nm_auto (_nm_auto_unref_team_link_watcher)
|
||||
NM_AUTO_DEFINE_FCN0 (NMTeamLinkWatcher *, _nm_auto_unref_team_link_watcher, nm_team_link_watcher_unref)
|
||||
|
||||
|
Reference in New Issue
Block a user