revert multicast changes in last upstream release, they do not work on OS
which require the interface IP address for IP_{ADD,DROP}_MEMBERSHIP reported by Raphael Mazelier
This commit is contained in:
parent
5e21b7b72c
commit
1931eaa0b1
@ -1,9 +1,9 @@
|
||||
# $OpenBSD: Makefile,v 1.31 2012/12/08 18:42:43 brad Exp $
|
||||
# $OpenBSD: Makefile,v 1.32 2013/01/04 00:24:10 sthen Exp $
|
||||
|
||||
COMMENT= multi-threaded routing daemon
|
||||
|
||||
DISTNAME= quagga-0.99.21
|
||||
REVISION= 0
|
||||
REVISION= 1
|
||||
SHARED_LIBS= ospf 0.0 \
|
||||
ospfapiclient 0.0 \
|
||||
zebra 0.0
|
||||
|
237
net/quagga/patches/patch-lib_sockopt_c
Normal file
237
net/quagga/patches/patch-lib_sockopt_c
Normal file
@ -0,0 +1,237 @@
|
||||
$OpenBSD: patch-lib_sockopt_c,v 1.1 2013/01/04 00:24:10 sthen Exp $
|
||||
|
||||
Revert 69bf3a39; does not work on at least (Open/Net)BSD.
|
||||
This can be put back if we get RFC3678 support.
|
||||
|
||||
--- lib/sockopt.c.orig Thu Jan 3 00:29:56 2013
|
||||
+++ lib/sockopt.c Thu Jan 3 00:29:45 2013
|
||||
@@ -197,7 +197,7 @@ setsockopt_ipv6_tclass(int sock, int tclass)
|
||||
|
||||
/*
|
||||
* Process multicast socket options for IPv4 in an OS-dependent manner.
|
||||
- * Supported options are IP_{ADD,DROP}_MEMBERSHIP.
|
||||
+ * Supported options are IP_MULTICAST_IF and IP_{ADD,DROP}_MEMBERSHIP.
|
||||
*
|
||||
* Many operating systems have a limit on the number of groups that
|
||||
* can be joined per socket (where each group and local address
|
||||
@@ -217,133 +217,121 @@ setsockopt_ipv6_tclass(int sock, int tclass)
|
||||
* allow leaves, or implicitly leave all groups joined to down interfaces.
|
||||
*/
|
||||
int
|
||||
-setsockopt_ipv4_multicast(int sock,
|
||||
+setsockopt_multicast_ipv4(int sock,
|
||||
int optname,
|
||||
+ struct in_addr if_addr /* required */,
|
||||
unsigned int mcast_addr,
|
||||
- unsigned int ifindex)
|
||||
+ unsigned int ifindex /* optional: if non-zero, may be
|
||||
+ used instead of if_addr */)
|
||||
{
|
||||
-#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;
|
||||
|
||||
-#elif defined(HAVE_STRUCT_IP_MREQN_IMR_IFINDEX) && !defined(__FreeBSD__)
|
||||
+#ifdef HAVE_STRUCT_IP_MREQN_IMR_IFINDEX
|
||||
+ /* This is better because it uses ifindex directly */
|
||||
struct ip_mreqn mreqn;
|
||||
int ret;
|
||||
|
||||
- assert(optname == IP_ADD_MEMBERSHIP || optname == IP_DROP_MEMBERSHIP);
|
||||
- memset (&mreqn, 0, sizeof(mreqn));
|
||||
-
|
||||
- mreqn.imr_multiaddr.s_addr = mcast_addr;
|
||||
- mreqn.imr_ifindex = ifindex;
|
||||
-
|
||||
- ret = setsockopt(sock, IPPROTO_IP, optname,
|
||||
- (void *)&mreqn, sizeof(mreqn));
|
||||
- if ((ret < 0) && (optname == IP_ADD_MEMBERSHIP) && (errno == EADDRINUSE))
|
||||
+ switch (optname)
|
||||
{
|
||||
- /* see above: handle possible problem when interface comes back up */
|
||||
- char buf[1][INET_ADDRSTRLEN];
|
||||
- zlog_info("setsockopt_ipv4_multicast attempting to drop and "
|
||||
- "re-add (fd %d, mcast %s, ifindex %u)",
|
||||
- sock,
|
||||
- inet_ntop(AF_INET, &mreqn.imr_multiaddr,
|
||||
- buf[0], sizeof(buf[0])), ifindex);
|
||||
- setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP,
|
||||
- (void *)&mreqn, sizeof(mreqn));
|
||||
- ret = setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
|
||||
- (void *)&mreqn, sizeof(mreqn));
|
||||
+ case IP_MULTICAST_IF:
|
||||
+ case IP_ADD_MEMBERSHIP:
|
||||
+ case IP_DROP_MEMBERSHIP:
|
||||
+ memset (&mreqn, 0, sizeof(mreqn));
|
||||
+
|
||||
+ if (mcast_addr)
|
||||
+ mreqn.imr_multiaddr.s_addr = mcast_addr;
|
||||
+
|
||||
+ if (ifindex)
|
||||
+ mreqn.imr_ifindex = ifindex;
|
||||
+ else
|
||||
+ mreqn.imr_address = if_addr;
|
||||
+
|
||||
+ ret = setsockopt(sock, IPPROTO_IP, optname,
|
||||
+ (void *)&mreqn, sizeof(mreqn));
|
||||
+ if ((ret < 0) && (optname == IP_ADD_MEMBERSHIP) && (errno == EADDRINUSE))
|
||||
+ {
|
||||
+ /* see above: handle possible problem when interface comes back up */
|
||||
+ char buf[2][INET_ADDRSTRLEN];
|
||||
+ zlog_info("setsockopt_multicast_ipv4 attempting to drop and "
|
||||
+ "re-add (fd %d, ifaddr %s, mcast %s, ifindex %u)",
|
||||
+ sock,
|
||||
+ inet_ntop(AF_INET, &if_addr, buf[0], sizeof(buf[0])),
|
||||
+ inet_ntop(AF_INET, &mreqn.imr_multiaddr,
|
||||
+ buf[1], sizeof(buf[1])), ifindex);
|
||||
+ setsockopt(sock, IPPROTO_IP, IP_DROP_MEMBERSHIP,
|
||||
+ (void *)&mreqn, sizeof(mreqn));
|
||||
+ ret = setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
|
||||
+ (void *)&mreqn, sizeof(mreqn));
|
||||
+ }
|
||||
+ return ret;
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ /* Can out and give an understandable error */
|
||||
+ errno = EINVAL;
|
||||
+ return -1;
|
||||
+ break;
|
||||
}
|
||||
- return ret;
|
||||
|
||||
/* Example defines for another OS, boilerplate off other code in this
|
||||
function, AND handle optname as per other sections for consistency !! */
|
||||
/* #elif defined(BOGON_NIX) && EXAMPLE_VERSION_CODE > -100000 */
|
||||
/* Add your favourite OS here! */
|
||||
|
||||
-#elif defined(HAVE_BSD_STRUCT_IP_MREQ_HACK) /* #if OS_TYPE */
|
||||
+#else /* #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);
|
||||
+#ifdef HAVE_BSD_STRUCT_IP_MREQ_HACK
|
||||
+ if (ifindex)
|
||||
+ m.s_addr = htonl(ifindex);
|
||||
+ else
|
||||
+#endif
|
||||
+ m = if_addr;
|
||||
|
||||
- m.s_addr = htonl(ifindex);
|
||||
-
|
||||
- memset (&mreq, 0, sizeof(mreq));
|
||||
- mreq.imr_multiaddr.s_addr = mcast_addr;
|
||||
- mreq.imr_interface = m;
|
||||
-
|
||||
- ret = setsockopt (sock, IPPROTO_IP, optname, (void *)&mreq, sizeof(mreq));
|
||||
- if ((ret < 0) && (optname == IP_ADD_MEMBERSHIP) && (errno == EADDRINUSE))
|
||||
+ switch (optname)
|
||||
{
|
||||
- /* see above: handle possible problem when interface comes back up */
|
||||
- char buf[1][INET_ADDRSTRLEN];
|
||||
- zlog_info("setsockopt_ipv4_multicast attempting to drop and "
|
||||
- "re-add (fd %d, mcast %s, ifindex %u)",
|
||||
- sock,
|
||||
- inet_ntop(AF_INET, &mreq.imr_multiaddr,
|
||||
- buf[0], sizeof(buf[0])), ifindex);
|
||||
- setsockopt (sock, IPPROTO_IP, IP_DROP_MEMBERSHIP,
|
||||
- (void *)&mreq, sizeof(mreq));
|
||||
- ret = setsockopt (sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
|
||||
- (void *)&mreq, sizeof(mreq));
|
||||
- }
|
||||
- return ret;
|
||||
+ case IP_MULTICAST_IF:
|
||||
+ return setsockopt (sock, IPPROTO_IP, optname, (void *)&m, sizeof(m));
|
||||
+ break;
|
||||
|
||||
-#else
|
||||
- #error "Unsupported multicast API"
|
||||
+ case IP_ADD_MEMBERSHIP:
|
||||
+ case IP_DROP_MEMBERSHIP:
|
||||
+ memset (&mreq, 0, sizeof(mreq));
|
||||
+ mreq.imr_multiaddr.s_addr = mcast_addr;
|
||||
+ mreq.imr_interface = m;
|
||||
+
|
||||
+ ret = setsockopt (sock, IPPROTO_IP, optname, (void *)&mreq, sizeof(mreq));
|
||||
+ if ((ret < 0) && (optname == IP_ADD_MEMBERSHIP) && (errno == EADDRINUSE))
|
||||
+ {
|
||||
+ /* see above: handle possible problem when interface comes back up */
|
||||
+ char buf[2][INET_ADDRSTRLEN];
|
||||
+ zlog_info("setsockopt_multicast_ipv4 attempting to drop and "
|
||||
+ "re-add (fd %d, ifaddr %s, mcast %s, ifindex %u)",
|
||||
+ sock,
|
||||
+ inet_ntop(AF_INET, &if_addr, buf[0], sizeof(buf[0])),
|
||||
+ inet_ntop(AF_INET, &mreq.imr_multiaddr,
|
||||
+ buf[1], sizeof(buf[1])), ifindex);
|
||||
+ setsockopt (sock, IPPROTO_IP, IP_DROP_MEMBERSHIP,
|
||||
+ (void *)&mreq, sizeof(mreq));
|
||||
+ ret = setsockopt (sock, IPPROTO_IP, IP_ADD_MEMBERSHIP,
|
||||
+ (void *)&mreq, sizeof(mreq));
|
||||
+ }
|
||||
+ return ret;
|
||||
+ break;
|
||||
+
|
||||
+ default:
|
||||
+ /* Can out and give an understandable error */
|
||||
+ errno = EINVAL;
|
||||
+ return -1;
|
||||
+ break;
|
||||
+ }
|
||||
#endif /* #if OS_TYPE */
|
||||
|
||||
}
|
||||
|
||||
-/*
|
||||
- * Set IP_MULTICAST_IF socket option in an OS-dependent manner.
|
||||
- */
|
||||
-int
|
||||
-setsockopt_ipv4_multicast_if(int sock,
|
||||
- unsigned int ifindex)
|
||||
-{
|
||||
-
|
||||
-#ifdef HAVE_STRUCT_IP_MREQN_IMR_IFINDEX
|
||||
- struct ip_mreqn mreqn;
|
||||
- memset (&mreqn, 0, sizeof(mreqn));
|
||||
-
|
||||
- mreqn.imr_ifindex = ifindex;
|
||||
- return setsockopt(sock, IPPROTO_IP, IP_MULTICAST_IF, (void *)&mreqn, sizeof(mreqn));
|
||||
-
|
||||
- /* Example defines for another OS, boilerplate off other code in this
|
||||
- function */
|
||||
- /* #elif defined(BOGON_NIX) && EXAMPLE_VERSION_CODE > -100000 */
|
||||
- /* Add your favourite OS here! */
|
||||
-#elif defined(HAVE_BSD_STRUCT_IP_MREQ_HACK)
|
||||
- struct in_addr m;
|
||||
-
|
||||
- m.s_addr = htonl(ifindex);
|
||||
-
|
||||
- return setsockopt (sock, IPPROTO_IP, IP_MULTICAST_IF, (void *)&m, sizeof(m));
|
||||
-#else
|
||||
- #error "Unsupported multicast API"
|
||||
-#endif
|
||||
-}
|
||||
-
|
||||
static int
|
||||
setsockopt_ipv4_ifindex (int sock, int val)
|
||||
{
|
25
net/quagga/patches/patch-lib_sockopt_h
Normal file
25
net/quagga/patches/patch-lib_sockopt_h
Normal file
@ -0,0 +1,25 @@
|
||||
$OpenBSD: patch-lib_sockopt_h,v 1.1 2013/01/04 00:24:10 sthen Exp $
|
||||
|
||||
Revert 69bf3a39; does not work on at least (Open/Net)BSD.
|
||||
This can be put back if we get RFC3678 support.
|
||||
|
||||
--- lib/sockopt.h.orig Tue Apr 17 14:56:26 2012
|
||||
+++ lib/sockopt.h Thu Jan 3 00:24:26 2013
|
||||
@@ -83,11 +83,13 @@ 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,
|
||||
- unsigned int ifindex);
|
||||
-extern int setsockopt_ipv4_multicast(int sock, int optname,
|
||||
+extern int setsockopt_multicast_ipv4(int sock, int optname,
|
||||
+ struct in_addr if_addr
|
||||
+ /* required: interface to join on */,
|
||||
unsigned int mcast_addr,
|
||||
- unsigned int ifindex);
|
||||
+ unsigned int ifindex
|
||||
+ /* optional: if non-zero, may be used
|
||||
+ instead of if_addr */);
|
||||
extern int setsockopt_ipv4_tos(int sock, int tos);
|
||||
|
||||
/* Ask for, and get, ifindex, by whatever method is supported. */
|
61
net/quagga/patches/patch-ospfd_ospf_network_c
Normal file
61
net/quagga/patches/patch-ospfd_ospf_network_c
Normal file
@ -0,0 +1,61 @@
|
||||
$OpenBSD: patch-ospfd_ospf_network_c,v 1.1 2013/01/04 00:24:10 sthen Exp $
|
||||
|
||||
Revert 69bf3a39; does not work on at least (Open/Net)BSD.
|
||||
This can be put back if we get RFC3678 support.
|
||||
|
||||
--- ospfd/ospf_network.c.orig Tue Apr 17 14:56:26 2012
|
||||
+++ ospfd/ospf_network.c Thu Jan 3 00:24:26 2013
|
||||
@@ -52,8 +52,8 @@ ospf_if_add_allspfrouters (struct ospf *top, struct pr
|
||||
{
|
||||
int ret;
|
||||
|
||||
- ret = setsockopt_ipv4_multicast (top->fd, IP_ADD_MEMBERSHIP,
|
||||
- htonl (OSPF_ALLSPFROUTERS),
|
||||
+ ret = setsockopt_multicast_ipv4 (top->fd, IP_ADD_MEMBERSHIP,
|
||||
+ p->u.prefix4, htonl (OSPF_ALLSPFROUTERS),
|
||||
ifindex);
|
||||
if (ret < 0)
|
||||
zlog_warn ("can't setsockopt IP_ADD_MEMBERSHIP (fd %d, addr %s, "
|
||||
@@ -73,8 +73,8 @@ ospf_if_drop_allspfrouters (struct ospf *top, struct p
|
||||
{
|
||||
int ret;
|
||||
|
||||
- ret = setsockopt_ipv4_multicast (top->fd, IP_DROP_MEMBERSHIP,
|
||||
- htonl (OSPF_ALLSPFROUTERS),
|
||||
+ ret = setsockopt_multicast_ipv4 (top->fd, IP_DROP_MEMBERSHIP,
|
||||
+ p->u.prefix4, htonl (OSPF_ALLSPFROUTERS),
|
||||
ifindex);
|
||||
if (ret < 0)
|
||||
zlog_warn ("can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %s, "
|
||||
@@ -94,8 +94,8 @@ ospf_if_add_alldrouters (struct ospf *top, struct pref
|
||||
{
|
||||
int ret;
|
||||
|
||||
- ret = setsockopt_ipv4_multicast (top->fd, IP_ADD_MEMBERSHIP,
|
||||
- htonl (OSPF_ALLDROUTERS),
|
||||
+ ret = setsockopt_multicast_ipv4 (top->fd, IP_ADD_MEMBERSHIP,
|
||||
+ p->u.prefix4, htonl (OSPF_ALLDROUTERS),
|
||||
ifindex);
|
||||
if (ret < 0)
|
||||
zlog_warn ("can't setsockopt IP_ADD_MEMBERSHIP (fd %d, addr %s, "
|
||||
@@ -115,8 +115,8 @@ ospf_if_drop_alldrouters (struct ospf *top, struct pre
|
||||
{
|
||||
int ret;
|
||||
|
||||
- ret = setsockopt_ipv4_multicast (top->fd, IP_DROP_MEMBERSHIP,
|
||||
- htonl (OSPF_ALLDROUTERS),
|
||||
+ ret = setsockopt_multicast_ipv4 (top->fd, IP_DROP_MEMBERSHIP,
|
||||
+ 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,8 @@ ospf_if_ipmulticast (struct ospf *top, struct prefix *
|
||||
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_multicast_ipv4 (top->fd, IP_MULTICAST_IF,
|
||||
+ p->u.prefix4, 0, ifindex);
|
||||
if (ret < 0)
|
||||
zlog_warn("can't setsockopt IP_MULTICAST_IF(fd %d, addr %s, "
|
||||
"ifindex %u): %s",
|
51
net/quagga/patches/patch-ripd_rip_interface_c
Normal file
51
net/quagga/patches/patch-ripd_rip_interface_c
Normal file
@ -0,0 +1,51 @@
|
||||
$OpenBSD: patch-ripd_rip_interface_c,v 1.1 2013/01/04 00:24:10 sthen Exp $
|
||||
|
||||
Revert 69bf3a39; does not work on at least (Open/Net)BSD.
|
||||
This can be put back if we get RFC3678 support.
|
||||
|
||||
--- ripd/rip_interface.c.orig Tue Apr 17 14:56:26 2012
|
||||
+++ ripd/rip_interface.c Thu Jan 3 00:24:26 2013
|
||||
@@ -78,8 +78,9 @@ ipv4_multicast_join (int sock,
|
||||
{
|
||||
int ret;
|
||||
|
||||
- ret = setsockopt_ipv4_multicast (sock,
|
||||
+ ret = setsockopt_multicast_ipv4 (sock,
|
||||
IP_ADD_MEMBERSHIP,
|
||||
+ ifa,
|
||||
group.s_addr,
|
||||
ifindex);
|
||||
|
||||
@@ -99,8 +100,9 @@ ipv4_multicast_leave (int sock,
|
||||
{
|
||||
int ret;
|
||||
|
||||
- ret = setsockopt_ipv4_multicast (sock,
|
||||
+ ret = setsockopt_multicast_ipv4 (sock,
|
||||
IP_DROP_MEMBERSHIP,
|
||||
+ ifa,
|
||||
group.s_addr,
|
||||
ifindex);
|
||||
|
||||
@@ -136,13 +138,18 @@ 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_multicast_ipv4 (sock, IP_MULTICAST_IF, addr, 0,
|
||||
+ connected->ifp->ifindex) < 0)
|
||||
{
|
||||
zlog_warn ("Can't setsockopt IP_MULTICAST_IF on fd %d to "
|
||||
- "ifindex %d for interface %s",
|
||||
- sock, connected->ifp->ifindex,
|
||||
+ "source address %s for interface %s",
|
||||
+ sock, inet_ntoa(addr),
|
||||
connected->ifp->name);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user