/*
 * 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 retrieval. 
     */
    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 = (ipCidrRouteTable_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 = (ipCidrRouteTable_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 = (ipCidrRouteTable_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 = (ipCidrRouteTable_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 = (ipCidrRouteTable_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 = (ipCidrRouteTable_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 = (ipCidrRouteTable_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 = (ipCidrRouteTable_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 = (ipCidrRouteTable_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 = (ipCidrRouteTable_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 = (ipCidrRouteTable_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(IPCIDRROUTETABLE_CACHE_TIMEOUT,
                                         _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_ctx->container->container_name = strdup("ipCidrRouteTable");

    /* 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;
}                               /* _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 = (ipCidrRouteTable_rowreq_ctx*)
        CONTAINER_FIND(ipCidrRouteTable_if_ctx.container, &oid_idx);

    return rowreq_ctx;
}
