/**
 * ============================================================================
 * = COPYRIGHT
 *              INTEL CORPORATION PROPRIETARY INFORMATION
 *   This software is supplied under the terms of a license agreement or
 *   nondisclosure agreement with Intel Corporation and may not be copied 
 *   or disclosed except in accordance with the terms in that agreement.
 *      Copyright (C) 2000-2001 Intel Corporation. All rights reserved.
 *
 * = PRODUCT
 *      Intel(r) IXA SDK 3.0 for the IXP2000 Network Processor, Release 5
 *
 * = LIBRARY
 *      
 *
 * = MODULE
 *      IPv4 Forwarder Core Component - message helpers
 *
 * = FILENAME
 *      ix_cc_ipv4_msg_helpers.c
 *
 * = DESCRIPTION
 *      The file defines message helper interface functions.
 *
 * = AUTHOR
 *       Govindan Nair
 *       govindan.nair@intel.com
 *
 * = AKNOWLEDGEMENTS
 *      
 *
 * = CREATION TIME
 *      07/08/2002
 *
 * = CHANGE HISTORY
 *
 * ============================================================================
 */
#define IX_ERROR_FILE_IDENT "$Id: ix_cc_ipv4_msg_helpers.c,v 1.12 2002/10/09 01:44:25 gnair1 Exp $";



/**
 * System defined include files
 */

/**
 * User defined include files
 */

#include "ix_cc_error.h"
#include "ix_ossl.h"
#include "ix_rm.h"
#include "cc/ix_cc_rtmv4.h"
#include "ipv4_fwder_uc.h"
#include "ix_cc.h"
#include "bindings.h"
#include "cc/ix_cc_ipv4.h"
#include "cc/ix_cc_msup.h"


#include "cc/ipv4/internal/icmp.h"
#include "cc/ipv4/internal/ix_cc_ipv4_msg_handler.h"




/**
 * Preprocessor symbols and Macros used in this file
 */

/**
 * Type definitions whose scope is limited to this file
 */


/**
 * Variable declarations global to this file only. Externs are followed by 
 * static variables.
 */


/** 
 * Extern function prototypes.
 */

/** 
 * Static function prototypes.
 */




/** 
 * Function definitions.
 */



/**
 * NAME: ix_cc_ipv4_async_add_route
 *
 * DESCRIPTION: This message helper primitive helps client to add a route in RTM. 
 * Client needs to successfully add nextHopId to RTM by calling ix_cc_ipv4_async_add_next_hop
 * messaging helper primitive before sending this message to IPv4 Forwarder core component. 
 * 
 * @Param:  - IN arg_IpAddr: network IP address identifying the route.
 * @Param:  - IN arg_NetMask: network mask for the route.
 * @Param:  - IN arg_NextHopId: next hop identifier for route.
 * @Param:  - IN arg_Callback : pointer to client provided callback function.
 * @Param:  - IN arg_pUserContext: pointer to client defined context.
 *
 * @Param:  - OUT - none
 * 
 * @Return: IX_SUCCESS if successful or a valid error token for failure.
 *
 * Error Codes:
 * 
 * IX_CC_ERROR_NULL - invalid pointer
 * IX_CC_IPV4_ERROR_MSG_LIBRARY- failure from Message Support Library
 * 
 */

ix_error ix_cc_ipv4_async_add_route(ix_uint32 arg_IpAddr,
                                    ix_uint32 arg_NetMask,
                                    ix_cc_rtmv4_nhid arg_NextHopId,
                                    ix_cc_ipv4_cb_route_op arg_Callback,
                                    void* arg_pUserContext
                                   )
{
    ix_cc_ipv4_add_route_data addRoute;
    ix_cc_ipv4_general_callback_data* cbContext;
    ix_error err = IX_SUCCESS;

    if(arg_Callback == NULL)
    {
        return IX_ERROR_WARNING(IX_CC_ERROR_NULL,
                               ("Invalid pointer: arg_pCallback"));
    }/* end if(arg_Callback == NULL) */

    cbContext = (ix_cc_ipv4_general_callback_data*) ix_ossl_malloc(sizeof(ix_cc_ipv4_general_callback_data));    
    if(cbContext == NULL)
    {
        return IX_ERROR_WARNING(IX_CC_ERROR_OOM,("No memory for context"));
    }/* end if no memory for context */

    addRoute.ipAddr = arg_IpAddr;
    addRoute.netMask = arg_NetMask;
    addRoute.nextHopId = arg_NextHopId;


    cbContext->pUserCallback = arg_Callback;   
    cbContext->pUserContext = arg_pUserContext;

    IX_ERROR_CGT(ix_cc_msup_send_async_msg(IX_CC_IPV4_MSG_INPUT,
                                    _ix_cc_ipv4_cb_general,
                                    (void*)cbContext,
                                    IX_CC_IPV4_MSG_ADD_ROUTE,
                                    (void *)&addRoute,
                                    sizeof(ix_cc_ipv4_add_route_data)),
                 err,
                 IX_CC_IPV4_ERROR_MSG_LIBRARY,
                 IX_ERROR_LEVEL_WARNING,
                 cleanup_context);

    return IX_SUCCESS;

cleanup_context:
    if(cbContext != NULL)
    {
        ix_ossl_free(cbContext);
    }/* end if cbContext != NULL */
    return err;
} /* end ix_cc_ipv4_async_add_route */





/**
 * NAME: ix_cc_ipv4_async_delete_route
 *
 * DESCRIPTION:This message helper primitive helps a client to delete a route in RTM. 
 * Client needs to delete all routes associate with a next hop to delete the next hop
 * by calling ix_cc_ipv4_async_delete_next_hop message helper primitive. 
 * 
 * @Param:  - IN arg_IpAddr: network IP address identifying the route.
 * @Param:  - IN arg_NetMask: network mask for the route.
 * @Param:  - IN arg_Callback : pointer to client provided callback function.
 * @Param:  - IN arg_pUserContext: pointer to client defined context.
 *
 * @Param:  - OUT -none
 * 
 * @Return: IX_SUCCESS if successful or a valid error token for failure.
 *
 * Error Codes:
 *
 * IX_CC_ERROR_NULL - invalid pointer
 * IX_CC_IPV4_ERROR_MSG_LIBRARY- failure from Message Support Library 
 * 
 */

