]> git.proxmox.com Git - mirror_frr.git/commitdiff
Merge remote-tracking branch 'origin/master' into EIGRP
authorDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 26 Apr 2017 18:21:40 +0000 (14:21 -0400)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Wed, 26 Apr 2017 18:21:40 +0000 (14:21 -0400)
20 files changed:
ldpd/Makefile.am
ldpd/adjacency.c
ldpd/control.c
ldpd/control.h
ldpd/interface.c
ldpd/lde.c
ldpd/lde.h
ldpd/lde_lib.c
ldpd/ldp_vty_conf.c
ldpd/ldp_vty_exec.c
ldpd/ldp_zebra.c
ldpd/ldpd.c
ldpd/ldpd.h
ldpd/ldpe.c
ldpd/ldpe.h
ldpd/log.c
ldpd/log.h
ldpd/logmsg.c [new file with mode: 0644]
ldpd/notification.c
ldpd/packet.c

index 19f819ae365d00fc3559a7d6d192cfca91da2afe..b760b44573141d40331a8a428062e2a1129a8c0d 100644 (file)
@@ -16,7 +16,7 @@ EXTRA_DIST += ldp_vty.xml
 libldp_a_SOURCES = \
        accept.c address.c adjacency.c control.c hello.c init.c interface.c \
        keepalive.c l2vpn.c labelmapping.c lde.c lde_lib.c ldpd.c \
-       ldpe.c log.c neighbor.c notification.c packet.c pfkey.c \
+       ldpe.c log.c logmsg.c neighbor.c notification.c packet.c pfkey.c \
        socket.c util.c ldp_vty_cmds.c ldp_vty_conf.c ldp_vty_exec.c \
        ldp_debug.c ldp_zebra.c
 
index 8659202ee4e5c14bf7fbaec47fb7dc2b575c86f1..3ec57f158971385ed445ba788e89bbfa592bf109 100644 (file)
@@ -29,6 +29,8 @@ static __inline int adj_compare(struct adj *, struct adj *);
 static int      adj_itimer(struct thread *);
 static __inline int tnbr_compare(struct tnbr *, struct tnbr *);
 static void     tnbr_del(struct ldpd_conf *, struct tnbr *);
+static void     tnbr_start(struct tnbr *);
+static void     tnbr_stop(struct tnbr *);
 static int      tnbr_hello_timer(struct thread *);
 static void     tnbr_start_hello_timer(struct tnbr *);
 static void     tnbr_stop_hello_timer(struct tnbr *);
@@ -245,9 +247,7 @@ tnbr_new(int af, union ldpd_addr *addr)
 static void
 tnbr_del(struct ldpd_conf *xconf, struct tnbr *tnbr)
 {
-       tnbr_stop_hello_timer(tnbr);
-       if (tnbr->adj)
-               adj_del(tnbr->adj, S_SHUTDOWN);
+       tnbr_stop(tnbr);
        RB_REMOVE(tnbr_head, &xconf->tnbr_tree, tnbr);
        free(tnbr);
 }
@@ -273,6 +273,23 @@ tnbr_check(struct ldpd_conf *xconf, struct tnbr *tnbr)
        return (tnbr);
 }
 
+static void
+tnbr_start(struct tnbr *tnbr)
+{
+       send_hello(HELLO_TARGETED, NULL, tnbr);
+       tnbr_start_hello_timer(tnbr);
+       tnbr->state = TNBR_STA_ACTIVE;
+}
+
+static void
+tnbr_stop(struct tnbr *tnbr)
+{
+       tnbr_stop_hello_timer(tnbr);
+       if (tnbr->adj)
+               adj_del(tnbr->adj, S_SHUTDOWN);
+       tnbr->state = TNBR_STA_DOWN;
+}
+
 void
 tnbr_update(struct tnbr *tnbr)
 {
@@ -292,16 +309,12 @@ tnbr_update(struct tnbr *tnbr)
                if (!socket_ok || !rtr_id_ok)
                        return;
 
-               tnbr->state = TNBR_STA_ACTIVE;
-               send_hello(HELLO_TARGETED, NULL, tnbr);
-
-               tnbr_start_hello_timer(tnbr);
+               tnbr_start(tnbr);
        } else if (tnbr->state == TNBR_STA_ACTIVE) {
                if (socket_ok && rtr_id_ok)
                        return;
 
-               tnbr->state = TNBR_STA_DOWN;
-               tnbr_stop_hello_timer(tnbr);
+               tnbr_stop(tnbr);
        }
 }
 
index 5c530e1b701163736f876a63206e7deccfb1f9dd..d40e0342c13a76011e0a112fec96145e2a783feb 100644 (file)
@@ -37,7 +37,7 @@ struct ctl_conns       ctl_conns;
 static int              control_fd;
 
 int
-control_init(void)
+control_init(char *path)
 {
        struct sockaddr_un       s_un;
        int                      fd;
@@ -51,28 +51,28 @@ control_init(void)
 
        memset(&s_un, 0, sizeof(s_un));
        s_un.sun_family = AF_UNIX;
-       strlcpy(s_un.sun_path, ctl_sock_path, sizeof(s_un.sun_path));
+       strlcpy(s_un.sun_path, path, sizeof(s_un.sun_path));
 
-       if (unlink(ctl_sock_path) == -1)
+       if (unlink(path) == -1)
                if (errno != ENOENT) {
-                       log_warn("%s: unlink %s", __func__, ctl_sock_path);
+                       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__, ctl_sock_path);
+               log_warn("%s: bind: %s", __func__, path);
                close(fd);
                umask(old_umask);
                return (-1);
        }
        umask(old_umask);
 
-       if (chmod(ctl_sock_path, 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(ctl_sock_path);
+               (void)unlink(path);
                return (-1);
        }
 
@@ -93,11 +93,11 @@ control_listen(void)
 }
 
 void
-control_cleanup(void)
+control_cleanup(char *path)
 {
        accept_del(control_fd);
        close(control_fd);
-       unlink(ctl_sock_path);
+       unlink(path);
 }
 
 /* ARGSUSED */
index 32c49fdf8760cfd7782210ea1da5bc4092a24d39..0e66a1636aa88354fd83db989b961856cf05aa4f 100644 (file)
@@ -29,9 +29,9 @@ TAILQ_HEAD(ctl_conns, ctl_conn);
 
 extern struct ctl_conns ctl_conns;
 
-int    control_init(void);
+int    control_init(char *);
 int    control_listen(void);
-void   control_cleanup(void);
+void   control_cleanup(char *);
 int    control_imsg_relay(struct imsg *);
 
 #endif /* _CONTROL_H_ */
index b7f473d3960762d05632e66b9cb08a01dfb94f91..7678152470ecd32d887b34febc499f4bfc126e77 100644 (file)
@@ -287,8 +287,9 @@ if_start(struct iface *iface, int af)
        }
 
        send_hello(HELLO_LINK, ia, NULL);
-
        if_start_hello_timer(ia);
+       ia->state = IF_STA_ACTIVE;
+
        return (0);
 }
 
@@ -318,9 +319,11 @@ if_reset(struct iface *iface, int af)
                        if_leave_ipv6_group(iface, &global.mcast_addr_v6);
                break;
        default:
-               fatalx("if_start: unknown af");
+               fatalx("if_reset: unknown af");
        }
 
+       ia->state = IF_STA_DOWN;
+
        return (0);
 }
 
@@ -367,13 +370,11 @@ if_update_af(struct iface_af *ia, int link_ok)
                    !rtr_id_ok)
                        return;
 
-               ia->state = IF_STA_ACTIVE;
                if_start(ia->iface, ia->af);
        } else if (ia->state == IF_STA_ACTIVE) {
                if (ia->enabled && link_ok && addr_ok && socket_ok && rtr_id_ok)
                        return;
 
-               ia->state = IF_STA_DOWN;
                if_reset(ia->iface, ia->af);
        }
 }
index d8a2924b31c9fdd4ee60c6628b01182ac59df5c1..25f7178b6b47d1f918d68db9a89621b501f16f32 100644 (file)
@@ -54,9 +54,9 @@ static void            lde_map_free(void *);
 static int              lde_address_add(struct lde_nbr *, struct lde_addr *);
 static int              lde_address_del(struct lde_nbr *, struct lde_addr *);
 static void             lde_address_list_free(struct lde_nbr *);
-static void             zclient_sync_init (u_short instance);
+static void             zclient_sync_init(u_short instance);
 static void             lde_label_list_init(void);
-static int              lde_get_label_chunk (void);
+static int              lde_get_label_chunk(void);
 static void             on_get_label_chunk_response(uint32_t start, uint32_t end);
 static uint32_t                 lde_get_next_label(void);
 
@@ -93,8 +93,11 @@ static struct zebra_privs_t lde_privs =
 };
 
 /* List of chunks of labels externally assigned by Zebra */
-struct list *label_chunk_list;
-struct listnode *current_label_chunk;
+static struct list *label_chunk_list;
+static struct listnode *current_label_chunk;
+
+/* Synchronous zclient to request labels */
+static struct zclient *zclient_sync;
 
 /* SIGINT / SIGTERM handler. */
 static void
@@ -119,60 +122,17 @@ static struct quagga_signal_t lde_signals[] =
        },
 };
 
-static void
-lde_sleep (void)
-{
-       sleep(1);
-       if (lde_signals[0].caught || lde_signals[1].caught)
-               lde_shutdown();
-}
-struct zclient *zclient_sync = NULL;
-static void
-zclient_sync_init(u_short instance)
-{
-       /* Initialize special zclient for synchronous message exchanges. */
-       log_debug("Initializing synchronous zclient for label manager");
-       zclient_sync = zclient_new(master);
-       zclient_sync->sock = -1;
-       zclient_sync->redist_default = ZEBRA_ROUTE_LDP;
-       zclient_sync->instance = instance;
-       while (zclient_socket_connect (zclient_sync) < 0) {
-               fprintf(stderr, "Error connecting synchronous zclient!\n");
-               lde_sleep();
-       }
-
-       /* Connect to label manager */
-       while (lm_label_manager_connect (zclient_sync) != 0) {
-               fprintf(stderr, "Error connecting to label manager!\n");
-               lde_sleep();
-       }
-}
-
 /* label decision engine */
 void
