mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-07-17 19:05:44 +00:00
commit
effd4c7bdd
@ -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))
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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),
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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")
|
||||
|
||||
|
@ -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")
|
||||
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user