]> git.puffer.fish Git - matthieu/frr.git/commitdiff
ldpd: do not consume vty_conf when updating the configuration
authorRenato Westphal <renato@opensourcerouting.org>
Thu, 30 Mar 2017 14:33:08 +0000 (11:33 -0300)
committerRenato Westphal <renato@opensourcerouting.org>
Fri, 31 Mar 2017 16:51:53 +0000 (13:51 -0300)
David Lamparter gave the idea of keeping vty_conf as a permanent copy of
ldpd_conf in order to simplify the CLI code and facilitate the integration
with his cap'n proto framework in the future. Doing this demanded quite
some effort but it was worth it as the code looks much better now.

Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
ldpd/interface.c
ldpd/lde.c
ldpd/ldp_vty_conf.c
ldpd/ldpd.c
ldpd/ldpd.h
ldpd/ldpe.c
ldpd/ldpe.h

index 11bce12b09636c8f0004d5875a48d5c694b3d761..b7f473d3960762d05632e66b9cb08a01dfb94f91 100644 (file)
@@ -62,21 +62,35 @@ if_new(const char *name)
        iface->ipv4.af = AF_INET;
        iface->ipv4.iface = iface;
        iface->ipv4.enabled = 0;
-       iface->ipv4.state = IF_STA_DOWN;
-       RB_INIT(&iface->ipv4.adj_tree);
 
        /* ipv6 */
        iface->ipv6.af = AF_INET6;
        iface->ipv6.iface = iface;
        iface->ipv6.enabled = 0;
-       iface->ipv6.state = IF_STA_DOWN;
-       RB_INIT(&iface->ipv6.adj_tree);
 
        return (iface);
 }
 
 void
