From 92ed0cdef522c148250186cd3fbdf61cc9789d77 Mon Sep 17 00:00:00 2001 From: Christian Franke Date: Thu, 10 May 2018 19:05:40 +0200 Subject: [PATCH] fabricd: allow to configure tier-level advertisement While OpenFabric calculates most tier numbers automatically by the fabric locality calculation algorithm, that algorithm requires two systems to be manually configured as tier 0, so it has reference points. Also, completely manual configuration is possible. To support this, introduce appropriate CLI commands and flood the configured information. Signed-off-by: Christian Franke --- isisd/fabricd.c | 56 ++++++++++++++++++++++++++++++++++++++++ isisd/fabricd.h | 4 +++ isisd/isis_lsp.c | 8 ++++++ isisd/isis_vty_fabricd.c | 32 ++++++++++++++++++++++- isisd/isisd.c | 9 +++++++ 5 files changed, 108 insertions(+), 1 deletion(-) diff --git a/isisd/fabricd.c b/isisd/fabricd.c index 853b672075..11d1ff695e 100644 --- a/isisd/fabricd.c +++ b/isisd/fabricd.c @@ -27,6 +27,8 @@ #include "isisd/isis_misc.h" #include "isisd/isis_adjacency.h" #include "isisd/isis_spf.h" +#include "isisd/isis_tlvs.h" +#include "isisd/isis_lsp.h" DEFINE_MTYPE_STATIC(ISISD, FABRICD_STATE, "ISIS OpenFabric") @@ -42,20 +44,27 @@ enum fabricd_sync_state { }; struct fabricd { + struct isis_area *area; + enum fabricd_sync_state initial_sync_state; time_t initial_sync_start; struct isis_circuit *initial_sync_circuit; struct thread *initial_sync_timeout; struct isis_spftree *spftree; + + uint8_t tier; + uint8_t tier_config; }; struct fabricd *fabricd_new(struct isis_area *area) { struct fabricd *rv = XCALLOC(MTYPE_FABRICD_STATE, sizeof(*rv)); + rv->area = area; rv->initial_sync_state = FABRICD_SYNC_PENDING; rv->spftree = isis_spftree_new(area); + rv->tier = rv->tier_config = ISIS_TIER_UNDEFINED; return rv; }; @@ -147,6 +156,16 @@ void fabricd_initial_sync_finish(struct isis_area *area) f->initial_sync_timeout = NULL; } +static void fabricd_set_tier(struct fabricd *f, uint8_t tier) +{ + if (f->tier == tier) + return; + + f->tier = tier; + + lsp_regenerate_schedule(f->area, ISIS_LEVEL2, 0); +} + void fabricd_run_spf(struct isis_area *area) { struct fabricd *f = area->fabricd; @@ -166,3 +185,40 @@ struct isis_spftree *fabricd_spftree(struct isis_area *area) return f->spftree; } + +void fabricd_configure_tier(struct isis_area *area, uint8_t tier) +{ + struct fabricd *f = area->fabricd; + + if (!f || f->tier_config == tier) + return; + + f->tier_config = tier; + fabricd_set_tier(f, tier); +} + +uint8_t fabricd_tier(struct isis_area *area) +{ + struct fabricd *f = area->fabricd; + + if (!f) + return ISIS_TIER_UNDEFINED; + + return f->tier; +} + +int fabricd_write_settings(struct isis_area *area, struct vty *vty) +{ + struct fabricd *f = area->fabricd; + int written = 0; + + if (!f) + return written; + + if (f->tier_config != ISIS_TIER_UNDEFINED) { + vty_out(vty, " fabric-tier %" PRIu8 "\n", f->tier_config); + written++; + } + + return written; +} diff --git a/isisd/fabricd.h b/isisd/fabricd.h index 1707adf36e..a6dc979729 100644 --- a/isisd/fabricd.h +++ b/isisd/fabricd.h @@ -27,6 +27,7 @@ struct fabricd; struct isis_circuit; struct isis_area; struct isis_spftree; +struct vty; struct fabricd *fabricd_new(struct isis_area *area); void fabricd_finish(struct fabricd *f); @@ -36,5 +37,8 @@ struct isis_circuit *fabricd_initial_sync_circuit(struct isis_area *area); void fabricd_initial_sync_finish(struct isis_area *area); void fabricd_run_spf(struct isis_area *area); struct isis_spftree *fabricd_spftree(struct isis_area *area); +void fabricd_configure_tier(struct isis_area *area, uint8_t tier); +uint8_t fabricd_tier(struct isis_area *area); +int fabricd_write_settings(struct isis_area *area, struct vty *vty); #endif diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c index 90bcece15d..f8ebce2efd 100644 --- a/isisd/isis_lsp.c +++ b/isisd/isis_lsp.c @@ -929,6 +929,14 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area) lsp_debug("ISIS (%s): Adding circuit specific information.", area->area_tag); + if (fabricd) { + lsp_debug( + "ISIS (%s): Adding tier %" PRIu8 " spine-leaf-extension tlv.", + area->area_tag, fabricd_tier(area)); + isis_tlvs_add_spine_leaf(lsp->tlvs, fabricd_tier(area), true, + false, false, false); + } + struct isis_circuit *circuit; for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) { if (!circuit->interface) diff --git a/isisd/isis_vty_fabricd.c b/isisd/isis_vty_fabricd.c index 22876301c3..5ef3af0f19 100644 --- a/isisd/isis_vty_fabricd.c +++ b/isisd/isis_vty_fabricd.c @@ -25,8 +25,38 @@ #include "isisd.h" #include "isis_vty_common.h" +#include "fabricd.h" +#include "isis_tlvs.h" + +DEFUN (fabric_tier, + fabric_tier_cmd, + "fabric-tier (0-14)", + "Statically configure the tier to advertise\n" + "Tier to advertise\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + + uint8_t tier = atoi(argv[1]->arg); + + fabricd_configure_tier(area, tier); + return CMD_SUCCESS; +} + +DEFUN (no_fabric_tier, + no_fabric_tier_cmd, + "no fabric-tier [(0-14)]", + NO_STR + "Statically configure the tier to advertise\n" + "Tier to advertise\n") +{ + VTY_DECLVAR_CONTEXT(isis_area, area); + + fabricd_configure_tier(area, ISIS_TIER_UNDEFINED); + return CMD_SUCCESS; +} void isis_vty_daemon_init(void) { - return; + install_element(ROUTER_NODE, &fabric_tier_cmd); + install_element(ROUTER_NODE, &no_fabric_tier_cmd); } diff --git a/isisd/isisd.c b/isisd/isisd.c index cc5463ffe7..84f44b1648 100644 --- a/isisd/isisd.c +++ b/isisd/isisd.c @@ -1299,6 +1299,14 @@ DEFUN (show_isis_summary, vty_out(vty, "Area %s:\n", area->area_tag ? area->area_tag : "null"); + if (fabricd) { + uint8_t tier = fabricd_tier(area); + if (tier == ISIS_TIER_UNDEFINED) + vty_out(vty, " Tier: undefined\n"); + else + vty_out(vty, " Tier: %" PRIu8 "\n", tier); + } + if (listcount(area->area_addrs) > 0) { struct area_addr *area_addr; for (ALL_LIST_ELEMENTS_RO(area->area_addrs, node2, @@ -2133,6 +2141,7 @@ int isis_config_write(struct vty *vty) } write += area_write_mt_settings(area, vty); + write += fabricd_write_settings(area, vty); } isis_mpls_te_config_write_router(vty); } -- 2.39.5