2005-11-09 11:56:26

by Yan Zheng

[permalink] [raw]
Subject: [PATCH 1/2][MCAST] Fix for is_in(...)

Hi.


Include/exclude count of source filter also need check when type is MLD2_MODE_IS_INCLUDE or MLD2_MODE_IS_EXCLUDE.
If the check is ignored, MODE_IS_EXCLUDE report may include sources that have include count greater than zero.

You can check this bug by test.c and query.c in the attachments.

test.c create two socket and make both of them join multicast address M.
The first socket set it's filter mode to INCLUDE{X} and the second set it's filter mode to EXCLUDE{Y}.
Now the interface state for multicast address M should be EXCLUDE{Y}.


let's send a Multicast Address Specific Query by query.c.
You will notice that both X and Y are included in the MODE_IS_EXCLUDE report's source address list.


I hope I provide enough information this time. :-)


Regards

Signed-off-by: Yan Zheng<[email protected]>

Index:net/ipv6/mcast.c
==============================================================
--- linux-2.6.14/net/ipv6/mcast.c 2005-11-09 16:00:48.000000000 +0800
+++ linux/net/ipv6/mcast.c 2005-11-09 18:44:37.000000000 +0800
@@ -1273,22 +1273,27 @@ static int is_in(struct ifmcaddr6 *pmc,
{
switch (type) {
case MLD2_MODE_IS_INCLUDE:
- case MLD2_MODE_IS_EXCLUDE:
+ case MLD2_CHANGE_TO_INCLUDE:
if (gdeleted || sdeleted)
return 0;
+ if (psf->sf_count[MCAST_INCLUDE] == 0)
+ return 0; // maybe never happen
+ if (type == MLD2_CHANGE_TO_INCLUDE)
+ return 1;
return !((pmc->mca_flags & MAF_GSQUERY) && !psf->sf_gsresp);
- case MLD2_CHANGE_TO_INCLUDE:
- if (gdeleted || sdeleted)
- return 0;
- return psf->sf_count[MCAST_INCLUDE] != 0;
+ case MLD2_MODE_IS_EXCLUDE:
case MLD2_CHANGE_TO_EXCLUDE:
if (gdeleted || sdeleted)
return 0;
if (pmc->mca_sfcount[MCAST_EXCLUDE] == 0 ||
psf->sf_count[MCAST_INCLUDE])
return 0;
- return pmc->mca_sfcount[MCAST_EXCLUDE] ==
- psf->sf_count[MCAST_EXCLUDE];
+ if (pmc->mca_sfcount[MCAST_EXCLUDE] !=
+ psf->sf_count[MCAST_EXCLUDE])
+ return 0;
+ if (type == MLD2_CHANGE_TO_EXCLUDE)
+ return 1;
+ return !((pmc->mca_flags & MAF_GSQUERY) && !psf->sf_gsresp);
case MLD2_ALLOW_NEW_SOURCES:
if (gdeleted || !psf->sf_crcount)
return 0;




Attachments:
test.c (1.27 kB)
query.c (945.00 B)
Download all attachments