-if_exit(struct iface *iface)
+ldpe_if_init(struct iface *iface)
+{
+       log_debug("%s: interface %s", __func__, iface->name);
+
+       LIST_INIT(&iface->addr_list);
+
+       /* ipv4 */
+       iface->ipv4.iface = iface;
+       iface->ipv4.state = IF_STA_DOWN;
+       RB_INIT(&iface->ipv4.adj_tree);
+
+       /* ipv6 */
+       iface->ipv6.iface = iface;
+       iface->ipv6.state = IF_STA_DOWN;
+       RB_INIT(&iface->ipv6.adj_tree);
+}
+
+void
+ldpe_if_exit(struct iface *iface)
 {
        struct if_addr          *if_addr;
 
index 607a9f7b149ab33309acfa54193a0a31c6e59e4b..d8a2924b31c9fdd4ee60c6628b01182ac59df5c1 100644 (file)
@@ -566,12 +566,6 @@ lde_dispatch_parent(struct thread *thread)
                                fatal(NULL);
                        memcpy(niface, imsg.data, sizeof(struct iface));
 
-                       LIST_INIT(&niface->addr_list);
-                       RB_INIT(&niface->ipv4.adj_tree);
-                       RB_INIT(&niface->ipv6.adj_tree);
-                       niface->ipv4.iface = niface;
-                       niface->ipv6.iface = niface;
-
                        RB_INSERT(iface_head, &nconf->iface_tree, niface);
                        break;
                case IMSG_RECONF_TNBR:
@@ -604,7 +598,6 @@ lde_dispatch_parent(struct thread *thread)
                                fatal(NULL);
                        memcpy(nlif, imsg.data, sizeof(struct l2vpn_if));
 
-                       nlif->l2vpn = nl2vpn;
                        RB_INSERT(l2vpn_if_head, &nl2vpn->if_tree, nlif);
                        break;
                case IMSG_RECONF_L2VPN_PW:
@@ -612,7 +605,6 @@ lde_dispatch_parent(struct thread *thread)
                                fatal(NULL);
                        memcpy(npw, imsg.data, sizeof(struct l2vpn_pw));
 
-                       npw->l2vpn = nl2vpn;
                        RB_INSERT(l2vpn_pw_head, &nl2vpn->pw_tree, npw);
                        break;
                case IMSG_RECONF_L2VPN_IPW:
@@ -620,11 +612,11 @@ lde_dispatch_parent(struct thread *thread)
                                fatal(NULL);
                        memcpy(npw, imsg.data, sizeof(struct l2vpn_pw));
 
-                       npw->l2vpn = nl2vpn;
                        RB_INSERT(l2vpn_pw_head, &nl2vpn->pw_inactive_tree, npw);
                        break;
                case IMSG_RECONF_END:
                        merge_config(ldeconf, nconf);
+                       ldp_clear_config(nconf);
                        nconf = NULL;
                        break;
                case IMSG_DEBUG_UPDATE:
index 4c6cfcd4a366234ddeaaf9fae4be34478f96851d..e4fc7b00545fc281f34edc8651bc9bf2bcc655f2 100644 (file)
@@ -36,17 +36,11 @@ static void  ldp_af_iface_config_write(struct vty *, int);
 static void     ldp_af_config_write(struct vty *, int, struct ldpd_conf *,
                    struct ldpd_af_conf *);
 static void     ldp_l2vpn_pw_config_write(struct vty *, struct l2vpn_pw *);
-static void     ldp_vty_push_node(struct vty *, int, void *);
-static void    *ldp_vty_get_node(struct vty *, void *, int);
 static int      ldp_vty_get_af(struct vty *);
 static int      ldp_iface_is_configured(struct ldpd_conf *, const char *);
 static int      ldp_vty_nbr_session_holdtime(struct vty *, struct vty_arg *[]);
 static int      ldp_vty_af_session_holdtime(struct vty *, struct vty_arg *[]);
 
-static struct iface    *vty_iface;
-static struct l2vpn    *vty_l2vpn;
-static struct l2vpn_pw *vty_pw;
-
 struct cmd_node ldp_node =
 {
        LDP_NODE,
@@ -391,94 +385,6 @@ ldp_l2vpn_config_write(struct vty *vty)
        return (0);
 }
 
-void
-ldp_vty_push_node(struct vty *vty, int node, void *ptr)
-{
-       if (global.sighup) {
-               switch (node) {
-               case LDP_IPV4_IFACE_NODE:
-               case LDP_IPV6_IFACE_NODE:
-                       vty_iface = ptr;
-                       break;
-               case LDP_L2VPN_NODE:
-                       vty_l2vpn = ptr;
-                       break;
-               case LDP_PSEUDOWIRE_NODE:
-                       vty_pw = ptr;
-                       break;
-               default:
-                       fatalx("ldp_vty_push_node: unexpected node");
-               }
-               vty->node = node;
-               return;
-       }
-
-       switch (node) {
-       case LDP_IPV4_IFACE_NODE:
-       case LDP_IPV6_IFACE_NODE:
-               VTY_PUSH_CONTEXT(node, (struct iface *)ptr);
-               break;
-       case LDP_L2VPN_NODE:
-               VTY_PUSH_CONTEXT(node, (struct l2vpn *)ptr);
-               break;
-       case LDP_PSEUDOWIRE_NODE:
-               VTY_PUSH_CONTEXT_SUB(node, (struct l2vpn_pw *)ptr);
-               break;
-       default:
-               fatalx("ldp_vty_push_node: unexpected node");
-       }
-}
-
-void *
-ldp_vty_get_node(struct vty *vty, void *parent, int node)
-{
-       struct iface            *iface;
-       struct l2vpn            *l2vpn;
-       struct l2vpn_pw         *pw;
-
-       if (global.sighup) {
-               switch (node) {
-               case LDP_IPV4_IFACE_NODE:
-               case LDP_IPV6_IFACE_NODE:
-                       return (vty_iface);
-               case LDP_L2VPN_NODE:
-                       return (vty_l2vpn);
-               case LDP_PSEUDOWIRE_NODE:
-                       return (vty_pw);
-               default:
-                       fatalx("ldp_vty_get_node: unexpected node");
-               }
-       }
-
-       /*
-        * Since VTY_GET_CONTEXT() returns a pointer to an element of ldpd_conf,
-        * we have to find the equivalent element inside vty_conf (which should
-        * always exist as vty_conf is a duplicate of ldpd_conf).
-        */
-       switch (node) {
-       case LDP_IPV4_IFACE_NODE:
-       case LDP_IPV6_IFACE_NODE:
-               iface = VTY_GET_CONTEXT(iface);
-               if (iface)
-                       return (if_lookup_name(vty_conf, iface->name));
-               break;
-       case LDP_L2VPN_NODE:
-               l2vpn = VTY_GET_CONTEXT(l2vpn);
-               if (l2vpn)
-                       return (l2vpn_find(vty_conf, l2vpn->name));
-               break;
-       case LDP_PSEUDOWIRE_NODE:
-               pw = VTY_GET_CONTEXT_SUB(l2vpn_pw);
-               if (pw)
-                       return (l2vpn_pw_find(parent, pw->ifname));
-               break;
-       default:
-               fatalx("ldp_vty_get_node: unexpected node");
-       }
-
-       return (NULL);
-}
-
 static int
 ldp_vty_get_af(struct vty *vty)
 {
@@ -656,7 +562,7 @@ ldp_vty_disc_holdtime(struct vty *vty, struct vty_arg *args[])
        case LDP_IPV4_IFACE_NODE:
        case LDP_IPV6_IFACE_NODE:
                af = ldp_vty_get_af(vty);
-               iface = ldp_vty_get_node(vty, NULL, vty->node);
+               iface = VTY_GET_CONTEXT(iface);
                VTY_CHECK_CONTEXT(iface);
 
                ia = iface_af_get(iface, af);
@@ -664,6 +570,7 @@ ldp_vty_disc_holdtime(struct vty *vty, struct vty_arg *args[])
                        ia->hello_holdtime = 0;
                else
                        ia->hello_holdtime = secs;
+
                ldp_reload(vty_conf);
                break;
        default:
@@ -756,7 +663,7 @@ ldp_vty_disc_interval(struct vty *vty, struct vty_arg *args[])
        case LDP_IPV4_IFACE_NODE:
        case LDP_IPV6_IFACE_NODE:
                af = ldp_vty_get_af(vty);
-               iface = ldp_vty_get_node(vty, NULL, vty->node);
+               iface = VTY_GET_CONTEXT(iface);
                VTY_CHECK_CONTEXT(iface);
 
                ia = iface_af_get(iface, af);
@@ -764,6 +671,7 @@ ldp_vty_disc_interval(struct vty *vty, struct vty_arg *args[])
                        ia->hello_interval = 0;
                else
                        ia->hello_interval = secs;
+
                ldp_reload(vty_conf);
                break;
        default:
@@ -825,14 +733,14 @@ ldp_vty_nbr_session_holdtime(struct vty *vty, struct vty_arg *args[])
                return (CMD_WARNING);
        }
 
-       nbrp = nbr_params_find(vty_conf, lsr_id);
-
        secs = strtol(seconds_str, &ep, 10);
        if (*ep != '\0' || secs < MIN_KEEPALIVE || secs > MAX_KEEPALIVE) {
                vty_out(vty, "%% Invalid holdtime%s", VTY_NEWLINE);
                return (CMD_SUCCESS);
        }
 
+       nbrp = nbr_params_find(vty_conf, lsr_id);
+
        if (disable) {
                if (nbrp == NULL)
                        return (CMD_SUCCESS);
@@ -843,6 +751,7 @@ ldp_vty_nbr_session_holdtime(struct vty *vty, struct vty_arg *args[])
                if (nbrp == NULL) {
                        nbrp = nbr_params_new(lsr_id);
                        RB_INSERT(nbrp_head, &vty_conf->nbrp_tree, nbrp);
+                       QOBJ_REG(nbrp, nbr_params);
                } else if (nbrp->keepalive == secs)
                        return (CMD_SUCCESS);
 
@@ -927,7 +836,9 @@ ldp_vty_interface(struct vty *vty, struct vty_arg *args[])
                ia->enabled = 0;
                ia->hello_holdtime = 0;
                ia->hello_interval = 0;
+
                ldp_reload(vty_conf);
+
                return (CMD_SUCCESS);
        }
 
@@ -942,6 +853,8 @@ ldp_vty_interface(struct vty *vty, struct vty_arg *args[])
                ia = iface_af_get(iface, af);
                ia->enabled = 1;
                RB_INSERT(iface_head, &vty_conf->iface_tree, iface);
+               QOBJ_REG(iface, iface);
+
                ldp_reload(vty_conf);
        } else {
                ia = iface_af_get(iface, af);
@@ -953,10 +866,10 @@ ldp_vty_interface(struct vty *vty, struct vty_arg *args[])
 
        switch (af) {
        case AF_INET:
-               ldp_vty_push_node(vty, LDP_IPV4_IFACE_NODE, iface);
+               VTY_PUSH_CONTEXT(LDP_IPV4_IFACE_NODE, iface);
                break;
        case AF_INET6:
-               ldp_vty_push_node(vty, LDP_IPV6_IFACE_NODE, iface);
+               VTY_PUSH_CONTEXT(LDP_IPV6_IFACE_NODE, iface);
                break;
        default:
                break;
@@ -1024,9 +937,12 @@ ldp_vty_neighbor_targeted(struct vty *vty, struct vty_arg *args[])
                if (tnbr == NULL)
                        return (CMD_SUCCESS);
 
+               QOBJ_UNREG(tnbr);
                RB_REMOVE(tnbr_head, &vty_conf->tnbr_tree, tnbr);
                free(tnbr);
+
                ldp_reload(vty_conf);
+
                return (CMD_SUCCESS);
        }
 
@@ -1036,6 +952,7 @@ ldp_vty_neighbor_targeted(struct vty *vty, struct vty_arg *args[])
        tnbr = tnbr_new(af, &addr);
        tnbr->flags |= F_TNBR_CONFIGURED;
        RB_INSERT(tnbr_head, &vty_conf->tnbr_tree, tnbr);
+       QOBJ_REG(tnbr, tnbr);
 
        ldp_reload(vty_conf);
 
@@ -1290,6 +1207,7 @@ ldp_vty_neighbor_password(struct vty *vty, struct vty_arg *args[])
                if (nbrp == NULL) {
                        nbrp = nbr_params_new(lsr_id);
                        RB_INSERT(nbrp_head, &vty_conf->nbrp_tree, nbrp);
+                       QOBJ_REG(nbrp, nbr_params);
                } else if (nbrp->auth.method == AUTH_MD5SIG &&
                    strcmp(nbrp->auth.md5key, password_str) == 0)
                        return (CMD_SUCCESS);
@@ -1350,6 +1268,7 @@ ldp_vty_neighbor_ttl_security(struct vty *vty, struct vty_arg *args[])
                if (nbrp == NULL) {
                        nbrp = nbr_params_new(lsr_id);
                        RB_INSERT(nbrp_head, &vty_conf->nbrp_tree, nbrp);
+                       QOBJ_REG(nbrp, nbr_params);
                }
 
                nbrp->flags |= F_NBRP_GTSM;
@@ -1371,6 +1290,8 @@ int
 ldp_vty_l2vpn(struct vty *vty, struct vty_arg *args[])
 {
        struct l2vpn            *l2vpn;
+       struct l2vpn_if         *lif;
+       struct l2vpn_pw         *pw;
        const char              *name_str;
        int                      disable;
 
@@ -1383,23 +1304,34 @@ ldp_vty_l2vpn(struct vty *vty, struct vty_arg *args[])
                if (l2vpn == NULL)
                        return (CMD_SUCCESS);
 
+               RB_FOREACH(lif, l2vpn_if_head, &l2vpn->if_tree)
+                       QOBJ_UNREG(lif);
+               RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree)
+                       QOBJ_UNREG(pw);
+               RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_inactive_tree)
+                       QOBJ_UNREG(pw);
+               QOBJ_UNREG(l2vpn);
                RB_REMOVE(l2vpn_head, &vty_conf->l2vpn_tree, l2vpn);
                l2vpn_del(l2vpn);
