#include "lde.h"
#include "log.h"
-static __inline int nbr_id_compare(struct nbr *, struct nbr *);
-static __inline int nbr_addr_compare(struct nbr *, struct nbr *);
-static __inline int nbr_pid_compare(struct nbr *, struct nbr *);
+static __inline int nbr_id_compare(const struct nbr *, const struct nbr *);
+static __inline int nbr_addr_compare(const struct nbr *,
+ const struct nbr *);
+static __inline int nbr_pid_compare(const struct nbr *,
+ const struct nbr *);
static void nbr_update_peerid(struct nbr *);
static int nbr_ktimer(struct thread *);
static void nbr_start_ktimer(struct nbr *);
static int nbr_idtimer(struct thread *);
static int nbr_act_session_operational(struct nbr *);
static void nbr_send_labelmappings(struct nbr *);
-static __inline int nbr_params_compare(struct nbr_params *,
- struct nbr_params *);
+static __inline int nbr_params_compare(const struct nbr_params *,
+ const struct nbr_params *);
RB_GENERATE(nbr_id_head, nbr, id_tree, nbr_id_compare)
RB_GENERATE(nbr_addr_head, nbr, addr_tree, nbr_addr_compare)
struct nbr_pid_head nbrs_by_pid = RB_INITIALIZER(&nbrs_by_pid);
static __inline int
-nbr_id_compare(struct nbr *a, struct nbr *b)
+nbr_id_compare(const struct nbr *a, const struct nbr *b)
{
return (ntohl(a->id.s_addr) - ntohl(b->id.s_addr));
}
static __inline int
-nbr_addr_compare(struct nbr *a, struct nbr *b)
+nbr_addr_compare(const struct nbr *a, const struct nbr *b)
{
if (a->af < b->af)
return (-1);
}
static __inline int
-nbr_pid_compare(struct nbr *a, struct nbr *b)
+nbr_pid_compare(const struct nbr *a, const struct nbr *b)
{
return (a->peerid - b->peerid);
}
if ((nbr = calloc(1, sizeof(*nbr))) == NULL)
fatal(__func__);
- RB_INIT(&nbr->adj_tree);
+ RB_INIT(nbr_adj_head, &nbr->adj_tree);
nbr->state = NBR_STA_PRESENT;
nbr->peerid = 0;
nbr->af = af;
void
nbr_del(struct nbr *nbr)
{
+ struct adj *adj;
+
log_debug("%s: lsr-id %s", __func__, inet_ntoa(nbr->id));
nbr_fsm(nbr, NBR_EVT_CLOSE_SESSION);
mapping_list_clr(&nbr->release_list);
mapping_list_clr(&nbr->abortreq_list);
+ while (!RB_EMPTY(nbr_adj_head, &nbr->adj_tree)) {
+ adj = RB_ROOT(nbr_adj_head, &nbr->adj_tree);
+
+ adj->nbr = NULL;
+ RB_REMOVE(nbr_adj_head, &nbr->adj_tree, adj);
+ }
+
if (nbr->peerid)
RB_REMOVE(nbr_pid_head, &nbrs_by_pid, nbr);
RB_REMOVE(nbr_id_head, &nbrs_by_id, nbr);
int
nbr_establish_connection(struct nbr *nbr)
{
- struct sockaddr_storage local_sa;
- struct sockaddr_storage remote_sa;
+ union sockunion local_su;
+ union sockunion remote_su;
struct adj *adj;
struct nbr_params *nbrp;
#ifdef __OpenBSD__
#endif
}
- memcpy(&local_sa, addr2sa(nbr->af, &nbr->laddr, 0), sizeof(local_sa));
- memcpy(&remote_sa, addr2sa(nbr->af, &nbr->raddr, LDP_PORT),
- sizeof(local_sa));
+ addr2sa(nbr->af, &nbr->laddr, 0, &local_su);
+ addr2sa(nbr->af, &nbr->raddr, LDP_PORT, &remote_su);
if (nbr->af == AF_INET6 && nbr->raddr_scope)
- addscope((struct sockaddr_in6 *)&remote_sa, nbr->raddr_scope);
+ addscope(&remote_su.sin6, nbr->raddr_scope);
- if (bind(nbr->fd, (struct sockaddr *)&local_sa,
- sockaddr_len((struct sockaddr *)&local_sa)) == -1) {
+ if (bind(nbr->fd, &local_su.sa, sockaddr_len(&local_su.sa)) == -1) {
log_warn("%s: error while binding socket to %s", __func__,
- log_sockaddr((struct sockaddr *)&local_sa));
+ log_sockaddr(&local_su.sa));
close(nbr->fd);
return (-1);
}
send_hello(adj->source.type, adj->source.link.ia,
adj->source.target);
- if (connect(nbr->fd, (struct sockaddr *)&remote_sa,
- sockaddr_len((struct sockaddr *)&remote_sa)) == -1) {
+ if (connect(nbr->fd, &remote_su.sa, sockaddr_len(&remote_su.sa))
+ == -1) {
if (errno == EINPROGRESS) {
thread_add_write(master, nbr_connect_cb, nbr, nbr->fd,
&nbr->ev_connect);
return (0);
}
log_warn("%s: error while connecting to %s", __func__,
- log_sockaddr((struct sockaddr *)&remote_sa));
+ log_sockaddr(&remote_su.sa));
close(nbr->fd);
return (-1);
}
}
static __inline int
-nbr_params_compare(struct nbr_params *a, struct nbr_params *b)
+nbr_params_compare(const struct nbr_params *a, const struct nbr_params *b)
{
return (ntohl(a->lsr_id.s_addr) - ntohl(b->lsr_id.s_addr));
}