]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
interfaces: compute interface index for fixed management address
authorVincent Bernat <vincent@bernat.ch>
Sat, 27 Jul 2019 15:28:01 +0000 (17:28 +0200)
committerVincent Bernat <vincent@bernat.ch>
Sat, 27 Jul 2019 15:34:16 +0000 (17:34 +0200)
When management address is provided without a pattern, fetch the
appropriate interface index if the interface is known. Thanks to
@kefins for the actual patch.

Fix #338.

src/daemon/interfaces.c
tests/integration/test_basic.py

index 3c6c255da2e8cb8dacc448051e41bbd78216ca06..e6fcc551defc382b63780b589f87cf79414e8509 100644 (file)
@@ -477,6 +477,9 @@ interfaces_helper_mgmt(struct lldpd *cfg,
        if (pattern && strpbrk(pattern, "!,*?") == NULL) {
                struct in6_addr addr;
                size_t addr_size;
+               struct lldpd_mgmt *mgmt;
+               struct interfaces_address *ifaddr;
+
                for (af = LLDPD_AF_UNSPEC + 1;
                     af != LLDPD_AF_LAST; af++) {
                        switch (af) {
@@ -490,17 +493,35 @@ interfaces_helper_mgmt(struct lldpd *cfg,
                if (af == LLDPD_AF_LAST) {
                        log_debug("interfaces",
                            "interface management pattern is an incorrect IP");
-               } else {
-                       struct lldpd_mgmt *mgmt;
-                       mgmt = lldpd_alloc_mgmt(af, &addr, addr_size, 0);
-                       if (mgmt == NULL) {
-                               log_warn("interfaces", "out of memory error");
-                               return;
+                       return;
+               }
+
+               /* Try to get the index if possible. */
+               TAILQ_FOREACH(ifaddr, addrs, next) {
+                       if (ifaddr->address.ss_family != lldpd_af(af))
+                               continue;
+                       if (LLDPD_AF_IPV4 == af) {
+                               struct sockaddr_in *sa_sin;
+                               sa_sin = (struct sockaddr_in *)&ifaddr->address;
+                               if ((sa_sin->sin_addr.s_addr) == ((struct in_addr *)&addr)->s_addr)
+                                       break;
                        }
-                       log_debug("interfaces", "add exact management address %s",
-                               pattern);
-                       TAILQ_INSERT_TAIL(&LOCAL_CHASSIS(cfg)->c_mgmt, mgmt, m_entries);
+                       else if (LLDPD_AF_IPV6 == af) {
+                               if (0 == memcmp(&addr,
+                                   &((struct sockaddr_in6 *)&ifaddr->address)->sin6_addr,
+                                   addr_size))
+                                       break;
+                       }
+               }
+
+               mgmt = lldpd_alloc_mgmt(af, &addr, addr_size, ifaddr ? ifaddr->index : 0);
+               if (mgmt == NULL) {
+                       log_warn("interfaces", "out of memory error");
+                       return;
                }
+               log_debug("interfaces", "add exact management address %s",
+                   pattern);
+               TAILQ_INSERT_TAIL(&LOCAL_CHASSIS(cfg)->c_mgmt, mgmt, m_entries);
                return;
        }
 
index 6d79020cd0eadd31e3db5549d23ec9adb9540894..f2cea6ba1565ff54e4e004c0412c8c720713e44d 100644 (file)
@@ -146,7 +146,7 @@ def test_listen_only(lldpd1, lldpd, lldpcli, namespaces):
         assert out == {}
 
 
-def test_forced_management_address(lldpd1, lldpd, lldpcli, namespaces):
+def test_forced_unknown_management_address(lldpd1, lldpd, lldpcli, namespaces):
     with namespaces(2):
         lldpd("-m", "2001:db8::47")
     with namespaces(1):
@@ -155,6 +155,18 @@ def test_forced_management_address(lldpd1, lldpd, lldpcli, namespaces):
         assert out["lldp.eth0.chassis.mgmt-iface"] == "0"
 
 
+def test_forced_known_management_address(lldpd1, lldpd, lldpcli, namespaces):
+    with namespaces(2):
+        ipr = pyroute2.IPRoute()
+        idx = ipr.link_lookup(ifname="eth1")[0]
+        ipr.addr('add', index=idx, address="192.168.14.2", mask=24)
+        lldpd("-m", "192.168.14.2")
+    with namespaces(1):
+        out = lldpcli("-f", "keyvalue", "show", "neighbors")
+        assert out["lldp.eth0.chassis.mgmt-ip"] == "192.168.14.2"
+        assert out["lldp.eth0.chassis.mgmt-iface"] == "2"
+
+
 def test_management_address(lldpd1, lldpd, lldpcli, links, namespaces):
     with namespaces(2):
         ipr = pyroute2.IPRoute()