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 @@
+
+
+
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_