summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ospfd/ospf_apiserver.c6
-rw-r--r--ospfd/ospf_apiserver.h3
-rw-r--r--ospfd/ospf_ext.c18
-rw-r--r--ospfd/ospf_gr_helper.c9
-rw-r--r--ospfd/ospf_opaque.c18
-rw-r--r--ospfd/ospf_opaque.h3
-rw-r--r--ospfd/ospf_ri.c11
-rw-r--r--ospfd/ospf_te.c9
-rwxr-xr-xtests/topotests/ospf6_gr_topo1/test_ospf6_gr_topo1.py95
-rwxr-xr-xtests/topotests/ospf_gr_topo1/test_ospf_gr_topo1.py94
-rw-r--r--zebra/zserv.c20
11 files changed, 235 insertions, 51 deletions
diff --git a/ospfd/ospf_apiserver.c b/ospfd/ospf_apiserver.c
index cbd03441ef..a33ca95777 100644
--- a/ospfd/ospf_apiserver.c
+++ b/ospfd/ospf_apiserver.c
@@ -2059,7 +2059,8 @@ void ospf_apiserver_nsm_change(struct ospf_neighbor *nbr, int old_status)
}
}
-void ospf_apiserver_show_info(struct vty *vty, struct ospf_lsa *lsa)
+void ospf_apiserver_show_info(struct vty *vty, struct json_object *json,
+ struct ospf_lsa *lsa)
{
struct opaque_lsa {
struct lsa_header header;
@@ -2070,6 +2071,9 @@ void ospf_apiserver_show_info(struct vty *vty, struct ospf_lsa *lsa)
struct opaque_lsa *olsa;
int opaquelen;
+ if (json)
+ return;
+
olsa = (struct opaque_lsa *)lsa->data;
if (VALID_OPAQUE_INFO_LEN(lsa->data))
diff --git a/ospfd/ospf_apiserver.h b/ospfd/ospf_apiserver.h
index 89a9474972..544a32a28c 100644
--- a/ospfd/ospf_apiserver.h
+++ b/ospfd/ospf_apiserver.h
@@ -182,7 +182,8 @@ extern void ospf_apiserver_nsm_change(struct ospf_neighbor *nbr,
extern void ospf_apiserver_config_write_router(struct vty *vty);
extern void ospf_apiserver_config_write_if(struct vty *vty,
struct interface *ifp);
-extern void ospf_apiserver_show_info(struct vty *vty, struct ospf_lsa *lsa);
+extern void ospf_apiserver_show_info(struct vty *vty, struct json_object *json,
+ struct ospf_lsa *lsa);
extern int ospf_ospf_apiserver_lsa_originator(void *arg);
extern struct ospf_lsa *ospf_apiserver_lsa_refresher(struct ospf_lsa *lsa);
extern void ospf_apiserver_flush_opaque_lsa(struct ospf_apiserver *apiserv,
diff --git a/ospfd/ospf_ext.c b/ospfd/ospf_ext.c
index 2d08eeece2..ea1506ea27 100644
--- a/ospfd/ospf_ext.c
+++ b/ospfd/ospf_ext.c
@@ -80,7 +80,8 @@ static struct ospf_ext_lp OspfEXT;
*/
/* Extended Prefix Opaque LSA related callback functions */
-static void ospf_ext_pref_show_info(struct vty *vty, struct ospf_lsa *lsa);
+static void ospf_ext_pref_show_info(struct vty *vty, struct json_object *json,
+ struct ospf_lsa *lsa);
static int ospf_ext_pref_lsa_originate(void *arg);
static struct ospf_lsa *ospf_ext_pref_lsa_refresh(struct ospf_lsa *lsa);
static void ospf_ext_pref_lsa_schedule(struct ext_itf *exti,
@@ -90,7 +91,8 @@ static int ospf_ext_link_new_if(struct interface *ifp);
static int ospf_ext_link_del_if(struct interface *ifp);
static void ospf_ext_ism_change(struct ospf_interface *oi, int old_status);
static void ospf_ext_link_nsm_change(struct ospf_neighbor *nbr, int old_status);
-static void ospf_ext_link_show_info(struct vty *vty, struct ospf_lsa *lsa);
+static void ospf_ext_link_show_info(struct vty *vty, struct json_object *json,
+ struct ospf_lsa *lsa);
static int ospf_ext_link_lsa_originate(void *arg);
static struct ospf_lsa *ospf_ext_link_lsa_refresh(struct ospf_lsa *lsa);
static void ospf_ext_link_lsa_schedule(struct ext_itf *exti,
@@ -1846,12 +1848,16 @@ static uint16_t show_vty_link_info(struct vty *vty, struct tlv_header *ext,
}
/* Extended Link TLVs */
-static void ospf_ext_link_show_info(struct vty *vty, struct ospf_lsa *lsa)
+static void ospf_ext_link_show_info(struct vty *vty, struct json_object *json,
+ struct ospf_lsa *lsa)
{
struct lsa_header *lsah = lsa->data;
struct tlv_header *tlvh;
uint16_t length = 0, sum = 0;
+ if (json)
+ return;
+
/* Initialize TLV browsing */
length = lsa->size - OSPF_LSA_HEADER_SIZE;
@@ -1932,12 +1938,16 @@ static uint16_t show_vty_pref_info(struct vty *vty, struct tlv_header *ext,
}
/* Extended Prefix TLVs */
-static void ospf_ext_pref_show_info(struct vty *vty, struct ospf_lsa *lsa)
+static void ospf_ext_pref_show_info(struct vty *vty, struct json_object *json,
+ struct ospf_lsa *lsa)
{
struct lsa_header *lsah = lsa->data;
struct tlv_header *tlvh;
uint16_t length = 0, sum = 0;
+ if (json)
+ return;
+
/* Initialize TLV browsing */
length = lsa->size - OSPF_LSA_HEADER_SIZE;
diff --git a/ospfd/ospf_gr_helper.c b/ospfd/ospf_gr_helper.c
index b3eaf7bbdb..a58a120b6b 100644
--- a/ospfd/ospf_gr_helper.c
+++ b/ospfd/ospf_gr_helper.c
@@ -75,7 +75,8 @@ static const char * const ospf_rejected_reason_desc[] = {
"Router is in the process of graceful restart",
};
-static void show_ospf_grace_lsa_info(struct vty *vty, struct ospf_lsa *lsa);
+static void show_ospf_grace_lsa_info(struct vty *vty, struct json_object *json,
+ struct ospf_lsa *lsa);
static bool ospf_check_change_in_rxmt_list(struct ospf_neighbor *nbr);
static unsigned int ospf_enable_rtr_hash_key(const void *data)
@@ -1012,7 +1013,8 @@ void ospf_gr_helper_set_supported_planned_only_restart(struct ospf *ospf,
* Returns:
* Nothing.
*/
-static void show_ospf_grace_lsa_info(struct vty *vty, struct ospf_lsa *lsa)
+static void show_ospf_grace_lsa_info(struct vty *vty, struct json_object *json,
+ struct ospf_lsa *lsa)
{
struct lsa_header *lsah = NULL;
struct tlv_header *tlvh = NULL;
@@ -1022,6 +1024,9 @@ static void show_ospf_grace_lsa_info(struct vty *vty, struct ospf_lsa *lsa)
uint16_t length = 0;
int sum = 0;
+ if (json)
+ return;
+
lsah = (struct lsa_header *)lsa->data;
if (lsa->size <= OSPF_LSA_HEADER_SIZE) {
diff --git a/ospfd/ospf_opaque.c b/ospfd/ospf_opaque.c
index 9ec2ed0aa8..a89e90bf70 100644
--- a/ospfd/ospf_opaque.c
+++ b/ospfd/ospf_opaque.c
@@ -274,7 +274,8 @@ struct ospf_opaque_functab {
void (*config_write_router)(struct vty *vty);
void (*config_write_if)(struct vty *vty, struct interface *ifp);
void (*config_write_debug)(struct vty *vty);
- void (*show_opaque_info)(struct vty *vty, struct ospf_lsa *lsa);
+ void (*show_opaque_info)(struct vty *vty, struct json_object *json,
+ struct ospf_lsa *lsa);
int (*lsa_originator)(void *arg);
struct ospf_lsa *(*lsa_refresher)(struct ospf_lsa *lsa);
int (*new_lsa_hook)(struct ospf_lsa *lsa);
@@ -373,7 +374,8 @@ int ospf_register_opaque_functab(
void (*config_write_router)(struct vty *vty),
void (*config_write_if)(struct vty *vty, struct interface *ifp),
void (*config_write_debug)(struct vty *vty),
- void (*show_opaque_info)(struct vty *vty, struct ospf_lsa *lsa),
+ void (*show_opaque_info)(struct vty *vty, struct json_object *json,
+ struct ospf_lsa *lsa),
int (*lsa_originator)(void *arg),
struct ospf_lsa *(*lsa_refresher)(struct ospf_lsa *lsa),
int (*new_lsa_hook)(struct ospf_lsa *lsa),
@@ -1182,6 +1184,16 @@ void show_opaque_info_detail(struct vty *vty, struct ospf_lsa *lsa,
VALID_OPAQUE_INFO_LEN(lsah)
? ""
: "(Invalid length?)");
+ } else {
+ json_object_string_add(
+ json, "opaqueType",
+ ospf_opaque_type_name(opaque_type));
+ json_object_int_add(json, "opaqueId", opaque_id);
+ json_object_int_add(json, "opaqueDataLength",
+ ntohs(lsah->length)
+ - OSPF_LSA_HEADER_SIZE);
+ json_object_boolean_add(json, "opaqueDataLengthValid",
+ VALID_OPAQUE_INFO_LEN(lsah));
}
} else {
zlog_debug(" Opaque-Type %u (%s)", opaque_type,
@@ -1197,7 +1209,7 @@ void show_opaque_info_detail(struct vty *vty, struct ospf_lsa *lsa,
/* Call individual output functions. */
if ((functab = ospf_opaque_functab_lookup(lsa)) != NULL)
if (functab->show_opaque_info != NULL)
- (*functab->show_opaque_info)(vty, lsa);
+ (*functab->show_opaque_info)(vty, json, lsa);
return;
}
diff --git a/ospfd/ospf_opaque.h b/ospfd/ospf_opaque.h
index 7d401c3dcc..bded32215b 100644
--- a/ospfd/ospf_opaque.h
+++ b/ospfd/ospf_opaque.h
@@ -136,7 +136,8 @@ extern int ospf_register_opaque_functab(
void (*config_write_router)(struct vty *vty),
void (*config_write_if)(struct vty *vty, struct interface *ifp),
void (*config_write_debug)(struct vty *vty),
- void (*show_opaque_info)(struct vty *vty, struct ospf_lsa *lsa),
+ void (*show_opaque_info)(struct vty *vty, struct json_object *json,
+ struct ospf_lsa *lsa),
int (*lsa_originator)(void *arg),
struct ospf_lsa *(*lsa_refresher)(struct ospf_lsa *lsa),
int (*new_lsa_hook)(struct ospf_lsa *lsa),
diff --git a/ospfd/ospf_ri.c b/ospfd/ospf_ri.c
index 602f98d141..0efa6ca4d5 100644
--- a/ospfd/ospf_ri.c
+++ b/ospfd/ospf_ri.c
@@ -73,7 +73,9 @@ static struct ospf_router_info OspfRI;
static void ospf_router_info_ism_change(struct ospf_interface *oi,
int old_status);
static void ospf_router_info_config_write_router(struct vty *vty);
-static void ospf_router_info_show_info(struct vty *vty, struct ospf_lsa *lsa);
+static void ospf_router_info_show_info(struct vty *vty,
+ struct json_object *json,
+ struct ospf_lsa *lsa);
static int ospf_router_info_lsa_originate(void *arg);
static struct ospf_lsa *ospf_router_info_lsa_refresh(struct ospf_lsa *lsa);
static void ospf_router_info_lsa_schedule(struct ospf_ri_area_info *ai,
@@ -1552,12 +1554,17 @@ static uint16_t show_vty_sr_msd(struct vty *vty, struct tlv_header *tlvh)
return TLV_SIZE(tlvh);
}
-static void ospf_router_info_show_info(struct vty *vty, struct ospf_lsa *lsa)
+static void ospf_router_info_show_info(struct vty *vty,
+ struct json_object *json,
+ struct ospf_lsa *lsa)
{
struct lsa_header *lsah = lsa->data;
struct tlv_header *tlvh;
uint16_t length = 0, sum = 0;
+ if (json)
+ return;
+
/* Initialize TLV browsing */
length = lsa->size - OSPF_LSA_HEADER_SIZE;
diff --git a/ospfd/ospf_te.c b/ospfd/ospf_te.c
index d95e677f6f..03fa572859 100644
--- a/ospfd/ospf_te.c
+++ b/ospfd/ospf_te.c
@@ -87,7 +87,8 @@ static int ospf_mpls_te_del_if(struct interface *ifp);
static void ospf_mpls_te_ism_change(struct ospf_interface *oi, int old_status);
static void ospf_mpls_te_nsm_change(struct ospf_neighbor *nbr, int old_status);
static void ospf_mpls_te_config_write_router(struct vty *vty);
-static void ospf_mpls_te_show_info(struct vty *vty, struct ospf_lsa *lsa);
+static void ospf_mpls_te_show_info(struct vty *vty, struct json_object *json,
+ struct ospf_lsa *lsa);
static int ospf_mpls_te_lsa_originate_area(void *arg);
static int ospf_mpls_te_lsa_inter_as_as(void *arg);
static int ospf_mpls_te_lsa_inter_as_area(void *arg);
@@ -3783,7 +3784,8 @@ static uint16_t ospf_mpls_te_show_link_subtlv(struct vty *vty,
return sum;
}
-static void ospf_mpls_te_show_info(struct vty *vty, struct ospf_lsa *lsa)
+static void ospf_mpls_te_show_info(struct vty *vty, struct json_object *json,
+ struct ospf_lsa *lsa)
{
struct lsa_header *lsah = lsa->data;
struct tlv_header *tlvh, *next;
@@ -3791,6 +3793,9 @@ static void ospf_mpls_te_show_info(struct vty *vty, struct ospf_lsa *lsa)
uint16_t (*subfunc)(struct vty * vty, struct tlv_header * tlvh,
uint16_t subtotal, uint16_t total) = NULL;
+ if (json)
+ return;
+
sum = 0;
total = lsa->size - OSPF_LSA_HEADER_SIZE;
diff --git a/tests/topotests/ospf6_gr_topo1/test_ospf6_gr_topo1.py b/tests/topotests/ospf6_gr_topo1/test_ospf6_gr_topo1.py
index ccbcadb8b1..e59333ebd2 100755
--- a/tests/topotests/ospf6_gr_topo1/test_ospf6_gr_topo1.py
+++ b/tests/topotests/ospf6_gr_topo1/test_ospf6_gr_topo1.py
@@ -171,14 +171,60 @@ def router_compare_json_output(rname, command, reference, tries):
assert diff is None, assertmsg
+def expect_grace_lsa(restarting, helper):
+ """
+ Check if the given helper neighbor has already received a Grace-LSA from
+ the router performing a graceful restart.
+ """
+ tgen = get_topogen()
+
+ logger.info(
+ "'{}': checking if a Grace-LSA was received from '{}'".format(
+ helper, restarting
+ )
+ )
+ test_func = partial(
+ topotest.router_json_cmp,
+ tgen.gears[helper],
+ "show ipv6 ospf6 database json",
+ {
+ "interfaceScopedLinkStateDb": [
+ {
+ "lsa": [
+ {
+ "type": "GR",
+ "advRouter": restarting,
+ }
+ ]
+ }
+ ]
+ },
+ )
+ _, result = topotest.run_and_expect(test_func, None, count=60, wait=1)
+ assertmsg = '"{}" didn\'t receive a Grace-LSA from "{}"'.format(helper, restarting)
+
+ assert result 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 we are not on initial convergence *but* we are checking
+ # after a restart. Looking in the zebra rib for installed
+ # is a recipe for test failure. Why? because if we are restarting
+ # then ospf is in the process of establishing neighbors and passing
+ # new routes to zebra. Zebra will not mark the route as installed
+ # when it receives a replacement from ospf until it has finished
+ # processing it. Let's give it a few seconds to allow this to happen
+ # under load.
if initial_convergence == True:
tries = 240
else:
- tries = 1
+ if restarting != None:
+ tries = 40
+ else:
+ tries = 1
router_compare_json_output(
rname, "show ipv6 route ospf json", "show_ipv6_route.json", tries
)
@@ -212,6 +258,26 @@ def check_routers(initial_convergence=False, exiting=None, restarting=None):
)
+def ensure_gr_is_in_zebra(rname):
+ retry = True
+ retry_times = 10
+ tgen = get_topogen()
+
+ while retry and retry_times > 0:
+ out = tgen.net[rname].cmd(
+ 'vtysh -c "show zebra client" | grep "Client: ospf6$" -A 40 | grep "Capabilities "'
+ )
+
+ if "Graceful Restart" not in out:
+ sleep(2)
+ retry_times -= 1
+ else:
+ retry = False
+
+ assertmsg = "%s does not appear to have Graceful Restart setup" % rname
+ assert not retry and retry_times > 0, assertmsg
+
+
#
# Test initial network convergence
#
@@ -238,10 +304,10 @@ def test_gr_rt1():
pytest.skip(tgen.errors)
tgen.net["rt1"].cmd('vtysh -c "graceful-restart prepare ipv6 ospf"')
- sleep(5)
+ expect_grace_lsa(restarting="1.1.1.1", helper="rt2")
+ ensure_gr_is_in_zebra("rt1")
kill_router_daemons(tgen, "rt1", ["ospf6d"], save_config=False)
check_routers(exiting="rt1")
-
start_router_daemons(tgen, "rt1", ["ospf6d"])
check_routers(restarting="rt1")
@@ -258,7 +324,9 @@ def test_gr_rt2():
pytest.skip(tgen.errors)
tgen.net["rt2"].cmd('vtysh -c "graceful-restart prepare ipv6 ospf"')
- sleep(5)
+ expect_grace_lsa(restarting="2.2.2.2", helper="rt1")
+ expect_grace_lsa(restarting="2.2.2.2", helper="rt3")
+ ensure_gr_is_in_zebra("rt2")
kill_router_daemons(tgen, "rt2", ["ospf6d"], save_config=False)
check_routers(exiting="rt2")
@@ -278,7 +346,10 @@ def test_gr_rt3():
pytest.skip(tgen.errors)
tgen.net["rt3"].cmd('vtysh -c "graceful-restart prepare ipv6 ospf"')
- sleep(5)
+ expect_grace_lsa(restarting="3.3.3.3", helper="rt2")
+ expect_grace_lsa(restarting="3.3.3.3", helper="rt4")
+ expect_grace_lsa(restarting="3.3.3.3", helper="rt6")
+ ensure_gr_is_in_zebra("rt3")
kill_router_daemons(tgen, "rt3", ["ospf6d"], save_config=False)
check_routers(exiting="rt3")
@@ -298,7 +369,9 @@ def test_gr_rt4():
pytest.skip(tgen.errors)
tgen.net["rt4"].cmd('vtysh -c "graceful-restart prepare ipv6 ospf"')
- sleep(5)
+ expect_grace_lsa(restarting="4.4.4.4", helper="rt3")
+ expect_grace_lsa(restarting="4.4.4.4", helper="rt5")
+ ensure_gr_is_in_zebra("rt4")
kill_router_daemons(tgen, "rt4", ["ospf6d"], save_config=False)
check_routers(exiting="rt4")
@@ -318,7 +391,8 @@ def test_gr_rt5():
pytest.skip(tgen.errors)
tgen.net["rt5"].cmd('vtysh -c "graceful-restart prepare ipv6 ospf"')
- sleep(5)
+ expect_grace_lsa(restarting="5.5.5.5", helper="rt4")
+ ensure_gr_is_in_zebra("rt5")
kill_router_daemons(tgen, "rt5", ["ospf6d"], save_config=False)
check_routers(exiting="rt5")
@@ -338,7 +412,9 @@ def test_gr_rt6():
pytest.skip(tgen.errors)
tgen.net["rt6"].cmd('vtysh -c "graceful-restart prepare ipv6 ospf"')
- sleep(5)
+ expect_grace_lsa(restarting="6.6.6.6", helper="rt3")
+ expect_grace_lsa(restarting="6.6.6.6", helper="rt7")
+ ensure_gr_is_in_zebra("rt6")
kill_router_daemons(tgen, "rt6", ["ospf6d"], save_config=False)
check_routers(exiting="rt6")
@@ -358,7 +434,8 @@ def test_gr_rt7():
pytest.skip(tgen.errors)
tgen.net["rt7"].cmd('vtysh -c "graceful-restart prepare ipv6 ospf"')
- sleep(5)
+ expect_grace_lsa(restarting="6.6.6.6", helper="rt6")
+ ensure_gr_is_in_zebra("rt7")
kill_router_daemons(tgen, "rt7", ["ospf6d"], save_config=False)
check_routers(exiting="rt7")
diff --git a/tests/topotests/ospf_gr_topo1/test_ospf_gr_topo1.py b/tests/topotests/ospf_gr_topo1/test_ospf_gr_topo1.py
index 7d9cc68412..3e3bf5cb8c 100755
--- a/tests/topotests/ospf_gr_topo1/test_ospf_gr_topo1.py
+++ b/tests/topotests/ospf_gr_topo1/test_ospf_gr_topo1.py
@@ -180,14 +180,60 @@ def router_compare_json_output(rname, command, reference, tries):
assert diff is None, assertmsg
+def expect_grace_lsa(restarting, area, helper):
+ """
+ Check if the given helper neighbor has already received a Grace-LSA from
+ the router performing a graceful restart.
+ """
+ tgen = get_topogen()
+
+ logger.info(
+ "'{}': checking if a Grace-LSA was received from '{}'".format(
+ helper, restarting
+ )
+ )
+ test_func = partial(
+ topotest.router_json_cmp,
+ tgen.gears[helper],
+ "show ip ospf database opaque-link json",
+ {
+ "linkLocalOpaqueLsa": {
+ "areas": {
+ area: [
+ {
+ "advertisingRouter": restarting,
+ "opaqueType": "Grace-LSA",
+ }
+ ]
+ }
+ }
+ },
+ )
+ _, result = topotest.run_and_expect(test_func, None, count=60, wait=1)
+ assertmsg = '"{}" didn\'t receive a Grace-LSA from "{}"'.format(helper, restarting)
+
+ assert result 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 we are not on initial convergence *but* we are checking
+ # after a restart. Looking in the zebra rib for installed
+ # is a recipe for test failure. Why? because if we are restarting
+ # then ospf is in the process of establishing neighbors and passing
+ # new routes to zebra. Zebra will not mark the route as installed
+ # when it receives a replacement from ospf until it has finished
+ # processing it. Let's give it a few seconds to allow this to happen
+ # under load.
if initial_convergence == True:
tries = 240
else:
- tries = 1
+ if restarting != None:
+ tries = 40
+ else:
+ tries = 1
router_compare_json_output(
rname, "show ip route ospf json", "show_ip_route.json", tries
)
@@ -215,6 +261,26 @@ def check_routers(initial_convergence=False, exiting=None, restarting=None):
)
+def ensure_gr_is_in_zebra(rname):
+ retry = True
+ retry_times = 10
+ tgen = get_topogen()
+
+ while retry and retry_times > 0:
+ out = tgen.net[rname].cmd(
+ 'vtysh -c "show zebra client" | grep "Client: ospf$" -A 40 | grep "Capabilities "'
+ )
+
+ if "Graceful Restart" not in out:
+ sleep(2)
+ retry_times -= 1
+ else:
+ retry = False
+
+ assertmsg = "%s does not appear to have Graceful Restart setup" % rname
+ assert not retry and retry_times > 0, assertmsg
+
+
#
# Test initial network convergence
#
@@ -241,7 +307,8 @@ def test_gr_rt1():
pytest.skip(tgen.errors)
tgen.net["rt1"].cmd('vtysh -c "graceful-restart prepare ip ospf"')
- sleep(3)
+ expect_grace_lsa(restarting="1.1.1.1", area="0.0.0.1", helper="rt2")
+ ensure_gr_is_in_zebra("rt1")
kill_router_daemons(tgen, "rt1", ["ospfd"], save_config=False)
check_routers(exiting="rt1")
@@ -261,7 +328,9 @@ def test_gr_rt2():
pytest.skip(tgen.errors)
tgen.net["rt2"].cmd('vtysh -c "graceful-restart prepare ip ospf"')
- sleep(3)
+ expect_grace_lsa(restarting="2.2.2.2", area="0.0.0.1", helper="rt1")
+ expect_grace_lsa(restarting="2.2.2.2", area="0.0.0.0", helper="rt3")
+ ensure_gr_is_in_zebra("rt2")
kill_router_daemons(tgen, "rt2", ["ospfd"], save_config=False)
check_routers(exiting="rt2")
@@ -281,7 +350,10 @@ def test_gr_rt3():
pytest.skip(tgen.errors)
tgen.net["rt3"].cmd('vtysh -c "graceful-restart prepare ip ospf"')
- sleep(3)
+ expect_grace_lsa(restarting="3.3.3.3", area="0.0.0.0", helper="rt2")
+ expect_grace_lsa(restarting="3.3.3.3", area="0.0.0.0", helper="rt4")
+ expect_grace_lsa(restarting="3.3.3.3", area="0.0.0.0", helper="rt6")
+ ensure_gr_is_in_zebra("rt3")
kill_router_daemons(tgen, "rt3", ["ospfd"], save_config=False)
check_routers(exiting="rt3")
@@ -301,7 +373,9 @@ def test_gr_rt4():
pytest.skip(tgen.errors)
tgen.net["rt4"].cmd('vtysh -c "graceful-restart prepare ip ospf"')
- sleep(3)
+ expect_grace_lsa(restarting="4.4.4.4", area="0.0.0.0", helper="rt3")
+ expect_grace_lsa(restarting="4.4.4.4", area="0.0.0.2", helper="rt5")
+ ensure_gr_is_in_zebra("rt4")
kill_router_daemons(tgen, "rt4", ["ospfd"], save_config=False)
check_routers(exiting="rt4")
@@ -321,7 +395,8 @@ def test_gr_rt5():
pytest.skip(tgen.errors)
tgen.net["rt5"].cmd('vtysh -c "graceful-restart prepare ip ospf"')
- sleep(3)
+ expect_grace_lsa(restarting="5.5.5.5", area="0.0.0.2", helper="rt4")
+ ensure_gr_is_in_zebra("rt5")
kill_router_daemons(tgen, "rt5", ["ospfd"], save_config=False)
check_routers(exiting="rt5")
@@ -341,7 +416,9 @@ def test_gr_rt6():
pytest.skip(tgen.errors)
tgen.net["rt6"].cmd('vtysh -c "graceful-restart prepare ip ospf"')
- sleep(3)
+ expect_grace_lsa(restarting="6.6.6.6", area="0.0.0.0", helper="rt3")
+ expect_grace_lsa(restarting="6.6.6.6", area="0.0.0.3", helper="rt7")
+ ensure_gr_is_in_zebra("rt6")
kill_router_daemons(tgen, "rt6", ["ospfd"], save_config=False)
check_routers(exiting="rt6")
@@ -361,7 +438,8 @@ def test_gr_rt7():
pytest.skip(tgen.errors)
tgen.net["rt7"].cmd('vtysh -c "graceful-restart prepare ip ospf"')
- sleep(3)
+ expect_grace_lsa(restarting="7.7.7.7", area="0.0.0.3", helper="rt6")
+ ensure_gr_is_in_zebra("rt7")
kill_router_daemons(tgen, "rt7", ["ospfd"], save_config=False)
check_routers(exiting="rt7")
diff --git a/zebra/zserv.c b/zebra/zserv.c
index e4a48093f7..abb9c5ca5d 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -1007,7 +1007,6 @@ static void zebra_show_client_detail(struct vty *vty, struct zserv *client)
char wbuf[ZEBRA_TIME_BUF], nhbuf[ZEBRA_TIME_BUF], mbuf[ZEBRA_TIME_BUF];
time_t connect_time, last_read_time, last_write_time;
uint32_t last_read_cmd, last_write_cmd;
- struct client_gr_info *info = NULL;
vty_out(vty, "Client: %s", zebra_route_string(client->proto));
if (client->instance)
@@ -1100,22 +1099,6 @@ static void zebra_show_client_detail(struct vty *vty, struct zserv *client)
client->local_es_evi_add_cnt, 0, client->local_es_evi_del_cnt);
vty_out(vty, "Errors: %u\n", client->error_cnt);
- TAILQ_FOREACH (info, &client->gr_info_queue, gr_info) {
- vty_out(vty, "VRF : %s\n", vrf_id_to_name(info->vrf_id));
- vty_out(vty, "Capabilities : ");
- switch (info->capabilities) {
- case ZEBRA_CLIENT_GR_CAPABILITIES:
- vty_out(vty, "Graceful Restart\n");
- break;
- case ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE:
- case ZEBRA_CLIENT_ROUTE_UPDATE_PENDING:
- case ZEBRA_CLIENT_GR_DISABLE:
- case ZEBRA_CLIENT_RIB_STALE_TIME:
- vty_out(vty, "None\n");
- break;
- }
- }
-
#if defined DEV_BUILD
vty_out(vty, "Input Fifo: %zu:%zu Output Fifo: %zu:%zu\n",
client->ibuf_fifo->count, client->ibuf_fifo->max_count,
@@ -1151,7 +1134,8 @@ static void zebra_show_stale_client_detail(struct vty *vty,
vty_out(vty, "Capabilities : ");
switch (info->capabilities) {
case ZEBRA_CLIENT_GR_CAPABILITIES:
- vty_out(vty, "Graceful Restart\n");
+ vty_out(vty, "Graceful Restart(%u seconds)\n",
+ info->stale_removal_time);
break;
case ZEBRA_CLIENT_ROUTE_UPDATE_COMPLETE:
case ZEBRA_CLIENT_ROUTE_UPDATE_PENDING: