mirror of
https://github.com/FRRouting/frr.git
synced 2025-04-30 13:37:17 +02:00
lib: use "protocol-independed API" from RFC3678, if that is available
(This commit is based on the patch from BZ#420, and should fix that bug.) * configure.ac: detect availability of that API * sockopt.c (setsockopt_ipv4_multicast): use it for join/leave IPv4 multicast groups
This commit is contained in:
parent
ee7e75d38b
commit
10d04cdb41
|
@ -943,6 +943,15 @@ AC_TRY_COMPILE([#ifdef HAVE_SYS_PARAM_H
|
||||||
AC_DEFINE(HAVE_BSD_STRUCT_IP_MREQ_HACK,,[Can pass ifindex in struct ip_mreq])],
|
AC_DEFINE(HAVE_BSD_STRUCT_IP_MREQ_HACK,,[Can pass ifindex in struct ip_mreq])],
|
||||||
AC_MSG_RESULT(no))
|
AC_MSG_RESULT(no))
|
||||||
|
|
||||||
|
AC_MSG_CHECKING([for RFC3678 protocol-independed API])
|
||||||
|
AC_TRY_COMPILE([
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
], [struct group_req gr; int sock; setsockopt(sock, IPPROTO_IP, MCAST_JOIN_GROUP, (void*)&gr, sizeof(gr));
|
||||||
|
], [AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(HAVE_RFC3678,1,[Have RFC3678 protocol-independed API])],
|
||||||
|
AC_MSG_RESULT(no))
|
||||||
|
|
||||||
dnl ---------------------------------------------------------------
|
dnl ---------------------------------------------------------------
|
||||||
dnl figure out how to check link-state
|
dnl figure out how to check link-state
|
||||||
dnl ---------------------------------------------------------------
|
dnl ---------------------------------------------------------------
|
||||||
|
|
|
@ -209,17 +209,35 @@ setsockopt_ipv4_multicast(int sock,
|
||||||
unsigned int mcast_addr,
|
unsigned int mcast_addr,
|
||||||
unsigned int ifindex)
|
unsigned int ifindex)
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_RFC3678
|
||||||
|
struct group_req gr;
|
||||||
|
struct sockaddr_in *si;
|
||||||
|
int ret;
|
||||||
|
memset (&gr, 0, sizeof(gr));
|
||||||
|
si = (struct sockaddr_in *)&gr.gr_group;
|
||||||
|
gr.gr_interface = ifindex;
|
||||||
|
si->sin_family = AF_INET;
|
||||||
|
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
|
||||||
|
si->sin_len = sizeof(struct sockaddr_in);
|
||||||
|
#endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */
|
||||||
|
si->sin_addr.s_addr = mcast_addr;
|
||||||
|
ret = setsockopt(sock, IPPROTO_IP, (optname == IP_ADD_MEMBERSHIP) ?
|
||||||
|
MCAST_JOIN_GROUP : MCAST_LEAVE_GROUP, (void *)&gr, sizeof(gr));
|
||||||
|
if ((ret < 0) && (optname == IP_ADD_MEMBERSHIP) && (errno == EADDRINUSE))
|
||||||
|
{
|
||||||
|
setsockopt(sock, IPPROTO_IP, MCAST_LEAVE_GROUP, (void *)&gr, sizeof(gr));
|
||||||
|
ret = setsockopt(sock, IPPROTO_IP, MCAST_JOIN_GROUP, (void *)&gr, sizeof(gr));
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
|
||||||
#ifdef HAVE_STRUCT_IP_MREQN_IMR_IFINDEX
|
#elif defined(HAVE_STRUCT_IP_MREQN_IMR_IFINDEX) && !defined(__FreeBSD__)
|
||||||
struct ip_mreqn mreqn;
|
struct ip_mreqn mreqn;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
assert(optname == IP_ADD_MEMBERSHIP || optname == IP_DROP_MEMBERSHIP);
|
assert(optname == IP_ADD_MEMBERSHIP || optname == IP_DROP_MEMBERSHIP);
|
||||||
memset (&mreqn, 0, sizeof(mreqn));
|
memset (&mreqn, 0, sizeof(mreqn));
|
||||||
|
|
||||||
if (mcast_addr)
|
mreqn.imr_multiaddr.s_addr = mcast_addr;
|
||||||
mreqn.imr_multiaddr.s_addr = mcast_addr;
|
|
||||||
|
|
||||||
mreqn.imr_ifindex = ifindex;
|
mreqn.imr_ifindex = ifindex;
|
||||||
|
|
||||||
ret = setsockopt(sock, IPPROTO_IP, optname,
|
ret = setsockopt(sock, IPPROTO_IP, optname,
|
||||||
|
|
Loading…
Reference in a new issue