]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: correctly schedule select() at session startup
authorQuentin Young <qlyoung@cumulusnetworks.com>
Thu, 6 Apr 2017 23:45:57 +0000 (23:45 +0000)
committerQuentin Young <qlyoung@cumulusnetworks.com>
Thu, 30 Nov 2017 21:17:58 +0000 (16:17 -0500)
On TCP connection failure during session setup, bgp_stop() checks
whether peer->t_read is non-null to know whether or not to unschedule
select() on peer->fd before calling close() on it. Using the API exposed
by thread.c instead of bgpd's wrapper macro BGP_READ_ON() results in
this thread value never being set, which causes bgp_stop() to skip the
cancellation of select() before calling close(). Subsequent calls to
select() on that fd crash the daemon.

Use the macro instead.

Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
bgpd/bgp_fsm.c

index 3344bf3126661016be61a93e8b18d8e95a3b6299..d965b49c4900569ad9cc7c23308fafb9bbef89aa 100644 (file)
@@ -1176,6 +1176,10 @@ static int bgp_connect_check(struct thread *thread)
 
        peer = THREAD_ARG(thread);
 
+       /* This value needs to be unset in order for bgp_read() to be scheduled
+        */
+       BGP_READ_OFF(peer->t_read);
+
        /* Check file descriptor. */
        slen = sizeof(status);
        ret = getsockopt(peer->fd, SOL_SOCKET, SO_ERROR, (void *)&status,
@@ -1356,7 +1360,7 @@ int bgp_start(struct peer *peer)
                // when the socket becomes ready (or fails to connect),
                // bgp_connect_check
                // will be called.
-               thread_add_read(bm->master, bgp_connect_check, peer, peer->fd);
+               BGP_READ_ON(peer->t_read, bgp_connect_check, peer->fd);
                break;
        }
        return 0;