diff --git a/ldpd/interface.c b/ldpd/interface.c index 11bce12b09..b7f473d396 100644 --- a/ldpd/interface.c +++ b/ldpd/interface.c @@ -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; diff --git a/ldpd/lde.c b/ldpd/lde.c index 607a9f7b14..d8a2924b31 100644 --- a/ldpd/lde.c +++ b/ldpd/lde.c @@ -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: diff --git a/ldpd/ldp_vty_conf.c b/ldpd/ldp_vty_conf.c index 4c6cfcd4a3..e4fc7b0054 100644 --- a/ldpd/ldp_vty_conf.c +++ b/ldpd/ldp_vty_conf.c @@ -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); } diff --git a/ldpd/ldpd.c b/ldpd/ldpd.c index ea9317c41d..9729499e28 100644 --- a/ldpd/ldpd.c +++ b/ldpd/ldpd.c @@ -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; + struct l2vpn *l2vpn; + struct l2vpn_if *lif; + struct l2vpn_pw *pw; -#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); - - 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); - } - continue; - } + COPY(lif, xf); + RB_INSERT(l2vpn_if_head, &l2vpn->if_tree, lif); + lif->l2vpn = l2vpn; - RB_REMOVE(l2vpn_if_head, &xl->if_tree, xf); - free(xf); + switch (ldpd_process) { + case PROC_LDP_ENGINE: + case PROC_LDE_ENGINE: + break; + case PROC_MAIN: + kif_redistribute(lif->ifname); + break; + } + } } /* 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); } diff --git a/ldpd/ldpd.h b/ldpd/ldpd.h index a0474a5a2d..d2fc5aa3af 100644 --- a/ldpd/ldpd.h +++ b/ldpd/ldpd.h @@ -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); diff --git a/ldpd/ldpe.c b/ldpd/ldpe.c index f8e9abab02..1bec3d2a95 100644 --- a/ldpd/ldpe.c +++ b/ldpd/ldpe.c @@ -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; diff --git a/ldpd/ldpe.h b/ldpd/ldpe.h index e4b8394aa0..a3f41a8b9f 100644 --- a/ldpd/ldpe.h +++ b/ldpd/ldpe.h @@ -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 *);