From c3f7b406b1196374abbc19658fc295ae6dc3fcfb Mon Sep 17 00:00:00 2001 From: Olivier Dugeon Date: Mon, 4 May 2020 18:26:21 +0200 Subject: [PATCH] isisd: IS-IS-SR preparation for master 4/5 * Regroup fonctions to install label for Prefix and Adjacency SID * Change 'replace_semantics' variable name by 'make_before_break' in sr_prefix_reinstall() function and adjust comments * Call directly lsp_regenerate_schedule() from isis_nb_config.c when MSD is updated Signed-off-by: Olivier Dugeon --- isisd/isis_nb_config.c | 8 +++-- isisd/isis_sr.c | 67 ++++++++++++------------------------------ isisd/isis_sr.h | 1 - isisd/isis_zebra.c | 57 +++++++++++++++++++++++++++++++++-- isisd/isis_zebra.h | 5 ++-- 5 files changed, 83 insertions(+), 55 deletions(-) diff --git a/isisd/isis_nb_config.c b/isisd/isis_nb_config.c index ec3b7baa31..a649e896fa 100644 --- a/isisd/isis_nb_config.c +++ b/isisd/isis_nb_config.c @@ -1521,7 +1521,9 @@ int isis_instance_segment_routing_msd_node_msd_modify( area = nb_running_get_entry(args->dnode, NULL, true); area->srdb.config.msd = yang_dnode_get_uint8(args->dnode, NULL); - isis_sr_cfg_msd_update(area); + + /* Update and regenerate LSP */ + lsp_regenerate_schedule(area, area->is_type, 0); return NB_OK; } @@ -1536,7 +1538,9 @@ int isis_instance_segment_routing_msd_node_msd_destroy( area = nb_running_get_entry(args->dnode, NULL, true); area->srdb.config.msd = 0; - isis_sr_cfg_msd_update(area); + + /* Update and regenerate LSP */ + lsp_regenerate_schedule(area, area->is_type, 0); return NB_OK; } diff --git a/isisd/isis_sr.c b/isisd/isis_sr.c index 948b8e39c8..fc97c0fc98 100644 --- a/isisd/isis_sr.c +++ b/isisd/isis_sr.c @@ -51,8 +51,7 @@ DEFINE_MTYPE_STATIC(ISISD, ISIS_SR_INFO, "ISIS segment routing information") static void sr_prefix_uninstall(struct sr_prefix *srp); -static void sr_prefix_reinstall(struct sr_prefix *srp, - bool replace_semantics); +static void sr_prefix_reinstall(struct sr_prefix *srp, bool make_before_break); /*----------------------------------------------------------------------------*/ @@ -138,12 +137,6 @@ int isis_sr_cfg_srgb_update(struct isis_area *area, uint32_t lower_bound, return 0; } -/* Handle changes in the local MSD configuration. */ -void isis_sr_cfg_msd_update(struct isis_area *area) -{ - lsp_regenerate_schedule(area, area->is_type, 0); -} - /* Handle new Prefix-SID configuration. */ struct sr_prefix_cfg *isis_sr_cfg_prefix_add(struct isis_area *area, const struct prefix *prefix) @@ -368,8 +361,10 @@ static void sr_node_srgb_update(struct isis_area *area, int level, continue; /* - * Reinstall all Prefix-SID nexthops using route replace - * semantics. + * The Prefix-SID input label hasn't changed. We could + * re-install all Prefix-SID with "Make Before Break" + * option. Zebra layer will update output label(s) by + * adding new entry before removing the old one(s). */ sr_prefix_reinstall(srp, true); break; @@ -506,7 +501,7 @@ static int sr_prefix_install_local(struct sr_prefix *srp) isis_sr_nexthop_update(&srp->u.local.info, MPLS_LABEL_IMPLICIT_NULL); /* Install Prefix-SID in the forwarding plane. */ - isis_zebra_install_prefix_sid(srp); + isis_zebra_send_prefix_sid(ZEBRA_MPLS_LABELS_REPLACE, srp); return 0; } @@ -587,7 +582,7 @@ static int sr_prefix_install_remote(struct sr_prefix *srp) srp->input_label = input_label; /* Install Prefix-SID in the forwarding plane. */ - isis_zebra_install_prefix_sid(srp); + isis_zebra_send_prefix_sid(ZEBRA_MPLS_LABELS_REPLACE, srp); return 0; } @@ -647,7 +642,7 @@ static void sr_prefix_uninstall(struct sr_prefix *srp) srp->sid.value); /* Uninstall Prefix-SID from the forwarding plane. */ - isis_zebra_uninstall_prefix_sid(srp); + isis_zebra_send_prefix_sid(ZEBRA_MPLS_LABELS_DELETE, srp); /* Reset internal state. */ srp->input_label = MPLS_INVALID_LABEL; @@ -666,15 +661,16 @@ static void sr_prefix_uninstall(struct sr_prefix *srp) } /* Reinstall local or remote Prefix-SID. */ -static void sr_prefix_reinstall(struct sr_prefix *srp, bool replace_semantics) +static inline void sr_prefix_reinstall(struct sr_prefix *srp, + bool make_before_break) { /* - * Route replace semantics can be used only when we know for sure that + * Make Before Break can be used only when we know for sure that * the Prefix-SID input label hasn't changed. Otherwise we need to * uninstall the Prefix-SID first using the old input label before * reinstalling it. */ - if (!replace_semantics) + if (!make_before_break) sr_prefix_uninstall(srp); sr_prefix_install(srp); @@ -960,6 +956,11 @@ static int sr_route_update(struct isis_area *area, struct prefix *prefix, return 0; if (CHECK_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ACTIVE)) { + /* + * The Prefix-SID input label hasn't changed. We could use the + * "Make Before Break" option. Zebra layer will update output + * label by adding new label(s) before removing old one(s). + */ sr_prefix_reinstall(srp, true); srp->u.remote.rinfo = route_info; } else { @@ -972,36 +973,6 @@ static int sr_route_update(struct isis_area *area, struct prefix *prefix, /*----------------------------------------------------------------------------*/ -/* Install or uninstall (LAN)-Adj-SID. */ -static void sr_adj_sid_install_uninstall(bool install, - const struct sr_adjacency *sra) -{ - struct zapi_labels zl; - struct zapi_nexthop *znh; - int cmd; - - cmd = install ? ZEBRA_MPLS_LABELS_ADD : ZEBRA_MPLS_LABELS_DELETE; - - sr_debug(" |- %s label %u for interface %s", - install ? "Add" : "Delete", sra->nexthop.label, - sra->adj->circuit->interface->name); - - memset(&zl, 0, sizeof(zl)); - zl.type = ZEBRA_LSP_ISIS_SR; - zl.local_label = sra->nexthop.label; - zl.nexthop_num = 1; - znh = &zl.nexthops[0]; - znh->gate = sra->nexthop.address; - znh->type = (sra->nexthop.family == AF_INET) - ? NEXTHOP_TYPE_IPV4_IFINDEX - : NEXTHOP_TYPE_IPV6_IFINDEX; - znh->ifindex = sra->adj->circuit->interface->ifindex; - znh->label_num = 1; - znh->labels[0] = MPLS_LABEL_IMPLICIT_NULL; - - (void)zebra_send_mpls_labels(zclient, cmd, &zl); -} - /* Add new local Adj-SID. */ static void sr_adj_sid_add_single(struct isis_adjacency *adj, int family, bool backup) @@ -1082,7 +1053,7 @@ static void sr_adj_sid_add_single(struct isis_adjacency *adj, int family, listnode_add(area->srdb.adj_sids, sra); listnode_add(adj->adj_sids, sra); - sr_adj_sid_install_uninstall(true, sra); + isis_zebra_send_adjacency_sid(ZEBRA_MPLS_LABELS_ADD, sra); } static void sr_adj_sid_add(struct isis_adjacency *adj, int family) @@ -1099,7 +1070,7 @@ static void sr_adj_sid_del(struct sr_adjacency *sra) sr_debug("ISIS-Sr (%s): Delete Adjacency SID", area->area_tag); - sr_adj_sid_install_uninstall(false, sra); + isis_zebra_send_adjacency_sid(ZEBRA_MPLS_LABELS_DELETE, sra); switch (circuit->circ_type) { case CIRCUIT_T_BROADCAST: diff --git a/isisd/isis_sr.h b/isisd/isis_sr.h index 0b84db90ff..b2e0130754 100644 --- a/isisd/isis_sr.h +++ b/isisd/isis_sr.h @@ -240,7 +240,6 @@ struct isis_sr_db { /* Prototypes. */ extern int isis_sr_cfg_srgb_update(struct isis_area *area, uint32_t lower_bound, uint32_t upper_bound); -extern void isis_sr_cfg_msd_update(struct isis_area *area); extern struct sr_prefix_cfg * isis_sr_cfg_prefix_add(struct isis_area *area, const struct prefix *prefix); extern void isis_sr_cfg_prefix_del(struct sr_prefix_cfg *pcfg); diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c index 94ad0ae488..68f80a3f1f 100644 --- a/isisd/isis_zebra.c +++ b/isisd/isis_zebra.c @@ -49,6 +49,7 @@ #include "isisd/isis_lsp.h" #include "isisd/isis_route.h" #include "isisd/isis_zebra.h" +#include "isisd/isis_adjacency.h" #include "isisd/isis_te.h" #include "isisd/isis_sr.h" @@ -254,7 +255,7 @@ void isis_zebra_route_del_route(struct prefix *prefix, } /* Install Prefix-SID in the forwarding plane. */ -void isis_zebra_install_prefix_sid(const struct sr_prefix *srp) +static void isis_zebra_prefix_install_prefix_sid(const struct sr_prefix *srp) { struct zapi_labels zl; struct zapi_nexthop *znh; @@ -315,7 +316,7 @@ void isis_zebra_install_prefix_sid(const struct sr_prefix *srp) } /* Uninstall Prefix-SID from the forwarding plane. */ -void isis_zebra_uninstall_prefix_sid(const struct sr_prefix *srp) +static void isis_zebra_uninstall_prefix_sid(const struct sr_prefix *srp) { struct zapi_labels zl; @@ -336,6 +337,58 @@ void isis_zebra_uninstall_prefix_sid(const struct sr_prefix *srp) (void)zebra_send_mpls_labels(zclient, ZEBRA_MPLS_LABELS_DELETE, &zl); } +void isis_zebra_send_prefix_sid(int cmd, const struct sr_prefix *srp) +{ + + if (cmd != ZEBRA_MPLS_LABELS_REPLACE + && cmd != ZEBRA_MPLS_LABELS_DELETE) { + flog_warn(EC_LIB_DEVELOPMENT, "%s: wrong ZEBRA command", + __func__); + return; + } + + sr_debug(" |- %s label %u for prefix %pFX", + cmd == ZEBRA_MPLS_LABELS_REPLACE ? "Update" : "Delete", + srp->input_label, &srp->prefix); + + if (cmd == ZEBRA_MPLS_LABELS_REPLACE) + isis_zebra_prefix_install_prefix_sid(srp); + else + isis_zebra_uninstall_prefix_sid(srp); +} + +/* Install or uninstall (LAN)-Adj-SID. */ +void isis_zebra_send_adjacency_sid(int cmd, const struct sr_adjacency *sra) +{ + struct zapi_labels zl; + struct zapi_nexthop *znh; + + if (cmd != ZEBRA_MPLS_LABELS_ADD && cmd != ZEBRA_MPLS_LABELS_DELETE) { + flog_warn(EC_LIB_DEVELOPMENT, "%s: wrong ZEBRA command", + __func__); + return; + } + + sr_debug(" |- %s label %u for interface %s", + cmd == ZEBRA_MPLS_LABELS_ADD ? "Add" : "Delete", + sra->nexthop.label, sra->adj->circuit->interface->name); + + memset(&zl, 0, sizeof(zl)); + zl.type = ZEBRA_LSP_ISIS_SR; + zl.local_label = sra->nexthop.label; + zl.nexthop_num = 1; + znh = &zl.nexthops[0]; + znh->gate = sra->nexthop.address; + znh->type = (sra->nexthop.family == AF_INET) + ? NEXTHOP_TYPE_IPV4_IFINDEX + : NEXTHOP_TYPE_IPV6_IFINDEX; + znh->ifindex = sra->adj->circuit->interface->ifindex; + znh->label_num = 1; + znh->labels[0] = MPLS_LABEL_IMPLICIT_NULL; + + (void)zebra_send_mpls_labels(zclient, cmd, &zl); +} + static int isis_zebra_read(ZAPI_CALLBACK_ARGS) { struct zapi_route api; diff --git a/isisd/isis_zebra.h b/isisd/isis_zebra.h index cca2b08811..b143d34626 100644 --- a/isisd/isis_zebra.h +++ b/isisd/isis_zebra.h @@ -36,6 +36,7 @@ void isis_zebra_stop(void); struct isis_route_info; struct sr_prefix; +struct sr_adjacency; void isis_zebra_route_add_route(struct prefix *prefix, struct prefix_ipv6 *src_p, @@ -43,8 +44,8 @@ void isis_zebra_route_add_route(struct prefix *prefix, void isis_zebra_route_del_route(struct prefix *prefix, struct prefix_ipv6 *src_p, struct isis_route_info *route_info); -void isis_zebra_install_prefix_sid(const struct sr_prefix *srp); -void isis_zebra_uninstall_prefix_sid(const struct sr_prefix *srp); +void isis_zebra_send_prefix_sid(int cmd, const struct sr_prefix *srp); +void isis_zebra_send_adjacency_sid(int cmd, const struct sr_adjacency *sra); int isis_distribute_list_update(int routetype); void isis_zebra_redistribute_set(afi_t afi, int type); void isis_zebra_redistribute_unset(afi_t afi, int type); -- 2.39.5