mgmtd: testc: add listen for datastore notifications

Signed-off-by: Christian Hopps <chopps@labn.net>
This commit is contained in:
Christian Hopps 2025-01-16 06:14:54 +00:00
parent 597d79a89e
commit d54ab3b112
2 changed files with 100 additions and 11 deletions

View file

@ -84,6 +84,13 @@ static const char *const zebra_oper_xpaths[] = {
NULL,
};
#ifdef HAVE_MGMTD_TESTC
static const char *const mgmtd_testc_oper_xpaths[] = {
"/frr-backend:clients",
NULL,
};
#endif
#ifdef HAVE_RIPD
static const char *const ripd_config_xpaths[] = {
"/frr-filter:lib",
@ -154,6 +161,9 @@ static const char *const *be_client_config_xpaths[MGMTD_BE_CLIENT_ID_MAX] = {
};
static const char *const *be_client_oper_xpaths[MGMTD_BE_CLIENT_ID_MAX] = {
#ifdef HAVE_MGMTD_TESTC
[MGMTD_BE_CLIENT_ID_TESTC] = mgmtd_testc_oper_xpaths,
#endif
#ifdef HAVE_RIPD
[MGMTD_BE_CLIENT_ID_RIPD] = ripd_oper_xpaths,
#endif

View file

@ -9,8 +9,10 @@
#include <zebra.h>
#include <lib/version.h>
#include "darr.h"
#include "debug.h"
#include "libfrr.h"
#include "mgmt_be_client.h"
#include "mgmt_msg_native.h"
#include "northbound.h"
/* ---------------- */
@ -43,15 +45,15 @@ struct zebra_privs_t __privs = {
.cap_num_i = 0,
};
#define OPTION_LISTEN 2000
#define OPTION_NOTIF_COUNT 2001
#define OPTION_TIMEOUT 2002
const struct option longopts[] = {
#define OPTION_DATASTORE 2000
#define OPTION_LISTEN 2001
#define OPTION_NOTIF_COUNT 2002
#define OPTION_TIMEOUT 2003
const struct option longopts[] = { { "datastore", no_argument, NULL, OPTION_DATASTORE },
{ "listen", no_argument, NULL, OPTION_LISTEN },
{ "notif-count", required_argument, NULL, OPTION_NOTIF_COUNT },
{ "notify-count", required_argument, NULL, OPTION_NOTIF_COUNT },
{ "timeout", required_argument, NULL, OPTION_TIMEOUT },
{ 0 }
};
{ 0 } };
/* Master of threads. */
@ -79,6 +81,20 @@ struct frr_signal_t __signals[] = {
#define MGMTD_TESTC_VTY_PORT 2624
/* clang-format off */
static const struct frr_yang_module_info frr_if_info = {
.name = "frr-interface",
.ignore_cfg_cbs = true,
.nodes = {
{
.xpath = "/frr-interface:lib/interface",
.cbs.notify = async_notification,
},
{
.xpath = NULL,
}
}
};
static const struct frr_yang_module_info frr_ripd_info = {
.name = "frr-ripd",
.ignore_cfg_cbs = true,
@ -98,6 +114,8 @@ static const struct frr_yang_module_info frr_ripd_info = {
};
static const struct frr_yang_module_info *const mgmt_yang_modules[] = {
&frr_backend_info,
&frr_if_info,
&frr_ripd_info,
};
@ -123,6 +141,7 @@ const char **__rpc_xpaths;
struct mgmt_be_client_cbs __client_cbs = {};
struct event *event_timeout;
int f_datastore;
int o_notif_count = 1;
int o_timeout;
@ -165,10 +184,56 @@ static void success(struct event *event)
quit(0);
}
static void async_notification(struct nb_cb_notify_args *args)
static void __ds_notification(struct nb_cb_notify_args *args)
{
zlog_notice("Received YANG notification");
uint8_t *output = NULL;
zlog_notice("Received YANG datastore notification: op %u", args->op);
if (args->op == NOTIFY_OP_NOTIFICATION) {
zlog_warn("ignoring non-datastore op notification: %s", args->xpath);
return;
}
/* datastore notification */
switch (args->op) {
case NOTIFY_OP_DS_REPLACE:
printfrr("#OP=REPLACE: %s\n", args->xpath);
break;
case NOTIFY_OP_DS_DELETE:
printfrr("#OP=DELETE: %s\n", args->xpath);
break;
case NOTIFY_OP_DS_PATCH:
printfrr("#OP=PATCH: %s\n", args->xpath);
break;
default:
printfrr("#OP=%u: unknown notify op\n", args->op);
quit(1);
}
if (args->dnode && args->op != NOTIFY_OP_DS_DELETE) {
output = yang_print_tree(args->dnode, LYD_JSON, LYD_PRINT_SHRINK);
if (output) {
printfrr("%s\n", output);
darr_free(output);
}
}
fflush(stdout);
if (o_notif_count && !--o_notif_count)
quit(0);
}
static void __notification(struct nb_cb_notify_args *args)
{
zlog_notice("Received YANG notification: op: %u", args->op);
if (args->op != NOTIFY_OP_NOTIFICATION) {
zlog_warn("ignoring datastore notification: op: %u: path %s", args->op, args->xpath);
return;
}
/* bogus, we should print the actual data */
printf("{\"frr-ripd:authentication-failure\": {\"interface-name\": \"%s\"}}\n",
yang_dnode_get_string(args->dnode, "interface-name"));
@ -176,6 +241,14 @@ static void async_notification(struct nb_cb_notify_args *args)
quit(0);
}
static void async_notification(struct nb_cb_notify_args *args)
{
if (f_datastore)
__ds_notification(args);
else
__notification(args);
}
static int rpc_callback(struct nb_cb_rpc_args *args)
{
const char *vrf = NULL;
@ -210,6 +283,9 @@ int main(int argc, char **argv)
break;
switch (opt) {
case OPTION_DATASTORE:
f_datastore = 1;
break;
case OPTION_LISTEN:
f_listen = 1;
break;
@ -228,6 +304,9 @@ int main(int argc, char **argv)
master = frr_init();
mgmt_be_client_lib_vty_init();
mgmt_dbg_be_client.flags = DEBUG_MODE_ALL;
/*
* Setup notification listen
*/