ix_error ix_cc_ipv4_async_delete_route(ix_uint32 arg_IpAddr,
                                       ix_uint32 arg_NetMask,
                                       ix_cc_ipv4_cb_route_op arg_Callback,
                                       void* arg_pUserContext
                                      )
{

    ix_cc_ipv4_delete_route_data deleteRoute;
    ix_cc_ipv4_general_callback_data *cbContext;
    ix_error err = IX_SUCCESS;

    if(arg_Callback == NULL)
    {
        return IX_ERROR_WARNING(IX_CC_ERROR_NULL,
                                ("Invalid pointer: arg_pCallback"));
    }/* end if(arg_Callback == NULL) */

    cbContext = (ix_cc_ipv4_general_callback_data*) ix_ossl_malloc(sizeof(ix_cc_ipv4_general_callback_data));    
    if(cbContext == NULL)
    {
        return IX_ERROR_WARNING(IX_CC_ERROR_OOM,("No memory for context"));
    }/* end if no memory for context */
    
    deleteRoute.ipAddr = arg_IpAddr;
    deleteRoute.netMask = arg_NetMask;


    cbContext->pUserCallback = arg_Callback;   
    cbContext->pUserContext = arg_pUserContext;

    IX_ERROR_CGT(ix_cc_msup_send_async_msg(IX_CC_IPV4_MSG_INPUT,
                                    _ix_cc_ipv4_cb_general,
                                    (void *)cbContext,
                                    IX_CC_IPV4_MSG_DELETE_ROUTE,
                                    (void *)&deleteRoute,
                                    sizeof(ix_cc_ipv4_delete_route_data)),
                 err,
                 IX_CC_IPV4_ERROR_MSG_LIBRARY,
                 IX_ERROR_LEVEL_WARNING, cleanup_context);

    return IX_SUCCESS;
cleanup_context:
    if(cbContext != NULL)
    {
        ix_ossl_free(cbContext);
    }/* end if cbContext != NULL */
    return err;

} /* end ix_cc_ipv4_async_delete_route */




/**
 * NAME: ix_cc_ipv4_async_update_route
 *
 * DESCRIPTION: This message helper primitive helps client to update a route in RTM. 
 * Client needs to successfully add nextHopId to RTM by calling ix_cc_ipv4_async_add_next_hop
 * messaging helper primitive before sending this message to IPv4 Forwarder core component. 
 * 
 * @Param:  - IN arg_IpAddr: network IP address identifying the route.
 * @Param:  - IN arg_NetMask: network mask for the route.
 * @Param:  - IN arg_NextHopId: next hop identifier for the route.
 * @Param:  - IN arg_Callback : pointer to client provided callback function.
 * @Param:  - IN arg_pUserContext: pointer to client defined context.
 *
 * @Param:  - OUT - none
 * 
 * @Return: IX_SUCCESS if successful or a valid error token for failure.
 *
 * Error Codes:
 * 
 * IX_CC_ERROR_NULL - invalid pointer
 * IX_CC_IPV4_ERROR_MSG_LIBRARY- failure from Message Support Library
 * 
 */

ix_error ix_cc_ipv4_async_update_route(ix_uint32 arg_IpAddr,
                                    ix_uint32 arg_NetMask,
                                    ix_cc_rtmv4_nhid arg_NextHopId,
                                    ix_cc_ipv4_cb_route_op arg_Callback,
                                    void* arg_pUserContext
                                   )
{
    ix_cc_ipv4_add_route_data addRoute;
    ix_cc_ipv4_general_callback_data *cbContext;
    ix_error err = IX_SUCCESS;

    if(arg_Callback == NULL)
    {
        return IX_ERROR_WARNING(IX_CC_ERROR_NULL,
                               ("Invalid pointer: arg_pCallback"));
    }/* end if(arg_Callback == NULL) */

    cbContext = (ix_cc_ipv4_general_callback_data*) ix_ossl_malloc(sizeof(ix_cc_ipv4_general_callback_data));    
    if(cbContext == NULL)
    {
        return IX_ERROR_WARNING(IX_CC_ERROR_OOM,("No memory for context"));
    }/* end if no memory for context */
    
    addRoute.ipAddr = arg_IpAddr;
    addRoute.netMask = arg_NetMask;
    addRoute.nextHopId = arg_NextHopId;


    cbContext->pUserCallback = arg_Callback;   
    cbContext->pUserContext = arg_pUserContext;

    IX_ERROR_CGT(ix_cc_msup_send_async_msg(IX_CC_IPV4_MSG_INPUT,
                                    _ix_cc_ipv4_cb_general,
                                    (void *)cbContext,
                                    IX_CC_IPV4_MSG_UPDATE_ROUTE,
                                    (void *)&addRoute,
                                    sizeof(ix_cc_ipv4_add_route_data)),
                 err,
                 IX_CC_IPV4_ERROR_MSG_LIBRARY,
                 IX_ERROR_LEVEL_WARNING, cleanup_context);
   

    return IX_SUCCESS;
cleanup_context:
    if(cbContext != NULL)
    {
        ix_ossl_free(cbContext);
    }/* end if cbContext != NULL */
    return err;

} /* end ix_cc_ipv4_async_update_route */



/**
 * NAME: ix_cc_ipv4_async_lookup_route
 *
 * DESCRIPTION: This primitive helps a client to look up routing information 
 * for a given IP address. If there is a successful match, then the information will be 
 * given to client are nextHopId (including the blade id), portId, mtu and flags. 
 * If there is no match, then IX_CC_RTMV4_NHID_NO_ROUTE will be assigned to nextHopId
 * field of pNextHopData and all other information are invalid.
 * 
 * @Param:  - IN arg_IpAddr: network IP address identifying the route.
 * @Param:  - IN arg_Callback : pointer to client provided callback function.
 * @Param:  - IN arg_pUserContext: pointer to client defined context.
 *
 * @Param:  - OUT -none
 * 
 * @Return: IX_SUCCESS if successful or a valid error token for failure.
 *
 * Error Codes:
 *
 * IX_CC_ERROR_NULL - invalid pointer
 * IX_CC_IPV4_ERROR_MSG_LIBRARY- failure from Message Support Library 
 */

