diff options
Diffstat (limited to 'doc/developer')
24 files changed, 318 insertions, 147 deletions
diff --git a/doc/developer/bgp-typecodes.rst b/doc/developer/bgp-typecodes.rst index beb7ca1f8a..c7921a772f 100644 --- a/doc/developer/bgp-typecodes.rst +++ b/doc/developer/bgp-typecodes.rst @@ -17,9 +17,6 @@ various BGP RFCs. In the code these are defined as BGP_ATTR_<ATTR>. | 8 | COMMUNITIES | [RFC 1997] | | 9 | ORIGINATOR_ID | [RFC 4456] | | 10 | CLUSTER_LIST | [RFC 4456] | -| 11 | DPA | [draft-ietf-idr-bgp-dpa-05.txt(expired)] | -| 12 | ADVERTISER | [RFC 1863] | -| 13 | RCID_PATH | [RFC 1863] | | 14 | MP_REACH_NLRI | [RFC 4760] | | 15 | MP_UNREACH_NLRI | [RFC 4760] | | 16 | EXT_COMMUNITIES | [RFC 4360] | diff --git a/doc/developer/building-frr-for-archlinux.rst b/doc/developer/building-frr-for-archlinux.rst index af1677e89e..406d22d618 100644 --- a/doc/developer/building-frr-for-archlinux.rst +++ b/doc/developer/building-frr-for-archlinux.rst @@ -11,7 +11,9 @@ Installing Dependencies git autoconf automake libtool make cmake pcre readline texinfo \ pkg-config pam json-c bison flex python-pytest \ c-ares python python2-ipaddress python-sphinx \ - net-snmp perl libcap libelf + net-snmp perl libcap libelf libunwind + +.. include:: building-libunwind-note.rst .. include:: building-libyang.rst diff --git a/doc/developer/building-frr-for-centos7.rst b/doc/developer/building-frr-for-centos7.rst index ce11126f70..c40b5de594 100644 --- a/doc/developer/building-frr-for-centos7.rst +++ b/doc/developer/building-frr-for-centos7.rst @@ -22,7 +22,9 @@ Add packages: readline-devel texinfo net-snmp-devel groff pkgconfig \ json-c-devel pam-devel bison flex pytest c-ares-devel \ python-devel python-sphinx libcap-devel \ - elfutils-libelf-devel + elfutils-libelf-devel libunwind-devel + +.. include:: building-libunwind-note.rst .. include:: building-libyang.rst diff --git a/doc/developer/building-frr-for-centos8.rst b/doc/developer/building-frr-for-centos8.rst index 109a7866d9..659752f6df 100644 --- a/doc/developer/building-frr-for-centos8.rst +++ b/doc/developer/building-frr-for-centos8.rst @@ -15,7 +15,9 @@ Add packages: automake libtool make readline-devel texinfo net-snmp-devel pkgconfig \ groff pkgconfig json-c-devel pam-devel bison flex python2-pytest \ c-ares-devel python2-devel libcap-devel \ - elfutils-libelf-devel + elfutils-libelf-devel libunwind-devel + +.. include:: building-libunwind-note.rst .. include:: building-libyang.rst diff --git a/doc/developer/building-frr-for-debian9.rst b/doc/developer/building-frr-for-debian9.rst index f8d8025f62..b2fdef9990 100644 --- a/doc/developer/building-frr-for-debian9.rst +++ b/doc/developer/building-frr-for-debian9.rst @@ -11,7 +11,9 @@ Add packages: sudo apt-get install git autoconf automake libtool make \ libreadline-dev texinfo libjson-c-dev pkg-config bison flex \ libc-ares-dev python3-dev python3-pytest python3-sphinx build-essential \ - libsnmp-dev libcap-dev libelf-dev + libsnmp-dev libcap-dev libelf-dev libunwind-dev + +.. include:: building-libunwind-note.rst .. include:: building-libyang.rst diff --git a/doc/developer/building-frr-for-fedora.rst b/doc/developer/building-frr-for-fedora.rst index 6ce76ba158..dc869ece10 100644 --- a/doc/developer/building-frr-for-fedora.rst +++ b/doc/developer/building-frr-for-fedora.rst @@ -15,7 +15,9 @@ Installing Dependencies readline-devel texinfo net-snmp-devel groff pkgconfig json-c-devel \ pam-devel python3-pytest bison flex c-ares-devel python3-devel \ python3-sphinx perl-core patch libcap-devel \ - elfutils-libelf-devel + elfutils-libelf-devel libunwind-devel + +.. include:: building-libunwind-note.rst .. include:: building-libyang.rst diff --git a/doc/developer/building-frr-for-freebsd10.rst b/doc/developer/building-frr-for-freebsd10.rst index e85cb80053..5e70b81d43 100644 --- a/doc/developer/building-frr-for-freebsd10.rst +++ b/doc/developer/building-frr-for-freebsd10.rst @@ -17,7 +17,9 @@ is first package install and asked) :: pkg install git autoconf automake libtool gmake json-c pkgconf \ - bison flex py36-pytest c-ares python3.6 py36-sphinx + bison flex py36-pytest c-ares python3.6 py36-sphinx libunwind + +.. include:: building-libunwind-note.rst Make sure there is no /usr/bin/flex preinstalled (and use the newly installed in /usr/local/bin): (FreeBSD frequently provides a older flex diff --git a/doc/developer/building-frr-for-freebsd11.rst b/doc/developer/building-frr-for-freebsd11.rst index b97538b763..808207b831 100644 --- a/doc/developer/building-frr-for-freebsd11.rst +++ b/doc/developer/building-frr-for-freebsd11.rst @@ -17,7 +17,9 @@ is first package install and asked) .. code-block:: shell pkg install git autoconf automake libtool gmake json-c pkgconf \ - bison flex py36-pytest c-ares python3.6 py36-sphinx texinfo + bison flex py36-pytest c-ares python3.6 py36-sphinx texinfo libunwind + +.. include:: building-libunwind-note.rst Make sure there is no /usr/bin/flex preinstalled (and use the newly installed in /usr/local/bin): (FreeBSD frequently provides a older flex diff --git a/doc/developer/building-frr-for-opensuse.rst b/doc/developer/building-frr-for-opensuse.rst index ee6a36a14b..d9800a1638 100644 --- a/doc/developer/building-frr-for-opensuse.rst +++ b/doc/developer/building-frr-for-opensuse.rst @@ -14,7 +14,9 @@ Installing Dependencies readline-devel texinfo net-snmp-devel groff pkgconfig libjson-c-devel\ pam-devel python3-pytest bison flex c-ares-devel python3-devel\ python3-Sphinx perl patch libcap-devel libyang-devel \ - libelf-devel + libelf-devel libunwind-devel + +.. include:: building-libunwind-note.rst Building & Installing FRR ------------------------- diff --git a/doc/developer/building-frr-for-ubuntu1804.rst b/doc/developer/building-frr-for-ubuntu1804.rst index 3e8c6c0d0b..fcfd94ec2c 100644 --- a/doc/developer/building-frr-for-ubuntu1804.rst +++ b/doc/developer/building-frr-for-ubuntu1804.rst @@ -15,7 +15,9 @@ Installing Dependencies pkg-config libpam0g-dev libjson-c-dev bison flex \ libc-ares-dev python3-dev python3-sphinx \ install-info build-essential libsnmp-dev perl libcap-dev \ - libelf-dev + libelf-dev libunwind-dev + +.. include:: building-libunwind-note.rst .. include:: building-libyang.rst diff --git a/doc/developer/building-frr-for-ubuntu2004.rst b/doc/developer/building-frr-for-ubuntu2004.rst index 28e7ca6518..fdfc25da9d 100644 --- a/doc/developer/building-frr-for-ubuntu2004.rst +++ b/doc/developer/building-frr-for-ubuntu2004.rst @@ -15,7 +15,9 @@ Installing Dependencies pkg-config libpam0g-dev libjson-c-dev bison flex \ libc-ares-dev python3-dev python3-sphinx \ install-info build-essential libsnmp-dev perl \ - libcap-dev python2 libelf-dev + libcap-dev python2 libelf-dev libunwind-dev + +.. include:: building-libunwind-note.rst Note that Ubuntu 20 no longer installs python 2.x, so it must be installed explicitly. Ensure that your system has a symlink named diff --git a/doc/developer/building-libunwind-note.rst b/doc/developer/building-libunwind-note.rst new file mode 100644 index 0000000000..0beb1f8d37 --- /dev/null +++ b/doc/developer/building-libunwind-note.rst @@ -0,0 +1,6 @@ +.. note:: + + The ``libunwind`` library is optional but highly recommended, as it improves + backtraces printed for crashes and debugging. However, if it is not + available for some reason, it can simply be left out without any loss of + functionality. diff --git a/doc/developer/conf.py b/doc/developer/conf.py index 8f282c0790..79f8233978 100644 --- a/doc/developer/conf.py +++ b/doc/developer/conf.py @@ -136,8 +136,10 @@ language = None # directories to ignore when looking for source files. exclude_patterns = [ "_build", + "building-libunwind-note.rst", "building-libyang.rst", "topotests-snippets.rst", + "topotests-markers.rst", "include-compile.rst", ] diff --git a/doc/developer/frr-release-procedure.rst b/doc/developer/frr-release-procedure.rst index 08e3057ae6..6a7f9c4ca9 100644 --- a/doc/developer/frr-release-procedure.rst +++ b/doc/developer/frr-release-procedure.rst @@ -6,27 +6,33 @@ FRR Release Procedure ``<version>`` - version to be released, e.g. 7.3 ``origin`` - FRR upstream repository -1. Checkout ``dev/<version>``. +Stage 1 - Preparation +--------------------- + +#. Prepare changelog for the new release + + Note: use ``tools/release_notes.py`` to help draft release notes changelog + +#. Checkout the existing ``dev/<version>`` branch. .. code-block:: console git checkout dev/<version> -2. Create and push a new branch called ``stable/<version>`` based on the +#. Create and push a new branch called ``stable/<version>`` based on the ``dev/<version>`` branch. .. code-block:: console git checkout -b stable/<version> - git push origin stable/<version>:refs/heads/stable/<version> -3. Remove the development branch called ``dev/<version>`` +#. Remove the development branch called ``dev/<version>`` .. code-block:: console git push origin --delete dev/<version> -4. Update Changelog for Red Hat Packages: +#. Update Changelog for Red Hat Packages: Edit :file:`redhat/frr.spec.in` and look for the ``%changelog`` section: @@ -47,7 +53,7 @@ FRR Release Procedure - Add the changelog text below this entry. -5. Update Changelog for Debian Packages: +#. Update Changelog for Debian Packages: Update :file:`debian/changelog`: @@ -80,104 +86,148 @@ FRR Release Procedure . * Your Changes Here -6. Change main version number: +#. Commit the changes, adding the changelog to the commit message. Follow all + existing commit guidelines. The commit message should be akin to:: + + debian, redhat: updating changelog for new release + +#. Change main version number: + + - Edit :file:`configure.ac` and change version in the ``AC_INIT`` command + to ``<version>`` + + Add and commit this change. This commit should be separate from the commit + containing the changelog. The commit message should be:: + + FRR Release <version> + + The version field should be complete; i.e. for ``8.0.0``, the version should + be ``8.0.0`` and not ``8.0`` or ``8``. + + +Stage 2 - Staging +----------------- + +#. Push the stable branch to a new remote branch prefixed with ``rc``:: + + git push origin stable/<version>:rc/version - - Edit :file:`configure.ac` and change version in the ``AC_INIT`` command - to ``<version>`` + This will trigger the NetDEF CI, which serve as a sanity check on the + release branch. Verify that all tests pass and that all package builds are + successful. To do this, go to the NetDEF CI located here: -7. Commit the changes, adding the changelog to the commit message. Follow all - existing commit guidelines. + https://ci1.netdef.org/browse/FRR-FRR -8. Create and submit a GitHub pull request, with the ``HEAD`` set to - ``stable/<version>`` and the base set to the upstream ``master`` branch. - Allow NetDef CI to complete its run and verify that all package builds were - successful. + In the top left, look for ``rc-<version>`` in the "Plan branch" dropdown. + Select this version. Note that it may take a few minutes for the CI to kick + in on this new branch and appear in the list. -9. Create a git tag for the version: +#. Push the stable branch: .. code-block:: console - git tag -a frr-<version> -m "FRRouting Release <version>" + git push origin stable/<version>:refs/heads/stable/<version> -10. Push the commit and new tag. +#. Create and push a git tag for the version: .. code-block:: console - git push origin stable/<version>:refs/head/stable/<version> + git tag -a frr-<version> -m "FRRouting Release <version>" git push origin frr-<version> -11. Kick off the Release build plan on the CI system for the correct release. - Contact Martin Winter for this step. Ensure all release packages build - successfully. +#. Create a new branch based on ``master``, cherry-pick the commit made earlier + that added the changelogs, and use it to create a PR against ``master``. + This way ``master`` has the latest changelog for the next cycle. + +#. Kick off the "Release" build plan on the CI system for the correct release. + Contact Martin Winter for this step. Ensure all release packages build + successfully. + +#. Kick off the Snapcraft build plan for the release. + + +Stage 3 - Publish +----------------- -12. Kick off the Snapcraft build plan for the release. +#. Upload both the Debian and RPM packages to their respective repositories. -13. Acquire the release RPM binary packages from Martin Winter. +#. Coordinate with the maintainer of FRR's RPM repository to publish the RPM + packages on that repository. Update the repository webpage. Verify that the + instructions on the webpage work and that FRR is installable from the + repository on a Red Hat system. -14. On GitHub, go to the <https://github.com/FRRouting/frr/releases>_ and click - "Draft a new release". Write a release announcement. The release - announcement should follow the template in - ``release-announcement-template.md``, located next to this document. Check - for spelling errors, and optionally (but preferably) have other maintainers - proofread the announcement text. + Current maintainer: *Martin Winter* - Attach **only** the binary RPM packages to the GitHub release using - GitHub's attachment functionality. Do not attach Debian packages. Do not - attach source tarballs - these will be generated and attached by GitHub - automatically. Do not publish the release yet. +#. Coordinate with the maintainer of FRR Debian package to publish the Debian + packages on that repository. Update the repository webpage. Verify that the + instructions on the webpage work and that FRR is installable from the + repository on a Debian system. -15. Contact the current Debian maintainer for FRR to get new Debian packages - built and published on our APT repository at https://deb.frrouting.net/. - Ensure the webpage text is updated. Verify that new packages install - successfully on a vanilla Debian installation using the instructions on the - webpage. + Current maintainer: *Jafar Al-Gharaibeh* -16. Deploy Snapcraft release (after CI system finishes the tests for snapcraft - testplan). +#. Log in to the Read The Docs instance. in the "FRRouting" project, navigate + to the "Overview" tab. Ensure there is a ``stable-<version>`` version listed + and that it is enabled. Go to "Admin" and then "Advanced Settings". Change + "Default version" to the new version. This ensures that the documentation + shown to visitors is that of the latest release by default. -17. Update the Read The Docs instance to being publishing documentation built - off the ``stable/<version>`` branch. Contact Quentin Young for this step. + This step must be performed by someone with administrative access to the + Read the Docs instance. -18. Publish the GitHub release. +#. On GitHub, go to the <https://github.com/FRRouting/frr/releases>_ and click + "Draft a new release". Write a release announcement. The release + announcement should follow the template in + ``release-announcement-template.md``, located next to this document. Check + for spelling errors, and optionally (but preferably) have other maintainers + proofread the announcement text. -19. Clone the ``frr-www`` repository: + Do not attach any packages or source tarballs to the GitHub release. - .. code-block:: console + Publish the release once it is reviewed. - git clone https://github.com/FRRouting/frr-www.git +#. Deploy Snapcraft release. Remember that this will automatically upgrade Snap + users. -20. Add a new release announcement, using a previous announcement as template: + Current maintainer: *Martin Winter* - .. code-block:: console +#. Build and publish the Docker containers. - cp <old-version>-launch.md <version>-launch.md + Current maintainer: *Quentin Young* - Paste the GitHub release announcement text into this document, and **remove - line breaks**. In other words, this:: +#. Clone the ``frr-www`` repository: + + .. code-block:: console + + git clone https://github.com/FRRouting/frr-www.git + +#. Add a new release announcement, using a previous announcement as template: + + .. code-block:: console - This is one continuous - sentence that should be - rendered on one line + cp <old-version>.md <version>.md - Needs to be changed to this:: + Paste the GitHub release announcement text into this document, and **remove + line breaks**. In other words, this:: - This is one continuous sentence that should be rendered on one line + This is one continuous + sentence that should be + rendered on one line - This is very important otherwise the announcement will be unreadable on the - website. + Needs to be changed to this:: - Make sure to add a link to the GitHub releases page at the top. + This is one continuous sentence that should be rendered on one line - 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. + This is very important otherwise the announcement will be unreadable on the + website. -21. Deploy the updated ``frr-www`` on the frrouting.org web server and verify - that the announcement text is visible. + Make sure to add a link to the GitHub releases page at the top. -22. Send an email to ``announce@lists.frrouting.org``. The text of this email - should include the text from the GitHub release. + 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. -23. Update masters version of the changelog-auto.in +#. Deploy the updated ``frr-www`` on the frrouting.org web server and verify + that the announcement text is visible. - Take the change data and cut-n-paste the changes into the master version below - the @VERSION@-0 lines. So we have the history of the previous release. +#. Send an email to ``announce@lists.frrouting.org``. The text of this email + should include text as appropriate from the GitHub release and a link to the + GitHub release, Debian repository, and RPM repository. 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/process-architecture.rst b/doc/developer/process-architecture.rst index 6a028d0000..37bd620f24 100644 --- a/doc/developer/process-architecture.rst +++ b/doc/developer/process-architecture.rst @@ -3,34 +3,38 @@ Process Architecture ==================== -FRR inherited its overall design architecture from Quagga. The chosen model for -Quagga is that of a suite of independent daemons that do IPC via Unix domain -sockets. Within each daemon, the architecture follows the event-driven model. -FRR has inherited this model as well. As FRR is deployed at larger scales and -gains ever more features, each adding to the overall processing workload, we -are approaching the saturation point for a single thread per daemon. In light -of this, there are ongoing efforts to introduce multithreading to various -components of FRR. This document aims to describe the current design choices -and overall model for integrating the event-driven and multithreaded -architectures into a cohesive whole. +FRR is a suite of daemons that serve different functions. This document +describes internal architecture of daemons, focusing their general design +patterns, and especially how threads are used in the daemons that use them. + +Overview +-------- +The fundamental pattern used in FRR daemons is an `event loop +<https://en.wikipedia.org/wiki/Event_loop>`_. Some daemons use `kernel threads +<https://en.wikipedia.org/wiki/Thread_(computing)#Kernel_threads>`_. In these +daemons, each kernel thread runs its own event loop. The event loop +implementation is constructed to be thread safe and to allow threads other than +its owning thread to schedule events on it. The rest of this document describes +these two designs in detail. Terminology ----------- -Because this document describes the architecture for true kernel threads as -well as the event system, a digression on terminology is in order here. +Because this document describes the architecture for kernel threads as well as +the event system, a digression on terminology is in order here. -Historically Quagga's event system was viewed as an implementation of userspace +Historically Quagga's loop system was viewed as an implementation of userspace threading. Because of this design choice, the names for various datastructures within the event system are variations on the term "thread". The primary -context datastructure in this system is called a "threadmaster". What would -today be called an 'event' or 'task' in systems such as libevent are called -"threads" and the datastructure for them is ``struct thread``. To add to the -confusion, these "threads" have various types, one of which is "event". To -hopefully avoid some of this confusion, this document refers to these "threads" -as a 'task' except where the datastructures are explicitly named. When they are -explicitly named, they will be formatted ``like this`` to differentiate from -the conceptual names. When speaking of kernel threads, the term used will be -"pthread" since FRR's kernel threading implementation is POSIX threads. +datastructure that holds the state of an event loop in this system is called a +"threadmaster". Events scheduled on the event loop - what would today be called +an 'event' or 'task' in systems such as libevent - are called "threads" and the +datastructure for them is ``struct thread``. To add to the confusion, these +"threads" have various types, one of which is "event". To hopefully avoid some +of this confusion, this document refers to these "threads" as a 'task' except +where the datastructures are explicitly named. When they are explicitly named, +they will be formatted ``like this`` to differentiate from the conceptual +names. When speaking of kernel threads, the term used will be "pthread" since +FRR's kernel threading implementation uses the POSIX threads API. .. This should be broken into its document under :ref:`libfrr` .. _event-architecture: 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/subdir.am b/doc/developer/subdir.am index d16420c7e7..c8654d6725 100644 --- a/doc/developer/subdir.am +++ b/doc/developer/subdir.am @@ -23,6 +23,7 @@ dev_RSTFILES = \ doc/developer/building-frr-for-ubuntu1604.rst \ doc/developer/building-frr-for-ubuntu1804.rst \ doc/developer/building-frr-for-ubuntu2004.rst \ + doc/developer/building-libunwind-note.rst \ doc/developer/building-libyang.rst \ doc/developer/building.rst \ doc/developer/cli.rst \ diff --git a/doc/developer/topotests.rst b/doc/developer/topotests.rst index b4f6ec521c..fa1fd20067 100644 --- a/doc/developer/topotests.rst +++ b/doc/developer/topotests.rst @@ -8,19 +8,21 @@ Topotests is a suite of topology tests for FRR built on top of micronet. Installation and Setup ---------------------- -Topotests run under python3. Additionally, for ExaBGP (which is used in some of -the BGP tests) an older python2 version must be installed. +Topotests run under python3. Additionally, for ExaBGP (which is used +in some of the BGP tests) an older python2 version (and the python2 +version of ``pip``) must be installed. -Tested with Ubuntu 20.04 and Ubuntu 18.04 and Debian 11. +Tested with Ubuntu 20.04,Ubuntu 18.04, and Debian 11. -Instructions are the same for all setups (i.e. ExaBGP is only used for BGP -tests). +Instructions are the same for all setups (i.e. ExaBGP is only used for +BGP tests). Installing Topotest Requirements ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ .. code:: shell + apt-get install gdb apt-get install iproute2 apt-get install net-tools apt-get install python3-pip @@ -41,7 +43,6 @@ Optional, will give better output. .. code:: shell - apt-get install gdb disable apport (which move core files) Set ``enabled=0`` in ``/etc/default/apport``. @@ -137,14 +138,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 +198,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 +386,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 +904,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 +914,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: |
