On Fri, Jan 15, 2021 at 02:53:17PM +0100, Claudio Jeker wrote:
> I forgot to add ip_mreqn support to IP_MULTICAST_IF and so the
> IP_ADD_MEMBERSHIP change is not fixing all the issues I have.
>
> Linux supports calling IP_MULTICAST_IF with a struct in_addr, a struct
> ip_mreq, or a struct ip_mreqn. FreeBSD only does the first and last.
> I followed the Linux way because doing that was not that hard. In the end
> only the imr_ifindex field and the imr_address field need to be checked
> and if the imr_ifindex is 0 then just use the old code. If the imr_ifindex
> is set then use this for interface index and break early.
>
> Any opinions about this?
This is the corresponding diff for ospfd.
Additionally this initalizes the imr_address field. It is not used but we
should not send stack garbage to the kernel.
--
:wq Claudio
Index: interface.c
===================================================================
RCS file: /cvs/src/usr.sbin/ospfd/interface.c,v
retrieving revision 1.85
diff -u -p -r1.85 interface.c
--- interface.c 12 Jan 2021 09:11:09 -0000 1.85
+++ interface.c 15 Jan 2021 14:00:39 -0000
@@ -734,6 +734,7 @@ if_join_group(struct iface *iface, struc
return (0);
mreq.imr_multiaddr.s_addr = addr->s_addr;
+ mreq.imr_address.s_addr = 0;
mreq.imr_ifindex = iface->ifindex;
if (setsockopt(iface->fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
@@ -782,6 +783,7 @@ if_leave_group(struct iface *iface, stru
}
mreq.imr_multiaddr.s_addr = addr->s_addr;
+ mreq.imr_address.s_addr = 0;
mreq.imr_ifindex = iface->ifindex;
if (setsockopt(iface->fd, IPPROTO_IP, IP_DROP_MEMBERSHIP,
@@ -808,11 +810,15 @@ if_leave_group(struct iface *iface, stru
int
if_set_mcast(struct iface *iface)
{
+ struct ip_mreqn mreq;
+
switch (iface->type) {
case IF_TYPE_POINTOPOINT:
case IF_TYPE_BROADCAST:
+ memset(&mreq, 0, sizeof(mreq));
+ mreq.imr_ifindex = iface->ifindex;
if (setsockopt(iface->fd, IPPROTO_IP, IP_MULTICAST_IF,
- &iface->addr.s_addr, sizeof(iface->addr.s_addr)) == -1) {
+ &mreq, sizeof(mreq)) == -1) {
log_warn("if_set_mcast: error setting "
"IP_MULTICAST_IF, interface %s", iface->name);
return (-1);