mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-04-28 17:01:51 +00:00
isisd: Add JSON object functions to save overload status between restarts.
Signed-off-by: Isabella de Leon <ideleon@microsoft.com>
This commit is contained in:
parent
4afc783610
commit
450841fe05
@ -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])
|
||||
|
@ -1372,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;
|
||||
@ -1380,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) {
|
||||
@ -1448,20 +1461,6 @@ static int lsp_regenerate(struct isis_area *area, int level)
|
||||
if ((area == NULL) || (area->is_type & level) != level)
|
||||
return ISIS_ERROR;
|
||||
|
||||
/*
|
||||
* Check if the device is initializing and set overload bit on startup
|
||||
* is configured.
|
||||
*/
|
||||
if (device_startup) {
|
||||
if (area->overload_on_startup_time > 0) {
|
||||
isis_area_overload_bit_set(area, true);
|
||||
thread_add_timer(master, set_overload_on_start_timer,
|
||||
area, area->overload_on_startup_time,
|
||||
&area->t_overload_on_startup_timer);
|
||||
}
|
||||
device_startup = false;
|
||||
}
|
||||
|
||||
head = &area->lspdb[level - 1];
|
||||
memset(lspid, 0, ISIS_SYS_ID_LEN + 2);
|
||||
memcpy(lspid, area->isis->sysid, ISIS_SYS_ID_LEN);
|
||||
|
@ -3214,8 +3214,104 @@ 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)
|
||||
{
|
||||
if (area->overload_on_startup_time != 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)
|
||||
|
@ -319,7 +319,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"
|
||||
|
@ -436,35 +436,6 @@ def test_isis_overload_on_startup():
|
||||
assert result
|
||||
|
||||
|
||||
@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
|
||||
|
||||
|
||||
def test_isis_overload_on_startup_cancel_timer():
|
||||
"Check that overload on startup timer is cancelled when overload bit is set/unset"
|
||||
|
||||
@ -476,7 +447,9 @@ def test_isis_overload_on_startup_cancel_timer():
|
||||
if tgen.routers_have_failure():
|
||||
pytest.skip(tgen.errors)
|
||||
|
||||
logger.info("Testing overload on startup behavior with set overload bit: cancel timer")
|
||||
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"]
|
||||
@ -527,7 +500,9 @@ def test_isis_overload_on_startup_override_timer():
|
||||
if tgen.routers_have_failure():
|
||||
pytest.skip(tgen.errors)
|
||||
|
||||
logger.info("Testing overload on startup behavior with set overload bit: override timer")
|
||||
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"]
|
||||
@ -558,15 +533,42 @@ def test_isis_overload_on_startup_override_timer():
|
||||
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"
|
||||
)
|
||||
thread_output = router.vtysh_cmd("show thread timers")
|
||||
|
||||
timer_running = "set_overload_on_start_timer" in thread_output
|
||||
if timer_running == timer_expected:
|
||||
@ -577,9 +579,7 @@ def _check_overload_timer(router, timer_expected):
|
||||
def check_overload_timer(router, timer_expected):
|
||||
"Verfiy overload bit in router's LSP"
|
||||
|
||||
assertmsg = _check_overload_timer(
|
||||
router, timer_expected
|
||||
)
|
||||
assertmsg = _check_overload_timer(router, timer_expected)
|
||||
assert assertmsg is True, assertmsg
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user