[Bug 242677] multicast: setsockopt(...IP_DROP_MEMBERSHIP...) doesn't lead to sending IGMP packet.
bugzilla-noreply at freebsd.org
bugzilla-noreply at freebsd.org
Tue Dec 17 07:26:54 UTC 2019
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=242677
Bug ID: 242677
Summary: multicast: setsockopt(...IP_DROP_MEMBERSHIP...)
doesn't lead to sending IGMP packet.
Product: Base System
Version: CURRENT
Hardware: Any
OS: Any
Status: New
Severity: Affects Many People
Priority: ---
Component: kern
Assignee: bugs at FreeBSD.org
Reporter: aleksandr.fedorov at itglobal.com
Attachment #210002 text/plain
mime type:
Created attachment 210002
--> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=210002&action=edit
Test code.
Revision 355322 fixes multicast in case of closing the socket.
But the problem remains if you try to exit the multicast group before closing
the socket.
If you run test code from attachment.
#./mcasttest
Add membership
igb1:
inet 192.168.1.55
igmpv3 rv 2 qi 125 qri 10 uri 3
group 239.0.0.5 mode exclude
mcast-macaddr 01:00:5e:00:00:05
group 224.0.0.1 mode exclude
mcast-macaddr 01:00:5e:00:00:01
Drop membership
igb1:
inet 192.168.1.55
igmpv3 rv 2 qi 125 qri 10 uri 3
group 224.0.0.1 mode exclude
mcast-macaddr 01:00:5e:00:00:01
Add membership
igb1:
inet 192.168.1.55
igmpv3 rv 2 qi 125 qri 10 uri 3
group 239.0.0.5 mode exclude
mcast-macaddr 01:00:5e:00:00:05
group 224.0.0.1 mode exclude
mcast-macaddr 01:00:5e:00:00:01
Drop membership
igb1:
inet 192.168.1.55
igmpv3 rv 2 qi 125 qri 10 uri 3
group 224.0.0.1 mode exclude
mcast-macaddr 01:00:5e:00:00:01
As you can see, the ADD/DROP membership to/from the group is successful.
But, there are no IGMP leave packets on igb1:
# tcpdump -i igb1 -vvv
tcpdump: listening on igb1, link-type EN10MB (Ethernet), capture size 262144
bytes
08:14:31.403346 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has
192.168.1.55 tell 192.168.1.55, length 28
08:14:33.678193 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto IGMP
(2), length 40, options (RA))
192.168.1.55 > igmp.mcast.net: igmp v3 report, 1 group record(s) [gaddr
239.0.0.5 to_ex { }]
08:14:34.526191 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto IGMP
(2), length 40, options (RA))
192.168.1.55 > igmp.mcast.net: igmp v3 report, 1 group record(s) [gaddr
239.0.0.5 to_ex { }]
08:14:37.905173 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto IGMP
(2), length 40, options (RA))
192.168.1.55 > igmp.mcast.net: igmp v3 report, 1 group record(s) [gaddr
239.0.0.5 to_ex { }]
08:14:39.177149 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto IGMP
(2), length 40, options (RA))
192.168.1.55 > igmp.mcast.net: igmp v3 report, 1 group record(s) [gaddr
239.0.0.5 to_ex { }]
It seems that the function inp_leave_group() is broken:
2409 if (is_final) {
2410 ip_mfilter_remove(&imo->imo_head, imf);
(1) For IP_DROP_MEMBERSHIP is_final is true. Mark socket-layer filter set as
INCLUDE {} at t1.
2411 imf_leave(imf);
2412 } else {
2413 if (imf->imf_st[0] == MCAST_EXCLUDE) {
2414 error = EADDRNOTAVAIL;
2415 goto out_inp_locked;
2416 }
2417 ims = imo_match_source(imf, &ssa->sa);
2418 if (ims == NULL) {
2419 CTR3(KTR_IGMPV3, "%s: source 0x%08x %spresent",
2420 __func__, ntohl(ssa->sin.sin_addr.s_addr),
"not ");
2421 error = EADDRNOTAVAIL;
2422 goto out_inp_locked;
2423 }
2424 CTR2(KTR_IGMPV3, "%s: %s source", __func__, "block");
2425 error = imf_prune(imf, &ssa->sin);
2426 if (error) {
2427 CTR1(KTR_IGMPV3, "%s: merge imf state failed",
2428 __func__);
2429 goto out_inp_locked;
2430 }
2431 }
2432
....
(2) Commit and reap socket filter deltas.
2460 imf_commit(imf);
2461 imf_reap(imf);
2462
2463 out_inp_locked:
2464 INP_WUNLOCK(inp);
2465
2466 if (is_final && imf) {
2467 /*
2468 * Give up the multicast address record to which
2469 * the membership points.
2470 */
(3) in_leavegroup_locked() call igmp_change_state(). But, because source filter
deltas already committed and reaped, the call igmp_change_state() doesn't lead
to IGMP state transition and sending IGMP packets.
2471 (void) in_leavegroup_locked(imf->imf_inm, imf);
2472 ip_mfilter_free(imf);
2473 }
2474
2475 IN_MULTI_UNLOCK();
2476 return (error);
2477 }
What do you think about move the in_leavegroup_locked() call before commit and
reap?
Something like this:
Index: sys/netinet/in_mcast.c
===================================================================
--- sys/netinet/in_mcast.c (revision 355800)
+++ sys/netinet/in_mcast.c (working copy)
@@ -2409,6 +2409,7 @@
if (is_final) {
ip_mfilter_remove(&imo->imo_head, imf);
imf_leave(imf);
+ (void) in_leavegroup_locked(imf->imf_inm, imf);
} else {
if (imf->imf_st[0] == MCAST_EXCLUDE) {
error = EADDRNOTAVAIL;
@@ -2468,7 +2469,6 @@
* Give up the multicast address record to which
* the membership points.
*/
- (void) in_leavegroup_locked(imf->imf_inm, imf);
ip_mfilter_free(imf);
}
With this patch.
# ./mcasttest
Add membership
igb1:
inet 192.168.1.55
igmpv3 rv 2 qi 125 qri 10 uri 3
group 239.0.0.5 mode exclude
mcast-macaddr 01:00:5e:00:00:05
group 224.0.0.1 mode exclude
mcast-macaddr 01:00:5e:00:00:01
Drop membership
igb1:
inet 192.168.1.55
igmpv3 rv 2 qi 125 qri 10 uri 3
group 224.0.0.1 mode exclude
mcast-macaddr 01:00:5e:00:00:01
Add membership
igb1:
inet 192.168.1.55
igmpv3 rv 2 qi 125 qri 10 uri 3
group 239.0.0.5 mode exclude
mcast-macaddr 01:00:5e:00:00:05
group 224.0.0.1 mode exclude
mcast-macaddr 01:00:5e:00:00:01
Drop membership
igb1:
inet 192.168.1.55
igmpv3 rv 2 qi 125 qri 10 uri 3
group 224.0.0.1 mode exclude
mcast-macaddr 01:00:5e:00:00:01
And tcpdump shows:
# tcpdump -i igb1 -vvv
tcpdump: listening on igb1, link-type EN10MB (Ethernet), capture size 262144
bytes
10:19:22.059334 ARP, Ethernet (len 6), IPv4 (len 4), Request who-has
192.168.1.55 tell 192.168.1.55, length 28
10:19:24.232247 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto IGMP
(2), length 40, options (RA))
192.168.1.55 > igmp.mcast.net: igmp v3 report, 1 group record(s) [gaddr
239.0.0.5 to_ex { }]
10:19:24.861942 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto IGMP
(2), length 40, options (RA))
192.168.1.55 > igmp.mcast.net: igmp v3 report, 1 group record(s) [gaddr
239.0.0.5 to_ex { }]
10:19:29.502570 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto IGMP
(2), length 40, options (RA))
192.168.1.55 > igmp.mcast.net: igmp v3 report, 1 group record(s) [gaddr
239.0.0.5 to_in { }]
10:19:31.807624 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto IGMP
(2), length 40, options (RA))
192.168.1.55 > igmp.mcast.net: igmp v3 report, 1 group record(s) [gaddr
239.0.0.5 to_in { }]
10:19:34.747646 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto IGMP
(2), length 40, options (RA))
192.168.1.55 > igmp.mcast.net: igmp v3 report, 1 group record(s) [gaddr
239.0.0.5 to_ex { }]
10:19:35.595604 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto IGMP
(2), length 40, options (RA))
192.168.1.55 > igmp.mcast.net: igmp v3 report, 1 group record(s) [gaddr
239.0.0.5 to_ex { }]
10:19:39.818577 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto IGMP
(2), length 40, options (RA))
192.168.1.55 > igmp.mcast.net: igmp v3 report, 1 group record(s) [gaddr
239.0.0.5 to_in { }]
10:19:40.242591 IP (tos 0xc0, ttl 1, id 0, offset 0, flags [DF], proto IGMP
(2), length 40, options (RA))
192.168.1.55 > igmp.mcast.net: igmp v3 report, 1 group record(s) [gaddr
239.0.0.5 to_in { }]
--
You are receiving this mail because:
You are the assignee for the bug.
More information about the freebsd-bugs
mailing list