/*
 * Note: this file originally auto-generated by mib2c using
 *       version : 1.48 $ of : mfd-top.m2c,v $ 
 *
 * $Id$
 */
/** \page MFD helper for inetCidrRouteTable
 *
 * \section intro Introduction
 * Introductory text.
 *
 */
/*
 * 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 "inetCidrRouteTable.h"

#include <net-snmp/agent/mib_modules.h>

#include "inetCidrRouteTable_interface.h"

const oid       inetCidrRouteTable_oid[] = { INETCIDRROUTETABLE_OID };
const int       inetCidrRouteTable_oid_size =
OID_LENGTH(inetCidrRouteTable_oid);

inetCidrRouteTable_registration inetCidrRouteTable_user_context;
static inetCidrRouteTable_registration *inetCidrRouteTable_user_context_p;

void            initialize_table_inetCidrRouteTable(void);
void            shutdown_table_inetCidrRouteTable(void);

int
_route_number_handler(netsnmp_mib_handler *handler,
                      netsnmp_handler_registration *reginfo,
                      netsnmp_agent_request_info *reqinfo,
                      netsnmp_request_info *requests);


/**
 * Initializes the inetCidrRouteTable module
 */
void
init_inetCidrRouteTable(void)
{
    DEBUGMSGTL(("verbose:inetCidrRouteTable:init_inetCidrRouteTable",
                "called\n"));

    /*
     * TODO:300:o: Perform inetCidrRouteTable one-time module initialization.
     */

    /*
     * here we initialize all the tables we're planning on supporting
     */
    if (should_init("inetCidrRouteTable"))
        initialize_table_inetCidrRouteTable();

}                               /* init_inetCidrRouteTable */

/**
 * Shut-down the inetCidrRouteTable module (agent is exiting)
 */
void
shutdown_inetCidrRouteTable(void)
{
    if (should_init("inetCidrRouteTable"))
        shutdown_table_inetCidrRouteTable();

}

/**
 * Initialize the table inetCidrRouteTable 
 *    (Define its contents and how it's structured)
 */
void
initialize_table_inetCidrRouteTable(void)
{
    u_long          flags;

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

    /*
     * TODO:301:o: Perform inetCidrRouteTable one-time table initialization.
     */

    /*
     * TODO:302:o: |->Initialize inetCidrRouteTable user context
     * if you'd like to pass in a pointer to some data for this
     * table, allocate or set it up here.
     */
    /*
     * a netsnmp_data_list is a simple way to store void pointers. A simple
     * string token is used to add, find or remove pointers.
     */
    inetCidrRouteTable_user_context_p = 
	netsnmp_create_data_list("inetCidrRouteTable", NULL, NULL);

    /*
     * No support for any flags yet, but in the future you would
     * set any flags here.
     */
    flags = 0;

    /*
     * call interface initialization code
     */
    _inetCidrRouteTable_initialize_interface
	(inetCidrRouteTable_user_context_p, flags);

    /*
     * regester scalar for route number
     */
    {
        oid             reg_oid[] =
            { INETCIDRROUTENUMBER_OID };
        netsnmp_handler_registration *myreg;
        netsnmp_mib_handler *handler;

        myreg =
            netsnmp_create_handler_registration("route number",
                                                _route_number_handler,
                                                reg_oid,
                                                OID_LENGTH(reg_oid),
                                                HANDLER_CAN_RONLY);
        /*
         * snarf cache to use w/cache handler to make sure the
         * container is loaded w/up to date data.
         */
        netsnmp_assert(NULL != inetCidrRouteTable_get_cache());
        handler =
            netsnmp_cache_handler_get(inetCidrRouteTable_get_cache());
        netsnmp_inject_handler(myreg, handler);
        
        netsnmp_register_instance(myreg);
    }
}                               /* initialize_table_inetCidrRouteTable */

/**
 * Shutdown the table inetCidrRouteTable 
 */
void
shutdown_table_inetCidrRouteTable(void)
{
    /*
     * call interface shutdown code
     */
    _inetCidrRouteTable_shutdown_interface
        (inetCidrRouteTable_user_context_p);
    netsnmp_free_all_list_data(inetCidrRouteTable_user_context_p);
    inetCidrRouteTable_user_context_p = NULL;
}

/**
 * extra context initialization (eg default values)
 *
 * @param rowreq_ctx    : row request context
 * @param user_init_ctx : void pointer for user (parameter to rowreq_ctx_allocate)
 *
 * @retval MFD_SUCCESS  : no errors
 * @retval MFD_ERROR    : error (context allocate will fail)
 */
