summaryrefslogtreecommitdiff
path: root/lib/zclient.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/zclient.c')
-rw-r--r--lib/zclient.c80
1 files changed, 76 insertions, 4 deletions
diff --git a/lib/zclient.c b/lib/zclient.c
index 9b1ff7237f..aa5fa082a1 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -3121,6 +3121,7 @@ int zclient_send_opaque(struct zclient *zclient, uint32_t type,
{
int ret;
struct stream *s;
+ uint16_t flags = 0;
/* Check buffer size */
if (STREAM_SIZE(zclient->obuf) <
@@ -3132,8 +3133,9 @@ int zclient_send_opaque(struct zclient *zclient, uint32_t type,
zclient_create_header(s, ZEBRA_OPAQUE_MESSAGE, VRF_DEFAULT);
- /* Send sub-type */
+ /* Send sub-type and flags */
stream_putl(s, type);
+ stream_putw(s, flags);
/* Send opaque data */
stream_write(s, data, datasize);
@@ -3147,6 +3149,77 @@ int zclient_send_opaque(struct zclient *zclient, uint32_t type,
}
/*
+ * Send an OPAQUE message to a specific zclient. The contents are opaque
+ * to zebra.
+ */
+int zclient_send_opaque_unicast(struct zclient *zclient, uint32_t type,
+ uint8_t proto, uint16_t instance,
+ uint32_t session_id, const uint8_t *data,
+ size_t datasize)
+{
+ int ret;
+ struct stream *s;
+ uint16_t flags = 0;
+
+ /* Check buffer size */
+ if (STREAM_SIZE(zclient->obuf) <
+ (ZEBRA_HEADER_SIZE + sizeof(struct zapi_opaque_msg) + datasize))
+ return -1;
+
+ s = zclient->obuf;
+ stream_reset(s);
+
+ zclient_create_header(s, ZEBRA_OPAQUE_MESSAGE, VRF_DEFAULT);
+
+ /* Send sub-type and flags */
+ SET_FLAG(flags, ZAPI_OPAQUE_FLAG_UNICAST);
+ stream_putl(s, type);
+ stream_putw(s, flags);
+
+ /* Send destination client info */
+ stream_putc(s, proto);
+ stream_putw(s, instance);
+ stream_putl(s, session_id);
+
+ /* 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;
+}
+
+/*
+ * Decode incoming opaque message into info struct
+ */
+int zclient_opaque_decode(struct stream *s, struct zapi_opaque_msg *info)
+{
+ memset(info, 0, sizeof(*info));
+
+ /* Decode subtype and flags */
+ STREAM_GETL(s, info->type);
+ STREAM_GETW(s, info->flags);
+
+ /* Decode unicast client info if present */
+ if (CHECK_FLAG(info->flags, ZAPI_OPAQUE_FLAG_UNICAST)) {
+ STREAM_GETC(s, info->proto);
+ STREAM_GETW(s, info->instance);
+ STREAM_GETL(s, info->session_id);
+ }
+
+ info->len = STREAM_READABLE(s);
+
+ return 0;
+
+stream_failure:
+
+ return -1;
+}
+
+/*
* Send a registration request for opaque messages with a specified subtype.
*/
int zclient_register_opaque(struct zclient *zclient, uint32_t type)
@@ -3204,9 +3277,8 @@ int zclient_unregister_opaque(struct zclient *zclient, uint32_t type)
return ret;
}
-/* Utility to parse opaque registration info */
-int zapi_parse_opaque_reg(struct stream *s,
- struct zapi_opaque_reg_info *info)
+/* Utility to decode opaque registration info */
+int zapi_opaque_reg_decode(struct stream *s, struct zapi_opaque_reg_info *info)
{
STREAM_GETL(s, info->type);
STREAM_GETC(s, info->proto);