]> git.puffer.fish Git - mirror/frr.git/commitdiff
bgpd: write NOTIFY non-blockingly
authorDavid Lamparter <equinox@opensourcerouting.org>
Wed, 31 Jul 2013 12:39:41 +0000 (14:39 +0200)
committerDavid Lamparter <equinox@opensourcerouting.org>
Wed, 31 Jul 2013 12:44:24 +0000 (14:44 +0200)
switching the socket to blocking may well block the entire bgpd process
for some time if our peer is overloaded (which may well be the original
reason for the NOTIFY)

The error handling is slightly different from the previous ML discussion
on this;  buffer exhaustion isn't technically a fatal TCP error, and we
should probably proceed with FSM actions according to a sent NOTIFY
(adjusting timers) even if we didn't manage to get the NOTIFY onto the
wire.

Acked-by: Leonid Rosenboim <lrosenbo@wrs.com>
Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
bgpd/bgp_packet.c

index d115353f8ba8ef822ca747374c634e41328aa0c8..d71df0823ffe3254563319e4a5d3405f220afc61 100644 (file)
@@ -719,14 +719,15 @@ bgp_write_notify (struct peer *peer)
     return 0;
   assert (stream_get_endp (s) >= BGP_HEADER_SIZE);
 
-  /* Put socket in blocking mode. */
-  val = fcntl (peer->fd, F_GETFL, 0);
-  fcntl (peer->fd, F_SETFL, val & ~O_NONBLOCK);
-
   /* Stop collecting data within the socket */
   sockopt_cork (peer->fd, 0);
 
+  /* socket is in nonblocking mode, if we can't deliver the NOTIFY, well,
+   * we only care about getting a clean shutdown at this point. */
   ret = write (peer->fd, STREAM_DATA (s), stream_get_endp (s));
+
+  /* only connection reset/close gets counted as TCP_fatal_error, failure
+   * to write the entire NOTIFY doesn't get different FSM treatment */
   if (ret <= 0)
     {
       BGP_EVENT_ADD (peer, TCP_fatal_error);