summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2018-12-20 18:31:45 +0100
committerBeniamino Galvani <bgalvani@redhat.com>2018-12-20 18:56:14 +0100
commitc17068fb73338ac14ebe938dd4e8ed9bd512a811 (patch)
treed6753bfda0c12481255e882ac06425ec64bf736e
parent72dfb22cb755773a2829f0cc4ab5a2168334e824 (diff)
downloadNetworkManager-bg/lldp-parse-all-vlans-rh1652211.tar.gz
lldp: support multiple VLANsbg/lldp-parse-all-vlans-rh1652211
-rw-r--r--clients/cli/devices.c25
-rw-r--r--libnm-core/nm-dbus-interface.h1
-rw-r--r--src/devices/nm-lldp-listener.c62
-rw-r--r--src/devices/tests/test-lldp.c2
4 files changed, 57 insertions, 33 deletions
diff --git a/clients/cli/devices.c b/clients/cli/devices.c
index f582889d10..de210378d5 100644
--- a/clients/cli/devices.c
+++ b/clients/cli/devices.c
@@ -678,11 +678,12 @@ const NmcMetaGenericInfo *const nmc_fields_dev_lldp_list[] = {
NMC_META_GENERIC ("IEEE-802-1-PVID"), /* 9 */
NMC_META_GENERIC ("IEEE-802-1-PPVID"), /* 10 */
NMC_META_GENERIC ("IEEE-802-1-PPVID-FLAGS"), /* 11 */
- NMC_META_GENERIC ("IEEE-802-1-VID"), /* 12 */
- NMC_META_GENERIC ("IEEE-802-1-VLAN-NAME"), /* 13 */
- NMC_META_GENERIC ("DESTINATION"), /* 14 */
- NMC_META_GENERIC ("CHASSIS-ID-TYPE"), /* 15 */
- NMC_META_GENERIC ("PORT-ID-TYPE"), /* 16 */
+ NMC_META_GENERIC ("IEEE-802-1-VLANS"), /* 12 */
+ NMC_META_GENERIC ("IEEE-802-1-VID"), /* 13 */
+ NMC_META_GENERIC ("IEEE-802-1-VLAN-NAME"), /* 14 */
+ NMC_META_GENERIC ("DESTINATION"), /* 15 */
+ NMC_META_GENERIC ("CHASSIS-ID-TYPE"), /* 16 */
+ NMC_META_GENERIC ("PORT-ID-TYPE"), /* 17 */
NULL,
};
#define NMC_FIELDS_DEV_LLDP_LIST_COMMON "DEVICE,CHASSIS-ID,PORT-ID,PORT-DESCRIPTION,SYSTEM-NAME,SYSTEM-DESCRIPTION," \
@@ -4047,20 +4048,24 @@ show_device_lldp_list (NMDevice *device, NmCli *nmc, const char *fields_str, int
if (nm_lldp_neighbor_get_attr_uint_value (neighbor, NM_LLDP_ATTR_IEEE_802_1_PPVID_FLAGS, &value))
set_val_str (arr, 11, g_strdup_printf ("%u", value));
+ /* FIXME */
+ variant = nm_lldp_neighbor_get_attr_value (neighbor, NM_LLDP_ATTR_IEEE_802_1_VLANS);
+ set_val_str (arr, 12, variant ? g_variant_print (variant, FALSE) : g_strdup (""));
+
if (nm_lldp_neighbor_get_attr_uint_value (neighbor, NM_LLDP_ATTR_IEEE_802_1_VID, &value))
- set_val_str (arr, 12, g_strdup_printf ("%u", value));
+ set_val_str (arr, 13, g_strdup_printf ("%u", value));
if (nm_lldp_neighbor_get_attr_string_value (neighbor, NM_LLDP_ATTR_IEEE_802_1_VLAN_NAME, &str))
- set_val_strc (arr, 13, str);
+ set_val_strc (arr, 14, str);
if (nm_lldp_neighbor_get_attr_string_value (neighbor, NM_LLDP_ATTR_DESTINATION, &str))
- set_val_strc (arr, 14, str);
+ set_val_strc (arr, 15, str);
if (nm_lldp_neighbor_get_attr_uint_value (neighbor, NM_LLDP_ATTR_CHASSIS_ID_TYPE, &value))
- set_val_strc (arr, 15, g_strdup_printf ("%u", value));
+ set_val_strc (arr, 16, g_strdup_printf ("%u", value));
if (nm_lldp_neighbor_get_attr_uint_value (neighbor, NM_LLDP_ATTR_PORT_ID_TYPE, &value))
- set_val_strc (arr, 16, g_strdup_printf ("%u", value));
+ set_val_strc (arr, 17, g_strdup_printf ("%u", value));
g_ptr_array_add (out.output_data, arr);
}
diff --git a/libnm-core/nm-dbus-interface.h b/libnm-core/nm-dbus-interface.h
index f9ee2cc706..497b2f40e8 100644
--- a/libnm-core/nm-dbus-interface.h
+++ b/libnm-core/nm-dbus-interface.h
@@ -832,6 +832,7 @@ typedef enum /*< flags >*/ {
#define NM_LLDP_ATTR_IEEE_802_1_PPVID_FLAGS "ieee-802-1-ppvid-flags"
#define NM_LLDP_ATTR_IEEE_802_1_VID "ieee-802-1-vid"
#define NM_LLDP_ATTR_IEEE_802_1_VLAN_NAME "ieee-802-1-vlan-name"
+#define NM_LLDP_ATTR_IEEE_802_1_VLANS "ieee-802-1-vlans"
#define NM_LLDP_DEST_NEAREST_BRIDGE "nearest-bridge"
#define NM_LLDP_DEST_NEAREST_NON_TPMR_BRIDGE "nearest-non-tpmr-bridge"
diff --git a/src/devices/nm-lldp-listener.c b/src/devices/nm-lldp-listener.c
index a3037e3898..b10621ba60 100644
--- a/src/devices/nm-lldp-listener.c
+++ b/src/devices/nm-lldp-listener.c
@@ -58,6 +58,7 @@ typedef enum {
LLDP_ATTR_ID_IEEE_802_1_PPVID_FLAGS,
LLDP_ATTR_ID_IEEE_802_1_VID,
LLDP_ATTR_ID_IEEE_802_1_VLAN_NAME,
+ LLDP_ATTR_ID_IEEE_802_1_VLANS,
_LLDP_ATTR_ID_COUNT,
} LldpAttrId;
@@ -198,6 +199,7 @@ NM_UTILS_LOOKUP_STR_DEFINE_STATIC (_lldp_attr_id_to_name, LldpAttrId,
NM_UTILS_LOOKUP_STR_ITEM (LLDP_ATTR_ID_IEEE_802_1_PPVID_FLAGS, NM_LLDP_ATTR_IEEE_802_1_PPVID_FLAGS),
NM_UTILS_LOOKUP_STR_ITEM (LLDP_ATTR_ID_IEEE_802_1_VID, NM_LLDP_ATTR_IEEE_802_1_VID),
NM_UTILS_LOOKUP_STR_ITEM (LLDP_ATTR_ID_IEEE_802_1_VLAN_NAME, NM_LLDP_ATTR_IEEE_802_1_VLAN_NAME),
+ NM_UTILS_LOOKUP_STR_ITEM (LLDP_ATTR_ID_IEEE_802_1_VLANS, NM_LLDP_ATTR_IEEE_802_1_VLANS),
NM_UTILS_LOOKUP_ITEM_IGNORE (_LLDP_ATTR_ID_COUNT),
);
@@ -213,6 +215,7 @@ _NM_UTILS_LOOKUP_DEFINE (static, _lldp_attr_id_to_type, LldpAttrId, LldpAttrType
NM_UTILS_LOOKUP_ITEM (LLDP_ATTR_ID_IEEE_802_1_PPVID_FLAGS, LLDP_ATTR_TYPE_UINT32),
NM_UTILS_LOOKUP_ITEM (LLDP_ATTR_ID_IEEE_802_1_VID, LLDP_ATTR_TYPE_UINT32),
NM_UTILS_LOOKUP_ITEM (LLDP_ATTR_ID_IEEE_802_1_VLAN_NAME, LLDP_ATTR_TYPE_STRING),
+ NM_UTILS_LOOKUP_ITEM (LLDP_ATTR_ID_IEEE_802_1_VLANS, LLDP_ATTR_TYPE_ARRAY_OF_VARDICTS),
NM_UTILS_LOOKUP_ITEM_IGNORE (_LLDP_ATTR_ID_COUNT),
);
@@ -231,41 +234,44 @@ _lldp_attr_set_str (LldpAttrData *pdata, LldpAttrId attr_id, const char *v_strin
pdata->v_string = g_strdup (v_string ?: "");
}
-static void
-_lldp_attr_set_str_ptr (LldpAttrData *pdata, LldpAttrId attr_id, const void *str, gsize len)
+static char *
+escape_string (const void *str, gsize len)
{
const char *s = str;
const char *tmp;
gsize len0 = len;
gs_free char *str_free = NULL;
- nm_assert (pdata);
- nm_assert (_lldp_attr_id_to_type (attr_id) == LLDP_ATTR_TYPE_STRING);
-
- pdata = &pdata[attr_id];
-
- /* we ignore duplicate fields silently. */
- if (pdata->attr_type != LLDP_ATTR_TYPE_NONE)
- return;
-
- pdata->attr_type = LLDP_ATTR_TYPE_STRING;
-
/* truncate at first NUL, including removing trailing NULs*/
tmp = memchr (s, '\0', len);
if (tmp)
len = tmp - s;
- if (!len) {
- pdata->v_string = g_strdup ("");
- return;
- }
+ if (!len)
+ return g_strdup ("");
if (len0 <= len || s[len] != '\0') {
/* hmpf, g_strescape needs a trailing NUL. Need to clone */
s = str_free = g_strndup (s, len);
}
- pdata->v_string = g_strescape (s, NULL);
+ return g_strescape (s, NULL);
+}
+
+static void
+_lldp_attr_take_str_ptr (LldpAttrData *pdata, LldpAttrId attr_id, char *str)
+{
+ nm_assert (pdata);
+ nm_assert (_lldp_attr_id_to_type (attr_id) == LLDP_ATTR_TYPE_STRING);
+
+ pdata = &pdata[attr_id];
+
+ /* we ignore duplicate fields silently. */
+ if (pdata->attr_type != LLDP_ATTR_TYPE_NONE)
+ return;
+
+ pdata->attr_type = LLDP_ATTR_TYPE_STRING;
+ pdata->v_string = str;
}
static void
@@ -643,6 +649,9 @@ lldp_neighbor_new (sd_lldp_neighbor *neighbor_sd, GError **error)
break;
case SD_LLDP_OUI_802_1_SUBTYPE_VLAN_NAME: {
int l;
+ GVariantDict dict;
+ guint vid;
+ char *name;
if (len <= 3)
continue;
@@ -653,10 +662,19 @@ lldp_neighbor_new (sd_lldp_neighbor *neighbor_sd, GError **error)
if (l > 32)
continue;
- _lldp_attr_set_uint32 (neigh->attrs, LLDP_ATTR_ID_IEEE_802_1_VID,
- _access_uint16 (&data8[0]));
- _lldp_attr_set_str_ptr (neigh->attrs, LLDP_ATTR_ID_IEEE_802_1_VLAN_NAME,
- &data8[3], l);
+ name = escape_string (&data8[3], l);
+ vid = _access_uint16 (&data8[0]);
+
+ g_variant_dict_init (&dict, NULL);
+ g_variant_dict_insert (&dict, "vid", "u", vid);
+ g_variant_dict_insert (&dict, "name", "s", name);
+
+ _lldp_attr_add_vardict (neigh->attrs,
+ LLDP_ATTR_ID_IEEE_802_1_VLANS,
+ g_variant_ref_sink (g_variant_dict_end (&dict)));
+
+ _lldp_attr_set_uint32 (neigh->attrs, LLDP_ATTR_ID_IEEE_802_1_VID, vid);
+ _lldp_attr_take_str_ptr (neigh->attrs, LLDP_ATTR_ID_IEEE_802_1_VLAN_NAME, name);
break;
}
default:
diff --git a/src/devices/tests/test-lldp.c b/src/devices/tests/test-lldp.c
index 7227d08264..dcf5eeb9ce 100644
--- a/src/devices/tests/test-lldp.c
+++ b/src/devices/tests/test-lldp.c
@@ -242,7 +242,7 @@ _test_recv_data1_check (GMainLoop *loop, NMLldpListener *listener)
SD_LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS, "00:01:30:F9:AD:A0",
SD_LLDP_PORT_SUBTYPE_INTERFACE_NAME, "1/1");
g_assert (neighbor);
- g_assert_cmpint (g_variant_n_children (neighbor), ==, 4 + 10);
+ g_assert_cmpint (g_variant_n_children (neighbor), ==, 4 + 12);
attr = g_variant_lookup_value (neighbor, NM_LLDP_ATTR_DESTINATION, G_VARIANT_TYPE_STRING);
nmtst_assert_variant_string (attr, NM_LLDP_DEST_NEAREST_BRIDGE);