Files
m241Neelima/components/ip_net2-6.9/ipmipha/src/ipmipha_if.c
T
2026-07-30 11:19:44 +05:30

791 lines
31 KiB
C

/*
******************************************************************************
* INTERPEAK SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmipha_if.c,v $ $Revision: 1.20.10.1 $
* $Source: /home/interpeak/CVSRoot/ipmipha/src/ipmipha_if.c,v $
* $Author: svc-cmnet $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelis@interpeak.se>
******************************************************************************
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
#include "ipmipha_config.h"
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#define IPCOM_USE_CLIB_PROTO
#include <ipcom_clib.h>
#include <ipcom_err.h>
#include <ipcom_inet.h>
#include <ipcom_ipd.h>
#include <ipcom_list.h>
#include <ipcom_hash.h>
#include <ipcom_os.h>
#include <ipcom_sock.h>
#include <ipcom_sock.h>
#include <ipcom_sock2.h>
#include <ipcom_syslog.h>
#include <ipmip.h>
#include <private/ipmip_sysvar.h>
#include <private/ipmip_timer.h>
#include <private/ipmip_dhcp.h>
#include <ipmip4.h>
#include <private/ipmip4_context.h>
#include <private/ipmip4_util.h>
#include <private/ipmip4_sysext.h>
#include <private/ipmip4_auth.h>
#include <private/ipmip4_pkt.h>
#include "ipmipha.h"
#include "ipmipha_h.h"
#include "ipmipha_attr_h.h"
#include "ipmipha_if.h"
#include "ipmipha_agent.h"
#include "ipmipha_node.h"
#include "ipmipha_route.h"
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
/*
****************************************************************************
* 9 STATIC FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipmipha_destroy_tunnel
*===========================================================================
* Description: Destroy a particular tunnel.
* Parameters: tunnel - The tunnel to destroy.
* Returns:
*/
IP_STATIC void
ipmipha_if_destroy_tunnel(Ipmipha_data_t *data,
Ipmip_proc_t *proc,
Ipmipha_iff_tunnel_t *iff)
{
/* No tunnel, don't bother */
if (iff->iff.ipmip.ifindex == 0)
return;
/* Add the policy rule */
ipmip_netlink_inX_rule(&data->ipmip4.ipmip,
proc,
IP_AF_INET,
IP_RTM_DELRULE,
data->route->inbound_table,
IPMIPHA_ROUTE_PRID(0),
iff->iff.ipmip.ifindex,
IP_NULL,
0,
IP_NULL,
0,
0,
IP_FIB_RULE_FIND_SADDR);
IPMIP_UNUSED_PARAMETER(data);
IPMIP_UNUSED_PARAMETER(proc);
}
/*
*===========================================================================
* ipmipha_if_create_tunnel
*===========================================================================
* Description: Create a specific tunnel for the provided interface
* Parameters: data - The FA configuration data structure
* iff - The interface in question.
* iname - Instance name
* num - Configuration instance num
* remote - The remote end
* identity - The identity
* tunnel_type - Kind of tunnel.
* Returns: A newly allocated tunnel instance
*
*/
IP_STATIC Ipmipha_iff_tunnel_t *
ipmipha_if_create_tunnel(Ipmipha_data_t *data,
Ipmip_proc_t *proc,
Ipmipha_iff_t *iff,
Ip_u32 ifindex,
Ip_u32 remote,
Ip_u8 identity,
Ip_u8 tunnel_type)
{
Ipmipha_iff_tunnel_t *tiff;
char ifname[IP_IFNAMSIZ + 1];
/* Create the name */
ipcom_snprintf(ifname,
sizeof(ifname),
"%s%dha%x",
ipmip_util_tunnel_to_bsdname(tunnel_type),
tunnel_type,
ifindex);
tiff = (Ipmipha_iff_tunnel_t*)ipmip4_if_alloc_tunnel(&data->ipmip4,
proc,
sizeof(*tiff),
ifname,
iff->iff.ifaddr,
data->ipmip4.pkt->s_udp_out.sin_port,
remote,
identity,
tunnel_type,
iff->reordering,
(Ipmip_if_cleanup_t )ipmipha_if_destroy_tunnel);
return tiff;
}
/*
*===========================================================================
* ipmipha_if_delete
*===========================================================================
* Description: Delete an interface
* Parameters: iff - The interface to delete.
* Returns:
*
*/
IP_STATIC void
ipmipha_if_delete(Ipmipha_data_t *data,
Ipmip_proc_t *proc,
Ipmipha_iff_t *iff)
{
/* Free the final resources */
int i;
ipmip4_auth_context_destroy(iff->security.spi_ctx);
/* Free the SPI route tables */
ipmip4_auth_spi_table_destroy(iff->security.spi_fa);
ipmip4_auth_spi_table_destroy(iff->security.spi_mn);
ipmip4_auth_spi_hash_destroy(iff->security.spi_nai);
if (iff->nai_ha)
ipcom_free(iff->nai_ha);
/**/
if (iff->security.spi_mn_lookup_order)
ipcom_free(iff->security.spi_mn_lookup_order);
/* Destroy the tunnels */
for (i = 0; i < IPMIP_TUNNELTYPE_MAX; i++)
{
if (iff->tunnels[i] != IP_NULL)
ipmip_if_free(&data->ipmip4.ipmip, proc, &iff->tunnels[i]->iff.ipmip);
}
ipmip_dhcp_rtab_destroy(iff->dhcp_rtab);
/* Destroy the nodes */
ipmipha_node_context_destroy(data, proc, iff->nodes);
/* Destroy the lock */
if (iff->if_lock)
ipmip_timer_lock_destroy(&data->ipmip4.ipmip, proc, iff->if_lock);
}
/*
*===========================================================================
* ipmipha_if_alloc
*===========================================================================
* Description: Allocate a specified interface, and verify arch specific
* data.
* Parameters: data - The FA data structure.
* ifname - The interface name.
* Returns: The interface structure if successfull; IP_NULL otherwise.
*
*/
IP_STATIC Ipmipha_iff_t *
ipmipha_if_alloc(Ipmipha_data_t *data,
Ipmip_proc_t *proc,
const char *ifname)
{
/* Allocate an interface structure */
Ipmipha_iff_t *iff = IP_NULL;
Ip_u32 ifindex;
ifindex = ipcom_if_nametoindex(ifname);
if (ifindex == 0)
{
IPMIP4_EVENT_IF(ERR, proc,
ipmip_log_event_add(&data->ipmip4.ipmip,
proc,
"Configuration failed, due to unknown interface '%s'",
ifname));
return IP_NULL;
}
/* Allocate the structure */
iff = (Ipmipha_iff_t*)ipmip4_if_alloc(&data->ipmip4,
proc,
sizeof(*iff),
ifname,
ifindex,
IPMIP_IF_TYPE_GENERIC,
IPMIPHA_IFF_IDENTITY_HA,
(Ipmip_if_cleanup_t )ipmipha_if_delete);
/* Sanity */
if (iff == IP_NULL)
return IP_NULL;
/* Return the interface structure */
return iff;
}
/*
*===========================================================================
* ipmipha_if_configure
*===========================================================================
* Description: Post creation configuration
* Parameters: data - The data
* proc - Current process
* iff - The interface we're configuring.
* conf - The configuration context.
* Returns: IP_TRUE if successful
*
*/
IP_STATIC Ip_bool
ipmipha_if_configure(Ipmipha_data_t *data,
Ipmip_proc_t *proc,
Ipmipha_iff_t *iff,
Ipmipha_conf_t *conf)
{
IPMIP_UNUSED_PARAMETER(conf);
/* If we don't have the FA address, try resolve it */
if (iff->iff.ifaddr == 0)
{
/* Store extracted address */
iff->iff.ifaddr = ipmip4_if_get_primary_address(&data->ipmip4, proc, &iff->iff);
/* Sanity */
if (iff->iff.ifaddr == IP_INADDR_NONE ||
iff->iff.ifaddr == IP_INADDR_ANY)
{
IPMIP4_EVENT_IF(ERR, proc,
ipmip_log_event_add(&data->ipmip4.ipmip,
proc,
"auto-configuring: FAIL, %s returned for interface '%s'",
ipmip_ntop_inet(proc, iff->iff.ifaddr),
iff->iff.ipmip.ifname));
return IP_FALSE;
}
/**/
IPMIP4_EVENT_IF(INFO, proc,
ipmip_log_event_add(&data->ipmip4.ipmip,
proc,
"auto-configuring: interface '%s' configured to use %s",
iff->iff.ipmip.ifname,
ipmip_ntop_inet(proc, iff->iff.ifaddr)));
}
/* Get MAC address. */
if (ipmip_if_resolve_lla(&data->ipmip4.ipmip, proc, &iff->iff.ipmip) == IP_FALSE)
{
IPMIP4_EVENT_IF(ERR, proc,
ipmip_log_event_add(&data->ipmip4.ipmip,
proc,
"Unable to retrieve link-layer address for interface '%s'",
iff->iff.ipmip.ifname));
return IP_FALSE;
}
/* Need to install the routing policy forcing traffic to the fwd table */
{
int i;
/*!!CALLED ONCE PER INTERFACE?? ADV_FD ONE PER INTERFACE?? Listen to solicitations sent to 224.0.0.1 */
if (!ipmip4_pkt_icmp_join(&data->ipmip4, proc, ip_htonl(IP_INADDR_ALLHOSTS_GROUP), iff->iff.ipmip.ifindex))
{
IPMIP4_EVENT_IF(ERR, proc,
ipmip_log_event_add(&data->ipmip4.ipmip,
proc,
"Unable to join all hosts group on interface '%s'",
iff->iff.ipmip.ifname));
return IP_FALSE;
}
/* Listen to solicitations sent to 224.0.0.2 */
if (!ipmip4_pkt_icmp_join(&data->ipmip4, proc, ip_htonl(IP_INADDR_ALLRTRS_GROUP), iff->iff.ipmip.ifindex))
{
IPMIP4_EVENT_IF(ERR, proc,
ipmip_log_event_add(&data->ipmip4.ipmip,
proc,
"Unable to join all routers group on interface '%s'",
iff->iff.ipmip.ifname));
return IP_FALSE;
}
/* Listen to solicitations sent to the Mobile-Agents multicast group 224.0.0.11 */
if (!ipmip4_pkt_icmp_join(&data->ipmip4, proc, ip_htonl(IP_INADDR_ALLMA_GROUP), iff->iff.ipmip.ifindex))
{
IPMIP4_EVENT_IF(ERR, proc,
ipmip_log_event_add(&data->ipmip4.ipmip,
proc,
"Unable to join all mobile agents group on interface '%s'",
iff->iff.ipmip.ifname));
return IP_FALSE;
}
if (iff->adv_address != ip_htonl(IP_INADDR_ALLHOSTS_GROUP) &&
iff->adv_address != ip_htonl(IP_INADDR_ALLRTRS_GROUP) &&
iff->adv_address != ip_htonl(IP_INADDR_ALLMA_GROUP) &&
IP_IN_CLASSD(iff->adv_address))
{
IPMIP4_EVENT_IF(ERR, proc,
ipmip_log_event_add(&data->ipmip4.ipmip,
proc,
"Bad advertisement group %s on interface '%s'",
ipmip_ntop_inet(proc, iff->adv_address),
iff->iff.ipmip.ifname));
return IP_FALSE;
}
/* IPIP tunnel */
for (i = 0; i < IPMIP_TUNNELTYPE_MAX; i++)
{
if (iff->tunnel.enabled[i])
{
iff->tunnels[i] = ipmipha_if_create_tunnel(data,
proc,
iff,
iff->iff.ipmip.ifindex,
IP_INADDR_ANY,
IPMIPHA_IFF_IDENTITY_HA_TUNNEL,
i);
/**/
if (iff->tunnels[i] == IP_NULL)
iff->tunnel.enabled[i] = IP_FALSE;
else
{
/* Add the policy rule */
ipmip_netlink_inX_rule(&data->ipmip4.ipmip,
proc,
IP_AF_INET,
IP_RTM_NEWRULE,
data->route->inbound_table,
IPMIPHA_ROUTE_PRID(0),
iff->tunnels[i]->iff.ipmip.ifindex,
IP_NULL,
0,
IP_NULL,
0,
0,
IP_FIB_RULE_FIND_SADDR);
}
}
}
}
return IP_TRUE;
}
/*
*===========================================================================
* ipmipha_if_output_timeout
*===========================================================================
* Description: Periodically send RtAdv.
* Parameters: iff - The interface we're sending on.
* Returns: IP_TRUE
*
*/
IP_STATIC Ip_bool
ipmipha_if_advert_output_timeout(int event,
Ipmipha_data_t *data,
Ipmip_proc_t *proc,
Ipmipha_iff_t *iff,
void *extra)
{
IPMIP_UNUSED_PARAMETER(extra);
if (event == IPMIP_TIMER_EVENT_RUN)
{
/* Output it */
if (IP_BIT_ISFALSE(data->shutdown, IPMIPHA_SHUTDOWN_ADV))
ipmipha_agent_advert_output(data, proc, iff, IP_NULL, IP_NULL);
}
else
{
/* Do nothing on cancellation */
}
return IPMIP_TIMER_RET_REINSERT;
}
/*
****************************************************************************
* 10 GLOBAL FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipmipha_if_create
*===========================================================================
* Description: Create an interface for a specified configuration.
* Parameters: data - The FA entity.
* proc - Current process.
* conf - The current configuration.
* ifname - The name of the interface.
* Returns: IP_TRUE if successful.
*
*/
IP_GLOBAL Ip_bool
ipmipha_if_create(Ipmipha_data_t *data,
Ipmip_proc_t *proc,
Ipmipha_conf_t *conf,
const char *ifname)
{
Ipmipha_iff_t *iff;
unsigned si;
int i;
/* Try create the interface in question */
if ((iff = ipmipha_if_alloc(data,proc,ifname)) == IP_NULL)
return IP_FALSE;
iff->nodes = ipmipha_node_context_alloc(data, proc);
if (iff->nodes == IP_NULL)
goto fail;
iff->dhcp_rtab = ipmip_dhcp_rtab_create(&data->ipmip4.ipmip, proc, IP_NULL);
/* Store it */
ipcom_list_insert_first(&conf->if_head, &iff->iff.ipmip.next);
/* Initialize the lock */
iff->if_lock = ipmip_timer_lock_alloc(&data->ipmip4.ipmip, proc, IP_NULL, IP_NULL);
/* Create the security context */
iff->security.spi_ctx = ipmip4_auth_context_create();
iff->security.spi_fa = ipmip4_auth_spi_table_create(iff->security.spi_ctx);
iff->security.spi_mn = ipmip4_auth_spi_table_create(iff->security.spi_ctx);
iff->security.spi_nai = ipmip4_auth_spi_hash_create(iff->security.spi_ctx);
/* Do the SPI tables */
iff->security.spi_fa_lookup_required = ipmip_sysvar_bool(ipmip_sysvar_bool(IP_FALSE, "ipmipha.fa.sa.lookup.required"), "ipmipha.if.%s.fa.sa.lookup.required", iff->iff.ipmip.ifname);
iff->security.spi_mn_lookup_required = ipmip_sysvar_bool(ipmip_sysvar_bool(IP_FALSE, "ipmipha.mn.sa.lookup.required"), "ipmipha.if.%s.mn.sa.lookup.required", iff->iff.ipmip.ifname);
/* Read SPI's */
ipmip_sysvar_foreach(proc,
(Ipmip_sysvar_foreach_t) ipmip4_sysext_foreach_spi,
iff->security.spi_ctx,
"ipmipha.if.%s.spi.*", iff->iff.ipmip.ifname);
ipmip_sysvar_foreach(proc,
(Ipmip_sysvar_foreach_t) ipmip4_sysext_foreach_spi,
iff->security.spi_ctx,
"ipmipha.spi.*");
ipmip_sysvar_foreach(proc,
(Ipmip_sysvar_foreach_t) ipmip4_sysext_foreach_spiroute,
iff->security.spi_fa,
"ipmipha.if.%s.fa.sa.address.*", iff->iff.ipmip.ifname);
ipmip_sysvar_foreach(proc,
(Ipmip_sysvar_foreach_t) ipmip4_sysext_foreach_spiroute,
iff->security.spi_fa,
"ipmipha.fa.sa.address.*");
ipmip_sysvar_foreach(proc,
(Ipmip_sysvar_foreach_t) ipmip4_sysext_foreach_spiroute,
iff->security.spi_mn,
"ipmipha.if.%s.mn.sa.address.*", iff->iff.ipmip.ifname);
ipmip_sysvar_foreach(proc,
(Ipmip_sysvar_foreach_t) ipmip4_sysext_foreach_spiroute,
iff->security.spi_mn,
"ipmipha.mn.sa.address.*");
ipmip_sysvar_foreach(proc,
(Ipmip_sysvar_foreach_t) ipmip4_sysext_foreach_spihash,
iff->security.spi_nai,
"ipmipha.if.%s.mn.sa.nai.*", iff->iff.ipmip.ifname);
ipmip_sysvar_foreach(proc,
(Ipmip_sysvar_foreach_t) ipmip4_sysext_foreach_spihash,
iff->security.spi_nai,
"ipmipha.mn.sa.nai.*");
/* Initialize ADV timeout */
IPMIP_TIMER_INIT(&iff->adv_timer);
/* Get foreign agent addresses. Reachable by foreign subnets. */
ipmip_sysvar_inet(0, &iff->iff.ifaddr, IP_NULL, "ipmipha.if.%s.homeagent", iff->iff.ipmip.ifname);
/* Backward compatibility */
iff->lifetime = (Ip_u16)ipmip_sysvar_ulong(ipmip_sysvar_ulong(ipmip_sysvar_ulong(0, "ipmipha.lifetime"), "ipmipha.reg_lifetime"), "ipmipha.if.%s.lifetime", iff->iff.ipmip.ifname);
if (iff->lifetime == 0)
iff->lifetime = 0xffff;
iff->replay_diff = ipmip_sysvar_long(ipmip_sysvar_long(ipmip_sysvar_long(0, "ipmipha.timestamp_replay_protection_max_diff"), "ipmipha.timestampreplayprotectionmaxdiff"), "ipmipha.if.%s.timestamp_replay_protection_max_diff", iff->iff.ipmip.ifname);
if ((iff->nai_ha = (Ipmip4_msgext_uhdr_t *)ipmip4_sysext_nai_ha("ipmipha.if.%s.nai.ha", iff->iff.ipmip.ifname)) == IP_NULL)
iff->nai_ha = (Ipmip4_msgext_uhdr_t *)ipmip4_sysext_nai_ha("ipmipha.nai.ha");
iff->mn_nai_require = ipmip_sysvar_bool(ipmip_sysvar_bool(IP_FALSE, "ipmipha.mn.nai.required"), "ipmipha.if.%s.mn.nai.required", iff->iff.ipmip.ifname);
/* Resolve the home netmask */
if (!ipmip_sysvar_inet(ip_htonl(0xffffff00), &iff->home_netmask, IP_NULL, "ipmipha.if.%s.homenetmask", iff->iff.ipmip.ifname))
ipmip_sysvar_inet(ip_htonl(0xffffff00), &iff->home_netmask, IP_NULL, "ipmipha.homenetmask");
if ((iff->security.spi_mn_lookup_order = ipmip_sysvar_array(ipmipha_attr_lookup, "ipmipha.if.%s.mn.sa.lookup.order", iff->iff.ipmip.ifname)) == IP_NULL)
iff->security.spi_mn_lookup_order = ipmip_sysvar_array(ipmipha_attr_lookup, "ipmipha.mn.sa.lookup.order");
if (iff->security.spi_mn_lookup_order == IP_NULL)
{
iff->security.spi_mn_lookup_order = ipcom_calloc(3, sizeof(int));
if (iff->security.spi_mn_lookup_order == IP_NULL)
{
IPMIP4_EVENT_IF(ERR, proc,
ipmip_log_event_add(&data->ipmip4.ipmip,
proc,
"Failed to allocate memory required for lookup order structure",
iff->iff.ipmip.ifname));
goto fail;
}
/**/
iff->security.spi_mn_lookup_order[0] = IPMIPHA_SPI_MN_HOA;
iff->security.spi_mn_lookup_order[1] = IPMIPHA_SPI_MN_NAI;
iff->security.spi_mn_lookup_order[2] = IPMIPHA_SPI_MN_NONE;
}
/* Get ADV lifetime */
iff->adv_lifetime = (Ip_u16)ipmip_sysvar_ulong(ipmip_sysvar_ulong(50, "ipmipha.adv_lifetime"), "ipmipha.if.%s.adv_lifetime", iff->iff.ipmip.ifname);
/* Get ADV interval */
iff->adv_interval = ipmip_sysvar_long(ipmip_sysvar_long(10, "ipmipha.adv_interval"), "ipmipha.if.%s.adv_interval", iff->iff.ipmip.ifname);
/* Get ADV address */
if (!ipmip_sysvar_inet(ip_htonl(IP_INADDR_ALLMA_GROUP), &iff->adv_address, IP_NULL, "ipmipha.if.%s.adv_address", iff->iff.ipmip.ifname))
ipmip_sysvar_inet(ip_htonl(IP_INADDR_ALLMA_GROUP), &iff->adv_address, IP_NULL, "ipmipha.adv_address");
if (iff->adv_address == 0)
{
IPMIP4_EVENT_IF(ERR, proc,
ipmip_log_event_add(&data->ipmip4.ipmip,
proc,
"Bad advertisement group %s on interface '%s'",
ipmip_ntop_inet(proc, iff->adv_address),
iff->iff.ipmip.ifname));
goto fail;
}
/* NAT-T configuration */
iff->nat_t = ipmip_sysvar_bool(ipmip_sysvar_bool(IP_TRUE, "ipmipha.nat_t.enabled"), "ipmipha.if.%s.nat_t.enabled", iff->iff.ipmip.ifname);
iff->nat_t_keepalive = (Ip_u16)ipmip_sysvar_ulong(ipmip_sysvar_ulong(0, "ipmipha.nat_t.keepalive"), "ipmipha.if.%s.nat_t.keepalive", iff->iff.ipmip.ifname);
/* Do we require foreign agent authentication */
iff->fa_auth = ipmip_sysvar_bool(ipmip_sysvar_bool(IP_FALSE, "ipmipha.fa_auth"), "ipmipha.if.%s.fa_auth", iff->iff.ipmip.ifname);
/* Do we require foreign agent authentication */
iff->reordering = ipmip_sysvar_bool(ipmip_sysvar_bool(IP_FALSE, "ipmipha.tunnel.reordering"), "ipmipha.if.%s.tunnel.reordering", iff->iff.ipmip.ifname);
/* Reverse tunneling state? */
iff->tunnel.reverse = ipmip_sysvar_mode(ipmip_sysvar_mode(IPMIP_SYSVAR_MODE_OPTIONAL, "ipmipha.tunnel.reverse"), "ipmipha.if.%s.tunnel.reverse", iff->iff.ipmip.ifname);
/**/
iff->tunnel.enabled[IPMIP_TUNNELTYPE_NONE] = IP_TRUE;
/* IPIP allowed */
iff->tunnel.enabled[IPMIP_TUNNELTYPE_IPIP] = ipmip_sysvar_bool(ipmip_sysvar_bool(IP_TRUE, "ipmipha.tunnel.ipip"), "ipmipha.if.%s.tunnel.ipip", iff->iff.ipmip.ifname);
/* GRE allowed? */
iff->tunnel.enabled[IPMIP_TUNNELTYPE_GRE] = ipmip_sysvar_bool(ipmip_sysvar_bool(IP_TRUE, "ipmipha.tunnel.gre"), "ipmipha.if.%s.tunnel.gre", iff->iff.ipmip.ifname);
/* MINENC allowed? */
iff->tunnel.enabled[IPMIP_TUNNELTYPE_MINENC] = ipmip_sysvar_bool(ipmip_sysvar_bool(IP_TRUE, "ipmipha.tunnel.minenc"), "ipmipha.if.%s.tunnel.minenc", iff->iff.ipmip.ifname);
/* Simultaneous bindings */
iff->simbind_enabled = ipmip_sysvar_bool(ipmip_sysvar_bool(IP_TRUE, "ipmipha.simbind.enable"), "ipmipha.if.%s.simbind.enable", iff->iff.ipmip.ifname);
iff->simbind_max = ipmip_sysvar_ulong(ipmip_sysvar_ulong(3, "ipmipha.simbind.max"), "ipmipha.if.%s.simbind.max", iff->iff.ipmip.ifname);
iff->revocation = ipmip_sysvar_bool(ipmip_sysvar_bool(IP_TRUE, "ipmipha.revocation.enabled"), "ipmipha.if.%s.revocation.enabled", iff->iff.ipmip.ifname);
iff->revocation_inform = ipmip_sysvar_mode(ipmip_sysvar_mode(IPMIP_SYSVAR_MODE_OPTIONAL, "ipmipha.revocation.inform"), "ipmipha.if.%s.revocation.inform", iff->iff.ipmip.ifname);
if (!ipmipha_if_configure(data, proc, iff, conf))
goto fail;
iff->ha_subbrd = iff->iff.ifaddr | ~iff->home_netmask;
iff->ha_netbrd = iff->iff.ifaddr | ~IP_NETMASK(iff->iff.ifaddr);
/* Do the external parsing */
/* Do the external parsing */
for (i = IPMIPHA_FUNCTION_MAX - 1; i >= 0; i--)
{
for (si = 0; si < data->extensions[i].num; si++)
{
if (data->extensions[i].functions[si]->config_ifp != IP_NULL)
{
if (data->extensions[i].functions[si]->ifp_data_size)
{
iff->extdata[i][si] = ipcom_calloc(1, data->extensions[i].functions[si]->ifp_data_size);
(*data->extensions[i].functions[si]->config_ifp) (data, proc, IPMIP_CALLBACK_CONFIG_READ, iff, conf->extdata[i][si], iff->extdata[i][si], IP_NULL);
}
}
}
}
return IP_TRUE;
fail:
ipmip_if_free(&data->ipmip4.ipmip, proc, &iff->iff.ipmip);
return IP_FALSE;
}
/*
*===========================================================================
* ipmipha_if_start
*===========================================================================
* Description: Start interfaces for a specified configuration.
* Parameters: data - The FA entity.
* proc - Current process.
* Returns:
*
*/
IP_GLOBAL void
ipmipha_if_start(Ipmipha_data_t *data,
Ipmip_proc_t *proc)
{
Ipmipha_iff_t *iff;
if (data->conf == IP_NULL)
return;
/* free interface list */
for (iff = IPCOM_LIST_FIRST(&data->conf->if_head); iff != IP_NULL; iff = IPCOM_LIST_NEXT(&iff->iff.ipmip.next))
{
/* Is it activated? */
if (iff->adv_interval > 0)
{
ipmip_timer_request(&data->ipmip4.ipmip,
proc,
&iff->adv_timer,
iff->if_lock,
(Ipmip_timer_func_t)ipmipha_if_advert_output_timeout,
iff,
IP_NULL,
iff->adv_interval * 1000);
}
}
}
/*
*===========================================================================
* ipmipfa_if_start
*===========================================================================
* Description: Start an interface for a specified configuration.
* Parameters: data - The FA entity.
* proc - Current process.
* Returns:
*
*/
IP_GLOBAL void
ipmipha_if_stop(Ipmipha_data_t *data,
Ipmip_proc_t *proc,
Ipmipha_conf_t *conf)
{
Ipmipha_iff_t *iff;
/* Send instant RtAdv on all active interfaces */
while (IP_NULL != (iff = IPCOM_LIST_FIRST(&conf->if_head)))
{
int i;
unsigned si;
for (i = IPMIPHA_FUNCTION_MAX - 1; i >= 0; i--)
{
for (si = 0; si < data->extensions[i].num; si++)
{
if (data->extensions[i].functions[si]->config_ifp != IP_NULL)
{
if (iff->extdata[i][si])
{
(*data->extensions[i].functions[si]->config_ifp) (data, proc, IPMIP_CALLBACK_CONFIG_FREE, iff, conf->extdata[i][si], iff->extdata[i][si], IP_NULL);
ipcom_free(iff->extdata[i][si]);
iff->extdata[i][si] = IP_NULL;
}
}
}
}
ipmip_if_free(&data->ipmip4.ipmip, proc, &iff->iff.ipmip);
}
}
/*
****************************************************************************
* 11 PUBLIC FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/