]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
lldpd: do not stay stuck in the receive loop 0.5.7
authorVincent Bernat <bernat@luffy.cx>
Wed, 29 Feb 2012 22:14:41 +0000 (23:14 +0100)
committerVincent Bernat <bernat@luffy.cx>
Wed, 29 Feb 2012 22:25:50 +0000 (23:25 +0100)
On some corner case conditions, we can stay stuck in the receive loop
because we did not send packets for more than 30 seconds. In this
case, we keep reset the timeout to 30 seconds and we cannot exit the
loop (since the first condition to exit the loop is to have reached
the timeout).

Therefore, we invert the condition. If we have stay too long in the
loop, just exit. We know for sure that we will hit lldpd_send_all()
soon and get back to a sane state.

Also, in receive only state, we are also stuck in the loop. This
forbids us to update data about local chassis and interfaces. We also
fix this.

CHANGELOG
configure.ac
src/lldpd.c

index cfcb2d0d131ace1ce00fa532e5bb2866ea0f9802..6b40e2677216a7d198abf18417758b55ea557455 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,8 @@
 lldpd (0.5.7)
  * Fixes:
     + Configure issue with NetSNMP and some linkers
+    + Fix infinite loop for the receive part: on certain conditions,
+      lldpd will stop sending packets and stop updating local data.
 
 lldpd (0.5.6)
   * Features:
index 59a5aa42b46b5cbf12338613ea33e3635326c1ff..2822ebc6ae3a73c52ad4d9d2868909c9b01a085e 100644 (file)
@@ -6,7 +6,7 @@
 
 # Configure autoconf
 AC_PREREQ([2.64])
-AC_INIT([lldpd], [0.5.6], [bernat@luffy.cx])
+AC_INIT([lldpd], [0.5.7], [bernat@luffy.cx])
 AC_CONFIG_SRCDIR([src/lldpd.c])
 AC_CONFIG_HEADER([config.h])
 AC_CONFIG_FILES([Makefile src/Makefile man/Makefile tests/Makefile])
index 6f592d61e35a584433be0e5fb038651fba3edc0b..bbfe2a7255618fd2917d0962da144f4498b6a326 100644 (file)
@@ -776,7 +776,9 @@ lldpd_recv_all(struct lldpd *cfg)
        do {
                tv.tv_sec = cfg->g_delay - (time(NULL) - cfg->g_lastsent);
                if (tv.tv_sec < 0)
-                       tv.tv_sec = LLDPD_TX_DELAY;
+                       /* We did not send packets in a long time,
+                          just give up receive for now. */
+                       break;
                if (tv.tv_sec >= cfg->g_delay)
                        tv.tv_sec = cfg->g_delay;
                tv.tv_usec = 0;
@@ -879,6 +881,7 @@ lldpd_send_all(struct lldpd *cfg)
        int i, sent;
 
        cfg->g_lastsent = time(NULL);
+       if (cfg->g_receiveonly) return;
        TAILQ_FOREACH(hardware, &cfg->g_hardware, h_entries) {
                /* Ignore if interface is down */
                if ((hardware->h_flags & IFF_RUNNING) == 0)
@@ -1061,8 +1064,7 @@ lldpd_loop(struct lldpd *cfg)
        lldpd_update_localports(cfg);
        lldpd_cleanup(cfg);
        lldpd_update_localchassis(cfg);
-       if (!cfg->g_receiveonly)
-               lldpd_send_all(cfg);
+       lldpd_send_all(cfg);
        lldpd_recv_all(cfg);
 }