/*
 * Note: this file originally auto-generated by mib2c using
 *       version : 1.67 $ of : mfd-interface.m2c,v $ 
 *
 * $Id$
 */
/*
 * *********************************************************************
 * *********************************************************************
 * *********************************************************************
 * ***                                                               ***
 * ***  NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE NOTE  ***
 * ***                                                               ***
 * ***                                                               ***
 * ***       THIS FILE DOES NOT CONTAIN ANY USER EDITABLE CODE.      ***
 * ***                                                               ***
 * ***                                                               ***
 * ***       THE GENERATED CODE IS INTERNAL IMPLEMENTATION, AND      ***
 * ***                                                               ***
 * ***                                                               ***
 * ***    IS SUBJECT TO CHANGE WITHOUT WARNING IN FUTURE RELEASES.   ***
 * ***                                                               ***
 * ***                                                               ***
 * *********************************************************************
 * *********************************************************************
 * *********************************************************************
 */

/*
 * standard Net-SNMP includes 
 */
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-features.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>

/*
 * include our parent header 
 */
#include "inetCidrRouteTable.h"


#include <net-snmp/agent/table_container.h>
#include <net-snmp/library/container.h>

#include "inetCidrRouteTable_interface.h"

#include <ctype.h>

netsnmp_feature_child_of(inetCidrRouteTable_external_access, libnetsnmpmibs)
netsnmp_feature_require(row_merge)
netsnmp_feature_require(baby_steps)
netsnmp_feature_require(table_container_row_insert)
netsnmp_feature_require(check_all_requests_error)

netsnmp_feature_child_of(inetCidrRouteTable_container_size, inetCidrRouteTable_external_access)
netsnmp_feature_child_of(inetCidrRouteTable_registration_set, inetCidrRouteTable_external_access)
netsnmp_feature_child_of(inetCidrRouteTable_registration_get, inetCidrRouteTable_external_access)
netsnmp_feature_child_of(inetCidrRouteTable_container_get, inetCidrRouteTable_external_access)
/**********************************************************************
 **********************************************************************
 ***
 *** Table inetCidrRouteTable
 ***
 **********************************************************************
 **********************************************************************/
/*
 * IP-FORWARD-MIB::inetCidrRouteTable is subid 7 of ipForward.
 * Its status is Current.
 * OID: .1.3.6.1.2.1.4.24.7, length: 9
 */
typedef struct inetCidrRouteTable_interface_ctx_s {

    netsnmp_container *container;
    netsnmp_cache  *cache;

    inetCidrRouteTable_registration *user_ctx;

    netsnmp_table_registration_info tbl_info;

    netsnmp_baby_steps_access_methods access_multiplexer;

    u_int           table_dirty;

} inetCidrRouteTable_interface_ctx;

static inetCidrRouteTable_interface_ctx inetCidrRouteTable_if_ctx;

static void
                _inetCidrRouteTable_container_init(inetCidrRouteTable_interface_ctx *
                                                   if_ctx);
static void
                _inetCidrRouteTable_container_shutdown(inetCidrRouteTable_interface_ctx *
                                                       if_ctx);

#ifndef NETSNMP_FEATURE_REMOVE_INETCIDRROUTETABLE_CONTAINER_GET
netsnmp_container *
inetCidrRouteTable_container_get(void)
{
    return inetCidrRouteTable_if_ctx.container;
}
#endif /* NETSNMP_FEATURE_REMOVE_INETCIDRROUTETABLE_CONTAINER_GET */

#ifndef NETSNMP_FEATURE_REMOVE_INETCIDRROUTETABLE_REGISTRATION_GET
inetCidrRouteTable_registration *
inetCidrRouteTable_registration_get(void)
{
    return inetCidrRouteTable_if_ctx.user_ctx;
}
#endif /* NETSNMP_FEATURE_REMOVE_INETCIDRROUTETABLE_REGISTRATION_GET */

#ifndef NETSNMP_FEATURE_REMOVE_INETCIDRROUTETABLE_REGISTRATION_SET
inetCidrRouteTable_registration *
inetCidrRouteTable_registration_set(inetCidrRouteTable_registration *
                                    newreg)
{
    inetCidrRouteTable_registration *old =
        inetCidrRouteTable_if_ctx.user_ctx;
    inetCidrRouteTable_if_ctx.user_ctx = newreg;
    return old;
}
#endif /* NETSNMP_FEATURE_REMOVE_INETCIDRROUTETABLE_REGISTRATION_SET */

#ifndef NETSNMP_FEATURE_REMOVE_INETCIDRROUTETABLE_CONTAINER_SIZE
int
inetCidrRouteTable_container_size(void)
{
    return CONTAINER_SIZE(inetCidrRouteTable_if_ctx.container);
}
#endif /* NETSNMP_FEATURE_REMOVE_INETCIDRROUTETABLE_CONTAINER_SIZE */

u_int
inetCidrRouteTable_dirty_get(void)
{
    return inetCidrRouteTable_if_ctx.table_dirty;
}

void
inetCidrRouteTable_dirty_set(u_int status)
{
    DEBUGMSGTL(("inetCidrRouteTable:inetCidrRouteTable_dirty_set",
                "called. was %d, now %d\n",
                inetCidrRouteTable_if_ctx.table_dirty, status));
    inetCidrRouteTable_if_ctx.table_dirty = status;
}

netsnmp_cache  *
inetCidrRouteTable_get_cache(void)
{
    return inetCidrRouteTable_if_ctx.cache;
}


/*
 * mfd multiplexer modes
 */
static Netsnmp_Node_Handler _mfd_inetCidrRouteTable_pre_request;
static Netsnmp_Node_Handler _mfd_inetCidrRouteTable_post_request;
static Netsnmp_Node_Handler _mfd_inetCidrRouteTable_object_lookup;
static Netsnmp_Node_Handler _mfd_inetCidrRouteTable_get_values;
#if !(defined(NETSNMP_NO_WRITE_SUPPORT) || defined(NETSNMP_DISABLE_SET_SUPPORT))
static Netsnmp_Node_Handler _mfd_inetCidrRouteTable_check_objects;
static Netsnmp_Node_Handler _mfd_inetCidrRouteTable_undo_setup;
static Netsnmp_Node_Handler _mfd_inetCidrRouteTable_set_values;
static Netsnmp_Node_Handler _mfd_inetCidrRouteTable_undo_cleanup;
static Netsnmp_Node_Handler _mfd_inetCidrRouteTable_undo_values;
static Netsnmp_Node_Handler _mfd_inetCidrRouteTable_commit;
static Netsnmp_Node_Handler _mfd_inetCidrRouteTable_undo_commit;
static Netsnmp_Node_Handler _mfd_inetCidrRouteTable_irreversible_commit;
static Netsnmp_Node_Handler _mfd_inetCidrRouteTable_check_dependencies;
#endif /* NETSNMP_NO_WRITE_SUPPORT || NETSNMP_DISABLE_SET_SUPPORT */

NETSNMP_STATIC_INLINE int
                _inetCidrRouteTable_check_indexes(inetCidrRouteTable_rowreq_ctx * rowreq_ctx);
/**
 * @internal
 * Initialize the table inetCidrRouteTable 
 *    (Define its contents and how it's structured)
 */
void
_inetCidrRouteTable_initialize_interface(inetCidrRouteTable_registration *
                                         reg_ptr, u_long flags)
{
    netsnmp_baby_steps_access_methods *access_multiplexer =
        &inetCidrRouteTable_if_ctx.access_multiplexer;
    netsnmp_table_registration_info *tbl_info =
        &inetCidrRouteTable_if_ctx.tbl_info;
    netsnmp_handler_registration *reginfo;
    netsnmp_mib_handler *handler;
    int             mfd_modes = 0;

    DEBUGMSGTL(("internal:inetCidrRouteTable:_inetCidrRouteTable_initialize_interface", "called\n"));


    /*************************************************
     *
     * save interface context for inetCidrRouteTable
     */
    /*
     * Setting up the table's definition
     */
    netsnmp_table_helper_add_indexes(tbl_info, ASN_INTEGER,
                                               /** index: inetCidrRouteDestType */
                                     ASN_OCTET_STR,
                                                 /** index: inetCidrRouteDest */
                                     ASN_UNSIGNED,
                                                /** index: inetCidrRoutePfxLen */
                                     ASN_OBJECT_ID,
                                                 /** index: inetCidrRoutePolicy */
                                     ASN_INTEGER,
                                               /** index: inetCidrRouteNextHopType */
                                     ASN_OCTET_STR,
                                                 /** index: inetCidrRouteNextHop */
                                     0);

    /*
     * Define the minimum and maximum accessible columns.  This
     * optimizes retrieval. 
     */
    tbl_info->min_column = INETCIDRROUTETABLE_MIN_COL;
    tbl_info->max_column = INETCIDRROUTETABLE_MAX_COL;

    /*
     * save users context
     */
    inetCidrRouteTable_if_ctx.user_ctx = reg_ptr;

    /*
     * call data access initialization code
     */
    inetCidrRouteTable_init_data(reg_ptr);

    /*
     * set up the container
     */
    _inetCidrRouteTable_container_init(&inetCidrRouteTable_if_ctx);
    if (NULL == inetCidrRouteTable_if_ctx.container) {
        snmp_log(LOG_ERR,
                 "could not initialize container for inetCidrRouteTable\n");
        return;
    }

    /*
     * access_multiplexer: REQUIRED wrapper for get request handling
     */
    access_multiplexer->object_lookup =
        _mfd_inetCidrRouteTable_object_lookup;
    access_multiplexer->get_values = _mfd_inetCidrRouteTable_get_values;

    /*
     * no wrappers yet
     */
    access_multiplexer->pre_request = _mfd_inetCidrRouteTable_pre_request;
    access_multiplexer->post_request =
        _mfd_inetCidrRouteTable_post_request;


#if !(defined(NETSNMP_NO_WRITE_SUPPORT) || defined(NETSNMP_DISABLE_SET_SUPPORT))
    /*
     * REQUIRED wrappers for set request handling
     */
    access_multiplexer->object_syntax_checks =
        _mfd_inetCidrRouteTable_check_objects;
    access_multiplexer->undo_setup = _mfd_inetCidrRouteTable_undo_setup;
    access_multiplexer->undo_cleanup =
        _mfd_inetCidrRouteTable_undo_cleanup;
    access_multiplexer->set_values = _mfd_inetCidrRouteTable_set_values;
    access_multiplexer->undo_sets = _mfd_inetCidrRouteTable_undo_values;

    /*
     * no wrappers yet
     */
    access_multiplexer->commit = _mfd_inetCidrRouteTable_commit;
    access_multiplexer->undo_commit = _mfd_inetCidrRouteTable_undo_commit;
    access_multiplexer->irreversible_commit =
        _mfd_inetCidrRouteTable_irreversible_commit;

    /*
     * REQUIRED for tables with dependencies
     */
    access_multiplexer->consistency_checks =
        _mfd_inetCidrRouteTable_check_dependencies;
#endif /* NETSNMP_NO_WRITE_SUPPORT || NETSNMP_DISABLE_SET_SUPPORT */

    /*************************************************
     *
     * Create a registration, save our reg data, register table.
     */
    DEBUGMSGTL(("inetCidrRouteTable:init_inetCidrRouteTable",
                "Registering inetCidrRouteTable as a mibs-for-dummies table.\n"));
    handler =
        netsnmp_baby_steps_access_multiplexer_get(access_multiplexer);
    reginfo =
        netsnmp_handler_registration_create("inetCidrRouteTable", handler,
                                            inetCidrRouteTable_oid,
                                            inetCidrRouteTable_oid_size,
                                            HANDLER_CAN_BABY_STEP
#ifndef NETSNMP_DISABLE_SET_SUPPORT
                                          | HANDLER_CAN_RWRITE
#endif
                                          );
    if (NULL == reginfo) {
        snmp_log(LOG_ERR, "error registering table inetCidrRouteTable\n");
        return;
    }
    reginfo->my_reg_void = &inetCidrRouteTable_if_ctx;

    /*************************************************
     *
     * set up baby steps handler, create it and inject it
     */
    if (access_multiplexer->object_lookup)
        mfd_modes |= BABY_STEP_OBJECT_LOOKUP;
    if (access_multiplexer->pre_request)
        mfd_modes |= BABY_STEP_PRE_REQUEST;
    if (access_multiplexer->post_request)
        mfd_modes |= BABY_STEP_POST_REQUEST;

#if !(defined(NETSNMP_NO_WRITE_SUPPORT) || defined(NETSNMP_DISABLE_SET_SUPPORT))
    if (access_multiplexer->set_values)
        mfd_modes |= BABY_STEP_SET_VALUES;
    if (access_multiplexer->irreversible_commit)
        mfd_modes |= BABY_STEP_IRREVERSIBLE_COMMIT;
    if (access_multiplexer->object_syntax_checks)
        mfd_modes |= BABY_STEP_CHECK_OBJECT;

    if (access_multiplexer->undo_setup)
        mfd_modes |= BABY_STEP_UNDO_SETUP;
    if (access_multiplexer->undo_cleanup)
        mfd_modes |= BABY_STEP_UNDO_CLEANUP;
    if (access_multiplexer->undo_sets)
        mfd_modes |= BABY_STEP_UNDO_SETS;

    if (access_multiplexer->row_creation)
        mfd_modes |= BABY_STEP_ROW_CREATE;
    if (access_multiplexer->consistency_checks)
        mfd_modes |= BABY_STEP_CHECK_CONSISTENCY;
    if (access_multiplexer->commit)
        mfd_modes |= BABY_STEP_COMMIT;
    if (access_multiplexer->undo_commit)
        mfd_modes |= BABY_STEP_UNDO_COMMIT;
#endif /* NETSNMP_NO_WRITE_SUPPORT || NETSNMP_DISABLE_SET_SUPPORT */

    handler = netsnmp_baby_steps_handler_get(mfd_modes);
    netsnmp_inject_handler(reginfo, handler);

    /*************************************************
     *
     * inject row_merge helper with prefix rootoid_len + 2 (entry.col)
     */
    handler = netsnmp_get_row_merge_handler(reginfo->rootoid_len + 2);
    netsnmp_inject_handler(reginfo, handler);

    /*************************************************
     *
     * inject container_table helper
     */
    handler =
        netsnmp_container_table_handler_get(tbl_info,
                                            inetCidrRouteTable_if_ctx.
                                            container,
                                            TABLE_CONTAINER_KEY_NETSNMP_INDEX);
    netsnmp_inject_handler(reginfo, handler);

    /*************************************************
     *
     * inject cache helper
     */
    if (NULL != inetCidrRouteTable_if_ctx.cache) {
        handler =
            netsnmp_cache_handler_get(inetCidrRouteTable_if_ctx.cache);
        netsnmp_inject_handler(reginfo, handler);
    }

    /*
     * register table
     */
    netsnmp_register_table(reginfo, tbl_info);

}                               /* _inetCidrRouteTable_initialize_interface */

