/* ****************************************************************************** * INTERPEAK SOURCE FILE * * Document no: @(#) $Name: VXWORKS_ITER40_2019102207 $ $RCSfile: ipmip6mn_service_radvd.c,v $ $Revision: 1.11 $ * $Source: /home/interpeak/CVSRoot/ipmip6mn/config/ipmip6mn_service_radvd.c,v $ * $Author: jhorteli $ * $State: Exp $ $Locker: $ * * INTERPEAK_COPYRIGHT_STRING * Design and implementation by Joel Hortelius ****************************************************************************** */ /* **************************************************************************** * 1 DESCRIPTION **************************************************************************** */ /* **************************************************************************** * 2 CONFIGURATION **************************************************************************** */ #include "ipmip6mn_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 "ipmip6mn_h.h" #include "ipmip6mn_pktbuf.h" #include "ipmip6mn_coa.h" /* **************************************************************************** * 4 DEFINES **************************************************************************** */ #define IPMIP6MN_SERVICE_RADVD_NAME "RADVD" /* **************************************************************************** * 5 TYPES **************************************************************************** */ typedef struct Ipmip6mn_service_radvd_config { Ip_bool enabled; Ipnet_radvd_if_data radvd; Ipnet_radvd_if_prefix_data prefix; } Ipmip6mn_service_radvd_config_t; typedef struct Ipmip6mn_service_radvd_handle_data { Ipnet_radvd_if_handle radvd; } Ipmip6mn_service_radvd_handle_data_t; /* **************************************************************************** * 6 EXTERN PROTOTYPES **************************************************************************** */ /* **************************************************************************** * 7 LOCAL PROTOTYPES **************************************************************************** */ /* **************************************************************************** * 8 DATA **************************************************************************** */ /* **************************************************************************** * 9 STATIC FUNCTIONS **************************************************************************** */ IP_STATIC int ipmip6mn_service_radvd_provide(struct Ipmip6mn_context *ctx, struct Ipmip_proc *proc, int action, struct Ipmip6mn_node *node, struct Ipmip6mn_node_config *cfg, Ipmip6mn_service_radvd_config_t *priv_cfg, Ipmip6mn_service_radvd_handle_data_t *handle, struct Ipmip_timer *service) { Ipmip6mn_entry_nemo_t *nemo; unsigned i; IPMIP_UNUSED_PARAMETER(cfg); IPMIP_UNUSED_PARAMETER(service); if (action == IPMIP_CALLBACK_ENABLE) { if (priv_cfg->enabled) { for (nemo = IPCOM_LIST_FIRST(&node->config->nemo); nemo != IP_NULL; nemo = IPCOM_LIST_NEXT(&nemo->nemo_next)) { Ipnet_radvd_if_data radvd; ipcom_memcpy(&radvd, &priv_cfg->radvd, sizeof(radvd)); ipcom_strcpy(radvd.ifname, nemo->nemo_ingress); if (ipnet_radvd_if_open(&handle->radvd, &radvd) != IPCOM_SUCCESS) { IPMIP6_EVENT_IF(INFO, proc, ipmip_log_event_add(&ctx->ipmip6.ipmip, proc, "Unable to start service for Mobile node %s", node->name)); } else { Ipnet_radvd_if_prefix_handle phandle; Ipnet_radvd_if_prefix_data pdata; ipcom_memcpy(&pdata, &priv_cfg->prefix, sizeof(pdata)); /* Do the prefixes */ for (i = 0; i < nemo->nemo_prefixes.numelem; i++) { Ipmip6_mh_mo_mobile_prefix_t *mo = (Ipmip6_mh_mo_mobile_prefix_t *)nemo->nemo_prefixes.hdrs[i]; /* Add prefix by prefix */ ipcom_memcpy(&pdata.prefix, &mo->prefix, sizeof(pdata.prefix)); pdata.prefixlen = mo->prefix_length; if (ipnet_radvd_if_prefix_open(handle->radvd, &phandle, &pdata) != IPCOM_SUCCESS) { IPMIP6_EVENT_IF(INFO, proc, ipmip_log_event_add(&ctx->ipmip6.ipmip, proc, "Unable to start service on prefix %s/%d for Mobile node %s", ipmip_ntop_inet6(proc, &pdata.prefix, IP_NULL), pdata.prefixlen, node->name)); } } /* Start it */ ipnet_radvd_if_start(handle->radvd); } } } } else if (action == IPMIP_CALLBACK_DISABLE) { if (priv_cfg->enabled) { if (handle) ipnet_radvd_if_close(handle->radvd); } } return IPMIP_CALLBACK_RET_SUCCESS; } IP_STATIC void ipmip6mn_service_radvd_config(struct Ipmip6mn_context *ctx, struct Ipmip_proc *proc, int action, struct Ipmip6mn_node *node, struct Ipmip6mn_node_config *cfg, Ipmip6mn_service_radvd_config_t *priv_cfg, Ipmip_cli_message_t *request) { IPMIP_UNUSED_PARAMETER(ctx); IPMIP_UNUSED_PARAMETER(proc); IPMIP_UNUSED_PARAMETER(cfg); if (action == IPMIP_CALLBACK_CONFIG_READ) { priv_cfg->enabled = ipmip_sysvar_bool(IP_FALSE, "ipmip6mn.%s.mobile_router.radvd", node->name); priv_cfg->radvd.max_rtr_adv_interval = ipmip_sysvar_u32(600000, "ipmip6mn.%s.mobile_router.radvd.MaxRtrAdvInterval", node->name); priv_cfg->radvd.min_rtr_adv_interval = ipmip_sysvar_u32(priv_cfg->radvd.max_rtr_adv_interval / 3, "ipmip6mn.%s.mobile_router.radvd.MinRtrAdvInterval", node->name); priv_cfg->radvd.min_delay_between_ras = ipmip_sysvar_u32(IP_MIN(priv_cfg->radvd.min_rtr_adv_interval, 3000), "ipmip6mn.%s.mobile_router.radvd.MinDelayBetweenRAs", node->name); priv_cfg->radvd.default_lifetime = ipmip_sysvar_u32(IP_MAX(1000, (3 * priv_cfg->radvd.max_rtr_adv_interval)), "ipmip6mn.%s.mobile_router.radvd.AdvDefaultLifetime", node->name); priv_cfg->radvd.link_mtu = ipmip_sysvar_u32(0, "ipmip6mn.%s.mobile_router.radvd.AdvLinkMTU", node->name); priv_cfg->radvd.reachable_time = ipmip_sysvar_u32(0, "ipmip6mn.%s.mobile_router.radvd.AdvReachableTime", node->name); priv_cfg->radvd.retrans_timer = ipmip_sysvar_ulong(0, "ipmip6mn.%s.mobile_router.radvd.AdvRetransTimer", node->name); priv_cfg->radvd.hoplimit = (Ip_u8)ipmip_sysvar_ulong(64, "ipmip6mn.%s.mobile_router.radvd.AdvCurHopLimit", node->name); priv_cfg->radvd.managed = ipmip_sysvar_bool(IP_FALSE, "ipmip6mn.%s.mobile_router.radvd.AdvManagedFlag", node->name); priv_cfg->radvd.other_config = ipmip_sysvar_bool(IP_FALSE, "ipmip6mn.%s.mobile_router.radvd.AdvOtherConfigFlag", node->name); priv_cfg->radvd.home_agent = ipmip_sysvar_bool(IP_FALSE, "ipmip6mn.%s.mobile_router.radvd.AdvHomeAgentFlag", node->name); priv_cfg->radvd.adv_interval_opt = ipmip_sysvar_bool(IP_FALSE, "ipmip6mn.%s.mobile_router.radvd.AdvIntervalOpt", node->name); priv_cfg->radvd.adv_home_agent_opt = ipmip_sysvar_bool(IP_FALSE, "ipmip6mn.%s.mobile_router.radvd.AdvHomeAgentOpt", node->name); priv_cfg->radvd.adv_home_agent_opt_lifetime = ipmip_sysvar_u32(0, "ipmip6mn.%s.mobile_router.radvd.AdvHomeAgentOptLifetime", node->name); priv_cfg->radvd.adv_home_agent_opt_preference = ipmip_sysvar_u32(0, "ipmip6mn.%s.mobile_router.radvd.AdvHomeAgentOptPreference", node->name); /* Do prefix */ priv_cfg->prefix.valid_lifetime = ipmip_sysvar_u32(2592000, "ipmip6mn.%s.mobile_router.radvd.prefix.AdvValidLifetime", node->name); priv_cfg->prefix.preferred_lifetime = ipmip_sysvar_u32(604800, "ipmip6mn.%s.mobile_router.radvd.prefix.AdvPreferredLifetime", node->name); priv_cfg->prefix.on_link = ipmip_sysvar_bool(IP_TRUE, "ipmip6mn.%s.mobile_router.radvd.prefix.AdvOnLinkFlag", node->name); priv_cfg->prefix.autonomous = ipmip_sysvar_bool(IP_TRUE, "ipmip6mn.%s.mobile_router.radvd.prefix.AdvAutonomousFlag", node->name); priv_cfg->prefix.router_address = ipmip_sysvar_bool(IP_FALSE, "ipmip6mn.%s.mobile_router.radvd.prefix.AdvRouterAddressFlag", node->name); } else if (action == IPMIP_CALLBACK_CONFIG_FREE) { /* Do nothing */ } else if (action == IPMIP_CALLBACK_CONFIG_DUMP) { ipmip_cli_config_printf(&request->message, "ipmip6mn.%s.mobile_router.radvd=%s", node->name, priv_cfg->enabled? "enabled" : "disabled"); ipmip_cli_config_printf(&request->message, "ipmip6mn.%s.mobile_router.radvd.MaxRtrAdvInterval=%u", node->name, priv_cfg->radvd.max_rtr_adv_interval); ipmip_cli_config_printf(&request->message, "ipmip6mn.%s.mobile_router.radvd.MinRtrAdvInterval=%u", node->name, priv_cfg->radvd.min_rtr_adv_interval); ipmip_cli_config_printf(&request->message, "ipmip6mn.%s.mobile_router.radvd.MinDelayBetweenRAs=%u", node->name, priv_cfg->radvd.min_delay_between_ras); ipmip_cli_config_printf(&request->message, "ipmip6mn.%s.mobile_router.radvd.AdvDefaultLifetime=%u", node->name, priv_cfg->radvd.default_lifetime); ipmip_cli_config_printf(&request->message, "ipmip6mn.%s.mobile_router.radvd.AdvLinkMTU=%u", node->name, priv_cfg->radvd.link_mtu); ipmip_cli_config_printf(&request->message, "ipmip6mn.%s.mobile_router.radvd.AdvReachableTime=%u", node->name, priv_cfg->radvd.reachable_time); ipmip_cli_config_printf(&request->message, "ipmip6mn.%s.mobile_router.radvd.AdvRetransTimer=%u", node->name, priv_cfg->radvd.retrans_timer); ipmip_cli_config_printf(&request->message, "ipmip6mn.%s.mobile_router.radvd.AdvCurHopLimit=%u", node->name, priv_cfg->radvd.hoplimit); ipmip_cli_config_printf(&request->message, "ipmip6mn.%s.mobile_router.radvd.AdvManagedFlag=%s", node->name, priv_cfg->radvd.managed? "true" : "false"); ipmip_cli_config_printf(&request->message, "ipmip6mn.%s.mobile_router.radvd.AdvOtherConfigFlag=%s", node->name, priv_cfg->radvd.other_config? "true" : "false"); ipmip_cli_config_printf(&request->message, "ipmip6mn.%s.mobile_router.radvd.AdvHomeAgentFlag=%s", node->name, priv_cfg->radvd.home_agent? "true" : "false"); ipmip_cli_config_printf(&request->message, "ipmip6mn.%s.mobile_router.radvd.AdvIntervalOpt=%s", node->name, priv_cfg->radvd.adv_interval_opt? "true" : "false"); ipmip_cli_config_printf(&request->message, "ipmip6mn.%s.mobile_router.radvd.AdvHomeAgentOpt=%s", node->name, priv_cfg->radvd.adv_home_agent_opt? "true" : "false"); ipmip_cli_config_printf(&request->message, "ipmip6mn.%s.mobile_router.radvd.AdvHomeAgentOptLifetime=%u", node->name, priv_cfg->radvd.adv_home_agent_opt_lifetime); ipmip_cli_config_printf(&request->message, "ipmip6mn.%s.mobile_router.radvd.AdvHomeAgentOptPreference=%u", node->name, priv_cfg->radvd.adv_home_agent_opt_preference); /* Do prefix */ ipmip_cli_config_printf(&request->message, "ipmip6mn.%s.mobile_router.radvd.prefix.AdvValidLifetime=%u", node->name, priv_cfg->prefix.valid_lifetime); ipmip_cli_config_printf(&request->message, "ipmip6mn.%s.mobile_router.radvd.prefix.AdvPreferredLifetime=%u", node->name, priv_cfg->prefix.preferred_lifetime); ipmip_cli_config_printf(&request->message, "ipmip6mn.%s.mobile_router.radvd.prefix.AdvOnLinkFlag=%s", node->name, priv_cfg->prefix.on_link? "true" : "false"); ipmip_cli_config_printf(&request->message, "ipmip6mn.%s.mobile_router.radvd.prefix.AdvAutonomousFlag=%s", node->name, priv_cfg->prefix.autonomous? "true" : "false"); ipmip_cli_config_printf(&request->message, "ipmip6mn.%s.mobile_router.radvd.prefix.AdvRouterAddressFlag=%s", node->name, priv_cfg->prefix.router_address? "true" : "false"); } } /* **************************************************************************** * 10 GLOBAL FUNCTIONS **************************************************************************** */ IP_GLOBAL void ipmip6mn_service_radvd_install(struct Ipmip6mn_context *ctx); IP_GLOBAL void ipmip6mn_service_radvd_install(struct Ipmip6mn_context *ctx) { static Ipmip6mn_extension_t srv; srv.name = IPMIP6MN_SERVICE_RADVD_NAME; srv.node_data_size = sizeof(Ipmip6mn_service_radvd_handle_data_t); srv.node_config_size = sizeof(Ipmip6mn_service_radvd_config_t); srv.config = (Ipmip6mn_extension_config_t)ipmip6mn_service_radvd_config; srv.provide = (Ipmip6mn_extension_provide_t)ipmip6mn_service_radvd_provide; /* This is a PMIP only feature */ ipmip6mn_context_register_extension(ctx, &srv); } /* **************************************************************************** * 11 PUBLIC FUNCTIONS **************************************************************************** */ /* **************************************************************************** * END OF FILE **************************************************************************** */