This allows us to get an instant linkup/linkdown notification.
---
 .../mibgroup/if-mib/data_access/interface_linux.c  |   92 ++++++++++++++++++++
 agent/mibgroup/if-mib/ifTable/ifTable_interface.c  |   10 +++
 agent/mibgroup/if-mib/ifTable/ifTable_interface.h  |    5 ++
 3 files changed, 107 insertions(+)

diff --git a/agent/mibgroup/if-mib/data_access/interface_linux.c 
b/agent/mibgroup/if-mib/data_access/interface_linux.c
index d4ac61b..c1ed508 100644
--- a/agent/mibgroup/if-mib/data_access/interface_linux.c
+++ b/agent/mibgroup/if-mib/data_access/interface_linux.c
@@ -102,6 +102,9 @@ netsnmp_prefix_listen_info list_info;
  
 int netsnmp_prefix_listen(void);
 #endif
+#ifdef HAVE_LINUX_RTNETLINK_H
+static int netsnmp_iflink_listen(void);
+#endif
 
 
 void
@@ -141,6 +144,9 @@ netsnmp_arch_interface_init(void)
     list_info.list_head = &prefix_head_list;
     netsnmp_prefix_listen();
 #endif
+#ifdef HAVE_LINUX_RTNETLINK_H
+    netsnmp_iflink_listen();
+#endif
 
 #ifdef HAVE_PCI_LOOKUP_NAME
     pci_access = pci_alloc();
@@ -1046,6 +1052,92 @@ static int netsnmp_netlink_listen(unsigned subscriptions)
     return fd;
 }
 #endif
+
+#ifdef HAVE_LINUX_RTNETLINK_H
+static void netsnmp_iflink_process(int fd, void *data)
+{
+    int                status;
+    char               buf[16384];
+    struct nlmsghdr    *nlmp;
+    struct ifinfomsg   *ifi;
+    int                len, req_len, length; 
+
+    status = recv(fd, buf, sizeof(buf), 0);
+    if (status < 0) {
+        snmp_log(LOG_ERR,"netsnmp_iflink_listen: Receive failed.\n");
+        return;
+    }
+
+    if (status == 0){
+        DEBUGMSGTL(("access:interface:iflink", "End of File\n"));
+        return;
+    }
+
+    for (nlmp = (struct nlmsghdr *)buf;
+        status > sizeof(*nlmp);
+        status -= NLMSG_ALIGN(len),
+            nlmp = (struct nlmsghdr*)((char*)nlmp + NLMSG_ALIGN(len))) {
+       len = nlmp->nlmsg_len;
+        req_len = len - sizeof(*nlmp);
+
+        if (req_len < 0 || len > status) {
+            snmp_log(LOG_ERR,"netsnmp_iflink_listen: Error in length\n");
+            return;
+        }
+
+        if (!NLMSG_OK(nlmp, status)) {
+            DEBUGMSGTL(("access:interface:iflink", "NLMSG not OK\n"));
+            return;
+        }
+
+        if (nlmp->nlmsg_type == RTM_NEWLINK ||
+           nlmp->nlmsg_type == RTM_DELLINK) {
+           ifi = NLMSG_DATA(nlmp);
+            length = nlmp->nlmsg_len - NLMSG_LENGTH(sizeof(*ifi));
+
+            if (length < 0) {
+                DEBUGMSGTL(("access:interface:iflink", "wrong nlmsg length 
%d\n", length));
+                return;
+            }
+
+           /* Just request a refresh! */
+           ifTable_cache_reload();
+        }
+    }
+}
+
+static int netsnmp_iflink_listen()
+{
+    struct {
+       struct nlmsghdr nlh;
+       struct rtgenmsg g;
+    } req;
+    int status;
+    int fd = netsnmp_netlink_listen(RTNLGRP_LINK);
+    if (fd < 0) return -1;
+
+    memset(&req, 0, sizeof(req));
+    req.nlh.nlmsg_len = sizeof(req);
+    req.nlh.nlmsg_type = RTM_GETLINK;
+    req.nlh.nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST;
+    req.g.rtgen_family = AF_UNSPEC;
+
+    status = send(fd, (void*)&req, sizeof(req), 0);
+    if (status < 0) {
+        snmp_log(LOG_ERR,"netsnmp_iflink_listen: send failed\n");
+        close(fd);
+        return -1;
+    }
+
+    if (register_readfd(fd, netsnmp_iflink_process, NULL) != 0) {
+        snmp_log(LOG_ERR,"netsnmp_iflink_listen: error registering netlink 
socket\n");
+        close(fd);
+        return -1;
+    }
+    return 0;
+
+}
+#endif
     
 #ifdef SUPPORT_PREFIX_FLAGS
 void netsnmp_prefix_process(int fd, void *data);
diff --git a/agent/mibgroup/if-mib/ifTable/ifTable_interface.c 
b/agent/mibgroup/if-mib/ifTable/ifTable_interface.c
index 41d38ee..151a807 100644
--- a/agent/mibgroup/if-mib/ifTable/ifTable_interface.c
+++ b/agent/mibgroup/if-mib/ifTable/ifTable_interface.c
@@ -1853,6 +1853,16 @@ _mfd_ifTable_irreversible_commit(netsnmp_mib_handler 
*handler,
  ***********************************************************************/
 static void     _container_free(netsnmp_container *container);
 
+void
+ifTable_cache_reload()
+{
+    DEBUGMSGTL(("ifTable:cache_reload", "triggered\n"));
+    if (NULL != ifTable_if_ctx.cache) {
+       ifTable_if_ctx.cache->valid = 0;
+       netsnmp_cache_check_and_reload(ifTable_if_ctx.cache);
+    }
+}
+
 /**
  * @internal
  */
diff --git a/agent/mibgroup/if-mib/ifTable/ifTable_interface.h 
b/agent/mibgroup/if-mib/ifTable/ifTable_interface.h
index be2028a..fb0f871 100644
--- a/agent/mibgroup/if-mib/ifTable/ifTable_interface.h
+++ b/agent/mibgroup/if-mib/ifTable/ifTable_interface.h
@@ -89,6 +89,11 @@ extern          "C" {
     void            if_mib_container_init(void);
 
     /*
+     * Invalidate and reload cache.
+     */
+    void            ifTable_cache_reload(void);
+
+    /*
      */
     void            ifTable_lastChange_set(u_long uptime);
 
-- 
1.7.10.4


------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Net-snmp-coders mailing list
Net-snmp-coders@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/net-snmp-coders

Reply via email to