-lde(const char *user, const char *group, u_short instance)
+lde(void)
 {
        struct thread            thread;
-       struct timeval           now;
-
-       ldeconf = config_new_empty();
 
 #ifdef HAVE_SETPROCTITLE
        setproctitle("label decision engine");
 #endif
        ldpd_process = PROC_LDE_ENGINE;
-
-       /* drop privileges */
-       if (user)
-               lde_privs.user = user;
-       if (group)
-               lde_privs.group = group;
-       zprivs_init(&lde_privs);
-
-#ifdef HAVE_PLEDGE
-       if (pledge("stdio recvfd unix", NULL) == -1)
-               fatal("pledge");
-#endif
+       log_procname = log_procnames[PROC_LDE_ENGINE];
 
        master = thread_master_create();
 
@@ -192,27 +152,46 @@ lde(const char *user, const char *group, u_short instance)
                fatal(NULL);
        imsg_init(&iev_main_sync->ibuf, LDPD_FD_SYNC);
 
+       /* create base configuration */
+       ldeconf = config_new_empty();
+
+       /* Fetch next active thread. */
+       while (thread_fetch(master, &thread))
+               thread_call(&thread);
+}
+
+void
+lde_init(struct ldpd_init *init)
+{
+       /* drop privileges */
+       if (init->user)
+               lde_privs.user = init->user;
+       if (init->group)
+               lde_privs.group = init->group;
+       zprivs_init(&lde_privs);
+
+#ifdef HAVE_PLEDGE
+       if (pledge("stdio recvfd unix", NULL) == -1)
+               fatal("pledge");
+#endif
+
        /* start the LIB garbage collector */
        lde_gc_start_timer();
 
-       gettimeofday(&now, NULL);
-       global.uptime = now.tv_sec;
-
        /* Init synchronous zclient and label list */
-       zclient_sync_init(instance);
+       zclient_serv_path_set(init->zclient_serv_path);
+       zclient_sync_init(init->instance);
        lde_label_list_init();
-
-       /* Fetch next active thread. */
-       while (thread_fetch(master, &thread))
-               thread_call(&thread);
 }
 
 static void
 lde_shutdown(void)
 {
        /* close pipes */
-       msgbuf_clear(&iev_ldpe->ibuf.w);
-       close(iev_ldpe->ibuf.fd);
+       if (iev_ldpe) {
+               msgbuf_clear(&iev_ldpe->ibuf.w);
+               close(iev_ldpe->ibuf.fd);
+       }
        msgbuf_clear(&iev_main->ibuf.w);
        close(iev_main->ibuf.fd);
        msgbuf_clear(&iev_main_sync->ibuf.w);
@@ -224,7 +203,8 @@ lde_shutdown(void)
 
        config_clear(ldeconf);
 
-       free(iev_ldpe);
+       if (iev_ldpe)
+               free(iev_ldpe);
        free(iev_main);
        free(iev_main_sync);
 
@@ -239,6 +219,13 @@ lde_imsg_compose_parent(int type, pid_t pid, void *data, uint16_t datalen)
        return (imsg_compose_event(iev_main, type, 0, pid, -1, data, datalen));
 }
 
+void
+lde_imsg_compose_parent_sync(int type, pid_t pid, void *data, uint16_t datalen)
+{
+       imsg_compose_event(iev_main_sync, type, 0, pid, -1, data, datalen);
+       imsg_flush(&iev_main_sync->ibuf);
+}
+
 int
 lde_imsg_compose_ldpe(int type, uint32_t peerid, pid_t pid, void *data,
     uint16_t datalen)
@@ -550,6 +537,14 @@ lde_dispatch_parent(struct thread *thread)
                        iev_ldpe->handler_write = ldp_write_handler;
                        iev_ldpe->ev_write = NULL;
                        break;
+               case IMSG_INIT:
+                       if (imsg.hdr.len != IMSG_HEADER_SIZE +
+                           sizeof(struct ldpd_init))
+                               fatalx("INIT imsg with wrong len");
+
+                       memcpy(&init, imsg.data, sizeof(init));
+                       lde_init(&init);
+                       break;
                case IMSG_RECONF_CONF:
                        if ((nconf = malloc(sizeof(struct ldpd_conf))) ==
                            NULL)
@@ -719,7 +714,7 @@ lde_update_label(struct fec_node *fn)
            fn->local_label > MPLS_LABEL_RESERVED_MAX)
                return (fn->local_label);
 
-       return lde_get_next_label ();
+       return (lde_get_next_label());
 }
 
 void
@@ -901,10 +896,23 @@ lde_map2fec(struct map *map, struct in_addr lsr_id, struct fec *fec)
 void
 lde_send_labelmapping(struct lde_nbr *ln, struct fec_node *fn, int single)
 {
-       struct lde_req  *lre;
-       struct lde_map  *me;
-       struct map       map;
-       struct l2vpn_pw *pw;
+       struct lde_wdraw        *lw;
+       struct lde_map          *me;
+       struct lde_req          *lre;
+       struct map               map;
+       struct l2vpn_pw         *pw;
+
+       /*
+        * We shouldn't send a new label mapping if we have a pending
+        * label release to receive. In this case, schedule to send a
+        * label mapping as soon as a label release is received.
+        */
+       lw = (struct lde_wdraw *)fec_find(&ln->sent_wdraw, &fn->fec);
+       if (lw) {
+               if (!fec_find(&ln->sent_map_pending, &fn->fec))
+                       lde_map_pending_add(ln, fn);
+               return;
+       }
 
        /*
         * This function skips SL.1 - 3 and SL.9 - 14 because the label
@@ -1210,6 +1218,7 @@ lde_nbr_new(uint32_t peerid, struct lde_nbr *new)
        ln->peerid = peerid;
        fec_init(&ln->recv_map);
        fec_init(&ln->sent_map);
+       fec_init(&ln->sent_map_pending);
        fec_init(&ln->recv_req);
        fec_init(&ln->sent_req);
        fec_init(&ln->sent_wdraw);
@@ -1265,6 +1274,7 @@ lde_nbr_del(struct lde_nbr *ln)
 
        fec_clear(&ln->recv_map, lde_map_free);
        fec_clear(&ln->sent_map, lde_map_free);
+       fec_clear(&ln->sent_map_pending, free);
        fec_clear(&ln->recv_req, free);
        fec_clear(&ln->sent_req, free);
        fec_clear(&ln->sent_wdraw, free);
@@ -1415,6 +1425,30 @@ lde_map_free(void *ptr)
        free(map);
 }
 
+struct fec *
+lde_map_pending_add(struct lde_nbr *ln, struct fec_node *fn)
+{
+       struct fec      *map;
+
+       map = calloc(1, sizeof(*map));
+       if (map == NULL)
+               fatal(__func__);
+
+       *map = fn->fec;
+       if (fec_insert(&ln->sent_map_pending, map))
+               log_warnx("failed to add %s to sent map (pending)",
+                   log_fec(map));
+
+       return (map);
+}
+
+void
+lde_map_pending_del(struct lde_nbr *ln, struct fec *map)
+{
+       fec_remove(&ln->sent_map_pending, map);
+       free(map);
+}
+
 struct lde_req *
 lde_req_add(struct lde_nbr *ln, struct fec *fec, int sent)
 {
@@ -1580,21 +1614,42 @@ lde_address_list_free(struct lde_nbr *ln)
        }
 }
 
+static void
+zclient_sync_init(u_short instance)
+{
+       /* Initialize special zclient for synchronous message exchanges. */
+       log_debug("Initializing synchronous zclient for label manager");
+       zclient_sync = zclient_new(master);
+       zclient_sync->sock = -1;
+       zclient_sync->redist_default = ZEBRA_ROUTE_LDP;
+       zclient_sync->instance = instance;
+       while (zclient_socket_connect(zclient_sync) < 0) {
+               log_warnx("Error connecting synchronous zclient!");
+               sleep(1);
+       }
+
+       /* Connect to label manager */
+       while (lm_label_manager_connect(zclient_sync) != 0) {
+               log_warnx("Error connecting to label manager!");
+               sleep(1);
+       }
+}
+
 static void
 lde_del_label_chunk(void *val)
 {
        free(val);
 }
+
 static int
 lde_get_label_chunk(void)
 {
-       int ret;
-       uint32_t start, end;
+       int              ret;
+       uint32_t         start, end;
 
        log_debug("Getting label chunk");
        ret = lm_get_label_chunk(zclient_sync, 0, CHUNK_SIZE, &start, &end);
-       if (ret < 0)
-       {
+       if (ret < 0) {
                log_warnx("Error getting label chunk!");
                close(zclient_sync->sock);
                zclient_sync->sock = -1;
@@ -1603,8 +1658,9 @@ lde_get_label_chunk(void)
 
        on_get_label_chunk_response(start, end);
 
-       return 0;
+       return (0);
 }
+
 static void
 lde_label_list_init(void)
 {
@@ -1613,8 +1669,8 @@ lde_label_list_init(void)
 
        /* get first chunk */
        while (lde_get_label_chunk () != 0) {
-               fprintf(stderr, "Error getting first label chunk!\n");
-               lde_sleep();
+               log_warnx("Error getting first label chunk!");
+               sleep(1);
        }
 }
 
@@ -1645,9 +1701,9 @@ on_get_label_chunk_response(uint32_t start, uint32_t end)
 static uint32_t
 lde_get_next_label(void)
 {
-       struct label_chunk *label_chunk;
-       uint32_t i, pos, size;
-       uint32_t label = NO_LABEL;
+       struct label_chunk      *label_chunk;
+       uint32_t                 i, pos, size;
+       uint32_t                 label = NO_LABEL;
 
        while (current_label_chunk) {
                label_chunk = listgetdata(current_label_chunk);
@@ -1669,12 +1725,13 @@ lde_get_next_label(void)
 end:
        /* we moved till the last chunk, or were not able to find a label,
           so let's ask for another one */
-       if (!current_label_chunk || current_label_chunk == listtail(label_chunk_list)
-               || label == NO_LABEL) {
+       if (!current_label_chunk ||
+           current_label_chunk == listtail(label_chunk_list) ||
+           label == NO_LABEL) {
                if (lde_get_label_chunk() != 0)
                        log_warn("%s: Error getting label chunk!", __func__);
 
        }
 
-       return label;
+       return (label);
 }
index 57791cd1b0c64ea5a033e349dd188c97736ee65a..1cce483832d19283e81a1466f5d2530259faedf1 100644 (file)
@@ -95,6 +95,7 @@ struct lde_nbr {
        struct fec_tree          sent_req;
        struct fec_tree          recv_map;
        struct fec_tree          sent_map;
+       struct fec_tree          sent_map_pending;
        struct fec_tree          sent_wdraw;
        TAILQ_HEAD(, lde_addr)   addr_list;
 };
@@ -139,8 +140,10 @@ extern struct nbr_tree      lde_nbrs;
 extern struct thread   *gc_timer;
 
 /* lde.c */
-void            lde(const char *, const char *, u_short instance);
+void            lde(void);
+void            lde_init(struct ldpd_init *);
 int             lde_imsg_compose_parent(int, pid_t, void *, uint16_t);
+void            lde_imsg_compose_parent_sync(int, pid_t, void *, uint16_t);
 int             lde_imsg_compose_ldpe(int, uint32_t, pid_t, void *, uint16_t);
 int             lde_acl_check(char *, int, union ldpd_addr *, uint8_t);
 uint32_t        lde_update_label(struct fec_node *);
@@ -169,6 +172,8 @@ struct lde_nbr      *lde_nbr_find_by_lsrid(struct in_addr);
 struct lde_nbr *lde_nbr_find_by_addr(int, union ldpd_addr *);
 struct lde_map *lde_map_add(struct lde_nbr *, struct fec_node *, int);
 void            lde_map_del(struct lde_nbr *, struct lde_map *, int);
+struct fec     *lde_map_pending_add(struct lde_nbr *, struct fec_node *);
+void            lde_map_pending_del(struct lde_nbr *, struct fec *);
 struct lde_req *lde_req_add(struct lde_nbr *, struct fec *, int);
 void            lde_req_del(struct lde_nbr *, struct lde_req *, int);
 struct lde_wdraw *lde_wdraw_add(struct lde_nbr *, struct fec_node *);
index db2682a173698a65c357ee0d6e37779e9965cdd3..37a670bc8ca58be4988cba4cfa7172df69b4bb5b 100644 (file)
@@ -383,20 +383,23 @@ lde_kernel_update(struct fec *fec)
        if (LIST_EMPTY(&fn->nexthops)) {
                RB_FOREACH(ln, nbr_tree, &lde_nbrs)
                        lde_send_labelwithdraw(ln, fn, NULL, NULL);
-               fn->local_label = NO_LABEL;
                fn->data = NULL;
-       } else {
-               uint32_t         previous_label;
 
-               previous_label = fn->local_label;
+               /*
+                * Do not deallocate the local label now, do that only in the
+                * LIB garbage collector. This will prevent ldpd from changing
+                * the input label of some prefixes too often when running on
+                * an unstable network. Also, restart the garbage collector
+                * timer so that labels are deallocated only when the network
+                * is stabilized.
+                */
+               lde_gc_start_timer();
+       } else {
                fn->local_label = lde_update_label(fn);
-
-               if (fn->local_label != NO_LABEL &&
-                   fn->local_label != previous_label) {
+               if (fn->local_label != NO_LABEL && RB_EMPTY(&fn->upstream))
                        /* FEC.1: perform lsr label distribution procedure */
                        RB_FOREACH(ln, nbr_tree, &lde_nbrs)
                                lde_send_labelmapping(ln, fn, 1);
-               }
        }
 
        LIST_FOREACH(fnh, &fn->nexthops, entry) {
@@ -659,6 +662,7 @@ lde_check_release(struct map *map, struct lde_nbr *ln)
        struct fec_node         *fn;
        struct lde_wdraw        *lw;
        struct lde_map          *me;
+       struct fec              *pending_map;
 
        /* wildcard label release */
        if (map->type == MAP_TYPE_WILDCARD ||
@@ -674,17 +678,24 @@ lde_check_release(struct map *map, struct lde_nbr *ln)
        if (fn == NULL)
                return;
 
+       /* LRl.6: check sent map list and remove it if available */
+       me = (struct lde_map *)fec_find(&ln->sent_map, &fn->fec);
+       if (me && (map->label == NO_LABEL || map->label == me->map.label))
+               lde_map_del(ln, me, 1);
+
        /* LRl.3: first check if we have a pending withdraw running */
        lw = (struct lde_wdraw *)fec_find(&ln->sent_wdraw, &fn->fec);
        if (lw && (map->label == NO_LABEL || map->label == lw->label)) {
                /* LRl.4: delete record of outstanding label withdraw */
                lde_wdraw_del(ln, lw);
-       }
 
-       /* LRl.6: check sent map list and remove it if available */
-       me = (struct lde_map *)fec_find(&ln->sent_map, &fn->fec);
-       if (me && (map->label == NO_LABEL || map->label == me->map.label))
-               lde_map_del(ln, me, 1);
+               /* send pending label mapping if any */
+               pending_map = fec_find(&ln->sent_map_pending, &fn->fec);
+               if (pending_map) {
+                       lde_send_labelmapping(ln, fn, 1);
+                       lde_map_pending_del(ln, pending_map);
+               }
+       }
 
        /*
         * LRl.11 - 13 are unnecessary since we remove the label from
@@ -699,6 +710,7 @@ lde_check_release_wcard(struct map *map, struct lde_nbr *ln)
        struct fec_node         *fn;
        struct lde_wdraw        *lw;
        struct lde_map          *me;
+       struct fec              *pending_map;
 
        RB_FOREACH(f, fec_tree, &ft) {
                fn = (struct fec_node *)f;
@@ -708,17 +720,24 @@ lde_check_release_wcard(struct map *map, struct lde_nbr *ln)
                if (lde_wildcard_apply(map, &fn->fec, me) == 0)
                        continue;
 
+               /* LRl.6: check sent map list and remove it if available */
+               if (me &&
+                   (map->label == NO_LABEL || map->label == me->map.label))
+                       lde_map_del(ln, me, 1);
+
                /* LRl.3: first check if we have a pending withdraw running */
                lw = (struct lde_wdraw *)fec_find(&ln->sent_wdraw, &fn->fec);
                if (lw && (map->label == NO_LABEL || map->label == lw->label)) {
                        /* LRl.4: delete record of outstanding lbl withdraw */
                        lde_wdraw_del(ln, lw);
-               }
 
-               /* LRl.6: check sent map list and remove it if available */
-               if (me &&
-                   (map->label == NO_LABEL || map->label == me->map.label))
-                       lde_map_del(ln, me, 1);
+                       /* send pending label mapping if any */
+                       pending_map = fec_find(&ln->sent_map_pending, &fn->fec);
+                       if (pending_map) {
+                               lde_send_labelmapping(ln, fn, 1);
+                               lde_map_pending_del(ln, pending_map);
+                       }
+               }
 
                /*
                 * LRl.11 - 13 are unnecessary since we remove the label from
index e4fc7b00545fc281f34edc8651bc9bf2bcc655f2..6943e8edc6234cd14bab30ae9fa4cb2151858d9a 100644 (file)
@@ -1641,7 +1641,7 @@ iface_new_api(struct ldpd_conf *conf, const char *name)
        struct iface            *iface;
 
        if (ldp_iface_is_configured(conf, ifname))
-               return NULL;
+               return (NULL);
 
        iface = if_new(name);
        RB_INSERT(iface_head, &conf->iface_tree, iface);
index a149b7fe3522b4993dbd758cb88559dad8e291fa..ffd20abb4a73fce9000c4dcadbfde5028bb18067 100644 (file)
@@ -517,8 +517,7 @@ show_nbr_msg(struct vty *vty, struct imsg *imsg, struct show_params *params)
                    nbr_state_name(nbr->nbr_state), addr);
                if (strlen(addr) > 15)
                        vty_out(vty, "%s%48s", VTY_NEWLINE, " ");
-               vty_out(vty, " %8s%s", nbr->uptime == 0 ? "-" :
-                   log_time(nbr->uptime), VTY_NEWLINE);
+               vty_out(vty, " %8s%s", log_time(nbr->uptime), VTY_NEWLINE);
                break;
        case IMSG_CTL_END:
                return (1);
@@ -909,6 +908,7 @@ show_nbr_capabilities_msg(struct vty *vty, struct imsg *imsg, struct show_params
                vty_out(vty, "Peer LDP Identifier: %s:0%s", inet_ntoa(nbr->id),
                    VTY_NEWLINE);
                show_nbr_capabilities(vty, nbr);
+               vty_out(vty, "%s", VTY_NEWLINE);
                break;
        case IMSG_CTL_END:
                vty_out(vty, "%s", VTY_NEWLINE);
index 702b5c5eaaf5203a37335b5007a628bb105e4460..241603b8e11c7566cf9a79057fb35d03f9386594 100644 (file)
@@ -357,6 +357,7 @@ ldp_zebra_read_route(int command, struct zclient *zclient, zebra_size_t length,
        struct kroute            kr;
        int                      nhnum = 0, nhlen;
        size_t                   nhmark;
+       int                      add = 0;
 
        memset(&kr, 0, sizeof(kr));
        s = zclient->ibuf;
@@ -423,21 +424,14 @@ ldp_zebra_read_route(int command, struct zclient *zclient, zebra_size_t length,
        if (CHECK_FLAG(message_flags, ZAPI_MESSAGE_NEXTHOP))
                stream_set_getp(s, nhmark);
 
-       if (nhnum == 0) {
-               switch (command) {
-               case ZEBRA_REDISTRIBUTE_IPV4_ADD:
-               case ZEBRA_REDISTRIBUTE_IPV6_ADD:
-                       return (0);
-               case ZEBRA_REDISTRIBUTE_IPV4_DEL:
-               case ZEBRA_REDISTRIBUTE_IPV6_DEL:
-                       debug_zebra_in("route delete %s/%d (%s)",
-                           log_addr(kr.af, &kr.prefix), kr.prefixlen,
-                           zebra_route_string(type));
-                       break;
-               default:
-                       fatalx("ldp_zebra_read_route: unknown command");
-               }
-       }
+       if (command == ZEBRA_REDISTRIBUTE_IPV4_ADD ||
+           command == ZEBRA_REDISTRIBUTE_IPV6_ADD)
+               add = 1;
+
+       if (nhnum == 0)
+               debug_zebra_in("route %s %s/%d (%s)", (add) ? "add" : "delete",
+                   log_addr(kr.af, &kr.prefix), kr.prefixlen,
+                   zebra_route_string(type));
 
        /* loop through all the nexthops */
        for (; nhnum > 0; nhnum--) {
@@ -454,19 +448,14 @@ ldp_zebra_read_route(int command, struct zclient *zclient, zebra_size_t length,
                stream_getc(s); /* ifindex_num, unused. */
                kr.ifindex = stream_getl(s);
 
-               switch (command) {
-               case ZEBRA_REDISTRIBUTE_IPV4_ADD:
-               case ZEBRA_REDISTRIBUTE_IPV6_ADD:
-                       debug_zebra_in("route add %s/%d nexthop %s "
-                           "ifindex %u (%s)", log_addr(kr.af, &kr.prefix),
-                           kr.prefixlen, log_addr(kr.af, &kr.nexthop),
-                           kr.ifindex, zebra_route_string(type));
+               debug_zebra_in("route %s %s/%d nexthop %s ifindex %u (%s)",
+                   (add) ? "add" : "delete", log_addr(kr.af, &kr.prefix),
+                   kr.prefixlen, log_addr(kr.af, &kr.nexthop), kr.ifindex,
+                   zebra_route_string(type));
+
+               if (add)
                        main_imsg_compose_lde(IMSG_NETWORK_ADD, 0, &kr,
                            sizeof(kr));
-                       break;
-               default:
-                       break;
-               }
        }
 
        main_imsg_compose_lde(IMSG_NETWORK_UPDATE, 0, &kr, sizeof(kr));
index 9729499e284cc5f89054a76ee4445aa573840f17..bdf70973234559c47c333fd8c479e2d0c9219b4a 100644 (file)
@@ -44,8 +44,7 @@
 #include "libfrr.h"
 
 static void             ldpd_shutdown(void);
-static pid_t            start_child(enum ldpd_process, char *, int, int,
-                           const char *, const char *, const char *, const char *);
+static pid_t            start_child(enum ldpd_process, char *, int, int);
 static int              main_dispatch_ldpe(struct thread *);
 static int              main_dispatch_lde(struct thread *);
 static int              main_imsg_send_ipc_sockets(struct imsgbuf *,
@@ -77,6 +76,7 @@ DEFINE_QOBJ_TYPE(l2vpn)
 DEFINE_QOBJ_TYPE(ldpd_conf)
 
 struct ldpd_global      global;
+struct ldpd_init        init;
 struct ldpd_conf       *ldpd_conf, *vty_conf;
 
 static struct imsgev   *iev_ldpe, *iev_ldpe_sync;
@@ -200,14 +200,10 @@ main(int argc, char *argv[])
        int                      lflag = 0, eflag = 0;
        int                      pipe_parent2ldpe[2], pipe_parent2ldpe_sync[2];
        int                      pipe_parent2lde[2], pipe_parent2lde_sync[2];
-       char                    *ctl_sock_custom_path = NULL;
        char                    *ctl_sock_name;
-       const char              *user = NULL;
-       const char              *group = NULL;
-       u_short                  instance = 0;
-       const char              *instance_char = NULL;
 
        ldpd_process = PROC_MAIN;
+       log_procname = log_procnames[ldpd_process];
 
        saved_argv0 = argv[0];
        if (saved_argv0 == NULL)
@@ -241,17 +237,14 @@ main(int argc, char *argv[])
                                 * sensible config
                                 */
                                ctl_sock_name = (char *)LDPD_SOCKET;
-                       ctl_sock_custom_path = optarg;
-                       strlcpy(ctl_sock_path, ctl_sock_custom_path,
-                           sizeof(ctl_sock_path));
+                       strlcpy(ctl_sock_path, optarg, sizeof(ctl_sock_path));
                        strlcat(ctl_sock_path, "/", sizeof(ctl_sock_path));
                        strlcat(ctl_sock_path, ctl_sock_name,
                            sizeof(ctl_sock_path));
                        break;
                case 'n':
-                       instance = atoi(optarg);
-                       instance_char = optarg;
-                       if (instance < 1)
+                       init.instance = atoi(optarg);
+                       if (init.instance < 1)
                                exit(0);
                        break;
                case 'L':
@@ -266,8 +259,11 @@ main(int argc, char *argv[])
                }
        }
 
-       user = ldpd_privs.user;
-       group = ldpd_privs.group;
+       strlcpy(init.user, ldpd_privs.user, sizeof(init.user));
+       strlcpy(init.group, ldpd_privs.group, sizeof(init.group));
+       strlcpy(init.ctl_sock_path, ctl_sock_path, sizeof(init.ctl_sock_path));
+       strlcpy(init.zclient_serv_path, zclient_serv_path_get(),
+           sizeof(init.zclient_serv_path));
 
        argc -= optind;
        argv += optind;
@@ -281,14 +277,14 @@ main(int argc, char *argv[])
                exit(1);
        }
 
-       if (lflag)
-               lde(user, group, instance);
-       else if (eflag)
-               ldpe(user, group, ctl_sock_path);
-
        openzlog(ldpd_di.progname, "LDP", 0,
            LOG_CONS | LOG_NDELAY | LOG_PID, LOG_DAEMON);
 
+       if (lflag)
+               lde();
+       else if (eflag)
+               ldpe();
+
        if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_parent2ldpe) == -1)
                fatal("socketpair");
        if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC,
@@ -316,11 +312,9 @@ main(int argc, char *argv[])
 
        /* start children */
        lde_pid = start_child(PROC_LDE_ENGINE, saved_argv0,
-           pipe_parent2lde[1], pipe_parent2lde_sync[1],
-           user, group, ctl_sock_custom_path, instance_char);
+           pipe_parent2lde[1], pipe_parent2lde_sync[1]);
        ldpe_pid = start_child(PROC_LDP_ENGINE, saved_argv0,
-           pipe_parent2ldpe[1], pipe_parent2ldpe_sync[1],
-           user, group, ctl_sock_custom_path, instance_char);
+           pipe_parent2ldpe[1], pipe_parent2ldpe_sync[1]);
 
        /* drop privileges */
        zprivs_init(&ldpd_privs);
