]> git.proxmox.com Git - mirror_frr.git/commitdiff
lib,zebra,sharpd: modify opaque zapi message to support unicast
authorMark Stapp <mjs@voltanet.io>
Thu, 4 Jun 2020 17:11:35 +0000 (13:11 -0400)
committerMark Stapp <mjs@voltanet.io>
Wed, 10 Jun 2020 12:26:27 +0000 (08:26 -0400)
Start modifying the OPAQUE zapi message to include optional
unicast destination zapi client info. Add a 'decode' api and
opaque msg struct to encapsulate that optional info.

Signed-off-by: Mark Stapp <mjs@voltanet.io>
lib/zclient.c
lib/zclient.h
sharpd/sharp_zebra.c
zebra/zebra_opaque.c

index 4297bf16a6e9fbd53e6505444d8da4ba4cb77d14..aa5fa082a132b061af5ceb4720f577a371387f52 100644 (file)
@@ -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);
@@ -3146,6 +3148,77 @@ int zclient_send_opaque(struct zclient *zclient, uint32_t type,
        return ret;
 }
 
+/*
+ * 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.
  */
@@ -3205,8 +3278,7 @@ int zclient_unregister_opaque(struct zclient *zclient, uint32_t type)
 }
 
 /* Utility to decode opaque registration info */
-int zapi_opaque_reg_decode(struct stream *s,
-                          struct zapi_opaque_reg_info *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);
index f5aa1d758db130f2f1015a996509a2e6b7ee3926..3ded2f55d7040e91c57733aff1b97616dcafbf8e 100644 (file)
@@ -457,6 +457,7 @@ struct zapi_route {
  */
 #define ZEBRA_FLAG_RR_USE_DISTANCE    0x40
 
+       /* The older XXX_MESSAGE flags live here */
        uint8_t message;
 
        /*
@@ -849,6 +850,25 @@ extern void zclient_send_mlag_data(struct zclient *client,
 int zclient_send_opaque(struct zclient *zclient, uint32_t type,
                        const uint8_t *data, size_t datasize);
 
+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);
+
+/* 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;
+};
+
+#define ZAPI_OPAQUE_FLAG_UNICAST   0x01
+
 /* Simple struct to convey registration/unreg requests */
 struct zapi_opaque_reg_info {
        /* Message subtype */
@@ -860,6 +880,9 @@ struct zapi_opaque_reg_info {
        uint32_t session_id;
 };
 
+/* Decode incoming opaque */
+int zclient_opaque_decode(struct stream *msg, struct zapi_opaque_msg *info);
+
 int zclient_register_opaque(struct zclient *zclient, uint32_t type);
 int zclient_unregister_opaque(struct zclient *zclient, uint32_t type);
 int zapi_opaque_reg_decode(struct stream *msg,
index 34cc1a4b5a221f743210b6a62a00bb926262bf65..d94e272dd2afcdc10f65d9ad4b095ee1f6c47a3a 100644 (file)
@@ -483,16 +483,15 @@ static int sharp_redistribute_route(ZAPI_CALLBACK_ARGS)
 /* Handler for opaque messages */
 static int sharp_opaque_handler(ZAPI_CALLBACK_ARGS)
 {
-       uint32_t type;
        struct stream *s;
+       struct zapi_opaque_msg info;
 
        s = zclient->ibuf;
 
-       STREAM_GETL(s, type);
-
-       zlog_debug("%s: received opaque type %u", __func__, type);
+       if (zclient_opaque_decode(s, &info) != 0)
+               return -1;
 
-stream_failure:
+       zlog_debug("%s: received opaque type %u", __func__, info.type);
 
        return 0;
 }
index 0b7c5b26b033307d756ad8be9625392cdecc4cf5..8fb02114d155a2f71740346109f031428c43622a 100644 (file)
@@ -347,8 +347,9 @@ static int dispatch_opq_messages(struct stream_fifo *msg_fifo)
 {
        struct stream *msg, *dup;
        struct zmsghdr hdr;
+       struct zapi_opaque_msg info;
        struct opq_msg_reg *reg;
-       uint32_t type;
+       int ret;
        struct opq_client_reg *client;
        struct zserv *zclient;
        char buf[50];
@@ -372,15 +373,17 @@ static int dispatch_opq_messages(struct stream_fifo *msg_fifo)
 
                /* Dispatch to any registered ZAPI client(s) */
 
-               /* Extract subtype */
-               STREAM_GETL(msg, type);
+               /* Extract subtype and flags */
+               ret = zclient_opaque_decode(msg, &info);
+               if (ret != 0)
+                       goto drop_it;
 
                /* Look up registered ZAPI client(s) */
-               reg = opq_reg_lookup(type);
+               reg = opq_reg_lookup(info.type);
                if (reg == NULL) {
                        if (IS_ZEBRA_DEBUG_RECV)
-                               zlog_debug("%s: no registrations for opaque type %u",
-                                          __func__, type);
+                               zlog_debug("%s: no registrations for opaque type %u, flags %#x",
+                                          __func__, info.type, info.flags);
                        goto drop_it;
                }
 
@@ -427,7 +430,7 @@ static int dispatch_opq_messages(struct stream_fifo *msg_fifo)
                        } else {
                                if (IS_ZEBRA_DEBUG_RECV)
                                        zlog_debug("%s: type %u: no zclient for %s",
-                                                  __func__, type,
+                                                  __func__, info.type,
                                                   opq_client2str(buf,
                                                                  sizeof(buf),
                                                                  client));
@@ -438,7 +441,7 @@ static int dispatch_opq_messages(struct stream_fifo *msg_fifo)
                }
 
 drop_it:
-stream_failure:
+
                if (msg)
                        stream_free(msg);
        }