[Bug 248512] MCAST_LEAVE_GROUP/IP_DROP_MEMBERSHIP broken in 12.x
bugzilla-noreply at freebsd.org
bugzilla-noreply at freebsd.org
Fri Aug 7 10:28:37 UTC 2020
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=248512
Bug ID: 248512
Summary: MCAST_LEAVE_GROUP/IP_DROP_MEMBERSHIP broken in 12.x
Product: Base System
Version: 12.1-STABLE
Hardware: Any
OS: Any
Status: New
Severity: Affects Many People
Priority: ---
Component: kern
Assignee: bugs at FreeBSD.org
Reporter: sietse at wizdom.nu
It seems that multicast is seriously broken in FreeBSD 12.x groups are joined,
but never left, even after closing socket / exiting application. This is
causing serioud bandwith issues with for instance IPTV, as streams keep
running. Even downing / upping interfaces group membership is retained. Issue
is seen since upgrading from 11.4 to version 12.1p7, and still present in p8.
On FreeBSD 12, MC groups are joined correctly:
[root at freebsd /usr/home/sietse]# ifmcstat
vmx0:
inet 10.0.20.123
igmpv3 rv 2 qi 125 qri 10 uri 3
group 225.0.71.1 mode exclude
mcast-macaddr 01:00:5e:00:47:01
group 239.255.255.253 mode exclude
mcast-macaddr 01:00:5e:7f:ff:fd
group 239.255.255.250 mode exclude
mcast-macaddr 01:00:5e:7f:ff:fa
group 224.0.0.1 mode exclude
mcast-macaddr 01:00:5e:00:00:01
vmx1:
inet 10.0.22.122
igmpv2
group 224.0.0.22 mode undefined
mcast-macaddr 01:00:5e:00:00:16
group 224.0.0.2 mode undefined
mcast-macaddr 01:00:5e:00:00:02
group 224.0.0.1 mode exclude
mcast-macaddr 01:00:5e:00:00:01
vmx2:
inet 192.168.1.123
igmpv3 rv 2 qi 125 qri 100 uri 3
group 224.0.0.22 mode undefined
mcast-macaddr 01:00:5e:00:00:16
group 224.0.0.2 mode undefined
mcast-macaddr 01:00:5e:00:00:02
group 224.0.0.1 mode exclude
mcast-macaddr 01:00:5e:00:00:01
But after issueing MC_LEAVE_GROUP/IP_DROP_MEMBERSHIP or exiting process /
closing FD group membership remains:
[root at freebsd /usr/home/sietse]# ifmcstat
vmx0:
inet 10.0.20.123
igmpv3 rv 2 qi 125 qri 10 uri 3
group 225.0.71.1 mode exclude
mcast-macaddr 01:00:5e:00:47:01
group 239.255.255.253 mode exclude
mcast-macaddr 01:00:5e:7f:ff:fd
group 239.255.255.250 mode exclude
mcast-macaddr 01:00:5e:7f:ff:fa
group 224.0.0.1 mode exclude
mcast-macaddr 01:00:5e:00:00:01
vmx1:
inet 10.0.22.122
igmpv2
group 224.0.0.22 mode undefined
mcast-macaddr 01:00:5e:00:00:16
group 224.0.0.2 mode undefined
mcast-macaddr 01:00:5e:00:00:02
group 224.0.0.1 mode exclude
mcast-macaddr 01:00:5e:00:00:01
vmx2:
inet 192.168.1.123
igmpv3 rv 2 qi 125 qri 100 uri 3
group 224.0.0.22 mode undefined
mcast-macaddr 01:00:5e:00:00:16
group 224.0.0.2 mode undefined
mcast-macaddr 01:00:5e:00:00:02
group 224.0.0.1 mode exclude
mcast-macaddr 01:00:5e:00:00:01
On FREEBSD 11 / Linux group membership is dropped correctly after
MC_LEAVE_GROUP:
[root at freebsd-test2 /usr/home/sietse/igmpproxy]# ifmcstat
vmx0:
inet 10.0.20.201
igmpv3 rv 2 qi 125 qri 10 uri 3
group 224.0.0.1 mode exclude
mcast-macaddr 01:00:5e:00:00:01
vmx1:
inet 10.0.22.201
igmpv2
group 224.0.0.1 mode exclude
mcast-macaddr 01:00:5e:00:00:01
vmx2:
inet 192.168.1.127
igmpv2
group 224.0.0.1 mode exclude
mcast-macaddr 01:00:5e:00:00:01
Code of application leading up to this issue:
void openUdpSocket(uint32_t PeerInAdr, uint16_t PeerPort) {
struct sockaddr_in SockAdr;
if ((udpSock = socket(AF_INET, SOCK_RAW, IPPROTO_IGMP)) < 0) {
my_log(LOG_ERR, errno, "UDP socket open");
}
memset(&SockAdr, 0, sizeof(SockAdr));
SockAdr.sin_family = AF_INET;
SockAdr.sin_port = htons(PeerPort);
SockAdr.sin_addr.s_addr = htonl(PeerInAdr);
if (bind(udpSock, (struct sockaddr *)&SockAdr, sizeof(SockAdr))) {
my_log(LOG_ERR, errno, "UDP socket bind");
}
}
/**
* Common function for joining or leaving a MCast group.
*/
static void joinleave(int Cmd, struct IfDesc *IfDp, uint32_t mcastaddr) {
const char *CmdSt = Cmd == 'j' ? "join" : "leave";
struct group_req GrpReq;
#ifdef __linux__
struct sockaddr_in Grp = { AF_INET, 0, mcastaddr };
#else
struct sockaddr_in Grp = { sizeof(struct sockaddr_in), AF_INET, 0,
mcastaddr };
#endif
GrpReq.gr_interface = IfDp ? if_nametoindex(IfDp->Name) : 0;
memcpy(&GrpReq.gr_group, &Grp, sizeof(Grp));
my_log(LOG_NOTICE, 0, "%sMcGroup: %s on %s", CmdSt,
inetFmt(Grp.sin_addr.s_addr, s1), IfDp->Name);
if (setsockopt(udpSock, IPPROTO_IP, Cmd == 'j' ? MCAST_JOIN_GROUP :
MCAST_LEAVE_GROUP, &GrpReq, sizeof(GrpReq))) {
int mcastGroupExceeded = (Cmd == 'j' && errno == ENOBUFS);
my_log(LOG_WARNING, errno, "MCAST_%s_GROUP failed", Cmd == 'j' ? "JOIN"
: "LEAVE");
if (mcastGroupExceeded) {
my_log(LOG_WARNING, 0, "Maximum number of multicast groups were
exceeded");
#ifdef __linux__
my_log(LOG_WARNING, 0, "Check settings of '/sbin/sysctl
net.ipv4.igmp_max_memberships'");
#endif
}
}
}
Application contains a thorough cleanup routing on exit
static void igmpProxyCleanUp(void) {
my_log( LOG_DEBUG, 0, "clean handler called" );
freeQueriers(); // Free all group queriers.
timer_freeQueue(); // Free all timeouts.
clearRoutes(NULL,NULL); // Remove all routes and leave all groups.
freeIfDescP(0); // Free IfDesc table.
freeConfig(0); // Free config.
freeVifDescVc(); // Free VifDesc table.
disableMRouter(); // Disable the MRouter API.
free(recv_buf); // Free receive buffer.
free(send_buf); // Free send buffer.
close(udpSock); // Close UDP Socket.
}
--
You are receiving this mail because:
You are the assignee for the bug.
More information about the freebsd-bugs
mailing list