summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/link_state.c46
-rw-r--r--lib/zclient.c88
-rw-r--r--lib/zclient.h25
-rw-r--r--zebra/zebra_opaque.c6
4 files changed, 98 insertions, 67 deletions
diff --git a/lib/link_state.c b/lib/link_state.c
index 58727a568b..6537f881ce 100644
--- a/lib/link_state.c
+++ b/lib/link_state.c
@@ -1138,31 +1138,13 @@ int ls_unregister(struct zclient *zclient, bool server)
int ls_request_sync(struct zclient *zclient)
{
- struct stream *s;
- uint16_t flags = 0;
-
/* Check buffer size */
if (STREAM_SIZE(zclient->obuf)
< (ZEBRA_HEADER_SIZE + 3 * sizeof(uint32_t)))
return -1;
- s = zclient->obuf;
- stream_reset(s);
-
- zclient_create_header(s, ZEBRA_OPAQUE_MESSAGE, VRF_DEFAULT);
-
- /* Set type and flags */
- stream_putl(s, LINK_STATE_SYNC);
- stream_putw(s, flags);
- /* Send destination client info */
- stream_putc(s, zclient->redist_default);
- stream_putw(s, zclient->instance);
- stream_putl(s, zclient->session_id);
-
- /* Put length into the header at the start of the stream. */
- stream_putw_at(s, 0, stream_get_endp(s));
-
- return zclient_send_message(zclient);
+ /* No data with this message */
+ return zclient_send_opaque(zclient, LINK_STATE_SYNC, NULL, 0);
}
static struct ls_node *ls_parse_node(struct stream *s)
@@ -1623,23 +1605,15 @@ int ls_send_msg(struct zclient *zclient, struct ls_message *msg,
(ZEBRA_HEADER_SIZE + sizeof(uint32_t) + sizeof(msg)))
return -1;
+ /* Init the message, then encode the data inline. */
+ if (dst == NULL)
+ zapi_opaque_init(zclient, LINK_STATE_UPDATE, flags);
+ else
+ zapi_opaque_unicast_init(zclient, LINK_STATE_UPDATE, flags,
+ dst->proto, dst->instance,
+ dst->session_id);
+
s = zclient->obuf;
- stream_reset(s);
-
- zclient_create_header(s, ZEBRA_OPAQUE_MESSAGE, VRF_DEFAULT);
-
- /* Set sub-type, flags and destination for unicast message */
- stream_putl(s, LINK_STATE_UPDATE);
- if (dst != NULL) {
- SET_FLAG(flags, ZAPI_OPAQUE_FLAG_UNICAST);
- stream_putw(s, flags);
- /* Send destination client info */
- stream_putc(s, dst->proto);
- stream_putw(s, dst->instance);
- stream_putl(s, dst->session_id);
- } else {
- stream_putw(s, flags);
- }
/* Format Link State message */
if (ls_format_msg(s, msg) < 0) {
diff --git a/lib/zclient.c b/lib/zclient.c
index 8526cbfaa1..b3b3c92302 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -3824,6 +3824,53 @@ enum zclient_send_status zclient_send_mlag_data(struct zclient *client,
}
/*
+ * Init/header setup for opaque zapi messages
+ */
+enum zclient_send_status zapi_opaque_init(struct zclient *zclient,
+ uint32_t type, uint16_t flags)
+{
+ struct stream *s;
+
+ s = zclient->obuf;
+ stream_reset(s);
+
+ zclient_create_header(s, ZEBRA_OPAQUE_MESSAGE, VRF_DEFAULT);
+
+ /* Send sub-type and flags */
+ stream_putl(s, type);
+ stream_putw(s, flags);
+
+ /* Source daemon identifiers */
+ stream_putc(s, zclient->redist_default);
+ stream_putw(s, zclient->instance);
+ stream_putl(s, zclient->session_id);
+
+ return ZCLIENT_SEND_SUCCESS;
+}
+
+/*
+ * Init, header setup for opaque unicast messages.
+ */
+enum zclient_send_status
+zapi_opaque_unicast_init(struct zclient *zclient, uint32_t type, uint16_t flags,
+ uint8_t proto, uint16_t instance, uint32_t session_id)
+{
+ struct stream *s;
+
+ s = zclient->obuf;
+
+ /* Common init */
+ zapi_opaque_init(zclient, type, flags | ZAPI_OPAQUE_FLAG_UNICAST);
+
+ /* Send destination client info */
+ stream_putc(s, proto);
+ stream_putw(s, instance);
+ stream_putl(s, session_id);
+
+ return ZCLIENT_SEND_SUCCESS;
+}
+
+/*
* Send an OPAQUE message, contents opaque to zebra. The message header
* is a message subtype.
*/
@@ -3840,16 +3887,12 @@ enum zclient_send_status zclient_send_opaque(struct zclient *zclient,
return ZCLIENT_SEND_FAILURE;
s = zclient->obuf;
- stream_reset(s);
- zclient_create_header(s, ZEBRA_OPAQUE_MESSAGE, VRF_DEFAULT);
-
- /* Send sub-type and flags */
- stream_putl(s, type);
- stream_putw(s, flags);
+ zapi_opaque_init(zclient, type, flags);
/* Send opaque data */
- stream_write(s, data, datasize);
+ if (datasize > 0)
+ 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));
@@ -3876,22 +3919,14 @@ zclient_send_opaque_unicast(struct zclient *zclient, uint32_t type,
return ZCLIENT_SEND_FAILURE;
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);
+ /* Common init */
+ zapi_opaque_unicast_init(zclient, type, flags, proto, instance,
+ session_id);
/* Send opaque data */
- stream_write(s, data, datasize);
+ if (datasize > 0)
+ 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));
@@ -3910,11 +3945,16 @@ int zclient_opaque_decode(struct stream *s, struct zapi_opaque_msg *info)
STREAM_GETL(s, info->type);
STREAM_GETW(s, info->flags);
- /* Decode unicast client info if present */
+ /* Decode sending daemon info */
+ STREAM_GETC(s, info->src_proto);
+ STREAM_GETW(s, info->src_instance);
+ STREAM_GETL(s, info->src_session_id);
+
+ /* Decode unicast destination 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);
+ STREAM_GETC(s, info->dest_proto);
+ STREAM_GETW(s, info->dest_instance);
+ STREAM_GETL(s, info->dest_session_id);
}
info->len = STREAM_READABLE(s);
diff --git a/lib/zclient.h b/lib/zclient.h
index e43393fd70..fe296fe950 100644
--- a/lib/zclient.h
+++ b/lib/zclient.h
@@ -1176,16 +1176,33 @@ zclient_send_opaque_unicast(struct zclient *zclient, uint32_t type,
uint32_t session_id, const uint8_t *data,
size_t datasize);
+/* Init functions also provided for clients who want to encode their
+ * data inline into the zclient's stream buffer. Please use these instead
+ * of hand-encoding the header info, since that may change over time.
+ * Note that these will reset the zclient's outbound stream before encoding.
+ */
+enum zclient_send_status zapi_opaque_init(struct zclient *zclient,
+ uint32_t type, uint16_t flags);
+
+enum zclient_send_status
+zapi_opaque_unicast_init(struct zclient *zclient, uint32_t type, uint16_t flags,
+ uint8_t proto, uint16_t instance, uint32_t session_id);
+
/* Struct representing the decoded opaque header info */
struct zapi_opaque_msg {
uint32_t type; /* Subtype */
uint16_t len; /* len after zapi header and this info */
uint16_t flags;
- /* Client-specific info - *if* UNICAST flag is set */
- uint8_t proto;
- uint16_t instance;
- uint32_t session_id;
+ /* Sending client info */
+ uint8_t src_proto;
+ uint16_t src_instance;
+ uint32_t src_session_id;
+
+ /* Destination client info - *if* UNICAST flag is set */
+ uint8_t dest_proto;
+ uint16_t dest_instance;
+ uint32_t dest_session_id;
};
#define ZAPI_OPAQUE_FLAG_UNICAST 0x01
diff --git a/zebra/zebra_opaque.c b/zebra/zebra_opaque.c
index 8ceb1f8dc5..2bd6ac084d 100644
--- a/zebra/zebra_opaque.c
+++ b/zebra/zebra_opaque.c
@@ -381,9 +381,9 @@ static int dispatch_opq_messages(struct stream_fifo *msg_fifo)
if (CHECK_FLAG(info.flags, ZAPI_OPAQUE_FLAG_UNICAST)) {
- if (client->proto != info.proto ||
- client->instance != info.instance ||
- client->session_id != info.session_id)
+ if (client->proto != info.dest_proto ||
+ client->instance != info.dest_instance ||
+ client->session_id != info.dest_session_id)
continue;
if (IS_ZEBRA_DEBUG_RECV &&