diff options
author | Beniamino Galvani <bgalvani@redhat.com> | 2018-12-20 18:31:45 +0100 |
---|---|---|
committer | Beniamino Galvani <bgalvani@redhat.com> | 2018-12-20 18:56:14 +0100 |
commit | c17068fb73338ac14ebe938dd4e8ed9bd512a811 (patch) | |
tree | d6753bfda0c12481255e882ac06425ec64bf736e | |
parent | 72dfb22cb755773a2829f0cc4ab5a2168334e824 (diff) | |
download | NetworkManager-bg/lldp-parse-all-vlans-rh1652211.tar.gz |
lldp: support multiple VLANsbg/lldp-parse-all-vlans-rh1652211
-rw-r--r-- | clients/cli/devices.c | 25 | ||||
-rw-r--r-- | libnm-core/nm-dbus-interface.h | 1 | ||||
-rw-r--r-- | src/devices/nm-lldp-listener.c | 62 | ||||
-rw-r--r-- | src/devices/tests/test-lldp.c | 2 |
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); |