]> git.puffer.fish Git - matthieu/frr.git/commitdiff
isisd: Add advertise high metrics base functionality
authorIsabella de Leon <ideleon@microsoft.com>
Wed, 11 Jan 2023 01:58:29 +0000 (17:58 -0800)
committerIsabella de Leon <ideleon@microsoft.com>
Tue, 28 Feb 2023 19:39:12 +0000 (11:39 -0800)
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 <ideleon@microsoft.com>
isisd/isis_circuit.c
isisd/isisd.c

index dd5f921bef38a40fe51a9ed1aeab410c8c1ac5f4..8644da2f085375babe35b36aba87557cc513fca1 100644 (file)
@@ -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.
index 523333300f82ca90afb68daaefd8d4dee2382940..586785b05f21908001fb1b8a5b69f7d7d000e877 100644 (file)
@@ -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);
+               }
+       }
 }
 
 /*