diff --git a/doc/user/isisd.rst b/doc/user/isisd.rst index 4a711a8feb..5d53f60f93 100644 --- a/doc/user/isisd.rst +++ b/doc/user/isisd.rst @@ -318,6 +318,11 @@ Traffic Engineering .. note:: + IS-IS-TE supports RFC 5305 (base TE), RFC 6119 (IPv6) and RFC 7810 / 8570 + (Extended Metric) with or without Multi-Topology. All Traffic Engineering + information are stored in a database formally named TED. However, best + acccuracy is provided without Multi-Topology due to inconsistency of Traffic + Engineering Advertisement of 3rd party commercial routers when MT is enabled. At this time, FRR offers partial support for some of the routing protocol extensions that can be used with MPLS-TE. FRR does not currently support a complete RSVP-TE solution. @@ -330,6 +335,15 @@ Traffic Engineering Configure stable IP address for MPLS-TE. +.. clicmd:: mpls-te router-address ipv6 + + Configure stable IPv6 address for MPLS-TE. + +.. clicmd:: mpls-te export + + Export Traffic Engineering DataBase to other daemons through the ZAPI + Opaque Link State messages. + .. clicmd:: show isis mpls-te interface .. clicmd:: show isis mpls-te interface INTERFACE @@ -340,6 +354,16 @@ Traffic Engineering Show Traffic Engineering router parameters. +.. clicmd:: show isis [vrf ] mpls-te database [detail|json] + +.. clicmd:: show isis [vrf ] mpls-te database vertex [WORD] [detail|json] + +.. clicmd:: show isis [vrf ] mpls-te database edge [A.B.C.D|X:X::X:X] [detail|json] + +.. clicmd:: show isis [vrf ] mpls-te database subnet [A.B.C.D/M|X:X::X:X/M] [detail|json] + + Show Traffic Engineering Database + .. seealso:: :ref:`ospf-traffic-engineering` @@ -445,6 +469,10 @@ Debugging ISIS Update related packets. +.. clicmd:: debug isis te-events + + IS-IS Traffic Engineering events + .. clicmd:: debug isis sr-events diff --git a/isisd/isis_adjacency.c b/isisd/isis_adjacency.c index 9529adb09a..d75613f300 100644 --- a/isisd/isis_adjacency.c +++ b/isisd/isis_adjacency.c @@ -168,7 +168,7 @@ void isis_delete_adj(void *arg) XFREE(MTYPE_ISIS_ADJACENCY_INFO, adj->area_addresses); XFREE(MTYPE_ISIS_ADJACENCY_INFO, adj->ipv4_addresses); - XFREE(MTYPE_ISIS_ADJACENCY_INFO, adj->ipv6_addresses); + XFREE(MTYPE_ISIS_ADJACENCY_INFO, adj->ll_ipv6_addrs); adj_mt_finish(adj); list_delete(&adj->adj_sids); @@ -420,11 +420,11 @@ void isis_adj_print(struct isis_adjacency *adj) zlog_debug("%pI4", &adj->ipv4_addresses[i]); } - if (adj->ipv6_address_count) { + if (adj->ll_ipv6_count) { zlog_debug("IPv6 Address(es):"); - for (unsigned int i = 0; i < adj->ipv6_address_count; i++) { + for (unsigned int i = 0; i < adj->ll_ipv6_count; i++) { char buf[INET6_ADDRSTRLEN]; - inet_ntop(AF_INET6, &adj->ipv6_addresses[i], buf, + inet_ntop(AF_INET6, &adj->ll_ipv6_addrs[i], buf, sizeof(buf)); zlog_debug("%s", buf); } @@ -583,12 +583,21 @@ void isis_adj_print_vty(struct isis_adjacency *adj, struct vty *vty, vty_out(vty, " %pI4\n", &adj->ipv4_addresses[i]); } - if (adj->ipv6_address_count) { + if (adj->ll_ipv6_count) { vty_out(vty, " IPv6 Address(es):\n"); - for (unsigned int i = 0; i < adj->ipv6_address_count; + for (unsigned int i = 0; i < adj->ll_ipv6_count; i++) { + char buf[INET6_ADDRSTRLEN]; + inet_ntop(AF_INET6, &adj->ll_ipv6_addrs[i], + buf, sizeof(buf)); + vty_out(vty, " %s\n", buf); + } + } + if (adj->global_ipv6_count) { + vty_out(vty, " Global IPv6 Address(es):\n"); + for (unsigned int i = 0; i < adj->global_ipv6_count; i++) { char buf[INET6_ADDRSTRLEN]; - inet_ntop(AF_INET6, &adj->ipv6_addresses[i], + inet_ntop(AF_INET6, &adj->global_ipv6_addrs[i], buf, sizeof(buf)); vty_out(vty, " %s\n", buf); } diff --git a/isisd/isis_adjacency.h b/isisd/isis_adjacency.h index 4aa553e303..af70775a87 100644 --- a/isisd/isis_adjacency.h +++ b/isisd/isis_adjacency.h @@ -88,8 +88,10 @@ struct isis_adjacency { struct in_addr *ipv4_addresses; unsigned int ipv4_address_count; struct in_addr router_address; - struct in6_addr *ipv6_addresses; - unsigned int ipv6_address_count; + struct in6_addr *ll_ipv6_addrs; /* Link local IPv6 neighbor address */ + unsigned int ll_ipv6_count; + struct in6_addr *global_ipv6_addrs; /* Global IPv6 neighbor address */ + unsigned int global_ipv6_count; struct in6_addr router_address6; uint8_t prio[ISIS_LEVELS]; /* priorityOfNeighbour for DIS */ int circuit_t; /* from hello PDU hdr */ @@ -127,9 +129,11 @@ void isis_adj_process_threeway(struct isis_adjacency *adj, enum isis_adj_usage adj_usage); DECLARE_HOOK(isis_adj_state_change_hook, (struct isis_adjacency *adj), (adj)); DECLARE_HOOK(isis_adj_ip_enabled_hook, - (struct isis_adjacency *adj, int family), (adj, family)); + (struct isis_adjacency * adj, int family, bool global), + (adj, family, global)); DECLARE_HOOK(isis_adj_ip_disabled_hook, - (struct isis_adjacency *adj, int family), (adj, family)); + (struct isis_adjacency * adj, int family, bool global), + (adj, family, global)); void isis_log_adj_change(struct isis_adjacency *adj, enum isis_adj_state old_state, enum isis_adj_state new_state, const char *reason); diff --git a/isisd/isis_bfd.c b/isisd/isis_bfd.c index a7548e2f13..1f50fb9342 100644 --- a/isisd/isis_bfd.c +++ b/isisd/isis_bfd.c @@ -81,7 +81,7 @@ static void bfd_handle_adj_up(struct isis_adjacency *adj) */ if (circuit->ipv6_router && (listcount(circuit->ipv6_link) == 0 - || adj->ipv6_address_count == 0)) { + || adj->ll_ipv6_count == 0)) { if (IS_DEBUG_BFD) zlog_debug( "ISIS-BFD: skipping BFD initialization on adjacency with %s because IPv6 is enabled but not ready", @@ -93,9 +93,9 @@ static void bfd_handle_adj_up(struct isis_adjacency *adj) * If IS-IS is enabled for both IPv4 and IPv6 on the circuit, prefer * creating a BFD session over IPv6. */ - if (circuit->ipv6_router && adj->ipv6_address_count) { + if (circuit->ipv6_router && adj->ll_ipv6_count) { family = AF_INET6; - dst_ip.ipv6 = adj->ipv6_addresses[0]; + dst_ip.ipv6 = adj->ll_ipv6_addrs[0]; local_ips = circuit->ipv6_link; if (!local_ips || list_isempty(local_ips)) { if (IS_DEBUG_BFD) @@ -181,10 +181,11 @@ void isis_bfd_circuit_cmd(struct isis_circuit *circuit) } } -static int bfd_handle_adj_ip_enabled(struct isis_adjacency *adj, int family) +static int bfd_handle_adj_ip_enabled(struct isis_adjacency *adj, int family, + bool global) { - if (family != AF_INET6) + if (family != AF_INET6 || global) return 0; if (adj->bfd_session) diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c index a91bbd0b95..0ad6190ba4 100644 --- a/isisd/isis_circuit.c +++ b/isisd/isis_circuit.c @@ -335,8 +335,16 @@ void isis_circuit_add_addr(struct isis_circuit *circuit, if (IN6_IS_ADDR_LINKLOCAL(&ipv6->prefix)) listnode_add(circuit->ipv6_link, ipv6); - else + else { listnode_add(circuit->ipv6_non_link, ipv6); + /* Update Local IPv6 address param. if MPLS TE is on */ + if (circuit->ext && circuit->area + && IS_MPLS_TE(circuit->area->mta)) { + IPV6_ADDR_COPY(&circuit->ext->local_addr6, + &ipv6->prefix); + SET_SUBTLV(circuit->ext, EXT_LOCAL_ADDR6); + } + } if (circuit->area) lsp_regenerate_schedule(circuit->area, circuit->is_type, 0); diff --git a/isisd/isis_cli.c b/isisd/isis_cli.c index 21162045ad..9feabfa012 100644 --- a/isisd/isis_cli.c +++ b/isisd/isis_cli.c @@ -1140,6 +1140,43 @@ void cli_show_isis_mpls_te_router_addr(struct vty *vty, yang_dnode_get_string(dnode, NULL)); } +/* + * XPath: /frr-isisd:isis/instance/mpls-te/router-address-v6 + */ +DEFPY_YANG(isis_mpls_te_router_addr_v6, isis_mpls_te_router_addr_v6_cmd, + "mpls-te router-address ipv6 X:X::X:X", + MPLS_TE_STR + "Stable IP address of the advertising router\n" + "IPv6 address\n" + "MPLS-TE router address in IPv6 address format\n") +{ + nb_cli_enqueue_change(vty, "./mpls-te/router-address-v6", NB_OP_MODIFY, + ipv6_str); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG(no_isis_mpls_te_router_addr_v6, no_isis_mpls_te_router_addr_v6_cmd, + "no mpls-te router-address ipv6 [X:X::X:X]", + NO_STR MPLS_TE_STR + "Delete IP address of the advertising router\n" + "IPv6 address\n" + "MPLS-TE router address in IPv6 address format\n") +{ + nb_cli_enqueue_change(vty, "./mpls-te/router-address-v6", NB_OP_DESTROY, + NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_mpls_te_router_addr_ipv6(struct vty *vty, + const struct lyd_node *dnode, + bool show_defaults) +{ + vty_out(vty, " mpls-te router-address ipv6 %s\n", + yang_dnode_get_string(dnode, NULL)); +} + DEFPY_YANG(isis_mpls_te_inter_as, isis_mpls_te_inter_as_cmd, "[no] mpls-te inter-as [level-1|level-1-2|level-2-only]", NO_STR MPLS_TE_STR @@ -1152,6 +1189,36 @@ DEFPY_YANG(isis_mpls_te_inter_as, isis_mpls_te_inter_as_cmd, return CMD_SUCCESS; } +/* + * XPath: /frr-isisd:isis/instance/mpls-te/export + */ +DEFPY_YANG(isis_mpls_te_export, isis_mpls_te_export_cmd, "mpls-te export", + MPLS_TE_STR "Enable export of MPLS-TE Link State information\n") +{ + nb_cli_enqueue_change(vty, "./mpls-te/export", NB_OP_MODIFY, "true"); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY_YANG(no_isis_mpls_te_export, no_isis_mpls_te_export_cmd, + "no mpls-te export", + NO_STR MPLS_TE_STR + "Disable export of MPLS-TE Link State information\n") +{ + nb_cli_enqueue_change(vty, "./mpls-te/export", NB_OP_MODIFY, "false"); + + return nb_cli_apply_changes(vty, NULL); +} + +void cli_show_isis_mpls_te_export(struct vty *vty, const struct lyd_node *dnode, + bool show_defaults) +{ + if (!yang_dnode_get_bool(dnode, NULL)) + vty_out(vty, " no"); + + vty_out(vty, " mpls-te export\n"); +} + /* * XPath: /frr-isisd:isis/instance/default-information-originate */ @@ -3125,7 +3192,11 @@ void isis_cli_init(void) install_element(ISIS_NODE, &no_isis_mpls_te_on_cmd); install_element(ISIS_NODE, &isis_mpls_te_router_addr_cmd); install_element(ISIS_NODE, &no_isis_mpls_te_router_addr_cmd); + install_element(ISIS_NODE, &isis_mpls_te_router_addr_v6_cmd); + install_element(ISIS_NODE, &no_isis_mpls_te_router_addr_v6_cmd); install_element(ISIS_NODE, &isis_mpls_te_inter_as_cmd); + install_element(ISIS_NODE, &isis_mpls_te_export_cmd); + install_element(ISIS_NODE, &no_isis_mpls_te_export_cmd); install_element(ISIS_NODE, &isis_default_originate_cmd); install_element(ISIS_NODE, &isis_redistribute_cmd); diff --git a/isisd/isis_lfa.c b/isisd/isis_lfa.c index e033c28fef..84aac24d52 100644 --- a/isisd/isis_lfa.c +++ b/isisd/isis_lfa.c @@ -1443,9 +1443,8 @@ static mpls_label_t rlfa_nexthop_label(struct isis_spftree *spftree, } break; case AF_INET6: - for (unsigned int j = 0; j < adj->ipv6_address_count; - j++) { - struct in6_addr addr = adj->ipv6_addresses[j]; + for (unsigned int j = 0; j < adj->ll_ipv6_count; j++) { + struct in6_addr addr = adj->ll_ipv6_addrs[j]; if (!IPV6_ADDR_SAME( &addr, diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c index e3de6f08c0..92d329f035 100644 --- a/isisd/isis_lsp.c +++ b/isisd/isis_lsp.c @@ -124,6 +124,8 @@ static void lsp_destroy(struct isis_lsp *lsp) ISIS_FLAGS_CLEAR_ALL(lsp->SSNflags); + isis_te_lsp_event(lsp, LSP_DEL); + lsp_clear_data(lsp); if (!LSP_FRAGMENT(lsp->hdr.lsp_id)) { @@ -335,6 +337,7 @@ void lsp_inc_seqno(struct isis_lsp *lsp, uint32_t seqno) lsp_pack_pdu(lsp); isis_spf_schedule(lsp->area, lsp->level); + isis_te_lsp_event(lsp, LSP_INC); } static void lsp_purge_add_poi(struct isis_lsp *lsp, @@ -570,8 +573,10 @@ void lsp_update(struct isis_lsp *lsp, struct isis_lsp_hdr *hdr, lsp_link_fragment(lsp, lsp0); } - if (lsp->hdr.seqno) + if (lsp->hdr.seqno) { isis_spf_schedule(lsp->area, lsp->level); + isis_te_lsp_event(lsp, LSP_UPD); + } } /* creation of LSP directly from what we received */ @@ -636,8 +641,10 @@ struct isis_lsp *lsp_new(struct isis_area *area, uint8_t *lsp_id, void lsp_insert(struct lspdb_head *head, struct isis_lsp *lsp) { lspdb_add(head, lsp); - if (lsp->hdr.seqno) + if (lsp->hdr.seqno) { isis_spf_schedule(lsp->area, lsp->level); + isis_te_lsp_event(lsp, LSP_ADD); + } } /* @@ -1030,6 +1037,10 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area) cap.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; } isis_tlvs_set_router_capability(lsp->tlvs, &cap); @@ -1067,6 +1078,14 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area) area->area_tag); } + if (IS_MPLS_TE(area->mta) + && !IN6_IS_ADDR_UNSPECIFIED(&area->mta->router_id_ipv6)) { + lsp_debug("ISIS (%s): Adding IPv6 TE Router ID tlv.", + area->area_tag); + isis_tlvs_set_te_router_id_ipv6(lsp->tlvs, + &area->mta->router_id_ipv6); + } + lsp_debug("ISIS (%s): Adding circuit specific information.", area->area_tag); @@ -1601,6 +1620,7 @@ static void lsp_build_pseudo(struct isis_lsp *lsp, struct isis_circuit *circuit, struct list *adj_list; struct listnode *node; struct isis_area *area = circuit->area; + uint16_t mtid; lsp_clear_data(lsp); lsp->tlvs = isis_alloc_tlvs(); @@ -1630,8 +1650,11 @@ static void lsp_build_pseudo(struct isis_lsp *lsp, struct isis_circuit *circuit, LSP_PSEUDO_ID(ne_id)); } if (circuit->area->newmetric) { - isis_tlvs_add_extended_reach(lsp->tlvs, ISIS_MT_IPV4_UNICAST, - ne_id, 0, NULL); + if (area_is_mt(circuit->area)) + mtid = ISIS_MT_IPV4_UNICAST; + else + mtid = ISIS_MT_DISABLE; + isis_tlvs_add_extended_reach(lsp->tlvs, mtid, ne_id, 0, NULL); lsp_debug( "ISIS (%s): Adding %s.%02x as te-style neighbor (self)", area->area_tag, sysid_print(ne_id), @@ -2000,6 +2023,7 @@ int lsp_tick(struct thread *thread) /* 7.3.16.4 c) record the time to purge * FIXME */ isis_spf_schedule(lsp->area, lsp->level); + isis_te_lsp_event(lsp, LSP_TICK); } if (lsp->age_out == 0) { @@ -2154,7 +2178,7 @@ int isis_lsp_iterate_ip_reach(struct isis_lsp *lsp, int family, uint16_t mtid, if (lsp->hdr.seqno == 0 || lsp->hdr.rem_lifetime == 0) return LSP_ITER_CONTINUE; - /* Parse main LSP. */ + /* Parse LSP */ if (lsp->tlvs) { if (!fabricd && !pseudo_lsp && family == AF_INET && mtid == ISIS_MT_IPV4_UNICAST) { @@ -2224,13 +2248,17 @@ int isis_lsp_iterate_ip_reach(struct isis_lsp *lsp, int family, uint16_t mtid, } } - /* Parse LSP fragments. */ - for (ALL_LIST_ELEMENTS_RO(lsp->lspu.frags, node, frag)) { - if (!frag->tlvs) - continue; + /* Parse LSP fragments if it is not a fragment itself */ + if (!LSP_FRAGMENT(lsp->hdr.lsp_id)) + for (ALL_LIST_ELEMENTS_RO(lsp->lspu.frags, node, frag)) { + if (!frag->tlvs) + continue; - isis_lsp_iterate_ip_reach(frag, family, mtid, cb, arg); - } + if (isis_lsp_iterate_ip_reach(frag, family, mtid, cb, + arg) + == LSP_ITER_STOP) + return LSP_ITER_STOP; + } return LSP_ITER_CONTINUE; } @@ -2251,7 +2279,7 @@ int isis_lsp_iterate_is_reach(struct isis_lsp *lsp, uint16_t mtid, if (lsp->hdr.seqno == 0 || lsp->hdr.rem_lifetime == 0) return LSP_ITER_CONTINUE; - /* Parse main LSP. */ + /* Parse LSP */ if (lsp->tlvs) { if (pseudo_lsp || mtid == ISIS_MT_IPV4_UNICAST) { head = lsp->tlvs->oldstyle_reach.head; @@ -2283,13 +2311,16 @@ int isis_lsp_iterate_is_reach(struct isis_lsp *lsp, uint16_t mtid, } } - /* Parse LSP fragments. */ - for (ALL_LIST_ELEMENTS_RO(lsp->lspu.frags, node, frag)) { - if (!frag->tlvs) - continue; + /* Parse LSP fragments if it not a fragment itself. */ + if (!LSP_FRAGMENT(lsp->hdr.lsp_id)) + for (ALL_LIST_ELEMENTS_RO(lsp->lspu.frags, node, frag)) { + if (!frag->tlvs) + continue; - isis_lsp_iterate_is_reach(frag, mtid, cb, arg); - } + if (isis_lsp_iterate_is_reach(frag, mtid, cb, arg) + == LSP_ITER_STOP) + return LSP_ITER_STOP; + } return LSP_ITER_CONTINUE; } diff --git a/isisd/isis_mt.c b/isisd/isis_mt.c index c024549fcc..f937bdf55c 100644 --- a/isisd/isis_mt.c +++ b/isisd/isis_mt.c @@ -515,6 +515,17 @@ static void tlvs_add_mt_set(struct isis_area *area, struct isis_tlvs *tlvs, uint8_t *id, uint32_t metric, struct isis_ext_subtlvs *ext) { + /* Check if MT is enable for this area */ + if (!area_is_mt(area)) { + lsp_debug( + "ISIS (%s): Adding %s.%02x as te-style neighbor (MT disable)", + area->area_tag, sysid_print(id), LSP_PSEUDO_ID(id)); + isis_tlvs_add_extended_reach(tlvs, ISIS_MT_DISABLE, id, metric, + ext); + return; + } + + /* Process Multi-Topology */ for (unsigned int i = 0; i < mt_count; i++) { uint16_t mtid = mt_set[i]; if (mt_set[i] == ISIS_MT_IPV4_UNICAST) { diff --git a/isisd/isis_mt.h b/isisd/isis_mt.h index fd9ee133ca..2952a2f171 100644 --- a/isisd/isis_mt.h +++ b/isisd/isis_mt.h @@ -33,6 +33,8 @@ #define ISIS_MT_IPV6_MULTICAST 4 #define ISIS_MT_IPV6_MGMT 5 #define ISIS_MT_IPV6_DSTSRC 3996 /* FIXME: IANA */ +/* Use first Reserved Flag to indicate that there is no MT Topology active */ +#define ISIS_MT_DISABLE 4096 #define ISIS_MT_NAMES \ "inter_as = off; new->interas_areaid.s_addr = 0; new->router_id.s_addr = 0; + new->ted = ls_ted_new(1, "ISIS", 0); + if (!new->ted) + zlog_warn("Unable to create Link State Data Base"); area->mta = new; } else { area->mta->status = enable; } + /* Initialize Link State Database */ + if (area->mta->ted) + isis_te_init_ted(area); + /* Update Extended TLVs according to Interface link parameters */ for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) isis_link_params_update(circuit, circuit->interface); @@ -1858,6 +1867,9 @@ int isis_instance_mpls_te_destroy(struct nb_cb_destroy_args *args) else return NB_OK; + /* Remove Link State Database */ + ls_ted_del_all(area->mta->ted); + /* Flush LSP if circuit engage */ for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) { if (!IS_EXT_TE(circuit->ext)) @@ -1929,6 +1941,88 @@ int isis_instance_mpls_te_router_address_destroy( return NB_OK; } +/* + * XPath: /frr-isisd:isis/instance/mpls-te/router-address-v6 + */ +int isis_instance_mpls_te_router_address_ipv6_modify( + struct nb_cb_modify_args *args) +{ + struct in6_addr value; + struct isis_area *area; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + area = nb_running_get_entry(args->dnode, NULL, true); + /* only proceed if MPLS-TE is enabled */ + if (!IS_MPLS_TE(area->mta)) + return NB_OK; + + yang_dnode_get_ipv6(&value, args->dnode, NULL); + /* Update Area IPv6 Router ID if different */ + if (!IPV6_ADDR_SAME(&area->mta->router_id_ipv6, &value)) { + IPV6_ADDR_COPY(&area->mta->router_id_ipv6, &value); + + /* And re-schedule LSP update */ + lsp_regenerate_schedule(area, area->is_type, 0); + } + + return NB_OK; +} + +int isis_instance_mpls_te_router_address_ipv6_destroy( + struct nb_cb_destroy_args *args) +{ + struct isis_area *area; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + area = nb_running_get_entry(args->dnode, NULL, true); + /* only proceed if MPLS-TE is enabled */ + if (!IS_MPLS_TE(area->mta)) + return NB_OK; + + /* Reset Area Router ID */ + IPV6_ADDR_COPY(&area->mta->router_id_ipv6, &in6addr_any); + + /* And re-schedule LSP update */ + lsp_regenerate_schedule(area, area->is_type, 0); + + return NB_OK; +} + +/* + * XPath: /frr-isisd:isis/instance/mpls-te/export + */ +int isis_instance_mpls_te_export_modify(struct nb_cb_modify_args *args) +{ + struct isis_area *area; + + if (args->event != NB_EV_APPLY) + return NB_OK; + + area = nb_running_get_entry(args->dnode, NULL, true); + /* only proceed if MPLS-TE is enabled */ + if (!IS_MPLS_TE(area->mta)) + return NB_OK; + + area->mta->export = yang_dnode_get_bool(args->dnode, NULL); + if (area->mta->export) { + if (IS_DEBUG_EVENTS) + zlog_debug("MPLS-TE: Enabled Link State export"); + if (isis_zebra_ls_register(true) != 0) + zlog_warn("Unable to register Link State\n"); + } else { + if (IS_DEBUG_EVENTS) + zlog_debug("MPLS-TE: Disable Link State export"); + if (isis_zebra_ls_register(false) != 0) + zlog_warn("Unable to register Link State\n"); + } + + return NB_OK; +} + /* * XPath: /frr-isisd:isis/instance/segment-routing/enabled */ diff --git a/isisd/isis_pdu.c b/isisd/isis_pdu.c index 7256fcbbc7..0814f3eea0 100644 --- a/isisd/isis_pdu.c +++ b/isisd/isis_pdu.c @@ -1971,6 +1971,11 @@ int send_hello(struct isis_circuit *circuit, int level) if (circuit->ipv6_router && circuit->ipv6_link) isis_tlvs_add_ipv6_addresses(tlvs, circuit->ipv6_link); + /* RFC6119 section 4 define TLV 233 to provide Global IPv6 address */ + if (circuit->ipv6_router && circuit->ipv6_non_link) + isis_tlvs_add_global_ipv6_addresses(tlvs, + circuit->ipv6_non_link); + if (isis_pack_tlvs(tlvs, circuit->snd_stream, len_pointer, circuit->pad_hellos, false)) { isis_free_tlvs(tlvs); diff --git a/isisd/isis_route.c b/isisd/isis_route.c index bf0079d814..764a0b0cd3 100644 --- a/isisd/isis_route.c +++ b/isisd/isis_route.c @@ -145,8 +145,8 @@ void adjinfo2nexthop(int family, struct list *nexthops, } break; case AF_INET6: - for (unsigned int i = 0; i < adj->ipv6_address_count; i++) { - ip.ipv6 = adj->ipv6_addresses[i]; + for (unsigned int i = 0; i < adj->ll_ipv6_count; i++) { + ip.ipv6 = adj->ll_ipv6_addrs[i]; if (!nexthoplookup(nexthops, AF_INET6, &ip, adj->circuit->interface->ifindex)) { diff --git a/isisd/isis_snmp.c b/isisd/isis_snmp.c index c530eb9169..319977f417 100644 --- a/isisd/isis_snmp.c +++ b/isisd/isis_snmp.c @@ -1186,14 +1186,13 @@ static int isis_snmp_adj_helper(struct isis_adjacency *adj, int data_id, break; case ISIS_SNMP_ADJ_DATA_IP_ADDR: - if (data_off - >= (adj->ipv4_address_count + adj->ipv6_address_count)) + if (data_off >= (adj->ipv4_address_count + adj->ll_ipv6_count)) return 0; if (data_off >= adj->ipv4_address_count) { - data = (uint8_t *)&adj->ipv6_addresses + data = (uint8_t *)&adj->ll_ipv6_addrs [data_off - adj->ipv4_address_count]; - data_len = sizeof(adj->ipv6_addresses[0]); + data_len = sizeof(adj->ll_ipv6_addrs[0]); } else { data = (uint8_t *)&adj->ipv4_addresses[data_off]; data_len = sizeof(adj->ipv4_addresses[0]); diff --git a/isisd/isis_sr.c b/isisd/isis_sr.c index 54e31f0040..18a727adde 100644 --- a/isisd/isis_sr.c +++ b/isisd/isis_sr.c @@ -661,10 +661,10 @@ void sr_adj_sid_add_single(struct isis_adjacency *adj, int family, bool backup, nexthop.ipv4 = adj->ipv4_addresses[0]; break; case AF_INET6: - if (!circuit->ipv6_router || !adj->ipv6_address_count) + if (!circuit->ipv6_router || !adj->ll_ipv6_count) return; - nexthop.ipv6 = adj->ipv6_addresses[0]; + nexthop.ipv6 = adj->ll_ipv6_addrs[0]; break; default: flog_err(EC_LIB_DEVELOPMENT, @@ -880,12 +880,14 @@ static int sr_adj_state_change(struct isis_adjacency *adj) * * @param adj IS-IS Adjacency * @param family Inet Family (IPv4 or IPv6) + * @param global Indicate if it concerns the Local or Global IPv6 addresses * * @return 0 */ -static int sr_adj_ip_enabled(struct isis_adjacency *adj, int family) +static int sr_adj_ip_enabled(struct isis_adjacency *adj, int family, + bool global) { - if (!adj->circuit->area->srdb.enabled) + if (!adj->circuit->area->srdb.enabled || global) return 0; sr_adj_sid_add(adj, family); @@ -899,15 +901,17 @@ static int sr_adj_ip_enabled(struct isis_adjacency *adj, int family) * * @param adj IS-IS Adjacency * @param family Inet Family (IPv4 or IPv6) + * @param global Indicate if it concerns the Local or Global IPv6 addresses * * @return 0 */ -static int sr_adj_ip_disabled(struct isis_adjacency *adj, int family) +static int sr_adj_ip_disabled(struct isis_adjacency *adj, int family, + bool global) { struct sr_adjacency *sra; struct listnode *node, *nnode; - if (!adj->circuit->area->srdb.enabled) + if (!adj->circuit->area->srdb.enabled || global) return 0; for (ALL_LIST_ELEMENTS(adj->adj_sids, node, nnode, sra)) @@ -1148,7 +1152,7 @@ int isis_sr_start(struct isis_area *area) for (ALL_LIST_ELEMENTS_RO(area->adjacency_list, node, adj)) { if (adj->ipv4_address_count > 0) sr_adj_sid_add(adj, AF_INET); - if (adj->ipv6_address_count > 0) + if (adj->ll_ipv6_count > 0) sr_adj_sid_add(adj, AF_INET6); } diff --git a/isisd/isis_te.c b/isisd/isis_te.c index 8daa2b36bf..93be70036e 100644 --- a/isisd/isis_te.c +++ b/isisd/isis_te.c @@ -43,6 +43,8 @@ #include "sockunion.h" #include "network.h" #include "sbuf.h" +#include "link_state.h" +#include "lib/json.h" #include "isisd/isis_constants.h" #include "isisd/isis_common.h" @@ -57,6 +59,8 @@ #include "isisd/isis_csm.h" #include "isisd/isis_adjacency.h" #include "isisd/isis_spf.h" +#include "isisd/isis_tlvs.h" +#include "isisd/isis_mt.h" #include "isisd/isis_te.h" #include "isisd/isis_zebra.h" @@ -82,14 +86,14 @@ void isis_link_params_update(struct isis_circuit *circuit, if ((ifp == NULL) || (circuit->state != C_STATE_UP)) return; - zlog_debug("TE(%s): Update circuit parameters for interface %s", - circuit->area->area_tag, ifp->name); + te_debug("ISIS-TE(%s): Update circuit parameters for interface %s", + circuit->area->area_tag, ifp->name); /* Check if MPLS TE Circuit context has not been already created */ if (circuit->ext == NULL) { circuit->ext = isis_alloc_ext_subtlvs(); - zlog_debug(" |- Allocated new Ext-subTLVs for interface %s", - ifp->name); + te_debug(" |- Allocated new Ext-subTLVs for interface %s", + ifp->name); } ext = circuit->ext; @@ -113,19 +117,6 @@ void isis_link_params_update(struct isis_circuit *circuit, } else UNSET_SUBTLV(ext, EXT_LOCAL_ADDR); - /* Same for Remote IPv4 address */ - if (circuit->circ_type == CIRCUIT_T_P2P) { - struct isis_adjacency *adj = circuit->u.p2p.neighbor; - - if (adj && adj->adj_state == ISIS_ADJ_UP - && adj->ipv4_address_count) { - IPV4_ADDR_COPY(&ext->neigh_addr, - &adj->ipv4_addresses[0]); - SET_SUBTLV(ext, EXT_NEIGH_ADDR); - } - } else - UNSET_SUBTLV(ext, EXT_NEIGH_ADDR); - /* If known, register local IPv6 addr from ip_addr list */ if (circuit->ipv6_non_link != NULL && listcount(circuit->ipv6_non_link) != 0) { @@ -137,18 +128,12 @@ void isis_link_params_update(struct isis_circuit *circuit, } else UNSET_SUBTLV(ext, EXT_LOCAL_ADDR6); - /* Same for Remote IPv6 address */ - if (circuit->circ_type == CIRCUIT_T_P2P) { - struct isis_adjacency *adj = circuit->u.p2p.neighbor; - - if (adj && adj->adj_state == ISIS_ADJ_UP - && adj->ipv6_address_count) { - IPV6_ADDR_COPY(&ext->neigh_addr6, - &adj->ipv6_addresses[0]); - SET_SUBTLV(ext, EXT_NEIGH_ADDR6); - } - } else - UNSET_SUBTLV(ext, EXT_NEIGH_ADDR6); + /* + * Remote IPv4 and IPv6 addresses are now added in + * isis_mpls_te_adj_ip_enabled() to get the right IP address + * in particular for IPv6 to get the global IPv6 address and + * not the link-local IPv6 address. + */ if (IS_PARAM_SET(ifp->link_params, LP_MAX_BW)) { ext->max_bw = ifp->link_params->max_bw; @@ -231,11 +216,11 @@ void isis_link_params_update(struct isis_circuit *circuit, UNSET_SUBTLV(ext, EXT_RMT_AS); UNSET_SUBTLV(ext, EXT_RMT_IP); } - zlog_debug(" |- New MPLS-TE link parameters status 0x%x", - ext->status); + te_debug(" |- New MPLS-TE link parameters status 0x%x", + ext->status); } else { - zlog_debug(" |- Reset Extended subTLVs status 0x%x", - ext->status); + te_debug(" |- Reset Extended subTLVs status 0x%x", + ext->status); /* Reset TE subTLVs keeping SR one's */ if (IS_SUBTLV(ext, EXT_ADJ_SID)) ext->status = EXT_ADJ_SID; @@ -248,29 +233,95 @@ void isis_link_params_update(struct isis_circuit *circuit, return; } -static int isis_link_update_adj_hook(struct isis_adjacency *adj) +static int isis_mpls_te_adj_ip_enabled(struct isis_adjacency *adj, int family, + bool global) { + struct isis_circuit *circuit; + struct isis_ext_subtlvs *ext; - struct isis_circuit *circuit = adj->circuit; - - /* Update MPLS TE Remote IP address parameter if possible */ - if (!IS_MPLS_TE(circuit->area->mta) || !IS_EXT_TE(circuit->ext)) + /* Sanity Check */ + if (!adj || !adj->circuit) return 0; - /* IPv4 first */ - if (adj->ipv4_address_count > 0) { - IPV4_ADDR_COPY(&circuit->ext->neigh_addr, - &adj->ipv4_addresses[0]); - SET_SUBTLV(circuit->ext, EXT_NEIGH_ADDR); + circuit = adj->circuit; + + /* Check that MPLS TE is enabled */ + if (!IS_MPLS_TE(circuit->area->mta) || !circuit->ext) + return 0; + + ext = circuit->ext; + + /* Determine nexthop IP address */ + switch (family) { + case AF_INET: + if (!circuit->ip_router || !adj->ipv4_address_count) + UNSET_SUBTLV(ext, EXT_NEIGH_ADDR); + else { + IPV4_ADDR_COPY(&ext->neigh_addr, + &adj->ipv4_addresses[0]); + SET_SUBTLV(ext, EXT_NEIGH_ADDR); + } + break; + case AF_INET6: + if (!global) + return 0; + + if (!circuit->ipv6_router || !adj->global_ipv6_count) + UNSET_SUBTLV(ext, EXT_NEIGH_ADDR6); + else { + IPV6_ADDR_COPY(&ext->neigh_addr6, + &adj->global_ipv6_addrs[0]); + SET_SUBTLV(ext, EXT_NEIGH_ADDR6); + } + break; + default: + return 0; } - /* and IPv6 */ - if (adj->ipv6_address_count > 0) { - IPV6_ADDR_COPY(&circuit->ext->neigh_addr6, - &adj->ipv6_addresses[0]); - SET_SUBTLV(circuit->ext, EXT_NEIGH_ADDR6); + /* Update LSP */ + lsp_regenerate_schedule(circuit->area, circuit->is_type, 0); + + return 0; +} + +static int isis_mpls_te_adj_ip_disabled(struct isis_adjacency *adj, int family, + bool global) +{ + struct isis_circuit *circuit; + struct isis_ext_subtlvs *ext; + + /* Sanity Check */ + if (!adj || !adj->circuit || !adj->circuit->ext) + return 0; + + circuit = adj->circuit; + + /* Check that MPLS TE is enabled */ + if (!IS_MPLS_TE(circuit->area->mta) || !circuit->ext) + return 0; + + ext = circuit->ext; + + /* Update MPLS TE IP address parameters if possible */ + if (!IS_MPLS_TE(circuit->area->mta) || !IS_EXT_TE(ext)) + return 0; + + /* Determine nexthop IP address */ + switch (family) { + case AF_INET: + UNSET_SUBTLV(ext, EXT_NEIGH_ADDR); + break; + case AF_INET6: + if (global) + UNSET_SUBTLV(ext, EXT_NEIGH_ADDR6); + break; + default: + return 0; } + /* Update LSP */ + lsp_regenerate_schedule(circuit->area, circuit->is_type, 0); + return 0; } @@ -299,9 +350,908 @@ int isis_mpls_te_update(struct interface *ifp) return rc; } + +/** + * Export Link State information to consumer daemon through ZAPI Link State + * Opaque Message. + * + * @param type Type of Link State Element i.e. Vertex, Edge or Subnet + * @param link_state Pointer to Link State Vertex, Edge or Subnet + * + * @return 0 if success, -1 otherwise + */ +static int isis_te_export(uint8_t type, void *link_state) +{ + struct ls_message msg = {}; + int rc = 0; + + switch (type) { + case LS_MSG_TYPE_NODE: + ls_vertex2msg(&msg, (struct ls_vertex *)link_state); + rc = ls_send_msg(zclient, &msg, NULL); + break; + case LS_MSG_TYPE_ATTRIBUTES: + ls_edge2msg(&msg, (struct ls_edge *)link_state); + rc = ls_send_msg(zclient, &msg, NULL); + break; + case LS_MSG_TYPE_PREFIX: + ls_subnet2msg(&msg, (struct ls_subnet *)link_state); + rc = ls_send_msg(zclient, &msg, NULL); + break; + default: + rc = -1; + break; + } + + return rc; +} + +/** + * Parse LSP and build corresponding vertex. If vertex doesn't exist in the + * Link State Database it is created otherwise updated. + * + * @param ted Traffic Engineering Link State Database + * @param lsp IS-IS Link State PDU + * + * @return Link State Vertex or NULL in case of error + */ +static struct ls_vertex *lsp_to_vertex(struct ls_ted *ted, struct isis_lsp *lsp) +{ + struct ls_vertex *vertex = NULL; + struct ls_node *old, lnode = {}; + struct isis_tlvs *tlvs; + const struct in_addr inaddr_any = {.s_addr = INADDR_ANY}; + + /* Sanity check */ + if (!ted || !lsp) + return NULL; + + /* Compute Link State Node ID from IS-IS sysID ... */ + if (lsp->level == ISIS_LEVEL1) + lnode.adv.origin = ISIS_L1; + else + lnode.adv.origin = ISIS_L2; + memcpy(&lnode.adv.id.iso.sys_id, &lsp->hdr.lsp_id, ISIS_SYS_ID_LEN); + lnode.adv.id.iso.level = lsp->level; + /* ... and search the corresponding vertex */ + vertex = ls_find_vertex_by_id(ted, lnode.adv); + /* Create a new one if not found */ + if (!vertex) { + old = ls_node_new(lnode.adv, inaddr_any, in6addr_any); + old->type = STANDARD; + vertex = ls_vertex_add(ted, old); + } + old = vertex->node; + te_debug(" |- %s Vertex (%" PRIu64 ") for node %s", + vertex->status == NEW ? "Create" : "Found", vertex->key, + print_sys_hostname(old->adv.id.iso.sys_id)); + + /* Fulfill Link State Node information */ + tlvs = lsp->tlvs; + if (tlvs) { + if (tlvs->te_router_id) { + IPV4_ADDR_COPY(&lnode.router_id, tlvs->te_router_id); + SET_FLAG(lnode.flags, LS_NODE_ROUTER_ID); + } + if (tlvs->te_router_id_ipv6) { + IPV6_ADDR_COPY(&lnode.router_id6, + tlvs->te_router_id_ipv6); + SET_FLAG(lnode.flags, LS_NODE_ROUTER_ID6); + } + if (tlvs->hostname) { + memcpy(&lnode.name, tlvs->hostname, MAX_NAME_LENGTH); + SET_FLAG(lnode.flags, LS_NODE_NAME); + } + if (tlvs->router_cap) { + struct isis_router_cap *cap = tlvs->router_cap; + + if (cap->srgb.lower_bound != 0 + && cap->srgb.range_size != 0) { + SET_FLAG(lnode.flags, LS_NODE_SR); + lnode.srgb.flag = cap->srgb.flags; + lnode.srgb.lower_bound = cap->srgb.lower_bound; + lnode.srgb.range_size = cap->srgb.range_size; + for (int i = 0; i < SR_ALGORITHM_COUNT; i++) + lnode.algo[i] = cap->algo[i]; + } + + if (cap->srlb.lower_bound != 0 + && cap->srlb.range_size != 0) { + lnode.srlb.lower_bound = cap->srlb.lower_bound; + lnode.srlb.range_size = cap->srlb.range_size; + SET_FLAG(lnode.flags, LS_NODE_SRLB); + } + if (cap->msd != 0) { + lnode.msd = cap->msd; + SET_FLAG(lnode.flags, LS_NODE_MSD); + } + } + } + + /* Update Link State Node information */ + if (!ls_node_same(old, &lnode)) { + te_debug(" |- Update Link State Node information"); + memcpy(old, &lnode, sizeof(struct ls_node)); + if (vertex->status != NEW) + vertex->status = UPDATE; + } + + /* Set self TED vertex if LSP corresponds to the own router */ + if (lsp->own_lsp) + ted->self = vertex; + + return vertex; +} + +/** + * Get Link State Edge from Link State Attributes in TE Database. + * Edge structure is dynamically allocated and fulfill with Link State + * Attributes if not found. + * + * @param ted Link State Database + * @param attr Link State Attributes + * + * @return New Link State Edge if success, NULL otherwise + */ +static struct ls_edge *get_edge(struct ls_ted *ted, struct ls_attributes *attr) +{ + struct ls_edge *edge; + struct ls_standard *std; + uint64_t key = 0; + + /* Check parameters */ + if (!ted || !attr) + return NULL; + + std = &attr->standard; + + /* Compute keys in function of local address (IPv4/v6) or identifier */ + if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR)) + key = ((uint64_t)ntohl(std->local.s_addr)) & 0xffffffff; + else if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR6)) + key = ((uint64_t)ntohl(std->local6.s6_addr32[2]) << 32 + | (uint64_t)ntohl(std->local6.s6_addr32[3])); + else if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ID)) + key = ((uint64_t)std->remote_id << 32) + | (((uint64_t)std->local_id) & 0xffffffff); + else + key = 0; + + /* Stop here if we don't got a valid key */ + if (key == 0) + return NULL; + + /* Get corresponding Edge by key from Link State Data Base */ + edge = ls_find_edge_by_key(ted, key); + + /* and create new one if not exist */ + if (!edge) { + edge = ls_edge_add(ted, attr); + /* + * Edge could be Null if no local ID is found in Attributes. + * Stop the processing as without any local ID it is not + * possible to store Edge in the TED. + */ + if (!edge) + return NULL; + } + + if (CHECK_FLAG(edge->attributes->flags, LS_ATTR_LOCAL_ADDR)) + te_debug(" |- %s Edge (%" PRIu64 + ") from Extended Reach. %pI4", + edge->status == NEW ? "Create" : "Found", edge->key, + &attr->standard.local); + else if (CHECK_FLAG(edge->attributes->flags, LS_ATTR_LOCAL_ADDR6)) + te_debug(" |- %s Edge (%" PRIu64 + ") from Extended Reach. %pI6", + edge->status == NEW ? "Create" : "Found", edge->key, + &attr->standard.local6); + else + te_debug(" |- %s Edge (%" PRIu64 ")", + edge->status == NEW ? "Create" : "Found", edge->key); + + return edge; +} + +/** + * Get Link State Attributes from IS-IS Sub-TLVs. Structure is dynamically + * allocated and should be free once not use anymore. + * + * @param adv Link State Node ID + * @param tlvs IS-IS Sub TLVs + * + * @return New Link State attributes if success, NULL otherwise + */ +static struct ls_attributes *get_attributes(struct ls_node_id adv, + struct isis_ext_subtlvs *tlvs) +{ + struct ls_attributes *attr; + struct in_addr local = {.s_addr = INADDR_ANY}; + struct in6_addr local6 = in6addr_any; + uint32_t local_id = 0; + + /* Got Local identifier */ + if (CHECK_FLAG(tlvs->status, EXT_LOCAL_ADDR)) + local.s_addr = tlvs->local_addr.s_addr; + + if (CHECK_FLAG(tlvs->status, EXT_LOCAL_ADDR6)) + memcpy(&local6, &tlvs->local_addr6, IPV6_MAX_BYTELEN); + + if (CHECK_FLAG(tlvs->status, EXT_LLRI)) + local_id = tlvs->local_llri; + + /* Create LS Attributes */ + attr = ls_attributes_new(adv, local, local6, local_id); + if (!attr) + return NULL; + + /* Browse sub-TLV and fulfill Link State Attributes */ + if (CHECK_FLAG(tlvs->status, EXT_ADM_GRP)) { + attr->standard.admin_group = tlvs->adm_group; + SET_FLAG(attr->flags, LS_ATTR_ADM_GRP); + } + if (CHECK_FLAG(tlvs->status, EXT_LLRI)) { + attr->standard.local_id = tlvs->local_llri; + attr->standard.remote_id = tlvs->remote_llri; + SET_FLAG(attr->flags, LS_ATTR_LOCAL_ID); + SET_FLAG(attr->flags, LS_ATTR_NEIGH_ID); + } + if (CHECK_FLAG(tlvs->status, EXT_NEIGH_ADDR)) { + attr->standard.remote.s_addr = tlvs->neigh_addr.s_addr; + SET_FLAG(attr->flags, LS_ATTR_NEIGH_ADDR); + } + if (CHECK_FLAG(tlvs->status, EXT_NEIGH_ADDR6)) { + memcpy(&attr->standard.remote6, &tlvs->neigh_addr6, + IPV6_MAX_BYTELEN); + SET_FLAG(attr->flags, LS_ATTR_NEIGH_ADDR6); + } + if (CHECK_FLAG(tlvs->status, EXT_MAX_BW)) { + attr->standard.max_bw = tlvs->max_bw; + SET_FLAG(attr->flags, LS_ATTR_MAX_BW); + } + if (CHECK_FLAG(tlvs->status, EXT_MAX_RSV_BW)) { + attr->standard.max_rsv_bw = tlvs->max_rsv_bw; + SET_FLAG(attr->flags, LS_ATTR_MAX_RSV_BW); + } + if (CHECK_FLAG(tlvs->status, EXT_UNRSV_BW)) { + memcpy(&attr->standard.unrsv_bw, tlvs->unrsv_bw, + ISIS_SUBTLV_UNRSV_BW_SIZE); + SET_FLAG(attr->flags, LS_ATTR_UNRSV_BW); + } + if (CHECK_FLAG(tlvs->status, EXT_TE_METRIC)) { + attr->standard.te_metric = tlvs->te_metric; + SET_FLAG(attr->flags, LS_ATTR_TE_METRIC); + } + if (CHECK_FLAG(tlvs->status, EXT_RMT_AS)) { + attr->standard.remote_as = tlvs->remote_as; + SET_FLAG(attr->flags, LS_ATTR_REMOTE_AS); + } + if (CHECK_FLAG(tlvs->status, EXT_RMT_IP)) { + attr->standard.remote_addr = tlvs->remote_ip; + SET_FLAG(attr->flags, LS_ATTR_REMOTE_ADDR); + } + if (CHECK_FLAG(tlvs->status, EXT_DELAY)) { + attr->extended.delay = tlvs->delay; + SET_FLAG(attr->flags, LS_ATTR_DELAY); + } + if (CHECK_FLAG(tlvs->status, EXT_MM_DELAY)) { + attr->extended.min_delay = tlvs->min_delay; + attr->extended.max_delay = tlvs->max_delay; + SET_FLAG(attr->flags, LS_ATTR_MIN_MAX_DELAY); + } + if (CHECK_FLAG(tlvs->status, EXT_DELAY_VAR)) { + attr->extended.jitter = tlvs->delay_var; + SET_FLAG(attr->flags, LS_ATTR_JITTER); + } + if (CHECK_FLAG(tlvs->status, EXT_PKT_LOSS)) { + attr->extended.pkt_loss = tlvs->pkt_loss; + SET_FLAG(attr->flags, LS_ATTR_PACKET_LOSS); + } + if (CHECK_FLAG(tlvs->status, EXT_AVA_BW)) { + attr->extended.ava_bw = tlvs->ava_bw; + SET_FLAG(attr->flags, LS_ATTR_AVA_BW); + } + if (CHECK_FLAG(tlvs->status, EXT_RES_BW)) { + attr->extended.rsv_bw = tlvs->res_bw; + SET_FLAG(attr->flags, LS_ATTR_RSV_BW); + } + if (CHECK_FLAG(tlvs->status, EXT_USE_BW)) { + attr->extended.used_bw = tlvs->use_bw; + SET_FLAG(attr->flags, LS_ATTR_USE_BW); + } + if (CHECK_FLAG(tlvs->status, EXT_ADJ_SID)) { + struct isis_adj_sid *adj = + (struct isis_adj_sid *)tlvs->adj_sid.head; + int i; + for (; adj; adj = adj->next) { + i = adj->flags & EXT_SUBTLV_LINK_ADJ_SID_BFLG ? 1 : 0; + i += adj->flags & EXT_SUBTLV_LINK_ADJ_SID_FFLG ? 2 : 0; + attr->adj_sid[i].flags = adj->flags; + attr->adj_sid[i].weight = adj->weight; + attr->adj_sid[i].sid = adj->sid; + switch (i) { + case ADJ_PRI_IPV4: + SET_FLAG(attr->flags, LS_ATTR_ADJ_SID); + break; + case ADJ_BCK_IPV4: + SET_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SID); + break; + case ADJ_PRI_IPV6: + SET_FLAG(attr->flags, LS_ATTR_ADJ_SID6); + break; + case ADJ_BCK_IPV6: + SET_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SID6); + break; + } + } + } + if (CHECK_FLAG(tlvs->status, EXT_LAN_ADJ_SID)) { + struct isis_lan_adj_sid *ladj = + (struct isis_lan_adj_sid *)tlvs->lan_sid.head; + int i; + for (; ladj; ladj = ladj->next) { + i = ladj->flags & EXT_SUBTLV_LINK_ADJ_SID_BFLG ? 1 : 0; + i += ladj->flags & EXT_SUBTLV_LINK_ADJ_SID_FFLG ? 2 : 0; + attr->adj_sid[i].flags = ladj->flags; + attr->adj_sid[i].weight = ladj->weight; + attr->adj_sid[i].sid = ladj->sid; + memcpy(&attr->adj_sid[i].neighbor.sysid, + &ladj->neighbor_id, ISIS_SYS_ID_LEN); + switch (i) { + case ADJ_PRI_IPV4: + SET_FLAG(attr->flags, LS_ATTR_ADJ_SID); + break; + case ADJ_BCK_IPV4: + SET_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SID); + break; + case ADJ_PRI_IPV6: + SET_FLAG(attr->flags, LS_ATTR_ADJ_SID6); + break; + case ADJ_BCK_IPV6: + SET_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SID6); + break; + } + } + } + + return attr; +} + +/** + * Parse Extended Reachability TLVs and create or update the corresponding + * Link State Edge and Attributes. Vertex connections are also updated if + * needed based on the remote IP address of the Edge and existing reverse Edge. + * + * @param id ID of Extended IS + * @param metric Metric of the link + * @param old_metric Boolean that indicate if it is an old metric (no TE) + * @param tlvs SubTlvs that contains TE information + * @param arg IS-IS TE argument (TED, Vertex, and export indication) + * + * @return 0 if success, -1 otherwise + */ +static int lsp_to_edge_cb(const uint8_t *id, uint32_t metric, bool old_metric, + struct isis_ext_subtlvs *tlvs, void *arg) +{ + struct isis_te_args *args = (struct isis_te_args *)arg; + struct ls_vertex *vertex; + struct ls_edge *edge, *dst; + struct ls_attributes *attr; + + te_debug(" |- Process Extended IS for %s", sysid_print(id)); + + /* Check parameters */ + if (old_metric || !args || !tlvs) + return LSP_ITER_CONTINUE; + + /* Initialize Link State Attributes */ + vertex = args->vertex; + attr = get_attributes(vertex->node->adv, tlvs); + /* + * Attributes may be Null if no local ID has been found in the LSP. + * Stop processing here as without any local ID it is not possible to + * create corresponding Edge in the TED. + */ + if (!attr) + return LSP_ITER_CONTINUE; + + attr->metric = metric; + + /* Get corresponding Edge from Link State Data Base */ + edge = get_edge(args->ted, attr); + /* + * Edge could be Null if no local ID has been found in Attributes. + * Stop processing here as without any local ID it is not possible to + * create corresponding Edge in the TED. + */ + if (!edge) { + ls_attributes_del(attr); + return LSP_ITER_CONTINUE; + } + + /* Update Attribute fields if there are different */ + if (edge->status != NEW) { + if (!ls_attributes_same(edge->attributes, attr)) { + te_debug(" |- Update Edge Attributes information"); + ls_attributes_del(edge->attributes); + edge->attributes = attr; + edge->status = UPDATE; + } else { + if (edge->attributes != attr) + ls_attributes_del(attr); + edge->status = SYNC; + } + } + + /* Try to update remote Link from remote address or reachability ID */ + te_debug(" |- Link Edge (%" PRIu64 ") to destination vertex (%s)", + edge->key, print_sys_hostname(id)); + dst = ls_find_edge_by_destination(args->ted, edge->attributes); + if (dst) { + /* Attach remote link if not set */ + if (edge->source && dst->destination == NULL) { + vertex = edge->source; + if (vertex->incoming_edges) + listnode_add_sort_nodup(vertex->incoming_edges, + dst); + dst->destination = vertex; + } + /* and destination vertex to this edge if not set */ + if (dst->source && edge->destination == NULL) { + vertex = dst->source; + if (vertex->incoming_edges) + listnode_add_sort_nodup(vertex->incoming_edges, + edge); + edge->destination = vertex; + } + } else { + /* Search dst. Vertex by Extended Reach. ID if not found */ + if (edge->destination == NULL) { + vertex = ls_find_vertex_by_key(args->ted, + sysid_to_key(id)); + if (vertex && vertex->incoming_edges) + listnode_add_sort_nodup(vertex->incoming_edges, + edge); + edge->destination = vertex; + } + } + + /* Update status and Export Link State Edge if needed */ + if (edge->status != SYNC) { + if (args->export) + isis_te_export(LS_MSG_TYPE_ATTRIBUTES, edge); + edge->status = SYNC; + } + + return LSP_ITER_CONTINUE; +} + +/** + * Parse Extended IP Reachability or MT IPv6 Reachability TLVs and create or + * update the corresponding Link State Subnet and Prefix. + * + * @param prefix Prefix associated to this subnet + * @param metric Metric of this prefix + * @param external Boolean to indicate if the prefix is external + * @param subtlvs Subtlvs if any (mostly Segment Routing ID) + * @param arg IS-IS TE argument (TED, Vertex, and export indication) + * + * @return 0 if success, -1 otherwise + */ +static int lsp_to_subnet_cb(const struct prefix *prefix, uint32_t metric, + bool external, struct isis_subtlvs *subtlvs, + void *arg) +{ + struct isis_te_args *args = (struct isis_te_args *)arg; + struct ls_vertex *vertex; + struct ls_subnet *subnet; + struct ls_prefix *ls_pref; + struct listnode *node; + struct ls_edge *edge; + struct ls_standard *std = NULL; + struct prefix p; + + /* Sanity Check */ + if (!args || !prefix) + return LSP_ITER_CONTINUE; + + te_debug(" |- Process Extended %s Reachability %pFX", + prefix->family == AF_INET ? "IP" : "IPv6", prefix); + + vertex = args->vertex; + + /* + * Prefix with mask different from /32 or /128 are advertised by at + * least 2 nodes. To avoid subnet attached to undetermined vertex, and + * gives the possibility to send the information to client e.g. BGP for + * Link State advertisement, we adjust the prefix with the corresponding + * IP address of the belonging interface when it is available. Other + * prefixes are kept unchanged. + */ + if (prefix->family == AF_INET && prefix->prefixlen < IPV4_MAX_BITLEN) { + std = NULL; + for (ALL_LIST_ELEMENTS_RO(vertex->outgoing_edges, node, edge)) { + if (!CHECK_FLAG(edge->attributes->flags, + LS_ATTR_LOCAL_ADDR)) + continue; + + p.u.prefix4 = edge->attributes->standard.local; + p.family = AF_INET; + p.prefixlen = prefix->prefixlen; + apply_mask_ipv4((struct prefix_ipv4 *)&p); + if (IPV4_ADDR_SAME(&p.u.prefix4, &prefix->u.prefix4)) { + std = &edge->attributes->standard; + break; + } + } + if (std) + p.u.prefix4 = std->local; + + } else if (prefix->family == AF_INET6 + && prefix->prefixlen < IPV6_MAX_BITLEN) { + std = NULL; + for (ALL_LIST_ELEMENTS_RO(vertex->outgoing_edges, node, edge)) { + if (!CHECK_FLAG(edge->attributes->flags, + LS_ATTR_LOCAL_ADDR6)) + continue; + + p.u.prefix6 = edge->attributes->standard.local6; + p.family = AF_INET6; + p.prefixlen = prefix->prefixlen; + apply_mask_ipv6((struct prefix_ipv6 *)&p); + if (IPV6_ADDR_SAME(&p.u.prefix6, &prefix->u.prefix6)) { + std = &edge->attributes->standard; + break; + } + } + if (std) + p.u.prefix6 = std->local6; + } + if (!std) + p = *prefix; + else + te_debug(" |- Adjust prefix %pFX with local address to: %pFX", + prefix, &p); + + /* Search existing Subnet in TED ... */ + subnet = ls_find_subnet(args->ted, p); + /* ... and create a new Subnet if not found */ + if (!subnet) { + ls_pref = ls_prefix_new(vertex->node->adv, p); + subnet = ls_subnet_add(args->ted, ls_pref); + if (!subnet) + return LSP_ITER_CONTINUE; + } + ls_pref = subnet->ls_pref; + + te_debug(" |- %s Subnet from prefix %pFX", + subnet->status == NEW ? "Create" : "Found", &p); + + /* Update Metric */ + if (!CHECK_FLAG(ls_pref->flags, LS_PREF_METRIC) + || (ls_pref->metric != metric)) { + ls_pref->metric = metric; + SET_FLAG(ls_pref->flags, LS_PREF_METRIC); + if (subnet->status != NEW) + subnet->status = UPDATE; + } else { + if (subnet->status == ORPHAN) + subnet->status = SYNC; + } + + /* Update Prefix SID if any */ + if (subtlvs && subtlvs->prefix_sids.count != 0) { + struct isis_prefix_sid *psid; + struct ls_sid sr = {}; + + psid = (struct isis_prefix_sid *)subtlvs->prefix_sids.head; + sr.algo = psid->algorithm; + sr.sid_flag = psid->flags; + sr.sid = psid->value; + + if (!CHECK_FLAG(ls_pref->flags, LS_PREF_SR) + || !memcmp(&ls_pref->sr, &sr, sizeof(struct ls_sid))) { + memcpy(&ls_pref->sr, &sr, sizeof(struct ls_sid)); + SET_FLAG(ls_pref->flags, LS_PREF_SR); + if (subnet->status != NEW) + subnet->status = UPDATE; + } else { + if (subnet->status == ORPHAN) + subnet->status = SYNC; + } + } else { + if (CHECK_FLAG(ls_pref->flags, LS_PREF_SR)) { + UNSET_FLAG(ls_pref->flags, LS_PREF_SR); + if (subnet->status != NEW) + subnet->status = UPDATE; + } else { + if (subnet->status == ORPHAN) + subnet->status = SYNC; + } + } + + /* Update status and Export Link State Edge if needed */ + if (subnet->status != SYNC) { + if (args->export) + isis_te_export(LS_MSG_TYPE_PREFIX, subnet); + subnet->status = SYNC; + } + + return LSP_ITER_CONTINUE; +} + +/** + * Parse ISIS LSP to fulfill the Link State Database + * + * @param ted Link State Database + * @param lsp ISIS Link State PDU + */ +static void isis_te_parse_lsp(struct mpls_te_area *mta, struct isis_lsp *lsp) +{ + struct ls_ted *ted; + struct ls_vertex *vertex; + struct ls_edge *edge; + struct ls_subnet *subnet; + struct listnode *node; + struct isis_te_args args; + + /* Sanity Check */ + if (!IS_MPLS_TE(mta) || !mta->ted || !lsp) + return; + + ted = mta->ted; + + te_debug("ISIS-TE(%s): Parse LSP %s", lsp->area->area_tag, + sysid_print(lsp->hdr.lsp_id)); + + /* First parse LSP to obtain the corresponding Vertex */ + vertex = lsp_to_vertex(ted, lsp); + if (!vertex) { + zlog_warn("Unable to build Vertex from LSP %s. Abort!", + sysid_print(lsp->hdr.lsp_id)); + return; + } + + /* Check if Vertex has been modified */ + if (vertex->status != SYNC) { + /* Vertex is out of sync: export it if requested */ + if (IS_EXPORT_TE(mta)) + isis_te_export(LS_MSG_TYPE_NODE, vertex); + vertex->status = SYNC; + } + + /* Mark outgoing Edges and Subnets as ORPHAN to detect deletion */ + for (ALL_LIST_ELEMENTS_RO(vertex->outgoing_edges, node, edge)) + edge->status = ORPHAN; + + for (ALL_LIST_ELEMENTS_RO(vertex->prefixes, node, subnet)) + subnet->status = ORPHAN; + + /* Process all Extended Reachability in LSP (all fragments) */ + args.ted = ted; + args.vertex = vertex; + args.export = mta->export; + isis_lsp_iterate_is_reach(lsp, ISIS_MT_IPV4_UNICAST, lsp_to_edge_cb, + &args); + + isis_lsp_iterate_is_reach(lsp, ISIS_MT_IPV6_UNICAST, lsp_to_edge_cb, + &args); + + /* Process all Extended IP (v4 & v6) in LSP (all fragments) */ + isis_lsp_iterate_ip_reach(lsp, AF_INET, ISIS_MT_IPV4_UNICAST, + lsp_to_subnet_cb, &args); + isis_lsp_iterate_ip_reach(lsp, AF_INET6, ISIS_MT_IPV6_UNICAST, + lsp_to_subnet_cb, &args); + isis_lsp_iterate_ip_reach(lsp, AF_INET6, ISIS_MT_IPV4_UNICAST, + lsp_to_subnet_cb, &args); + + /* Clean remaining Orphan Edges or Subnets */ + if (IS_EXPORT_TE(mta)) + ls_vertex_clean(ted, vertex, zclient); + else + ls_vertex_clean(ted, vertex, NULL); +} + +/** + * Delete Link State Database Vertex, Edge & Prefix that correspond to this + * ISIS Link State PDU + * + * @param ted Link State Database + * @param lsp ISIS Link State PDU + */ +static void isis_te_delete_lsp(struct mpls_te_area *mta, struct isis_lsp *lsp) +{ + struct ls_ted *ted; + struct ls_vertex *vertex = NULL; + struct ls_node lnode = {}; + struct ls_edge *edge; + struct ls_subnet *subnet; + struct listnode *nnode, *node; + + /* Sanity Check */ + if (!IS_MPLS_TE(mta) || !mta->ted || !lsp) + return; + + te_debug("ISIS-TE(%s): Delete Link State TED objects from LSP %s", + lsp->area->area_tag, sysid_print(lsp->hdr.lsp_id)); + + /* Compute Link State Node ID from IS-IS sysID ... */ + if (lsp->level == ISIS_LEVEL1) + lnode.adv.origin = ISIS_L1; + else + lnode.adv.origin = ISIS_L2; + memcpy(&lnode.adv.id.iso.sys_id, &lsp->hdr.lsp_id, ISIS_SYS_ID_LEN); + lnode.adv.id.iso.level = lsp->level; + ted = mta->ted; + /* ... and search the corresponding vertex */ + vertex = ls_find_vertex_by_id(ted, lnode.adv); + if (!vertex) + return; + + te_debug(" |- Delete Vertex %s", vertex->node->name); + + /* + * We can't use the ls_vertex_del_all() function if export TE is set, + * as we must first advertise the client daemons of each removal. + */ + /* Remove outgoing Edges */ + for (ALL_LIST_ELEMENTS(vertex->outgoing_edges, node, nnode, edge)) { + if (IS_EXPORT_TE(mta)) { + edge->status = DELETE; + isis_te_export(LS_MSG_TYPE_ATTRIBUTES, edge); + } + ls_edge_del_all(ted, edge); + } + + /* Disconnect incoming Edges */ + for (ALL_LIST_ELEMENTS(vertex->incoming_edges, node, nnode, edge)) { + ls_disconnect(vertex, edge, false); + if (edge->source == NULL) { + if (IS_EXPORT_TE(mta)) { + edge->status = DELETE; + isis_te_export(LS_MSG_TYPE_ATTRIBUTES, edge); + } + ls_edge_del_all(ted, edge); + } + } + + /* Remove subnets */ + for (ALL_LIST_ELEMENTS(vertex->prefixes, node, nnode, subnet)) { + if (IS_EXPORT_TE(mta)) { + subnet->status = DELETE; + isis_te_export(LS_MSG_TYPE_PREFIX, subnet); + } + ls_subnet_del_all(ted, subnet); + } + + /* Then remove Link State Node */ + if (IS_EXPORT_TE(mta)) { + vertex->status = DELETE; + isis_te_export(LS_MSG_TYPE_NODE, vertex); + } + ls_node_del(vertex->node); + + /* Finally, remove Vertex */ + ls_vertex_del(ted, vertex); +} + +/** + * Process ISIS LSP according to the event to add, update or remove + * corresponding vertex, edge and prefix in the Link State database. + * Since LSP could be fragmented, the function starts by searching the root LSP + * to retrieve the complete LSP, including eventual fragment before processing + * all of them. + * + * @param lsp ISIS Link State PDU + * @param event LSP event: ADD, UPD, INC & DEL (TICK are ignored) + * + */ +void isis_te_lsp_event(struct isis_lsp *lsp, enum lsp_event event) +{ + struct isis_area *area; + struct isis_lsp *lsp0; + + /* Sanity check */ + if (!lsp || !lsp->area) + return; + + area = lsp->area; + if (!IS_MPLS_TE(area->mta)) + return; + + /* Adjust LSP0 in case of fragment */ + if (LSP_FRAGMENT(lsp->hdr.lsp_id)) + lsp0 = lsp->lspu.zero_lsp; + else + lsp0 = lsp; + + /* Then process event */ + switch (event) { + case LSP_ADD: + case LSP_UPD: + case LSP_INC: + isis_te_parse_lsp(area->mta, lsp0); + break; + case LSP_DEL: + isis_te_delete_lsp(area->mta, lsp0); + break; + default: + break; + } +} + +/** + * Send the whole Link State Traffic Engineering Database to the consumer that + * request it through a ZAPI Link State Synchronous Opaque Message. + * + * @param info ZAPI Opaque message + * + * @return 0 if success, -1 otherwise + */ +int isis_te_sync_ted(struct zapi_opaque_reg_info dst) +{ + struct listnode *node, *inode; + struct isis *isis; + struct isis_area *area; + struct mpls_te_area *mta; + int rc = -1; + + te_debug("ISIS-TE(%s): Received TED synchro from client %d", __func__, + dst.proto); + /* For each area, send TED if TE distribution is enabled */ + for (ALL_LIST_ELEMENTS_RO(im->isis, inode, isis)) { + for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) { + mta = area->mta; + if (IS_MPLS_TE(mta) && IS_EXPORT_TE(mta)) { + te_debug(" |- Export TED from area %s", + area->area_tag); + rc = ls_sync_ted(mta->ted, zclient, &dst); + if (rc != 0) + return rc; + } + } + } + + return rc; +} + +/** + * Initialize the Link State database from the LSP already stored for this area + * + * @param area ISIS area + */ +void isis_te_init_ted(struct isis_area *area) +{ + struct isis_lsp *lsp; + + /* Iterate over all lsp. */ + for (int level = ISIS_LEVEL1; level <= ISIS_LEVELS; level++) + frr_each (lspdb, &area->lspdb[level - 1], lsp) + isis_te_parse_lsp(area->mta, lsp); +} + /* Followings are vty command functions */ #ifndef FABRICD +static void show_router_id(struct vty *vty, struct isis_area *area) +{ + bool no_match = true; + + vty_out(vty, "Area %s:\n", area->area_tag); + if (area->mta->router_id.s_addr != 0) { + vty_out(vty, " MPLS-TE IPv4 Router-Address: %pI4\n", + &area->mta->router_id); + no_match = false; + } + if (!IN6_IS_ADDR_UNSPECIFIED(&area->mta->router_id_ipv6)) { + vty_out(vty, " MPLS-TE IPv6 Router-Address: %pI6\n", + &area->mta->router_id_ipv6); + no_match = false; + } + if (no_match) + vty_out(vty, " N/A\n"); +} + DEFUN(show_isis_mpls_te_router, show_isis_mpls_te_router_cmd, "show " PROTO_NAME " [vrf ] mpls-te router", @@ -331,15 +1281,7 @@ DEFUN(show_isis_mpls_te_router, if (!IS_MPLS_TE(area->mta)) continue; - vty_out(vty, "Area %s:\n", - area->area_tag); - if (ntohs(area->mta->router_id.s_addr) - != 0) - vty_out(vty, - " MPLS-TE Router-Address: %pI4\n", - &area->mta->router_id); - else - vty_out(vty, " N/A\n"); + show_router_id(vty, area); } } return 0; @@ -352,13 +1294,7 @@ DEFUN(show_isis_mpls_te_router, if (!IS_MPLS_TE(area->mta)) continue; - vty_out(vty, "Area %s:\n", area->area_tag); - if (ntohs(area->mta->router_id.s_addr) != 0) - vty_out(vty, - " MPLS-TE Router-Address: %pI4\n", - &area->mta->router_id); - else - vty_out(vty, " N/A\n"); + show_router_id(vty, area); } } } @@ -528,7 +1464,308 @@ DEFUN (show_isis_mpls_te_interface, return CMD_SUCCESS; } -#endif + +/** + * Search Vertex in TED that corresponds to the given string that represent + * the ISO system ID in the forms [.-] + * + * @param ted Link State Database + * @param id ISO System ID + * @param isis Main reference to the isis daemon + * + * @return Vertex if found, NULL otherwise + */ +static struct ls_vertex *vertex_for_arg(struct ls_ted *ted, const char *id, + struct isis *isis) +{ + char sysid[255] = {0}; + uint8_t number[3]; + const char *pos; + uint8_t lspid[ISIS_SYS_ID_LEN + 2] = {0}; + struct isis_dynhn *dynhn; + uint64_t key = 0; + + if (!id) + return NULL; + + /* + * extract fragment and pseudo id from the string argv + * in the forms: + * (a) .- or + * (b) . or + * (c) or + * Where systemid is in the form: + * xxxx.xxxx.xxxx + */ + strlcpy(sysid, id, sizeof(sysid)); + if (strlen(id) > 3) { + pos = id + strlen(id) - 3; + if (strncmp(pos, "-", 1) == 0) { + memcpy(number, ++pos, 2); + lspid[ISIS_SYS_ID_LEN + 1] = + (uint8_t)strtol((char *)number, NULL, 16); + pos -= 4; + if (strncmp(pos, ".", 1) != 0) + return NULL; + } + if (strncmp(pos, ".", 1) == 0) { + memcpy(number, ++pos, 2); + lspid[ISIS_SYS_ID_LEN] = + (uint8_t)strtol((char *)number, NULL, 16); + sysid[pos - id - 1] = '\0'; + } + } + + /* + * Try to find the lsp-id if the argv + * string is in + * the form + * hostname.- + */ + if (sysid2buff(lspid, sysid)) { + key = sysid_to_key(lspid); + } else if ((dynhn = dynhn_find_by_name(isis, sysid))) { + memcpy(lspid, dynhn->id, ISIS_SYS_ID_LEN); + key = sysid_to_key(lspid); + } else if (strncmp(cmd_hostname_get(), sysid, 15) == 0) { + memcpy(lspid, isis->sysid, ISIS_SYS_ID_LEN); + key = sysid_to_key(lspid); + } + + if (key == 0) + return NULL; + + return ls_find_vertex_by_key(ted, key); +} + +/** + * Show Link State Traffic Engineering Database extracted from IS-IS LSP. + * + * @param vty VTY output console + * @param argv Command line argument + * @param argc Number of command line argument + * @param ted Traffic Engineering Database + * @param isis isis Main reference to the isis daemon + * + * @return Command Success if OK, Command Warning otherwise + */ +static int show_ted(struct vty *vty, struct cmd_token *argv[], int argc, + struct isis_area *area, struct isis *isis) +{ + int idx; + char *id; + struct in_addr ip_addr; + struct in6_addr ip6_addr; + struct prefix pref; + struct ls_ted *ted; + struct ls_vertex *vertex; + struct ls_edge *edge; + struct ls_subnet *subnet; + uint64_t key; + bool detail = false; + bool uj = use_json(argc, argv); + json_object *json = NULL; + + if (!IS_MPLS_TE(area->mta) || !area->mta->ted) { + vty_out(vty, "MPLS-TE is disabled for Area %s\n", + area->area_tag ? area->area_tag : "null"); + return CMD_SUCCESS; + } + + ted = area->mta->ted; + + if (uj) + json = json_object_new_object(); + else + vty_out(vty, "Area %s:\n", + area->area_tag ? area->area_tag : "null"); + + if (argv[argc - 1]->arg && strmatch(argv[argc - 1]->text, "detail")) + detail = true; + + idx = 4; + if (argv_find(argv, argc, "vertex", &idx)) { + /* Show Vertex */ + id = argv_find(argv, argc, "WORD", &idx) ? argv[idx]->arg + : NULL; + if (!id) + vertex = NULL; + else if (!strncmp(id, "self", 4)) + vertex = ted->self; + else { + vertex = vertex_for_arg(ted, id, isis); + if (!vertex) { + vty_out(vty, "No vertex found for ID %s\n", id); + return CMD_WARNING; + } + } + + if (vertex) + ls_show_vertex(vertex, vty, json, detail); + else + ls_show_vertices(ted, vty, json, detail); + + } else if (argv_find(argv, argc, "edge", &idx)) { + /* Show Edge */ + if (argv_find(argv, argc, "A.B.C.D", &idx)) { + if (!inet_pton(AF_INET, argv[idx]->arg, &ip_addr)) { + vty_out(vty, + "Specified Edge ID %s is invalid\n", + argv[idx]->arg); + return CMD_WARNING_CONFIG_FAILED; + } + /* Get the Edge from the Link State Database */ + key = ((uint64_t)ntohl(ip_addr.s_addr)) & 0xffffffff; + edge = ls_find_edge_by_key(ted, key); + if (!edge) { + vty_out(vty, "No edge found for ID %pI4\n", + &ip_addr); + return CMD_WARNING; + } + } else if (argv_find(argv, argc, "X:X::X:X", &idx)) { + if (!inet_pton(AF_INET6, argv[idx]->arg, &ip6_addr)) { + vty_out(vty, + "Specified Edge ID %s is invalid\n", + argv[idx]->arg); + return CMD_WARNING_CONFIG_FAILED; + } + /* Get the Edge from the Link State Database */ + key = (uint64_t)ntohl(ip6_addr.s6_addr32[3]) + | ((uint64_t)ntohl(ip6_addr.s6_addr32[2]) << 32); + edge = ls_find_edge_by_key(ted, key); + if (!edge) { + vty_out(vty, "No edge found for ID %pI6\n", + &ip6_addr); + return CMD_WARNING; + } + } else + edge = NULL; + + if (edge) + ls_show_edge(edge, vty, json, detail); + else + ls_show_edges(ted, vty, json, detail); + + } else if (argv_find(argv, argc, "subnet", &idx)) { + /* Show Subnet */ + if (argv_find(argv, argc, "A.B.C.D/M", &idx)) { + if (!str2prefix(argv[idx]->arg, &pref)) { + vty_out(vty, "Invalid prefix format %s\n", + argv[idx]->arg); + return CMD_WARNING_CONFIG_FAILED; + } + /* Get the Subnet from the Link State Database */ + subnet = ls_find_subnet(ted, pref); + if (!subnet) { + vty_out(vty, "No subnet found for ID %pFX\n", + &pref); + return CMD_WARNING; + } + } else if (argv_find(argv, argc, "X:X::X:X/M", &idx)) { + if (!str2prefix(argv[idx]->arg, &pref)) { + vty_out(vty, "Invalid prefix format %s\n", + argv[idx]->arg); + return CMD_WARNING_CONFIG_FAILED; + } + /* Get the Subnet from the Link State Database */ + subnet = ls_find_subnet(ted, pref); + if (!subnet) { + vty_out(vty, "No subnet found for ID %pFX\n", + &pref); + return CMD_WARNING; + } + } else + subnet = NULL; + + if (subnet) + ls_show_subnet(subnet, vty, json, detail); + else + ls_show_subnets(ted, vty, json, detail); + + } else { + /* Show the complete TED */ + ls_show_ted(ted, vty, json, detail); + } + + if (uj) { + vty_out(vty, "%s\n", + json_object_to_json_string_ext( + json, JSON_C_TO_STRING_PRETTY)); + json_object_free(json); + } + + return CMD_SUCCESS; +} + +/** + * Show ISIS Traffic Engineering Database + * + * @param vty VTY output console + * @param argv Command line argument + * @param argc Number of command line argument + * @param isis isis Main reference to the isis daemon + + * @return Command Success if OK, Command Warning otherwise + */ +static int show_isis_ted(struct vty *vty, struct cmd_token *argv[], int argc, + struct isis *isis) +{ + struct listnode *node; + struct isis_area *area; + int rc; + + for (ALL_LIST_ELEMENTS_RO(isis->area_list, node, area)) { + rc = show_ted(vty, argv, argc, area, isis); + if (rc != CMD_SUCCESS) + return rc; + } + return CMD_SUCCESS; +} + +DEFUN(show_isis_mpls_te_db, + show_isis_mpls_te_db_cmd, + "show " PROTO_NAME " [vrf ] mpls-te database [] [detail|json]", + SHOW_STR PROTO_HELP VRF_CMD_HELP_STR + "All VRFs\n" + MPLS_TE_STR + "MPLS-TE database\n" + "MPLS-TE Vertex\n" + "MPLS-TE Vertex ID (as an ISO ID, hostname or \"self\")\n" + "MPLS-TE Edge\n" + "MPLS-TE Edge ID (as an IPv4 address)\n" + "MPLS-TE Edge ID (as an IPv6 address)\n" + "MPLS-TE Subnet\n" + "MPLS-TE Subnet ID (as an IPv4 prefix)\n" + "MPLS-TE Subnet ID (as an IPv6 prefix)\n" + "Detailed information\n" + JSON_STR) +{ + int idx_vrf = 0; + const char *vrf_name = VRF_DEFAULT_NAME; + bool all_vrf = false; + struct listnode *node; + struct isis *isis; + int rc = CMD_WARNING; + + ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf); + if (vrf_name) { + if (all_vrf) { + for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis)) { + rc = show_isis_ted(vty, argv, argc, isis); + if (rc != CMD_SUCCESS) + return rc; + } + return CMD_SUCCESS; + } + isis = isis_lookup_by_vrfname(vrf_name); + if (isis) + rc = show_isis_ted(vty, argv, argc, isis); + } + + return rc; +} + +#endif /* #ifndef FRABRICD */ /* Initialize MPLS_TE */ void isis_mpls_te_init(void) @@ -536,13 +1773,14 @@ void isis_mpls_te_init(void) /* Register Circuit and Adjacency hook */ hook_register(isis_if_new_hook, isis_mpls_te_update); - hook_register(isis_adj_state_change_hook, isis_link_update_adj_hook); - + hook_register(isis_adj_ip_enabled_hook, isis_mpls_te_adj_ip_enabled); + hook_register(isis_adj_ip_disabled_hook, isis_mpls_te_adj_ip_disabled); #ifndef FABRICD /* Register new VTY commands */ install_element(VIEW_NODE, &show_isis_mpls_te_router_cmd); install_element(VIEW_NODE, &show_isis_mpls_te_interface_cmd); + install_element(VIEW_NODE, &show_isis_mpls_te_db_cmd); #endif return; diff --git a/isisd/isis_te.h b/isisd/isis_te.h index 2a6911d500..56954073dd 100644 --- a/isisd/isis_te.h +++ b/isisd/isis_te.h @@ -88,8 +88,10 @@ typedef enum _interas_mode_t { off, region, as, emulate } interas_mode_t; && e->status != EXT_ADJ_SID \ && e->status != EXT_LAN_ADJ_SID) #define IS_MPLS_TE(a) (a && a->status == enable) +#define IS_EXPORT_TE(a) (a->export) /* Per area MPLS-TE parameters */ +struct ls_ted; struct mpls_te_area { /* Status of MPLS-TE: enable or disable */ status_t status; @@ -101,13 +103,30 @@ struct mpls_te_area { interas_mode_t inter_as; struct in_addr interas_areaid; - /* MPLS_TE router ID */ + /* MPLS_TE IPv4 & IPv6 Router IDs */ struct in_addr router_id; + struct in6_addr router_id_ipv6; + + /* Link State Database */ + struct ls_ted *ted; + bool export; }; +/* Structure to provide parameters to lsp iterate callback function */ +struct isis_te_args { + struct ls_ted *ted; + struct ls_vertex *vertex; + bool export; +}; + +enum lsp_event { LSP_UNKNOWN, LSP_ADD, LSP_UPD, LSP_DEL, LSP_INC, LSP_TICK }; + /* Prototypes. */ void isis_mpls_te_init(void); void isis_link_params_update(struct isis_circuit *, struct interface *); int isis_mpls_te_update(struct interface *); +void isis_te_lsp_event(struct isis_lsp *lsp, enum lsp_event event); +int isis_te_sync_ted(struct zapi_opaque_reg_info dst); +void isis_te_init_ted(struct isis_area *area); #endif /* _ZEBRA_ISIS_MPLS_TE_H */ diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c index a66d3b00f7..9a442e0374 100644 --- a/isisd/isis_tlvs.c +++ b/isisd/isis_tlvs.c @@ -99,6 +99,7 @@ static const struct pack_order_entry pack_order[] = { PACK_ENTRY(OLDSTYLE_IP_REACH_EXT, ISIS_ITEMS, oldstyle_ip_reach_ext), PACK_ENTRY(IPV4_ADDRESS, ISIS_ITEMS, ipv4_address), PACK_ENTRY(IPV6_ADDRESS, ISIS_ITEMS, ipv6_address), + PACK_ENTRY(GLOBAL_IPV6_ADDRESS, ISIS_ITEMS, global_ipv6_address), PACK_ENTRY(EXTENDED_IP_REACH, ISIS_ITEMS, extended_ip_reach), PACK_ENTRY(MT_IP_REACH, ISIS_MT_ITEMS, mt_ip_reach), PACK_ENTRY(IPV6_REACH, ISIS_ITEMS, ipv6_reach), @@ -128,27 +129,41 @@ struct isis_ext_subtlvs *isis_alloc_ext_subtlvs(void) } /* - * mtid parameter is used to determine if Adjacency is related to IPv4 or IPv6. - * A negative value could be used to skip copy of Adjacency SID. + * mtid parameter is used to determine if Adjacency is related to IPv4 or IPv6 + * Multi-Topology. Special 4096 value i.e. first R flag set is used to indicate + * that MT is disabled i.e. IS-IS is working with a Single Topology. */ static struct isis_ext_subtlvs * -copy_item_ext_subtlvs(struct isis_ext_subtlvs *exts, int16_t mtid) +copy_item_ext_subtlvs(struct isis_ext_subtlvs *exts, uint16_t mtid) { struct isis_ext_subtlvs *rv = XCALLOC(MTYPE_ISIS_SUBTLV, sizeof(*rv)); struct isis_adj_sid *adj; struct isis_lan_adj_sid *lan; + /* Copy the Extended IS main part */ memcpy(rv, exts, sizeof(struct isis_ext_subtlvs)); + + /* Disable IPv4 / IPv6 advertisement in function of MTID */ + if (mtid == ISIS_MT_IPV4_UNICAST) { + UNSET_SUBTLV(rv, EXT_LOCAL_ADDR6); + UNSET_SUBTLV(rv, EXT_NEIGH_ADDR6); + } + if (mtid == ISIS_MT_IPV6_UNICAST) { + UNSET_SUBTLV(rv, EXT_LOCAL_ADDR); + UNSET_SUBTLV(rv, EXT_NEIGH_ADDR); + } + + /* Prepare (LAN)-Adjacency Segment Routing ID*/ init_item_list(&rv->adj_sid); init_item_list(&rv->lan_sid); UNSET_SUBTLV(rv, EXT_ADJ_SID); UNSET_SUBTLV(rv, EXT_LAN_ADJ_SID); - /* Copy Adj SID and LAN Adj SID list for IPv4 if needed */ + /* Copy Adj SID list for IPv4 & IPv6 in function of MT ID */ for (adj = (struct isis_adj_sid *)exts->adj_sid.head; adj != NULL; adj = adj->next) { - if ((mtid != -1) + if ((mtid != ISIS_MT_DISABLE) && (((mtid == ISIS_MT_IPV4_UNICAST) && (adj->family != AF_INET)) || ((mtid == ISIS_MT_IPV6_UNICAST) @@ -166,9 +181,10 @@ copy_item_ext_subtlvs(struct isis_ext_subtlvs *exts, int16_t mtid) SET_SUBTLV(rv, EXT_ADJ_SID); } + /* Same for LAN Adj SID */ for (lan = (struct isis_lan_adj_sid *)exts->lan_sid.head; lan != NULL; lan = lan->next) { - if ((mtid != -1) + if ((mtid != ISIS_MT_DISABLE) && (((mtid == ISIS_MT_IPV4_UNICAST) && (lan->family != AF_INET)) || ((mtid == ISIS_MT_IPV6_UNICAST) @@ -196,8 +212,6 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, uint16_t mtid) { - char ibuf[PREFIX2STR_BUFFER]; - /* Standard metrics */ if (IS_SUBTLV(exts, EXT_ADM_GRP)) sbuf_push(buf, indent, "Administrative Group: 0x%x\n", @@ -212,16 +226,17 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, sbuf_push(buf, indent, "Local Interface IP Address(es): %pI4\n", &exts->local_addr); if (IS_SUBTLV(exts, EXT_NEIGH_ADDR)) - sbuf_push(buf, indent, "Remote Interface IP Address(es): %pI4\n", + sbuf_push(buf, indent, + "Remote Interface IP Address(es): %pI4\n", &exts->neigh_addr); if (IS_SUBTLV(exts, EXT_LOCAL_ADDR6)) - sbuf_push(buf, indent, "Local Interface IPv6 Address(es): %s\n", - inet_ntop(AF_INET6, &exts->local_addr6, ibuf, - PREFIX2STR_BUFFER)); + sbuf_push(buf, indent, + "Local Interface IPv6 Address(es): %pI6\n", + &exts->local_addr6); if (IS_SUBTLV(exts, EXT_NEIGH_ADDR6)) - sbuf_push(buf, indent, "Remote Interface IPv6 Address(es): %s\n", - inet_ntop(AF_INET6, &exts->local_addr6, ibuf, - PREFIX2STR_BUFFER)); + sbuf_push(buf, indent, + "Remote Interface IPv6 Address(es): %pI6\n", + &exts->neigh_addr6); if (IS_SUBTLV(exts, EXT_MAX_BW)) sbuf_push(buf, indent, "Maximum Bandwidth: %g (Bytes/sec)\n", exts->max_bw); @@ -289,11 +304,6 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, for (adj = (struct isis_adj_sid *)exts->adj_sid.head; adj; adj = adj->next) { - if (((mtid == ISIS_MT_IPV4_UNICAST) - && (adj->family != AF_INET)) - || ((mtid == ISIS_MT_IPV6_UNICAST) - && (adj->family != AF_INET6))) - continue; sbuf_push( buf, indent, "Adjacency-SID: %u, Weight: %hhu, Flags: F:%c B:%c, V:%c, L:%c, S:%c, P:%c\n", @@ -319,10 +329,6 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts, for (lan = (struct isis_lan_adj_sid *)exts->lan_sid.head; lan; lan = lan->next) { - if (((mtid == ISIS_MT_IPV4_UNICAST) - && (lan->family != AF_INET)) - || ((mtid == ISIS_MT_IPV6_UNICAST) - && (lan->family != AF_INET6))) continue; sbuf_push(buf, indent, "Lan-Adjacency-SID: %u, Weight: %hhu, Flags: F:%c B:%c, V:%c, L:%c, S:%c, P:%c\n" @@ -1839,12 +1845,12 @@ static int pack_item_ipv6_address(struct isis_item *i, struct stream *s, { struct isis_ipv6_address *a = (struct isis_ipv6_address *)i; - if (STREAM_WRITEABLE(s) < 16) { - *min_len = 16; + if (STREAM_WRITEABLE(s) < IPV6_MAX_BYTELEN) { + *min_len = IPV6_MAX_BYTELEN; return 1; } - stream_put(s, &a->addr, 16); + stream_put(s, &a->addr, IPV6_MAX_BYTELEN); return 0; } @@ -1865,7 +1871,7 @@ static int unpack_item_ipv6_address(uint16_t mtid, uint8_t len, } struct isis_ipv6_address *rv = XCALLOC(MTYPE_ISIS_TLV, sizeof(*rv)); - stream_get(&rv->addr, s, 16); + stream_get(&rv->addr, s, IPV6_MAX_BYTELEN); format_item_ipv6_address(mtid, (struct isis_item *)rv, log, indent + 2); append_item(&tlvs->ipv6_address, (struct isis_item *)rv); @@ -1873,6 +1879,70 @@ static int unpack_item_ipv6_address(uint16_t mtid, uint8_t len, } +/* Functions related to TLV 233 Global IPv6 Interface addresses */ +static struct isis_item *copy_item_global_ipv6_address(struct isis_item *i) +{ + struct isis_ipv6_address *a = (struct isis_ipv6_address *)i; + struct isis_ipv6_address *rv = XCALLOC(MTYPE_ISIS_TLV, sizeof(*rv)); + + rv->addr = a->addr; + return (struct isis_item *)rv; +} + +static void format_item_global_ipv6_address(uint16_t mtid, struct isis_item *i, + struct sbuf *buf, int indent) +{ + struct isis_ipv6_address *a = (struct isis_ipv6_address *)i; + char addrbuf[INET6_ADDRSTRLEN]; + + inet_ntop(AF_INET6, &a->addr, addrbuf, sizeof(addrbuf)); + sbuf_push(buf, indent, "Global IPv6 Interface Address: %s\n", addrbuf); +} + +static void free_item_global_ipv6_address(struct isis_item *i) +{ + XFREE(MTYPE_ISIS_TLV, i); +} + +static int pack_item_global_ipv6_address(struct isis_item *i, struct stream *s, + size_t *min_len) +{ + struct isis_ipv6_address *a = (struct isis_ipv6_address *)i; + + if (STREAM_WRITEABLE(s) < IPV6_MAX_BYTELEN) { + *min_len = IPV6_MAX_BYTELEN; + return 1; + } + + stream_put(s, &a->addr, IPV6_MAX_BYTELEN); + + return 0; +} + +static int unpack_item_global_ipv6_address(uint16_t mtid, uint8_t len, + struct stream *s, struct sbuf *log, + void *dest, int indent) +{ + struct isis_tlvs *tlvs = dest; + + sbuf_push(log, indent, "Unpack Global IPv6 Interface address...\n"); + if (len < IPV6_MAX_BYTELEN) { + sbuf_push( + log, indent, + "Not enough data left.(Expected 16 bytes of IPv6 address, got %hhu)\n", + len); + return 1; + } + + struct isis_ipv6_address *rv = XCALLOC(MTYPE_ISIS_TLV, sizeof(*rv)); + stream_get(&rv->addr, s, IPV6_MAX_BYTELEN); + + format_item_global_ipv6_address(mtid, (struct isis_item *)rv, log, + indent + 2); + append_item(&tlvs->global_ipv6_address, (struct isis_item *)rv); + return 0; +} + /* Functions related to TLV 229 MT Router information */ static struct isis_item *copy_item_mt_router_info(struct isis_item *i) { @@ -2273,6 +2343,77 @@ static int unpack_tlv_dynamic_hostname(enum isis_tlv_context context, return 0; } +/* Functions related to TLV 140 IPv6 TE Router ID */ + +static struct in6_addr *copy_tlv_te_router_id_ipv6(const struct in6_addr *id) +{ + if (!id) + return NULL; + + struct in6_addr *rv = XCALLOC(MTYPE_ISIS_TLV, sizeof(*rv)); + memcpy(rv, id, sizeof(*rv)); + return rv; +} + +static void format_tlv_te_router_id_ipv6(const struct in6_addr *id, + struct sbuf *buf, int indent) +{ + if (!id) + return; + + char addrbuf[INET6_ADDRSTRLEN]; + inet_ntop(AF_INET6, id, addrbuf, sizeof(addrbuf)); + sbuf_push(buf, indent, "IPv6 TE Router ID: %s\n", addrbuf); +} + +static void free_tlv_te_router_id_ipv6(struct in6_addr *id) +{ + XFREE(MTYPE_ISIS_TLV, id); +} + +static int pack_tlv_te_router_id_ipv6(const struct in6_addr *id, + struct stream *s) +{ + if (!id) + return 0; + + if (STREAM_WRITEABLE(s) < (unsigned)(2 + sizeof(*id))) + return 1; + + stream_putc(s, ISIS_TLV_TE_ROUTER_ID_IPV6); + stream_putc(s, IPV6_MAX_BYTELEN); + stream_put(s, id, IPV6_MAX_BYTELEN); + return 0; +} + +static int unpack_tlv_te_router_id_ipv6(enum isis_tlv_context context, + uint8_t tlv_type, uint8_t tlv_len, + struct stream *s, struct sbuf *log, + void *dest, int indent) +{ + struct isis_tlvs *tlvs = dest; + + sbuf_push(log, indent, "Unpacking IPv6 TE Router ID TLV...\n"); + if (tlv_len != IPV6_MAX_BYTELEN) { + sbuf_push(log, indent, "WARNING: Length invalid\n"); + return 1; + } + + if (tlvs->te_router_id_ipv6) { + sbuf_push( + log, indent, + "WARNING: IPv6 TE Router ID present multiple times.\n"); + stream_forward_getp(s, tlv_len); + return 0; + } + + tlvs->te_router_id_ipv6 = XCALLOC(MTYPE_ISIS_TLV, IPV6_MAX_BYTELEN); + stream_get(tlvs->te_router_id_ipv6, s, IPV6_MAX_BYTELEN); + format_tlv_te_router_id_ipv6(tlvs->te_router_id_ipv6, log, indent + 2); + return 0; +} + + /* Functions related to TLV 150 Spine-Leaf-Extension */ static struct isis_spine_leaf *copy_tlv_spine_leaf( @@ -3640,6 +3781,7 @@ struct isis_tlvs *isis_alloc_tlvs(void) init_item_list(&result->oldstyle_ip_reach_ext); init_item_list(&result->ipv4_address); init_item_list(&result->ipv6_address); + init_item_list(&result->global_ipv6_address); init_item_list(&result->extended_ip_reach); RB_INIT(isis_mt_item_list, &result->mt_ip_reach); init_item_list(&result->ipv6_reach); @@ -3696,8 +3838,14 @@ struct isis_tlvs *isis_copy_tlvs(struct isis_tlvs *tlvs) copy_items(ISIS_CONTEXT_LSP, ISIS_TLV_IPV6_ADDRESS, &tlvs->ipv6_address, &rv->ipv6_address); + copy_items(ISIS_CONTEXT_LSP, ISIS_TLV_GLOBAL_IPV6_ADDRESS, + &tlvs->global_ipv6_address, &rv->global_ipv6_address); + rv->te_router_id = copy_tlv_te_router_id(tlvs->te_router_id); + rv->te_router_id_ipv6 = + copy_tlv_te_router_id_ipv6(tlvs->te_router_id_ipv6); + copy_items(ISIS_CONTEXT_LSP, ISIS_TLV_EXTENDED_IP_REACH, &tlvs->extended_ip_reach, &rv->extended_ip_reach); @@ -3751,6 +3899,7 @@ static void format_tlvs(struct isis_tlvs *tlvs, struct sbuf *buf, int indent) format_tlv_dynamic_hostname(tlvs->hostname, buf, indent); format_tlv_te_router_id(tlvs->te_router_id, buf, indent); + format_tlv_te_router_id_ipv6(tlvs->te_router_id_ipv6, buf, indent); format_tlv_router_cap(tlvs->router_cap, buf, indent); format_items(ISIS_CONTEXT_LSP, ISIS_TLV_EXTENDED_REACH, @@ -3771,6 +3920,9 @@ static void format_tlvs(struct isis_tlvs *tlvs, struct sbuf *buf, int indent) format_items(ISIS_CONTEXT_LSP, ISIS_TLV_IPV6_ADDRESS, &tlvs->ipv6_address, buf, indent); + format_items(ISIS_CONTEXT_LSP, ISIS_TLV_GLOBAL_IPV6_ADDRESS, + &tlvs->global_ipv6_address, buf, indent); + format_items(ISIS_CONTEXT_LSP, ISIS_TLV_EXTENDED_IP_REACH, &tlvs->extended_ip_reach, buf, indent); @@ -3828,7 +3980,10 @@ void isis_free_tlvs(struct isis_tlvs *tlvs) &tlvs->ipv4_address); free_items(ISIS_CONTEXT_LSP, ISIS_TLV_IPV6_ADDRESS, &tlvs->ipv6_address); + free_items(ISIS_CONTEXT_LSP, ISIS_TLV_GLOBAL_IPV6_ADDRESS, + &tlvs->global_ipv6_address); free_tlv_te_router_id(tlvs->te_router_id); + free_tlv_te_router_id_ipv6(tlvs->te_router_id_ipv6); free_items(ISIS_CONTEXT_LSP, ISIS_TLV_EXTENDED_IP_REACH, &tlvs->extended_ip_reach); free_mt_items(ISIS_CONTEXT_LSP, ISIS_TLV_MT_IP_REACH, @@ -4035,6 +4190,14 @@ static int pack_tlvs(struct isis_tlvs *tlvs, struct stream *stream, copy_tlv_te_router_id(tlvs->te_router_id); } + rv = pack_tlv_te_router_id_ipv6(tlvs->te_router_id_ipv6, stream); + if (rv) + return rv; + if (fragment_tlvs) { + fragment_tlvs->te_router_id_ipv6 = + copy_tlv_te_router_id_ipv6(tlvs->te_router_id_ipv6); + } + rv = pack_tlv_threeway_adj(tlvs->threeway_adj, stream); if (rv) return rv; @@ -4255,10 +4418,12 @@ ITEM_TLV_OPS(ipv4_address, "TLV 132 IPv4 Interface Address"); TLV_OPS(te_router_id, "TLV 134 TE Router ID"); ITEM_TLV_OPS(extended_ip_reach, "TLV 135 Extended IP Reachability"); TLV_OPS(dynamic_hostname, "TLV 137 Dynamic Hostname"); +TLV_OPS(te_router_id_ipv6, "TLV 140 IPv6 TE Router ID"); TLV_OPS(spine_leaf, "TLV 150 Spine Leaf Extensions"); ITEM_TLV_OPS(mt_router_info, "TLV 229 MT Router Information"); TLV_OPS(threeway_adj, "TLV 240 P2P Three-Way Adjacency"); ITEM_TLV_OPS(ipv6_address, "TLV 232 IPv6 Interface Address"); +ITEM_TLV_OPS(global_ipv6_address, "TLV 233 Global IPv6 Interface Address"); ITEM_TLV_OPS(ipv6_reach, "TLV 236 IPv6 Reachability"); TLV_OPS(router_cap, "TLV 242 Router Capability"); @@ -4279,12 +4444,14 @@ static const struct tlv_ops *const tlv_table[ISIS_CONTEXT_MAX][ISIS_TLV_MAX] = { [ISIS_TLV_OLDSTYLE_IP_REACH_EXT] = &tlv_oldstyle_ip_reach_ops, [ISIS_TLV_IPV4_ADDRESS] = &tlv_ipv4_address_ops, [ISIS_TLV_TE_ROUTER_ID] = &tlv_te_router_id_ops, + [ISIS_TLV_TE_ROUTER_ID_IPV6] = &tlv_te_router_id_ipv6_ops, [ISIS_TLV_EXTENDED_IP_REACH] = &tlv_extended_ip_reach_ops, [ISIS_TLV_DYNAMIC_HOSTNAME] = &tlv_dynamic_hostname_ops, [ISIS_TLV_SPINE_LEAF_EXT] = &tlv_spine_leaf_ops, [ISIS_TLV_MT_REACH] = &tlv_extended_reach_ops, [ISIS_TLV_MT_ROUTER_INFO] = &tlv_mt_router_info_ops, [ISIS_TLV_IPV6_ADDRESS] = &tlv_ipv6_address_ops, + [ISIS_TLV_GLOBAL_IPV6_ADDRESS] = &tlv_global_ipv6_address_ops, [ISIS_TLV_MT_IP_REACH] = &tlv_extended_ip_reach_ops, [ISIS_TLV_IPV6_REACH] = &tlv_ipv6_reach_ops, [ISIS_TLV_MT_IPV6_REACH] = &tlv_ipv6_reach_ops, @@ -4427,6 +4594,26 @@ void isis_tlvs_add_ipv6_addresses(struct isis_tlvs *tlvs, } } +void isis_tlvs_add_global_ipv6_addresses(struct isis_tlvs *tlvs, + struct list *addresses) +{ + struct listnode *node; + struct prefix_ipv6 *ip_addr; + unsigned int addr_count = 0; + + for (ALL_LIST_ELEMENTS_RO(addresses, node, ip_addr)) { + if (addr_count >= 15) + break; + + struct isis_ipv6_address *a = + XCALLOC(MTYPE_ISIS_TLV, sizeof(*a)); + + a->addr = ip_addr->prefix; + append_item(&tlvs->global_ipv6_address, (struct isis_item *)a); + addr_count++; + } +} + typedef bool (*auth_validator_func)(struct isis_passwd *passwd, struct stream *stream, struct isis_auth *auth, bool is_lsp); @@ -4606,10 +4793,12 @@ static void tlvs_protocols_supported_to_adj(struct isis_tlvs *tlvs, memcpy(adj->nlpids.nlpids, reduced.nlpids, reduced.count); } -DEFINE_HOOK(isis_adj_ip_enabled_hook, (struct isis_adjacency *adj, int family), - (adj, family)); +DEFINE_HOOK(isis_adj_ip_enabled_hook, + (struct isis_adjacency * adj, int family, bool global), + (adj, family, global)); DEFINE_HOOK(isis_adj_ip_disabled_hook, - (struct isis_adjacency *adj, int family), (adj, family)); + (struct isis_adjacency * adj, int family, bool global), + (adj, family, global)); static void tlvs_ipv4_addresses_to_adj(struct isis_tlvs *tlvs, struct isis_adjacency *adj, @@ -4620,7 +4809,7 @@ static void tlvs_ipv4_addresses_to_adj(struct isis_tlvs *tlvs, if (adj->ipv4_address_count == 0 && tlvs->ipv4_address.count > 0) ipv4_enabled = true; else if (adj->ipv4_address_count > 0 && tlvs->ipv4_address.count == 0) - hook_call(isis_adj_ip_disabled_hook, adj, AF_INET); + hook_call(isis_adj_ip_disabled_hook, adj, AF_INET, false); if (adj->ipv4_address_count != tlvs->ipv4_address.count) { uint32_t oc = adj->ipv4_address_count; @@ -4654,7 +4843,7 @@ static void tlvs_ipv4_addresses_to_adj(struct isis_tlvs *tlvs, } if (ipv4_enabled) - hook_call(isis_adj_ip_enabled_hook, adj, AF_INET); + hook_call(isis_adj_ip_enabled_hook, adj, AF_INET, false); } static void tlvs_ipv6_addresses_to_adj(struct isis_tlvs *tlvs, @@ -4663,23 +4852,23 @@ static void tlvs_ipv6_addresses_to_adj(struct isis_tlvs *tlvs, { bool ipv6_enabled = false; - if (adj->ipv6_address_count == 0 && tlvs->ipv6_address.count > 0) + if (adj->ll_ipv6_count == 0 && tlvs->ipv6_address.count > 0) ipv6_enabled = true; - else if (adj->ipv6_address_count > 0 && tlvs->ipv6_address.count == 0) - hook_call(isis_adj_ip_disabled_hook, adj, AF_INET6); + else if (adj->ll_ipv6_count > 0 && tlvs->ipv6_address.count == 0) + hook_call(isis_adj_ip_disabled_hook, adj, AF_INET6, false); - if (adj->ipv6_address_count != tlvs->ipv6_address.count) { - uint32_t oc = adj->ipv6_address_count; + if (adj->ll_ipv6_count != tlvs->ipv6_address.count) { + uint32_t oc = adj->ll_ipv6_count; *changed = true; - adj->ipv6_address_count = tlvs->ipv6_address.count; - adj->ipv6_addresses = XREALLOC( - MTYPE_ISIS_ADJACENCY_INFO, adj->ipv6_addresses, - adj->ipv6_address_count * sizeof(*adj->ipv6_addresses)); + adj->ll_ipv6_count = tlvs->ipv6_address.count; + adj->ll_ipv6_addrs = XREALLOC( + MTYPE_ISIS_ADJACENCY_INFO, adj->ll_ipv6_addrs, + adj->ll_ipv6_count * sizeof(*adj->ll_ipv6_addrs)); - for (; oc < adj->ipv6_address_count; oc++) { - memset(&adj->ipv6_addresses[oc], 0, - sizeof(adj->ipv6_addresses[oc])); + for (; oc < adj->ll_ipv6_count; oc++) { + memset(&adj->ll_ipv6_addrs[oc], 0, + sizeof(adj->ll_ipv6_addrs[oc])); } } @@ -4691,16 +4880,65 @@ static void tlvs_ipv6_addresses_to_adj(struct isis_tlvs *tlvs, else addr = addr->next; - if (!memcmp(&adj->ipv6_addresses[i], &addr->addr, + if (!memcmp(&adj->ll_ipv6_addrs[i], &addr->addr, sizeof(addr->addr))) continue; *changed = true; - adj->ipv6_addresses[i] = addr->addr; + adj->ll_ipv6_addrs[i] = addr->addr; } if (ipv6_enabled) - hook_call(isis_adj_ip_enabled_hook, adj, AF_INET6); + hook_call(isis_adj_ip_enabled_hook, adj, AF_INET6, false); +} + + +static void tlvs_global_ipv6_addresses_to_adj(struct isis_tlvs *tlvs, + struct isis_adjacency *adj, + bool *changed) +{ + bool global_ipv6_enabled = false; + + if (adj->global_ipv6_count == 0 && tlvs->global_ipv6_address.count > 0) + global_ipv6_enabled = true; + else if (adj->global_ipv6_count > 0 + && tlvs->global_ipv6_address.count == 0) + hook_call(isis_adj_ip_disabled_hook, adj, AF_INET6, true); + + if (adj->global_ipv6_count != tlvs->global_ipv6_address.count) { + uint32_t oc = adj->global_ipv6_count; + + *changed = true; + adj->global_ipv6_count = tlvs->global_ipv6_address.count; + adj->global_ipv6_addrs = XREALLOC( + MTYPE_ISIS_ADJACENCY_INFO, adj->global_ipv6_addrs, + adj->global_ipv6_count + * sizeof(*adj->global_ipv6_addrs)); + + for (; oc < adj->global_ipv6_count; oc++) { + memset(&adj->global_ipv6_addrs[oc], 0, + sizeof(adj->global_ipv6_addrs[oc])); + } + } + + struct isis_ipv6_address *addr = NULL; + for (unsigned int i = 0; i < tlvs->global_ipv6_address.count; i++) { + if (!addr) + addr = (struct isis_ipv6_address *) + tlvs->global_ipv6_address.head; + else + addr = addr->next; + + if (!memcmp(&adj->global_ipv6_addrs[i], &addr->addr, + sizeof(addr->addr))) + continue; + + *changed = true; + adj->global_ipv6_addrs[i] = addr->addr; + } + + if (global_ipv6_enabled) + hook_call(isis_adj_ip_enabled_hook, adj, AF_INET6, true); } void isis_tlvs_to_adj(struct isis_tlvs *tlvs, struct isis_adjacency *adj, @@ -4712,6 +4950,7 @@ void isis_tlvs_to_adj(struct isis_tlvs *tlvs, struct isis_adjacency *adj, tlvs_protocols_supported_to_adj(tlvs, adj, changed); tlvs_ipv4_addresses_to_adj(tlvs, adj, changed); tlvs_ipv6_addresses_to_adj(tlvs, adj, changed); + tlvs_global_ipv6_addresses_to_adj(tlvs, adj, changed); } bool isis_tlvs_own_snpa_found(struct isis_tlvs *tlvs, uint8_t *snpa) @@ -4793,6 +5032,16 @@ void isis_tlvs_set_te_router_id(struct isis_tlvs *tlvs, memcpy(tlvs->te_router_id, id, sizeof(*id)); } +void isis_tlvs_set_te_router_id_ipv6(struct isis_tlvs *tlvs, + const struct in6_addr *id) +{ + XFREE(MTYPE_ISIS_TLV, tlvs->te_router_id_ipv6); + if (!id) + return; + tlvs->te_router_id_ipv6 = XCALLOC(MTYPE_ISIS_TLV, sizeof(*id)); + memcpy(tlvs->te_router_id_ipv6, id, sizeof(*id)); +} + void isis_tlvs_add_oldstyle_ip_reach(struct isis_tlvs *tlvs, struct prefix_ipv4 *dest, uint8_t metric) { @@ -4922,7 +5171,7 @@ void isis_tlvs_add_extended_reach(struct isis_tlvs *tlvs, uint16_t mtid, r->subtlvs = copy_item_ext_subtlvs(exts, mtid); struct isis_item_list *l; - if (mtid == ISIS_MT_IPV4_UNICAST) + if ((mtid == ISIS_MT_IPV4_UNICAST) || (mtid == ISIS_MT_DISABLE)) l = &tlvs->extended_reach; else l = isis_get_mt_items(&tlvs->mt_reach, mtid); diff --git a/isisd/isis_tlvs.h b/isisd/isis_tlvs.h index 0438d13ae0..38470ef85e 100644 --- a/isisd/isis_tlvs.h +++ b/isisd/isis_tlvs.h @@ -324,9 +324,11 @@ struct isis_tlvs { struct isis_item_list oldstyle_ip_reach_ext; struct isis_item_list ipv4_address; struct isis_item_list ipv6_address; + struct isis_item_list global_ipv6_address; struct isis_item_list mt_router_info; bool mt_router_info_empty; struct in_addr *te_router_id; + struct in6_addr *te_router_id_ipv6; struct isis_item_list extended_ip_reach; struct isis_mt_item_list mt_ip_reach; char *hostname; @@ -372,10 +374,12 @@ enum isis_tlv_type { ISIS_TLV_TE_ROUTER_ID = 134, ISIS_TLV_EXTENDED_IP_REACH = 135, ISIS_TLV_DYNAMIC_HOSTNAME = 137, + ISIS_TLV_TE_ROUTER_ID_IPV6 = 140, ISIS_TLV_SPINE_LEAF_EXT = 150, ISIS_TLV_MT_REACH = 222, ISIS_TLV_MT_ROUTER_INFO = 229, ISIS_TLV_IPV6_ADDRESS = 232, + ISIS_TLV_GLOBAL_IPV6_ADDRESS = 233, ISIS_TLV_MT_IP_REACH = 235, ISIS_TLV_IPV6_REACH = 236, ISIS_TLV_MT_IPV6_REACH = 237, @@ -575,6 +579,8 @@ void isis_tlvs_add_ipv4_addresses(struct isis_tlvs *tlvs, struct list *addresses); void isis_tlvs_add_ipv6_addresses(struct isis_tlvs *tlvs, struct list *addresses); +void isis_tlvs_add_global_ipv6_addresses(struct isis_tlvs *tlvs, + struct list *addresses); int isis_tlvs_auth_is_valid(struct isis_tlvs *tlvs, struct isis_passwd *passwd, struct stream *stream, bool is_lsp); bool isis_tlvs_area_addresses_match(struct isis_tlvs *tlvs, @@ -594,6 +600,8 @@ void isis_tlvs_set_router_capability(struct isis_tlvs *tlvs, const struct isis_router_cap *cap); void isis_tlvs_set_te_router_id(struct isis_tlvs *tlvs, const struct in_addr *id); +void isis_tlvs_set_te_router_id_ipv6(struct isis_tlvs *tlvs, + const struct in6_addr *id); void isis_tlvs_add_oldstyle_ip_reach(struct isis_tlvs *tlvs, struct prefix_ipv4 *dest, uint8_t metric); void isis_tlvs_add_extended_ip_reach(struct isis_tlvs *tlvs, diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c index 27e80e2501..52a5cdd64f 100644 --- a/isisd/isis_zebra.c +++ b/isisd/isis_zebra.c @@ -38,6 +38,7 @@ #include "vrf.h" #include "libfrr.h" #include "bfd.h" +#include "link_state.h" #include "isisd/isis_constants.h" #include "isisd/isis_common.h" @@ -747,6 +748,25 @@ static void isis_zebra_connected(struct zclient *zclient) bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER, VRF_DEFAULT); } +/** + * Register / unregister Link State ZAPI Opaque Message + * + * @param up True to register, false to unregister + * + * @return 0 if success, -1 otherwise + */ +int isis_zebra_ls_register(bool up) +{ + int rc; + + if (up) + rc = ls_register(zclient, true); + else + rc = ls_unregister(zclient, true); + + return rc; +} + /* * opaque messages between processes */ @@ -754,6 +774,7 @@ static int isis_opaque_msg_handler(ZAPI_CALLBACK_ARGS) { struct stream *s; struct zapi_opaque_msg info; + struct zapi_opaque_reg_info dst; struct ldp_igp_sync_if_state state; struct ldp_igp_sync_announce announce; struct zapi_rlfa_response rlfa; @@ -764,6 +785,13 @@ static int isis_opaque_msg_handler(ZAPI_CALLBACK_ARGS) return -1; switch (info.type) { + case LINK_STATE_SYNC: + STREAM_GETC(s, dst.proto); + STREAM_GETW(s, dst.instance); + STREAM_GETL(s, dst.session_id); + dst.type = LINK_STATE_SYNC; + ret = isis_te_sync_ted(dst); + break; case LDP_IGP_SYNC_IF_STATE_UPDATE: STREAM_GET(&state, s, sizeof(state)); ret = isis_ldp_sync_state_update(state); diff --git a/isisd/isis_zebra.h b/isisd/isis_zebra.h index 348d7b3eab..84dc58ec6c 100644 --- a/isisd/isis_zebra.h +++ b/isisd/isis_zebra.h @@ -67,5 +67,6 @@ int isis_zebra_request_label_range(uint32_t base, uint32_t chunk_size); int isis_zebra_release_label_range(uint32_t start, uint32_t end); void isis_zebra_vrf_register(struct isis *isis); void isis_zebra_vrf_deregister(struct isis *isis); +int isis_zebra_ls_register(bool up); #endif /* _ZEBRA_ISIS_ZEBRA_H */ diff --git a/isisd/isisd.c b/isisd/isisd.c index 21c97aced4..3fa2b7cc20 100644 --- a/isisd/isisd.c +++ b/isisd/isisd.c @@ -81,6 +81,7 @@ unsigned long debug_tx_queue; unsigned long debug_sr; unsigned long debug_ldp_sync; unsigned long debug_lfa; +unsigned long debug_te; DEFINE_MGROUP(ISISD, "isisd"); @@ -1374,6 +1375,10 @@ void print_debug(struct vty *vty, int flags, int onoff) if (flags & DEBUG_SR) vty_out(vty, "IS-IS Segment Routing events debugging is %s\n", onoffs); + if (flags & DEBUG_TE) + vty_out(vty, + "IS-IS Traffic Engineering events debugging is %s\n", + onoffs); if (flags & DEBUG_LFA) vty_out(vty, "IS-IS LFA events debugging is %s\n", onoffs); if (flags & DEBUG_UPDATE_PACKETS) @@ -1416,6 +1421,8 @@ DEFUN_NOSH (show_debugging, print_debug(vty, DEBUG_SPF_EVENTS, 1); if (IS_DEBUG_SR) print_debug(vty, DEBUG_SR, 1); + if (IS_DEBUG_TE) + print_debug(vty, DEBUG_TE, 1); if (IS_DEBUG_UPDATE_PACKETS) print_debug(vty, DEBUG_UPDATE_PACKETS, 1); if (IS_DEBUG_RTE_EVENTS) @@ -1473,6 +1480,10 @@ static int config_write_debug(struct vty *vty) vty_out(vty, "debug " PROTO_NAME " sr-events\n"); write++; } + if (IS_DEBUG_TE) { + vty_out(vty, "debug " PROTO_NAME " te-events\n"); + write++; + } if (IS_DEBUG_LFA) { vty_out(vty, "debug " PROTO_NAME " lfa\n"); write++; @@ -1707,6 +1718,33 @@ DEFUN (no_debug_isis_srevents, return CMD_SUCCESS; } +DEFUN (debug_isis_teevents, + debug_isis_teevents_cmd, + "debug " PROTO_NAME " te-events", + DEBUG_STR + PROTO_HELP + "IS-IS Traffic Engineering Events\n") +{ + debug_te |= DEBUG_TE; + print_debug(vty, DEBUG_TE, 1); + + return CMD_SUCCESS; +} + +DEFUN (no_debug_isis_teevents, + no_debug_isis_teevents_cmd, + "no debug " PROTO_NAME " te-events", + NO_STR + UNDEBUG_STR + PROTO_HELP + "IS-IS Traffic Engineering Events\n") +{ + debug_te &= ~DEBUG_TE; + print_debug(vty, DEBUG_TE, 0); + + return CMD_SUCCESS; +} + DEFUN (debug_isis_lfa, debug_isis_lfa_cmd, "debug " PROTO_NAME " lfa", @@ -3095,6 +3133,8 @@ void isis_init(void) install_element(ENABLE_NODE, &no_debug_isis_spfevents_cmd); install_element(ENABLE_NODE, &debug_isis_srevents_cmd); install_element(ENABLE_NODE, &no_debug_isis_srevents_cmd); + install_element(ENABLE_NODE, &debug_isis_teevents_cmd); + install_element(ENABLE_NODE, &no_debug_isis_teevents_cmd); install_element(ENABLE_NODE, &debug_isis_lfa_cmd); install_element(ENABLE_NODE, &no_debug_isis_lfa_cmd); install_element(ENABLE_NODE, &debug_isis_rtevents_cmd); @@ -3126,6 +3166,8 @@ void isis_init(void) install_element(CONFIG_NODE, &no_debug_isis_spfevents_cmd); install_element(CONFIG_NODE, &debug_isis_srevents_cmd); install_element(CONFIG_NODE, &no_debug_isis_srevents_cmd); + install_element(CONFIG_NODE, &debug_isis_teevents_cmd); + install_element(CONFIG_NODE, &no_debug_isis_teevents_cmd); install_element(CONFIG_NODE, &debug_isis_lfa_cmd); install_element(CONFIG_NODE, &no_debug_isis_lfa_cmd); install_element(CONFIG_NODE, &debug_isis_rtevents_cmd); diff --git a/isisd/isisd.h b/isisd/isisd.h index 3febda1d87..7f8474a5f2 100644 --- a/isisd/isisd.h +++ b/isisd/isisd.h @@ -331,6 +331,7 @@ extern unsigned long debug_tx_queue; extern unsigned long debug_sr; extern unsigned long debug_ldp_sync; extern unsigned long debug_lfa; +extern unsigned long debug_te; #define DEBUG_ADJ_PACKETS (1<<0) #define DEBUG_SNP_PACKETS (1<<1) @@ -347,6 +348,7 @@ extern unsigned long debug_lfa; #define DEBUG_SR (1<<12) #define DEBUG_LDP_SYNC (1<<13) #define DEBUG_LFA (1<<14) +#define DEBUG_TE (1<<15) /* Debug related macro. */ #define IS_DEBUG_ADJ_PACKETS (debug_adj_pkt & DEBUG_ADJ_PACKETS) @@ -364,6 +366,7 @@ extern unsigned long debug_lfa; #define IS_DEBUG_SR (debug_sr & DEBUG_SR) #define IS_DEBUG_LDP_SYNC (debug_ldp_sync & DEBUG_LDP_SYNC) #define IS_DEBUG_LFA (debug_lfa & DEBUG_LFA) +#define IS_DEBUG_TE (debug_te & DEBUG_TE) #define lsp_debug(...) \ do { \ @@ -383,6 +386,10 @@ extern unsigned long debug_lfa; zlog_debug(__VA_ARGS__); \ } while (0) -#define DEBUG_TE DEBUG_LSP_GEN +#define te_debug(...) \ + do { \ + if (IS_DEBUG_TE) \ + zlog_debug(__VA_ARGS__); \ + } while (0) #endif /* ISISD_H */ diff --git a/lib/link_state.c b/lib/link_state.c index b0bc386b79..e4ccd0fb65 100644 --- a/lib/link_state.c +++ b/lib/link_state.c @@ -89,7 +89,7 @@ struct ls_node *ls_node_new(struct ls_node_id adv, struct in_addr rid, } } if (!IN6_IS_ADDR_UNSPECIFIED(&rid6)) { - new->router6_id = rid6; + new->router_id6 = rid6; SET_FLAG(new->flags, LS_NODE_ROUTER_ID6); } return new; @@ -127,7 +127,7 @@ int ls_node_same(struct ls_node *n1, struct ls_node *n2) && !IPV4_ADDR_SAME(&n1->router_id, &n2->router_id)) return 0; if (CHECK_FLAG(n1->flags, LS_NODE_ROUTER_ID6) - && !IPV6_ADDR_SAME(&n1->router6_id, &n2->router6_id)) + && !IPV6_ADDR_SAME(&n1->router_id6, &n2->router_id6)) return 0; if (CHECK_FLAG(n1->flags, LS_NODE_FLAG) && (n1->node_flag != n2->node_flag)) @@ -306,36 +306,23 @@ int ls_attributes_same(struct ls_attributes *l1, struct ls_attributes *l2) if (CHECK_FLAG(l1->flags, LS_ATTR_USE_BW) && (l1->extended.used_bw != l2->extended.used_bw)) return 0; - if (CHECK_FLAG(l1->flags, LS_ATTR_ADJ_SID)) { - if ((l1->adj_sid[0].sid != l2->adj_sid[0].sid) - || (l1->adj_sid[0].flags != l2->adj_sid[0].flags) - || (l1->adj_sid[0].weight != l2->adj_sid[0].weight)) + for (int i = 0; i < LS_ADJ_MAX; i++) { + if (!CHECK_FLAG(l1->flags, (LS_ATTR_ADJ_SID << i))) + continue; + if ((l1->adj_sid[i].sid != l2->adj_sid[i].sid) + || (l1->adj_sid[i].flags != l2->adj_sid[i].flags) + || (l1->adj_sid[i].weight != l2->adj_sid[i].weight)) return 0; if (((l1->adv.origin == ISIS_L1) || (l1->adv.origin == ISIS_L2)) - && (memcmp(&l1->adj_sid[0].neighbor.sysid, - &l2->adj_sid[0].neighbor.sysid, ISO_SYS_ID_LEN) + && (memcmp(&l1->adj_sid[i].neighbor.sysid, + &l2->adj_sid[i].neighbor.sysid, ISO_SYS_ID_LEN) != 0)) return 0; if (((l1->adv.origin == OSPFv2) || (l1->adv.origin == STATIC) || (l1->adv.origin == DIRECT)) - && (!IPV4_ADDR_SAME(&l1->adj_sid[0].neighbor.addr, - &l2->adj_sid[0].neighbor.addr))) - return 0; - } - if (CHECK_FLAG(l1->flags, LS_ATTR_BCK_ADJ_SID)) { - if ((l1->adj_sid[1].sid != l2->adj_sid[1].sid) - || (l1->adj_sid[1].flags != l2->adj_sid[1].flags) - || (l1->adj_sid[1].weight != l2->adj_sid[1].weight)) - return 0; - if (((l1->adv.origin == ISIS_L1) || (l1->adv.origin == ISIS_L2)) - && (memcmp(&l1->adj_sid[1].neighbor.sysid, - &l2->adj_sid[1].neighbor.sysid, ISO_SYS_ID_LEN) - != 0)) - return 0; - if (((l1->adv.origin == OSPFv2) || (l1->adv.origin == STATIC) - || (l1->adv.origin == DIRECT)) - && (!IPV4_ADDR_SAME(&l1->adj_sid[1].neighbor.addr, - &l2->adj_sid[1].neighbor.addr))) + && (i < ADJ_PRI_IPV6) + && (!IPV4_ADDR_SAME(&l1->adj_sid[i].neighbor.addr, + &l2->adj_sid[i].neighbor.addr))) return 0; } if (CHECK_FLAG(l1->flags, LS_ATTR_SRLG) @@ -417,6 +404,25 @@ int ls_prefix_same(struct ls_prefix *p1, struct ls_prefix *p2) /** * Link State Vertices management functions */ +uint64_t sysid_to_key(const uint8_t sysid[ISO_SYS_ID_LEN]) +{ + uint64_t key = 0; + +#if BYTE_ORDER == LITTLE_ENDIAN + uint8_t *byte = (uint8_t *)&key; + + for (int i = 0; i < ISO_SYS_ID_LEN; i++) + byte[i] = sysid[ISO_SYS_ID_LEN - i - 1]; + + byte[6] = 0; + byte[7] = 0; +#else + memcpy(&key, sysid, ISO_SYS_ID_LEN); +#endif + + return key; +} + struct ls_vertex *ls_vertex_add(struct ls_ted *ted, struct ls_node *node) { struct ls_vertex *new; @@ -435,7 +441,7 @@ struct ls_vertex *ls_vertex_add(struct ls_ted *ted, struct ls_node *node) break; case ISIS_L1: case ISIS_L2: - memcpy(&key, &node->adv.id.iso.sys_id, ISO_SYS_ID_LEN); + key = sysid_to_key(node->adv.id.iso.sys_id); break; default: key = 0; @@ -557,7 +563,7 @@ struct ls_vertex *ls_find_vertex_by_id(struct ls_ted *ted, break; case ISIS_L1: case ISIS_L2: - memcpy(&vertex.key, &nid.id.iso.sys_id, ISO_SYS_ID_LEN); + vertex.key = sysid_to_key(nid.id.iso.sys_id); break; default: return NULL; @@ -673,6 +679,46 @@ static void ls_edge_connect_to(struct ls_ted *ted, struct ls_edge *edge) } } +static uint64_t get_edge_key(struct ls_attributes *attr, bool dst) +{ + uint64_t key = 0; + struct ls_standard *std; + + if (!attr) + return key; + + std = &attr->standard; + + if (dst) { + /* Key is the IPv4 remote address */ + if (CHECK_FLAG(attr->flags, LS_ATTR_NEIGH_ADDR)) + key = ((uint64_t)ntohl(std->remote.s_addr)) + & 0xffffffff; + /* or the 64 bits LSB of IPv6 remote address */ + else if (CHECK_FLAG(attr->flags, LS_ATTR_NEIGH_ADDR6)) + key = ((uint64_t)ntohl(std->remote6.s6_addr32[2]) << 32 + | (uint64_t)ntohl(std->remote6.s6_addr32[3])); + /* of remote identifier if no IP addresses are defined */ + else if (CHECK_FLAG(attr->flags, LS_ATTR_NEIGH_ID)) + key = (((uint64_t)std->remote_id) & 0xffffffff) + | ((uint64_t)std->local_id << 32); + } else { + /* Key is the IPv4 local address */ + if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR)) + key = ((uint64_t)ntohl(std->local.s_addr)) & 0xffffffff; + /* or the 64 bits LSB of IPv6 local address */ + else if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR6)) + key = ((uint64_t)ntohl(std->local6.s6_addr32[2]) << 32 + | (uint64_t)ntohl(std->local6.s6_addr32[3])); + /* of local identifier if no IP addresses are defined */ + else if (CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ID)) + key = (((uint64_t)std->local_id) & 0xffffffff) + | ((uint64_t)std->remote_id << 32); + } + + return key; +} + struct ls_edge *ls_edge_add(struct ls_ted *ted, struct ls_attributes *attributes) { @@ -682,23 +728,7 @@ struct ls_edge *ls_edge_add(struct ls_ted *ted, if (attributes == NULL) return NULL; - /* Key is the IPv4 local address */ - if (!IPV4_NET0(attributes->standard.local.s_addr)) - key = ((uint64_t)ntohl(attributes->standard.local.s_addr)) - & 0xffffffff; - /* or the IPv6 local address if IPv4 is not defined */ - else if (!IN6_IS_ADDR_UNSPECIFIED(&attributes->standard.local6)) - key = (uint64_t)(attributes->standard.local6.s6_addr32[0] - & 0xffffffff) - | ((uint64_t)attributes->standard.local6.s6_addr32[1] - << 32); - /* of local identifier if no IP addresses are defined */ - else if (attributes->standard.local_id != 0) - key = (uint64_t)( - (attributes->standard.local_id & 0xffffffff) - | ((uint64_t)attributes->standard.remote_id << 32)); - - /* Check that key is valid */ + key = get_edge_key(attributes, false); if (key == 0) return NULL; @@ -736,23 +766,7 @@ struct ls_edge *ls_find_edge_by_source(struct ls_ted *ted, if (attributes == NULL) return NULL; - edge.key = 0; - /* Key is the IPv4 local address */ - if (!IPV4_NET0(attributes->standard.local.s_addr)) - edge.key = ((uint64_t)ntohl(attributes->standard.local.s_addr)) - & 0xffffffff; - /* or the IPv6 local address if IPv4 is not defined */ - else if (!IN6_IS_ADDR_UNSPECIFIED(&attributes->standard.local6)) - edge.key = (uint64_t)(attributes->standard.local6.s6_addr32[0] - & 0xffffffff) - | ((uint64_t)attributes->standard.local6.s6_addr32[1] - << 32); - /* of local identifier if no IP addresses are defined */ - else if (attributes->standard.local_id != 0) - edge.key = (uint64_t)( - (attributes->standard.local_id & 0xffffffff) - | ((uint64_t)attributes->standard.remote_id << 32)); - + edge.key = get_edge_key(attributes, false); if (edge.key == 0) return NULL; @@ -767,24 +781,7 @@ struct ls_edge *ls_find_edge_by_destination(struct ls_ted *ted, if (attributes == NULL) return NULL; - edge.key = 0; - /* Key is the IPv4 remote address */ - if (!IPV4_NET0(attributes->standard.remote.s_addr)) - edge.key = ((uint64_t)ntohl(attributes->standard.remote.s_addr)) - & 0xffffffff; - /* or the IPv6 remote address if IPv4 is not defined */ - else if (!IN6_IS_ADDR_UNSPECIFIED(&attributes->standard.remote6)) - edge.key = - (uint64_t)(attributes->standard.remote6.s6_addr32[0] - & 0xffffffff) - | ((uint64_t)attributes->standard.remote6.s6_addr32[1] - << 32); - /* of remote identifier if no IP addresses are defined */ - else if (attributes->standard.remote_id != 0) - edge.key = (uint64_t)( - (attributes->standard.remote_id & 0xffffffff) - | ((uint64_t)attributes->standard.local_id << 32)); - + edge.key = get_edge_key(attributes, true); if (edge.key == 0) return NULL; @@ -1177,7 +1174,7 @@ static struct ls_node *ls_parse_node(struct stream *s) if (CHECK_FLAG(node->flags, LS_NODE_ROUTER_ID)) node->router_id.s_addr = stream_get_ipv4(s); if (CHECK_FLAG(node->flags, LS_NODE_ROUTER_ID6)) - STREAM_GET(&node->router6_id, s, IPV6_MAX_BYTELEN); + STREAM_GET(&node->router_id6, s, IPV6_MAX_BYTELEN); if (CHECK_FLAG(node->flags, LS_NODE_FLAG)) STREAM_GETC(s, node->node_flag); if (CHECK_FLAG(node->flags, LS_NODE_TYPE)) @@ -1267,26 +1264,32 @@ static struct ls_attributes *ls_parse_attributes(struct stream *s) if (CHECK_FLAG(attr->flags, LS_ATTR_USE_BW)) STREAM_GETF(s, attr->extended.used_bw); if (CHECK_FLAG(attr->flags, LS_ATTR_ADJ_SID)) { - STREAM_GETL(s, attr->adj_sid[0].sid); - STREAM_GETC(s, attr->adj_sid[0].flags); - STREAM_GETC(s, attr->adj_sid[0].weight); - if (attr->adv.origin == ISIS_L1 || attr->adv.origin == ISIS_L2) - STREAM_GET(attr->adj_sid[0].neighbor.sysid, s, - ISO_SYS_ID_LEN); - else if (attr->adv.origin == OSPFv2) - attr->adj_sid[0].neighbor.addr.s_addr = - stream_get_ipv4(s); + STREAM_GETL(s, attr->adj_sid[ADJ_PRI_IPV4].sid); + STREAM_GETC(s, attr->adj_sid[ADJ_PRI_IPV4].flags); + STREAM_GETC(s, attr->adj_sid[ADJ_PRI_IPV4].weight); + attr->adj_sid[ADJ_PRI_IPV4].neighbor.addr.s_addr = + stream_get_ipv4(s); } if (CHECK_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SID)) { - STREAM_GETL(s, attr->adj_sid[1].sid); - STREAM_GETC(s, attr->adj_sid[1].flags); - STREAM_GETC(s, attr->adj_sid[1].weight); - if (attr->adv.origin == ISIS_L1 || attr->adv.origin == ISIS_L2) - STREAM_GET(attr->adj_sid[1].neighbor.sysid, s, - ISO_SYS_ID_LEN); - else if (attr->adv.origin == OSPFv2) - attr->adj_sid[1].neighbor.addr.s_addr = - stream_get_ipv4(s); + STREAM_GETL(s, attr->adj_sid[ADJ_BCK_IPV4].sid); + STREAM_GETC(s, attr->adj_sid[ADJ_BCK_IPV4].flags); + STREAM_GETC(s, attr->adj_sid[ADJ_BCK_IPV4].weight); + attr->adj_sid[ADJ_BCK_IPV4].neighbor.addr.s_addr = + stream_get_ipv4(s); + } + if (CHECK_FLAG(attr->flags, LS_ATTR_ADJ_SID6)) { + STREAM_GETL(s, attr->adj_sid[ADJ_PRI_IPV6].sid); + STREAM_GETC(s, attr->adj_sid[ADJ_PRI_IPV6].flags); + STREAM_GETC(s, attr->adj_sid[ADJ_PRI_IPV6].weight); + STREAM_GET(attr->adj_sid[ADJ_PRI_IPV6].neighbor.sysid, s, + ISO_SYS_ID_LEN); + } + if (CHECK_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SID6)) { + STREAM_GETL(s, attr->adj_sid[ADJ_BCK_IPV6].sid); + STREAM_GETC(s, attr->adj_sid[ADJ_BCK_IPV6].flags); + STREAM_GETC(s, attr->adj_sid[ADJ_BCK_IPV6].weight); + STREAM_GET(attr->adj_sid[ADJ_BCK_IPV6].neighbor.sysid, s, + ISO_SYS_ID_LEN); } if (CHECK_FLAG(attr->flags, LS_ATTR_SRLG)) { STREAM_GETC(s, len); @@ -1401,7 +1404,7 @@ static int ls_format_node(struct stream *s, struct ls_node *node) if (CHECK_FLAG(node->flags, LS_NODE_ROUTER_ID)) stream_put_ipv4(s, node->router_id.s_addr); if (CHECK_FLAG(node->flags, LS_NODE_ROUTER_ID6)) - stream_put(s, &node->router6_id, IPV6_MAX_BYTELEN); + stream_put(s, &node->router_id6, IPV6_MAX_BYTELEN); if (CHECK_FLAG(node->flags, LS_NODE_FLAG)) stream_putc(s, node->node_flag); if (CHECK_FLAG(node->flags, LS_NODE_TYPE)) @@ -1487,26 +1490,32 @@ static int ls_format_attributes(struct stream *s, struct ls_attributes *attr) if (CHECK_FLAG(attr->flags, LS_ATTR_USE_BW)) stream_putf(s, attr->extended.used_bw); if (CHECK_FLAG(attr->flags, LS_ATTR_ADJ_SID)) { - stream_putl(s, attr->adj_sid[0].sid); - stream_putc(s, attr->adj_sid[0].flags); - stream_putc(s, attr->adj_sid[0].weight); - if (attr->adv.origin == ISIS_L1 || attr->adv.origin == ISIS_L2) - stream_put(s, attr->adj_sid[0].neighbor.sysid, - ISO_SYS_ID_LEN); - else if (attr->adv.origin == OSPFv2) - stream_put_ipv4(s, - attr->adj_sid[0].neighbor.addr.s_addr); + stream_putl(s, attr->adj_sid[ADJ_PRI_IPV4].sid); + stream_putc(s, attr->adj_sid[ADJ_PRI_IPV4].flags); + stream_putc(s, attr->adj_sid[ADJ_PRI_IPV4].weight); + stream_put_ipv4( + s, attr->adj_sid[ADJ_PRI_IPV4].neighbor.addr.s_addr); } if (CHECK_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SID)) { - stream_putl(s, attr->adj_sid[1].sid); - stream_putc(s, attr->adj_sid[1].flags); - stream_putc(s, attr->adj_sid[1].weight); - if (attr->adv.origin == ISIS_L1 || attr->adv.origin == ISIS_L2) - stream_put(s, attr->adj_sid[1].neighbor.sysid, - ISO_SYS_ID_LEN); - else if (attr->adv.origin == OSPFv2) - stream_put_ipv4(s, - attr->adj_sid[1].neighbor.addr.s_addr); + stream_putl(s, attr->adj_sid[ADJ_BCK_IPV4].sid); + stream_putc(s, attr->adj_sid[ADJ_BCK_IPV4].flags); + stream_putc(s, attr->adj_sid[ADJ_BCK_IPV4].weight); + stream_put_ipv4( + s, attr->adj_sid[ADJ_BCK_IPV4].neighbor.addr.s_addr); + } + if (CHECK_FLAG(attr->flags, LS_ATTR_ADJ_SID6)) { + stream_putl(s, attr->adj_sid[ADJ_PRI_IPV6].sid); + stream_putc(s, attr->adj_sid[ADJ_PRI_IPV6].flags); + stream_putc(s, attr->adj_sid[ADJ_PRI_IPV6].weight); + stream_put(s, attr->adj_sid[ADJ_PRI_IPV6].neighbor.sysid, + ISO_SYS_ID_LEN); + } + if (CHECK_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SID6)) { + stream_putl(s, attr->adj_sid[ADJ_BCK_IPV6].sid); + stream_putc(s, attr->adj_sid[ADJ_BCK_IPV6].flags); + stream_putc(s, attr->adj_sid[ADJ_BCK_IPV6].weight); + stream_put(s, attr->adj_sid[ADJ_BCK_IPV6].neighbor.sysid, + ISO_SYS_ID_LEN); } if (CHECK_FLAG(attr->flags, LS_ATTR_SRLG)) { stream_putc(s, attr->srlg_len); @@ -1955,6 +1964,7 @@ static void ls_show_vertex_vty(struct ls_vertex *vertex, struct vty *vty, struct listnode *node; struct ls_node *lsn; struct ls_edge *edge; + struct ls_attributes *attr; struct ls_subnet *subnet; struct sbuf sbuf; uint32_t upper; @@ -2019,9 +2029,15 @@ static void ls_show_vertex_vty(struct ls_vertex *vertex, struct vty *vty, } else { sbuf_push(&sbuf, 6, "To:\t- (0.0.0.0)"); } - sbuf_push(&sbuf, 0, "\tLocal: %pI4\tRemote: %pI4\n", - &edge->attributes->standard.local, - &edge->attributes->standard.remote); + attr = edge->attributes; + if ((CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR))) + sbuf_push(&sbuf, 0, "\tLocal: %pI4\tRemote: %pI4\n", + &attr->standard.local, + &attr->standard.remote); + else if ((CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR6))) + sbuf_push(&sbuf, 0, "\tLocal: %pI6\tRemote: %pI6\n", + &attr->standard.local6, + &attr->standard.remote6); } sbuf_push(&sbuf, 4, "Incoming Edges: %d\n", @@ -2034,9 +2050,15 @@ static void ls_show_vertex_vty(struct ls_vertex *vertex, struct vty *vty, } else { sbuf_push(&sbuf, 6, "From:\t- (0.0.0.0)"); } - sbuf_push(&sbuf, 0, "\tRemote: %pI4\tLocal: %pI4\n", - &edge->attributes->standard.local, - &edge->attributes->standard.remote); + attr = edge->attributes; + if ((CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR))) + sbuf_push(&sbuf, 0, "\tLocal: %pI4\tRemote: %pI4\n", + &attr->standard.local, + &attr->standard.remote); + else if ((CHECK_FLAG(attr->flags, LS_ATTR_LOCAL_ADDR6))) + sbuf_push(&sbuf, 0, "\tLocal: %pI6\tRemote: %pI6\n", + &attr->standard.local6, + &attr->standard.remote6); } sbuf_push(&sbuf, 4, "Subnets: %d\n", listcount(vertex->prefixes)); @@ -2071,7 +2093,7 @@ static void ls_show_vertex_json(struct ls_vertex *vertex, json_object_string_add(json, "router-id", buf); } if (CHECK_FLAG(lsn->flags, LS_NODE_ROUTER_ID6)) { - snprintfrr(buf, INET6_BUFSIZ, "%pI6", &lsn->router6_id); + snprintfrr(buf, INET6_BUFSIZ, "%pI6", &lsn->router_id6); json_object_string_add(json, "router-id-v6", buf); } if (CHECK_FLAG(lsn->flags, LS_NODE_TYPE)) @@ -2235,15 +2257,32 @@ static void ls_show_edge_vty(struct ls_edge *edge, struct vty *vty, sbuf_push(&sbuf, 4, "Utilized Bandwidth: %g (Bytes/s)\n", attr->extended.used_bw); if (CHECK_FLAG(attr->flags, LS_ATTR_ADJ_SID)) { - sbuf_push(&sbuf, 4, "Adjacency-SID: %u", attr->adj_sid[0].sid); + sbuf_push(&sbuf, 4, "IPv4 Adjacency-SID: %u", + attr->adj_sid[ADJ_PRI_IPV4].sid); sbuf_push(&sbuf, 0, "\tFlags: 0x%x\tWeight: 0x%x\n", - attr->adj_sid[0].flags, attr->adj_sid[0].weight); + attr->adj_sid[ADJ_PRI_IPV4].flags, + attr->adj_sid[ADJ_PRI_IPV4].weight); } if (CHECK_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SID)) { - sbuf_push(&sbuf, 4, "Bck. Adjacency-SID: %u", - attr->adj_sid[1].sid); + sbuf_push(&sbuf, 4, "IPv4 Bck. Adjacency-SID: %u", + attr->adj_sid[ADJ_BCK_IPV4].sid); sbuf_push(&sbuf, 0, "\tFlags: 0x%x\tWeight: 0x%x\n", - attr->adj_sid[1].flags, attr->adj_sid[1].weight); + attr->adj_sid[ADJ_BCK_IPV4].flags, + attr->adj_sid[ADJ_BCK_IPV4].weight); + } + if (CHECK_FLAG(attr->flags, LS_ATTR_ADJ_SID6)) { + sbuf_push(&sbuf, 4, "IPv6 Adjacency-SID: %u", + attr->adj_sid[ADJ_PRI_IPV6].sid); + sbuf_push(&sbuf, 0, "\tFlags: 0x%x\tWeight: 0x%x\n", + attr->adj_sid[ADJ_PRI_IPV6].flags, + attr->adj_sid[ADJ_PRI_IPV6].weight); + } + if (CHECK_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SID6)) { + sbuf_push(&sbuf, 4, "IPv6 Bck. Adjacency-SID: %u", + attr->adj_sid[ADJ_BCK_IPV6].sid); + sbuf_push(&sbuf, 0, "\tFlags: 0x%x\tWeight: 0x%x\n", + attr->adj_sid[ADJ_BCK_IPV6].flags, + attr->adj_sid[ADJ_BCK_IPV6].weight); } if (CHECK_FLAG(attr->flags, LS_ATTR_SRLG)) { sbuf_push(&sbuf, 4, "SRLGs: %d", attr->srlg_len); @@ -2374,10 +2413,12 @@ static void ls_show_edge_json(struct ls_edge *edge, struct json_object *json) jsr = json_object_new_array(); json_object_object_add(json, "segment-routing", jsr); jobj = json_object_new_object(); - json_object_int_add(jobj, "adj-sid", attr->adj_sid[0].sid); - snprintfrr(buf, 6, "0x%x", attr->adj_sid[0].flags); + json_object_int_add(jobj, "adj-sid", + attr->adj_sid[ADJ_PRI_IPV4].sid); + snprintfrr(buf, 6, "0x%x", attr->adj_sid[ADJ_PRI_IPV4].flags); json_object_string_add(jobj, "flags", buf); - json_object_int_add(jobj, "weight", attr->adj_sid[0].weight); + json_object_int_add(jobj, "weight", + attr->adj_sid[ADJ_PRI_IPV4].weight); json_object_array_add(jsr, jobj); } if (CHECK_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SID)) { @@ -2386,10 +2427,38 @@ static void ls_show_edge_json(struct ls_edge *edge, struct json_object *json) json_object_object_add(json, "segment-routing", jsr); } jobj = json_object_new_object(); - json_object_int_add(jobj, "adj-sid", attr->adj_sid[1].sid); - snprintfrr(buf, 6, "0x%x", attr->adj_sid[1].flags); + json_object_int_add(jobj, "adj-sid", + attr->adj_sid[ADJ_BCK_IPV4].sid); + snprintfrr(buf, 6, "0x%x", attr->adj_sid[ADJ_BCK_IPV4].flags); json_object_string_add(jobj, "flags", buf); - json_object_int_add(jobj, "weight", attr->adj_sid[1].weight); + json_object_int_add(jobj, "weight", + attr->adj_sid[ADJ_BCK_IPV4].weight); + json_object_array_add(jsr, jobj); + } + if (CHECK_FLAG(attr->flags, LS_ATTR_ADJ_SID6)) { + jsr = json_object_new_array(); + json_object_object_add(json, "segment-routing", jsr); + jobj = json_object_new_object(); + json_object_int_add(jobj, "adj-sid", + attr->adj_sid[ADJ_PRI_IPV6].sid); + snprintfrr(buf, 6, "0x%x", attr->adj_sid[ADJ_PRI_IPV6].flags); + json_object_string_add(jobj, "flags", buf); + json_object_int_add(jobj, "weight", + attr->adj_sid[ADJ_PRI_IPV6].weight); + json_object_array_add(jsr, jobj); + } + if (CHECK_FLAG(attr->flags, LS_ATTR_BCK_ADJ_SID6)) { + if (!jsr) { + jsr = json_object_new_array(); + json_object_object_add(json, "segment-routing", jsr); + } + jobj = json_object_new_object(); + json_object_int_add(jobj, "adj-sid", + attr->adj_sid[ADJ_BCK_IPV6].sid); + snprintfrr(buf, 6, "0x%x", attr->adj_sid[ADJ_BCK_IPV6].flags); + json_object_string_add(jobj, "flags", buf); + json_object_int_add(jobj, "weight", + attr->adj_sid[ADJ_BCK_IPV6].weight); json_object_array_add(jsr, jobj); } } diff --git a/lib/link_state.h b/lib/link_state.h index 981e8b5285..761e8b6a27 100644 --- a/lib/link_state.h +++ b/lib/link_state.h @@ -122,7 +122,7 @@ struct ls_node { struct ls_node_id adv; /* Adv. Router of this Link State */ char name[MAX_NAME_LENGTH]; /* Name of the Node (IS-IS only) */ struct in_addr router_id; /* IPv4 Router ID */ - struct in6_addr router6_id; /* IPv6 Router ID */ + struct in6_addr router_id6; /* IPv6 Router ID */ uint8_t node_flag; /* IS-IS or OSPF Node flag */ enum ls_node_type type; /* Type of Node */ uint32_t as_number; /* Local or neighbor AS number */ @@ -166,6 +166,8 @@ struct ls_node { #define LS_ATTR_USE_BW 0x00400000 #define LS_ATTR_ADJ_SID 0x01000000 #define LS_ATTR_BCK_ADJ_SID 0x02000000 +#define LS_ATTR_ADJ_SID6 0x04000000 +#define LS_ATTR_BCK_ADJ_SID6 0x08000000 #define LS_ATTR_SRLG 0x10000000 /* Link State Attributes */ @@ -200,6 +202,11 @@ struct ls_attributes { float rsv_bw; /* Reserved Bandwidth */ float used_bw; /* Utilized Bandwidth */ } extended; +#define ADJ_PRI_IPV4 0 +#define ADJ_BCK_IPV4 1 +#define ADJ_PRI_IPV6 2 +#define ADJ_BCK_IPV6 3 +#define LS_ADJ_MAX 4 struct ls_adjacency { /* (LAN)-Adjacency SID for OSPF */ uint32_t sid; /* SID as MPLS label or index */ uint8_t flags; /* Flags */ @@ -208,7 +215,7 @@ struct ls_attributes { struct in_addr addr; /* Neighbor @IP for OSPF */ uint8_t sysid[ISO_SYS_ID_LEN]; /* or Sys-ID for ISIS */ } neighbor; - } adj_sid[2]; /* Primary & Backup (LAN)-Adj. SID */ + } adj_sid[4]; /* IPv4/IPv6 & Primary/Backup (LAN)-Adj. SID */ uint32_t *srlgs; /* List of Shared Risk Link Group */ uint8_t srlg_len; /* number of SRLG in the list */ }; @@ -412,21 +419,34 @@ struct ls_subnet { macro_inline int vertex_cmp(const struct ls_vertex *node1, const struct ls_vertex *node2) { - return (node1->key - node2->key); + return numcmp(node1->key, node2->key); } DECLARE_RBTREE_UNIQ(vertices, struct ls_vertex, entry, vertex_cmp); macro_inline int edge_cmp(const struct ls_edge *edge1, const struct ls_edge *edge2) { - return (edge1->key - edge2->key); + return numcmp(edge1->key, edge2->key); } DECLARE_RBTREE_UNIQ(edges, struct ls_edge, entry, edge_cmp); +/* + * Prefix comparison are done to the host part so, 10.0.0.1/24 + * and 10.0.0.2/24 are considered come different + */ macro_inline int subnet_cmp(const struct ls_subnet *a, - const struct ls_subnet *b) + const struct ls_subnet *b) { - return prefix_cmp(&a->key, &b->key); + if (a->key.family != b->key.family) + return numcmp(a->key.family, b->key.family); + + if (a->key.prefixlen != b->key.prefixlen) + return numcmp(a->key.prefixlen, b->key.prefixlen); + + if (a->key.family == AF_INET) + return memcmp(&a->key.u.val, &b->key.u.val, 4); + + return memcmp(&a->key.u.val, &b->key.u.val, 16); } DECLARE_RBTREE_UNIQ(subnets, struct ls_subnet, entry, subnet_cmp); @@ -503,6 +523,16 @@ extern struct ls_vertex *ls_vertex_update(struct ls_ted *ted, */ extern void ls_vertex_clean(struct ls_ted *ted, struct ls_vertex *vertex, struct zclient *zclient); + +/** + * This function convert the ISIS ISO system ID into a 64 bits unsigned integer + * following the architecture dependent byte order. + * + * @param sysid The ISO system ID + * @return Key as 64 bits unsigned integer + */ +extern uint64_t sysid_to_key(const uint8_t sysid[ISO_SYS_ID_LEN]); + /** * Find Vertex in the Link State DB by its unique key. * diff --git a/tests/isisd/test_fuzz_isis_tlv_tests.h.gz b/tests/isisd/test_fuzz_isis_tlv_tests.h.gz index b50c5683bf..accc906bf2 100644 Binary files a/tests/isisd/test_fuzz_isis_tlv_tests.h.gz and b/tests/isisd/test_fuzz_isis_tlv_tests.h.gz differ diff --git a/tests/topotests/isis_te_topo1/__init__.py b/tests/topotests/isis_te_topo1/__init__.py new file mode 100755 index 0000000000..e69de29bb2 diff --git a/tests/topotests/isis_te_topo1/r1/isisd.conf b/tests/topotests/isis_te_topo1/r1/isisd.conf new file mode 100644 index 0000000000..938d713ced --- /dev/null +++ b/tests/topotests/isis_te_topo1/r1/isisd.conf @@ -0,0 +1,31 @@ +! +hostname r1 +! +interface lo + ip router isis TE + ipv6 router isis TE + isis circuit-type level-2-only + isis passive +! +interface r1-eth0 + ip router isis TE + isis circuit-type level-2-only + isis network point-to-point + isis hello-multiplier 3 +! +interface r1-eth1 + ip router isis TE + ipv6 router isis TE + isis circuit-type level-2-only + isis network point-to-point + isis hello-multiplier 3 +! +router isis TE + net 49.0000.0000.0000.0001.00 + is-type level-2-only + topology ipv6-unicast + lsp-timers gen-interval 2 refresh-interval 10 max-lifetime 350 + mpls-te on + mpls-te router-address 10.0.255.1 +! + diff --git a/tests/topotests/isis_te_topo1/r1/zebra.conf b/tests/topotests/isis_te_topo1/r1/zebra.conf new file mode 100644 index 0000000000..814d8f8c97 --- /dev/null +++ b/tests/topotests/isis_te_topo1/r1/zebra.conf @@ -0,0 +1,25 @@ +! +hostname r1 +! +interface lo + ip address 10.0.255.1/32 + ipv6 address 2001:db8:ffff::1/128 +! +interface r1-eth0 + ip address 10.0.0.1/24 + link-params + metric 20 + delay 10000 + ava-bw 1.25e+08 + enable + exit-link-params +! +interface r1-eth1 + ip address 10.0.1.1/24 + ipv6 address 2001:db8:1::1:1/64 + link-params + enable + exit-link-params +! +ip forwarding +! diff --git a/tests/topotests/isis_te_topo1/r2/isisd.conf b/tests/topotests/isis_te_topo1/r2/isisd.conf new file mode 100644 index 0000000000..f389e90762 --- /dev/null +++ b/tests/topotests/isis_te_topo1/r2/isisd.conf @@ -0,0 +1,45 @@ +! +hostname r2 +! +! debug isis te-events +! +interface lo + ip router isis TE + ipv6 router isis TE + isis circuit-type level-2-only + isis passive +! +interface r2-eth0 + ip router isis TE + isis circuit-type level-2-only + isis network point-to-point + isis hello-multiplier 3 +! +interface r2-eth1 + ip router isis TE + ipv6 router isis TE + isis circuit-type level-2-only + isis network point-to-point + isis hello-multiplier 3 +! +interface r2-eth2 + ip router isis TE + ipv6 router isis TE + isis circuit-type level-2-only + isis network point-to-point + isis hello-multiplier 3 +! +interface r2-eth3 + ip router isis TE + isis circuit-type level-2-only + isis network point-to-point + isis hello-multiplier 3 +! +router isis TE + net 49.0000.0000.0000.0002.00 + is-type level-2-only + topology ipv6-unicast + lsp-timers gen-interval 2 refresh-interval 10 max-lifetime 350 + mpls-te on + mpls-te router-address 10.0.255.2 +! diff --git a/tests/topotests/isis_te_topo1/r2/zebra.conf b/tests/topotests/isis_te_topo1/r2/zebra.conf new file mode 100644 index 0000000000..26b48ded78 --- /dev/null +++ b/tests/topotests/isis_te_topo1/r2/zebra.conf @@ -0,0 +1,39 @@ +! +hostname r2 +! +interface lo + ip address 10.0.255.2/32 + ipv6 address 2001:db8:ffff::2/128 +! +interface r2-eth0 + ip address 10.0.0.2/24 + link-params + enable + exit-link-params +! +interface r2-eth1 + ip address 10.0.1.2/24 + ipv6 address 2001:db8:1::1:2/64 + link-params + enable + exit-link-params +! +interface r2-eth2 + ip address 10.0.3.2/24 + ipv6 address 2001:db8:3::3:2/64 + link-params + enable + exit-link-params +! +interface r2-eth3 + ip address 10.0.4.2/24 + ipv6 address 2001:db8:4::4:2/64 + link-params + metric 30 + delay 25000 + use-bw 1.25e+8 + enable + exit-link-params +! +ip forwarding +! diff --git a/tests/topotests/isis_te_topo1/r3/isisd.conf b/tests/topotests/isis_te_topo1/r3/isisd.conf new file mode 100644 index 0000000000..4920a17c4c --- /dev/null +++ b/tests/topotests/isis_te_topo1/r3/isisd.conf @@ -0,0 +1,34 @@ +! +hostname r3 +! +! debug isis te-events +! +interface lo + ip router isis TE + ipv6 router isis TE + isis circuit-type level-2-only + isis passive +! +interface r3-eth0 + ip router isis TE + ipv6 router isis TE + isis circuit-type level-2-only + isis network point-to-point + isis hello-multiplier 3 +! +interface r3-eth1 + ipv6 router isis TE + isis circuit-type level-2-only + isis network point-to-point + isis hello-multiplier 3 +! +! +router isis TE + net 49.0000.0000.0000.0003.00 + is-type level-2-only + topology ipv6-unicast + lsp-timers gen-interval 2 refresh-interval 10 max-lifetime 350 + mpls-te on + mpls-te router-address 10.0.255.3 + mpls-te router-address ipv6 2001:db8:1000::3 +! diff --git a/tests/topotests/isis_te_topo1/r3/zebra.conf b/tests/topotests/isis_te_topo1/r3/zebra.conf new file mode 100644 index 0000000000..6a82f30d82 --- /dev/null +++ b/tests/topotests/isis_te_topo1/r3/zebra.conf @@ -0,0 +1,25 @@ +! +hostname r3 +! +interface lo + ip address 10.0.255.3/32 + ipv6 address 2001:db8:ffff::3/128 +! +interface r3-eth0 + ip address 10.0.3.3/24 + ipv6 address 2001:db8:3::3:3/64 + link-params + enable + admin-grp 0x20 + exit-link-params +! +interface r3-eth1 + ipv6 address 2001:db8:5::4:3/64 + link-params + enable + metric 10 + delay 50000 + exit-link-params +! +ip forwarding +! diff --git a/tests/topotests/isis_te_topo1/r4/isisd.conf b/tests/topotests/isis_te_topo1/r4/isisd.conf new file mode 100644 index 0000000000..51e9ba6dec --- /dev/null +++ b/tests/topotests/isis_te_topo1/r4/isisd.conf @@ -0,0 +1,39 @@ +! +hostname r4 +! +! debug isis te-events +! debug isis sr-events +! debug isis lsp-gen +! +interface lo + ip router isis TE + ipv6 router isis TE + isis circuit-type level-2-only + isis passive +! +interface r4-eth0 + ip router isis TE + isis circuit-type level-2-only + isis network point-to-point + isis hello-multiplier 3 +! +interface r4-eth1 + ipv6 router isis TE + isis circuit-type level-2-only + isis network point-to-point + isis hello-multiplier 3 +! +! +router isis TE + net 49.0000.0000.0000.0004.00 + is-type level-2-only + topology ipv6-unicast + lsp-timers gen-interval 2 refresh-interval 10 max-lifetime 350 + mpls-te on + mpls-te router-address 10.0.255.4 + segment-routing on + segment-routing global-block 10000 19999 local-block 5000 5999 + segment-routing node-msd 12 + segment-routing prefix 10.0.255.4/32 index 400 no-php-flag + segment-routing prefix 2001:db8:ffff::4/128 index 1400 no-php-flag +! diff --git a/tests/topotests/isis_te_topo1/r4/zebra.conf b/tests/topotests/isis_te_topo1/r4/zebra.conf new file mode 100644 index 0000000000..2f6a38e77a --- /dev/null +++ b/tests/topotests/isis_te_topo1/r4/zebra.conf @@ -0,0 +1,22 @@ +! +hostname r4 +! +interface lo + ip address 10.0.255.4/32 + ipv6 address 2001:db8:ffff::4/128 +! +interface r4-eth0 + ip address 10.0.4.4/24 + ipv6 address 2001:db8:4::2:4/64 + link-params + enable + exit-link-params +! +interface r4-eth1 + ipv6 address 2001:db8:5::3:4/64 + link-params + enable + exit-link-params +! +ip forwarding +! diff --git a/tests/topotests/isis_te_topo1/reference/ted_step1.json b/tests/topotests/isis_te_topo1/reference/ted_step1.json new file mode 100644 index 0000000000..7a47733801 --- /dev/null +++ b/tests/topotests/isis_te_topo1/reference/ted_step1.json @@ -0,0 +1,851 @@ +{ + "ted":{ + "name":"ISIS", + "key":1, + "verticesCount":4, + "edgesCount":14, + "subnetsCount":22, + "vertices":[ + { + "vertex-id":1, + "status":"Sync", + "origin":"ISIS_L2", + "name":"r1", + "router-id":"10.0.255.1" + }, + { + "vertex-id":2, + "status":"Sync", + "origin":"ISIS_L2", + "name":"r2", + "router-id":"10.0.255.2" + }, + { + "vertex-id":3, + "status":"Sync", + "origin":"ISIS_L2", + "name":"r3", + "router-id":"10.0.255.3", + "router-id-v6":"2001:db8:1000::3" + }, + { + "vertex-id":4, + "status":"Sync", + "origin":"ISIS_L2", + "name":"r4", + "router-id":"10.0.255.4", + "segment-routing":{ + "srgb-size":10000, + "srgb-lower":10000, + "algorithms":[ + { + "0":"SPF" + } + ], + "srlb-size":1000, + "srlb-lower":5000, + "msd":12 + } + } + ], + "edges":[ + { + "edge-id":65537, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "local-vertex-id":1, + "remote-vertex-id":2, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address-v6":"2001:db8:1::1:1", + "remote-address-v6":"2001:db8:1::1:2", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":65538, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "local-vertex-id":2, + "remote-vertex-id":1, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address-v6":"2001:db8:1::1:2", + "remote-address-v6":"2001:db8:1::1:1", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":196610, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "local-vertex-id":2, + "remote-vertex-id":3, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address-v6":"2001:db8:3::3:2", + "remote-address-v6":"2001:db8:3::3:3", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":196611, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "local-vertex-id":3, + "remote-vertex-id":2, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "admin-group":32, + "local-address-v6":"2001:db8:3::3:3", + "remote-address-v6":"2001:db8:3::3:2", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":196612, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0004", + "local-vertex-id":4, + "remote-vertex-id":3, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address-v6":"2001:db8:5::3:4", + "remote-address-v6":"2001:db8:5::4:3", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + }, + "segment-routing":[ + { + "adj-sid":5001, + "flags":"0xb0", + "weight":0 + } + ] + }, + { + "edge-id":262147, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "local-vertex-id":3, + "remote-vertex-id":4, + "metric":10, + "edge-attributes":{ + "te-metric":10, + "local-address-v6":"2001:db8:5::4:3", + "remote-address-v6":"2001:db8:5::3:4", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ], + "delay":50000 + } + }, + { + "edge-id":167772161, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "local-vertex-id":1, + "remote-vertex-id":2, + "metric":10, + "edge-attributes":{ + "te-metric":20, + "local-address":"10.0.0.1", + "remote-address":"10.0.0.2", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ], + "delay":10000, + "available-bandwidth":125000000.0 + } + }, + { + "edge-id":167772162, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "local-vertex-id":2, + "remote-vertex-id":1, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address":"10.0.0.2", + "remote-address":"10.0.0.1", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":167772417, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "local-vertex-id":1, + "remote-vertex-id":2, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address":"10.0.1.1", + "remote-address":"10.0.1.2", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":167772418, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "local-vertex-id":2, + "remote-vertex-id":1, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address":"10.0.1.2", + "remote-address":"10.0.1.1", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":167772930, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "local-vertex-id":2, + "remote-vertex-id":3, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address":"10.0.3.2", + "remote-address":"10.0.3.3", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":167772931, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "local-vertex-id":3, + "remote-vertex-id":2, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "admin-group":32, + "local-address":"10.0.3.3", + "remote-address":"10.0.3.2", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":167773186, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "local-vertex-id":2, + "remote-vertex-id":4, + "metric":10, + "edge-attributes":{ + "te-metric":30, + "local-address":"10.0.4.2", + "remote-address":"10.0.4.4", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ], + "delay":25000, + "utilized-bandwidth":125000000.0 + } + }, + { + "edge-id":167773188, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0004", + "local-vertex-id":4, + "remote-vertex-id":2, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address":"10.0.4.4", + "remote-address":"10.0.4.2", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + }, + "segment-routing":[ + { + "adj-sid":5000, + "flags":"0x30", + "weight":0 + } + ] + } + ], + "subnets":[ + { + "subnet-id":"10.0.0.1\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "vertex-id":1, + "metric":10 + }, + { + "subnet-id":"10.0.0.2\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"10.0.1.1\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "vertex-id":1, + "metric":10 + }, + { + "subnet-id":"10.0.1.2\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"10.0.3.2\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"10.0.3.3\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "vertex-id":3, + "metric":10 + }, + { + "subnet-id":"10.0.4.2\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"10.0.4.4\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0004", + "vertex-id":4, + "metric":10 + }, + { + "subnet-id":"10.0.255.1\/32", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "vertex-id":1, + "metric":10 + }, + { + "subnet-id":"10.0.255.2\/32", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"10.0.255.3\/32", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "vertex-id":3, + "metric":10 + }, + { + "subnet-id":"10.0.255.4\/32", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0004", + "vertex-id":4, + "metric":10, + "segment-routing":{ + "pref-sid":400, + "algo":0, + "flags":"0x60" + } + }, + { + "subnet-id":"2001:db8:1::1:1\/64", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "vertex-id":1, + "metric":10 + }, + { + "subnet-id":"2001:db8:1::1:2\/64", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"2001:db8:3::3:2\/64", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"2001:db8:3::3:3\/64", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "vertex-id":3, + "metric":10 + }, + { + "subnet-id":"2001:db8:5::3:4\/64", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0004", + "vertex-id":4, + "metric":10 + }, + { + "subnet-id":"2001:db8:5::4:3\/64", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "vertex-id":3, + "metric":10 + }, + { + "subnet-id":"2001:db8:ffff::1\/128", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "vertex-id":1, + "metric":10 + }, + { + "subnet-id":"2001:db8:ffff::2\/128", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"2001:db8:ffff::3\/128", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "vertex-id":3, + "metric":10 + }, + { + "subnet-id":"2001:db8:ffff::4\/128", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0004", + "vertex-id":4, + "metric":10, + "segment-routing":{ + "pref-sid":1400, + "algo":0, + "flags":"0x60" + } + } + ] + } +} diff --git a/tests/topotests/isis_te_topo1/reference/ted_step2.json b/tests/topotests/isis_te_topo1/reference/ted_step2.json new file mode 100644 index 0000000000..8277e6d532 --- /dev/null +++ b/tests/topotests/isis_te_topo1/reference/ted_step2.json @@ -0,0 +1,651 @@ +{ + "ted":{ + "name":"ISIS", + "key":1, + "verticesCount":4, + "edgesCount":10, + "subnetsCount":18, + "vertices":[ + { + "vertex-id":1, + "status":"Sync", + "origin":"ISIS_L2", + "name":"r1", + "router-id":"10.0.255.1" + }, + { + "vertex-id":2, + "status":"Sync", + "origin":"ISIS_L2", + "name":"r2", + "router-id":"10.0.255.2" + }, + { + "vertex-id":3, + "status":"Sync", + "origin":"ISIS_L2", + "name":"r3", + "router-id":"10.0.255.3", + "router-id-v6":"2001:db8:1000::3" + }, + { + "vertex-id":4, + "status":"Sync", + "origin":"ISIS_L2", + "name":"r4", + "router-id":"10.0.255.4", + "segment-routing":{ + "srgb-size":10000, + "srgb-lower":10000, + "algorithms":[ + { + "0":"SPF" + } + ], + "srlb-size":1000, + "srlb-lower":5000, + "msd":12 + } + } + ], + "edges":[ + { + "edge-id":196610, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "local-vertex-id":2, + "remote-vertex-id":3, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address-v6":"2001:db8:3::3:2", + "remote-address-v6":"2001:db8:3::3:3", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":196611, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "local-vertex-id":3, + "remote-vertex-id":2, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "admin-group":32, + "local-address-v6":"2001:db8:3::3:3", + "remote-address-v6":"2001:db8:3::3:2", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":196612, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0004", + "local-vertex-id":4, + "remote-vertex-id":3, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address-v6":"2001:db8:5::3:4", + "remote-address-v6":"2001:db8:5::4:3", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + }, + "segment-routing":[ + { + "adj-sid":5001, + "flags":"0xb0", + "weight":0 + } + ] + }, + { + "edge-id":262147, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "local-vertex-id":3, + "remote-vertex-id":4, + "metric":10, + "edge-attributes":{ + "te-metric":10, + "local-address-v6":"2001:db8:5::4:3", + "remote-address-v6":"2001:db8:5::3:4", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ], + "delay":50000 + } + }, + { + "edge-id":167772161, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "local-vertex-id":1, + "remote-vertex-id":2, + "metric":10, + "edge-attributes":{ + "te-metric":20, + "local-address":"10.0.0.1", + "remote-address":"10.0.0.2", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ], + "delay":10000, + "available-bandwidth":125000000.0 + } + }, + { + "edge-id":167772162, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "local-vertex-id":2, + "remote-vertex-id":1, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address":"10.0.0.2", + "remote-address":"10.0.0.1", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":167772930, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "local-vertex-id":2, + "remote-vertex-id":3, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address":"10.0.3.2", + "remote-address":"10.0.3.3", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":167772931, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "local-vertex-id":3, + "remote-vertex-id":2, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "admin-group":32, + "local-address":"10.0.3.3", + "remote-address":"10.0.3.2", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":167773186, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "local-vertex-id":2, + "remote-vertex-id":4, + "metric":10, + "edge-attributes":{ + "te-metric":30, + "local-address":"10.0.4.2", + "remote-address":"10.0.4.4", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ], + "delay":25000, + "utilized-bandwidth":125000000.0 + } + }, + { + "edge-id":167773188, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0004", + "local-vertex-id":4, + "remote-vertex-id":2, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address":"10.0.4.4", + "remote-address":"10.0.4.2", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + }, + "segment-routing":[ + { + "adj-sid":5000, + "flags":"0x30", + "weight":0 + } + ] + } + ], + "subnets":[ + { + "subnet-id":"10.0.0.1\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "vertex-id":1, + "metric":10 + }, + { + "subnet-id":"10.0.0.2\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"10.0.3.2\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"10.0.3.3\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "vertex-id":3, + "metric":10 + }, + { + "subnet-id":"10.0.4.2\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"10.0.4.4\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0004", + "vertex-id":4, + "metric":10 + }, + { + "subnet-id":"10.0.255.1\/32", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "vertex-id":1, + "metric":10 + }, + { + "subnet-id":"10.0.255.2\/32", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"10.0.255.3\/32", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "vertex-id":3, + "metric":10 + }, + { + "subnet-id":"10.0.255.4\/32", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0004", + "vertex-id":4, + "metric":10, + "segment-routing":{ + "pref-sid":400, + "algo":0, + "flags":"0x60" + } + }, + { + "subnet-id":"2001:db8:3::3:2\/64", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"2001:db8:3::3:3\/64", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "vertex-id":3, + "metric":10 + }, + { + "subnet-id":"2001:db8:5::3:4\/64", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0004", + "vertex-id":4, + "metric":10 + }, + { + "subnet-id":"2001:db8:5::4:3\/64", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "vertex-id":3, + "metric":10 + }, + { + "subnet-id":"2001:db8:ffff::1\/128", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "vertex-id":1, + "metric":10 + }, + { + "subnet-id":"2001:db8:ffff::2\/128", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"2001:db8:ffff::3\/128", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "vertex-id":3, + "metric":10 + }, + { + "subnet-id":"2001:db8:ffff::4\/128", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0004", + "vertex-id":4, + "metric":10, + "segment-routing":{ + "pref-sid":1400, + "algo":0, + "flags":"0x60" + } + } + ] + } +} diff --git a/tests/topotests/isis_te_topo1/reference/ted_step3.json b/tests/topotests/isis_te_topo1/reference/ted_step3.json new file mode 100644 index 0000000000..0ade398847 --- /dev/null +++ b/tests/topotests/isis_te_topo1/reference/ted_step3.json @@ -0,0 +1,752 @@ +{ + "ted":{ + "name":"ISIS", + "key":1, + "verticesCount":4, + "edgesCount":12, + "subnetsCount":20, + "vertices":[ + { + "vertex-id":1, + "status":"Sync", + "origin":"ISIS_L2", + "name":"r1", + "router-id":"10.0.255.1" + }, + { + "vertex-id":2, + "status":"Sync", + "origin":"ISIS_L2", + "name":"r2", + "router-id":"10.0.255.2" + }, + { + "vertex-id":3, + "status":"Sync", + "origin":"ISIS_L2", + "name":"r3", + "router-id":"10.0.255.3", + "router-id-v6":"2001:db8:1000::3" + }, + { + "vertex-id":4, + "status":"Sync", + "origin":"ISIS_L2", + "name":"r4", + "router-id":"10.0.255.4", + "segment-routing":{ + "srgb-size":10000, + "srgb-lower":10000, + "algorithms":[ + { + "0":"SPF" + } + ], + "srlb-size":1000, + "srlb-lower":5000, + "msd":12 + } + } + ], + "edges":[ + { + "edge-id":1, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "local-vertex-id":1, + "remote-vertex-id":2, + "metric":10, + "edge-attributes":{ + "te-metric":20, + "local-address-v6":"2001:db8::1", + "remote-address-v6":"2001:db8::2", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ], + "delay":10000, + "available-bandwidth":125000000.0 + } + }, + { + "edge-id":2, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "local-vertex-id":2, + "remote-vertex-id":1, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address-v6":"2001:db8::2", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":196610, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "local-vertex-id":2, + "remote-vertex-id":3, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address-v6":"2001:db8:3::3:2", + "remote-address-v6":"2001:db8:3::3:3", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":196611, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "local-vertex-id":3, + "remote-vertex-id":2, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "admin-group":32, + "local-address-v6":"2001:db8:3::3:3", + "remote-address-v6":"2001:db8:3::3:2", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":196612, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0004", + "local-vertex-id":4, + "remote-vertex-id":3, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address-v6":"2001:db8:5::3:4", + "remote-address-v6":"2001:db8:5::4:3", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + }, + "segment-routing":[ + { + "adj-sid":5001, + "flags":"0xb0", + "weight":0 + } + ] + }, + { + "edge-id":262147, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "local-vertex-id":3, + "remote-vertex-id":4, + "metric":10, + "edge-attributes":{ + "te-metric":10, + "local-address-v6":"2001:db8:5::4:3", + "remote-address-v6":"2001:db8:5::3:4", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ], + "delay":50000 + } + }, + { + "edge-id":167772161, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "local-vertex-id":1, + "remote-vertex-id":2, + "metric":10, + "edge-attributes":{ + "te-metric":20, + "local-address":"10.0.0.1", + "remote-address":"10.0.0.2", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ], + "delay":10000, + "available-bandwidth":125000000.0 + } + }, + { + "edge-id":167772162, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "local-vertex-id":2, + "remote-vertex-id":1, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address":"10.0.0.2", + "remote-address":"10.0.0.1", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":167772930, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "local-vertex-id":2, + "remote-vertex-id":3, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address":"10.0.3.2", + "remote-address":"10.0.3.3", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":167772931, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "local-vertex-id":3, + "remote-vertex-id":2, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "admin-group":32, + "local-address":"10.0.3.3", + "remote-address":"10.0.3.2", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":167773186, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "local-vertex-id":2, + "remote-vertex-id":4, + "metric":10, + "edge-attributes":{ + "te-metric":30, + "local-address":"10.0.4.2", + "remote-address":"10.0.4.4", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ], + "delay":25000, + "utilized-bandwidth":125000000.0 + } + }, + { + "edge-id":167773188, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0004", + "local-vertex-id":4, + "remote-vertex-id":2, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address":"10.0.4.4", + "remote-address":"10.0.4.2", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + }, + "segment-routing":[ + { + "adj-sid":5000, + "flags":"0x30", + "weight":0 + } + ] + } + ], + "subnets":[ + { + "subnet-id":"10.0.0.1\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "vertex-id":1, + "metric":10 + }, + { + "subnet-id":"10.0.0.2\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"10.0.3.2\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"10.0.3.3\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "vertex-id":3, + "metric":10 + }, + { + "subnet-id":"10.0.4.2\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"10.0.4.4\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0004", + "vertex-id":4, + "metric":10 + }, + { + "subnet-id":"10.0.255.1\/32", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "vertex-id":1, + "metric":10 + }, + { + "subnet-id":"10.0.255.2\/32", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"10.0.255.3\/32", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "vertex-id":3, + "metric":10 + }, + { + "subnet-id":"10.0.255.4\/32", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0004", + "vertex-id":4, + "metric":10, + "segment-routing":{ + "pref-sid":400, + "algo":0, + "flags":"0x60" + } + }, + { + "subnet-id":"2001:db8::1\/64", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "vertex-id":1, + "metric":10 + }, + { + "subnet-id":"2001:db8::2\/64", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"2001:db8:3::3:2\/64", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"2001:db8:3::3:3\/64", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "vertex-id":3, + "metric":10 + }, + { + "subnet-id":"2001:db8:5::3:4\/64", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0004", + "vertex-id":4, + "metric":10 + }, + { + "subnet-id":"2001:db8:5::4:3\/64", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "vertex-id":3, + "metric":10 + }, + { + "subnet-id":"2001:db8:ffff::1\/128", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "vertex-id":1, + "metric":10 + }, + { + "subnet-id":"2001:db8:ffff::2\/128", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"2001:db8:ffff::3\/128", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "vertex-id":3, + "metric":10 + }, + { + "subnet-id":"2001:db8:ffff::4\/128", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0004", + "vertex-id":4, + "metric":10, + "segment-routing":{ + "pref-sid":1400, + "algo":0, + "flags":"0x60" + } + } + ] + } +} diff --git a/tests/topotests/isis_te_topo1/reference/ted_step4.json b/tests/topotests/isis_te_topo1/reference/ted_step4.json new file mode 100644 index 0000000000..0ade398847 --- /dev/null +++ b/tests/topotests/isis_te_topo1/reference/ted_step4.json @@ -0,0 +1,752 @@ +{ + "ted":{ + "name":"ISIS", + "key":1, + "verticesCount":4, + "edgesCount":12, + "subnetsCount":20, + "vertices":[ + { + "vertex-id":1, + "status":"Sync", + "origin":"ISIS_L2", + "name":"r1", + "router-id":"10.0.255.1" + }, + { + "vertex-id":2, + "status":"Sync", + "origin":"ISIS_L2", + "name":"r2", + "router-id":"10.0.255.2" + }, + { + "vertex-id":3, + "status":"Sync", + "origin":"ISIS_L2", + "name":"r3", + "router-id":"10.0.255.3", + "router-id-v6":"2001:db8:1000::3" + }, + { + "vertex-id":4, + "status":"Sync", + "origin":"ISIS_L2", + "name":"r4", + "router-id":"10.0.255.4", + "segment-routing":{ + "srgb-size":10000, + "srgb-lower":10000, + "algorithms":[ + { + "0":"SPF" + } + ], + "srlb-size":1000, + "srlb-lower":5000, + "msd":12 + } + } + ], + "edges":[ + { + "edge-id":1, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "local-vertex-id":1, + "remote-vertex-id":2, + "metric":10, + "edge-attributes":{ + "te-metric":20, + "local-address-v6":"2001:db8::1", + "remote-address-v6":"2001:db8::2", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ], + "delay":10000, + "available-bandwidth":125000000.0 + } + }, + { + "edge-id":2, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "local-vertex-id":2, + "remote-vertex-id":1, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address-v6":"2001:db8::2", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":196610, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "local-vertex-id":2, + "remote-vertex-id":3, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address-v6":"2001:db8:3::3:2", + "remote-address-v6":"2001:db8:3::3:3", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":196611, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "local-vertex-id":3, + "remote-vertex-id":2, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "admin-group":32, + "local-address-v6":"2001:db8:3::3:3", + "remote-address-v6":"2001:db8:3::3:2", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":196612, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0004", + "local-vertex-id":4, + "remote-vertex-id":3, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address-v6":"2001:db8:5::3:4", + "remote-address-v6":"2001:db8:5::4:3", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + }, + "segment-routing":[ + { + "adj-sid":5001, + "flags":"0xb0", + "weight":0 + } + ] + }, + { + "edge-id":262147, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "local-vertex-id":3, + "remote-vertex-id":4, + "metric":10, + "edge-attributes":{ + "te-metric":10, + "local-address-v6":"2001:db8:5::4:3", + "remote-address-v6":"2001:db8:5::3:4", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ], + "delay":50000 + } + }, + { + "edge-id":167772161, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "local-vertex-id":1, + "remote-vertex-id":2, + "metric":10, + "edge-attributes":{ + "te-metric":20, + "local-address":"10.0.0.1", + "remote-address":"10.0.0.2", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ], + "delay":10000, + "available-bandwidth":125000000.0 + } + }, + { + "edge-id":167772162, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "local-vertex-id":2, + "remote-vertex-id":1, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address":"10.0.0.2", + "remote-address":"10.0.0.1", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":167772930, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "local-vertex-id":2, + "remote-vertex-id":3, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address":"10.0.3.2", + "remote-address":"10.0.3.3", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":167772931, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "local-vertex-id":3, + "remote-vertex-id":2, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "admin-group":32, + "local-address":"10.0.3.3", + "remote-address":"10.0.3.2", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":167773186, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "local-vertex-id":2, + "remote-vertex-id":4, + "metric":10, + "edge-attributes":{ + "te-metric":30, + "local-address":"10.0.4.2", + "remote-address":"10.0.4.4", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ], + "delay":25000, + "utilized-bandwidth":125000000.0 + } + }, + { + "edge-id":167773188, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0004", + "local-vertex-id":4, + "remote-vertex-id":2, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address":"10.0.4.4", + "remote-address":"10.0.4.2", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + }, + "segment-routing":[ + { + "adj-sid":5000, + "flags":"0x30", + "weight":0 + } + ] + } + ], + "subnets":[ + { + "subnet-id":"10.0.0.1\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "vertex-id":1, + "metric":10 + }, + { + "subnet-id":"10.0.0.2\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"10.0.3.2\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"10.0.3.3\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "vertex-id":3, + "metric":10 + }, + { + "subnet-id":"10.0.4.2\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"10.0.4.4\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0004", + "vertex-id":4, + "metric":10 + }, + { + "subnet-id":"10.0.255.1\/32", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "vertex-id":1, + "metric":10 + }, + { + "subnet-id":"10.0.255.2\/32", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"10.0.255.3\/32", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "vertex-id":3, + "metric":10 + }, + { + "subnet-id":"10.0.255.4\/32", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0004", + "vertex-id":4, + "metric":10, + "segment-routing":{ + "pref-sid":400, + "algo":0, + "flags":"0x60" + } + }, + { + "subnet-id":"2001:db8::1\/64", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "vertex-id":1, + "metric":10 + }, + { + "subnet-id":"2001:db8::2\/64", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"2001:db8:3::3:2\/64", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"2001:db8:3::3:3\/64", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "vertex-id":3, + "metric":10 + }, + { + "subnet-id":"2001:db8:5::3:4\/64", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0004", + "vertex-id":4, + "metric":10 + }, + { + "subnet-id":"2001:db8:5::4:3\/64", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "vertex-id":3, + "metric":10 + }, + { + "subnet-id":"2001:db8:ffff::1\/128", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "vertex-id":1, + "metric":10 + }, + { + "subnet-id":"2001:db8:ffff::2\/128", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"2001:db8:ffff::3\/128", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "vertex-id":3, + "metric":10 + }, + { + "subnet-id":"2001:db8:ffff::4\/128", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0004", + "vertex-id":4, + "metric":10, + "segment-routing":{ + "pref-sid":1400, + "algo":0, + "flags":"0x60" + } + } + ] + } +} diff --git a/tests/topotests/isis_te_topo1/reference/ted_step5.json b/tests/topotests/isis_te_topo1/reference/ted_step5.json new file mode 100644 index 0000000000..ba9bdb01ff --- /dev/null +++ b/tests/topotests/isis_te_topo1/reference/ted_step5.json @@ -0,0 +1,952 @@ +{ + "ted":{ + "name":"ISIS", + "key":1, + "verticesCount":4, + "edgesCount":16, + "subnetsCount":24, + "vertices":[ + { + "vertex-id":1, + "status":"Sync", + "origin":"ISIS_L2", + "name":"r1", + "router-id":"10.0.255.1" + }, + { + "vertex-id":2, + "status":"Sync", + "origin":"ISIS_L2", + "name":"r2", + "router-id":"10.0.255.2" + }, + { + "vertex-id":3, + "status":"Sync", + "origin":"ISIS_L2", + "name":"r3", + "router-id":"10.0.255.3", + "router-id-v6":"2001:db8:1000::3" + }, + { + "vertex-id":4, + "status":"Sync", + "origin":"ISIS_L2", + "name":"r4", + "router-id":"10.0.255.4", + "segment-routing":{ + "srgb-size":10000, + "srgb-lower":10000, + "algorithms":[ + { + "0":"SPF" + } + ], + "srlb-size":1000, + "srlb-lower":5000, + "msd":12 + } + } + ], + "edges":[ + { + "edge-id":1, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "local-vertex-id":1, + "remote-vertex-id":2, + "metric":10, + "edge-attributes":{ + "te-metric":20, + "local-address-v6":"2001:db8::1", + "remote-address-v6":"2001:db8::2", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ], + "delay":10000, + "available-bandwidth":125000000.0 + } + }, + { + "edge-id":2, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "local-vertex-id":2, + "remote-vertex-id":1, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address-v6":"2001:db8::2", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":65537, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "local-vertex-id":1, + "remote-vertex-id":2, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address-v6":"2001:db8:1::1:1", + "remote-address-v6":"2001:db8:1::1:2", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":65538, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "local-vertex-id":2, + "remote-vertex-id":1, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address-v6":"2001:db8:1::1:2", + "remote-address-v6":"2001:db8:1::1:1", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":196610, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "local-vertex-id":2, + "remote-vertex-id":3, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address-v6":"2001:db8:3::3:2", + "remote-address-v6":"2001:db8:3::3:3", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":196611, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "local-vertex-id":3, + "remote-vertex-id":2, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "admin-group":32, + "local-address-v6":"2001:db8:3::3:3", + "remote-address-v6":"2001:db8:3::3:2", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":196612, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0004", + "local-vertex-id":4, + "remote-vertex-id":3, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address-v6":"2001:db8:5::3:4", + "remote-address-v6":"2001:db8:5::4:3", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + }, + "segment-routing":[ + { + "adj-sid":5001, + "flags":"0xb0", + "weight":0 + } + ] + }, + { + "edge-id":262147, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "local-vertex-id":3, + "remote-vertex-id":4, + "metric":10, + "edge-attributes":{ + "te-metric":10, + "local-address-v6":"2001:db8:5::4:3", + "remote-address-v6":"2001:db8:5::3:4", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ], + "delay":50000 + } + }, + { + "edge-id":167772161, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "local-vertex-id":1, + "remote-vertex-id":2, + "metric":10, + "edge-attributes":{ + "te-metric":20, + "local-address":"10.0.0.1", + "remote-address":"10.0.0.2", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ], + "delay":10000, + "available-bandwidth":125000000.0 + } + }, + { + "edge-id":167772162, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "local-vertex-id":2, + "remote-vertex-id":1, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address":"10.0.0.2", + "remote-address":"10.0.0.1", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":167772417, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "local-vertex-id":1, + "remote-vertex-id":2, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address":"10.0.1.1", + "remote-address":"10.0.1.2", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":167772418, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "local-vertex-id":2, + "remote-vertex-id":1, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address":"10.0.1.2", + "remote-address":"10.0.1.1", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":167772930, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "local-vertex-id":2, + "remote-vertex-id":3, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address":"10.0.3.2", + "remote-address":"10.0.3.3", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":167772931, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "local-vertex-id":3, + "remote-vertex-id":2, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "admin-group":32, + "local-address":"10.0.3.3", + "remote-address":"10.0.3.2", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":167773186, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "local-vertex-id":2, + "remote-vertex-id":4, + "metric":10, + "edge-attributes":{ + "te-metric":30, + "local-address":"10.0.4.2", + "remote-address":"10.0.4.4", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ], + "delay":25000, + "utilized-bandwidth":125000000.0 + } + }, + { + "edge-id":167773188, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0004", + "local-vertex-id":4, + "remote-vertex-id":2, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address":"10.0.4.4", + "remote-address":"10.0.4.2", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + }, + "segment-routing":[ + { + "adj-sid":5000, + "flags":"0x30", + "weight":0 + } + ] + } + ], + "subnets":[ + { + "subnet-id":"10.0.0.1\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "vertex-id":1, + "metric":10 + }, + { + "subnet-id":"10.0.0.2\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"10.0.1.1\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "vertex-id":1, + "metric":10 + }, + { + "subnet-id":"10.0.1.2\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"10.0.3.2\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"10.0.3.3\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "vertex-id":3, + "metric":10 + }, + { + "subnet-id":"10.0.4.2\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"10.0.4.4\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0004", + "vertex-id":4, + "metric":10 + }, + { + "subnet-id":"10.0.255.1\/32", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "vertex-id":1, + "metric":10 + }, + { + "subnet-id":"10.0.255.2\/32", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"10.0.255.3\/32", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "vertex-id":3, + "metric":10 + }, + { + "subnet-id":"10.0.255.4\/32", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0004", + "vertex-id":4, + "metric":10, + "segment-routing":{ + "pref-sid":400, + "algo":0, + "flags":"0x60" + } + }, + { + "subnet-id":"2001:db8::1\/64", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "vertex-id":1, + "metric":10 + }, + { + "subnet-id":"2001:db8::2\/64", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"2001:db8:1::1:1\/64", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "vertex-id":1, + "metric":10 + }, + { + "subnet-id":"2001:db8:1::1:2\/64", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"2001:db8:3::3:2\/64", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"2001:db8:3::3:3\/64", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "vertex-id":3, + "metric":10 + }, + { + "subnet-id":"2001:db8:5::3:4\/64", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0004", + "vertex-id":4, + "metric":10 + }, + { + "subnet-id":"2001:db8:5::4:3\/64", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "vertex-id":3, + "metric":10 + }, + { + "subnet-id":"2001:db8:ffff::1\/128", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "vertex-id":1, + "metric":10 + }, + { + "subnet-id":"2001:db8:ffff::2\/128", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"2001:db8:ffff::3\/128", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "vertex-id":3, + "metric":10 + }, + { + "subnet-id":"2001:db8:ffff::4\/128", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0004", + "vertex-id":4, + "metric":10, + "segment-routing":{ + "pref-sid":1400, + "algo":0, + "flags":"0x60" + } + } + ] + } +} diff --git a/tests/topotests/isis_te_topo1/reference/ted_step6.json b/tests/topotests/isis_te_topo1/reference/ted_step6.json new file mode 100644 index 0000000000..83bb27235e --- /dev/null +++ b/tests/topotests/isis_te_topo1/reference/ted_step6.json @@ -0,0 +1,953 @@ +{ + "ted":{ + "name":"ISIS", + "key":1, + "verticesCount":4, + "edgesCount":16, + "subnetsCount":24, + "vertices":[ + { + "vertex-id":1, + "status":"Sync", + "origin":"ISIS_L2", + "name":"r1", + "router-id":"10.0.255.1" + }, + { + "vertex-id":2, + "status":"Sync", + "origin":"ISIS_L2", + "name":"r2", + "router-id":"10.0.255.2" + }, + { + "vertex-id":3, + "status":"Sync", + "origin":"ISIS_L2", + "name":"r3", + "router-id":"10.0.255.3", + "router-id-v6":"2001:db8:1000::3" + }, + { + "vertex-id":4, + "status":"Sync", + "origin":"ISIS_L2", + "name":"r4", + "router-id":"10.0.255.4", + "segment-routing":{ + "srgb-size":10000, + "srgb-lower":10000, + "algorithms":[ + { + "0":"SPF" + } + ], + "srlb-size":1000, + "srlb-lower":5000, + "msd":12 + } + } + ], + "edges":[ + { + "edge-id":1, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "local-vertex-id":1, + "remote-vertex-id":2, + "metric":10, + "edge-attributes":{ + "te-metric":20, + "local-address-v6":"2001:db8::1", + "remote-address-v6":"2001:db8::2", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ], + "delay":10000, + "available-bandwidth":125000000.0 + } + }, + { + "edge-id":2, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "local-vertex-id":2, + "remote-vertex-id":1, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address-v6":"2001:db8::2", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":65537, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "local-vertex-id":1, + "remote-vertex-id":2, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address-v6":"2001:db8:1::1:1", + "remote-address-v6":"2001:db8:1::1:2", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":65538, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "local-vertex-id":2, + "remote-vertex-id":1, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address-v6":"2001:db8:1::1:2", + "remote-address-v6":"2001:db8:1::1:1", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":196610, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "local-vertex-id":2, + "remote-vertex-id":3, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address-v6":"2001:db8:3::3:2", + "remote-address-v6":"2001:db8:3::3:3", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":196611, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "local-vertex-id":3, + "remote-vertex-id":2, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "admin-group":32, + "local-address-v6":"2001:db8:3::3:3", + "remote-address-v6":"2001:db8:3::3:2", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":196612, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0004", + "local-vertex-id":4, + "remote-vertex-id":3, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address-v6":"2001:db8:5::3:4", + "remote-address-v6":"2001:db8:5::4:3", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + }, + "segment-routing":[ + { + "adj-sid":5001, + "flags":"0xb0", + "weight":0 + } + ] + }, + { + "edge-id":262147, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "local-vertex-id":3, + "remote-vertex-id":4, + "metric":10, + "edge-attributes":{ + "te-metric":10, + "local-address-v6":"2001:db8:5::4:3", + "remote-address-v6":"2001:db8:5::3:4", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ], + "delay":50000 + } + }, + { + "edge-id":167772161, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "local-vertex-id":1, + "remote-vertex-id":2, + "metric":10, + "edge-attributes":{ + "te-metric":20, + "local-address":"10.0.0.1", + "remote-address":"10.0.0.2", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ], + "delay":10000, + "available-bandwidth":125000000.0 + } + }, + { + "edge-id":167772162, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "local-vertex-id":2, + "remote-vertex-id":1, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address":"10.0.0.2", + "remote-address":"10.0.0.1", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":167772417, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "local-vertex-id":1, + "remote-vertex-id":2, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address":"10.0.1.1", + "remote-address":"10.0.1.2", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":167772418, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "local-vertex-id":2, + "remote-vertex-id":1, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address":"10.0.1.2", + "remote-address":"10.0.1.1", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":167772930, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "local-vertex-id":2, + "remote-vertex-id":3, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address":"10.0.3.2", + "remote-address":"10.0.3.3", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":167772931, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "local-vertex-id":3, + "remote-vertex-id":2, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "admin-group":32, + "local-address":"10.0.3.3", + "remote-address":"10.0.3.2", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ] + } + }, + { + "edge-id":167773186, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "local-vertex-id":2, + "remote-vertex-id":4, + "metric":10, + "edge-attributes":{ + "te-metric":30, + "local-address":"10.0.4.2", + "remote-address":"10.0.4.4", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ], + "delay":25000 + } + }, + { + "edge-id":167773188, + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0004", + "local-vertex-id":4, + "remote-vertex-id":2, + "metric":10, + "edge-attributes":{ + "te-metric":0, + "local-address":"10.0.4.4", + "remote-address":"10.0.4.2", + "max-link-bandwidth":176258176.0, + "max-resv-link-bandwidth":176258176.0, + "unreserved-bandwidth":[ + { + "class-type-0":176258176.0 + }, + { + "class-type-1":176258176.0 + }, + { + "class-type-2":176258176.0 + }, + { + "class-type-3":176258176.0 + }, + { + "class-type-4":176258176.0 + }, + { + "class-type-5":176258176.0 + }, + { + "class-type-6":176258176.0 + }, + { + "class-type-7":176258176.0 + } + ], + "delay":20000, + "jitter":10000 + }, + "segment-routing":[ + { + "adj-sid":5000, + "flags":"0x30", + "weight":0 + } + ] + } + ], + "subnets":[ + { + "subnet-id":"10.0.0.1\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "vertex-id":1, + "metric":10 + }, + { + "subnet-id":"10.0.0.2\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"10.0.1.1\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "vertex-id":1, + "metric":10 + }, + { + "subnet-id":"10.0.1.2\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"10.0.3.2\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"10.0.3.3\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "vertex-id":3, + "metric":10 + }, + { + "subnet-id":"10.0.4.2\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"10.0.4.4\/24", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0004", + "vertex-id":4, + "metric":10 + }, + { + "subnet-id":"10.0.255.1\/32", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "vertex-id":1, + "metric":10 + }, + { + "subnet-id":"10.0.255.2\/32", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"10.0.255.3\/32", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "vertex-id":3, + "metric":10 + }, + { + "subnet-id":"10.0.255.4\/32", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0004", + "vertex-id":4, + "metric":10, + "segment-routing":{ + "pref-sid":400, + "algo":0, + "flags":"0x60" + } + }, + { + "subnet-id":"2001:db8::1\/64", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "vertex-id":1, + "metric":10 + }, + { + "subnet-id":"2001:db8::2\/64", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"2001:db8:1::1:1\/64", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "vertex-id":1, + "metric":10 + }, + { + "subnet-id":"2001:db8:1::1:2\/64", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"2001:db8:3::3:2\/64", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"2001:db8:3::3:3\/64", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "vertex-id":3, + "metric":10 + }, + { + "subnet-id":"2001:db8:5::3:4\/64", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0004", + "vertex-id":4, + "metric":10 + }, + { + "subnet-id":"2001:db8:5::4:3\/64", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "vertex-id":3, + "metric":10 + }, + { + "subnet-id":"2001:db8:ffff::1\/128", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0001", + "vertex-id":1, + "metric":10 + }, + { + "subnet-id":"2001:db8:ffff::2\/128", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0002", + "vertex-id":2, + "metric":10 + }, + { + "subnet-id":"2001:db8:ffff::3\/128", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0003", + "vertex-id":3, + "metric":10 + }, + { + "subnet-id":"2001:db8:ffff::4\/128", + "status":"Sync", + "origin":"ISIS_L2", + "advertised-router":"0000.0000.0004", + "vertex-id":4, + "metric":10, + "segment-routing":{ + "pref-sid":1400, + "algo":0, + "flags":"0x60" + } + } + ] + } +} diff --git a/tests/topotests/isis_te_topo1/test_isis_te_topo1.py b/tests/topotests/isis_te_topo1/test_isis_te_topo1.py new file mode 100644 index 0000000000..0e453d30e3 --- /dev/null +++ b/tests/topotests/isis_te_topo1/test_isis_te_topo1.py @@ -0,0 +1,265 @@ +#!/usr/bin/env python + +# +# test_isis_te_topo1.py +# Part of NetDEF Topology Tests +# +# Copyright (c) 2021 by Orange +# Author: Olivier Dugeon +# +# Permission to use, copy, modify, and/or distribute this software +# for any purpose with or without fee is hereby granted, provided +# that the above copyright notice and this permission notice appear +# in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS +# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +# OF THIS SOFTWARE. +# + +""" +test_isis_te_topo1.py: Test the FRR IS-IS with Traffic Engineering. + + +------------+ + | | + | R1 | + | 10.0.225.1 | + | | + +------------+ + r1-eth0| |r1-eth1 + | | + 10.0.0.0/24| |10.0.1.0/24 + | |2001:db8:1:/64 + | | + r2-eth0| |r2-eth1 + +------------+ +------------+ + | | | | + | R2 |r2-eth2 r3-eth0| R3 | + | 10.0.255.2 +------------------+ 10.0.255.3 | + | | 10.0.3.0/24 | | + +------------+ 2001:db8:3:/64 +------+-----+ + r2-eth3| r3-eth1| + | | + 10.0.4.0/24| | + | | + | | + r4-eth0| 2001:db8:5:/64| + +------------+ | + | | | + | R4 |r4-eth1 | + | 10.0.255.4 +-------------------------+ + | | + +------------+ + +""" + +import os +import sys +import json +from functools import partial + +# Save the Current Working Directory to find configuration files. +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# pylint: disable=C0413 + +# Import topogen and topotest helpers +from lib import topotest +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topolog import logger + +# and Finally pytest +import pytest + +pytestmark = [pytest.mark.isisd] + + +def build_topo(tgen): + "Build function" + + # Create 4 routers + for routern in range(1, 5): + tgen.add_router("r{}".format(routern)) + + # Interconect router 1 and 2 with 2 links + switch = tgen.add_switch("s1") + switch.add_link(tgen.gears["r1"]) + switch.add_link(tgen.gears["r2"]) + switch = tgen.add_switch("s2") + switch.add_link(tgen.gears["r1"]) + switch.add_link(tgen.gears["r2"]) + + # Interconect router 3 and 2 + switch = tgen.add_switch("s3") + switch.add_link(tgen.gears["r3"]) + switch.add_link(tgen.gears["r2"]) + + # Interconect router 4 and 2 + switch = tgen.add_switch("s4") + switch.add_link(tgen.gears["r4"]) + switch.add_link(tgen.gears["r2"]) + + # Interconnect router 3 and 4 + switch = tgen.add_switch("s5") + switch.add_link(tgen.gears["r3"]) + switch.add_link(tgen.gears["r4"]) + + +def setup_module(mod): + "Sets up the pytest environment" + + logger.info("\n\n---- Starting IS-IS TE tests ----\n") + + tgen = Topogen(build_topo, mod.__name__) + tgen.start_topology() + + router_list = tgen.routers() + + for rname, router in router_list.items(): + router.load_config( + TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname)) + ) + router.load_config( + TopoRouter.RD_ISIS, os.path.join(CWD, "{}/isisd.conf".format(rname)) + ) + + # Initialize all routers. + tgen.start_router() + + +def teardown_module(): + "Teardown the pytest environment" + + tgen = get_topogen() + tgen.stop_topology() + + logger.info("\n\n---- IS-IS TE tests End ----\n") + + +def compare_ted_json_output(tgen, rname, fileref): + "Compare TED JSON output" + + logger.info('Comparing router "%s" TED output', rname) + + filename = "{}/reference/{}".format(CWD, fileref) + expected = json.loads(open(filename).read()) + command = "show isis mpls-te database json" + + # Run test function until we get an result. Wait at most 60 seconds. + test_func = partial(topotest.router_json_cmp, tgen.gears[rname], command, expected) + _, diff = topotest.run_and_expect(test_func, None, count=60, wait=2) + assertmsg = '"{}" TED JSON output mismatches the expected result'.format(rname) + assert diff is None, assertmsg + + +def setup_testcase(msg): + "Setup test case" + + logger.info(msg) + tgen = get_topogen() + + # Skip if previous fatal error condition is raised + if tgen.routers_have_failure(): + pytest.skip(tgen.errors) + + return tgen + + +# Note that all routers must discover the same Network Topology, so the same TED. + + +def test_step1(): + "Step1: Check initial topology" + + tgen = setup_testcase("Step1: test initial IS-IS TE Data Base") + + for rname in ["r1", "r2", "r3", "r4"]: + compare_ted_json_output(tgen, rname, "ted_step1.json") + + +def test_step2(): + "Step2: Shutdown interface between r1 and r2 and verify that \ + corresponding Edges are removed from the TED on all routers " + + tgen = setup_testcase("Step2: Shutdown interface between r1 & r2") + + tgen.net["r1"].cmd('vtysh -c "conf t" -c "interface r1-eth1" -c "shutdown"') + tgen.net["r2"].cmd('vtysh -c "conf t" -c "interface r2-eth1" -c "shutdown"') + + for rname in ["r1", "r2", "r3", "r4"]: + compare_ted_json_output(tgen, rname, "ted_step2.json") + + +def test_step3(): + "Step3: Enable IPv6 address between r1 and r2 and verify that \ + corresponding Edges are added in the TED on all routers" + + tgen = setup_testcase("Step3: Add IPv6 on r1 and r2 interfaces") + + tgen.net["r1"].cmd('vtysh -c "conf t" -c "interface r1-eth0" -c "ipv6 address 2001:db8:0::1/64"') + tgen.net["r1"].cmd('vtysh -c "conf t" -c "interface r1-eth0" -c "ipv6 router isis TE"') + tgen.net["r2"].cmd('vtysh -c "conf t" -c "interface r2-eth0" -c "ipv6 address 2001:db8:0::2/64"') + tgen.net["r2"].cmd('vtysh -c "conf t" -c "interface r2-eth0" -c "ipv6 router isis TE"') + for rname in ["r1", "r2", "r3", "r4"]: + compare_ted_json_output(tgen, rname, "ted_step3.json") + + +def test_step4(): + "Step4: Modify Segment Routing Prefix SID advertisement on Router r4" + + tgen = setup_testcase("Step4: Modify Prefix SID on router r4") + + tgen.net["r4"].cmd('vtysh -c "conf t" -c "router isis TE" -c "segment-routing prefix 10.0.255.4/32 index 40"') + tgen.net["r4"].cmd('vtysh -c "conf t" -c "router isis TE" -c "segment-routing prefix 2001:db8:ffff::4/128 index 1040"') + + for rname in ["r1", "r2", "r3", "r4"]: + compare_ted_json_output(tgen, rname, "ted_step4.json") + + +def test_step5(): + "Step5: Re-enable interface between r1 & r2 and verify that corresponding \ + Edges are added in the TED on all routers" + + tgen = setup_testcase("Step5: Re-enable interface between r1 & r2") + + tgen.net["r1"].cmd('vtysh -c "conf t" -c "interface r1-eth1" -c "no shutdown"') + tgen.net["r2"].cmd('vtysh -c "conf t" -c "interface r2-eth1" -c "no shutdown"') + + for rname in ["r1", "r2", "r3", "r4"]: + compare_ted_json_output(tgen, rname, "ted_step5.json") + + +def test_step6(): + "Step6: Set delay and jitter for interface r4-eth0 on r4, remove use-bw \ + for interface r2-eth3 on r2 and verify that corresponding Edges are \ + updated in the TED on all routers" + + tgen = setup_testcase("Step6: Modify link parameters on r2 & r4") + + tgen.net["r2"].cmd('vtysh -c "conf t" -c "interface r2-eth3" -c "link-params" -c "no use-bw"') + tgen.net["r4"].cmd('vtysh -c "conf t" -c "interface r4-eth0" -c "link-params" -c "delay 20000"') + tgen.net["r4"].cmd('vtysh -c "conf t" -c "interface r4-eth0" -c "link-params" -c "delay-variation 10000"') + + for rname in ["r1", "r2", "r3", "r4"]: + compare_ted_json_output(tgen, rname, "ted_step6.json") + + +def test_memory_leak(): + "Run the memory leak test and report results." + + tgen = get_topogen() + if not tgen.is_memleak_enabled(): + pytest.skip("Memory leak test/report is disabled") + + tgen.report_memory_leaks() + + +if __name__ == "__main__": + args = ["-s"] + sys.argv[1:] + sys.exit(pytest.main(args)) diff --git a/yang/frr-isisd.yang b/yang/frr-isisd.yang index 5997e8866a..defb2b2038 100644 --- a/yang/frr-isisd.yang +++ b/yang/frr-isisd.yang @@ -1481,6 +1481,17 @@ module frr-isisd { description "Stable IP address of the advertising router."; } + leaf router-address-v6 { + type inet:ipv6-address; + description + "Stable IPv6 address of the advertising router."; + } + leaf export { + type boolean; + default "false"; + description + "Export Link State informatin."; + } } container segment-routing {