net/mld: Resolve and issue with sending reports from multiple groups in the same polling cycle.
This commit is contained in:
parent
2b3ec4172d
commit
1a56229386
@ -131,6 +131,7 @@
|
||||
#define MLD_LASTREPORT (1 << 3) /* We were the last to report */
|
||||
#define MLD_SCHEDMSG (1 << 4) /* Outgoing message scheduled */
|
||||
#define MLD_WAITMSG (1 << 5) /* Block until message sent */
|
||||
#define MLD_RPTPEND (1 << 6) /* Report pending */
|
||||
|
||||
#define SET_MLD_QUERIER(f) do { (f) |= MLD_QUERIER; } while (0)
|
||||
#define SET_MLD_STARTUP(f) do { (f) |= MLD_STARTUP; } while (0)
|
||||
@ -138,6 +139,7 @@
|
||||
#define SET_MLD_LASTREPORT(f) do { (f) |= MLD_LASTREPORT; } while (0)
|
||||
#define SET_MLD_SCHEDMSG(f) do { (f) |= MLD_SCHEDMSG; } while (0)
|
||||
#define SET_MLD_WAITMSG(f) do { (f) |= MLD_WAITMSG; } while (0)
|
||||
#define SET_MLD_RPTPEND(f) do { (f) |= MLD_RPTPEND; } while (0)
|
||||
|
||||
#define CLR_MLD_QUERIER(f) do { (f) &= ~MLD_QUERIER; } while (0)
|
||||
#define CLR_MLD_STARTUP(f) do { (f) &= ~MLD_STARTUP; } while (0)
|
||||
@ -145,6 +147,7 @@
|
||||
#define CLR_MLD_LASTREPORT(f) do { (f) &= ~MLD_LASTREPORT; } while (0)
|
||||
#define CLR_MLD_SCHEDMSG(f) do { (f) &= ~MLD_SCHEDMSG; } while (0)
|
||||
#define CLR_MLD_WAITMSG(f) do { (f) &= ~MLD_WAITMSG; } while (0)
|
||||
#define CLR_MLD_RPTPEND(f) do { (f) &= ~MLD_RPTPEND; } while (0)
|
||||
|
||||
#define IS_MLD_QUERIER(f) (((f) & MLD_QUERIER) != 0)
|
||||
#define IS_MLD_STARTUP(f) (((f) & MLD_STARTUP) != 0)
|
||||
@ -152,6 +155,7 @@
|
||||
#define IS_MLD_LASTREPORT(f) (((f) & MLD_LASTREPORT) != 0)
|
||||
#define IS_MLD_SCHEDMSG(f) (((f) & MLD_SCHEDMSG) != 0)
|
||||
#define IS_MLD_WAITMSG(f) (((f) & MLD_WAITMSG) != 0)
|
||||
#define IS_MLD_RPTPEND(f) (((f) & MLD_RPTPEND) != 0)
|
||||
|
||||
/* Debug ********************************************************************/
|
||||
|
||||
@ -418,6 +422,17 @@ void mld_poll(FAR struct net_driver_s *dev);
|
||||
void mld_send(FAR struct net_driver_s *dev, FAR struct mld_group_s *group,
|
||||
uint8_t msgtype);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mld_report_msgtype
|
||||
*
|
||||
* Description:
|
||||
* Determine which type of Report to send, MLDv1 or MLDv2, depending on
|
||||
* current state of compatibility mode flag.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint8_t mld_report_msgtype(FAR struct mld_group_s *group);
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mld_joingroup
|
||||
*
|
||||
|
@ -49,29 +49,6 @@
|
||||
#include "devif/devif.h"
|
||||
#include "mld/mld.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mld_sched_send
|
||||
*
|
||||
* Description:
|
||||
* Construct and send the MLD message.
|
||||
*
|
||||
* Returned Value:
|
||||
* Returns a non-zero value if an MLD message is sent.
|
||||
*
|
||||
* Assumptions:
|
||||
* This function ust be called with the network locked.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline void mld_sched_send(FAR struct net_driver_s *dev,
|
||||
FAR struct mld_group_s *group)
|
||||
{
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
@ -127,11 +104,30 @@ void mld_poll(FAR struct net_driver_s *dev)
|
||||
if (IS_MLD_WAITMSG(group->flags))
|
||||
{
|
||||
mldinfo("Awakening waiter\n");
|
||||
|
||||
CLR_MLD_WAITMSG(group->flags);
|
||||
nxsem_post(&group->sem);
|
||||
}
|
||||
|
||||
/* And break out of the loop */
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* No.. does this message have a pending report still to be sent? */
|
||||
|
||||
else if (IS_MLD_RPTPEND(group->flags))
|
||||
{
|
||||
/* Yes.. create the MLD message in the driver buffer */
|
||||
|
||||
mld_send(dev, group, mld_report_msgtype(group));
|
||||
|
||||
/* Indicate that the report is no longer pending */
|
||||
|
||||
CLR_MLD_RPTPEND(group->flags);
|
||||
|
||||
/* And break out of the loop */
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -133,27 +133,6 @@ static void mld_setup_v1compat(FAR struct mld_group_s *group,
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mld_report_msgtype
|
||||
*
|
||||
* Description:
|
||||
* Determine which type of Report to send, MLDv1 or MLDv2, depending on
|
||||
* current state of compatibility mode flag.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint8_t mld_report_msgtype(FAR struct mld_group_s *group)
|
||||
{
|
||||
if (IS_MLD_V1COMPAT(group->flags))
|
||||
{
|
||||
return MLD_SEND_V1REPORT;
|
||||
}
|
||||
else
|
||||
{
|
||||
return MLD_SEND_V2REPORT;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mld_mrc2mrd
|
||||
*
|
||||
@ -416,10 +395,6 @@ int mld_query(FAR struct net_driver_s *dev,
|
||||
* packets. When the report is sent, it will clobber the incoming
|
||||
* query. Any attempt to send an additional Report would also clobber
|
||||
* a preceding report
|
||||
*
|
||||
* REVISIT: This is a design flaw: Only a single report can be sent
|
||||
* in this context because there is no mechanism to preserve the
|
||||
* incoming request nor to queue multiple outgoing reports.
|
||||
*/
|
||||
|
||||
for (member = (FAR struct mld_group_s *)dev->d_mld_grplist.head;
|
||||
@ -430,16 +405,28 @@ int mld_query(FAR struct net_driver_s *dev,
|
||||
|
||||
if (!net_ipv6addr_cmp(member->grpaddr, g_ipv6_allnodes))
|
||||
{
|
||||
|
||||
/* Check MLDv1 compatibility mode */
|
||||
|
||||
mld_setup_v1compat(member, query, mldv1);
|
||||
|
||||
/* Send one report and break out of the loop */
|
||||
/* Have we already sent a report from this loop? */
|
||||
|
||||
mld_send(dev, member, mld_report_msgtype(member));
|
||||
rptsent = true;
|
||||
break;
|
||||
if (rptsent)
|
||||
{
|
||||
/* Yes.. Just mark that a report as pending. The pending
|
||||
* flag will checked on the next driver poll.
|
||||
*/
|
||||
|
||||
SET_MLD_RPTPEND(member->flags);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No.. Send one report now. */
|
||||
|
||||
mld_send(dev, member, mld_report_msgtype(member));
|
||||
rptsent = true;
|
||||
CLR_MLD_RPTPEND(member->flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -304,8 +304,12 @@ void mld_send(FAR struct net_driver_s *dev, FAR struct mld_group_s *group,
|
||||
MLD_STATINCR(g_netstats.mld.query_sent);
|
||||
|
||||
#ifdef CONFIG_NET_MLD_ROUTER
|
||||
/* Save the number of members that reported in the previous query cycle;
|
||||
* reset the number of members that have reported in the new query cycle.
|
||||
/* Save the number of members that reported in the previous query
|
||||
* cycle; reset the number of members that have reported in the
|
||||
* new query cycle.
|
||||
*
|
||||
* REVISIT: This would have to be done for all groups, not just
|
||||
* this one.
|
||||
*/
|
||||
|
||||
group->lstmbrs = group->members;
|
||||
@ -390,3 +394,24 @@ void mld_send(FAR struct net_driver_s *dev, FAR struct mld_group_s *group,
|
||||
|
||||
mld_dumppkt((FAR const uint8_t *)IPv6BUF, MLD_HDRLEN + mldsize);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mld_report_msgtype
|
||||
*
|
||||
* Description:
|
||||
* Determine which type of Report to send, MLDv1 or MLDv2, depending on
|
||||
* current state of compatibility mode flag.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
uint8_t mld_report_msgtype(FAR struct mld_group_s *group)
|
||||
{
|
||||
if (IS_MLD_V1COMPAT(group->flags))
|
||||
{
|
||||
return MLD_SEND_V1REPORT;
|
||||
}
|
||||
else
|
||||
{
|
||||
return MLD_SEND_V2REPORT;
|
||||
}
|
||||
}
|
||||
|
@ -59,27 +59,6 @@
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mld_report_msgtype
|
||||
*
|
||||
* Description:
|
||||
* Determine which type of Report to send, MLDv1 or MLDv2, depending on
|
||||
* current state of compatibility mode flag.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static inline uint8_t mld_report_msgtype(FAR struct mld_group_s *group)
|
||||
{
|
||||
if (IS_MLD_V1COMPAT(group->flags))
|
||||
{
|
||||
return MLD_SEND_V1REPORT;
|
||||
}
|
||||
else
|
||||
{
|
||||
return MLD_SEND_V2REPORT;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: mld_polldog_work
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user