From a9dc7e9cc0c06ab27d16f44490f560b65569eac0 Mon Sep 17 00:00:00 2001 From: Christian Hopps Date: Sat, 13 Jan 2024 14:26:55 +0000 Subject: [PATCH] doc: mgmtd: update mgmtd conversion doc to be current. Also change `be_client_xpaths` to `be_client_config_xpaths` referred in the doc to make much clearer it's use (since there's a separate `be_client_oper_xpaths`. Signed-off-by: Christian Hopps --- doc/developer/mgmtd-dev.rst | 194 ++++++++++-------- .../retrofitting-configuration-commands.rst | 3 + mgmtd/mgmt_be_adapter.c | 12 +- 3 files changed, 119 insertions(+), 90 deletions(-) diff --git a/doc/developer/mgmtd-dev.rst b/doc/developer/mgmtd-dev.rst index 92911bf65043..d611f9c11b8d 100644 --- a/doc/developer/mgmtd-dev.rst +++ b/doc/developer/mgmtd-dev.rst @@ -37,11 +37,10 @@ easily be added as *front-ends* to mgmtd to support those protocols as well. Converting A Daemon to MGMTD ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -A daemon must first be transitioned to the new *northbound* interface if that -has not already been done (see `this northbound conversion documentation -`_ -for how to do this). Once this is done a few simple steps are all that is -required move the daemon over to ``mgmtd`` control. +A daemon must first be transitioned to the new :ref:`northbound` interface if that +has not already been done (see :ref:`nb-retrofit` for how to do this). Once this +is done a few simple steps are all that is required move the daemon over to +``mgmtd`` control. Overview of Changes ------------------- @@ -52,16 +51,27 @@ requires enabling *frontend* (CLI and YANG) and *backend* (YANG) support. Front-End Interface: -1. Add YANG module file to ``mgmtd/subdir.am`` (e.g., ``yang/frr-staticd.c``) -2. Add YANG module description into array defined in ``mgmtd/mgmt_main.c`` -3. Add CLI handler file[s] to ``mgmtd/subdir.am`` (e.g., ``staticd/static_vty.c``) -4. [if needed] Exclude (#ifndef) non-configuration CLI handlers from CLI source - file (e.g., inside ``staticd/static_vty.c``) +1. Add YANG module file to ``mgmtd/subdir.am`` (e.g., ``yang/frr-staticd.yang.c``). +2. 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 + 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: -5. Add XPATHs mappings to a couple arrays to direct ``mgmtd`` at your daemon in - ``mgmtd/mgmt_be_adapter.c`` +8. In ``mgmtd/mgmt_be_adapter.c`` add xpath prefix mappings to a one or both + 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 @@ -72,44 +82,48 @@ As an example here is the addition made to ``mgmtd/subdir.am`` for adding .. code-block:: make - if STATICD - nodist_mgmtd_mgmtd_SOURCES += \ + if STATICD + nodist_mgmtd_mgmtd_SOURCES += \ yang/frr-staticd.yang.c \ yang/frr-bfdd.yang.c \ # end - nodist_mgmtd_libmgmt_be_nb_la_SOURCES += staticd/static_vty.c - endif + nodist_mgmtd_libmgmt_be_nb_la_SOURCES += staticd/static_vty.c + endif An here is the addition to the modules array in ``mgmtd/mgmt_main.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, ... - #ifdef HAVE_STATICD - &(struct frr_yang_module_info){.name = "frr-staticd", - .ignore_cfg_cbs = true}, - #endif - } + #ifdef HAVE_STATICD + &frr_staticd_info, + #endif + } -CLI Handlers ------------- +CLI Config and Show Handlers +---------------------------- -The daemon's CLI handlers for configuration (which having been converted to -*northbound* now simply generate YANG changes) will be linked directly into +The daemon's CLI handlers for configuration (which having been converted to the +:ref:`northbound` now simply generate YANG changes) will be linked directly into ``mgmtd``. 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 CPP #ifndef's will be required. -Currently ``mgmtd`` supports configuration CLI but not operational -state so if both types of CLI handlers are present in a single file (e.g. a -``xxx_vty.c`` or ``xxx_cli.c`` file ) then #ifndef will be used to exclude these -non-configuration CLI handlers from ``mgmtd``. The same goes for *debug* CLI -handlers. For example: +``mgmtd`` supports both config and operational state. However, many +daemons have not had their operational state CLI commands converted over to the +new YANG based methods. If that is the case and if both types of CLI handlers +are present in a single file (e.g. a ``xxx_vty.c`` or ``xxx_cli.c`` file) then +: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 @@ -121,7 +135,7 @@ handlers. For example: } #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]" ... { @@ -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 `_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 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. +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 - static const struct mgmt_be_xpath_map_init mgmt_xpath_map_init[] = { - { - .xpath_regexp = "/frr-vrf:lib/*", - .subscr_info = - { - #if HAVE_STATICD - [MGMTD_BE_CLIENT_ID_STATICD] = - MGMT_SUBSCR_VALIDATE_CFG | - 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 struct mgmt_be_client_xpath staticd_xpaths[] = { - { - .xpath = "/frr-vrf:lib/*", - .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 - mgmt_client_xpaths[MGMTD_BE_CLIENT_ID_MAX] = { - #ifdef HAVE_STATICD - [MGMTD_BE_CLIENT_ID_STATICD] = {staticd_xpaths, - array_size(staticd_xpaths)}, - #endif - }; + #if HAVE_STATICD + static const char *const staticd_xpaths[] = { + "/frr-vrf:lib", + "/frr-interface:lib", + "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd", + NULL, + }; + #endif + + static const char *const *be_client_xpaths[MGMTD_BE_CLIENT_ID_MAX] = { + #ifdef HAVE_STATICD + [MGMTD_BE_CLIENT_ID_STATICD] = staticd_xpaths, + #endif + }; + +Below are the strings added for zebra operational state support (note zebra is +not conditionalized b/c it should always be present): + +.. code-block:: c + + 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 diff --git a/doc/developer/northbound/retrofitting-configuration-commands.rst b/doc/developer/northbound/retrofitting-configuration-commands.rst index 41f9902b6ac7..6ccc578a0de8 100644 --- a/doc/developer/northbound/retrofitting-configuration-commands.rst +++ b/doc/developer/northbound/retrofitting-configuration-commands.rst @@ -1,3 +1,6 @@ + +.. _nb-retrofit: + Retrofitting Configuration Commands ----------------------------------- diff --git a/mgmtd/mgmt_be_adapter.c b/mgmtd/mgmt_be_adapter.c index eb6e79f2a5e9..2be70901a840 100644 --- a/mgmtd/mgmt_be_adapter.c +++ b/mgmtd/mgmt_be_adapter.c @@ -59,7 +59,7 @@ struct mgmt_be_xpath_map { * above map as well. */ #if HAVE_STATICD -static const char *const staticd_xpaths[] = { +static const char *const staticd_config_xpaths[] = { "/frr-vrf:lib", "/frr-interface:lib", "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd", @@ -67,10 +67,9 @@ static const char *const staticd_xpaths[] = { }; #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 - [MGMTD_BE_CLIENT_ID_STATICD] = staticd_xpaths, + [MGMTD_BE_CLIENT_ID_STATICD] = staticd_config_xpaths, #endif }; @@ -190,7 +189,7 @@ static void mgmt_be_xpath_map_init(void) FOREACH_MGMTD_BE_CLIENT_ID (id) { /* 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); 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'", 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) { for (; *xpaths; xpaths++) { if (mgmt_be_xpath_prefix(*xpaths, xpath)) {