ix_error ix_cc_ipv4_async_lookup_route(ix_uint32 arg_IpAddr,
                                       ix_cc_ipv4_cb_lookup_route arg_Callback,
                                       void* arg_pUserContext
                                      )
{
    ix_cc_ipv4_lookup_callback_data *cbContext;
    ix_error err = IX_SUCCESS;

    if(arg_Callback == NULL)
    {
        return IX_ERROR_WARNING(IX_CC_ERROR_NULL,
                               ("Invalid pointer: arg_pCallback"));
    }/* end if(arg_Callback == NULL)  */

    cbContext = (ix_cc_ipv4_lookup_callback_data*) ix_ossl_malloc(sizeof(ix_cc_ipv4_lookup_callback_data));    
    if(cbContext == NULL)
    {
        return IX_ERROR_WARNING(IX_CC_ERROR_OOM,("No memory for context"));
    }/* end if no memory for context */

   
    cbContext->pUserCallback = arg_Callback;   
    cbContext->pUserContext = arg_pUserContext;

    IX_ERROR_CGT(ix_cc_msup_send_async_msg(IX_CC_IPV4_MSG_INPUT,
                                    _ix_cc_ipv4_cb_lookup_rtm,
                                    (void *)cbContext,
                                    IX_CC_IPV4_MSG_LOOKUP_ROUTE,
                                    (void *)&arg_IpAddr,
                                    sizeof(ix_uint32)),
                 err,
                 IX_CC_IPV4_ERROR_MSG_LIBRARY,
                 IX_ERROR_LEVEL_WARNING, cleanup_context);

    return IX_SUCCESS;
cleanup_context:
    if(cbContext != NULL)
    {
        ix_ossl_free(cbContext);
    }/* end if cbContext != NULL */
    return err;

} /* end ix_cc_ipv4_async_lookup_route */


/**
 * NAME: ix_cc_ipv4_async_purge_routes
 *
 * DESCRIPTION: This primitive helps a client to remove all routes from RTM.
 * 
 * @Param:  - IN none
 *
 * @Param:  - OUT none
 * 
 * @Return: IX_SUCCESS if successful or a valid error token for failure.
 *
 * Error Codes:
 *
 * IX_CC_IPV4_ERROR_MSG_LIBRARY- failure from Message Support Library 
 */

ix_error ix_cc_ipv4_async_purge_routes()
{

    IX_ERROR_CRT(ix_cc_msup_send_msg(IX_CC_IPV4_MSG_INPUT,
                              IX_CC_IPV4_MSG_PURGE_ROUTES,
                              NULL,0),
                 IX_CC_IPV4_ERROR_MSG_LIBRARY,
                 IX_ERROR_LEVEL_WARNING);

    return IX_SUCCESS;

} /* end ix_cc_ipv4_async_purge_routes */


/**
 * NAME: ix_cc_ipv4_async_dump_routes
 *
 * DESCRIPTION: This primitive helps to dump all routes of RTM in memory
 * 
 * @Param:  - IN arg_Callback : pointer to client provided callback function.
 * @Param:  - IN arg_pUserContext: pointer to client defined context
 *
 * @Param:  - OUT none
 * 
 * @Return: IX_SUCCESS if successful or a valid error token for failure.
 *
 * Error Codes:
 *
 * IX_CC_ERROR_NULL - invalid pointer
 * IX_CC_IPV4_ERROR_MSG_LIBRARY- failure from Message Support Library 
 * 
 */

ix_error ix_cc_ipv4_async_dump_routes(ix_cc_ipv4_cb_dump_data arg_Callback,
                                      void* arg_pUserContext
                                     )
{
    ix_cc_ipv4_dump_callback_data *cbContext;
    ix_error err = IX_SUCCESS;
    

    if(arg_Callback == NULL)
    {
        return IX_ERROR_WARNING(IX_CC_ERROR_NULL,
                                ("Invalid pointer: arg_pCallback "));
    }/* end if(arg_Callback == NULL)  */

    cbContext = (ix_cc_ipv4_dump_callback_data*) ix_ossl_malloc(sizeof(ix_cc_ipv4_dump_callback_data));    
    if(cbContext == NULL)
    {
        return IX_ERROR_WARNING(IX_CC_ERROR_OOM,("No memory for context"));
    }/* end if no memory for context */


    cbContext->pUserCallback = arg_Callback;   
    cbContext->pUserContext = arg_pUserContext;

    IX_ERROR_CGT(ix_cc_msup_send_async_msg(IX_CC_IPV4_MSG_INPUT,
                                    _ix_cc_ipv4_cb_dump_rtm,
                                    (void *)cbContext,
                                    IX_CC_IPV4_MSG_DUMP_ROUTES,
                                    NULL,
                                    0),
                 err,
                 IX_CC_IPV4_ERROR_MSG_LIBRARY,
                 IX_ERROR_LEVEL_WARNING, cleanup_context);
   
    return IX_SUCCESS;
cleanup_context:
    if(cbContext != NULL)
    {
        ix_ossl_free(cbContext);
    }/* end if cbContext != NULL */
    return err;

} /* end ix_cc_ipv4_async_dump_routes */



/**
 * NAME: ix_cc_ipv4_async_add_next_hop
 *
 * DESCRIPTION: This primitive helps a client to add next hop information to RTM database. 
 * Client needs to add next hop to RTM in order to add routes referring to that next hop.
 * 
 * @Param:  - IN arg_NextHopId: identifier of next hop to be added
 * @Param:  - IN arg_pNextHopData: pointer to next hop information
 * @Param:  - IN arg_Callback : pointer to client provided callback function.
 * @Param:  - IN arg_pUserContext: pointer to client defined contex
 * 
 * @Param:  - OUT - none
 * 
 * @Return: IX_SUCCESS if successful or a valid error token for failure.
 *
 * Error Codes:
 *
 * IX_CC_ERROR_NULL - invalid pointer
 * IX_CC_IPV4_ERROR_MSG_LIBRARY- failure from Message Support Library 
 * 
 */

ix_error ix_cc_ipv4_async_add_next_hop(ix_cc_rtmv4_nhid arg_NextHopId,
                                       ix_cc_rtmv4_next_hop_info* arg_pNextHopData,
                                       ix_cc_ipv4_cb_route_op arg_Callback,
                                       void* arg_pUserContext
                                      )
{
    ix_cc_ipv4_general_callback_data *cbContext;
    ix_cc_ipv4_add_next_hop_data addNextHop;
    ix_error err = IX_SUCCESS;

    if(arg_Callback == NULL)
    {
        return IX_ERROR_WARNING(IX_CC_ERROR_NULL,
                               ("Invalid pointer: arg_pCallback"));
    }/* end if(arg_Callback == NULL) */

    cbContext = (ix_cc_ipv4_general_callback_data*) ix_ossl_malloc(sizeof(ix_cc_ipv4_general_callback_data));    
    if(cbContext == NULL)
    {
        return IX_ERROR_WARNING(IX_CC_ERROR_OOM,("No memory for context"));
    }/* end if no memory for context */


    addNextHop.nextHopId = arg_NextHopId;
    ix_ossl_memcpy(&addNextHop.nextHopInfo,arg_pNextHopData,sizeof(ix_cc_rtmv4_next_hop_info));

    
    cbContext->pUserCallback = arg_Callback;   
    cbContext->pUserContext = arg_pUserContext;

    IX_ERROR_CGT(ix_cc_msup_send_async_msg(IX_CC_IPV4_MSG_INPUT,
                                    _ix_cc_ipv4_cb_general,
                                    (void *)cbContext,
                                    IX_CC_IPV4_MSG_ADD_NEXT_HOP,
                                    (void *)&addNextHop,
                                    sizeof(ix_cc_ipv4_add_next_hop_data)),
                 err,
                 IX_CC_IPV4_ERROR_MSG_LIBRARY,
                 IX_ERROR_LEVEL_WARNING, cleanup_context);   

    return IX_SUCCESS;
cleanup_context:
    if(cbContext != NULL)
    {
        ix_ossl_free(cbContext);
    }/* end if cbContext != NULL */
    return err;

} /* end ix_cc_ipv4_async_add_next_hop */





