diff options
Diffstat (limited to '')
-rw-r--r-- | net/quagga/files/patch-cvs-5-sendbuffer | 294 |
1 files changed, 294 insertions, 0 deletions
diff --git a/net/quagga/files/patch-cvs-5-sendbuffer b/net/quagga/files/patch-cvs-5-sendbuffer new file mode 100644 index 000000000000..52187f7e0426 --- /dev/null +++ b/net/quagga/files/patch-cvs-5-sendbuffer @@ -0,0 +1,294 @@ +--- lib/sockopt.c.orig 2007-07-09 16:36:45.000000000 +0400 ++++ lib/sockopt.c 2007-08-02 17:38:50.000000000 +0400 +@@ -29,20 +29,49 @@ + int ret; + + if ( (ret = setsockopt (sock, SOL_SOCKET, SO_RCVBUF, (char *) + &size, sizeof (int))) < 0) + zlog_err ("fd %d: can't setsockopt SO_RCVBUF to %d: %s", + sock,size,safe_strerror(errno)); + + return ret; + } + ++int ++setsockopt_so_sendbuf (const int sock, int size) ++{ ++ int ret = setsockopt (sock, SOL_SOCKET, SO_SNDBUF, ++ (char *)&size, sizeof (int)); ++ ++ if (ret < 0) ++ zlog_err ("fd %d: can't setsockopt SO_SNDBUF to %d: %s", ++ sock, size, safe_strerror (errno)); ++ ++ return ret; ++} ++ ++int ++getsockopt_so_sendbuf (const int sock) ++{ ++ u_int32_t optval; ++ socklen_t optlen = sizeof (optval); ++ int ret = getsockopt (sock, SOL_SOCKET, SO_SNDBUF, ++ (char *)&optval, &optlen); ++ if (ret < 0) ++ { ++ zlog_err ("fd %d: can't getsockopt SO_SNDBUF: %d (%s)", ++ sock, errno, safe_strerror (errno)); ++ return ret; ++ } ++ return optval; ++} ++ + static void * + getsockopt_cmsg_data (struct msghdr *msgh, int level, int type) + { + struct cmsghdr *cmsg; + void *ptr = NULL; + + for (cmsg = ZCMSG_FIRSTHDR(msgh); + cmsg != NULL; + cmsg = CMSG_NXTHDR(msgh, cmsg)) + if (cmsg->cmsg_level == level && cmsg->cmsg_type) +--- lib/sockopt.h.orig 2007-07-09 16:36:45.000000000 +0400 ++++ lib/sockopt.h 2007-08-01 17:37:33.000000000 +0400 +@@ -16,20 +16,22 @@ + * You should have received a copy of the GNU General Public License + * along with GNU Zebra; see the file COPYING. If not, write to the Free + * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + * 02111-1307, USA. + */ + + #ifndef _ZEBRA_SOCKOPT_H + #define _ZEBRA_SOCKOPT_H + + extern int setsockopt_so_recvbuf (int sock, int size); ++extern int setsockopt_so_sendbuf (const int sock, int size); ++extern int getsockopt_so_sendbuf (const int sock); + + #ifdef HAVE_IPV6 + extern int setsockopt_ipv6_pktinfo (int, int); + extern int setsockopt_ipv6_checksum (int, int); + extern int setsockopt_ipv6_multicast_hops (int, int); + extern int setsockopt_ipv6_unicast_hops (int, int); + extern int setsockopt_ipv6_hoplimit (int, int); + extern int setsockopt_ipv6_multicast_loop (int, int); + #endif /* HAVE_IPV6 */ + +--- ospfd/ospfd.c.orig 2007-05-01 03:42:20.000000000 +0400 ++++ ospfd/ospfd.c 2007-08-01 19:07:46.000000000 +0400 +@@ -205,20 +205,22 @@ + new->t_lsa_refresher = thread_add_timer (master, ospf_lsa_refresh_walker, + new, new->lsa_refresh_interval); + new->lsa_refresher_started = quagga_time (NULL); + + if ((new->fd = ospf_sock_init()) < 0) + { + zlog_err("ospf_new: fatal error: ospf_sock_init was unable to open " + "a socket"); + exit(1); + } ++ new->maxsndbuflen = 0; ++ ospf_adjust_sndbuflen (new, OSPF_SNDBUFLEN_DEFAULT); + if ((new->ibuf = stream_new(OSPF_MAX_PACKET_SIZE+1)) == NULL) + { + zlog_err("ospf_new: fatal error: stream_new(%u) failed allocating ibuf", + OSPF_MAX_PACKET_SIZE+1); + exit(1); + } + new->t_read = thread_add_read (master, ospf_read, new, new->fd); + new->oi_write_q = list_new (); + + return new; +--- ospfd/ospfd.h.orig 2006-10-18 00:45:04.000000000 +0400 ++++ ospfd/ospfd.h 2007-08-01 17:10:36.000000000 +0400 +@@ -122,20 +122,23 @@ + + /* OSPF Database Description flags. */ + #define OSPF_DD_FLAG_MS 0x01 + #define OSPF_DD_FLAG_M 0x02 + #define OSPF_DD_FLAG_I 0x04 + #define OSPF_DD_FLAG_ALL 0x07 + + #define OSPF_LS_REFRESH_SHIFT (60 * 15) + #define OSPF_LS_REFRESH_JITTER 60 + ++/* Initial send buffer size for ospfd raw sending socket. */ ++#define OSPF_SNDBUFLEN_DEFAULT 1024 ++ + /* OSPF master for system wide configuration and variables. */ + struct ospf_master + { + /* OSPF instance. */ + struct list *ospf; + + /* OSPF thread master. */ + struct thread_master *master; + + /* Zebra interface list. */ +@@ -259,20 +262,21 @@ + #ifdef HAVE_OPAQUE_LSA + struct thread *t_opaque_lsa_self; /* Type-11 Opaque-LSAs origin event. */ + #endif /* HAVE_OPAQUE_LSA */ + struct thread *t_maxage; /* MaxAge LSA remover timer. */ + struct thread *t_maxage_walker; /* MaxAge LSA checking timer. */ + struct thread *t_deferred_shutdown; /* deferred/stub-router shutdown timer*/ + + struct thread *t_write; + struct thread *t_read; + int fd; ++ int maxsndbuflen; + struct stream *ibuf; + struct list *oi_write_q; + + /* Distribute lists out of other route sources. */ + struct + { + char *name; + struct access_list *list; + } dlist[ZEBRA_ROUTE_MAX]; + #define DISTRIBUTE_NAME(O,T) (O)->dlist[T].name +--- ospfd/ospf_interface.c.orig 2007-04-22 17:26:38.000000000 +0400 ++++ ospfd/ospf_interface.c 2007-08-02 18:31:53.000000000 +0400 +@@ -774,20 +774,25 @@ + int + ospf_if_up (struct ospf_interface *oi) + { + if (oi == NULL) + return 0; + + if (oi->type == OSPF_IFTYPE_LOOPBACK) + OSPF_ISM_EVENT_SCHEDULE (oi, ISM_LoopInd); + else + { ++ struct ospf *ospf = ospf_lookup (); ++ if (ospf != NULL) ++ ospf_adjust_sndbuflen (ospf, oi->ifp->mtu); ++ else ++ zlog_warn ("%s: ospf_lookup() returned NULL"); + ospf_if_stream_set (oi); + OSPF_ISM_EVENT_SCHEDULE (oi, ISM_InterfaceUp); + } + + return 1; + } + + int + ospf_if_down (struct ospf_interface *oi) + { +--- ospfd/ospf_network.c.orig 2005-05-09 22:37:56.000000000 +0400 ++++ ospfd/ospf_network.c 2007-08-01 20:03:26.000000000 +0400 +@@ -34,20 +34,21 @@ + extern struct zebra_privs_t ospfd_privs; + + #include "ospfd/ospfd.h" + #include "ospfd/ospf_network.h" + #include "ospfd/ospf_interface.h" + #include "ospfd/ospf_asbr.h" + #include "ospfd/ospf_lsa.h" + #include "ospfd/ospf_lsdb.h" + #include "ospfd/ospf_neighbor.h" + #include "ospfd/ospf_packet.h" ++#include "ospfd/ospf_dump.h" + + + + /* Join to the OSPF ALL SPF ROUTERS multicast group. */ + int + ospf_if_add_allspfrouters (struct ospf *top, struct prefix *p, + unsigned int ifindex) + { + int ret; + +@@ -226,10 +227,44 @@ + zlog_warn ("Can't set pktinfo option for fd %d", ospf_sock); + + if (ospfd_privs.change (ZPRIVS_LOWER)) + { + zlog_err ("ospf_sock_init: could not lower privs, %s", + safe_strerror (errno) ); + } + + return ospf_sock; + } ++ ++void ++ospf_adjust_sndbuflen (struct ospf * ospf, 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 ++ * (OSPF_SNDBUFLEN_DEFAULT initially, which seems to be a sane ++ * default; or the MTU of a newly added interface). However, ++ * if the OS has truncated the actual buffer size to somewhat ++ * less or bigger size, try to detect it and update our records ++ * appropriately. ++ */ ++ ret = setsockopt_so_sendbuf (ospf->fd, buflen); ++ newbuflen = getsockopt_so_sendbuf (ospf->fd); ++ if (ret < 0 || newbuflen != buflen) ++ zlog_warn ("%s: tried to set SO_SNDBUF to %d, but got %d", ++ __func__, buflen, newbuflen); ++ if (newbuflen >= 0) ++ ospf->maxsndbuflen = 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)); ++} +--- ospfd/ospf_network.h.orig 2005-05-06 21:26:18.000000000 +0400 ++++ ospfd/ospf_network.h 2007-08-01 19:17:11.000000000 +0400 +@@ -27,12 +27,13 @@ + extern int ospf_if_add_allspfrouters (struct ospf *, struct prefix *, + unsigned int); + extern int ospf_if_drop_allspfrouters (struct ospf *, struct prefix *, + unsigned int); + extern int ospf_if_add_alldrouters (struct ospf *, struct prefix *, + unsigned int); + extern int ospf_if_drop_alldrouters (struct ospf *, struct prefix *, + unsigned int); + extern int ospf_if_ipmulticast (struct ospf *, struct prefix *, unsigned int); + extern int ospf_sock_init (void); ++extern void ospf_adjust_sndbuflen (struct ospf *, int); + + #endif /* _ZEBRA_OSPF_NETWORK_H */ +--- ospfd/ospf_packet.c.orig 2007-05-10 00:59:34.000000000 +0400 ++++ ospfd/ospf_packet.c 2007-08-01 18:32:36.000000000 +0400 +@@ -595,22 +595,26 @@ + assert (node); + oi = listgetdata (node); + assert (oi); + + #ifdef WANT_OSPF_WRITE_FRAGMENT + /* seed ipid static with low order bits of time */ + if (ipid == 0) + ipid = (time(NULL) & 0xffff); + #endif /* WANT_OSPF_WRITE_FRAGMENT */ + +- /* convenience - max OSPF data per packet */ +- maxdatasize = oi->ifp->mtu - sizeof (struct ip); ++ /* convenience - max OSPF data per packet, ++ * and reliability - not more data, than our ++ * socket can accept ++ */ ++ maxdatasize = MIN (oi->ifp->mtu, ospf->maxsndbuflen) - ++ sizeof (struct ip); + + /* Get one packet from queue. */ + op = ospf_fifo_head (oi->obuf); + assert (op); + assert (op->length >= OSPF_HEADER_SIZE); + + if (op->dst.s_addr == htonl (OSPF_ALLSPFROUTERS) + || op->dst.s_addr == htonl (OSPF_ALLDROUTERS)) + ospf_if_ipmulticast (ospf, oi->address, oi->ifp->ifindex); + |