mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-05 01:47:58 +02:00
lldp: separate LLDP attribute list from LldpNeighbor
We actually only need to parse the attributes while constructing the GVariant. In a first step decouple the tracking of the parsed attributes from LldpNeighbor struct. More will follow.
This commit is contained in:
parent
e189d65ab6
commit
28a0093d67
1 changed files with 89 additions and 67 deletions
|
|
@ -103,6 +103,10 @@ G_DEFINE_TYPE (NMLldpListener, nm_lldp_listener, G_TYPE_OBJECT)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
LldpAttrData a[_LLDP_ATTR_ID_COUNT];
|
||||
} LldpAttrs;
|
||||
|
||||
typedef struct {
|
||||
GVariant *variant;
|
||||
char *chassis_id;
|
||||
|
|
@ -110,7 +114,7 @@ typedef struct {
|
|||
|
||||
sd_lldp_neighbor *neighbor_sd;
|
||||
|
||||
LldpAttrData attrs[_LLDP_ATTR_ID_COUNT];
|
||||
LldpAttrs attrs;
|
||||
|
||||
struct ether_addr destination_address;
|
||||
|
||||
|
|
@ -224,12 +228,14 @@ _lldp_attr_id_to_type (LldpAttrId attr_id)
|
|||
}
|
||||
|
||||
static void
|
||||
_lldp_attr_set_str (LldpAttrData *pdata, LldpAttrId attr_id, const char *v_string)
|
||||
_lldp_attrs_set_str (LldpAttrs *attrs, LldpAttrId attr_id, const char *v_string)
|
||||
{
|
||||
nm_assert (pdata);
|
||||
LldpAttrData *pdata;
|
||||
|
||||
nm_assert (attrs);
|
||||
nm_assert (_lldp_attr_id_to_type (attr_id) == LLDP_ATTR_TYPE_STRING);
|
||||
|
||||
pdata = &pdata[attr_id];
|
||||
pdata = &attrs->a[attr_id];
|
||||
|
||||
/* we ignore duplicate fields silently. */
|
||||
if (pdata->attr_type != LLDP_ATTR_TYPE_NONE)
|
||||
|
|
@ -239,12 +245,14 @@ _lldp_attr_set_str (LldpAttrData *pdata, LldpAttrId attr_id, const char *v_strin
|
|||
}
|
||||
|
||||
static void
|
||||
_lldp_attr_set_str_take (LldpAttrData *pdata, LldpAttrId attr_id, char *str)
|
||||
_lldp_attrs_set_str_take (LldpAttrs *attrs, LldpAttrId attr_id, char *str)
|
||||
{
|
||||
nm_assert (pdata);
|
||||
LldpAttrData *pdata;
|
||||
|
||||
nm_assert (attrs);
|
||||
nm_assert (_lldp_attr_id_to_type (attr_id) == LLDP_ATTR_TYPE_STRING);
|
||||
|
||||
pdata = &pdata[attr_id];
|
||||
pdata = &attrs->a[attr_id];
|
||||
|
||||
/* we ignore duplicate fields silently. */
|
||||
if (pdata->attr_type != LLDP_ATTR_TYPE_NONE) {
|
||||
|
|
@ -257,12 +265,14 @@ _lldp_attr_set_str_take (LldpAttrData *pdata, LldpAttrId attr_id, char *str)
|
|||
}
|
||||
|
||||
static void
|
||||
_lldp_attr_set_uint32 (LldpAttrData *pdata, LldpAttrId attr_id, guint32 v_uint32)
|
||||
_lldp_attrs_set_uint32 (LldpAttrs *attrs, LldpAttrId attr_id, guint32 v_uint32)
|
||||
{
|
||||
nm_assert (pdata);
|
||||
LldpAttrData *pdata;
|
||||
|
||||
nm_assert (attrs);
|
||||
nm_assert (_lldp_attr_id_to_type (attr_id) == LLDP_ATTR_TYPE_UINT32);
|
||||
|
||||
pdata = &pdata[attr_id];
|
||||
pdata = &attrs->a[attr_id];
|
||||
|
||||
/* we ignore duplicate fields silently. */
|
||||
if (pdata->attr_type != LLDP_ATTR_TYPE_NONE)
|
||||
|
|
@ -272,13 +282,14 @@ _lldp_attr_set_uint32 (LldpAttrData *pdata, LldpAttrId attr_id, guint32 v_uint32
|
|||
}
|
||||
|
||||
static void
|
||||
_lldp_attr_set_variant (LldpAttrData *pdata, LldpAttrId attr_id, GVariant *variant)
|
||||
_lldp_attrs_set_variant (LldpAttrs *attrs, LldpAttrId attr_id, GVariant *variant)
|
||||
{
|
||||
LldpAttrData *pdata;
|
||||
|
||||
nm_assert (pdata);
|
||||
nm_assert (attrs);
|
||||
nm_assert (_lldp_attr_id_to_type (attr_id) == LLDP_ATTR_TYPE_VARIANT);
|
||||
|
||||
pdata = &pdata[attr_id];
|
||||
pdata = &attrs->a[attr_id];
|
||||
|
||||
/* we ignore duplicate fields silently */
|
||||
if (pdata->attr_type != LLDP_ATTR_TYPE_NONE) {
|
||||
|
|
@ -291,14 +302,16 @@ _lldp_attr_set_variant (LldpAttrData *pdata, LldpAttrId attr_id, GVariant *varia
|
|||
}
|
||||
|
||||
static void
|
||||
_lldp_attr_add_variant (LldpAttrData *pdata, LldpAttrId attr_id, GVariant *variant)
|
||||
_lldp_attr_add_variant (LldpAttrs *attrs, LldpAttrId attr_id, GVariant *variant)
|
||||
{
|
||||
nm_assert (pdata);
|
||||
LldpAttrData *pdata;
|
||||
|
||||
nm_assert (attrs);
|
||||
nm_assert (_lldp_attr_id_to_type (attr_id) == LLDP_ATTR_TYPE_ARRAY_OF_VARIANTS);
|
||||
|
||||
g_variant_ref_sink (variant);
|
||||
|
||||
pdata = &pdata[attr_id];
|
||||
pdata = &attrs->a[attr_id];
|
||||
|
||||
if (pdata->attr_type == LLDP_ATTR_TYPE_NONE) {
|
||||
pdata->attr_type = LLDP_ATTR_TYPE_ARRAY_OF_VARIANTS;
|
||||
|
|
@ -328,6 +341,39 @@ _lldp_attr_add_variant (LldpAttrData *pdata, LldpAttrId attr_id, GVariant *varia
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
_lldp_attrs_clear (LldpAttrs *attrs)
|
||||
{
|
||||
LldpAttrId attr_id;
|
||||
guint i;
|
||||
|
||||
for (attr_id = 0; attr_id < _LLDP_ATTR_ID_COUNT; attr_id++) {
|
||||
LldpAttrData *pdata = &attrs->a[attr_id];
|
||||
|
||||
switch (pdata->attr_type) {
|
||||
case LLDP_ATTR_TYPE_STRING:
|
||||
g_free (pdata->v_string);
|
||||
break;
|
||||
case LLDP_ATTR_TYPE_VARIANT:
|
||||
g_variant_unref (pdata->v_variant);
|
||||
break;
|
||||
case LLDP_ATTR_TYPE_ARRAY_OF_VARIANTS:
|
||||
if (pdata->v_variant_list.alloc == 1)
|
||||
g_variant_unref (pdata->v_variant_list.arr1);
|
||||
else {
|
||||
for (i = 0; i < pdata->v_variant_list.len; i++)
|
||||
g_variant_unref (pdata->v_variant_list.arr[i]);
|
||||
g_free (pdata->v_variant_list.arr);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
static void
|
||||
lldp_neighbor_get_raw (LldpNeighbor *neigh,
|
||||
const guint8 **out_raw_data,
|
||||
|
|
@ -391,37 +437,12 @@ lldp_neighbor_id_equal (gconstpointer a, gconstpointer b)
|
|||
static void
|
||||
lldp_neighbor_free (LldpNeighbor *neighbor)
|
||||
{
|
||||
LldpAttrId attr_id;
|
||||
guint i;
|
||||
|
||||
if (!neighbor)
|
||||
return;
|
||||
|
||||
g_free (neighbor->chassis_id);
|
||||
g_free (neighbor->port_id);
|
||||
for (attr_id = 0; attr_id < _LLDP_ATTR_ID_COUNT; attr_id++) {
|
||||
LldpAttrData *pdata = &neighbor->attrs[attr_id];
|
||||
|
||||
switch (pdata->attr_type) {
|
||||
case LLDP_ATTR_TYPE_STRING:
|
||||
g_free (pdata->v_string);
|
||||
break;
|
||||
case LLDP_ATTR_TYPE_VARIANT:
|
||||
g_variant_unref (pdata->v_variant);
|
||||
break;
|
||||
case LLDP_ATTR_TYPE_ARRAY_OF_VARIANTS:
|
||||
if (pdata->v_variant_list.alloc == 1)
|
||||
g_variant_unref (pdata->v_variant_list.arr1);
|
||||
else {
|
||||
for (i = 0; i < pdata->v_variant_list.len; i++)
|
||||
g_variant_unref (pdata->v_variant_list.arr[i]);
|
||||
g_free (pdata->v_variant_list.arr);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
}
|
||||
_lldp_attrs_clear (&neighbor->attrs);
|
||||
nm_g_variant_unref (neighbor->variant);
|
||||
sd_lldp_neighbor_unref (neighbor->neighbor_sd);
|
||||
nm_g_slice_free (neighbor);
|
||||
|
|
@ -618,16 +639,16 @@ lldp_neighbor_new (sd_lldp_neighbor *neighbor_sd, GError **error)
|
|||
}
|
||||
|
||||
if (sd_lldp_neighbor_get_port_description (neighbor_sd, &str) == 0)
|
||||
_lldp_attr_set_str (neigh->attrs, LLDP_ATTR_ID_PORT_DESCRIPTION, str);
|
||||
_lldp_attrs_set_str (&neigh->attrs, LLDP_ATTR_ID_PORT_DESCRIPTION, str);
|
||||
|
||||
if (sd_lldp_neighbor_get_system_name (neighbor_sd, &str) == 0)
|
||||
_lldp_attr_set_str (neigh->attrs, LLDP_ATTR_ID_SYSTEM_NAME, str);
|
||||
_lldp_attrs_set_str (&neigh->attrs, LLDP_ATTR_ID_SYSTEM_NAME, str);
|
||||
|
||||
if (sd_lldp_neighbor_get_system_description (neighbor_sd, &str) == 0)
|
||||
_lldp_attr_set_str (neigh->attrs, LLDP_ATTR_ID_SYSTEM_DESCRIPTION, str);
|
||||
_lldp_attrs_set_str (&neigh->attrs, LLDP_ATTR_ID_SYSTEM_DESCRIPTION, str);
|
||||
|
||||
if (sd_lldp_neighbor_get_system_capabilities (neighbor_sd, &data16) == 0)
|
||||
_lldp_attr_set_uint32 (neigh->attrs, LLDP_ATTR_ID_SYSTEM_CAPABILITIES, data16);
|
||||
_lldp_attrs_set_uint32 (&neigh->attrs, LLDP_ATTR_ID_SYSTEM_CAPABILITIES, data16);
|
||||
|
||||
r = sd_lldp_neighbor_tlv_rewind (neighbor_sd);
|
||||
if (r < 0) {
|
||||
|
|
@ -650,7 +671,7 @@ lldp_neighbor_new (sd_lldp_neighbor *neighbor_sd, GError **error)
|
|||
case SD_LLDP_TYPE_MGMT_ADDRESS:
|
||||
variant = parse_management_address_tlv (data8, len);
|
||||
if (variant) {
|
||||
_lldp_attr_add_variant (neigh->attrs,
|
||||
_lldp_attr_add_variant (&neigh->attrs,
|
||||
LLDP_ATTR_ID_MANAGEMENT_ADDRESSES,
|
||||
variant);
|
||||
}
|
||||
|
|
@ -699,22 +720,22 @@ lldp_neighbor_new (sd_lldp_neighbor *neighbor_sd, GError **error)
|
|||
case SD_LLDP_OUI_802_1_SUBTYPE_PORT_VLAN_ID:
|
||||
if (len != 2)
|
||||
continue;
|
||||
_lldp_attr_set_uint32 (neigh->attrs, LLDP_ATTR_ID_IEEE_802_1_PVID,
|
||||
unaligned_read_be16 (data8));
|
||||
_lldp_attrs_set_uint32 (&neigh->attrs, LLDP_ATTR_ID_IEEE_802_1_PVID,
|
||||
unaligned_read_be16 (data8));
|
||||
break;
|
||||
case SD_LLDP_OUI_802_1_SUBTYPE_PORT_PROTOCOL_VLAN_ID:
|
||||
if (len != 3)
|
||||
continue;
|
||||
_lldp_attr_set_uint32 (neigh->attrs, LLDP_ATTR_ID_IEEE_802_1_PPVID_FLAGS,
|
||||
data8[0]);
|
||||
_lldp_attr_set_uint32 (neigh->attrs, LLDP_ATTR_ID_IEEE_802_1_PPVID,
|
||||
unaligned_read_be16 (&data8[1]));
|
||||
_lldp_attrs_set_uint32 (&neigh->attrs, LLDP_ATTR_ID_IEEE_802_1_PPVID_FLAGS,
|
||||
data8[0]);
|
||||
_lldp_attrs_set_uint32 (&neigh->attrs, LLDP_ATTR_ID_IEEE_802_1_PPVID,
|
||||
unaligned_read_be16 (&data8[1]));
|
||||
|
||||
g_variant_dict_init (&dict, NULL);
|
||||
g_variant_dict_insert (&dict, "ppvid", "u", (guint32) unaligned_read_be16 (&data8[1]));
|
||||
g_variant_dict_insert (&dict, "flags", "u", (guint32) data8[0]);
|
||||
|
||||
_lldp_attr_add_variant (neigh->attrs,
|
||||
_lldp_attr_add_variant (&neigh->attrs,
|
||||
LLDP_ATTR_ID_IEEE_802_1_PPVIDS,
|
||||
g_variant_dict_end (&dict));
|
||||
break;
|
||||
|
|
@ -740,15 +761,15 @@ lldp_neighbor_new (sd_lldp_neighbor *neighbor_sd, GError **error)
|
|||
g_variant_dict_insert (&dict, "vid", "u", vid);
|
||||
g_variant_dict_insert (&dict, "name", "s", name);
|
||||
|
||||
_lldp_attr_add_variant (neigh->attrs,
|
||||
_lldp_attr_add_variant (&neigh->attrs,
|
||||
LLDP_ATTR_ID_IEEE_802_1_VLANS,
|
||||
g_variant_dict_end (&dict));
|
||||
|
||||
_lldp_attr_set_uint32 (neigh->attrs, LLDP_ATTR_ID_IEEE_802_1_VID, vid);
|
||||
_lldp_attrs_set_uint32 (&neigh->attrs, LLDP_ATTR_ID_IEEE_802_1_VID, vid);
|
||||
if (name_to_free)
|
||||
_lldp_attr_set_str_take (neigh->attrs, LLDP_ATTR_ID_IEEE_802_1_VLAN_NAME, name_to_free);
|
||||
_lldp_attrs_set_str_take (&neigh->attrs, LLDP_ATTR_ID_IEEE_802_1_VLAN_NAME, name_to_free);
|
||||
else
|
||||
_lldp_attr_set_str (neigh->attrs, LLDP_ATTR_ID_IEEE_802_1_VLAN_NAME, name);
|
||||
_lldp_attrs_set_str (&neigh->attrs, LLDP_ATTR_ID_IEEE_802_1_VLAN_NAME, name);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
@ -767,9 +788,9 @@ lldp_neighbor_new (sd_lldp_neighbor *neighbor_sd, GError **error)
|
|||
g_variant_dict_insert (&dict, "pmd-autoneg-cap", "u", (guint32) unaligned_read_be16 (&data8[1]));
|
||||
g_variant_dict_insert (&dict, "operational-mau-type", "u", (guint32) unaligned_read_be16 (&data8[3]));
|
||||
|
||||
_lldp_attr_set_variant (neigh->attrs,
|
||||
LLDP_ATTR_ID_IEEE_802_3_MAC_PHY_CONF,
|
||||
g_variant_dict_end (&dict));
|
||||
_lldp_attrs_set_variant (&neigh->attrs,
|
||||
LLDP_ATTR_ID_IEEE_802_3_MAC_PHY_CONF,
|
||||
g_variant_dict_end (&dict));
|
||||
break;
|
||||
case SD_LLDP_OUI_802_3_SUBTYPE_POWER_VIA_MDI:
|
||||
if (len != 3)
|
||||
|
|
@ -780,15 +801,16 @@ lldp_neighbor_new (sd_lldp_neighbor *neighbor_sd, GError **error)
|
|||
g_variant_dict_insert (&dict, "pse-power-pair", "u", (guint32) data8[1]);
|
||||
g_variant_dict_insert (&dict, "power-class", "u", (guint32) data8[2]);
|
||||
|
||||
_lldp_attr_set_variant (neigh->attrs,
|
||||
LLDP_ATTR_ID_IEEE_802_3_POWER_VIA_MDI,
|
||||
g_variant_dict_end (&dict));
|
||||
_lldp_attrs_set_variant (&neigh->attrs,
|
||||
LLDP_ATTR_ID_IEEE_802_3_POWER_VIA_MDI,
|
||||
g_variant_dict_end (&dict));
|
||||
break;
|
||||
case SD_LLDP_OUI_802_3_SUBTYPE_MAXIMUM_FRAME_SIZE:
|
||||
if (len != 2)
|
||||
continue;
|
||||
_lldp_attr_set_uint32 (neigh->attrs, LLDP_ATTR_ID_IEEE_802_3_MAX_FRAME_SIZE,
|
||||
unaligned_read_be16 (data8));
|
||||
_lldp_attrs_set_uint32 (&neigh->attrs,
|
||||
LLDP_ATTR_ID_IEEE_802_3_MAX_FRAME_SIZE,
|
||||
unaligned_read_be16 (data8));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -848,7 +870,7 @@ lldp_neighbor_to_variant (LldpNeighbor *neigh)
|
|||
}
|
||||
|
||||
for (attr_id = 0; attr_id < _LLDP_ATTR_ID_COUNT; attr_id++) {
|
||||
const LldpAttrData *pdata = &neigh->attrs[attr_id];
|
||||
const LldpAttrData *pdata = &neigh->attrs.a[attr_id];
|
||||
|
||||
nm_assert (NM_IN_SET (pdata->attr_type, _lldp_attr_id_to_type (attr_id), LLDP_ATTR_TYPE_NONE));
|
||||
switch (pdata->attr_type) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue