mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-15 09:20:25 +00:00
Merge pull request #17782 from LabNConsulting/chopps/new-notify-msg-fmt
New YANG notify msg fmt
This commit is contained in:
commit
0a52c233d3
@ -312,11 +312,11 @@ static int be_client_send_error(struct mgmt_be_client *client, uint64_t txn_id,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mgmt_be_send_notification(void *__be_client, const char *xpath,
|
static int __send_notification(struct mgmt_be_client *client, const char *xpath,
|
||||||
const struct lyd_node *tree)
|
const struct lyd_node *tree, uint8_t op)
|
||||||
{
|
{
|
||||||
struct mgmt_be_client *client = __be_client;
|
|
||||||
struct mgmt_msg_notify_data *msg = NULL;
|
struct mgmt_msg_notify_data *msg = NULL;
|
||||||
|
// LYD_FORMAT format = LYD_LYB;
|
||||||
LYD_FORMAT format = LYD_JSON;
|
LYD_FORMAT format = LYD_JSON;
|
||||||
uint8_t **darrp;
|
uint8_t **darrp;
|
||||||
LY_ERR err;
|
LY_ERR err;
|
||||||
@ -324,37 +324,91 @@ static int mgmt_be_send_notification(void *__be_client, const char *xpath,
|
|||||||
|
|
||||||
assert(tree);
|
assert(tree);
|
||||||
|
|
||||||
debug_be_client("%s: sending YANG notification: %s", __func__,
|
debug_be_client("%s: sending %sYANG %snotification: %s", __func__,
|
||||||
tree->schema->name);
|
op == NOTIFY_OP_DS_DELETE ? "delete "
|
||||||
|
: op == NOTIFY_OP_DS_REPLACE ? "replace "
|
||||||
|
: op == NOTIFY_OP_DS_PATCH ? "patch "
|
||||||
|
: "",
|
||||||
|
op == NOTIFY_OP_NOTIFICATION ? "" : "DS ", xpath ?: tree->schema->name);
|
||||||
/*
|
/*
|
||||||
* Allocate a message and append the data to it using `format`
|
* Allocate a message and append the data to it using `format`
|
||||||
*/
|
*/
|
||||||
msg = mgmt_msg_native_alloc_msg(struct mgmt_msg_notify_data, 0,
|
msg = mgmt_msg_native_alloc_msg(struct mgmt_msg_notify_data, 0, MTYPE_MSG_NATIVE_NOTIFY);
|
||||||
MTYPE_MSG_NATIVE_NOTIFY);
|
|
||||||
msg->code = MGMT_MSG_CODE_NOTIFY;
|
msg->code = MGMT_MSG_CODE_NOTIFY;
|
||||||
msg->result_type = format;
|
msg->result_type = format;
|
||||||
|
msg->op = op;
|
||||||
|
|
||||||
mgmt_msg_native_xpath_encode(msg, xpath);
|
mgmt_msg_native_xpath_encode(msg, xpath);
|
||||||
|
|
||||||
|
if (tree) {
|
||||||
darrp = mgmt_msg_native_get_darrp(msg);
|
darrp = mgmt_msg_native_get_darrp(msg);
|
||||||
err = yang_print_tree_append(darrp, tree, format,
|
err = yang_print_tree_append(darrp, tree, format,
|
||||||
(LYD_PRINT_SHRINK | LYD_PRINT_WD_EXPLICIT |
|
(LYD_PRINT_SHRINK | LYD_PRINT_WD_EXPLICIT |
|
||||||
LYD_PRINT_WITHSIBLINGS));
|
LYD_PRINT_WITHSIBLINGS));
|
||||||
if (err) {
|
if (err) {
|
||||||
flog_err(EC_LIB_LIBYANG,
|
flog_err(EC_LIB_LIBYANG, "%s: error creating notification data: %s",
|
||||||
"%s: error creating notification data: %s", __func__,
|
__func__, ly_strerrcode(err));
|
||||||
ly_strerrcode(err));
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
(void)be_client_send_native_msg(client, msg,
|
ret = be_client_send_native_msg(client, msg, mgmt_msg_native_get_msg_len(msg), false);
|
||||||
mgmt_msg_native_get_msg_len(msg), false);
|
|
||||||
done:
|
done:
|
||||||
mgmt_msg_native_free_msg(msg);
|
mgmt_msg_native_free_msg(msg);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mgmt_be_send_ds_delete_notification() - Send DS notification to mgmtd
|
||||||
|
*/
|
||||||
|
int mgmt_be_send_ds_delete_notification(const char *path)
|
||||||
|
{
|
||||||
|
if (!__be_client) {
|
||||||
|
debug_be_client("%s: No mgmtd connection for DS delete notification: %s", __func__,
|
||||||
|
path);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return __send_notification(__be_client, path, NULL, NOTIFY_OP_DS_DELETE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mgmt_be_send_ds_patch_notification() - Send a YANG patch DS notification to mgmtd
|
||||||
|
*/
|
||||||
|
int mgmt_be_send_ds_patch_notification(const char *path, const struct lyd_node *patch)
|
||||||
|
{
|
||||||
|
if (!__be_client) {
|
||||||
|
debug_be_client("%s: No mgmtd connection for DS delete notification: %s", __func__,
|
||||||
|
path);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return __send_notification(__be_client, path, patch, NOTIFY_OP_DS_PATCH);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mgmt_be_send_ds_replace_notification() - Send a replace DS notification to mgmtd
|
||||||
|
*/
|
||||||
|
int mgmt_be_send_ds_replace_notification(const char *path, const struct lyd_node *tree)
|
||||||
|
{
|
||||||
|
if (!__be_client) {
|
||||||
|
debug_be_client("%s: No mgmtd connection for DS delete notification: %s", __func__,
|
||||||
|
path);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return __send_notification(__be_client, path, tree, NOTIFY_OP_DS_REPLACE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mgmt_be_send_notification() - Send notification to mgmtd
|
||||||
|
*
|
||||||
|
* This function is attached to the northbound notification hook.
|
||||||
|
*/
|
||||||
|
static int mgmt_be_send_notification(void *__client, const char *path, const struct lyd_node *tree)
|
||||||
|
{
|
||||||
|
__send_notification(__client, path, tree, NOTIFY_OP_NOTIFICATION);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int mgmt_be_send_txn_reply(struct mgmt_be_client *client_ctx,
|
static int mgmt_be_send_txn_reply(struct mgmt_be_client *client_ctx,
|
||||||
uint64_t txn_id, bool create)
|
uint64_t txn_id, bool create)
|
||||||
{
|
{
|
||||||
|
@ -112,6 +112,22 @@ extern struct mgmt_be_client *
|
|||||||
mgmt_be_client_create(const char *name, struct mgmt_be_client_cbs *cbs,
|
mgmt_be_client_create(const char *name, struct mgmt_be_client_cbs *cbs,
|
||||||
uintptr_t user_data, struct event_loop *event_loop);
|
uintptr_t user_data, struct event_loop *event_loop);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mgmt_be_send_ds_delete_notification() - Send a datastore delete notification.
|
||||||
|
*/
|
||||||
|
extern int mgmt_be_send_ds_delete_notification(const char *path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mgmt_be_send_ds_patch_notification() - Send a datastore YANG patch notification.
|
||||||
|
*/
|
||||||
|
extern int mgmt_be_send_ds_patch_notification(const char *path, const struct lyd_node *tree);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mgmt_be_send_ds_replace_notification() - Send a datastore replace notification.
|
||||||
|
*/
|
||||||
|
extern int mgmt_be_send_ds_replace_notification(const char *path, const struct lyd_node *tree);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize library vty (adds debug support).
|
* Initialize library vty (adds debug support).
|
||||||
*
|
*
|
||||||
|
@ -323,22 +323,29 @@ _Static_assert(sizeof(struct mgmt_msg_get_data) ==
|
|||||||
offsetof(struct mgmt_msg_get_data, xpath),
|
offsetof(struct mgmt_msg_get_data, xpath),
|
||||||
"Size mismatch");
|
"Size mismatch");
|
||||||
|
|
||||||
|
|
||||||
|
#define NOTIFY_OP_NOTIFICATION 0
|
||||||
|
#define NOTIFY_OP_DS_REPLACE 1
|
||||||
|
#define NOTIFY_OP_DS_DELETE 2
|
||||||
|
#define NOTIFY_OP_DS_PATCH 3
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct mgmt_msg_notify_data - Message carrying notification data.
|
* struct mgmt_msg_notify_data - Message carrying notification data.
|
||||||
*
|
*
|
||||||
* @result_type: ``LYD_FORMAT`` for format of the @result value.
|
* @result_type: ``LYD_FORMAT`` for format of the @result value.
|
||||||
* @data: The xpath string of the notification followed by the tree data in
|
* @data: The xpath string of the notification followed by the tree data in
|
||||||
* @result_type format.
|
* @result_type format.
|
||||||
|
* @op: notify operation type.
|
||||||
*/
|
*/
|
||||||
struct mgmt_msg_notify_data {
|
struct mgmt_msg_notify_data {
|
||||||
struct mgmt_msg_header;
|
struct mgmt_msg_header;
|
||||||
uint8_t result_type;
|
uint8_t result_type;
|
||||||
uint8_t resv2[7];
|
uint8_t op;
|
||||||
|
uint8_t resv2[6];
|
||||||
|
|
||||||
alignas(8) char data[];
|
alignas(8) char data[];
|
||||||
};
|
};
|
||||||
_Static_assert(sizeof(struct mgmt_msg_notify_data) ==
|
_Static_assert(sizeof(struct mgmt_msg_notify_data) == offsetof(struct mgmt_msg_notify_data, data),
|
||||||
offsetof(struct mgmt_msg_notify_data, data),
|
|
||||||
"Size mismatch");
|
"Size mismatch");
|
||||||
|
|
||||||
#define EDIT_FLAG_IMPLICIT_LOCK 0x01
|
#define EDIT_FLAG_IMPLICIT_LOCK 0x01
|
||||||
|
@ -78,8 +78,13 @@ GET_DATA_FLAG_STATE = 0x1
|
|||||||
GET_DATA_FLAG_CONFIG = 0x2
|
GET_DATA_FLAG_CONFIG = 0x2
|
||||||
GET_DATA_FLAG_EXACT = 0x4
|
GET_DATA_FLAG_EXACT = 0x4
|
||||||
|
|
||||||
MSG_NOTIFY_FMT = "=B7x"
|
MSG_NOTIFY_FMT = "=BB6x"
|
||||||
NOTIFY_FIELD_RESULT_TYPE = 0
|
NOTIFY_FIELD_RESULT_TYPE = 0
|
||||||
|
NOTIFY_FIELD_OP = 1
|
||||||
|
NOTIFY_OP_NOTIFICATION = 0
|
||||||
|
NOTIFY_OP_REPLACE = 1
|
||||||
|
NOTIFY_OP_DELETE = 2
|
||||||
|
NOTIFY_OP_PATCH = 3
|
||||||
|
|
||||||
MSG_NOTIFY_SELECT_FMT = "=B7x"
|
MSG_NOTIFY_SELECT_FMT = "=B7x"
|
||||||
|
|
||||||
@ -363,10 +368,12 @@ class Session:
|
|||||||
raise Exception(f"Received NON-NOTIFY Message: {mfixed}: {mdata}")
|
raise Exception(f"Received NON-NOTIFY Message: {mfixed}: {mdata}")
|
||||||
|
|
||||||
vsplit = mhdr[HDR_FIELD_VSPLIT]
|
vsplit = mhdr[HDR_FIELD_VSPLIT]
|
||||||
|
result_type = mfixed[0]
|
||||||
|
op = mfixed[1]
|
||||||
assert mdata[vsplit - 1] == 0
|
assert mdata[vsplit - 1] == 0
|
||||||
assert mdata[-1] == 0
|
assert mdata[-1] == 0
|
||||||
# xpath = mdata[: vsplit - 1].decode("utf-8")
|
xpath = mdata[: vsplit - 1].decode("utf-8")
|
||||||
return mdata[vsplit:-1].decode("utf-8")
|
return result_type, op, xpath, mdata[vsplit:-1].decode("utf-8")
|
||||||
else:
|
else:
|
||||||
raise TimeoutError("Timeout waiting for notifications")
|
raise TimeoutError("Timeout waiting for notifications")
|
||||||
|
|
||||||
@ -389,6 +396,9 @@ def __parse_args():
|
|||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-c", "--config-only", action="store_true", help="return config only"
|
"-c", "--config-only", action="store_true", help="return config only"
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--datastore", action="store_true", help="listen for datastore notifications"
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-q", "--query", nargs="+", metavar="XPATH", help="xpath[s] to query"
|
"-q", "--query", nargs="+", metavar="XPATH", help="xpath[s] to query"
|
||||||
)
|
)
|
||||||
@ -434,9 +444,31 @@ def __main():
|
|||||||
|
|
||||||
if args.listen is not None:
|
if args.listen is not None:
|
||||||
i = args.notify_count
|
i = args.notify_count
|
||||||
|
if args.listen:
|
||||||
|
sess.add_notify_select(True, args.listen)
|
||||||
while i > 0 or args.notify_count == 0:
|
while i > 0 or args.notify_count == 0:
|
||||||
notif = sess.recv_notify(args.listen)
|
result_type, op, xpath, notif = sess.recv_notify()
|
||||||
|
if op == NOTIFY_OP_NOTIFICATION:
|
||||||
|
if args.datastore:
|
||||||
|
logging.warning("ignoring non-datastore notification: %s", notif)
|
||||||
|
else:
|
||||||
print(notif)
|
print(notif)
|
||||||
|
elif not args.datastore:
|
||||||
|
logging.warning(
|
||||||
|
"ignoring datastore notification op: %s xpath: %s data: %s",
|
||||||
|
op,
|
||||||
|
xpath,
|
||||||
|
notif,
|
||||||
|
)
|
||||||
|
elif op == NOTIFY_OP_PATCH:
|
||||||
|
print(f"#OP=PATCH: {xpath}")
|
||||||
|
print(notif)
|
||||||
|
elif op == NOTIFY_OP_REPLACE:
|
||||||
|
print(f"#OP=REPLACE: {xpath}")
|
||||||
|
print(notif)
|
||||||
|
elif op == NOTIFY_OP_DELETE:
|
||||||
|
print(f"#OP=DELETE: {xpath}")
|
||||||
|
assert len(notif) == 0
|
||||||
i -= 1
|
i -= 1
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user