/*
 * 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-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>

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


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

#include "ipCidrRouteTable_interface.h"

#include <ctype.h>

/**********************************************************************
 **********************************************************************
 ***
 *** Table ipCidrRouteTable
 ***
 **********************************************************************
 **********************************************************************/
/*
 * IP-FORWARD-MIB::ipCidrRouteTable is subid 4 of ipForward.
 * Its status is Deprecated.
 * OID: .1.3.6.1.2.1.4.24.4, length: 9
 */
typedef struct ipCidrRouteTable_interface_ctx_s {

    netsnmp_container *container;
    netsnmp_cache  *cache;

    ipCidrRouteTable_registration *user_ctx;

    netsnmp_table_registration_info tbl_info;

    netsnmp_baby_steps_access_methods access_multiplexer;

    u_int           table_dirty;

} ipCidrRouteTable_interface_ctx;

static ipCidrRouteTable_interface_ctx ipCidrRouteTable_if_ctx;

static void
                _ipCidrRouteTable_container_init(ipCidrRouteTable_interface_ctx * if_ctx);
static void
                _ipCidrRouteTable_container_shutdown(ipCidrRouteTable_interface_ctx *
                                                     if_ctx);


netsnmp_container *
ipCidrRouteTable_container_get(void)
{
    return ipCidrRouteTable_if_ctx.container;
}

ipCidrRouteTable_registration *
ipCidrRouteTable_registration_get(void)
{
    return ipCidrRouteTable_if_ctx.user_ctx;
}

ipCidrRouteTable_registration *
ipCidrRouteTable_registration_set(ipCidrRouteTable_registration * newreg)
{
    ipCidrRouteTable_registration *old = ipCidrRouteTable_if_ctx.user_ctx;
    ipCidrRouteTable_if_ctx.user_ctx = newreg;
    return old;
}

int
ipCidrRouteTable_container_size(void)
{
    return CONTAINER_SIZE(ipCidrRouteTable_if_ctx.container);
}

u_int
ipCidrRouteTable_dirty_get(void)
{
    return ipCidrRouteTable_if_ctx.table_dirty;
}

void
ipCidrRouteTable_dirty_set(u_int status)
{
    DEBUGMSGTL(("ipCidrRouteTable:ipCidrRouteTable_dirty_set",
                "called. was %d, now %d\n",
                ipCidrRouteTable_if_ctx.table_dirty, status));
    ipCidrRouteTable_if_ctx.table_dirty = status;
}

/*
 * mfd multiplexer modes
 */
static Netsnmp_Node_Handler _mfd_ipCidrRouteTable_pre_request;
static Netsnmp_Node_Handler _mfd_ipCidrRouteTable_post_request;
static Netsnmp_Node_Handler _mfd_ipCidrRouteTable_object_lookup;
static Netsnmp_Node_Handler _mfd_ipCidrRouteTable_get_values;
#ifndef NETSNMP_DISABLE_SET_SUPPORT
static Netsnmp_Node_Handler _mfd_ipCidrRouteTable_check_objects;
static Netsnmp_Node_Handler _mfd_ipCidrRouteTable_undo_setup;
static Netsnmp_Node_Handler _mfd_ipCidrRouteTable_set_values;
static Netsnmp_Node_Handler _mfd_ipCidrRouteTable_undo_cleanup;
static Netsnmp_Node_Handler _mfd_ipCidrRouteTable_undo_values;
static Netsnmp_Node_Handler _mfd_ipCidrRouteTable_commit;
static Netsnmp_Node_Handler _mfd_ipCidrRouteTable_undo_commit;
static Netsnmp_Node_Handler _mfd_ipCidrRouteTable_irreversible_commit;

NETSNMP_STATIC_INLINE int
                _ipCidrRouteTable_undo_column(ipCidrRouteTable_rowreq_ctx * rowreq_ctx,
                                              netsnmp_variable_list * var,
                                              int column);
#endif

NETSNMP_STATIC_INLINE int
                _ipCidrRouteTable_check_indexes(ipCidrRouteTable_rowreq_ctx * rowreq_ctx);

/**
 * @internal
 * Initialize the table ipCidrRouteTable 
 *    (Define its contents and how it's structured)
 */
void
_ipCidrRouteTable_initialize_interface(ipCidrRouteTable_registration *
                                       reg_ptr, u_long flags)
{
    netsnmp_baby_steps_access_methods *access_multiplexer =
        &ipCidrRouteTable_if_ctx.access_multiplexer;
    netsnmp_table_registration_info *tbl_info =
        &ipCidrRouteTable_if_ctx.tbl_info;
    netsnmp_handler_registration *reginfo;
    netsnmp_mib_handler *handler;
    int             mfd_modes = 0;

    DEBUGMSGTL(("internal:ipCidrRouteTable:_ipCidrRouteTable_initialize_interface", "called\n"));


    /*************************************************
     *
     * save interface context for ipCidrRouteTable
     */
    /*
     * Setting up the table's definition
     */
    netsnmp_table_helper_add_indexes(tbl_info, ASN_IPADDRESS,
                                                 /** index: ipCidrRouteDest */
                                     ASN_IPADDRESS,
                                                 /** index: ipCidrRouteMask */
                                     ASN_INTEGER,
                                               /** index: ipCidrRouteTos */
                                     ASN_IPADDRESS,
                                                 /** index: ipCidrRouteNextHop */
                                     0);

    /*
     * Define the minimum and maximum accessible columns.  This
     * optimizes retrival. 
     */
    tbl_info->min_column = IPCIDRROUTETABLE_MIN_COL;
    tbl_info->max_column = IPCIDRROUTETABLE_MAX_COL;

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

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

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

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

    /*
     * no wrappers yet
     */
    access_multiplexer->pre_request = _mfd_ipCidrRouteTable_pre_request;
    access_multiplexer->post_request = _mfd_ipCidrRouteTable_post_request;


#ifndef NETSNMP_DISABLE_SET_SUPPORT
    /*
     * REQUIRED wrappers for set request handling
     */
    access_multiplexer->object_syntax_checks =
        _mfd_ipCidrRouteTable_check_objects;
    access_multiplexer->undo_setup = _mfd_ipCidrRouteTable_undo_setup;
    access_multiplexer->undo_cleanup = _mfd_ipCidrRouteTable_undo_cleanup;
    access_multiplexer->set_values = _mfd_ipCidrRouteTable_set_values;
    access_multiplexer->undo_sets = _mfd_ipCidrRouteTable_undo_values;

    /*
     * no wrappers yet
     */
    access_multiplexer->commit = _mfd_ipCidrRouteTable_commit;
    access_multiplexer->undo_commit = _mfd_ipCidrRouteTable_undo_commit;
    access_multiplexer->irreversible_commit =
        _mfd_ipCidrRouteTable_irreversible_commit;
#endif

    /*************************************************
     *
     * Create a registration, save our reg data, register table.
     */
    DEBUGMSGTL(("ipCidrRouteTable:init_ipCidrRouteTable",
                "Registering ipCidrRouteTable as a mibs-for-dummies table.\n"));
    handler =
        netsnmp_baby_steps_access_multiplexer_get(access_multiplexer);
    reginfo =
        netsnmp_handler_registration_create("ipCidrRouteTable", handler,
                                            ipCidrRouteTable_oid,
                                            ipCidrRouteTable_oid_size,
                                            HANDLER_CAN_BABY_STEP |
                                            HANDLER_CAN_RONLY);
    if (NULL == reginfo) {
        snmp_log(LOG_ERR, "error registering table ipCidrRouteTable\n");
        return;
    }
    reginfo->my_reg_void = &ipCidrRouteTable_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;

#ifndef 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

    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,
                                            ipCidrRouteTable_if_ctx.
                                            container,
                                            TABLE_CONTAINER_KEY_NETSNMP_INDEX);
    netsnmp_inject_handler(reginfo, handler);

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

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

}                               /* _ipCidrRouteTable_initialize_interface */