/**
 * @internal
 * Shutdown the table inetCidrRouteTable
 */
void
_inetCidrRouteTable_shutdown_interface(inetCidrRouteTable_registration *
                                       reg_ptr)
{
    /*
     * shutdown the container
     */
    _inetCidrRouteTable_container_shutdown(&inetCidrRouteTable_if_ctx);
}

void
inetCidrRouteTable_valid_columns_set(netsnmp_column_info *vc)
{
    inetCidrRouteTable_if_ctx.tbl_info.valid_columns = vc;
}                               /* inetCidrRouteTable_valid_columns_set */

/**
 * @internal
 * convert the index component stored in the context to an oid
 */
int
inetCidrRouteTable_index_to_oid(netsnmp_index * oid_idx,
                                inetCidrRouteTable_mib_index * mib_idx)
{
    int             err = SNMP_ERR_NOERROR;

    /*
     * temp storage for parsing indexes
     */
    /*
     * inetCidrRouteDestType(1)/InetAddressType/ASN_INTEGER/long(u_long)//l/a/w/E/r/d/h
     */
    netsnmp_variable_list var_inetCidrRouteDestType;
    /*
     * inetCidrRouteDest(2)/InetAddress/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h
     */
    netsnmp_variable_list var_inetCidrRouteDest;
    /*
     * inetCidrRoutePfxLen(3)/InetAddressPrefixLength/ASN_UNSIGNED/u_long(u_long)//l/a/w/e/R/d/H
     */
    netsnmp_variable_list var_inetCidrRoutePfxLen;
    /*
     * inetCidrRoutePolicy(4)/OBJECTID/ASN_OBJECT_ID/oid(oid)//L/a/w/e/r/d/h
     */
    netsnmp_variable_list var_inetCidrRoutePolicy;
    /*
     * inetCidrRouteNextHopType(5)/InetAddressType/ASN_INTEGER/long(u_long)//l/a/w/E/r/d/h
     */
    netsnmp_variable_list var_inetCidrRouteNextHopType;
    /*
     * inetCidrRouteNextHop(6)/InetAddress/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h
     */
    netsnmp_variable_list var_inetCidrRouteNextHop;

    /*
     * set up varbinds
     */
    memset(&var_inetCidrRouteDestType, 0x00,
           sizeof(var_inetCidrRouteDestType));
    var_inetCidrRouteDestType.type = ASN_INTEGER;
    memset(&var_inetCidrRouteDest, 0x00, sizeof(var_inetCidrRouteDest));
    var_inetCidrRouteDest.type = ASN_OCTET_STR;
    memset(&var_inetCidrRoutePfxLen, 0x00,
           sizeof(var_inetCidrRoutePfxLen));
    var_inetCidrRoutePfxLen.type = ASN_UNSIGNED;
    memset(&var_inetCidrRoutePolicy, 0x00,
           sizeof(var_inetCidrRoutePolicy));
    var_inetCidrRoutePolicy.type = ASN_OBJECT_ID;
    memset(&var_inetCidrRouteNextHopType, 0x00,
           sizeof(var_inetCidrRouteNextHopType));
    var_inetCidrRouteNextHopType.type = ASN_INTEGER;
    memset(&var_inetCidrRouteNextHop, 0x00,
           sizeof(var_inetCidrRouteNextHop));
    var_inetCidrRouteNextHop.type = ASN_OCTET_STR;

    /*
     * chain temp index varbinds together
     */
    var_inetCidrRouteDestType.next_variable = &var_inetCidrRouteDest;
    var_inetCidrRouteDest.next_variable = &var_inetCidrRoutePfxLen;
    var_inetCidrRoutePfxLen.next_variable = &var_inetCidrRoutePolicy;
    var_inetCidrRoutePolicy.next_variable = &var_inetCidrRouteNextHopType;
    var_inetCidrRouteNextHopType.next_variable = &var_inetCidrRouteNextHop;
    var_inetCidrRouteNextHop.next_variable = NULL;


    DEBUGMSGTL(("verbose:inetCidrRouteTable:inetCidrRouteTable_index_to_oid", "called\n"));

    /*
     * inetCidrRouteDestType(1)/InetAddressType/ASN_INTEGER/long(u_long)//l/a/w/E/r/d/h 
     */
    snmp_set_var_value(&var_inetCidrRouteDestType,
                       (u_char *) & mib_idx->inetCidrRouteDestType,
                       sizeof(mib_idx->inetCidrRouteDestType));

    /*
     * inetCidrRouteDest(2)/InetAddress/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h 
     */
    snmp_set_var_value(&var_inetCidrRouteDest,
                       (u_char *) & mib_idx->inetCidrRouteDest,
                       mib_idx->inetCidrRouteDest_len *
                       sizeof(mib_idx->inetCidrRouteDest[0]));

    /*
     * inetCidrRoutePfxLen(3)/InetAddressPrefixLength/ASN_UNSIGNED/u_long(u_long)//l/a/w/e/R/d/H 
     */
    snmp_set_var_value(&var_inetCidrRoutePfxLen,
                       (u_char *) & mib_idx->inetCidrRoutePfxLen,
                       sizeof(mib_idx->inetCidrRoutePfxLen));

    /*
     * inetCidrRoutePolicy(4)/OBJECTID/ASN_OBJECT_ID/oid(oid)//L/a/w/e/r/d/h 
     */
    snmp_set_var_value(&var_inetCidrRoutePolicy,
                       (u_char *) & mib_idx->inetCidrRoutePolicy,
                       mib_idx->inetCidrRoutePolicy_len *
                       sizeof(mib_idx->inetCidrRoutePolicy[0]));

    /*
     * inetCidrRouteNextHopType(5)/InetAddressType/ASN_INTEGER/long(u_long)//l/a/w/E/r/d/h 
     */
    snmp_set_var_value(&var_inetCidrRouteNextHopType,
                       (u_char *) & mib_idx->inetCidrRouteNextHopType,
                       sizeof(mib_idx->inetCidrRouteNextHopType));

    /*
     * inetCidrRouteNextHop(6)/InetAddress/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h 
     */
    snmp_set_var_value(&var_inetCidrRouteNextHop,
                       (u_char *) & mib_idx->inetCidrRouteNextHop,
                       mib_idx->inetCidrRouteNextHop_len *
                       sizeof(mib_idx->inetCidrRouteNextHop[0]));


    err = build_oid_noalloc(oid_idx->oids, oid_idx->len, &oid_idx->len,
                            NULL, 0, &var_inetCidrRouteDestType);
    if (err)
        snmp_log(LOG_ERR, "error %d converting index to oid\n", err);

    /*
     * parsing may have allocated memory. free it.
     */
    snmp_reset_var_buffers(&var_inetCidrRouteDestType);

    return err;
}                               /* inetCidrRouteTable_index_to_oid */

/**
 * extract inetCidrRouteTable indexes from a netsnmp_index
 *
 * @retval SNMP_ERR_NOERROR  : no error
 * @retval SNMP_ERR_GENERR   : error
 */
