zclient_send_message(client);
return 0;
}
+
+
+/*
+ * Opaque notification features
+ */
+
+/*
+ * Common encode helper for opaque notifications, both registration
+ * and async notification messages.
+ */
+static int opaque_notif_encode_common(struct stream *s, uint32_t msg_type,
+ bool request, bool reg, uint8_t proto,
+ uint16_t instance, uint32_t session_id)
+{
+ int ret = 0;
+ uint8_t val = 0;
+
+ stream_reset(s);
+
+ zclient_create_header(s, ZEBRA_OPAQUE_NOTIFY, VRF_DEFAULT);
+
+ /* Notification or request */
+ if (request)
+ val = 1;
+ stream_putc(s, val);
+
+ if (reg)
+ val = 1;
+ else
+ val = 0;
+ stream_putc(s, val);
+
+ stream_putl(s, msg_type);
+
+ stream_putc(s, proto);
+ stream_putw(s, instance);
+ stream_putl(s, session_id);
+
+ /* And capture message length */
+ stream_putw_at(s, 0, stream_get_endp(s));
+
+ return ret;
+}
+
+/*
+ * Encode a zapi opaque message type notification into buffer 's'
+ */
+int zclient_opaque_notif_encode(struct stream *s, uint32_t msg_type, bool reg,
+ uint8_t proto, uint16_t instance,
+ uint32_t session_id)
+{
+ return opaque_notif_encode_common(s, msg_type, false /* !request */,
+ reg, proto, instance, session_id);
+}
+
+/*
+ * Decode an incoming zapi opaque message type notification
+ */
+int zclient_opaque_notif_decode(struct stream *s,
+ struct zapi_opaque_notif_info *info)
+{
+ uint8_t val;
+
+ memset(info, 0, sizeof(*info));
+
+ STREAM_GETC(s, val); /* Registration or notification */
+ info->request = (val != 0);
+
+ STREAM_GETC(s, val);
+ info->reg = (val != 0);
+
+ STREAM_GETL(s, info->msg_type);
+
+ STREAM_GETC(s, info->proto);
+ STREAM_GETW(s, info->instance);
+ STREAM_GETL(s, info->session_id);
+
+ return 0;
+
+stream_failure:
+ return -1;
+}
+
+/*
+ * Encode and send a zapi opaque message type notification request to zebra
+ */
+enum zclient_send_status zclient_opaque_request_notify(struct zclient *zclient,
+ uint32_t msgtype)
+{
+ struct stream *s;
+
+ if (!zclient || zclient->sock < 0)
+ return ZCLIENT_SEND_FAILURE;
+
+ s = zclient->obuf;
+
+ opaque_notif_encode_common(s, msgtype, true /* request */,
+ true /* register */, zclient->redist_default,
+ zclient->instance, zclient->session_id);
+
+ return zclient_send_message(zclient);
+}
+
+/*
+ * Encode and send a request to drop notifications for an opaque message type.
+ */
+enum zclient_send_status zclient_opaque_drop_notify(struct zclient *zclient,
+ uint32_t msgtype)
+{
+ struct stream *s;
+
+ if (!zclient || zclient->sock < 0)
+ return ZCLIENT_SEND_FAILURE;
+
+ s = zclient->obuf;
+
+ opaque_notif_encode_common(s, msgtype, true /* req */,
+ false /* unreg */, zclient->redist_default,
+ zclient->instance, zclient->session_id);
+
+ return zclient_send_message(zclient);
+}
extern struct sockaddr_storage zclient_addr;
extern socklen_t zclient_addr_len;
-/* Zebra message types. */
+/* Zebra message types. Please update the corresponding
+ * command_types array with any changes!
+ */
typedef enum {
ZEBRA_INTERFACE_ADD,
ZEBRA_INTERFACE_DELETE,
ZEBRA_TC_CLASS_DELETE,
ZEBRA_TC_FILTER_ADD,
ZEBRA_TC_FILTER_DELETE,
+ ZEBRA_OPAQUE_NOTIFY,
} zebra_message_types_t;
+/* Zebra message types. Please update the corresponding
+ * command_types array with any changes!
+ */
enum zebra_error_types {
ZEBRA_UNKNOWN_ERROR, /* Error of unknown type */
uint32_t session_id;
};
+/* Simple struct conveying information about opaque notifications.
+ * Daemons can request notifications about the status of registration for
+ * opaque message types. For example, a client daemon can request notification
+ * when a server registers to receive a certain message code. Or a server can
+ * request notification when a subscriber registers for its output.
+ */
+struct zapi_opaque_notif_info {
+ bool request; /* Request to register, or notification from zebra */
+ bool reg; /* Register or unregister */
+ uint32_t msg_type; /* Target message code */
+
+ /* For notif registration, zapi info for the client.
+ * For notifications, zapi info for the message's server/registrant.
+ * For notification that there is no server/registrant, not present.
+ */
+ uint8_t proto;
+ uint16_t instance;
+ uint32_t session_id;
+};
+
+/* The same ZAPI message is used for daemon->zebra requests, and for
+ * zebra->daemon notifications.
+ * Daemons send 'request' true, and 'reg' true or false.
+ * Zebra sends 'request' false, 'reg' set if the notification is a
+ * server/receiver registration for the message type, and false if the event
+ * is the end of registrations.
+ */
+
/* Decode incoming opaque */
int zclient_opaque_decode(struct stream *msg, struct zapi_opaque_msg *info);
int zapi_opaque_reg_decode(struct stream *msg,
struct zapi_opaque_reg_info *info);
+/* Opaque notification features */
+enum zclient_send_status zclient_opaque_request_notify(struct zclient *zclient,
+ uint32_t msgtype);
+enum zclient_send_status zclient_opaque_drop_notify(struct zclient *zclient,
+ uint32_t msgtype);
+
+/* Encode, decode an incoming zapi opaque notification */
+int zclient_opaque_notif_encode(struct stream *s, uint32_t msg_type,
+ bool reg /* register or unreg*/, uint8_t proto,
+ uint16_t instance, uint32_t session_id);
+int zclient_opaque_notif_decode(struct stream *s,
+ struct zapi_opaque_notif_info *info);
+
/*
* Registry of opaque message types. Please do not reuse an in-use
* type code; some daemons are likely relying on it.