From 7c4755176342ae490e1372902c2455d34153067e Mon Sep 17 00:00:00 2001 From: Isabella de Leon Date: Tue, 10 Jan 2023 17:58:29 -0800 Subject: [PATCH] isisd: Add advertise high metrics base functionality Implement advertise-high-metrics set function - when advertise-high-metrics is configured, iterate through each isis interface and update each metric to its high metric value. When advertise-high-metrics is disabled, revert each interface's metric to its originally configured value. Signed-off-by: Isabella de Leon --- isisd/isis_circuit.c | 4 ++++ isisd/isisd.c | 48 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c index dd5f921bef..8644da2f08 100644 --- a/isisd/isis_circuit.c +++ b/isisd/isis_circuit.c @@ -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. diff --git a/isisd/isisd.c b/isisd/isisd.c index 523333300f..586785b05f 100644 --- a/isisd/isisd.c +++ b/isisd/isisd.c @@ -3253,7 +3253,53 @@ void config_end_lsp_generate(struct isis_area *area) void isis_area_advertise_high_metrics_set(struct isis_area *area, bool advertise_high_metrics) { - /* TODO */ + 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); + } + } } /* -- 2.39.5