* Fixes:
+ Driver whitelisting is done before checking if an interface has
a lower interface in Linux.
+ + Expire remote ports and chassis in a timely manner.
lldpd (0.7.1)
* Features
log_debug("event", "received something for %s",
hardware->h_ifname);
lldpd_recv(cfg, hardware, fd);
+ levent_schedule_cleanup(cfg);
}
void
return 0;
}
+static void
+levent_trigger_cleanup(evutil_socket_t fd, short what, void *arg)
+{
+ struct lldpd *cfg = arg;
+ lldpd_cleanup(cfg);
+}
+
+void
+levent_schedule_cleanup(struct lldpd *cfg)
+{
+ log_debug("event", "schedule next cleanup");
+ if (cfg->g_cleanup_timer != NULL) {
+ event_free(cfg->g_cleanup_timer);
+ }
+ cfg->g_cleanup_timer = evtimer_new(cfg->g_base, levent_trigger_cleanup, cfg);
+ if (cfg->g_cleanup_timer == NULL) {
+ log_warnx("event",
+ "unable to allocate a new event for cleanup tasks");
+ return;
+ }
+
+ /* Compute the next TTL event */
+ struct timeval tv = { LOCAL_CHASSIS(cfg)->c_ttl, 0 };
+ time_t now = time(NULL);
+ time_t next;
+ struct lldpd_hardware *hardware;
+ struct lldpd_port *port;
+ TAILQ_FOREACH(hardware, &cfg->g_hardware, h_entries) {
+ TAILQ_FOREACH(port, &hardware->h_rports, p_entries) {
+ next = port->p_chassis->c_ttl - (now - port->p_lastupdate);
+ if (next > 0 && next < tv.tv_sec)
+ tv.tv_sec = next;
+ }
+ }
+
+ log_debug("event", "next cleanup in %ld seconds",
+ (long)tv.tv_sec);
+ if (event_add(cfg->g_cleanup_timer, &tv) == -1) {
+ log_warnx("event",
+ "unable to schedula cleanup task");
+ event_free(cfg->g_cleanup_timer);
+ cfg->g_cleanup_timer = NULL;
+ return;
+ }
+}
+
static void
levent_send_pdu(evutil_socket_t fd, short what, void *arg)
{
}
}
-static void
+void
lldpd_cleanup(struct lldpd *cfg)
{
struct lldpd_hardware *hardware, *hardware_next;
struct lldpd_chassis *chassis, *chassis_next;
- log_debug("alloc", "cleanup all local ports");
+ log_debug("localchassis", "cleanup all ports");
for (hardware = TAILQ_FIRST(&cfg->g_hardware); hardware != NULL;
hardware = hardware_next) {
lldpd_remote_cleanup(hardware, notify_clients_deletion);
}
- log_debug("alloc", "cleanup all chassis");
+ log_debug("localchassis", "cleanup all chassis");
for (chassis = TAILQ_FIRST(&cfg->g_chassis); chassis;
chassis = chassis_next) {
lldpd_chassis_cleanup(chassis, 1);
}
}
+
+ levent_schedule_cleanup(cfg);
}
/* Update chassis `ochassis' with values from `chassis'. The later one is not
struct protocol *g_protocols;
int g_lastrid;
struct event *g_main_loop;
+ struct event *g_cleanup_timer;
#ifdef USE_SNMP
int g_snmp;
struct event *g_snmp_timeout;
void lldpd_loop(struct lldpd *);
int lldpd_main(int, char **);
void lldpd_update_localports(struct lldpd *);
+void lldpd_cleanup(struct lldpd *);
/* frame.c */
u_int16_t frame_checksum(const u_int8_t *, int, int);
void levent_send_now(struct lldpd *);
int levent_iface_subscribe(struct lldpd *, int);
void levent_schedule_pdu(struct lldpd_hardware *);
+void levent_schedule_cleanup(struct lldpd *);
/* lldp.c */
int lldp_send(PROTO_SEND_SIG);
{
struct lldpd_port *port, *port_next;
int del;
+ time_t now = time(NULL);
log_debug("alloc", "cleanup remote port on %s",
hardware->h_ifname);
port_next = TAILQ_NEXT(port, p_entries);
del = (expire == NULL);
if (expire &&
- (time(NULL) - port->p_lastupdate > port->p_chassis->c_ttl)) {
+ (now - port->p_lastupdate > port->p_chassis->c_ttl)) {
hardware->h_ageout_cnt++;
hardware->h_delete_cnt++;
expire(hardware, port);