Merge pull request #40 from opensourcerouting/ldpd-ordered-output

ldpd ordered output - fixes issue#18
This commit is contained in:
Donald Sharp 2017-01-06 14:01:23 -05:00 committed by GitHub
commit aac93a83e3
14 changed files with 460 additions and 370 deletions

View file

@ -25,12 +25,55 @@
#include "ldpe.h" #include "ldpe.h"
#include "log.h" #include "log.h"
static __inline int adj_compare(struct adj *, struct adj *);
static int adj_itimer(struct thread *); static int adj_itimer(struct thread *);
static void tnbr_del(struct tnbr *); static __inline int tnbr_compare(struct tnbr *, struct tnbr *);
static void tnbr_del(struct ldpd_conf *, struct tnbr *);
static int tnbr_hello_timer(struct thread *); static int tnbr_hello_timer(struct thread *);
static void tnbr_start_hello_timer(struct tnbr *); static void tnbr_start_hello_timer(struct tnbr *);
static void tnbr_stop_hello_timer(struct tnbr *); static void tnbr_stop_hello_timer(struct tnbr *);
RB_GENERATE(global_adj_head, adj, global_entry, adj_compare)
RB_GENERATE(nbr_adj_head, adj, nbr_entry, adj_compare)
RB_GENERATE(ia_adj_head, adj, ia_entry, adj_compare)
RB_GENERATE(tnbr_head, tnbr, entry, tnbr_compare)
static __inline int
adj_compare(struct adj *a, struct adj *b)
{
if (a->source.type < b->source.type)
return (-1);
if (a->source.type > b->source.type)
return (1);
switch (a->source.type) {
case HELLO_LINK:
if (strcmp(a->source.link.ia->iface->name,
b->source.link.ia->iface->name) < 0)
return (-1);
if (strcmp(a->source.link.ia->iface->name,
b->source.link.ia->iface->name) > 0)
return (1);
if (a->source.link.ia->af < b->source.link.ia->af)
return (-1);
if (a->source.link.ia->af > b->source.link.ia->af)
return (1);
return (ldp_addrcmp(a->source.link.ia->af,
&a->source.link.src_addr, &b->source.link.src_addr));
case HELLO_TARGETED:
if (a->source.target->af < b->source.target->af)
return (-1);
if (a->source.target->af > b->source.target->af)
return (1);
return (ldp_addrcmp(a->source.target->af,
&a->source.target->addr, &b->source.target->addr));
default:
fatalx("adj_get_af: unknown hello type");
}
return (0);
}
struct adj * struct adj *
adj_new(struct in_addr lsr_id, struct hello_source *source, adj_new(struct in_addr lsr_id, struct hello_source *source,
union ldpd_addr *addr) union ldpd_addr *addr)
@ -48,11 +91,11 @@ adj_new(struct in_addr lsr_id, struct hello_source *source,
adj->source = *source; adj->source = *source;
adj->trans_addr = *addr; adj->trans_addr = *addr;
LIST_INSERT_HEAD(&global.adj_list, adj, global_entry); RB_INSERT(global_adj_head, &global.adj_tree, adj);
switch (source->type) { switch (source->type) {
case HELLO_LINK: case HELLO_LINK:
LIST_INSERT_HEAD(&source->link.ia->adj_list, adj, ia_entry); RB_INSERT(ia_adj_head, &source->link.ia->adj_tree, adj);
break; break;
case HELLO_TARGETED: case HELLO_TARGETED:
source->target->adj = adj; source->target->adj = adj;
@ -70,12 +113,12 @@ adj_del_single(struct adj *adj)
adj_stop_itimer(adj); adj_stop_itimer(adj);
LIST_REMOVE(adj, global_entry); RB_REMOVE(global_adj_head, &global.adj_tree, adj);
if (adj->nbr) if (adj->nbr)
LIST_REMOVE(adj, nbr_entry); RB_REMOVE(nbr_adj_head, &adj->nbr->adj_tree, adj);
switch (adj->source.type) { switch (adj->source.type) {
case HELLO_LINK: case HELLO_LINK:
LIST_REMOVE(adj, ia_entry); RB_REMOVE(ia_adj_head, &adj->source.link.ia->adj_tree, adj);
break; break;
case HELLO_TARGETED: case HELLO_TARGETED:
adj->source.target->adj = NULL; adj->source.target->adj = NULL;
@ -99,7 +142,7 @@ adj_del(struct adj *adj, uint32_t notif_status)
* then delete it. * then delete it.
*/ */
if (nbr && nbr_adj_count(nbr, nbr->af) == 0) { if (nbr && nbr_adj_count(nbr, nbr->af) == 0) {
LIST_FOREACH_SAFE(adj, &nbr->adj_list, nbr_entry, atmp) RB_FOREACH_SAFE(adj, nbr_adj_head, &nbr->adj_tree, atmp)
adj_del_single(adj); adj_del_single(adj);
session_shutdown(nbr, notif_status, 0, 0); session_shutdown(nbr, notif_status, 0, 0);
nbr_del(nbr); nbr_del(nbr);
@ -109,31 +152,9 @@ adj_del(struct adj *adj, uint32_t notif_status)
struct adj * struct adj *
adj_find(struct hello_source *source) adj_find(struct hello_source *source)
{ {
struct adj *adj; struct adj adj;
adj.source = *source;
LIST_FOREACH(adj, &global.adj_list, global_entry) { return (RB_FIND(global_adj_head, &global.adj_tree, &adj));
if (adj->source.type != source->type)
continue;
switch (source->type) {
case HELLO_LINK:
if (strcmp(source->link.ia->iface->name,
adj->source.link.ia->iface->name))
continue;
if (ldp_addrcmp(source->link.ia->af,
&adj->source.link.src_addr,
&source->link.src_addr) == 0)
return (adj);
break;
case HELLO_TARGETED:
if (adj->source.target == source->target)
return (adj);
break;
}
}
return (NULL);
} }
int int
@ -165,7 +186,7 @@ adj_itimer(struct thread *thread)
if (!(adj->source.target->flags & F_TNBR_CONFIGURED) && if (!(adj->source.target->flags & F_TNBR_CONFIGURED) &&
adj->source.target->pw_count == 0) { adj->source.target->pw_count == 0) {
/* remove dynamic targeted neighbor */ /* remove dynamic targeted neighbor */
tnbr_del(adj->source.target); tnbr_del(leconf, adj->source.target);
return (0); return (0);
} }
adj->source.target->adj = NULL; adj->source.target->adj = NULL;
@ -192,6 +213,17 @@ adj_stop_itimer(struct adj *adj)
/* targeted neighbors */ /* targeted neighbors */
static __inline int
tnbr_compare(struct tnbr *a, struct tnbr *b)
{
if (a->af < b->af)
return (-1);
if (a->af > b->af)
return (1);
return (ldp_addrcmp(a->af, &a->addr, &b->addr));
}
struct tnbr * struct tnbr *
tnbr_new(int af, union ldpd_addr *addr) tnbr_new(int af, union ldpd_addr *addr)
{ {
@ -208,34 +240,30 @@ tnbr_new(int af, union ldpd_addr *addr)
} }
static void static void
tnbr_del(struct tnbr *tnbr) tnbr_del(struct ldpd_conf *xconf, struct tnbr *tnbr)
{ {
tnbr_stop_hello_timer(tnbr); tnbr_stop_hello_timer(tnbr);
if (tnbr->adj) if (tnbr->adj)
adj_del(tnbr->adj, S_SHUTDOWN); adj_del(tnbr->adj, S_SHUTDOWN);
LIST_REMOVE(tnbr, entry); RB_REMOVE(tnbr_head, &xconf->tnbr_tree, tnbr);
free(tnbr); free(tnbr);
} }
struct tnbr * struct tnbr *
tnbr_find(struct ldpd_conf *xconf, int af, union ldpd_addr *addr) tnbr_find(struct ldpd_conf *xconf, int af, union ldpd_addr *addr)
{ {
struct tnbr *tnbr; struct tnbr tnbr;
tnbr.af = af;
LIST_FOREACH(tnbr, &xconf->tnbr_list, entry) tnbr.addr = *addr;
if (af == tnbr->af && return (RB_FIND(tnbr_head, &xconf->tnbr_tree, &tnbr));
ldp_addrcmp(af, addr, &tnbr->addr) == 0)
return (tnbr);
return (NULL);
} }
struct tnbr * struct tnbr *
tnbr_check(struct tnbr *tnbr) tnbr_check(struct ldpd_conf *xconf, struct tnbr *tnbr)
{ {
if (!(tnbr->flags & (F_TNBR_CONFIGURED|F_TNBR_DYNAMIC)) && if (!(tnbr->flags & (F_TNBR_CONFIGURED|F_TNBR_DYNAMIC)) &&
tnbr->pw_count == 0) { tnbr->pw_count == 0) {
tnbr_del(tnbr); tnbr_del(xconf, tnbr);
return (NULL); return (NULL);
} }
@ -280,7 +308,7 @@ tnbr_update_all(int af)
struct tnbr *tnbr; struct tnbr *tnbr;
/* update targeted neighbors */ /* update targeted neighbors */
LIST_FOREACH(tnbr, &leconf->tnbr_list, entry) RB_FOREACH(tnbr, tnbr_head, &leconf->tnbr_tree)
if (tnbr->af == af || af == AF_UNSPEC) if (tnbr->af == af || af == AF_UNSPEC)
tnbr_update(tnbr); tnbr_update(tnbr);
} }

View file

@ -261,7 +261,7 @@ recv_hello(struct in_addr lsr_id, struct ldp_msg *msg, int af,
if (tnbr && (tnbr->flags & F_TNBR_DYNAMIC) && if (tnbr && (tnbr->flags & F_TNBR_DYNAMIC) &&
!((flags & F_HELLO_REQ_TARG))) { !((flags & F_HELLO_REQ_TARG))) {
tnbr->flags &= ~F_TNBR_DYNAMIC; tnbr->flags &= ~F_TNBR_DYNAMIC;
tnbr = tnbr_check(tnbr); tnbr = tnbr_check(leconf, tnbr);
} }
if (!tnbr) { if (!tnbr) {
@ -273,7 +273,7 @@ recv_hello(struct in_addr lsr_id, struct ldp_msg *msg, int af,
tnbr = tnbr_new(af, src); tnbr = tnbr_new(af, src);
tnbr->flags |= F_TNBR_DYNAMIC; tnbr->flags |= F_TNBR_DYNAMIC;
tnbr_update(tnbr); tnbr_update(tnbr);
LIST_INSERT_HEAD(&leconf->tnbr_list, tnbr, entry); RB_INSERT(tnbr_head, &leconf->tnbr_tree, tnbr);
} }
source.type = HELLO_TARGETED; source.type = HELLO_TARGETED;
@ -364,7 +364,7 @@ recv_hello(struct in_addr lsr_id, struct ldp_msg *msg, int af,
adj = adj_new(lsr_id, &source, &trans_addr); adj = adj_new(lsr_id, &source, &trans_addr);
if (nbr) { if (nbr) {
adj->nbr = nbr; adj->nbr = nbr;
LIST_INSERT_HEAD(&nbr->adj_list, adj, nbr_entry); RB_INSERT(nbr_adj_head, &nbr->adj_tree, adj);
} }
} }

View file

@ -26,6 +26,7 @@
#include "sockopt.h" #include "sockopt.h"
static __inline int iface_compare(struct iface *, struct iface *);
static struct if_addr *if_addr_new(struct kaddr *); static struct if_addr *if_addr_new(struct kaddr *);
static struct if_addr *if_addr_lookup(struct if_addr_head *, struct kaddr *); static struct if_addr *if_addr_lookup(struct if_addr_head *, struct kaddr *);
static int if_start(struct iface *, int); static int if_start(struct iface *, int);
@ -39,6 +40,14 @@ static int if_leave_ipv4_group(struct iface *, struct in_addr *);
static int if_join_ipv6_group(struct iface *, struct in6_addr *); static int if_join_ipv6_group(struct iface *, struct in6_addr *);
static int if_leave_ipv6_group(struct iface *, struct in6_addr *); static int if_leave_ipv6_group(struct iface *, struct in6_addr *);
RB_GENERATE(iface_head, iface, entry, iface_compare)
static __inline int
iface_compare(struct iface *a, struct iface *b)
{
return (strcmp(a->name, b->name));
}
struct iface * struct iface *
if_new(struct kif *kif) if_new(struct kif *kif)
{ {
@ -57,30 +66,18 @@ if_new(struct kif *kif)
iface->ipv4.iface = iface; iface->ipv4.iface = iface;
iface->ipv4.enabled = 0; iface->ipv4.enabled = 0;
iface->ipv4.state = IF_STA_DOWN; iface->ipv4.state = IF_STA_DOWN;
LIST_INIT(&iface->ipv4.adj_list); RB_INIT(&iface->ipv4.adj_tree);
/* ipv6 */ /* ipv6 */
iface->ipv6.af = AF_INET6; iface->ipv6.af = AF_INET6;
iface->ipv6.iface = iface; iface->ipv6.iface = iface;
iface->ipv6.enabled = 0; iface->ipv6.enabled = 0;
iface->ipv6.state = IF_STA_DOWN; iface->ipv6.state = IF_STA_DOWN;
LIST_INIT(&iface->ipv6.adj_list); RB_INIT(&iface->ipv6.adj_tree);
return (iface); return (iface);
} }
struct iface *
if_lookup(struct ldpd_conf *xconf, unsigned short ifindex)
{
struct iface *iface;
LIST_FOREACH(iface, &xconf->iface_list, entry)
if (iface->ifindex == ifindex)
return (iface);
return (NULL);
}
void void
if_exit(struct iface *iface) if_exit(struct iface *iface)
{ {
@ -100,17 +97,25 @@ if_exit(struct iface *iface)
} }
struct iface * struct iface *
if_lookup_name(struct ldpd_conf *xconf, const char *ifname) if_lookup(struct ldpd_conf *xconf, unsigned short ifindex)
{ {
struct iface *iface; struct iface *iface;
LIST_FOREACH(iface, &xconf->iface_list, entry) RB_FOREACH(iface, iface_head, &xconf->iface_tree)
if (strcmp(iface->name, ifname) == 0) if (iface->ifindex == ifindex)
return (iface); return (iface);
return (NULL); return (NULL);
} }
struct iface *
if_lookup_name(struct ldpd_conf *xconf, const char *ifname)
{
struct iface iface;
strlcpy(iface.name, ifname, sizeof(iface.name));
return (RB_FIND(iface_head, &xconf->iface_tree, &iface));
}
void void
if_update_info(struct iface *iface, struct kif *kif) if_update_info(struct iface *iface, struct kif *kif)
{ {
@ -288,7 +293,7 @@ if_reset(struct iface *iface, int af)
ia = iface_af_get(iface, af); ia = iface_af_get(iface, af);
if_stop_hello_timer(ia); if_stop_hello_timer(ia);
while ((adj = LIST_FIRST(&ia->adj_list)) != NULL) while ((adj = RB_ROOT(&ia->adj_tree)) != NULL)
adj_del(adj, S_SHUTDOWN); adj_del(adj, S_SHUTDOWN);
/* try to cleanup */ /* try to cleanup */
@ -380,7 +385,7 @@ if_update_all(int af)
{ {
struct iface *iface; struct iface *iface;
LIST_FOREACH(iface, &leconf->iface_list, entry) RB_FOREACH(iface, iface_head, &leconf->iface_tree)
if_update(iface, af); if_update(iface, af);
} }
@ -460,7 +465,7 @@ if_to_ctl(struct iface_af *ia)
ictl.uptime = 0; ictl.uptime = 0;
ictl.adj_cnt = 0; ictl.adj_cnt = 0;
LIST_FOREACH(adj, &ia->adj_list, ia_entry) RB_FOREACH(adj, ia_adj_head, &ia->adj_tree)
ictl.adj_cnt++; ictl.adj_cnt++;
return (&ictl); return (&ictl);

View file

@ -26,7 +26,20 @@
#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 *);
static __inline int l2vpn_if_compare(struct l2vpn_if *, struct l2vpn_if *);
static __inline int l2vpn_pw_compare(struct l2vpn_pw *, struct l2vpn_pw *);
RB_GENERATE(l2vpn_head, l2vpn, entry, l2vpn_compare)
RB_GENERATE(l2vpn_if_head, l2vpn_if, entry, l2vpn_if_compare)
RB_GENERATE(l2vpn_pw_head, l2vpn_pw, entry, l2vpn_pw_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)
@ -42,9 +55,9 @@ l2vpn_new(const char *name)
l2vpn->mtu = DEFAULT_L2VPN_MTU; l2vpn->mtu = DEFAULT_L2VPN_MTU;
l2vpn->pw_type = DEFAULT_PW_TYPE; l2vpn->pw_type = DEFAULT_PW_TYPE;
LIST_INIT(&l2vpn->if_list); RB_INIT(&l2vpn->if_tree);
LIST_INIT(&l2vpn->pw_list); RB_INIT(&l2vpn->pw_tree);
LIST_INIT(&l2vpn->pw_inactive_list); RB_INIT(&l2vpn->pw_inactive_tree);
return (l2vpn); return (l2vpn);
} }
@ -52,13 +65,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
@ -67,16 +76,16 @@ l2vpn_del(struct l2vpn *l2vpn)
struct l2vpn_if *lif; struct l2vpn_if *lif;
struct l2vpn_pw *pw; struct l2vpn_pw *pw;
while ((lif = LIST_FIRST(&l2vpn->if_list)) != NULL) { while ((lif = RB_ROOT(&l2vpn->if_tree)) != NULL) {
LIST_REMOVE(lif, entry); RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif);
free(lif); free(lif);
} }
while ((pw = LIST_FIRST(&l2vpn->pw_list)) != NULL) { while ((pw = RB_ROOT(&l2vpn->pw_tree)) != NULL) {
LIST_REMOVE(pw, entry); RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_tree, pw);
free(pw); free(pw);
} }
while ((pw = LIST_FIRST(&l2vpn->pw_inactive_list)) != NULL) { while ((pw = RB_ROOT(&l2vpn->pw_inactive_tree)) != NULL) {
LIST_REMOVE(pw, entry); RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
free(pw); free(pw);
} }
@ -88,7 +97,7 @@ l2vpn_init(struct l2vpn *l2vpn)
{ {
struct l2vpn_pw *pw; struct l2vpn_pw *pw;
LIST_FOREACH(pw, &l2vpn->pw_list, entry) RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree)
l2vpn_pw_init(pw); l2vpn_pw_init(pw);
} }
@ -97,10 +106,16 @@ l2vpn_exit(struct l2vpn *l2vpn)
{ {
struct l2vpn_pw *pw; struct l2vpn_pw *pw;
LIST_FOREACH(pw, &l2vpn->pw_list, entry) RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree)
l2vpn_pw_exit(pw); l2vpn_pw_exit(pw);
} }
static __inline int
l2vpn_if_compare(struct l2vpn_if *a, struct l2vpn_if *b)
{
return (strcmp(a->ifname, b->ifname));
}
struct l2vpn_if * struct l2vpn_if *
l2vpn_if_new(struct l2vpn *l2vpn, struct kif *kif) l2vpn_if_new(struct l2vpn *l2vpn, struct kif *kif)
{ {
@ -122,7 +137,7 @@ l2vpn_if_find(struct l2vpn *l2vpn, unsigned int ifindex)
{ {
struct l2vpn_if *lif; struct l2vpn_if *lif;
LIST_FOREACH(lif, &l2vpn->if_list, entry) RB_FOREACH(lif, l2vpn_if_head, &l2vpn->if_tree)
if (lif->ifindex == ifindex) if (lif->ifindex == ifindex)
return (lif); return (lif);
@ -132,15 +147,16 @@ l2vpn_if_find(struct l2vpn *l2vpn, unsigned int ifindex)
struct l2vpn_if * struct l2vpn_if *
l2vpn_if_find_name(struct l2vpn *l2vpn, const char *ifname) l2vpn_if_find_name(struct l2vpn *l2vpn, const char *ifname)
{ {
struct l2vpn_if *lif; struct l2vpn_if lif;
strlcpy(lif.ifname, ifname, sizeof(lif.ifname));
LIST_FOREACH(lif, &l2vpn->if_list, entry) return (RB_FIND(l2vpn_if_head, &l2vpn->if_tree, &lif));
if (strcmp(lif->ifname, ifname) == 0)
return (lif);
return (NULL);
} }
static __inline int
l2vpn_pw_compare(struct l2vpn_pw *a, struct l2vpn_pw *b)
{
return (strcmp(a->ifname, b->ifname));
}
struct l2vpn_pw * struct l2vpn_pw *
l2vpn_pw_new(struct l2vpn *l2vpn, struct kif *kif) l2vpn_pw_new(struct l2vpn *l2vpn, struct kif *kif)
@ -162,10 +178,10 @@ l2vpn_pw_find(struct l2vpn *l2vpn, unsigned int ifindex)
{ {
struct l2vpn_pw *pw; struct l2vpn_pw *pw;
LIST_FOREACH(pw, &l2vpn->pw_list, entry) RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree)
if (pw->ifindex == ifindex) if (pw->ifindex == ifindex)
return (pw); return (pw);
LIST_FOREACH(pw, &l2vpn->pw_inactive_list, entry) RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_inactive_tree)
if (pw->ifindex == ifindex) if (pw->ifindex == ifindex)
return (pw); return (pw);
@ -176,15 +192,13 @@ struct l2vpn_pw *
l2vpn_pw_find_name(struct l2vpn *l2vpn, const char *ifname) l2vpn_pw_find_name(struct l2vpn *l2vpn, const char *ifname)
{ {
struct l2vpn_pw *pw; struct l2vpn_pw *pw;
struct l2vpn_pw s;
LIST_FOREACH(pw, &l2vpn->pw_list, entry) strlcpy(s.ifname, ifname, sizeof(s.ifname));
if (strcmp(pw->ifname, ifname) == 0) pw = RB_FIND(l2vpn_pw_head, &l2vpn->pw_tree, &s);
return (pw); if (pw)
LIST_FOREACH(pw, &l2vpn->pw_inactive_list, entry) return (pw);
if (strcmp(pw->ifname, ifname) == 0) return (RB_FIND(l2vpn_pw_head, &l2vpn->pw_inactive_tree, &s));
return (pw);
return (NULL);
} }
void void
@ -399,8 +413,8 @@ 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) { RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree) {
if (af != pw->af || ldp_addrcmp(af, &pw->addr, addr)) if (af != pw->af || ldp_addrcmp(af, &pw->addr, addr))
continue; continue;
@ -428,8 +442,8 @@ 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) { RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree) {
memset(&pwctl, 0, sizeof(pwctl)); memset(&pwctl, 0, sizeof(pwctl));
strlcpy(pwctl.l2vpn_name, pw->l2vpn->name, strlcpy(pwctl.l2vpn_name, pw->l2vpn->name,
sizeof(pwctl.l2vpn_name)); sizeof(pwctl.l2vpn_name));
@ -459,7 +473,7 @@ l2vpn_binding_ctl(pid_t pid)
fn = (struct fec_node *)f; fn = (struct fec_node *)f;
if (fn->local_label == NO_LABEL && if (fn->local_label == NO_LABEL &&
LIST_EMPTY(&fn->downstream)) RB_EMPTY(&fn->downstream))
continue; continue;
memset(&pwctl, 0, sizeof(pwctl)); memset(&pwctl, 0, sizeof(pwctl));
@ -477,7 +491,7 @@ l2vpn_binding_ctl(pid_t pid)
} else } else
pwctl.local_label = NO_LABEL; pwctl.local_label = NO_LABEL;
LIST_FOREACH(me, &fn->downstream, entry) RB_FOREACH(me, lde_map_head, &fn->downstream)
if (f->u.pwid.lsr_id.s_addr == me->nexthop->id.s_addr) if (f->u.pwid.lsr_id.s_addr == me->nexthop->id.s_addr)
break; break;
@ -508,7 +522,7 @@ ldpe_l2vpn_init(struct l2vpn *l2vpn)
{ {
struct l2vpn_pw *pw; struct l2vpn_pw *pw;
LIST_FOREACH(pw, &l2vpn->pw_list, entry) RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree)
ldpe_l2vpn_pw_init(pw); ldpe_l2vpn_pw_init(pw);
} }
@ -517,7 +531,7 @@ ldpe_l2vpn_exit(struct l2vpn *l2vpn)
{ {
struct l2vpn_pw *pw; struct l2vpn_pw *pw;
LIST_FOREACH(pw, &l2vpn->pw_list, entry) RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree)
ldpe_l2vpn_pw_exit(pw); ldpe_l2vpn_pw_exit(pw);
} }
@ -530,7 +544,7 @@ ldpe_l2vpn_pw_init(struct l2vpn_pw *pw)
if (tnbr == NULL) { if (tnbr == NULL) {
tnbr = tnbr_new(pw->af, &pw->addr); tnbr = tnbr_new(pw->af, &pw->addr);
tnbr_update(tnbr); tnbr_update(tnbr);
LIST_INSERT_HEAD(&leconf->tnbr_list, tnbr, entry); RB_INSERT(tnbr_head, &leconf->tnbr_tree, tnbr);
} }
tnbr->pw_count++; tnbr->pw_count++;
@ -544,6 +558,6 @@ ldpe_l2vpn_pw_exit(struct l2vpn_pw *pw)
tnbr = tnbr_find(leconf, pw->af, &pw->addr); tnbr = tnbr_find(leconf, pw->af, &pw->addr);
if (tnbr) { if (tnbr) {
tnbr->pw_count--; tnbr->pw_count--;
tnbr_check(tnbr); tnbr_check(leconf, tnbr);
} }
} }

View file

@ -45,12 +45,14 @@ static struct lde_nbr *lde_nbr_find(uint32_t);
static void lde_nbr_clear(void); static void lde_nbr_clear(void);
static void lde_nbr_addr_update(struct lde_nbr *, static void lde_nbr_addr_update(struct lde_nbr *,
struct lde_addr *, int); struct lde_addr *, int);
static __inline int lde_map_compare(struct lde_map *, struct lde_map *);
static void lde_map_free(void *); static void lde_map_free(void *);
static int lde_address_add(struct lde_nbr *, struct lde_addr *); static int lde_address_add(struct lde_nbr *, struct lde_addr *);
static int lde_address_del(struct lde_nbr *, struct lde_addr *); static int lde_address_del(struct lde_nbr *, struct lde_addr *);
static void lde_address_list_free(struct lde_nbr *); static void lde_address_list_free(struct lde_nbr *);
RB_GENERATE(nbr_tree, lde_nbr, entry, lde_nbr_compare) RB_GENERATE(nbr_tree, lde_nbr, entry, lde_nbr_compare)
RB_GENERATE(lde_map_head, lde_map, entry, lde_map_compare)
struct ldpd_conf *ldeconf; struct ldpd_conf *ldeconf;
struct nbr_tree lde_nbrs = RB_INITIALIZER(&lde_nbrs); struct nbr_tree lde_nbrs = RB_INITIALIZER(&lde_nbrs);
@ -471,10 +473,10 @@ lde_dispatch_parent(struct thread *thread)
fatal(NULL); fatal(NULL);
memcpy(nconf, imsg.data, sizeof(struct ldpd_conf)); memcpy(nconf, imsg.data, sizeof(struct ldpd_conf));
LIST_INIT(&nconf->iface_list); RB_INIT(&nconf->iface_tree);
LIST_INIT(&nconf->tnbr_list); RB_INIT(&nconf->tnbr_tree);
LIST_INIT(&nconf->nbrp_list); 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)
@ -482,37 +484,37 @@ lde_dispatch_parent(struct thread *thread)
memcpy(niface, imsg.data, sizeof(struct iface)); memcpy(niface, imsg.data, sizeof(struct iface));
LIST_INIT(&niface->addr_list); LIST_INIT(&niface->addr_list);
LIST_INIT(&niface->ipv4.adj_list); RB_INIT(&niface->ipv4.adj_tree);
LIST_INIT(&niface->ipv6.adj_list); RB_INIT(&niface->ipv6.adj_tree);
niface->ipv4.iface = niface; niface->ipv4.iface = niface;
niface->ipv6.iface = niface; niface->ipv6.iface = niface;
LIST_INSERT_HEAD(&nconf->iface_list, niface, entry); RB_INSERT(iface_head, &nconf->iface_tree, niface);
break; break;
case IMSG_RECONF_TNBR: case IMSG_RECONF_TNBR:
if ((ntnbr = malloc(sizeof(struct tnbr))) == NULL) if ((ntnbr = malloc(sizeof(struct tnbr))) == NULL)
fatal(NULL); fatal(NULL);
memcpy(ntnbr, imsg.data, sizeof(struct tnbr)); memcpy(ntnbr, imsg.data, sizeof(struct tnbr));
LIST_INSERT_HEAD(&nconf->tnbr_list, ntnbr, entry); RB_INSERT(tnbr_head, &nconf->tnbr_tree, ntnbr);
break; break;
case IMSG_RECONF_NBRP: case IMSG_RECONF_NBRP:
if ((nnbrp = malloc(sizeof(struct nbr_params))) == NULL) if ((nnbrp = malloc(sizeof(struct nbr_params))) == NULL)
fatal(NULL); fatal(NULL);
memcpy(nnbrp, imsg.data, sizeof(struct nbr_params)); memcpy(nnbrp, imsg.data, sizeof(struct nbr_params));
LIST_INSERT_HEAD(&nconf->nbrp_list, nnbrp, entry); RB_INSERT(nbrp_head, &nconf->nbrp_tree, nnbrp);
break; break;
case IMSG_RECONF_L2VPN: case IMSG_RECONF_L2VPN:
if ((nl2vpn = malloc(sizeof(struct l2vpn))) == NULL) if ((nl2vpn = malloc(sizeof(struct l2vpn))) == NULL)
fatal(NULL); fatal(NULL);
memcpy(nl2vpn, imsg.data, sizeof(struct l2vpn)); memcpy(nl2vpn, imsg.data, sizeof(struct l2vpn));
LIST_INIT(&nl2vpn->if_list); RB_INIT(&nl2vpn->if_tree);
LIST_INIT(&nl2vpn->pw_list); RB_INIT(&nl2vpn->pw_tree);
LIST_INIT(&nl2vpn->pw_inactive_list); RB_INIT(&nl2vpn->pw_inactive_tree);
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)
@ -520,7 +522,7 @@ lde_dispatch_parent(struct thread *thread)
memcpy(nlif, imsg.data, sizeof(struct l2vpn_if)); memcpy(nlif, imsg.data, sizeof(struct l2vpn_if));
nlif->l2vpn = nl2vpn; nlif->l2vpn = nl2vpn;
LIST_INSERT_HEAD(&nl2vpn->if_list, nlif, entry); RB_INSERT(l2vpn_if_head, &nl2vpn->if_tree, nlif);
break; break;
case IMSG_RECONF_L2VPN_PW: case IMSG_RECONF_L2VPN_PW:
if ((npw = malloc(sizeof(struct l2vpn_pw))) == NULL) if ((npw = malloc(sizeof(struct l2vpn_pw))) == NULL)
@ -528,7 +530,7 @@ lde_dispatch_parent(struct thread *thread)
memcpy(npw, imsg.data, sizeof(struct l2vpn_pw)); memcpy(npw, imsg.data, sizeof(struct l2vpn_pw));
npw->l2vpn = nl2vpn; npw->l2vpn = nl2vpn;
LIST_INSERT_HEAD(&nl2vpn->pw_list, npw, entry); RB_INSERT(l2vpn_pw_head, &nl2vpn->pw_tree, npw);
break; break;
case IMSG_RECONF_L2VPN_IPW: case IMSG_RECONF_L2VPN_IPW:
if ((npw = malloc(sizeof(struct l2vpn_pw))) == NULL) if ((npw = malloc(sizeof(struct l2vpn_pw))) == NULL)
@ -536,7 +538,7 @@ lde_dispatch_parent(struct thread *thread)
memcpy(npw, imsg.data, sizeof(struct l2vpn_pw)); memcpy(npw, imsg.data, sizeof(struct l2vpn_pw));
npw->l2vpn = nl2vpn; npw->l2vpn = nl2vpn;
LIST_INSERT_HEAD(&nl2vpn->pw_inactive_list, npw, entry); RB_INSERT(l2vpn_pw_head, &nl2vpn->pw_inactive_tree, npw);
break; break;
case IMSG_RECONF_END: case IMSG_RECONF_END:
merge_config(ldeconf, nconf); merge_config(ldeconf, nconf);
@ -1141,6 +1143,13 @@ lde_nbr_addr_update(struct lde_nbr *ln, struct lde_addr *lde_addr, int removed)
} }
} }
static __inline int
lde_map_compare(struct lde_map *a, struct lde_map *b)
{
return (ldp_addrcmp(AF_INET, (union ldpd_addr *)&a->nexthop->id,
(union ldpd_addr *)&b->nexthop->id));
}
struct lde_map * struct lde_map *
lde_map_add(struct lde_nbr *ln, struct fec_node *fn, int sent) lde_map_add(struct lde_nbr *ln, struct fec_node *fn, int sent)
{ {
@ -1154,13 +1163,15 @@ lde_map_add(struct lde_nbr *ln, struct fec_node *fn, int sent)
me->nexthop = ln; me->nexthop = ln;
if (sent) { if (sent) {
LIST_INSERT_HEAD(&fn->upstream, me, entry); RB_INSERT(lde_map_head, &fn->upstream, me);
me->head = &fn->upstream;
if (fec_insert(&ln->sent_map, &me->fec)) if (fec_insert(&ln->sent_map, &me->fec))
log_warnx("failed to add %s to sent map", log_warnx("failed to add %s to sent map",
log_fec(&me->fec)); log_fec(&me->fec));
/* XXX on failure more cleanup is needed */ /* XXX on failure more cleanup is needed */
} else { } else {
LIST_INSERT_HEAD(&fn->downstream, me, entry); RB_INSERT(lde_map_head, &fn->downstream, me);
me->head = &fn->downstream;
if (fec_insert(&ln->recv_map, &me->fec)) if (fec_insert(&ln->recv_map, &me->fec))
log_warnx("failed to add %s to recv map", log_warnx("failed to add %s to recv map",
log_fec(&me->fec)); log_fec(&me->fec));
@ -1185,7 +1196,7 @@ lde_map_free(void *ptr)
{ {
struct lde_map *map = ptr; struct lde_map *map = ptr;
LIST_REMOVE(map, entry); RB_REMOVE(lde_map_head, map->head, map);
free(map); free(map);
} }

View file

@ -62,10 +62,13 @@ struct lde_req {
/* mapping entries */ /* mapping entries */
struct lde_map { struct lde_map {
struct fec fec; struct fec fec;
LIST_ENTRY(lde_map) entry; struct lde_map_head *head; /* fec_node's upstream/downstream */
RB_ENTRY(lde_map) entry;
struct lde_nbr *nexthop; struct lde_nbr *nexthop;
struct map map; struct map map;
}; };
RB_HEAD(lde_map_head, lde_map);
RB_PROTOTYPE(lde_map_head, lde_map, entry, lde_map_cmp);
/* withdraw entries */ /* withdraw entries */
struct lde_wdraw { struct lde_wdraw {
@ -112,8 +115,8 @@ struct fec_node {
struct fec fec; struct fec fec;
LIST_HEAD(, fec_nh) nexthops; /* fib nexthops */ LIST_HEAD(, fec_nh) nexthops; /* fib nexthops */
LIST_HEAD(, lde_map) downstream; /* recv mappings */ struct lde_map_head downstream; /* recv mappings */
LIST_HEAD(, lde_map) upstream; /* sent mappings */ struct lde_map_head upstream; /* sent mappings */
uint32_t local_label; uint32_t local_label;
void *data; /* fec specific data */ void *data; /* fec specific data */

View file

@ -159,7 +159,7 @@ rt_dump(pid_t pid)
RB_FOREACH(f, fec_tree, &ft) { RB_FOREACH(f, fec_tree, &ft) {
fn = (struct fec_node *)f; fn = (struct fec_node *)f;
if (fn->local_label == NO_LABEL && if (fn->local_label == NO_LABEL &&
LIST_EMPTY(&fn->downstream)) RB_EMPTY(&fn->downstream))
continue; continue;
rtctl.first = 1; rtctl.first = 1;
@ -179,7 +179,7 @@ rt_dump(pid_t pid)
} }
rtctl.local_label = fn->local_label; rtctl.local_label = fn->local_label;
LIST_FOREACH(me, &fn->downstream, entry) { RB_FOREACH(me, lde_map_head, &fn->downstream) {
rtctl.in_use = lde_nbr_is_nexthop(fn, me->nexthop); rtctl.in_use = lde_nbr_is_nexthop(fn, me->nexthop);
rtctl.nexthop = me->nexthop->id; rtctl.nexthop = me->nexthop->id;
rtctl.remote_label = me->map.label; rtctl.remote_label = me->map.label;
@ -188,7 +188,7 @@ rt_dump(pid_t pid)
&rtctl, sizeof(rtctl)); &rtctl, sizeof(rtctl));
rtctl.first = 0; rtctl.first = 0;
} }
if (LIST_EMPTY(&fn->downstream)) { if (RB_EMPTY(&fn->downstream)) {
rtctl.in_use = 0; rtctl.in_use = 0;
rtctl.nexthop.s_addr = INADDR_ANY; rtctl.nexthop.s_addr = INADDR_ANY;
rtctl.remote_label = NO_LABEL; rtctl.remote_label = NO_LABEL;
@ -224,10 +224,10 @@ fec_free(void *arg)
while ((fnh = LIST_FIRST(&fn->nexthops))) while ((fnh = LIST_FIRST(&fn->nexthops)))
fec_nh_del(fnh); fec_nh_del(fnh);
if (!LIST_EMPTY(&fn->downstream)) if (!RB_EMPTY(&fn->downstream))
log_warnx("%s: fec %s downstream list not empty", __func__, log_warnx("%s: fec %s downstream list not empty", __func__,
log_fec(&fn->fec)); log_fec(&fn->fec));
if (!LIST_EMPTY(&fn->upstream)) if (!RB_EMPTY(&fn->upstream))
log_warnx("%s: fec %s upstream list not empty", __func__, log_warnx("%s: fec %s upstream list not empty", __func__,
log_fec(&fn->fec)); log_fec(&fn->fec));
@ -251,8 +251,8 @@ fec_add(struct fec *fec)
fn->fec = *fec; fn->fec = *fec;
fn->local_label = NO_LABEL; fn->local_label = NO_LABEL;
LIST_INIT(&fn->upstream); RB_INIT(&fn->upstream);
LIST_INIT(&fn->downstream); RB_INIT(&fn->downstream);
LIST_INIT(&fn->nexthops); LIST_INIT(&fn->nexthops);
if (fec_insert(&ft, &fn->fec)) if (fec_insert(&ft, &fn->fec))
@ -774,8 +774,8 @@ lde_gc_timer(struct thread *thread)
fn = (struct fec_node *) fec; fn = (struct fec_node *) fec;
if (!LIST_EMPTY(&fn->nexthops) || if (!LIST_EMPTY(&fn->nexthops) ||
!LIST_EMPTY(&fn->downstream) || !RB_EMPTY(&fn->downstream) ||
!LIST_EMPTY(&fn->upstream)) !RB_EMPTY(&fn->upstream))
continue; continue;
fec_remove(&ft, &fn->fec); fec_remove(&ft, &fn->fec);

View file

@ -74,7 +74,7 @@ ldp_vty_debug(struct vty *vty, struct vty_arg *args[])
DEBUG_OFF(event, EVENT); DEBUG_OFF(event, EVENT);
else else
DEBUG_ON(event, EVENT); DEBUG_ON(event, EVENT);
} else if (strcmp(type_str, "messages") == 0) { } else if (strcmp(type_str, "messages") == 0) {
all = (vty_get_arg_value(args, "all")) ? 1 : 0; all = (vty_get_arg_value(args, "all")) ? 1 : 0;
dir_str = vty_get_arg_value(args, "dir"); dir_str = vty_get_arg_value(args, "dir");
if (dir_str == NULL) if (dir_str == NULL)
@ -99,7 +99,7 @@ ldp_vty_debug(struct vty *vty, struct vty_arg *args[])
DEBUG_ON(msg, MSG_SEND_ALL); DEBUG_ON(msg, MSG_SEND_ALL);
} }
} }
} else if (strcmp(type_str, "zebra") == 0) { } else if (strcmp(type_str, "zebra") == 0) {
if (disable) if (disable)
DEBUG_OFF(zebra, ZEBRA); DEBUG_OFF(zebra, ZEBRA);
else else

View file

@ -142,7 +142,7 @@ ldp_af_iface_config_write(struct vty *vty, int af)
struct iface *iface; struct iface *iface;
struct iface_af *ia; struct iface_af *ia;
LIST_FOREACH(iface, &ldpd_conf->iface_list, entry) { RB_FOREACH(iface, iface_head, &ldpd_conf->iface_tree) {
ia = iface_af_get(iface, af); ia = iface_af_get(iface, af);
if (!ia->enabled) if (!ia->enabled)
continue; continue;
@ -213,7 +213,7 @@ ldp_af_config_write(struct vty *vty, int af, struct ldpd_conf *conf,
vty_out(vty, " session holdtime %u%s", af_conf->keepalive, vty_out(vty, " session holdtime %u%s", af_conf->keepalive,
VTY_NEWLINE); VTY_NEWLINE);
LIST_FOREACH(tnbr, &ldpd_conf->tnbr_list, entry) { RB_FOREACH(tnbr, tnbr_head, &ldpd_conf->tnbr_tree) {
if (tnbr->af == af) { if (tnbr->af == af) {
vty_out(vty, " !%s", VTY_NEWLINE); vty_out(vty, " !%s", VTY_NEWLINE);
vty_out(vty, " neighbor %s targeted%s", vty_out(vty, " neighbor %s targeted%s",
@ -265,7 +265,7 @@ ldp_config_write(struct vty *vty)
if (ldpd_conf->flags & F_LDPD_DS_CISCO_INTEROP) if (ldpd_conf->flags & F_LDPD_DS_CISCO_INTEROP)
vty_out(vty, " dual-stack cisco-interop%s", VTY_NEWLINE); vty_out(vty, " dual-stack cisco-interop%s", VTY_NEWLINE);
LIST_FOREACH(nbrp, &ldpd_conf->nbrp_list, entry) { RB_FOREACH(nbrp, nbrp_head, &ldpd_conf->nbrp_tree) {
if (nbrp->flags & F_NBRP_KEEPALIVE) if (nbrp->flags & F_NBRP_KEEPALIVE)
vty_out(vty, " neighbor %s session holdtime %u%s", vty_out(vty, " neighbor %s session holdtime %u%s",
inet_ntoa(nbrp->lsr_id), nbrp->keepalive, inet_ntoa(nbrp->lsr_id), nbrp->keepalive,
@ -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)
@ -354,13 +354,13 @@ ldp_l2vpn_config_write(struct vty *vty)
vty_out(vty, " bridge %s%s", l2vpn->br_ifname, vty_out(vty, " bridge %s%s", l2vpn->br_ifname,
VTY_NEWLINE); VTY_NEWLINE);
LIST_FOREACH(lif, &l2vpn->if_list, entry) RB_FOREACH(lif, l2vpn_if_head, &l2vpn->if_tree)
vty_out(vty, " member interface %s%s", lif->ifname, vty_out(vty, " member interface %s%s", lif->ifname,
VTY_NEWLINE); VTY_NEWLINE);
LIST_FOREACH(pw, &l2vpn->pw_list, entry) RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree)
ldp_l2vpn_pw_config_write(vty, pw); ldp_l2vpn_pw_config_write(vty, pw);
LIST_FOREACH(pw, &l2vpn->pw_inactive_list, entry) RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_inactive_tree)
ldp_l2vpn_pw_config_write(vty, pw); ldp_l2vpn_pw_config_write(vty, pw);
vty_out(vty, " !%s", VTY_NEWLINE); vty_out(vty, " !%s", VTY_NEWLINE);
@ -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))
@ -740,7 +740,7 @@ ldp_vty_nbr_session_holdtime(struct vty *vty, struct vty_arg *args[])
} else { } else {
if (nbrp == NULL) { if (nbrp == NULL) {
nbrp = nbr_params_new(lsr_id); nbrp = nbr_params_new(lsr_id);
LIST_INSERT_HEAD(&vty_conf->nbrp_list, nbrp, entry); RB_INSERT(nbrp_head, &vty_conf->nbrp_tree, nbrp);
} else if (nbrp->keepalive == secs) } else if (nbrp->keepalive == secs)
goto cancel; goto cancel;
@ -857,7 +857,7 @@ ldp_vty_interface(struct vty *vty, struct vty_arg *args[])
ia = iface_af_get(iface, af); ia = iface_af_get(iface, af);
ia->enabled = 1; ia->enabled = 1;
LIST_INSERT_HEAD(&vty_conf->iface_list, iface, entry); RB_INSERT(iface_head, &vty_conf->iface_tree, iface);
ldp_reload_ref(vty_conf, (void **)&iface); ldp_reload_ref(vty_conf, (void **)&iface);
} else { } else {
memset(&kif, 0, sizeof(kif)); memset(&kif, 0, sizeof(kif));
@ -955,7 +955,7 @@ ldp_vty_neighbor_targeted(struct vty *vty, struct vty_arg *args[])
if (tnbr == NULL) if (tnbr == NULL)
goto cancel; goto cancel;
LIST_REMOVE(tnbr, entry); RB_REMOVE(tnbr_head, &vty_conf->tnbr_tree, tnbr);
free(tnbr); free(tnbr);
ldp_reload(vty_conf); ldp_reload(vty_conf);
return (CMD_SUCCESS); return (CMD_SUCCESS);
@ -966,7 +966,7 @@ ldp_vty_neighbor_targeted(struct vty *vty, struct vty_arg *args[])
tnbr = tnbr_new(af, &addr); tnbr = tnbr_new(af, &addr);
tnbr->flags |= F_TNBR_CONFIGURED; tnbr->flags |= F_TNBR_CONFIGURED;
LIST_INSERT_HEAD(&vty_conf->tnbr_list, tnbr, entry); RB_INSERT(tnbr_head, &vty_conf->tnbr_tree, tnbr);
ldp_reload(vty_conf); ldp_reload(vty_conf);
@ -1129,7 +1129,7 @@ ldp_vty_neighbor_password(struct vty *vty, struct vty_arg *args[])
} else { } else {
if (nbrp == NULL) { if (nbrp == NULL) {
nbrp = nbr_params_new(lsr_id); nbrp = nbr_params_new(lsr_id);
LIST_INSERT_HEAD(&vty_conf->nbrp_list, nbrp, entry); RB_INSERT(nbrp_head, &vty_conf->nbrp_tree, nbrp);
} else if (nbrp->auth.method == AUTH_MD5SIG && } else if (nbrp->auth.method == AUTH_MD5SIG &&
strcmp(nbrp->auth.md5key, password_str) == 0) strcmp(nbrp->auth.md5key, password_str) == 0)
goto cancel; goto cancel;
@ -1195,7 +1195,7 @@ ldp_vty_neighbor_ttl_security(struct vty *vty, struct vty_arg *args[])
} else { } else {
if (nbrp == NULL) { if (nbrp == NULL) {
nbrp = nbr_params_new(lsr_id); nbrp = nbr_params_new(lsr_id);
LIST_INSERT_HEAD(&vty_conf->nbrp_list, nbrp, entry); RB_INSERT(nbrp_head, &vty_conf->nbrp_tree, nbrp);
} }
nbrp->flags |= F_NBRP_GTSM; nbrp->flags |= F_NBRP_GTSM;
@ -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_ref(vty_conf, (void **)&l2vpn); ldp_reload_ref(vty_conf, (void **)&l2vpn);
VTY_PUSH_CONTEXT(LDP_L2VPN_NODE, l2vpn); VTY_PUSH_CONTEXT(LDP_L2VPN_NODE, l2vpn);
@ -1369,7 +1369,7 @@ ldp_vty_l2vpn_interface(struct vty *vty, struct vty_arg *args[])
if (lif == NULL) if (lif == NULL)
goto cancel; goto cancel;
LIST_REMOVE(lif, entry); RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif);
free(lif); free(lif);
ldp_reload(vty_conf); ldp_reload(vty_conf);
return (CMD_SUCCESS); return (CMD_SUCCESS);
@ -1392,7 +1392,7 @@ ldp_vty_l2vpn_interface(struct vty *vty, struct vty_arg *args[])
} }
lif = l2vpn_if_new(l2vpn, &kif); lif = l2vpn_if_new(l2vpn, &kif);
LIST_INSERT_HEAD(&l2vpn->if_list, lif, entry); RB_INSERT(l2vpn_if_head, &l2vpn->if_tree, lif);
ldp_reload_ref(vty_conf, (void **)&l2vpn); ldp_reload_ref(vty_conf, (void **)&l2vpn);
@ -1425,7 +1425,7 @@ ldp_vty_l2vpn_pseudowire(struct vty *vty, struct vty_arg *args[])
if (pw == NULL) if (pw == NULL)
goto cancel; goto cancel;
LIST_REMOVE(pw, entry); RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
free(pw); free(pw);
ldp_reload(vty_conf); ldp_reload(vty_conf);
return (CMD_SUCCESS); return (CMD_SUCCESS);
@ -1451,7 +1451,7 @@ ldp_vty_l2vpn_pseudowire(struct vty *vty, struct vty_arg *args[])
pw = l2vpn_pw_new(l2vpn, &kif); pw = l2vpn_pw_new(l2vpn, &kif);
pw->flags = F_PW_STATUSTLV_CONF|F_PW_CWORD_CONF; pw->flags = F_PW_STATUSTLV_CONF|F_PW_CWORD_CONF;
LIST_INSERT_HEAD(&l2vpn->pw_inactive_list, pw, entry); RB_INSERT(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
ldp_reload_ref(vty_conf, (void **)&pw); ldp_reload_ref(vty_conf, (void **)&pw);
VTY_PUSH_CONTEXT_SUB(LDP_PSEUDOWIRE_NODE, pw); VTY_PUSH_CONTEXT_SUB(LDP_PSEUDOWIRE_NODE, pw);
@ -1641,14 +1641,14 @@ iface_new_api(struct ldpd_conf *conf, const char *name)
} }
iface = if_new(&kif); iface = if_new(&kif);
LIST_INSERT_HEAD(&conf->iface_list, iface, entry); RB_INSERT(iface_head, &conf->iface_tree, iface);
return (iface); return (iface);
} }
void void
iface_del_api(struct iface *iface) iface_del_api(struct ldpd_conf *conf, struct iface *iface)
{ {
LIST_REMOVE(iface, entry); RB_REMOVE(iface_head, &conf->iface_tree, iface);
free(iface); free(iface);
} }
@ -1665,14 +1665,14 @@ tnbr_new_api(struct ldpd_conf *conf, int af, union ldpd_addr *addr)
tnbr = tnbr_new(af, addr); tnbr = tnbr_new(af, addr);
tnbr->flags |= F_TNBR_CONFIGURED; tnbr->flags |= F_TNBR_CONFIGURED;
LIST_INSERT_HEAD(&conf->tnbr_list, tnbr, entry); RB_INSERT(tnbr_head, &conf->tnbr_tree, tnbr);
return (tnbr); return (tnbr);
} }
void void
tnbr_del_api(struct tnbr *tnbr) tnbr_del_api(struct ldpd_conf *conf, struct tnbr *tnbr)
{ {
LIST_REMOVE(tnbr, entry); RB_REMOVE(tnbr_head, &conf->tnbr_tree, tnbr);
free(tnbr); free(tnbr);
} }
@ -1685,14 +1685,14 @@ nbrp_new_api(struct ldpd_conf *conf, struct in_addr lsr_id)
return (NULL); return (NULL);
nbrp = nbr_params_new(lsr_id); nbrp = nbr_params_new(lsr_id);
LIST_INSERT_HEAD(&conf->nbrp_list, nbrp, entry); RB_INSERT(nbrp_head, &conf->nbrp_tree, nbrp);
return (nbrp); return (nbrp);
} }
void void
nbrp_del_api(struct nbr_params *nbrp) nbrp_del_api(struct ldpd_conf *conf, struct nbr_params *nbrp)
{ {
LIST_REMOVE(nbrp, entry); RB_REMOVE(nbrp_head, &conf->nbrp_tree, nbrp);
free(nbrp); free(nbrp);
} }
@ -1706,29 +1706,29 @@ 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;
while ((lif = LIST_FIRST(&l2vpn->if_list)) != NULL) { while ((lif = RB_ROOT(&l2vpn->if_tree)) != NULL) {
LIST_REMOVE(lif, entry); RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif);
free(lif); free(lif);
} }
while ((pw = LIST_FIRST(&l2vpn->pw_list)) != NULL) { while ((pw = RB_ROOT(&l2vpn->pw_tree)) != NULL) {
LIST_REMOVE(pw, entry); RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_tree, pw);
free(pw); free(pw);
} }
while ((pw = LIST_FIRST(&l2vpn->pw_inactive_list)) != NULL) { while ((pw = RB_ROOT(&l2vpn->pw_inactive_tree)) != NULL) {
LIST_REMOVE(pw, entry); RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
free(pw); free(pw);
} }
LIST_REMOVE(l2vpn, entry); RB_REMOVE(l2vpn_head, &conf->l2vpn_tree, l2vpn);
free(l2vpn); free(l2vpn);
} }
@ -1752,14 +1752,14 @@ l2vpn_if_new_api(struct ldpd_conf *conf, struct l2vpn *l2vpn,
} }
lif = l2vpn_if_new(l2vpn, &kif); lif = l2vpn_if_new(l2vpn, &kif);
LIST_INSERT_HEAD(&l2vpn->if_list, lif, entry); RB_INSERT(l2vpn_if_head, &l2vpn->if_tree, lif);
return (lif); return (lif);
} }
void void
l2vpn_if_del_api(struct l2vpn_if *lif) l2vpn_if_del_api(struct l2vpn *l2vpn, struct l2vpn_if *lif)
{ {
LIST_REMOVE(lif, entry); RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif);
free(lif); free(lif);
} }
@ -1784,13 +1784,13 @@ l2vpn_pw_new_api(struct ldpd_conf *conf, struct l2vpn *l2vpn,
pw = l2vpn_pw_new(l2vpn, &kif); pw = l2vpn_pw_new(l2vpn, &kif);
pw->flags = F_PW_STATUSTLV_CONF|F_PW_CWORD_CONF; pw->flags = F_PW_STATUSTLV_CONF|F_PW_CWORD_CONF;
LIST_INSERT_HEAD(&l2vpn->pw_inactive_list, pw, entry); RB_INSERT(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
return (pw); return (pw);
} }
void void
l2vpn_pw_del_api(struct l2vpn_pw *pw) l2vpn_pw_del_api(struct l2vpn *l2vpn, struct l2vpn_pw *pw)
{ {
LIST_REMOVE(pw, entry); RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
free(pw); free(pw);
} }

