mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-17 15:02:20 +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_ADD),
|
||||||
DESC_ENTRY(ZEBRA_TC_CLASS_DELETE),
|
DESC_ENTRY(ZEBRA_TC_CLASS_DELETE),
|
||||||
DESC_ENTRY(ZEBRA_TC_FILTER_ADD),
|
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
|
#undef DESC_ENTRY
|
||||||
|
|
||||||
static const struct zebra_desc_table unknown = {0, "unknown", '?'};
|
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);
|
zclient_send_message(client);
|
||||||
return 0;
|
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 struct sockaddr_storage zclient_addr;
|
||||||
extern socklen_t zclient_addr_len;
|
extern socklen_t zclient_addr_len;
|
||||||
|
|
||||||
/* Zebra message types. */
|
/* Zebra message types. Please update the corresponding
|
||||||
|
* command_types array with any changes!
|
||||||
|
*/
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ZEBRA_INTERFACE_ADD,
|
ZEBRA_INTERFACE_ADD,
|
||||||
ZEBRA_INTERFACE_DELETE,
|
ZEBRA_INTERFACE_DELETE,
|
||||||
@ -232,7 +234,11 @@ typedef enum {
|
|||||||
ZEBRA_TC_CLASS_DELETE,
|
ZEBRA_TC_CLASS_DELETE,
|
||||||
ZEBRA_TC_FILTER_ADD,
|
ZEBRA_TC_FILTER_ADD,
|
||||||
ZEBRA_TC_FILTER_DELETE,
|
ZEBRA_TC_FILTER_DELETE,
|
||||||
|
ZEBRA_OPAQUE_NOTIFY,
|
||||||
} zebra_message_types_t;
|
} zebra_message_types_t;
|
||||||
|
/* Zebra message types. Please update the corresponding
|
||||||
|
* command_types array with any changes!
|
||||||
|
*/
|
||||||
|
|
||||||
enum zebra_error_types {
|
enum zebra_error_types {
|
||||||
ZEBRA_UNKNOWN_ERROR, /* Error of unknown type */
|
ZEBRA_UNKNOWN_ERROR, /* Error of unknown type */
|
||||||
@ -1218,6 +1224,34 @@ struct zapi_opaque_reg_info {
|
|||||||
uint32_t session_id;
|
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 */
|
/* Decode incoming opaque */
|
||||||
int zclient_opaque_decode(struct stream *msg, struct zapi_opaque_msg *info);
|
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,
|
int zapi_opaque_reg_decode(struct stream *msg,
|
||||||
struct zapi_opaque_reg_info *info);
|
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
|
* Registry of opaque message types. Please do not reuse an in-use
|
||||||
* type code; some daemons are likely relying on it.
|
* type code; some daemons are likely relying on it.
|
||||||
|
Loading…
Reference in New Issue
Block a user