#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_lookup(struct if_addr_head *, struct kaddr *);
static int if_start(struct iface *, int);
static int if_join_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 *
if_new(struct kif *kif)
{
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
if_exit(struct iface *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;
- LIST_FOREACH(iface, &xconf->iface_list, entry)
- if (strcmp(iface->name, ifname) == 0)
+ RB_FOREACH(iface, iface_head, &xconf->iface_tree)
+ if (iface->ifindex == ifindex)
return (iface);
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
if_update_info(struct iface *iface, struct kif *kif)
{
{
struct iface *iface;
- LIST_FOREACH(iface, &leconf->iface_list, entry)
+ RB_FOREACH(iface, iface_head, &leconf->iface_tree)
if_update(iface, af);
}
fatal(NULL);
memcpy(nconf, imsg.data, sizeof(struct ldpd_conf));
- LIST_INIT(&nconf->iface_list);
+ RB_INIT(&nconf->iface_tree);
LIST_INIT(&nconf->tnbr_list);
LIST_INIT(&nconf->nbrp_list);
LIST_INIT(&nconf->l2vpn_list);
niface->ipv4.iface = niface;
niface->ipv6.iface = niface;
- LIST_INSERT_HEAD(&nconf->iface_list, niface, entry);
+ RB_INSERT(iface_head, &nconf->iface_tree, niface);
break;
case IMSG_RECONF_TNBR:
if ((ntnbr = malloc(sizeof(struct tnbr))) == NULL)
DEBUG_OFF(event, EVENT);
else
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;
dir_str = vty_get_arg_value(args, "dir");
if (dir_str == NULL)
DEBUG_ON(msg, MSG_SEND_ALL);
}
}
- } else if (strcmp(type_str, "zebra") == 0) {
+ } else if (strcmp(type_str, "zebra") == 0) {
if (disable)
DEBUG_OFF(zebra, ZEBRA);
else
struct iface *iface;
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);
if (!ia->enabled)
continue;
ia = iface_af_get(iface, af);
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);
} else {
memset(&kif, 0, sizeof(kif));
}
iface = if_new(&kif);
- LIST_INSERT_HEAD(&conf->iface_list, iface, entry);
+ RB_INSERT(iface_head, &conf->iface_tree, iface);
return (iface);
}
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);
}
sizeof(*xconf)) == -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,
sizeof(*iface)) == -1)
return (-1);
struct iface *iface;
struct nbr_params *nbrp;
- while ((iface = LIST_FIRST(&conf->iface_list)) != NULL) {
+ while ((iface = RB_ROOT(&conf->iface_tree)) != NULL) {
if (ref && *ref == iface)
*ref = NULL;
- LIST_REMOVE(iface, entry);
+ RB_REMOVE(iface_head, &conf->iface_tree, iface);
free(iface);
}
struct iface_af *ia;
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->enabled = 0;
}
} while (0)
COPY(xconf, conf);
- LIST_INIT(&xconf->iface_list);
+ RB_INIT(&xconf->iface_tree);
LIST_INIT(&xconf->tnbr_list);
LIST_INIT(&xconf->nbrp_list);
LIST_INIT(&xconf->l2vpn_list);
- LIST_FOREACH(iface, &conf->iface_list, entry) {
+ RB_FOREACH(iface, iface_head, &conf->iface_tree) {
COPY(xi, iface);
xi->ipv4.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) {
COPY(xt, tnbr);
struct nbr_params *nbrp;
struct l2vpn *l2vpn;
- while ((iface = LIST_FIRST(&xconf->iface_list)) != NULL) {
- LIST_REMOVE(iface, entry);
+ while ((iface = RB_ROOT(&xconf->iface_tree)) != NULL) {
+ RB_REMOVE(iface_head, &xconf->iface_tree, iface);
free(iface);
}
while ((tnbr = LIST_FIRST(&xconf->tnbr_list)) != NULL) {
{
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 */
if ((xi = if_lookup_name(xconf, iface->name)) == NULL) {
- LIST_REMOVE(iface, entry);
+ RB_REMOVE(iface_head, &conf->iface_tree, iface);
switch (ldpd_process) {
case PROC_LDE_ENGINE:
free(iface);
}
}
- LIST_FOREACH_SAFE(xi, &xconf->iface_list, entry, itmp) {
+ RB_FOREACH_SAFE(xi, iface_head, &xconf->iface_tree, itmp) {
/* find new interfaces */
if ((iface = if_lookup_name(conf, xi->name)) == NULL) {
- LIST_REMOVE(xi, entry);
- LIST_INSERT_HEAD(&conf->iface_list, xi, entry);
+ RB_REMOVE(iface_head, &xconf->iface_tree, xi);
+ RB_INSERT(iface_head, &conf->iface_tree, xi);
if (ldpd_process == PROC_MAIN) {
QOBJ_REG (xi, iface);
/* update existing interfaces */
merge_iface_af(&iface->ipv4, &xi->ipv4);
merge_iface_af(&iface->ipv6, &xi->ipv6);
- LIST_REMOVE(xi, entry);
+ RB_REMOVE(iface_head, &xconf->iface_tree, xi);
if (ref && *ref == xi)
*ref = iface;
free(xi);
if (xconf == NULL)
fatal(NULL);
- LIST_INIT(&xconf->iface_list);
+ RB_INIT(&xconf->iface_tree);
LIST_INIT(&xconf->tnbr_list);
LIST_INIT(&xconf->nbrp_list);
LIST_INIT(&xconf->l2vpn_list);
};
struct iface {
- LIST_ENTRY(iface) entry;
+ RB_ENTRY(iface) entry;
char name[IF_NAMESIZE];
unsigned int ifindex;
struct if_addr_head addr_list;
struct iface_af ipv6;
QOBJ_FIELDS
};
+RB_HEAD(iface_head, iface);
+RB_PROTOTYPE(iface_head, iface, entry, iface_compare);
DECLARE_QOBJ_TYPE(iface)
/* source of targeted hellos */
struct in_addr rtr_id;
struct ldpd_af_conf ipv4;
struct ldpd_af_conf ipv6;
- LIST_HEAD(, iface) iface_list;
+ struct iface_head iface_tree;
LIST_HEAD(, tnbr) tnbr_list;
LIST_HEAD(, nbr_params) nbrp_list;
LIST_HEAD(, l2vpn) l2vpn_list;
/* ldp_vty_conf.c */
/* 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);
-void iface_del_api(struct iface *iface);
+void iface_del_api(struct ldpd_conf *conf,
+ struct iface *iface);
struct tnbr *tnbr_new_api(struct ldpd_conf *cfg, int af,
union ldpd_addr *addr);
void tnbr_del_api(struct tnbr *tnbr);
fatal(NULL);
memcpy(nconf, imsg.data, sizeof(struct ldpd_conf));
- LIST_INIT(&nconf->iface_list);
+ RB_INIT(&nconf->iface_tree);
LIST_INIT(&nconf->tnbr_list);
LIST_INIT(&nconf->nbrp_list);
LIST_INIT(&nconf->l2vpn_list);
niface->ipv4.iface = niface;
niface->ipv6.iface = niface;
- LIST_INSERT_HEAD(&nconf->iface_list, niface, entry);
+ RB_INSERT(iface_head, &nconf->iface_tree, niface);
break;
case IMSG_RECONF_TNBR:
if ((ntnbr = malloc(sizeof(struct tnbr))) == NULL)
struct iface_af *ia;
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) {
ia = iface_af_get(iface, af);
if (!ia->enabled)
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));
ictl.active_v4 = (iface->ipv4.state == IF_STA_ACTIVE);
ictl.active_v6 = (iface->ipv6.state == IF_STA_ACTIVE);