/**
 * NAME: ix_cc_ipv4_async_delete_next_hop
 *
 * DESCRIPTION: This message helper primitive helps a client to delete next hop information 
 * from RTM database. Client needs to remove all routes associated with next hop before 
 * calling this primitive. If not, client gets an error.
 * 
 * @Param:  - IN arg_NextHopId: identifier of next hop to be removed.
 * @Param:  - IN arg_Callback : pointer to client provided callback function.
 * @Param:  - IN arg_pUserContext: pointer to client defined context
 *
 * @Param:  - OUT - none
 * 
 * @Return: IX_SUCCESS if successful or a valid error token for failure.
 *
 * Error Codes:
 *
 * IX_CC_ERROR_NULL - invalid pointer
 * IX_CC_IPV4_ERROR_MSG_LIBRARY- failure from Message Support Library 
 */

ix_error ix_cc_ipv4_async_delete_next_hop(ix_cc_rtmv4_nhid arg_NextHopId,
                                          ix_cc_ipv4_cb_route_op arg_Callback,
                                          void* arg_pUserContext
                                          )
{
    ix_cc_ipv4_general_callback_data *cbContext;
    ix_error err = IX_SUCCESS;

    if(arg_Callback == NULL)
    {
        return IX_ERROR_WARNING(IX_CC_ERROR_NULL,
                               ("Invalid pointer: arg_pCallback"));
    }/* end if(arg_Callback == NULL) */
    cbContext = (ix_cc_ipv4_general_callback_data*) ix_ossl_malloc(sizeof(ix_cc_ipv4_general_callback_data));    
    if(cbContext == NULL)
    {
        return IX_ERROR_WARNING(IX_CC_ERROR_OOM,("No memory for context"));
    }/* end if no memory for context */


    cbContext->pUserCallback = arg_Callback;   
    cbContext->pUserContext = arg_pUserContext;

    IX_ERROR_CGT(ix_cc_msup_send_async_msg(IX_CC_IPV4_MSG_INPUT,
                                    _ix_cc_ipv4_cb_general,
                                    (void *)cbContext,
                                    IX_CC_IPV4_MSG_DELETE_NEXT_HOP,
                                    (void *)&arg_NextHopId,
                                    sizeof(ix_cc_rtmv4_nhid)),
                 err,
                 IX_CC_IPV4_ERROR_MSG_LIBRARY,
                 IX_ERROR_LEVEL_WARNING, cleanup_context);

    return IX_SUCCESS;
cleanup_context:
    if(cbContext != NULL)
    {
        ix_ossl_free(cbContext);
    }/* end if cbContext != NULL */
    return err;

} /* end ix_cc_ipv4_async_delete_next_hop */



/**
 * NAME: ix_cc_ipv4_async_update_next_hop
 *
 * DESCRIPTION: This primitive helps a client to update next hop information to RTM database. 
 * Client needs to add next hop to RTM in order to add routes referring to that next hop.
 * 
 * @Param:  - IN arg_NextHopId: identifier of next hop to be updated
 * @Param:  - IN arg_pNextHopData: pointer to next hop information
 * @Param:  - IN arg_Callback : pointer to client provided callback function.
 * @Param:  - IN arg_pUserContext: pointer to client defined contex
 * 
 * @Param:  - OUT - none
 * 
 * @Return: IX_SUCCESS if successful or a valid error token for failure.
 *
 * Error Codes:
 *
 * IX_CC_ERROR_NULL - invalid pointer
 * IX_CC_IPV4_ERROR_MSG_LIBRARY- failure from Message Support Library 
 * 
 */

ix_error ix_cc_ipv4_async_update_next_hop(ix_cc_rtmv4_nhid arg_NextHopId,
                                       ix_cc_rtmv4_next_hop_info* arg_pNextHopData,
                                       ix_cc_ipv4_cb_route_op arg_Callback,
                                       void* arg_pUserContext
                                      )
{
    ix_cc_ipv4_general_callback_data *cbContext;
    ix_cc_ipv4_add_next_hop_data addNextHop;
    ix_error err = IX_SUCCESS;

    if(arg_Callback == NULL)
    {
        return IX_ERROR_WARNING(IX_CC_ERROR_NULL,
                               ("Invalid pointer: arg_pCallback"));
    }/* end if(arg_Callback == NULL) */
    cbContext = (ix_cc_ipv4_general_callback_data*) ix_ossl_malloc(sizeof(ix_cc_ipv4_general_callback_data));    
    if(cbContext == NULL)
    {
        return IX_ERROR_WARNING(IX_CC_ERROR_OOM,("No memory for context"));
    }/* end if no memory for context */


    addNextHop.nextHopId = arg_NextHopId;
    ix_ossl_memcpy(&addNextHop.nextHopInfo,arg_pNextHopData,sizeof(ix_cc_rtmv4_next_hop_info));

    
    cbContext->pUserCallback = arg_Callback;   
    cbContext->pUserContext = arg_pUserContext;

    IX_ERROR_CGT(ix_cc_msup_send_async_msg(IX_CC_IPV4_MSG_INPUT,
                                    _ix_cc_ipv4_cb_general,
                                    (void *)cbContext,
                                    IX_CC_IPV4_MSG_UPDATE_NEXT_HOP,
                                    (void *)&addNextHop,
                                    sizeof(ix_cc_ipv4_add_next_hop_data)),
                  err,
                  IX_CC_IPV4_ERROR_MSG_LIBRARY,
                  IX_ERROR_LEVEL_WARNING, cleanup_context);   

    return IX_SUCCESS;
cleanup_context:
    if(cbContext != NULL)
    {
        ix_ossl_free(cbContext);
    }/* end if cbContext != NULL */
    return err;

} /* end ix_cc_ipv4_async_update_next_hop */