/**
 * @internal
 * Shutdown the table ipCidrRouteTable
 */
void
_ipCidrRouteTable_shutdown_interface(ipCidrRouteTable_registration *
                                     reg_ptr)
{
    /*
     * shutdown the container
     */
    _ipCidrRouteTable_container_shutdown(&ipCidrRouteTable_if_ctx);
}

void
ipCidrRouteTable_valid_columns_set(netsnmp_column_info *vc)
{
    ipCidrRouteTable_if_ctx.tbl_info.valid_columns = vc;
}                               /* ipCidrRouteTable_valid_columns_set */

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

    /*
     * temp storage for parsing indexes
     */
    /*
     * ipCidrRouteDest(1)/IPADDR/ASN_IPADDRESS/u_long(u_long)//l/A/w/e/r/d/h
     */
    netsnmp_variable_list var_ipCidrRouteDest;
    /*
     * ipCidrRouteMask(2)/IPADDR/ASN_IPADDRESS/u_long(u_long)//l/A/w/e/r/d/h
     */
    netsnmp_variable_list var_ipCidrRouteMask;
    /*
     * ipCidrRouteTos(3)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/R/d/h
     */
    netsnmp_variable_list var_ipCidrRouteTos;
    /*
     * ipCidrRouteNextHop(4)/IPADDR/ASN_IPADDRESS/u_long(u_long)//l/A/w/e/r/d/h
     */
    netsnmp_variable_list var_ipCidrRouteNextHop;

    /*
     * set up varbinds
     */
    memset(&var_ipCidrRouteDest, 0x00, sizeof(var_ipCidrRouteDest));
    var_ipCidrRouteDest.type = ASN_PRIV_IMPLIED_OCTET_STR;
    memset(&var_ipCidrRouteMask, 0x00, sizeof(var_ipCidrRouteMask));
    var_ipCidrRouteMask.type = ASN_PRIV_IMPLIED_OCTET_STR;
    memset(&var_ipCidrRouteTos, 0x00, sizeof(var_ipCidrRouteTos));
    var_ipCidrRouteTos.type = ASN_INTEGER;
    memset(&var_ipCidrRouteNextHop, 0x00, sizeof(var_ipCidrRouteNextHop));
    var_ipCidrRouteNextHop.type = ASN_PRIV_IMPLIED_OCTET_STR;

    /*
     * chain temp index varbinds together
     */
    var_ipCidrRouteDest.next_variable = &var_ipCidrRouteMask;
    var_ipCidrRouteMask.next_variable = &var_ipCidrRouteTos;
    var_ipCidrRouteTos.next_variable = &var_ipCidrRouteNextHop;
    var_ipCidrRouteNextHop.next_variable = NULL;


    DEBUGMSGTL(("verbose:ipCidrRouteTable:ipCidrRouteTable_index_to_oid",
                "called\n"));

    /*
     * ipCidrRouteDest(1)/IPADDR/ASN_IPADDRESS/u_long(u_long)//l/A/w/e/r/d/h 
     */
    snmp_set_var_value(&var_ipCidrRouteDest,
                       (u_char *) & mib_idx->ipCidrRouteDest,
                       sizeof(mib_idx->ipCidrRouteDest));

    /*
     * ipCidrRouteMask(2)/IPADDR/ASN_IPADDRESS/u_long(u_long)//l/A/w/e/r/d/h 
     */
    snmp_set_var_value(&var_ipCidrRouteMask,
                       (u_char *) & mib_idx->ipCidrRouteMask,
                       sizeof(mib_idx->ipCidrRouteMask));

    /*
     * ipCidrRouteTos(3)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/R/d/h 
     */
    snmp_set_var_value(&var_ipCidrRouteTos,
                       (u_char *) & mib_idx->ipCidrRouteTos,
                       sizeof(mib_idx->ipCidrRouteTos));

    /*
     * ipCidrRouteNextHop(4)/IPADDR/ASN_IPADDRESS/u_long(u_long)//l/A/w/e/r/d/h 
     */
    snmp_set_var_value(&var_ipCidrRouteNextHop,
                       (u_char *) & mib_idx->ipCidrRouteNextHop,
                       sizeof(mib_idx->ipCidrRouteNextHop));


    err = build_oid_noalloc(oid_idx->oids, oid_idx->len, &oid_idx->len,
                            NULL, 0, &var_ipCidrRouteDest);
    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_ipCidrRouteDest);

    return err;
}                               /* ipCidrRouteTable_index_to_oid */

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

    /*
     * temp storage for parsing indexes
     */
    /*
     * ipCidrRouteDest(1)/IPADDR/ASN_IPADDRESS/u_long(u_long)//l/A/w/e/r/d/h
     */
    netsnmp_variable_list var_ipCidrRouteDest;
    /*
     * ipCidrRouteMask(2)/IPADDR/ASN_IPADDRESS/u_long(u_long)//l/A/w/e/r/d/h
     */
    netsnmp_variable_list var_ipCidrRouteMask;
    /*
     * ipCidrRouteTos(3)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/R/d/h
     */
    netsnmp_variable_list var_ipCidrRouteTos;
    /*
     * ipCidrRouteNextHop(4)/IPADDR/ASN_IPADDRESS/u_long(u_long)//l/A/w/e/r/d/h
     */
    netsnmp_variable_list var_ipCidrRouteNextHop;

    /*
     * set up varbinds
     */
    memset(&var_ipCidrRouteDest, 0x00, sizeof(var_ipCidrRouteDest));
    var_ipCidrRouteDest.type = ASN_IPADDRESS;
    memset(&var_ipCidrRouteMask, 0x00, sizeof(var_ipCidrRouteMask));
    var_ipCidrRouteMask.type = ASN_IPADDRESS;
    memset(&var_ipCidrRouteTos, 0x00, sizeof(var_ipCidrRouteTos));
    var_ipCidrRouteTos.type = ASN_INTEGER;
    memset(&var_ipCidrRouteNextHop, 0x00, sizeof(var_ipCidrRouteNextHop));
    var_ipCidrRouteNextHop.type = ASN_IPADDRESS;

    /*
     * chain temp index varbinds together
     */
    var_ipCidrRouteDest.next_variable = &var_ipCidrRouteMask;
    var_ipCidrRouteMask.next_variable = &var_ipCidrRouteTos;
    var_ipCidrRouteTos.next_variable = &var_ipCidrRouteNextHop;
    var_ipCidrRouteNextHop.next_variable = NULL;


    DEBUGMSGTL(("verbose:ipCidrRouteTable:ipCidrRouteTable_index_from_oid",
                "called\n"));

    /*
     * parse the oid into the individual index components
     */
    err = parse_oid_indexes(oid_idx->oids, oid_idx->len,
                            &var_ipCidrRouteDest);
    if (err == SNMP_ERR_NOERROR) {
        /*
         * copy out values
         */
        mib_idx->ipCidrRouteDest =
            *((u_long *) var_ipCidrRouteDest.val.string);
        mib_idx->ipCidrRouteMask =
            *((u_long *) var_ipCidrRouteMask.val.string);
        mib_idx->ipCidrRouteTos =
            *((long *) var_ipCidrRouteTos.val.string);
        mib_idx->ipCidrRouteNextHop =
            *((u_long *) var_ipCidrRouteNextHop.val.string);


    }

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

    return err;
}                               /* ipCidrRouteTable_index_from_oid */


