summaryrefslogtreecommitdiffstats
path: root/doc/developer/workflow.rst
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-09 13:16:35 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-09 13:16:35 +0000
commite2bbf175a2184bd76f6c54ccf8456babeb1a46fc (patch)
treef0b76550d6e6f500ada964a3a4ee933a45e5a6f1 /doc/developer/workflow.rst
parentInitial commit. (diff)
downloadfrr-e2bbf175a2184bd76f6c54ccf8456babeb1a46fc.tar.xz
frr-e2bbf175a2184bd76f6c54ccf8456babeb1a46fc.zip
Adding upstream version 9.1.upstream/9.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'doc/developer/workflow.rst')
-rw-r--r--doc/developer/workflow.rst1740
1 files changed, 1740 insertions, 0 deletions
diff --git a/doc/developer/workflow.rst b/doc/developer/workflow.rst
new file mode 100644
index 0000000..68834ed
--- /dev/null
+++ b/doc/developer/workflow.rst
@@ -0,0 +1,1740 @@
+.. _process-and-workflow:
+
+*******************
+Process & Workflow
+*******************
+
+.. highlight:: none
+
+FRR is a large project developed by many different groups. This section
+documents standards for code style & quality, commit messages, pull requests
+and best practices that all contributors are asked to follow.
+
+This chapter is "descriptive/post-factual" in that it documents pratices that
+are in use; it is not "definitive/pre-factual" in prescribing practices. This
+means that when a procedure changes, it is agreed upon, then put into practice,
+and then documented here. If this document doesn't match reality, it's the
+document that needs to be updated, not reality.
+
+Mailing Lists
+=============
+
+The FRR development group maintains multiple mailing lists for use by the
+community. Italicized lists are private.
+
++----------------------------------+--------------------------------+
+| Topic | List |
++==================================+================================+
+| Development | dev@lists.frrouting.org |
++----------------------------------+--------------------------------+
+| Users & Operators | frog@lists.frrouting.org |
++----------------------------------+--------------------------------+
+| Announcements | announce@lists.frrouting.org |
++----------------------------------+--------------------------------+
+| *Security* | security@lists.frrouting.org |
++----------------------------------+--------------------------------+
+| *Technical Steering Committee* | tsc@lists.frrouting.org |
++----------------------------------+--------------------------------+
+
+The Development list is used to discuss and document general issues related to
+project development and governance. The public
+`Slack instance <https://frrouting.slack.com>`_ and weekly technical meetings
+provide a higher bandwidth channel for discussions. The results of such
+discussions must be reflected in updates, as appropriate, to code (i.e.,
+merges), `GitHub issues`_, and for governance or process changes, updates to
+the Development list and either this file or information posted at
+https://frrouting.org/.
+
+Development & Release Cycle
+===========================
+
+Development
+-----------
+
+.. figure:: ../figures/git_branches.png
+ :align: center
+ :scale: 55%
+ :alt: Merging Git branches into a central trunk
+
+ Rough outline of FRR development workflow
+
+The master Git for FRR resides on `GitHub`_.
+
+There is one main branch for development, ``master``. For each major release
+(2.0, 3.0 etc) a new release branch is created based on the master. Significant
+bugfixes should be backported to upcoming and existing release branches no more
+than 1 year old. As a general rule new features are not backported to release
+branches.
+
+Subsequent point releases based on a major branch are handled with git tags.
+
+Releases
+--------
+FRR employs a ``<MAJOR>.<MINOR>.<BUGFIX>`` versioning scheme.
+
+``MAJOR``
+ Significant new features or multiple minor features. This should mostly
+ cover any kind of disruptive change that is visible or "risky" to operators.
+ New features or protocols do not necessarily trigger this. (This was changed
+ for FRR 7.x after feedback from users that the pace of major version number
+ increments was too high.)
+
+``MINOR``
+ General incremental development releases, excluding "major" changes
+ mentioned above. Not necessarily fully backwards compatible, as smaller
+ (but still visible) changes or deprecated feature removals may still happen.
+ However, there shouldn't be any huge "surprises" between minor releases.
+
+``BUGFIX``
+ Fixes for actual bugs and/or security issues. Fully compatible.
+
+Releases are scheduled in a 4-month cycle on the first Tuesday each
+March/July/November. Walking backwards from this date:
+
+ - 6 weeks earlier, ``master`` is frozen for new features, and feature PRs
+ are considered lowest priority (regardless of when they were opened.)
+
+ - 4 weeks earlier, the stable branch separates from master (named
+ ``dev/MAJOR.MINOR`` at this point) and tagged as ``base_X.Y``.
+ 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.)
+
+ Below is the snippet of the commands to use in this step.
+
+ .. code-block:: console
+
+ % git remote --verbose
+ upstream git@github.com:frrouting/frr (fetch)
+ upstream git@github.com:frrouting/frr (push)
+
+ % git checkout master
+ % git pull upstream master
+ % git checkout -b dev/8.2
+ % git tag base_8.2
+ % git push upstream base_8.2
+ % git push upstream dev/8.2
+ % git checkout master
+ % sed -i 's/8.2-dev/8.3-dev/' configure.ac
+ % git add configure.ac
+ % git commit -s -m "build: FRR 8.3 development version"
+ % git tag -a frr-8.3-dev -m "frr-8.3-dev"
+ % git push upstream master
+ % git push upstream frr-8.3-dev
+
+ In this step, we also have to update package versions to reflect
+ the development version. Versions need to be updated using
+ a standard way of development (Pull Requests) based on master branch.
+
+ Only change the version number with no other changes. This will produce
+ packages with the a version number that is higher than any previous
+ version. Once the release is done, whatever updates we make to changelog
+ files on the release branch need to be cherry-picked to the master branch.
+
+ Update essential dates in advance for reference table (below) when
+ the next freeze, dev/X.Y, RC, and release phases are scheduled. This should
+ go in the ``master`` branch.
+
+ - 2 weeks earlier, a ``frr-X.Y-rc`` release candidate is tagged.
+
+ .. code-block:: console
+
+ % git remote --verbose
+ upstream git@github.com:frrouting/frr (fetch)
+ upstream git@github.com:frrouting/frr (push)
+
+ % git checkout dev/8.2
+ % git tag frr-8.2-rc
+ % git push upstream frr-8.2-rc
+
+ - on release date, the branch is renamed to ``stable/MAJOR.MINOR``.
+
+The 2 week window between each of these events should be used to run any and
+all testing possible for the release in progress. However, the current
+intention is to stick to the schedule even if known issues remain. This would
+hopefully occur only after all avenues of fixing issues are exhausted, but to
+achieve this, an as exhaustive as possible list of issues needs to be available
+as early as possible, i.e. the first 2-week window.
+
+For reference, the expected release schedule according to the above is:
+
++---------+------------+------------+------------+
+| Release | 2023-11-07 | 2024-03-05 | 2024-07-02 |
++---------+------------+------------+------------+
+| RC | 2023-10-24 | 2024-02-20 | 2024-06-18 |
++---------+------------+------------+------------+
+| dev/X.Y | 2023-10-10 | 2024-02-06 | 2024-06-04 |
++---------+------------+------------+------------+
+| freeze | 2023-09-26 | 2024-01-23 | 2024-05-21 |
++---------+------------+------------+------------+
+
+Here is the hint on how to get the dates easily:
+
+ .. code-block:: console
+
+ ~$ # Release date is 2023-11-07 (First Tuesday each March/July/November)
+ ~$ date +%F --date='2023-11-07 -42 days' # Next freeze date
+ 2023-09-26
+ ~$ date +%F --date='2023-11-07 -28 days' # Next dev/X.Y date
+ 2023-10-10
+ ~$ date +%F --date='2023-11-07 -14 days' # Next RC date
+ 2023-10-24
+
+Each release is managed by one or more volunteer release managers from the FRR
+community. These release managers are expected to handle the branch for a period
+of one year. To spread and distribute this workload, this should be rotated for
+subsequent releases. The release managers are currently assumed/expected to
+run a release management meeting during the weeks listed above. Barring other
+constraints, this would be scheduled before the regular weekly FRR community
+call such that important items can be carried over into that call.
+
+Bugfixes are applied to the two most recent releases. It is expected that
+each bugfix backported should include some reasoning for its inclusion
+as well as receiving approval by the release managers for that release before
+accepted into the release branch. This does not necessarily preclude backporting of
+bug fixes to older than the two most recent releases.
+
+Security fixes are backported to all releases less than or equal to at least one
+year old. Security fixes may also be backported to older releases depending on
+severity.
+
+For detailed instructions on how to produce an FRR release, refer to
+:ref:`frr-release-procedure`.
+
+
+Long term support branches ( LTS )
+-----------------------------------------
+
+This kind of branch is not yet officially supported, and need experimentation
+before being effective.
+
+Previous definition of releases prevents long term support of previous releases.
+For instance, bug and security fixes are not applied if the stable branch is too
+old.
+
+Because the FRR users have a need to backport bug and security fixes after the
+stable branch becomes too old, there is a need to provide support on a long term
+basis on that stable branch. If that support is applied on that stable branch,
+then that branch is a long term support branch.
+
+Having a LTS branch requires extra-work and requires one person to be in charge
+of that maintenance branch for a certain amount of time. The amount of time will
+be by default set to 4 months, and can be increased. 4 months stands for the time
+between two releases, this time can be applied to the decision to continue with a
+LTS release or not. In all cases, that time period will be well-defined and
+published. Also, a self nomination from a person that proposes to handle the LTS
+branch is required. The work can be shared by multiple people. In all cases, there
+must be at least one person that is in charge of the maintenance branch. The person
+on people responsible for a maintenance branch must be a FRR maintainer. Note that
+they may choose to abandon support for the maintenance branch at any time. If
+no one takes over the responsibility of the LTS branch, then the support will be
+discontinued.
+
+The LTS branch duties are the following ones:
+
+- organise meetings on a (bi-)weekly or monthly basis, the handling of issues
+ and pull requested relative to that branch. When time permits, this may be done
+ during the regularly scheduled FRR meeting.
+
+- ensure the stability of the branch, by using and eventually adapting the
+ checking the CI tools of FRR ( indeed, maintaining may lead to create
+ maintenance branches for topotests or for CI).
+
+It will not be possible to backport feature requests to LTS branches. Actually, it
+is a false good idea to use LTS for that need. Introducing feature requests may
+break the paradigm where all more recent releases should also include the feature
+request. This would require the LTS maintainer to ensure that all more recent
+releases have support for this feature request. Moreover, introducing features
+requests may result in breaking the stability of the branch. LTS branches are first
+done to bring long term support for stability.
+
+Development Branches
+--------------------
+
+Occassionally the community will desire the ability to work together
+on a feature that is considered useful to FRR. In this case the
+parties may ask the Maintainers for the creation of a development
+branch in the main FRR repository. Requirements for this to happen
+are:
+
+- A one paragraph description of the feature being implemented to
+ allow for the facilitation of discussion about the feature. This
+ might include pointers to relevant RFC's or presentations that
+ explain what is planned. This is intended to set a somewhat
+ low bar for organization.
+- A branch maintainer must be named. This person is responsible for
+ keeping the branch up to date, and general communication about the
+ project with the other FRR Maintainers. Additionally this person
+ must already be a FRR Maintainer.
+- Commits to this branch must follow the normal PR and commit process
+ as outlined in other areas of this document. The goal of this is
+ to prevent the current state where large features are submitted
+ and are so large they are difficult to review.
+
+After a development branch has completed the work together, a final
+review can be made and the branch merged into master. If a development
+branch is becomes un-maintained or not being actively worked on after
+three months then the Maintainers can decide to remove the branch.
+
+Debian Branches
+---------------
+
+The Debian project contains "official" packages for FRR. While FRR
+Maintainers may participate in creating these, it is entirely the Debian
+project's decision what to ship and how to work on this.
+
+As a courtesy and for FRR's benefit, this packaging work is currently visible
+in git branches named ``debian/*`` on the main FRR git repository. These
+branches are for the exclusive use by people involved in Debian packaging work
+for FRR. Direct commit access may be handed out and FRR git rules (review,
+testing, etc.) do not apply. Do not push to these branches without talking
+to the people noted under ``Maintainer:`` and ``Uploaders:`` in
+``debian/control`` on the target branch -- even if you are a FRR Maintainer.
+
+Changelog
+---------
+The changelog will be the base for the release notes. A changelog entry for
+your changes is usually not required and will be added based on your commit
+messages by the maintainers. However, you are free to include an update to the
+changelog with some better description.
+
+Accords: non-code community consensus
+=====================================
+
+The FRR repository has a place for "accords" - these are items of
+consideration for FRR that influence how we work as a community, but either
+haven't resulted in code *yet*, or may *never* result in code being written.
+They are placed in the ``doc/accords/`` directory.
+
+The general idea is to simply pass small blurbs of text through our normal PR
+procedures, giving them the same visibility, comment and review mechanisms as
+code PRs - and changing them later is another PR. Please refer to the README
+file in ``doc/accords/`` for further details. The file names of items in that
+directory are hopefully helpful in determining whether some of them might be
+relevant to your work.
+
+Submitting Patches and Enhancements
+===================================
+
+FRR accepts patches using GitHub pull requests.
+
+The base branch for new contributions and non-critical bug fixes should be
+``master``. Please ensure your pull request is based on this branch when you
+submit it.
+
+Code submitted by pull request will be automatically tested by one or more CI
+systems. Once the automated tests succeed, other developers will review your
+code for quality and correctness. After any concerns are resolved, your code
+will be merged into the branch it was submitted against.
+
+The title of the pull request should provide a high level technical
+summary of the included patches. The description should provide
+additional details that will help the reviewer to understand the context
+of the included patches.
+
+Squash commits
+--------------
+
+Before merging make sure a PR has squashed the following kinds of commits:
+
+- Fixes/review feedback
+- Typos
+- Merges and rebases
+- Work in progress
+
+This helps to automatically generate human-readable changelog messages.
+
+Commit Guidelines
+-----------------
+
+There is a built-in commit linter. Basic rules:
+
+- Commit messages must be prefixed with the name of the changed subsystem, followed
+ by a colon and a space and start with an imperative verb.
+
+ `Check <https://github.com/FRRouting/frr/tree/master/.github/commitlint.config.js>`_ all
+ the supported subsystems.
+
+- Commit messages must not end with a period ``.``
+
+Why was my pull request closed?
+-------------------------------
+
+Pull requests older than 180 days will be closed. Exceptions can be made for
+pull requests that have active review comments, or that are awaiting other
+dependent pull requests. Closed pull requests are easy to recreate, and little
+work is lost by closing a pull request that subsequently needs to be reopened.
+
+We want to limit the total number of pull requests in flight to:
+
+- Maintain a clean project
+- Remove old pull requests that would be difficult to rebase as the underlying code has changed over time
+- Encourage code velocity
+
+.. _license-for-contributions:
+
+License for Contributions
+-------------------------
+FRR is under a “GPLv2 or later” license. Any code submitted must be released
+under the same license (preferred) or any license which allows redistribution
+under this GPLv2 license (eg MIT License).
+It is forbidden to push any code that prevents from using GPLv3 license. This
+becomes a community rule, as FRR produces binaries that links with Apache 2.0
+libraries. Apache 2.0 and GPLv2 license are incompatible, if put together.
+Please see `<http://www.apache.org/licenses/GPL-compatibility.html>`_ for
+more information. This rule guarantees the user to distribute FRR binary code
+without any licensing issues.
+
+Pre-submission Checklist
+------------------------
+- Format code (see `Code Formatting <#code-formatting>`__)
+- Verify and acknowledge license (see :ref:`license-for-contributions`)
+- Ensure you have properly signed off (see :ref:`signing-off`)
+- Test building with various configurations:
+
+ - ``buildtest.sh``
+
+- Verify building source distribution:
+
+ - ``make dist`` (and try rebuilding from the resulting tar file)
+
+- Run unit tests:
+
+ - ``make test``
+
+- In the case of a major new feature or other significant change, document
+ plans for continued maintenance of the feature. In addition it is a
+ requirement that automated testing must be written that exercises
+ 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
+-----------
+Code submitted to FRR must be signed off. We have the same requirements for
+using the signed-off-by process as the Linux kernel. In short, you must include
+a ``Signed-off-by`` tag in every patch.
+
+An easy way to do this is to use ``git commit -s`` where ``-s`` will automatically
+append a signed-off line to the end of your commit message. Also, if you commit
+and forgot to add the line you can use ``git commit --amend -s`` to add the
+signed-off line to the last commit.
+
+``Signed-off-by`` is a developer's certification that they have the right to
+submit the patch for inclusion into the project. It is an agreement to the
+:ref:`Developer's Certificate of Origin <developers-certificate-of-origin>`.
+Code without a proper ``Signed-off-by`` line cannot and will not be merged.
+
+If you are unfamiliar with this process, you should read the
+`official policy at kernel.org <https://www.kernel.org/doc/html/latest/process/submitting-patches.html>`_.
+You might also find
+`this article <http://www.linuxfoundation.org/content/how-participate-linux-community-0>`_
+about participating in the Linux community on the Linux Foundation website to
+be a helpful resource.
+
+.. _developers-certificate-of-origin:
+
+In short, when you sign off on a commit, you assert your agreement to all of
+the following::
+
+ Developer's Certificate of Origin 1.1
+
+ By making a contribution to this project, I certify that:
+
+ (a) The contribution was created in whole or in part by me and I
+ have the right to submit it under the open source license
+ indicated in the file; or
+
+ (b) The contribution is based upon previous work that, to the best
+ of my knowledge, is covered under an appropriate open source
+ license and I have the right under that license to submit that
+ work with modifications, whether created in whole or in part by
+ me, under the same open source license (unless I am permitted to
+ submit under a different license), as indicated in the file; or
+
+ (c) The contribution was provided directly to me by some other
+ person who certified (a), (b) or (c) and I have not modified it.
+
+ (d) I understand and agree that this project and the contribution
+ are public and that a record of the contribution (including all
+ personal information I submit with it, including my sign-off) is
+ maintained indefinitely and may be redistributed consistent with
+ this project or the open source license(s) involved.
+
+After Submitting Your Changes
+-----------------------------
+
+- Watch for Continuous Integration (CI) test results
+
+ - You should automatically receive an email with the test results
+ within less than 2 hrs of the submission. If you don’t get the
+ email, then check status on the GitHub pull request.
+ - Please notify the development mailing list if you think something
+ doesn't work.
+
+- If the tests failed:
+
+ - In general, expect the community to ignore the submission until
+ the tests pass.
+ - It is up to you to fix and resubmit.
+
+ - This includes fixing existing unit (“make test”) tests if your
+ changes broke or changed them.
+ - It also includes fixing distribution packages for the failing
+ platforms (ie if new libraries are required).
+ - Feel free to ask for help on the development list.
+
+ - Go back to the submission process and repeat until the tests pass.
+
+- If the tests pass:
+
+ - Wait for reviewers. Someone will review your code or be assigned
+ to review your code.
+ - Respond to any comments or concerns the reviewer has. Use e-mail or
+ add a comment via github to respond or to let the reviewer know how
+ their comment or concern is addressed.
+ - An author must never delete or manually dismiss someone else's comments
+ or review. (A review may be overridden by agreement in the weekly
+ technical meeting.)
+ - When you have addressed someone's review comments, please click the
+ "re-request review" button (in the top-right corner of the PR page, next
+ to the reviewer's name, an icon that looks like "reload")
+ - The responsibility for keeping a PR moving rests with the author at
+ least as long as there are either negative CI results or negative review
+ comments. If you forget to mark a review comment as addressed (by
+ clicking re-request review), the reviewer may very well not notice and
+ won't come back to your PR.
+ - Automatically generated comments, e.g., those generated by CI systems,
+ may be deleted by authors and others when such comments are not the most
+ recent results from that automated comment source.
+ - After all comments and concerns are addressed, expect your patch
+ to be merged.
+
+- Watch out for questions on the mailing list. At this time there will
+ be a manual code review and further (longer) tests by various
+ community members.
+- Your submission is done once it is merged to the master branch.
+
+Programming Languages, Tools and Libraries
+==========================================
+
+The core of FRR is written in C (gcc or clang supported) and makes
+use of GNU compiler extensions. Additionally, the CLI generation
+tool, `clippy`, requires Python. A few other non-essential scripts are
+implemented in Perl and Python. FRR requires the following tools
+to build distribution packages: automake, autoconf, texinfo, libtool and
+gawk and various libraries (i.e. libpam and libjson-c).
+
+If your contribution requires a new library or other tool, then please
+highlight this in your description of the change. Also make sure it’s
+supported by all FRR platform OSes or provide a way to build
+without the library (potentially without the new feature) on the other
+platforms.
+
+Documentation should be written in reStructuredText. Sphinx extensions may be
+utilized but pure ReST is preferred where possible. See
+:ref:`documentation`.
+
+Use of C++
+----------
+
+While C++ is not accepted for core components of FRR, extensions, modules or
+other distinct components may want to use C++ and include FRR header files.
+There is no requirement on contributors to work to retain C++ compatibility,
+but fixes for C++ compatibility are welcome.
+
+This implies that the burden of work to keep C++ compatibility is placed with
+the people who need it, and they may provide it at their leisure to the extent
+it is useful to them. So, if only a subset of header files, or even parts of
+a header file are made available to C++, this is perfectly fine.
+
+Code Reviews
+============
+
+Code quality is paramount for any large program. Consequently we require
+reviews of all submitted patches by at least one person other than the
+submitter before the patch is merged.
+
+Because of the nature of the software, FRR's maintainer list (i.e. those with
+commit permissions) tends to contain employees / members of various
+organizations. In order to prevent conflicts of interest, we use an honor
+system in which submissions from an individual representing one company should
+be merged by someone unaffiliated with that company.
+
+Guidelines for code review
+--------------------------
+
+- As a rule of thumb, the depth of the review should be proportional to the
+ scope and / or impact of the patch.
+
+- Anyone may review a patch.
+
+- When using GitHub reviews, marking "Approve" on a code review indicates
+ willingness to merge the PR.
+
+- For individuals with merge rights, marking "Changes requested" is equivalent
+ to a NAK.
+
+- For a PR you marked with "Changes requested", please respond to updates in a
+ timely manner to avoid impeding the flow of development.
+
+- Rejected or obsolete PRs are generally closed by the submitter based
+ on requests and/or agreement captured in a PR comment. The comment
+ may originate with a reviewer or document agreement reached on Slack,
+ the Development mailing list, or the weekly technical meeting.
+
+- Reviewers may ask for new automated testing if they feel that the
+ code change is large enough/significant enough to warrant such
+ a requirement.
+
+For project members with merge permissions, the following patterns have
+emerged:
+
+- a PR with any reviews requesting changes may not be merged.
+
+- a PR with any negative CI result may not be merged.
+
+- an open "yellow" review mark ("review requested, but not done") should be
+ given some time (a few days up to weeks, depending on the size of the PR),
+ but is not a merge blocker.
+
+- a "textbubble" review mark ("review comments, but not positive/negative")
+ should be read through but is not a merge blocker.
+
+- non-trivial PRs are generally given some time (again depending on the size)
+ for people to mark an interest in reviewing. Trivial PRs may be merged
+ immediately when CI is green.
+
+
+Coding Practices & Style
+========================
+
+Commit messages
+---------------
+
+Commit messages should be formatted in the same way as Linux kernel
+commit messages. The format is roughly::
+
+ dir: short summary
+
+ extended summary
+
+``dir`` should be the top level source directory under which the change was
+made. For example, a change in :file:`bgpd/rfapi` would be formatted as::
+
+ bgpd: short summary
+
+ ...
+
+The first line should be no longer than 50 characters. Subsequent lines should
+be wrapped to 72 characters.
+
+The purpose of commit messages is to briefly summarize what the commit is
+changing. Therefore, the extended summary portion should be in the form of an
+English paragraph. Brief examples of program output are acceptable but if
+present should be short (on the order of 10 lines) and clearly demonstrate what
+has changed. The goal should be that someone with only passing familiarity with
+the code in question can understand what is being changed.
+
+Commit messages consisting entirely of program output are *unacceptable*. These
+do not describe the behavior changed. For example, putting VTYSH output or the
+result of test runs as the sole content of commit messages is unacceptable.
+
+You must also sign off on your commit.
+
+.. seealso:: :ref:`signing-off`
+
+
+Source File Header
+------------------
+
+New files must have a copyright header (see :ref:`license-for-contributions`
+above) added to the file. The header should be:
+
+.. code-block:: c
+
+ // SPDX-License-Identifier: GPL-2.0-or-later
+ /*
+ * Title/Function of file
+ * Copyright (C) YEAR Author’s Name
+ */
+
+ #include <zebra.h>
+
+A ``SPDX-License-Identifier`` header is required in all source files, i.e.
+``.c``, ``.h``, ``.cpp`` and ``.py`` files. The license boilerplate should be
+removed in these files. Some existing files are missing this header, this is
+slowly being fixed.
+
+A ``SPDX-License-Identifier`` header *and* the full license boilerplate is
+required in schema definition files, i.e. ``.yang`` and ``.proto``. The
+rationale for this is that these files are likely to be individually copied to
+places outside FRR, and having only the SPDX header would become a "dangling
+pointer".
+
+.. warning::
+
+ **DO NOT REMOVE A "Copyright" LINE OR AUTHOR NAME, EVER.**
+
+ **DO NOT APPLY AN SPDX HEADER WHEN THE LICENSE IS UNCLEAR, UNLESS YOU HAVE
+ CHECKED WITH *ALL* SIGNIFICANT AUTHORS.**
+
+Please to keep ``#include <zebra.h>``. The absolute first header included in
+any C file **must** be either ``zebra.h`` or ``config.h`` (with HAVE_CONFIG_H
+guard.)
+
+
+Adding Copyright Claims to Existing Files
+-----------------------------------------
+
+When adding copyright claims for modifications to an existing file, please
+add a ``Portions:`` section as shown below. If this section already exists, add
+your new claim at the end of the list.
+
+.. code-block:: c
+
+ /*
+ * Title/Function of file
+ * Copyright (C) YEAR Author’s Name
+ * Portions:
+ * Copyright (C) 2010 Entity A ....
+ * Copyright (C) 2016 Your name [optional brief change description]
+ * ...
+ */
+
+Defensive coding requirements
+-----------------------------
+
+In general, code submitted into FRR will be rejected if it uses unsafe
+programming practices. While there is no enforced overall ruleset, the
+following requirements have achieved consensus:
+
+- ``strcpy``, ``strcat`` and ``sprintf`` are unacceptable without exception.
+ Use ``strlcpy``, ``strlcat`` and ``snprintf`` instead. (Rationale: even if
+ you know the operation cannot overflow the buffer, a future code change may
+ inadvertedly introduce an overflow.)
+
+- buffer size arguments, particularly to ``strlcpy`` and ``snprintf``, must
+ use ``sizeof()`` whereever possible. Particularly, do not use a size
+ constant in these cases. (Rationale: changing a buffer to another size
+ constant may leave the write operations on a now-incorrect size limit.)
+
+- For stack allocated structs and arrays that should be zero initialized,
+ prefer initializer expressions over ``memset()`` wherever possible. This
+ helps prevent ``memset()`` calls being missed in branches, and eliminates the
+ error class of an incorrect ``size`` argument to ``memset()``.
+
+ For example, instead of:
+
+ .. code-block:: c
+
+ struct foo mystruct;
+ ...
+ memset(&mystruct, 0x00, sizeof(struct foo));
+
+ Prefer:
+
+ .. code-block:: c
+
+ struct foo mystruct = {};
+
+- Do not zero initialize stack allocated values that must be initialized with a
+ nonzero value in order to be used. This way the compiler and memory checking
+ tools can catch uninitialized value use that would otherwise be suppressed by
+ the (incorrect) zero initialization.
+
+- Usage of ``system()`` or other c library routines that cause signals to
+ possibly be ignored are not allowed. This includes the ``fork()`` and
+ ``execXX`` call patterns, which is actually what system() does underneath
+ the covers. This pattern causes the system shutdown to never work properly
+ as the SIGINT sent is never received. It is better to just prohibit code
+ that does this instead of having to debug shutdown issues again.
+
+Other than these specific rules, coding practices from the Linux kernel as
+well as CERT or MISRA C guidelines may provide useful input on safe C code.
+However, these rules are not applied as-is; some of them expressly collide
+with established practice.
+
+
+Container implementations
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In particular to gain defensive coding benefits from better compiler type
+checks, there is a set of replacement container data structures to be found
+in :file:`lib/typesafe.h`. They're documented under :ref:`lists`.
+
+Unfortunately, the FRR codebase is quite large, and migrating existing code to
+use these new structures is a tedious and far-reaching process (even if it
+can be automated with coccinelle, the patches would touch whole swaths of code
+and create tons of merge conflicts for ongoing work.) Therefore, little
+existing code has been migrated.
+
+However, both **new code and refactors of existing code should use the new
+containers**. If there are any reasons this can't be done, please work to
+remove these reasons (e.g. by adding necessary features to the new containers)
+rather than falling back to the old code.
+
+In order of likelyhood of removal, these are the old containers:
+
+- :file:`nhrpd/list.*`, ``hlist_*`` ⇒ ``DECLARE_LIST``
+- :file:`nhrpd/list.*`, ``list_*`` ⇒ ``DECLARE_DLIST``
+- :file:`lib/skiplist.*`, ``skiplist_*`` ⇒ ``DECLARE_SKIPLIST``
+- :file:`lib/*_queue.h` (BSD), ``SLIST_*`` ⇒ ``DECLARE_LIST``
+- :file:`lib/*_queue.h` (BSD), ``LIST_*`` ⇒ ``DECLARE_DLIST``
+- :file:`lib/*_queue.h` (BSD), ``STAILQ_*`` ⇒ ``DECLARE_LIST``
+- :file:`lib/*_queue.h` (BSD), ``TAILQ_*`` ⇒ ``DECLARE_DLIST``
+- :file:`lib/hash.*`, ``hash_*`` ⇒ ``DECLARE_HASH``
+- :file:`lib/linklist.*`, ``list_*`` ⇒ ``DECLARE_DLIST``
+- open-coded linked lists ⇒ ``DECLARE_LIST``/``DECLARE_DLIST``
+
+
+Code Formatting
+---------------
+
+C Code
+^^^^^^
+
+For C code, FRR uses Linux kernel style except where noted below. Code which
+does not comply with these style guidelines will not be accepted.
+
+The project provides multiple tools to allow you to correctly style your code
+as painlessly as possible, primarily built around ``clang-format``.
+
+clang-format
+
+ In the project root there is a :file:`.clang-format` configuration file
+ which can be used with the ``clang-format`` source formatter tool from the
+ LLVM project. Most of the time, this is the easiest and smartest tool to
+ use. It can be run in a variety of ways. If you point it at a C source file
+ or directory of source files, it will format all of them. In the LLVM source
+ tree there are scripts that allow you to integrate it with ``git``, ``vim``
+ and ``emacs``, and there are third-party plugins for other editors. The
+ ``git`` integration is particularly useful; suppose you have some changes in
+ your git index. Then, with the integration installed, you can do the
+ following:
+
+ ::
+
+ git clang-format
+
+ This will format *only* the changes present in your index. If you have just
+ made a few commits and would like to correctly style only the changes made
+ in those commits, you can use the following syntax:
+
+ ::
+
+ git clang-format HEAD~X
+
+ Where X is one more than the number of commits back from the tip of your
+ branch you would like ``clang-format`` to look at (similar to specifying the
+ target for a rebase).
+
+ The ``vim`` plugin is particularly useful. It allows you to select lines in
+ visual line mode and press a key binding to invoke ``clang-format`` on only
+ those lines.
+
+ When using ``clang-format``, it is recommended to use the latest version.
+ Each consecutive version generally has better handling of various edge
+ cases. You may notice on occasion that two consecutive runs of
+ ``clang-format`` over the same code may result in changes being made on the
+ second run. This is an unfortunate artifact of the tool. Please check with
+ the kernel style guide if in doubt.
+
+ One stylistic problem with the FRR codebase is the use of ``DEFUN`` macros
+ for defining CLI commands. ``clang-format`` will happily format these macro
+ invocations, but the result is often unsightly and difficult to read.
+ Consequently, FRR takes a more relaxed position with how these are
+ formatted. In general you should lean towards using the style exemplified in
+ the section on :ref:`command-line-interface`. Because ``clang-format``
+ mangles this style, there is a Python script named ``tools/indent.py`` that
+ wraps ``clang-format`` and handles ``DEFUN`` macros as well as some other
+ edge cases specific to FRR. If you are submitting a new file, it is
+ recommended to run that script over the new file, preferably after ensuring
+ that the latest stable release of ``clang-format`` is in your ``PATH``.
+
+ Documentation on ``clang-format`` and its various integrations is maintained
+ on the LLVM website.
+
+ https://clang.llvm.org/docs/ClangFormat.html
+
+checkpatch.sh
+checkpatch.pl
+
+ .. seealso:: :ref:`checkpatch`
+
+ In the Linux kernel source tree there is a Perl script used to check
+ incoming patches for style errors. FRR uses a shell script front end and an
+ adapted version of the perl script for the same purpose. These scripts can
+ be found at :file:`tools/checkpatch.sh` and :file:`tools/checkpatch.pl`.
+ This script takes a git-formatted diff or patch file, applies it to a clean
+ FRR tree, and inspects the result to catch potential style errors. Running
+ this script on your patches before submission is highly recommended. The CI
+ system runs this script as well and will comment on the PR with the results
+ if style errors are found.
+
+ It is run like this::
+
+ ./checkpatch.sh <patch> <tree>
+
+ Reports are generated on ``stderr`` and the exit code indicates whether
+ issues were found (2, 1) or not (0).
+
+ Where ``<patch>`` is the path to the diff or patch file and ``<tree>`` is
+ the path to your FRR source tree. The tree should be on the branch that you
+ intend to submit the patch against. The script will make a best-effort
+ attempt to save the state of your working tree and index before applying the
+ patch, and to restore it when it is done, but it is still recommended that
+ you have a clean working tree as the script does perform a hard reset on
+ your tree during its run.
+
+ The script reports two classes of issues, namely WARNINGs and ERRORs. Please
+ pay attention to both of them. The script will generally report WARNINGs
+ where it cannot be 100% sure that a particular issue is real. In most cases
+ WARNINGs indicate an issue that needs to be fixed. Sometimes the script will
+ report false positives; these will be handled in code review on a
+ case-by-case basis. Since the script only looks at changed lines,
+ occasionally changing one part of a line can cause the script to report a
+ style issue already present on that line that is unrelated to the change.
+ When convenient it is preferred that these be cleaned up inline, but this is
+ not required.
+
+ In general, a developer should heed the information reported by checkpatch.
+ However, some flexibility is needed for cases where human judgement yields
+ better clarity than the script. Accordingly, it may be appropriate to
+ ignore some checkpatch.sh warnings per discussion among the submitter(s)
+ and reviewer(s) of a change. Misreporting of errors by the script is
+ possible. When this occurs, the exception should be handled either by
+ patching checkpatch to correct the false error report, or by documenting the
+ exception in this document under :ref:`style-exceptions`. If the incorrect
+ report is likely to appear again, a checkpatch update is preferred.
+
+ If the script finds one or more WARNINGs it will exit with 1. If it finds
+ one or more ERRORs it will exit with 2.
+
+ For convenience the Linux documentation for the :file:`tools/checkpatch.pl`
+ script has been included unmodified (i.e., it has not been updated to
+ reflect local changes) :doc:`here <checkpatch>`
+
+
+Please remember that while FRR provides these tools for your convenience,
+responsibility for properly formatting your code ultimately lies on the
+shoulders of the submitter. As such, it is recommended to double-check the
+results of these tools to avoid delays in merging your submission.
+
+In some cases, these tools modify or flag the format in ways that go beyond or
+even conflict [#tool_style_conflicts]_ with the canonical documented Linux
+kernel style. In these cases, the Linux kernel style takes priority;
+non-canonical issues flagged by the tools are not compulsory but rather are
+opportunities for discussion among the submitter(s) and reviewer(s) of a change.
+
+**Whitespace changes in untouched parts of the code are not acceptable
+in patches that change actual code.** To change/fix formatting issues,
+please create a separate patch that only does formatting changes and
+nothing else.
+
+Kernel and BSD styles are documented externally:
+
+- https://www.kernel.org/doc/html/latest/process/coding-style.html
+- http://man.openbsd.org/style
+
+For GNU coding style, use ``indent`` with the following invocation:
+
+::
+
+ indent -nut -nfc1 file_for_submission.c
+
+
+Historically, FRR used fixed-width integral types that do not exist in any
+standard but were defined by most platforms at some point. Officially these
+types are not guaranteed to exist. Therefore, please use the fixed-width
+integral types introduced in the C99 standard when contributing new code to
+FRR. If you need to convert a large amount of code to use the correct types,
+there is a shell script in :file:`tools/convert-fixedwidth.sh` that will do the
+necessary replacements.
+
++-----------+--------------------------+
+| Incorrect | Correct |
++===========+==========================+
+| u_int8_t | uint8_t |
++-----------+--------------------------+
+| u_int16_t | uint16_t |
++-----------+--------------------------+
+| u_int32_t | uint32_t |
++-----------+--------------------------+
+| u_int64_t | uint64_t |
++-----------+--------------------------+
+| u_char | uint8_t or unsigned char |
++-----------+--------------------------+
+| u_short | unsigned short |
++-----------+--------------------------+
+| u_int | unsigned int |
++-----------+--------------------------+
+| u_long | unsigned long |
++-----------+--------------------------+
+
+FRR also uses unnamed struct fields, enabled with ``-fms-extensions`` (cf.
+https://gcc.gnu.org/onlinedocs/gcc/Unnamed-Fields.html). The following two
+patterns can/should be used where contextually appropriate:
+
+.. code-block:: c
+
+ struct outer {
+ struct inner;
+ };
+
+.. code-block:: c
+
+ struct outer {
+ union {
+ struct inner;
+ struct inner inner_name;
+ };
+ };
+
+
+.. _style-exceptions:
+
+Exceptions
+""""""""""
+
+FRR project code comes from a variety of sources, so there are some
+stylistic exceptions in place. They are organized here by branch.
+
+For ``master``:
+
+BSD coding style applies to:
+
+- ``ldpd/``
+
+``babeld`` uses, approximately, the following style:
+
+- K&R style braces
+- Indents are 4 spaces
+- Function return types are on their own line
+
+For ``stable/3.0`` and ``stable/2.0``:
+
+GNU coding style apply to the following parts:
+
+- ``lib/``
+- ``zebra/``
+- ``bgpd/``
+- ``ospfd/``
+- ``ospf6d/``
+- ``isisd/``
+- ``ripd/``
+- ``ripngd/``
+- ``vtysh/``
+
+BSD coding style applies to:
+
+- ``ldpd/``
+
+
+Python Code
+^^^^^^^^^^^
+
+Format all Python code with `black <https://github.com/psf/black>`_.
+
+In a line::
+
+ python3 -m black <file.py>
+
+Run this on any Python files you modify before committing.
+
+FRR's Python code has been formatted with black version 19.10b.
+
+
+YANG
+^^^^
+
+FRR uses YANG to define data models for its northbound interface. YANG models
+should follow conventions used by the IETF standard models. From a practical
+standpoint, this corresponds to the output produced by the ``yanglint`` tool
+included in the ``libyang`` project, which is used by FRR to parse and validate
+YANG models. You should run the following command on all YANG documents you
+write:
+
+.. code-block:: console
+
+ yanglint -f yang <model>
+
+The output of this command should be identical to the input file. The sole
+exception to this is comments. ``yanglint`` does not support comments and will
+strip them from its output. You may include comments in your YANG documents,
+but they should be indented appropriately (use spaces). Where possible,
+comments should be eschewed in favor of a suitable ``description`` statement.
+
+In short, a diff between your input file and the output of ``yanglint`` should
+either be empty or contain only comments.
+
+Specific Exceptions
+^^^^^^^^^^^^^^^^^^^
+
+Most of the time checkpatch errors should be corrected. Occasionally as a group
+maintainers will decide to ignore certain stylistic issues. Usually this is
+because correcting the issue is not possible without large unrelated code
+changes. When an exception is made, if it is unlikely to show up again and
+doesn't warrant an update to checkpatch, it is documented here.
+
++------------------------------------------+---------------------------------------------------------------+
+| Issue | Ignore Reason |
++==========================================+===============================================================+
+| DEFPY_HIDDEN, DEFPY_ATTR: complex macros | DEF* macros cannot be wrapped in parentheses without updating |
+| should be wrapped in parentheses | all usages of the macro, which would be highly disruptive. |
++------------------------------------------+---------------------------------------------------------------+
+
+Types of configurables
+----------------------
+
+.. note::
+
+ This entire section essentially just argues to not make configuration
+ unnecessarily involved for the user. Rather than rules, this is more of
+ a list of conclusions intended to help make FRR usable for operators.
+
+
+Almost every feature FRR has comes with its own set of switches and options.
+There are several stages at which configuration can be applied. In order of
+preference, these are:
+
+- at configuration/runtime, through YANG.
+
+ This is the preferred way for all FRR knobs. Not all daemons and features
+ are fully YANGified yet, so in some cases new features cannot rely on a
+ YANG interface. If a daemon already implements a YANG interface (even
+ partial), new CLI options must be implemented through a YANG model.
+
+ .. warning::
+
+ Unlike everything else in this section being guidelines with some slack,
+ implementing and using a YANG interface for new CLI options in (even
+ partially!) YANGified daemons is a hard requirement.
+
+
+- at configuration/runtime, through the CLI.
+
+ The "good old" way for all regular configuration. More involved for users
+ to automate *correctly* than YANG.
+
+- at startup, by loading additional modules.
+
+ If a feature introduces a dependency on additional libraries (e.g. libsnmp,
+ rtrlib, etc.), this is the best way to encapsulate the dependency. Having
+ a separate module allows the distribution to create a separate package
+ with the extra dependency, so FRR can still be installed without pulling
+ everything in.
+
+ A module may also be appropriate if a feature is large and reasonably well
+ isolated. Reducing the amount of running the code is a security benefit,
+ so even if there are no new external dependencies, modules can be useful.
+
+ While modules cannot currently be loaded at runtime, this is a tradeoff
+ decision that was made to allow modules to change/extend code that is very
+ hard to (re)adjust at runtime. If there is a case for runtime (un)loading
+ of modules, this tradeoff can absolutely be reevaluated.
+
+- at startup, with command line options.
+
+ This interface is only appropriate for options that have an effect very
+ early in FRR startup, i.e. before configuration is loaded. Anything that
+ affects configuration load itself should be here, as well as options
+ changing the environment FRR runs in.
+
+ If a tunable can be changed at runtime, a command line option is only
+ acceptable if the configured value has an effect before configuration is
+ loaded (e.g. zebra reads routes from the kernel before loading config, so
+ the netlink buffer size is an appropriate command line option.)
+
+- at compile time, with ``./configure`` options.
+
+ This is the absolute last preference for tunables, since the distribution
+ needs to make the decision for the user and/or the user needs to rebuild
+ FRR in order to change the option.
+
+ "Good" configure options do one of three things:
+
+ - set distribution-specific parameters, most prominently all the path
+ options. File system layout is a distribution/packaging choice, so the
+ user would hopefully never need to adjust these.
+
+ - changing toolchain behavior, e.g. instrumentation, warnings,
+ optimizations and sanitizers.
+
+ - enabling/disabling parts of the build, especially if they need
+ additional dependencies. Being able to build only parts of FRR, or
+ without some library, is useful. **The only effect these options should
+ have is adding or removing files from the build result.** If a knob
+ in this category causes the same binary to exist in different variants,
+ it is likely implemented incorrectly!
+
+ .. note::
+
+ This last guideline is currently ignored by several configure options.
+ ``vtysh`` in general depends on the entire list of enabled daemons,
+ and options like ``--enable-bgp-vnc`` and ``--enable-ospfapi`` change
+ daemons internally. Consider this more of an "ideal" than a "rule".
+
+
+Whenever adding new knobs, please try reasonably hard to go up as far as
+possible on the above list. Especially ``./configure`` flags are often enough
+the "easy way out" but should be avoided when at all possible. To a lesser
+degree, the same applies to command line options.
+
+
+Compile-time conditional code
+-----------------------------
+
+Many users access FRR via binary packages from 3rd party sources;
+compile-time code puts inclusion/exclusion in the hands of the package
+maintainer. Please think very carefully before making code conditional
+at compile time, as it increases regression testing, maintenance
+burdens, and user confusion. In particular, please avoid gratuitous
+``--enable-…`` switches to the configure script - in general, code
+should be of high quality and in working condition, or it shouldn’t be
+in FRR at all.
+
+When code must be compile-time conditional, try have the compiler make
+it conditional rather than the C pre-processor so that it will still be
+checked by the compiler, even if disabled. For example,
+
+::
+
+ if (SOME_SYMBOL)
+ frobnicate();
+
+is preferred to
+
+::
+
+ #ifdef SOME_SYMBOL
+ frobnicate ();
+ #endif /* SOME_SYMBOL */
+
+Note that the former approach requires ensuring that ``SOME_SYMBOL`` will be
+defined (watch your ``AC_DEFINE``\ s).
+
+Debug-guards in code
+--------------------
+
+Debugging statements are an important methodology to allow developers to fix
+issues found in the code after it has been released. The caveat here is that
+the developer must remember that people will be using the code at scale and in
+ways that can be unexpected for the original implementor. As such debugs
+**MUST** be guarded in such a way that they can be turned off. FRR has the
+ability to turn on/off debugs from the CLI and it is expected that the
+developer will use this convention to allow control of their debugs.
+
+Custom syntax-like block macros
+-------------------------------
+
+FRR uses some macros that behave like the ``for`` or ``if`` C keywords. These
+macros follow these patterns:
+
+- loop-style macros are named ``frr_each_*`` (and ``frr_each``)
+- single run macros are named ``frr_with_*``
+- to avoid confusion, ``frr_with_*`` macros must always use a ``{ ... }``
+ block even if the block only contains one statement. The ``frr_each``
+ constructs are assumed to be well-known enough to use normal ``for`` rules.
+- ``break``, ``return`` and ``goto`` all work correctly. For loop-style
+ macros, ``continue`` works correctly too.
+
+Both the ``each`` and ``with`` keywords are inspired by other (more
+higher-level) programming languages that provide these constructs.
+
+There are also some older iteration macros, e.g. ``ALL_LIST_ELEMENTS`` and
+``FOREACH_AFI_SAFI``. These macros in some cases do **not** fulfill the above
+pattern (e.g. ``break`` does not work in ``FOREACH_AFI_SAFI`` because it
+expands to 2 nested loops.)
+
+Static Analysis and Sanitizers
+------------------------------
+Clang/LLVM and GCC come with a variety of tools that can be used to help find
+bugs in FRR.
+
+clang-analyze
+ This is a static analyzer that scans the source code looking for patterns
+ that are likely to be bugs. The tool is run automatically on pull requests
+ as part of CI and new static analysis warnings will be placed in the CI
+ results. FRR aims for absolutely zero static analysis errors. While the
+ project is not quite there, code that introduces new static analysis errors
+ is very unlikely to be merged.
+
+AddressSanitizer
+ This is an excellent tool that provides runtime instrumentation for
+ detecting memory errors. As part of CI FRR is built with this
+ instrumentation and run through a series of tests to look for any results.
+ Testing your own code with this tool before submission is encouraged. You
+ can enable it by passing::
+
+ --enable-address-sanitizer
+
+ to ``configure``.
+
+ThreadSanitizer
+ Similar to AddressSanitizer, this tool provides runtime instrumentation for
+ detecting data races. If you are working on or around multithreaded code,
+ extensive testing with this instrumtation enabled is *highly* recommended.
+ You can enable it by passing::
+
+ --enable-thread-sanitizer
+
+ to ``configure``.
+
+MemorySanitizer
+ Similar to AddressSanitizer, this tool provides runtime instrumentation for
+ detecting use of uninitialized heap memory. Testing your own code with this
+ tool before submission is encouraged. You can enable it by passing::
+
+ --enable-memory-sanitizer
+
+ to ``configure``.
+
+All of the above tools are available in the Clang/LLVM toolchain since 3.4.
+AddressSanitizer and ThreadSanitizer are available in recent versions of GCC,
+but are no longer actively maintained. MemorySanitizer is not available in GCC.
+
+.. note::
+
+ 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 for static analysis
+errors with Coverity and pull request changes are scanned as part of the
+Continuous Integration (CI) process. Developers can scan their commits for
+Coverity static analysis errors prior to submission using the
+``scan-build`` command. To use this command, the ``clang-tools`` package must
+be installed. For example, this can be accomplished on Ubuntu with the
+``sudo apt-get install clang-tools`` command. Then, touch the files you want scanned and
+invoke the ``scan-build`` command. For example::
+
+ cd ~/GitHub/frr
+ touch ospfd/ospf_flood.c ospfd/ospf_vty.c ospfd/ospf_opaque.c
+ cd build
+ scan-build make -j32
+
+The results of the scan including any static analysis errors will appear inline.
+Additionally, there will a directory in the /tmp containing the Coverity
+reports (e.g., scan-build-2023-06-09-120100-473730-1).
+
+Executing non-installed dynamic binaries
+----------------------------------------
+
+Since FRR uses the GNU autotools build system, it inherits its shortcomings.
+To execute a binary directly from the build tree under a wrapper like
+`valgrind`, `gdb` or `strace`, use::
+
+ ./libtool --mode=execute valgrind [--valgrind-opts] zebra/zebra [--zebra-opts]
+
+While replacing valgrind/zebra as needed. The `libtool` script is found in
+the root of the build directory after `./configure` has completed. Its purpose
+is to correctly set up `LD_LIBRARY_PATH` so that libraries from the build tree
+are used. (On some systems, `libtool` is also available from PATH, but this is
+not always the case.)
+
+.. _cli-workflow:
+
+CLI changes
+-----------
+
+CLI's are a complicated ugly beast. Additions or changes to the CLI should use
+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
+-----------------------
+
+As a general principle, changes to CLI and code in the lib/ directory should be
+made in a backwards compatible fashion. This means that changes that are purely
+stylistic in nature should be avoided, e.g., renaming an existing macro or
+library function name without any functional change. When adding new parameters
+to common functions, it is also good to consider if this too should be done in
+a backward compatible fashion, e.g., by preserving the old form in addition to
+adding the new form.
+
+This is not to say that minor or even major functional changes to CLI and
+common code should be avoided, but rather that the benefit gained from a change
+should be weighed against the added cost/complexity to existing code. Also,
+that when making such changes, it is good to preserve compatibility when
+possible to do so without introducing maintenance overhead/cost. It is also
+important to keep in mind, existing code includes code that may reside in
+private repositories (and is yet to be submitted) or code that has yet to be
+migrated from Quagga to FRR.
+
+That said, compatibility measures can (and should) be removed when either:
+
+- they become a significant burden, e.g. when data structures change and the
+ compatibility measure would need a complex adaptation layer or becomes
+ flat-out impossible
+- some measure of time (dependent on the specific case) has passed, so that
+ the compatibility grace period is considered expired.
+
+For CLI commands, the deprecation period is 1 year.
+
+In all cases, compatibility pieces should be marked with compiler/preprocessor
+annotations to print warnings at compile time, pointing to the appropriate
+update path. A ``-Werror`` build should fail if compatibility bits are used. To
+avoid compilation issues in released code, such compiler/preprocessor
+annotations must be ignored non-development branches. For example:
+
+.. code-block:: c
+
+ #if CONFDATE > 20180403
+ CPP_NOTICE("Use of <XYZ> is deprecated, please use <ABC>")
+ #endif
+
+Preferably, the shell script :file:`tools/fixup-deprecated.py` will be
+updated along with making non-backwards compatible code changes, or an
+alternate script should be introduced, to update the code to match the
+change. When the script is updated, there is no need to preserve the
+deprecated code. Note that this does not apply to user interface
+changes, just internal code, macros and libraries.
+
+Miscellaneous
+-------------
+
+When in doubt, follow the guidelines in the Linux kernel style guide, or ask on
+the development mailing list / public Slack instance.
+
+JSON Output
+^^^^^^^^^^^
+
+New JSON output in FRR needs to be backed by schema, in particular a YANG model.
+When adding new JSON, first search for an existing YANG model, either in FRR or
+a standard model (e.g., IETF) and use that model as the basis for any JSON
+structure and *especially* for key names and canonical values formats.
+
+If no YANG model exists to support the JSON then an FRR YANG model needs to be
+added to or created to support the JSON format.
+
+* All JSON keys are to be ``camelCased``, with no spaces. YANG modules almost
+ always use ``kebab-case`` (i.e., all lower case with hyphens to separate
+ words), so these identifiers need to be mapped to ``camelCase`` by removing
+ the hyphen (or symbol) and capitalizing the following letter, for
+ example "router-id" becomes "routerId"
+* Commands which output JSON should produce ``{}`` if they have nothing to
+ display
+* In general JSON commands include a ``json`` keyword typically at the end of
+ the CLI command (e.g., ``show ip ospf json``)
+
+Use of const
+^^^^^^^^^^^^
+
+Please consider using ``const`` when possible: it's a useful hint to
+callers about the limits to side-effects from your apis, and it makes
+it possible to use your apis in paths that involve ``const``
+objects. If you encounter existing apis that *could* be ``const``,
+consider including changes in your own pull-request.
+
+Help with specific warnings
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+FRR's configure script enables a whole batch of extra warnings, some of which
+may not be obvious in how to fix. Here are some notes on specific warnings:
+
+* ``-Wstrict-prototypes``: you probably just forgot the ``void`` in a function
+ declaration with no parameters, i.e. ``static void foo() {...}`` rather than
+ ``static void foo(void) {...}``.
+
+ Without the ``void``, in C, it's a function with *unspecified* parameters
+ (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:
+
+Documentation
+=============
+
+FRR uses Sphinx+RST as its documentation system. The document you are currently
+reading was generated by Sphinx from RST source in
+:file:`doc/developer/workflow.rst`. The documentation is structured as follows:
+
++-----------------------+-------------------------------------------+
+| Directory | Contents |
++=======================+===========================================+
+| :file:`doc/user` | User documentation; configuration guides; |
+| | protocol overviews |
++-----------------------+-------------------------------------------+
+| :file:`doc/developer` | Developer's documentation; API specs; |
+| | datastructures; architecture overviews; |
+| | project management procedure |
++-----------------------+-------------------------------------------+
+| :file:`doc/manpages` | Source for manpages |
++-----------------------+-------------------------------------------+
+| :file:`doc/figures` | Images and diagrams |
++-----------------------+-------------------------------------------+
+| :file:`doc/extra` | Miscellaneous Sphinx extensions, scripts, |
+| | customizations, etc. |
++-----------------------+-------------------------------------------+
+
+Each of these directories, with the exception of :file:`doc/figures` and
+:file:`doc/extra`, contains a Sphinx-generated Makefile and configuration
+script :file:`conf.py` used to set various document parameters. The makefile
+can be used for a variety of targets; invoke `make help` in any of these
+directories for a listing of available output formats. For convenience, there
+is a top-level :file:`Makefile.am` that has targets for PDF and HTML
+documentation for both developer and user documentation, respectively. That
+makefile is also responsible for building manual pages packed with distribution
+builds.
+
+Indent and styling should follow existing conventions:
+
+- 3 spaces for indents under directives
+- Cross references may contain only lowercase alphanumeric characters and
+ hyphens ('-')
+- Lines wrapped to 80 characters where possible
+
+Characters for header levels should follow Python documentation guide:
+
+- ``#`` with overline, for parts
+- ``*`` with overline, for chapters
+- ``=``, for sections
+- ``-``, for subsections
+- ``^``, for subsubsections
+- ``"``, for paragraphs
+
+After you have made your changes, please make sure that you can invoke
+``make latexpdf`` and ``make html`` with no warnings.
+
+The documentation is currently incomplete and needs love. If you find a broken
+cross-reference, figure, dead hyperlink, style issue or any other nastiness we
+gladly accept documentation patches.
+
+To build the docs, please ensure you have installed a recent version of
+`Sphinx <http://www.sphinx-doc.org/en/stable/install.html>`_. If you want to
+build LaTeX or PDF docs, you will also need a full LaTeX distribution
+installed.
+
+Code
+----
+
+FRR is a large and complex software project developed by many different people
+over a long period of time. Without adequate documentation, it can be
+exceedingly difficult to understand code segments, APIs and other interfaces.
+In the interest of keeping the project healthy and maintainable, you should
+make every effort to document your code so that other people can understand
+what it does without needing to closely read the code itself.
+
+Some specific guidelines that contributors should follow are:
+
+- Functions exposed in header files should have descriptive comments above
+ their signatures in the header file. At a minimum, a function comment should
+ contain information about the return value, parameters, and a general summary
+ of the function's purpose. Documentation on parameter values can be omitted
+ if it is (very) obvious what they are used for.
+
+ Function comments must follow the style for multiline comments laid out in
+ the kernel style guide.
+
+ Example:
+
+ .. code-block:: c
+
+ /*
+ * Determines whether or not a string is cool.
+ *
+ * text
+ * the string to check for coolness
+ *
+ * is_clccfc
+ * whether capslock is cruise control for cool
+ *
+ * Returns:
+ * 7 if the text is cool, 0 otherwise
+ */
+ int check_coolness(const char *text, bool is_clccfc);
+
+ Function comments should make it clear what parameters and return values are
+ used for.
+
+- Static functions should have descriptive comments in the same form as above
+ if what they do is not immediately obvious. Use good engineering judgement
+ when deciding whether a comment is necessary. If you are unsure, document
+ your code.
+- Global variables, static or not, should have a comment describing their use.
+- **For new code in lib/, these guidelines are hard requirements.**
+
+If you make significant changes to portions of the codebase covered in the
+Developer's Manual, add a major subsystem or feature, or gain arcane mastery of
+some undocumented or poorly documented part of the codebase, please document
+your work so others can benefit. If you add a major feature or introduce a new
+API, please document the architecture and API to the best of your abilities in
+the Developer's Manual, using good judgement when choosing where to place it.
+
+Finally, if you come across some code that is undocumented and feel like
+going above and beyond, document it! We absolutely appreciate and accept
+patches that document previously undocumented code.
+
+User
+----
+
+If you are contributing code that adds significant user-visible functionality
+please document how to use it in :file:`doc/user`. Use good judgement when
+choosing where to place documentation. For example, instructions on how to use
+your implementation of a new BGP draft should go in the BGP chapter instead of
+being its own chapter. If you are adding a new protocol daemon, please create a
+new chapter.
+
+FRR Specific Markup
+-------------------
+
+FRR has some customizations applied to the Sphinx markup that go a long way
+towards making documentation easier to use, write and maintain.
+
+CLI Commands
+^^^^^^^^^^^^
+
+When documenting CLI please use the ``.. clicmd::`` directive. This directive
+will format the command and generate index entries automatically. For example,
+the command :clicmd:`show pony` would be documented as follows:
+
+.. code-block:: rest
+
+ .. clicmd:: show pony
+
+ Prints an ASCII pony. Example output:::
+
+ >>\.
+ /_ )`.
+ / _)`^)`. _.---. _
+ (_,' \ `^-)"" `.\
+ | | \
+ \ / |
+ / \ /.___.'\ (\ (_
+ < ,"|| \ |`. \`-'
+ \\ () )| )/
+ hjw |_>|> /_] //
+ /_] /_]
+
+
+When documented this way, CLI commands can be cross referenced with the
+``:clicmd:`` inline markup like so:
+
+.. code-block:: rest
+
+ :clicmd:`show pony`
+
+This is very helpful for users who want to quickly remind themselves what a
+particular command does.
+
+When documenting a cli that has a ``no`` form, please do not include the ``no``
+form. I.e. ``no show pony`` would not be documented anywhere. Since most
+commands have ``no`` forms, users should be able to infer these or get help
+from vtysh's completions.
+
+When documenting commands that have lots of possible variants, just document
+the single command in summary rather than enumerating each possible variant.
+E.g. for ``show pony [foo|bar]``, do not:
+
+.. code-block:: rest
+
+ .. clicmd:: show pony
+ .. clicmd:: show pony foo
+ .. clicmd:: show pony bar
+
+Do:
+
+.. code-block:: rest
+
+ .. clicmd:: show pony [foo|bar]
+
+
+Configuration Snippets
+^^^^^^^^^^^^^^^^^^^^^^
+
+When putting blocks of example configuration please use the
+``.. code-block::`` directive and specify ``frr`` as the highlighting language,
+as in the following example. This will tell Sphinx to use a custom Pygments
+lexer to highlight FRR configuration syntax.
+
+.. code-block:: rest
+
+ .. code-block:: frr
+
+ !
+ ! Example configuration file.
+ !
+ log file /tmp/log.log
+ service integrated-vtysh-config
+ !
+ ip route 1.2.3.0/24 reject
+ ipv6 route de:ea:db:ee:ff::/64 reject
+ !
+
+
+.. _GitHub: https://github.com/frrouting/frr
+.. _GitHub issues: https://github.com/frrouting/frr/issues
+
+.. rubric:: Footnotes
+
+.. [#tool_style_conflicts] For example, lines over 80 characters are allowed
+ for text strings to make it possible to search the code for them: please
+ see `Linux kernel style (breaking long lines and strings) <https://www.kernel.org/doc/html/v4.10/process/coding-style.html#breaking-long-lines-and-strings>`_
+ and `Issue #1794 <https://github.com/FRRouting/frr/issues/1794>`_.