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

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

#include "ipCidrRouteTable_interface.h"

const oid       ipCidrRouteTable_oid[] = { IPCIDRROUTETABLE_OID };
const int       ipCidrRouteTable_oid_size =
OID_LENGTH(ipCidrRouteTable_oid);

ipCidrRouteTable_registration ipCidrRouteTable_user_context;
static ipCidrRouteTable_registration *ipCidrRouteTable_user_context_p;

void            initialize_table_ipCidrRouteTable(void);
void            shutdown_table_ipCidrRouteTable(void);


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

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

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

}                               /* init_ipCidrRouteTable */

/**
 * Shut-down the ipCidrRouteTable module (agent is exiting)
 */
void
shutdown_ipCidrRouteTable(void)
{
    if (should_init("ipCidrRouteTable"))
        shutdown_table_ipCidrRouteTable();

}

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

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

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

    /*
     * TODO:302:o: |->Initialize ipCidrRouteTable 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.
     */
    ipCidrRouteTable_user_context_p
	= netsnmp_create_data_list("ipCidrRouteTable", NULL, NULL);

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

    /*
     * call interface initialization code
     */
    _ipCidrRouteTable_initialize_interface
	(ipCidrRouteTable_user_context_p, flags);
}                               /* initialize_table_ipCidrRouteTable */

/**
 * Shutdown the table ipCidrRouteTable 
 */
void
shutdown_table_ipCidrRouteTable(void)
{
    /*
     * call interface shutdown code
     */
    _ipCidrRouteTable_shutdown_interface(ipCidrRouteTable_user_context_p);
    netsnmp_free_all_list_data(ipCidrRouteTable_user_context_p);
    ipCidrRouteTable_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
ipCidrRouteTable_rowreq_ctx_init(ipCidrRouteTable_rowreq_ctx * rowreq_ctx,
                                 void *user_init_ctx)
{
    DEBUGMSGTL(("verbose:ipCidrRouteTable:ipCidrRouteTable_rowreq_ctx_init", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:210:o: |-> Perform extra ipCidrRouteTable rowreq initialization. (eg DEFVALS)
     */


    return MFD_SUCCESS;
}                               /* ipCidrRouteTable_rowreq_ctx_init */

/**
 * extra context cleanup
 *
 */
void
ipCidrRouteTable_rowreq_ctx_cleanup(ipCidrRouteTable_rowreq_ctx *
                                    rowreq_ctx)
{
    DEBUGMSGTL(("verbose:ipCidrRouteTable:ipCidrRouteTable_rowreq_ctx_cleanup", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

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

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

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

    return MFD_SUCCESS;
}                               /* ipCidrRouteTable_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
ipCidrRouteTable_post_request(ipCidrRouteTable_registration * user_context,
                              int rc)
{
    DEBUGMSGTL(("verbose:ipCidrRouteTable:ipCidrRouteTable_post_request",
                "called\n"));

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

    /*
     * check to set if any rows were changed.
     */
    if (ipCidrRouteTable_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
             */
        }

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

    return MFD_SUCCESS;
}                               /* ipCidrRouteTable_post_request */


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

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

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

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

    return rtn;
}                               /* ipCidrRouteTable_allocate_data */

/*
 * ipCidrRouteTable_release_data
 *
 * Purpose: release ipCidrRouteTable data.
 */
void
ipCidrRouteTable_release_data(ipCidrRouteTable_data * data)
{
    DEBUGMSGTL(("verbose:ipCidrRouteTable:ipCidrRouteTable_release_data",
                "called\n"));

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



/**
 * set mib index(es)
 *
 * @param tbl_idx mib index structure
 * @param ipCidrRouteDest_val
 * @param ipCidrRouteMask_val
 * @param ipCidrRouteTos_val
 * @param ipCidrRouteNextHop_val
 *
 * @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
ipCidrRouteTable_indexes_set_tbl_idx(ipCidrRouteTable_mib_index * tbl_idx,
                                     in_addr_t ipCidrRouteDest_val,
                                     in_addr_t ipCidrRouteMask_val,
                                     long ipCidrRouteTos_val,
                                     in_addr_t ipCidrRouteNextHop_val)
{
    DEBUGMSGTL(("verbose:ipCidrRouteTable:ipCidrRouteTable_indexes_set_tbl_idx", "called\n"));

    /*
     * ipCidrRouteDest(1)/IPADDR/ASN_IPADDRESS/u_long(u_long)//l/A/w/e/r/d/h 
     */
    tbl_idx->ipCidrRouteDest = ipCidrRouteDest_val;

    /*
     * ipCidrRouteMask(2)/IPADDR/ASN_IPADDRESS/u_long(u_long)//l/A/w/e/r/d/h 
     */
    tbl_idx->ipCidrRouteMask = ipCidrRouteMask_val;

    /*
     * ipCidrRouteTos(3)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/R/d/h 
     */
    tbl_idx->ipCidrRouteTos = ipCidrRouteTos_val;

    /*
     * ipCidrRouteNextHop(4)/IPADDR/ASN_IPADDRESS/u_long(u_long)//l/A/w/e/r/d/h 
     */
    tbl_idx->ipCidrRouteNextHop = ipCidrRouteNextHop_val;


    return MFD_SUCCESS;
}                               /* ipCidrRouteTable_indexes_set_tbl_idx */

/**
 * @internal
 * set row context indexes
 *
 * @param reqreq_ctx the row context that needs updated indexes
 *
 * @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
ipCidrRouteTable_indexes_set(ipCidrRouteTable_rowreq_ctx * rowreq_ctx,
                             in_addr_t ipCidrRouteDest_val,
                             in_addr_t ipCidrRouteMask_val,
                             long ipCidrRouteTos_val,
                             in_addr_t ipCidrRouteNextHop_val)
{
    DEBUGMSGTL(("verbose:ipCidrRouteTable:ipCidrRouteTable_indexes_set",
                "called\n"));

    if (MFD_SUCCESS !=
        ipCidrRouteTable_indexes_set_tbl_idx(&rowreq_ctx->tbl_idx,
                                             ipCidrRouteDest_val,
                                             ipCidrRouteMask_val,
                                             ipCidrRouteTos_val,
                                             ipCidrRouteNextHop_val))
        return MFD_ERROR;

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

    return MFD_SUCCESS;
}                               /* ipCidrRouteTable_indexes_set */


/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::ipCidrRouteEntry.ipCidrRouteIfIndex
 * ipCidrRouteIfIndex is subid 5 of ipCidrRouteEntry.
 * Its status is Deprecated, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.24.4.1.5
 * Description:
The ifIndex value which identifies  the local interface 


                through which the next hop of this route should be  
                reached.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 1
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *   defval: 0
 *
 *
 * 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 ipCidrRouteIfIndex data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipCidrRouteIfIndex_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
ipCidrRouteIfIndex_get(ipCidrRouteTable_rowreq_ctx * rowreq_ctx,
                       long *ipCidrRouteIfIndex_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ipCidrRouteIfIndex_val_ptr);


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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ipCidrRouteIfIndex data.
     * copy (* ipCidrRouteIfIndex_val_ptr ) from rowreq_ctx->data
     */
    (*ipCidrRouteIfIndex_val_ptr) = rowreq_ctx->data->if_index;

    return MFD_SUCCESS;
}                               /* ipCidrRouteIfIndex_get */

/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::ipCidrRouteEntry.ipCidrRouteType
 * ipCidrRouteType is subid 6 of ipCidrRouteEntry.
 * Its status is Deprecated, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.24.4.1.6
 * 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. This is used in  
                some protocols as a means of correctly aggregating  
                routes.
 *
 * 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)
 *
 * 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 ipCidrRouteType data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipCidrRouteType_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
ipCidrRouteType_get(ipCidrRouteTable_rowreq_ctx * rowreq_ctx,
                    u_long * ipCidrRouteType_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ipCidrRouteType_val_ptr);


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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ipCidrRouteType data.
     * copy (* ipCidrRouteType_val_ptr ) from rowreq_ctx->data
     */
    (*ipCidrRouteType_val_ptr) = rowreq_ctx->data->rt_type;

    return MFD_SUCCESS;
}                               /* ipCidrRouteType_get */

