mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-07-25 13:27:03 +00:00
Merge pull request #675 from opensourcerouting/ldpd-cherry-picks
ldpd: cherry-pick fixes from master to stable/3.0
This commit is contained in:
commit
f46f475631
@ -16,7 +16,7 @@ EXTRA_DIST += ldp_vty.xml
|
||||
libldp_a_SOURCES = \
|
||||
accept.c address.c adjacency.c control.c hello.c init.c interface.c \
|
||||
keepalive.c l2vpn.c labelmapping.c lde.c lde_lib.c ldpd.c \
|
||||
ldpe.c log.c neighbor.c notification.c packet.c pfkey.c \
|
||||
ldpe.c log.c logmsg.c neighbor.c notification.c packet.c pfkey.c \
|
||||
socket.c util.c ldp_vty_cmds.c ldp_vty_conf.c ldp_vty_exec.c \
|
||||
ldp_debug.c ldp_zebra.c
|
||||
|
||||
|
@ -29,6 +29,8 @@ static __inline int adj_compare(struct adj *, struct adj *);
|
||||
static int adj_itimer(struct thread *);
|
||||
static __inline int tnbr_compare(struct tnbr *, struct tnbr *);
|
||||
static void tnbr_del(struct ldpd_conf *, struct tnbr *);
|
||||
static void tnbr_start(struct tnbr *);
|
||||
static void tnbr_stop(struct tnbr *);
|
||||
static int tnbr_hello_timer(struct thread *);
|
||||
static void tnbr_start_hello_timer(struct tnbr *);
|
||||
static void tnbr_stop_hello_timer(struct tnbr *);
|
||||
@ -245,9 +247,7 @@ tnbr_new(int af, union ldpd_addr *addr)
|
||||
static void
|
||||
tnbr_del(struct ldpd_conf *xconf, struct tnbr *tnbr)
|
||||
{
|
||||
tnbr_stop_hello_timer(tnbr);
|
||||
if (tnbr->adj)
|
||||
adj_del(tnbr->adj, S_SHUTDOWN);
|
||||
tnbr_stop(tnbr);
|
||||
RB_REMOVE(tnbr_head, &xconf->tnbr_tree, tnbr);
|
||||
free(tnbr);
|
||||
}
|
||||
@ -273,6 +273,23 @@ tnbr_check(struct ldpd_conf *xconf, struct tnbr *tnbr)
|
||||
return (tnbr);
|
||||
}
|
||||
|
||||
static void
|
||||
tnbr_start(struct tnbr *tnbr)
|
||||
{
|
||||
send_hello(HELLO_TARGETED, NULL, tnbr);
|
||||
tnbr_start_hello_timer(tnbr);
|
||||
tnbr->state = TNBR_STA_ACTIVE;
|
||||
}
|
||||
|
||||
static void
|
||||
tnbr_stop(struct tnbr *tnbr)
|
||||
{
|
||||
tnbr_stop_hello_timer(tnbr);
|
||||
if (tnbr->adj)
|
||||
adj_del(tnbr->adj, S_SHUTDOWN);
|
||||
tnbr->state = TNBR_STA_DOWN;
|
||||
}
|
||||
|
||||
void
|
||||
tnbr_update(struct tnbr *tnbr)
|
||||
{
|
||||
@ -292,16 +309,12 @@ tnbr_update(struct tnbr *tnbr)
|
||||
if (!socket_ok || !rtr_id_ok)
|
||||
return;
|
||||
|
||||
tnbr->state = TNBR_STA_ACTIVE;
|
||||
send_hello(HELLO_TARGETED, NULL, tnbr);
|
||||
|
||||
tnbr_start_hello_timer(tnbr);
|
||||
tnbr_start(tnbr);
|
||||
} else if (tnbr->state == TNBR_STA_ACTIVE) {
|
||||
if (socket_ok && rtr_id_ok)
|
||||
return;
|
||||
|
||||
tnbr->state = TNBR_STA_DOWN;
|
||||
tnbr_stop_hello_timer(tnbr);
|
||||
tnbr_stop(tnbr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -37,7 +37,7 @@ struct ctl_conns ctl_conns;
|
||||
static int control_fd;
|
||||
|
||||
int
|
||||
control_init(void)
|
||||
control_init(char *path)
|
||||
{
|
||||
struct sockaddr_un s_un;
|
||||
int fd;
|
||||
@ -51,28 +51,28 @@ control_init(void)
|
||||
|
||||
memset(&s_un, 0, sizeof(s_un));
|
||||
s_un.sun_family = AF_UNIX;
|
||||
strlcpy(s_un.sun_path, ctl_sock_path, sizeof(s_un.sun_path));
|
||||
strlcpy(s_un.sun_path, path, sizeof(s_un.sun_path));
|
||||
|
||||
if (unlink(ctl_sock_path) == -1)
|
||||
if (unlink(path) == -1)
|
||||
if (errno != ENOENT) {
|
||||
log_warn("%s: unlink %s", __func__, ctl_sock_path);
|
||||
log_warn("%s: unlink %s", __func__, path);
|
||||
close(fd);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
old_umask = umask(S_IXUSR|S_IXGRP|S_IWOTH|S_IROTH|S_IXOTH);
|
||||
if (bind(fd, (struct sockaddr *)&s_un, sizeof(s_un)) == -1) {
|
||||
log_warn("%s: bind: %s", __func__, ctl_sock_path);
|
||||
log_warn("%s: bind: %s", __func__, path);
|
||||
close(fd);
|
||||
umask(old_umask);
|
||||
return (-1);
|
||||
}
|
||||
umask(old_umask);
|
||||
|
||||
if (chmod(ctl_sock_path, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) == -1) {
|
||||
if (chmod(path, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP) == -1) {
|
||||
log_warn("%s: chmod", __func__);
|
||||
close(fd);
|
||||
(void)unlink(ctl_sock_path);
|
||||
(void)unlink(path);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@ -93,11 +93,11 @@ control_listen(void)
|
||||
}
|
||||
|
||||
void
|
||||
control_cleanup(void)
|
||||
control_cleanup(char *path)
|
||||
{
|
||||
accept_del(control_fd);
|
||||
close(control_fd);
|
||||
unlink(ctl_sock_path);
|
||||
unlink(path);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
|
@ -29,9 +29,9 @@ TAILQ_HEAD(ctl_conns, ctl_conn);
|
||||
|
||||
extern struct ctl_conns ctl_conns;
|
||||
|
||||
int control_init(void);
|
||||
int control_init(char *);
|
||||
int control_listen(void);
|
||||
void control_cleanup(void);
|
||||
void control_cleanup(char *);
|
||||
int control_imsg_relay(struct imsg *);
|
||||
|
||||
#endif /* _CONTROL_H_ */
|
||||
|
@ -287,8 +287,9 @@ if_start(struct iface *iface, int af)
|
||||
}
|
||||
|
||||
send_hello(HELLO_LINK, ia, NULL);
|
||||
|
||||
if_start_hello_timer(ia);
|
||||
ia->state = IF_STA_ACTIVE;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -318,9 +319,11 @@ if_reset(struct iface *iface, int af)
|
||||
if_leave_ipv6_group(iface, &global.mcast_addr_v6);
|
||||
break;
|
||||
default:
|
||||
fatalx("if_start: unknown af");
|
||||
fatalx("if_reset: unknown af");
|
||||
}
|
||||
|
||||
ia->state = IF_STA_DOWN;
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -367,14 +370,12 @@ if_update_af(struct iface_af *ia)
|
||||
!socket_ok || !rtr_id_ok)
|
||||
return;
|
||||
|
||||
ia->state = IF_STA_ACTIVE;
|
||||
if_start(ia->iface, ia->af);
|
||||
} else if (ia->state == IF_STA_ACTIVE) {
|
||||
if (ia->enabled && ia->iface->operative && addr_ok &&
|
||||
socket_ok && rtr_id_ok)
|
||||
return;
|
||||
|
||||
ia->state = IF_STA_DOWN;
|
||||
if_reset(ia->iface, ia->af);
|
||||
}
|
||||
}
|
||||
|
145
ldpd/lde.c
145
ldpd/lde.c
@ -80,10 +80,6 @@ static zebra_capabilities_t _caps_p [] =
|
||||
|
||||
static struct zebra_privs_t lde_privs =
|
||||
{
|
||||
#if defined(FRR_USER) && defined(FRR_GROUP)
|
||||
.user = FRR_USER,
|
||||
.group = FRR_GROUP,
|
||||
#endif
|
||||
#if defined(VTY_GROUP)
|
||||
.vty_group = VTY_GROUP,
|
||||
#endif
|
||||
@ -119,13 +115,6 @@ static struct quagga_signal_t lde_signals[] =
|
||||
},
|
||||
};
|
||||
|
||||
static void
|
||||
lde_sleep (void)
|
||||
{
|
||||
sleep(1);
|
||||
if (lde_signals[0].caught || lde_signals[1].caught)
|
||||
lde_shutdown();
|
||||
}
|
||||
struct zclient *zclient_sync = NULL;
|
||||
static void
|
||||
zclient_sync_init(u_short instance)
|
||||
@ -137,44 +126,30 @@ zclient_sync_init(u_short instance)
|
||||
zclient_sync->redist_default = ZEBRA_ROUTE_LDP;
|
||||
zclient_sync->instance = instance;
|
||||
while (zclient_socket_connect (zclient_sync) < 0) {
|
||||
fprintf(stderr, "Error connecting synchronous zclient!\n");
|
||||
lde_sleep();
|
||||
log_warnx("Error connecting synchronous zclient!");
|
||||
sleep(1);
|
||||
}
|
||||
/* make socket non-blocking */
|
||||
sock_set_nonblock(zclient_sync->sock);
|
||||
|
||||
/* Connect to label manager */
|
||||
while (lm_label_manager_connect (zclient_sync) != 0) {
|
||||
fprintf(stderr, "Error connecting to label manager!\n");
|
||||
lde_sleep();
|
||||
log_warnx("Error connecting to label manager!");
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
/* label decision engine */
|
||||
void
|
||||
lde(const char *user, const char *group, u_short instance)
|
||||
lde(void)
|
||||
{
|
||||
struct thread thread;
|
||||
struct timeval now;
|
||||
|
||||
ldeconf = config_new_empty();
|
||||
|
||||
#ifdef HAVE_SETPROCTITLE
|
||||
setproctitle("label decision engine");
|
||||
#endif
|
||||
ldpd_process = PROC_LDE_ENGINE;
|
||||
|
||||
/* drop privileges */
|
||||
if (user)
|
||||
lde_privs.user = user;
|
||||
if (group)
|
||||
lde_privs.group = group;
|
||||
zprivs_init(&lde_privs);
|
||||
|
||||
#ifdef HAVE_PLEDGE
|
||||
if (pledge("stdio recvfd unix", NULL) == -1)
|
||||
fatal("pledge");
|
||||
#endif
|
||||
log_procname = log_procnames[PROC_LDE_ENGINE];
|
||||
|
||||
master = thread_master_create();
|
||||
|
||||
@ -194,27 +169,44 @@ lde(const char *user, const char *group, u_short instance)
|
||||
fatal(NULL);
|
||||
imsg_init(&iev_main_sync->ibuf, LDPD_FD_SYNC);
|
||||
|
||||
/* start the LIB garbage collector */
|
||||
lde_gc_start_timer();
|
||||
|
||||
gettimeofday(&now, NULL);
|
||||
global.uptime = now.tv_sec;
|
||||
|
||||
/* Init synchronous zclient and label list */
|
||||
zclient_sync_init(instance);
|
||||
lde_label_list_init();
|
||||
/* create base configuration */
|
||||
ldeconf = config_new_empty();
|
||||
|
||||
/* Fetch next active thread. */
|
||||
while (thread_fetch(master, &thread))
|
||||
thread_call(&thread);
|
||||
}
|
||||
|
||||
void
|
||||
lde_init(struct ldpd_init *init)
|
||||
{
|
||||
/* drop privileges */
|
||||
lde_privs.user = init->user;
|
||||
lde_privs.group = init->group;
|
||||
zprivs_init(&lde_privs);
|
||||
|
||||
#ifdef HAVE_PLEDGE
|
||||
if (pledge("stdio recvfd unix", NULL) == -1)
|
||||
fatal("pledge");
|
||||
#endif
|
||||
|
||||
/* start the LIB garbage collector */
|
||||
lde_gc_start_timer();
|
||||
|
||||
/* Init synchronous zclient and label list */
|
||||
zclient_serv_path_set(init->zclient_serv_path);
|
||||
zclient_sync_init(init->instance);
|
||||
lde_label_list_init();
|
||||
}
|
||||
|
||||
static void
|
||||
lde_shutdown(void)
|
||||
{
|
||||
/* close pipes */
|
||||
msgbuf_clear(&iev_ldpe->ibuf.w);
|
||||
close(iev_ldpe->ibuf.fd);
|
||||
if (iev_ldpe) {
|
||||
msgbuf_clear(&iev_ldpe->ibuf.w);
|
||||
close(iev_ldpe->ibuf.fd);
|
||||
}
|
||||
msgbuf_clear(&iev_main->ibuf.w);
|
||||
close(iev_main->ibuf.fd);
|
||||
msgbuf_clear(&iev_main_sync->ibuf.w);
|
||||
@ -226,7 +218,8 @@ lde_shutdown(void)
|
||||
|
||||
config_clear(ldeconf);
|
||||
|
||||
free(iev_ldpe);
|
||||
if (iev_ldpe)
|
||||
free(iev_ldpe);
|
||||
free(iev_main);
|
||||
free(iev_main_sync);
|
||||
|
||||
@ -241,6 +234,13 @@ lde_imsg_compose_parent(int type, pid_t pid, void *data, uint16_t datalen)
|
||||
return (imsg_compose_event(iev_main, type, 0, pid, -1, data, datalen));
|
||||
}
|
||||
|
||||
void
|
||||
lde_imsg_compose_parent_sync(int type, pid_t pid, void *data, uint16_t datalen)
|
||||
{
|
||||
imsg_compose_event(iev_main_sync, type, 0, pid, -1, data, datalen);
|
||||
imsg_flush(&iev_main_sync->ibuf);
|
||||
}
|
||||
|
||||
int
|
||||
lde_imsg_compose_ldpe(int type, uint32_t peerid, pid_t pid, void *data,
|
||||
uint16_t datalen)
|
||||
@ -552,6 +552,14 @@ lde_dispatch_parent(struct thread *thread)
|
||||
iev_ldpe->handler_write = ldp_write_handler;
|
||||
iev_ldpe->ev_write = NULL;
|
||||
break;
|
||||
case IMSG_INIT:
|
||||
if (imsg.hdr.len != IMSG_HEADER_SIZE +
|
||||
sizeof(struct ldpd_init))
|
||||
fatalx("INIT imsg with wrong len");
|
||||
|
||||
memcpy(&init, imsg.data, sizeof(init));
|
||||
lde_init(&init);
|
||||
break;
|
||||
case IMSG_RECONF_CONF:
|
||||
if ((nconf = malloc(sizeof(struct ldpd_conf))) ==
|
||||
NULL)
|
||||
@ -903,10 +911,23 @@ lde_map2fec(struct map *map, struct in_addr lsr_id, struct fec *fec)
|
||||
void
|
||||
lde_send_labelmapping(struct lde_nbr *ln, struct fec_node *fn, int single)
|
||||
{
|
||||
struct lde_req *lre;
|
||||
struct lde_map *me;
|
||||
struct map map;
|
||||
struct l2vpn_pw *pw;
|
||||
struct lde_wdraw *lw;
|
||||
struct lde_map *me;
|
||||
struct lde_req *lre;
|
||||
struct map map;
|
||||
struct l2vpn_pw *pw;
|
||||
|
||||
/*
|
||||
* We shouldn't send a new label mapping if we have a pending
|
||||
* label release to receive. In this case, schedule to send a
|
||||
* label mapping as soon as a label release is received.
|
||||
*/
|
||||
lw = (struct lde_wdraw *)fec_find(&ln->sent_wdraw, &fn->fec);
|
||||
if (lw) {
|
||||
if (!fec_find(&ln->sent_map_pending, &fn->fec))
|
||||
lde_map_pending_add(ln, fn);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function skips SL.1 - 3 and SL.9 - 14 because the label
|
||||
@ -1212,6 +1233,7 @@ lde_nbr_new(uint32_t peerid, struct lde_nbr *new)
|
||||
ln->peerid = peerid;
|
||||
fec_init(&ln->recv_map);
|
||||
fec_init(&ln->sent_map);
|
||||
fec_init(&ln->sent_map_pending);
|
||||
fec_init(&ln->recv_req);
|
||||
fec_init(&ln->sent_req);
|
||||
fec_init(&ln->sent_wdraw);
|
||||
@ -1267,6 +1289,7 @@ lde_nbr_del(struct lde_nbr *ln)
|
||||
|
||||
fec_clear(&ln->recv_map, lde_map_free);
|
||||
fec_clear(&ln->sent_map, lde_map_free);
|
||||
fec_clear(&ln->sent_map_pending, free);
|
||||
fec_clear(&ln->recv_req, free);
|
||||
fec_clear(&ln->sent_req, free);
|
||||
fec_clear(&ln->sent_wdraw, free);
|
||||
@ -1417,6 +1440,30 @@ lde_map_free(void *ptr)
|
||||
free(map);
|
||||
}
|
||||
|
||||
struct fec *
|
||||
lde_map_pending_add(struct lde_nbr *ln, struct fec_node *fn)
|
||||
{
|
||||
struct fec *map;
|
||||
|
||||
map = calloc(1, sizeof(*map));
|
||||
if (map == NULL)
|
||||
fatal(__func__);
|
||||
|
||||
*map = fn->fec;
|
||||
if (fec_insert(&ln->sent_map_pending, map))
|
||||
log_warnx("failed to add %s to sent map (pending)",
|
||||
log_fec(map));
|
||||
|
||||
return (map);
|
||||
}
|
||||
|
||||
void
|
||||
lde_map_pending_del(struct lde_nbr *ln, struct fec *map)
|
||||
{
|
||||
fec_remove(&ln->sent_map_pending, map);
|
||||
free(map);
|
||||
}
|
||||
|
||||
struct lde_req *
|
||||
lde_req_add(struct lde_nbr *ln, struct fec *fec, int sent)
|
||||
{
|
||||
@ -1613,8 +1660,8 @@ lde_label_list_init(void)
|
||||
|
||||
/* get first chunk */
|
||||
while (lde_get_label_chunk () != 0) {
|
||||
fprintf(stderr, "Error getting first label chunk!\n");
|
||||
lde_sleep();
|
||||
log_warnx("Error getting first label chunk!");
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,6 +95,7 @@ struct lde_nbr {
|
||||
struct fec_tree sent_req;
|
||||
struct fec_tree recv_map;
|
||||
struct fec_tree sent_map;
|
||||
struct fec_tree sent_map_pending;
|
||||
struct fec_tree sent_wdraw;
|
||||
TAILQ_HEAD(, lde_addr) addr_list;
|
||||
};
|
||||
@ -139,8 +140,10 @@ extern struct nbr_tree lde_nbrs;
|
||||
extern struct thread *gc_timer;
|
||||
|
||||
/* lde.c */
|
||||
void lde(const char *, const char *, u_short instance);
|
||||
void lde(void);
|
||||
void lde_init(struct ldpd_init *);
|
||||
int lde_imsg_compose_parent(int, pid_t, void *, uint16_t);
|
||||
void lde_imsg_compose_parent_sync(int, pid_t, void *, uint16_t);
|
||||
int lde_imsg_compose_ldpe(int, uint32_t, pid_t, void *, uint16_t);
|
||||
int lde_acl_check(char *, int, union ldpd_addr *, uint8_t);
|
||||
uint32_t lde_update_label(struct fec_node *);
|
||||
@ -169,6 +172,8 @@ struct lde_nbr *lde_nbr_find_by_lsrid(struct in_addr);
|
||||
struct lde_nbr *lde_nbr_find_by_addr(int, union ldpd_addr *);
|
||||
struct lde_map *lde_map_add(struct lde_nbr *, struct fec_node *, int);
|
||||
void lde_map_del(struct lde_nbr *, struct lde_map *, int);
|
||||
struct fec *lde_map_pending_add(struct lde_nbr *, struct fec_node *);
|
||||
void lde_map_pending_del(struct lde_nbr *, struct fec *);
|
||||
struct lde_req *lde_req_add(struct lde_nbr *, struct fec *, int);
|
||||
void lde_req_del(struct lde_nbr *, struct lde_req *, int);
|
||||
struct lde_wdraw *lde_wdraw_add(struct lde_nbr *, struct fec_node *);
|
||||
|
@ -383,20 +383,23 @@ lde_kernel_update(struct fec *fec)
|
||||
if (LIST_EMPTY(&fn->nexthops)) {
|
||||
RB_FOREACH(ln, nbr_tree, &lde_nbrs)
|
||||
lde_send_labelwithdraw(ln, fn, NULL, NULL);
|
||||
fn->local_label = NO_LABEL;
|
||||
fn->data = NULL;
|
||||
|
||||
/*
|
||||
* Do not deallocate the local label now, do that only in the
|
||||
* LIB garbage collector. This will prevent ldpd from changing
|
||||
* the input label of some prefixes too often when running on
|
||||
* an unstable network. Also, restart the garbage collector
|
||||
* timer so that labels are deallocated only when the network
|
||||
* is stabilized.
|
||||
*/
|
||||
lde_gc_start_timer();
|
||||
} else {
|
||||
uint32_t previous_label;
|
||||
|
||||
previous_label = fn->local_label;
|
||||
fn->local_label = lde_update_label(fn);
|
||||
|
||||
if (fn->local_label != NO_LABEL &&
|
||||
fn->local_label != previous_label) {
|
||||
if (fn->local_label != NO_LABEL && RB_EMPTY(&fn->upstream))
|
||||
/* FEC.1: perform lsr label distribution procedure */
|
||||
RB_FOREACH(ln, nbr_tree, &lde_nbrs)
|
||||
lde_send_labelmapping(ln, fn, 1);
|
||||
}
|
||||
}
|
||||
|
||||
LIST_FOREACH(fnh, &fn->nexthops, entry) {
|
||||
@ -659,6 +662,7 @@ lde_check_release(struct map *map, struct lde_nbr *ln)
|
||||
struct fec_node *fn;
|
||||
struct lde_wdraw *lw;
|
||||
struct lde_map *me;
|
||||
struct fec *pending_map;
|
||||
|
||||
/* wildcard label release */
|
||||
if (map->type == MAP_TYPE_WILDCARD ||
|
||||
@ -674,17 +678,24 @@ lde_check_release(struct map *map, struct lde_nbr *ln)
|
||||
if (fn == NULL)
|
||||
return;
|
||||
|
||||
/* LRl.6: check sent map list and remove it if available */
|
||||
me = (struct lde_map *)fec_find(&ln->sent_map, &fn->fec);
|
||||
if (me && (map->label == NO_LABEL || map->label == me->map.label))
|
||||
lde_map_del(ln, me, 1);
|
||||
|
||||
/* LRl.3: first check if we have a pending withdraw running */
|
||||
lw = (struct lde_wdraw *)fec_find(&ln->sent_wdraw, &fn->fec);
|
||||
if (lw && (map->label == NO_LABEL || map->label == lw->label)) {
|
||||
/* LRl.4: delete record of outstanding label withdraw */
|
||||
lde_wdraw_del(ln, lw);
|
||||
}
|
||||
|
||||
/* LRl.6: check sent map list and remove it if available */
|
||||
me = (struct lde_map *)fec_find(&ln->sent_map, &fn->fec);
|
||||
if (me && (map->label == NO_LABEL || map->label == me->map.label))
|
||||
lde_map_del(ln, me, 1);
|
||||
/* send pending label mapping if any */
|
||||
pending_map = fec_find(&ln->sent_map_pending, &fn->fec);
|
||||
if (pending_map) {
|
||||
lde_send_labelmapping(ln, fn, 1);
|
||||
lde_map_pending_del(ln, pending_map);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* LRl.11 - 13 are unnecessary since we remove the label from
|
||||
@ -699,6 +710,7 @@ lde_check_release_wcard(struct map *map, struct lde_nbr *ln)
|
||||
struct fec_node *fn;
|
||||
struct lde_wdraw *lw;
|
||||
struct lde_map *me;
|
||||
struct fec *pending_map;
|
||||
|
||||
RB_FOREACH(f, fec_tree, &ft) {
|
||||
fn = (struct fec_node *)f;
|
||||
@ -708,17 +720,24 @@ lde_check_release_wcard(struct map *map, struct lde_nbr *ln)
|
||||
if (lde_wildcard_apply(map, &fn->fec, me) == 0)
|
||||
continue;
|
||||
|
||||
/* LRl.6: check sent map list and remove it if available */
|
||||
if (me &&
|
||||
(map->label == NO_LABEL || map->label == me->map.label))
|
||||
lde_map_del(ln, me, 1);
|
||||
|
||||
/* LRl.3: first check if we have a pending withdraw running */
|
||||
lw = (struct lde_wdraw *)fec_find(&ln->sent_wdraw, &fn->fec);
|
||||
if (lw && (map->label == NO_LABEL || map->label == lw->label)) {
|
||||
/* LRl.4: delete record of outstanding lbl withdraw */
|
||||
lde_wdraw_del(ln, lw);
|
||||
}
|
||||
|
||||
/* LRl.6: check sent map list and remove it if available */
|
||||
if (me &&
|
||||
(map->label == NO_LABEL || map->label == me->map.label))
|
||||
lde_map_del(ln, me, 1);
|
||||
/* send pending label mapping if any */
|
||||
pending_map = fec_find(&ln->sent_map_pending, &fn->fec);
|
||||
if (pending_map) {
|
||||
lde_send_labelmapping(ln, fn, 1);
|
||||
lde_map_pending_del(ln, pending_map);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* LRl.11 - 13 are unnecessary since we remove the label from
|
||||
|
@ -517,8 +517,7 @@ show_nbr_msg(struct vty *vty, struct imsg *imsg, struct show_params *params)
|
||||
nbr_state_name(nbr->nbr_state), addr);
|
||||
if (strlen(addr) > 15)
|
||||
vty_out(vty, "%s%48s", VTY_NEWLINE, " ");
|
||||
vty_out(vty, " %8s%s", nbr->uptime == 0 ? "-" :
|
||||
log_time(nbr->uptime), VTY_NEWLINE);
|
||||
vty_out(vty, " %8s%s", log_time(nbr->uptime), VTY_NEWLINE);
|
||||
break;
|
||||
case IMSG_CTL_END:
|
||||
return (1);
|
||||
@ -909,6 +908,7 @@ show_nbr_capabilities_msg(struct vty *vty, struct imsg *imsg, struct show_params
|
||||
vty_out(vty, "Peer LDP Identifier: %s:0%s", inet_ntoa(nbr->id),
|
||||
VTY_NEWLINE);
|
||||
show_nbr_capabilities(vty, nbr);
|
||||
vty_out(vty, "%s", VTY_NEWLINE);
|
||||
break;
|
||||
case IMSG_CTL_END:
|
||||
vty_out(vty, "%s", VTY_NEWLINE);
|
||||
|
@ -360,6 +360,7 @@ ldp_zebra_read_route(int command, struct zclient *zclient, zebra_size_t length,
|
||||
struct kroute kr;
|
||||
int nhnum = 0, nhlen;
|
||||
size_t nhmark;
|
||||
int add = 0;
|
||||
|
||||
memset(&kr, 0, sizeof(kr));
|
||||
s = zclient->ibuf;
|
||||
@ -426,21 +427,14 @@ ldp_zebra_read_route(int command, struct zclient *zclient, zebra_size_t length,
|
||||
if (CHECK_FLAG(message_flags, ZAPI_MESSAGE_NEXTHOP))
|
||||
stream_set_getp(s, nhmark);
|
||||
|
||||
if (nhnum == 0) {
|
||||
switch (command) {
|
||||
case ZEBRA_REDISTRIBUTE_IPV4_ADD:
|
||||
case ZEBRA_REDISTRIBUTE_IPV6_ADD:
|
||||
return (0);
|
||||
case ZEBRA_REDISTRIBUTE_IPV4_DEL:
|
||||
case ZEBRA_REDISTRIBUTE_IPV6_DEL:
|
||||
debug_zebra_in("route delete %s/%d (%s)",
|
||||
log_addr(kr.af, &kr.prefix), kr.prefixlen,
|
||||
zebra_route_string(type));
|
||||
break;
|
||||
default:
|
||||
fatalx("ldp_zebra_read_route: unknown command");
|
||||
}
|
||||
}
|
||||
if (command == ZEBRA_REDISTRIBUTE_IPV4_ADD ||
|
||||
command == ZEBRA_REDISTRIBUTE_IPV6_ADD)
|
||||
add = 1;
|
||||
|
||||
if (nhnum == 0)
|
||||
debug_zebra_in("route %s %s/%d (%s)", (add) ? "add" : "delete",
|
||||
log_addr(kr.af, &kr.prefix), kr.prefixlen,
|
||||
zebra_route_string(type));
|
||||
|
||||
/* loop through all the nexthops */
|
||||
for (; nhnum > 0; nhnum--) {
|
||||
@ -457,19 +451,14 @@ ldp_zebra_read_route(int command, struct zclient *zclient, zebra_size_t length,
|
||||
stream_getc(s); /* ifindex_num, unused. */
|
||||
kr.ifindex = stream_getl(s);
|
||||
|
||||
switch (command) {
|
||||
case ZEBRA_REDISTRIBUTE_IPV4_ADD:
|
||||
case ZEBRA_REDISTRIBUTE_IPV6_ADD:
|
||||
debug_zebra_in("route add %s/%d nexthop %s "
|
||||
"ifindex %u (%s)", log_addr(kr.af, &kr.prefix),
|
||||
kr.prefixlen, log_addr(kr.af, &kr.nexthop),
|
||||
kr.ifindex, zebra_route_string(type));
|
||||
debug_zebra_in("route %s %s/%d nexthop %s ifindex %u (%s)",
|
||||
(add) ? "add" : "delete", log_addr(kr.af, &kr.prefix),
|
||||
kr.prefixlen, log_addr(kr.af, &kr.nexthop), kr.ifindex,
|
||||
zebra_route_string(type));
|
||||
|
||||
if (add)
|
||||
main_imsg_compose_lde(IMSG_NETWORK_ADD, 0, &kr,
|
||||
sizeof(kr));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
main_imsg_compose_lde(IMSG_NETWORK_UPDATE, 0, &kr, sizeof(kr));
|
||||
|
78
ldpd/ldpd.c
78
ldpd/ldpd.c
@ -44,8 +44,7 @@
|
||||
#include "libfrr.h"
|
||||
|
||||
static void ldpd_shutdown(void);
|
||||
static pid_t start_child(enum ldpd_process, char *, int, int,
|
||||
const char *, const char *, const char *, const char *);
|
||||
static pid_t start_child(enum ldpd_process, char *, int, int);
|
||||
static int main_dispatch_ldpe(struct thread *);
|
||||
static int main_dispatch_lde(struct thread *);
|
||||
static int main_imsg_send_ipc_sockets(struct imsgbuf *,
|
||||
@ -77,6 +76,7 @@ DEFINE_QOBJ_TYPE(l2vpn)
|
||||
DEFINE_QOBJ_TYPE(ldpd_conf)
|
||||
|
||||
struct ldpd_global global;
|
||||
struct ldpd_init init;
|
||||
struct ldpd_conf *ldpd_conf, *vty_conf;
|
||||
|
||||
static struct imsgev *iev_ldpe, *iev_ldpe_sync;
|
||||
@ -200,14 +200,10 @@ main(int argc, char *argv[])
|
||||
int lflag = 0, eflag = 0;
|
||||
int pipe_parent2ldpe[2], pipe_parent2ldpe_sync[2];
|
||||
int pipe_parent2lde[2], pipe_parent2lde_sync[2];
|
||||
char *ctl_sock_custom_path = NULL;
|
||||
char *ctl_sock_name;
|
||||
const char *user = NULL;
|
||||
const char *group = NULL;
|
||||
u_short instance = 0;
|
||||
const char *instance_char = NULL;
|
||||
|
||||
ldpd_process = PROC_MAIN;
|
||||
log_procname = log_procnames[ldpd_process];
|
||||
|
||||
saved_argv0 = argv[0];
|
||||
if (saved_argv0 == NULL)
|
||||
@ -241,17 +237,14 @@ main(int argc, char *argv[])
|
||||
* sensible config
|
||||
*/
|
||||
ctl_sock_name = (char *)LDPD_SOCKET;
|
||||
ctl_sock_custom_path = optarg;
|
||||
strlcpy(ctl_sock_path, ctl_sock_custom_path,
|
||||
sizeof(ctl_sock_path));
|
||||
strlcpy(ctl_sock_path, optarg, sizeof(ctl_sock_path));
|
||||
strlcat(ctl_sock_path, "/", sizeof(ctl_sock_path));
|
||||
strlcat(ctl_sock_path, ctl_sock_name,
|
||||
sizeof(ctl_sock_path));
|
||||
break;
|
||||
case 'n':
|
||||
instance = atoi(optarg);
|
||||
instance_char = optarg;
|
||||
if (instance < 1)
|
||||
init.instance = atoi(optarg);
|
||||
if (init.instance < 1)
|
||||
exit(0);
|
||||
break;
|
||||
case 'L':
|
||||
@ -266,8 +259,11 @@ main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
user = ldpd_privs.user;
|
||||
group = ldpd_privs.group;
|
||||
strlcpy(init.user, ldpd_privs.user, sizeof(init.user));
|
||||
strlcpy(init.group, ldpd_privs.group, sizeof(init.group));
|
||||
strlcpy(init.ctl_sock_path, ctl_sock_path, sizeof(init.ctl_sock_path));
|
||||
strlcpy(init.zclient_serv_path, zclient_serv_path_get(),
|
||||
sizeof(init.zclient_serv_path));
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
@ -281,14 +277,14 @@ main(int argc, char *argv[])
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (lflag)
|
||||
lde(user, group, instance);
|
||||
else if (eflag)
|
||||
ldpe(user, group, ctl_sock_path);
|
||||
|
||||
openzlog(ldpd_di.progname, "LDP", 0,
|
||||
LOG_CONS | LOG_NDELAY | LOG_PID, LOG_DAEMON);
|
||||
|
||||
if (lflag)
|
||||
lde();
|
||||
else if (eflag)
|
||||
ldpe();
|
||||
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe_parent2ldpe) == -1)
|
||||
fatal("socketpair");
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC,
|
||||
@ -316,11 +312,9 @@ main(int argc, char *argv[])
|
||||
|
||||
/* start children */
|
||||
lde_pid = start_child(PROC_LDE_ENGINE, saved_argv0,
|
||||
pipe_parent2lde[1], pipe_parent2lde_sync[1],
|
||||
user, group, ctl_sock_custom_path, instance_char);
|
||||
pipe_parent2lde[1], pipe_parent2lde_sync[1]);
|
||||
ldpe_pid = start_child(PROC_LDP_ENGINE, saved_argv0,
|
||||
pipe_parent2ldpe[1], pipe_parent2ldpe_sync[1],
|
||||
user, group, ctl_sock_custom_path, instance_char);
|
||||
pipe_parent2ldpe[1], pipe_parent2ldpe_sync[1]);
|
||||
|
||||
/* drop privileges */
|
||||
zprivs_init(&ldpd_privs);
|
||||
@ -388,6 +382,7 @@ main(int argc, char *argv[])
|
||||
|
||||
if (main_imsg_send_ipc_sockets(&iev_ldpe->ibuf, &iev_lde->ibuf))
|
||||
fatal("could not establish imsg links");
|
||||
main_imsg_compose_both(IMSG_INIT, &init, sizeof(init));
|
||||
main_imsg_compose_both(IMSG_DEBUG_UPDATE, &ldp_debug,
|
||||
sizeof(ldp_debug));
|
||||
main_imsg_send_config(ldpd_conf);
|
||||
@ -452,11 +447,9 @@ ldpd_shutdown(void)
|
||||
}
|
||||
|
||||
static pid_t
|
||||
start_child(enum ldpd_process p, char *argv0, int fd_async, int fd_sync,
|
||||
const char *user, const char *group, const char *ctl_sock_custom_path,
|
||||
const char *instance)
|
||||
start_child(enum ldpd_process p, char *argv0, int fd_async, int fd_sync)
|
||||
{
|
||||
char *argv[13];
|
||||
char *argv[3];
|
||||
int argc = 0;
|
||||
pid_t pid;
|
||||
|
||||
@ -487,29 +480,6 @@ start_child(enum ldpd_process p, char *argv0, int fd_async, int fd_sync,
|
||||
argv[argc++] = (char *)"-E";
|
||||
break;
|
||||
}
|
||||
if (user) {
|
||||
argv[argc++] = (char *)"-u";
|
||||
argv[argc++] = (char *)user;
|
||||
}
|
||||
if (group) {
|
||||
argv[argc++] = (char *)"-g";
|
||||
argv[argc++] = (char *)group;
|
||||
}
|
||||
if (ctl_sock_custom_path) {
|
||||
argv[argc++] = (char *)"--ctl_socket";
|
||||
argv[argc++] = (char *)ctl_sock_custom_path;
|
||||
}
|
||||
/* zclient serv path */
|
||||
#ifdef HAVE_TCP_ZEBRA
|
||||
#else
|
||||
argv[argc++] = (char *)"-z";
|
||||
argv[argc++] = (char *)zclient_serv_path_get();
|
||||
#endif
|
||||
/* instance */
|
||||
if (instance) {
|
||||
argv[argc++] = (char *)"-n";
|
||||
argv[argc++] = (char *)instance;
|
||||
}
|
||||
argv[argc++] = NULL;
|
||||
|
||||
execvp(argv0, argv);
|
||||
@ -1709,8 +1679,7 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl)
|
||||
session_shutdown(nbr, S_SHUTDOWN, 0, 0);
|
||||
}
|
||||
}
|
||||
if (ldpd_process == PROC_LDE_ENGINE &&
|
||||
!reset_nbr && reinstall_pwfec)
|
||||
if (ldpd_process == PROC_LDE_ENGINE && reinstall_pwfec)
|
||||
l2vpn_pw_exit(pw);
|
||||
pw->lsr_id = xp->lsr_id;
|
||||
pw->af = xp->af;
|
||||
@ -1732,8 +1701,7 @@ merge_l2vpn(struct ldpd_conf *xconf, struct l2vpn *l2vpn, struct l2vpn *xl)
|
||||
pw->flags &= ~F_PW_STATIC_NBR_ADDR;
|
||||
if (ldpd_process == PROC_LDP_ENGINE && reinstall_tnbr)
|
||||
ldpe_l2vpn_pw_init(pw);
|
||||
if (ldpd_process == PROC_LDE_ENGINE &&
|
||||
!reset_nbr && reinstall_pwfec) {
|
||||
if (ldpd_process == PROC_LDE_ENGINE && reinstall_pwfec) {
|
||||
l2vpn->pw_type = xl->pw_type;
|
||||
l2vpn->mtu = xl->mtu;
|
||||
l2vpn_pw_init(pw);
|
||||
|
43
ldpd/ldpd.h
43
ldpd/ldpd.h
@ -147,7 +147,16 @@ enum imsg_type {
|
||||
IMSG_LOG,
|
||||
IMSG_ACL_CHECK,
|
||||
IMSG_GET_LABEL_CHUNK,
|
||||
IMSG_RELEASE_LABEL_CHUNK
|
||||
IMSG_RELEASE_LABEL_CHUNK,
|
||||
IMSG_INIT
|
||||
};
|
||||
|
||||
struct ldpd_init {
|
||||
char user[256];
|
||||
char group[256];
|
||||
char ctl_sock_path[MAXPATHLEN];
|
||||
char zclient_serv_path[MAXPATHLEN];
|
||||
u_short instance;
|
||||
};
|
||||
|
||||
union ldpd_addr {
|
||||
@ -439,6 +448,12 @@ enum ldpd_process {
|
||||
PROC_LDE_ENGINE
|
||||
} ldpd_process;
|
||||
|
||||
static const char * const log_procnames[] = {
|
||||
"parent",
|
||||
"ldpe",
|
||||
"lde"
|
||||
};
|
||||
|
||||
enum socket_type {
|
||||
LDP_SOCKET_DISC,
|
||||
LDP_SOCKET_EDISC,
|
||||
@ -504,7 +519,6 @@ struct ldpd_af_global {
|
||||
struct ldpd_global {
|
||||
int cmd_opts;
|
||||
int sighup;
|
||||
time_t uptime;
|
||||
struct in_addr rtr_id;
|
||||
struct ldpd_af_global ipv4;
|
||||
struct ldpd_af_global ipv6;
|
||||
@ -649,6 +663,7 @@ struct ctl_pw {
|
||||
|
||||
extern struct ldpd_conf *ldpd_conf, *vty_conf;
|
||||
extern struct ldpd_global global;
|
||||
extern struct ldpd_init init;
|
||||
|
||||
/* parse.y */
|
||||
struct ldpd_conf *parse_config(char *);
|
||||
@ -762,6 +777,30 @@ int sock_set_ipv6_mcast_hops(int, int);
|
||||
int sock_set_ipv6_mcast(struct iface *);
|
||||
int sock_set_ipv6_mcast_loop(int);
|
||||
|
||||
/* logmsg.h */
|
||||
struct in6_addr;
|
||||
union ldpd_addr;
|
||||
struct hello_source;
|
||||
struct fec;
|
||||
|
||||
const char *log_sockaddr(void *);
|
||||
const char *log_in6addr(const struct in6_addr *);
|
||||
const char *log_in6addr_scope(const struct in6_addr *, unsigned int);
|
||||
const char *log_addr(int, const union ldpd_addr *);
|
||||
char *log_label(uint32_t);
|
||||
const char *log_time(time_t);
|
||||
char *log_hello_src(const struct hello_source *);
|
||||
const char *log_map(const struct map *);
|
||||
const char *log_fec(const struct fec *);
|
||||
const char *af_name(int);
|
||||
const char *socket_name(int);
|
||||
const char *nbr_state_name(int);
|
||||
const char *if_state_name(int);
|
||||
const char *if_type_name(enum iface_type);
|
||||
const char *msg_name(uint16_t);
|
||||
const char *status_code_name(uint32_t);
|
||||
const char *pw_type_name(uint16_t);
|
||||
|
||||
/* quagga */
|
||||
extern struct thread_master *master;
|
||||
extern char ctl_sock_path[MAXPATHLEN];
|
||||
|
109
ldpd/ldpe.c
109
ldpd/ldpe.c
@ -66,10 +66,6 @@ static zebra_capabilities_t _caps_p [] =
|
||||
|
||||
struct zebra_privs_t ldpe_privs =
|
||||
{
|
||||
#if defined(FRR_USER) && defined(FRR_GROUP)
|
||||
.user = FRR_USER,
|
||||
.group = FRR_GROUP,
|
||||
#endif
|
||||
#if defined(VTY_GROUP)
|
||||
.vty_group = VTY_GROUP,
|
||||
#endif
|
||||
@ -103,46 +99,17 @@ static struct quagga_signal_t ldpe_signals[] =
|
||||
|
||||
/* label distribution protocol engine */
|
||||
void
|
||||
ldpe(const char *user, const char *group, const char *ctl_path)
|
||||
ldpe(void)
|
||||
{
|
||||
struct thread thread;
|
||||
|
||||
leconf = config_new_empty();
|
||||
|
||||
#ifdef HAVE_SETPROCTITLE
|
||||
setproctitle("ldp engine");
|
||||
#endif
|
||||
ldpd_process = PROC_LDP_ENGINE;
|
||||
|
||||
LIST_INIT(&global.addr_list);
|
||||
RB_INIT(&global.adj_tree);
|
||||
TAILQ_INIT(&global.pending_conns);
|
||||
if (inet_pton(AF_INET, AllRouters_v4, &global.mcast_addr_v4) != 1)
|
||||
fatal("inet_pton");
|
||||
if (inet_pton(AF_INET6, AllRouters_v6, &global.mcast_addr_v6) != 1)
|
||||
fatal("inet_pton");
|
||||
#ifdef __OpenBSD__
|
||||
global.pfkeysock = pfkey_init();
|
||||
#endif
|
||||
|
||||
/* drop privileges */
|
||||
if (user)
|
||||
ldpe_privs.user = user;
|
||||
if (group)
|
||||
ldpe_privs.group = group;
|
||||
zprivs_init(&ldpe_privs);
|
||||
|
||||
strlcpy(ctl_sock_path, ctl_path, sizeof(ctl_sock_path));
|
||||
if (control_init() == -1)
|
||||
fatalx("control socket setup failed");
|
||||
|
||||
#ifdef HAVE_PLEDGE
|
||||
if (pledge("stdio cpath inet mcast recvfd", NULL) == -1)
|
||||
fatal("pledge");
|
||||
#endif
|
||||
log_procname = log_procnames[ldpd_process];
|
||||
|
||||
master = thread_master_create();
|
||||
accept_init();
|
||||
|
||||
/* setup signal handler */
|
||||
signal_init(master, array_size(ldpe_signals), ldpe_signals);
|
||||
@ -160,7 +127,43 @@ ldpe(const char *user, const char *group, const char *ctl_path)
|
||||
fatal(NULL);
|
||||
imsg_init(&iev_main_sync->ibuf, LDPD_FD_SYNC);
|
||||
|
||||
/* create base configuration */
|
||||
leconf = config_new_empty();
|
||||
|
||||
/* Fetch next active thread. */
|
||||
while (thread_fetch(master, &thread))
|
||||
thread_call(&thread);
|
||||
}
|
||||
|
||||
void
|
||||
ldpe_init(struct ldpd_init *init)
|
||||
{
|
||||
/* drop privileges */
|
||||
ldpe_privs.user = init->user;
|
||||
ldpe_privs.group = init->group;
|
||||
zprivs_init(&ldpe_privs);
|
||||
|
||||
/* listen on ldpd control socket */
|
||||
strlcpy(ctl_sock_path, init->ctl_sock_path, sizeof(ctl_sock_path));
|
||||
if (control_init(ctl_sock_path) == -1)
|
||||
fatalx("control socket setup failed");
|
||||
TAILQ_INIT(&ctl_conns);
|
||||
control_listen();
|
||||
|
||||
#ifdef HAVE_PLEDGE
|
||||
if (pledge("stdio cpath inet mcast recvfd", NULL) == -1)
|
||||
fatal("pledge");
|
||||
#endif
|
||||
|
||||
LIST_INIT(&global.addr_list);
|
||||
RB_INIT(&global.adj_tree);
|
||||
TAILQ_INIT(&global.pending_conns);
|
||||
if (inet_pton(AF_INET, AllRouters_v4, &global.mcast_addr_v4) != 1)
|
||||
fatal("inet_pton");
|
||||
if (inet_pton(AF_INET6, AllRouters_v6, &global.mcast_addr_v6) != 1)
|
||||
fatal("inet_pton");
|
||||
#ifdef __OpenBSD__
|
||||
global.pfkeysock = pfkey_init();
|
||||
if (sysdep.no_pfkey == 0)
|
||||
pfkey_ev = thread_add_read(master, ldpe_dispatch_pfkey,
|
||||
NULL, global.pfkeysock);
|
||||
@ -174,16 +177,10 @@ ldpe(const char *user, const char *group, const char *ctl_path)
|
||||
global.ipv6.ldp_edisc_socket = -1;
|
||||
global.ipv6.ldp_session_socket = -1;
|
||||
|
||||
/* listen on ldpd control socket */
|
||||
TAILQ_INIT(&ctl_conns);
|
||||
control_listen();
|
||||
|
||||
if ((pkt_ptr = calloc(1, IBUF_READ_SIZE)) == NULL)
|
||||
fatal(__func__);
|
||||
|
||||
/* Fetch next active thread. */
|
||||
while (thread_fetch(master, &thread))
|
||||
thread_call(&thread);
|
||||
accept_init();
|
||||
}
|
||||
|
||||
static void
|
||||
@ -193,16 +190,18 @@ ldpe_shutdown(void)
|
||||
struct adj *adj;
|
||||
|
||||
/* close pipes */
|
||||
msgbuf_write(&iev_lde->ibuf.w);
|
||||
msgbuf_clear(&iev_lde->ibuf.w);
|
||||
close(iev_lde->ibuf.fd);
|
||||
if (iev_lde) {
|
||||
msgbuf_write(&iev_lde->ibuf.w);
|
||||
msgbuf_clear(&iev_lde->ibuf.w);
|
||||
close(iev_lde->ibuf.fd);
|
||||
}
|
||||
msgbuf_write(&iev_main->ibuf.w);
|
||||
msgbuf_clear(&iev_main->ibuf.w);
|
||||
close(iev_main->ibuf.fd);
|
||||
msgbuf_clear(&iev_main_sync->ibuf.w);
|
||||
close(iev_main_sync->ibuf.fd);
|
||||
|
||||
control_cleanup();
|
||||
control_cleanup(ctl_sock_path);
|
||||
config_clear(leconf);
|
||||
|
||||
#ifdef __OpenBSD__
|
||||
@ -223,7 +222,8 @@ ldpe_shutdown(void)
|
||||
adj_del(adj, S_SHUTDOWN);
|
||||
|
||||
/* clean up */
|
||||
free(iev_lde);
|
||||
if (iev_lde)
|
||||
free(iev_lde);
|
||||
free(iev_main);
|
||||
free(iev_main_sync);
|
||||
free(pkt_ptr);
|
||||
@ -239,6 +239,13 @@ ldpe_imsg_compose_parent(int type, pid_t pid, void *data, uint16_t datalen)
|
||||
return (imsg_compose_event(iev_main, type, 0, pid, -1, data, datalen));
|
||||
}
|
||||
|
||||
void
|
||||
ldpe_imsg_compose_parent_sync(int type, pid_t pid, void *data, uint16_t datalen)
|
||||
{
|
||||
imsg_compose_event(iev_main_sync, type, 0, pid, -1, data, datalen);
|
||||
imsg_flush(&iev_main_sync->ibuf);
|
||||
}
|
||||
|
||||
int
|
||||
ldpe_imsg_compose_lde(int type, uint32_t peerid, pid_t pid, void *data,
|
||||
uint16_t datalen)
|
||||
@ -351,6 +358,14 @@ ldpe_dispatch_main(struct thread *thread)
|
||||
iev_lde->handler_write = ldp_write_handler;
|
||||
iev_lde->ev_write = NULL;
|
||||
break;
|
||||
case IMSG_INIT:
|
||||
if (imsg.hdr.len != IMSG_HEADER_SIZE +
|
||||
sizeof(struct ldpd_init))
|
||||
fatalx("INIT imsg with wrong len");
|
||||
|
||||
memcpy(&init, imsg.data, sizeof(init));
|
||||
ldpe_init(&init);
|
||||
break;
|
||||
case IMSG_CLOSE_SOCKETS:
|
||||
af = imsg.hdr.peerid;
|
||||
|
||||
|
@ -195,9 +195,11 @@ int tlv_decode_fec_elm(struct nbr *, struct ldp_msg *, char *,
|
||||
uint16_t, struct map *);
|
||||
|
||||
/* ldpe.c */
|
||||
void ldpe(const char *, const char *, const char *);
|
||||
void ldpe(void);
|
||||
void ldpe_init(struct ldpd_init *);
|
||||
int ldpe_imsg_compose_parent(int, pid_t, void *,
|
||||
uint16_t);
|
||||
void ldpe_imsg_compose_parent_sync(int, pid_t, void *, uint16_t);
|
||||
int ldpe_imsg_compose_lde(int, uint32_t, pid_t, void *,
|
||||
uint16_t);
|
||||
int ldpe_acl_check(char *, int, union ldpd_addr *, uint8_t);
|
||||
|
493
ldpd/log.c
493
ldpd/log.c
@ -25,15 +25,8 @@
|
||||
|
||||
#include <lib/log.h>
|
||||
#include <lib/log_int.h>
|
||||
#include "mpls.h"
|
||||
|
||||
static const char * const procnames[] = {
|
||||
"parent",
|
||||
"ldpe",
|
||||
"lde"
|
||||
};
|
||||
|
||||
void vlog(int, const char *, va_list);
|
||||
const char *log_procname;
|
||||
|
||||
void
|
||||
logit(int pri, const char *fmt, ...)
|
||||
@ -53,11 +46,13 @@ vlog(int pri, const char *fmt, va_list ap)
|
||||
switch (ldpd_process) {
|
||||
case PROC_LDE_ENGINE:
|
||||
vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||
lde_imsg_compose_parent(IMSG_LOG, pri, buf, strlen(buf) + 1);
|
||||
lde_imsg_compose_parent_sync(IMSG_LOG, pri, buf,
|
||||
strlen(buf) + 1);
|
||||
break;
|
||||
case PROC_LDP_ENGINE:
|
||||
vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||
ldpe_imsg_compose_parent(IMSG_LOG, pri, buf, strlen(buf) + 1);
|
||||
ldpe_imsg_compose_parent_sync(IMSG_LOG, pri, buf,
|
||||
strlen(buf) + 1);
|
||||
break;
|
||||
case PROC_MAIN:
|
||||
vzlog(pri, fmt, ap);
|
||||
@ -73,16 +68,16 @@ log_warn(const char *emsg, ...)
|
||||
|
||||
/* best effort to even work in out of memory situations */
|
||||
if (emsg == NULL)
|
||||
logit(LOG_CRIT, "%s", strerror(errno));
|
||||
logit(LOG_ERR, "%s", strerror(errno));
|
||||
else {
|
||||
va_start(ap, emsg);
|
||||
|
||||
if (asprintf(&nfmt, "%s: %s", emsg, strerror(errno)) == -1) {
|
||||
/* we tried it... */
|
||||
vlog(LOG_CRIT, emsg, ap);
|
||||
logit(LOG_CRIT, "%s", strerror(errno));
|
||||
vlog(LOG_ERR, emsg, ap);
|
||||
logit(LOG_ERR, "%s", strerror(errno));
|
||||
} else {
|
||||
vlog(LOG_CRIT, nfmt, ap);
|
||||
vlog(LOG_ERR, nfmt, ap);
|
||||
free(nfmt);
|
||||
}
|
||||
va_end(ap);
|
||||
@ -95,7 +90,7 @@ log_warnx(const char *emsg, ...)
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, emsg);
|
||||
vlog(LOG_CRIT, emsg, ap);
|
||||
vlog(LOG_ERR, emsg, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
@ -133,15 +128,15 @@ void
|
||||
fatal(const char *emsg)
|
||||
{
|
||||
if (emsg == NULL)
|
||||
logit(LOG_CRIT, "fatal in %s: %s", procnames[ldpd_process],
|
||||
logit(LOG_CRIT, "fatal in %s: %s", log_procname,
|
||||
strerror(errno));
|
||||
else
|
||||
if (errno)
|
||||
logit(LOG_CRIT, "fatal in %s: %s: %s",
|
||||
procnames[ldpd_process], emsg, strerror(errno));
|
||||
log_procname, emsg, strerror(errno));
|
||||
else
|
||||
logit(LOG_CRIT, "fatal in %s: %s",
|
||||
procnames[ldpd_process], emsg);
|
||||
log_procname, emsg);
|
||||
|
||||
exit(1);
|
||||
}
|
||||
@ -152,465 +147,3 @@ fatalx(const char *emsg)
|
||||
errno = 0;
|
||||
fatal(emsg);
|
||||
}
|
||||
|
||||
#define NUM_LOGS 4
|
||||
const char *
|
||||
log_sockaddr(void *vp)
|
||||
{
|
||||
static char buf[NUM_LOGS][NI_MAXHOST];
|
||||
static int round = 0;
|
||||
struct sockaddr *sa = vp;
|
||||
|
||||
round = (round + 1) % NUM_LOGS;
|
||||
|
||||
if (getnameinfo(sa, sockaddr_len(sa), buf[round], NI_MAXHOST, NULL, 0,
|
||||
NI_NUMERICHOST))
|
||||
return ("(unknown)");
|
||||
else
|
||||
return (buf[round]);
|
||||
}
|
||||
|
||||
const char *
|
||||
log_in6addr(const struct in6_addr *addr)
|
||||
{
|
||||
struct sockaddr_in6 sa_in6;
|
||||
|
||||
memset(&sa_in6, 0, sizeof(sa_in6));
|
||||
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
|
||||
sa_in6.sin6_len = sizeof(sa_in6);
|
||||
#endif
|
||||
sa_in6.sin6_family = AF_INET6;
|
||||
sa_in6.sin6_addr = *addr;
|
||||
|
||||
recoverscope(&sa_in6);
|
||||
|
||||
return (log_sockaddr(&sa_in6));
|
||||
}
|
||||
|
||||
const char *
|
||||
log_in6addr_scope(const struct in6_addr *addr, unsigned int ifindex)
|
||||
{
|
||||
struct sockaddr_in6 sa_in6;
|
||||
|
||||
memset(&sa_in6, 0, sizeof(sa_in6));
|
||||
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
|
||||
sa_in6.sin6_len = sizeof(sa_in6);
|
||||
#endif
|
||||
sa_in6.sin6_family = AF_INET6;
|
||||
sa_in6.sin6_addr = *addr;
|
||||
|
||||
addscope(&sa_in6, ifindex);
|
||||
|
||||
return (log_sockaddr(&sa_in6));
|
||||
}
|
||||
|
||||
const char *
|
||||
log_addr(int af, const union ldpd_addr *addr)
|
||||
{
|
||||
static char buf[NUM_LOGS][INET6_ADDRSTRLEN];
|
||||
static int round = 0;
|
||||
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
round = (round + 1) % NUM_LOGS;
|
||||
if (inet_ntop(AF_INET, &addr->v4, buf[round],
|
||||
sizeof(buf[round])) == NULL)
|
||||
return ("???");
|
||||
return (buf[round]);
|
||||
case AF_INET6:
|
||||
return (log_in6addr(&addr->v6));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ("???");
|
||||
}
|
||||
|
||||
#define TF_BUFS 4
|
||||
#define TF_LEN 32
|
||||
|
||||
char *
|
||||
log_label(uint32_t label)
|
||||
{
|
||||
char *buf;
|
||||
static char tfbuf[TF_BUFS][TF_LEN]; /* ring buffer */
|
||||
static int idx = 0;
|
||||
|
||||
buf = tfbuf[idx++];
|
||||
if (idx == TF_BUFS)
|
||||
idx = 0;
|
||||
|
||||
switch (label) {
|
||||
case NO_LABEL:
|
||||
snprintf(buf, TF_LEN, "-");
|
||||
break;
|
||||
case MPLS_LABEL_IMPLNULL:
|
||||
snprintf(buf, TF_LEN, "imp-null");
|
||||
break;
|
||||
case MPLS_LABEL_IPV4NULL:
|
||||
case MPLS_LABEL_IPV6NULL:
|
||||
snprintf(buf, TF_LEN, "exp-null");
|
||||
break;
|
||||
default:
|
||||
snprintf(buf, TF_LEN, "%u", label);
|
||||
break;
|
||||
}
|
||||
|
||||
return (buf);
|
||||
}
|
||||
|
||||
const char *
|
||||
log_time(time_t t)
|
||||
{
|
||||
char *buf;
|
||||
static char tfbuf[TF_BUFS][TF_LEN]; /* ring buffer */
|
||||
static int idx = 0;
|
||||
unsigned int sec, min, hrs, day, week;
|
||||
|
||||
buf = tfbuf[idx++];
|
||||
if (idx == TF_BUFS)
|
||||
idx = 0;
|
||||
|
||||
week = t;
|
||||
|
||||
sec = week % 60;
|
||||
week /= 60;
|
||||
min = week % 60;
|
||||
week /= 60;
|
||||
hrs = week % 24;
|
||||
week /= 24;
|
||||
day = week % 7;
|
||||
week /= 7;
|
||||
|
||||
if (week > 0)
|
||||
snprintf(buf, TF_LEN, "%02uw%01ud%02uh", week, day, hrs);
|
||||
else if (day > 0)
|
||||
snprintf(buf, TF_LEN, "%01ud%02uh%02um", day, hrs, min);
|
||||
else
|
||||
snprintf(buf, TF_LEN, "%02u:%02u:%02u", hrs, min, sec);
|
||||
|
||||
return (buf);
|
||||
}
|
||||
|
||||
char *
|
||||
log_hello_src(const struct hello_source *src)
|
||||
{
|
||||
static char buf[64];
|
||||
|
||||
switch (src->type) {
|
||||
case HELLO_LINK:
|
||||
snprintf(buf, sizeof(buf), "iface %s",
|
||||
src->link.ia->iface->name);
|
||||
break;
|
||||
case HELLO_TARGETED:
|
||||
snprintf(buf, sizeof(buf), "source %s",
|
||||
log_addr(src->target->af, &src->target->addr));
|
||||
break;
|
||||
}
|
||||
|
||||
return (buf);
|
||||
}
|
||||
|
||||
const char *
|
||||
log_map(const struct map *map)
|
||||
{
|
||||
static char buf[128];
|
||||
|
||||
switch (map->type) {
|
||||
case MAP_TYPE_WILDCARD:
|
||||
if (snprintf(buf, sizeof(buf), "wildcard") < 0)
|
||||
return ("???");
|
||||
break;
|
||||
case MAP_TYPE_PREFIX:
|
||||
if (snprintf(buf, sizeof(buf), "%s/%u",
|
||||
log_addr(map->fec.prefix.af, &map->fec.prefix.prefix),
|
||||
map->fec.prefix.prefixlen) == -1)
|
||||
return ("???");
|
||||
break;
|
||||
case MAP_TYPE_PWID:
|
||||
if (snprintf(buf, sizeof(buf), "pw-id %u group-id %u (%s)",
|
||||
map->fec.pwid.pwid, map->fec.pwid.group_id,
|
||||
pw_type_name(map->fec.pwid.type)) == -1)
|
||||
return ("???");
|
||||
break;
|
||||
case MAP_TYPE_TYPED_WCARD:
|
||||
if (snprintf(buf, sizeof(buf), "typed wildcard") < 0)
|
||||
return ("???");
|
||||
switch (map->fec.twcard.type) {
|
||||
case MAP_TYPE_PREFIX:
|
||||
if (snprintf(buf + strlen(buf), sizeof(buf) -
|
||||
strlen(buf), " (prefix, address-family %s)",
|
||||
af_name(map->fec.twcard.u.prefix_af)) < 0)
|
||||
return ("???");
|
||||
break;
|
||||
case MAP_TYPE_PWID:
|
||||
if (snprintf(buf + strlen(buf), sizeof(buf) -
|
||||
strlen(buf), " (pwid, type %s)",
|
||||
pw_type_name(map->fec.twcard.u.pw_type)) < 0)
|
||||
return ("???");
|
||||
break;
|
||||
default:
|
||||
if (snprintf(buf + strlen(buf), sizeof(buf) -
|
||||
strlen(buf), " (unknown type)") < 0)
|
||||
return ("???");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return ("???");
|
||||
}
|
||||
|
||||
return (buf);
|
||||
}
|
||||
|
||||
const char *
|
||||
log_fec(const struct fec *fec)
|
||||
{
|
||||
static char buf[64];
|
||||
union ldpd_addr addr;
|
||||
|
||||
switch (fec->type) {
|
||||
case FEC_TYPE_IPV4:
|
||||
addr.v4 = fec->u.ipv4.prefix;
|
||||
if (snprintf(buf, sizeof(buf), "ipv4 %s/%u",
|
||||
log_addr(AF_INET, &addr), fec->u.ipv4.prefixlen) == -1)
|
||||
return ("???");
|
||||
break;
|
||||
case FEC_TYPE_IPV6:
|
||||
addr.v6 = fec->u.ipv6.prefix;
|
||||
if (snprintf(buf, sizeof(buf), "ipv6 %s/%u",
|
||||
log_addr(AF_INET6, &addr), fec->u.ipv6.prefixlen) == -1)
|
||||
return ("???");
|
||||
break;
|
||||
case FEC_TYPE_PWID:
|
||||
if (snprintf(buf, sizeof(buf),
|
||||
"pwid %u (%s) - %s",
|
||||
fec->u.pwid.pwid, pw_type_name(fec->u.pwid.type),
|
||||
inet_ntoa(fec->u.pwid.lsr_id)) == -1)
|
||||
return ("???");
|
||||
break;
|
||||
default:
|
||||
return ("???");
|
||||
}
|
||||
|
||||
return (buf);
|
||||
}
|
||||
|
||||
/* names */
|
||||
const char *
|
||||
af_name(int af)
|
||||
{
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return ("ipv4");
|
||||
case AF_INET6:
|
||||
return ("ipv6");
|
||||
#ifdef AF_MPLS
|
||||
case AF_MPLS:
|
||||
return ("mpls");
|
||||
#endif
|
||||
default:
|
||||
return ("UNKNOWN");
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
socket_name(int type)
|
||||
{
|
||||
switch (type) {
|
||||
case LDP_SOCKET_DISC:
|
||||
return ("discovery");
|
||||
case LDP_SOCKET_EDISC:
|
||||
return ("extended discovery");
|
||||
case LDP_SOCKET_SESSION:
|
||||
return ("session");
|
||||
default:
|
||||
return ("UNKNOWN");
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
nbr_state_name(int state)
|
||||
{
|
||||
switch (state) {
|
||||
case NBR_STA_PRESENT:
|
||||
return ("PRESENT");
|
||||
case NBR_STA_INITIAL:
|
||||
return ("INITIALIZED");
|
||||
case NBR_STA_OPENREC:
|
||||
return ("OPENREC");
|
||||
case NBR_STA_OPENSENT:
|
||||
return ("OPENSENT");
|
||||
case NBR_STA_OPER:
|
||||
return ("OPERATIONAL");
|
||||
default:
|
||||
return ("UNKNOWN");
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
if_state_name(int state)
|
||||
{
|
||||
switch (state) {
|
||||
case IF_STA_DOWN:
|
||||
return ("DOWN");
|
||||
case IF_STA_ACTIVE:
|
||||
return ("ACTIVE");
|
||||
default:
|
||||
return ("UNKNOWN");
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
if_type_name(enum iface_type type)
|
||||
{
|
||||
switch (type) {
|
||||
case IF_TYPE_POINTOPOINT:
|
||||
return ("POINTOPOINT");
|
||||
case IF_TYPE_BROADCAST:
|
||||
return ("BROADCAST");
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return ("UNKNOWN");
|
||||
}
|
||||
|
||||
const char *
|
||||
msg_name(uint16_t msg)
|
||||
{
|
||||
static char buf[16];
|
||||
|
||||
switch (msg) {
|
||||
case MSG_TYPE_NOTIFICATION:
|
||||
return ("notification");
|
||||
case MSG_TYPE_HELLO:
|
||||
return ("hello");
|
||||
case MSG_TYPE_INIT:
|
||||
return ("initialization");
|
||||
case MSG_TYPE_KEEPALIVE:
|
||||
return ("keepalive");
|
||||
case MSG_TYPE_CAPABILITY:
|
||||
return ("capability");
|
||||
case MSG_TYPE_ADDR:
|
||||
return ("address");
|
||||
case MSG_TYPE_ADDRWITHDRAW:
|
||||
return ("address withdraw");
|
||||
case MSG_TYPE_LABELMAPPING:
|
||||
return ("label mapping");
|
||||
case MSG_TYPE_LABELREQUEST:
|
||||
return ("label request");
|
||||
case MSG_TYPE_LABELWITHDRAW:
|
||||
return ("label withdraw");
|
||||
case MSG_TYPE_LABELRELEASE:
|
||||
return ("label release");
|
||||
case MSG_TYPE_LABELABORTREQ:
|
||||
default:
|
||||
snprintf(buf, sizeof(buf), "[%08x]", msg);
|
||||
return (buf);
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
status_code_name(uint32_t status)
|
||||
{
|
||||
static char buf[16];
|
||||
|
||||
switch (status) {
|
||||
case S_SUCCESS:
|
||||
return ("Success");
|
||||
case S_BAD_LDP_ID:
|
||||
return ("Bad LDP Identifier");
|
||||
case S_BAD_PROTO_VER:
|
||||
return ("Bad Protocol Version");
|
||||
case S_BAD_PDU_LEN:
|
||||
return ("Bad PDU Length");
|
||||
case S_UNKNOWN_MSG:
|
||||
return ("Unknown Message Type");
|
||||
case S_BAD_MSG_LEN:
|
||||
return ("Bad Message Length");
|
||||
case S_UNKNOWN_TLV:
|
||||
return ("Unknown TLV");
|
||||
case S_BAD_TLV_LEN:
|
||||
return ("Bad TLV Length");
|
||||
case S_BAD_TLV_VAL:
|
||||
return ("Malformed TLV Value");
|
||||
case S_HOLDTIME_EXP:
|
||||
return ("Hold Timer Expired");
|
||||
case S_SHUTDOWN:
|
||||
return ("Shutdown");
|
||||
case S_LOOP_DETECTED:
|
||||
return ("Loop Detected");
|
||||
case S_UNKNOWN_FEC:
|
||||
return ("Unknown FEC");
|
||||
case S_NO_ROUTE:
|
||||
return ("No Route");
|
||||
case S_NO_LABEL_RES:
|
||||
return ("No Label Resources");
|
||||
case S_AVAILABLE:
|
||||
return ("Label Resources Available");
|
||||
case S_NO_HELLO:
|
||||
return ("Session Rejected, No Hello");
|
||||
case S_PARM_ADV_MODE:
|
||||
return ("Rejected Advertisement Mode Parameter");
|
||||
case S_MAX_PDU_LEN:
|
||||
return ("Rejected Max PDU Length Parameter");
|
||||
case S_PARM_L_RANGE:
|
||||
return ("Rejected Label Range Parameter");
|
||||
case S_KEEPALIVE_TMR:
|
||||
return ("KeepAlive Timer Expired");
|
||||
case S_LAB_REQ_ABRT:
|
||||
return ("Label Request Aborted");
|
||||
case S_MISS_MSG:
|
||||
return ("Missing Message Parameters");
|
||||
case S_UNSUP_ADDR:
|
||||
return ("Unsupported Address Family");
|
||||
case S_KEEPALIVE_BAD:
|
||||
return ("Bad KeepAlive Time");
|
||||
case S_INTERN_ERR:
|
||||
return ("Internal Error");
|
||||
case S_ILLEGAL_CBIT:
|
||||
return ("Illegal C-Bit");
|
||||
case S_WRONG_CBIT:
|
||||
return ("Wrong C-Bit");
|
||||
case S_INCPT_BITRATE:
|
||||
return ("Incompatible bit-rate");
|
||||
case S_CEP_MISCONF:
|
||||
return ("CEP-TDM mis-configuration");
|
||||
case S_PW_STATUS:
|
||||
return ("PW Status");
|
||||
case S_UNASSIGN_TAI:
|
||||
return ("Unassigned/Unrecognized TAI");
|
||||
case S_MISCONF_ERR:
|
||||
return ("Generic Misconfiguration Error");
|
||||
case S_WITHDRAW_MTHD:
|
||||
return ("Label Withdraw PW Status Method");
|
||||
case S_UNSSUPORTDCAP:
|
||||
return ("Unsupported Capability");
|
||||
case S_ENDOFLIB:
|
||||
return ("End-of-LIB");
|
||||
case S_TRANS_MISMTCH:
|
||||
return ("Transport Connection Mismatch");
|
||||
case S_DS_NONCMPLNCE:
|
||||
return ("Dual-Stack Noncompliance");
|
||||
default:
|
||||
snprintf(buf, sizeof(buf), "[%08x]", status);
|
||||
return (buf);
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
pw_type_name(uint16_t pw_type)
|
||||
{
|
||||
static char buf[64];
|
||||
|
||||
switch (pw_type) {
|
||||
case PW_TYPE_ETHERNET_TAGGED:
|
||||
return ("Eth Tagged");
|
||||
case PW_TYPE_ETHERNET:
|
||||
return ("Ethernet");
|
||||
case PW_TYPE_WILDCARD:
|
||||
return ("Wildcard");
|
||||
default:
|
||||
snprintf(buf, sizeof(buf), "[%0x]", pw_type);
|
||||
return (buf);
|
||||
}
|
||||
}
|
||||
|
66
ldpd/log.h
66
ldpd/log.h
@ -16,50 +16,32 @@
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _LOG_H_
|
||||
#define _LOG_H_
|
||||
#ifndef LOG_H
|
||||
#define LOG_H
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
struct in6_addr;
|
||||
union ldpd_addr;
|
||||
struct hello_source;
|
||||
struct fec;
|
||||
extern const char *log_procname;
|
||||
|
||||
void logit(int, const char *, ...)
|
||||
__attribute__((__format__ (printf, 2, 3)));
|
||||
void log_warn(const char *, ...)
|
||||
__attribute__((__format__ (printf, 1, 2)));
|
||||
void log_warnx(const char *, ...)
|
||||
__attribute__((__format__ (printf, 1, 2)));
|
||||
void log_info(const char *, ...)
|
||||
__attribute__((__format__ (printf, 1, 2)));
|
||||
void log_notice(const char *, ...)
|
||||
__attribute__((__format__ (printf, 1, 2)));
|
||||
void log_debug(const char *, ...)
|
||||
__attribute__((__format__ (printf, 1, 2)));
|
||||
void fatal(const char *)
|
||||
__attribute__ ((noreturn))
|
||||
__attribute__((__format__ (printf, 1, 0)));
|
||||
void fatalx(const char *)
|
||||
__attribute__ ((noreturn))
|
||||
__attribute__((__format__ (printf, 1, 0)));
|
||||
const char *log_sockaddr(void *);
|
||||
const char *log_in6addr(const struct in6_addr *);
|
||||
const char *log_in6addr_scope(const struct in6_addr *, unsigned int);
|
||||
const char *log_addr(int, const union ldpd_addr *);
|
||||
char *log_label(uint32_t);
|
||||
const char *log_time(time_t);
|
||||
char *log_hello_src(const struct hello_source *);
|
||||
const char *log_map(const struct map *);
|
||||
const char *log_fec(const struct fec *);
|
||||
const char *af_name(int);
|
||||
const char *socket_name(int);
|
||||
const char *nbr_state_name(int);
|
||||
const char *if_state_name(int);
|
||||
const char *if_type_name(enum iface_type);
|
||||
const char *msg_name(uint16_t);
|
||||
const char *status_code_name(uint32_t);
|
||||
const char *pw_type_name(uint16_t);
|
||||
void logit(int, const char *, ...)
|
||||
__attribute__((__format__ (printf, 2, 3)));
|
||||
void vlog(int, const char *, va_list)
|
||||
__attribute__((__format__ (printf, 2, 0)));
|
||||
void log_warn(const char *, ...)
|
||||
__attribute__((__format__ (printf, 1, 2)));
|
||||
void log_warnx(const char *, ...)
|
||||
__attribute__((__format__ (printf, 1, 2)));
|
||||
void log_info(const char *, ...)
|
||||
__attribute__((__format__ (printf, 1, 2)));
|
||||
void log_notice(const char *, ...)
|
||||
__attribute__((__format__ (printf, 1, 2)));
|
||||
void log_debug(const char *, ...)
|
||||
__attribute__((__format__ (printf, 1, 2)));
|
||||
void fatal(const char *)
|
||||
__attribute__ ((noreturn))
|
||||
__attribute__((__format__ (printf, 1, 0)));
|
||||
void fatalx(const char *)
|
||||
__attribute__ ((noreturn))
|
||||
__attribute__((__format__ (printf, 1, 0)));
|
||||
|
||||
#endif /* _LOG_H_ */
|
||||
#endif /* LOG_H */
|
||||
|
487
ldpd/logmsg.c
Normal file
487
ldpd/logmsg.c
Normal file
@ -0,0 +1,487 @@
|
||||
/* $OpenBSD$ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <zebra.h>
|
||||
|
||||
#include "mpls.h"
|
||||
|
||||
#include "ldpd.h"
|
||||
#include "ldpe.h"
|
||||
#include "lde.h"
|
||||
|
||||
#define NUM_LOGS 4
|
||||
const char *
|
||||
log_sockaddr(void *vp)
|
||||
{
|
||||
static char buf[NUM_LOGS][NI_MAXHOST];
|
||||
static int round = 0;
|
||||
struct sockaddr *sa = vp;
|
||||
|
||||
round = (round + 1) % NUM_LOGS;
|
||||
|
||||
if (getnameinfo(sa, sockaddr_len(sa), buf[round], NI_MAXHOST, NULL, 0,
|
||||
NI_NUMERICHOST))
|
||||
return ("(unknown)");
|
||||
else
|
||||
return (buf[round]);
|
||||
}
|
||||
|
||||
const char *
|
||||
log_in6addr(const struct in6_addr *addr)
|
||||
{
|
||||
struct sockaddr_in6 sa_in6;
|
||||
|
||||
memset(&sa_in6, 0, sizeof(sa_in6));
|
||||
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
|
||||
sa_in6.sin6_len = sizeof(sa_in6);
|
||||
#endif
|
||||
sa_in6.sin6_family = AF_INET6;
|
||||
sa_in6.sin6_addr = *addr;
|
||||
|
||||
recoverscope(&sa_in6);
|
||||
|
||||
return (log_sockaddr(&sa_in6));
|
||||
}
|
||||
|
||||
const char *
|
||||
log_in6addr_scope(const struct in6_addr *addr, unsigned int ifindex)
|
||||
{
|
||||
struct sockaddr_in6 sa_in6;
|
||||
|
||||
memset(&sa_in6, 0, sizeof(sa_in6));
|
||||
#ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN
|
||||
sa_in6.sin6_len = sizeof(sa_in6);
|
||||
#endif
|
||||
sa_in6.sin6_family = AF_INET6;
|
||||
sa_in6.sin6_addr = *addr;
|
||||
|
||||
addscope(&sa_in6, ifindex);
|
||||
|
||||
return (log_sockaddr(&sa_in6));
|
||||
}
|
||||
|
||||
const char *
|
||||
log_addr(int af, const union ldpd_addr *addr)
|
||||
{
|
||||
static char buf[NUM_LOGS][INET6_ADDRSTRLEN];
|
||||
static int round = 0;
|
||||
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
round = (round + 1) % NUM_LOGS;
|
||||
if (inet_ntop(AF_INET, &addr->v4, buf[round],
|
||||
sizeof(buf[round])) == NULL)
|
||||
return ("???");
|
||||
return (buf[round]);
|
||||
case AF_INET6:
|
||||
return (log_in6addr(&addr->v6));
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return ("???");
|
||||
}
|
||||
|
||||
#define TF_BUFS 4
|
||||
#define TF_LEN 32
|
||||
|
||||
char *
|
||||
log_label(uint32_t label)
|
||||
{
|
||||
char *buf;
|
||||
static char tfbuf[TF_BUFS][TF_LEN]; /* ring buffer */
|
||||
static int idx = 0;
|
||||
|
||||
buf = tfbuf[idx++];
|
||||
if (idx == TF_BUFS)
|
||||
idx = 0;
|
||||
|
||||
switch (label) {
|
||||
case NO_LABEL:
|
||||
snprintf(buf, TF_LEN, "-");
|
||||
break;
|
||||
case MPLS_LABEL_IMPLNULL:
|
||||
snprintf(buf, TF_LEN, "imp-null");
|
||||
break;
|
||||
case MPLS_LABEL_IPV4NULL:
|
||||
case MPLS_LABEL_IPV6NULL:
|
||||
snprintf(buf, TF_LEN, "exp-null");
|
||||
break;
|
||||
default:
|
||||
snprintf(buf, TF_LEN, "%u", label);
|
||||
break;
|
||||
}
|
||||
|
||||
return (buf);
|
||||
}
|
||||
|
||||
const char *
|
||||
log_time(time_t t)
|
||||
{
|
||||
char *buf;
|
||||
static char tfbuf[TF_BUFS][TF_LEN]; /* ring buffer */
|
||||
static int idx = 0;
|
||||
unsigned int sec, min, hrs, day, week;
|
||||
|
||||
buf = tfbuf[idx++];
|
||||
if (idx == TF_BUFS)
|
||||
idx = 0;
|
||||
|
||||
week = t;
|
||||
|
||||
sec = week % 60;
|
||||
week /= 60;
|
||||
min = week % 60;
|
||||
week /= 60;
|
||||
hrs = week % 24;
|
||||
week /= 24;
|
||||
day = week % 7;
|
||||
week /= 7;
|
||||
|
||||
if (week > 0)
|
||||
snprintf(buf, TF_LEN, "%02uw%01ud%02uh", week, day, hrs);
|
||||
else if (day > 0)
|
||||
snprintf(buf, TF_LEN, "%01ud%02uh%02um", day, hrs, min);
|
||||
else
|
||||
snprintf(buf, TF_LEN, "%02u:%02u:%02u", hrs, min, sec);
|
||||
|
||||
return (buf);
|
||||
}
|
||||
|
||||
char *
|
||||
log_hello_src(const struct hello_source *src)
|
||||
{
|
||||
static char buf[64];
|
||||
|
||||
switch (src->type) {
|
||||
case HELLO_LINK:
|
||||
snprintf(buf, sizeof(buf), "iface %s",
|
||||
src->link.ia->iface->name);
|
||||
break;
|
||||
case HELLO_TARGETED:
|
||||
snprintf(buf, sizeof(buf), "source %s",
|
||||
log_addr(src->target->af, &src->target->addr));
|
||||
break;
|
||||
}
|
||||
|
||||
return (buf);
|
||||
}
|
||||
|
||||
const char *
|
||||
log_map(const struct map *map)
|
||||
{
|
||||
static char buf[128];
|
||||
|
||||
switch (map->type) {
|
||||
case MAP_TYPE_WILDCARD:
|
||||
if (snprintf(buf, sizeof(buf), "wildcard") < 0)
|
||||
return ("???");
|
||||
break;
|
||||
case MAP_TYPE_PREFIX:
|
||||
if (snprintf(buf, sizeof(buf), "%s/%u",
|
||||
log_addr(map->fec.prefix.af, &map->fec.prefix.prefix),
|
||||
map->fec.prefix.prefixlen) == -1)
|
||||
return ("???");
|
||||
break;
|
||||
case MAP_TYPE_PWID:
|
||||
if (snprintf(buf, sizeof(buf), "pw-id %u group-id %u (%s)",
|
||||
map->fec.pwid.pwid, map->fec.pwid.group_id,
|
||||
pw_type_name(map->fec.pwid.type)) == -1)
|
||||
return ("???");
|
||||
break;
|
||||
case MAP_TYPE_TYPED_WCARD:
|
||||
if (snprintf(buf, sizeof(buf), "typed wildcard") < 0)
|
||||
return ("???");
|
||||
switch (map->fec.twcard.type) {
|
||||
case MAP_TYPE_PREFIX:
|
||||
if (snprintf(buf + strlen(buf), sizeof(buf) -
|
||||
strlen(buf), " (prefix, address-family %s)",
|
||||
af_name(map->fec.twcard.u.prefix_af)) < 0)
|
||||
return ("???");
|
||||
break;
|
||||
case MAP_TYPE_PWID:
|
||||
if (snprintf(buf + strlen(buf), sizeof(buf) -
|
||||
strlen(buf), " (pwid, type %s)",
|
||||
pw_type_name(map->fec.twcard.u.pw_type)) < 0)
|
||||
return ("???");
|
||||
break;
|
||||
default:
|
||||
if (snprintf(buf + strlen(buf), sizeof(buf) -
|
||||
strlen(buf), " (unknown type)") < 0)
|
||||
return ("???");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return ("???");
|
||||
}
|
||||
|
||||
return (buf);
|
||||
}
|
||||
|
||||
const char *
|
||||
log_fec(const struct fec *fec)
|
||||
{
|
||||
static char buf[64];
|
||||
union ldpd_addr addr;
|
||||
|
||||
switch (fec->type) {
|
||||
case FEC_TYPE_IPV4:
|
||||
addr.v4 = fec->u.ipv4.prefix;
|
||||
if (snprintf(buf, sizeof(buf), "ipv4 %s/%u",
|
||||
log_addr(AF_INET, &addr), fec->u.ipv4.prefixlen) == -1)
|
||||
return ("???");
|
||||
break;
|
||||
case FEC_TYPE_IPV6:
|
||||
addr.v6 = fec->u.ipv6.prefix;
|
||||
if (snprintf(buf, sizeof(buf), "ipv6 %s/%u",
|
||||
log_addr(AF_INET6, &addr), fec->u.ipv6.prefixlen) == -1)
|
||||
return ("???");
|
||||
break;
|
||||
case FEC_TYPE_PWID:
|
||||
if (snprintf(buf, sizeof(buf),
|
||||
"pwid %u (%s) - %s",
|
||||
fec->u.pwid.pwid, pw_type_name(fec->u.pwid.type),
|
||||
inet_ntoa(fec->u.pwid.lsr_id)) == -1)
|
||||
return ("???");
|
||||
break;
|
||||
default:
|
||||
return ("???");
|
||||
}
|
||||
|
||||
return (buf);
|
||||
}
|
||||
|
||||
/* names */
|
||||
const char *
|
||||
af_name(int af)
|
||||
{
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return ("ipv4");
|
||||
case AF_INET6:
|
||||
return ("ipv6");
|
||||
#ifdef AF_MPLS
|
||||
case AF_MPLS:
|
||||
return ("mpls");
|
||||
#endif
|
||||
default:
|
||||
return ("UNKNOWN");
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
socket_name(int type)
|
||||
{
|
||||
switch (type) {
|
||||
case LDP_SOCKET_DISC:
|
||||
return ("discovery");
|
||||
case LDP_SOCKET_EDISC:
|
||||
return ("extended discovery");
|
||||
case LDP_SOCKET_SESSION:
|
||||
return ("session");
|
||||
default:
|
||||
return ("UNKNOWN");
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
nbr_state_name(int state)
|
||||
{
|
||||
switch (state) {
|
||||
case NBR_STA_PRESENT:
|
||||
return ("PRESENT");
|
||||
case NBR_STA_INITIAL:
|
||||
return ("INITIALIZED");
|
||||
case NBR_STA_OPENREC:
|
||||
return ("OPENREC");
|
||||
case NBR_STA_OPENSENT:
|
||||
return ("OPENSENT");
|
||||
case NBR_STA_OPER:
|
||||
return ("OPERATIONAL");
|
||||
default:
|
||||
return ("UNKNOWN");
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
if_state_name(int state)
|
||||
{
|
||||
switch (state) {
|
||||
case IF_STA_DOWN:
|
||||
return ("DOWN");
|
||||
case IF_STA_ACTIVE:
|
||||
return ("ACTIVE");
|
||||
default:
|
||||
return ("UNKNOWN");
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
if_type_name(enum iface_type type)
|
||||
{
|
||||
switch (type) {
|
||||
case IF_TYPE_POINTOPOINT:
|
||||
return ("POINTOPOINT");
|
||||
case IF_TYPE_BROADCAST:
|
||||
return ("BROADCAST");
|
||||
}
|
||||
/* NOTREACHED */
|
||||
return ("UNKNOWN");
|
||||
}
|
||||
|
||||
const char *
|
||||
msg_name(uint16_t msg)
|
||||
{
|
||||
static char buf[16];
|
||||
|
||||
switch (msg) {
|
||||
case MSG_TYPE_NOTIFICATION:
|
||||
return ("notification");
|
||||
case MSG_TYPE_HELLO:
|
||||
return ("hello");
|
||||
case MSG_TYPE_INIT:
|
||||
return ("initialization");
|
||||
case MSG_TYPE_KEEPALIVE:
|
||||
return ("keepalive");
|
||||
case MSG_TYPE_CAPABILITY:
|
||||
return ("capability");
|
||||
case MSG_TYPE_ADDR:
|
||||
return ("address");
|
||||
case MSG_TYPE_ADDRWITHDRAW:
|
||||
return ("address withdraw");
|
||||
case MSG_TYPE_LABELMAPPING:
|
||||
return ("label mapping");
|
||||
case MSG_TYPE_LABELREQUEST:
|
||||
return ("label request");
|
||||
case MSG_TYPE_LABELWITHDRAW:
|
||||
return ("label withdraw");
|
||||
case MSG_TYPE_LABELRELEASE:
|
||||
return ("label release");
|
||||
case MSG_TYPE_LABELABORTREQ:
|
||||
default:
|
||||
snprintf(buf, sizeof(buf), "[%08x]", msg);
|
||||
return (buf);
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
status_code_name(uint32_t status)
|
||||
{
|
||||
static char buf[16];
|
||||
|
||||
switch (status) {
|
||||
case S_SUCCESS:
|
||||
return ("Success");
|
||||
case S_BAD_LDP_ID:
|
||||
return ("Bad LDP Identifier");
|
||||
case S_BAD_PROTO_VER:
|
||||
return ("Bad Protocol Version");
|
||||
case S_BAD_PDU_LEN:
|
||||
return ("Bad PDU Length");
|
||||
case S_UNKNOWN_MSG:
|
||||
return ("Unknown Message Type");
|
||||
case S_BAD_MSG_LEN:
|
||||
return ("Bad Message Length");
|
||||
case S_UNKNOWN_TLV:
|
||||
return ("Unknown TLV");
|
||||
case S_BAD_TLV_LEN:
|
||||
return ("Bad TLV Length");
|
||||
case S_BAD_TLV_VAL:
|
||||
return ("Malformed TLV Value");
|
||||
case S_HOLDTIME_EXP:
|
||||
return ("Hold Timer Expired");
|
||||
case S_SHUTDOWN:
|
||||
return ("Shutdown");
|
||||
case S_LOOP_DETECTED:
|
||||
return ("Loop Detected");
|
||||
case S_UNKNOWN_FEC:
|
||||
return ("Unknown FEC");
|
||||
case S_NO_ROUTE:
|
||||
return ("No Route");
|
||||
case S_NO_LABEL_RES:
|
||||
return ("No Label Resources");
|
||||
case S_AVAILABLE:
|
||||
return ("Label Resources Available");
|
||||
case S_NO_HELLO:
|
||||
return ("Session Rejected, No Hello");
|
||||
case S_PARM_ADV_MODE:
|
||||
return ("Rejected Advertisement Mode Parameter");
|
||||
case S_MAX_PDU_LEN:
|
||||
return ("Rejected Max PDU Length Parameter");
|
||||
case S_PARM_L_RANGE:
|
||||
return ("Rejected Label Range Parameter");
|
||||
case S_KEEPALIVE_TMR:
|
||||
return ("KeepAlive Timer Expired");
|
||||
case S_LAB_REQ_ABRT:
|
||||
return ("Label Request Aborted");
|
||||
case S_MISS_MSG:
|
||||
return ("Missing Message Parameters");
|
||||
case S_UNSUP_ADDR:
|
||||
return ("Unsupported Address Family");
|
||||
case S_KEEPALIVE_BAD:
|
||||
return ("Bad KeepAlive Time");
|
||||
case S_INTERN_ERR:
|
||||
return ("Internal Error");
|
||||
case S_ILLEGAL_CBIT:
|
||||
return ("Illegal C-Bit");
|
||||
case S_WRONG_CBIT:
|
||||
return ("Wrong C-Bit");
|
||||
case S_INCPT_BITRATE:
|
||||
return ("Incompatible bit-rate");
|
||||
case S_CEP_MISCONF:
|
||||
return ("CEP-TDM mis-configuration");
|
||||
case S_PW_STATUS:
|
||||
return ("PW Status");
|
||||
case S_UNASSIGN_TAI:
|
||||
return ("Unassigned/Unrecognized TAI");
|
||||
case S_MISCONF_ERR:
|
||||
return ("Generic Misconfiguration Error");
|
||||
case S_WITHDRAW_MTHD:
|
||||
return ("Label Withdraw PW Status Method");
|
||||
case S_UNSSUPORTDCAP:
|
||||
return ("Unsupported Capability");
|
||||
case S_ENDOFLIB:
|
||||
return ("End-of-LIB");
|
||||
case S_TRANS_MISMTCH:
|
||||
return ("Transport Connection Mismatch");
|
||||
case S_DS_NONCMPLNCE:
|
||||
return ("Dual-Stack Noncompliance");
|
||||
default:
|
||||
snprintf(buf, sizeof(buf), "[%08x]", status);
|
||||
return (buf);
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
pw_type_name(uint16_t pw_type)
|
||||
{
|
||||
static char buf[64];
|
||||
|
||||
switch (pw_type) {
|
||||
case PW_TYPE_ETHERNET_TAGGED:
|
||||
return ("Eth Tagged");
|
||||
case PW_TYPE_ETHERNET:
|
||||
return ("Ethernet");
|
||||
case PW_TYPE_WILDCARD:
|
||||
return ("Wildcard");
|
||||
default:
|
||||
snprintf(buf, sizeof(buf), "[%0x]", pw_type);
|
||||
return (buf);
|
||||
}
|
||||
}
|
@ -237,6 +237,16 @@ recv_notification(struct nbr *nbr, char *buf, uint16_t len)
|
||||
if (nbr->state == NBR_STA_OPENSENT)
|
||||
nbr_start_idtimer(nbr);
|
||||
|
||||
/*
|
||||
* RFC 5036 - Section 3.5.1.1:
|
||||
* "When an LSR receives a Shutdown message during session
|
||||
* initialization, it SHOULD transmit a Shutdown message and
|
||||
* then close the transport connection".
|
||||
*/
|
||||
if (nbr->state != NBR_STA_OPER && nm.status_code == S_SHUTDOWN)
|
||||
send_notification(nbr->tcp, S_SHUTDOWN,
|
||||
msg.id, msg.type);
|
||||
|
||||
nbr_fsm(nbr, NBR_EVT_CLOSE_SESSION);
|
||||
return (-1);
|
||||
}
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include "sockopt.h"
|
||||
|
||||
static struct iface *disc_find_iface(unsigned int, int,
|
||||
union ldpd_addr *, int);
|
||||
union ldpd_addr *);
|
||||
static int session_read(struct thread *);
|
||||
static int session_write(struct thread *);
|
||||
static ssize_t session_get_pdu(struct ibuf_read *, char **);
|
||||
@ -134,7 +134,7 @@ disc_recv_packet(struct thread *thread)
|
||||
int af;
|
||||
union ldpd_addr src;
|
||||
unsigned int ifindex = 0;
|
||||
struct iface *iface;
|
||||
struct iface *iface = NULL;
|
||||
uint16_t len;
|
||||
struct ldp_hdr ldp_hdr;
|
||||
uint16_t pdu_len;
|
||||
@ -212,9 +212,11 @@ disc_recv_packet(struct thread *thread)
|
||||
ifindex = getsockopt_ifindex(af, &m);
|
||||
|
||||
/* find a matching interface */
|
||||
iface = disc_find_iface(ifindex, af, &src, multicast);
|
||||
if (iface == NULL)
|
||||
return (0);
|
||||
if (multicast) {
|
||||
iface = disc_find_iface(ifindex, af, &src);
|
||||
if (iface == NULL)
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* check packet size */
|
||||
len = (uint16_t)r;
|
||||
@ -280,8 +282,7 @@ disc_recv_packet(struct thread *thread)
|
||||
}
|
||||
|
||||
static struct iface *
|
||||
disc_find_iface(unsigned int ifindex, int af, union ldpd_addr *src,
|
||||
int multicast)
|
||||
disc_find_iface(unsigned int ifindex, int af, union ldpd_addr *src)
|
||||
{
|
||||
struct iface *iface;
|
||||
struct iface_af *ia;
|
||||
@ -299,7 +300,7 @@ disc_find_iface(unsigned int ifindex, int af, union ldpd_addr *src,
|
||||
* "Link-local IPv6 address MUST be used as the source IP address in
|
||||
* IPv6 LDP Link Hellos".
|
||||
*/
|
||||
if (multicast && af == AF_INET6 && !IN6_IS_ADDR_LINKLOCAL(&src->v6))
|
||||
if (af == AF_INET6 && !IN6_IS_ADDR_LINKLOCAL(&src->v6))
|
||||
return (NULL);
|
||||
|
||||
return (iface);
|
||||
@ -519,6 +520,8 @@ session_read(struct thread *thread)
|
||||
return (0);
|
||||
}
|
||||
break;
|
||||
case MSG_TYPE_NOTIFICATION:
|
||||
break;
|
||||
default:
|
||||
if (nbr->state != NBR_STA_OPER) {
|
||||
session_shutdown(nbr, S_SHUTDOWN,
|
||||
@ -661,8 +664,6 @@ session_shutdown(struct nbr *nbr, uint32_t status, uint32_t msg_id,
|
||||
case NBR_STA_OPENREC:
|
||||
case NBR_STA_OPENSENT:
|
||||
case NBR_STA_OPER:
|
||||
log_debug("%s: lsr-id %s", __func__, inet_ntoa(nbr->id));
|
||||
|
||||
send_notification(nbr->tcp, status, msg_id, msg_type);
|
||||
|
||||
nbr_fsm(nbr, NBR_EVT_CLOSE_SESSION);
|
||||
|
Loading…
Reference in New Issue
Block a user