mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-08 14:34:22 +00:00
ldpd: use red-black trees to store 'l2vpn' elements
Using red-black trees instead of linked lists brings the following benefits: 1 - Elements are naturally ordered (no need to reorder anything before outputting data to the user); 2 - Faster lookups/deletes: O(log n) time complexity against O(n). The insert operation with red-black trees is more expensive though, but that's not a big issue since lookups are much more frequent. Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
This commit is contained in:
parent
c485351c52
commit
2db4e1fca1
25
ldpd/l2vpn.c
25
ldpd/l2vpn.c
@ -26,7 +26,16 @@
|
|||||||
#include "lde.h"
|
#include "lde.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
static void l2vpn_pw_fec(struct l2vpn_pw *, struct fec *);
|
static void l2vpn_pw_fec(struct l2vpn_pw *, struct fec *);
|
||||||
|
static __inline int l2vpn_compare(struct l2vpn *, struct l2vpn *);
|
||||||
|
|
||||||
|
RB_GENERATE(l2vpn_head, l2vpn, entry, l2vpn_compare)
|
||||||
|
|
||||||
|
static __inline int
|
||||||
|
l2vpn_compare(struct l2vpn *a, struct l2vpn *b)
|
||||||
|
{
|
||||||
|
return (strcmp(a->name, b->name));
|
||||||
|
}
|
||||||
|
|
||||||
struct l2vpn *
|
struct l2vpn *
|
||||||
l2vpn_new(const char *name)
|
l2vpn_new(const char *name)
|
||||||
@ -52,13 +61,9 @@ l2vpn_new(const char *name)
|
|||||||
struct l2vpn *
|
struct l2vpn *
|
||||||
l2vpn_find(struct ldpd_conf *xconf, const char *name)
|
l2vpn_find(struct ldpd_conf *xconf, const char *name)
|
||||||
{
|
{
|
||||||
struct l2vpn *l2vpn;
|
struct l2vpn l2vpn;
|
||||||
|
strlcpy(l2vpn.name, name, sizeof(l2vpn.name));
|
||||||
LIST_FOREACH(l2vpn, &xconf->l2vpn_list, entry)
|
return (RB_FIND(l2vpn_head, &xconf->l2vpn_tree, &l2vpn));
|
||||||
if (strcmp(l2vpn->name, name) == 0)
|
|
||||||
return (l2vpn);
|
|
||||||
|
|
||||||
return (NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -399,7 +404,7 @@ l2vpn_sync_pws(int af, union ldpd_addr *addr)
|
|||||||
struct fec_node *fn;
|
struct fec_node *fn;
|
||||||
struct fec_nh *fnh;
|
struct fec_nh *fnh;
|
||||||
|
|
||||||
LIST_FOREACH(l2vpn, &ldeconf->l2vpn_list, entry) {
|
RB_FOREACH(l2vpn, l2vpn_head, &ldeconf->l2vpn_tree) {
|
||||||
LIST_FOREACH(pw, &l2vpn->pw_list, entry) {
|
LIST_FOREACH(pw, &l2vpn->pw_list, entry) {
|
||||||
if (af != pw->af || ldp_addrcmp(af, &pw->addr, addr))
|
if (af != pw->af || ldp_addrcmp(af, &pw->addr, addr))
|
||||||
continue;
|
continue;
|
||||||
@ -428,7 +433,7 @@ l2vpn_pw_ctl(pid_t pid)
|
|||||||
struct l2vpn_pw *pw;
|
struct l2vpn_pw *pw;
|
||||||
static struct ctl_pw pwctl;
|
static struct ctl_pw pwctl;
|
||||||
|
|
||||||
LIST_FOREACH(l2vpn, &ldeconf->l2vpn_list, entry)
|
RB_FOREACH(l2vpn, l2vpn_head, &ldeconf->l2vpn_tree)
|
||||||
LIST_FOREACH(pw, &l2vpn->pw_list, entry) {
|
LIST_FOREACH(pw, &l2vpn->pw_list, entry) {
|
||||||
memset(&pwctl, 0, sizeof(pwctl));
|
memset(&pwctl, 0, sizeof(pwctl));
|
||||||
strlcpy(pwctl.l2vpn_name, pw->l2vpn->name,
|
strlcpy(pwctl.l2vpn_name, pw->l2vpn->name,
|
||||||
|
@ -475,7 +475,7 @@ lde_dispatch_parent(struct thread *thread)
|
|||||||
RB_INIT(&nconf->iface_tree);
|
RB_INIT(&nconf->iface_tree);
|
||||||
RB_INIT(&nconf->tnbr_tree);
|
RB_INIT(&nconf->tnbr_tree);
|
||||||
RB_INIT(&nconf->nbrp_tree);
|
RB_INIT(&nconf->nbrp_tree);
|
||||||
LIST_INIT(&nconf->l2vpn_list);
|
RB_INIT(&nconf->l2vpn_tree);
|
||||||
break;
|
break;
|
||||||
case IMSG_RECONF_IFACE:
|
case IMSG_RECONF_IFACE:
|
||||||
if ((niface = malloc(sizeof(struct iface))) == NULL)
|
if ((niface = malloc(sizeof(struct iface))) == NULL)
|
||||||
@ -513,7 +513,7 @@ lde_dispatch_parent(struct thread *thread)
|
|||||||
LIST_INIT(&nl2vpn->pw_list);
|
LIST_INIT(&nl2vpn->pw_list);
|
||||||
LIST_INIT(&nl2vpn->pw_inactive_list);
|
LIST_INIT(&nl2vpn->pw_inactive_list);
|
||||||
|
|
||||||
LIST_INSERT_HEAD(&nconf->l2vpn_list, nl2vpn, entry);
|
RB_INSERT(l2vpn_head, &nconf->l2vpn_tree, nl2vpn);
|
||||||
break;
|
break;
|
||||||
case IMSG_RECONF_L2VPN_IF:
|
case IMSG_RECONF_L2VPN_IF:
|
||||||
if ((nlif = malloc(sizeof(struct l2vpn_if))) == NULL)
|
if ((nlif = malloc(sizeof(struct l2vpn_if))) == NULL)
|
||||||
|
@ -341,7 +341,7 @@ ldp_l2vpn_config_write(struct vty *vty)
|
|||||||
struct l2vpn_if *lif;
|
struct l2vpn_if *lif;
|
||||||
struct l2vpn_pw *pw;
|
struct l2vpn_pw *pw;
|
||||||
|
|
||||||
LIST_FOREACH(l2vpn, &ldpd_conf->l2vpn_list, entry) {
|
RB_FOREACH(l2vpn, l2vpn_head, &ldpd_conf->l2vpn_tree) {
|
||||||
vty_out(vty, "l2vpn %s type vpls%s", l2vpn->name, VTY_NEWLINE);
|
vty_out(vty, "l2vpn %s type vpls%s", l2vpn->name, VTY_NEWLINE);
|
||||||
|
|
||||||
if (l2vpn->pw_type != DEFAULT_PW_TYPE)
|
if (l2vpn->pw_type != DEFAULT_PW_TYPE)
|
||||||
@ -393,7 +393,7 @@ ldp_iface_is_configured(struct ldpd_conf *xconf, const char *ifname)
|
|||||||
if (if_lookup_name(xconf, ifname))
|
if (if_lookup_name(xconf, ifname))
|
||||||
return (1);
|
return (1);
|
||||||
|
|
||||||
LIST_FOREACH(l2vpn, &xconf->l2vpn_list, entry) {
|
RB_FOREACH(l2vpn, l2vpn_head, &xconf->l2vpn_tree) {
|
||||||
if (l2vpn_if_find_name(l2vpn, ifname))
|
if (l2vpn_if_find_name(l2vpn, ifname))
|
||||||
return (1);
|
return (1);
|
||||||
if (l2vpn_pw_find_name(l2vpn, ifname))
|
if (l2vpn_pw_find_name(l2vpn, ifname))
|
||||||
@ -1235,7 +1235,7 @@ ldp_vty_l2vpn(struct vty *vty, struct vty_arg *args[])
|
|||||||
if (l2vpn == NULL)
|
if (l2vpn == NULL)
|
||||||
goto cancel;
|
goto cancel;
|
||||||
|
|
||||||
LIST_REMOVE(l2vpn, entry);
|
RB_REMOVE(l2vpn_head, &vty_conf->l2vpn_tree, l2vpn);
|
||||||
l2vpn_del(l2vpn);
|
l2vpn_del(l2vpn);
|
||||||
ldp_reload(vty_conf);
|
ldp_reload(vty_conf);
|
||||||
return (CMD_SUCCESS);
|
return (CMD_SUCCESS);
|
||||||
@ -1248,7 +1248,7 @@ ldp_vty_l2vpn(struct vty *vty, struct vty_arg *args[])
|
|||||||
|
|
||||||
l2vpn = l2vpn_new(name_str);
|
l2vpn = l2vpn_new(name_str);
|
||||||
l2vpn->type = L2VPN_TYPE_VPLS;
|
l2vpn->type = L2VPN_TYPE_VPLS;
|
||||||
LIST_INSERT_HEAD(&vty_conf->l2vpn_list, l2vpn, entry);
|
RB_INSERT(l2vpn_head, &vty_conf->l2vpn_tree, l2vpn);
|
||||||
|
|
||||||
ldp_reload(vty_conf);
|
ldp_reload(vty_conf);
|
||||||
VTY_PUSH_CONTEXT(LDP_L2VPN_NODE, l2vpn);
|
VTY_PUSH_CONTEXT(LDP_L2VPN_NODE, l2vpn);
|
||||||
@ -1713,12 +1713,12 @@ l2vpn_new_api(struct ldpd_conf *conf, const char *name)
|
|||||||
|
|
||||||
l2vpn = l2vpn_new(name);
|
l2vpn = l2vpn_new(name);
|
||||||
l2vpn->type = L2VPN_TYPE_VPLS;
|
l2vpn->type = L2VPN_TYPE_VPLS;
|
||||||
LIST_INSERT_HEAD(&conf->l2vpn_list, l2vpn, entry);
|
RB_INSERT(l2vpn_head, &conf->l2vpn_tree, l2vpn);
|
||||||
return (l2vpn);
|
return (l2vpn);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
l2vpn_del_api(struct l2vpn *l2vpn)
|
l2vpn_del_api(struct ldpd_conf *conf, struct l2vpn *l2vpn)
|
||||||
{
|
{
|
||||||
struct l2vpn_if *lif;
|
struct l2vpn_if *lif;
|
||||||
struct l2vpn_pw *pw;
|
struct l2vpn_pw *pw;
|
||||||
@ -1735,7 +1735,7 @@ l2vpn_del_api(struct l2vpn *l2vpn)
|
|||||||
LIST_REMOVE(pw, entry);
|
LIST_REMOVE(pw, entry);
|
||||||
free(pw);
|
free(pw);
|
||||||
}
|
}
|
||||||
LIST_REMOVE(l2vpn, entry);
|
RB_REMOVE(l2vpn_head, &conf->l2vpn_tree, l2vpn);
|
||||||
free(l2vpn);
|
free(l2vpn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
28
ldpd/ldpd.c
28
ldpd/ldpd.c
@ -909,7 +909,7 @@ main_imsg_send_config(struct ldpd_conf *xconf)
|
|||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
LIST_FOREACH(l2vpn, &xconf->l2vpn_list, entry) {
|
RB_FOREACH(l2vpn, l2vpn_head, &xconf->l2vpn_tree) {
|
||||||
if (main_imsg_compose_both(IMSG_RECONF_L2VPN, l2vpn,
|
if (main_imsg_compose_both(IMSG_RECONF_L2VPN, l2vpn,
|
||||||
sizeof(*l2vpn)) == -1)
|
sizeof(*l2vpn)) == -1)
|
||||||
return (-1);
|
return (-1);
|
||||||
@ -971,7 +971,7 @@ ldp_config_normalize(struct ldpd_conf *xconf, void **ref)
|
|||||||
ldp_config_reset_af(xconf, AF_INET6, ref);
|
ldp_config_reset_af(xconf, AF_INET6, ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
LIST_FOREACH(l2vpn, &xconf->l2vpn_list, entry) {
|
RB_FOREACH(l2vpn, l2vpn_head, &xconf->l2vpn_tree) {
|
||||||
LIST_FOREACH(pw, &l2vpn->pw_list, entry) {
|
LIST_FOREACH(pw, &l2vpn->pw_list, entry) {
|
||||||
if (pw->flags & F_PW_STATIC_NBR_ADDR)
|
if (pw->flags & F_PW_STATIC_NBR_ADDR)
|
||||||
continue;
|
continue;
|
||||||
@ -1076,7 +1076,7 @@ ldp_dup_config_ref(struct ldpd_conf *conf, void **ref)
|
|||||||
RB_INIT(&xconf->iface_tree);
|
RB_INIT(&xconf->iface_tree);
|
||||||
RB_INIT(&xconf->tnbr_tree);
|
RB_INIT(&xconf->tnbr_tree);
|
||||||
RB_INIT(&xconf->nbrp_tree);
|
RB_INIT(&xconf->nbrp_tree);
|
||||||
LIST_INIT(&xconf->l2vpn_list);
|
RB_INIT(&xconf->l2vpn_tree);
|
||||||
|
|
||||||
RB_FOREACH(iface, iface_head, &conf->iface_tree) {
|
RB_FOREACH(iface, iface_head, &conf->iface_tree) {
|
||||||
COPY(xi, iface);
|
COPY(xi, iface);
|
||||||
@ -1092,12 +1092,12 @@ ldp_dup_config_ref(struct ldpd_conf *conf, void **ref)
|
|||||||
COPY(xn, nbrp);
|
COPY(xn, nbrp);
|
||||||
RB_INSERT(nbrp_head, &xconf->nbrp_tree, xn);
|
RB_INSERT(nbrp_head, &xconf->nbrp_tree, xn);
|
||||||
}
|
}
|
||||||
LIST_FOREACH(l2vpn, &conf->l2vpn_list, entry) {
|
RB_FOREACH(l2vpn, l2vpn_head, &conf->l2vpn_tree) {
|
||||||
COPY(xl, l2vpn);
|
COPY(xl, l2vpn);
|
||||||
LIST_INIT(&xl->if_list);
|
LIST_INIT(&xl->if_list);
|
||||||
LIST_INIT(&xl->pw_list);
|
LIST_INIT(&xl->pw_list);
|
||||||
LIST_INIT(&xl->pw_inactive_list);
|
LIST_INIT(&xl->pw_inactive_list);
|
||||||
LIST_INSERT_HEAD(&xconf->l2vpn_list, xl, entry);
|
RB_INSERT(l2vpn_head, &xconf->l2vpn_tree, xl);
|
||||||
|
|
||||||
LIST_FOREACH(lif, &l2vpn->if_list, entry) {
|
LIST_FOREACH(lif, &l2vpn->if_list, entry) {
|
||||||
COPY(xf, lif);
|
COPY(xf, lif);
|
||||||
@ -1146,8 +1146,8 @@ ldp_clear_config(struct ldpd_conf *xconf)
|
|||||||
RB_REMOVE(nbrp_head, &xconf->nbrp_tree, nbrp);
|
RB_REMOVE(nbrp_head, &xconf->nbrp_tree, nbrp);
|
||||||
free(nbrp);
|
free(nbrp);
|
||||||
}
|
}
|
||||||
while ((l2vpn = LIST_FIRST(&xconf->l2vpn_list)) != NULL) {
|
while ((l2vpn = RB_ROOT(&xconf->l2vpn_tree)) != NULL) {
|
||||||
LIST_REMOVE(l2vpn, entry);
|
RB_REMOVE(l2vpn_head, &xconf->l2vpn_tree, l2vpn);
|
||||||
l2vpn_del(l2vpn);
|
l2vpn_del(l2vpn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1510,10 +1510,10 @@ merge_l2vpns(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
|
|||||||
struct l2vpn_if *lif;
|
struct l2vpn_if *lif;
|
||||||
struct l2vpn_pw *pw;
|
struct l2vpn_pw *pw;
|
||||||
|
|
||||||
LIST_FOREACH_SAFE(l2vpn, &conf->l2vpn_list, entry, ltmp) {
|
RB_FOREACH_SAFE(l2vpn, l2vpn_head, &conf->l2vpn_tree, ltmp) {
|
||||||
/* find deleted l2vpns */
|
/* find deleted l2vpns */
|
||||||
if ((xl = l2vpn_find(xconf, l2vpn->name)) == NULL) {
|
if ((xl = l2vpn_find(xconf, l2vpn->name)) == NULL) {
|
||||||
LIST_REMOVE(l2vpn, entry);
|
RB_REMOVE(l2vpn_head, &conf->l2vpn_tree, l2vpn);
|
||||||
|
|
||||||
switch (ldpd_process) {
|
switch (ldpd_process) {
|
||||||
case PROC_LDE_ENGINE:
|
case PROC_LDE_ENGINE:
|
||||||
@ -1535,11 +1535,11 @@ merge_l2vpns(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
|
|||||||
l2vpn_del(l2vpn);
|
l2vpn_del(l2vpn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LIST_FOREACH_SAFE(xl, &xconf->l2vpn_list, entry, ltmp) {
|
RB_FOREACH_SAFE(xl, l2vpn_head, &xconf->l2vpn_tree, ltmp) {
|
||||||
/* find new l2vpns */
|
/* find new l2vpns */
|
||||||
if ((l2vpn = l2vpn_find(conf, xl->name)) == NULL) {
|
if ((l2vpn = l2vpn_find(conf, xl->name)) == NULL) {
|
||||||
LIST_REMOVE(xl, entry);
|
RB_REMOVE(l2vpn_head, &xconf->l2vpn_tree, xl);
|
||||||
LIST_INSERT_HEAD(&conf->l2vpn_list, xl, entry);
|
RB_INSERT(l2vpn_head, &conf->l2vpn_tree, xl);
|
||||||
|
|
||||||
switch (ldpd_process) {
|
switch (ldpd_process) {
|
||||||
case PROC_LDE_ENGINE:
|
case PROC_LDE_ENGINE:
|
||||||
@ -1557,7 +1557,7 @@ merge_l2vpns(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
|
|||||||
|
|
||||||
/* update existing l2vpns */
|
/* update existing l2vpns */
|
||||||
merge_l2vpn(conf, l2vpn, xl, ref);
|
merge_l2vpn(conf, l2vpn, xl, ref);
|
||||||
LIST_REMOVE(xl, entry);
|
RB_REMOVE(l2vpn_head, &xconf->l2vpn_tree, xl);
|
||||||
if (ref && *ref == xl)
|
if (ref && *ref == xl)
|
||||||
*ref = l2vpn;
|
*ref = l2vpn;
|
||||||
free(xl);
|
free(xl);
|
||||||
@ -1814,7 +1814,7 @@ config_new_empty(void)
|
|||||||
RB_INIT(&xconf->iface_tree);
|
RB_INIT(&xconf->iface_tree);
|
||||||
RB_INIT(&xconf->tnbr_tree);
|
RB_INIT(&xconf->tnbr_tree);
|
||||||
RB_INIT(&xconf->nbrp_tree);
|
RB_INIT(&xconf->nbrp_tree);
|
||||||
LIST_INIT(&xconf->l2vpn_list);
|
RB_INIT(&xconf->l2vpn_tree);
|
||||||
|
|
||||||
return (xconf);
|
return (xconf);
|
||||||
}
|
}
|
||||||
|
11
ldpd/ldpd.h
11
ldpd/ldpd.h
@ -358,7 +358,7 @@ DECLARE_QOBJ_TYPE(l2vpn_pw)
|
|||||||
#define F_PW_STATIC_NBR_ADDR 0x20 /* static neighbor address configured */
|
#define F_PW_STATIC_NBR_ADDR 0x20 /* static neighbor address configured */
|
||||||
|
|
||||||
struct l2vpn {
|
struct l2vpn {
|
||||||
LIST_ENTRY(l2vpn) entry;
|
RB_ENTRY(l2vpn) entry;
|
||||||
char name[L2VPN_NAME_LEN];
|
char name[L2VPN_NAME_LEN];
|
||||||
int type;
|
int type;
|
||||||
int pw_type;
|
int pw_type;
|
||||||
@ -370,6 +370,8 @@ struct l2vpn {
|
|||||||
LIST_HEAD(, l2vpn_pw) pw_inactive_list;
|
LIST_HEAD(, l2vpn_pw) pw_inactive_list;
|
||||||
QOBJ_FIELDS
|
QOBJ_FIELDS
|
||||||
};
|
};
|
||||||
|
RB_HEAD(l2vpn_head, l2vpn);
|
||||||
|
RB_PROTOTYPE(l2vpn_head, l2vpn, entry, l2vpn_compare);
|
||||||
DECLARE_QOBJ_TYPE(l2vpn)
|
DECLARE_QOBJ_TYPE(l2vpn)
|
||||||
#define L2VPN_TYPE_VPWS 1
|
#define L2VPN_TYPE_VPWS 1
|
||||||
#define L2VPN_TYPE_VPLS 2
|
#define L2VPN_TYPE_VPLS 2
|
||||||
@ -413,7 +415,7 @@ struct ldpd_conf {
|
|||||||
struct iface_head iface_tree;
|
struct iface_head iface_tree;
|
||||||
struct tnbr_head tnbr_tree;
|
struct tnbr_head tnbr_tree;
|
||||||
struct nbrp_head nbrp_tree;
|
struct nbrp_head nbrp_tree;
|
||||||
LIST_HEAD(, l2vpn) l2vpn_list;
|
struct l2vpn_head l2vpn_tree;
|
||||||
uint16_t lhello_holdtime;
|
uint16_t lhello_holdtime;
|
||||||
uint16_t lhello_interval;
|
uint16_t lhello_interval;
|
||||||
uint16_t thello_holdtime;
|
uint16_t thello_holdtime;
|
||||||
@ -644,8 +646,9 @@ struct nbr_params *nbrp_new_api(struct ldpd_conf *conf,
|
|||||||
struct in_addr lsr_id);
|
struct in_addr lsr_id);
|
||||||
void nbrp_del_api(struct ldpd_conf *conf,
|
void nbrp_del_api(struct ldpd_conf *conf,
|
||||||
struct nbr_params *nbrp);
|
struct nbr_params *nbrp);
|
||||||
struct l2vpn *l2vpn_new_api(struct ldpd_conf *cfg, const char *name);
|
struct l2vpn *l2vpn_new_api(struct ldpd_conf *conf, const char *name);
|
||||||
void l2vpn_del_api(struct l2vpn *l2vpn);
|
void l2vpn_del_api(struct ldpd_conf *conf,
|
||||||
|
struct l2vpn *l2vpn);
|
||||||
struct l2vpn_if *l2vpn_if_new_api(struct ldpd_conf *conf,
|
struct l2vpn_if *l2vpn_if_new_api(struct ldpd_conf *conf,
|
||||||
struct l2vpn *l2vpn, const char *ifname);
|
struct l2vpn *l2vpn, const char *ifname);
|
||||||
void l2vpn_if_del_api(struct l2vpn_if *lif);
|
void l2vpn_if_del_api(struct l2vpn_if *lif);
|
||||||
|
@ -418,7 +418,7 @@ ldpe_dispatch_main(struct thread *thread)
|
|||||||
RB_INIT(&nconf->iface_tree);
|
RB_INIT(&nconf->iface_tree);
|
||||||
RB_INIT(&nconf->tnbr_tree);
|
RB_INIT(&nconf->tnbr_tree);
|
||||||
RB_INIT(&nconf->nbrp_tree);
|
RB_INIT(&nconf->nbrp_tree);
|
||||||
LIST_INIT(&nconf->l2vpn_list);
|
RB_INIT(&nconf->l2vpn_tree);
|
||||||
break;
|
break;
|
||||||
case IMSG_RECONF_IFACE:
|
case IMSG_RECONF_IFACE:
|
||||||
if ((niface = malloc(sizeof(struct iface))) == NULL)
|
if ((niface = malloc(sizeof(struct iface))) == NULL)
|
||||||
@ -456,7 +456,7 @@ ldpe_dispatch_main(struct thread *thread)
|
|||||||
LIST_INIT(&nl2vpn->pw_list);
|
LIST_INIT(&nl2vpn->pw_list);
|
||||||
LIST_INIT(&nl2vpn->pw_inactive_list);
|
LIST_INIT(&nl2vpn->pw_inactive_list);
|
||||||
|
|
||||||
LIST_INSERT_HEAD(&nconf->l2vpn_list, nl2vpn, entry);
|
RB_INSERT(l2vpn_head, &nconf->l2vpn_tree, nl2vpn);
|
||||||
break;
|
break;
|
||||||
case IMSG_RECONF_L2VPN_IF:
|
case IMSG_RECONF_L2VPN_IF:
|
||||||
if ((nlif = malloc(sizeof(struct l2vpn_if))) == NULL)
|
if ((nlif = malloc(sizeof(struct l2vpn_if))) == NULL)
|
||||||
|
Loading…
Reference in New Issue
Block a user