/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::ipCidrRouteEntry.ipCidrRouteProto
 * ipCidrRouteProto is subid 7 of ipCidrRouteEntry.
 * Its status is Deprecated, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.4.24.4.1.7
 * 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: 11/16. 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)
 *
 * 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 ipCidrRouteProto data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipCidrRouteProto_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
ipCidrRouteProto_get(ipCidrRouteTable_rowreq_ctx * rowreq_ctx,
                     u_long * ipCidrRouteProto_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ipCidrRouteProto_val_ptr);


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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ipCidrRouteProto data.
     * copy (* ipCidrRouteProto_val_ptr ) from rowreq_ctx->data
     */
    (*ipCidrRouteProto_val_ptr) = rowreq_ctx->data->rt_proto;

    return MFD_SUCCESS;
}                               /* ipCidrRouteProto_get */

/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::ipCidrRouteEntry.ipCidrRouteAge
 * ipCidrRouteAge is subid 8 of ipCidrRouteEntry.
 * Its status is Deprecated, and its access level is ReadOnly.
 * OID: .1.3.6.1.2.1.4.24.4.1.8
 * 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 1
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   0
 *   defval: 0
 *
 *
 * 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 ipCidrRouteAge data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipCidrRouteAge_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
ipCidrRouteAge_get(ipCidrRouteTable_rowreq_ctx * rowreq_ctx,
                   long *ipCidrRouteAge_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ipCidrRouteAge_val_ptr);


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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ipCidrRouteAge data.
     * copy (* ipCidrRouteAge_val_ptr ) from rowreq_ctx->data
     */
    /*
     * TODO:235:M: |-> Remove log message/SKIP once you've set ipCidrRouteAge data
     */
    return MFD_SKIP;

    return MFD_SUCCESS;
}                               /* ipCidrRouteAge_get */

/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::ipCidrRouteEntry.ipCidrRouteInfo
 * ipCidrRouteInfo is subid 9 of ipCidrRouteEntry.
 * Its status is Deprecated, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.24.4.1.9
 * Description:
A reference to MIB definitions specific to the  
                particular routing protocol which is responsible for  
                this route, as determined by the value specified in the  
                route's ipCidrRouteProto value.  If this information is  
                not present, its value should be set to the OBJECT  
                IDENTIFIER { 0 0 }, which is a syntactically valid  
                object identifier, and any implementation conforming to  
                ASN.1 and the Basic Encoding Rules must be able to  
                generate and recognize this value.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *
 *
 * Its syntax is OBJECTID (based on perltype OBJECTID)
 * The net-snmp type is ASN_OBJECT_ID. The C type decl is oid (oid)
 * This data type requires a length.  (Max )
 */
/**
 * Extract the current value of the ipCidrRouteInfo data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipCidrRouteInfo_val_ptr_ptr
 *        Pointer to storage for a oid variable
 * @param ipCidrRouteInfo_val_ptr_len_ptr
 *        Pointer to a size_t. On entry, it will contain the size (in bytes)
 *        pointed to by ipCidrRouteInfo.
 *        On exit, this value should contain the data size (in bytes).
 *
 * @retval MFD_SUCCESS         : success
 * @retval MFD_SKIP            : skip this node (no value for now)
 * @retval MFD_ERROR           : Any other error
*
 * @note If you need more than (*ipCidrRouteInfo_val_ptr_len_ptr) bytes of memory,
 *       allocate it using malloc() and update ipCidrRouteInfo_val_ptr_ptr.
 *       <b>DO NOT</b> free the previous pointer.
 *       The MFD helper will release the memory you allocate.
 *
 * @remark If you call this function yourself, you are responsible
 *         for checking if the pointer changed, and freeing any
 *         previously allocated memory. (Not necessary if you pass
 *         in a pointer to static memory, obviously.)
 */
int
ipCidrRouteInfo_get(ipCidrRouteTable_rowreq_ctx * rowreq_ctx,
                    oid ** ipCidrRouteInfo_val_ptr_ptr,
                    size_t * ipCidrRouteInfo_val_ptr_len_ptr)
{
   /** we should have a non-NULL pointer and enough storage */
    netsnmp_assert((NULL != ipCidrRouteInfo_val_ptr_ptr)
                   && (NULL != *ipCidrRouteInfo_val_ptr_ptr));
    netsnmp_assert(NULL != ipCidrRouteInfo_val_ptr_len_ptr);


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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ipCidrRouteInfo data.
     * copy (* ipCidrRouteInfo_val_ptr_ptr ) data and (* ipCidrRouteInfo_val_ptr_len_ptr ) from rowreq_ctx->data
     */
    /** nullOidLen is in bytes, so not sizeof(oid) needed */
    if ((*ipCidrRouteInfo_val_ptr_len_ptr) < (size_t)nullOidLen) {
        (*ipCidrRouteInfo_val_ptr_ptr) = (oid*)malloc(nullOidLen);
        if (NULL == (*ipCidrRouteInfo_val_ptr_ptr))
            return MFD_ERROR;
    }
    (*ipCidrRouteInfo_val_ptr_len_ptr) = (size_t)nullOidLen;
    memcpy((*ipCidrRouteInfo_val_ptr_ptr), nullOid, (size_t)nullOidLen);

    return MFD_SUCCESS;
}                               /* ipCidrRouteInfo_get */

/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::ipCidrRouteEntry.ipCidrRouteNextHopAS
 * ipCidrRouteNextHopAS is subid 10 of ipCidrRouteEntry.
 * Its status is Deprecated, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.24.4.1.10
 * 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 ipCidrRouteProto  
                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   0
 *   settable   1
 *   defval: 0
 *
 *
 * 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 ipCidrRouteNextHopAS data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipCidrRouteNextHopAS_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
ipCidrRouteNextHopAS_get(ipCidrRouteTable_rowreq_ctx * rowreq_ctx,
                         long *ipCidrRouteNextHopAS_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ipCidrRouteNextHopAS_val_ptr);


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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ipCidrRouteNextHopAS data.
     * copy (* ipCidrRouteNextHopAS_val_ptr ) from rowreq_ctx->data
     */
    (*ipCidrRouteNextHopAS_val_ptr) = rowreq_ctx->data->rt_nexthop_as;

    return MFD_SUCCESS;
}                               /* ipCidrRouteNextHopAS_get */

/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::ipCidrRouteEntry.ipCidrRouteMetric1
 * ipCidrRouteMetric1 is subid 11 of ipCidrRouteEntry.
 * Its status is Deprecated, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.24.4.1.11
 * Description:
The primary routing metric for this route.  The  
                semantics of this metric are determined by the routing- 
                protocol specified in the route's ipCidrRouteProto  
                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 ipCidrRouteMetric1 data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipCidrRouteMetric1_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
ipCidrRouteMetric1_get(ipCidrRouteTable_rowreq_ctx * rowreq_ctx,
                       long *ipCidrRouteMetric1_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ipCidrRouteMetric1_val_ptr);


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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ipCidrRouteMetric1 data.
     * copy (* ipCidrRouteMetric1_val_ptr ) from rowreq_ctx->data
     */
    (*ipCidrRouteMetric1_val_ptr) = rowreq_ctx->data->rt_metric1;

    return MFD_SUCCESS;
}                               /* ipCidrRouteMetric1_get */

