diff --git a/source/TR-181/middle_layer_src/wanmgr_rdkbus_common.h b/source/TR-181/middle_layer_src/wanmgr_rdkbus_common.h index 9abbff8f..7e437816 100644 --- a/source/TR-181/middle_layer_src/wanmgr_rdkbus_common.h +++ b/source/TR-181/middle_layer_src/wanmgr_rdkbus_common.h @@ -90,7 +90,6 @@ typedef struct _CONTEXT_LINK_OBJECT #define DML_ALIAS_NAME_LENGTH 64 #define DML_DHCP_CLIENT_IFNAME "erouter0" -#define CFG_TR181_DHCPv6_SERVER_IfName "brlan0" ANSC_STATUS SListPushEntryByInsNum (PSLIST_HEADER pListHead, PCONTEXT_LINK_OBJECT pLinkContext); diff --git a/source/WanManager/DHCPv6cMsgHandler/dhcpv6c_msg_apis.c b/source/WanManager/DHCPv6cMsgHandler/dhcpv6c_msg_apis.c index 51865edf..82867e1b 100644 --- a/source/WanManager/DHCPv6cMsgHandler/dhcpv6c_msg_apis.c +++ b/source/WanManager/DHCPv6cMsgHandler/dhcpv6c_msg_apis.c @@ -674,14 +674,19 @@ static void * WanMgr_DhcpV6MsgHandler() CcspTraceInfo(("%s %d Prefix Assigned\n", __FUNCTION__, __LINE__)); snprintf(dhcpv6_data.sitePrefix, sizeof(dhcpv6_data.sitePrefix), "%s/%d", v6pref, pref_len); - dhcpv6_data.prefixAssigned = TRUE; strncpy(dhcpv6_data.pdIfAddress, "", sizeof(dhcpv6_data.pdIfAddress)); dhcpv6_data.prefixCmd = 0; remove_single_quote(iapd_pretm); remove_single_quote(iapd_vldtm); sscanf(iapd_pretm, "%d", &(dhcpv6_data.prefixPltime)); sscanf(iapd_vldtm, "%d", &(dhcpv6_data.prefixVltime)); - + // Set prefixAssigned to TRUE only if both preferred and valid lifetimes are positive + if (dhcpv6_data.prefixPltime > 0 && dhcpv6_data.prefixVltime > 0) + { + dhcpv6_data.prefixAssigned = TRUE; + } else { + dhcpv6_data.prefixAssigned = FALSE; + } //IPv6 prefix related sysevents // Define the eventMaps array as before Ipv6SyseventMap eventMaps[] = { diff --git a/source/WanManager/wanmgr_dhcp_event_handler.c b/source/WanManager/wanmgr_dhcp_event_handler.c index fc0500c0..3d02c6c8 100644 --- a/source/WanManager/wanmgr_dhcp_event_handler.c +++ b/source/WanManager/wanmgr_dhcp_event_handler.c @@ -104,6 +104,17 @@ 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; + if(!pDhcpv6Data->addrAssigned && pDhcpv6Data->prefixAssigned) + { + /* In an IPv6 lease, if only IAPD is received and we never received IANA, + * We can use the received IAPD to construct a Ipv6 /128 address which can be used for managerment and voice ... + * If we reach this point, only IAPD has been received. Calculate Wan Ipv6 address + */ + + CcspTraceInfo(("IANA is not assigned by DHCPV6. Constructing WAN address from the IAPD for Wan Interface \n")); + wanmgr_construct_wan_address_from_IAPD(pDhcpv6Data); + } + } pthread_mutex_t DhcpClientEvents_mutex = PTHREAD_MUTEX_INITIALIZER; @@ -189,7 +200,7 @@ void* WanMgr_DhcpClientEventsHandler_Thread(void *arg) //TODO: Check for sysevents if(pVirtIf->IP.Ipv6Data.prefixAssigned == TRUE) { - WanManager_Ipv6PrefixUtil(pVirtIf->Name, SET_LFT, pVirtIf->IP.Ipv6Data.prefixPltime, pVirtIf->IP.Ipv6Data.prefixVltime); + WanManager_Ipv6AddrUtil(pVirtIf, SET_LFT); sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_RADVD_RESTART, NULL, 0); } CcspTraceInfo(("%s-%d : DHCPv6 lease renewed for %s\n", __FUNCTION__, __LINE__, pVirtIf->Name)); diff --git a/source/WanManager/wanmgr_dhcpv6_apis.c b/source/WanManager/wanmgr_dhcpv6_apis.c index d3f4fcd9..dd0846bb 100644 --- a/source/WanManager/wanmgr_dhcpv6_apis.c +++ b/source/WanManager/wanmgr_dhcpv6_apis.c @@ -53,10 +53,8 @@ extern char g_Subsystem[32]; #endif #endif -#if defined(FEATURE_RDKB_CONFIGURABLE_WAN_INTERFACE) #define COSA_DML_WANIface_ADDR_SYSEVENT_NAME "tr_%s_dhcpv6_client_v6addr" char PreviousIPv6Address[128] = {0}; //Global varibale to store previous IPv6 address -#endif static struct { pthread_t dhcpv6c_thread; @@ -1406,8 +1404,14 @@ WanMgr_DmlDhcpv6Remove(ANSC_HANDLE hContext) } #if defined(FEATURE_RDKB_CONFIGURABLE_WAN_INTERFACE) - /* dhcpv6_assign_global_ip Copied from PAM module */ -int dhcpv6_assign_global_ip(char * prefix, char * intfName, char * ipAddr) +/** +@brief Generates a full IPv6 address in EUI-64 format from a delegated prefix. +@param prefix The delegated IPv6 prefix. +@param intfName The name of the network interface. +@param ipAddr The buffer to store the generated IPv6 address. +@return int 0 on success, non-zero on failure. +*/ +static int WanMgr_create_eui64_ipv6_address(char * prefix, char * intfName, char * ipAddr) { unsigned int length = 0; @@ -1447,28 +1451,6 @@ int dhcpv6_assign_global_ip(char * prefix, char * intfName, char * ipAddr) CcspTraceError(("error, there is not '::' in prefix:%s\n", prefix)); return 1; } -#if defined(_HUB4_PRODUCT_REQ_) || defined(_RDKB_GLOBAL_PRODUCT_REQ_) -#if defined(_RDKB_GLOBAL_PRODUCT_REQ_) - WanMgr_Config_Data_t *pWanConfigData = WanMgr_GetConfigData_locked(); - unsigned char IPv6EUI64FormatSupport = TRUE; - - if( NULL != pWanConfigData ) - { - IPv6EUI64FormatSupport = pWanConfigData->data.IPv6EUI64FormatSupport; - WanMgrDml_GetConfigData_release(pWanConfigData); - } - - if ( FALSE == IPv6EUI64FormatSupport ) -#endif /** _RDKB_GLOBAL_PRODUCT_REQ_ */ - { - if(strncmp(intfName, COSA_DML_DHCPV6_SERVER_IFNAME, strlen(intfName)) == 0) - { - snprintf(ipAddr, 128, "%s1", globalIP); - CcspTraceInfo(("the full part is:%s\n", ipAddr)); - return 0; - } - } -#endif j = i-2; k = 0; @@ -1487,6 +1469,7 @@ int dhcpv6_assign_global_ip(char * prefix, char * intfName, char * ipAddr) CcspTraceInfo(("the first part is:%s\n", globalIP)); /* prepare second part */ + /* Step 1: Extract the MAC address of the specified network interface */ fp = v_secure_popen("r", "ifconfig %s | grep HWaddr", intfName ); _get_shell_output(fp, out, sizeof(out)); v_secure_pclose(fp); @@ -1499,6 +1482,7 @@ int dhcpv6_assign_global_ip(char * prefix, char * intfName, char * ipAddr) while( pMac && (pMac[0] == ' ') ) pMac++; + /* Step 2: Toggle the 7th bit of the first byte of the MAC address */ /* switch 7bit to 1*/ tmp[0] = pMac[1]; @@ -1513,12 +1497,14 @@ int dhcpv6_assign_global_ip(char * prefix, char * intfName, char * ipAddr) pMac[1] = k; pMac[17] = '\0'; + /* Step 3: Insert the "FF:FE" sequence in the middle of the MAC address */ //00:50:56: FF:FE: 92:00:22 _ansc_strncpy(out, pMac, 9); out[9] = '\0'; _ansc_strcat(out, "FF:FE:"); _ansc_strcat(out, pMac+9); + /* Step 4: Format the resulting string into the IPv6 address format */ for(k=0,j=0;out[j];j++){ if ( out[j] == ':' ) continue; @@ -1531,7 +1517,7 @@ int dhcpv6_assign_global_ip(char * prefix, char * intfName, char * ipAddr) globalIP[i-1] = '\0'; - CcspTraceInfo(("the full part is:%s\n", globalIP)); + CcspTraceInfo(("The generated Ip v6 address for interface %s is:%s\n",intfName, globalIP)); _ansc_strncpy(ipAddr, globalIP, sizeof(globalIP) - 1); /* This IP should be unique. If not I have no idea. */ return 0; @@ -1592,6 +1578,98 @@ static int WanMgr_CopyPreviousPrefix(WANMGR_IPV6_DATA* pOld, WANMGR_IPV6_DATA* p } #endif +/** + * @brief Constructs a dedicated WAN IPv6 address from the received IAPD (IA Prefix Delegation). + * + * This function extracts the IPv6 prefix and its length from the given IAPD data. It then uses + * the provided prefix to construct a unique WAN IPv6 address by using the next available /64 subnet. + * The first /64 subnet of the IAPD is reserved for LAN, while the next /64 is used for the WAN address. + * The constructed WAN address is assigned to the specified WAN interface. + * + * @param[in] pIpv6DataNew Pointer to the WANMGR_IPV6_DATA structure. + * + * @return + * - 0 on success. + * - -1 on failure (e.g., invalid prefix format, prefix length >= 64, or system command failure). + * + * @note The function assumes that if the prefix length is less than 64, there are sufficient bits available + * to split the IAPD into multiple /64 subnets. If the prefix length is 64 or greater, it logs an error + * and returns -1 since further subnetting is not possible. + * + * ### Example: + * Given an IAPD of "2a06:5906:13:d000::/56", the function may construct the following addresses: + * - LAN IPv6 Address Range: "2a06:5906:13:d000::/64" + * - WAN IPv6 Address: "2a06:5906:13:d001::1/128" + */ +#define WAN_SUFFIX 1 +int wanmgr_construct_wan_address_from_IAPD(WANMGR_IPV6_DATA *pIpv6DataNew) +{ + int prefix_length; + char iapd_prefix[128] = {0}; + char cmdLine[256] = {0}; + if (sscanf(pIpv6DataNew->sitePrefix, "%[^/]/%d", iapd_prefix, &prefix_length) != 2) + { + return -1; // Parsing failed + } + + if ( prefix_length >= 64) + { + CcspTraceError(("%s %d Prefix length is >= 64. Can't split to multiple /64 networks\n", __FUNCTION__, __LINE__)); + return -1; + } + + struct in6_addr prefix; + // Convert prefix to binary format + if (inet_pton(AF_INET6, iapd_prefix, &prefix) != 1) + { + + CcspTraceError(("%s %d Failed to convert prefix to in6_addr\n", __FUNCTION__, __LINE__)); + return -1; + } + + prefix.s6_addr[7] += 0x01; // Use next subnet for WAN. First /64 will be used for LAN. + + WanMgr_Config_Data_t *pWanConfigData = WanMgr_GetConfigData_locked(); + unsigned char IPv6EUI64FormatSupport = TRUE; + if( NULL != pWanConfigData ) + { + IPv6EUI64FormatSupport = pWanConfigData->data.IPv6EUI64FormatSupport; + WanMgrDml_GetConfigData_release(pWanConfigData); + } + + if(IPv6EUI64FormatSupport) + { + char newPref[128] = {0}; + inet_ntop(AF_INET6, &prefix, newPref, sizeof(newPref)); + CcspTraceInfo(("%s %d EUI64 format is enabled using new prefix %s \n", __FUNCTION__, __LINE__, newPref)); + snprintf(cmdLine, sizeof(cmdLine), "%s/%d", newPref, prefix_length); + WanMgr_create_eui64_ipv6_address(cmdLine, pIpv6DataNew->ifname, pIpv6DataNew->address); + } + else + { + CcspTraceInfo(("%s %d EUI64 format is not enabled using WAN SUFFIX %d \n", __FUNCTION__, __LINE__, WAN_SUFFIX)); + prefix.s6_addr[15] = WAN_SUFFIX; // Setting the last byte for WAN address + inet_ntop(AF_INET6, &prefix, pIpv6DataNew->address, sizeof(pIpv6DataNew->address)); + } + + pIpv6DataNew->addrAssigned = true; + pIpv6DataNew->addrCmd = IFADDRCONF_ADD; + + CcspTraceInfo(("%s %d Calculated WAN network IP %s/128 \n", __FUNCTION__, __LINE__, pIpv6DataNew->address)); + //Since this address calculated by us, it will be assigned by the DHCPv6c client. Assign the address on the Wan interface + memset(cmdLine, 0, sizeof(cmdLine)); + snprintf(cmdLine, sizeof(cmdLine), "ip -6 addr add %s/128 dev %s", pIpv6DataNew->address, pIpv6DataNew->ifname); + if (WanManager_DoSystemActionWithStatus(__FUNCTION__, cmdLine) != 0) + CcspTraceError(("failed to run cmd: %s", cmdLine)); + + memset(cmdLine, 0, sizeof(cmdLine)); + snprintf(cmdLine, sizeof(cmdLine), COSA_DML_WANIface_ADDR_SYSEVENT_NAME , pIpv6DataNew->ifname); + sysevent_set(sysevent_fd, sysevent_token, cmdLine, pIpv6DataNew->address, 0); + + return 0; +} + + ANSC_STATUS wanmgr_handle_dhcpv6_event_data(DML_VIRTUAL_IFACE * pVirtIf) { if(NULL == pVirtIf) @@ -1664,7 +1742,8 @@ ANSC_STATUS wanmgr_handle_dhcpv6_event_data(DML_VIRTUAL_IFACE * pVirtIf) /* In an IPv6 lease, both IANA and IAPD details are sent together in a struct. * If only one of them is renewed, the other field will be set to its default value. * In this scenario, we should not consider IANA or IAPD as deleted. - * If we reach this point, only IAPD has been renewed. Use the previous IANA details. */ + * If we reach this point, only IAPD has been renewed. Use the previous IANA details. + */ CcspTraceWarning(("%s %d IANA is not assigned in this IPC msg, but we have IANA configured from previous lease. Assuming only IAPD renewed. \n", __FUNCTION__, __LINE__)); strncpy(Ipv6DataNew.address, pDhcp6cInfoCur->address, sizeof(Ipv6DataNew.address)); @@ -1672,6 +1751,18 @@ ANSC_STATUS wanmgr_handle_dhcpv6_event_data(DML_VIRTUAL_IFACE * pVirtIf) pNewIpcMsg->addrAssigned = true; Ipv6DataNew.addrCmd = pDhcp6cInfoCur->addrCmd; } + else if(Ipv6DataNew.prefixAssigned) + { + /* In an IPv6 lease, if only IAPD is received and we never received IANA, + * We can use the received IAPD to construct a Ipv6 /128 address which can be used for managerment and voice ... + * If we reach this point, only IAPD has been received. Canculate Wan Ipv6 address + */ + + CcspTraceInfo(("IANA is not assigned by DHCPV6. Constructing WAN address from the IAPD for Wan Interface \n")); + wanmgr_construct_wan_address_from_IAPD(&Ipv6DataNew); + pNewIpcMsg->addrAssigned = true; + } + /* dhcp6c receives prefix delegation for LAN */ if (pNewIpcMsg->prefixAssigned && !IS_EMPTY_STRING(pNewIpcMsg->sitePrefix)) @@ -1873,29 +1964,8 @@ ANSC_STATUS wanmgr_handle_dhcpv6_event_data(DML_VIRTUAL_IFACE * pVirtIf) { if(pVirtIf->Status == WAN_IFACE_STATUS_UP && pNewIpcMsg->prefixPltime > 0 && pNewIpcMsg->prefixVltime > 0 ) //Update life time only if the interface is active. { -#if !(defined (_XB6_PRODUCT_REQ_) || defined (_CBR2_PRODUCT_REQ_) || defined(_PLATFORM_RASPBERRYPI_)) || defined(_RDKB_GLOBAL_PRODUCT_REQ_) //Do not add prefix on LAN bridge for the Comcast platforms. -#if defined(_RDKB_GLOBAL_PRODUCT_REQ_) - WanMgr_Config_Data_t *pWanConfigData = WanMgr_GetConfigData_locked(); - unsigned char ConfigureWANIPv6OnLANBridgeSupport = FALSE; - - if( NULL != pWanConfigData ) - { - ConfigureWANIPv6OnLANBridgeSupport = pWanConfigData->data.ConfigureWANIPv6OnLANBridgeSupport; - WanMgrDml_GetConfigData_release(pWanConfigData); - } - - if ( TRUE == ConfigureWANIPv6OnLANBridgeSupport ) -#endif /** _RDKB_GLOBAL_PRODUCT_REQ_ */ - { - //call function for changing the prlft and vallft - if ((WanManager_Ipv6PrefixUtil(pVirtIf->Name, SET_LFT, pNewIpcMsg->prefixPltime, pNewIpcMsg->prefixVltime) < 0)) - { - CcspTraceError(("Life Time Setting Failed")); - } sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_RADVD_RESTART, NULL, 0); } -#endif - } pVirtIf->IP.Ipv6Renewed = TRUE; } // update current IPv6 Data @@ -1953,6 +2023,14 @@ ANSC_STATUS wanmgr_handle_dhcpv6_event_data(DML_VIRTUAL_IFACE * pVirtIf) return ANSC_STATUS_SUCCESS; } /* End of ProcessDhcp6cStateChanged() */ +/** + * @brief Sets up the IPv6 /128 address for the LAN bridge. + * This function creates an IPv6 /128 address for the LAN bridge, + * configures all necessary system events for the IPv6 LAN, + * and restarts the DHCPv6 server and RA server if required. + * @param pVirtIf Pointer to the virtual interface structure. + * @return int 0 on success, non-zero on failure. + */ int setUpLanPrefixIPv6(DML_VIRTUAL_IFACE* pVirtIf) { if (pVirtIf == NULL) @@ -2013,27 +2091,22 @@ int setUpLanPrefixIPv6(DML_VIRTUAL_IFACE* pVirtIf) if (pVirtIf->IP.Ipv6Data.prefixPltime != 0 && pVirtIf->IP.Ipv6Data.prefixVltime != 0) { - ret = dhcpv6_assign_global_ip(pVirtIf->IP.Ipv6Data.sitePrefix, COSA_DML_DHCPV6_SERVER_IFNAME, globalIP); + //Create a global IP for the LAN bridge from the received delegated prefix. + ret = WanMgr_create_eui64_ipv6_address(pVirtIf->IP.Ipv6Data.sitePrefix, COSA_DML_DHCPV6_SERVER_IFNAME, globalIP); if(ret != 0) { CcspTraceInfo(("Assign global ip error \n")); } else { -#if !(defined (_XB6_PRODUCT_REQ_) || defined (_CBR2_PRODUCT_REQ_) || defined(_PLATFORM_RASPBERRYPI_)) //Do not add prefix on LAN bridge for the Comcast platforms. - CcspTraceInfo(("%s Going to set [%s] address on brlan0 interface \n", __FUNCTION__, globalIP)); - memset(cmdLine, 0, sizeof(cmdLine)); - snprintf(cmdLine, sizeof(cmdLine), "ip -6 addr add %s/64 dev %s valid_lft %d preferred_lft %d", - globalIP, COSA_DML_DHCPV6_SERVER_IFNAME, pVirtIf->IP.Ipv6Data.prefixVltime, pVirtIf->IP.Ipv6Data.prefixPltime); - if (WanManager_DoSystemActionWithStatus(__FUNCTION__, cmdLine) != 0) - CcspTraceError(("failed to run cmd: %s", cmdLine)); -#endif - CcspTraceInfo(("%s lan_ipaddr_v6 set to [%s] \n", __FUNCTION__, globalIP)); + snprintf(pVirtIf->IP.Ipv6Data.pdIfAddress, sizeof(pVirtIf->IP.Ipv6Data.pdIfAddress), "%s/64", globalIP); /*This is for brlan0 interface */ char pref_len[10] ={0}; sscanf (pVirtIf->IP.Ipv6Data.sitePrefix,"%*[^/]/%s" ,pref_len); sysevent_set(sysevent_fd, sysevent_token, "lan_prefix_v6", pref_len, 0); sysevent_set(sysevent_fd, sysevent_token, "lan_ipaddr_v6", globalIP, 0); sysevent_set(sysevent_fd, sysevent_token, "lan_prefix_set", globalIP, 0); //TODO: This was a event to Wanmanager. if no other process listens to it. remove it. + sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIELD_TR_BRLAN0_DHCPV6_SERVER_ADDRESS, globalIP, 0); + CcspTraceInfo(("%s lan_ipaddr_v6 set to [%s] \n", __FUNCTION__, globalIP)); } memset(cmdLine, 0, sizeof(cmdLine)); snprintf(cmdLine, sizeof(cmdLine), "ip -6 route add %s dev %s", pVirtIf->IP.Ipv6Data.sitePrefix, COSA_DML_DHCPV6_SERVER_IFNAME); @@ -2080,11 +2153,12 @@ int setUpLanPrefixIPv6(DML_VIRTUAL_IFACE* pVirtIf) int index = strcspn(pVirtIf->IP.Ipv6Data.sitePrefix, "/"); if (index < strlen(pVirtIf->IP.Ipv6Data.sitePrefix) && index < sizeof(prefix)) { - strncpy(prefix, pVirtIf->IP.Ipv6Data.sitePrefix, index); // only copy prefix without the prefix length - snprintf(set_value, sizeof(set_value), "%s1", prefix); // concatenate "1" onto the prefix, which is in the form "xxxx:xxxx:xxxx:xxxx::" - snprintf(pVirtIf->IP.Ipv6Data.pdIfAddress, sizeof(pVirtIf->IP.Ipv6Data.pdIfAddress), "%s/64", set_value); // concatenate prefix address with length "/64" - syscfg_set_string(SYSCFG_FIELD_IPV6_PREFIX_ADDRESS, pVirtIf->IP.Ipv6Data.pdIfAddress); - sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIELD_TR_BRLAN0_DHCPV6_SERVER_ADDRESS, set_value, 0); + strncpy(prefix, pVirtIf->IP.Ipv6Data.sitePrefix, index); // only copy prefix without the prefix length + // Create and set IPv6 address with /128 prefix length //TODO: SYSCFG_FIELD_IPV6_PREFIX_ADDRESS may not be used anymore. Check and remove if not used in the NTP script + char ipv6_addr_with_prefix[BUFLEN_64] = {0}; + snprintf(ipv6_addr_with_prefix, sizeof(ipv6_addr_with_prefix), "%s/128", pVirtIf->IP.Ipv6Data.address); + syscfg_set_string(SYSCFG_FIELD_IPV6_PREFIX_ADDRESS, ipv6_addr_with_prefix); + CcspTraceInfo(("%s %d IPv6 address syscfg %s set to %s\n", __FUNCTION__, __LINE__, SYSCFG_FIELD_IPV6_PREFIX_ADDRESS, ipv6_addr_with_prefix)); CcspTraceInfo(("%s %d new prefix = %s\n", __FUNCTION__, __LINE__, pVirtIf->IP.Ipv6Data.sitePrefix)); #if defined(CISCO_CONFIG_DHCPV6_PREFIX_DELEGATION) /* Use the delegated prefix length directly for platforms that support prefix delegation to LAN clients */ diff --git a/source/WanManager/wanmgr_dhcpv6_apis.h b/source/WanManager/wanmgr_dhcpv6_apis.h index ec591e69..bcc262db 100644 --- a/source/WanManager/wanmgr_dhcpv6_apis.h +++ b/source/WanManager/wanmgr_dhcpv6_apis.h @@ -49,7 +49,7 @@ #define ULOGF #endif -#define COSA_DML_DHCPV6_SERVER_IFNAME CFG_TR181_DHCPv6_SERVER_IfName +#define COSA_DML_DHCPV6_SERVER_IFNAME "brlan0" #define COSA_DML_DHCPV6C_PREF_SYSEVENT_NAME "tr_"DML_DHCP_CLIENT_IFNAME"_dhcpv6_client_v6pref" #define COSA_DML_DHCPV6C_PREF_IAID_SYSEVENT_NAME "tr_"DML_DHCP_CLIENT_IFNAME"_dhcpv6_client_pref_iaid" @@ -353,6 +353,31 @@ void _get_shell_output(FILE *fp, char * out, int len); ************************************************************************************/ int setUpLanPrefixIPv6(DML_VIRTUAL_IFACE* pVirtIf); +/** + * @brief Constructs a dedicated WAN IPv6 address from the received IAPD (IA Prefix Delegation). + * + * This function extracts the IPv6 prefix and its length from the given IAPD data. It then uses + * the provided prefix to construct a unique WAN IPv6 address by using the next available /64 subnet. + * The first /64 subnet of the IAPD is reserved for LAN, while the next /64 is used for the WAN address. + * The constructed WAN address is assigned to the specified WAN interface. + * + * @param[in] pIpv6DataNew Pointer to the WANMGR_IPV6_DATA structure. + * + * @return + * - 0 on success. + * - -1 on failure (e.g., invalid prefix format, prefix length >= 64, or system command failure). + * + * @note The function assumes that if the prefix length is less than 64, there are sufficient bits available + * to split the IAPD into multiple /64 subnets. If the prefix length is 64 or greater, it logs an error + * and returns -1 since further subnetting is not possible. + * + * ### Example: + * Given an IAPD of "2a06:5906:13:d000::/56", the function may construct the following addresses: + * - LAN IPv6 Address Range: "2a06:5906:13:d000::/64" + * - WAN IPv6 Address: "2a06:5906:13:d001::1/128" + */ +int wanmgr_construct_wan_address_from_IAPD(WANMGR_IPV6_DATA *pIpv6DataNew); + ANSC_STATUS WanMgr_Handle_Dhcpv6_NetLink_Address_Event(IPv6NetLinkAddrEvent *pstAddrEvent); #endif //_WANMGR_DHCPV6_APIS_H_ diff --git a/source/WanManager/wanmgr_interface_sm.c b/source/WanManager/wanmgr_interface_sm.c index 8d2d103d..cd1367f5 100644 --- a/source/WanManager/wanmgr_interface_sm.c +++ b/source/WanManager/wanmgr_interface_sm.c @@ -59,9 +59,6 @@ #define POSTD_START_FILE "/tmp/.postd_started" #define SELECTED_MODE_TIMEOUT_SECONDS 10 -#if defined(FEATURE_IPOE_HEALTH_CHECK) && defined(IPOE_HEALTH_CHECK_LAN_SYNC_SUPPORT) -extern lanState_t lanState; -#endif #if defined(FEATURE_464XLAT) typedef enum @@ -198,7 +195,7 @@ static ANSC_STATUS WanManager_ClearDHCPData(DML_VIRTUAL_IFACE * pVirtIf); * lan ipv6 address ready to use. * @return RETURN_OK on success else RETURN_ERR *************************************************************************************/ -static int checkIpv6LanAddressIsReadyToUse(DML_VIRTUAL_IFACE* p_VirtIf); +static int checkIpv6AddressIsReadyToUse(DML_VIRTUAL_IFACE* p_VirtIf); #ifdef FEATURE_MAPE /************************************************************************************* @@ -1035,57 +1032,37 @@ int wan_updateDNS(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl, BOOL addIPv4, BOOL return ret; } -/* Check Duplicate Address Detection (DAD) status. The way it works is that - after an address is added to an interface, the operating system uses the - Neighbor Discovery Protocol to check if any other host on the network - has the same address. The whole process will take around 3 to 4 seconds - to complete. Also we need to check and ensure that the gateway has - a valid default route entry. + +/** + * @brief Checks if the IPv6 address is ready to use. + * + * This function checks the tentative address, detects Duplicate Address Detection (DAD) failure, and verifies the default route. + * If DAD fails, it also triggers a Router Solicitation. + * + * @param p_VirtIf Pointer to the virtual interface structure. + * @return int 0 on success, negative value on failure. */ -static int checkIpv6LanAddressIsReadyToUse(DML_VIRTUAL_IFACE* p_VirtIf) +static int checkIpv6AddressIsReadyToUse(DML_VIRTUAL_IFACE* p_VirtIf) { char buffer[BUFLEN_256] = {0}; - FILE *fp_dad = NULL; - FILE *fp_route = NULL; + FILE *fp_dad = NULL; + FILE *fp_route = NULL; int dad_flag = 0; int route_flag = 0; - int i; - char IfaceName[BUFLEN_16] = {0}; - int BridgeMode = 0; - - { //TODO : temporary debug code to identify the bridgemode sysevent failure issue. - char Output[BUFLEN_16] = {0}; - if (sysevent_get(sysevent_fd, sysevent_token, "bridge_mode", Output, sizeof(Output)) !=0) - { - CcspTraceError(("%s-%d: bridge_mode sysevent get failed. \n", __FUNCTION__, __LINE__)); - } - BridgeMode = atoi(Output); - CcspTraceInfo(("%s-%d: <> bridge_mode sysevent value set to =%d \n", __FUNCTION__, __LINE__, BridgeMode)); - } - /*TODO: - *Below Code should be removed once V6 Prefix/IP is assigned on erouter0 Instead of brlan0 for sky Devices. - */ - strncpy(IfaceName, ETH_BRIDGE_NAME, sizeof(IfaceName)-1); - if (WanMgr_isBridgeModeEnabled() == TRUE) - { - CcspTraceInfo(("%s-%d: Device is in bridge mode. Assigning IPv6 address on WAN interface.\n", __FUNCTION__, __LINE__)); - memset(IfaceName, 0, sizeof(IfaceName)); - strncpy(IfaceName, p_VirtIf->Name, sizeof(IfaceName)-1); - } - CcspTraceInfo(("%s-%d: IfaceName=%s, BridgeMode=%d \n", __FUNCTION__, __LINE__, IfaceName, BridgeMode)); - /* TODO: the below code assumes if the LAN ipv6 address is tentaive for 15 seconds DAD has failed. Do we need additional check? - * IANA dad is handled in the DHCPv6 client for the Wan Interface. - * Should we remove the IP from LAN bridge and request a different Delegated prefix? - * Should we use EUI-64 based Interface identifiers for all platforms? - */ + /* Check Duplicate Address Detection (DAD) status. The way it works is that after an address is added to an interface, the operating system uses the + Neighbor Discovery Protocol to check if any other host on the network has the same address. The whole process will take around 3 to 4 seconds + to complete. Also we need to check and ensure that the gateway has a valid default route entry. + */ + // Note: This check is not strictly necessary and this check could delay the WAN up by 15 seconds in worst case. If the IPv6 address (IANA) is obtained via DHCPv6, and the DHCP client already performs the DAD check. + // However, it is beneficial to verify that the WAN IPv6 address is auto-calculated from the delegated prefix or via SLAAC. - for(i=0; i<15; i++) + for(int i=0; i<15; i++) { buffer[0] = '\0'; if(dad_flag == 0) { - if ((fp_dad = v_secure_popen("r","ip address show dev %s tentative", IfaceName))) + if ((fp_dad = v_secure_popen("r","ip address show dev %s tentative", p_VirtIf->Name))) { if(fp_dad != NULL) { @@ -1098,7 +1075,6 @@ static int checkIpv6LanAddressIsReadyToUse(DML_VIRTUAL_IFACE* p_VirtIf) } } } - if(dad_flag == 0) { sleep(1); @@ -1122,10 +1098,10 @@ static int checkIpv6LanAddressIsReadyToUse(DML_VIRTUAL_IFACE* p_VirtIf) } } - //if DAD failed on LAN bridge, log an ERROR message and continue with the WAN process. + //if DAD failed on WAN interface, log an ERROR message and continue with the WAN process. if(dad_flag == 0 || route_flag == 0) { - CcspTraceError(("%s %d dad_flag[%d] route_flag[%d] Failed \n", __FUNCTION__, __LINE__,dad_flag,route_flag)); + CcspTraceError(("%s %d dad_flag[%s] route_flag[%s] Failed \n", __FUNCTION__, __LINE__, dad_flag ? "SUCCESS" : "FAILED", route_flag ? "SUCCESS" : "FAILED")); } if(route_flag == 0) @@ -1627,8 +1603,9 @@ static int wan_tearDownIPv6(WanMgr_IfaceSM_Controller_t * pWanIfaceCtrl) } } #endif + /** Unconfig IPv6. */ - if ( WanManager_Ipv6PrefixUtil(p_VirtIf->Name, DEL_ADDR,0,0) < 0) + if ( WanManager_Ipv6AddrUtil(p_VirtIf, DEL_ADDR) < 0) { AnscTraceError(("%s %d - Failed to remove inactive address \n", __FUNCTION__,__LINE__)); } @@ -1661,6 +1638,7 @@ static int wan_tearDownIPv6(WanMgr_IfaceSM_Controller_t * pWanIfaceCtrl) sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIREWALL_RESTART, NULL, 0); //RBUS_WAN_IP +//TODO : **************************** Check this ************************ #if defined (RBUS_WAN_IP) #if defined(_RDKB_GLOBAL_PRODUCT_REQ_) unsigned char ConfigureWANIPv6OnLANBridgeSupport = FALSE; @@ -1869,14 +1847,14 @@ static ANSC_STATUS WanMgr_SendMsgTo_ConnectivityCheck(WanMgr_IfaceSM_Controller_ //Restarting firewall to add IPOE_HEALTH_CHECK firewall rules. sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIREWALL_RESTART, NULL, 0); } - WanMgr_SendMsgToIHC(IPOE_MSG_WAN_CONNECTION_UP, p_VirtIf->Name); + WanMgr_SendMsgToIHC(IPOE_MSG_WAN_CONNECTION_UP, p_VirtIf); pWanIfaceCtrl->IhcV4Status = IHC_STARTED; } } else if(type == CONNECTION_MSG_IPV4 && ConnStatus == FALSE) { CcspTraceInfo(("%s %d Sending IPOE_MSG_WAN_CONNECTION_DOWN \n", __FUNCTION__, __LINE__)); - WanMgr_SendMsgToIHC(IPOE_MSG_WAN_CONNECTION_DOWN, p_VirtIf->Name); + WanMgr_SendMsgToIHC(IPOE_MSG_WAN_CONNECTION_DOWN, p_VirtIf); pWanIfaceCtrl->IhcV4Status = IHC_STOPPED; } else if(type == CONNECTION_MSG_IPV6 && ConnStatus == TRUE) @@ -1892,14 +1870,14 @@ static ANSC_STATUS WanMgr_SendMsgTo_ConnectivityCheck(WanMgr_IfaceSM_Controller_ //Restarting firewall to add IPOE_HEALTH_CHECK firewall rules. sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIREWALL_RESTART, NULL, 0); } - WanMgr_SendMsgToIHC(IPOE_MSG_WAN_CONNECTION_IPV6_UP, p_VirtIf->Name); + WanMgr_SendMsgToIHC(IPOE_MSG_WAN_CONNECTION_IPV6_UP, p_VirtIf); pWanIfaceCtrl->IhcV6Status = IHC_STARTED; } } else if(type == CONNECTION_MSG_IPV6 && ConnStatus == FALSE) { CcspTraceInfo(("%s %d Sending IPOE_MSG_WAN_CONNECTION_IPV6_DOWN \n", __FUNCTION__, __LINE__)); - WanMgr_SendMsgToIHC(IPOE_MSG_WAN_CONNECTION_IPV6_DOWN, p_VirtIf->Name); + WanMgr_SendMsgToIHC(IPOE_MSG_WAN_CONNECTION_IPV6_DOWN, p_VirtIf); pWanIfaceCtrl->IhcV6Status = IHC_STOPPED; } @@ -2753,7 +2731,6 @@ static eWanState_t wan_transition_ipv6_down(WanMgr_IfaceSM_Controller_t* pWanIfa WanMgr_Rbus_EventPublishHandler(param_name, "", RBUS_STRING); snprintf(param_name, sizeof(param_name), "Device.X_RDK_WanManager.Interface.%d.VirtualInterface.%d.IP.IPv6Prefix", p_VirtIf->baseIfIdx+1, p_VirtIf->VirIfIdx+1); WanMgr_Rbus_EventPublishHandler(param_name, "", RBUS_STRING); - WanManager_UpdateInterfaceStatus (p_VirtIf, WANMGR_IFACE_CONNECTION_IPV6_DOWN); //Disable accept_ra WanMgr_Configure_accept_ra(p_VirtIf, FALSE); @@ -2775,6 +2752,16 @@ static eWanState_t wan_transition_ipv6_down(WanMgr_IfaceSM_Controller_t* pWanIfa } } + WanManager_UpdateInterfaceStatus (p_VirtIf, WANMGR_IFACE_CONNECTION_IPV6_DOWN); + //clear IPv6 lease from the interface data + memset(&(p_VirtIf->IP.Ipv6Data), 0, sizeof(WANMGR_IPV6_DATA)); + if (p_VirtIf->IP.pIpcIpv6Data != NULL ) + { + //free memory + free(p_VirtIf->IP.pIpcIpv6Data); + p_VirtIf->IP.pIpcIpv6Data = NULL; + } + #if defined(FEATURE_464XLAT) xlat_status = xlat_state_get(); if(xlat_status == XLAT_ON) @@ -3649,7 +3636,7 @@ static eWanState_t wan_state_obtaining_ip_addresses(WanMgr_IfaceSM_Controller_t* p_VirtIf->IP.Ipv6Changed = FALSE; return WAN_STATE_OBTAINING_IP_ADDRESSES; } - if (checkIpv6LanAddressIsReadyToUse(p_VirtIf) == RETURN_OK) + if (checkIpv6AddressIsReadyToUse(p_VirtIf) == RETURN_OK) { return wan_transition_ipv6_up(pWanIfaceCtrl); } @@ -3720,7 +3707,7 @@ static eWanState_t wan_state_standby(WanMgr_IfaceSM_Controller_t* pWanIfaceCtrl) } p_VirtIf->IP.Ipv6Changed = FALSE; } - if (checkIpv6LanAddressIsReadyToUse(p_VirtIf) == RETURN_OK) + if (checkIpv6AddressIsReadyToUse(p_VirtIf) == RETURN_OK) { ret = wan_transition_ipv6_up(pWanIfaceCtrl); CcspTraceInfo((" %s %d - IPv6 Address Assigned to Bridge Yet.\n", __FUNCTION__, __LINE__)); @@ -3823,7 +3810,7 @@ static eWanState_t wan_state_ipv4_leased(WanMgr_IfaceSM_Controller_t* pWanIfaceC p_VirtIf->IP.Ipv6Changed = FALSE; return WAN_STATE_IPV4_LEASED; } - if (checkIpv6LanAddressIsReadyToUse(p_VirtIf) == RETURN_OK) + if (checkIpv6AddressIsReadyToUse(p_VirtIf) == RETURN_OK) { return wan_transition_ipv6_up(pWanIfaceCtrl); } @@ -3931,7 +3918,7 @@ static eWanState_t wan_state_ipv6_leased(WanMgr_IfaceSM_Controller_t* pWanIfaceC } #if defined(FEATURE_MAPT) || defined(FEATURE_SUPPORT_MAPT_NAT46) || defined(FEATURE_MAPE) else if (pInterface->Selection.Status == WAN_IFACE_ACTIVE && - ((p_VirtIf->EnableMAPT == TRUE && p_VirtIf->MAP.MaptStatus == WAN_IFACE_MAPT_STATE_UP && checkIpv6LanAddressIsReadyToUse(p_VirtIf) ==RETURN_OK) + ((p_VirtIf->EnableMAPT == TRUE && p_VirtIf->MAP.MaptStatus == WAN_IFACE_MAPT_STATE_UP && checkIpv6AddressIsReadyToUse(p_VirtIf) ==RETURN_OK) || (p_VirtIf->MAP.dhcp6cMAPparameters.mapType == MAP_TYPE_MAPE && p_VirtIf->Status == WAN_IFACE_STATUS_UP && p_VirtIf->MAP.MapeStatus == WAN_IFACE_MAPE_STATE_UP))) { CcspTraceInfo(("%s %d - calling wan_transition_map_up \n", __FUNCTION__, __LINE__)); @@ -3960,18 +3947,6 @@ static eWanState_t wan_state_ipv6_leased(WanMgr_IfaceSM_Controller_t* pWanIfaceC 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_IPV6_LEASED; } @@ -4070,7 +4045,7 @@ static eWanState_t wan_state_dual_stack_active(WanMgr_IfaceSM_Controller_t* pWan } #if defined(FEATURE_MAPT) || defined(FEATURE_SUPPORT_MAPT_NAT46) || defined(FEATURE_MAPE) else if (pInterface->Selection.Status == WAN_IFACE_ACTIVE && - ((p_VirtIf->EnableMAPT == TRUE && p_VirtIf->MAP.MaptStatus == WAN_IFACE_MAPT_STATE_UP && checkIpv6LanAddressIsReadyToUse(p_VirtIf) ==RETURN_OK) + ((p_VirtIf->EnableMAPT == TRUE && p_VirtIf->MAP.MaptStatus == WAN_IFACE_MAPT_STATE_UP && checkIpv6AddressIsReadyToUse(p_VirtIf) ==RETURN_OK) || (p_VirtIf->MAP.dhcp6cMAPparameters.mapType == MAP_TYPE_MAPE && p_VirtIf->Status == WAN_IFACE_STATUS_UP && p_VirtIf->MAP.MapeStatus == WAN_IFACE_MAPE_STATE_UP))) { CcspTraceInfo(("%s %d - calling wan_transition_map_up \n", __FUNCTION__, __LINE__)); @@ -4106,18 +4081,6 @@ static eWanState_t wan_state_dual_stack_active(WanMgr_IfaceSM_Controller_t* pWan 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_DUAL_STACK_ACTIVE; } @@ -4262,18 +4225,7 @@ static eWanState_t wan_state_map_active(WanMgr_IfaceSM_Controller_t* pWanIfaceCt 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_MAP_ACTIVE; } diff --git a/source/WanManager/wanmgr_ipc.c b/source/WanManager/wanmgr_ipc.c index bd2b1442..a0361174 100644 --- a/source/WanManager/wanmgr_ipc.c +++ b/source/WanManager/wanmgr_ipc.c @@ -431,7 +431,7 @@ static void WanMgr_RemoveSingleQuote(char *buf) return 0; } -ANSC_STATUS WanMgr_SendMsgToIHC (ipoe_msg_type_t msgType, char *ifName) +ANSC_STATUS WanMgr_SendMsgToIHC (ipoe_msg_type_t msgType, DML_VIRTUAL_IFACE *p_VirtIf ) { int sock = -1; int conn = -1; @@ -444,25 +444,7 @@ ANSC_STATUS WanMgr_SendMsgToIHC (ipoe_msg_type_t msgType, char *ifName) if (msgType == IPOE_MSG_WAN_CONNECTION_IPV6_UP) { // V6 UP Message needs Wan V6 IP - char* pattern = NULL; - char ipv6_prefix[INET6_ADDRSTRLEN] = {0}; - - sysevent_get(sysevent_fd, sysevent_token, SYSCFG_FIELD_IPV6_PREFIX, ipv6_prefix, sizeof(ipv6_prefix)); - if(ipv6_prefix == NULL || *ipv6_prefix == '\0'|| (0 == strncmp(ipv6_prefix, "(null)", strlen("(null)")))) - { - CcspTraceError(("[%s-%d] Unable to get ipv6_prefix..\n", __FUNCTION__, __LINE__)); - return ANSC_STATUS_FAILURE; - } - - pattern = strstr(ipv6_prefix, "/"); - if (pattern == NULL) - { - CcspTraceError(("[%s-%d] Invalid ipv6_prefix :%s\n", __FUNCTION__, __LINE__, ipv6_prefix)); - return ANSC_STATUS_FAILURE; - } - sprintf(pattern, "%c%c", '1', '\0'); //Form the global address with ::1 - strncpy(msgBody.ipv6Address, ipv6_prefix, sizeof(ipv6_prefix)); - + strncpy(msgBody.ipv6Address, p_VirtIf->IP.Ipv6Data.address, sizeof(msgBody.ipv6Address) - 1); if( 0 == syscfg_get( NULL, "ntp_server1", domainName, sizeof(domainName)) ) { WanMgr_RemoveSingleQuote(domainName); @@ -477,16 +459,7 @@ ANSC_STATUS WanMgr_SendMsgToIHC (ipoe_msg_type_t msgType, char *ifName) } else if (msgType == IPOE_MSG_WAN_CONNECTION_UP) { - char ipv4_wan_address[IP_ADDR_LENGTH] = {0}; - char sysevent_param_name[BUFLEN_64] = {0}; - snprintf(sysevent_param_name, sizeof(sysevent_param_name), SYSEVENT_IPV4_IP_ADDRESS, ifName); - sysevent_get(sysevent_fd, sysevent_token, sysevent_param_name, ipv4_wan_address, sizeof(ipv4_wan_address)); - if(ipv4_wan_address == NULL || *ipv4_wan_address == '\0'|| (0 == strncmp(ipv4_wan_address, "(null)", strlen("(null)")))) - { - CcspTraceError(("[%s-%d] Unable to get ipv4_erouter0_ipaddr..\n", __FUNCTION__, __LINE__)); - return ANSC_STATUS_FAILURE; - } - strncpy(msgBody.ipv4Address, ipv4_wan_address, sizeof(ipv4_wan_address)); + strncpy(msgBody.ipv4Address, p_VirtIf->IP.Ipv4Data.ip, sizeof(msgBody.ipv4Address)-1); if( 0 == syscfg_get( NULL, "ntp_server1", domainName, sizeof(domainName)) ) { @@ -500,9 +473,9 @@ ANSC_STATUS WanMgr_SendMsgToIHC (ipoe_msg_type_t msgType, char *ifName) CcspTraceInfo(("[%s-%d] Sending IPOE_MSG_WAN_CONNECTION_UP msg with addr :%s and domainName: [%s] \n", __FUNCTION__, __LINE__, msgBody.ipv4Address, msgBody.domainName)); } - strncpy(msgBody.ifName, ifName, IFNAME_LENGTH-1); + strncpy(msgBody.ifName, p_VirtIf->Name, IFNAME_LENGTH-1); - CcspTraceInfo(("[%s-%d] Sending msg = %d for interface %s \n", __FUNCTION__, __LINE__, msgType, ifName)); + CcspTraceInfo(("[%s-%d] Sending msg = %d for interface %s \n", __FUNCTION__, __LINE__, msgType, p_VirtIf->Name)); int bytes = 0; int msgSize = sizeof(ipc_ihc_data_t); diff --git a/source/WanManager/wanmgr_ipc.h b/source/WanManager/wanmgr_ipc.h index f0d6d8b2..d8a716b7 100644 --- a/source/WanManager/wanmgr_ipc.h +++ b/source/WanManager/wanmgr_ipc.h @@ -27,7 +27,7 @@ #include "wanmgr_interface_sm.h" #ifdef FEATURE_IPOE_HEALTH_CHECK -ANSC_STATUS WanMgr_SendMsgToIHC (ipoe_msg_type_t msgType, char *ifName); +ANSC_STATUS WanMgr_SendMsgToIHC (ipoe_msg_type_t msgType, DML_VIRTUAL_IFACE *p_VirtIf); #endif diff --git a/source/WanManager/wanmgr_net_utils.c b/source/WanManager/wanmgr_net_utils.c index 7e2e1676..52671bd3 100644 --- a/source/WanManager/wanmgr_net_utils.c +++ b/source/WanManager/wanmgr_net_utils.c @@ -326,114 +326,72 @@ int isModuleLoaded(char *moduleName) ****************************************************************************/ static INT IsIPObtained(char *pInterfaceName); -int WanManager_Ipv6PrefixUtil(char *ifname, Ipv6OperType opr, int preflft, int vallft) +/*************************************************************************** + * @brief Utility function used to perform operation on IPV6 addresses + * for a particular interface + * @param p_VirtIf Pointer to the virtual interface + * @param opr indicates operation type (Delete/Set) + * @return 0 upon success else -1 returned + ***************************************************************************/ +int WanManager_Ipv6AddrUtil(DML_VIRTUAL_IFACE* p_VirtIf,Ipv6OperType opr) { char cmdLine[128] = {0}; - char prefix[BUFLEN_48] = {0}; - char prefixAddr[BUFLEN_48] = {0}; - char IfaceName[BUFLEN_16] = {0}; - int BridgeMode = 0; - - memset(prefix, 0, sizeof(prefix)); - sysevent_get(sysevent_fd, sysevent_token, SYSEVENT_FIELD_IPV6_PREFIX, prefix, sizeof(prefix)); - - memset(prefixAddr, 0, sizeof(prefixAddr)); - sysevent_get(sysevent_fd, sysevent_token, SYSEVENT_GLOBAL_IPV6_PREFIX_SET, prefixAddr, sizeof(prefixAddr)); - - { //TODO : temporary debug code to identify the bridgemode sysevent failure issue. - char Output[BUFLEN_16] = {0}; - if (sysevent_get(sysevent_fd, sysevent_token, "bridge_mode", Output, sizeof(Output)) !=0) - { - CcspTraceError(("%s-%d: bridge_mode sysevent get failed. \n", __FUNCTION__, __LINE__)); - } - BridgeMode = atoi(Output); - CcspTraceInfo(("%s-%d: <> bridge_mode sysevent value set to =%d \n", __FUNCTION__, __LINE__, BridgeMode)); - } - - /*TODO: - *Below Code should be removed once V6 Prefix/IP is assigned on erouter0 Instead of brlan0 for sky Devices. - */ - strcpy(IfaceName, LAN_BRIDGE_NAME); - if (WanMgr_isBridgeModeEnabled() == TRUE) - { - memset(IfaceName, 0, sizeof(IfaceName)); - strncpy(IfaceName, ifname, strlen(ifname)); - } - - CcspTraceInfo(("%s-%d: IfaceName=%s \n", __FUNCTION__, __LINE__, IfaceName)); switch (opr) { case DEL_ADDR: { - if (strlen(prefix) > 0) + if (strlen( p_VirtIf->IP.Ipv6Data.address) > 0) { -#if !(defined (_XB6_PRODUCT_REQ_) || defined (_CBR2_PRODUCT_REQ_) || defined(_PLATFORM_RASPBERRYPI_)) || defined(_RDKB_GLOBAL_PRODUCT_REQ_) //Do not delete prefix from LAn bridge for the comcast platforms. -#if defined(_RDKB_GLOBAL_PRODUCT_REQ_) - WanMgr_Config_Data_t *pWanConfigData = WanMgr_GetConfigData_locked(); - unsigned char ConfigureWANIPv6OnLANBridgeSupport = FALSE; - - if( NULL != pWanConfigData ) - { - ConfigureWANIPv6OnLANBridgeSupport = pWanConfigData->data.ConfigureWANIPv6OnLANBridgeSupport; - WanMgrDml_GetConfigData_release(pWanConfigData); - } + memset(cmdLine, 0, sizeof(cmdLine)); + snprintf(cmdLine, sizeof(cmdLine), "ip -6 addr del %s/128 dev %s", p_VirtIf->IP.Ipv6Data.address, p_VirtIf->Name); + if (WanManager_DoSystemActionWithStatus("ip -6 addr del ADDR dev xxxx", cmdLine) != 0) + CcspTraceError(("failed to run cmd: %s", cmdLine)); - if ( TRUE == ConfigureWANIPv6OnLANBridgeSupport ) -#endif /** _RDKB_GLOBAL_PRODUCT_REQ_ */ - { - memset(cmdLine, 0, sizeof(cmdLine)); - snprintf(cmdLine, sizeof(cmdLine), "ip -6 addr del %s/64 dev %s", prefixAddr, IfaceName); - if (WanManager_DoSystemActionWithStatus("ip -6 addr del ADDR dev xxxx", cmdLine) != 0) - CcspTraceError(("failed to run cmd: %s", cmdLine)); - } -#endif memset(cmdLine, 0, sizeof(cmdLine)); -#if defined(FEATURE_RDKB_CONFIGURABLE_WAN_INTERFACE) - snprintf(cmdLine, sizeof(cmdLine), "ip -6 route flush match %s ", prefix); -#else - snprintf(cmdLine, sizeof(cmdLine), "ip -6 route flush %s ", prefix); -#endif - if (WanManager_DoSystemActionWithStatus("ip -6 route flush PREFIX ", cmdLine) != 0) + snprintf(cmdLine, sizeof(cmdLine), "ip -6 route flush match %s ", p_VirtIf->IP.Ipv6Data.address); + + if (WanManager_DoSystemActionWithStatus(cmdLine, cmdLine) != 0) CcspTraceError(("failed to run cmd: %s", cmdLine)); - CcspTraceInfo(("%s-%d: Successfully del addr and route from Interface %s, prefix=%s, prefixAddr=%s \n", - __FUNCTION__, __LINE__, IfaceName, prefix, prefixAddr)); + CcspTraceInfo(("%s-%d: Successfully del addr and route from Interface %s, Ipv6 Addr=%s \n", + __FUNCTION__, __LINE__, p_VirtIf->Name, p_VirtIf->IP.Ipv6Data.address)); memset(cmdLine, 0, sizeof(cmdLine)); snprintf(cmdLine, sizeof(cmdLine), "ip -6 route delete default"); if (WanManager_DoSystemActionWithStatus("ip -6 route delete default", cmdLine) != 0) CcspTraceError(("failed to run cmd: %s", cmdLine)); + CcspTraceInfo(("%s-%d: Successfully deleted ipv6 default route\n", __FUNCTION__, __LINE__)); } else { - CcspTraceError(("%s-%d: Failed to delete addr and route from Interface %s, prefix=%s, prefixAddr=%s \n", - __FUNCTION__, __LINE__, IfaceName, prefix, prefixAddr)); + CcspTraceError(("%s-%d: Failed to delete addr and route from Interface %s, IPv6 Addr=%s \n", + __FUNCTION__, __LINE__, p_VirtIf->Name, p_VirtIf->IP.Ipv6Data.address)); } break; } + case SET_LFT: { - if (strlen(prefixAddr) > 0) + if (strlen(p_VirtIf->IP.Ipv6Data.address) > 0) { memset(cmdLine, 0, sizeof(cmdLine)); - snprintf(cmdLine, sizeof(cmdLine), "ip -6 addr change %s dev %s valid_lft %d preferred_lft %d ", prefixAddr, IfaceName, vallft, preflft); + snprintf(cmdLine, sizeof(cmdLine), "ip -6 addr change %s dev %s valid_lft %d preferred_lft %d ", p_VirtIf->IP.Ipv6Data.address, p_VirtIf->Name, p_VirtIf->IP.Ipv6Data.prefixVltime, p_VirtIf->IP.Ipv6Data.prefixPltime); if (WanManager_DoSystemActionWithStatus("processDhcp6cStateChanged: ip -6 addr change L3IfName", (cmdLine)) != 0) CcspTraceError(("failed to run cmd: %s", cmdLine)); - CcspTraceInfo(("%s-%d: Successfully updated addr from Interface %s, prefixAddr=%s, vallft=%d, preflft=%d \n", - __FUNCTION__, __LINE__, IfaceName, prefixAddr, vallft, preflft)); + CcspTraceInfo(("%s-%d: Successfully updated addr from Interface %s, Ipv6 Addr=%s, vallft=%d, preflft=%d \n", + __FUNCTION__, __LINE__, p_VirtIf->Name, p_VirtIf->IP.Ipv6Data.address, p_VirtIf->IP.Ipv6Data.prefixVltime, p_VirtIf->IP.Ipv6Data.prefixPltime)); } else { - CcspTraceError(("%s-%d: Failed to update addr from Interface %s, prefixAddr=%s, vallft=%d, preflft=%d \n", - __FUNCTION__, __LINE__, IfaceName, prefixAddr, vallft, preflft)); + CcspTraceError(("%s-%d: Failed to update addr from Interface %s, Ipv6 Addr=%s, vallft=%d, preflft=%d \n", + __FUNCTION__, __LINE__, p_VirtIf->Name, p_VirtIf->IP.Ipv6Data.address, p_VirtIf->IP.Ipv6Data.prefixVltime, p_VirtIf->IP.Ipv6Data.prefixPltime)); } break; } } - return 0; } diff --git a/source/WanManager/wanmgr_net_utils.h b/source/WanManager/wanmgr_net_utils.h index 69e42d12..ce0439c3 100644 --- a/source/WanManager/wanmgr_net_utils.h +++ b/source/WanManager/wanmgr_net_utils.h @@ -37,8 +37,6 @@ #define PTM_IFC_STR "ptm" #define PHY_WAN_IF_NAME "erouter0" #define ETH_BRIDGE_NAME "brlan0" -#define LAN_BRIDGE_NAME "brlan0" -// #define WAN_STATUS_UP "up" #define WAN_STATUS_DOWN "down" @@ -160,13 +158,11 @@ BOOL WanManager_IsApplicationRunning(const char *appName, const char * args); /*************************************************************************** * @brief Utility function used to perform operation on IPV6 addresses * for a particular interface - * @param ifname string indicates interface name + * @param p_VirtIf Pointer to the virtual interface * @param opr indicates operation type (Delete/Set) - * @param preflft indicates preferred lifetime - * @param vallft indicates valid lifetime * @return 0 upon success else -1 returned ***************************************************************************/ -int WanManager_Ipv6PrefixUtil(char *ifname,Ipv6OperType opr,int preflft,int vallft); +int WanManager_Ipv6AddrUtil(DML_VIRTUAL_IFACE* p_VirtIf,Ipv6OperType opr); /*************************************************************************** * @brief Utility function used to check a process is running using PID diff --git a/source/WanManager/wanmgr_sysevents.c b/source/WanManager/wanmgr_sysevents.c index 0443bcf7..1f291dbf 100644 --- a/source/WanManager/wanmgr_sysevents.c +++ b/source/WanManager/wanmgr_sysevents.c @@ -67,6 +67,7 @@ extern int WanMgr_TriggerPrimaryDnsConnectivityRestart(void); #endif #endif + static int isDefaultGatewayAdded = 0; //global varibale for default route status. static int lan_wan_started = 0; static int ipv4_connection_up = 0; @@ -77,10 +78,6 @@ static int set_default_conf_entry(); int mapt_feature_enable_changed = FALSE; #endif -#if defined(FEATURE_IPOE_HEALTH_CHECK) && defined(IPOE_HEALTH_CHECK_LAN_SYNC_SUPPORT) -lanState_t lanState = LAN_STATE_RESET; -#endif - #if defined(_DT_WAN_Manager_Enable_) bool needDibblerRestart = TRUE; #endif @@ -620,9 +617,10 @@ static void *WanManagerSyseventHandler(void *args) async_id_t primary_v6ipaddress_asyncid; #endif #endif - sysevent_set_options(sysevent_msg_fd, sysevent_msg_token, SYSEVENT_IPV6_TOGGLE, TUPLE_FLAG_EVENT); sysevent_setnotification(sysevent_msg_fd, sysevent_msg_token, SYSEVENT_IPV6_TOGGLE, &default_route_change_event_asyncid); + + #if defined (_HUB4_PRODUCT_REQ_) || defined(_RDKB_GLOBAL_PRODUCT_REQ_) sysevent_set_options(sysevent_msg_fd, sysevent_msg_token, SYSEVENT_ULA_ADDRESS, TUPLE_FLAG_EVENT); sysevent_setnotification(sysevent_msg_fd, sysevent_msg_token, SYSEVENT_ULA_ADDRESS, &lan_ula_address_event_asyncid); @@ -1207,7 +1205,6 @@ int Force_IPv6_toggle (char* wanInterface) } isDefaultGatewayAdded = 1; //Reset isDefaultGatewayAdded flag; - return ret; } diff --git a/source/WanManager/wanmgr_sysevents.h b/source/WanManager/wanmgr_sysevents.h index 84a9f62d..cd8edc82 100644 --- a/source/WanManager/wanmgr_sysevents.h +++ b/source/WanManager/wanmgr_sysevents.h @@ -205,18 +205,6 @@ #define WANMNGR_INTERFACE_DEFAULT_MTU_SIZE (1500) -/* IPOE_HEALTH_CHECK_LAN_SYNC_SUPPORT - stops and starts IPOE HEALTH CHECK Service based on lan events(SYSEVENT_LAN_STATUS). - * SKY IPoE Health check depends on the global ipv6 address configured on brlan0 and during the lan stop event brlan0 interface - * is made down affecting the IPoE service. - * */ -#if defined(FEATURE_IPOE_HEALTH_CHECK) && defined(IPOE_HEALTH_CHECK_LAN_SYNC_SUPPORT) -typedef enum{ - LAN_STATE_RESET = 0, - LAN_STATE_STOPPED, - LAN_STATE_STARTED, -}lanState_t; -#endif - //Bridge Mode #if defined(WAN_MANAGER_UNIFICATION_ENABLED) #define SYSEVENT_BRIDGE_MODE "bridge_mode"