diff options
Diffstat (limited to 'bgpd/bgp_bfd.c')
-rw-r--r-- | bgpd/bgp_bfd.c | 354 |
1 files changed, 103 insertions, 251 deletions
diff --git a/bgpd/bgp_bfd.c b/bgpd/bgp_bfd.c index 02047f7f0..87feebe8a 100644 --- a/bgpd/bgp_bfd.c +++ b/bgpd/bgp_bfd.c @@ -32,8 +32,9 @@ #include "stream.h" #include "zclient.h" #include "vty.h" -#include "bgp_fsm.h" +#include "bfd.h" #include "bgpd/bgpd.h" +#include "bgp_fsm.h" #include "bgpd/bgp_bfd.h" #include "bgpd/bgp_debug.h" #include "bgpd/bgp_vty.h" @@ -41,46 +42,23 @@ extern struct zclient *zclient; /* - * bgp_bfd_peer_init - Allocate and initialize the peer BFD information - * with default values. - */ -void -bgp_bfd_peer_init(struct peer *peer) -{ - struct bgp_bfd_peer_info *bfd_info; - - peer->bfd_info = XCALLOC (MTYPE_BGP_PEER_BFD_INFO, - sizeof (struct bgp_bfd_peer_info)); - - bfd_info = (struct bgp_bfd_peer_info *)peer->bfd_info; - - /* Set default BFD parameter values */ - bfd_info->required_min_rx = BGP_BFD_DEF_MIN_RX; - bfd_info->desired_min_tx = BGP_BFD_DEF_MIN_TX; - bfd_info->detect_mult = BGP_BFD_DEF_DETECT_MULT; -} - -/* - * bgp_bfd_peer_free - Free the peer BFD information. - */ -void -bgp_bfd_peer_free(struct peer *peer) -{ - XFREE (MTYPE_BGP_PEER_BFD_INFO, peer->bfd_info); -} - -/* * bgp_bfd_peer_group2peer_copy - Copy the BFD information from peer group template * to peer. */ void bgp_bfd_peer_group2peer_copy(struct peer *conf, struct peer *peer) { - struct bgp_bfd_peer_info *bfd_info; - struct bgp_bfd_peer_info *conf_bfd_info; + struct bfd_info *bfd_info; + struct bfd_info *conf_bfd_info; + + if (!conf->bfd_info) + return; + + conf_bfd_info = (struct bfd_info *)conf->bfd_info; + if (!peer->bfd_info) + peer->bfd_info = bfd_info_create(); - bfd_info = (struct bgp_bfd_peer_info *)peer->bfd_info; - conf_bfd_info = (struct bgp_bfd_peer_info *)conf->bfd_info; + bfd_info = (struct bfd_info *)peer->bfd_info; /* Copy BFD parameter values */ bfd_info->required_min_rx = conf_bfd_info->required_min_rx; @@ -101,111 +79,28 @@ bgp_bfd_is_peer_multihop(struct peer *peer) } /* - * sendmsg_bfd_peer - Format and send a Peer register/Unregister - * command to Zebra to be forwarded to BFD + * bgp_bfd_peer_sendmsg - Format and send a Peer register/Unregister + * command to Zebra to be forwarded to BFD */ static void -sendmsg_bfd_peer (struct peer *peer, int command) +bgp_bfd_peer_sendmsg (struct peer *peer, int command) { - struct stream *s; - int ret; - int len; - struct bgp_bfd_peer_info *bfd_info; - - bfd_info = (struct bgp_bfd_peer_info *)peer->bfd_info; - - /* Check socket. */ - if (!zclient || zclient->sock < 0) - { - zlog_debug("%s: Can't send BFD peer register, Zebra client not established", - __FUNCTION__); - return; - } - - s = zclient->obuf; - stream_reset (s); - zclient_create_header (s, command); - - stream_putw(s, peer->su.sa.sa_family); - switch (peer->su.sa.sa_family) - { - case AF_INET: - stream_put_in_addr (s, &peer->su.sin.sin_addr); - break; -#ifdef HAVE_IPV6 - case AF_INET6: - stream_put(s, &(peer->su.sin6.sin6_addr), 16); - break; -#endif - default: - break; - } - - if (command != ZEBRA_BFD_DEST_DEREGISTER) - { - stream_putl(s, bfd_info->required_min_rx); - stream_putl(s, bfd_info->desired_min_tx); - stream_putc(s, bfd_info->detect_mult); - } - - if (bgp_bfd_is_peer_multihop(peer)) - { - stream_putc(s, 1); - /* Multi-hop destination send the source IP address to BFD */ - if (peer->su_local) - { - stream_putw(s, peer->su_local->sa.sa_family); - switch (peer->su_local->sa.sa_family) - { - case AF_INET: - stream_put_in_addr (s, &peer->su_local->sin.sin_addr); - break; - #ifdef HAVE_IPV6 - case AF_INET6: - stream_put(s, &(peer->su_local->sin6.sin6_addr), 16); - break; - #endif - default: - break; - } - } - stream_putc(s, peer->ttl); - } - else - { - stream_putc(s, 0); -#ifdef HAVE_IPV6 - if ((peer->su.sa.sa_family == AF_INET6) && (peer->su_local)) - { - stream_putw(s, peer->su_local->sa.sa_family); - stream_put(s, &(peer->su_local->sin6.sin6_addr), 16); - } -#endif - - if (peer->nexthop.ifp) - { - len = strlen(peer->nexthop.ifp->name); - stream_putc(s, len); - stream_put(s, peer->nexthop.ifp->name, len); - } - else - { - stream_putc(s, 0); - } - } - - stream_putw_at (s, 0, stream_get_endp (s)); - - ret = zclient_send_message(zclient); - - if (ret < 0) - zlog_warn("sendmsg_bfd_peer: zclient_send_message() failed"); - - if (command == ZEBRA_BFD_DEST_REGISTER) - SET_FLAG(bfd_info->flags, BGP_BFD_FLAG_BFD_REG); - else if (command == ZEBRA_BFD_DEST_DEREGISTER) - UNSET_FLAG(bfd_info->flags, BGP_BFD_FLAG_BFD_REG); - return; + struct bfd_info *bfd_info; + + bfd_info = (struct bfd_info *)peer->bfd_info; + + if (peer->su.sa.sa_family == AF_INET) + bfd_peer_sendmsg (zclient, bfd_info, AF_INET, + &peer->su.sin.sin_addr, + (peer->su_local) ? &peer->su_local->sin.sin_addr : NULL, + (peer->nexthop.ifp) ? peer->nexthop.ifp->name : NULL, + peer->ttl, bgp_bfd_is_peer_multihop(peer), command, 1); + else if (peer->su.sa.sa_family == AF_INET6) + bfd_peer_sendmsg (zclient, bfd_info, AF_INET6, + &peer->su.sin6.sin6_addr, + (peer->su_local) ? &peer->su_local->sin6.sin6_addr : NULL, + (peer->nexthop.ifp) ? peer->nexthop.ifp->name : NULL, + peer->ttl, bgp_bfd_is_peer_multihop(peer), command, 1); } /* @@ -215,16 +110,17 @@ sendmsg_bfd_peer (struct peer *peer, int command) void bgp_bfd_register_peer (struct peer *peer) { - struct bgp_bfd_peer_info *bfd_info; + struct bfd_info *bfd_info; - bfd_info = (struct bgp_bfd_peer_info *)peer->bfd_info; + if (!peer->bfd_info) + return; + bfd_info = (struct bfd_info *)peer->bfd_info; /* Check if BFD is enabled and peer has already been registered with BFD */ - if (!CHECK_FLAG(peer->flags, PEER_FLAG_BFD) || - CHECK_FLAG(bfd_info->flags, BGP_BFD_FLAG_BFD_REG)) + if (CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_REG)) return; - sendmsg_bfd_peer(peer, ZEBRA_BFD_DEST_REGISTER); + bgp_bfd_peer_sendmsg(peer, ZEBRA_BFD_DEST_REGISTER); } /** @@ -235,41 +131,44 @@ bgp_bfd_register_peer (struct peer *peer) void bgp_bfd_deregister_peer (struct peer *peer) { - struct bgp_bfd_peer_info *bfd_info; + struct bfd_info *bfd_info; - bfd_info = (struct bgp_bfd_peer_info *)peer->bfd_info; + if (!peer->bfd_info) + return; + bfd_info = (struct bfd_info *)peer->bfd_info; /* Check if BFD is eanbled and peer has not been registered */ - if (!CHECK_FLAG(peer->flags, PEER_FLAG_BFD) || - !CHECK_FLAG(bfd_info->flags, BGP_BFD_FLAG_BFD_REG)) + if (!CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_REG)) return; - sendmsg_bfd_peer(peer, ZEBRA_BFD_DEST_DEREGISTER); + bgp_bfd_peer_sendmsg(peer, ZEBRA_BFD_DEST_DEREGISTER); } /* * bgp_bfd_update_peer - update peer with BFD with new BFD paramters * through zebra. */ -void +static void bgp_bfd_update_peer (struct peer *peer) { - struct bgp_bfd_peer_info *bfd_info; + struct bfd_info *bfd_info; - bfd_info = (struct bgp_bfd_peer_info *)peer->bfd_info; + if (!peer->bfd_info) + return; + bfd_info = (struct bfd_info *)peer->bfd_info; /* Check if the peer has been registered with BFD*/ - if (!CHECK_FLAG(bfd_info->flags, BGP_BFD_FLAG_BFD_REG)) + if (!CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_REG)) return; - sendmsg_bfd_peer(peer, ZEBRA_BFD_DEST_UPDATE); + bgp_bfd_peer_sendmsg(peer, ZEBRA_BFD_DEST_UPDATE); } /* * bgp_bfd_dest_replay - Replay all the peers that have BFD enabled * to zebra */ -int +static int bgp_bfd_dest_replay (int command, struct zclient *client, zebra_size_t length) { struct listnode *mnode, *node, *nnode; @@ -284,9 +183,6 @@ bgp_bfd_dest_replay (int command, struct zclient *client, zebra_size_t length) for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp)) for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer)) { - if (!CHECK_FLAG (peer->flags, PEER_FLAG_BFD)) - continue; - bgp_bfd_update_peer(peer); } @@ -298,7 +194,7 @@ bgp_bfd_dest_replay (int command, struct zclient *client, zebra_size_t length) * has changed and bring down the peer * connectivity. */ -int +static int bgp_interface_bfd_dest_down (int command, struct zclient *zclient, zebra_size_t length) { @@ -306,7 +202,7 @@ bgp_interface_bfd_dest_down (int command, struct zclient *zclient, struct prefix dp; struct prefix sp; - ifp = zebra_interface_bfd_read (zclient->ibuf, &dp, &sp); + ifp = bfd_get_peer_info (zclient->ibuf, &dp, &sp); if (BGP_DEBUG (zebra, ZEBRA)) { @@ -334,7 +230,7 @@ bgp_interface_bfd_dest_down (int command, struct zclient *zclient, for (ALL_LIST_ELEMENTS_RO (bm->bgp, mnode, bgp)) for (ALL_LIST_ELEMENTS (bgp->peer, node, nnode, peer)) { - if (!CHECK_FLAG (peer->flags, PEER_FLAG_BFD)) + if (!peer->bfd_info) continue; if ((dp.family == AF_INET) && (peer->su.sa.sa_family == AF_INET)) @@ -394,53 +290,39 @@ bgp_interface_bfd_dest_down (int command, struct zclient *zclient, /* * bgp_bfd_peer_param_set - Set the configured BFD paramter values for peer. */ -int +static int bgp_bfd_peer_param_set (struct peer *peer, u_int32_t min_rx, u_int32_t min_tx, - u_int8_t detect_mult, int reg_peer, int defaults) + u_int8_t detect_mult, int defaults) { struct peer_group *group; struct listnode *node, *nnode; - int change = 0; - struct bgp_bfd_peer_info *bfd_info; - - bfd_info = (struct bgp_bfd_peer_info *)peer->bfd_info; - - if ((bfd_info->required_min_rx != min_rx) || - (bfd_info->desired_min_tx != min_tx) || - (bfd_info->detect_mult != detect_mult)) - change = 1; + int command = 0; - bfd_info->required_min_rx = min_rx; - bfd_info->desired_min_tx = min_tx; - bfd_info->detect_mult = detect_mult; - - if (!defaults) - SET_FLAG (bfd_info->flags, BGP_BFD_FLAG_PARAM_CFG); - else - UNSET_FLAG (bfd_info->flags, BGP_BFD_FLAG_PARAM_CFG); + bfd_set_param(&(peer->bfd_info), min_rx, min_tx, detect_mult, + defaults, &command); if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) { group = peer->group; for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer)) { - bfd_info = (struct bgp_bfd_peer_info *)peer->bfd_info; - bfd_info->required_min_rx = min_rx; - bfd_info->desired_min_tx = min_tx; - bfd_info->detect_mult = detect_mult; - SET_FLAG (bfd_info->flags, BGP_BFD_FLAG_PARAM_CFG); + command = 0; + bfd_set_param(&(peer->bfd_info), min_rx, min_tx, detect_mult, + defaults, &command); - if (reg_peer && (peer->status == Established)) + if ((peer->status == Established) && + (command == ZEBRA_BFD_DEST_REGISTER)) bgp_bfd_register_peer(peer); - else if (change) + else if (command == ZEBRA_BFD_DEST_UPDATE) bgp_bfd_update_peer(peer); } } - else + else { - if (reg_peer && (peer->status == Established)) + if ((peer->status == Established) && + (command == ZEBRA_BFD_DEST_REGISTER)) bgp_bfd_register_peer(peer); - else if (change) + else if (command == ZEBRA_BFD_DEST_UPDATE) bgp_bfd_update_peer(peer); } return 0; @@ -449,35 +331,30 @@ bgp_bfd_peer_param_set (struct peer *peer, u_int32_t min_rx, u_int32_t min_tx, /* * bgp_bfd_peer_param_unset - Unset the configured BFD paramter values for peer. */ -int +static int bgp_bfd_peer_param_unset (struct peer *peer) { struct peer_group *group; struct listnode *node, *nnode; - struct bgp_bfd_peer_info *bfd_info; - - bfd_info = (struct bgp_bfd_peer_info *)peer->bfd_info; - bfd_info->required_min_rx = BGP_BFD_DEF_MIN_RX; - bfd_info->desired_min_tx = BGP_BFD_DEF_MIN_TX; - bfd_info->detect_mult = BGP_BFD_DEF_DETECT_MULT; - UNSET_FLAG (bfd_info->flags, BGP_BFD_FLAG_PARAM_CFG); + if (!peer->bfd_info) + return 0; if (CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) { + bfd_info_free(&(peer->bfd_info)); group = peer->group; for (ALL_LIST_ELEMENTS (group->peer, node, nnode, peer)) { - bfd_info->required_min_rx = BGP_BFD_DEF_MIN_RX; - bfd_info->desired_min_tx = BGP_BFD_DEF_MIN_TX; - bfd_info->detect_mult = BGP_BFD_DEF_DETECT_MULT; - UNSET_FLAG (bfd_info->flags, BGP_BFD_FLAG_PARAM_CFG); - bgp_bfd_deregister_peer(peer); + bfd_info_free(&(peer->bfd_info)); } } else - bgp_bfd_deregister_peer(peer); + { + bgp_bfd_deregister_peer(peer); + bfd_info_free(&(peer->bfd_info)); + } return 0; } @@ -487,11 +364,14 @@ bgp_bfd_peer_param_unset (struct peer *peer) void bgp_bfd_peer_config_write(struct vty *vty, struct peer *peer, char *addr) { - struct bgp_bfd_peer_info *bfd_info; + struct bfd_info *bfd_info; - bfd_info = (struct bgp_bfd_peer_info *)peer->bfd_info; + if (!peer->bfd_info) + return; + + bfd_info = (struct bfd_info *)peer->bfd_info; - if (CHECK_FLAG (bfd_info->flags, BGP_BFD_FLAG_PARAM_CFG)) + if (CHECK_FLAG (bfd_info->flags, BFD_FLAG_PARAM_CFG)) vty_out (vty, " neighbor %s bfd %d %d %d%s", addr, bfd_info->detect_mult, bfd_info->required_min_rx, bfd_info->desired_min_tx, VTY_NEWLINE); @@ -505,20 +385,20 @@ bgp_bfd_peer_config_write(struct vty *vty, struct peer *peer, char *addr) void bgp_bfd_show_info(struct vty *vty, struct peer *peer) { - struct bgp_bfd_peer_info *bfd_info; + struct bfd_info *bfd_info; + + if (!peer->bfd_info) + return; - bfd_info = (struct bgp_bfd_peer_info *)peer->bfd_info; + bfd_info = (struct bfd_info *)peer->bfd_info; - if (CHECK_FLAG(peer->flags, PEER_FLAG_BFD)) - { - vty_out (vty, " BFD: Multi-hop: %s%s", - (bgp_bfd_is_peer_multihop(peer)) ? "yes" : "no", VTY_NEWLINE); - vty_out (vty, " Detect Mul: %d, Min Rx interval: %d," - " Min Tx interval: %d%s", - bfd_info->detect_mult, bfd_info->required_min_rx, - bfd_info->desired_min_tx, VTY_NEWLINE); - vty_out (vty, "%s", VTY_NEWLINE); - } + vty_out (vty, " BFD: Multi-hop: %s%s", + (bgp_bfd_is_peer_multihop(peer)) ? "yes" : "no", VTY_NEWLINE); + vty_out (vty, " Detect Mul: %d, Min Rx interval: %d," + " Min Tx interval: %d%s", + bfd_info->detect_mult, bfd_info->required_min_rx, + bfd_info->desired_min_tx, VTY_NEWLINE); + vty_out (vty, "%s", VTY_NEWLINE); } DEFUN (neighbor_bfd, @@ -530,23 +410,13 @@ DEFUN (neighbor_bfd, { struct peer *peer; int ret; - int reg_peer = 0; peer = peer_and_group_lookup_vty (vty, argv[0]); if (! peer) return CMD_WARNING; - if ( !CHECK_FLAG (peer->flags, PEER_FLAG_BFD) ) - { - ret = peer_flag_set (peer, PEER_FLAG_BFD); - if (ret != 0) - return bgp_vty_return (vty, ret); - - reg_peer = 1; - } - - ret = bgp_bfd_peer_param_set (peer, BGP_BFD_DEF_MIN_RX, BGP_BFD_DEF_MIN_TX, - BGP_BFD_DEF_DETECT_MULT, reg_peer, 1); + ret = bgp_bfd_peer_param_set (peer, BFD_DEF_MIN_RX, BFD_DEF_MIN_TX, + BFD_DEF_DETECT_MULT, 1); if (ret != 0) return bgp_vty_return (vty, ret); @@ -556,7 +426,7 @@ DEFUN (neighbor_bfd, DEFUN (neighbor_bfd_param, neighbor_bfd_param_cmd, - NEIGHBOR_CMD2 "bfd <2-255> <50-60000> <50-60000>", + NEIGHBOR_CMD2 "bfd " BFD_CMD_DETECT_MULT_RANGE BFD_CMD_MIN_RX_RANGE BFD_CMD_MIN_TX_RANGE, NEIGHBOR_STR NEIGHBOR_ADDR_STR2 "Enables BFD support\n" @@ -569,26 +439,16 @@ DEFUN (neighbor_bfd_param, u_int32_t tx_val; u_int8_t dm_val; int ret; - int reg_peer = 0; peer = peer_and_group_lookup_vty (vty, argv[0]); if (!peer) return CMD_WARNING; - if (!CHECK_FLAG (peer->flags, PEER_FLAG_BFD)) - { - ret = peer_flag_set (peer, PEER_FLAG_BFD); - if (ret != 0) - return bgp_vty_return (vty, ret); - - reg_peer = 1; - } - - VTY_GET_INTEGER_RANGE ("detect-mul", dm_val, argv[1], 2, 255); - VTY_GET_INTEGER_RANGE ("min-rx", rx_val, argv[2], 50, 60000); - VTY_GET_INTEGER_RANGE ("min-tx", tx_val, argv[3], 50, 60000); + if ((ret = bfd_validate_param (vty, argv[1], argv[2], argv[3], &dm_val, + &rx_val, &tx_val)) != CMD_SUCCESS) + return ret; - ret = bgp_bfd_peer_param_set (peer, rx_val, tx_val, dm_val, reg_peer, 0); + ret = bgp_bfd_peer_param_set (peer, rx_val, tx_val, dm_val, 0); if (ret != 0) return bgp_vty_return (vty, ret); @@ -611,18 +471,10 @@ DEFUN (no_neighbor_bfd, if (! peer) return CMD_WARNING; - /* Do nothing if there is no change in the flag */ - if ( !CHECK_FLAG (peer->flags, PEER_FLAG_BFD) ) - return CMD_SUCCESS; - ret = bgp_bfd_peer_param_unset(peer); if (ret != 0) return bgp_vty_return (vty, ret); - ret = peer_flag_unset (peer, PEER_FLAG_BFD); - if (ret != 0) - return bgp_vty_return (vty, ret); - return CMD_SUCCESS; } |