int
inetCidrRouteTable_rowreq_ctx_init(inetCidrRouteTable_rowreq_ctx *
                                   rowreq_ctx, void *user_init_ctx)
{
    DEBUGMSGTL(("verbose:inetCidrRouteTable:inetCidrRouteTable_rowreq_ctx_init", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:210:o: |-> Perform extra inetCidrRouteTable rowreq initialization. (eg DEFVALS)
     */
    rowreq_ctx->data->rt_nexthop_type = 0;

    rowreq_ctx->data->rt_metric1 = -1;

    rowreq_ctx->data->rt_metric2 = -1;

    rowreq_ctx->data->rt_metric3 = -1;

    rowreq_ctx->data->rt_metric4 = -1;

    rowreq_ctx->data->rt_metric5 = -1;


    return MFD_SUCCESS;
}                               /* inetCidrRouteTable_rowreq_ctx_init */

/**
 * extra context cleanup
 *
 */
void
inetCidrRouteTable_rowreq_ctx_cleanup(inetCidrRouteTable_rowreq_ctx *
                                      rowreq_ctx)
{
    DEBUGMSGTL(("verbose:inetCidrRouteTable:inetCidrRouteTable_rowreq_ctx_cleanup", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:211:o: |-> Perform extra inetCidrRouteTable rowreq cleanup.
     */
    if (NULL != rowreq_ctx->data) {
        inetCidrRouteTable_release_data(rowreq_ctx->data);
        rowreq_ctx->data = NULL;
    }
}                               /* inetCidrRouteTable_rowreq_ctx_cleanup */

/**
 * pre-request callback
 *
 *
 * @retval MFD_SUCCESS              : success.
 * @retval MFD_ERROR                : other error
 */
int
inetCidrRouteTable_pre_request(inetCidrRouteTable_registration *
                               user_context)
{
    DEBUGMSGTL(("verbose:inetCidrRouteTable:inetCidrRouteTable_pre_request", "called\n"));

    /*
     * TODO:510:o: Perform inetCidrRouteTable pre-request actions.
     */

    return MFD_SUCCESS;
}                               /* inetCidrRouteTable_pre_request */

/**
 * post-request callback
 *
 * Note:
 *   New rows have been inserted into the container, and
 *   deleted rows have been removed from the container and
 *   released.
 *
 * @param user_context 
 * @param rc : MFD_SUCCESS if all requests succeeded
 *
 * @retval MFD_SUCCESS : success.
 * @retval MFD_ERROR   : other error (ignored)
 */
int
inetCidrRouteTable_post_request(inetCidrRouteTable_registration *
                                user_context, int rc)
{
    DEBUGMSGTL(("verbose:inetCidrRouteTable:inetCidrRouteTable_post_request", "called\n"));

    /*
     * TODO:511:o: Perform inetCidrRouteTable post-request actions.
     */

    /*
     * check to set if any rows were changed.
     */
    if (inetCidrRouteTable_dirty_get()) {
        /*
         * check if request was successful. If so, this would be
         * a good place to save data to its persistent store.
         */
        if (MFD_SUCCESS == rc) {
            /*
             * save changed rows, if you haven't already
             */
        }

        inetCidrRouteTable_dirty_set(0);        /* clear table dirty flag */
    }

    return MFD_SUCCESS;
}                               /* inetCidrRouteTable_post_request */


/**********************************************************************
 **********************************************************************
 ***
 *** Table inetCidrRouteTable
 ***
 **********************************************************************
 **********************************************************************/
/*
 * IP-FORWARD-MIB::inetCidrRouteTable is subid 7 of ipForward.
 * Its status is Current.
 * OID: .1.3.6.1.2.1.4.24.7, length: 9
 */

/*
 * ---------------------------------------------------------------------
 * * TODO:200:r: Implement inetCidrRouteTable data context functions.
 */
/*
 * inetCidrRouteTable_allocate_data
 *
 * Purpose: create new inetCidrRouteTable_data->
 */
inetCidrRouteTable_data *
inetCidrRouteTable_allocate_data(void)
{
    /*
     * TODO:201:r: |-> allocate memory for the inetCidrRouteTable data context.
     */
    inetCidrRouteTable_data *rtn = netsnmp_access_route_entry_create();

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

    if (NULL == rtn) {
        snmp_log(LOG_ERR, "unable to malloc memory for new "
                 "inetCidrRouteTable_data->\n");
    }

    return rtn;
}                               /* inetCidrRouteTable_allocate_data */

/*
 * inetCidrRouteTable_release_data
 *
 * Purpose: release inetCidrRouteTable data->
 */
void
inetCidrRouteTable_release_data(inetCidrRouteTable_data * data)
{
    DEBUGMSGTL(("verbose:inetCidrRouteTable:inetCidrRouteTable_release_data", "called\n"));

    /*
     * TODO:202:r: |-> release memory for the inetCidrRouteTable data context.
     */
    netsnmp_access_route_entry_free(data);
}                               /* inetCidrRouteTable_release_data */



/**
 * set mib index(es)
 *
 * @param tbl_idx mib index structure
 * @param inetCidrRouteDestType_val
 * @param inetCidrRouteDest_val_ptr
 * @param inetCidrRouteDest_val_ptr_len
 * @param inetCidrRoutePfxLen_val
 * @param inetCidrRoutePolicy_val_ptr
 * @param inetCidrRoutePolicy_val_ptr_len
 * @param inetCidrRouteNextHopType_val
 * @param inetCidrRouteNextHop_val_ptr
 * @param inetCidrRouteNextHop_val_ptr_len
 * @retval MFD_SUCCESS     : success.
 * @retval MFD_ERROR       : other error.
 *
 * @remark
 *  This convenience function is useful for setting all the MIB index
 *  components with a single function call. It is assume that the C values
 *  have already been mapped from their native/rawformat to the MIB format.
 */
int
inetCidrRouteTable_indexes_set_tbl_idx(inetCidrRouteTable_mib_index *
                                       tbl_idx,
                                       u_long inetCidrRouteDestType_val,
                                       char *inetCidrRouteDest_val_ptr,
                                       size_t
                                       inetCidrRouteDest_val_ptr_len,
                                       u_long inetCidrRoutePfxLen_val,
                                       oid * inetCidrRoutePolicy_val_ptr,
                                       size_t
                                       inetCidrRoutePolicy_val_ptr_len,
                                       u_long inetCidrRouteNextHopType_val,
                                       char *inetCidrRouteNextHop_val_ptr,
                                       size_t
                                       inetCidrRouteNextHop_val_ptr_len)
{
    DEBUGMSGTL(("verbose:inetCidrRouteTable:inetCidrRouteTable_indexes_set_tbl_idx", "called\n"));

    /*
     * inetCidrRouteDestType(1)/InetAddressType/ASN_INTEGER/long(u_long)//l/a/w/E/r/d/h 
     */
    /** WARNING: this code might not work for netsnmp_route_entry */
    tbl_idx->inetCidrRouteDestType = inetCidrRouteDestType_val;

    /*
     * inetCidrRouteDest(2)/InetAddress/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h 
     */
    tbl_idx->inetCidrRouteDest_len = sizeof(tbl_idx->inetCidrRouteDest) / sizeof(tbl_idx->inetCidrRouteDest[0]);        /* max length */
    /** WARNING: this code might not work for netsnmp_route_entry */
    /*
     * make sure there is enough space for inetCidrRouteDest data
     */
    if ((NULL == tbl_idx->inetCidrRouteDest) ||
        (tbl_idx->inetCidrRouteDest_len <
         (inetCidrRouteDest_val_ptr_len))) {
        snmp_log(LOG_ERR, "not enough space for value\n");
        return MFD_ERROR;
    }
    tbl_idx->inetCidrRouteDest_len = inetCidrRouteDest_val_ptr_len;
    memcpy(tbl_idx->inetCidrRouteDest, inetCidrRouteDest_val_ptr,
           inetCidrRouteDest_val_ptr_len *
           sizeof(inetCidrRouteDest_val_ptr[0]));

    /*
     * inetCidrRoutePfxLen(3)/InetAddressPrefixLength/ASN_UNSIGNED/u_long(u_long)//l/a/w/e/R/d/H 
     */
    /** WARNING: this code might not work for netsnmp_route_entry */
    tbl_idx->inetCidrRoutePfxLen = inetCidrRoutePfxLen_val;

    /*
     * inetCidrRoutePolicy(4)/OBJECTID/ASN_OBJECT_ID/oid(oid)//L/a/w/e/r/d/h 
     */
    tbl_idx->inetCidrRoutePolicy_len = sizeof(tbl_idx->inetCidrRoutePolicy) / sizeof(tbl_idx->inetCidrRoutePolicy[0]);  /* max length */
    /** WARNING: this code might not work for netsnmp_route_entry */
    /*
     * make sure there is enough space for inetCidrRoutePolicy data
     */
    if ((NULL == tbl_idx->inetCidrRoutePolicy) ||
        (tbl_idx->inetCidrRoutePolicy_len <
         (inetCidrRoutePolicy_val_ptr_len))) {
        snmp_log(LOG_ERR, "not enough space for value\n");
        return MFD_ERROR;
    }
    if (0 == inetCidrRoutePolicy_val_ptr_len) {
        inetCidrRoutePolicy_val_ptr_len = nullOidLen / sizeof(oid);
        inetCidrRoutePolicy_val_ptr = nullOid;
    }
    tbl_idx->inetCidrRoutePolicy_len = inetCidrRoutePolicy_val_ptr_len;
    memcpy(tbl_idx->inetCidrRoutePolicy, inetCidrRoutePolicy_val_ptr,
           inetCidrRoutePolicy_val_ptr_len *
           sizeof(inetCidrRoutePolicy_val_ptr[0]));

    /*
     * inetCidrRouteNextHopType(5)/InetAddressType/ASN_INTEGER/long(u_long)//l/a/w/E/r/d/h 
     */
    /** WARNING: this code might not work for netsnmp_route_entry */
    tbl_idx->inetCidrRouteNextHopType = inetCidrRouteNextHopType_val;

    /*
     * inetCidrRouteNextHop(6)/InetAddress/ASN_OCTET_STR/char(char)//L/a/w/e/R/d/h 
     */
    tbl_idx->inetCidrRouteNextHop_len = sizeof(tbl_idx->inetCidrRouteNextHop) / sizeof(tbl_idx->inetCidrRouteNextHop[0]);       /* max length */
    /** WARNING: this code might not work for netsnmp_route_entry */
    /*
     * make sure there is enough space for inetCidrRouteNextHop data
     */
    if ((NULL == tbl_idx->inetCidrRouteNextHop) ||
        (tbl_idx->inetCidrRouteNextHop_len <
         (inetCidrRouteNextHop_val_ptr_len))) {
        snmp_log(LOG_ERR, "not enough space for value\n");
        return MFD_ERROR;
    }
    tbl_idx->inetCidrRouteNextHop_len = inetCidrRouteNextHop_val_ptr_len;
    memcpy(tbl_idx->inetCidrRouteNextHop, inetCidrRouteNextHop_val_ptr,
           inetCidrRouteNextHop_val_ptr_len *
           sizeof(inetCidrRouteNextHop_val_ptr[0]));


    return MFD_SUCCESS;
}                               /* inetCidrRouteTable_indexes_set_tbl_idx */

/**
 * @internal
 * set row context indexes
 *
 * @param rowreq_ctx the row context that needs updated indexes
 * @param inetCidrRouteDestType_val
 * @param inetCidrRouteDest_val_ptr
 * @param inetCidrRouteDest_val_ptr_len
 * @param inetCidrRoutePfxLen_val
 * @param inetCidrRoutePolicy_val_ptr
 * @param inetCidrRoutePolicy_val_ptr_len
 * @param inetCidrRouteNextHopType_val
 * @param inetCidrRouteNextHop_val_ptr
 * @param inetCidrRouteNextHop_val_ptr_len
 *
 * @retval MFD_SUCCESS     : success.
 * @retval MFD_ERROR       : other error.
 *
 * @remark
 *  This function sets the mib indexs, then updates the oid indexs
 *  from the mib index.
 */
int
inetCidrRouteTable_indexes_set(inetCidrRouteTable_rowreq_ctx * rowreq_ctx,
                               u_long inetCidrRouteDestType_val,
                               char *inetCidrRouteDest_val_ptr,
                               size_t inetCidrRouteDest_val_ptr_len,
                               u_long inetCidrRoutePfxLen_val,
                               oid * inetCidrRoutePolicy_val_ptr,
                               size_t inetCidrRoutePolicy_val_ptr_len,
                               u_long inetCidrRouteNextHopType_val,
                               char *inetCidrRouteNextHop_val_ptr,
                               size_t inetCidrRouteNextHop_val_ptr_len)
{
    DEBUGMSGTL(("verbose:inetCidrRouteTable:inetCidrRouteTable_indexes_set", "called\n"));

    if (MFD_SUCCESS !=
        inetCidrRouteTable_indexes_set_tbl_idx(&rowreq_ctx->tbl_idx,
                                               inetCidrRouteDestType_val,
                                               inetCidrRouteDest_val_ptr,
                                               inetCidrRouteDest_val_ptr_len,
                                               inetCidrRoutePfxLen_val,
                                               inetCidrRoutePolicy_val_ptr,
                                               inetCidrRoutePolicy_val_ptr_len,
                                               inetCidrRouteNextHopType_val,
                                               inetCidrRouteNextHop_val_ptr,
                                               inetCidrRouteNextHop_val_ptr_len))
        return MFD_ERROR;

    /*
     * convert mib index to oid index
     */
    rowreq_ctx->oid_idx.len = sizeof(rowreq_ctx->oid_tmp) / sizeof(oid);
    if (0 != inetCidrRouteTable_index_to_oid(&rowreq_ctx->oid_idx,
                                             &rowreq_ctx->tbl_idx)) {
        return MFD_ERROR;
    }

    return MFD_SUCCESS;
}                               /* inetCidrRouteTable_indexes_set */


/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::inetCidrRouteEntry.inetCidrRouteIfIndex
 * inetCidrRouteIfIndex is subid 7 of inetCidrRouteEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.24.7.1.7
 * Description:
The ifIndex value which identifies the local interface 
                through which the next hop of this route should be  
                reached.  A value of 0 is valid and represents the 
                scenario where no interface is specified.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 1      hashint   1
 *   settable   1
 *   hint: d
 *
 * Ranges:  0 - 2147483647;
 *
 * Its syntax is InterfaceIndexOrZero (based on perltype INTEGER32)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (long)
 */
/**
 * Extract the current value of the inetCidrRouteIfIndex data->
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param inetCidrRouteIfIndex_val_ptr
 *        Pointer to storage for a long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
inetCidrRouteIfIndex_get(inetCidrRouteTable_rowreq_ctx * rowreq_ctx,
                         long *inetCidrRouteIfIndex_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != inetCidrRouteIfIndex_val_ptr);


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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the inetCidrRouteIfIndex data->
     * copy (* inetCidrRouteIfIndex_val_ptr ) from rowreq_ctx->data
     */
    /*
     * TODO:235:M: |-> Remove log message/SKIP once you've set inetCidrRouteIfIndex data
     */
    (*inetCidrRouteIfIndex_val_ptr) = rowreq_ctx->data->if_index;

    return MFD_SUCCESS;
}                               /* inetCidrRouteIfIndex_get */

/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::inetCidrRouteEntry.inetCidrRouteType
 * inetCidrRouteType is subid 8 of inetCidrRouteEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.24.7.1.8
 * Description:
The type of route.  Note that local(3) refers to a  
                route for which the next hop is the final destination;  
                remote(4)refers to a route for which the next hop is  
                not the final destination. 

                Routes which do not result in traffic forwarding or 
                rejection should not be displayed even if the  
                implementation keeps them stored internally. 

                reject(2) refers to a route which, if matched, discards  
                the message as unreachable and returns a notification  
                (e.g. ICMP error) to the message sender.  This is used  
                in some protocols as a means of correctly aggregating  
                routes. 

                blackhole(5) refers to a route which, if matched,  
                discards the message silently.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *
 * Enum range: 3/8. Values:  other(1), reject(2), local(3), remote(4), blackhole(5)
 *
 * Its syntax is INTEGER (based on perltype INTEGER)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
 */
/**
 * Extract the current value of the inetCidrRouteType data->
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param inetCidrRouteType_val_ptr
 *        Pointer to storage for a long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
inetCidrRouteType_get(inetCidrRouteTable_rowreq_ctx * rowreq_ctx,
                      u_long * inetCidrRouteType_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != inetCidrRouteType_val_ptr);


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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the inetCidrRouteType data->
     * copy (* inetCidrRouteType_val_ptr ) from rowreq_ctx->data
     */
    /*
     * TODO:235:M: |-> Remove log message/SKIP once you've set inetCidrRouteType data
     */
    (*inetCidrRouteType_val_ptr) = rowreq_ctx->data->rt_type;

    return MFD_SUCCESS;
}                               /* inetCidrRouteType_get */

/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::inetCidrRouteEntry.inetCidrRouteProto
 * inetCidrRouteProto is subid 9 of inetCidrRouteEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.4.24.7.1.9
 * Description:
The routing mechanism via which this route was learned. 
                Inclusion of values for gateway routing protocols is  
                not intended to imply that hosts should support those 
                protocols.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 * Enum range: 13/32. Values:  other(1), local(2), netmgmt(3), icmp(4), egp(5), ggp(6), hello(7), rip(8), isIs(9), esIs(10), ciscoIgrp(11), bbnSpfIgp(12), ospf(13), bgp(14), idpr(15), ciscoEigrp(16), dvmrp(17)
 *
 * Its syntax is IANAipRouteProtocol (based on perltype INTEGER)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
 */
/**
 * Extract the current value of the inetCidrRouteProto data->
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param inetCidrRouteProto_val_ptr
 *        Pointer to storage for a long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
inetCidrRouteProto_get(inetCidrRouteTable_rowreq_ctx * rowreq_ctx,
                       u_long * inetCidrRouteProto_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != inetCidrRouteProto_val_ptr);


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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the inetCidrRouteProto data->
     * copy (* inetCidrRouteProto_val_ptr ) from rowreq_ctx->data
     */
    /*
     * TODO:235:M: |-> Remove log message/SKIP once you've set inetCidrRouteProto data
     */
    (*inetCidrRouteProto_val_ptr) = rowreq_ctx->data->rt_proto;

    return MFD_SUCCESS;
}                               /* inetCidrRouteProto_get */

/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::inetCidrRouteEntry.inetCidrRouteAge
 * inetCidrRouteAge is subid 10 of inetCidrRouteEntry.
 * Its status is Current, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.4.24.7.1.10
 * Description:
The number of seconds since this route was last updated  
                or otherwise determined to be correct.  Note that no  
                semantics of 'too old' can be implied except through  
                knowledge of the routing protocol by which the route  
                was learned.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *
 *
 * Its syntax is GAUGE (based on perltype GAUGE)
 * The net-snmp type is ASN_GAUGE. The C type decl is u_long (u_long)
 */
/**
 * Extract the current value of the inetCidrRouteAge data->
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param inetCidrRouteAge_val_ptr
 *        Pointer to storage for a u_long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
inetCidrRouteAge_get(inetCidrRouteTable_rowreq_ctx * rowreq_ctx,
                     u_long * inetCidrRouteAge_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != inetCidrRouteAge_val_ptr);


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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the inetCidrRouteAge data->
     * copy (* inetCidrRouteAge_val_ptr ) from rowreq_ctx->data
     */
    /*
     * TODO:235:M: |-> Remove log message/SKIP once you've set inetCidrRouteAge data
     */
    (*inetCidrRouteAge_val_ptr) = rowreq_ctx->data->rt_age;

    return MFD_SUCCESS;
}                               /* inetCidrRouteAge_get */

