original files of m241

This commit is contained in:
neelimap
2026-07-30 11:19:44 +05:30
parent 170c2b3f3a
commit afc7070c1f
12254 changed files with 7655111 additions and 0 deletions
@@ -0,0 +1,238 @@
/*
*******************************************************************************
* INTERPEAK SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmipfa.c,v $ $Revision: 1.89 $
* $Source: /home/interpeak/CVSRoot/ipmipfa/src/ipmipfa.c,v $
* $Author: jhorteli $
* $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 <ipmip4.h>
#include <private/ipmip4_sysext.h>
#include <private/ipmip4_util.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"
/*
****************************************************************************
* 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
****************************************************************************
*/
/*
****************************************************************************
* 9 STATIC FUNCTIONS
****************************************************************************
*/
IP_PUBLIC IPCOM_PROCESS(ipmipfa_proc);
/*
*===========================================================================
* ipmipfad
*===========================================================================
* Description: The main process.
* Parameters:
* Returns:
*
*/
IP_PUBLIC
IPCOM_PROCESS(ipmipfa_proc)
{
ipmipfa_main();
}
/*
****************************************************************************
* 10 GLOBAL FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* 11 PUBLIC FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipmipfa_start
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_PUBLIC Ip_err
ipmipfa_start(void)
{
Ipcom_proc_attr attr;
Ip_err ret;
#ifdef IPSNMP
static int mib_once = 0;
#endif
ipcom_proc_attr_init(&attr);
attr.stacksize = IPCOM_PROC_STACK_LARGE;
ret = ipcom_proc_acreate("ipmipfad", ipmipfa_proc, &attr, IP_NULL);
ip_assert(ret == IPCOM_SUCCESS);
#ifdef IPSNMP
if (mib_once == 0)
{
mib_once = 1;
if (ipmip4_mip_mib_init() != IPCOM_SUCCESS)
ret = IPCOM_ERR_FAILED;
if (ipmipfa_mip_mib_init() != IPCOM_SUCCESS)
ret = IPCOM_ERR_FAILED;
}
#endif
return ret;
}
/*
*===========================================================================
* ipmipfa_version
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_PUBLIC const char *
ipmipfa_version(void)
{
return "@(#) IPMIPFA $Name: VXWORKS_ITER40_2019102207 $ - INTERPEAK_COPYRIGHT_STRING";
}
#if defined (IP_PORT_LAS)
/* Prototypes */
IP_PUBLIC Ip_err ipcom_daemon_configure(void);
IP_PUBLIC Ip_err ipcom_daemon_create(void);
IP_PUBLIC Ip_err
ipcom_daemon_configure(void)
{
return IPCOM_SUCCESS;
}
IP_PUBLIC Ip_err
ipcom_daemon_create(void)
{
return IPCOM_SUCCESS;
}
#endif
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,676 @@
/*
******************************************************************************
* INTERPEAK SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmipfa_agent.c,v $ $Revision: 1.24 $
* $Source: /home/interpeak/CVSRoot/ipmipfa/src/ipmipfa_agent.c,v $
* $Author: jhorteli $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelis@interpeak.se>
******************************************************************************
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
#include "ipmipfa_config.h"
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#define IPCOM_USE_CLIB_PROTO
#include <ipcom_clib.h>
#include <ipcom_cstyle.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_sysvar.h>
#include <ipmip4.h>
#include <private/ipmip4_pkt.h>
#include <private/ipmip4_util.h>
#include "ipmipfa.h"
#include "ipmipfa_h.h"
#include "ipmipfa_if.h"
#include "ipmipfa_agent.h"
#include "ipmipfa_reg.h"
#include "ipmipfa_node.h"
#include "ipmipfa_llh.h"
#include "ipmipfa_pktbuf.h"
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
/*
****************************************************************************
* 9 STATIC FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipmipfa_agent_advert_input
*===========================================================================
* Description: ICMP advertisement input.
* Parameters: data - The context
* proc - Current process
* pbuf - The packet buffer
* Returns:
*
*/
IP_STATIC void
ipmipfa_agent_advert_input(Ipmipfa_data_t *data,
Ipmip_proc_t *proc,
Ipmipfa_pktbuf_t *pbuf)
{
Ipmip4_icmp_advert_t *advpkt;
int adv_len;
Ipmip4_icmp_ext_advert_t *ext = IP_NULL;
Ip_u8 *ext_start;
int ext_len;
int i;
if (IPMIP_BUFFER_SIZE(&pbuf->ipmip4.ipmip.packet) < 8)
{
IPCOM_LOG2(WARNING,
"ipcom_recvmsg(RtAdv) failed from '%s', short packet [length = %d]",
ipmip_ntop_sa(proc, pbuf->ipmip4.ipmip.srcinfo.src),
IPMIP_BUFFER_SIZE(&pbuf->ipmip4.ipmip.packet));
return;
}
/* Cache lengths and pointers */
advpkt = IPMIP_BUFFER_PTR(&pbuf->ipmip4.ipmip.packet);
adv_len = sizeof(Ipmip4_icmp_advert_t) + (advpkt->adv_num_addrs * advpkt->adv_addr_entry_size * 4);
/* Payload length check */
if (IPMIP_BUFFER_SIZE(&pbuf->ipmip4.ipmip.packet) < (unsigned)adv_len)
{
IPCOM_LOG3(WARNING,
"ipcom_recvmsg(RtAdv) failed from '%s', short packet [length = %d/%d]",
ipmip_ntop_sa(proc, pbuf->ipmip4.ipmip.srcinfo.src),
IPMIP_BUFFER_SIZE(&pbuf->ipmip4.ipmip.packet),
adv_len);
return;
}
ext_start = ipmip_buffer_offset(&pbuf->ipmip4.ipmip.packet, adv_len);
ext_len = IPMIP_BUFFER_SIZE(&pbuf->ipmip4.ipmip.packet) - adv_len;
i = ipmip4_msgext_icmp_parse(proc,
pbuf->iff.priv->iff.ipmip.ifname,
pbuf->ipmip4.ipmip.srcinfo.src->sin.sin_addr.s_addr,
&pbuf->ipmip4.ext.icmp,
ext_start,
ext_len);
if (i != IPMIP4_REG_EXT_SUCCESS)
return;
if (pbuf->ipmip4.ext.icmp.agent == IP_NULL)
return;
/* Cast to something usable */
ext = (Ipmip4_icmp_ext_advert_t *) pbuf->ipmip4.ext.icmp.agent;
if (IP_BIT_ISFALSE(IP_GET_NTOHS(&ext->flags), IPMIP4_ICMP_ADVEXT_FLAG_FOREIGN_AGENT))
return;
if (pbuf->ipmip4.ext.icmp.lla.found)
{
/* Input the advertisement to the LLH system */
ipmipfa_llh_advert_input(data, proc, pbuf);
}
}
/*
*===========================================================================
* ipmipfa_agent_solicitation_process
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC int
ipmipfa_agent_solicitation_process(int event,
Ipmipfa_data_t *data,
Ipmip_proc_t *proc,
Ipmipfa_pktbuf_t *pbuf,
Ipmipfa_node_t *node)
{
if (event == IPMIP_TIMER_EVENT_RUN)
{
if (pbuf->ipmip4.ext.icmp.lla.found)
{
/* Feed this solicitation to the LLH system */
ipmipfa_llh_solicit_input(data,
proc,
node,
pbuf);
}
else
{
IPCOM_LOG4(DEBUG2,
"----> Received RtSol <if=%s, src=%s, dst=%s, src_lla=%s>",
pbuf->iff.pub->ipmip.ifname,
ipmip_ntop_sa(proc, pbuf->ipmip4.ipmip.srcinfo.src),
ipmip_ntop_sa(proc, &pbuf->ipmip4.ipmip.srcinfo.dst->dst),
ipmip_ntop_lladdr(proc, pbuf->ipmip4.ipmip.srcinfo.lladdr));
if (pbuf->ipmip4.ipmip.srcinfo.ttl != 1)
{
IPCOM_LOG2(WARNING,
"ipcom_recvmsg(RtSol) failed from '%s', ttl != 1 (%d)",
ipmip_ntop_sa(proc, pbuf->ipmip4.ipmip.srcinfo.src),
pbuf->ipmip4.ipmip.srcinfo.ttl);
}
else
{
/* Received local RtSol, may be L2-LU */
if (node != IP_NULL)
{
/* This is a LU trigger for ST */
ipmipfa_llh_L2_LU(data,
proc,
node,
pbuf->ipmip4.ipmip.srcinfo.src->sin.sin_addr.s_addr,
pbuf->iff.priv,
pbuf->ipmip4.ipmip.srcinfo.lladdr);
}
/* Write a directed output */
ipmipfa_agent_advert_output(data,
proc,
pbuf->iff.priv,
node,
&pbuf->ipmip4.ipmip.srcinfo.src->sin.sin_addr.s_addr,
pbuf->ipmip4.ipmip.srcinfo.lladdr,
IP_FALSE);
}
}
}
else
{
/* Aborted or cancelled */
}
ipmip_pktbuf_release(&data->ipmip4.ipmip, proc, &pbuf->ipmip4.ipmip);
return IPMIP_TIMER_RET_DONE;
}
/*
*===========================================================================
* ipmipfa_agent_solicitation_input
*===========================================================================
* Description: Process received ICMP Agent solicitations.
* Parameters: pbuf - The packet buffer
* Returns:
*
*/
IP_STATIC Ip_bool
ipmipfa_agent_solicitation_input(Ipmipfa_data_t *data,
Ipmip_proc_t *proc,
Ipmipfa_pktbuf_t *pbuf)
{
Ip_u8 *ext_start;
int ext_len;
int i;
Ipmip4_icmp_solicit_t *solpkt;
int sol_len;
/* Solicitation packet */
solpkt = IPMIP_BUFFER_PTR(&pbuf->ipmip4.ipmip.packet);
sol_len = sizeof(Ipmip4_icmp_solicit_t);
if (IPMIP_BUFFER_SIZE(&pbuf->ipmip4.ipmip.packet) < (unsigned)sol_len)
{
IPCOM_LOG3(WARNING,
"ipcom_recvmsg(RtSol) failed from '%s', short packet [length = %d/%d]",
ipmip_ntop_sa(proc, pbuf->ipmip4.ipmip.srcinfo.src),
IPMIP_BUFFER_SIZE(&pbuf->ipmip4.ipmip.packet),
sol_len);
return IP_FALSE;
}
/* Extension part */
ext_start = ipmip_buffer_offset(&pbuf->ipmip4.ipmip.packet, sol_len);
ext_len = IPMIP_BUFFER_SIZE(&pbuf->ipmip4.ipmip.packet) - sol_len;
i = ipmip4_msgext_icmp_parse(proc,
pbuf->iff.pub->ipmip.ifname,
pbuf->ipmip4.ipmip.srcinfo.src->sin.sin_addr.s_addr,
&pbuf->ipmip4.ext.icmp,
ext_start,
ext_len);
if (i != IPMIP4_REG_EXT_SUCCESS)
return IP_FALSE;
/* Found any extensions? */
if (pbuf->ipmip4.ext.icmp.lla.found)
{
/* Verify that it's unicast */
if (pbuf->ipmip4.ipmip.srcinfo.dst->dst.sin.sin_addr.s_addr != pbuf->iff.pub->ifaddr)
{
IPCOM_LOG4(DEBUG,
"----> Received PrRtSol not unicast, discarding <if=%s, src=%s, dst=%s, src_lla=%s>",
pbuf->iff.pub->ipmip.ifname,
ipmip_ntop_sa(proc, pbuf->ipmip4.ipmip.srcinfo.src),
ipmip_ntop_sa(proc, &pbuf->ipmip4.ipmip.srcinfo.dst->dst),
ipmip_ntop_lladdr(proc, pbuf->ipmip4.ipmip.srcinfo.lladdr));
return IP_FALSE;
}
}
/* Invoke through the node manager */
ipmipfa_node_findbykey(data,
proc,
pbuf->iff.priv,
pbuf->ipmip4.ipmip.srcinfo.src->sin.sin_addr.s_addr,
0,
IP_NULL,
pbuf->ipmip4.ipmip.srcinfo.lladdr,
&pbuf->ipmip4.ipmip.timeout,
(Ipmip_timer_func_t)ipmipfa_agent_solicitation_process,
pbuf);
return IP_TRUE;
}
/*
****************************************************************************
* 10 GLOBAL FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipmipfa_agent_solicitation_build
*===========================================================================
* Description: Build solicitation
* Parameters: adv - The buffer to build the solicitation in.
* lla - Optional extension
* Returns: IP_TRUE on success
*
*/
IP_GLOBAL Ip_bool
ipmipfa_agent_solicitation_build(Ipmip_buffer_t *adv,
Ipmip_lladdr_t *lladdr)
{
Ipmip4_icmp_solicit_t solpkt;
Ipmip4_icmp_solicit_t *solpktp;
ipcom_memset(&solpkt, 0, sizeof(solpkt));
solpkt.icmp_type = IPMIP4_ICMP_ROUTER_SOLICITATION;
ipmip_buffer_append(adv, &solpkt, sizeof(solpkt));
/* Copy extension in case of PrRtSol */
if (lladdr != IP_NULL)
ipmip4_lla_llh_lladdr_buffer_icmp_append(adv, lladdr);
solpktp = IPMIP_BUFFER_PTR(adv);
solpktp->icmp_checksum = ipcom_in_checksum(IPMIP_BUFFER_DATA(adv), IPMIP_BUFFER_SIZE(adv));
return IP_TRUE;
}
/*
*===========================================================================
* ipmipfa_agent_challenge_build
*===========================================================================
* Description: Create a challenge extension.
* Parameters: iff - The interface to build the challenge for.
* node - The node if it's directed to it.
* buf - The extension we're building.
* icmp - Is it an ICMP or UDP extension.
* Returns:
*
*/
IP_GLOBAL void
ipmipfa_agent_challenge_build(Ipmipfa_data_t *data,
Ipmip_proc_t *proc,
Ipmipfa_iff_t *iff,
Ipmipfa_node_t *node,
Ipmip_buffer_t *buf,
Ip_bool icmp)
{
Ip_u8 *challenge;
int off;
/* Unicast variety? */
if (node)
{
/* Generate a new UNICAST challenge if required */
if (IP_BIT_ISFALSE(node->flags, IPMIPFA_NODE_CHALLENGE_UNICAST_VALID))
{
/* Generate a unicast challenge */
ipmipfa_if_challenge_generate(data, proc, iff, node->unicast_challenge);
IP_BIT_SET(node->flags, IPMIPFA_NODE_CHALLENGE_UNICAST_VALID);
}
/* Store */
challenge = node->unicast_challenge;
}
else
{
/* Get the greatest & latest */
int i = iff->current_challenge % IPMIPFA_CONF_CHALLENGE_WINDOW;
challenge = iff->challenge_window[i];
}
/**/
off = ipmip_buffer_append(buf, IP_NULL, IPMIPFA_CONF_CHALLENGE_EXTSIZE);
if (off != -1)
{
Ipmip4_msgext_uhdr_t *cha_ext = ipmip_buffer_offset(buf, off);
cha_ext->shdr.type = icmp? IPMIP4_ICMP_EXT_TYPE_AGENT_ADV_CHALLENGE : IPMIP4_EXT_TYPE_AGENT_ADV_CHALLENGE;
cha_ext->shdr.length = IPMIPFA_CONF_CHALLENGE_LEN;
/* Copy the challenge */
ipcom_memcpy(IPMIP4_MSGEXT_SHDR_EXT_DATA(cha_ext), challenge, IPMIPFA_CONF_CHALLENGE_LEN);
}
}
/*
*===========================================================================
* ipmipfa_agent_advert_build
*===========================================================================
* Description: Create an advertisement.
* Parameters: data - Context
* proc - Process
* adv - The buffer to create the advertisement in.
* iff - The interface for which we create the buffer.
* lla_ext - Append the interfaces LLA extension
* revoke - Revocation request.
* Returns: IP_TRUE on success.
*
*/
IP_GLOBAL Ip_bool
ipmipfa_agent_advert_build(Ipmipfa_data_t *data,
Ipmip_proc_t *proc,
Ipmip_buffer_t *adv,
Ipmipfa_iff_t *iff,
Ipmipfa_node_t *node,
Ip_bool lla_ext,
Ip_bool revoke)
{
Ipmip4_icmp_advert_t advpkt;
Ipmip4_icmp_advert_t *advpktp;
Ipmip4_icmp_ext_advert_t adv_ext;
Ip_u16 adv_seq;
ipcom_memset(&advpkt, 0, sizeof(advpkt));
ipcom_memset(&adv_ext, 0, sizeof(adv_ext));
/* ICMP advertisement header */
advpkt.icmp_type = IPMIP4_ICMP_AGENT_ADVERTISEMENT;
advpkt.icmp_code = data->ipnet_is_router ? IPMIP4_ICMP_CODE_GENERIC_ROUTER : IPMIP4_ICMP_CODE_AGENT_ONLY;
advpkt.icmp_checksum = 0;
advpkt.adv_num_addrs = 0;
advpkt.adv_addr_entry_size = 2;
advpkt.adv_lifetime = ip_htons(iff->adv_lifetime);
ipmip_buffer_append(adv, &advpkt, sizeof(advpkt));
/* Store */
if (!revoke)
{
adv_seq = iff->adv_seq;
if (++iff->adv_seq == 0)
/* Roll-over prevention, so it does not look like we have rebooted */
iff->adv_seq = 256;
}
else
{
adv_seq = 0;
}
/* Add mobility agent advertisement extension */
adv_ext.type = IPMIP4_ICMP_EXT_TYPE_MOBILITY_AGENT_ADV;
adv_ext.length = 6 + 4; /* 4=size of a careof address, possibly more of those here. +4n */
adv_ext.seq = ip_htons(adv_seq);
adv_ext.reg_lifetime = ip_htons(iff->lifetime);
adv_ext.flags = ip_ntohs(IPMIP4_ICMP_ADVEXT_FLAG_REG_REQUIRED | IPMIP4_ICMP_ADVEXT_FLAG_FOREIGN_AGENT);
/**/
if (IP_BIT_ISTRUE(data->shutdown, IPMIPFA_SHUTDOWN_ADV))
adv_ext.flags |= ip_ntohs(IPMIP4_ICMP_ADVEXT_FLAG_BUSY);
/* Set flags depending on configuration */
if (iff->tunnel.enabled[IPMIP_TUNNELTYPE_GRE])
adv_ext.flags |= ip_ntohs(IPMIP4_ICMP_ADVEXT_FLAG_GRE_ENCAP);
if (iff->tunnel.enabled[IPMIP_TUNNELTYPE_MINENC])
adv_ext.flags |= ip_ntohs(IPMIP4_ICMP_ADVEXT_FLAG_MINIMAL_ENCAP);
if (iff->tunnel.reverse != IPMIP_SYSVAR_MODE_DISABLED)
adv_ext.flags |= ip_ntohs(IPMIP4_ICMP_ADVEXT_FLAG_REV_TUNNEL);
if (iff->nat_t != 0)
adv_ext.flags |= ip_ntohs(IPMIP4_ICMP_ADVEXT_FLAG_UDP_TUNNELING);
if (iff->ext.revocation)
adv_ext.flags |= ip_ntohs(IPMIP4_ICMP_ADVEXT_FLAG_REVOCATION);
adv_ext.coa[0] = iff->iff.ifaddr;
ipmip_buffer_append(adv, &adv_ext, sizeof(adv_ext));
if (iff->ext.challenge)
ipmipfa_agent_challenge_build(data, proc, iff, node,adv, IP_TRUE);
/* Append extension */
if (lla_ext == IP_TRUE)
{
/**/
ipmip4_lla_llh_lladdr_buffer_icmp_append(adv,
iff->iff.ipmip.lladdr);
}
advpktp = IPMIP_BUFFER_PTR(adv);
advpktp->icmp_checksum = ipcom_in_checksum(IPMIP_BUFFER_DATA(adv), IPMIP_BUFFER_SIZE(adv));
IPCOM_LOG5(DEBUG2,
"<--- Creating %s #%d on %s <src=%s, lt=%d>",
lla_ext? "PrRtAdv" : "RtAdv",
adv_seq,
iff->iff.ipmip.ifname,
ipmip_ntop_inet(proc, iff->iff.ifaddr),
iff->adv_lifetime);
/* Return advlen */
return IP_TRUE;
}
/*
*===========================================================================
* ipmipfa_agent_advert_output
*===========================================================================
* Description: Write an ordinary multicast/unicast advertisement
* Parameters: data - Context
* proc - Process
* iff - The interface to send the advertisment from.
* node - Unicast destination node.
* dst - If specified, unicast dst address
* lla - If specified, unicast LLA address
* Returns:
*
*/
IP_GLOBAL void
ipmipfa_agent_advert_output(Ipmipfa_data_t *data,
Ipmip_proc_t *proc,
Ipmipfa_iff_t *iff,
Ipmipfa_node_t *node,
Ip_addr4 *dst,
Ipmip_lladdr_t *lladdr,
Ip_bool revoke)
{
Ipmip_buffer_t adv;
ipmip_buffer_init(&adv);
/* Create the advertisement */
if (ipmipfa_agent_advert_build(data, proc, &adv, iff, node, IP_FALSE, revoke))
{
/* If dst is zero, specify it as the advertisement address */
if (dst == IP_NULL)
dst = &iff->adv_address;
/* Write the request */
if (ipmip4_pkt_icmp_write(&data->ipmip4,
proc,
&adv,
iff->iff.ifaddr,
*dst,
&iff->iff,
lladdr) != IP_TRUE)
{
IPCOM_LOG2(ERR,
"----> Failed to send %s local RtAdv <IF=%s>",
(dst == &iff->adv_address)? "unicast" : "multicast",
iff->iff.ipmip.ifname);
}
ipmip_buffer_release(&adv);
}
}
/*
*===========================================================================
* ipmipfa_adv_recv
*===========================================================================
* Description: Handles incoming advertisements or solicitations
* Parameters: data - Context
* proc - Current process.
* pbuf - Packet buffer
* Returns:
*
*/
IP_GLOBAL void
ipmipfa_adv_recv(struct Ipmipfa_data *data,
struct Ipmip_proc *proc,
Ipmipfa_pktbuf_t *pbuf)
{
if (data->conf == IP_NULL)
return;
if (IP_BIT_ISTRUE(data->shutdown, IPMIPFA_SHUTDOWN_ADV))
return;
if (pbuf->ipmip4.ipmip.srcinfo.lladdr != IP_NULL)
{
Ipcom_icmp_header *icmph = IPMIP_BUFFER_PTR(&pbuf->ipmip4.ipmip.packet);
/* Truncated packet? */
if (IPMIP_BUFFER_SIZE(&pbuf->ipmip4.ipmip.packet) < IPCOM_ICMP_HEADER_LENGTH)
goto done_out;
if (pbuf->ipmip4.ipmip.srcinfo.dst->dst.sin.sin_addr.s_addr == ip_htonl(IP_INADDR_ALLHOSTS_GROUP)
|| pbuf->ipmip4.ipmip.srcinfo.dst->dst.sin.sin_addr.s_addr == ip_htonl(IP_INADDR_ALLRTRS_GROUP)
|| pbuf->ipmip4.ipmip.srcinfo.dst->dst.sin.sin_addr.s_addr == ip_htonl(IP_INADDR_ALLMA_GROUP)
|| pbuf->ipmip4.ipmip.srcinfo.dst->dst.sin.sin_addr.s_addr == 0xffffffff)
{
/* Must find the interface */
if ((pbuf->iff.pub = (Ipmip4_if_t *)ipmip_if_findbyindex(&data->conf->if_head, pbuf->ipmip4.ipmip.srcinfo.dst->ifindex)) == IP_NULL)
goto done_out;
}
else if ((pbuf->iff.pub = ipmip4_if_findbyaddr(&data->conf->if_head, pbuf->ipmip4.ipmip.srcinfo.dst->dst.sin.sin_addr.s_addr)) == IP_NULL)
goto done_out;
ipmip_lladdr_sanitize(pbuf->iff.pub->ipmip.lladdr, pbuf->ipmip4.ipmip.srcinfo.lladdr);
switch (icmph->type)
{
case IPMIP4_ICMP_ROUTER_SOLICITATION:
if (IP_BIT_ISFALSE(data->shutdown, IPMIPFA_SHUTDOWN_MUTE))
if (ipmipfa_agent_solicitation_input(data, proc, pbuf))
return;
case IPMIP4_ICMP_AGENT_ADVERTISEMENT:
ipmipfa_agent_advert_input(data, proc, pbuf);
break;
}
}
else
{
/* Failure */
IPCOM_LOG0(ERR,
"NO MAC");
}
done_out:
/* Free the packet buffer */
ipmip_pktbuf_release(&data->ipmip4.ipmip, proc, &pbuf->ipmip4.ipmip);
}
/*
****************************************************************************
* 11 PUBLIC FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,263 @@
/* ipmipfa_agent.h - ipmipfa_agent.h */
/*
******************************************************************************
* HEADER FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmipfa_agent.h,v $ $Revision: 1.16 $
* $Source: /home/interpeak/CVSRoot/ipmipfa/src/ipmipfa_agent.h,v $
* $Author: jhorteli $ $Date: 2009-03-31 14:57:58 $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelius@interpeak.se>
******************************************************************************
*/
#ifndef IPMIPFA_AGENT_H
#define IPMIPFA_AGENT_H
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
DESCRIPTION
No description currently provided
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#include "ipmipfa_if.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
#define IPMIPFA_CONF_CHALLENGE_EXTSIZE (IPMIPFA_CONF_CHALLENGE_LEN + IPMIP4_MSGEXT_SHDR_HDR_SIZE)
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
struct Ipmipfa_fa;
struct Ipmipfa_node;
struct Ipmipfa_iff;
struct Ipmipfa_data;
struct Ipmipfa_pktbuf;
/*
****************************************************************************
* 6 FUNCTIONS
****************************************************************************
*/
/*******************************************************************************
*
* ipmipfa_agent_challenge_build - ipmipfa_agent_challenge_build
*
* Create a challenge extension.
*
* Parameters:
* \is
* \i data
* Context
* \i proc
* Process
* \i iff
* The interface to build the challenge for.
* \i node
* The node if it's directed to it.
* \i buf
* The extension we're building.
* \i icmp
* Is it an ICMP or UDP extension.
* \ie
*
* RETURNS: No return value
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL void ipmipfa_agent_challenge_build
(
struct Ipmipfa_data *data,
struct Ipmip_proc *proc,
struct Ipmipfa_iff *iff,
struct Ipmipfa_node *node,
Ipmip_buffer_t *buf,
Ip_bool icmp
);
/*******************************************************************************
*
* ipmipfa_agent_solicitation_build - ipmipfa_agent_solicitation_build
*
* Build solicitation
*
* Parameters:
* \is
* \i adv
* The buffer to build the solicitation in.
* \i lla
* Optional extension
* \ie
*
* RETURNS: IP_TRUE on success
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL Ip_bool ipmipfa_agent_solicitation_build
(
Ipmip_buffer_t *adv,
Ipmip_lladdr_t *lladdr
);
/*******************************************************************************
*
* ipmipfa_agent_advert_output - ipmipfa_agent_advert_output
*
* Write an ordinary multicast/unicast advertisement
*
* Parameters:
* \is
* \i data
* The context
* \i proc
* Current process
* \i iff
* The interface to send the advertisment from.
* \i node
* Unicast directed node
* \i dst
* If specified, unicast dst address
* \i lla
* If specified, unicast LLA address
* \i revoke
* Revocation advertisement.
* \ie
*
* RETURNS: No return value
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL void ipmipfa_agent_advert_output
(
struct Ipmipfa_data *data,
struct Ipmip_proc *proc,
struct Ipmipfa_iff *iff,
struct Ipmipfa_node *node,
Ip_addr4 *dst,
Ipmip_lladdr_t *lla,
Ip_bool revoke
);
/*******************************************************************************
*
* ipmipfa_adv_recv - ipmipfa_adv_recv
*
* Handles incoming advertisements or solicitations
*
* Parameters:
* \is
* \i data
* Context
* \i proc
* Current process.
* \i pbuf
* Packet buffer
* \ie
*
* RETURNS: No return value
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL void ipmipfa_adv_recv
(
struct Ipmipfa_data *data,
struct Ipmip_proc *proc,
struct Ipmipfa_pktbuf *pbuf
);
/*******************************************************************************
*
* ipmipfa_agent_advert_build - ipmipfa_agent_advert_build
*
* Create an advertisement.
*
* Parameters:
* \is
* \i data
* Context
* \i proc
* Process
* \i adv
* The buffer to create the advertisement in.
* \i iff
* The interface for which we create the buffer.
* \i node
* Node we're sending a solicited advertisement to.
* \i lla_ext
* Append the interfaces LLA extension
* \i revoke
* Revocation request
* \ie
*
* RETURNS: IP_TRUE on success.
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL Ip_bool ipmipfa_agent_advert_build
(
struct Ipmipfa_data *data,
struct Ipmip_proc *proc,
Ipmip_buffer_t *adv,
struct Ipmipfa_iff *iff,
struct Ipmipfa_node *node,
Ip_bool lla_ext,
Ip_bool revoke
);
#ifdef __cplusplus
}
#endif
#endif
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,109 @@
/* ipmipfa_attr_h.h - ipmipfa_attr_h.h */
/*
******************************************************************************
* HEADER FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmipfa_attr_h.h,v $ $Revision: 1.8 $
* $Source: /home/interpeak/CVSRoot/ipmipfa/src/ipmipfa_attr_h.h,v $
* $Author: jhorteli $ $Date: 2009-03-31 14:57:58 $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelius@interpeak.se>
******************************************************************************
*/
#ifndef IPMIPFA_ATTR_H_H
#define IPMIPFA_ATTR_H_H
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
DESCRIPTION
No description currently provided
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#include "ipmipfa_attr.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
struct Ipmip4_context;
struct Ipmip_proc;
struct Ipmipfa_data;
/*
****************************************************************************
* 6 FUNCTIONS
****************************************************************************
*/
/*******************************************************************************
*
* ipmipfa_attr_command - ipmipfa_attr_command
*
* Process an attribute command
*
* Parameters:
* \is
* \i data
* Context
* \i proc
* Process
* \i request
* Issued command.
* \ie
*
* RETURNS: IPCOM_SUCCESS when successful
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL int ipmipfa_attr_command
(
struct Ipmipfa_data *data,
struct Ipmip_proc *proc,
struct Ipmip_cli_message *request
);
#ifdef __cplusplus
}
#endif
#endif
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,461 @@
/*
******************************************************************************
* INTERPEAK SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmipfa_cli.c,v $ $Revision: 1.3 $
* $Source: /home/interpeak/CVSRoot/ipmipfa/src/ipmipfa_cli.c,v $
* $Author: jhorteli $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelis@interpeak.se>
******************************************************************************
*/
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
#include "ipmipfa_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_sysctl.h>
#include <ipcom_syslog.h>
#include <ipcom_route.h>
#include <ipmip.h>
#include <private/ipmip_buffer.h>
#include <private/ipmip_util.h>
#include <ipmip4.h>
#include <private/ipmip4_context.h>
#include "ipmipfa.h"
#include "ipmipfa_attr.h"
#include "ipmipfa_cli.h"
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
/*
****************************************************************************
* 9 STATIC FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* 10 GLOBAL FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* 11 PUBLIC FUNCTIONS
****************************************************************************
*/
IP_PUBLIC Ip_bool
ipmipfa_cli_connect(Ipmip_cli_daemon_t *daemon_info)
{
ipmip_cli_daemon_init(daemon_info, "ipmipfa", IPCOM_IPD_ID_IPMIPFA);
return ipmip_cli_daemon_connect(daemon_info);
}
IP_PUBLIC void
ipmipfa_cli_request_set_nai(Ipmip_cli_daemon_req_t *req,
const char *nai)
{
if (nai)
ipmip_attr_put_str(&req->reqbuf, IPMIPFA_CLI_ATTR_BC_X_NAI, nai);
}
IP_PUBLIC void
ipmipfa_cli_request_set_handle(Ipmip_cli_daemon_req_t *req,
Ip_u32 handle)
{
ipmip_attr_put_u32(&req->reqbuf, IPMIPFA_CLI_ATTR_BC_X_HANDLE, handle);
}
IP_PUBLIC void
ipmipfa_cli_request_set_home_address(Ipmip_cli_daemon_req_t *req,
Ip_u32 hoa)
{
if (hoa)
ipmip_attr_put_inet(&req->reqbuf, IPMIPFA_CLI_ATTR_BC_X_HOA, hoa);
}
IP_PUBLIC void
ipmipfa_cli_request_set_home_agent(Ipmip_cli_daemon_req_t *req,
Ip_u32 ha)
{
if (ha)
ipmip_attr_put_inet(&req->reqbuf, IPMIPFA_CLI_ATTR_BC_X_HA, ha);
}
IP_PUBLIC void
ipmipfa_cli_request_set_ifname(Ipmip_cli_daemon_req_t *req,
const char *ifname)
{
if (ifname)
ipmip_attr_put_str(&req->reqbuf,IPMIPFA_CLI_ATTR_BC_X_IFNAME, ifname);
}
IP_PUBLIC Ip_time_t
ipmipfa_cli_node_get_created(struct Ipmip_attr *node)
{
/**/
return ipmip_attr_payload_find_time_t(node, IPMIPFA_CLI_ATTR_BC_X_CREATION_TIME);
}
IP_PUBLIC Ip_u32
ipmipfa_cli_node_get_handle(struct Ipmip_attr *node)
{
return ipmip_attr_payload_find_u32(node, IPMIPFA_CLI_ATTR_BC_X_HANDLE);
}
IP_PUBLIC Ip_u32
ipmipfa_cli_node_get_home_address(struct Ipmip_attr *node)
{
return ipmip_attr_payload_find_inet(node, IPMIPFA_CLI_ATTR_BC_X_HOA);
}
IP_PUBLIC Ip_u32
ipmipfa_cli_node_get_tunnel_endpoint(struct Ipmip_attr *node)
{
return ipmip_attr_payload_find_inet(node, IPMIPFA_CLI_ATTR_BC_X_TUNNEL_ENDPOINT);
}
IP_PUBLIC Ip_u32
ipmipfa_cli_node_get_tunnel_type(struct Ipmip_attr *node)
{
return ipmip_attr_payload_find_u32(node, IPMIPFA_CLI_ATTR_BC_X_TUNNEL_TYPE);
}
IP_PUBLIC Ip_u32
ipmipfa_cli_node_get_tunnel_flags(struct Ipmip_attr *node)
{
return ipmip_attr_payload_find_u32(node, IPMIPFA_CLI_ATTR_BC_X_TUNNEL_FLAGS);
}
IP_PUBLIC Ip_u32
ipmipfa_cli_node_get_home_agent(struct Ipmip_attr *node)
{
return ipmip_attr_payload_find_inet(node, IPMIPFA_CLI_ATTR_BC_X_HA);
}
IP_PUBLIC Ip_u32
ipmipfa_cli_node_get_time_granted(struct Ipmip_attr *node)
{
return ipmip_attr_payload_find_u32(node, IPMIPFA_CLI_ATTR_BC_X_TIME_GRANTED);
}
IP_PUBLIC Ip_u32
ipmipfa_cli_node_get_time_remaining(struct Ipmip_attr *node)
{
return ipmip_attr_payload_find_u32(node, IPMIPFA_CLI_ATTR_BC_X_TIME_REMAINING);
}
IP_PUBLIC Ip_time_t
ipmipfa_cli_node_get_last_updated(struct Ipmip_attr *node)
{
return ipmip_attr_payload_find_time_t(node, IPMIPFA_CLI_ATTR_BC_X_LAST_UPDATED);
}
IP_PUBLIC Ip_u32
ipmipfa_cli_node_get_registration_type(struct Ipmip_attr *node)
{
return ipmip_attr_payload_find_u32(node, IPMIPFA_CLI_ATTR_BC_X_REG_TYPE);
}
IP_PUBLIC Ip_u32
ipmipfa_cli_node_get_spi_mobile_foreign(struct Ipmip_attr *node)
{
return ipmip_attr_payload_find_u32(node, IPMIPFA_CLI_ATTR_BC_X_SPI_MF);
}
IP_PUBLIC Ip_u32
ipmipfa_cli_node_get_spi_foreign_home(struct Ipmip_attr *node)
{
return ipmip_attr_payload_find_u32(node, IPMIPFA_CLI_ATTR_BC_X_SPI_FH);
}
IP_PUBLIC Ip_u32
ipmipfa_cli_node_get_spi_mobile_AAA(struct Ipmip_attr *node)
{
return ipmip_attr_payload_find_u32(node, IPMIPFA_CLI_ATTR_BC_X_SPI_AAA);
}
IP_PUBLIC Ip_u32
ipmipfa_cli_node_get_registration_flags(struct Ipmip_attr *node)
{
return ipmip_attr_payload_find_u32(node, IPMIPFA_CLI_ATTR_BC_X_REG_FLAGS);
}
IP_PUBLIC Ip_u32
ipmipfa_cli_node_get_visitor_ip(struct Ipmip_attr *node)
{
return ipmip_attr_payload_find_inet(node, IPMIPFA_CLI_ATTR_BC_X_VISITOR_IP);
}
IP_PUBLIC Ip_u32
ipmipfa_cli_node_get_RegIdHigh(struct Ipmip_attr *node)
{
return ipmip_attr_payload_find_u32(node, IPMIPFA_CLI_ATTR_BC_X_REGIDHIGH);
}
IP_PUBLIC Ip_u32
ipmipfa_cli_node_get_RegIdLow(struct Ipmip_attr *node)
{
return ipmip_attr_payload_find_u32(node, IPMIPFA_CLI_ATTR_BC_X_REGIDLOW);
}
IP_PUBLIC Ip_u64
ipmipfa_cli_node_get_stats_rcv_octets64(struct Ipmip_attr *node)
{
return ipmip_attr_payload_find_u64(node, IPMIPFA_CLI_ATTR_BC_X_STATS_RCV_OCTETS64);
}
IP_PUBLIC Ip_u64
ipmipfa_cli_node_get_stats_rcv_pkts64(struct Ipmip_attr *node)
{
return ipmip_attr_payload_find_u64(node, IPMIPFA_CLI_ATTR_BC_X_STATS_RCV_PKTS64);
}
IP_PUBLIC Ip_u64
ipmipfa_cli_node_get_stats_snd_octets64(struct Ipmip_attr *node)
{
return ipmip_attr_payload_find_u64(node, IPMIPFA_CLI_ATTR_BC_X_STATS_SND_OCTETS64);
}
IP_PUBLIC Ip_u64
ipmipfa_cli_node_get_stats_snd_pkts64(struct Ipmip_attr *node)
{
return ipmip_attr_payload_find_u64(node, IPMIPFA_CLI_ATTR_BC_X_STATS_SND_PKTS64);
}
IP_PUBLIC const char *
ipmipfa_cli_node_get_ifname(struct Ipmip_attr *node)
{
/**/
return ipmip_attr_payload_find_str(node, IPMIPFA_CLI_ATTR_BC_X_IFNAME);
}
IP_PUBLIC const char *
ipmipfa_cli_node_get_nai(struct Ipmip_attr *node)
{
/**/
return ipmip_attr_payload_find_str(node, IPMIPFA_CLI_ATTR_BC_X_NAI);
}
IP_PUBLIC struct Ipmip_lladdr *
ipmipfa_cli_node_get_lladdr(struct Ipmip_attr *node)
{
/**/
return (struct Ipmip_lladdr *)ipmip_attr_payload_find_data(node, IPMIPFA_CLI_ATTR_BC_X_LLADDR);
}
IP_PUBLIC int
ipmipfa_cli_node_list(Ipmip_cli_daemon_t *daemon,
Ipmip_cli_daemon_req_t *req,
const char *nai,
const char *ifname,
Ip_u32 hoa,
Ip_u32 ha)
{
ipmip_cli_daemon_request_start(req, IPMIPFA_CLI_BC_X_LIST);
ipmipfa_cli_request_set_ifname(req, ifname);
ipmipfa_cli_request_set_nai(req, nai);
ipmipfa_cli_request_set_home_address(req, hoa);
ipmipfa_cli_request_set_home_agent(req, ha);
return ipmip_cli_daemon_request(daemon, req);
}
IP_PUBLIC struct Ipmip_attr *
ipmipfa_cli_node_get(Ipmip_cli_daemon_t *daemon,
Ipmip_cli_daemon_req_t *req,
Ip_u32 handle)
{
ipmip_cli_daemon_request_start(req, IPMIPFA_CLI_BC_X_GET);
ipmipfa_cli_request_set_handle(req, handle);
if (ipmip_cli_daemon_request(daemon, req) == IPCOM_SUCCESS)
return ipmip_cli_daemon_find_request(req, IPMIPFA_CLI_ATTR_BC_X);
return IP_NULL;
}
IP_PUBLIC Ip_u32
ipmipfa_cli_handle_next(Ipmip_attr_iter_t *iter)
{
/**/
return ipmip_attr_get_u32(ipmip_attr_iter_next(iter, IPMIPFA_CLI_ATTR_BC_X_HANDLE));
}
IP_PUBLIC void
ipmipfa_cli_daemon_mute(Ipmip_cli_daemon_t *daemon)
{
Ipmip_cli_daemon_req_t req;
ipmip_cli_daemon_request_init(&req);
ipmip_cli_daemon_request_start(&req, IPMIPFA_CLI_DAEMON_MUTE);
ipmip_cli_daemon_request(daemon, &req);
ipmip_cli_daemon_request_release(&req);
}
IP_PUBLIC void
ipmipfa_cli_daemon_start(Ipmip_cli_daemon_t *daemon)
{
Ipmip_cli_daemon_req_t req;
ipmip_cli_daemon_request_init(&req);
ipmip_cli_daemon_request_start(&req, IPMIPFA_CLI_DAEMON_START);
ipmip_cli_daemon_request(daemon, &req);
ipmip_cli_daemon_request_release(&req);
}
IP_PUBLIC void
ipmipfa_cli_daemon_stop(Ipmip_cli_daemon_t *daemon)
{
Ipmip_cli_daemon_req_t req;
ipmip_cli_daemon_request_init(&req);
ipmip_cli_daemon_request_start(&req, IPMIPFA_CLI_DAEMON_STOP);
ipmip_cli_daemon_request(daemon, &req);
ipmip_cli_daemon_request_release(&req);
}
IP_PUBLIC struct Ipmipfa_mib_RegistrationCounters *
ipmipfa_cli_daemon_registration_counters(Ipmip_cli_daemon_t *daemon,
Ipmip_cli_daemon_req_t *req)
{
ipmip_cli_daemon_request_start(req, IPMIPFA_CLI_DAEMON_REGISTRATION_COUNTERS);
if (ipmip_cli_daemon_request(daemon, req) == IPCOM_SUCCESS)
return (struct Ipmipfa_mib_RegistrationCounters *)ipmip_cli_daemon_find_request_data(req, IPMIPFA_CLI_ATTR_DAEMON_REGCOUNTER);
return IP_NULL;
}
IP_PUBLIC void
ipmipfa_cli_node_delete(Ipmip_cli_daemon_t *daemon,
Ip_u32 handle)
{
Ipmip_cli_daemon_req_t req;
ipmip_cli_daemon_request_init(&req);
ipmip_cli_daemon_request_start(&req, IPMIPFA_CLI_BC_X_DELETE);
ipmipfa_cli_request_set_handle(&req, handle);
ipmip_cli_daemon_request(daemon, &req);
ipmip_cli_daemon_request_release(&req);
}
IP_PUBLIC void
ipmipfa_cli_node_revoke(Ipmip_cli_daemon_t *daemon,
Ip_u32 handle)
{
Ipmip_cli_daemon_req_t req;
ipmip_cli_daemon_request_init(&req);
ipmip_cli_daemon_request_start(&req, IPMIPFA_CLI_BC_X_REVOKE);
ipmipfa_cli_request_set_handle(&req, handle);
ipmip_cli_daemon_request(daemon, &req);
ipmip_cli_daemon_request_release(&req);
}
IP_PUBLIC Ip_bool
ipmipfa_cli_daemon_l2_trigger(Ipmip_cli_daemon_t *daemon,
int trigger,
Ip_u32 mnip,
const char *ifname,
Ip_u32 faip,
const char *ll)
{
int ret;
Ipmip_cli_daemon_req_t req;
ipmip_cli_daemon_request_init(&req);
ipmip_cli_daemon_request_start(&req, trigger);
if (mnip)
ipmip_attr_put_inet(&req.reqbuf, IPMIPFA_CLI_ATTR_BC_X_HOA, mnip);
if (faip)
ipmip_attr_put_inet(&req.reqbuf, IPMIPFA_CLI_ATTR_BC_X_VISITOR_IP, faip);
if (ifname)
ipmip_attr_put_str(&req.reqbuf, IPMIPFA_CLI_ATTR_BC_X_IFNAME, ifname);
if (ll)
ipmip_attr_put_str(&req.reqbuf, IPMIPFA_CLI_ATTR_BC_X_LLA_NAME, ll);
ret = ipmip_cli_daemon_request(daemon, &req);
ipmip_cli_daemon_request_release(&req);
return ret == IPCOM_SUCCESS;
}
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,692 @@
/*
*******************************************************************************
* INTERPEAK SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmipfa_cmd_fa.c,v $ $Revision: 1.30 $
* $Source: /home/interpeak/CVSRoot/ipmipfa/src/ipmipfa_cmd_fa.c,v $
* $Author: jhorteli $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Niklas Lundberg <n@interpeak.se>
******************************************************************************
*/
/*
*******************************************************************************
* 1 DESCRIPTION
*******************************************************************************
*
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#define IPCOM_USE_CLIB_PROTO
#include <ipcom_os.h>
#include <ipcom_clib.h>
#include <ipcom_sock.h>
#include <ipcom_getopt.h>
#include <ipcom_ipd.h>
#include <ipcom_err.h>
#include <ipcom_list.h>
#include <ipcom_cmd.h>
#include <ipmip.h>
#include <private/ipmip_context.h>
#include <private/ipmip_cli.h>
#include <private/ipmip_ntop.h>
#include <ipmip4.h>
#include <private/ipmip4_msgext.h>
#include <private/ipmip4_lla.h>
#include "ipmipfa.h"
#include "ipmipfa_attr.h"
#include "ipmipfa_cli.h"
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
enum
{
IPMIPFA_CMD_LLH = 1,
IPMIPFA_CMD_OP_LIST,
IPMIPFA_CMD_OP_SHOW,
IPMIPFA_CMD_OP_STATS,
IPMIPFA_CMD_OP_REVOKE,
IPMIPFA_CMD_OP_STOP,
IPMIPFA_CMD_OP_START,
IPMIPFA_CMD_OP_DELETE,
IPMIPFA_CMD_OP_MUTE,
};
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
IP_PUBLIC int ipmipfa_cmd_fa(int argc, char **argv);
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
IP_STATIC Ipcom_cmd_int_str_map ipmipfa_cmd_ops[] =
{
{ IPMIPFA_CMD_LLH, "st" },
{ IPMIPFA_CMD_LLH, "tt" },
{ IPMIPFA_CMD_LLH, "lu" },
{ IPMIPFA_CMD_LLH, "ld" },
{ IPMIPFA_CMD_OP_LIST, "list" },
{ IPMIPFA_CMD_OP_SHOW, "show" },
{ IPMIPFA_CMD_OP_REVOKE, "revoke" },
{ IPMIPFA_CMD_OP_DELETE, "delete" },
{ IPMIPFA_CMD_OP_STOP, "stop" },
{ IPMIPFA_CMD_OP_START, "start" },
{ IPMIPFA_CMD_OP_MUTE, "mute" },
{ IPMIPFA_CMD_OP_STATS , "stats" },
{ IPMIPFA_CMD_OP_STATS , "statistics" },
{ 0, 0 }
};
IP_STATIC Ipcom_cmd_int_str_map ipmipfa_cmd_l2_ops[] =
{
{ IPMIPFA_CLI_BC_X_L2_TRIGGER_ST, "st" },
{ IPMIPFA_CLI_BC_X_L2_TRIGGER_TT, "tt" },
{ IPMIPFA_CLI_BC_X_L2_TRIGGER_LU, "lu" },
{ IPMIPFA_CLI_BC_X_L2_TRIGGER_LD, "ld" },
{ 0, 0 }
};
/*
****************************************************************************
* 9 STATIC FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipmipfa_cmd_registered_flags
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC char *
ipmipfa_cmd_regflags(char *buffer,
struct Ipmip_attr *node)
{
char *tt = "";
Ip_u32 tmp = ipmipfa_cli_node_get_tunnel_type(node);
if (tmp == IPMIP_TUNNELTYPE_GRE)
tt = "G";
else if (tmp == IPMIP_TUNNELTYPE_MINENC)
tt = "M";
tmp = ipmipfa_cli_node_get_tunnel_flags(node);
ipcom_sprintf(buffer,
"%-2s %s%s%s",
ipmipfa_attr_bc_x_regshort[ipmipfa_cli_node_get_registration_type(node)],
IP_BIT_ISTRUE(tmp, IPMIP4_TUNNELMODE_REVERSE)? "T" : "",
IP_BIT_ARESET(tmp, IPMIP4_TUNNELMODE_NAT_T_CONFIRMED)? "*" : "",
tt);
return buffer;
}
IP_STATIC void
ipmipfa_cmd_print_binding_fmt(Ip_u32 identity,
const char *hoa,
const char *hagent,
const char *ifname,
const char *lifetime,
const char *flags)
{
/* */
if (identity)
ipcom_printf("0x%08x %-10s %-15s %-15s %-16s %-15s"IP_LF,
identity, flags, hoa, hagent, ifname, lifetime);
else
ipcom_printf("Identity %-10s %-15s %-15s %-16s %-15s"IP_LF,
flags, hoa, hagent, ifname, lifetime);
}
IP_STATIC void
ipmipfa_cmd_print_binding(Ipmip_proc_t *proc,
struct Ipmip_attr *node)
{
ipcom_snprintf(proc->ntop.ntop_name,
sizeof(proc->ntop.ntop_name),
"%d/%d",
ipmipfa_cli_node_get_time_remaining(node),
ipmipfa_cli_node_get_time_granted(node));
/* OK; Time to print */
ipmipfa_cmd_print_binding_fmt(ipmipfa_cli_node_get_handle(node),
ipmip_ntop_inet(proc, ipmipfa_cli_node_get_home_address(node)),
ipmip_ntop_inet(proc, ipmipfa_cli_node_get_home_agent(node)),
ipmipfa_cli_node_get_ifname(node),
proc->ntop.ntop_name,
ipmipfa_cmd_regflags(proc->ntop.ntop_pbuf, node));
}
/*
*===========================================================================
* ipmipfa_cmd_show_binding
*===========================================================================
* Description:
* Parameters:
* Returns:
*
*/
IP_STATIC void
ipmipfa_cmd_show_binding(Ipmip_proc_t *proc,
struct Ipmip_attr *node)
{
Ip_u32 tmp;
const char *ptr;
Ipmip_lladdr_t *lladdr;
/**/
ipcom_printf("0x%08x %s:%s:"IP_LF,
ipmipfa_cli_node_get_handle(node),
ipmip_ntop_inet(proc, ipmipfa_cli_node_get_home_address(node)),
ipmip_ntop_inet(proc, ipmipfa_cli_node_get_home_agent(node)));
ipcom_printf(" Creation : %s"IP_LF, ipmip_ntop_tm(proc, ipmipfa_cli_node_get_created(node)));
/* Is it a valid NAI */
if ((ptr = ipmipfa_cli_node_get_nai(node)) != IP_NULL)
ipcom_printf(" Mobile NAI : %s"IP_LF, ptr);
if ((lladdr = ipmipfa_cli_node_get_lladdr(node)) != IP_NULL)
ipcom_printf(" Link : %s"IP_LF, ipmip_ntop_lladdr(proc, lladdr));
ipcom_printf(" Registration Type : %s"IP_LF, ipmipfa_attr_bc_x_regtype[ipmipfa_cli_node_get_registration_type(node)]);
ipcom_printf(" Forwarding Address : %s"IP_LF, ipmip_ntop_inet(proc, ipmipfa_cli_node_get_tunnel_endpoint(node)));
ipcom_printf(" Registration:"IP_LF);
ipcom_printf(" Last updated : %s"IP_LF, ipmip_ntop_tm(proc, ipmipfa_cli_node_get_last_updated(node)));
ipcom_printf(" Lifetime requested: %u"IP_LF, ipmipfa_cli_node_get_time_granted(node));
ipcom_printf(" Lifetime remaining: %u"IP_LF, ipmipfa_cli_node_get_time_remaining(node));
tmp = ipmipfa_cli_node_get_tunnel_flags(node);
ipcom_printf(" Reverse tunnel : %s"IP_LF, IP_BIT_ISSET(tmp, IPMIP4_TUNNELMODE_REVERSE)? "yes" : "no");
if (IP_BIT_ARESET(tmp, IPMIP4_TUNNELMODE_REVOCATION_CONFIRMED))
ipcom_printf(" Revocation : yes%s"IP_LF, IP_BIT_ISSET(tmp, IPMIP4_TUNNELMODE_REVOCATION_INFORM)? " (inform)" : "");
else
ipcom_printf(" Revocation : no"IP_LF);
ipcom_printf(" Nat traversal : %s"IP_LF, IP_BIT_ARESET(tmp, IPMIP4_TUNNELMODE_NAT_T_CONFIRMED)? "yes" : "no");
ipcom_printf(" Interface : %s"IP_LF, ipmipfa_cli_node_get_ifname(node));
tmp = ipmipfa_cli_node_get_spi_mobile_foreign(node);
if (tmp)
ipcom_printf(" SPI MF : %u"IP_LF, tmp);
tmp = ipmipfa_cli_node_get_spi_foreign_home(node);
if (tmp)
ipcom_printf(" SPI FH : %u"IP_LF, tmp);
tmp = ipmipfa_cli_node_get_spi_mobile_AAA(node);
if (tmp)
ipcom_printf(" SPI AAA : %u"IP_LF, tmp);
ipcom_printf(" Tunnel type : %s"IP_LF, ipmip_util_tunnel_to_desc(ipmipfa_cli_node_get_tunnel_type(node)));
/**/
ipcom_printf(" Sent Bytes : %lld"IP_LF, ipmipfa_cli_node_get_stats_snd_octets64(node));
ipcom_printf(" Sent Packets : %lld"IP_LF, ipmipfa_cli_node_get_stats_snd_pkts64(node));
ipcom_printf(" Receive Bytes : %lld"IP_LF, ipmipfa_cli_node_get_stats_rcv_octets64(node));
ipcom_printf(" Receive Packets : %lld"IP_LF, ipmipfa_cli_node_get_stats_rcv_pkts64(node));
}
IP_STATIC void
ipmipfa_cmd_handle_exec(Ipmip_proc_t *proc,
Ipmip_cli_daemon_t *daemon,
Ip_u32 handle,
Ip_u32 cmd)
{
struct Ipmip_attr *node;
Ipmip_cli_daemon_req_t nreq;
ipmip_cli_daemon_request_init(&nreq);
if ((node = ipmipfa_cli_node_get(daemon, &nreq, handle)) != IP_NULL)
{
switch (cmd)
{
case IPMIPFA_CMD_OP_LIST:
ipmipfa_cmd_print_binding(proc, node);
break;
case IPMIPFA_CMD_OP_SHOW:
ipmipfa_cmd_show_binding(proc, node);
break;
case IPMIPFA_CMD_OP_REVOKE:
ipmipfa_cli_node_revoke(daemon, handle);
break;
case IPMIPFA_CMD_OP_DELETE:
ipmipfa_cli_node_delete(daemon, handle);
break;
}
}
ipmip_cli_daemon_request_release(&nreq);
}
/*
****************************************************************************
* 10 GLOBAL FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* 11 PUBLIC FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipmipfa_cmd_fa
*===========================================================================
* Description:
* Parameters: .
* Returns: .
*
*/
IP_PUBLIC int
ipmipfa_cmd_fa(int argc, char **argv)
{
Ipcom_getopt opt;
int c;
int op_val;
char *op;
Ipmip_proc_t *proc = IP_NULL;
int used = 1;
int vr = ipcom_proc_vr_get();
int vr_new = vr;
Ipmip_cli_daemon_t daemon;
Ipmip_cli_daemon_req_t req;
int i;
/**/
daemon.fd = IP_INVALID_SOCKET;
ipmip_cli_daemon_request_init(&req);
ipcom_getopt_clear_r(&opt);
proc = ipmip_proc_alloc();
if (proc == IP_NULL)
{
ipcom_printf("fa: failed to create process context"IP_LF);
return -1;
}
if (argc < 2)
goto usage;
if (argc >= 4 && ipcom_strcmp(argv[1], "-V") == 0)
{
used += 2;
vr_new = ipcom_atoi(argv[2]);
}
ipcom_proc_vr_set(vr_new);
/* Get a connection to the home agent. */
for (i = 0; i < 10; i++)
{
if (ipmipfa_cli_connect(&daemon))
break;
ipcom_sleep(1);
}
if (daemon.fd == IP_INVALID_SOCKET)
{
ipcom_printf("fa: failed to connect to foreign agent"IP_LF);
ipmip_proc_destroy(proc);
ipcom_proc_vr_set(vr);
return -1;
}
op = argv[used];
op_val = ipcom_cmd_str_to_key(ipmipfa_cmd_ops, op);
if (op_val == -1)
{
/**/
if (ipmip4_cli_shell_pmipv4_cmd(argc - used + 1, argv + used - 1, proc, &daemon) == -1 &&
ipmip4_cli_shell_cmd(argc - used + 1, argv + used - 1, proc, &daemon) == -1)
{
ipcom_printf("'%s' is an invalid operation"IP_LF, op);
goto usage;
}
goto exit_out;
}
ipcom_getopt_clear_r(&opt);
if (op_val == IPMIPFA_CMD_OP_STATS)
{
struct Ipmipfa_mib_faVisitorEntry **fahdr = ipmipfa_attr_mib_faVisitorEntry();
struct Ipmipfa_mib_RegistrationCounters *regcnt = ipmipfa_attr_mib_RegistrationCounters();
i = 0;
if (fahdr)
{
for (i = 0; fahdr[i] != IP_NULL; i++)
;
ipcom_free(fahdr);
}
ipcom_printf("Number of nodes : %d"IP_LF, i);
if (regcnt)
{
ipcom_printf("Received Registration Requests: %d"IP_LF, regcnt->faRegRequestsReceived);
ipcom_printf("Received Registration Requests: %d"IP_LF, regcnt->faRegRequestsReceived);
ipcom_printf("Relayed Registration Requests : %d"IP_LF, regcnt->faRegRequestsRelayed);
ipcom_printf("Received Registration Replies : %d"IP_LF, regcnt->faRegRepliesRecieved);
ipcom_printf("Relayed Registration Replies : %d"IP_LF, regcnt->faRegRepliesRelayed);
ipcom_printf("Errors:"IP_LF);
ipcom_printf(" Reason Unspecified : %d"IP_LF, regcnt->faReasonUnspecified);
ipcom_printf(" Administratively Prohibited : %d"IP_LF, regcnt->faAdmProhibited);
ipcom_printf(" Insufficient Resources : %d"IP_LF, regcnt->faInsufficientResource);
ipcom_printf(" MN Authentication Failure : %d"IP_LF, regcnt->faMNAuthenticationFailure);
ipcom_printf(" Lifetime Too Long : %d"IP_LF, regcnt->faRegLifetimeTooLong);
ipcom_printf(" Poorly Formed Request : %d"IP_LF, regcnt->faPoorlyFormedRequests);
ipcom_printf(" Encapsulation Unavailable : %d"IP_LF, regcnt->faPoorlyFormedReplies);
ipcom_printf(" Home Agent Unreachable : %d"IP_LF, regcnt->faHAUnreachable);
ipcom_printf(" HA Authentication Failure : %d"IP_LF, regcnt->faHAAuthenticationFailure);
ipcom_printf(" Poorly Formed Replies : %d"IP_LF, regcnt->faPoorlyFormedReplies);
ipcom_free(regcnt);
}
}
else if (op_val == IPMIPFA_CMD_OP_SHOW ||
op_val == IPMIPFA_CMD_OP_REVOKE ||
op_val == IPMIPFA_CMD_OP_DELETE ||
op_val == IPMIPFA_CMD_OP_LIST)
{
static struct Ip_option long_options[] =
{
{"hoa", 1, 0, 0},
{"ha", 1, 0, 0},
{"nai", 1, 0, 0},
{"all", 0, 0, 0},
{"ifname", 1, 0, 0},
{0, 0, 0, 0}
};
Ip_bool all = IP_FALSE;
const char *nai = IP_NULL;
const char *ifname = IP_NULL;
Ip_u32 hoa = 0;
Ip_u32 ha = 0;
int ret = IPCOM_SUCCESS;
int args = 0;
/* --nai=joel@interpeak.se
* --ha=10.2.3.1
* --hoa=101.1.1.20
*/
/* Show node information */
opt.long_only = 1;
opt.long_options = long_options;
while ((i = ipcom_getopt_r(argc - used, argv + used, "a", &opt)) != -1)
{
args++;
switch (i)
{
case 0:
switch(opt.long_index)
{
case 0:
/* hoa -- Home Address */
if (ipcom_inet_pton(IP_AF_INET, opt.optarg, &hoa) != 1)
{
ipcom_printf("bad '--hoa' IPv4 address."IP_LF);
goto usage;
}
break;
case 1:
/* ha */
if (ipcom_inet_pton(IP_AF_INET, opt.optarg, &ha) != 1)
{
ipcom_printf("bad '--ha' IPv4 address."IP_LF);
goto usage;
}
break;
case 2:
/* nai */
nai = opt.optarg;
break;
case 3:
all = IP_TRUE;
break;
case 4:
ifname = opt.optarg;
break;
default:
ipcom_printf("unknown option %s", long_options[opt.long_index].name);
if (opt.optarg)
ipcom_printf(" with arg %s", opt.optarg);
ipcom_printf(IP_LF);
goto usage;
}
break;
case 'a':
all = IP_TRUE;
break;
default:
ipcom_printf("fa: invalid option '%c'"IP_LF, i);
goto usage;
}
}
/**/
if (op_val == IPMIPFA_CMD_OP_LIST)
ipmipfa_cmd_print_binding_fmt(0,
"Home Address",
"Home Agent",
"Interface",
"Lifetime",
"Status");
if (args > 0)
{
if (all)
ret = ipmipfa_cli_node_list(&daemon, &req, IP_NULL, IP_NULL, 0, 0);
else
ret = ipmipfa_cli_node_list(&daemon, &req, nai, ifname, hoa, ha);
if (ret == IPCOM_SUCCESS)
{
Ipmip_attr_iter_t riter;
Ip_u32 handle;
/**/
ipmip_cli_daemon_iter_request_init(&req, &riter);
while ((handle = ipmipfa_cli_handle_next(&riter)) != 0)
ipmipfa_cmd_handle_exec(proc, &daemon, handle, op_val);
}
}
else
{
for (i = opt.optind + used; i < argc; i++)
ipmipfa_cmd_handle_exec(proc, &daemon, ipcom_strtoul(argv[i], IP_NULL, 0), op_val);
}
}
else if (op_val == IPMIPFA_CMD_OP_START)
ipmipfa_cli_daemon_start(&daemon);
else if (op_val == IPMIPFA_CMD_OP_STOP)
ipmipfa_cli_daemon_stop(&daemon);
else if (op_val == IPMIPFA_CMD_OP_MUTE)
ipmipfa_cli_daemon_mute(&daemon);
else if (op_val == IPMIPFA_CMD_LLH)
{
const char *ll = IP_NULL;
const char *ifname = IP_NULL;
Ip_u32 mnip = 0;
Ip_u32 faip = 0;
int trigger = ipcom_cmd_str_to_key(ipmipfa_cmd_l2_ops, op);
static struct Ip_option long_options[] =
{
{"fa", 1, 0, 0},
{"hoa", 1, 0, 0},
{"ifname", 1, 0, 0},
{"lla", 1, 0, 0},
{0, 0, 0, 0}
};
opt.long_only = 1;
opt.long_options = long_options;
while((c = ipcom_getopt_r(argc - used, argv + used, "", &opt)) != -1)
{
switch (c)
{
case 0:
switch(opt.long_index)
{
case 0: /* fa */
if (ipcom_inet_pton(IP_AF_INET, opt.optarg, &faip) != 1)
{
ipcom_printf("bad '-faip' IPv4 address."IP_LF);
goto usage;
}
break;
case 1: /* hoa */
if (ipcom_inet_pton(IP_AF_INET, opt.optarg, &mnip) != 1)
{
ipcom_printf("bad '--hoa' IPv4 address."IP_LF);
goto usage;
}
break;
case 2: /* ifname */
ifname = opt.optarg;
break;
case 3: /* lla */
ll = opt.optarg;
break;
default:
ipcom_printf("unknown option %s", long_options[opt.long_index].name);
if (opt.optarg)
ipcom_printf(" with arg %s", opt.optarg);
ipcom_printf(IP_LF);
goto usage;
}
break;
default:
goto usage;
}
}
/* Send Trigger */
ipmipfa_cli_daemon_l2_trigger(&daemon, trigger, mnip, ifname, faip, ll);
}
goto exit_out;
/****** Usage ******/
usage:
ipmip_util_identprintf(proc, 0, "NAME"IP_LF);
ipmip_util_identprintf(proc, 1, "fa - Displays Foreign Agent IPv4 bindings, statistics and status" IP_LF);
ipmip_util_identprintf(proc, 0, "SYNOPSIS"IP_LF);
ipmip_util_identprintf(proc, 1, "fa <command> [arguments]"IP_LF);
ipmip_util_identprintf(proc, 0, "DESCRIPTION"IP_LF);
ipmip_util_identprintf(proc, 1,
"The fa command version %u.%u.%u is used to display current Foreign Agent MIPv4"IP_LF
"bindings, statistics and status."IP_LF,
(IPMIPFA_RELEASE / 10000) % 100, (IPMIPFA_RELEASE / 100) % 100, IPMIPFA_RELEASE % 100);
ipmip_util_identprintf(proc, 0, "COMMANDS"IP_LF);
ipmip_util_cmdprintf(proc, 1, "list [-a] [--nai=<nai>] [--ifname=<interface>] [--hoa=<home address>] [--ha=<home agent>] [<handle>]", "Short list the specified binding(s)");
ipmip_util_identprintf(proc, 2, "Legend:"IP_LF);
ipmip_util_identprintf(proc, 3, "+ - Normal Registration"IP_LF);
ipmip_util_identprintf(proc, 3, "- - Pending Registration"IP_LF);
ipmip_util_identprintf(proc, 3, "TT - Pre LLH Target Trigger"IP_LF);
ipmip_util_identprintf(proc, 3, "ST - Pre LLH Source Trigger"IP_LF);
ipmip_util_identprintf(proc, 3, "MT - Pre LLH Mobile Trigger"IP_LF);
ipmip_util_identprintf(proc, 3, "tt - Post LLH Target Trigger"IP_LF);
ipmip_util_identprintf(proc, 3, "st - Post LLH Source Trigger"IP_LF);
ipmip_util_identprintf(proc, 3, "G - GRE Tunneling"IP_LF);
ipmip_util_identprintf(proc, 3, "M - Minimal Encapsulation Tunneling"IP_LF);
ipmip_util_identprintf(proc, 3, "T - Reverse Encapsulation"IP_LF);
ipmip_util_identprintf(proc, 3, "* - NAT UDP Encapsulation"IP_LF);
ipmip_util_cmdprintf(proc, 1, "show [-a] [--nai=<nai>] [--ifname=<interface>] [--hoa=<home address>] [--ha=<home agent>] [<handle>]", "Show the specified binding(s)");
ipmip_util_cmdprintf(proc, 1, "revoke [-a] [--nai=<nai>] [--ifname=<interface>] [--hoa=<home address>] [--ha=<home agent>] [<handle>]", "Revoke the specified binding(s)");
ipmip_util_cmdprintf(proc, 1, "delete [-a] [--nai=<nai>] [--ifname=<interface>] [--hoa=<home address>] [--ha=<home agent>] [<handle>]", "Delete the specified binding(s)");
ipmip_util_identprintf(proc, 2, "-a All bindings"IP_LF);
ipmip_util_identprintf(proc, 2, "--nai=<nai> The network access name"IP_LF);
ipmip_util_identprintf(proc, 2, "--hoa=<home address> The home address"IP_LF);
ipmip_util_identprintf(proc, 2, "--ha=<home agent> The home agent"IP_LF);
ipmip_util_identprintf(proc, 2, "--ifname=<interface> The interface the binding is registered on"IP_LF);
ipmip_util_identprintf(proc, 2, "handle=<handle number> The unique handle of this binding"IP_LF);
ipmip_util_cmdprintf(proc, 1, "lu --hoa=<home address> --ifname=<interface> [--fa=<foreign agent>] [--lla=<Link Layer Address>]", "Link Up indicator to the specific node");
ipmip_util_cmdprintf(proc, 1, "ld --hoa=<home address> --ifname=<interface> [--fa=<foreign agent>] [--lla=<Link Layer Address>]", "Link Down indicator to the specific node");
ipmip_util_cmdprintf(proc, 1, "tt --hoa=<home address> --ifname=<interface> [--fa=<foreign agent>] [--lla=<Link Layer Address>]", "Target Trigger indicator to the specific node");
ipmip_util_cmdprintf(proc, 1, "st --hoa=<home address> --ifname=<interface> [--fa=<foreign agent>] [--lla=<Link Layer Address>]", "Source Trigger indicator to the specific node");
ipmip_util_identprintf(proc, 2, "--hoa=<home address> The home address"IP_LF);
ipmip_util_identprintf(proc, 2, "--fa=<foreign agent> The foreign agent"IP_LF);
ipmip_util_identprintf(proc, 2, "--ifname=<interface> The interface the binding is registered on"IP_LF);
ipmip_util_identprintf(proc, 2, "--lla=<link layer address> The mobile nodes link layer address"IP_LF);
ipmip_util_cmdprintf(proc, 1, "stats", "View global statistics");
ipmip4_cli_shell_pmipv4_usage(proc);
ipmip4_cli_shell_usage(proc);
exit_out:
ipmip_cli_daemon_disconnect(&daemon);
ipmip_cli_daemon_request_release(&req);
if (proc)
ipmip_proc_destroy(proc);
ipcom_proc_vr_set(vr);
return 0;
}
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,344 @@
/* ipmipfa_h.h - ipmipfa_h.h */
/*
******************************************************************************
* HEADER FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmipfa_h.h,v $ $Revision: 1.22 $
* $Source: /home/interpeak/CVSRoot/ipmipfa/src/ipmipfa_h.h,v $
* $Author: jhorteli $ $Date: 2009-06-17 11:00:48 $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelius@interpeak.se>
******************************************************************************
*/
#ifndef IPMIPFA_H_H
#define IPMIPFA_H_H
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
DESCRIPTION
No description currently provided
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#include <private/ipmip_cli.h>
#include <private/ipmip_pktbuf.h>
#include <private/ipmip4_msgext.h>
#include <private/ipmip4_context.h>
#include <ipmipfa_mib.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
#define IPMIPFA_SHUTDOWN_ADV (1 << 0)
#define IPMIPFA_SHUTDOWN_REG (1 << 1)
#define IPMIPFA_SHUTDOWN_MUTE (1 << 2)
#define IPMIPFA_SHUTDOWN_ALL (IPMIPFA_SHUTDOWN_REG|IPMIPFA_SHUTDOWN_ADV)
enum
{
IPMIPFA_FUNCTION_AAA = 0,
IPMIPFA_FUNCTION_REGEXT,
IPMIPFA_FUNCTION_MAX
};
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
struct Ipmipfa_data;
struct Ipmip_proc;
struct Ipmip_cli_message;
struct Ipmipfa_iff;
struct Ipmipfa_node;
struct Ipmipfa_pktbuf;
struct Ipmipfa_node_context;
struct Ipmip4_radius_context;
typedef void (*Ipmipfa_extension_config_global_t)
(
struct Ipmipfa_data *ctx,
struct Ipmip_proc *proc,
int action,
void *global_config,
struct Ipmip_cli_message *request
);
typedef void (*Ipmipfa_extension_config_ifp_t)
(
struct Ipmipfa_data *ctx,
struct Ipmip_proc *proc,
int action,
struct Ipmipfa_iff *ifp,
void *global_config,
void *ifp_config,
struct Ipmip_cli_message *request
);
typedef Ip_bool (*Ipmipfa_extension_attr_ifp_t)
(
struct Ipmipfa_data *ctx,
struct Ipmip_proc *proc,
struct Ipmipfa_iff *ifp,
void *global_config,
void *ifp_config,
struct Ipmip_cli_message *request
);
typedef int (*Ipmipfa_extension_provide_t)
(
struct Ipmipfa_data *ctx,
struct Ipmip_proc *proc,
int action,
void *global_config,
void *ifp_config,
void *node_config,
struct Ipmipfa_node *node
);
typedef void (*Ipmipfa_extension_revoke_inform_t)
(
struct Ipmipfa_data *ctx,
struct Ipmip_proc *proc,
void *global_config,
void *ifp_config,
void *node_config,
struct Ipmipfa_node *node
);
typedef Ip_bool (*Ipmipfa_extension_setup_t)
(
struct Ipmipfa_data *ctx,
struct Ipmip_proc *proc,
int action,
void *global_config,
void *ifp_config,
void *node_config,
struct Ipmipfa_node *node,
struct Ipmip_cli_message *request
);
typedef Ip_bool (*Ipmipfa_extension_pkt_req_validate_t)
(
struct Ipmipfa_data *ctx,
struct Ipmip_proc *proc,
void *global_config,
void *ifp_config,
void *node_config,
struct Ipmipfa_node *node,
struct Ipmipfa_pktbuf *pbuf
);
typedef void (*Ipmipfa_extension_pkt_req_forward_t)
(
struct Ipmipfa_data *ctx,
struct Ipmip_proc *proc,
void *global_config,
void *ifp_config,
void *node_config,
struct Ipmipfa_node *node,
struct Ipmipfa_pktbuf *pbuf
);
typedef Ip_bool (*Ipmipfa_extension_pkt_req_transport_t)
(
struct Ipmipfa_data *ctx,
struct Ipmip_proc *proc,
void *global_config,
void *ifp_config,
void *node_config,
struct Ipmipfa_node *node,
struct Ipmipfa_pktbuf *pbuf
);
typedef Ip_bool (*Ipmipfa_extension_pkt_rep_validate_t)
(
struct Ipmipfa_data *ctx,
struct Ipmip_proc *proc,
void *global_config,
void *ifp_config,
void *node_config,
struct Ipmipfa_node *node,
struct Ipmipfa_pktbuf *pbuf
);
typedef void (*Ipmipfa_extension_pkt_rep_forward_t)
(
struct Ipmipfa_data *ctx,
struct Ipmip_proc *proc,
void *global_config,
void *ifp_config,
void *node_config,
struct Ipmipfa_node *node,
struct Ipmipfa_pktbuf *pbuf
);
typedef void (*Ipmipfa_extension_pkt_reqrep_accepted_t)
(
struct Ipmipfa_data *ctx,
struct Ipmip_proc *proc,
void *global_config,
void *ifp_config,
void *node_config,
struct Ipmipfa_node *node,
struct Ipmipfa_pktbuf *pbuf
);
typedef struct Ipmipfa_extension
{
const char *name;
Ip_u32 node_data_size;
Ip_u32 ifp_data_size;
Ip_u32 global_data_size;
/**/
Ipmip_pktbuf_payload_t pktaux;
/* Callbacks */
Ipmipfa_extension_config_ifp_t config_ifp;
Ipmipfa_extension_config_global_t config_global;
Ipmipfa_extension_provide_t provide;
Ipmipfa_extension_setup_t setup;
Ipmipfa_extension_pkt_req_validate_t pkt_req_validate;
Ipmipfa_extension_pkt_req_forward_t pkt_req_forward;
Ipmipfa_extension_pkt_req_transport_t pkt_req_transport;
Ipmipfa_extension_pkt_rep_validate_t pkt_rep_validate;
Ipmipfa_extension_pkt_rep_forward_t pkt_rep_forward;
Ipmipfa_extension_pkt_reqrep_accepted_t pkt_reqrep_accepted;
Ipmipfa_extension_attr_ifp_t attr_ifp;
Ipmipfa_extension_revoke_inform_t revoke_inform;
/* Set by FA */
Ip_u32 type;
Ip_u32 func;
Ip_u32 unique;
} Ipmipfa_extension_t;
typedef struct Ipmipfa_function_context
{
Ipmipfa_extension_t *functions[32];
Ip_u32 num;
Ip_u32 node_data;
Ip_u32 mask;
} Ipmipfa_function_context_t;
/*
*===========================================================================
* Configuration data
*===========================================================================
*/
struct Ipmipfa_data;
struct Ipmipfa_route_context;
typedef struct Ipmipfa_conf
{
Ipcom_list if_head;
void *extdata[IPMIPFA_FUNCTION_MAX][32];
}
Ipmipfa_conf_t;
/*
*===========================================================================
* Global IPMIPFA data
*===========================================================================
*/
typedef struct Ipmipfa_data
{
Ipmip4_context_t ipmip4;
/* Pointers */
Ipmipfa_conf_t *conf;
Ip_u32 counter;
struct Ipmipfa_route_context *route;
int ipnet_is_router;
struct Ipmip_context_id *idents;
/* Sockets */
Ip_fd fd_ipd; /* ipd */
Ipmip_timer_lock_t *llh_lock;
/**/
int shutdown;
/* MIB Registration Counters */
Ipcom_mutex mibLock;
struct Ipmipfa_mib_RegistrationCounters mibRegCounters;
Ipmipfa_function_context_t *extensions;
Ip_u32 *extensions_node_data;
} Ipmipfa_data_t;
#define IPMIPFA_MIB_COUNTER_ADD(d,c,v) \
do { \
ipcom_mutex_lock((d)->mibLock); \
(c) += (v); \
ipcom_mutex_unlock((d)->mibLock); \
} while (0)
/*
****************************************************************************
* 6 FUNCTIONS
****************************************************************************
*/
struct Ipmip4_msgext_vendor_parse_ext;
IP_GLOBAL void ipmipfa_main(void);
IP_GLOBAL Ip_u32 ipmipfa_context_register_extension(Ipmipfa_extension_t *srv,
int function);
IP_GLOBAL void ipmipfa_msgext_vendor_parse_ext_register(struct Ipmip4_msgext_vendor_parse_ext *pext);
#ifdef __cplusplus
}
#endif
#endif
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,983 @@
/*
******************************************************************************
* INTERPEAK SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmipfa_if.c,v $ $Revision: 1.29.10.1 $
* $Source: /home/interpeak/CVSRoot/ipmipfa/src/ipmipfa_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
****************************************************************************
*/
/*
****************************************************************************
* 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_cmd.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>
#if 0
#include <ipnet_routesock.h>
#include <ipnet_policy_routing.h>
#endif
#include <ipmip.h>
#include <private/ipmip_sysvar.h>
#include <private/ipmip_netlink.h>
#include <ipmip4.h>
#include <private/ipmip4_sysext.h>
#include <private/ipmip4_util.h>
#include <private/ipmip4_auth.h>
#include <private/ipmip4_pkt.h>
#include "ipmipfa.h"
#include "ipmipfa_h.h"
#include "ipmipfa_if.h"
#include "ipmipfa_agent.h"
#include "ipmipfa_reg.h"
#include "ipmipfa_node.h"
#include "ipmipfa_route.h"
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
typedef struct Ipmipfa_iff_tunnel
{
Ipmip4_if_t iff;
Ipmipfa_iff_t *master;
#if 0
struct Ipnet_policy_routing_rule blk_rt_rule; /* Tunneled IF to Tunnel rule table */
struct Ipnet_policy_routing_rule lkl_rt_rule; /* Local IF to Tunnel rule table */
#endif
}
Ipmipfa_iff_tunnel_t;
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
/*
****************************************************************************
* 9 STATIC FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipmipfa_if_delete
*===========================================================================
* Description: Delete an interface
* Parameters: iff - The interface to delete.
* Returns:
*
*/
IP_STATIC void
ipmipfa_if_delete(Ipmipfa_data_t *data,
Ipmip_proc_t *proc,
Ipmipfa_iff_t *iff)
{
/* Free the final resources */
int i;
ipmipfa_llh_config_exit(data, proc, iff);
/* free spi list */
ipmip4_auth_context_destroy(iff->security.spi_ctx);
/* Free the SPI route tables */
ipmip4_auth_spi_table_destroy(iff->security.spi_ha);
ipmip4_auth_spi_table_destroy(iff->security.spi_fa);
ipmip_netlink_inX_rule(&data->ipmip4.ipmip,
proc,
IP_AF_INET,
IP_RTM_DELRULE,
iff->tnl_table,
IPMIPFA_ROUTE_PRID(0),
iff->iff.ipmip.ifindex,
IP_NULL,
0,
0,
0,
0,
IP_FIB_RULE_FIND_SADDR);
/* 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]->ipmip);
}
/* Destroy the node context */
ipmipfa_node_context_destroy(data, proc, iff->node);
/* Destroy black hole route table */
ipmip_util_route_table_free(&data->ipmip4.ipmip, proc, iff->fwd_table);
ipmip_util_route_table_free(&data->ipmip4.ipmip, proc, iff->tnl_table);
if (iff->link_layer)
ipcom_free(iff->link_layer);
/* Destroy the lock */
ipmip_timer_lock_destroy(&data->ipmip4.ipmip, proc, iff->if_lock);
}
/*
*===========================================================================
* ipmipfa_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 Ipmipfa_iff_t *
ipmipfa_if_alloc(Ipmipfa_data_t *data,
Ipmip_proc_t *proc,
const char *ifname)
{
/* Allocate an interface structure */
Ipmipfa_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,
"Unknown interface '%s'", ifname));
return IP_NULL;
}
/* Allocate the structure */
iff = (Ipmipfa_iff_t*)ipmip4_if_alloc(&data->ipmip4,
proc,
sizeof(*iff),
ifname,
ifindex,
IPMIP_IF_TYPE_GENERIC,
IPMIPFA_IFF_IDENTITY_FA,
(Ipmip_if_cleanup_t )ipmipfa_if_delete);
/* Sanity */
if (iff == IP_NULL)
return IP_NULL;
/* Return the interface structure */
return iff;
}
/*
*===========================================================================
* ipmipfa_if_challenge_next
*===========================================================================
* Description: Generate the next challenge.
* Parameters: iff - The interface we're working on.
* Returns:
*
*/
IP_STATIC void
ipmipfa_if_challenge_next(Ipmipfa_data_t *data,
Ipmip_proc_t *proc,
Ipmipfa_iff_t *iff)
{
int i;
/* Advance */
iff->current_challenge++;
/* The index */
i = iff->current_challenge % IPMIPFA_CONF_CHALLENGE_WINDOW;
/* Generate it */
ipmipfa_if_challenge_generate(data, proc, iff, iff->challenge_window[i]);
}
/*
*===========================================================================
* ipmipfa_if_output_timeout
*===========================================================================
* Description: Periodically send RtAdv.
* Parameters: iff - The interface we're sending on.
* Returns: IP_TRUE
*
*/
IP_STATIC Ip_bool
ipmipfa_if_advert_output_timeout(int event,
Ipmipfa_data_t *data,
Ipmip_proc_t *proc,
Ipmipfa_iff_t *iff,
void *extra)
{
IPMIP_UNUSED_PARAMETER(extra);
if (event == IPMIP_TIMER_EVENT_RUN)
{
if (IP_BIT_ISFALSE(data->shutdown, IPMIPFA_SHUTDOWN_MUTE))
{
/* Generate next challenge */
ipmipfa_if_challenge_next(data, proc, iff);
/* Output it */
ipmipfa_agent_advert_output(data, proc, iff, IP_NULL, IP_NULL, IP_NULL, IP_FALSE);
}
}
else
{
/* Do nothing on cancellation */
}
return IPMIP_TIMER_RET_REINSERT;
}
/*
*===========================================================================
* ipmipfa_destroy_tunnel
*===========================================================================
* Description: Destroy a particular tunnel.
* Parameters: tunnel - The tunnel to destroy.
* Returns:
*/
IP_STATIC void
ipmipfa_if_destroy_tunnel(Ipmipfa_data_t *data,
Ipmip_proc_t *proc,
Ipmipfa_iff_tunnel_t *iff)
{
/* No tunnel, don't bother */
if (iff->iff.ipmip.ifindex == 0)
return;
ipmip_netlink_inX_rule(&data->ipmip4.ipmip,
proc,
IP_AF_INET,
IP_RTM_DELRULE,
data->route->blk_table,
IPMIPFA_ROUTE_PRID(-2),
iff->iff.ipmip.ifindex,
IP_NULL,
0,
0,
0,
0,
0);
ipmip_netlink_inX_rule(&data->ipmip4.ipmip,
proc,
IP_AF_INET,
IP_RTM_DELRULE,
iff->master->fwd_table,
IPMIPFA_ROUTE_PRID(-1),
iff->iff.ipmip.ifindex,
IP_NULL,
0,
0,
0,
0,
0);
}
/*
*===========================================================================
* ipmipfa_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 Ipmip4_if_t *
ipmipfa_if_create_tunnel(Ipmipfa_data_t *data,
Ipmip_proc_t *proc,
Ipmipfa_iff_t *iff,
Ip_u32 ifindex,
Ip_u32 remote,
Ip_u8 identity,
Ip_u8 tunnel_type)
{
Ipmipfa_iff_tunnel_t *tiff;
char ifname[IP_IFNAMSIZ + 1];
/* Create the name */
ipcom_snprintf(ifname, sizeof(ifname), "%s%dfa%x", ipmip_util_tunnel_to_bsdname(tunnel_type), tunnel_type, ifindex);
tiff = (Ipmipfa_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 )ipmipfa_if_destroy_tunnel);
if (tiff == IP_NULL)
return IP_NULL;
/* Store master interface */
tiff->master = iff;
ipmip_netlink_inX_rule(&data->ipmip4.ipmip,
proc,
IP_AF_INET,
IP_RTM_NEWRULE,
data->route->blk_table,
IPMIPFA_ROUTE_PRID(-2),
tiff->iff.ipmip.ifindex,
IP_NULL,
0,
0,
0,
0,
0);
ipmip_netlink_inX_rule(&data->ipmip4.ipmip,
proc,
IP_AF_INET,
IP_RTM_NEWRULE,
iff->fwd_table,
IPMIPFA_ROUTE_PRID(-1),
tiff->iff.ipmip.ifindex,
IP_NULL,
0,
0,
0,
0,
0);
IPMIP4_EVENT_IF(DEBUG2, proc,
ipmip_log_event_add(&data->ipmip4.ipmip,
proc,
"Created tunnel interface '%s'", tiff->iff.ipmip.ifname));
return &tiff->iff;
}
/*
*===========================================================================
* ipmipfa_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
ipmipfa_if_configure(Ipmipfa_data_t *data,
Ipmip_proc_t *proc,
Ipmipfa_iff_t *iff,
Ipmipfa_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 CoA %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] = ipmipfa_if_create_tunnel(data,
proc,
iff,
iff->iff.ipmip.ifindex,
IP_INADDR_ANY,
IPMIPFA_IFF_IDENTITY_FA_TUNNEL,
i);
}
}
return IP_TRUE;
}
/*
****************************************************************************
* 10 GLOBAL FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* ipmipfa_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
ipmipfa_if_create(Ipmipfa_data_t *data,
Ipmip_proc_t *proc,
Ipmipfa_conf_t *conf,
const char *ifname)
{
Ipmipfa_iff_t *iff;
int i;
unsigned si;
char *dptr;
/* Try create the interface in question */
if ((iff = ipmipfa_if_alloc(data,proc,ifname)) == IP_NULL)
return IP_FALSE;
/**/
if ((iff->node = ipmipfa_node_context_alloc(data, proc)) == IP_NULL)
goto fail;
iff->tnl_table = ipmip_util_route_table_alloc(&data->ipmip4.ipmip, proc);
iff->fwd_table = ipmip_util_route_table_alloc(&data->ipmip4.ipmip, proc);
ipmip_netlink_inX_rule(&data->ipmip4.ipmip,
proc,
IP_AF_INET,
IP_RTM_NEWRULE,
iff->tnl_table,
IPMIPFA_ROUTE_PRID(0),
iff->iff.ipmip.ifindex,
IP_NULL,
0,
0,
0,
0,
IP_FIB_RULE_FIND_SADDR);
iff->conf = conf;
/* Initialize the lock */
iff->if_lock = ipmip_timer_lock_alloc(&data->ipmip4.ipmip, proc, IP_NULL, IP_NULL);
/* Create the security setup */
iff->security.spi_ctx = ipmip4_auth_context_create();
iff->security.spi_ha = ipmip4_auth_spi_table_create(iff->security.spi_ctx);
iff->security.spi_fa = ipmip4_auth_spi_table_create(iff->security.spi_ctx);
/* Initialize ADV timeout */
IPMIP_TIMER_INIT(&iff->adv_timer);
/**/
ipcom_list_init(&iff->fa_head);
/* Store it */
ipcom_list_insert_first(&conf->if_head, &iff->iff.ipmip.next);
ipmip_sysvar_foreach(proc,
(Ipmip_sysvar_foreach_t) ipmip4_sysext_foreach_spi,
iff->security.spi_ctx,
"ipmipfa.if.%s.spi.*",
iff->iff.ipmip.ifname);
ipmip_sysvar_foreach(proc,
(Ipmip_sysvar_foreach_t) ipmip4_sysext_foreach_spi,
iff->security.spi_ctx,
"ipmipfa.spi.*");
/* Read the SPI lookup definitions */
ipmip_sysvar_foreach(proc,
(Ipmip_sysvar_foreach_t) ipmip4_sysext_foreach_spiroute,
iff->security.spi_ha,
"ipmipfa.if.%s.ha.sa.address.*",
iff->iff.ipmip.ifname);
ipmip_sysvar_foreach(proc,
(Ipmip_sysvar_foreach_t) ipmip4_sysext_foreach_spiroute,
iff->security.spi_ha,
"ipmipfa.ha.sa.address.*");
ipmip_sysvar_foreach(proc,
(Ipmip_sysvar_foreach_t) ipmip4_sysext_foreach_spiroute,
iff->security.spi_fa,
"ipmipfa.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,
"ipmipfa.fa.sa.address.*");
iff->security.spi_ha_lookup_required = ipmip_sysvar_bool(ipmip_sysvar_bool(IP_FALSE, "ipmipfa.ha.sa.lookup.required"), "ipmipfa.if.%s.ha.sa.lookup.required", iff->iff.ipmip.ifname);
/* Get foreign agent addresses. Reachable by foreign subnets. */
ipmip_sysvar_inet(0, &iff->iff.ifaddr, IP_NULL, "ipmipfa.if.%s.foreignagent", iff->iff.ipmip.ifname);
/* Get ADV lifetime */
iff->mn_auth = ipmip_sysvar_bool(ipmip_sysvar_bool(IP_FALSE, "ipmipfa.mn_auth"), "ipmipfa.if.%s.mn_auth", iff->iff.ipmip.ifname);
/* Get ADV lifetime */
iff->adv_lifetime = (Ip_u16)ipmip_sysvar_ulong(ipmip_sysvar_ulong(300, "ipmipfa.adv_lifetime"), "ipmipfa.if.%s.adv_lifetime", iff->iff.ipmip.ifname);
/* Get ADV interval */
iff->adv_interval = ipmip_sysvar_long(10, "ipmipfa.if.%s.adv_interval", iff->iff.ipmip.ifname);
iff->lifetime = (Ip_u16)ipmip_sysvar_ulong(ipmip_sysvar_ulong(ipmip_sysvar_ulong(60, "ipmipfa.lifetime"), "ipmipfa.reg_lifetime"), "ipmipfa.if.%s.lifetime", iff->iff.ipmip.ifname);
if (iff->lifetime == 0)
iff->lifetime = 0xffff; /* infinite */
/* Get ADV address */
if (!ipmip_sysvar_inet(ip_htonl(IP_INADDR_ALLMA_GROUP), &iff->adv_address, IP_NULL, "ipmipfa.if.%s.adv_address", iff->iff.ipmip.ifname))
ipmip_sysvar_inet(ip_htonl(IP_INADDR_ALLMA_GROUP), &iff->adv_address, IP_NULL, "ipmipfa.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;
}
/* FA Error Extension (RFC4636) */
iff->ext.fa_error = ipmip_sysvar_bool(ipmip_sysvar_bool(IP_TRUE, "ipmipfa.ext.fa_error"), "ipmipfa.if.%s.ext.fa_error", iff->iff.ipmip.ifname);;
/* DHAA (RFC4433) */
iff->ext.dhaa = ipmip_sysvar_bool(ipmip_sysvar_bool(IP_TRUE, "ipmipfa.ext.dhaa"), "ipmipfa.if.%s.ext.dhaa", iff->iff.ipmip.ifname);
if (!ipmip_sysvar_inet(0, &iff->ext.dhaa_address, IP_NULL, "ipmipfa.if.%s.ext.dhaa.address", iff->iff.ipmip.ifname))
ipmip_sysvar_inet(0, &iff->ext.dhaa_address, IP_NULL, "ipmipfa.ext.dhaa.address");
/* Challenge (RFC3012) */
iff->ext.challenge = ipmip_sysvar_bool(ipmip_sysvar_bool(IP_FALSE, "ipmipfa.challenge"), "ipmipfa.if.%s.challenge", iff->iff.ipmip.ifname);
/* */
iff->ext.revocation = ipmip_sysvar_bool(ipmip_sysvar_bool(IP_TRUE, "ipmipfa.revocation.enabled"), "ipmipfa.if.%s.revocation.enabled", iff->iff.ipmip.ifname);
iff->ext.revocation_inform = ipmip_sysvar_mode(ipmip_sysvar_mode(IPMIP_SYSVAR_MODE_OPTIONAL, "ipmipfa.revocation.inform"), "ipmipfa.if.%s.revocation.inform", iff->iff.ipmip.ifname);
/* Reverse tunneling state? */
iff->tunnel.reverse = ipmip_sysvar_mode(ipmip_sysvar_mode(IPMIP_SYSVAR_MODE_OPTIONAL, "ipmipfa.tunnel.reverse"), "ipmipfa.if.%s.tunnel.reverse", iff->iff.ipmip.ifname);
/**/
iff->tunnel.enabled[IPMIP_TUNNELTYPE_NONE] = IP_TRUE;
/* Get tunnel reordering */
iff->reordering = ipmip_sysvar_bool(ipmip_sysvar_bool(IP_FALSE, "ipmipfa.tunnel.reordering"), "ipmipfa.if.%s.tunnel.reordering", iff->iff.ipmip.ifname);
/**/
iff->tunnel.enabled[IPMIP_TUNNELTYPE_IPIP] = ipmip_sysvar_bool(ipmip_sysvar_bool(IP_TRUE, "ipmipfa.tunnel.ipip"), "ipmipfa.if.%s.tunnel.ipip", iff->iff.ipmip.ifname);
/* GRE allowed? */
iff->tunnel.enabled[IPMIP_TUNNELTYPE_GRE] = ipmip_sysvar_bool(ipmip_sysvar_bool(IP_TRUE, "ipmipfa.tunnel.gre"), "ipmipfa.if.%s.tunnel.gre", iff->iff.ipmip.ifname);
/* MINENC allowed? */
iff->tunnel.enabled[IPMIP_TUNNELTYPE_MINENC] = ipmip_sysvar_bool(ipmip_sysvar_bool(IP_TRUE, "ipmipfa.tunnel.minenc"), "ipmipfa.if.%s.tunnel.minenc", iff->iff.ipmip.ifname);
/* NAT-T enabled? */
iff->nat_t = ipmip_sysvar_bool(ipmip_sysvar_bool(IP_TRUE, "ipmipfa.nat_t.enabled"), "ipmipfa.if.%s.nat_t.enabled", iff->iff.ipmip.ifname);
/* NAT-T keepalive? */
iff->nat_t_keepalive = (Ip_u8)ipmip_sysvar_ulong(ipmip_sysvar_ulong(120, "ipmipfa.nat_t.keepalive"), "ipmipfa.if.%s.nat_t.keepalive", iff->iff.ipmip.ifname);
/* NAT-T forced if enabled? */
iff->nat_t_force = ipmip_sysvar_bool(ipmip_sysvar_bool(IP_FALSE, "ipmipfa.nat_t.forced"), "ipmipfa.if.%s.nat_t.forced", iff->iff.ipmip.ifname);
/* Get tunnel type */
i = ipmip4_sysext_tunnel_type(ipmip4_sysext_tunnel_type(IPMIP_TUNNELTYPE_NONE, "ipmipfa.nat_t.tunnel_type"), "ipmipfa.if.%s.nat_t.tunnel_type", iff->iff.ipmip.ifname);
if (i == -1)
{
IPMIP4_EVENT_IF(ERR, proc,
ipmip_log_event_add(&data->ipmip4.ipmip,
proc,
"invalid 'nat_t.tunnel_type' configuration in UDP encap for interface '%s'",
iff->iff.ipmip.ifname));
goto fail;
}
iff->nat_t_tunnel = (Ip_u8)i;
/* Configure the interface */
if (ipmipfa_if_configure(data, proc, iff, conf) == IP_FALSE)
goto fail;
/* Generate a window full of challenges */
for (i = 0; i < IPMIPFA_CONF_CHALLENGE_WINDOW; i++)
ipmipfa_if_challenge_next(data, proc, iff);
if ((dptr = ipmip_sysvar("ipmipfa.if.%s.link.layer", iff->iff.ipmip.ifname)) == IP_NULL)
dptr = ipmip_sysvar("ipmipfa.link.layer");
/* */
if (dptr != IP_NULL)
{
iff->link_layer = ipmip_lladdr_parse(proc, iff->iff.ipmip.lladdr->type, iff->iff.ipmip.lladdr->subtype, dptr);
ipcom_free(dptr);
if (iff->link_layer)
{
ipmip_if_clear_flags(&data->ipmip4.ipmip, proc, &iff->iff.ipmip, IP_IFF_UP);
/* Assign LLADDR */
if (ipmip_netlink_link(&data->ipmip4.ipmip,
proc,
IP_RTM_SETLINK,
iff->iff.ipmip.ifindex,
0,
0,
IPMIP_LLADDR_DATA(iff->link_layer),
IPMIP_LLADDR_LEN_LLA(iff->link_layer),
0) != 0)
{
/* Do something */
IPMIP4_EVENT_IF(WARNING, proc,
ipmip_log_event_add(&data->ipmip4.ipmip,
proc,
"Foreign Agent interface %s unable to assign Link-Layer address",
iff->iff.ipmip.ifname));
}
ipmip_if_set_flags(&data->ipmip4.ipmip, proc, &iff->iff.ipmip, IP_IFF_UP);
/**/
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 assigned link-layer address for interface '%s'",
iff->iff.ipmip.ifname));
}
}
}
ipmipfa_llh_config_read(data, proc, iff);
/* Do the external parsing */
for (i = IPMIPFA_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;
}
IP_GLOBAL void *
ipmipfa_if_extension_data(Ipmipfa_iff_t *ifp,
Ipmipfa_extension_t *ext)
{
if (ext->ifp_data_size == 0)
return IP_NULL;
return ifp->extdata[ext->func][ext->type];
}
/*
*===========================================================================
* ipmipfa_if_start
*===========================================================================
* Description: Start an interface for a specified configuration.
* Parameters: data - The FA entity.
* proc - Current process.
* Returns:
*
*/
IP_GLOBAL void
ipmipfa_if_stop(Ipmipfa_data_t *data,
Ipmip_proc_t *proc,
Ipmipfa_conf_t *conf)
{
Ipmipfa_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 = IPMIPFA_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);
}
}
/*
*===========================================================================
* ipmipfa_if_start
*===========================================================================
* Description: Start an interface for a specified configuration.
* Parameters: data - The FA entity.
* proc - Current process.
* Returns:
*
*/
IP_GLOBAL void
ipmipfa_if_start(Ipmipfa_data_t *data,
Ipmip_proc_t *proc)
{
Ipmipfa_iff_t *iff;
if (data->conf == IP_NULL)
return;
/* 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))
{
/* 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)ipmipfa_if_advert_output_timeout,
iff,
IP_NULL,
iff->adv_interval * 1000);
}
}
}
/*
*===========================================================================
* ipmipfa_if_challenge_generate
*===========================================================================
* Description: Generate a challenge
* Parameters: data - Context
* proc - Process
* iff - The interface the challenge belongs to.
* challenge - Where to store the challenge.
* Returns:
*
*/
IP_GLOBAL void
ipmipfa_if_challenge_generate(Ipmipfa_data_t *data,
Ipmip_proc_t *proc,
Ipmipfa_iff_t *iff,
Ip_u8 *challenge)
{
struct Ip_timeval tv;
int i;
IPMIP_UNUSED_PARAMETER(iff);
IPMIP_UNUSED_PARAMETER(data);
IPMIP_UNUSED_PARAMETER(proc);
ipcom_microtime(&tv);
ipcom_srandom((unsigned int) (tv.tv_sec + tv.tv_usec));
for (i = 0; i < IPMIPFA_CONF_CHALLENGE_LEN; i++)
challenge[i] = (Ip_u8) ipcom_random();
}
/*
****************************************************************************
* 11 PUBLIC FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,315 @@
/* ipmipfa_if.h - ipmipfa_if.h */
/*
******************************************************************************
* HEADER FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmipfa_if.h,v $ $Revision: 1.23 $
* $Source: /home/interpeak/CVSRoot/ipmipfa/src/ipmipfa_if.h,v $
* $Author: ulf $ $Date: 2009-06-08 11:05:46 $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelius@interpeak.se>
******************************************************************************
*/
#ifndef IPMIPFA_IF_H
#define IPMIPFA_IF_H
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
DESCRIPTION
No description currently provided
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#include <ipcom_route.h>
#include <ipmip4.h>
#include <private/ipmip4_if.h>
#ifdef __cplusplus
extern "C" {
#endif
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
#define IPMIPFA_IFF_IDENTITY_FA (0)
#define IPMIPFA_IFF_IDENTITY_FA_TUNNEL (1)
#define IPMIPFA_IFF_IDENTITY_LLH_TUNNEL (2)
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
struct Ipmipfa_node;
struct Ipmipfa_data;
struct Ipmipfa_conf;
struct Ipmipfa_iff;
struct Ipmip4_auth_context;
struct Ipmip4_auth_spi_table;
/*
*===========================================================================
* Interface data
*===========================================================================
*/
typedef struct Ipmipfa_iff_ext_conf
{
Ip_u8 fa_error; /* 0: Disabled; 1: Enabled */
Ip_u8 dhaa; /* 0: Disabled; 1: Enabled */
Ip_u8 challenge; /* 0: Disabled; 1: Enabled */
Ip_u8 revocation; /* 0: Disabled; 1: Enabled */
Ip_u8 revocation_inform; /* 0: Disabled; 1: Enabled */
Ip_u32 dhaa_address;
}
Ipmipfa_iff_ext_conf_t;
typedef struct Ipmipfa_iff_tunnel_conf
{
Ip_u8 reverse; /* 0: Disabled; 1: Optional; 2: Required */
Ip_bool enabled[IPMIP_TUNNELTYPE_MAX + 1];
}
Ipmipfa_iff_tunnel_conf_t;
typedef struct Ipmipfa_iff_llh_conf
{
Ip_bool pre_enabled; /* PRE LLH enabled */
Ip_bool post_enabled; /* POST LLH enabled */
Ip_u16 post_bet_lifetime; /* Number of seconds the tunnel should be alive */
Ipcom_route *neighbor;
Ipcom_route *ap;
}
Ipmipfa_iff_llh_conf_t;
typedef struct Ipmipfa_iff_conf_sa
{
struct Ipmip4_auth_context *spi_ctx;
struct Ipmip4_auth_spi_table *spi_fa;
struct Ipmip4_auth_spi_table *spi_ha;
Ip_bool spi_ha_lookup_required;
} Ipmipfa_iff_conf_sa_t;
typedef struct Ipmipfa_iff
{
Ipmip4_if_t iff;
/* Advertisement data */
Ip_u16 adv_lifetime;
Ip_u16 adv_seq;
int adv_interval;
Ip_u32 adv_address; /* constant 255.255.255.255 or 224.0.0.X (from config) */
Ipmip_timer_t adv_timer;
Ipmip_timer_lock_t *if_lock;
Ipmipfa_iff_llh_conf_t llh;
Ipmipfa_iff_conf_sa_t security;
Ipmipfa_iff_tunnel_conf_t tunnel;
Ipmipfa_iff_ext_conf_t ext;
struct Ipmipfa_conf *conf;
struct Ipmipfa_node_context *node;
/* Challenge support */
int current_challenge; /* Index where the next challenge should be stored */
/* The collection of acceptable challenges in registration requests */
Ip_u8 challenge_window[IPMIPFA_CONF_CHALLENGE_WINDOW][IPMIPFA_CONF_CHALLENGE_LEN];
/* FA neigbor list */
Ipcom_list fa_head;
Ip_u8 fa_any; /* Wildcard match FA */
Ip_u8 mn_auth;
Ip_u8 reordering;
Ip_u8 nat_t; /* NAT-T */
Ip_u8 nat_t_tunnel; /* NAT-T; Tunnel Type? */
Ip_u16 nat_t_keepalive; /* NAT-T KeepAlive */
Ip_u16 nat_t_force; /* NAT-T; If enabled force usage? */
Ip_u16 lifetime; /* Default. */
Ipmip_lladdr_t *link_layer;
/* Tables */
Ip_u32 fwd_table; /* Home agent routing table */
Ip_u32 tnl_table; /* Home agent routing table */
/* Tunnel interfaces */
Ipmip4_if_t *tunnels[IPMIP_TUNNELTYPE_MAX + 1];
void *extdata[IPMIPFA_FUNCTION_MAX][32];
}
Ipmipfa_iff_t;
/*
****************************************************************************
* 6 FUNCTIONS
****************************************************************************
*/
/*******************************************************************************
*
* ipmipfa_if_create - ipmipfa_if_create
*
* Create an interface for a specified configuration.
*
* Parameters:
* \is
* \i data
* The FA entity.
* \i proc
* Current process
* \i conf
* The current configuration.
* \i ifname
* The name of the interface.
* \ie
*
* RETURNS: IP_TRUE if successful.
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL Ip_bool ipmipfa_if_create
(
struct Ipmipfa_data *data,
struct Ipmip_proc *proc,
struct Ipmipfa_conf *conf,
const char *ifname
);
/*******************************************************************************
*
* ipmipfa_if_stop - ipmipfa_if_stop
*
* Stop the interfaces belonging to a particular configuration
*
* Parameters:
* \is
* \i data
* The FA entity.
* \i proc
* Current process
* \i conf
* The current configuration.
* \ie
*
* RETURNS: No return value
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL void ipmipfa_if_stop
(
struct Ipmipfa_data *data,
struct Ipmip_proc *proc,
struct Ipmipfa_conf *conf
);
/*******************************************************************************
*
* ipmipfa_if_start - ipmipfa_if_start
*
* Start an interface for a specified configuration.
*
* Parameters:
* \is
* \i data
* The FA entity.
* \i proc
* Current process.
* \ie
*
* RETURNS: No return value
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL void ipmipfa_if_start
(
struct Ipmipfa_data *data,
struct Ipmip_proc *proc
);
/*******************************************************************************
*
* ipmipfa_if_challenge_generate - ipmipfa_if_challenge_generate
*
* Generate a challenge
*
* Parameters:
* \is
* \i data
* Context
* \i proc
* Process
* \i iff
* The interface the challenge belongs to.
* \i challenge
* Where to store the challenge.
* \ie
*
* RETURNS: No return value
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL void ipmipfa_if_challenge_generate
(
struct Ipmipfa_data *data,
struct Ipmip_proc *proc,
Ipmipfa_iff_t *iff,
Ip_u8 *challenge
);
IP_GLOBAL void *ipmipfa_if_extension_data
(
Ipmipfa_iff_t *ifp,
Ipmipfa_extension_t *ext
);
#ifdef __cplusplus
}
#endif
#endif
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,707 @@
/* ipmipfa_llh.h - ipmipfa_llh.h */
/*
******************************************************************************
* HEADER FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmipfa_llh.h,v $ $Revision: 1.15 $
* $Source: /home/interpeak/CVSRoot/ipmipfa/src/ipmipfa_llh.h,v $
* $Author: jhorteli $ $Date: 2009-04-23 14:32:14 $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelius@interpeak.se>
******************************************************************************
*/
#ifndef IPMIPFA_FA_H
#define IPMIPFA_FA_H
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
DESCRIPTION
No description currently provided
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#include "ipmipfa_agent.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
struct Ipmipfa_node;
struct Ipmipfa_conf;
struct Ipmipfa_data;
struct Ipmip4_msgext_array;
struct Ipmipfa_pktbuf;
struct Ipmip_cli_message;
typedef struct Ipmipfa_llh_agent
{
Ip_u32 addr;
Ipmipfa_iff_t *iff;
Ipmip_lladdr_t *lladdr;
} Ipmipfa_llh_agent_t;
/* Low Latency Handoff, the node's entering. We're nFA */
struct Ipmipfa_llh_pre_registration_TT
{
struct Ipmipfa_pktbuf *nFA_pbuf;
};
/* Low Latency Handoff, the node's entering. We're nFA */
struct Ipmipfa_llh_post_registration
{
Ip_u32 faVisitorRegIDLow; /* */
Ip_u32 faVisitorHomeAgentAddress; /* */
Ip_u16 faVisitorTimeGranted; /* The agreed upon lifetime */
Ip_u8 done; /* Received the wanted signal? */
Ip_u8 type; /* Type of message sent */
};
/* Low Latency Handoff, Pre Registration ST/MT/TT information for oFA/nFA */
union Ipmipfa_llh_pending
{
struct Ipmipfa_llh_pre_registration_TT pre_tt;
struct Ipmipfa_llh_post_registration post;
};
/*
****************************************************************************
* 6 FUNCTIONS
****************************************************************************
*/
/*******************************************************************************
*
* ipmipfa_llh_advert_input - ipmipfa_llh_advert_input
*
* Process a received advertisement.
*
* Parameters:
* \is
* \i data
* Data
* \i proc
* Process
* \i pbuf
* Packet buffer.
* \ie
*
* RETURNS: No return value
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL void ipmipfa_llh_advert_input
(
struct Ipmipfa_data *data,
struct Ipmip_proc *proc,
struct Ipmipfa_pktbuf *pbuf
);
/*******************************************************************************
*
* ipmipfa_llh_solicit_input - ipmipfa_llh_solicit_input
*
* Feed a PrRtSol into the LLH system.
*
* Parameters:
* \is
* \i data
* Data
* \i proc
* Process
* \i node
* Node if found, otherwise IP_NULL
* \i pbuf
* Packet buffer
* \ie
*
* RETURNS: No return value
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL void ipmipfa_llh_solicit_input
(
struct Ipmipfa_data *data,
struct Ipmip_proc *proc,
struct Ipmipfa_node *node,
struct Ipmipfa_pktbuf *pbuf
);
/*******************************************************************************
*
* ipmipfa_llh_clear - ipmipfa_llh_clear
*
* Delete any fast handover data belonging to the node.
*
* Parameters:
* \is
* \i data
* Context
* \i proc
* Process
* \i node
* The node
* \ie
*
* RETURNS: IP_FALSE
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL Ip_bool ipmipfa_llh_clear
(
struct Ipmipfa_data *data,
struct Ipmip_proc *proc,
struct Ipmipfa_node *node
);
/* Low-Latency Handoff; PRE REGISTRATION Methods */
/*******************************************************************************
*
* ipmipfa_llh_registration_received - ipmipfa_llh_registration_received
*
* We've just received a registration request with the
* following data
*
* Parameters:
* \is
* \i data
* Context
* \i proc
* Process
* \i node
* The node we're processing
* \i iff
* The interface
* \i lladdr
* Optional mobile node LLA
* \i ext
* Found LLA extensions.
* \ie
*
* RETURNS: No return value
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL void ipmipfa_llh_registration_received
(
struct Ipmipfa_data *data,
struct Ipmip_proc *proc,
struct Ipmipfa_node *node,
struct Ipmipfa_iff *iff,
Ipmip_lladdr_t *lladdr,
struct Ipmip4_msgext_array *ext
);
/*******************************************************************************
*
* ipmipfa_llh_registration_complete - ipmipfa_llh_registration_complete
*
* Registration has been completed
*
* Parameters:
* \is
* \i data
* Context
* \i proc
* Process
* \i node
* The node we're processing
* \ie
*
* RETURNS: No return value
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL void ipmipfa_llh_registration_complete
(
struct Ipmipfa_data *data,
struct Ipmip_proc *proc,
struct Ipmipfa_node *node
);
/*******************************************************************************
*
* ipmipfa_llh_L2_LU - ipmipfa_llh_L2_LU
*
* This is a L2-LU trigger for a mobile node. This means
* that a mobile node has become active on our network.
*
* Parameters:
* \is
* \i data
* The FA data entity.
* \i proc
* Process.
* \i node
* The node that received the L2-LU.
* \i home_addr
* Home address
* \i iff
* The interface it received the L2-LU on.
* \i lladdr
* The node's LLA identifier.
* \ie
*
* RETURNS: No return value
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL void ipmipfa_llh_L2_LU
(
struct Ipmipfa_data *data,
struct Ipmip_proc *proc,
struct Ipmipfa_node *node,
Ip_addr4 home_addr,
struct Ipmipfa_iff *iff,
Ipmip_lladdr_t *lladdr
);
/*******************************************************************************
*
* ipmipfa_llh_L2_LD - ipmipfa_llh_L2_LD
*
* This is a L2-LD trigger for a mobile node. This means
* that a mobile node has become inactive on our network.
*
* Parameters:
* \is
* \i data
* The FA data entity.
* \i proc
* Process.
* \i node
* The node that received the L2-LD.
* \i lla
* The node's LLA identifier.
* \ie
*
* RETURNS: A timer code.
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL int ipmipfa_llh_L2_LD
(
struct Ipmipfa_data *data,
struct Ipmip_proc *proc,
struct Ipmipfa_node *node,
Ipmip_lladdr_t *lladdr
);
/*******************************************************************************
*
* ipmipfa_llh_pre_registration_reply - ipmipfa_llh_pre_registration_reply
*
* Store a response to a mobile node PRE REGISTRATION request.
*
* Parameters:
* \is
* \i data
* FA data struct
* \i proc
* Process.
* \i node
* The node we're processing
* \i pbuf
* Packet buffer
* \ie
*
* RETURNS: IP_TRUE if stored.
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL Ip_bool ipmipfa_llh_pre_registration_reply
(
struct Ipmipfa_data *data,
struct Ipmip_proc *proc,
struct Ipmipfa_node *node,
struct Ipmipfa_pktbuf *pbuf
);
/*******************************************************************************
*
* ipmipfa_llh_hrqst_hrply_error - ipmipfa_llh_hrqst_hrply_error
*
* Error stage
*
* Parameters:
* \is
* \i data
* Context
* \i proc
* Process
* \i pbuf
* The packet buffer
* \ie
*
* RETURNS: No return value
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL int ipmipfa_llh_hrqst_hrply_error
(
struct Ipmipfa_data *data,
struct Ipmip_proc *proc,
struct Ipmipfa_pktbuf *pbuf,
Ip_u8 code
);
/*******************************************************************************
*
* ipmipfa_llh_post_registration_hrqst_input - ipmipfa_llh_post_registration_hrqst_input
*
* Parse a HRQST input.
*
* Parameters:
* \is
* \i event
* Event to run
* \i data
* Context
* \i proc
* Process
* \i pbuf
* Packet buffer
* \i node
* Node
* \ie
*
* RETURNS: One of the timer result values.
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL int ipmipfa_llh_post_registration_hrqst_input
(
int event,
struct Ipmipfa_data *data,
struct Ipmip_proc *proc,
struct Ipmipfa_pktbuf *pbuf,
struct Ipmipfa_node *node
);
/*******************************************************************************
*
* ipmipfa_llh_post_registration_hrply_input - ipmipfa_llh_post_registration_hrply_input
*
* Parse a HRPLY input.
*
* Parameters:
* \is
* \i event
* The event
* \i data
* Context
* \i proc
* Process
* \i pbuf
* Packet buffer
* \i node
* The mobile node
* \ie
*
* RETURNS: One of the defined timer result codes-
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL int ipmipfa_llh_post_registration_hrply_input
(
int event,
struct Ipmipfa_data *data,
struct Ipmip_proc *proc,
struct Ipmipfa_pktbuf *pbuf,
struct Ipmipfa_node *node
);
/*******************************************************************************
*
* ipmipfa_llh_config_read - ipmipfa_llh_config_read
*
* Read configuration variables
*
* Parameters:
* \is
* \i data
* The FA data structure
* \i proc
* Current process
* \i iff
* Interface pointer
* \ie
*
* RETURNS: No return value
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL void ipmipfa_llh_config_read
(
struct Ipmipfa_data *data,
struct Ipmip_proc *proc,
Ipmipfa_iff_t *iff
);
/*******************************************************************************
*
* ipmipfa_llh_config_exit - ipmipfa_llh_config_exit
*
* Free configuration variables
*
* Parameters:
* \is
* \i data
* The FA data structure
* \i proc
* Current process
* \i iff
* Interface pointer
* \ie
*
* RETURNS: No return value
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL void ipmipfa_llh_config_exit
(
struct Ipmipfa_data *data,
struct Ipmip_proc *proc,
Ipmipfa_iff_t *iff
);
/*******************************************************************************
*
* ipmipfa_llh_config_dump - ipmipfa_llh_config_dump
*
* Dump configuration variables
*
* Parameters:
* \is
* \i data
* The FA data structure
* \i proc
* Current process
* \i iff
* Interface pointer
* \i request
* Request
* \ie
*
* RETURNS: No return value
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL void ipmipfa_llh_config_dump
(
struct Ipmipfa_data *data,
struct Ipmip_proc *proc,
Ipmipfa_iff_t *iff,
struct Ipmip_cli_message *request
);
/*******************************************************************************
*
* ipmipfa_llh_ip_to_agent - ipmipfa_llh_ip_to_agent
*
* Convert an IP address to an agent structure
*
* Parameters:
* \is
* \i data
* The FA data structure
* \i proc
* Current process
* \i iff
* Interface
* \i ip
* Agent address
* \ie
*
* RETURNS: Agent structure if successful.
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL Ipmipfa_llh_agent_t *ipmipfa_llh_ip_to_agent
(
struct Ipmipfa_data *data,
struct Ipmip_proc *proc,
struct Ipmipfa_iff *iff,
Ip_addr4 ip
);
/*******************************************************************************
*
* ipmipfa_llh_L2_ST - ipmipfa_llh_L2_ST
*
* An ST LLH Trigger
*
* Parameters:
* \is
* \i data
* The FA data structure
* \i proc
* Current process
* \i node
* Node
* \i agent
* Agent structure
* \i lladdr
* Link Layer address
* \i iff
* Interface
* \i type
* Type
* \i regtype
* Registration type
* \ie
*
* RETURNS: No return value
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL void ipmipfa_llh_L2_ST
(
struct Ipmipfa_data *data,
struct Ipmip_proc *proc,
struct Ipmipfa_node *node,
Ipmipfa_llh_agent_t *agent,
struct Ipmip_lladdr *lladdr,
struct Ipmipfa_iff *iff,
int type,
int regtype
);
/*******************************************************************************
*
* ipmipfa_llh_L2_TT - ipmipfa_llh_L2_TT
*
* An TT LLH Trigger
*
* Parameters:
* \is
* \i data
* The FA data structure
* \i proc
* Current process
* \i home_addr
* Node's home address
* \i home_agent
* Node's home agent
* \i lladdr
* Link Layer address
* \i iff
* Interface
* \i node
* Node
* \i agent
* Agent structure
* \i post
* IP_TRUE if POST LLH.
* \ie
*
* RETURNS: No return value
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL void ipmipfa_llh_L2_TT
(
struct Ipmipfa_data *data,
struct Ipmip_proc *proc,
Ip_u32 home_addr,
Ip_u32 home_agent,
struct Ipmip_lladdr *lladdr,
struct Ipmipfa_iff *iff,
struct Ipmipfa_node *node,
Ipmipfa_llh_agent_t *agent,
Ip_bool post
);
#ifdef __cplusplus
}
#endif
#endif
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,750 @@
/*
*******************************************************************************
* 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
****************************************************************************
*/
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,344 @@
/* ipmipfa_reg.h - ipmipfa_reg.h */
/*
******************************************************************************
* HEADER FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmipfa_reg.h,v $ $Revision: 1.20 $
* $Source: /home/interpeak/CVSRoot/ipmipfa/src/ipmipfa_reg.h,v $
* $Author: jhorteli $ $Date: 2009-04-23 14:32:14 $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelius@interpeak.se>
******************************************************************************
*/
#ifndef IPMIPFA_REG_H
#define IPMIPFA_REG_H
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
DESCRIPTION
No description currently provided
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#include "ipmipfa.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
struct Ipmipfa_data;
struct Ipmipfa_pktbuf;
struct Ipmipfa_iff;
struct Ipmipfa_node;
struct Ipmipfa_node_req;
struct Ipmip_proc;
struct Ipmip4_context;
/*
****************************************************************************
* 6 FUNCTIONS
****************************************************************************
*/
/*******************************************************************************
*
* ipmipfa_reg_input_reply - ipmipfa_reg_input_reply
*
* Handles registration request and reply packages.
* Either forwards a reply from ha -> mn,
*
* or replies to mn cause of mn's bad request.
*
* Parameters:
* \is
* \i data
* Context
* \i proc
* Current process
* \i pbuf
* The packet buffer
* \ie
*
* RETURNS: No return value
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL void ipmipfa_reg_input_reply
(
struct Ipmipfa_data *data,
struct Ipmip_proc *proc,
struct Ipmipfa_pktbuf *pbuf
);
/*******************************************************************************
*
* ipmipfa_reg_recv - ipmipfa_reg_recv
*
* Handles registration request and reply packages.
* Either forwards a request from mn -> ha,
*
* or either forwards a reply from ha -> mn,
*
* or replies to mn cause of mn's bad request.
*
* Parameters:
* \is
* \i data
* Context
* \i proc
* Current process.
* \i pbuf
* Packet buffer
* \ie
*
* RETURNS: No return value
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL void ipmipfa_reg_recv
(
struct Ipmipfa_data *data,
struct Ipmip_proc *proc,
struct Ipmipfa_pktbuf *pbuf,
void *arg
);
/*******************************************************************************
*
* ipmipfa_reg_reply - ipmipfa_reg_reply
*
* Send a FA RegReply with bad-code to the MN
*
* Parameters:
* \is
* \i data
* Context
* \i proc
* Current process
* \i node
* The node we're replying to.
* \i pbuf
* The currently processed packet buffer
* \ie
*
* RETURNS: No return value
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL void ipmipfa_reg_reply
(
struct Ipmipfa_data *data,
struct Ipmip_proc *proc,
struct Ipmipfa_node *node,
struct Ipmipfa_pktbuf *pbuf
);
/*******************************************************************************
*
* ipmipfa_reg_forward_reply - ipmipfa_reg_forward_reply
*
* Forward HA RegReply to MN.
*
* Parameters:
* \is
* \i data
* Context
* \i proc
* Current process
* \i node
* The node we're forwarding to.
* \i pbuf
* Current packet buffer
* \i llh
* Is this a low latency forwarding.
* \ie
*
* RETURNS: No return value
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL void ipmipfa_reg_forward_reply
(
struct Ipmipfa_data *data,
struct Ipmip_proc *proc,
struct Ipmipfa_node *node,
struct Ipmipfa_pktbuf *pbuf,
Ip_bool llh
);
/*******************************************************************************
*
* ipmipfa_reg_hrply_write - ipmipfa_reg_hrply_write
*
* Write a reply for a HRQST message.
*
* Parameters:
* \is
* \i data
* The context
* \i proc
* The current process
* \i node
* Node.
* \i pbuf
* The packet buffer
* \i flags
* Flags
* \i code
* The return code.
* \i mn_lladdr
* The mobile node's LLA
* \i afa_lladdr
* The AFA's LLA
* \ie
*
* RETURNS: No return value
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL void ipmipfa_reg_hrply_write
(
struct Ipmipfa_data *data,
struct Ipmip_proc *proc,
struct Ipmipfa_node *node,
struct Ipmipfa_pktbuf *pbuf,
Ip_u8 flags,
Ip_u8 code,
Ipmip_lladdr_t *mn_lladdr,
Ipmip_lladdr_t *afa_lladdr
);
/*******************************************************************************
*
* ipmipfa_reg_hrqst_write - ipmipfa_reg_hrqst_write
*
* Write a reply for a HRQST message.
*
* Parameters:
* \is
* \i data
* The context
* \i proc
* Current process
* \i node
* The node we're sending the request for.
* \i fa_ip
* IP of the remote FA
* \i lifetime
* The lifetime to request.
* \i type
* Type of HRQST.
* \i mn_lladdr
* The mobile node's LLA
* \i afa_lladdr
* The AFA's LLA
* \ie
*
* RETURNS: No return value
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL void ipmipfa_reg_hrqst_write
(
struct Ipmipfa_data *data,
struct Ipmip_proc *proc,
struct Ipmipfa_node *node,
Ip_addr4 fa_ip,
Ip_u16 lifetime,
Ip_u8 type,
Ipmip_lladdr_t *mn_lladdr,
Ipmip_lladdr_t *afa_lladdr
);
/*******************************************************************************
*
* ipmipfa_reg_revoke_request - ipmipfa_reg_revoke_request
*
* Send a revocation request for this particular binding
*
* Parameters:
* \is
* \i data
* Data
* \i proc
* Process
* \i node
* Node
* \ie
*
* RETURNS: IP_TRUE if revocation was successfully initiated.
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL Ip_bool ipmipfa_reg_revoke_request
(
Ipmipfa_data_t *data,
Ipmip_proc_t *proc,
struct Ipmipfa_node *node
);
#ifdef __cplusplus
}
#endif
#endif
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,931 @@
/*
******************************************************************************
* INTERPEAK SOURCE FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmipfa_route.c,v $ $Revision: 1.13.10.1 $
* $Source: /home/interpeak/CVSRoot/ipmipfa/src/ipmipfa_route.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 "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_cmd.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_sysvar.h>
#include <ipmip4.h>
#include <private/ipmip4_sysext.h>
#include <private/ipmip4_util.h>
#include <private/ipmip4_usr.h>
#include <private/ipmip4_netlink.h>
#include "ipmipfa.h"
#include "ipmipfa_h.h"
#include "ipmipfa_if.h"
#include "ipmipfa_agent.h"
#include "ipmipfa_reg.h"
#include "ipmipfa_node.h"
#include "ipmipfa_route.h"
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
/*
****************************************************************************
* 6 EXTERN PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 7 LOCAL PROTOTYPES
****************************************************************************
*/
/*
****************************************************************************
* 8 DATA
****************************************************************************
*/
/*
****************************************************************************
* 9 STATIC FUNCTIONS
****************************************************************************
*/
IP_STATIC int
ipmipfa_netlink_new_link_send(struct Ipmipfa_data *ctx,
struct Ipmip_proc *proc,
Ipmipfa_node_t *node,
Ip_u32 eflags)
{
Ipmip_buffer_t rbuf;
Ip_size_t hdr_off;
struct Ip_mipmsg *msg;
int ret;
Ipmip_netlink_kern_handle_t handle;
Ipmip4_if_t *tunnel = IP_NULL;
Ipmipfa_iff_t *iff = node->ifp;
Ipmip_netlink_kern_compare_t scmp;
/* Locate the correct interface */
tunnel = iff->tunnels[node->faVisitorTunnelType];
/* Bad type or interface doesn't exist */
if (tunnel == IP_NULL || tunnel->ipmip.ifindex == 0)
{
IPCOM_LOG3(ERR, "adding MN tunnel %s -> through %s on %s -- FAILED (bad tunnel)",
ipmip_ntop_inet(proc, node->mib.faVisitorHomeAddress.s_addr),
ipmip_ntop_inet(proc, node->faVisitorTunnelingEndpoint),
tunnel? tunnel->ipmip.ifname : "<unknown>");
return 0;
}
ipmip_buffer_init(&rbuf);
/* Create NLMSG HDR */
ipmip_netlink_nlmsghdr_request(&rbuf, 0, 0, IP_RTM_NEWMIP, 0);
msg = ipmip_buffer_offset(&rbuf, ipmip_netlink_nlmsghdr_put(&rbuf, IP_NULL, sizeof(*msg)));
msg->mip_family = IP_AF_INET;
msg->mip_type = IP_WRMOB4_NEW_LINK_TX;
msg->mip_flags = 0;
/* Create the nested HoA attribute */
hdr_off = ipmip_netlink_nlmsghdr_rta_begin(&rbuf, IP_MIP_ENCAP);
ipmip_netlink_nlmsghdr_rta_put(&rbuf, IP_WRMOB4_ROUTE_DST, 4, &node->mib.faVisitorHomeAddress.s_addr);
ipmip_netlink_nlmsghdr_rta_put_u32(&rbuf, IP_WRMOB4_ROUTE_DST_LEN, 32);
ipmip_netlink_nlmsghdr_rta_put_u32(&rbuf, IP_WRMOB4_ROUTE_TABLE, node->ifp->tnl_table);
ipmip_netlink_nlmsghdr_rta_put_u32(&rbuf, IP_WRMOB4_ROUTE_LINK, IPMIP_LINK_SEND);
/* Route a binding */
ipmip_netlink_nlmsghdr_rta_put_u32(&rbuf, IP_WRMOB4_ROUTE_IFINDEX, tunnel->ipmip.ifindex);
ipmip_netlink_nlmsghdr_rta_put(&rbuf, IP_WRMOB4_ROUTE_GW, 4, &node->faVisitorTunnelingEndpoint);
ipmip_netlink_nlmsghdr_rta_put_u32(&rbuf, IP_WRMOB4_ROUTE_FLAGS, eflags);
if (IP_BIT_ARESET(node->faVisitorTunnelFlags, IPMIP4_TUNNELMODE_NAT_T_CONFIRMED))
ipmip_netlink_nlmsghdr_rta_put_u32(&rbuf, IP_WRMOB4_ROUTE_NAT_PORT, (IP_UDP_NAT_T_RFC3519 << 16 | ip_htons(IPMIP4_PORT)));
/* Identity */
handle.mip_facility = IPCOM_IPD_ID_IPMIPFA;
handle.mip_ident = node->faVisitorIdentity;
ipmip_netlink_nlmsghdr_rta_put(&rbuf, IP_WRMOB4_ROUTE_HANDLE, sizeof(handle), &handle);
if (node->reginfo.faVisitorRoute)
{
ipcom_memset(&scmp, 0, sizeof(scmp));
if (node->reginfo.faVisitorRoute->type == IPMIP_LLADDR_TYPE_INET)
ipmip_netlink_route_src_tunnel_in(&scmp, IP_GET_32ON8(&node->reginfo.faVisitorRoute->lla[0]), IP_NULL);
else
ipmip_netlink_route_src_mac(&scmp, node->reginfo.faVisitorRoute->lla, IPMIP_LLADDR_LEN_LLA(node->reginfo.faVisitorRoute));
ipmip_netlink_nlmsghdr_rta_put(&rbuf, IP_WRMOB4_ROUTE_SRCMAC, sizeof(scmp), &scmp);
}
ipmip_netlink_nlmsghdr_rta_end(&rbuf, hdr_off);
/* Complete the buffer */
ipmip_netlink_nlmsghdr_done(&rbuf, 0);
/* NETLINK request */
ret = ipmip_netlink_request(&ctx->ipmip4.ipmip,
proc,
ctx->ipmip4.ipmip.nl_req,
0,
0,
(struct Ip_nlmsghdr *)IPMIP_BUFFER_PTR(&rbuf),
IP_NULL);
/**/
ipmip_buffer_release(&rbuf);
if (ret < 0)
{
IPMIP4_EVENT_IF(ERR, proc,
ipmip_log_event_add(&ctx->ipmip4.ipmip,
proc,
"Unable to perform Foreign Agent NEW LINK SEND = %d", -ret));
}
return ret;
}
IP_STATIC int
ipmipfa_netlink_del_link_send(struct Ipmipfa_data *ctx,
struct Ipmip_proc *proc,
Ipmipfa_node_t *node)
{
Ipmip_buffer_t rbuf;
Ip_size_t hdr_off;
struct Ip_mipmsg *msg;
int ret;
Ipmip_netlink_kern_handle_t handle;
Ipmip4_if_t *tunnel = IP_NULL;
Ipmipfa_iff_t *iff = node->ifp;
/* Locate the correct interface */
tunnel = iff->tunnels[node->faVisitorTunnelType];
/* Bad type or interface doesn't exist */
if (tunnel == IP_NULL || tunnel->ipmip.ifindex == 0)
{
IPCOM_LOG3(ERR, "deleting MN tunnel %s -> through %s on %s -- FAILED (bad tunnel)",
ipmip_ntop_inet(proc, node->mib.faVisitorHomeAddress.s_addr),
ipmip_ntop_inet(proc, node->faVisitorTunnelingEndpoint),
tunnel? tunnel->ipmip.ifname : "<unknown>");
return 0;
}
ipmip_buffer_init(&rbuf);
/* Create NLMSG HDR */
ipmip_netlink_nlmsghdr_request(&rbuf, 0, 0, IP_RTM_DELMIP, 0);
msg = ipmip_buffer_offset(&rbuf, ipmip_netlink_nlmsghdr_put(&rbuf, IP_NULL, sizeof(*msg)));
msg->mip_family = IP_AF_INET;
msg->mip_type = IP_WRMOB4_DEL_LINK_TX;
msg->mip_flags = 0;
/* Create the nested HoA attribute */
hdr_off = ipmip_netlink_nlmsghdr_rta_begin(&rbuf, IP_MIP_ENCAP);
ipmip_netlink_nlmsghdr_rta_put(&rbuf, IP_WRMOB4_ROUTE_DST, 4, &node->mib.faVisitorHomeAddress.s_addr);
ipmip_netlink_nlmsghdr_rta_put_u32(&rbuf, IP_WRMOB4_ROUTE_DST_LEN, 32);
ipmip_netlink_nlmsghdr_rta_put_u32(&rbuf, IP_WRMOB4_ROUTE_TABLE, node->ifp->tnl_table);
/* Route a binding */
ipmip_netlink_nlmsghdr_rta_put_u32(&rbuf, IP_WRMOB4_ROUTE_IFINDEX, tunnel->ipmip.ifindex);
ipmip_netlink_nlmsghdr_rta_put(&rbuf, IP_WRMOB4_ROUTE_GW, 4, &node->faVisitorTunnelingEndpoint);
ipmip_netlink_nlmsghdr_rta_put_u32(&rbuf, IP_WRMOB4_ROUTE_FLAGS, IPMIP_RTF_TUNNELEND);
/* Identity */
handle.mip_facility = IPCOM_IPD_ID_IPMIPFA;
handle.mip_ident = node->faVisitorIdentity;
ipmip_netlink_nlmsghdr_rta_put(&rbuf, IP_WRMOB4_ROUTE_HANDLE, sizeof(handle), &handle);
ipmip_netlink_nlmsghdr_rta_end(&rbuf, hdr_off);
/* Complete the buffer */
ipmip_netlink_nlmsghdr_done(&rbuf, 0);
/* NETLINK request */
ret = ipmip_netlink_request(&ctx->ipmip4.ipmip,
proc,
ctx->ipmip4.ipmip.nl_req,
0,
0,
(struct Ip_nlmsghdr *)IPMIP_BUFFER_PTR(&rbuf),
IP_NULL);
/**/
ipmip_buffer_release(&rbuf);
if (ret < 0)
{
IPMIP4_EVENT_IF(ERR, proc,
ipmip_log_event_add(&ctx->ipmip4.ipmip,
proc,
"Unable to perform Foreign Agent DEL LINK SEND = %d", -ret));
}
return ret;
}
IP_STATIC int
ipmipfa_netlink_new_link_recv2mac(struct Ipmipfa_data *ctx,
struct Ipmip_proc *proc,
Ipmipfa_node_t *node)
{
Ipmip_buffer_t rbuf;
Ip_size_t hdr_off;
struct Ip_mipmsg *msg;
int ret;
Ipmip_netlink_kern_handle_t handle;
Ipmip_netlink_kern_compare_t scmp;
struct Ip_sockaddr_dl lnk;
ipcom_memset(&lnk, 0, sizeof(lnk));
ipmip_buffer_init(&rbuf);
/* Create NLMSG HDR */
ipmip_netlink_nlmsghdr_request(&rbuf, 0, 0, IP_RTM_NEWMIP, 0);
msg = ipmip_buffer_offset(&rbuf, ipmip_netlink_nlmsghdr_put(&rbuf, IP_NULL, sizeof(*msg)));
msg->mip_family = IP_AF_INET;
msg->mip_type = IP_WRMOB4_NEW_LINK_RX;
msg->mip_flags = 0;
/* Create the nested HoA attribute */
hdr_off = ipmip_netlink_nlmsghdr_rta_begin(&rbuf, IP_MIP_ENCAP);
ipmip_netlink_nlmsghdr_rta_put(&rbuf, IP_WRMOB4_ROUTE_DST, 4, &node->mib.faVisitorHomeAddress.s_addr);
ipmip_netlink_nlmsghdr_rta_put_u32(&rbuf, IP_WRMOB4_ROUTE_DST_LEN, 32);
ipmip_netlink_nlmsghdr_rta_put_u32(&rbuf, IP_WRMOB4_ROUTE_TABLE, node->ifp->fwd_table);
ipmip_netlink_nlmsghdr_rta_put_u32(&rbuf, IP_WRMOB4_ROUTE_LINK, IPMIP_LINK_RECV);
/* Route a binding */
ipmip_netlink_nlmsghdr_rta_put_u32(&rbuf, IP_WRMOB4_ROUTE_IFINDEX, node->ifp->iff.ipmip.ifindex);
IPCOM_SA_LEN_SET(&lnk, sizeof(struct Ip_sockaddr_dl));
lnk.sdl_family = IP_AF_LINK;
lnk.sdl_index = node->ifp->iff.ipmip.ifindex;
lnk.sdl_type = IP_IFT_ETHER;
lnk.sdl_nlen = 0;
lnk.sdl_alen = (Ip_u8)IPMIP_LLADDR_LEN_LLA(node->reginfo.faVisitorRoute);
lnk.sdl_slen = 0;
ipcom_memcpy(IP_SOCKADDR_DL_LLADDR(&lnk), node->reginfo.faVisitorRoute->lla, lnk.sdl_alen);
ipmip_netlink_nlmsghdr_rta_put(&rbuf, IP_WRMOB4_ROUTE_GW, sizeof(lnk), &lnk);
/* Identity */
handle.mip_facility = IPCOM_IPD_ID_IPMIPFA;
handle.mip_ident = node->faVisitorIdentity;
ipmip_netlink_nlmsghdr_rta_put(&rbuf, IP_WRMOB4_ROUTE_HANDLE, sizeof(handle), &handle);
ipcom_memset(&scmp, 0, sizeof(scmp));
ipmip_netlink_route_src_tunnel_in(&scmp, node->faVisitorTunnelingEndpoint, IP_NULL);
ipmip_netlink_nlmsghdr_rta_put(&rbuf, IP_WRMOB4_ROUTE_SRCMAC, sizeof(scmp), &scmp);
ipmip_netlink_nlmsghdr_rta_end(&rbuf, hdr_off);
/* Complete the buffer */
ipmip_netlink_nlmsghdr_done(&rbuf, 0);
/* NETLINK request */
ret = ipmip_netlink_request(&ctx->ipmip4.ipmip,
proc,
ctx->ipmip4.ipmip.nl_req,
0,
0,
(struct Ip_nlmsghdr *)IPMIP_BUFFER_PTR(&rbuf),
IP_NULL);
/**/
ipmip_buffer_release(&rbuf);
if (ret < 0)
{
IPMIP4_EVENT_IF(ERR, proc,
ipmip_log_event_add(&ctx->ipmip4.ipmip,
proc,
"Unable to perform Foreign Agent NEW LINK RECV = %d", -ret));
}
return ret;
}
IP_STATIC int
ipmipfa_netlink_new_link_recv2tunnel(struct Ipmipfa_data *ctx,
struct Ipmip_proc *proc,
Ipmipfa_node_t *node)
{
Ipmip_buffer_t rbuf;
Ip_size_t hdr_off;
struct Ip_mipmsg *msg;
int ret;
Ipmip_netlink_kern_handle_t handle;
Ipmip_netlink_kern_compare_t scmp;
struct Ip_sockaddr_dl lnk;
ipcom_memset(&lnk, 0, sizeof(lnk));
ipmip_buffer_init(&rbuf);
/* Create NLMSG HDR */
ipmip_netlink_nlmsghdr_request(&rbuf, 0, 0, IP_RTM_NEWMIP, 0);
msg = ipmip_buffer_offset(&rbuf, ipmip_netlink_nlmsghdr_put(&rbuf, IP_NULL, sizeof(*msg)));
msg->mip_family = IP_AF_INET;
msg->mip_type = IP_WRMOB4_NEW_LINK_RX;
msg->mip_flags = 0;
/* Create the nested HoA attribute */
hdr_off = ipmip_netlink_nlmsghdr_rta_begin(&rbuf, IP_MIP_ENCAP);
ipmip_netlink_nlmsghdr_rta_put(&rbuf, IP_WRMOB4_ROUTE_DST, 4, &node->mib.faVisitorHomeAddress.s_addr);
ipmip_netlink_nlmsghdr_rta_put_u32(&rbuf, IP_WRMOB4_ROUTE_DST_LEN, 32);
ipmip_netlink_nlmsghdr_rta_put_u32(&rbuf, IP_WRMOB4_ROUTE_TABLE, node->ifp->fwd_table);
ipmip_netlink_nlmsghdr_rta_put_u32(&rbuf, IP_WRMOB4_ROUTE_LINK, IPMIP_LINK_RECV);
/* Route a binding */
ipmip_netlink_nlmsghdr_rta_put_u32(&rbuf, IP_WRMOB4_ROUTE_IFINDEX, node->ifp->tunnels[node->faVisitorTunnelType]->ipmip.ifindex);
ipmip_netlink_nlmsghdr_rta_put_u32(&rbuf, IP_WRMOB4_ROUTE_FLAGS, IPMIP_RTF_TUNNELEND);
ipmip_netlink_nlmsghdr_rta_put(&rbuf, IP_WRMOB4_ROUTE_GW, 4, &node->reginfo.faVisitorRoute->lla[0]);
/* Identity */
handle.mip_facility = IPCOM_IPD_ID_IPMIPFA;
handle.mip_ident = node->faVisitorIdentity;
ipmip_netlink_nlmsghdr_rta_put(&rbuf, IP_WRMOB4_ROUTE_HANDLE, sizeof(handle), &handle);
ipcom_memset(&scmp, 0, sizeof(scmp));
ipmip_netlink_route_src_tunnel_in(&scmp, node->faVisitorTunnelingEndpoint, IP_NULL);
ipmip_netlink_nlmsghdr_rta_put(&rbuf, IP_WRMOB4_ROUTE_SRCMAC, sizeof(scmp), &scmp);
ipmip_netlink_nlmsghdr_rta_end(&rbuf, hdr_off);
/* Complete the buffer */
ipmip_netlink_nlmsghdr_done(&rbuf, 0);
/* NETLINK request */
ret = ipmip_netlink_request(&ctx->ipmip4.ipmip,
proc,
ctx->ipmip4.ipmip.nl_req,
0,
0,
(struct Ip_nlmsghdr *)IPMIP_BUFFER_PTR(&rbuf),
IP_NULL);
/**/
ipmip_buffer_release(&rbuf);
if (ret < 0)
{
IPMIP4_EVENT_IF(ERR, proc,
ipmip_log_event_add(&ctx->ipmip4.ipmip,
proc,
"Unable to perform Foreign Agent NEW LINK RECV = %d", -ret));
}
return ret;
}
IP_STATIC int
ipmipfa_netlink_del_link_recv2mac(struct Ipmipfa_data *ctx,
struct Ipmip_proc *proc,
Ipmipfa_node_t *node)
{
Ipmip_buffer_t rbuf;
Ip_size_t hdr_off;
struct Ip_mipmsg *msg;
int ret;
Ipmip_netlink_kern_handle_t handle;
struct Ip_sockaddr_dl lnk;
ipcom_memset(&lnk, 0, sizeof(lnk));
ipmip_buffer_init(&rbuf);
/* Create NLMSG HDR */
ipmip_netlink_nlmsghdr_request(&rbuf, 0, 0, IP_RTM_DELMIP, 0);
msg = ipmip_buffer_offset(&rbuf, ipmip_netlink_nlmsghdr_put(&rbuf, IP_NULL, sizeof(*msg)));
msg->mip_family = IP_AF_INET;
msg->mip_type = IP_WRMOB4_DEL_LINK_RX;
msg->mip_flags = 0;
/* Create the nested HoA attribute */
hdr_off = ipmip_netlink_nlmsghdr_rta_begin(&rbuf, IP_MIP_ENCAP);
ipmip_netlink_nlmsghdr_rta_put(&rbuf, IP_WRMOB4_ROUTE_DST, 4, &node->mib.faVisitorHomeAddress.s_addr);
ipmip_netlink_nlmsghdr_rta_put_u32(&rbuf, IP_WRMOB4_ROUTE_DST_LEN, 32);
ipmip_netlink_nlmsghdr_rta_put_u32(&rbuf, IP_WRMOB4_ROUTE_TABLE, node->ifp->fwd_table);
/* Route a binding */
ipmip_netlink_nlmsghdr_rta_put_u32(&rbuf, IP_WRMOB4_ROUTE_IFINDEX, node->ifp->iff.ipmip.ifindex);
IPCOM_SA_LEN_SET(&lnk, sizeof(struct Ip_sockaddr_dl));
lnk.sdl_family = IP_AF_LINK;
lnk.sdl_index = node->ifp->iff.ipmip.ifindex;
lnk.sdl_type = IP_IFT_ETHER;
lnk.sdl_nlen = 0;
lnk.sdl_alen = (Ip_u8)IPMIP_LLADDR_LEN_LLA(node->reginfo.faVisitorRoute);
lnk.sdl_slen = 0;
ipcom_memcpy(IP_SOCKADDR_DL_LLADDR(&lnk), node->reginfo.faVisitorRoute->lla, lnk.sdl_alen);
ipmip_netlink_nlmsghdr_rta_put(&rbuf, IP_WRMOB4_ROUTE_GW, sizeof(lnk), &lnk);
/* Identity */
handle.mip_facility = IPCOM_IPD_ID_IPMIPFA;
handle.mip_ident = node->faVisitorIdentity;
ipmip_netlink_nlmsghdr_rta_put(&rbuf, IP_WRMOB4_ROUTE_HANDLE, sizeof(handle), &handle);
ipmip_netlink_nlmsghdr_rta_end(&rbuf, hdr_off);
/* Complete the buffer */
ipmip_netlink_nlmsghdr_done(&rbuf, 0);
/* NETLINK request */
ret = ipmip_netlink_request(&ctx->ipmip4.ipmip,
proc,
ctx->ipmip4.ipmip.nl_req,
0,
0,
(struct Ip_nlmsghdr *)IPMIP_BUFFER_PTR(&rbuf),
IP_NULL);
/**/
ipmip_buffer_release(&rbuf);
if (ret < 0)
{
IPMIP4_EVENT_IF(ERR, proc,
ipmip_log_event_add(&ctx->ipmip4.ipmip,
proc,
"Unable to perform Foreign Agent DEL LINK RECV = %d", -ret));
}
return ret;
}
IP_STATIC int
ipmipfa_netlink_del_link_recv2tunnel(struct Ipmipfa_data *ctx,
struct Ipmip_proc *proc,
Ipmipfa_node_t *node)
{
Ipmip_buffer_t rbuf;
Ip_size_t hdr_off;
struct Ip_mipmsg *msg;
int ret;
Ipmip_netlink_kern_handle_t handle;
struct Ip_sockaddr_dl lnk;
ipcom_memset(&lnk, 0, sizeof(lnk));
ipmip_buffer_init(&rbuf);
/* Create NLMSG HDR */
ipmip_netlink_nlmsghdr_request(&rbuf, 0, 0, IP_RTM_DELMIP, 0);
msg = ipmip_buffer_offset(&rbuf, ipmip_netlink_nlmsghdr_put(&rbuf, IP_NULL, sizeof(*msg)));
msg->mip_family = IP_AF_INET;
msg->mip_type = IP_WRMOB4_DEL_LINK_RX;
msg->mip_flags = 0;
/* Create the nested HoA attribute */
hdr_off = ipmip_netlink_nlmsghdr_rta_begin(&rbuf, IP_MIP_ENCAP);
ipmip_netlink_nlmsghdr_rta_put(&rbuf, IP_WRMOB4_ROUTE_DST, 4, &node->mib.faVisitorHomeAddress.s_addr);
ipmip_netlink_nlmsghdr_rta_put_u32(&rbuf, IP_WRMOB4_ROUTE_DST_LEN, 32);
ipmip_netlink_nlmsghdr_rta_put_u32(&rbuf, IP_WRMOB4_ROUTE_TABLE, node->ifp->fwd_table);
/* Route a binding */
ipmip_netlink_nlmsghdr_rta_put_u32(&rbuf, IP_WRMOB4_ROUTE_IFINDEX, node->ifp->tunnels[node->faVisitorTunnelType]->ipmip.ifindex);
ipmip_netlink_nlmsghdr_rta_put_u32(&rbuf, IP_WRMOB4_ROUTE_FLAGS, IPMIP_RTF_TUNNELEND);
ipmip_netlink_nlmsghdr_rta_put(&rbuf, IP_WRMOB4_ROUTE_GW, 4, &node->reginfo.faVisitorRoute->lla[0]);
/* Identity */
handle.mip_facility = IPCOM_IPD_ID_IPMIPFA;
handle.mip_ident = node->faVisitorIdentity;
ipmip_netlink_nlmsghdr_rta_put(&rbuf, IP_WRMOB4_ROUTE_HANDLE, sizeof(handle), &handle);
ipmip_netlink_nlmsghdr_rta_end(&rbuf, hdr_off);
/* Complete the buffer */
ipmip_netlink_nlmsghdr_done(&rbuf, 0);
/* NETLINK request */
ret = ipmip_netlink_request(&ctx->ipmip4.ipmip,
proc,
ctx->ipmip4.ipmip.nl_req,
0,
0,
(struct Ip_nlmsghdr *)IPMIP_BUFFER_PTR(&rbuf),
IP_NULL);
/**/
ipmip_buffer_release(&rbuf);
if (ret < 0)
{
IPMIP4_EVENT_IF(ERR, proc,
ipmip_log_event_add(&ctx->ipmip4.ipmip,
proc,
"Unable to perform Foreign Agent DEL LINK RECV = %d", -ret));
}
return ret;
}
/*
*===========================================================================
* ipmipfa_route_local_mac
*===========================================================================
* Description: Add or delete a forward route for a specific node.
* Parameters: data - Context
* proc - Process
* cmd - Command
* iff - The interface we'll force this traffic by.
* dst - The address destination.
* lla - The LLA address of the node.
* Returns:
*
*/
IP_STATIC void
ipmipfa_route_local_mac(Ipmipfa_data_t *data,
Ipmip_proc_t *proc,
Ip_bool add,
struct Ipmipfa_node *node)
{
/* */
IPCOM_LOG4(DEBUG2, "%s MN route %s -> mac=%s on %s",
add? "adding" : "deleting",
ipmip_ntop_inet(proc, node->mib.faVisitorHomeAddress.s_addr),
ipmip_ntop_lladdr(proc, node->reginfo.faVisitorRoute),
node->ifp->iff.ipmip.ifname);
if (add)
ipmipfa_netlink_new_link_recv2mac(data, proc, node);
else
ipmipfa_netlink_del_link_recv2mac(data, proc, node);
}
/*
*===========================================================================
* ipmipfa_route_local_fa
*===========================================================================
* Description: Add or delete a tunnel route between FA's
* Parameters: add - IP_TRUE if the route is to be added
* iff - The interface we'll force this traffic by.
* dst - The address destination.
* lla - The LLA address of the node.
* Returns:
*
*/
IP_STATIC void
ipmipfa_route_local_fa(Ipmipfa_data_t *data,
Ipmip_proc_t *proc,
Ip_bool add,
struct Ipmipfa_node *node)
{
/* */
IPCOM_LOG5(DEBUG2, "%s MN route %s tunneled through %s at %s [REQ SRC = %s]",
add? "adding" : "deleting",
ipmip_ntop_inet(proc, node->mib.faVisitorHomeAddress.s_addr),
ipmip_ntop_inet(proc, IP_GET_32ON8(&node->reginfo.faVisitorRoute->lla[0])),
node->ifp->iff.ipmip.ifname,
ipmip_ntop_inet(proc, node->faVisitorTunnelingEndpoint));
if (add)
ipmipfa_netlink_new_link_recv2tunnel(data, proc, node);
else
ipmipfa_netlink_del_link_recv2tunnel(data, proc, node);
}
/*
****************************************************************************
* 10 GLOBAL FUNCTIONS
****************************************************************************
*/
/*
*===========================================================================
* Ipmipfa_route_context_t
*===========================================================================
* Description: Allocate a route context
* Parameters: data - Context
* proc - Process
* Returns: IP_TRUE on success
*
*/
IP_GLOBAL Ip_bool
ipmipfa_route_context_alloc(Ipmipfa_data_t *data,
Ipmip_proc_t *proc)
{
Ip_u32 loopback = ip_htonl(IP_INADDR_LOOPBACK);
data->route = ipcom_calloc(1, sizeof(Ipmipfa_route_context_t));
if (data->route == IP_NULL)
return IP_FALSE;
data->route->blk_table = ipmip_util_route_table_alloc(&data->ipmip4.ipmip, proc);
/* Add the blackhole route */
ipmip_netlink_inX_route(&data->ipmip4.ipmip,
proc,
IP_AF_INET,
IP_RTM_NEWROUTE,
data->route->blk_table,
0,
IP_NULL,
0,
&loopback,
IP_RTN_BLACKHOLE);
return IP_TRUE;
}
/*
*===========================================================================
* ipmipfa_route_context_destroy
*===========================================================================
* Description: Destroy a route context
* Parameters: data - Context
* proc - Process
* Returns:
*
*/
IP_GLOBAL void
ipmipfa_route_context_destroy(Ipmipfa_data_t *data,
Ipmip_proc_t *proc)
{
if (data->route)
{
ipmip_util_route_table_free(&data->ipmip4.ipmip, proc, data->route->blk_table);
ipcom_free(data->route);
data->route = IP_NULL;
}
}
/*
*===========================================================================
* ipmipfa_route_local
*===========================================================================
* Description: Add or delete a forward route for a specific node.
* Parameters: data - Context
* proc - Process
* cmd - command
* iff - The interface we'll force this traffic by.
* dst - The address destination.
* lla - The LLA address of the node.
* Returns:
*
*/
IP_GLOBAL Ip_bool
ipmipfa_route_local(Ipmipfa_data_t *data,
Ipmip_proc_t *proc,
Ip_bool add,
struct Ipmipfa_node *node)
{
/* We need the tunneling endpoint */
if (node->faVisitorTunnelingEndpoint == 0)
return IP_FALSE;
/* Only handle MAC's right now */
switch (node->reginfo.faVisitorRoute->type)
{
case IPMIP_LLADDR_TYPE_MAC:
ipmipfa_route_local_mac(data, proc, add, node);
break;
case IPMIP_LLADDR_TYPE_INET:
ipmipfa_route_local_fa(data, proc, add, node);
break;
}
return IP_TRUE;
}
/*
*===========================================================================
* ipmipfa_route_tunnel
*===========================================================================
* Description: Setup the tunnel for a specific node.
* Parameters: add - IP_TRUE if we're to add a tunnel route.
* node - The node we're dealing with
* nat_t - Is NAT-T enabled or not
* Returns:
*
*/
IP_GLOBAL void
ipmipfa_route_tunnel(Ipmipfa_data_t *data,
Ipmip_proc_t *proc,
Ip_bool add,
Ipmipfa_node_t *node,
Ip_bool nat_t)
{
Ipmip4_if_t *tunnel = IP_NULL;
Ipmipfa_iff_t *iff = node->ifp;
/* Locate the correct interface */
tunnel = iff->tunnels[node->faVisitorTunnelType];
/* Bad type or interface doesn't exist */
if (tunnel == IP_NULL || tunnel->ipmip.ifindex == 0)
{
IPCOM_LOG4(ERR, "%s MN tunnel %s -> through %s on %s -- FAILED (bad tunnel)",
add? "adding" : "deleting",
ipmip_ntop_inet(proc, node->mib.faVisitorHomeAddress.s_addr),
ipmip_ntop_inet(proc, node->faVisitorTunnelingEndpoint),
tunnel? tunnel->ipmip.ifname : "<unknown>");
return;
}
/* */
IPCOM_LOG6(DEBUG2, "%s MN tunnel %s -> through %s on %s %s [REQ SRC = %s]",
add? "adding" : "deleting" ,
ipmip_ntop_inet(proc, node->mib.faVisitorHomeAddress.s_addr),
ipmip_ntop_inet(proc, node->faVisitorTunnelingEndpoint),
tunnel->ipmip.ifname,
nat_t? "[RFC3519 NAT-T]" : "",
ipmip_ntop_lladdr(proc, node->reginfo.faVisitorRoute));
if (add)
ipmipfa_netlink_new_link_send(data, proc, node, IPMIP_RTF_TUNNELEND);
else
ipmipfa_netlink_del_link_send(data, proc, node);
}
/*
*===========================================================================
* ipmipfa_route_skip
*===========================================================================
* Description: Setup the skip route for a specific node.
* Parameters: add - IP_TRUE if we're to add a tunnel route.
* node - The node we're dealing with
* Returns:
*
*/
IP_GLOBAL void
ipmipfa_route_skip(Ipmipfa_data_t *data,
Ipmip_proc_t *proc,
Ip_bool add,
Ipmipfa_node_t *node)
{
Ipmip4_if_t *tunnel = IP_NULL;
Ipmipfa_iff_t *iff = node->ifp;
/* Locate the correct interface */
tunnel = iff->tunnels[node->faVisitorTunnelType];
/* Bad type or interface doesn't exist */
if (tunnel == IP_NULL || tunnel->ipmip.ifindex == 0)
{
IPCOM_LOG4(ERR, "%s MN skip %s -> attached to %s on %s -- FAILED (bad tunnel)",
add? "adding" : "deleting",
ipmip_ntop_inet(proc, node->mib.faVisitorHomeAddress.s_addr),
ipmip_ntop_inet(proc, node->faVisitorTunnelingEndpoint),
tunnel->ipmip.ifname);
return;
}
/* */
IPCOM_LOG4(DEBUG2, "%s MN skip %s -> attached to %s on %s",
add? "adding" : "deleting",
ipmip_ntop_inet(proc, node->mib.faVisitorHomeAddress.s_addr),
ipmip_ntop_inet(proc, node->faVisitorTunnelingEndpoint),
tunnel->ipmip.ifname);
if (add)
ipmipfa_netlink_new_link_send(data, proc, node, IPMIP_RTF_SKIP);
else
ipmipfa_netlink_del_link_send(data, proc, node);
}
IP_GLOBAL int
ipmipfa_netlink_new_handle(struct Ipmipfa_data *ctx,
struct Ipmip_proc *proc,
struct Ipmipfa_node *node)
{
/**/
return ipmip4_netlink_new_handle(&ctx->ipmip4, proc, IPCOM_IPD_ID_IPMIPFA, node->faVisitorIdentity);
}
IP_GLOBAL int
ipmipfa_netlink_del_handle(struct Ipmipfa_data *ctx,
struct Ipmip_proc *proc,
struct Ipmipfa_node *node)
{
/**/
return ipmip4_netlink_del_handle(&ctx->ipmip4, proc, IPCOM_IPD_ID_IPMIPFA, node->faVisitorIdentity);
}
IP_GLOBAL Ip_bool
ipmipfa_netlink_get_handle_stat(struct Ipmipfa_data *ctx,
struct Ipmip_proc *proc,
struct Ipmipfa_node *node)
{
Ipmip4_netlink_kern_statistics_t link_recv, link_send;
Ipmip_netlink_kern_handle_t handle;
/* Identity */
handle.mip_facility = IPCOM_IPD_ID_IPMIPFA;
handle.mip_ident = node->faVisitorIdentity;
if (ipmip4_netlink_get_handle_stat(&ctx->ipmip4, proc, &handle, &link_recv, &link_send))
{
/* Update stats */
IP_U64_ADD32(node->faVisitorSndOctets, link_send.mip_s_octets);
IP_U64_ADD32(node->faVisitorSndPkts, link_send.mip_s_pkts);
/* Update stats */
IP_U64_ADD32(node->faVisitorRcvOctets, link_recv.mip_s_octets);
IP_U64_ADD32(node->faVisitorRcvPkts, link_recv.mip_s_pkts);
return IP_TRUE;
}
return IP_FALSE;
}
/*
****************************************************************************
* 11 PUBLIC FUNCTIONS
****************************************************************************
*/
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/
@@ -0,0 +1,301 @@
/* ipmipfa_route.h - ipmipfa_route.h */
/*
******************************************************************************
* HEADER FILE
*
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmipfa_route.h,v $ $Revision: 1.9 $
* $Source: /home/interpeak/CVSRoot/ipmipfa/src/ipmipfa_route.h,v $
* $Author: jhorteli $ $Date: 2010-10-15 11:28:07 $
* $State: Exp $ $Locker: $
*
* INTERPEAK_COPYRIGHT_STRING
* Design and implementation by Joel Hortelius <joel.hortelius@interpeak.se>
******************************************************************************
*/
#ifndef IPMIPFA_ROUTE_H
#define IPMIPFA_ROUTE_H
/*
****************************************************************************
* 1 DESCRIPTION
****************************************************************************
*/
/*
DESCRIPTION
No description currently provided
*/
/*
****************************************************************************
* 2 CONFIGURATION
****************************************************************************
*/
/*
****************************************************************************
* 3 INCLUDE FILES
****************************************************************************
*/
#ifdef __cplusplus
extern "C" {
#endif
/*
****************************************************************************
* 4 DEFINES
****************************************************************************
*/
#define IPMIPFA_ROUTE_BASE_PRID (100)
#define IPMIPFA_ROUTE_PRID(x) (IPMIPFA_ROUTE_BASE_PRID + (x))
/*
****************************************************************************
* 5 TYPES
****************************************************************************
*/
struct Ipmipfa_data;
struct Ipmipfa_iff;
struct Ipmipfa_node;
struct Ipnet_policy_routing_rule;
typedef struct Ipmipfa_route_context
{
struct Ipmipfa_data *data;
/* */
Ip_u32 fwd_table; /* Basic forwarding table */
Ip_u32 blk_table; /* Home agent routing table */
#if 0
Ip_u32 tnl_if_rule_id;
Ip_u32 fwd_fa_rule_id;
#endif
} Ipmipfa_route_context_t;
/*
****************************************************************************
* 6 FUNCTIONS
****************************************************************************
*/
/*******************************************************************************
*
* ipmipfa_route_context_alloc - ipmipfa_route_context_alloc
*
* Allocate a route context
*
* Parameters:
* \is
* \i data
* The FA context
* \i proc
* Current process
* \ie
*
* RETURNS: IP_TRUE on success
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL Ip_bool ipmipfa_route_context_alloc
(
struct Ipmipfa_data *data,
struct Ipmip_proc *proc
);
/*******************************************************************************
*
* ipmipfa_route_context_destroy - ipmipfa_route_context_destroy
*
* Destroy a route context
*
* Parameters:
* \is
* \i data
* Context
* \i proc
* Process
* \ie
*
* RETURNS: No return value
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL void ipmipfa_route_context_destroy
(
struct Ipmipfa_data *data,
struct Ipmip_proc *proc
);
/*******************************************************************************
*
* ipmipfa_route_policy_init - ipmipfa_route_policy_init
*
* Initialize a routing policy rule based on a routing
* table.
*
* Parameters:
* \is
* \i rule
* The rule to initialize.
* \i table
* The table to initialize it to.
* \ie
*
* RETURNS: No return value
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL void ipmipfa_route_policy_init
(
struct Ipnet_policy_routing_rule *rule,
Ip_u32 table
);
/*******************************************************************************
*
* ipmipfa_route_local - ipmipfa_route_local
*
* Add or delete a forward route for a specific node.
*
* Parameters:
* \is
* \i data
* Context
* \i proc
* Process
* \i add
* IP_TRUE to add, IP_FALSE to delete.
* \i node
* The node to route for
* \ie
*
* RETURNS: IP_TRUE if the route was successfully processed
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL Ip_bool ipmipfa_route_local
(
struct Ipmipfa_data *data,
struct Ipmip_proc *proc,
Ip_bool add,
struct Ipmipfa_node *node
);
/*******************************************************************************
*
* ipmipfa_route_tunnel - ipmipfa_route_tunnel
*
* Setup the tunnel for a specific node.
*
* Parameters:
* \is
* \i data
* Context
* \i proc
* Current process.
* \i add
* IP_TRUE to add, IP_FALSE to delete.
* \i node
* The node we're dealing with
* \i nat_t
* Is NAT-T enabled or not.
* \ie
*
* RETURNS: No return value
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL void ipmipfa_route_tunnel
(
struct Ipmipfa_data *data,
struct Ipmip_proc *proc,
Ip_bool add,
struct Ipmipfa_node *node,
Ip_bool nat_t
);
/*******************************************************************************
*
* ipmipfa_route_skip - ipmipfa_route_skip
*
* Setup the skip route for a specific node.
*
* Parameters:
* \is
* \i data
* Context
* \i proc
* Current process
* \i add
* IP_TRUE to add, IP_FALSE to delete
* \i node
* The node we're dealing with
* \ie
*
* RETURNS: No return value
*
* ERRNO:
*
* \NOMANUAL
*/
IP_GLOBAL void ipmipfa_route_skip
(
struct Ipmipfa_data *data,
struct Ipmip_proc *proc,
Ip_bool add,
struct Ipmipfa_node *node
);
IP_GLOBAL int ipmipfa_netlink_new_handle
(
struct Ipmipfa_data *ctx,
struct Ipmip_proc *proc,
struct Ipmipfa_node *node
);
IP_GLOBAL int ipmipfa_netlink_del_handle
(
struct Ipmipfa_data *ctx,
struct Ipmip_proc *proc,
struct Ipmipfa_node *node
);
IP_GLOBAL Ip_bool ipmipfa_netlink_get_handle_stat
(
struct Ipmipfa_data *ctx,
struct Ipmip_proc *proc,
struct Ipmipfa_node *node
);
#ifdef __cplusplus
}
#endif
#endif
/*
****************************************************************************
* END OF FILE
****************************************************************************
*/