[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
kernel/2164: igmp v2 leave sent to group address instead of allrouters mcast address
>Number: 2164
>Category: kernel
>Synopsis: igmp v2 leave sent to group address instead of to allrouters mcast address.
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: bugs
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Thu Nov 1 12:40:02 MST 2001
>Last-Modified:
>Originator: Goeran Bengtson
>Organization:
Chalmers
>Release: current
>Environment:
System : OpenBSD 3.0
Architecture: OpenBSD.any
Machine : any
>Description:
igmp V2 leave messages are sent to the group address instead of the
allrouters address (as was specified in an earlier RFC). Although it is
recommended that multicast routers handle messages to both address
(backward compatibility), following current specs is recommended.
In addition, using the old destination address (i.e. group address)
breaks CISCO cgmp fast leave processing (and maybe igmp snooping fast
leave processing too), if that matters to anyone.
>How-To-Repeat:
Join and leave a IPv4 multicast group
>Fix:
Suggested fix follows (some parts from NetBSD).
src/sys/netinet/igmp.c, src/sys/netinet/in.h and src/sbin/routed/defs.h
(to avoid compilation warning for routed).
Index: src/sys/netinet/igmp.c
===================================================================
RCS file: /cvs/src/sys/netinet/igmp.c,v
retrieving revision 1.11
diff -u -r1.11 igmp.c
--- src/sys/netinet/igmp.c 2001/06/08 03:53:45 1.11
+++ src/sys/netinet/igmp.c 2001/11/01 19:06:36
@@ -35,7 +35,7 @@
int igmp_timers_are_running;
static struct router_info *rti_head;
-void igmp_sendpkt __P((struct in_multi *, int));
+void igmp_sendpkt __P((struct in_multi *, int, in_addr_t));
static int rti_fill __P((struct in_multi *));
static struct router_info * rti_find __P((struct ifnet *));
@@ -409,7 +409,7 @@
(inm->inm_ifp->if_flags & IFF_LOOPBACK) == 0) {
if ((i = rti_fill(inm)) == -1)
return;
- igmp_sendpkt(inm, i);
+ igmp_sendpkt(inm, i, 0);
inm->inm_state = IGMP_DELAYING_MEMBER;
inm->inm_timer = IGMP_RANDOM_DELAY(
IGMP_MAX_HOST_REPORT_DELAY * PR_FASTHZ);
@@ -430,7 +430,8 @@
if (!IN_LOCAL_GROUP(inm->inm_addr.s_addr) &&
(inm->inm_ifp->if_flags & IFF_LOOPBACK) == 0)
if (inm->inm_rti->rti_type != IGMP_v1_ROUTER)
- igmp_sendpkt(inm, IGMP_HOST_LEAVE_MESSAGE);
+ igmp_sendpkt(inm, IGMP_HOST_LEAVE_MESSAGE,
+ INADDR_ALLROUTERS_GROUP);
break;
case IGMP_LAZY_MEMBER:
case IGMP_AWAKENING_MEMBER:
@@ -463,10 +464,10 @@
if (inm->inm_state == IGMP_DELAYING_MEMBER) {
if (inm->inm_rti->rti_type == IGMP_v1_ROUTER)
igmp_sendpkt(inm,
- IGMP_v1_HOST_MEMBERSHIP_REPORT);
+ IGMP_v1_HOST_MEMBERSHIP_REPORT, 0);
else
igmp_sendpkt(inm,
- IGMP_v2_HOST_MEMBERSHIP_REPORT);
+ IGMP_v2_HOST_MEMBERSHIP_REPORT, 0);
inm->inm_state = IGMP_IDLE_MEMBER;
}
} else {
@@ -494,9 +495,10 @@
}
void
-igmp_sendpkt(inm, type)
+igmp_sendpkt(inm, type, addr)
struct in_multi *inm;
int type;
+ in_addr_t addr;
{
struct mbuf *m;
struct igmp *igmp;
@@ -523,7 +525,11 @@
ip->ip_off = 0;
ip->ip_p = IPPROTO_IGMP;
ip->ip_src.s_addr = INADDR_ANY;
- ip->ip_dst = inm->inm_addr;
+ if (addr) {
+ ip->ip_dst.s_addr = addr;
+ } else {
+ ip->ip_dst = inm->inm_addr;
+ }
m->m_data += sizeof(struct ip);
m->m_len -= sizeof(struct ip);
Index: src/sys/netinet/in.h
===================================================================
RCS file: /cvs/src/sys/netinet/in.h,v
retrieving revision 1.54
diff -u -r1.54 in.h
--- src/sys/netinet/in.h 2001/07/05 08:40:12 1.54
+++ src/sys/netinet/in.h 2001/11/01 19:06:23
@@ -201,6 +201,7 @@
#define INADDR_UNSPEC_GROUP __IPADDR(0xe0000000) /* 224.0.0.0 */
#define INADDR_ALLHOSTS_GROUP __IPADDR(0xe0000001) /* 224.0.0.1 */
+#define INADDR_ALLROUTERS_GROUP __IPADDR(0xe0000002) /* 224.0.0.2 */
#define INADDR_MAX_LOCAL_GROUP __IPADDR(0xe00000ff) /* 224.0.0.255 */
#define IN_LOOPBACKNET 127 /* official! */
Index: src/sbin/routed/defs.h
===================================================================
RCS file: /cvs/src/sbin/routed/defs.h,v
retrieving revision 1.6
diff -u -r1.6 defs.h
--- src/sbin/routed/defs.h 1997/07/30 23:28:40 1.6
+++ src/sbin/routed/defs.h 2001/11/01 19:06:07
@@ -115,7 +115,9 @@
/* Router Discovery parameters */
#ifndef sgi
+#ifndef INADDR_ALLROUTERS_GROUP
#define INADDR_ALLROUTERS_GROUP 0xe0000002 /* 224.0.0.2 */
+#endif
#endif
#define MaxMaxAdvertiseInterval 1800
#define MinMaxAdvertiseInterval 4
>Audit-Trail:
>Unformatted: