summaryrefslogtreecommitdiffstats
path: root/ospf6d
diff options
context:
space:
mode:
authorradhika <radhika@cumulusnetworks.com>2015-08-31 23:56:11 +0200
committerradhika <radhika@cumulusnetworks.com>2015-08-31 23:56:11 +0200
commit68fe91d6c7731fba199a7f4bd53e12a559e3b3de (patch)
tree03d95c7f20f6fa589c3b9a3a84fdff76cc58956e /ospf6d
parentBGP: Fix MD5 authentication for unnumbered neighbors (diff)
downloadfrr-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 'ospf6d')
-rw-r--r--ospf6d/ospf6_bfd.c95
-rw-r--r--ospf6d/ospf6_bfd.h10
-rw-r--r--ospf6d/ospf6_interface.c5
-rw-r--r--ospf6d/ospf6_interface.h2
-rw-r--r--ospf6d/ospf6_neighbor.c4
-rw-r--r--ospf6d/ospf6_neighbor.h3
6 files changed, 103 insertions, 16 deletions
diff --git a/ospf6d/ospf6_bfd.c b/ospf6d/ospf6_bfd.c
index e30f4962d..5ef4ab4ca 100644
--- a/ospf6d/ospf6_bfd.c
+++ b/ospf6d/ospf6_bfd.c
@@ -46,6 +46,27 @@
extern struct zclient *zclient;
/*
+ * ospf6_bfd_info_free - Free BFD info structure
+ */
+void
+ospf6_bfd_info_free(void **bfd_info)
+{
+ bfd_info_free((struct bfd_info **) bfd_info);
+}
+
+/*
+ * ospf6_bfd_show_info - Show BFD info structure
+ */
+void
+ospf6_bfd_show_info(struct vty *vty, void *bfd_info, int param_only)
+{
+ if (param_only)
+ bfd_show_param(vty, bfd_info, 1, 0, 0, NULL);
+ else
+ bfd_show_info(vty, bfd_info, 0, 1, 0, NULL);
+}
+
+/*
* ospf6_bfd_reg_dereg_nbr - Register/Deregister a neighbor with BFD through
* zebra for starting/stopping the monitoring of
* the neighbor rechahability.
@@ -102,6 +123,11 @@ ospf6_bfd_reg_dereg_all_nbr (struct ospf6_interface *oi, int command)
for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, node, on))
{
+ if (command != ZEBRA_BFD_DEST_DEREGISTER)
+ ospf6_bfd_info_nbr_create(oi, on);
+ else
+ bfd_info_free((struct bfd_info **)&on->bfd_info);
+
if (on->state < OSPF6_NEIGHBOR_TWOWAY)
continue;
@@ -151,13 +177,13 @@ ospf6_bfd_nbr_replay (int command, struct zclient *client, zebra_size_t length)
}
/*
- * ospf6_bfd_interface_dest_down - Find the neighbor for which the BFD status
- * has changed and bring down the neighbor
- * connectivity.
+ * ospf6_bfd_interface_dest_update - Find the neighbor for which the BFD status
+ * has changed and bring down the neighbor
+ * connectivity if BFD down is received.
*/
static int
-ospf6_bfd_interface_dest_down (int command, struct zclient *zclient,
- zebra_size_t length)
+ospf6_bfd_interface_dest_update (int command, struct zclient *zclient,
+ zebra_size_t length)
{
struct interface *ifp;
struct ospf6_interface *oi;
@@ -166,8 +192,12 @@ ospf6_bfd_interface_dest_down (int command, struct zclient *zclient,
struct prefix sp;
struct listnode *node, *nnode;
char dst[64];
+ int status;
+ int old_status;
+ struct bfd_info *bfd_info;
+ struct timeval tv;
- ifp = bfd_get_peer_info(zclient->ibuf, &dp, &sp);
+ ifp = bfd_get_peer_info(zclient->ibuf, &dp, &sp, &status);
if ((ifp == NULL) || (dp.family != AF_INET6))
return 0;
@@ -176,7 +206,8 @@ ospf6_bfd_interface_dest_down (int command, struct zclient *zclient,
{
char buf[128];
prefix2str(&dp, buf, sizeof(buf));
- zlog_debug("Zebra: interface %s bfd destination %s down", ifp->name, buf);
+ zlog_debug("Zebra: interface %s bfd destination %s %s", ifp->name, buf,
+ bfd_get_status_str(status));
}
@@ -192,17 +223,57 @@ ospf6_bfd_interface_dest_down (int command, struct zclient *zclient,
if (IS_OSPF6_DEBUG_NEIGHBOR (EVENT))
{
inet_ntop (AF_INET6, &on->linklocal_addr, dst, sizeof (dst));
- zlog_debug ("[%s:%s]: BFD Down", ifp->name, dst);
+ zlog_debug ("[%s:%s]: BFD %s", ifp->name, dst,
+ bfd_get_status_str(status));
}
- THREAD_OFF (on->inactivity_timer);
- thread_add_event (master, inactivity_timer, on, 0);
+ if (!on->bfd_info)
+ continue;
+
+ bfd_info = (struct bfd_info *)on->bfd_info;
+ if (bfd_info->status == status)
+ continue;
+
+ old_status = bfd_info->status;
+ bfd_info->status = status;
+ quagga_gettime (QUAGGA_CLK_MONOTONIC, &tv);
+ bfd_info->last_update = tv.tv_sec;
+
+ if ((status == BFD_STATUS_DOWN) && (old_status == BFD_STATUS_UP))
+ {
+ THREAD_OFF (on->inactivity_timer);
+ thread_add_event (master, inactivity_timer, on, 0);
+ }
}
return 0;
}
/*
+ * ospf6_bfd_info_nbr_create - Create/update BFD information for a neighbor.
+ */
+void
+ospf6_bfd_info_nbr_create (struct ospf6_interface *oi,
+ struct ospf6_neighbor *on)
+{
+ struct bfd_info *oi_bfd_info;
+ struct bfd_info *on_bfd_info;
+
+ if (!oi->bfd_info)
+ return;
+
+ oi_bfd_info = (struct bfd_info *)oi->bfd_info;
+
+ if (!on->bfd_info)
+ on->bfd_info = bfd_info_create();
+
+ on_bfd_info = (struct bfd_info *)on->bfd_info;
+ on_bfd_info->detect_mult = oi_bfd_info->detect_mult;
+ on_bfd_info->desired_min_tx = oi_bfd_info->desired_min_tx;
+ on_bfd_info->required_min_rx = oi_bfd_info->required_min_rx;
+}
+
+/*
* ospf6_bfd_write_config - Write the interface BFD configuration.
*/
void
@@ -321,7 +392,7 @@ DEFUN (no_ipv6_ospf6_bfd,
if (oi->bfd_info)
{
ospf6_bfd_reg_dereg_all_nbr(oi, ZEBRA_BFD_DEST_DEREGISTER);
- bfd_info_free(&(oi->bfd_info));
+ bfd_info_free((struct bfd_info **)&(oi->bfd_info));
}
return CMD_SUCCESS;
@@ -331,7 +402,7 @@ void
ospf6_bfd_init(void)
{
/* Initialize BFD client functions */
- zclient->interface_bfd_dest_down = ospf6_bfd_interface_dest_down;
+ zclient->interface_bfd_dest_update = ospf6_bfd_interface_dest_update;
zclient->bfd_dest_replay = ospf6_bfd_nbr_replay;
/* Install BFD command */
diff --git a/ospf6d/ospf6_bfd.h b/ospf6d/ospf6_bfd.h
index eaaf15785..11b13d66f 100644
--- a/ospf6d/ospf6_bfd.h
+++ b/ospf6d/ospf6_bfd.h
@@ -33,4 +33,14 @@ ospf6_bfd_trigger_event(struct ospf6_neighbor *nbr, int old_state, int state);
extern void
ospf6_bfd_write_config(struct vty *vty, struct ospf6_interface *oi);
+extern void
+ospf6_bfd_info_nbr_create (struct ospf6_interface *oi,
+ struct ospf6_neighbor *on);
+
+extern void
+ospf6_bfd_info_free(void **bfd_info);
+
+extern void
+ospf6_bfd_show_info(struct vty *vty, void *bfd_info, int param_only);
+
#endif /* OSPF6_BFD_H */
diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c
index 63783cc8f..21751656b 100644
--- a/ospf6d/ospf6_interface.c
+++ b/ospf6d/ospf6_interface.c
@@ -29,7 +29,6 @@
#include "prefix.h"
#include "plist.h"
#include "zclient.h"
-#include "bfd.h"
#include "ospf6_lsa.h"
#include "ospf6_lsdb.h"
@@ -263,7 +262,7 @@ ospf6_interface_delete (struct ospf6_interface *oi)
if (oi->plist_name)
XFREE (MTYPE_PREFIX_LIST_STR, oi->plist_name);
- bfd_info_free(&(oi->bfd_info));
+ ospf6_bfd_info_free(&(oi->bfd_info));
XFREE (MTYPE_OSPF6_IF, oi);
}
@@ -977,7 +976,7 @@ ospf6_interface_show (struct vty *vty, struct interface *ifp)
for (lsa = ospf6_lsdb_head (oi->lsack_list); lsa;
lsa = ospf6_lsdb_next (lsa))
vty_out (vty, " %s%s", lsa->name, VNL);
-
+ ospf6_bfd_show_info(vty, oi->bfd_info, 1);
return 0;
}
diff --git a/ospf6d/ospf6_interface.h b/ospf6d/ospf6_interface.h
index 3f5c5f041..6ef9e3782 100644
--- a/ospf6d/ospf6_interface.h
+++ b/ospf6d/ospf6_interface.h
@@ -115,7 +115,7 @@ struct ospf6_interface
char *plist_name;
/* BFD information */
- struct bfd_info *bfd_info;
+ void *bfd_info;
};
/* interface state */
diff --git a/ospf6d/ospf6_neighbor.c b/ospf6d/ospf6_neighbor.c
index c5edd226d..1636c2628 100644
--- a/ospf6d/ospf6_neighbor.c
+++ b/ospf6d/ospf6_neighbor.c
@@ -103,6 +103,8 @@ ospf6_neighbor_create (u_int32_t router_id, struct ospf6_interface *oi)
on->lsack_list = ospf6_lsdb_create (on);
listnode_add_sort (oi->neighbor_list, on);
+
+ ospf6_bfd_info_nbr_create(oi, on);
return on;
}
@@ -139,6 +141,7 @@ ospf6_neighbor_delete (struct ospf6_neighbor *on)
THREAD_OFF (on->thread_send_lsupdate);
THREAD_OFF (on->thread_send_lsack);
+ ospf6_bfd_info_free(&on->bfd_info);
XFREE (MTYPE_OSPF6_NEIGHBOR, on);
}
@@ -815,6 +818,7 @@ ospf6_neighbor_show_detail (struct vty *vty, struct ospf6_neighbor *on)
lsa = ospf6_lsdb_next (lsa))
vty_out (vty, " %s%s", lsa->name, VNL);
+ ospf6_bfd_show_info(vty, on->bfd_info, 0);
}
DEFUN (show_ipv6_ospf6_neighbor,
diff --git a/ospf6d/ospf6_neighbor.h b/ospf6d/ospf6_neighbor.h
index cba2cb99d..fad7fd578 100644
--- a/ospf6d/ospf6_neighbor.h
+++ b/ospf6d/ospf6_neighbor.h
@@ -96,6 +96,9 @@ struct ospf6_neighbor
struct thread *thread_send_lsreq;
struct thread *thread_send_lsupdate;
struct thread *thread_send_lsack;
+
+ /* BFD information */
+ void *bfd_info;
};
/* Neighbor state */