]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
lldp: don't send VLANs when there are too many of them
authorVincent Bernat <vincent@bernat.ch>
Sat, 14 May 2022 20:58:00 +0000 (22:58 +0200)
committerVincent Bernat <vincent@bernat.ch>
Sat, 14 May 2022 21:10:51 +0000 (23:10 +0200)
NEWS
src/daemon/protocols/lldp.c
tests/integration/test_dot1.py

diff --git a/NEWS b/NEWS
index 698a052f784b5ab7ff97e7efdd9b1f29a760890c..9af1fc43f9171bf63dad3ec91a7fb51612531202 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,7 @@ lldpd (1.0.14)
  * Fix:
    + Update seccomp rules for newer kernel/libc (#488)
    + Correctly handle an interface whose index has changed (#490)
+   + Don't send VLANs when there are too many (#510)
 
 lldpd (1.0.13)
  * Fix:
index c7c444297bc87d0ce7453dad018e9ea5fec3a0a7..04cca90f30c495b7a7ca7609f2d7a02339eb0053 100644 (file)
@@ -59,7 +59,8 @@ static int _lldp_send(struct lldpd *global,
     u_int8_t p_id_subtype,
     char *p_id,
     int p_id_len,
-    int shutdown)
+    int shutdown,
+    int without_vlans)
 {
        struct lldpd_port *port;
        struct lldpd_chassis *chassis;
@@ -68,6 +69,7 @@ static int _lldp_send(struct lldpd *global,
        u_int8_t *packet, *pos, *tlv;
        struct lldpd_mgmt *mgmt;
        int proto;
+       int vlans = 0;
 
        u_int8_t mcastaddr_regular[] = LLDP_ADDR_NEAREST_BRIDGE;
        u_int8_t mcastaddr_nontpmr[] = LLDP_ADDR_NEAREST_NONTPMR_BRIDGE;
@@ -248,6 +250,7 @@ static int _lldp_send(struct lldpd *global,
        }
        /* VLANs */
        TAILQ_FOREACH(vlan, &port->p_vlans, v_entries) {
+               vlans++;
                if (!(
                      POKE_START_LLDP_TLV(LLDP_TLV_ORG) &&
                      POKE_BYTES(dot1, sizeof(dot1)) &&
@@ -532,8 +535,21 @@ end:
        return 0;
 
 toobig:
-       log_info("lldp", "Cannot send LLDP packet for %s, too big message", hardware->h_ifname);
        free(packet);
+       if (vlans > 0 && !without_vlans) {
+               /* Retry without VLANs */
+               return _lldp_send(global,
+                   hardware,
+                   c_id_subtype,
+                   c_id,
+                   c_id_len,
+                   p_id_subtype,
+                   p_id,
+                   p_id_len,
+                   shutdown,
+                   1);
+       }
+       log_info("lldp", "Cannot send LLDP packet for %s, too big message", hardware->h_ifname);
        return E2BIG;
 }
 
@@ -552,7 +568,7 @@ lldp_send_shutdown(struct lldpd *global,
            hardware->h_lport_previous_id_subtype,
            hardware->h_lport_previous_id,
            hardware->h_lport_previous_id_len,
-           1);
+           1, 0);
 }
 
 int
@@ -590,7 +606,7 @@ lldp_send(struct lldpd *global,
                    port->p_id_subtype,
                    port->p_id,
                    port->p_id_len,
-                   0)) != 0)
+                   0, 0)) != 0)
                return ret;
 
        /* Record current chassis and port ID */
index ba16baa4c0967409149a4b3e5344cd25d2f06f35..03d6eb92f969bb17aec96d357619dd5f6dcc644d 100644 (file)
@@ -27,4 +27,13 @@ class TestLldpDot1(object):
             assert out['lldp.eth0.vlan.vlan-id'] == \
                 ['100', '200', '300', '4000']
 
+    def test_too_many_vlans(self, lldpd1, lldpd, lldpcli, namespaces, links):
+        with namespaces(2):
+            for v in range(100, 1000):
+                links.vlan('vlan{}'.format(v), v, 'eth1')
+            lldpd()
+        with namespaces(1):
+            out = lldpcli("-f", "keyvalue", "show", "neighbors", "details")
+            assert 'lldp.eth0.vlan' not in out
+
     # TODO: PI and PPVID (but lldpd doesn't know how to generate them)