/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::ipCidrRouteEntry.ipCidrRouteMetric2
 * ipCidrRouteMetric2 is subid 12 of ipCidrRouteEntry.
 * Its status is Deprecated, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.24.4.1.12
 * Description:
An alternate routing metric for this route.  The  
                semantics of this metric are determined by the routing- 
                protocol specified in the route's ipCidrRouteProto  
                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 ipCidrRouteMetric2 data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipCidrRouteMetric2_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
ipCidrRouteMetric2_get(ipCidrRouteTable_rowreq_ctx * rowreq_ctx,
                       long *ipCidrRouteMetric2_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ipCidrRouteMetric2_val_ptr);


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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ipCidrRouteMetric2 data.
     * copy (* ipCidrRouteMetric2_val_ptr ) from rowreq_ctx->data
     */
    (*ipCidrRouteMetric2_val_ptr) = rowreq_ctx->data->rt_metric2;

    return MFD_SUCCESS;
}                               /* ipCidrRouteMetric2_get */

/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::ipCidrRouteEntry.ipCidrRouteMetric3
 * ipCidrRouteMetric3 is subid 13 of ipCidrRouteEntry.
 * Its status is Deprecated, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.24.4.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 ipCidrRouteProto  
                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 ipCidrRouteMetric3 data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipCidrRouteMetric3_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
ipCidrRouteMetric3_get(ipCidrRouteTable_rowreq_ctx * rowreq_ctx,
                       long *ipCidrRouteMetric3_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ipCidrRouteMetric3_val_ptr);


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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ipCidrRouteMetric3 data.
     * copy (* ipCidrRouteMetric3_val_ptr ) from rowreq_ctx->data
     */
    (*ipCidrRouteMetric3_val_ptr) = rowreq_ctx->data->rt_metric3;

    return MFD_SUCCESS;
}                               /* ipCidrRouteMetric3_get */

/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::ipCidrRouteEntry.ipCidrRouteMetric4
 * ipCidrRouteMetric4 is subid 14 of ipCidrRouteEntry.
 * Its status is Deprecated, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.24.4.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 ipCidrRouteProto  
                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 ipCidrRouteMetric4 data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipCidrRouteMetric4_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
ipCidrRouteMetric4_get(ipCidrRouteTable_rowreq_ctx * rowreq_ctx,
                       long *ipCidrRouteMetric4_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ipCidrRouteMetric4_val_ptr);


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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ipCidrRouteMetric4 data.
     * copy (* ipCidrRouteMetric4_val_ptr ) from rowreq_ctx->data
     */
    (*ipCidrRouteMetric4_val_ptr) = rowreq_ctx->data->rt_metric4;

    return MFD_SUCCESS;
}                               /* ipCidrRouteMetric4_get */

/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::ipCidrRouteEntry.ipCidrRouteMetric5
 * ipCidrRouteMetric5 is subid 15 of ipCidrRouteEntry.
 * Its status is Deprecated, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.24.4.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 ipCidrRouteProto  
                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 ipCidrRouteMetric5 data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipCidrRouteMetric5_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
ipCidrRouteMetric5_get(ipCidrRouteTable_rowreq_ctx * rowreq_ctx,
                       long *ipCidrRouteMetric5_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ipCidrRouteMetric5_val_ptr);


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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:231:o: |-> Extract the current value of the ipCidrRouteMetric5 data.
     * copy (* ipCidrRouteMetric5_val_ptr ) from rowreq_ctx->data
     */
    (*ipCidrRouteMetric5_val_ptr) = rowreq_ctx->data->rt_metric5;

    return MFD_SUCCESS;
}                               /* ipCidrRouteMetric5_get */

/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::ipCidrRouteEntry.ipCidrRouteStatus
 * ipCidrRouteStatus is subid 16 of ipCidrRouteEntry.
 * Its status is Deprecated, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.24.4.1.16
 * Description:
The row status variable, used according to row  
                installation and removal conventions.
 *
 * 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 ipCidrRouteStatus data.
 *
 * Set a value using the data context for the row.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipCidrRouteStatus_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
ipCidrRouteStatus_get(ipCidrRouteTable_rowreq_ctx * rowreq_ctx,
                      u_long * ipCidrRouteStatus_val_ptr)
{
   /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != ipCidrRouteStatus_val_ptr);

    (*ipCidrRouteStatus_val_ptr) = rowreq_ctx->ipCidrRouteStatus;

    return MFD_SUCCESS;
}                               /* ipCidrRouteStatus_get */



/** @} */
/**********************************************************************
 **********************************************************************
 ***
 *** Table ipCidrRouteTable
 ***
 **********************************************************************
 **********************************************************************/
/*
 * IP-FORWARD-MIB::ipCidrRouteTable is subid 4 of ipForward.
 * Its status is Deprecated.
 * OID: .1.3.6.1.2.1.4.24.4, length: 9
 */
    /*
     * 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
 * ipCidrRouteTable_allocate_data(), but may need extra
 * initialization similar to what you may have done in
 * ipCidrRouteTable_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 (ipCidrRouteTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 */
int
ipCidrRouteTable_undo_setup(ipCidrRouteTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

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

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

    /*
     * TODO:451:M: |-> Setup ipCidrRouteTable undo.
     * set up ipCidrRouteTable undo information, in preparation for a set.
     * Undo storage is in (* ipCidrRouteStatus_val_ptr )*
     */

    return rc;
}                               /* ipCidrRouteTable_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 (ipCidrRouteTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 */
int
ipCidrRouteTable_undo(ipCidrRouteTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

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

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

    /*
     * TODO:451:M: |-> ipCidrRouteTable undo.
     * ipCidrRouteTable undo information, in response to a failed set.
     * Undo storage is in (* ipCidrRouteStatus_val_ptr )*
     */

    return rc;
}                               /* ipCidrRouteTable_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 (ipCidrRouteTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error
 */
