+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2003 Yasuhiro Ohara
- *
- * This file is part of GNU Zebra.
- *
- * GNU Zebra is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * GNU Zebra is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; see the file COPYING; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <zebra.h>
return NULL;
}
+static void ospf6_neighbor_clear_ls_lists(struct ospf6_neighbor *on)
+{
+ struct ospf6_lsa *lsa;
+ struct ospf6_lsa *lsanext;
+
+ ospf6_lsdb_remove_all(on->summary_list);
+ if (on->last_ls_req) {
+ ospf6_lsa_unlock(on->last_ls_req);
+ on->last_ls_req = NULL;
+ }
+ ospf6_lsdb_remove_all(on->request_list);
+ for (ALL_LSDB(on->retrans_list, lsa, lsanext)) {
+ ospf6_decrement_retrans_count(lsa);
+ ospf6_lsdb_remove(lsa, on->retrans_list);
+ }
+}
+
/* create ospf6_neighbor */
struct ospf6_neighbor *ospf6_neighbor_create(uint32_t router_id,
struct ospf6_interface *oi)
{
struct ospf6_neighbor *on;
char buf[16];
+ int type;
on = XCALLOC(MTYPE_OSPF6_NEIGHBOR, sizeof(struct ospf6_neighbor));
inet_ntop(AF_INET, &router_id, buf, sizeof(buf));
on->lsupdate_list = ospf6_lsdb_create(on);
on->lsack_list = ospf6_lsdb_create(on);
+ for (type = 0; type < OSPF6_MESSAGE_TYPE_MAX; type++) {
+ on->seqnum_l[type] = 0;
+ on->seqnum_h[type] = 0;
+ }
+
+ on->auth_present = false;
+
listnode_add_sort(oi->neighbor_list, on);
ospf6_bfd_info_nbr_create(oi, on);
void ospf6_neighbor_delete(struct ospf6_neighbor *on)
{
- struct ospf6_lsa *lsa, *lsanext;
-
- ospf6_lsdb_remove_all(on->summary_list);
- ospf6_lsdb_remove_all(on->request_list);
- for (ALL_LSDB(on->retrans_list, lsa, lsanext)) {
- ospf6_decrement_retrans_count(lsa);
- ospf6_lsdb_remove(lsa, on->retrans_list);
- }
+ ospf6_neighbor_clear_ls_lists(on);
ospf6_lsdb_remove_all(on->dbdesc_list);
ospf6_lsdb_remove_all(on->lsupdate_list);
/* log */
if (IS_OSPF6_DEBUG_NEIGHBOR(STATE)) {
- zlog_debug("Neighbor state change %s: [%s]->[%s] (%s)",
- on->name, ospf6_neighbor_state_str[prev_state],
- ospf6_neighbor_state_str[next_state],
- ospf6_neighbor_event_string(event));
+ zlog_debug(
+ "Neighbor state change %s (Router-ID: %pI4): [%s]->[%s] (%s)",
+ on->name, &on->router_id,
+ ospf6_neighbor_state_str[prev_state],
+ ospf6_neighbor_state_str[next_state],
+ ospf6_neighbor_event_string(event));
}
/* Optionally notify about adjacency changes */
OSPF6_LOG_ADJACENCY_DETAIL)
|| (next_state == OSPF6_NEIGHBOR_FULL)
|| (next_state < prev_state)))
- zlog_notice("AdjChg: Nbr %s: %s -> %s (%s)", on->name,
- ospf6_neighbor_state_str[prev_state],
- ospf6_neighbor_state_str[next_state],
- ospf6_neighbor_event_string(event));
+ zlog_notice(
+ "AdjChg: Nbr %pI4(%s) on %s: %s -> %s (%s)",
+ &on->router_id,
+ vrf_id_to_name(on->ospf6_if->interface->vrf->vrf_id),
+ on->name, ospf6_neighbor_state_str[prev_state],
+ ospf6_neighbor_state_str[next_state],
+ ospf6_neighbor_event_string(event));
if (prev_state == OSPF6_NEIGHBOR_FULL
|| next_state == OSPF6_NEIGHBOR_FULL) {
return 0;
}
-int hello_received(struct thread *thread)
+void hello_received(struct thread *thread)
{
struct ospf6_neighbor *on;
if (on->state <= OSPF6_NEIGHBOR_DOWN)
ospf6_neighbor_state_change(OSPF6_NEIGHBOR_INIT, on,
OSPF6_NEIGHBOR_EVENT_HELLO_RCVD);
-
- return 0;
}
-int twoway_received(struct thread *thread)
+void twoway_received(struct thread *thread)
{
struct ospf6_neighbor *on;
assert(on);
if (on->state > OSPF6_NEIGHBOR_INIT)
- return 0;
+ return;
if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
zlog_debug("Neighbor Event %s: *2Way-Received*", on->name);
if (!need_adjacency(on)) {
ospf6_neighbor_state_change(OSPF6_NEIGHBOR_TWOWAY, on,
OSPF6_NEIGHBOR_EVENT_TWOWAY_RCVD);
- return 0;
+ return;
}
ospf6_neighbor_state_change(OSPF6_NEIGHBOR_EXSTART, on,
THREAD_OFF(on->thread_send_dbdesc);
thread_add_event(master, ospf6_dbdesc_send, on, 0,
&on->thread_send_dbdesc);
-
- return 0;
}
-int negotiation_done(struct thread *thread)
+void negotiation_done(struct thread *thread)
{
struct ospf6_neighbor *on;
struct ospf6_lsa *lsa, *lsanext;
assert(on);
if (on->state != OSPF6_NEIGHBOR_EXSTART)
- return 0;
+ return;
if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
zlog_debug("Neighbor Event %s: *NegotiationDone*", on->name);
/* clear ls-list */
- ospf6_lsdb_remove_all(on->summary_list);
- ospf6_lsdb_remove_all(on->request_list);
- for (ALL_LSDB(on->retrans_list, lsa, lsanext)) {
- ospf6_decrement_retrans_count(lsa);
- ospf6_lsdb_remove(lsa, on->retrans_list);
- }
+ ospf6_neighbor_clear_ls_lists(on);
/* Interface scoped LSAs */
for (ALL_LSDB(on->ospf6_if->lsdb, lsa, lsanext)) {
UNSET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT);
ospf6_neighbor_state_change(OSPF6_NEIGHBOR_EXCHANGE, on,
OSPF6_NEIGHBOR_EVENT_NEGOTIATION_DONE);
-
- return 0;
}
-static int ospf6_neighbor_last_dbdesc_release(struct thread *thread)
+static void ospf6_neighbor_last_dbdesc_release(struct thread *thread)
{
struct ospf6_neighbor *on = THREAD_ARG(thread);
assert(on);
memset(&on->dbdesc_last, 0, sizeof(struct ospf6_dbdesc));
-
- return 0;
}
-int exchange_done(struct thread *thread)
+void exchange_done(struct thread *thread)
{
struct ospf6_neighbor *on;
assert(on);
if (on->state != OSPF6_NEIGHBOR_EXCHANGE)
- return 0;
+ return;
if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
zlog_debug("Neighbor Event %s: *ExchangeDone*", on->name);
thread_add_event(master, ospf6_lsreq_send, on, 0,
&on->thread_send_lsreq);
}
-
- return 0;
}
/* Check loading state. */
if (on->request_list->count == 0)
thread_add_event(master, loading_done, on, 0, NULL);
else if (on->last_ls_req == NULL) {
- if (on->thread_send_lsreq != NULL)
- THREAD_OFF(on->thread_send_lsreq);
+ THREAD_OFF(on->thread_send_lsreq);
thread_add_event(master, ospf6_lsreq_send, on, 0,
&on->thread_send_lsreq);
}
}
}
-int loading_done(struct thread *thread)
+void loading_done(struct thread *thread)
{
struct ospf6_neighbor *on;
assert(on);
if (on->state != OSPF6_NEIGHBOR_LOADING)
- return 0;
+ return;
if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
zlog_debug("Neighbor Event %s: *LoadingDone*", on->name);
ospf6_neighbor_state_change(OSPF6_NEIGHBOR_FULL, on,
OSPF6_NEIGHBOR_EVENT_LOADING_DONE);
-
- return 0;
}
-int adj_ok(struct thread *thread)
+void adj_ok(struct thread *thread)
{
struct ospf6_neighbor *on;
- struct ospf6_lsa *lsa, *lsanext;
on = (struct ospf6_neighbor *)THREAD_ARG(thread);
assert(on);
SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT);
THREAD_OFF(on->thread_send_dbdesc);
- on->thread_send_dbdesc = NULL;
thread_add_event(master, ospf6_dbdesc_send, on, 0,
&on->thread_send_dbdesc);
} else if (on->state >= OSPF6_NEIGHBOR_EXSTART && !need_adjacency(on)) {
ospf6_neighbor_state_change(OSPF6_NEIGHBOR_TWOWAY, on,
OSPF6_NEIGHBOR_EVENT_ADJ_OK);
- ospf6_lsdb_remove_all(on->summary_list);
- ospf6_lsdb_remove_all(on->request_list);
- for (ALL_LSDB(on->retrans_list, lsa, lsanext)) {
- ospf6_decrement_retrans_count(lsa);
- ospf6_lsdb_remove(lsa, on->retrans_list);
- }
+ ospf6_neighbor_clear_ls_lists(on);
}
-
- return 0;
}
-int seqnumber_mismatch(struct thread *thread)
+void seqnumber_mismatch(struct thread *thread)
{
struct ospf6_neighbor *on;
- struct ospf6_lsa *lsa, *lsanext;
on = (struct ospf6_neighbor *)THREAD_ARG(thread);
assert(on);
if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
- return 0;
+ return;
if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
zlog_debug("Neighbor Event %s: *SeqNumberMismatch*", on->name);
SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT);
SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT);
- ospf6_lsdb_remove_all(on->summary_list);
- ospf6_lsdb_remove_all(on->request_list);
- for (ALL_LSDB(on->retrans_list, lsa, lsanext)) {
- ospf6_decrement_retrans_count(lsa);
- ospf6_lsdb_remove(lsa, on->retrans_list);
- }
+ ospf6_neighbor_clear_ls_lists(on);
THREAD_OFF(on->thread_send_dbdesc);
on->dbdesc_seqnum++; /* Incr seqnum as per RFC2328, sec 10.3 */
- on->thread_send_dbdesc = NULL;
thread_add_event(master, ospf6_dbdesc_send, on, 0,
&on->thread_send_dbdesc);
-
- return 0;
}
-int bad_lsreq(struct thread *thread)
+void bad_lsreq(struct thread *thread)
{
struct ospf6_neighbor *on;
- struct ospf6_lsa *lsa, *lsanext;
on = (struct ospf6_neighbor *)THREAD_ARG(thread);
assert(on);
if (on->state < OSPF6_NEIGHBOR_EXCHANGE)
- return 0;
+ return;
if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
zlog_debug("Neighbor Event %s: *BadLSReq*", on->name);
SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_MBIT);
SET_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT);
- ospf6_lsdb_remove_all(on->summary_list);
- ospf6_lsdb_remove_all(on->request_list);
- for (ALL_LSDB(on->retrans_list, lsa, lsanext)) {
- ospf6_decrement_retrans_count(lsa);
- ospf6_lsdb_remove(lsa, on->retrans_list);
- }
+ ospf6_neighbor_clear_ls_lists(on);
THREAD_OFF(on->thread_send_dbdesc);
on->dbdesc_seqnum++; /* Incr seqnum as per RFC2328, sec 10.3 */
- on->thread_send_dbdesc = NULL;
thread_add_event(master, ospf6_dbdesc_send, on, 0,
&on->thread_send_dbdesc);
- return 0;
}
-int oneway_received(struct thread *thread)
+void oneway_received(struct thread *thread)
{
struct ospf6_neighbor *on;
- struct ospf6_lsa *lsa, *lsanext;
on = (struct ospf6_neighbor *)THREAD_ARG(thread);
assert(on);
if (on->state < OSPF6_NEIGHBOR_TWOWAY)
- return 0;
+ return;
if (IS_OSPF6_DEBUG_NEIGHBOR(EVENT))
zlog_debug("Neighbor Event %s: *1Way-Received*", on->name);
OSPF6_NEIGHBOR_EVENT_ONEWAY_RCVD);
thread_add_event(master, neighbor_change, on->ospf6_if, 0, NULL);
- ospf6_lsdb_remove_all(on->summary_list);
- ospf6_lsdb_remove_all(on->request_list);
- for (ALL_LSDB(on->retrans_list, lsa, lsanext)) {
- ospf6_decrement_retrans_count(lsa);
- ospf6_lsdb_remove(lsa, on->retrans_list);
- }
+ ospf6_neighbor_clear_ls_lists(on);
THREAD_OFF(on->thread_send_dbdesc);
THREAD_OFF(on->thread_send_lsreq);
THREAD_OFF(on->thread_send_lsack);
THREAD_OFF(on->thread_exchange_done);
THREAD_OFF(on->thread_adj_ok);
-
- return 0;
}
-int inactivity_timer(struct thread *thread)
+void inactivity_timer(struct thread *thread)
{
struct ospf6_neighbor *on;
on->ospf6_if->dead_interval,
&on->inactivity_timer);
}
-
- return 0;
}
timerclear(&res);
- if (on->thread_send_dbdesc)
+ if (thread_is_scheduled(on->thread_send_dbdesc))
timersub(&on->thread_send_dbdesc->u.sands, &now, &res);
timerstring(&res, duration, sizeof(duration));
json_object_int_add(json_neighbor, "pendingLsaDbDescCount",
on->dbdesc_list->count);
json_object_string_add(json_neighbor, "pendingLsaDbDescTime",
duration);
- json_object_string_add(json_neighbor, "dbDescSendThread",
- (on->thread_send_dbdesc ? "on" : "off"));
+ json_object_string_add(
+ json_neighbor, "dbDescSendThread",
+ (thread_is_scheduled(on->thread_send_dbdesc) ? "on"
+ : "off"));
json_array = json_object_new_array();
for (ALL_LSDB(on->dbdesc_list, lsa, lsanext))
json_object_array_add(
json_array);
timerclear(&res);
- if (on->thread_send_lsreq)
+ if (thread_is_scheduled(on->thread_send_lsreq))
timersub(&on->thread_send_lsreq->u.sands, &now, &res);
timerstring(&res, duration, sizeof(duration));
json_object_int_add(json_neighbor, "pendingLsaLsReqCount",
on->request_list->count);
json_object_string_add(json_neighbor, "pendingLsaLsReqTime",
duration);
- json_object_string_add(json_neighbor, "lsReqSendThread",
- (on->thread_send_lsreq ? "on" : "off"));
+ json_object_string_add(
+ json_neighbor, "lsReqSendThread",
+ (thread_is_scheduled(on->thread_send_lsreq) ? "on"
+ : "off"));
json_array = json_object_new_array();
for (ALL_LSDB(on->request_list, lsa, lsanext))
json_object_array_add(
timerclear(&res);
- if (on->thread_send_lsupdate)
+ if (thread_is_scheduled(on->thread_send_lsupdate))
timersub(&on->thread_send_lsupdate->u.sands, &now,
&res);
timerstring(&res, duration, sizeof(duration));
duration);
json_object_string_add(
json_neighbor, "lsUpdateSendThread",
- (on->thread_send_lsupdate ? "on" : "off"));
+ (thread_is_scheduled(on->thread_send_lsupdate)
+ ? "on"
+ : "off"));
json_array = json_object_new_array();
for (ALL_LSDB(on->lsupdate_list, lsa, lsanext))
json_object_array_add(
json_array);
timerclear(&res);
- if (on->thread_send_lsack)
+ if (thread_is_scheduled(on->thread_send_lsack))
timersub(&on->thread_send_lsack->u.sands, &now, &res);
timerstring(&res, duration, sizeof(duration));
json_object_int_add(json_neighbor, "pendingLsaLsAckCount",
on->lsack_list->count);
json_object_string_add(json_neighbor, "pendingLsaLsAckTime",
duration);
- json_object_string_add(json_neighbor, "lsAckSendThread",
- (on->thread_send_lsack ? "on" : "off"));
+ json_object_string_add(
+ json_neighbor, "lsAckSendThread",
+ (thread_is_scheduled(on->thread_send_lsack) ? "on"
+ : "off"));
json_array = json_object_new_array();
for (ALL_LSDB(on->lsack_list, lsa, lsanext))
json_object_array_add(
bfd_sess_show(vty, json_neighbor, on->bfd_session);
- json_object_object_add(json, on->name, json_neighbor);
+ if (on->auth_present == true) {
+ json_object_string_add(json_neighbor, "authStatus",
+ "enabled");
+ json_object_int_add(
+ json_neighbor, "recvdHelloHigherSeqNo",
+ on->seqnum_h[OSPF6_MESSAGE_TYPE_HELLO]);
+ json_object_int_add(
+ json_neighbor, "recvdHelloLowerSeqNo",
+ on->seqnum_l[OSPF6_MESSAGE_TYPE_HELLO]);
+ json_object_int_add(
+ json_neighbor, "recvdDBDescHigherSeqNo",
+ on->seqnum_h[OSPF6_MESSAGE_TYPE_DBDESC]);
+ json_object_int_add(
+ json_neighbor, "recvdDBDescLowerSeqNo",
+ on->seqnum_l[OSPF6_MESSAGE_TYPE_DBDESC]);
+ json_object_int_add(
+ json_neighbor, "recvdLSReqHigherSeqNo",
+ on->seqnum_h[OSPF6_MESSAGE_TYPE_LSREQ]);
+ json_object_int_add(
+ json_neighbor, "recvdLSReqLowerSeqNo",
+ on->seqnum_l[OSPF6_MESSAGE_TYPE_LSREQ]);
+ json_object_int_add(
+ json_neighbor, "recvdLSUpdHigherSeqNo",
+ on->seqnum_h[OSPF6_MESSAGE_TYPE_LSUPDATE]);
+ json_object_int_add(
+ json_neighbor, "recvdLSUpdLowerSeqNo",
+ on->seqnum_l[OSPF6_MESSAGE_TYPE_LSUPDATE]);
+ json_object_int_add(
+ json_neighbor, "recvdLSAckHigherSeqNo",
+ on->seqnum_h[OSPF6_MESSAGE_TYPE_LSACK]);
+ json_object_int_add(
+ json_neighbor, "recvdLSAckLowerSeqNo",
+ on->seqnum_l[OSPF6_MESSAGE_TYPE_LSACK]);
+ } else
+ json_object_string_add(json_neighbor, "authStatus",
+ "disabled");
+ json_object_object_add(json, on->name, json_neighbor);
} else {
vty_out(vty, " Neighbor %s\n", on->name);
vty_out(vty, " %s\n", lsa->name);
timerclear(&res);
- if (on->thread_send_dbdesc)
+ if (thread_is_scheduled(on->thread_send_dbdesc))
timersub(&on->thread_send_dbdesc->u.sands, &now, &res);
timerstring(&res, duration, sizeof(duration));
vty_out(vty,
" %d Pending LSAs for DbDesc in Time %s [thread %s]\n",
on->dbdesc_list->count, duration,
- (on->thread_send_dbdesc ? "on" : "off"));
+ (thread_is_scheduled(on->thread_send_dbdesc) ? "on"
+ : "off"));
for (ALL_LSDB(on->dbdesc_list, lsa, lsanext))
vty_out(vty, " %s\n", lsa->name);
timerclear(&res);
- if (on->thread_send_lsreq)
+ if (thread_is_scheduled(on->thread_send_lsreq))
timersub(&on->thread_send_lsreq->u.sands, &now, &res);
timerstring(&res, duration, sizeof(duration));
vty_out(vty,
" %d Pending LSAs for LSReq in Time %s [thread %s]\n",
on->request_list->count, duration,
- (on->thread_send_lsreq ? "on" : "off"));
+ (thread_is_scheduled(on->thread_send_lsreq) ? "on"
+ : "off"));
for (ALL_LSDB(on->request_list, lsa, lsanext))
vty_out(vty, " %s\n", lsa->name);
timerclear(&res);
- if (on->thread_send_lsupdate)
+ if (thread_is_scheduled(on->thread_send_lsupdate))
timersub(&on->thread_send_lsupdate->u.sands, &now,
&res);
timerstring(&res, duration, sizeof(duration));
vty_out(vty,
" %d Pending LSAs for LSUpdate in Time %s [thread %s]\n",
on->lsupdate_list->count, duration,
- (on->thread_send_lsupdate ? "on" : "off"));
+ (thread_is_scheduled(on->thread_send_lsupdate)
+ ? "on"
+ : "off"));
for (ALL_LSDB(on->lsupdate_list, lsa, lsanext))
vty_out(vty, " %s\n", lsa->name);
timerclear(&res);
- if (on->thread_send_lsack)
+ if (thread_is_scheduled(on->thread_send_lsack))
timersub(&on->thread_send_lsack->u.sands, &now, &res);
timerstring(&res, duration, sizeof(duration));
vty_out(vty,
" %d Pending LSAs for LSAck in Time %s [thread %s]\n",
on->lsack_list->count, duration,
- (on->thread_send_lsack ? "on" : "off"));
+ (thread_is_scheduled(on->thread_send_lsack) ? "on"
+ : "off"));
for (ALL_LSDB(on->lsack_list, lsa, lsanext))
vty_out(vty, " %s\n", lsa->name);
bfd_sess_show(vty, NULL, on->bfd_session);
+
+ if (on->auth_present == true) {
+ vty_out(vty, " Authentication header present\n");
+ vty_out(vty,
+ "\t\t\t hello DBDesc LSReq LSUpd LSAck\n");
+ vty_out(vty,
+ " Higher sequence no 0x%-10X 0x%-10X 0x%-10X 0x%-10X 0x%-10X\n",
+ on->seqnum_h[OSPF6_MESSAGE_TYPE_HELLO],
+ on->seqnum_h[OSPF6_MESSAGE_TYPE_DBDESC],
+ on->seqnum_h[OSPF6_MESSAGE_TYPE_LSREQ],
+ on->seqnum_h[OSPF6_MESSAGE_TYPE_LSUPDATE],
+ on->seqnum_h[OSPF6_MESSAGE_TYPE_LSACK]);
+ vty_out(vty,
+ " Lower sequence no 0x%-10X 0x%-10X 0x%-10X 0x%-10X 0x%-10X\n",
+ on->seqnum_l[OSPF6_MESSAGE_TYPE_HELLO],
+ on->seqnum_l[OSPF6_MESSAGE_TYPE_DBDESC],
+ on->seqnum_l[OSPF6_MESSAGE_TYPE_LSREQ],
+ on->seqnum_l[OSPF6_MESSAGE_TYPE_LSUPDATE],
+ on->seqnum_l[OSPF6_MESSAGE_TYPE_LSACK]);
+ } else
+ vty_out(vty, " Authentication header not present\n");
}
}