/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::inetCidrRouteEntry.inetCidrRouteNextHopAS
 * inetCidrRouteNextHopAS is subid 11 of inetCidrRouteEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.24.7.1.11
 * Description:
The Autonomous System Number of the Next Hop.  The  
                semantics of this object are determined by the routing- 
                protocol specified in the route's inetCidrRouteProto  
                value. When this object is unknown or not relevant its  
                value should be set to zero.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 1
 *   readable   1     iscolumn 1     ranges 0      hashint   1
 *   settable   1
 *   defval: 0
 *   hint: d
 *
 *
 * Its syntax is InetAutonomousSystemNumber (based on perltype UNSIGNED32)
 * The net-snmp type is ASN_UNSIGNED. The C type decl is u_long (u_long)
 */
/**
 * Extract the current value of the inetCidrRouteNextHopAS data->
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param inetCidrRouteNextHopAS_val_ptr
 *        Pointer to storage for a u_long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
inetCidrRouteNextHopAS_get(inetCidrRouteTable_rowreq_ctx * rowreq_ctx,
                           u_long * inetCidrRouteNextHopAS_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != inetCidrRouteNextHopAS_val_ptr);


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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the inetCidrRouteNextHopAS data->
     * copy (* inetCidrRouteNextHopAS_val_ptr ) from rowreq_ctx->data
     */
    /*
     * TODO:235:M: |-> Remove log message/SKIP once you've set inetCidrRouteNextHopAS data
     */
    (*inetCidrRouteNextHopAS_val_ptr) = rowreq_ctx->data->rt_nexthop_as;

    return MFD_SUCCESS;
}                               /* inetCidrRouteNextHopAS_get */

/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::inetCidrRouteEntry.inetCidrRouteMetric1
 * inetCidrRouteMetric1 is subid 12 of inetCidrRouteEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.24.7.1.12
 * Description:
The primary routing metric for this route.  The  
                semantics of this metric are determined by the routing- 
                protocol specified in the route's inetCidrRouteProto  
                value.  If this metric is not used, its value should be  
                set to -1.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 1
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *   defval: -1
 *
 *
 * Its syntax is INTEGER32 (based on perltype INTEGER32)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (long)
 */
/**
 * Extract the current value of the inetCidrRouteMetric1 data->
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param inetCidrRouteMetric1_val_ptr
 *        Pointer to storage for a long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
inetCidrRouteMetric1_get(inetCidrRouteTable_rowreq_ctx * rowreq_ctx,
                         long *inetCidrRouteMetric1_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != inetCidrRouteMetric1_val_ptr);


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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the inetCidrRouteMetric1 data->
     * copy (* inetCidrRouteMetric1_val_ptr ) from rowreq_ctx->data
     */
    /*
     * TODO:235:M: |-> Remove log message/SKIP once you've set inetCidrRouteMetric1 data
     */
    (*inetCidrRouteMetric1_val_ptr) = rowreq_ctx->data->rt_metric1;

    return MFD_SUCCESS;
}                               /* inetCidrRouteMetric1_get */

/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::inetCidrRouteEntry.inetCidrRouteMetric2
 * inetCidrRouteMetric2 is subid 13 of inetCidrRouteEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.24.7.1.13
 * Description:
An alternate routing metric for this route.  The  
                semantics of this metric are determined by the routing- 
                protocol specified in the route's inetCidrRouteProto  
                value.  If this metric is not used, its value should be  
                set to -1.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 1
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *   defval: -1
 *
 *
 * Its syntax is INTEGER32 (based on perltype INTEGER32)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (long)
 */
/**
 * Extract the current value of the inetCidrRouteMetric2 data->
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param inetCidrRouteMetric2_val_ptr
 *        Pointer to storage for a long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
inetCidrRouteMetric2_get(inetCidrRouteTable_rowreq_ctx * rowreq_ctx,
                         long *inetCidrRouteMetric2_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != inetCidrRouteMetric2_val_ptr);


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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the inetCidrRouteMetric2 data->
     * copy (* inetCidrRouteMetric2_val_ptr ) from rowreq_ctx->data
     */
    /*
     * TODO:235:M: |-> Remove log message/SKIP once you've set inetCidrRouteMetric2 data
     */
    (*inetCidrRouteMetric2_val_ptr) = rowreq_ctx->data->rt_metric2;

    return MFD_SUCCESS;
}                               /* inetCidrRouteMetric2_get */

