summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael Zalamena <rzalamena@opensourcerouting.org>2018-07-11 20:55:12 +0200
committerRafael Zalamena <rzalamena@opensourcerouting.org>2018-08-08 23:25:08 +0200
commit971532e2e73089be449586240fabe5d42ebf7c4b (patch)
tree1656488c11b1b218ea76fa75121856780a1f783b
parentbfdd: show single hop local-address (diff)
downloadfrr-971532e2e73089be449586240fabe5d42ebf7c4b.tar.xz
frr-971532e2e73089be449586240fabe5d42ebf7c4b.zip
bfdd: send replay request on zebra connection
This will make `bfdd` synchronize with its client when zebra dies or bfdd is restarted. Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
-rw-r--r--bfdd/ptm_adapter.c22
-rw-r--r--zebra/zebra_ptm.c33
2 files changed, 48 insertions, 7 deletions
diff --git a/bfdd/ptm_adapter.c b/bfdd/ptm_adapter.c
index 5e79be91f..28e332626 100644
--- a/bfdd/ptm_adapter.c
+++ b/bfdd/ptm_adapter.c
@@ -180,6 +180,9 @@ int ptm_bfd_notify(struct bfd_session *bs)
/* TODO: VRF handling */
zclient_create_header(msg, ZEBRA_BFD_DEST_REPLAY, VRF_DEFAULT);
+ /* This header will be handled by `zebra_ptm.c`. */
+ stream_putl(msg, ZEBRA_INTERFACE_BFD_DEST_UPDATE);
+
/* NOTE: Interface is a shortcut to avoid comparing source address. */
stream_putl(msg, bs->ifindex);
@@ -515,6 +518,22 @@ stream_failure:
return -1;
}
+static void bfdd_zebra_connected(struct zclient *zc)
+{
+ struct stream *msg = zc->obuf;
+
+ /*
+ * The replay is an empty message just to trigger client daemons
+ * configuration replay.
+ */
+ stream_reset(msg);
+ zclient_create_header(msg, ZEBRA_BFD_DEST_REPLAY, VRF_DEFAULT);
+ stream_putl(msg, ZEBRA_BFD_DEST_REPLAY);
+ stream_putw_at(msg, 0, stream_get_endp(msg));
+
+ zclient_send_message(zclient);
+}
+
void bfdd_zclient_init(struct zebra_privs_t *bfdd_priv)
{
zclient = zclient_new_notify(master, &zclient_options_default);
@@ -527,6 +546,9 @@ void bfdd_zclient_init(struct zebra_privs_t *bfdd_priv)
* avoid having to create too many handlers.
*/
zclient->bfd_dest_replay = bfdd_replay;
+
+ /* Send replay request on zebra connect. */
+ zclient->zebra_connected = bfdd_zebra_connected;
}
void bfdd_zclient_stop(void)
diff --git a/zebra/zebra_ptm.c b/zebra/zebra_ptm.c
index 5a69568fe..76e427570 100644
--- a/zebra/zebra_ptm.c
+++ b/zebra/zebra_ptm.c
@@ -1468,6 +1468,7 @@ void zebra_ptm_bfd_dst_replay(ZAPI_HANDLER_ARGS)
{
struct stream *msgc;
size_t zmsglen, zhdrlen;
+ uint32_t cmd;
/*
* NOTE:
@@ -1480,6 +1481,21 @@ void zebra_ptm_bfd_dst_replay(ZAPI_HANDLER_ARGS)
zebra_route_string(client->proto), hdr->length);
/*
+ * Client messages must be re-routed, otherwise do the `bfdd`
+ * special treatment.
+ */
+ if (client->proto != ZEBRA_ROUTE_BFD) {
+ _zebra_ptm_reroute(client, msg, ZEBRA_BFD_DEST_REPLAY);
+ return;
+ }
+
+ /* Figure out if this is an DEST_UPDATE or DEST_REPLAY. */
+ if (stream_getl2(msg, &cmd) == false) {
+ zlog_err("%s: expected at least 4 bytes (command)", __func__);
+ return;
+ }
+
+ /*
* Don't modify message in the zebra API. In order to do that we
* need to allocate a new message stream and copy the message
* provided by zebra.
@@ -1491,16 +1507,19 @@ void zebra_ptm_bfd_dst_replay(ZAPI_HANDLER_ARGS)
}
/* Calculate our header size plus the message contents. */
- zhdrlen = ZEBRA_HEADER_SIZE;
- zmsglen = msg->endp - msg->getp;
- memcpy(msgc->data + zhdrlen, msg->data + msg->getp, zmsglen);
+ if (cmd != ZEBRA_BFD_DEST_REPLAY) {
+ zhdrlen = ZEBRA_HEADER_SIZE;
+ zmsglen = msg->endp - msg->getp;
+ memcpy(msgc->data + zhdrlen, msg->data + msg->getp, zmsglen);
- zclient_create_header(msgc, ZEBRA_INTERFACE_BFD_DEST_UPDATE,
- zvrf_id(zvrf));
+ zclient_create_header(msgc, cmd, zvrf_id(zvrf));
+
+ msgc->getp = 0;
+ msgc->endp = zhdrlen + zmsglen;
+ } else
+ zclient_create_header(msgc, cmd, zvrf_id(zvrf));
/* Update the data pointers. */
- msgc->getp = 0;
- msgc->endp = zhdrlen + zmsglen;
stream_putw_at(msgc, 0, stream_get_endp(msgc));
zebra_ptm_send_clients(msgc);