+
                ldp_reload(vty_conf);
+
                return (CMD_SUCCESS);
        }
 
        if (l2vpn) {
-               ldp_vty_push_node(vty, LDP_L2VPN_NODE, l2vpn);
+               VTY_PUSH_CONTEXT(LDP_L2VPN_NODE, l2vpn);
                return (CMD_SUCCESS);
        }
 
        l2vpn = l2vpn_new(name_str);
        l2vpn->type = L2VPN_TYPE_VPLS;
        RB_INSERT(l2vpn_head, &vty_conf->l2vpn_tree, l2vpn);
+       QOBJ_REG(l2vpn, l2vpn);
+
+       VTY_PUSH_CONTEXT(LDP_L2VPN_NODE, l2vpn);
 
        ldp_reload(vty_conf);
-       ldp_vty_push_node(vty, LDP_L2VPN_NODE, l2vpn);
 
        return (CMD_SUCCESS);
 }
@@ -1407,16 +1339,13 @@ ldp_vty_l2vpn(struct vty *vty, struct vty_arg *args[])
 int
 ldp_vty_l2vpn_bridge(struct vty *vty, struct vty_arg *args[])
 {
-       struct l2vpn            *l2vpn;
+       VTY_DECLVAR_CONTEXT(l2vpn, l2vpn);
        const char              *ifname;
        int                      disable;
 
        disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
        ifname = vty_get_arg_value(args, "ifname");
 
-       l2vpn = ldp_vty_get_node(vty, NULL, LDP_L2VPN_NODE);
-       VTY_CHECK_CONTEXT(l2vpn);
-
        if (disable)
                memset(l2vpn->br_ifname, 0, sizeof(l2vpn->br_ifname));
        else
@@ -1430,7 +1359,7 @@ ldp_vty_l2vpn_bridge(struct vty *vty, struct vty_arg *args[])
 int
 ldp_vty_l2vpn_mtu(struct vty *vty, struct vty_arg *args[])
 {
-       struct l2vpn            *l2vpn;
+       VTY_DECLVAR_CONTEXT(l2vpn, l2vpn);
        char                    *ep;
        int                      mtu;
        const char              *mtu_str;
@@ -1445,9 +1374,6 @@ ldp_vty_l2vpn_mtu(struct vty *vty, struct vty_arg *args[])
                return (CMD_WARNING);
        }
 
-       l2vpn = ldp_vty_get_node(vty, NULL, LDP_L2VPN_NODE);
-       VTY_CHECK_CONTEXT(l2vpn);
-
        if (disable)
                l2vpn->mtu = DEFAULT_L2VPN_MTU;
        else
@@ -1461,7 +1387,7 @@ ldp_vty_l2vpn_mtu(struct vty *vty, struct vty_arg *args[])
 int
 ldp_vty_l2vpn_pwtype(struct vty *vty, struct vty_arg *args[])
 {
-       struct l2vpn            *l2vpn;
+       VTY_DECLVAR_CONTEXT(l2vpn, l2vpn);
        int                      pw_type;
        const char              *type_str;
        int                      disable;
@@ -1474,9 +1400,6 @@ ldp_vty_l2vpn_pwtype(struct vty *vty, struct vty_arg *args[])
        else
                pw_type = PW_TYPE_ETHERNET_TAGGED;
 
-       l2vpn = ldp_vty_get_node(vty, NULL, LDP_L2VPN_NODE);
-       VTY_CHECK_CONTEXT(l2vpn);
-
        if (disable)
                l2vpn->pw_type = DEFAULT_PW_TYPE;
        else
@@ -1490,7 +1413,7 @@ ldp_vty_l2vpn_pwtype(struct vty *vty, struct vty_arg *args[])
 int
 ldp_vty_l2vpn_interface(struct vty *vty, struct vty_arg *args[])
 {
-       struct l2vpn            *l2vpn;
+       VTY_DECLVAR_CONTEXT(l2vpn, l2vpn);
        struct l2vpn_if         *lif;
        const char              *ifname;
        int                      disable;
@@ -1498,17 +1421,18 @@ ldp_vty_l2vpn_interface(struct vty *vty, struct vty_arg *args[])
        disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
        ifname = vty_get_arg_value(args, "ifname");
 
-       l2vpn = ldp_vty_get_node(vty, NULL, LDP_L2VPN_NODE);
-       VTY_CHECK_CONTEXT(l2vpn);
        lif = l2vpn_if_find(l2vpn, ifname);
 
        if (disable) {
                if (lif == NULL)
                        return (CMD_SUCCESS);
 
+               QOBJ_UNREG(lif);
                RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif);
                free(lif);
+
                ldp_reload(vty_conf);
+
                return (CMD_SUCCESS);
        }
 
@@ -1522,6 +1446,7 @@ ldp_vty_l2vpn_interface(struct vty *vty, struct vty_arg *args[])
 
        lif = l2vpn_if_new(l2vpn, ifname);
        RB_INSERT(l2vpn_if_head, &l2vpn->if_tree, lif);
+       QOBJ_REG(lif, l2vpn_if);
 
        ldp_reload(vty_conf);
 
@@ -1531,7 +1456,7 @@ ldp_vty_l2vpn_interface(struct vty *vty, struct vty_arg *args[])
 int
 ldp_vty_l2vpn_pseudowire(struct vty *vty, struct vty_arg *args[])
 {
-       struct l2vpn            *l2vpn;
+       VTY_DECLVAR_CONTEXT(l2vpn, l2vpn);
        struct l2vpn_pw         *pw;
        const char              *ifname;
        int                      disable;
@@ -1539,22 +1464,26 @@ ldp_vty_l2vpn_pseudowire(struct vty *vty, struct vty_arg *args[])
        disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
        ifname = vty_get_arg_value(args, "ifname");
 
-       l2vpn = ldp_vty_get_node(vty, NULL, LDP_L2VPN_NODE);
-       VTY_CHECK_CONTEXT(l2vpn);
        pw = l2vpn_pw_find(l2vpn, ifname);
 
        if (disable) {
                if (pw == NULL)
                        return (CMD_SUCCESS);
 
-               RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
+               QOBJ_UNREG(pw);
+               if (pw->lsr_id.s_addr == INADDR_ANY || pw->pwid == 0)
+                       RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
+               else
+                       RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_tree, pw);
                free(pw);
+
                ldp_reload(vty_conf);
+
                return (CMD_SUCCESS);
        }
 
        if (pw) {
-               ldp_vty_push_node(vty, LDP_PSEUDOWIRE_NODE, pw);
+               VTY_PUSH_CONTEXT_SUB(LDP_PSEUDOWIRE_NODE, pw);
                return (CMD_SUCCESS);
        }
 
@@ -1566,9 +1495,11 @@ ldp_vty_l2vpn_pseudowire(struct vty *vty, struct vty_arg *args[])
        pw = l2vpn_pw_new(l2vpn, ifname);
        pw->flags = F_PW_STATUSTLV_CONF|F_PW_CWORD_CONF;
        RB_INSERT(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
+       QOBJ_REG(pw, l2vpn_pw);
+
+       VTY_PUSH_CONTEXT_SUB(LDP_PSEUDOWIRE_NODE, pw);
 
        ldp_reload(vty_conf);
-       ldp_vty_push_node(vty, LDP_PSEUDOWIRE_NODE, pw);
 
        return (CMD_SUCCESS);
 }
@@ -1576,19 +1507,13 @@ ldp_vty_l2vpn_pseudowire(struct vty *vty, struct vty_arg *args[])
 int
 ldp_vty_l2vpn_pw_cword(struct vty *vty, struct vty_arg *args[])
 {
-       struct l2vpn            *l2vpn;
-       struct l2vpn_pw         *pw;
+       VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw);
        const char              *preference_str;
        int                      disable;
 
        disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
        preference_str = vty_get_arg_value(args, "preference");
 
-       l2vpn = ldp_vty_get_node(vty, NULL, LDP_L2VPN_NODE);
-       VTY_CHECK_CONTEXT(l2vpn);
-       pw = ldp_vty_get_node(vty, l2vpn, LDP_PSEUDOWIRE_NODE);
-       VTY_CHECK_CONTEXT(pw);
-
        if (disable)
                pw->flags |= F_PW_CWORD_CONF;
        else {
@@ -1606,8 +1531,7 @@ ldp_vty_l2vpn_pw_cword(struct vty *vty, struct vty_arg *args[])
 int
 ldp_vty_l2vpn_pw_nbr_addr(struct vty *vty, struct vty_arg *args[])
 {
-       struct l2vpn            *l2vpn;
-       struct l2vpn_pw         *pw;
+       VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw);
        int                      af;
        union ldpd_addr          addr;
        const char              *addr_str;
@@ -1622,11 +1546,6 @@ ldp_vty_l2vpn_pw_nbr_addr(struct vty *vty, struct vty_arg *args[])
                return (CMD_WARNING);
        }
 
-       l2vpn = ldp_vty_get_node(vty, NULL, LDP_L2VPN_NODE);
-       VTY_CHECK_CONTEXT(l2vpn);
-       pw = ldp_vty_get_node(vty, l2vpn, LDP_PSEUDOWIRE_NODE);
-       VTY_CHECK_CONTEXT(pw);
-
        if (disable) {
                pw->af = AF_UNSPEC;
                memset(&pw->addr, 0, sizeof(pw->addr));
@@ -1645,8 +1564,7 @@ ldp_vty_l2vpn_pw_nbr_addr(struct vty *vty, struct vty_arg *args[])
 int
 ldp_vty_l2vpn_pw_nbr_id(struct vty *vty, struct vty_arg *args[])
 {
-       struct l2vpn            *l2vpn;
-       struct l2vpn_pw         *pw;
+       VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw);
        struct in_addr           lsr_id;
        const char              *lsr_id_str;
        int                      disable;
@@ -1660,11 +1578,6 @@ ldp_vty_l2vpn_pw_nbr_id(struct vty *vty, struct vty_arg *args[])
                return (CMD_WARNING);
        }
 
-       l2vpn = ldp_vty_get_node(vty, NULL, LDP_L2VPN_NODE);
-       VTY_CHECK_CONTEXT(l2vpn);
-       pw = ldp_vty_get_node(vty, l2vpn, LDP_PSEUDOWIRE_NODE);
-       VTY_CHECK_CONTEXT(pw);
-
        if (disable)
                pw->lsr_id.s_addr = INADDR_ANY;
        else
@@ -1678,8 +1591,7 @@ ldp_vty_l2vpn_pw_nbr_id(struct vty *vty, struct vty_arg *args[])
 int
 ldp_vty_l2vpn_pw_pwid(struct vty *vty, struct vty_arg *args[])
 {
-       struct l2vpn            *l2vpn;
-       struct l2vpn_pw         *pw;
+       VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw);
        char                    *ep;
        uint32_t                 pwid;
        const char              *pwid_str;
@@ -1694,11 +1606,6 @@ ldp_vty_l2vpn_pw_pwid(struct vty *vty, struct vty_arg *args[])
                return (CMD_WARNING);
        }
 
-       l2vpn = ldp_vty_get_node(vty, NULL, LDP_L2VPN_NODE);
-       VTY_CHECK_CONTEXT(l2vpn);
-       pw = ldp_vty_get_node(vty, l2vpn, LDP_PSEUDOWIRE_NODE);
-       VTY_CHECK_CONTEXT(pw);
-
        if (disable)
                pw->pwid = 0;
        else
@@ -1712,17 +1619,11 @@ ldp_vty_l2vpn_pw_pwid(struct vty *vty, struct vty_arg *args[])
 int
 ldp_vty_l2vpn_pw_pwstatus(struct vty *vty, struct vty_arg *args[])
 {
-       struct l2vpn            *l2vpn;
-       struct l2vpn_pw         *pw;
+       VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw);
        int                      disable;
 
        disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
 
-       l2vpn = ldp_vty_get_node(vty, NULL, LDP_L2VPN_NODE);
-       VTY_CHECK_CONTEXT(l2vpn);
-       pw = ldp_vty_get_node(vty, l2vpn, LDP_PSEUDOWIRE_NODE);
-       VTY_CHECK_CONTEXT(pw);
-
        if (disable)
                pw->flags |= F_PW_STATUSTLV_CONF;
        else
@@ -1744,12 +1645,14 @@ iface_new_api(struct ldpd_conf *conf, const char *name)
 
        iface = if_new(name);
        RB_INSERT(iface_head, &conf->iface_tree, iface);
+       QOBJ_REG(iface, iface);
        return (iface);
 }
 
 void
 iface_del_api(struct ldpd_conf *conf, struct iface *iface)
 {
+       QOBJ_UNREG(iface);
        RB_REMOVE(iface_head, &conf->iface_tree, iface);
        free(iface);
 }
