RDKB-58910 : Move the WAN IPV6 configuration from LAN bridge#79
RDKB-58910 : Move the WAN IPV6 configuration from LAN bridge#79S-Parthiban-Selvaraj wants to merge 87 commits intomainfrom
Conversation
Reason for change: Solving Build errors
Test Procedure:
Updated in Jira.
Risks: none
Priority: P1
Signed-off-by: parthiban.selvaraj <[email protected]>
Signed-off-by: parthiban.selvaraj <[email protected]>
Signed-off-by: parthiban.selvaraj <[email protected]>
Signed-off-by: Parthiban Selvaraj <[email protected]>
Signed-off-by: Parthiban Selvaraj <[email protected]>
Signed-off-by: S-Parthiban-Selvaraj <[email protected]>
Signed-off-by: S-Parthiban-Selvaraj <[email protected]>
Signed-off-by: S-Parthiban-Selvaraj <[email protected]>
Signed-off-by: S-Parthiban-Selvaraj <[email protected]>
Signed-off-by: Parthiban Selvaraj <[email protected]>
Signed-off-by: S-Parthiban-Selvaraj <[email protected]>
Signed-off-by: Parthiban Selvaraj <[email protected]>
Signed-off-by: S-Parthiban-Selvaraj <[email protected]>
Signed-off-by: S-Parthiban-Selvaraj <[email protected]>
Signed-off-by: S-Parthiban-Selvaraj <[email protected]>
Signed-off-by: Parthiban Selvaraj <[email protected]>
Signed-off-by: S-Parthiban-Selvaraj <[email protected]>
…eint after WFO Signed-off-by: Parthiban Selvaraj <[email protected]>
Signed-off-by: Parthiban Selvaraj <[email protected]>
Fixing Virtual interface name set. Signed-off-by: S-Parthiban-Selvaraj <[email protected]>
Signed-off-by: Parthiban Selvaraj <[email protected]>
Signed-off-by: Parthiban Selvaraj <[email protected]>
…ive VISM for products use the same default name for all interfaces Signed-off-by: Parthiban Selvaraj <[email protected]>
Signed-off-by: S-Parthiban-Selvaraj <[email protected]>
Signed-off-by: S-Parthiban-Selvaraj <[email protected]>
Co-authored-by: Copilot <[email protected]>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 12 changed files in this pull request and generated 3 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| * 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. | ||
| */ |
There was a problem hiding this comment.
Corrected spelling of 'Canculate' to 'Calculate'.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 12 changed files in this pull request and generated 12 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| 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); |
There was a problem hiding this comment.
In DEL_ADDR, ip -6 route flush match is run with the interface IPv6 host address (...match <addr>). That will only flush routes whose destination matches that /128, and will not remove routes for the delegated prefix (e.g., the ip -6 route add <sitePrefix> dev brlan0 route added during PD handling). Please flush based on the delegated prefix (or remove the specific prefix route you added) rather than matching the /128 address.
| snprintf(cmdLine, sizeof(cmdLine), "ip -6 route flush match %s ", p_VirtIf->IP.Ipv6Data.address); | |
| snprintf(cmdLine, sizeof(cmdLine), "ip -6 route flush dev %s", p_VirtIf->Name); |
| @@ -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)); | |||
There was a problem hiding this comment.
WanMgr_SendMsgToIHC now dereferences p_VirtIf unconditionally and no longer validates that the IPv4/IPv6 address fields are populated before sending (the previous implementation rejected empty/"(null)" values). Please add a null check for p_VirtIf and validate p_VirtIf->IP.Ipv4Data.ip / p_VirtIf->IP.Ipv6Data.address for the relevant message types to avoid sending empty addresses (or crashing if p_VirtIf is unexpectedly null).
| /** | ||
| * @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. | ||
| */ |
There was a problem hiding this comment.
The new docstring for setUpLanPrefixIPv6 says it "Sets up the IPv6 /128 address for the LAN bridge" and that it "creates" the address, but the implementation no longer assigns an IPv6 address to brlan0 (it only sets sysevents and adds a route). Please update the comment to match the actual behavior (or restore the missing address assignment if it is still required).
| { | ||
| 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); |
There was a problem hiding this comment.
wanmgr_construct_wan_address_from_IAPD calls WanMgr_create_eui64_ipv6_address, but that helper is only compiled when FEATURE_RDKB_CONFIGURABLE_WAN_INTERFACE is defined (it is static inside that #if). Since wanmgr_construct_wan_address_from_IAPD is compiled unconditionally, builds that don't define FEATURE_RDKB_CONFIGURABLE_WAN_INTERFACE will fail (undefined symbol / implicit declaration). Please either move wanmgr_construct_wan_address_from_IAPD under the same feature guard, or provide a non-conditional implementation/declaration for the EUI-64 helper (or a fallback path).
| { | |
| 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); | |
| { | |
| #ifdef FEATURE_RDKB_CONFIGURABLE_WAN_INTERFACE | |
| 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 enabled in configuration but FEATURE_RDKB_CONFIGURABLE_WAN_INTERFACE is not defined; using WAN SUFFIX %d instead \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)); | |
| #endif |
| 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: <<DEBUG>> 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); | ||
|
|
There was a problem hiding this comment.
cmdLine is only 128 bytes, but the new commands include an IPv6 literal (up to ~45 chars) plus an interface name up to BUFLEN_64 (DML_VIRTUAL_IFACE.Name), which can exceed 128 and get truncated by snprintf, causing the system action to fail. Please increase the buffer (e.g., BUFLEN_256) or compute the required length to ensure the full command is preserved.
| 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; |
There was a problem hiding this comment.
wanmgr_construct_wan_address_from_IAPD sets addrAssigned=true and returns 0 regardless of whether address generation or ip -6 addr add actually succeeded (return value from WanMgr_create_eui64_ipv6_address is ignored; WanManager_DoSystemActionWithStatus failure is only logged). This can leave WanManager believing an IPv6 address exists when it does not. Please check these return codes and propagate failure (return -1 and avoid updating addrAssigned / sysevents on failure).
| // Convert prefix to binary format | ||
| if (inet_pton(AF_INET6, iapd_prefix, &prefix) != 1) | ||
| { | ||
| fprintf(stderr, "Invalid IPv6 prefix\n"); |
There was a problem hiding this comment.
wanmgr_construct_wan_address_from_IAPD writes directly to stderr (fprintf(stderr, ...)) on parse failure. This bypasses the component logging used elsewhere and may not be captured in production logs. Please use the existing CcspTraceError logging (and include the offending prefix) instead of writing to stderr.
| fprintf(stderr, "Invalid IPv6 prefix\n"); | |
| CcspTraceError(("%s %d Invalid IPv6 prefix: %s\n", __FUNCTION__, __LINE__, iapd_prefix)); |
| 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. 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(pDhcpv6Data); | ||
| } | ||
|
|
There was a problem hiding this comment.
copyDhcpv6Data is a copy/helper routine but now has side effects (it may call wanmgr_construct_wan_address_from_IAPD, which runs ip -6 addr add and sets sysevents). Since DHCPv6 lease updates can arrive multiple times, this risks repeatedly trying to add the same /128 address (and doing potentially slow system calls while holding DhcpClientEvents_mutex). Please keep copyDhcpv6Data pure and move the WAN-address construction to the event-handling logic with proper idempotency (e.g., use ip -6 addr replace or check if the address is already present before adding).
| 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. 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(pDhcpv6Data); | |
| } |
| sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIREWALL_RESTART, NULL, 0); | ||
|
|
||
| //RBUS_WAN_IP | ||
| //TODO : **************************** Check this ************************ |
There was a problem hiding this comment.
This placeholder TODO (//TODO : **************************** Check this ************************) is not actionable and will be hard to triage later. Please either remove it or replace it with a specific TODO that states what needs to be verified and under what conditions (ideally with a ticket reference).
| //TODO : **************************** Check this ************************ | |
| // TODO: Verify that the RBUS_WAN_IP IPv6 sysevent keys cleared below are correct for all product variants when WAN IPv6 goes down. |
| 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. 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(pDhcpv6Data); | ||
| } |
There was a problem hiding this comment.
wanmgr_dhcp_event_handler.c calls wanmgr_construct_wan_address_from_IAPD() but does not include the header that declares it (wanmgr_dhcpv6_apis.h). This will rely on an implicit declaration in some toolchains (or fail to compile under C99/C11 with -Werror=implicit-function-declaration). Please include the proper header or add a forward declaration.
Co-authored-by: Copilot <[email protected]>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 12 changed files in this pull request and generated 10 comments.
Comments suppressed due to low confidence (1)
source/WanManager/wanmgr_ipc.c:438
WanMgr_SendMsgToIHCnow dereferencesp_VirtIfwithout validating it. Add a NULL check at the start of the function and fail early to avoid a crash if a caller passes NULL.
ANSC_STATUS WanMgr_SendMsgToIHC (ipoe_msg_type_t msgType, DML_VIRTUAL_IFACE *p_VirtIf )
{
int sock = -1;
int conn = -1;
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| * @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. |
There was a problem hiding this comment.
The docstring says this function “sets up the IPv6 /128 address for the LAN bridge” and “creates an IPv6 /128 address”, but the current implementation no longer assigns an address on brlan0 (it only derives an address and sets sysevents). Update the comment to reflect the actual behavior (or restore the address assignment if it’s still required here).
| * @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. | |
| * @brief Sets up IPv6-related configuration for the LAN bridge. | |
| * This function derives the LAN IPv6 prefix from the delegated prefix, | |
| * configures the relevant system events and IPv6 settings needed for | |
| * LAN IPv6 operation, and allows other components (such as the DHCPv6 | |
| * and RA servers) to react to those changes as needed. |
| sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIREWALL_RESTART, NULL, 0); | ||
|
|
||
| //RBUS_WAN_IP | ||
| //TODO : **************************** Check this ************************ |
There was a problem hiding this comment.
The added //TODO : **************************** Check this ************************ is a placeholder and doesn’t describe an actionable task. Please replace it with a specific TODO (what/why) and ideally a ticket reference, or remove it if not needed.
| //TODO : **************************** Check this ************************ |
| if (WanManager_DoSystemActionWithStatus(__FUNCTION__, cmdLine) != 0) | ||
| CcspTraceError(("failed to run cmd: %s", cmdLine)); |
There was a problem hiding this comment.
If ip -6 addr add ... fails, the function still continues and returns success. Propagate the failure (return -1) so callers don’t treat IPv6 as configured when it isn’t.
| if (WanManager_DoSystemActionWithStatus(__FUNCTION__, cmdLine) != 0) | |
| CcspTraceError(("failed to run cmd: %s", cmdLine)); | |
| int rc = WanManager_DoSystemActionWithStatus(__FUNCTION__, cmdLine); | |
| if (rc != 0) | |
| { | |
| CcspTraceError(("failed to run cmd: %s", cmdLine)); | |
| return -1; | |
| } |
| snprintf(cmdLine, sizeof(cmdLine), "ip -6 route flush match %s ", p_VirtIf->IP.Ipv6Data.address); | ||
|
|
||
| if (WanManager_DoSystemActionWithStatus(cmdLine, cmdLine) != 0) |
There was a problem hiding this comment.
ip -6 route flush match expects a prefix/CIDR. Flushing with p_VirtIf->IP.Ipv6Data.address (without /128) is likely a no-op/error and won’t remove routes for the delegated prefix. Use an appropriate CIDR (e.g., the delegated prefix in sitePrefix or %s/128 for the host route) and keep the first argument to WanManager_DoSystemActionWithStatus as a stable log tag rather than the full command string.
| snprintf(cmdLine, sizeof(cmdLine), "ip -6 route flush match %s ", p_VirtIf->IP.Ipv6Data.address); | |
| if (WanManager_DoSystemActionWithStatus(cmdLine, cmdLine) != 0) | |
| snprintf(cmdLine, sizeof(cmdLine), "ip -6 route flush match %s/128", p_VirtIf->IP.Ipv6Data.address); | |
| if (WanManager_DoSystemActionWithStatus("ip -6 route flush match ADDR/128", cmdLine) != 0) |
| 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); |
There was a problem hiding this comment.
Before sending IPOE_MSG_WAN_CONNECTION_IPV6_UP, validate that p_VirtIf->IP.Ipv6Data.address is non-empty (and ideally a valid IPv6 string). Otherwise IHC can receive an “UP” message with an empty/invalid IPv6 address.
| return 0; | ||
| } |
There was a problem hiding this comment.
This helper is documented as returning -1 on failure, but it always returns 0 even when a system command fails. Propagate the command failure status (and return -1) so callers can react appropriately.
| wanmgr_construct_wan_address_from_IAPD(&Ipv6DataNew); | ||
| pNewIpcMsg->addrAssigned = true; |
There was a problem hiding this comment.
wanmgr_construct_wan_address_from_IAPD(&Ipv6DataNew) return value is ignored, but pNewIpcMsg->addrAssigned is forced true. If construction/assignment fails, IPv6 will be treated as up with no usable address. Gate addrAssigned updates on successful construction and handle the failure path.
| wanmgr_construct_wan_address_from_IAPD(&Ipv6DataNew); | |
| pNewIpcMsg->addrAssigned = true; | |
| /* Construct WAN IPv6 address from the delegated prefix only if possible. */ | |
| if (wanmgr_construct_wan_address_from_IAPD(&Ipv6DataNew) == 0) | |
| { | |
| Ipv6DataNew.addrAssigned = true; | |
| pNewIpcMsg->addrAssigned = true; | |
| } | |
| else | |
| { | |
| CcspTraceError(("%s %d Failed to construct WAN IPv6 address from IAPD. IPv6 address will not be marked as assigned.\n", | |
| __FUNCTION__, __LINE__)); | |
| } |
| 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); | ||
|
|
There was a problem hiding this comment.
Before sending IPOE_MSG_WAN_CONNECTION_UP, validate that p_VirtIf->IP.Ipv4Data.ip is non-empty (and ideally a valid IPv4 string). Otherwise IHC can receive an “UP” message with an empty/invalid IPv4 address.
| { | ||
| 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); |
There was a problem hiding this comment.
ip -6 addr change generally requires an address with prefix length (e.g., .../128). p_VirtIf->IP.Ipv6Data.address is stored without a prefix length, so this command will fail and lifetimes won’t be updated. Append the correct prefix length (likely /128) when building the command.
| 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); | |
| snprintf(cmdLine, sizeof(cmdLine), "ip -6 addr change %s/128 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); |
|
|
||
| prefix.s6_addr[7] += 0x01; // Use next subnet for WAN. First /64 will be used for LAN. | ||
|
|
There was a problem hiding this comment.
Incrementing prefix.s6_addr[7] to pick the “next /64” only works for some prefix lengths (e.g., /56). For prefixes like /57, /60, /48 this can alter provider-assigned prefix bits and generate an address outside the delegated range. Compute the next /64 by incrementing the subnet-id bits between prefix_length and 64 (bitwise), rather than hardcoding byte 7.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 12 changed files in this pull request and generated 5 comments.
Comments suppressed due to low confidence (1)
source/WanManager/wanmgr_dhcpv6_apis.c:2122
setUpLanPrefixIPv6()no longer configures the computed global IPv6 address onbrlan0(the previousip -6 addr add ... dev brlan0call is gone), but it still adds a route viabrlan0and restarts LAN RA/DHCPv6 services. If no other component is responsible for assigninglan_ipaddr_v6ontobrlan0, LAN IPv6 will be broken. Please either restore theip -6 addr addon the LAN bridge (with lifetimes), or clearly ensure/trigger the component that applieslan_ipaddr_v6to the interface before restarting services.
//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
{
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);
if (WanManager_DoSystemActionWithStatus(__FUNCTION__, cmdLine) != 0)
{
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| sysevent_set(sysevent_fd, sysevent_token, SYSEVENT_FIREWALL_RESTART, NULL, 0); | ||
|
|
||
| //RBUS_WAN_IP | ||
| //TODO : **************************** Check this ************************ |
There was a problem hiding this comment.
This TODO is non-actionable (“Check this” with asterisks) and doesn’t provide enough context for future maintainers. Please replace it with a specific description of what needs verification (and ideally a tracking ID/link), or remove it if it’s no longer needed.
| //TODO : **************************** Check this ************************ |
| * 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 |
There was a problem hiding this comment.
Typo in comment: “managerment” should be “management”.
| * 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 | |
| * We can use the received IAPD to construct a Ipv6 /128 address which can be used for management and voice ... | |
| * If we reach this point, only IAPD has been received. Calculate Wan Ipv6 address |
| 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)); | ||
|
|
There was a problem hiding this comment.
wanmgr_construct_wan_address_from_IAPD() marks addrAssigned=true and returns success even if address generation or ip -6 addr add ... fails. This can leave the state machine believing IPv6 is up while the interface has no usable address. Please check return codes from WanMgr_create_eui64_ipv6_address() and WanManager_DoSystemActionWithStatus() and propagate failures (and avoid setting addrAssigned/addrCmd on failure).
| #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)); | ||
| } |
There was a problem hiding this comment.
wanmgr_construct_wan_address_from_IAPD() is declared unconditionally in the header, but its implementation depends on FEATURE_RDKB_CONFIGURABLE_WAN_INTERFACE (it writes addrAssigned/addrCmd fields that are feature-gated in WANMGR_IPV6_DATA, and it calls WanMgr_create_eui64_ipv6_address() which is only compiled under that same feature). This will break builds where the feature macro is off. Please either wrap the prototype+implementation in the same #if defined(FEATURE_RDKB_CONFIGURABLE_WAN_INTERFACE) guard, or make the needed struct fields / helper available unconditionally.
| 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 ... |
There was a problem hiding this comment.
Typo in comment: “managerment” should be “management”.
| * We can use the received IAPD to construct a Ipv6 /128 address which can be used for managerment and voice ... | |
| * We can use the received IAPD to construct a Ipv6 /128 address which can be used for management and voice ... |
…_CONFIGURABLE_WAN_INTERFACE - Remove FEATURE_RDKB_CONFIGURABLE_WAN_INTERFACE guard from addrAssigned, addrCmd, prefixAssigned, prefixCmd, and domainNameAssigned fields in WANMGR_IPV6_DATA struct so they are available on all platforms - Add missing CcspTraceInfo log before sysevent_set in wanmgr_construct_wan_address_from_IAPD
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 13 changed files in this pull request and generated 7 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| char cmd[128]; | ||
| snprintf(cmd, sizeof(cmd), "ip -6 ro show default dev %s", p_VirtIf->Name); | ||
| if ((fp_route = popen(cmd, "r"))) { | ||
| if(fp_route != NULL) { | ||
| fgets(buffer, BUFLEN_256, fp_route); | ||
| if(strlen(buffer) > 0 ) { | ||
| route_flag = 1; | ||
| } | ||
| pclose(fp_route); | ||
| } |
There was a problem hiding this comment.
The default-route check uses popen() with a shell command string, while the rest of this function uses v_secure_popen()/v_secure_pclose(). For consistency with the secure-wrapper usage in this codebase and to avoid shell-invocation risks, use v_secure_popen() here as well (and close with v_secure_pclose()).
| 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)); | ||
| } | ||
|
|
There was a problem hiding this comment.
wanmgr_construct_wan_address_from_IAPD() chooses the “next /64” by incrementing prefix.s6_addr[7] and then (when EUI-64 is enabled) calls WanMgr_create_eui64_ipv6_address() with the original delegated prefix length. This does not reliably produce a valid address on the intended /64 subnet for prefixes that are not already /64. Compute a proper /64 prefix for the selected WAN subnet and pass /64 into the EUI-64 generator (or construct the full /128 address directly from the /64).
| 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)); | |
| } | |
| { | |
| struct in6_addr wan_prefix = prefix; | |
| int bit_index = 0; | |
| /* Normalize the delegated prefix by clearing all bits after prefix_length. */ | |
| for (bit_index = prefix_length; bit_index < 128; bit_index++) | |
| { | |
| wan_prefix.s6_addr[bit_index / 8] &= ~(0x80 >> (bit_index % 8)); | |
| } | |
| /* | |
| * Select the WAN /64 subnet while keeping the first /64 available for LAN. | |
| * For prefixes shorter than /64, set the first subnet-id bit after the | |
| * delegated prefix. For /64 or longer prefixes, keep the normalized prefix. | |
| */ | |
| if (prefix_length < 64) | |
| { | |
| wan_prefix.s6_addr[prefix_length / 8] |= (0x80 >> (prefix_length % 8)); | |
| } | |
| /* Convert the selected subnet into a clean /64 prefix. */ | |
| for (bit_index = 64; bit_index < 128; bit_index++) | |
| { | |
| wan_prefix.s6_addr[bit_index / 8] &= ~(0x80 >> (bit_index % 8)); | |
| } | |
| 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, &wan_prefix, newPref, sizeof(newPref)); | |
| CcspTraceInfo(("%s %d EUI64 format is enabled using new prefix %s/64 \n", __FUNCTION__, __LINE__, newPref)); | |
| snprintf(cmdLine, sizeof(cmdLine), "%s/64", newPref); | |
| 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)); | |
| wan_prefix.s6_addr[15] = WAN_SUFFIX; // Setting the last byte for WAN address | |
| inet_ntop(AF_INET6, &wan_prefix, pIpv6DataNew->address, sizeof(pIpv6DataNew->address)); | |
| } | |
| } | |
| 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)); |
There was a problem hiding this comment.
SYSCFG_FIELD_IPV6_PREFIX_ADDRESS is set here to a WAN /128 address (<wan-address>/128). In the non-FEATURE_RDKB_CONFIGURABLE_WAN_INTERFACE path this syscfg key is used to store the delegated-prefix-derived LAN /64 address (pdIfAddress). Reusing the same syscfg key for different semantics across build flags is brittle and can break scripts that assume it always contains a “prefix address”. Consider introducing a dedicated syscfg key for the WAN /128 address or keep this key storing the LAN prefix address consistently.
| @@ -462,25 +462,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)) ) | |||
There was a problem hiding this comment.
WanMgr_SendMsgToIHC() no longer validates its inputs. If p_VirtIf is NULL (or if the IPv4/IPv6 address fields are empty) this will either segfault or send an UP message with an empty address, which may break the health-check consumer. Add a NULL check and validate required address fields for the *_UP message types before sending.
| 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__)); |
There was a problem hiding this comment.
WanManager_Ipv6AddrUtil() deletes the IPv6 default route using ip -6 route delete default without scoping it to the interface. This can remove the active default route for a different WAN interface during failover/dual-WAN scenarios. Delete the default route for this specific interface (e.g., ... del default dev <if>), or rely on WanMgr_RemoveIPv6RouteAndAddress() which already does an interface-scoped deletion.
| 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__)); | |
| snprintf(cmdLine, sizeof(cmdLine), "ip -6 route delete default dev %s", p_VirtIf->Name); | |
| if (WanManager_DoSystemActionWithStatus("ip -6 route delete default dev xxxx", cmdLine) != 0) | |
| CcspTraceError(("failed to run cmd: %s", cmdLine)); | |
| CcspTraceInfo(("%s-%d: Successfully deleted ipv6 default route for interface %s\n", __FUNCTION__, __LINE__, p_VirtIf->Name)); |
| wanmgr_construct_wan_address_from_IAPD(&Ipv6DataNew); | ||
| pNewIpcMsg->addrAssigned = true; |
There was a problem hiding this comment.
wanmgr_handle_dhcpv6_event_data() sets pNewIpcMsg->addrAssigned = true unconditionally after calling wanmgr_construct_wan_address_from_IAPD(). If address construction fails, the rest of the pipeline will believe an IPv6 address is present and may skip SLAAC detection / other recovery paths. Use the function's return value and only set addrAssigned on success (and consider copying the generated address back into the IPC struct if downstream code expects it).
| wanmgr_construct_wan_address_from_IAPD(&Ipv6DataNew); | |
| pNewIpcMsg->addrAssigned = true; | |
| if (wanmgr_construct_wan_address_from_IAPD(&Ipv6DataNew)) | |
| { | |
| strncpy(pNewIpcMsg->address, Ipv6DataNew.address, sizeof(pNewIpcMsg->address)); | |
| pNewIpcMsg->addrAssigned = true; | |
| } | |
| else | |
| { | |
| CcspTraceWarning(("%s %d Failed to construct WAN IPv6 address from IAPD. Keeping addrAssigned unset.\n", __FUNCTION__, __LINE__)); | |
| } |
| 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)); | ||
|
|
There was a problem hiding this comment.
WanManager_Ipv6AddrUtil() flushes routes with ip -6 route flush match <IPv6-address>. Flushing by host address is unlikely to remove routes installed for the delegated prefix/site prefix and may leave stale routes behind. Consider flushing based on the relevant prefix (e.g., sitePrefix) or flushing routes dev <if> as appropriate for your routing model.
…4. WAN address now comes from the same /64 as LAN. 2. Changed prefix_length >= 64 to prefix_length > 64 — Now accepts /64 delegations (previously rejected them). Only rejects prefixes longer than /64 where no /64 subnet can be derived. 3. Updated all comments and doxygen with RFC references: RFC 7084 Section 4.2 WAA-7 — CE router MUST create address from delegated prefix RFC 9096 Section 3.3 & 3.5 — Addresses should track prefix lifetimes; using same /64 aligns with renumbering expectations RFC 4862 Section 5.4 — DAD is mandatory, provides collision safeguard Inline comments explain why EUI-64 is collision-free (different MACs) and why ::1 suffix is safe
- Enable NDP proxy on the LAN bridge to respond to Neighbor Solicitations for the WAN address. - Add NDP proxy entry for the WAN address to facilitate upstream routing and prevent DAD success for LAN clients. - Update function to remove NDP proxy entry when removing IPv6 routes and addresses. Co-authored-by: Copilot <[email protected]>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 13 out of 13 changed files in this pull request and generated 8 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| 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); |
There was a problem hiding this comment.
setUpLanPrefixIPv6() sets SYSCFG_FIELD_IPV6_PREFIX_ADDRESS to "%s/128" using pVirtIf->IP.Ipv6Data.address. That is the WAN IPv6 address, not the LAN/PD-derived prefix address implied by the surrounding "create global IPv6 address (::1)" comment. Please base this syscfg value on the delegated prefix/LAN bridge address (e.g., globalIP or prefix + "::1") instead.
| 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); | |
| strncpy(prefix, pVirtIf->IP.Ipv6Data.sitePrefix, index); // only copy prefix without the prefix length | |
| // Create and set IPv6 address with /128 prefix length from the delegated/LAN prefix //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}; | |
| size_t prefix_len = strlen(prefix); | |
| while (prefix_len > 0 && prefix[prefix_len - 1] == ':') | |
| { | |
| prefix[--prefix_len] = '\0'; | |
| } | |
| snprintf(ipv6_addr_with_prefix, sizeof(ipv6_addr_with_prefix), "%s::1/128", prefix); |
| /* 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; |
There was a problem hiding this comment.
wanmgr_construct_wan_address_from_IAPD() can return -1 on parse/validation failures, but this call ignores the return value and unconditionally sets pNewIpcMsg->addrAssigned = true. Please check the return status and only set addrAssigned/connected when the WAN address was successfully constructed and applied; otherwise keep addrAssigned false and log a clear error.
| /* 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; | |
| int ret = 0; | |
| /* 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")); | |
| ret = wanmgr_construct_wan_address_from_IAPD(&Ipv6DataNew); | |
| if (ret == 0) | |
| { | |
| Ipv6DataNew.addrAssigned = true; | |
| pNewIpcMsg->addrAssigned = true; | |
| } | |
| else | |
| { | |
| Ipv6DataNew.addrAssigned = false; | |
| pNewIpcMsg->addrAssigned = false; | |
| CcspTraceError(("%s %d Failed to construct WAN IPv6 address from IAPD. Leaving addrAssigned unset \n", __FUNCTION__, __LINE__)); | |
| } |
| pIpv6DataNew->addrAssigned = true; | ||
| pIpv6DataNew->addrCmd = IFADDRCONF_ADD; | ||
|
|
||
| CcspTraceInfo(("%s %d Calculated WAN address %s/128\n", __FUNCTION__, __LINE__, pIpv6DataNew->address)); | ||
| // Assign the /128 host 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)); | ||
|
|
There was a problem hiding this comment.
wanmgr_construct_wan_address_from_IAPD() marks addrAssigned=true and logs the calculated address before attempting "ip -6 addr add". If the system command fails, the function only logs an error and still returns 0. Please treat command failures as hard errors: return -1 and avoid leaving addrAssigned set when the address wasn’t actually configured.
| pIpv6DataNew->addrAssigned = true; | |
| pIpv6DataNew->addrCmd = IFADDRCONF_ADD; | |
| CcspTraceInfo(("%s %d Calculated WAN address %s/128\n", __FUNCTION__, __LINE__, pIpv6DataNew->address)); | |
| // Assign the /128 host 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)); | |
| CcspTraceInfo(("%s %d Calculated WAN address %s/128\n", __FUNCTION__, __LINE__, pIpv6DataNew->address)); | |
| // Assign the /128 host 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)); | |
| return -1; | |
| } | |
| pIpv6DataNew->addrAssigned = true; | |
| pIpv6DataNew->addrCmd = IFADDRCONF_ADD; |
| //RBUS_WAN_IP | ||
| //TODO : **************************** Check this ************************ |
There was a problem hiding this comment.
This TODO marker ("**************************** Check this ************************") is non-actionable and doesn’t describe what needs to be verified or why. Please either remove it or replace it with a specific TODO (what to check, expected behavior, and a ticket/reference).
| //RBUS_WAN_IP | |
| //TODO : **************************** Check this ************************ | |
| // RBUS_WAN_IP: reset the IPv6 address sysevent on the appropriate interface | |
| // based on product configuration. |
|
|
||
| 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); |
There was a problem hiding this comment.
_ansc_strncpy(ipAddr, globalIP, sizeof(globalIP) - 1) can overflow/pad past the actual ipAddr buffer (e.g., WANMGR_IPV6_DATA.address is BUFLEN_48). Please pass the destination size into WanMgr_create_eui64_ipv6_address() (or use snprintf) and bound the copy to that size; also avoid unbounded _ansc_strcpy(globalIP, prefix).
| _ansc_strncpy(ipAddr, globalIP, sizeof(globalIP) - 1); | |
| snprintf(ipAddr, BUFLEN_48, "%s", globalIP); |
| * @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" |
There was a problem hiding this comment.
wanmgr_construct_wan_address_from_IAPD() header comment says it uses the “next available /64 subnet” and reserves the first /64 for LAN, but the implementation derives the WAN /128 from the first /64 (same /64 as LAN). Please update this header comment to match the implementation (or vice versa) so integrators don’t rely on incorrect subnet selection.
| * @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" | |
| * @brief Constructs a 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 derives | |
| * a WAN IPv6 /128 address from the first available /64 within the delegated prefix and assigns the | |
| * constructed WAN address 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 requires a delegated prefix length of less than 64 so that a /64 can be derived | |
| * from the IAPD. If the prefix length is 64 or greater, it logs an error and returns -1. | |
| * | |
| * ### Example: | |
| * Given an IAPD of "2a06:5906:13:d000::/56", the function may construct the following addresses: | |
| * - First /64 derived from the IAPD: "2a06:5906:13:d000::/64" | |
| * - WAN IPv6 Address: "2a06:5906:13:d000::1/128" |
| * @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, |
There was a problem hiding this comment.
The setUpLanPrefixIPv6() header says it “sets up the IPv6 /128 address for the LAN bridge”, but the function derives/records the LAN bridge address as “%s/64” in pdIfAddress and sets lan_ipaddr_v6 to the un-suffixed address. Please update the comment to match the actual configuration (and clarify whether LAN bridge is intended to be /64 vs /128).
| * @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, | |
| * @brief Sets up the IPv6 /64 LAN bridge address derived from the delegated prefix. | |
| * This function creates and records the LAN bridge IPv6 address using a /64 prefix, | |
| * configures all necessary system events for the IPv6 LAN, |
| * 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. |
There was a problem hiding this comment.
The docstring says “If DAD fails, it also triggers a Router Solicitation”, but the current implementation only triggers RS when route_flag==0 (missing default route), not when dad_flag==0. Please update the comment (or adjust the logic) so documentation matches behavior.
| * 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. | |
| * This function checks the tentative address, detects Duplicate Address Detection (DAD) | |
| * failure, and verifies that a default route is present. | |
| * If the default route is missing, it triggers a Router Solicitation. |
This PR moves WAN IPv6 configuration from the LAN bridge to the WAN interface itself, addressing an issue where IANA is not assigned by the BNG (Broadband Network Gateway). The changes enable the creation of IPv6 addresses on WAN interfaces from delegated prefixes when IANA addresses are not provided.
Key changes:
Removed IPv6 configuration from LAN bridge and moved it to WAN interfaces
Added new function to construct WAN IPv6 addresses from IAPD (IA Prefix Delegation)
Updated IPv6 utility functions to work with virtual interfaces instead of interface names
Cleaned up LAN-specific IPv6 handling code and legacy bridge mode logic
This PR is dependent on the following related PRs:
rdkcentral/telco-voice-manager#5
rdkcentral/utopia#69
#79
rdkcentral/provisioning-and-management#127
rdkcentral/xconf-client#20
rdkcentral/test-and-diagnostic#172
https://github.com/rdk-gdcs/firewall/pull/5
rdkcentral/sysint-broadband#34