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([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([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_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]
|
||||
|
||||
|
@ -743,6 +752,17 @@ Graceful Restart Helper
|
|||
restarts. By default, it supports both planned and
|
||||
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 Information
|
||||
|
|
|
@ -438,6 +438,8 @@ struct cmd_node {
|
|||
#define BFD_PROFILE_STR "BFD profile.\n"
|
||||
#define BFD_PROFILE_NAME_STR "BFD profile name.\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 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 */
|
||||
{
|
||||
if (ospf->gr_info.restart_in_progress)
|
||||
return;
|
||||
|
||||
if (IS_DEBUG_OSPF_NSSA)
|
||||
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. */
|
||||
void ospf_abr_task(struct ospf *ospf)
|
||||
{
|
||||
if (ospf->gr_info.restart_in_progress)
|
||||
return;
|
||||
|
||||
if (IS_DEBUG_OSPF_EVENT)
|
||||
zlog_debug("ospf_abr_task(): Start");
|
||||
|
||||
|
|
|
@ -609,6 +609,16 @@ static int ospf_ase_calculate_timer(struct thread *t)
|
|||
+ (stop_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;
|
||||
}
|
||||
|
||||
|
|
|
@ -1552,21 +1552,16 @@ DEFUN(no_debug_ospf_ldp_sync,
|
|||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFPY (debug_ospf_gr,
|
||||
debug_ospf_gr_cmd,
|
||||
"[no$no] debug ospf graceful-restart helper",
|
||||
NO_STR
|
||||
DEBUG_STR OSPF_STR
|
||||
"Gracefull restart\n"
|
||||
"Helper Information\n")
|
||||
DEFPY(debug_ospf_gr, debug_ospf_gr_cmd, "[no$no] debug ospf graceful-restart",
|
||||
NO_STR DEBUG_STR OSPF_STR "OSPF Graceful Restart\n")
|
||||
{
|
||||
if (vty->node == CONFIG_NODE)
|
||||
CONF_DEBUG_ON(gr, GR_HELPER);
|
||||
CONF_DEBUG_ON(gr, GR);
|
||||
|
||||
if (!no)
|
||||
TERM_DEBUG_ON(gr, GR_HELPER);
|
||||
TERM_DEBUG_ON(gr, GR);
|
||||
else
|
||||
TERM_DEBUG_OFF(gr, GR_HELPER);
|
||||
TERM_DEBUG_OFF(gr, GR);
|
||||
|
||||
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)
|
||||
vty_out(vty, " OSPF ldp-sync debugging is on\n");
|
||||
|
||||
/* Show debug status for GR helper. */
|
||||
if (IS_DEBUG_OSPF(gr, GR_HELPER) == OSPF_DEBUG_GR_HELPER)
|
||||
vty_out(vty, " OSPF Graceful Restart Helper debugging is on\n");
|
||||
/* Show debug status for GR. */
|
||||
if (IS_DEBUG_OSPF(gr, GR) == OSPF_DEBUG_GR)
|
||||
vty_out(vty, " OSPF Graceful Restart debugging is on\n");
|
||||
|
||||
if (IS_DEBUG_OSPF(bfd, BFD_LIB) == OSPF_DEBUG_BFD_LIB)
|
||||
vty_out(vty,
|
||||
|
@ -1953,9 +1948,9 @@ static int config_write_debug(struct vty *vty)
|
|||
write = 1;
|
||||
}
|
||||
|
||||
/* debug ospf gr helper */
|
||||
if (IS_CONF_DEBUG_OSPF(gr, GR_HELPER) == OSPF_DEBUG_GR_HELPER) {
|
||||
vty_out(vty, "debug ospf%s graceful-restart helper\n", str);
|
||||
/* debug ospf gr */
|
||||
if (IS_CONF_DEBUG_OSPF(gr, GR) == OSPF_DEBUG_GR) {
|
||||
vty_out(vty, "debug ospf%s graceful-restart\n", str);
|
||||
write = 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -64,8 +64,7 @@
|
|||
#define OSPF_DEBUG_DEFAULTINFO 0x20
|
||||
#define OSPF_DEBUG_LDP_SYNC 0x40
|
||||
|
||||
#define OSPF_DEBUG_GR_HELPER 0x01
|
||||
#define OSPF_DEBUG_GR 0x03
|
||||
#define OSPF_DEBUG_GR 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_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) \
|
||||
(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);
|
||||
(void)ospf_lsa_is_self_originated(ospf, new); /* Let it set the flag */
|
||||
|
||||
/* Received Grace LSA */
|
||||
if (IS_GRACE_LSA(new)) {
|
||||
/* Received non-self-originated Grace LSA */
|
||||
if (IS_GRACE_LSA(new) && !IS_LSA_SELF(new)) {
|
||||
|
||||
if (IS_LSA_MAXAGE(new)) {
|
||||
|
||||
/* Handling Max age grace LSA.*/
|
||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
||||
if (IS_DEBUG_OSPF_GR)
|
||||
zlog_debug(
|
||||
"%s, Received a maxage GRACE-LSA from router %pI4",
|
||||
__func__, &new->data->adv_router);
|
||||
|
@ -393,21 +393,21 @@ int ospf_flood(struct ospf *ospf, struct ospf_neighbor *nbr,
|
|||
if (current) {
|
||||
ospf_process_maxage_grace_lsa(ospf, new, nbr);
|
||||
} else {
|
||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
||||
if (IS_DEBUG_OSPF_GR)
|
||||
zlog_debug(
|
||||
"%s, Grace LSA doesn't exist in lsdb, so discarding grace lsa",
|
||||
__func__);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
||||
if (IS_DEBUG_OSPF_GR)
|
||||
zlog_debug(
|
||||
"%s, Received a GRACE-LSA from router %pI4",
|
||||
__func__, &new->data->adv_router);
|
||||
|
||||
if (ospf_process_grace_lsa(ospf, new, nbr)
|
||||
== OSPF_GR_NOT_HELPER) {
|
||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
||||
if (IS_DEBUG_OSPF_GR)
|
||||
zlog_debug(
|
||||
"%s, Not moving to HELPER role, So discarding grace LSA",
|
||||
__func__);
|
||||
|
@ -445,9 +445,9 @@ int ospf_flood(struct ospf *ospf, struct ospf_neighbor *nbr,
|
|||
}
|
||||
|
||||
/* OSPF LSA flooding -- RFC2328 Section 13.3. */
|
||||
static int ospf_flood_through_interface(struct ospf_interface *oi,
|
||||
struct ospf_neighbor *inbr,
|
||||
struct ospf_lsa *lsa)
|
||||
int ospf_flood_through_interface(struct ospf_interface *oi,
|
||||
struct ospf_neighbor *inbr,
|
||||
struct ospf_lsa *lsa)
|
||||
{
|
||||
struct ospf_neighbor *onbr;
|
||||
struct route_node *rn;
|
||||
|
@ -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. */
|
||||
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
|
||||
more time for the ACK to be received and avoid
|
||||
retransmissions */
|
||||
lsa->data->ls_age = htons(OSPF_LSA_MAXAGE);
|
||||
if (IS_DEBUG_OSPF_EVENT)
|
||||
zlog_debug("%s: MAXAGE set to LSA %pI4", __func__,
|
||||
&lsa->data->id);
|
||||
zlog_debug("%s: MaxAge set to LSA[%s]", __func__,
|
||||
dump_lsa_key(lsa));
|
||||
monotime(&lsa->tv_recv);
|
||||
lsa->tv_orig = lsa->tv_recv;
|
||||
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)
|
||||
{
|
||||
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
|
||||
more time for the ACK to be received and avoid
|
||||
retransmissions */
|
||||
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);
|
||||
lsa->tv_orig = lsa->tv_recv;
|
||||
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 *);
|
||||
extern int ospf_flood_through_as(struct ospf *, struct ospf_neighbor *,
|
||||
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 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
|
||||
*/
|
||||
|
||||
#ifndef _ZEBRA_OSPF_GR_HELPER_H
|
||||
#define _ZEBRA_OSPF_GR_HELPER_H
|
||||
#ifndef _ZEBRA_OSPF_GR_H
|
||||
#define _ZEBRA_OSPF_GR_H
|
||||
|
||||
#define OSPF_GR_NOT_HELPER 0
|
||||
#define OSPF_GR_ACTIVE_HELPER 1
|
||||
|
@ -32,6 +32,7 @@
|
|||
|
||||
#define OSPF_MAX_GRACE_INTERVAL 1800
|
||||
#define OSPF_MIN_GRACE_INTERVAL 1
|
||||
#define OSPF_DFLT_GRACE_INTERVAL 120
|
||||
|
||||
enum ospf_helper_exit_reason {
|
||||
OSPF_GR_HELPER_EXIT_NONE = 0,
|
||||
|
@ -55,7 +56,8 @@ enum ospf_gr_helper_rejected_reason {
|
|||
OSPF_HELPER_NOT_A_VALID_NEIGHBOUR,
|
||||
OSPF_HELPER_PLANNED_ONLY_RESTART,
|
||||
OSPF_HELPER_TOPO_CHANGE_RTXMT_LIST,
|
||||
OSPF_HELPER_LSA_AGE_MORE
|
||||
OSPF_HELPER_LSA_AGE_MORE,
|
||||
OSPF_HELPER_RESTARTING,
|
||||
};
|
||||
|
||||
/* Ref RFC3623 appendex-A */
|
||||
|
@ -101,7 +103,8 @@ struct ospf_helper_info {
|
|||
|
||||
/* Grace timer,This Router acts as
|
||||
* helper until this timer until
|
||||
* this timer expires*/
|
||||
* this timer expires.
|
||||
*/
|
||||
struct thread *t_grace_timer;
|
||||
|
||||
/* Helper status */
|
||||
|
@ -178,4 +181,11 @@ extern void ospf_gr_helper_supported_gracetime_set(struct ospf *ospf,
|
|||
uint32_t interval);
|
||||
extern void ospf_gr_helper_set_supported_planned_only_restart(struct ospf *ospf,
|
||||
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_nsm.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[] = {
|
||||
"Unknown reason",
|
||||
|
@ -72,6 +72,7 @@ static const char * const ospf_rejected_reason_desc[] = {
|
|||
"Supports only planned restart but received unplanned",
|
||||
"Topo change due to change in lsa rxmt list",
|
||||
"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);
|
||||
|
@ -161,7 +162,7 @@ const char *ospf_rejected_reason2str(unsigned int reason)
|
|||
*/
|
||||
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__);
|
||||
|
||||
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)
|
||||
{
|
||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
||||
if (IS_DEBUG_OSPF_GR)
|
||||
zlog_debug("%s, GR helper deinit.", __func__);
|
||||
|
||||
ospf_enable_rtr_hash_destroy(ospf);
|
||||
|
@ -203,7 +204,7 @@ void ospf_gr_helper_init(void)
|
|||
{
|
||||
int rc;
|
||||
|
||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
||||
if (IS_DEBUG_OSPF_GR)
|
||||
zlog_debug("%s, GR Helper init.", __func__);
|
||||
|
||||
rc = ospf_register_opaque_functab(
|
||||
|
@ -225,8 +226,7 @@ void ospf_gr_helper_init(void)
|
|||
*/
|
||||
void ospf_gr_helper_stop(void)
|
||||
{
|
||||
|
||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
||||
if (IS_DEBUG_OSPF_GR)
|
||||
zlog_debug("%s, GR helper deinit.", __func__);
|
||||
|
||||
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 */
|
||||
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",
|
||||
__func__, length);
|
||||
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 */
|
||||
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",
|
||||
__func__, TLV_SIZE(tlvh));
|
||||
return OSPF_GR_FAILURE;
|
||||
|
@ -324,7 +324,7 @@ static int ospf_extract_grace_lsa_fields(struct ospf_lsa *lsa,
|
|||
sum += TLV_SIZE(tlvh);
|
||||
break;
|
||||
default:
|
||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
||||
if (IS_DEBUG_OSPF_GR)
|
||||
zlog_debug(
|
||||
"%s, Malformed packet.Invalid TLV type:%d",
|
||||
__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,
|
||||
&restart_reason);
|
||||
if (ret != OSPF_GR_SUCCESS) {
|
||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
||||
if (IS_DEBUG_OSPF_GR)
|
||||
zlog_debug("%s, Wrong Grace LSA packet.", __func__);
|
||||
return OSPF_GR_NOT_HELPER;
|
||||
}
|
||||
|
||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
||||
if (IS_DEBUG_OSPF_GR)
|
||||
zlog_debug(
|
||||
"%s, Grace LSA received from %pI4, grace interval:%u, restart reason:%s",
|
||||
__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);
|
||||
|
||||
if (!restarter) {
|
||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
||||
if (IS_DEBUG_OSPF_GR)
|
||||
zlog_debug(
|
||||
"%s, Restarter is not a nbr(%pI4) for this router.",
|
||||
__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;
|
||||
|
||||
if (!hash_lookup(ospf->enable_rtr_list, &lookup)) {
|
||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
||||
if (IS_DEBUG_OSPF_GR)
|
||||
zlog_debug(
|
||||
"%s, HELPER support is disabled, So not a HELPER",
|
||||
__func__);
|
||||
|
@ -442,7 +442,7 @@ int ospf_process_grace_lsa(struct ospf *ospf, struct ospf_lsa *lsa,
|
|||
* became a adjacency.
|
||||
*/
|
||||
if (!IS_NBR_STATE_FULL(restarter)) {
|
||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
||||
if (IS_DEBUG_OSPF_GR)
|
||||
zlog_debug(
|
||||
"%s, This Neighbour %pI4 is not in FULL state.",
|
||||
__func__, &restarter->src);
|
||||
|
@ -456,7 +456,7 @@ int ospf_process_grace_lsa(struct ospf *ospf, struct ospf_lsa *lsa,
|
|||
*/
|
||||
if (ospf->only_planned_restart
|
||||
&& !OSPF_GR_IS_PLANNED_RESTART(restart_reason)) {
|
||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
||||
if (IS_DEBUG_OSPF_GR)
|
||||
zlog_debug(
|
||||
"%s, Router supports only planned restarts but received the GRACE LSA for an unplanned restart.",
|
||||
__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)
|
||||
&& ospf_check_change_in_rxmt_list(restarter)) {
|
||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
||||
if (IS_DEBUG_OSPF_GR)
|
||||
zlog_debug(
|
||||
"%s, Changed LSA in Rxmt list. So not Helper.",
|
||||
__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 */
|
||||
if (ntohs(lsa->data->ls_age) >= grace_interval) {
|
||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
||||
if (IS_DEBUG_OSPF_GR)
|
||||
zlog_debug(
|
||||
"%s, Grace LSA age(%d) is more than the grace interval(%d)",
|
||||
__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;
|
||||
}
|
||||
|
||||
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
|
||||
* if configured, use this to start the grace
|
||||
* 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;
|
||||
if (grace_interval > ospf->supported_grace_time) {
|
||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
||||
if (IS_DEBUG_OSPF_GR)
|
||||
zlog_debug(
|
||||
"%s, Received grace period %d is larger than supported grace %d",
|
||||
__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)
|
||||
ospf->active_restarter_cnt--;
|
||||
|
||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
||||
if (IS_DEBUG_OSPF_GR)
|
||||
zlog_debug(
|
||||
"%s, Router is already acting as a HELPER for this nbr,so restart the grace timer",
|
||||
__func__);
|
||||
} else {
|
||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
||||
if (IS_DEBUG_OSPF_GR)
|
||||
zlog_debug(
|
||||
"%s, This Router becomes a HELPER for the neighbour %pI4",
|
||||
__func__, &restarter->src);
|
||||
|
@ -535,7 +545,7 @@ int ospf_process_grace_lsa(struct ospf *ospf, struct ospf_lsa *lsa,
|
|||
/* Increment the active restarter count */
|
||||
ospf->active_restarter_cnt++;
|
||||
|
||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
||||
if (IS_DEBUG_OSPF_GR)
|
||||
zlog_debug("%s, Grace timer started.interval:%d", __func__,
|
||||
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)
|
||||
return;
|
||||
|
||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
||||
zlog_debug(
|
||||
"%s, Topo change detected due to lsa LSID:%pI4 type:%d",
|
||||
__func__, &lsa->data->id, lsa->data->type);
|
||||
if (IS_DEBUG_OSPF_GR)
|
||||
zlog_debug("%s: Topo change detected due to LSA[%s]", __func__,
|
||||
dump_lsa_key(lsa));
|
||||
|
||||
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))
|
||||
return;
|
||||
|
||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
||||
if (IS_DEBUG_OSPF_GR)
|
||||
zlog_debug("%s, Exiting from HELPER support to %pI4, due to %s",
|
||||
__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 (reason != OSPF_GR_HELPER_COMPLETED) {
|
||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
||||
if (IS_DEBUG_OSPF_GR)
|
||||
zlog_debug(
|
||||
"%s, Failed GR exit, so bringing down the neighbour",
|
||||
__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,
|
||||
&restartReason);
|
||||
if (ret != OSPF_GR_SUCCESS) {
|
||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
||||
if (IS_DEBUG_OSPF_GR)
|
||||
zlog_debug("%s, Wrong Grace LSA packet.", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
||||
if (IS_DEBUG_OSPF_GR)
|
||||
zlog_debug("%s, GraceLSA received for neighbour %pI4", __func__,
|
||||
&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);
|
||||
|
||||
if (!restarter) {
|
||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
||||
if (IS_DEBUG_OSPF_GR)
|
||||
zlog_debug(
|
||||
"%s, Restarter is not a neighbour for this router.",
|
||||
__func__);
|
||||
|
|
|
@ -819,6 +819,14 @@ static struct ospf_lsa *ospf_router_lsa_originate(struct ospf_area *area)
|
|||
{
|
||||
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. */
|
||||
if ((new = ospf_router_lsa_new(area)) == NULL) {
|
||||
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;
|
||||
|
||||
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) {
|
||||
ospf_lsa_refresh(oi->ospf, oi->network_lsa_self);
|
||||
return;
|
||||
|
@ -1212,6 +1228,14 @@ struct ospf_lsa *ospf_summary_lsa_originate(struct prefix_ipv4 *p,
|
|||
struct ospf_lsa *new;
|
||||
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);
|
||||
|
||||
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 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,
|
||||
p);
|
||||
|
||||
|
@ -1799,6 +1831,13 @@ struct ospf_lsa *ospf_translated_nssa_originate(struct ospf *ospf,
|
|||
struct ospf_lsa *new;
|
||||
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
|
||||
* 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;
|
||||
|
||||
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....
|
||||
|
||||
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_DEBUG_OSPF(lsa, LSA_INSTALL))
|
||||
zlog_debug("LSA[Type%d:%pI4]: Install LSA %p, MaxAge",
|
||||
new->data->type, &new->data->id, lsa);
|
||||
zlog_debug("LSA[%s]: Install LSA %p, MaxAge",
|
||||
dump_lsa_key(new), 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))
|
||||
zlog_debug(
|
||||
"LSA[Type%d:%pI4]: MaxAge LSA removed from list",
|
||||
lsa->data->type,
|
||||
&lsa->data->id);
|
||||
"LSA[%s]: MaxAge LSA removed from list",
|
||||
dump_lsa_key(lsa));
|
||||
|
||||
if (CHECK_FLAG(lsa->flags, OSPF_LSA_PREMATURE_AGE)) {
|
||||
if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
|
||||
|
@ -2882,9 +2927,8 @@ static int ospf_maxage_lsa_remover(struct thread *thread)
|
|||
*/
|
||||
if (old != lsa) {
|
||||
flog_err(EC_OSPF_LSA_MISSING,
|
||||
"%s: LSA[Type%d:%pI4]: LSA not in LSDB",
|
||||
__func__, lsa->data->type,
|
||||
&lsa->data->id);
|
||||
"%s: LSA[%s]: LSA not in LSDB",
|
||||
__func__, dump_lsa_key(lsa));
|
||||
|
||||
continue;
|
||||
}
|
||||
|
@ -2893,9 +2937,8 @@ static int ospf_maxage_lsa_remover(struct thread *thread)
|
|||
} else {
|
||||
if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
|
||||
zlog_debug(
|
||||
"%s: LSA[Type%d:%pI4]: No associated LSDB!",
|
||||
__func__, lsa->data->type,
|
||||
&lsa->data->id);
|
||||
"%s: LSA[%s]: No associated LSDB!",
|
||||
__func__, dump_lsa_key(lsa));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
|
||||
zlog_debug(
|
||||
"LSA[Type%d:%pI4]: %p already exists on MaxAge LSA list",
|
||||
lsa->data->type, &lsa->data->id,
|
||||
(void *)lsa);
|
||||
"LSA[%s]: %p already exists on MaxAge LSA list",
|
||||
dump_lsa_key(lsa), lsa);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include "ospfd/ospf_zebra.h"
|
||||
#include "ospfd/ospf_vty.h"
|
||||
#include "ospfd/ospf_bfd.h"
|
||||
#include "ospfd/ospf_gr.h"
|
||||
#include "ospfd/ospf_errors.h"
|
||||
#include "ospfd/ospf_ldp_sync.h"
|
||||
#include "ospfd/ospf_routemap_nb.h"
|
||||
|
@ -225,6 +226,7 @@ int main(int argc, char **argv)
|
|||
|
||||
ospf_route_map_init();
|
||||
ospf_opaque_init();
|
||||
ospf_gr_init();
|
||||
ospf_gr_helper_init();
|
||||
|
||||
/* OSPF errors init */
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
#include "ospfd/ospf_flood.h"
|
||||
#include "ospfd/ospf_dump.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
|
||||
* from the ospf_interface's nbrs table. Indexed by interface address
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#ifndef _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>
|
||||
|
||||
/* Neighbor Data Structure */
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "ospfd/ospf_flood.h"
|
||||
#include "ospfd/ospf_abr.h"
|
||||
#include "ospfd/ospf_bfd.h"
|
||||
#include "ospfd/ospf_gr.h"
|
||||
#include "ospfd/ospf_errors.h"
|
||||
|
||||
DEFINE_HOOK(ospf_nsm_change,
|
||||
|
@ -75,7 +76,7 @@ static int ospf_inactivity_timer(struct thread *thread)
|
|||
*/
|
||||
if (!OSPF_GR_IS_ACTIVE_HELPER(nbr))
|
||||
OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_InactivityTimer);
|
||||
else if (IS_DEBUG_OSPF_GR_HELPER)
|
||||
else if (IS_DEBUG_OSPF_GR)
|
||||
zlog_debug(
|
||||
"%s, Acting as HELPER for this neighbour, So inactivitytimer event will not be fired.",
|
||||
__func__);
|
||||
|
@ -727,6 +728,9 @@ static void nsm_change_state(struct ospf_neighbor *nbr, int state)
|
|||
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);
|
||||
|
|
|
@ -2147,6 +2147,11 @@ void ospf_opaque_self_originated_lsa_received(struct ospf_neighbor *nbr,
|
|||
if ((top = oi_to_top(nbr->oi)) == NULL)
|
||||
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
|
||||
* LSDB, just flush them without calling ospf_ls_maxage() afterward.
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
#include "ospfd/ospf_dump.h"
|
||||
#include "ospfd/ospf_errors.h"
|
||||
#include "ospfd/ospf_zebra.h"
|
||||
#include "ospfd/ospf_gr_helper.h"
|
||||
#include "ospfd/ospf_gr.h"
|
||||
|
||||
/*
|
||||
* OSPF Fragmentation / fragmented writes
|
||||
|
@ -2025,9 +2025,11 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph,
|
|||
|
||||
ospf_ls_ack_send(nbr, lsa);
|
||||
|
||||
ospf_opaque_self_originated_lsa_received(nbr,
|
||||
lsa);
|
||||
continue;
|
||||
if (!ospf->gr_info.restart_in_progress) {
|
||||
ospf_opaque_self_originated_lsa_received(
|
||||
nbr, lsa);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2213,6 +2215,9 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph,
|
|||
|
||||
assert(listcount(lsas) == 0);
|
||||
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. */
|
||||
|
@ -3575,14 +3580,13 @@ static int ospf_make_ls_upd(struct ospf_interface *oi, struct list *update,
|
|||
struct lsa_header *lsah;
|
||||
uint16_t ls_age;
|
||||
|
||||
if (IS_DEBUG_OSPF_EVENT)
|
||||
zlog_debug("ospf_make_ls_upd: List Iteration %d",
|
||||
count);
|
||||
|
||||
lsa = listgetdata(node);
|
||||
|
||||
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 */
|
||||
if ((length + delta + ntohs(lsa->data->length) > size_noauth) &&
|
||||
(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;
|
||||
|
||||
if (IS_GRACE_LSA(lsa)) {
|
||||
if (IS_DEBUG_OSPF_GR_HELPER)
|
||||
if (IS_DEBUG_OSPF_GR)
|
||||
zlog_debug("%s, Sending GRACE ACK to Restarter.",
|
||||
__func__);
|
||||
}
|
||||
|
|
|
@ -1903,6 +1903,8 @@ static int ospf_spf_calculate_schedule_worker(struct thread *thread)
|
|||
strlcat(rbuf, "ASBR, ", sizeof(rbuf));
|
||||
if (spf_reason_flags & (1 << SPF_FLAG_MAXAGE))
|
||||
strlcat(rbuf, "M, ", sizeof(rbuf));
|
||||
if (spf_reason_flags & (1 << SPF_FLAG_GR_FINISH))
|
||||
strlcat(rbuf, "GR, ", sizeof(rbuf));
|
||||
|
||||
size_t rbuflen = strlen(rbuf);
|
||||
if (rbuflen >= 2)
|
||||
|
|
|
@ -69,6 +69,7 @@ typedef enum {
|
|||
SPF_FLAG_ABR_STATUS_CHANGE,
|
||||
SPF_FLAG_ASBR_STATUS_CHANGE,
|
||||
SPF_FLAG_CONFIG_CHANGE,
|
||||
SPF_FLAG_GR_FINISH,
|
||||
} 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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (ospf->is_helper_supported)
|
||||
|
@ -12464,7 +12476,8 @@ static int ospf_config_write_one(struct vty *vty, struct ospf *ospf)
|
|||
/* Redistribute information print. */
|
||||
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);
|
||||
|
||||
/* Print external route aggregation. */
|
||||
|
|
|
@ -264,6 +264,14 @@ void ospf_zebra_add(struct ospf *ospf, struct prefix_ipv4 *p,
|
|||
struct ospf_path *path;
|
||||
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));
|
||||
api.vrf_id = ospf->vrf_id;
|
||||
api.type = ZEBRA_ROUTE_OSPF;
|
||||
|
@ -323,6 +331,14 @@ void ospf_zebra_delete(struct ospf *ospf, struct prefix_ipv4 *p,
|
|||
{
|
||||
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));
|
||||
api.vrf_id = ospf->vrf_id;
|
||||
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;
|
||||
|
||||
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));
|
||||
api.vrf_id = ospf->vrf_id;
|
||||
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;
|
||||
|
||||
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));
|
||||
api.vrf_id = ospf->vrf_id;
|
||||
api.type = ZEBRA_ROUTE_OSPF;
|
||||
|
@ -1180,6 +1212,36 @@ void ospf_routemap_unset(struct ospf_redist *red)
|
|||
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. */
|
||||
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 void ospf_routemap_set(struct ospf_redist *, const char *);
|
||||
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 *,
|
||||
const char *, 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_ase.h"
|
||||
#include "ospfd/ospf_ldp_sync.h"
|
||||
#include "ospfd/ospf_gr_helper.h"
|
||||
#include "ospfd/ospf_gr.h"
|
||||
|
||||
|
||||
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);
|
||||
|
||||
/*
|
||||
* Read from non-volatile memory whether this instance is performing a
|
||||
* graceful restart or not.
|
||||
*/
|
||||
ospf_gr_nvm_read(new);
|
||||
|
||||
return new;
|
||||
}
|
||||
|
||||
|
@ -708,7 +714,8 @@ static void ospf_finish_final(struct ospf *ospf)
|
|||
|
||||
ospf_opaque_finish();
|
||||
|
||||
ospf_flush_self_originated_lsas_now(ospf);
|
||||
if (!ospf->gr_info.prepare_in_progress)
|
||||
ospf_flush_self_originated_lsas_now(ospf);
|
||||
|
||||
/* Unregister redistribution */
|
||||
for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
|
||||
|
@ -805,6 +812,7 @@ static void ospf_finish_final(struct ospf *ospf)
|
|||
OSPF_TIMER_OFF(ospf->t_sr_update);
|
||||
OSPF_TIMER_OFF(ospf->t_default_routemap_timer);
|
||||
OSPF_TIMER_OFF(ospf->t_external_aggr);
|
||||
OSPF_TIMER_OFF(ospf->gr_info.t_grace_period);
|
||||
|
||||
LSDB_LOOP (OPAQUE_AS_LSDB(ospf), rn, lsa)
|
||||
ospf_discard_from_db(ospf, ospf->lsdb, lsa);
|
||||
|
@ -826,7 +834,8 @@ static void ospf_finish_final(struct ospf *ospf)
|
|||
if (ospf->old_table)
|
||||
ospf_route_table_free(ospf->old_table);
|
||||
if (ospf->new_table) {
|
||||
ospf_route_delete(ospf, ospf->new_table);
|
||||
if (!ospf->gr_info.prepare_in_progress)
|
||||
ospf_route_delete(ospf, ospf->new_table);
|
||||
ospf_route_table_free(ospf->new_table);
|
||||
}
|
||||
if (ospf->old_rtrs)
|
||||
|
@ -834,11 +843,13 @@ static void ospf_finish_final(struct ospf *ospf)
|
|||
if (ospf->new_rtrs)
|
||||
ospf_rtrs_free(ospf->new_rtrs);
|
||||
if (ospf->new_external_route) {
|
||||
ospf_route_delete(ospf, ospf->new_external_route);
|
||||
if (!ospf->gr_info.prepare_in_progress)
|
||||
ospf_route_delete(ospf, ospf->new_external_route);
|
||||
ospf_route_table_free(ospf->new_external_route);
|
||||
}
|
||||
if (ospf->old_external_route) {
|
||||
ospf_route_delete(ospf, ospf->old_external_route);
|
||||
if (!ospf->gr_info.prepare_in_progress)
|
||||
ospf_route_delete(ospf, ospf->old_external_route);
|
||||
ospf_route_table_free(ospf->old_external_route);
|
||||
}
|
||||
if (ospf->external_lsas) {
|
||||
|
|
|
@ -134,6 +134,16 @@ enum protection_type {
|
|||
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. */
|
||||
struct ospf {
|
||||
/* OSPF's running state based on the '[no] router ospf [<instance>]'
|
||||
|
@ -384,6 +394,9 @@ struct ospf {
|
|||
/* MPLS LDP-IGP Sync */
|
||||
struct ldp_sync_info_cmd ldp_sync_cmd;
|
||||
|
||||
/* OSPF Graceful Restart info */
|
||||
struct ospf_gr_info gr_info;
|
||||
|
||||
/* TI-LFA support for all interfaces. */
|
||||
bool ti_lfa_enabled;
|
||||
enum protection_type ti_lfa_protection_type;
|
||||
|
|
|
@ -8,6 +8,7 @@ sbin_PROGRAMS += ospfd/ospfd
|
|||
vtysh_scan += \
|
||||
ospfd/ospf_bfd.c \
|
||||
ospfd/ospf_dump.c \
|
||||
ospfd/ospf_gr.c \
|
||||
ospfd/ospf_ldp_sync.c \
|
||||
ospfd/ospf_opaque.c \
|
||||
ospfd/ospf_ri.c \
|
||||
|
@ -35,6 +36,7 @@ ospfd_libfrrospf_a_SOURCES = \
|
|||
ospfd/ospf_errors.c \
|
||||
ospfd/ospf_ext.c \
|
||||
ospfd/ospf_flood.c \
|
||||
ospfd/ospf_gr.c \
|
||||
ospfd/ospf_ia.c \
|
||||
ospfd/ospf_interface.c \
|
||||
ospfd/ospf_ism.c \
|
||||
|
@ -82,6 +84,7 @@ clippy_scan += \
|
|||
ospfd/ospf_vty.c \
|
||||
ospfd/ospf_ldp_sync.c \
|
||||
ospfd/ospf_dump.c \
|
||||
ospfd/ospf_gr.c \
|
||||
# end
|
||||
|
||||
noinst_HEADERS += \
|
||||
|
@ -100,6 +103,7 @@ noinst_HEADERS += \
|
|||
ospfd/ospf_network.h \
|
||||
ospfd/ospf_packet.h \
|
||||
ospfd/ospf_ri.h \
|
||||
ospfd/ospf_gr.h \
|
||||
ospfd/ospf_route.h \
|
||||
ospfd/ospf_routemap_nb.h \
|
||||
ospfd/ospf_spf.h \
|
||||
|
@ -108,7 +112,6 @@ noinst_HEADERS += \
|
|||
ospfd/ospf_te.h \
|
||||
ospfd/ospf_vty.h \
|
||||
ospfd/ospf_zebra.h \
|
||||
ospfd/ospf_gr_helper.h \
|
||||
# end
|
||||
|
||||
ospfd_ospfd_LDADD = ospfd/libfrrospf.a lib/libfrr.la $(LIBCAP) $(LIBM)
|
||||
|
|
|
@ -365,7 +365,7 @@ def create_common_configuration(
|
|||
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
|
||||
and daemon would be killed forcefully using SIGKILL.
|
||||
|
@ -379,9 +379,10 @@ def kill_router_daemons(tgen, router, daemons):
|
|||
try:
|
||||
router_list = tgen.routers()
|
||||
|
||||
# Saving router config to /etc/frr, which will be loaded to router
|
||||
# when it starts
|
||||
router_list[router].vtysh_cmd("write memory")
|
||||
if save_config:
|
||||
# Saving router config to /etc/frr, which will be loaded to router
|
||||
# when it starts
|
||||
router_list[router].vtysh_cmd("write memory")
|
||||
|
||||
# Kill Daemons
|
||||
result = router_list[router].killDaemons(daemons)
|
||||
|
|
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