@@ -1768,12 +1671,14 @@ tnbr_new_api(struct ldpd_conf *conf, int af, union ldpd_addr *addr)
        tnbr = tnbr_new(af, addr);
        tnbr->flags |= F_TNBR_CONFIGURED;
        RB_INSERT(tnbr_head, &conf->tnbr_tree, tnbr);
+       QOBJ_REG(tnbr, tnbr);
        return (tnbr);
 }
 
 void
 tnbr_del_api(struct ldpd_conf *conf, struct tnbr *tnbr)
 {
+       QOBJ_UNREG(tnbr);
        RB_REMOVE(tnbr_head, &conf->tnbr_tree, tnbr);
        free(tnbr);
 }
@@ -1788,12 +1693,14 @@ nbrp_new_api(struct ldpd_conf *conf, struct in_addr lsr_id)
 
        nbrp = nbr_params_new(lsr_id);
        RB_INSERT(nbrp_head, &conf->nbrp_tree, nbrp);
+       QOBJ_REG(nbrp, nbr_params);
        return (nbrp);
 }
 
 void
 nbrp_del_api(struct ldpd_conf *conf, struct nbr_params *nbrp)
 {
+       QOBJ_UNREG(nbrp);
        RB_REMOVE(nbrp_head, &conf->nbrp_tree, nbrp);
        free(nbrp);
 }
