]> git.proxmox.com Git - mirror_frr.git/blobdiff - ldpd/lde.c
*: use frr_elevate_privs() (2/2: manual)
[mirror_frr.git] / ldpd / lde.c
index 582582babfe62f75f4c4c2fc3adf7b33cce3f495..03b62b482b26076fd10c0162d217dec626c2a6f7 100644 (file)
@@ -37,6 +37,7 @@
 #include "zclient.h"
 #include "stream.h"
 #include "network.h"
+#include "libfrr.h"
 
 static void             lde_shutdown(void);
 static int              lde_dispatch_imsg(struct thread *);
@@ -55,7 +56,7 @@ 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(unsigned short instance);
 static void             lde_label_list_init(void);
 static int              lde_get_label_chunk(void);
 static void             on_get_label_chunk_response(uint32_t start, uint32_t end);
@@ -76,7 +77,7 @@ struct thread_master *master;
 /* lde privileges */
 static zebra_capabilities_t _caps_p [] =
 {
-       /* none */
+       ZCAP_NET_ADMIN
 };
 
 static struct zebra_privs_t lde_privs =
@@ -171,7 +172,8 @@ lde_init(struct ldpd_init *init)
        lde_gc_start_timer();
 
        /* Init synchronous zclient and label list */
-       zclient_serv_path_set(init->zclient_serv_path);
+       frr_zclient_addr(&zclient_addr, &zclient_addr_len,
+                        init->zclient_serv_path);
        zclient_sync_init(init->instance);
        lde_label_list_init();
 }
@@ -183,11 +185,14 @@ lde_shutdown(void)
        if (iev_ldpe) {
                msgbuf_clear(&iev_ldpe->ibuf.w);
                close(iev_ldpe->ibuf.fd);
+               iev_ldpe->ibuf.fd = -1;
        }
        msgbuf_clear(&iev_main->ibuf.w);
        close(iev_main->ibuf.fd);
+       iev_main->ibuf.fd = -1;
        msgbuf_clear(&iev_main_sync->ibuf.w);
        close(iev_main_sync->ibuf.fd);
+       iev_main_sync->ibuf.fd = -1;
 
        lde_gc_stop_timer();
        lde_nbr_clear();
@@ -208,12 +213,16 @@ lde_shutdown(void)
 int
 lde_imsg_compose_parent(int type, pid_t pid, void *data, uint16_t datalen)
 {
+       if (iev_main->ibuf.fd == -1)
+               return (0);
        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)
 {
+       if (iev_main_sync->ibuf.fd == -1)
+               return;
        imsg_compose_event(iev_main_sync, type, 0, pid, -1, data, datalen);
        imsg_flush(&iev_main_sync->ibuf);
 }
@@ -222,6 +231,8 @@ int
 lde_imsg_compose_ldpe(int type, uint32_t peerid, pid_t pid, void *data,
     uint16_t datalen)
 {
+       if (iev_ldpe->ibuf.fd == -1)
+               return (0);
        return (imsg_compose_event(iev_ldpe, type, peerid, pid,
             -1, data, datalen));
 }
@@ -427,7 +438,7 @@ lde_dispatch_parent(struct thread *thread)
        struct imsg              imsg;
        struct kif              *kif;
        struct kroute           *kr;
-       int                      fd = THREAD_FD(thread);
+       int                      fd;
        struct imsgev           *iev = THREAD_ARG(thread);
        struct imsgbuf          *ibuf = &iev->ibuf;
        ssize_t                  n;
@@ -691,20 +702,20 @@ lde_update_label(struct fec_node *fn)
                switch (fn->fec.type) {
                case FEC_TYPE_IPV4:
                        if (!(ldeconf->ipv4.flags & F_LDPD_AF_EXPNULL))
-                               return (MPLS_LABEL_IMPLNULL);
+                               return (MPLS_LABEL_IMPLICIT_NULL);
                        if (lde_acl_check(ldeconf->ipv4.acl_label_expnull_for,
                            AF_INET, (union ldpd_addr *)&fn->fec.u.ipv4.prefix,
                            fn->fec.u.ipv4.prefixlen) != FILTER_PERMIT)
-                               return (MPLS_LABEL_IMPLNULL);
-                       return (MPLS_LABEL_IPV4NULL);
+                               return (MPLS_LABEL_IMPLICIT_NULL);
+                       return MPLS_LABEL_IPV4_EXPLICIT_NULL;
                case FEC_TYPE_IPV6:
                        if (!(ldeconf->ipv6.flags & F_LDPD_AF_EXPNULL))
-                               return (MPLS_LABEL_IMPLNULL);
+                               return (MPLS_LABEL_IMPLICIT_NULL);
                        if (lde_acl_check(ldeconf->ipv6.acl_label_expnull_for,
                            AF_INET6, (union ldpd_addr *)&fn->fec.u.ipv6.prefix,
                            fn->fec.u.ipv6.prefixlen) != FILTER_PERMIT)
-                               return (MPLS_LABEL_IMPLNULL);
-                       return (MPLS_LABEL_IPV6NULL);
+                               return (MPLS_LABEL_IMPLICIT_NULL);
+                       return MPLS_LABEL_IPV6_EXPLICIT_NULL;
                default:
                        fatalx("lde_update_label: unexpected fec type");
                        break;
@@ -756,11 +767,12 @@ lde_send_change_klabel(struct fec_node *fn, struct fec_nh *fnh)
                    sizeof(kr));
                break;
        case FEC_TYPE_PWID:
