aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet/udp_usrreq.c
diff options
context:
space:
mode:
authorBruce M Simpson <bms@FreeBSD.org>2003-11-12 20:17:11 +0000
committerBruce M Simpson <bms@FreeBSD.org>2003-11-12 20:17:11 +0000
commit83453a06dee113058b9ceb81b998ef8b604cd243 (patch)
tree52b473230ba2792672e6acc727761206faf38788 /sys/netinet/udp_usrreq.c
parent5645e50570e95d1f9b675eea3cd705a44eaffeb3 (diff)
downloadsrc-83453a06dee113058b9ceb81b998ef8b604cd243.tar.gz
src-83453a06dee113058b9ceb81b998ef8b604cd243.zip
Add a new sysctl knob, net.inet.udp.strict_mcast_mship, to the udp_input path.
This switch toggles between strict multicast delivery, and traditional multicast delivery. The traditional (default) behaviour is to deliver multicast datagrams to all sockets which are members of that group, regardless of the network interface where the datagrams were received. The strict behaviour is to deliver multicast datagrams received on a particular interface only to sockets whose membership is bound to that interface. Note that as a matter of course, multicast consumers specifying INADDR_ANY for their interface get joined on the interface where the default route happens to be bound. This switch has no effect if the interface which the consumer specifies for IP_ADD_MEMBERSHIP is not UP and RUNNING. The original patch has been cleaned up somewhat from that submitted. It has been tested on a multihomed machine with multiple QuickTime RTP streams running over the local switch, which doesn't do IGMP snooping. PR: kern/58359 Submitted by: William A. Carrel Reviewed by: rwatson MFC after: 1 week
Notes
Notes: svn path=/head/; revision=122579
Diffstat (limited to 'sys/netinet/udp_usrreq.c')
-rw-r--r--sys/netinet/udp_usrreq.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index 8eb71bd01d8d..4b755af01778 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -108,6 +108,10 @@ static int blackhole = 0;
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;
@@ -308,6 +312,30 @@ udp_input(m, off)
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
+ */
+#define MSHIP(_inp, n) ((_inp)->inp_moptions->imo_membership[(n)])
+#define NMSHIPS(_inp) ((_inp)->inp_moptions->imo_num_memberships)
+ if (strict_mcast_mship && inp->inp_moptions != NULL) {
+ int mship, foundmship = 0;
+
+ for (mship = 0; mship < NMSHIPS(inp); mship++) {
+ if (MSHIP(inp, mship)->inm_addr.s_addr
+ == ip->ip_dst.s_addr &&
+ MSHIP(inp, mship)->inm_ifp
+ == m->m_pkthdr.rcvif) {
+ foundmship = 1;
+ break;
+ }
+ }
+ if (foundmship == 0)
+ goto docontinue;
+ }
+#undef NMSHIPS
+#undef MSHIP
if (last != NULL) {
struct mbuf *n;