/**
 * NAME: ix_cc_ipv4_async_get_next_hop
 *
 * DESCRIPTION: This message helper primitive helps a client to retrieve 
 * next hop information from RTM database. 
 * 
 * @Param:  - IN arg_NextHopId: Identifier of the next hop information to be retrieved from RTM.
 * @Param:  - IN arg_Callback: pointer to client provided callback function.
 * @Param:  - IN arg_pUserContext: pointer to client defined context.
 *
 * @Param:  - OUT - none
 * 
 * @Return: IX_SUCCESS if successful or a valid error token for failure.
 *
 * Error Codes:
 *
 * IX_CC_ERROR_NULL - invalid pointer
 * IX_CC_IPV4_ERROR_MSG_LIBRARY- failure from Message Support Library 
 */

ix_error ix_cc_ipv4_async_get_next_hop(ix_cc_rtmv4_nhid arg_NextHopId,
                                       ix_cc_ipv4_cb_get_next_hop arg_Callback,
                                       void* arg_pUserContext
                                      )
{

    ix_cc_ipv4_lookup_callback_data *cbContext;
    ix_error err = IX_SUCCESS;

    if(arg_Callback == NULL)
    {
        return IX_ERROR_WARNING(IX_CC_ERROR_NULL,
                               ("Invalid pointer: arg_pCallback"));

    }/* end if(arg_Callback == NULL)  */

    cbContext = (ix_cc_ipv4_lookup_callback_data*) ix_ossl_malloc(sizeof(ix_cc_ipv4_lookup_callback_data));    
    if(cbContext == NULL)
    {
        return IX_ERROR_WARNING(IX_CC_ERROR_OOM,("No memory for context"));
    }/* end if no memory for context */
    
   
    cbContext->pUserCallback = arg_Callback;   
    cbContext->pUserContext = arg_pUserContext;

    IX_ERROR_CGT(ix_cc_msup_send_async_msg(IX_CC_IPV4_MSG_INPUT,
                                    _ix_cc_ipv4_cb_lookup_rtm,
                                    (void *)cbContext,
                                    IX_CC_IPV4_MSG_GET_NEXT_HOP,
                                    (void *)&arg_NextHopId,
                                    sizeof(ix_cc_rtmv4_nhid)),
                 err,
                 IX_CC_IPV4_ERROR_MSG_LIBRARY,
                 IX_ERROR_LEVEL_WARNING, cleanup_context);

    return IX_SUCCESS;
cleanup_context:
    if(cbContext != NULL)
    {
        ix_ossl_free(cbContext);
    }/* end if cbContext != NULL */
    return err;

} /* end ix_cc_ipv4_async_get_next_hop */





/**
 * NAME: ix_cc_ipv4_async_purge_rtm
 *
 * DESCRIPTION: This primitive helps a client to removes all routes and next hops from RTM database
 * 
 * @Param:  - IN none
 *
 * @Param:  - OUT - none
 * 
 * @Return: IX_SUCCESS if successful or a valid error token for failure.
 *
 * Error Codes:
 *
 * IX_CC_IPV4_ERROR_MSG_LIBRARY- failure from Message Support Library 
 * 
 */

ix_error ix_cc_ipv4_async_purge_rtm()
{

   
    IX_ERROR_CRT(ix_cc_msup_send_msg(IX_CC_IPV4_MSG_INPUT,
                              IX_CC_IPV4_MSG_PURGE_RTM,
                              NULL,
                              0),
                 IX_CC_IPV4_ERROR_MSG_LIBRARY,
                 IX_ERROR_LEVEL_WARNING);

    return IX_SUCCESS;

} /* end ix_cc_ipv4_async_purge_rtm */






/**
 * NAME: ix_cc_ipv4_async_dump_next_hops
 *
 * DESCRIPTION:   This primitive helps to dump all next hops of RTM in memory.
 * 
 * @Param:  - IN arg_Callback : pointer to client provided callback function.
 * @Param:  - IN arg_pUserContext: pointer to client defined context.
 *
 * @Param:  - OUT none
 * 
 * @Return: IX_SUCCESS if successful or a valid error token for failure.
 *
 * Error Codes:
 *
 * IX_CC_ERROR_NULL - invalid pointer
 * IX_CC_IPV4_ERROR_MSG_LIBRARY- failure from Message Support Library 
 */

ix_error ix_cc_ipv4_async_dump_next_hops(ix_cc_ipv4_cb_dump_data arg_Callback,
                                         void* arg_pUserContext
                                        )
{
    ix_cc_ipv4_dump_callback_data *cbContext;
    ix_error err = IX_SUCCESS;

    if(arg_Callback == NULL)
    {
        return IX_ERROR_WARNING(IX_CC_ERROR_NULL,
                                ("Invalid pointer: arg_pCallback "));
    }/* end if(arg_Callback == NULL)  */

    cbContext = (ix_cc_ipv4_dump_callback_data*) ix_ossl_malloc(sizeof(ix_cc_ipv4_dump_callback_data));    
    if(cbContext == NULL)
    {
        return IX_ERROR_WARNING(IX_CC_ERROR_OOM,("No memory for context"));
    }/* end if no memory for context */


    cbContext->pUserCallback = arg_Callback;   
    cbContext->pUserContext = arg_pUserContext;

    IX_ERROR_CGT(ix_cc_msup_send_async_msg(IX_CC_IPV4_MSG_INPUT,
                                    _ix_cc_ipv4_cb_dump_rtm,
                                    (void *)cbContext,
                                    IX_CC_IPV4_MSG_DUMP_NEXT_HOPS,
                                    NULL,
                                    0),
                  err,
                  IX_CC_IPV4_ERROR_MSG_LIBRARY,
                  IX_ERROR_LEVEL_WARNING, cleanup_context);
      
    return IX_SUCCESS;

cleanup_context:
    if(cbContext != NULL)
    {
        ix_ossl_free(cbContext);
    }/* end if cbContext != NULL */
    return err;

} /* end ix_cc_ipv4_async_dump_next_hops */







/**
 * NAME: ix_cc_ipv4_async_set_mtu
 *
 * DESCRIPTION:This primitive helps client to update MTU for a given next hop. 
 * Before calling this message helper, client needs to call ix_cc_ipv4_async_add_next_hop to 
 * add next hop identifier in RTM database. The validity of MTU shall be done by the client.
 * 
 * @Param:  - IN arg_NextHopId: identifier of next hop.
 * @Param:  - IN arg_Mtu: new maximum transmission unit for the given next hop.
 * @Param:  - IN arg_pUserContext: pointer to client defined context.
 *
 * @Param:  - OUT - none
 * 
 * @Return: IX_SUCCESS if successful or a valid error token for failure.
 *
 * Error Codes:
 *
 * IX_CC_ERROR_NULL - invalid pointer
 * IX_CC_IPV4_ERROR_MSG_LIBRARY- failure from Message Support Library 
 */

