summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRenato Westphal <renato@opensourcerouting.org>2017-03-30 16:33:08 +0200
committerRenato Westphal <renato@opensourcerouting.org>2017-03-31 18:51:53 +0200
commit1d75a89d8553caab99e58668af30a9803d40d49b (patch)
treebdfdc77f6f84973d2fe3e27a1da6d0fa1b75a322
parentldpd: extend the ldp_config_normalize() function (diff)
downloadfrr-1d75a89d8553caab99e58668af30a9803d40d49b.tar.xz
frr-1d75a89d8553caab99e58668af30a9803d40d49b.zip
ldpd: do not consume vty_conf when updating the configuration
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>
-rw-r--r--ldpd/interface.c24
-rw-r--r--ldpd/lde.c10
-rw-r--r--ldpd/ldp_vty_conf.c232
-rw-r--r--ldpd/ldpd.c266
-rw-r--r--ldpd/ldpd.h1
-rw-r--r--ldpd/ldpe.c10
-rw-r--r--ldpd/ldpe.h3
7 files changed, 204 insertions, 342 deletions
diff --git a/ldpd/interface.c b/ldpd/interface.c
index 11bce12b0..b7f473d39 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 607a9f7b1..d8a2924b3 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 4c6cfcd4a..e4fc7b005 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 ea9317c41..9729499e2 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;
-
-#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);
}
diff --git a/ldpd/ldpd.h b/ldpd/ldpd.h
index a0474a5a2..d2fc5aa3a 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 f8e9abab0..1bec3d2a9 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 e4b8394aa..a3f41a8b9 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 *);