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