/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::inetCidrRouteEntry.inetCidrRouteMetric3
 * inetCidrRouteMetric3 is subid 14 of inetCidrRouteEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.24.7.1.14
 * Description:
An alternate routing metric for this route.  The  
                semantics of this metric are determined by the routing- 
                protocol specified in the route's inetCidrRouteProto  
                value.  If this metric is not used, its value should be  
                set to -1.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 1
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *   defval: -1
 *
 *
 * Its syntax is INTEGER32 (based on perltype INTEGER32)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (long)
 */
/**
 * Extract the current value of the inetCidrRouteMetric3 data->
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param inetCidrRouteMetric3_val_ptr
 *        Pointer to storage for a long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
inetCidrRouteMetric3_get(inetCidrRouteTable_rowreq_ctx * rowreq_ctx,
                         long *inetCidrRouteMetric3_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != inetCidrRouteMetric3_val_ptr);


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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the inetCidrRouteMetric3 data->
     * copy (* inetCidrRouteMetric3_val_ptr ) from rowreq_ctx->data
     */
    /*
     * TODO:235:M: |-> Remove log message/SKIP once you've set inetCidrRouteMetric3 data
     */
    (*inetCidrRouteMetric3_val_ptr) = rowreq_ctx->data->rt_metric3;

    return MFD_SUCCESS;
}                               /* inetCidrRouteMetric3_get */

/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::inetCidrRouteEntry.inetCidrRouteMetric4
 * inetCidrRouteMetric4 is subid 15 of inetCidrRouteEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.24.7.1.15
 * Description:
An alternate routing metric for this route.  The  
                semantics of this metric are determined by the routing- 
                protocol specified in the route's inetCidrRouteProto  
                value.  If this metric is not used, its value should be  
                set to -1.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 1
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *   defval: -1
 *
 *
 * Its syntax is INTEGER32 (based on perltype INTEGER32)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (long)
 */
/**
 * Extract the current value of the inetCidrRouteMetric4 data->
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param inetCidrRouteMetric4_val_ptr
 *        Pointer to storage for a long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
inetCidrRouteMetric4_get(inetCidrRouteTable_rowreq_ctx * rowreq_ctx,
                         long *inetCidrRouteMetric4_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != inetCidrRouteMetric4_val_ptr);


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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the inetCidrRouteMetric4 data->
     * copy (* inetCidrRouteMetric4_val_ptr ) from rowreq_ctx->data
     */
    /*
     * TODO:235:M: |-> Remove log message/SKIP once you've set inetCidrRouteMetric4 data
     */
    (*inetCidrRouteMetric4_val_ptr) = rowreq_ctx->data->rt_metric4;

    return MFD_SUCCESS;
}                               /* inetCidrRouteMetric4_get */

/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::inetCidrRouteEntry.inetCidrRouteMetric5
 * inetCidrRouteMetric5 is subid 16 of inetCidrRouteEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.24.7.1.16
 * Description:
An alternate routing metric for this route.  The  
                semantics of this metric are determined by the routing- 
                protocol specified in the route's inetCidrRouteProto  
                value.  If this metric is not used, its value should be  
                set to -1.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 1
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *   defval: -1
 *
 *
 * Its syntax is INTEGER32 (based on perltype INTEGER32)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (long)
 */
/**
 * Extract the current value of the inetCidrRouteMetric5 data->
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param inetCidrRouteMetric5_val_ptr
 *        Pointer to storage for a long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
inetCidrRouteMetric5_get(inetCidrRouteTable_rowreq_ctx * rowreq_ctx,
                         long *inetCidrRouteMetric5_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != inetCidrRouteMetric5_val_ptr);


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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the inetCidrRouteMetric5 data->
     * copy (* inetCidrRouteMetric5_val_ptr ) from rowreq_ctx->data
     */
    /*
     * TODO:235:M: |-> Remove log message/SKIP once you've set inetCidrRouteMetric5 data
     */
    (*inetCidrRouteMetric5_val_ptr) = rowreq_ctx->data->rt_metric5;

    return MFD_SUCCESS;
}                               /* inetCidrRouteMetric5_get */

/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::inetCidrRouteEntry.inetCidrRouteStatus
 * inetCidrRouteStatus is subid 17 of inetCidrRouteEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.24.7.1.17
 * Description:
The row status variable, used according to row  
                installation and removal conventions. 

                A row entry cannot be modified when the status is 
                marked as active(1).
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *
 * Enum range: 3/8. Values:  active(1), notInService(2), notReady(3), createAndGo(4), createAndWait(5), destroy(6)
 *
 * Its syntax is RowStatus (based on perltype INTEGER)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
 */
/**
 * Extract the current value of the inetCidrRouteStatus data->
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param inetCidrRouteStatus_val_ptr
 *        Pointer to storage for a long variable
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
 */
int
inetCidrRouteStatus_get(inetCidrRouteTable_rowreq_ctx * rowreq_ctx,
                        u_long * inetCidrRouteStatus_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != inetCidrRouteStatus_val_ptr);

    /** WARNING: this code might not work for netsnmp_route_entry */
    (*inetCidrRouteStatus_val_ptr) = rowreq_ctx->row_status;

    return MFD_SUCCESS;
}                               /* inetCidrRouteStatus_get */



/** @} */
/**********************************************************************
 **********************************************************************
 ***
 *** Table inetCidrRouteTable
 ***
 **********************************************************************
 **********************************************************************/
/*
 * IP-FORWARD-MIB::inetCidrRouteTable is subid 7 of ipForward.
 * Its status is Current.
 * OID: .1.3.6.1.2.1.4.24.7, length: 9
 */
    /*
     * NOTE: if you update this chart, please update the versions in
     *       local/mib2c-conf.d/parent-set.m2i
     *       agent/mibgroup/helpers/baby_steps.c
     * while you're at it.
     */
    /*
     ***********************************************************************
     * Baby Steps Flow Chart (2004.06.05)                                  *
     *                                                                     *
     * +--------------+    +================+    U = unconditional path    *
     * |optional state|    ||required state||    S = path for success      *
     * +--------------+    +================+    E = path for error        *
     ***********************************************************************
     *
     *                        +--------------+
     *                        |     pre      |
     *                        |   request    |
     *                        +--------------+
     *                               | U
     * +-------------+        +==============+
     * |    row    |f|<-------||  object    ||
     * |  create   |1|      E ||  lookup    ||
     * +-------------+        +==============+
     *     E |   | S                 | S
     *       |   +------------------>|
     *       |                +==============+
     *       |              E ||   check    ||
     *       |<---------------||   values   ||
     *       |                +==============+
     *       |                       | S
     *       |                +==============+
     *       |       +<-------||   undo     ||
     *       |       |      E ||   setup    ||
     *       |       |        +==============+
     *       |       |               | S
     *       |       |        +==============+
     *       |       |        ||    set     ||-------------------------->+
     *       |       |        ||   value    || E                         |
     *       |       |        +==============+                           |
     *       |       |               | S                                 |
     *       |       |        +--------------+                           |
     *       |       |        |    check     |-------------------------->|
     *       |       |        |  consistency | E                         |
     *       |       |        +--------------+                           |
     *       |       |               | S                                 |
     *       |       |        +==============+         +==============+  |
     *       |       |        ||   commit   ||-------->||     undo   ||  |
     *       |       |        ||            || E       ||    commit  ||  |
     *       |       |        +==============+         +==============+  |
     *       |       |               | S                     U |<--------+
     *       |       |        +--------------+         +==============+
     *       |       |        | irreversible |         ||    undo    ||
     *       |       |        |    commit    |         ||     set    ||
     *       |       |        +--------------+         +==============+
     *       |       |               | U                     U |
     *       |       +-------------->|<------------------------+
     *       |                +==============+
     *       |                ||   undo     ||
     *       |                ||  cleanup   ||
     *       |                +==============+
     *       +---------------------->| U
     *                               |
     *                          (err && f1)------------------->+
     *                               |                         |
     *                        +--------------+         +--------------+
     *                        |    post      |<--------|      row     |
     *                        |   request    |       U |    release   |
     *                        +--------------+         +--------------+
     *
     */

/**
 * Setup up context with information needed to undo a set request.
 *
 * This function will be called before the individual node undo setup
 * functions are called. If you need to do any undo setup that is not
 * related to a specific column, you can do it here.
 *
 * Note that the undo context has been allocated with
 * inetCidrRouteTable_allocate_data(), but may need extra
 * initialization similar to what you may have done in
 * inetCidrRouteTable_rowreq_ctx_init().
 * Note that an individual node's undo_setup function will only be called
 * if that node is being set to a new value.
 *
 * If there is any setup specific to a particular column (e.g. allocating
 * memory for a string), you should do that setup in the node's undo_setup
 * function, so it won't be done unless it is necessary.
 *
 * @param rowreq_ctx
 *        Pointer to the table context (inetCidrRouteTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 */
int
inetCidrRouteTable_undo_setup(inetCidrRouteTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

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

    /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:451:M: |-> Setup inetCidrRouteTable undo.
     * set up inetCidrRouteTable undo information, in preparation for a set.
     * Undo storage is in (* inetCidrRouteStatus_val_ptr )*
     */
    rowreq_ctx->row_status_undo = rowreq_ctx->row_status;

    rc = netsnmp_access_route_entry_copy(rowreq_ctx->undo,
                                         rowreq_ctx->data);

    return rc;
}                               /* inetCidrRouteTable_undo_setup */