int
inetCidrRouteTable_index_from_oid(netsnmp_index * oid_idx,
                                  inetCidrRouteTable_mib_index * mib_idx)
{
    int             err = SNMP_ERR_NOERROR;

    /*
     * temp storage for parsing indexes
     */
    /*
     * inetCidrRouteDestType(1)/InetAddressType/ASN_INTEGER/long(u_long)//l/a/w/E/r/d/h
     */
    netsnmp_variable_list var_inetCidrRouteDestType;
    /*
     * inetCidrRouteDest(2)/InetAddress/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h
     */
    netsnmp_variable_list var_inetCidrRouteDest;
    /*
     * inetCidrRoutePfxLen(3)/InetAddressPrefixLength/ASN_UNSIGNED/u_long(u_long)//l/a/w/e/R/d/H
     */
    netsnmp_variable_list var_inetCidrRoutePfxLen;
    /*
     * inetCidrRoutePolicy(4)/OBJECTID/ASN_OBJECT_ID/oid(oid)//L/a/w/e/r/d/h
     */
    netsnmp_variable_list var_inetCidrRoutePolicy;
    /*
     * inetCidrRouteNextHopType(5)/InetAddressType/ASN_INTEGER/long(u_long)//l/a/w/E/r/d/h
     */
    netsnmp_variable_list var_inetCidrRouteNextHopType;
    /*
     * inetCidrRouteNextHop(6)/InetAddress/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h
     */
    netsnmp_variable_list var_inetCidrRouteNextHop;

    /*
     * set up varbinds
     */
    memset(&var_inetCidrRouteDestType, 0x00,
           sizeof(var_inetCidrRouteDestType));
    var_inetCidrRouteDestType.type = ASN_INTEGER;
    memset(&var_inetCidrRouteDest, 0x00, sizeof(var_inetCidrRouteDest));
    var_inetCidrRouteDest.type = ASN_OCTET_STR;
    memset(&var_inetCidrRoutePfxLen, 0x00,
           sizeof(var_inetCidrRoutePfxLen));
    var_inetCidrRoutePfxLen.type = ASN_UNSIGNED;
    memset(&var_inetCidrRoutePolicy, 0x00,
           sizeof(var_inetCidrRoutePolicy));
    var_inetCidrRoutePolicy.type = ASN_OBJECT_ID;
    memset(&var_inetCidrRouteNextHopType, 0x00,
           sizeof(var_inetCidrRouteNextHopType));
    var_inetCidrRouteNextHopType.type = ASN_INTEGER;
    memset(&var_inetCidrRouteNextHop, 0x00,
           sizeof(var_inetCidrRouteNextHop));
    var_inetCidrRouteNextHop.type = ASN_OCTET_STR;

    /*
     * chain temp index varbinds together
     */
    var_inetCidrRouteDestType.next_variable = &var_inetCidrRouteDest;
    var_inetCidrRouteDest.next_variable = &var_inetCidrRoutePfxLen;
    var_inetCidrRoutePfxLen.next_variable = &var_inetCidrRoutePolicy;
    var_inetCidrRoutePolicy.next_variable = &var_inetCidrRouteNextHopType;
    var_inetCidrRouteNextHopType.next_variable = &var_inetCidrRouteNextHop;
    var_inetCidrRouteNextHop.next_variable = NULL;


    DEBUGMSGTL(("verbose:inetCidrRouteTable:inetCidrRouteTable_index_from_oid", "called\n"));

    /*
     * parse the oid into the individual index components
     */
    err = parse_oid_indexes(oid_idx->oids, oid_idx->len,
                            &var_inetCidrRouteDestType);
    if (err == SNMP_ERR_NOERROR) {
        /*
         * copy out values
         */
        mib_idx->inetCidrRouteDestType =
            *((u_long *) var_inetCidrRouteDestType.val.string);
        /*
         * NOTE: val_len is in bytes, inetCidrRouteDest_len might not be
         */
        if (var_inetCidrRouteDest.val_len >
            sizeof(mib_idx->inetCidrRouteDest))
            err = SNMP_ERR_GENERR;
        else {
            memcpy(mib_idx->inetCidrRouteDest,
                   var_inetCidrRouteDest.val.string,
                   var_inetCidrRouteDest.val_len);
            mib_idx->inetCidrRouteDest_len =
                var_inetCidrRouteDest.val_len /
                sizeof(mib_idx->inetCidrRouteDest[0]);
        }
        mib_idx->inetCidrRoutePfxLen =
            *((u_long *) var_inetCidrRoutePfxLen.val.string);
        /*
         * NOTE: val_len is in bytes, inetCidrRoutePolicy_len might not be
         */
        if (var_inetCidrRoutePolicy.val_len >
            sizeof(mib_idx->inetCidrRoutePolicy))
            err = SNMP_ERR_GENERR;
        else {
            memcpy(mib_idx->inetCidrRoutePolicy,
                   var_inetCidrRoutePolicy.val.string,
                   var_inetCidrRoutePolicy.val_len);
            mib_idx->inetCidrRoutePolicy_len =
                var_inetCidrRoutePolicy.val_len /
                sizeof(mib_idx->inetCidrRoutePolicy[0]);
        }
        mib_idx->inetCidrRouteNextHopType =
            *((u_long *) var_inetCidrRouteNextHopType.val.string);
        /*
         * NOTE: val_len is in bytes, inetCidrRouteNextHop_len might not be
         */
        if (var_inetCidrRouteNextHop.val_len >
            sizeof(mib_idx->inetCidrRouteNextHop))
            err = SNMP_ERR_GENERR;
        else {
            memcpy(mib_idx->inetCidrRouteNextHop,
                   var_inetCidrRouteNextHop.val.string,
                   var_inetCidrRouteNextHop.val_len);
            mib_idx->inetCidrRouteNextHop_len =
                var_inetCidrRouteNextHop.val_len /
                sizeof(mib_idx->inetCidrRouteNextHop[0]);
        }


    }

    /*
     * parsing may have allocated memory. free it.
     */
    snmp_reset_var_buffers(&var_inetCidrRouteDestType);

    return err;
}                               /* inetCidrRouteTable_index_from_oid */


/*
 *********************************************************************
 * @internal
 * allocate resources for a inetCidrRouteTable_rowreq_ctx
 */
inetCidrRouteTable_rowreq_ctx *
inetCidrRouteTable_allocate_rowreq_ctx(inetCidrRouteTable_data * data,
                                       void *user_init_ctx)
{
    inetCidrRouteTable_rowreq_ctx *rowreq_ctx =
        SNMP_MALLOC_TYPEDEF(inetCidrRouteTable_rowreq_ctx);

    DEBUGMSGTL(("internal:inetCidrRouteTable:inetCidrRouteTable_allocate_rowreq_ctx", "called\n"));

    if (NULL == rowreq_ctx) {
        snmp_log(LOG_ERR, "Couldn't allocate memory for a "
                 "inetCidrRouteTable_rowreq_ctx.\n");
        return NULL;
    } else {
        if (NULL != data) {
            /*
             * track if we got data from user
             */
            rowreq_ctx->rowreq_flags |= MFD_ROW_DATA_FROM_USER;
            rowreq_ctx->data = data;
        } else if (NULL ==
                   (rowreq_ctx->data =
                    inetCidrRouteTable_allocate_data())) {
            SNMP_FREE(rowreq_ctx);
            return NULL;
        }
    }

    /*
     * undo context will be allocated when needed (in *_undo_setup)
     */

    rowreq_ctx->oid_idx.oids = rowreq_ctx->oid_tmp;

    rowreq_ctx->inetCidrRouteTable_data_list = NULL;

    /*
     * if we allocated data, call init routine
     */
    if (!(rowreq_ctx->rowreq_flags & MFD_ROW_DATA_FROM_USER)) {
        if (SNMPERR_SUCCESS !=
            inetCidrRouteTable_rowreq_ctx_init(rowreq_ctx,
                                               user_init_ctx)) {
            inetCidrRouteTable_release_rowreq_ctx(rowreq_ctx);
            rowreq_ctx = NULL;
        }
    }

    return rowreq_ctx;
}                               /* inetCidrRouteTable_allocate_rowreq_ctx */

/*
 * @internal
 * release resources for a inetCidrRouteTable_rowreq_ctx
 */
