From: GalaxyGorilla Date: Fri, 10 Jul 2020 11:26:55 +0000 (+0000) Subject: *: add BFD profile support for IS-IS X-Git-Tag: base_7.5~164^2~2 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=4affdba79e306d3eab88af0ed63a7ca38ceb77f9;p=mirror%2Ffrr.git *: add BFD profile support for IS-IS BFD profiles can now be used on the interface level like this: interface eth1 ip router isis 1 isis bfd isis bfd profile default Here the 'default' profile needs to be specified as usual in the bfdd configuration. Signed-off-by: GalaxyGorilla --- diff --git a/bgpd/bgp_bfd.c b/bgpd/bgp_bfd.c index 54970af67b..c8de575f7f 100644 --- a/bgpd/bgp_bfd.c +++ b/bgpd/bgp_bfd.c @@ -487,7 +487,7 @@ static int bgp_bfd_peer_param_set(struct peer *peer, uint32_t min_rx, int command = 0; bfd_set_param((struct bfd_info **)&(peer->bfd_info), min_rx, min_tx, - detect_mult, defaults, &command); + detect_mult, NULL, defaults, &command); /* This command overrides profile if it was previously applied. */ bi = peer->bfd_info; @@ -498,8 +498,8 @@ static int bgp_bfd_peer_param_set(struct peer *peer, uint32_t min_rx, for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) { command = 0; bfd_set_param((struct bfd_info **)&(peer->bfd_info), - min_rx, min_tx, detect_mult, defaults, - &command); + min_rx, min_tx, detect_mult, NULL, + defaults, &command); /* * This command overrides profile if it was previously @@ -565,7 +565,7 @@ static int bgp_bfd_peer_param_type_set(struct peer *peer, if (!peer->bfd_info) bfd_set_param((struct bfd_info **)&(peer->bfd_info), BFD_DEF_MIN_RX, BFD_DEF_MIN_TX, - BFD_DEF_DETECT_MULT, 1, &command); + BFD_DEF_DETECT_MULT, NULL, 1, &command); bfd_info = (struct bfd_info *)peer->bfd_info; bfd_info->type = type; @@ -578,7 +578,7 @@ static int bgp_bfd_peer_param_type_set(struct peer *peer, bfd_set_param( (struct bfd_info **)&(peer->bfd_info), BFD_DEF_MIN_RX, BFD_DEF_MIN_TX, - BFD_DEF_DETECT_MULT, 1, &command); + BFD_DEF_DETECT_MULT, NULL, 1, &command); bfd_info = (struct bfd_info *)peer->bfd_info; bfd_info->type = type; @@ -613,7 +613,7 @@ static int bgp_bfd_peer_set_profile(struct peer *peer, const char *profile) struct bfd_info *bfd_info; bfd_set_param((struct bfd_info **)&(peer->bfd_info), BFD_DEF_MIN_RX, - BFD_DEF_MIN_TX, BFD_DEF_DETECT_MULT, 1, &command); + BFD_DEF_MIN_TX, BFD_DEF_DETECT_MULT, NULL, 1, &command); bfd_info = (struct bfd_info *)peer->bfd_info; @@ -629,7 +629,7 @@ static int bgp_bfd_peer_set_profile(struct peer *peer, const char *profile) command = 0; bfd_set_param((struct bfd_info **)&(peer->bfd_info), BFD_DEF_MIN_RX, BFD_DEF_MIN_TX, - BFD_DEF_DETECT_MULT, 1, &command); + BFD_DEF_DETECT_MULT, NULL, 1, &command); bfd_info = (struct bfd_info *)peer->bfd_info; diff --git a/doc/user/bfd.rst b/doc/user/bfd.rst index 618d90a85e..47792317ad 100644 --- a/doc/user/bfd.rst +++ b/doc/user/bfd.rst @@ -254,7 +254,7 @@ IS-IS BFD Configuration The following commands are available inside the interface configuration node. .. index:: isis bfd -.. clicmd:: ip isis bfd +.. clicmd:: isis bfd Listen for BFD events on peers created on the interface. Every time a new neighbor is found a BFD peer is created to monitor the link @@ -269,6 +269,15 @@ The following commands are available inside the interface configuration node. IPv4 and IPv6 support are configured then just a IPv6 based session is created. +.. index:: isis bfd profile BFDPROF +.. clicmd:: isis bfd profile BFDPROF + + Use a BFD profile BFDPROF as provided in the BFD configuration. + +.. index:: no isis bfd profile BFDPROF +.. clicmd:: no isis bfd profile BFDPROF + + Removes any BFD profile if present. .. _bfd-ospf-peer-config: diff --git a/isisd/isis_bfd.c b/isisd/isis_bfd.c index 69c971ee2c..4408c8bb8b 100644 --- a/isisd/isis_bfd.c +++ b/isisd/isis_bfd.c @@ -383,14 +383,14 @@ void isis_bfd_circuit_cmd(struct isis_circuit *circuit, int command) } } -void isis_bfd_circuit_param_set(struct isis_circuit *circuit, - uint32_t min_rx, uint32_t min_tx, - uint32_t detect_mult, int defaults) +void isis_bfd_circuit_param_set(struct isis_circuit *circuit, uint32_t min_rx, + uint32_t min_tx, uint32_t detect_mult, + const char *profile, int defaults) { int command = 0; - bfd_set_param(&circuit->bfd_info, min_rx, - min_tx, detect_mult, defaults, &command); + bfd_set_param(&circuit->bfd_info, min_rx, min_tx, detect_mult, profile, + defaults, &command); if (command) isis_bfd_circuit_cmd(circuit, command); diff --git a/isisd/isis_bfd.h b/isisd/isis_bfd.h index 3193f16061..6ce630688c 100644 --- a/isisd/isis_bfd.h +++ b/isisd/isis_bfd.h @@ -22,9 +22,9 @@ struct isis_circuit; void isis_bfd_circuit_cmd(struct isis_circuit *circuit, int command); -void isis_bfd_circuit_param_set(struct isis_circuit *circuit, - uint32_t min_rx, uint32_t min_tx, - uint32_t detect_mult, int defaults); +void isis_bfd_circuit_param_set(struct isis_circuit *circuit, uint32_t min_rx, + uint32_t min_tx, uint32_t detect_mult, + const char *profile, int defaults); void isis_bfd_init(void); #endif diff --git a/isisd/isis_cli.c b/isisd/isis_cli.c index df69b1c7be..6ea3c5fb5c 100644 --- a/isisd/isis_cli.c +++ b/isisd/isis_cli.c @@ -330,8 +330,7 @@ void cli_show_ip_isis_ipv6(struct vty *vty, struct lyd_node *dnode, DEFPY(isis_bfd, isis_bfd_cmd, "[no] isis bfd", - NO_STR - PROTO_HELP + NO_STR PROTO_HELP "Enable BFD support\n") { const struct lyd_node *dnode; @@ -343,19 +342,53 @@ DEFPY(isis_bfd, return CMD_SUCCESS; } - nb_cli_enqueue_change(vty, "./frr-isisd:isis/bfd-monitoring", + nb_cli_enqueue_change(vty, "./frr-isisd:isis/bfd-monitoring/enabled", NB_OP_MODIFY, no ? "false" : "true"); return nb_cli_apply_changes(vty, NULL); } +/* + * XPath: /frr-interface:lib/interface/frr-isisd:isis/bfd-monitoring/profile + */ +DEFPY(isis_bfd_profile, + isis_bfd_profile_cmd, + "[no] isis bfd profile WORD", + NO_STR PROTO_HELP + "Enable BFD support\n" + "Use a pre-configured profile\n" + "Profile name\n") +{ + const struct lyd_node *dnode; + + dnode = yang_dnode_get(vty->candidate_config->dnode, + "%s/frr-isisd:isis", VTY_CURR_XPATH); + if (dnode == NULL) { + vty_out(vty, "ISIS is not enabled on this circuit\n"); + return CMD_SUCCESS; + } + + nb_cli_enqueue_change(vty, "./frr-isisd:isis/bfd-monitoring/profile", + NB_OP_MODIFY, no ? NULL : profile); + + return nb_cli_apply_changes(vty, NULL); +} + void cli_show_ip_isis_bfd_monitoring(struct vty *vty, struct lyd_node *dnode, bool show_defaults) { - if (!yang_dnode_get_bool(dnode, NULL)) + const char *profile; + + if (!yang_dnode_get_bool(dnode, "./enabled")) vty_out(vty, " no"); vty_out(vty, " isis bfd\n"); + + if (yang_dnode_exists(dnode, "./profile")) { + profile = yang_dnode_get_string(dnode, "./profile"); + if (profile[0] != '\0') + vty_out(vty, " isis bfd profile %s\n", profile); + } } /* @@ -2301,6 +2334,7 @@ void isis_cli_init(void) install_element(INTERFACE_NODE, &ip6_router_isis_cmd); install_element(INTERFACE_NODE, &no_ip_router_isis_cmd); install_element(INTERFACE_NODE, &isis_bfd_cmd); + install_element(INTERFACE_NODE, &isis_bfd_profile_cmd); install_element(ISIS_NODE, &net_cmd); diff --git a/isisd/isis_nb.c b/isisd/isis_nb.c index 1d842eb13b..2b8b02e3f1 100644 --- a/isisd/isis_nb.c +++ b/isisd/isis_nb.c @@ -574,10 +574,23 @@ const struct frr_yang_module_info frr_isisd_info = { { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/bfd-monitoring", .cbs = { - .modify = lib_interface_isis_bfd_monitoring_modify, + .apply_finish = lib_interface_isis_bfd_monitoring_apply_finish, .cli_show = cli_show_ip_isis_bfd_monitoring, } }, + { + .xpath = "/frr-interface:lib/interface/frr-isisd:isis/bfd-monitoring/enabled", + .cbs = { + .modify = lib_interface_isis_bfd_monitoring_enabled_modify, + } + }, + { + .xpath = "/frr-interface:lib/interface/frr-isisd:isis/bfd-monitoring/profile", + .cbs = { + .modify = lib_interface_isis_bfd_monitoring_profile_modify, + .destroy = lib_interface_isis_bfd_monitoring_profile_destroy, + } + }, { .xpath = "/frr-interface:lib/interface/frr-isisd:isis/csnp-interval", .cbs = { diff --git a/isisd/isis_nb.h b/isisd/isis_nb.h index e887b1a388..a9401bc86a 100644 --- a/isisd/isis_nb.h +++ b/isisd/isis_nb.h @@ -171,7 +171,14 @@ int lib_interface_isis_area_tag_modify(struct nb_cb_modify_args *args); int lib_interface_isis_ipv4_routing_modify(struct nb_cb_modify_args *args); int lib_interface_isis_ipv6_routing_modify(struct nb_cb_modify_args *args); int lib_interface_isis_circuit_type_modify(struct nb_cb_modify_args *args); -int lib_interface_isis_bfd_monitoring_modify(struct nb_cb_modify_args *args); +void lib_interface_isis_bfd_monitoring_apply_finish( + struct nb_cb_apply_finish_args *args); +int lib_interface_isis_bfd_monitoring_enabled_modify( + struct nb_cb_modify_args *args); +int lib_interface_isis_bfd_monitoring_profile_modify( + struct nb_cb_modify_args *args); +int lib_interface_isis_bfd_monitoring_profile_destroy( + struct nb_cb_destroy_args *args); int isis_instance_segment_routing_enabled_modify( struct nb_cb_modify_args *args); int isis_instance_segment_routing_enabled_modify( diff --git a/isisd/isis_nb_config.c b/isisd/isis_nb_config.c index c17433cb27..a7a70dff0a 100644 --- a/isisd/isis_nb_config.c +++ b/isisd/isis_nb_config.c @@ -2030,26 +2030,53 @@ int lib_interface_isis_ipv6_routing_modify(struct nb_cb_modify_args *args) /* * XPath: /frr-interface:lib/interface/frr-isisd:isis/bfd-monitoring */ -int lib_interface_isis_bfd_monitoring_modify(struct nb_cb_modify_args *args) +void lib_interface_isis_bfd_monitoring_apply_finish( + struct nb_cb_apply_finish_args *args) { struct isis_circuit *circuit; - bool bfd_monitoring; - - if (args->event != NB_EV_APPLY) - return NB_OK; + bool enabled; + const char *profile = NULL; circuit = nb_running_get_entry(args->dnode, NULL, true); - bfd_monitoring = yang_dnode_get_bool(args->dnode, NULL); + enabled = yang_dnode_get_bool(args->dnode, "./enabled"); + + if (yang_dnode_exists(args->dnode, "./profile")) + profile = yang_dnode_get_string(args->dnode, "./profile"); - if (bfd_monitoring) { + if (enabled) { isis_bfd_circuit_param_set(circuit, BFD_DEF_MIN_RX, BFD_DEF_MIN_TX, BFD_DEF_DETECT_MULT, - true); + profile, true); } else { isis_bfd_circuit_cmd(circuit, ZEBRA_BFD_DEST_DEREGISTER); bfd_info_free(&circuit->bfd_info); } +} + +/* + * XPath: /frr-interface:lib/interface/frr-isisd:isis/bfd-monitoring/enabled + */ +int lib_interface_isis_bfd_monitoring_enabled_modify( + struct nb_cb_modify_args *args) +{ + /* Everything done in apply_finish */ + return NB_OK; +} +/* + * XPath: /frr-interface:lib/interface/frr-isisd:isis/bfd-monitoring/profile + */ +int lib_interface_isis_bfd_monitoring_profile_modify( + struct nb_cb_modify_args *args) +{ + /* Everything done in apply_finish */ + return NB_OK; +} + +int lib_interface_isis_bfd_monitoring_profile_destroy( + struct nb_cb_destroy_args *args) +{ + /* Everything done in apply_finish */ return NB_OK; } diff --git a/isisd/isis_vty_fabricd.c b/isisd/isis_vty_fabricd.c index 09b8d28258..ffb17f9acf 100644 --- a/isisd/isis_vty_fabricd.c +++ b/isisd/isis_vty_fabricd.c @@ -316,8 +316,8 @@ DEFUN (isis_bfd, return CMD_SUCCESS; } - isis_bfd_circuit_param_set(circuit, BFD_DEF_MIN_RX, - BFD_DEF_MIN_TX, BFD_DEF_DETECT_MULT, true); + isis_bfd_circuit_param_set(circuit, BFD_DEF_MIN_RX, BFD_DEF_MIN_TX, + BFD_DEF_DETECT_MULT, NULL, true); return CMD_SUCCESS; } diff --git a/lib/bfd.c b/lib/bfd.c index 7c84648d91..d2bcb5b8aa 100644 --- a/lib/bfd.c +++ b/lib/bfd.c @@ -94,7 +94,8 @@ int bfd_validate_param(struct vty *vty, const char *dm_str, const char *rx_str, * bfd_set_param - Set the configured BFD paramter values */ void bfd_set_param(struct bfd_info **bfd_info, uint32_t min_rx, uint32_t min_tx, - uint8_t detect_mult, int defaults, int *command) + uint8_t detect_mult, const char *profile, int defaults, + int *command) { if (!*bfd_info) { *bfd_info = bfd_info_create(); @@ -102,7 +103,8 @@ void bfd_set_param(struct bfd_info **bfd_info, uint32_t min_rx, uint32_t min_tx, } else { if (((*bfd_info)->required_min_rx != min_rx) || ((*bfd_info)->desired_min_tx != min_tx) - || ((*bfd_info)->detect_mult != detect_mult)) + || ((*bfd_info)->detect_mult != detect_mult) + || (profile && strcmp((*bfd_info)->profile, profile))) *command = ZEBRA_BFD_DEST_UPDATE; } @@ -110,6 +112,11 @@ void bfd_set_param(struct bfd_info **bfd_info, uint32_t min_rx, uint32_t min_tx, (*bfd_info)->required_min_rx = min_rx; (*bfd_info)->desired_min_tx = min_tx; (*bfd_info)->detect_mult = detect_mult; + if (profile) + strlcpy((*bfd_info)->profile, profile, + BFD_PROFILE_NAME_LEN); + else + (*bfd_info)->profile[0] = '\0'; } if (!defaults) @@ -162,6 +169,11 @@ void bfd_peer_sendmsg(struct zclient *zclient, struct bfd_info *bfd_info, args.min_rx = bfd_info->required_min_rx; args.min_tx = bfd_info->desired_min_tx; args.detection_multiplier = bfd_info->detect_mult; + if (bfd_info->profile[0]) { + args.profilelen = strlen(bfd_info->profile); + strlcpy(args.profile, bfd_info->profile, + sizeof(args.profile)); + } } addrlen = family == AF_INET ? sizeof(struct in_addr) diff --git a/lib/bfd.h b/lib/bfd.h index d7d4b5fe35..ceab4628b6 100644 --- a/lib/bfd.h +++ b/lib/bfd.h @@ -92,8 +92,8 @@ extern int bfd_validate_param(struct vty *vty, const char *dm_str, uint32_t *tx_val); extern void bfd_set_param(struct bfd_info **bfd_info, uint32_t min_rx, - uint32_t min_tx, uint8_t detect_mult, int defaults, - int *command); + uint32_t min_tx, uint8_t detect_mult, + const char *profile, int defaults, int *command); extern void bfd_peer_sendmsg(struct zclient *zclient, struct bfd_info *bfd_info, int family, void *dst_ip, void *src_ip, char *if_name, int ttl, int multihop, int cbit, diff --git a/ospf6d/ospf6_bfd.c b/ospf6d/ospf6_bfd.c index 4e7a0050aa..916e59baf0 100644 --- a/ospf6d/ospf6_bfd.c +++ b/ospf6d/ospf6_bfd.c @@ -308,7 +308,7 @@ static void ospf6_bfd_if_param_set(struct ospf6_interface *oi, uint32_t min_rx, int command = 0; bfd_set_param((struct bfd_info **)&(oi->bfd_info), min_rx, min_tx, - detect_mult, defaults, &command); + detect_mult, NULL, defaults, &command); if (command) ospf6_bfd_reg_dereg_all_nbr(oi, command); } diff --git a/ospfd/ospf_bfd.c b/ospfd/ospf_bfd.c index b9e78f4cd3..d2c5090f2f 100644 --- a/ospfd/ospf_bfd.c +++ b/ospfd/ospf_bfd.c @@ -381,7 +381,7 @@ static void ospf_bfd_if_param_set(struct interface *ifp, uint32_t min_rx, params = IF_DEF_PARAMS(ifp); bfd_set_param((struct bfd_info **)&(params->bfd_info), min_rx, min_tx, - detect_mult, defaults, &command); + detect_mult, NULL, defaults, &command); if (command) ospf_bfd_reg_dereg_all_nbr(ifp, command); } diff --git a/pimd/pim_bfd.c b/pimd/pim_bfd.c index 0df8ea6922..146b53fa8f 100644 --- a/pimd/pim_bfd.c +++ b/pimd/pim_bfd.c @@ -194,7 +194,7 @@ void pim_bfd_if_param_set(struct interface *ifp, uint32_t min_rx, if (!pim_ifp) return; - bfd_set_param(&(pim_ifp->bfd_info), min_rx, min_tx, detect_mult, + bfd_set_param(&(pim_ifp->bfd_info), min_rx, min_tx, detect_mult, NULL, defaults, &command); if (pim_ifp->bfd_info) { diff --git a/yang/frr-isisd.yang b/yang/frr-isisd.yang index befdc3467d..1bb693a1ef 100644 --- a/yang/frr-isisd.yang +++ b/yang/frr-isisd.yang @@ -361,11 +361,18 @@ module frr-isisd { "IS-type of this circuit."; } - leaf bfd-monitoring { - type boolean; - default "false"; - description - "Monitor IS-IS peers on this circuit."; + container bfd-monitoring { + leaf enabled { + type boolean; + default "false"; + description + "Monitor IS-IS peers on this circuit."; + } + leaf profile { + type string; + description + "Let BFD use a pre-configured profile."; + } } container csnp-interval {