#include "isisd/fabricd.h"
#include "isisd/isis_tx_queue.h"
#include "isisd/isis_nb.h"
+#include "isisd/isis_flex_algo.h"
DEFINE_MTYPE_STATIC(ISISD, ISIS_LSP, "ISIS LSP");
return refresh_time;
}
+static void lsp_build_internal_reach_ipv4(struct isis_lsp *lsp,
+ struct isis_area *area,
+ struct prefix_ipv4 *ipv4,
+ uint32_t metric)
+{
+ struct sr_prefix_cfg *pcfgs[SR_ALGORITHM_COUNT] = {NULL};
+
+ if (area->oldmetric) {
+ lsp_debug(
+ "ISIS (%s): Adding old-style IP reachability for %pFX",
+ area->area_tag, ipv4);
+ isis_tlvs_add_oldstyle_ip_reach(lsp->tlvs, ipv4, metric);
+ }
+
+ if (area->newmetric) {
+ lsp_debug("ISIS (%s): Adding te-style IP reachability for %pFX",
+ area->area_tag, ipv4);
+
+ if (area->srdb.enabled)
+ for (int i = 0; i < SR_ALGORITHM_COUNT; i++) {
+#ifndef FABRICD
+ if (flex_algo_id_valid(i) &&
+ !isis_flex_algo_elected_supported(i, area))
+ continue;
+#endif /* ifndef FABRICD */
+ pcfgs[i] =
+ isis_sr_cfg_prefix_find(area, ipv4, i);
+ }
+
+ isis_tlvs_add_extended_ip_reach(lsp->tlvs, ipv4, metric, false,
+ pcfgs);
+ }
+}
+
+static void lsp_build_internal_reach_ipv6(struct isis_lsp *lsp,
+ struct isis_area *area,
+ struct prefix_ipv6 *ipv6,
+ uint32_t metric)
+{
+ struct sr_prefix_cfg *pcfgs[SR_ALGORITHM_COUNT] = {NULL};
+
+ lsp_debug("ISIS (%s): Adding IPv6 reachability for %pFX",
+ area->area_tag, ipv6);
+
+ if (area->srdb.enabled)
+ for (int i = 0; i < SR_ALGORITHM_COUNT; i++) {
+#ifndef FABRICD
+ if (flex_algo_id_valid(i) &&
+ !isis_flex_algo_elected_supported(i, area))
+ continue;
+#endif /* ifndef FABRICD */
+ pcfgs[i] = isis_sr_cfg_prefix_find(area, ipv6, i);
+ }
+
+ isis_tlvs_add_ipv6_reach(lsp->tlvs, isis_area_ipv6_topology(area), ipv6,
+ metric, false, pcfgs);
+}
+
+
static void lsp_build_ext_reach_ipv4(struct isis_lsp *lsp,
struct isis_area *area)
{
isis_tlvs_add_oldstyle_ip_reach(lsp->tlvs, ipv4,
metric);
if (area->newmetric) {
- struct sr_prefix_cfg *pcfg = NULL;
+ struct sr_prefix_cfg *pcfgs[SR_ALGORITHM_COUNT] = {
+ NULL};
if (area->srdb.enabled)
- pcfg = isis_sr_cfg_prefix_find(area, ipv4);
+ for (int i = 0; i < SR_ALGORITHM_COUNT; i++) {
+#ifndef FABRICD
+ if (flex_algo_id_valid(i) &&
+ !isis_flex_algo_elected_supported(
+ i, area))
+ continue;
+#endif /* ifndef FABRICD */
+ pcfgs[i] = isis_sr_cfg_prefix_find(
+ area, ipv4, i);
+ }
isis_tlvs_add_extended_ip_reach(lsp->tlvs, ipv4, metric,
- true, pcfg);
+ true, pcfgs);
}
}
}
metric = MAX_WIDE_PATH_METRIC;
if (!src_p || !src_p->prefixlen) {
- struct sr_prefix_cfg *pcfg = NULL;
+ struct sr_prefix_cfg *pcfgs[SR_ALGORITHM_COUNT] = {
+ NULL};
if (area->srdb.enabled)
- pcfg = isis_sr_cfg_prefix_find(area, p);
+ for (int i = 0; i < SR_ALGORITHM_COUNT; i++) {
+#ifndef FABRICD
+ if (flex_algo_id_valid(i) &&
+ !isis_flex_algo_elected_supported(
+ i, area))
+ continue;
+#endif /* ifndef FABRICD */
+ pcfgs[i] = isis_sr_cfg_prefix_find(
+ area, p, i);
+ }
isis_tlvs_add_ipv6_reach(lsp->tlvs,
isis_area_ipv6_topology(area),
- p, metric, true, pcfg);
+ p, metric, true, pcfgs);
} else if (isis_area_ipv6_dstsrc_enabled(area)) {
isis_tlvs_add_ipv6_dstsrc_reach(lsp->tlvs,
ISIS_MT_IPV6_DSTSRC,
/* Add Router Capability TLV. */
if (area->isis->router_id != 0) {
- struct isis_router_cap cap = {};
+ struct isis_router_cap *rcap;
+#ifndef FABRICD
+ struct isis_router_cap_fad *rcap_fad;
+ struct listnode *node;
+ struct flex_algo *fa;
+#endif /* ifndef FABRICD */
- cap.router_id.s_addr = area->isis->router_id;
+ rcap = isis_tlvs_init_router_capability(lsp->tlvs);
+
+ rcap->router_id.s_addr = area->isis->router_id;
+
+#ifndef FABRICD
+ /* Set flex-algo definitions */
+ for (ALL_LIST_ELEMENTS_RO(area->flex_algos->flex_algos, node,
+ fa)) {
+ if (!fa->advertise_definition)
+ continue;
+ lsp_debug("ISIS (%s): Flex-Algo Definition %u",
+ area->area_tag, fa->algorithm);
+ isis_tlvs_set_router_capability_fad(lsp->tlvs, fa,
+ fa->algorithm,
+ area->isis->sysid);
+ }
+#endif /* ifndef FABRICD */
/* Add SR Sub-TLVs if SR is enabled. */
if (area->srdb.enabled) {
/* SRGB first */
range_size = srdb->config.srgb_upper_bound
- srdb->config.srgb_lower_bound + 1;
- cap.srgb.flags = ISIS_SUBTLV_SRGB_FLAG_I
- | ISIS_SUBTLV_SRGB_FLAG_V;
- cap.srgb.range_size = range_size;
- cap.srgb.lower_bound = srdb->config.srgb_lower_bound;
+ rcap->srgb.flags = ISIS_SUBTLV_SRGB_FLAG_I |
+ ISIS_SUBTLV_SRGB_FLAG_V;
+ rcap->srgb.range_size = range_size;
+ rcap->srgb.lower_bound = srdb->config.srgb_lower_bound;
/* Then Algorithm */
- cap.algo[0] = SR_ALGORITHM_SPF;
- cap.algo[1] = SR_ALGORITHM_UNSET;
+ rcap->algo[0] = SR_ALGORITHM_SPF;
+ rcap->algo[1] = SR_ALGORITHM_UNSET;
+#ifndef FABRICD
+ for (ALL_LIST_ELEMENTS_RO(area->flex_algos->flex_algos,
+ node, fa)) {
+ if (fa->advertise_definition)
+ rcap_fad = rcap->fads[fa->algorithm];
+ else
+ rcap_fad = NULL;
+
+ if (!isis_flex_algo_elected_supported_local_fad(
+ fa->algorithm, area, &rcap_fad)) {
+ fa->state = false;
+ continue;
+ }
+ fa->state = true;
+ lsp_debug("ISIS (%s): SR Algorithm %u",
+ area->area_tag, fa->algorithm);
+ rcap->algo[fa->algorithm] = fa->algorithm;
+ }
+#endif /* ifndef FABRICD */
/* SRLB */
- cap.srlb.flags = 0;
+ rcap->srlb.flags = 0;
range_size = srdb->config.srlb_upper_bound
- srdb->config.srlb_lower_bound + 1;
- cap.srlb.range_size = range_size;
- cap.srlb.lower_bound = srdb->config.srlb_lower_bound;
+ rcap->srlb.range_size = range_size;
+ rcap->srlb.lower_bound = srdb->config.srlb_lower_bound;
/* And finally MSD */
- cap.msd = srdb->config.msd;
- } else {
- /* Disable SR Algorithm */
- cap.algo[0] = SR_ALGORITHM_UNSET;
- cap.algo[1] = SR_ALGORITHM_UNSET;
+ rcap->msd = srdb->config.msd;
}
-
- isis_tlvs_set_router_capability(lsp->tlvs, &cap);
- lsp_debug("ISIS (%s): Adding Router Capabilities information",
- area->area_tag);
}
/* IPv4 address and TE router ID TLVs.
struct listnode *ipnode;
struct prefix_ipv4 *ipv4;
for (ALL_LIST_ELEMENTS_RO(circuit->ip_addrs, ipnode,
- ipv4)) {
- if (area->oldmetric) {
- lsp_debug(
- "ISIS (%s): Adding old-style IP reachability for %pFX",
- area->area_tag, ipv4);
- isis_tlvs_add_oldstyle_ip_reach(
- lsp->tlvs, ipv4, metric);
- }
-
- if (area->newmetric) {
- struct sr_prefix_cfg *pcfg = NULL;
-
- lsp_debug(
- "ISIS (%s): Adding te-style IP reachability for %pFX",
- area->area_tag, ipv4);
-
- if (area->srdb.enabled)
- pcfg = isis_sr_cfg_prefix_find(
- area, ipv4);
-
- isis_tlvs_add_extended_ip_reach(
- lsp->tlvs, ipv4, metric, false,
- pcfg);
- }
- }
+ ipv4))
+ lsp_build_internal_reach_ipv4(lsp, area, ipv4,
+ metric);
}
if (circuit->ipv6_router && circuit->ipv6_non_link->count > 0) {
struct prefix_ipv6 *ipv6;
for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_non_link,
- ipnode, ipv6)) {
- struct sr_prefix_cfg *pcfg = NULL;
-
- lsp_debug(
- "ISIS (%s): Adding IPv6 reachability for %pFX",
- area->area_tag, ipv6);
-
- if (area->srdb.enabled)
- pcfg = isis_sr_cfg_prefix_find(area,
- ipv6);
-
- isis_tlvs_add_ipv6_reach(
- lsp->tlvs,
- isis_area_ipv6_topology(area), ipv6,
- metric, false, pcfg);
- }
+ ipnode, ipv6))
+ lsp_build_internal_reach_ipv6(lsp, area, ipv6,
+ metric);
}
switch (circuit->circ_type) {