int
ipCidrRouteTable_undo_cleanup(ipCidrRouteTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

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

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

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

    return rc;
}                               /* ipCidrRouteTable_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
 * ipCidrRouteTable.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
ipCidrRouteTable_commit(ipCidrRouteTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;
    int             save_flags;

    DEBUGMSGTL(("verbose:ipCidrRouteTable:ipCidrRouteTable_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 ipCidrRouteTable 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.
     */
    if (save_flags & COLUMN_IPCIDRROUTEIFINDEX_FLAG) {
        save_flags &= ~COLUMN_IPCIDRROUTEIFINDEX_FLAG;  /* clear ipCidrRouteIfIndex */
        /*
         * TODO:482:o: |-> commit column ipCidrRouteIfIndex.
         */
        rc = -1;
        if (-1 == rc) {
            snmp_log(LOG_ERR,
                     "ipCidrRouteTable column ipCidrRouteIfIndex commit failed\n");
        } else {
            /*
             * set flag, in case we need to undo ipCidrRouteIfIndex
             */
            rowreq_ctx->column_set_flags |= COLUMN_IPCIDRROUTEIFINDEX_FLAG;
        }
    }

    if (save_flags & COLUMN_IPCIDRROUTETYPE_FLAG) {
        save_flags &= ~COLUMN_IPCIDRROUTETYPE_FLAG;     /* clear ipCidrRouteType */
        /*
         * TODO:482:o: |-> commit column ipCidrRouteType.
         */
        rc = -1;
        if (-1 == rc) {
            snmp_log(LOG_ERR,
                     "ipCidrRouteTable column ipCidrRouteType commit failed\n");
        } else {
            /*
             * set flag, in case we need to undo ipCidrRouteType
             */
            rowreq_ctx->column_set_flags |= COLUMN_IPCIDRROUTETYPE_FLAG;
        }
    }

    if (save_flags & COLUMN_IPCIDRROUTEINFO_FLAG) {
        save_flags &= ~COLUMN_IPCIDRROUTEINFO_FLAG;     /* clear ipCidrRouteInfo */
        /*
         * TODO:482:o: |-> commit column ipCidrRouteInfo.
         */
        rc = -1;
        if (-1 == rc) {
            snmp_log(LOG_ERR,
                     "ipCidrRouteTable column ipCidrRouteInfo commit failed\n");
        } else {
            /*
             * set flag, in case we need to undo ipCidrRouteInfo
             */
            rowreq_ctx->column_set_flags |= COLUMN_IPCIDRROUTEINFO_FLAG;
        }
    }

    if (save_flags & COLUMN_IPCIDRROUTENEXTHOPAS_FLAG) {
        save_flags &= ~COLUMN_IPCIDRROUTENEXTHOPAS_FLAG;        /* clear ipCidrRouteNextHopAS */
        /*
         * TODO:482:o: |-> commit column ipCidrRouteNextHopAS.
         */
        rc = -1;
        if (-1 == rc) {
            snmp_log(LOG_ERR,
                     "ipCidrRouteTable column ipCidrRouteNextHopAS commit failed\n");
        } else {
            /*
             * set flag, in case we need to undo ipCidrRouteNextHopAS
             */
            rowreq_ctx->column_set_flags |=
                COLUMN_IPCIDRROUTENEXTHOPAS_FLAG;
        }
    }

    if (save_flags & COLUMN_IPCIDRROUTEMETRIC1_FLAG) {
        save_flags &= ~COLUMN_IPCIDRROUTEMETRIC1_FLAG;  /* clear ipCidrRouteMetric1 */
        /*
         * TODO:482:o: |-> commit column ipCidrRouteMetric1.
         */
        rc = -1;
        if (-1 == rc) {
            snmp_log(LOG_ERR,
                     "ipCidrRouteTable column ipCidrRouteMetric1 commit failed\n");
        } else {
            /*
             * set flag, in case we need to undo ipCidrRouteMetric1
             */
            rowreq_ctx->column_set_flags |= COLUMN_IPCIDRROUTEMETRIC1_FLAG;
        }
    }

    if (save_flags & COLUMN_IPCIDRROUTEMETRIC2_FLAG) {
        save_flags &= ~COLUMN_IPCIDRROUTEMETRIC2_FLAG;  /* clear ipCidrRouteMetric2 */
        /*
         * TODO:482:o: |-> commit column ipCidrRouteMetric2.
         */
        rc = -1;
        if (-1 == rc) {
            snmp_log(LOG_ERR,
                     "ipCidrRouteTable column ipCidrRouteMetric2 commit failed\n");
        } else {
            /*
             * set flag, in case we need to undo ipCidrRouteMetric2
             */
            rowreq_ctx->column_set_flags |= COLUMN_IPCIDRROUTEMETRIC2_FLAG;
        }
    }

    if (save_flags & COLUMN_IPCIDRROUTEMETRIC3_FLAG) {
        save_flags &= ~COLUMN_IPCIDRROUTEMETRIC3_FLAG;  /* clear ipCidrRouteMetric3 */
        /*
         * TODO:482:o: |-> commit column ipCidrRouteMetric3.
         */
        rc = -1;
        if (-1 == rc) {
            snmp_log(LOG_ERR,
                     "ipCidrRouteTable column ipCidrRouteMetric3 commit failed\n");
        } else {
            /*
             * set flag, in case we need to undo ipCidrRouteMetric3
             */
            rowreq_ctx->column_set_flags |= COLUMN_IPCIDRROUTEMETRIC3_FLAG;
        }
    }

    if (save_flags & COLUMN_IPCIDRROUTEMETRIC4_FLAG) {
        save_flags &= ~COLUMN_IPCIDRROUTEMETRIC4_FLAG;  /* clear ipCidrRouteMetric4 */
        /*
         * TODO:482:o: |-> commit column ipCidrRouteMetric4.
         */
        rc = -1;
        if (-1 == rc) {
            snmp_log(LOG_ERR,
                     "ipCidrRouteTable column ipCidrRouteMetric4 commit failed\n");
        } else {
            /*
             * set flag, in case we need to undo ipCidrRouteMetric4
             */
            rowreq_ctx->column_set_flags |= COLUMN_IPCIDRROUTEMETRIC4_FLAG;
        }
    }

    if (save_flags & COLUMN_IPCIDRROUTEMETRIC5_FLAG) {
        save_flags &= ~COLUMN_IPCIDRROUTEMETRIC5_FLAG;  /* clear ipCidrRouteMetric5 */
        /*
         * TODO:482:o: |-> commit column ipCidrRouteMetric5.
         */
        rc = -1;
        if (-1 == rc) {
            snmp_log(LOG_ERR,
                     "ipCidrRouteTable column ipCidrRouteMetric5 commit failed\n");
        } else {
            /*
             * set flag, in case we need to undo ipCidrRouteMetric5
             */
            rowreq_ctx->column_set_flags |= COLUMN_IPCIDRROUTEMETRIC5_FLAG;
        }
    }

    if (save_flags & COLUMN_IPCIDRROUTESTATUS_FLAG) {
        save_flags &= ~COLUMN_IPCIDRROUTESTATUS_FLAG;   /* clear ipCidrRouteStatus */
        /*
         * TODO:482:o: |-> commit column ipCidrRouteStatus.
         */
        rc = -1;
        if (-1 == rc) {
            snmp_log(LOG_ERR,
                     "ipCidrRouteTable column ipCidrRouteStatus commit failed\n");
        } else {
            /*
             * set flag, in case we need to undo ipCidrRouteStatus
             */
            rowreq_ctx->column_set_flags |= COLUMN_IPCIDRROUTESTATUS_FLAG;
        }
    }

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

    if (save_flags) {
        snmp_log(LOG_ERR, "unhandled columns (0x%x) in commit\n",
                 save_flags);
        return MFD_ERROR;
    }

    return rc;
}                               /* ipCidrRouteTable_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
 * ipCidrRouteTable.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
ipCidrRouteTable_undo_commit(ipCidrRouteTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

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

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

    /*
     * TODO:485:M: |-> Undo ipCidrRouteTable 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 we successfully un-commited this row, clear the dirty flag.
     */
    if (MFD_SUCCESS == rc) {
        rowreq_ctx->rowreq_flags &= ~MFD_ROW_DIRTY;
    }

    return rc;
}                               /* ipCidrRouteTable_undo_commit */

/*
 * TODO:440:M: Implement ipCidrRouteTable node value checks.
 * TODO:450:M: Implement ipCidrRouteTable undo functions.
 * TODO:460:M: Implement ipCidrRouteTable set functions.
 * TODO:480:M: Implement ipCidrRouteTable commit functions.
 */
/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::ipCidrRouteEntry.ipCidrRouteIfIndex
 * ipCidrRouteIfIndex is subid 5 of ipCidrRouteEntry.
 * Its status is Deprecated, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.24.4.1.5
 * Description:
The ifIndex value which identifies  the local interface 


                through which the next hop of this route should be  
                reached.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 1
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *   defval: 0
 *
 *
 * 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 ipCidrRouteIfIndex_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
 * ipCidrRouteTable_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
