TAILQ_INSERT_TAIL(&cfg->g_hardware, hardware, h_entries);
} else {
if (hardware->h_flags) continue; /* Already seen this time */
- lldpd_port_cleanup(&hardware->h_lport, 0);
+ lldpd_port_cleanup(cfg, &hardware->h_lport, 0);
}
port = &hardware->h_lport;
if (hardware->h_flags) continue; /* Already seen this time */
memset(hardware->h_data, 0, IFNAMSIZ);
if_indextoname(master, hardware->h_data);
- lldpd_port_cleanup(&hardware->h_lport, 0);
+ lldpd_port_cleanup(cfg, &hardware->h_lport, 0);
}
port = &hardware->h_lport;
/* If `all' is true, clear all information, including information that
are not refreshed periodically. Port should be freed manually. */
void
-lldpd_port_cleanup(struct lldpd_port *port, int all)
+lldpd_port_cleanup(struct lldpd *cfg, struct lldpd_port *port, int all)
{
#ifdef ENABLE_LLDPMED
int i;
free(port->p_descr);
if (all) {
free(port->p_lastframe);
- if (port->p_chassis) /* chassis may not have been attributed, yet */
+ if (port->p_chassis) { /* chassis may not have been attributed, yet */
port->p_chassis->c_refcount--;
+ if (port->p_chassis->c_refcount == 0) {
+ /* This is the last port referencing this chassis */
+ TAILQ_REMOVE(&cfg->g_chassis, port->p_chassis, c_entries);
+ lldpd_chassis_cleanup(port->p_chassis, 1);
+ }
+ port->p_chassis = NULL;
+ }
}
}
}
if (del) {
TAILQ_REMOVE(&hardware->h_rports, port, p_entries);
- lldpd_port_cleanup(port, 1);
+ lldpd_port_cleanup(cfg, port, 1);
free(port);
}
}
lldpd_hardware_cleanup(struct lldpd *cfg, struct lldpd_hardware *hardware)
{
int i;
- lldpd_port_cleanup(&hardware->h_lport, 1);
+ lldpd_port_cleanup(cfg, &hardware->h_lport, 1);
/* If we have a dedicated cleanup function, use it. Otherwise,
we just free the hardware-dependent data and close all FD
in h_recvfds and h_sendfd. */
if (oport) {
/* The port is known, remove it before adding it back */
TAILQ_REMOVE(&hardware->h_rports, oport, p_entries);
- lldpd_port_cleanup(oport, 1);
+ lldpd_port_cleanup(cfg, oport, 1);
free(oport);
}
if (ochassis) {
TAILQ_INIT(&cfg->g_hardware);
TAILQ_INIT(&cfg->g_chassis);
TAILQ_INSERT_TAIL(&cfg->g_chassis, lchassis, c_entries);
- lchassis->c_refcount++;
+ lchassis->c_refcount++; /* We should always keep a reference to local chassis */
TAILQ_INIT(&cfg->g_callbacks);
void lldpd_vlan_cleanup(struct lldpd_port *);
#endif
void lldpd_remote_cleanup(struct lldpd *, struct lldpd_hardware *, int);
-void lldpd_port_cleanup(struct lldpd_port *, int);
+void lldpd_port_cleanup(struct lldpd*, struct lldpd_port *, int);
void lldpd_chassis_cleanup(struct lldpd_chassis *, int);
int lldpd_callback_add(struct lldpd *, int, void(*fn)(CALLBACK_SIG), void *);
void lldpd_callback_del(struct lldpd *, int, void(*fn)(CALLBACK_SIG));