bgpd: correctly schedule select() at session startup

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>
This commit is contained in:
Quentin Young 2017-04-06 23:45:57 +00:00
parent 727c4f870b
commit dc1188bb4d
No known key found for this signature in database
GPG Key ID: DAF48E0F57E0834F

View 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;