mirror of
				https://git.proxmox.com/git/mirror_frr
				synced 2025-11-04 01:43:38 +00:00 
			
		
		
		
	The documentation pages on checkpatch and CSPF were not reachable because they were not included in any toctree. Include them in the tree! Signed-off-by: Quentin Young <qlyoung@qlyoung.net>
		
			
				
	
	
		
			1741 lines
		
	
	
		
			71 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
			
		
		
	
	
			1741 lines
		
	
	
		
			71 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
.. _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>`_.
 |