]> git.proxmox.com Git - mirror_frr.git/blobdiff - ldpd/ldpd.c
Merge remote-tracking branch 'frr/master' into tcp-zebra
[mirror_frr.git] / ldpd / ldpd.c
index 710dcd15f41d49853d672df5ef1e70d58f403387..80af2b14e5da6accde082303f01eae3427835f10 100644 (file)
@@ -53,6 +53,7 @@ static void            main_imsg_send_net_sockets(int);
 static void             main_imsg_send_net_socket(int, enum socket_type);
 static int              main_imsg_send_config(struct ldpd_conf *);
 static void             ldp_config_normalize(struct ldpd_conf *);
+static void             ldp_config_reset(struct ldpd_conf *);
 static void             ldp_config_reset_main(struct ldpd_conf *);
 static void             ldp_config_reset_af(struct ldpd_conf *, int);
 static void             ldp_config_reset_l2vpns(struct ldpd_conf *);
@@ -131,20 +132,13 @@ sighup(void)
 {
        log_info("SIGHUP received");
 
-       /* reset vty_conf */
-       ldp_config_reset_main(vty_conf);
-       ldp_config_reset_l2vpns(vty_conf);
-
-       /* read configuration file without applying any changes */
-       global.sighup = 1;
-       vty_read_config(ldpd_di.config_file, config_default);
-       global.sighup = 0;
-
        /*
-        * Apply the new configuration all at once, this way merge_config()
-        * will be the least disruptive as possible.
+        * Do a full configuration reload. In other words, reset vty_conf
+        * and build a new configuartion from scratch.
         */
-       ldp_reload(vty_conf);
+       ldp_config_reset(vty_conf);
+       vty_read_config(ldpd_di.config_file, config_default);
+       ldp_config_apply(NULL, vty_conf);
 }
 
 /* SIGINT / SIGTERM handler. */
@@ -262,7 +256,7 @@ main(int argc, char *argv[])
        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(),
+       strlcpy(init.zclient_serv_path, frr_zclientpath,
            sizeof(init.zclient_serv_path));
 
        argc -= optind;
@@ -277,9 +271,9 @@ main(int argc, char *argv[])
                exit(1);
        }
 
-       openzlog(ldpd_di.progname, "LDP", 0,
-           LOG_CONS | LOG_NDELAY | LOG_PID, LOG_DAEMON);
-
+       if (lflag || eflag)
+               openzlog(ldpd_di.progname, "LDP", 0,
+                        LOG_CONS | LOG_NDELAY | LOG_PID, LOG_DAEMON);
        if (lflag)
                lde();
        else if (eflag)
@@ -316,40 +310,30 @@ main(int argc, char *argv[])
        ldpe_pid = start_child(PROC_LDP_ENGINE, saved_argv0,
            pipe_parent2ldpe[1], pipe_parent2ldpe_sync[1]);
 
-       /* drop privileges */
-       zprivs_init(&ldpd_privs);
-
-       /* setup signal handler */
-       signal_init(master, array_size(ldp_signals), ldp_signals);
-
-       /* thread master */
-       master = thread_master_create();
+       master = frr_init();
 
-       /* library inits */
-       cmd_init(1);
        vty_config_lockless();
-       vty_init(master);
        vrf_init(NULL, NULL, NULL, NULL);
        access_list_init();
        ldp_vty_init();
        ldp_zebra_init(master);
 
-       /* create base configuration with sane defaults */
-       ldpd_conf = config_new_empty();
-       ldp_config_reset_main(ldpd_conf);
-
        /*
-        * Create vty_conf as a duplicate of the main configuration. All
-        * configuration requests (e.g. CLI) act on vty_conf and then call
-        * ldp_reload() to merge the changes into ldpd_conf.
+        * Create base configuration with sane defaults. All configuration
+        * requests (e.g. CLI) act on vty_conf and then call ldp_config_apply()
+        * to merge the changes into ldpd_conf, which contains the actual
+        * running configuration.
         */
+       ldpd_conf = config_new_empty();
        vty_conf = config_new_empty();
-       ldp_config_reset_main(vty_conf);
        QOBJ_REG(vty_conf, ldpd_conf);
 
        /* read configuration file and daemonize  */
        frr_config_fork();
 
