Skip to content

Commit

Permalink
Merge pull request #12650 from isabelladeleon12/advertise_high_metrics
Browse files Browse the repository at this point in the history
isisd: Add support for advertise-high-metrics
  • Loading branch information
riw777 authored Mar 2, 2023
2 parents 48cdfc1 + 102a6e2 commit 15424f5
Show file tree
Hide file tree
Showing 19 changed files with 711 additions and 0 deletions.
6 changes: 6 additions & 0 deletions doc/user/isisd.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
4 changes: 4 additions & 0 deletions isisd/isis_circuit.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
25 changes: 25 additions & 0 deletions isisd/isis_cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -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);
Expand Down
7 changes: 7 additions & 0 deletions isisd/isis_nb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down
4 changes: 4 additions & 0 deletions isisd/isis_nb.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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,
Expand Down
18 changes: 18 additions & 0 deletions isisd/isis_nb_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down
55 changes: 55 additions & 0 deletions isisd/isisd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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.
Expand Down
4 changes: 4 additions & 0 deletions isisd/isisd.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
Empty file.
19 changes: 19 additions & 0 deletions tests/topotests/isis_advertise_high_metrics/r1/isisd.conf
Original file line number Diff line number Diff line change
@@ -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
!
5 changes: 5 additions & 0 deletions tests/topotests/isis_advertise_high_metrics/r1/zebra.conf
Original file line number Diff line number Diff line change
@@ -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 changes: 18 additions & 0 deletions tests/topotests/isis_advertise_high_metrics/r2/isisd.conf
Original file line number Diff line number Diff line change
@@ -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
!
5 changes: 5 additions & 0 deletions tests/topotests/isis_advertise_high_metrics/r2/zebra.conf
Original file line number Diff line number Diff line change
@@ -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 changes: 20 additions & 0 deletions tests/topotests/isis_advertise_high_metrics/r3/isisd.conf
Original file line number Diff line number Diff line change
@@ -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
!
5 changes: 5 additions & 0 deletions tests/topotests/isis_advertise_high_metrics/r3/zebra.conf
Original file line number Diff line number Diff line change
@@ -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 changes: 19 additions & 0 deletions tests/topotests/isis_advertise_high_metrics/r4/isisd.conf
Original file line number Diff line number Diff line change
@@ -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
!
5 changes: 5 additions & 0 deletions tests/topotests/isis_advertise_high_metrics/r4/zebra.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
interface eth-r2
ip address 192.168.1.6/31

interface eth-r3
ip address 192.168.1.5/31
Loading

0 comments on commit 15424f5

Please sign in to comment.