/* ****************************************************************************** * INTERPEAK SOURCE FILE * * Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmip6ha_pmipv6_dhcpv6.c,v $ $Revision: 1.12.16.1 $ * $Source: /home/interpeak/CVSRoot/ipmip6ha/config/ipmip6ha_pmipv6_dhcpv6.c,v $ * $Author: jhorteli $ * $State: Exp $ $Locker: $ * * INTERPEAK_COPYRIGHT_STRING * Design and implementation by Joel Hortelius ****************************************************************************** */ /* **************************************************************************** * 1 DESCRIPTION **************************************************************************** */ /* **************************************************************************** * 2 CONFIGURATION **************************************************************************** */ #include "ipmip6ha_config.h" /* **************************************************************************** * 3 INCLUDE FILES **************************************************************************** */ #define IPCOM_USE_CLIB_PROTO #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ipmip6ha_h.h" #include "ipmip6ha_attr_h.h" #include "ipmip6ha_if.h" #include "ipmip6ha_node.h" #include "ipmip6ha_pktbuf.h" #include "ipmip6ha_nemo.h" #ifdef IPDHCPS6 #include /* **************************************************************************** * 4 DEFINES **************************************************************************** */ #define IPMIP6HA_PMIPV6_DHCPV6_SERVER "DHCPV6-SERVER" /* **************************************************************************** * 5 TYPES **************************************************************************** */ typedef struct Ipmip6ha_pmipv6_dhcpv6_config_global { Ip_bool enabled; Ip_u32 preferred; Ip_u32 valid; } Ipmip6ha_pmipv6_dhcpv6_config_global_t; typedef struct Ipmip6ha_pmipv6_dhcpv6_config { Ip_bool enabled; Ip_u32 preferred; Ip_u32 valid; } Ipmip6ha_pmipv6_dhcpv6_config_t; /* **************************************************************************** * 6 EXTERN PROTOTYPES **************************************************************************** */ /* **************************************************************************** * 7 LOCAL PROTOTYPES **************************************************************************** */ /* **************************************************************************** * 8 DATA **************************************************************************** */ /* **************************************************************************** * 9 STATIC FUNCTIONS **************************************************************************** */ IP_STATIC void ipmip6ha_pmipv6_dhcpv6_config_global(struct Ipmip6ha_context *ctx, struct Ipmip_proc *proc, int action, Ipmip6ha_pmipv6_dhcpv6_config_global_t *gcfg, Ipmip_cli_message_t *request) { IPMIP_UNUSED_PARAMETER(ctx); IPMIP_UNUSED_PARAMETER(proc); IPMIP_UNUSED_PARAMETER(gcfg); if (action == IPMIP_CALLBACK_CONFIG_READ) { gcfg->enabled = ipmip_sysvar_bool(IP_FALSE, "ipmip6ha.LMA.dhcp.server"); gcfg->preferred = ipmip_sysvar_u32(10000, "ipmip6ha.LMA.dhcp.server.preferred"); gcfg->valid = ipmip_sysvar_u32(10000, "ipmip6ha.LMA.dhcp.server.valid"); } else if (action == IPMIP_CALLBACK_CONFIG_FREE) { /* Do nothing */ } else if (action == IPMIP_CALLBACK_CONFIG_DUMP) { ipmip_cli_config_printf(&request->message, "ipmip6ha.LMA.dhcp.server=%s", gcfg->enabled? "enabled" : "disabled"); ipmip_cli_config_printf(&request->message, "ipmip6ha.LMA.dhcp.server.valid=%u", gcfg->valid); ipmip_cli_config_printf(&request->message, "ipmip6ha.LMA.dhcp.server.preferred=%u", gcfg->preferred); } } IP_STATIC void ipmip6ha_pmipv6_dhcpv6_config(struct Ipmip6ha_context *ctx, struct Ipmip_proc *proc, int action, struct Ipmip6ha_if *ifp, Ipmip6ha_pmipv6_dhcpv6_config_global_t *gcfg, Ipmip6ha_pmipv6_dhcpv6_config_t *cfg, Ipmip_cli_message_t *request) { IPMIP_UNUSED_PARAMETER(ctx); IPMIP_UNUSED_PARAMETER(proc); IPMIP_UNUSED_PARAMETER(ifp); IPMIP_UNUSED_PARAMETER(gcfg); if (action == IPMIP_CALLBACK_CONFIG_READ) { cfg->enabled = ipmip_sysvar_bool(gcfg->enabled, "ipmip6ha.interface.%s.LMA.dhcp.server", ifp->ipmip6.iff.ifname); cfg->preferred = ipmip_sysvar_u32(gcfg->preferred, "ipmip6ha.interface.%s.LMA.dhcp.server.preferred", ifp->ipmip6.iff.ifname); cfg->valid = ipmip_sysvar_u32(gcfg->valid, "ipmip6ha.interface.%s.LMA.dhcp.server.valid", ifp->ipmip6.iff.ifname); if (cfg->enabled) ipmip_dhcp6_embedded_server_start(&ctx->ipmip6.ipmip, proc, ifp->ipmip6.iff.ifname); } else if (action == IPMIP_CALLBACK_CONFIG_FREE) { /* Do nothing */ if (cfg->enabled) ipmip_dhcp6_embedded_server_stop(&ctx->ipmip6.ipmip, proc); } else if (action == IPMIP_CALLBACK_CONFIG_DUMP) { ipmip_cli_config_printf(&request->message, "ipmip6ha.interface.%s.LMA.dhcp.server=%s", ifp->ipmip6.iff.ifname, cfg->enabled? "enabled" : "disabled"); ipmip_cli_config_printf(&request->message, "ipmip6ha.interface.%s.LMA.dhcp.server.valid=%u", ifp->ipmip6.iff.ifname, cfg->valid); ipmip_cli_config_printf(&request->message, "ipmip6ha.interface.%s.LMA.dhcp.server.preferred=%u", ifp->ipmip6.iff.ifname, cfg->preferred); } } IP_STATIC int ipmip6ha_pmipv6_dhcpv6_provide(struct Ipmip6ha_context *ctx, struct Ipmip_proc *proc, int action, Ipmip6ha_pmipv6_dhcpv6_config_global_t *gcfg, Ipmip6ha_pmipv6_dhcpv6_config_t *cfg, void *handle, struct Ipmip6ha_node_P *node, struct Ipmip_timer *service) { Ipmip6ha_nemo_t *nemo, *nnemo; Ipmip6ha_nemo_t *nemo_p, *nnemo_p; Ipdhcps6_subnet subnet; IPMIP_UNUSED_PARAMETER(service); IPMIP_UNUSED_PARAMETER(cfg); IPMIP_UNUSED_PARAMETER(handle); IPMIP_UNUSED_PARAMETER(gcfg); if (cfg->enabled) { if (action == IPMIP_CALLBACK_ENABLE) { for (nemo = IPCOM_LIST_FIRST(&node->node.nemo_v6); nemo != IP_NULL; nemo = nnemo) { nnemo = IPCOM_LIST_NEXT(&nemo->next); ipcom_memset(&subnet, 0, sizeof(subnet)); ipcom_memcpy(&subnet.prefix, &nemo->prefix, sizeof(struct Ip_in6_addr)); subnet.prefix_len = nemo->len; if (ipdhcps6_subnet_add(&subnet) != IPCOM_SUCCESS) { IPMIP6_EVENT_IF(ERR, proc, ipmip_log_event_add(&ctx->ipmip6.ipmip, proc, "%s failed to add subnet '%s/%d'", ipmip6ha_node_describe(proc, &node->node), ipmip_ntop_inet6(proc, &nemo->prefix, IP_NULL), nemo->len)); } for (nemo_p = IPCOM_LIST_FIRST(&node->node.nemo_v6); nemo_p != IP_NULL; nemo_p = nnemo_p) { Ipdhcps6_poolinfo pool; nnemo_p = IPCOM_LIST_NEXT(&nemo_p->next); ipcom_memcpy(&pool.first, &nemo_p->prefix, sizeof(struct Ip_in6_addr)); pool.first.in6.addr32[3] = 0x1; ipcom_memcpy(&pool.last, &pool.first, sizeof(struct Ip_in6_addr)); pool.preferred_lifetime = cfg->preferred; pool.valid_lifetime = cfg->valid; pool.prefix_len = 0; if (ipdhcps6_pool_add(&subnet, &pool) != IPCOM_SUCCESS) { IPMIP6_EVENT_IF(ERR, proc, ipmip_log_event_add(&ctx->ipmip6.ipmip, proc, "%s failed to add pool to subnet '%s/%d'", ipmip6ha_node_describe(proc, &node->node), ipmip_ntop_inet6(proc, &nemo->prefix, IP_NULL), nemo->len)); } } } } else if (action == IPMIP_CALLBACK_DISABLE || action == IPMIP_CALLBACK_UPDATE) { for (nemo = IPCOM_LIST_FIRST(&node->node.nemo_v6); nemo != IP_NULL; nemo = nnemo) { nnemo = IPCOM_LIST_NEXT(&nemo->next); /* Subnet delete will delete any associated pools as well */ ipcom_memset(&subnet, 0, sizeof(subnet)); ipcom_memcpy(&subnet.prefix, &nemo->prefix, sizeof(struct Ip_in6_addr)); subnet.prefix_len = nemo->len; if (ipdhcps6_subnet_delete(&subnet) != IPCOM_SUCCESS) { IPMIP6_EVENT_IF(ERR, proc, ipmip_log_event_add(&ctx->ipmip6.ipmip, proc, "%s failed to delete subnet '%s/%d'", ipmip6ha_node_describe(proc, &node->node), ipmip_ntop_inet6(proc, &nemo->prefix, IP_NULL), nemo->len)); } } if (action == IPMIP_CALLBACK_UPDATE) return IPMIP_CALLBACK_RET_FAILED; } } /* Don't delay */ return IPMIP_CALLBACK_RET_SUCCESS; } /* **************************************************************************** * 10 GLOBAL FUNCTIONS **************************************************************************** */ IP_GLOBAL void ipmip6ha_pmipv6_dhcpv6_install(struct Ipmip6ha_context *ctx); IP_GLOBAL void ipmip6ha_pmipv6_dhcpv6_install(struct Ipmip6ha_context *ctx) { static Ipmip6ha_extension_t srv; ipcom_memset(&srv, 0, sizeof(srv)); srv.name = IPMIP6HA_PMIPV6_DHCPV6_SERVER; srv.ifp_data_size = sizeof(Ipmip6ha_pmipv6_dhcpv6_config_t); srv.global_data_size= sizeof(Ipmip6ha_pmipv6_dhcpv6_config_global_t); srv.config_global = (Ipmip6ha_extension_config_global_t)ipmip6ha_pmipv6_dhcpv6_config_global; srv.config_ifp = (Ipmip6ha_extension_config_ifp_t)ipmip6ha_pmipv6_dhcpv6_config; srv.provide = (Ipmip6ha_extension_provide_t)ipmip6ha_pmipv6_dhcpv6_provide; /* This is a PMIP only feature */ ipmip6ha_context_register_extension(ctx, &srv, IP_FALSE, IP_TRUE); } /* **************************************************************************** * 11 PUBLIC FUNCTIONS **************************************************************************** */ #else IP_GLOBAL void ipmip6ha_pmipv6_dhcpv6_install(struct Ipmip6ha_context *ctx); IP_GLOBAL void ipmip6ha_pmipv6_dhcpv6_install(struct Ipmip6ha_context *ctx) { IPMIP_UNUSED_PARAMETER(ctx); } #endif /* IPDHCPS6 */ /* **************************************************************************** * END OF FILE **************************************************************************** */