ipCidrRouteIfIndex_check_value(ipCidrRouteTable_rowreq_ctx * rowreq_ctx,
                               long ipCidrRouteIfIndex_val)
{
    DEBUGMSGTL(("verbose:ipCidrRouteTable:ipCidrRouteIfIndex_check_value",
                "called\n"));

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

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

    return MFD_SUCCESS;         /* ipCidrRouteIfIndex value not illegal */
}                               /* ipCidrRouteIfIndex_check_value */

/**
 * Save old value information
 *
 * @param rowreq_ctx
 *        Pointer to the table context (ipCidrRouteTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 *
 * This function will be called after the table level undo setup function
 * ipCidrRouteTable_undo_setup has been called.
 *
 *@note
 * this function will only be called if a new value is set for this column.
 *
 * If there is any setup specific to a particular column (e.g. allocating
 * memory for a string), you should do that setup in this function, so it
 * won't be done unless it is necessary.
 */
int
ipCidrRouteIfIndex_undo_setup(ipCidrRouteTable_rowreq_ctx * rowreq_ctx)
{
    DEBUGMSGTL(("verbose:ipCidrRouteTable:ipCidrRouteIfIndex_undo_setup",
                "called\n"));

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

    /*
     * TODO:455:o: |-> Setup ipCidrRouteIfIndex undo.
     */
    /*
     * copy ipCidrRouteIfIndex data
     * set rowreq_ctx->undo->ipCidrRouteIfIndex from rowreq_ctx->data->ipCidrRouteIfIndex
     */


    return MFD_SUCCESS;
}                               /* ipCidrRouteIfIndex_undo_setup */

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

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

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

    /*
     * TODO:461:M: |-> Set ipCidrRouteIfIndex value.
     * set ipCidrRouteIfIndex value in rowreq_ctx->data
     */

    return MFD_SUCCESS;
}                               /* ipCidrRouteIfIndex_set */

/**
 * undo the previous set.
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 */
int
ipCidrRouteIfIndex_undo(ipCidrRouteTable_rowreq_ctx * rowreq_ctx)
{

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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:456:o: |-> Clean up ipCidrRouteIfIndex undo.
     */
    /*
     * copy ipCidrRouteIfIndex data
     * set rowreq_ctx->data->ipCidrRouteIfIndex from rowreq_ctx->undo->ipCidrRouteIfIndex
     */


    return MFD_SUCCESS;
}                               /* ipCidrRouteIfIndex_undo */

/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::ipCidrRouteEntry.ipCidrRouteType
 * ipCidrRouteType is subid 6 of ipCidrRouteEntry.
 * Its status is Deprecated, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.24.4.1.6
 * 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. This is used in  
                some protocols as a means of correctly aggregating  
                routes.
 *
 * 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)
 *
 * 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 ipCidrRouteType_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
 * ipCidrRouteTable_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)
 *
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
 *
 */
int
ipCidrRouteType_check_value(ipCidrRouteTable_rowreq_ctx * rowreq_ctx,
                            u_long ipCidrRouteType_val)
{
    DEBUGMSGTL(("verbose:ipCidrRouteTable:ipCidrRouteType_check_value",
                "called\n"));

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

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

    return MFD_SUCCESS;         /* ipCidrRouteType value not illegal */
}                               /* ipCidrRouteType_check_value */

/**
 * Save old value information
 *
 * @param rowreq_ctx
 *        Pointer to the table context (ipCidrRouteTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 *
 * This function will be called after the table level undo setup function
 * ipCidrRouteTable_undo_setup has been called.
 *
 *@note
 * this function will only be called if a new value is set for this column.
 *
 * If there is any setup specific to a particular column (e.g. allocating
 * memory for a string), you should do that setup in this function, so it
 * won't be done unless it is necessary.
 */
int
ipCidrRouteType_undo_setup(ipCidrRouteTable_rowreq_ctx * rowreq_ctx)
{
    DEBUGMSGTL(("verbose:ipCidrRouteTable:ipCidrRouteType_undo_setup",
                "called\n"));

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

    /*
     * TODO:455:o: |-> Setup ipCidrRouteType undo.
     */
    /*
     * copy ipCidrRouteType data
     * set rowreq_ctx->undo->ipCidrRouteType from rowreq_ctx->data->ipCidrRouteType
     */


    return MFD_SUCCESS;
}                               /* ipCidrRouteType_undo_setup */

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

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

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

    /*
     * TODO:461:M: |-> Set ipCidrRouteType value.
     * set ipCidrRouteType value in rowreq_ctx->data
     */

    return MFD_SUCCESS;
}                               /* ipCidrRouteType_set */

/**
 * undo the previous set.
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 */
int
ipCidrRouteType_undo(ipCidrRouteTable_rowreq_ctx * rowreq_ctx)
{

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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:456:o: |-> Clean up ipCidrRouteType undo.
     */
    /*
     * copy ipCidrRouteType data
     * set rowreq_ctx->data->ipCidrRouteType from rowreq_ctx->undo->ipCidrRouteType
     */


    return MFD_SUCCESS;
}                               /* ipCidrRouteType_undo */

/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::ipCidrRouteEntry.ipCidrRouteInfo
 * ipCidrRouteInfo is subid 9 of ipCidrRouteEntry.
 * Its status is Deprecated, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.24.4.1.9
 * Description:
A reference to MIB definitions specific to the  
                particular routing protocol which is responsible for  
                this route, as determined by the value specified in the  
                route's ipCidrRouteProto value.  If this information is  
                not present, its value should be set to the OBJECT  
                IDENTIFIER { 0 0 }, which is a syntactically valid  
                object identifier, and any implementation conforming to  
                ASN.1 and the Basic Encoding Rules must be able to  
                generate and recognize this value.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *
 *
 * Its syntax is OBJECTID (based on perltype OBJECTID)
 * The net-snmp type is ASN_OBJECT_ID. The C type decl is oid (oid)
 * This data type requires a length.  (Max )
 */
/**
 * Check that the proposed new value is potentially valid.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param ipCidrRouteInfo_val_ptr
 *        A oid containing the new value.
 * @param ipCidrRouteInfo_val_ptr_len
 *        The size (in bytes) of the data pointed to by ipCidrRouteInfo_val_ptr
 *
 * @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).
 *
 * Since you aren't using a generated data context, you also need to
 * check the length, to make sure you don't overflow your storage space.
 *
 * 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
 * ipCidrRouteTable_check_dependencies() function.
 *
 * The following checks have already been done for you:
 *    The syntax is ASN_OBJECT_ID
 *
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
 *
 */
int
ipCidrRouteInfo_check_value(ipCidrRouteTable_rowreq_ctx * rowreq_ctx,
                            oid * ipCidrRouteInfo_val_ptr,
                            size_t ipCidrRouteInfo_val_ptr_len)
{
    DEBUGMSGTL(("verbose:ipCidrRouteTable:ipCidrRouteInfo_check_value",
                "called\n"));

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

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

    return MFD_SUCCESS;         /* ipCidrRouteInfo value not illegal */
}                               /* ipCidrRouteInfo_check_value */

/**
 * Save old value information
 *
 * @param rowreq_ctx
 *        Pointer to the table context (ipCidrRouteTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 *
 * This function will be called after the table level undo setup function
 * ipCidrRouteTable_undo_setup has been called.
 *
 *@note
 * this function will only be called if a new value is set for this column.
 *
 * If there is any setup specific to a particular column (e.g. allocating
 * memory for a string), you should do that setup in this function, so it
 * won't be done unless it is necessary.
 */
