]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
lldpd: do not stay stuck in the receive loop
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:32:45 +0000 (23:32 +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
src/lldpd.c

index da95107eaf8c23524da43cefe4a140c5782eee55..3d8ed5f0956a5d3595b26597f2dedf201567bcf2 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -10,6 +10,12 @@ lldpd (0.6)
   * Fixes:
     + Several small SNMP fixes (discovered by unit tests).
 
+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:
     + Send and receive native VLAN TLV with CDP
index ba72c207305b36f23da3dce6b0f8e13b2fb6376f..e1d603ae8ace5d4baa6db64e046dfb6f31c003a5 100644 (file)
@@ -756,7 +756,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;
@@ -859,6 +861,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)
@@ -1039,8 +1042,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);
 }