Bug 265540 - EADDRNOTAVAIL when leaving IPv6 multicast group and ipv6_mreq.ipv6mr_interface=0
Summary: EADDRNOTAVAIL when leaving IPv6 multicast group and ipv6_mreq.ipv6mr_interface=0
Status: New
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Only Me
Assignee: freebsd-net (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2022-07-31 19:29 UTC by Dmitri Goutnik
Modified: 2022-07-31 19:29 UTC (History)
0 users

See Also:


Attachments
mcast.c (1.42 KB, text/plain)
2022-07-31 19:29 UTC, Dmitri Goutnik
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Dmitri Goutnik freebsd_committer freebsd_triage 2022-07-31 19:29:36 UTC
Created attachment 235586 [details]
mcast.c

When porting some Linux code, I noticed that when ipv6_mreq.ipv6mr_interface=0, it is possible to join an IPv6 multicast group, but setsockopts() returns EADDRNOTAVAIL when leaving. Running attached mcast.c on 14.0-CURRENT:

$ ./mcast
mcast: addr: ff02::42
mcast: setsockopt: join ok
mcast: setsockopt: IPV6_LEAVE_GROUP: Can't assign requested address

I'm not sure whether this is a correct fix, but I think the lookup code in in6p_leave_group() is missing an in6_setscope() call:

--- a/sys/netinet6/in6_mcast.c
+++ b/sys/netinet6/in6_mcast.c
@@ -2312,6 +2312,9 @@ in6p_leave_group(struct inpcb *inp, struct sockopt *sopt)
                            "ifp for group %s.", __func__,
                            ip6_sprintf(ip6tbuf, &gsa->sin6.sin6_addr));
                        ifp = in6p_lookup_mcast_ifp(inp, &gsa->sin6);
+                       if (ifp == NULL)
+                               return (EADDRNOTAVAIL);
+                       (void)in6_setscope(&gsa->sin6.sin6_addr, ifp, NULL);
                } else {
                        NET_EPOCH_ENTER(et);
                        ifp = ifnet_byindex(ifindex);

in6p_join_group() calls in6_setscope() in in6_mcast.c:1996, but the lookup by im6o_match_group() in in6_mcast.c:2336 is performed using unscoped address.