From e280279d5ac6fff4aa5583af0ecf97e5bc2767ad Mon Sep 17 00:00:00 2001 From: Rafael Zalamena Date: Mon, 28 Nov 2022 15:26:06 -0300 Subject: [PATCH] lib,staticd: BFD integration CLI commands Implement the static route monitoring feature with BFD integration. Signed-off-by: Rafael Zalamena --- lib/command.h | 7 ++ staticd/static_vty.c | 185 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 182 insertions(+), 10 deletions(-) diff --git a/lib/command.h b/lib/command.h index 0f9715e81c..5cc40f71f6 100644 --- a/lib/command.h +++ b/lib/command.h @@ -497,6 +497,13 @@ struct cmd_node { #define ROLE_STR \ "Providing transit\nRoute server\nRS client\nUsing transit\nPublic/private peering\n" +/* BFD protocol integration strings. */ +#define BFD_INTEGRATION_STR "BFD monitoring\n" +#define BFD_INTEGRATION_MULTI_HOP_STR "Use BFD multi hop session\n" +#define BFD_INTEGRATION_SOURCE_STR "Use source for BFD session\n" +#define BFD_INTEGRATION_SOURCEV4_STR "Use IPv4 source for BFD session\n" +#define BFD_INTEGRATION_SOURCEV6_STR "Use IPv4 source for BFD session\n" + /* Prototypes. */ extern void install_node(struct cmd_node *node); extern void install_default(enum node_type); diff --git a/staticd/static_vty.c b/staticd/static_vty.c index efae3c53da..0d4a91f347 100644 --- a/staticd/static_vty.c +++ b/staticd/static_vty.c @@ -65,6 +65,11 @@ struct static_route_args { const char *label; const char *table; const char *color; + + bool bfd; + bool bfd_multi_hop; + const char *bfd_source; + const char *bfd_profile; }; static int static_route_nb_run(struct vty *vty, struct static_route_args *args) @@ -138,6 +143,11 @@ static int static_route_nb_run(struct vty *vty, struct static_route_args *args) apply_mask(&p); prefix2str(&p, buf_prefix, sizeof(buf_prefix)); + if (args->bfd && args->gateway == NULL) { + vty_out(vty, "%% Route monitoring requires a gateway\n"); + return CMD_WARNING_CONFIG_FAILED; + } + if (args->source) prefix2str(&src, buf_src_prefix, sizeof(buf_src_prefix)); if (args->gateway) @@ -332,6 +342,41 @@ static int static_route_nb_run(struct vty *vty, struct static_route_args *args) nb_cli_enqueue_change(vty, xpath_mpls, NB_OP_DESTROY, NULL); } + + if (args->bfd) { + char xpath_bfd[XPATH_MAXLEN]; + + if (args->bfd_source) { + strlcpy(xpath_bfd, xpath_nexthop, + sizeof(xpath_bfd)); + strlcat(xpath_bfd, + "/frr-staticd:bfd-monitoring/source", + sizeof(xpath_bfd)); + nb_cli_enqueue_change(vty, xpath_bfd, + NB_OP_MODIFY, + args->bfd_source); + } + + strlcpy(xpath_bfd, xpath_nexthop, sizeof(xpath_bfd)); + strlcat(xpath_bfd, + "/frr-staticd:bfd-monitoring/multi-hop", + sizeof(xpath_bfd)); + nb_cli_enqueue_change(vty, xpath_bfd, NB_OP_MODIFY, + args->bfd_multi_hop ? "true" + : "false"); + + if (args->bfd_profile) { + strlcpy(xpath_bfd, xpath_nexthop, + sizeof(xpath_bfd)); + strlcat(xpath_bfd, + "/frr-staticd:bfd-monitoring/profile", + sizeof(xpath_bfd)); + nb_cli_enqueue_change(vty, xpath_bfd, + NB_OP_MODIFY, + args->bfd_profile); + } + } + ret = nb_cli_apply_changes(vty, xpath_prefix); } else { if (args->source) @@ -375,14 +420,23 @@ static int static_route_nb_run(struct vty *vty, struct static_route_args *args) /* Static unicast routes for multicast RPF lookup. */ DEFPY_YANG (ip_mroute_dist, ip_mroute_dist_cmd, - "[no] ip mroute A.B.C.D/M$prefix [(1-255)$distance]", + "[no] ip mroute A.B.C.D/M$prefix [{" + "(1-255)$distance" + "|bfd$bfd [{multi-hop$bfd_multi_hop|source A.B.C.D$bfd_source|profile BFDPROF$bfd_profile}]" + "}]", NO_STR IP_STR "Configure static unicast route into MRIB for multicast RPF lookup\n" "IP destination prefix (e.g. 10.0.0.0/8)\n" "Nexthop address\n" "Nexthop interface name\n" - "Distance\n") + "Distance\n" + BFD_INTEGRATION_STR + BFD_INTEGRATION_MULTI_HOP_STR + BFD_INTEGRATION_SOURCE_STR + BFD_INTEGRATION_SOURCEV4_STR + BFD_PROFILE_STR + BFD_PROFILE_NAME_STR) { struct static_route_args args = { .delete = !!no, @@ -392,6 +446,10 @@ DEFPY_YANG (ip_mroute_dist, .gateway = gate_str, .interface_name = ifname, .distance = distance_str, + .bfd = !!bfd, + .bfd_multi_hop = !!bfd_multi_hop, + .bfd_source = bfd_source_str, + .bfd_profile = bfd_profile, }; return static_route_nb_run(vty, &args); @@ -506,6 +564,7 @@ DEFPY_YANG(ip_route_address_interface, |nexthop-vrf NAME \ |onlink$onlink \ |color (1-4294967295) \ + |bfd$bfd [{multi-hop$bfd_multi_hop|source A.B.C.D$bfd_source|profile BFDPROF$bfd_profile}] \ }]", NO_STR IP_STR "Establish static routes\n" @@ -525,7 +584,13 @@ DEFPY_YANG(ip_route_address_interface, VRF_CMD_HELP_STR "Treat the nexthop as directly attached to the interface\n" "SR-TE color\n" - "The SR-TE color to configure\n") + "The SR-TE color to configure\n" + BFD_INTEGRATION_STR + BFD_INTEGRATION_MULTI_HOP_STR + BFD_INTEGRATION_SOURCE_STR + BFD_INTEGRATION_SOURCEV4_STR + BFD_PROFILE_STR + BFD_PROFILE_NAME_STR) { struct static_route_args args = { .delete = !!no, @@ -543,6 +608,10 @@ DEFPY_YANG(ip_route_address_interface, .onlink = !!onlink, .vrf = vrf, .nexthop_vrf = nexthop_vrf, + .bfd = !!bfd, + .bfd_multi_hop = !!bfd_multi_hop, + .bfd_source = bfd_source_str, + .bfd_profile = bfd_profile, }; return static_route_nb_run(vty, &args); @@ -562,6 +631,7 @@ DEFPY_YANG(ip_route_address_interface_vrf, |nexthop-vrf NAME \ |onlink$onlink \ |color (1-4294967295) \ + |bfd$bfd [{multi-hop$bfd_multi_hop|source A.B.C.D$bfd_source|profile BFDPROF$bfd_profile}] \ }]", NO_STR IP_STR "Establish static routes\n" @@ -580,7 +650,13 @@ DEFPY_YANG(ip_route_address_interface_vrf, VRF_CMD_HELP_STR "Treat the nexthop as directly attached to the interface\n" "SR-TE color\n" - "The SR-TE color to configure\n") + "The SR-TE color to configure\n" + BFD_INTEGRATION_STR + BFD_INTEGRATION_MULTI_HOP_STR + BFD_INTEGRATION_SOURCE_STR + BFD_INTEGRATION_SOURCEV4_STR + BFD_PROFILE_STR + BFD_PROFILE_NAME_STR) { struct static_route_args args = { .delete = !!no, @@ -598,6 +674,10 @@ DEFPY_YANG(ip_route_address_interface_vrf, .onlink = !!onlink, .xpath_vrf = true, .nexthop_vrf = nexthop_vrf, + .bfd = !!bfd, + .bfd_multi_hop = !!bfd_multi_hop, + .bfd_source = bfd_source_str, + .bfd_profile = bfd_profile, }; return static_route_nb_run(vty, &args); @@ -616,6 +696,7 @@ DEFPY_YANG(ip_route, |table (1-4294967295) \ |nexthop-vrf NAME \ |color (1-4294967295) \ + |bfd$bfd [{multi-hop$bfd_multi_hop|source A.B.C.D$bfd_source|profile BFDPROF$bfd_profile}] \ }]", NO_STR IP_STR "Establish static routes\n" @@ -634,7 +715,13 @@ DEFPY_YANG(ip_route, "The table number to configure\n" VRF_CMD_HELP_STR "SR-TE color\n" - "The SR-TE color to configure\n") + "The SR-TE color to configure\n" + BFD_INTEGRATION_STR + BFD_INTEGRATION_MULTI_HOP_STR + BFD_INTEGRATION_SOURCE_STR + BFD_INTEGRATION_SOURCEV4_STR + BFD_PROFILE_STR + BFD_PROFILE_NAME_STR) { struct static_route_args args = { .delete = !!no, @@ -651,6 +738,10 @@ DEFPY_YANG(ip_route, .color = color_str, .vrf = vrf, .nexthop_vrf = nexthop_vrf, + .bfd = !!bfd, + .bfd_multi_hop = !!bfd_multi_hop, + .bfd_source = bfd_source_str, + .bfd_profile = bfd_profile, }; return static_route_nb_run(vty, &args); @@ -668,6 +759,7 @@ DEFPY_YANG(ip_route_vrf, |table (1-4294967295) \ |nexthop-vrf NAME \ |color (1-4294967295) \ + |bfd$bfd [{multi-hop$bfd_multi_hop|source A.B.C.D$bfd_source|profile BFDPROF$bfd_profile}] \ }]", NO_STR IP_STR "Establish static routes\n" @@ -685,7 +777,13 @@ DEFPY_YANG(ip_route_vrf, "The table number to configure\n" VRF_CMD_HELP_STR "SR-TE color\n" - "The SR-TE color to configure\n") + "The SR-TE color to configure\n" + BFD_INTEGRATION_STR + BFD_INTEGRATION_MULTI_HOP_STR + BFD_INTEGRATION_SOURCE_STR + BFD_INTEGRATION_SOURCEV4_STR + BFD_PROFILE_STR + BFD_PROFILE_NAME_STR) { struct static_route_args args = { .delete = !!no, @@ -702,6 +800,10 @@ DEFPY_YANG(ip_route_vrf, .color = color_str, .xpath_vrf = true, .nexthop_vrf = nexthop_vrf, + .bfd = !!bfd, + .bfd_multi_hop = !!bfd_multi_hop, + .bfd_source = bfd_source_str, + .bfd_profile = bfd_profile, }; return static_route_nb_run(vty, &args); @@ -814,6 +916,7 @@ DEFPY_YANG(ipv6_route_address_interface, |nexthop-vrf NAME \ |onlink$onlink \ |color (1-4294967295) \ + |bfd$bfd [{multi-hop$bfd_multi_hop|source X:X::X:X$bfd_source|profile BFDPROF$bfd_profile}] \ }]", NO_STR IPV6_STR @@ -834,7 +937,13 @@ DEFPY_YANG(ipv6_route_address_interface, VRF_CMD_HELP_STR "Treat the nexthop as directly attached to the interface\n" "SR-TE color\n" - "The SR-TE color to configure\n") + "The SR-TE color to configure\n" + BFD_INTEGRATION_STR + BFD_INTEGRATION_MULTI_HOP_STR + BFD_INTEGRATION_SOURCE_STR + BFD_INTEGRATION_SOURCEV4_STR + BFD_PROFILE_STR + BFD_PROFILE_NAME_STR) { struct static_route_args args = { .delete = !!no, @@ -852,6 +961,10 @@ DEFPY_YANG(ipv6_route_address_interface, .onlink = !!onlink, .vrf = vrf, .nexthop_vrf = nexthop_vrf, + .bfd = !!bfd, + .bfd_multi_hop = !!bfd_multi_hop, + .bfd_source = bfd_source_str, + .bfd_profile = bfd_profile, }; return static_route_nb_run(vty, &args); @@ -870,6 +983,7 @@ DEFPY_YANG(ipv6_route_address_interface_vrf, |nexthop-vrf NAME \ |onlink$onlink \ |color (1-4294967295) \ + |bfd$bfd [{multi-hop$bfd_multi_hop|source X:X::X:X$bfd_source|profile BFDPROF$bfd_profile}] \ }]", NO_STR IPV6_STR @@ -889,7 +1003,13 @@ DEFPY_YANG(ipv6_route_address_interface_vrf, VRF_CMD_HELP_STR "Treat the nexthop as directly attached to the interface\n" "SR-TE color\n" - "The SR-TE color to configure\n") + "The SR-TE color to configure\n" + BFD_INTEGRATION_STR + BFD_INTEGRATION_MULTI_HOP_STR + BFD_INTEGRATION_SOURCE_STR + BFD_INTEGRATION_SOURCEV4_STR + BFD_PROFILE_STR + BFD_PROFILE_NAME_STR) { struct static_route_args args = { .delete = !!no, @@ -907,6 +1027,10 @@ DEFPY_YANG(ipv6_route_address_interface_vrf, .onlink = !!onlink, .xpath_vrf = true, .nexthop_vrf = nexthop_vrf, + .bfd = !!bfd, + .bfd_multi_hop = !!bfd_multi_hop, + .bfd_source = bfd_source_str, + .bfd_profile = bfd_profile, }; return static_route_nb_run(vty, &args); @@ -924,6 +1048,7 @@ DEFPY_YANG(ipv6_route, |table (1-4294967295) \ |nexthop-vrf NAME \ |color (1-4294967295) \ + |bfd$bfd [{multi-hop$bfd_multi_hop|source X:X::X:X$bfd_source|profile BFDPROF$bfd_profile}] \ }]", NO_STR IPV6_STR @@ -943,7 +1068,13 @@ DEFPY_YANG(ipv6_route, "The table number to configure\n" VRF_CMD_HELP_STR "SR-TE color\n" - "The SR-TE color to configure\n") + "The SR-TE color to configure\n" + BFD_INTEGRATION_STR + BFD_INTEGRATION_MULTI_HOP_STR + BFD_INTEGRATION_SOURCE_STR + BFD_INTEGRATION_SOURCEV4_STR + BFD_PROFILE_STR + BFD_PROFILE_NAME_STR) { struct static_route_args args = { .delete = !!no, @@ -960,6 +1091,10 @@ DEFPY_YANG(ipv6_route, .color = color_str, .vrf = vrf, .nexthop_vrf = nexthop_vrf, + .bfd = !!bfd, + .bfd_multi_hop = !!bfd_multi_hop, + .bfd_source = bfd_source_str, + .bfd_profile = bfd_profile, }; return static_route_nb_run(vty, &args); @@ -976,6 +1111,7 @@ DEFPY_YANG(ipv6_route_vrf, |table (1-4294967295) \ |nexthop-vrf NAME \ |color (1-4294967295) \ + |bfd$bfd [{multi-hop$bfd_multi_hop|source X:X::X:X$bfd_source|profile BFDPROF$bfd_profile}] \ }]", NO_STR IPV6_STR @@ -994,7 +1130,13 @@ DEFPY_YANG(ipv6_route_vrf, "The table number to configure\n" VRF_CMD_HELP_STR "SR-TE color\n" - "The SR-TE color to configure\n") + "The SR-TE color to configure\n" + BFD_INTEGRATION_STR + BFD_INTEGRATION_MULTI_HOP_STR + BFD_INTEGRATION_SOURCE_STR + BFD_INTEGRATION_SOURCEV4_STR + BFD_PROFILE_STR + BFD_PROFILE_NAME_STR) { struct static_route_args args = { .delete = !!no, @@ -1011,6 +1153,10 @@ DEFPY_YANG(ipv6_route_vrf, .color = color_str, .xpath_vrf = true, .nexthop_vrf = nexthop_vrf, + .bfd = !!bfd, + .bfd_multi_hop = !!bfd_multi_hop, + .bfd_source = bfd_source_str, + .bfd_profile = bfd_profile, }; return static_route_nb_run(vty, &args); @@ -1165,6 +1311,25 @@ static void nexthop_cli_show(struct vty *vty, const struct lyd_node *route, vty_out(vty, " color %s", yang_dnode_get_string(nexthop, "./srte-color")); + if (yang_dnode_exists(nexthop, "./bfd-monitoring")) { + const struct lyd_node *bfd_dnode = + yang_dnode_get(nexthop, "./bfd-monitoring"); + + if (yang_dnode_get_bool(bfd_dnode, "./multi-hop")) { + vty_out(vty, " bfd multi-hop"); + + if (yang_dnode_exists(bfd_dnode, "./source")) + vty_out(vty, " source %s", + yang_dnode_get_string(bfd_dnode, + "./source")); + } else + vty_out(vty, " bfd"); + + if (yang_dnode_exists(bfd_dnode, "./profile")) + vty_out(vty, " profile %s", + yang_dnode_get_string(bfd_dnode, "./profile")); + } + vty_out(vty, "\n"); } -- 2.39.5