756 lines
30 KiB
C
756 lines
30 KiB
C
|
|
/*
|
|
******************************************************************************
|
|
* INTERPEAK SOURCE FILE
|
|
*
|
|
* Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmip6ha_attr.c,v $ $Revision: 1.27 $
|
|
* $Source: /home/interpeak/CVSRoot/ipmip6ha/src/ipmip6ha_attr.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 "ipmip6ha_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 <ipmip6.h>
|
|
#include <private/ipmip6_context.h>
|
|
#include <private/ipmip6_icmp_pkt.h>
|
|
#include <private/ipmip6_mh.h>
|
|
#include <private/ipmip6_mh_pkt.h>
|
|
#include <private/ipmip6_if.h>
|
|
#include <private/ipmip6_attr.h>
|
|
#include <private/ipmip6_util.h>
|
|
|
|
#include "ipmip6ha_h.h"
|
|
#include "ipmip6ha_attr.h"
|
|
#include "ipmip6ha_attr_h.h"
|
|
#include "ipmip6ha_node.h"
|
|
#include "ipmip6ha_nemo.h"
|
|
#include "ipmip6ha_nemo_dsmipv6.h"
|
|
#include "ipmip6ha_if.h"
|
|
#include "ipmip6ha_route.h"
|
|
#include "ipmip6ha_mag.h"
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 4 DEFINES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 5 TYPES
|
|
****************************************************************************
|
|
*/
|
|
struct Ipmip6ha_attr_op
|
|
{
|
|
Ipmip_cli_message_t *request;
|
|
struct Ip_in6_addr *hoa;
|
|
const char *nai_mn;
|
|
Ip_size_t nai_mn_len;
|
|
Ip_u32 ifindex;
|
|
};
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 6 EXTERN PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 7 LOCAL PROTOTYPES
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 8 DATA
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 9 STATIC FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipmipfa_node_del_cb
|
|
*===========================================================================
|
|
* Description:
|
|
* Parameters:
|
|
* Returns:
|
|
*
|
|
*/
|
|
IP_STATIC void
|
|
ipmip6ha_attr_list_nodes(Ipmip6ha_context_t *ctx,
|
|
Ipmip_proc_t *proc,
|
|
Ipmip6ha_node_t *node,
|
|
struct Ipmip6ha_attr_op *ops,
|
|
void *unused)
|
|
{
|
|
IPMIP_UNUSED_PARAMETER(ctx);
|
|
IPMIP_UNUSED_PARAMETER(proc);
|
|
IPMIP_UNUSED_PARAMETER(unused);
|
|
|
|
if (ops->hoa != IP_NULL && !IP_IN6_ARE_ADDR_EQUAL(ops->hoa, &node->mip6BindingCacheEntry.mip6BindingHomeAddress.ipv6))
|
|
return;
|
|
|
|
if (ops->nai_mn != IP_NULL && ops->nai_mn_len > 0)
|
|
{
|
|
/* Check NAI */
|
|
Ipmip6_mh_mo_nai_t *nai = (Ipmip6_mh_mo_nai_t *)node->nai_mn;
|
|
|
|
if (!nai)
|
|
return;
|
|
|
|
/* Does the NAI match? */
|
|
if (!ipmip_util_strnnmatch(ops->nai_mn, ops->nai_mn_len, (char *)&nai->nai[0], (Ip_size_t)(nai->hdr.len - 1)))
|
|
return;
|
|
}
|
|
|
|
if (ops->ifindex != 0 && ops->ifindex != node->ifp_home->ipmip6.iff.ifindex)
|
|
return;
|
|
|
|
/**/
|
|
ipmip_attr_put_u32(&ops->request->message, IPMIP6HA_CLI_ATTR_BC_X_HANDLE, node->identity);
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipmip6ha_attr_node_dump
|
|
*===========================================================================
|
|
* Description: Dump a node
|
|
* Parameters: event - Current event
|
|
* data - Data
|
|
* proc - Current process
|
|
* lock - Command locking structure
|
|
* node - Node.
|
|
* Returns: IP_FALSE
|
|
*
|
|
*/
|
|
IP_STATIC int
|
|
ipmip6ha_attr_node_dump(Ipmip6ha_context_t *ctx,
|
|
Ipmip_proc_t *proc,
|
|
Ipmip_cli_message_t *request,
|
|
Ipmip6ha_node_t *node)
|
|
{
|
|
struct Ipmip_attr_header *hdr = (struct Ipmip_attr_header *)IPMIP_BUFFER_DATA(&request->request);
|
|
Ip_size_t rhdr = 0;
|
|
Ip_size_t rta;
|
|
|
|
if (node == IP_NULL)
|
|
rhdr = ipmip_attr_hdr_err(&request->message, hdr, IP_ERRNO_ENOENT, IP_NULL);
|
|
else
|
|
{
|
|
/**/
|
|
rhdr = ipmip_attr_hdr_ack(&request->message, hdr);
|
|
|
|
/* Do retrieve statistics */
|
|
ipmip6ha_netlink_get_handle_stat(ctx, proc, node);
|
|
|
|
/**/
|
|
rta = ipmip_attr_begin(&request->message, IPMIP6HA_CLI_ATTR_BC_X);
|
|
|
|
/* */
|
|
if (!IP_IN6_IS_ADDR_UNSPECIFIED(&node->mip6BindingCacheEntry.mip6BindingHomeAddress.ipv6))
|
|
ipmip_attr_put_inet6(&request->message, IPMIP6HA_CLI_ATTR_BC_X_HOA_V6, &node->mip6BindingCacheEntry.mip6BindingHomeAddress.ipv6);
|
|
|
|
/* Put the home address entry */
|
|
ipmip_attr_put_str(&request->message, IPMIP6HA_CLI_ATTR_BC_X_IFNAME,node->ifp_home->ipmip6.iff.ifname);
|
|
ipmip_attr_put_time_t(&request->message, IPMIP6HA_CLI_ATTR_BC_X_UPDATED, node->updated);
|
|
ipmip_attr_put_u32(&request->message, IPMIP6HA_CLI_ATTR_BC_X_REGFLAGS, node->regflags);
|
|
ipmip_attr_put_u32(&request->message, IPMIP6HA_CLI_ATTR_BC_X_HANDLE, node->identity);
|
|
|
|
if (node->nemo_v6.size > 0
|
|
#ifdef IPMIP_USE_INET
|
|
|| node->nemo_hoa_v4.size > 0 || node->nemo_prefix_v4.size > 0
|
|
#endif
|
|
)
|
|
{
|
|
Ipmip6ha_nemo_t *nemo;
|
|
#ifdef IPMIP_USE_INET
|
|
Ipmip6ha_nemo_dsmipv6_t *dsmipv6;
|
|
#endif
|
|
Ipmip_buffer_t pdata;
|
|
|
|
ipmip_buffer_init(&pdata);
|
|
for (nemo = IPCOM_LIST_FIRST(&node->nemo_v6); nemo != IP_NULL; nemo = IPCOM_LIST_NEXT(&nemo->next))
|
|
{
|
|
Ipmip6_address_t address;
|
|
|
|
ipcom_memcpy(&address.prefix, &nemo->prefix, sizeof(address.prefix));
|
|
address.len = nemo->len;
|
|
|
|
ipmip_buffer_append(&pdata, &address, sizeof(address));
|
|
}
|
|
|
|
if (IPMIP_BUFFER_SIZE(&pdata))
|
|
{
|
|
ipmip_attr_put(&request->message, IPMIP6HA_CLI_ATTR_BC_X_PREFIX_V6,(Ip_u32)IPMIP_BUFFER_SIZE(&pdata),IPMIP_BUFFER_DATA(&pdata));
|
|
ipmip_buffer_shrink(&pdata, 0);
|
|
}
|
|
#ifdef IPMIP_USE_INET
|
|
for (dsmipv6 = IPCOM_LIST_FIRST(&node->nemo_prefix_v4); dsmipv6 != IP_NULL; dsmipv6 = IPCOM_LIST_NEXT(&dsmipv6->next))
|
|
{
|
|
Ipmip6_inet_t address;
|
|
|
|
address.prefix = dsmipv6->prefix;
|
|
address.len = (Ip_u8)dsmipv6->len;
|
|
|
|
ipmip_buffer_append(&pdata, &address, sizeof(address));
|
|
}
|
|
|
|
if (IPMIP_BUFFER_SIZE(&pdata))
|
|
{
|
|
ipmip_attr_put(&request->message, IPMIP6HA_CLI_ATTR_BC_X_PREFIX_V4,(Ip_u32)IPMIP_BUFFER_SIZE(&pdata),IPMIP_BUFFER_DATA(&pdata));
|
|
ipmip_buffer_shrink(&pdata, 0);
|
|
}
|
|
|
|
for (dsmipv6 = IPCOM_LIST_FIRST(&node->nemo_hoa_v4); dsmipv6 != IP_NULL; dsmipv6 = IPCOM_LIST_NEXT(&dsmipv6->next))
|
|
ipmip_buffer_append(&pdata, &dsmipv6->prefix, sizeof(dsmipv6->prefix));
|
|
|
|
if (IPMIP_BUFFER_SIZE(&pdata))
|
|
{
|
|
ipmip_attr_put(&request->message, IPMIP6HA_CLI_ATTR_BC_X_HOA_V4,(Ip_u32)IPMIP_BUFFER_SIZE(&pdata),IPMIP_BUFFER_DATA(&pdata));
|
|
ipmip_buffer_shrink(&pdata, 0);
|
|
}
|
|
#endif
|
|
/* Free memory */
|
|
ipmip_buffer_release(&pdata);
|
|
}
|
|
|
|
/* Add the MO for MN NAI */
|
|
if (node->nai_mn != IP_NULL)
|
|
ipmip_attr_put_strn(&request->message, IPMIP6HA_CLI_ATTR_BC_X_MOBILE_NAI,(char *)&((Ipmip6_mh_mo_nai_t *)node->nai_mn)->nai[0], (Ip_size_t)(node->nai_mn->len - 1));
|
|
|
|
/**/
|
|
ipmip_attr_put(&request->message, IPMIP6HA_CLI_ATTR_BC_X_MIB_mip6BindingCacheEntry, sizeof(node->mip6BindingCacheEntry), &node->mip6BindingCacheEntry);
|
|
ipmip_attr_put(&request->message, IPMIP6HA_CLI_ATTR_BC_X_MIB_mip6NodeTrafficEntry, sizeof(node->mip6NodeTrafficEntry), &node->mip6NodeTrafficEntry);
|
|
|
|
ipmip_attr_end(&request->message, rta);
|
|
}
|
|
|
|
/* If we have a reply header; terminate it */
|
|
ipmip_attr_hdr_finalize(&request->message, rhdr);
|
|
|
|
/* Commit the reply */
|
|
ipmip_cli_message_commit(&ctx->ipmip6.ipmip, proc, request);
|
|
return IPMIP_TIMER_RET_DONE;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipmip6ha_attr_node_delete
|
|
*===========================================================================
|
|
* Description: Dump a node
|
|
* Parameters: event - Current event
|
|
* data - Data
|
|
* proc - Current process
|
|
* lock - Command locking structure
|
|
* node - Node.
|
|
* Returns: IP_FALSE
|
|
*
|
|
*/
|
|
IP_STATIC int
|
|
ipmip6ha_attr_node_delete(Ipmip6ha_context_t *ctx,
|
|
Ipmip_proc_t *proc,
|
|
Ipmip_cli_message_t *request,
|
|
Ipmip6ha_node_t *node)
|
|
{
|
|
struct Ipmip_attr_header *hdr = (struct Ipmip_attr_header *)IPMIP_BUFFER_DATA(&request->request);
|
|
|
|
/**/
|
|
ipmip_attr_hdr_finalize(&request->message, ipmip_attr_hdr_ack(&request->message, hdr));
|
|
/* Commit the reply */
|
|
ipmip_cli_message_commit(&ctx->ipmip6.ipmip, proc, request);
|
|
|
|
/* Terminate the node(s) */
|
|
ipmip6ha_node_delete(ctx, proc, node, "administrative termination");
|
|
|
|
return IPMIP_TIMER_RET_DONE;
|
|
}
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipmip6ha_attr_node_delete
|
|
*===========================================================================
|
|
* Description: Dump a node
|
|
* Parameters: event - Current event
|
|
* data - Data
|
|
* proc - Current process
|
|
* lock - Command locking structure
|
|
* node - Node.
|
|
* Returns: IP_FALSE
|
|
*
|
|
*/
|
|
IP_STATIC int
|
|
ipmip6ha_attr_node_revoke(Ipmip6ha_context_t *ctx,
|
|
Ipmip_proc_t *proc,
|
|
Ipmip_cli_message_t *request,
|
|
Ipmip6ha_node_t *node,
|
|
Ip_bool inet)
|
|
{
|
|
struct Ipmip_attr_header *hdr = (struct Ipmip_attr_header *)IPMIP_BUFFER_DATA(&request->request);
|
|
Ip_size_t rhdr = 0;
|
|
int ret = IPMIP_TIMER_RET_DONE;
|
|
if (node == IP_NULL)
|
|
rhdr = ipmip_attr_hdr_err(&request->message, hdr, IP_ERRNO_ENOENT, IP_NULL);
|
|
else
|
|
{
|
|
struct Ipmip_attr *rta_reason = ipmip_attr_hdr_find(hdr, IPMIP6HA_CLI_ATTR_BC_X_REVOKE_REASON);
|
|
Ip_u8 reason = IPMIP6_MH_BRI_TRIGGER_ADMINISTRATIVE_REASON;
|
|
|
|
/**/
|
|
if (rta_reason != IP_NULL)
|
|
reason = (Ip_u8)ipmip_attr_get_u32(rta_reason);
|
|
|
|
/**/
|
|
rhdr = ipmip_attr_hdr_ack(&request->message, hdr);
|
|
|
|
|
|
/* Terminate the node(s) */
|
|
ret = ipmip6ha_node_revoke(ctx, proc, node, inet, reason, IP_NULL);
|
|
}
|
|
|
|
/* If we have a reply header; terminate it */
|
|
ipmip_attr_hdr_finalize(&request->message, rhdr);
|
|
|
|
/* Commit the reply */
|
|
ipmip_cli_message_commit(&ctx->ipmip6.ipmip, proc, request);
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
/*
|
|
*===========================================================================
|
|
* ipmip6mn_attr_network_dump
|
|
*===========================================================================
|
|
* Description: Dump a node
|
|
* Parameters: event - Current event
|
|
* data - Data
|
|
* proc - Current process
|
|
* lock - Command locking structure
|
|
* node - Node.
|
|
* Returns: IP_FALSE
|
|
*
|
|
*/
|
|
IP_STATIC int
|
|
ipmip6ha_attr_node_do(int event,
|
|
Ipmip6ha_context_t *ctx,
|
|
Ipmip_proc_t *proc,
|
|
Ipmip_cli_message_t *request,
|
|
Ipmip6ha_node_t *node)
|
|
{
|
|
if (event == IPMIP_TIMER_EVENT_RUN)
|
|
{
|
|
struct Ipmip_attr_header *hdr = (struct Ipmip_attr_header *)IPMIP_BUFFER_DATA(&request->request);
|
|
switch (IPMIP_ATTR_HDR_TYPE(hdr))
|
|
{
|
|
case IPMIP6HA_CLI_BC_X_GET:
|
|
return ipmip6ha_attr_node_dump(ctx, proc, request, node);
|
|
case IPMIP6HA_CLI_BC_X_DELETE:
|
|
return ipmip6ha_attr_node_delete(ctx, proc, request, node);
|
|
case IPMIP6HA_CLI_BC_X_REVOKE_NODE:
|
|
return ipmip6ha_attr_node_revoke(ctx, proc, request, node, IP_FALSE);
|
|
case IPMIP6HA_CLI_BC_X_REVOKE_NODE_INET:
|
|
return ipmip6ha_attr_node_revoke(ctx, proc, request, node, IP_TRUE);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* Free the request */
|
|
ipmip_cli_message_free(&ctx->ipmip6.ipmip, proc, request);
|
|
}
|
|
|
|
/**/
|
|
return IPMIP_TIMER_RET_DONE;
|
|
}
|
|
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 10 GLOBAL FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
|
|
IP_GLOBAL int
|
|
ipmip6ha_attr_command(struct Ipmip6ha_context *ctx,
|
|
struct Ipmip_proc *proc,
|
|
struct Ipmip_cli_message *request)
|
|
{
|
|
struct Ipmip_attr_header *hdr = (struct Ipmip_attr_header *)IPMIP_BUFFER_DATA(&request->request);
|
|
Ip_size_t rhdr = 0;
|
|
struct Ipmip_attr *idattr[IPMIP6HA_CLI_ATTR_BC_X_MAX + 1];
|
|
|
|
|
|
switch (IPMIP_ATTR_HDR_TYPE(hdr))
|
|
{
|
|
case IPMIP6HA_CLI_BC_X_LIST:
|
|
{
|
|
struct Ipmip6ha_attr_op aop;
|
|
Ip_bool do_nai;
|
|
|
|
ipcom_memset(&aop, 0, sizeof(aop));
|
|
|
|
aop.request = request;
|
|
|
|
ipmip_attr_hdr_parse(IPMIP6HA_CLI_ATTR_BC_X_MAX, hdr, idattr);
|
|
|
|
|
|
aop.hoa = ipmip_attr_get_inet6(idattr[IPMIP6HA_CLI_ATTR_BC_X_HOA_V6]);
|
|
|
|
if (idattr[IPMIP6HA_CLI_ATTR_BC_X_IFNAME])
|
|
aop.ifindex = ipcom_if_nametoindex(ipmip_attr_get_str(idattr[IPMIP6HA_CLI_ATTR_BC_X_IFNAME]));
|
|
|
|
/* NAI */
|
|
if (idattr[IPMIP6HA_CLI_ATTR_BC_X_MOBILE_NAI] != IP_NULL)
|
|
{
|
|
aop.nai_mn = IPMIP_ATTR_DATA(idattr[IPMIP6HA_CLI_ATTR_BC_X_MOBILE_NAI]);
|
|
aop.nai_mn_len = IPMIP_ATTR_PAYLOAD(idattr[IPMIP6HA_CLI_ATTR_BC_X_MOBILE_NAI]);
|
|
}
|
|
|
|
rhdr = ipmip_attr_hdr_ack(&request->message, hdr);
|
|
|
|
ipmip_context_id_lock(ctx->idents);
|
|
ipmip_context_id_foreach(&ctx->ipmip6.ipmip,
|
|
proc,
|
|
ctx->idents,
|
|
(Ipmip_util_hash_foreach_t)ipmip6ha_attr_list_nodes,
|
|
&aop,
|
|
&do_nai);
|
|
ipmip_context_id_unlock(ctx->idents);
|
|
}
|
|
break;
|
|
case IPMIP6HA_CLI_BC_X_GET:
|
|
case IPMIP6HA_CLI_BC_X_DELETE:
|
|
case IPMIP6HA_CLI_BC_X_REVOKE_NODE:
|
|
case IPMIP6HA_CLI_BC_X_REVOKE_NODE_INET:
|
|
{
|
|
struct Ipmip_attr *rta_handle = ipmip_attr_hdr_find(hdr, IPMIP6HA_CLI_ATTR_BC_X_HANDLE);
|
|
/**/
|
|
if (rta_handle == IP_NULL)
|
|
return -IP_ERRNO_EINVAL;
|
|
|
|
/* Get by identity */
|
|
ipmip6ha_node_lookup_handle(ctx,
|
|
proc,
|
|
ipmip_attr_get_u32(rta_handle),
|
|
&request->timer,
|
|
(Ipmip_timer_func_t)ipmip6ha_attr_node_do,
|
|
request);
|
|
return 0;
|
|
}
|
|
|
|
case IPMIP_CLI_NAME_LIST:
|
|
rhdr = ipmip_attr_hdr_ack(&request->message, hdr);
|
|
{
|
|
/* Dump each configuration item we've currently got in human readable form */
|
|
Ipmip6ha_if_notify_t *notify;
|
|
|
|
ipmip_attr_put_str(&request->message, IPMIP_CLI_ITEM_NAME, "global");
|
|
|
|
/* Clear any old interfaces */
|
|
for (notify = IPCOM_LIST_FIRST(&ctx->ifs); notify != IP_NULL; notify = IPCOM_LIST_NEXT(¬ify->next))
|
|
ipmip_attr_put_str(&request->message, IPMIP_CLI_ITEM_NAME, notify->ipmip6.ifp->iff.ifname);
|
|
}
|
|
break;
|
|
case IPMIP_CLI_CONFIG_GET:
|
|
rhdr = ipmip_attr_hdr_ack(&request->message, hdr);
|
|
|
|
{
|
|
/* Dump each configuration item we've currently got in human readable form */
|
|
Ipmip6ha_if_notify_t *notify;
|
|
unsigned int si;
|
|
|
|
struct Ipmip_attr *rta_name = ipmip_attr_hdr_find(hdr, IPMIP_CLI_ITEM_NAME);
|
|
|
|
if (rta_name == IP_NULL || ipcom_strcasecmp("global", ipmip_attr_get_str(rta_name)) == 0)
|
|
{
|
|
for (si = 0; si < ctx->extensions_num; si++)
|
|
{
|
|
if (ctx->extensions[si]->config_global != IP_NULL && ctx->extdata[si] != IP_NULL)
|
|
(*ctx->extensions[si]->config_global) (ctx, proc, IPMIP_CALLBACK_CONFIG_DUMP, ctx->extdata[si], request);
|
|
}
|
|
|
|
/* Dump the relay map */
|
|
ipmip6ha_dump_relay_map(ctx, proc, &request->message);
|
|
}
|
|
|
|
/* Clear any old interfaces */
|
|
for (notify = IPCOM_LIST_FIRST(&ctx->ifs); notify != IP_NULL; notify = IPCOM_LIST_NEXT(¬ify->next))
|
|
{
|
|
Ipmip6ha_if_t *ife = (Ipmip6ha_if_t *)notify->ipmip6.ifp;
|
|
|
|
if (rta_name != IP_NULL && ipcom_strcasecmp(ife->ipmip6.iff.ifname, ipmip_attr_get_str(rta_name)) != 0)
|
|
continue;
|
|
|
|
/**/
|
|
ipmip_cli_config_printf(&request->message,
|
|
"ipmip6ha.interface.%s.lifetime=%d",
|
|
ife->ipmip6.iff.ifname, ife->lifetime);
|
|
|
|
ipmip_cli_config_printf(&request->message,
|
|
"ipmip6ha.interface.%s.refresh=%d",
|
|
ife->ipmip6.iff.ifname, ife->refresh);
|
|
|
|
ipmip_cli_config_printf(&request->message,
|
|
"ipmip6ha.interface.%s.homeagent=%s",
|
|
ife->ipmip6.iff.ifname, ipmip_ntop_inet6(proc, &ife->ifaddr.prefix, IP_NULL));
|
|
|
|
#ifdef IPMIP_USE_INET
|
|
ipmip_cli_config_printf(&request->message,
|
|
"ipmip6ha.interface.%s.inet.homeagent=%s",
|
|
ife->ipmip6.iff.ifname, ipmip_ntop_inet(proc, ife->ifaddr_v4));
|
|
|
|
ipmip_cli_config_printf(&request->message,
|
|
"ipmip6ha.interface.%s.tunnel.inet.ipip=%s",
|
|
ife->ipmip6.iff.ifname, ife->ifenabled_H[IPMIP_TUNNELTYPE_IPIP]? "enabled" : "disabled");
|
|
|
|
ipmip_cli_config_printf(&request->message,
|
|
"ipmip6ha.interface.%s.LMA.inet.tunnel.ipip=%s",
|
|
ife->ipmip6.iff.ifname, ife->ifenabled_P[IPMIP_TUNNELTYPE_IPIP]? "enabled" : "disabled");
|
|
|
|
ipmip_cli_config_printf(&request->message,
|
|
"ipmip6ha.interface.%s.LMA.inet.tunnel.gre=%s",
|
|
ife->ipmip6.iff.ifname, ife->ifenabled_P[IPMIP_TUNNELTYPE_GRE]? "enabled" : "disabled");
|
|
|
|
ipmip_cli_config_printf(&request->message,
|
|
"ipmip6ha.interface.%s.inet.AcceptForcedIPv4UDPEncapsulationRequest=%s",
|
|
ife->ipmip6.iff.ifname, ife->AcceptForcedIPv4UDPEncapsulationRequest? "true" : "false");
|
|
|
|
ipmip_cli_config_printf(&request->message,
|
|
"ipmip6ha.interface.%s.inet.ForceIPv4UDPEncapsulation=%s",
|
|
ife->ipmip6.iff.ifname, ife->ForceIPv4UDPEncapsulation? "true" : "false");
|
|
|
|
ipmip_cli_config_printf(&request->message,
|
|
"ipmip6ha.interface.%s.inet.IPv4UDPEncapsulationNATTimeout=%u",
|
|
ife->ipmip6.iff.ifname, ife->IPv4UDPEncapsulationNATTimeout);
|
|
#endif
|
|
|
|
ipmip_cli_config_printf(&request->message,
|
|
"ipmip6ha.interface.%s.AcceptUDPTLVEncapsulation=%s",
|
|
ife->ipmip6.iff.ifname, ife->AcceptUDPTLVEncapsulation? "true" : "false");
|
|
|
|
ipmip_cli_config_printf(&request->message,
|
|
"ipmip6ha.interface.%s.tunnel.ip6ip6=%s",
|
|
ife->ipmip6.iff.ifname, ife->ifenabled_H[IPMIP_TUNNELTYPE_IP6IP6]? "enabled" : "disabled");
|
|
|
|
ipmip_cli_config_printf(&request->message,
|
|
"ipmip6ha.interface.%s.BRIMaxRetriesNumber=%d",
|
|
ife->ipmip6.iff.ifname, ife->BRIMaxRetriesNumber);
|
|
|
|
ipmip_cli_config_printf(&request->message,
|
|
"ipmip6ha.interface.%s.LMA.BindingRevocation=%s",
|
|
ife->ipmip6.iff.ifname, ife->BindingRevocationEnabled? "enabled" : "disabled");
|
|
|
|
ipmip_cli_config_printf(&request->message,
|
|
"ipmip6ha.interface.%s.MINDelayBRIs=%d",
|
|
ife->ipmip6.iff.ifname, ife->MINDelayBRIs);
|
|
|
|
ipmip_cli_config_printf(&request->message,
|
|
"ipmip6ha.interface.%s.LMA.tunnel.ip6ip6=%s",
|
|
ife->ipmip6.iff.ifname, ife->ifenabled_P[IPMIP_TUNNELTYPE_IP6IP6]? "enabled" : "disabled");
|
|
|
|
ipmip_cli_config_printf(&request->message,
|
|
"ipmip6ha.interface.%s.LMA.tunnel.gre=%s",
|
|
ife->ipmip6.iff.ifname, ife->ifenabled_P[IPMIP_TUNNELTYPE_GRE6]? "enabled" : "disabled");
|
|
|
|
ipmip_cli_config_printf(&request->message,
|
|
"ipmip6ha.interface.%s.LMA.MinDelayBeforeBCEDelete=%d",
|
|
ife->ipmip6.iff.ifname, ife->MinDelayBeforeBCEDelete);
|
|
|
|
ipmip_cli_config_printf(&request->message,
|
|
"ipmip6ha.interface.%s.LMA.MaxDelayBeforeNewBCEAssign=%d",
|
|
ife->ipmip6.iff.ifname, ife->MaxDelayBeforeNewBCEAssign);
|
|
|
|
ipmip_cli_config_printf(&request->message,
|
|
"ipmip6ha.interface.%s.LMA.TimestampValidityWindow=%d",
|
|
ife->ipmip6.iff.ifname, ife->TimestampValidityWindow);
|
|
|
|
ipmip_cli_config_printf(&request->message,
|
|
"ipmip6ha.interface.%s.LMA.TimestampBasedApproachInUse=%d",
|
|
ife->ipmip6.iff.ifname, ife->TimestampBasedApproachInUse? 1 : 0);
|
|
|
|
ipmip_cli_config_printf(&request->message,
|
|
"ipmip6ha.interface.%s.LMA.MobileNodeGeneratedTimestampInUse=%d",
|
|
ife->ipmip6.iff.ifname, ife->MobileNodeGeneratedTimestampInUse? 1 : 0);
|
|
|
|
ipmip_cli_config_printf(&request->message,
|
|
"ipmip6ha.interface.%s.AlwaysVerifyTunnelSrc=%s",
|
|
ife->ipmip6.iff.ifname, ife->AlwaysVerifyTunnelSrc? "enabled" : "disabled");
|
|
|
|
ipmip_cli_config_printf(&request->message,
|
|
"ipmip6ha.interface.%s.RelayBindings=%s",
|
|
ife->ipmip6.iff.ifname, ife->RelayBindings? "enabled" : "disabled");
|
|
|
|
ipmip6ha_mag_configure_dump(ctx, proc, ife, &request->message);
|
|
|
|
ipmip6ha_nemo_dump_config(ctx, proc, ife->nemo, ife->ipmip6.iff.ifname, &request->message);
|
|
|
|
for (si = 0; si < ctx->extensions_num; si++)
|
|
{
|
|
if (ctx->extensions[si]->config_ifp != IP_NULL)
|
|
(*ctx->extensions[si]->config_ifp) (ctx, proc, IPMIP_CALLBACK_CONFIG_DUMP, ife, ctx->extdata[si], ife->extdata[si], request);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* */
|
|
break;
|
|
case IPMIP6HA_CLI_PREFIX_GET:
|
|
rhdr = ipmip_attr_hdr_ack(&request->message, hdr);
|
|
{
|
|
Ipmip6ha_if_notify_t *notify;
|
|
/* Clear any old interfaces */
|
|
for (notify = IPCOM_LIST_FIRST(&ctx->ifs); notify != IP_NULL; notify = IPCOM_LIST_NEXT(¬ify->next))
|
|
{
|
|
Ipmip6ha_if_t *ifp = (Ipmip6ha_if_t *)notify->ipmip6.ifp;
|
|
Ipmip6_if_prefix_t *prefix;
|
|
Ipmip6_if_router_t *router;
|
|
|
|
ipmip_timer_lock_acquire(&ctx->ipmip6.ipmip, proc, ifp->ipmip6.iff_lock);
|
|
|
|
/* We have the address; do prefix matching */
|
|
for (router = IPCOM_LIST_FIRST(&ifp->ipmip6.routers); router != IP_NULL; router = IPCOM_LIST_NEXT(&router->next))
|
|
{
|
|
for (prefix = IPCOM_LIST_FIRST(&router->prefixes); prefix != IP_NULL; prefix = IPCOM_LIST_NEXT(&prefix->next))
|
|
{
|
|
if (IP_BIT_ISSET(prefix->flags, IPMIP6_ND_OPT_PI_FLAG_ONLINK))
|
|
{
|
|
Ip_size_t rta = ipmip_attr_begin(&request->message, IPMIP6HA_CLI_ATTR_PREFIX);
|
|
|
|
/* */
|
|
ipmip_attr_put(&request->message, IPMIP6HA_CLI_ATTR_PREFIX_PREFIX, sizeof(prefix->prefix), &prefix->prefix);
|
|
ipmip_attr_put_inet6(&request->message, IPMIP6HA_CLI_ATTR_PREFIX_ROUTER, &router->addr);
|
|
ipmip_attr_put_str(&request->message, IPMIP6HA_CLI_ATTR_PREFIX_IFNAME, ifp->ipmip6.iff.ifname);
|
|
ipmip_attr_put_time_t(&request->message, IPMIP6HA_CLI_ATTR_PREFIX_VALID, prefix->valid);
|
|
ipmip_attr_put_time_t(&request->message, IPMIP6HA_CLI_ATTR_PREFIX_TIMESTAMP, prefix->stamp);
|
|
ipmip_attr_end(&request->message, rta);
|
|
}
|
|
}
|
|
}
|
|
|
|
ipmip_timer_lock_release(&ctx->ipmip6.ipmip, proc, ifp->ipmip6.iff_lock);
|
|
}
|
|
|
|
}
|
|
break;
|
|
|
|
case IPMIP6HA_CLI_MAG_GET:
|
|
rhdr = ipmip_attr_hdr_ack(&request->message, hdr);
|
|
{
|
|
Ipmip6ha_if_notify_t *notify;
|
|
/* Clear any old interfaces */
|
|
for (notify = IPCOM_LIST_FIRST(&ctx->ifs); notify != IP_NULL; notify = IPCOM_LIST_NEXT(¬ify->next))
|
|
ipmip6ha_mag_attr_get(ctx, proc, (Ipmip6ha_if_t *)notify->ipmip6.ifp, &request->message);
|
|
}
|
|
break;
|
|
|
|
case IPMIP6HA_CLI_MAG_REVOKE:
|
|
/* Must locate MAG and */
|
|
{
|
|
const char *m_ifname = ipmip_attr_hdr_find_str(hdr, IPMIP6HA_CLI_ATTR_MAG_IFNAME);
|
|
struct Ip_in6_addr *m_addr = ipmip_attr_hdr_find_inet6(hdr, IPMIP6HA_CLI_ATTR_MAG_ADDR_V6);
|
|
Ipmip6ha_if_notify_t *notify;
|
|
Ipmip6ha_if_t *ife;
|
|
Ipmip6ha_mag_t *mag;
|
|
|
|
/**/
|
|
if (m_ifname == IP_NULL || m_addr == IP_NULL)
|
|
return -IP_ERRNO_EINVAL;
|
|
|
|
for (notify = IPCOM_LIST_FIRST(&ctx->ifs); notify != IP_NULL; notify = IPCOM_LIST_NEXT(¬ify->next))
|
|
{
|
|
ife = (Ipmip6ha_if_t *)notify->ipmip6.ifp;
|
|
if (ipcom_strcasecmp(ife->ipmip6.iff.ifname, m_ifname) == 0)
|
|
break;
|
|
}
|
|
|
|
if (notify == IP_NULL)
|
|
return -IP_ERRNO_ENXIO;
|
|
|
|
/* Time to find the MAG */
|
|
mag = ipmip6ha_mag_get(ctx, proc, ife, m_addr, 0);
|
|
if (mag == IP_NULL)
|
|
return -IP_ERRNO_ENOENT;
|
|
|
|
/* Time to revoke */
|
|
ipmip6ha_mag_revoke(ctx, proc, mag, (Ip_u8)ipmip_attr_hdr_find_u32(hdr, IPMIP6HA_CLI_ATTR_MAG_REASON), ipmip_attr_hdr_find_str(hdr, IPMIP6HA_CLI_ATTR_MAG_MATCH));
|
|
|
|
/* Must release */
|
|
ipmip6ha_mag_release(ctx, proc, mag);
|
|
|
|
rhdr = ipmip_attr_hdr_ack(&request->message, hdr);
|
|
}
|
|
break;
|
|
default:
|
|
/**/
|
|
return ipmip6_attr_command(&ctx->ipmip6, proc, request);
|
|
}
|
|
|
|
/* If we have a reply header; terminate it */
|
|
ipmip_attr_hdr_finalize(&request->message, rhdr);
|
|
|
|
/* Commit the reply */
|
|
ipmip_cli_message_commit(&ctx->ipmip6.ipmip, proc, request);
|
|
return 0;
|
|
}
|
|
|
|
/*
|
|
****************************************************************************
|
|
* 11 PUBLIC FUNCTIONS
|
|
****************************************************************************
|
|
*/
|
|
|
|
/*
|
|
****************************************************************************
|
|
* END OF FILE
|
|
****************************************************************************
|
|
*/
|