View file

@ -850,40 +850,40 @@ main_imsg_send_config(struct ldpd_conf *xconf)
sizeof(*xconf)) == -1) sizeof(*xconf)) == -1)
return (-1); return (-1);
LIST_FOREACH(iface, &xconf->iface_list, entry) { RB_FOREACH(iface, iface_head, &xconf->iface_tree) {
if (main_imsg_compose_both(IMSG_RECONF_IFACE, iface, if (main_imsg_compose_both(IMSG_RECONF_IFACE, iface,
sizeof(*iface)) == -1) sizeof(*iface)) == -1)
return (-1); return (-1);
} }
LIST_FOREACH(tnbr, &xconf->tnbr_list, entry) { RB_FOREACH(tnbr, tnbr_head, &xconf->tnbr_tree) {
if (main_imsg_compose_both(IMSG_RECONF_TNBR, tnbr, if (main_imsg_compose_both(IMSG_RECONF_TNBR, tnbr,
sizeof(*tnbr)) == -1) sizeof(*tnbr)) == -1)
return (-1); return (-1);
} }
LIST_FOREACH(nbrp, &xconf->nbrp_list, entry) { RB_FOREACH(nbrp, nbrp_head, &xconf->nbrp_tree) {
if (main_imsg_compose_both(IMSG_RECONF_NBRP, nbrp, if (main_imsg_compose_both(IMSG_RECONF_NBRP, nbrp,
sizeof(*nbrp)) == -1) sizeof(*nbrp)) == -1)
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);
LIST_FOREACH(lif, &l2vpn->if_list, entry) { RB_FOREACH(lif, l2vpn_if_head, &l2vpn->if_tree) {
if (main_imsg_compose_both(IMSG_RECONF_L2VPN_IF, lif, if (main_imsg_compose_both(IMSG_RECONF_L2VPN_IF, lif,
sizeof(*lif)) == -1) sizeof(*lif)) == -1)
return (-1); return (-1);
} }
LIST_FOREACH(pw, &l2vpn->pw_list, entry) { RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree) {
if (main_imsg_compose_both(IMSG_RECONF_L2VPN_PW, pw, if (main_imsg_compose_both(IMSG_RECONF_L2VPN_PW, pw,
sizeof(*pw)) == -1) sizeof(*pw)) == -1)
return (-1); return (-1);
} }
LIST_FOREACH(pw, &l2vpn->pw_inactive_list, entry) { RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_inactive_tree) {
if (main_imsg_compose_both(IMSG_RECONF_L2VPN_IPW, pw, if (main_imsg_compose_both(IMSG_RECONF_L2VPN_IPW, pw,
sizeof(*pw)) == -1) sizeof(*pw)) == -1)
return (-1); return (-1);
@ -930,15 +930,15 @@ 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) { RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree) {
if (pw->flags & F_PW_STATIC_NBR_ADDR) if (pw->flags & F_PW_STATIC_NBR_ADDR)
continue; continue;
pw->af = AF_INET; pw->af = AF_INET;
pw->addr.v4 = pw->lsr_id; pw->addr.v4 = pw->lsr_id;
} }
LIST_FOREACH(pw, &l2vpn->pw_inactive_list, entry) { RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_inactive_tree) {
if (pw->flags & F_PW_STATIC_NBR_ADDR) if (pw->flags & F_PW_STATIC_NBR_ADDR)
continue; continue;
@ -954,17 +954,17 @@ ldp_config_reset_main(struct ldpd_conf *conf, void **ref)
struct iface *iface; struct iface *iface;
struct nbr_params *nbrp; struct nbr_params *nbrp;
while ((iface = LIST_FIRST(&conf->iface_list)) != NULL) { while ((iface = RB_ROOT(&conf->iface_tree)) != NULL) {
if (ref && *ref == iface) if (ref && *ref == iface)
*ref = NULL; *ref = NULL;
LIST_REMOVE(iface, entry); RB_REMOVE(iface_head, &conf->iface_tree, iface);
free(iface); free(iface);
} }
while ((nbrp = LIST_FIRST(&conf->nbrp_list)) != NULL) { while ((nbrp = RB_ROOT(&conf->nbrp_tree)) != NULL) {
if (ref && *ref == nbrp) if (ref && *ref == nbrp)
*ref = NULL; *ref = NULL;
LIST_REMOVE(nbrp, entry); RB_REMOVE(nbrp_head, &conf->nbrp_tree, nbrp);
free(nbrp); free(nbrp);
} }
@ -987,18 +987,18 @@ ldp_config_reset_af(struct ldpd_conf *conf, int af, void **ref)
struct iface_af *ia; struct iface_af *ia;
struct tnbr *tnbr, *ttmp; struct tnbr *tnbr, *ttmp;
LIST_FOREACH(iface, &conf->iface_list, entry) { RB_FOREACH(iface, iface_head, &conf->iface_tree) {
ia = iface_af_get(iface, af); ia = iface_af_get(iface, af);
ia->enabled = 0; ia->enabled = 0;
} }
LIST_FOREACH_SAFE(tnbr, &conf->tnbr_list, entry, ttmp) { RB_FOREACH_SAFE(tnbr, tnbr_head, &conf->tnbr_tree, ttmp) {
if (tnbr->af != af) if (tnbr->af != af)
continue; continue;
if (ref && *ref == tnbr) if (ref && *ref == tnbr)
*ref = NULL; *ref = NULL;
LIST_REMOVE(tnbr, entry); RB_REMOVE(tnbr_head, &conf->tnbr_tree, tnbr);
free(tnbr); free(tnbr);
} }
@ -1032,46 +1032,46 @@ ldp_dup_config_ref(struct ldpd_conf *conf, void **ref)
} while (0) } while (0)
COPY(xconf, conf); COPY(xconf, conf);
LIST_INIT(&xconf->iface_list); RB_INIT(&xconf->iface_tree);
LIST_INIT(&xconf->tnbr_list); RB_INIT(&xconf->tnbr_tree);
LIST_INIT(&xconf->nbrp_list); RB_INIT(&xconf->nbrp_tree);
LIST_INIT(&xconf->l2vpn_list); RB_INIT(&xconf->l2vpn_tree);
LIST_FOREACH(iface, &conf->iface_list, entry) { RB_FOREACH(iface, iface_head, &conf->iface_tree) {
COPY(xi, iface); COPY(xi, iface);
xi->ipv4.iface = xi; xi->ipv4.iface = xi;
xi->ipv6.iface = xi; xi->ipv6.iface = xi;
LIST_INSERT_HEAD(&xconf->iface_list, xi, entry); RB_INSERT(iface_head, &xconf->iface_tree, xi);
} }
LIST_FOREACH(tnbr, &conf->tnbr_list, entry) { RB_FOREACH(tnbr, tnbr_head, &conf->tnbr_tree) {
COPY(xt, tnbr); COPY(xt, tnbr);
LIST_INSERT_HEAD(&xconf->tnbr_list, xt, entry); RB_INSERT(tnbr_head, &xconf->tnbr_tree, xt);
} }
LIST_FOREACH(nbrp, &conf->nbrp_list, entry) { RB_FOREACH(nbrp, nbrp_head, &conf->nbrp_tree) {
COPY(xn, nbrp); COPY(xn, nbrp);
LIST_INSERT_HEAD(&xconf->nbrp_list, xn, entry); 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); RB_INIT(&xl->if_tree);
LIST_INIT(&xl->pw_list); RB_INIT(&xl->pw_tree);
LIST_INIT(&xl->pw_inactive_list); RB_INIT(&xl->pw_inactive_tree);
LIST_INSERT_HEAD(&xconf->l2vpn_list, xl, entry); RB_INSERT(l2vpn_head, &xconf->l2vpn_tree, xl);
LIST_FOREACH(lif, &l2vpn->if_list, entry) { RB_FOREACH(lif, l2vpn_if_head, &l2vpn->if_tree) {
COPY(xf, lif); COPY(xf, lif);
xf->l2vpn = xl; xf->l2vpn = xl;
LIST_INSERT_HEAD(&xl->if_list, xf, entry); RB_INSERT(l2vpn_if_head, &xl->if_tree, xf);
} }
LIST_FOREACH(pw, &l2vpn->pw_list, entry) { RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree) {
COPY(xp, pw); COPY(xp, pw);
xp->l2vpn = xl; xp->l2vpn = xl;
LIST_INSERT_HEAD(&xl->pw_list, xp, entry); RB_INSERT(l2vpn_pw_head, &xl->pw_tree, xp);
} }
LIST_FOREACH(pw, &l2vpn->pw_inactive_list, entry) { RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_inactive_tree) {
COPY(xp, pw); COPY(xp, pw);
xp->l2vpn = xl; xp->l2vpn = xl;
LIST_INSERT_HEAD(&xl->pw_inactive_list, xp, entry); RB_INSERT(l2vpn_pw_head, &xl->pw_inactive_tree, xp);
} }
} }
#undef COPY #undef COPY
@ -1093,20 +1093,20 @@ ldp_clear_config(struct ldpd_conf *xconf)
struct nbr_params *nbrp; struct nbr_params *nbrp;
struct l2vpn *l2vpn; struct l2vpn *l2vpn;
while ((iface = LIST_FIRST(&xconf->iface_list)) != NULL) { while ((iface = RB_ROOT(&xconf->iface_tree)) != NULL) {
LIST_REMOVE(iface, entry); RB_REMOVE(iface_head, &xconf->iface_tree, iface);
free(iface); free(iface);
} }
while ((tnbr = LIST_FIRST(&xconf->tnbr_list)) != NULL) { while ((tnbr = RB_ROOT(&xconf->tnbr_tree)) != NULL) {
LIST_REMOVE(tnbr, entry); RB_REMOVE(tnbr_head, &xconf->tnbr_tree, tnbr);
free(tnbr); free(tnbr);
} }
while ((nbrp = LIST_FIRST(&xconf->nbrp_list)) != NULL) { while ((nbrp = RB_ROOT(&xconf->nbrp_tree)) != NULL) {
LIST_REMOVE(nbrp, entry); 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);
} }
@ -1236,10 +1236,10 @@ merge_ifaces(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
{ {
struct iface *iface, *itmp, *xi; struct iface *iface, *itmp, *xi;
LIST_FOREACH_SAFE(iface, &conf->iface_list, entry, itmp) { RB_FOREACH_SAFE(iface, iface_head, &conf->iface_tree, itmp) {
/* find deleted interfaces */ /* find deleted interfaces */
if ((xi = if_lookup_name(xconf, iface->name)) == NULL) { if ((xi = if_lookup_name(xconf, iface->name)) == NULL) {
LIST_REMOVE(iface, entry); RB_REMOVE(iface_head, &conf->iface_tree, iface);
switch (ldpd_process) { switch (ldpd_process) {
case PROC_LDE_ENGINE: case PROC_LDE_ENGINE:
@ -1254,11 +1254,11 @@ merge_ifaces(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
free(iface); free(iface);
} }
} }
LIST_FOREACH_SAFE(xi, &xconf->iface_list, entry, itmp) { RB_FOREACH_SAFE(xi, iface_head, &xconf->iface_tree, itmp) {
/* find new interfaces */ /* find new interfaces */
if ((iface = if_lookup_name(conf, xi->name)) == NULL) { if ((iface = if_lookup_name(conf, xi->name)) == NULL) {
LIST_REMOVE(xi, entry); RB_REMOVE(iface_head, &xconf->iface_tree, xi);
LIST_INSERT_HEAD(&conf->iface_list, xi, entry); RB_INSERT(iface_head, &conf->iface_tree, xi);
if (ldpd_process == PROC_MAIN) { if (ldpd_process == PROC_MAIN) {
QOBJ_REG (xi, iface); QOBJ_REG (xi, iface);
@ -1271,7 +1271,7 @@ merge_ifaces(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
/* update existing interfaces */ /* update existing interfaces */
merge_iface_af(&iface->ipv4, &xi->ipv4); merge_iface_af(&iface->ipv4, &xi->ipv4);
merge_iface_af(&iface->ipv6, &xi->ipv6); merge_iface_af(&iface->ipv6, &xi->ipv6);
LIST_REMOVE(xi, entry); RB_REMOVE(iface_head, &xconf->iface_tree, xi);
if (ref && *ref == xi) if (ref && *ref == xi)
*ref = iface; *ref = iface;
free(xi); free(xi);
@ -1295,7 +1295,7 @@ merge_tnbrs(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
{ {
struct tnbr *tnbr, *ttmp, *xt; struct tnbr *tnbr, *ttmp, *xt;
LIST_FOREACH_SAFE(tnbr, &conf->tnbr_list, entry, ttmp) { RB_FOREACH_SAFE(tnbr, tnbr_head, &conf->tnbr_tree, ttmp) {
if (!(tnbr->flags & F_TNBR_CONFIGURED)) if (!(tnbr->flags & F_TNBR_CONFIGURED))
continue; continue;
@ -1303,26 +1303,26 @@ merge_tnbrs(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
if ((xt = tnbr_find(xconf, tnbr->af, &tnbr->addr)) == NULL) { if ((xt = tnbr_find(xconf, tnbr->af, &tnbr->addr)) == NULL) {
switch (ldpd_process) { switch (ldpd_process) {
case PROC_LDE_ENGINE: case PROC_LDE_ENGINE:
LIST_REMOVE(tnbr, entry); RB_REMOVE(tnbr_head, &conf->tnbr_tree, tnbr);
free(tnbr); free(tnbr);
break; break;
case PROC_LDP_ENGINE: case PROC_LDP_ENGINE:
tnbr->flags &= ~F_TNBR_CONFIGURED; tnbr->flags &= ~F_TNBR_CONFIGURED;
tnbr_check(tnbr); tnbr_check(conf, tnbr);
break; break;
case PROC_MAIN: case PROC_MAIN:
LIST_REMOVE(tnbr, entry); RB_REMOVE(tnbr_head, &conf->tnbr_tree, tnbr);
QOBJ_UNREG (tnbr); QOBJ_UNREG (tnbr);
free(tnbr); free(tnbr);
break; break;
} }
} }
} }
LIST_FOREACH_SAFE(xt, &xconf->tnbr_list, entry, ttmp) { RB_FOREACH_SAFE(xt, tnbr_head, &xconf->tnbr_tree, ttmp) {
/* find new tnbrs */ /* find new tnbrs */
if ((tnbr = tnbr_find(conf, xt->af, &xt->addr)) == NULL) { if ((tnbr = tnbr_find(conf, xt->af, &xt->addr)) == NULL) {
LIST_REMOVE(xt, entry); RB_REMOVE(tnbr_head, &xconf->tnbr_tree, xt);
LIST_INSERT_HEAD(&conf->tnbr_list, xt, entry); RB_INSERT(tnbr_head, &conf->tnbr_tree, xt);
switch (ldpd_process) { switch (ldpd_process) {
case PROC_LDE_ENGINE: case PROC_LDE_ENGINE:
@ -1340,7 +1340,7 @@ merge_tnbrs(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
/* update existing tnbrs */ /* update existing tnbrs */
if (!(tnbr->flags & F_TNBR_CONFIGURED)) if (!(tnbr->flags & F_TNBR_CONFIGURED))
tnbr->flags |= F_TNBR_CONFIGURED; tnbr->flags |= F_TNBR_CONFIGURED;
LIST_REMOVE(xt, entry); RB_REMOVE(tnbr_head, &xconf->tnbr_tree, xt);
if (ref && *ref == xt) if (ref && *ref == xt)
*ref = tnbr; *ref = tnbr;
free(xt); free(xt);
@ -1354,7 +1354,7 @@ merge_nbrps(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
struct nbr *nbr; struct nbr *nbr;
int nbrp_changed; int nbrp_changed;
LIST_FOREACH_SAFE(nbrp, &conf->nbrp_list, entry, ntmp) { RB_FOREACH_SAFE(nbrp, nbrp_head, &conf->nbrp_tree, ntmp) {
/* find deleted nbrps */ /* find deleted nbrps */
if ((xn = nbr_params_find(xconf, nbrp->lsr_id)) == NULL) { if ((xn = nbr_params_find(xconf, nbrp->lsr_id)) == NULL) {
switch (ldpd_process) { switch (ldpd_process) {
@ -1380,15 +1380,15 @@ merge_nbrps(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
QOBJ_UNREG (nbrp); QOBJ_UNREG (nbrp);
break; break;
} }
LIST_REMOVE(nbrp, entry); RB_REMOVE(nbrp_head, &conf->nbrp_tree, nbrp);
free(nbrp); free(nbrp);
} }
} }
LIST_FOREACH_SAFE(xn, &xconf->nbrp_list, entry, ntmp) { RB_FOREACH_SAFE(xn, nbrp_head, &xconf->nbrp_tree, ntmp) {
/* find new nbrps */ /* find new nbrps */
if ((nbrp = nbr_params_find(conf, xn->lsr_id)) == NULL) { if ((nbrp = nbr_params_find(conf, xn->lsr_id)) == NULL) {
LIST_REMOVE(xn, entry); RB_REMOVE(nbrp_head, &xconf->nbrp_tree, xn);
LIST_INSERT_HEAD(&conf->nbrp_list, xn, entry); RB_INSERT(nbrp_head, &conf->nbrp_tree, xn);
switch (ldpd_process) { switch (ldpd_process) {
case PROC_LDE_ENGINE: case PROC_LDE_ENGINE:
@ -1455,7 +1455,7 @@ merge_nbrps(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
nbr_establish_connection(nbr); nbr_establish_connection(nbr);
} }
} }
LIST_REMOVE(xn, entry); RB_REMOVE(nbrp_head, &xconf->nbrp_tree, xn);
if (ref && *ref == xn) if (ref && *ref == xn)
*ref = nbrp; *ref = nbrp;
free(xn); free(xn);
@ -1469,10 +1469,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:
@ -1482,11 +1482,11 @@ merge_l2vpns(struct ldpd_conf *conf, struct ldpd_conf *xconf, void **ref)
ldpe_l2vpn_exit(l2vpn); ldpe_l2vpn_exit(l2vpn);
break; break;
case PROC_MAIN: case PROC_MAIN:
LIST_FOREACH(lif, &l2vpn->if_list, entry) RB_FOREACH(lif, l2vpn_if_head, &l2vpn->if_tree)
QOBJ_UNREG (lif); QOBJ_UNREG (lif);
LIST_FOREACH(pw, &l2vpn->pw_list, entry) RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree)
QOBJ_UNREG (pw); QOBJ_UNREG (pw);
LIST_FOREACH(pw, &l2vpn->pw_inactive_list, entry) RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_inactive_tree)
QOBJ_UNREG (pw); QOBJ_UNREG (pw);
QOBJ_UNREG (l2vpn); QOBJ_UNREG (l2vpn);
break; break;
@ -1494,11 +1494,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:
@ -1516,7 +1516,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);
@ -1530,42 +1530,42 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl, void
struct l2vpn_pw *pw, *ptmp, *xp; struct l2vpn_pw *pw, *ptmp, *xp;
struct nbr *nbr; struct nbr *nbr;
int reset_nbr, reinstall_pwfec, reinstall_tnbr; int reset_nbr, reinstall_pwfec, reinstall_tnbr;
LIST_HEAD(, l2vpn_pw) pw_aux_list; struct l2vpn_pw_head pw_aux_list;
int previous_pw_type, previous_mtu; int previous_pw_type, previous_mtu;
previous_pw_type = l2vpn->pw_type; previous_pw_type = l2vpn->pw_type;
previous_mtu = l2vpn->mtu; previous_mtu = l2vpn->mtu;
/* merge intefaces */ /* merge intefaces */
LIST_FOREACH_SAFE(lif, &l2vpn->if_list, entry, ftmp) { RB_FOREACH_SAFE(lif, l2vpn_if_head, &l2vpn->if_tree, ftmp) {
/* find deleted interfaces */ /* find deleted interfaces */
if ((xf = l2vpn_if_find_name(xl, lif->ifname)) == NULL) { if ((xf = l2vpn_if_find_name(xl, lif->ifname)) == NULL) {
if (ldpd_process == PROC_MAIN) if (ldpd_process == PROC_MAIN)
QOBJ_UNREG (lif); QOBJ_UNREG (lif);
LIST_REMOVE(lif, entry); RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif);
free(lif); free(lif);
} }
} }
LIST_FOREACH_SAFE(xf, &xl->if_list, entry, ftmp) { RB_FOREACH_SAFE(xf, l2vpn_if_head, &xl->if_tree, ftmp) {
/* find new interfaces */ /* find new interfaces */
if ((lif = l2vpn_if_find_name(l2vpn, xf->ifname)) == NULL) { if ((lif = l2vpn_if_find_name(l2vpn, xf->ifname)) == NULL) {
LIST_REMOVE(xf, entry); RB_REMOVE(l2vpn_if_head, &xl->if_tree, xf);
LIST_INSERT_HEAD(&l2vpn->if_list, xf, entry); RB_INSERT(l2vpn_if_head, &l2vpn->if_tree, xf);
xf->l2vpn = l2vpn; xf->l2vpn = l2vpn;
if (ldpd_process == PROC_MAIN) if (ldpd_process == PROC_MAIN)
QOBJ_REG (xf, l2vpn_if); QOBJ_REG (xf, l2vpn_if);
continue; continue;
} }
LIST_REMOVE(xf, entry); RB_REMOVE(l2vpn_if_head, &xl->if_tree, xf);
if (ref && *ref == xf) if (ref && *ref == xf)
*ref = lif; *ref = lif;
free(xf); free(xf);
} }
/* merge active pseudowires */ /* merge active pseudowires */
LIST_INIT(&pw_aux_list); RB_INIT(&pw_aux_list);
LIST_FOREACH_SAFE(pw, &l2vpn->pw_list, entry, ptmp) { RB_FOREACH_SAFE(pw, l2vpn_pw_head, &l2vpn->pw_tree, ptmp) {
/* find deleted active pseudowires */ /* find deleted active pseudowires */
if ((xp = l2vpn_pw_find_name(xl, pw->ifname)) == NULL) { if ((xp = l2vpn_pw_find_name(xl, pw->ifname)) == NULL) {
switch (ldpd_process) { switch (ldpd_process) {
@ -1580,15 +1580,15 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl, void
break; break;
} }
LIST_REMOVE(pw, entry); RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_tree, pw);
free(pw); free(pw);
} }
} }
LIST_FOREACH_SAFE(xp, &xl->pw_list, entry, ptmp) { RB_FOREACH_SAFE(xp, l2vpn_pw_head, &xl->pw_tree, ptmp) {
/* find new active pseudowires */ /* find new active pseudowires */
if ((pw = l2vpn_pw_find_name(l2vpn, xp->ifname)) == NULL) { if ((pw = l2vpn_pw_find_name(l2vpn, xp->ifname)) == NULL) {
LIST_REMOVE(xp, entry); RB_REMOVE(l2vpn_pw_head, &xl->pw_tree, xp);
LIST_INSERT_HEAD(&l2vpn->pw_list, xp, entry); RB_INSERT(l2vpn_pw_head, &l2vpn->pw_tree, xp);
xp->l2vpn = l2vpn; xp->l2vpn = l2vpn;
switch (ldpd_process) { switch (ldpd_process) {
@ -1644,8 +1644,8 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl, void
} }
/* remove from active list */ /* remove from active list */
LIST_REMOVE(pw, entry); RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_tree, pw);
LIST_INSERT_HEAD(&pw_aux_list, pw, entry); RB_INSERT(l2vpn_pw_head, &pw_aux_list, pw);
} }
if (ldpd_process == PROC_LDP_ENGINE) { if (ldpd_process == PROC_LDP_ENGINE) {
@ -1689,27 +1689,27 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl, void
l2vpn->mtu = previous_mtu; l2vpn->mtu = previous_mtu;
} }
LIST_REMOVE(xp, entry); RB_REMOVE(l2vpn_pw_head, &xl->pw_tree, xp);
if (ref && *ref == xp) if (ref && *ref == xp)
*ref = pw; *ref = pw;
free(xp); free(xp);
} }
/* merge inactive pseudowires */ /* merge inactive pseudowires */
LIST_FOREACH_SAFE(pw, &l2vpn->pw_inactive_list, entry, ptmp) { RB_FOREACH_SAFE(pw, l2vpn_pw_head, &l2vpn->pw_inactive_tree, ptmp) {
/* find deleted inactive pseudowires */ /* find deleted inactive pseudowires */
if ((xp = l2vpn_pw_find_name(xl, pw->ifname)) == NULL) { if ((xp = l2vpn_pw_find_name(xl, pw->ifname)) == NULL) {
LIST_REMOVE(pw, entry); RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
if (ldpd_process == PROC_MAIN) if (ldpd_process == PROC_MAIN)
QOBJ_UNREG (pw); QOBJ_UNREG (pw);
free(pw); free(pw);
} }
} }
LIST_FOREACH_SAFE(xp, &xl->pw_inactive_list, entry, ptmp) { RB_FOREACH_SAFE(xp, l2vpn_pw_head, &xl->pw_inactive_tree, ptmp) {
/* find new inactive pseudowires */ /* find new inactive pseudowires */
if ((pw = l2vpn_pw_find_name(l2vpn, xp->ifname)) == NULL) { if ((pw = l2vpn_pw_find_name(l2vpn, xp->ifname)) == NULL) {
LIST_REMOVE(xp, entry); RB_REMOVE(l2vpn_pw_head, &xl->pw_inactive_tree, xp);
LIST_INSERT_HEAD(&l2vpn->pw_inactive_list, xp, entry); RB_INSERT(l2vpn_pw_head, &l2vpn->pw_inactive_tree, xp);
xp->l2vpn = l2vpn; xp->l2vpn = l2vpn;
if (ldpd_process == PROC_MAIN) if (ldpd_process == PROC_MAIN)
QOBJ_REG (xp, l2vpn_pw); QOBJ_REG (xp, l2vpn_pw);
@ -1728,8 +1728,8 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl, void
/* check if the pseudowire should be activated */ /* check if the pseudowire should be activated */
if (pw->lsr_id.s_addr != INADDR_ANY && pw->pwid != 0) { if (pw->lsr_id.s_addr != INADDR_ANY && pw->pwid != 0) {
/* remove from inactive list */ /* remove from inactive list */
LIST_REMOVE(pw, entry); RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
LIST_INSERT_HEAD(&l2vpn->pw_list, pw, entry); RB_INSERT(l2vpn_pw_head, &l2vpn->pw_tree, pw);
switch (ldpd_process) { switch (ldpd_process) {
case PROC_LDE_ENGINE: case PROC_LDE_ENGINE:
@ -1743,16 +1743,16 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl, void
} }
} }
LIST_REMOVE(xp, entry); RB_REMOVE(l2vpn_pw_head, &xl->pw_inactive_tree, xp);
if (ref && *ref == xp) if (ref && *ref == xp)
*ref = pw; *ref = pw;
free(xp); free(xp);
} }
/* insert pseudowires that were disabled in the inactive list */ /* insert pseudowires that were disabled in the inactive list */
LIST_FOREACH_SAFE(pw, &pw_aux_list, entry, ptmp) { RB_FOREACH_SAFE(pw, l2vpn_pw_head, &pw_aux_list, ptmp) {
LIST_REMOVE(pw, entry); RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_tree, pw);
LIST_INSERT_HEAD(&l2vpn->pw_inactive_list, pw, entry); RB_INSERT(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
} }
l2vpn->pw_type = xl->pw_type; l2vpn->pw_type = xl->pw_type;
@ -1770,10 +1770,10 @@ config_new_empty(void)
if (xconf == NULL) if (xconf == NULL)
fatal(NULL); fatal(NULL);
LIST_INIT(&xconf->iface_list); RB_INIT(&xconf->iface_tree);
LIST_INIT(&xconf->tnbr_list); RB_INIT(&xconf->tnbr_tree);
LIST_INIT(&xconf->nbrp_list); RB_INIT(&xconf->nbrp_tree);
LIST_INIT(&xconf->l2vpn_list); RB_INIT(&xconf->l2vpn_tree);
return (xconf); return (xconf);
} }

View file

@ -196,7 +196,10 @@ enum nbr_action {
NBR_ACT_CLOSE_SESSION NBR_ACT_CLOSE_SESSION
}; };
TAILQ_HEAD(mapping_head, mapping_entry); /* forward declarations */
RB_HEAD(global_adj_head, adj);
RB_HEAD(nbr_adj_head, adj);
RB_HEAD(ia_adj_head, adj);
struct map { struct map {
uint8_t type; uint8_t type;
@ -256,7 +259,7 @@ struct iface_af {
int af; int af;
int enabled; int enabled;
int state; int state;
LIST_HEAD(, adj) adj_list; struct ia_adj_head adj_tree;
time_t uptime; time_t uptime;
struct thread *hello_timer; struct thread *hello_timer;
uint16_t hello_holdtime; uint16_t hello_holdtime;
@ -264,7 +267,7 @@ struct iface_af {
}; };
struct iface { struct iface {
LIST_ENTRY(iface) entry; RB_ENTRY(iface) entry;
char name[IF_NAMESIZE]; char name[IF_NAMESIZE];
unsigned int ifindex; unsigned int ifindex;
struct if_addr_head addr_list; struct if_addr_head addr_list;
@ -275,11 +278,13 @@ struct iface {
struct iface_af ipv6; struct iface_af ipv6;
QOBJ_FIELDS QOBJ_FIELDS
}; };
RB_HEAD(iface_head, iface);
RB_PROTOTYPE(iface_head, iface, entry, iface_compare);
DECLARE_QOBJ_TYPE(iface) DECLARE_QOBJ_TYPE(iface)
/* source of targeted hellos */ /* source of targeted hellos */
struct tnbr { struct tnbr {
LIST_ENTRY(tnbr) entry; RB_ENTRY(tnbr) entry;
struct thread *hello_timer; struct thread *hello_timer;
struct adj *adj; struct adj *adj;
int af; int af;
@ -289,6 +294,8 @@ struct tnbr {
uint8_t flags; uint8_t flags;
QOBJ_FIELDS QOBJ_FIELDS
}; };
RB_HEAD(tnbr_head, tnbr);
RB_PROTOTYPE(tnbr_head, tnbr, entry, tnbr_compare);
DECLARE_QOBJ_TYPE(tnbr) DECLARE_QOBJ_TYPE(tnbr)
#define F_TNBR_CONFIGURED 0x01 #define F_TNBR_CONFIGURED 0x01
#define F_TNBR_DYNAMIC 0x02 #define F_TNBR_DYNAMIC 0x02
@ -300,7 +307,7 @@ enum auth_method {
/* neighbor specific parameters */ /* neighbor specific parameters */
struct nbr_params { struct nbr_params {
LIST_ENTRY(nbr_params) entry; RB_ENTRY(nbr_params) entry;
struct in_addr lsr_id; struct in_addr lsr_id;
uint16_t keepalive; uint16_t keepalive;
int gtsm_enabled; int gtsm_enabled;
@ -313,23 +320,27 @@ struct nbr_params {
uint8_t flags; uint8_t flags;
QOBJ_FIELDS QOBJ_FIELDS
}; };
RB_HEAD(nbrp_head, nbr_params);
RB_PROTOTYPE(nbrp_head, nbr_params, entry, nbr_params_compare);
DECLARE_QOBJ_TYPE(nbr_params) DECLARE_QOBJ_TYPE(nbr_params)
#define F_NBRP_KEEPALIVE 0x01 #define F_NBRP_KEEPALIVE 0x01
#define F_NBRP_GTSM 0x02 #define F_NBRP_GTSM 0x02
#define F_NBRP_GTSM_HOPS 0x04 #define F_NBRP_GTSM_HOPS 0x04
struct l2vpn_if { struct l2vpn_if {
LIST_ENTRY(l2vpn_if) entry; RB_ENTRY(l2vpn_if) entry;
struct l2vpn *l2vpn; struct l2vpn *l2vpn;
char ifname[IF_NAMESIZE]; char ifname[IF_NAMESIZE];
unsigned int ifindex; unsigned int ifindex;
uint16_t flags; uint16_t flags;
QOBJ_FIELDS QOBJ_FIELDS
}; };
RB_HEAD(l2vpn_if_head, l2vpn_if);
RB_PROTOTYPE(l2vpn_if_head, l2vpn_if, entry, l2vpn_if_compare);
DECLARE_QOBJ_TYPE(l2vpn_if) DECLARE_QOBJ_TYPE(l2vpn_if)
struct l2vpn_pw { struct l2vpn_pw {
LIST_ENTRY(l2vpn_pw) entry; RB_ENTRY(l2vpn_pw) entry;
struct l2vpn *l2vpn; struct l2vpn *l2vpn;
struct in_addr lsr_id; struct in_addr lsr_id;
int af; int af;
@ -343,6 +354,8 @@ struct l2vpn_pw {
uint8_t flags; uint8_t flags;
QOBJ_FIELDS QOBJ_FIELDS
}; };
RB_HEAD(l2vpn_pw_head, l2vpn_pw);
RB_PROTOTYPE(l2vpn_pw_head, l2vpn_pw, entry, l2vpn_pw_compare);
DECLARE_QOBJ_TYPE(l2vpn_pw) DECLARE_QOBJ_TYPE(l2vpn_pw)
#define F_PW_STATUSTLV_CONF 0x01 /* status tlv configured */ #define F_PW_STATUSTLV_CONF 0x01 /* status tlv configured */
#define F_PW_STATUSTLV 0x02 /* status tlv negotiated */ #define F_PW_STATUSTLV 0x02 /* status tlv negotiated */
@ -352,18 +365,20 @@ 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;
int mtu; int mtu;
char br_ifname[IF_NAMESIZE]; char br_ifname[IF_NAMESIZE];
unsigned int br_ifindex; unsigned int br_ifindex;
LIST_HEAD(, l2vpn_if) if_list; struct l2vpn_if_head if_tree;
LIST_HEAD(, l2vpn_pw) pw_list; struct l2vpn_pw_head pw_tree;
LIST_HEAD(, l2vpn_pw) pw_inactive_list; struct l2vpn_pw_head pw_inactive_tree;
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
@ -404,10 +419,10 @@ struct ldpd_conf {
struct in_addr rtr_id; struct in_addr rtr_id;
struct ldpd_af_conf ipv4; struct ldpd_af_conf ipv4;
struct ldpd_af_conf ipv6; struct ldpd_af_conf ipv6;
LIST_HEAD(, iface) iface_list; struct iface_head iface_tree;
LIST_HEAD(, tnbr) tnbr_list; struct tnbr_head tnbr_tree;
LIST_HEAD(, nbr_params) nbrp_list; 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;
@ -438,7 +453,7 @@ struct ldpd_global {
uint32_t conf_seqnum; uint32_t conf_seqnum;
int pfkeysock; int pfkeysock;
struct if_addr_head addr_list; struct if_addr_head addr_list;
LIST_HEAD(, adj) adj_list; struct global_adj_head adj_tree;
struct in_addr mcast_addr_v4; struct in_addr mcast_addr_v4;
struct in6_addr mcast_addr_v6; struct in6_addr mcast_addr_v6;
TAILQ_HEAD(, pending_conn) pending_conns; TAILQ_HEAD(, pending_conn) pending_conns;
@ -627,23 +642,28 @@ void config_clear(struct ldpd_conf *);
/* ldp_vty_conf.c */ /* ldp_vty_conf.c */
/* NOTE: the parameters' names should be preserved because of codegen */ /* NOTE: the parameters' names should be preserved because of codegen */
struct iface *iface_new_api(struct ldpd_conf *cfg, struct iface *iface_new_api(struct ldpd_conf *conf,
const char *name); const char *name);
void iface_del_api(struct iface *iface); void iface_del_api(struct ldpd_conf *conf,
struct tnbr *tnbr_new_api(struct ldpd_conf *cfg, int af, struct iface *iface);
struct tnbr *tnbr_new_api(struct ldpd_conf *conf, int af,
union ldpd_addr *addr); union ldpd_addr *addr);
void tnbr_del_api(struct tnbr *tnbr); void tnbr_del_api(struct ldpd_conf *conf, struct tnbr *tnbr);
struct nbr_params *nbrp_new_api(struct ldpd_conf *cfg, 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 nbr_params *nbrp); void nbrp_del_api(struct ldpd_conf *conf,
struct l2vpn *l2vpn_new_api(struct ldpd_conf *cfg, const char *name); struct nbr_params *nbrp);
void l2vpn_del_api(struct l2vpn *l2vpn); struct l2vpn *l2vpn_new_api(struct ldpd_conf *conf, const char *name);
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 *l2vpn,
struct l2vpn_if *lif);
struct l2vpn_pw *l2vpn_pw_new_api(struct ldpd_conf *conf, struct l2vpn_pw *l2vpn_pw_new_api(struct ldpd_conf *conf,
struct l2vpn *l2vpn, const char *ifname); struct l2vpn *l2vpn, const char *ifname);
void l2vpn_pw_del_api(struct l2vpn_pw *pw); void l2vpn_pw_del_api(struct l2vpn *l2vpn,
struct l2vpn_pw *pw);
/* socket.c */ /* socket.c */
int ldp_create_socket(int, enum socket_type); int ldp_create_socket(int, enum socket_type);

View file

@ -111,7 +111,7 @@ ldpe(const char *user, const char *group)
ldpd_process = PROC_LDP_ENGINE; ldpd_process = PROC_LDP_ENGINE;
LIST_INIT(&global.addr_list); LIST_INIT(&global.addr_list);
LIST_INIT(&global.adj_list); RB_INIT(&global.adj_tree);
TAILQ_INIT(&global.pending_conns); TAILQ_INIT(&global.pending_conns);
if (inet_pton(AF_INET, AllRouters_v4, &global.mcast_addr_v4) != 1) if (inet_pton(AF_INET, AllRouters_v4, &global.mcast_addr_v4) != 1)
fatal("inet_pton"); fatal("inet_pton");
@ -209,7 +209,7 @@ ldpe_shutdown(void)
LIST_REMOVE(if_addr, entry); LIST_REMOVE(if_addr, entry);
free(if_addr); free(if_addr);
} }
while ((adj = LIST_FIRST(&global.adj_list)) != NULL) while ((adj = RB_ROOT(&global.adj_tree)) != NULL)
adj_del(adj, S_SHUTDOWN); adj_del(adj, S_SHUTDOWN);
/* clean up */ /* clean up */
@ -414,10 +414,10 @@ ldpe_dispatch_main(struct thread *thread)
fatal(NULL); fatal(NULL);
memcpy(nconf, imsg.data, sizeof(struct ldpd_conf)); memcpy(nconf, imsg.data, sizeof(struct ldpd_conf));
LIST_INIT(&nconf->iface_list); RB_INIT(&nconf->iface_tree);
LIST_INIT(&nconf->tnbr_list); RB_INIT(&nconf->tnbr_tree);
LIST_INIT(&nconf->nbrp_list); 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)
@ -425,37 +425,37 @@ ldpe_dispatch_main(struct thread *thread)
memcpy(niface, imsg.data, sizeof(struct iface)); memcpy(niface, imsg.data, sizeof(struct iface));
LIST_INIT(&niface->addr_list); LIST_INIT(&niface->addr_list);
LIST_INIT(&niface->ipv4.adj_list); RB_INIT(&niface->ipv4.adj_tree);
LIST_INIT(&niface->ipv6.adj_list); RB_INIT(&niface->ipv6.adj_tree);
niface->ipv4.iface = niface; niface->ipv4.iface = niface;
niface->ipv6.iface = niface; niface->ipv6.iface = niface;
LIST_INSERT_HEAD(&nconf->iface_list, niface, entry); RB_INSERT(iface_head, &nconf->iface_tree, niface);
break; break;
case IMSG_RECONF_TNBR: case IMSG_RECONF_TNBR:
if ((ntnbr = malloc(sizeof(struct tnbr))) == NULL) if ((ntnbr = malloc(sizeof(struct tnbr))) == NULL)
fatal(NULL); fatal(NULL);
memcpy(ntnbr, imsg.data, sizeof(struct tnbr)); memcpy(ntnbr, imsg.data, sizeof(struct tnbr));
LIST_INSERT_HEAD(&nconf->tnbr_list, ntnbr, entry); RB_INSERT(tnbr_head, &nconf->tnbr_tree, ntnbr);
break; break;
case IMSG_RECONF_NBRP: case IMSG_RECONF_NBRP:
if ((nnbrp = malloc(sizeof(struct nbr_params))) == NULL) if ((nnbrp = malloc(sizeof(struct nbr_params))) == NULL)
fatal(NULL); fatal(NULL);
memcpy(nnbrp, imsg.data, sizeof(struct nbr_params)); memcpy(nnbrp, imsg.data, sizeof(struct nbr_params));
LIST_INSERT_HEAD(&nconf->nbrp_list, nnbrp, entry); RB_INSERT(nbrp_head, &nconf->nbrp_tree, nnbrp);
break; break;
case IMSG_RECONF_L2VPN: case IMSG_RECONF_L2VPN:
if ((nl2vpn = malloc(sizeof(struct l2vpn))) == NULL) if ((nl2vpn = malloc(sizeof(struct l2vpn))) == NULL)
fatal(NULL); fatal(NULL);
memcpy(nl2vpn, imsg.data, sizeof(struct l2vpn)); memcpy(nl2vpn, imsg.data, sizeof(struct l2vpn));
LIST_INIT(&nl2vpn->if_list); RB_INIT(&nl2vpn->if_tree);
LIST_INIT(&nl2vpn->pw_list); RB_INIT(&nl2vpn->pw_tree);
LIST_INIT(&nl2vpn->pw_inactive_list); RB_INIT(&nl2vpn->pw_inactive_tree);
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)
@ -463,7 +463,7 @@ ldpe_dispatch_main(struct thread *thread)
memcpy(nlif, imsg.data, sizeof(struct l2vpn_if)); memcpy(nlif, imsg.data, sizeof(struct l2vpn_if));
nlif->l2vpn = nl2vpn; nlif->l2vpn = nl2vpn;
LIST_INSERT_HEAD(&nl2vpn->if_list, nlif, entry); RB_INSERT(l2vpn_if_head, &nl2vpn->if_tree, nlif);
break; break;
case IMSG_RECONF_L2VPN_PW: case IMSG_RECONF_L2VPN_PW:
if ((npw = malloc(sizeof(struct l2vpn_pw))) == NULL) if ((npw = malloc(sizeof(struct l2vpn_pw))) == NULL)
@ -471,7 +471,7 @@ ldpe_dispatch_main(struct thread *thread)
memcpy(npw, imsg.data, sizeof(struct l2vpn_pw)); memcpy(npw, imsg.data, sizeof(struct l2vpn_pw));
npw->l2vpn = nl2vpn; npw->l2vpn = nl2vpn;
LIST_INSERT_HEAD(&nl2vpn->pw_list, npw, entry); RB_INSERT(l2vpn_pw_head, &nl2vpn->pw_tree, npw);
break; break;
case IMSG_RECONF_L2VPN_IPW: case IMSG_RECONF_L2VPN_IPW:
if ((npw = malloc(sizeof(struct l2vpn_pw))) == NULL) if ((npw = malloc(sizeof(struct l2vpn_pw))) == NULL)
@ -479,7 +479,7 @@ ldpe_dispatch_main(struct thread *thread)
memcpy(npw, imsg.data, sizeof(struct l2vpn_pw)); memcpy(npw, imsg.data, sizeof(struct l2vpn_pw));
npw->l2vpn = nl2vpn; npw->l2vpn = nl2vpn;
LIST_INSERT_HEAD(&nl2vpn->pw_inactive_list, npw, entry); RB_INSERT(l2vpn_pw_head, &nl2vpn->pw_inactive_tree, npw);
break; break;
case IMSG_RECONF_END: case IMSG_RECONF_END:
merge_config(leconf, nconf); merge_config(leconf, nconf);
@ -743,12 +743,12 @@ ldpe_remove_dynamic_tnbrs(int af)
{ {
struct tnbr *tnbr, *safe; struct tnbr *tnbr, *safe;
LIST_FOREACH_SAFE(tnbr, &leconf->tnbr_list, entry, safe) { RB_FOREACH_SAFE(tnbr, tnbr_head, &leconf->tnbr_tree, safe) {
if (tnbr->af != af) if (tnbr->af != af)
continue; continue;
tnbr->flags &= ~F_TNBR_DYNAMIC; tnbr->flags &= ~F_TNBR_DYNAMIC;
tnbr_check(tnbr); tnbr_check(leconf, tnbr);
} }
} }
@ -772,7 +772,7 @@ ldpe_iface_af_ctl(struct ctl_conn *c, int af, unsigned int idx)
struct iface_af *ia; struct iface_af *ia;
struct ctl_iface *ictl; struct ctl_iface *ictl;
LIST_FOREACH(iface, &leconf->iface_list, entry) { RB_FOREACH(iface, iface_head, &leconf->iface_tree) {
if (idx == 0 || idx == iface->ifindex) { if (idx == 0 || idx == iface->ifindex) {
ia = iface_af_get(iface, af); ia = iface_af_get(iface, af);
if (!ia->enabled) if (!ia->enabled)
@ -805,7 +805,7 @@ ldpe_adj_ctl(struct ctl_conn *c)
imsg_compose_event(&c->iev, IMSG_CTL_SHOW_DISCOVERY, 0, 0, -1, NULL, 0); imsg_compose_event(&c->iev, IMSG_CTL_SHOW_DISCOVERY, 0, 0, -1, NULL, 0);
LIST_FOREACH(iface, &leconf->iface_list, entry) { RB_FOREACH(iface, iface_head, &leconf->iface_tree) {
memset(&ictl, 0, sizeof(ictl)); memset(&ictl, 0, sizeof(ictl));
ictl.active_v4 = (iface->ipv4.state == IF_STA_ACTIVE); ictl.active_v4 = (iface->ipv4.state == IF_STA_ACTIVE);
ictl.active_v6 = (iface->ipv6.state == IF_STA_ACTIVE); ictl.active_v6 = (iface->ipv6.state == IF_STA_ACTIVE);
@ -814,25 +814,25 @@ ldpe_adj_ctl(struct ctl_conn *c)
continue; continue;
strlcpy(ictl.name, iface->name, sizeof(ictl.name)); strlcpy(ictl.name, iface->name, sizeof(ictl.name));
if (LIST_EMPTY(&iface->ipv4.adj_list) && if (RB_EMPTY(&iface->ipv4.adj_tree) &&
LIST_EMPTY(&iface->ipv6.adj_list)) RB_EMPTY(&iface->ipv6.adj_tree))
ictl.no_adj = 1; ictl.no_adj = 1;
imsg_compose_event(&c->iev, IMSG_CTL_SHOW_DISC_IFACE, 0, 0, imsg_compose_event(&c->iev, IMSG_CTL_SHOW_DISC_IFACE, 0, 0,
-1, &ictl, sizeof(ictl)); -1, &ictl, sizeof(ictl));
LIST_FOREACH(adj, &iface->ipv4.adj_list, ia_entry) { RB_FOREACH(adj, ia_adj_head, &iface->ipv4.adj_tree) {
actl = adj_to_ctl(adj); actl = adj_to_ctl(adj);
imsg_compose_event(&c->iev, IMSG_CTL_SHOW_DISC_ADJ, imsg_compose_event(&c->iev, IMSG_CTL_SHOW_DISC_ADJ,
0, 0, -1, actl, sizeof(struct ctl_adj)); 0, 0, -1, actl, sizeof(struct ctl_adj));
} }
LIST_FOREACH(adj, &iface->ipv6.adj_list, ia_entry) { RB_FOREACH(adj, ia_adj_head, &iface->ipv6.adj_tree) {
actl = adj_to_ctl(adj); actl = adj_to_ctl(adj);
imsg_compose_event(&c->iev, IMSG_CTL_SHOW_DISC_ADJ, imsg_compose_event(&c->iev, IMSG_CTL_SHOW_DISC_ADJ,
0, 0, -1, actl, sizeof(struct ctl_adj)); 0, 0, -1, actl, sizeof(struct ctl_adj));
} }
} }
LIST_FOREACH(tnbr, &leconf->tnbr_list, entry) { RB_FOREACH(tnbr, tnbr_head, &leconf->tnbr_tree) {
memset(&tctl, 0, sizeof(tctl)); memset(&tctl, 0, sizeof(tctl));
tctl.af = tnbr->af; tctl.af = tnbr->af;
tctl.addr = tnbr->addr; tctl.addr = tnbr->addr;
@ -869,7 +869,7 @@ ldpe_nbr_ctl(struct ctl_conn *c)
imsg_compose_event(&c->iev, IMSG_CTL_SHOW_NBR, 0, 0, -1, nctl, imsg_compose_event(&c->iev, IMSG_CTL_SHOW_NBR, 0, 0, -1, nctl,
sizeof(struct ctl_nbr)); sizeof(struct ctl_nbr));
LIST_FOREACH(adj, &nbr->adj_list, nbr_entry) { RB_FOREACH(adj, nbr_adj_head, &nbr->adj_tree) {
actl = adj_to_ctl(adj); actl = adj_to_ctl(adj);
imsg_compose_event(&c->iev, IMSG_CTL_SHOW_NBR_DISC, imsg_compose_event(&c->iev, IMSG_CTL_SHOW_NBR_DISC,
0, 0, -1, actl, sizeof(struct ctl_adj)); 0, 0, -1, actl, sizeof(struct ctl_adj));

View file

@ -32,6 +32,9 @@
#define min(x,y) ((x) <= (y) ? (x) : (y)) #define min(x,y) ((x) <= (y) ? (x) : (y))
#define max(x,y) ((x) > (y) ? (x) : (y)) #define max(x,y) ((x) > (y) ? (x) : (y))
/* forward declarations */
TAILQ_HEAD(mapping_head, mapping_entry);
struct hello_source { struct hello_source {
enum hello_type type; enum hello_type type;
struct { struct {
@ -42,9 +45,7 @@ struct hello_source {
}; };
struct adj { struct adj {
LIST_ENTRY(adj) global_entry; RB_ENTRY(adj) global_entry, nbr_entry, ia_entry;
LIST_ENTRY(adj) nbr_entry;
LIST_ENTRY(adj) ia_entry;
struct in_addr lsr_id; struct in_addr lsr_id;
struct nbr *nbr; struct nbr *nbr;
int ds_tlv; int ds_tlv;
@ -53,6 +54,9 @@ struct adj {
uint16_t holdtime; uint16_t holdtime;
union ldpd_addr trans_addr; union ldpd_addr trans_addr;
}; };
RB_PROTOTYPE(global_adj_head, adj, global_entry, adj_compare)
RB_PROTOTYPE(nbr_adj_head, adj, nbr_entry, adj_compare)
RB_PROTOTYPE(ia_adj_head, adj, ia_entry, adj_compare)
struct tcp_conn { struct tcp_conn {
struct nbr *nbr; struct nbr *nbr;
@ -67,7 +71,7 @@ struct tcp_conn {
struct nbr { struct nbr {
RB_ENTRY(nbr) id_tree, addr_tree, pid_tree; RB_ENTRY(nbr) id_tree, addr_tree, pid_tree;
struct tcp_conn *tcp; struct tcp_conn *tcp;
LIST_HEAD(, adj) adj_list; /* adjacencies */ struct nbr_adj_head adj_tree; /* adjacencies */
struct thread *ev_connect; struct thread *ev_connect;
struct thread *keepalive_timer; struct thread *keepalive_timer;
struct thread *keepalive_timeout; struct thread *keepalive_timeout;
@ -225,7 +229,7 @@ void adj_start_itimer(struct adj *);
void adj_stop_itimer(struct adj *); void adj_stop_itimer(struct adj *);
struct tnbr *tnbr_new(int, union ldpd_addr *); struct tnbr *tnbr_new(int, union ldpd_addr *);
struct tnbr *tnbr_find(struct ldpd_conf *, int, union ldpd_addr *); struct tnbr *tnbr_find(struct ldpd_conf *, int, union ldpd_addr *);
struct tnbr *tnbr_check(struct tnbr *); struct tnbr *tnbr_check(struct ldpd_conf *, struct tnbr *);
void tnbr_update(struct tnbr *); void tnbr_update(struct tnbr *);
void tnbr_update_all(int); void tnbr_update_all(int);
uint16_t tnbr_get_hello_holdtime(struct tnbr *); uint16_t tnbr_get_hello_holdtime(struct tnbr *);

View file

@ -39,10 +39,13 @@ static void nbr_start_itimeout(struct nbr *);
static int nbr_idtimer(struct thread *); static int nbr_idtimer(struct thread *);
static int nbr_act_session_operational(struct nbr *); static int nbr_act_session_operational(struct nbr *);
static void nbr_send_labelmappings(struct nbr *); static void nbr_send_labelmappings(struct nbr *);
static __inline int nbr_params_compare(struct nbr_params *,
struct nbr_params *);
RB_GENERATE(nbr_id_head, nbr, id_tree, nbr_id_compare) RB_GENERATE(nbr_id_head, nbr, id_tree, nbr_id_compare)
RB_GENERATE(nbr_addr_head, nbr, addr_tree, nbr_addr_compare) RB_GENERATE(nbr_addr_head, nbr, addr_tree, nbr_addr_compare)
RB_GENERATE(nbr_pid_head, nbr, pid_tree, nbr_pid_compare) RB_GENERATE(nbr_pid_head, nbr, pid_tree, nbr_pid_compare)
RB_GENERATE(nbrp_head, nbr_params, entry, nbr_params_compare)
struct { struct {
int state; int state;
@ -226,7 +229,7 @@ nbr_new(struct in_addr id, int af, int ds_tlv, union ldpd_addr *addr,
if ((nbr = calloc(1, sizeof(*nbr))) == NULL) if ((nbr = calloc(1, sizeof(*nbr))) == NULL)
fatal(__func__); fatal(__func__);
LIST_INIT(&nbr->adj_list); RB_INIT(&nbr->adj_tree);
nbr->state = NBR_STA_PRESENT; nbr->state = NBR_STA_PRESENT;
nbr->peerid = 0; nbr->peerid = 0;
nbr->af = af; nbr->af = af;
@ -241,10 +244,10 @@ nbr_new(struct in_addr id, int af, int ds_tlv, union ldpd_addr *addr,
nbr->raddr_scope = scope_id; nbr->raddr_scope = scope_id;
nbr->conf_seqnum = 0; nbr->conf_seqnum = 0;
LIST_FOREACH(adj, &global.adj_list, global_entry) { RB_FOREACH(adj, global_adj_head, &global.adj_tree) {
if (adj->lsr_id.s_addr == nbr->id.s_addr) { if (adj->lsr_id.s_addr == nbr->id.s_addr) {
adj->nbr = nbr; adj->nbr = nbr;
LIST_INSERT_HEAD(&nbr->adj_list, adj, nbr_entry); RB_INSERT(nbr_adj_head, &nbr->adj_tree, adj);
} }
} }
@ -363,7 +366,7 @@ nbr_adj_count(struct nbr *nbr, int af)
struct adj *adj; struct adj *adj;
int total = 0; int total = 0;
LIST_FOREACH(adj, &nbr->adj_list, nbr_entry) RB_FOREACH(adj, nbr_adj_head, &nbr->adj_tree)
if (adj_get_af(adj) == af) if (adj_get_af(adj) == af)
total++; total++;
@ -621,7 +624,7 @@ nbr_establish_connection(struct nbr *nbr)
* Send an extra hello to guarantee that the remote peer has formed * Send an extra hello to guarantee that the remote peer has formed
* an adjacency as well. * an adjacency as well.
*/ */
LIST_FOREACH(adj, &nbr->adj_list, nbr_entry) RB_FOREACH(adj, nbr_adj_head, &nbr->adj_tree)
send_hello(adj->source.type, adj->source.link.ia, send_hello(adj->source.type, adj->source.link.ia,
adj->source.target); adj->source.target);
@ -752,6 +755,12 @@ nbr_send_labelmappings(struct nbr *nbr)
NULL, 0); NULL, 0);
} }
static __inline int
nbr_params_compare(struct nbr_params *a, struct nbr_params *b)
{
return (ntohl(a->lsr_id.s_addr) - ntohl(b->lsr_id.s_addr));
}
struct nbr_params * struct nbr_params *
nbr_params_new(struct in_addr lsr_id) nbr_params_new(struct in_addr lsr_id)
{ {
@ -769,13 +778,9 @@ nbr_params_new(struct in_addr lsr_id)
struct nbr_params * struct nbr_params *
nbr_params_find(struct ldpd_conf *xconf, struct in_addr lsr_id) nbr_params_find(struct ldpd_conf *xconf, struct in_addr lsr_id)
{ {
struct nbr_params *nbrp; struct nbr_params nbrp;
nbrp.lsr_id = lsr_id;
LIST_FOREACH(nbrp, &xconf->nbrp_list, entry) return (RB_FIND(nbrp_head, &xconf->nbrp_tree, &nbrp));
if (nbrp->lsr_id.s_addr == lsr_id.s_addr)
return (nbrp);
return (NULL);
} }
uint16_t uint16_t