tnbr
struct tnbr *
struct tnbr *tnbr;
if ((tnbr = calloc(1, sizeof(*tnbr))) == NULL)
tnbr->af = af;
tnbr->addr = *addr;
tnbr->state = TNBR_STA_DOWN;
tnbr->hello_holdtime = (ldp_af_conf_get(xconf, af))->thello_holdtime;
tnbr->hello_interval = (ldp_af_conf_get(xconf, af))->thello_interval;
return (tnbr);
tnbr_del(struct tnbr *tnbr)
tnbr_stop_hello_timer(tnbr);
if (tnbr->adj)
adj_del(tnbr->adj, S_SHUTDOWN);
LIST_REMOVE(tnbr, entry);
free(tnbr);
struct tnbr *
struct tnbr *tnbr;
LIST_FOREACH(tnbr, &xconf->tnbr_list, entry)
if (af == tnbr->af &&
ldp_addrcmp(af, addr, &tnbr->addr) == 0)
return (tnbr);
struct tnbr *
tnbr_check(struct tnbr *tnbr)
if (!(tnbr->flags & (F_TNBR_CONFIGURED|F_TNBR_DYNAMIC)) &&
tnbr->pw_count == 0) {
tnbr_del(tnbr);
return (tnbr);
tnbr_update(struct tnbr *tnbr)
if ((ldp_af_global_get(&global, tnbr->af))->ldp_edisc_socket != -1)
if (tnbr->state == TNBR_STA_DOWN) {
tnbr->state = TNBR_STA_ACTIVE;
send_hello(HELLO_TARGETED, NULL, tnbr);
evtimer_set(&tnbr->hello_timer, tnbr_hello_timer, tnbr);
tnbr_start_hello_timer(tnbr);
} else if (tnbr->state == TNBR_STA_ACTIVE) {
tnbr->state = TNBR_STA_DOWN;
tnbr_stop_hello_timer(tnbr);
struct tnbr *tnbr;
LIST_FOREACH(tnbr, &leconf->tnbr_list, entry)
if (tnbr->af == af || af == AF_UNSPEC)
tnbr_update(tnbr);
struct tnbr *tnbr = arg;
send_hello(HELLO_TARGETED, NULL, tnbr);
tnbr_start_hello_timer(tnbr);
tnbr_start_hello_timer(struct tnbr *tnbr)
tv.tv_sec = tnbr->hello_interval;
if (evtimer_add(&tnbr->hello_timer, &tv) == -1)
tnbr_stop_hello_timer(struct tnbr *tnbr)
if (evtimer_pending(&tnbr->hello_timer, NULL) &&
evtimer_del(&tnbr->hello_timer) == -1)
static void tnbr_del(struct tnbr *);
static void tnbr_start_hello_timer(struct tnbr *);
static void tnbr_stop_hello_timer(struct tnbr *);
struct tnbr *tnbr = NULL;
tnbr = tnbr_find(leconf, af, src);
if (tnbr && (tnbr->flags & F_TNBR_DYNAMIC) &&
tnbr->flags &= ~F_TNBR_DYNAMIC;
tnbr = tnbr_check(tnbr);
if (!tnbr) {
tnbr = tnbr_new(leconf, af, src);
tnbr->flags |= F_TNBR_DYNAMIC;
tnbr_update(tnbr);
LIST_INSERT_HEAD(&leconf->tnbr_list, tnbr, entry);
source.target = tnbr;
send_hello(enum hello_type type, struct iface_af *ia, struct tnbr *tnbr)
adj->holdtime = min(tnbr->hello_holdtime, holdtime);
af = tnbr->af;
holdtime = tnbr->hello_holdtime;
if ((tnbr->flags & F_TNBR_CONFIGURED) || tnbr->pw_count)
dst = tnbr->addr;
struct tnbr *tnbr;
tnbr = tnbr_find(leconf, pw->af, &pw->addr);
if (tnbr == NULL) {
tnbr = tnbr_new(leconf, pw->af, &pw->addr);
tnbr_update(tnbr);
LIST_INSERT_HEAD(&leconf->tnbr_list, tnbr, entry);
tnbr->pw_count++;
struct tnbr *tnbr;
tnbr = tnbr_find(leconf, pw->af, &pw->addr);
if (tnbr) {
tnbr->pw_count--;
tnbr_check(tnbr);
struct tnbr *ntnbr;
if ((ntnbr = malloc(sizeof(struct tnbr))) == NULL)
memcpy(ntnbr, imsg.data, sizeof(struct tnbr));
struct tnbr *tnbr;
LIST_FOREACH(tnbr, &xconf->tnbr_list, entry) {
if (main_imsg_compose_both(IMSG_RECONF_TNBR, tnbr,
sizeof(*tnbr)) == -1)
struct tnbr *tnbr, *ttmp, *xt;
LIST_FOREACH_SAFE(tnbr, &conf->tnbr_list, entry, ttmp) {
if (!(tnbr->flags & F_TNBR_CONFIGURED))
if ((xt = tnbr_find(xconf, tnbr->af, &tnbr->addr)) == NULL) {
tnbr->flags &= ~F_TNBR_CONFIGURED;
tnbr_check(tnbr);
LIST_REMOVE(tnbr, entry);
free(tnbr);
if ((tnbr = tnbr_find(conf, xt->af, &xt->addr)) == NULL) {
if (!(tnbr->flags & F_TNBR_CONFIGURED))
tnbr->flags |= F_TNBR_CONFIGURED;
tnbr->hello_holdtime = xt->hello_holdtime;
tnbr->hello_interval = xt->hello_interval;
LIST_ENTRY(tnbr) entry;
LIST_HEAD(, tnbr) tnbr_list;
struct tnbr *ntnbr;
if ((ntnbr = malloc(sizeof(struct tnbr))) == NULL)
memcpy(ntnbr, imsg.data, sizeof(struct tnbr));
struct tnbr *tnbr, *safe;
LIST_FOREACH_SAFE(tnbr, &leconf->tnbr_list, entry, safe) {
if (tnbr->af != af)
tnbr->flags &= ~F_TNBR_DYNAMIC;
tnbr_check(tnbr);
int send_hello(enum hello_type, struct iface_af *, struct tnbr *);
struct tnbr *tnbr_new(struct ldpd_conf *, int, union ldpd_addr *);
struct tnbr *tnbr_find(struct ldpd_conf *, int, union ldpd_addr *);
struct tnbr *tnbr_check(struct tnbr *);
void tnbr_update(struct tnbr *);
struct tnbr *target;
static struct tnbr *conf_get_tnbr(union ldpd_addr *);
static struct tnbr *tnbr;
static struct tnbr *
struct tnbr *t;
struct tnbr *t;
tnbr = conf_get_tnbr(&addr);
if (tnbr == NULL)
tnbr->hello_holdtime = defs->thello_holdtime;
tnbr->hello_interval = defs->thello_interval;
tnbr = NULL;
print_tnbr(struct tnbr *tnbr)
printf("\n\ttargeted-neighbor %s {\n", log_addr(tnbr->af, &tnbr->addr));
printf("\t\ttargeted-hello-holdtime %u\n", tnbr->hello_holdtime);
printf("\t\ttargeted-hello-interval %u\n", tnbr->hello_interval);
static void print_tnbr(struct tnbr *);
struct tnbr *tnbr;
LIST_FOREACH(tnbr, &conf->tnbr_list, entry)
if (tnbr->af == af && tnbr->flags & F_TNBR_CONFIGURED)
print_tnbr(tnbr);