diff --git a/lib/sockopt.c b/lib/sockopt.c index 257271bc0b..d8204936f9 100644 --- a/lib/sockopt.c +++ b/lib/sockopt.c @@ -219,6 +219,7 @@ setsockopt_ipv6_tclass(int sock, int tclass) int setsockopt_ipv4_multicast(int sock, int optname, + struct in_addr if_addr, unsigned int mcast_addr, unsigned int ifindex) { @@ -279,18 +280,20 @@ setsockopt_ipv4_multicast(int sock, #elif defined(HAVE_BSD_STRUCT_IP_MREQ_HACK) /* #if OS_TYPE */ /* standard BSD API */ - struct in_addr m; struct ip_mreq mreq; int ret; assert(optname == IP_ADD_MEMBERSHIP || optname == IP_DROP_MEMBERSHIP); - m.s_addr = htonl(ifindex); memset (&mreq, 0, sizeof(mreq)); mreq.imr_multiaddr.s_addr = mcast_addr; - mreq.imr_interface = m; - +#if !defined __OpenBSD__ + mreq.imr_interface.s_addr = htonl (ifindex); +#else + mreq.imr_interface.s_addr = if_addr.s_addr; +#endif + ret = setsockopt (sock, IPPROTO_IP, optname, (void *)&mreq, sizeof(mreq)); if ((ret < 0) && (optname == IP_ADD_MEMBERSHIP) && (errno == EADDRINUSE)) { @@ -318,7 +321,7 @@ setsockopt_ipv4_multicast(int sock, * Set IP_MULTICAST_IF socket option in an OS-dependent manner. */ int -setsockopt_ipv4_multicast_if(int sock, +setsockopt_ipv4_multicast_if(int sock, struct in_addr if_addr, unsigned int ifindex) { @@ -336,7 +339,11 @@ setsockopt_ipv4_multicast_if(int sock, #elif defined(HAVE_BSD_STRUCT_IP_MREQ_HACK) struct in_addr m; - m.s_addr = htonl(ifindex); +#if !defined __OpenBSD__ + m.s_addr = htonl (ifindex); +#else + m.s_addr = if_addr.s_addr; +#endif return setsockopt (sock, IPPROTO_IP, IP_MULTICAST_IF, (void *)&m, sizeof(m)); #else diff --git a/lib/sockopt.h b/lib/sockopt.h index cb14efc7ba..a597314c3d 100644 --- a/lib/sockopt.h +++ b/lib/sockopt.h @@ -83,9 +83,10 @@ extern int setsockopt_ipv6_tclass (int, int); (((af) == AF_INET) : SOPT_SIZE_CMSG_IFINDEX_IPV4() \ ? SOPT_SIZE_CMSG_PKTINFO_IPV6()) -extern int setsockopt_ipv4_multicast_if(int sock, +extern int setsockopt_ipv4_multicast_if(int sock, struct in_addr if_addr, unsigned int ifindex); extern int setsockopt_ipv4_multicast(int sock, int optname, + struct in_addr if_addr, unsigned int mcast_addr, unsigned int ifindex); extern int setsockopt_ipv4_tos(int sock, int tos); diff --git a/ospfd/ospf_network.c b/ospfd/ospf_network.c index 2f167a50a5..9f516d7390 100644 --- a/ospfd/ospf_network.c +++ b/ospfd/ospf_network.c @@ -53,7 +53,7 @@ ospf_if_add_allspfrouters (struct ospf *top, struct prefix *p, int ret; ret = setsockopt_ipv4_multicast (top->fd, IP_ADD_MEMBERSHIP, - htonl (OSPF_ALLSPFROUTERS), + p->u.prefix4, htonl (OSPF_ALLSPFROUTERS), ifindex); if (ret < 0) zlog_warn ("can't setsockopt IP_ADD_MEMBERSHIP (fd %d, addr %s, " @@ -74,7 +74,7 @@ ospf_if_drop_allspfrouters (struct ospf *top, struct prefix *p, int ret; ret = setsockopt_ipv4_multicast (top->fd, IP_DROP_MEMBERSHIP, - htonl (OSPF_ALLSPFROUTERS), + p->u.prefix4, htonl (OSPF_ALLSPFROUTERS), ifindex); if (ret < 0) zlog_warn ("can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %s, " @@ -95,7 +95,7 @@ ospf_if_add_alldrouters (struct ospf *top, struct prefix *p, unsigned int int ret; ret = setsockopt_ipv4_multicast (top->fd, IP_ADD_MEMBERSHIP, - htonl (OSPF_ALLDROUTERS), + p->u.prefix4, htonl (OSPF_ALLDROUTERS), ifindex); if (ret < 0) zlog_warn ("can't setsockopt IP_ADD_MEMBERSHIP (fd %d, addr %s, " @@ -116,7 +116,7 @@ ospf_if_drop_alldrouters (struct ospf *top, struct prefix *p, unsigned int int ret; ret = setsockopt_ipv4_multicast (top->fd, IP_DROP_MEMBERSHIP, - htonl (OSPF_ALLDROUTERS), + p->u.prefix4, htonl (OSPF_ALLDROUTERS), ifindex); if (ret < 0) zlog_warn ("can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %s, " @@ -151,7 +151,7 @@ ospf_if_ipmulticast (struct ospf *top, struct prefix *p, unsigned int ifindex) zlog_warn ("can't setsockopt IP_MULTICAST_TTL(1) for fd %d: %s", top->fd, safe_strerror (errno)); - ret = setsockopt_ipv4_multicast_if (top->fd, ifindex); + ret = setsockopt_ipv4_multicast_if (top->fd, p->u.prefix4, ifindex); if (ret < 0) zlog_warn("can't setsockopt IP_MULTICAST_IF(fd %d, addr %s, " "ifindex %u): %s", diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c index 6748e197da..4499966ad0 100644 --- a/ripd/rip_interface.c +++ b/ripd/rip_interface.c @@ -80,6 +80,7 @@ ipv4_multicast_join (int sock, ret = setsockopt_ipv4_multicast (sock, IP_ADD_MEMBERSHIP, + ifa, group.s_addr, ifindex); @@ -101,6 +102,7 @@ ipv4_multicast_leave (int sock, ret = setsockopt_ipv4_multicast (sock, IP_DROP_MEMBERSHIP, + ifa, group.s_addr, ifindex); @@ -136,9 +138,13 @@ rip_interface_new (void) void rip_interface_multicast_set (int sock, struct connected *connected) { + struct in_addr addr; + assert (connected != NULL); - - if (setsockopt_ipv4_multicast_if (sock, connected->ifp->ifindex) < 0) + + addr = CONNECTED_ID(connected)->u.prefix4; + + if (setsockopt_ipv4_multicast_if (sock, addr, connected->ifp->ifindex) < 0) { zlog_warn ("Can't setsockopt IP_MULTICAST_IF on fd %d to " "ifindex %d for interface %s",