int
ipCidrRouteInfo_undo_setup(ipCidrRouteTable_rowreq_ctx * rowreq_ctx)
{
    DEBUGMSGTL(("verbose:ipCidrRouteTable:ipCidrRouteInfo_undo_setup",
                "called\n"));

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

    /*
     * TODO:455:o: |-> Setup ipCidrRouteInfo undo.
     */
    /*
     * copy ipCidrRouteInfo and ipCidrRouteInfo_len data
     * set rowreq_ctx->undo->ipCidrRouteInfo from rowreq_ctx->data->ipCidrRouteInfo
     */


    return MFD_SUCCESS;
}                               /* ipCidrRouteInfo_undo_setup */

/**
 * Set the new value.
 *
 * @param rowreq_ctx
 *        Pointer to the users context. You should know how to
 *        manipulate the value from this object.
 * @param ipCidrRouteInfo_val_ptr
 *        A oid containing the new value.
 * @param ipCidrRouteInfo_val_ptr_len
 *        The size (in bytes) of the data pointed to by ipCidrRouteInfo_val_ptr
 */
int
ipCidrRouteInfo_set(ipCidrRouteTable_rowreq_ctx * rowreq_ctx,
                    oid * ipCidrRouteInfo_val_ptr,
                    size_t ipCidrRouteInfo_val_ptr_len)
{

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

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

    /*
     * TODO:461:M: |-> Set ipCidrRouteInfo value.
     * set ipCidrRouteInfo value in rowreq_ctx->data
     */

    return MFD_SUCCESS;
}                               /* ipCidrRouteInfo_set */

/**
 * undo the previous set.
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 */
int
ipCidrRouteInfo_undo(ipCidrRouteTable_rowreq_ctx * rowreq_ctx)
{

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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:456:o: |-> Clean up ipCidrRouteInfo undo.
     */
    /*
     * copy ipCidrRouteInfo and ipCidrRouteInfo_len data
     * set rowreq_ctx->data->ipCidrRouteInfo from rowreq_ctx->undo->ipCidrRouteInfo
     */


    return MFD_SUCCESS;
}                               /* ipCidrRouteInfo_undo */

/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::ipCidrRouteEntry.ipCidrRouteNextHopAS
 * ipCidrRouteNextHopAS is subid 10 of ipCidrRouteEntry.
 * Its status is Deprecated, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.24.4.1.10
 * 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 ipCidrRouteProto  
                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   0
 *   settable   1
 *   defval: 0
 *
 *
 * 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 ipCidrRouteNextHopAS_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
 * ipCidrRouteTable_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
ipCidrRouteNextHopAS_check_value(ipCidrRouteTable_rowreq_ctx * rowreq_ctx,
                                 long ipCidrRouteNextHopAS_val)
{
    DEBUGMSGTL(("verbose:ipCidrRouteTable:ipCidrRouteNextHopAS_check_value", "called\n"));

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

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

    return MFD_SUCCESS;         /* ipCidrRouteNextHopAS value not illegal */
}                               /* ipCidrRouteNextHopAS_check_value */

/**
 * Save old value information
 *
 * @param rowreq_ctx
 *        Pointer to the table context (ipCidrRouteTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 *
 * This function will be called after the table level undo setup function
 * ipCidrRouteTable_undo_setup has been called.
 *
 *@note
 * this function will only be called if a new value is set for this column.
 *
 * If there is any setup specific to a particular column (e.g. allocating
 * memory for a string), you should do that setup in this function, so it
 * won't be done unless it is necessary.
 */
int
ipCidrRouteNextHopAS_undo_setup(ipCidrRouteTable_rowreq_ctx * rowreq_ctx)
{
    DEBUGMSGTL(("verbose:ipCidrRouteTable:ipCidrRouteNextHopAS_undo_setup",
                "called\n"));

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

    /*
     * TODO:455:o: |-> Setup ipCidrRouteNextHopAS undo.
     */
    /*
     * copy ipCidrRouteNextHopAS data
     * set rowreq_ctx->undo->ipCidrRouteNextHopAS from rowreq_ctx->data->ipCidrRouteNextHopAS
     */


    return MFD_SUCCESS;
}                               /* ipCidrRouteNextHopAS_undo_setup */

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

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

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

    /*
     * TODO:461:M: |-> Set ipCidrRouteNextHopAS value.
     * set ipCidrRouteNextHopAS value in rowreq_ctx->data
     */

    return MFD_SUCCESS;
}                               /* ipCidrRouteNextHopAS_set */

/**
 * undo the previous set.
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 */
int
ipCidrRouteNextHopAS_undo(ipCidrRouteTable_rowreq_ctx * rowreq_ctx)
{

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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:456:o: |-> Clean up ipCidrRouteNextHopAS undo.
     */
    /*
     * copy ipCidrRouteNextHopAS data
     * set rowreq_ctx->data->ipCidrRouteNextHopAS from rowreq_ctx->undo->ipCidrRouteNextHopAS
     */


    return MFD_SUCCESS;
}                               /* ipCidrRouteNextHopAS_undo */

/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::ipCidrRouteEntry.ipCidrRouteMetric1
 * ipCidrRouteMetric1 is subid 11 of ipCidrRouteEntry.
 * Its status is Deprecated, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.24.4.1.11
 * Description:
The primary routing metric for this route.  The  
                semantics of this metric are determined by the routing- 
                protocol specified in the route's ipCidrRouteProto  
                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 ipCidrRouteMetric1_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
 * ipCidrRouteTable_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
ipCidrRouteMetric1_check_value(ipCidrRouteTable_rowreq_ctx * rowreq_ctx,
                               long ipCidrRouteMetric1_val)
{
    DEBUGMSGTL(("verbose:ipCidrRouteTable:ipCidrRouteMetric1_check_value",
                "called\n"));

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

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

    return MFD_SUCCESS;         /* ipCidrRouteMetric1 value not illegal */
}                               /* ipCidrRouteMetric1_check_value */

/**
 * Save old value information
 *
 * @param rowreq_ctx
 *        Pointer to the table context (ipCidrRouteTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 *
 * This function will be called after the table level undo setup function
 * ipCidrRouteTable_undo_setup has been called.
 *
 *@note
 * this function will only be called if a new value is set for this column.
 *
 * If there is any setup specific to a particular column (e.g. allocating
 * memory for a string), you should do that setup in this function, so it
 * won't be done unless it is necessary.
 */
int
ipCidrRouteMetric1_undo_setup(ipCidrRouteTable_rowreq_ctx * rowreq_ctx)
{
    DEBUGMSGTL(("verbose:ipCidrRouteTable:ipCidrRouteMetric1_undo_setup",
                "called\n"));

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

    /*
     * TODO:455:o: |-> Setup ipCidrRouteMetric1 undo.
     */
    /*
     * copy ipCidrRouteMetric1 data
     * set rowreq_ctx->undo->ipCidrRouteMetric1 from rowreq_ctx->data->ipCidrRouteMetric1
     */


    return MFD_SUCCESS;
}                               /* ipCidrRouteMetric1_undo_setup */

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

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

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

    /*
     * TODO:461:M: |-> Set ipCidrRouteMetric1 value.
     * set ipCidrRouteMetric1 value in rowreq_ctx->data
     */

    return MFD_SUCCESS;
}                               /* ipCidrRouteMetric1_set */

/**
 * undo the previous set.
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 */
int
ipCidrRouteMetric1_undo(ipCidrRouteTable_rowreq_ctx * rowreq_ctx)
{

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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:456:o: |-> Clean up ipCidrRouteMetric1 undo.
     */
    /*
     * copy ipCidrRouteMetric1 data
     * set rowreq_ctx->data->ipCidrRouteMetric1 from rowreq_ctx->undo->ipCidrRouteMetric1
     */


    return MFD_SUCCESS;
}                               /* ipCidrRouteMetric1_undo */

