diff options
Diffstat (limited to 'doc/developer')
| -rw-r--r-- | doc/developer/conf.py | 1 | ||||
| -rw-r--r-- | doc/developer/link-state.rst | 19 | ||||
| -rw-r--r-- | doc/developer/lists.rst | 51 | ||||
| -rw-r--r-- | doc/developer/locking.rst | 8 | ||||
| -rw-r--r-- | doc/developer/logging.rst | 6 | ||||
| -rw-r--r-- | doc/developer/memtypes.rst | 2 | ||||
| -rw-r--r-- | doc/developer/rcu.rst | 8 | ||||
| -rw-r--r-- | doc/developer/topotests.rst | 11 | ||||
| -rw-r--r-- | doc/developer/workflow.rst | 59 |
9 files changed, 128 insertions, 37 deletions
diff --git a/doc/developer/conf.py b/doc/developer/conf.py index 8f282c0790..61df6e0e60 100644 --- a/doc/developer/conf.py +++ b/doc/developer/conf.py @@ -138,6 +138,7 @@ exclude_patterns = [ "_build", "building-libyang.rst", "topotests-snippets.rst", + "topotests-markers.rst", "include-compile.rst", ] diff --git a/doc/developer/link-state.rst b/doc/developer/link-state.rst index 1cbaf27ffe..2072595e36 100644 --- a/doc/developer/link-state.rst +++ b/doc/developer/link-state.rst @@ -53,15 +53,15 @@ Data structures 3 types of Link State structure have been defined: -.. c:type:: struct ls_node +.. c:struct:: ls_node that groups all information related to a node -.. c:type:: struct ls_attributes +.. c:struct:: ls_attributes that groups all information related to a link -.. c:type:: struct ls_prefix +.. c:struct:: ls_prefix that groups all information related to a prefix @@ -73,7 +73,7 @@ identifier which advertises the Link State and a bit mask as flags to indicates which parameters are valid i.e. for which the value is valid and corresponds to a Link State information conveyed by the routing protocol. -.. c:type:: struct ls_node_id +.. c:struct:: ls_node_id defines the Node identifier as router ID IPv4 address plus the area ID for OSPF or the ISO System ID plus the IS-IS level for IS-IS. @@ -159,10 +159,11 @@ A unique Key is used to identify both Vertices and Edges within the Graph. 4 data structures have been defined to implement the Graph model: -.. c:type:: struct ls_vertex -.. c:type:: struct ls_edge -.. c:type:: struct ls_prefix -.. c:type:: struct ls_ted +.. c:struct:: ls_vertex +.. c:struct:: ls_edge +.. c:struct:: ls_ted + + - :c:struct:`ls_prefix` TED stores Vertex, Edge and Subnet elements with a RB Tree structure. The Vertex key corresponds to the Router ID for OSPF and ISO System ID for @@ -412,7 +413,7 @@ Data Structures The Link State Message is defined to convey Link State parameters from the routing protocol (OSPF or IS-IS) to other daemons e.g. BGP. -.. c:type:: struct ls_message +.. c:struct:: ls_message The structure is composed of: diff --git a/doc/developer/lists.rst b/doc/developer/lists.rst index 553bd1f596..dc8f236927 100644 --- a/doc/developer/lists.rst +++ b/doc/developer/lists.rst @@ -106,19 +106,25 @@ Functions provided: | _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 | @@ -182,7 +188,7 @@ Common iteration macros The following iteration macros work across all data structures: -.. c:function:: frr_each(Z, &head, item) +.. c:macro:: frr_each(Z, head, item) Equivalent to: @@ -193,7 +199,7 @@ The following iteration macros work across all data structures: Note that this will fail if the list is modified while being iterated over. -.. c:function:: frr_each_safe(Z, &head, item) +.. c:macro:: frr_each_safe(Z, head, item) Same as the previous, but the next element is pre-loaded into a "hidden" variable (named ``Z_safe``.) Equivalent to: @@ -212,7 +218,7 @@ The following iteration macros work across all data structures: tables is resized while iterating. This will cause items to be skipped or iterated over twice. -.. c:function:: frr_each_from(Z, &head, item, from) +.. 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: @@ -268,6 +274,16 @@ The following documentation assumes that a list has been defined using outdated by the time this function returns and can therefore only be used as an estimate. +.. c:function:: bool Z_member(const struct Z_head *, const itemtype *) + + Determines whether some item is a member of the given container. The + item must either be valid on some container, or set to all zeroes. + + On some containers, if no faster way to determine membership is possible, + this is simply ``item == Z_find(head, item)``. + + Not currently available for atomic containers. + .. c:function:: const itemtype *Z_const_first(const struct Z_head *) .. c:function:: itemtype *Z_first(struct Z_head *) @@ -297,7 +313,7 @@ The following documentation assumes that a list has been defined using affected by the "modification while iterating" problem. To remove all items from a hash table, use the loop demonstrated above. -.. c:function:: const itemtype *Z_next(const struct Z_head *, const itemtype *prev) +.. c:function:: const itemtype *Z_const_next(const struct Z_head *, const itemtype *prev) .. c:function:: itemtype *Z_next(struct Z_head *, itemtype *prev) Return the item that follows after ``prev``, or ``NULL`` if ``prev`` is @@ -346,7 +362,7 @@ are several functions exposed to insert data: ``item`` must not be ``NULL`` for any of the following functions. -.. c:function:: DECLARE_XXX(Z, type, field) +.. c:macro:: DECLARE_XXX(Z, type, field) :param listtype XXX: ``LIST``, ``DLIST`` or ``ATOMLIST`` to select a data structure implementation. @@ -396,6 +412,17 @@ are several functions exposed to insert data: maybe flip the order of ``item`` & ``after``? ``Z_add_after(head, item, after)`` +.. c:function:: bool Z_anywhere(const itemtype *) + + Returns whether an item is a member of *any* container of this type. + The item must either be valid on some container, or set to all zeroes. + + Guaranteed to be fast (pointer compare or similar.) + + Not currently available for sorted and atomic containers. Might be added + for sorted containers at some point (when needed.) + + API for sorted structures ------------------------- @@ -403,7 +430,7 @@ 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. -.. c:function:: DECLARE_XXX_UNIQ(Z, type, field, compare_func) +.. c:macro:: DECLARE_XXX_UNIQ(Z, type, field, compare_func) :param listtype XXX: One of the following: ``SORTLIST`` (single-linked sorted list), ``SKIPLIST`` (skiplist), @@ -423,7 +450,7 @@ sorted lists can be searched for a value. ``int function(const itemtype *, const itemtype*)``. This function may be static if the list is only used in one file. -.. c:function:: DECLARE_XXX_NONUNIQ(Z, type, field, compare_func) +.. c:macro:: DECLARE_XXX_NONUNIQ(Z, type, field, compare_func) Same as above, but allow adding multiple items to the list that compare as equal in ``compare_func``. Ordering between these items is undefined @@ -439,7 +466,7 @@ sorted lists can be searched for a value. For ``_NONUNIQ`` lists, this function always returns NULL since ``item`` can always be successfully added to the list. -.. c:function:: const itemtype *Z_find(const struct Z_head *, const itemtype *ref) +.. 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 @@ -461,13 +488,13 @@ sorted lists can be searched for a value. containing non-unique items, more than one item may compare as equal to the item that is searched for. -.. c:function:: const itemtype *Z_find_gteq(const struct Z_head *, const itemtype *ref) +.. 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 ``ref``. See :c:func:`Z_find()` above. -.. c:function:: const itemtype *Z_find_lt(const struct Z_head *, const itemtype *ref) +.. 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 @@ -477,9 +504,9 @@ sorted lists can be searched for a value. API for hash tables ------------------- -.. c:function:: DECLARE_XXX(Z, type, field, compare_func, hash_func) +.. c:macro:: DECLARE_HASH(Z, type, field, compare_func, hash_func) - :param listtype XXX: Only ``HASH`` is currently available. + :param listtype HASH: Only ``HASH`` is currently available. :param token Z: Gives the name prefix that is used for the functions created for this instantiation. ``DECLARE_XXX(foo, ...)`` gives ``struct foo_item``, ``foo_add()``, ``foo_count()``, etc. Note diff --git a/doc/developer/locking.rst b/doc/developer/locking.rst index d698789f9f..c8366480d2 100644 --- a/doc/developer/locking.rst +++ b/doc/developer/locking.rst @@ -7,7 +7,9 @@ FRR ships two small wrappers around ``pthread_mutex_lock()`` / ``pthread_mutex_unlock``. Use ``#include "frr_pthread.h"`` to get these macros. -.. c:function:: frr_with_mutex(pthread_mutex_t *mutex) +.. c:macro:: frr_with_mutex(mutex) + + (With ``pthread_mutex_t *mutex``.) Begin a C statement block that is executed with the mutex locked. Any exit from the block (``break``, ``return``, ``goto``, end of block) will @@ -43,7 +45,9 @@ macros. statement works correctly, FRR coding style requires that this macro always be used with a ``{ ... }`` block. -.. c:function:: frr_mutex_lock_autounlock(pthread_mutex_t *mutex) +.. c:macro:: frr_mutex_lock_autounlock(mutex) + + (With ``pthread_mutex_t *mutex``.) Lock mutex and unlock at the end of the current C statement block:: diff --git a/doc/developer/logging.rst b/doc/developer/logging.rst index 681fc1173c..eaf8625efa 100644 --- a/doc/developer/logging.rst +++ b/doc/developer/logging.rst @@ -489,7 +489,7 @@ calls to :c:func:`zlog_tls_buffer_flush()` in appropriate places: buffer. This function is safe to call regardless of the per-thread log buffer being set up / in use or not. -When working with threads that do not use the :c:type:`struct thread_master` +When working with threads that do not use the :c:struct:`thread_master` event loop, per-thread buffers can be managed with: .. c:function:: void zlog_tls_buffer_init(void) @@ -531,7 +531,7 @@ that they use. Basic internals ^^^^^^^^^^^^^^^ -.. c:type:: struct zlog_target +.. c:struct:: zlog_target This struct needs to be filled in by any log target and then passed to :c:func:`zlog_target_replace()`. After it has been registered, @@ -570,7 +570,7 @@ Basic internals Allocates a logging target struct. Note that the ``oldzt`` argument may be ``NULL`` to allocate a "from scratch". If ``oldzt`` is not ``NULL``, the - generic bits in :c:type:`struct zlog_target` are copied. **Target specific + generic bits in :c:struct:`zlog_target` are copied. **Target specific bits are not copied.** .. c:function:: struct zlog_target *zlog_target_replace(struct zlog_target *oldzt, struct zlog_target *newzt) diff --git a/doc/developer/memtypes.rst b/doc/developer/memtypes.rst index 08dad7fb68..2e181c4f2b 100644 --- a/doc/developer/memtypes.rst +++ b/doc/developer/memtypes.rst @@ -42,7 +42,7 @@ Example: Definition ---------- -.. c:type:: struct memtype +.. c:struct:: memtype This is the (internal) type used for MTYPE definitions. The macros below should be used to create these, but in some cases it is useful to pass a diff --git a/doc/developer/rcu.rst b/doc/developer/rcu.rst index c2ddf93f53..c8248194b7 100644 --- a/doc/developer/rcu.rst +++ b/doc/developer/rcu.rst @@ -133,9 +133,9 @@ atomic ops & datastructures with other types of locking, e.g. rwlocks. become invalid, as another thread may have called :c:func:`rcu_free` on them. -.. c:type:: struct rcu_head -.. c:type:: struct rcu_head_close -.. c:type:: struct rcu_action +.. c:struct:: rcu_head +.. c:struct:: rcu_head_close +.. c:struct:: rcu_action The ``rcu_head`` structures are small (16-byte) bits that contain the queueing machinery for the RCU sweeper/cleanup mechanisms. @@ -209,7 +209,7 @@ atomic ops & datastructures with other types of locking, e.g. rwlocks. Internals ^^^^^^^^^ -.. c:type:: struct rcu_thread +.. c:struct:: rcu_thread Per-thread state maintained by the RCU code, set up by the following functions. A pointer to a thread's own ``rcu_thread`` is saved in diff --git a/doc/developer/topotests.rst b/doc/developer/topotests.rst index b4f6ec521c..d8b3650944 100644 --- a/doc/developer/topotests.rst +++ b/doc/developer/topotests.rst @@ -137,14 +137,14 @@ Topotests must be run as root. Normally this will be accomplished through the use of the ``sudo`` command. In order for topotests to be able to open new windows (either XTerm or byobu/screen/tmux windows) certain environment variables must be passed through the sudo command. One way to do this is to -specify the :option:`-E` flag to ``sudo``. This will carry over most if not all +specify the ``-E`` flag to ``sudo``. This will carry over most if not all your environment variables include ``PATH``. For example: .. code:: shell sudo -E python3 -m pytest -s -v -If you do not wish to use :option:`-E` (e.g., to avoid ``sudo`` inheriting +If you do not wish to use ``-E`` (e.g., to avoid ``sudo`` inheriting ``PATH``) you can modify your `/etc/sudoers` config file to specifically pass the environment variables required by topotests. Add the following commands to your ``/etc/sudoers`` config file. @@ -197,7 +197,7 @@ the run. Here we see that 4 tests have failed. We an dig deeper by displaying the captured logs and errors. First let's redisplay the results enumerated by adding -the :option:`-E` flag +the ``-E`` flag .. code:: shell @@ -385,7 +385,7 @@ to launch the given programs. NOTE: you must run the topotest (pytest) such that your DISPLAY, STY or TMUX environment variables are carried over. You can do this by passing the -:option:`-E` flag to ``sudo`` or you can modify your ``/etc/sudoers`` config to +``-E`` flag to ``sudo`` or you can modify your ``/etc/sudoers`` config to automatically pass that environment variable through to the ``sudo`` environment. @@ -903,6 +903,7 @@ Interface), from here you can call your router ``vtysh`` or even bash. Here's the help text: .. code:: shell + unet> help Commands: @@ -912,8 +913,6 @@ Here's the help text: vtysh [hosts] :: open vtysh terminals for hosts [hosts] <vtysh-command> :: execute vtysh-command on hosts -.. code:: shell - Here are some commands example: .. code:: shell diff --git a/doc/developer/workflow.rst b/doc/developer/workflow.rst index 2ce5f5d1c8..e52ec056ad 100644 --- a/doc/developer/workflow.rst +++ b/doc/developer/workflow.rst @@ -98,6 +98,16 @@ March/July/November. Walking backwards from this date: ``dev/MAJOR.MINOR`` at this point) and a ``rc1`` release candidate is tagged. Master is unfrozen and new features may again proceed. + Part of unfreezing master is editing the ``AC_INIT`` statement in + :file:`configure.ac` to reflect the new development version that master + now refers to. This is accompanied by a ``frr-X.Y-dev`` tag on master, + which should always be on the first commit on master *after* the stable + branch was forked (even if that is not the edit to ``AC_INIT``; it's more + important to have it on the very first commit on master after the fork.) + + (The :file:`configure.ac` edit and tag push are considered git housekeeping + and are pushed directly to ``master``, not through a PR.) + - 2 weeks earlier, a ``rc2`` release candidate is tagged. - on release date, the branch is renamed to ``stable/MAJOR.MINOR``. @@ -1151,6 +1161,37 @@ but are no longer actively maintained. MemorySanitizer is not available in GCC. The different Sanitizers are mostly incompatible with each other. Please refer to GCC/LLVM documentation for details. +frr-format plugin + This is a GCC plugin provided with FRR that does extended type checks for + ``%pFX``-style printfrr extensions. To use this plugin, + + 1. install GCC plugin development files, e.g.:: + + apt-get install gcc-10-plugin-dev + + 2. **before** running ``configure``, compile the plugin with:: + + make -C tools/gcc-plugins CXX=g++-10 + + (Edit the GCC version to what you're using, it should work for GCC 9 or + newer.) + + After this, the plugin should be automatically picked up by ``configure``. + The plugin does not change very frequently, so you can keep it around across + work on different FRR branches. After a ``git clean -x``, the ``make`` line + will need to be run again. You can also add ``--with-frr-format`` to the + ``configure`` line to make sure the plugin is used, otherwise if something + is not set up correctly it might be silently ignored. + + .. warning:: + + Do **not** enable this plugin for package/release builds. It is intended + for developer/debug builds only. Since it modifies the compiler, it may + cause silent corruption of the executable files. + + Using the plugin also changes the string for ``PRI[udx]64`` from the + system value to ``%L[udx]`` (normally ``%ll[udx]`` or ``%l[udx]``.) + Additionally, the FRR codebase is regularly scanned with Coverity. Unfortunately Coverity does not have the ability to handle scanning pull requests, but after code is merged it will send an email notifying project @@ -1264,6 +1305,24 @@ may not be obvious in how to fix. Here are some notes on specific warnings: (and varargs calling convention.) This is a notable difference to C++, where the ``void`` is optional and an empty parameter list means no parameters. +* ``"strict match required"`` from the frr-format plugin: check if you are + using a cast in a printf parameter list. The frr-format plugin cannot + access correct full type information for casts like + ``printfrr(..., (uint64_t)something, ...)`` and will print incorrect + warnings particularly if ``uint64_t``, ``size_t`` or ``ptrdiff_t`` are + involved. The problem is *not* triggered with a variable or function return + value of the exact same type (without a cast). + + Since these cases are very rare, community consensus is to just work around + the warning even though the code might be correct. If you are running into + this, your options are: + + 1. try to avoid the cast altogether, maybe using a different printf format + specifier (e.g. ``%lu`` instead of ``%zu`` or ``PRIu64``). + 2. fix the type(s) of the function/variable/struct member being printed + 3. create a temporary variable with the value and print that without a cast + (this is the last resort and was not necessary anywhere so far.) + .. _documentation: |
