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
This commit is contained in:
parent
5645e50570
commit
83453a06de
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=122579
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user