@@ -388,6 +382,7 @@ main(int argc, char *argv[])
 
        if (main_imsg_send_ipc_sockets(&iev_ldpe->ibuf, &iev_lde->ibuf))
                fatal("could not establish imsg links");
+       main_imsg_compose_both(IMSG_INIT, &init, sizeof(init));
        main_imsg_compose_both(IMSG_DEBUG_UPDATE, &ldp_debug,
            sizeof(ldp_debug));
        main_imsg_send_config(ldpd_conf);
@@ -452,11 +447,9 @@ ldpd_shutdown(void)
 }
 
 static pid_t
-start_child(enum ldpd_process p, char *argv0, int fd_async, int fd_sync,
-    const char *user, const char *group, const char *ctl_sock_custom_path,
-    const char *instance)
+start_child(enum ldpd_process p, char *argv0, int fd_async, int fd_sync)
 {
-       char    *argv[13];
+       char    *argv[3];
        int      argc = 0;
        pid_t    pid;
 
@@ -487,26 +480,6 @@ start_child(enum ldpd_process p, char *argv0, int fd_async, int fd_sync,
                argv[argc++] = (char *)"-E";
                break;
        }
-       if (user) {
-               argv[argc++] = (char *)"-u";
-               argv[argc++] = (char *)user;
-       }
-       if (group) {
-               argv[argc++] = (char *)"-g";
-               argv[argc++] = (char *)group;
-       }
-       if (ctl_sock_custom_path) {
-               argv[argc++] = (char *)"--ctl_socket";
-               argv[argc++] = (char *)ctl_sock_custom_path;
-       }
-       /* zclient serv path */
-       argv[argc++] = (char *)"-z";
-       argv[argc++] = (char *)zclient_serv_path_get();
-       /* instance */
-       if (instance) {
-               argv[argc++] = (char *)"-n";
-               argv[argc++] = (char *)instance;
-       }
        argv[argc++] = NULL;
 
        execvp(argv0, argv);
index d2fc5aa3afe8be4d12c0dfacfbd00ec843597e0a..cba1939d98b67e845256380387ecf115435ada82 100644 (file)
@@ -146,8 +146,15 @@ enum imsg_type {
        IMSG_DEBUG_UPDATE,
        IMSG_LOG,
        IMSG_ACL_CHECK,
-       IMSG_GET_LABEL_CHUNK,
-       IMSG_RELEASE_LABEL_CHUNK
+       IMSG_INIT
+};
+
+struct ldpd_init {
+       char             user[256];
+       char             group[256];
+       char             ctl_sock_path[MAXPATHLEN];
+       char             zclient_serv_path[MAXPATHLEN];
+       u_short          instance;
 };
 
 union ldpd_addr {
@@ -439,6 +446,12 @@ enum ldpd_process {
        PROC_LDE_ENGINE
 } ldpd_process;
 
+static const char * const log_procnames[] = {
+       "parent",
+       "ldpe",
+       "lde"
+};
+
 enum socket_type {
        LDP_SOCKET_DISC,
        LDP_SOCKET_EDISC,
@@ -504,7 +517,6 @@ struct ldpd_af_global {
 struct ldpd_global {
        int                      cmd_opts;
        int                      sighup;
-       time_t                   uptime;
        struct in_addr           rtr_id;
        struct ldpd_af_global    ipv4;
        struct ldpd_af_global    ipv6;
@@ -648,6 +660,7 @@ struct ctl_pw {
 
 extern struct ldpd_conf                *ldpd_conf, *vty_conf;
 extern struct ldpd_global       global;
+extern struct ldpd_init                 init;
 
 /* parse.y */
 struct ldpd_conf       *parse_config(char *);
@@ -761,6 +774,30 @@ int                 sock_set_ipv6_mcast_hops(int, int);
 int             sock_set_ipv6_mcast(struct iface *);
 int             sock_set_ipv6_mcast_loop(int);
 
+/* logmsg.h */
+struct in6_addr;
+union ldpd_addr;
+struct hello_source;
+struct fec;
+
+const char     *log_sockaddr(void *);
+const char     *log_in6addr(const struct in6_addr *);
+const char     *log_in6addr_scope(const struct in6_addr *, unsigned int);
+const char     *log_addr(int, const union ldpd_addr *);
+char           *log_label(uint32_t);
+const char     *log_time(time_t);
+char           *log_hello_src(const struct hello_source *);
+const char     *log_map(const struct map *);
+const char     *log_fec(const struct fec *);
+const char     *af_name(int);
+const char     *socket_name(int);
+const char     *nbr_state_name(int);
+const char     *if_state_name(int);
+const char     *if_type_name(enum iface_type);
+const char     *msg_name(uint16_t);
+const char     *status_code_name(uint32_t);
+const char     *pw_type_name(uint16_t);
+
 /* quagga */
 extern struct thread_master    *master;
 extern char                     ctl_sock_path[MAXPATHLEN];
index 1bec3d2a958cd08532db799f5390d71f7263c626..20cc9f7444290bef31c86e05e9e8873b7cfa5b66 100644 (file)
@@ -103,46 +103,17 @@ static struct quagga_signal_t ldpe_signals[] =
 
 /* label distribution protocol engine */
 void
-ldpe(const char *user, const char *group, const char *ctl_path)
+ldpe(void)
 {
        struct thread            thread;
 
-       leconf = config_new_empty();
-
 #ifdef HAVE_SETPROCTITLE
        setproctitle("ldp engine");
 #endif
        ldpd_process = PROC_LDP_ENGINE;
-
-       LIST_INIT(&global.addr_list);
-       RB_INIT(&global.adj_tree);
-       TAILQ_INIT(&global.pending_conns);
-       if (inet_pton(AF_INET, AllRouters_v4, &global.mcast_addr_v4) != 1)
-               fatal("inet_pton");
-       if (inet_pton(AF_INET6, AllRouters_v6, &global.mcast_addr_v6) != 1)
-               fatal("inet_pton");
-#ifdef __OpenBSD__
-       global.pfkeysock = pfkey_init();
-#endif
-
-       /* drop privileges */
-       if (user)
-               ldpe_privs.user = user;
-       if (group)
-               ldpe_privs.group = group;
-       zprivs_init(&ldpe_privs);
-
-       strlcpy(ctl_sock_path, ctl_path, sizeof(ctl_sock_path));
-       if (control_init() == -1)
-               fatalx("control socket setup failed");
-
-#ifdef HAVE_PLEDGE
-       if (pledge("stdio cpath inet mcast recvfd", NULL) == -1)
-               fatal("pledge");
-#endif
+       log_procname = log_procnames[ldpd_process];
 
        master = thread_master_create();
-       accept_init();
 
        /* setup signal handler */
        signal_init(master, array_size(ldpe_signals), ldpe_signals);
@@ -160,7 +131,45 @@ ldpe(const char *user, const char *group, const char *ctl_path)
                fatal(NULL);
        imsg_init(&iev_main_sync->ibuf, LDPD_FD_SYNC);
 
+       /* create base configuration */
+       leconf = config_new_empty();
+
+       /* Fetch next active thread. */
+       while (thread_fetch(master, &thread))
+               thread_call(&thread);
+}
+
+void
+ldpe_init(struct ldpd_init *init)
+{
+       /* drop privileges */
+       if (init->user)
+               ldpe_privs.user = init->user;
+       if (init->group)
+               ldpe_privs.group = init->group;
+       zprivs_init(&ldpe_privs);
+
+       /* listen on ldpd control socket */
+       strlcpy(ctl_sock_path, init->ctl_sock_path, sizeof(ctl_sock_path));
+       if (control_init(ctl_sock_path) == -1)
+               fatalx("control socket setup failed");
+       TAILQ_INIT(&ctl_conns);
+       control_listen();
+
+#ifdef HAVE_PLEDGE
+       if (pledge("stdio cpath inet mcast recvfd", NULL) == -1)
+               fatal("pledge");
+#endif
+
+       LIST_INIT(&global.addr_list);
+       RB_INIT(&global.adj_tree);
+       TAILQ_INIT(&global.pending_conns);
+       if (inet_pton(AF_INET, AllRouters_v4, &global.mcast_addr_v4) != 1)
+               fatal("inet_pton");
+       if (inet_pton(AF_INET6, AllRouters_v6, &global.mcast_addr_v6) != 1)
+               fatal("inet_pton");
 #ifdef __OpenBSD__
+       global.pfkeysock = pfkey_init();
        if (sysdep.no_pfkey == 0)
                pfkey_ev = thread_add_read(master, ldpe_dispatch_pfkey,
                    NULL, global.pfkeysock);
@@ -174,16 +183,10 @@ ldpe(const char *user, const char *group, const char *ctl_path)
        global.ipv6.ldp_edisc_socket = -1;
        global.ipv6.ldp_session_socket = -1;
 
-       /* listen on ldpd control socket */
-       TAILQ_INIT(&ctl_conns);
-       control_listen();
-
        if ((pkt_ptr = calloc(1, IBUF_READ_SIZE)) == NULL)
                fatal(__func__);
 
-       /* Fetch next active thread. */
-       while (thread_fetch(master, &thread))
-               thread_call(&thread);
+       accept_init();
 }
 
 static void
@@ -193,16 +196,18 @@ ldpe_shutdown(void)
        struct adj              *adj;
 
        /* close pipes */
-       msgbuf_write(&iev_lde->ibuf.w);
-       msgbuf_clear(&iev_lde->ibuf.w);
-       close(iev_lde->ibuf.fd);
+       if (iev_lde) {
+               msgbuf_write(&iev_lde->ibuf.w);
+               msgbuf_clear(&iev_lde->ibuf.w);
+               close(iev_lde->ibuf.fd);
+       }
        msgbuf_write(&iev_main->ibuf.w);
        msgbuf_clear(&iev_main->ibuf.w);
        close(iev_main->ibuf.fd);
        msgbuf_clear(&iev_main_sync->ibuf.w);
        close(iev_main_sync->ibuf.fd);
 
-       control_cleanup();
+       control_cleanup(ctl_sock_path);
        config_clear(leconf);
 
 #ifdef __OpenBSD__
@@ -223,7 +228,8 @@ ldpe_shutdown(void)
                adj_del(adj, S_SHUTDOWN);
 
        /* clean up */
-       free(iev_lde);
+       if (iev_lde)
+               free(iev_lde);
        free(iev_main);
        free(iev_main_sync);
        free(pkt_ptr);
@@ -239,6 +245,13 @@ ldpe_imsg_compose_parent(int type, pid_t pid, void *data, uint16_t datalen)
        return (imsg_compose_event(iev_main, type, 0, pid, -1, data, datalen));
 }
 
+void
+ldpe_imsg_compose_parent_sync(int type, pid_t pid, void *data, uint16_t datalen)
+{
+       imsg_compose_event(iev_main_sync, type, 0, pid, -1, data, datalen);
+       imsg_flush(&iev_main_sync->ibuf);
+}
+
 int
 ldpe_imsg_compose_lde(int type, uint32_t peerid, pid_t pid, void *data,
     uint16_t datalen)
@@ -351,6 +364,14 @@ ldpe_dispatch_main(struct thread *thread)
                        iev_lde->handler_write = ldp_write_handler;
                        iev_lde->ev_write = NULL;
                        break;
+               case IMSG_INIT:
+                       if (imsg.hdr.len != IMSG_HEADER_SIZE +
+                           sizeof(struct ldpd_init))
+                               fatalx("INIT imsg with wrong len");
+
+                       memcpy(&init, imsg.data, sizeof(init));
+                       ldpe_init(&init);
+                       break;
                case IMSG_CLOSE_SOCKETS:
                        af = imsg.hdr.peerid;
 
index a3f41a8b9fa12f1914fb59e0d1eb1a8e2c10c97e..d34ca4dc246542a09be32d0696f88e78e0aea1b1 100644 (file)
@@ -195,9 +195,11 @@ int         tlv_decode_fec_elm(struct nbr *, struct ldp_msg *, char *,
            uint16_t, struct map *);
 
 /* ldpe.c */
-void            ldpe(const char *, const char *, const char *);
+void            ldpe(void);
+void            ldpe_init(struct ldpd_init *);
 int             ldpe_imsg_compose_parent(int, pid_t, void *,
                    uint16_t);
+void            ldpe_imsg_compose_parent_sync(int, pid_t, void *, uint16_t);
 int             ldpe_imsg_compose_lde(int, uint32_t, pid_t, void *,
                    uint16_t);
 int             ldpe_acl_check(char *, int, union ldpd_addr *, uint8_t);
index 407668bb03763f2f7505c5dd21dbcb2887043986..b138e5754aa7762890c3e6d124c722718368024c 100644 (file)
 
 #include <lib/log.h>
 #include <lib/log_int.h>
-#include "mpls.h"
 
-static const char * const procnames[] = {
-       "parent",
-       "ldpe",
-       "lde"
-};
-
-void            vlog(int, const char *, va_list);
+const char     *log_procname;
 
 void
 logit(int pri, const char *fmt, ...)
@@ -53,11 +46,13 @@ vlog(int pri, const char *fmt, va_list ap)
        switch (ldpd_process) {
        case PROC_LDE_ENGINE:
                vsnprintf(buf, sizeof(buf), fmt, ap);
-               lde_imsg_compose_parent(IMSG_LOG, pri, buf, strlen(buf) + 1);
+               lde_imsg_compose_parent_sync(IMSG_LOG, pri, buf,
+                   strlen(buf) + 1);
                break;
        case PROC_LDP_ENGINE:
                vsnprintf(buf, sizeof(buf), fmt, ap);
-               ldpe_imsg_compose_parent(IMSG_LOG, pri, buf, strlen(buf) + 1);
+               ldpe_imsg_compose_parent_sync(IMSG_LOG, pri, buf,
+                   strlen(buf) + 1);
                break;
        case PROC_MAIN:
                vzlog(pri, fmt, ap);
@@ -73,16 +68,16 @@ log_warn(const char *emsg, ...)
 
        /* best effort to even work in out of memory situations */
        if (emsg == NULL)
-               logit(LOG_CRIT, "%s", strerror(errno));
+               logit(LOG_ERR, "%s", strerror(errno));
        else {
                va_start(ap, emsg);
 
                if (asprintf(&nfmt, "%s: %s", emsg, strerror(errno)) == -1) {
                        /* we tried it... */
-                       vlog(LOG_CRIT, emsg, ap);
-                       logit(LOG_CRIT, "%s", strerror(errno));
+                       vlog(LOG_ERR, emsg, ap);
+                       logit(LOG_ERR, "%s", strerror(errno));
                } else {
-                       vlog(LOG_CRIT, nfmt, ap);
+                       vlog(LOG_ERR, nfmt, ap);
                        free(nfmt);
                }
                va_end(ap);
@@ -95,7 +90,7 @@ log_warnx(const char *emsg, ...)
        va_list  ap;
 
        va_start(ap, emsg);
-       vlog(LOG_CRIT, emsg, ap);
+       vlog(LOG_ERR, emsg, ap);
        va_end(ap);
 }
 
@@ -133,15 +128,15 @@ void
 fatal(const char *emsg)
 {
        if (emsg == NULL)
-               logit(LOG_CRIT, "fatal in %s: %s", procnames[ldpd_process],
+               logit(LOG_CRIT, "fatal in %s: %s", log_procname,
                    strerror(errno));
        else
                if (errno)
                        logit(LOG_CRIT, "fatal in %s: %s: %s",
-                           procnames[ldpd_process], emsg, strerror(errno));
+                           log_procname, emsg, strerror(errno));
                else
                        logit(LOG_CRIT, "fatal in %s: %s",
-                           procnames[ldpd_process], emsg);
+                           log_procname, emsg);
 
        exit(1);
 }
@@ -152,465 +147,3 @@ fatalx(const char *emsg)
        errno = 0;
        fatal(emsg);
 }
-
-#define NUM_LOGS       4
-const char *
-log_sockaddr(void *vp)
-{
-       static char      buf[NUM_LOGS][NI_MAXHOST];
-       static int       round = 0;
-       struct sockaddr *sa = vp;
-
-       round = (round + 1) % NUM_LOGS;
-
-       if (getnameinfo(sa, sockaddr_len(sa), buf[round], NI_MAXHOST, NULL, 0,
-           NI_NUMERICHOST))
-               return ("(unknown)");
-       else
-               return (buf[round]);
-}
-
-const char *
-log_in6addr(const struct in6_addr *addr)
-{
-       struct sockaddr_in6     sa_in6;
-
-       memset(&sa_in6, 0, sizeof(sa_in6));
-#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
-       sa_in6.sin6_len = sizeof(sa_in6);
-#endif
-       sa_in6.sin6_family = AF_INET6;
-       sa_in6.sin6_addr = *addr;
-
-       recoverscope(&sa_in6);
-
-       return (log_sockaddr(&sa_in6));
-}
-
-const char *
-log_in6addr_scope(const struct in6_addr *addr, unsigned int ifindex)
-{
-       struct sockaddr_in6     sa_in6;
-
-       memset(&sa_in6, 0, sizeof(sa_in6));
-#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
-       sa_in6.sin6_len = sizeof(sa_in6);
-#endif
-       sa_in6.sin6_family = AF_INET6;
-       sa_in6.sin6_addr = *addr;
-
-       addscope(&sa_in6, ifindex);
-
-       return (log_sockaddr(&sa_in6));
-}
-
-const char *
-log_addr(int af, const union ldpd_addr *addr)
-{
-       static char      buf[NUM_LOGS][INET6_ADDRSTRLEN];
-       static int       round = 0;
-
-       switch (af) {
-       case AF_INET:
-               round = (round + 1) % NUM_LOGS;
-               if (inet_ntop(AF_INET, &addr->v4, buf[round],
-                   sizeof(buf[round])) == NULL)
-                       return ("???");
-               return (buf[round]);
-       case AF_INET6:
-               return (log_in6addr(&addr->v6));
-       default:
-               break;
-       }
-
-       return ("???");
-}
-
-#define        TF_BUFS 4
-#define        TF_LEN  32
-
-char *
-log_label(uint32_t label)
-{
-       char            *buf;
-       static char      tfbuf[TF_BUFS][TF_LEN];        /* ring buffer */
-       static int       idx = 0;
-
-       buf = tfbuf[idx++];
-       if (idx == TF_BUFS)
-               idx = 0;
-
-       switch (label) {
-       case NO_LABEL:
-               snprintf(buf, TF_LEN, "-");
-               break;
-       case MPLS_LABEL_IMPLNULL:
-               snprintf(buf, TF_LEN, "imp-null");
-               break;
-       case MPLS_LABEL_IPV4NULL:
-       case MPLS_LABEL_IPV6NULL:
-               snprintf(buf, TF_LEN, "exp-null");
-               break;
-       default:
-               snprintf(buf, TF_LEN, "%u", label);
-               break;
-       }
-
-       return (buf);
-}
-
-const char *
-log_time(time_t t)
-{
-       char            *buf;
-       static char      tfbuf[TF_BUFS][TF_LEN];        /* ring buffer */
-       static int       idx = 0;
-       unsigned int     sec, min, hrs, day, week;
-
-       buf = tfbuf[idx++];
-       if (idx == TF_BUFS)
-               idx = 0;
-
-       week = t;
-
-       sec = week % 60;
-       week /= 60;
-       min = week % 60;
-       week /= 60;
-       hrs = week % 24;
-       week /= 24;
-       day = week % 7;
-       week /= 7;
-
-       if (week > 0)
-               snprintf(buf, TF_LEN, "%02uw%01ud%02uh", week, day, hrs);
-       else if (day > 0)
-               snprintf(buf, TF_LEN, "%01ud%02uh%02um", day, hrs, min);
-       else
-               snprintf(buf, TF_LEN, "%02u:%02u:%02u", hrs, min, sec);
-
-       return (buf);
-}
-
-char *
-log_hello_src(const struct hello_source *src)
-{
-       static char buf[64];
-
-       switch (src->type) {
-       case HELLO_LINK:
-               snprintf(buf, sizeof(buf), "iface %s",
-                   src->link.ia->iface->name);
-               break;
-       case HELLO_TARGETED:
-               snprintf(buf, sizeof(buf), "source %s",
-                   log_addr(src->target->af, &src->target->addr));
-               break;
-       }
-
-       return (buf);
-}
-
-const char *
-log_map(const struct map *map)
-{
-       static char     buf[128];
-
-       switch (map->type) {
-       case MAP_TYPE_WILDCARD:
-               if (snprintf(buf, sizeof(buf), "wildcard") < 0)
-                       return ("???");
-               break;
-       case MAP_TYPE_PREFIX:
-               if (snprintf(buf, sizeof(buf), "%s/%u",
-                   log_addr(map->fec.prefix.af, &map->fec.prefix.prefix),
-                   map->fec.prefix.prefixlen) == -1)
-                       return ("???");
-               break;
-       case MAP_TYPE_PWID:
-               if (snprintf(buf, sizeof(buf), "pw-id %u group-id %u (%s)",
-                   map->fec.pwid.pwid, map->fec.pwid.group_id,
-                   pw_type_name(map->fec.pwid.type)) == -1)
-                       return ("???");
-               break;
-       case MAP_TYPE_TYPED_WCARD:
-               if (snprintf(buf, sizeof(buf), "typed wildcard") < 0)
-                       return ("???");
-               switch (map->fec.twcard.type) {
-               case MAP_TYPE_PREFIX:
-                       if (snprintf(buf + strlen(buf), sizeof(buf) -
-                           strlen(buf), " (prefix, address-family %s)",
-                           af_name(map->fec.twcard.u.prefix_af)) < 0)
-                               return ("???");
-                       break;
-               case MAP_TYPE_PWID:
-                       if (snprintf(buf + strlen(buf), sizeof(buf) -
-                           strlen(buf), " (pwid, type %s)",
-                           pw_type_name(map->fec.twcard.u.pw_type)) < 0)
-                               return ("???");
-                       break;
-               default:
-                       if (snprintf(buf + strlen(buf), sizeof(buf) -
-                           strlen(buf), " (unknown type)") < 0)
-                               return ("???");
-                       break;
-               }
-               break;
-       default:
-               return ("???");
-       }
-
-       return (buf);
-}
-
-const char *
-log_fec(const struct fec *fec)
-{
-       static char     buf[64];
-       union ldpd_addr addr;
-
-       switch (fec->type) {
-       case FEC_TYPE_IPV4:
-               addr.v4 = fec->u.ipv4.prefix;
-               if (snprintf(buf, sizeof(buf), "ipv4 %s/%u",
-                   log_addr(AF_INET, &addr), fec->u.ipv4.prefixlen) == -1)
-                       return ("???");
-               break;
-       case FEC_TYPE_IPV6:
-               addr.v6 = fec->u.ipv6.prefix;
-               if (snprintf(buf, sizeof(buf), "ipv6 %s/%u",
-                   log_addr(AF_INET6, &addr), fec->u.ipv6.prefixlen) == -1)
-                       return ("???");
-               break;
-       case FEC_TYPE_PWID:
-               if (snprintf(buf, sizeof(buf),
-                   "pwid %u (%s) - %s",
-                   fec->u.pwid.pwid, pw_type_name(fec->u.pwid.type),
-                   inet_ntoa(fec->u.pwid.lsr_id)) == -1)
-                       return ("???");
-               break;
-       default:
-               return ("???");
-       }
-
-       return (buf);
-}
-
-/* names */
-const char *
-af_name(int af)
-{
-       switch (af) {
-       case AF_INET:
-               return ("ipv4");
-       case AF_INET6:
-               return ("ipv6");
-#ifdef AF_MPLS
-       case AF_MPLS:
-               return ("mpls");
-#endif
-       default:
-               return ("UNKNOWN");
-       }
-}
-
-const char *
-socket_name(int type)
-{
-       switch (type) {
-       case LDP_SOCKET_DISC:
-               return ("discovery");
-       case LDP_SOCKET_EDISC:
-               return ("extended discovery");
-       case LDP_SOCKET_SESSION:
-               return ("session");
-       default:
-               return ("UNKNOWN");
-       }
-}
-
-const char *
-nbr_state_name(int state)
-{
-       switch (state) {
-       case NBR_STA_PRESENT:
-               return ("PRESENT");
-       case NBR_STA_INITIAL:
-               return ("INITIALIZED");
-       case NBR_STA_OPENREC:
-               return ("OPENREC");
-       case NBR_STA_OPENSENT:
-               return ("OPENSENT");
-       case NBR_STA_OPER:
-               return ("OPERATIONAL");
-       default:
-               return ("UNKNOWN");
-       }
-}
-
-const char *
-if_state_name(int state)
-{
-       switch (state) {
-       case IF_STA_DOWN:
-               return ("DOWN");
-       case IF_STA_ACTIVE:
-               return ("ACTIVE");
-       default:
-               return ("UNKNOWN");
-       }
-}
-
-const char *
-if_type_name(enum iface_type type)
-{
-       switch (type) {
-       case IF_TYPE_POINTOPOINT:
-               return ("POINTOPOINT");
-       case IF_TYPE_BROADCAST:
-               return ("BROADCAST");
-       }
-       /* NOTREACHED */
-       return ("UNKNOWN");
-}
-
-const char *
-msg_name(uint16_t msg)
-{
-       static char buf[16];
-
-       switch (msg) {
-       case MSG_TYPE_NOTIFICATION:
-               return ("notification");
-       case MSG_TYPE_HELLO:
-               return ("hello");
-       case MSG_TYPE_INIT:
-               return ("initialization");
-       case MSG_TYPE_KEEPALIVE:
-               return ("keepalive");
-       case MSG_TYPE_CAPABILITY:
-               return ("capability");
-       case MSG_TYPE_ADDR:
-               return ("address");
-       case MSG_TYPE_ADDRWITHDRAW:
-               return ("address withdraw");
-       case MSG_TYPE_LABELMAPPING:
-               return ("label mapping");
-       case MSG_TYPE_LABELREQUEST:
-               return ("label request");
-       case MSG_TYPE_LABELWITHDRAW:
-               return ("label withdraw");
-       case MSG_TYPE_LABELRELEASE:
-               return ("label release");
-       case MSG_TYPE_LABELABORTREQ:
-       default:
-               snprintf(buf, sizeof(buf), "[%08x]", msg);
-               return (buf);
-       }
-}
-
-const char *
-status_code_name(uint32_t status)
-{
-       static char buf[16];
-
-       switch (status) {
-       case S_SUCCESS:
-               return ("Success");
-       case S_BAD_LDP_ID:
-               return ("Bad LDP Identifier");
-       case S_BAD_PROTO_VER:
-               return ("Bad Protocol Version");
-       case S_BAD_PDU_LEN:
-               return ("Bad PDU Length");
-       case S_UNKNOWN_MSG:
-               return ("Unknown Message Type");
-       case S_BAD_MSG_LEN:
-               return ("Bad Message Length");
-       case S_UNKNOWN_TLV:
-               return ("Unknown TLV");
-       case S_BAD_TLV_LEN:
-               return ("Bad TLV Length");
-       case S_BAD_TLV_VAL:
-               return ("Malformed TLV Value");
-       case S_HOLDTIME_EXP:
-               return ("Hold Timer Expired");
-       case S_SHUTDOWN:
-               return ("Shutdown");
-       case S_LOOP_DETECTED:
-               return ("Loop Detected");
-       case S_UNKNOWN_FEC:
-               return ("Unknown FEC");
-       case S_NO_ROUTE:
-               return ("No Route");
-       case S_NO_LABEL_RES:
-               return ("No Label Resources");
-       case S_AVAILABLE:
-               return ("Label Resources Available");
-       case S_NO_HELLO:
-               return ("Session Rejected, No Hello");
-       case S_PARM_ADV_MODE:
-               return ("Rejected Advertisement Mode Parameter");
-       case S_MAX_PDU_LEN:
-               return ("Rejected Max PDU Length Parameter");
-       case S_PARM_L_RANGE:
-               return ("Rejected Label Range Parameter");
-       case S_KEEPALIVE_TMR:
-               return ("KeepAlive Timer Expired");
-       case S_LAB_REQ_ABRT:
-               return ("Label Request Aborted");
-       case S_MISS_MSG:
-               return ("Missing Message Parameters");
-       case S_UNSUP_ADDR:
-               return ("Unsupported Address Family");
-       case S_KEEPALIVE_BAD:
-               return ("Bad KeepAlive Time");
-       case S_INTERN_ERR:
-               return ("Internal Error");
-       case S_ILLEGAL_CBIT:
-               return ("Illegal C-Bit");
-       case S_WRONG_CBIT:
-               return ("Wrong C-Bit");
-       case S_INCPT_BITRATE:
-               return ("Incompatible bit-rate");
-       case S_CEP_MISCONF:
-               return ("CEP-TDM mis-configuration");
-       case S_PW_STATUS:
-               return ("PW Status");
-       case S_UNASSIGN_TAI:
-               return ("Unassigned/Unrecognized TAI");
-       case S_MISCONF_ERR:
-               return ("Generic Misconfiguration Error");
-       case S_WITHDRAW_MTHD:
-               return ("Label Withdraw PW Status Method");
-       case S_UNSSUPORTDCAP:
-               return ("Unsupported Capability");
-       case S_ENDOFLIB:
-               return ("End-of-LIB");
-       case S_TRANS_MISMTCH:
-               return ("Transport Connection Mismatch");
-       case S_DS_NONCMPLNCE:
-               return ("Dual-Stack Noncompliance");
-       default:
-               snprintf(buf, sizeof(buf), "[%08x]", status);
-               return (buf);
-       }
-}
-
-const char *
-pw_type_name(uint16_t pw_type)
-{
-       static char buf[64];
-
-       switch (pw_type) {
-       case PW_TYPE_ETHERNET_TAGGED:
-               return ("Eth Tagged");
-       case PW_TYPE_ETHERNET:
-               return ("Ethernet");
-       case PW_TYPE_WILDCARD:
-               return ("Wildcard");
-       default:
-               snprintf(buf, sizeof(buf), "[%0x]", pw_type);
-               return (buf);
-       }
-}
index 4d6da43cac9b6c6e411cdbf142e5434f6d350ad7..8c236ff5fe3f3bd3b0e95626fdeb89fac29d1b11 100644 (file)
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#ifndef _LOG_H_
-#define        _LOG_H_
+#ifndef LOG_H
+#define LOG_H
 
 #include <stdarg.h>
 
-struct in6_addr;
-union ldpd_addr;
-struct hello_source;
-struct fec;
+extern const char      *log_procname;
 
-void            logit(int, const char *, ...)
-                       __attribute__((__format__ (printf, 2, 3)));
-void            log_warn(const char *, ...)
-                       __attribute__((__format__ (printf, 1, 2)));
-void            log_warnx(const char *, ...)
-                       __attribute__((__format__ (printf, 1, 2)));
-void            log_info(const char *, ...)
-                       __attribute__((__format__ (printf, 1, 2)));
-void            log_notice(const char *, ...)
-                       __attribute__((__format__ (printf, 1, 2)));
-void            log_debug(const char *, ...)
-                       __attribute__((__format__ (printf, 1, 2)));
-void            fatal(const char *)
-                       __attribute__ ((noreturn))
-                       __attribute__((__format__ (printf, 1, 0)));
-void            fatalx(const char *)
-                       __attribute__ ((noreturn))
-                       __attribute__((__format__ (printf, 1, 0)));
-const char     *log_sockaddr(void *);
-const char     *log_in6addr(const struct in6_addr *);
-const char     *log_in6addr_scope(const struct in6_addr *, unsigned int);
-const char     *log_addr(int, const union ldpd_addr *);
-char           *log_label(uint32_t);
-const char     *log_time(time_t);
-char           *log_hello_src(const struct hello_source *);
-const char     *log_map(const struct map *);
-const char     *log_fec(const struct fec *);
-const char     *af_name(int);
-const char     *socket_name(int);
-const char     *nbr_state_name(int);
-const char     *if_state_name(int);
-const char     *if_type_name(enum iface_type);
-const char     *msg_name(uint16_t);
-const char     *status_code_name(uint32_t);
-const char     *pw_type_name(uint16_t);
+void    logit(int, const char *, ...)
+               __attribute__((__format__ (printf, 2, 3)));
+void    vlog(int, const char *, va_list)
+               __attribute__((__format__ (printf, 2, 0)));
+void    log_warn(const char *, ...)
+               __attribute__((__format__ (printf, 1, 2)));
+void    log_warnx(const char *, ...)
+               __attribute__((__format__ (printf, 1, 2)));
+void    log_info(const char *, ...)
+               __attribute__((__format__ (printf, 1, 2)));
+void    log_notice(const char *, ...)
+               __attribute__((__format__ (printf, 1, 2)));
+void    log_debug(const char *, ...)
+               __attribute__((__format__ (printf, 1, 2)));
+void    fatal(const char *)
+               __attribute__ ((noreturn))
+               __attribute__((__format__ (printf, 1, 0)));
+void    fatalx(const char *)
+               __attribute__ ((noreturn))
+               __attribute__((__format__ (printf, 1, 0)));
 
-#endif /* _LOG_H_ */
+#endif /* LOG_H */
diff --git a/ldpd/logmsg.c b/ldpd/logmsg.c
new file mode 100644 (file)
index 0000000..c819b33
--- /dev/null
@@ -0,0 +1,487 @@
+/*     $OpenBSD$ */
+
+/*
+ * Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <zebra.h>
+
+#include "mpls.h"
+
+#include "ldpd.h"
+#include "ldpe.h"
+#include "lde.h"
+
+#define NUM_LOGS       4
+const char *
+log_sockaddr(void *vp)
+{
+       static char      buf[NUM_LOGS][NI_MAXHOST];
+       static int       round = 0;
+       struct sockaddr *sa = vp;
+
+       round = (round + 1) % NUM_LOGS;
+
+       if (getnameinfo(sa, sockaddr_len(sa), buf[round], NI_MAXHOST, NULL, 0,
+           NI_NUMERICHOST))
+               return ("(unknown)");
+       else
+               return (buf[round]);
+}
+
+const char *
+log_in6addr(const struct in6_addr *addr)
+{
+       struct sockaddr_in6     sa_in6;
+
+       memset(&sa_in6, 0, sizeof(sa_in6));
+#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
+       sa_in6.sin6_len = sizeof(sa_in6);
+#endif
+       sa_in6.sin6_family = AF_INET6;
+       sa_in6.sin6_addr = *addr;
+
+       recoverscope(&sa_in6);
+
+       return (log_sockaddr(&sa_in6));
+}
+
+const char *
+log_in6addr_scope(const struct in6_addr *addr, unsigned int ifindex)
+{
+       struct sockaddr_in6     sa_in6;
+
+       memset(&sa_in6, 0, sizeof(sa_in6));
+#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
+       sa_in6.sin6_len = sizeof(sa_in6);
+#endif
+       sa_in6.sin6_family = AF_INET6;
+       sa_in6.sin6_addr = *addr;
+
+       addscope(&sa_in6, ifindex);
+
+       return (log_sockaddr(&sa_in6));
+}
+
+const char *
+log_addr(int af, const union ldpd_addr *addr)
+{
+       static char      buf[NUM_LOGS][INET6_ADDRSTRLEN];
+       static int       round = 0;
+
+       switch (af) {
+       case AF_INET:
+               round = (round + 1) % NUM_LOGS;
+               if (inet_ntop(AF_INET, &addr->v4, buf[round],
+                   sizeof(buf[round])) == NULL)
+                       return ("???");
+               return (buf[round]);
+       case AF_INET6:
+               return (log_in6addr(&addr->v6));
+       default:
+               break;
+       }
+
+       return ("???");
+}
+
+#define        TF_BUFS 4
+#define        TF_LEN  32
+
+char *
+log_label(uint32_t label)
+{
+       char            *buf;
+       static char      tfbuf[TF_BUFS][TF_LEN];        /* ring buffer */
+       static int       idx = 0;
+
+       buf = tfbuf[idx++];
+       if (idx == TF_BUFS)
+               idx = 0;
+
+       switch (label) {
+       case NO_LABEL:
+               snprintf(buf, TF_LEN, "-");
+               break;
+       case MPLS_LABEL_IMPLNULL:
+               snprintf(buf, TF_LEN, "imp-null");
+               break;
+       case MPLS_LABEL_IPV4NULL:
+       case MPLS_LABEL_IPV6NULL:
+               snprintf(buf, TF_LEN, "exp-null");
+               break;
+       default:
+               snprintf(buf, TF_LEN, "%u", label);
+               break;
+       }
+
+       return (buf);
+}
+
+const char *
+log_time(time_t t)
+{
+       char            *buf;
+       static char      tfbuf[TF_BUFS][TF_LEN];        /* ring buffer */
+       static int       idx = 0;
+       unsigned int     sec, min, hrs, day, week;
+
+       buf = tfbuf[idx++];
+       if (idx == TF_BUFS)
+               idx = 0;
+
+       week = t;
+
+       sec = week % 60;
+       week /= 60;
+       min = week % 60;
+       week /= 60;
+       hrs = week % 24;
+       week /= 24;
+       day = week % 7;
+       week /= 7;
+
+       if (week > 0)
+               snprintf(buf, TF_LEN, "%02uw%01ud%02uh", week, day, hrs);
+       else if (day > 0)
+               snprintf(buf, TF_LEN, "%01ud%02uh%02um", day, hrs, min);
+       else
+               snprintf(buf, TF_LEN, "%02u:%02u:%02u", hrs, min, sec);
+
+       return (buf);
+}
+
+char *
+log_hello_src(const struct hello_source *src)
+{
+       static char buf[64];
+
+       switch (src->type) {
+       case HELLO_LINK:
+               snprintf(buf, sizeof(buf), "iface %s",
+                   src->link.ia->iface->name);
+               break;
+       case HELLO_TARGETED:
+               snprintf(buf, sizeof(buf), "source %s",
+                   log_addr(src->target->af, &src->target->addr));
+               break;
+       }
+
+       return (buf);
+}
+
+const char *
+log_map(const struct map *map)
+{
+       static char     buf[128];
+
+       switch (map->type) {
+       case MAP_TYPE_WILDCARD:
+               if (snprintf(buf, sizeof(buf), "wildcard") < 0)
+                       return ("???");
+               break;
+       case MAP_TYPE_PREFIX:
+               if (snprintf(buf, sizeof(buf), "%s/%u",
+                   log_addr(map->fec.prefix.af, &map->fec.prefix.prefix),
+                   map->fec.prefix.prefixlen) == -1)
+                       return ("???");
+               break;
+       case MAP_TYPE_PWID:
+               if (snprintf(buf, sizeof(buf), "pw-id %u group-id %u (%s)",
+                   map->fec.pwid.pwid, map->fec.pwid.group_id,
+                   pw_type_name(map->fec.pwid.type)) == -1)
+                       return ("???");
+               break;
+       case MAP_TYPE_TYPED_WCARD:
+               if (snprintf(buf, sizeof(buf), "typed wildcard") < 0)
+                       return ("???");
+               switch (map->fec.twcard.type) {
+               case MAP_TYPE_PREFIX:
+                       if (snprintf(buf + strlen(buf), sizeof(buf) -
+                           strlen(buf), " (prefix, address-family %s)",
+                           af_name(map->fec.twcard.u.prefix_af)) < 0)
+                               return ("???");
+                       break;
+               case MAP_TYPE_PWID:
+                       if (snprintf(buf + strlen(buf), sizeof(buf) -
+                           strlen(buf), " (pwid, type %s)",
+                           pw_type_name(map->fec.twcard.u.pw_type)) < 0)
+                               return ("???");
+                       break;
+               default:
+                       if (snprintf(buf + strlen(buf), sizeof(buf) -
+                           strlen(buf), " (unknown type)") < 0)
+                               return ("???");
+                       break;
+               }
+               break;
+       default:
+               return ("???");
+       }
+
+       return (buf);
+}
+
+const char *
+log_fec(const struct fec *fec)
+{
+       static char     buf[64];
+       union ldpd_addr addr;
+
+       switch (fec->type) {
+       case FEC_TYPE_IPV4:
+               addr.v4 = fec->u.ipv4.prefix;
+               if (snprintf(buf, sizeof(buf), "ipv4 %s/%u",
+                   log_addr(AF_INET, &addr), fec->u.ipv4.prefixlen) == -1)
+                       return ("???");
+               break;
+       case FEC_TYPE_IPV6:
+               addr.v6 = fec->u.ipv6.prefix;
+               if (snprintf(buf, sizeof(buf), "ipv6 %s/%u",
+                   log_addr(AF_INET6, &addr), fec->u.ipv6.prefixlen) == -1)
+                       return ("???");
+               break;
+       case FEC_TYPE_PWID:
+               if (snprintf(buf, sizeof(buf),
+                   "pwid %u (%s) - %s",
+                   fec->u.pwid.pwid, pw_type_name(fec->u.pwid.type),
+                   inet_ntoa(fec->u.pwid.lsr_id)) == -1)
+                       return ("???");
+               break;
+       default:
+               return ("???");
+       }
+
+       return (buf);
+}
+
+/* names */
+const char *
+af_name(int af)
+{
+       switch (af) {
+       case AF_INET:
+               return ("ipv4");
+       case AF_INET6:
+               return ("ipv6");
+#ifdef AF_MPLS
+       case AF_MPLS:
+               return ("mpls");
+#endif
+       default:
+               return ("UNKNOWN");
+       }
+}
+
+const char *
+socket_name(int type)
+{
+       switch (type) {
+       case LDP_SOCKET_DISC:
+               return ("discovery");
+       case LDP_SOCKET_EDISC:
+               return ("extended discovery");
+       case LDP_SOCKET_SESSION:
+               return ("session");
+       default:
+               return ("UNKNOWN");
+       }
+}
+
+const char *
+nbr_state_name(int state)
+{
+       switch (state) {
+       case NBR_STA_PRESENT:
+               return ("PRESENT");
+       case NBR_STA_INITIAL:
+               return ("INITIALIZED");
+       case NBR_STA_OPENREC:
+               return ("OPENREC");
+       case NBR_STA_OPENSENT:
+               return ("OPENSENT");
+       case NBR_STA_OPER:
+               return ("OPERATIONAL");
+       default:
+               return ("UNKNOWN");
+       }
+}
+
+const char *
+if_state_name(int state)
+{
+       switch (state) {
+       case IF_STA_DOWN:
+               return ("DOWN");
+       case IF_STA_ACTIVE:
+               return ("ACTIVE");
+       default:
+               return ("UNKNOWN");
+       }
+}
+
+const char *
+if_type_name(enum iface_type type)
+{
+       switch (type) {
+       case IF_TYPE_POINTOPOINT:
+               return ("POINTOPOINT");
+       case IF_TYPE_BROADCAST:
+               return ("BROADCAST");
+       }
+       /* NOTREACHED */
+       return ("UNKNOWN");
+}
+
+const char *
+msg_name(uint16_t msg)
+{
+       static char buf[16];
+
+       switch (msg) {
+       case MSG_TYPE_NOTIFICATION:
+               return ("notification");
+       case MSG_TYPE_HELLO:
+               return ("hello");
+       case MSG_TYPE_INIT:
+               return ("initialization");
+       case MSG_TYPE_KEEPALIVE:
+               return ("keepalive");
+       case MSG_TYPE_CAPABILITY:
+               return ("capability");
+       case MSG_TYPE_ADDR:
+               return ("address");
+       case MSG_TYPE_ADDRWITHDRAW:
+               return ("address withdraw");
+       case MSG_TYPE_LABELMAPPING:
+               return ("label mapping");
+       case MSG_TYPE_LABELREQUEST:
+               return ("label request");
+       case MSG_TYPE_LABELWITHDRAW:
+               return ("label withdraw");
+       case MSG_TYPE_LABELRELEASE:
+               return ("label release");
+       case MSG_TYPE_LABELABORTREQ:
+       default:
+               snprintf(buf, sizeof(buf), "[%08x]", msg);
+               return (buf);
+       }
+}
+
+const char *
+status_code_name(uint32_t status)
+{
+       static char buf[16];
+
+       switch (status) {
+       case S_SUCCESS:
+               return ("Success");
+       case S_BAD_LDP_ID:
+               return ("Bad LDP Identifier");
+       case S_BAD_PROTO_VER:
+               return ("Bad Protocol Version");
+       case S_BAD_PDU_LEN:
+               return ("Bad PDU Length");
+       case S_UNKNOWN_MSG:
+               return ("Unknown Message Type");
+       case S_BAD_MSG_LEN:
+               return ("Bad Message Length");
+       case S_UNKNOWN_TLV:
+               return ("Unknown TLV");
+       case S_BAD_TLV_LEN:
+               return ("Bad TLV Length");
+       case S_BAD_TLV_VAL:
+               return ("Malformed TLV Value");
+       case S_HOLDTIME_EXP:
+               return ("Hold Timer Expired");
+       case S_SHUTDOWN:
+               return ("Shutdown");
+       case S_LOOP_DETECTED:
+               return ("Loop Detected");
+       case S_UNKNOWN_FEC:
+               return ("Unknown FEC");
+       case S_NO_ROUTE:
+               return ("No Route");
+       case S_NO_LABEL_RES:
+               return ("No Label Resources");
+       case S_AVAILABLE:
+               return ("Label Resources Available");
+       case S_NO_HELLO:
+               return ("Session Rejected, No Hello");
+       case S_PARM_ADV_MODE:
+               return ("Rejected Advertisement Mode Parameter");
+       case S_MAX_PDU_LEN:
+               return ("Rejected Max PDU Length Parameter");
+       case S_PARM_L_RANGE:
+               return ("Rejected Label Range Parameter");
+       case S_KEEPALIVE_TMR:
+               return ("KeepAlive Timer Expired");
+       case S_LAB_REQ_ABRT:
+               return ("Label Request Aborted");
+       case S_MISS_MSG:
+               return ("Missing Message Parameters");
+       case S_UNSUP_ADDR:
+               return ("Unsupported Address Family");
+       case S_KEEPALIVE_BAD:
+               return ("Bad KeepAlive Time");
+       case S_INTERN_ERR:
+               return ("Internal Error");
+       case S_ILLEGAL_CBIT:
+               return ("Illegal C-Bit");
+       case S_WRONG_CBIT:
+               return ("Wrong C-Bit");
+       case S_INCPT_BITRATE:
+               return ("Incompatible bit-rate");
+       case S_CEP_MISCONF:
+               return ("CEP-TDM mis-configuration");
+       case S_PW_STATUS:
+               return ("PW Status");
+       case S_UNASSIGN_TAI:
+               return ("Unassigned/Unrecognized TAI");
+       case S_MISCONF_ERR:
+               return ("Generic Misconfiguration Error");
+       case S_WITHDRAW_MTHD:
+               return ("Label Withdraw PW Status Method");
+       case S_UNSSUPORTDCAP:
+               return ("Unsupported Capability");
+       case S_ENDOFLIB:
+               return ("End-of-LIB");
+       case S_TRANS_MISMTCH:
+               return ("Transport Connection Mismatch");
+       case S_DS_NONCMPLNCE:
+               return ("Dual-Stack Noncompliance");
+       default:
+               snprintf(buf, sizeof(buf), "[%08x]", status);
+               return (buf);
+       }
+}
+
+const char *
+pw_type_name(uint16_t pw_type)
+{
+       static char buf[64];
+
+       switch (pw_type) {
+       case PW_TYPE_ETHERNET_TAGGED:
+               return ("Eth Tagged");
+       case PW_TYPE_ETHERNET:
+               return ("Ethernet");
+       case PW_TYPE_WILDCARD:
+               return ("Wildcard");
+       default:
+               snprintf(buf, sizeof(buf), "[%0x]", pw_type);
+               return (buf);
+       }
+}
index f10faa4a54b3bcf06b602388a86cabed616f09b5..4a5f3c8fa4bbc9ad2081c184b6c42d413d6837ef 100644 (file)
@@ -237,6 +237,16 @@ recv_notification(struct nbr *nbr, char *buf, uint16_t len)
                if (nbr->state == NBR_STA_OPENSENT)
                        nbr_start_idtimer(nbr);
 
+               /*
+                * RFC 5036 - Section 3.5.1.1:
+                * "When an LSR receives a Shutdown message during session
+                * initialization, it SHOULD transmit a Shutdown message and
+                * then close the transport connection".
+                */
+               if (nbr->state != NBR_STA_OPER && nm.status_code == S_SHUTDOWN)
+                       send_notification(nbr->tcp, S_SHUTDOWN,
+                           msg.id, msg.type);
+
                nbr_fsm(nbr, NBR_EVT_CLOSE_SESSION);
                return (-1);
        }
index 46893b992bd5b2e2d0f193e47dc4c1613c4541f8..df6bd8e57a8849cc6b9654370bf624909680dd04 100644 (file)
@@ -27,7 +27,7 @@
 #include "sockopt.h"
 
 static struct iface            *disc_find_iface(unsigned int, int,
-                                   union ldpd_addr *, int);
+                                   union ldpd_addr *);
 static int                      session_read(struct thread *);
 static int                      session_write(struct thread *);
 static ssize_t                  session_get_pdu(struct ibuf_read *, char **);
@@ -134,7 +134,7 @@ disc_recv_packet(struct thread *thread)
        int                      af;
        union ldpd_addr          src;
        unsigned int             ifindex = 0;
-       struct iface            *iface;
+       struct iface            *iface = NULL;
        uint16_t                 len;
        struct ldp_hdr           ldp_hdr;
        uint16_t                 pdu_len;
@@ -212,9 +212,11 @@ disc_recv_packet(struct thread *thread)
        ifindex = getsockopt_ifindex(af, &m);
 
        /* find a matching interface */
-       iface = disc_find_iface(ifindex, af, &src, multicast);
-       if (iface == NULL)
-               return (0);
+       if (multicast) {
+               iface = disc_find_iface(ifindex, af, &src);
+               if (iface == NULL)
+                       return (0);
+       }
 
        /* check packet size */
        len = (uint16_t)r;
@@ -280,8 +282,7 @@ disc_recv_packet(struct thread *thread)
 }
 
 static struct iface *