/*
 *********************************************************************
 * @internal
 * allocate resources for a ipCidrRouteTable_rowreq_ctx
 */
ipCidrRouteTable_rowreq_ctx *
ipCidrRouteTable_allocate_rowreq_ctx(ipCidrRouteTable_data * data,
                                     void *user_init_ctx)
{
    ipCidrRouteTable_rowreq_ctx *rowreq_ctx =
        SNMP_MALLOC_TYPEDEF(ipCidrRouteTable_rowreq_ctx);

    DEBUGMSGTL(("internal:ipCidrRouteTable:ipCidrRouteTable_allocate_rowreq_ctx", "called\n"));

    if (NULL == rowreq_ctx) {
        snmp_log(LOG_ERR, "Couldn't allocate memory for a "
                 "ipCidrRouteTable_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 = ipCidrRouteTable_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->ipCidrRouteTable_data_list = NULL;

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

    return rowreq_ctx;
}                               /* ipCidrRouteTable_allocate_rowreq_ctx */

/*
 * @internal
 * release resources for a ipCidrRouteTable_rowreq_ctx
 */
void
ipCidrRouteTable_release_rowreq_ctx(ipCidrRouteTable_rowreq_ctx *
                                    rowreq_ctx)
{
    DEBUGMSGTL(("internal:ipCidrRouteTable:ipCidrRouteTable_release_rowreq_ctx", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    ipCidrRouteTable_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))
        ipCidrRouteTable_release_data(rowreq_ctx->data);

    if (rowreq_ctx->undo)
        ipCidrRouteTable_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);
}                               /* ipCidrRouteTable_release_rowreq_ctx */

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

    DEBUGMSGTL(("internal:ipCidrRouteTable:_mfd_ipCidrRouteTable_pre_request", "called\n"));

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

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_ipCidrRouteTable_pre_request */

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

    DEBUGMSGTL(("internal:ipCidrRouteTable:_mfd_ipCidrRouteTable_post_request", "called\n"));

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

    /*
     * wait for last call before calling user
     */
    if (1 != netsnmp_row_merge_status_last(reginfo, agtreq_info)) {
        DEBUGMSGTL(("internal:ipCidrRouteTable",
                    "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) && ipCidrRouteTable_dirty_get()) {
        /*
         * we shouldn't get here. the undo steps should also clear
         * the dirty flags.
         */
        snmp_log(LOG_WARNING,
                 "ipCidrRouteTable dirty flag set in post_request "
                 "but status != SUCCESS.\n");
    }

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_ipCidrRouteTable_post_request */

/**
 * @internal
 * wrapper
 */
static ipCidrRouteTable_rowreq_ctx *
_mfd_ipCidrRouteTable_rowreq_from_index(netsnmp_index * oid_idx,
                                        int *rc_ptr)
{
    ipCidrRouteTable_rowreq_ctx *rowreq_ctx;
    ipCidrRouteTable_mib_index mib_idx;
    int             rc;

    DEBUGMSGTL(("internal:ipCidrRouteTable:_mfd_ipCidrRouteTable_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 = ipCidrRouteTable_index_from_oid(oid_idx, &mib_idx);
    if (MFD_SUCCESS != *rc_ptr) {
        DEBUGMSGT(("ipCidrRouteTable", "error parsing index\n"));
        return NULL;
    }

    /*
     * allocate new context
     */
    rowreq_ctx = ipCidrRouteTable_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 = _ipCidrRouteTable_check_indexes(rowreq_ctx);
    if (MFD_SUCCESS != *rc_ptr) {
        netsnmp_assert((*rc_ptr == SNMP_ERR_NOCREATION) ||
                       (*rc_ptr == SNMP_ERR_INCONSISTENTNAME));
        ipCidrRouteTable_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_ipCidrRouteTable_rowreq_from_index */


/**
 * @internal
 * wrapper
 */
static int
_mfd_ipCidrRouteTable_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;
    ipCidrRouteTable_rowreq_ctx *rowreq_ctx =
        netsnmp_container_table_row_extract(requests);

    DEBUGMSGTL(("internal:ipCidrRouteTable:_mfd_ipCidrRouteTable_object_lookup", "called\n"));

    /*
     * get our context from mfd
     * ipCidrRouteTable_interface_ctx *if_ctx =
     *             (ipCidrRouteTable_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_ipCidrRouteTable_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
        ipCidrRouteTable_row_prep(rowreq_ctx);

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

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

    DEBUGMSGTL(("internal:ipCidrRouteTable:_mfd_ipCidrRouteTable_get_column", "called for %d\n", column));


    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

        /*
         * (INDEX) ipCidrRouteDest(1)/IPADDR/ASN_IPADDRESS/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IPCIDRROUTEDEST:
        var->type = ASN_IPADDRESS;
        var->val_len = sizeof(in_addr_t);
        memcpy(var->val.integer, &rowreq_ctx->tbl_idx.ipCidrRouteDest, sizeof(in_addr_t));
        break;

        /*
         * (INDEX) ipCidrRouteMask(2)/IPADDR/ASN_IPADDRESS/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IPCIDRROUTEMASK:
        var->type = ASN_IPADDRESS;
        var->val_len = sizeof(in_addr_t);
        memcpy(var->val.integer, &rowreq_ctx->tbl_idx.ipCidrRouteMask, sizeof(in_addr_t));
        break;

        /*
         * (INDEX) ipCidrRouteTos(3)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/R/d/h 
         */
    case COLUMN_IPCIDRROUTETOS:
        var->type = ASN_INTEGER;
        var->val_len = sizeof(long);
        (*var->val.integer) = rowreq_ctx->tbl_idx.ipCidrRouteTos;
        break;

        /*
         * (INDEX) ipCidrRouteNextHop(4)/IPADDR/ASN_IPADDRESS/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IPCIDRROUTENEXTHOP:
        var->type = ASN_IPADDRESS;
        var->val_len = sizeof(in_addr_t);
        memcpy(var->val.integer, &rowreq_ctx->tbl_idx.ipCidrRouteNextHop, sizeof(in_addr_t));
        break;

        /*
         * ipCidrRouteIfIndex(5)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_IPCIDRROUTEIFINDEX:
        var->val_len = sizeof(long);
        var->type = ASN_INTEGER;
        rc = ipCidrRouteIfIndex_get(rowreq_ctx, (long *) var->val.string);
        break;

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

        /*
         * ipCidrRouteProto(7)/INTEGER/ASN_INTEGER/long(u_long)//l/A/w/E/r/d/h 
         */
    case COLUMN_IPCIDRROUTEPROTO:
        var->val_len = sizeof(u_long);
        var->type = ASN_INTEGER;
        rc = ipCidrRouteProto_get(rowreq_ctx, (u_long *) var->val.string);
        break;

        /*
         * ipCidrRouteAge(8)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/r/D/h 
         */
    case COLUMN_IPCIDRROUTEAGE:
        var->val_len = sizeof(long);
        var->type = ASN_INTEGER;
        rc = ipCidrRouteAge_get(rowreq_ctx, (long *) var->val.string);
        break;

        /*
         * ipCidrRouteInfo(9)/OBJECTID/ASN_OBJECT_ID/oid(oid)//L/A/W/e/r/d/h 
         */
    case COLUMN_IPCIDRROUTEINFO:
        var->type = ASN_OBJECT_ID;
        rc = ipCidrRouteInfo_get(rowreq_ctx, (oid **) & var->val.string,
                                 &var->val_len);
        break;

        /*
         * ipCidrRouteNextHopAS(10)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_IPCIDRROUTENEXTHOPAS:
        var->val_len = sizeof(long);
        var->type = ASN_INTEGER;
        rc = ipCidrRouteNextHopAS_get(rowreq_ctx,
                                      (long *) var->val.string);
        break;

        /*
         * ipCidrRouteMetric1(11)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_IPCIDRROUTEMETRIC1:
        var->val_len = sizeof(long);
        var->type = ASN_INTEGER;
        rc = ipCidrRouteMetric1_get(rowreq_ctx, (long *) var->val.string);
        break;

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

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

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

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

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

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

    return rc;
}                               /* _ipCidrRouteTable_get_column */

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

    DEBUGMSGTL(("internal:ipCidrRouteTable:_mfd_ipCidrRouteTable_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 = _ipCidrRouteTable_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_ipCidrRouteTable_get_values */

NETSNMP_STATIC_INLINE int
_ipCidrRouteTable_check_indexes(ipCidrRouteTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = SNMPERR_SUCCESS;

    DEBUGMSGTL(("internal:ipCidrRouteTable:_ipCidrRouteTable_check_indexes", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);


    /*
     * (INDEX) ipCidrRouteDest(1)/IPADDR/ASN_IPADDRESS/u_long(u_long)//l/A/w/e/r/d/h 
     */
    if (MFD_SUCCESS != rc)
        return rc;
    rc = ipCidrRouteDest_check_index(rowreq_ctx);
    if (MFD_SUCCESS != rc)
        return SNMP_ERR_NOCREATION;

    /*
     * (INDEX) ipCidrRouteMask(2)/IPADDR/ASN_IPADDRESS/u_long(u_long)//l/A/w/e/r/d/h 
     */
    if (MFD_SUCCESS != rc)
        return rc;
    rc = ipCidrRouteMask_check_index(rowreq_ctx);
    if (MFD_SUCCESS != rc)
        return SNMP_ERR_NOCREATION;

    /*
     * (INDEX) ipCidrRouteTos(3)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/R/d/h 
     */
    /*
     * check defined range(s). 
     */
    if ((SNMPERR_SUCCESS == rc)
        && ((rowreq_ctx->tbl_idx.ipCidrRouteTos < 0)
            || (rowreq_ctx->tbl_idx.ipCidrRouteTos > 2147483647))
        ) {
        rc = SNMP_ERR_WRONGVALUE;
    }
    if (MFD_SUCCESS != rc)
        return rc;
    rc = ipCidrRouteTos_check_index(rowreq_ctx);
    if (MFD_SUCCESS != rc)
        return SNMP_ERR_NOCREATION;

    /*
     * (INDEX) ipCidrRouteNextHop(4)/IPADDR/ASN_IPADDRESS/u_long(u_long)//l/A/w/e/r/d/h 
     */
    if (MFD_SUCCESS != rc)
        return rc;
    rc = ipCidrRouteNextHop_check_index(rowreq_ctx);
    if (MFD_SUCCESS != rc)
        return SNMP_ERR_NOCREATION;

    /*
     * if individual parts look ok, check them as a whole
     */
    return ipCidrRouteTable_validate_index(ipCidrRouteTable_if_ctx.
                                           user_ctx, rowreq_ctx);
}                               /* _ipCidrRouteTable_check_indexes */

#ifndef NETSNMP_DISABLE_SET_SUPPORT
/***********************************************************************
 *
 * SET processing
 *
 ***********************************************************************/

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

    DEBUGMSGTL(("internal:ipCidrRouteTable:_ipCidrRouteTable_check_column",
                "called for %d\n", column));

    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {
        /*
         * (INDEX) ipCidrRouteDest(1)/IPADDR/ASN_IPADDRESS/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IPCIDRROUTEDEST:
        rc = SNMP_ERR_NOTWRITABLE;      /* can not change index of active row */
        break;
        /*
         * (INDEX) ipCidrRouteMask(2)/IPADDR/ASN_IPADDRESS/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IPCIDRROUTEMASK:
        rc = SNMP_ERR_NOTWRITABLE;      /* can not change index of active row */
        break;
        /*
         * (INDEX) ipCidrRouteTos(3)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/R/d/h 
         */
    case COLUMN_IPCIDRROUTETOS:
        rc = SNMP_ERR_NOTWRITABLE;      /* can not change index of active row */
        break;
        /*
         * (INDEX) ipCidrRouteNextHop(4)/IPADDR/ASN_IPADDRESS/u_long(u_long)//l/A/w/e/r/d/h 
         */
    case COLUMN_IPCIDRROUTENEXTHOP:
        rc = SNMP_ERR_NOTWRITABLE;      /* can not change index of active row */
        break;

        /*
         * ipCidrRouteIfIndex(5)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_IPCIDRROUTEIFINDEX:
        rc = netsnmp_check_vb_type(var, ASN_INTEGER);
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("ipCidrRouteTable:_ipCidrRouteTable_check_column:ipCidrRouteIfIndex", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = ipCidrRouteIfIndex_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 ipCidrRouteIfIndex_check_value\n",
                         rc);
                rc = SNMP_ERR_GENERR;
            }
        }
        break;

        /*
         * ipCidrRouteType(6)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_IPCIDRROUTETYPE:
        rc = netsnmp_check_vb_type(var, ASN_INTEGER);
        /*
         * check that the value is one of defined enums 
         */
        if ((SNMPERR_SUCCESS == rc)
            && (*var->val.integer != IPCIDRROUTETYPE_OTHER)
            && (*var->val.integer != IPCIDRROUTETYPE_REJECT)
            && (*var->val.integer != IPCIDRROUTETYPE_LOCAL)
            && (*var->val.integer != IPCIDRROUTETYPE_REMOTE)
            ) {
            rc = SNMP_ERR_WRONGVALUE;
        }
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("ipCidrRouteTable:_ipCidrRouteTable_check_column:ipCidrRouteType", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = ipCidrRouteType_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 ipCidrRouteType_check_value\n",
                         rc);
                rc = SNMP_ERR_GENERR;
            }
        }
        break;

        /*
         * ipCidrRouteProto(7)/INTEGER/ASN_INTEGER/long(u_long)//l/A/w/E/r/d/h 
         */
    case COLUMN_IPCIDRROUTEPROTO:
        rc = SNMP_ERR_NOTWRITABLE;
        break;

        /*
         * ipCidrRouteAge(8)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/r/D/h 
         */
    case COLUMN_IPCIDRROUTEAGE:
        rc = SNMP_ERR_NOTWRITABLE;
        break;

        /*
         * ipCidrRouteInfo(9)/OBJECTID/ASN_OBJECT_ID/oid(oid)//L/A/W/e/r/d/h 
         */
    case COLUMN_IPCIDRROUTEINFO:
        rc = netsnmp_check_vb_type(var, ASN_OBJECT_ID);
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("ipCidrRouteTable:_ipCidrRouteTable_check_column:ipCidrRouteInfo", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = ipCidrRouteInfo_check_value(rowreq_ctx,
                                             (oid *) var->val.string,
                                             var->val_len);
            if ((MFD_SUCCESS != rc) && (MFD_NOT_VALID_EVER != rc)
                && (MFD_NOT_VALID_NOW != rc)) {
                snmp_log(LOG_ERR,
                         "bad rc %d from ipCidrRouteInfo_check_value\n",
                         rc);
                rc = SNMP_ERR_GENERR;
            }
        }
        break;

        /*
         * ipCidrRouteNextHopAS(10)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_IPCIDRROUTENEXTHOPAS:
        rc = netsnmp_check_vb_type(var, ASN_INTEGER);
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("ipCidrRouteTable:_ipCidrRouteTable_check_column:ipCidrRouteNextHopAS", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = ipCidrRouteNextHopAS_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 ipCidrRouteNextHopAS_check_value\n",
                         rc);
                rc = SNMP_ERR_GENERR;
            }
        }
        break;

        /*
         * ipCidrRouteMetric1(11)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_IPCIDRROUTEMETRIC1:
        rc = netsnmp_check_vb_type(var, ASN_INTEGER);
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("ipCidrRouteTable:_ipCidrRouteTable_check_column:ipCidrRouteMetric1", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = ipCidrRouteMetric1_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 ipCidrRouteMetric1_check_value\n",
                         rc);
                rc = SNMP_ERR_GENERR;
            }
        }
        break;

        /*
         * ipCidrRouteMetric2(12)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_IPCIDRROUTEMETRIC2:
        rc = netsnmp_check_vb_type(var, ASN_INTEGER);
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("ipCidrRouteTable:_ipCidrRouteTable_check_column:ipCidrRouteMetric2", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = ipCidrRouteMetric2_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 ipCidrRouteMetric2_check_value\n",
                         rc);
                rc = SNMP_ERR_GENERR;
            }
        }
        break;

        /*
         * ipCidrRouteMetric3(13)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_IPCIDRROUTEMETRIC3:
        rc = netsnmp_check_vb_type(var, ASN_INTEGER);
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("ipCidrRouteTable:_ipCidrRouteTable_check_column:ipCidrRouteMetric3", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = ipCidrRouteMetric3_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 ipCidrRouteMetric3_check_value\n",
                         rc);
                rc = SNMP_ERR_GENERR;
            }
        }
        break;

        /*
         * ipCidrRouteMetric4(14)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_IPCIDRROUTEMETRIC4:
        rc = netsnmp_check_vb_type(var, ASN_INTEGER);
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("ipCidrRouteTable:_ipCidrRouteTable_check_column:ipCidrRouteMetric4", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = ipCidrRouteMetric4_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 ipCidrRouteMetric4_check_value\n",
                         rc);
                rc = SNMP_ERR_GENERR;
            }
        }
        break;

        /*
         * ipCidrRouteMetric5(15)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_IPCIDRROUTEMETRIC5:
        rc = netsnmp_check_vb_type(var, ASN_INTEGER);
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("ipCidrRouteTable:_ipCidrRouteTable_check_column:ipCidrRouteMetric5", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = ipCidrRouteMetric5_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 ipCidrRouteMetric5_check_value\n",
                         rc);
                rc = SNMP_ERR_GENERR;
            }
        }
        break;

        /*
         * ipCidrRouteStatus(16)/RowStatus/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_IPCIDRROUTESTATUS:
        rc = netsnmp_check_vb_rowstatus_value(var);
        if (SNMPERR_SUCCESS != rc) {
            DEBUGMSGTL(("ipCidrRouteTable:_ipCidrRouteTable_check_column:ipCidrRouteStatus", "varbind validation failed (eg bad type or size)\n"));
        } else {
            rc = ipCidrRouteStatus_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 ipCidrRouteStatus_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 _ipCidrRouteTable_check_column\n",
                 column);
    }

    return rc;
}                               /* _ipCidrRouteTable_check_column */

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

    DEBUGMSGTL(("internal:ipCidrRouteTable:_mfd_ipCidrRouteTable_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
         */
        netsnmp_table_request_info *tri;
        tri = netsnmp_extract_table_info(requests);
        if (NULL == tri)
            continue;

        rc = _ipCidrRouteTable_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_ipCidrRouteTable_check_objects */


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

    DEBUGMSGTL(("internal:ipCidrRouteTable:_ipCidrRouteTable_undo_setup_column", "called for %d\n", column));

    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

        /*
         * ipCidrRouteIfIndex(5)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_IPCIDRROUTEIFINDEX:
        rowreq_ctx->column_set_flags |= COLUMN_IPCIDRROUTEIFINDEX_FLAG;
        rc = ipCidrRouteIfIndex_undo_setup(rowreq_ctx);
        break;

        /*
         * ipCidrRouteType(6)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_IPCIDRROUTETYPE:
        rowreq_ctx->column_set_flags |= COLUMN_IPCIDRROUTETYPE_FLAG;
        rc = ipCidrRouteType_undo_setup(rowreq_ctx);
        break;

        /*
         * ipCidrRouteInfo(9)/OBJECTID/ASN_OBJECT_ID/oid(oid)//L/A/W/e/r/d/h 
         */
    case COLUMN_IPCIDRROUTEINFO:
        rowreq_ctx->column_set_flags |= COLUMN_IPCIDRROUTEINFO_FLAG;
        rc = ipCidrRouteInfo_undo_setup(rowreq_ctx);
        break;

        /*
         * ipCidrRouteNextHopAS(10)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_IPCIDRROUTENEXTHOPAS:
        rowreq_ctx->column_set_flags |= COLUMN_IPCIDRROUTENEXTHOPAS_FLAG;
        rc = ipCidrRouteNextHopAS_undo_setup(rowreq_ctx);
        break;

        /*
         * ipCidrRouteMetric1(11)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_IPCIDRROUTEMETRIC1:
        rowreq_ctx->column_set_flags |= COLUMN_IPCIDRROUTEMETRIC1_FLAG;
        rc = ipCidrRouteMetric1_undo_setup(rowreq_ctx);
        break;

        /*
         * ipCidrRouteMetric2(12)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_IPCIDRROUTEMETRIC2:
        rowreq_ctx->column_set_flags |= COLUMN_IPCIDRROUTEMETRIC2_FLAG;
        rc = ipCidrRouteMetric2_undo_setup(rowreq_ctx);
        break;

        /*
         * ipCidrRouteMetric3(13)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_IPCIDRROUTEMETRIC3:
        rowreq_ctx->column_set_flags |= COLUMN_IPCIDRROUTEMETRIC3_FLAG;
        rc = ipCidrRouteMetric3_undo_setup(rowreq_ctx);
        break;

        /*
         * ipCidrRouteMetric4(14)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_IPCIDRROUTEMETRIC4:
        rowreq_ctx->column_set_flags |= COLUMN_IPCIDRROUTEMETRIC4_FLAG;
        rc = ipCidrRouteMetric4_undo_setup(rowreq_ctx);
        break;

        /*
         * ipCidrRouteMetric5(15)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_IPCIDRROUTEMETRIC5:
        rowreq_ctx->column_set_flags |= COLUMN_IPCIDRROUTEMETRIC5_FLAG;
        rc = ipCidrRouteMetric5_undo_setup(rowreq_ctx);
        break;

        /*
         * ipCidrRouteStatus(16)/RowStatus/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_IPCIDRROUTESTATUS:
        rowreq_ctx->column_set_flags |= COLUMN_IPCIDRROUTESTATUS_FLAG;
        rc = ipCidrRouteStatus_undo_setup(rowreq_ctx);
        break;

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

    return rc;
}                               /* _ipCidrRouteTable_undo_setup_column */


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

    DEBUGMSGTL(("internal:ipCidrRouteTable:_mfd_ipCidrRouteTable_undo_setup", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * allocate undo context
     */
    rowreq_ctx->undo = ipCidrRouteTable_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 = ipCidrRouteTable_undo_setup(rowreq_ctx);
    if (MFD_SUCCESS != rc) {
        DEBUGMSGTL(("ipCidrRouteTable:mfd", "error %d from "
                    "ipCidrRouteTable_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 = _ipCidrRouteTable_undo_setup_column(rowreq_ctx,
                                                     tri->colnum);
            if (MFD_SUCCESS != rc) {
                DEBUGMSGTL(("ipCidrRouteTable:mfd", "error %d from "
                            "ipCidrRouteTable_undo_setup_column\n", rc));
                netsnmp_set_request_error(agtreq_info, requests,
                                          SNMP_VALIDATE_ERR(rc));
            }
        }                       /* for results */
    }

    return SNMP_ERR_NOERROR;
}                               /* _mfd_ipCidrRouteTable_undo_setup */

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

    DEBUGMSGTL(("internal:ipCidrRouteTable:_mfd_ipCidrRouteTable_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 = ipCidrRouteTable_undo_cleanup(rowreq_ctx);
    if (MFD_SUCCESS != rc) {
        /*
         * nothing we can do about it but log it
         */
        DEBUGMSGTL(("ipCidrRouteTable:mfd", "error %d from "
                    "ipCidrRouteTable_undo_cleanup\n", rc));
    }

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


    return SNMP_ERR_NOERROR;
}                               /* _mfd_ipCidrRouteTable_undo_cleanup */

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

    DEBUGMSGTL(("internal:ipCidrRouteTable:_ipCidrRouteTable_set_column",
                "called for %d\n", column));

    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

        /*
         * ipCidrRouteIfIndex(5)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_IPCIDRROUTEIFINDEX:
        rowreq_ctx->column_set_flags |= COLUMN_IPCIDRROUTEIFINDEX_FLAG;
        rc = ipCidrRouteIfIndex_set(rowreq_ctx,
                                    *((long *) var->val.string));
        break;

        /*
         * ipCidrRouteType(6)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_IPCIDRROUTETYPE:
        rowreq_ctx->column_set_flags |= COLUMN_IPCIDRROUTETYPE_FLAG;
        rc = ipCidrRouteType_set(rowreq_ctx,
                                 *((u_long *) var->val.string));
        break;

        /*
         * ipCidrRouteInfo(9)/OBJECTID/ASN_OBJECT_ID/oid(oid)//L/A/W/e/r/d/h 
         */
    case COLUMN_IPCIDRROUTEINFO:
        rowreq_ctx->column_set_flags |= COLUMN_IPCIDRROUTEINFO_FLAG;
        rc = ipCidrRouteInfo_set(rowreq_ctx, (oid *) var->val.string,
                                 var->val_len);
        break;

        /*
         * ipCidrRouteNextHopAS(10)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_IPCIDRROUTENEXTHOPAS:
        rowreq_ctx->column_set_flags |= COLUMN_IPCIDRROUTENEXTHOPAS_FLAG;
        rc = ipCidrRouteNextHopAS_set(rowreq_ctx,
                                      *((long *) var->val.string));
        break;

        /*
         * ipCidrRouteMetric1(11)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_IPCIDRROUTEMETRIC1:
        rowreq_ctx->column_set_flags |= COLUMN_IPCIDRROUTEMETRIC1_FLAG;
        rc = ipCidrRouteMetric1_set(rowreq_ctx,
                                    *((long *) var->val.string));
        break;

        /*
         * ipCidrRouteMetric2(12)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_IPCIDRROUTEMETRIC2:
        rowreq_ctx->column_set_flags |= COLUMN_IPCIDRROUTEMETRIC2_FLAG;
        rc = ipCidrRouteMetric2_set(rowreq_ctx,
                                    *((long *) var->val.string));
        break;

        /*
         * ipCidrRouteMetric3(13)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_IPCIDRROUTEMETRIC3:
        rowreq_ctx->column_set_flags |= COLUMN_IPCIDRROUTEMETRIC3_FLAG;
        rc = ipCidrRouteMetric3_set(rowreq_ctx,
                                    *((long *) var->val.string));
        break;

        /*
         * ipCidrRouteMetric4(14)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_IPCIDRROUTEMETRIC4:
        rowreq_ctx->column_set_flags |= COLUMN_IPCIDRROUTEMETRIC4_FLAG;
        rc = ipCidrRouteMetric4_set(rowreq_ctx,
                                    *((long *) var->val.string));
        break;

        /*
         * ipCidrRouteMetric5(15)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_IPCIDRROUTEMETRIC5:
        rowreq_ctx->column_set_flags |= COLUMN_IPCIDRROUTEMETRIC5_FLAG;
        rc = ipCidrRouteMetric5_set(rowreq_ctx,
                                    *((long *) var->val.string));
        break;

        /*
         * ipCidrRouteStatus(16)/RowStatus/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_IPCIDRROUTESTATUS:
        rowreq_ctx->column_set_flags |= COLUMN_IPCIDRROUTESTATUS_FLAG;
        rc = ipCidrRouteStatus_set(rowreq_ctx,
                                   *((u_long *) var->val.string));
        break;

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

    return rc;
}                               /* _ipCidrRouteTable_set_column */

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

    DEBUGMSGTL(("internal:ipCidrRouteTable:_mfd_ipCidrRouteTable_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 = _ipCidrRouteTable_set_column(rowreq_ctx,
                                          requests->requestvb,
                                          tri->colnum);
        if (MFD_SUCCESS != rc) {
            DEBUGMSGTL(("ipCidrRouteTable:mfd", "error %d from "
                        "ipCidrRouteTable_set_column\n", rc));
            netsnmp_set_request_error(agtreq_info, requests,
                                      SNMP_VALIDATE_ERR(rc));
        }
    }                           /* for results */

    return SNMP_ERR_NOERROR;
}                               /* _mfd_ipCidrRouteTable_set_values */

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

    DEBUGMSGTL(("internal:ipCidrRouteTable:_mfd_ipCidrRouteTable_commit",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    rc = ipCidrRouteTable_commit(rowreq_ctx);
    if (MFD_SUCCESS != rc) {
        DEBUGMSGTL(("ipCidrRouteTable:mfd", "error %d from "
                    "ipCidrRouteTable_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...
         */
        ipCidrRouteTable_dirty_set(ipCidrRouteTable_dirty_get() + 1);   /* set table dirty flag */
    }

    return SNMP_ERR_NOERROR;
}

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

    DEBUGMSGTL(("internal:ipCidrRouteTable:_mfd_ipCidrRouteTable_undo_commit", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

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

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

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

    return SNMP_ERR_NOERROR;
}                               /* _mfd_ipCidrRouteTable_commit */

/*----------------------------------------------------------------------
 *
 * SET: Undo
 *
 *---------------------------------------------------------------------*/
/**
 * @internal
 * undo the value for a particular column
 */
NETSNMP_STATIC_INLINE int
_ipCidrRouteTable_undo_column(ipCidrRouteTable_rowreq_ctx * rowreq_ctx,
                              netsnmp_variable_list * var, int column)
{
    int             rc = SNMPERR_SUCCESS;

    DEBUGMSGTL(("internal:ipCidrRouteTable:_ipCidrRouteTable_undo_column",
                "called for %d\n", column));

    netsnmp_assert(NULL != rowreq_ctx);

    switch (column) {

        /*
         * ipCidrRouteIfIndex(5)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_IPCIDRROUTEIFINDEX:
        rc = ipCidrRouteIfIndex_undo(rowreq_ctx);
        break;

        /*
         * ipCidrRouteType(6)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_IPCIDRROUTETYPE:
        rc = ipCidrRouteType_undo(rowreq_ctx);
        break;

        /*
         * ipCidrRouteInfo(9)/OBJECTID/ASN_OBJECT_ID/oid(oid)//L/A/W/e/r/d/h 
         */
    case COLUMN_IPCIDRROUTEINFO:
        rc = ipCidrRouteInfo_undo(rowreq_ctx);
        break;

        /*
         * ipCidrRouteNextHopAS(10)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_IPCIDRROUTENEXTHOPAS:
        rc = ipCidrRouteNextHopAS_undo(rowreq_ctx);
        break;

        /*
         * ipCidrRouteMetric1(11)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_IPCIDRROUTEMETRIC1:
        rc = ipCidrRouteMetric1_undo(rowreq_ctx);
        break;

        /*
         * ipCidrRouteMetric2(12)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_IPCIDRROUTEMETRIC2:
        rc = ipCidrRouteMetric2_undo(rowreq_ctx);
        break;

        /*
         * ipCidrRouteMetric3(13)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_IPCIDRROUTEMETRIC3:
        rc = ipCidrRouteMetric3_undo(rowreq_ctx);
        break;

        /*
         * ipCidrRouteMetric4(14)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_IPCIDRROUTEMETRIC4:
        rc = ipCidrRouteMetric4_undo(rowreq_ctx);
        break;

        /*
         * ipCidrRouteMetric5(15)/INTEGER32/ASN_INTEGER/long(long)//l/A/W/e/r/D/h 
         */
    case COLUMN_IPCIDRROUTEMETRIC5:
        rc = ipCidrRouteMetric5_undo(rowreq_ctx);
        break;

        /*
         * ipCidrRouteStatus(16)/RowStatus/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h 
         */
    case COLUMN_IPCIDRROUTESTATUS:
        rc = ipCidrRouteStatus_undo(rowreq_ctx);
        break;

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

    return rc;
}                               /* _ipCidrRouteTable_undo_column */

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

    DEBUGMSGTL(("internal:ipCidrRouteTable:_mfd_ipCidrRouteTable_undo_values", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

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

        rc = _ipCidrRouteTable_undo_column(rowreq_ctx, requests->requestvb,
                                           tri->colnum);
        if (MFD_SUCCESS != rc) {
            /*
             * nothing we can do about it but log it
             */
            DEBUGMSGTL(("ipCidrRouteTable:mfd", "error %d from "
                        "ipCidrRouteTable_undo_column\n", rc));
        }
    }                           /* for results */

    return SNMP_ERR_NOERROR;
}                               /* _mfd_ipCidrRouteTable_undo_values */

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

    DEBUGMSGTL(("internal:ipCidrRouteTable:_mfd_ipCidrRouteTable_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(ipCidrRouteTable_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(ipCidrRouteTable_if_ctx.container,
                             rowreq_ctx);
        }
    }

    return SNMP_ERR_NOERROR;
}                               /* _mfd_ipCidrRouteTable_irreversible_commit */
#endif

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

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

    if ((NULL == cache) || (NULL == cache->magic)) {
        snmp_log(LOG_ERR,
                 "invalid cache for ipCidrRouteTable_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 ipCidrRouteTable_container_load((netsnmp_container *) cache->
                                           magic);
}                               /* _cache_load */

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

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

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

    container = (netsnmp_container *) cache->magic;

    _container_free(container);
}                               /* _cache_free */

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

    if (NULL == rowreq_ctx)
        return;

    ipCidrRouteTable_release_rowreq_ctx(rowreq_ctx);
}                               /* _container_item_free */

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

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

    /*
     * call user code
     */
    ipCidrRouteTable_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
_ipCidrRouteTable_container_init(ipCidrRouteTable_interface_ctx * if_ctx)
{
    DEBUGMSGTL(("internal:ipCidrRouteTable:_ipCidrRouteTable_container_init", "called\n"));

    /*
     * cache init
     */
    if_ctx->cache = netsnmp_cache_create(30,    /* timeout in seconds */
                                         _cache_load, _cache_free,
                                         ipCidrRouteTable_oid,
                                         ipCidrRouteTable_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;

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

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

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

    ipCidrRouteTable_container_shutdown(if_ctx->container);

    _container_free(if_ctx->container);

}                               /* _ipCidrRouteTable_container_shutdown */


ipCidrRouteTable_rowreq_ctx *
ipCidrRouteTable_row_find_by_mib_index(ipCidrRouteTable_mib_index *
                                       mib_idx)
{
    ipCidrRouteTable_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 = ipCidrRouteTable_index_to_oid(&oid_idx, mib_idx);
    if (MFD_SUCCESS != rc)
        return NULL;

    rowreq_ctx =
        CONTAINER_FIND(ipCidrRouteTable_if_ctx.container, &oid_idx);

    return rowreq_ctx;
}
