Merge pull request #11980 from isabelladeleon12/set_overload_startup

isisd: Add support for set-overload on-startup
This commit is contained in:
Russ White 2022-10-13 10:59:24 -04:00 committed by GitHub
commit 07735ca345
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 538 additions and 41 deletions

View File

@ -2631,6 +2631,7 @@ AC_DEFINE_UNQUOTED([ZEBRA_SERV_PATH], ["$frr_statedir%s%s/zserv.api"], [zebra ap
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([OSPF6D_GR_STATE], ["$frr_statedir/ospf6d-gr.json"], [ospf6d GR state information])
AC_DEFINE_UNQUOTED([ISISD_RESTART], ["$frr_statedir%s/isid-restart.json"], [isisd restart information])
AC_DEFINE_UNQUOTED([OSPF6_AUTH_SEQ_NUM_FILE], ["$frr_statedir/ospf6d-at-seq-no.dat"], [ospf6d AT Sequence number 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])

View File

@ -83,6 +83,10 @@ writing, *isisd* does not support multiple ISIS processes.
Set overload bit to avoid any transit traffic.
.. clicmd:: set-overload-bit on-startup (0-86400)
Set overload bit on startup for the specified duration, in seconds. Reference: :rfc:`3277`
.. clicmd:: purge-originator
Enable or disable :rfc:`6232` purge originator identification.

View File

@ -404,7 +404,7 @@ DEFPY_YANG(set_overload_bit, set_overload_bit_cmd, "[no] set-overload-bit",
"Reset overload bit to accept transit traffic\n"
"Set overload bit to avoid any transit traffic\n")
{
nb_cli_enqueue_change(vty, "./overload", NB_OP_MODIFY,
nb_cli_enqueue_change(vty, "./overload/enabled", NB_OP_MODIFY,
no ? "false" : "true");
return nb_cli_apply_changes(vty, NULL);
@ -418,6 +418,42 @@ void cli_show_isis_overload(struct vty *vty, const struct lyd_node *dnode,
vty_out(vty, " set-overload-bit\n");
}
/*
* XPath: /frr-isisd:isis/instance/overload/on-startup
*/
DEFPY_YANG(set_overload_bit_on_startup, set_overload_bit_on_startup_cmd,
"set-overload-bit on-startup (0-86400)$val",
"Set overload bit to avoid any transit traffic\n"
"Set overload bit on startup\n"
"Set overload time in seconds\n")
{
nb_cli_enqueue_change(vty, "./overload/on-startup", NB_OP_MODIFY,
val_str);
return nb_cli_apply_changes(vty, NULL);
}
DEFPY_YANG(no_set_overload_bit_on_startup, no_set_overload_bit_on_startup_cmd,
"no set-overload-bit on-startup [(0-86400)$val]",
NO_STR
"Reset overload bit to accept transit traffic\n"
"Set overload bit on startup\n"
"Set overload time in seconds\n")
{
nb_cli_enqueue_change(vty, "./overload/on-startup", NB_OP_DESTROY,
NULL);
return nb_cli_apply_changes(vty, NULL);
}
void cli_show_isis_overload_on_startup(struct vty *vty,
const struct lyd_node *dnode,
bool show_defaults)
{
vty_out(vty, " set-overload-bit on-startup %s\n",
yang_dnode_get_string(dnode, NULL));
}
/*
* XPath: /frr-isisd:isis/instance/attach-send
*/
@ -3107,6 +3143,9 @@ void isis_cli_init(void)
install_element(ISIS_NODE, &dynamic_hostname_cmd);
install_element(ISIS_NODE, &set_overload_bit_cmd);
install_element(ISIS_NODE, &set_overload_bit_on_startup_cmd);
install_element(ISIS_NODE, &no_set_overload_bit_on_startup_cmd);
install_element(ISIS_NODE, &attached_bit_send_cmd);
install_element(ISIS_NODE, &attached_bit_receive_ignore_cmd);

View File

@ -68,6 +68,8 @@ static void lsp_l2_refresh_pseudo(struct thread *thread);
static void lsp_destroy(struct isis_lsp *lsp);
static bool device_startup;
int lsp_id_cmp(uint8_t *id1, uint8_t *id2)
{
return memcmp(id1, id2, ISIS_SYS_ID_LEN + 2);
@ -437,6 +439,21 @@ bool isis_level2_adj_up(struct isis_area *area)
return false;
}
/*
* Unset the overload bit after the timer expires
*/
void set_overload_on_start_timer(struct thread *thread)
{
struct isis_area *area = THREAD_ARG(thread);
assert(area);
area->t_overload_on_startup_timer = NULL;
/* Check if set-overload-bit is not currently configured */
if (!area->overload_configured)
isis_area_overload_bit_set(area, false);
}
static void isis_reset_attach_bit(struct isis_adjacency *adj)
{
struct isis_area *area = adj->circuit->area;
@ -1355,6 +1372,7 @@ int lsp_generate(struct isis_area *area, int level)
uint32_t seq_num = 0;
uint8_t lspid[ISIS_SYS_ID_LEN + 2];
uint16_t rem_lifetime, refresh_time;
uint32_t overload_time;
if ((area == NULL) || (area->is_type & level) != level)
return ISIS_ERROR;
@ -1363,6 +1381,18 @@ int lsp_generate(struct isis_area *area, int level)
memcpy(&lspid, area->isis->sysid, ISIS_SYS_ID_LEN);
/* Check if device should be overloaded on startup */
if (device_startup) {
overload_time = isis_restart_read_overload_time(area);
if (overload_time > 0) {
isis_area_overload_bit_set(area, true);
thread_add_timer(master, set_overload_on_start_timer,
area, overload_time,
&area->t_overload_on_startup_timer);
}
device_startup = false;
}
/* only builds the lsp if the area shares the level */
oldlsp = lsp_search(&area->lspdb[level - 1], lspid);
if (oldlsp) {
@ -2373,6 +2403,7 @@ int isis_lsp_iterate_is_reach(struct isis_lsp *lsp, uint16_t mtid,
void lsp_init(void)
{
device_startup = true;
hook_register(isis_adj_state_change_hook,
lsp_handle_adj_state_change);
}

View File

@ -66,6 +66,7 @@ DECLARE_RBTREE_UNIQ(lspdb, struct isis_lsp, dbe, lspdb_compare);
void lsp_db_init(struct lspdb_head *head);
void lsp_db_fini(struct lspdb_head *head);
void lsp_tick(struct thread *thread);
void set_overload_on_start_timer(struct thread *thread);
int lsp_generate(struct isis_area *area, int level);
#define lsp_regenerate_schedule(area, level, all_pseudo) \

View File

@ -81,11 +81,18 @@ const struct frr_yang_module_info frr_isisd_info = {
},
},
{
.xpath = "/frr-isisd:isis/instance/overload",
.xpath = "/frr-isisd:isis/instance/overload/enabled",
.cbs = {
.cli_show = cli_show_isis_overload,
.modify = isis_instance_overload_modify,
},
.modify = isis_instance_overload_enabled_modify,
}
},
{
.xpath = "/frr-isisd:isis/instance/overload/on-startup",
.cbs = {
.cli_show = cli_show_isis_overload_on_startup,
.modify = isis_instance_overload_on_startup_modify,
}
},
{
.xpath = "/frr-isisd:isis/instance/metric-style",

View File

@ -37,7 +37,8 @@ int isis_instance_dynamic_hostname_modify(struct nb_cb_modify_args *args);
int isis_instance_attached_send_modify(struct nb_cb_modify_args *args);
int isis_instance_attached_receive_modify(struct nb_cb_modify_args *args);
int isis_instance_attached_modify(struct nb_cb_modify_args *args);
int isis_instance_overload_modify(struct nb_cb_modify_args *args);
int isis_instance_overload_enabled_modify(struct nb_cb_modify_args *args);
int isis_instance_overload_on_startup_modify(struct nb_cb_modify_args *args);
int isis_instance_metric_style_modify(struct nb_cb_modify_args *args);
int isis_instance_purge_originator_modify(struct nb_cb_modify_args *args);
int isis_instance_lsp_mtu_modify(struct nb_cb_modify_args *args);
@ -442,6 +443,9 @@ void cli_show_isis_attached_receive(struct vty *vty,
bool show_defaults);
void cli_show_isis_overload(struct vty *vty, const struct lyd_node *dnode,
bool show_defaults);
void cli_show_isis_overload_on_startup(struct vty *vty,
const struct lyd_node *dnode,
bool show_defaults);
void cli_show_isis_metric_style(struct vty *vty, const struct lyd_node *dnode,
bool show_defaults);
void cli_show_isis_area_pwd(struct vty *vty, const struct lyd_node *dnode,

View File

@ -336,9 +336,9 @@ int isis_instance_attached_modify(struct nb_cb_modify_args *args)
}
/*
* XPath: /frr-isisd:isis/instance/overload
* XPath: /frr-isisd:isis/instance/overload/enabled
*/
int isis_instance_overload_modify(struct nb_cb_modify_args *args)
int isis_instance_overload_enabled_modify(struct nb_cb_modify_args *args)
{
struct isis_area *area;
bool overload;
@ -348,11 +348,31 @@ int isis_instance_overload_modify(struct nb_cb_modify_args *args)
area = nb_running_get_entry(args->dnode, NULL, true);
overload = yang_dnode_get_bool(args->dnode, NULL);
area->overload_configured = overload;
isis_area_overload_bit_set(area, overload);
return NB_OK;
}
/*
* XPath: /frr-isisd:isis/instance/overload/on-startup
*/
int isis_instance_overload_on_startup_modify(struct nb_cb_modify_args *args)
{
struct isis_area *area;
uint32_t overload_time;
if (args->event != NB_EV_APPLY)
return NB_OK;
overload_time = yang_dnode_get_uint32(args->dnode, NULL);
area = nb_running_get_entry(args->dnode, NULL, true);
isis_area_overload_on_startup_set(area, overload_time);
return NB_OK;
}
/*
* XPath: /frr-isisd:isis/instance/metric-style
*/

View File

@ -3198,9 +3198,15 @@ void isis_area_overload_bit_set(struct isis_area *area, bool overload_bit)
if (new_overload_bit != area->overload_bit) {
area->overload_bit = new_overload_bit;
if (new_overload_bit)
if (new_overload_bit) {
area->overload_counter++;
} else {
/* Cancel overload on startup timer if it's running */
if (area->t_overload_on_startup_timer) {
THREAD_OFF(area->t_overload_on_startup_timer);
area->t_overload_on_startup_timer = NULL;
}
}
#ifndef FABRICD
hook_call(isis_hook_db_overload, area);
@ -3213,6 +3219,109 @@ void isis_area_overload_bit_set(struct isis_area *area, bool overload_bit)
#endif /* ifndef FABRICD */
}
void isis_area_overload_on_startup_set(struct isis_area *area,
uint32_t startup_time)
{
if (area->overload_on_startup_time != startup_time) {
area->overload_on_startup_time = startup_time;
isis_restart_write_overload_time(area, startup_time);
}
}
/*
* Returns the path of the file (non-volatile memory) that contains restart
* information.
*/
char *isis_restart_filepath()
{
static char filepath[MAXPATHLEN];
snprintf(filepath, sizeof(filepath), ISISD_RESTART, "");
return filepath;
}
/*
* Record in non-volatile memory the overload on startup time.
*/
void isis_restart_write_overload_time(struct isis_area *isis_area,
uint32_t overload_time)
{
char *filepath;
const char *area_name;
json_object *json;
json_object *json_areas;
json_object *json_area;
filepath = isis_restart_filepath();
area_name = isis_area->area_tag;
json = json_object_from_file(filepath);
if (json == NULL)
json = json_object_new_object();
json_object_object_get_ex(json, "areas", &json_areas);
if (!json_areas) {
json_areas = json_object_new_object();
json_object_object_add(json, "areas", json_areas);
}
json_object_object_get_ex(json_areas, area_name, &json_area);
if (!json_area) {
json_area = json_object_new_object();
json_object_object_add(json_areas, area_name, json_area);
}
json_object_int_add(json_area, "overload_time",
isis_area->overload_on_startup_time);
json_object_to_file_ext(filepath, json, JSON_C_TO_STRING_PRETTY);
json_object_free(json);
}
/*
* Fetch from non-volatile memory the overload on startup time.
*/
uint32_t isis_restart_read_overload_time(struct isis_area *isis_area)
{
char *filepath;
const char *area_name;
json_object *json;
json_object *json_areas;
json_object *json_area;
json_object *json_overload_time;
uint32_t overload_time = 0;
filepath = isis_restart_filepath();
area_name = isis_area->area_tag;
json = json_object_from_file(filepath);
if (json == NULL)
json = json_object_new_object();
json_object_object_get_ex(json, "areas", &json_areas);
if (!json_areas) {
json_areas = json_object_new_object();
json_object_object_add(json, "areas", json_areas);
}
json_object_object_get_ex(json_areas, area_name, &json_area);
if (!json_area) {
json_area = json_object_new_object();
json_object_object_add(json_areas, area_name, json_area);
}
json_object_object_get_ex(json_area, "overload_time",
&json_overload_time);
if (json_overload_time) {
overload_time = json_object_get_int(json_overload_time);
}
json_object_object_del(json_areas, area_name);
json_object_to_file_ext(filepath, json, JSON_C_TO_STRING_PRETTY);
json_object_free(json);
return overload_time;
}
void isis_area_attached_bit_send_set(struct isis_area *area, bool attached_bit)
{

View File

@ -142,6 +142,7 @@ struct isis_area {
struct flags flags;
struct thread *t_tick; /* LSP walker */
struct thread *t_lsp_refresh[ISIS_LEVELS];
struct thread *t_overload_on_startup_timer;
struct timeval last_lsp_refresh_event[ISIS_LEVELS];
struct thread *t_rlfa_rib_update;
/* t_lsp_refresh is used in two ways:
@ -180,7 +181,9 @@ struct isis_area {
char is_type; /* level-1 level-1-2 or level-2-only */
/* are we overloaded? */
char overload_bit;
bool overload_configured;
uint32_t overload_counter;
uint32_t overload_on_startup_time;
/* L1/L2 router identifier for inter-area traffic */
char attached_bit_send;
char attached_bit_rcv_ignore;
@ -290,6 +293,8 @@ void isis_area_invalidate_routes(struct isis_area *area, int levels);
void isis_area_verify_routes(struct isis_area *area);
void isis_area_overload_bit_set(struct isis_area *area, bool overload_bit);
void isis_area_overload_on_startup_set(struct isis_area *area,
uint32_t startup_time);
void isis_area_attached_bit_send_set(struct isis_area *area, bool attached_bit);
void isis_area_attached_bit_receive_set(struct isis_area *area,
bool attached_bit);
@ -315,7 +320,10 @@ void show_isis_database_lspdb_json(struct json_object *json,
void show_isis_database_lspdb_vty(struct vty *vty, struct isis_area *area,
int level, struct lspdb_head *lspdb,
const char *argv, int ui_level);
char *isis_restart_filepath(void);
void isis_restart_write_overload_time(struct isis_area *isis_area,
uint32_t overload_time);
uint32_t isis_restart_read_overload_time(struct isis_area *isis_area);
/* YANG paths */
#define ISIS_INSTANCE "/frr-isisd:isis/instance"
#define ISIS_SR "/frr-isisd:isis/instance/segment-routing"

View File

@ -25,7 +25,7 @@
"""
test_isis_topo1.py: Test ISIS topology.
"""
import datetime
import functools
import json
import os
@ -38,6 +38,11 @@ sys.path.append(os.path.join(CWD, "../"))
# pylint: disable=C0413
from lib import topotest
from lib.common_config import (
retry,
stop_router,
start_router,
)
from lib.topogen import Topogen, TopoRouter, get_topogen
from lib.topolog import logger
@ -248,10 +253,12 @@ def test_isis_summary_json():
for rname, router in tgen.routers().items():
logger.info("Checking router %s", rname)
json_output = tgen.gears[rname].vtysh_cmd("show isis summary json", isjson=True)
assertmsg = "Test isis summary json failed in '{}' data '{}'".format(rname, json_output)
assert json_output['vrf'] == "default", assertmsg
assert json_output['areas'][0]['area'] == "1", assertmsg
assert json_output['areas'][0]['levels'][0]['id'] != '3', assertmsg
assertmsg = "Test isis summary json failed in '{}' data '{}'".format(
rname, json_output
)
assert json_output["vrf"] == "default", assertmsg
assert json_output["areas"][0]["area"] == "1", assertmsg
assert json_output["areas"][0]["levels"][0]["id"] != "3", assertmsg
def test_isis_interface_json():
@ -265,15 +272,29 @@ def test_isis_interface_json():
logger.info("Checking 'show isis interface json'")
for rname, router in tgen.routers().items():
logger.info("Checking router %s", rname)
json_output = tgen.gears[rname].vtysh_cmd("show isis interface json", isjson=True)
assertmsg = "Test isis interface json failed in '{}' data '{}'".format(rname, json_output)
assert json_output['areas'][0]['circuits'][0]['interface']['name'] == rname+"-eth0", assertmsg
json_output = tgen.gears[rname].vtysh_cmd(
"show isis interface json", isjson=True
)
assertmsg = "Test isis interface json failed in '{}' data '{}'".format(
rname, json_output
)
assert (
json_output["areas"][0]["circuits"][0]["interface"]["name"]
== rname + "-eth0"
), assertmsg
for rname, router in tgen.routers().items():
logger.info("Checking router %s", rname)
json_output = tgen.gears[rname].vtysh_cmd("show isis interface detail json", isjson=True)
assertmsg = "Test isis interface json failed in '{}' data '{}'".format(rname, json_output)
assert json_output['areas'][0]['circuits'][0]['interface']['name'] == rname+"-eth0", assertmsg
json_output = tgen.gears[rname].vtysh_cmd(
"show isis interface detail json", isjson=True
)
assertmsg = "Test isis interface json failed in '{}' data '{}'".format(
rname, json_output
)
assert (
json_output["areas"][0]["circuits"][0]["interface"]["name"]
== rname + "-eth0"
), assertmsg
def test_isis_neighbor_json():
@ -284,19 +305,32 @@ def test_isis_neighbor_json():
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
#tgen.mininet_cli()
# tgen.mininet_cli()
logger.info("Checking 'show isis neighbor json'")
for rname, router in tgen.routers().items():
logger.info("Checking router %s", rname)
json_output = tgen.gears[rname].vtysh_cmd("show isis neighbor json", isjson=True)
assertmsg = "Test isis neighbor json failed in '{}' data '{}'".format(rname, json_output)
assert json_output['areas'][0]['circuits'][0]['interface'] == rname+"-eth0", assertmsg
json_output = tgen.gears[rname].vtysh_cmd(
"show isis neighbor json", isjson=True
)
assertmsg = "Test isis neighbor json failed in '{}' data '{}'".format(
rname, json_output
)
assert (
json_output["areas"][0]["circuits"][0]["interface"] == rname + "-eth0"
), assertmsg
for rname, router in tgen.routers().items():
logger.info("Checking router %s", rname)
json_output = tgen.gears[rname].vtysh_cmd("show isis neighbor detail json", isjson=True)
assertmsg = "Test isis neighbor json failed in '{}' data '{}'".format(rname, json_output)
assert json_output['areas'][0]['circuits'][0]['interface']['name'] == rname+"-eth0", assertmsg
json_output = tgen.gears[rname].vtysh_cmd(
"show isis neighbor detail json", isjson=True
)
assertmsg = "Test isis neighbor json failed in '{}' data '{}'".format(
rname, json_output
)
assert (
json_output["areas"][0]["circuits"][0]["interface"]["name"]
== rname + "-eth0"
), assertmsg
def test_isis_database_json():
@ -307,21 +341,246 @@ def test_isis_database_json():
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
#tgen.mininet_cli()
# tgen.mininet_cli()
logger.info("Checking 'show isis database json'")
for rname, router in tgen.routers().items():
logger.info("Checking router %s", rname)
json_output = tgen.gears[rname].vtysh_cmd("show isis database json", isjson=True)
assertmsg = "Test isis database json failed in '{}' data '{}'".format(rname, json_output)
assert json_output['areas'][0]['area']['name'] == "1", assertmsg
assert json_output['areas'][0]['levels'][0]['id'] != '3', assertmsg
json_output = tgen.gears[rname].vtysh_cmd(
"show isis database json", isjson=True
)
assertmsg = "Test isis database json failed in '{}' data '{}'".format(
rname, json_output
)
assert json_output["areas"][0]["area"]["name"] == "1", assertmsg
assert json_output["areas"][0]["levels"][0]["id"] != "3", assertmsg
for rname, router in tgen.routers().items():
logger.info("Checking router %s", rname)
json_output = tgen.gears[rname].vtysh_cmd("show isis database detail json", isjson=True)
assertmsg = "Test isis database json failed in '{}' data '{}'".format(rname, json_output)
assert json_output['areas'][0]['area']['name'] == "1", assertmsg
assert json_output['areas'][0]['levels'][0]['id'] != '3', assertmsg
json_output = tgen.gears[rname].vtysh_cmd(
"show isis database detail json", isjson=True
)
assertmsg = "Test isis database json failed in '{}' data '{}'".format(
rname, json_output
)
assert json_output["areas"][0]["area"]["name"] == "1", assertmsg
assert json_output["areas"][0]["levels"][0]["id"] != "3", assertmsg
def test_isis_overload_on_startup():
"Check that overload on startup behaves as expected"
tgen = get_topogen()
net = get_topogen().net
overload_time = 120
# Don't run this test if we have any failure.
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
logger.info("Testing overload on startup behavior")
# Configure set-overload-bit on-startup on r3
r3 = tgen.gears["r3"]
r3.vtysh_cmd(
f"""
configure
router isis 1
set-overload-bit on-startup {overload_time}
"""
)
# Restart r3
logger.info("Stop router")
stop_router(tgen, "r3")
logger.info("Start router")
tstamp_before_start_router = datetime.datetime.now()
start_router(tgen, "r3")
tstamp_after_start_router = datetime.datetime.now()
startup_router_time = (
tstamp_after_start_router - tstamp_before_start_router
).total_seconds()
# Check that the overload bit is set in r3's LSP
check_lsp_overload_bit("r3", "r3.00-00", "0/0/1")
check_lsp_overload_bit("r1", "r3.00-00", "0/0/1")
# Attempt to unset overload bit while timer is still running
r3.vtysh_cmd(
"""
configure
router isis 1
no set-overload-bit on-startup
no set-overload-bit
"""
)
# Check overload bit is still set
check_lsp_overload_bit("r1", "r3.00-00", "0/0/1")
# Check that overload bit is unset after timer completes
check_lsp_overload_bit("r3", "r3.00-00", "0/0/0")
tstamp_after_bit_unset = datetime.datetime.now()
check_lsp_overload_bit("r1", "r3.00-00", "0/0/0")
# Collect time overloaded
time_overloaded = (
tstamp_after_bit_unset - tstamp_after_start_router
).total_seconds()
logger.info(f"Time Overloaded: {time_overloaded}")
# Use time it took to startup router as lower bound
logger.info(
f"Assert that overload time falls in range: {overload_time - startup_router_time} < {time_overloaded} <= {overload_time}"
)
result = overload_time - startup_router_time < time_overloaded <= overload_time
assert result
def test_isis_overload_on_startup_cancel_timer():
"Check that overload on startup timer is cancelled when overload bit is set/unset"
tgen = get_topogen()
net = get_topogen().net
overload_time = 90
# Don't run this test if we have any failure.
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
logger.info(
"Testing overload on startup behavior with set overload bit: cancel timer"
)
# Configure set-overload-bit on-startup on r3
r3 = tgen.gears["r3"]
r3.vtysh_cmd(
f"""
configure
router isis 1
set-overload-bit on-startup {overload_time}
set-overload-bit
"""
)
# Restart r3
logger.info("Stop router")
stop_router(tgen, "r3")
logger.info("Start router")
start_router(tgen, "r3")
# Check that the overload bit is set in r3's LSP
check_lsp_overload_bit("r3", "r3.00-00", "0/0/1")
# Check that overload timer is running
check_overload_timer("r3", True)
# Unset overload bit while timer is running
r3.vtysh_cmd(
"""
configure
router isis 1
no set-overload-bit
"""
)
# Check that overload timer is cancelled
check_overload_timer("r3", False)
# Check overload bit is unset
check_lsp_overload_bit("r3", "r3.00-00", "0/0/0")
def test_isis_overload_on_startup_override_timer():
"Check that overload bit remains set after overload timer expires if overload bit is configured"
tgen = get_topogen()
net = get_topogen().net
overload_time = 60
# Don't run this test if we have any failure.
if tgen.routers_have_failure():
pytest.skip(tgen.errors)
logger.info(
"Testing overload on startup behavior with set overload bit: override timer"
)
# Configure set-overload-bit on-startup on r3
r3 = tgen.gears["r3"]
r3.vtysh_cmd(
f"""
configure
router isis 1
set-overload-bit on-startup {overload_time}
set-overload-bit
"""
)
# Restart r3
logger.info("Stop router")
stop_router(tgen, "r3")
logger.info("Start router")
start_router(tgen, "r3")
# Check that the overload bit is set in r3's LSP
check_lsp_overload_bit("r3", "r3.00-00", "0/0/1")
# Check that overload timer is running
check_overload_timer("r3", True)
# Check that overload timer expired
check_overload_timer("r3", False)
# Check overload bit is still set
check_lsp_overload_bit("r3", "r3.00-00", "0/0/1")
@retry(retry_timeout=200)
def _check_lsp_overload_bit(router, overloaded_router_lsp, att_p_ol_expected):
"Verfiy overload bit in router's LSP"
tgen = get_topogen()
router = tgen.gears[router]
logger.info(f"check_overload_bit {router}")
isis_database_output = router.vtysh_cmd(
"show isis database {} json".format(overloaded_router_lsp)
)
database_json = json.loads(isis_database_output)
att_p_ol = database_json["areas"][0]["levels"][1]["att-p-ol"]
if att_p_ol == att_p_ol_expected:
return True
return "{} peer with expected att_p_ol {} got {} ".format(
router.name, att_p_ol_expected, att_p_ol
)
def check_lsp_overload_bit(router, overloaded_router_lsp, att_p_ol_expected):
"Verfiy overload bit in router's LSP"
assertmsg = _check_lsp_overload_bit(
router, overloaded_router_lsp, att_p_ol_expected
)
assert assertmsg is True, assertmsg
@retry(retry_timeout=200)
def _check_overload_timer(router, timer_expected):
"Verfiy overload bit in router's LSP"
tgen = get_topogen()
router = tgen.gears[router]
thread_output = router.vtysh_cmd("show thread timers")
timer_running = "set_overload_on_start_timer" in thread_output
if timer_running == timer_expected:
return True
return "Expected timer running status: {}".format(timer_expected)
def check_overload_timer(router, timer_expected):
"Verfiy overload bit in router's LSP"
assertmsg = _check_overload_timer(router, timer_expected)
assert assertmsg is True, assertmsg
def test_memory_leak():

View File

@ -1066,11 +1066,25 @@ module frr-isisd {
"If true, identify as L1/L2 router for inter-area traffic.";
}
leaf overload {
type boolean;
default "false";
container overload {
description
"If true, avoid any transit traffic.";
"Overload bit configuration.";
leaf enabled {
type boolean;
default "false";
description
"If true, avoid any transit traffic.";
}
leaf on-startup {
type uint32 {
range "0..86400";
}
units "seconds";
default "0";
description
"The duration the overload bit should be set on startup.";
}
}
leaf metric-style {