-disc_find_iface(unsigned int ifindex, int af, union ldpd_addr *src,
-    int multicast)
+disc_find_iface(unsigned int ifindex, int af, union ldpd_addr *src)
 {
        struct iface    *iface;
        struct iface_af *ia;
@@ -299,7 +300,7 @@ disc_find_iface(unsigned int ifindex, int af, union ldpd_addr *src,
         * "Link-local IPv6 address MUST be used as the source IP address in
         * IPv6 LDP Link Hellos".
         */
-       if (multicast && af == AF_INET6 && !IN6_IS_ADDR_LINKLOCAL(&src->v6))
+       if (af == AF_INET6 && !IN6_IS_ADDR_LINKLOCAL(&src->v6))
                return (NULL);
 
        return (iface);
@@ -519,6 +520,8 @@ session_read(struct thread *thread)
                                        return (0);
                                }
                                break;
+                       case MSG_TYPE_NOTIFICATION:
+                               break;
                        default:
                                if (nbr->state != NBR_STA_OPER) {
                                        session_shutdown(nbr, S_SHUTDOWN,
@@ -661,8 +664,6 @@ session_shutdown(struct nbr *nbr, uint32_t status, uint32_t msg_id,
        case NBR_STA_OPENREC:
        case NBR_STA_OPENSENT:
        case NBR_STA_OPER:
-               log_debug("%s: lsr-id %s", __func__, inet_ntoa(nbr->id));
-
                send_notification(nbr->tcp, status, msg_id, msg_type);
 
                nbr_fsm(nbr, NBR_EVT_CLOSE_SESSION);