@@ -1809,6 +1716,7 @@ l2vpn_new_api(struct ldpd_conf *conf, const char *name)
        l2vpn = l2vpn_new(name);
        l2vpn->type = L2VPN_TYPE_VPLS;
        RB_INSERT(l2vpn_head, &conf->l2vpn_tree, l2vpn);
+       QOBJ_REG(l2vpn, l2vpn);
        return (l2vpn);
 }
 
@@ -1819,17 +1727,21 @@ l2vpn_del_api(struct ldpd_conf *conf, struct l2vpn *l2vpn)
        struct l2vpn_pw         *pw;
 
        while ((lif = RB_ROOT(&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) {
+               QOBJ_UNREG(pw);
                RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_tree, pw);
                free(pw);
        }
        while ((pw = RB_ROOT(&l2vpn->pw_inactive_tree)) != NULL) {
+               QOBJ_UNREG(pw);
                RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
                free(pw);
        }
+       QOBJ_UNREG(l2vpn);
        RB_REMOVE(l2vpn_head, &conf->l2vpn_tree, l2vpn);
        free(l2vpn);
 }
@@ -1845,12 +1757,14 @@ l2vpn_if_new_api(struct ldpd_conf *conf, struct l2vpn *l2vpn,
 
        lif = l2vpn_if_new(l2vpn, ifname);
        RB_INSERT(l2vpn_if_head, &l2vpn->if_tree, lif);
+       QOBJ_REG(lif, l2vpn_if);
        return (lif);
 }
 
 void
 l2vpn_if_del_api(struct l2vpn *l2vpn, struct l2vpn_if *lif)
 {
+       QOBJ_UNREG(lif);
        RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif);
        free(lif);
 }
@@ -1867,12 +1781,14 @@ l2vpn_pw_new_api(struct ldpd_conf *conf, struct l2vpn *l2vpn,
        pw = l2vpn_pw_new(l2vpn, ifname);
        pw->flags = F_PW_STATUSTLV_CONF|F_PW_CWORD_CONF;
        RB_INSERT(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
+       QOBJ_REG(pw, l2vpn_pw);
        return (pw);
 }
 
 void
 l2vpn_pw_del_api(struct l2vpn *l2vpn, struct l2vpn_pw *pw)
 {
+       QOBJ_UNREG(pw);
        RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
        free(pw);
 }
index ea9317c41da151400911d51595694ec71fa024ad..9729499e284cc5f89054a76ee4445aa573840f17 100644 (file)
@@ -56,6 +56,7 @@ static int             main_imsg_send_config(struct ldpd_conf *);
 static void             ldp_config_normalize(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 *);
 static void             merge_global(struct ldpd_conf *, struct ldpd_conf *);
 static void             merge_af(int, struct ldpd_af_conf *,
                            struct ldpd_af_conf *);
@@ -131,9 +132,8 @@ sighup(void)
        log_info("SIGHUP received");
 
        /* reset vty_conf */
-       ldp_clear_config(vty_conf);
-       vty_conf = config_new_empty();
        ldp_config_reset_main(vty_conf);
+       ldp_config_reset_l2vpns(vty_conf);
 
        /* read configuration file without applying any changes */
        global.sighup = 1;
@@ -343,14 +343,15 @@ main(int argc, char *argv[])
        /* create base configuration with sane defaults */
        ldpd_conf = config_new_empty();
        ldp_config_reset_main(ldpd_conf);
-       QOBJ_REG(ldpd_conf, 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.
         */
-       vty_conf = ldp_dup_config(ldpd_conf);
+       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();
@@ -415,7 +416,11 @@ ldpd_shutdown(void)
        close(iev_lde->ibuf.fd);
 
        config_clear(ldpd_conf);
-       QOBJ_UNREG(ldpd_conf);
+
+       ldp_config_reset_main(vty_conf);
+       ldp_config_reset_l2vpns(vty_conf);
+       QOBJ_UNREG(vty_conf);
+       free(vty_conf);
 
        log_debug("waiting for children to terminate");
        do {
@@ -992,8 +997,6 @@ ldp_reload(struct ldpd_conf *xconf)
 
        merge_config(ldpd_conf, xconf);
 
-       vty_conf = ldp_dup_config(ldpd_conf);
-
        return (0);
 }
 
@@ -1017,6 +1020,7 @@ ldp_config_normalize(struct ldpd_conf *xconf)
                        if (iface->ipv4.enabled || iface->ipv6.enabled)
                                continue;
 
+                       QOBJ_UNREG(iface);
                        RB_REMOVE(iface_head, &vty_conf->iface_tree, iface);
                        free(iface);
                }
@@ -1027,6 +1031,7 @@ ldp_config_normalize(struct ldpd_conf *xconf)
                        if (nbrp->auth.method != AUTH_NONE)
                                continue;
 
+                       QOBJ_UNREG(nbrp);
                        RB_REMOVE(nbrp_head, &vty_conf->nbrp_tree, nbrp);
                        free(nbrp);
                }
@@ -1066,11 +1071,13 @@ ldp_config_reset_main(struct ldpd_conf *conf)
        struct nbr_params       *nbrp;
 
        while ((iface = RB_ROOT(&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) {
+               QOBJ_UNREG(nbrp);
                RB_REMOVE(nbrp_head, &conf->nbrp_tree, nbrp);
                free(nbrp);
        }
@@ -1103,6 +1110,7 @@ ldp_config_reset_af(struct ldpd_conf *conf, int af)
                if (tnbr->af != af)
                        continue;
 
+               QOBJ_UNREG(tnbr);
                RB_REMOVE(tnbr_head, &conf->tnbr_tree, tnbr);
                free(tnbr);
        }
@@ -1117,70 +1125,33 @@ ldp_config_reset_af(struct ldpd_conf *conf, int af)
        af_conf->flags = 0;
 }
 