/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::ipCidrRouteEntry.ipCidrRouteMetric2
 * ipCidrRouteMetric2 is subid 12 of ipCidrRouteEntry.
 * Its status is Deprecated, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.24.4.1.12
 * Description:
An alternate routing metric for this route.  The  
                semantics of this metric are determined by the routing- 
                protocol specified in the route's ipCidrRouteProto  
                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 ipCidrRouteMetric2_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
 * ipCidrRouteTable_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
ipCidrRouteMetric2_check_value(ipCidrRouteTable_rowreq_ctx * rowreq_ctx,
                               long ipCidrRouteMetric2_val)
{
    DEBUGMSGTL(("verbose:ipCidrRouteTable:ipCidrRouteMetric2_check_value",
                "called\n"));

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

    /*
     * TODO:441:o: |-> Check for valid ipCidrRouteMetric2 value.
     */
    /*
     * does any os use metric 2-5? if so, update to deal with it.
     * otherwise, only accept same value we have.
     */
    if (ipCidrRouteMetric2_val != rowreq_ctx->data->rt_metric2)
        return MFD_NOT_VALID_EVER;

    return MFD_SUCCESS;         /* ipCidrRouteMetric2 value not illegal */
}                               /* ipCidrRouteMetric2_check_value */

/**
 * Save old value information
 *
 * @param rowreq_ctx
 *        Pointer to the table context (ipCidrRouteTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 *
 * This function will be called after the table level undo setup function
 * ipCidrRouteTable_undo_setup has been called.
 *
 *@note
 * this function will only be called if a new value is set for this column.
 *
 * If there is any setup specific to a particular column (e.g. allocating
 * memory for a string), you should do that setup in this function, so it
 * won't be done unless it is necessary.
 */
int
ipCidrRouteMetric2_undo_setup(ipCidrRouteTable_rowreq_ctx * rowreq_ctx)
{
    DEBUGMSGTL(("verbose:ipCidrRouteTable:ipCidrRouteMetric2_undo_setup",
                "called\n"));

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

    /*
     * TODO:455:o: |-> Setup ipCidrRouteMetric2 undo.
     */
    /*
     * copy ipCidrRouteMetric2 data
     * set rowreq_ctx->undo->ipCidrRouteMetric2 from rowreq_ctx->data->ipCidrRouteMetric2
     */


    return MFD_SUCCESS;
}                               /* ipCidrRouteMetric2_undo_setup */

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

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

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

    /*
     * TODO:461:M: |-> Set ipCidrRouteMetric2 value.
     * set ipCidrRouteMetric2 value in rowreq_ctx->data
     */

    return MFD_SUCCESS;
}                               /* ipCidrRouteMetric2_set */

/**
 * undo the previous set.
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 */
int
ipCidrRouteMetric2_undo(ipCidrRouteTable_rowreq_ctx * rowreq_ctx)
{

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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:456:o: |-> Clean up ipCidrRouteMetric2 undo.
     */
    /*
     * copy ipCidrRouteMetric2 data
     * set rowreq_ctx->data->ipCidrRouteMetric2 from rowreq_ctx->undo->ipCidrRouteMetric2
     */


    return MFD_SUCCESS;
}                               /* ipCidrRouteMetric2_undo */

/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::ipCidrRouteEntry.ipCidrRouteMetric3
 * ipCidrRouteMetric3 is subid 13 of ipCidrRouteEntry.
 * Its status is Deprecated, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.24.4.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 ipCidrRouteProto  
                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 ipCidrRouteMetric3_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
 * ipCidrRouteTable_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
ipCidrRouteMetric3_check_value(ipCidrRouteTable_rowreq_ctx * rowreq_ctx,
                               long ipCidrRouteMetric3_val)
{
    DEBUGMSGTL(("verbose:ipCidrRouteTable:ipCidrRouteMetric3_check_value",
                "called\n"));

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

    /*
     * TODO:441:o: |-> Check for valid ipCidrRouteMetric3 value.
     */
    /*
     * does any os use metric 2-5? if so, update to deal with it.
     * otherwise, only accept same value we have.
     */
    if (ipCidrRouteMetric3_val != rowreq_ctx->data->rt_metric3)
        return MFD_NOT_VALID_EVER;

    return MFD_SUCCESS;         /* ipCidrRouteMetric3 value not illegal */
}                               /* ipCidrRouteMetric3_check_value */

/**
 * Save old value information
 *
 * @param rowreq_ctx
 *        Pointer to the table context (ipCidrRouteTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 *
 * This function will be called after the table level undo setup function
 * ipCidrRouteTable_undo_setup has been called.
 *
 *@note
 * this function will only be called if a new value is set for this column.
 *
 * If there is any setup specific to a particular column (e.g. allocating
 * memory for a string), you should do that setup in this function, so it
 * won't be done unless it is necessary.
 */
int
ipCidrRouteMetric3_undo_setup(ipCidrRouteTable_rowreq_ctx * rowreq_ctx)
{
    DEBUGMSGTL(("verbose:ipCidrRouteTable:ipCidrRouteMetric3_undo_setup",
                "called\n"));

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

    /*
     * TODO:455:o: |-> Setup ipCidrRouteMetric3 undo.
     */
    /*
     * copy ipCidrRouteMetric3 data
     * set rowreq_ctx->undo->ipCidrRouteMetric3 from rowreq_ctx->data->ipCidrRouteMetric3
     */


    return MFD_SUCCESS;
}                               /* ipCidrRouteMetric3_undo_setup */

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

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

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

    /*
     * TODO:461:M: |-> Set ipCidrRouteMetric3 value.
     * set ipCidrRouteMetric3 value in rowreq_ctx->data
     */

    return MFD_SUCCESS;
}                               /* ipCidrRouteMetric3_set */

/**
 * undo the previous set.
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 */
int
ipCidrRouteMetric3_undo(ipCidrRouteTable_rowreq_ctx * rowreq_ctx)
{

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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:456:o: |-> Clean up ipCidrRouteMetric3 undo.
     */
    /*
     * copy ipCidrRouteMetric3 data
     * set rowreq_ctx->data->ipCidrRouteMetric3 from rowreq_ctx->undo->ipCidrRouteMetric3
     */


    return MFD_SUCCESS;
}                               /* ipCidrRouteMetric3_undo */

/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::ipCidrRouteEntry.ipCidrRouteMetric4
 * ipCidrRouteMetric4 is subid 14 of ipCidrRouteEntry.
 * Its status is Deprecated, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.24.4.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 ipCidrRouteProto  
                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 ipCidrRouteMetric4_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
 * ipCidrRouteTable_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
ipCidrRouteMetric4_check_value(ipCidrRouteTable_rowreq_ctx * rowreq_ctx,
                               long ipCidrRouteMetric4_val)
{
    DEBUGMSGTL(("verbose:ipCidrRouteTable:ipCidrRouteMetric4_check_value",
                "called\n"));

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

    /*
     * TODO:441:o: |-> Check for valid ipCidrRouteMetric4 value.
     */
    /*
     * does any os use metric 2-5? if so, update to deal with it.
     * otherwise, only accept same value we have.
     */
    if (ipCidrRouteMetric4_val != rowreq_ctx->data->rt_metric4)
        return MFD_NOT_VALID_EVER;

    return MFD_SUCCESS;         /* ipCidrRouteMetric4 value not illegal */
}                               /* ipCidrRouteMetric4_check_value */

