blob: 84c181066f93bc3b50a3604df97e4ee858b6033c [file] [log] [blame]
/*
* Interface MIB architecture support
*
* $Id$
*/
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include "mibII/mibII_common.h"
#include <net-snmp/agent/net-snmp-agent-includes.h>
#include <net-snmp/data_access/route.h>
/**---------------------------------------------------------------------*/
/*
* local static prototypes
*/
static void _access_route_entry_release(netsnmp_route_entry * entry, void *unused);
/**---------------------------------------------------------------------*/
/*
* external per-architecture functions prototypes
*
* These shouldn't be called by the general public, so they aren't in
* the header file.
*/
extern int netsnmp_access_route_container_arch_load(netsnmp_container* container,
u_int load_flags);
extern int
netsnmp_arch_route_create(netsnmp_route_entry *entry);
extern int
netsnmp_arch_route_delete(netsnmp_route_entry *entry);
/**---------------------------------------------------------------------*/
/*
* container functions
*/
/**
* @retval NULL error
* @retval !NULL pointer to container
*/
netsnmp_container*
netsnmp_access_route_container_load(netsnmp_container* container, u_int load_flags)
{
int rc;
DEBUGMSGTL(("access:route:container", "load\n"));
if (NULL == container) {
container = netsnmp_container_find("access:_route:fifo");
if (NULL == container) {
snmp_log(LOG_ERR, "no container specified/found for access_route\n");
return NULL;
}
}
container->container_name = strdup("_route");
rc = netsnmp_access_route_container_arch_load(container, load_flags);
if (0 != rc) {
netsnmp_access_route_container_free(container, NETSNMP_ACCESS_ROUTE_FREE_NOFLAGS);
container = NULL;
}
return container;
}
void
netsnmp_access_route_container_free(netsnmp_container *container, u_int free_flags)
{
DEBUGMSGTL(("access:route:container", "free\n"));
if (NULL == container) {
snmp_log(LOG_ERR, "invalid container for netsnmp_access_route_free\n");
return;
}
if(! (free_flags & NETSNMP_ACCESS_ROUTE_FREE_DONT_CLEAR)) {
/*
* free all items.
*/
CONTAINER_CLEAR(container,
(netsnmp_container_obj_func*)_access_route_entry_release,
NULL);
}
if(! (free_flags & NETSNMP_ACCESS_ROUTE_FREE_KEEP_CONTAINER))
CONTAINER_FREE(container);
}
/**---------------------------------------------------------------------*/
/*
* ifentry functions
*/
/** create route entry
*
* @note:
* if you create a route for entry into a container of your own, you
* must set ns_rt_index to a unique index for your container.
*/
netsnmp_route_entry *
netsnmp_access_route_entry_create(void)
{
netsnmp_route_entry *entry = SNMP_MALLOC_TYPEDEF(netsnmp_route_entry);
if(NULL == entry) {
snmp_log(LOG_ERR, "could not allocate route entry\n");
return NULL;
}
entry->oid_index.oids = &entry->ns_rt_index;
entry->oid_index.len = 1;
entry->rt_metric1 = -1;
entry->rt_metric2 = -1;
entry->rt_metric3 = -1;
entry->rt_metric4 = -1;
entry->rt_metric5 = -1;
/** entry->row_status? */
return entry;
}
/**
*/
void
netsnmp_access_route_entry_free(netsnmp_route_entry * entry)
{
if (NULL == entry)
return;
#ifdef USING_IP_FORWARD_MIB_INETCIDRROUTETABLE_INETCIDRROUTETABLE_MODULE
if ((NULL != entry->rt_policy) &&
!(entry->flags & NETSNMP_ACCESS_ROUTE_POLICY_STATIC))
free(entry->rt_policy);
#endif
#ifdef USING_IP_FORWARD_MIB_IPCIDRROUTETABLE_IPCIDRROUTETABLE_MODULE
if (NULL != entry->rt_info)
free(entry->rt_info);
#endif
free(entry);
}
/**
* update underlying data store (kernel) for entry
*
* @retval 0 : success
* @retval -1 : error
*/
int
netsnmp_access_route_entry_set(netsnmp_route_entry * entry)
{
int rc = SNMP_ERR_NOERROR;
if (NULL == entry) {
netsnmp_assert(NULL != entry);
return -1;
}
/*
*
*/
if (entry->flags & NETSNMP_ACCESS_ROUTE_CREATE) {
rc = netsnmp_arch_route_create(entry);
}
else if (entry->flags & NETSNMP_ACCESS_ROUTE_CHANGE) {
/** xxx-rks:9 route change not implemented */
snmp_log(LOG_ERR,"netsnmp_access_route_entry_set change not supported yet\n");
rc = -1;
}
else if (entry->flags & NETSNMP_ACCESS_ROUTE_DELETE) {
rc = netsnmp_arch_route_delete(entry);
}
else {
snmp_log(LOG_ERR,"netsnmp_access_route_entry_set with no mode\n");
netsnmp_assert(!"route_entry_set == unknown mode"); /* always false */
rc = -1;
}
return rc;
}
/**
* copy an route_entry
*
* @retval -1 : error
* @retval 0 : no error
*/
int
netsnmp_access_route_entry_copy(netsnmp_route_entry *lhs,
netsnmp_route_entry *rhs)
{
#if 0 /* no arch stuff in route (yet) */
int rc;
/*
* copy arch stuff. we don't care if it changed
*/
rc = netsnmp_arch_route_entry_copy(lhs,rhs);
if (0 != rc) {
snmp_log(LOG_ERR,"arch route copy failed\n");
return -1;
}
#endif
lhs->if_index = rhs->if_index;
lhs->rt_dest_len = rhs->rt_dest_len;
memcpy(lhs->rt_dest, rhs->rt_dest, rhs->rt_dest_len);
lhs->rt_dest_type = rhs->rt_dest_type;
lhs->rt_nexthop_len = rhs->rt_nexthop_len;
memcpy(lhs->rt_nexthop, rhs->rt_nexthop, rhs->rt_nexthop_len);
lhs->rt_nexthop_type = rhs->rt_nexthop_type;
#ifdef USING_IP_FORWARD_MIB_INETCIDRROUTETABLE_INETCIDRROUTETABLE_MODULE
if (NULL != lhs->rt_policy) {
if (NETSNMP_ACCESS_ROUTE_POLICY_STATIC & lhs->flags)
lhs->rt_policy = NULL;
else {
SNMP_FREE(lhs->rt_policy);
}
}
if (NULL != rhs->rt_policy) {
if ((NETSNMP_ACCESS_ROUTE_POLICY_STATIC & rhs->flags) &&
! (NETSNMP_ACCESS_ROUTE_POLICY_DEEP_COPY & rhs->flags)) {
lhs->rt_policy = rhs->rt_policy;
}
else {
snmp_clone_mem((void **) &lhs->rt_policy, rhs->rt_policy,
rhs->rt_policy_len * sizeof(oid));
}
}
lhs->rt_policy_len = rhs->rt_policy_len;
#endif
lhs->rt_pfx_len = rhs->rt_pfx_len;
lhs->rt_type = rhs->rt_type;
lhs->rt_proto = rhs->rt_proto;
#ifdef USING_IP_FORWARD_MIB_IPCIDRROUTETABLE_IPCIDRROUTETABLE_MODULE
SNMP_FREE(lhs->rt_info);
if (NULL != rhs->rt_info)
snmp_clone_mem((void **) &lhs->rt_info, rhs->rt_info,
rhs->rt_info_len * sizeof(oid));
lhs->rt_info_len = rhs->rt_info_len;
lhs->rt_mask = rhs->rt_mask;
lhs->rt_tos = rhs->rt_tos;
#endif
lhs->rt_age = rhs->rt_age;
lhs->rt_nexthop_as = rhs->rt_nexthop_as;
lhs->rt_metric1 = rhs->rt_metric1;
lhs->rt_metric2 = rhs->rt_metric2;
lhs->rt_metric3 = rhs->rt_metric3;
lhs->rt_metric4 = rhs->rt_metric4;
lhs->rt_metric5 = rhs->rt_metric5;
lhs->flags = rhs->flags;
return 0;
}
/**---------------------------------------------------------------------*/
/*
* Utility routines
*/
/**
*/
void
_access_route_entry_release(netsnmp_route_entry * entry, void *context)
{
netsnmp_access_route_entry_free(entry);
}