diff options
author | Rafael Zalamena <rzalamena@opensourcerouting.org> | 2018-07-11 20:55:12 +0200 |
---|---|---|
committer | Rafael Zalamena <rzalamena@opensourcerouting.org> | 2018-08-08 23:25:08 +0200 |
commit | 971532e2e73089be449586240fabe5d42ebf7c4b (patch) | |
tree | 1656488c11b1b218ea76fa75121856780a1f783b | |
parent | bfdd: show single hop local-address (diff) | |
download | frr-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.c | 22 | ||||
-rw-r--r-- | zebra/zebra_ptm.c | 33 |
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); |