void
inetCidrRouteTable_release_rowreq_ctx(inetCidrRouteTable_rowreq_ctx *
                                      rowreq_ctx)
{
    DEBUGMSGTL(("internal:inetCidrRouteTable:inetCidrRouteTable_release_rowreq_ctx", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    inetCidrRouteTable_rowreq_ctx_cleanup(rowreq_ctx);

    /*
     * for non-transient data, don't free data we got from the user
     */
    if ((rowreq_ctx->data) &&
        !(rowreq_ctx->rowreq_flags & MFD_ROW_DATA_FROM_USER))
        inetCidrRouteTable_release_data(rowreq_ctx->data);

    if (rowreq_ctx->undo)
        inetCidrRouteTable_release_data(rowreq_ctx->undo);

    /*
     * free index oid pointer
     */
    if (rowreq_ctx->oid_idx.oids != rowreq_ctx->oid_tmp)
        free(rowreq_ctx->oid_idx.oids);

    SNMP_FREE(rowreq_ctx);
}                               /* inetCidrRouteTable_release_rowreq_ctx */

/**
 * @internal
 * wrapper
 */
static int
_mfd_inetCidrRouteTable_pre_request(netsnmp_mib_handler *handler,
                                    netsnmp_handler_registration *reginfo,
                                    netsnmp_agent_request_info
                                    *agtreq_info,
                                    netsnmp_request_info *requests)
{
    int             rc;

    DEBUGMSGTL(("internal:inetCidrRouteTable:_mfd_inetCidrRouteTable_pre_request", "called\n"));

    if (1 != netsnmp_row_merge_status_first(reginfo, agtreq_info)) {
        DEBUGMSGTL(("internal:inetCidrRouteTable",
                    "skipping additional pre_request\n"));
        return SNMP_ERR_NOERROR;
    }

    rc = inetCidrRouteTable_pre_request(inetCidrRouteTable_if_ctx.
                                        user_ctx);
    if (MFD_SUCCESS != rc) {
        /*
         * nothing we can do about it but log it
         */
        DEBUGMSGTL(("inetCidrRouteTable", "error %d from "
                    "inetCidrRouteTable_pre_request\n", rc));
        netsnmp_request_set_error_all(requests, SNMP_VALIDATE_ERR(rc));
    }

    return SNMP_ERR_NOERROR;
}                               /* _mfd_inetCidrRouteTable_pre_request */

/**
 * @internal
 * wrapper
 */
static int
_mfd_inetCidrRouteTable_post_request(netsnmp_mib_handler *handler,
                                     netsnmp_handler_registration *reginfo,
                                     netsnmp_agent_request_info
                                     *agtreq_info,
                                     netsnmp_request_info *requests)
{
    inetCidrRouteTable_rowreq_ctx *rowreq_ctx = (inetCidrRouteTable_rowreq_ctx*)
        netsnmp_container_table_row_extract(requests);
    int             rc, packet_rc;

    DEBUGMSGTL(("internal:inetCidrRouteTable:_mfd_inetCidrRouteTable_post_request", "called\n"));

    /*
     * release row context, if deleted
     */
    if (rowreq_ctx && (rowreq_ctx->rowreq_flags & MFD_ROW_DELETED))
        inetCidrRouteTable_release_rowreq_ctx(rowreq_ctx);

    /*
     * wait for last call before calling user
     */
    if (1 != netsnmp_row_merge_status_last(reginfo, agtreq_info)) {
        DEBUGMSGTL(("internal:inetCidrRouteTable",
                    "waiting for last post_request\n"));
        return SNMP_ERR_NOERROR;
    }

    packet_rc = netsnmp_check_all_requests_error(agtreq_info->asp, 0);
    if ((MFD_SUCCESS != packet_rc) && inetCidrRouteTable_dirty_get()) {
        /*
         * we shouldn't get here. the undo steps should also clear
         * the dirty flags.
         */
        snmp_log(LOG_WARNING,
                 "inetCidrRouteTable dirty flag set in post_request "
                 "but status != SUCCESS.\n");
    }

    rc = inetCidrRouteTable_post_request(inetCidrRouteTable_if_ctx.
                                         user_ctx, packet_rc);
    if (MFD_SUCCESS != rc) {
        /*
         * nothing we can do about it but log it
         */
        DEBUGMSGTL(("inetCidrRouteTable", "error %d from "
                    "inetCidrRouteTable_post_request\n", rc));
    }

    return SNMP_ERR_NOERROR;
}                               /* _mfd_inetCidrRouteTable_post_request */

/**
 * @internal
 * wrapper
 */
static inetCidrRouteTable_rowreq_ctx *
_mfd_inetCidrRouteTable_rowreq_from_index(netsnmp_index * oid_idx,
                                          int *rc_ptr)
{
    inetCidrRouteTable_rowreq_ctx *rowreq_ctx;
    inetCidrRouteTable_mib_index mib_idx;
    int             rc;

    DEBUGMSGTL(("internal:inetCidrRouteTable:_mfd_inetCidrRouteTable_rowreq_from_index", "called\n"));

    if (NULL == rc_ptr)
        rc_ptr = &rc;
    *rc_ptr = MFD_SUCCESS;

    memset(&mib_idx, 0x0, sizeof(mib_idx));

    /*
     * try to parse oid
     */
    *rc_ptr = inetCidrRouteTable_index_from_oid(oid_idx, &mib_idx);
    if (MFD_SUCCESS != *rc_ptr) {
        DEBUGMSGT(("inetCidrRouteTable", "error parsing index\n"));
        return NULL;
    }

    /*
     * allocate new context
     */
    rowreq_ctx = inetCidrRouteTable_allocate_rowreq_ctx(NULL, NULL);
    if (NULL == rowreq_ctx) {
        *rc_ptr = MFD_ERROR;
        return NULL;            /* msg already logged */
    }

    memcpy(&rowreq_ctx->tbl_idx, &mib_idx, sizeof(mib_idx));

    /*
     * check indexes
     */
    *rc_ptr = _inetCidrRouteTable_check_indexes(rowreq_ctx);
    if (MFD_SUCCESS != *rc_ptr) {
        netsnmp_assert((*rc_ptr == SNMP_ERR_NOCREATION) ||
                       (*rc_ptr == SNMP_ERR_INCONSISTENTNAME));
        inetCidrRouteTable_release_rowreq_ctx(rowreq_ctx);
        return NULL;
    }

    /*
     * copy indexes
     */
    rowreq_ctx->oid_idx.len = oid_idx->len;
    memcpy(rowreq_ctx->oid_idx.oids, oid_idx->oids,
           oid_idx->len * sizeof(oid));

    return rowreq_ctx;
}                               /* _mfd_inetCidrRouteTable_rowreq_from_index */


/**
 * @internal
 * wrapper
 */
static int
_mfd_inetCidrRouteTable_object_lookup(netsnmp_mib_handler *handler, netsnmp_handler_registration
                                      *reginfo, netsnmp_agent_request_info
                                      *agtreq_info,
                                      netsnmp_request_info *requests)
{
    int             rc = SNMP_ERR_NOERROR;
    inetCidrRouteTable_rowreq_ctx *rowreq_ctx = (inetCidrRouteTable_rowreq_ctx*)
        netsnmp_container_table_row_extract(requests);

    DEBUGMSGTL(("internal:inetCidrRouteTable:_mfd_inetCidrRouteTable_object_lookup", "called\n"));

    /*
     * get our context from mfd
     * inetCidrRouteTable_interface_ctx *if_ctx =
     *             (inetCidrRouteTable_interface_ctx *)reginfo->my_reg_void;
     */

    if (NULL == rowreq_ctx) {
        netsnmp_table_request_info *tblreq_info;
        netsnmp_index   oid_idx;

        tblreq_info = netsnmp_extract_table_info(requests);
        if (NULL == tblreq_info) {
            snmp_log(LOG_ERR, "request had no table info\n");
            return MFD_ERROR;
        }

        /*
         * try create rowreq
         */
        oid_idx.oids = tblreq_info->index_oid;
        oid_idx.len = tblreq_info->index_oid_len;

        rowreq_ctx =
            _mfd_inetCidrRouteTable_rowreq_from_index(&oid_idx, &rc);
        if (MFD_SUCCESS == rc) {
            netsnmp_assert(NULL != rowreq_ctx);
            rowreq_ctx->rowreq_flags |= MFD_ROW_CREATED;
            /*
             * add rowreq_ctx to request data lists
             */
            netsnmp_container_table_row_insert(requests, (netsnmp_index *)
                                               rowreq_ctx);
        }
    }

    if (MFD_SUCCESS != rc)
        netsnmp_request_set_error_all(requests, rc);
    else
        inetCidrRouteTable_row_prep(rowreq_ctx);

    return SNMP_VALIDATE_ERR(rc);
}                               /* _mfd_inetCidrRouteTable_object_lookup */

/***********************************************************************
 *
 * GET processing
 *
 ***********************************************************************/
/*
 * @internal
 * Retrieve the value for a particular column
 */
NETSNMP_STATIC_INLINE int
_inetCidrRouteTable_get_column(inetCidrRouteTable_rowreq_ctx * rowreq_ctx,
                               netsnmp_variable_list * var, int column)
{
    int             rc = SNMPERR_SUCCESS;

    DEBUGMSGTL(("internal:inetCidrRouteTable:_mfd_inetCidrRouteTable_get_column", "called for %d\n", column));


    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

        /*
         * inetCidrRouteIfIndex(7)/InterfaceIndexOrZero/ASN_INTEGER/long(long)//l/A/W/e/R/d/H 
         */
    case COLUMN_INETCIDRROUTEIFINDEX:
        var->val_len = sizeof(long);
        var->type = ASN_INTEGER;
        rc = inetCidrRouteIfIndex_get(rowreq_ctx,
                                      (long *) var->val.string);
        break;

        /*
         * inetCidrRouteType(8)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_INETCIDRROUTETYPE:
        var->val_len = sizeof(u_long);
        var->type = ASN_INTEGER;
        rc = inetCidrRouteType_get(rowreq_ctx, (u_long *) var->val.string);
        break;

        /*
         * inetCidrRouteProto(9)/IANAipRouteProtocol/ASN_INTEGER/long(u_long)//l/A/w/E/r/d/h 
         */
    case COLUMN_INETCIDRROUTEPROTO:
        var->val_len = sizeof(u_long);
        var->type = ASN_INTEGER;
        rc = inetCidrRouteProto_get(rowreq_ctx,
                                    (u_long *) var->val.string);
        break;

        /*
         * inetCidrRouteAge(10)/GAUGE/ASN_GAUGE/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_INETCIDRROUTEAGE:
        var->val_len = sizeof(u_long);
        var->type = ASN_GAUGE;
        rc = inetCidrRouteAge_get(rowreq_ctx, (u_long *) var->val.string);
        break;

        /*
         * inetCidrRouteNextHopAS(11)/InetAutonomousSystemNumber/ASN_UNSIGNED/u_long(u_long)//l/A/W/e/r/D/H 
         */
    case COLUMN_INETCIDRROUTENEXTHOPAS:
        var->val_len = sizeof(u_long);
        var->type = ASN_UNSIGNED;
        rc = inetCidrRouteNextHopAS_get(rowreq_ctx,
                                        (u_long *) var->val.string);
        break;

        /*
         * inetCidrRouteMetric1(12)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_INETCIDRROUTEMETRIC1:
        var->val_len = sizeof(long);
        var->type = ASN_INTEGER;
        rc = inetCidrRouteMetric1_get(rowreq_ctx,
                                      (long *) var->val.string);
        break;

        /*
         * inetCidrRouteMetric2(13)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_INETCIDRROUTEMETRIC2:
        var->val_len = sizeof(long);
        var->type = ASN_INTEGER;
        rc = inetCidrRouteMetric2_get(rowreq_ctx,
                                      (long *) var->val.string);
        break;

        /*
         * inetCidrRouteMetric3(14)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_INETCIDRROUTEMETRIC3:
        var->val_len = sizeof(long);
        var->type = ASN_INTEGER;
        rc = inetCidrRouteMetric3_get(rowreq_ctx,
                                      (long *) var->val.string);
        break;

        /*
         * inetCidrRouteMetric4(15)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_INETCIDRROUTEMETRIC4:
        var->val_len = sizeof(long);
        var->type = ASN_INTEGER;
        rc = inetCidrRouteMetric4_get(rowreq_ctx,
                                      (long *) var->val.string);
        break;

        /*
         * inetCidrRouteMetric5(16)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_INETCIDRROUTEMETRIC5:
        var->val_len = sizeof(long);
        var->type = ASN_INTEGER;
        rc = inetCidrRouteMetric5_get(rowreq_ctx,
                                      (long *) var->val.string);
        break;

        /*
         * inetCidrRouteStatus(17)/RowStatus/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_INETCIDRROUTESTATUS:
        var->val_len = sizeof(u_long);
        var->type = ASN_INTEGER;
        rc = inetCidrRouteStatus_get(rowreq_ctx,
                                     (u_long *) var->val.string);
        break;

    default:
        snmp_log(LOG_ERR,
                 "unknown column %d in _inetCidrRouteTable_get_column\n",
                 column);
        break;
    }

    return rc;
}                               /* _inetCidrRouteTable_get_column */

int
_mfd_inetCidrRouteTable_get_values(netsnmp_mib_handler *handler,
                                   netsnmp_handler_registration *reginfo,
                                   netsnmp_agent_request_info *agtreq_info,
                                   netsnmp_request_info *requests)
{
    inetCidrRouteTable_rowreq_ctx *rowreq_ctx = (inetCidrRouteTable_rowreq_ctx*)
        netsnmp_container_table_row_extract(requests);
    netsnmp_table_request_info *tri;
    u_char         *old_string;
    void            (*dataFreeHook) (void *);
    int             rc;

    DEBUGMSGTL(("internal:inetCidrRouteTable:_mfd_inetCidrRouteTable_get_values", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    for (; requests; requests = requests->next) {
        /*
         * save old pointer, so we can free it if replaced
         */
        old_string = requests->requestvb->val.string;
        dataFreeHook = requests->requestvb->dataFreeHook;
        if (NULL == requests->requestvb->val.string) {
            requests->requestvb->val.string = requests->requestvb->buf;
            requests->requestvb->val_len =
                sizeof(requests->requestvb->buf);
        } else if (requests->requestvb->buf ==
                   requests->requestvb->val.string) {
            if (requests->requestvb->val_len !=
                sizeof(requests->requestvb->buf))
                requests->requestvb->val_len =
                    sizeof(requests->requestvb->buf);
        }

        /*
         * get column data
         */
        tri = netsnmp_extract_table_info(requests);
        if (NULL == tri)
            continue;

        rc = _inetCidrRouteTable_get_column(rowreq_ctx,
                                            requests->requestvb,
                                            tri->colnum);
        if (rc) {
            if (MFD_SKIP == rc) {
                requests->requestvb->type = SNMP_NOSUCHINSTANCE;
                rc = SNMP_ERR_NOERROR;
            }
        } else if (NULL == requests->requestvb->val.string) {
            snmp_log(LOG_ERR, "NULL varbind data pointer!\n");
            rc = SNMP_ERR_GENERR;
        }
        if (rc)
            netsnmp_request_set_error(requests, SNMP_VALIDATE_ERR(rc));

        /*
         * if the buffer wasn't used previously for the old data (i.e. it
         * was allcoated memory)  and the get routine replaced the pointer,
         * we need to free the previous pointer.
         */
        if (old_string && (old_string != requests->requestvb->buf) &&
            (requests->requestvb->val.string != old_string)) {
            if (dataFreeHook)
                (*dataFreeHook) (old_string);
            else
                free(old_string);
        }
    }                           /* for results */

    return SNMP_ERR_NOERROR;
}                               /* _mfd_inetCidrRouteTable_get_values */

NETSNMP_STATIC_INLINE int
_inetCidrRouteTable_check_indexes(inetCidrRouteTable_rowreq_ctx *
                                  rowreq_ctx)
{
    int             rc = SNMPERR_SUCCESS;

    DEBUGMSGTL(("internal:inetCidrRouteTable:_inetCidrRouteTable_check_indexes", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);


    /*
     * (INDEX) inetCidrRouteDestType(1)/InetAddressType/ASN_INTEGER/long(u_long)//l/a/w/E/r/d/h 
     */
    /*
     * check that the value is one of defined enums 
     */
    if ((SNMPERR_SUCCESS == rc)
        && (rowreq_ctx->tbl_idx.inetCidrRouteDestType !=
            INETADDRESSTYPE_UNKNOWN)
        && (rowreq_ctx->tbl_idx.inetCidrRouteDestType !=
            INETADDRESSTYPE_IPV4)
        && (rowreq_ctx->tbl_idx.inetCidrRouteDestType !=
            INETADDRESSTYPE_IPV6)
        && (rowreq_ctx->tbl_idx.inetCidrRouteDestType !=
            INETADDRESSTYPE_IPV4Z)
        && (rowreq_ctx->tbl_idx.inetCidrRouteDestType !=
            INETADDRESSTYPE_IPV6Z)
        && (rowreq_ctx->tbl_idx.inetCidrRouteDestType !=
            INETADDRESSTYPE_DNS)
        ) {
        rc = SNMP_ERR_WRONGVALUE;
    }
    if (MFD_SUCCESS != rc)
        return rc;
    rc = inetCidrRouteDestType_check_index(rowreq_ctx);
    if (MFD_SUCCESS != rc)
        return SNMP_ERR_NOCREATION;

    /* MORE CHECKING REQUIRED */

    /*
     * (INDEX) inetCidrRouteDest(2)/InetAddress/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h 
     */
    /*
     * check defined range(s). 
     */
    if ((SNMPERR_SUCCESS == rc)
        && ((rowreq_ctx->tbl_idx.inetCidrRouteDest_len < 0)
            || (rowreq_ctx->tbl_idx.inetCidrRouteDest_len > 255))
        ) {
        rc = SNMP_ERR_WRONGLENGTH;
    }
    if (MFD_SUCCESS != rc)
        return rc;
    rc = inetCidrRouteDest_check_index(rowreq_ctx);
    if (MFD_SUCCESS != rc)
        return SNMP_ERR_NOCREATION;

    /*
     * (INDEX) inetCidrRoutePfxLen(3)/InetAddressPrefixLength/ASN_UNSIGNED/u_long(u_long)//l/a/w/e/R/d/H 
     */
    /*
     * check defined range(s). 
     */
    if ((SNMPERR_SUCCESS == rc)
        && ((rowreq_ctx->tbl_idx.inetCidrRoutePfxLen < 0)
            || (rowreq_ctx->tbl_idx.inetCidrRoutePfxLen > 2040))
        ) {
        rc = SNMP_ERR_WRONGVALUE;
    }
    if (MFD_SUCCESS != rc)
        return rc;
    rc = inetCidrRoutePfxLen_check_index(rowreq_ctx);
    if (MFD_SUCCESS != rc)
        return SNMP_ERR_NOCREATION;

    /*
     * (INDEX) inetCidrRoutePolicy(4)/OBJECTID/ASN_OBJECT_ID/oid(oid)//L/a/w/e/r/d/h 
     */
    if (MFD_SUCCESS != rc)
        return rc;
    rc = inetCidrRoutePolicy_check_index(rowreq_ctx);
    if (MFD_SUCCESS != rc)
        return SNMP_ERR_NOCREATION;

    /*
     * (INDEX) inetCidrRouteNextHopType(5)/InetAddressType/ASN_INTEGER/long(u_long)//l/a/w/E/r/d/h 
     */
    /*
     * check that the value is one of defined enums 
     */
    if ((SNMPERR_SUCCESS == rc)
        && (rowreq_ctx->tbl_idx.inetCidrRouteNextHopType !=
            INETADDRESSTYPE_UNKNOWN)
        && (rowreq_ctx->tbl_idx.inetCidrRouteNextHopType !=
            INETADDRESSTYPE_IPV4)
        && (rowreq_ctx->tbl_idx.inetCidrRouteNextHopType !=
            INETADDRESSTYPE_IPV6)
        && (rowreq_ctx->tbl_idx.inetCidrRouteNextHopType !=
            INETADDRESSTYPE_IPV4Z)
        && (rowreq_ctx->tbl_idx.inetCidrRouteNextHopType !=
            INETADDRESSTYPE_IPV6Z)
        && (rowreq_ctx->tbl_idx.inetCidrRouteNextHopType !=
            INETADDRESSTYPE_DNS)
        ) {
        rc = SNMP_ERR_WRONGVALUE;
    }
    if (MFD_SUCCESS != rc)
        return rc;
    rc = inetCidrRouteNextHopType_check_index(rowreq_ctx);
    if (MFD_SUCCESS != rc)
        return SNMP_ERR_NOCREATION;

    /*
     * (INDEX) inetCidrRouteNextHop(6)/InetAddress/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h 
     */
    /*
     * check defined range(s). 
     */
    if ((SNMPERR_SUCCESS == rc)
        && ((rowreq_ctx->tbl_idx.inetCidrRouteNextHop_len < 0)
            || (rowreq_ctx->tbl_idx.inetCidrRouteNextHop_len > 255))
        ) {
        rc = SNMP_ERR_WRONGLENGTH;
    }
    if (MFD_SUCCESS != rc)
        return rc;
    rc = inetCidrRouteNextHop_check_index(rowreq_ctx);
    if (MFD_SUCCESS != rc)
        return SNMP_ERR_NOCREATION;

    /*
     * if individual parts look ok, check them as a whole
     */
    return inetCidrRouteTable_validate_index(inetCidrRouteTable_if_ctx.
                                             user_ctx, rowreq_ctx);
}                               /* _inetCidrRouteTable_check_indexes */

#if !(defined(NETSNMP_NO_WRITE_SUPPORT) || defined(NETSNMP_DISABLE_SET_SUPPORT))
/***********************************************************************
 *
 * SET processing
 *
 ***********************************************************************/

/*----------------------------------------------------------------------
 *
 * SET: Syntax checks
 *
 *---------------------------------------------------------------------*/
/*
 * @internal
 * Check the syntax for a particular column
 */
NETSNMP_STATIC_INLINE int
_inetCidrRouteTable_check_column(inetCidrRouteTable_rowreq_ctx *
                                 rowreq_ctx, netsnmp_variable_list * var,
                                 int column)
{
    int             rc = SNMPERR_SUCCESS;

    DEBUGMSGTL(("internal:inetCidrRouteTable:_inetCidrRouteTable_check_column", "called for %d\n", column));

    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {
        /*
         * (INDEX) inetCidrRouteDestType(1)/InetAddressType/ASN_INTEGER/long(u_long)//l/a/w/E/r/d/h 
         */
    case COLUMN_INETCIDRROUTEDESTTYPE:
        rc = SNMP_ERR_NOTWRITABLE;      /* can not change index of active row */
        break;
        /*
         * (INDEX) inetCidrRouteDest(2)/InetAddress/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h 
         */
    case COLUMN_INETCIDRROUTEDEST:
        rc = SNMP_ERR_NOTWRITABLE;      /* can not change index of active row */
        break;
        /*
         * (INDEX) inetCidrRoutePfxLen(3)/InetAddressPrefixLength/ASN_UNSIGNED/u_long(u_long)//l/a/w/e/R/d/H 
         */
    case COLUMN_INETCIDRROUTEPFXLEN:
        rc = SNMP_ERR_NOTWRITABLE;      /* can not change index of active row */
        break;
        /*
         * (INDEX) inetCidrRoutePolicy(4)/OBJECTID/ASN_OBJECT_ID/oid(oid)//L/a/w/e/r/d/h 
         */
    case COLUMN_INETCIDRROUTEPOLICY:
        rc = SNMP_ERR_NOTWRITABLE;      /* can not change index of active row */
        break;
        /*
         * (INDEX) inetCidrRouteNextHopType(5)/InetAddressType/ASN_INTEGER/long(u_long)//l/a/w/E/r/d/h 
         */
    case COLUMN_INETCIDRROUTENEXTHOPTYPE:
        rc = SNMP_ERR_NOTWRITABLE;      /* can not change index of active row */
        break;
        /*
         * (INDEX) inetCidrRouteNextHop(6)/InetAddress/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h 
         */
    case COLUMN_INETCIDRROUTENEXTHOP:
        rc = SNMP_ERR_NOTWRITABLE;      /* can not change index of active row */
        break;

        /*
         * inetCidrRouteIfIndex(7)/InterfaceIndexOrZero/ASN_INTEGER/long(long)//l/A/W/e/R/d/H 
         */
    case COLUMN_INETCIDRROUTEIFINDEX:
        rc = netsnmp_check_vb_type(var, ASN_INTEGER);
        /*
         * check defined range(s). 
         */
        if ((SNMPERR_SUCCESS == rc)
            && ((*var->val.integer < 0)
                || (*var->val.integer > 2147483647))
            ) {
            rc = SNMP_ERR_WRONGVALUE;
        }
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("inetCidrRouteTable:_inetCidrRouteTable_check_column:inetCidrRouteIfIndex", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = inetCidrRouteIfIndex_check_value(rowreq_ctx,
                                                  *((long *) var->val.
                                                    string));
            if ((MFD_SUCCESS != rc) && (MFD_NOT_VALID_EVER != rc)
                && (MFD_NOT_VALID_NOW != rc)) {
                snmp_log(LOG_ERR,
                         "bad rc %d from inetCidrRouteIfIndex_check_value\n",
                         rc);
                rc = SNMP_ERR_GENERR;
            }
        }
        break;

        /*
         * inetCidrRouteType(8)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_INETCIDRROUTETYPE:
        rc = netsnmp_check_vb_type(var, ASN_INTEGER);
        /*
         * check that the value is one of defined enums 
         */
        if ((SNMPERR_SUCCESS == rc)
            && (*var->val.integer != INETCIDRROUTETYPE_OTHER)
            && (*var->val.integer != INETCIDRROUTETYPE_REJECT)
            && (*var->val.integer != INETCIDRROUTETYPE_LOCAL)
            && (*var->val.integer != INETCIDRROUTETYPE_REMOTE)
            && (*var->val.integer != INETCIDRROUTETYPE_BLACKHOLE)
            ) {
            rc = SNMP_ERR_WRONGVALUE;
        }
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("inetCidrRouteTable:_inetCidrRouteTable_check_column:inetCidrRouteType", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = inetCidrRouteType_check_value(rowreq_ctx,
                                               *((u_long *) var->val.
                                                 string));
            if ((MFD_SUCCESS != rc) && (MFD_NOT_VALID_EVER != rc)
                && (MFD_NOT_VALID_NOW != rc)) {
                snmp_log(LOG_ERR,
                         "bad rc %d from inetCidrRouteType_check_value\n",
                         rc);
                rc = SNMP_ERR_GENERR;
            }
        }
        break;

        /*
         * inetCidrRouteProto(9)/IANAipRouteProtocol/ASN_INTEGER/long(u_long)//l/A/w/E/r/d/h 
         */
    case COLUMN_INETCIDRROUTEPROTO:
        rc = SNMP_ERR_NOTWRITABLE;
        break;

        /*
         * inetCidrRouteAge(10)/GAUGE/ASN_GAUGE/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_INETCIDRROUTEAGE:
        rc = SNMP_ERR_NOTWRITABLE;
        break;

        /*
         * inetCidrRouteNextHopAS(11)/InetAutonomousSystemNumber/ASN_UNSIGNED/u_long(u_long)//l/A/W/e/r/D/H 
         */
    case COLUMN_INETCIDRROUTENEXTHOPAS:
        rc = netsnmp_check_vb_type(var, ASN_UNSIGNED);
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("inetCidrRouteTable:_inetCidrRouteTable_check_column:inetCidrRouteNextHopAS", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = inetCidrRouteNextHopAS_check_value(rowreq_ctx,
                                                    *((u_long *) var->val.
                                                      string));
            if ((MFD_SUCCESS != rc) && (MFD_NOT_VALID_EVER != rc)
                && (MFD_NOT_VALID_NOW != rc)) {
                snmp_log(LOG_ERR,
                         "bad rc %d from inetCidrRouteNextHopAS_check_value\n",
                         rc);
                rc = SNMP_ERR_GENERR;
            }
        }
        break;

        /*
         * inetCidrRouteMetric1(12)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_INETCIDRROUTEMETRIC1:
        rc = netsnmp_check_vb_type(var, ASN_INTEGER);
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("inetCidrRouteTable:_inetCidrRouteTable_check_column:inetCidrRouteMetric1", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = inetCidrRouteMetric1_check_value(rowreq_ctx,
                                                  *((long *) var->val.
                                                    string));
            if ((MFD_SUCCESS != rc) && (MFD_NOT_VALID_EVER != rc)
                && (MFD_NOT_VALID_NOW != rc)) {
                snmp_log(LOG_ERR,
                         "bad rc %d from inetCidrRouteMetric1_check_value\n",
                         rc);
                rc = SNMP_ERR_GENERR;
            }
        }
        break;

        /*
         * inetCidrRouteMetric2(13)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_INETCIDRROUTEMETRIC2:
        rc = netsnmp_check_vb_type(var, ASN_INTEGER);
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("inetCidrRouteTable:_inetCidrRouteTable_check_column:inetCidrRouteMetric2", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = inetCidrRouteMetric2_check_value(rowreq_ctx,
                                                  *((long *) var->val.
                                                    string));
            if ((MFD_SUCCESS != rc) && (MFD_NOT_VALID_EVER != rc)
                && (MFD_NOT_VALID_NOW != rc)) {
                snmp_log(LOG_ERR,
                         "bad rc %d from inetCidrRouteMetric2_check_value\n",
                         rc);
                rc = SNMP_ERR_GENERR;
            }
        }
        break;

        /*
         * inetCidrRouteMetric3(14)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_INETCIDRROUTEMETRIC3:
        rc = netsnmp_check_vb_type(var, ASN_INTEGER);
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("inetCidrRouteTable:_inetCidrRouteTable_check_column:inetCidrRouteMetric3", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = inetCidrRouteMetric3_check_value(rowreq_ctx,
                                                  *((long *) var->val.
                                                    string));
            if ((MFD_SUCCESS != rc) && (MFD_NOT_VALID_EVER != rc)
                && (MFD_NOT_VALID_NOW != rc)) {
                snmp_log(LOG_ERR,
                         "bad rc %d from inetCidrRouteMetric3_check_value\n",
                         rc);
                rc = SNMP_ERR_GENERR;
            }
        }
        break;

        /*
         * inetCidrRouteMetric4(15)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_INETCIDRROUTEMETRIC4:
        rc = netsnmp_check_vb_type(var, ASN_INTEGER);
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("inetCidrRouteTable:_inetCidrRouteTable_check_column:inetCidrRouteMetric4", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = inetCidrRouteMetric4_check_value(rowreq_ctx,
                                                  *((long *) var->val.
                                                    string));
            if ((MFD_SUCCESS != rc) && (MFD_NOT_VALID_EVER != rc)
                && (MFD_NOT_VALID_NOW != rc)) {
                snmp_log(LOG_ERR,
                         "bad rc %d from inetCidrRouteMetric4_check_value\n",
                         rc);
                rc = SNMP_ERR_GENERR;
            }
        }
        break;

        /*
         * inetCidrRouteMetric5(16)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_INETCIDRROUTEMETRIC5:
        rc = netsnmp_check_vb_type(var, ASN_INTEGER);
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("inetCidrRouteTable:_inetCidrRouteTable_check_column:inetCidrRouteMetric5", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = inetCidrRouteMetric5_check_value(rowreq_ctx,
                                                  *((long *) var->val.
                                                    string));
            if ((MFD_SUCCESS != rc) && (MFD_NOT_VALID_EVER != rc)
                && (MFD_NOT_VALID_NOW != rc)) {
                snmp_log(LOG_ERR,
                         "bad rc %d from inetCidrRouteMetric5_check_value\n",
                         rc);
                rc = SNMP_ERR_GENERR;
            }
        }
        break;

        /*
         * inetCidrRouteStatus(17)/RowStatus/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_INETCIDRROUTESTATUS:
        rc = netsnmp_check_vb_rowstatus_value(var);
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("inetCidrRouteTable:_inetCidrRouteTable_check_column:inetCidrRouteStatus", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = inetCidrRouteStatus_check_value(rowreq_ctx,
                                                 *((u_long *) var->val.
                                                   string));
            if ((MFD_SUCCESS != rc) && (MFD_NOT_VALID_EVER != rc)
                && (MFD_NOT_VALID_NOW != rc)) {
                snmp_log(LOG_ERR,
                         "bad rc %d from inetCidrRouteStatus_check_value\n",
                         rc);
                rc = SNMP_ERR_GENERR;
            }
        }
        break;

    default:   /** We shouldn't get here */
        rc = SNMP_ERR_GENERR;
        snmp_log(LOG_ERR,
                 "unknown column %d in _inetCidrRouteTable_check_column\n",
                 column);
    }

    return rc;
}                               /* _inetCidrRouteTable_check_column */

int
_mfd_inetCidrRouteTable_check_objects(netsnmp_mib_handler *handler, netsnmp_handler_registration
                                      *reginfo, netsnmp_agent_request_info
                                      *agtreq_info,
                                      netsnmp_request_info *requests)
{
    inetCidrRouteTable_rowreq_ctx *rowreq_ctx = (inetCidrRouteTable_rowreq_ctx*)
        netsnmp_container_table_row_extract(requests);
    netsnmp_table_request_info *tri;
    int             rc;

    DEBUGMSGTL(("internal:inetCidrRouteTable:_mfd_inetCidrRouteTable_check_objects", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    for (; requests; requests = requests->next) {

        /*
         * get column number from table request info, and check that column
         */
        tri = netsnmp_extract_table_info(requests);
        if (NULL == tri)
            continue;

        rc = _inetCidrRouteTable_check_column(rowreq_ctx,
                                              requests->requestvb,
                                              tri->colnum);
        if (rc) {
            netsnmp_request_set_error(requests, SNMP_VALIDATE_ERR(rc));
            break;
        }

    }                           /* for results */

    return SNMP_ERR_NOERROR;
}                               /* _mfd_inetCidrRouteTable_check_objects */


/*----------------------------------------------------------------------
 *
 * SET: check dependencies
 *
 *---------------------------------------------------------------------*/
/*
 * @internal
 * Check dependencies wrapper
 */
static int
_mfd_inetCidrRouteTable_check_dependencies(netsnmp_mib_handler *handler, netsnmp_handler_registration
                                           *reginfo, netsnmp_agent_request_info
                                           *agtreq_info,
                                           netsnmp_request_info *requests)
{
    int             rc;
    inetCidrRouteTable_rowreq_ctx *rowreq_ctx = (inetCidrRouteTable_rowreq_ctx*)
        netsnmp_container_table_row_extract(requests);
    DEBUGMSGTL(("internal:inetCidrRouteTable:_mfd_inetCidrRouteTable_check_dependencies", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    rc = inetCidrRouteTable_check_dependencies(rowreq_ctx);
    if (rc) {
        DEBUGMSGTL(("inetCidrRouteTable:mfd", "error %d from "
                    "inetCidrRouteTable_check_dependencies\n", rc));
        netsnmp_request_set_error_all(requests, SNMP_VALIDATE_ERR(rc));
    }

    return SNMP_ERR_NOERROR;
}                               /* _mfd_inetCidrRouteTable_check_dependencies */

/*----------------------------------------------------------------------
 *
 * SET: Undo setup
 *
 *---------------------------------------------------------------------*/
/*
 * @internal
 * Set the value for a particular column
 */
NETSNMP_STATIC_INLINE int
_inetCidrRouteTable_undo_setup_column(inetCidrRouteTable_rowreq_ctx *
                                      rowreq_ctx, int column)
{
    int             rc = SNMPERR_SUCCESS;

    DEBUGMSGTL(("internal:inetCidrRouteTable:_inetCidrRouteTable_undo_setup_column", "called for %d\n", column));

    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

        /*
         * inetCidrRouteIfIndex(7)/InterfaceIndexOrZero/ASN_INTEGER/long(long)//l/A/W/e/R/d/H 
         */
    case COLUMN_INETCIDRROUTEIFINDEX:
        rowreq_ctx->column_set_flags |= COLUMN_INETCIDRROUTEIFINDEX_FLAG;
        break;

        /*
         * inetCidrRouteType(8)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_INETCIDRROUTETYPE:
        rowreq_ctx->column_set_flags |= COLUMN_INETCIDRROUTETYPE_FLAG;
        break;

        /*
         * inetCidrRouteNextHopAS(11)/InetAutonomousSystemNumber/ASN_UNSIGNED/u_long(u_long)//l/A/W/e/r/D/H 
         */
    case COLUMN_INETCIDRROUTENEXTHOPAS:
        rowreq_ctx->column_set_flags |= COLUMN_INETCIDRROUTENEXTHOPAS_FLAG;
        break;

        /*
         * inetCidrRouteMetric1(12)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_INETCIDRROUTEMETRIC1:
        rowreq_ctx->column_set_flags |= COLUMN_INETCIDRROUTEMETRIC1_FLAG;
        break;

        /*
         * inetCidrRouteMetric2(13)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_INETCIDRROUTEMETRIC2:
        rowreq_ctx->column_set_flags |= COLUMN_INETCIDRROUTEMETRIC2_FLAG;
        break;

        /*
         * inetCidrRouteMetric3(14)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_INETCIDRROUTEMETRIC3:
        rowreq_ctx->column_set_flags |= COLUMN_INETCIDRROUTEMETRIC3_FLAG;
        break;

        /*
         * inetCidrRouteMetric4(15)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_INETCIDRROUTEMETRIC4:
        rowreq_ctx->column_set_flags |= COLUMN_INETCIDRROUTEMETRIC4_FLAG;
        break;

        /*
         * inetCidrRouteMetric5(16)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_INETCIDRROUTEMETRIC5:
        rowreq_ctx->column_set_flags |= COLUMN_INETCIDRROUTEMETRIC5_FLAG;
        break;

        /*
         * inetCidrRouteStatus(17)/RowStatus/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_INETCIDRROUTESTATUS:
        rowreq_ctx->column_set_flags |= COLUMN_INETCIDRROUTESTATUS_FLAG;
        break;

    default:
        snmp_log(LOG_ERR,
                 "unknown column %d in _inetCidrRouteTable_undo_setup_column\n",
                 column);
        break;
    }

    return rc;
}                               /* _inetCidrRouteTable_undo_setup_column */


/**
 * @internal
 * undo setup
 */
int
_mfd_inetCidrRouteTable_undo_setup(netsnmp_mib_handler *handler,
                                   netsnmp_handler_registration *reginfo,
                                   netsnmp_agent_request_info *agtreq_info,
                                   netsnmp_request_info *requests)
{
    int             rc;
    inetCidrRouteTable_rowreq_ctx *rowreq_ctx = (inetCidrRouteTable_rowreq_ctx*)
        netsnmp_container_table_row_extract(requests);

    DEBUGMSGTL(("internal:inetCidrRouteTable:_mfd_inetCidrRouteTable_undo_setup", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * allocate undo context
     */
    rowreq_ctx->undo = inetCidrRouteTable_allocate_data();
    if (NULL == rowreq_ctx->undo) {
        /** msg already logged */
        netsnmp_request_set_error_all(requests,
                                      SNMP_ERR_RESOURCEUNAVAILABLE);
        return SNMP_ERR_NOERROR;
    }

    /*
     * row undo setup
     */
    rowreq_ctx->column_set_flags = 0;
    rc = inetCidrRouteTable_undo_setup(rowreq_ctx);
    if (MFD_SUCCESS != rc) {
        DEBUGMSGTL(("inetCidrRouteTable:mfd", "error %d from "
                    "inetCidrRouteTable_undo_setup\n", rc));
        netsnmp_request_set_error_all(requests, SNMP_VALIDATE_ERR(rc));
    } else {
        /*
         * column undo setup
         */
        netsnmp_table_request_info *tri;
        for (; requests; requests = requests->next) {
            /*
             * set column data
             */
            tri = netsnmp_extract_table_info(requests);
            if (NULL == tri)
                continue;

            rc = _inetCidrRouteTable_undo_setup_column(rowreq_ctx,
                                                       tri->colnum);
            if (MFD_SUCCESS != rc) {
                DEBUGMSGTL(("inetCidrRouteTable:mfd", "error %d from "
                            "inetCidrRouteTable_undo_setup_column\n", rc));
                netsnmp_set_request_error(agtreq_info, requests,
                                          SNMP_VALIDATE_ERR(rc));
            }
        }                       /* for results */
    }

    return SNMP_ERR_NOERROR;
}                               /* _mfd_inetCidrRouteTable_undo_setup */

/**
 * @internal
 * undo setup
 */
int
_mfd_inetCidrRouteTable_undo_cleanup(netsnmp_mib_handler *handler,
                                     netsnmp_handler_registration *reginfo,
                                     netsnmp_agent_request_info
                                     *agtreq_info,
                                     netsnmp_request_info *requests)
{
    inetCidrRouteTable_rowreq_ctx *rowreq_ctx = (inetCidrRouteTable_rowreq_ctx*)
        netsnmp_container_table_row_extract(requests);
    int             rc;

    DEBUGMSGTL(("internal:inetCidrRouteTable:_mfd_inetCidrRouteTable_undo_cleanup", "called\n"));

    /*
     * failed row create in early stages has no rowreq_ctx
     */
    if (NULL == rowreq_ctx)
        return MFD_SUCCESS;

    /*
     * call user cleanup
     */
    rc = inetCidrRouteTable_undo_cleanup(rowreq_ctx);
    if (MFD_SUCCESS != rc) {
        /*
         * nothing we can do about it but log it
         */
        DEBUGMSGTL(("inetCidrRouteTable:mfd", "error %d from "
                    "inetCidrRouteTable_undo_cleanup\n", rc));
    }

    /*
     * release undo context, if needed
     */
    if (rowreq_ctx->undo) {
        inetCidrRouteTable_release_data(rowreq_ctx->undo);
        rowreq_ctx->undo = NULL;
    }


    return SNMP_ERR_NOERROR;
}                               /* _mfd_inetCidrRouteTable_undo_cleanup */

/*----------------------------------------------------------------------
 *
 * SET: Set values
 *
 *---------------------------------------------------------------------*/
/*
 * @internal
 * Set the value for a particular column
 */
NETSNMP_STATIC_INLINE int
_inetCidrRouteTable_set_column(inetCidrRouteTable_rowreq_ctx * rowreq_ctx,
                               netsnmp_variable_list * var, int column)
{
    int             rc = SNMPERR_SUCCESS;

    DEBUGMSGTL(("internal:inetCidrRouteTable:_inetCidrRouteTable_set_column", "called for %d\n", column));

    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

        /*
         * inetCidrRouteIfIndex(7)/InterfaceIndexOrZero/ASN_INTEGER/long(long)//l/A/W/e/R/d/H 
         */
    case COLUMN_INETCIDRROUTEIFINDEX:
        rowreq_ctx->column_set_flags |= COLUMN_INETCIDRROUTEIFINDEX_FLAG;
        rc = inetCidrRouteIfIndex_set(rowreq_ctx,
                                      *((long *) var->val.string));
        break;

        /*
         * inetCidrRouteType(8)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_INETCIDRROUTETYPE:
        rowreq_ctx->column_set_flags |= COLUMN_INETCIDRROUTETYPE_FLAG;
        rc = inetCidrRouteType_set(rowreq_ctx,
                                   *((u_long *) var->val.string));
        break;

        /*
         * inetCidrRouteNextHopAS(11)/InetAutonomousSystemNumber/ASN_UNSIGNED/u_long(u_long)//l/A/W/e/r/D/H 
         */
    case COLUMN_INETCIDRROUTENEXTHOPAS:
        rowreq_ctx->column_set_flags |= COLUMN_INETCIDRROUTENEXTHOPAS_FLAG;
        rc = inetCidrRouteNextHopAS_set(rowreq_ctx,
                                        *((u_long *) var->val.string));
        break;

        /*
         * inetCidrRouteMetric1(12)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_INETCIDRROUTEMETRIC1:
        rowreq_ctx->column_set_flags |= COLUMN_INETCIDRROUTEMETRIC1_FLAG;
        rc = inetCidrRouteMetric1_set(rowreq_ctx,
                                      *((long *) var->val.string));
        break;

        /*
         * inetCidrRouteMetric2(13)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_INETCIDRROUTEMETRIC2:
        rowreq_ctx->column_set_flags |= COLUMN_INETCIDRROUTEMETRIC2_FLAG;
        rc = inetCidrRouteMetric2_set(rowreq_ctx,
                                      *((long *) var->val.string));
        break;

        /*
         * inetCidrRouteMetric3(14)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_INETCIDRROUTEMETRIC3:
        rowreq_ctx->column_set_flags |= COLUMN_INETCIDRROUTEMETRIC3_FLAG;
        rc = inetCidrRouteMetric3_set(rowreq_ctx,
                                      *((long *) var->val.string));
        break;

        /*
         * inetCidrRouteMetric4(15)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_INETCIDRROUTEMETRIC4:
        rowreq_ctx->column_set_flags |= COLUMN_INETCIDRROUTEMETRIC4_FLAG;
        rc = inetCidrRouteMetric4_set(rowreq_ctx,
                                      *((long *) var->val.string));
        break;

        /*
         * inetCidrRouteMetric5(16)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_INETCIDRROUTEMETRIC5:
        rowreq_ctx->column_set_flags |= COLUMN_INETCIDRROUTEMETRIC5_FLAG;
        rc = inetCidrRouteMetric5_set(rowreq_ctx,
                                      *((long *) var->val.string));
        break;

        /*
         * inetCidrRouteStatus(17)/RowStatus/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_INETCIDRROUTESTATUS:
        rowreq_ctx->column_set_flags |= COLUMN_INETCIDRROUTESTATUS_FLAG;
        rc = inetCidrRouteStatus_set(rowreq_ctx,
                                     *((u_long *) var->val.string));
        break;

    default:
        snmp_log(LOG_ERR,
                 "unknown column %d in _inetCidrRouteTable_set_column\n",
                 column);
        rc = SNMP_ERR_GENERR;
        break;
    }

    return rc;
}                               /* _inetCidrRouteTable_set_column */

int
_mfd_inetCidrRouteTable_set_values(netsnmp_mib_handler *handler,
                                   netsnmp_handler_registration *reginfo,
                                   netsnmp_agent_request_info *agtreq_info,
                                   netsnmp_request_info *requests)
{
    inetCidrRouteTable_rowreq_ctx *rowreq_ctx = (inetCidrRouteTable_rowreq_ctx*)
        netsnmp_container_table_row_extract(requests);
    netsnmp_table_request_info *tri;
    int             rc = SNMP_ERR_NOERROR;

    DEBUGMSGTL(("internal:inetCidrRouteTable:_mfd_inetCidrRouteTable_set_values", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    rowreq_ctx->column_set_flags = 0;
    for (; requests; requests = requests->next) {
        /*
         * set column data
         */
        tri = netsnmp_extract_table_info(requests);
        if (NULL == tri)
            continue;

        rc = _inetCidrRouteTable_set_column(rowreq_ctx,
                                            requests->requestvb,
                                            tri->colnum);
        if (MFD_SUCCESS != rc) {
            DEBUGMSGTL(("inetCidrRouteTable:mfd", "error %d from "
                        "inetCidrRouteTable_set_column\n", rc));
            netsnmp_set_request_error(agtreq_info, requests,
                                      SNMP_VALIDATE_ERR(rc));
        }
    }                           /* for results */

    return SNMP_ERR_NOERROR;
}                               /* _mfd_inetCidrRouteTable_set_values */

/*----------------------------------------------------------------------
 *
 * SET: commit
 *
 *---------------------------------------------------------------------*/
/**
 * @internal
 * commit the values
 */
int
_mfd_inetCidrRouteTable_commit(netsnmp_mib_handler *handler,
                               netsnmp_handler_registration *reginfo,
                               netsnmp_agent_request_info *agtreq_info,
                               netsnmp_request_info *requests)
{
    int             rc;
    inetCidrRouteTable_rowreq_ctx *rowreq_ctx = (inetCidrRouteTable_rowreq_ctx*)
        netsnmp_container_table_row_extract(requests);

    DEBUGMSGTL(("internal:inetCidrRouteTable:_mfd_inetCidrRouteTable_commit", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    rc = inetCidrRouteTable_commit(rowreq_ctx);
    if (MFD_SUCCESS != rc) {
        DEBUGMSGTL(("inetCidrRouteTable:mfd", "error %d from "
                    "inetCidrRouteTable_commit\n", rc));
        netsnmp_request_set_error_all(requests, SNMP_VALIDATE_ERR(rc));
    }

    if (rowreq_ctx->rowreq_flags & MFD_ROW_DIRTY) {
        /*
         * if we successfully commited this row, set the dirty flag. Use the
         * current value + 1 (i.e. dirty = # rows changed).
         * this is checked in post_request...
         */
        inetCidrRouteTable_dirty_set(inetCidrRouteTable_dirty_get() + 1);       /* set table dirty flag */
    }

    return SNMP_ERR_NOERROR;
}

int
_mfd_inetCidrRouteTable_undo_commit(netsnmp_mib_handler *handler,
                                    netsnmp_handler_registration *reginfo,
                                    netsnmp_agent_request_info
                                    *agtreq_info,
                                    netsnmp_request_info *requests)
{
    int             rc;
    inetCidrRouteTable_rowreq_ctx *rowreq_ctx = (inetCidrRouteTable_rowreq_ctx*)
        netsnmp_container_table_row_extract(requests);

    DEBUGMSGTL(("internal:inetCidrRouteTable:_mfd_inetCidrRouteTable_undo_commit", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    if (rowreq_ctx->rowreq_flags & MFD_ROW_DIRTY) {
        u_int           d = inetCidrRouteTable_dirty_get();

        netsnmp_assert(d != 0);
        if (d)
            inetCidrRouteTable_dirty_set(d - 1);
    }

    rc = inetCidrRouteTable_undo_commit(rowreq_ctx);
    if (MFD_SUCCESS != rc) {
        /*
         * nothing we can do about it but log it
         */
        DEBUGMSGTL(("inetCidrRouteTable:mfd", "error %d from "
                    "inetCidrRouteTable_undo_commit\n", rc));
    }

    if (rowreq_ctx->rowreq_flags & MFD_ROW_DIRTY) {
        snmp_log(LOG_WARNING,
                 "inetCidrRouteTable row dirty flag still set after undo_commit\n");
        rowreq_ctx->rowreq_flags &= ~MFD_ROW_DIRTY;
    }

    return SNMP_ERR_NOERROR;
}                               /* _mfd_inetCidrRouteTable_commit */

/*----------------------------------------------------------------------
 *
 * SET: Undo
 *
 *---------------------------------------------------------------------*/
int
_mfd_inetCidrRouteTable_undo_values(netsnmp_mib_handler *handler,
                                    netsnmp_handler_registration *reginfo,
                                    netsnmp_agent_request_info
                                    *agtreq_info,
                                    netsnmp_request_info *requests)
{
    int             rc;
    inetCidrRouteTable_rowreq_ctx *rowreq_ctx = (inetCidrRouteTable_rowreq_ctx*)
        netsnmp_container_table_row_extract(requests);

    DEBUGMSGTL(("internal:inetCidrRouteTable:_mfd_inetCidrRouteTable_undo_values", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    rc = inetCidrRouteTable_undo(rowreq_ctx);
    if (MFD_SUCCESS != rc) {
        /*
         * nothing we can do about it but log it
         */
        DEBUGMSGTL(("inetCidrRouteTable:mfd", "error %d from "
                    "inetCidrRouteTable_undo\n", rc));
    }

    return SNMP_ERR_NOERROR;
}                               /* _mfd_inetCidrRouteTable_undo_values */

/*----------------------------------------------------------------------
 *
 * SET: irreversible commit
 *
 *---------------------------------------------------------------------*/
/**
 * @internal
 * commit irreversible actions
 */
int
_mfd_inetCidrRouteTable_irreversible_commit(netsnmp_mib_handler *handler, netsnmp_handler_registration
                                            *reginfo, netsnmp_agent_request_info
                                            *agtreq_info,
                                            netsnmp_request_info *requests)
{
    inetCidrRouteTable_rowreq_ctx *rowreq_ctx = (inetCidrRouteTable_rowreq_ctx*)
        netsnmp_container_table_row_extract(requests);

    DEBUGMSGTL(("internal:inetCidrRouteTable:_mfd_inetCidrRouteTable_irreversible:commit", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * check for and handle row creation/deletion
     * and update column exist flags...
     */
    if (rowreq_ctx->rowreq_flags & MFD_ROW_DELETED) {
        if (!(rowreq_ctx->rowreq_flags & MFD_ROW_CREATED))
            CONTAINER_REMOVE(inetCidrRouteTable_if_ctx.container, rowreq_ctx);
    } else {
        if (rowreq_ctx->column_set_flags) {
            rowreq_ctx->column_set_flags = 0;
        }
        if (rowreq_ctx->rowreq_flags & MFD_ROW_CREATED) {
            rowreq_ctx->rowreq_flags &= ~MFD_ROW_CREATED;
            CONTAINER_INSERT(inetCidrRouteTable_if_ctx.container,
                             rowreq_ctx);
        }
    }

    return SNMP_ERR_NOERROR;
}                               /* _mfd_inetCidrRouteTable_irreversible_commit */
#endif /* NETSNMP_NO_WRITE_SUPPORT || NETSNMP_DISABLE_SET_SUPPORT */

/***********************************************************************
 *
 * DATA ACCESS
 *
 ***********************************************************************/
static void     _container_free(netsnmp_container *container);

/**
 * @internal
 */
static int
_cache_load(netsnmp_cache * cache, void *vmagic)
{
    DEBUGMSGTL(("internal:inetCidrRouteTable:_cache_load", "called\n"));

    if ((NULL == cache) || (NULL == cache->magic)) {
        snmp_log(LOG_ERR,
                 "invalid cache for inetCidrRouteTable_cache_load\n");
        return -1;
    }

    /** should only be called for an invalid or expired cache */
    netsnmp_assert((0 == cache->valid) || (1 == cache->expired));

    /*
     * call user code
     */
    return inetCidrRouteTable_container_load((netsnmp_container *) cache->
                                             magic);
}                               /* _cache_load */

/**
 * @internal
 */
static void
_cache_free(netsnmp_cache * cache, void *magic)
{
    netsnmp_container *container;

    DEBUGMSGTL(("internal:inetCidrRouteTable:_cache_free", "called\n"));

    if ((NULL == cache) || (NULL == cache->magic)) {
        snmp_log(LOG_ERR,
                 "invalid cache in inetCidrRouteTable_cache_free\n");
        return;
    }

    container = (netsnmp_container *) cache->magic;

    _container_free(container);
}                               /* _cache_free */

/**
 * @internal
 */
static void
_container_item_free(inetCidrRouteTable_rowreq_ctx * rowreq_ctx,
                     void *context)
{
    DEBUGMSGTL(("internal:inetCidrRouteTable:_container_item_free",
                "called\n"));

    if (NULL == rowreq_ctx)
        return;

    inetCidrRouteTable_release_rowreq_ctx(rowreq_ctx);
}                               /* _container_item_free */

/**
 * @internal
 */
static void
_container_free(netsnmp_container *container)
{
    DEBUGMSGTL(("internal:inetCidrRouteTable:_container_free",
                "called\n"));

    if (NULL == container) {
        snmp_log(LOG_ERR,
                 "invalid container in inetCidrRouteTable_container_free\n");
        return;
    }

    /*
     * call user code
     */
    inetCidrRouteTable_container_free(container);

    /*
     * free all items. inefficient, but easy.
     */
    CONTAINER_CLEAR(container,
                    (netsnmp_container_obj_func *) _container_item_free,
                    NULL);
}                               /* _container_free */

/**
 * @internal
 * initialize the container with functions or wrappers
 */
void
_inetCidrRouteTable_container_init(inetCidrRouteTable_interface_ctx *
                                   if_ctx)
{
    DEBUGMSGTL(("internal:inetCidrRouteTable:_inetCidrRouteTable_container_init", "called\n"));

    /*
     * cache init
     */
    if_ctx->cache = netsnmp_cache_create(INETCIDRROUTETABLE_CACHE_TIMEOUT,
                                         _cache_load, _cache_free,
                                         inetCidrRouteTable_oid,
                                         inetCidrRouteTable_oid_size);

    if (NULL == if_ctx->cache) {
        snmp_log(LOG_ERR, "error creating cache for ipCidrRouteTable\n");
        return;
    }

    if_ctx->cache->flags = NETSNMP_CACHE_DONT_INVALIDATE_ON_SET;

    inetCidrRouteTable_container_init(&if_ctx->container, if_ctx->cache);
    if (NULL == if_ctx->container) {
        if_ctx->container =
            netsnmp_container_find("inetCidrRouteTable:table_container");
        if (NULL == if_ctx->container) {
            snmp_log(LOG_ERR, "error creating container in "
                     "inetCidrRouteTable_container_init\n");
            return;
        }
    }

    if_ctx->container->container_name = strdup("inetCidrRouteTable");

   /* set allow duplicates this makes insert O(1) */
   netsnmp_binary_array_options_set(if_ctx->container, 1,
                                    CONTAINER_KEY_ALLOW_DUPLICATES);

    if (NULL != if_ctx->cache)
        if_ctx->cache->magic = (void *) if_ctx->container;
}                               /* _inetCidrRouteTable_container_init */

/**
 * @internal
 * shutdown the container with functions or wrappers
 */
void
_inetCidrRouteTable_container_shutdown(inetCidrRouteTable_interface_ctx *
                                       if_ctx)
{
    DEBUGMSGTL(("internal:inetCidrRouteTable:_inetCidrRouteTable_container_shutdown", "called\n"));

    inetCidrRouteTable_container_shutdown(if_ctx->container);

    _container_free(if_ctx->container);

}                               /* _inetCidrRouteTable_container_shutdown */


#ifndef NETSNMP_FEATURE_REMOVE_INETCIDRROUTETABLE_EXTERNAL_ACCESS
inetCidrRouteTable_rowreq_ctx *
inetCidrRouteTable_row_find_by_mib_index(inetCidrRouteTable_mib_index *
                                         mib_idx)
{
    inetCidrRouteTable_rowreq_ctx *rowreq_ctx;
    oid             oid_tmp[MAX_OID_LEN];
    netsnmp_index   oid_idx;
    int             rc;

    /*
     * set up storage for OID
     */
    oid_idx.oids = oid_tmp;
    oid_idx.len = sizeof(oid_tmp) / sizeof(oid);

    /*
     * convert
     */
    rc = inetCidrRouteTable_index_to_oid(&oid_idx, mib_idx);
    if (MFD_SUCCESS != rc)
        return NULL;

    rowreq_ctx = (inetCidrRouteTable_rowreq_ctx*)
        CONTAINER_FIND(inetCidrRouteTable_if_ctx.container, &oid_idx);

    return rowreq_ctx;
}
#endif /* NETSNMP_FEATURE_REMOVE_INETCIDRROUTETABLE_EXTERNAL_ACCESS */
