]> git.proxmox.com Git - mirror_frr.git/commitdiff
bfdd: send replay request on zebra connection
authorRafael Zalamena <rzalamena@opensourcerouting.org>
Wed, 11 Jul 2018 18:55:12 +0000 (15:55 -0300)
committerRafael Zalamena <rzalamena@opensourcerouting.org>
Wed, 8 Aug 2018 21:25:08 +0000 (18:25 -0300)
This will make `bfdd` synchronize with its client when zebra dies or
bfdd is restarted.

Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
bfdd/ptm_adapter.c
zebra/zebra_ptm.c

index 5e79be91f831421f53bcebb63a9e56756445d234..28e332626473ff26ad9bda88f3a558e94e0cd1e2 100644 (file)
@@ -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)
index 5a69568fe8096f2474942b1ab5f43906f9001244..76e427570b81af26c59a512b87c9be967f4efb55 100644 (file)
@@ -1468,6 +1468,7 @@ void zebra_ptm_bfd_dst_replay(ZAPI_HANDLER_ARGS)
 {
        struct stream *msgc;
        size_t zmsglen, zhdrlen;
+       uint32_t cmd;
 
        /*
         * NOTE:
@@ -1479,6 +1480,21 @@ void zebra_ptm_bfd_dst_replay(ZAPI_HANDLER_ARGS)
                zlog_debug("bfd_dst_update msg from client %s: length=%d",
                           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
@@ -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);