-struct ldpd_conf *
-ldp_dup_config(struct ldpd_conf *conf)
+static void
+ldp_config_reset_l2vpns(struct ldpd_conf *conf)
 {
-       struct ldpd_conf        *xconf;
-       struct iface            *iface, *xi;
-       struct tnbr             *tnbr, *xt;
-       struct nbr_params       *nbrp, *xn;
-       struct l2vpn            *l2vpn, *xl;
-       struct l2vpn_if         *lif, *xf;
-       struct l2vpn_pw         *pw, *xp;
-
-#define COPY(a, b) do { \
-               a = calloc(1, sizeof(*a)); \
-               if (a == NULL) \
-                       fatal(__func__); \
-               *a = *b; \
-       } while (0)
-
-       COPY(xconf, conf);
-       RB_INIT(&xconf->iface_tree);
-       RB_INIT(&xconf->tnbr_tree);
-       RB_INIT(&xconf->nbrp_tree);
-       RB_INIT(&xconf->l2vpn_tree);
-
-       RB_FOREACH(iface, iface_head, &conf->iface_tree) {
-               COPY(xi, iface);
-               xi->ipv4.iface = xi;
-               xi->ipv6.iface = xi;
-               RB_INSERT(iface_head, &xconf->iface_tree, xi);
-       }
-       RB_FOREACH(tnbr, tnbr_head, &conf->tnbr_tree) {
-               COPY(xt, tnbr);
-               RB_INSERT(tnbr_head, &xconf->tnbr_tree, xt);
-       }
-       RB_FOREACH(nbrp, nbrp_head, &conf->nbrp_tree) {
-               COPY(xn, nbrp);
-               RB_INSERT(nbrp_head, &xconf->nbrp_tree, xn);
-       }
-       RB_FOREACH(l2vpn, l2vpn_head, &conf->l2vpn_tree) {
-               COPY(xl, l2vpn);
-               RB_INIT(&xl->if_tree);
-               RB_INIT(&xl->pw_tree);
-               RB_INIT(&xl->pw_inactive_tree);
-               RB_INSERT(l2vpn_head, &xconf->l2vpn_tree, xl);
+       struct l2vpn            *l2vpn;
+       struct l2vpn_if         *lif;
+       struct l2vpn_pw         *pw;
 
-               RB_FOREACH(lif, l2vpn_if_head, &l2vpn->if_tree) {
-                       COPY(xf, lif);
-                       xf->l2vpn = xl;
-                       RB_INSERT(l2vpn_if_head, &xl->if_tree, xf);
+       while ((l2vpn = RB_ROOT(&conf->l2vpn_tree)) != NULL) {
+               while ((lif = RB_ROOT(&l2vpn->if_tree)) != NULL) {
+                       QOBJ_UNREG(lif);
+                       RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif);
+                       free(lif);
                }
-               RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree) {
-                       COPY(xp, pw);
-                       xp->l2vpn = xl;
-                       RB_INSERT(l2vpn_pw_head, &xl->pw_tree, xp);
+               while ((pw = RB_ROOT(&l2vpn->pw_tree)) != NULL) {
+                       QOBJ_UNREG(pw);
+                       RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_tree, pw);
+                       free(pw);
                }
-               RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_inactive_tree) {
-                       COPY(xp, pw);
-                       xp->l2vpn = xl;
-                       RB_INSERT(l2vpn_pw_head, &xl->pw_inactive_tree, xp);
+               while ((pw = RB_ROOT(&l2vpn->pw_inactive_tree)) != NULL) {
+                       QOBJ_UNREG(pw);
+                       RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
+                       free(pw);
                }
+               QOBJ_UNREG(l2vpn);
+               RB_REMOVE(l2vpn_head, &conf->l2vpn_tree, l2vpn);
+               free(l2vpn);
        }
-#undef COPY
-
-       return (xconf);
 }
 
 void
@@ -1211,6 +1182,13 @@ ldp_clear_config(struct ldpd_conf *xconf)
        free(xconf);
 }
 
+#define COPY(a, b) do { \
+               a = malloc(sizeof(*a)); \
+               if (a == NULL) \
+                       fatal(__func__); \
+               *a = *b; \
+       } while (0)
+
 void
 merge_config(struct ldpd_conf *conf, struct ldpd_conf *xconf)
 {
@@ -1221,7 +1199,6 @@ merge_config(struct ldpd_conf *conf, struct ldpd_conf *xconf)
        merge_tnbrs(conf, xconf);
        merge_nbrps(conf, xconf);
        merge_l2vpns(conf, xconf);
-       free(xconf);
 }
 
 static void
@@ -1365,31 +1342,34 @@ merge_ifaces(struct ldpd_conf *conf, struct ldpd_conf *xconf)
        RB_FOREACH_SAFE(iface, iface_head, &conf->iface_tree, itmp) {
                /* find deleted interfaces */
                if ((xi = if_lookup_name(xconf, iface->name)) == NULL) {
-                       RB_REMOVE(iface_head, &conf->iface_tree, iface);
-
                        switch (ldpd_process) {
-                       case PROC_LDE_ENGINE:
-                               break;
                        case PROC_LDP_ENGINE:
-                               if_exit(iface);
+                               ldpe_if_exit(iface);
                                break;
+                       case PROC_LDE_ENGINE:
                        case PROC_MAIN:
-                               QOBJ_UNREG (iface);
                                break;
                        }
+                       RB_REMOVE(iface_head, &conf->iface_tree, iface);
                        free(iface);
                }
        }
        RB_FOREACH_SAFE(xi, iface_head, &xconf->iface_tree, itmp) {
                /* find new interfaces */
                if ((iface = if_lookup_name(conf, xi->name)) == NULL) {
-                       RB_REMOVE(iface_head, &xconf->iface_tree, xi);
-                       RB_INSERT(iface_head, &conf->iface_tree, xi);
+                       COPY(iface, xi);
+                       RB_INSERT(iface_head, &conf->iface_tree, iface);
 
-                       if (ldpd_process == PROC_MAIN) {
-                               QOBJ_REG (xi, iface);
+                       switch (ldpd_process) {
+                       case PROC_LDP_ENGINE:
+                               ldpe_if_init(iface);
+                               break;
+                       case PROC_LDE_ENGINE:
+                               break;
+                       case PROC_MAIN:
                                /* resend addresses to activate new interfaces */
-                               kif_redistribute(xi->name);
+                               kif_redistribute(iface->name);
+                               break;
                        }
                        continue;
                }
@@ -1397,8 +1377,6 @@ merge_ifaces(struct ldpd_conf *conf, struct ldpd_conf *xconf)
                /* update existing interfaces */
                merge_iface_af(&iface->ipv4, &xi->ipv4);
                merge_iface_af(&iface->ipv6, &xi->ipv6);
-               RB_REMOVE(iface_head, &xconf->iface_tree, xi);
-               free(xi);
        }
 }
 