/**
 * Undo a set request.
 *
 * This function will be called before the individual node undo
 * functions are called. If you need to do any undo that is not
 * related to a specific column, you can do it here.
 *
 * Note that an individual node's undo function will only be called
 * if that node is being set to a new value.
 *
 * If there is anything  specific to a particular column (e.g. releasing
 * memory for a string), you should do that setup in the node's undo
 * function, so it won't be done unless it is necessary.
 *
 * @param rowreq_ctx
 *        Pointer to the table context (inetCidrRouteTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 */
int
inetCidrRouteTable_undo(inetCidrRouteTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

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

    /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:451:M: |-> inetCidrRouteTable undo.
     * inetCidrRouteTable undo information, in response to a failed set.
     * Undo storage is in (* inetCidrRouteStatus_val_ptr )*
     */
    rowreq_ctx->row_status = rowreq_ctx->row_status_undo;

    rc = netsnmp_access_route_entry_copy(rowreq_ctx->data,
                                         rowreq_ctx->undo);

    return rc;
}                               /* inetCidrRouteTable_undo_setup */

/**
 * Cleanup up context undo information.
 *
 * This function will be called after set/commit processing. If you
 * allocated any resources in undo_setup, this is the place to release
 * those resources.
 *
 * This function is called regardless of the success or failure of the set
 * request. If you need to perform different steps for cleanup depending
 * on success or failure, you can add a flag to the rowreq_ctx.
 *
 * @param rowreq_ctx
 *        Pointer to the table context (inetCidrRouteTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error
 */
int
inetCidrRouteTable_undo_cleanup(inetCidrRouteTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

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

    /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:452:M: |-> Cleanup inetCidrRouteTable undo.
     * Undo storage is in (* inetCidrRouteStatus_val_ptr )*
     */

    return rc;
}                               /* inetCidrRouteTable_undo_cleanup */

/**
 * commit new values.
 *
 * At this point, you should have done everything you can to ensure that
 * this commit will not fail.
 *
 * Should you need different behavior depending on which columns were
 * set, rowreq_ctx->column_set_flags will indicate which writeable columns were
 * set. The definitions for the COLUMN_*_FLAG bits can be found in
 * inetCidrRouteTable.h.
 * A new row will have the MFD_ROW_CREATED bit set in rowreq_flags.
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error
 */
int
inetCidrRouteTable_commit(inetCidrRouteTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;
    int             save_flags;

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

    /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * save flags, then clear until we actually do something
     */
    save_flags = rowreq_ctx->column_set_flags;
    rowreq_ctx->column_set_flags = 0;

    /*
     * commit inetCidrRouteTable data
     * 1) check the column's flag in save_flags to see if it was set.
     * 2) clear the flag when you handle that column
     * 3) set the column's flag in column_set_flags if it needs undo
     *    processing in case of a failure.
     */
    /*
     * did anything change?
     */
    if (0 == save_flags) {
        DEBUGMSGTL(("ipAddressTable:ipAddressTable_commit",
                    "no change\n"));
        return MFD_SUCCESS;
    }

    /*
     * pass everything to data access
     */
    if (save_flags & COLUMN_INETCIDRROUTESTATUS_FLAG) {
        if (rowreq_ctx->rowreq_flags & MFD_ROW_CREATED) {
            if (ROWSTATUS_DESTROY == rowreq_ctx->row_status) {
                rowreq_ctx->rowreq_flags |= MFD_ROW_DELETED;
                return MFD_SUCCESS;
            }
            netsnmp_assert(ROWSTATUS_ACTIVE == rowreq_ctx->row_status);
            rowreq_ctx->data->flags |= NETSNMP_ACCESS_ROUTE_CREATE;
        } else if (ROWSTATUS_DESTROY == rowreq_ctx->row_status) {
            rowreq_ctx->data->flags |= NETSNMP_ACCESS_ROUTE_DELETE;
        } else
            rowreq_ctx->data->flags |= NETSNMP_ACCESS_ROUTE_CHANGE;
    } else
        rowreq_ctx->data->flags |= NETSNMP_ACCESS_ROUTE_CHANGE;

    /*
     * do it
     * let data access know what columns are set
     */
    rowreq_ctx->data->flags |=
        (save_flags & NETSNMP_ACCESS_ROUTE_RESERVED_BITS);
    rc = netsnmp_access_route_entry_set(rowreq_ctx->data);
    if (rc) {
        snmp_log(LOG_ERR,
                 "inetCidrRouteTable column inetCidrRouteStatus commit failed\n");
        rc = MFD_ERROR;
    } else {
        /*
         * set flag, in case we need to undo 
         */
        rowreq_ctx->column_set_flags |= save_flags;
    }

    /*
     * if we successfully commited this row, set the dirty flag.
     */
    if (MFD_SUCCESS == rc) {
        rowreq_ctx->rowreq_flags |= MFD_ROW_DIRTY;
    }

    return rc;
}                               /* inetCidrRouteTable_commit */

/**
 * undo commit new values.
 *
 * Should you need different behavior depending on which columns were
 * set, rowreq_ctx->column_set_flags will indicate which writeable columns were
 * set. The definitions for the COLUMN_*_FLAG bits can be found in
 * inetCidrRouteTable.h.
 * A new row will have the MFD_ROW_CREATED bit set in rowreq_flags.
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error
 */
int
inetCidrRouteTable_undo_commit(inetCidrRouteTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

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

    /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:485:M: |-> Undo inetCidrRouteTable commit.
     * check the column's flag in rowreq_ctx->column_set_flags to see
     * if it was set during commit, then undo it.
     *
     * eg: if (rowreq_ctx->column_set_flags & COLUMN__FLAG) {}
     */
    if (rowreq_ctx->column_set_flags & COLUMN_INETCIDRROUTESTATUS_FLAG) {
        /*
         * if we created an addr, delete it. if we deleted it,
         * re-create it. If we changed it, change it back.
         */
        if (rowreq_ctx->rowreq_flags & MFD_ROW_CREATED) {
            rowreq_ctx->undo->flags |= NETSNMP_ACCESS_ROUTE_DELETE;
        } else if (ROWSTATUS_DESTROY == rowreq_ctx->row_status) {
            rowreq_ctx->undo->flags |= NETSNMP_ACCESS_ROUTE_CREATE;
        } else
            rowreq_ctx->undo->flags |= NETSNMP_ACCESS_ROUTE_CHANGE;
    } else
        rowreq_ctx->undo->flags |= NETSNMP_ACCESS_ROUTE_CHANGE;

    /*
     * do it
     */
    rc = netsnmp_access_route_entry_set(rowreq_ctx->undo);
    if (rc) {
        DEBUGMSGTL(("ipAddressTable",
                    "bad rc %d from IP address data access\n", rc));
        rc = MFD_ERROR;
    }

    /*
     * if we successfully un-commited this row, clear the dirty flag.
     */
    if (MFD_SUCCESS == rc) {
        rowreq_ctx->rowreq_flags &= ~MFD_ROW_DIRTY;
    }

    return rc;
}                               /* inetCidrRouteTable_undo_commit */

/*
 * TODO:440:M: Implement inetCidrRouteTable node value checks.
 * TODO:450:M: Implement inetCidrRouteTable undo functions.
 * TODO:460:M: Implement inetCidrRouteTable set functions.
 * TODO:480:M: Implement inetCidrRouteTable commit functions.
 */
/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::inetCidrRouteEntry.inetCidrRouteIfIndex
 * inetCidrRouteIfIndex is subid 7 of inetCidrRouteEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.24.7.1.7
 * Description:
The ifIndex value which identifies the local interface 
                through which the next hop of this route should be  
                reached.  A value of 0 is valid and represents the 
                scenario where no interface is specified.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 1      hashint   1
 *   settable   1
 *   hint: d
 *
 * Ranges:  0 - 2147483647;
 *
 * Its syntax is InterfaceIndexOrZero (based on perltype INTEGER32)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (long)
 */
/**
 * Check that the proposed new value is potentially valid.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param inetCidrRouteIfIndex_val
 *        A long containing the new value.
 *
 * @retval MFD_SUCCESS        : incoming value is legal
 * @retval MFD_NOT_VALID_NOW  : incoming value is not valid now
 * @retval MFD_NOT_VALID_EVER : incoming value is never valid
 *
 * This is the place to check for requirements that are not
 * expressed in the mib syntax (for example, a requirement that
 * is detailed in the description for an object).
 *
 * You should check that the requested change between the undo value and the
 * new value is legal (ie, the transistion from one value to another
 * is legal).
 *      
 *@note
 * This check is only to determine if the new value
 * is \b potentially valid. This is the first check of many, and
 * is one of the simplest ones.
 * 
 *@note
 * this is not the place to do any checks for values
 * which depend on some other value in the mib. Those
 * types of checks should be done in the
 * inetCidrRouteTable_check_dependencies() function.
 *
 * The following checks have already been done for you:
 *    The syntax is ASN_INTEGER
 *    The value is in (one of) the range set(s):  0 - 2147483647
 *
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
 *
 */
