/*
 * 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;

    /*
     * (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 */
