diff options
author | radhika <radhika@cumulusnetworks.com> | 2015-08-31 23:56:11 +0200 |
---|---|---|
committer | radhika <radhika@cumulusnetworks.com> | 2015-08-31 23:56:11 +0200 |
commit | 68fe91d6c7731fba199a7f4bd53e12a559e3b3de (patch) | |
tree | 03d95c7f20f6fa589c3b9a3a84fdff76cc58956e /zebra/zebra_ptm.c | |
parent | BGP: Fix MD5 authentication for unnumbered neighbors (diff) | |
download | frr-68fe91d6c7731fba199a7f4bd53e12a559e3b3de.tar.xz frr-68fe91d6c7731fba199a7f4bd53e12a559e3b3de.zip |
Support of BFD status in Quagga
Ticket:CM-6802, CM-6952
Reviewed By: Donald, Kanna
Testing Done:
Double commit of b76943235e09472ec174edcf7204fc82d27fe966 from br2.5. But, manually resolved all the compilation errors. Also, modified the shows to support the json format which was not supported in br2.5.
CM-6802 – Currently, BFD session status can be monitored only through ptmctl. There is no way to check the BFD status of a peer/neighbor through Quagga. Debugging becomes easier if BFD status is shown in Quagga too. BFD status is relevant when it is shown against the BGP peer/OSPF neighbor. For, this following code changes have been done:
- Only down messages from PTM were being propagated from Zebra daemon to clients (bgpd, ospfd and ospf6d). Now, both up and down messages are redistributed to the clients from zebra. BFD status field has been added to the messaging. Handling of BFD session up messages has been added to the client code. BGP/OSPF neighbor is brought down only if the old BFD session status is ‘Up’ to handle extra/initial down messages.
- BFD status and last update timestamp fields have been added to the common BFD info structure. Also, common show functions for showing BFD information have been added to BFD lib.
- Modified the BGP neighbor show functions to call common BFD lib functions.
- For ospf and ospf6, BFD information was maintained only at interface level. To show BFD status per neighbor, BFD information has been added at neighbor level too. “show ip ospf interface”, “show ip ospf neighbor detail”, “show ipv6 ospf6 interface” and “show ipv6 ospf6 neighbor detail” output have been modified to show BFD information.
CM-6952 - IBGP peers were always assumed to be multi-hop since there was no easy way to determine whether an IBGP peer was single hop or multihop unlike EBGP. But, this is causing problem with IBGP link local peers since BFD doesn't allow multihop BFD session with link local IP addresses. Link local peers were discovered when the interface peering was enabled. Interface peering is always singlehop. So, added checks to treat all interface based peers as single hop irrespective of whether the peer is IBGP or EBGP.
Diffstat (limited to 'zebra/zebra_ptm.c')
-rw-r--r-- | zebra/zebra_ptm.c | 76 |
1 files changed, 33 insertions, 43 deletions
diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c index 6c85eaa89..0fecd17d5 100644 --- a/zebra/zebra_ptm.c +++ b/zebra/zebra_ptm.c @@ -33,6 +33,7 @@ #include "ptm_lib.h" #include "buffer.h" #include "zebra/zebra_ptm_redistribute.h" +#include "bfd.h" #define ZEBRA_PTM_RECONNECT_TIME_INITIAL 1 /* initial reconnect is 1s */ #define ZEBRA_PTM_RECONNECT_TIME_MAX 300 @@ -68,6 +69,7 @@ const char ZEBRA_PTM_BFD_CLIENT_FIELD[] = "client"; const char ZEBRA_PTM_BFD_SEQID_FIELD[] = "seqid"; const char ZEBRA_PTM_BFD_IFNAME_FIELD[] = "ifName"; const char ZEBRA_PTM_BFD_MAX_HOP_CNT_FIELD[] = "maxHopCnt"; +const char ZEBRA_PTM_BFD_SEND_EVENT[] = "sendEvent"; extern struct zebra_t zebrad; @@ -341,7 +343,8 @@ zebra_ptm_install_commands (void) /* BFD session goes down, send message to the protocols. */ static void -if_bfd_session_down (struct interface *ifp, struct prefix *dp, struct prefix *sp) +if_bfd_session_update (struct interface *ifp, struct prefix *dp, + struct prefix *sp, int status) { if (IS_ZEBRA_DEBUG_EVENT) { @@ -349,22 +352,24 @@ if_bfd_session_down (struct interface *ifp, struct prefix *dp, struct prefix *sp if (ifp) { - zlog_debug ("MESSAGE: ZEBRA_INTERFACE_BFD_DEST_DOWN %s/%d on %s", - inet_ntop (dp->family, &dp->u.prefix, buf[0], - INET6_ADDRSTRLEN), dp->prefixlen, ifp->name); + zlog_debug ("MESSAGE: ZEBRA_INTERFACE_BFD_DEST_UPDATE %s/%d on %s" + " %s event", + inet_ntop (dp->family, &dp->u.prefix, buf[0], + INET6_ADDRSTRLEN), dp->prefixlen, ifp->name, + bfd_get_status_str(status)); } else { - zlog_debug ("MESSAGE: ZEBRA_INTERFACE_BFD_DEST_DOWN %s/%d " - "with src %s/%d", + zlog_debug ("MESSAGE: ZEBRA_INTERFACE_BFD_DEST_UPDATE %s/%d " + "with src %s/%d %s event", inet_ntop (dp->family, &dp->u.prefix, buf[0], INET6_ADDRSTRLEN), dp->prefixlen, inet_ntop (sp->family, &sp->u.prefix, buf[1], INET6_ADDRSTRLEN), - sp->prefixlen); + sp->prefixlen, bfd_get_status_str(status)); } } - zebra_interface_bfd_update (ifp, dp, sp); + zebra_interface_bfd_update (ifp, dp, sp, status); } static int @@ -403,44 +408,25 @@ zebra_ptm_handle_bfd_msg(void *arg, void *in_ctxt, struct interface *ifp) __func__, ifp ? ifp->name : "N/A", bfdst_str, dest_str, src_str); - /* we only care if bfd session goes down */ - if (!strcmp (bfdst_str, ZEBRA_PTM_BFDSTATUS_DOWN_STR)) { - if (inet_pton(AF_INET, dest_str, &dest_prefix.u.prefix4) > 0) { - dest_prefix.family = AF_INET; - dest_prefix.prefixlen = IPV4_MAX_PREFIXLEN; - } -#ifdef HAVE_IPV6 - else if (inet_pton(AF_INET6, dest_str, &dest_prefix.u.prefix6) > 0) { - dest_prefix.family = AF_INET6; - dest_prefix.prefixlen = IPV6_MAX_PREFIXLEN; - } -#endif /* HAVE_IPV6 */ - else { - zlog_err("%s: Peer addr %s not found", __func__, - dest_str); - return -1; - } + if (str2prefix(dest_str, &dest_prefix) == 0) { + zlog_err("%s: Peer addr %s not found", __func__, + dest_str); + return -1; + } - memset(&src_prefix, 0, sizeof(struct prefix)); - if (strcmp(ZEBRA_PTM_INVALID_SRC_IP, src_str)) { - if (inet_pton(AF_INET, src_str, &src_prefix.u.prefix4) > 0) { - src_prefix.family = AF_INET; - src_prefix.prefixlen = IPV4_MAX_PREFIXLEN; - } -#ifdef HAVE_IPV6 - else if (inet_pton(AF_INET6, src_str, &src_prefix.u.prefix6) > 0) { - src_prefix.family = AF_INET6; - src_prefix.prefixlen = IPV6_MAX_PREFIXLEN; - } -#endif /* HAVE_IPV6 */ - else { - zlog_err("%s: Local addr %s not found", __func__, - src_str); - return -1; - } + memset(&src_prefix, 0, sizeof(struct prefix)); + if (strcmp(ZEBRA_PTM_INVALID_SRC_IP, src_str)) { + if (str2prefix(src_str, &src_prefix) == 0) { + zlog_err("%s: Local addr %s not found", __func__, + src_str); + return -1; } + } - if_bfd_session_down(ifp, &dest_prefix, &src_prefix); + if (!strcmp (bfdst_str, ZEBRA_PTM_BFDSTATUS_DOWN_STR)) { + if_bfd_session_update(ifp, &dest_prefix, &src_prefix, BFD_STATUS_DOWN); + } else { + if_bfd_session_update(ifp, &dest_prefix, &src_prefix, BFD_STATUS_UP); } return 0; @@ -718,6 +704,10 @@ zebra_ptm_bfd_dst_register (struct zserv *client, int sock, u_short length, if_name); } + sprintf(tmp_buf, "%d", 1); + ptm_lib_append_msg(ptm_hdl, out_ctxt, ZEBRA_PTM_BFD_SEND_EVENT, + tmp_buf); + ptm_lib_complete_msg(ptm_hdl, out_ctxt, ptm_cb.out_data, &data_len); if (IS_ZEBRA_DEBUG_SEND) |