Skip to content

Commit 9ac727e

Browse files
author
Emil Popov
committed
changes the mreq structures definition to be more inline with the rest of the world.
a bunch of refactoring
1 parent 4e210f9 commit 9ac727e

File tree

7 files changed

+143
-87
lines changed

7 files changed

+143
-87
lines changed

source/FreeRTOS_IGMP.c

Lines changed: 79 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -88,19 +88,16 @@
8888
pxInterface->pfAddMulticastMAC( IGMP_MacAddress.ucBytes );
8989
}
9090

91-
IGMPReportDesc_t * pxIRD;
91+
MCastReportData_t * pxIRD;
9292
#if ( ipconfigUSE_LLMNR != 0 )
93-
if( NULL != ( pxIRD = ( IGMPReportDesc_t * ) pvPortMalloc( sizeof( IGMPReportDesc_t ) ) ) )
93+
if( NULL != ( pxIRD = ( MCastReportData_t * ) pvPortMalloc( sizeof( MCastReportData_t ) ) ) )
9494
{
9595
listSET_LIST_ITEM_OWNER( &( pxIRD->xListItem ), ( void * ) pxIRD );
9696
/* Quick and dirty assignment of end-point. This will probably have to be re-designed and re-done. */
97-
pxIRD->pxEndPoint = FreeRTOS_FirstEndPoint( FreeRTOS_FirstNetworkInterface() );
98-
pxIRD->mreq.imr_interface.sin_family = FREERTOS_AF_INET;
99-
pxIRD->mreq.imr_interface.sin_len = sizeof( struct freertos_sockaddr );
100-
pxIRD->mreq.imr_interface.sin_address.ulIP_IPv4 = FreeRTOS_htonl( 0x00000000U );
101-
pxIRD->mreq.imr_multiaddr.sin_family = FREERTOS_AF_INET;
102-
pxIRD->mreq.imr_multiaddr.sin_len = sizeof( struct freertos_sockaddr );
103-
pxIRD->mreq.imr_multiaddr.sin_address.ulIP_IPv4 = ipLLMNR_IP_ADDR;
97+
/* ToDo: make sure we also join the IPv6 multicast group */
98+
pxIRD->pxEndPoint = NULL;
99+
pxIRD->xMCastGroupAddress.xIs_IPv6 = pdFALSE_UNSIGNED;
100+
pxIRD->xMCastGroupAddress.xIPAddress.ulIP_IPv4 = ipLLMNR_IP_ADDR;
104101
BaseType_t bReportItemConsumed = xAddIGMPReportToList( pxIRD );
105102

106103
if( pdTRUE != bReportItemConsumed )
@@ -198,33 +195,33 @@
198195

199196
/* and schedule the reports. Note, the IGMP event is set at 100ms
200197
* which corresponds to the increment used in ucMaxRespTime.
201-
* pxIRD->ucCountDown holds a count in increments of the IGMP event time, so 12 = 1200ms = 1.2s */
198+
* pxMRD->ucCountDown holds a count in increments of the IGMP event time, so 12 = 1200ms = 1.2s */
202199
const ListItem_t * pxIterator;
203200
const ListItem_t * xEnd = listGET_END_MARKER( &xIGMP_ScheduleList );
204-
IGMPReportDesc_t * pxIRD;
201+
MCastReportData_t * pxMRD;
205202

206203
for( pxIterator = ( const ListItem_t * ) listGET_NEXT( xEnd );
207204
pxIterator != ( const ListItem_t * ) xEnd;
208205
pxIterator = ( const ListItem_t * ) listGET_NEXT( pxIterator ) )
209206
{
210-
pxIRD = ( IGMPReportDesc_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
207+
pxMRD = ( MCastReportData_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
211208

212209
/* Continue parsing if we are dealing with a general query, or if we are servicing a group-specific
213210
* query and this report matches the group-specific query's destination address*/
214-
if( ( uiGroupAddress == 0U ) || ( uiGroupAddress == pxIRD->mreq.imr_multiaddr.sin_address.ulIP_IPv4 ) )
211+
if( ( uiGroupAddress == 0U ) || ( uiGroupAddress == pxMRD->xMCastGroupAddress.xIPAddress.ulIP_IPv4 ) )
215212
{
216213
/* This report needs to be scheduled for sending. Remember that it may already be scheduled.
217-
* pxIRD->ucCountDown of zero means the report is not scheduled to be sent. If a report is scheduled, and it's
214+
* pxMRD->ucCountDown of zero means the report is not scheduled to be sent. If a report is scheduled, and it's
218215
* scheduled time is before ucMaxRespTime, there is nothing to be done. If a
219216
* report is scheduled past ucMaxRespTime, or not scheduled at all, we need
220217
* to schedule it for a random time between 0 and ucMaxRespTime. */
221-
if( ( pxIRD->ucCountDown == 0 ) || ( pxIRD->ucCountDown >= ucMaxRespTime ) )
218+
if( ( pxMRD->ucCountDown == 0 ) || ( pxMRD->ucCountDown >= ucMaxRespTime ) )
222219
{
223220
uint32_t uiRandom;
224221

225222
if( xApplicationGetRandomNumber( &( uiRandom ) ) == pdFALSE )
226223
{
227-
pxIRD->ucCountDown = uiNonRandomCounter++;
224+
pxMRD->ucCountDown = uiNonRandomCounter++;
228225

229226
if( uiNonRandomCounter > ucMaxRespTime )
230227
{
@@ -245,7 +242,7 @@
245242
uiRandom -= ucMaxRespTime;
246243
}
247244

248-
pxIRD->ucCountDown = ( uint8_t ) uiRandom;
245+
pxMRD->ucCountDown = ( uint8_t ) uiRandom;
249246
}
250247
}
251248
}
@@ -261,30 +258,67 @@
261258
/* Go through the list of IGMP reports and send anything that needs to be sent. */
262259
const ListItem_t * pxIterator;
263260
const ListItem_t * xEnd = listGET_END_MARKER( &xIGMP_ScheduleList );
264-
IGMPReportDesc_t * pxIRD;
261+
MCastReportData_t * pxMRD;
262+
NetworkInterface_t * pxInterface;
263+
NetworkEndPoint_t * pxEndPoint;
265264

266265
for( pxIterator = ( const ListItem_t * ) listGET_NEXT( xEnd ); pxIterator != ( const ListItem_t * ) xEnd; pxIterator = ( const ListItem_t * ) listGET_NEXT( pxIterator ) )
267266
{
268-
pxIRD = ( IGMPReportDesc_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
267+
pxMRD = ( MCastReportData_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
269268

270269
/* Only decrement down to one. Decrementing to zero is handled later. */
271-
if( pxIRD->ucCountDown > 1 )
270+
if( pxMRD->ucCountDown > 1 )
272271
{
273-
pxIRD->ucCountDown--;
272+
pxMRD->ucCountDown--;
274273
}
275274

276-
if( pxIRD->pxEndPoint->bits.bIPv6 )
275+
if( pxMRD->xMCastGroupAddress.xIs_IPv6 == pdTRUE_UNSIGNED )
277276
{
278277
/* ToDo: handle IPv6 multicast groups through ICMPv6 messages */
279278
continue;
280279
}
281280

282-
/* Hold off on sending reports until our IP is non-zero. This allows a bit of a wait during power up
283-
* when the IP can be zero and also allows us to add reports to the list with a countdown of 1 for fast initial delay. */
284-
if( ( pxIRD->ucCountDown == 1 ) && ( pxIRD->pxEndPoint->ipv4_settings.ulIPAddress != 0 ) )
281+
if( pxMRD->ucCountDown == 1 )
285282
{
286-
pxIRD->ucCountDown = 0;
287-
xSendIGMP( 0, ipIGMP_MEMBERSHIP_REPORT_V2, 0, pxIRD->mreq.imr_multiaddr.sin_address.ulIP_IPv4, pxIRD->pxEndPoint );
283+
pxEndPoint = pxMRD->pxEndPoint;
284+
/* If the end-point is null, the report is for all interfaces. */
285+
if ( pxEndPoint == NULL)
286+
{
287+
for( pxInterface = FreeRTOS_FirstNetworkInterface();
288+
pxInterface != NULL;
289+
pxInterface = FreeRTOS_NextNetworkInterface( pxInterface ) )
290+
{
291+
for( pxEndPoint = FreeRTOS_FirstEndPoint( pxInterface );
292+
pxEndPoint != NULL;
293+
pxEndPoint = FreeRTOS_NextEndPoint( pxInterface, pxEndPoint ) )
294+
{
295+
if ( pxEndPoint->bits.bIPv6 == pdTRUE_UNSIGNED )
296+
{
297+
/* ToDo: handle ICMPv6 reports*/
298+
continue;
299+
}
300+
301+
/* Make sure the end-point has an IP address */
302+
if ( pxEndPoint->ipv4_settings.ulIPAddress != 0 )
303+
{
304+
pxMRD->ucCountDown = 0;
305+
xSendIGMP( 0, ipIGMP_MEMBERSHIP_REPORT_V2, 0, pxMRD->xMCastGroupAddress.xIPAddress.ulIP_IPv4, pxEndPoint );
306+
}
307+
else
308+
{
309+
}
310+
}
311+
}
312+
}
313+
else
314+
{
315+
/* Make sure the end-point has an IP address */
316+
if ( pxEndPoint->ipv4_settings.ulIPAddress != 0 )
317+
{
318+
pxMRD->ucCountDown = 0;
319+
xSendIGMP( 0, ipIGMP_MEMBERSHIP_REPORT_V2, 0, pxMRD->xMCastGroupAddress.xIPAddress.ulIP_IPv4, pxEndPoint );
320+
}
321+
}
288322
}
289323
}
290324

@@ -324,15 +358,21 @@
324358

325359
const ListItem_t * pxIterator;
326360
const ListItem_t * xEnd = listGET_END_MARKER( &xIGMP_ScheduleList );
327-
IGMPReportDesc_t * pxIRD;
361+
MCastReportData_t * pxIRD;
328362

329363
for( pxIterator = ( const ListItem_t * ) listGET_NEXT( xEnd );
330364
pxIterator != ( const ListItem_t * ) xEnd;
331365
pxIterator = ( const ListItem_t * ) listGET_NEXT( pxIterator ) )
332366
{
333-
pxIRD = ( IGMPReportDesc_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
334-
335-
if( pxIRD->mreq.imr_multiaddr.sin_address.ulIP_IPv4 == pMCastGroup->imr_multiaddr.sin_address.ulIP_IPv4 )
367+
pxIRD = ( MCastReportData_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
368+
369+
if ( pxIRD->xMCastGroupAddress.xIs_IPv6 == pdTRUE_UNSIGNED )
370+
{
371+
/* ToDo: handle IPv6 */
372+
continue;
373+
}
374+
375+
if( pxIRD->xMCastGroupAddress.xIPAddress.ulIP_IPv4 == pMCastGroup->imr_multiaddr.s_addr )
336376
{
337377
/* Found a match. */
338378
if( pxIRD->xNumSockets > 0 )
@@ -356,21 +396,21 @@
356396
*
357397
* @param[in] pNewEntry: The multicast group descriptor to search for.
358398
*/
359-
BaseType_t xAddIGMPReportToList( IGMPReportDesc_t * pNewEntry )
399+
BaseType_t xAddIGMPReportToList( MCastReportData_t * pNewEntry )
360400
{
361401
configASSERT( pNewEntry != NULL );
362402

363403
const ListItem_t * pxIterator;
364404
const ListItem_t * xEnd = listGET_END_MARKER( &xIGMP_ScheduleList );
365-
IGMPReportDesc_t * pxIRD;
405+
MCastReportData_t * pxIRD;
366406

367407
for( pxIterator = ( const ListItem_t * ) listGET_NEXT( xEnd );
368408
pxIterator != ( const ListItem_t * ) xEnd;
369409
pxIterator = ( const ListItem_t * ) listGET_NEXT( pxIterator ) )
370410
{
371-
pxIRD = ( IGMPReportDesc_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
411+
pxIRD = ( MCastReportData_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
372412

373-
if( pxIRD->mreq.imr_multiaddr.sin_address.ulIP_IPv4 == pNewEntry->mreq.imr_multiaddr.sin_address.ulIP_IPv4 )
413+
if( pxIRD->xMCastGroupAddress.xIPAddress.ulIP_IPv4 == pNewEntry->xMCastGroupAddress.xIPAddress.ulIP_IPv4 )
374414
{
375415
/* Found a duplicate. All IGMP snooping switches already know that we are interested.
376416
* Just keep track of how many sockets are interested in this multicast group. */
@@ -431,7 +471,7 @@
431471
{
432472
pxMCG = ( MCastGroupDesc_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
433473

434-
if( pxMCG->mreq.imr_multiaddr.sin_address.ulIP_IPv4 == pxMulticastGroup->mreq.imr_multiaddr.sin_address.ulIP_IPv4 )
474+
if( pxMCG->mreq.imr_multiaddr.s_addr == pxMulticastGroup->mreq.imr_multiaddr.s_addr )
435475
{
436476
/* Found a match. If we need to remove this address, go ahead.
437477
* If we need to add it, it's already there, so just free the the descriptor to prevent memory leaks. */
@@ -462,7 +502,7 @@
462502
vListInsertEnd( &( pxSocket->u.xUDP.xMulticastGroupsList ), &( pxMulticastGroup->xListItem ) );
463503
/* Inform the network driver */
464504
uint8_t MCastDestMacBytes[ 6 ];
465-
vSetMultiCastIPv4MacAddress( pxMulticastGroup->mreq.imr_multiaddr.sin_address.ulIP_IPv4, MCastDestMacBytes );
505+
vSetMultiCastIPv4MacAddress( pxMulticastGroup->mreq.imr_multiaddr.s_addr, MCastDestMacBytes );
466506

467507
if( pxNetIf )
468508
{
@@ -493,7 +533,7 @@
493533
else
494534
{
495535
/* Adding, but found duplicate. No need to inform the network driver. Simply free
496-
* the IGMPReportDesc_t */
536+
* the MCastReportData_t */
497537
if( pxMulticastGroup->pxIGMPReportDesc )
498538
{
499539
vPortFree( pxMulticastGroup->pxIGMPReportDesc );
@@ -512,7 +552,7 @@
512552
/* Removing and found a match. */
513553
/* Inform the network driver */
514554
uint8_t MCastDestMacBytes[ 6 ];
515-
vSetMultiCastIPv4MacAddress( pxMulticastGroup->mreq.imr_multiaddr.sin_address.ulIP_IPv4, MCastDestMacBytes );
555+
vSetMultiCastIPv4MacAddress( pxMulticastGroup->mreq.imr_multiaddr.s_addr, MCastDestMacBytes );
516556

517557
if( pxNetIf )
518558
{

source/FreeRTOS_Sockets.c

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6472,22 +6472,22 @@ void * pvSocketGetSocketID( const ConstSocket_t xSocket )
64726472

64736473
struct freertos_ip_mreq * pMReq = ( struct freertos_ip_mreq * ) pvOptionValue;
64746474

6475-
if( pdFALSE == xIsIPv4Multicast( pMReq->imr_multiaddr.sin_address.ulIP_IPv4 ) )
6475+
if( pdFALSE == xIsIPv4Multicast( pMReq->imr_multiaddr.s_addr ) )
64766476
{
64776477
break; /* will return -pdFREERTOS_ERRNO_EINVAL */
64786478
}
64796479

64806480
/* Allocate some RAM to remember the multicast group that is being registered */
64816481
MCastGroupDesc_t * pxMCG = ( MCastGroupDesc_t * ) pvPortMalloc( sizeof( MCastGroupDesc_t ) );
6482-
IGMPReportDesc_t * pxIRD = ( IGMPReportDesc_t * ) pvPortMalloc( sizeof( IGMPReportDesc_t ) );
6482+
MCastReportData_t * pxMRD = ( MCastReportData_t * ) pvPortMalloc( sizeof( MCastReportData_t ) );
64836483

64846484
if( NULL == pxMCG )
64856485
{
64866486
xReturn = -pdFREERTOS_ERRNO_ENOMEM;
64876487
break;
64886488
}
64896489

6490-
if( NULL == pxIRD )
6490+
if( NULL == pxMRD )
64916491
{
64926492
xReturn = -pdFREERTOS_ERRNO_ENOMEM;
64936493
vPortFree( pxMCG );
@@ -6505,24 +6505,26 @@ void * pvSocketGetSocketID( const ConstSocket_t xSocket )
65056505

65066506
/* Init the IGMP report description. It needs to hold the same membership information
65076507
* and it will eventually be added to the IGMP list. */
6508-
( void ) memcpy( ( void * ) &pxIRD->mreq, pvOptionValue, uxOptionLength );
6509-
listSET_LIST_ITEM_OWNER( &( pxIRD->xListItem ), ( void * ) pxIRD );
6510-
pxIRD->xNumSockets = 0;
6511-
pxIRD->ucCountDown = 0;
6508+
pxMRD->xMCastGroupAddress.xIs_IPv6 = pdFALSE_UNSIGNED;
6509+
pxMRD->xMCastGroupAddress.xIPAddress.ulIP_IPv4 = pMReq->imr_multiaddr.s_addr;
6510+
pxMRD->pxEndPoint = NULL;
6511+
listSET_LIST_ITEM_OWNER( &( pxMRD->xListItem ), ( void * ) pxMRD );
6512+
pxMRD->xNumSockets = 0;
6513+
pxMRD->ucCountDown = 0;
65126514
/* Quick and dirty assignment of end-point. This will probably have to be re-designed and re-done. */
6513-
pxIRD->pxEndPoint = ( pxSocket->bits.bIsIPv6 ) ? FreeRTOS_FirstEndPoint_IPv6( FreeRTOS_FirstNetworkInterface() ) : FreeRTOS_FirstEndPoint( FreeRTOS_FirstNetworkInterface() );
6515+
pxMRD->pxEndPoint = ( pxSocket->bits.bIsIPv6 ) ? FreeRTOS_FirstEndPoint_IPv6( FreeRTOS_FirstNetworkInterface() ) : FreeRTOS_FirstEndPoint( FreeRTOS_FirstNetworkInterface() );
65146516

65156517

65166518
/* Pass the IGMP report descriptor inside the multicast group descriptor,
65176519
* so we can easily pass it to the IP task in one message. */
6518-
pxMCG->pxIGMPReportDesc = pxIRD;
6520+
pxMCG->pxIGMPReportDesc = pxMRD;
65196521

65206522
IPStackEvent_t xSockOptsEvent = { eSocketOptAddMembership, ( void * ) pxMCG };
65216523

65226524
if( xSendEventStructToIPTask( &( xSockOptsEvent ), portMAX_DELAY ) != pdPASS )
65236525
{
65246526
vPortFree( pxMCG );
6525-
vPortFree( pxIRD );
6527+
vPortFree( pxMRD );
65266528
xReturn = -1;
65276529
}
65286530
else
@@ -6541,7 +6543,7 @@ void * pvSocketGetSocketID( const ConstSocket_t xSocket )
65416543

65426544
struct freertos_ip_mreq * pMReq = ( struct freertos_ip_mreq * ) pvOptionValue;
65436545

6544-
if( pdFALSE == xIsIPv4Multicast( pMReq->imr_multiaddr.sin_address.ulIP_IPv4 ) )
6546+
if( pdFALSE == xIsIPv4Multicast( pMReq->imr_multiaddr.s_addr ) )
65456547
{
65466548
break; /* will return -pdFREERTOS_ERRNO_EINVAL */
65476549
}

source/FreeRTOS_UDP_IPv4.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ BaseType_t xProcessReceivedUDPPacket_IPv4( NetworkBufferDescriptor_t * pxNetwork
394394
{
395395
MCastGroupDesc_t * pxMCG = ( MCastGroupDesc_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
396396

397-
if( pxMCG->mreq.imr_multiaddr.sin_address.ulIP_IPv4 == pxUDPPacket->xIPHeader.ulDestinationIPAddress )
397+
if( pxMCG->mreq.imr_multiaddr.s_addr == pxUDPPacket->xIPHeader.ulDestinationIPAddress )
398398
{
399399
break;
400400
}

source/include/FreeRTOS_IGMP.h

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -62,32 +62,6 @@
6262
#define ipIGMP_IP_ADDR 0x010000E0UL
6363
#endif /* ipconfigBYTE_ORDER == pdFREERTOS_BIG_ENDIAN */
6464

65-
struct freertos_ip_mreq
66-
{
67-
/* _EVP_ This can be simplified a bit on a single IF, IPv4 only system
68-
* but keeping it more generic allows for future use in multi-IF dual-stack implementations. */
69-
struct freertos_sockaddr imr_multiaddr; /* IP multicast address of a group */
70-
struct freertos_sockaddr imr_interface; /* local IP address of the interface to be used */
71-
};
72-
73-
/** @brief The structure information about the IGMP reports that will get sent when the stack receives an IGMP general query. */
74-
typedef struct xIGMPReportDesc
75-
{
76-
struct freertos_ip_mreq mreq; /**< Struct for storing the original mreq structure that was sent to setsockopts() */
77-
struct xLIST_ITEM xListItem; /**< List struct. */
78-
NetworkEndPoint_t * pxEndPoint;
79-
BaseType_t xNumSockets;
80-
uint8_t ucCountDown;
81-
} IGMPReportDesc_t;
82-
83-
/** @brief The structure to hold a "descriptor" for a multicast group that a socket has registered to. */
84-
typedef struct xMCastGroupDesc
85-
{
86-
struct freertos_ip_mreq mreq; /**< Struct for storing the original mreq structure that was sent to setsockopts() */
87-
struct xLIST_ITEM xListItem; /**< List struct. */
88-
FreeRTOS_Socket_t * pxSocket;
89-
IGMPReportDesc_t * pxIGMPReportDesc; /** Optional. used to hold the allocated IGMP report descriptor while passing from user code to the IP Task. */
90-
} MCastGroupDesc_t;
9165

9266
#include "pack_struct_start.h"
9367
struct xIGMP_HEADER
@@ -116,7 +90,7 @@
11690
BaseType_t xSendIGMPEvent( void );
11791
void vHandleIGMP_Event( void );
11892
void vRemoveIGMPReportFromList( struct freertos_ip_mreq * pMCastGroup );
119-
BaseType_t xAddIGMPReportToList( IGMPReportDesc_t * pNewEntry );
93+
BaseType_t xAddIGMPReportToList( MCastReportData_t * pNewEntry );
12094
eFrameProcessingResult_t eProcessIGMPPacket( NetworkBufferDescriptor_t * const pxNetworkBuffer );
12195

12296

source/include/FreeRTOS_IP_Common.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,30 @@ typedef struct xxIPv46_Address
5555
BaseType_t xIs_IPv6; /**< pdTRUE if IPv6 address. */
5656
} IPv46_Address_t;
5757

58+
#if ( ipconfigSUPPORT_IP_MULTICAST != 0 )
59+
/** @brief The structure represents an IPv4 address. */
60+
typedef struct freertos_in_addr {
61+
uint32_t s_addr; /**< IPv4 address in network byte order */
62+
} In_Addr_t;
63+
64+
/** @brief The structure is used to join/leave an IPv4 multicast group. */
65+
typedef struct freertos_ip_mreq {
66+
In_Addr_t imr_multiaddr; /**< The address of the multicast group */
67+
In_Addr_t imr_interface; /**< The address of the network interface on which the multicast group is to be joined or left */
68+
} IP_MReq_t;
69+
70+
/** @brief The structure represents an IPv6 address. */
71+
typedef struct freertos_in6_addr {
72+
IPv6_Address_t s6_addr; /**< IPv6 address */
73+
}In6_Addr_t;
74+
75+
/** @brief The structure is used to join/leave an IPv6 multicast group. */
76+
typedef struct freertos_ipv6_mreq {
77+
In6_Addr_t ipv6mr_multiaddr; /**< The address of the multicast group */
78+
uint32_t ipv6mr_interface; /**< The network interface index on which the multicast group is to be joined or left. 0 means use the default multicast interface. */
79+
} IP6_MReq_t;
80+
#endif
81+
5882
struct xNetworkEndPoint;
5983
struct xNetworkInterface;
6084

0 commit comments

Comments
 (0)