mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-16 02:30:52 +00:00
lib: add notifications for opaque zapi messages
Add a new notification zapi message type. A zapi client that uses opaque messages can register to be notified when a server for an opaque type is present. Signed-off-by: Mark Stapp <mjs@labn.net>
This commit is contained in:
parent
ef8e3ac02c
commit
06647109ab
@ -457,7 +457,9 @@ static const struct zebra_desc_table command_types[] = {
|
||||
DESC_ENTRY(ZEBRA_TC_CLASS_ADD),
|
||||
DESC_ENTRY(ZEBRA_TC_CLASS_DELETE),
|
||||
DESC_ENTRY(ZEBRA_TC_FILTER_ADD),
|
||||
DESC_ENTRY(ZEBRA_TC_FILTER_DELETE)};
|
||||
DESC_ENTRY(ZEBRA_TC_FILTER_DELETE),
|
||||
DESC_ENTRY(ZEBRA_OPAQUE_NOTIFY)
|
||||
};
|
||||
#undef DESC_ENTRY
|
||||
|
||||
static const struct zebra_desc_table unknown = {0, "unknown", '?'};
|
||||
|
122
lib/zclient.c
122
lib/zclient.c
@ -4512,3 +4512,125 @@ int zclient_send_zebra_gre_request(struct zclient *client,
|
||||
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);
|
||||
}
|
||||
|
@ -87,7 +87,9 @@ enum zserv_client_capabilities {
|
||||
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,
|
||||
@ -232,7 +234,11 @@ typedef enum {
|
||||
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 */
|
||||
@ -1218,6 +1224,34 @@ struct zapi_opaque_reg_info {
|
||||
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);
|
||||
|
||||
@ -1228,6 +1262,19 @@ enum zclient_send_status zclient_unregister_opaque(struct zclient *zclient,
|
||||
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.
|
||||
|
Loading…
Reference in New Issue
Block a user