summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2015-10-07 11:48:44 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2015-10-07 11:49:49 +0200
commit823c6c5b51fd6e302c62fef3614f673224794a21 (patch)
tree82bdb89a03e489f43bcc4881d73884948b5585e8
parent36bb2778d53cac63cb638ce152ff1157ec7013eb (diff)
downloadNetworkManager-bg/lldp-rh1142898-v4.tar.gz
libnm: add LLDP supportbg/lldp-rh1142898-v4
Add functions to libnm for retrieving a list of LLDP neighbors and accessor functions to get their attributes.
-rw-r--r--libnm/libnm.ver8
-rw-r--r--libnm/nm-device.c258
-rw-r--r--libnm/nm-device.h23
3 files changed, 289 insertions, 0 deletions
diff --git a/libnm/libnm.ver b/libnm/libnm.ver
index c720760a8f..a3f9282822 100644
--- a/libnm/libnm.ver
+++ b/libnm/libnm.ver
@@ -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;
diff --git a/libnm/nm-device.c b/libnm/nm-device.c
index 725762de61..dfc0d483a4 100644
--- a/libnm/nm-device.c
+++ b/libnm/nm-device.c
@@ -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,41 @@ 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),
+ g_variant_ref_sink (attr_variant));
+ g_variant_unref (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 +242,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 +394,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 +506,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 +887,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 */
/**
@@ -2011,6 +2071,25 @@ 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.
+ *
+ * Since: 1.2
+ **/
+const 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 +2439,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) 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;
+
+}
diff --git a/libnm/nm-device.h b/libnm/nm-device.h
index 4453bfeb2c..33b9dc2607 100644
--- a/libnm/nm-device.h
+++ b/libnm/nm-device.h
@@ -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
+const 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__ */