@@ -659,8 +659,66 @@ TaskHandle_t FreeRTOS_GetIPTaskHandle( void )
659659 */
660660void vIPNetworkUpCalls ( struct xNetworkEndPoint * pxEndPoint )
661661{
662+ #if ( ipconfigSUPPORT_IP_MULTICAST != 0 )
663+ MCastReportData_t * pxMRD ;
664+ IPv6_Type_t xAddressType ;
665+ MACAddress_t xMACAddress ;
666+ #endif /* ( ipconfigSUPPORT_IP_MULTICAST != 0 ) */
667+
662668 pxEndPoint -> bits .bEndPointUp = pdTRUE_UNSIGNED ;
663669
670+ #if ( ipconfigSUPPORT_IP_MULTICAST != 0 )
671+ if ( pxEndPoint -> bits .bIPv6 == pdTRUE_UNSIGNED )
672+ {
673+ /* Now that the network is up, pxEndPoint->ipv6_settings should hold the actual address of this
674+ * end-point. For unicast addresses, generate the solicited-node multicast address that corresponds
675+ * to the address and generate an MLD report for it.
676+ * ToDo: Figure out what the proper place is to remove multicast addresses that are no longer valid. For
677+ * example when a DHCPv6 lease expires. */
678+ xAddressType = xIPv6_GetIPType ( & ( pxEndPoint -> ipv6_settings .xIPAddress ) );
679+
680+ if ( ( xAddressType == eIPv6_LinkLocal ) || ( xAddressType == eIPv6_SiteLocal ) || ( xAddressType == eIPv6_Global ) )
681+ {
682+ if ( NULL != ( pxMRD = ( MCastReportData_t * ) pvPortMalloc ( sizeof ( MCastReportData_t ) ) ) )
683+ {
684+ listSET_LIST_ITEM_OWNER ( & ( pxMRD -> xListItem ), ( void * ) pxMRD );
685+ pxMRD -> pxEndPoint = pxEndPoint ;
686+ pxMRD -> xMCastGroupAddress .xIs_IPv6 = pdTRUE_UNSIGNED ;
687+
688+ /* Generate the solicited-node multicast address in the form of
689+ * ff02::1:ffnn:nnnn, where nn:nnnn are the last 3 bytes of the IPv6 address. */
690+ pxMRD -> xMCastGroupAddress .xIPAddress .xIP_IPv6 .ucBytes [ 0 ] = 0xFFU ;
691+ pxMRD -> xMCastGroupAddress .xIPAddress .xIP_IPv6 .ucBytes [ 1 ] = 0x02U ;
692+ ( void ) memset ( & pxMRD -> xMCastGroupAddress .xIPAddress .xIP_IPv6 .ucBytes [ 2 ], 0x00 , 9 );
693+ pxMRD -> xMCastGroupAddress .xIPAddress .xIP_IPv6 .ucBytes [ 11 ] = 0x01U ;
694+ pxMRD -> xMCastGroupAddress .xIPAddress .xIP_IPv6 .ucBytes [ 12 ] = 0xFFU ;
695+ ( void ) memcpy ( & pxMRD -> xMCastGroupAddress .xIPAddress .xIP_IPv6 .ucBytes [ 13 ], & pxEndPoint -> ipv6_settings .xIPAddress .ucBytes [ 13 ], 3 );
696+
697+ if ( pdTRUE != xAddIGMPReportToList ( pxMRD ) )
698+ {
699+ vPortFree ( pxMRD );
700+ pxMRD = NULL ;
701+ }
702+ else
703+ {
704+ /* The report was consumed, therfore it was added to the list. Tell the network
705+ * driver to begin receiving the associated MAC address */
706+ if ( pxEndPoint -> pxNetworkInterface && ( pxEndPoint -> pxNetworkInterface -> pfAddMulticastMAC != NULL ) )
707+ {
708+ xMACAddress .ucBytes [ 0 ] = 0x33 ;
709+ xMACAddress .ucBytes [ 1 ] = 0x33 ;
710+ xMACAddress .ucBytes [ 2 ] = 0xFF ;
711+ xMACAddress .ucBytes [ 3 ] = pxEndPoint -> ipv6_settings .xIPAddress .ucBytes [ 13 ];
712+ xMACAddress .ucBytes [ 4 ] = pxEndPoint -> ipv6_settings .xIPAddress .ucBytes [ 14 ];
713+ xMACAddress .ucBytes [ 5 ] = pxEndPoint -> ipv6_settings .xIPAddress .ucBytes [ 15 ];
714+ pxEndPoint -> pxNetworkInterface -> pfAddMulticastMAC ( xMACAddress .ucBytes );
715+ }
716+ }
717+ }
718+ }
719+ }
720+ #endif /* ( ipconfigSUPPORT_IP_MULTICAST != 0 ) */
721+
664722 #if ( ipconfigUSE_NETWORK_EVENT_HOOK == 1 )
665723 #if ( ipconfigIPv4_BACKWARD_COMPATIBLE == 1 )
666724 {
0 commit comments