mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-09-20 00:21:29 +00:00
libnm: add LLDP support
Add functions to libnm for retrieving a list of LLDP neighbors and accessor functions to get their attributes.
This commit is contained in:
parent
07a9364d9c
commit
d3d2b49400
|
@ -859,11 +859,19 @@ libnm_1_2_0 {
|
|||
global:
|
||||
nm_access_point_get_last_seen;
|
||||
nm_device_ethernet_get_s390_subchannels;
|
||||
nm_device_get_lldp_neighbors;
|
||||
nm_device_get_metered;
|
||||
nm_device_get_nm_plugin_missing;
|
||||
nm_device_set_managed;
|
||||
nm_device_wifi_request_scan_options;
|
||||
nm_device_wifi_request_scan_options_async;
|
||||
nm_lldp_neighbor_get_attr_names;
|
||||
nm_lldp_neighbor_get_attr_string_value;
|
||||
nm_lldp_neighbor_get_attr_type;
|
||||
nm_lldp_neighbor_get_attr_uint_value;
|
||||
nm_lldp_neighbor_new;
|
||||
nm_lldp_neighbor_ref;
|
||||
nm_lldp_neighbor_unref;
|
||||
nm_metered_get_type;
|
||||
nm_setting_802_1x_check_cert_scheme;
|
||||
nm_setting_bridge_get_multicast_snooping;
|
||||
|
|
|
@ -105,6 +105,7 @@ typedef struct {
|
|||
|
||||
char *physical_port_id;
|
||||
guint32 mtu;
|
||||
GPtrArray *lldp_neighbors;
|
||||
} NMDevicePrivate;
|
||||
|
||||
enum {
|
||||
|
@ -134,6 +135,7 @@ enum {
|
|||
PROP_PHYSICAL_PORT_ID,
|
||||
PROP_MTU,
|
||||
PROP_METERED,
|
||||
PROP_LLDP_NEIGHBORS,
|
||||
|
||||
LAST_PROP
|
||||
};
|
||||
|
@ -146,6 +148,11 @@ enum {
|
|||
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
struct _NMLldpNeighbor {
|
||||
guint refcount;
|
||||
GHashTable *attrs;
|
||||
};
|
||||
|
||||
static void
|
||||
nm_device_init (NMDevice *device)
|
||||
{
|
||||
|
@ -153,6 +160,7 @@ nm_device_init (NMDevice *device)
|
|||
|
||||
priv->state = NM_DEVICE_STATE_UNKNOWN;
|
||||
priv->reason = NM_DEVICE_STATE_REASON_NONE;
|
||||
priv->lldp_neighbors = g_ptr_array_new ();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -165,6 +173,38 @@ demarshal_state_reason (NMObject *object, GParamSpec *pspec, GVariant *value, gp
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
demarshal_lldp_neighbors (NMObject *object, GParamSpec *pspec, GVariant *value, gpointer field)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (object);
|
||||
GVariantIter iter, attrs_iter;
|
||||
GVariant *variant, *attr_variant;
|
||||
const char *attr_name;
|
||||
|
||||
g_return_val_if_fail (g_variant_is_of_type (value, G_VARIANT_TYPE ("aa{sv}")), FALSE);
|
||||
|
||||
g_ptr_array_unref (priv->lldp_neighbors);
|
||||
priv->lldp_neighbors = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_lldp_neighbor_unref);
|
||||
g_variant_iter_init (&iter, value);
|
||||
|
||||
while (g_variant_iter_next (&iter, "@a{sv}", &variant)) {
|
||||
NMLldpNeighbor *neigh;
|
||||
|
||||
neigh = nm_lldp_neighbor_new ();
|
||||
g_variant_iter_init (&attrs_iter, variant);
|
||||
|
||||
while (g_variant_iter_next (&attrs_iter, "{&sv}", &attr_name, &attr_variant))
|
||||
g_hash_table_insert (neigh->attrs, g_strdup (attr_name), attr_variant);
|
||||
|
||||
g_variant_unref (variant);
|
||||
g_ptr_array_add (priv->lldp_neighbors, neigh);
|
||||
}
|
||||
|
||||
_nm_object_queue_notify (object, NM_DEVICE_LLDP_NEIGHBORS);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
device_state_changed (NMDBusDevice *proxy,
|
||||
guint new_state,
|
||||
|
@ -199,6 +239,7 @@ init_dbus (NMObject *object)
|
|||
{ NM_DEVICE_PHYSICAL_PORT_ID, &priv->physical_port_id },
|
||||
{ NM_DEVICE_MTU, &priv->mtu },
|
||||
{ NM_DEVICE_METERED, &priv->metered },
|
||||
{ NM_DEVICE_LLDP_NEIGHBORS, &priv->lldp_neighbors, demarshal_lldp_neighbors },
|
||||
|
||||
/* Properties that exist in D-Bus but that we don't track */
|
||||
{ "ip4-address", NULL },
|
||||
|
@ -350,6 +391,7 @@ dispose (GObject *object)
|
|||
g_clear_object (&priv->active_connection);
|
||||
|
||||
g_clear_pointer (&priv->available_connections, g_ptr_array_unref);
|
||||
g_clear_pointer (&priv->lldp_neighbors, g_ptr_array_unref);
|
||||
|
||||
G_OBJECT_CLASS (nm_device_parent_class)->dispose (object);
|
||||
}
|
||||
|
@ -461,6 +503,9 @@ get_property (GObject *object,
|
|||
case PROP_METERED:
|
||||
g_value_set_uint (value, nm_device_get_metered (device));
|
||||
break;
|
||||
case PROP_LLDP_NEIGHBORS:
|
||||
g_value_set_boxed (value, nm_device_get_lldp_neighbors (device));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
@ -839,6 +884,18 @@ nm_device_class_init (NMDeviceClass *device_class)
|
|||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/**
|
||||
* NMDevice:lldp-neighbors:
|
||||
*
|
||||
* The LLDP neighbors.
|
||||
**/
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_LLDP_NEIGHBORS,
|
||||
g_param_spec_boxed (NM_DEVICE_LLDP_NEIGHBORS, "", "",
|
||||
G_TYPE_PTR_ARRAY,
|
||||
G_PARAM_READABLE |
|
||||
G_PARAM_STATIC_STRINGS));
|
||||
|
||||
/* signals */
|
||||
|
||||
/**
|
||||
|
@ -2010,6 +2067,26 @@ nm_device_get_metered (NMDevice *device)
|
|||
|
||||
NM_BACKPORT_SYMBOL (libnm_1_0_6, NMMetered, nm_device_get_metered, (NMDevice *device), (device));
|
||||
|
||||
/**
|
||||
* nm_device_get_lldp_neighbors:
|
||||
* @device: a #NMDevice
|
||||
*
|
||||
* Gets the list of neighbors discovered through LLDP.
|
||||
*
|
||||
* Returns: (element-type NMLldpNeighbor) (transfer none): the #GPtrArray
|
||||
* containing #NMLldpNeighbor<!-- -->s. This is the internal copy used by the
|
||||
* device and must not be modified.
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
GPtrArray *
|
||||
nm_device_get_lldp_neighbors (NMDevice *device)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_DEVICE (device), NULL);
|
||||
|
||||
return NM_DEVICE_GET_PRIVATE (device)->lldp_neighbors;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_device_is_software:
|
||||
* @device: a #NMDevice
|
||||
|
@ -2360,3 +2437,182 @@ nm_device_get_setting_type (NMDevice *device)
|
|||
|
||||
return NM_DEVICE_GET_CLASS (device)->get_setting_type (device);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_lldp_neighbor_new
|
||||
*
|
||||
* Creates a new #NMLldpNeighbor object.
|
||||
*
|
||||
* Returns: (transfer full): the new #NMLldpNeighbor object.
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
NMLldpNeighbor *
|
||||
nm_lldp_neighbor_new (void)
|
||||
{
|
||||
NMLldpNeighbor *neigh;
|
||||
|
||||
neigh = g_new0 (NMLldpNeighbor, 1);
|
||||
neigh->refcount = 1;
|
||||
neigh->attrs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
|
||||
(GDestroyNotify) g_variant_unref);
|
||||
|
||||
return neigh;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_lldp_neighbor_ref
|
||||
* @neighbor: the #NMLldpNeighbor
|
||||
*
|
||||
* Increases the reference count of the object.
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
void
|
||||
nm_lldp_neighbor_ref (NMLldpNeighbor *neighbor)
|
||||
{
|
||||
g_return_if_fail (neighbor);
|
||||
g_return_if_fail (neighbor->refcount > 0);
|
||||
|
||||
neighbor->refcount++;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_lldp_neighbor_unref:
|
||||
* @neighbor: the #NMLldpNeighbor
|
||||
*
|
||||
* Decreases the reference count of the object. If the reference count
|
||||
* reaches zero, the object will be destroyed.
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
void
|
||||
nm_lldp_neighbor_unref (NMLldpNeighbor *neighbor)
|
||||
{
|
||||
g_return_if_fail (neighbor);
|
||||
g_return_if_fail (neighbor->refcount > 0);
|
||||
|
||||
if (--neighbor->refcount == 0) {
|
||||
g_return_if_fail (neighbor->attrs);
|
||||
g_hash_table_unref (neighbor->attrs);
|
||||
g_free (neighbor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_lldp_neighbor_get_attr_names:
|
||||
* @neighbor: the #NMLldpNeighbor
|
||||
*
|
||||
* Gets an array of attribute names available for @neighbor.
|
||||
*
|
||||
* Returns: (transfer full): a %NULL-terminated array of attribute names.
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
char **
|
||||
nm_lldp_neighbor_get_attr_names (NMLldpNeighbor *neighbor)
|
||||
{
|
||||
GHashTableIter iter;
|
||||
const char *key;
|
||||
GPtrArray *names;
|
||||
|
||||
g_return_val_if_fail (neighbor, NULL);
|
||||
g_return_val_if_fail (neighbor->attrs, NULL);
|
||||
|
||||
names = g_ptr_array_new ();
|
||||
|
||||
g_hash_table_iter_init (&iter, neighbor->attrs);
|
||||
while (g_hash_table_iter_next (&iter, (gpointer *) &key, NULL))
|
||||
g_ptr_array_add (names, g_strdup (key));
|
||||
|
||||
g_ptr_array_add (names, NULL);
|
||||
|
||||
return (char **) g_ptr_array_free (names, FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_lldp_neighbor_get_attr_string_value:
|
||||
* @neighbor: the #NMLldpNeighbor
|
||||
* @name: the attribute name
|
||||
* @out_value: (out) (allow-none) (transfer none): on return, the attribute value
|
||||
*
|
||||
* Gets the string value of attribute with name @name on @neighbor
|
||||
*
|
||||
* Returns: %TRUE if a string attribute with name @name was found, %FALSE otherwise
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
gboolean
|
||||
nm_lldp_neighbor_get_attr_string_value (NMLldpNeighbor *neighbor, char *name,
|
||||
const char **out_value)
|
||||
{
|
||||
GVariant *variant;
|
||||
|
||||
g_return_val_if_fail (neighbor, FALSE);
|
||||
g_return_val_if_fail (name && name[0], FALSE);
|
||||
|
||||
variant = g_hash_table_lookup (neighbor->attrs, name);
|
||||
if (variant && g_variant_is_of_type (variant, G_VARIANT_TYPE_STRING)) {
|
||||
if (out_value)
|
||||
*out_value = g_variant_get_string (variant, NULL);
|
||||
return TRUE;
|
||||
} else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_lldp_neighbor_get_attr_uint_value:
|
||||
* @neighbor: the #NMLldpNeighbor
|
||||
* @name: the attribute name
|
||||
* @out_value: (out) (allow-none) on return, the attribute value
|
||||
*
|
||||
* Gets the uint value of attribute with name @name on @neighbor
|
||||
*
|
||||
* Returns: %TRUE if a uint attribute with name @name was found, %FALSE otherwise
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
gboolean
|
||||
nm_lldp_neighbor_get_attr_uint_value (NMLldpNeighbor *neighbor, char *name,
|
||||
guint *out_value)
|
||||
{
|
||||
GVariant *variant;
|
||||
|
||||
g_return_val_if_fail (neighbor, FALSE);
|
||||
g_return_val_if_fail (name && name[0], FALSE);
|
||||
|
||||
variant = g_hash_table_lookup (neighbor->attrs, name);
|
||||
if (variant && g_variant_is_of_type (variant, G_VARIANT_TYPE_UINT32)) {
|
||||
if (out_value)
|
||||
*out_value = g_variant_get_uint32 (variant);
|
||||
return TRUE;
|
||||
} else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_lldp_neighbor_get_attr_type:
|
||||
* @neighbor: the #NMLldpNeighbor
|
||||
* @name: the attribute name
|
||||
*
|
||||
* Get the type of an attribute.
|
||||
*
|
||||
* Returns: the #GVariantType of the attribute with name @name
|
||||
*
|
||||
* Since: 1.2
|
||||
**/
|
||||
const GVariantType *
|
||||
nm_lldp_neighbor_get_attr_type (NMLldpNeighbor *neighbor, char *name)
|
||||
{
|
||||
GVariant *variant;
|
||||
|
||||
g_return_val_if_fail (neighbor, NULL);
|
||||
g_return_val_if_fail (name && name[0], NULL);
|
||||
|
||||
variant = g_hash_table_lookup (neighbor->attrs, name);
|
||||
if (variant)
|
||||
return g_variant_get_type (variant);
|
||||
else
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
|
|
@ -62,6 +62,7 @@ G_BEGIN_DECLS
|
|||
#define NM_DEVICE_PHYSICAL_PORT_ID "physical-port-id"
|
||||
#define NM_DEVICE_MTU "mtu"
|
||||
#define NM_DEVICE_METERED "metered"
|
||||
#define NM_DEVICE_LLDP_NEIGHBORS "lldp-neighbors"
|
||||
|
||||
struct _NMDevice {
|
||||
NMObject parent;
|
||||
|
@ -90,6 +91,8 @@ typedef struct {
|
|||
gpointer padding[8];
|
||||
} NMDeviceClass;
|
||||
|
||||
typedef struct _NMLldpNeighbor NMLldpNeighbor;
|
||||
|
||||
GType nm_device_get_type (void);
|
||||
|
||||
const char * nm_device_get_iface (NMDevice *device);
|
||||
|
@ -127,6 +130,8 @@ const char * nm_device_get_vendor (NMDevice *device);
|
|||
const char * nm_device_get_description (NMDevice *device);
|
||||
NM_AVAILABLE_IN_1_2
|
||||
NMMetered nm_device_get_metered (NMDevice *device);
|
||||
NM_AVAILABLE_IN_1_2
|
||||
GPtrArray * nm_device_get_lldp_neighbors (NMDevice *device);
|
||||
char ** nm_device_disambiguate_names (NMDevice **devices,
|
||||
int num_devices);
|
||||
|
||||
|
@ -164,6 +169,24 @@ gboolean nm_device_connection_compatible (NMDevice *device,
|
|||
|
||||
GType nm_device_get_setting_type (NMDevice *device);
|
||||
|
||||
NM_AVAILABLE_IN_1_2
|
||||
NMLldpNeighbor *nm_lldp_neighbor_new (void);
|
||||
NM_AVAILABLE_IN_1_2
|
||||
void nm_lldp_neighbor_ref (NMLldpNeighbor *neighbor);
|
||||
NM_AVAILABLE_IN_1_2
|
||||
void nm_lldp_neighbor_unref (NMLldpNeighbor *neighbor);
|
||||
NM_AVAILABLE_IN_1_2
|
||||
char **nm_lldp_neighbor_get_attr_names (NMLldpNeighbor *neighbor);
|
||||
NM_AVAILABLE_IN_1_2
|
||||
gboolean nm_lldp_neighbor_get_attr_string_value (NMLldpNeighbor *neighbor, char *name,
|
||||
const char **out_value);
|
||||
NM_AVAILABLE_IN_1_2
|
||||
gboolean nm_lldp_neighbor_get_attr_uint_value (NMLldpNeighbor *neighbor, char *name,
|
||||
guint *out_value);
|
||||
|
||||
NM_AVAILABLE_IN_1_2
|
||||
const GVariantType *nm_lldp_neighbor_get_attr_type (NMLldpNeighbor *neighbor, char *name);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __NM_DEVICE_H__ */
|
||||
|
|
Loading…
Reference in a new issue