@@ -1426,17 +1404,13 @@ merge_tnbrs(struct ldpd_conf *conf, struct ldpd_conf *xconf)
                /* find deleted tnbrs */
                if ((xt = tnbr_find(xconf, tnbr->af, &tnbr->addr)) == NULL) {
                        switch (ldpd_process) {
-                       case PROC_LDE_ENGINE:
-                               RB_REMOVE(tnbr_head, &conf->tnbr_tree, tnbr);
-                               free(tnbr);
-                               break;
                        case PROC_LDP_ENGINE:
                                tnbr->flags &= ~F_TNBR_CONFIGURED;
                                tnbr_check(conf, tnbr);
                                break;
+                       case PROC_LDE_ENGINE:
                        case PROC_MAIN:
                                RB_REMOVE(tnbr_head, &conf->tnbr_tree, tnbr);
-                               QOBJ_UNREG (tnbr);
                                free(tnbr);
                                break;
                        }
@@ -1445,17 +1419,15 @@ merge_tnbrs(struct ldpd_conf *conf, struct ldpd_conf *xconf)
        RB_FOREACH_SAFE(xt, tnbr_head, &xconf->tnbr_tree, ttmp) {
                /* find new tnbrs */
                if ((tnbr = tnbr_find(conf, xt->af, &xt->addr)) == NULL) {
-                       RB_REMOVE(tnbr_head, &xconf->tnbr_tree, xt);
-                       RB_INSERT(tnbr_head, &conf->tnbr_tree, xt);
+                       COPY(tnbr, xt);
+                       RB_INSERT(tnbr_head, &conf->tnbr_tree, tnbr);
 
                        switch (ldpd_process) {
-                       case PROC_LDE_ENGINE:
-                               break;
                        case PROC_LDP_ENGINE:
-                               tnbr_update(xt);
+                               tnbr_update(tnbr);
                                break;
+                       case PROC_LDE_ENGINE:
                        case PROC_MAIN:
-                               QOBJ_REG (xt, tnbr);
                                break;
                        }
                        continue;
@@ -1464,8 +1436,6 @@ merge_tnbrs(struct ldpd_conf *conf, struct ldpd_conf *xconf)
                /* update existing tnbrs */
                if (!(tnbr->flags & F_TNBR_CONFIGURED))
                        tnbr->flags |= F_TNBR_CONFIGURED;
-               RB_REMOVE(tnbr_head, &xconf->tnbr_tree, xt);
-               free(xt);
        }
 }
 
@@ -1480,8 +1450,6 @@ merge_nbrps(struct ldpd_conf *conf, struct ldpd_conf *xconf)
                /* find deleted nbrps */
                if ((xn = nbr_params_find(xconf, nbrp->lsr_id)) == NULL) {
                        switch (ldpd_process) {
-                       case PROC_LDE_ENGINE:
-                               break;
                        case PROC_LDP_ENGINE:
                                nbr = nbr_find_ldpid(nbrp->lsr_id.s_addr);
                                if (nbr) {
@@ -1499,8 +1467,8 @@ merge_nbrps(struct ldpd_conf *conf, struct ldpd_conf *xconf)
                                                nbr_establish_connection(nbr);
                                }
                                break;
+                       case PROC_LDE_ENGINE:
                        case PROC_MAIN:
-                               QOBJ_UNREG (nbrp);
                                break;
                        }
                        RB_REMOVE(nbrp_head, &conf->nbrp_tree, nbrp);
@@ -1510,33 +1478,31 @@ merge_nbrps(struct ldpd_conf *conf, struct ldpd_conf *xconf)
        RB_FOREACH_SAFE(xn, nbrp_head, &xconf->nbrp_tree, ntmp) {
                /* find new nbrps */
                if ((nbrp = nbr_params_find(conf, xn->lsr_id)) == NULL) {
-                       RB_REMOVE(nbrp_head, &xconf->nbrp_tree, xn);
-                       RB_INSERT(nbrp_head, &conf->nbrp_tree, xn);
+                       COPY(nbrp, xn);
+                       RB_INSERT(nbrp_head, &conf->nbrp_tree, nbrp);
 
                        switch (ldpd_process) {
-                       case PROC_LDE_ENGINE:
-                               break;
                        case PROC_LDP_ENGINE:
-                               nbr = nbr_find_ldpid(xn->lsr_id.s_addr);
+                               nbr = nbr_find_ldpid(nbrp->lsr_id.s_addr);
                                if (nbr) {
                                        session_shutdown(nbr, S_SHUTDOWN, 0, 0);
-                                       nbr->auth.method = xn->auth.method;
+                                       nbr->auth.method = nbrp->auth.method;
 #ifdef __OpenBSD__
-                                       if (pfkey_establish(nbr, xn) == -1)
+                                       if (pfkey_establish(nbr, nbrp) == -1)
                                                fatalx("pfkey setup failed");
 #else
                                        sock_set_md5sig(
                                            (ldp_af_global_get(&global,
                                            nbr->af))->ldp_session_socket,
                                            nbr->af, &nbr->raddr,
-                                           xn->auth.md5key);
+                                           nbrp->auth.md5key);
 #endif
                                        if (nbr_session_active_role(nbr))
                                                nbr_establish_connection(nbr);
                                }
                                break;
+                       case PROC_LDE_ENGINE:
                        case PROC_MAIN:
-                               QOBJ_REG (xn, nbr_params);
                                break;
                        }
                        continue;
@@ -1581,8 +1547,6 @@ merge_nbrps(struct ldpd_conf *conf, struct ldpd_conf *xconf)
                                        nbr_establish_connection(nbr);
                        }
                }
-               RB_REMOVE(nbrp_head, &xconf->nbrp_tree, xn);
-               free(xn);
        }
 }
 
@@ -1590,14 +1554,10 @@ static void
 merge_l2vpns(struct ldpd_conf *conf, struct ldpd_conf *xconf)
 {
        struct l2vpn            *l2vpn, *ltmp, *xl;
-       struct l2vpn_if         *lif;
-       struct l2vpn_pw         *pw;
 
        RB_FOREACH_SAFE(l2vpn, l2vpn_head, &conf->l2vpn_tree, ltmp) {
                /* find deleted l2vpns */
                if ((xl = l2vpn_find(xconf, l2vpn->name)) == NULL) {
-                       RB_REMOVE(l2vpn_head, &conf->l2vpn_tree, l2vpn);
-
                        switch (ldpd_process) {
                        case PROC_LDE_ENGINE:
                                l2vpn_exit(l2vpn);
@@ -1606,42 +1566,35 @@ merge_l2vpns(struct ldpd_conf *conf, struct ldpd_conf *xconf)
                                ldpe_l2vpn_exit(l2vpn);
                                break;
                        case PROC_MAIN:
-                               RB_FOREACH(lif, l2vpn_if_head, &l2vpn->if_tree)
-                                       QOBJ_UNREG (lif);
-                               RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree)
-                                       QOBJ_UNREG (pw);
-                               RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_inactive_tree)
-                                       QOBJ_UNREG (pw);
-                               QOBJ_UNREG (l2vpn);
                                break;
                        }
+                       RB_REMOVE(l2vpn_head, &conf->l2vpn_tree, l2vpn);
                        l2vpn_del(l2vpn);
                }
        }
        RB_FOREACH_SAFE(xl, l2vpn_head, &xconf->l2vpn_tree, ltmp) {
                /* find new l2vpns */
                if ((l2vpn = l2vpn_find(conf, xl->name)) == NULL) {
-                       RB_REMOVE(l2vpn_head, &xconf->l2vpn_tree, xl);
-                       RB_INSERT(l2vpn_head, &conf->l2vpn_tree, xl);
+                       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);
 
                        switch (ldpd_process) {
                        case PROC_LDE_ENGINE:
-                               l2vpn_init(xl);
+                               l2vpn_init(l2vpn);
                                break;
                        case PROC_LDP_ENGINE:
-                               ldpe_l2vpn_init(xl);
+                               ldpe_l2vpn_init(l2vpn);
                                break;
                        case PROC_MAIN:
-                               QOBJ_REG (xl, l2vpn);
                                break;
                        }
-                       continue;
                }
 
                /* update existing l2vpns */
                merge_l2vpn(conf, l2vpn, xl);
-               RB_REMOVE(l2vpn_head, &xconf->l2vpn_tree, xl);
-               free(xl);
        }
 }
 
@@ -1661,8 +1614,6 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl)
        RB_FOREACH_SAFE(lif, l2vpn_if_head, &l2vpn->if_tree, ftmp) {
                /* find deleted interfaces */
                if ((xf = l2vpn_if_find(xl, lif->ifname)) == NULL) {
-                       if (ldpd_process == PROC_MAIN)
-                               QOBJ_UNREG (lif);
                        RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif);
                        free(lif);
                }
@@ -1670,18 +1621,19 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl)
        RB_FOREACH_SAFE(xf, l2vpn_if_head, &xl->if_tree, ftmp) {
                /* find new interfaces */
                if ((lif = l2vpn_if_find(l2vpn, xf->ifname)) == NULL) {
-                       RB_REMOVE(l2vpn_if_head, &xl->if_tree, xf);
-                       RB_INSERT(l2vpn_if_head, &l2vpn->if_tree, xf);
-                       xf->l2vpn = l2vpn;
-                       if (ldpd_process == PROC_MAIN) {
-                               QOBJ_REG(xf, l2vpn_if);
-                               kif_redistribute(xf->ifname);
+                       COPY(lif, xf);
+                       RB_INSERT(l2vpn_if_head, &l2vpn->if_tree, lif);
+                       lif->l2vpn = l2vpn;
+
+                       switch (ldpd_process) {
+                       case PROC_LDP_ENGINE:
+                       case PROC_LDE_ENGINE:
+                               break;
+                       case PROC_MAIN:
+                               kif_redistribute(lif->ifname);
+                               break;
                        }
-                       continue;
                }
-
-               RB_REMOVE(l2vpn_if_head, &xl->if_tree, xf);
-               free(xf);
        }
 
        /* merge active pseudowires */
@@ -1696,7 +1648,6 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl)
                                ldpe_l2vpn_pw_exit(pw);
                                break;
                        case PROC_MAIN:
