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;
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:
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:
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:
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:
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,
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)
{
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);
ia->hello_holdtime = 0;
else
ia->hello_holdtime = secs;
+
ldp_reload(vty_conf);
break;
default:
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);
ia->hello_interval = 0;
else
ia->hello_interval = secs;
+
ldp_reload(vty_conf);
break;
default:
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);
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);
ia->enabled = 0;
ia->hello_holdtime = 0;
ia->hello_interval = 0;
+
ldp_reload(vty_conf);
+
return (CMD_SUCCESS);
}
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);
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;
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);
}
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);
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);
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;
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;
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);
}
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
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;
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
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;
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
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;
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);
}
lif = l2vpn_if_new(l2vpn, ifname);
RB_INSERT(l2vpn_if_head, &l2vpn->if_tree, lif);
+ QOBJ_REG(lif, l2vpn_if);
ldp_reload(vty_conf);
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;
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);
}
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);
}
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 {
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;
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));
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;
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
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;
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
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
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);
}
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);
}
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);
}
l2vpn = l2vpn_new(name);
l2vpn->type = L2VPN_TYPE_VPLS;
RB_INSERT(l2vpn_head, &conf->l2vpn_tree, l2vpn);
+ QOBJ_REG(l2vpn, l2vpn);
return (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);
}
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);
}
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);
}
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 *);
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;
/* 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();
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 {
merge_config(ldpd_conf, xconf);
- vty_conf = ldp_dup_config(ldpd_conf);
-
return (0);
}
if (iface->ipv4.enabled || iface->ipv6.enabled)
continue;
+ QOBJ_UNREG(iface);
RB_REMOVE(iface_head, &vty_conf->iface_tree, iface);
free(iface);
}
if (nbrp->auth.method != AUTH_NONE)
continue;
+ QOBJ_UNREG(nbrp);
RB_REMOVE(nbrp_head, &vty_conf->nbrp_tree, nbrp);
free(nbrp);
}
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);
}
if (tnbr->af != af)
continue;
+ QOBJ_UNREG(tnbr);
RB_REMOVE(tnbr_head, &conf->tnbr_tree, tnbr);
free(tnbr);
}
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
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)
{
merge_tnbrs(conf, xconf);
merge_nbrps(conf, xconf);
merge_l2vpns(conf, xconf);
- free(xconf);
}
static void
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;
}
/* 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);
}
}
/* 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;
}
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;
/* update existing tnbrs */
if (!(tnbr->flags & F_TNBR_CONFIGURED))
tnbr->flags |= F_TNBR_CONFIGURED;
- RB_REMOVE(tnbr_head, &xconf->tnbr_tree, xt);
- free(xt);
}
}
/* 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) {
nbr_establish_connection(nbr);
}
break;
+ case PROC_LDE_ENGINE:
case PROC_MAIN:
- QOBJ_UNREG (nbrp);
break;
}
RB_REMOVE(nbrp_head, &conf->nbrp_tree, nbrp);
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;
nbr_establish_connection(nbr);
}
}
- RB_REMOVE(nbrp_head, &xconf->nbrp_tree, xn);
- free(xn);
}
}
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);
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);
}
}
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);
}
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 */
ldpe_l2vpn_pw_exit(pw);
break;
case PROC_MAIN:
- QOBJ_UNREG (pw);
break;
}
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;
l2vpn->pw_type = previous_pw_type;
l2vpn->mtu = previous_mtu;
}
-
- RB_REMOVE(l2vpn_pw_head, &xl->pw_tree, xp);
- free(xp);
}
/* merge inactive pseudowires */
/* 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;
}
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;
xconf->trans_pref = conf->trans_pref;
xconf->flags = conf->flags;
merge_config(conf, xconf);
+ free(xconf);
free(conf);
}
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);
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:
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:
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:
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;
/* 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 *);