summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRenato Westphal <renato@cvs.openbsd.org>2016-06-09 17:26:33 +0000
committerRenato Westphal <renato@cvs.openbsd.org>2016-06-09 17:26:33 +0000
commitf429e0627900f54d72548e50b7af0b713296264f (patch)
treed6fb243a4b73a9a1af440f8eb23623c40016d6b3
parent5e5312976e5a2bcd103b6fb160a065a2496dc956 (diff)
Send a fatal notification when the last hello adjacency is deleted.
RFC 5036 says: "When the last Hello adjacency for an LDP session is deleted, the LSR terminates the LDP session by sending a Notification message and closing the transport connection". Send a "Hold Timer Expired" notification when the triggering event is a hello hold time timeout. In the other cases, like disabling LDP on an interface, send a "Shutdown" notification instead. Before this patch we were just closing the neighbor's transport connection. Fixes the following ANVL LDP tests: 7.17 and 23.3.
-rw-r--r--usr.sbin/ldpd/adjacency.c13
-rw-r--r--usr.sbin/ldpd/hello.c4
-rw-r--r--usr.sbin/ldpd/interface.c4
-rw-r--r--usr.sbin/ldpd/ldpe.c4
-rw-r--r--usr.sbin/ldpd/ldpe.h4
5 files changed, 16 insertions, 13 deletions
diff --git a/usr.sbin/ldpd/adjacency.c b/usr.sbin/ldpd/adjacency.c
index bf86dc931b5..6cc73af45ef 100644
--- a/usr.sbin/ldpd/adjacency.c
+++ b/usr.sbin/ldpd/adjacency.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: adjacency.c,v 1.22 2016/05/23 19:14:03 renato Exp $ */
+/* $OpenBSD: adjacency.c,v 1.23 2016/06/09 17:26:32 renato Exp $ */
/*
* Copyright (c) 2013, 2015 Renato Westphal <renato@openbsd.org>
@@ -68,7 +68,7 @@ adj_new(struct in_addr lsr_id, struct hello_source *source,
}
void
-adj_del(struct adj *adj)
+adj_del(struct adj *adj, int send_notif, uint32_t notif_status)
{
log_debug("%s: lsr-id %s, %s", __func__, inet_ntoa(adj->lsr_id),
log_hello_src(&adj->source));
@@ -82,8 +82,11 @@ adj_del(struct adj *adj)
LIST_REMOVE(adj, ia_entry);
/* last adjacency deleted */
- if (adj->nbr && LIST_EMPTY(&adj->nbr->adj_list))
+ if (adj->nbr && LIST_EMPTY(&adj->nbr->adj_list)) {
+ if (send_notif)
+ session_shutdown(adj->nbr, notif_status, 0, 0);
nbr_del(adj->nbr);
+ }
free(adj);
}
@@ -147,7 +150,7 @@ adj_itimer(int fd, short event, void *arg)
adj->source.target->adj = NULL;
}
- adj_del(adj);
+ adj_del(adj, 1, S_HOLDTIME_EXP);
}
void
@@ -193,7 +196,7 @@ tnbr_del(struct tnbr *tnbr)
{
tnbr_stop_hello_timer(tnbr);
if (tnbr->adj)
- adj_del(tnbr->adj);
+ adj_del(tnbr->adj, 1, S_SHUTDOWN);
LIST_REMOVE(tnbr, entry);
free(tnbr);
}
diff --git a/usr.sbin/ldpd/hello.c b/usr.sbin/ldpd/hello.c
index 1e16691de2e..5d8cd202f4a 100644
--- a/usr.sbin/ldpd/hello.c
+++ b/usr.sbin/ldpd/hello.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: hello.c,v 1.44 2016/06/08 23:14:03 renato Exp $ */
+/* $OpenBSD: hello.c,v 1.45 2016/06/09 17:26:32 renato Exp $ */
/*
* Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
@@ -279,7 +279,7 @@ recv_hello(struct in_addr lsr_id, struct ldp_msg *lm, int af,
session_shutdown(nbr, S_TRANS_MISMTCH, lm->msgid,
lm->type);
if (adj)
- adj_del(adj);
+ adj_del(adj, 0, 0);
return;
}
diff --git a/usr.sbin/ldpd/interface.c b/usr.sbin/ldpd/interface.c
index ef4fdfc00bc..c455279ed14 100644
--- a/usr.sbin/ldpd/interface.c
+++ b/usr.sbin/ldpd/interface.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: interface.c,v 1.44 2016/05/23 19:14:03 renato Exp $ */
+/* $OpenBSD: interface.c,v 1.45 2016/06/09 17:26:32 renato Exp $ */
/*
* Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
@@ -278,7 +278,7 @@ if_reset(struct iface *iface, int af)
if_stop_hello_timer(ia);
while ((adj = LIST_FIRST(&ia->adj_list)) != NULL)
- adj_del(adj);
+ adj_del(adj, 1, S_SHUTDOWN);
/* try to cleanup */
switch (af) {
diff --git a/usr.sbin/ldpd/ldpe.c b/usr.sbin/ldpd/ldpe.c
index 8e33edf243d..d29f2676886 100644
--- a/usr.sbin/ldpd/ldpe.c
+++ b/usr.sbin/ldpd/ldpe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldpe.c,v 1.63 2016/06/08 23:30:07 renato Exp $ */
+/* $OpenBSD: ldpe.c,v 1.64 2016/06/09 17:26:32 renato Exp $ */
/*
* Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
@@ -179,7 +179,7 @@ ldpe_shutdown(void)
free(if_addr);
}
while ((adj = LIST_FIRST(&global.adj_list)) != NULL)
- adj_del(adj);
+ adj_del(adj, 1, S_SHUTDOWN);
/* clean up */
msgbuf_write(&iev_lde->ibuf.w);
diff --git a/usr.sbin/ldpd/ldpe.h b/usr.sbin/ldpd/ldpe.h
index 288aa25d5a8..09b7ec92398 100644
--- a/usr.sbin/ldpd/ldpe.h
+++ b/usr.sbin/ldpd/ldpe.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ldpe.h,v 1.57 2016/05/23 19:20:55 renato Exp $ */
+/* $OpenBSD: ldpe.h,v 1.58 2016/06/09 17:26:32 renato Exp $ */
/*
* Copyright (c) 2013, 2016 Renato Westphal <renato@openbsd.org>
@@ -204,7 +204,7 @@ in_addr_t if_get_ipv4_addr(struct iface *);
/* adjacency.c */
struct adj *adj_new(struct in_addr, struct hello_source *,
union ldpd_addr *);
-void adj_del(struct adj *);
+void adj_del(struct adj *, int, uint32_t);
struct adj *adj_find(struct hello_source *);
int adj_get_af(struct adj *adj);
void adj_start_itimer(struct adj *);