]> git.proxmox.com Git - mirror_frr.git/blobdiff - ldpd/control.c
Merge pull request #3405 from LabNConsulting/working/master/fix-vrf
[mirror_frr.git] / ldpd / control.c
index b7cb3f10639813e5a3ce2bd5c5b5b258ad74ec99..cde99dc8a9927391d0048bb3247820c7cf2ce450 100644 (file)
  * 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);
        }
 
@@ -98,16 +93,16 @@ control_listen(void)
 }
 
 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;
@@ -115,8 +110,8 @@ control_accept(int listenfd, short event, void *bula)
        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.
@@ -125,24 +120,28 @@ control_accept(int listenfd, short event, void *bula)
                        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 *
@@ -150,9 +149,10 @@ control_connbyfd(int fd)
 {
        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);
 }
@@ -162,9 +162,10 @@ control_connbypid(pid_t pid)
 {
        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);
 }
@@ -182,45 +183,40 @@ control_close(int fd)
        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)
@@ -230,16 +226,10 @@ control_dispatch_imsg(int fd, short event, void *bula)
                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 +
@@ -253,6 +243,9 @@ control_dispatch_imsg(int fd, short event, void *bula)
                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:
@@ -271,18 +264,7 @@ control_dispatch_imsg(int fd, short event, void *bula)
                        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__,
@@ -293,6 +275,8 @@ control_dispatch_imsg(int fd, short event, void *bula)
        }
 
        imsg_event_add(&c->iev);
+
+       return (0);
 }
 
 int