[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: