mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-13 21:10:28 +00:00
Merge pull request #12650 from isabelladeleon12/advertise_high_metrics
isisd: Add support for advertise-high-metrics
This commit is contained in:
commit
15424f55f3
@ -79,6 +79,12 @@ writing, *isisd* does not support multiple ISIS processes.
|
||||
- wide
|
||||
Use new style of TLVs to carry wider metric. FRR uses this as a default value
|
||||
|
||||
.. clicmd:: advertise-high-metrics
|
||||
|
||||
Advertise high metric value on all interfaces to gracefully shift traffic off the router. Reference: :rfc:`3277`
|
||||
|
||||
For narrow metrics, the high metric value is 63; for wide metrics, 16777215; for transition metrics, 62.
|
||||
|
||||
.. clicmd:: set-overload-bit
|
||||
|
||||
Set overload bit to avoid any transit traffic.
|
||||
|
@ -1499,6 +1499,10 @@ ferr_r isis_circuit_metric_set(struct isis_circuit *circuit, int level,
|
||||
return ferr_cfg_invalid("metric %d too large for narrow metric",
|
||||
metric);
|
||||
|
||||
/* Don't modify metric if advertise high metrics is configured */
|
||||
if (circuit->area && circuit->area->advertise_high_metrics)
|
||||
return ferr_ok();
|
||||
|
||||
/* inform ldp-sync of metric change
|
||||
* if ldp-sync is running need to save metric
|
||||
* and restore new values after ldp-sync completion.
|
||||
|
@ -439,6 +439,29 @@ void cli_show_isis_overload_on_startup(struct vty *vty,
|
||||
yang_dnode_get_string(dnode, NULL));
|
||||
}
|
||||
|
||||
/*
|
||||
* XPath: /frr-isisd:isis/instance/advertise-high-metrics
|
||||
*/
|
||||
DEFPY_YANG(advertise_high_metrics, advertise_high_metrics_cmd,
|
||||
"[no] advertise-high-metrics",
|
||||
NO_STR "Advertise high metric value on all interfaces\n")
|
||||
{
|
||||
nb_cli_enqueue_change(vty, "./advertise-high-metrics", NB_OP_MODIFY,
|
||||
no ? "false" : "true");
|
||||
|
||||
return nb_cli_apply_changes(vty, NULL);
|
||||
}
|
||||
|
||||
void cli_show_advertise_high_metrics(struct vty *vty,
|
||||
const struct lyd_node *dnode,
|
||||
bool show_defaults)
|
||||
{
|
||||
if (yang_dnode_get_bool(dnode, NULL))
|
||||
vty_out(vty, " advertise-high-metrics\n");
|
||||
else if (show_defaults)
|
||||
vty_out(vty, " no advertise-high-metrics\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* XPath: /frr-isisd:isis/instance/attach-send
|
||||
*/
|
||||
@ -3160,6 +3183,8 @@ void isis_cli_init(void)
|
||||
install_element(ISIS_NODE, &metric_style_cmd);
|
||||
install_element(ISIS_NODE, &no_metric_style_cmd);
|
||||
|
||||
install_element(ISIS_NODE, &advertise_high_metrics_cmd);
|
||||
|
||||
install_element(ISIS_NODE, &area_passwd_cmd);
|
||||
install_element(ISIS_NODE, &domain_passwd_cmd);
|
||||
install_element(ISIS_NODE, &no_area_passwd_cmd);
|
||||
|
@ -81,6 +81,13 @@ const struct frr_yang_module_info frr_isisd_info = {
|
||||
.modify = isis_instance_overload_on_startup_modify,
|
||||
}
|
||||
},
|
||||
{
|
||||
.xpath = "/frr-isisd:isis/instance/advertise-high-metrics",
|
||||
.cbs = {
|
||||
.cli_show = cli_show_advertise_high_metrics,
|
||||
.modify = isis_instance_advertise_high_metrics_modify,
|
||||
}
|
||||
},
|
||||
{
|
||||
.xpath = "/frr-isisd:isis/instance/metric-style",
|
||||
.cbs = {
|
||||
|
@ -26,6 +26,7 @@ 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_enabled_modify(struct nb_cb_modify_args *args);
|
||||
int isis_instance_overload_on_startup_modify(struct nb_cb_modify_args *args);
|
||||
int isis_instance_advertise_high_metrics_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);
|
||||
@ -464,6 +465,9 @@ void cli_show_isis_overload(struct vty *vty, const struct lyd_node *dnode,
|
||||
void cli_show_isis_overload_on_startup(struct vty *vty,
|
||||
const struct lyd_node *dnode,
|
||||
bool show_defaults);
|
||||
void cli_show_advertise_high_metrics(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,
|
||||
|
@ -360,6 +360,24 @@ int isis_instance_overload_on_startup_modify(struct nb_cb_modify_args *args)
|
||||
return NB_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* XPath: /frr-isisd:isis/instance/advertise-high-metrics
|
||||
*/
|
||||
int isis_instance_advertise_high_metrics_modify(struct nb_cb_modify_args *args)
|
||||
{
|
||||
struct isis_area *area;
|
||||
bool advertise_high_metrics;
|
||||
|
||||
if (args->event != NB_EV_APPLY)
|
||||
return NB_OK;
|
||||
|
||||
advertise_high_metrics = yang_dnode_get_bool(args->dnode, NULL);
|
||||
area = nb_running_get_entry(args->dnode, NULL, true);
|
||||
isis_area_advertise_high_metrics_set(area, advertise_high_metrics);
|
||||
|
||||
return NB_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* XPath: /frr-isisd:isis/instance/metric-style
|
||||
*/
|
||||
|
@ -2503,6 +2503,9 @@ static void common_isis_summary_vty(struct vty *vty, struct isis *isis)
|
||||
vty_out(vty, " RX counters per PDU type:\n");
|
||||
pdu_counter_print(vty, " ", area->pdu_rx_counters);
|
||||
|
||||
vty_out(vty, " Advertise high metrics: %s\n",
|
||||
area->advertise_high_metrics ? "Enabled" : "Disabled");
|
||||
|
||||
for (level = ISIS_LEVEL1; level <= ISIS_LEVELS; level++) {
|
||||
if ((area->is_type & level) == 0)
|
||||
continue;
|
||||
@ -3247,6 +3250,58 @@ void config_end_lsp_generate(struct isis_area *area)
|
||||
}
|
||||
}
|
||||
|
||||
void isis_area_advertise_high_metrics_set(struct isis_area *area,
|
||||
bool advertise_high_metrics)
|
||||
{
|
||||
struct listnode *node;
|
||||
struct isis_circuit *circuit;
|
||||
int max_metric;
|
||||
char xpath[XPATH_MAXLEN];
|
||||
struct lyd_node *dnode;
|
||||
int configured_metric_l1;
|
||||
int configured_metric_l2;
|
||||
|
||||
if (area->advertise_high_metrics == advertise_high_metrics)
|
||||
return;
|
||||
|
||||
if (advertise_high_metrics) {
|
||||
if (area->oldmetric && area->newmetric)
|
||||
max_metric = ISIS_NARROW_METRIC_INFINITY;
|
||||
else if (area->newmetric)
|
||||
max_metric = MAX_WIDE_LINK_METRIC;
|
||||
else
|
||||
max_metric = MAX_NARROW_LINK_METRIC;
|
||||
|
||||
for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) {
|
||||
isis_circuit_metric_set(circuit, IS_LEVEL_1,
|
||||
max_metric);
|
||||
isis_circuit_metric_set(circuit, IS_LEVEL_2,
|
||||
max_metric);
|
||||
}
|
||||
|
||||
area->advertise_high_metrics = true;
|
||||
} else {
|
||||
area->advertise_high_metrics = false;
|
||||
for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) {
|
||||
/* Get configured metric */
|
||||
snprintf(xpath, XPATH_MAXLEN,
|
||||
"/frr-interface:lib/interface[name='%s']",
|
||||
circuit->interface->name);
|
||||
dnode = yang_dnode_get(running_config->dnode, xpath);
|
||||
|
||||
configured_metric_l1 = yang_dnode_get_uint32(
|
||||
dnode, "./frr-isisd:isis/metric/level-1");
|
||||
configured_metric_l2 = yang_dnode_get_uint32(
|
||||
dnode, "./frr-isisd:isis/metric/level-2");
|
||||
|
||||
isis_circuit_metric_set(circuit, IS_LEVEL_1,
|
||||
configured_metric_l1);
|
||||
isis_circuit_metric_set(circuit, IS_LEVEL_2,
|
||||
configured_metric_l2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the path of the file (non-volatile memory) that contains restart
|
||||
* information.
|
||||
|
@ -175,6 +175,8 @@ struct isis_area {
|
||||
uint32_t overload_on_startup_time;
|
||||
/* advertise prefixes of passive interfaces only? */
|
||||
bool advertise_passive_only;
|
||||
/* Are we advertising high metrics? */
|
||||
bool advertise_high_metrics;
|
||||
/* L1/L2 router identifier for inter-area traffic */
|
||||
char attached_bit_send;
|
||||
char attached_bit_rcv_ignore;
|
||||
@ -289,6 +291,8 @@ void isis_area_switchover_routes(struct isis_area *area, int family,
|
||||
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_advertise_high_metrics_set(struct isis_area *area,
|
||||
bool advertise_high_metrics);
|
||||
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);
|
||||
|
19
tests/topotests/isis_advertise_high_metrics/r1/isisd.conf
Normal file
19
tests/topotests/isis_advertise_high_metrics/r1/isisd.conf
Normal file
@ -0,0 +1,19 @@
|
||||
hostname r1
|
||||
! debug isis adj-packets
|
||||
! debug isis events
|
||||
! debug isis update-packets
|
||||
interface eth-r2
|
||||
ip router isis 1
|
||||
isis circuit-type level-2-only
|
||||
isis network point-to-point
|
||||
!
|
||||
interface eth-r3
|
||||
ip router isis 1
|
||||
isis circuit-type level-2-only
|
||||
isis metric 20
|
||||
isis network point-to-point
|
||||
!
|
||||
router isis 1
|
||||
is-type level-2-only
|
||||
net 10.0000.0000.0000.0000.0000.0000.0000.0000.0000.00
|
||||
!
|
@ -0,0 +1,5 @@
|
||||
interface eth-r2
|
||||
ip address 192.168.1.0/31
|
||||
|
||||
interface eth-r3
|
||||
ip address 192.168.1.2/31
|
18
tests/topotests/isis_advertise_high_metrics/r2/isisd.conf
Normal file
18
tests/topotests/isis_advertise_high_metrics/r2/isisd.conf
Normal file
@ -0,0 +1,18 @@
|
||||
hostname r2
|
||||
! debug isis adj-packets
|
||||
! debug isis events
|
||||
! debug isis update-packets
|
||||
interface eth-r1
|
||||
ip router isis 1
|
||||
isis circuit-type level-2-only
|
||||
isis network point-to-point
|
||||
!
|
||||
interface eth-r4
|
||||
ip router isis 1
|
||||
isis circuit-type level-2-only
|
||||
isis network point-to-point
|
||||
!
|
||||
router isis 1
|
||||
is-type level-2-only
|
||||
net 10.0000.0000.0000.0000.0000.0000.0000.0000.0001.00
|
||||
!
|
@ -0,0 +1,5 @@
|
||||
interface eth-r1
|
||||
ip address 192.168.1.1/31
|
||||
|
||||
interface eth-r4
|
||||
ip address 192.168.1.7/31
|
20
tests/topotests/isis_advertise_high_metrics/r3/isisd.conf
Normal file
20
tests/topotests/isis_advertise_high_metrics/r3/isisd.conf
Normal file
@ -0,0 +1,20 @@
|
||||
hostname r3
|
||||
! debug isis adj-packets
|
||||
! debug isis events
|
||||
! debug isis update-packets
|
||||
interface eth-r1
|
||||
ip router isis 1
|
||||
isis circuit-type level-2-only
|
||||
isis metric 20
|
||||
isis network point-to-point
|
||||
!
|
||||
interface eth-r4
|
||||
ip router isis 1
|
||||
isis circuit-type level-2-only
|
||||
isis metric 20
|
||||
isis network point-to-point
|
||||
!
|
||||
router isis 1
|
||||
is-type level-2-only
|
||||
net 10.0000.0000.0000.0000.0000.0000.0000.0000.0002.00
|
||||
!
|
@ -0,0 +1,5 @@
|
||||
interface eth-r1
|
||||
ip address 192.168.1.3/31
|
||||
|
||||
interface eth-r4
|
||||
ip address 192.168.1.4/31
|
19
tests/topotests/isis_advertise_high_metrics/r4/isisd.conf
Normal file
19
tests/topotests/isis_advertise_high_metrics/r4/isisd.conf
Normal file
@ -0,0 +1,19 @@
|
||||
hostname r4
|
||||
! debug isis adj-packets
|
||||
! debug isis events
|
||||
! debug isis update-packets
|
||||
interface eth-r2
|
||||
ip router isis 1
|
||||
isis circuit-type level-2-only
|
||||
isis network point-to-point
|
||||
!
|
||||
interface eth-r3
|
||||
ip router isis 1
|
||||
isis circuit-type level-2-only
|
||||
isis metric 20
|
||||
isis network point-to-point
|
||||
!
|
||||
router isis 1
|
||||
is-type level-2-only
|
||||
net 10.0000.0000.0000.0000.0000.0000.0000.0000.0003.00
|
||||
!
|
@ -0,0 +1,5 @@
|
||||
interface eth-r2
|
||||
ip address 192.168.1.6/31
|
||||
|
||||
interface eth-r3
|
||||
ip address 192.168.1.5/31
|
@ -0,0 +1,485 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
#
|
||||
# test_isis_advertise_high_metrics.py
|
||||
# Part of NetDEF Topology Tests
|
||||
#
|
||||
# Copyright (c) 2020 by Volta Networks
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
r"""
|
||||
test_isis_advertise_high_metrics.py: Advertise High Metrics FRR ISIS Test
|
||||
"""
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import pytest
|
||||
import json
|
||||
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.common_config import (
|
||||
retry,
|
||||
stop_router,
|
||||
start_router,
|
||||
)
|
||||
from lib.topogen import Topogen, TopoRouter, get_topogen
|
||||
from lib.topolog import logger
|
||||
|
||||
# Required to instantiate the topology builder class.
|
||||
|
||||
pytestmark = [pytest.mark.isisd]
|
||||
|
||||
|
||||
def build_topo(tgen):
|
||||
"Build function"
|
||||
|
||||
# Add ISIS routers:
|
||||
# r2
|
||||
# / \
|
||||
# r1 r4
|
||||
# \ /
|
||||
# r3
|
||||
|
||||
#
|
||||
# Define FRR Routers
|
||||
#
|
||||
for router in ["r1", "r2", "r3", "r4"]:
|
||||
tgen.add_router(router)
|
||||
#
|
||||
# Define connections
|
||||
#
|
||||
switch = tgen.add_switch("s0")
|
||||
switch.add_link(tgen.gears["r1"], nodeif="eth-r2")
|
||||
switch.add_link(tgen.gears["r2"], nodeif="eth-r1")
|
||||
|
||||
switch = tgen.add_switch("s1")
|
||||
switch.add_link(tgen.gears["r1"], nodeif="eth-r3")
|
||||
switch.add_link(tgen.gears["r3"], nodeif="eth-r1")
|
||||
|
||||
switch = tgen.add_switch("s2")
|
||||
switch.add_link(tgen.gears["r2"], nodeif="eth-r4")
|
||||
switch.add_link(tgen.gears["r4"], nodeif="eth-r2")
|
||||
|
||||
switch = tgen.add_switch("s3")
|
||||
switch.add_link(tgen.gears["r3"], nodeif="eth-r4")
|
||||
switch.add_link(tgen.gears["r4"], nodeif="eth-r3")
|
||||
|
||||
|
||||
def setup_module(mod):
|
||||
"Sets up the pytest environment"
|
||||
tgen = Topogen(build_topo, mod.__name__)
|
||||
tgen.start_topology()
|
||||
|
||||
# For all registered routers, load the zebra configuration file
|
||||
for rname, router in tgen.routers().items():
|
||||
router.load_config(
|
||||
TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
|
||||
)
|
||||
router.load_config(
|
||||
TopoRouter.RD_ISIS, os.path.join(CWD, "{}/isisd.conf".format(rname))
|
||||
)
|
||||
|
||||
# After loading the configurations, this function loads configured daemons.
|
||||
tgen.start_router()
|
||||
|
||||
|
||||
def teardown_module(mod):
|
||||
"Teardown the pytest environment"
|
||||
tgen = get_topogen()
|
||||
|
||||
# This function tears down the whole topology.
|
||||
tgen.stop_topology()
|
||||
|
||||
|
||||
@retry(retry_timeout=60)
|
||||
def _check_interface_metrics(router, expected_metrics):
|
||||
"Verfiy metrics on router's isis interfaces"
|
||||
|
||||
tgen = get_topogen()
|
||||
router = tgen.gears[router]
|
||||
logger.info(f"check_interface_metrics {router}")
|
||||
isis_interface_output = router.vtysh_cmd(
|
||||
"show isis interface detail json"
|
||||
)
|
||||
|
||||
intf_json = json.loads(isis_interface_output)
|
||||
for i in range(len(expected_metrics)):
|
||||
metric = intf_json["areas"][0]["circuits"][i]["interface"]["levels"][0]["metric"]
|
||||
if (metric != expected_metrics[i]):
|
||||
intf_name = intf_json["areas"][0]["circuits"][i]["interface"]["name"]
|
||||
return "{} with expected metric {} on {} got {}".format(
|
||||
router.name, expected_metrics[i], intf_name, metric
|
||||
)
|
||||
return True
|
||||
|
||||
|
||||
def check_interface_metrics(router, expected_metrics):
|
||||
"Verfiy metrics on router's isis interfaces"
|
||||
|
||||
assertmsg = _check_interface_metrics(
|
||||
router, expected_metrics
|
||||
)
|
||||
assert assertmsg is True, assertmsg
|
||||
|
||||
|
||||
@retry(retry_timeout=60)
|
||||
def _check_lsp_metrics(router, lsp, expected_metrics):
|
||||
"Verfiy metrics on router's lsp"
|
||||
tgen = get_topogen()
|
||||
router = tgen.gears[router]
|
||||
logger.info(f"check_lsp_metrics {router}")
|
||||
isis_lsp_output = router.vtysh_cmd(
|
||||
"show isis database detail {}".format(lsp)
|
||||
)
|
||||
|
||||
metrics_list = [int(i) for i in re.findall(r"Metric: (\d+)", isis_lsp_output)]
|
||||
if len(metrics_list) == 0:
|
||||
return False
|
||||
for metric in metrics_list:
|
||||
if metric not in expected_metrics:
|
||||
return "{} with expected metrics {} got {}".format(
|
||||
router.name, expected_metrics, metrics_list
|
||||
)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def check_lsp_metrics(router, lsp, expected_metrics):
|
||||
"Verfiy metrics on router's lsp"
|
||||
|
||||
assertmsg = _check_lsp_metrics(
|
||||
router, lsp, expected_metrics
|
||||
)
|
||||
assert assertmsg is True, assertmsg
|
||||
|
||||
|
||||
@retry(retry_timeout=60)
|
||||
def _check_ip_route(router, destination, expected_interface):
|
||||
"Verfiy IS-IS route"
|
||||
|
||||
tgen = get_topogen()
|
||||
router = tgen.gears[router]
|
||||
logger.info(f"check_ip_route {router}")
|
||||
route_output = router.vtysh_cmd(
|
||||
"show ip route {} json".format(destination)
|
||||
)
|
||||
route_json = json.loads(route_output)
|
||||
|
||||
interface = route_json[destination][0]["nexthops"][0]["interfaceName"]
|
||||
|
||||
if (interface != expected_interface):
|
||||
return "{} with expected route to {} got {} expected {}".format(
|
||||
router.name, destination, interface, expected_interface
|
||||
)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def check_ip_route(router, destination, expected_interface):
|
||||
"Verfiy IS-IS route"
|
||||
|
||||
assertmsg = _check_ip_route(
|
||||
router, destination, expected_interface
|
||||
)
|
||||
assert assertmsg is True, assertmsg
|
||||
|
||||
|
||||
def test_isis_daemon_up():
|
||||
"Check isis daemon up before starting test"
|
||||
tgen = get_topogen()
|
||||
# Don't run this test if we have any failure.
|
||||
if tgen.routers_have_failure():
|
||||
pytest.skip(tgen.errors)
|
||||
|
||||
for router in ["r1", "r2", "r3", "r4"]:
|
||||
r = tgen.gears[router]
|
||||
daemons = r.vtysh_cmd(
|
||||
"show daemons"
|
||||
)
|
||||
assert "isisd" in daemons
|
||||
|
||||
# Verify initial metric values.
|
||||
check_lsp_metrics("r1", "r1.00-00", [10, 20])
|
||||
check_lsp_metrics("r2", "r2.00-00", [10, 10])
|
||||
check_lsp_metrics("r3", "r3.00-00", [20, 20])
|
||||
check_lsp_metrics("r4", "r4.00-00", [10, 20])
|
||||
|
||||
|
||||
def test_isis_advertise_high_metrics():
|
||||
"Check that advertise high metrics behaves as expected"
|
||||
|
||||
tgen = get_topogen()
|
||||
net = get_topogen().net
|
||||
|
||||
# Don't run this test if we have any failure.
|
||||
if tgen.routers_have_failure():
|
||||
pytest.skip(tgen.errors)
|
||||
|
||||
logger.info("Testing advertise high metrics basic behavior")
|
||||
|
||||
# Confirm low metrics values on each isis interface on r1
|
||||
r1 = tgen.gears["r1"]
|
||||
check_interface_metrics("r1", [10, 20])
|
||||
|
||||
# Confirm low metrics values within isis database on r1
|
||||
check_lsp_metrics("r1", "r1.00-00", [10, 20])
|
||||
|
||||
# Configure advertise high metrics
|
||||
r1.vtysh_cmd(
|
||||
f"""
|
||||
configure
|
||||
router isis 1
|
||||
advertise-high-metrics
|
||||
"""
|
||||
)
|
||||
|
||||
# Confirm high wide metrics values on each isis interface on r1
|
||||
check_interface_metrics("r1", [16777215])
|
||||
|
||||
# Confirm high wide metrics values within isis database on r1
|
||||
check_lsp_metrics("r1", "r1.00-00", [16777215])
|
||||
|
||||
# Remove advertise high metrics
|
||||
r1.vtysh_cmd(
|
||||
f"""
|
||||
configure
|
||||
router isis 1
|
||||
no advertise-high-metrics
|
||||
"""
|
||||
)
|
||||
|
||||
# Confirm low metrics values on each isis interface on r1
|
||||
check_interface_metrics("r1", [10, 20])
|
||||
|
||||
# Confirm low metrics values within isis database on r1
|
||||
check_lsp_metrics("r1", "r1.00-00", [10, 20])
|
||||
|
||||
|
||||
def test_isis_advertise_high_metrics_narrow():
|
||||
"Check that advertise high metrics behaves as expected with narrow metrics"
|
||||
|
||||
tgen = get_topogen()
|
||||
net = get_topogen().net
|
||||
|
||||
# Don't run this test if we have any failure.
|
||||
if tgen.routers_have_failure():
|
||||
pytest.skip(tgen.errors)
|
||||
|
||||
logger.info("Testing advertise high metrics with narrow metric style")
|
||||
|
||||
r1 = tgen.gears["r1"]
|
||||
|
||||
# Configure narrow metric-style
|
||||
r1.vtysh_cmd(
|
||||
f"""
|
||||
configure
|
||||
router isis 1
|
||||
metric-style narrow
|
||||
"""
|
||||
)
|
||||
|
||||
# Confirm low metrics values on each isis interface on r1
|
||||
check_interface_metrics("r1", [10, 20])
|
||||
|
||||
# Confirm low metrics values within isis database on r1
|
||||
check_lsp_metrics("r1", "r1.00-00", [10, 20])
|
||||
|
||||
# Configure advertise high metrics
|
||||
r1.vtysh_cmd(
|
||||
f"""
|
||||
configure
|
||||
router isis 1
|
||||
advertise-high-metrics
|
||||
"""
|
||||
)
|
||||
|
||||
# Confirm high narrow metrics values on each isis interface on r1
|
||||
check_interface_metrics("r1", [63])
|
||||
|
||||
# Confirm high narrow metrics values within isis database on r1
|
||||
check_lsp_metrics("r1", "r1.00-00", [63])
|
||||
|
||||
# Remove advertise high metrics
|
||||
r1.vtysh_cmd(
|
||||
f"""
|
||||
configure
|
||||
router isis 1
|
||||
no advertise-high-metrics
|
||||
"""
|
||||
)
|
||||
|
||||
# Confirm low metrics values on each isis interface on r1
|
||||
check_interface_metrics("r1", [10, 20])
|
||||
|
||||
# Confirm low metrics values within isis database on r1
|
||||
check_lsp_metrics("r1", "r1.00-00", [10, 20])
|
||||
|
||||
# Remove narrow metric-style
|
||||
r1.vtysh_cmd(
|
||||
f"""
|
||||
configure
|
||||
router isis 1
|
||||
no metric-style narrow
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def test_isis_advertise_high_metrics_transition():
|
||||
"Check that advertise high metrics behaves as expected with transition metrics"
|
||||
tgen = get_topogen()
|
||||
net = get_topogen().net
|
||||
|
||||
# Don't run this test if we have any failure.
|
||||
if tgen.routers_have_failure():
|
||||
pytest.skip(tgen.errors)
|
||||
|
||||
logger.info("Testing advertise high metrics with transition metric style")
|
||||
|
||||
r1 = tgen.gears["r1"]
|
||||
|
||||
# Configure transition metric-style
|
||||
r1.vtysh_cmd(
|
||||
f"""
|
||||
configure
|
||||
router isis 1
|
||||
metric-style transition
|
||||
"""
|
||||
)
|
||||
|
||||
# Confirm low metrics values on each isis interface on r1
|
||||
check_interface_metrics("r1", [10, 20])
|
||||
|
||||
# Confirm low metrics values within isis database on r1
|
||||
check_lsp_metrics("r1", "r1.00-00", [10, 20])
|
||||
|
||||
# Configure advertise high metrics
|
||||
r1.vtysh_cmd(
|
||||
f"""
|
||||
configure
|
||||
router isis 1
|
||||
advertise-high-metrics
|
||||
"""
|
||||
)
|
||||
|
||||
# Confirm high transition metrics values on each isis interface on r1
|
||||
check_interface_metrics("r1", [62])
|
||||
|
||||
# Confirm high transition metrics values within isis database on r1
|
||||
check_lsp_metrics("r1", "r1.00-00", [62])
|
||||
|
||||
# Remove advertise high metrics
|
||||
r1.vtysh_cmd(
|
||||
f"""
|
||||
configure
|
||||
router isis 1
|
||||
no advertise-high-metrics
|
||||
"""
|
||||
)
|
||||
|
||||
# Confirm low metrics values on each isis interface on r1
|
||||
check_interface_metrics("r1", [10, 20])
|
||||
|
||||
# Confirm low metrics values within isis database on r1
|
||||
check_lsp_metrics("r1", "r1.00-00", [10, 20])
|
||||
|
||||
# Remove narrow metric-style
|
||||
r1.vtysh_cmd(
|
||||
f"""
|
||||
configure
|
||||
router isis 1
|
||||
no metric-style transition
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def test_isis_advertise_high_metrics_route():
|
||||
"""
|
||||
Topology:
|
||||
|
||||
r2
|
||||
/ \
|
||||
r1 r4
|
||||
\ /
|
||||
r3
|
||||
|
||||
Devices are configured with preferred route between r1 and r4:
|
||||
r1 -> r2 -> r4
|
||||
Configure "advertise-high-metrics" on r2 and check that preferred route is:
|
||||
r1 -> r3 -> r4.
|
||||
Shut r3 and check that preferred route is:
|
||||
r1 -> r2 -> r4.
|
||||
"""
|
||||
tgen = get_topogen()
|
||||
net = get_topogen().net
|
||||
|
||||
# Don't run this test if we have any failure.
|
||||
if tgen.routers_have_failure():
|
||||
pytest.skip(tgen.errors)
|
||||
|
||||
logger.info("Testing advertise high metrics route behavior")
|
||||
|
||||
r1 = tgen.gears["r1"]
|
||||
r2 = tgen.gears["r2"]
|
||||
|
||||
# Verify the preferred path from r1 to r4 (192.168.1.6) is currently via 192.168.1.1, eth-r2
|
||||
check_ip_route("r1", "192.168.1.6/31", "eth-r2")
|
||||
|
||||
# Configure advertise high metrics on r2
|
||||
r2.vtysh_cmd(
|
||||
f"""
|
||||
configure
|
||||
router isis 1
|
||||
advertise-high-metrics
|
||||
"""
|
||||
)
|
||||
|
||||
# Verify the preferred path from r1 to r4 (192.168.1.6) is now via 192.168.1.3, eth-r3
|
||||
check_ip_route("r1", "192.168.1.6/31", "eth-r3")
|
||||
|
||||
# Shutdown r3
|
||||
logger.info("Stop router r3")
|
||||
stop_router(tgen, "r3")
|
||||
|
||||
# Verify the preferred path from r1 to r4 (192.168.1.6) is now via 192.168.1.1, eth-r2
|
||||
check_ip_route("r1", "192.168.1.6/31", "eth-r2")
|
||||
|
||||
# Start r3
|
||||
logger.info("Start router r3")
|
||||
start_router(tgen, "r3")
|
||||
|
||||
|
||||
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))
|
@ -1169,6 +1169,13 @@ module frr-isisd {
|
||||
"Define the style of TLVs metric supported.";
|
||||
}
|
||||
|
||||
leaf advertise-high-metrics {
|
||||
type boolean;
|
||||
default "false";
|
||||
description
|
||||
"Advertise high metric value on all interfaces.";
|
||||
}
|
||||
|
||||
leaf purge-originator {
|
||||
type boolean;
|
||||
default "false";
|
||||
|
Loading…
Reference in New Issue
Block a user