net/multicast: should not send source list records when have filter mode change
Based on RFC3376 5.1 and RFC3810 6.1 If the per-interface listening change that triggers the new report is a filter mode change, then the next [Robustness Variable] State Change Reports will include a Filter Mode Change Record. This applies even if any number of source list changes occur in that period. Old State New State State Change Record Sent --------- --------- ------------------------ INCLUDE (A) EXCLUDE (B) TO_EX (B) EXCLUDE (A) INCLUDE (B) TO_IN (B) So we should not send source-list change if there is a filter-mode change. Here are two scenarios: 1. Group deleted and filter mode is EXCLUDE, which means we need send a TO_IN { }. 2. Not group deleted, but has pcm->crcount, which means we need send a normal filter-mode-change. At the same time, if the type is ALLOW or BLOCK, and have psf->sf_crcount, we stop add records and decrease sf_crcount directly Reference: https://www.ietf.org/mail-archive/web/magma/current/msg01274.html Signed-off-by: Hangbin Liu <liuhangbin@gmail.com> Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
013ad40d37
Коммит
a052517a8f
|
@ -472,6 +472,15 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc,
|
|||
continue;
|
||||
}
|
||||
|
||||
/* Based on RFC3376 5.1. Should not send source-list change
|
||||
* records when there is a filter mode change.
|
||||
*/
|
||||
if (((gdeleted && pmc->sfmode == MCAST_EXCLUDE) ||
|
||||
(!gdeleted && pmc->crcount)) &&
|
||||
(type == IGMPV3_ALLOW_NEW_SOURCES ||
|
||||
type == IGMPV3_BLOCK_OLD_SOURCES) && psf->sf_crcount)
|
||||
goto decrease_sf_crcount;
|
||||
|
||||
/* clear marks on query responses */
|
||||
if (isquery)
|
||||
psf->sf_gsresp = 0;
|
||||
|
@ -499,6 +508,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc,
|
|||
scount++; stotal++;
|
||||
if ((type == IGMPV3_ALLOW_NEW_SOURCES ||
|
||||
type == IGMPV3_BLOCK_OLD_SOURCES) && psf->sf_crcount) {
|
||||
decrease_sf_crcount:
|
||||
psf->sf_crcount--;
|
||||
if ((sdeleted || gdeleted) && psf->sf_crcount == 0) {
|
||||
if (psf_prev)
|
||||
|
|
|
@ -1739,6 +1739,15 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc,
|
|||
continue;
|
||||
}
|
||||
|
||||
/* Based on RFC3810 6.1. Should not send source-list change
|
||||
* records when there is a filter mode change.
|
||||
*/
|
||||
if (((gdeleted && pmc->mca_sfmode == MCAST_EXCLUDE) ||
|
||||
(!gdeleted && pmc->mca_crcount)) &&
|
||||
(type == MLD2_ALLOW_NEW_SOURCES ||
|
||||
type == MLD2_BLOCK_OLD_SOURCES) && psf->sf_crcount)
|
||||
goto decrease_sf_crcount;
|
||||
|
||||
/* clear marks on query responses */
|
||||
if (isquery)
|
||||
psf->sf_gsresp = 0;
|
||||
|
@ -1766,6 +1775,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc,
|
|||
scount++; stotal++;
|
||||
if ((type == MLD2_ALLOW_NEW_SOURCES ||
|
||||
type == MLD2_BLOCK_OLD_SOURCES) && psf->sf_crcount) {
|
||||
decrease_sf_crcount:
|
||||
psf->sf_crcount--;
|
||||
if ((sdeleted || gdeleted) && psf->sf_crcount == 0) {
|
||||
if (psf_prev)
|
||||
|
|
Загрузка…
Ссылка в новой задаче