-                               QOBJ_UNREG (pw);
                                break;
                        }
 
@@ -1707,20 +1658,19 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl)
        RB_FOREACH_SAFE(xp, l2vpn_pw_head, &xl->pw_tree, ptmp) {
                /* find new active pseudowires */
                if ((pw = l2vpn_pw_find_active(l2vpn, xp->ifname)) == NULL) {
-                       RB_REMOVE(l2vpn_pw_head, &xl->pw_tree, xp);
-                       RB_INSERT(l2vpn_pw_head, &l2vpn->pw_tree, xp);
-                       xp->l2vpn = l2vpn;
+                       COPY(pw, xp);
+                       RB_INSERT(l2vpn_pw_head, &l2vpn->pw_tree, pw);
+                       pw->l2vpn = l2vpn;
 
                        switch (ldpd_process) {
                        case PROC_LDE_ENGINE:
-                               l2vpn_pw_init(xp);
+                               l2vpn_pw_init(pw);
                                break;
                        case PROC_LDP_ENGINE:
-                               ldpe_l2vpn_pw_init(xp);
+                               ldpe_l2vpn_pw_init(pw);
                                break;
                        case PROC_MAIN:
-                               QOBJ_REG (xp, l2vpn_pw);
-                               kif_redistribute(xp->ifname);
+                               kif_redistribute(pw->ifname);
                                break;
                        }
                        continue;
@@ -1787,9 +1737,6 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl)
                        l2vpn->pw_type = previous_pw_type;
                        l2vpn->mtu = previous_mtu;
                }
-
-               RB_REMOVE(l2vpn_pw_head, &xl->pw_tree, xp);
-               free(xp);
        }
 
        /* merge inactive pseudowires */
@@ -1797,20 +1744,23 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl)
                /* find deleted inactive pseudowires */
                if ((xp = l2vpn_pw_find_inactive(xl, pw->ifname)) == NULL) {
                        RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
-                       if (ldpd_process == PROC_MAIN)
-                               QOBJ_UNREG (pw);
                        free(pw);
                }
        }
        RB_FOREACH_SAFE(xp, l2vpn_pw_head, &xl->pw_inactive_tree, ptmp) {
                /* find new inactive pseudowires */
                if ((pw = l2vpn_pw_find_inactive(l2vpn, xp->ifname)) == NULL) {
-                       RB_REMOVE(l2vpn_pw_head, &xl->pw_inactive_tree, xp);
-                       RB_INSERT(l2vpn_pw_head, &l2vpn->pw_inactive_tree, xp);
-                       xp->l2vpn = l2vpn;
-                       if (ldpd_process == PROC_MAIN) {
-                               QOBJ_REG (xp, l2vpn_pw);
-                               kif_redistribute(xp->ifname);
+                       COPY(pw, xp);
+                       RB_INSERT(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
+                       pw->l2vpn = l2vpn;
+
+                       switch (ldpd_process) {
+                       case PROC_LDE_ENGINE:
+                       case PROC_LDP_ENGINE:
+                               break;
+                       case PROC_MAIN:
+                               kif_redistribute(pw->ifname);
+                               break;
                        }
                        continue;
                }
@@ -1823,9 +1773,6 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl)
                strlcpy(pw->ifname, xp->ifname, sizeof(pw->ifname));
                pw->ifindex = xp->ifindex;
                pw->flags = xp->flags;
-
-               RB_REMOVE(l2vpn_pw_head, &xl->pw_inactive_tree, xp);
-               free(xp);
        }
 
        l2vpn->pw_type = xl->pw_type;
@@ -1869,5 +1816,6 @@ config_clear(struct ldpd_conf *conf)
        xconf->trans_pref = conf->trans_pref;
        xconf->flags = conf->flags;
        merge_config(conf, xconf);
+       free(xconf);
        free(conf);
 }
index a0474a5a2dae862724f0b90b66983ea46bbcf3d0..d2fc5aa3afe8be4d12c0dfacfbd00ec843597e0a 100644 (file)
@@ -706,7 +706,6 @@ struct ldpd_af_global       *ldp_af_global_get(struct ldpd_global *, int);
 int                     ldp_is_dual_stack(struct ldpd_conf *);
 in_addr_t               ldp_rtr_id_get(struct ldpd_conf *);
 int                     ldp_reload(struct ldpd_conf *);
-struct ldpd_conf       *ldp_dup_config(struct ldpd_conf *);
 void                    ldp_clear_config(struct ldpd_conf *);
 void                    merge_config(struct ldpd_conf *, struct ldpd_conf *);
 struct ldpd_conf       *config_new_empty(void);
index f8e9abab02375486854bc670ea6bd77e207e1590..1bec3d2a958cd08532db799f5390d71f7263c626 100644 (file)
@@ -452,12 +452,6 @@ ldpe_dispatch_main(struct thread *thread)
                                fatal(NULL);
                        memcpy(niface, imsg.data, sizeof(struct iface));
 
-                       LIST_INIT(&niface->addr_list);
-                       RB_INIT(&niface->ipv4.adj_tree);
-                       RB_INIT(&niface->ipv6.adj_tree);
-                       niface->ipv4.iface = niface;
-                       niface->ipv6.iface = niface;
-
                        RB_INSERT(iface_head, &nconf->iface_tree, niface);
                        break;
                case IMSG_RECONF_TNBR:
@@ -490,7 +484,6 @@ ldpe_dispatch_main(struct thread *thread)
                                fatal(NULL);
                        memcpy(nlif, imsg.data, sizeof(struct l2vpn_if));
 
-                       nlif->l2vpn = nl2vpn;
                        RB_INSERT(l2vpn_if_head, &nl2vpn->if_tree, nlif);
                        break;
                case IMSG_RECONF_L2VPN_PW:
@@ -498,7 +491,6 @@ ldpe_dispatch_main(struct thread *thread)
                                fatal(NULL);
                        memcpy(npw, imsg.data, sizeof(struct l2vpn_pw));
 
-                       npw->l2vpn = nl2vpn;
                        RB_INSERT(l2vpn_pw_head, &nl2vpn->pw_tree, npw);
                        break;
                case IMSG_RECONF_L2VPN_IPW:
@@ -506,11 +498,11 @@ ldpe_dispatch_main(struct thread *thread)
                                fatal(NULL);
                        memcpy(npw, imsg.data, sizeof(struct l2vpn_pw));
 
-                       npw->l2vpn = nl2vpn;
                        RB_INSERT(l2vpn_pw_head, &nl2vpn->pw_inactive_tree, npw);
                        break;
                case IMSG_RECONF_END:
                        merge_config(leconf, nconf);
+                       ldp_clear_config(nconf);
                        nconf = NULL;
                        global.conf_seqnum++;
                        break;
index e4b8394aa0984ed3a72500956213428b50ed1a15..a3f41a8b9fa12f1914fb59e0d1eb1a8e2c10c97e 100644 (file)
@@ -215,7 +215,8 @@ void                 mapping_list_clr(struct mapping_head *);
 
 /* interface.c */
 struct iface   *if_new(const char *);
-void            if_exit(struct iface *);
+void            ldpe_if_init(struct iface *);
+void            ldpe_if_exit(struct iface *);
 struct iface   *if_lookup(struct ldpd_conf *, unsigned short);
 struct iface   *if_lookup_name(struct ldpd_conf *, const char *);
 void            if_update_info(struct iface *, struct kif *);