ix_error ix_cc_ipv4_async_set_mtu(ix_cc_rtmv4_nhid arg_NextHopId,
                                  ix_uint32 arg_Mtu,
                                  ix_cc_ipv4_cb_route_op arg_Callback,
                                  void* arg_pUserContext
                                 )
{
    ix_cc_ipv4_general_callback_data *cbContext;
    ix_cc_ipv4_set_mtu_data mtuData;
    ix_error err = IX_SUCCESS;

    if(arg_Callback == NULL)
    {
        return IX_ERROR_WARNING(IX_CC_ERROR_NULL,
                               ("Invalid pointer: arg_pCallback "));
    }/* end if(arg_Callback == NULL)  */

    cbContext = (ix_cc_ipv4_general_callback_data*) ix_ossl_malloc(sizeof(ix_cc_ipv4_general_callback_data));    
    if(cbContext == NULL)
    {
        return IX_ERROR_WARNING(IX_CC_ERROR_OOM,("No memory for context"));
    }/* end if no memory for context */

    cbContext->pUserCallback = arg_Callback;   
    cbContext->pUserContext = arg_pUserContext;

    mtuData.nextHopId = arg_NextHopId;
    mtuData.mtu = arg_Mtu;

    IX_ERROR_CGT(ix_cc_msup_send_async_msg(IX_CC_IPV4_MSG_INPUT,
                                    _ix_cc_ipv4_cb_general,
                                    (void *)cbContext,
                                    IX_CC_IPV4_MSG_SET_MTU,
                                    (void*)&mtuData,
                                    sizeof(ix_cc_ipv4_set_mtu_data)),
                  err,
                  IX_CC_IPV4_ERROR_MSG_LIBRARY,
                  IX_ERROR_LEVEL_WARNING, cleanup_context);
    
    return IX_SUCCESS;

cleanup_context:
    if(cbContext != NULL)
    {
        ix_ossl_free(cbContext);
    }/* end if cbContext != NULL */
    return err;

} /* end ix_cc_ipv4_async_set_mtu  */





/**
 * NAME: ix_cc_ipv4_async_set_flags
 *
 * DESCRIPTION:This primitive helps client to update flags for a given next hop.
 * Before calling this message helper, client needs to call ix_cc_ipv4_async_add_next_hop to add next hop 
 * identifier in RTM database. The supported flags are defined by IPv4 Forwarder microblock.
 * 
 * @Param:  - IN arg_NextHopId: identifier of next hop.
 * @Param:  - IN arg_Flags: new flags[BLDBLK] for the given next hop 
 * @Param:  - IN arg_pUserContext: pointer to client defined context
 *
 * @Param:  - OUT - none
 * 
 * @Return: IX_SUCCESS if successful or a valid error token for failure.
 *
 * Error Codes:
 *
 * IX_CC_ERROR_NULL - invalid pointer
 * IX_CC_IPV4_ERROR_MSG_LIBRARY- failure from Message Support Library 
 * IX_CC_IPV4_ERROR_INVALID_FLAGS - invalid flags
 */

ix_error ix_cc_ipv4_async_set_flags(ix_cc_rtmv4_nhid arg_NextHopId,
                                    ix_uint32 arg_Flags,
                                    ix_cc_ipv4_cb_route_op arg_Callback,
                                    void* arg_pUserContext
                                   )
{
    ix_cc_ipv4_general_callback_data *cbContext;
    ix_cc_ipv4_set_flags_data flagsData;
    ix_error err = IX_SUCCESS;
    

    if(arg_Callback == NULL)
    {
        return IX_ERROR_WARNING(IX_CC_ERROR_NULL,
                                ("Invalid pointer: arg_pCallback "));
    }/* end if(arg_Callback == NULL)  */

    cbContext = (ix_cc_ipv4_general_callback_data*) ix_ossl_malloc(sizeof(ix_cc_ipv4_general_callback_data));    
    if(cbContext == NULL)
    {
        return IX_ERROR_WARNING(IX_CC_ERROR_OOM,("No memory for context"));
    }/* end if no memory for context */

    if((arg_Flags !=IPV4_NH_FLAGS_LOCAL_BIT) &&
      (arg_Flags !=IPV4_NH_FLAGS_DOWN_BIT) &&
      (arg_Flags !=IPV4_NH_FLAGS_DROP_BIT) &&
      (arg_Flags !=IPV4_NH_FLAGS_BROADCAST_BIT) &&
      (arg_Flags !=IPV4_NH_FLAGS_MULTICAST_BIT))
    {
        return IX_ERROR_WARNING(IX_CC_IPV4_ERROR_INVALID_FLAGS,
                                    ("Invalid flags "));
    }/* end if flag bit */

    cbContext->pUserCallback = arg_Callback;   
    cbContext->pUserContext = arg_pUserContext;

    flagsData.nextHopId = arg_NextHopId;
    flagsData.flags = arg_Flags;

    IX_ERROR_CGT(ix_cc_msup_send_async_msg(IX_CC_IPV4_MSG_INPUT,
                                           _ix_cc_ipv4_cb_general,
                                           (void *)cbContext,
                                           IX_CC_IPV4_MSG_SET_FLAGS,
                                           (void*)&flagsData,
                                           sizeof(ix_cc_ipv4_set_flags_data)),
                 err,
                 IX_CC_IPV4_ERROR_MSG_LIBRARY,
                 IX_ERROR_LEVEL_WARNING, cleanup_context);
   
    return IX_SUCCESS;

cleanup_context:
    if(cbContext != NULL)
    {
        ix_ossl_free(cbContext);
    }/* end if cbContext != NULL */
    return err;

} /* end ix_cc_ipv4_async_set_flags */



/**
 * NAME: ix_cc_ipv4_async_get_sleep_time
 *
 * DESCRIPTION:This message helper primitive helps client to retrieve the number of seconds 
 * between when the event will fire causing the ICMP messages to dequeue and send. 
 * 
 * @Param:  - IN arg_Callback: pointer to client provided callback function.
 * @Param:  - IN arg_pUserContext: pointer to client defined context.
 *
 * @Param:  - OUT - none
 * 
 * @Return: IX_SUCCESS if successful or a valid error token for failure.
 *
 * Error Codes:
 *
 * IX_CC_ERROR_NULL - invalid pointer
 * IX_CC_IPV4_ERROR_MSG_LIBRARY- failure from Message Support Library 
 * 
 */

