Merge pull request #15152 from LabNConsulting/chopps/doc-mgmtd-convert-update

doc: mgmtd: update mgmtd conversion doc to be current.
This commit is contained in:
Donald Sharp 2024-01-13 20:46:36 -05:00 committed by GitHub
commit ef0ae6e815
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 117 additions and 88 deletions

View file

@ -37,11 +37,10 @@ easily be added as *front-ends* to mgmtd to support those protocols as well.
Converting A Daemon to MGMTD Converting A Daemon to MGMTD
^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
A daemon must first be transitioned to the new *northbound* interface if that A daemon must first be transitioned to the new :ref:`northbound` interface if that
has not already been done (see `this northbound conversion documentation has not already been done (see :ref:`nb-retrofit` for how to do this). Once this
<https://github.com/opensourcerouting/frr/wiki/Retrofitting-Configuration-Commands>`_ is done a few simple steps are all that is required move the daemon over to
for how to do this). Once this is done a few simple steps are all that is ``mgmtd`` control.
required move the daemon over to ``mgmtd`` control.
Overview of Changes Overview of Changes
------------------- -------------------
@ -52,16 +51,27 @@ requires enabling *frontend* (CLI and YANG) and *backend* (YANG) support.
Front-End Interface: Front-End Interface:
1. Add YANG module file to ``mgmtd/subdir.am`` (e.g., ``yang/frr-staticd.c``) 1. Add YANG module file to ``mgmtd/subdir.am`` (e.g., ``yang/frr-staticd.yang.c``).
2. Add YANG module description into array defined in ``mgmtd/mgmt_main.c`` 2. Add CLI handler file[s] to ``mgmtd/subdir.am`` (e.g., ``staticd/static_vty.c``).
3. Add CLI handler file[s] to ``mgmtd/subdir.am`` (e.g., ``staticd/static_vty.c``) 3. [if needed] Exclude (#ifndef) non-configuration CLI handlers from CLI source
4. [if needed] Exclude (#ifndef) non-configuration CLI handlers from CLI source file (e.g., inside ``staticd/static_vty.c``).
file (e.g., inside ``staticd/static_vty.c``) 4. [otherwise] Remove CLI handler file from SOURCES in daemon (e.g in :file:`staticd/subdir.am`)
5. Add YANG module description into array defined in ``mgmtd/mgmt_main.c`` (see :ref:`mgmtd-config-write`).
6. Initialize the CLI handlers inside :code:`mgmt_vty_init` in :file:`mgmtd/mgmt_vty.c`.
7. Direct ``vtysh`` to send CLI commands to ``mgmtd`` by modifying
``vtysh/vtysh.h``. At the top of this file each daemon has a bit
``#define``'d (e.g., ``#define VTYSH_STATICD 0x08000``) below this there are
groupings, replace all the uses of the daemons bit with ``VTYSH_MGMTD``
instead so that the CLI commands get properly routed to ``mgmtd`` rather than
the daemon now.
Back-End Interface: Back-End Interface:
5. Add XPATHs mappings to a couple arrays to direct ``mgmtd`` at your daemon in 8. In ``mgmtd/mgmt_be_adapter.c`` add xpath prefix mappings to a one or both
``mgmtd/mgmt_be_adapter.c`` mapping arrays (``be_client_config_xpaths`` and ``be_client_oper_xpaths``) to
direct ``mgmtd`` to send config and oper-state requests to your daemon. NOTE:
make sure to include library supported xpaths prefixes as well (e.g.,
"/frr-interface:lib").
Add YANG and CLI into MGMTD Add YANG and CLI into MGMTD
@ -72,44 +82,48 @@ As an example here is the addition made to ``mgmtd/subdir.am`` for adding
.. code-block:: make .. code-block:: make
if STATICD if STATICD
nodist_mgmtd_mgmtd_SOURCES += \ nodist_mgmtd_mgmtd_SOURCES += \
yang/frr-staticd.yang.c \ yang/frr-staticd.yang.c \
yang/frr-bfdd.yang.c \ yang/frr-bfdd.yang.c \
# end # end
nodist_mgmtd_libmgmt_be_nb_la_SOURCES += staticd/static_vty.c nodist_mgmtd_libmgmt_be_nb_la_SOURCES += staticd/static_vty.c
endif endif
An here is the addition to the modules array in ``mgmtd/mgmt_main.c``: An here is the addition to the modules array in ``mgmtd/mgmt_main.c``:
.. code-block:: c .. code-block:: c
static const struct frr_yang_module_info *const mgmt_yang_modules[] = { #ifdef HAVE_STATICD
extern const struct frr_yang_module_info frr_staticd_info;
#endif
static const struct frr_yang_module_info *const mgmt_yang_modules[] = {
&frr_filter_info, &frr_filter_info,
... ...
#ifdef HAVE_STATICD #ifdef HAVE_STATICD
&(struct frr_yang_module_info){.name = "frr-staticd", &frr_staticd_info,
.ignore_cfg_cbs = true}, #endif
#endif }
}
CLI Handlers CLI Config and Show Handlers
------------ ----------------------------
The daemon's CLI handlers for configuration (which having been converted to The daemon's CLI handlers for configuration (which having been converted to the
*northbound* now simply generate YANG changes) will be linked directly into :ref:`northbound` now simply generate YANG changes) will be linked directly into
``mgmtd``. ``mgmtd``.
If the operational and debug CLI commands are kept in files separate from the If the operational and debug CLI commands are kept in files separate from the
daemon's configuration CLI commands then no extra work is required. Otherwise some daemon's configuration CLI commands then no extra work is required. Otherwise some
CPP #ifndef's will be required. CPP #ifndef's will be required.
Currently ``mgmtd`` supports configuration CLI but not operational ``mgmtd`` supports both config and operational state. However, many
state so if both types of CLI handlers are present in a single file (e.g. a daemons have not had their operational state CLI commands converted over to the
``xxx_vty.c`` or ``xxx_cli.c`` file ) then #ifndef will be used to exclude these new YANG based methods. If that is the case and if both types of CLI handlers
non-configuration CLI handlers from ``mgmtd``. The same goes for *debug* CLI are present in a single file (e.g. a ``xxx_vty.c`` or ``xxx_cli.c`` file) then
handlers. For example: :code:`#ifndef` will need to be used to exclude the non-config CLI handlers from
``mgmtd``. The same goes for unconverted *debug* CLI handlers. For example:
.. code-block:: c .. code-block:: c
@ -121,7 +135,7 @@ handlers. For example:
} }
#ifndef INCLUDE_MGMTD_CMDDEFS_ONLY #ifndef INCLUDE_MGMTD_CMDDEFS_ONLY
DEFPY(daemon_show_oepr, daemon_show_oepr_cmd, DEFPY(daemon_show_oper, daemon_show_oper_cmd,
"show daemon oper [all]" "show daemon oper [all]"
... ...
{ {
@ -140,67 +154,79 @@ handlers. For example:
} }
.. _mgmtd-config-write:
Add Back-End XPATH mappings CLI Config Write Handlers (:code:`cli_show`)
--------------------------- --------------------------------------------
To support writing out the CLI configuration file the northbound API defines a
2 callbacks (:code:`cli_show` and :code:`cli_show_end`). Pointers to these
callbacks used to live side-by-side in a daemons :code:`struct frr_yang_module_info`,
with the daemons back-end configuration and operational state callbacks
(normally in a file named `<daemon>_nb.c`).
However, these 2 functionalities need to be split up now. The *frontend* config
writing callbacks (:code:`cli_show`) should now be linked into ``mgmtd`` while
the *backend* config and oper-state callbacks (e.g., :code:`create`,
:code:`modify`, etc) should continue to be linked into the daemon.
So you will need to define 2 :code:`struct frr_yang_module_info` arrays.
1. The existing array remains in the same place in the daemon, but with all the
:code:`cli_show` handlers removed.
2. The removed :code:`cli_show` handlers should be added to a new
:code:`struct frr_yang_module_info` array. This second array should be
included in the same file that includes that actual function pointed to by
the the :code:`cli_show` callbacks (i.e., the file is compiled into
``mgmtd``).
This new :code:`struct frr_yang_module_info` array is the one to be included
in mgmtd in `mgmt_yang_modules` inside ``mgmtd/mgmt_main.c``.
Back-End XPATH mappings
-----------------------
In order for ``mgmtd`` to direct configuration to your daemon you need to add In order for ``mgmtd`` to direct configuration to your daemon you need to add
some XPATH mappings to ``mgmtd/mgmt_be_adapter.c``. These XPATHs determine which some XPATH mappings to ``mgmtd/mgmt_be_adapter.c``. These XPATHs determine which
configuration changes get sent over the *back-end* interface to your daemon. configuration changes get sent over the *back-end* interface to your daemon.
There are 2 arrays to update the first for config support and the second for
operational state.
Below are the strings added for staticd support: Below are the strings added for staticd config support:
.. code-block:: c .. code-block:: c
static const struct mgmt_be_xpath_map_init mgmt_xpath_map_init[] = { #if HAVE_STATICD
{ static const char *const staticd_xpaths[] = {
.xpath_regexp = "/frr-vrf:lib/*", "/frr-vrf:lib",
.subscr_info = "/frr-interface:lib",
{ "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd",
#if HAVE_STATICD NULL,
[MGMTD_BE_CLIENT_ID_STATICD] = };
MGMT_SUBSCR_VALIDATE_CFG | #endif
MGMT_SUBSCR_NOTIFY_CFG,
#endif
},
},
...
{
.xpath_regexp =
"/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/*",
.subscr_info =
{
#if HAVE_STATICD
[MGMTD_BE_CLIENT_ID_STATICD] =
MGMT_SUBSCR_VALIDATE_CFG |
MGMT_SUBSCR_NOTIFY_CFG,
#endif
},
},
};
#if HAVE_STATICD static const char *const *be_client_xpaths[MGMTD_BE_CLIENT_ID_MAX] = {
static struct mgmt_be_client_xpath staticd_xpaths[] = { #ifdef HAVE_STATICD
{ [MGMTD_BE_CLIENT_ID_STATICD] = staticd_xpaths,
.xpath = "/frr-vrf:lib/*", #endif
.subscribed = MGMT_SUBSCR_VALIDATE_CFG | MGMT_SUBSCR_NOTIFY_CFG, };
},
...
{
.xpath =
"/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/*",
.subscribed = MGMT_SUBSCR_VALIDATE_CFG | MGMT_SUBSCR_NOTIFY_CFG,
},
};
#endif
static struct mgmt_be_client_xpath_map Below are the strings added for zebra operational state support (note zebra is
mgmt_client_xpaths[MGMTD_BE_CLIENT_ID_MAX] = { not conditionalized b/c it should always be present):
#ifdef HAVE_STATICD
[MGMTD_BE_CLIENT_ID_STATICD] = {staticd_xpaths, .. code-block:: c
array_size(staticd_xpaths)},
#endif static const char *const zebra_oper_xpaths[] = {
}; "/frr-interface:lib/interface",
"/frr-vrf:lib/vrf/frr-zebra:zebra",
"/frr-zebra:zebra",
NULL,
};
static const char *const *be_client_oper_xpaths[MGMTD_BE_CLIENT_ID_MAX] = {
[MGMTD_BE_CLIENT_ID_ZEBRA] = zebra_oper_xpaths,
};
MGMTD Internals MGMTD Internals