int
inetCidrRouteIfIndex_check_value(inetCidrRouteTable_rowreq_ctx *
                                 rowreq_ctx, long inetCidrRouteIfIndex_val)
{
    DEBUGMSGTL(("verbose:inetCidrRouteTable:inetCidrRouteIfIndex_check_value", "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:441:o: |-> Check for valid inetCidrRouteIfIndex value.
     */

    return MFD_SUCCESS;         /* inetCidrRouteIfIndex value not illegal */
}                               /* inetCidrRouteIfIndex_check_value */

/**
 * Set the new value.
 *
 * @param rowreq_ctx
 *        Pointer to the users context. You should know how to
 *        manipulate the value from this object.
 * @param inetCidrRouteIfIndex_val
 *        A long containing the new value.
 */
int
inetCidrRouteIfIndex_set(inetCidrRouteTable_rowreq_ctx * rowreq_ctx,
                         long inetCidrRouteIfIndex_val)
{

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

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:461:M: |-> Set inetCidrRouteIfIndex value.
     * set inetCidrRouteIfIndex value in rowreq_ctx->data
     */
    rowreq_ctx->data->if_index = inetCidrRouteIfIndex_val;

    return MFD_SUCCESS;
}                               /* inetCidrRouteIfIndex_set */

/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::inetCidrRouteEntry.inetCidrRouteType
 * inetCidrRouteType is subid 8 of inetCidrRouteEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.24.7.1.8
 * Description:
The type of route.  Note that local(3) refers to a  
                route for which the next hop is the final destination;  
                remote(4)refers to a route for which the next hop is  
                not the final destination. 

                Routes which do not result in traffic forwarding or 
                rejection should not be displayed even if the  
                implementation keeps them stored internally. 

                reject(2) refers to a route which, if matched, discards  
                the message as unreachable and returns a notification  
                (e.g. ICMP error) to the message sender.  This is used  
                in some protocols as a means of correctly aggregating  
                routes. 

                blackhole(5) refers to a route which, if matched,  
                discards the message silently.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *
 * Enum range: 3/8. Values:  other(1), reject(2), local(3), remote(4), blackhole(5)
 *
 * Its syntax is INTEGER (based on perltype INTEGER)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
 */
/**
 * Check that the proposed new value is potentially valid.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param inetCidrRouteType_val
 *        A long containing the new value.
 *
 * @retval MFD_SUCCESS        : incoming value is legal
 * @retval MFD_NOT_VALID_NOW  : incoming value is not valid now
 * @retval MFD_NOT_VALID_EVER : incoming value is never valid
 *
 * This is the place to check for requirements that are not
 * expressed in the mib syntax (for example, a requirement that
 * is detailed in the description for an object).
 *
 * You should check that the requested change between the undo value and the
 * new value is legal (ie, the transistion from one value to another
 * is legal).
 *      
 *@note
 * This check is only to determine if the new value
 * is \b potentially valid. This is the first check of many, and
 * is one of the simplest ones.
 * 
 *@note
 * this is not the place to do any checks for values
 * which depend on some other value in the mib. Those
 * types of checks should be done in the
 * inetCidrRouteTable_check_dependencies() function.
 *
 * The following checks have already been done for you:
 *    The syntax is ASN_INTEGER
 *    The value is one of  other(1), reject(2), local(3), remote(4), blackhole(5)
 *
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
 *
 */
int
inetCidrRouteType_check_value(inetCidrRouteTable_rowreq_ctx * rowreq_ctx,
                              u_long inetCidrRouteType_val)
{
    DEBUGMSGTL(("verbose:inetCidrRouteTable:inetCidrRouteType_check_value",
                "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:441:o: |-> Check for valid inetCidrRouteType value.
     */

    return MFD_SUCCESS;         /* inetCidrRouteType value not illegal */
}                               /* inetCidrRouteType_check_value */

/**
 * Set the new value.
 *
 * @param rowreq_ctx
 *        Pointer to the users context. You should know how to
 *        manipulate the value from this object.
 * @param inetCidrRouteType_val
 *        A long containing the new value.
 */
int
inetCidrRouteType_set(inetCidrRouteTable_rowreq_ctx * rowreq_ctx,
                      u_long inetCidrRouteType_val)
{

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

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:461:M: |-> Set inetCidrRouteType value.
     * set inetCidrRouteType value in rowreq_ctx->data
     */
    rowreq_ctx->data->rt_type = inetCidrRouteType_val;

    return MFD_SUCCESS;
}                               /* inetCidrRouteType_set */

/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::inetCidrRouteEntry.inetCidrRouteNextHopAS
 * inetCidrRouteNextHopAS is subid 11 of inetCidrRouteEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.24.7.1.11
 * Description:
The Autonomous System Number of the Next Hop.  The  
                semantics of this object are determined by the routing- 
                protocol specified in the route's inetCidrRouteProto  
                value. When this object is unknown or not relevant its  
                value should be set to zero.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 1
 *   readable   1     iscolumn 1     ranges 0      hashint   1
 *   settable   1
 *   defval: 0
 *   hint: d
 *
 *
 * Its syntax is InetAutonomousSystemNumber (based on perltype UNSIGNED32)
 * The net-snmp type is ASN_UNSIGNED. The C type decl is u_long (u_long)
 */
/**
 * Check that the proposed new value is potentially valid.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param inetCidrRouteNextHopAS_val
 *        A u_long containing the new value.
 *
 * @retval MFD_SUCCESS        : incoming value is legal
 * @retval MFD_NOT_VALID_NOW  : incoming value is not valid now
 * @retval MFD_NOT_VALID_EVER : incoming value is never valid
 *
 * This is the place to check for requirements that are not
 * expressed in the mib syntax (for example, a requirement that
 * is detailed in the description for an object).
 *
 * You should check that the requested change between the undo value and the
 * new value is legal (ie, the transistion from one value to another
 * is legal).
 *      
 *@note
 * This check is only to determine if the new value
 * is \b potentially valid. This is the first check of many, and
 * is one of the simplest ones.
 * 
 *@note
 * this is not the place to do any checks for values
 * which depend on some other value in the mib. Those
 * types of checks should be done in the
 * inetCidrRouteTable_check_dependencies() function.
 *
 * The following checks have already been done for you:
 *    The syntax is ASN_UNSIGNED
 *
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
 *
 */
int
inetCidrRouteNextHopAS_check_value(inetCidrRouteTable_rowreq_ctx *
                                   rowreq_ctx,
                                   u_long inetCidrRouteNextHopAS_val)
{
    DEBUGMSGTL(("verbose:inetCidrRouteTable:inetCidrRouteNextHopAS_check_value", "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:441:o: |-> Check for valid inetCidrRouteNextHopAS value.
     */

    return MFD_SUCCESS;         /* inetCidrRouteNextHopAS value not illegal */
}                               /* inetCidrRouteNextHopAS_check_value */

/**
 * Set the new value.
 *
 * @param rowreq_ctx
 *        Pointer to the users context. You should know how to
 *        manipulate the value from this object.
 * @param inetCidrRouteNextHopAS_val
 *        A u_long containing the new value.
 */
int
inetCidrRouteNextHopAS_set(inetCidrRouteTable_rowreq_ctx * rowreq_ctx,
                           u_long inetCidrRouteNextHopAS_val)
{

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

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:461:M: |-> Set inetCidrRouteNextHopAS value.
     * set inetCidrRouteNextHopAS value in rowreq_ctx->data
     */
    rowreq_ctx->data->rt_nexthop_type = inetCidrRouteNextHopAS_val;

    return MFD_SUCCESS;
}                               /* inetCidrRouteNextHopAS_set */

/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::inetCidrRouteEntry.inetCidrRouteMetric1
 * inetCidrRouteMetric1 is subid 12 of inetCidrRouteEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.24.7.1.12
 * Description:
The primary routing metric for this route.  The  
                semantics of this metric are determined by the routing- 
                protocol specified in the route's inetCidrRouteProto  
                value.  If this metric is not used, its value should be  
                set to -1.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 1
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *   defval: -1
 *
 *
 * Its syntax is INTEGER32 (based on perltype INTEGER32)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (long)
 */
/**
 * Check that the proposed new value is potentially valid.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param inetCidrRouteMetric1_val
 *        A long containing the new value.
 *
 * @retval MFD_SUCCESS        : incoming value is legal
 * @retval MFD_NOT_VALID_NOW  : incoming value is not valid now
 * @retval MFD_NOT_VALID_EVER : incoming value is never valid
 *
 * This is the place to check for requirements that are not
 * expressed in the mib syntax (for example, a requirement that
 * is detailed in the description for an object).
 *
 * You should check that the requested change between the undo value and the
 * new value is legal (ie, the transistion from one value to another
 * is legal).
 *      
 *@note
 * This check is only to determine if the new value
 * is \b potentially valid. This is the first check of many, and
 * is one of the simplest ones.
 * 
 *@note
 * this is not the place to do any checks for values
 * which depend on some other value in the mib. Those
 * types of checks should be done in the
 * inetCidrRouteTable_check_dependencies() function.
 *
 * The following checks have already been done for you:
 *    The syntax is ASN_INTEGER
 *
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
 *
 */
int
inetCidrRouteMetric1_check_value(inetCidrRouteTable_rowreq_ctx *
                                 rowreq_ctx, long inetCidrRouteMetric1_val)
{
    DEBUGMSGTL(("verbose:inetCidrRouteTable:inetCidrRouteMetric1_check_value", "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:441:o: |-> Check for valid inetCidrRouteMetric1 value.
     */

    return MFD_SUCCESS;         /* inetCidrRouteMetric1 value not illegal */
}                               /* inetCidrRouteMetric1_check_value */

/**
 * Set the new value.
 *
 * @param rowreq_ctx
 *        Pointer to the users context. You should know how to
 *        manipulate the value from this object.
 * @param inetCidrRouteMetric1_val
 *        A long containing the new value.
 */
int
inetCidrRouteMetric1_set(inetCidrRouteTable_rowreq_ctx * rowreq_ctx,
                         long inetCidrRouteMetric1_val)
{

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

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:461:M: |-> Set inetCidrRouteMetric1 value.
     * set inetCidrRouteMetric1 value in rowreq_ctx->data
     */
    rowreq_ctx->data->rt_metric1 = inetCidrRouteMetric1_val;

    return MFD_SUCCESS;
}                               /* inetCidrRouteMetric1_set */

/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::inetCidrRouteEntry.inetCidrRouteMetric2
 * inetCidrRouteMetric2 is subid 13 of inetCidrRouteEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.24.7.1.13
 * Description:
An alternate routing metric for this route.  The  
                semantics of this metric are determined by the routing- 
                protocol specified in the route's inetCidrRouteProto  
                value.  If this metric is not used, its value should be  
                set to -1.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 1
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *   defval: -1
 *
 *
 * Its syntax is INTEGER32 (based on perltype INTEGER32)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (long)
 */
/**
 * Check that the proposed new value is potentially valid.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param inetCidrRouteMetric2_val
 *        A long containing the new value.
 *
 * @retval MFD_SUCCESS        : incoming value is legal
 * @retval MFD_NOT_VALID_NOW  : incoming value is not valid now
 * @retval MFD_NOT_VALID_EVER : incoming value is never valid
 *
 * This is the place to check for requirements that are not
 * expressed in the mib syntax (for example, a requirement that
 * is detailed in the description for an object).
 *
 * You should check that the requested change between the undo value and the
 * new value is legal (ie, the transistion from one value to another
 * is legal).
 *      
 *@note
 * This check is only to determine if the new value
 * is \b potentially valid. This is the first check of many, and
 * is one of the simplest ones.
 * 
 *@note
 * this is not the place to do any checks for values
 * which depend on some other value in the mib. Those
 * types of checks should be done in the
 * inetCidrRouteTable_check_dependencies() function.
 *
 * The following checks have already been done for you:
 *    The syntax is ASN_INTEGER
 *
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
 *
 */
int
inetCidrRouteMetric2_check_value(inetCidrRouteTable_rowreq_ctx *
                                 rowreq_ctx, long inetCidrRouteMetric2_val)
{
    DEBUGMSGTL(("verbose:inetCidrRouteTable:inetCidrRouteMetric2_check_value", "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:441:o: |-> Check for valid inetCidrRouteMetric2 value.
     */
    /*
     * does any os use metrics 2-5? If so, update this to deal with it.
     */

    return MFD_NOT_VALID_EVER;
}                               /* inetCidrRouteMetric2_check_value */

/**
 * Set the new value.
 *
 * @param rowreq_ctx
 *        Pointer to the users context. You should know how to
 *        manipulate the value from this object.
 * @param inetCidrRouteMetric2_val
 *        A long containing the new value.
 */
int
inetCidrRouteMetric2_set(inetCidrRouteTable_rowreq_ctx * rowreq_ctx,
                         long inetCidrRouteMetric2_val)
{

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

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:461:M: |-> Set inetCidrRouteMetric2 value.
     * set inetCidrRouteMetric2 value in rowreq_ctx->data
     */
    rowreq_ctx->data->rt_metric2 = inetCidrRouteMetric2_val;

    return MFD_SUCCESS;
}                               /* inetCidrRouteMetric2_set */

/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::inetCidrRouteEntry.inetCidrRouteMetric3
 * inetCidrRouteMetric3 is subid 14 of inetCidrRouteEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.24.7.1.14
 * Description:
An alternate routing metric for this route.  The  
                semantics of this metric are determined by the routing- 
                protocol specified in the route's inetCidrRouteProto  
                value.  If this metric is not used, its value should be  
                set to -1.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 1
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *   defval: -1
 *
 *
 * Its syntax is INTEGER32 (based on perltype INTEGER32)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (long)
 */
/**
 * Check that the proposed new value is potentially valid.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param inetCidrRouteMetric3_val
 *        A long containing the new value.
 *
 * @retval MFD_SUCCESS        : incoming value is legal
 * @retval MFD_NOT_VALID_NOW  : incoming value is not valid now
 * @retval MFD_NOT_VALID_EVER : incoming value is never valid
 *
 * This is the place to check for requirements that are not
 * expressed in the mib syntax (for example, a requirement that
 * is detailed in the description for an object).
 *
 * You should check that the requested change between the undo value and the
 * new value is legal (ie, the transistion from one value to another
 * is legal).
 *      
 *@note
 * This check is only to determine if the new value
 * is \b potentially valid. This is the first check of many, and
 * is one of the simplest ones.
 * 
 *@note
 * this is not the place to do any checks for values
 * which depend on some other value in the mib. Those
 * types of checks should be done in the
 * inetCidrRouteTable_check_dependencies() function.
 *
 * The following checks have already been done for you:
 *    The syntax is ASN_INTEGER
 *
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
 *
 */
int
inetCidrRouteMetric3_check_value(inetCidrRouteTable_rowreq_ctx *
                                 rowreq_ctx, long inetCidrRouteMetric3_val)
{
    DEBUGMSGTL(("verbose:inetCidrRouteTable:inetCidrRouteMetric3_check_value", "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:441:o: |-> Check for valid inetCidrRouteMetric3 value.
     */
    /*
     * does any os use metrics 2-5? If so, update this to deal with it.
     */

    return MFD_NOT_VALID_NOW;
}                               /* inetCidrRouteMetric3_check_value */

/**
 * Set the new value.
 *
 * @param rowreq_ctx
 *        Pointer to the users context. You should know how to
 *        manipulate the value from this object.
 * @param inetCidrRouteMetric3_val
 *        A long containing the new value.
 */
int
inetCidrRouteMetric3_set(inetCidrRouteTable_rowreq_ctx * rowreq_ctx,
                         long inetCidrRouteMetric3_val)
{

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

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:461:M: |-> Set inetCidrRouteMetric3 value.
     * set inetCidrRouteMetric3 value in rowreq_ctx->data
     */
    rowreq_ctx->data->rt_metric3 = inetCidrRouteMetric3_val;

    return MFD_SUCCESS;
}                               /* inetCidrRouteMetric3_set */

/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::inetCidrRouteEntry.inetCidrRouteMetric4
 * inetCidrRouteMetric4 is subid 15 of inetCidrRouteEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.24.7.1.15
 * Description:
An alternate routing metric for this route.  The  
                semantics of this metric are determined by the routing- 
                protocol specified in the route's inetCidrRouteProto  
                value.  If this metric is not used, its value should be  
                set to -1.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 1
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *   defval: -1
 *
 *
 * Its syntax is INTEGER32 (based on perltype INTEGER32)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (long)
 */
/**
 * Check that the proposed new value is potentially valid.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param inetCidrRouteMetric4_val
 *        A long containing the new value.
 *
 * @retval MFD_SUCCESS        : incoming value is legal
 * @retval MFD_NOT_VALID_NOW  : incoming value is not valid now
 * @retval MFD_NOT_VALID_EVER : incoming value is never valid
 *
 * This is the place to check for requirements that are not
 * expressed in the mib syntax (for example, a requirement that
 * is detailed in the description for an object).
 *
 * You should check that the requested change between the undo value and the
 * new value is legal (ie, the transistion from one value to another
 * is legal).
 *      
 *@note
 * This check is only to determine if the new value
 * is \b potentially valid. This is the first check of many, and
 * is one of the simplest ones.
 * 
 *@note
 * this is not the place to do any checks for values
 * which depend on some other value in the mib. Those
 * types of checks should be done in the
 * inetCidrRouteTable_check_dependencies() function.
 *
 * The following checks have already been done for you:
 *    The syntax is ASN_INTEGER
 *
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
 *
 */
int
inetCidrRouteMetric4_check_value(inetCidrRouteTable_rowreq_ctx *
                                 rowreq_ctx, long inetCidrRouteMetric4_val)
{
    DEBUGMSGTL(("verbose:inetCidrRouteTable:inetCidrRouteMetric4_check_value", "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:441:o: |-> Check for valid inetCidrRouteMetric4 value.
     */
    /*
     * does any os use metrics 2-5? If so, update this to deal with it.
     */

    return MFD_NOT_VALID_NOW;
}                               /* inetCidrRouteMetric4_check_value */

/**
 * Set the new value.
 *
 * @param rowreq_ctx
 *        Pointer to the users context. You should know how to
 *        manipulate the value from this object.
 * @param inetCidrRouteMetric4_val
 *        A long containing the new value.
 */
int
inetCidrRouteMetric4_set(inetCidrRouteTable_rowreq_ctx * rowreq_ctx,
                         long inetCidrRouteMetric4_val)
{

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

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:461:M: |-> Set inetCidrRouteMetric4 value.
     * set inetCidrRouteMetric4 value in rowreq_ctx->data
     */
    rowreq_ctx->data->rt_metric4 = inetCidrRouteMetric4_val;

    return MFD_SUCCESS;
}                               /* inetCidrRouteMetric4_set */

/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::inetCidrRouteEntry.inetCidrRouteMetric5
 * inetCidrRouteMetric5 is subid 16 of inetCidrRouteEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.24.7.1.16
 * Description:
An alternate routing metric for this route.  The  
                semantics of this metric are determined by the routing- 
                protocol specified in the route's inetCidrRouteProto  
                value.  If this metric is not used, its value should be  
                set to -1.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 1
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *   defval: -1
 *
 *
 * Its syntax is INTEGER32 (based on perltype INTEGER32)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (long)
 */
/**
 * Check that the proposed new value is potentially valid.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param inetCidrRouteMetric5_val
 *        A long containing the new value.
 *
 * @retval MFD_SUCCESS        : incoming value is legal
 * @retval MFD_NOT_VALID_NOW  : incoming value is not valid now
 * @retval MFD_NOT_VALID_EVER : incoming value is never valid
 *
 * This is the place to check for requirements that are not
 * expressed in the mib syntax (for example, a requirement that
 * is detailed in the description for an object).
 *
 * You should check that the requested change between the undo value and the
 * new value is legal (ie, the transistion from one value to another
 * is legal).
 *      
 *@note
 * This check is only to determine if the new value
 * is \b potentially valid. This is the first check of many, and
 * is one of the simplest ones.
 * 
 *@note
 * this is not the place to do any checks for values
 * which depend on some other value in the mib. Those
 * types of checks should be done in the
 * inetCidrRouteTable_check_dependencies() function.
 *
 * The following checks have already been done for you:
 *    The syntax is ASN_INTEGER
 *
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
 *
 */
int
inetCidrRouteMetric5_check_value(inetCidrRouteTable_rowreq_ctx *
                                 rowreq_ctx, long inetCidrRouteMetric5_val)
{
    DEBUGMSGTL(("verbose:inetCidrRouteTable:inetCidrRouteMetric5_check_value", "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:441:o: |-> Check for valid inetCidrRouteMetric5 value.
     */
    /*
     * does any os use metrics 2-5? If so, update this to deal with it.
     */
    return MFD_NOT_VALID_NOW;
}                               /* inetCidrRouteMetric5_check_value */

/**
 * Set the new value.
 *
 * @param rowreq_ctx
 *        Pointer to the users context. You should know how to
 *        manipulate the value from this object.
 * @param inetCidrRouteMetric5_val
 *        A long containing the new value.
 */
int
inetCidrRouteMetric5_set(inetCidrRouteTable_rowreq_ctx * rowreq_ctx,
                         long inetCidrRouteMetric5_val)
{

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

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:461:M: |-> Set inetCidrRouteMetric5 value.
     * set inetCidrRouteMetric5 value in rowreq_ctx->data
     */
    rowreq_ctx->data->rt_metric5 = inetCidrRouteMetric5_val;

    return MFD_SUCCESS;
}                               /* inetCidrRouteMetric5_set */

/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::inetCidrRouteEntry.inetCidrRouteStatus
 * inetCidrRouteStatus is subid 17 of inetCidrRouteEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.24.7.1.17
 * Description:
The row status variable, used according to row  
                installation and removal conventions. 

                A row entry cannot be modified when the status is 
                marked as active(1).
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  1      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *
 * Enum range: 3/8. Values:  active(1), notInService(2), notReady(3), createAndGo(4), createAndWait(5), destroy(6)
 *
 * Its syntax is RowStatus (based on perltype INTEGER)
 * The net-snmp type is ASN_INTEGER. The C type decl is long (u_long)
 */
/**
 * Check that the proposed new value is potentially valid.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param inetCidrRouteStatus_val
 *        A long containing the new value.
 *
 * @retval MFD_SUCCESS        : incoming value is legal
 * @retval MFD_NOT_VALID_NOW  : incoming value is not valid now
 * @retval MFD_NOT_VALID_EVER : incoming value is never valid
 *
 * This is the place to check for requirements that are not
 * expressed in the mib syntax (for example, a requirement that
 * is detailed in the description for an object).
 *
 * You should check that the requested change between the undo value and the
 * new value is legal (ie, the transistion from one value to another
 * is legal).
 *      
 *@note
 * This check is only to determine if the new value
 * is \b potentially valid. This is the first check of many, and
 * is one of the simplest ones.
 * 
 *@note
 * this is not the place to do any checks for values
 * which depend on some other value in the mib. Those
 * types of checks should be done in the
 * inetCidrRouteTable_check_dependencies() function.
 *
 * The following checks have already been done for you:
 *    The syntax is ASN_INTEGER
 *    The value is one of  active(1), notInService(2), notReady(3), createAndGo(4), createAndWait(5), destroy(6)
 *
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
 *
 */
int
inetCidrRouteStatus_check_value(inetCidrRouteTable_rowreq_ctx * rowreq_ctx,
                                u_long inetCidrRouteStatus_val)
{
    DEBUGMSGTL(("verbose:inetCidrRouteTable:inetCidrRouteStatus_check_value", "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:441:o: |-> Check for valid inetCidrRouteStatus value.
     */

    return MFD_SUCCESS;         /* inetCidrRouteStatus value not illegal */
}                               /* inetCidrRouteStatus_check_value */

/**
 * Set the new value.
 *
 * @param rowreq_ctx
 *        Pointer to the users context. You should know how to
 *        manipulate the value from this object.
 * @param inetCidrRouteStatus_val
 *        A long containing the new value.
 */
int
inetCidrRouteStatus_set(inetCidrRouteTable_rowreq_ctx * rowreq_ctx,
                        u_long inetCidrRouteStatus_val)
{

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

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:461:M: |-> Set inetCidrRouteStatus value.
     * set inetCidrRouteStatus value in rowreq_ctx->data
     */
    rowreq_ctx->row_status = inetCidrRouteStatus_val;

    return MFD_SUCCESS;
}                               /* inetCidrRouteStatus_set */

/**
 * check dependencies
 *
 * This is useful for for tables which have dependencies between columns
 * (or rows, or tables). For example, two columns allocating a percentage
 * of something add up 100%.
 *
 * Should you need different behavior depending on which columns were
 * set, rowreq_ctx->column_set_flags will indicate which writeable columns were
 * set. The definitions for the COLUMN_*_FLAG bits can be found in
 * inetCidrRouteTable.h.
 * A new row will have the MFD_ROW_CREATED bit set in rowreq_flags.
 *
 * @retval MFD_SUCCESS all the changes to the row are legal
 * @retval MFD_ERROR   one or more changes are not legal
 *
 * (see README-table-inetCidrRouteTable if you don't have dependencies)
 */
int
inetCidrRouteTable_check_dependencies(inetCidrRouteTable_rowreq_ctx *
                                      rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:470:o: Check inetCidrRouteTable row dependencies.
     * check that all new value are legal and consistent with each other
     */
    /*
     * can't modify an active row
     */
    if ((ROWSTATUS_ACTIVE == rowreq_ctx->row_status) &&
        (ROWSTATUS_ACTIVE == rowreq_ctx->row_status_undo)) {
        DEBUGMSGTL(("inetCidrRouteTable",
                    "can't change active row (yet)\n"));
        return MFD_ERROR;
    }

    /*
     * check RowStatus dependencies
     */
    if (rowreq_ctx->column_set_flags & COLUMN_INETCIDRROUTESTATUS_FLAG) {
        /*
         * check for valid RowStatus transition (old, new)
         * (Note: move transition check to 
         *  to catch errors earlier)
         */
        rc = check_rowstatus_transition(rowreq_ctx->row_status_undo,
                                        rowreq_ctx->row_status);
        if (MFD_SUCCESS != rc)
            return rc;

        /*
         * row creation requirements
         */
        if (rowreq_ctx->rowreq_flags & MFD_ROW_CREATED) {
            if (ROWSTATUS_DESTROY == rowreq_ctx->row_status) {
                rowreq_ctx->rowreq_flags |= MFD_ROW_DELETED;
            } else if (ROWSTATUS_CREATEANDGO == rowreq_ctx->row_status) {
                if ((rowreq_ctx->
                     column_set_flags & INETCIDRROUTETABLE_REQUIRED_COLS)
                    != INETCIDRROUTETABLE_REQUIRED_COLS) {
                    DEBUGMSGTL(("inetCidrRouteTable",
                                "required columns missing (0x%0x != 0x%0x)\n",
                                rowreq_ctx->column_set_flags,
                                INETCIDRROUTETABLE_REQUIRED_COLS));
                    return MFD_CANNOT_CREATE_NOW;
                }
                rowreq_ctx->row_status = ROWSTATUS_ACTIVE;
            }
        } /* row creation */
        else {
            /*
             * row change requirements
             */
            /*
             * don't allow a destroy if any other value was changed, since
             * that might call data access routines with bad info.
             *
             * you may or may not require the row be notInService before it
             * can be destroyed.
             */
            if (ROWSTATUS_DESTROY == rowreq_ctx->row_status) {
                if (rowreq_ctx->
                    column_set_flags & ~COLUMN_INETCIDRROUTESTATUS_FLAG) {
                    DEBUGMSGTL(("inetCidrRouteTable",
                                "destroy must be only varbind for row\n"));
                    return MFD_NOT_VALID_NOW;
                }
                rowreq_ctx->rowreq_flags |= MFD_ROW_DELETED;

            }                   /* row destroy */
        }                       /* row change */
    } else {
        /*
         * must have row status to create a row
         */
        if (rowreq_ctx->rowreq_flags & MFD_ROW_CREATED) {
            DEBUGMSGTL(("inetCidrRouteTable",
                        "must use RowStatus to create rows\n"));
            return MFD_CANNOT_CREATE_NOW;
        }
    }                           /* row status not set */

    if (MFD_SUCCESS != rc)
        return rc;

    return rc;
}                               /* inetCidrRouteTable_check_dependencies */


int
_route_number_handler(netsnmp_mib_handler *handler,
                      netsnmp_handler_registration *reginfo,
                      netsnmp_agent_request_info *reqinfo,
                      netsnmp_request_info *requests)
{
    if (MODE_GET == reqinfo->mode) {
        int val = inetCidrRouteTable_container_size();
        snmp_set_var_typed_value(requests->requestvb, ASN_UNSIGNED,
                                 (u_char *) &val, sizeof(val));
    } else
        netsnmp_assert("bad mode in RO handler");
    
    if (handler->next && handler->next->access_method)
        return netsnmp_call_next_handler(handler, reginfo, reqinfo,
                                         requests);
    
    return SNMP_ERR_NOERROR;
}

/** @} */
/** @{ */