+       /* apply configuration */
+       ldp_config_apply(NULL, vty_conf);
+
        /* setup pipes to children */
        if ((iev_ldpe = calloc(1, sizeof(struct imsgev))) == NULL ||
            (iev_ldpe_sync = calloc(1, sizeof(struct imsgev))) == NULL ||
@@ -416,8 +400,7 @@ ldpd_shutdown(void)
 
        config_clear(ldpd_conf);
 
-       ldp_config_reset_main(vty_conf);
-       ldp_config_reset_l2vpns(vty_conf);
+       ldp_config_reset(vty_conf);
        QOBJ_UNREG(vty_conf);
        free(vty_conf);
 
@@ -595,21 +578,36 @@ main_dispatch_lde(struct thread *thread)
                        if (kr_delete(imsg.data))
                                log_warnx("%s: error deleting route", __func__);
                        break;
-               case IMSG_KPWLABEL_CHANGE:
+               case IMSG_KPW_ADD:
+               case IMSG_KPW_DELETE:
+               case IMSG_KPW_SET:
+               case IMSG_KPW_UNSET:
                        if (imsg.hdr.len - IMSG_HEADER_SIZE !=
-                           sizeof(struct kpw))
+                           sizeof(struct zapi_pw))
                                fatalx("invalid size of IMSG_KPWLABEL_CHANGE");
-                       if (kmpw_set(imsg.data))
-                               log_warnx("%s: error changing pseudowire",
-                                   __func__);
-                       break;
-               case IMSG_KPWLABEL_DELETE:
-                       if (imsg.hdr.len - IMSG_HEADER_SIZE !=
-                           sizeof(struct kpw))
-                               fatalx("invalid size of IMSG_KPWLABEL_DELETE");
-                       if (kmpw_unset(imsg.data))
-                               log_warnx("%s: error unsetting pseudowire",
-                                   __func__);
+
+                       switch (imsg.hdr.type) {
+                       case IMSG_KPW_ADD:
+                               if (kmpw_add(imsg.data))
+                                       log_warnx("%s: error adding "
+                                           "pseudowire", __func__);
+                               break;
+                       case IMSG_KPW_DELETE:
+                               if (kmpw_del(imsg.data))
+                                       log_warnx("%s: error deleting "
+                                           "pseudowire", __func__);
+                               break;
+                       case IMSG_KPW_SET:
+                               if (kmpw_set(imsg.data))
+                                       log_warnx("%s: error setting "
+                                           "pseudowire", __func__);
+                               break;
+                       case IMSG_KPW_UNSET:
+                               if (kmpw_unset(imsg.data))
+                                       log_warnx("%s: error unsetting "
+                                           "pseudowire", __func__);
+                               break;
+                       }
                        break;
                case IMSG_ACL_CHECK:
                        if (imsg.hdr.len != IMSG_HEADER_SIZE +
@@ -962,9 +960,15 @@ main_imsg_send_config(struct ldpd_conf *xconf)
 }
 
 int
-ldp_reload(struct ldpd_conf *xconf)
+ldp_config_apply(struct vty *vty, struct ldpd_conf *xconf)
 {
-       if (global.sighup)
+       /*
+        * When reading from a configuration file (startup and sighup), we
+        * call merge_config() only once after the whole config has been read.
+        * This is the optimal and least disruptive way to update the running
+        * configuration.
+        */
+       if (vty && vty->type == VTY_FILE)
                return (0);
 
        ldp_config_normalize(xconf);
@@ -1041,19 +1045,26 @@ ldp_config_normalize(struct ldpd_conf *xconf)
        }
 }
 