View file

@ -1,3 +1,6 @@
.. _nb-retrofit:
Retrofitting Configuration Commands Retrofitting Configuration Commands
----------------------------------- -----------------------------------

View file

@ -59,7 +59,7 @@ struct mgmt_be_xpath_map {
* above map as well. * above map as well.
*/ */
#if HAVE_STATICD #if HAVE_STATICD
static const char *const staticd_xpaths[] = { static const char *const staticd_config_xpaths[] = {
"/frr-vrf:lib", "/frr-vrf:lib",
"/frr-interface:lib", "/frr-interface:lib",
"/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd", "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd",
@ -67,10 +67,9 @@ static const char *const staticd_xpaths[] = {
}; };
#endif #endif
static const char *const *be_client_xpaths[MGMTD_BE_CLIENT_ID_MAX] = { static const char *const *be_client_config_xpaths[MGMTD_BE_CLIENT_ID_MAX] = {
#ifdef HAVE_STATICD #ifdef HAVE_STATICD
[MGMTD_BE_CLIENT_ID_STATICD] = staticd_xpaths, [MGMTD_BE_CLIENT_ID_STATICD] = staticd_config_xpaths,
#endif #endif
}; };
@ -190,7 +189,7 @@ static void mgmt_be_xpath_map_init(void)
FOREACH_MGMTD_BE_CLIENT_ID (id) { FOREACH_MGMTD_BE_CLIENT_ID (id) {
/* Initialize the common config init map */ /* Initialize the common config init map */
for (init = be_client_xpaths[id]; init && *init; init++) { for (init = be_client_config_xpaths[id]; init && *init; init++) {
MGMTD_BE_ADAPTER_DBG(" - CFG XPATH: '%s'", *init); MGMTD_BE_ADAPTER_DBG(" - CFG XPATH: '%s'", *init);
mgmt_register_client_xpath(id, *init, true); mgmt_register_client_xpath(id, *init, true);
} }
@ -843,7 +842,8 @@ static bool be_is_client_interested(const char *xpath,
MGMTD_BE_ADAPTER_DBG("Checking client: %s for xpath: '%s'", MGMTD_BE_ADAPTER_DBG("Checking client: %s for xpath: '%s'",
mgmt_be_client_id2name(id), xpath); mgmt_be_client_id2name(id), xpath);
xpaths = config ? be_client_xpaths[id] : be_client_oper_xpaths[id]; xpaths = config ? be_client_config_xpaths[id]
: be_client_oper_xpaths[id];
if (xpaths) { if (xpaths) {
for (; *xpaths; xpaths++) { for (; *xpaths; xpaths++) {
if (mgmt_be_xpath_prefix(*xpaths, xpath)) { if (mgmt_be_xpath_prefix(*xpaths, xpath)) {