kern/58359: Strict Multicast Membership (patch w/ sysctl knob)

William A.Carrel william.a at carrel.org
Sat Oct 25 00:01:30 PDT 2003


I've been told thirdhand that there has been some amount of 
handwringing regarding this PR.  My impression is that the worries 
mainly surround the fact that certain programs may depend on the fairly 
sparsely documented (http://www.kohala.com/start/mcast.api.txt) 
behavior currently shown.  Change in behavior of decades old code can 
certainly be a concern, yet I would also like to see the option of the 
new behavior (which I'm told matches Solaris), therefore...

Here is a new patch which provides a sysctl to turn this "extra" 
filtering on and off.  net.inet.udp.strict_mcast_mship.  It defaults to 
off so as to reduce any risk of POLA violation to zero.  This also can 
help push any bikeshed discussions about the default into the future.  
;-)  If it would help, I can also work on providing a patch for the 
ip(4) manpage to reflect this option and/or note the current stack 
behavior more explicitly.

Please feel free to let me know what you think, or feel free to let 
word of what you think drift through a few layers of indirection before 
it gets to me.  I'll do what I can to mitigate concerns either way. :-) 
  Thanks for reading.

--- freebsd_current_udp_usrreq.c.orig	Fri Oct 24 12:35:36 2003
+++ freebsd_current_udp_usrreq.c	Fri Oct 24 23:19:11 2003
@@ -108,6 +108,10 @@
  SYSCTL_INT(_net_inet_udp, OID_AUTO, blackhole, CTLFLAG_RW,
  	&blackhole, 0, "Do not send port unreachables for refused connects");

+static int	strict_mcast_mship = 0;
+SYSCTL_INT(_net_inet_udp, OID_AUTO, strict_mcast_mship, CTLFLAG_RW,
+	&strict_mcast_mship, 0, "Only send multicast to member sockets");
+
  struct	inpcbhead udb;		/* from udp_var.h */
  #define	udb6	udb  /* for KAME src sync over BSD*'s */
  struct	inpcbinfo udbinfo;
@@ -306,6 +310,28 @@
  				    ip->ip_src.s_addr ||
  				    inp->inp_fport != uh->uh_sport)
  					goto docontinue;
+			}
+			/*
+			 * Check multicast packets to make sure they are only
+			 * sent to sockets with multicast memberships for the
+			 * packet's destination address and arrival interface
+			 */
+			if (strict_mcast_mship &&
+			    IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) &&
+			    inp->inp_moptions != NULL) {
+				int mshipno;
+
+				for (mshipno = 0;
+				     mshipno <= inp->inp_moptions->imo_num_memberships;
+				     ++mshipno) {
+					if (ip->ip_dst.s_addr == 
inp->inp_moptions->imo_membership[mshipno]->inm_addr.s_addr && 
m->m_pkthdr.rcvif == inp->inp_mo
+ptions->imo_membership[mshipno]->inm_ifp)
+						break;
+				}
+				if (mshipno ==
+				    inp->inp_moptions->imo_num_memberships)
+					goto docontinue;
+					
  			}

  			if (last != NULL) {

--- freebsd_stable_udp_usrreq.c.orig	Fri Oct 24 12:35:46 2003
+++ freebsd_stable_udp_usrreq.c	Fri Oct 24 23:22:01 2003
@@ -102,6 +102,10 @@
  SYSCTL_INT(_net_inet_udp, OID_AUTO, blackhole, CTLFLAG_RW,
  	&blackhole, 0, "Do not send port unreachables for refused connects");

+static int	strict_mcast_mship = 0;
+SYSCTL_INT(_net_inet_udp, OID_AUTO, strict_mcast_mship, CTLFLAG_RW,
+	&strict_mcast_mship, 0, "Only send multicast to member sockets");
+
  struct	inpcbhead udb;		/* from udp_var.h */
  #define	udb6	udb  /* for KAME src sync over BSD*'s */
  struct	inpcbinfo udbinfo;
@@ -290,6 +294,27 @@
  				if (inp->inp_faddr.s_addr !=
  				    ip->ip_src.s_addr ||
  				    inp->inp_fport != uh->uh_sport)
+					continue;
+			}
+			/*
+			 * Check multicast packets to make sure they are only
+			 * sent to sockets with multicast memberships for the
+			 * packet's destination address and arrival interface
+			 */
+			if (strict_mcast_mship &&
+			    IN_MULTICAST(ntohl(ip->ip_dst.s_addr)) &&
+			    inp->inp_moptions != NULL) {
+				int mshipno;
+				
+				for (mshipno = 0;
+				     mshipno <=
+				        inp->inp_moptions->imo_num_memberships;
+				     ++mshipno) {
+					if (ip->ip_dst.s_addr == 
inp->inp_moptions->imo_membership[mshipno]->inm_addr.s_addr && 
m->m_pkthdr.rcvif == 
inp->inp_moptions->imo_membership[mshipno]->inm_ifp)
+						break;
+				}
+				if (mshipno ==
+				    inp->inp_moptions->imo_num_memberships)
  					continue;
  			}



More information about the freebsd-net mailing list