+static void
+ldp_config_reset(struct ldpd_conf *conf)
+{
+       ldp_config_reset_main(conf);
+       ldp_config_reset_l2vpns(conf);
+}
+
 static void
 ldp_config_reset_main(struct ldpd_conf *conf)
 {
        struct iface            *iface;
        struct nbr_params       *nbrp;
 
-       while ((iface = RB_ROOT(&conf->iface_tree)) != NULL) {
+       while ((iface = RB_ROOT(iface_head, &conf->iface_tree)) != NULL) {
                QOBJ_UNREG(iface);
                RB_REMOVE(iface_head, &conf->iface_tree, iface);
                free(iface);
        }
 
-       while ((nbrp = RB_ROOT(&conf->nbrp_tree)) != NULL) {
+       while ((nbrp = RB_ROOT(nbrp_head, &conf->nbrp_tree)) != NULL) {
                QOBJ_UNREG(nbrp);
                RB_REMOVE(nbrp_head, &conf->nbrp_tree, nbrp);
                free(nbrp);
@@ -1109,18 +1120,20 @@ ldp_config_reset_l2vpns(struct ldpd_conf *conf)
        struct l2vpn_if         *lif;
        struct l2vpn_pw         *pw;
 
-       while ((l2vpn = RB_ROOT(&conf->l2vpn_tree)) != NULL) {
-               while ((lif = RB_ROOT(&l2vpn->if_tree)) != NULL) {
+       while ((l2vpn = RB_ROOT(l2vpn_head, &conf->l2vpn_tree)) != NULL) {
+               while ((lif = RB_ROOT(l2vpn_if_head,
+                   &l2vpn->if_tree)) != NULL) {
                        QOBJ_UNREG(lif);
                        RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif);
                        free(lif);
                }
-               while ((pw = RB_ROOT(&l2vpn->pw_tree)) != NULL) {
+               while ((pw = RB_ROOT(l2vpn_pw_head, &l2vpn->pw_tree)) != NULL) {
                        QOBJ_UNREG(pw);
                        RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_tree, pw);
                        free(pw);
                }
-               while ((pw = RB_ROOT(&l2vpn->pw_inactive_tree)) != NULL) {
+               while ((pw = RB_ROOT(l2vpn_pw_head,
+                   &l2vpn->pw_inactive_tree)) != NULL) {
                        QOBJ_UNREG(pw);
                        RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
                        free(pw);
@@ -1139,19 +1152,19 @@ ldp_clear_config(struct ldpd_conf *xconf)
        struct nbr_params       *nbrp;
        struct l2vpn            *l2vpn;
 
-       while ((iface = RB_ROOT(&xconf->iface_tree)) != NULL) {
+       while ((iface = RB_ROOT(iface_head, &xconf->iface_tree)) != NULL) {
                RB_REMOVE(iface_head, &xconf->iface_tree, iface);
                free(iface);
        }
-       while ((tnbr = RB_ROOT(&xconf->tnbr_tree)) != NULL) {
+       while ((tnbr = RB_ROOT(tnbr_head, &xconf->tnbr_tree)) != NULL) {
                RB_REMOVE(tnbr_head, &xconf->tnbr_tree, tnbr);
                free(tnbr);
        }
-       while ((nbrp = RB_ROOT(&xconf->nbrp_tree)) != NULL) {
+       while ((nbrp = RB_ROOT(nbrp_head, &xconf->nbrp_tree)) != NULL) {
                RB_REMOVE(nbrp_head, &xconf->nbrp_tree, nbrp);
                free(nbrp);
        }
-       while ((l2vpn = RB_ROOT(&xconf->l2vpn_tree)) != NULL) {
+       while ((l2vpn = RB_ROOT(l2vpn_head, &xconf->l2vpn_tree)) != NULL) {
                RB_REMOVE(l2vpn_head, &xconf->l2vpn_tree, l2vpn);
                l2vpn_del(l2vpn);
        }
@@ -1554,9 +1567,9 @@ merge_l2vpns(struct ldpd_conf *conf, struct ldpd_conf *xconf)
                if ((l2vpn = l2vpn_find(conf, xl->name)) == NULL) {
                        COPY(l2vpn, xl);
                        RB_INSERT(l2vpn_head, &conf->l2vpn_tree, l2vpn);
-                       RB_INIT(&l2vpn->if_tree);
-                       RB_INIT(&l2vpn->pw_tree);
-                       RB_INIT(&l2vpn->pw_inactive_tree);
+                       RB_INIT(l2vpn_if_head, &l2vpn->if_tree);
+                       RB_INIT(l2vpn_pw_head, &l2vpn->pw_tree);
+                       RB_INIT(l2vpn_pw_head, &l2vpn->pw_inactive_tree);
 
                        switch (ldpd_process) {
                        case PROC_LDE_ENGINE:
@@ -1683,8 +1696,7 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl)
                                        session_shutdown(nbr, S_SHUTDOWN, 0, 0);
                        }
                }
-               if (ldpd_process == PROC_LDE_ENGINE &&
-                   !reset_nbr && reinstall_pwfec)
+               if (ldpd_process == PROC_LDE_ENGINE && reinstall_pwfec)
                        l2vpn_pw_exit(pw);
                pw->lsr_id = xp->lsr_id;
                pw->af = xp->af;
@@ -1706,8 +1718,7 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl)
                        pw->flags &= ~F_PW_STATIC_NBR_ADDR;
                if (ldpd_process == PROC_LDP_ENGINE && reinstall_tnbr)
                        ldpe_l2vpn_pw_init(pw);
-               if (ldpd_process == PROC_LDE_ENGINE &&
-                   !reset_nbr && reinstall_pwfec) {
+               if (ldpd_process == PROC_LDE_ENGINE && reinstall_pwfec) {
                        l2vpn->pw_type = xl->pw_type;
                        l2vpn->mtu = xl->mtu;
                        l2vpn_pw_init(pw);
@@ -1767,10 +1778,13 @@ config_new_empty(void)
        if (xconf == NULL)
                fatal(NULL);
 
-       RB_INIT(&xconf->iface_tree);
-       RB_INIT(&xconf->tnbr_tree);
-       RB_INIT(&xconf->nbrp_tree);
-       RB_INIT(&xconf->l2vpn_tree);
+       RB_INIT(iface_head, &xconf->iface_tree);
+       RB_INIT(tnbr_head, &xconf->tnbr_tree);
+       RB_INIT(nbrp_head, &xconf->nbrp_tree);
+       RB_INIT(l2vpn_head, &xconf->l2vpn_tree);
+
+       /* set default values */
+       ldp_config_reset(xconf);
 
        return (xconf);
 }