/**
 * Save old value information
 *
 * @param rowreq_ctx
 *        Pointer to the table context (ipCidrRouteTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 *
 * This function will be called after the table level undo setup function
 * ipCidrRouteTable_undo_setup has been called.
 *
 *@note
 * this function will only be called if a new value is set for this column.
 *
 * If there is any setup specific to a particular column (e.g. allocating
 * memory for a string), you should do that setup in this function, so it
 * won't be done unless it is necessary.
 */
int
ipCidrRouteMetric4_undo_setup(ipCidrRouteTable_rowreq_ctx * rowreq_ctx)
{
    DEBUGMSGTL(("verbose:ipCidrRouteTable:ipCidrRouteMetric4_undo_setup",
                "called\n"));

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

    /*
     * TODO:455:o: |-> Setup ipCidrRouteMetric4 undo.
     */
    /*
     * copy ipCidrRouteMetric4 data
     * set rowreq_ctx->undo->ipCidrRouteMetric4 from rowreq_ctx->data->ipCidrRouteMetric4
     */


    return MFD_SUCCESS;
}                               /* ipCidrRouteMetric4_undo_setup */

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

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

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

    /*
     * TODO:461:M: |-> Set ipCidrRouteMetric4 value.
     * set ipCidrRouteMetric4 value in rowreq_ctx->data
     */

    return MFD_SUCCESS;
}                               /* ipCidrRouteMetric4_set */

/**
 * undo the previous set.
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 */
int
ipCidrRouteMetric4_undo(ipCidrRouteTable_rowreq_ctx * rowreq_ctx)
{

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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:456:o: |-> Clean up ipCidrRouteMetric4 undo.
     */
    /*
     * copy ipCidrRouteMetric4 data
     * set rowreq_ctx->data->ipCidrRouteMetric4 from rowreq_ctx->undo->ipCidrRouteMetric4
     */


    return MFD_SUCCESS;
}                               /* ipCidrRouteMetric4_undo */

/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::ipCidrRouteEntry.ipCidrRouteMetric5
 * ipCidrRouteMetric5 is subid 15 of ipCidrRouteEntry.
 * Its status is Deprecated, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.24.4.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 ipCidrRouteProto  
                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 ipCidrRouteMetric5_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
 * ipCidrRouteTable_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
ipCidrRouteMetric5_check_value(ipCidrRouteTable_rowreq_ctx * rowreq_ctx,
                               long ipCidrRouteMetric5_val)
{
    DEBUGMSGTL(("verbose:ipCidrRouteTable:ipCidrRouteMetric5_check_value",
                "called\n"));

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

    /*
     * TODO:441:o: |-> Check for valid ipCidrRouteMetric5 value.
     */
    /*
     * does any os use metric 2-5? if so, update to deal with it.
     * otherwise, only accept same value we have.
     */
    if (ipCidrRouteMetric5_val != rowreq_ctx->data->rt_metric5)
        return MFD_NOT_VALID_EVER;

    return MFD_SUCCESS;         /* ipCidrRouteMetric5 value not illegal */
}                               /* ipCidrRouteMetric5_check_value */

/**
 * Save old value information
 *
 * @param rowreq_ctx
 *        Pointer to the table context (ipCidrRouteTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 *
 * This function will be called after the table level undo setup function
 * ipCidrRouteTable_undo_setup has been called.
 *
 *@note
 * this function will only be called if a new value is set for this column.
 *
 * If there is any setup specific to a particular column (e.g. allocating
 * memory for a string), you should do that setup in this function, so it
 * won't be done unless it is necessary.
 */
int
ipCidrRouteMetric5_undo_setup(ipCidrRouteTable_rowreq_ctx * rowreq_ctx)
{
    DEBUGMSGTL(("verbose:ipCidrRouteTable:ipCidrRouteMetric5_undo_setup",
                "called\n"));

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

    /*
     * TODO:455:o: |-> Setup ipCidrRouteMetric5 undo.
     */
    /*
     * copy ipCidrRouteMetric5 data
     * set rowreq_ctx->undo->ipCidrRouteMetric5 from rowreq_ctx->data->ipCidrRouteMetric5
     */


    return MFD_SUCCESS;
}                               /* ipCidrRouteMetric5_undo_setup */

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

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

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

    /*
     * TODO:461:M: |-> Set ipCidrRouteMetric5 value.
     * set ipCidrRouteMetric5 value in rowreq_ctx->data
     */

    return MFD_SUCCESS;
}                               /* ipCidrRouteMetric5_set */

/**
 * undo the previous set.
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 */
int
ipCidrRouteMetric5_undo(ipCidrRouteTable_rowreq_ctx * rowreq_ctx)
{

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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:456:o: |-> Clean up ipCidrRouteMetric5 undo.
     */
    /*
     * copy ipCidrRouteMetric5 data
     * set rowreq_ctx->data->ipCidrRouteMetric5 from rowreq_ctx->undo->ipCidrRouteMetric5
     */


    return MFD_SUCCESS;
}                               /* ipCidrRouteMetric5_undo */

/*---------------------------------------------------------------------
 * IP-FORWARD-MIB::ipCidrRouteEntry.ipCidrRouteStatus
 * ipCidrRouteStatus is subid 16 of ipCidrRouteEntry.
 * Its status is Deprecated, and its access level is Create.
 * OID: .1.3.6.1.2.1.4.24.4.1.16
 * Description:
The row status variable, used according to row  
                installation and removal conventions.
 *
 * 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 ipCidrRouteStatus_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
 * ipCidrRouteTable_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
ipCidrRouteStatus_check_value(ipCidrRouteTable_rowreq_ctx * rowreq_ctx,
                              u_long ipCidrRouteStatus_val)
{
    DEBUGMSGTL(("verbose:ipCidrRouteTable:ipCidrRouteStatus_check_value",
                "called\n"));

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

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

    return MFD_SUCCESS;         /* ipCidrRouteStatus value not illegal */
}                               /* ipCidrRouteStatus_check_value */

/**
 * Save old value information
 *
 * @param rowreq_ctx
 *        Pointer to the table context (ipCidrRouteTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 *
 * This function will be called after the table level undo setup function
 * ipCidrRouteTable_undo_setup has been called.
 *
 *@note
 * this function will only be called if a new value is set for this column.
 *
 * If there is any setup specific to a particular column (e.g. allocating
 * memory for a string), you should do that setup in this function, so it
 * won't be done unless it is necessary.
 */
int
ipCidrRouteStatus_undo_setup(ipCidrRouteTable_rowreq_ctx * rowreq_ctx)
{
    DEBUGMSGTL(("verbose:ipCidrRouteTable:ipCidrRouteStatus_undo_setup",
                "called\n"));

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

    /*
     * TODO:455:o: |-> Setup ipCidrRouteStatus undo.
     */
    /*
     * copy ipCidrRouteStatus data
     * set rowreq_ctx->undo->ipCidrRouteStatus from rowreq_ctx->data->ipCidrRouteStatus
     */


    return MFD_SUCCESS;
}                               /* ipCidrRouteStatus_undo_setup */

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

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

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

    /*
     * TODO:461:M: |-> Set ipCidrRouteStatus value.
     * set ipCidrRouteStatus value in rowreq_ctx->data
     */

    return MFD_SUCCESS;
}                               /* ipCidrRouteStatus_set */

/**
 * undo the previous set.
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 */
int
ipCidrRouteStatus_undo(ipCidrRouteTable_rowreq_ctx * rowreq_ctx)
{

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

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:456:o: |-> Clean up ipCidrRouteStatus undo.
     */
    /*
     * copy ipCidrRouteStatus data
     * set rowreq_ctx->data->ipCidrRouteStatus from rowreq_ctx->undo->ipCidrRouteStatus
     */


    return MFD_SUCCESS;
}                               /* ipCidrRouteStatus_undo */

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