ix_error ix_cc_ipv4_async_get_sleep_time(ix_cc_ipv4_cb_get_sleep_time arg_Callback,
                                         void* arg_pUserContext
                                        )
{
    ix_cc_ipv4_icmp_callback_data *cbContext;
    ix_error err = IX_SUCCESS;
    

    if(arg_Callback == NULL)
    {
        return IX_ERROR_WARNING(IX_CC_ERROR_NULL,
                                ("Invalid pointer: arg_pCallback "));
    }/* end if(arg_Callback == NULL)  */
    cbContext = (ix_cc_ipv4_icmp_callback_data*) ix_ossl_malloc(sizeof(ix_cc_ipv4_icmp_callback_data));    
    if(cbContext == NULL)
    {
        return IX_ERROR_WARNING(IX_CC_ERROR_OOM,("No memory for context"));
    }/* end if no memory for context */


    cbContext->pUserCallback = arg_Callback;   
    cbContext->pUserContext = arg_pUserContext;

    IX_ERROR_CGT(ix_cc_msup_send_async_msg(IX_CC_IPV4_MSG_INPUT,
                                    _ix_cc_ipv4_cb_icmp,
                                    (void *)cbContext,
                                    IX_CC_IPV4_MSG_GET_SLEEP_TIME,
                                    NULL,
                                    0),
                 err,
                 IX_CC_IPV4_ERROR_MSG_LIBRARY,
                 IX_ERROR_LEVEL_WARNING, cleanup_context);
   
    return IX_SUCCESS;

cleanup_context:
    if(cbContext != NULL)
    {
        ix_ossl_free(cbContext);
    }/* end if cbContext != NULL */
    return err;

} /* end ix_cc_ipv4_async_get_sleep_time  */



/**
 * NAME: ix_cc_ipv4_async_set_sleep_time
 *
 * DESCRIPTION: This message helper primitive helps client to set the number of seconds between 
 * when the event will fire causing the ICMP messages to dequeue and send.  The lower the value of arg_SleepTime, 
 * the more frequent the ICMP messages will be dequeued and sent.
 * 
 * @Param:  - IN arg_SleepTime: minimum value is 1 second and maximum value is 32 seconds.
 *
 * @Param:  - OUT - none
 * 
 * @Return: IX_SUCCESS if successful or a valid error token for failure.
 *
 * Error Codes:
 *
 * IX_CC_IPV4_ERROR_INVALID_SLEEP_TIME - invalid sleep time
 * IX_CC_IPV4_ERROR_MSG_LIBRARY- failure from Message Support Library 
 * 
 */

ix_error ix_cc_ipv4_async_set_sleep_time(ix_uint16 arg_SleepTime)
{

    if((arg_SleepTime < IX_CC_IPV4_ICMP_MIN_SLEEP_TIME) ||
      (arg_SleepTime > IX_CC_IPV4_ICMP_MAX_SLEEP_TIME))
    {
        return IX_ERROR_WARNING(IX_CC_IPV4_ERROR_INVALID_SLEEP_TIME,
                                ("Invalid value: arg_SleepTime "));
    }/* end if(arg_Callback == NULL)  */


    IX_ERROR_CRT(ix_cc_msup_send_msg(IX_CC_IPV4_MSG_INPUT,
                              IX_CC_IPV4_MSG_SET_SLEEP_TIME,
                              (void*)&arg_SleepTime,
                              sizeof(ix_uint16)),
                 IX_CC_IPV4_ERROR_MSG_LIBRARY,
                 IX_ERROR_LEVEL_WARNING);

    return IX_SUCCESS;

} /* end ix_cc_ipv4_async_set_sleep_time */






/**
 * NAME: ix_cc_ipv4_async_get_queue_depth
 *
 * DESCRIPTION:This message helper primitive helps client to retrieves the depth of the ICMP error message queue. 
 * Client retrieves the maximum number of ICMP messages that can fit in the queue, not the number of messages
 * currently in the queue.
 * 
 * @Param:  - IN arg_Callback: pointer to client provided callback function.
 * @Param:  - IN arg_pUserContext: pointer to client defined context.
 *
 * @Param:  - OUT
 * 
 * @Return: IX_SUCCESS if successful or a valid error token for failure.
 *
 * Error Codes:
 *
 * IX_CC_ERROR_NULL - invalid pointer
 * IX_CC_IPV4_ERROR_MSG_LIBRARY- failure from Message Support Library 
 * 
 */

ix_error ix_cc_ipv4_async_get_queue_depth(ix_cc_ipv4_cb_get_queue_depth arg_Callback,
                                          void* arg_pUserContext
                                         )
{
    ix_cc_ipv4_icmp_callback_data *cbContext;
    ix_error err = IX_SUCCESS;

    if(arg_Callback == NULL)
    {
        return IX_ERROR_WARNING(IX_CC_ERROR_NULL,
                               ("Invalid pointer: arg_Callback "));
    }/* end if(arg_Callback == NULL)  */
    cbContext = (ix_cc_ipv4_icmp_callback_data*) ix_ossl_malloc(sizeof(ix_cc_ipv4_icmp_callback_data));    
    if(cbContext == NULL)
    {
        return IX_ERROR_WARNING(IX_CC_ERROR_OOM,("No memory for context"));
    }/* end if no memory for context */


    cbContext->pUserCallback = arg_Callback;   
    cbContext->pUserContext = arg_pUserContext;

    IX_ERROR_CGT(ix_cc_msup_send_async_msg(IX_CC_IPV4_MSG_INPUT,
                                    _ix_cc_ipv4_cb_icmp,
                                    (void *)cbContext,
                                    IX_CC_IPV4_MSG_GET_QUEUE_DEPTH,
                                    NULL,
                                    0),
                  err,
                  IX_CC_IPV4_ERROR_MSG_LIBRARY,
                  IX_ERROR_LEVEL_WARNING, cleanup_context);
   
    return IX_SUCCESS;

cleanup_context:
    if(cbContext != NULL)
    {
        ix_ossl_free(cbContext);
    }/* end if cbContext != NULL */
    return err;

} /* end ix_cc_ipv4_async_get_queue_depth  */



