751 lines
23 KiB
C
751 lines
23 KiB
C
/*
|
|
*******************************************************************************
|
|
* INTERPEAK SOURCE FILE
|
|
*
|
|
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmipfa_main.c,v $ $Revision: 1.8.16.1 $
|
|
* $Source: /home/interpeak/CVSRoot/ipmipfa/src/ipmipfa_main.c,v $
|
|
* $Author: jsheng $
|
|
* $State: Exp $ $Locker: $
|
|
*
|
|
* INTERPEAK_COPYRIGHT_STRING
|
|
* Design and implementation by Niklas Lundberg <n@interpeak.se>
|
|
******************************************************************************
|
|
*/
|
|
|
|
|
|
/*
|
|
*******************************************************************************
|
|
* 1 DESCRIPTION
|
|
*******************************************************************************
|
|
*
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 2 CONFIGURATION
|
|
****************************************************************************
|
|
*/
|
|
|
|
|
|
#include "ipmipfa_config.h"
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 3 INCLUDE FILES
|
|
****************************************************************************
|
|
*/
|
|
|
|
#define IPCOM_USE_CLIB_PROTO
|
|
#include <ipcom_clib.h>
|
|
#include <ipcom_drv_eth_filter.h>
|
|
#include <ipcom_err.h>
|
|
#include <ipcom_hash.h>
|
|
#include <ipcom_inet.h>
|
|
#include <ipcom_ipd.h>
|
|
#include <ipcom_list.h>
|
|
#include <ipcom_os.h>
|
|
#include <ipcom_sock.h>
|
|
#include <ipcom_sock2.h>
|
|
#include <ipcom_sysctl.h>
|
|
#include <ipcom_syslog.h>
|
|
#include <ipcom_netif.h>
|
|
#include <ipcom_sysvar.h>
|
|
|
|
#include <ipmip.h>
|
|
#include <private/ipmip_cli.h>
|
|
#include <private/ipmip_sysvar.h>
|
|
#include <private/ipmip_dhcp.h>
|
|
|
|
#include <ipmip4.h>
|
|
#include <private/ipmip4_sysext.h>
|
|
#include <private/ipmip4_util.h>
|
|
#include <private/ipmip4_pkt.h>
|
|
#include <private/ipmip4_radius.h>
|
|
|
|
#include "ipmipfa.h"
|
|
#include "ipmipfa_h.h"
|
|
#include "ipmipfa_reg.h"
|
|
#include "ipmipfa_node.h"
|
|
#include "ipmipfa_agent.h"
|
|
#include "ipmipfa_attr_h.h"
|
|
#include "ipmipfa_route.h"
|
|
#include "ipmipfa_pktbuf.h"
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 4 DEFINES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 5 TYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* Application datatypes
|
|
*===========================================================================
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 6 EXTERN PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
IP_PUBLIC Ip_err ipmipfa_configure(void);
|
|
IP_PUBLIC Ip_err ipmipfa_init(void);
|
|
IP_PUBLIC Ip_err ipmipfa_exit(void);
|
|
|
|
#ifdef IPSNMP
|
|
IP_EXTERN Ip_err ipmipfa_mip_mib_init(void);
|
|
IP_EXTERN Ip_err ipmip4_mip_mib_init(void);
|
|
#endif
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 7 LOCAL PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
IP_PUBLIC Ip_err ipmipfa_start(void);
|
|
IP_PUBLIC const char *ipmipfa_version(void);
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 8 DATA
|
|
****************************************************************************
|
|
*/
|
|
|
|
static int ipmipfa_instances = 0;
|
|
static Ipcom_once_t ipmipfa_extensions_once = IPCOM_ONCE_INIT;
|
|
static Ipmipfa_function_context_t ipmipfa_extensions[IPMIPFA_FUNCTION_MAX];
|
|
static Ip_u32 ipmipfa_extensions_node_data = 0;
|
|
static Ipcom_list ipmipfa_msgext_vendor_extensions;
|
|
static Ipmip_pktbuf_pktaux_t ipmipfa_pktaux;
|
|
/*
|
|
****************************************************************************
|
|
* 9 STATIC FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
IP_STATIC Ip_err
|
|
ipmipfa_main_once_init(void *unused)
|
|
{
|
|
int f;
|
|
|
|
IPMIP_UNUSED_PARAMETER(unused);
|
|
|
|
/* Clear */
|
|
ipcom_memset(&ipmipfa_extensions[0], 0, sizeof(ipmipfa_extensions));
|
|
ipcom_memset(&ipmipfa_pktaux, 0, sizeof(ipmipfa_pktaux));
|
|
ipcom_list_init(&ipmipfa_msgext_vendor_extensions);
|
|
|
|
/* Do service init */
|
|
for (f = 0; ipmipfa_function_registrations[f] != IP_NULL; f++)
|
|
(*ipmipfa_function_registrations[f]) ();
|
|
|
|
return IPCOM_SUCCESS;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipmipfa_exit_agent
|
|
*===========================================================================
|
|
* Description: Cleanup the resources allocated by this FA entity.
|
|
* Parameters: data - The FA entity structure.
|
|
* proc - Current process
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC void
|
|
ipmipfa_exit_agent(Ipmipfa_data_t *data,
|
|
Ipmip_proc_t *proc)
|
|
{
|
|
/* Sanity */
|
|
if (data == IP_NULL)
|
|
return;
|
|
|
|
IPMIP4_EVENT_IF(INFO, proc,
|
|
ipmip_log_event_add(&data->ipmip4.ipmip,
|
|
proc,
|
|
"IPMIPFA ending"));
|
|
/* Stop the context */
|
|
ipmip4_context_stop(&data->ipmip4, proc);
|
|
|
|
/* Destroy route context */
|
|
ipmipfa_route_context_destroy(data, proc);
|
|
|
|
/**/
|
|
ipmip_timer_lock_destroy(&data->ipmip4.ipmip, proc, data->llh_lock);
|
|
|
|
/* Exit the IPD */
|
|
if (data->fd_ipd == IP_INVALID_SOCKET)
|
|
(void)ipcom_ipd_init("ipmipfa", IPCOM_ERR_FAILED, &data->fd_ipd);
|
|
|
|
(void)ipcom_ipd_exit("ipmipfa", data->fd_ipd);
|
|
|
|
/**/
|
|
ipcom_mutex_delete(&data->mibLock);
|
|
|
|
/**/
|
|
ipmip_context_id_destroy(data->idents);
|
|
|
|
/* Free the context */
|
|
ipmip4_context_destroy(&data->ipmip4, proc);
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipmipfa_init_agent
|
|
*===========================================================================
|
|
* Description: Allocate and initialize a FA entity structure.
|
|
* Parameters: proc - Current process
|
|
* Returns: The new FA entity structure if successful.
|
|
*
|
|
*/
|
|
IP_STATIC Ipmipfa_data_t *
|
|
ipmipfa_init_agent(Ipmip_proc_t *proc)
|
|
{
|
|
Ipmipfa_data_t *data;
|
|
|
|
(void)IPMIP_ONCE(&ipmipfa_extensions_once, ipmipfa_main_once_init, IP_NULL);
|
|
|
|
data = (Ipmipfa_data_t *) ipmip_context_alloc(proc, sizeof(*data), "ipmipfa", IPMIP4_SYSTEM_PRIORITY, IPMIPFA_EVENT_BACKLOG);
|
|
if (data == IP_NULL)
|
|
return IP_NULL;
|
|
|
|
/* Setup the extension structure */
|
|
data->extensions = &ipmipfa_extensions[0];
|
|
data->extensions_node_data = &ipmipfa_extensions_node_data;
|
|
data->ipmip4.vendor_extensions = &ipmipfa_msgext_vendor_extensions;
|
|
data->ipmip4.ipmip.pktaux = &ipmipfa_pktaux;
|
|
|
|
ipmip4_context_init(&data->ipmip4, proc);
|
|
|
|
/* Initialize file descriptors */
|
|
data->fd_ipd = IP_INVALID_SOCKET;
|
|
|
|
IPMIP4_EVENT_IF(INFO, proc,
|
|
ipmip_log_event_add(&data->ipmip4.ipmip,
|
|
proc,
|
|
"IPMIPFA starting [VR %d]", data->ipmip4.ipmip.vr));
|
|
|
|
data->llh_lock = ipmip_timer_lock_alloc(&data->ipmip4.ipmip, proc, IP_NULL, IP_NULL);
|
|
if(IP_NULL == data->llh_lock)
|
|
goto fail;
|
|
|
|
(void)ipcom_mutex_create(&data->mibLock);
|
|
|
|
/* IPD init. */
|
|
if (ipcom_ipd_init("ipmipfa", IPCOM_SUCCESS, &data->fd_ipd) != IPCOM_SUCCESS)
|
|
goto fail;
|
|
|
|
data->idents = ipmip_context_id_create(ip_offsetof(Ipmipfa_node_t, faVisitorIdentity), 0xFFFFFFFF);
|
|
|
|
/* Initialize the parse structure */
|
|
ipmip_cli_context_create(&data->ipmip4.ipmip,
|
|
proc,
|
|
"ipmipfa",
|
|
IPCOM_IPD_ID_IPMIPFA,
|
|
(Ipmip_cli_callback_t)ipmipfa_attr_command);
|
|
|
|
/* Create the packet buffer context */
|
|
ipmip_pktbuf_context_create(&data->ipmip4.ipmip,
|
|
proc,
|
|
(Ipmip_pkt_buf_alloc_t)ipmipfa_pktbuf_alloc,
|
|
(Ipmip_pkt_buf_free_t)ipmipfa_pktbuf_free);
|
|
|
|
ipmip4_pkt_context_create(&data->ipmip4,
|
|
proc,
|
|
IPMIP4_PKT_UDP_IN_434|IPMIP4_PKT_UDP_IN_OUT|IPMIP4_PKT_PKT_OUT|IPMIP4_PKT_ICMP_IN,
|
|
(Ipmip4_pkt_udp_cb_t)ipmipfa_reg_recv,
|
|
(Ipmip4_pkt_icmp_cb_t)ipmipfa_adv_recv,
|
|
IP_NULL);
|
|
|
|
ipmipfa_route_context_alloc(data, proc);
|
|
|
|
|
|
return data;
|
|
|
|
fail:
|
|
ipmipfa_exit_agent(data, proc);
|
|
return IP_NULL;
|
|
}
|
|
|
|
|
|
IP_STATIC void
|
|
ipmipfa_services_clear(Ipmipfa_data_t *ctx,
|
|
Ipmip_proc_t *proc,
|
|
Ipmipfa_conf_t *conf)
|
|
{
|
|
unsigned si, f;
|
|
|
|
for (f = 0; f < IPMIPFA_FUNCTION_MAX; f++)
|
|
{
|
|
for (si = 0; si < ctx->extensions[f].num; si++)
|
|
{
|
|
if (ctx->extensions[f].functions[si]->config_global != IP_NULL && conf->extdata[f][si])
|
|
{
|
|
(*ctx->extensions[f].functions[si]->config_global) (ctx, proc, IPMIP_CALLBACK_CONFIG_FREE, conf->extdata[f][si], IP_NULL);
|
|
ipcom_free(conf->extdata[f][si]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
IP_STATIC void
|
|
ipmipfa_services_read(Ipmipfa_data_t *ctx,
|
|
Ipmip_proc_t *proc,
|
|
Ipmipfa_conf_t *conf)
|
|
{
|
|
unsigned si, f;
|
|
|
|
for (f = 0; f < IPMIPFA_FUNCTION_MAX; f++)
|
|
{
|
|
for (si = 0; si < ctx->extensions[f].num; si++)
|
|
{
|
|
if (ctx->extensions[f].functions[si]->config_global != IP_NULL && ctx->extensions[f].functions[si]->global_data_size)
|
|
{
|
|
conf->extdata[f][si] = ipcom_calloc(1, ctx->extensions[f].functions[si]->global_data_size);;
|
|
(*ctx->extensions[f].functions[si]->config_global) (ctx, proc, IPMIP_CALLBACK_CONFIG_READ, conf->extdata[f][si], IP_NULL);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipmipfa_config_exit
|
|
*===========================================================================
|
|
* Description: Clear out a configuration structure, free any resources
|
|
* associated with it.
|
|
* Parameters: data - The FA entity it belongs to
|
|
* proc - The process
|
|
* conf - The configuration structure.
|
|
* Returns:
|
|
*/
|
|
IP_STATIC void
|
|
ipmipfa_config_free(Ipmipfa_data_t *data,
|
|
Ipmip_proc_t *proc,
|
|
Ipmipfa_conf_t *conf)
|
|
{
|
|
/* free interface list */
|
|
ipmipfa_if_stop(data, proc, conf);
|
|
|
|
ipmipfa_services_clear(data, proc, conf);
|
|
ipcom_free(conf);
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipmipfa_config_exit
|
|
*===========================================================================
|
|
* Description: Clear out a configuration structure, free any resources
|
|
* associated with it.
|
|
* Parameters: data - The FA entity it belongs to
|
|
* proc - The process
|
|
* conf - The configuration structure.
|
|
* Returns:
|
|
*/
|
|
IP_STATIC void
|
|
ipmipfa_config_exit(Ipmipfa_data_t *data,
|
|
Ipmip_proc_t *proc)
|
|
{
|
|
Ipmipfa_iff_t *iff;
|
|
|
|
if (data->conf == IP_NULL)
|
|
return;
|
|
|
|
/* Stop the current context */
|
|
ipmip4_pkt_context_stop(&data->ipmip4, proc);
|
|
data->shutdown = IPMIPFA_SHUTDOWN_ALL;
|
|
ipmip4_pkt_context_start(&data->ipmip4, proc);
|
|
|
|
/* Free all mobile nodes */
|
|
ipmipfa_node_clear(data, proc);
|
|
|
|
/**/
|
|
ipmip4_context_stop(&data->ipmip4, proc);
|
|
|
|
/* free interface list */
|
|
for (iff = IPCOM_LIST_FIRST(&data->conf->if_head); iff != IP_NULL; iff = IPCOM_LIST_NEXT(&iff->iff.ipmip.next))
|
|
{
|
|
if (iff->adv_interval > 0 &&
|
|
iff->iff.ifaddr != 0)
|
|
{
|
|
/* Reduce lifetime to 0 */
|
|
iff->lifetime = 0;
|
|
iff->adv_lifetime = 0;
|
|
ipmipfa_agent_advert_output(data, proc, iff, IP_NULL, IP_NULL, IP_NULL, IP_FALSE);
|
|
}
|
|
}
|
|
|
|
/* Free the configuration */
|
|
ipmipfa_config_free(data, proc, data->conf);
|
|
ipmip_dhcp_context_destroy(&data->ipmip4.ipmip, proc);
|
|
data->conf = IP_NULL;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipmipfa_config_read
|
|
*===========================================================================
|
|
* Description: Read IPMIPFA config.
|
|
* used in ipmipfa_config_init
|
|
* Parameters: data - The FA entity.
|
|
* proc - Process
|
|
* Returns: The new configuration entity.
|
|
*
|
|
*/
|
|
IP_STATIC Ipmipfa_conf_t *
|
|
ipmipfa_config_read(Ipmipfa_data_t *data,
|
|
Ipmip_proc_t *proc)
|
|
{
|
|
Ipmipfa_conf_t *conf;
|
|
char **arr = IP_NULL;
|
|
|
|
conf = ipcom_calloc(1, sizeof(Ipmipfa_conf_t));
|
|
if (conf == IP_NULL)
|
|
return IP_NULL;
|
|
|
|
/* Init */
|
|
ipcom_list_init(&conf->if_head);
|
|
|
|
ipmipfa_services_read(data, proc, conf);
|
|
|
|
/* Find all interfaces */
|
|
arr = ipmip_sysvar_strarr("ipmipfa.interfaces");
|
|
if (arr == IP_NULL)
|
|
{
|
|
IPMIP4_EVENT_IF(ERR, proc,
|
|
ipmip_log_event_add(&data->ipmip4.ipmip,
|
|
proc,
|
|
"Bad configuration. Invalid/missing \"ipmipfa.interfaces\""));
|
|
goto fail;
|
|
}
|
|
else
|
|
{
|
|
int i;
|
|
for (i = 0; arr[i] != IP_NULL; i++)
|
|
{
|
|
/* If I can't create the interface, exit */
|
|
if (ipmipfa_if_create(data, proc, conf, arr[i]) == IP_FALSE)
|
|
goto fail;
|
|
}
|
|
}
|
|
/* */
|
|
ipcom_free(arr);
|
|
return conf; /* success */
|
|
|
|
fail:
|
|
if (arr != IP_NULL)
|
|
ipcom_free(arr);
|
|
ipmipfa_config_free(data, proc, conf);
|
|
return IP_NULL;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipmipfa_config_init
|
|
*===========================================================================
|
|
* Description: Setup MIP ha after config has been read.
|
|
* Parameters: data - The FA data entity.
|
|
* proc - The process
|
|
* Returns: -1 on error; 0 otherwise.
|
|
*
|
|
*/
|
|
IP_STATIC int
|
|
ipmipfa_config_init(Ipmipfa_data_t *data,
|
|
Ipmip_proc_t *proc)
|
|
{
|
|
Ipmipfa_conf_t *conf;
|
|
#ifndef IP_PORT_LAS
|
|
int name[4];
|
|
Ip_size_t oldlenp;
|
|
#endif
|
|
Ipmipfa_iff_t *iff;
|
|
|
|
/* Reconfigure (existing config was in place) */
|
|
if (data->conf)
|
|
ipmipfa_config_exit(data, proc);
|
|
|
|
/* Read configuration. */
|
|
conf = ipmipfa_config_read(data, proc);
|
|
if (conf == IP_NULL)
|
|
{
|
|
ipmip_context_start(&data->ipmip4.ipmip, proc);
|
|
return -1;
|
|
}
|
|
|
|
#ifndef IP_PORT_LAS
|
|
/* Check if we are a router */
|
|
name[0] = IP_CTL_NET;
|
|
name[1] = IP_AF_INET;
|
|
name[2] = IP_IPPROTO_IP;
|
|
name[3] = IP_IPCTL_FORWARDING;
|
|
oldlenp = sizeof(data->ipnet_is_router);
|
|
if (ipcom_sysctl(name, 4, &data->ipnet_is_router, &oldlenp, IP_NULL, IP_NULL) < 0)
|
|
data->ipnet_is_router = 0;
|
|
#endif
|
|
|
|
data->conf = conf;
|
|
|
|
data->shutdown = 0;
|
|
ipmip4_context_start(&data->ipmip4, proc);
|
|
ipmipfa_if_start(data, proc);
|
|
|
|
/* Send instant RtAdv on all active interfaces */
|
|
for (iff = IPCOM_LIST_FIRST(&data->conf->if_head); iff;
|
|
iff = IPCOM_LIST_NEXT(&iff->iff.ipmip.next))
|
|
{
|
|
/* Should I send a multicast PrRtAdv? */
|
|
if (iff->adv_interval > 0)
|
|
ipmipfa_agent_advert_output(data, proc, iff, IP_NULL, IP_NULL, IP_NULL, IP_FALSE);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipmipfa_data_process
|
|
*===========================================================================
|
|
* Description: Process any file descriptors set by the platform.
|
|
* Parameters: data - The data structure
|
|
* rset - The read set.
|
|
* Returns: IP_FALSE if we should exit the process.
|
|
*
|
|
*/
|
|
IP_STATIC Ip_bool
|
|
ipmipfa_ipd_process(Ipmipfa_data_t *data,
|
|
Ipmip_proc_t *proc)
|
|
{
|
|
/* IPD input. */
|
|
int event;
|
|
Ip_ssize_t len;
|
|
Ipmipfa_pktbuf_t *pbuf = (Ipmipfa_pktbuf_t *)ipmip_pktbuf_alloc(&data->ipmip4.ipmip, proc, 512);
|
|
|
|
if (pbuf == IP_NULL)
|
|
return IP_TRUE;
|
|
|
|
len = ipcom_ipd_read(data->fd_ipd, IPMIP_BUFFER_PTR(&pbuf->ipmip4.ipmip.packet), 512, &event);
|
|
if (len < 0)
|
|
ipmip_util_sock_clear(data->fd_ipd);
|
|
else
|
|
{
|
|
/* Advance past */
|
|
ipmip_buffer_append(&pbuf->ipmip4.ipmip.packet, IP_NULL, len);
|
|
|
|
switch (event)
|
|
{
|
|
case IPCOM_IPD_EVENT_RECONFIGURE:
|
|
IPMIP4_EVENT_IF(INFO, proc,
|
|
ipmip_log_event_add(&data->ipmip4.ipmip,
|
|
proc,
|
|
"Received IPD reconfigure message"));
|
|
if (ipmipfa_config_init(data, proc) != 0)
|
|
{
|
|
IPMIP4_EVENT_IF(ERR, proc,
|
|
ipmip_log_event_add(&data->ipmip4.ipmip,
|
|
proc,
|
|
"Invalid new configuration - reconfigure failed and process suspended. Please correct configuration"));
|
|
|
|
}
|
|
break;
|
|
|
|
case IPCOM_IPD_EVENT_KILL:
|
|
IPMIP4_EVENT_IF(INFO, proc,
|
|
ipmip_log_event_add(&data->ipmip4.ipmip,
|
|
proc,
|
|
"Received IPD kill message"));
|
|
ipmip_pktbuf_release(&data->ipmip4.ipmip, proc, &pbuf->ipmip4.ipmip);
|
|
return IP_FALSE;
|
|
|
|
default:
|
|
/* Ignore all other IPD messages */
|
|
break;
|
|
}
|
|
}
|
|
|
|
ipmip_pktbuf_release(&data->ipmip4.ipmip, proc, &pbuf->ipmip4.ipmip);
|
|
return IP_TRUE;
|
|
}
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 10 GLOBAL FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipmipfad
|
|
*===========================================================================
|
|
* Description: The main process.
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_GLOBAL void
|
|
ipmipfa_main(void)
|
|
{
|
|
char icmp_redirect[8];
|
|
Ip_size_t size = sizeof(icmp_redirect);
|
|
Ipmipfa_data_t *data = IP_NULL;
|
|
Ipmip_proc_t *proc;
|
|
|
|
ipcom_proc_init();
|
|
|
|
/* Get me a process context for this thread */
|
|
proc = ipmip_proc_alloc();
|
|
if(IP_NULL == proc)
|
|
return;
|
|
|
|
/* Init IPMIPFA */
|
|
if (ipmipfa_instances++ == 0)
|
|
(void)ipmipfa_init();
|
|
|
|
ipcom_sysvar_get("ipnet.inet.IcmpRedirectSend",
|
|
icmp_redirect,
|
|
&size);
|
|
if (ipcom_sysvar_set("ipnet.inet.IcmpRedirectSend", "0", IPCOM_SYSVAR_FLAG_OVERWRITE) != IPCOM_SUCCESS)
|
|
goto end;
|
|
|
|
/* Configure IPMIPFA. */
|
|
if (ipmipfa_configure() != IPCOM_SUCCESS)
|
|
goto end;
|
|
|
|
/* Init IPMIPFA data. */
|
|
if ((data = ipmipfa_init_agent(proc)) == IP_NULL)
|
|
goto end;
|
|
|
|
/* Init FA from configuration. */
|
|
if (ipmipfa_config_init(data, proc) != 0)
|
|
{
|
|
IPMIP4_EVENT_IF(ERR, proc,
|
|
ipmip_log_event_add(&data->ipmip4.ipmip,
|
|
proc,
|
|
"Invalid configuration - configure failed and process suspended. Please correct configuration"));
|
|
}
|
|
|
|
for (;;)
|
|
{
|
|
int num;
|
|
int max_fd;
|
|
Ip_fd_set read_set;
|
|
|
|
IP_FD_ZERO(&read_set);
|
|
|
|
/* Set the IPD */
|
|
max_fd = data->fd_ipd;
|
|
IP_FD_SET(data->fd_ipd, &read_set);
|
|
|
|
/* Select */
|
|
num = ipcom_socketselect(max_fd + 1, &read_set, IP_NULL, IP_NULL, IP_NULL);
|
|
|
|
switch(num)
|
|
{
|
|
case -1: /* socket error. */
|
|
(void)ipcom_sleep(1);
|
|
break;
|
|
|
|
case 0: /* timeout, not used. triggered by bug in linux glibc if compiled with nptl */
|
|
(void)ipcom_millisleep(1);
|
|
break;
|
|
|
|
default:
|
|
/* Process IPD */
|
|
if (IP_FD_ISSET(data->fd_ipd, &read_set))
|
|
{
|
|
if (ipmipfa_ipd_process(data, proc) == IP_FALSE)
|
|
goto end;
|
|
}
|
|
}
|
|
}
|
|
|
|
end:
|
|
/* If we've gotten the data, clear it */
|
|
if (data != IP_NULL)
|
|
{
|
|
ipmipfa_config_exit(data, proc);
|
|
ipmipfa_exit_agent(data, proc);
|
|
}
|
|
|
|
(void)ipcom_sysvar_set("ipnet.inet.IcmpRedirectSend",
|
|
icmp_redirect,
|
|
IPCOM_SYSVAR_FLAG_OVERWRITE);
|
|
|
|
/* Exit IPMIPFA */
|
|
if (--ipmipfa_instances == 0)
|
|
(void)ipmipfa_exit();
|
|
|
|
/* Free the context process */
|
|
ipmip_proc_destroy(proc);
|
|
|
|
ipcom_proc_exit();
|
|
}
|
|
|
|
/* INIT FUNCTIONS */
|
|
IP_GLOBAL Ip_u32
|
|
ipmipfa_context_register_extension(Ipmipfa_extension_t *srv,
|
|
int function)
|
|
{
|
|
Ipmipfa_function_context_t *func = &ipmipfa_extensions[function];
|
|
Ip_u32 type = func->num++;
|
|
|
|
/* Store values */
|
|
srv->type = type;
|
|
srv->func = function;
|
|
|
|
/* Create the unique identifier */
|
|
srv->unique = type;
|
|
srv->unique |= function << 16;
|
|
|
|
func->mask |= (1 << type);
|
|
ipmipfa_extensions_node_data += srv->node_data_size;
|
|
ipmipfa_extensions_node_data += sizeof(void *);
|
|
|
|
func->functions[type] = srv;
|
|
func->node_data += srv->node_data_size;
|
|
|
|
/* Register payload, if requested */
|
|
if (srv->pktaux.pktbuf_data_size != 0)
|
|
ipmip_pktbuf_pktaux_add(&ipmipfa_pktaux, &srv->pktaux);
|
|
|
|
return srv->unique;
|
|
}
|
|
|
|
IP_GLOBAL void
|
|
ipmipfa_msgext_vendor_parse_ext_register(struct Ipmip4_msgext_vendor_parse_ext *pext)
|
|
{
|
|
/**/
|
|
ipmip4_msgext_vendor_parse_ext_register(&ipmipfa_msgext_vendor_extensions, &ipmipfa_pktaux, pext);
|
|
}
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 11 PUBLIC FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* END OF FILE
|
|
****************************************************************************
|
|
*/
|