From d1890d041eae5a4c389321053a1328a277726945 Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Fri, 8 Dec 2017 11:47:49 -0500 Subject: [PATCH] doc: begin developer's manual * Move doc/code/ -> doc/developer/ * Move disparate code documentation to doc/developer/ * Convert Markdown docs to reStructuredText * Organize docs into Sphinx tree * Move build docs -> doc/developer/ * Change build doc titles to fit under Building subsection of manual Signed-off-by: Quentin Young --- doc/.gitignore | 1 + doc/cli.md | 557 -------------- doc/code/.gitignore | 3 - doc/code/Makefile | 216 ------ .../Building_FRR_on_CentOS6.rst} | 117 ++- .../Building_FRR_on_CentOS7.rst} | 85 ++- .../Building_FRR_on_Debian8.rst} | 75 +- .../Building_FRR_on_Debian9.rst} | 65 +- .../Building_FRR_on_Fedora24.rst} | 81 +- .../Building_FRR_on_FreeBSD10.rst} | 51 +- .../Building_FRR_on_FreeBSD11.rst} | 49 +- .../Building_FRR_on_FreeBSD9.rst} | 54 +- .../Building_FRR_on_LEDE-OpenWRT.rst} | 77 +- .../Building_FRR_on_NetBSD6.rst} | 60 +- .../Building_FRR_on_NetBSD7.rst} | 55 +- .../Building_FRR_on_OmniOS.rst} | 51 +- .../Building_FRR_on_OpenBSD6.rst} | 76 +- .../Building_FRR_on_Ubuntu1204.rst} | 82 +- .../Building_FRR_on_Ubuntu1404.rst} | 72 +- .../Building_FRR_on_Ubuntu1604.rst} | 90 ++- doc/developer/building.rst | 22 + doc/developer/cli.rst | 615 +++++++++++++++ doc/{code => developer}/conf.py | 6 +- doc/developer/dev-modules.rst | 125 +++ doc/developer/git_branches.svg | 720 ++++++++++++++++++ doc/{code => developer}/hooks.rst | 0 doc/{code => developer}/index.rst | 12 +- doc/{ => developer}/ldpd-basic-test-setup.md | 0 doc/{code => developer}/library.rst | 2 + doc/{code => developer}/memtypes.rst | 0 doc/{ => developer}/next-hop-tracking.txt | 0 doc/developer/workflow.rst | 544 +++++++++++++ 32 files changed, 2821 insertions(+), 1142 deletions(-) delete mode 100644 doc/cli.md delete mode 100644 doc/code/.gitignore delete mode 100644 doc/code/Makefile rename doc/{Building_FRR_on_CentOS6.md => developer/Building_FRR_on_CentOS6.rst} (65%) rename doc/{Building_FRR_on_CentOS7.md => developer/Building_FRR_on_CentOS7.rst} (71%) rename doc/{Building_FRR_on_Debian8.md => developer/Building_FRR_on_Debian8.rst} (74%) rename doc/{Building_FRR_on_Debian9.md => developer/Building_FRR_on_Debian9.rst} (77%) rename doc/{Building_FRR_on_Fedora24.md => developer/Building_FRR_on_Fedora24.rst} (73%) rename doc/{Building_FRR_on_FreeBSD10.md => developer/Building_FRR_on_FreeBSD10.rst} (75%) rename doc/{Building_FRR_on_FreeBSD11.md => developer/Building_FRR_on_FreeBSD11.rst} (75%) rename doc/{Building_FRR_on_FreeBSD9.md => developer/Building_FRR_on_FreeBSD9.rst} (73%) rename doc/{Building_FRR_for_LEDE-OpenWRT.md => developer/Building_FRR_on_LEDE-OpenWRT.rst} (59%) rename doc/{Building_FRR_on_NetBSD6.md => developer/Building_FRR_on_NetBSD6.rst} (79%) rename doc/{Building_FRR_on_NetBSD7.md => developer/Building_FRR_on_NetBSD7.rst} (79%) rename doc/{Building_FRR_on_OmniOS.md => developer/Building_FRR_on_OmniOS.rst} (81%) rename doc/{Building_FRR_on_OpenBSD6.md => developer/Building_FRR_on_OpenBSD6.rst} (82%) rename doc/{Building_FRR_on_Ubuntu1204.md => developer/Building_FRR_on_Ubuntu1204.rst} (79%) rename doc/{Building_FRR_on_Ubuntu1404.md => developer/Building_FRR_on_Ubuntu1404.rst} (74%) rename doc/{Building_FRR_on_Ubuntu1604.md => developer/Building_FRR_on_Ubuntu1604.rst} (68%) create mode 100644 doc/developer/building.rst create mode 100644 doc/developer/cli.rst rename doc/{code => developer}/conf.py (98%) create mode 100644 doc/developer/dev-modules.rst create mode 100644 doc/developer/git_branches.svg rename doc/{code => developer}/hooks.rst (100%) rename doc/{code => developer}/index.rst (50%) rename doc/{ => developer}/ldpd-basic-test-setup.md (100%) rename doc/{code => developer}/library.rst (82%) rename doc/{code => developer}/memtypes.rst (100%) rename doc/{ => developer}/next-hop-tracking.txt (100%) create mode 100644 doc/developer/workflow.rst diff --git a/doc/.gitignore b/doc/.gitignore index 57c66cb4ac..8dada02288 100644 --- a/doc/.gitignore +++ b/doc/.gitignore @@ -35,3 +35,4 @@ stamp-vti *~ *.loT refix +_build diff --git a/doc/cli.md b/doc/cli.md deleted file mode 100644 index 723237ebb8..0000000000 --- a/doc/cli.md +++ /dev/null @@ -1,557 +0,0 @@ -FRR Command Line Interface -========================== - -Definition Grammar ------------------- - -This is a reference for the syntax used when defining new CLI commands. An -example definition is: - -``` -DEFUN (command_name, - command_name_cmd, ---> "example DEFINITION...", - <..doc strings..>) -``` - -The arrowed part is the definition string. - -Explicit syntax rules in Flex and Bison may be found in lib/command_lex.l and -lib/command_parse.y, respectively. If you can read BNF and regex those will be -more useful than this document. - -If the parser is throwing syntax or other errors and you can't figure out why, -it's unlikely to be a bug in the parser. If the error message is not useful, -please file a bug for a better error message. If all else fails, read the token -definitions in the lexer source and the Bison BNF in the parser source. - -Characters allowed in each token type: - -Tokens ------- -* `WORD` -- A token that begins with +, -, or a lowercase letter. It is - an unchanging part of the command and will only match itself. - Example: "show ip bgp", every token is a WORD. -* `IPV4` -- 'A.B.C.D', matches an IPv4 address. -* `IPV6` -- 'X:X::X:X', matches an IPv6 address. -* `IPV4_PREFIX` -- 'A.B.C.D/M', matches an IPv4 prefix in CIDR notation. -* `IPV6_PREFIX` -- 'X:X::X:X/M', matches an IPv6 prefix in CIDR notation. -* `MAC` -- 'M:A:C', matches a 48-bit mac address -* `MAC_PREFIX` -- 'M:A:C/M', matches a 48-bit mac address with a mask -* `VARIABLE` -- Begins with a capital letter. Matches any input. -* `RANGE` -- Numeric range delimited by parentheses, e.g. (-100 - 100) or - (10-20). Will only match numbers in the range. - -Rules ------ -* `` -- Contain sequences of tokens separated by pipes and - provide mutual exclusion. Sequences may contain - `` but not as the first token. - Disallowed: `"example < c|d>"` - Allowed: `"example "` -* `[square brackets]` -- Contains sequences of tokens that are optional (can be - omitted). `[]` can be shortened to `[a|b]`. -* `{curly|braces}` -- similar to angle brackets, but instead of mutual - exclusion, curly braces indicate that one or more of the - pipe-separated sequences may be provided in any order. -* `VARIADICS...` -- Any token which accepts input (so anything except WORD) - and that occurs as the last token of a line may be - followed by an ellipsis, which indicates that input - matching the token may be repeated an unlimited number - of times. -* `$name` -- Specify a variable name for the preceding token. See - "Variable Names" below. - -Some general notes: - -* Options are allowed at the beginning of the command. The developer is - entreated to use these extremely sparingly. They are most useful for - implementing the 'no' form of configuration commands. Please think carefully - before using them for anything else. There is usually a better solution, even - if it is just separating out the command definition into separate ones. - -* The developer should judiciously apply separation of concerns when defining - CLI. CLI definitions for two unrelated or vaguely related commands or - configuration items should be defined in separate commands. Clarity is - preferred over LOC (within reason). - -* The maximum number of space-separated tokens that can be entered is presently - limited to 256. Please keep this limit in mind when implementing new CLI. - -Variable Names --------------- -The parser tries to fill the "varname" field on each token. This can happen -either manually or automatically. Manual specifications work by appending -`"$name"` after the input specifier: - -``` -foo bar$cmd WORD$name A.B.C.D$ip -``` - -Note that you can also assign variable names to fixed input tokens, this can -be useful if multiple commands share code. You can also use "$name" after a -multiple-choice option: - -``` -foo bar $addr [optionA|optionB]$mode -``` - -The variable name is in this case assigned to the last token in each of the -branches. - -Automatic assignment of variable names works by applying the following rules: - -- manual names always have priority -- a "[no]" at the beginning receives "no" as varname on the "no" token -- VARIABLE tokens whose text is not "WORD" or "NAME" receive a cleaned lowercase - version of the token text as varname, e.g. "ROUTE-MAP" becomes "route_map". -- other variable tokens (i.e. everything except "fixed") receive the text of - the preceding fixed token as varname, if one can be found. E.g.: - "ip route A.B.C.D/M INTERFACE" assigns "route" to the "A.B.C.D/M" token. - -These rules should make it possible to avoid manual varname assignment in 90% -of the cases. - -DEFPY ------ - -`DEFPY(...)` is an enhanced version of `DEFUN()` which is preprocessed by -` python/clidef.py`. The python script parses the command definition string, -extracts variable names and types, and generates a C wrapper function that -parses the variables and passes them on. This means that in the CLI function -body, you will receive additional parameters with appropriate types. - -This is best explained by an example: - -``` -DEFPY(func, func_cmd, "[no] foo bar A.B.C.D (0-99)$num", "...help...") - -=> - -func(self, vty, argc, argv, /* standard CLI arguments */ - - const char *no, /* unparsed "no" */ - struct in_addr bar, /* parsed IP address */ - const char *bar_str, /* unparsed IP address */ - long num, /* parsed num */ - const char *num_str) /* unparsed num */ -``` - -Note that as documented in the previous section, "bar" is automatically -applied as variable name for "A.B.C.D". The python code then detects this -is an IP address argument and generates code to parse it into a -`struct in_addr`, passing it in `bar`. The raw value is passed in `bar_str`. -The range/number argument works in the same way with the explicitly given -variable name. - -### Type rules - -| Token(s) | Type | Value if omitted by user | -|--------------------------|-------------|--------------------------| -| `A.B.C.D` | `struct in_addr` | 0.0.0.0 | -| `X:X::X:X` | `struct in6_addr` | :: | -| `A.B.C.D + X:X::X:X` | `const union sockunion *` | NULL | -| `A.B.C.D/M` | `const struct prefix_ipv4 *` | NULL | -| `X:X::X:X/M` | `const struct prefix_ipv6 *` | NULL | -| `A.B.C.D/M + X:X::X:X/M` | `const struct prefix *` | NULL | -| `(0-9)` | `long` | 0 | -| `VARIABLE` | `const char *` | NULL | -| `word` | `const char *` | NULL | -| _all other_ | `const char *` | NULL | - -Note the following details: - -* not all parameters are pointers, some are passed as values. -* when the type is not `const char *`, there will be an extra `_str` argument - with type `const char *`. -* you can give a variable name not only to `VARIABLE` tokens but also to - `word` tokens (e.g. constant words). This is useful if some parts of a - command are optional. The type will be `const char *`. -* `[no]` will be passed as `const char *no`. -* pointers will be NULL when the argument is optional and the user did not - use it. -* if a parameter is not a pointer, but is optional and the user didn't use it, - the default value will be passed. Check the `_str` argument if you need to - determine whether the parameter was omitted. -* if the definition contains multiple parameters with the same variable name, - they will be collapsed into a single function parameter. The python code - will detect if the types are compatible (i.e. IPv4 + IPv6 variantes) and - choose a corresponding C type. -* the standard DEFUN parameters (self, vty, argc, argv) are still present and - can be used. A DEFUN can simply be **edited into a DEFPY without further - changes and it will still work**; this allows easy forward migration. -* a file may contain both DEFUN and DEFPY statements. - -### Getting a parameter dump - -The clidef.py script can be called to get a list of DEFUNs/DEFPYs with -the parameter name/type list: - -``` -lib/clippy python/clidef.py --all-defun --show lib/plist.c > /dev/null -``` - -The generated code is printed to stdout, the info dump to stderr. The -`--all-defun` argument will make it process DEFUN blocks as well as DEFPYs, -which is useful prior to converting some DEFUNs. **The dump does not list -the `_str` arguments** to keep the output shorter. - -Note that the clidef.py script cannot be run with python directly, it needs -to be run with _clippy_ since the latter makes the CLI parser available. - -### Include & Makefile requirements - -A source file that uses DEFPY needs to include the `_clippy.c` file **before -all DEFPY statements**: - -``` -/* GPL header */ -#include ... - -... - -#include "daemon/filename_clippy.c" - -DEFPY(...) -DEFPY(...) - -install_element(...) -``` - -This dependency needs to be marked in Makefile.am: (there is no ordering -requirement) - -``` -include ../common.am - -# ... - -# if linked into a LTLIBRARY (.la/.so): -filename.lo: filename_clippy.c - -# if linked into an executable or static library (.a): -filename.o: filename_clippy.c -``` - -Doc Strings ------------ -Each token in a command definition should be documented with a brief doc -string that informs a user of the meaning and/or purpose of the subsequent -command tree. These strings are provided as the last parameter to DEFUN macros, -concatenated together and separated by an escaped newline ('\n'). These are -best explained by example. - -``` -DEFUN (config_terminal, - config_terminal_cmd, - "configure terminal", - "Configuration from vty interface\n" - "Configuration terminal\n") -``` - -The last parameter is split into two lines for readability. Two newline -delimited doc strings are present, one for each token in the command. The -second string documents the functionality of the 'terminal' command in the -'configure' tree. - -Note that the first string, for 'configure' does not contain documentation for -'terminal'. This is because the CLI is best envisioned as a tree, with tokens -defining branches. An imaginary 'start' token is the root of every command in a -CLI node. Each subsequent written token descends into a subtree, so the -documentation for that token ideally summarizes all the functionality contained -in the subtree. - -A consequence of this structure is that the developer must be careful to use -the same doc strings when defining multiple commands that are part of the same -tree. Commands which share prefixes must share the same doc strings for those -prefixes. On startup the parser will generate warnings if it notices -inconsistent doc strings. Behavior is undefined; the same token may show up -twice in completions, with different doc strings, or it may show up once with a -random doc string. Parser warnings should be heeded and fixed to avoid -confusing users. - -The number of doc strings provided must be equal to the amount of tokens -present in the command definition, read left to right, ignoring any special -constructs. - -In the examples below, each arrowed token needs a doc string. - -``` - "show ip bgp" - ^ ^ ^ - - "command [example]" - ^ ^ ^ ^ -``` - -Data Structures ---------------- -On startup, the CLI parser sequentially parses each command string definition -and constructs a directed graph with each token forming a node. This graph is -the basis of the entire CLI system. It is used to match user input in order to -generate command completions and match commands to functions. - -There is one graph per CLI node (not the same as a graph node in the CLI -graph). The CLI node struct keeps a reference to its graph (see lib/command.h). - -While most of the graph maintains the form of a tree, special constructs -outlined in the Rules section introduce some quirks. <>, [] and {} form -self-contained 'subgraphs'. Each subgraph is a tree except that all of the -'leaves' actually share a child node. This helps with minimizing graph size and -debugging. - -As an example, the subgraph generated by looks like this: - - . - . - | - +----+---+ - +--- -+ FORK +----+ - | +--------+ | - +--v---+ +--v---+ - | foo | | bar | - +--+---+ +--+---+ - | +------+ | - +------> JOIN <-----+ - +---+--+ - | - . - . - -FORK and JOIN nodes are plumbing nodes that don't correspond to user input. -They're necessary in order to deduplicate these constructs where applicable. - -Options follow the same form, except that there is an edge from the FORK node -to the JOIN node. - -Keywords follow the same form, except that there is an edge from JOIN to FORK. -Because of this the CLI graph cannot be called acyclic. There is special logic -in the input matching code that keeps a stack of paths already taken through -the node in order to disallow following the same path more than once. - -Variadics are a bit special; they have an edge back to themselves, which allows -repeating the same input indefinitely. - -The leaves of the graph are nodes that have no out edges. These nodes are -special; their data section does not contain a token, as most nodes do, or -NULL, as in FORK/JOIN nodes, but instead has a pointer to a cmd_element. All -paths through the graph that terminate on a leaf are guaranteed to be defined -by that command. When a user enters a complete command, the command matcher -tokenizes the input and executes a DFS on the CLI graph. If it is -simultaneously able to exhaust all input (one input token per graph node), and -then find exactly one leaf connected to the last node it reaches, then the -input has matched the corresponding command and the command is executed. If it -finds more than one node, then the command is ambiguous (more on this in -deduplication). If it cannot exhaust all input, the command is unknown. If it -exhausts all input but does not find an edge node, the command is incomplete. - -The parser uses an incremental strategy to build the CLI graph for a node. Each -command is parsed into its own graph, and then this graph is merged into the -overall graph. During this merge step, the parser makes a best-effort attempt -to remove duplicate nodes. If it finds a node in the overall graph that is -equal to a node in the corresponding position in the command graph, it will -intelligently merge the properties from the node in the command graph into the -already-existing node. Subgraphs are also checked for isomorphism and merged -where possible. The definition of whether two nodes are 'equal' is based on the -equality of some set of token properties; read the parser source for the most -up-to-date definition of equality. - -When the parser is unable to deduplicate some complicated constructs, this -can result in two identical paths through separate parts of the graph. If -this occurs and the user enters input that matches these paths, they will -receive an 'ambiguous command' error and will be unable to execute the command. -Most of the time the parser can detect and warn about duplicate commands, but -it will not always be able to do this. Hence care should be taken before -defining a new command to ensure it is not defined elsewhere. - - -Command handlers ----------------- -The block that follows a CLI definition is executed when a user enters input -that matches the definition. Its function signature looks like this: - -int (*func) (const struct cmd_element *, struct vty *, int, struct cmd_token *[]); - -The first argument is the command definition struct. The last argument is an -ordered array of tokens that correspond to the path taken through the graph, -and the argument just prior to that is the length of the array. - -The arrangement of the token array has changed from the prior incarnation of -the CLI system. In the old system, missing arguments were padded with NULLs so -that the same parts of a command would show up at the same indices regardless -of what was entered. The new system does not perform such padding and therefore -it is generally _incorrect_ to assume consistent indices in this array. As a -simple example: - -Command definition: -``` - command [foo] -``` - -User enters: -``` - command foo bar -``` - -Array: -``` - [0] -> command - [1] -> foo - [2] -> bar -``` - -User enters: -``` - command baz -``` - -Array: -``` - [0] -> command - [1] -> baz -``` - - - -Command abbreviation & matching priority ----------------------------------------- -As in the prior implementation, it is possible for users to elide parts of -tokens when the CLI matcher does not need them to make an unambiguous match. -This is best explained by example. - -Command definitions: -``` - command dog cow - command dog crow -``` - -User input: -``` - c d c -> ambiguous command - c d co -> match "command dog cow" -``` - -In the new implementation, this functionality has improved. Where previously -the parser would stop at the first ambiguous token, it will now look ahead and -attempt to disambiguate based on tokens later on in the input string. - -Command definitions: -``` - show ip bgp A.B.C.D - show ipv6 bgp X:X::X:X -``` - -User enters: -``` - s i b 4.3.2.1 -> match "show ip bgp A.B.C.D" - s i b ::e0 -> match "show ipv6 bgp X:X::X:X" -``` - -Previously both of these commands would be ambiguous since 'i' does not -explicitly select either 'ip' or 'ipv6'. However, since the user later provides -a token that matches only one of the commands (an IPv4 or IPv6 address) the -parser is able to look ahead and select the appropriate command. This has some -implications for parsing the argv*[] that is passed to the command handler. - -Now consider a command definition such as: -``` - command -``` - -'foo' only matches the string 'foo', but 'VAR' matches any input, including -'foo'. Who wins? In situations like this the matcher will always choose the -'better' match, so 'foo' will win. - -Consider also: -``` - show foo -``` - -User input: -``` - show ip foo -``` - -'ip' partially matches 'ipv6' but exactly matches 'ip', so 'ip' will win. - - -struct cmd_token ----------------- - -``` -/* Command token struct. */ -struct cmd_token -{ - enum cmd_token_type type; // token type - u_char attr; // token attributes - bool allowrepeat; // matcher allowed to match token repetitively? - - char *text; // token text - char *desc; // token description - long long min, max; // for ranges - char *arg; // user input that matches this token - char *varname; // variable name -}; -``` - -This struct is used in the CLI graph to match input against. It is also used to -pass user input to command handler functions, as it is frequently useful for -handlers to have access to that information. When a command is matched, the -sequence of cmd_tokens that form the matching path are duplicated and placed in -order into argv*[]. Before this happens the ->arg field is set to point at the -snippet of user input that matched it. - -For most nontrivial commands the handler function will need to determine which -of the possible matching inputs was entered. Previously this was done by -looking at the first few characters of input. This is now considered an -anti-pattern and should be avoided. Instead, the ->type or ->text fields for -this logic. The ->type field can be used when the possible inputs differ in -type. When the possible types are the same, use the ->text field. This field -has the full text of the corresponding token in the definition string and using -it makes for much more readable code. An example is helpful. - -Command definition: -``` - command <(1-10)|foo|BAR> -``` - -In this example, the user may enter any one of: - * an integer between 1 and 10 - * "foo" - * anything at all - -If the user enters "command f", then: - -``` -argv[1]->type == WORD_TKN -argv[1]->arg == "f" -argv[1]->text == "foo" -``` - -Range tokens have some special treatment; a token with ->type == RANGE_TKN will -have the ->min and ->max fields set to the bounding values of the range. - - -Permutations ------------- -Finally, it is sometimes useful to check all the possible combinations of input -that would match an arbitrary definition string. There is a tool in tools/ -called 'permutations' that reads CLI definition strings on stdin and prints out -all matching input permutations. It also dumps a text representation of the -graph, which is more useful for debugging than anything else. It looks like -this: - -``` -$ ./permutations "show [ip] bgp [ WORD]" - -show ip bgp view WORD -show ip bgp vrf WORD -show ip bgp -show bgp view WORD -show bgp vrf WORD -show bgp -``` - -This functionality is also built into VTY/VTYSH; the 'list permutations' -command will list all possible matching input permutations in the current CLI -node. diff --git a/doc/code/.gitignore b/doc/code/.gitignore deleted file mode 100644 index 0505537159..0000000000 --- a/doc/code/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/_templates -/_build -!/Makefile diff --git a/doc/code/Makefile b/doc/code/Makefile deleted file mode 100644 index 056b78e68e..0000000000 --- a/doc/code/Makefile +++ /dev/null @@ -1,216 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = _build - -# User-friendly check for sphinx-build -ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) -$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) -endif - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . -# the i18n builder cannot share the environment and doctrees with the others -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . - -.PHONY: help -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " applehelp to make an Apple Help Book" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " texinfo to make Texinfo files" - @echo " info to make Texinfo files and run them through makeinfo" - @echo " gettext to make PO message catalogs" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " xml to make Docutils-native XML files" - @echo " pseudoxml to make pseudoxml-XML files for display purposes" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - @echo " coverage to run coverage check of the documentation (if enabled)" - -.PHONY: clean -clean: - rm -rf $(BUILDDIR)/* - -.PHONY: html -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -.PHONY: dirhtml -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -.PHONY: singlehtml -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -.PHONY: pickle -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -.PHONY: json -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -.PHONY: htmlhelp -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -.PHONY: qthelp -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/FRR.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/FRR.qhc" - -.PHONY: applehelp -applehelp: - $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp - @echo - @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." - @echo "N.B. You won't be able to view it unless you put it in" \ - "~/Library/Documentation/Help or install it in your application" \ - "bundle." - -.PHONY: devhelp -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/FRR" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/FRR" - @echo "# devhelp" - -.PHONY: epub -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -.PHONY: latex -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -.PHONY: latexpdf -latexpdf: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -.PHONY: latexpdfja -latexpdfja: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through platex and dvipdfmx..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -.PHONY: text -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -.PHONY: man -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -.PHONY: texinfo -texinfo: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo - @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." - @echo "Run \`make' in that directory to run these through makeinfo" \ - "(use \`make info' here to do that automatically)." - -.PHONY: info -info: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo "Running Texinfo files through makeinfo..." - make -C $(BUILDDIR)/texinfo info - @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." - -.PHONY: gettext -gettext: - $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale - @echo - @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." - -.PHONY: changes -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -.PHONY: linkcheck -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -.PHONY: doctest -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." - -.PHONY: coverage -coverage: - $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage - @echo "Testing of coverage in the sources finished, look at the " \ - "results in $(BUILDDIR)/coverage/python.txt." - -.PHONY: xml -xml: - $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml - @echo - @echo "Build finished. The XML files are in $(BUILDDIR)/xml." - -.PHONY: pseudoxml -pseudoxml: - $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml - @echo - @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." diff --git a/doc/Building_FRR_on_CentOS6.md b/doc/developer/Building_FRR_on_CentOS6.rst similarity index 65% rename from doc/Building_FRR_on_CentOS6.md rename to doc/developer/Building_FRR_on_CentOS6.rst index 10830e5016..e93ae603ef 100644 --- a/doc/Building_FRR_on_CentOS6.md +++ b/doc/developer/Building_FRR_on_CentOS6.rst @@ -1,46 +1,53 @@ -Building FRR on CentOS 6 from Git Source +CentOS 6 ======================================== (As an alternative to this installation, you may prefer to create a FRR -rpm package yourself and install that package instead. See instructions -in redhat/README.rpm_build.md on how to build a rpm package) +rpm package yourself and install that package instead. See instructions +in redhat/README.rpm\_build.md on how to build a rpm package) -Instructions are tested with `CentOS 6.8` on `x86_64` platform +Instructions are tested with ``CentOS 6.8`` on ``x86_64`` platform CentOS 6 restrictions: ---------------------- -- PIMd is not supported on `CentOS 6`. Upgrade to `CentOS 7` if PIMd is - needed -- MPLS is not supported on `CentOS 6`. MPLS requires Linux Kernel 4.5 or - higher (LDP can be built, but may have limited use without MPLS) -- Zebra is unable to detect what bridge/vrf an interface is associcated - with (IFLA_INFO_SLAVE_KIND does not exist in the kernel headers, you - can use a newer kernel + headers to get this functionality) -- frr_reload.py will not work, as this requires Python 2.7, and CentOS 6 - only has 2.6. You can install Python 2.7 via IUS, but it won't work - properly unless you compile and install the ipaddr package for it. +- PIMd is not supported on ``CentOS 6``. Upgrade to ``CentOS 7`` if + PIMd is needed +- MPLS is not supported on ``CentOS 6``. MPLS requires Linux Kernel 4.5 + or higher (LDP can be built, but may have limited use without MPLS) +- Zebra is unable to detect what bridge/vrf an interface is associcated + with (IFLA\_INFO\_SLAVE\_KIND does not exist in the kernel headers, + you can use a newer kernel + headers to get this functionality) +- frr\_reload.py will not work, as this requires Python 2.7, and CentOS + 6 only has 2.6. You can install Python 2.7 via IUS, but it won't work + properly unless you compile and install the ipaddr package for it. Install required packages ------------------------- Add packages: +:: + sudo yum install git autoconf automake libtool make gawk \ readline-devel texinfo net-snmp-devel groff pkgconfig \ json-c-devel pam-devel flex epel-release perl-XML-LibXML \ c-ares-devel -Install newer version of bison (CentOS 6 package source is too old) from +Install newer version of bison (CentOS 6 package source is too old) from CentOS 7 +:: + sudo yum install rpm-build curl -O http://vault.centos.org/7.0.1406/os/Source/SPackages/bison-2.7-4.el7.src.rpm rpmbuild --rebuild ./bison-2.7-4.el7.src.rpm sudo yum install ./rpmbuild/RPMS/x86_64/bison-2.7-4.el6.x86_64.rpm rm -rf rpmbuild -Install newer version of autoconf and automake (Package versions are too old) +Install newer version of autoconf and automake (Package versions are too +old) + +:: curl -O http://ftp.gnu.org/gnu/autoconf/autoconf-2.69.tar.gz tar xvf autoconf-2.69.tar.gz @@ -49,7 +56,7 @@ Install newer version of autoconf and automake (Package versions are too old) make sudo make install cd .. - + curl -O http://ftp.gnu.org/gnu/automake/automake-1.15.tar.gz tar xvf automake-1.15.tar.gz cd automake-1.15 @@ -58,35 +65,45 @@ Install newer version of autoconf and automake (Package versions are too old) sudo make install cd .. -Install `Python 2.7` in parallel to default 2.6. -Make sure you've install EPEL (`epel-release` as above). Then install current -`python27`, `python27-devel` and `pytest` +Install ``Python 2.7`` in parallel to default 2.6. Make sure you've +install EPEL (``epel-release`` as above). Then install current +``python27``, ``python27-devel`` and ``pytest`` + +:: sudo rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm sudo rpm -ivh https://centos6.iuscommunity.org/ius-release.rpm sudo yum install python27 python27-pip python27-devel sudo pip2.7 install pytest -Please note that `CentOS 6` needs to keep python pointing to version 2.6 -for `yum` to keep working, so don't create a symlink for python2.7 to python +Please note that ``CentOS 6`` needs to keep python pointing to version +2.6 for ``yum`` to keep working, so don't create a symlink for python2.7 +to python Get FRR, compile it and install it (from Git) --------------------------------------------- -**This assumes you want to build and install FRR from source and not using -any packages** +**This assumes you want to build and install FRR from source and not +using any packages** -### Add frr groups and user +Add frr groups and user +~~~~~~~~~~~~~~~~~~~~~~~ + +:: sudo groupadd -g 92 frr sudo groupadd -r -g 85 frrvt sudo useradd -u 92 -g 92 -M -r -G frrvt -s /sbin/nologin \ -c "FRR FRRouting suite" -d /var/run/frr frr -### Download Source, configure and compile it -(You may prefer different options on configure statement. These are just +Download Source, configure and compile it +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +(You may prefer different options on configure statement. These are just an example.) +:: + git clone https://github.com/frrouting/frr.git frr cd frr ./bootstrap.sh @@ -120,7 +137,11 @@ an example.) make check PYTHON=/usr/bin/python2.7 sudo make install -### Create empty FRR configuration files +Create empty FRR configuration files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + sudo mkdir /var/log/frr sudo mkdir /etc/frr sudo touch /etc/frr/zebra.conf @@ -138,20 +159,28 @@ an example.) sudo chown frr:frrvt /etc/frr/vtysh.conf sudo chmod 640 /etc/frr/*.conf -### Install daemon config file +Install daemon config file +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + sudo install -p -m 644 redhat/daemons /etc/frr/ sudo chown frr:frr /etc/frr/daemons -### Edit /etc/frr/daemons as needed to select the required daemons +Edit /etc/frr/daemons as needed to select the required daemons +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Look for the section with `watchfrr_enable=...` and `zebra=...` etc. -Enable the daemons as required by changing the value to `yes` +Look for the section with ``watchfrr_enable=...`` and ``zebra=...`` etc. +Enable the daemons as required by changing the value to ``yes`` -### Enable IP & IPv6 forwarding +Enable IP & IPv6 forwarding +~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Edit `/etc/sysctl.conf` and set the following values (ignore the other +Edit ``/etc/sysctl.conf`` and set the following values (ignore the other settings) +:: + # Controls IP packet forwarding net.ipv4.ip_forward = 1 net.ipv6.conf.all.forwarding=1 @@ -161,14 +190,28 @@ settings) Load the modifed sysctl's on the system: +:: + sudo sysctl -p /etc/sysctl.d/90-routing-sysctl.conf -### Add init.d startup files +Add init.d startup files +~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + sudo install -p -m 755 redhat/frr.init /etc/init.d/frr sudo chkconfig --add frr -### Enable frr daemon at startup +Enable frr daemon at startup +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + sudo chkconfig frr on -### Start FRR manually (or reboot) +Start FRR manually (or reboot) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + sudo /etc/init.d/frr start diff --git a/doc/Building_FRR_on_CentOS7.md b/doc/developer/Building_FRR_on_CentOS7.rst similarity index 71% rename from doc/Building_FRR_on_CentOS7.md rename to doc/developer/Building_FRR_on_CentOS7.rst index 787b80fbf7..60c4266894 100644 --- a/doc/Building_FRR_on_CentOS7.md +++ b/doc/developer/Building_FRR_on_CentOS7.rst @@ -1,22 +1,24 @@ -Building FRR on CentOS 7 from Git Source +CentOS 7 ======================================== (As an alternative to this installation, you may prefer to create a FRR rpm package yourself and install that package instead. See instructions -in redhat/README.rpm_build.md on how to build a rpm package) +in redhat/README.rpm\_build.md on how to build a rpm package) CentOS 7 restrictions: ---------------------- -- MPLS is not supported on `CentOS 7` with default kernel. MPLS requires - Linux Kernel 4.5 or higher (LDP can be built, but may have limited use - without MPLS) - +- MPLS is not supported on ``CentOS 7`` with default kernel. MPLS + requires Linux Kernel 4.5 or higher (LDP can be built, but may have + limited use without MPLS) + Install required packages ------------------------- Add packages: +:: + sudo yum install git autoconf automake libtool make gawk \ readline-devel texinfo net-snmp-devel groff pkgconfig \ json-c-devel pam-devel bison flex pytest c-ares-devel \ @@ -25,20 +27,27 @@ Add packages: Get FRR, compile it and install it (from Git) --------------------------------------------- -**This assumes you want to build and install FRR from source and not using -any packages** +**This assumes you want to build and install FRR from source and not +using any packages** + +Add frr groups and user +~~~~~~~~~~~~~~~~~~~~~~~ -### Add frr groups and user +:: sudo groupadd -g 92 frr sudo groupadd -r -g 85 frrvt sudo useradd -u 92 -g 92 -M -r -G frrvt -s /sbin/nologin \ -c "FRR FRRouting suite" -d /var/run/frr frr -### Download Source, configure and compile it -(You may prefer different options on configure statement. These are just +Download Source, configure and compile it +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +(You may prefer different options on configure statement. These are just an example.) +:: + git clone https://github.com/frrouting/frr.git frr cd frr ./bootstrap.sh @@ -72,7 +81,11 @@ an example.) make check sudo make install -### Create empty FRR configuration files +Create empty FRR configuration files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + sudo mkdir /var/log/frr sudo mkdir /etc/frr sudo touch /etc/frr/zebra.conf @@ -91,20 +104,28 @@ an example.) sudo chown frr:frrvt /etc/frr/vtysh.conf sudo chmod 640 /etc/frr/*.conf -### Install daemon config file +Install daemon config file +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + sudo install -p -m 644 redhat/daemons /etc/frr/ sudo chown frr:frr /etc/frr/daemons -### Edit /etc/frr/daemons as needed to select the required daemons +Edit /etc/frr/daemons as needed to select the required daemons +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Look for the section with `watchfrr_enable=...` and `zebra=...` etc. -Enable the daemons as required by changing the value to `yes` +Look for the section with ``watchfrr_enable=...`` and ``zebra=...`` etc. +Enable the daemons as required by changing the value to ``yes`` -### Enable IP & IPv6 forwarding +Enable IP & IPv6 forwarding +~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Create a new file `/etc/sysctl.d/90-routing-sysctl.conf` with the +Create a new file ``/etc/sysctl.d/90-routing-sysctl.conf`` with the following content: +:: + # Sysctl for routing # # Routing: We need to forward packets @@ -113,17 +134,35 @@ following content: Load the modifed sysctl's on the system: +:: + sudo sysctl -p /etc/sysctl.d/90-routing-sysctl.conf -### Install frr Service and redhat init files +Install frr Service and redhat init files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + sudo install -p -m 644 redhat/frr.service /usr/lib/systemd/system/frr.service sudo install -p -m 755 redhat/frr.init /usr/lib/frr/frr -### Register the systemd files +Register the systemd files +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + sudo systemctl preset frr.service - -### Enable required frr at startup + +Enable required frr at startup +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + sudo systemctl enable frr -### Reboot or start FRR manually +Reboot or start FRR manually +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + sudo systemctl start frr diff --git a/doc/Building_FRR_on_Debian8.md b/doc/developer/Building_FRR_on_Debian8.rst similarity index 74% rename from doc/Building_FRR_on_Debian8.md rename to doc/developer/Building_FRR_on_Debian8.rst index a2dbbdb30f..af24539cb6 100644 --- a/doc/Building_FRR_on_Debian8.md +++ b/doc/developer/Building_FRR_on_Debian8.rst @@ -1,33 +1,40 @@ -Building FRR on Debian 8 from Git Source +Debian 8 ======================================== Debian 8 restrictions: ---------------------- -- MPLS is not supported on `Debian 8` with default kernel. MPLS requires - Linux Kernel 4.5 or higher (LDP can be built, but may have limited use - without MPLS) +- MPLS is not supported on ``Debian 8`` with default kernel. MPLS + requires Linux Kernel 4.5 or higher (LDP can be built, but may have + limited use without MPLS) Install required packages ------------------------- Add packages: +:: + sudo apt-get install git autoconf automake libtool make gawk \ libreadline-dev texinfo libjson-c-dev pkg-config bison flex \ python-pip libc-ares-dev python3-dev -Install newer pytest (>3.0) from pip +Install newer pytest (>3.0) from pip + +:: sudo pip install pytest Get FRR, compile it and install it (from Git) --------------------------------------------- -**This assumes you want to build and install FRR from source and not using -any packages** +**This assumes you want to build and install FRR from source and not +using any packages** + +Add frr groups and user +~~~~~~~~~~~~~~~~~~~~~~~ -### Add frr groups and user +:: sudo addgroup --system --gid 92 frr sudo addgroup --system --gid 85 frrvty @@ -35,10 +42,14 @@ any packages** --gecos "FRR suite" --shell /bin/false frr sudo usermod -a -G frrvty frr -### Download Source, configure and compile it +Download Source, configure and compile it +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + (You may prefer different options on configure statement. These are just an example.) +:: + git clone https://github.com/frrouting/frr.git frr cd frr ./bootstrap.sh @@ -68,7 +79,10 @@ an example.) make check sudo make install -### Create empty FRR configuration files +Create empty FRR configuration files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: sudo install -m 755 -o frr -g frr -d /var/log/frr sudo install -m 775 -o frr -g frrvty -d /etc/frr @@ -84,11 +98,14 @@ an example.) sudo install -m 640 -o frr -g frr /dev/null /etc/frr/nhrpd.conf sudo install -m 640 -o frr -g frrvty /dev/null /etc/frr/vtysh.conf -### Enable IP & IPv6 forwarding +Enable IP & IPv6 forwarding +~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Edit `/etc/sysctl.conf` and uncomment the following values (ignore the +Edit ``/etc/sysctl.conf`` and uncomment the following values (ignore the other settings) +:: + # Uncomment the next line to enable packet forwarding for IPv4 net.ipv4.ip_forward=1 @@ -97,35 +114,43 @@ other settings) # based on Router Advertisements for this host net.ipv6.conf.all.forwarding=1 -**Reboot** or use `sysctl -p` to apply the same config to the running system +**Reboot** or use ``sysctl -p`` to apply the same config to the running +system -### Troubleshooting +Troubleshooting +~~~~~~~~~~~~~~~ **Local state directory** -The local state directory must exist and have the correct permissions applied -for the frrouting daemons to start. In the above ./configure example the -local state directory is set to /var/run/frr (--localstatedir=/var/run/frr) -Debian considers /var/run/frr to be temporary and this is removed after a -reboot. +The local state directory must exist and have the correct permissions +applied for the frrouting daemons to start. In the above ./configure +example the local state directory is set to /var/run/frr +(--localstatedir=/var/run/frr) Debian considers /var/run/frr to be +temporary and this is removed after a reboot. When using a different local state directory you need to create the new directory and change the ownership to the frr user, for example: +:: + mkdir /var/opt/frr chown frr /var/opt/frr **Shared library error** -If you try and start any of the frrouting daemons you may see the below error -due to the frrouting shared library directory not being found: +If you try and start any of the frrouting daemons you may see the below +error due to the frrouting shared library directory not being found: + +:: ./zebra: error while loading shared libraries: libfrr.so.0: cannot open shared object file: No such file or directory -The fix is to add the following line to /etc/ld.so.conf which will continue to -reference the library directory after the system reboots. To load the library -directory path immediately run the ldconfig command after adding the line to -the file eg: +The fix is to add the following line to /etc/ld.so.conf which will +continue to reference the library directory after the system reboots. To +load the library directory path immediately run the ldconfig command +after adding the line to the file eg: + +:: echo include /usr/local/lib >> /etc/ld.so.conf ldconfig diff --git a/doc/Building_FRR_on_Debian9.md b/doc/developer/Building_FRR_on_Debian9.rst similarity index 77% rename from doc/Building_FRR_on_Debian9.md rename to doc/developer/Building_FRR_on_Debian9.rst index 1536c25932..a3e3d7ff97 100644 --- a/doc/Building_FRR_on_Debian9.md +++ b/doc/developer/Building_FRR_on_Debian9.rst @@ -1,4 +1,4 @@ -Building FRR on Debian 9 from Git Source +Debian 9 ======================================== Install required packages @@ -6,6 +6,8 @@ Install required packages Add packages: +:: + sudo apt-get install git autoconf automake libtool make \ libreadline-dev texinfo libjson-c-dev pkg-config bison flex \ python-pip libc-ares-dev python3-dev python-pytest @@ -13,10 +15,13 @@ Add packages: Get FRR, compile it and install it (from Git) --------------------------------------------- -**This assumes you want to build and install FRR from source and not using -any packages** +**This assumes you want to build and install FRR from source and not +using any packages** + +Add frr groups and user +~~~~~~~~~~~~~~~~~~~~~~~ -### Add frr groups and user +:: sudo addgroup --system --gid 92 frr sudo addgroup --system --gid 85 frrvty @@ -24,10 +29,14 @@ any packages** --gecos "FRR suite" --shell /bin/false frr sudo usermod -a -G frrvty frr -### Download Source, configure and compile it +Download Source, configure and compile it +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + (You may prefer different options on configure statement. These are just an example.) +:: + git clone https://github.com/frrouting/frr.git frr cd frr git checkout stable/3.0 @@ -58,7 +67,10 @@ an example.) make check sudo make install -### Create empty FRR configuration files +Create empty FRR configuration files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: sudo install -m 755 -o frr -g frr -d /var/log/frr sudo install -m 775 -o frr -g frrvty -d /etc/frr @@ -74,11 +86,14 @@ an example.) sudo install -m 640 -o frr -g frr /dev/null /etc/frr/nhrpd.conf sudo install -m 640 -o frr -g frrvty /dev/null /etc/frr/vtysh.conf -### Enable IP & IPv6 forwarding +Enable IP & IPv6 forwarding +~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Edit `/etc/sysctl.conf` and uncomment the following values (ignore the +Edit ``/etc/sysctl.conf`` and uncomment the following values (ignore the other settings) +:: + # Uncomment the next line to enable packet forwarding for IPv4 net.ipv4.ip_forward=1 @@ -87,35 +102,43 @@ other settings) # based on Router Advertisements for this host net.ipv6.conf.all.forwarding=1 -**Reboot** or use `sysctl -p` to apply the same config to the running system +**Reboot** or use ``sysctl -p`` to apply the same config to the running +system -### Troubleshooting +Troubleshooting +~~~~~~~~~~~~~~~ **Local state directory** -The local state directory must exist and have the correct permissions applied -for the frrouting daemons to start. In the above ./configure example the -local state directory is set to /var/run/frr (--localstatedir=/var/run/frr) -Debian considers /var/run/frr to be temporary and this is removed after a -reboot. +The local state directory must exist and have the correct permissions +applied for the frrouting daemons to start. In the above ./configure +example the local state directory is set to /var/run/frr +(--localstatedir=/var/run/frr) Debian considers /var/run/frr to be +temporary and this is removed after a reboot. When using a different local state directory you need to create the new directory and change the ownership to the frr user, for example: +:: + mkdir /var/opt/frr chown frr /var/opt/frr **Shared library error** -If you try and start any of the frrouting daemons you may see the below error -due to the frrouting shared library directory not being found: +If you try and start any of the frrouting daemons you may see the below +error due to the frrouting shared library directory not being found: + +:: ./zebra: error while loading shared libraries: libfrr.so.0: cannot open shared object file: No such file or directory -The fix is to add the following line to /etc/ld.so.conf which will continue to -reference the library directory after the system reboots. To load the library -directory path immediately run the ldconfig command after adding the line to -the file eg: +The fix is to add the following line to /etc/ld.so.conf which will +continue to reference the library directory after the system reboots. To +load the library directory path immediately run the ldconfig command +after adding the line to the file eg: + +:: echo include /usr/local/lib >> /etc/ld.so.conf ldconfig diff --git a/doc/Building_FRR_on_Fedora24.md b/doc/developer/Building_FRR_on_Fedora24.rst similarity index 73% rename from doc/Building_FRR_on_Fedora24.md rename to doc/developer/Building_FRR_on_Fedora24.rst index 0070fd1534..5ba4dd0e5f 100644 --- a/doc/Building_FRR_on_Fedora24.md +++ b/doc/developer/Building_FRR_on_Fedora24.rst @@ -1,15 +1,17 @@ -Building FRR on Fedora 24 from Git Source +Fedora 24 ========================================= (As an alternative to this installation, you may prefer to create a FRR rpm package yourself and install that package instead. See instructions -in redhat/README.rpm_build.md on how to build a rpm package) +in redhat/README.rpm\_build.md on how to build a rpm package) Install required packages ------------------------- Add packages: +:: + sudo dnf install git autoconf automake libtool make gawk \ readline-devel texinfo net-snmp-devel groff pkgconfig \ json-c-devel pam-devel perl-XML-LibXML pytest bison flex \ @@ -18,20 +20,27 @@ Add packages: Get FRR, compile it and install it (from Git) --------------------------------------------- -**This assumes you want to build and install FRR from source and not +**This assumes you want to build and install FRR from source and not using any packages** -### Add frr groups and user +Add frr groups and user +~~~~~~~~~~~~~~~~~~~~~~~ + +:: sudo groupadd -g 92 frr sudo groupadd -r -g 85 frrvt sudo useradd -u 92 -g 92 -M -r -G frrvt -s /sbin/nologin \ -c "FRR FRRouting suite" -d /var/run/frr frr -### Download Source, configure and compile it -(You may prefer different options on configure statement. These are just +Download Source, configure and compile it +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +(You may prefer different options on configure statement. These are just an example.) +:: + git clone https://github.com/frrouting/frr.git frr cd frr ./bootstrap.sh @@ -65,7 +74,11 @@ an example.) make check sudo make install -### Create empty FRR configuration files +Create empty FRR configuration files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + sudo mkdir /var/log/frr sudo mkdir /etc/frr sudo touch /etc/frr/zebra.conf @@ -85,21 +98,28 @@ an example.) sudo chown frr:frrvt /etc/frr/vtysh.conf sudo chmod 640 /etc/frr/*.conf -### Install daemon config file +Install daemon config file +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + sudo install -p -m 644 redhat/daemons /etc/frr/ sudo chown frr:frr /etc/frr/daemons -### Edit /etc/frr/daemons as needed to select the required daemons +Edit /etc/frr/daemons as needed to select the required daemons +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Look for the section with `watchfrr_enable=...` and `zebra=...` etc. -Enable the daemons as required by changing the value to `yes` +Look for the section with ``watchfrr_enable=...`` and ``zebra=...`` etc. +Enable the daemons as required by changing the value to ``yes`` -### Enable IP & IPv6 forwarding (and MPLS) +Enable IP & IPv6 forwarding (and MPLS) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Create a new file `/etc/sysctl.d/90-routing-sysctl.conf` with the -following content: -(Please make sure to list all interfaces with required MPLS similar -to `net.mpls.conf.eth0.input=1`) +Create a new file ``/etc/sysctl.d/90-routing-sysctl.conf`` with the +following content: (Please make sure to list all interfaces with +required MPLS similar to ``net.mpls.conf.eth0.input=1``) + +:: # Sysctl for routing # @@ -115,9 +135,14 @@ to `net.mpls.conf.eth0.input=1`) Load the modifed sysctl's on the system: +:: + sudo sysctl -p /etc/sysctl.d/90-routing-sysctl.conf -Create a new file `/etc/modules-load.d/mpls.conf` with the following content: +Create a new file ``/etc/modules-load.d/mpls.conf`` with the following +content: + +:: # Load MPLS Kernel Modules mpls-router @@ -125,14 +150,28 @@ Create a new file `/etc/modules-load.d/mpls.conf` with the following content: And load the kernel modules on the running system: +:: + sudo modprobe mpls-router mpls-iptunnel -### Install frr Service and redhat init files +Install frr Service and redhat init files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + sudo install -p -m 644 redhat/frr.service /usr/lib/systemd/system/frr.service sudo install -p -m 755 redhat/frr.init /usr/lib/frr/frr - -### Enable required frr at startup + +Enable required frr at startup +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + sudo systemctl enable frr -### Reboot or start FRR manually +Reboot or start FRR manually +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + sudo systemctl start frr diff --git a/doc/Building_FRR_on_FreeBSD10.md b/doc/developer/Building_FRR_on_FreeBSD10.rst similarity index 75% rename from doc/Building_FRR_on_FreeBSD10.md rename to doc/developer/Building_FRR_on_FreeBSD10.rst index ccae83a667..94f2f27282 100644 --- a/doc/Building_FRR_on_FreeBSD10.md +++ b/doc/developer/Building_FRR_on_FreeBSD10.rst @@ -1,46 +1,53 @@ -Building FRR on FreeBSD 10 from Git Source +FreeBSD 10 ========================================== FreeBSD 10 restrictions: ------------------------ -- MPLS is not supported on `FreeBSD`. MPLS requires a Linux Kernel - (4.5 or higher). LDP can be built, but may have limited use - without MPLS +- MPLS is not supported on ``FreeBSD``. MPLS requires a Linux Kernel + (4.5 or higher). LDP can be built, but may have limited use without + MPLS Install required packages ------------------------- -Add packages: -(Allow the install of the package managment tool if this is first package -install and asked) +Add packages: (Allow the install of the package managment tool if this +is first package install and asked) + +:: pkg install git autoconf automake libtool gmake gawk json-c pkgconf \ bison flex py27-pytest c-ares python3 -Make sure there is no /usr/bin/flex preinstalled (and use the newly -installed in /usr/local/bin): -(FreeBSD frequently provides a older flex as part of the base OS which -takes preference in path) +Make sure there is no /usr/bin/flex preinstalled (and use the newly +installed in /usr/local/bin): (FreeBSD frequently provides a older flex +as part of the base OS which takes preference in path) + +:: rm -f /usr/bin/flex Get FRR, compile it and install it (from Git) --------------------------------------------- -**This assumes you want to build and install FRR from source and not +**This assumes you want to build and install FRR from source and not using any packages** -### Add frr group and user +Add frr group and user +~~~~~~~~~~~~~~~~~~~~~~ + +:: pw groupadd frr -g 101 pw groupadd frrvty -g 102 pw adduser frr -g 101 -u 101 -G 102 -c "FRR suite" \ -d /usr/local/etc/frr -s /usr/sbin/nologin -(You may prefer different options on configure statement. These are just +(You may prefer different options on configure statement. These are just an example) +:: + git clone https://github.com/frrouting/frr.git frr cd frr ./bootstrap.sh @@ -68,7 +75,11 @@ an example) gmake check sudo gmake install -### Create empty FRR configuration files +Create empty FRR configuration files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + sudo mkdir /usr/local/etc/frr sudo touch /usr/local/etc/frr/zebra.conf sudo touch /usr/local/etc/frr/bgpd.conf @@ -83,12 +94,16 @@ an example) sudo chown frr:frrvty /usr/local/etc/frr/vtysh.conf sudo chmod 640 /usr/local/etc/frr/*.conf -### Enable IP & IPv6 forwarding +Enable IP & IPv6 forwarding +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Add the following lines to the end of ``/etc/sysctl.conf``: -Add the following lines to the end of `/etc/sysctl.conf`: +:: # Routing: We need to forward packets net.inet.ip.forwarding=1 net.inet6.ip6.forwarding=1 -**Reboot** or use `sysctl` to apply the same config to the running system +**Reboot** or use ``sysctl`` to apply the same config to the running +system diff --git a/doc/Building_FRR_on_FreeBSD11.md b/doc/developer/Building_FRR_on_FreeBSD11.rst similarity index 75% rename from doc/Building_FRR_on_FreeBSD11.md rename to doc/developer/Building_FRR_on_FreeBSD11.rst index 71ccd149ff..de118093e6 100644 --- a/doc/Building_FRR_on_FreeBSD11.md +++ b/doc/developer/Building_FRR_on_FreeBSD11.rst @@ -1,37 +1,42 @@ -Building FRR on FreeBSD 11 from Git Source +FreeBSD 11 ========================================== FreeBSD 11 restrictions: ------------------------ -- MPLS is not supported on `FreeBSD`. MPLS requires a Linux Kernel - (4.5 or higher). LDP can be built, but may have limited use - without MPLS +- MPLS is not supported on ``FreeBSD``. MPLS requires a Linux Kernel + (4.5 or higher). LDP can be built, but may have limited use without + MPLS Install required packages ------------------------- -Add packages: -(Allow the install of the package managment tool if this is first package -install and asked) +Add packages: (Allow the install of the package managment tool if this +is first package install and asked) + +:: pkg install git autoconf automake libtool gmake gawk json-c pkgconf \ bison flex py27-pytest c-ares python3 -Make sure there is no /usr/bin/flex preinstalled (and use the newly -installed in /usr/local/bin): -(FreeBSD frequently provides a older flex as part of the base OS which -takes preference in path) +Make sure there is no /usr/bin/flex preinstalled (and use the newly +installed in /usr/local/bin): (FreeBSD frequently provides a older flex +as part of the base OS which takes preference in path) + +:: rm -f /usr/bin/flex Get FRR, compile it and install it (from Git) --------------------------------------------- -**This assumes you want to build and install FRR from source and not +**This assumes you want to build and install FRR from source and not using any packages** -### Add frr group and user +Add frr group and user +~~~~~~~~~~~~~~~~~~~~~~ + +:: pw groupadd frr -g 101 pw groupadd frrvty -g 102 @@ -41,6 +46,8 @@ using any packages** (You may prefer different options on configure statement. These are just an example) +:: + git clone https://github.com/frrouting/frr.git frr cd frr ./bootstrap.sh @@ -68,7 +75,11 @@ an example) gmake check sudo gmake install -### Create empty FRR configuration files +Create empty FRR configuration files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + sudo mkdir /usr/local/etc/frr sudo touch /usr/local/etc/frr/zebra.conf sudo touch /usr/local/etc/frr/bgpd.conf @@ -83,12 +94,16 @@ an example) sudo chown frr:frrvty /usr/local/etc/frr/vtysh.conf sudo chmod 640 /usr/local/etc/frr/*.conf -### Enable IP & IPv6 forwarding +Enable IP & IPv6 forwarding +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Add the following lines to the end of ``/etc/sysctl.conf``: -Add the following lines to the end of `/etc/sysctl.conf`: +:: # Routing: We need to forward packets net.inet.ip.forwarding=1 net.inet6.ip6.forwarding=1 -**Reboot** or use `sysctl` to apply the same config to the running system +**Reboot** or use ``sysctl`` to apply the same config to the running +system diff --git a/doc/Building_FRR_on_FreeBSD9.md b/doc/developer/Building_FRR_on_FreeBSD9.rst similarity index 73% rename from doc/Building_FRR_on_FreeBSD9.md rename to doc/developer/Building_FRR_on_FreeBSD9.rst index 8a09d8a4cc..2ccf56be13 100644 --- a/doc/Building_FRR_on_FreeBSD9.md +++ b/doc/developer/Building_FRR_on_FreeBSD9.rst @@ -1,32 +1,39 @@ -Building FRR on FreeBSD 9 from Git Source +FreeBSD 9 ========================================= FreeBSD 9 restrictions: ----------------------- -- MPLS is not supported on `FreeBSD`. MPLS requires a Linux Kernel - (4.5 or higher). LDP can be built, but may have limited use - without MPLS - +- MPLS is not supported on ``FreeBSD``. MPLS requires a Linux Kernel + (4.5 or higher). LDP can be built, but may have limited use without + MPLS + Install required packages ------------------------- -Add packages: -(Allow the install of the package managment tool if this is first package -install and asked) +Add packages: (Allow the install of the package managment tool if this +is first package install and asked) + +:: pkg install -y git autoconf automake libtool gmake gawk \ pkgconf texinfo json-c bison flex py27-pytest c-ares \ python3 Make sure there is no /usr/bin/flex preinstalled (and use the newly -installed in /usr/local/bin): -(FreeBSD frequently provides a older flex as part of the base OS which -takes preference in path) +installed in /usr/local/bin): (FreeBSD frequently provides a older flex +as part of the base OS which takes preference in path) + +:: rm -f /usr/bin/flex -For building with clang (instead of gcc), upgrade clang from 3.4 default to 3.6 *This is needed to build FreeBSD packages as well - for packages clang is default* (Clang 3.4 as shipped with FreeBSD 9 crashes during compile) +For building with clang (instead of gcc), upgrade clang from 3.4 default +to 3.6 *This is needed to build FreeBSD packages as well - for packages +clang is default* (Clang 3.4 as shipped with FreeBSD 9 crashes during +compile) + +:: pkg install clang36 pkg delete clang34 @@ -39,7 +46,10 @@ Get FRR, compile it and install it (from Git) **This assumes you want to build and install FRR from source and not using any packages** -### Add frr group and user +Add frr group and user +~~~~~~~~~~~~~~~~~~~~~~ + +:: pw groupadd frr -g 101 pw groupadd frrvty -g 102 @@ -49,6 +59,8 @@ using any packages** (You may prefer different options on configure statement. These are just an example) +:: + git clone https://github.com/frrouting/frr.git frr cd frr ./bootstrap.sh @@ -76,7 +88,11 @@ an example) gmake check sudo gmake install -### Create empty FRR configuration files +Create empty FRR configuration files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + sudo mkdir /usr/local/etc/frr sudo touch /usr/local/etc/frr/zebra.conf sudo touch /usr/local/etc/frr/bgpd.conf @@ -91,12 +107,16 @@ an example) sudo chown frr:frrvty /usr/local/etc/frr/vtysh.conf sudo chmod 640 /usr/local/etc/frr/*.conf -### Enable IP & IPv6 forwarding +Enable IP & IPv6 forwarding +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Add the following lines to the end of ``/etc/sysctl.conf``: -Add the following lines to the end of `/etc/sysctl.conf`: +:: # Routing: We need to forward packets net.inet.ip.forwarding=1 net.inet6.ip6.forwarding=1 -**Reboot** or use `sysctl` to apply the same config to the running system +**Reboot** or use ``sysctl`` to apply the same config to the running +system diff --git a/doc/Building_FRR_for_LEDE-OpenWRT.md b/doc/developer/Building_FRR_on_LEDE-OpenWRT.rst similarity index 59% rename from doc/Building_FRR_for_LEDE-OpenWRT.md rename to doc/developer/Building_FRR_on_LEDE-OpenWRT.rst index cde68dbd0b..2ddd8bcc44 100644 --- a/doc/Building_FRR_for_LEDE-OpenWRT.md +++ b/doc/developer/Building_FRR_on_LEDE-OpenWRT.rst @@ -1,9 +1,10 @@ -Building FRR for OpenWRT/LEDE from Git Source -=============================================== +OpenWRT/LEDE +============================================= -- for the moment because of cross compile problems, master is not supported, - only upto 3.0 -- LDP can't be built because of missing Perl-XML-LibXML in OpenWRT/LEDE tree +- for the moment because of cross compile problems, master is not + supported, only up to 3.0 +- LDP can't be built because of missing Perl-XML-LibXML in OpenWRT/LEDE + tree Prepare build environment ------------------------- @@ -14,27 +15,37 @@ for Ubuntu 12.04LTS: +:: + sudo apt-get install build-essential subversion git-core \ libncurses5-dev zlib1g-dev gawk flex quilt libssl-dev xsltproc \ libxml-parser-perl mercurial bzr ecj cvs unzip Ubuntu 64bit: +:: + sudo apt-get install build-essential subversion libncurses5-dev zlib1g-dev \ gawk gcc-multilib flex git-core gettext libssl-dev Debian 8 Jessie: +:: + sudo apt-get install build-essential libncurses5-dev gawk git subversion \ libssl-dev gettext unzip zlib1g-dev file python Debian 9 Stretch: +:: + sudo apt-get install build-essential libncurses5-dev gawk git subversion \ libssl-dev gettext zlib1g-dev Centos x86-64 (some packages require EPEL): +:: + yum install subversion binutils bzip2 gcc gcc-c++ gawk gettext flex \ ncurses-devel zlib-devel zlib-static make patch unzip glibc glibc-devel \ perl-ExtUtils-MakeMaker glibc-static quilt ncurses-libs sed sdcc bison \ @@ -42,35 +53,33 @@ Centos x86-64 (some packages require EPEL): Fedora 24 - 64Bit: +:: + dnf install -y subversion binutils bzip2 gcc gcc-c++ gawk gettext git-core \ unzip ncurses-devel ncurses-compat-libs zlib-devel zlib-static make \ flex patch perl-ExtUtils-MakeMaker perl-Thread-Queue glibc glibc-devel \ glibc-static quilt sed sdcc intltool sharutils bison wget openssl-devel - Get LEDE Sources (from Git) --------------------------- -LEDE and OpenWRT is planned to remerge and won't cover the similar OpenWRT build -As normal user: - git clone https://git.lede-project.org/source.git lede - cd lede - ./scripts/feeds update -a - ./scripts/feeds install -a - cd feeds/routing - git pull origin pull/319/head - ln -s ../../../feeds/routing/frr/ ../../package/feeds/routing/ - cd ../.. - make menuconfig - -Select the needed target then select needed packages in -Network -> Routing and Redirection -> frr, exit and save +LEDE and OpenWRT is planned to remerge and won't cover the similar +OpenWRT build As normal user: git clone +https://git.lede-project.org/source.git lede cd lede ./scripts/feeds +update -a ./scripts/feeds install -a cd feeds/routing git pull origin +pull/319/head ln -s ../../../feeds/routing/frr/ +../../package/feeds/routing/ cd ../.. make menuconfig + +Select the needed target then select needed packages in Network -> +Routing and Redirection -> frr, exit and save + +:: make or make package/frr/compile -It may be possible that on first build `make package/frr/compile` not to work -and it may be needed to run a `make` for the entire build envronment, add V=s -for debugging +It may be possible that on first build ``make package/frr/compile`` not +to work and it may be needed to run a ``make`` for the entire build +envronment, add V=s for debugging Work with sources ----------------- @@ -78,19 +87,21 @@ Work with sources To update the rc1 version or add other options, the Makefile is found in feeds/routing/frr -edit: - PKG_VERSION:= - PKG_SOURCE_VERSION:= +edit: PKG\_VERSION:= PKG\_SOURCE\_VERSION:= Usage ----- -Edit `/usr/sbin/frr.init` and add/remove the daemons name in section DAEMONS= -or don't install unneded packages -For example: zebra bgpd ldpd isisd nhrpd ospfd ospf6d pimd ripd ripngd +Edit ``/usr/sbin/frr.init`` and add/remove the daemons name in section +DAEMONS= or don't install unneded packages For example: zebra bgpd ldpd +isisd nhrpd ospfd ospf6d pimd ripd ripngd + +Enable the serivce +~~~~~~~~~~~~~~~~~~ + +- service frr enable -### Enable the serivce - - service frr enable +Start the service +~~~~~~~~~~~~~~~~~ -### Start the service - - service frr start +- service frr start diff --git a/doc/Building_FRR_on_NetBSD6.md b/doc/developer/Building_FRR_on_NetBSD6.rst similarity index 79% rename from doc/Building_FRR_on_NetBSD6.md rename to doc/developer/Building_FRR_on_NetBSD6.rst index 4fe7109bcd..b4476127e3 100644 --- a/doc/Building_FRR_on_NetBSD6.md +++ b/doc/developer/Building_FRR_on_NetBSD6.rst @@ -1,50 +1,66 @@ -Building FRR on NetBSD 6 from Git Source +NetBSD 6 ======================================== NetBSD 6 restrictions: ---------------------- -- MPLS is not supported on `NetBSD`. MPLS requires a Linux Kernel - (4.5 or higher). LDP can be built, but may have limited use - without MPLS +- MPLS is not supported on ``NetBSD``. MPLS requires a Linux Kernel + (4.5 or higher). LDP can be built, but may have limited use without + MPLS Install required packages ------------------------- + Configure Package location: +:: + PKG_PATH="ftp://ftp.NetBSD.org/pub/pkgsrc/packages/NetBSD/`uname -m`/`uname -r`/All" export PKG_PATH Add packages: +:: + sudo pkg_add git autoconf automake libtool gmake gawk openssl \ pkg-config json-c python27 py27-test python35 Install SSL Root Certificates (for git https access): +:: + sudo pkg_add mozilla-rootcerts sudo touch /etc/openssl/openssl.cnf sudo mozilla-rootcerts install Select default Python and py.test +:: + sudo ln -s /usr/pkg/bin/python2.7 /usr/bin/python sudo ln -s /usr/pkg/bin/py.test-2.7 /usr/bin/py.test Get FRR, compile it and install it (from Git) ------------------------------------------------- +--------------------------------------------- + +Add frr groups and user +~~~~~~~~~~~~~~~~~~~~~~~ -### Add frr groups and user +:: sudo groupadd -g 92 frr sudo groupadd -g 93 frrvty sudo useradd -g 92 -u 92 -G frrvty -c "FRR suite" \ -d /nonexistent -s /sbin/nologin frr -### Download Source, configure and compile it -(You may prefer different options on configure statement. These are just +Download Source, configure and compile it +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +(You may prefer different options on configure statement. These are just an example) +:: + git clone https://github.com/frrouting/frr.git frr cd frr ./bootstrap.sh @@ -72,7 +88,11 @@ an example) gmake check sudo gmake install -### Create empty FRR configuration files +Create empty FRR configuration files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + sudo mkdir /var/log/frr sudo mkdir /usr/pkg/etc/frr sudo touch /usr/pkg/etc/frr/zebra.conf @@ -88,23 +108,35 @@ an example) sudo chown frr:frrvty /usr/pkg/etc/frr/*.conf sudo chmod 640 /usr/pkg/etc/frr/*.conf -### Enable IP & IPv6 forwarding +Enable IP & IPv6 forwarding +~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Add the following lines to the end of `/etc/sysctl.conf`: +Add the following lines to the end of ``/etc/sysctl.conf``: + +:: # Routing: We need to forward packets net.inet.ip.forwarding=1 net.inet6.ip6.forwarding=1 -**Reboot** or use `sysctl` to apply the same config to the running system +**Reboot** or use ``sysctl`` to apply the same config to the running +system + +Install rc.d init files +~~~~~~~~~~~~~~~~~~~~~~~ + +:: -### Install rc.d init files cp pkgsrc/*.sh /etc/rc.d/ chmod 555 /etc/rc.d/*.sh -### Enable FRR processes +Enable FRR processes +~~~~~~~~~~~~~~~~~~~~ + (Enable the required processes only) +:: + echo "zebra=YES" >> /etc/rc.conf echo "bgpd=YES" >> /etc/rc.conf echo "ospfd=YES" >> /etc/rc.conf diff --git a/doc/Building_FRR_on_NetBSD7.md b/doc/developer/Building_FRR_on_NetBSD7.rst similarity index 79% rename from doc/Building_FRR_on_NetBSD7.md rename to doc/developer/Building_FRR_on_NetBSD7.rst index 7fe9ad20c9..e4ff1df8a5 100644 --- a/doc/Building_FRR_on_NetBSD7.md +++ b/doc/developer/Building_FRR_on_NetBSD7.rst @@ -1,44 +1,57 @@ -Building FRR on NetBSD 7 from Git Source +NetBSD 7 ======================================== NetBSD 7 restrictions: ---------------------- -- MPLS is not supported on `NetBSD`. MPLS requires a Linux Kernel - (4.5 or higher). LDP can be built, but may have limited use - without MPLS +- MPLS is not supported on ``NetBSD``. MPLS requires a Linux Kernel + (4.5 or higher). LDP can be built, but may have limited use without + MPLS Install required packages ------------------------- +:: + sudo pkgin install git autoconf automake libtool gmake gawk openssl \ pkg-config json-c python27 py27-test python35 Install SSL Root Certificates (for git https access): +:: + sudo pkgin install mozilla-rootcerts sudo touch /etc/openssl/openssl.cnf sudo mozilla-rootcerts install Select default Python and py.test +:: + sudo ln -s /usr/pkg/bin/python2.7 /usr/bin/python sudo ln -s /usr/pkg/bin/py.test-2.7 /usr/bin/py.test Get FRR, compile it and install it (from Git) ------------------------------------------------- +--------------------------------------------- + +Add frr groups and user +~~~~~~~~~~~~~~~~~~~~~~~ -### Add frr groups and user +:: sudo groupadd -g 92 frr sudo groupadd -g 93 frrvty sudo useradd -g 92 -u 92 -G frrvty -c "FRR suite" \ -d /nonexistent -s /sbin/nologin frr -### Download Source, configure and compile it +Download Source, configure and compile it +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + (You may prefer different options on configure statement. These are just an example) +:: + git clone https://github.com/frrouting/frr.git frr cd frr ./bootstrap.sh @@ -66,7 +79,11 @@ an example) gmake check sudo gmake install -### Create empty FRR configuration files +Create empty FRR configuration files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + sudo mkdir /usr/pkg/etc/frr sudo touch /usr/pkg/etc/frr/zebra.conf sudo touch /usr/pkg/etc/frr/bgpd.conf @@ -81,23 +98,35 @@ an example) sudo chown frr:frrvty /usr/pkg/etc/frr/*.conf sudo chmod 640 /usr/pkg/etc/frr/*.conf -### Enable IP & IPv6 forwarding +Enable IP & IPv6 forwarding +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Add the following lines to the end of ``/etc/sysctl.conf``: -Add the following lines to the end of `/etc/sysctl.conf`: +:: # Routing: We need to forward packets net.inet.ip.forwarding=1 net.inet6.ip6.forwarding=1 -**Reboot** or use `sysctl` to apply the same config to the running system +**Reboot** or use ``sysctl`` to apply the same config to the running +system + +Install rc.d init files +~~~~~~~~~~~~~~~~~~~~~~~ + +:: -### Install rc.d init files cp pkgsrc/*.sh /etc/rc.d/ chmod 555 /etc/rc.d/*.sh -### Enable FRR processes +Enable FRR processes +~~~~~~~~~~~~~~~~~~~~ + (Enable the required processes only) +:: + echo "zebra=YES" >> /etc/rc.conf echo "bgpd=YES" >> /etc/rc.conf echo "ospfd=YES" >> /etc/rc.conf diff --git a/doc/Building_FRR_on_OmniOS.md b/doc/developer/Building_FRR_on_OmniOS.rst similarity index 81% rename from doc/Building_FRR_on_OmniOS.md rename to doc/developer/Building_FRR_on_OmniOS.rst index 6e4575f07b..bc4ff45715 100644 --- a/doc/Building_FRR_on_OmniOS.md +++ b/doc/developer/Building_FRR_on_OmniOS.rst @@ -1,14 +1,17 @@ -Building FRR on OmniOS (OpenSolaris) from Git Source +OmniOS (OpenSolaris) ==================================================== OmniOS restrictions: -------------------- -- MPLS is not supported on `OmniOS` or `Solaris`. MPLS requires a Linux - Kernel (4.5 or higher). LDP can be built, but may have limited use - without MPLS +- MPLS is not supported on ``OmniOS`` or ``Solaris``. MPLS requires a + Linux Kernel (4.5 or higher). LDP can be built, but may have limited + use without MPLS -### Enable IP & IPv6 forwarding +Enable IP & IPv6 forwarding +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: routeadm -e ipv4-forwarding routeadm -e ipv6-forwarding @@ -18,6 +21,8 @@ Install required packages Add packages: +:: + pkg install \ developer/build/autoconf \ developer/build/automake \ @@ -36,6 +41,8 @@ Add packages: Add additional Solaris packages: +:: + pkgadd -d http://get.opencsw.org/now /opt/csw/bin/pkgutil -U /opt/csw/bin/pkgutil -y -i texinfo @@ -45,33 +52,46 @@ Add additional Solaris packages: Add libjson to Solaris equivalent of ld.so.conf +:: + crle -l /opt/csw/lib -u Add pytest: +:: + pip install pytest Select Python 2.7 as default (required for pytest) +:: + rm -f /usr/bin/python ln -s /opt/csw/bin/python2.7 /usr/bin/python -Fix PATH for all users and non-interactive sessions. Edit `/etc/default/login` -and add the following default PATH: +Fix PATH for all users and non-interactive sessions. Edit +``/etc/default/login`` and add the following default PATH: + +:: PATH=/usr/gnu/bin:/usr/bin:/usr/sbin:/sbin:/opt/csw/bin -Edit `~/.profile` and add the following default PATH: +Edit ``~/.profile`` and add the following default PATH: + +:: PATH=/usr/gnu/bin:/usr/bin:/usr/sbin:/sbin:/opt/csw/bin Get FRR, compile it and install it (from Git) --------------------------------------------- -**This assumes you want to build and install FRR from source and not using -any packages** +**This assumes you want to build and install FRR from source and not +using any packages** + +Add frr group and user +~~~~~~~~~~~~~~~~~~~~~~ -### Add frr group and user +:: sudo groupadd -g 93 frr sudo groupadd -g 94 frrvty @@ -81,6 +101,8 @@ any packages** (You may prefer different options on configure statement. These are just an example) +:: + git clone https://github.com/frrouting/frr.git frr cd frr ./bootstrap.sh @@ -111,7 +133,10 @@ an example) gmake check sudo gmake install -### Enable IP & IPv6 forwarding +Enable IP & IPv6 forwarding +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: routeadm -e ipv4-forwarding - routeadm -e ipv6-forwarding + routeadm -e ipv6-forwarding diff --git a/doc/Building_FRR_on_OpenBSD6.md b/doc/developer/Building_FRR_on_OpenBSD6.rst similarity index 82% rename from doc/Building_FRR_on_OpenBSD6.md rename to doc/developer/Building_FRR_on_OpenBSD6.rst index c1bfa5005e..0e51c8660c 100644 --- a/doc/Building_FRR_on_OpenBSD6.md +++ b/doc/developer/Building_FRR_on_OpenBSD6.rst @@ -1,39 +1,52 @@ -Building FRR on OpenBSD 6 from Git Source +OpenBSD 6 ========================================= Install required packages ------------------------- -Configure PKG_PATH +Configure PKG\_PATH + +:: export PKG_PATH=http://ftp5.usa.openbsd.org/pub/OpenBSD/$(uname -r)/packages/$(machine -a)/ Add packages: +:: + pkg_add git autoconf-2.69p2 automake-1.15p0 libtool bison pkg_add gmake gawk dejagnu openssl json-c py-test Select Python2.7 as default (required for pytest) +:: + ln -s /usr/local/bin/python2.7 /usr/local/bin/python Get FRR, compile it and install it (from Git) --------------------------------------------- -**This assumes you want to build and install FRR from source and not using -any packages** +**This assumes you want to build and install FRR from source and not +using any packages** -### Add frr group and user +Add frr group and user +~~~~~~~~~~~~~~~~~~~~~~ + +:: groupadd -g 525 _frr groupadd -g 526 _frrvty useradd -g 525 -u 525 -c "FRR suite" -G _frrvty \ -d /nonexistent -s /sbin/nologin _frr -### Download Source, configure and compile it -(You may prefer different options on configure statement. These are just +Download Source, configure and compile it +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +(You may prefer different options on configure statement. These are just an example) +:: + git clone https://github.com/frrouting/frr.git frr cd frr export AUTOCONF_VERSION="2.69" @@ -61,7 +74,10 @@ an example) gmake check doas gmake install -### Create empty FRR configuration files +Create empty FRR configuration files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: doas mkdir /var/frr doas chown _frr:_frr /var/frr @@ -83,9 +99,12 @@ an example) doas chmod 750 /etc/frr doas chmod 640 /etc/frr/*.conf -### Enable IP & IPv6 forwarding +Enable IP & IPv6 forwarding +~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Add the following lines to the end of `/etc/rc.conf`: +Add the following lines to the end of ``/etc/rc.conf``: + +:: net.inet6.ip6.forwarding=1 # 1=Permit forwarding of IPv6 packets net.inet6.ip6.mforwarding=1 # 1=Permit forwarding of IPv6 multicast packets @@ -93,37 +112,52 @@ Add the following lines to the end of `/etc/rc.conf`: **Reboot** to apply the config to the system -### Enable MPLS Forwarding +Enable MPLS Forwarding +~~~~~~~~~~~~~~~~~~~~~~ + +To enable MPLS forwarding on a given interface, use the following +command: -To enable MPLS forwarding on a given interface, use the following command: +:: doas ifconfig em0 mpls -Alternatively, to make MPLS forwarding persistent across reboots, add the "mpls" -keyword in the hostname.* files of the desired interfaces. Example: +Alternatively, to make MPLS forwarding persistent across reboots, add +the "mpls" keyword in the hostname.\* files of the desired interfaces. +Example: + +:: cat /etc/hostname.em0 inet 10.0.1.1 255.255.255.0 mpls -### Install rc.d init files -(create them in /etc/rc.d - no example are included at this time with +Install rc.d init files +~~~~~~~~~~~~~~~~~~~~~~~ + +(create them in /etc/rc.d - no example are included at this time with FRR source) -Example (for zebra - store as `/etc/rc.d/frr_zebra.sh`) +Example (for zebra - store as ``/etc/rc.d/frr_zebra.sh``) + +:: #!/bin/sh # # $OpenBSD: frr_zebra.rc,v 1.1 2013/04/18 20:29:08 sthen Exp $ - + daemon="/usr/local/sbin/zebra -d" - + . /etc/rc.d/rc.subr - + rc_cmd $1 -### Enable FRR processes +Enable FRR processes +~~~~~~~~~~~~~~~~~~~~ + (Enable the required processes only) +:: + echo "frr_zebra=YES" >> /etc/rc.conf echo "frr_bgpd=YES" >> /etc/rc.conf echo "frr_ospfd=YES" >> /etc/rc.conf diff --git a/doc/Building_FRR_on_Ubuntu1204.md b/doc/developer/Building_FRR_on_Ubuntu1204.rst similarity index 79% rename from doc/Building_FRR_on_Ubuntu1204.md rename to doc/developer/Building_FRR_on_Ubuntu1204.rst index 58aa167d57..935d199842 100644 --- a/doc/Building_FRR_on_Ubuntu1204.md +++ b/doc/developer/Building_FRR_on_Ubuntu1204.rst @@ -1,22 +1,26 @@ -Building FRR on Ubuntu 12.04LTS from Git Source +Ubuntu 12.04LTS =============================================== -- MPLS is not supported on `Ubuntu 12.04` with default kernel. MPLS requires - Linux Kernel 4.5 or higher (LDP can be built, but may have limited use - without MPLS) - For an updated Ubuntu Kernel, see http://kernel.ubuntu.com/~kernel-ppa/mainline/ +- MPLS is not supported on ``Ubuntu 12.04`` with default kernel. MPLS + requires Linux Kernel 4.5 or higher (LDP can be built, but may have + limited use without MPLS) For an updated Ubuntu Kernel, see + http://kernel.ubuntu.com/~kernel-ppa/mainline/ Install required packages ------------------------- Add packages: +:: + apt-get install git autoconf automake libtool make gawk libreadline-dev \ texinfo libpam0g-dev dejagnu libjson0-dev pkg-config libpam0g-dev \ libjson0-dev flex python-pip libc-ares-dev python3-dev -Install newer bison from 14.04 package source (Ubuntu 12.04 package source -is too old) +Install newer bison from 14.04 package source (Ubuntu 12.04 package +source is too old) + +:: mkdir builddir cd builddir @@ -35,6 +39,8 @@ is too old) Install newer version of autoconf and automake: +:: + wget http://ftp.gnu.org/gnu/autoconf/autoconf-2.69.tar.gz tar xvf autoconf-2.69.tar.gz cd autoconf-2.69 @@ -42,7 +48,7 @@ Install newer version of autoconf and automake: make sudo make install cd .. - + wget http://ftp.gnu.org/gnu/automake/automake-1.15.tar.gz tar xvf automake-1.15.tar.gz cd automake-1.15 @@ -53,15 +59,20 @@ Install newer version of autoconf and automake: Install pytest: +:: + pip install pytest Get FRR, compile it and install it (from Git) --------------------------------------------- -**This assumes you want to build and install FRR from source and not using -any packages** +**This assumes you want to build and install FRR from source and not +using any packages** + +Add frr groups and user +~~~~~~~~~~~~~~~~~~~~~~~ -### Add frr groups and user +:: sudo groupadd -g 92 frr sudo groupadd -r -g 85 frrvty @@ -69,10 +80,14 @@ any packages** --gecos "FRR suite" --shell /sbin/nologin frr sudo usermod -a -G frrvty frr -### Download Source, configure and compile it +Download Source, configure and compile it +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + (You may prefer different options on configure statement. These are just an example.) +:: + git clone https://github.com/frrouting/frr.git frr cd frr ./bootstrap.sh @@ -100,7 +115,10 @@ an example.) make check sudo make install -### Create empty FRR configuration files +Create empty FRR configuration files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: sudo install -m 755 -o frr -g frr -d /var/log/frr sudo install -m 775 -o frr -g frrvty -d /etc/frr @@ -116,11 +134,14 @@ an example.) sudo install -m 640 -o frr -g frr /dev/null /etc/frr/nhrpd.conf sudo install -m 640 -o frr -g frrvty /dev/null /etc/frr/vtysh.conf -### Enable IP & IPv6 forwarding +Enable IP & IPv6 forwarding +~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Edit `/etc/sysctl.conf` and uncomment the following values (ignore the +Edit ``/etc/sysctl.conf`` and uncomment the following values (ignore the other settings) +:: + # Uncomment the next line to enable packet forwarding for IPv4 net.ipv4.ip_forward=1 @@ -129,18 +150,27 @@ other settings) # based on Router Advertisements for this host net.ipv6.conf.all.forwarding=1 -**Reboot** or use `sysctl -p` to apply the same config to the running system +**Reboot** or use ``sysctl -p`` to apply the same config to the running +system -### Install the init.d service +Install the init.d service +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: sudo install -m 755 tools/frr /etc/init.d/frr sudo install -m 644 tools/etc/frr/daemons /etc/frr/daemons sudo install -m 644 tools/etc/frr/daemons.conf /etc/frr/daemons.conf sudo install -m 644 -o frr -g frr tools/etc/frr/vtysh.conf /etc/frr/vtysh.conf - -### Enable daemons -Edit `/etc/frr/daemons` and change the value from "no" to "yes" for those daemons you want to start by systemd. -For example. + +Enable daemons +~~~~~~~~~~~~~~ + +| Edit ``/etc/frr/daemons`` and change the value from "no" to "yes" for + those daemons you want to start by systemd. +| For example. + +:: zebra=yes bgpd=yes @@ -149,7 +179,9 @@ For example. ripd=yes ripngd=yes isisd=yes - -### Start the init.d service -- /etc/init.d/frr start -- use `/etc/init.d/frr status` to check its status. + +Start the init.d service +~~~~~~~~~~~~~~~~~~~~~~~~ + +- /etc/init.d/frr start +- use ``/etc/init.d/frr status`` to check its status. diff --git a/doc/Building_FRR_on_Ubuntu1404.md b/doc/developer/Building_FRR_on_Ubuntu1404.rst similarity index 74% rename from doc/Building_FRR_on_Ubuntu1404.md rename to doc/developer/Building_FRR_on_Ubuntu1404.rst index 8e6b38cc2d..4a4e38ea30 100644 --- a/doc/Building_FRR_on_Ubuntu1404.md +++ b/doc/developer/Building_FRR_on_Ubuntu1404.rst @@ -1,16 +1,18 @@ -Building FRR on Ubuntu 14.04LTS from Git Source +Ubuntu 14.04LTS =============================================== -- MPLS is not supported on `Ubuntu 14.04` with default kernel. MPLS requires - Linux Kernel 4.5 or higher (LDP can be built, but may have limited use - without MPLS) - For an updated Ubuntu Kernel, see http://kernel.ubuntu.com/~kernel-ppa/mainline/ +- MPLS is not supported on ``Ubuntu 14.04`` with default kernel. MPLS + requires Linux Kernel 4.5 or higher (LDP can be built, but may have + limited use without MPLS) For an updated Ubuntu Kernel, see + http://kernel.ubuntu.com/~kernel-ppa/mainline/ Install required packages ------------------------- Add packages: +:: + apt-get install git autoconf automake libtool make gawk libreadline-dev \ texinfo dejagnu pkg-config libpam0g-dev libjson-c-dev bison flex \ python-pytest libc-ares-dev python3-dev @@ -18,10 +20,13 @@ Add packages: Get FRR, compile it and install it (from Git) --------------------------------------------- -**This assumes you want to build and install FRR from source and not using -any packages** +**This assumes you want to build and install FRR from source and not +using any packages** + +Add frr groups and user +~~~~~~~~~~~~~~~~~~~~~~~ -### Add frr groups and user +:: sudo groupadd -g 92 frr sudo groupadd -r -g 85 frrvty @@ -29,10 +34,14 @@ any packages** --gecos "FRR suite" --shell /sbin/nologin frr sudo usermod -a -G frrvty frr -### Download Source, configure and compile it -(You may prefer different options on configure statement. These are just +Download Source, configure and compile it +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +(You may prefer different options on configure statement. These are just an example.) +:: + git clone https://github.com/frrouting/frr.git frr cd frr ./bootstrap.sh @@ -61,7 +70,10 @@ an example.) make check sudo make install -### Create empty FRR configuration files +Create empty FRR configuration files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: sudo install -m 755 -o frr -g frr -d /var/log/frr sudo install -m 775 -o frr -g frrvty -d /etc/frr @@ -77,11 +89,14 @@ an example.) sudo install -m 640 -o frr -g frr /dev/null /etc/frr/nhrpd.conf sudo install -m 640 -o frr -g frrvty /dev/null /etc/frr/vtysh.conf -### Enable IP & IPv6 forwarding +Enable IP & IPv6 forwarding +~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Edit `/etc/sysctl.conf` and uncomment the following values (ignore the +Edit ``/etc/sysctl.conf`` and uncomment the following values (ignore the other settings) +:: + # Uncomment the next line to enable packet forwarding for IPv4 net.ipv4.ip_forward=1 @@ -90,19 +105,24 @@ other settings) # based on Router Advertisements for this host net.ipv6.conf.all.forwarding=1 -**Reboot** or use `sysctl -p` to apply the same config to the running system -### Install the init.d service +**Reboot** or use ``sysctl -p`` to apply the same config to the running +system ### Install the init.d service + +:: sudo install -m 755 tools/frr /etc/init.d/frr sudo install -m 644 tools/etc/frr/daemons /etc/frr/daemons sudo install -m 644 tools/etc/frr/daemons.conf /etc/frr/daemons.conf sudo install -m 644 -o frr -g frr tools/etc/frr/vtysh.conf /etc/frr/vtysh.conf - - -### Enable daemons -Edit `/etc/frr/daemons` and change the value from "no" to "yes" for those daemons you want to start by systemd. -For example. +Enable daemons +~~~~~~~~~~~~~~ + +| Edit ``/etc/frr/daemons`` and change the value from "no" to "yes" for + those daemons you want to start by systemd. +| For example. + +:: zebra=yes bgpd=yes @@ -111,9 +131,9 @@ For example. ripd=yes ripngd=yes isisd=yes - -### Start the init.d service -- /etc/init.d/frr start -- use `/etc/init.d/frr status` to check its status. - - + +Start the init.d service +~~~~~~~~~~~~~~~~~~~~~~~~ + +- /etc/init.d/frr start +- use ``/etc/init.d/frr status`` to check its status. diff --git a/doc/Building_FRR_on_Ubuntu1604.md b/doc/developer/Building_FRR_on_Ubuntu1604.rst similarity index 68% rename from doc/Building_FRR_on_Ubuntu1604.md rename to doc/developer/Building_FRR_on_Ubuntu1604.rst index bdd0a96249..dccc37adcc 100644 --- a/doc/Building_FRR_on_Ubuntu1604.md +++ b/doc/developer/Building_FRR_on_Ubuntu1604.rst @@ -1,17 +1,18 @@ -Building FRR on Ubuntu 16.04LTS from Git Source +Ubuntu 16.04LTS =============================================== -- MPLS is not supported on `Ubuntu 16.04` with default kernel. MPLS requires - Linux Kernel 4.5 or higher (LDP can be built, but may have limited use - without MPLS) - For an updated Ubuntu Kernel, see - http://kernel.ubuntu.com/~kernel-ppa/mainline/ +- MPLS is not supported on ``Ubuntu 16.04`` with default kernel. MPLS + requires Linux Kernel 4.5 or higher (LDP can be built, but may have + limited use without MPLS) For an updated Ubuntu Kernel, see + http://kernel.ubuntu.com/~kernel-ppa/mainline/ Install required packages ------------------------- Add packages: +:: + apt-get install git autoconf automake libtool make gawk libreadline-dev \ texinfo dejagnu pkg-config libpam0g-dev libjson-c-dev bison flex \ python-pytest libc-ares-dev python3-dev libsystemd-dev python-ipaddr @@ -19,10 +20,13 @@ Add packages: Get FRR, compile it and install it (from Git) --------------------------------------------- -**This assumes you want to build and install FRR from source and not using -any packages** +**This assumes you want to build and install FRR from source and not +using any packages** + +Add frr groups and user +~~~~~~~~~~~~~~~~~~~~~~~ -### Add frr groups and user +:: sudo groupadd -g 92 frr sudo groupadd -r -g 85 frrvty @@ -30,10 +34,14 @@ any packages** --gecos "FRR suite" --shell /sbin/nologin frr sudo usermod -a -G frrvty frr -### Download Source, configure and compile it -(You may prefer different options on configure statement. These are just +Download Source, configure and compile it +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +(You may prefer different options on configure statement. These are just an example.) +:: + git clone https://github.com/frrouting/frr.git frr cd frr ./bootstrap.sh @@ -62,7 +70,10 @@ an example.) make check sudo make install -### Create empty FRR configuration files +Create empty FRR configuration files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: sudo install -m 755 -o frr -g frr -d /var/log/frr sudo install -m 775 -o frr -g frrvty -d /etc/frr @@ -78,11 +89,14 @@ an example.) sudo install -m 640 -o frr -g frr /dev/null /etc/frr/nhrpd.conf sudo install -m 640 -o frr -g frrvty /dev/null /etc/frr/vtysh.conf -### Enable IPv4 & IPv6 forwarding +Enable IPv4 & IPv6 forwarding +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Edit `/etc/sysctl.conf` and uncomment the following values (ignore the +Edit ``/etc/sysctl.conf`` and uncomment the following values (ignore the other settings) +:: + # Uncomment the next line to enable packet forwarding for IPv4 net.ipv4.ip_forward=1 @@ -91,10 +105,14 @@ other settings) # based on Router Advertisements for this host net.ipv6.conf.all.forwarding=1 -### Enable MPLS Forwarding (with Linux Kernel >= 4.5) +Enable MPLS Forwarding (with Linux Kernel >= 4.5) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Edit `/etc/sysctl.conf` and the following lines. Make sure to add a line -equal to `net.mpls.conf.eth0.input` or each interface used with MPLS +Edit ``/etc/sysctl.conf`` and the following lines. Make sure to add a +line equal to ``net.mpls.conf.eth0.input`` or each interface used with +MPLS + +:: # Enable MPLS Label processing on all interfaces net.mpls.conf.eth0.input=1 @@ -102,18 +120,24 @@ equal to `net.mpls.conf.eth0.input` or each interface used with MPLS net.mpls.conf.eth2.input=1 net.mpls.platform_labels=100000 -### Add MPLS kernel modules +Add MPLS kernel modules +~~~~~~~~~~~~~~~~~~~~~~~ + +Add the following lines to ``/etc/modules-load.d/modules.conf``: -Add the following lines to `/etc/modules-load.d/modules.conf`: +:: # Load MPLS Kernel Modules mpls-router mpls-iptunnel -**Reboot** or use `sysctl -p` to apply the same config to the running system +**Reboot** or use ``sysctl -p`` to apply the same config to the running +system +Install the systemd service (if rebooted from last step, change directory back to frr directory) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -### Install the systemd service (if rebooted from last step, change directory back to frr directory) +:: sudo install -m 644 tools/frr.service /etc/systemd/system/frr.service sudo install -m 644 tools/etc/default/frr /etc/default/frr @@ -122,10 +146,14 @@ Add the following lines to `/etc/modules-load.d/modules.conf`: sudo install -m 644 tools/etc/frr/frr.conf /etc/frr/frr.conf sudo install -m 644 -o frr -g frr tools/etc/frr/vtysh.conf /etc/frr/vtysh.conf -### Enable daemons +Enable daemons +~~~~~~~~~~~~~~ + +| Edit ``/etc/frr/daemons`` and change the value from "no" to "yes" for + those daemons you want to start by systemd. +| For example. -Edit `/etc/frr/daemons` and change the value from "no" to "yes" for those daemons you want to start by systemd. -For example. +:: zebra=yes bgpd=yes @@ -135,9 +163,13 @@ For example. ripngd=yes isisd=yes -### Enable the systemd service - - systemctl enable frr +Enable the systemd service +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- systemctl enable frr + +Start the systemd service +~~~~~~~~~~~~~~~~~~~~~~~~~ -### Start the systemd service -- systemctl start frr -- use `systemctl status frr` to check its status. +- systemctl start frr +- use ``systemctl status frr`` to check its status. diff --git a/doc/developer/building.rst b/doc/developer/building.rst new file mode 100644 index 0000000000..4715bca532 --- /dev/null +++ b/doc/developer/building.rst @@ -0,0 +1,22 @@ +Building FRR +========================= + +.. toctree:: + :maxdepth: 2 + + Building_FRR_on_LEDE-OpenWRT + Building_FRR_on_CentOS6 + Building_FRR_on_CentOS7 + Building_FRR_on_Debian8 + Building_FRR_on_Debian9 + Building_FRR_on_Fedora24 + Building_FRR_on_FreeBSD10 + Building_FRR_on_FreeBSD11 + Building_FRR_on_FreeBSD9 + Building_FRR_on_NetBSD6 + Building_FRR_on_NetBSD7 + Building_FRR_on_OmniOS + Building_FRR_on_OpenBSD6 + Building_FRR_on_Ubuntu1204 + Building_FRR_on_Ubuntu1404 + Building_FRR_on_Ubuntu1604 diff --git a/doc/developer/cli.rst b/doc/developer/cli.rst new file mode 100644 index 0000000000..7462887410 --- /dev/null +++ b/doc/developer/cli.rst @@ -0,0 +1,615 @@ +FRR Command Line Interface +========================== + +Definition Grammar +------------------ + +This is a reference for the syntax used when defining new CLI commands. +An example definition is: + +:: + + DEFUN (command_name, + command_name_cmd, + --> "example DEFINITION...", + <..doc strings..>) + +The arrowed part is the definition string. + +Explicit syntax rules in Flex and Bison may be found in +lib/command\_lex.l and lib/command\_parse.y, respectively. If you can +read BNF and regex those will be more useful than this document. + +If the parser is throwing syntax or other errors and you can't figure +out why, it's unlikely to be a bug in the parser. If the error message +is not useful, please file a bug for a better error message. If all else +fails, read the token definitions in the lexer source and the Bison BNF +in the parser source. + +Characters allowed in each token type: + +Tokens +------ + +- ``WORD`` -- A token that begins with +, -, or a lowercase letter. It + is an unchanging part of the command and will only match itself. + Example: "show ip bgp", every token is a WORD. +- ``IPV4`` -- 'A.B.C.D', matches an IPv4 address. +- ``IPV6`` -- 'X:X::X:X', matches an IPv6 address. +- ``IPV4_PREFIX`` -- 'A.B.C.D/M', matches an IPv4 prefix in CIDR + notation. +- ``IPV6_PREFIX`` -- 'X:X::X:X/M', matches an IPv6 prefix in CIDR + notation. +- ``MAC`` -- 'M:A:C', matches a 48-bit mac address +- ``MAC_PREFIX`` -- 'M:A:C/M', matches a 48-bit mac address with a mask +- ``VARIABLE`` -- Begins with a capital letter. Matches any input. +- ``RANGE`` -- Numeric range delimited by parentheses, e.g. (-100 - + 100) or (10-20). Will only match numbers in the range. + +Rules +----- + +- ```` -- Contain sequences of tokens separated by + pipes and provide mutual exclusion. Sequences may contain + ```` but not as the first token. Disallowed: + ``"example < c|d>"`` Allowed: ``"example "`` +- ``[square brackets]`` -- Contains sequences of tokens that are + optional (can be omitted). ``[]`` can be shortened to ``[a|b]``. +- ``{curly|braces}`` -- similar to angle brackets, but instead of + mutual exclusion, curly braces indicate that one or more of the + pipe-separated sequences may be provided in any order. +- ``VARIADICS...`` -- Any token which accepts input (so anything except + WORD) and that occurs as the last token of a line may be followed by + an ellipsis, which indicates that input matching the token may be + repeated an unlimited number of times. +- ``$name`` -- Specify a variable name for the preceding token. See + "Variable Names" below. + +Some general notes: + +- Options are allowed at the beginning of the command. The developer is + entreated to use these extremely sparingly. They are most useful for + implementing the 'no' form of configuration commands. Please think + carefully before using them for anything else. There is usually a + better solution, even if it is just separating out the command + definition into separate ones. + +- The developer should judiciously apply separation of concerns when + defining + +CLI. CLI definitions for two unrelated or vaguely related commands or + configuration items should be defined in separate commands. Clarity + is preferred over LOC (within reason). + +- The maximum number of space-separated tokens that can be entered is + presently limited to 256. Please keep this limit in mind when + implementing new CLI. + +Variable Names +-------------- + +The parser tries to fill the "varname" field on each token. This can +happen either manually or automatically. Manual specifications work by +appending ``"$name"`` after the input specifier: + +:: + + foo bar$cmd WORD$name A.B.C.D$ip + +Note that you can also assign variable names to fixed input tokens, this +can be useful if multiple commands share code. You can also use "$name" +after a multiple-choice option: + +:: + + foo bar $addr [optionA|optionB]$mode + +The variable name is in this case assigned to the last token in each of +the branches. + +Automatic assignment of variable names works by applying the following +rules: + +- manual names always have priority +- a "[no]" at the beginning receives "no" as varname on the "no" token +- VARIABLE tokens whose text is not "WORD" or "NAME" receive a cleaned + lowercase version of the token text as varname, e.g. "ROUTE-MAP" + becomes "route\_map". +- other variable tokens (i.e. everything except "fixed") receive the + text of the preceding fixed token as varname, if one can be found. + E.g.: "ip route A.B.C.D/M INTERFACE" assigns "route" to the + "A.B.C.D/M" token. + +These rules should make it possible to avoid manual varname assignment +in 90% of the cases. + +DEFPY +----- + +``DEFPY(...)`` is an enhanced version of ``DEFUN()`` which is +preprocessed by ``python/clidef.py``. The python script parses the +command definition string, extracts variable names and types, and +generates a C wrapper function that parses the variables and passes them +on. This means that in the CLI function body, you will receive +additional parameters with appropriate types. + +This is best explained by an example: + +:: + + DEFPY(func, func_cmd, "[no] foo bar A.B.C.D (0-99)$num", "...help...") + + => + + func(self, vty, argc, argv, /* standard CLI arguments */ + + const char *no, /* unparsed "no" */ + struct in_addr bar, /* parsed IP address */ + const char *bar_str, /* unparsed IP address */ + long num, /* parsed num */ + const char *num_str) /* unparsed num */ + +Note that as documented in the previous section, "bar" is automatically +applied as variable name for "A.B.C.D". The python code then detects +this is an IP address argument and generates code to parse it into a +``struct in_addr``, passing it in ``bar``. The raw value is passed in +``bar_str``. The range/number argument works in the same way with the +explicitly given variable name. + +Type rules +~~~~~~~~~~ + ++------------------------------+----------------------------------+----------------------------+ +| Token(s) | Type | Value if omitted by user | ++==============================+==================================+============================+ +| ``A.B.C.D`` | ``struct in_addr`` | 0.0.0.0 | ++------------------------------+----------------------------------+----------------------------+ +| ``X:X::X:X`` | ``struct in6_addr`` | :: | ++------------------------------+----------------------------------+----------------------------+ +| ``A.B.C.D + X:X::X:X`` | ``const union sockunion *`` | NULL | ++------------------------------+----------------------------------+----------------------------+ +| ``A.B.C.D/M`` | ``const struct prefix_ipv4 *`` | NULL | ++------------------------------+----------------------------------+----------------------------+ +| ``X:X::X:X/M`` | ``const struct prefix_ipv6 *`` | NULL | ++------------------------------+----------------------------------+----------------------------+ +| ``A.B.C.D/M + X:X::X:X/M`` | ``const struct prefix *`` | NULL | ++------------------------------+----------------------------------+----------------------------+ +| ``(0-9)`` | ``long`` | 0 | ++------------------------------+----------------------------------+----------------------------+ +| ``VARIABLE`` | ``const char *`` | NULL | ++------------------------------+----------------------------------+----------------------------+ +| ``word`` | ``const char *`` | NULL | ++------------------------------+----------------------------------+----------------------------+ +| *all other* | ``const char *`` | NULL | ++------------------------------+----------------------------------+----------------------------+ + +Note the following details: + +- not all parameters are pointers, some are passed as values. +- when the type is not ``const char *``, there will be an extra + ``_str`` argument with type ``const char *``. +- you can give a variable name not only to ``VARIABLE`` tokens but also + to ``word`` tokens (e.g. constant words). This is useful if some + parts of a command are optional. The type will be ``const char *``. +- ``[no]`` will be passed as ``const char *no``. +- pointers will be NULL when the argument is optional and the user did + not use it. +- if a parameter is not a pointer, but is optional and the user didn't + use it, the default value will be passed. Check the ``_str`` argument + if you need to determine whether the parameter was omitted. +- if the definition contains multiple parameters with the same variable + name, they will be collapsed into a single function parameter. The + python code will detect if the types are compatible (i.e. IPv4 + IPv6 + variantes) and choose a corresponding C type. +- the standard DEFUN parameters (self, vty, argc, argv) are still + present and can be used. A DEFUN can simply be **edited into a DEFPY + without further changes and it will still work**; this allows easy + forward migration. +- a file may contain both DEFUN and DEFPY statements. + +Getting a parameter dump +~~~~~~~~~~~~~~~~~~~~~~~~ + +The clidef.py script can be called to get a list of DEFUNs/DEFPYs with +the parameter name/type list: + +:: + + lib/clippy python/clidef.py --all-defun --show lib/plist.c > /dev/null + +The generated code is printed to stdout, the info dump to stderr. The +``--all-defun`` argument will make it process DEFUN blocks as well as +DEFPYs, which is useful prior to converting some DEFUNs. **The dump does +not list the ``_str`` arguments** to keep the output shorter. + +Note that the clidef.py script cannot be run with python directly, it +needs to be run with *clippy* since the latter makes the CLI parser +available. + +Include & Makefile requirements +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A source file that uses DEFPY needs to include the ``_clippy.c`` file +**before all DEFPY statements**: + +:: + + /* GPL header */ + #include ... + + ... + + #include "daemon/filename_clippy.c" + + DEFPY(...) + DEFPY(...) + + install_element(...) + +This dependency needs to be marked in Makefile.am: (there is no ordering +requirement) + +:: + + include ../common.am + + # ... + + # if linked into a LTLIBRARY (.la/.so): + filename.lo: filename_clippy.c + + # if linked into an executable or static library (.a): + filename.o: filename_clippy.c + +Doc Strings +----------- + +Each token in a command definition should be documented with a brief doc +string that informs a user of the meaning and/or purpose of the +subsequent command tree. These strings are provided as the last +parameter to DEFUN macros, concatenated together and separated by an +escaped newline (':raw-latex:`\n`'). These are best explained by +example. + +:: + + DEFUN (config_terminal, + config_terminal_cmd, + "configure terminal", + "Configuration from vty interface\n" + "Configuration terminal\n") + +The last parameter is split into two lines for readability. Two newline +delimited doc strings are present, one for each token in the command. +The second string documents the functionality of the 'terminal' command +in the 'configure' tree. + +Note that the first string, for 'configure' does not contain +documentation for 'terminal'. This is because the CLI is best envisioned +as a tree, with tokens defining branches. An imaginary 'start' token is +the root of every command in a CLI node. Each subsequent written token +descends into a subtree, so the documentation for that token ideally +summarizes all the functionality contained in the subtree. + +A consequence of this structure is that the developer must be careful to +use the same doc strings when defining multiple commands that are part +of the same tree. Commands which share prefixes must share the same doc +strings for those prefixes. On startup the parser will generate warnings +if it notices inconsistent doc strings. Behavior is undefined; the same +token may show up twice in completions, with different doc strings, or +it may show up once with a random doc string. Parser warnings should be +heeded and fixed to avoid confusing users. + +The number of doc strings provided must be equal to the amount of tokens +present in the command definition, read left to right, ignoring any +special constructs. + +In the examples below, each arrowed token needs a doc string. + +:: + + "show ip bgp" + ^ ^ ^ + + "command [example]" + ^ ^ ^ ^ + +Data Structures +--------------- + +On startup, the CLI parser sequentially parses each command string +definition and constructs a directed graph with each token forming a +node. This graph is the basis of the entire CLI system. It is used to +match user input in order to generate command completions and match +commands to functions. + +There is one graph per CLI node (not the same as a graph node in the CLI +graph). The CLI node struct keeps a reference to its graph (see +lib/command.h). + +While most of the graph maintains the form of a tree, special constructs +outlined in the Rules section introduce some quirks. <>, [] and {} form +self-contained 'subgraphs'. Each subgraph is a tree except that all of +the 'leaves' actually share a child node. This helps with minimizing +graph size and debugging. + +As an example, the subgraph generated by looks like this: + +:: + + . + . + | + +----+---+ + +--- -+ FORK +----+ + | +--------+ | + +--v---+ +--v---+ + | foo | | bar | + +--+---+ +--+---+ + | +------+ | + +------> JOIN <-----+ + +---+--+ + | + . + . + +FORK and JOIN nodes are plumbing nodes that don't correspond to user +input. They're necessary in order to deduplicate these constructs where +applicable. + +Options follow the same form, except that there is an edge from the FORK +node to the JOIN node. + +Keywords follow the same form, except that there is an edge from JOIN to +FORK. Because of this the CLI graph cannot be called acyclic. There is +special logic in the input matching code that keeps a stack of paths +already taken through the node in order to disallow following the same +path more than once. + +Variadics are a bit special; they have an edge back to themselves, which +allows repeating the same input indefinitely. + +The leaves of the graph are nodes that have no out edges. These nodes +are special; their data section does not contain a token, as most nodes +do, or NULL, as in FORK/JOIN nodes, but instead has a pointer to a +cmd\_element. All paths through the graph that terminate on a leaf are +guaranteed to be defined by that command. When a user enters a complete +command, the command matcher tokenizes the input and executes a DFS on +the CLI graph. If it is simultaneously able to exhaust all input (one +input token per graph node), and then find exactly one leaf connected to +the last node it reaches, then the input has matched the corresponding +command and the command is executed. If it finds more than one node, +then the command is ambiguous (more on this in deduplication). If it +cannot exhaust all input, the command is unknown. If it exhausts all +input but does not find an edge node, the command is incomplete. + +The parser uses an incremental strategy to build the CLI graph for a +node. Each command is parsed into its own graph, and then this graph is +merged into the overall graph. During this merge step, the parser makes +a best-effort attempt to remove duplicate nodes. If it finds a node in +the overall graph that is equal to a node in the corresponding position +in the command graph, it will intelligently merge the properties from +the node in the command graph into the already-existing node. Subgraphs +are also checked for isomorphism and merged where possible. The +definition of whether two nodes are 'equal' is based on the equality of +some set of token properties; read the parser source for the most +up-to-date definition of equality. + +When the parser is unable to deduplicate some complicated constructs, +this can result in two identical paths through separate parts of the +graph. If this occurs and the user enters input that matches these +paths, they will receive an 'ambiguous command' error and will be unable +to execute the command. Most of the time the parser can detect and warn +about duplicate commands, but it will not always be able to do this. +Hence care should be taken before defining a new command to ensure it is +not defined elsewhere. + +Command handlers +---------------- + +The block that follows a CLI definition is executed when a user enters +input that matches the definition. Its function signature looks like +this: + +int (*func) (const struct cmd\_element *, struct vty *, int, struct +cmd\_token *\ []); + +The first argument is the command definition struct. The last argument +is an ordered array of tokens that correspond to the path taken through +the graph, and the argument just prior to that is the length of the +array. + +The arrangement of the token array has changed from the prior +incarnation of the CLI system. In the old system, missing arguments were +padded with NULLs so that the same parts of a command would show up at +the same indices regardless of what was entered. The new system does not +perform such padding and therefore it is generally *incorrect* to assume +consistent indices in this array. As a simple example: + +Command definition: + +:: + + command [foo] + +User enters: + +:: + + command foo bar + +Array: + +:: + + [0] -> command + [1] -> foo + [2] -> bar + +User enters: + +:: + + command baz + +Array: + +:: + + [0] -> command + [1] -> baz + +Command abbreviation & matching priority +---------------------------------------- + +As in the prior implementation, it is possible for users to elide parts +of tokens when the CLI matcher does not need them to make an unambiguous +match. This is best explained by example. + +Command definitions: + +:: + + command dog cow + command dog crow + +User input: + +:: + + c d c -> ambiguous command + c d co -> match "command dog cow" + +In the new implementation, this functionality has improved. Where +previously the parser would stop at the first ambiguous token, it will +now look ahead and attempt to disambiguate based on tokens later on in +the input string. + +Command definitions: + +:: + + show ip bgp A.B.C.D + show ipv6 bgp X:X::X:X + +User enters: + +:: + + s i b 4.3.2.1 -> match "show ip bgp A.B.C.D" + s i b ::e0 -> match "show ipv6 bgp X:X::X:X" + +Previously both of these commands would be ambiguous since 'i' does not +explicitly select either 'ip' or 'ipv6'. However, since the user later +provides a token that matches only one of the commands (an IPv4 or IPv6 +address) the parser is able to look ahead and select the appropriate +command. This has some implications for parsing the argv\*[] that is +passed to the command handler. + +Now consider a command definition such as: + +:: + + command + +'foo' only matches the string 'foo', but 'VAR' matches any input, +including 'foo'. Who wins? In situations like this the matcher will +always choose the 'better' match, so 'foo' will win. + +Consider also: + +:: + + show foo + +User input: + +:: + + show ip foo + +'ip' partially matches 'ipv6' but exactly matches 'ip', so 'ip' will +win. + +struct cmd\_token +----------------- + +:: + + /* Command token struct. */ + struct cmd_token + { + enum cmd_token_type type; // token type + u_char attr; // token attributes + bool allowrepeat; // matcher allowed to match token repetitively? + + char *text; // token text + char *desc; // token description + long long min, max; // for ranges + char *arg; // user input that matches this token + char *varname; // variable name + }; + +This struct is used in the CLI graph to match input against. It is also +used to pass user input to command handler functions, as it is +frequently useful for handlers to have access to that information. When +a command is matched, the sequence of cmd\_tokens that form the matching +path are duplicated and placed in order into argv\*[]. Before this +happens the ->arg field is set to point at the snippet of user input +that matched it. + +For most nontrivial commands the handler function will need to determine +which of the possible matching inputs was entered. Previously this was +done by looking at the first few characters of input. This is now +considered an anti-pattern and should be avoided. Instead, the ->type or +->text fields for this logic. The ->type field can be used when the +possible inputs differ in type. When the possible types are the same, +use the ->text field. This field has the full text of the corresponding +token in the definition string and using it makes for much more readable +code. An example is helpful. + +Command definition: + +:: + + command <(1-10)|foo|BAR> + +In this example, the user may enter any one of: \* an integer between 1 +and 10 \* "foo" \* anything at all + +If the user enters "command f", then: + +:: + + argv[1]->type == WORD_TKN + argv[1]->arg == "f" + argv[1]->text == "foo" + +Range tokens have some special treatment; a token with ->type == +RANGE\_TKN will have the ->min and ->max fields set to the bounding +values of the range. + +Permutations +------------ + +Finally, it is sometimes useful to check all the possible combinations +of input that would match an arbitrary definition string. There is a +tool in tools/ called 'permutations' that reads CLI definition strings +on stdin and prints out all matching input permutations. It also dumps a +text representation of the graph, which is more useful for debugging +than anything else. It looks like this: + +:: + + $ ./permutations "show [ip] bgp [ WORD]" + + show ip bgp view WORD + show ip bgp vrf WORD + show ip bgp + show bgp view WORD + show bgp vrf WORD + show bgp + +This functionality is also built into VTY/VTYSH; the 'list permutations' +command will list all possible matching input permutations in the +current CLI node. diff --git a/doc/code/conf.py b/doc/developer/conf.py similarity index 98% rename from doc/code/conf.py rename to doc/developer/conf.py index 38be7f2fca..6c39c6e26d 100644 --- a/doc/code/conf.py +++ b/doc/developer/conf.py @@ -231,7 +231,7 @@ latex_elements = { # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - (master_doc, 'FRR.tex', u'FRR Documentation', + (master_doc, 'FRR.tex', u'FRR Developer\'s Documentation', u'FRR', 'manual'), ] @@ -261,7 +261,7 @@ latex_documents = [ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ - (master_doc, 'frr', u'FRR Documentation', + (master_doc, 'frr', u'FRR Developer\'s Documentation', [author], 1) ] @@ -275,7 +275,7 @@ man_pages = [ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - (master_doc, 'FRR', u'FRR Documentation', + (master_doc, 'FRR', u'FRR Developer\'s Documentation', author, 'FRR', 'One line description of project.', 'Miscellaneous'), ] diff --git a/doc/developer/dev-modules.rst b/doc/developer/dev-modules.rst new file mode 100644 index 0000000000..5cf1939ff3 --- /dev/null +++ b/doc/developer/dev-modules.rst @@ -0,0 +1,125 @@ +Module and Hook support (developer docs) +======================================== + +What it does +------------ + +It uses ``dlopen()`` to load DSOs at startup. + +Limitations +----------- + +- can't load, unload, or reload during runtime. This just needs some + work and can probably be done in the future. +- doesn't fix any of the "things need to be changed in the code in the + library" issues. Most prominently, you can't add a CLI node because + CLI nodes are listed in the library... +- if your module crashes, the daemon crashes. Should be obvious. +- **does not provide a stable API or ABI**. Your module must match a + version of FRR and you may have to update it frequently to match + changes. +- **does not create a license boundary**. Your module will need to link + libzebra and include header files from the daemons, meaning it will + be GPL-encumbered. + +Installation +------------ + +Look for ``moduledir`` in ``configure.ac``, default is normally +``/usr/lib64/frr/modules`` but depends on ``--libdir`` / ``--prefix``. + +The daemon's name is prepended when looking for a module, e.g. "snmp" +tries to find "zebra\_snmp" first when used in zebra. This is just to +make it nicer for the user, with the snmp module having the same name +everywhere. + +Modules can be packaged separately from FRR. The SNMP and FPM modules +are good candidates for this because they have dependencies (net-snmp / +protobuf) that are not FRR dependencies. However, any distro packages +should have an "exact-match" dependency onto the FRR package. Using a +module from a different FRR version will probably blow up nicely. + +For snapcraft (and during development), modules can be loaded with full +path (e.g. -M ``$SNAP/lib/frr/modules/zebra_snmp.so``). Note that +libtool puts output files in the .libs directory, so during development +you have to use ``./zebra -M .libs/zebra_snmp.so``. + +Creating a module +----------------- + +... best to look at the existing SNMP or FPM modules. + +Basic boilerplate: + +:: + + #include "hook.h" + #include "module.h" + + static int + module_init (void) + { + hook_register(frr_late_init, module_late_init); + return 0; + } + + FRR_MODULE_SETUP( + .name = "my module", + .version = "0.0", + .description = "my module", + .init = module_init, + ) + +The ``frr_late_init`` hook will be called after the daemon has finished +its other startup and is about to enter the main event loop; this is the +best place for most initialisation. + +Compiler & Linker magic +----------------------- + +There's a ``THIS_MODULE`` (like in the Linux kernel), which uses +``visibility`` attributes to restrict it to the current module. If you +get a linker error with ``_frrmod_this_module``, there is some linker +SNAFU. This shouldn't be possible, though one way to get it would be to +not include libzebra (which provides a fallback definition for the +symbol). + +libzebra and the daemons each have their own ``THIS_MODULE``, as do all +loadable modules. In any other libraries (e.g. ``libfrrsnmp``), +``THIS_MODULE`` will use the definition in libzebra; same applies if the +main executable doesn't use ``FRR_DAEMON_INFO`` (e.g. all testcases). + +The deciding factor here is "what dynamic linker unit are you using the +symbol from." If you're in a library function and want to know who +called you, you can't use ``THIS_MODULE`` (because that'll just tell you +you're in the library). Put a macro around your function that adds +``THIS_MODULE`` in the *caller's code calling your function*. + +The idea is to use this in the future for module unloading. Hooks +already remember which module they were installed by, as groundwork for +a function that removes all of a module's installed hooks. + +There's also the ``frr_module`` symbol in modules, pretty much a +standard entry point for loadable modules. + +Hooks +----- + +Hooks are just points in the code where you can register your callback +to be called. The parameter list is specific to the hook point. Since +there is no stable API, the hook code has some extra type safety checks +making sure you get a compiler warning when the hook parameter list +doesn't match your callback. Don't ignore these warnings. + +Relation to MTYPE macros +------------------------ + +The MTYPE macros, while primarily designed to decouple MTYPEs from the +library and beautify the code, also work very nicely with loadable +modules -- both constructors and destructors are executed when +loading/unloading modules. + +This means there is absolutely no change required to MTYPEs, you can +just use them in a module and they will even clean up themselves when we +implement module unloading and an unload happens. In fact, it's +impossible to create a bug where unloading fails to de-register a MTYPE. diff --git a/doc/developer/git_branches.svg b/doc/developer/git_branches.svg new file mode 100644 index 0000000000..0c2c96e39e --- /dev/null +++ b/doc/developer/git_branches.svg @@ -0,0 +1,720 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + 1.0ReleaseBranch + + + + + + + + + + Master(Stable) + + + + + + + + + 1.1ReleaseBranch + Version 1.0.a1 + Version 1.1.a1 + Version 1.1.a2 + + + + + Version 1.1.b1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Patch Email (Patchwork) + Github Pull Request + Github Pull Request + Patch Email (Patchwork) + Patch Email (Patchwork) + Github Pull Request + Github Pull Request + Github Pull Request + Patch Email (Patchwork) + Github Pull Request + Github Pull Request + Github Pull Request + Github Pull Request + Github Pull Request + Github Pull Request + + + + + + + + + Version 1.0.a2 + Version 1.0.b1 + Version 1.0.0 + Version 1.1.0 + Version 1.1.1 + Version 1.1.2 + + + + + + + + + + + + + + + + + + diff --git a/doc/code/hooks.rst b/doc/developer/hooks.rst similarity index 100% rename from doc/code/hooks.rst rename to doc/developer/hooks.rst diff --git a/doc/code/index.rst b/doc/developer/index.rst similarity index 50% rename from doc/code/index.rst rename to doc/developer/index.rst index 79647d0b92..6f0dbebdfd 100644 --- a/doc/code/index.rst +++ b/doc/developer/index.rst @@ -1,18 +1,10 @@ Welcome to FRR's documentation! =============================== -Contents: - .. toctree:: :maxdepth: 2 + workflow library - - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` + building diff --git a/doc/ldpd-basic-test-setup.md b/doc/developer/ldpd-basic-test-setup.md similarity index 100% rename from doc/ldpd-basic-test-setup.md rename to doc/developer/ldpd-basic-test-setup.md diff --git a/doc/code/library.rst b/doc/developer/library.rst similarity index 82% rename from doc/code/library.rst rename to doc/developer/library.rst index dd46021db8..a8837b1253 100644 --- a/doc/code/library.rst +++ b/doc/developer/library.rst @@ -6,5 +6,7 @@ libfrr library facilities memtypes hooks + cli + dev-modules diff --git a/doc/code/memtypes.rst b/doc/developer/memtypes.rst similarity index 100% rename from doc/code/memtypes.rst rename to doc/developer/memtypes.rst diff --git a/doc/next-hop-tracking.txt b/doc/developer/next-hop-tracking.txt similarity index 100% rename from doc/next-hop-tracking.txt rename to doc/developer/next-hop-tracking.txt diff --git a/doc/developer/workflow.rst b/doc/developer/workflow.rst new file mode 100644 index 0000000000..38cf0b878d --- /dev/null +++ b/doc/developer/workflow.rst @@ -0,0 +1,544 @@ +Developing for FRRouting +======================== + +General note on this document +----------------------------- + +This document 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. + +Git Structure +------------- + +The master Git for FRRouting resides on Github at +`https://github.com/frrouting/frr `__ + +.. figure:: git_branches.svg + :alt: git branches continually merging to the left from 3 lanes; + float-right + + git branches continually merging to the left from 3 lanes; + float-right + +There is one main branch for development and a release branch for each +major release. + +New contributions are done against the head of the master branch. The CI +systems will pick up the Github Pull Requests or the new patch from +Patchwork, run some basic build and functional tests. + +For each major release (1.0, 1.1 etc) a new release branch is created +based on the master. + +There was an attempt to use a "develop" branch automatically maintained +by the CI system. This is not currently in active use, though the system +is operational. If the "develop" branch is in active use and this +paragraph is still here, this document obviously wasn't updated. + +Programming language, Tools and Libraries +----------------------------------------- + +The core of FRRouting is written in C (gcc or clang supported) and makes +use of GNU compiler extensions. A few non-essential scripts are +implemented in Perl and Python. FRRouting 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 FRRouting 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 Tex (.texi) or Markdown (.md) format +with a preference for Markdown. + +Mailing lists +------------- + +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 | ++----------------------------------+--------------------------------+ + +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. The changelog will +be the base for the release notes. + +Submitting Patches and Enhancements +----------------------------------- + +Pre-submission Checklist +~~~~~~~~~~~~~~~~~~~~~~~~ + +- Format code (see `Developer's Guidelines <#developers-guidelines>`__) +- Verify and acknowledge license (see `License for + contributions <#license-for-contributions>`__) +- Ensure you have properly signed off (see `Signing + Off <#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`` + +- Document Regression Runs and plans for continued maintenance of the + feature + +License for contributions +~~~~~~~~~~~~~~~~~~~~~~~~~ + +FRRouting 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). + +Signing Off +~~~~~~~~~~~ + +Code submitted to FRRouting 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. + +``Signed-off-by:`` this is a developer's certification that he or she +has the right to submit the patch for inclusion into the project. It is +an agreement to the Developer's Certificate of Origin (below). Code +without a proper signoff can not and will not be merged. + +If you are unfamiliar with this process, you should read the `official +policy at +kernel.org `__ +and you might find this article about `participating in the Linux +community on the Linux Foundation +website `__ +to be a helpful resource. + +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. + +What do I submit my changes against? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +We've documented where we would like to have the different fixes applied +at +https://github.com/FRRouting/frr/wiki/Where-Do-I-create-a-Pull-Request-against%3F +If you are unsure where your submission goes, look at that document or +ask a project maintainer. + +Github pull requests +~~~~~~~~~~~~~~~~~~~~ + +The preferred method of submitting changes is a Github pull request. +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. + +Patch submission via mailing list +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +As an alternative submission method, a patch can be mailed to the +development mailing list. Patches received on the mailing list will be +picked up by Patchwork and tested against the latest development branch. + +The recommended way to send the patch (or series of NN patches) to the +list is by using ``git send-email`` as follows (assuming they are the N +most recent commit(s) in your git history: + +:: + + git send-email -NN --annotate --to=dev@lists.frrouting.org + +If your commits do not already contain a ``Signed-off-by`` line, then +use the following command to add it (after making sure you agree to the +Developer Certificate of Origin as outlined above): + +:: + + git send-email -NN --annotate --signoff --to=dev@lists.frrouting.org + +Submitting multi-commit patches as a Github pull request is **strongly +encouraged** and increases the probability of your patch getting +reviewed and merged in a timely manner. + +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 (if submitted + by pull request) or on Patchwork at + https://patchwork.frrouting.org (if submitted as patch to mailing + list). + - 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. + - 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. + +Developer's Guidelines +---------------------- + +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 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. + +Source file header +~~~~~~~~~~~~~~~~~~ + +New files need to have a Copyright header (see `License for +contributions <#license-for-contributions>`__ above) added to the file. +Preferred form of the header is as follows: + +:: + + /* + * Title/Function of file + * Copyright (C) YEAR Author’s Name + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + #include + +Adding copyright claims to existing files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When adding copyright claims for modifications to an existing file, +please preface the claim with "Portions: " on a line before it and +indent the "Copyright ..." string. If such a case already exists, add +your indented claim immediately after. E.g.: + +:: + + Portions: + Copyright (C) 2010 Entity A .... + Copyright (C) 2016 Your name [optional brief change description] + +Code formatting +~~~~~~~~~~~~~~~ + +FRR uses Linux kernel style except where noted below. Code which does +not comply with these style guidelines will not be accepted. + +To assist with compliance, in the project root there is a .clang-format +configuration file which can be used with the ``clang-format`` tool from +the LLVM project. In the ``tools/`` directory there is a Python script +named ``indent.py`` that wraps clang-format and handles some edge cases +specific to FRR. If you are submitting a new file, it is recommended to +run that script over the new file after ensuring that the latest stable +release of ``clang-format`` is in your PATH. + +**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. + +Style documentation +^^^^^^^^^^^^^^^^^^^ + +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 + +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/`` + +Documentation +~~~~~~~~~~~~~ + +FRRouting 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: + +:: + + /* + * Determines whether or not a string is cool. + * + * @param text - the string to check for coolness + * @param is_clccfc - whether capslock is cruise control for cool + * @return 7 if the text is cool, 0 otherwise + */ + int check_coolness(const char *text, bool is_clccfc); + +The Javadoc-style annotations are not required, but you should still +strive to make it equally 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 are contributing code that adds significant user-visible +functionality or introduces a new API, please document it in ``doc/``. +Markdown and LaTeX are acceptable formats, although Markdown is +currently preferred for new documentation. This may change in the near +future. + +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. + +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. + +CLI changes +~~~~~~~~~~~ + +CLI's are a complicated ugly beast. Additions or changes to the CLI +should use a DEFUN to encapsulate one setting as much as is possible. +Additionally as new DEFUN's are added to the system, documentation +should be provided for the new 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. + +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. + +Miscellaneous +~~~~~~~~~~~~~ + +When in doubt, follow the guidelines in the Linux kernel style guide, or +ask on the development mailing list / public Slack instance. -- 2.39.5