diff options
| author | Mark Stapp <mjs@voltanet.io> | 2020-04-06 16:10:13 -0400 |
|---|---|---|
| committer | Mark Stapp <mjs@voltanet.io> | 2020-06-02 08:20:54 -0400 |
| commit | ff491140956129580a7d68ea8510b521cce80c9d (patch) | |
| tree | 076b1f5d5ab772763c5727e8c5f48a22fdb7fdfd /lib/zclient.c | |
| parent | f8c511cddb9bc54d190d8bfcded339ed7f3ec219 (diff) | |
lib: add OPAQUE zapi message
Add a zapi message type designed to carry opaque data. Add
'send' api, and prototype for client handler function. Also
add registration/unreg messages, so that clients can 'subscribe'
to receive these messages as they're passing through zebra.
Signed-off-by: Mark Stapp <mjs@voltanet.io>
Diffstat (limited to 'lib/zclient.c')
| -rw-r--r-- | lib/zclient.c | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/lib/zclient.c b/lib/zclient.c index 02532e7069..9b1ff7237f 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -3112,6 +3112,114 @@ static void zclient_mlag_handle_msg(ZAPI_CALLBACK_ARGS) (*zclient->mlag_handle_msg)(zclient->ibuf, length); } +/* + * Send an OPAQUE message, contents opaque to zebra. The message header + * is a message subtype. + */ +int zclient_send_opaque(struct zclient *zclient, uint32_t type, + const uint8_t *data, size_t datasize) +{ + int ret; + struct stream *s; + + /* Check buffer size */ + if (STREAM_SIZE(zclient->obuf) < + (ZEBRA_HEADER_SIZE + sizeof(type) + datasize)) + return -1; + + s = zclient->obuf; + stream_reset(s); + + zclient_create_header(s, ZEBRA_OPAQUE_MESSAGE, VRF_DEFAULT); + + /* Send sub-type */ + stream_putl(s, type); + + /* Send opaque data */ + stream_write(s, data, datasize); + + /* Put length into the header at the start of the stream. */ + stream_putw_at(s, 0, stream_get_endp(s)); + + ret = zclient_send_message(zclient); + + return ret; +} + +/* + * Send a registration request for opaque messages with a specified subtype. + */ +int zclient_register_opaque(struct zclient *zclient, uint32_t type) +{ + int ret; + struct stream *s; + + s = zclient->obuf; + stream_reset(s); + + zclient_create_header(s, ZEBRA_OPAQUE_REGISTER, VRF_DEFAULT); + + /* Send sub-type */ + stream_putl(s, type); + + /* Add zclient info */ + stream_putc(s, zclient->redist_default); + stream_putw(s, zclient->instance); + stream_putl(s, zclient->session_id); + + /* Put length at the first point of the stream. */ + stream_putw_at(s, 0, stream_get_endp(s)); + + ret = zclient_send_message(zclient); + + return ret; +} + +/* + * Send an un-registration request for a specified opaque subtype. + */ +int zclient_unregister_opaque(struct zclient *zclient, uint32_t type) +{ + int ret; + struct stream *s; + + s = zclient->obuf; + stream_reset(s); + + zclient_create_header(s, ZEBRA_OPAQUE_UNREGISTER, VRF_DEFAULT); + + /* Send sub-type */ + stream_putl(s, type); + + /* Add zclient info */ + stream_putc(s, zclient->redist_default); + stream_putw(s, zclient->instance); + stream_putl(s, zclient->session_id); + + /* Put length at the first point of the stream. */ + stream_putw_at(s, 0, stream_get_endp(s)); + + ret = zclient_send_message(zclient); + + return ret; +} + +/* Utility to parse opaque registration info */ +int zapi_parse_opaque_reg(struct stream *s, + struct zapi_opaque_reg_info *info) +{ + STREAM_GETL(s, info->type); + STREAM_GETC(s, info->proto); + STREAM_GETW(s, info->instance); + STREAM_GETL(s, info->session_id); + + return 0; + +stream_failure: + + return -1; +} + /* Zebra client message read function. */ static int zclient_read(struct thread *thread) { @@ -3417,6 +3525,22 @@ static int zclient_read(struct thread *thread) break; case ZEBRA_ERROR: zclient_handle_error(command, zclient, length, vrf_id); + break; + case ZEBRA_OPAQUE_MESSAGE: + if (zclient->opaque_msg_handler) + (*zclient->opaque_msg_handler)(command, zclient, length, + vrf_id); + break; + case ZEBRA_OPAQUE_REGISTER: + if (zclient->opaque_register_handler) + (*zclient->opaque_register_handler)(command, zclient, + length, vrf_id); + break; + case ZEBRA_OPAQUE_UNREGISTER: + if (zclient->opaque_unregister_handler) + (*zclient->opaque_unregister_handler)(command, zclient, + length, vrf_id); + break; default: break; } |
