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

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(&notify->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(&notify->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(&notify->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(&notify->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(&notify->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
****************************************************************************
*/