From d1890d041eae5a4c389321053a1328a277726945 Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Fri, 8 Dec 2017 11:47:49 -0500 Subject: 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/developer/conf.py | 293 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 293 insertions(+) create mode 100644 doc/developer/conf.py (limited to 'doc/developer/conf.py') diff --git a/doc/developer/conf.py b/doc/developer/conf.py new file mode 100644 index 0000000000..6c39c6e26d --- /dev/null +++ b/doc/developer/conf.py @@ -0,0 +1,293 @@ +# -*- coding: utf-8 -*- +# +# FRR documentation build configuration file, created by +# sphinx-quickstart on Tue Jan 31 16:00:52 2017. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys +import os +import re + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.insert(0, os.path.abspath('.')) + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = ['sphinx.ext.todo'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix(es) of source filenames. +# You can specify multiple suffix as a list of string: +# source_suffix = ['.rst', '.md'] +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'FRR' +copyright = u'2017, FRR' +author = u'FRR' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. + +# The short X.Y version. +version = u'?.?' +# The full version, including alpha/beta/rc tags. +release = u'?.?-?' + +val = re.compile('^S\["([^"]+)"\]="(.*)"$') +with open('../../config.status', 'r') as cfgstatus: + for ln in cfgstatus.readlines(): + m = val.match(ln) + if m is None: continue + if m.group(1) == 'PACKAGE_VERSION': + release = m.group(2) + version = release.split('-')[0] + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# +# This is also used if you do content translation via gettext catalogs. +# Usually you set "language" from the command line for these cases. +language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ['_build'] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +#keep_warnings = False + +# If true, `todo` and `todoList` produce output, else they produce nothing. +todo_include_todos = True + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'sphinx_rtd_theme' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +#html_extra_path = [] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Language to be used for generating the HTML full-text search index. +# Sphinx supports the following languages: +# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja' +# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr' +#html_search_language = 'en' + +# A dictionary with options for the search language support, empty by default. +# Now only 'ja' uses this config value +#html_search_options = {'type': 'default'} + +# The name of a javascript file (relative to the configuration directory) that +# implements a search results scorer. If empty, the default will be used. +#html_search_scorer = 'scorer.js' + +# Output file base name for HTML help builder. +htmlhelp_basename = 'FRRdoc' + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { +# The paper size ('letterpaper' or 'a4paper'). +#'papersize': 'letterpaper', + +# The font size ('10pt', '11pt' or '12pt'). +#'pointsize': '10pt', + +# Additional stuff for the LaTeX preamble. +#'preamble': '', + +# Latex figure (float) alignment +#'figure_align': 'htbp', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + (master_doc, 'FRR.tex', u'FRR Developer\'s Documentation', + u'FRR', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + (master_doc, 'frr', u'FRR Developer\'s Documentation', + [author], 1) +] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + (master_doc, 'FRR', u'FRR Developer\'s Documentation', + author, 'FRR', 'One line description of project.', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +#texinfo_no_detailmenu = False -- cgit v1.2.3 From b22ba015ef8c42e584876d9ac73df8e2b71b6eaf Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Fri, 8 Dec 2017 18:22:26 -0500 Subject: doc: more organizing & updating * Add chapter on BGPD * Add diagram for git workflow * Convert next-hop tracking documents to ReST * Update & organize workflow document * Move ldpd docs back up to the parent directory Signed-off-by: Quentin Young --- doc/developer/bgpd.rst | 8 + doc/developer/conf.py | 6 +- doc/developer/git_branches.png | Bin 0 -> 53216 bytes doc/developer/index.rst | 1 + doc/developer/ldpd-basic-test-setup.md | 681 --------------------------------- doc/developer/next-hop-tracking.rst | 352 +++++++++++++++++ doc/developer/next-hop-tracking.txt | 326 ---------------- doc/developer/workflow.rst | 128 +++---- doc/ldpd-basic-test-setup.md | 681 +++++++++++++++++++++++++++++++++ 9 files changed, 1108 insertions(+), 1075 deletions(-) create mode 100644 doc/developer/bgpd.rst create mode 100644 doc/developer/git_branches.png delete mode 100644 doc/developer/ldpd-basic-test-setup.md create mode 100644 doc/developer/next-hop-tracking.rst delete mode 100644 doc/developer/next-hop-tracking.txt create mode 100644 doc/ldpd-basic-test-setup.md (limited to 'doc/developer/conf.py') diff --git a/doc/developer/bgpd.rst b/doc/developer/bgpd.rst new file mode 100644 index 0000000000..053c0779de --- /dev/null +++ b/doc/developer/bgpd.rst @@ -0,0 +1,8 @@ +BGPD +========================= + +.. toctree:: + :maxdepth: 2 + + next-hop-tracking + diff --git a/doc/developer/conf.py b/doc/developer/conf.py index 6c39c6e26d..233056666d 100644 --- a/doc/developer/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 Developer\'s Documentation', + (master_doc, 'FRR.tex', u'FRR Developer\'s Manual', 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 Developer\'s Documentation', + (master_doc, 'frr', u'FRR Developer\'s Manual', [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 Developer\'s Documentation', + (master_doc, 'FRR', u'FRR Developer\'s Manual', author, 'FRR', 'One line description of project.', 'Miscellaneous'), ] diff --git a/doc/developer/git_branches.png b/doc/developer/git_branches.png new file mode 100644 index 0000000000..21001c30a1 Binary files /dev/null and b/doc/developer/git_branches.png differ diff --git a/doc/developer/index.rst b/doc/developer/index.rst index 6f0dbebdfd..f1a39d2828 100644 --- a/doc/developer/index.rst +++ b/doc/developer/index.rst @@ -6,5 +6,6 @@ Welcome to FRR's documentation! workflow library + bgpd building diff --git a/doc/developer/ldpd-basic-test-setup.md b/doc/developer/ldpd-basic-test-setup.md deleted file mode 100644 index b25a2b6d4b..0000000000 --- a/doc/developer/ldpd-basic-test-setup.md +++ /dev/null @@ -1,681 +0,0 @@ -## Topology - -The goal of this test is to verify that the all the basic functionality -of ldpd is working as expected, be it running on Linux or OpenBSD. In -addition to that, more advanced features are also tested, like LDP -sessions over IPv6, MD5 authentication and pseudowire signaling. - -In the topology below there are 3 PE routers, 3 CE routers and one P -router (not attached to any consumer site). - -All routers have IPv4 addresses and OSPF is used as the IGP. The -three routers from the bottom of the picture, P, PE2 and PE3, are also -configured for IPv6 (dual-stack) and static IPv6 routes are used to -provide connectivity among them. - -The three CEs share the same VPLS membership. LDP is used to set up the -LSPs among the PEs and to signal the pseudowires. MD5 authentication is -used to protect all LDP sessions. - -``` - CE1 172.16.1.1/24 - + - | - +---+---+ - | PE1 | - | IOS XE| - | | - +---+---+ - | - | 10.0.1.0/24 - | - +---+---+ - | P | - +------+ IOS XR+------+ - | | | | - | +-------+ | - 10.0.2.0/24 | | 10.0.3.0/24 -2001:db8:2::/64 | | 2001:db8:3::/64 - | | - +---+---+ +---+---+ - | PE2 | | PE3 | - |OpenBSD+-------------+ Linux | - | | | | - +---+---+ 10.0.4.0/24 +---+---+ - | 2001:db8:4::/64 | - + + - 172.16.1.2/24 CE2 CE3 172.16.1.3/24 -``` - -## Configuration - -#### Linux -1 - Enable IPv4/v6 forwarding: -``` -# sysctl -w net.ipv4.ip_forward=1 -# sysctl -w net.ipv6.conf.all.forwarding=1 -``` - -2 - Enable MPLS forwarding: -``` -# modprobe mpls-router -# modprobe mpls-iptunnel -# echo 100000 > /proc/sys/net/mpls/platform_labels -# echo 1 > /proc/sys/net/mpls/conf/eth1/input -# echo 1 > /proc/sys/net/mpls/conf/eth2/input -``` - -3 - Set up the interfaces: -``` -# ip link add name lo1 type dummy -# ip link set dev lo1 up -# ip addr add 4.4.4.4/32 dev lo1 -# ip -6 addr add 4:4:4::4/128 dev lo1 -# ip link set dev eth1 up -# ip addr add 10.0.4.4/24 dev eth1 -# ip -6 addr add 2001:db8:4::4/64 dev eth1 -# ip link set dev eth2 up -# ip addr add 10.0.3.4/24 dev eth2 -# ip -6 addr add 2001:db8:3::4/64 dev eth2 -``` - -4 - Set up the bridge and pseudowire interfaces: -``` -# ip link add type bridge -# ip link set dev bridge0 up -# ip link set dev eth0 up -# ip link set dev eth0 master bridge0 -# ip link add name mpw0 type dummy -# ip link set dev mpw0 up -# ip link set dev mpw0 master bridge0 -# ip link add name mpw1 type dummy -# ip link set dev mpw1 up -# ip link set dev mpw1 master bridge0 -``` - -> NOTE: MPLS support in the Linux kernel is very recent and it still -doesn't support pseudowire interfaces. We are using here dummy interfaces -just to show how the VPLS configuration should look like in the future. - -5 - Add static IPv6 routes for the remote loopbacks: -``` -# ip -6 route add 2:2:2::2/128 via 2001:db8:3::2 -# ip -6 route add 3:3:3::3/128 via 2001:db8:4::3 -``` - -6 - Edit /etc/frr/ospfd.conf: -``` -router ospf - network 4.4.4.4/32 area 0.0.0.0 - network 10.0.3.4/24 area 0.0.0.0 - network 10.0.4.4/24 area 0.0.0.0 -! -``` - -7 - Edit /etc/frr/ldpd.conf: -``` -debug mpls ldp messages recv -debug mpls ldp messages sent -debug mpls ldp zebra -! -mpls ldp - router-id 4.4.4.4 - dual-stack cisco-interop - neighbor 1.1.1.1 password opensourcerouting - neighbor 2.2.2.2 password opensourcerouting - neighbor 3.3.3.3 password opensourcerouting - ! - address-family ipv4 - discovery transport-address 4.4.4.4 - label local advertise explicit-null - ! - interface eth2 - ! - interface eth1 - ! - ! - address-family ipv6 - discovery transport-address 4:4:4::4 - ttl-security disable - ! - interface eth2 - ! - interface eth1 - ! - ! -! -l2vpn ENG type vpls - bridge br0 - member interface eth0 - ! - member pseudowire mpw0 - neighbor lsr-id 1.1.1.1 - pw-id 100 - ! - member pseudowire mpw1 - neighbor lsr-id 3.3.3.3 - neighbor address 3:3:3::3 - pw-id 100 - ! -! -``` - -> NOTE: We have to disable ttl-security under the ipv6 address-family -in order to interoperate with the IOS-XR router. GTSM is mandatory for -LDPv6 but the IOS-XR implementation is not RFC compliant in this regard. - -8 - Run zebra, ospfd and ldpd. - -#### OpenBSD -1 - Enable IPv4/v6 forwarding: -``` -# sysctl net.inet.ip.forwarding=1 -# sysctl net.inet6.ip6.forwarding=1 -``` - -2 - Enable MPLS forwarding: -``` -# ifconfig em2 10.0.2.3/24 mpls -# ifconfig em3 10.0.4.3/24 mpls -``` - -3 - Set up the interfaces: -``` -# ifconfig lo1 alias 3.3.3.3 netmask 255.255.255.255 -# ifconfig lo1 inet6 3:3:3::3/128 -# ifconfig em2 inet6 2001:db8:2::3/64 -# ifconfig em3 inet6 2001:db8:4::3/64 -``` - -4 - Set up the bridge and pseudowire interfaces: -``` -# ifconfig bridge0 create -# ifconfig bridge0 up -# ifconfig em1 up -# ifconfig bridge0 add em1 -# ifconfig mpw0 create -# ifconfig mpw0 up -# ifconfig bridge0 add mpw0 -# ifconfig mpw1 create -# ifconfig mpw1 up -# ifconfig bridge0 add mpw1 -``` - -5 - Add static IPv6 routes for the remote loopbacks: -``` -# route -n add 4:4:4::4/128 2001:db8:4::4 -# route -n add 2:2:2::2/128 2001:db8:2::2 -``` - -6 - Edit /etc/frr/ospfd.conf: -``` -router ospf - network 10.0.2.3/24 area 0 - network 10.0.4.3/24 area 0 - network 3.3.3.3/32 area 0 -! -``` - -7 - Edit /etc/frr/ldpd.conf: -``` -debug mpls ldp messages recv -debug mpls ldp messages sent -debug mpls ldp zebra -! -mpls ldp - router-id 3.3.3.3 - dual-stack cisco-interop - neighbor 1.1.1.1 password opensourcerouting - neighbor 2.2.2.2 password opensourcerouting - neighbor 4.4.4.4 password opensourcerouting - ! - address-family ipv4 - discovery transport-address 3.3.3.3 - label local advertise explicit-null - ! - interface em3 - ! - interface em2 - ! - ! - address-family ipv6 - discovery transport-address 3:3:3::3 - ttl-security disable - ! - interface em3 - ! - interface em2 - ! - ! -! -l2vpn ENG type vpls - bridge br0 - member interface em1 - ! - member pseudowire mpw0 - neighbor lsr-id 1.1.1.1 - pw-id 100 - ! - member pseudowire mpw1 - neighbor lsr-id 4.4.4.4 - neighbor address 4:4:4::4 - pw-id 100 - ! -! -``` - -8 - Run zebra, ospfd and ldpd. - -#### Cisco routers -CE1 (IOS): -``` -interface FastEthernet0/0 - ip address 172.16.1.1 255.255.255.0 - ! -! -``` - -CE2 (IOS): -``` -interface FastEthernet0/0 - ip address 172.16.1.2 255.255.255.0 - ! -! -``` - -CE3 (IOS): -``` -interface FastEthernet0/0 - ip address 172.16.1.3 255.255.255.0 - ! -! -``` - -PE1 - IOS-XE (1): -``` -mpls ldp neighbor 2.2.2.2 password opensourcerouting -mpls ldp neighbor 3.3.3.3 password opensourcerouting -mpls ldp neighbor 4.4.4.4 password opensourcerouting -! -l2vpn vfi context VFI - vpn id 1 - member pseudowire2 - member pseudowire1 -! -bridge-domain 1 - member GigabitEthernet1 service-instance 1 - member vfi VFI -! -interface Loopback1 - ip address 1.1.1.1 255.255.255.255 -! -interface pseudowire1 - encapsulation mpls - neighbor 3.3.3.3 100 -! -interface pseudowire2 - encapsulation mpls - neighbor 4.4.4.4 100 -! -interface GigabitEthernet3 - ip address 10.0.1.1 255.255.255.0 - mpls ip -! -router ospf 1 - network 0.0.0.0 255.255.255.255 area 0 -! -``` - -P - IOS-XR (2): -``` -interface Loopback1 - ipv4 address 2.2.2.2 255.255.255.255 - ipv6 address 2:2:2::2/128 -! -interface GigabitEthernet0/0/0/0 - ipv4 address 10.0.1.2 255.255.255.0 -! -interface GigabitEthernet0/0/0/1 - ipv4 address 10.0.2.2 255.255.255.0 - ipv6 address 2001:db8:2::2/64 - ipv6 enable -! -interface GigabitEthernet0/0/0/2 - ipv4 address 10.0.3.2 255.255.255.0 - ipv6 address 2001:db8:3::2/64 - ipv6 enable -! -router static - address-family ipv6 unicast - 3:3:3::3/128 2001:db8:2::3 - 4:4:4::4/128 2001:db8:3::4 - ! -! -router ospf 1 - router-id 2.2.2.2 - address-family ipv4 unicast - area 0 - interface Loopback1 - ! - interface GigabitEthernet0/0/0/0 - ! - interface GigabitEthernet0/0/0/1 - ! - interface GigabitEthernet0/0/0/2 - ! - ! -! -mpls ldp - router-id 2.2.2.2 - neighbor - 1.1.1.1:0 password clear opensourcerouting - 3.3.3.3:0 password clear opensourcerouting - 4.4.4.4:0 password clear opensourcerouting - ! - address-family ipv4 - ! - address-family ipv6 - discovery transport-address 2:2:2::2 - ! - interface GigabitEthernet0/0/0/0 - address-family ipv4 - ! - ! - interface GigabitEthernet0/0/0/1 - address-family ipv4 - ! - address-family ipv6 - ! - ! - interface GigabitEthernet0/0/0/2 - address-family ipv4 - ! - address-family ipv6 - ! - ! -! -``` - -## Verification - Control Plane - -Using the CLI on the Linux box, the goal is to ensure that everything -is working as expected. - -First, verify that all the required adjacencies and neighborships sessions -were established: - -``` -linux# show mpls ldp discovery -Local LDP Identifier: 4.4.4.4:0 -Discovery Sources: - Interfaces: - eth1: xmit/recv - LDP Id: 3.3.3.3:0, Transport address: 3.3.3.3 - Hold time: 15 sec - LDP Id: 3.3.3.3:0, Transport address: 3:3:3::3 - Hold time: 15 sec - eth2: xmit/recv - LDP Id: 2.2.2.2:0, Transport address: 2.2.2.2 - Hold time: 15 sec - LDP Id: 2.2.2.2:0, Transport address: 2:2:2::2 - Hold time: 15 sec - Targeted Hellos: - 4.4.4.4 -> 1.1.1.1: xmit/recv - LDP Id: 1.1.1.1:0, Transport address: 1.1.1.1 - Hold time: 45 sec - 4:4:4::4 -> 3:3:3::3: xmit/recv - LDP Id: 3.3.3.3:0, Transport address: 3:3:3::3 - Hold time: 45 sec - -linux# show mpls ldp neighbor -Peer LDP Identifier: 1.1.1.1:0 - TCP connection: 4.4.4.4:40921 - 1.1.1.1:646 - Session Holdtime: 180 sec - State: OPERATIONAL; Downstream-Unsolicited - Up time: 00:06:02 - LDP Discovery Sources: - IPv4: - Targeted Hello: 1.1.1.1 - -Peer LDP Identifier: 2.2.2.2:0 - TCP connection: 4:4:4::4:52286 - 2:2:2::2:646 - Session Holdtime: 180 sec - State: OPERATIONAL; Downstream-Unsolicited - Up time: 00:06:02 - LDP Discovery Sources: - IPv4: - Interface: eth2 - IPv6: - Interface: eth2 - -Peer LDP Identifier: 3.3.3.3:0 - TCP connection: 4:4:4::4:60575 - 3:3:3::3:646 - Session Holdtime: 180 sec - State: OPERATIONAL; Downstream-Unsolicited - Up time: 00:05:57 - LDP Discovery Sources: - IPv4: - Interface: eth1 - IPv6: - Targeted Hello: 3:3:3::3 - Interface: eth1 -``` - -Note that the neighborships with the P and PE2 routers were established -over IPv6, since this is the default behavior for dual-stack LSRs, as -specified in RFC 7552. If desired, the **dual-stack transport-connection -prefer ipv4** command can be used to establish these sessions over IPv4 -(the command should be applied an all routers). - -Now, verify that there's a remote label for each PE address: -``` -linux# show mpls ldp binding -1.1.1.1/32 - Local binding: label: 20 - Remote bindings: - Peer Label - ----------------- --------- - 1.1.1.1 imp-null - 2.2.2.2 24000 - 3.3.3.3 20 -2.2.2.2/32 - Local binding: label: 21 - Remote bindings: - Peer Label - ----------------- --------- - 1.1.1.1 18 - 2.2.2.2 imp-null - 3.3.3.3 21 -3.3.3.3/32 - Local binding: label: 22 - Remote bindings: - Peer Label - ----------------- --------- - 1.1.1.1 21 - 2.2.2.2 24003 - 3.3.3.3 imp-null -4.4.4.4/32 - Local binding: label: imp-null - Remote bindings: - Peer Label - ----------------- --------- - 1.1.1.1 22 - 2.2.2.2 24001 - 3.3.3.3 22 -10.0.1.0/24 - Local binding: label: 23 - Remote bindings: - Peer Label - ----------------- --------- - 1.1.1.1 imp-null - 2.2.2.2 imp-null - 3.3.3.3 23 -10.0.2.0/24 - Local binding: label: 24 - Remote bindings: - Peer Label - ----------------- --------- - 1.1.1.1 20 - 2.2.2.2 imp-null - 3.3.3.3 imp-null -10.0.3.0/24 - Local binding: label: imp-null - Remote bindings: - Peer Label - ----------------- --------- - 1.1.1.1 19 - 2.2.2.2 imp-null - 3.3.3.3 24 -10.0.4.0/24 - Local binding: label: imp-null - Remote bindings: - Peer Label - ----------------- --------- - 1.1.1.1 23 - 2.2.2.2 24002 - 3.3.3.3 imp-null -2:2:2::2/128 - Local binding: label: 18 - Remote bindings: - Peer Label - ----------------- --------- - 2.2.2.2 imp-null - 3.3.3.3 18 -3:3:3::3/128 - Local binding: label: 19 - Remote bindings: - Peer Label - ----------------- --------- - 2.2.2.2 24007 -4:4:4::4/128 - Local binding: label: imp-null - Remote bindings: - Peer Label - ----------------- --------- - 2.2.2.2 24006 - 3.3.3.3 19 -2001:db8:2::/64 - Local binding: label: - - Remote bindings: - Peer Label - ----------------- --------- - 2.2.2.2 imp-null - 3.3.3.3 imp-null -2001:db8:3::/64 - Local binding: label: imp-null - Remote bindings: - Peer Label - ----------------- --------- - 2.2.2.2 imp-null -2001:db8:4::/64 - Local binding: label: imp-null - Remote bindings: - Peer Label - ----------------- --------- - 3.3.3.3 imp-null -``` - -Check if the pseudowires are up: -``` -linux# show l2vpn atom vc -Interface Peer ID VC ID Name Status ---------- --------------- ---------- ---------------- ---------- -mpw1 3.3.3.3 100 ENG UP -mpw0 1.1.1.1 100 ENG UP -``` - -Check the label bindings of the pseudowires: -``` -linux# show l2vpn atom binding - Destination Address: 1.1.1.1, VC ID: 100 - Local Label: 25 - Cbit: 1, VC Type: Ethernet, GroupID: 0 - MTU: 1500 - Remote Label: 16 - Cbit: 1, VC Type: Ethernet, GroupID: 0 - MTU: 1500 - Destination Address: 3.3.3.3, VC ID: 100 - Local Label: 26 - Cbit: 1, VC Type: Ethernet, GroupID: 0 - MTU: 1500 - Remote Label: 26 - Cbit: 1, VC Type: Ethernet, GroupID: 0 - MTU: 1500 -``` - -## Verification - Data Plane - -Verify that all the exchanged label mappings were installed in zebra: -``` -linux# show mpls table - Inbound Outbound - Label Type Nexthop Label --------- ------- --------------- -------- - 17 LDP 2001:db8:3::2 3 - 19 LDP 2001:db8:3::2 24005 - 20 LDP 10.0.3.2 24000 - 21 LDP 10.0.3.2 3 - 22 LDP 10.0.3.2 24001 - 23 LDP 10.0.3.2 3 - 24 LDP 10.0.3.2 3 - 25 LDP 10.0.3.2 3 - -linux# show ip route ldp -Codes: K - kernel route, C - connected, S - static, R - RIP, - O - OSPF, I - IS-IS, B - BGP, P - PIM, A - Babel, L - LDP, - > - selected route, * - FIB route - -L>* 1.1.1.1/32 [0/0] via 10.0.3.2, eth2 label 24000 -L>* 3.3.3.3/32 [0/0] via 10.0.3.2, eth2 label 24001 -``` - -Verify that all the exchanged label mappings were installed in the kernel: -``` -$ ip -M ro -17 via inet6 2001:db8:3::2 dev eth2 proto zebra -19 as to 24005 via inet6 2001:db8:3::2 dev eth2 proto zebra -20 as to 24000 via inet 10.0.3.2 dev eth2 proto zebra -21 via inet 10.0.3.2 dev eth2 proto zebra -22 as to 24001 via inet 10.0.3.2 dev eth2 proto zebra -23 via inet 10.0.3.2 dev eth2 proto zebra -24 via inet 10.0.3.2 dev eth2 proto zebra -25 via inet 10.0.3.2 dev eth2 proto zebra -$ -$ ip route | grep mpls -1.1.1.1 encap mpls 24000 via 10.0.3.2 dev eth2 proto zebra metric 20 -3.3.3.3 encap mpls 24001 via 10.0.3.2 dev eth2 proto zebra metric 20 -``` - -Now ping PE1's loopback using lo1's address as a source address: -``` -$ ping -c 5 -I 4.4.4.4 1.1.1.1 -PING 1.1.1.1 (1.1.1.1) from 4.4.4.4 : 56(84) bytes of data. -64 bytes from 1.1.1.1: icmp_seq=1 ttl=253 time=3.02 ms -64 bytes from 1.1.1.1: icmp_seq=2 ttl=253 time=3.13 ms -64 bytes from 1.1.1.1: icmp_seq=3 ttl=253 time=3.19 ms -64 bytes from 1.1.1.1: icmp_seq=4 ttl=253 time=3.07 ms -64 bytes from 1.1.1.1: icmp_seq=5 ttl=253 time=3.27 ms - ---- 1.1.1.1 ping statistics --- -5 packets transmitted, 5 received, 0% packet loss, time 4005ms -rtt min/avg/max/mdev = 3.022/3.140/3.278/0.096 ms -``` - -Verify that the ICMP echo request packets are leaving with the MPLS -label advertised by the P router. Also, verify that the ICMP echo reply -packets are arriving with an explicit-null MPLS label: -``` -# tcpdump -n -i eth2 mpls and icmp -tcpdump: verbose output suppressed, use -v or -vv for full protocol decode -listening on eth2, link-type EN10MB (Ethernet), capture size 262144 bytes -10:01:40.758771 MPLS (label 24000, exp 0, [S], ttl 64) IP 4.4.4.4 > 1.1.1.1: ICMP echo request, id 13370, seq 1, length 64 -10:01:40.761777 MPLS (label 0, exp 0, [S], ttl 254) IP 1.1.1.1 > 4.4.4.4: ICMP echo reply, id 13370, seq 1, length 64 -10:01:41.760343 MPLS (label 24000, exp 0, [S], ttl 64) IP 4.4.4.4 > 1.1.1.1: ICMP echo request, id 13370, seq 2, length 64 -10:01:41.763448 MPLS (label 0, exp 0, [S], ttl 254) IP 1.1.1.1 > 4.4.4.4: ICMP echo reply, id 13370, seq 2, length 64 -10:01:42.761758 MPLS (label 24000, exp 0, [S], ttl 64) IP 4.4.4.4 > 1.1.1.1: ICMP echo request, id 13370, seq 3, length 64 -10:01:42.764924 MPLS (label 0, exp 0, [S], ttl 254) IP 1.1.1.1 > 4.4.4.4: ICMP echo reply, id 13370, seq 3, length 64 -10:01:43.763193 MPLS (label 24000, exp 0, [S], ttl 64) IP 4.4.4.4 > 1.1.1.1: ICMP echo request, id 13370, seq 4, length 64 -10:01:43.766237 MPLS (label 0, exp 0, [S], ttl 254) IP 1.1.1.1 > 4.4.4.4: ICMP echo reply, id 13370, seq 4, length 64 -10:01:44.764552 MPLS (label 24000, exp 0, [S], ttl 64) IP 4.4.4.4 > 1.1.1.1: ICMP echo request, id 13370, seq 5, length 64 -10:01:44.767803 MPLS (label 0, exp 0, [S], ttl 254) IP 1.1.1.1 > 4.4.4.4: ICMP echo reply, id 13370, seq 5, length 64 -``` diff --git a/doc/developer/next-hop-tracking.rst b/doc/developer/next-hop-tracking.rst new file mode 100644 index 0000000000..1d65956f8c --- /dev/null +++ b/doc/developer/next-hop-tracking.rst @@ -0,0 +1,352 @@ +Next Hop Tracking +================== + +Next hop tracking is an optimization feature that reduces the processing time +involved in the BGP bestpath algorithm by monitoring changes to the routing +table. + +Background +----------- + +Recursive routes are of the form: + +:: + + p/m --> n + [Ex: 1.1.0.0/16 --> 2.2.2.2] + +where 'n' itself is resolved through another route as follows: + +:: + + p2/m --> h, interface + [Ex: 2.2.2.0/24 --> 3.3.3.3, eth0] + +Usually, BGP routes are recursive in nature and BGP nexthops get resolved +through an IGP route. IGP usually adds its routes pointing to an interface +(these are called non-recursive routes). + +When BGP receives a recursive route from a peer, it needs to validate the +nexthop. The path is marked valid or invalid based on the reachability status +of the nexthop. Nexthop validation is also important for BGP decision process +as the metric to reach the nexthop is a parameter to best path selection +process. + +As it goes with routing, this is a dynamic process. Route to the nexthop can +change. The nexthop can become unreachable or reachable. In the current BGP +implementation, the nexthop validation is done periodically in the scanner run. +The default scanner run interval is one minute. Every minute, the scanner task +walks the entire BGP table. It checks the validity of each nexthop with Zebra +(the routing table manager) through a request and response message exchange +between BGP and Zebra process. BGP process is blocked for that duration. The +mechanism has two major drawbacks: + +- The scanner task runs to completion. That can potentially starve the other + tasks for long periods of time, based on the BGP table size and number of + nexthops. + +- Convergence around routing changes that affect the nexthops can be long + (around a minute with the default intervals). The interval can be shortened + to achieve faster reaction time, but it makes the first problem worse, with + the scanner task consuming most of the CPU resources. + +The next-hop tracking feature makes this process event-driven. It eliminates +periodic nexthop validation and introduces an asynchronous communication path +between BGP and Zebra for route change notifications that can then be acted +upon. + +Goal +---- + +Stating the obvious, the main goal is to remove the two limitations we +discussed in the previous section. The goals, in a constructive tone, +are the following: + +- **Fairness**: the scanner run should not consume an unjustly high amount of + CPU time. This should give an overall good performance and response time to + other events (route changes, session events, IO/user interface). + +- **Convergence**: BGP must react to nexthop changes instantly and provide + sub-second convergence. This may involve diverting the routes from one + nexthop to another. + +Overview of changes +------------------------ + +The changes are in both BGP and Zebra modules. The short summary is +the following: + +- Zebra implements a registration mechanism by which clients can + register for next hop notification. Consequently, it maintains a + separate table, per (VRF, AF) pair, of next hops and interested + client-list per next hop. + +- When the main routing table changes in Zebra, it evaluates the next + hop table: for each next hop, it checks if the route table + modifications have changed its state. If so, it notifies the + interested clients. + +- BGP is one such client. It registers the next hops corresponding to + all of its received routes/paths. It also threads the paths against + each nexthop structure. + +- When BGP receives a next hop notification from Zebra, it walks the + corresponding path list. It makes them valid or invalid depending + on the next hop notification. It then re-computes best path for the + corresponding destination. This may result in re-announcing those + destinations to peers. + +Design +------ + +Modules +~~~~~~~ + +The core design introduces an "nht" (next hop tracking) module in BGP +and "rnh" (recursive nexthop) module in Zebra. The "nht" module +provides the following APIs: + ++----------------------------+--------------------------------------------------+ +| Function | Action | ++============================+==================================================+ +| bgp_find_or_add_nexthop() | find or add a nexthop in BGP nexthop table | ++----------------------------+--------------------------------------------------+ +| bgp_find_nexthop() | find a nexthop in BGP nexthop table | ++----------------------------+--------------------------------------------------+ +| bgp_parse_nexthop_update() | parse a nexthop update message coming from zebra | ++----------------------------+--------------------------------------------------+ + +The "rnh" module provides the following APIs: + ++----------------------------+----------------------------------------------------------------------------------------------------------+ +| Function | Action | ++============================+==========================================================================================================+ +| zebra_add_rnh() | add a recursive nexthop | ++----------------------------+----------------------------------------------------------------------------------------------------------+ +| zebra_delete_rnh() | delete a recursive nexthop | ++----------------------------+----------------------------------------------------------------------------------------------------------+ +| zebra_lookup_rnh() | lookup a recursive nexthop | ++----------------------------+----------------------------------------------------------------------------------------------------------+ +| zebra_add_rnh_client() | register a client for nexthop notifications against a recursive nexthop | ++----------------------------+----------------------------------------------------------------------------------------------------------+ +| zebra_remove_rnh_client() | remove the client registration for a recursive nexthop | ++----------------------------+----------------------------------------------------------------------------------------------------------+ +| zebra_evaluate_rnh_table() | (re)evaluate the recursive nexthop table (most probably because the main routing table has changed). | ++----------------------------+----------------------------------------------------------------------------------------------------------+ +| zebra_cleanup_rnh_client() | Cleanup a client from the "rnh" module data structures (most probably because the client is going away). | ++----------------------------+----------------------------------------------------------------------------------------------------------+ + +4.2. Control flow + +The next hop registration control flow is the following: + +:: + + <==== BGP Process ====>|<==== Zebra Process ====> + | + receive module nht module | zserv module rnh module + ---------------------------------------------------------------------- + | | | + bgp_update_ | | | + main() | bgp_find_or_add_ | | + | nexthop() | | + | | | + | | zserv_nexthop_ | + | | register() | + | | | zebra_add_rnh() + | | | + + +The next hop notification control flow is the following: + +:: + + <==== Zebra Process ====>|<==== BGP Process ====> + | + rib module rnh module | zebra module nht module + ---------------------------------------------------------------------- + | | | + meta_queue_ | | | + process() | zebra_evaluate_ | | + | rnh_table() | | + | | | + | | bgp_read_nexthop_ | + | | update() | + | | | bgp_parse_ + | | | nexthop_update() + | | | + + +zclient message format +~~~~~~~~~~~~~~~~~~~~~~ + +ZEBRA_NEXTHOP_REGISTER and ZEBRA_NEXTHOP_UNREGISTER messages are +encoded in the following way: + +:: + + . 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | AF | prefix len | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + . Nexthop prefix . + . . + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + . . + . . + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | AF | prefix len | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + . Nexthop prefix . + . . + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + +``ZEBRA_NEXTHOP_UPDATE`` message is encoded as follows: + +:: + + . 0 1 2 3 + 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | AF | prefix len | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + . Nexthop prefix getting resolved . + . . + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | metric | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | #nexthops | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | nexthop type | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + . resolving Nexthop details . + . . + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + . . + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | nexthop type | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + . resolving Nexthop details . + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + +BGP data structure +~~~~~~~~~~~~~~~~~~ +Legend: + +:: + + /\ struct bgp_node: a BGP destination/route/prefix + \/ + + [ ] struct bgp_info: a BGP path (e.g. route received from a peer) + + _ + (_) struct bgp_nexthop_cache: a BGP nexthop + + /\ NULL + \/--+ ^ + | : + +--[ ]--[ ]--[ ]--> NULL + /\ : + \/--+ : + | : + +--[ ]--[ ]--> NULL + : + _ : + (_)........... + + +Zebra data structure +~~~~~~~~~~~~~~~~~~~~ + +RNH table:: + + O + / \ + O O + / \ + O O + + struct rnh + { + u_char flags; + struct route_entry *state; + struct list *client_list; + struct route_node *node; + }; + +User interface changes +~~~~~~~~~~~~~~~~~~~~~~ + +:: + + frr# show ip nht + 3.3.3.3 + resolved via kernel + via 11.0.0.6, swp1 + Client list: bgp(fd 12) + 11.0.0.10 + resolved via connected + is directly connected, swp2 + Client list: bgp(fd 12) + 11.0.0.18 + resolved via connected + is directly connected, swp4 + Client list: bgp(fd 12) + 11.11.11.11 + resolved via kernel + via 10.0.1.2, eth0 + Client list: bgp(fd 12) + + frr# show ip bgp nexthop + Current BGP nexthop cache: + 3.3.3.3 valid [IGP metric 0], #paths 3 + Last update: Wed Oct 16 04:43:49 2013 + + 11.0.0.10 valid [IGP metric 1], #paths 1 + Last update: Wed Oct 16 04:43:51 2013 + + 11.0.0.18 valid [IGP metric 1], #paths 2 + Last update: Wed Oct 16 04:43:47 2013 + + 11.11.11.11 valid [IGP metric 0], #paths 1 + Last update: Wed Oct 16 04:43:47 2013 + + frr# show ipv6 nht + frr# show ip bgp nexthop detail + + frr# debug bgp nht + frr# debug zebra nht + + 6. Sample test cases + + r2----r3 + / \ / + r1----r4 + + - Verify that a change in IGP cost triggers NHT + + shutdown the r1-r4 and r2-r4 links + + no shut the r1-r4 and r2-r4 links and wait for OSPF to come back + up + + We should be back to the original nexthop via r4 now + - Verify that a NH becoming unreachable triggers NHT + + Shutdown all links to r4 + - Verify that a NH becoming reachable triggers NHT + + no shut all links to r4 + +Future work +~~~~~~~~~~~ + +- route-policy for next hop validation (e.g. ignore default route) +- damping for rapid next hop changes +- prioritized handling of nexthop changes ((un)reachability vs. metric + changes) +- handling recursion loop, e.g:: + + 11.11.11.11/32 -> 12.12.12.12 + 12.12.12.12/32 -> 11.11.11.11 + 11.0.0.0/8 -> +- better statistics diff --git a/doc/developer/next-hop-tracking.txt b/doc/developer/next-hop-tracking.txt deleted file mode 100644 index 12ed63947b..0000000000 --- a/doc/developer/next-hop-tracking.txt +++ /dev/null @@ -1,326 +0,0 @@ -0. Introduction - -This is the design specification for next hop tracking feature in -Frr. - -1. Background - -Recursive routes are of the form: - - p/m --> n - [Ex: 1.1.0.0/16 --> 2.2.2.2] - -where 'n' itself is resolved through another route as follows: - - p2/m --> h, interface - [Ex: 2.2.2.0/24 --> 3.3.3.3, eth0] - -Usually, BGP routes are recursive in nature and BGP nexthops get -resolved through an IGP route. IGP usually adds its routes pointing to -an interface (these are called non-recursive routes). - -When BGP receives a recursive route from a peer, it needs to validate -the nexthop. The path is marked valid or invalid based on the -reachability status of the nexthop. Nexthop validation is also -important for BGP decision process as the metric to reach the nexthop -is a parameter to best path selection process. - -As it goes with routing, this is a dynamic process. Route to the -nexthop can change. The nexthop can become unreachable or -reachable. In the current BGP implementation, the nexthop validation -is done periodically in the scanner run. The default scanner run -interval is one minute. Every minute, the scanner task walks the -entire BGP table. It checks the validity of each nexthop with Zebra -(the routing table manager) through a request and response message -exchange between BGP and Zebra process. BGP process is blocked for -that duration. The mechanism has two major drawbacks: - -(1) The scanner task runs to completion. That can potentially starve - the other tasks for long periods of time, based on the BGP table - size and number of nexthops. - -(2) Convergence around routing changes that affect the nexthops can be - long (around a minute with the default intervals). The interval - can be shortened to achieve faster reaction time, but it makes the - first problem worse, with the scanner task consuming most of the - CPU resources. - -"Next hop tracking" feature makes this process event-driven. It -eliminates periodic nexthop validation and introduces an asynchronous -communication path between BGP and Zebra for route change notifications -that can then be acted upon. - -2. Goal - -Stating the obvious, the main goal is to remove the two limitations we -discussed in the previous section. The goals, in a constructive tone, -are the following: - -- fairness: the scanner run should not consume an unjustly high amount - of CPU time. This should give an overall good performance and - response time to other events (route changes, session events, - IO/user interface). - -- convergence: BGP must react to nexthop changes instantly and provide - sub-second convergence. This may involve diverting the routes from - one nexthop to another. - -3. Overview of the changes - -The changes are in both BGP and Zebra modules. The short summary is -the following: - -- Zebra implements a registration mechanism by which clients can - register for next hop notification. Consequently, it maintains a - separate table, per (VRF, AF) pair, of next hops and interested - client-list per next hop. - -- When the main routing table changes in Zebra, it evaluates the next - hop table: for each next hop, it checks if the route table - modifications have changed its state. If so, it notifies the - interested clients. - -- BGP is one such client. It registers the next hops corresponding to - all of its received routes/paths. It also threads the paths against - each nexthop structure. - -- When BGP receives a next hop notification from Zebra, it walks the - corresponding path list. It makes them valid or invalid depending - on the next hop notification. It then re-computes best path for the - corresponding destination. This may result in re-announcing those - destinations to peers. - -4. Design - -4.1. Modules - -The core design introduces an "nht" (next hop tracking) module in BGP -and "rnh" (recursive nexthop) module in Zebra. The "nht" module -provides the following APIs: - -bgp_find_or_add_nexthop() : find or add a nexthop in BGP nexthop table -bgp_find_nexthop() : find a nexthop in BGP nexthop table -bgp_parse_nexthop_update() : parse a nexthop update message coming - from zebra - -The "rnh" module provides the following APIs: - -zebra_add_rnh() : add a recursive nexthop -zebra_delete_rnh() : delete a recursive nexthop -zebra_lookup_rnh() : lookup a recursive nexthop - -zebra_add_rnh_client() : register a client for nexthop notifications - against a recursive nexthop - -zebra_remove_rnh_client(): remove the client registration for a - recursive nexthop - -zebra_evaluate_rnh_table(): (re)evaluate the recursive nexthop table - (most probably because the main routing - table has changed). - -zebra_cleanup_rnh_client(): Cleanup a client from the "rnh" module - data structures (most probably because the - client is going away). - -4.2. Control flow - -The next hop registration control flow is the following: - -<==== BGP Process ====>|<==== Zebra Process ====> - | -receive module nht module | zserv module rnh module ----------------------------------------------------------------------- - | | | -bgp_update_ | | | - main() | bgp_find_or_add_ | | - | nexthop() | | - | | | - | | zserv_nexthop_ | - | | register() | - | | | zebra_add_rnh() - | | | - - -The next hop notification control flow is the following: - -<==== Zebra Process ====>|<==== BGP Process ====> - | -rib module rnh module | zebra module nht module ----------------------------------------------------------------------- - | | | -meta_queue_ | | | - process() | zebra_evaluate_ | | - | rnh_table() | | - | | | - | | bgp_read_nexthop_ | - | | update() | - | | | bgp_parse_ - | | | nexthop_update() - | | | - - -4.3. zclient message format - -ZEBRA_NEXTHOP_REGISTER and ZEBRA_NEXTHOP_UNREGISTER messages are -encoded in the following way: - -/* - * 0 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | AF | prefix len | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * . Nexthop prefix . - * . . - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * . . - * . . - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | AF | prefix len | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * . Nexthop prefix . - * . . - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - */ - -ZEBRA_NEXTHOP_UPDATE message is encoded as follows: - -/* - * 0 1 2 3 - * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | AF | prefix len | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * . Nexthop prefix getting resolved . - * . . - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | metric | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | #nexthops | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | nexthop type | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * . resolving Nexthop details . - * . . - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * . . - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * | nexthop type | - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - * . resolving Nexthop details . - * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ - */ - -4.4. BGP data structure - -Legend: - -/\ struct bgp_node: a BGP destination/route/prefix -\/ - -[ ] struct bgp_info: a BGP path (e.g. route received from a peer) - - _ -(_) struct bgp_nexthop_cache: a BGP nexthop - - - - /\ NULL - \/--+ ^ - | : - +--[ ]--[ ]--[ ]--> NULL - /\ : - \/--+ : - | : - +--[ ]--[ ]--> NULL - : - _ : - (_)............. - - -4.5. Zebra data structure - -rnh table: - - O - / \ - O O - / \ - O O - - struct rnh - { - u_char flags; - struct route_entry *state; - struct list *client_list; - struct route_node *node; - }; - -5. User interface changes - -frr# show ip nht -3.3.3.3 - resolved via kernel - via 11.0.0.6, swp1 - Client list: bgp(fd 12) -11.0.0.10 - resolved via connected - is directly connected, swp2 - Client list: bgp(fd 12) -11.0.0.18 - resolved via connected - is directly connected, swp4 - Client list: bgp(fd 12) -11.11.11.11 - resolved via kernel - via 10.0.1.2, eth0 - Client list: bgp(fd 12) - -frr# show ip bgp nexthop -Current BGP nexthop cache: - 3.3.3.3 valid [IGP metric 0], #paths 3 - Last update: Wed Oct 16 04:43:49 2013 - - 11.0.0.10 valid [IGP metric 1], #paths 1 - Last update: Wed Oct 16 04:43:51 2013 - - 11.0.0.18 valid [IGP metric 1], #paths 2 - Last update: Wed Oct 16 04:43:47 2013 - - 11.11.11.11 valid [IGP metric 0], #paths 1 - Last update: Wed Oct 16 04:43:47 2013 - -frr# show ipv6 nht -frr# show ip bgp nexthop detail - -frr# debug bgp nht -frr# debug zebra nht - -6. Sample test cases - - r2----r3 - / \ / - r1----r4 - -- Verify that a change in IGP cost triggers NHT - + shutdown the r1-r4 and r2-r4 links - + no shut the r1-r4 and r2-r4 links and wait for OSPF to come back - up - + We should be back to the original nexthop via r4 now -- Verify that a NH becoming unreachable triggers NHT - + Shutdown all links to r4 -- Verify that a NH becoming reachable triggers NHT - + no shut all links to r4 - -7. Future work - -- route-policy for next hop validation (e.g. ignore default route) -- damping for rapid next hop changes -- prioritized handling of nexthop changes ((un)reachability vs. metric - changes) -- handling recursion loop, e.g. - 11.11.11.11/32 -> 12.12.12.12 - 12.12.12.12/32 -> 11.11.11.11 - 11.0.0.0/8 -> -- better statistics diff --git a/doc/developer/workflow.rst b/doc/developer/workflow.rst index 38cf0b878d..4ab70ac3c5 100644 --- a/doc/developer/workflow.rst +++ b/doc/developer/workflow.rst @@ -1,67 +1,52 @@ -Developing for FRRouting +Process & Workflow ======================== -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. +FRR is a large project developed by many different groups. This section +documents standards for code style & quality, commit messages, pull requests +and best practices that all contributors are asked to follow. -This 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. +This section 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 +The master Git for FRR resides on `Github +`__. -There is one main branch for development and a release branch for each -major release. +.. figure:: git_branches.png -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. +There is one main branch for development, ``master``. For each major release +(2.0, 3.0 etc) a new release branch is created based on the master. Subsequent +point releases based on a major branch are marked by tagging. Programming language, Tools and Libraries ----------------------------------------- -The core of FRRouting is written in C (gcc or clang supported) and makes +The core of FRR 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 +implemented in Perl and Python. FRR requires the following tools to build distribution packages: automake, autoconf, texinfo, libtool and gawk and various libraries (i.e. libpam and libjson-c). If your contribution requires a new library or other tool, then please highlight this in your description of the change. Also make sure it’s -supported by all FRRouting platform OSes or provide a way to build +supported by all FRR platform OSes or provide a way to build without the library (potentially without the new feature) on the other platforms. -Documentation should be written in Tex (.texi) or Markdown (.md) format -with a preference for Markdown. +Documentation should be written in reStructuredText. Sphinx extensions may be +utilized but pure ReST is preferred where possible. See `Documentation +<#documentation>`__. Mailing lists ------------- -Italicized lists are private. +The FRR development group maintains multiple mailing lists for use by the +community. Italicized lists are private. +----------------------------------+--------------------------------+ | Topic | List | @@ -80,19 +65,31 @@ Italicized lists are private. 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. +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. Submitting Patches and Enhancements ----------------------------------- +FRR accepts patches from two sources: + +- Email (git format-patch) +- Github pull request + +Contributors are highly encouraged to use Github's fork-and-pr workflow. It is +easier for us to review it, test it, try it and discuss it on Github than it is +via email, thus your patch will get more attention more quickly on Github. + +The base branch for new contributions and non-critical bug fixes should be +``master``. Please ensure your pull request is based on this branch when you +submit it. + Pre-submission Checklist ~~~~~~~~~~~~~~~~~~~~~~~~ -- Format code (see `Developer's Guidelines <#developers-guidelines>`__) +- Format code (see `Code Formatting <#developers-guidelines>`__) - Verify and acknowledge license (see `License for contributions <#license-for-contributions>`__) - Ensure you have properly signed off (see `Signing @@ -115,14 +112,14 @@ Pre-submission Checklist License for contributions ~~~~~~~~~~~~~~~~~~~~~~~~~ -FRRouting is under a “GPLv2 or later” license. Any code submitted must +FRR is under a “GPLv2 or later” license. Any code submitted must be released under the same license (preferred) or any license which allows redistribution under this GPLv2 license (eg MIT License). Signing Off ~~~~~~~~~~~ -Code submitted to FRRouting must be signed off. We have the same +Code submitted to FRR must be signed off. We have the same requirements for using the signed-off-by process as the Linux kernel. In short, you must include a signed-off-by tag in every patch. @@ -142,6 +139,8 @@ 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: @@ -171,7 +170,7 @@ 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 +https://github.com/FRR/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. @@ -219,12 +218,9 @@ After submitting your changes - 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). + email, then check status on the Github pull request. - Please notify the development mailing list if you think something - doesn’t work. + doesn't work. - If the tests failed: @@ -253,8 +249,8 @@ After submitting your changes community members. - Your submission is done once it is merged to the master branch. -Developer's Guidelines ----------------------- +Coding Practices & Style +------------------------ Commit messages ~~~~~~~~~~~~~~~ @@ -392,13 +388,12 @@ BSD coding style applies to: 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. +FRR is a large and complex software project developed by many different people +over a long period of time. Without adequate documentation, it can be +exceedingly difficult to understand code segments, APIs and other interfaces. +In the interest of keeping the project healthy and maintainable, you should +make every effort to document your code so that other people can understand +what it does without needing to closely read the code itself. Some specific guidelines that contributors should follow are: @@ -440,10 +435,13 @@ used for. - **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. +functionality please document it in ``doc/``. If you make significant changes +to portions of the codebase covered in the Developer's Manual, please +update the relevant sections. If you add a major feature or introduce a new +API, please document the architecture and API to the best of your abilities in +the Developer's Manual. + +Documentation should be in reStructuredText. Finally, if you come across some code that is undocumented and feel like going above and beyond, document it! We absolutely appreciate and accept diff --git a/doc/ldpd-basic-test-setup.md b/doc/ldpd-basic-test-setup.md new file mode 100644 index 0000000000..b25a2b6d4b --- /dev/null +++ b/doc/ldpd-basic-test-setup.md @@ -0,0 +1,681 @@ +## Topology + +The goal of this test is to verify that the all the basic functionality +of ldpd is working as expected, be it running on Linux or OpenBSD. In +addition to that, more advanced features are also tested, like LDP +sessions over IPv6, MD5 authentication and pseudowire signaling. + +In the topology below there are 3 PE routers, 3 CE routers and one P +router (not attached to any consumer site). + +All routers have IPv4 addresses and OSPF is used as the IGP. The +three routers from the bottom of the picture, P, PE2 and PE3, are also +configured for IPv6 (dual-stack) and static IPv6 routes are used to +provide connectivity among them. + +The three CEs share the same VPLS membership. LDP is used to set up the +LSPs among the PEs and to signal the pseudowires. MD5 authentication is +used to protect all LDP sessions. + +``` + CE1 172.16.1.1/24 + + + | + +---+---+ + | PE1 | + | IOS XE| + | | + +---+---+ + | + | 10.0.1.0/24 + | + +---+---+ + | P | + +------+ IOS XR+------+ + | | | | + | +-------+ | + 10.0.2.0/24 | | 10.0.3.0/24 +2001:db8:2::/64 | | 2001:db8:3::/64 + | | + +---+---+ +---+---+ + | PE2 | | PE3 | + |OpenBSD+-------------+ Linux | + | | | | + +---+---+ 10.0.4.0/24 +---+---+ + | 2001:db8:4::/64 | + + + + 172.16.1.2/24 CE2 CE3 172.16.1.3/24 +``` + +## Configuration + +#### Linux +1 - Enable IPv4/v6 forwarding: +``` +# sysctl -w net.ipv4.ip_forward=1 +# sysctl -w net.ipv6.conf.all.forwarding=1 +``` + +2 - Enable MPLS forwarding: +``` +# modprobe mpls-router +# modprobe mpls-iptunnel +# echo 100000 > /proc/sys/net/mpls/platform_labels +# echo 1 > /proc/sys/net/mpls/conf/eth1/input +# echo 1 > /proc/sys/net/mpls/conf/eth2/input +``` + +3 - Set up the interfaces: +``` +# ip link add name lo1 type dummy +# ip link set dev lo1 up +# ip addr add 4.4.4.4/32 dev lo1 +# ip -6 addr add 4:4:4::4/128 dev lo1 +# ip link set dev eth1 up +# ip addr add 10.0.4.4/24 dev eth1 +# ip -6 addr add 2001:db8:4::4/64 dev eth1 +# ip link set dev eth2 up +# ip addr add 10.0.3.4/24 dev eth2 +# ip -6 addr add 2001:db8:3::4/64 dev eth2 +``` + +4 - Set up the bridge and pseudowire interfaces: +``` +# ip link add type bridge +# ip link set dev bridge0 up +# ip link set dev eth0 up +# ip link set dev eth0 master bridge0 +# ip link add name mpw0 type dummy +# ip link set dev mpw0 up +# ip link set dev mpw0 master bridge0 +# ip link add name mpw1 type dummy +# ip link set dev mpw1 up +# ip link set dev mpw1 master bridge0 +``` + +> NOTE: MPLS support in the Linux kernel is very recent and it still +doesn't support pseudowire interfaces. We are using here dummy interfaces +just to show how the VPLS configuration should look like in the future. + +5 - Add static IPv6 routes for the remote loopbacks: +``` +# ip -6 route add 2:2:2::2/128 via 2001:db8:3::2 +# ip -6 route add 3:3:3::3/128 via 2001:db8:4::3 +``` + +6 - Edit /etc/frr/ospfd.conf: +``` +router ospf + network 4.4.4.4/32 area 0.0.0.0 + network 10.0.3.4/24 area 0.0.0.0 + network 10.0.4.4/24 area 0.0.0.0 +! +``` + +7 - Edit /etc/frr/ldpd.conf: +``` +debug mpls ldp messages recv +debug mpls ldp messages sent +debug mpls ldp zebra +! +mpls ldp + router-id 4.4.4.4 + dual-stack cisco-interop + neighbor 1.1.1.1 password opensourcerouting + neighbor 2.2.2.2 password opensourcerouting + neighbor 3.3.3.3 password opensourcerouting + ! + address-family ipv4 + discovery transport-address 4.4.4.4 + label local advertise explicit-null + ! + interface eth2 + ! + interface eth1 + ! + ! + address-family ipv6 + discovery transport-address 4:4:4::4 + ttl-security disable + ! + interface eth2 + ! + interface eth1 + ! + ! +! +l2vpn ENG type vpls + bridge br0 + member interface eth0 + ! + member pseudowire mpw0 + neighbor lsr-id 1.1.1.1 + pw-id 100 + ! + member pseudowire mpw1 + neighbor lsr-id 3.3.3.3 + neighbor address 3:3:3::3 + pw-id 100 + ! +! +``` + +> NOTE: We have to disable ttl-security under the ipv6 address-family +in order to interoperate with the IOS-XR router. GTSM is mandatory for +LDPv6 but the IOS-XR implementation is not RFC compliant in this regard. + +8 - Run zebra, ospfd and ldpd. + +#### OpenBSD +1 - Enable IPv4/v6 forwarding: +``` +# sysctl net.inet.ip.forwarding=1 +# sysctl net.inet6.ip6.forwarding=1 +``` + +2 - Enable MPLS forwarding: +``` +# ifconfig em2 10.0.2.3/24 mpls +# ifconfig em3 10.0.4.3/24 mpls +``` + +3 - Set up the interfaces: +``` +# ifconfig lo1 alias 3.3.3.3 netmask 255.255.255.255 +# ifconfig lo1 inet6 3:3:3::3/128 +# ifconfig em2 inet6 2001:db8:2::3/64 +# ifconfig em3 inet6 2001:db8:4::3/64 +``` + +4 - Set up the bridge and pseudowire interfaces: +``` +# ifconfig bridge0 create +# ifconfig bridge0 up +# ifconfig em1 up +# ifconfig bridge0 add em1 +# ifconfig mpw0 create +# ifconfig mpw0 up +# ifconfig bridge0 add mpw0 +# ifconfig mpw1 create +# ifconfig mpw1 up +# ifconfig bridge0 add mpw1 +``` + +5 - Add static IPv6 routes for the remote loopbacks: +``` +# route -n add 4:4:4::4/128 2001:db8:4::4 +# route -n add 2:2:2::2/128 2001:db8:2::2 +``` + +6 - Edit /etc/frr/ospfd.conf: +``` +router ospf + network 10.0.2.3/24 area 0 + network 10.0.4.3/24 area 0 + network 3.3.3.3/32 area 0 +! +``` + +7 - Edit /etc/frr/ldpd.conf: +``` +debug mpls ldp messages recv +debug mpls ldp messages sent +debug mpls ldp zebra +! +mpls ldp + router-id 3.3.3.3 + dual-stack cisco-interop + neighbor 1.1.1.1 password opensourcerouting + neighbor 2.2.2.2 password opensourcerouting + neighbor 4.4.4.4 password opensourcerouting + ! + address-family ipv4 + discovery transport-address 3.3.3.3 + label local advertise explicit-null + ! + interface em3 + ! + interface em2 + ! + ! + address-family ipv6 + discovery transport-address 3:3:3::3 + ttl-security disable + ! + interface em3 + ! + interface em2 + ! + ! +! +l2vpn ENG type vpls + bridge br0 + member interface em1 + ! + member pseudowire mpw0 + neighbor lsr-id 1.1.1.1 + pw-id 100 + ! + member pseudowire mpw1 + neighbor lsr-id 4.4.4.4 + neighbor address 4:4:4::4 + pw-id 100 + ! +! +``` + +8 - Run zebra, ospfd and ldpd. + +#### Cisco routers +CE1 (IOS): +``` +interface FastEthernet0/0 + ip address 172.16.1.1 255.255.255.0 + ! +! +``` + +CE2 (IOS): +``` +interface FastEthernet0/0 + ip address 172.16.1.2 255.255.255.0 + ! +! +``` + +CE3 (IOS): +``` +interface FastEthernet0/0 + ip address 172.16.1.3 255.255.255.0 + ! +! +``` + +PE1 - IOS-XE (1): +``` +mpls ldp neighbor 2.2.2.2 password opensourcerouting +mpls ldp neighbor 3.3.3.3 password opensourcerouting +mpls ldp neighbor 4.4.4.4 password opensourcerouting +! +l2vpn vfi context VFI + vpn id 1 + member pseudowire2 + member pseudowire1 +! +bridge-domain 1 + member GigabitEthernet1 service-instance 1 + member vfi VFI +! +interface Loopback1 + ip address 1.1.1.1 255.255.255.255 +! +interface pseudowire1 + encapsulation mpls + neighbor 3.3.3.3 100 +! +interface pseudowire2 + encapsulation mpls + neighbor 4.4.4.4 100 +! +interface GigabitEthernet3 + ip address 10.0.1.1 255.255.255.0 + mpls ip +! +router ospf 1 + network 0.0.0.0 255.255.255.255 area 0 +! +``` + +P - IOS-XR (2): +``` +interface Loopback1 + ipv4 address 2.2.2.2 255.255.255.255 + ipv6 address 2:2:2::2/128 +! +interface GigabitEthernet0/0/0/0 + ipv4 address 10.0.1.2 255.255.255.0 +! +interface GigabitEthernet0/0/0/1 + ipv4 address 10.0.2.2 255.255.255.0 + ipv6 address 2001:db8:2::2/64 + ipv6 enable +! +interface GigabitEthernet0/0/0/2 + ipv4 address 10.0.3.2 255.255.255.0 + ipv6 address 2001:db8:3::2/64 + ipv6 enable +! +router static + address-family ipv6 unicast + 3:3:3::3/128 2001:db8:2::3 + 4:4:4::4/128 2001:db8:3::4 + ! +! +router ospf 1 + router-id 2.2.2.2 + address-family ipv4 unicast + area 0 + interface Loopback1 + ! + interface GigabitEthernet0/0/0/0 + ! + interface GigabitEthernet0/0/0/1 + ! + interface GigabitEthernet0/0/0/2 + ! + ! +! +mpls ldp + router-id 2.2.2.2 + neighbor + 1.1.1.1:0 password clear opensourcerouting + 3.3.3.3:0 password clear opensourcerouting + 4.4.4.4:0 password clear opensourcerouting + ! + address-family ipv4 + ! + address-family ipv6 + discovery transport-address 2:2:2::2 + ! + interface GigabitEthernet0/0/0/0 + address-family ipv4 + ! + ! + interface GigabitEthernet0/0/0/1 + address-family ipv4 + ! + address-family ipv6 + ! + ! + interface GigabitEthernet0/0/0/2 + address-family ipv4 + ! + address-family ipv6 + ! + ! +! +``` + +## Verification - Control Plane + +Using the CLI on the Linux box, the goal is to ensure that everything +is working as expected. + +First, verify that all the required adjacencies and neighborships sessions +were established: + +``` +linux# show mpls ldp discovery +Local LDP Identifier: 4.4.4.4:0 +Discovery Sources: + Interfaces: + eth1: xmit/recv + LDP Id: 3.3.3.3:0, Transport address: 3.3.3.3 + Hold time: 15 sec + LDP Id: 3.3.3.3:0, Transport address: 3:3:3::3 + Hold time: 15 sec + eth2: xmit/recv + LDP Id: 2.2.2.2:0, Transport address: 2.2.2.2 + Hold time: 15 sec + LDP Id: 2.2.2.2:0, Transport address: 2:2:2::2 + Hold time: 15 sec + Targeted Hellos: + 4.4.4.4 -> 1.1.1.1: xmit/recv + LDP Id: 1.1.1.1:0, Transport address: 1.1.1.1 + Hold time: 45 sec + 4:4:4::4 -> 3:3:3::3: xmit/recv + LDP Id: 3.3.3.3:0, Transport address: 3:3:3::3 + Hold time: 45 sec + +linux# show mpls ldp neighbor +Peer LDP Identifier: 1.1.1.1:0 + TCP connection: 4.4.4.4:40921 - 1.1.1.1:646 + Session Holdtime: 180 sec + State: OPERATIONAL; Downstream-Unsolicited + Up time: 00:06:02 + LDP Discovery Sources: + IPv4: + Targeted Hello: 1.1.1.1 + +Peer LDP Identifier: 2.2.2.2:0 + TCP connection: 4:4:4::4:52286 - 2:2:2::2:646 + Session Holdtime: 180 sec + State: OPERATIONAL; Downstream-Unsolicited + Up time: 00:06:02 + LDP Discovery Sources: + IPv4: + Interface: eth2 + IPv6: + Interface: eth2 + +Peer LDP Identifier: 3.3.3.3:0 + TCP connection: 4:4:4::4:60575 - 3:3:3::3:646 + Session Holdtime: 180 sec + State: OPERATIONAL; Downstream-Unsolicited + Up time: 00:05:57 + LDP Discovery Sources: + IPv4: + Interface: eth1 + IPv6: + Targeted Hello: 3:3:3::3 + Interface: eth1 +``` + +Note that the neighborships with the P and PE2 routers were established +over IPv6, since this is the default behavior for dual-stack LSRs, as +specified in RFC 7552. If desired, the **dual-stack transport-connection +prefer ipv4** command can be used to establish these sessions over IPv4 +(the command should be applied an all routers). + +Now, verify that there's a remote label for each PE address: +``` +linux# show mpls ldp binding +1.1.1.1/32 + Local binding: label: 20 + Remote bindings: + Peer Label + ----------------- --------- + 1.1.1.1 imp-null + 2.2.2.2 24000 + 3.3.3.3 20 +2.2.2.2/32 + Local binding: label: 21 + Remote bindings: + Peer Label + ----------------- --------- + 1.1.1.1 18 + 2.2.2.2 imp-null + 3.3.3.3 21 +3.3.3.3/32 + Local binding: label: 22 + Remote bindings: + Peer Label + ----------------- --------- + 1.1.1.1 21 + 2.2.2.2 24003 + 3.3.3.3 imp-null +4.4.4.4/32 + Local binding: label: imp-null + Remote bindings: + Peer Label + ----------------- --------- + 1.1.1.1 22 + 2.2.2.2 24001 + 3.3.3.3 22 +10.0.1.0/24 + Local binding: label: 23 + Remote bindings: + Peer Label + ----------------- --------- + 1.1.1.1 imp-null + 2.2.2.2 imp-null + 3.3.3.3 23 +10.0.2.0/24 + Local binding: label: 24 + Remote bindings: + Peer Label + ----------------- --------- + 1.1.1.1 20 + 2.2.2.2 imp-null + 3.3.3.3 imp-null +10.0.3.0/24 + Local binding: label: imp-null + Remote bindings: + Peer Label + ----------------- --------- + 1.1.1.1 19 + 2.2.2.2 imp-null + 3.3.3.3 24 +10.0.4.0/24 + Local binding: label: imp-null + Remote bindings: + Peer Label + ----------------- --------- + 1.1.1.1 23 + 2.2.2.2 24002 + 3.3.3.3 imp-null +2:2:2::2/128 + Local binding: label: 18 + Remote bindings: + Peer Label + ----------------- --------- + 2.2.2.2 imp-null + 3.3.3.3 18 +3:3:3::3/128 + Local binding: label: 19 + Remote bindings: + Peer Label + ----------------- --------- + 2.2.2.2 24007 +4:4:4::4/128 + Local binding: label: imp-null + Remote bindings: + Peer Label + ----------------- --------- + 2.2.2.2 24006 + 3.3.3.3 19 +2001:db8:2::/64 + Local binding: label: - + Remote bindings: + Peer Label + ----------------- --------- + 2.2.2.2 imp-null + 3.3.3.3 imp-null +2001:db8:3::/64 + Local binding: label: imp-null + Remote bindings: + Peer Label + ----------------- --------- + 2.2.2.2 imp-null +2001:db8:4::/64 + Local binding: label: imp-null + Remote bindings: + Peer Label + ----------------- --------- + 3.3.3.3 imp-null +``` + +Check if the pseudowires are up: +``` +linux# show l2vpn atom vc +Interface Peer ID VC ID Name Status +--------- --------------- ---------- ---------------- ---------- +mpw1 3.3.3.3 100 ENG UP +mpw0 1.1.1.1 100 ENG UP +``` + +Check the label bindings of the pseudowires: +``` +linux# show l2vpn atom binding + Destination Address: 1.1.1.1, VC ID: 100 + Local Label: 25 + Cbit: 1, VC Type: Ethernet, GroupID: 0 + MTU: 1500 + Remote Label: 16 + Cbit: 1, VC Type: Ethernet, GroupID: 0 + MTU: 1500 + Destination Address: 3.3.3.3, VC ID: 100 + Local Label: 26 + Cbit: 1, VC Type: Ethernet, GroupID: 0 + MTU: 1500 + Remote Label: 26 + Cbit: 1, VC Type: Ethernet, GroupID: 0 + MTU: 1500 +``` + +## Verification - Data Plane + +Verify that all the exchanged label mappings were installed in zebra: +``` +linux# show mpls table + Inbound Outbound + Label Type Nexthop Label +-------- ------- --------------- -------- + 17 LDP 2001:db8:3::2 3 + 19 LDP 2001:db8:3::2 24005 + 20 LDP 10.0.3.2 24000 + 21 LDP 10.0.3.2 3 + 22 LDP 10.0.3.2 24001 + 23 LDP 10.0.3.2 3 + 24 LDP 10.0.3.2 3 + 25 LDP 10.0.3.2 3 + +linux# show ip route ldp +Codes: K - kernel route, C - connected, S - static, R - RIP, + O - OSPF, I - IS-IS, B - BGP, P - PIM, A - Babel, L - LDP, + > - selected route, * - FIB route + +L>* 1.1.1.1/32 [0/0] via 10.0.3.2, eth2 label 24000 +L>* 3.3.3.3/32 [0/0] via 10.0.3.2, eth2 label 24001 +``` + +Verify that all the exchanged label mappings were installed in the kernel: +``` +$ ip -M ro +17 via inet6 2001:db8:3::2 dev eth2 proto zebra +19 as to 24005 via inet6 2001:db8:3::2 dev eth2 proto zebra +20 as to 24000 via inet 10.0.3.2 dev eth2 proto zebra +21 via inet 10.0.3.2 dev eth2 proto zebra +22 as to 24001 via inet 10.0.3.2 dev eth2 proto zebra +23 via inet 10.0.3.2 dev eth2 proto zebra +24 via inet 10.0.3.2 dev eth2 proto zebra +25 via inet 10.0.3.2 dev eth2 proto zebra +$ +$ ip route | grep mpls +1.1.1.1 encap mpls 24000 via 10.0.3.2 dev eth2 proto zebra metric 20 +3.3.3.3 encap mpls 24001 via 10.0.3.2 dev eth2 proto zebra metric 20 +``` + +Now ping PE1's loopback using lo1's address as a source address: +``` +$ ping -c 5 -I 4.4.4.4 1.1.1.1 +PING 1.1.1.1 (1.1.1.1) from 4.4.4.4 : 56(84) bytes of data. +64 bytes from 1.1.1.1: icmp_seq=1 ttl=253 time=3.02 ms +64 bytes from 1.1.1.1: icmp_seq=2 ttl=253 time=3.13 ms +64 bytes from 1.1.1.1: icmp_seq=3 ttl=253 time=3.19 ms +64 bytes from 1.1.1.1: icmp_seq=4 ttl=253 time=3.07 ms +64 bytes from 1.1.1.1: icmp_seq=5 ttl=253 time=3.27 ms + +--- 1.1.1.1 ping statistics --- +5 packets transmitted, 5 received, 0% packet loss, time 4005ms +rtt min/avg/max/mdev = 3.022/3.140/3.278/0.096 ms +``` + +Verify that the ICMP echo request packets are leaving with the MPLS +label advertised by the P router. Also, verify that the ICMP echo reply +packets are arriving with an explicit-null MPLS label: +``` +# tcpdump -n -i eth2 mpls and icmp +tcpdump: verbose output suppressed, use -v or -vv for full protocol decode +listening on eth2, link-type EN10MB (Ethernet), capture size 262144 bytes +10:01:40.758771 MPLS (label 24000, exp 0, [S], ttl 64) IP 4.4.4.4 > 1.1.1.1: ICMP echo request, id 13370, seq 1, length 64 +10:01:40.761777 MPLS (label 0, exp 0, [S], ttl 254) IP 1.1.1.1 > 4.4.4.4: ICMP echo reply, id 13370, seq 1, length 64 +10:01:41.760343 MPLS (label 24000, exp 0, [S], ttl 64) IP 4.4.4.4 > 1.1.1.1: ICMP echo request, id 13370, seq 2, length 64 +10:01:41.763448 MPLS (label 0, exp 0, [S], ttl 254) IP 1.1.1.1 > 4.4.4.4: ICMP echo reply, id 13370, seq 2, length 64 +10:01:42.761758 MPLS (label 24000, exp 0, [S], ttl 64) IP 4.4.4.4 > 1.1.1.1: ICMP echo request, id 13370, seq 3, length 64 +10:01:42.764924 MPLS (label 0, exp 0, [S], ttl 254) IP 1.1.1.1 > 4.4.4.4: ICMP echo reply, id 13370, seq 3, length 64 +10:01:43.763193 MPLS (label 24000, exp 0, [S], ttl 64) IP 4.4.4.4 > 1.1.1.1: ICMP echo request, id 13370, seq 4, length 64 +10:01:43.766237 MPLS (label 0, exp 0, [S], ttl 254) IP 1.1.1.1 > 4.4.4.4: ICMP echo reply, id 13370, seq 4, length 64 +10:01:44.764552 MPLS (label 24000, exp 0, [S], ttl 64) IP 4.4.4.4 > 1.1.1.1: ICMP echo request, id 13370, seq 5, length 64 +10:01:44.767803 MPLS (label 0, exp 0, [S], ttl 254) IP 1.1.1.1 > 4.4.4.4: ICMP echo reply, id 13370, seq 5, length 64 +``` -- cgit v1.2.3 From 7bd01bd49b4d399ac6afbb2f127249e25305741d Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Wed, 31 Jan 2018 16:16:07 -0500 Subject: doc: copy conf.py for developer's docs Info extracted will probably prove useful here as well. Signed-off-by: Quentin Young --- doc/developer/conf.py | 64 +++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 55 insertions(+), 9 deletions(-) (limited to 'doc/developer/conf.py') diff --git a/doc/developer/conf.py b/doc/developer/conf.py index 233056666d..1eac6af763 100644 --- a/doc/developer/conf.py +++ b/doc/developer/conf.py @@ -24,7 +24,10 @@ import re # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' +needs_sphinx = '1.0' + +# prolog for various variable substitutions +rst_prolog = '' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom @@ -36,7 +39,7 @@ templates_path = ['_templates'] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: -# source_suffix = ['.rst', '.md'] +# source_suffix = ['.rst'] source_suffix = '.rst' # The encoding of source files. @@ -59,14 +62,51 @@ version = u'?.?' # The full version, including alpha/beta/rc tags. release = u'?.?-?' + +# ----------------------------------------------------------------------------- +# Extract values from codebase for substitution into docs. +# ----------------------------------------------------------------------------- + +# Various installation prefixes. Reasonable defaults are set where possible. +# Values are overridden by logic below. +replace_vars = { + 'AUTHORS': 'Kunihiro Ishiguro, et al.', + 'COPYRIGHT_YEAR': '1999-2005', + 'COPYRIGHT_STR': None, + 'PACKAGE_NAME': project.lower(), + 'PACKAGE_TARNAME': project.lower(), + 'PACKAGE_STRING': None, + 'PACKAGE_URL': 'https://frrouting.org/', + 'PACKAGE_VERSION': None, + 'INSTALL_PREFIX_ETC': None, + 'INSTALL_PREFIX_SBIN': None, + 'INSTALL_PREFIX_STATE': None, + 'INSTALL_PREFIX_MODULES': None, + 'INSTALL_USER': None, + 'INSTALL_GROUP': None, + 'INSTALL_VTY_GROUP': None, +} + +# extract version information, installation location, other stuff we need to +# use when building final documents val = re.compile('^S\["([^"]+)"\]="(.*)"$') with open('../../config.status', 'r') as cfgstatus: for ln in cfgstatus.readlines(): m = val.match(ln) - if m is None: continue - if m.group(1) == 'PACKAGE_VERSION': - release = m.group(2) - version = release.split('-')[0] + if not m or m.group(1) not in replace_vars.keys(): continue + replace_vars[m.group(1)] = m.group(2) + +# manually fill out some of these we can't get from config.status +replace_vars['COPYRIGHT_STR'] = "Copyright (c)" +replace_vars['COPYRIGHT_STR'] += ' {}'.format(replace_vars['COPYRIGHT_YEAR']) +replace_vars['COPYRIGHT_STR'] += ' {}'.format(replace_vars['AUTHORS']) +release = replace_vars['PACKAGE_VERSION'] +version = release.split('-')[0] + +# add substitutions to prolog +for key, value in replace_vars.items(): + rst_prolog += '.. |{0}| replace:: {1}\n'.format(key, value) + # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -231,7 +271,7 @@ latex_elements = { # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - (master_doc, 'FRR.tex', u'FRR Developer\'s Manual', + (master_doc, 'FRR.tex', u'FRR User Manual', u'FRR', 'manual'), ] @@ -261,7 +301,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 Developer\'s Manual', + (master_doc, 'frr', u'FRR User Manual', [author], 1) ] @@ -275,7 +315,7 @@ man_pages = [ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - (master_doc, 'FRR', u'FRR Developer\'s Manual', + (master_doc, 'FRR', u'FRR User Manual', author, 'FRR', 'One line description of project.', 'Miscellaneous'), ] @@ -291,3 +331,9 @@ texinfo_documents = [ # If true, do not generate a @detailmenu in the "Top" node's menu. #texinfo_no_detailmenu = False + +# custom extensions here +def setup(app): + # object type for FRR CLI commands, can be extended to document parent CLI + # node later on + app.add_object_type('clicmd', 'clicmd') -- cgit v1.2.3 From 9de103f0c9b27e2942437978e8854813c55cd128 Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Fri, 2 Feb 2018 15:19:04 -0500 Subject: doc: document documentation Signed-off-by: Quentin Young --- doc/developer/conf.py | 6 +- doc/developer/workflow.rst | 367 ++++++++++++++++++++++++++++----------------- 2 files changed, 234 insertions(+), 139 deletions(-) (limited to 'doc/developer/conf.py') diff --git a/doc/developer/conf.py b/doc/developer/conf.py index 1eac6af763..c3295f88bd 100644 --- a/doc/developer/conf.py +++ b/doc/developer/conf.py @@ -271,7 +271,7 @@ latex_elements = { # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - (master_doc, 'FRR.tex', u'FRR User Manual', + (master_doc, 'FRR.tex', u"FRR Developer's Manual", u'FRR', 'manual'), ] @@ -301,7 +301,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 User Manual', + (master_doc, 'frr', u"FRR Developer's Manual", [author], 1) ] @@ -315,7 +315,7 @@ man_pages = [ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - (master_doc, 'FRR', u'FRR User Manual', + (master_doc, 'FRR', u"FRR Developer's Manual", author, 'FRR', 'One line description of project.', 'Miscellaneous'), ] diff --git a/doc/developer/workflow.rst b/doc/developer/workflow.rst index 88ae7ef761..1f33a51adc 100644 --- a/doc/developer/workflow.rst +++ b/doc/developer/workflow.rst @@ -1,53 +1,21 @@ +.. _process-and-workflow: + +******************* Process & Workflow -======================== +******************* FRR is a large project developed by many different groups. This section documents standards for code style & quality, commit messages, pull requests and best practices that all contributors are asked to follow. -This section is "descriptive/post-factual" in that it documents pratices that -are in use; it is not "definitive/pre-factual" in prescribing practices. This +This chapter is "descriptive/post-factual" in that it documents pratices that +are in use; it is not "definitive/pre-factual" in prescribing practices. This means that when a procedure changes, it is agreed upon, then put into practice, and then documented here. If this document doesn't match reality, it's the document that needs to be updated, not reality. -Git Structure -------------- - -The master Git for FRR resides on `Github -`__. - -.. figure:: ../figures/git_branches.png - :align: right - :alt: merging get branches into a central trunk - - Rough outline of FRR development workflow - -There is one main branch for development, ``master``. For each major release -(2.0, 3.0 etc) a new release branch is created based on the master. Subsequent -point releases based on a major branch are marked by tagging. - -Programming language, Tools and Libraries ------------------------------------------ - -The core of FRR 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. FRR requires the following tools -to build distribution packages: automake, autoconf, texinfo, libtool and -gawk and various libraries (i.e. libpam and libjson-c). - -If your contribution requires a new library or other tool, then please -highlight this in your description of the change. Also make sure it’s -supported by all FRR platform OSes or provide a way to build -without the library (potentially without the new feature) on the other -platforms. - -Documentation should be written in reStructuredText. Sphinx extensions may be -utilized but pure ReST is preferred where possible. See `Documentation -<#documentation>`__. - -Mailing lists -------------- +Mailing Lists +============= The FRR development group maintains multiple mailing lists for use by the community. Italicized lists are private. @@ -66,19 +34,17 @@ community. Italicized lists are private. | *Technical Steering Committee* | tsc@lists.frrouting.org | +----------------------------------+--------------------------------+ -The Development list is used to discuss and document general issues -related to project development and governance. The public Slack -instance, frrouting.slack.com, and weekly technical meetings provide a -higher bandwidth channel for discussions. The results of such -discussions must be reflected in updates, as appropriate, to code (i.e., -merges), `Github <#https://github.com/FRRouting/frr/issues`__ tracked -issues, and for governance or process changes, updates to the -Development list and either this file or information posted at -`https://frrouting.org/ <#https://frrouting.org/>`__. +The Development list is used to discuss and document general issues related to +project development and governance. The public Slack instance, +frrouting.slack.com, and weekly technical meetings provide a higher bandwidth +channel for discussions. The results of such discussions must be reflected in +updates, as appropriate, to code (i.e., merges), `Github issues`_, and for +governance or process changes, updates to the Development list and either this +file or information posted at https://frrouting.org/. 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 @@ -86,7 +52,7 @@ messages by the maintainers. However, you are free to include an update to the changelog with some better description. Submitting Patches and Enhancements ------------------------------------ +=================================== FRR accepts patches from two sources: @@ -102,7 +68,7 @@ The base branch for new contributions and non-critical bug fixes should be submit it. Pre-submission Checklist -~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------ - Format code (see `Code Formatting <#developers-guidelines>`__) - Verify and acknowledge license (see `License for @@ -125,14 +91,14 @@ Pre-submission Checklist feature License for contributions -~~~~~~~~~~~~~~~~~~~~~~~~~ +------------------------- FRR is under a “GPLv2 or later” license. Any code submitted must be released under the same license (preferred) or any license which allows redistribution under this GPLv2 license (eg MIT License). Signing Off -~~~~~~~~~~~ +----------- Code submitted to FRR must be signed off. We have the same requirements for using the signed-off-by process as the Linux kernel. In @@ -181,7 +147,7 @@ all of the following: 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 @@ -190,7 +156,7 @@ 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 @@ -200,7 +166,7 @@ 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 @@ -264,11 +230,47 @@ After submitting your changes community members. - Your submission is done once it is merged to the master branch. +Git Structure +============= + +.. figure:: ../figures/git_branches.png + :align: center + :scale: 55% + :alt: Merging Git branches into a central trunk + + Rough outline of FRR development workflow + +The master Git for FRR resides on `GitHub`_. + +There is one main branch for development, ``master``. For each major release +(2.0, 3.0 etc) a new release branch is created based on the master. Subsequent +point releases based on a major branch are marked by tagging. + +Programming Languages, Tools and Libraries +========================================== + +The core of FRR 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. FRR requires the following tools +to build distribution packages: automake, autoconf, texinfo, libtool and +gawk and various libraries (i.e. libpam and libjson-c). + +If your contribution requires a new library or other tool, then please +highlight this in your description of the change. Also make sure it’s +supported by all FRR platform OSes or provide a way to build +without the library (potentially without the new feature) on the other +platforms. + +Documentation should be written in reStructuredText. Sphinx extensions may be +utilized but pure ReST is preferred where possible. See +:ref:`documentation`. + + Coding Practices & Style ------------------------- +======================== Commit messages -~~~~~~~~~~~~~~~ +--------------- Commit messages should be formatted in the same way as Linux kernel commit messages. The format is roughly @@ -280,15 +282,15 @@ commit messages. The format is roughly 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: +was made. For example, a change in bgpd/rfapi would be formatted as::: -``bgpd: short summary`` + 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. @@ -318,7 +320,7 @@ Preferred form of the header is as follows: #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 @@ -332,7 +334,7 @@ your indented claim immediately after. E.g.: 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. @@ -350,9 +352,6 @@ 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 @@ -370,7 +369,8 @@ 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``:** +For ``master`` +"""""""""""""" BSD coding style applies to: @@ -382,7 +382,8 @@ BSD coding style applies to: - Indents are 4 spaces - Function return types are on their own line -**For ``stable/3.0`` and ``stable/2.0``:** +For ``stable/3.0`` and ``stable/2.0`` +""""""""""""""""""""""""""""""""""""" GNU coding style apply to the following parts: @@ -400,70 +401,8 @@ BSD coding style applies to: - ``ldpd/`` -Documentation -~~~~~~~~~~~~~ - -FRR is a large and complex software project developed by many different people -over a long period of time. Without adequate documentation, it can be -exceedingly difficult to understand code segments, APIs and other interfaces. -In the interest of keeping the project healthy and maintainable, you should -make every effort to document your code so that other people can understand -what it does without needing to closely read the code itself. - -Some specific guidelines that contributors should follow are: - -- Functions exposed in header files should have descriptive comments - above their signatures in the header file. At a minimum, a function - comment should contain information about the return value, - parameters, and a general summary of the function's purpose. - Documentation on parameter values can be omitted if it is (very) - obvious what they are used for. - -Function comments must follow the style for multiline comments laid out -in the kernel style guide. - -Example: - -:: - - /* - * 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 please document it in ``doc/``. If you make significant changes -to portions of the codebase covered in the Developer's Manual, please -update the relevant sections. If you add a major feature or introduce a new -API, please document the architecture and API to the best of your abilities in -the Developer's Manual. - -Documentation should be in reStructuredText. - -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 @@ -495,7 +434,7 @@ 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 @@ -507,7 +446,7 @@ 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. @@ -515,7 +454,7 @@ 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 @@ -551,7 +490,163 @@ 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. + + +.. _documentation: + +Documentation +============= + +FRR uses Sphinx+RST as its documentation system. The document you are currently +reading was generated by Sphinx from RST source in +:file:`doc/developer/workflow.rst`. The documentation is structured as follows: + ++-----------------------+--------------------------------------------------------------+ +| Directory | Contents | ++=======================+==============================================================+ +| :file:`doc/user` | User documentation; configuration guides; protocol overviews | ++-----------------------+--------------------------------------------------------------+ +| :file:`doc/developer` | Developer's documentation; API specs; datastructures; | +| | architecture overviews; project management procedure | ++-----------------------+--------------------------------------------------------------+ +| :file:`doc/manpages` | Source for manpages | ++-----------------------+--------------------------------------------------------------+ +| :file:`doc/figures` | Images and diagrams | ++-----------------------+--------------------------------------------------------------+ + +Each of these directories, with the exception of :file:`doc/figures`, contains +a Sphinx-generated Makefile and configuration script :file:`conf.py` used to +set various document parameters. The makefile can be used for a variety of +targets; invoke `make help` in any of these directories for a listing of +available output formats. For convenience, there is a top-level +:file:`Makefile.am` that has targets for PDF and HTML documentation for both +developer and user documentation, respectively. That makefile is also +responsible for building manual pages packed with distribution builds. + +Indent and styling should follow existing conventions: + +- 3 spaces for indents under directives +- Cross references may contain only lowercase alphanumeric characters and + hyphens ('-') +- Lines wrapped to 80 characters where possible + +Characters for header levels should follow Python documentation guide: + +- ``#`` with overline, for parts +- ``*`` with overline, for chapters +- ``=``, for sections +- ``-``, for subsections +- ``^``, for subsubsections +- ``"``, for paragraphs + +After you have made your changes, please make sure that you can invoke +``make latexpdf`` and ``make html`` with no warnings. + +The documentation is currently incomplete and needs love. If you find a broken +cross-reference, figure, dead hyperlink, style issue or any other nastiness we +gladly accept documentation patches. + +Code +---- + +FRR is a large and complex software project developed by many different people +over a long period of time. Without adequate documentation, it can be +exceedingly difficult to understand code segments, APIs and other interfaces. +In the interest of keeping the project healthy and maintainable, you should +make every effort to document your code so that other people can understand +what it does without needing to closely read the code itself. + +Some specific guidelines that contributors should follow are: + +- Functions exposed in header files should have descriptive comments above + their signatures in the header file. At a minimum, a function comment should + contain information about the return value, parameters, and a general summary + of the function's purpose. Documentation on parameter values can be omitted + if it is (very) obvious what they are used for. + + Function comments must follow the style for multiline comments laid out in + the kernel style guide. + + Example: + + .. code-block:: c + + /* + * Determines whether or not a string is cool. + * + * @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 make significant changes to portions of the codebase covered in the +Developer's Manual, add a major subsystem or feature, or gain arcane mastery of +some undocumented or poorly documented part of the codebase, please document +your work so others can benefit. If you add a major feature or introduce a new +API, please document the architecture and API to the best of your abilities in +the Developer's Manual, using good judgement when choosing where to place it. + +Finally, if you come across some code that is undocumented and feel like +going above and beyond, document it! We absolutely appreciate and accept +patches that document previously undocumented code. + +User +---- + +If you are contributing code that adds significant user-visible functionality +please document how to use it in :file:`doc/user`. Use good judgement when +choosing where to place documentation. For example, instructions on how to use +your implementation of a new BGP draft should go in the BGP chapter instead of +being its own chapter. If you are adding a new protocol daemon, please create a +new chapter. + +When documenting CLI please use a combination of the ``.. index::`` and +``.. clicmd::`` directives. For example, the command :clicmd:`show pony` would +be documented as follows: + +.. code-block:: rest + + .. index:: show pony + .. clicmd:: show pony + + Prints an ASCII pony. Example output::: + + >>\. + /_ )`. + / _)`^)`. _.---. _ + (_,' \ `^-)"" `.\ + | | \ + \ / | + / \ /.___.'\ (\ (_ + < ,"|| \ |`. \`-' + \\ () )| )/ + hjw |_>|> /_] // + /_] /_] + +When documented this way, CLI commands can be cross referenced with the +``:clicmd:`` inline markup like so: + +.. code-block:: rest + + :clicmd:`show pony` + +This is very helpful for users who want to quickly remind themselves what a +particular command does. + +.. _GitHub: https://github.com/frrouting/frr +.. _GitHub issues: https://github.com/frrouting/frr/issues -- cgit v1.2.3 From 5a32c42459ea04b7a8b666745e55528edc57b302 Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Fri, 2 Feb 2018 16:27:00 -0500 Subject: doc: add logos Branding! Signed-off-by: Quentin Young --- doc/developer/conf.py | 6 +++--- doc/figures/frr-logo-icon.png | Bin 0 -> 1609 bytes doc/figures/frr-logo-medium.png | Bin 0 -> 13129 bytes doc/figures/frr-logo-small.png | Bin 0 -> 6175 bytes doc/figures/frr-logo.png | Bin 0 -> 26502 bytes doc/user/conf.py | 6 +++--- 6 files changed, 6 insertions(+), 6 deletions(-) create mode 100644 doc/figures/frr-logo-icon.png create mode 100644 doc/figures/frr-logo-medium.png create mode 100644 doc/figures/frr-logo-small.png create mode 100644 doc/figures/frr-logo.png (limited to 'doc/developer/conf.py') diff --git a/doc/developer/conf.py b/doc/developer/conf.py index c3295f88bd..e4c56f54c3 100644 --- a/doc/developer/conf.py +++ b/doc/developer/conf.py @@ -176,12 +176,12 @@ html_theme = 'sphinx_rtd_theme' # The name of an image file (relative to this directory) to place at the top # of the sidebar. -#html_logo = None +html_logo = '../figures/frr-logo-medium.png' # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. -#html_favicon = None +html_favicon = '../figures/frr-logo-icon.png' # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, @@ -277,7 +277,7 @@ latex_documents = [ # The name of an image file (relative to this directory) to place at the top of # the title page. -#latex_logo = None +latex_logo = '../figures/frr-logo-medium.png' # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. diff --git a/doc/figures/frr-logo-icon.png b/doc/figures/frr-logo-icon.png new file mode 100644 index 0000000000..37973fcf2d Binary files /dev/null and b/doc/figures/frr-logo-icon.png differ diff --git a/doc/figures/frr-logo-medium.png b/doc/figures/frr-logo-medium.png new file mode 100644 index 0000000000..04e18ebf5d Binary files /dev/null and b/doc/figures/frr-logo-medium.png differ diff --git a/doc/figures/frr-logo-small.png b/doc/figures/frr-logo-small.png new file mode 100644 index 0000000000..2a9a2c7fd5 Binary files /dev/null and b/doc/figures/frr-logo-small.png differ diff --git a/doc/figures/frr-logo.png b/doc/figures/frr-logo.png new file mode 100644 index 0000000000..6e66414c3a Binary files /dev/null and b/doc/figures/frr-logo.png differ diff --git a/doc/user/conf.py b/doc/user/conf.py index e79dea0bdf..6aa97de304 100644 --- a/doc/user/conf.py +++ b/doc/user/conf.py @@ -176,12 +176,12 @@ html_theme = 'sphinx_rtd_theme' # The name of an image file (relative to this directory) to place at the top # of the sidebar. -#html_logo = None +html_logo = '../figures/frr-logo-medium.png' # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. -#html_favicon = None +html_favicon = '../figures/frr-logo-icon.png' # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, @@ -277,7 +277,7 @@ latex_documents = [ # The name of an image file (relative to this directory) to place at the top of # the title page. -#latex_logo = None +latex_logo = '../figures/frr-logo-medium.png' # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. -- cgit v1.2.3 From 6c749456224b383a95e717c95cdb6289eb9cb5e4 Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Wed, 7 Feb 2018 19:22:52 -0500 Subject: doc: use python 2.6 format strings Centos 6 only has python 2.6 which requires numerical identifiers for format strings Signed-off-by: Quentin Young --- doc/developer/conf.py | 4 ++-- doc/manpages/conf.py | 6 +++--- doc/user/conf.py | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'doc/developer/conf.py') diff --git a/doc/developer/conf.py b/doc/developer/conf.py index e4c56f54c3..1cb1d45af6 100644 --- a/doc/developer/conf.py +++ b/doc/developer/conf.py @@ -98,8 +98,8 @@ with open('../../config.status', 'r') as cfgstatus: # manually fill out some of these we can't get from config.status replace_vars['COPYRIGHT_STR'] = "Copyright (c)" -replace_vars['COPYRIGHT_STR'] += ' {}'.format(replace_vars['COPYRIGHT_YEAR']) -replace_vars['COPYRIGHT_STR'] += ' {}'.format(replace_vars['AUTHORS']) +replace_vars['COPYRIGHT_STR'] += ' {0}'.format(replace_vars['COPYRIGHT_YEAR']) +replace_vars['COPYRIGHT_STR'] += ' {0}'.format(replace_vars['AUTHORS']) release = replace_vars['PACKAGE_VERSION'] version = release.split('-')[0] diff --git a/doc/manpages/conf.py b/doc/manpages/conf.py index 403e86e55e..6da6ebff0a 100644 --- a/doc/manpages/conf.py +++ b/doc/manpages/conf.py @@ -100,8 +100,8 @@ with open('../../config.status', 'r') as cfgstatus: # manually fill out some of these we can't get from config.status replace_vars['COPYRIGHT_STR'] = "Copyright (c)" -replace_vars['COPYRIGHT_STR'] += ' {}'.format(replace_vars['COPYRIGHT_YEAR']) -replace_vars['COPYRIGHT_STR'] += ' {}'.format(replace_vars['AUTHORS']) +replace_vars['COPYRIGHT_STR'] += ' {0}'.format(replace_vars['COPYRIGHT_YEAR']) +replace_vars['COPYRIGHT_STR'] += ' {0}'.format(replace_vars['AUTHORS']) release = replace_vars['PACKAGE_VERSION'] version = release.split('-')[0] @@ -306,7 +306,7 @@ latex_documents = [ # If true, show URL addresses after external links. #man_show_urls = False -fwfrr = "{} routing engine for use with FRRouting." +fwfrr = "{0} routing engine for use with FRRouting." man_pages = [ ('bgpd', 'bgpd', fwfrr.format("a BGPv4, BGPv4+, BGPv4- "), [], 8), diff --git a/doc/user/conf.py b/doc/user/conf.py index 6aa97de304..bd1bf6c041 100644 --- a/doc/user/conf.py +++ b/doc/user/conf.py @@ -98,8 +98,8 @@ with open('../../config.status', 'r') as cfgstatus: # manually fill out some of these we can't get from config.status replace_vars['COPYRIGHT_STR'] = "Copyright (c)" -replace_vars['COPYRIGHT_STR'] += ' {}'.format(replace_vars['COPYRIGHT_YEAR']) -replace_vars['COPYRIGHT_STR'] += ' {}'.format(replace_vars['AUTHORS']) +replace_vars['COPYRIGHT_STR'] += ' {0}'.format(replace_vars['COPYRIGHT_YEAR']) +replace_vars['COPYRIGHT_STR'] += ' {0}'.format(replace_vars['AUTHORS']) release = replace_vars['PACKAGE_VERSION'] version = release.split('-')[0] -- cgit v1.2.3 From 2f8c365e02d044898c9286b907695d87f1fa0e1b Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Thu, 8 Feb 2018 11:53:49 -0500 Subject: doc: change html theme, add svg logo Signed-off-by: Quentin Young --- doc/developer/conf.py | 10 ++++++---- doc/figures/frr-icon.svg | 39 +++++++++++++++++++++++++++++++++++++++ doc/user/conf.py | 10 ++++++---- 3 files changed, 51 insertions(+), 8 deletions(-) create mode 100644 doc/figures/frr-icon.svg (limited to 'doc/developer/conf.py') diff --git a/doc/developer/conf.py b/doc/developer/conf.py index 1cb1d45af6..7078910289 100644 --- a/doc/developer/conf.py +++ b/doc/developer/conf.py @@ -157,12 +157,14 @@ todo_include_todos = True # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'sphinx_rtd_theme' +html_theme = 'classic' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. -#html_theme_options = {} +html_theme_options = { + 'sidebarbgcolor': '#374249' +} # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = [] @@ -176,7 +178,7 @@ html_theme = 'sphinx_rtd_theme' # The name of an image file (relative to this directory) to place at the top # of the sidebar. -html_logo = '../figures/frr-logo-medium.png' +html_logo = '../figures/frr-icon.svg' # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 @@ -186,7 +188,7 @@ html_favicon = '../figures/frr-logo-icon.png' # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] +#html_static_path = ['_static'] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied diff --git a/doc/figures/frr-icon.svg b/doc/figures/frr-icon.svg new file mode 100644 index 0000000000..f7bdebc62e --- /dev/null +++ b/doc/figures/frr-icon.svg @@ -0,0 +1,39 @@ + +image/svg+xml \ No newline at end of file diff --git a/doc/user/conf.py b/doc/user/conf.py index bd1bf6c041..a9ea4ad90c 100644 --- a/doc/user/conf.py +++ b/doc/user/conf.py @@ -157,12 +157,14 @@ todo_include_todos = True # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'sphinx_rtd_theme' +html_theme = 'classic' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. -#html_theme_options = {} +html_theme_options = { + 'sidebarbgcolor': '#374249' +} # Add any paths that contain custom themes here, relative to this directory. #html_theme_path = [] @@ -176,7 +178,7 @@ html_theme = 'sphinx_rtd_theme' # The name of an image file (relative to this directory) to place at the top # of the sidebar. -html_logo = '../figures/frr-logo-medium.png' +html_logo = '../figures/frr-icon.svg' # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 @@ -186,7 +188,7 @@ html_favicon = '../figures/frr-logo-icon.png' # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] +# html_static_path = ['_static'] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied -- cgit v1.2.3 From b59555c6bf74592c9959a85033e6c56bdac15eae Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Thu, 22 Feb 2018 12:27:12 -0500 Subject: doc: change info file name from FRR -> frr conventions yo Signed-off-by: Quentin Young --- debianpkg/frr-doc.info | 2 +- debianpkg/rules | 4 ++-- doc/Makefile.am | 4 ++-- doc/developer/conf.py | 2 +- doc/user/conf.py | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) (limited to 'doc/developer/conf.py') diff --git a/debianpkg/frr-doc.info b/debianpkg/frr-doc.info index 5fadb0024d..a83255a24f 100644 --- a/debianpkg/frr-doc.info +++ b/debianpkg/frr-doc.info @@ -1 +1 @@ -doc/user/_build/texinfo/FRR.info +doc/user/_build/texinfo/frr.info diff --git a/debianpkg/rules b/debianpkg/rules index 1d98e2099b..14294f54fe 100755 --- a/debianpkg/rules +++ b/debianpkg/rules @@ -140,8 +140,8 @@ override_dh_auto_build: ifeq ($(GENERATE_PDF), 1) dh_auto_build -- -C doc user.pdf endif - rm -vf doc/user/_build/texinfo/FRR.info - dh_auto_build -- -C doc FRR.info + rm -vf doc/user/_build/texinfo/frr.info + dh_auto_build -- -C doc frr.info override_dh_auto_test: diff --git a/doc/Makefile.am b/doc/Makefile.am index 943fba91e2..b822a3c685 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -86,8 +86,8 @@ developer.html: # info target, handled by automake installation install-data-local: frr.info - gzip < user/_build/texinfo/FRR.info > ${infodir}/FRR.info.gz - install-info user/_build/texinfo/FRR.info ${infodir}/dir + gzip < user/_build/texinfo/frr.info > ${infodir}/frr.info.gz + install-info user/_build/texinfo/frr.info ${infodir}/dir # include sources for shipped docs EXTRA_DIST = manpages/defines.rst \ diff --git a/doc/developer/conf.py b/doc/developer/conf.py index 7078910289..3f531c14b0 100644 --- a/doc/developer/conf.py +++ b/doc/developer/conf.py @@ -317,7 +317,7 @@ man_pages = [ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - (master_doc, 'FRR', u"FRR Developer's Manual", + (master_doc, 'frr', u"FRR Developer's Manual", author, 'FRR', 'One line description of project.', 'Miscellaneous'), ] diff --git a/doc/user/conf.py b/doc/user/conf.py index a9ea4ad90c..817a6d83bb 100644 --- a/doc/user/conf.py +++ b/doc/user/conf.py @@ -317,7 +317,7 @@ man_pages = [ # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ - (master_doc, 'FRR', u'FRR User Manual', + (master_doc, 'frr', u'FRR User Manual', author, 'FRR', 'One line description of project.', 'Miscellaneous'), ] -- cgit v1.2.3 From 37ba370b9eb45c2905c9c411f29c8ecf5e0e4c53 Mon Sep 17 00:00:00 2001 From: Quentin Young Date: Wed, 7 Mar 2018 16:28:23 -0500 Subject: doc: change html theme to 'default' Looks like older versions of Sphinx switched around naming for the default themes. Signed-off-by: Quentin Young --- doc/Makefile.am | 5 +++-- doc/developer/conf.py | 2 +- doc/manpages/conf.py | 2 +- doc/user/conf.py | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) (limited to 'doc/developer/conf.py') diff --git a/doc/Makefile.am b/doc/Makefile.am index 62f3ae2b6a..caa909d50d 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -10,7 +10,7 @@ # never built as part of a regular build. They are only built when explicitly # asked for. See comment further down. SUBDIRS = manpages user -AM_MAKEFLAGS = DESTDIR=${DESTDIR} infodir=${infodir} +AM_MAKEFLAGS = DESTDIR=${DESTDIR} infodir=${infodir} doczdir=${abs_srcdir} MANPAGE_BUILDDIR = manpages/_build/man @@ -117,7 +117,8 @@ developer-html: # $ make help # dist tarballs want doc sources -EXTRA_DIST = manpages/defines.rst \ +EXTRA_DIST = frr-sphinx.mk \ + manpages/defines.rst \ manpages/ldpd.rst \ manpages/index.rst \ manpages/bgpd.rst \ diff --git a/doc/developer/conf.py b/doc/developer/conf.py index 3f531c14b0..e2293b2a6b 100644 --- a/doc/developer/conf.py +++ b/doc/developer/conf.py @@ -157,7 +157,7 @@ todo_include_todos = True # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'classic' +html_theme = 'default' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the diff --git a/doc/manpages/conf.py b/doc/manpages/conf.py index 50331b6f0a..a78e1a2c38 100644 --- a/doc/manpages/conf.py +++ b/doc/manpages/conf.py @@ -159,7 +159,7 @@ todo_include_todos = True # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'classic' +html_theme = 'default' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the diff --git a/doc/user/conf.py b/doc/user/conf.py index 817a6d83bb..efe1023740 100644 --- a/doc/user/conf.py +++ b/doc/user/conf.py @@ -157,7 +157,7 @@ todo_include_todos = True # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'classic' +html_theme = 'default' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the -- cgit v1.2.3