* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include <sys/types.h>
-#include <sys/stat.h>
+#include <zebra.h>
#include <sys/un.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
#include "ldpd.h"
#include "ldpe.h"
#define CONTROL_BACKLOG 5
-static void control_accept(int, short, void *);
+static int control_accept(struct thread *);
static struct ctl_conn *control_connbyfd(int);
static struct ctl_conn *control_connbypid(pid_t);
static void control_close(int);
-static void control_dispatch_imsg(int, short, void *);
+static int control_dispatch_imsg(struct thread *);
struct ctl_conns ctl_conns;
static int control_fd;
int
-control_init(void)
+control_init(char *path)
{
struct sockaddr_un s_un;
int fd;
mode_t old_umask;
- if ((fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
- 0)) == -1) {
+ if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
log_warn("%s: socket", __func__);
return (-1);
}
+ sock_set_nonblock(fd);
memset(&s_un, 0, sizeof(s_un));
s_un.sun_family = AF_UNIX;
- strlcpy(s_un.sun_path, LDPD_SOCKET, sizeof(s_un.sun_path));
+ strlcpy(s_un.sun_path, path, sizeof(s_un.sun_path));
- if (unlink(LDPD_SOCKET) == -1)
+ if (unlink(path) == -1)
if (errno != ENOENT) {
- log_warn("%s: unlink %s", __func__, LDPD_SOCKET);
+ log_warn("%s: unlink %s", __func__, path);
close(fd);
return (-1);
}
old_umask = umask(S_IXUSR|S_IXGRP|S_IWOTH|S_IROTH|S_IXOTH);
if (bind(fd, (struct sockaddr *)&s_un, sizeof(s_un)) == -1) {
- log_warn("%s: bind: %s", __func__, LDPD_SOCKET);
+ log_warn("%s: bind: %s", __func__, path);
close(fd);
umask(old_umask);
return (-1);
}
umask(old_umask);
- if (chmod(LDPD_SOCKET, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) == -1) {
+ if (chmod(path, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) == -1) {
log_warn("%s: chmod", __func__);
close(fd);
- (void)unlink(LDPD_SOCKET);
+ (void)unlink(path);
return (-1);
}
}
void
-control_cleanup(void)
+control_cleanup(char *path)
{
accept_del(control_fd);
close(control_fd);
- unlink(LDPD_SOCKET);
+ unlink(path);
}
/* ARGSUSED */
-static void
-control_accept(int listenfd, short event, void *bula)
+static int
+control_accept(struct thread *thread)
{
int connfd;
socklen_t len;
struct ctl_conn *c;
len = sizeof(s_un);
- if ((connfd = accept4(listenfd, (struct sockaddr *)&s_un, &len,
- SOCK_NONBLOCK | SOCK_CLOEXEC)) == -1) {
+ if ((connfd = accept(THREAD_FD(thread), (struct sockaddr *)&s_un,
+ &len)) == -1) {
/*
* Pause accept if we are out of file descriptors, or
* libevent will haunt us here too.
accept_pause();
else if (errno != EWOULDBLOCK && errno != EINTR &&
errno != ECONNABORTED)
- log_warn("%s: accept4", __func__);
- return;
+ log_warn("%s: accept", __func__);
+ return (0);
}
+ sock_set_nonblock(connfd);
if ((c = calloc(1, sizeof(struct ctl_conn))) == NULL) {
log_warn(__func__);
close(connfd);
- return;
+ return (0);
}
imsg_init(&c->iev.ibuf, connfd);
- c->iev.handler = control_dispatch_imsg;
- c->iev.events = EV_READ;
- event_set(&c->iev.ev, c->iev.ibuf.fd, c->iev.events,
- c->iev.handler, &c->iev);
- event_add(&c->iev.ev, NULL);
+ c->iev.handler_read = control_dispatch_imsg;
+ c->iev.ev_read = NULL;
+ thread_add_read(master, c->iev.handler_read, &c->iev, c->iev.ibuf.fd,
+ &c->iev.ev_read);
+ c->iev.handler_write = ldp_write_handler;
+ c->iev.ev_write = NULL;
TAILQ_INSERT_TAIL(&ctl_conns, c, entry);
+
+ return (0);
}
static struct ctl_conn *
{
struct ctl_conn *c;
- for (c = TAILQ_FIRST(&ctl_conns); c != NULL && c->iev.ibuf.fd != fd;
- c = TAILQ_NEXT(c, entry))
- ; /* nothing */
+ TAILQ_FOREACH(c, &ctl_conns, entry) {
+ if (c->iev.ibuf.fd == fd)
+ break;
+ }
return (c);
}
{
struct ctl_conn *c;
- for (c = TAILQ_FIRST(&ctl_conns); c != NULL && c->iev.ibuf.pid != pid;
- c = TAILQ_NEXT(c, entry))
- ; /* nothing */
+ TAILQ_FOREACH(c, &ctl_conns, entry) {
+ if (c->iev.ibuf.pid == pid)
+ break;
+ }
return (c);
}
msgbuf_clear(&c->iev.ibuf.w);
TAILQ_REMOVE(&ctl_conns, c, entry);
- event_del(&c->iev.ev);
+ THREAD_READ_OFF(c->iev.ev_read);
+ THREAD_WRITE_OFF(c->iev.ev_write);
close(c->iev.ibuf.fd);
accept_unpause();
free(c);
}
/* ARGSUSED */
-static void
-control_dispatch_imsg(int fd, short event, void *bula)
+static int
+control_dispatch_imsg(struct thread *thread)
{
+ int fd = THREAD_FD(thread);
struct ctl_conn *c;
struct imsg imsg;
ssize_t n;
unsigned int ifidx;
- int verbose;
if ((c = control_connbyfd(fd)) == NULL) {
log_warnx("%s: fd %d: not found", __func__, fd);
- return;
+ return (0);
}
- if (event & EV_READ) {
- if (((n = imsg_read(&c->iev.ibuf)) == -1 && errno != EAGAIN) ||
- n == 0) {
- control_close(fd);
- return;
- }
- }
- if (event & EV_WRITE) {
- if (msgbuf_write(&c->iev.ibuf.w) <= 0 && errno != EAGAIN) {
- control_close(fd);
- return;
- }
+ c->iev.ev_read = NULL;
+
+ if (((n = imsg_read(&c->iev.ibuf)) == -1 && errno != EAGAIN) ||
+ n == 0) {
+ control_close(fd);
+ return (0);
}
for (;;) {
if ((n = imsg_get(&c->iev.ibuf, &imsg)) == -1) {
control_close(fd);
- return;
+ return (0);
}
if (n == 0)
case IMSG_CTL_FIB_COUPLE:
case IMSG_CTL_FIB_DECOUPLE:
case IMSG_CTL_RELOAD:
- c->iev.ibuf.pid = imsg.hdr.pid;
- ldpe_imsg_compose_parent(imsg.hdr.type, 0, NULL, 0);
- break;
case IMSG_CTL_KROUTE:
case IMSG_CTL_KROUTE_ADDR:
case IMSG_CTL_IFINFO:
- c->iev.ibuf.pid = imsg.hdr.pid;
- ldpe_imsg_compose_parent(imsg.hdr.type,
- imsg.hdr.pid, imsg.data,
- imsg.hdr.len - IMSG_HEADER_SIZE);
+ /* ignore */
break;
case IMSG_CTL_SHOW_INTERFACE:
if (imsg.hdr.len == IMSG_HEADER_SIZE +
case IMSG_CTL_SHOW_DISCOVERY:
ldpe_adj_ctl(c);
break;
+ case IMSG_CTL_SHOW_DISCOVERY_DTL:
+ ldpe_adj_detail_ctl(c);
+ break;
case IMSG_CTL_SHOW_LIB:
case IMSG_CTL_SHOW_L2VPN_PW:
case IMSG_CTL_SHOW_L2VPN_BINDING:
nbr_clear_ctl(imsg.data);
break;
case IMSG_CTL_LOG_VERBOSE:
- if (imsg.hdr.len != IMSG_HEADER_SIZE +
- sizeof(verbose))
- break;
-
- /* forward to other processes */
- ldpe_imsg_compose_parent(imsg.hdr.type, imsg.hdr.pid,
- imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE);
- ldpe_imsg_compose_lde(imsg.hdr.type, 0, imsg.hdr.pid,
- imsg.data, imsg.hdr.len - IMSG_HEADER_SIZE);
-
- memcpy(&verbose, imsg.data, sizeof(verbose));
- log_verbose(verbose);
+ /* ignore */
break;
default:
log_debug("%s: error handling imsg %d", __func__,
}
imsg_event_add(&c->iev);
+
+ return (0);
}
int