mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-07 04:58:01 +02:00
We currently use the systemd LLDP client, which we consume by forking systemd code. That is a maintenance burden, because it's not a self-contained, stable library that we use. Hence there is a need for an individual library or properly integrating the fork in our tree. Optimally, we would create a new nettools project with an LLDP library. That was not done because: - nettools may want to be dual licensed with LGPL-2.1+ and Apache. Systemd code is LGPL-2.1+ so it is fine for NetworkManager but possibly not for nettools. - nettools provides independent librares, as such they don't have an event loop, instead they expose an epoll file descriptor and the user needs to integrate it. Systemd and NetworkManager on the other hand have their established event loop (sd_event and GMainContext, respectively). It's simpler to implement the library on those terms, in particular porting the systemd library from sd_event to GMainContext. - NetworkManager uses glib and has various helper utils. While it's possible to do without them, it's more work. The main reason to not write a new NetworkManager-agnostic library from scratch, is that it's much simpler to fork the systemd library and make it part of NetworkManager, than making it a nettools library. Do it.
124 lines
5.1 KiB
C
124 lines
5.1 KiB
C
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
|
#ifndef __NM_LLDP_RX_H__
|
|
#define __NM_LLDP_RX_H__
|
|
|
|
#include "nm-lldp.h"
|
|
|
|
typedef struct _NMLldpRX NMLldpRX;
|
|
typedef struct _NMLldpNeighbor NMLldpNeighbor;
|
|
|
|
typedef enum {
|
|
NM_LLDP_RX_EVENT_ADDED,
|
|
NM_LLDP_RX_EVENT_REMOVED,
|
|
NM_LLDP_RX_EVENT_UPDATED,
|
|
NM_LLDP_RX_EVENT_REFRESHED,
|
|
_NM_LLDP_RX_EVENT_MAX,
|
|
_NM_LLDP_RX_EVENT_INVALID = -EINVAL,
|
|
} NMLldpRXEvent;
|
|
|
|
const char *nm_lldp_rx_event_to_string(NMLldpRXEvent e) _nm_pure;
|
|
|
|
typedef struct {
|
|
/* The spec calls this an "MSAP identifier" */
|
|
const void *chassis_id;
|
|
size_t chassis_id_size;
|
|
|
|
const void *port_id;
|
|
size_t port_id_size;
|
|
} NMLldpNeighborID;
|
|
|
|
guint nm_lldp_neighbor_id_hash(const NMLldpNeighborID *id);
|
|
int nm_lldp_neighbor_id_cmp(const NMLldpNeighborID *x, const NMLldpNeighborID *y);
|
|
gboolean nm_lldp_neighbor_id_equal(const NMLldpNeighborID *x, const NMLldpNeighborID *y);
|
|
|
|
typedef void (*NMLldpRXCallback)(NMLldpRX *lldp_rx,
|
|
NMLldpRXEvent event,
|
|
NMLldpNeighbor *n,
|
|
void *userdata);
|
|
|
|
typedef struct {
|
|
int ifindex;
|
|
guint neighbors_max;
|
|
const char *log_ifname;
|
|
const char *log_uuid;
|
|
NMLldpRXCallback callback;
|
|
void *userdata;
|
|
|
|
/* In order to deal nicely with bridges that send back our own packets, allow one address to be filtered, so
|
|
* that our own can be filtered out here. */
|
|
NMEtherAddr filter_address;
|
|
|
|
uint16_t capability_mask;
|
|
bool has_capability_mask : 1;
|
|
} NMLldpRXConfig;
|
|
|
|
NMLldpRX *nm_lldp_rx_new(const NMLldpRXConfig *config);
|
|
NMLldpRX *nm_lldp_rx_ref(NMLldpRX *lldp_rx);
|
|
void nm_lldp_rx_unref(NMLldpRX *lldp_rx);
|
|
|
|
NM_AUTO_DEFINE_FCN(NMLldpRX *, nm_lldp_rx_unrefp, nm_lldp_rx_unref);
|
|
|
|
int nm_lldp_rx_start(NMLldpRX *lldp_rx);
|
|
int nm_lldp_rx_stop(NMLldpRX *lldp_rx);
|
|
gboolean nm_lldp_rx_is_running(NMLldpRX *lldp_rx);
|
|
|
|
/* Controls how much and what to store in the neighbors database */
|
|
|
|
NMLldpNeighbor **nm_lldp_rx_get_neighbors(NMLldpRX *lldp_rx, guint *out_len);
|
|
|
|
/*****************************************************************************/
|
|
|
|
NMLldpNeighbor *nm_lldp_neighbor_new_from_raw(const void *raw, size_t raw_size);
|
|
|
|
NMLldpNeighbor *nm_lldp_neighbor_ref(NMLldpNeighbor *n);
|
|
NMLldpNeighbor *nm_lldp_neighbor_unref(NMLldpNeighbor *n);
|
|
|
|
NM_AUTO_DEFINE_FCN(NMLldpNeighbor *, nm_lldp_neighbor_unrefp, nm_lldp_neighbor_unref);
|
|
|
|
int nm_lldp_neighbor_cmp(const NMLldpNeighbor *a, const NMLldpNeighbor *b);
|
|
|
|
static inline gboolean
|
|
nm_lldp_neighbor_equal(const NMLldpNeighbor *a, const NMLldpNeighbor *b)
|
|
{
|
|
return nm_lldp_neighbor_cmp(a, b) == 0;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
|
|
static inline const NMLldpNeighborID *
|
|
nm_lldp_neighbor_get_id(NMLldpNeighbor *lldp_neigbor)
|
|
{
|
|
return (const NMLldpNeighborID *) ((gconstpointer) lldp_neigbor);
|
|
}
|
|
|
|
/* Access to LLDP frame metadata */
|
|
int nm_lldp_neighbor_get_source_address(NMLldpNeighbor *n, NMEtherAddr *address);
|
|
int nm_lldp_neighbor_get_destination_address(NMLldpNeighbor *n, NMEtherAddr *address);
|
|
int nm_lldp_neighbor_get_timestamp_usec(NMLldpNeighbor *n, gint64 *out_usec);
|
|
int nm_lldp_neighbor_get_raw(NMLldpNeighbor *n, const void **ret, size_t *size);
|
|
|
|
/* High-level, direct, parsed out field access. These fields exist at most once, hence may be queried directly. */
|
|
int
|
|
nm_lldp_neighbor_get_chassis_id(NMLldpNeighbor *n, uint8_t *type, const void **ret, size_t *size);
|
|
const char *nm_lldp_neighbor_get_chassis_id_as_string(NMLldpNeighbor *n);
|
|
int nm_lldp_neighbor_get_port_id(NMLldpNeighbor *n, uint8_t *type, const void **ret, size_t *size);
|
|
const char *nm_lldp_neighbor_get_port_id_as_string(NMLldpNeighbor *n);
|
|
int nm_lldp_neighbor_get_ttl(NMLldpNeighbor *n, uint16_t *ret_sec);
|
|
int nm_lldp_neighbor_get_system_name(NMLldpNeighbor *n, const char **ret);
|
|
int nm_lldp_neighbor_get_system_description(NMLldpNeighbor *n, const char **ret);
|
|
int nm_lldp_neighbor_get_port_description(NMLldpNeighbor *n, const char **ret);
|
|
int nm_lldp_neighbor_get_mud_url(NMLldpNeighbor *n, const char **ret);
|
|
int nm_lldp_neighbor_get_system_capabilities(NMLldpNeighbor *n, uint16_t *ret);
|
|
int nm_lldp_neighbor_get_enabled_capabilities(NMLldpNeighbor *n, uint16_t *ret);
|
|
|
|
/* Low-level, iterative TLV access. This is for everything else, it iteratively goes through all available TLVs
|
|
* (including the ones covered with the calls above), and allows multiple TLVs for the same fields. */
|
|
int nm_lldp_neighbor_tlv_rewind(NMLldpNeighbor *n);
|
|
int nm_lldp_neighbor_tlv_next(NMLldpNeighbor *n);
|
|
int nm_lldp_neighbor_tlv_get_type(NMLldpNeighbor *n, uint8_t *type);
|
|
int nm_lldp_neighbor_tlv_is_type(NMLldpNeighbor *n, uint8_t type);
|
|
int nm_lldp_neighbor_tlv_get_oui(NMLldpNeighbor *n, uint8_t oui[static 3], uint8_t *subtype);
|
|
int nm_lldp_neighbor_tlv_is_oui(NMLldpNeighbor *n, const uint8_t oui[static 3], uint8_t subtype);
|
|
int nm_lldp_neighbor_tlv_get_raw(NMLldpNeighbor *n, const void **ret, size_t *size);
|
|
|
|
#endif /* __NM_LLDP_RX_H__ */
|