summaryrefslogtreecommitdiffstats
path: root/bfdd/ptm_adapter.c
diff options
context:
space:
mode:
authorRafael Zalamena <rzalamena@opensourcerouting.org>2019-01-10 20:13:32 +0100
committerRafael Zalamena <rzalamena@opensourcerouting.org>2019-01-10 20:18:35 +0100
commit80edb6758fdc7b81032f3acc7f01930cd8d1fe80 (patch)
tree4794da913c9f7c91b4e40166b2241f747d08d1da /bfdd/ptm_adapter.c
parentMerge pull request #3565 from rhonda/patch-1 (diff)
downloadfrr-80edb6758fdc7b81032f3acc7f01930cd8d1fe80.tar.xz
frr-80edb6758fdc7b81032f3acc7f01930cd8d1fe80.zip
bfdd: use zebra to learn about network interfaces
Don't use system calls to search for and get interface information, instead use the FRR provided API to learn and cache it. Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
Diffstat (limited to '')
-rw-r--r--bfdd/ptm_adapter.c49
1 files changed, 46 insertions, 3 deletions
diff --git a/bfdd/ptm_adapter.c b/bfdd/ptm_adapter.c
index f9c7c16fb..a57167376 100644
--- a/bfdd/ptm_adapter.c
+++ b/bfdd/ptm_adapter.c
@@ -189,7 +189,10 @@ int ptm_bfd_notify(struct bfd_session *bs)
stream_putl(msg, ZEBRA_INTERFACE_BFD_DEST_UPDATE);
/* NOTE: Interface is a shortcut to avoid comparing source address. */
- stream_putl(msg, bs->ifindex);
+ if (bs->ifp != NULL)
+ stream_putl(msg, bs->ifp->ifindex);
+ else
+ stream_putl(msg, IFINDEX_INTERNAL);
/* BFD destination prefix information. */
if (BFD_CHECK_FLAG(bs->flags, BFD_SESS_FLAG_MH))
@@ -287,6 +290,7 @@ stream_failure:
static int _ptm_msg_read(struct stream *msg, int command,
struct bfd_peer_cfg *bpc, struct ptm_client **pc)
{
+ struct interface *ifp;
uint32_t pid;
uint8_t ttl __attribute__((unused));
size_t ifnamelen;
@@ -393,9 +397,19 @@ static int _ptm_msg_read(struct stream *msg, int command,
*/
if (bpc->bpc_ipv4 == false
&& IN6_IS_ADDR_LINKLOCAL(
- &bpc->bpc_peer.sa_sin6.sin6_addr))
+ &bpc->bpc_peer.sa_sin6.sin6_addr)) {
+ ifp = if_lookup_by_name_all_vrf(
+ bpc->bpc_localif);
+ if (ifp == NULL) {
+ log_error(
+ "ptm-read: interface %s doesn't exists",
+ bpc->bpc_localif);
+ return -1;
+ }
+
bpc->bpc_peer.sa_sin6.sin6_scope_id =
- ptm_bfd_fetch_ifindex(bpc->bpc_localif);
+ ifp->ifindex;
+ }
}
}
@@ -576,9 +590,34 @@ static void bfdd_zebra_connected(struct zclient *zc)
stream_putl(msg, ZEBRA_BFD_DEST_REPLAY);
stream_putw_at(msg, 0, stream_get_endp(msg));
+ /* Ask for interfaces information. */
+ zclient_create_header(msg, ZEBRA_INTERFACE_ADD, VRF_DEFAULT);
+
+ /* Send requests. */
zclient_send_message(zclient);
}
+static int bfdd_interface_update(int cmd, struct zclient *zc, uint16_t len,
+ vrf_id_t vrfid)
+{
+ /*
+ * `zebra_interface_add_read` will handle the interface creation
+ * on `lib/if.c`. We'll use that data structure instead of
+ * rolling our own.
+ */
+ if (cmd == ZEBRA_INTERFACE_ADD) {
+ zebra_interface_add_read(zc->ibuf, vrfid);
+ return 0;
+ }
+
+ /* Update interface information. */
+ zebra_interface_state_read(zc->ibuf, vrfid);
+
+ /* TODO: stop all sessions using this interface. */
+
+ return 0;
+}
+
void bfdd_zclient_init(struct zebra_privs_t *bfdd_priv)
{
zclient = zclient_new(master, &zclient_options_default);
@@ -594,6 +633,10 @@ void bfdd_zclient_init(struct zebra_privs_t *bfdd_priv)
/* Send replay request on zebra connect. */
zclient->zebra_connected = bfdd_zebra_connected;
+
+ /* Learn interfaces from zebra instead of the OS. */
+ zclient->interface_add = bfdd_interface_update;
+ zclient->interface_delete = bfdd_interface_update;
}
void bfdd_zclient_stop(void)