forked from Mirror/frr
Merge pull request #8767 from opensourcerouting/ospfd-gr
ospfd: introduce support for Graceful Restart (restarting mode)
This commit is contained in:
commit
000df71ccd
|
@ -2514,6 +2514,7 @@ AC_SUBST([frr_statedir])
|
||||||
AC_DEFINE_UNQUOTED([LDPD_SOCKET], ["$frr_statedir%s%s/ldpd.sock"], [ldpd control socket])
|
AC_DEFINE_UNQUOTED([LDPD_SOCKET], ["$frr_statedir%s%s/ldpd.sock"], [ldpd control socket])
|
||||||
AC_DEFINE_UNQUOTED([ZEBRA_SERV_PATH], ["$frr_statedir%s%s/zserv.api"], [zebra api socket])
|
AC_DEFINE_UNQUOTED([ZEBRA_SERV_PATH], ["$frr_statedir%s%s/zserv.api"], [zebra api socket])
|
||||||
AC_DEFINE_UNQUOTED([BFDD_CONTROL_SOCKET], ["$frr_statedir%s%s/bfdd.sock"], [bfdd control socket])
|
AC_DEFINE_UNQUOTED([BFDD_CONTROL_SOCKET], ["$frr_statedir%s%s/bfdd.sock"], [bfdd control socket])
|
||||||
|
AC_DEFINE_UNQUOTED([OSPFD_GR_STATE], ["$frr_statedir%s/ospfd-gr.json"], [ospfd GR state information])
|
||||||
AC_DEFINE_UNQUOTED([DAEMON_VTY_DIR], ["$frr_statedir%s%s"], [daemon vty directory])
|
AC_DEFINE_UNQUOTED([DAEMON_VTY_DIR], ["$frr_statedir%s%s"], [daemon vty directory])
|
||||||
AC_DEFINE_UNQUOTED([DAEMON_DB_DIR], ["$frr_statedir"], [daemon database directory])
|
AC_DEFINE_UNQUOTED([DAEMON_DB_DIR], ["$frr_statedir"], [daemon database directory])
|
||||||
|
|
||||||
|
|
|
@ -710,8 +710,17 @@ Redistribution
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Graceful Restart Helper
|
Graceful Restart
|
||||||
=======================
|
================
|
||||||
|
|
||||||
|
.. clicmd:: graceful-restart [grace-period (1-1800)]
|
||||||
|
|
||||||
|
|
||||||
|
Configure Graceful Restart (RFC 3623) restarting support.
|
||||||
|
When enabled, the default grace period is 120 seconds.
|
||||||
|
|
||||||
|
To perform a graceful shutdown, the "graceful-restart prepare ip ospf"
|
||||||
|
EXEC-level command needs to be issued before restarting the ospfd daemon.
|
||||||
|
|
||||||
.. clicmd:: graceful-restart helper-only [A.B.C.D]
|
.. clicmd:: graceful-restart helper-only [A.B.C.D]
|
||||||
|
|
||||||
|
@ -743,6 +752,17 @@ Graceful Restart Helper
|
||||||
restarts. By default, it supports both planned and
|
restarts. By default, it supports both planned and
|
||||||
unplanned outages.
|
unplanned outages.
|
||||||
|
|
||||||
|
|
||||||
|
.. clicmd:: graceful-restart prepare ip ospf
|
||||||
|
|
||||||
|
|
||||||
|
Initiate a graceful restart for all OSPF instances configured with the
|
||||||
|
"graceful-restart" command. The ospfd daemon should be restarted during
|
||||||
|
the instance-specific grace period, otherwise the graceful restart will fail.
|
||||||
|
|
||||||
|
This is an EXEC-level command.
|
||||||
|
|
||||||
|
|
||||||
.. _showing-ospf-information:
|
.. _showing-ospf-information:
|
||||||
|
|
||||||
Showing Information
|
Showing Information
|
||||||
|
|
|
@ -438,6 +438,8 @@ struct cmd_node {
|
||||||
#define BFD_PROFILE_STR "BFD profile.\n"
|
#define BFD_PROFILE_STR "BFD profile.\n"
|
||||||
#define BFD_PROFILE_NAME_STR "BFD profile name.\n"
|
#define BFD_PROFILE_NAME_STR "BFD profile name.\n"
|
||||||
#define SHARP_STR "Sharp Routing Protocol\n"
|
#define SHARP_STR "Sharp Routing Protocol\n"
|
||||||
|
#define OSPF_GR_STR \
|
||||||
|
"OSPF non-stop forwarding (NSF) also known as OSPF Graceful Restart\n"
|
||||||
|
|
||||||
#define CMD_VNI_RANGE "(1-16777215)"
|
#define CMD_VNI_RANGE "(1-16777215)"
|
||||||
#define CONF_BACKUP_EXT ".sav"
|
#define CONF_BACKUP_EXT ".sav"
|
||||||
|
|
|
@ -1694,6 +1694,9 @@ static void ospf_abr_manage_discard_routes(struct ospf *ospf)
|
||||||
|
|
||||||
static void ospf_abr_nssa_task(struct ospf *ospf) /* called only if any_nssa */
|
static void ospf_abr_nssa_task(struct ospf *ospf) /* called only if any_nssa */
|
||||||
{
|
{
|
||||||
|
if (ospf->gr_info.restart_in_progress)
|
||||||
|
return;
|
||||||
|
|
||||||
if (IS_DEBUG_OSPF_NSSA)
|
if (IS_DEBUG_OSPF_NSSA)
|
||||||
zlog_debug("Check for NSSA-ABR Tasks():");
|
zlog_debug("Check for NSSA-ABR Tasks():");
|
||||||
|
|
||||||
|
@ -1758,6 +1761,9 @@ static void ospf_abr_nssa_task(struct ospf *ospf) /* called only if any_nssa */
|
||||||
summary-LSA origination and flooding. */
|
summary-LSA origination and flooding. */
|
||||||
void ospf_abr_task(struct ospf *ospf)
|
void ospf_abr_task(struct ospf *ospf)
|
||||||
{
|
{
|
||||||
|
if (ospf->gr_info.restart_in_progress)
|
||||||
|
return;
|
||||||
|
|
||||||
if (IS_DEBUG_OSPF_EVENT)
|
if (IS_DEBUG_OSPF_EVENT)
|
||||||
zlog_debug("ospf_abr_task(): Start");
|
zlog_debug("ospf_abr_task(): Start");
|
||||||
|
|
||||||
|
|
|
@ -609,6 +609,16 @@ static int ospf_ase_calculate_timer(struct thread *t)
|
||||||
+ (stop_time.tv_usec
|
+ (stop_time.tv_usec
|
||||||
- start_time.tv_usec));
|
- start_time.tv_usec));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Uninstall remnant routes that were installed before the restart, but
|
||||||
|
* that are no longer valid.
|
||||||
|
*/
|
||||||
|
if (ospf->gr_info.finishing_restart) {
|
||||||
|
ospf_zebra_gr_disable(ospf);
|
||||||
|
ospf->gr_info.finishing_restart = false;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1552,21 +1552,16 @@ DEFUN(no_debug_ospf_ldp_sync,
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFPY (debug_ospf_gr,
|
DEFPY(debug_ospf_gr, debug_ospf_gr_cmd, "[no$no] debug ospf graceful-restart",
|
||||||
debug_ospf_gr_cmd,
|
NO_STR DEBUG_STR OSPF_STR "OSPF Graceful Restart\n")
|
||||||
"[no$no] debug ospf graceful-restart helper",
|
|
||||||
NO_STR
|
|
||||||
DEBUG_STR OSPF_STR
|
|
||||||
"Gracefull restart\n"
|
|
||||||
"Helper Information\n")
|
|
||||||
{
|
{
|
||||||
if (vty->node == CONFIG_NODE)
|
if (vty->node == CONFIG_NODE)
|
||||||
CONF_DEBUG_ON(gr, GR_HELPER);
|
CONF_DEBUG_ON(gr, GR);
|
||||||
|
|
||||||
if (!no)
|
if (!no)
|
||||||
TERM_DEBUG_ON(gr, GR_HELPER);
|
TERM_DEBUG_ON(gr, GR);
|
||||||
else
|
else
|
||||||
TERM_DEBUG_OFF(gr, GR_HELPER);
|
TERM_DEBUG_OFF(gr, GR);
|
||||||
|
|
||||||
return CMD_SUCCESS;
|
return CMD_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -1764,9 +1759,9 @@ static int show_debugging_ospf_common(struct vty *vty)
|
||||||
if (IS_DEBUG_OSPF(ldp_sync, LDP_SYNC) == OSPF_DEBUG_LDP_SYNC)
|
if (IS_DEBUG_OSPF(ldp_sync, LDP_SYNC) == OSPF_DEBUG_LDP_SYNC)
|
||||||
vty_out(vty, " OSPF ldp-sync debugging is on\n");
|
vty_out(vty, " OSPF ldp-sync debugging is on\n");
|
||||||
|
|
||||||
/* Show debug status for GR helper. */
|
/* Show debug status for GR. */
|
||||||
if (IS_DEBUG_OSPF(gr, GR_HELPER) == OSPF_DEBUG_GR_HELPER)
|
if (IS_DEBUG_OSPF(gr, GR) == OSPF_DEBUG_GR)
|
||||||
vty_out(vty, " OSPF Graceful Restart Helper debugging is on\n");
|
vty_out(vty, " OSPF Graceful Restart debugging is on\n");
|
||||||
|
|
||||||
if (IS_DEBUG_OSPF(bfd, BFD_LIB) == OSPF_DEBUG_BFD_LIB)
|
if (IS_DEBUG_OSPF(bfd, BFD_LIB) == OSPF_DEBUG_BFD_LIB)
|
||||||
vty_out(vty,
|
vty_out(vty,
|
||||||
|
@ -1953,9 +1948,9 @@ static int config_write_debug(struct vty *vty)
|
||||||
write = 1;
|
write = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* debug ospf gr helper */
|
/* debug ospf gr */
|
||||||
if (IS_CONF_DEBUG_OSPF(gr, GR_HELPER) == OSPF_DEBUG_GR_HELPER) {
|
if (IS_CONF_DEBUG_OSPF(gr, GR) == OSPF_DEBUG_GR) {
|
||||||
vty_out(vty, "debug ospf%s graceful-restart helper\n", str);
|
vty_out(vty, "debug ospf%s graceful-restart\n", str);
|
||||||
write = 1;
|
write = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,8 +64,7 @@
|
||||||
#define OSPF_DEBUG_DEFAULTINFO 0x20
|
#define OSPF_DEBUG_DEFAULTINFO 0x20
|
||||||
#define OSPF_DEBUG_LDP_SYNC 0x40
|
#define OSPF_DEBUG_LDP_SYNC 0x40
|
||||||
|
|
||||||
#define OSPF_DEBUG_GR_HELPER 0x01
|
#define OSPF_DEBUG_GR 0x01
|
||||||
#define OSPF_DEBUG_GR 0x03
|
|
||||||
|
|
||||||
#define OSPF_DEBUG_BFD_LIB 0x01
|
#define OSPF_DEBUG_BFD_LIB 0x01
|
||||||
|
|
||||||
|
@ -118,7 +117,7 @@
|
||||||
#define IS_DEBUG_OSPF_DEFAULT_INFO IS_DEBUG_OSPF(defaultinfo, DEFAULTINFO)
|
#define IS_DEBUG_OSPF_DEFAULT_INFO IS_DEBUG_OSPF(defaultinfo, DEFAULTINFO)
|
||||||
|
|
||||||
#define IS_DEBUG_OSPF_LDP_SYNC IS_DEBUG_OSPF(ldp_sync, LDP_SYNC)
|
#define IS_DEBUG_OSPF_LDP_SYNC IS_DEBUG_OSPF(ldp_sync, LDP_SYNC)
|
||||||
#define IS_DEBUG_OSPF_GR_HELPER IS_DEBUG_OSPF(gr, GR_HELPER)
|
#define IS_DEBUG_OSPF_GR IS_DEBUG_OSPF(gr, GR)
|
||||||
|
|
||||||
#define IS_CONF_DEBUG_OSPF_PACKET(a, b) \
|
#define IS_CONF_DEBUG_OSPF_PACKET(a, b) \
|
||||||
(conf_debug_ospf_packet[a] & OSPF_DEBUG_##b)
|
(conf_debug_ospf_packet[a] & OSPF_DEBUG_##b)
|
||||||
|
|
|
@ -379,13 +379,13 @@ int ospf_flood(struct ospf *ospf, struct ospf_neighbor *nbr,
|
||||||
SET_FLAG(new->flags, OSPF_LSA_RECEIVED);
|
SET_FLAG(new->flags, OSPF_LSA_RECEIVED);
|
||||||
(void)ospf_lsa_is_self_originated(ospf, new); /* Let it set the flag */
|
(void)ospf_lsa_is_self_originated(ospf, new); /* Let it set the flag */
|
||||||
|
|
||||||
/* Received Grace LSA */
|
/* Received non-self-originated Grace LSA */
|
||||||
if (IS_GRACE_LSA(new)) {
|
if (IS_GRACE_LSA(new) && !IS_LSA_SELF(new)) {
|
||||||
|
|
||||||
if (IS_LSA_MAXAGE(new)) {
|
if (IS_LSA_MAXAGE(new)) {
|
||||||
|
|
||||||
/* Handling Max age grace LSA.*/
|
/* Handling Max age grace LSA.*/
|
||||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
if (IS_DEBUG_OSPF_GR)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s, Received a maxage GRACE-LSA from router %pI4",
|
"%s, Received a maxage GRACE-LSA from router %pI4",
|
||||||
__func__, &new->data->adv_router);
|
__func__, &new->data->adv_router);
|
||||||
|
@ -393,21 +393,21 @@ int ospf_flood(struct ospf *ospf, struct ospf_neighbor *nbr,
|
||||||
if (current) {
|
if (current) {
|
||||||
ospf_process_maxage_grace_lsa(ospf, new, nbr);
|
ospf_process_maxage_grace_lsa(ospf, new, nbr);
|
||||||
} else {
|
} else {
|
||||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
if (IS_DEBUG_OSPF_GR)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s, Grace LSA doesn't exist in lsdb, so discarding grace lsa",
|
"%s, Grace LSA doesn't exist in lsdb, so discarding grace lsa",
|
||||||
__func__);
|
__func__);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
if (IS_DEBUG_OSPF_GR)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s, Received a GRACE-LSA from router %pI4",
|
"%s, Received a GRACE-LSA from router %pI4",
|
||||||
__func__, &new->data->adv_router);
|
__func__, &new->data->adv_router);
|
||||||
|
|
||||||
if (ospf_process_grace_lsa(ospf, new, nbr)
|
if (ospf_process_grace_lsa(ospf, new, nbr)
|
||||||
== OSPF_GR_NOT_HELPER) {
|
== OSPF_GR_NOT_HELPER) {
|
||||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
if (IS_DEBUG_OSPF_GR)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s, Not moving to HELPER role, So discarding grace LSA",
|
"%s, Not moving to HELPER role, So discarding grace LSA",
|
||||||
__func__);
|
__func__);
|
||||||
|
@ -445,7 +445,7 @@ int ospf_flood(struct ospf *ospf, struct ospf_neighbor *nbr,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* OSPF LSA flooding -- RFC2328 Section 13.3. */
|
/* OSPF LSA flooding -- RFC2328 Section 13.3. */
|
||||||
static int ospf_flood_through_interface(struct ospf_interface *oi,
|
int ospf_flood_through_interface(struct ospf_interface *oi,
|
||||||
struct ospf_neighbor *inbr,
|
struct ospf_neighbor *inbr,
|
||||||
struct ospf_lsa *lsa)
|
struct ospf_lsa *lsa)
|
||||||
{
|
{
|
||||||
|
@ -1031,25 +1031,50 @@ void ospf_ls_retransmit_delete_nbr_as(struct ospf *ospf, struct ospf_lsa *lsa)
|
||||||
flushing an LSA from the whole domain. */
|
flushing an LSA from the whole domain. */
|
||||||
void ospf_lsa_flush_area(struct ospf_lsa *lsa, struct ospf_area *area)
|
void ospf_lsa_flush_area(struct ospf_lsa *lsa, struct ospf_area *area)
|
||||||
{
|
{
|
||||||
|
struct ospf *ospf = area->ospf;
|
||||||
|
|
||||||
|
if (ospf_lsa_is_self_originated(ospf, lsa)
|
||||||
|
&& ospf->gr_info.restart_in_progress) {
|
||||||
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
||||||
|
zlog_debug(
|
||||||
|
"%s:LSA[Type%d:%pI4]: Graceful Restart in progress -- not flushing self-originated LSA",
|
||||||
|
ospf_get_name(ospf), lsa->data->type,
|
||||||
|
&lsa->data->id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Reset the lsa origination time such that it gives
|
/* Reset the lsa origination time such that it gives
|
||||||
more time for the ACK to be received and avoid
|
more time for the ACK to be received and avoid
|
||||||
retransmissions */
|
retransmissions */
|
||||||
lsa->data->ls_age = htons(OSPF_LSA_MAXAGE);
|
lsa->data->ls_age = htons(OSPF_LSA_MAXAGE);
|
||||||
if (IS_DEBUG_OSPF_EVENT)
|
if (IS_DEBUG_OSPF_EVENT)
|
||||||
zlog_debug("%s: MAXAGE set to LSA %pI4", __func__,
|
zlog_debug("%s: MaxAge set to LSA[%s]", __func__,
|
||||||
&lsa->data->id);
|
dump_lsa_key(lsa));
|
||||||
monotime(&lsa->tv_recv);
|
monotime(&lsa->tv_recv);
|
||||||
lsa->tv_orig = lsa->tv_recv;
|
lsa->tv_orig = lsa->tv_recv;
|
||||||
ospf_flood_through_area(area, NULL, lsa);
|
ospf_flood_through_area(area, NULL, lsa);
|
||||||
ospf_lsa_maxage(area->ospf, lsa);
|
ospf_lsa_maxage(ospf, lsa);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ospf_lsa_flush_as(struct ospf *ospf, struct ospf_lsa *lsa)
|
void ospf_lsa_flush_as(struct ospf *ospf, struct ospf_lsa *lsa)
|
||||||
{
|
{
|
||||||
|
if (ospf_lsa_is_self_originated(ospf, lsa)
|
||||||
|
&& ospf->gr_info.restart_in_progress) {
|
||||||
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
||||||
|
zlog_debug(
|
||||||
|
"%s:LSA[Type%d:%pI4]: Graceful Restart in progress -- not flushing self-originated LSA",
|
||||||
|
ospf_get_name(ospf), lsa->data->type,
|
||||||
|
&lsa->data->id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Reset the lsa origination time such that it gives
|
/* Reset the lsa origination time such that it gives
|
||||||
more time for the ACK to be received and avoid
|
more time for the ACK to be received and avoid
|
||||||
retransmissions */
|
retransmissions */
|
||||||
lsa->data->ls_age = htons(OSPF_LSA_MAXAGE);
|
lsa->data->ls_age = htons(OSPF_LSA_MAXAGE);
|
||||||
|
if (IS_DEBUG_OSPF_EVENT)
|
||||||
|
zlog_debug("%s: MaxAge set to LSA[%s]", __func__,
|
||||||
|
dump_lsa_key(lsa));
|
||||||
monotime(&lsa->tv_recv);
|
monotime(&lsa->tv_recv);
|
||||||
lsa->tv_orig = lsa->tv_recv;
|
lsa->tv_orig = lsa->tv_recv;
|
||||||
ospf_flood_through_as(ospf, NULL, lsa);
|
ospf_flood_through_as(ospf, NULL, lsa);
|
||||||
|
|
|
@ -30,6 +30,9 @@ extern int ospf_flood_through_area(struct ospf_area *, struct ospf_neighbor *,
|
||||||
struct ospf_lsa *);
|
struct ospf_lsa *);
|
||||||
extern int ospf_flood_through_as(struct ospf *, struct ospf_neighbor *,
|
extern int ospf_flood_through_as(struct ospf *, struct ospf_neighbor *,
|
||||||
struct ospf_lsa *);
|
struct ospf_lsa *);
|
||||||
|
extern int ospf_flood_through_interface(struct ospf_interface *oi,
|
||||||
|
struct ospf_neighbor *inbr,
|
||||||
|
struct ospf_lsa *lsa);
|
||||||
|
|
||||||
extern unsigned long ospf_ls_request_count(struct ospf_neighbor *);
|
extern unsigned long ospf_ls_request_count(struct ospf_neighbor *);
|
||||||
extern int ospf_ls_request_isempty(struct ospf_neighbor *);
|
extern int ospf_ls_request_isempty(struct ospf_neighbor *);
|
||||||
|
|
824
ospfd/ospf_gr.c
Normal file
824
ospfd/ospf_gr.c
Normal file
|
@ -0,0 +1,824 @@
|
||||||
|
/*
|
||||||
|
* This is an implementation of RFC 3623 Graceful OSPF Restart.
|
||||||
|
*
|
||||||
|
* Copyright 2021 NetDEF (c), All rights reserved.
|
||||||
|
* Copyright 2020 6WIND (c), All rights reserved.
|
||||||
|
*
|
||||||
|
* This program 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 of the License, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program 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>
|
||||||
|
|
||||||
|
#include "memory.h"
|
||||||
|
#include "command.h"
|
||||||
|
#include "table.h"
|
||||||
|
#include "vty.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "printfrr.h"
|
||||||
|
|
||||||
|
#include "ospfd/ospfd.h"
|
||||||
|
#include "ospfd/ospf_abr.h"
|
||||||
|
#include "ospfd/ospf_flood.h"
|
||||||
|
#include "ospfd/ospf_ism.h"
|
||||||
|
#include "ospfd/ospf_interface.h"
|
||||||
|
#include "ospfd/ospf_asbr.h"
|
||||||
|
#include "ospfd/ospf_lsa.h"
|
||||||
|
#include "ospfd/ospf_route.h"
|
||||||
|
#include "ospfd/ospf_zebra.h"
|
||||||
|
#include "ospfd/ospf_lsdb.h"
|
||||||
|
#include "ospfd/ospf_neighbor.h"
|
||||||
|
#include "ospfd/ospf_opaque.h"
|
||||||
|
#include "ospfd/ospf_nsm.h"
|
||||||
|
#include "ospfd/ospf_gr.h"
|
||||||
|
#include "ospfd/ospf_errors.h"
|
||||||
|
#include "ospfd/ospf_dump.h"
|
||||||
|
#ifndef VTYSH_EXTRACT_PL
|
||||||
|
#include "ospfd/ospf_gr_clippy.c"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void ospf_gr_nvm_delete(struct ospf *ospf);
|
||||||
|
|
||||||
|
/* Lookup self-originated Grace-LSA in the LSDB. */
|
||||||
|
static struct ospf_lsa *ospf_gr_lsa_lookup(struct ospf *ospf,
|
||||||
|
struct ospf_area *area)
|
||||||
|
{
|
||||||
|
struct ospf_lsa *lsa;
|
||||||
|
struct in_addr lsa_id;
|
||||||
|
uint32_t lsa_id_host_byte_order;
|
||||||
|
|
||||||
|
lsa_id_host_byte_order = SET_OPAQUE_LSID(OPAQUE_TYPE_GRACE_LSA, 0);
|
||||||
|
lsa_id.s_addr = htonl(lsa_id_host_byte_order);
|
||||||
|
lsa = ospf_lsa_lookup(ospf, area, OSPF_OPAQUE_LINK_LSA, lsa_id,
|
||||||
|
ospf->router_id);
|
||||||
|
|
||||||
|
return lsa;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Fill in fields of the Grace-LSA that is being originated. */
|
||||||
|
static void ospf_gr_lsa_body_set(struct ospf_gr_info *gr_info,
|
||||||
|
struct ospf_interface *oi, struct stream *s)
|
||||||
|
{
|
||||||
|
struct grace_tlv_graceperiod tlv_period = {};
|
||||||
|
struct grace_tlv_restart_reason tlv_reason = {};
|
||||||
|
struct grace_tlv_restart_addr tlv_address = {};
|
||||||
|
|
||||||
|
/* Put grace period. */
|
||||||
|
tlv_period.header.type = htons(GRACE_PERIOD_TYPE);
|
||||||
|
tlv_period.header.length = htons(GRACE_PERIOD_LENGTH);
|
||||||
|
tlv_period.interval = htonl(gr_info->grace_period);
|
||||||
|
stream_put(s, &tlv_period, sizeof(tlv_period));
|
||||||
|
|
||||||
|
/* Put restart reason. */
|
||||||
|
tlv_reason.header.type = htons(RESTART_REASON_TYPE);
|
||||||
|
tlv_reason.header.length = htons(RESTART_REASON_LENGTH);
|
||||||
|
if (gr_info->restart_support)
|
||||||
|
tlv_reason.reason = OSPF_GR_SW_RESTART;
|
||||||
|
else
|
||||||
|
tlv_reason.reason = OSPF_GR_UNKNOWN_RESTART;
|
||||||
|
stream_put(s, &tlv_reason, sizeof(tlv_reason));
|
||||||
|
|
||||||
|
/* Put IP address. */
|
||||||
|
if (oi->type == OSPF_IFTYPE_BROADCAST || oi->type == OSPF_IFTYPE_NBMA
|
||||||
|
|| oi->type == OSPF_IFTYPE_POINTOMULTIPOINT) {
|
||||||
|
tlv_address.header.type = htons(RESTARTER_IP_ADDR_TYPE);
|
||||||
|
tlv_address.header.length = htons(RESTARTER_IP_ADDR_LEN);
|
||||||
|
tlv_address.addr = oi->address->u.prefix4;
|
||||||
|
stream_put(s, &tlv_address, sizeof(tlv_address));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generate Grace-LSA for a given interface. */
|
||||||
|
static struct ospf_lsa *ospf_gr_lsa_new(struct ospf_interface *oi)
|
||||||
|
{
|
||||||
|
struct stream *s;
|
||||||
|
struct lsa_header *lsah;
|
||||||
|
struct ospf_lsa *new;
|
||||||
|
uint8_t options, lsa_type;
|
||||||
|
struct in_addr lsa_id;
|
||||||
|
uint32_t lsa_id_host_byte_order;
|
||||||
|
uint16_t length;
|
||||||
|
|
||||||
|
/* Create a stream for LSA. */
|
||||||
|
s = stream_new(OSPF_MAX_LSA_SIZE);
|
||||||
|
|
||||||
|
lsah = (struct lsa_header *)STREAM_DATA(s);
|
||||||
|
|
||||||
|
options = LSA_OPTIONS_GET(oi->area);
|
||||||
|
options |= LSA_OPTIONS_NSSA_GET(oi->area);
|
||||||
|
options |= OSPF_OPTION_O;
|
||||||
|
|
||||||
|
lsa_type = OSPF_OPAQUE_LINK_LSA;
|
||||||
|
lsa_id_host_byte_order = SET_OPAQUE_LSID(OPAQUE_TYPE_GRACE_LSA, 0);
|
||||||
|
lsa_id.s_addr = htonl(lsa_id_host_byte_order);
|
||||||
|
|
||||||
|
/* Set opaque-LSA header fields. */
|
||||||
|
lsa_header_set(s, options, lsa_type, lsa_id, oi->ospf->router_id);
|
||||||
|
|
||||||
|
/* Set opaque-LSA body fields. */
|
||||||
|
ospf_gr_lsa_body_set(&oi->ospf->gr_info, oi, s);
|
||||||
|
|
||||||
|
/* Set length. */
|
||||||
|
length = stream_get_endp(s);
|
||||||
|
lsah->length = htons(length);
|
||||||
|
|
||||||
|
/* Now, create an OSPF LSA instance. */
|
||||||
|
new = ospf_lsa_new_and_data(length);
|
||||||
|
|
||||||
|
if (IS_DEBUG_OSPF_GR)
|
||||||
|
zlog_debug("LSA[Type%d:%pI4]: Create an Opaque-LSA/GR instance",
|
||||||
|
lsa_type, &lsa_id);
|
||||||
|
|
||||||
|
new->area = oi->area;
|
||||||
|
new->oi = oi;
|
||||||
|
SET_FLAG(new->flags, OSPF_LSA_SELF);
|
||||||
|
memcpy(new->data, lsah, length);
|
||||||
|
stream_free(s);
|
||||||
|
|
||||||
|
return new;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Originate and install Grace-LSA for a given interface. */
|
||||||
|
static void ospf_gr_lsa_originate(struct ospf_interface *oi)
|
||||||
|
{
|
||||||
|
struct ospf_lsa *lsa, *old;
|
||||||
|
|
||||||
|
if (ospf_interface_neighbor_count(oi) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Create new Grace-LSA. */
|
||||||
|
lsa = ospf_gr_lsa_new(oi);
|
||||||
|
if (!lsa) {
|
||||||
|
zlog_warn("%s: ospf_gr_lsa_new() failed", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find the old LSA and increase the seqno. */
|
||||||
|
old = ospf_gr_lsa_lookup(oi->ospf, oi->area);
|
||||||
|
if (old)
|
||||||
|
lsa->data->ls_seqnum = lsa_seqnum_increment(old);
|
||||||
|
|
||||||
|
/* Install this LSA into LSDB. */
|
||||||
|
if (ospf_lsa_install(oi->ospf, oi, lsa) == NULL) {
|
||||||
|
zlog_warn("%s: ospf_lsa_install() failed", __func__);
|
||||||
|
ospf_lsa_unlock(&lsa);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update new LSA origination count. */
|
||||||
|
oi->ospf->lsa_originate_count++;
|
||||||
|
|
||||||
|
/* Flood the LSA through out the interface */
|
||||||
|
ospf_flood_through_interface(oi, NULL, lsa);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Flush a given self-originated Grace-LSA. */
|
||||||
|
static struct ospf_lsa *ospf_gr_flush_grace_lsa(struct ospf_interface *oi,
|
||||||
|
struct ospf_lsa *old)
|
||||||
|
{
|
||||||
|
struct ospf_lsa *lsa;
|
||||||
|
|
||||||
|
if (ospf_interface_neighbor_count(oi) == 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (IS_DEBUG_OSPF_GR)
|
||||||
|
zlog_debug(
|
||||||
|
"GR: flushing self-originated Grace-LSAs [interface %s]",
|
||||||
|
oi->ifp->name);
|
||||||
|
|
||||||
|
lsa = ospf_lsa_dup(old);
|
||||||
|
lsa->data->ls_age = htons(OSPF_LSA_MAXAGE);
|
||||||
|
lsa->data->ls_seqnum = lsa_seqnum_increment(lsa);
|
||||||
|
|
||||||
|
/* Install updated LSA into LSDB. */
|
||||||
|
if (ospf_lsa_install(oi->ospf, oi, lsa) == NULL) {
|
||||||
|
zlog_warn("%s: ospf_lsa_install() failed", __func__);
|
||||||
|
ospf_lsa_unlock(&lsa);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Flood the LSA through out the interface */
|
||||||
|
ospf_flood_through_interface(oi, NULL, lsa);
|
||||||
|
|
||||||
|
return lsa;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Flush all self-originated Grace-LSAs. */
|
||||||
|
static void ospf_gr_flush_grace_lsas(struct ospf *ospf)
|
||||||
|
{
|
||||||
|
struct ospf_area *area;
|
||||||
|
struct listnode *anode;
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(ospf->areas, anode, area)) {
|
||||||
|
struct ospf_lsa *lsa;
|
||||||
|
struct ospf_interface *oi;
|
||||||
|
struct listnode *inode;
|
||||||
|
|
||||||
|
if (IS_DEBUG_OSPF_GR)
|
||||||
|
zlog_debug(
|
||||||
|
"GR: flushing self-originated Grace-LSAs [area %pI4]",
|
||||||
|
&area->area_id);
|
||||||
|
|
||||||
|
lsa = ospf_gr_lsa_lookup(ospf, area);
|
||||||
|
if (!lsa) {
|
||||||
|
zlog_warn("%s: Grace-LSA not found [area %pI4]",
|
||||||
|
__func__, &area->area_id);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(area->oiflist, inode, oi))
|
||||||
|
ospf_gr_flush_grace_lsa(oi, lsa);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Exit from the Graceful Restart mode. */
|
||||||
|
static void ospf_gr_restart_exit(struct ospf *ospf, const char *reason)
|
||||||
|
{
|
||||||
|
struct ospf_area *area;
|
||||||
|
struct listnode *onode, *anode;
|
||||||
|
|
||||||
|
if (IS_DEBUG_OSPF_GR)
|
||||||
|
zlog_debug("GR: exiting graceful restart: %s", reason);
|
||||||
|
|
||||||
|
ospf->gr_info.restart_in_progress = false;
|
||||||
|
OSPF_TIMER_OFF(ospf->gr_info.t_grace_period);
|
||||||
|
|
||||||
|
/* Record in non-volatile memory that the restart is complete. */
|
||||||
|
ospf_gr_nvm_delete(ospf);
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(ospf->areas, onode, area)) {
|
||||||
|
struct ospf_interface *oi;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 1) The router should reoriginate its router-LSAs for all
|
||||||
|
* attached areas in order to make sure they have the correct
|
||||||
|
* contents.
|
||||||
|
*/
|
||||||
|
ospf_router_lsa_update_area(area);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 2) The router should reoriginate network-LSAs on all segments
|
||||||
|
* where it is the Designated Router.
|
||||||
|
*/
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(area->oiflist, anode, oi))
|
||||||
|
if (oi->state == ISM_DR)
|
||||||
|
ospf_network_lsa_update(oi);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 5) Any received self-originated LSAs that are no longer valid should
|
||||||
|
* be flushed.
|
||||||
|
*/
|
||||||
|
ospf_schedule_abr_task(ospf);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 3) The router reruns its OSPF routing calculations, this time
|
||||||
|
* installing the results into the system forwarding table, and
|
||||||
|
* originating summary-LSAs, Type-7 LSAs and AS-external-LSAs as
|
||||||
|
* necessary.
|
||||||
|
*
|
||||||
|
* 4) Any remnant entries in the system forwarding table that were
|
||||||
|
* installed before the restart, but that are no longer valid,
|
||||||
|
* should be removed.
|
||||||
|
*/
|
||||||
|
ospf->gr_info.finishing_restart = true;
|
||||||
|
ospf_spf_calculate_schedule(ospf, SPF_FLAG_GR_FINISH);
|
||||||
|
|
||||||
|
/* 6) Any grace-LSAs that the router originated should be flushed. */
|
||||||
|
ospf_gr_flush_grace_lsas(ospf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if a Router-LSA contains a given link. */
|
||||||
|
static bool ospf_router_lsa_contains_adj(struct ospf_lsa *lsa,
|
||||||
|
struct in_addr *id)
|
||||||
|
{
|
||||||
|
struct router_lsa *rl;
|
||||||
|
|
||||||
|
rl = (struct router_lsa *)lsa->data;
|
||||||
|
for (int i = 0; i < ntohs(rl->links); i++) {
|
||||||
|
struct in_addr *link_id = &rl->link[i].link_id;
|
||||||
|
|
||||||
|
if (rl->link[i].type != LSA_LINK_TYPE_POINTOPOINT)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (IPV4_ADDR_SAME(id, link_id))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ospf_gr_check_router_lsa_consistency(struct ospf *ospf,
|
||||||
|
struct ospf_area *area,
|
||||||
|
struct ospf_lsa *lsa)
|
||||||
|
{
|
||||||
|
if (CHECK_FLAG(lsa->flags, OSPF_LSA_SELF)) {
|
||||||
|
struct ospf_lsa *lsa_self = lsa;
|
||||||
|
struct router_lsa *rl = (struct router_lsa *)lsa->data;
|
||||||
|
|
||||||
|
for (int i = 0; i < ntohs(rl->links); i++) {
|
||||||
|
struct in_addr *link_id = &rl->link[i].link_id;
|
||||||
|
struct ospf_lsa *lsa_adj;
|
||||||
|
|
||||||
|
if (rl->link[i].type != LSA_LINK_TYPE_POINTOPOINT)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
lsa_adj = ospf_lsa_lookup_by_id(area, OSPF_ROUTER_LSA,
|
||||||
|
*link_id);
|
||||||
|
if (!lsa_adj)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!ospf_router_lsa_contains_adj(lsa_adj,
|
||||||
|
&lsa_self->data->id))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
struct ospf_lsa *lsa_self;
|
||||||
|
|
||||||
|
lsa_self = ospf_lsa_lookup_by_id(area, OSPF_ROUTER_LSA,
|
||||||
|
ospf->router_id);
|
||||||
|
if (!lsa_self
|
||||||
|
|| !CHECK_FLAG(lsa_self->flags, OSPF_LSA_RECEIVED))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (ospf_router_lsa_contains_adj(lsa, &ospf->router_id)
|
||||||
|
!= ospf_router_lsa_contains_adj(lsa_self, &lsa->data->id))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check for LSAs that are inconsistent with the pre-restart LSAs, and abort the
|
||||||
|
* ongoing graceful restart when that's the case.
|
||||||
|
*/
|
||||||
|
void ospf_gr_check_lsdb_consistency(struct ospf *ospf, struct ospf_area *area)
|
||||||
|
{
|
||||||
|
struct route_node *rn;
|
||||||
|
struct ospf_lsa *lsa;
|
||||||
|
|
||||||
|
for (rn = route_top(ROUTER_LSDB(area)); rn; rn = route_next(rn)) {
|
||||||
|
lsa = rn->info;
|
||||||
|
if (!lsa)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!ospf_gr_check_router_lsa_consistency(ospf, area, lsa)) {
|
||||||
|
char reason[256];
|
||||||
|
|
||||||
|
snprintfrr(reason, sizeof(reason),
|
||||||
|
"detected inconsistent LSA[%s] [area %pI4]",
|
||||||
|
dump_lsa_key(lsa), &area->area_id);
|
||||||
|
ospf_gr_restart_exit(ospf, reason);
|
||||||
|
route_unlock_node(rn);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Lookup neighbor by address in a given OSPF area. */
|
||||||
|
static struct ospf_neighbor *
|
||||||
|
ospf_area_nbr_lookup_by_addr(struct ospf_area *area, struct in_addr *addr)
|
||||||
|
{
|
||||||
|
struct ospf_interface *oi;
|
||||||
|
struct ospf_neighbor *nbr;
|
||||||
|
struct listnode *node;
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(area->oiflist, node, oi)) {
|
||||||
|
nbr = ospf_nbr_lookup_by_addr(oi->nbrs, addr);
|
||||||
|
if (nbr)
|
||||||
|
return nbr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Lookup neighbor by Router ID in a given OSPF area. */
|
||||||
|
static struct ospf_neighbor *
|
||||||
|
ospf_area_nbr_lookup_by_routerid(struct ospf_area *area, struct in_addr *id)
|
||||||
|
{
|
||||||
|
struct ospf_interface *oi;
|
||||||
|
struct ospf_neighbor *nbr;
|
||||||
|
struct listnode *node;
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(area->oiflist, node, oi)) {
|
||||||
|
nbr = ospf_nbr_lookup_by_routerid(oi->nbrs, id);
|
||||||
|
if (nbr)
|
||||||
|
return nbr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if there's a fully formed adjacency with the given neighbor ID. */
|
||||||
|
static bool ospf_gr_check_adj_id(struct ospf_area *area,
|
||||||
|
struct in_addr *nbr_id)
|
||||||
|
{
|
||||||
|
struct ospf_neighbor *nbr;
|
||||||
|
|
||||||
|
nbr = ospf_area_nbr_lookup_by_routerid(area, nbr_id);
|
||||||
|
if (!nbr || nbr->state < NSM_Full) {
|
||||||
|
if (IS_DEBUG_OSPF_GR)
|
||||||
|
zlog_debug("GR: missing adjacency to router %pI4",
|
||||||
|
nbr_id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ospf_gr_check_adjs_lsa_transit(struct ospf_area *area,
|
||||||
|
struct in_addr *link_id)
|
||||||
|
{
|
||||||
|
struct ospf *ospf = area->ospf;
|
||||||
|
struct ospf_interface *oi;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if the transit network refers to a local interface (in which
|
||||||
|
* case it must be a DR for that network).
|
||||||
|
*/
|
||||||
|
oi = ospf_if_lookup_by_local_addr(ospf, NULL, *link_id);
|
||||||
|
if (oi) {
|
||||||
|
struct ospf_lsa *lsa;
|
||||||
|
struct network_lsa *nlsa;
|
||||||
|
size_t cnt;
|
||||||
|
|
||||||
|
/* Lookup Network LSA corresponding to this interface. */
|
||||||
|
lsa = ospf_lsa_lookup_by_id(area, OSPF_NETWORK_LSA, *link_id);
|
||||||
|
if (!lsa)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* Iterate over all routers present in the network. */
|
||||||
|
nlsa = (struct network_lsa *)lsa->data;
|
||||||
|
cnt = (lsa->size - (OSPF_LSA_HEADER_SIZE + 4)) / 4;
|
||||||
|
for (size_t i = 0; i < cnt; i++) {
|
||||||
|
struct in_addr *nbr_id = &nlsa->routers[i];
|
||||||
|
|
||||||
|
/* Skip self in the pseudonode. */
|
||||||
|
if (IPV4_ADDR_SAME(nbr_id, &ospf->router_id))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if there's a fully formed adjacency with this
|
||||||
|
* router.
|
||||||
|
*/
|
||||||
|
if (!ospf_gr_check_adj_id(area, nbr_id))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
struct ospf_neighbor *nbr;
|
||||||
|
|
||||||
|
/* Check if there's a fully formed adjacency with the DR. */
|
||||||
|
nbr = ospf_area_nbr_lookup_by_addr(area, link_id);
|
||||||
|
if (!nbr || nbr->state < NSM_Full) {
|
||||||
|
if (IS_DEBUG_OSPF_GR)
|
||||||
|
zlog_debug(
|
||||||
|
"GR: missing adjacency to DR router %pI4",
|
||||||
|
link_id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ospf_gr_check_adjs_lsa(struct ospf_area *area, struct ospf_lsa *lsa)
|
||||||
|
{
|
||||||
|
struct router_lsa *rl = (struct router_lsa *)lsa->data;
|
||||||
|
|
||||||
|
for (int i = 0; i < ntohs(rl->links); i++) {
|
||||||
|
struct in_addr *link_id = &rl->link[i].link_id;
|
||||||
|
|
||||||
|
switch (rl->link[i].type) {
|
||||||
|
case LSA_LINK_TYPE_POINTOPOINT:
|
||||||
|
if (!ospf_gr_check_adj_id(area, link_id))
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
case LSA_LINK_TYPE_TRANSIT:
|
||||||
|
if (!ospf_gr_check_adjs_lsa_transit(area, link_id))
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if all adjacencies prior to the restart were reestablished.
|
||||||
|
*
|
||||||
|
* This is done using pre-restart Router LSAs and pre-restart Network LSAs
|
||||||
|
* received from the helping neighbors.
|
||||||
|
*/
|
||||||
|
void ospf_gr_check_adjs(struct ospf *ospf)
|
||||||
|
{
|
||||||
|
struct ospf_area *area;
|
||||||
|
struct listnode *node;
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
|
||||||
|
struct ospf_lsa *lsa_self;
|
||||||
|
|
||||||
|
lsa_self = ospf_lsa_lookup_by_id(area, OSPF_ROUTER_LSA,
|
||||||
|
ospf->router_id);
|
||||||
|
if (!lsa_self || !ospf_gr_check_adjs_lsa(area, lsa_self)) {
|
||||||
|
if (IS_DEBUG_OSPF_GR)
|
||||||
|
zlog_debug(
|
||||||
|
"GR: not all adjacencies were reestablished yet [area %pI4]",
|
||||||
|
&area->area_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ospf_gr_restart_exit(ospf, "all adjacencies were reestablished");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handling of grace period expiry. */
|
||||||
|
static int ospf_gr_grace_period_expired(struct thread *thread)
|
||||||
|
{
|
||||||
|
struct ospf *ospf = THREAD_ARG(thread);
|
||||||
|
|
||||||
|
ospf->gr_info.t_grace_period = NULL;
|
||||||
|
ospf_gr_restart_exit(ospf, "grace period has expired");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the path of the file (non-volatile memory) that contains GR status
|
||||||
|
* information.
|
||||||
|
*/
|
||||||
|
static char *ospf_gr_nvm_filepath(struct ospf *ospf)
|
||||||
|
{
|
||||||
|
static char filepath[MAXPATHLEN];
|
||||||
|
char instance[16] = "";
|
||||||
|
|
||||||
|
if (ospf->instance)
|
||||||
|
snprintf(instance, sizeof(instance), "-%d", ospf->instance);
|
||||||
|
snprintf(filepath, sizeof(filepath), OSPFD_GR_STATE, instance);
|
||||||
|
return filepath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Record in non-volatile memory that the given OSPF instance is attempting to
|
||||||
|
* perform a graceful restart.
|
||||||
|
*/
|
||||||
|
static void ospf_gr_nvm_update(struct ospf *ospf)
|
||||||
|
{
|
||||||
|
char *filepath;
|
||||||
|
const char *inst_name;
|
||||||
|
json_object *json;
|
||||||
|
json_object *json_instances;
|
||||||
|
json_object *json_instance;
|
||||||
|
|
||||||
|
filepath = ospf_gr_nvm_filepath(ospf);
|
||||||
|
inst_name = ospf->name ? ospf->name : VRF_DEFAULT_NAME;
|
||||||
|
|
||||||
|
json = json_object_from_file(filepath);
|
||||||
|
if (json == NULL)
|
||||||
|
json = json_object_new_object();
|
||||||
|
|
||||||
|
json_object_object_get_ex(json, "instances", &json_instances);
|
||||||
|
if (!json_instances) {
|
||||||
|
json_instances = json_object_new_object();
|
||||||
|
json_object_object_add(json, "instances", json_instances);
|
||||||
|
}
|
||||||
|
|
||||||
|
json_object_object_get_ex(json_instances, inst_name, &json_instance);
|
||||||
|
if (!json_instance) {
|
||||||
|
json_instance = json_object_new_object();
|
||||||
|
json_object_object_add(json_instances, inst_name,
|
||||||
|
json_instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Record not only the grace period, but also a UNIX timestamp
|
||||||
|
* corresponding to the end of that period. That way, once ospfd is
|
||||||
|
* restarted, it will be possible to take into account the time that
|
||||||
|
* passed while ospfd wasn't running.
|
||||||
|
*/
|
||||||
|
json_object_int_add(json_instance, "gracePeriod",
|
||||||
|
ospf->gr_info.grace_period);
|
||||||
|
json_object_int_add(json_instance, "timestamp",
|
||||||
|
time(NULL) + ospf->gr_info.grace_period);
|
||||||
|
|
||||||
|
json_object_to_file_ext(filepath, json, JSON_C_TO_STRING_PRETTY);
|
||||||
|
json_object_free(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Delete GR status information about the given OSPF instance from non-volatile
|
||||||
|
* memory.
|
||||||
|
*/
|
||||||
|
static void ospf_gr_nvm_delete(struct ospf *ospf)
|
||||||
|
{
|
||||||
|
char *filepath;
|
||||||
|
const char *inst_name;
|
||||||
|
json_object *json;
|
||||||
|
json_object *json_instances;
|
||||||
|
|
||||||
|
filepath = ospf_gr_nvm_filepath(ospf);
|
||||||
|
inst_name = ospf->name ? ospf->name : VRF_DEFAULT_NAME;
|
||||||
|
|
||||||
|
json = json_object_from_file(filepath);
|
||||||
|
if (json == NULL)
|
||||||
|
json = json_object_new_object();
|
||||||
|
|
||||||
|
json_object_object_get_ex(json, "instances", &json_instances);
|
||||||
|
if (!json_instances) {
|
||||||
|
json_instances = json_object_new_object();
|
||||||
|
json_object_object_add(json, "instances", json_instances);
|
||||||
|
}
|
||||||
|
|
||||||
|
json_object_object_del(json_instances, inst_name);
|
||||||
|
|
||||||
|
json_object_to_file_ext(filepath, json, JSON_C_TO_STRING_PRETTY);
|
||||||
|
json_object_free(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fetch from non-volatile memory whether the given OSPF instance is performing
|
||||||
|
* a graceful shutdown or not.
|
||||||
|
*/
|
||||||
|
void ospf_gr_nvm_read(struct ospf *ospf)
|
||||||
|
{
|
||||||
|
char *filepath;
|
||||||
|
const char *inst_name;
|
||||||
|
json_object *json;
|
||||||
|
json_object *json_instances;
|
||||||
|
json_object *json_instance;
|
||||||
|
json_object *json_timestamp;
|
||||||
|
time_t timestamp = 0;
|
||||||
|
|
||||||
|
filepath = ospf_gr_nvm_filepath(ospf);
|
||||||
|
inst_name = ospf->name ? ospf->name : VRF_DEFAULT_NAME;
|
||||||
|
|
||||||
|
json = json_object_from_file(filepath);
|
||||||
|
if (json == NULL)
|
||||||
|
json = json_object_new_object();
|
||||||
|
|
||||||
|
json_object_object_get_ex(json, "instances", &json_instances);
|
||||||
|
if (!json_instances) {
|
||||||
|
json_instances = json_object_new_object();
|
||||||
|
json_object_object_add(json, "instances", json_instances);
|
||||||
|
}
|
||||||
|
|
||||||
|
json_object_object_get_ex(json_instances, inst_name, &json_instance);
|
||||||
|
if (!json_instance) {
|
||||||
|
json_instance = json_object_new_object();
|
||||||
|
json_object_object_add(json_instances, inst_name,
|
||||||
|
json_instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
json_object_object_get_ex(json_instance, "timestamp", &json_timestamp);
|
||||||
|
if (json_timestamp) {
|
||||||
|
time_t now;
|
||||||
|
unsigned long remaining_time;
|
||||||
|
|
||||||
|
/* Check if the grace period has already expired. */
|
||||||
|
now = time(NULL);
|
||||||
|
timestamp = json_object_get_int(json_timestamp);
|
||||||
|
if (now > timestamp) {
|
||||||
|
ospf_gr_restart_exit(
|
||||||
|
ospf, "grace period has expired already");
|
||||||
|
} else {
|
||||||
|
/* Schedule grace period timeout. */
|
||||||
|
ospf->gr_info.restart_in_progress = true;
|
||||||
|
remaining_time = timestamp - time(NULL);
|
||||||
|
if (IS_DEBUG_OSPF_GR)
|
||||||
|
zlog_debug(
|
||||||
|
"GR: remaining time until grace period expires: %lu(s)",
|
||||||
|
remaining_time);
|
||||||
|
thread_add_timer(master, ospf_gr_grace_period_expired,
|
||||||
|
ospf, remaining_time,
|
||||||
|
&ospf->gr_info.t_grace_period);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
json_object_object_del(json_instances, inst_name);
|
||||||
|
|
||||||
|
json_object_to_file_ext(filepath, json, JSON_C_TO_STRING_PRETTY);
|
||||||
|
json_object_free(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prepare to start a Graceful Restart. */
|
||||||
|
static void ospf_gr_prepare(void)
|
||||||
|
{
|
||||||
|
struct ospf *ospf;
|
||||||
|
struct ospf_interface *oi;
|
||||||
|
struct listnode *onode;
|
||||||
|
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(om->ospf, onode, ospf)) {
|
||||||
|
struct listnode *inode;
|
||||||
|
|
||||||
|
if (!ospf->gr_info.restart_support
|
||||||
|
|| ospf->gr_info.prepare_in_progress)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (IS_DEBUG_OSPF_GR)
|
||||||
|
zlog_debug(
|
||||||
|
"GR: preparing to perform a graceful restart [period %u second(s)] [vrf %s]",
|
||||||
|
ospf->gr_info.grace_period,
|
||||||
|
ospf_vrf_id_to_name(ospf->vrf_id));
|
||||||
|
|
||||||
|
if (!CHECK_FLAG(ospf->config, OSPF_OPAQUE_CAPABLE)) {
|
||||||
|
zlog_warn(
|
||||||
|
"%s: failed to activate graceful restart: opaque capability not enabled",
|
||||||
|
__func__);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Freeze OSPF routes in the RIB. */
|
||||||
|
if (ospf_zebra_gr_enable(ospf, ospf->gr_info.grace_period)) {
|
||||||
|
zlog_warn(
|
||||||
|
"%s: failed to activate graceful restart: not connected to zebra",
|
||||||
|
__func__);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Send a Grace-LSA to all neighbors. */
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, inode, oi))
|
||||||
|
ospf_gr_lsa_originate(oi);
|
||||||
|
|
||||||
|
/* Record end of the grace period in non-volatile memory. */
|
||||||
|
ospf_gr_nvm_update(ospf);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Mark that a Graceful Restart preparation is in progress, to
|
||||||
|
* prevent ospfd from flushing its self-originated LSAs on exit.
|
||||||
|
*/
|
||||||
|
ospf->gr_info.prepare_in_progress = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFPY(graceful_restart_prepare, graceful_restart_prepare_cmd,
|
||||||
|
"graceful-restart prepare ip ospf",
|
||||||
|
"Graceful Restart commands\n"
|
||||||
|
"Prepare upcoming graceful restart\n"
|
||||||
|
IP_STR
|
||||||
|
"Prepare to restart the OSPF process")
|
||||||
|
{
|
||||||
|
ospf_gr_prepare();
|
||||||
|
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFPY(graceful_restart, graceful_restart_cmd,
|
||||||
|
"graceful-restart [grace-period (1-1800)$grace_period]",
|
||||||
|
OSPF_GR_STR
|
||||||
|
"Maximum length of the 'grace period'\n"
|
||||||
|
"Maximum length of the 'grace period' in seconds\n")
|
||||||
|
{
|
||||||
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
||||||
|
|
||||||
|
/* Check and get restart period if present. */
|
||||||
|
if (!grace_period_str)
|
||||||
|
grace_period = OSPF_DFLT_GRACE_INTERVAL;
|
||||||
|
|
||||||
|
ospf->gr_info.restart_support = true;
|
||||||
|
ospf->gr_info.grace_period = grace_period;
|
||||||
|
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFPY(no_graceful_restart, no_graceful_restart_cmd,
|
||||||
|
"no graceful-restart [period (1-1800)]",
|
||||||
|
NO_STR OSPF_GR_STR
|
||||||
|
"Maximum length of the 'grace period'\n"
|
||||||
|
"Maximum length of the 'grace period' in seconds\n")
|
||||||
|
{
|
||||||
|
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
|
||||||
|
|
||||||
|
if (!ospf->gr_info.restart_support)
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
|
||||||
|
if (ospf->gr_info.prepare_in_progress) {
|
||||||
|
vty_out(vty,
|
||||||
|
"%% Error: Graceful Restart preparation in progress\n");
|
||||||
|
return CMD_WARNING;
|
||||||
|
}
|
||||||
|
|
||||||
|
ospf->gr_info.restart_support = false;
|
||||||
|
ospf->gr_info.grace_period = OSPF_DFLT_GRACE_INTERVAL;
|
||||||
|
|
||||||
|
return CMD_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ospf_gr_init(void)
|
||||||
|
{
|
||||||
|
install_element(ENABLE_NODE, &graceful_restart_prepare_cmd);
|
||||||
|
install_element(OSPF_NODE, &graceful_restart_cmd);
|
||||||
|
install_element(OSPF_NODE, &no_graceful_restart_cmd);
|
||||||
|
}
|
|
@ -21,8 +21,8 @@
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _ZEBRA_OSPF_GR_HELPER_H
|
#ifndef _ZEBRA_OSPF_GR_H
|
||||||
#define _ZEBRA_OSPF_GR_HELPER_H
|
#define _ZEBRA_OSPF_GR_H
|
||||||
|
|
||||||
#define OSPF_GR_NOT_HELPER 0
|
#define OSPF_GR_NOT_HELPER 0
|
||||||
#define OSPF_GR_ACTIVE_HELPER 1
|
#define OSPF_GR_ACTIVE_HELPER 1
|
||||||
|
@ -32,6 +32,7 @@
|
||||||
|
|
||||||
#define OSPF_MAX_GRACE_INTERVAL 1800
|
#define OSPF_MAX_GRACE_INTERVAL 1800
|
||||||
#define OSPF_MIN_GRACE_INTERVAL 1
|
#define OSPF_MIN_GRACE_INTERVAL 1
|
||||||
|
#define OSPF_DFLT_GRACE_INTERVAL 120
|
||||||
|
|
||||||
enum ospf_helper_exit_reason {
|
enum ospf_helper_exit_reason {
|
||||||
OSPF_GR_HELPER_EXIT_NONE = 0,
|
OSPF_GR_HELPER_EXIT_NONE = 0,
|
||||||
|
@ -55,7 +56,8 @@ enum ospf_gr_helper_rejected_reason {
|
||||||
OSPF_HELPER_NOT_A_VALID_NEIGHBOUR,
|
OSPF_HELPER_NOT_A_VALID_NEIGHBOUR,
|
||||||
OSPF_HELPER_PLANNED_ONLY_RESTART,
|
OSPF_HELPER_PLANNED_ONLY_RESTART,
|
||||||
OSPF_HELPER_TOPO_CHANGE_RTXMT_LIST,
|
OSPF_HELPER_TOPO_CHANGE_RTXMT_LIST,
|
||||||
OSPF_HELPER_LSA_AGE_MORE
|
OSPF_HELPER_LSA_AGE_MORE,
|
||||||
|
OSPF_HELPER_RESTARTING,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Ref RFC3623 appendex-A */
|
/* Ref RFC3623 appendex-A */
|
||||||
|
@ -101,7 +103,8 @@ struct ospf_helper_info {
|
||||||
|
|
||||||
/* Grace timer,This Router acts as
|
/* Grace timer,This Router acts as
|
||||||
* helper until this timer until
|
* helper until this timer until
|
||||||
* this timer expires*/
|
* this timer expires.
|
||||||
|
*/
|
||||||
struct thread *t_grace_timer;
|
struct thread *t_grace_timer;
|
||||||
|
|
||||||
/* Helper status */
|
/* Helper status */
|
||||||
|
@ -178,4 +181,11 @@ extern void ospf_gr_helper_supported_gracetime_set(struct ospf *ospf,
|
||||||
uint32_t interval);
|
uint32_t interval);
|
||||||
extern void ospf_gr_helper_set_supported_planned_only_restart(struct ospf *ospf,
|
extern void ospf_gr_helper_set_supported_planned_only_restart(struct ospf *ospf,
|
||||||
bool planned_only);
|
bool planned_only);
|
||||||
#endif /* _ZEBRA_OSPF_HELPER_H */
|
|
||||||
|
extern void ospf_gr_check_lsdb_consistency(struct ospf *ospf,
|
||||||
|
struct ospf_area *area);
|
||||||
|
extern void ospf_gr_check_adjs(struct ospf *ospf);
|
||||||
|
extern void ospf_gr_nvm_read(struct ospf *ospf);
|
||||||
|
extern void ospf_gr_init(void);
|
||||||
|
|
||||||
|
#endif /* _ZEBRA_OSPF_GR_H */
|
|
@ -48,7 +48,7 @@
|
||||||
#include "ospfd/ospf_errors.h"
|
#include "ospfd/ospf_errors.h"
|
||||||
#include "ospfd/ospf_nsm.h"
|
#include "ospfd/ospf_nsm.h"
|
||||||
#include "ospfd/ospf_ism.h"
|
#include "ospfd/ospf_ism.h"
|
||||||
#include "ospfd/ospf_gr_helper.h"
|
#include "ospfd/ospf_gr.h"
|
||||||
|
|
||||||
static const char * const ospf_exit_reason_desc[] = {
|
static const char * const ospf_exit_reason_desc[] = {
|
||||||
"Unknown reason",
|
"Unknown reason",
|
||||||
|
@ -72,6 +72,7 @@ static const char * const ospf_rejected_reason_desc[] = {
|
||||||
"Supports only planned restart but received unplanned",
|
"Supports only planned restart but received unplanned",
|
||||||
"Topo change due to change in lsa rxmt list",
|
"Topo change due to change in lsa rxmt list",
|
||||||
"LSA age is more than Grace interval",
|
"LSA age is more than Grace interval",
|
||||||
|
"Router is in the process of graceful restart",
|
||||||
};
|
};
|
||||||
|
|
||||||
static void show_ospf_grace_lsa_info(struct vty *vty, struct ospf_lsa *lsa);
|
static void show_ospf_grace_lsa_info(struct vty *vty, struct ospf_lsa *lsa);
|
||||||
|
@ -161,7 +162,7 @@ const char *ospf_rejected_reason2str(unsigned int reason)
|
||||||
*/
|
*/
|
||||||
void ospf_gr_helper_instance_init(struct ospf *ospf)
|
void ospf_gr_helper_instance_init(struct ospf *ospf)
|
||||||
{
|
{
|
||||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
if (IS_DEBUG_OSPF_GR)
|
||||||
zlog_debug("%s, GR Helper init.", __func__);
|
zlog_debug("%s, GR Helper init.", __func__);
|
||||||
|
|
||||||
ospf->is_helper_supported = OSPF_GR_FALSE;
|
ospf->is_helper_supported = OSPF_GR_FALSE;
|
||||||
|
@ -187,7 +188,7 @@ void ospf_gr_helper_instance_init(struct ospf *ospf)
|
||||||
*/
|
*/
|
||||||
void ospf_gr_helper_instance_stop(struct ospf *ospf)
|
void ospf_gr_helper_instance_stop(struct ospf *ospf)
|
||||||
{
|
{
|
||||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
if (IS_DEBUG_OSPF_GR)
|
||||||
zlog_debug("%s, GR helper deinit.", __func__);
|
zlog_debug("%s, GR helper deinit.", __func__);
|
||||||
|
|
||||||
ospf_enable_rtr_hash_destroy(ospf);
|
ospf_enable_rtr_hash_destroy(ospf);
|
||||||
|
@ -203,7 +204,7 @@ void ospf_gr_helper_init(void)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
if (IS_DEBUG_OSPF_GR)
|
||||||
zlog_debug("%s, GR Helper init.", __func__);
|
zlog_debug("%s, GR Helper init.", __func__);
|
||||||
|
|
||||||
rc = ospf_register_opaque_functab(
|
rc = ospf_register_opaque_functab(
|
||||||
|
@ -225,8 +226,7 @@ void ospf_gr_helper_init(void)
|
||||||
*/
|
*/
|
||||||
void ospf_gr_helper_stop(void)
|
void ospf_gr_helper_stop(void)
|
||||||
{
|
{
|
||||||
|
if (IS_DEBUG_OSPF_GR)
|
||||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
|
||||||
zlog_debug("%s, GR helper deinit.", __func__);
|
zlog_debug("%s, GR helper deinit.", __func__);
|
||||||
|
|
||||||
ospf_delete_opaque_functab(OSPF_OPAQUE_LINK_LSA, OPAQUE_TYPE_GRACE_LSA);
|
ospf_delete_opaque_functab(OSPF_OPAQUE_LINK_LSA, OPAQUE_TYPE_GRACE_LSA);
|
||||||
|
@ -259,7 +259,7 @@ static int ospf_extract_grace_lsa_fields(struct ospf_lsa *lsa,
|
||||||
|
|
||||||
/* Check LSA len */
|
/* Check LSA len */
|
||||||
if (lsa->size <= OSPF_LSA_HEADER_SIZE) {
|
if (lsa->size <= OSPF_LSA_HEADER_SIZE) {
|
||||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
if (IS_DEBUG_OSPF_GR)
|
||||||
zlog_debug("%s: Malformed packet: Invalid LSA len:%d",
|
zlog_debug("%s: Malformed packet: Invalid LSA len:%d",
|
||||||
__func__, length);
|
__func__, length);
|
||||||
return OSPF_GR_FAILURE;
|
return OSPF_GR_FAILURE;
|
||||||
|
@ -272,7 +272,7 @@ static int ospf_extract_grace_lsa_fields(struct ospf_lsa *lsa,
|
||||||
|
|
||||||
/* Check TLV len against overall LSA */
|
/* Check TLV len against overall LSA */
|
||||||
if (sum + TLV_SIZE(tlvh) > length) {
|
if (sum + TLV_SIZE(tlvh) > length) {
|
||||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
if (IS_DEBUG_OSPF_GR)
|
||||||
zlog_debug("%s: Malformed packet: Invalid TLV len:%u",
|
zlog_debug("%s: Malformed packet: Invalid TLV len:%u",
|
||||||
__func__, TLV_SIZE(tlvh));
|
__func__, TLV_SIZE(tlvh));
|
||||||
return OSPF_GR_FAILURE;
|
return OSPF_GR_FAILURE;
|
||||||
|
@ -324,7 +324,7 @@ static int ospf_extract_grace_lsa_fields(struct ospf_lsa *lsa,
|
||||||
sum += TLV_SIZE(tlvh);
|
sum += TLV_SIZE(tlvh);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
if (IS_DEBUG_OSPF_GR)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s, Malformed packet.Invalid TLV type:%d",
|
"%s, Malformed packet.Invalid TLV type:%d",
|
||||||
__func__, ntohs(tlvh->type));
|
__func__, ntohs(tlvh->type));
|
||||||
|
@ -391,12 +391,12 @@ int ospf_process_grace_lsa(struct ospf *ospf, struct ospf_lsa *lsa,
|
||||||
ret = ospf_extract_grace_lsa_fields(lsa, &grace_interval, &restart_addr,
|
ret = ospf_extract_grace_lsa_fields(lsa, &grace_interval, &restart_addr,
|
||||||
&restart_reason);
|
&restart_reason);
|
||||||
if (ret != OSPF_GR_SUCCESS) {
|
if (ret != OSPF_GR_SUCCESS) {
|
||||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
if (IS_DEBUG_OSPF_GR)
|
||||||
zlog_debug("%s, Wrong Grace LSA packet.", __func__);
|
zlog_debug("%s, Wrong Grace LSA packet.", __func__);
|
||||||
return OSPF_GR_NOT_HELPER;
|
return OSPF_GR_NOT_HELPER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
if (IS_DEBUG_OSPF_GR)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s, Grace LSA received from %pI4, grace interval:%u, restart reason:%s",
|
"%s, Grace LSA received from %pI4, grace interval:%u, restart reason:%s",
|
||||||
__func__, &restart_addr, grace_interval,
|
__func__, &restart_addr, grace_interval,
|
||||||
|
@ -410,7 +410,7 @@ int ospf_process_grace_lsa(struct ospf *ospf, struct ospf_lsa *lsa,
|
||||||
restarter = ospf_nbr_lookup_by_addr(oi->nbrs, &restart_addr);
|
restarter = ospf_nbr_lookup_by_addr(oi->nbrs, &restart_addr);
|
||||||
|
|
||||||
if (!restarter) {
|
if (!restarter) {
|
||||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
if (IS_DEBUG_OSPF_GR)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s, Restarter is not a nbr(%pI4) for this router.",
|
"%s, Restarter is not a nbr(%pI4) for this router.",
|
||||||
__func__, &restart_addr);
|
__func__, &restart_addr);
|
||||||
|
@ -427,7 +427,7 @@ int ospf_process_grace_lsa(struct ospf *ospf, struct ospf_lsa *lsa,
|
||||||
lookup.advRtrAddr.s_addr = restarter->router_id.s_addr;
|
lookup.advRtrAddr.s_addr = restarter->router_id.s_addr;
|
||||||
|
|
||||||
if (!hash_lookup(ospf->enable_rtr_list, &lookup)) {
|
if (!hash_lookup(ospf->enable_rtr_list, &lookup)) {
|
||||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
if (IS_DEBUG_OSPF_GR)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s, HELPER support is disabled, So not a HELPER",
|
"%s, HELPER support is disabled, So not a HELPER",
|
||||||
__func__);
|
__func__);
|
||||||
|
@ -442,7 +442,7 @@ int ospf_process_grace_lsa(struct ospf *ospf, struct ospf_lsa *lsa,
|
||||||
* became a adjacency.
|
* became a adjacency.
|
||||||
*/
|
*/
|
||||||
if (!IS_NBR_STATE_FULL(restarter)) {
|
if (!IS_NBR_STATE_FULL(restarter)) {
|
||||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
if (IS_DEBUG_OSPF_GR)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s, This Neighbour %pI4 is not in FULL state.",
|
"%s, This Neighbour %pI4 is not in FULL state.",
|
||||||
__func__, &restarter->src);
|
__func__, &restarter->src);
|
||||||
|
@ -456,7 +456,7 @@ int ospf_process_grace_lsa(struct ospf *ospf, struct ospf_lsa *lsa,
|
||||||
*/
|
*/
|
||||||
if (ospf->only_planned_restart
|
if (ospf->only_planned_restart
|
||||||
&& !OSPF_GR_IS_PLANNED_RESTART(restart_reason)) {
|
&& !OSPF_GR_IS_PLANNED_RESTART(restart_reason)) {
|
||||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
if (IS_DEBUG_OSPF_GR)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s, Router supports only planned restarts but received the GRACE LSA for an unplanned restart.",
|
"%s, Router supports only planned restarts but received the GRACE LSA for an unplanned restart.",
|
||||||
__func__);
|
__func__);
|
||||||
|
@ -470,7 +470,7 @@ int ospf_process_grace_lsa(struct ospf *ospf, struct ospf_lsa *lsa,
|
||||||
*/
|
*/
|
||||||
if (ospf->strict_lsa_check && !ospf_ls_retransmit_isempty(restarter)
|
if (ospf->strict_lsa_check && !ospf_ls_retransmit_isempty(restarter)
|
||||||
&& ospf_check_change_in_rxmt_list(restarter)) {
|
&& ospf_check_change_in_rxmt_list(restarter)) {
|
||||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
if (IS_DEBUG_OSPF_GR)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s, Changed LSA in Rxmt list. So not Helper.",
|
"%s, Changed LSA in Rxmt list. So not Helper.",
|
||||||
__func__);
|
__func__);
|
||||||
|
@ -481,7 +481,7 @@ int ospf_process_grace_lsa(struct ospf *ospf, struct ospf_lsa *lsa,
|
||||||
|
|
||||||
/*LSA age must be less than the grace period */
|
/*LSA age must be less than the grace period */
|
||||||
if (ntohs(lsa->data->ls_age) >= grace_interval) {
|
if (ntohs(lsa->data->ls_age) >= grace_interval) {
|
||||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
if (IS_DEBUG_OSPF_GR)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s, Grace LSA age(%d) is more than the grace interval(%d)",
|
"%s, Grace LSA age(%d) is more than the grace interval(%d)",
|
||||||
__func__, lsa->data->ls_age, grace_interval);
|
__func__, lsa->data->ls_age, grace_interval);
|
||||||
|
@ -490,6 +490,16 @@ int ospf_process_grace_lsa(struct ospf *ospf, struct ospf_lsa *lsa,
|
||||||
return OSPF_GR_NOT_HELPER;
|
return OSPF_GR_NOT_HELPER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ospf->gr_info.restart_in_progress) {
|
||||||
|
if (IS_DEBUG_OSPF_GR)
|
||||||
|
zlog_debug(
|
||||||
|
"%s: router is in the process of graceful restart",
|
||||||
|
__func__);
|
||||||
|
restarter->gr_helper_info.rejected_reason =
|
||||||
|
OSPF_HELPER_RESTARTING;
|
||||||
|
return OSPF_GR_NOT_HELPER;
|
||||||
|
}
|
||||||
|
|
||||||
/* check supported grace period configured
|
/* check supported grace period configured
|
||||||
* if configured, use this to start the grace
|
* if configured, use this to start the grace
|
||||||
* timer otherwise use the interval received
|
* timer otherwise use the interval received
|
||||||
|
@ -497,7 +507,7 @@ int ospf_process_grace_lsa(struct ospf *ospf, struct ospf_lsa *lsa,
|
||||||
*/
|
*/
|
||||||
actual_grace_interval = grace_interval;
|
actual_grace_interval = grace_interval;
|
||||||
if (grace_interval > ospf->supported_grace_time) {
|
if (grace_interval > ospf->supported_grace_time) {
|
||||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
if (IS_DEBUG_OSPF_GR)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s, Received grace period %d is larger than supported grace %d",
|
"%s, Received grace period %d is larger than supported grace %d",
|
||||||
__func__, grace_interval,
|
__func__, grace_interval,
|
||||||
|
@ -512,12 +522,12 @@ int ospf_process_grace_lsa(struct ospf *ospf, struct ospf_lsa *lsa,
|
||||||
if (ospf->active_restarter_cnt > 0)
|
if (ospf->active_restarter_cnt > 0)
|
||||||
ospf->active_restarter_cnt--;
|
ospf->active_restarter_cnt--;
|
||||||
|
|
||||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
if (IS_DEBUG_OSPF_GR)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s, Router is already acting as a HELPER for this nbr,so restart the grace timer",
|
"%s, Router is already acting as a HELPER for this nbr,so restart the grace timer",
|
||||||
__func__);
|
__func__);
|
||||||
} else {
|
} else {
|
||||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
if (IS_DEBUG_OSPF_GR)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s, This Router becomes a HELPER for the neighbour %pI4",
|
"%s, This Router becomes a HELPER for the neighbour %pI4",
|
||||||
__func__, &restarter->src);
|
__func__, &restarter->src);
|
||||||
|
@ -535,7 +545,7 @@ int ospf_process_grace_lsa(struct ospf *ospf, struct ospf_lsa *lsa,
|
||||||
/* Increment the active restarter count */
|
/* Increment the active restarter count */
|
||||||
ospf->active_restarter_cnt++;
|
ospf->active_restarter_cnt++;
|
||||||
|
|
||||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
if (IS_DEBUG_OSPF_GR)
|
||||||
zlog_debug("%s, Grace timer started.interval:%d", __func__,
|
zlog_debug("%s, Grace timer started.interval:%d", __func__,
|
||||||
actual_grace_interval);
|
actual_grace_interval);
|
||||||
|
|
||||||
|
@ -622,10 +632,9 @@ void ospf_helper_handle_topo_chg(struct ospf *ospf, struct ospf_lsa *lsa)
|
||||||
if (!ospf->strict_lsa_check)
|
if (!ospf->strict_lsa_check)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
if (IS_DEBUG_OSPF_GR)
|
||||||
zlog_debug(
|
zlog_debug("%s: Topo change detected due to LSA[%s]", __func__,
|
||||||
"%s, Topo change detected due to lsa LSID:%pI4 type:%d",
|
dump_lsa_key(lsa));
|
||||||
__func__, &lsa->data->id, lsa->data->type);
|
|
||||||
|
|
||||||
lsa->to_be_acknowledged = OSPF_GR_TRUE;
|
lsa->to_be_acknowledged = OSPF_GR_TRUE;
|
||||||
|
|
||||||
|
@ -686,7 +695,7 @@ void ospf_gr_helper_exit(struct ospf_neighbor *nbr,
|
||||||
if (!OSPF_GR_IS_ACTIVE_HELPER(nbr))
|
if (!OSPF_GR_IS_ACTIVE_HELPER(nbr))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
if (IS_DEBUG_OSPF_GR)
|
||||||
zlog_debug("%s, Exiting from HELPER support to %pI4, due to %s",
|
zlog_debug("%s, Exiting from HELPER support to %pI4, due to %s",
|
||||||
__func__, &nbr->src, ospf_exit_reason2str(reason));
|
__func__, &nbr->src, ospf_exit_reason2str(reason));
|
||||||
|
|
||||||
|
@ -717,7 +726,7 @@ void ospf_gr_helper_exit(struct ospf_neighbor *nbr,
|
||||||
* If no, bring down the neighbour.
|
* If no, bring down the neighbour.
|
||||||
*/
|
*/
|
||||||
if (reason != OSPF_GR_HELPER_COMPLETED) {
|
if (reason != OSPF_GR_HELPER_COMPLETED) {
|
||||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
if (IS_DEBUG_OSPF_GR)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s, Failed GR exit, so bringing down the neighbour",
|
"%s, Failed GR exit, so bringing down the neighbour",
|
||||||
__func__);
|
__func__);
|
||||||
|
@ -768,12 +777,12 @@ void ospf_process_maxage_grace_lsa(struct ospf *ospf, struct ospf_lsa *lsa,
|
||||||
ret = ospf_extract_grace_lsa_fields(lsa, &graceInterval, &restartAddr,
|
ret = ospf_extract_grace_lsa_fields(lsa, &graceInterval, &restartAddr,
|
||||||
&restartReason);
|
&restartReason);
|
||||||
if (ret != OSPF_GR_SUCCESS) {
|
if (ret != OSPF_GR_SUCCESS) {
|
||||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
if (IS_DEBUG_OSPF_GR)
|
||||||
zlog_debug("%s, Wrong Grace LSA packet.", __func__);
|
zlog_debug("%s, Wrong Grace LSA packet.", __func__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
if (IS_DEBUG_OSPF_GR)
|
||||||
zlog_debug("%s, GraceLSA received for neighbour %pI4", __func__,
|
zlog_debug("%s, GraceLSA received for neighbour %pI4", __func__,
|
||||||
&restartAddr);
|
&restartAddr);
|
||||||
|
|
||||||
|
@ -785,7 +794,7 @@ void ospf_process_maxage_grace_lsa(struct ospf *ospf, struct ospf_lsa *lsa,
|
||||||
restarter = ospf_nbr_lookup_by_addr(oi->nbrs, &restartAddr);
|
restarter = ospf_nbr_lookup_by_addr(oi->nbrs, &restartAddr);
|
||||||
|
|
||||||
if (!restarter) {
|
if (!restarter) {
|
||||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
if (IS_DEBUG_OSPF_GR)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s, Restarter is not a neighbour for this router.",
|
"%s, Restarter is not a neighbour for this router.",
|
||||||
__func__);
|
__func__);
|
||||||
|
|
|
@ -819,6 +819,14 @@ static struct ospf_lsa *ospf_router_lsa_originate(struct ospf_area *area)
|
||||||
{
|
{
|
||||||
struct ospf_lsa *new;
|
struct ospf_lsa *new;
|
||||||
|
|
||||||
|
if (area->ospf->gr_info.restart_in_progress) {
|
||||||
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
||||||
|
zlog_debug(
|
||||||
|
"LSA[Type%d]: Graceful Restart in progress, don't originate",
|
||||||
|
OSPF_ROUTER_LSA);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Create new router-LSA instance. */
|
/* Create new router-LSA instance. */
|
||||||
if ((new = ospf_router_lsa_new(area)) == NULL) {
|
if ((new = ospf_router_lsa_new(area)) == NULL) {
|
||||||
zlog_err("%s: ospf_router_lsa_new returned NULL", __func__);
|
zlog_err("%s: ospf_router_lsa_new returned NULL", __func__);
|
||||||
|
@ -1045,6 +1053,14 @@ void ospf_network_lsa_update(struct ospf_interface *oi)
|
||||||
{
|
{
|
||||||
struct ospf_lsa *new;
|
struct ospf_lsa *new;
|
||||||
|
|
||||||
|
if (oi->area->ospf->gr_info.restart_in_progress) {
|
||||||
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
||||||
|
zlog_debug(
|
||||||
|
"LSA[Type%d]: Graceful Restart in progress, don't originate",
|
||||||
|
OSPF_NETWORK_LSA);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (oi->network_lsa_self != NULL) {
|
if (oi->network_lsa_self != NULL) {
|
||||||
ospf_lsa_refresh(oi->ospf, oi->network_lsa_self);
|
ospf_lsa_refresh(oi->ospf, oi->network_lsa_self);
|
||||||
return;
|
return;
|
||||||
|
@ -1212,6 +1228,14 @@ struct ospf_lsa *ospf_summary_lsa_originate(struct prefix_ipv4 *p,
|
||||||
struct ospf_lsa *new;
|
struct ospf_lsa *new;
|
||||||
struct in_addr id;
|
struct in_addr id;
|
||||||
|
|
||||||
|
if (area->ospf->gr_info.restart_in_progress) {
|
||||||
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
||||||
|
zlog_debug(
|
||||||
|
"LSA[Type%d]: Graceful Restart in progress, don't originate",
|
||||||
|
OSPF_SUMMARY_LSA);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
id = ospf_lsa_unique_id(area->ospf, area->lsdb, OSPF_SUMMARY_LSA, p);
|
id = ospf_lsa_unique_id(area->ospf, area->lsdb, OSPF_SUMMARY_LSA, p);
|
||||||
|
|
||||||
if (id.s_addr == 0xffffffff) {
|
if (id.s_addr == 0xffffffff) {
|
||||||
|
@ -1353,6 +1377,14 @@ struct ospf_lsa *ospf_summary_asbr_lsa_originate(struct prefix_ipv4 *p,
|
||||||
struct ospf_lsa *new;
|
struct ospf_lsa *new;
|
||||||
struct in_addr id;
|
struct in_addr id;
|
||||||
|
|
||||||
|
if (area->ospf->gr_info.restart_in_progress) {
|
||||||
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
||||||
|
zlog_debug(
|
||||||
|
"LSA[Type%d]: Graceful Restart in progress, don't originate",
|
||||||
|
OSPF_ASBR_SUMMARY_LSA);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
id = ospf_lsa_unique_id(area->ospf, area->lsdb, OSPF_ASBR_SUMMARY_LSA,
|
id = ospf_lsa_unique_id(area->ospf, area->lsdb, OSPF_ASBR_SUMMARY_LSA,
|
||||||
p);
|
p);
|
||||||
|
|
||||||
|
@ -1799,6 +1831,13 @@ struct ospf_lsa *ospf_translated_nssa_originate(struct ospf *ospf,
|
||||||
struct ospf_lsa *new;
|
struct ospf_lsa *new;
|
||||||
struct as_external_lsa *extnew;
|
struct as_external_lsa *extnew;
|
||||||
|
|
||||||
|
if (ospf->gr_info.restart_in_progress) {
|
||||||
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
||||||
|
zlog_debug(
|
||||||
|
"LSA[Translated Type5]: Graceful Restart in progress, don't originate");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* we cant use ospf_external_lsa_originate() as we need to set
|
/* we cant use ospf_external_lsa_originate() as we need to set
|
||||||
* the OSPF_LSA_LOCAL_XLT flag, must originate by hand
|
* the OSPF_LSA_LOCAL_XLT flag, must originate by hand
|
||||||
*/
|
*/
|
||||||
|
@ -1953,6 +1992,13 @@ struct ospf_lsa *ospf_external_lsa_originate(struct ospf *ospf,
|
||||||
{
|
{
|
||||||
struct ospf_lsa *new;
|
struct ospf_lsa *new;
|
||||||
|
|
||||||
|
if (ospf->gr_info.restart_in_progress) {
|
||||||
|
if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
|
||||||
|
zlog_debug(
|
||||||
|
"LSA[Type5]: Graceful Restart in progress, don't originate");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Added for NSSA project....
|
/* Added for NSSA project....
|
||||||
|
|
||||||
External LSAs are originated in ASBRs as usual, but for NSSA
|
External LSAs are originated in ASBRs as usual, but for NSSA
|
||||||
|
@ -2779,8 +2825,8 @@ struct ospf_lsa *ospf_lsa_install(struct ospf *ospf, struct ospf_interface *oi,
|
||||||
*/
|
*/
|
||||||
if (IS_LSA_MAXAGE(new)) {
|
if (IS_LSA_MAXAGE(new)) {
|
||||||
if (IS_DEBUG_OSPF(lsa, LSA_INSTALL))
|
if (IS_DEBUG_OSPF(lsa, LSA_INSTALL))
|
||||||
zlog_debug("LSA[Type%d:%pI4]: Install LSA %p, MaxAge",
|
zlog_debug("LSA[%s]: Install LSA %p, MaxAge",
|
||||||
new->data->type, &new->data->id, lsa);
|
dump_lsa_key(new), lsa);
|
||||||
ospf_lsa_maxage(ospf, lsa);
|
ospf_lsa_maxage(ospf, lsa);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2862,9 +2908,8 @@ static int ospf_maxage_lsa_remover(struct thread *thread)
|
||||||
|
|
||||||
if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
|
if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"LSA[Type%d:%pI4]: MaxAge LSA removed from list",
|
"LSA[%s]: MaxAge LSA removed from list",
|
||||||
lsa->data->type,
|
dump_lsa_key(lsa));
|
||||||
&lsa->data->id);
|
|
||||||
|
|
||||||
if (CHECK_FLAG(lsa->flags, OSPF_LSA_PREMATURE_AGE)) {
|
if (CHECK_FLAG(lsa->flags, OSPF_LSA_PREMATURE_AGE)) {
|
||||||
if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
|
if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
|
||||||
|
@ -2882,9 +2927,8 @@ static int ospf_maxage_lsa_remover(struct thread *thread)
|
||||||
*/
|
*/
|
||||||
if (old != lsa) {
|
if (old != lsa) {
|
||||||
flog_err(EC_OSPF_LSA_MISSING,
|
flog_err(EC_OSPF_LSA_MISSING,
|
||||||
"%s: LSA[Type%d:%pI4]: LSA not in LSDB",
|
"%s: LSA[%s]: LSA not in LSDB",
|
||||||
__func__, lsa->data->type,
|
__func__, dump_lsa_key(lsa));
|
||||||
&lsa->data->id);
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -2893,9 +2937,8 @@ static int ospf_maxage_lsa_remover(struct thread *thread)
|
||||||
} else {
|
} else {
|
||||||
if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
|
if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s: LSA[Type%d:%pI4]: No associated LSDB!",
|
"%s: LSA[%s]: No associated LSDB!",
|
||||||
__func__, lsa->data->type,
|
__func__, dump_lsa_key(lsa));
|
||||||
&lsa->data->id);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2952,9 +2995,8 @@ void ospf_lsa_maxage(struct ospf *ospf, struct ospf_lsa *lsa)
|
||||||
if (CHECK_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE)) {
|
if (CHECK_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE)) {
|
||||||
if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
|
if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"LSA[Type%d:%pI4]: %p already exists on MaxAge LSA list",
|
"LSA[%s]: %p already exists on MaxAge LSA list",
|
||||||
lsa->data->type, &lsa->data->id,
|
dump_lsa_key(lsa), lsa);
|
||||||
(void *)lsa);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
#include "ospfd/ospf_zebra.h"
|
#include "ospfd/ospf_zebra.h"
|
||||||
#include "ospfd/ospf_vty.h"
|
#include "ospfd/ospf_vty.h"
|
||||||
#include "ospfd/ospf_bfd.h"
|
#include "ospfd/ospf_bfd.h"
|
||||||
|
#include "ospfd/ospf_gr.h"
|
||||||
#include "ospfd/ospf_errors.h"
|
#include "ospfd/ospf_errors.h"
|
||||||
#include "ospfd/ospf_ldp_sync.h"
|
#include "ospfd/ospf_ldp_sync.h"
|
||||||
#include "ospfd/ospf_routemap_nb.h"
|
#include "ospfd/ospf_routemap_nb.h"
|
||||||
|
@ -225,6 +226,7 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
ospf_route_map_init();
|
ospf_route_map_init();
|
||||||
ospf_opaque_init();
|
ospf_opaque_init();
|
||||||
|
ospf_gr_init();
|
||||||
ospf_gr_helper_init();
|
ospf_gr_helper_init();
|
||||||
|
|
||||||
/* OSPF errors init */
|
/* OSPF errors init */
|
||||||
|
|
|
@ -44,7 +44,7 @@
|
||||||
#include "ospfd/ospf_flood.h"
|
#include "ospfd/ospf_flood.h"
|
||||||
#include "ospfd/ospf_dump.h"
|
#include "ospfd/ospf_dump.h"
|
||||||
#include "ospfd/ospf_bfd.h"
|
#include "ospfd/ospf_bfd.h"
|
||||||
#include "ospfd/ospf_gr_helper.h"
|
#include "ospfd/ospf_gr.h"
|
||||||
|
|
||||||
/* Fill in the the 'key' as appropriate to retrieve the entry for nbr
|
/* Fill in the the 'key' as appropriate to retrieve the entry for nbr
|
||||||
* from the ospf_interface's nbrs table. Indexed by interface address
|
* from the ospf_interface's nbrs table. Indexed by interface address
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
#ifndef _ZEBRA_OSPF_NEIGHBOR_H
|
#ifndef _ZEBRA_OSPF_NEIGHBOR_H
|
||||||
#define _ZEBRA_OSPF_NEIGHBOR_H
|
#define _ZEBRA_OSPF_NEIGHBOR_H
|
||||||
|
|
||||||
#include <ospfd/ospf_gr_helper.h>
|
#include <ospfd/ospf_gr.h>
|
||||||
#include <ospfd/ospf_packet.h>
|
#include <ospfd/ospf_packet.h>
|
||||||
|
|
||||||
/* Neighbor Data Structure */
|
/* Neighbor Data Structure */
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
#include "ospfd/ospf_flood.h"
|
#include "ospfd/ospf_flood.h"
|
||||||
#include "ospfd/ospf_abr.h"
|
#include "ospfd/ospf_abr.h"
|
||||||
#include "ospfd/ospf_bfd.h"
|
#include "ospfd/ospf_bfd.h"
|
||||||
|
#include "ospfd/ospf_gr.h"
|
||||||
#include "ospfd/ospf_errors.h"
|
#include "ospfd/ospf_errors.h"
|
||||||
|
|
||||||
DEFINE_HOOK(ospf_nsm_change,
|
DEFINE_HOOK(ospf_nsm_change,
|
||||||
|
@ -75,7 +76,7 @@ static int ospf_inactivity_timer(struct thread *thread)
|
||||||
*/
|
*/
|
||||||
if (!OSPF_GR_IS_ACTIVE_HELPER(nbr))
|
if (!OSPF_GR_IS_ACTIVE_HELPER(nbr))
|
||||||
OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_InactivityTimer);
|
OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_InactivityTimer);
|
||||||
else if (IS_DEBUG_OSPF_GR_HELPER)
|
else if (IS_DEBUG_OSPF_GR)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s, Acting as HELPER for this neighbour, So inactivitytimer event will not be fired.",
|
"%s, Acting as HELPER for this neighbour, So inactivitytimer event will not be fired.",
|
||||||
__func__);
|
__func__);
|
||||||
|
@ -727,6 +728,9 @@ static void nsm_change_state(struct ospf_neighbor *nbr, int state)
|
||||||
ospf_network_lsa_update(oi);
|
ospf_network_lsa_update(oi);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (state == NSM_Full && oi->ospf->gr_info.restart_in_progress)
|
||||||
|
ospf_gr_check_adjs(oi->ospf);
|
||||||
}
|
}
|
||||||
|
|
||||||
ospf_opaque_nsm_change(nbr, old_state);
|
ospf_opaque_nsm_change(nbr, old_state);
|
||||||
|
|
|
@ -2147,6 +2147,11 @@ void ospf_opaque_self_originated_lsa_received(struct ospf_neighbor *nbr,
|
||||||
if ((top = oi_to_top(nbr->oi)) == NULL)
|
if ((top = oi_to_top(nbr->oi)) == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (IS_DEBUG_OSPF_EVENT)
|
||||||
|
zlog_debug(
|
||||||
|
"LSA[Type%d:%pI4]: processing self-originated Opaque-LSA",
|
||||||
|
lsa->data->type, &lsa->data->id);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Since these LSA entries are not yet installed into corresponding
|
* Since these LSA entries are not yet installed into corresponding
|
||||||
* LSDB, just flush them without calling ospf_ls_maxage() afterward.
|
* LSDB, just flush them without calling ospf_ls_maxage() afterward.
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
#include "ospfd/ospf_dump.h"
|
#include "ospfd/ospf_dump.h"
|
||||||
#include "ospfd/ospf_errors.h"
|
#include "ospfd/ospf_errors.h"
|
||||||
#include "ospfd/ospf_zebra.h"
|
#include "ospfd/ospf_zebra.h"
|
||||||
#include "ospfd/ospf_gr_helper.h"
|
#include "ospfd/ospf_gr.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* OSPF Fragmentation / fragmented writes
|
* OSPF Fragmentation / fragmented writes
|
||||||
|
@ -2025,11 +2025,13 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph,
|
||||||
|
|
||||||
ospf_ls_ack_send(nbr, lsa);
|
ospf_ls_ack_send(nbr, lsa);
|
||||||
|
|
||||||
ospf_opaque_self_originated_lsa_received(nbr,
|
if (!ospf->gr_info.restart_in_progress) {
|
||||||
lsa);
|
ospf_opaque_self_originated_lsa_received(
|
||||||
|
nbr, lsa);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* It might be happen that received LSA is self-originated
|
/* It might be happen that received LSA is self-originated
|
||||||
* network LSA, but
|
* network LSA, but
|
||||||
|
@ -2213,6 +2215,9 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph,
|
||||||
|
|
||||||
assert(listcount(lsas) == 0);
|
assert(listcount(lsas) == 0);
|
||||||
list_delete(&lsas);
|
list_delete(&lsas);
|
||||||
|
|
||||||
|
if (ospf->gr_info.restart_in_progress)
|
||||||
|
ospf_gr_check_lsdb_consistency(oi->ospf, oi->area);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
|
/* OSPF Link State Acknowledgment message read -- RFC2328 Section 13.7. */
|
||||||
|
@ -3575,14 +3580,13 @@ static int ospf_make_ls_upd(struct ospf_interface *oi, struct list *update,
|
||||||
struct lsa_header *lsah;
|
struct lsa_header *lsah;
|
||||||
uint16_t ls_age;
|
uint16_t ls_age;
|
||||||
|
|
||||||
if (IS_DEBUG_OSPF_EVENT)
|
|
||||||
zlog_debug("ospf_make_ls_upd: List Iteration %d",
|
|
||||||
count);
|
|
||||||
|
|
||||||
lsa = listgetdata(node);
|
lsa = listgetdata(node);
|
||||||
|
|
||||||
assert(lsa->data);
|
assert(lsa->data);
|
||||||
|
|
||||||
|
if (IS_DEBUG_OSPF_EVENT)
|
||||||
|
zlog_debug("%s: List Iteration %d LSA[%s]", __func__,
|
||||||
|
count, dump_lsa_key(lsa));
|
||||||
|
|
||||||
/* Will it fit? Minimum it has to fit atleast one */
|
/* Will it fit? Minimum it has to fit atleast one */
|
||||||
if ((length + delta + ntohs(lsa->data->length) > size_noauth) &&
|
if ((length + delta + ntohs(lsa->data->length) > size_noauth) &&
|
||||||
(count > 0))
|
(count > 0))
|
||||||
|
@ -4264,7 +4268,7 @@ void ospf_ls_ack_send(struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
|
||||||
struct ospf_interface *oi = nbr->oi;
|
struct ospf_interface *oi = nbr->oi;
|
||||||
|
|
||||||
if (IS_GRACE_LSA(lsa)) {
|
if (IS_GRACE_LSA(lsa)) {
|
||||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
if (IS_DEBUG_OSPF_GR)
|
||||||
zlog_debug("%s, Sending GRACE ACK to Restarter.",
|
zlog_debug("%s, Sending GRACE ACK to Restarter.",
|
||||||
__func__);
|
__func__);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1903,6 +1903,8 @@ static int ospf_spf_calculate_schedule_worker(struct thread *thread)
|
||||||
strlcat(rbuf, "ASBR, ", sizeof(rbuf));
|
strlcat(rbuf, "ASBR, ", sizeof(rbuf));
|
||||||
if (spf_reason_flags & (1 << SPF_FLAG_MAXAGE))
|
if (spf_reason_flags & (1 << SPF_FLAG_MAXAGE))
|
||||||
strlcat(rbuf, "M, ", sizeof(rbuf));
|
strlcat(rbuf, "M, ", sizeof(rbuf));
|
||||||
|
if (spf_reason_flags & (1 << SPF_FLAG_GR_FINISH))
|
||||||
|
strlcat(rbuf, "GR, ", sizeof(rbuf));
|
||||||
|
|
||||||
size_t rbuflen = strlen(rbuf);
|
size_t rbuflen = strlen(rbuf);
|
||||||
if (rbuflen >= 2)
|
if (rbuflen >= 2)
|
||||||
|
|
|
@ -69,6 +69,7 @@ typedef enum {
|
||||||
SPF_FLAG_ABR_STATUS_CHANGE,
|
SPF_FLAG_ABR_STATUS_CHANGE,
|
||||||
SPF_FLAG_ASBR_STATUS_CHANGE,
|
SPF_FLAG_ASBR_STATUS_CHANGE,
|
||||||
SPF_FLAG_CONFIG_CHANGE,
|
SPF_FLAG_CONFIG_CHANGE,
|
||||||
|
SPF_FLAG_GR_FINISH,
|
||||||
} ospf_spf_reason_t;
|
} ospf_spf_reason_t;
|
||||||
|
|
||||||
extern void ospf_spf_calculate_schedule(struct ospf *, ospf_spf_reason_t);
|
extern void ospf_spf_calculate_schedule(struct ospf *, ospf_spf_reason_t);
|
||||||
|
|
|
@ -12250,6 +12250,18 @@ static int ospf_cfg_write_helper_dis_rtr_walkcb(struct hash_bucket *bucket,
|
||||||
return HASHWALK_CONTINUE;
|
return HASHWALK_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void config_write_ospf_gr(struct vty *vty, struct ospf *ospf)
|
||||||
|
{
|
||||||
|
if (!ospf->gr_info.restart_support)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ospf->gr_info.grace_period == OSPF_DFLT_GRACE_INTERVAL)
|
||||||
|
vty_out(vty, " graceful-restart\n");
|
||||||
|
else
|
||||||
|
vty_out(vty, " graceful-restart grace-period %u\n",
|
||||||
|
ospf->gr_info.grace_period);
|
||||||
|
}
|
||||||
|
|
||||||
static int config_write_ospf_gr_helper(struct vty *vty, struct ospf *ospf)
|
static int config_write_ospf_gr_helper(struct vty *vty, struct ospf *ospf)
|
||||||
{
|
{
|
||||||
if (ospf->is_helper_supported)
|
if (ospf->is_helper_supported)
|
||||||
|
@ -12464,7 +12476,8 @@ static int ospf_config_write_one(struct vty *vty, struct ospf *ospf)
|
||||||
/* Redistribute information print. */
|
/* Redistribute information print. */
|
||||||
config_write_ospf_redistribute(vty, ospf);
|
config_write_ospf_redistribute(vty, ospf);
|
||||||
|
|
||||||
/* Print gr helper configs */
|
/* Graceful Restart print */
|
||||||
|
config_write_ospf_gr(vty, ospf);
|
||||||
config_write_ospf_gr_helper(vty, ospf);
|
config_write_ospf_gr_helper(vty, ospf);
|
||||||
|
|
||||||
/* Print external route aggregation. */
|
/* Print external route aggregation. */
|
||||||
|
|
|
@ -264,6 +264,14 @@ void ospf_zebra_add(struct ospf *ospf, struct prefix_ipv4 *p,
|
||||||
struct ospf_path *path;
|
struct ospf_path *path;
|
||||||
struct listnode *node;
|
struct listnode *node;
|
||||||
|
|
||||||
|
if (ospf->gr_info.restart_in_progress) {
|
||||||
|
if (IS_DEBUG_OSPF_GR)
|
||||||
|
zlog_debug(
|
||||||
|
"Zebra: Graceful Restart in progress -- not installing %pFX",
|
||||||
|
p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
memset(&api, 0, sizeof(api));
|
memset(&api, 0, sizeof(api));
|
||||||
api.vrf_id = ospf->vrf_id;
|
api.vrf_id = ospf->vrf_id;
|
||||||
api.type = ZEBRA_ROUTE_OSPF;
|
api.type = ZEBRA_ROUTE_OSPF;
|
||||||
|
@ -323,6 +331,14 @@ void ospf_zebra_delete(struct ospf *ospf, struct prefix_ipv4 *p,
|
||||||
{
|
{
|
||||||
struct zapi_route api;
|
struct zapi_route api;
|
||||||
|
|
||||||
|
if (ospf->gr_info.restart_in_progress) {
|
||||||
|
if (IS_DEBUG_OSPF_GR)
|
||||||
|
zlog_debug(
|
||||||
|
"Zebra: Graceful Restart in progress -- not uninstalling %pFX",
|
||||||
|
p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
memset(&api, 0, sizeof(api));
|
memset(&api, 0, sizeof(api));
|
||||||
api.vrf_id = ospf->vrf_id;
|
api.vrf_id = ospf->vrf_id;
|
||||||
api.type = ZEBRA_ROUTE_OSPF;
|
api.type = ZEBRA_ROUTE_OSPF;
|
||||||
|
@ -340,6 +356,14 @@ void ospf_zebra_add_discard(struct ospf *ospf, struct prefix_ipv4 *p)
|
||||||
{
|
{
|
||||||
struct zapi_route api;
|
struct zapi_route api;
|
||||||
|
|
||||||
|
if (ospf->gr_info.restart_in_progress) {
|
||||||
|
if (IS_DEBUG_OSPF_GR)
|
||||||
|
zlog_debug(
|
||||||
|
"Zebra: Graceful Restart in progress -- not installing %pFX",
|
||||||
|
p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
memset(&api, 0, sizeof(api));
|
memset(&api, 0, sizeof(api));
|
||||||
api.vrf_id = ospf->vrf_id;
|
api.vrf_id = ospf->vrf_id;
|
||||||
api.type = ZEBRA_ROUTE_OSPF;
|
api.type = ZEBRA_ROUTE_OSPF;
|
||||||
|
@ -358,6 +382,14 @@ void ospf_zebra_delete_discard(struct ospf *ospf, struct prefix_ipv4 *p)
|
||||||
{
|
{
|
||||||
struct zapi_route api;
|
struct zapi_route api;
|
||||||
|
|
||||||
|
if (ospf->gr_info.restart_in_progress) {
|
||||||
|
if (IS_DEBUG_OSPF_GR)
|
||||||
|
zlog_debug(
|
||||||
|
"Zebra: Graceful Restart in progress -- not uninstalling %pFX",
|
||||||
|
p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
memset(&api, 0, sizeof(api));
|
memset(&api, 0, sizeof(api));
|
||||||
api.vrf_id = ospf->vrf_id;
|
api.vrf_id = ospf->vrf_id;
|
||||||
api.type = ZEBRA_ROUTE_OSPF;
|
api.type = ZEBRA_ROUTE_OSPF;
|
||||||
|
@ -1180,6 +1212,36 @@ void ospf_routemap_unset(struct ospf_redist *red)
|
||||||
ROUTEMAP(red) = NULL;
|
ROUTEMAP(red) = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ospf_zebra_gr_update(struct ospf *ospf, int command,
|
||||||
|
uint32_t stale_time)
|
||||||
|
{
|
||||||
|
struct zapi_cap api;
|
||||||
|
|
||||||
|
if (!zclient || zclient->sock < 0 || !ospf)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
memset(&api, 0, sizeof(struct zapi_cap));
|
||||||
|
api.cap = command;
|
||||||
|
api.stale_removal_time = stale_time;
|
||||||
|
api.vrf_id = ospf->vrf_id;
|
||||||
|
|
||||||
|
(void)zclient_capabilities_send(ZEBRA_CLIENT_CAPABILITIES, zclient,
|
||||||
|
&api);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ospf_zebra_gr_enable(struct ospf *ospf, uint32_t stale_time)
|
||||||
|
{
|
||||||
|
return ospf_zebra_gr_update(ospf, ZEBRA_CLIENT_GR_CAPABILITIES,
|
||||||
|
stale_time);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ospf_zebra_gr_disable(struct ospf *ospf)
|
||||||
|
{
|
||||||
|
return ospf_zebra_gr_update(ospf, ZEBRA_CLIENT_GR_DISABLE, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/* Zebra route add and delete treatment. */
|
/* Zebra route add and delete treatment. */
|
||||||
static int ospf_zebra_read_route(ZAPI_CALLBACK_ARGS)
|
static int ospf_zebra_read_route(ZAPI_CALLBACK_ARGS)
|
||||||
{
|
{
|
||||||
|
|
|
@ -88,6 +88,8 @@ extern int ospf_distribute_list_out_set(struct ospf *, int, const char *);
|
||||||
extern int ospf_distribute_list_out_unset(struct ospf *, int, const char *);
|
extern int ospf_distribute_list_out_unset(struct ospf *, int, const char *);
|
||||||
extern void ospf_routemap_set(struct ospf_redist *, const char *);
|
extern void ospf_routemap_set(struct ospf_redist *, const char *);
|
||||||
extern void ospf_routemap_unset(struct ospf_redist *);
|
extern void ospf_routemap_unset(struct ospf_redist *);
|
||||||
|
extern int ospf_zebra_gr_enable(struct ospf *ospf, uint32_t stale_time);
|
||||||
|
extern int ospf_zebra_gr_disable(struct ospf *ospf);
|
||||||
extern int ospf_distance_set(struct vty *, struct ospf *, const char *,
|
extern int ospf_distance_set(struct vty *, struct ospf *, const char *,
|
||||||
const char *, const char *);
|
const char *, const char *);
|
||||||
extern int ospf_distance_unset(struct vty *, struct ospf *, const char *,
|
extern int ospf_distance_unset(struct vty *, struct ospf *, const char *,
|
||||||
|
|
|
@ -60,7 +60,7 @@
|
||||||
#include "ospfd/ospf_flood.h"
|
#include "ospfd/ospf_flood.h"
|
||||||
#include "ospfd/ospf_ase.h"
|
#include "ospfd/ospf_ase.h"
|
||||||
#include "ospfd/ospf_ldp_sync.h"
|
#include "ospfd/ospf_ldp_sync.h"
|
||||||
#include "ospfd/ospf_gr_helper.h"
|
#include "ospfd/ospf_gr.h"
|
||||||
|
|
||||||
|
|
||||||
DEFINE_QOBJ_TYPE(ospf);
|
DEFINE_QOBJ_TYPE(ospf);
|
||||||
|
@ -420,6 +420,12 @@ static struct ospf *ospf_new(unsigned short instance, const char *name)
|
||||||
|
|
||||||
thread_add_read(master, ospf_read, new, new->fd, &new->t_read);
|
thread_add_read(master, ospf_read, new, new->fd, &new->t_read);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read from non-volatile memory whether this instance is performing a
|
||||||
|
* graceful restart or not.
|
||||||
|
*/
|
||||||
|
ospf_gr_nvm_read(new);
|
||||||
|
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -708,6 +714,7 @@ static void ospf_finish_final(struct ospf *ospf)
|
||||||
|
|
||||||
ospf_opaque_finish();
|
ospf_opaque_finish();
|
||||||
|
|
||||||
|
if (!ospf->gr_info.prepare_in_progress)
|
||||||
ospf_flush_self_originated_lsas_now(ospf);
|
ospf_flush_self_originated_lsas_now(ospf);
|
||||||
|
|
||||||
/* Unregister redistribution */
|
/* Unregister redistribution */
|
||||||
|
@ -805,6 +812,7 @@ static void ospf_finish_final(struct ospf *ospf)
|
||||||
OSPF_TIMER_OFF(ospf->t_sr_update);
|
OSPF_TIMER_OFF(ospf->t_sr_update);
|
||||||
OSPF_TIMER_OFF(ospf->t_default_routemap_timer);
|
OSPF_TIMER_OFF(ospf->t_default_routemap_timer);
|
||||||
OSPF_TIMER_OFF(ospf->t_external_aggr);
|
OSPF_TIMER_OFF(ospf->t_external_aggr);
|
||||||
|
OSPF_TIMER_OFF(ospf->gr_info.t_grace_period);
|
||||||
|
|
||||||
LSDB_LOOP (OPAQUE_AS_LSDB(ospf), rn, lsa)
|
LSDB_LOOP (OPAQUE_AS_LSDB(ospf), rn, lsa)
|
||||||
ospf_discard_from_db(ospf, ospf->lsdb, lsa);
|
ospf_discard_from_db(ospf, ospf->lsdb, lsa);
|
||||||
|
@ -826,6 +834,7 @@ static void ospf_finish_final(struct ospf *ospf)
|
||||||
if (ospf->old_table)
|
if (ospf->old_table)
|
||||||
ospf_route_table_free(ospf->old_table);
|
ospf_route_table_free(ospf->old_table);
|
||||||
if (ospf->new_table) {
|
if (ospf->new_table) {
|
||||||
|
if (!ospf->gr_info.prepare_in_progress)
|
||||||
ospf_route_delete(ospf, ospf->new_table);
|
ospf_route_delete(ospf, ospf->new_table);
|
||||||
ospf_route_table_free(ospf->new_table);
|
ospf_route_table_free(ospf->new_table);
|
||||||
}
|
}
|
||||||
|
@ -834,10 +843,12 @@ static void ospf_finish_final(struct ospf *ospf)
|
||||||
if (ospf->new_rtrs)
|
if (ospf->new_rtrs)
|
||||||
ospf_rtrs_free(ospf->new_rtrs);
|
ospf_rtrs_free(ospf->new_rtrs);
|
||||||
if (ospf->new_external_route) {
|
if (ospf->new_external_route) {
|
||||||
|
if (!ospf->gr_info.prepare_in_progress)
|
||||||
ospf_route_delete(ospf, ospf->new_external_route);
|
ospf_route_delete(ospf, ospf->new_external_route);
|
||||||
ospf_route_table_free(ospf->new_external_route);
|
ospf_route_table_free(ospf->new_external_route);
|
||||||
}
|
}
|
||||||
if (ospf->old_external_route) {
|
if (ospf->old_external_route) {
|
||||||
|
if (!ospf->gr_info.prepare_in_progress)
|
||||||
ospf_route_delete(ospf, ospf->old_external_route);
|
ospf_route_delete(ospf, ospf->old_external_route);
|
||||||
ospf_route_table_free(ospf->old_external_route);
|
ospf_route_table_free(ospf->old_external_route);
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,6 +134,16 @@ enum protection_type {
|
||||||
OSPF_TI_LFA_NODE_PROTECTION,
|
OSPF_TI_LFA_NODE_PROTECTION,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* OSPF nonstop forwarding aka Graceful Restart */
|
||||||
|
struct ospf_gr_info {
|
||||||
|
bool restart_support;
|
||||||
|
bool restart_in_progress;
|
||||||
|
bool prepare_in_progress;
|
||||||
|
bool finishing_restart;
|
||||||
|
uint32_t grace_period;
|
||||||
|
struct thread *t_grace_period;
|
||||||
|
};
|
||||||
|
|
||||||
/* OSPF instance structure. */
|
/* OSPF instance structure. */
|
||||||
struct ospf {
|
struct ospf {
|
||||||
/* OSPF's running state based on the '[no] router ospf [<instance>]'
|
/* OSPF's running state based on the '[no] router ospf [<instance>]'
|
||||||
|
@ -384,6 +394,9 @@ struct ospf {
|
||||||
/* MPLS LDP-IGP Sync */
|
/* MPLS LDP-IGP Sync */
|
||||||
struct ldp_sync_info_cmd ldp_sync_cmd;
|
struct ldp_sync_info_cmd ldp_sync_cmd;
|
||||||
|
|
||||||
|
/* OSPF Graceful Restart info */
|
||||||
|
struct ospf_gr_info gr_info;
|
||||||
|
|
||||||
/* TI-LFA support for all interfaces. */
|
/* TI-LFA support for all interfaces. */
|
||||||
bool ti_lfa_enabled;
|
bool ti_lfa_enabled;
|
||||||
enum protection_type ti_lfa_protection_type;
|
enum protection_type ti_lfa_protection_type;
|
||||||
|
|
|
@ -8,6 +8,7 @@ sbin_PROGRAMS += ospfd/ospfd
|
||||||
vtysh_scan += \
|
vtysh_scan += \
|
||||||
ospfd/ospf_bfd.c \
|
ospfd/ospf_bfd.c \
|
||||||
ospfd/ospf_dump.c \
|
ospfd/ospf_dump.c \
|
||||||
|
ospfd/ospf_gr.c \
|
||||||
ospfd/ospf_ldp_sync.c \
|
ospfd/ospf_ldp_sync.c \
|
||||||
ospfd/ospf_opaque.c \
|
ospfd/ospf_opaque.c \
|
||||||
ospfd/ospf_ri.c \
|
ospfd/ospf_ri.c \
|
||||||
|
@ -35,6 +36,7 @@ ospfd_libfrrospf_a_SOURCES = \
|
||||||
ospfd/ospf_errors.c \
|
ospfd/ospf_errors.c \
|
||||||
ospfd/ospf_ext.c \
|
ospfd/ospf_ext.c \
|
||||||
ospfd/ospf_flood.c \
|
ospfd/ospf_flood.c \
|
||||||
|
ospfd/ospf_gr.c \
|
||||||
ospfd/ospf_ia.c \
|
ospfd/ospf_ia.c \
|
||||||
ospfd/ospf_interface.c \
|
ospfd/ospf_interface.c \
|
||||||
ospfd/ospf_ism.c \
|
ospfd/ospf_ism.c \
|
||||||
|
@ -82,6 +84,7 @@ clippy_scan += \
|
||||||
ospfd/ospf_vty.c \
|
ospfd/ospf_vty.c \
|
||||||
ospfd/ospf_ldp_sync.c \
|
ospfd/ospf_ldp_sync.c \
|
||||||
ospfd/ospf_dump.c \
|
ospfd/ospf_dump.c \
|
||||||
|
ospfd/ospf_gr.c \
|
||||||
# end
|
# end
|
||||||
|
|
||||||
noinst_HEADERS += \
|
noinst_HEADERS += \
|
||||||
|
@ -100,6 +103,7 @@ noinst_HEADERS += \
|
||||||
ospfd/ospf_network.h \
|
ospfd/ospf_network.h \
|
||||||
ospfd/ospf_packet.h \
|
ospfd/ospf_packet.h \
|
||||||
ospfd/ospf_ri.h \
|
ospfd/ospf_ri.h \
|
||||||
|
ospfd/ospf_gr.h \
|
||||||
ospfd/ospf_route.h \
|
ospfd/ospf_route.h \
|
||||||
ospfd/ospf_routemap_nb.h \
|
ospfd/ospf_routemap_nb.h \
|
||||||
ospfd/ospf_spf.h \
|
ospfd/ospf_spf.h \
|
||||||
|
@ -108,7 +112,6 @@ noinst_HEADERS += \
|
||||||
ospfd/ospf_te.h \
|
ospfd/ospf_te.h \
|
||||||
ospfd/ospf_vty.h \
|
ospfd/ospf_vty.h \
|
||||||
ospfd/ospf_zebra.h \
|
ospfd/ospf_zebra.h \
|
||||||
ospfd/ospf_gr_helper.h \
|
|
||||||
# end
|
# end
|
||||||
|
|
||||||
ospfd_ospfd_LDADD = ospfd/libfrrospf.a lib/libfrr.la $(LIBCAP) $(LIBM)
|
ospfd_ospfd_LDADD = ospfd/libfrrospf.a lib/libfrr.la $(LIBCAP) $(LIBM)
|
||||||
|
|
|
@ -365,7 +365,7 @@ def create_common_configuration(
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def kill_router_daemons(tgen, router, daemons):
|
def kill_router_daemons(tgen, router, daemons, save_config=True):
|
||||||
"""
|
"""
|
||||||
Router's current config would be saved to /etc/frr/ for each daemon
|
Router's current config would be saved to /etc/frr/ for each daemon
|
||||||
and daemon would be killed forcefully using SIGKILL.
|
and daemon would be killed forcefully using SIGKILL.
|
||||||
|
@ -379,6 +379,7 @@ def kill_router_daemons(tgen, router, daemons):
|
||||||
try:
|
try:
|
||||||
router_list = tgen.routers()
|
router_list = tgen.routers()
|
||||||
|
|
||||||
|
if save_config:
|
||||||
# Saving router config to /etc/frr, which will be loaded to router
|
# Saving router config to /etc/frr, which will be loaded to router
|
||||||
# when it starts
|
# when it starts
|
||||||
router_list[router].vtysh_cmd("write memory")
|
router_list[router].vtysh_cmd("write memory")
|
||||||
|
|
0
tests/topotests/ospf_gr_topo1/__init__.py
Normal file
0
tests/topotests/ospf_gr_topo1/__init__.py
Normal file
32
tests/topotests/ospf_gr_topo1/rt1/ospfd.conf
Normal file
32
tests/topotests/ospf_gr_topo1/rt1/ospfd.conf
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
password 1
|
||||||
|
hostname rt1
|
||||||
|
log file ospfd.log
|
||||||
|
log commands
|
||||||
|
!
|
||||||
|
debug ospf zebra
|
||||||
|
debug ospf event
|
||||||
|
debug ospf lsa
|
||||||
|
debug ospf te
|
||||||
|
debug ospf packet all
|
||||||
|
debug ospf packet ls-update detail
|
||||||
|
debug ospf ism
|
||||||
|
debug ospf nsm
|
||||||
|
debug ospf nssa
|
||||||
|
debug ospf graceful-restart
|
||||||
|
!
|
||||||
|
interface lo
|
||||||
|
ip ospf area 1
|
||||||
|
!
|
||||||
|
interface eth-rt2
|
||||||
|
ip ospf network point-to-point
|
||||||
|
ip ospf area 1
|
||||||
|
ip ospf hello-interval 3
|
||||||
|
ip ospf dead-interval 9
|
||||||
|
!
|
||||||
|
router ospf
|
||||||
|
router-id 1.1.1.1
|
||||||
|
capability opaque
|
||||||
|
redistribute connected
|
||||||
|
graceful-restart grace-period 120
|
||||||
|
graceful-restart helper-only
|
||||||
|
!
|
98
tests/topotests/ospf_gr_topo1/rt1/show_ip_ospf_database.json
Normal file
98
tests/topotests/ospf_gr_topo1/rt1/show_ip_ospf_database.json
Normal file
|
@ -0,0 +1,98 @@
|
||||||
|
{
|
||||||
|
"routerId":"1.1.1.1",
|
||||||
|
"areas":{
|
||||||
|
"0.0.0.1":{
|
||||||
|
"routerLinkStates":[
|
||||||
|
{
|
||||||
|
"lsId":"1.1.1.1",
|
||||||
|
"advertisedRouter":"1.1.1.1",
|
||||||
|
"numOfRouterLinks":3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"2.2.2.2",
|
||||||
|
"advertisedRouter":"2.2.2.2",
|
||||||
|
"numOfRouterLinks":2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"summaryLinkStates":[
|
||||||
|
{
|
||||||
|
"lsId":"2.2.2.2",
|
||||||
|
"advertisedRouter":"2.2.2.2",
|
||||||
|
"summaryAddress":"2.2.2.2\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"3.3.3.3",
|
||||||
|
"advertisedRouter":"2.2.2.2",
|
||||||
|
"summaryAddress":"3.3.3.3\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"4.4.4.4",
|
||||||
|
"advertisedRouter":"2.2.2.2",
|
||||||
|
"summaryAddress":"4.4.4.4\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"5.5.5.5",
|
||||||
|
"advertisedRouter":"2.2.2.2",
|
||||||
|
"summaryAddress":"5.5.5.5\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"6.6.6.6",
|
||||||
|
"advertisedRouter":"2.2.2.2",
|
||||||
|
"summaryAddress":"6.6.6.6\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"7.7.7.7",
|
||||||
|
"advertisedRouter":"2.2.2.2",
|
||||||
|
"summaryAddress":"7.7.7.7\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.2.0",
|
||||||
|
"advertisedRouter":"2.2.2.2",
|
||||||
|
"summaryAddress":"10.0.2.0\/24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.3.0",
|
||||||
|
"advertisedRouter":"2.2.2.2",
|
||||||
|
"summaryAddress":"10.0.3.0\/24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.4.0",
|
||||||
|
"advertisedRouter":"2.2.2.2",
|
||||||
|
"summaryAddress":"10.0.4.0\/24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.5.0",
|
||||||
|
"advertisedRouter":"2.2.2.2",
|
||||||
|
"summaryAddress":"10.0.5.0\/24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.6.0",
|
||||||
|
"advertisedRouter":"2.2.2.2",
|
||||||
|
"summaryAddress":"10.0.6.0\/24"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"asbrSummaryLinkStates":[
|
||||||
|
{
|
||||||
|
"lsId":"6.6.6.6",
|
||||||
|
"advertisedRouter":"2.2.2.2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"asExternalLinkStates":[
|
||||||
|
{
|
||||||
|
"lsId":"172.16.1.0",
|
||||||
|
"advertisedRouter":"1.1.1.1",
|
||||||
|
"metricType":"E2",
|
||||||
|
"route":"172.16.1.0\/24",
|
||||||
|
"tag":0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"192.168.1.0",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"metricType":"E2",
|
||||||
|
"route":"192.168.1.0\/24",
|
||||||
|
"tag":0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
11
tests/topotests/ospf_gr_topo1/rt1/show_ip_ospf_neighbor.json
Normal file
11
tests/topotests/ospf_gr_topo1/rt1/show_ip_ospf_neighbor.json
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"neighbors":{
|
||||||
|
"2.2.2.2":[
|
||||||
|
{
|
||||||
|
"state":"Full\/DROther",
|
||||||
|
"address":"10.0.1.2",
|
||||||
|
"ifaceName":"eth-rt2:10.0.1.1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
180
tests/topotests/ospf_gr_topo1/rt1/show_ip_ospf_route.json
Normal file
180
tests/topotests/ospf_gr_topo1/rt1/show_ip_ospf_route.json
Normal file
|
@ -0,0 +1,180 @@
|
||||||
|
{
|
||||||
|
"1.1.1.1\/32":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":0,
|
||||||
|
"area":"0.0.0.1",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":" ",
|
||||||
|
"directly attached to":"lo"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"2.2.2.2\/32":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":10,
|
||||||
|
"area":"0.0.0.1",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.1.2",
|
||||||
|
"via":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"3.3.3.3\/32":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":20,
|
||||||
|
"area":"0.0.0.1",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.1.2",
|
||||||
|
"via":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"4.4.4.4\/32":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":30,
|
||||||
|
"area":"0.0.0.1",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.1.2",
|
||||||
|
"via":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"5.5.5.5\/32":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":40,
|
||||||
|
"area":"0.0.0.1",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.1.2",
|
||||||
|
"via":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"6.6.6.6\/32":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":30,
|
||||||
|
"area":"0.0.0.1",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.1.2",
|
||||||
|
"via":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"7.7.7.7\/32":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":40,
|
||||||
|
"area":"0.0.0.1",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.1.2",
|
||||||
|
"via":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.1.0\/24":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":10,
|
||||||
|
"area":"0.0.0.1",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":" ",
|
||||||
|
"directly attached to":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.2.0\/24":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":20,
|
||||||
|
"area":"0.0.0.1",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.1.2",
|
||||||
|
"via":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.3.0\/24":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":30,
|
||||||
|
"area":"0.0.0.1",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.1.2",
|
||||||
|
"via":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.4.0\/24":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":30,
|
||||||
|
"area":"0.0.0.1",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.1.2",
|
||||||
|
"via":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.5.0\/24":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":40,
|
||||||
|
"area":"0.0.0.1",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.1.2",
|
||||||
|
"via":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.6.0\/24":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":40,
|
||||||
|
"area":"0.0.0.1",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.1.2",
|
||||||
|
"via":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"2.2.2.2":{
|
||||||
|
"routeType":"R ",
|
||||||
|
"cost":10,
|
||||||
|
"area":"0.0.0.1",
|
||||||
|
"routerType":"abr",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.1.2",
|
||||||
|
"via":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"6.6.6.6":{
|
||||||
|
"routeType":"R ",
|
||||||
|
"cost":30,
|
||||||
|
"area":"0.0.0.1",
|
||||||
|
"IA":true,
|
||||||
|
"routerType":"asbr",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.1.2",
|
||||||
|
"via":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"192.168.1.0\/24":{
|
||||||
|
"routeType":"N E2",
|
||||||
|
"cost":40,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.1.2",
|
||||||
|
"via":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
210
tests/topotests/ospf_gr_topo1/rt1/show_ip_route.json
Normal file
210
tests/topotests/ospf_gr_topo1/rt1/show_ip_route.json
Normal file
|
@ -0,0 +1,210 @@
|
||||||
|
{
|
||||||
|
"1.1.1.1\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"1.1.1.1\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":0,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"directlyConnected":true,
|
||||||
|
"interfaceName":"lo"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"2.2.2.2\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"2.2.2.2\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":10,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.1.2",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"3.3.3.3\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"3.3.3.3\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":20,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.1.2",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"4.4.4.4\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"4.4.4.4\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":30,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.1.2",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"5.5.5.5\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"5.5.5.5\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":40,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.1.2",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"6.6.6.6\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"6.6.6.6\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":30,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.1.2",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"7.7.7.7\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"7.7.7.7\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":40,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.1.2",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.1.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.1.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":10,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"directlyConnected":true,
|
||||||
|
"interfaceName":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.2.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.2.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":20,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.1.2",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.3.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.3.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":30,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.1.2",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.4.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.4.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":30,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.1.2",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.5.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.5.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":40,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.1.2",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.6.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.6.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":40,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.1.2",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"192.168.1.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"192.168.1.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":20,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.1.2",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
23
tests/topotests/ospf_gr_topo1/rt1/zebra.conf
Normal file
23
tests/topotests/ospf_gr_topo1/rt1/zebra.conf
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
password 1
|
||||||
|
hostname rt1
|
||||||
|
log file zebra.log
|
||||||
|
log commands
|
||||||
|
!
|
||||||
|
debug zebra event
|
||||||
|
debug zebra packet
|
||||||
|
debug zebra rib
|
||||||
|
debug zebra kernel
|
||||||
|
!
|
||||||
|
interface lo
|
||||||
|
ip address 1.1.1.1/32
|
||||||
|
!
|
||||||
|
interface stub1
|
||||||
|
ip address 172.16.1.1/24
|
||||||
|
!
|
||||||
|
interface eth-rt2
|
||||||
|
ip address 10.0.1.1/24
|
||||||
|
!
|
||||||
|
ip forwarding
|
||||||
|
!
|
||||||
|
line vty
|
||||||
|
!
|
37
tests/topotests/ospf_gr_topo1/rt2/ospfd.conf
Normal file
37
tests/topotests/ospf_gr_topo1/rt2/ospfd.conf
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
password 1
|
||||||
|
hostname rt2
|
||||||
|
log file ospfd.log
|
||||||
|
log commands
|
||||||
|
!
|
||||||
|
debug ospf zebra
|
||||||
|
debug ospf event
|
||||||
|
debug ospf lsa
|
||||||
|
debug ospf te
|
||||||
|
debug ospf packet all
|
||||||
|
debug ospf packet ls-update detail
|
||||||
|
debug ospf ism
|
||||||
|
debug ospf nsm
|
||||||
|
debug ospf nssa
|
||||||
|
debug ospf graceful-restart
|
||||||
|
!
|
||||||
|
interface lo
|
||||||
|
ip ospf area 0
|
||||||
|
!
|
||||||
|
interface eth-rt1
|
||||||
|
ip ospf network point-to-point
|
||||||
|
ip ospf area 1
|
||||||
|
ip ospf hello-interval 3
|
||||||
|
ip ospf dead-interval 9
|
||||||
|
!
|
||||||
|
interface eth-rt3
|
||||||
|
ip ospf network point-to-point
|
||||||
|
ip ospf area 0
|
||||||
|
ip ospf hello-interval 3
|
||||||
|
ip ospf dead-interval 9
|
||||||
|
!
|
||||||
|
router ospf
|
||||||
|
router-id 2.2.2.2
|
||||||
|
capability opaque
|
||||||
|
graceful-restart grace-period 120
|
||||||
|
graceful-restart helper-only
|
||||||
|
!
|
160
tests/topotests/ospf_gr_topo1/rt2/show_ip_ospf_database.json
Normal file
160
tests/topotests/ospf_gr_topo1/rt2/show_ip_ospf_database.json
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
{
|
||||||
|
"routerId":"2.2.2.2",
|
||||||
|
"areas":{
|
||||||
|
"0.0.0.0":{
|
||||||
|
"routerLinkStates":[
|
||||||
|
{
|
||||||
|
"lsId":"2.2.2.2",
|
||||||
|
"advertisedRouter":"2.2.2.2",
|
||||||
|
"numOfRouterLinks":3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"3.3.3.3",
|
||||||
|
"advertisedRouter":"3.3.3.3",
|
||||||
|
"numOfRouterLinks":7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"4.4.4.4",
|
||||||
|
"advertisedRouter":"4.4.4.4",
|
||||||
|
"numOfRouterLinks":3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"6.6.6.6",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"numOfRouterLinks":3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"summaryLinkStates":[
|
||||||
|
{
|
||||||
|
"lsId":"1.1.1.1",
|
||||||
|
"advertisedRouter":"2.2.2.2",
|
||||||
|
"summaryAddress":"1.1.1.1\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"5.5.5.5",
|
||||||
|
"advertisedRouter":"4.4.4.4",
|
||||||
|
"summaryAddress":"5.5.5.5\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"7.7.7.7",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"summaryAddress":"7.7.7.7\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.1.0",
|
||||||
|
"advertisedRouter":"2.2.2.2",
|
||||||
|
"summaryAddress":"10.0.1.0\/24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.5.0",
|
||||||
|
"advertisedRouter":"4.4.4.4",
|
||||||
|
"summaryAddress":"10.0.5.0\/24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.6.0",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"summaryAddress":"10.0.6.0\/24"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"asbrSummaryLinkStates":[
|
||||||
|
{
|
||||||
|
"lsId":"1.1.1.1",
|
||||||
|
"advertisedRouter":"2.2.2.2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"0.0.0.1":{
|
||||||
|
"routerLinkStates":[
|
||||||
|
{
|
||||||
|
"lsId":"1.1.1.1",
|
||||||
|
"advertisedRouter":"1.1.1.1",
|
||||||
|
"numOfRouterLinks":3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"2.2.2.2",
|
||||||
|
"advertisedRouter":"2.2.2.2",
|
||||||
|
"numOfRouterLinks":2
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"summaryLinkStates":[
|
||||||
|
{
|
||||||
|
"lsId":"2.2.2.2",
|
||||||
|
"advertisedRouter":"2.2.2.2",
|
||||||
|
"summaryAddress":"2.2.2.2\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"3.3.3.3",
|
||||||
|
"advertisedRouter":"2.2.2.2",
|
||||||
|
"summaryAddress":"3.3.3.3\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"4.4.4.4",
|
||||||
|
"advertisedRouter":"2.2.2.2",
|
||||||
|
"summaryAddress":"4.4.4.4\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"5.5.5.5",
|
||||||
|
"advertisedRouter":"2.2.2.2",
|
||||||
|
"summaryAddress":"5.5.5.5\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"6.6.6.6",
|
||||||
|
"advertisedRouter":"2.2.2.2",
|
||||||
|
"summaryAddress":"6.6.6.6\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"7.7.7.7",
|
||||||
|
"advertisedRouter":"2.2.2.2",
|
||||||
|
"summaryAddress":"7.7.7.7\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.2.0",
|
||||||
|
"advertisedRouter":"2.2.2.2",
|
||||||
|
"summaryAddress":"10.0.2.0\/24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.3.0",
|
||||||
|
"advertisedRouter":"2.2.2.2",
|
||||||
|
"summaryAddress":"10.0.3.0\/24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.4.0",
|
||||||
|
"advertisedRouter":"2.2.2.2",
|
||||||
|
"summaryAddress":"10.0.4.0\/24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.5.0",
|
||||||
|
"advertisedRouter":"2.2.2.2",
|
||||||
|
"summaryAddress":"10.0.5.0\/24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.6.0",
|
||||||
|
"advertisedRouter":"2.2.2.2",
|
||||||
|
"summaryAddress":"10.0.6.0\/24"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"asbrSummaryLinkStates":[
|
||||||
|
{
|
||||||
|
"lsId":"6.6.6.6",
|
||||||
|
"advertisedRouter":"2.2.2.2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"asExternalLinkStates":[
|
||||||
|
{
|
||||||
|
"lsId":"172.16.1.0",
|
||||||
|
"advertisedRouter":"1.1.1.1",
|
||||||
|
"metricType":"E2",
|
||||||
|
"route":"172.16.1.0\/24",
|
||||||
|
"tag":0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"192.168.1.0",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"metricType":"E2",
|
||||||
|
"route":"192.168.1.0\/24",
|
||||||
|
"tag":0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
18
tests/topotests/ospf_gr_topo1/rt2/show_ip_ospf_neighbor.json
Normal file
18
tests/topotests/ospf_gr_topo1/rt2/show_ip_ospf_neighbor.json
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"neighbors":{
|
||||||
|
"1.1.1.1":[
|
||||||
|
{
|
||||||
|
"state":"Full\/DROther",
|
||||||
|
"address":"10.0.1.1",
|
||||||
|
"ifaceName":"eth-rt1:10.0.1.2"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"3.3.3.3":[
|
||||||
|
{
|
||||||
|
"state":"Full\/DROther",
|
||||||
|
"address":"10.0.2.3",
|
||||||
|
"ifaceName":"eth-rt3:10.0.2.2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
201
tests/topotests/ospf_gr_topo1/rt2/show_ip_ospf_route.json
Normal file
201
tests/topotests/ospf_gr_topo1/rt2/show_ip_ospf_route.json
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
{
|
||||||
|
"1.1.1.1\/32":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":10,
|
||||||
|
"area":"0.0.0.1",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.1.1",
|
||||||
|
"via":"eth-rt1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"2.2.2.2\/32":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":0,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":" ",
|
||||||
|
"directly attached to":"lo"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"3.3.3.3\/32":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":10,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.2.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"4.4.4.4\/32":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":20,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.2.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"5.5.5.5\/32":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":30,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.2.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"6.6.6.6\/32":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":20,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.2.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"7.7.7.7\/32":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":30,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.2.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.1.0\/24":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":10,
|
||||||
|
"area":"0.0.0.1",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":" ",
|
||||||
|
"directly attached to":"eth-rt1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.2.0\/24":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":10,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":" ",
|
||||||
|
"directly attached to":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.3.0\/24":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":20,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.2.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.4.0\/24":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":20,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.2.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.5.0\/24":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":30,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.2.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.6.0\/24":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":30,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.2.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"1.1.1.1":{
|
||||||
|
"routeType":"R ",
|
||||||
|
"cost":10,
|
||||||
|
"area":"0.0.0.1",
|
||||||
|
"routerType":"asbr",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.1.1",
|
||||||
|
"via":"eth-rt1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"4.4.4.4":{
|
||||||
|
"routeType":"R ",
|
||||||
|
"cost":20,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"routerType":"abr",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.2.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"6.6.6.6":{
|
||||||
|
"routeType":"R ",
|
||||||
|
"cost":20,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"routerType":"abr",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.2.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"172.16.1.0\/24":{
|
||||||
|
"routeType":"N E2",
|
||||||
|
"cost":10,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.1.1",
|
||||||
|
"via":"eth-rt1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"192.168.1.0\/24":{
|
||||||
|
"routeType":"N E2",
|
||||||
|
"cost":30,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.2.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
224
tests/topotests/ospf_gr_topo1/rt2/show_ip_route.json
Normal file
224
tests/topotests/ospf_gr_topo1/rt2/show_ip_route.json
Normal file
|
@ -0,0 +1,224 @@
|
||||||
|
{
|
||||||
|
"1.1.1.1\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"1.1.1.1\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":10,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.1.1",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"2.2.2.2\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"2.2.2.2\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":0,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"directlyConnected":true,
|
||||||
|
"interfaceName":"lo"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"3.3.3.3\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"3.3.3.3\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":10,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.2.3",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"4.4.4.4\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"4.4.4.4\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":20,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.2.3",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"5.5.5.5\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"5.5.5.5\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":30,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.2.3",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"6.6.6.6\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"6.6.6.6\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":20,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.2.3",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"7.7.7.7\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"7.7.7.7\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":30,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.2.3",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.1.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.1.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":10,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"directlyConnected":true,
|
||||||
|
"interfaceName":"eth-rt1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.2.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.2.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":10,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"directlyConnected":true,
|
||||||
|
"interfaceName":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.3.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.3.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":20,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.2.3",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.4.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.4.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":20,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.2.3",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.5.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.5.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":30,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.2.3",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.6.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.6.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":30,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.2.3",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"172.16.1.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"172.16.1.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":20,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.1.1",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt1"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"192.168.1.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"192.168.1.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":20,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.2.3",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
23
tests/topotests/ospf_gr_topo1/rt2/zebra.conf
Normal file
23
tests/topotests/ospf_gr_topo1/rt2/zebra.conf
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
password 1
|
||||||
|
hostname rt2
|
||||||
|
log file zebra.log
|
||||||
|
log commands
|
||||||
|
!
|
||||||
|
debug zebra event
|
||||||
|
debug zebra packet
|
||||||
|
debug zebra rib
|
||||||
|
debug zebra kernel
|
||||||
|
!
|
||||||
|
interface lo
|
||||||
|
ip address 2.2.2.2/32
|
||||||
|
!
|
||||||
|
interface eth-rt1
|
||||||
|
ip address 10.0.1.2/24
|
||||||
|
!
|
||||||
|
interface eth-rt3
|
||||||
|
ip address 10.0.2.2/24
|
||||||
|
!
|
||||||
|
ip forwarding
|
||||||
|
!
|
||||||
|
line vty
|
||||||
|
!
|
43
tests/topotests/ospf_gr_topo1/rt3/ospfd.conf
Normal file
43
tests/topotests/ospf_gr_topo1/rt3/ospfd.conf
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
password 1
|
||||||
|
hostname rt3
|
||||||
|
log file ospfd.log
|
||||||
|
log commands
|
||||||
|
!
|
||||||
|
debug ospf zebra
|
||||||
|
debug ospf event
|
||||||
|
debug ospf lsa
|
||||||
|
debug ospf te
|
||||||
|
debug ospf packet all
|
||||||
|
debug ospf packet ls-update detail
|
||||||
|
debug ospf ism
|
||||||
|
debug ospf nsm
|
||||||
|
debug ospf nssa
|
||||||
|
debug ospf graceful-restart
|
||||||
|
!
|
||||||
|
interface lo
|
||||||
|
ip ospf area 0
|
||||||
|
!
|
||||||
|
interface eth-rt2
|
||||||
|
ip ospf network point-to-point
|
||||||
|
ip ospf area 0
|
||||||
|
ip ospf hello-interval 3
|
||||||
|
ip ospf dead-interval 9
|
||||||
|
!
|
||||||
|
interface eth-rt4
|
||||||
|
ip ospf network point-to-point
|
||||||
|
ip ospf area 0
|
||||||
|
ip ospf hello-interval 3
|
||||||
|
ip ospf dead-interval 9
|
||||||
|
!
|
||||||
|
interface eth-rt6
|
||||||
|
ip ospf network point-to-point
|
||||||
|
ip ospf area 0
|
||||||
|
ip ospf hello-interval 3
|
||||||
|
ip ospf dead-interval 9
|
||||||
|
!
|
||||||
|
router ospf
|
||||||
|
router-id 3.3.3.3
|
||||||
|
capability opaque
|
||||||
|
graceful-restart grace-period 120
|
||||||
|
graceful-restart helper-only
|
||||||
|
!
|
83
tests/topotests/ospf_gr_topo1/rt3/show_ip_ospf_database.json
Normal file
83
tests/topotests/ospf_gr_topo1/rt3/show_ip_ospf_database.json
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
{
|
||||||
|
"routerId":"3.3.3.3",
|
||||||
|
"areas":{
|
||||||
|
"0.0.0.0":{
|
||||||
|
"routerLinkStates":[
|
||||||
|
{
|
||||||
|
"lsId":"2.2.2.2",
|
||||||
|
"advertisedRouter":"2.2.2.2",
|
||||||
|
"numOfRouterLinks":3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"3.3.3.3",
|
||||||
|
"advertisedRouter":"3.3.3.3",
|
||||||
|
"numOfRouterLinks":7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"4.4.4.4",
|
||||||
|
"advertisedRouter":"4.4.4.4",
|
||||||
|
"numOfRouterLinks":3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"6.6.6.6",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"numOfRouterLinks":3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"summaryLinkStates":[
|
||||||
|
{
|
||||||
|
"lsId":"1.1.1.1",
|
||||||
|
"advertisedRouter":"2.2.2.2",
|
||||||
|
"summaryAddress":"1.1.1.1\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"5.5.5.5",
|
||||||
|
"advertisedRouter":"4.4.4.4",
|
||||||
|
"summaryAddress":"5.5.5.5\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"7.7.7.7",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"summaryAddress":"7.7.7.7\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.1.0",
|
||||||
|
"advertisedRouter":"2.2.2.2",
|
||||||
|
"summaryAddress":"10.0.1.0\/24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.5.0",
|
||||||
|
"advertisedRouter":"4.4.4.4",
|
||||||
|
"summaryAddress":"10.0.5.0\/24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.6.0",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"summaryAddress":"10.0.6.0\/24"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"asbrSummaryLinkStates":[
|
||||||
|
{
|
||||||
|
"lsId":"1.1.1.1",
|
||||||
|
"advertisedRouter":"2.2.2.2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"asExternalLinkStates":[
|
||||||
|
{
|
||||||
|
"lsId":"172.16.1.0",
|
||||||
|
"advertisedRouter":"1.1.1.1",
|
||||||
|
"metricType":"E2",
|
||||||
|
"route":"172.16.1.0\/24",
|
||||||
|
"tag":0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"192.168.1.0",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"metricType":"E2",
|
||||||
|
"route":"192.168.1.0\/24",
|
||||||
|
"tag":0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
25
tests/topotests/ospf_gr_topo1/rt3/show_ip_ospf_neighbor.json
Normal file
25
tests/topotests/ospf_gr_topo1/rt3/show_ip_ospf_neighbor.json
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"neighbors":{
|
||||||
|
"2.2.2.2":[
|
||||||
|
{
|
||||||
|
"state":"Full\/DROther",
|
||||||
|
"address":"10.0.2.2",
|
||||||
|
"ifaceName":"eth-rt2:10.0.2.3"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"4.4.4.4":[
|
||||||
|
{
|
||||||
|
"state":"Full\/DROther",
|
||||||
|
"address":"10.0.3.4",
|
||||||
|
"ifaceName":"eth-rt4:10.0.3.3"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"6.6.6.6":[
|
||||||
|
{
|
||||||
|
"state":"Full\/DROther",
|
||||||
|
"address":"10.0.4.6",
|
||||||
|
"ifaceName":"eth-rt6:10.0.4.3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
214
tests/topotests/ospf_gr_topo1/rt3/show_ip_ospf_route.json
Normal file
214
tests/topotests/ospf_gr_topo1/rt3/show_ip_ospf_route.json
Normal file
|
@ -0,0 +1,214 @@
|
||||||
|
{
|
||||||
|
"1.1.1.1\/32":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":20,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.2.2",
|
||||||
|
"via":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"2.2.2.2\/32":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":10,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.2.2",
|
||||||
|
"via":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"3.3.3.3\/32":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":0,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":" ",
|
||||||
|
"directly attached to":"lo"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"4.4.4.4\/32":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":10,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.3.4",
|
||||||
|
"via":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"5.5.5.5\/32":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":20,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.3.4",
|
||||||
|
"via":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"6.6.6.6\/32":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":10,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.4.6",
|
||||||
|
"via":"eth-rt6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"7.7.7.7\/32":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":20,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.4.6",
|
||||||
|
"via":"eth-rt6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.1.0\/24":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":20,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.2.2",
|
||||||
|
"via":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.2.0\/24":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":10,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":" ",
|
||||||
|
"directly attached to":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.3.0\/24":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":10,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":" ",
|
||||||
|
"directly attached to":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.4.0\/24":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":10,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":" ",
|
||||||
|
"directly attached to":"eth-rt6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.5.0\/24":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":20,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.3.4",
|
||||||
|
"via":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.6.0\/24":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":20,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.4.6",
|
||||||
|
"via":"eth-rt6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"1.1.1.1":{
|
||||||
|
"routeType":"R ",
|
||||||
|
"cost":20,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"IA":true,
|
||||||
|
"routerType":"asbr",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.2.2",
|
||||||
|
"via":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"2.2.2.2":{
|
||||||
|
"routeType":"R ",
|
||||||
|
"cost":10,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"routerType":"abr",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.2.2",
|
||||||
|
"via":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"4.4.4.4":{
|
||||||
|
"routeType":"R ",
|
||||||
|
"cost":10,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"routerType":"abr",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.3.4",
|
||||||
|
"via":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"6.6.6.6":{
|
||||||
|
"routeType":"R ",
|
||||||
|
"cost":10,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"routerType":"abr",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.4.6",
|
||||||
|
"via":"eth-rt6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"172.16.1.0\/24":{
|
||||||
|
"routeType":"N E2",
|
||||||
|
"cost":20,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.2.2",
|
||||||
|
"via":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"192.168.1.0\/24":{
|
||||||
|
"routeType":"N E2",
|
||||||
|
"cost":20,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.4.6",
|
||||||
|
"via":"eth-rt6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
223
tests/topotests/ospf_gr_topo1/rt3/show_ip_route.json
Normal file
223
tests/topotests/ospf_gr_topo1/rt3/show_ip_route.json
Normal file
|
@ -0,0 +1,223 @@
|
||||||
|
{
|
||||||
|
"1.1.1.1\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"1.1.1.1\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":20,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.2.2",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"2.2.2.2\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"2.2.2.2\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":10,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.2.2",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"3.3.3.3\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"3.3.3.3\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":0,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"directlyConnected":true,
|
||||||
|
"interfaceName":"lo"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"4.4.4.4\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"4.4.4.4\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":10,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.3.4",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"5.5.5.5\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"5.5.5.5\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":20,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.3.4",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"6.6.6.6\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"6.6.6.6\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":10,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.4.6",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"7.7.7.7\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"7.7.7.7\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":20,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.4.6",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.1.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.1.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":20,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.2.2",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.2.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.2.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":10,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"directlyConnected":true,
|
||||||
|
"interfaceName":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.3.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.3.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":10,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"directlyConnected":true,
|
||||||
|
"interfaceName":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.4.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.4.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":10,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"directlyConnected":true,
|
||||||
|
"interfaceName":"eth-rt6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.5.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.5.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":20,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.3.4",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.6.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.6.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":20,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.4.6",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"172.16.1.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"172.16.1.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":20,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.2.2",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"192.168.1.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"192.168.1.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":20,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.4.6",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
26
tests/topotests/ospf_gr_topo1/rt3/zebra.conf
Normal file
26
tests/topotests/ospf_gr_topo1/rt3/zebra.conf
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
password 1
|
||||||
|
hostname rt3
|
||||||
|
log file zebra.log
|
||||||
|
log commands
|
||||||
|
!
|
||||||
|
debug zebra event
|
||||||
|
debug zebra packet
|
||||||
|
debug zebra rib
|
||||||
|
debug zebra kernel
|
||||||
|
!
|
||||||
|
interface lo
|
||||||
|
ip address 3.3.3.3/32
|
||||||
|
!
|
||||||
|
interface eth-rt2
|
||||||
|
ip address 10.0.2.3/24
|
||||||
|
!
|
||||||
|
interface eth-rt4
|
||||||
|
ip address 10.0.3.3/24
|
||||||
|
!
|
||||||
|
interface eth-rt6
|
||||||
|
ip address 10.0.4.3/24
|
||||||
|
!
|
||||||
|
ip forwarding
|
||||||
|
!
|
||||||
|
line vty
|
||||||
|
!
|
37
tests/topotests/ospf_gr_topo1/rt4/ospfd.conf
Normal file
37
tests/topotests/ospf_gr_topo1/rt4/ospfd.conf
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
password 1
|
||||||
|
hostname rt4
|
||||||
|
log file ospfd.log
|
||||||
|
log commands
|
||||||
|
!
|
||||||
|
debug ospf zebra
|
||||||
|
debug ospf event
|
||||||
|
debug ospf lsa
|
||||||
|
debug ospf te
|
||||||
|
debug ospf packet all
|
||||||
|
debug ospf packet ls-update detail
|
||||||
|
debug ospf ism
|
||||||
|
debug ospf nsm
|
||||||
|
debug ospf nssa
|
||||||
|
debug ospf graceful-restart
|
||||||
|
!
|
||||||
|
interface lo
|
||||||
|
ip ospf area 0
|
||||||
|
!
|
||||||
|
interface eth-rt3
|
||||||
|
ip ospf network point-to-point
|
||||||
|
ip ospf area 0
|
||||||
|
ip ospf hello-interval 3
|
||||||
|
ip ospf dead-interval 9
|
||||||
|
!
|
||||||
|
interface eth-rt5
|
||||||
|
ip ospf network point-to-point
|
||||||
|
ip ospf area 2
|
||||||
|
ip ospf hello-interval 3
|
||||||
|
ip ospf dead-interval 9
|
||||||
|
!
|
||||||
|
router ospf
|
||||||
|
router-id 4.4.4.4
|
||||||
|
capability opaque
|
||||||
|
graceful-restart grace-period 120
|
||||||
|
graceful-restart helper-only
|
||||||
|
!
|
164
tests/topotests/ospf_gr_topo1/rt4/show_ip_ospf_database.json
Normal file
164
tests/topotests/ospf_gr_topo1/rt4/show_ip_ospf_database.json
Normal file
|
@ -0,0 +1,164 @@
|
||||||
|
{
|
||||||
|
"routerId":"4.4.4.4",
|
||||||
|
"areas":{
|
||||||
|
"0.0.0.0":{
|
||||||
|
"routerLinkStates":[
|
||||||
|
{
|
||||||
|
"lsId":"2.2.2.2",
|
||||||
|
"advertisedRouter":"2.2.2.2",
|
||||||
|
"numOfRouterLinks":3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"3.3.3.3",
|
||||||
|
"advertisedRouter":"3.3.3.3",
|
||||||
|
"numOfRouterLinks":7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"4.4.4.4",
|
||||||
|
"advertisedRouter":"4.4.4.4",
|
||||||
|
"numOfRouterLinks":3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"6.6.6.6",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"numOfRouterLinks":3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"summaryLinkStates":[
|
||||||
|
{
|
||||||
|
"lsId":"1.1.1.1",
|
||||||
|
"advertisedRouter":"2.2.2.2",
|
||||||
|
"summaryAddress":"1.1.1.1\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"5.5.5.5",
|
||||||
|
"advertisedRouter":"4.4.4.4",
|
||||||
|
"summaryAddress":"5.5.5.5\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"7.7.7.7",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"summaryAddress":"7.7.7.7\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.1.0",
|
||||||
|
"advertisedRouter":"2.2.2.2",
|
||||||
|
"summaryAddress":"10.0.1.0\/24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.5.0",
|
||||||
|
"advertisedRouter":"4.4.4.4",
|
||||||
|
"summaryAddress":"10.0.5.0\/24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.6.0",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"summaryAddress":"10.0.6.0\/24"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"asbrSummaryLinkStates":[
|
||||||
|
{
|
||||||
|
"lsId":"1.1.1.1",
|
||||||
|
"advertisedRouter":"2.2.2.2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"0.0.0.2":{
|
||||||
|
"routerLinkStates":[
|
||||||
|
{
|
||||||
|
"lsId":"4.4.4.4",
|
||||||
|
"advertisedRouter":"4.4.4.4",
|
||||||
|
"numOfRouterLinks":2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"5.5.5.5",
|
||||||
|
"advertisedRouter":"5.5.5.5",
|
||||||
|
"numOfRouterLinks":3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"summaryLinkStates":[
|
||||||
|
{
|
||||||
|
"lsId":"1.1.1.1",
|
||||||
|
"advertisedRouter":"4.4.4.4",
|
||||||
|
"summaryAddress":"1.1.1.1\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"2.2.2.2",
|
||||||
|
"advertisedRouter":"4.4.4.4",
|
||||||
|
"summaryAddress":"2.2.2.2\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"3.3.3.3",
|
||||||
|
"advertisedRouter":"4.4.4.4",
|
||||||
|
"summaryAddress":"3.3.3.3\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"4.4.4.4",
|
||||||
|
"advertisedRouter":"4.4.4.4",
|
||||||
|
"summaryAddress":"4.4.4.4\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"6.6.6.6",
|
||||||
|
"advertisedRouter":"4.4.4.4",
|
||||||
|
"summaryAddress":"6.6.6.6\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"7.7.7.7",
|
||||||
|
"advertisedRouter":"4.4.4.4",
|
||||||
|
"summaryAddress":"7.7.7.7\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.1.0",
|
||||||
|
"advertisedRouter":"4.4.4.4",
|
||||||
|
"summaryAddress":"10.0.1.0\/24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.2.0",
|
||||||
|
"advertisedRouter":"4.4.4.4",
|
||||||
|
"summaryAddress":"10.0.2.0\/24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.3.0",
|
||||||
|
"advertisedRouter":"4.4.4.4",
|
||||||
|
"summaryAddress":"10.0.3.0\/24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.4.0",
|
||||||
|
"advertisedRouter":"4.4.4.4",
|
||||||
|
"summaryAddress":"10.0.4.0\/24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.6.0",
|
||||||
|
"advertisedRouter":"4.4.4.4",
|
||||||
|
"summaryAddress":"10.0.6.0\/24"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"asbrSummaryLinkStates":[
|
||||||
|
{
|
||||||
|
"lsId":"1.1.1.1",
|
||||||
|
"advertisedRouter":"4.4.4.4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"6.6.6.6",
|
||||||
|
"advertisedRouter":"4.4.4.4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"asExternalLinkStates":[
|
||||||
|
{
|
||||||
|
"lsId":"172.16.1.0",
|
||||||
|
"advertisedRouter":"1.1.1.1",
|
||||||
|
"metricType":"E2",
|
||||||
|
"route":"172.16.1.0\/24",
|
||||||
|
"tag":0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"192.168.1.0",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"metricType":"E2",
|
||||||
|
"route":"192.168.1.0\/24",
|
||||||
|
"tag":0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
18
tests/topotests/ospf_gr_topo1/rt4/show_ip_ospf_neighbor.json
Normal file
18
tests/topotests/ospf_gr_topo1/rt4/show_ip_ospf_neighbor.json
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"neighbors":{
|
||||||
|
"3.3.3.3":[
|
||||||
|
{
|
||||||
|
"state":"Full\/DROther",
|
||||||
|
"address":"10.0.3.3",
|
||||||
|
"ifaceName":"eth-rt3:10.0.3.4"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"5.5.5.5":[
|
||||||
|
{
|
||||||
|
"state":"Full\/DROther",
|
||||||
|
"address":"10.0.5.5",
|
||||||
|
"ifaceName":"eth-rt5:10.0.5.4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
202
tests/topotests/ospf_gr_topo1/rt4/show_ip_ospf_route.json
Normal file
202
tests/topotests/ospf_gr_topo1/rt4/show_ip_ospf_route.json
Normal file
|
@ -0,0 +1,202 @@
|
||||||
|
{
|
||||||
|
"1.1.1.1\/32":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":30,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.3.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"2.2.2.2\/32":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":20,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.3.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"3.3.3.3\/32":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":10,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.3.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"4.4.4.4\/32":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":0,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":" ",
|
||||||
|
"directly attached to":"lo"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"5.5.5.5\/32":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":10,
|
||||||
|
"area":"0.0.0.2",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.5.5",
|
||||||
|
"via":"eth-rt5"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"6.6.6.6\/32":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":20,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.3.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"7.7.7.7\/32":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":30,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.3.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.1.0\/24":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":30,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.3.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.2.0\/24":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":20,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.3.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.3.0\/24":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":10,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":" ",
|
||||||
|
"directly attached to":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.4.0\/24":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":20,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.3.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.5.0\/24":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":10,
|
||||||
|
"area":"0.0.0.2",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":" ",
|
||||||
|
"directly attached to":"eth-rt5"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.6.0\/24":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":30,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.3.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"1.1.1.1":{
|
||||||
|
"routeType":"R ",
|
||||||
|
"cost":30,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"IA":true,
|
||||||
|
"routerType":"asbr",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.3.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"2.2.2.2":{
|
||||||
|
"routeType":"R ",
|
||||||
|
"cost":20,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"routerType":"abr",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.3.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"6.6.6.6":{
|
||||||
|
"routeType":"R ",
|
||||||
|
"cost":20,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"routerType":"abr",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.3.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"172.16.1.0\/24":{
|
||||||
|
"routeType":"N E2",
|
||||||
|
"cost":30,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.3.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"192.168.1.0\/24":{
|
||||||
|
"routeType":"N E2",
|
||||||
|
"cost":30,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.3.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
224
tests/topotests/ospf_gr_topo1/rt4/show_ip_route.json
Normal file
224
tests/topotests/ospf_gr_topo1/rt4/show_ip_route.json
Normal file
|
@ -0,0 +1,224 @@
|
||||||
|
{
|
||||||
|
"1.1.1.1\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"1.1.1.1\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":30,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.3.3",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"2.2.2.2\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"2.2.2.2\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":20,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.3.3",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"3.3.3.3\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"3.3.3.3\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":10,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.3.3",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"4.4.4.4\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"4.4.4.4\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":0,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"directlyConnected":true,
|
||||||
|
"interfaceName":"lo"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"5.5.5.5\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"5.5.5.5\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":10,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.5.5",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt5"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"6.6.6.6\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"6.6.6.6\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":20,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.3.3",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"7.7.7.7\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"7.7.7.7\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":30,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.3.3",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.1.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.1.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":30,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.3.3",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.2.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.2.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":20,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.3.3",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.3.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.3.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":10,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"directlyConnected":true,
|
||||||
|
"interfaceName":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.4.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.4.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":20,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.3.3",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.5.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.5.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":10,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"directlyConnected":true,
|
||||||
|
"interfaceName":"eth-rt5"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.6.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.6.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":30,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.3.3",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"172.16.1.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"172.16.1.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":20,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.3.3",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"192.168.1.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"192.168.1.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":20,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.3.3",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
23
tests/topotests/ospf_gr_topo1/rt4/zebra.conf
Normal file
23
tests/topotests/ospf_gr_topo1/rt4/zebra.conf
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
password 1
|
||||||
|
hostname rt4
|
||||||
|
log file zebra.log
|
||||||
|
log commands
|
||||||
|
!
|
||||||
|
debug zebra event
|
||||||
|
debug zebra packet
|
||||||
|
debug zebra rib
|
||||||
|
debug zebra kernel
|
||||||
|
!
|
||||||
|
interface lo
|
||||||
|
ip address 4.4.4.4/32
|
||||||
|
!
|
||||||
|
interface eth-rt3
|
||||||
|
ip address 10.0.3.4/24
|
||||||
|
!
|
||||||
|
interface eth-rt5
|
||||||
|
ip address 10.0.5.4/24
|
||||||
|
!
|
||||||
|
ip forwarding
|
||||||
|
!
|
||||||
|
line vty
|
||||||
|
!
|
31
tests/topotests/ospf_gr_topo1/rt5/ospfd.conf
Normal file
31
tests/topotests/ospf_gr_topo1/rt5/ospfd.conf
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
password 1
|
||||||
|
hostname rt5
|
||||||
|
log file ospfd.log
|
||||||
|
log commands
|
||||||
|
!
|
||||||
|
debug ospf zebra
|
||||||
|
debug ospf event
|
||||||
|
debug ospf lsa
|
||||||
|
debug ospf te
|
||||||
|
debug ospf packet all
|
||||||
|
debug ospf packet ls-update detail
|
||||||
|
debug ospf ism
|
||||||
|
debug ospf nsm
|
||||||
|
debug ospf nssa
|
||||||
|
debug ospf graceful-restart
|
||||||
|
!
|
||||||
|
interface lo
|
||||||
|
ip ospf area 2
|
||||||
|
!
|
||||||
|
interface eth-rt4
|
||||||
|
ip ospf network point-to-point
|
||||||
|
ip ospf area 2
|
||||||
|
ip ospf hello-interval 3
|
||||||
|
ip ospf dead-interval 9
|
||||||
|
!
|
||||||
|
router ospf
|
||||||
|
router-id 5.5.5.5
|
||||||
|
capability opaque
|
||||||
|
graceful-restart grace-period 120
|
||||||
|
graceful-restart helper-only
|
||||||
|
!
|
102
tests/topotests/ospf_gr_topo1/rt5/show_ip_ospf_database.json
Normal file
102
tests/topotests/ospf_gr_topo1/rt5/show_ip_ospf_database.json
Normal file
|
@ -0,0 +1,102 @@
|
||||||
|
{
|
||||||
|
"routerId":"5.5.5.5",
|
||||||
|
"areas":{
|
||||||
|
"0.0.0.2":{
|
||||||
|
"routerLinkStates":[
|
||||||
|
{
|
||||||
|
"lsId":"4.4.4.4",
|
||||||
|
"advertisedRouter":"4.4.4.4",
|
||||||
|
"numOfRouterLinks":2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"5.5.5.5",
|
||||||
|
"advertisedRouter":"5.5.5.5",
|
||||||
|
"numOfRouterLinks":3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"summaryLinkStates":[
|
||||||
|
{
|
||||||
|
"lsId":"1.1.1.1",
|
||||||
|
"advertisedRouter":"4.4.4.4",
|
||||||
|
"summaryAddress":"1.1.1.1\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"2.2.2.2",
|
||||||
|
"advertisedRouter":"4.4.4.4",
|
||||||
|
"summaryAddress":"2.2.2.2\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"3.3.3.3",
|
||||||
|
"advertisedRouter":"4.4.4.4",
|
||||||
|
"summaryAddress":"3.3.3.3\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"4.4.4.4",
|
||||||
|
"advertisedRouter":"4.4.4.4",
|
||||||
|
"summaryAddress":"4.4.4.4\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"6.6.6.6",
|
||||||
|
"advertisedRouter":"4.4.4.4",
|
||||||
|
"summaryAddress":"6.6.6.6\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"7.7.7.7",
|
||||||
|
"advertisedRouter":"4.4.4.4",
|
||||||
|
"summaryAddress":"7.7.7.7\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.1.0",
|
||||||
|
"advertisedRouter":"4.4.4.4",
|
||||||
|
"summaryAddress":"10.0.1.0\/24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.2.0",
|
||||||
|
"advertisedRouter":"4.4.4.4",
|
||||||
|
"summaryAddress":"10.0.2.0\/24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.3.0",
|
||||||
|
"advertisedRouter":"4.4.4.4",
|
||||||
|
"summaryAddress":"10.0.3.0\/24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.4.0",
|
||||||
|
"advertisedRouter":"4.4.4.4",
|
||||||
|
"summaryAddress":"10.0.4.0\/24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.6.0",
|
||||||
|
"advertisedRouter":"4.4.4.4",
|
||||||
|
"summaryAddress":"10.0.6.0\/24"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"asbrSummaryLinkStates":[
|
||||||
|
{
|
||||||
|
"lsId":"1.1.1.1",
|
||||||
|
"advertisedRouter":"4.4.4.4"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"6.6.6.6",
|
||||||
|
"advertisedRouter":"4.4.4.4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"asExternalLinkStates":[
|
||||||
|
{
|
||||||
|
"lsId":"172.16.1.0",
|
||||||
|
"advertisedRouter":"1.1.1.1",
|
||||||
|
"metricType":"E2",
|
||||||
|
"route":"172.16.1.0\/24",
|
||||||
|
"tag":0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"192.168.1.0",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"metricType":"E2",
|
||||||
|
"route":"192.168.1.0\/24",
|
||||||
|
"tag":0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
11
tests/topotests/ospf_gr_topo1/rt5/show_ip_ospf_neighbor.json
Normal file
11
tests/topotests/ospf_gr_topo1/rt5/show_ip_ospf_neighbor.json
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"neighbors":{
|
||||||
|
"4.4.4.4":[
|
||||||
|
{
|
||||||
|
"state":"Full\/DROther",
|
||||||
|
"address":"10.0.5.4",
|
||||||
|
"ifaceName":"eth-rt4:10.0.5.5"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
203
tests/topotests/ospf_gr_topo1/rt5/show_ip_ospf_route.json
Normal file
203
tests/topotests/ospf_gr_topo1/rt5/show_ip_ospf_route.json
Normal file
|
@ -0,0 +1,203 @@
|
||||||
|
{
|
||||||
|
"1.1.1.1\/32":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":40,
|
||||||
|
"area":"0.0.0.2",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.5.4",
|
||||||
|
"via":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"2.2.2.2\/32":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":30,
|
||||||
|
"area":"0.0.0.2",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.5.4",
|
||||||
|
"via":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"3.3.3.3\/32":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":20,
|
||||||
|
"area":"0.0.0.2",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.5.4",
|
||||||
|
"via":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"4.4.4.4\/32":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":10,
|
||||||
|
"area":"0.0.0.2",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.5.4",
|
||||||
|
"via":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"5.5.5.5\/32":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":0,
|
||||||
|
"area":"0.0.0.2",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":" ",
|
||||||
|
"directly attached to":"lo"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"6.6.6.6\/32":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":30,
|
||||||
|
"area":"0.0.0.2",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.5.4",
|
||||||
|
"via":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"7.7.7.7\/32":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":40,
|
||||||
|
"area":"0.0.0.2",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.5.4",
|
||||||
|
"via":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.1.0\/24":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":40,
|
||||||
|
"area":"0.0.0.2",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.5.4",
|
||||||
|
"via":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.2.0\/24":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":30,
|
||||||
|
"area":"0.0.0.2",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.5.4",
|
||||||
|
"via":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.3.0\/24":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":20,
|
||||||
|
"area":"0.0.0.2",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.5.4",
|
||||||
|
"via":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.4.0\/24":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":30,
|
||||||
|
"area":"0.0.0.2",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.5.4",
|
||||||
|
"via":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.5.0\/24":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":10,
|
||||||
|
"area":"0.0.0.2",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":" ",
|
||||||
|
"directly attached to":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.6.0\/24":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":40,
|
||||||
|
"area":"0.0.0.2",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.5.4",
|
||||||
|
"via":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"1.1.1.1":{
|
||||||
|
"routeType":"R ",
|
||||||
|
"cost":40,
|
||||||
|
"area":"0.0.0.2",
|
||||||
|
"IA":true,
|
||||||
|
"routerType":"asbr",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.5.4",
|
||||||
|
"via":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"4.4.4.4":{
|
||||||
|
"routeType":"R ",
|
||||||
|
"cost":10,
|
||||||
|
"area":"0.0.0.2",
|
||||||
|
"routerType":"abr",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.5.4",
|
||||||
|
"via":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"6.6.6.6":{
|
||||||
|
"routeType":"R ",
|
||||||
|
"cost":30,
|
||||||
|
"area":"0.0.0.2",
|
||||||
|
"IA":true,
|
||||||
|
"routerType":"asbr",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.5.4",
|
||||||
|
"via":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"172.16.1.0\/24":{
|
||||||
|
"routeType":"N E2",
|
||||||
|
"cost":40,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.5.4",
|
||||||
|
"via":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"192.168.1.0\/24":{
|
||||||
|
"routeType":"N E2",
|
||||||
|
"cost":40,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.5.4",
|
||||||
|
"via":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
225
tests/topotests/ospf_gr_topo1/rt5/show_ip_route.json
Normal file
225
tests/topotests/ospf_gr_topo1/rt5/show_ip_route.json
Normal file
|
@ -0,0 +1,225 @@
|
||||||
|
{
|
||||||
|
"1.1.1.1\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"1.1.1.1\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":40,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.5.4",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"2.2.2.2\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"2.2.2.2\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":30,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.5.4",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"3.3.3.3\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"3.3.3.3\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":20,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.5.4",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"4.4.4.4\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"4.4.4.4\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":10,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.5.4",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"5.5.5.5\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"5.5.5.5\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":0,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"directlyConnected":true,
|
||||||
|
"interfaceName":"lo"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"6.6.6.6\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"6.6.6.6\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":30,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.5.4",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"7.7.7.7\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"7.7.7.7\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":40,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.5.4",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.1.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.1.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":40,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.5.4",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.2.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.2.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":30,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.5.4",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.3.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.3.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":20,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.5.4",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.4.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.4.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":30,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.5.4",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.5.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.5.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":10,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"directlyConnected":true,
|
||||||
|
"interfaceName":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.6.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.6.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":40,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.5.4",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"172.16.1.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"172.16.1.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":20,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.5.4",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"192.168.1.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"192.168.1.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":20,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.5.4",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt4"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
20
tests/topotests/ospf_gr_topo1/rt5/zebra.conf
Normal file
20
tests/topotests/ospf_gr_topo1/rt5/zebra.conf
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
password 1
|
||||||
|
hostname rt5
|
||||||
|
log file zebra.log
|
||||||
|
log commands
|
||||||
|
!
|
||||||
|
debug zebra event
|
||||||
|
debug zebra packet
|
||||||
|
debug zebra rib
|
||||||
|
debug zebra kernel
|
||||||
|
!
|
||||||
|
interface lo
|
||||||
|
ip address 5.5.5.5/32
|
||||||
|
!
|
||||||
|
interface eth-rt4
|
||||||
|
ip address 10.0.5.5/24
|
||||||
|
!
|
||||||
|
ip forwarding
|
||||||
|
!
|
||||||
|
line vty
|
||||||
|
!
|
38
tests/topotests/ospf_gr_topo1/rt6/ospfd.conf
Normal file
38
tests/topotests/ospf_gr_topo1/rt6/ospfd.conf
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
password 1
|
||||||
|
hostname rt6
|
||||||
|
log file ospfd.log
|
||||||
|
log commands
|
||||||
|
!
|
||||||
|
debug ospf zebra
|
||||||
|
debug ospf event
|
||||||
|
debug ospf lsa
|
||||||
|
debug ospf te
|
||||||
|
debug ospf packet all
|
||||||
|
debug ospf packet ls-update detail
|
||||||
|
debug ospf ism
|
||||||
|
debug ospf nsm
|
||||||
|
debug ospf nssa
|
||||||
|
debug ospf graceful-restart
|
||||||
|
!
|
||||||
|
interface lo
|
||||||
|
ip ospf area 0
|
||||||
|
!
|
||||||
|
interface eth-rt3
|
||||||
|
ip ospf network point-to-point
|
||||||
|
ip ospf area 0
|
||||||
|
ip ospf hello-interval 3
|
||||||
|
ip ospf dead-interval 9
|
||||||
|
!
|
||||||
|
interface eth-rt7
|
||||||
|
ip ospf network point-to-point
|
||||||
|
ip ospf area 3
|
||||||
|
ip ospf hello-interval 3
|
||||||
|
ip ospf dead-interval 9
|
||||||
|
!
|
||||||
|
router ospf
|
||||||
|
router-id 6.6.6.6
|
||||||
|
capability opaque
|
||||||
|
area 3 nssa
|
||||||
|
graceful-restart grace-period 120
|
||||||
|
graceful-restart helper-only
|
||||||
|
!
|
168
tests/topotests/ospf_gr_topo1/rt6/show_ip_ospf_database.json
Normal file
168
tests/topotests/ospf_gr_topo1/rt6/show_ip_ospf_database.json
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
{
|
||||||
|
"routerId":"6.6.6.6",
|
||||||
|
"areas":{
|
||||||
|
"0.0.0.0":{
|
||||||
|
"routerLinkStates":[
|
||||||
|
{
|
||||||
|
"lsId":"2.2.2.2",
|
||||||
|
"advertisedRouter":"2.2.2.2",
|
||||||
|
"numOfRouterLinks":3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"3.3.3.3",
|
||||||
|
"advertisedRouter":"3.3.3.3",
|
||||||
|
"numOfRouterLinks":7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"4.4.4.4",
|
||||||
|
"advertisedRouter":"4.4.4.4",
|
||||||
|
"numOfRouterLinks":3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"6.6.6.6",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"numOfRouterLinks":3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"summaryLinkStates":[
|
||||||
|
{
|
||||||
|
"lsId":"1.1.1.1",
|
||||||
|
"advertisedRouter":"2.2.2.2",
|
||||||
|
"summaryAddress":"1.1.1.1\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"5.5.5.5",
|
||||||
|
"advertisedRouter":"4.4.4.4",
|
||||||
|
"summaryAddress":"5.5.5.5\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"7.7.7.7",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"summaryAddress":"7.7.7.7\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.1.0",
|
||||||
|
"advertisedRouter":"2.2.2.2",
|
||||||
|
"summaryAddress":"10.0.1.0\/24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.5.0",
|
||||||
|
"advertisedRouter":"4.4.4.4",
|
||||||
|
"summaryAddress":"10.0.5.0\/24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.6.0",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"summaryAddress":"10.0.6.0\/24"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"asbrSummaryLinkStates":[
|
||||||
|
{
|
||||||
|
"lsId":"1.1.1.1",
|
||||||
|
"advertisedRouter":"2.2.2.2"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"0.0.0.3":{
|
||||||
|
"routerLinkStates":[
|
||||||
|
{
|
||||||
|
"lsId":"6.6.6.6",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"numOfRouterLinks":2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"7.7.7.7",
|
||||||
|
"advertisedRouter":"7.7.7.7",
|
||||||
|
"numOfRouterLinks":3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"summaryLinkStates":[
|
||||||
|
{
|
||||||
|
"lsId":"0.0.0.0",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"summaryAddress":"0.0.0.0\/0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"1.1.1.1",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"summaryAddress":"1.1.1.1\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"2.2.2.2",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"summaryAddress":"2.2.2.2\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"3.3.3.3",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"summaryAddress":"3.3.3.3\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"4.4.4.4",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"summaryAddress":"4.4.4.4\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"5.5.5.5",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"summaryAddress":"5.5.5.5\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"6.6.6.6",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"summaryAddress":"6.6.6.6\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.1.0",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"summaryAddress":"10.0.1.0\/24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.2.0",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"summaryAddress":"10.0.2.0\/24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.3.0",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"summaryAddress":"10.0.3.0\/24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.4.0",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"summaryAddress":"10.0.4.0\/24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.5.0",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"summaryAddress":"10.0.5.0\/24"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nssaExternalLinkStates":[
|
||||||
|
{
|
||||||
|
"lsId":"192.168.1.0",
|
||||||
|
"advertisedRouter":"7.7.7.7",
|
||||||
|
"metricType":"E2",
|
||||||
|
"route":"192.168.1.0\/24",
|
||||||
|
"tag":0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"asExternalLinkStates":[
|
||||||
|
{
|
||||||
|
"lsId":"172.16.1.0",
|
||||||
|
"advertisedRouter":"1.1.1.1",
|
||||||
|
"metricType":"E2",
|
||||||
|
"route":"172.16.1.0\/24",
|
||||||
|
"tag":0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"192.168.1.0",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"metricType":"E2",
|
||||||
|
"route":"192.168.1.0\/24",
|
||||||
|
"tag":0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
18
tests/topotests/ospf_gr_topo1/rt6/show_ip_ospf_neighbor.json
Normal file
18
tests/topotests/ospf_gr_topo1/rt6/show_ip_ospf_neighbor.json
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"neighbors":{
|
||||||
|
"3.3.3.3":[
|
||||||
|
{
|
||||||
|
"state":"Full\/DROther",
|
||||||
|
"address":"10.0.4.3",
|
||||||
|
"ifaceName":"eth-rt3:10.0.4.6"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"7.7.7.7":[
|
||||||
|
{
|
||||||
|
"state":"Full\/DROther",
|
||||||
|
"address":"10.0.6.7",
|
||||||
|
"ifaceName":"eth-rt7:10.0.6.6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
214
tests/topotests/ospf_gr_topo1/rt6/show_ip_ospf_route.json
Normal file
214
tests/topotests/ospf_gr_topo1/rt6/show_ip_ospf_route.json
Normal file
|
@ -0,0 +1,214 @@
|
||||||
|
{
|
||||||
|
"1.1.1.1\/32":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":30,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.4.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"2.2.2.2\/32":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":20,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.4.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"3.3.3.3\/32":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":10,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.4.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"4.4.4.4\/32":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":20,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.4.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"5.5.5.5\/32":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":30,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.4.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"6.6.6.6\/32":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":0,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":" ",
|
||||||
|
"directly attached to":"lo"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"7.7.7.7\/32":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":10,
|
||||||
|
"area":"0.0.0.3",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.6.7",
|
||||||
|
"via":"eth-rt7"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.1.0\/24":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":30,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.4.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.2.0\/24":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":20,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.4.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.3.0\/24":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":20,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.4.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.4.0\/24":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":10,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":" ",
|
||||||
|
"directly attached to":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.5.0\/24":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":30,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.4.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.6.0\/24":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":10,
|
||||||
|
"area":"0.0.0.3",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":" ",
|
||||||
|
"directly attached to":"eth-rt7"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"1.1.1.1":{
|
||||||
|
"routeType":"R ",
|
||||||
|
"cost":30,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"IA":true,
|
||||||
|
"routerType":"asbr",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.4.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"2.2.2.2":{
|
||||||
|
"routeType":"R ",
|
||||||
|
"cost":20,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"routerType":"abr",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.4.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"4.4.4.4":{
|
||||||
|
"routeType":"R ",
|
||||||
|
"cost":20,
|
||||||
|
"area":"0.0.0.0",
|
||||||
|
"routerType":"abr",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.4.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"7.7.7.7":{
|
||||||
|
"routeType":"R ",
|
||||||
|
"cost":10,
|
||||||
|
"area":"0.0.0.3",
|
||||||
|
"routerType":"asbr",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.6.7",
|
||||||
|
"via":"eth-rt7"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"172.16.1.0\/24":{
|
||||||
|
"routeType":"N E2",
|
||||||
|
"cost":30,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.4.3",
|
||||||
|
"via":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"192.168.1.0\/24":{
|
||||||
|
"routeType":"N E2",
|
||||||
|
"cost":10,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.6.7",
|
||||||
|
"via":"eth-rt7"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
224
tests/topotests/ospf_gr_topo1/rt6/show_ip_route.json
Normal file
224
tests/topotests/ospf_gr_topo1/rt6/show_ip_route.json
Normal file
|
@ -0,0 +1,224 @@
|
||||||
|
{
|
||||||
|
"1.1.1.1\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"1.1.1.1\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":30,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.4.3",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"2.2.2.2\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"2.2.2.2\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":20,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.4.3",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"3.3.3.3\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"3.3.3.3\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":10,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.4.3",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"4.4.4.4\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"4.4.4.4\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":20,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.4.3",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"5.5.5.5\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"5.5.5.5\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":30,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.4.3",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"6.6.6.6\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"6.6.6.6\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":0,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"directlyConnected":true,
|
||||||
|
"interfaceName":"lo"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"7.7.7.7\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"7.7.7.7\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":10,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.6.7",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt7"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.1.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.1.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":30,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.4.3",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.2.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.2.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":20,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.4.3",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.3.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.3.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":20,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.4.3",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.4.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.4.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":10,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"directlyConnected":true,
|
||||||
|
"interfaceName":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.5.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.5.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":30,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.4.3",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.6.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.6.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":10,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"directlyConnected":true,
|
||||||
|
"interfaceName":"eth-rt7"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"172.16.1.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"172.16.1.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":20,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.4.3",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt3"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"192.168.1.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"192.168.1.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":20,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.6.7",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt7"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
23
tests/topotests/ospf_gr_topo1/rt6/zebra.conf
Normal file
23
tests/topotests/ospf_gr_topo1/rt6/zebra.conf
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
password 1
|
||||||
|
hostname rt6
|
||||||
|
log file zebra.log
|
||||||
|
log commands
|
||||||
|
!
|
||||||
|
debug zebra event
|
||||||
|
debug zebra packet
|
||||||
|
debug zebra rib
|
||||||
|
debug zebra kernel
|
||||||
|
!
|
||||||
|
interface lo
|
||||||
|
ip address 6.6.6.6/32
|
||||||
|
!
|
||||||
|
interface eth-rt3
|
||||||
|
ip address 10.0.4.6/24
|
||||||
|
!
|
||||||
|
interface eth-rt7
|
||||||
|
ip address 10.0.6.6/24
|
||||||
|
!
|
||||||
|
ip forwarding
|
||||||
|
!
|
||||||
|
line vty
|
||||||
|
!
|
33
tests/topotests/ospf_gr_topo1/rt7/ospfd.conf
Normal file
33
tests/topotests/ospf_gr_topo1/rt7/ospfd.conf
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
password 1
|
||||||
|
hostname rt7
|
||||||
|
log file ospfd.log
|
||||||
|
log commands
|
||||||
|
!
|
||||||
|
debug ospf zebra
|
||||||
|
debug ospf event
|
||||||
|
debug ospf lsa
|
||||||
|
debug ospf te
|
||||||
|
debug ospf packet all
|
||||||
|
debug ospf packet ls-update detail
|
||||||
|
debug ospf ism
|
||||||
|
debug ospf nsm
|
||||||
|
debug ospf nssa
|
||||||
|
debug ospf graceful-restart
|
||||||
|
!
|
||||||
|
interface lo
|
||||||
|
ip ospf area 3
|
||||||
|
!
|
||||||
|
interface eth-rt6
|
||||||
|
ip ospf network point-to-point
|
||||||
|
ip ospf area 3
|
||||||
|
ip ospf hello-interval 3
|
||||||
|
ip ospf dead-interval 9
|
||||||
|
!
|
||||||
|
router ospf
|
||||||
|
router-id 7.7.7.7
|
||||||
|
capability opaque
|
||||||
|
redistribute connected
|
||||||
|
area 3 nssa
|
||||||
|
graceful-restart grace-period 120
|
||||||
|
graceful-restart helper-only
|
||||||
|
!
|
99
tests/topotests/ospf_gr_topo1/rt7/show_ip_ospf_database.json
Normal file
99
tests/topotests/ospf_gr_topo1/rt7/show_ip_ospf_database.json
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
{
|
||||||
|
"routerId":"7.7.7.7",
|
||||||
|
"areas":{
|
||||||
|
"0.0.0.3":{
|
||||||
|
"routerLinkStates":[
|
||||||
|
{
|
||||||
|
"lsId":"6.6.6.6",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"numOfRouterLinks":2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"7.7.7.7",
|
||||||
|
"advertisedRouter":"7.7.7.7",
|
||||||
|
"numOfRouterLinks":3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"summaryLinkStates":[
|
||||||
|
{
|
||||||
|
"lsId":"0.0.0.0",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"summaryAddress":"0.0.0.0\/0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"1.1.1.1",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"summaryAddress":"1.1.1.1\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"2.2.2.2",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"summaryAddress":"2.2.2.2\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"3.3.3.3",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"summaryAddress":"3.3.3.3\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"4.4.4.4",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"summaryAddress":"4.4.4.4\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"5.5.5.5",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"summaryAddress":"5.5.5.5\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"6.6.6.6",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"summaryAddress":"6.6.6.6\/32"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.1.0",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"summaryAddress":"10.0.1.0\/24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.2.0",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"summaryAddress":"10.0.2.0\/24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.3.0",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"summaryAddress":"10.0.3.0\/24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.4.0",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"summaryAddress":"10.0.4.0\/24"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"lsId":"10.0.5.0",
|
||||||
|
"advertisedRouter":"6.6.6.6",
|
||||||
|
"summaryAddress":"10.0.5.0\/24"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"nssaExternalLinkStates":[
|
||||||
|
{
|
||||||
|
"lsId":"192.168.1.0",
|
||||||
|
"advertisedRouter":"7.7.7.7",
|
||||||
|
"metricType":"E2",
|
||||||
|
"route":"192.168.1.0\/24",
|
||||||
|
"tag":0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"asExternalLinkStates":[
|
||||||
|
{
|
||||||
|
"lsId":"192.168.1.0",
|
||||||
|
"advertisedRouter":"7.7.7.7",
|
||||||
|
"metricType":"E2",
|
||||||
|
"route":"192.168.1.0\/24",
|
||||||
|
"tag":0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
11
tests/topotests/ospf_gr_topo1/rt7/show_ip_ospf_neighbor.json
Normal file
11
tests/topotests/ospf_gr_topo1/rt7/show_ip_ospf_neighbor.json
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"neighbors":{
|
||||||
|
"6.6.6.6":[
|
||||||
|
{
|
||||||
|
"state":"Full\/DROther",
|
||||||
|
"address":"10.0.6.6",
|
||||||
|
"ifaceName":"eth-rt6:10.0.6.7"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
168
tests/topotests/ospf_gr_topo1/rt7/show_ip_ospf_route.json
Normal file
168
tests/topotests/ospf_gr_topo1/rt7/show_ip_ospf_route.json
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
{
|
||||||
|
"0.0.0.0\/0":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":11,
|
||||||
|
"area":"0.0.0.3",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.6.6",
|
||||||
|
"via":"eth-rt6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"1.1.1.1\/32":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":40,
|
||||||
|
"area":"0.0.0.3",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.6.6",
|
||||||
|
"via":"eth-rt6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"2.2.2.2\/32":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":30,
|
||||||
|
"area":"0.0.0.3",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.6.6",
|
||||||
|
"via":"eth-rt6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"3.3.3.3\/32":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":20,
|
||||||
|
"area":"0.0.0.3",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.6.6",
|
||||||
|
"via":"eth-rt6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"4.4.4.4\/32":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":30,
|
||||||
|
"area":"0.0.0.3",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.6.6",
|
||||||
|
"via":"eth-rt6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"5.5.5.5\/32":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":40,
|
||||||
|
"area":"0.0.0.3",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.6.6",
|
||||||
|
"via":"eth-rt6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"6.6.6.6\/32":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":10,
|
||||||
|
"area":"0.0.0.3",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.6.6",
|
||||||
|
"via":"eth-rt6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"7.7.7.7\/32":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":0,
|
||||||
|
"area":"0.0.0.3",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":" ",
|
||||||
|
"directly attached to":"lo"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.1.0\/24":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":40,
|
||||||
|
"area":"0.0.0.3",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.6.6",
|
||||||
|
"via":"eth-rt6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.2.0\/24":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":30,
|
||||||
|
"area":"0.0.0.3",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.6.6",
|
||||||
|
"via":"eth-rt6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.3.0\/24":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":30,
|
||||||
|
"area":"0.0.0.3",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.6.6",
|
||||||
|
"via":"eth-rt6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.4.0\/24":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":20,
|
||||||
|
"area":"0.0.0.3",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.6.6",
|
||||||
|
"via":"eth-rt6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.5.0\/24":{
|
||||||
|
"routeType":"N IA",
|
||||||
|
"cost":40,
|
||||||
|
"area":"0.0.0.3",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.6.6",
|
||||||
|
"via":"eth-rt6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"10.0.6.0\/24":{
|
||||||
|
"routeType":"N",
|
||||||
|
"cost":10,
|
||||||
|
"area":"0.0.0.3",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":" ",
|
||||||
|
"directly attached to":"eth-rt6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"6.6.6.6":{
|
||||||
|
"routeType":"R ",
|
||||||
|
"cost":10,
|
||||||
|
"area":"0.0.0.3",
|
||||||
|
"routerType":"abr",
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.6.6",
|
||||||
|
"via":"eth-rt6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
210
tests/topotests/ospf_gr_topo1/rt7/show_ip_route.json
Normal file
210
tests/topotests/ospf_gr_topo1/rt7/show_ip_route.json
Normal file
|
@ -0,0 +1,210 @@
|
||||||
|
{
|
||||||
|
"0.0.0.0\/0":[
|
||||||
|
{
|
||||||
|
"prefix":"0.0.0.0\/0",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":11,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.6.6",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"1.1.1.1\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"1.1.1.1\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":40,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.6.6",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"2.2.2.2\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"2.2.2.2\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":30,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.6.6",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"3.3.3.3\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"3.3.3.3\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":20,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.6.6",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"4.4.4.4\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"4.4.4.4\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":30,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.6.6",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"5.5.5.5\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"5.5.5.5\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":40,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.6.6",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"6.6.6.6\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"6.6.6.6\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":10,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.6.6",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"7.7.7.7\/32":[
|
||||||
|
{
|
||||||
|
"prefix":"7.7.7.7\/32",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":0,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"directlyConnected":true,
|
||||||
|
"interfaceName":"lo"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.1.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.1.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":40,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.6.6",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.2.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.2.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":30,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.6.6",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.3.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.3.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":30,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.6.6",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.4.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.4.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":20,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.6.6",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.5.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.5.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":40,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"ip":"10.0.6.6",
|
||||||
|
"afi":"ipv4",
|
||||||
|
"interfaceName":"eth-rt6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"10.0.6.0\/24":[
|
||||||
|
{
|
||||||
|
"prefix":"10.0.6.0\/24",
|
||||||
|
"protocol":"ospf",
|
||||||
|
"distance":110,
|
||||||
|
"metric":10,
|
||||||
|
"nexthops":[
|
||||||
|
{
|
||||||
|
"directlyConnected":true,
|
||||||
|
"interfaceName":"eth-rt6"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
23
tests/topotests/ospf_gr_topo1/rt7/zebra.conf
Normal file
23
tests/topotests/ospf_gr_topo1/rt7/zebra.conf
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
password 1
|
||||||
|
hostname rt7
|
||||||
|
log file zebra.log
|
||||||
|
log commands
|
||||||
|
!
|
||||||
|
debug zebra event
|
||||||
|
debug zebra packet
|
||||||
|
debug zebra rib
|
||||||
|
debug zebra kernel
|
||||||
|
!
|
||||||
|
interface lo
|
||||||
|
ip address 7.7.7.7/32
|
||||||
|
!
|
||||||
|
interface stub1
|
||||||
|
ip address 192.168.1.1/24
|
||||||
|
!
|
||||||
|
interface eth-rt6
|
||||||
|
ip address 10.0.6.7/24
|
||||||
|
!
|
||||||
|
ip forwarding
|
||||||
|
!
|
||||||
|
line vty
|
||||||
|
!
|
393
tests/topotests/ospf_gr_topo1/test_ospf_gr_topo1.py
Executable file
393
tests/topotests/ospf_gr_topo1/test_ospf_gr_topo1.py
Executable file
|
@ -0,0 +1,393 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
#
|
||||||
|
# test_ospf_gr_topo1.py
|
||||||
|
# Part of NetDEF Topology Tests
|
||||||
|
#
|
||||||
|
# Copyright (c) 2021 by
|
||||||
|
# Network Device Education Foundation, Inc. ("NetDEF")
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and/or 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 NETDEF DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
"""
|
||||||
|
test_ospf_gr_topo1.py:
|
||||||
|
|
||||||
|
+---------+
|
||||||
|
| RT1 |
|
||||||
|
| 1.1.1.1 |
|
||||||
|
+---------+
|
||||||
|
|eth-rt2
|
||||||
|
|
|
||||||
|
|10.0.1.0/24
|
||||||
|
|
|
||||||
|
|eth-rt1
|
||||||
|
+---------+
|
||||||
|
| RT2 |
|
||||||
|
| 2.2.2.2 |
|
||||||
|
+---------+
|
||||||
|
|eth-rt3
|
||||||
|
|
|
||||||
|
|10.0.2.0/24
|
||||||
|
|
|
||||||
|
|eth-rt2
|
||||||
|
+---------+
|
||||||
|
| RT3 |
|
||||||
|
| 3.3.3.3 |
|
||||||
|
+---------+
|
||||||
|
eth-rt4| |eth-rt6
|
||||||
|
| |
|
||||||
|
10.0.3.0/24 | | 10.0.4.0/24
|
||||||
|
+---------+ +--------+
|
||||||
|
| |
|
||||||
|
|eth-rt3 |eth-rt3
|
||||||
|
+---------+ +---------+
|
||||||
|
| RT4 | | RT6 |
|
||||||
|
| 4.4.4.4 | | 6.6.6.6 |
|
||||||
|
+---------+ +---------+
|
||||||
|
|eth-rt5 |eth-rt7
|
||||||
|
| |
|
||||||
|
|10.0.5.0/24 |10.0.6.0/24
|
||||||
|
| |
|
||||||
|
|eth-rt4 |eth-rt6
|
||||||
|
+---------+ +---------+
|
||||||
|
| RT5 | | RT7 |
|
||||||
|
| 5.5.5.5 | | 7.7.7.7 |
|
||||||
|
+---------+ +---------+
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import pytest
|
||||||
|
import json
|
||||||
|
import re
|
||||||
|
import tempfile
|
||||||
|
from time import sleep
|
||||||
|
from functools import partial
|
||||||
|
|
||||||
|
# Save the Current Working Directory to find configuration files.
|
||||||
|
CWD = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
sys.path.append(os.path.join(CWD, "../"))
|
||||||
|
|
||||||
|
# pylint: disable=C0413
|
||||||
|
# Import topogen and topotest helpers
|
||||||
|
from lib import topotest
|
||||||
|
from lib.topogen import Topogen, TopoRouter, get_topogen
|
||||||
|
from lib.topolog import logger
|
||||||
|
from lib.common_config import (
|
||||||
|
kill_router_daemons,
|
||||||
|
start_router_daemons,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Required to instantiate the topology builder class.
|
||||||
|
from mininet.topo import Topo
|
||||||
|
|
||||||
|
pytestmark = [pytest.mark.ospfd]
|
||||||
|
|
||||||
|
# Global multi-dimensional dictionary containing all expected outputs
|
||||||
|
outputs = {}
|
||||||
|
|
||||||
|
|
||||||
|
class TemplateTopo(Topo):
|
||||||
|
"Test topology builder"
|
||||||
|
|
||||||
|
def build(self, *_args, **_opts):
|
||||||
|
"Build function"
|
||||||
|
tgen = get_topogen(self)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Define FRR Routers
|
||||||
|
#
|
||||||
|
for router in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6", "rt7"]:
|
||||||
|
tgen.add_router(router)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Define connections
|
||||||
|
#
|
||||||
|
switch = tgen.add_switch("s1")
|
||||||
|
switch.add_link(tgen.gears["rt1"], nodeif="eth-rt2")
|
||||||
|
switch.add_link(tgen.gears["rt2"], nodeif="eth-rt1")
|
||||||
|
|
||||||
|
switch = tgen.add_switch("s2")
|
||||||
|
switch.add_link(tgen.gears["rt1"], nodeif="stub1")
|
||||||
|
|
||||||
|
switch = tgen.add_switch("s3")
|
||||||
|
switch.add_link(tgen.gears["rt2"], nodeif="eth-rt3")
|
||||||
|
switch.add_link(tgen.gears["rt3"], nodeif="eth-rt2")
|
||||||
|
|
||||||
|
switch = tgen.add_switch("s4")
|
||||||
|
switch.add_link(tgen.gears["rt3"], nodeif="eth-rt4")
|
||||||
|
switch.add_link(tgen.gears["rt4"], nodeif="eth-rt3")
|
||||||
|
|
||||||
|
switch = tgen.add_switch("s5")
|
||||||
|
switch.add_link(tgen.gears["rt3"], nodeif="eth-rt6")
|
||||||
|
switch.add_link(tgen.gears["rt6"], nodeif="eth-rt3")
|
||||||
|
|
||||||
|
switch = tgen.add_switch("s6")
|
||||||
|
switch.add_link(tgen.gears["rt4"], nodeif="eth-rt5")
|
||||||
|
switch.add_link(tgen.gears["rt5"], nodeif="eth-rt4")
|
||||||
|
|
||||||
|
switch = tgen.add_switch("s7")
|
||||||
|
switch.add_link(tgen.gears["rt6"], nodeif="eth-rt7")
|
||||||
|
switch.add_link(tgen.gears["rt7"], nodeif="eth-rt6")
|
||||||
|
|
||||||
|
switch = tgen.add_switch("s8")
|
||||||
|
switch.add_link(tgen.gears["rt7"], nodeif="stub1")
|
||||||
|
|
||||||
|
|
||||||
|
def setup_module(mod):
|
||||||
|
"Sets up the pytest environment"
|
||||||
|
tgen = Topogen(TemplateTopo, mod.__name__)
|
||||||
|
tgen.start_topology()
|
||||||
|
|
||||||
|
router_list = tgen.routers()
|
||||||
|
|
||||||
|
# For all registered routers, load the zebra configuration file
|
||||||
|
for rname, router in router_list.items():
|
||||||
|
router.load_config(
|
||||||
|
TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
|
||||||
|
)
|
||||||
|
router.load_config(
|
||||||
|
TopoRouter.RD_OSPF, os.path.join(CWD, "{}/ospfd.conf".format(rname))
|
||||||
|
)
|
||||||
|
|
||||||
|
tgen.start_router()
|
||||||
|
|
||||||
|
|
||||||
|
def teardown_module(mod):
|
||||||
|
"Teardown the pytest environment"
|
||||||
|
tgen = get_topogen()
|
||||||
|
|
||||||
|
# This function tears down the whole topology.
|
||||||
|
tgen.stop_topology()
|
||||||
|
|
||||||
|
|
||||||
|
def router_compare_json_output(rname, command, reference, tries):
|
||||||
|
"Compare router JSON output"
|
||||||
|
|
||||||
|
logger.info('Comparing router "%s" "%s" output', rname, command)
|
||||||
|
|
||||||
|
tgen = get_topogen()
|
||||||
|
filename = "{}/{}/{}".format(CWD, rname, reference)
|
||||||
|
expected = json.loads(open(filename).read())
|
||||||
|
|
||||||
|
test_func = partial(topotest.router_json_cmp, tgen.gears[rname], command, expected)
|
||||||
|
_, diff = topotest.run_and_expect(test_func, None, count=tries, wait=0.5)
|
||||||
|
assertmsg = '"{}" JSON output mismatches the expected result'.format(rname)
|
||||||
|
assert diff is None, assertmsg
|
||||||
|
|
||||||
|
|
||||||
|
def check_routers(initial_convergence=False, exiting=None, restarting=None):
|
||||||
|
for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6", "rt7"]:
|
||||||
|
# Check the RIB first, which should be preserved across restarts in
|
||||||
|
# all routers of the routing domain.
|
||||||
|
if initial_convergence == True:
|
||||||
|
tries = 240
|
||||||
|
else:
|
||||||
|
tries = 1
|
||||||
|
router_compare_json_output(
|
||||||
|
rname, "show ip route ospf json", "show_ip_route.json", tries
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check that all adjacencies are up and running (except when there's
|
||||||
|
# an OSPF instance that is shutting down).
|
||||||
|
if exiting == None:
|
||||||
|
tries = 240
|
||||||
|
router_compare_json_output(
|
||||||
|
rname, "show ip ospf neighbor json", "show_ip_ospf_neighbor.json", tries
|
||||||
|
)
|
||||||
|
|
||||||
|
# Check the OSPF RIB and LSDB.
|
||||||
|
# In the restarting router, wait up to one minute for the LSDB to converge.
|
||||||
|
if exiting != rname:
|
||||||
|
if initial_convergence == True or restarting == rname:
|
||||||
|
tries = 240
|
||||||
|
else:
|
||||||
|
tries = 1
|
||||||
|
router_compare_json_output(
|
||||||
|
rname, "show ip ospf database json", "show_ip_ospf_database.json", tries
|
||||||
|
)
|
||||||
|
router_compare_json_output(
|
||||||
|
rname, "show ip ospf route json", "show_ip_ospf_route.json", tries
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test initial network convergence
|
||||||
|
#
|
||||||
|
def test_initial_convergence():
|
||||||
|
logger.info("Test: verify initial network convergence")
|
||||||
|
tgen = get_topogen()
|
||||||
|
|
||||||
|
# Skip if previous fatal error condition is raised
|
||||||
|
if tgen.routers_have_failure():
|
||||||
|
pytest.skip(tgen.errors)
|
||||||
|
|
||||||
|
check_routers(initial_convergence=True)
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test rt1 performing a graceful restart
|
||||||
|
#
|
||||||
|
def test_gr_rt1():
|
||||||
|
logger.info("Test: verify rt1 performing a graceful restart")
|
||||||
|
tgen = get_topogen()
|
||||||
|
|
||||||
|
# Skip if previous fatal error condition is raised
|
||||||
|
if tgen.routers_have_failure():
|
||||||
|
pytest.skip(tgen.errors)
|
||||||
|
|
||||||
|
tgen.net["rt1"].cmd('vtysh -c "graceful-restart prepare ip ospf"')
|
||||||
|
sleep(3)
|
||||||
|
kill_router_daemons(tgen, "rt1", ["ospfd"], save_config=False)
|
||||||
|
check_routers(exiting="rt1")
|
||||||
|
|
||||||
|
start_router_daemons(tgen, "rt1", ["ospfd"])
|
||||||
|
check_routers(restarting="rt1")
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test rt2 performing a graceful restart
|
||||||
|
#
|
||||||
|
def test_gr_rt2():
|
||||||
|
logger.info("Test: verify rt2 performing a graceful restart")
|
||||||
|
tgen = get_topogen()
|
||||||
|
|
||||||
|
# Skip if previous fatal error condition is raised
|
||||||
|
if tgen.routers_have_failure():
|
||||||
|
pytest.skip(tgen.errors)
|
||||||
|
|
||||||
|
tgen.net["rt2"].cmd('vtysh -c "graceful-restart prepare ip ospf"')
|
||||||
|
sleep(3)
|
||||||
|
kill_router_daemons(tgen, "rt2", ["ospfd"], save_config=False)
|
||||||
|
check_routers(exiting="rt2")
|
||||||
|
|
||||||
|
start_router_daemons(tgen, "rt2", ["ospfd"])
|
||||||
|
check_routers(restarting="rt2")
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test rt3 performing a graceful restart
|
||||||
|
#
|
||||||
|
def test_gr_rt3():
|
||||||
|
logger.info("Test: verify rt3 performing a graceful restart")
|
||||||
|
tgen = get_topogen()
|
||||||
|
|
||||||
|
# Skip if previous fatal error condition is raised
|
||||||
|
if tgen.routers_have_failure():
|
||||||
|
pytest.skip(tgen.errors)
|
||||||
|
|
||||||
|
tgen.net["rt3"].cmd('vtysh -c "graceful-restart prepare ip ospf"')
|
||||||
|
sleep(3)
|
||||||
|
kill_router_daemons(tgen, "rt3", ["ospfd"], save_config=False)
|
||||||
|
check_routers(exiting="rt3")
|
||||||
|
|
||||||
|
start_router_daemons(tgen, "rt3", ["ospfd"])
|
||||||
|
check_routers(restarting="rt3")
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test rt4 performing a graceful restart
|
||||||
|
#
|
||||||
|
def test_gr_rt4():
|
||||||
|
logger.info("Test: verify rt4 performing a graceful restart")
|
||||||
|
tgen = get_topogen()
|
||||||
|
|
||||||
|
# Skip if previous fatal error condition is raised
|
||||||
|
if tgen.routers_have_failure():
|
||||||
|
pytest.skip(tgen.errors)
|
||||||
|
|
||||||
|
tgen.net["rt4"].cmd('vtysh -c "graceful-restart prepare ip ospf"')
|
||||||
|
sleep(3)
|
||||||
|
kill_router_daemons(tgen, "rt4", ["ospfd"], save_config=False)
|
||||||
|
check_routers(exiting="rt4")
|
||||||
|
|
||||||
|
start_router_daemons(tgen, "rt4", ["ospfd"])
|
||||||
|
check_routers(restarting="rt4")
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test rt5 performing a graceful restart
|
||||||
|
#
|
||||||
|
def test_gr_rt5():
|
||||||
|
logger.info("Test: verify rt5 performing a graceful restart")
|
||||||
|
tgen = get_topogen()
|
||||||
|
|
||||||
|
# Skip if previous fatal error condition is raised
|
||||||
|
if tgen.routers_have_failure():
|
||||||
|
pytest.skip(tgen.errors)
|
||||||
|
|
||||||
|
tgen.net["rt5"].cmd('vtysh -c "graceful-restart prepare ip ospf"')
|
||||||
|
sleep(3)
|
||||||
|
kill_router_daemons(tgen, "rt5", ["ospfd"], save_config=False)
|
||||||
|
check_routers(exiting="rt5")
|
||||||
|
|
||||||
|
start_router_daemons(tgen, "rt5", ["ospfd"])
|
||||||
|
check_routers(restarting="rt5")
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test rt6 performing a graceful restart
|
||||||
|
#
|
||||||
|
def test_gr_rt6():
|
||||||
|
logger.info("Test: verify rt6 performing a graceful restart")
|
||||||
|
tgen = get_topogen()
|
||||||
|
|
||||||
|
# Skip if previous fatal error condition is raised
|
||||||
|
if tgen.routers_have_failure():
|
||||||
|
pytest.skip(tgen.errors)
|
||||||
|
|
||||||
|
tgen.net["rt6"].cmd('vtysh -c "graceful-restart prepare ip ospf"')
|
||||||
|
sleep(3)
|
||||||
|
kill_router_daemons(tgen, "rt6", ["ospfd"], save_config=False)
|
||||||
|
check_routers(exiting="rt6")
|
||||||
|
|
||||||
|
start_router_daemons(tgen, "rt6", ["ospfd"])
|
||||||
|
check_routers(restarting="rt6")
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test rt7 performing a graceful restart
|
||||||
|
#
|
||||||
|
def test_gr_rt7():
|
||||||
|
logger.info("Test: verify rt7 performing a graceful restart")
|
||||||
|
tgen = get_topogen()
|
||||||
|
|
||||||
|
# Skip if previous fatal error condition is raised
|
||||||
|
if tgen.routers_have_failure():
|
||||||
|
pytest.skip(tgen.errors)
|
||||||
|
|
||||||
|
tgen.net["rt7"].cmd('vtysh -c "graceful-restart prepare ip ospf"')
|
||||||
|
sleep(3)
|
||||||
|
kill_router_daemons(tgen, "rt7", ["ospfd"], save_config=False)
|
||||||
|
check_routers(exiting="rt7")
|
||||||
|
|
||||||
|
start_router_daemons(tgen, "rt7", ["ospfd"])
|
||||||
|
check_routers(restarting="rt7")
|
||||||
|
|
||||||
|
|
||||||
|
# Memory leak test template
|
||||||
|
def test_memory_leak():
|
||||||
|
"Run the memory leak test and report results."
|
||||||
|
tgen = get_topogen()
|
||||||
|
if not tgen.is_memleak_enabled():
|
||||||
|
pytest.skip("Memory leak test/report is disabled")
|
||||||
|
|
||||||
|
tgen.report_memory_leaks()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
args = ["-s"] + sys.argv[1:]
|
||||||
|
sys.exit(pytest.main(args))
|
Loading…
Reference in a new issue