/**
 * NAME: ix_cc_ipv4_async_get_packets_to_drain
 *
 * DESCRIPTION:This message helper primitive helps client to retrieve the maximum number of ICMP error messages 
 * to send each time the queue processing event fires. The processing event will send up to this many ICMP error
 * packets from the queue before going back to sleep. 
 * 
 * @Param:  - IN arg_Callback: pointer to client provided callback function.
 * @Param:  - IN arg_pUserContext: pointer to client defined context.
 *
 * @Param:  - OUT none
 * 
 * @Return: IX_SUCCESS if successful or a valid error token for failure.
 *
 * Error Codes:
 *
 * IX_CC_ERROR_NULL - invalid pointer
 * IX_CC_IPV4_ERROR_MSG_LIBRARY- failure from Message Support Library 
 * 
 */

ix_error ix_cc_ipv4_async_get_packets_to_drain(ix_cc_ipv4_cb_get_packets_to_drain arg_Callback,
                                               void* arg_pUserContext
                                              )
{
    ix_cc_ipv4_icmp_callback_data *cbContext;
    ix_error err = IX_SUCCESS;
    

    if(arg_Callback == NULL)
    {
        return IX_ERROR_WARNING(IX_CC_ERROR_NULL,
                                ("Invalid pointer: arg_pCallback "));
    }/* end if(arg_Callback == NULL)  */

    cbContext = (ix_cc_ipv4_icmp_callback_data*) ix_ossl_malloc(sizeof(ix_cc_ipv4_icmp_callback_data));    
    if(cbContext == NULL)
    {
        return IX_ERROR_WARNING(IX_CC_ERROR_OOM,("No memory for context"));
    }/* end if no memory for context */

    cbContext->pUserCallback = arg_Callback;   
    cbContext->pUserContext = arg_pUserContext;

    IX_ERROR_CGT(ix_cc_msup_send_async_msg(IX_CC_IPV4_MSG_INPUT,
                                    _ix_cc_ipv4_cb_icmp,
                                    (void *)cbContext,
                                    IX_CC_IPV4_MSG_GET_PACKETS_TO_DRAIN,
                                    NULL,
                                    0),
                 err,
                 IX_CC_IPV4_ERROR_MSG_LIBRARY,
                 IX_ERROR_LEVEL_WARNING, cleanup_context);
   
    return IX_SUCCESS;

cleanup_context:
    if(cbContext != NULL)
    {
        ix_ossl_free(cbContext);
    }/* end if cbContext != NULL */
    return err;

} /* end ix_cc_ipv4_async_get_packets_to_drain  */




/**
 * NAME: ix_cc_ipv4_async_set_packets_to_drain
 *
 * DESCRIPTION:This message helper primitive helps client to set the maximum number of ICMP error messages to 
 * send each time the queue processing event fires. The value to arg_PacketsToDrain must not exceed the depth of 
 * the queue.
 * 
 * @Param:  - IN arg_PacketsToDrain: The maximum number of packets to send each time the queue processing event fires.
 *
 * @Param:  - OUT
 * 
 * @Return: IX_SUCCESS if successful or a valid error token for failure.
 *
 * Error Codes:
 *
 * IX_CC_IPV4_ERROR_INVALID_PACKETS_TO_DRAIN - invalid value for packets to drain
 * IX_CC_IPV4_ERROR_MSG_LIBRARY- failure from Message Support Library 
 * 
 */

ix_error ix_cc_ipv4_async_set_packets_to_drain(ix_uint16 arg_PacketsToDrain)
{

    if(arg_PacketsToDrain > g_IcmpQueueDepth)
    {
        return IX_ERROR_WARNING(IX_CC_IPV4_ERROR_INVALID_PACKETS_TO_DRAIN,
                                   ("Invalid value: arg_PacketsToDrain"));
    }/* end if(arg_Callback == NULL)  */


    IX_ERROR_CRT(ix_cc_msup_send_msg(IX_CC_IPV4_MSG_INPUT,
                              IX_CC_IPV4_MSG_SET_PACKETS_TO_DRAIN,
                              (void*)&arg_PacketsToDrain,
                              sizeof(ix_uint16)),
                  IX_CC_IPV4_ERROR_MSG_LIBRARY,
                  IX_ERROR_LEVEL_WARNING);

    return IX_SUCCESS;

} /* end ix_cc_ipv4_async_set_packets_to_drain */





/**
 * NAME: ix_cc_ipv4_async_get_statistics
 *
 * DESCRIPTION:This message helper primitive helps client to retrieve statistics report from IPv4 Forwarder core component.
 * This primitive will give the statistics from IPv4 microblock, RTM and IPV4 Forwarder core component.  
 * 
 * @Param:  - IN arg_Callback: pointer to client provided callback.
 * @Param:  - IN arg_pUserContext: pointer to client defined context. 
 *
 * @Param:  - OUT none
 * 
 * @Return: IX_SUCCESS if successful or a valid error token for failure.
 *
 * Error Codes:
 *
 * IX_CC_ERROR_NULL - invalid pointer
 * IX_CC_IPV4_ERROR_MSG_LIBRARY- failure from Message Support Library 
 */

ix_error ix_cc_ipv4_async_get_statistics(ix_cc_ipv4_cb_get_statistics arg_Callback,
                                         void* arg_pUserContext
                                        )
{

    ix_cc_ipv4_statistics_callback_data *cbContext;
    ix_error err = IX_SUCCESS;
    

    if(arg_Callback == NULL)
    {
        return IX_ERROR_WARNING(IX_CC_ERROR_NULL,
                               ("Invalid pointer: arg_pCallback "));
    }/* end if(arg_Callback == NULL)  */

    cbContext = (ix_cc_ipv4_statistics_callback_data*) ix_ossl_malloc(sizeof(ix_cc_ipv4_statistics_callback_data));    
    if(cbContext == NULL)
    {
        return IX_ERROR_WARNING(IX_CC_ERROR_OOM,("No memory for context"));
    }/* end if no memory for context */

    cbContext->pUserCallback = arg_Callback;   
    cbContext->pUserContext = arg_pUserContext;

    IX_ERROR_CGT(ix_cc_msup_send_async_msg(IX_CC_IPV4_MSG_INPUT,
                                    _ix_cc_ipv4_cb_statistics,
                                    (void *)cbContext,
                                    IX_CC_IPV4_MSG_GET_STATISTICS,
                                    NULL,
                                    0),
                  err,
                  IX_CC_IPV4_ERROR_MSG_LIBRARY,
                  IX_ERROR_LEVEL_WARNING, cleanup_context);

    return IX_SUCCESS;

cleanup_context:
    if(cbContext != NULL)
    {
        ix_ossl_free(cbContext);
    }/* end if cbContext != NULL */
    return err;

} /* end ix_cc_ipv4_async_get_statistics  */


