summaryrefslogtreecommitdiff
path: root/bgpd/bgp_packet.c
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@vyatta.com>2010-08-05 10:26:25 -0700
committerPaul Jakma <paul@quagga.net>2011-03-21 17:30:52 +0000
commiteac5702d06ee574e9e155c4e60c251e525dc4149 (patch)
tree0b2fc1b7ff7432d21df8e0346736f6bf2f25287a /bgpd/bgp_packet.c
parent58192df7746231fbc82e248b5ddfc7cab95ab1e7 (diff)
bgpd: enable TCP corking
* bgp_packet.c: (bgp_write) On BGP write, use TCP_CORK to provide hints to kernel about TCP buffering. This will cause BGP packets to occur in bigger chunks (full size MTU), improving performance and getting rid of one of the problems reported in the UNH BGP conformance test.
Diffstat (limited to 'bgpd/bgp_packet.c')
-rw-r--r--bgpd/bgp_packet.c32
1 files changed, 18 insertions, 14 deletions
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index 5620e0c4..1d6b9eef 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -610,15 +610,16 @@ bgp_write (struct thread *thread)
return 0;
}
- /* Nonblocking write until TCP output buffer is full. */
- while (1)
+ s = bgp_write_packet (peer);
+ if (!s)
+ return 0; /* nothing to send */
+
+ sockopt_cork (peer->fd, 1);
+
+ /* Nonblocking write until TCP output buffer is full. */
+ do
{
int writenum;
- int val;
-
- s = bgp_write_packet (peer);
- if (! s)
- return 0;
/* Number of bytes to be sent. */
writenum = stream_get_endp (s) - stream_get_getp (s);
@@ -627,9 +628,11 @@ bgp_write (struct thread *thread)
num = write (peer->fd, STREAM_PNT (s), writenum);
if (num < 0)
{
- /* need to try again */
- if (!ERRNO_IO_RETRY(errno))
- BGP_EVENT_ADD (peer, TCP_fatal_error);
+ /* write failed either retry needed or error */
+ if (ERRNO_IO_RETRY(errno))
+ break;
+
+ BGP_EVENT_ADD (peer, TCP_fatal_error);
return 0;
}
@@ -637,7 +640,7 @@ bgp_write (struct thread *thread)
{
/* Partial write */
stream_forward_getp (s, num);
- continue;
+ break;
}
/* Retrieve BGP packet type. */
@@ -678,13 +681,14 @@ bgp_write (struct thread *thread)
/* OK we send packet so delete it. */
bgp_packet_delete (peer);
-
- if (++count >= BGP_WRITE_PACKET_MAX)
- break;
}
+ while (++count < BGP_WRITE_PACKET_MAX &&
+ (s = bgp_write_packet (peer)) != NULL);
if (bgp_write_proceed (peer))
BGP_WRITE_ON (peer->t_write, bgp_write, peer->fd);
+ else
+ sockopt_cork (peer->fd, 0);
return 0;
}