mirror of
https://github.com/FRRouting/frr.git
synced 2025-04-30 13:37:17 +02:00
mgmtd: testc: add listen for datastore notifications
Signed-off-by: Christian Hopps <chopps@labn.net>
This commit is contained in:
parent
597d79a89e
commit
d54ab3b112
|
@ -84,6 +84,13 @@ static const char *const zebra_oper_xpaths[] = {
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef HAVE_MGMTD_TESTC
|
||||||
|
static const char *const mgmtd_testc_oper_xpaths[] = {
|
||||||
|
"/frr-backend:clients",
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_RIPD
|
#ifdef HAVE_RIPD
|
||||||
static const char *const ripd_config_xpaths[] = {
|
static const char *const ripd_config_xpaths[] = {
|
||||||
"/frr-filter:lib",
|
"/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] = {
|
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
|
#ifdef HAVE_RIPD
|
||||||
[MGMTD_BE_CLIENT_ID_RIPD] = ripd_oper_xpaths,
|
[MGMTD_BE_CLIENT_ID_RIPD] = ripd_oper_xpaths,
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -9,8 +9,10 @@
|
||||||
#include <zebra.h>
|
#include <zebra.h>
|
||||||
#include <lib/version.h>
|
#include <lib/version.h>
|
||||||
#include "darr.h"
|
#include "darr.h"
|
||||||
|
#include "debug.h"
|
||||||
#include "libfrr.h"
|
#include "libfrr.h"
|
||||||
#include "mgmt_be_client.h"
|
#include "mgmt_be_client.h"
|
||||||
|
#include "mgmt_msg_native.h"
|
||||||
#include "northbound.h"
|
#include "northbound.h"
|
||||||
|
|
||||||
/* ---------------- */
|
/* ---------------- */
|
||||||
|
@ -43,15 +45,15 @@ struct zebra_privs_t __privs = {
|
||||||
.cap_num_i = 0,
|
.cap_num_i = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define OPTION_LISTEN 2000
|
#define OPTION_DATASTORE 2000
|
||||||
#define OPTION_NOTIF_COUNT 2001
|
#define OPTION_LISTEN 2001
|
||||||
#define OPTION_TIMEOUT 2002
|
#define OPTION_NOTIF_COUNT 2002
|
||||||
const struct option longopts[] = {
|
#define OPTION_TIMEOUT 2003
|
||||||
{ "listen", no_argument, NULL, OPTION_LISTEN },
|
const struct option longopts[] = { { "datastore", no_argument, NULL, OPTION_DATASTORE },
|
||||||
{ "notif-count", required_argument, NULL, OPTION_NOTIF_COUNT },
|
{ "listen", no_argument, NULL, OPTION_LISTEN },
|
||||||
{ "timeout", required_argument, NULL, OPTION_TIMEOUT },
|
{ "notify-count", required_argument, NULL, OPTION_NOTIF_COUNT },
|
||||||
{ 0 }
|
{ "timeout", required_argument, NULL, OPTION_TIMEOUT },
|
||||||
};
|
{ 0 } };
|
||||||
|
|
||||||
|
|
||||||
/* Master of threads. */
|
/* Master of threads. */
|
||||||
|
@ -79,6 +81,20 @@ struct frr_signal_t __signals[] = {
|
||||||
#define MGMTD_TESTC_VTY_PORT 2624
|
#define MGMTD_TESTC_VTY_PORT 2624
|
||||||
|
|
||||||
/* clang-format off */
|
/* 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 = {
|
static const struct frr_yang_module_info frr_ripd_info = {
|
||||||
.name = "frr-ripd",
|
.name = "frr-ripd",
|
||||||
.ignore_cfg_cbs = true,
|
.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[] = {
|
static const struct frr_yang_module_info *const mgmt_yang_modules[] = {
|
||||||
|
&frr_backend_info,
|
||||||
|
&frr_if_info,
|
||||||
&frr_ripd_info,
|
&frr_ripd_info,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -123,6 +141,7 @@ const char **__rpc_xpaths;
|
||||||
struct mgmt_be_client_cbs __client_cbs = {};
|
struct mgmt_be_client_cbs __client_cbs = {};
|
||||||
struct event *event_timeout;
|
struct event *event_timeout;
|
||||||
|
|
||||||
|
int f_datastore;
|
||||||
int o_notif_count = 1;
|
int o_notif_count = 1;
|
||||||
int o_timeout;
|
int o_timeout;
|
||||||
|
|
||||||
|
@ -165,10 +184,56 @@ static void success(struct event *event)
|
||||||
quit(0);
|
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",
|
printf("{\"frr-ripd:authentication-failure\": {\"interface-name\": \"%s\"}}\n",
|
||||||
yang_dnode_get_string(args->dnode, "interface-name"));
|
yang_dnode_get_string(args->dnode, "interface-name"));
|
||||||
|
|
||||||
|
@ -176,6 +241,14 @@ static void async_notification(struct nb_cb_notify_args *args)
|
||||||
quit(0);
|
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)
|
static int rpc_callback(struct nb_cb_rpc_args *args)
|
||||||
{
|
{
|
||||||
const char *vrf = NULL;
|
const char *vrf = NULL;
|
||||||
|
@ -210,6 +283,9 @@ int main(int argc, char **argv)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
|
case OPTION_DATASTORE:
|
||||||
|
f_datastore = 1;
|
||||||
|
break;
|
||||||
case OPTION_LISTEN:
|
case OPTION_LISTEN:
|
||||||
f_listen = 1;
|
f_listen = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -228,6 +304,9 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
master = frr_init();
|
master = frr_init();
|
||||||
|
|
||||||
|
mgmt_be_client_lib_vty_init();
|
||||||
|
mgmt_dbg_be_client.flags = DEBUG_MODE_ALL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Setup notification listen
|
* Setup notification listen
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue