summaryrefslogtreecommitdiff
path: root/doc/developer
diff options
context:
space:
mode:
Diffstat (limited to 'doc/developer')
-rw-r--r--doc/developer/cli.rst10
-rw-r--r--doc/developer/frr-release-procedure.rst15
-rw-r--r--doc/developer/lists.rst186
-rw-r--r--doc/developer/logging.rst4
-rw-r--r--doc/developer/topotests.rst6
-rw-r--r--doc/developer/workflow.rst11
6 files changed, 143 insertions, 89 deletions
diff --git a/doc/developer/cli.rst b/doc/developer/cli.rst
index 9254eb4739..ff6c4f6e16 100644
--- a/doc/developer/cli.rst
+++ b/doc/developer/cli.rst
@@ -48,6 +48,16 @@ a node and returns the parent of the node. This interface causes all manner of
insidious problems, even for experienced developers, and needs to be fixed at
some point in the future.
+Deprecation of old style of commands
+------------------------------------
+
+There are currently 2 styles of defining commands within a FRR source file.
+``DEFUN`` and ``DEFPY``. ``DEFPY`` should be used for all new commands that
+a developer is writing. This is because it allows for much better handling
+of command line arguments as well as ensuring that input is correct. ``DEFUN``
+is listed here for historical reasons as well as for ensuring that existing
+code can be understood by new developers.
+
Defining Commands
-----------------
All definitions for the CLI system are exposed in ``lib/command.h``. In this
diff --git a/doc/developer/frr-release-procedure.rst b/doc/developer/frr-release-procedure.rst
index 6a7f9c4ca9..4ef0ca8416 100644
--- a/doc/developer/frr-release-procedure.rst
+++ b/doc/developer/frr-release-procedure.rst
@@ -204,7 +204,7 @@ Stage 3 - Publish
.. code-block:: console
- cp <old-version>.md <version>.md
+ cp content/release/<old-version>.md content/release/<new-version>.md
Paste the GitHub release announcement text into this document, and **remove
line breaks**. In other words, this::
@@ -220,10 +220,17 @@ Stage 3 - Publish
This is very important otherwise the announcement will be unreadable on the
website.
- Make sure to add a link to the GitHub releases page at the top.
+ To get the number of commiters and commits, here is a couple of handy commands:
+
+ .. code-block:: console
- Once finished, manually add a new entry into ``index.html`` to link to this
- new announcement. Look at past commits to see how to do this.
+ # The number of commits
+ % git log --oneline --no-merges base_8.2...base_8.1 | wc -l
+
+ # The number of commiters
+ % git shortlog --summary --no-merges base_8.2...base_8.1 | wc -l
+
+ Make sure to add a link to the GitHub releases page at the top.
#. Deploy the updated ``frr-www`` on the frrouting.org web server and verify
that the announcement text is visible.
diff --git a/doc/developer/lists.rst b/doc/developer/lists.rst
index dc8f236927..4eaa85115e 100644
--- a/doc/developer/lists.rst
+++ b/doc/developer/lists.rst
@@ -1,23 +1,23 @@
.. _lists:
-List implementations
+Type-safe containers
====================
.. note::
- The term *list* is used generically for lists, skiplists, trees and hash
- tables in this document.
+ This section previously used the term *list*; it was changed to *container*
+ to be more clear.
-Common list interface
----------------------
+Common container interface
+--------------------------
-FRR includes a set of list-like data structure implementations with abstracted
+FRR includes a set of container implementations with abstracted
common APIs. The purpose of this is easily allow swapping out one
data structure for another while also making the code easier to read and write.
-There is one API for unsorted lists and a similar but not identical API for
-sorted lists - and heaps use a middle ground of both.
+There is one API for unsorted containers and a similar but not identical API
+for sorted containers - and heaps use a middle ground of both.
-For unsorted lists, the following implementations exist:
+For unsorted containers, the following implementations exist:
- single-linked list with tail pointer (e.g. STAILQ in BSD)
@@ -31,7 +31,7 @@ Being partially sorted, the oddball structure:
- an 8-ary heap
-For sorted lists, these data structures are implemented:
+For sorted containers, these data structures are implemented:
- single-linked list
@@ -44,7 +44,7 @@ For sorted lists, these data structures are implemented:
- hash table (note below)
Except for hash tables, each of the sorted data structures has a variant with
-unique and non-unique list items. Hash tables always require unique items
+unique and non-unique items. Hash tables always require unique items
and mostly follow the "sorted" API but use the hash value as sorting
key. Also, iterating while modifying does not work with hash tables.
Conversely, the heap always has non-unique items, but iterating while modifying
@@ -60,7 +60,7 @@ in the future:
The APIs are all designed to be as type-safe as possible. This means that
-there will be a compiler warning when an item doesn't match the list, or
+there will be a compiler warning when an item doesn't match the container, or
the return value has a different type, or other similar situations. **You
should never use casts with these APIs.** If a cast is neccessary in relation
to these APIs, there is probably something wrong with the overall design.
@@ -100,35 +100,39 @@ Available types:
Functions provided:
-+------------------------------------+------+------+------+---------+------------+
-| Function | LIST | HEAP | HASH | \*_UNIQ | \*_NONUNIQ |
-+====================================+======+======+======+=========+============+
-| _init, _fini | yes | yes | yes | yes | yes |
-+------------------------------------+------+------+------+---------+------------+
-| _first, _next, _next_safe, | yes | yes | yes | yes | yes |
-| | | | | | |
-| _const_first, _const_next | | | | | |
-+------------------------------------+------+------+------+---------+------------+
-| _swap_all | yes | yes | yes | yes | yes |
-+------------------------------------+------+------+------+---------+------------+
-| _anywhere | yes | -- | -- | -- | -- |
-+------------------------------------+------+------+------+---------+------------+
-| _add_head, _add_tail, _add_after | yes | -- | -- | -- | -- |
-+------------------------------------+------+------+------+---------+------------+
-| _add | -- | yes | yes | yes | yes |
-+------------------------------------+------+------+------+---------+------------+
-| _member | yes | yes | yes | yes | yes |
-+------------------------------------+------+------+------+---------+------------+
-| _del, _pop | yes | yes | yes | yes | yes |
-+------------------------------------+------+------+------+---------+------------+
-| _find, _const_find | -- | -- | yes | yes | -- |
-+------------------------------------+------+------+------+---------+------------+
-| _find_lt, _find_gteq, | -- | -- | -- | yes | yes |
-| | | | | | |
-| _const_find_lt, _const_find_gteq | | | | | |
-+------------------------------------+------+------+------+---------+------------+
-| use with frr_each() macros | yes | yes | yes | yes | yes |
-+------------------------------------+------+------+------+---------+------------+
++------------------------------------+-------+------+------+---------+------------+
+| Function | LIST | HEAP | HASH | \*_UNIQ | \*_NONUNIQ |
++====================================+=======+======+======+=========+============+
+| _init, _fini | yes | yes | yes | yes | yes |
++------------------------------------+-------+------+------+---------+------------+
+| _first, _next, _next_safe, | yes | yes | yes | yes | yes |
+| | | | | | |
+| _const_first, _const_next | | | | | |
++------------------------------------+-------+------+------+---------+------------+
+| _last, _prev, _prev_safe, | DLIST | -- | -- | RB only | RB only |
+| | only | | | | |
+| _const_last, _const_prev | | | | | |
++------------------------------------+-------+------+------+---------+------------+
+| _swap_all | yes | yes | yes | yes | yes |
++------------------------------------+-------+------+------+---------+------------+
+| _anywhere | yes | -- | -- | -- | -- |
++------------------------------------+-------+------+------+---------+------------+
+| _add_head, _add_tail, _add_after | yes | -- | -- | -- | -- |
++------------------------------------+-------+------+------+---------+------------+
+| _add | -- | yes | yes | yes | yes |
++------------------------------------+-------+------+------+---------+------------+
+| _member | yes | yes | yes | yes | yes |
++------------------------------------+-------+------+------+---------+------------+
+| _del, _pop | yes | yes | yes | yes | yes |
++------------------------------------+-------+------+------+---------+------------+
+| _find, _const_find | -- | -- | yes | yes | -- |
++------------------------------------+-------+------+------+---------+------------+
+| _find_lt, _find_gteq, | -- | -- | -- | yes | yes |
+| | | | | | |
+| _const_find_lt, _const_find_gteq | | | | | |
++------------------------------------+-------+------+------+---------+------------+
+| use with frr_each() macros | yes | yes | yes | yes | yes |
++------------------------------------+-------+------+------+---------+------------+
@@ -136,7 +140,7 @@ Datastructure type setup
------------------------
Each of the data structures has a ``PREDECL_*`` and a ``DECLARE_*`` macro to
-set up an "instantiation" of the list. This works somewhat similar to C++
+set up an "instantiation" of the container. This works somewhat similar to C++
templating, though much simpler.
**In all following text, the Z prefix is replaced with a name choosen
@@ -174,8 +178,8 @@ The common setup pattern will look like this:
``XXX`` is replaced with the name of the data structure, e.g. ``SKIPLIST``
or ``ATOMLIST``. The ``DECLARE_XXX`` invocation can either occur in a `.h`
-file (if the list needs to be accessed from several C files) or it can be
-placed in a `.c` file (if the list is only accessed from that file.) The
+file (if the container needs to be accessed from several C files) or it can be
+placed in a `.c` file (if the container is only accessed from that file.) The
``PREDECL_XXX`` invocation defines the ``struct Z_item`` and ``struct
Z_head`` types and must therefore occur before these are used.
@@ -196,7 +200,7 @@ The following iteration macros work across all data structures:
for (item = Z_first(&head); item; item = Z_next(&head, item))
- Note that this will fail if the list is modified while being iterated
+ Note that this will fail if the container is modified while being iterated
over.
.. c:macro:: frr_each_safe(Z, head, item)
@@ -220,8 +224,8 @@ The following iteration macros work across all data structures:
.. c:macro:: frr_each_from(Z, head, item, from)
- Iterates over the list, starting at item ``from``. This variant is "safe"
- as in the previous macro. Equivalent to:
+ Iterates over the container, starting at item ``from``. This variant is
+ "safe" as in the previous macro. Equivalent to:
.. code-block:: c
@@ -236,6 +240,13 @@ The following iteration macros work across all data structures:
resume iteration after breaking out of the loop by keeping the ``from``
value persistent and reusing it for the next loop.
+.. c:macro:: frr_rev_each(Z, head, item)
+.. c:macro:: frr_rev_each_safe(Z, head, item)
+.. c:macro:: frr_rev_each_from(Z, head, item, from)
+
+ Reverse direction variants of the above. Only supported on containers that
+ implement ``_last`` and ``_prev`` (i.e. ``RBTREE`` and ``DLIST``).
+
To iterate over ``const`` pointers, add ``_const`` to the name of the
datastructure (``Z`` above), e.g. ``frr_each (mylist, head, item)`` becomes
``frr_each (mylist_const, head, item)``.
@@ -243,24 +254,24 @@ datastructure (``Z`` above), e.g. ``frr_each (mylist, head, item)`` becomes
Common API
----------
-The following documentation assumes that a list has been defined using
-``Z`` as the name, and ``itemtype`` being the type of the list items (e.g.
+The following documentation assumes that a container has been defined using
+``Z`` as the name, and ``itemtype`` being the type of the items (e.g.
``struct item``.)
.. c:function:: void Z_init(struct Z_head *)
- Initializes the list for use. For most implementations, this just sets
+ Initializes the container for use. For most implementations, this just sets
some values. Hash tables are the only implementation that allocates
memory in this call.
.. c:function:: void Z_fini(struct Z_head *)
- Reverse the effects of :c:func:`Z_init()`. The list must be empty
+ Reverse the effects of :c:func:`Z_init()`. The container must be empty
when this function is called.
.. warning::
- This function may ``assert()`` if the list is not empty.
+ This function may ``assert()`` if the container is not empty.
.. c:function:: size_t Z_count(const struct Z_head *)
@@ -270,7 +281,7 @@ The following documentation assumes that a list has been defined using
.. note::
- For atomic lists with concurrent access, the value will already be
+ For atomic containers with concurrent access, the value will already be
outdated by the time this function returns and can therefore only be
used as an estimate.
@@ -291,6 +302,12 @@ The following documentation assumes that a list has been defined using
empty. This is O(1) for all data structures except red-black trees
where it is O(log n).
+.. c:function:: const itemtype *Z_const_last(const struct Z_head *)
+.. c:function:: itemtype *Z_last(struct Z_head *)
+
+ Last item in the structure, or ``NULL``. Only available on containers
+ that support reverse iteration (i.e. ``RBTREE`` and ``DLIST``).
+
.. c:function:: itemtype *Z_pop(struct Z_head *)
Remove and return the first item in the structure, or ``NULL`` if the
@@ -300,7 +317,7 @@ The following documentation assumes that a list has been defined using
This function can be used to build queues (with unsorted structures) or
priority queues (with sorted structures.)
- Another common pattern is deleting all list items:
+ Another common pattern is deleting all container items:
.. code-block:: c
@@ -329,16 +346,23 @@ The following documentation assumes that a list has been defined using
Same as :c:func:`Z_next()`, except that ``NULL`` is returned if
``prev`` is ``NULL``.
+.. c:function:: const itemtype *Z_const_prev(const struct Z_head *, const itemtype *next)
+.. c:function:: itemtype *Z_prev(struct Z_head *, itemtype *next)
+.. c:function:: itemtype *Z_prev_safe(struct Z_head *, itemtype *next)
+
+ As above, but preceding item. Only available on structures that support
+ reverse iteration (i.e. ``RBTREE`` and ``DLIST``).
+
.. c:function:: itemtype *Z_del(struct Z_head *, itemtype *item)
- Remove ``item`` from the list and return it.
+ Remove ``item`` from the container and return it.
.. note::
This function's behaviour is undefined if ``item`` is not actually
- on the list. Some structures return ``NULL`` in this case while others
- return ``item``. The function may also call ``assert()`` (but most
- don't.)
+ on the container. Some structures return ``NULL`` in this case while
+ others return ``item``. The function may also call ``assert()`` (but
+ most don't.)
.. c:function:: itemtype *Z_swap_all(struct Z_head *, struct Z_head *)
@@ -427,8 +451,8 @@ API for sorted structures
-------------------------
Sorted data structures do not need to have an insertion position specified,
-therefore the insertion calls are different from unsorted lists. Also,
-sorted lists can be searched for a value.
+therefore the insertion calls are different from unsorted containers. Also,
+sorted containers can be searched for a value.
.. c:macro:: DECLARE_XXX_UNIQ(Z, type, field, compare_func)
@@ -439,7 +463,7 @@ sorted lists can be searched for a value.
created for this instantiation. ``DECLARE_XXX(foo, ...)``
gives ``struct foo_item``, ``foo_add()``, ``foo_count()``, etc. Note
that this must match the value given in ``PREDECL_XXX(foo)``.
- :param typename type: Specifies the data type of the list items, e.g.
+ :param typename type: Specifies the data type of the items, e.g.
``struct item``. Note that ``struct`` must be added here, it is not
automatically added.
:param token field: References a struct member of ``type`` that must be
@@ -448,29 +472,29 @@ sorted lists can be searched for a value.
:param funcptr compare_func: Item comparison function, must have the
following function signature:
``int function(const itemtype *, const itemtype*)``. This function
- may be static if the list is only used in one file.
+ may be static if the container is only used in one file.
.. c:macro:: DECLARE_XXX_NONUNIQ(Z, type, field, compare_func)
- Same as above, but allow adding multiple items to the list that compare
+ Same as above, but allow adding multiple items to the container that compare
as equal in ``compare_func``. Ordering between these items is undefined
- and depends on the list implementation.
+ and depends on the container implementation.
.. c:function:: itemtype *Z_add(struct Z_head *, itemtype *item)
Insert an item at the appropriate sorted position. If another item exists
- in the list that compares as equal (``compare_func()`` == 0), ``item`` is
- not inserted into the list and the already-existing item in the list is
+ in the container that compares as equal (``compare_func()`` == 0), ``item``
+ is not inserted and the already-existing item in the container is
returned. Otherwise, on successful insertion, ``NULL`` is returned.
- For ``_NONUNIQ`` lists, this function always returns NULL since ``item``
- can always be successfully added to the list.
+ For ``_NONUNIQ`` containers, this function always returns NULL since
+ ``item`` can always be successfully added to the container.
.. c:function:: const itemtype *Z_const_find(const struct Z_head *, const itemtype *ref)
.. c:function:: itemtype *Z_find(struct Z_head *, const itemtype *ref)
- Search the list for an item that compares equal to ``ref``. If no equal
- item is found, return ``NULL``.
+ Search the container for an item that compares equal to ``ref``. If no
+ equal item is found, return ``NULL``.
This function is likely used with a temporary stack-allocated value for
``ref`` like so:
@@ -483,21 +507,21 @@ sorted lists can be searched for a value.
.. note::
- The ``Z_find()`` function is only available for lists that contain
- unique items (i.e. ``DECLARE_XXX_UNIQ``.) This is because on a list
- containing non-unique items, more than one item may compare as equal to
+ The ``Z_find()`` function is only available for containers that contain
+ unique items (i.e. ``DECLARE_XXX_UNIQ``.) This is because on a container
+ with non-unique items, more than one item may compare as equal to
the item that is searched for.
.. c:function:: const itemtype *Z_const_find_gteq(const struct Z_head *, const itemtype *ref)
.. c:function:: itemtype *Z_find_gteq(struct Z_head *, const itemtype *ref)
- Search the list for an item that compares greater or equal to
+ Search the container for an item that compares greater or equal to
``ref``. See :c:func:`Z_find()` above.
.. c:function:: const itemtype *Z_const_find_lt(const struct Z_head *, const itemtype *ref)
.. c:function:: itemtype *Z_find_lt(struct Z_head *, const itemtype *ref)
- Search the list for an item that compares less than
+ Search the container for an item that compares less than
``ref``. See :c:func:`Z_find()` above.
@@ -511,7 +535,7 @@ API for hash tables
created for this instantiation. ``DECLARE_XXX(foo, ...)``
gives ``struct foo_item``, ``foo_add()``, ``foo_count()``, etc. Note
that this must match the value given in ``PREDECL_XXX(foo)``.
- :param typename type: Specifies the data type of the list items, e.g.
+ :param typename type: Specifies the data type of the items, e.g.
``struct item``. Note that ``struct`` must be added here, it is not
automatically added.
:param token field: References a struct member of ``type`` that must be
@@ -520,7 +544,7 @@ API for hash tables
:param funcptr compare_func: Item comparison function, must have the
following function signature:
``int function(const itemtype *, const itemtype*)``. This function
- may be static if the list is only used in one file. For hash tables,
+ may be static if the container is only used in one file. For hash tables,
this function is only used to check for equality, the ordering is
ignored.
:param funcptr hash_func: Hash calculation function, must have the
@@ -725,13 +749,9 @@ Head removal (pop) and deallocation:
FAQ
---
-What are the semantics of ``const`` in the list APIs?
+What are the semantics of ``const`` in the container APIs?
``const`` pointers to list heads and/or items are interpreted to mean that
- both the list itself as well as the data items are read-only.
-
-Why is there no "is this item on a/the list" test?
- It's slow for several of the data structures, and the work of adding it
- just hasn't been done. It can certainly be added if it's needed.
+ both the container itself as well as the data items are read-only.
Why is it ``PREDECL`` + ``DECLARE`` instead of ``DECLARE`` + ``DEFINE``?
The rule is that a ``DEFINE`` must be in a ``.c`` file, and linked exactly
diff --git a/doc/developer/logging.rst b/doc/developer/logging.rst
index 4e6fc04206..7046361204 100644
--- a/doc/developer/logging.rst
+++ b/doc/developer/logging.rst
@@ -163,6 +163,10 @@ Networking data types
- :c:union:`prefixptr` (dereference to get :c:struct:`prefix`)
- :c:union:`prefixconstptr` (dereference to get :c:struct:`prefix`)
+ Options:
+
+ ``%pFXh``: (address only) :frrfmtout:`1.2.3.0` / :frrfmtout:`fe80::1234`
+
.. frrfmt:: %pPSG4 (struct prefix_sg *)
:frrfmtout:`(*,1.2.3.4)`
diff --git a/doc/developer/topotests.rst b/doc/developer/topotests.rst
index fa1fd20067..6c1d9148d1 100644
--- a/doc/developer/topotests.rst
+++ b/doc/developer/topotests.rst
@@ -35,6 +35,9 @@ Installing Topotest Requirements
python2 -m pip install 'exabgp<4.0.0'
useradd -d /var/run/exabgp/ -s /bin/false exabgp
+ # To enable the gRPC topotest install:
+ python3 -m pip install grpcio grpcio-tools
+
Enable Coredumps
""""""""""""""""
@@ -1088,6 +1091,9 @@ Requirements:
a pull request. This ensures we have a unified code style.
- Mark test modules with pytest markers depending on the daemons used during the
tests (see :ref:`topotests-markers`)
+- Always use IPv4 :rfc:`5737` (``192.0.2.0/24``, ``198.51.100.0/24``,
+ ``203.0.113.0/24``) and IPv6 :rfc:`3849` (``2001:db8::/32``) ranges reserved
+ for documentation.
Tips:
diff --git a/doc/developer/workflow.rst b/doc/developer/workflow.rst
index 45bee17b71..af8756a909 100644
--- a/doc/developer/workflow.rst
+++ b/doc/developer/workflow.rst
@@ -346,6 +346,13 @@ Pre-submission Checklist
the new feature within our existing CI infrastructure. Also the
addition of automated testing to cover any pull request is encouraged.
+- All new code must use the current latest version of acceptable code.
+
+ - If a daemon is converted to YANG, then new code must use YANG.
+ - DEFPY's must be used for new cli
+ - Typesafe lists must be used
+ - printf formatting changes must be used
+
.. _signing-off:
Signing Off
@@ -1250,8 +1257,8 @@ CLI changes
-----------
CLI's are a complicated ugly beast. Additions or changes to the CLI should use
-a DEFUN to encapsulate one setting as much as is possible. Additionally as new
-DEFUN's are added to the system, documentation should be provided for the new
+a DEFPY to encapsulate one setting as much as is possible. Additionally as new
+DEFPY's are added to the system, documentation should be provided for the new
commands.
Backwards Compatibility