diff --git a/config/RdkWanManager_v2.xml b/config/RdkWanManager_v2.xml index cfc366af..3d156f30 100644 --- a/config/RdkWanManager_v2.xml +++ b/config/RdkWanManager_v2.xml @@ -1436,6 +1436,142 @@ + + + + DSLite + object + + DSLite_GetParamBoolValue + DSLite_SetParamBoolValue + DSLite_GetParamUlongValue + + + + Enable + boolean + bool + true + + + InterfaceSettingNumberOfEntries + unsignedInt + uint32 + false + + + + + InterfaceSetting + writableTable + 128 + + + InterfaceSetting4_GetEntryCount + InterfaceSetting4_GetEntry + InterfaceSetting4_AddEntry + InterfaceSetting4_DelEntry + InterfaceSetting4_GetParamBoolValue + InterfaceSetting4_GetParamStringValue + InterfaceSetting4_GetParamUlongValue + InterfaceSetting4_SetParamBoolValue + InterfaceSetting4_SetParamStringValue + InterfaceSetting4_SetParamUlongValue + InterfaceSetting4_Validate + InterfaceSetting4_Commit + InterfaceSetting4_Rollback + + + + + Enable + boolean + bool + true + + + Status + string: Enabled(1), Disabled(2), Error(3) + uint32/mapped + + + Alias + string(64) + string + true + + + EndpointAssignmentPrecedence + string: DHCPv6(1), Static(2) + uint32/mapped + true + + + EndpointAddressTypePrecedence + string: FQDN(1), IPv6Address(2) + uint32/mapped + true + + + EndpointAddressInUse + string(256) + string + + + EndpointName + string(256) + string + true + + + EndpointAddress + string(256) + string + true + + + Origin + string: DHCPv6(1), Static(2) + uint32/mapped + + + TunnelInterface + string(256) + string + + + TunneledInterface + string(256) + string + + + X_RDKCENTRAL-COM_MssClampingEnable + boolean + bool + true + + + X_RDKCENTRAL-COM_Tcpmss + unsignedInt + uint32 + true + + + X_RDKCENTRAL-COM_IPv6FragEnable + boolean + bool + true + + + TunnelV4Addr + string(64) + string + true + + + + + diff --git a/configure.ac b/configure.ac index 58fccc0f..9056f1b3 100644 --- a/configure.ac +++ b/configure.ac @@ -113,6 +113,18 @@ AC_ARG_ENABLE([dhcp_manager], [echo "dhcp manager is disabled"]) AM_CONDITIONAL(DHCPMANAGER_ENABLED, test "x$DHCPMANAGER_SUPPORT_ENABLED" = xtrue) +AC_ARG_ENABLE([dslite_v2], + AS_HELP_STRING([--enable-dslite-v2],[enable next generation DSLite support (default is no)]), + [ + case "${enableval}" in + yes) DSLITE_SUPPORT_ENABLED=true;; + no) DSLITE_SUPPORT_ENABLED=false;; + *) AC_MSG_ERROR([bad value ${enableval} for --enable-dslite-v2 ]);; + esac + ], + [echo "DSLite support is disabled"]) +AM_CONDITIONAL(DSLITE_SUPPORT, test "x$DSLITE_SUPPORT_ENABLED" = xtrue) + dnl Checks for header files. AC_CHECK_HEADERS([limits.h memory.h stdlib.h string.h sys/socket.h unistd.h]) diff --git a/source/TR-181/include/dmsb_tr181_psm_definitions.h b/source/TR-181/include/dmsb_tr181_psm_definitions.h index c85c1a4e..0ff417f2 100644 --- a/source/TR-181/include/dmsb_tr181_psm_definitions.h +++ b/source/TR-181/include/dmsb_tr181_psm_definitions.h @@ -76,7 +76,9 @@ #define PSM_WANMANAGER_IF_VIRIF_ENABLE_MAPT "dmsb.wanmanager.if.%d.VirtualInterface.%d.EnableMAPT" #define PSM_WANMANAGER_IF_VIRIF_ENABLE_DSLITE "dmsb.wanmanager.if.%d.VirtualInterface.%d.EnableDSLite" - +#ifdef FEATURE_DSLITE_V2 +#define PSM_WANMANAGER_IF_VIRIF_DSLITE_PATH "dmsb.wanmanager.if.%d.VirtualInterface.%d.DSLite.Path" +#endif #define PSM_WANMANAGER_GROUP_POLICY "dmsb.wanmanager.group.%d.policy" #define PSM_WANMANAGER_WANIFCOUNT "dmsb.wanmanager.wan.interfacecount" diff --git a/source/TR-181/include/wanmgr_dml.h b/source/TR-181/include/wanmgr_dml.h index b9ccb539..2d7eee53 100644 --- a/source/TR-181/include/wanmgr_dml.h +++ b/source/TR-181/include/wanmgr_dml.h @@ -61,6 +61,16 @@ typedef enum _DEVICE_NETWORKING_MODE_ MODEM_MODE } DEVICE_NETWORKING_MODE; +typedef enum +_DML_WAN_DEVICE_MODE +{ + DML_WAN_DEVICE_MODE_Bridge = 1, + DML_WAN_DEVICE_MODE_Ipv4, + DML_WAN_DEVICE_MODE_Ipv6, + DML_WAN_DEVICE_MODE_Dualstack +} +DML_WAN_DEVICE_MODE; + typedef enum _DML_WAN_IFACE_OPER_STATUS { WAN_OPERSTATUS_UNKNOWN = 1, @@ -148,9 +158,24 @@ typedef enum _DML_WAN_IFACE_MAPT_STATUS typedef enum _DML_WAN_IFACE_DSLITE_STATUS { WAN_IFACE_DSLITE_STATE_UP = 1, - WAN_IFACE_DSLITE_STATE_DOWN + WAN_IFACE_DSLITE_STATE_DOWN, + WAN_IFACE_DSLITE_STATE_ERROR } DML_WAN_IFACE_DSLITE_STATUS; +#ifdef FEATURE_DSLITE_V2 +typedef enum _DML_WAN_DSLITE_ADDR_METHOD +{ + DSLITE_ENDPOINT_DHCPV6 = 1, + DSLITE_ENDPOINT_STATIC +} DML_WAN_DSLITE_ADDR_METHOD; + +typedef enum _DML_WAN_DSLITE_ADDR_PRECEDENCE +{ + DSLITE_ENDPOINT_FQDN = 1, + DSLITE_ENDPOINT_IPV6ADDRESS +} DML_WAN_DSLITE_ADDR_PRECEDENCE; +#endif + /** enum wan status */ typedef enum _WAN_NOTIFY_ENUM { @@ -364,6 +389,9 @@ typedef struct _WANMGR_IPV6_DATA uint32_t prefixCmd; bool domainNameAssigned; /**< Have we been assigned dns server addresses ? */ #endif +#ifdef FEATURE_DSLITE_V2 + char endpointName[BUFLEN_256]; +#endif } WANMGR_IPV6_DATA; typedef struct _WANMGR_IPV6_RA_DATA @@ -461,6 +489,45 @@ typedef struct _DML_WANIFACE_DSLITE BOOL Changed; } DML_WANIFACE_DSLITE; +#ifdef FEATURE_DSLITE_V2 +typedef struct _DML_DSLITE_CONFIG +{ + BOOL Enable; + DML_WAN_IFACE_DSLITE_STATUS Status; + CHAR Alias[BUFLEN_64]; // map to virtual interface Path + DML_WAN_DSLITE_ADDR_METHOD Mode; //EndpointAssignmentPrecedence + CHAR EndpointName[BUFLEN_256]; + CHAR EndpointAddr[BUFLEN_256]; + DML_WAN_DSLITE_ADDR_METHOD Origin; + CHAR TunnelIface[BUFLEN_256]; + CHAR TunneledIface[BUFLEN_256]; + DML_WAN_DSLITE_ADDR_PRECEDENCE Type; + CHAR AddrInUse[BUFLEN_256]; + BOOL MssClampingEnable; + UINT TcpMss; // X_RDKCENTRAL-COM_Tcpmss + BOOL Ipv6FragEnable; // X_RDKCENTRAL-COM_IPv6FragEnable + CHAR TunnelV4Addr[BUFLEN_64]; +} DML_DSLITE_CONFIG; + +typedef struct _DML_DSLITE_LIST +{ + struct _DML_DSLITE_LIST *next; + UINT InstanceNumber; + BOOL New; + DML_DSLITE_CONFIG PrevCfg; + DML_DSLITE_CONFIG CurrCfg; +} DML_DSLITE_LIST; + +// DSLITE CONFIG +typedef struct _WANMGR_DSLITE_CONFIG_DATA_ +{ + DML_DSLITE_LIST *DSLiteList; + BOOL Enable; + UINT InterfaceSettingNumberOfEntries; + UINT NextInstanceNumber; + BOOL Changed; +} WanMgr_DSLite_Data_t; +#endif typedef struct _DML_WANIFACE_SUBSCRIBE { @@ -483,6 +550,7 @@ typedef enum WAN_STATE_IPV6_LEASED, WAN_STATE_DUAL_STACK_ACTIVE, WAN_STATE_MAPT_ACTIVE, + WAN_STATE_DSLITE_ACTIVE, WAN_STATE_REFRESHING_WAN, WAN_STATE_DECONFIGURING_WAN, WAN_STATE_STANDBY @@ -673,5 +741,9 @@ typedef struct _WANMGR_DATA_ST_ //Iface Group WanMgr_IfaceGroup_t IfaceGroup; +#ifdef FEATURE_DSLITE_V2 + //DSLITE CONFIG + WanMgr_DSLite_Data_t DSLite; +#endif } WANMGR_DATA_ST; #endif //_WANMGR_DML_H_ diff --git a/source/TR-181/middle_layer_src/Makefile.am b/source/TR-181/middle_layer_src/Makefile.am index fd0b15f0..00c7f1b5 100644 --- a/source/TR-181/middle_layer_src/Makefile.am +++ b/source/TR-181/middle_layer_src/Makefile.am @@ -35,4 +35,8 @@ libCcspWanManager_middle_layer_src_la_LDFLAGS += -lrbus if DHCPMANAGER_ENABLED libCcspWanManager_middle_layer_src_la_SOURCES += wanmgr_rbus_dhcp_client_events.c -endif \ No newline at end of file +endif + +if DSLITE_SUPPORT +libCcspWanManager_middle_layer_src_la_SOURCES += wanmgr_dml_dslite_apis.c +endif diff --git a/source/TR-181/middle_layer_src/wanmgr_dml_dslite_apis.c b/source/TR-181/middle_layer_src/wanmgr_dml_dslite_apis.c new file mode 100644 index 00000000..692cbeed --- /dev/null +++ b/source/TR-181/middle_layer_src/wanmgr_dml_dslite_apis.c @@ -0,0 +1,589 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2025 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/********************************************************************** + Copyright [2014] [Cisco Systems, Inc.] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +**********************************************************************/ +#include "wanmgr_dslite.h" +#include "wanmgr_dml_dslite_apis.h" +#include "wanmgr_rdkbus_apis.h" +#include "wanmgr_net_utils.h" +#include "wanmgr_data.h" +#if defined (_XB6_PRODUCT_REQ_) || defined (_CBR2_PRODUCT_REQ_) || defined(_PLATFORM_RASPBERRYPI_) +#include "wanmgr_utils.h" +#endif +#include "wanmgr_telemetry.h" + +extern WANMGR_DATA_ST gWanMgrDataBase; + +BOOL DSLite_GetParamBoolValue(ANSC_HANDLE hInsContext, char *ParamName, BOOL *pBool) +{ + UNREFERENCED_PARAMETER(hInsContext); + WanMgr_DSLite_Data_t *pDSLiteData; + BOOL ret = FALSE; + + pDSLiteData = WanMgr_GetDSLiteData_locked(); + if (!pDSLiteData) + return ret; + + if (strcmp(ParamName, "Enable") == 0) + { + *pBool = pDSLiteData->Enable; + ret = TRUE; + } + + WanMgr_GetDSLiteData_release(); + return ret; +} + +BOOL DSLite_SetParamBoolValue(ANSC_HANDLE hInsContext, char *ParamName, BOOL bValue) +{ + UNREFERENCED_PARAMETER(hInsContext); + WanMgr_DSLite_Data_t *pDSLiteData; + BOOL ret = FALSE; + + pDSLiteData = WanMgr_GetDSLiteData_locked(); + if (!pDSLiteData) + return ret; + + if (strcmp(ParamName, "Enable") == 0) + { + if (pDSLiteData->Enable != bValue) + { + UINT deviceMode = 0; + + WanMgr_SysCfgGetUint("last_erouter_mode", &deviceMode); + if (bValue && (DML_WAN_DEVICE_MODE)deviceMode != DML_WAN_DEVICE_MODE_Ipv6) + { + CcspTraceWarning(("Cannot set DSLite, the device mode is not ipv6 only! \n")); + ret = FALSE; + } + else + { + pDSLiteData->Enable = bValue; + pDSLiteData->Changed = TRUE; + ret = TRUE; + } + } + else + { + ret = TRUE; + } + } + + WanMgr_GetDSLiteData_release(); + return ret; +} + +BOOL DSLite_GetParamUlongValue(ANSC_HANDLE hInsContext, char *ParamName, ULONG *pUlong) +{ + UNREFERENCED_PARAMETER(hInsContext); + WanMgr_DSLite_Data_t *pDSLiteData; + BOOL ret = FALSE; + + pDSLiteData = WanMgr_GetDSLiteData_locked(); + if (pDSLiteData == NULL) + return ret; + + if (strcmp(ParamName, "InterfaceSettingNumberOfEntries") == 0) + { + *pUlong = (ULONG)pDSLiteData->InterfaceSettingNumberOfEntries; + ret = TRUE; + } + + WanMgr_GetDSLiteData_release(); + return ret; +} + +BOOL InterfaceSetting4_GetParamBoolValue(ANSC_HANDLE hInsContext, char *ParamName, BOOL *pBool) +{ + UINT inst = (UINT)(uintptr_t)hInsContext; + BOOL ret = FALSE; + DML_DSLITE_CONFIG *cfg; + DML_DSLITE_LIST *entry; + + entry = WanMgr_getDSLiteEntryByInstance_locked(inst); + if (!entry) + return ret; + + cfg = &entry->CurrCfg; + + if (strcmp(ParamName, "Enable") == 0) + { + *pBool = cfg->Enable; + ret = TRUE; + } + else if (strcmp(ParamName, "X_RDKCENTRAL-COM_MssClampingEnable") == 0) + { + *pBool = (cfg->MssClampingEnable); + ret = TRUE; + } + else if (strcmp(ParamName, "X_RDKCENTRAL-COM_IPv6FragEnable") == 0) + { + *pBool = (cfg->Ipv6FragEnable); + ret = TRUE; + } + + WanMgr_GetDSLiteData_release(); + return ret; +} + +ULONG InterfaceSetting4_GetParamStringValue(ANSC_HANDLE hInsContext, char *ParamName, char *pValue, ULONG *pUlSize) +{ + UINT inst = (UINT)(uintptr_t)hInsContext; + INT ret = -1; + const char *src = NULL; + DML_DSLITE_LIST *entry; + DML_DSLITE_CONFIG *cfg; + + entry = WanMgr_getDSLiteEntryByInstance_locked(inst); + if (!entry) + return ret; + + cfg = &entry->CurrCfg; + + if (strcmp(ParamName, "Alias") == 0) + src = cfg->Alias; + else if (strcmp(ParamName, "EndpointAddressInUse") == 0) + src = cfg->AddrInUse; + else if (strcmp(ParamName, "EndpointName") == 0) /* TODO: ensure backend fills correctly */ + src = cfg->EndpointName; + else if (strcmp(ParamName, "EndpointAddress") == 0) + src = cfg->EndpointAddr; + else if (strcmp(ParamName, "TunnelInterface") == 0) + src = cfg->TunnelIface; + else if (strcmp(ParamName, "TunneledInterface") == 0) + src = cfg->TunneledIface; + else if (strcmp(ParamName, "TunnelV4Addr") == 0) + src = cfg->TunnelV4Addr; + else + { + WanMgr_GetDSLiteData_release(); + return ret; + } + + ULONG len = AnscSizeOfString(src); + if (len >= *pUlSize) + { + *pUlSize = len + 1; + ret = 1; + } + else + { + strncpy(pValue, src, len + 1); + pValue[len] = '\0'; + ret = 0; + } + + WanMgr_GetDSLiteData_release(); + return ret; +} + +BOOL InterfaceSetting4_GetParamUlongValue(ANSC_HANDLE hInsContext, char *ParamName, ULONG *pUlong) +{ + UINT inst = (UINT)(uintptr_t)hInsContext; + DML_DSLITE_LIST *entry; + DML_DSLITE_CONFIG *cfg; + BOOL ret = FALSE; + + entry = WanMgr_getDSLiteEntryByInstance_locked(inst); + if (!entry) + return ret; + + cfg = &entry->CurrCfg; + + if (strcmp(ParamName, "Status") == 0) + { + *pUlong = (ULONG)cfg->Status; /* TODO: ensure backend keeps this updated */ + ret = TRUE; + } + else if (strcmp(ParamName, "EndpointAssignmentPrecedence") == 0) + { + *pUlong = (ULONG)cfg->Mode; + ret = TRUE; + } + else if (strcmp(ParamName, "EndpointAddressTypePrecedence") == 0) + { + *pUlong = (ULONG)cfg->Type; + ret = TRUE; + } + else if (strcmp(ParamName, "Origin") == 0) + { + *pUlong = (ULONG)cfg->Origin; + ret = TRUE; + } + else if (strcmp(ParamName, "X_RDKCENTRAL-COM_Tcpmss") == 0) + { + *pUlong = (ULONG)cfg->TcpMss; + ret = TRUE; + } + + WanMgr_GetDSLiteData_release(); + return ret; +} + +BOOL InterfaceSetting4_SetParamBoolValue(ANSC_HANDLE hInsContext, char *ParamName, BOOL bValue) +{ + UINT inst = (UINT)(uintptr_t)hInsContext; + DML_DSLITE_LIST *entry; + DML_DSLITE_CONFIG *cfg; + UINT deviceMode = 0; + BOOL ret = FALSE; + + entry = WanMgr_getDSLiteEntryByInstance_locked(inst); + if (!entry) + return ret; + + WanMgr_SysCfgGetUint("last_erouter_mode", &deviceMode); + if ((DML_WAN_DEVICE_MODE)deviceMode != DML_WAN_DEVICE_MODE_Ipv6) + { + CcspTraceWarning(("Cannot set DSLite.InterfaceSetting, device mode is not ipv6 only\n")); + WanMgr_GetDSLiteData_release(); + return FALSE; + } + + cfg = &entry->CurrCfg; + + if (strcmp(ParamName, "Enable") == 0) + { + cfg->Enable = bValue; + ret = TRUE; + } + else if (strcmp(ParamName, "X_RDKCENTRAL-COM_MssClampingEnable") == 0) + { + cfg->MssClampingEnable = bValue; + ret = TRUE; + } + else if (strcmp(ParamName, "X_RDKCENTRAL-COM_IPv6FragEnable") == 0) + { + cfg->Ipv6FragEnable = bValue; + ret = TRUE; + } + + WanMgr_GetDSLiteData_release(); + return ret; +} + +BOOL InterfaceSetting4_SetParamStringValue(ANSC_HANDLE hInsContext, char *ParamName, char *pString) +{ + UINT inst = (UINT)(uintptr_t)hInsContext; + DML_DSLITE_LIST *entry; + DML_DSLITE_CONFIG *cfg; + char *dst = NULL; + size_t dst_size = 0; + BOOL ret = FALSE; + + entry = WanMgr_getDSLiteEntryByInstance_locked(inst); + if (!entry) + return ret; + + cfg = &entry->CurrCfg; + + CcspTraceWarning(("Dslite: set %s to %s\n", ParamName, pString)); + + if (strcmp(ParamName, "Alias") == 0) + { + dst = cfg->Alias; + dst_size = sizeof(cfg->Alias); + } + else if (strcmp(ParamName, "EndpointName") == 0) + { + /* EndpointName writable only when EndpointAssignmentPrecedence is Static */ + if (cfg->Mode != DSLITE_ENDPOINT_STATIC) + { + WanMgr_GetDSLiteData_release(); + return FALSE; + } + dst = cfg->EndpointName; + dst_size = sizeof(cfg->EndpointName); + } + else if (strcmp(ParamName, "EndpointAddress") == 0) + { + dst = cfg->EndpointAddr; + dst_size = sizeof(cfg->EndpointAddr); + } + else if (strcmp(ParamName, "TunnelV4Addr") == 0) + { + dst = cfg->TunnelV4Addr; + dst_size = sizeof(cfg->TunnelV4Addr); + } + + if (dst == NULL || (strlen(pString) >= dst_size)) + { + ret = FALSE; + } + else + { + strncpy(dst, pString, dst_size); + dst[dst_size - 1] = '\0'; + ret = TRUE; + } + + WanMgr_GetDSLiteData_release(); + return ret; +} + +BOOL InterfaceSetting4_SetParamUlongValue(ANSC_HANDLE hInsContext, char *ParamName, ULONG uValue) +{ + UINT inst = (UINT)(uintptr_t)hInsContext; + DML_DSLITE_LIST *entry; + DML_DSLITE_CONFIG *cfg; + BOOL ret = FALSE; + + entry = WanMgr_getDSLiteEntryByInstance_locked(inst); + if (!entry) + return ret; + + cfg = &entry->CurrCfg; + + if (strcmp(ParamName, "EndpointAssignmentPrecedence") == 0) + { + cfg->Mode = (DML_WAN_DSLITE_ADDR_METHOD)uValue; + ret = TRUE; + } + else if (strcmp(ParamName, "EndpointAddressTypePrecedence") == 0) + { + cfg->Type = (DML_WAN_DSLITE_ADDR_PRECEDENCE)uValue; + ret = TRUE; + } + else if (strcmp(ParamName, "X_RDKCENTRAL-COM_Tcpmss") == 0) + { + cfg->TcpMss = uValue; + ret = TRUE; + } + + WanMgr_GetDSLiteData_release(); + return ret; +} + +ULONG InterfaceSetting4_GetEntryCount(ANSC_HANDLE hInsContext) +{ + UNREFERENCED_PARAMETER(hInsContext); + WanMgr_DSLite_Data_t *pDSLiteData; + ULONG count = 0; + + pDSLiteData = WanMgr_GetDSLiteData_locked(); + if (!pDSLiteData) + return 0; + + count = (ULONG)pDSLiteData->InterfaceSettingNumberOfEntries; + + WanMgr_GetDSLiteData_release(); + return count; +} + +ANSC_HANDLE InterfaceSetting4_GetEntry(ANSC_HANDLE hInsContext, ULONG nIndex, ULONG *pInsNumber) +{ + UNREFERENCED_PARAMETER(hInsContext); + UINT inst; + DML_DSLITE_LIST *entry; + + entry = WanMgr_getDSLiteEntryByIdx_locked(nIndex); + if (!entry) + return NULL; + + *pInsNumber = entry->InstanceNumber; + inst = entry->InstanceNumber; + + WanMgr_GetDSLiteData_release(); + return (ANSC_HANDLE)(uintptr_t)inst; +} + +ANSC_HANDLE InterfaceSetting4_AddEntry(ANSC_HANDLE hInsContext, ULONG *pInsNumber) +{ + UNREFERENCED_PARAMETER(hInsContext); + UINT inst; + WanMgr_DSLite_Data_t *pDSLiteData; + + pDSLiteData = WanMgr_GetDSLiteData_locked(); + if (!pDSLiteData) + return NULL; + + if (pDSLiteData->InterfaceSettingNumberOfEntries >= MAX_DSLITE_CONFIG_ENTRY) + { + CcspTraceError(("%s: reached max entries %d\n", + __FUNCTION__, MAX_DSLITE_CONFIG_ENTRY)); + WanMgr_GetDSLiteData_release(); + return NULL; + } + inst = pDSLiteData->NextInstanceNumber++; + WanMgr_GetDSLiteData_release(); + + if (WanMgr_DSLite_AddToList(inst) != ANSC_STATUS_SUCCESS) + { + CcspTraceError(("%s: WanMgr_DSLite_AddToList failed\n", __FUNCTION__)); + return NULL; + } + *pInsNumber = inst; + + return (ANSC_HANDLE)(uintptr_t)inst; +} + +ULONG InterfaceSetting4_DelEntry(ANSC_HANDLE hInsContext, ANSC_HANDLE hInstance) +{ + UNREFERENCED_PARAMETER(hInsContext); + UINT inst = (UINT)(uintptr_t)hInstance; + + if (WanMgr_DSLite_DelFromList(inst) != ANSC_STATUS_SUCCESS) + { + CcspTraceError(("%s: WanMgr_DSLite_DelFromList failed\n", __FUNCTION__)); + return ANSC_STATUS_FAILURE; + } + + if (WanMgr_DSLite_DelFromSyscfg(inst) != ANSC_STATUS_SUCCESS) + { + CcspTraceError(("%s: WanMgr_DSLite_DelFromSyscfg failed\n", __FUNCTION__)); + return ANSC_STATUS_FAILURE; + } + + if (WanMgr_DSLite_WriteDSLiteCfgToSyscfg() != ANSC_STATUS_SUCCESS) + { + CcspTraceError(("%s: Failed to write DSLite main config after delete\n", __FUNCTION__)); + return ANSC_STATUS_FAILURE; + } + + return ANSC_STATUS_SUCCESS; +} + +BOOL InterfaceSetting4_Validate(ANSC_HANDLE hInsContext, char *pReturnParamName, ULONG *puLength) +{ + UNREFERENCED_PARAMETER(pReturnParamName); + UNREFERENCED_PARAMETER(puLength); + WanMgr_DSLite_Data_t* pDSLiteData; + DML_DSLITE_CONFIG *cfgThis; + DML_DSLITE_LIST *pThis, *entry; + UINT inst = (UINT)(uintptr_t)hInsContext; + BOOL ret = TRUE; + + pThis = WanMgr_getDSLiteEntryByInstance_locked(inst); + if (!pThis) + return FALSE; + + pDSLiteData = &gWanMgrDataBase.DSLite; + cfgThis = &pThis->CurrCfg; + if (cfgThis->Alias[0] != '\0') + { + /* Validate this instance by checking if another instance with the same Alias exists */ + entry = pDSLiteData->DSLiteList; // Called under lock, so no problem + while (entry) + { + if (entry != pThis) + { + DML_DSLITE_CONFIG *cfgOther = &entry->CurrCfg; + + if (strcmp(cfgOther->Alias, cfgThis->Alias) == 0) + { + ret = FALSE; + break; + } + } + entry = entry->next; + } + } + + WanMgr_GetDSLiteData_release(); + return ret; +} + +ULONG InterfaceSetting4_Commit(ANSC_HANDLE hInsContext) +{ + UINT inst = (UINT)(uintptr_t)hInsContext; + + if (WanMgr_DSLite_WriteDSLiteCfgToSyscfg() != ANSC_STATUS_SUCCESS) + { + CcspTraceError(("%s: Failed to write DSLite main config to syscfg\n", __FUNCTION__)); + return ANSC_STATUS_FAILURE; + } + + if (WanMgr_DSLite_WriteEntryCfgToSyscfg(inst) != ANSC_STATUS_SUCCESS) + { + CcspTraceError(("%s: Failed to write DSLite entry to syscfg\n", __FUNCTION__)); + + return ANSC_STATUS_FAILURE; + } + + if (WanMgr_DSLite_UpdateVirtIfDSLiteCfg(inst) != ANSC_STATUS_SUCCESS) + { + CcspTraceError(("%s: Failed to write DSLite entry to syscfg\n", __FUNCTION__)); + + return ANSC_STATUS_FAILURE; + } + + return ANSC_STATUS_SUCCESS; +} + +ULONG InterfaceSetting4_Rollback(ANSC_HANDLE hInsContext) +{ + UINT inst = (UINT)(uintptr_t)hInsContext; + WanMgr_DSLite_Data_t* pDSLiteData; + DML_DSLITE_LIST *entry; + + entry = WanMgr_getDSLiteEntryByInstance_locked(inst); + if (!entry) + return ANSC_STATUS_FAILURE; + + pDSLiteData = &gWanMgrDataBase.DSLite; + + if (entry->New) + { + /* remove from list and free it */ + DML_DSLITE_LIST *prev = NULL; + DML_DSLITE_LIST *curr = pDSLiteData->DSLiteList; // called under lock. So no problem + + while (curr) + { + if (curr == entry) + { + if (prev) + prev->next = curr->next; + else + pDSLiteData->DSLiteList = curr->next; + + AnscFreeMemory(curr); + if (pDSLiteData->InterfaceSettingNumberOfEntries > 0) + pDSLiteData->InterfaceSettingNumberOfEntries--; + + WanMgr_GetDSLiteData_release(); + return ANSC_STATUS_SUCCESS; + } + + prev = curr; + curr = curr->next; + } + } + else + { + entry->CurrCfg = entry->PrevCfg; + } + + WanMgr_GetDSLiteData_release(); + return ANSC_STATUS_SUCCESS; +} diff --git a/source/TR-181/middle_layer_src/wanmgr_dml_dslite_apis.h b/source/TR-181/middle_layer_src/wanmgr_dml_dslite_apis.h new file mode 100644 index 00000000..467ff239 --- /dev/null +++ b/source/TR-181/middle_layer_src/wanmgr_dml_dslite_apis.h @@ -0,0 +1,72 @@ +/********************************************************************** + * Copyright 2025 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +**********************************************************************/ + +#ifndef _WANMGR_DML_DSLITE_APIS_H +#define _WANMGR_DML_DSLITE_APIS_H + +#include "ansc_platform.h" + + +/*********************************************************************** + + APIs for Object: + + DSLite. + + * DSLite_GetParamBoolValue + * DSLite_SetParamBoolValue + + * InterfaceSetting4_GetEntryCount + * InterfaceSetting4_GetEntry + * InterfaceSetting4_AddEntry + * InterfaceSetting4_DelEntry + + * InterfaceSetting4_GetParamBoolValue + * InterfaceSetting4_GetParamStringValue + * InterfaceSetting4_GetParamUlongValue + + * InterfaceSetting4_SetParamBoolValue + * InterfaceSetting4_SetParamStringValue + * InterfaceSetting4_SetParamUlongValue + + * InterfaceSetting4_Validate + * InterfaceSetting4_Commit + * InterfaceSetting4_Rollback + +***********************************************************************/ + +BOOL DSLite_GetParamBoolValue(ANSC_HANDLE hInsContext, char *ParamName, BOOL *pBool); +BOOL DSLite_SetParamBoolValue(ANSC_HANDLE hInsContext, char *ParamName, BOOL bValue); +BOOL DSLite_GetParamUlongValue(ANSC_HANDLE hInsContext, char *ParamName, ULONG *pUlong); + +ULONG InterfaceSetting4_GetEntryCount(ANSC_HANDLE hInsContext); +ANSC_HANDLE InterfaceSetting4_GetEntry(ANSC_HANDLE hInsContext, ULONG nIndex, ULONG *pInsNumber); +ANSC_HANDLE InterfaceSetting4_AddEntry(ANSC_HANDLE hInsContext, ULONG *pInsNumber); +ULONG InterfaceSetting4_DelEntry(ANSC_HANDLE hInsContext, ANSC_HANDLE hInstance); + +BOOL InterfaceSetting4_GetParamBoolValue(ANSC_HANDLE hInsContext, char *ParamName, BOOL *pBool); +ULONG InterfaceSetting4_GetParamStringValue(ANSC_HANDLE hInsContext, char *ParamName, char *pValue, ULONG *pUlSize); +BOOL InterfaceSetting4_GetParamUlongValue(ANSC_HANDLE hInsContext, char *ParamName, ULONG *pUlong); + +BOOL InterfaceSetting4_SetParamBoolValue(ANSC_HANDLE hInsContext, char *ParamName, BOOL bValue); +BOOL InterfaceSetting4_SetParamStringValue(ANSC_HANDLE hInsContext, char *ParamName, char *strValue); +BOOL InterfaceSetting4_SetParamUlongValue(ANSC_HANDLE hInsContext, char *ParamName, ULONG uValue); + +BOOL InterfaceSetting4_Validate(ANSC_HANDLE hInsContext, char *pReturnParamName, ULONG *puLength); +ULONG InterfaceSetting4_Commit(ANSC_HANDLE hInsContext); +ULONG InterfaceSetting4_Rollback(ANSC_HANDLE hInsContext); + +#endif diff --git a/source/TR-181/middle_layer_src/wanmgr_plugin_main.c b/source/TR-181/middle_layer_src/wanmgr_plugin_main.c index 9a0f1dcb..713d5478 100644 --- a/source/TR-181/middle_layer_src/wanmgr_plugin_main.c +++ b/source/TR-181/middle_layer_src/wanmgr_plugin_main.c @@ -67,6 +67,9 @@ #endif /** WAN_MANAGER_UNIFICATION_ENABLED */ #include "wanmgr_dml_dhcpv4.h" #include "wanmgr_dml_dhcpv6.h" +#ifdef FEATURE_DSLITE_V2 +#include "wanmgr_dml_dslite_apis.h" +#endif void * g_pDslhDmlAgent; extern ANSC_HANDLE g_MessageBusHandle_Irep; @@ -581,7 +584,24 @@ int ANSC_EXPORT_API WanManagerDmlInit(ULONG uMaxVersionSupported, void* hCosaPlu pPlugInfo->RegisterFunction(pPlugInfo->hContext, "SentOption_GetEntryCount", SentOption_GetEntryCount); - +#ifdef FEATURE_DSLITE_V2 + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "DSLite_GetParamBoolValue", DSLite_GetParamBoolValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "DSLite_SetParamBoolValue", DSLite_SetParamBoolValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "DSLite_GetParamUlongValue", DSLite_GetParamUlongValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "InterfaceSetting4_GetEntryCount", InterfaceSetting4_GetEntryCount); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "InterfaceSetting4_GetEntry", InterfaceSetting4_GetEntry); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "InterfaceSetting4_AddEntry", InterfaceSetting4_AddEntry); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "InterfaceSetting4_DelEntry", InterfaceSetting4_DelEntry); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "InterfaceSetting4_GetParamBoolValue", InterfaceSetting4_GetParamBoolValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "InterfaceSetting4_GetParamStringValue", InterfaceSetting4_GetParamStringValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "InterfaceSetting4_GetParamUlongValue", InterfaceSetting4_GetParamUlongValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "InterfaceSetting4_SetParamBoolValue", InterfaceSetting4_SetParamBoolValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "InterfaceSetting4_SetParamStringValue", InterfaceSetting4_SetParamStringValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "InterfaceSetting4_SetParamUlongValue", InterfaceSetting4_SetParamUlongValue); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "InterfaceSetting4_Validate", InterfaceSetting4_Validate); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "InterfaceSetting4_Commit", InterfaceSetting4_Commit); + pPlugInfo->RegisterFunction(pPlugInfo->hContext, "InterfaceSetting4_Rollback", InterfaceSetting4_Rollback); +#endif /* Create backend framework */ g_pWanMgrBE = (WANMGR_BACKEND_OBJ*)BackEndManagerCreate(); diff --git a/source/TR-181/middle_layer_src/wanmgr_plugin_main_apis.h b/source/TR-181/middle_layer_src/wanmgr_plugin_main_apis.h index 8bcd1665..d3525388 100644 --- a/source/TR-181/middle_layer_src/wanmgr_plugin_main_apis.h +++ b/source/TR-181/middle_layer_src/wanmgr_plugin_main_apis.h @@ -121,7 +121,9 @@ extern COSARegisterCallBackAfterInitDmlProc g_RegisterCallBackAfterInitDml; #define DATAMODEL_RDKCENTRAL_CM_OID 42 #define WAN_DHCPV6_DATA_OID 25 #define WAN_DHCPV4_DATA_OID 2 - +#ifdef FEATURE_DSLITE_V2 +#define WAN_DSLITE_DATA_OID 122 +#endif typedef struct _WANMGR_BACKEND_OBJ_ { diff --git a/source/TR-181/middle_layer_src/wanmgr_rdkbus_apis.c b/source/TR-181/middle_layer_src/wanmgr_rdkbus_apis.c index 54716314..e5b15167 100644 --- a/source/TR-181/middle_layer_src/wanmgr_rdkbus_apis.c +++ b/source/TR-181/middle_layer_src/wanmgr_rdkbus_apis.c @@ -261,6 +261,13 @@ int get_Virtual_Interface_FromPSM(ULONG instancenum, ULONG virtInsNum ,DML_VIRTU pVirtIf->EnableDSLite = TRUE; } +#ifdef FEATURE_DSLITE_V2 + _ansc_memset(param_name, 0, sizeof(param_name)); + _ansc_memset(param_value, 0, sizeof(param_value)); + _ansc_sprintf(param_name, PSM_WANMANAGER_IF_VIRIF_DSLITE_PATH, instancenum, (virtInsNum + 1)); + retPsmGet = WanMgr_RdkBus_GetParamValuesFromDB(param_name,param_value,sizeof(param_value)); + AnscCopyString(pVirtIf->DSLite.Path, param_value); +#endif _ansc_memset(param_name, 0, sizeof(param_name)); _ansc_memset(param_value, 0, sizeof(param_value)); _ansc_sprintf(param_name, PSM_WANMANAGER_IF_VIRIF_ENABLE, instancenum, (virtInsNum + 1)); diff --git a/source/TR-181/middle_layer_src/wanmgr_rdkbus_utils.c b/source/TR-181/middle_layer_src/wanmgr_rdkbus_utils.c index fb30c8af..86ed21e6 100644 --- a/source/TR-181/middle_layer_src/wanmgr_rdkbus_utils.c +++ b/source/TR-181/middle_layer_src/wanmgr_rdkbus_utils.c @@ -1224,4 +1224,94 @@ ANSC_STATUS WanManager_RdkBus_EnableInterface(DML_WAN_IFACE* pInterface, BOOL En CcspTraceInfo(("%s %d DM %s(value:%s) and %s is for %s param Successful\n", __FUNCTION__,__LINE__, ((Enable) ? "Set" : "Unset"), acSetParamValue, ((Enable) ? "Subscribe" : "Unsubscribe"), acSetParamName)); return ANSC_STATUS_SUCCESS; -} \ No newline at end of file +} + +#ifdef FEATURE_DSLITE_V2 +int WanMgr_SetDSLiteEnableToPSM(DML_VIRTUAL_IFACE* pVirtIf, BOOL Enable) +{ + int retPsmSet = CCSP_SUCCESS; + char param_name[256] = {0}; + char param_value[256] = {0}; + + _ansc_sprintf(param_value, Enable ? "TRUE" : "FALSE"); + _ansc_sprintf(param_name, PSM_WANMANAGER_IF_VIRIF_ENABLE_DSLITE, pVirtIf->baseIfIdx +1, pVirtIf->VirIfIdx+1); + WanMgr_RdkBus_SetParamValuesToDB(param_name,param_value); + CcspTraceInfo(("%s-%d: EnableDSLite(%s) set to (%s)\n", __FUNCTION__, __LINE__, param_name, param_value)); + return 0; +} + +ANSC_STATUS WanMgr_SysCfgGetBool(const CHAR *key, BOOL *value) +{ + if (!key || !value) + return ANSC_STATUS_BAD_PARAMETER; + + char buf[8] = {0}; + + if (syscfg_get(NULL, key, buf, sizeof(buf)) != 0) + return ANSC_STATUS_FAILURE; + + if (strcasecmp(buf, "true") == 0 || buf[0] == '1') + *value = TRUE; + else + *value = FALSE; + + return ANSC_STATUS_SUCCESS; +} + +ANSC_STATUS WanMgr_SysCfgGetUint(const CHAR *key, UINT *value) +{ + if (!key || !value) + return ANSC_STATUS_BAD_PARAMETER; + + char buf[64] = {0}; + + if (syscfg_get(NULL, key, buf, sizeof(buf)) != 0) + return ANSC_STATUS_FAILURE; + + *value = atoi(buf); + return ANSC_STATUS_SUCCESS; +} + +ANSC_STATUS WanMgr_SysCfgGetStr(const CHAR *key, CHAR *dst, ULONG dst_len) +{ + if (!key || !dst || dst_len == 0) + return ANSC_STATUS_BAD_PARAMETER; + + dst[0] = '\0'; + + char buf[512] = {0}; + + if (syscfg_get(NULL, key, buf, sizeof(buf)) != 0) + return ANSC_STATUS_FAILURE; + + buf[sizeof(buf) - 1] = '\0'; + snprintf(dst, dst_len, "%s", buf); + + return ANSC_STATUS_SUCCESS; +} + +ANSC_STATUS WanMgr_SysCfgSetUint(const CHAR *key, UINT value) +{ + if (!key) + return ANSC_STATUS_BAD_PARAMETER; + + char buf[32]; + snprintf(buf, sizeof(buf), "%u", value); + + if (syscfg_set(NULL, key, buf) != 0) + return ANSC_STATUS_FAILURE; + + return ANSC_STATUS_SUCCESS; +} + +ANSC_STATUS WanMgr_SysCfgSetStr(const CHAR *key, const CHAR *value) +{ + if (!key || !value) + return ANSC_STATUS_BAD_PARAMETER; + + if (syscfg_set(NULL, key, value) != 0) + return ANSC_STATUS_FAILURE; + + return ANSC_STATUS_SUCCESS; +} +#endif \ No newline at end of file diff --git a/source/TR-181/middle_layer_src/wanmgr_rdkbus_utils.h b/source/TR-181/middle_layer_src/wanmgr_rdkbus_utils.h index d8a3192d..67579a49 100644 --- a/source/TR-181/middle_layer_src/wanmgr_rdkbus_utils.h +++ b/source/TR-181/middle_layer_src/wanmgr_rdkbus_utils.h @@ -238,4 +238,18 @@ void Wanmgr_TriggerReboot(); */ BOOL WanMgr_isBridgeModeEnabled(); +#if FEATURE_DSLITE_V2 +int WanMgr_SetDSLiteEnableToPSM(DML_VIRTUAL_IFACE *pVirtIf, BOOL Enable); +ANSC_STATUS WanMgr_SysCfgGetBool(const CHAR *key, BOOL *value); +ANSC_STATUS WanMgr_SysCfgGetUint(const CHAR *key, UINT *value); +ANSC_STATUS WanMgr_SysCfgGetStr(const CHAR *key, CHAR *dst, ULONG dst_len); +ANSC_STATUS WanMgr_SysCfgSetUint(const CHAR *key, UINT value); +ANSC_STATUS WanMgr_SysCfgSetStr(const CHAR *key, const CHAR *value); +#define DSLITE_WRITE_IF_CHANGED(cond, call) \ + do \ + { \ + if ((cond) && (call) != ANSC_STATUS_SUCCESS) \ + ret = ANSC_STATUS_FAILURE; \ + } while (0) +#endif #endif /* _WANMGR_RDKBUS_UTILS_H_ */ diff --git a/source/WanManager/Makefile.am b/source/WanManager/Makefile.am index 8be2afc6..60647d20 100644 --- a/source/WanManager/Makefile.am +++ b/source/WanManager/Makefile.am @@ -48,3 +48,7 @@ wanmanager_SOURCES += wanmgr_dhcp_event_handler.c else wanmanager_LDADD += -ldhcp_client_utils endif + +if DSLITE_SUPPORT +wanmanager_SOURCES += wanmgr_dslite.c +endif \ No newline at end of file diff --git a/source/WanManager/wanmgr_data.c b/source/WanManager/wanmgr_data.c index 572dcf0a..84710e68 100644 --- a/source/WanManager/wanmgr_data.c +++ b/source/WanManager/wanmgr_data.c @@ -21,6 +21,10 @@ #include "wanmgr_data.h" #include "wanmgr_rdkbus_apis.h" +#ifdef FEATURE_DSLITE_V2 +#include "wanmgr_dslite.h" +#endif + #if defined(WAN_MANAGER_UNIFICATION_ENABLED) && (defined (_XB6_PRODUCT_REQ_) || defined (_CBR2_PRODUCT_REQ_) || defined(_PLATFORM_RASPBERRYPI_)) extern ANSC_STATUS WanMgr_CheckAndResetV2PSMEntries(UINT IfaceCount); #endif @@ -28,6 +32,417 @@ extern ANSC_STATUS WanMgr_CheckAndResetV2PSMEntries(UINT IfaceCount); /******** WAN MGR DATABASE ********/ WANMGR_DATA_ST gWanMgrDataBase; +#ifdef FEATURE_DSLITE_V2 +/******** WANMGR DSLITE FUNCTIONS ********/ +/** + * @brief Checks if the DSLite feature is enabled for a given virtual interface. + * + * This function determines whether the DSLite feature is enabled globally and for the specified virtual interface. + * + * @param[in] p_VirtIf Pointer to the virtual interface structure to check. + * + * @return TRUE if DSLite is enabled for the interface, FALSE otherwise. + */ +BOOL WanMgr_DSLite_isEnabled(DML_VIRTUAL_IFACE *p_VirtIf) +{ + WanMgr_DSLite_Data_t *pDSLiteData; + BOOL enabled = FALSE; + + pDSLiteData = WanMgr_GetDSLiteData_locked(); + if (!pDSLiteData) + return FALSE; + + enabled = pDSLiteData->Enable && p_VirtIf->EnableDSLite; + + WanMgr_GetDSLiteData_release(); + return enabled; +} + +ANSC_STATUS WanMgr_DSLite_UpdateVirtIfDSLiteCfg(UINT inst) +{ + DML_DSLITE_LIST *entry; + DML_VIRTUAL_IFACE *p_VirtIf; + + entry = WanMgr_getDSLiteEntryByInstance_locked(inst); + if (!entry) + return ANSC_STATUS_FAILURE; + + p_VirtIf = WanMgr_GetVirtIfDataByDSLiteAlias_locked(entry->CurrCfg.Alias); + if (!p_VirtIf) + { + WanMgr_GetDSLiteData_release(); + return ANSC_STATUS_FAILURE; + } + + if (p_VirtIf->EnableDSLite != entry->CurrCfg.Enable) + { + p_VirtIf->EnableDSLite = entry->CurrCfg.Enable; + p_VirtIf->DSLite.Changed = TRUE; + WanMgr_SetDSLiteEnableToPSM(p_VirtIf, p_VirtIf->EnableDSLite); + + } + WanMgr_VirtualIfaceData_release(p_VirtIf); + + WanMgr_GetDSLiteData_release(); + return ANSC_STATUS_SUCCESS; +} + +ANSC_STATUS WanMgr_DSLite_WriteDSLiteCfgToSyscfg(void) +{ + WanMgr_DSLite_Data_t *pDSLiteData; + ANSC_STATUS ret = ANSC_STATUS_SUCCESS; + + pDSLiteData = WanMgr_GetDSLiteData_locked(); + if (!pDSLiteData) + return ANSC_STATUS_FAILURE; + + if (pDSLiteData->Changed) + { + CcspTraceInfo(("%s: Writing DSLite main config to sysCfg\n", __FUNCTION__)); + + if (WanMgr_SysCfgSetUint("dslite_next_insNum", pDSLiteData->NextInstanceNumber) != ANSC_STATUS_SUCCESS) + { + CcspTraceError(("%s: Failed to set dslite_next_instance_number in syscfg\n", __FUNCTION__)); + ret = ANSC_STATUS_FAILURE; + } + if (WanMgr_SysCfgSetUint("dslite_count", pDSLiteData->InterfaceSettingNumberOfEntries) != ANSC_STATUS_SUCCESS) + { + CcspTraceError(("%s: Failed to set dslite_count in syscfg\n", __FUNCTION__)); + ret = ANSC_STATUS_FAILURE; + } + if (WanMgr_SysCfgSetUint("dslite_enable", pDSLiteData->Enable ? 1 : 0) != ANSC_STATUS_SUCCESS) + { + CcspTraceError(("%s: Failed to set dslite_enable in syscfg\n", __FUNCTION__)); + ret = ANSC_STATUS_FAILURE; + } + pDSLiteData->Changed = FALSE; + if (syscfg_commit() != 0) + { + CcspTraceError(("%s: syscfg_commit() failed\n", __FUNCTION__)); + ret = ANSC_STATUS_FAILURE; + } + } + + WanMgr_GetDSLiteData_release(); + return ret; +} + +ANSC_STATUS WanMgr_DSLite_WriteEntryCfgToSyscfg(UINT inst) +{ + ANSC_STATUS ret = ANSC_STATUS_SUCCESS; + DML_DSLITE_CONFIG *prev, *curr; + DML_DSLITE_LIST *entry; + char key[BUFLEN_64]; + + entry = WanMgr_getDSLiteEntryByInstance_locked(inst); + if (!entry) + return ANSC_STATUS_FAILURE; + + prev = &entry->PrevCfg; + curr = &entry->CurrCfg; + + if (!entry->New && memcmp(prev, curr, sizeof(*prev)) == 0) + { + /* Nothing changed.. Returning */ + WanMgr_GetDSLiteData_release(); + return ANSC_STATUS_SUCCESS; + } + + CcspTraceInfo(("%s: Writing DSLite entry with InsNum=%lu to sysCfg\n", __FUNCTION__, inst)); + + snprintf(key, sizeof(key), "dslite_InsNum_%lu", inst); + if (entry->New) + { + if (WanMgr_SysCfgSetUint(key, inst) != ANSC_STATUS_SUCCESS) + ret = ANSC_STATUS_FAILURE; + } + + snprintf(key, sizeof(key), "dslite_active_%lu", inst); + if (entry->New || prev->Enable != curr->Enable) + { + if (WanMgr_SysCfgSetUint(key, curr->Enable ? 1 : 0) != ANSC_STATUS_SUCCESS) + ret = ANSC_STATUS_FAILURE; + } + + snprintf(key, sizeof(key), "dslite_alias_%lu", inst); + if (entry->New || strcmp(prev->Alias, curr->Alias) != 0) + { + if (WanMgr_SysCfgSetStr(key, curr->Alias) != ANSC_STATUS_SUCCESS) + ret = ANSC_STATUS_FAILURE; + } + + snprintf(key, sizeof(key), "dslite_mode_%lu", inst); + if (entry->New || prev->Mode != curr->Mode) + { + if (WanMgr_SysCfgSetUint(key, curr->Mode) != ANSC_STATUS_SUCCESS) + ret = ANSC_STATUS_FAILURE; + } + + snprintf(key, sizeof(key), "dslite_addr_type_%lu", inst); + if (entry->New || prev->Type != curr->Type) + { + if (WanMgr_SysCfgSetUint(key, curr->Type) != ANSC_STATUS_SUCCESS) + ret = ANSC_STATUS_FAILURE; + } + + snprintf(key, sizeof(key), "dslite_addr_fqdn_%lu", inst); + if (entry->New || strcmp(prev->EndpointName, curr->EndpointName) != 0) + { + if (WanMgr_SysCfgSetStr(key, curr->EndpointName) != ANSC_STATUS_SUCCESS) + ret = ANSC_STATUS_FAILURE; + } + + snprintf(key, sizeof(key), "dslite_addr_ipv6_%lu", inst); + if (entry->New || strcmp(prev->EndpointAddr, curr->EndpointAddr) != 0) + { + if (WanMgr_SysCfgSetStr(key, curr->EndpointAddr) != ANSC_STATUS_SUCCESS) + ret = ANSC_STATUS_FAILURE; + } + + snprintf(key, sizeof(key), "dslite_mss_clamping_enable_%lu", inst); + if (entry->New || prev->MssClampingEnable != curr->MssClampingEnable) + { + if (WanMgr_SysCfgSetUint(key, curr->MssClampingEnable ? 1 : 0) != ANSC_STATUS_SUCCESS) + ret = ANSC_STATUS_FAILURE; + } + + snprintf(key, sizeof(key), "dslite_tcpmss_%lu", inst); + if (entry->New || prev->TcpMss != curr->TcpMss) + { + if (WanMgr_SysCfgSetUint(key, curr->TcpMss) != ANSC_STATUS_SUCCESS) + ret = ANSC_STATUS_FAILURE; + } + + snprintf(key, sizeof(key), "dslite_ipv6_frag_enable_%lu", inst); + if (entry->New || prev->Ipv6FragEnable != curr->Ipv6FragEnable) + { + if (WanMgr_SysCfgSetUint(key, curr->Ipv6FragEnable ? 1 : 0) != ANSC_STATUS_SUCCESS) + ret = ANSC_STATUS_FAILURE; + } + + snprintf(key, sizeof(key), "dslite_tunnel_v4addr_%lu", inst); + if (entry->New || strcmp(prev->TunnelV4Addr, curr->TunnelV4Addr) != 0) + { + if (WanMgr_SysCfgSetStr(key, curr->TunnelV4Addr) != ANSC_STATUS_SUCCESS) + ret = ANSC_STATUS_FAILURE; + } + + if (syscfg_commit() != 0) + { + CcspTraceError(("%s: syscfg_commit() failed\n", __FUNCTION__)); + ret = ANSC_STATUS_FAILURE; + } + + if (ret != ANSC_STATUS_FAILURE) + { + *prev = *curr; + entry->New = FALSE; + } + + WanMgr_GetDSLiteData_release(); + + return ret; +} + +ANSC_STATUS WanMgr_DSLite_AddToList(UINT inst) +{ + DML_DSLITE_LIST *entry; + WanMgr_DSLite_Data_t *pDSLiteData; + + pDSLiteData = WanMgr_GetDSLiteData_locked(); + if (!pDSLiteData) + return ANSC_STATUS_FAILURE; + + entry = (DML_DSLITE_LIST *)AnscAllocateMemory(sizeof(DML_DSLITE_LIST)); + if (!entry) + { + CcspTraceError(("%s: allocation failed\n", __FUNCTION__)); + WanMgr_GetDSLiteData_release(); + return ANSC_STATUS_FAILURE; + } + + DSLITE_SET_DEFAULTVALUE(&entry->PrevCfg); + DSLITE_SET_DEFAULTVALUE(&entry->CurrCfg); + + snprintf(entry->CurrCfg.Alias, + sizeof(entry->CurrCfg.Alias), + "Dslite.Tunnel.%u", inst); + + entry->InstanceNumber = inst; + entry->New = TRUE; + entry->next = NULL; + + /* insert at list head */ + entry->next = pDSLiteData->DSLiteList; + pDSLiteData->DSLiteList = entry; + pDSLiteData->InterfaceSettingNumberOfEntries++; + pDSLiteData->Changed = TRUE; + + WanMgr_GetDSLiteData_release(); + return ANSC_STATUS_SUCCESS; +} + +ANSC_STATUS WanMgr_DSLite_DelFromList(UINT inst) +{ + WanMgr_DSLite_Data_t *pDSLiteData; + DML_DSLITE_LIST *prev = NULL, *curr = NULL; + + pDSLiteData = WanMgr_GetDSLiteData_locked(); + if (!pDSLiteData) + return ANSC_STATUS_FAILURE; + + curr = pDSLiteData->DSLiteList; + while (curr) + { + if (curr->InstanceNumber == inst) + { + if (prev) + prev->next = curr->next; + else + pDSLiteData->DSLiteList = curr->next; + + AnscFreeMemory(curr); + + pDSLiteData->InterfaceSettingNumberOfEntries--; + pDSLiteData->Changed = TRUE; + WanMgr_GetDSLiteData_release(); + return ANSC_STATUS_SUCCESS; + } + + prev = curr; + curr = curr->next; + } + + WanMgr_GetDSLiteData_release(); + return ANSC_STATUS_FAILURE; +} + +ANSC_STATUS WanMgr_DSLite_DelFromSyscfg(ULONG inst) +{ + char key[BUFLEN_64]; + int rc = 0; + + const char *fields[] = { + "dslite_InsNum_%lu", + "dslite_active_%lu", + "dslite_alias_%lu", + "dslite_mode_%lu", + "dslite_addr_type_%lu", + "dslite_addr_fqdn_%lu", + "dslite_addr_ipv6_%lu", + "dslite_mss_clamping_enable_%lu", + "dslite_tcpmss_%lu", + "dslite_ipv6_frag_enable_%lu", + "dslite_tunnel_v4addr_%lu" + }; + + for (size_t i = 0; i < sizeof(fields)/sizeof(fields[0]); i++) + { + snprintf(key, sizeof(key), fields[i], inst); + if (syscfg_unset(NULL, key) != 0) + { + CcspTraceError(("%s: syscfg_unset(%s) failed\n", + __FUNCTION__, key)); + rc = -1; + } + } + + if (syscfg_commit() != 0) + { + CcspTraceError(("%s: syscfg_commit() failed\n", __FUNCTION__)); + rc = -1; + } + + return (rc == 0) ? ANSC_STATUS_SUCCESS : ANSC_STATUS_FAILURE; +} + +DML_DSLITE_LIST *WanMgr_getDSLiteEntryByInstance_locked(UINT inst) +{ + if (pthread_mutex_lock(&gWanMgrDataBase.gDataMutex) == 0) + { + WanMgr_DSLite_Data_t *pDSLite = &gWanMgrDataBase.DSLite; + DML_DSLITE_LIST *entry = pDSLite->DSLiteList; + + while (entry != NULL) + { + if (entry->InstanceNumber == (ULONG)inst) + { + return entry; + } + entry = entry->next; + } + WanMgr_GetDSLiteData_release(); + } + return NULL; +} + +DML_DSLITE_LIST *WanMgr_getDSLiteEntryByIdx_locked(UINT idx) +{ + if (pthread_mutex_lock(&gWanMgrDataBase.gDataMutex) == 0) + { + UINT i = 0; + WanMgr_DSLite_Data_t *pDSLite = &(gWanMgrDataBase.DSLite); + DML_DSLITE_LIST *entry = pDSLite->DSLiteList; + + while (entry != NULL) + { + if (i++ == idx) + { + return entry; + } + entry = entry->next; + } + WanMgr_GetDSLiteData_release(); + } + return NULL; +} + +DML_DSLITE_LIST *WanMgr_getDSLiteEntryByAlias_locked(char *Alias) +{ + if (Alias == NULL) + return NULL; + + if (pthread_mutex_lock(&gWanMgrDataBase.gDataMutex) == 0) + { + WanMgr_DSLite_Data_t *pDSLite = &gWanMgrDataBase.DSLite; + DML_DSLITE_LIST *entry = pDSLite->DSLiteList; + + while (entry != NULL) + { + if (!strcmp(entry->CurrCfg.Alias, Alias)) + { + return entry; + } + + entry = entry->next; + } + WanMgr_GetDSLiteData_release(); + } + return NULL; +} + +WanMgr_DSLite_Data_t* WanMgr_GetDSLiteData_locked(void) +{ + WanMgr_DSLite_Data_t* pDSLiteData = &(gWanMgrDataBase.DSLite); + + //lock + if(pthread_mutex_lock(&gWanMgrDataBase.gDataMutex) == 0) + { + return pDSLiteData; + } + + return NULL; +} + +void WanMgr_GetDSLiteData_release(void) +{ + WanMgr_DSLite_Data_t* pDSLiteData = &(gWanMgrDataBase.DSLite); + if(pDSLiteData != NULL) + { + pthread_mutex_unlock (&gWanMgrDataBase.gDataMutex); + } +} +#endif /******** WANMGR CONFIG FUNCTIONS ********/ WanMgr_Config_Data_t* WanMgr_GetConfigData_locked(void) @@ -316,6 +731,19 @@ ANSC_STATUS WanMgr_WanConfigInit(void) WanMgr_Group_Configure(); //Wan Interface Configuration init retStatus = WanMgr_WanDataInit(); + if(retStatus != ANSC_STATUS_SUCCESS) + { + return retStatus; + } + +#ifdef FEATURE_DSLITE_V2 + // Wan DSLite Configuration init + retStatus = WanMgr_DSLiteInit(); + if (retStatus != ANSC_STATUS_SUCCESS) + { + return retStatus; + } +#endif return retStatus; } @@ -1114,3 +1542,42 @@ DML_VIRTUAL_IFACE* WanMgr_GetActiveVirtIfData_locked(void) } return NULL; } + +#ifdef FEATURE_DSLITE_V2 +/* + * This function checks virtual interfaces of all Interfaces and retuns if DSLite Alias is found. + */ +DML_VIRTUAL_IFACE* WanMgr_GetVirtIfDataByDSLiteAlias_locked(char* Alias) +{ + if (Alias == NULL) + { + CcspTraceError(("%s %d: invalid args\n", __FUNCTION__, __LINE__)); + return NULL; + } + UINT idx; + + if(pthread_mutex_lock(&gWanMgrDataBase.gDataMutex) == 0) + { + WanMgr_IfaceCtrl_Data_t* pWanIfaceCtrl = &(gWanMgrDataBase.IfaceCtrl); + if(pWanIfaceCtrl->pIface != NULL) + { + for(idx = 0; idx < pWanIfaceCtrl->ulTotalNumbWanInterfaces; idx++) + { + WanMgr_Iface_Data_t* pWanIfaceData = &(pWanIfaceCtrl->pIface[idx]); + DML_VIRTUAL_IFACE* virIface = pWanIfaceData->data.VirtIfList; + while(virIface != NULL) + { + if(!strcmp(Alias,virIface->DSLite.Path)) + { + return virIface; + } + virIface = virIface->next; + } + } + } + WanMgrDml_GetIfaceData_release(NULL); + } + + return NULL; +} +#endif \ No newline at end of file diff --git a/source/WanManager/wanmgr_data.h b/source/WanManager/wanmgr_data.h index 9328723a..f04751f4 100644 --- a/source/WanManager/wanmgr_data.h +++ b/source/WanManager/wanmgr_data.h @@ -32,7 +32,9 @@ //Minimum SelectionTimeOut Value #define SELECTION_TIMEOUT_DEFAULT_MIN 20 #define MAX_WAN_INTERFACE_ENTRY 32 - +#ifdef FEATURE_DSLITE_V2 +#define MAX_DSLITE_CONFIG_ENTRY 16 +#endif //WAN CONFIG WanMgr_Config_Data_t* WanMgr_GetConfigData_locked(void); void WanMgrDml_GetConfigData_release(WanMgr_Config_Data_t* pWanConfigData); @@ -85,4 +87,20 @@ WANMGR_IFACE_GROUP* WanMgr_GetIfaceGroup_locked(UINT iface_index); void WanMgrDml_GetIfaceGroup_release(void); ANSC_STATUS WanMgr_UpdatePrevData(void); void WanMgr_VirtIface_Init(DML_VIRTUAL_IFACE * pVirtIf, UINT iface_index); + +#ifdef FEATURE_DSLITE_V2 +DML_VIRTUAL_IFACE* WanMgr_GetVirtIfDataByDSLiteAlias_locked(char* Alias); +ANSC_STATUS WanMgr_DSLite_DelFromSyscfg(ULONG inst); +ANSC_STATUS WanMgr_DSLite_DelFromList(UINT inst); +ANSC_STATUS WanMgr_DSLite_AddToList(UINT inst); +DML_DSLITE_LIST *WanMgr_getDSLiteEntryByInstance_locked(UINT inst); +DML_DSLITE_LIST *WanMgr_getDSLiteEntryByIdx_locked(UINT idx); +DML_DSLITE_LIST *WanMgr_getDSLiteEntryByAlias_locked(char *Alias); +WanMgr_DSLite_Data_t* WanMgr_GetDSLiteData_locked(void); +void WanMgr_GetDSLiteData_release(void); +ANSC_STATUS WanMgr_DSLite_WriteDSLiteCfgToSyscfg(void); +ANSC_STATUS WanMgr_DSLite_WriteEntryCfgToSyscfg(UINT inst); +ANSC_STATUS WanMgr_DSLite_UpdateVirtIfDSLiteCfg(UINT inst); +BOOL WanMgr_DSLite_isEnabled(DML_VIRTUAL_IFACE *p_VirtIf); +#endif #endif //_WANMGR_DATA_H_ diff --git a/source/WanManager/wanmgr_dhcp_event_handler.c b/source/WanManager/wanmgr_dhcp_event_handler.c index 9c3775cb..ade5d1aa 100644 --- a/source/WanManager/wanmgr_dhcp_event_handler.c +++ b/source/WanManager/wanmgr_dhcp_event_handler.c @@ -81,6 +81,9 @@ static void copyDhcpv6Data(WANMGR_IPV6_DATA* pDhcpv6Data, const DHCP_MGR_IPV6_MS "| domainNameAssigned : %-40d |\n" #ifdef FEATURE_MAPT "| maptAssigned : %-40d |\n" +#endif +#ifdef FEATURE_DSLITE_V2 + "| endpointName : %-40s |\n" #endif "=================================================================\n", leaseInfo->ifname, leaseInfo->address, leaseInfo->nameserver, leaseInfo->nameserver1, @@ -88,6 +91,9 @@ static void copyDhcpv6Data(WANMGR_IPV6_DATA* pDhcpv6Data, const DHCP_MGR_IPV6_MS leaseInfo->addrAssigned, leaseInfo->prefixAssigned, leaseInfo->domainNameAssigned #ifdef FEATURE_MAPT , leaseInfo->maptAssigned +#endif +#ifdef FEATURE_DSLITE_V2 + , leaseInfo->endpointName #endif )); @@ -103,6 +109,9 @@ static void copyDhcpv6Data(WANMGR_IPV6_DATA* pDhcpv6Data, const DHCP_MGR_IPV6_MS pDhcpv6Data->prefixAssigned = leaseInfo->prefixAssigned; pDhcpv6Data->domainNameAssigned = leaseInfo->domainNameAssigned; pDhcpv6Data->ipv6_TimeOffset = leaseInfo->ipv6_TimeOffset; +#ifdef FEATURE_DSLITE_V2 + strncpy(pDhcpv6Data->endpointName, leaseInfo->endpointName, sizeof(pDhcpv6Data->endpointName) - 1); +#endif } pthread_mutex_t DhcpClientEvents_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -238,6 +247,13 @@ void* WanMgr_DhcpClientEventsHandler_Thread(void *arg) } } #endif // FEATURE_MAPT +#if FEATURE_DSLITE_V2 + if (WanMgr_DSLite_isEndpointNameChanged(pVirtIf, leaseInfo->endpointName)) + { + pVirtIf->DSLite.Changed = TRUE; // sm checks this flag to take action + CcspTraceInfo(("DS-Lite Endpoint name has been changed\n")); + } +#endif char param_name[256] = {0}; snprintf(param_name, sizeof(param_name), "Device.X_RDK_WanManager.Interface.%d.VirtualInterface.%d.IP.IPv6Address", pVirtIf->baseIfIdx+1, pVirtIf->VirIfIdx+1); WanMgr_Rbus_EventPublishHandler(param_name, pVirtIf->IP.Ipv6Data.address,RBUS_STRING); diff --git a/source/WanManager/wanmgr_dslite.c b/source/WanManager/wanmgr_dslite.c new file mode 100644 index 00000000..8c31ab15 --- /dev/null +++ b/source/WanManager/wanmgr_dslite.c @@ -0,0 +1,196 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2025 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/********************************************************************** + Copyright [2014] [Cisco Systems, Inc.] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +**********************************************************************/ + +#include "wanmgr_dml_dslite_apis.h" +#include "wanmgr_dslite.h" +#include "wanmgr_rdkbus_apis.h" +#include "wanmgr_data.h" + +BOOL WanMgr_DSLite_isEndpointNameChanged(DML_VIRTUAL_IFACE* pVirtIf, const char* newEndpoint) +{ + DML_DSLITE_LIST *entry; + BOOL changed = FALSE; + + if (!newEndpoint || !pVirtIf) + return FALSE; + + entry = WanMgr_getDSLiteEntryByAlias_locked(pVirtIf->DSLite.Path); + if (!entry) + return FALSE; + + if (entry->CurrCfg.Type != DSLITE_ENDPOINT_FQDN) + { + CcspTraceError(("%s: DSLite Endpoint Type is not FQDN, ignoring DHCP aftr (64) option\n", __FUNCTION__)); + WanMgr_GetDSLiteData_release(); + return FALSE; + } + changed = (strcasecmp(entry->CurrCfg.EndpointName, newEndpoint) != 0); + + WanMgr_GetDSLiteData_release(); + return changed; +} + +BOOL WanMgr_DSLite_isEndpointAssigned(DML_VIRTUAL_IFACE *pVirtIf) +{ + DML_DSLITE_LIST *entry; + BOOL assigned = FALSE; + + entry = WanMgr_getDSLiteEntryByAlias_locked(pVirtIf->DSLite.Path); + if (!entry) + return FALSE; + + if (entry->CurrCfg.Type == DSLITE_ENDPOINT_FQDN) + { + assigned = !IS_EMPTY_STRING(entry->CurrCfg.EndpointName); + } + else if (entry->CurrCfg.Type == DSLITE_ENDPOINT_IPV6ADDRESS) + { + assigned = !IS_EMPTY_STRING(entry->CurrCfg.EndpointAddr); + } + + WanMgr_GetDSLiteData_release(); + return assigned; +} + +/* Get whole DSLite conf from syscfg */ +ANSC_STATUS WanMgr_DSLiteInit(void) +{ + WanMgr_DSLite_Data_t *pDSLiteData; + ANSC_STATUS ret = ANSC_STATUS_SUCCESS; + + pDSLiteData = WanMgr_GetDSLiteData_locked(); + if (!pDSLiteData) + return ANSC_STATUS_FAILURE; + + memset(pDSLiteData, 0, sizeof(*pDSLiteData)); + + /* Device.DSLite.Enable */ + WanMgr_SysCfgGetBool("dslite_enable", &pDSLiteData->Enable); + WanMgr_SysCfgGetUint("dslite_count", &pDSLiteData->InterfaceSettingNumberOfEntries); + if (WanMgr_SysCfgGetUint("dslite_next_insNum", &pDSLiteData->NextInstanceNumber) != ANSC_STATUS_SUCCESS) + { + /* assume InterfaceSettingNumberOfEntries + 1 */ + pDSLiteData->NextInstanceNumber = pDSLiteData->InterfaceSettingNumberOfEntries + 1; + } + + for (UINT insNum = 1; insNum < pDSLiteData->NextInstanceNumber; insNum++) + { + DML_DSLITE_LIST *entry; + char key[BUFLEN_64]; + UINT tmp = 0; + + snprintf(key, sizeof(key), "dslite_InsNum_%d", insNum); + ret = WanMgr_SysCfgGetUint(key, &tmp); + if (ret != ANSC_STATUS_SUCCESS || tmp == 0) + { + /* Find existing DSLite configs by the insNum field */ + continue; + } + + /* Sanity Check */ + if (tmp != insNum) + { + CcspTraceError(("%s: syscfg_get(%s) returned mismatched insNum %lu (expected %d), skipping\n", + __FUNCTION__, key, tmp, insNum)); + continue; + } + + entry = (DML_DSLITE_LIST *)AnscAllocateMemory(sizeof(DML_DSLITE_LIST)); + if (!entry) + { + CcspTraceError(("%s: Allocation failed for DML_DSLITE_LIST (insNum=%d)\n", __FUNCTION__, insNum)); + ret = ANSC_STATUS_RESOURCES; + break; + } + entry->InstanceNumber = insNum; + + DML_DSLITE_CONFIG cfg; + DSLITE_SET_DEFAULTVALUE(&cfg); /* start from known defaults */ + + snprintf(key, sizeof(key), "dslite_active_%d", insNum); + WanMgr_SysCfgGetBool(key, &cfg.Enable); + + snprintf(key, sizeof(key), "dslite_alias_%d", insNum); + WanMgr_SysCfgGetStr(key, cfg.Alias, sizeof(cfg.Alias)); + + snprintf(key, sizeof(key), "dslite_mode_%d", insNum); + WanMgr_SysCfgGetUint(key, &cfg.Mode); + + snprintf(key, sizeof(key), "dslite_addr_type_%d", insNum); + WanMgr_SysCfgGetUint(key, &cfg.Type); + + snprintf(key, sizeof(key), "dslite_addr_fqdn_%d", insNum); + WanMgr_SysCfgGetStr(key, cfg.EndpointName, sizeof(cfg.EndpointName)); + + snprintf(key, sizeof(key), "dslite_addr_ipv6_%d", insNum); + WanMgr_SysCfgGetStr(key, cfg.EndpointAddr, sizeof(cfg.EndpointAddr)); + + snprintf(key, sizeof(key), "dslite_mss_clamping_enable_%d", insNum); + WanMgr_SysCfgGetBool(key, &cfg.MssClampingEnable); + + snprintf(key, sizeof(key), "dslite_tcpmss_%d", insNum); + WanMgr_SysCfgGetUint(key, &cfg.TcpMss); + + snprintf(key, sizeof(key), "dslite_ipv6_frag_enable_%d", insNum); + WanMgr_SysCfgGetBool(key, &cfg.Ipv6FragEnable); + + snprintf(key, sizeof(key), "dslite_status_%d", insNum); + WanMgr_SysCfgGetUint(key, &cfg.Status); + + snprintf(key, sizeof(key), "dslite_addr_inuse_%d", insNum); + WanMgr_SysCfgGetStr(key, cfg.AddrInUse, sizeof(cfg.AddrInUse)); + + snprintf(key, sizeof(key), "dslite_origin_%d", insNum); + WanMgr_SysCfgGetUint(key, &cfg.Origin); + + snprintf(key, sizeof(key), "dslite_tunnel_interface_%d", insNum); + WanMgr_SysCfgGetStr(key, cfg.TunnelIface, sizeof(cfg.TunnelIface)); + + snprintf(key, sizeof(key), "dslite_tunneled_interface_%d", insNum); + WanMgr_SysCfgGetStr(key, cfg.TunneledIface, sizeof(cfg.TunneledIface)); + + snprintf(key, sizeof(key), "dslite_tunnel_v4addr_%d", insNum); + WanMgr_SysCfgGetStr(key, cfg.TunnelV4Addr, sizeof(cfg.TunnelV4Addr)); + + entry->PrevCfg = cfg; + entry->CurrCfg = cfg; + entry->next = pDSLiteData->DSLiteList; + pDSLiteData->DSLiteList = entry; + } + + WanMgr_GetDSLiteData_release(); + return ret; +} + diff --git a/source/WanManager/wanmgr_dslite.h b/source/WanManager/wanmgr_dslite.h new file mode 100644 index 00000000..4ecac181 --- /dev/null +++ b/source/WanManager/wanmgr_dslite.h @@ -0,0 +1,58 @@ +/* + * If not stated otherwise in this file or this component's LICENSE file the + * following copyright and licenses apply: + * + * Copyright 2025 RDK Management + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/********************************************************************** + Copyright [2014] [Cisco Systems, Inc.] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +**********************************************************************/ + +#ifndef _WANMGR_DSLITE_H_ +#define _WANMGR_DSLITE_H_ + +#include "ansc_platform.h" +#include "wanmgr_dml.h" +#include "wanmgr_net_utils.h" + +#define DSLITE_SET_DEFAULTVALUE(__pCfg) \ + do \ + { \ + memset((__pCfg), 0, sizeof(*(__pCfg))); \ + (__pCfg)->Enable = FALSE; \ + (__pCfg)->Status = WAN_IFACE_DSLITE_STATE_DOWN; \ + (__pCfg)->Mode = DSLITE_ENDPOINT_DHCPV6; \ + (__pCfg)->Type = DSLITE_ENDPOINT_IPV6ADDRESS; \ + (__pCfg)->Origin = DSLITE_ENDPOINT_DHCPV6; \ + (__pCfg)->TcpMss = 1420; \ + } while (0) + +BOOL WanMgr_DSLite_isEndpointAssigned(DML_VIRTUAL_IFACE* pVirtIf); +BOOL WanMgr_DSLite_isEndpointNameChanged(DML_VIRTUAL_IFACE* pVirtIf, const char* newFqdn); +ANSC_STATUS WanMgr_DSLiteInit(void); +#endif /* _WANMGR_DSLITE_H_ */ \ No newline at end of file diff --git a/source/WanManager/wanmgr_interface_sm.c b/source/WanManager/wanmgr_interface_sm.c index 0c59acc9..79104608 100644 --- a/source/WanManager/wanmgr_interface_sm.c +++ b/source/WanManager/wanmgr_interface_sm.c @@ -39,7 +39,9 @@ #ifdef ENABLE_FEATURE_TELEMETRY2_0 #include #endif - +#ifdef FEATURE_DSLITE_V2 +#include "wanmgr_dslite.h" +#endif #define IF_SIZE 32 #define LOOP_TIMEOUT 50000 // timeout in microseconds. This is the state machine loop interval #define RESOLV_CONF_FILE "/etc/resolv.conf" @@ -81,6 +83,9 @@ static eWanState_t wan_state_dual_stack_active(WanMgr_IfaceSM_Controller_t* pWan #if defined(FEATURE_MAPT) || defined(FEATURE_SUPPORT_MAPT_NAT46) static eWanState_t wan_state_mapt_active(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl); #endif //FEATURE_MAPT +#if defined(FEATURE_DSLITE_V2) +static eWanState_t wan_state_dslite_active(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl); +#endif //FEATURE_DSLITE_V2 static eWanState_t wan_state_refreshing_wan(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl); static eWanState_t wan_state_deconfiguring_wan(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl); static eWanState_t wan_state_exit(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl); @@ -109,6 +114,10 @@ static eWanState_t wan_transition_mapt_up(WanMgr_IfaceSM_Controller_t* pWanIface static eWanState_t wan_transition_mapt_down(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl); extern int mapt_feature_enable_changed; #endif //FEATURE_MAPT +#if defined(FEATURE_DSLITE_V2) +static eWanState_t wan_transition_dslite_up(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl); +static eWanState_t wan_transition_dslite_down(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl); +#endif //FEATURE_DSLITE_V2 static eWanState_t wan_transition_configuring_interface(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl); static eWanState_t wan_transition_phy_deconfiguring(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl); static eWanState_t wan_transition_wan_deconfigured(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl); @@ -194,6 +203,22 @@ static ANSC_STATUS WanManager_ClearDHCPData(DML_VIRTUAL_IFACE * pVirtIf); *************************************************************************************/ static int checkIpv6LanAddressIsReadyToUse(DML_VIRTUAL_IFACE* p_VirtIf); +#ifdef FEATURE_DSLITE_V2 +/************************************************************************************* + * @brief Enable DSLite configuration on the interface. + * This API calls the HAL routine to Enable DSLite. + * @return RETURN_OK upon success else ERROR code returned + **************************************************************************************/ +static int wan_setUpDslite(WanMgr_IfaceSM_Controller_t * pWanIfaceCtrl); + +/************************************************************************************* + * @brief Disable DSLite configuration on the interface. + * This API calls the HAL routine to disable DSLite. + * @return RETURN_OK upon success else ERROR code returned + **************************************************************************************/ +static int wan_tearDownDslite(WanMgr_IfaceSM_Controller_t * pWanIfaceCtrl); +#endif + #ifdef FEATURE_MAPT /************************************************************************************* @@ -1600,6 +1625,52 @@ static int wan_tearDownIPv6(WanMgr_IfaceSM_Controller_t * pWanIfaceCtrl) return ret; } +#ifdef FEATURE_DSLITE_V2 +static int wan_tearDownDSLite(WanMgr_IfaceSM_Controller_t *pWanIfaceCtrl) +{ + if ((pWanIfaceCtrl == NULL) || (pWanIfaceCtrl->pIfaceData == NULL)) + { + CcspTraceError(("%s %d - Invalid args \n", __FUNCTION__, __LINE__)); + return RETURN_ERR; + } + DML_WAN_IFACE *pInterface = pWanIfaceCtrl->pIfaceData; + DML_VIRTUAL_IFACE *p_VirtIf = WanMgr_getVirtualIfaceById(pInterface->VirtIfList, pWanIfaceCtrl->VirIfIdx); + + // call DSLite tunnel setup fn here + + if (p_VirtIf->IP.Mode == DML_WAN_IP_MODE_IPV4_ONLY || p_VirtIf->IP.Mode == DML_WAN_IP_MODE_DUAL_STACK) + { + // Enabling IP forwarding + CcspTraceInfo(("%s %d - net.ipv4.ip_forward set to 1 \n", __FUNCTION__, __LINE__)); + v_secure_system("sysctl -w net.ipv4.ip_forward=1"); + } + return RETURN_OK; +} + +static int wan_setUpDSLite(WanMgr_IfaceSM_Controller_t *pWanIfaceCtrl) +{ + if ((pWanIfaceCtrl == NULL) || (pWanIfaceCtrl->pIfaceData == NULL)) + { + CcspTraceError(("%s %d - Invalid args \n", __FUNCTION__, __LINE__)); + return RETURN_ERR; + } + + DML_WAN_IFACE *pInterface = pWanIfaceCtrl->pIfaceData; + DML_VIRTUAL_IFACE *p_VirtIf = WanMgr_getVirtualIfaceById(pInterface->VirtIfList, pWanIfaceCtrl->VirIfIdx); + + // call DSLite tunnel setup fn here + + if (p_VirtIf->IP.Mode == DML_WAN_IP_MODE_IPV6_ONLY) + { + // Disabling IP forwarding + CcspTraceInfo(("%s %d - net.ipv4.ip_forward set to 0 \n", __FUNCTION__, __LINE__)); + v_secure_system("sysctl -w net.ipv4.ip_forward=0"); + } + return RETURN_OK; +} + +#endif + #ifdef FEATURE_IPOE_HEALTH_CHECK static ANSC_STATUS WanMgr_IfaceSM_IHC_Init(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl) { @@ -1974,6 +2045,13 @@ static eWanState_t wan_transition_physical_interface_down(WanMgr_IfaceSM_Control } #endif +#ifdef FEATURE_DSLITE_V2 + if (p_VirtIf->DSLite.Status == WAN_IFACE_DSLITE_STATE_UP) + { + wan_transition_dslite_down(pWanIfaceCtrl); + } +#endif + if(p_VirtIf->IP.Ipv4Status == WAN_IFACE_IPV4_STATE_UP) { wan_transition_ipv4_down(pWanIfaceCtrl); @@ -2090,13 +2168,15 @@ static eWanState_t wan_transition_wan_validated(WanMgr_IfaceSM_Controller_t* pWa p_VirtIf->IP.Ipv4ConnectivityStatus = WAN_CONNECTIVITY_UP; p_VirtIf->IP.Ipv6ConnectivityStatus = WAN_CONNECTIVITY_UP; - if(p_VirtIf->IP.SelectedMode == MAPT_MODE && p_VirtIf->IP.SelectedModeTimerStatus != EXPIRED) + if ((p_VirtIf->IP.SelectedMode == MAPT_MODE || p_VirtIf->IP.SelectedMode == DSLITE_MODE) && + p_VirtIf->IP.SelectedModeTimerStatus != EXPIRED) { - /* Start all interface with accept ra disbaled */ + /* Start all interface with accept ra disabled */ WanMgr_Configure_accept_ra(p_VirtIf, FALSE); /* Start DHCPv6 Client */ WanManager_StartDhcpv6Client(p_VirtIf, pInterface->IfaceType); - CcspTraceInfo(("%s %d - MAPT_MODE preferred \n", __FUNCTION__, __LINE__)); + CcspTraceInfo(("%s %d - %s_MODE preferred \n", __FUNCTION__, __LINE__, + p_VirtIf->IP.SelectedMode == MAPT_MODE ? "MAPT" : "DSLITE")); // clock start p_VirtIf->IP.SelectedModeTimerStatus = RUNNING; memset(&(p_VirtIf->IP.SelectedModeTimerStart), 0, sizeof(struct timespec)); @@ -2352,11 +2432,13 @@ static eWanState_t wan_transition_ipv4_down(WanMgr_IfaceSM_Controller_t* pWanIfa } else { - // start DHCPv4 client if it is not running, MAP-T not configured and PPP Disable scenario. - if(p_VirtIf->IP.Dhcp4cStatus != DHCPC_STARTED && + // start DHCPv4 client if it is not running, DSLite and MAP-T not configured and PPP Disable scenario. + if (p_VirtIf->IP.Dhcp4cStatus != DHCPC_STARTED && (p_VirtIf->PPP.Enable == FALSE) && - (!(p_VirtIf->EnableMAPT == TRUE && (pInterface->Selection.Status == WAN_IFACE_ACTIVE) && - (p_VirtIf->MAP.MaptStatus == WAN_IFACE_MAPT_STATE_UP)))) + (!(p_VirtIf->EnableMAPT == TRUE && (pInterface->Selection.Status == WAN_IFACE_ACTIVE) && + (p_VirtIf->MAP.MaptStatus == WAN_IFACE_MAPT_STATE_UP))) && + (!(WanMgr_DSLite_isEnabled(p_VirtIf) == TRUE && (pInterface->Selection.Status == WAN_IFACE_ACTIVE) && + (p_VirtIf->DSLite.Status == WAN_IFACE_DSLITE_STATE_UP)))) { WanManager_StartDhcpv4Client(p_VirtIf, pInterface->Name, pInterface->IfaceType); CcspTraceInfo(("%s %d - SELFHEAL - Started dhcpc on interface %s\n", __FUNCTION__, __LINE__, p_VirtIf->Name)); @@ -2907,6 +2989,67 @@ static eWanState_t wan_transition_mapt_down(WanMgr_IfaceSM_Controller_t* pWanIfa } #endif //FEATURE_MAPT +#ifdef FEATURE_DSLITE_V2 +static eWanState_t wan_transition_dslite_up(WanMgr_IfaceSM_Controller_t *pWanIfaceCtrl) +{ + if ((pWanIfaceCtrl == NULL) || (pWanIfaceCtrl->pIfaceData == NULL)) + { + return ANSC_STATUS_FAILURE; + } + + DML_WAN_IFACE *pInterface = pWanIfaceCtrl->pIfaceData; + DML_VIRTUAL_IFACE *p_VirtIf = WanMgr_getVirtualIfaceById(pInterface->VirtIfList, pWanIfaceCtrl->VirIfIdx); + + if (wan_setUpDSLite(pWanIfaceCtrl) != RETURN_OK) + { + p_VirtIf->DSLite.Status = WAN_IFACE_DSLITE_STATE_ERROR; + + CcspTraceError(("%s %d - Failed to setup DS-Lite for %s \n", __FUNCTION__, __LINE__, p_VirtIf->Name)); + CcspTraceInfo(("%s %d - Interface '%s' - TRANSITION to State=%d \n", __FUNCTION__, __LINE__, pInterface->Name, p_VirtIf->eCurrentState)); + + return p_VirtIf->eCurrentState; + } + + WanMgr_ProcessTelemetryMarker(p_VirtIf, WAN_INFO_DSLITE_STATUS_UP); + p_VirtIf->DSLite.Status = WAN_IFACE_DSLITE_STATE_UP; + p_VirtIf->DSLite.Changed = FALSE; + + wanmgr_firewall_restart(); + + CcspTraceInfo(("%s %d - Interface '%s' - TRANSITION DSLITE ACTIVE\n", __FUNCTION__, __LINE__, pInterface->Name)); + return WAN_STATE_DSLITE_ACTIVE; +} + +static eWanState_t wan_transition_dslite_down(WanMgr_IfaceSM_Controller_t *pWanIfaceCtrl) +{ + if ((pWanIfaceCtrl == NULL) || (pWanIfaceCtrl->pIfaceData == NULL)) + { + return ANSC_STATUS_FAILURE; + } + + DML_WAN_IFACE *pInterface = pWanIfaceCtrl->pIfaceData; + DML_VIRTUAL_IFACE *p_VirtIf = WanMgr_getVirtualIfaceById(pInterface->VirtIfList, pWanIfaceCtrl->VirIfIdx); + + if (wan_tearDownDSLite(pWanIfaceCtrl) != RETURN_OK) + { + p_VirtIf->DSLite.Status = WAN_IFACE_DSLITE_STATE_ERROR; + + CcspTraceError(("%s %d - Failed to tear down DS-Lite for %s \n", __FUNCTION__, __LINE__, p_VirtIf->Name)); + CcspTraceInfo(("%s %d - Interface '%s' - TRANSITION to State=%d \n", __FUNCTION__, __LINE__, pInterface->Name, p_VirtIf->eCurrentState)); + + return p_VirtIf->eCurrentState; + } + + WanMgr_ProcessTelemetryMarker(p_VirtIf, WAN_ERROR_DSLITE_STATUS_DOWN); + p_VirtIf->DSLite.Status = WAN_IFACE_DSLITE_STATE_DOWN; + + wanmgr_firewall_restart(); + + CcspTraceInfo(("%s %d - Interface '%s' - TRANSITION IPV6 LEASED\n", __FUNCTION__, __LINE__, pInterface->Name)); + return WAN_STATE_IPV6_LEASED; +} +#endif + static eWanState_t wan_transition_configuring_interface(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl) { CcspTraceInfo(("%s %d \n", __FUNCTION__, __LINE__)); @@ -3054,6 +3197,17 @@ static eWanState_t wan_transition_standby_deconfig_ips(WanMgr_IfaceSM_Controller } #endif +#ifdef FEATURE_DSLITE_V2 + if (p_VirtIf->DSLite.Status == WAN_IFACE_DSLITE_STATE_UP) + { + CcspTraceInfo(("%s %d - Deconfiguring DSLite for %s \n", __FUNCTION__, __LINE__, p_VirtIf->Name)); + if (wan_tearDownDSLite(pWanIfaceCtrl) != RETURN_OK) + { + CcspTraceError(("%s %d - Failed to tear down DSLite for %s \n", __FUNCTION__, __LINE__, p_VirtIf->Name)); + } + } +#endif + //FIXME: Currently ipoe_health_check doesn't support multiple instances. Kill the process if the inetrface is not active. if(p_VirtIf->IP.ConnectivityCheckType == WAN_CONNECTIVITY_TYPE_IHC) { @@ -3360,26 +3514,30 @@ static eWanState_t wan_state_obtaining_ip_addresses(WanMgr_IfaceSM_Controller_t* return wan_transition_physical_interface_down(pWanIfaceCtrl); } - if(p_VirtIf->IP.SelectedMode == MAPT_MODE) + if (p_VirtIf->IP.SelectedMode == MAPT_MODE || + p_VirtIf->IP.SelectedMode == DSLITE_MODE) { - if(p_VirtIf->MAP.MaptStatus == WAN_IFACE_MAPT_STATE_UP) + bool is_mapt = p_VirtIf->IP.SelectedMode == MAPT_MODE; + const char *mode_str = is_mapt ? "MAPT" : "DSLITE"; + bool iface_state_up = is_mapt + ? (p_VirtIf->MAP.MaptStatus == WAN_IFACE_MAPT_STATE_UP) + : (p_VirtIf->DSLite.Status == WAN_IFACE_DSLITE_STATE_UP); + + if (iface_state_up) { p_VirtIf->IP.SelectedModeTimerStatus = COMPLETE; - CcspTraceInfo(("%s %d MAPT option recieved in MAPT Preferred Mode - Timer complete \n", __FUNCTION__, __LINE__)); + CcspTraceInfo(("%s %d %s option received in %s Preferred Mode - Timer complete \n", __FUNCTION__, __LINE__, mode_str, mode_str)); } - else + else if (p_VirtIf->IP.SelectedModeTimerStatus == RUNNING) { - if(p_VirtIf->IP.SelectedModeTimerStatus == RUNNING) + if (difftime(CurrentTime.tv_sec, p_VirtIf->IP.SelectedModeTimerStart.tv_sec) > SELECTED_MODE_TIMEOUT_SECONDS || + p_VirtIf->IP.Ipv6Status == WAN_IFACE_IPV6_STATE_UP) { - if (difftime(CurrentTime.tv_sec, p_VirtIf->IP.SelectedModeTimerStart.tv_sec) > SELECTED_MODE_TIMEOUT_SECONDS || - p_VirtIf->IP.Ipv6Status == WAN_IFACE_IPV6_STATE_UP) - { - p_VirtIf->IP.SelectedModeTimerStatus = EXPIRED; - CcspTraceInfo(("%s %d MAPT option not recieved in MAPT Preferred Mode - Timer Expired \n", __FUNCTION__, __LINE__)); - return wan_transition_wan_validated(pWanIfaceCtrl); - } - return WAN_STATE_OBTAINING_IP_ADDRESSES; + p_VirtIf->IP.SelectedModeTimerStatus = EXPIRED; + CcspTraceInfo(("%s %d %s option not received in %s Preferred Mode - Timer Expired \n", __FUNCTION__, __LINE__, mode_str, mode_str)); + return wan_transition_wan_validated(pWanIfaceCtrl); } + return WAN_STATE_OBTAINING_IP_ADDRESSES; } } @@ -3759,6 +3917,19 @@ static eWanState_t wan_state_ipv6_leased(WanMgr_IfaceSM_Controller_t* pWanIfaceC } } #endif //FEATURE_MAPT + +#ifdef FEATURE_DSLITE_V2 + else if (WanMgr_DSLite_isEnabled(p_VirtIf) == TRUE && + pInterface->Selection.Status == WAN_IFACE_ACTIVE && + p_VirtIf->DSLite.Status == WAN_IFACE_DSLITE_STATE_DOWN && + WanMgr_DSLite_isEndpointAssigned(p_VirtIf) == TRUE) + { + if (checkIpv6LanAddressIsReadyToUse(p_VirtIf) == RETURN_OK) + { + return wan_transition_dslite_up(pWanIfaceCtrl); + } + } +#endif else if (p_VirtIf->IP.Ipv6Renewed == TRUE) { WanMgr_SendMsgTo_ConnectivityCheck(pWanIfaceCtrl, CONNECTION_MSG_IPV6 , TRUE); @@ -3897,6 +4068,24 @@ static eWanState_t wan_state_dual_stack_active(WanMgr_IfaceSM_Controller_t* pWan } } #endif //FEATURE_MAPT +#ifdef FEATURE_DSLITE_V2 + else if (WanMgr_DSLite_isEnabled(p_VirtIf) == TRUE && + WanMgr_DSLite_isEndpointAssigned(p_VirtIf) == TRUE && + pInterface->Selection.Status == WAN_IFACE_ACTIVE) + { + if (p_VirtIf->DSLite.Status == WAN_IFACE_DSLITE_STATE_DOWN) + { + if (checkIpv6LanAddressIsReadyToUse(p_VirtIf) == RETURN_OK) + { + return wan_transition_dslite_up(pWanIfaceCtrl); + } + } + else if (p_VirtIf->DSLite.Status == WAN_IFACE_DSLITE_STATE_UP) + { + return wan_transition_dslite_down(pWanIfaceCtrl); + } + } +#endif // FEATURE_DSLITE_V2 else if (p_VirtIf->IP.Ipv4Renewed == TRUE) { WanMgr_SendMsgTo_ConnectivityCheck(pWanIfaceCtrl, CONNECTION_MSG_IPV4 , TRUE); @@ -4073,6 +4262,119 @@ static eWanState_t wan_state_mapt_active(WanMgr_IfaceSM_Controller_t* pWanIfaceC } #endif //FEATURE_MAPT +#ifdef FEATURE_DSLITE_V2 +static eWanState_t wan_state_dslite_active(WanMgr_IfaceSM_Controller_t *pWanIfaceCtrl) +{ + if ((pWanIfaceCtrl == NULL) || (pWanIfaceCtrl->pIfaceData == NULL)) + { + return ANSC_STATUS_FAILURE; + } + + DML_WAN_IFACE *pInterface = pWanIfaceCtrl->pIfaceData; + DML_VIRTUAL_IFACE *p_VirtIf = WanMgr_getVirtualIfaceById(pInterface->VirtIfList, pWanIfaceCtrl->VirIfIdx); + + if (pWanIfaceCtrl->WanEnable == FALSE || + pInterface->Selection.Enable == FALSE || + pInterface->Selection.Status == WAN_IFACE_NOT_SELECTED || + p_VirtIf->Enable == FALSE || + p_VirtIf->Reset == TRUE || + p_VirtIf->VLAN.Reset == TRUE || + pInterface->BaseInterfaceStatus != WAN_IFACE_PHY_STATUS_UP) + { + return wan_transition_physical_interface_down(pWanIfaceCtrl); + } + else if ((pInterface->Selection.Status != WAN_IFACE_ACTIVE) || (pWanIfaceCtrl->DeviceNwModeChanged == TRUE)) + { + return wan_transition_standby_deconfig_ips(pWanIfaceCtrl); + } + else if (WanMgr_DSLite_isEnabled(p_VirtIf) == FALSE || + (p_VirtIf->IP.Ipv6Status == WAN_IFACE_IPV6_STATE_DOWN) || + (p_VirtIf->DSLite.Changed == TRUE && WanMgr_DSLite_isEndpointAssigned(p_VirtIf) == FALSE) || + (p_VirtIf->IP.RefreshDHCP == TRUE && p_VirtIf->IP.Mode != DML_WAN_IP_MODE_IPV6_ONLY && p_VirtIf->IP.Mode != DML_WAN_IP_MODE_DUAL_STACK) || + (p_VirtIf->VLAN.Enable == TRUE && p_VirtIf->VLAN.Status == WAN_IFACE_LINKSTATUS_DOWN)) + { + CcspTraceInfo(("%s %d - LinkStatus=[%d] \n", __FUNCTION__, __LINE__, p_VirtIf->VLAN.Status)); + return wan_transition_dslite_down(pWanIfaceCtrl); + } + else if (p_VirtIf->IP.Ipv6Changed == TRUE) + { + if (wan_tearDownIPv6(pWanIfaceCtrl) == RETURN_OK) + { + if (setUpLanPrefixIPv6(p_VirtIf) == RETURN_OK) + { + if (wan_setUpIPv6(pWanIfaceCtrl) == RETURN_OK) + { + WanMgr_SendMsgTo_ConnectivityCheck(pWanIfaceCtrl, CONNECTION_MSG_IPV6, TRUE); + p_VirtIf->IP.Ipv6Changed = FALSE; + CcspTraceInfo(("%s %d - Successfully updated IPv6 configure Changes for %s Interface \n", + __FUNCTION__, __LINE__, p_VirtIf->Name)); + + if (WanMgr_DSLite_isEnabled(p_VirtIf) == TRUE && + pInterface->Selection.Status == WAN_IFACE_ACTIVE && + p_VirtIf->DSLite.Status == WAN_IFACE_DSLITE_STATE_UP) + { + p_VirtIf->DSLite.Changed = TRUE; // Reconfigure DSLite if V6 Updated + } + } + else + { + CcspTraceError(("%s %d - Failed to configure IPv6 for %s Interface \n", __FUNCTION__, __LINE__, p_VirtIf->Name)); + } + } + else + { + CcspTraceError((" %s %d - Failed to configure IPv6 prefix for %s Interface \n", __FUNCTION__, __LINE__, p_VirtIf->Name)); + } + } + else + { + CcspTraceError(("%s %d - Failed to tear down IPv6 for %s Interface \n", __FUNCTION__, __LINE__, p_VirtIf->Name)); + } + } + else if (p_VirtIf->DSLite.Changed == TRUE) + { + if (wan_tearDownDSLite(pWanIfaceCtrl) == RETURN_OK) + { + if (wan_setUpDSLite(pWanIfaceCtrl) == RETURN_OK) + { + CcspTraceInfo(("%s %d - Successfully updated DS-Lite configure Changes for %s Interface \n", __FUNCTION__, __LINE__, p_VirtIf->Name)); + } + else + { + CcspTraceError((" %s %d - Failed to configure DS-Lite for %s Interface \n", __FUNCTION__, __LINE__, p_VirtIf->Name)); + } + } + else + { + CcspTraceError(("%s %d - Failed to tear down DS-Lite for %s Interface \n", __FUNCTION__, __LINE__, p_VirtIf->Name)); + } + } + else if (p_VirtIf->IP.Ipv6Renewed == TRUE) + { + WanMgr_SendMsgTo_ConnectivityCheck(pWanIfaceCtrl, CONNECTION_MSG_IPV6, TRUE); + p_VirtIf->IP.Ipv6Renewed = FALSE; + } + + // Start DHCP apps if not started + WanMgr_MonitorDhcpApps(pWanIfaceCtrl); + + WanMgr_CheckDefaultRA(p_VirtIf); +#if defined(FEATURE_IPOE_HEALTH_CHECK) && defined(IPOE_HEALTH_CHECK_LAN_SYNC_SUPPORT) + if (lanState == LAN_STATE_STOPPED) + { + WanMgr_SendMsgTo_ConnectivityCheck(pWanIfaceCtrl, CONNECTION_MSG_IPV6, FALSE); + lanState = LAN_STATE_RESET; + } + else if (lanState == LAN_STATE_STARTED) + { + WanMgr_SendMsgTo_ConnectivityCheck(pWanIfaceCtrl, CONNECTION_MSG_IPV6, TRUE); + lanState = LAN_STATE_RESET; + } +#endif + return WAN_STATE_DSLITE_ACTIVE; +} +#endif // FEATURE_DSLITE_V2 + static eWanState_t wan_state_refreshing_wan(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl) { if((pWanIfaceCtrl == NULL) || (pWanIfaceCtrl->pIfaceData == NULL)) @@ -4352,6 +4654,13 @@ static void* WanMgr_InterfaceSMThread( void *arg ) break; } #endif //FEATURE_MAPT +#ifdef FEATURE_DSLITE_V2 + case WAN_STATE_DSLITE_ACTIVE: + { + iface_sm_state = wan_state_dslite_active(pWanIfaceCtrl); + break; + } +#endif //FEATURE_DSLITE_V2 case WAN_STATE_REFRESHING_WAN: { iface_sm_state = wan_state_refreshing_wan(pWanIfaceCtrl); diff --git a/source/WanManager/wanmgr_t2_telemetry.c b/source/WanManager/wanmgr_t2_telemetry.c index fd5b3c76..e8e8f40c 100644 --- a/source/WanManager/wanmgr_t2_telemetry.c +++ b/source/WanManager/wanmgr_t2_telemetry.c @@ -176,6 +176,25 @@ ANSC_STATUS wanmgr_process_T2_telemetry_event(WanMgr_Telemetry_Marker_t *Marker) case WAN_ERROR_MAPT_STATUS_FAILED: break; + case WAN_INFO_DSLITE_STATUS_UP: + if(pVirtIntf->DSLite.Status == WAN_IFACE_DSLITE_STATE_UP) + { + return ANSC_STATUS_SUCCESS; + } + wanmgr_telemetry_append_key_value(WANMGR_T2_SELECTION_STATUS_STRING,(pIntf->Selection.Status == WAN_IFACE_ACTIVE) ? "Active" : (pIntf->Selection.Status == WAN_IFACE_VALIDATING) ? "Validating" : (pIntf->Selection.Status == WAN_IFACE_SELECTED ) ? "Selected" : "Standby"); + break; + + case WAN_ERROR_DSLITE_STATUS_DOWN: + if(pVirtIntf->DSLite.Status == WAN_IFACE_DSLITE_STATE_DOWN) + { + return ANSC_STATUS_SUCCESS; + } + wanmgr_telemetry_append_key_value(WANMGR_T2_SELECTION_STATUS_STRING,(pIntf->Selection.Status == WAN_IFACE_ACTIVE) ? "Active" : (pIntf->Selection.Status == WAN_IFACE_VALIDATING) ? "Validating" : (pIntf->Selection.Status == WAN_IFACE_SELECTED ) ? "Selected" : "Standby"); + break; + + case WAN_ERROR_DSLITE_STATUS_FAILED: + break; + case WAN_ERROR_VLAN_DOWN: if(pVirtIntf->VLAN.Status == WAN_IFACE_LINKSTATUS_DOWN) { diff --git a/source/WanManager/wanmgr_t2_telemetry.h b/source/WanManager/wanmgr_t2_telemetry.h index 57e23209..ff3b735a 100644 --- a/source/WanManager/wanmgr_t2_telemetry.h +++ b/source/WanManager/wanmgr_t2_telemetry.h @@ -39,6 +39,9 @@ static const char * const WanMgr_TelemetryEventStr[] = [WAN_INFO_MAPT_STATUS_UP] = "WAN_INFO_MAPT_STATUS_UP_split", [WAN_ERROR_MAPT_STATUS_DOWN] = "WAN_ERROR_MAPT_STATUS_DOWN_split", [WAN_ERROR_MAPT_STATUS_FAILED] = "WAN_ERROR_MAPT_STATUS_FAILED_split", + [WAN_INFO_DSLITE_STATUS_UP] = "WAN_INFO_DSLITE_STATUS_UP_split", + [WAN_ERROR_DSLITE_STATUS_DOWN] = "WAN_ERROR_DSLITE_STATUS_DOWN_split", + [WAN_ERROR_DSLITE_STATUS_FAILED] = "WAN_ERROR_DSLITE_STATUS_FAILED_split", [WAN_ERROR_VLAN_DOWN] = "WAN_ERROR_VLAN_DOWN_split", [WAN_ERROR_VLAN_CREATION_FAILED] = "WAN_ERROR_VLAN_CREATION_FAILED_split" }; diff --git a/source/WanManager/wanmgr_telemetry.h b/source/WanManager/wanmgr_telemetry.h index 8ebeac38..51db5838 100644 --- a/source/WanManager/wanmgr_telemetry.h +++ b/source/WanManager/wanmgr_telemetry.h @@ -33,7 +33,11 @@ typedef enum WanMgr_TelemetryEvent WAN_ERROR_MAPT_STATUS_DOWN, WAN_ERROR_MAPT_STATUS_FAILED, WAN_ERROR_VLAN_DOWN, - WAN_ERROR_VLAN_CREATION_FAILED + WAN_ERROR_VLAN_CREATION_FAILED, + WAN_INFO_DSLITE_STATUS_UP, + WAN_ERROR_DSLITE_STATUS_DOWN, + WAN_ERROR_DSLITE_STATUS_FAILED, + }WanMgr_TelemetryEvent_t; typedef struct _WANMGR_TELEMETRY_MARKER_