#include "ospfd/ospf_lsdb.h"
#include "ospfd/ospf_neighbor.h"
#include "ospfd/ospf_packet.h"
+#include "ospfd/ospf_dump.h"
{
int ret;
- ret = setsockopt_multicast_ipv4 (top->fd, IP_ADD_MEMBERSHIP,
- p->u.prefix4, htonl (OSPF_ALLSPFROUTERS),
+ ret = setsockopt_ipv4_multicast (top->fd, IP_ADD_MEMBERSHIP,
+ htonl (OSPF_ALLSPFROUTERS),
ifindex);
if (ret < 0)
zlog_warn ("can't setsockopt IP_ADD_MEMBERSHIP (fd %d, addr %s, "
"on # of multicast group memberships has been exceeded?",
top->fd, inet_ntoa(p->u.prefix4), ifindex, safe_strerror(errno));
else
- zlog_info ("interface %s join AllSPFRouters Multicast group.",
- inet_ntoa (p->u.prefix4));
+ zlog_debug ("interface %s [%u] join AllSPFRouters Multicast group.",
+ inet_ntoa (p->u.prefix4), ifindex);
return ret;
}
{
int ret;
- ret = setsockopt_multicast_ipv4 (top->fd, IP_DROP_MEMBERSHIP,
- p->u.prefix4, htonl (OSPF_ALLSPFROUTERS),
+ ret = setsockopt_ipv4_multicast (top->fd, IP_DROP_MEMBERSHIP,
+ htonl (OSPF_ALLSPFROUTERS),
ifindex);
if (ret < 0)
zlog_warn ("can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %s, "
"ifindex %u, AllSPFRouters): %s",
top->fd, inet_ntoa(p->u.prefix4), ifindex, safe_strerror(errno));
else
- zlog_info ("interface %s leave AllSPFRouters Multicast group.",
- inet_ntoa (p->u.prefix4));
+ zlog_debug ("interface %s [%u] leave AllSPFRouters Multicast group.",
+ inet_ntoa (p->u.prefix4), ifindex);
return ret;
}
{
int ret;
- ret = setsockopt_multicast_ipv4 (top->fd, IP_ADD_MEMBERSHIP,
- p->u.prefix4, htonl (OSPF_ALLDROUTERS),
+ ret = setsockopt_ipv4_multicast (top->fd, IP_ADD_MEMBERSHIP,
+ htonl (OSPF_ALLDROUTERS),
ifindex);
if (ret < 0)
zlog_warn ("can't setsockopt IP_ADD_MEMBERSHIP (fd %d, addr %s, "
"on # of multicast group memberships has been exceeded?",
top->fd, inet_ntoa(p->u.prefix4), ifindex, safe_strerror(errno));
else
- zlog_info ("interface %s join AllDRouters Multicast group.",
- inet_ntoa (p->u.prefix4));
+ zlog_debug ("interface %s [%u] join AllDRouters Multicast group.",
+ inet_ntoa (p->u.prefix4), ifindex);
return ret;
}
{
int ret;
- ret = setsockopt_multicast_ipv4 (top->fd, IP_DROP_MEMBERSHIP,
- p->u.prefix4, htonl (OSPF_ALLDROUTERS),
+ ret = setsockopt_ipv4_multicast (top->fd, IP_DROP_MEMBERSHIP,
+ htonl (OSPF_ALLDROUTERS),
ifindex);
if (ret < 0)
zlog_warn ("can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %s, "
"ifindex %u, AllDRouters): %s",
top->fd, inet_ntoa(p->u.prefix4), ifindex, safe_strerror(errno));
else
- zlog_info ("interface %s leave AllDRouters Multicast group.",
- inet_ntoa (p->u.prefix4));
+ zlog_debug ("interface %s [%u] leave AllDRouters Multicast group.",
+ inet_ntoa (p->u.prefix4), ifindex);
return ret;
}
zlog_warn ("can't setsockopt IP_MULTICAST_TTL(1) for fd %d: %s",
top->fd, safe_strerror (errno));
- ret = setsockopt_multicast_ipv4 (top->fd, IP_MULTICAST_IF,
- p->u.prefix4, 0, ifindex);
+ ret = setsockopt_ipv4_multicast_if (top->fd, ifindex);
if (ret < 0)
zlog_warn("can't setsockopt IP_MULTICAST_IF(fd %d, addr %s, "
"ifindex %u): %s",
ospf_sock_init (void)
{
int ospf_sock;
- /*
- * XXX warning: unused variable `tos'
- * tos should be ifdefed similarly to usage
- */
- int ret, tos, hincl = 1;
+ int ret, hincl = 1;
+ int bufsize = (8 * 1024 * 1024);
+ int optval;
+ socklen_t optlen = sizeof(optval);
if ( ospfd_privs.change (ZPRIVS_RAISE) )
zlog_err ("ospf_sock_init: could not raise privs, %s",
ospf_sock = socket (AF_INET, SOCK_RAW, IPPROTO_OSPFIGP);
if (ospf_sock < 0)
{
+ int save_errno = errno;
if ( ospfd_privs.change (ZPRIVS_LOWER) )
zlog_err ("ospf_sock_init: could not lower privs, %s",
safe_strerror (errno) );
- zlog_err ("ospf_read_sock_init: socket: %s", safe_strerror (errno));
- exit(-1);
+ zlog_err ("ospf_read_sock_init: socket: %s", safe_strerror (save_errno));
+ exit(1);
}
#ifdef IP_HDRINCL
ret = setsockopt (ospf_sock, IPPROTO_IP, IP_HDRINCL, &hincl, sizeof (hincl));
if (ret < 0)
{
+ int save_errno = errno;
if ( ospfd_privs.change (ZPRIVS_LOWER) )
zlog_err ("ospf_sock_init: could not lower privs, %s",
safe_strerror (errno) );
- zlog_warn ("Can't set IP_HDRINCL option for fd %d",ospf_sock);
+ zlog_warn ("Can't set IP_HDRINCL option for fd %d: %s",
+ ospf_sock, safe_strerror(save_errno));
}
#elif defined (IPTOS_PREC_INTERNETCONTROL)
#warning "IP_HDRINCL not available on this system"
#warning "using IPTOS_PREC_INTERNETCONTROL"
- /* Set precedence field. */
- tos = IPTOS_PREC_INTERNETCONTROL;
- ret = setsockopt (ospf_sock, IPPROTO_IP, IP_TOS,
- (char *) &tos, sizeof (int));
+ ret = setsockopt_ipv4_tos(ospf_sock, IPTOS_PREC_INTERNETCONTROL);
if (ret < 0)
{
+ int save_errno = errno;
if ( ospfd_privs.change (ZPRIVS_LOWER) )
zlog_err ("ospf_sock_init: could not lower privs, %s",
safe_strerror (errno) );
- zlog_warn ("can't set sockopt IP_TOS %d to socket %d", tos, ospf_sock);
+ zlog_warn ("can't set sockopt IP_TOS %d to socket %d: %s",
+ tos, ospf_sock, safe_strerror(save_errno));
close (ospf_sock); /* Prevent sd leak. */
return ret;
}
zlog_err ("ospf_sock_init: could not lower privs, %s",
safe_strerror (errno) );
}
+
+ if ((ret = setsockopt (ospf_sock, SOL_SOCKET, SO_RCVBUF,
+ &bufsize, sizeof (bufsize))) < 0)
+ {
+ zlog_err ("Couldn't increase raw rbuf size: %s\n", safe_strerror(errno));
+ }
+
+ if ((ret = getsockopt (ospf_sock, SOL_SOCKET, SO_RCVBUF,
+ &optval, &optlen)) < 0)
+ {
+ zlog_err("getsockopt of SO_RCVBUF failed with error %s\n", safe_strerror(errno));
+ }
+ if (optval < bufsize)
+ {
+ zlog_err("Unable to SO_RCVBUF to %d, set to %d\n", bufsize, optval);
+ }
+
+
+ if ((ret = setsockopt (ospf_sock, SOL_SOCKET, SO_SNDBUF,
+ &bufsize, sizeof (bufsize))) < 0)
+ {
+ zlog_err ("Couldn't increase raw wbuf size: %s\n", safe_strerror(errno));
+ }
+
+ if ((ret = getsockopt (ospf_sock, SOL_SOCKET, SO_SNDBUF,
+ &optval, &optlen)) < 0)
+ {
+ zlog_err ("getsockopt of SO_SNDBUF failed with error %s\n", safe_strerror(errno));
+ }
+ if (optval < bufsize)
+ {
+ zlog_err ("Unable to SO_SNDBUF to %d, set to %d\n", bufsize, optval);
+ }
return ospf_sock;
}
+
+void
+ospf_adjust_sndbuflen (struct ospf * ospf, unsigned int buflen)
+{
+ int ret, newbuflen;
+ /* Check if any work has to be done at all. */
+ if (ospf->maxsndbuflen >= buflen)
+ return;
+ if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE))
+ zlog_debug ("%s: adjusting OSPF send buffer size to %d",
+ __func__, buflen);
+ if (ospfd_privs.change (ZPRIVS_RAISE))
+ zlog_err ("%s: could not raise privs, %s", __func__,
+ safe_strerror (errno));
+ /* Now we try to set SO_SNDBUF to what our caller has requested
+ * (the MTU of a newly added interface). However, if the OS has
+ * truncated the actual buffer size to somewhat less size, try
+ * to detect it and update our records appropriately. The OS
+ * may allocate more buffer space, than requested, this isn't
+ * a error.
+ */
+ ret = setsockopt_so_sendbuf (ospf->fd, buflen);
+ newbuflen = getsockopt_so_sendbuf (ospf->fd);
+ if (ret < 0 || newbuflen < 0 || newbuflen < (int) buflen)
+ zlog_warn ("%s: tried to set SO_SNDBUF to %u, but got %d",
+ __func__, buflen, newbuflen);
+ if (newbuflen >= 0)
+ ospf->maxsndbuflen = (unsigned int)newbuflen;
+ else
+ zlog_warn ("%s: failed to get SO_SNDBUF", __func__);
+ if (ospfd_privs.change (ZPRIVS_LOWER))
+ zlog_err ("%s: could not lower privs, %s", __func__,
+ safe_strerror (errno));
+}