-               if (fn->local_label == NO_LABEL ||
+               pw = (struct l2vpn_pw *) fn->data;
+               if (!pw || fn->local_label == NO_LABEL ||
                    fnh->remote_label == NO_LABEL)
                        return;
 
-               pw = (struct l2vpn_pw *) fn->data;
+               pw->enabled = true;
                pw2zpw(pw, &zpw);
                zpw.local_label = fn->local_label;
                zpw.remote_label = fnh->remote_label;
@@ -807,6 +819,10 @@ lde_send_delete_klabel(struct fec_node *fn, struct fec_nh *fnh)
                break;
        case FEC_TYPE_PWID:
                pw = (struct l2vpn_pw *) fn->data;
+               if (!pw)
+                       return;
+
+               pw->enabled = false;
                pw2zpw(pw, &zpw);
                zpw.local_label = fn->local_label;
                zpw.remote_label = fnh->remote_label;
@@ -1308,8 +1324,11 @@ lde_nbr_clear(void)
 {
        struct lde_nbr  *ln;
 
-        while ((ln = RB_ROOT(nbr_tree, &lde_nbrs)) != NULL)
+       while (!RB_EMPTY(nbr_tree, &lde_nbrs)) {
+               ln = RB_ROOT(nbr_tree, &lde_nbrs);
+
                lde_nbr_del(ln);
+       }
 }
 
 static void
@@ -1506,11 +1525,15 @@ lde_change_egress_label(int af)
 
        /* explicitly withdraw all null labels */
        RB_FOREACH(ln, nbr_tree, &lde_nbrs) {
-               lde_send_labelwithdraw_wcard(ln, MPLS_LABEL_IMPLNULL);
+               lde_send_labelwithdraw_wcard(ln, MPLS_LABEL_IMPLICIT_NULL);
                if (ln->v4_enabled)
-                       lde_send_labelwithdraw_wcard(ln, MPLS_LABEL_IPV4NULL);
+                       lde_send_labelwithdraw_wcard(
+                               ln,
+                               MPLS_LABEL_IPV4_EXPLICIT_NULL);
                if (ln->v6_enabled)
-                       lde_send_labelwithdraw_wcard(ln, MPLS_LABEL_IPV6NULL);
+                       lde_send_labelwithdraw_wcard(
+                               ln,
+                               MPLS_LABEL_IPV6_EXPLICIT_NULL);
        }
 
        /* update label of connected routes */
@@ -1603,15 +1626,15 @@ lde_address_list_free(struct lde_nbr *ln)
        }
 }
 
-static void
-zclient_sync_init(u_short instance)
+static void zclient_sync_init(unsigned short instance)
 {
        /* Initialize special zclient for synchronous message exchanges. */
-       log_debug("Initializing synchronous zclient for label manager");
-       zclient_sync = zclient_new(master);
+       zclient_sync = zclient_new_notify(master, &zclient_options_default);
        zclient_sync->sock = -1;
        zclient_sync->redist_default = ZEBRA_ROUTE_LDP;
        zclient_sync->instance = instance;
+       zclient_sync->privs = &lde_privs;
+
        while (zclient_socket_connect(zclient_sync) < 0) {
                log_warnx("Error connecting synchronous zclient!");
                sleep(1);
@@ -1638,7 +1661,7 @@ lde_get_label_chunk(void)
        int              ret;
        uint32_t         start, end;
 
-       log_debug("Getting label chunk");
+       debug_labels("getting label chunk (size %u)", CHUNK_SIZE);
        ret = lm_get_label_chunk(zclient_sync, 0, CHUNK_SIZE, &start, &end);
        if (ret < 0) {
                log_warnx("Error getting label chunk!");
@@ -1668,7 +1691,7 @@ on_get_label_chunk_response(uint32_t start, uint32_t end)
 {
        struct label_chunk *new_label_chunk;
 
-       log_debug("Label Chunk assign: %u - %u", start, end);
+       debug_labels("label chunk assign: %u - %u", start, end);
 
        new_label_chunk = calloc(1, sizeof(struct label_chunk));
        if (!new_label_chunk) {
@@ -1691,7 +1714,8 @@ static uint32_t
 lde_get_next_label(void)
 {
        struct label_chunk      *label_chunk;
-       uint32_t                 i, pos, size;
+       uint32_t                 i, size;
+       uint64_t                 pos;
        uint32_t                 label = NO_LABEL;
 
        while (current_label_chunk) {