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>
This commit is contained in:
Renato Westphal 2017-03-30 11:33:08 -03:00
parent 7d0eeac1a1
commit 1d75a89d85
7 changed files with 205 additions and 343 deletions

View 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;

View 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:

View 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);
}

View 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;
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);
}

View 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);

View 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;

View 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 *);