summaryrefslogtreecommitdiffstats
path: root/doc/developer/mgmtd-dev.rst
blob: 9839aa8b6c8280ab51e5e28baec8e8e3f666f073 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
..
.. SPDX-License-Identifier: GPL-2.0-or-later
..
.. June 19 2023, Christian Hopps <chopps@labn.net>
..
.. Copyright (c) 2023, LabN Consulting, L.L.C.
..

.. _mgmtd_dev:

MGMTD Development
=================

Overview
^^^^^^^^

``mgmtd`` (Management Daemon) is a new centralized management daemon for FRR.

Previously, ``vtysh`` was the only centralized management service provided.
Internally ``vtysh`` connects to each daemon and sends CLI commands (both
configuration and operational state queries) over a socket connection. This
service only supports CLI which is no longer sufficient.

An important next step was made with the addition of YANG support. A YANG
infrastructure was added through a new development called *northbound*. This
*northbound* interface added the capability of daemons to be configured and
queried using YANG models. However, this interface was per daemon and not
centralized, which is not sufficient.

``mgmtd`` harnesses this new *northbound* interface to provide a centralized
interface for all daemons. It utilizes the daemons YANG models to interact with
each daemon. ``mgmtd`` currently provides the CLI interface for each daemon that
has been converted to it, but in the future RESTCONF and NETCONF servers can
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
<https://github.com/opensourcerouting/frr/wiki/Retrofitting-Configuration-Commands>`_
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
-------------------

Adding support for a *northbound* converted daemon involves very little work. It
requires enabling *frontend* (CLI and YANG) and *backend* (YANG) support.
``mgmtd`` was designed to keep this as simple as possible.

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``)

Back-End Interface:

5. Add XPATHs mappings to a couple arrays to direct ``mgmtd`` at your daemon in
   ``mgmtd/mgmt_be_adapter.c``


Add YANG and CLI into MGMTD
---------------------------

As an example here is the addition made to ``mgmtd/subdir.am`` for adding
``staticd`` support.

.. code-block:: make

   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

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[] = {
           &frr_filter_info,
           ...
   #ifdef HAVE_STATICD
           &(struct frr_yang_module_info){.name = "frr-staticd",
				         .ignore_cbs = true},
   #endif
   }


CLI Handlers
------------

The daemon's CLI handlers for configuration (which having been converted to
*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:

.. code-block:: c

  DEFPY(daemon_one_config, daemon_one_config_cmd,
        "daemon one [optional-arg]"
        ...
  {
        ...
  }

  #ifndef INCLUDE_MGMTD_CMDDEFS_ONLY
  DEFPY(daemon_show_oepr, daemon_show_oepr_cmd,
        "show daemon oper [all]"
        ...
  {
        ...
  }
  #endif /* ifndef INCLUDE_MGMTD_CMDDEFS_ONLY */

  void daemon_vty_init(void)
  {
	install_element(CONFIG_NODE, &daemon_one_config_cmd);
        ...

  #ifndef INCLUDE_MGMTD_CMDDEFS_ONLY
          install_element(ENABLE_NODE, &daemon_show_oper_cmd);
  #endif /* ifndef INCLUDE_MGMTD_CMDDEFS_ONLY */

  }


Add 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.

Below are the strings added for staticd 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
   };


MGMTD Internals
^^^^^^^^^^^^^^^

This section will describe the internal functioning of ``mgmtd``, for now a
couple diagrams are included to aide in source code perusal.


The client side of a CLI change

.. figure:: ../figures/cli-change-client.svg
   :align: center


The server (mgmtd) side of a CLI change

.. figure:: ../figures/cli-change-mgmtd.svg
   :align: center