net-snmp/Fix-for-Internet-Address-Prefix-Table.patch

877 lines
33 KiB
Diff

From 71ffec9f8c1bcd14a7bf6ca7762bc121ba1efaf1 Mon Sep 17 00:00:00 2001
From: Mitsuru Chinen <mitch@linux.vnet.ibm.com>
Date: Mon, 20 Oct 2008 17:42:57 +0900
Subject: [PATCH] Fix for Internet Address Prefix Table
From net-snmp patch tracker:
[ 1705594 ] ipAddressPrefixTable Fixes
http://sourceforge.net/tracker/index.php?func=detail&aid=1705594&group_id=12694&atid=312694
[ 1902105 ] hide some log messages introduced by patch 1705594
http://sourceforge.net/tracker/index.php?func=detail&aid=1902105&group_id=12694&atid=312694
Signed-off-by: Mitsuru Chinen <mitch@linux.vnet.ibm.com>
---
.../mibgroup/if-mib/data_access/interface_linux.c | 186 ++++++++++++++++++++
.../mibgroup/ip-mib/data_access/ipaddress_common.c | 67 +++++++
.../mibgroup/ip-mib/data_access/ipaddress_linux.c | 144 +++++++++++++++-
.../ipAddressPrefixTable/ipAddressPrefixTable.c | 7 +-
.../ipAddressPrefixTable_constants.h | 14 ++
.../ipAddressPrefixTable_data_access.c | 27 +++-
agent/mibgroup/util_funcs.c | 152 ++++++++++++++++-
agent/mibgroup/util_funcs.h | 41 +++++
include/net-snmp/data_access/ipaddress.h | 19 ++-
9 files changed, 645 insertions(+), 12 deletions(-)
diff --git a/agent/mibgroup/if-mib/data_access/interface_linux.c b/agent/mibgroup/if-mib/data_access/interface_linux.c
index 474a904..294963a 100644
--- a/agent/mibgroup/if-mib/data_access/interface_linux.c
+++ b/agent/mibgroup/if-mib/data_access/interface_linux.c
@@ -29,6 +29,7 @@ typedef __u8 u8; /* ditto */
#include <net-snmp/data_access/interface.h>
#include <net-snmp/data_access/ipaddress.h>
#include "if-mib/data_access/interface.h"
+#include "mibgroup/util_funcs.h"
#include "interface_ioctl.h"
#include <sys/types.h>
@@ -42,6 +43,15 @@ typedef __u8 u8; /* ditto */
#define IF_NAMESIZE 16
#endif
+#ifdef NETSNMP_ENABLE_IPV6
+#if defined(HAVE_PTHREAD_H) && defined(HAVE_LINUX_RTNETLINK_H)
+#include <pthread.h>
+#include <linux/rtnetlink.h>
+#ifdef RTMGRP_IPV6_PREFIX
+#define SUPPORT_PREFIX_FLAGS 1
+#endif /* RTMGRP_IPV6_PREFIX */
+#endif /* HAVE_PTHREAD_H && HAVE_LINUX_RTNETLINK_H */
+#endif /* NETSNMP_ENABLE_IPV6 */
unsigned int
netsnmp_linux_interface_get_if_speed(int fd, const char *name);
#ifdef HAVE_LINUX_ETHTOOL_H
@@ -59,6 +69,16 @@ static unsigned short retrans_time_factor = 1;
#define PROC_SYS_NET_IPVx_BASE_REACHABLE_TIME "/proc/sys/net/ipv%d/neigh/%s/base_reachable_time"
static const char *proc_sys_basereachable_time;
static unsigned short basereachable_time_ms = 0;
+#ifdef SUPPORT_PREFIX_FLAGS
+prefix_cbx *prefix_head_list = NULL;
+pthread_mutex_t prefix_mutex_lock = PTHREAD_MUTEX_INITIALIZER;
+netsnmp_prefix_listen_info list_info;
+pthread_t thread1;
+#define IF_PREFIX_ONLINK 0x01
+#define IF_PREFIX_AUTOCONF 0x02
+
+void *netsnmp_prefix_listen(netsnmp_prefix_listen_info *listen_info);
+#endif
void
netsnmp_arch_interface_init(void)
{
@@ -91,6 +111,13 @@ netsnmp_arch_interface_init(void)
else {
proc_sys_basereachable_time = PROC_SYS_NET_IPVx_BASE_REACHABLE_TIME;
}
+#ifdef SUPPORT_PREFIX_FLAGS
+ list_info.list_head = &prefix_head_list;
+ list_info.lockinfo = &prefix_mutex_lock;
+
+ if(pthread_create(&thread1, NULL, netsnmp_prefix_listen, &list_info) < 0)
+ snmp_log(LOG_ERR,"Unable to create thread\n");
+#endif
}
/*
@@ -885,3 +912,162 @@ netsnmp_linux_interface_get_if_speed(int fd, const char *name)
}
return retspeed;
}
+#ifdef SUPPORT_PREFIX_FLAGS
+void *netsnmp_prefix_listen(netsnmp_prefix_listen_info *listen_info)
+{
+ struct {
+ struct nlmsghdr n;
+ struct ifinfomsg r;
+ char buf[1024];
+ } req;
+
+ struct rtattr *rta;
+ int status;
+ char buf[16384];
+ struct nlmsghdr *nlmp;
+ struct rtattr *rtatp;
+ struct in6_addr *in6p;
+ struct sockaddr_nl localaddrinfo;
+ struct ifaddrmsg *ifa;
+ struct prefixmsg *prefix;
+ unsigned groups = 0;
+ struct rtattr *index_table[IFA_MAX+1];
+ char in6pAddr[40];
+ int flag1 = 0,flag2 = 0;
+ int onlink = 2,autonomous = 2; /*Assume as false*/
+ prefix_cbx *new;
+ int iret;
+ int len, req_len, length;
+ int fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
+
+
+ memset(&localaddrinfo, 0, sizeof(struct sockaddr_nl));
+ memset(&in6pAddr, '\0', sizeof(in6pAddr));
+
+ groups |= RTMGRP_IPV6_IFADDR;
+ groups |= RTMGRP_IPV6_PREFIX;
+ localaddrinfo.nl_family = AF_NETLINK;
+ localaddrinfo.nl_groups = groups;
+
+ if (bind(fd, (struct sockaddr*)&localaddrinfo, sizeof(localaddrinfo)) < 0) {
+ snmp_log(LOG_ERR,"netsnmp_prefix_listen: Bind failed. Exiting thread.\n");
+ exit(0);
+ }
+
+ memset(&req, 0, sizeof(req));
+ req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifinfomsg));
+ req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT;
+ req.n.nlmsg_type = RTM_GETLINK;
+ req.r.ifi_family = AF_INET6;
+ rta = (struct rtattr *)(((char *)&req) + NLMSG_ALIGN(req.n.nlmsg_len));
+ rta->rta_len = RTA_LENGTH(16);
+
+ status = send(fd, &req, req.n.nlmsg_len, 0);
+ if (status < 0) {
+ snmp_log(LOG_ERR,"netsnmp_prefix_listen: Send failed. Exiting thread\n");
+ exit(0);
+ }
+
+ while(1) {
+ status = recv(fd, buf, sizeof(buf), 0);
+ if (status < 0) {
+ snmp_log(LOG_ERR,"netsnmp_prefix_listen: Recieve failed. Exiting thread\n");
+ exit(0);
+ }
+
+ if(status == 0){
+ DEBUGMSGTL(("access:interface:prefix", "End of File\n"));
+ continue;
+ }
+
+ for(nlmp = (struct nlmsghdr *)buf; status > sizeof(*nlmp);){
+ len = nlmp->nlmsg_len;
+ req_len = len - sizeof(*nlmp);
+
+ if (req_len < 0 || len > status) {
+ snmp_log(LOG_ERR,"netsnmp_prefix_listen: Error in length. Exiting thread\n");
+ exit(0);
+ }
+
+ if (!NLMSG_OK(nlmp, status)) {
+ DEBUGMSGTL(("access:interface:prefix", "NLMSG not OK\n"));
+ continue;
+ }
+
+ if (nlmp->nlmsg_type == RTM_NEWADDR || nlmp->nlmsg_type == RTM_DELADDR) {
+ ifa = NLMSG_DATA(nlmp);
+ length = nlmp->nlmsg_len;
+ length -= NLMSG_LENGTH(sizeof(*ifa));
+
+ if (length < 0) {
+ DEBUGMSGTL(("access:interface:prefix", "wrong nlmsg length %d\n", length));
+ continue;
+ }
+ memset(index_table, 0, sizeof(struct rtattr *) * (IFA_MAX + 1));
+ if(!ifa->ifa_flags) {
+ rtatp = IFA_RTA(ifa);
+ while (RTA_OK(rtatp, length)) {
+ if (rtatp->rta_type <= IFA_MAX)
+ index_table[rtatp->rta_type] = rtatp;
+ rtatp = RTA_NEXT(rtatp,length);
+ }
+ if (index_table[IFA_ADDRESS]) {
+ in6p = (struct in6_addr *)RTA_DATA(index_table[IFA_ADDRESS]);
+ if(nlmp->nlmsg_type == RTM_DELADDR) {
+ sprintf(in6pAddr, "%04x%04x%04x%04x%04x%04x%04x%04x", NIP6(*in6p));
+ flag1 = -1;
+ } else {
+ sprintf(in6pAddr, "%04x%04x%04x%04x%04x%04x%04x%04x", NIP6(*in6p));
+ flag1 = 1;
+ }
+
+ }
+ }
+ }
+
+ if(nlmp->nlmsg_type == RTM_NEWPREFIX) {
+ prefix = NLMSG_DATA(nlmp);
+ length = nlmp->nlmsg_len;
+ length -= NLMSG_LENGTH(sizeof(*prefix));
+
+ if (length < 0) {
+ DEBUGMSGTL(("access:interface:prefix", "wrong nlmsg length %d\n", length));
+ continue;
+ }
+ flag2 = 1;
+ if (prefix->prefix_flags & IF_PREFIX_ONLINK)
+ onlink = 1;
+ if (prefix->prefix_flags & IF_PREFIX_AUTOCONF)
+ autonomous = 1;
+ }
+ status -= NLMSG_ALIGN(len);
+ nlmp = (struct nlmsghdr*)((char*)nlmp + NLMSG_ALIGN(len));
+ }
+ if((flag1 == 1) && (flag2 == 1)){
+ if(!(new = net_snmp_create_prefix_info (onlink, autonomous, in6pAddr)))
+ DEBUGMSGTL(("access:interface:prefix", "Unable to create prefix info\n"));
+ else {
+ iret = net_snmp_update_prefix_info (listen_info->list_head, new, listen_info->lockinfo);
+ if(iret < 0) {
+ DEBUGMSGTL(("access:interface:prefix", "Unable to add/update prefix info\n"));
+ free(new);
+ }
+ if(iret == 2) /*Only when enrty already exists and we are only updating*/
+ free(new);
+ }
+ flag1 = flag2 = 0;
+ onlink = autonomous = 2; /*Set to defaults again*/
+ } else if (flag1 == -1) {
+ iret = net_snmp_delete_prefix_info (listen_info->list_head, in6pAddr, listen_info->lockinfo);
+ if(iret < 0)
+ DEBUGMSGTL(("access:interface:prefix", "Unable to delete the prefix info\n"));
+ if(!iret)
+ DEBUGMSGTL(("access:interface:prefix", "Unable to find the node to delete\n"));
+ flag1 = 0;
+ }
+ }
+
+}
+#endif
+
+
diff --git a/agent/mibgroup/ip-mib/data_access/ipaddress_common.c b/agent/mibgroup/ip-mib/data_access/ipaddress_common.c
index 396fc96..3eef0cc 100644
--- a/agent/mibgroup/ip-mib/data_access/ipaddress_common.c
+++ b/agent/mibgroup/ip-mib/data_access/ipaddress_common.c
@@ -304,6 +304,27 @@ netsnmp_access_ipaddress_entry_update(netsnmp_ipaddress_entry *lhs,
++changed;
lhs->ia_origin = rhs->ia_origin;
}
+
+ if (lhs->ia_onlink_flag != rhs->ia_onlink_flag) {
+ ++changed;
+ lhs->ia_onlink_flag = rhs->ia_onlink_flag;
+ }
+
+ if (lhs->ia_autonomous_flag != rhs->ia_autonomous_flag) {
+ ++changed;
+ lhs->ia_autonomous_flag = rhs->ia_autonomous_flag;
+ }
+
+ if (lhs->ia_prefered_lifetime != rhs->ia_prefered_lifetime) {
+ ++changed;
+ lhs->ia_prefered_lifetime = rhs->ia_prefered_lifetime;
+ }
+
+ if (lhs->ia_valid_lifetime != rhs->ia_valid_lifetime) {
+ ++changed;
+ lhs->ia_valid_lifetime = rhs->ia_valid_lifetime;
+ }
+
return changed;
}
@@ -428,3 +449,49 @@ static int _access_ipaddress_entry_compare_addr(const void *lhs,
*/
return memcmp(lh->ia_address, rh->ia_address, lh->ia_address_len);
}
+
+int
+netsnmp_ipaddress_flags_copy(u_long *ipAddressPrefixAdvPreferredLifetime,
+ u_long *ipAddressPrefixAdvValidLifetime,
+ u_long *ipAddressPrefixOnLinkFlag,
+ u_long *ipAddressPrefixAutonomousFlag,
+ u_long *ia_prefered_lifetime,
+ u_long *ia_valid_lifetime,
+ u_char *ia_onlink_flag,
+ u_char *ia_autonomous_flag)
+{
+
+ /*Copy all the flags*/
+ *ipAddressPrefixAdvPreferredLifetime = *ia_prefered_lifetime;
+ *ipAddressPrefixAdvValidLifetime = *ia_valid_lifetime;
+ *ipAddressPrefixOnLinkFlag = *ia_onlink_flag;
+ *ipAddressPrefixAutonomousFlag = *ia_autonomous_flag;
+ return 0;
+}
+
+int
+netsnmp_ipaddress_prefix_origin_copy(u_long *ipAddressPrefixOrigin,
+ u_char ia_origin,
+ int flags,
+ u_long ipAddressAddrType)
+{
+ if(ipAddressAddrType == INETADDRESSTYPE_IPV4){
+ if(ia_origin == 6) /*Random*/
+ (*ipAddressPrefixOrigin) = 3 /*IPADDRESSPREFIXORIGINTC_WELLKNOWN*/;
+ else
+ (*ipAddressPrefixOrigin) = ia_origin;
+ } else {
+ if(ia_origin == 5) { /*Link Layer*/
+ if(!flags) /*Global address assigned by router adv*/
+ (*ipAddressPrefixOrigin) = 5 /*IPADDRESSPREFIXORIGINTC_ROUTERADV*/;
+ else
+ (*ipAddressPrefixOrigin) = 3 /*IPADDRESSPREFIXORIGINTC_WELLKNOWN*/;
+ }
+ else if(ia_origin == 6) /*Random*/
+ (*ipAddressPrefixOrigin) = 5 /*IPADDRESSPREFIXORIGINTC_ROUTERADV*/;
+ else
+ (*ipAddressPrefixOrigin) = ia_origin;
+ }
+ return 0;
+}
+
diff --git a/agent/mibgroup/ip-mib/data_access/ipaddress_linux.c b/agent/mibgroup/ip-mib/data_access/ipaddress_linux.c
index 4616649..c6e5fec 100644
--- a/agent/mibgroup/ip-mib/data_access/ipaddress_linux.c
+++ b/agent/mibgroup/ip-mib/data_access/ipaddress_linux.c
@@ -12,6 +12,8 @@
#include <net-snmp/data_access/interface.h>
#include "ip-mib/ipAddressTable/ipAddressTable_constants.h"
+#include "ip-mib/ipAddressPrefixTable/ipAddressPrefixTable_constants.h"
+#include "mibgroup/util_funcs.h"
#include <errno.h>
#include <sys/ioctl.h>
@@ -19,15 +21,29 @@
#if defined (NETSNMP_ENABLE_IPV6)
#include <linux/types.h>
#include <asm/types.h>
-#ifdef HAVE_LINUX_RTNETLINK_H
+#if defined(HAVE_PTHREAD_H) && defined(HAVE_LINUX_RTNETLINK_H)
#include <linux/netlink.h>
+#include <pthread.h>
#include <linux/rtnetlink.h>
-#endif
+#ifdef RTMGRP_IPV6_PREFIX
+#define SUPPORT_PREFIX_FLAGS 1
+#endif /* RTMGRP_IPV6_PREFIX */
+#endif /* HAVE_PTHREAD_H && HAVE_LINUX_RTNETLINK_H */
#endif
#include "ipaddress_ioctl.h"
-
+#ifdef SUPPORT_PREFIX_FLAGS
+extern prefix_cbx *prefix_head_list;
+extern pthread_mutex_t prefix_mutex_lock;
+#endif
int _load_v6(netsnmp_container *container, int idx_offset);
+#ifdef HAVE_LINUX_RTNETLINK_H
+int
+netsnmp_access_ipaddress_extra_prefix_info(int index,
+ u_long *preferedlt,
+ ulong *validlt,
+ char *addr);
+#endif
/*
* initialize arch specific storage
@@ -194,6 +210,7 @@ _load_v6(netsnmp_container *container, int idx_offset)
u_char *buf;
int if_index, pfx_len, scope, flags, rc = 0;
size_t in_len, out_len;
+ prefix_cbx prefix_val;
netsnmp_ipaddress_entry *entry;
_ioctl_extras *extras;
static int log_open_err = 1;
@@ -251,6 +268,7 @@ _load_v6(netsnmp_container *container, int idx_offset)
in_len = entry->ia_address_len = sizeof(entry->ia_address);
netsnmp_assert(16 == in_len);
out_len = 0;
+ entry->flags = flags;
buf = entry->ia_address;
if(1 != netsnmp_hex_to_binary(&buf, &in_len,
&out_len, 0, addr, ":")) {
@@ -341,6 +359,30 @@ _load_v6(netsnmp_container *container, int idx_offset)
entry->ia_storagetype = STORAGETYPE_PERMANENT;
/* xxx-rks: what can we do with scope? */
+#ifdef HAVE_LINUX_RTNETLINK_H
+ if(netsnmp_access_ipaddress_extra_prefix_info(entry->if_index, &entry->ia_prefered_lifetime
+ ,&entry->ia_valid_lifetime, addr) < 0){
+ DEBUGMSGTL(("access:ipaddress:container", "unable to fetch extra prefix info\n"));
+ }
+#else
+ entry->ia_prefered_lifetime = 0;
+ entry->ia_valid_lifetime = 0;
+#endif
+#ifdef SUPPORT_PREFIX_FLAGS
+ memset(&prefix_val, 0, sizeof(prefix_cbx));
+ if(net_snmp_find_prefix_info(&prefix_head_list, addr, &prefix_val, &prefix_mutex_lock) < 0) {
+ DEBUGMSGTL(("access:ipaddress:container", "unable to find info\n"));
+ entry->ia_onlink_flag = 1; /*Set by default as true*/
+ entry->ia_autonomous_flag = 2; /*Set by default as false*/
+
+ } else {
+ entry->ia_onlink_flag = prefix_val.ipAddressPrefixOnLinkFlag;
+ entry->ia_autonomous_flag = prefix_val.ipAddressPrefixAutonomousFlag;
+ }
+#else
+ entry->ia_onlink_flag = 1; /*Set by default as true*/
+ entry->ia_autonomous_flag = 2; /*Set by default as false*/
+#endif
/*
* add entry to container
@@ -448,4 +490,100 @@ netsnmp_access_other_info_get(int index, int family)
return addr;
#endif
}
+
+#ifdef HAVE_LINUX_RTNETLINK_H
+int
+netsnmp_access_ipaddress_extra_prefix_info(int index, u_long *preferedlt,
+ ulong *validlt, char *addr)
+{
+
+ struct {
+ struct nlmsghdr nlhdr;
+ struct ifaddrmsg ifaceinfo;
+ char buf[1024];
+ } req;
+
+ struct rtattr *rta;
+ int status;
+ char buf[16384];
+ char tmpaddr[40];
+ struct nlmsghdr *nlmp;
+ struct ifaddrmsg *rtmp;
+ struct rtattr *rtatp;
+ struct ifa_cacheinfo *cache_info;
+ struct in6_addr *in6p;
+ int rtattrlen;
+ int sd;
+ int reqaddr = 0;
+ sd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
+ if(sd < 0) {
+ snmp_log(LOG_ERR, "could not open netlink socket\n");
+ return -1;
+ }
+ memset(&req, 0, sizeof(req));
+ req.nlhdr.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg));
+ req.nlhdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_ROOT;
+ req.nlhdr.nlmsg_type = RTM_GETADDR;
+ req.ifaceinfo.ifa_family = AF_INET6;
+ rta = (struct rtattr *)(((char *)&req) + NLMSG_ALIGN(req.nlhdr.nlmsg_len));
+ rta->rta_len = RTA_LENGTH(16); /*For ipv6*/
+
+ status = send (sd, &req, req.nlhdr.nlmsg_len, 0);
+ if (status < 0) {
+ snmp_log(LOG_ERR, "could not send netlink request\n");
+ return -1;
+ }
+ status = recv (sd, buf, sizeof(buf), 0);
+ if (status < 0) {
+ snmp_log (LOG_ERR, "could not recieve netlink request\n");
+ return -1;
+ }
+ if (status == 0) {
+ snmp_log (LOG_ERR, "nothing to read\n");
+ return -1;
+ }
+ for (nlmp = (struct nlmsghdr *)buf; status > sizeof(*nlmp); ){
+
+ int len = nlmp->nlmsg_len;
+ int req_len = len - sizeof(*nlmp);
+
+ if (req_len < 0 || len > status) {
+ snmp_log (LOG_ERR, "invalid netlink message\n");
+ return -1;
+ }
+
+ if (!NLMSG_OK (nlmp, status)) {
+ snmp_log (LOG_ERR, "invalid NLMSG message\n");
+ return -1;
+ }
+ rtmp = (struct ifaddrmsg *)NLMSG_DATA(nlmp);
+ rtatp = (struct rtattr *)IFA_RTA(rtmp);
+ rtattrlen = IFA_PAYLOAD(nlmp);
+ if(index == rtmp->ifa_index) {
+ for (; RTA_OK(rtatp, rtattrlen); rtatp = RTA_NEXT(rtatp, rtattrlen)) {
+ if(rtatp->rta_type == IFA_ADDRESS) {
+ in6p = (struct in6_addr *)RTA_DATA(rtatp);
+ sprintf(tmpaddr, "%04x%04x%04x%04x%04x%04x%04x%04x", NIP6(*in6p));
+ if(!strcmp(tmpaddr ,addr))
+ reqaddr = 1;
+ }
+ if(rtatp->rta_type == IFA_CACHEINFO) {
+ cache_info = (struct ifa_cacheinfo *)RTA_DATA(rtatp);
+ if(reqaddr) {
+ reqaddr = 0;
+ *validlt = cache_info->ifa_valid;
+ *preferedlt = cache_info->ifa_prefered;
+ }
+
+ }
+
+ }
+ }
+ status -= NLMSG_ALIGN(len);
+ nlmp = (struct nlmsghdr*)((char*)nlmp + NLMSG_ALIGN(len));
+ }
+ close(sd);
+ return 0;
+}
+#endif
#endif
diff --git a/agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable.c b/agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable.c
index ecd26a0..9188f93 100644
--- a/agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable.c
+++ b/agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable.c
@@ -392,10 +392,9 @@ ipAddressPrefixOrigin_get(ipAddressPrefixTable_rowreq_ctx * rowreq_ctx,
* TODO:231:o: |-> Extract the current value of the ipAddressPrefixOrigin data.
* copy (* ipAddressPrefixOrigin_val_ptr ) from rowreq_ctx->data
*/
- (*ipAddressPrefixOrigin_val_ptr) =
- rowreq_ctx->data.ipAddressPrefixOrigin;
-
- return MFD_SUCCESS;
+ (*ipAddressPrefixOrigin_val_ptr) = rowreq_ctx->data.ipAddressPrefixOrigin;
+
+ return MFD_SUCCESS;
} /* ipAddressPrefixOrigin_get */
/*---------------------------------------------------------------------
diff --git a/agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable_constants.h b/agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable_constants.h
index d9c0cb0..6dd440d 100644
--- a/agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable_constants.h
+++ b/agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable_constants.h
@@ -137,3 +137,17 @@ extern "C" {
}
#endif
#endif /* IPADDRESSPREFIXTABLE_OIDS_H */
+/****************************************************************
+* Additional constants and definitions for common implementation
+*/
+#define INFINITY_LIFE_TIME 0xFFFFFFFFU
+#define NIP6(addr) \
+ ntohs((addr).s6_addr16[0]), \
+ ntohs((addr).s6_addr16[1]), \
+ ntohs((addr).s6_addr16[2]), \
+ ntohs((addr).s6_addr16[3]), \
+ ntohs((addr).s6_addr16[4]), \
+ ntohs((addr).s6_addr16[5]), \
+ ntohs((addr).s6_addr16[6]), \
+ ntohs((addr).s6_addr16[7])
+
diff --git a/agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable_data_access.c b/agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable_data_access.c
index 4cda4de..9e0b5fe 100644
--- a/agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable_data_access.c
+++ b/agent/mibgroup/ip-mib/ipAddressPrefixTable/ipAddressPrefixTable_data_access.c
@@ -251,6 +251,23 @@ ipAddressPrefixTable_container_load(netsnmp_container *container)
ia_address_len,
addr_rowreq_ctx->data->
ia_prefix_len);
+ netsnmp_ipaddress_flags_copy(&rowreq_ctx->data.
+ ipAddressPrefixAdvPreferredLifetime,
+ &rowreq_ctx->data.
+ ipAddressPrefixAdvValidLifetime,
+ &rowreq_ctx->data.
+ ipAddressPrefixOnLinkFlag,
+ &rowreq_ctx->data.
+ ipAddressPrefixAutonomousFlag,
+ &addr_rowreq_ctx->data->
+ ia_prefered_lifetime,
+ &addr_rowreq_ctx->data->
+ ia_valid_lifetime,
+ &addr_rowreq_ctx->data->
+ ia_onlink_flag,
+ &addr_rowreq_ctx->data->
+ ia_autonomous_flag);
+
if (MFD_SUCCESS !=
ipAddressPrefixTable_indexes_set(rowreq_ctx,
addr_rowreq_ctx->data->
@@ -277,8 +294,14 @@ ipAddressPrefixTable_container_load(netsnmp_container *container)
* TODO:352:r: | |-> populate ipAddressPrefixTable data context.
* Populate data context here. (optionally, delay until row prep)
*/
- rowreq_ctx->data.ipAddressPrefixOrigin =
- addr_rowreq_ctx->data->ia_origin;
+ netsnmp_ipaddress_prefix_origin_copy(&rowreq_ctx->data.
+ ipAddressPrefixOrigin,
+ addr_rowreq_ctx->data->
+ ia_origin,
+ addr_rowreq_ctx->data->
+ flags,
+ addr_rowreq_ctx->tbl_idx.
+ ipAddressAddrType);
/** defer the rest til row prep */
diff --git a/agent/mibgroup/util_funcs.c b/agent/mibgroup/util_funcs.c
index 26826f7..d060721 100644
--- a/agent/mibgroup/util_funcs.c
+++ b/agent/mibgroup/util_funcs.c
@@ -100,7 +100,9 @@
# include <ndir.h>
# endif
#endif
-
+#ifdef HAVE_PTHREAD_H
+#include <pthread.h>
+#endif
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>
@@ -1292,3 +1294,151 @@ get_pid_from_inode(unsigned long long inode)
}
#endif /* #ifdef linux */
+
+#if defined(HAVE_PTHREAD_H)
+prefix_cbx *net_snmp_create_prefix_info(unsigned long OnLinkFlag,
+ unsigned long AutonomousFlag,
+ char *in6ptr)
+{
+ prefix_cbx *node = SNMP_MALLOC_TYPEDEF(prefix_cbx);
+ if(!in6ptr) {
+ free(node);
+ return NULL;
+ }
+ if(!node) {
+ free(node);
+ return NULL;
+ }
+ node->next_info = NULL;
+ node->ipAddressPrefixOnLinkFlag = OnLinkFlag;
+ node->ipAddressPrefixAutonomousFlag = AutonomousFlag;
+ memcpy(node->in6p, in6ptr, sizeof(node->in6p));
+
+ return node;
+}
+
+int net_snmp_find_prefix_info(prefix_cbx **head,
+ char *address,
+ prefix_cbx *node_to_find,
+ pthread_mutex_t *lockid)
+{
+ int iret;
+ memset(node_to_find, 0, sizeof(prefix_cbx));
+ if(!*head)
+ return -1;
+ memcpy(node_to_find->in6p, address, sizeof(node_to_find->in6p));
+
+ iret = net_snmp_search_update_prefix_info(head, node_to_find, 1, lockid);
+ if(iret < 0) {
+ DEBUGMSGTL(("util_funcs:prefix", "Unable to search the list\n"));
+ return -1;
+ } else if (!iret) {
+ DEBUGMSGTL(("util_funcs:prefix", "Could not find prefix info\n"));
+ return -1;
+ } else
+ return 0;
+}
+
+int net_snmp_update_prefix_info(prefix_cbx **head,
+ prefix_cbx *node_to_update,
+ pthread_mutex_t *lockid)
+{
+ int iret;
+ iret = net_snmp_search_update_prefix_info(head, node_to_update, 0, lockid);
+ if(iret < 0) {
+ DEBUGMSGTL(("util_funcs:prefix", "Unable to update prefix info\n"));
+ return -1;
+ } else if (!iret) {
+ DEBUGMSGTL(("util_funcs:prefix", "Unable to find the node to update\n"));
+ return -1;
+ } else
+ return 0;
+}
+
+int net_snmp_search_update_prefix_info(prefix_cbx **head,
+ prefix_cbx *node_to_use,
+ int functionality,
+ pthread_mutex_t *lockid)
+{
+
+ /* We define functionality based on need *
+ * 0 - Need to do a search and update. We have to provide the node_to_use structure filled fully *
+ * 1 - Need to do only search. Provide the node_to_use with in6p value filled */
+
+ prefix_cbx *temp_node;
+ netsnmp_assert(NULL != head);
+ netsnmp_assert(NULL != node_to_use);
+
+ if(functionality > 1)
+ return -1;
+ if(!node_to_use)
+ return -1;
+
+
+ if (!functionality) {
+ if (!*head) {
+ *head = node_to_use;
+ return 1;
+ }
+
+ pthread_mutex_lock( lockid );
+ for (temp_node = *head; temp_node->next_info != NULL ; temp_node = temp_node->next_info) {
+ if (0 == strcmp(temp_node->in6p, node_to_use->in6p)) {
+ temp_node->ipAddressPrefixOnLinkFlag = node_to_use->ipAddressPrefixOnLinkFlag;
+ temp_node->ipAddressPrefixAutonomousFlag = node_to_use->ipAddressPrefixAutonomousFlag;
+ pthread_mutex_unlock( lockid );
+ return 2;
+ }
+ }
+ temp_node->next_info = node_to_use;
+ pthread_mutex_unlock( lockid );
+ return 1;
+ } else {
+ pthread_mutex_lock( lockid );
+ for (temp_node = *head; temp_node != NULL ; temp_node = temp_node->next_info) {
+ if (0 == strcmp(temp_node->in6p, node_to_use->in6p)) {
+ /*need yo put sem here as i read here */
+ node_to_use->ipAddressPrefixOnLinkFlag = temp_node->ipAddressPrefixOnLinkFlag;
+ node_to_use->ipAddressPrefixAutonomousFlag = temp_node->ipAddressPrefixAutonomousFlag;
+ pthread_mutex_unlock( lockid );
+ return 1;
+ }
+ }
+ pthread_mutex_unlock( lockid );
+ return 0;
+ }
+}
+
+int net_snmp_delete_prefix_info(prefix_cbx **head,
+ char *address,
+ pthread_mutex_t *lockid)
+{
+
+ prefix_cbx *temp_node,*prev_node;
+ if(!address)
+ return -1;
+ if(!head)
+ return -1;
+
+ /*Need to acquire lock here */
+ pthread_mutex_lock( lockid );
+ for (temp_node = *head, prev_node = NULL; temp_node;
+ prev_node = temp_node, temp_node = temp_node->next_info) {
+
+ if (temp_node->in6p && strcmp(temp_node->in6p, address) == 0) {
+ if (prev_node)
+ prev_node->next_info = temp_node->next_info;
+ else
+ *head = temp_node->next_info;
+ free(temp_node);
+ pthread_mutex_unlock( lockid );
+ return 1;
+ }
+
+ }
+ /*Release Lock here */
+ pthread_mutex_unlock( lockid );
+ return 0;
+}
+#endif
+
diff --git a/agent/mibgroup/util_funcs.h b/agent/mibgroup/util_funcs.h
index 4a0b99e..aa4257f 100644
--- a/agent/mibgroup/util_funcs.h
+++ b/agent/mibgroup/util_funcs.h
@@ -8,8 +8,23 @@
extern "C" {
#endif
+#ifdef HAVE_PTHREAD_H
+#include <pthread.h>
+#endif
#include "struct.h"
+typedef struct prefix_info
+{
+ struct prefix_info *next_info;
+ unsigned long ipAddressPrefixOnLinkFlag;
+ unsigned long ipAddressPrefixAutonomousFlag;
+ char in6p[40];
+}prefix_cbx;
+typedef struct
+{
+ prefix_cbx **list_head;
+ pthread_mutex_t *lockinfo;
+}netsnmp_prefix_listen_info;
void Exit(int);
int shell_command(struct extensible *);
int exec_command(struct extensible *);
@@ -37,6 +52,32 @@ const char *make_tempfile(void);
#ifdef linux
unsigned int get_pid_from_inode(unsigned long long);
#endif
+prefix_cbx *net_snmp_create_prefix_info(unsigned long OnLinkFlag,
+ unsigned long AutonomousFlag,
+ char *in6ptr);
+int net_snmp_find_prefix_info(prefix_cbx **head,
+ char *address,
+ prefix_cbx *node_to_find,
+ pthread_mutex_t *lockid);
+int net_snmp_update_prefix_info(prefix_cbx **head,
+ prefix_cbx *node_to_update,
+ pthread_mutex_t *lockid);
+int net_snmp_search_update_prefix_info(prefix_cbx **head,
+ prefix_cbx *node_to_use,
+ int functionality,
+ pthread_mutex_t *lockid);
+int net_snmp_delete_prefix_info(prefix_cbx **head,
+ char *address,
+ pthread_mutex_t *lockid);
+#define NIP6(addr) \
+ ntohs((addr).s6_addr16[0]), \
+ ntohs((addr).s6_addr16[1]), \
+ ntohs((addr).s6_addr16[2]), \
+ ntohs((addr).s6_addr16[3]), \
+ ntohs((addr).s6_addr16[4]), \
+ ntohs((addr).s6_addr16[5]), \
+ ntohs((addr).s6_addr16[6]), \
+ ntohs((addr).s6_addr16[7])
#define satosin(x) ((struct sockaddr_in *) &(x))
#define SOCKADDR(x) (satosin(x)->sin_addr.s_addr)
diff --git a/include/net-snmp/data_access/ipaddress.h b/include/net-snmp/data_access/ipaddress.h
index b751b47..37083be 100644
--- a/include/net-snmp/data_access/ipaddress.h
+++ b/include/net-snmp/data_access/ipaddress.h
@@ -47,7 +47,10 @@ typedef struct netsnmp_ipaddress_s {
u_char ia_status; /* IpAddressStatus (1-7) */
u_char ia_origin; /* IpAddressOrigin (1-6) */
u_char ia_storagetype; /* IpAddressStorageType (1-5) */
-
+ u_char ia_onlink_flag; /* IpOnlinkFlag */
+ u_char ia_autonomous_flag; /*IpAutonomousFlag */
+ u_long ia_prefered_lifetime;/*IpPreferedLifeTime*/
+ u_long ia_valid_lifetime;/*IpValidLifeTime*/
netsnmp_data_list *arch_data; /* arch specific data */
} netsnmp_ipaddress_entry;
@@ -142,7 +145,19 @@ int netsnmp_ipaddress_prefix_copy(u_char *dst, u_char *src,
int netsnmp_ipaddress_ipv4_prefix_len(in_addr_t mask);
-
+int netsnmp_ipaddress_flags_copy(u_long *ipAddressPrefixAdvPreferredLifetime,
+ u_long *ipAddressPrefixAdvValidLifetime,
+ u_long *ipAddressPrefixOnLinkFlag,
+ u_long *ipAddressPrefixAutonomousFlag,
+ u_long *ia_prefered_lifetime,
+ u_long *ia_valid_lifetime,
+ u_char *ia_onlink_flag,
+ u_char *ia_autonomous_flag);
+
+int netsnmp_ipaddress_prefix_origin_copy(u_long *ipAddressPrefixOrigin,
+ u_char ia_origin,
+ int flags,
+ u_long ipAddressAddrType);
/**---------------------------------------------------------------------*/
--
1.6.0.2