From: Quentin Young Date: Fri, 8 Dec 2017 16:47:49 +0000 (-0500) Subject: doc: begin developer's manual X-Git-Tag: frr-5.0-dev~165^2~99 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=d1890d041eae5a4c389321053a1328a277726945;p=mirror%2Ffrr.git 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 --- diff --git a/doc/.gitignore b/doc/.gitignore index 57c66cb4ac..8dada02288 100644 --- a/doc/.gitignore +++ b/doc/.gitignore @@ -35,3 +35,4 @@ stamp-vti *~ *.loT refix +_build diff --git a/doc/Building_FRR_for_LEDE-OpenWRT.md b/doc/Building_FRR_for_LEDE-OpenWRT.md deleted file mode 100644 index cde68dbd0b..0000000000 --- a/doc/Building_FRR_for_LEDE-OpenWRT.md +++ /dev/null @@ -1,96 +0,0 @@ -Building FRR for OpenWRT/LEDE from Git Source -=============================================== - -- for the moment because of cross compile problems, master is not supported, - only upto 3.0 -- LDP can't be built because of missing Perl-XML-LibXML in OpenWRT/LEDE tree - -Prepare build environment -------------------------- - -https://lede-project.org/docs/guide-developer/install-buildsystem - -for - -Ubuntu 12.04LTS: - - sudo apt-get install build-essential subversion git-core \ - libncurses5-dev zlib1g-dev gawk flex quilt libssl-dev xsltproc \ - libxml-parser-perl mercurial bzr ecj cvs unzip - -Ubuntu 64bit: - - sudo apt-get install build-essential subversion libncurses5-dev zlib1g-dev \ - gawk gcc-multilib flex git-core gettext libssl-dev - -Debian 8 Jessie: - - sudo apt-get install build-essential libncurses5-dev gawk git subversion \ - libssl-dev gettext unzip zlib1g-dev file python - -Debian 9 Stretch: - - sudo apt-get install build-essential libncurses5-dev gawk git subversion \ - libssl-dev gettext zlib1g-dev - -Centos x86-64 (some packages require EPEL): - - yum install subversion binutils bzip2 gcc gcc-c++ gawk gettext flex \ - ncurses-devel zlib-devel zlib-static make patch unzip glibc glibc-devel \ - perl-ExtUtils-MakeMaker glibc-static quilt ncurses-libs sed sdcc bison \ - intltool sharutils wget git-core openssl-devel xz - -Fedora 24 - 64Bit: - - dnf install -y subversion binutils bzip2 gcc gcc-c++ gawk gettext git-core \ - unzip ncurses-devel ncurses-compat-libs zlib-devel zlib-static make \ - flex patch perl-ExtUtils-MakeMaker perl-Thread-Queue glibc glibc-devel \ - glibc-static quilt sed sdcc intltool sharutils bison wget openssl-devel - - -Get LEDE Sources (from Git) ---------------------------- - -LEDE and OpenWRT is planned to remerge and won't cover the similar OpenWRT build -As normal user: - git clone https://git.lede-project.org/source.git lede - cd lede - ./scripts/feeds update -a - ./scripts/feeds install -a - cd feeds/routing - git pull origin pull/319/head - ln -s ../../../feeds/routing/frr/ ../../package/feeds/routing/ - cd ../.. - make menuconfig - -Select the needed target then select needed packages in -Network -> Routing and Redirection -> frr, exit and save - - make or make package/frr/compile - -It may be possible that on first build `make package/frr/compile` not to work -and it may be needed to run a `make` for the entire build envronment, add V=s -for debugging - -Work with sources ------------------ - -To update the rc1 version or add other options, the Makefile is found in -feeds/routing/frr - -edit: - PKG_VERSION:= - PKG_SOURCE_VERSION:= - -Usage ------ - -Edit `/usr/sbin/frr.init` and add/remove the daemons name in section DAEMONS= -or don't install unneded packages -For example: zebra bgpd ldpd isisd nhrpd ospfd ospf6d pimd ripd ripngd - -### Enable the serivce - - service frr enable - -### Start the service - - service frr start diff --git a/doc/Building_FRR_on_CentOS6.md b/doc/Building_FRR_on_CentOS6.md deleted file mode 100644 index 10830e5016..0000000000 --- a/doc/Building_FRR_on_CentOS6.md +++ /dev/null @@ -1,174 +0,0 @@ -Building FRR on CentOS 6 from Git Source -======================================== - -(As an alternative to this installation, you may prefer to create a FRR -rpm package yourself and install that package instead. See instructions -in redhat/README.rpm_build.md on how to build a rpm package) - -Instructions are tested with `CentOS 6.8` on `x86_64` platform - -CentOS 6 restrictions: ----------------------- - -- PIMd is not supported on `CentOS 6`. Upgrade to `CentOS 7` if PIMd is - needed -- MPLS is not supported on `CentOS 6`. MPLS requires Linux Kernel 4.5 or - higher (LDP can be built, but may have limited use without MPLS) -- Zebra is unable to detect what bridge/vrf an interface is associcated - with (IFLA_INFO_SLAVE_KIND does not exist in the kernel headers, you - can use a newer kernel + headers to get this functionality) -- frr_reload.py will not work, as this requires Python 2.7, and CentOS 6 - only has 2.6. You can install Python 2.7 via IUS, but it won't work - properly unless you compile and install the ipaddr package for it. - -Install required packages -------------------------- - -Add packages: - - sudo yum install git autoconf automake libtool make gawk \ - readline-devel texinfo net-snmp-devel groff pkgconfig \ - json-c-devel pam-devel flex epel-release perl-XML-LibXML \ - c-ares-devel - -Install newer version of bison (CentOS 6 package source is too old) from -CentOS 7 - - sudo yum install rpm-build - curl -O http://vault.centos.org/7.0.1406/os/Source/SPackages/bison-2.7-4.el7.src.rpm - rpmbuild --rebuild ./bison-2.7-4.el7.src.rpm - sudo yum install ./rpmbuild/RPMS/x86_64/bison-2.7-4.el6.x86_64.rpm - rm -rf rpmbuild - -Install newer version of autoconf and automake (Package versions are too old) - - curl -O http://ftp.gnu.org/gnu/autoconf/autoconf-2.69.tar.gz - tar xvf autoconf-2.69.tar.gz - cd autoconf-2.69 - ./configure --prefix=/usr - make - sudo make install - cd .. - - curl -O http://ftp.gnu.org/gnu/automake/automake-1.15.tar.gz - tar xvf automake-1.15.tar.gz - cd automake-1.15 - ./configure --prefix=/usr - make - sudo make install - cd .. - -Install `Python 2.7` in parallel to default 2.6. -Make sure you've install EPEL (`epel-release` as above). Then install current -`python27`, `python27-devel` and `pytest` - - sudo rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm - sudo rpm -ivh https://centos6.iuscommunity.org/ius-release.rpm - sudo yum install python27 python27-pip python27-devel - sudo pip2.7 install pytest - -Please note that `CentOS 6` needs to keep python pointing to version 2.6 -for `yum` to keep working, so don't create a symlink for python2.7 to python - -Get FRR, compile it and install it (from Git) ---------------------------------------------- - -**This assumes you want to build and install FRR from source and not using -any packages** - -### Add frr groups and user - - sudo groupadd -g 92 frr - sudo groupadd -r -g 85 frrvt - sudo useradd -u 92 -g 92 -M -r -G frrvt -s /sbin/nologin \ - -c "FRR FRRouting suite" -d /var/run/frr frr - -### Download Source, configure and compile it -(You may prefer different options on configure statement. These are just -an example.) - - git clone https://github.com/frrouting/frr.git frr - cd frr - ./bootstrap.sh - ./configure \ - --bindir=/usr/bin \ - --sbindir=/usr/lib/frr \ - --sysconfdir=/etc/frr \ - --libdir=/usr/lib/frr \ - --libexecdir=/usr/lib/frr \ - --localstatedir=/var/run/frr \ - --with-moduledir=/usr/lib/frr/modules \ - --disable-pimd \ - --enable-snmp=agentx \ - --enable-multipath=64 \ - --enable-ospfclient=yes \ - --enable-ospfapi=yes \ - --enable-user=frr \ - --enable-group=frr \ - --enable-vty-group=frrvt \ - --enable-rtadv \ - --disable-exampledir \ - --enable-watchfrr \ - --disable-ldpd \ - --enable-fpm \ - --enable-nhrpd \ - --enable-eigrpd \ - --enable-babeld \ - --with-pkg-git-version \ - --with-pkg-extra-version=-MyOwnFRRVersion - make - make check PYTHON=/usr/bin/python2.7 - sudo make install - -### Create empty FRR configuration files - sudo mkdir /var/log/frr - sudo mkdir /etc/frr - sudo touch /etc/frr/zebra.conf - sudo touch /etc/frr/bgpd.conf - sudo touch /etc/frr/ospfd.conf - sudo touch /etc/frr/ospf6d.conf - sudo touch /etc/frr/isisd.conf - sudo touch /etc/frr/ripd.conf - sudo touch /etc/frr/ripngd.conf - sudo touch /etc/frr/nhrpd.conf - sudo touch /etc/frr/eigrpd.conf - sudo touch /etc/frr/babeld.conf - sudo chown -R frr:frr /etc/frr/ - sudo touch /etc/frr/vtysh.conf - sudo chown frr:frrvt /etc/frr/vtysh.conf - sudo chmod 640 /etc/frr/*.conf - -### Install daemon config file - sudo install -p -m 644 redhat/daemons /etc/frr/ - sudo chown frr:frr /etc/frr/daemons - -### Edit /etc/frr/daemons as needed to select the required daemons - -Look for the section with `watchfrr_enable=...` and `zebra=...` etc. -Enable the daemons as required by changing the value to `yes` - -### Enable IP & IPv6 forwarding - -Edit `/etc/sysctl.conf` and set the following values (ignore the other -settings) - - # Controls IP packet forwarding - net.ipv4.ip_forward = 1 - net.ipv6.conf.all.forwarding=1 - - # Controls source route verification - net.ipv4.conf.default.rp_filter = 0 - -Load the modifed sysctl's on the system: - - sudo sysctl -p /etc/sysctl.d/90-routing-sysctl.conf - -### Add init.d startup files - sudo install -p -m 755 redhat/frr.init /etc/init.d/frr - sudo chkconfig --add frr - -### Enable frr daemon at startup - sudo chkconfig frr on - -### Start FRR manually (or reboot) - sudo /etc/init.d/frr start diff --git a/doc/Building_FRR_on_CentOS7.md b/doc/Building_FRR_on_CentOS7.md deleted file mode 100644 index 787b80fbf7..0000000000 --- a/doc/Building_FRR_on_CentOS7.md +++ /dev/null @@ -1,129 +0,0 @@ -Building FRR on CentOS 7 from Git Source -======================================== - -(As an alternative to this installation, you may prefer to create a FRR -rpm package yourself and install that package instead. See instructions -in redhat/README.rpm_build.md on how to build a rpm package) - -CentOS 7 restrictions: ----------------------- - -- MPLS is not supported on `CentOS 7` with default kernel. MPLS requires - Linux Kernel 4.5 or higher (LDP can be built, but may have limited use - without MPLS) - -Install required packages -------------------------- - -Add packages: - - sudo yum install git autoconf automake libtool make gawk \ - readline-devel texinfo net-snmp-devel groff pkgconfig \ - json-c-devel pam-devel bison flex pytest c-ares-devel \ - perl-XML-LibXML python-devel - -Get FRR, compile it and install it (from Git) ---------------------------------------------- - -**This assumes you want to build and install FRR from source and not using -any packages** - -### Add frr groups and user - - sudo groupadd -g 92 frr - sudo groupadd -r -g 85 frrvt - sudo useradd -u 92 -g 92 -M -r -G frrvt -s /sbin/nologin \ - -c "FRR FRRouting suite" -d /var/run/frr frr - -### Download Source, configure and compile it -(You may prefer different options on configure statement. These are just -an example.) - - git clone https://github.com/frrouting/frr.git frr - cd frr - ./bootstrap.sh - ./configure \ - --bindir=/usr/bin \ - --sbindir=/usr/lib/frr \ - --sysconfdir=/etc/frr \ - --libdir=/usr/lib/frr \ - --libexecdir=/usr/lib/frr \ - --localstatedir=/var/run/frr \ - --with-moduledir=/usr/lib/frr/modules \ - --enable-pimd \ - --enable-snmp=agentx \ - --enable-multipath=64 \ - --enable-ospfclient=yes \ - --enable-ospfapi=yes \ - --enable-user=frr \ - --enable-group=frr \ - --enable-vty-group=frrvt \ - --enable-rtadv \ - --disable-exampledir \ - --enable-watchfrr \ - --disable-ldpd \ - --enable-fpm \ - --enable-nhrpd \ - --enable-eigrpd \ - --enable-babeld \ - --with-pkg-git-version \ - --with-pkg-extra-version=-MyOwnFRRVersion - make - make check - sudo make install - -### Create empty FRR configuration files - sudo mkdir /var/log/frr - sudo mkdir /etc/frr - sudo touch /etc/frr/zebra.conf - sudo touch /etc/frr/bgpd.conf - sudo touch /etc/frr/ospfd.conf - sudo touch /etc/frr/ospf6d.conf - sudo touch /etc/frr/isisd.conf - sudo touch /etc/frr/ripd.conf - sudo touch /etc/frr/ripngd.conf - sudo touch /etc/frr/pimd.conf - sudo touch /etc/frr/nhrpd.conf - sudo touch /etc/frr/eigrpd.conf - sudo touch /etc/frr/babeld.conf - sudo chown -R frr:frr /etc/frr/ - sudo touch /etc/frr/vtysh.conf - sudo chown frr:frrvt /etc/frr/vtysh.conf - sudo chmod 640 /etc/frr/*.conf - -### Install daemon config file - sudo install -p -m 644 redhat/daemons /etc/frr/ - sudo chown frr:frr /etc/frr/daemons - -### Edit /etc/frr/daemons as needed to select the required daemons - -Look for the section with `watchfrr_enable=...` and `zebra=...` etc. -Enable the daemons as required by changing the value to `yes` - -### Enable IP & IPv6 forwarding - -Create a new file `/etc/sysctl.d/90-routing-sysctl.conf` with the -following content: - - # Sysctl for routing - # - # Routing: We need to forward packets - net.ipv4.conf.all.forwarding=1 - net.ipv6.conf.all.forwarding=1 - -Load the modifed sysctl's on the system: - - sudo sysctl -p /etc/sysctl.d/90-routing-sysctl.conf - -### Install frr Service and redhat init files - sudo install -p -m 644 redhat/frr.service /usr/lib/systemd/system/frr.service - sudo install -p -m 755 redhat/frr.init /usr/lib/frr/frr - -### Register the systemd files - sudo systemctl preset frr.service - -### Enable required frr at startup - sudo systemctl enable frr - -### Reboot or start FRR manually - sudo systemctl start frr diff --git a/doc/Building_FRR_on_Debian8.md b/doc/Building_FRR_on_Debian8.md deleted file mode 100644 index a2dbbdb30f..0000000000 --- a/doc/Building_FRR_on_Debian8.md +++ /dev/null @@ -1,131 +0,0 @@ -Building FRR on Debian 8 from Git Source -======================================== - -Debian 8 restrictions: ----------------------- - -- MPLS is not supported on `Debian 8` with default kernel. MPLS requires - Linux Kernel 4.5 or higher (LDP can be built, but may have limited use - without MPLS) - -Install required packages -------------------------- - -Add packages: - - sudo apt-get install git autoconf automake libtool make gawk \ - libreadline-dev texinfo libjson-c-dev pkg-config bison flex \ - python-pip libc-ares-dev python3-dev - -Install newer pytest (>3.0) from pip - - sudo pip install pytest - -Get FRR, compile it and install it (from Git) ---------------------------------------------- - -**This assumes you want to build and install FRR from source and not using -any packages** - -### Add frr groups and user - - sudo addgroup --system --gid 92 frr - sudo addgroup --system --gid 85 frrvty - sudo adduser --system --ingroup frr --home /var/run/frr/ \ - --gecos "FRR suite" --shell /bin/false frr - sudo usermod -a -G frrvty frr - -### Download Source, configure and compile it -(You may prefer different options on configure statement. These are just -an example.) - - git clone https://github.com/frrouting/frr.git frr - cd frr - ./bootstrap.sh - ./configure \ - --enable-exampledir=/usr/share/doc/frr/examples/ \ - --localstatedir=/var/run/frr \ - --sbindir=/usr/lib/frr \ - --sysconfdir=/etc/frr \ - --enable-vtysh \ - --enable-isisd \ - --enable-pimd \ - --enable-watchfrr \ - --enable-ospfclient=yes \ - --enable-ospfapi=yes \ - --enable-multipath=64 \ - --enable-user=frr \ - --enable-group=frr \ - --enable-vty-group=frrvty \ - --enable-configfile-mask=0640 \ - --enable-logfile-mask=0640 \ - --enable-rtadv \ - --enable-fpm \ - --enable-ldpd \ - --with-pkg-git-version \ - --with-pkg-extra-version=-MyOwnFRRVersion - make - make check - sudo make install - -### Create empty FRR configuration files - - sudo install -m 755 -o frr -g frr -d /var/log/frr - sudo install -m 775 -o frr -g frrvty -d /etc/frr - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/zebra.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/bgpd.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospfd.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospf6d.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/isisd.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripd.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripngd.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/pimd.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ldpd.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/nhrpd.conf - sudo install -m 640 -o frr -g frrvty /dev/null /etc/frr/vtysh.conf - -### Enable IP & IPv6 forwarding - -Edit `/etc/sysctl.conf` and uncomment the following values (ignore the -other settings) - - # Uncomment the next line to enable packet forwarding for IPv4 - net.ipv4.ip_forward=1 - - # Uncomment the next line to enable packet forwarding for IPv6 - # Enabling this option disables Stateless Address Autoconfiguration - # based on Router Advertisements for this host - net.ipv6.conf.all.forwarding=1 - -**Reboot** or use `sysctl -p` to apply the same config to the running system - -### Troubleshooting - -**Local state directory** - -The local state directory must exist and have the correct permissions applied -for the frrouting daemons to start. In the above ./configure example the -local state directory is set to /var/run/frr (--localstatedir=/var/run/frr) -Debian considers /var/run/frr to be temporary and this is removed after a -reboot. - -When using a different local state directory you need to create the new -directory and change the ownership to the frr user, for example: - - mkdir /var/opt/frr - chown frr /var/opt/frr - -**Shared library error** - -If you try and start any of the frrouting daemons you may see the below error -due to the frrouting shared library directory not being found: - - ./zebra: error while loading shared libraries: libfrr.so.0: cannot open shared object file: No such file or directory - -The fix is to add the following line to /etc/ld.so.conf which will continue to -reference the library directory after the system reboots. To load the library -directory path immediately run the ldconfig command after adding the line to -the file eg: - - echo include /usr/local/lib >> /etc/ld.so.conf - ldconfig diff --git a/doc/Building_FRR_on_Debian9.md b/doc/Building_FRR_on_Debian9.md deleted file mode 100644 index 1536c25932..0000000000 --- a/doc/Building_FRR_on_Debian9.md +++ /dev/null @@ -1,121 +0,0 @@ -Building FRR on Debian 9 from Git Source -======================================== - -Install required packages -------------------------- - -Add packages: - - sudo apt-get install git autoconf automake libtool make \ - libreadline-dev texinfo libjson-c-dev pkg-config bison flex \ - python-pip libc-ares-dev python3-dev python-pytest - -Get FRR, compile it and install it (from Git) ---------------------------------------------- - -**This assumes you want to build and install FRR from source and not using -any packages** - -### Add frr groups and user - - sudo addgroup --system --gid 92 frr - sudo addgroup --system --gid 85 frrvty - sudo adduser --system --ingroup frr --home /var/run/frr/ \ - --gecos "FRR suite" --shell /bin/false frr - sudo usermod -a -G frrvty frr - -### Download Source, configure and compile it -(You may prefer different options on configure statement. These are just -an example.) - - git clone https://github.com/frrouting/frr.git frr - cd frr - git checkout stable/3.0 - ./bootstrap.sh - ./configure \ - --enable-exampledir=/usr/share/doc/frr/examples/ \ - --localstatedir=/var/run/frr \ - --sbindir=/usr/lib/frr \ - --sysconfdir=/etc/frr \ - --enable-vtysh \ - --enable-isisd \ - --enable-pimd \ - --enable-watchfrr \ - --enable-ospfclient=yes \ - --enable-ospfapi=yes \ - --enable-multipath=64 \ - --enable-user=frr \ - --enable-group=frr \ - --enable-vty-group=frrvty \ - --enable-configfile-mask=0640 \ - --enable-logfile-mask=0640 \ - --enable-rtadv \ - --enable-fpm \ - --enable-ldpd \ - --with-pkg-git-version \ - --with-pkg-extra-version=-MyOwnFRRVersion - make - make check - sudo make install - -### Create empty FRR configuration files - - sudo install -m 755 -o frr -g frr -d /var/log/frr - sudo install -m 775 -o frr -g frrvty -d /etc/frr - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/zebra.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/bgpd.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospfd.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospf6d.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/isisd.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripd.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripngd.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/pimd.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ldpd.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/nhrpd.conf - sudo install -m 640 -o frr -g frrvty /dev/null /etc/frr/vtysh.conf - -### Enable IP & IPv6 forwarding - -Edit `/etc/sysctl.conf` and uncomment the following values (ignore the -other settings) - - # Uncomment the next line to enable packet forwarding for IPv4 - net.ipv4.ip_forward=1 - - # Uncomment the next line to enable packet forwarding for IPv6 - # Enabling this option disables Stateless Address Autoconfiguration - # based on Router Advertisements for this host - net.ipv6.conf.all.forwarding=1 - -**Reboot** or use `sysctl -p` to apply the same config to the running system - -### Troubleshooting - -**Local state directory** - -The local state directory must exist and have the correct permissions applied -for the frrouting daemons to start. In the above ./configure example the -local state directory is set to /var/run/frr (--localstatedir=/var/run/frr) -Debian considers /var/run/frr to be temporary and this is removed after a -reboot. - -When using a different local state directory you need to create the new -directory and change the ownership to the frr user, for example: - - mkdir /var/opt/frr - chown frr /var/opt/frr - -**Shared library error** - -If you try and start any of the frrouting daemons you may see the below error -due to the frrouting shared library directory not being found: - - ./zebra: error while loading shared libraries: libfrr.so.0: cannot open shared object file: No such file or directory - -The fix is to add the following line to /etc/ld.so.conf which will continue to -reference the library directory after the system reboots. To load the library -directory path immediately run the ldconfig command after adding the line to -the file eg: - - echo include /usr/local/lib >> /etc/ld.so.conf - ldconfig diff --git a/doc/Building_FRR_on_Fedora24.md b/doc/Building_FRR_on_Fedora24.md deleted file mode 100644 index 0070fd1534..0000000000 --- a/doc/Building_FRR_on_Fedora24.md +++ /dev/null @@ -1,138 +0,0 @@ -Building FRR on Fedora 24 from Git Source -========================================= - -(As an alternative to this installation, you may prefer to create a FRR -rpm package yourself and install that package instead. See instructions -in redhat/README.rpm_build.md on how to build a rpm package) - -Install required packages -------------------------- - -Add packages: - - sudo dnf install git autoconf automake libtool make gawk \ - readline-devel texinfo net-snmp-devel groff pkgconfig \ - json-c-devel pam-devel perl-XML-LibXML pytest bison flex \ - c-ares-devel python3-devel - -Get FRR, compile it and install it (from Git) ---------------------------------------------- - -**This assumes you want to build and install FRR from source and not -using any packages** - -### Add frr groups and user - - sudo groupadd -g 92 frr - sudo groupadd -r -g 85 frrvt - sudo useradd -u 92 -g 92 -M -r -G frrvt -s /sbin/nologin \ - -c "FRR FRRouting suite" -d /var/run/frr frr - -### Download Source, configure and compile it -(You may prefer different options on configure statement. These are just -an example.) - - git clone https://github.com/frrouting/frr.git frr - cd frr - ./bootstrap.sh - ./configure \ - --bindir=/usr/bin \ - --sbindir=/usr/lib/frr \ - --sysconfdir=/etc/frr \ - --libdir=/usr/lib/frr \ - --libexecdir=/usr/lib/frr \ - --localstatedir=/var/run/frr \ - --with-moduledir=/usr/lib/frr/modules \ - --enable-pimd \ - --enable-snmp=agentx \ - --enable-multipath=64 \ - --enable-ospfclient=yes \ - --enable-ospfapi=yes \ - --enable-user=frr \ - --enable-group=frr \ - --enable-vty-group=frrvt \ - --enable-rtadv \ - --disable-exampledir \ - --enable-watchfrr \ - --enable-ldpd \ - --enable-fpm \ - --enable-nhrpd \ - --enable-eigrpd \ - --enable-babeld \ - --with-pkg-git-version \ - --with-pkg-extra-version=-MyOwnFRRVersion - make - make check - sudo make install - -### Create empty FRR configuration files - sudo mkdir /var/log/frr - sudo mkdir /etc/frr - sudo touch /etc/frr/zebra.conf - sudo touch /etc/frr/bgpd.conf - sudo touch /etc/frr/ospfd.conf - sudo touch /etc/frr/ospf6d.conf - sudo touch /etc/frr/isisd.conf - sudo touch /etc/frr/ripd.conf - sudo touch /etc/frr/ripngd.conf - sudo touch /etc/frr/pimd.conf - sudo touch /etc/frr/ldpd.conf - sudo touch /etc/frr/nhrpd.conf - sudo touch /etc/frr/eigrpd.conf - sudo touch /etc/frr/babeld.conf - sudo chown -R frr:frr /etc/frr/ - sudo touch /etc/frr/vtysh.conf - sudo chown frr:frrvt /etc/frr/vtysh.conf - sudo chmod 640 /etc/frr/*.conf - -### Install daemon config file - sudo install -p -m 644 redhat/daemons /etc/frr/ - sudo chown frr:frr /etc/frr/daemons - -### Edit /etc/frr/daemons as needed to select the required daemons - -Look for the section with `watchfrr_enable=...` and `zebra=...` etc. -Enable the daemons as required by changing the value to `yes` - -### Enable IP & IPv6 forwarding (and MPLS) - -Create a new file `/etc/sysctl.d/90-routing-sysctl.conf` with the -following content: -(Please make sure to list all interfaces with required MPLS similar -to `net.mpls.conf.eth0.input=1`) - - # Sysctl for routing - # - # Routing: We need to forward packets - net.ipv4.conf.all.forwarding=1 - net.ipv6.conf.all.forwarding=1 - # - # Enable MPLS Label processing on all interfaces - net.mpls.conf.eth0.input=1 - net.mpls.conf.eth1.input=1 - net.mpls.conf.eth2.input=1 - net.mpls.platform_labels=100000 - -Load the modifed sysctl's on the system: - - sudo sysctl -p /etc/sysctl.d/90-routing-sysctl.conf - -Create a new file `/etc/modules-load.d/mpls.conf` with the following content: - - # Load MPLS Kernel Modules - mpls-router - mpls-iptunnel - -And load the kernel modules on the running system: - - sudo modprobe mpls-router mpls-iptunnel - -### Install frr Service and redhat init files - sudo install -p -m 644 redhat/frr.service /usr/lib/systemd/system/frr.service - sudo install -p -m 755 redhat/frr.init /usr/lib/frr/frr - -### Enable required frr at startup - sudo systemctl enable frr - -### Reboot or start FRR manually - sudo systemctl start frr diff --git a/doc/Building_FRR_on_FreeBSD10.md b/doc/Building_FRR_on_FreeBSD10.md deleted file mode 100644 index ccae83a667..0000000000 --- a/doc/Building_FRR_on_FreeBSD10.md +++ /dev/null @@ -1,94 +0,0 @@ -Building FRR on FreeBSD 10 from Git Source -========================================== - -FreeBSD 10 restrictions: ------------------------- - -- MPLS is not supported on `FreeBSD`. MPLS requires a Linux Kernel - (4.5 or higher). LDP can be built, but may have limited use - without MPLS - -Install required packages -------------------------- - -Add packages: -(Allow the install of the package managment tool if this is first package -install and asked) - - pkg install git autoconf automake libtool gmake gawk json-c pkgconf \ - bison flex py27-pytest c-ares python3 - -Make sure there is no /usr/bin/flex preinstalled (and use the newly -installed in /usr/local/bin): -(FreeBSD frequently provides a older flex as part of the base OS which -takes preference in path) - - rm -f /usr/bin/flex - -Get FRR, compile it and install it (from Git) ---------------------------------------------- - -**This assumes you want to build and install FRR from source and not -using any packages** - -### Add frr group and user - - pw groupadd frr -g 101 - pw groupadd frrvty -g 102 - pw adduser frr -g 101 -u 101 -G 102 -c "FRR suite" \ - -d /usr/local/etc/frr -s /usr/sbin/nologin - -(You may prefer different options on configure statement. These are just -an example) - - git clone https://github.com/frrouting/frr.git frr - cd frr - ./bootstrap.sh - export MAKE=gmake - export LDFLAGS="-L/usr/local/lib" - export CPPFLAGS="-I/usr/local/include" - ./configure \ - --sysconfdir=/usr/local/etc/frr \ - --enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \ - --localstatedir=/var/run/frr \ - --prefix=/usr/local \ - --enable-ospfclient=yes \ - --enable-ospfapi=yes \ - --enable-multipath=64 \ - --enable-user=frr \ - --enable-group=frr \ - --enable-vty-group=frrvty \ - --enable-configfile-mask=0640 \ - --enable-logfile-mask=0640 \ - --enable-rtadv \ - --enable-fpm \ - --with-pkg-git-version \ - --with-pkg-extra-version=-MyOwnFRRVersion - gmake - gmake check - sudo gmake install - -### Create empty FRR configuration files - sudo mkdir /usr/local/etc/frr - sudo touch /usr/local/etc/frr/zebra.conf - sudo touch /usr/local/etc/frr/bgpd.conf - sudo touch /usr/local/etc/frr/ospfd.conf - sudo touch /usr/local/etc/frr/ospf6d.conf - sudo touch /usr/local/etc/frr/isisd.conf - sudo touch /usr/local/etc/frr/ripd.conf - sudo touch /usr/local/etc/frr/ripngd.conf - sudo touch /usr/local/etc/frr/pimd.conf - sudo chown -R frr:frr /usr/local/etc/frr - sudo touch /usr/local/etc/frr/vtysh.conf - sudo chown frr:frrvty /usr/local/etc/frr/vtysh.conf - sudo chmod 640 /usr/local/etc/frr/*.conf - -### Enable IP & IPv6 forwarding - -Add the following lines to the end of `/etc/sysctl.conf`: - - # Routing: We need to forward packets - net.inet.ip.forwarding=1 - net.inet6.ip6.forwarding=1 - -**Reboot** or use `sysctl` to apply the same config to the running system diff --git a/doc/Building_FRR_on_FreeBSD11.md b/doc/Building_FRR_on_FreeBSD11.md deleted file mode 100644 index 71ccd149ff..0000000000 --- a/doc/Building_FRR_on_FreeBSD11.md +++ /dev/null @@ -1,94 +0,0 @@ -Building FRR on FreeBSD 11 from Git Source -========================================== - -FreeBSD 11 restrictions: ------------------------- - -- MPLS is not supported on `FreeBSD`. MPLS requires a Linux Kernel - (4.5 or higher). LDP can be built, but may have limited use - without MPLS - -Install required packages -------------------------- - -Add packages: -(Allow the install of the package managment tool if this is first package -install and asked) - - pkg install git autoconf automake libtool gmake gawk json-c pkgconf \ - bison flex py27-pytest c-ares python3 - -Make sure there is no /usr/bin/flex preinstalled (and use the newly -installed in /usr/local/bin): -(FreeBSD frequently provides a older flex as part of the base OS which -takes preference in path) - - rm -f /usr/bin/flex - -Get FRR, compile it and install it (from Git) ---------------------------------------------- - -**This assumes you want to build and install FRR from source and not -using any packages** - -### Add frr group and user - - pw groupadd frr -g 101 - pw groupadd frrvty -g 102 - pw adduser frr -g 101 -u 101 -G 102 -c "FRR suite" \ - -d /usr/local/etc/frr -s /usr/sbin/nologin - -(You may prefer different options on configure statement. These are just -an example) - - git clone https://github.com/frrouting/frr.git frr - cd frr - ./bootstrap.sh - export MAKE=gmake - export LDFLAGS="-L/usr/local/lib" - export CPPFLAGS="-I/usr/local/include" - ./configure \ - --sysconfdir=/usr/local/etc/frr \ - --enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \ - --localstatedir=/var/run/frr \ - --prefix=/usr/local \ - --enable-ospfclient=yes \ - --enable-ospfapi=yes \ - --enable-multipath=64 \ - --enable-user=frr \ - --enable-group=frr \ - --enable-vty-group=frrvty \ - --enable-configfile-mask=0640 \ - --enable-logfile-mask=0640 \ - --enable-rtadv \ - --enable-fpm \ - --with-pkg-git-version \ - --with-pkg-extra-version=-MyOwnFRRVersion - gmake - gmake check - sudo gmake install - -### Create empty FRR configuration files - sudo mkdir /usr/local/etc/frr - sudo touch /usr/local/etc/frr/zebra.conf - sudo touch /usr/local/etc/frr/bgpd.conf - sudo touch /usr/local/etc/frr/ospfd.conf - sudo touch /usr/local/etc/frr/ospf6d.conf - sudo touch /usr/local/etc/frr/isisd.conf - sudo touch /usr/local/etc/frr/ripd.conf - sudo touch /usr/local/etc/frr/ripngd.conf - sudo touch /usr/local/etc/frr/pimd.conf - sudo chown -R frr:frr /usr/local/etc/frr - sudo touch /usr/local/etc/frr/vtysh.conf - sudo chown frr:frrvty /usr/local/etc/frr/vtysh.conf - sudo chmod 640 /usr/local/etc/frr/*.conf - -### Enable IP & IPv6 forwarding - -Add the following lines to the end of `/etc/sysctl.conf`: - - # Routing: We need to forward packets - net.inet.ip.forwarding=1 - net.inet6.ip6.forwarding=1 - -**Reboot** or use `sysctl` to apply the same config to the running system diff --git a/doc/Building_FRR_on_FreeBSD9.md b/doc/Building_FRR_on_FreeBSD9.md deleted file mode 100644 index 8a09d8a4cc..0000000000 --- a/doc/Building_FRR_on_FreeBSD9.md +++ /dev/null @@ -1,102 +0,0 @@ -Building FRR on FreeBSD 9 from Git Source -========================================= - -FreeBSD 9 restrictions: ------------------------ - -- MPLS is not supported on `FreeBSD`. MPLS requires a Linux Kernel - (4.5 or higher). LDP can be built, but may have limited use - without MPLS - -Install required packages -------------------------- - -Add packages: -(Allow the install of the package managment tool if this is first package -install and asked) - - pkg install -y git autoconf automake libtool gmake gawk \ - pkgconf texinfo json-c bison flex py27-pytest c-ares \ - python3 - -Make sure there is no /usr/bin/flex preinstalled (and use the newly -installed in /usr/local/bin): -(FreeBSD frequently provides a older flex as part of the base OS which -takes preference in path) - - rm -f /usr/bin/flex - -For building with clang (instead of gcc), upgrade clang from 3.4 default to 3.6 *This is needed to build FreeBSD packages as well - for packages clang is default* (Clang 3.4 as shipped with FreeBSD 9 crashes during compile) - - pkg install clang36 - pkg delete clang34 - mv /usr/bin/clang /usr/bin/clang34 - ln -s /usr/local/bin/clang36 /usr/bin/clang - -Get FRR, compile it and install it (from Git) ---------------------------------------------- - -**This assumes you want to build and install FRR from source and not -using any packages** - -### Add frr group and user - - pw groupadd frr -g 101 - pw groupadd frrvty -g 102 - pw adduser frr -g 101 -u 101 -G 102 -c "FRR suite" \ - -d /usr/local/etc/frr -s /usr/sbin/nologin - -(You may prefer different options on configure statement. These are just -an example) - - git clone https://github.com/frrouting/frr.git frr - cd frr - ./bootstrap.sh - export MAKE=gmake - export LDFLAGS="-L/usr/local/lib" - export CPPFLAGS="-I/usr/local/include" - ./configure \ - --sysconfdir=/usr/local/etc/frr \ - --enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \ - --localstatedir=/var/run/frr \ - --prefix=/usr/local \ - --enable-ospfclient=yes \ - --enable-ospfapi=yes \ - --enable-multipath=64 \ - --enable-user=frr \ - --enable-group=frr \ - --enable-vty-group=frrvty \ - --enable-configfile-mask=0640 \ - --enable-logfile-mask=0640 \ - --enable-rtadv \ - --enable-fpm \ - --with-pkg-git-version \ - --with-pkg-extra-version=-MyOwnFRRVersion - gmake - gmake check - sudo gmake install - -### Create empty FRR configuration files - sudo mkdir /usr/local/etc/frr - sudo touch /usr/local/etc/frr/zebra.conf - sudo touch /usr/local/etc/frr/bgpd.conf - sudo touch /usr/local/etc/frr/ospfd.conf - sudo touch /usr/local/etc/frr/ospf6d.conf - sudo touch /usr/local/etc/frr/isisd.conf - sudo touch /usr/local/etc/frr/ripd.conf - sudo touch /usr/local/etc/frr/ripngd.conf - sudo touch /usr/local/etc/frr/pimd.conf - sudo chown -R frr:frr /usr/local/etc/frr - sudo touch /usr/local/etc/frr/vtysh.conf - sudo chown frr:frrvty /usr/local/etc/frr/vtysh.conf - sudo chmod 640 /usr/local/etc/frr/*.conf - -### Enable IP & IPv6 forwarding - -Add the following lines to the end of `/etc/sysctl.conf`: - - # Routing: We need to forward packets - net.inet.ip.forwarding=1 - net.inet6.ip6.forwarding=1 - -**Reboot** or use `sysctl` to apply the same config to the running system diff --git a/doc/Building_FRR_on_NetBSD6.md b/doc/Building_FRR_on_NetBSD6.md deleted file mode 100644 index 4fe7109bcd..0000000000 --- a/doc/Building_FRR_on_NetBSD6.md +++ /dev/null @@ -1,115 +0,0 @@ -Building FRR on NetBSD 6 from Git Source -======================================== - -NetBSD 6 restrictions: ----------------------- - -- MPLS is not supported on `NetBSD`. MPLS requires a Linux Kernel - (4.5 or higher). LDP can be built, but may have limited use - without MPLS - -Install required packages -------------------------- -Configure Package location: - - PKG_PATH="ftp://ftp.NetBSD.org/pub/pkgsrc/packages/NetBSD/`uname -m`/`uname -r`/All" - export PKG_PATH - -Add packages: - - sudo pkg_add git autoconf automake libtool gmake gawk openssl \ - pkg-config json-c python27 py27-test python35 - -Install SSL Root Certificates (for git https access): - - sudo pkg_add mozilla-rootcerts - sudo touch /etc/openssl/openssl.cnf - sudo mozilla-rootcerts install - -Select default Python and py.test - - sudo ln -s /usr/pkg/bin/python2.7 /usr/bin/python - sudo ln -s /usr/pkg/bin/py.test-2.7 /usr/bin/py.test - -Get FRR, compile it and install it (from Git) ------------------------------------------------- - -### Add frr groups and user - - sudo groupadd -g 92 frr - sudo groupadd -g 93 frrvty - sudo useradd -g 92 -u 92 -G frrvty -c "FRR suite" \ - -d /nonexistent -s /sbin/nologin frr - -### Download Source, configure and compile it -(You may prefer different options on configure statement. These are just -an example) - - git clone https://github.com/frrouting/frr.git frr - cd frr - ./bootstrap.sh - MAKE=gmake - export LDFLAGS="-L/usr/pkg/lib -R/usr/pkg/lib" - export CPPFLAGS="-I/usr/pkg/include" - ./configure \ - --sysconfdir=/usr/pkg/etc/frr \ - --enable-exampledir=/usr/pkg/share/examples/frr \ - --enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \ - --localstatedir=/var/run/frr \ - --enable-ospfclient=yes \ - --enable-ospfapi=yes \ - --enable-multipath=64 \ - --enable-user=frr \ - --enable-group=frr \ - --enable-vty-group=frrvty \ - --enable-configfile-mask=0640 \ - --enable-logfile-mask=0640 \ - --enable-rtadv \ - --enable-fpm \ - --with-pkg-git-version \ - --with-pkg-extra-version=-MyOwnFRRVersion - gmake - gmake check - sudo gmake install - -### Create empty FRR configuration files - sudo mkdir /var/log/frr - sudo mkdir /usr/pkg/etc/frr - sudo touch /usr/pkg/etc/frr/zebra.conf - sudo touch /usr/pkg/etc/frr/bgpd.conf - sudo touch /usr/pkg/etc/frr/ospfd.conf - sudo touch /usr/pkg/etc/frr/ospf6d.conf - sudo touch /usr/pkg/etc/frr/isisd.conf - sudo touch /usr/pkg/etc/frr/ripd.conf - sudo touch /usr/pkg/etc/frr/ripngd.conf - sudo touch /usr/pkg/etc/frr/pimd.conf - sudo chown -R frr:frr /usr/pkg/etc/frr - sudo touch /usr/local/etc/frr/vtysh.conf - sudo chown frr:frrvty /usr/pkg/etc/frr/*.conf - sudo chmod 640 /usr/pkg/etc/frr/*.conf - -### Enable IP & IPv6 forwarding - -Add the following lines to the end of `/etc/sysctl.conf`: - - # Routing: We need to forward packets - net.inet.ip.forwarding=1 - net.inet6.ip6.forwarding=1 - -**Reboot** or use `sysctl` to apply the same config to the running system - -### Install rc.d init files - cp pkgsrc/*.sh /etc/rc.d/ - chmod 555 /etc/rc.d/*.sh - -### Enable FRR processes -(Enable the required processes only) - - echo "zebra=YES" >> /etc/rc.conf - echo "bgpd=YES" >> /etc/rc.conf - echo "ospfd=YES" >> /etc/rc.conf - echo "ospf6d=YES" >> /etc/rc.conf - echo "isisd=YES" >> /etc/rc.conf - echo "ripngd=YES" >> /etc/rc.conf - echo "ripd=YES" >> /etc/rc.conf - echo "pimd=YES" >> /etc/rc.conf diff --git a/doc/Building_FRR_on_NetBSD7.md b/doc/Building_FRR_on_NetBSD7.md deleted file mode 100644 index 7fe9ad20c9..0000000000 --- a/doc/Building_FRR_on_NetBSD7.md +++ /dev/null @@ -1,108 +0,0 @@ -Building FRR on NetBSD 7 from Git Source -======================================== - -NetBSD 7 restrictions: ----------------------- - -- MPLS is not supported on `NetBSD`. MPLS requires a Linux Kernel - (4.5 or higher). LDP can be built, but may have limited use - without MPLS - -Install required packages -------------------------- - - sudo pkgin install git autoconf automake libtool gmake gawk openssl \ - pkg-config json-c python27 py27-test python35 - -Install SSL Root Certificates (for git https access): - - sudo pkgin install mozilla-rootcerts - sudo touch /etc/openssl/openssl.cnf - sudo mozilla-rootcerts install - -Select default Python and py.test - - sudo ln -s /usr/pkg/bin/python2.7 /usr/bin/python - sudo ln -s /usr/pkg/bin/py.test-2.7 /usr/bin/py.test - -Get FRR, compile it and install it (from Git) ------------------------------------------------- - -### Add frr groups and user - - sudo groupadd -g 92 frr - sudo groupadd -g 93 frrvty - sudo useradd -g 92 -u 92 -G frrvty -c "FRR suite" \ - -d /nonexistent -s /sbin/nologin frr - -### Download Source, configure and compile it -(You may prefer different options on configure statement. These are just -an example) - - git clone https://github.com/frrouting/frr.git frr - cd frr - ./bootstrap.sh - MAKE=gmake - export LDFLAGS="-L/usr/pkg/lib -R/usr/pkg/lib" - export CPPFLAGS="-I/usr/pkg/include" - ./configure \ - --sysconfdir=/usr/pkg/etc/frr \ - --enable-exampledir=/usr/pkg/share/examples/frr \ - --enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \ - --localstatedir=/var/run/frr \ - --enable-ospfclient=yes \ - --enable-ospfapi=yes \ - --enable-multipath=64 \ - --enable-user=frr \ - --enable-group=frr \ - --enable-vty-group=frrvty \ - --enable-configfile-mask=0640 \ - --enable-logfile-mask=0640 \ - --enable-rtadv \ - --enable-fpm \ - --with-pkg-git-version \ - --with-pkg-extra-version=-MyOwnFRRVersion - gmake - gmake check - sudo gmake install - -### Create empty FRR configuration files - sudo mkdir /usr/pkg/etc/frr - sudo touch /usr/pkg/etc/frr/zebra.conf - sudo touch /usr/pkg/etc/frr/bgpd.conf - sudo touch /usr/pkg/etc/frr/ospfd.conf - sudo touch /usr/pkg/etc/frr/ospf6d.conf - sudo touch /usr/pkg/etc/frr/isisd.conf - sudo touch /usr/pkg/etc/frr/ripd.conf - sudo touch /usr/pkg/etc/frr/ripngd.conf - sudo touch /usr/pkg/etc/frr/pimd.conf - sudo chown -R frr:frr /usr/pkg/etc/frr - sudo touch /usr/local/etc/frr/vtysh.conf - sudo chown frr:frrvty /usr/pkg/etc/frr/*.conf - sudo chmod 640 /usr/pkg/etc/frr/*.conf - -### Enable IP & IPv6 forwarding - -Add the following lines to the end of `/etc/sysctl.conf`: - - # Routing: We need to forward packets - net.inet.ip.forwarding=1 - net.inet6.ip6.forwarding=1 - -**Reboot** or use `sysctl` to apply the same config to the running system - -### Install rc.d init files - cp pkgsrc/*.sh /etc/rc.d/ - chmod 555 /etc/rc.d/*.sh - -### Enable FRR processes -(Enable the required processes only) - - echo "zebra=YES" >> /etc/rc.conf - echo "bgpd=YES" >> /etc/rc.conf - echo "ospfd=YES" >> /etc/rc.conf - echo "ospf6d=YES" >> /etc/rc.conf - echo "isisd=YES" >> /etc/rc.conf - echo "ripngd=YES" >> /etc/rc.conf - echo "ripd=YES" >> /etc/rc.conf - echo "pimd=YES" >> /etc/rc.conf diff --git a/doc/Building_FRR_on_OmniOS.md b/doc/Building_FRR_on_OmniOS.md deleted file mode 100644 index 6e4575f07b..0000000000 --- a/doc/Building_FRR_on_OmniOS.md +++ /dev/null @@ -1,117 +0,0 @@ -Building FRR on OmniOS (OpenSolaris) from Git Source -==================================================== - -OmniOS restrictions: --------------------- - -- MPLS is not supported on `OmniOS` or `Solaris`. MPLS requires a Linux - Kernel (4.5 or higher). LDP can be built, but may have limited use - without MPLS - -### Enable IP & IPv6 forwarding - - routeadm -e ipv4-forwarding - routeadm -e ipv6-forwarding - -Install required packages -------------------------- - -Add packages: - - pkg install \ - developer/build/autoconf \ - developer/build/automake \ - developer/lexer/flex \ - developer/parser/bison \ - developer/object-file \ - developer/linker \ - developer/library/lint \ - developer/build/gnu-make \ - developer/gcc51 \ - library/idnkit \ - library/idnkit/header-idnkit \ - system/header \ - system/library/math/header-math \ - git libtool gawk pkg-config - -Add additional Solaris packages: - - pkgadd -d http://get.opencsw.org/now - /opt/csw/bin/pkgutil -U - /opt/csw/bin/pkgutil -y -i texinfo - /opt/csw/bin/pkgutil -y -i perl - /opt/csw/bin/pkgutil -y -i libjson_c_dev - /opt/csw/bin/pkgutil -y -i python27 py_pip python27_dev - -Add libjson to Solaris equivalent of ld.so.conf - - crle -l /opt/csw/lib -u - -Add pytest: - - pip install pytest - -Select Python 2.7 as default (required for pytest) - - rm -f /usr/bin/python - ln -s /opt/csw/bin/python2.7 /usr/bin/python - -Fix PATH for all users and non-interactive sessions. Edit `/etc/default/login` -and add the following default PATH: - - PATH=/usr/gnu/bin:/usr/bin:/usr/sbin:/sbin:/opt/csw/bin - -Edit `~/.profile` and add the following default PATH: - - PATH=/usr/gnu/bin:/usr/bin:/usr/sbin:/sbin:/opt/csw/bin - -Get FRR, compile it and install it (from Git) ---------------------------------------------- - -**This assumes you want to build and install FRR from source and not using -any packages** - -### Add frr group and user - - sudo groupadd -g 93 frr - sudo groupadd -g 94 frrvty - sudo useradd -g 93 -u 93 -G frrvty -c "FRR suite" \ - -d /nonexistent -s /bin/false frr - -(You may prefer different options on configure statement. These are just -an example) - - git clone https://github.com/frrouting/frr.git frr - cd frr - ./bootstrap.sh - export MAKE=gmake - export LDFLAGS="-L/opt/csw/lib" - export CPPFLAGS="-I/opt/csw/include" - export PKG_CONFIG_PATH=/opt/csw/lib/pkgconfig - ./configure \ - --sysconfdir=/etc/frr \ - --enable-exampledir=/usr/share/doc/frr/examples/ \ - --localstatedir=/var/run/frr \ - --sbindir=/usr/lib/frr \ - --enable-vtysh \ - --enable-watchfrr \ - --enable-ospfclient=yes \ - --enable-ospfapi=yes \ - --enable-multipath=64 \ - --enable-user=frr \ - --enable-group=frr \ - --enable-vty-group=frrvty \ - --enable-configfile-mask=0640 \ - --enable-logfile-mask=0640 \ - --enable-rtadv \ - --enable-fpm \ - --with-pkg-git-version \ - --with-pkg-extra-version=-MyOwnFRRVersion - gmake - gmake check - sudo gmake install - -### Enable IP & IPv6 forwarding - - routeadm -e ipv4-forwarding - routeadm -e ipv6-forwarding diff --git a/doc/Building_FRR_on_OpenBSD6.md b/doc/Building_FRR_on_OpenBSD6.md deleted file mode 100644 index c1bfa5005e..0000000000 --- a/doc/Building_FRR_on_OpenBSD6.md +++ /dev/null @@ -1,135 +0,0 @@ -Building FRR on OpenBSD 6 from Git Source -========================================= - -Install required packages -------------------------- - -Configure PKG_PATH - - export PKG_PATH=http://ftp5.usa.openbsd.org/pub/OpenBSD/$(uname -r)/packages/$(machine -a)/ - -Add packages: - - pkg_add git autoconf-2.69p2 automake-1.15p0 libtool bison - pkg_add gmake gawk dejagnu openssl json-c py-test - -Select Python2.7 as default (required for pytest) - - ln -s /usr/local/bin/python2.7 /usr/local/bin/python - -Get FRR, compile it and install it (from Git) ---------------------------------------------- - -**This assumes you want to build and install FRR from source and not using -any packages** - -### Add frr group and user - - groupadd -g 525 _frr - groupadd -g 526 _frrvty - useradd -g 525 -u 525 -c "FRR suite" -G _frrvty \ - -d /nonexistent -s /sbin/nologin _frr - -### Download Source, configure and compile it -(You may prefer different options on configure statement. These are just -an example) - - git clone https://github.com/frrouting/frr.git frr - cd frr - export AUTOCONF_VERSION="2.69" - export AUTOMAKE_VERSION="1.15" - ./bootstrap.sh - export LDFLAGS="-L/usr/local/lib" - export CPPFLAGS="-I/usr/local/include" - ./configure \ - --sysconfdir=/etc/frr \ - --localstatedir=/var/frr \ - --enable-pimd \ - --enable-ospfclient=yes \ - --enable-ospfapi=yes \ - --enable-multipath=64 \ - --enable-user=_frr \ - --enable-group=_frr \ - --enable-vty-group=_frrvty \ - --enable-configfile-mask=0640 \ - --enable-logfile-mask=0640 \ - --enable-rtadv \ - --enable-fpm \ - --with-pkg-git-version \ - --with-pkg-extra-version=-MyOwnFRRVersion - gmake - gmake check - doas gmake install - -### Create empty FRR configuration files - - doas mkdir /var/frr - doas chown _frr:_frr /var/frr - doas chmod 755 /var/frr - doas mkdir /etc/frr - doas touch /etc/frr/zebra.conf - doas touch /etc/frr/bgpd.conf - doas touch /etc/frr/ospfd.conf - doas touch /etc/frr/ospf6d.conf - doas touch /etc/frr/isisd.conf - doas touch /etc/frr/ripd.conf - doas touch /etc/frr/ripngd.conf - doas touch /etc/frr/pimd.conf - doas touch /etc/frr/ldpd.conf - doas touch /etc/frr/nhrpd.conf - doas chown -R _frr:_frr /etc/frr - doas touch /etc/frr/vtysh.conf - doas chown -R _frr:_frrvty /etc/frr/vtysh.conf - doas chmod 750 /etc/frr - doas chmod 640 /etc/frr/*.conf - -### Enable IP & IPv6 forwarding - -Add the following lines to the end of `/etc/rc.conf`: - - net.inet6.ip6.forwarding=1 # 1=Permit forwarding of IPv6 packets - net.inet6.ip6.mforwarding=1 # 1=Permit forwarding of IPv6 multicast packets - net.inet6.ip6.multipath=1 # 1=Enable IPv6 multipath routing - -**Reboot** to apply the config to the system - -### Enable MPLS Forwarding - -To enable MPLS forwarding on a given interface, use the following command: - - doas ifconfig em0 mpls - -Alternatively, to make MPLS forwarding persistent across reboots, add the "mpls" -keyword in the hostname.* files of the desired interfaces. Example: - - cat /etc/hostname.em0 - inet 10.0.1.1 255.255.255.0 mpls - -### Install rc.d init files -(create them in /etc/rc.d - no example are included at this time with -FRR source) - -Example (for zebra - store as `/etc/rc.d/frr_zebra.sh`) - - #!/bin/sh - # - # $OpenBSD: frr_zebra.rc,v 1.1 2013/04/18 20:29:08 sthen Exp $ - - daemon="/usr/local/sbin/zebra -d" - - . /etc/rc.d/rc.subr - - rc_cmd $1 - -### Enable FRR processes -(Enable the required processes only) - - echo "frr_zebra=YES" >> /etc/rc.conf - echo "frr_bgpd=YES" >> /etc/rc.conf - echo "frr_ospfd=YES" >> /etc/rc.conf - echo "frr_ospf6d=YES" >> /etc/rc.conf - echo "frr_isisd=YES" >> /etc/rc.conf - echo "frr_ripngd=YES" >> /etc/rc.conf - echo "frr_ripd=YES" >> /etc/rc.conf - echo "frr_pimd=YES" >> /etc/rc.conf - echo "frr_ldpd=YES" >> /etc/rc.conf diff --git a/doc/Building_FRR_on_Ubuntu1204.md b/doc/Building_FRR_on_Ubuntu1204.md deleted file mode 100644 index 58aa167d57..0000000000 --- a/doc/Building_FRR_on_Ubuntu1204.md +++ /dev/null @@ -1,155 +0,0 @@ -Building FRR on Ubuntu 12.04LTS from Git Source -=============================================== - -- MPLS is not supported on `Ubuntu 12.04` with default kernel. MPLS requires - Linux Kernel 4.5 or higher (LDP can be built, but may have limited use - without MPLS) - For an updated Ubuntu Kernel, see http://kernel.ubuntu.com/~kernel-ppa/mainline/ - -Install required packages -------------------------- - -Add packages: - - apt-get install git autoconf automake libtool make gawk libreadline-dev \ - texinfo libpam0g-dev dejagnu libjson0-dev pkg-config libpam0g-dev \ - libjson0-dev flex python-pip libc-ares-dev python3-dev - -Install newer bison from 14.04 package source (Ubuntu 12.04 package source -is too old) - - mkdir builddir - cd builddir - wget http://archive.ubuntu.com/ubuntu/pool/main/b/bison/bison_3.0.2.dfsg-2.dsc - wget http://archive.ubuntu.com/ubuntu/pool/main/b/bison/bison_3.0.2.dfsg.orig.tar.bz2 - wget http://archive.ubuntu.com/ubuntu/pool/main/b/bison/bison_3.0.2.dfsg-2.debian.tar.gz - tar -jxvf bison_3.0.2.dfsg.orig.tar.bz2 - cd bison-3.0.2.dfsg/ - tar xzf ../bison_3.0.2.dfsg-2.debian.tar.gz - sudo apt-get build-dep bison - debuild -b -uc -us - cd .. - sudo dpkg -i ./libbison-dev_3.0.2.dfsg-2_amd64.deb ./bison_3.0.2.dfsg-2_amd64.deb - cd .. - rm -rf builddir - -Install newer version of autoconf and automake: - - wget http://ftp.gnu.org/gnu/autoconf/autoconf-2.69.tar.gz - tar xvf autoconf-2.69.tar.gz - cd autoconf-2.69 - ./configure --prefix=/usr - make - sudo make install - cd .. - - wget http://ftp.gnu.org/gnu/automake/automake-1.15.tar.gz - tar xvf automake-1.15.tar.gz - cd automake-1.15 - ./configure --prefix=/usr - make - sudo make install - cd .. - -Install pytest: - - pip install pytest - -Get FRR, compile it and install it (from Git) ---------------------------------------------- - -**This assumes you want to build and install FRR from source and not using -any packages** - -### Add frr groups and user - - sudo groupadd -g 92 frr - sudo groupadd -r -g 85 frrvty - sudo adduser --system --ingroup frr --home /var/run/frr/ \ - --gecos "FRR suite" --shell /sbin/nologin frr - sudo usermod -a -G frrvty frr - -### Download Source, configure and compile it -(You may prefer different options on configure statement. These are just -an example.) - - git clone https://github.com/frrouting/frr.git frr - cd frr - ./bootstrap.sh - ./configure \ - --prefix=/usr \ - --enable-exampledir=/usr/share/doc/frr/examples/ \ - --localstatedir=/var/run/frr \ - --sbindir=/usr/lib/frr \ - --sysconfdir=/etc/frr \ - --enable-pimd \ - --enable-watchfrr \ - --enable-ospfclient=yes \ - --enable-ospfapi=yes \ - --enable-multipath=64 \ - --enable-user=frr \ - --enable-group=frr \ - --enable-vty-group=frrvty \ - --enable-configfile-mask=0640 \ - --enable-logfile-mask=0640 \ - --enable-rtadv \ - --enable-fpm \ - --with-pkg-git-version \ - --with-pkg-extra-version=-MyOwnFRRVersion - make - make check - sudo make install - -### Create empty FRR configuration files - - sudo install -m 755 -o frr -g frr -d /var/log/frr - sudo install -m 775 -o frr -g frrvty -d /etc/frr - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/zebra.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/bgpd.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospfd.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospf6d.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/isisd.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripd.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripngd.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/pimd.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ldpd.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/nhrpd.conf - sudo install -m 640 -o frr -g frrvty /dev/null /etc/frr/vtysh.conf - -### Enable IP & IPv6 forwarding - -Edit `/etc/sysctl.conf` and uncomment the following values (ignore the -other settings) - - # Uncomment the next line to enable packet forwarding for IPv4 - net.ipv4.ip_forward=1 - - # Uncomment the next line to enable packet forwarding for IPv6 - # Enabling this option disables Stateless Address Autoconfiguration - # based on Router Advertisements for this host - net.ipv6.conf.all.forwarding=1 - -**Reboot** or use `sysctl -p` to apply the same config to the running system - -### Install the init.d service - - sudo install -m 755 tools/frr /etc/init.d/frr - sudo install -m 644 tools/etc/frr/daemons /etc/frr/daemons - sudo install -m 644 tools/etc/frr/daemons.conf /etc/frr/daemons.conf - sudo install -m 644 -o frr -g frr tools/etc/frr/vtysh.conf /etc/frr/vtysh.conf - -### Enable daemons -Edit `/etc/frr/daemons` and change the value from "no" to "yes" for those daemons you want to start by systemd. -For example. - - zebra=yes - bgpd=yes - ospfd=yes - ospf6d=yes - ripd=yes - ripngd=yes - isisd=yes - -### Start the init.d service -- /etc/init.d/frr start -- use `/etc/init.d/frr status` to check its status. diff --git a/doc/Building_FRR_on_Ubuntu1404.md b/doc/Building_FRR_on_Ubuntu1404.md deleted file mode 100644 index 8e6b38cc2d..0000000000 --- a/doc/Building_FRR_on_Ubuntu1404.md +++ /dev/null @@ -1,119 +0,0 @@ -Building FRR on Ubuntu 14.04LTS from Git Source -=============================================== - -- MPLS is not supported on `Ubuntu 14.04` with default kernel. MPLS requires - Linux Kernel 4.5 or higher (LDP can be built, but may have limited use - without MPLS) - For an updated Ubuntu Kernel, see http://kernel.ubuntu.com/~kernel-ppa/mainline/ - -Install required packages -------------------------- - -Add packages: - - apt-get install git autoconf automake libtool make gawk libreadline-dev \ - texinfo dejagnu pkg-config libpam0g-dev libjson-c-dev bison flex \ - python-pytest libc-ares-dev python3-dev - -Get FRR, compile it and install it (from Git) ---------------------------------------------- - -**This assumes you want to build and install FRR from source and not using -any packages** - -### Add frr groups and user - - sudo groupadd -g 92 frr - sudo groupadd -r -g 85 frrvty - sudo adduser --system --ingroup frr --home /var/run/frr/ \ - --gecos "FRR suite" --shell /sbin/nologin frr - sudo usermod -a -G frrvty frr - -### Download Source, configure and compile it -(You may prefer different options on configure statement. These are just -an example.) - - git clone https://github.com/frrouting/frr.git frr - cd frr - ./bootstrap.sh - ./configure \ - --prefix=/usr \ - --enable-exampledir=/usr/share/doc/frr/examples/ \ - --localstatedir=/var/run/frr \ - --sbindir=/usr/lib/frr \ - --sysconfdir=/etc/frr \ - --enable-pimd \ - --enable-watchfrr \ - --enable-ospfclient=yes \ - --enable-ospfapi=yes \ - --enable-multipath=64 \ - --enable-user=frr \ - --enable-group=frr \ - --enable-vty-group=frrvty \ - --enable-configfile-mask=0640 \ - --enable-logfile-mask=0640 \ - --enable-rtadv \ - --enable-fpm \ - --enable-ldpd \ - --with-pkg-git-version \ - --with-pkg-extra-version=-MyOwnFRRVersion - make - make check - sudo make install - -### Create empty FRR configuration files - - sudo install -m 755 -o frr -g frr -d /var/log/frr - sudo install -m 775 -o frr -g frrvty -d /etc/frr - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/zebra.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/bgpd.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospfd.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospf6d.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/isisd.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripd.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripngd.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/pimd.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ldpd.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/nhrpd.conf - sudo install -m 640 -o frr -g frrvty /dev/null /etc/frr/vtysh.conf - -### Enable IP & IPv6 forwarding - -Edit `/etc/sysctl.conf` and uncomment the following values (ignore the -other settings) - - # Uncomment the next line to enable packet forwarding for IPv4 - net.ipv4.ip_forward=1 - - # Uncomment the next line to enable packet forwarding for IPv6 - # Enabling this option disables Stateless Address Autoconfiguration - # based on Router Advertisements for this host - net.ipv6.conf.all.forwarding=1 - -**Reboot** or use `sysctl -p` to apply the same config to the running system -### Install the init.d service - - sudo install -m 755 tools/frr /etc/init.d/frr - sudo install -m 644 tools/etc/frr/daemons /etc/frr/daemons - sudo install -m 644 tools/etc/frr/daemons.conf /etc/frr/daemons.conf - sudo install -m 644 -o frr -g frr tools/etc/frr/vtysh.conf /etc/frr/vtysh.conf - - -### Enable daemons - -Edit `/etc/frr/daemons` and change the value from "no" to "yes" for those daemons you want to start by systemd. -For example. - - zebra=yes - bgpd=yes - ospfd=yes - ospf6d=yes - ripd=yes - ripngd=yes - isisd=yes - -### Start the init.d service -- /etc/init.d/frr start -- use `/etc/init.d/frr status` to check its status. - - diff --git a/doc/Building_FRR_on_Ubuntu1604.md b/doc/Building_FRR_on_Ubuntu1604.md deleted file mode 100644 index bdd0a96249..0000000000 --- a/doc/Building_FRR_on_Ubuntu1604.md +++ /dev/null @@ -1,143 +0,0 @@ -Building FRR on Ubuntu 16.04LTS from Git Source -=============================================== - -- MPLS is not supported on `Ubuntu 16.04` with default kernel. MPLS requires - Linux Kernel 4.5 or higher (LDP can be built, but may have limited use - without MPLS) - For an updated Ubuntu Kernel, see - http://kernel.ubuntu.com/~kernel-ppa/mainline/ - -Install required packages -------------------------- - -Add packages: - - apt-get install git autoconf automake libtool make gawk libreadline-dev \ - texinfo dejagnu pkg-config libpam0g-dev libjson-c-dev bison flex \ - python-pytest libc-ares-dev python3-dev libsystemd-dev python-ipaddr - -Get FRR, compile it and install it (from Git) ---------------------------------------------- - -**This assumes you want to build and install FRR from source and not using -any packages** - -### Add frr groups and user - - sudo groupadd -g 92 frr - sudo groupadd -r -g 85 frrvty - sudo adduser --system --ingroup frr --home /var/run/frr/ \ - --gecos "FRR suite" --shell /sbin/nologin frr - sudo usermod -a -G frrvty frr - -### Download Source, configure and compile it -(You may prefer different options on configure statement. These are just -an example.) - - git clone https://github.com/frrouting/frr.git frr - cd frr - ./bootstrap.sh - ./configure \ - --prefix=/usr \ - --enable-exampledir=/usr/share/doc/frr/examples/ \ - --localstatedir=/var/run/frr \ - --sbindir=/usr/lib/frr \ - --sysconfdir=/etc/frr \ - --enable-pimd \ - --enable-watchfrr \ - --enable-ospfclient=yes \ - --enable-ospfapi=yes \ - --enable-multipath=64 \ - --enable-user=frr \ - --enable-group=frr \ - --enable-vty-group=frrvty \ - --enable-configfile-mask=0640 \ - --enable-logfile-mask=0640 \ - --enable-rtadv \ - --enable-fpm \ - --enable-systemd=yes \ - --with-pkg-git-version \ - --with-pkg-extra-version=-MyOwnFRRVersion - make - make check - sudo make install - -### Create empty FRR configuration files - - sudo install -m 755 -o frr -g frr -d /var/log/frr - sudo install -m 775 -o frr -g frrvty -d /etc/frr - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/zebra.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/bgpd.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospfd.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospf6d.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/isisd.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripd.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripngd.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/pimd.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ldpd.conf - sudo install -m 640 -o frr -g frr /dev/null /etc/frr/nhrpd.conf - sudo install -m 640 -o frr -g frrvty /dev/null /etc/frr/vtysh.conf - -### Enable IPv4 & IPv6 forwarding - -Edit `/etc/sysctl.conf` and uncomment the following values (ignore the -other settings) - - # Uncomment the next line to enable packet forwarding for IPv4 - net.ipv4.ip_forward=1 - - # Uncomment the next line to enable packet forwarding for IPv6 - # Enabling this option disables Stateless Address Autoconfiguration - # based on Router Advertisements for this host - net.ipv6.conf.all.forwarding=1 - -### Enable MPLS Forwarding (with Linux Kernel >= 4.5) - -Edit `/etc/sysctl.conf` and the following lines. Make sure to add a line -equal to `net.mpls.conf.eth0.input` or each interface used with MPLS - - # Enable MPLS Label processing on all interfaces - net.mpls.conf.eth0.input=1 - net.mpls.conf.eth1.input=1 - net.mpls.conf.eth2.input=1 - net.mpls.platform_labels=100000 - -### Add MPLS kernel modules - -Add the following lines to `/etc/modules-load.d/modules.conf`: - - # Load MPLS Kernel Modules - mpls-router - mpls-iptunnel - -**Reboot** or use `sysctl -p` to apply the same config to the running system - - -### Install the systemd service (if rebooted from last step, change directory back to frr directory) - - sudo install -m 644 tools/frr.service /etc/systemd/system/frr.service - sudo install -m 644 tools/etc/default/frr /etc/default/frr - sudo install -m 644 tools/etc/frr/daemons /etc/frr/daemons - sudo install -m 644 tools/etc/frr/daemons.conf /etc/frr/daemons.conf - sudo install -m 644 tools/etc/frr/frr.conf /etc/frr/frr.conf - sudo install -m 644 -o frr -g frr tools/etc/frr/vtysh.conf /etc/frr/vtysh.conf - -### Enable daemons - -Edit `/etc/frr/daemons` and change the value from "no" to "yes" for those daemons you want to start by systemd. -For example. - - zebra=yes - bgpd=yes - ospfd=yes - ospf6d=yes - ripd=yes - ripngd=yes - isisd=yes - -### Enable the systemd service - - systemctl enable frr - -### Start the systemd service -- systemctl start frr -- use `systemctl status frr` to check its status. diff --git a/doc/cli.md b/doc/cli.md deleted file mode 100644 index 723237ebb8..0000000000 --- a/doc/cli.md +++ /dev/null @@ -1,557 +0,0 @@ -FRR Command Line Interface -========================== - -Definition Grammar ------------------- - -This is a reference for the syntax used when defining new CLI commands. An -example definition is: - -``` -DEFUN (command_name, - command_name_cmd, ---> "example DEFINITION...", - <..doc strings..>) -``` - -The arrowed part is the definition string. - -Explicit syntax rules in Flex and Bison may be found in lib/command_lex.l and -lib/command_parse.y, respectively. If you can read BNF and regex those will be -more useful than this document. - -If the parser is throwing syntax or other errors and you can't figure out why, -it's unlikely to be a bug in the parser. If the error message is not useful, -please file a bug for a better error message. If all else fails, read the token -definitions in the lexer source and the Bison BNF in the parser source. - -Characters allowed in each token type: - -Tokens ------- -* `WORD` -- A token that begins with +, -, or a lowercase letter. It is - an unchanging part of the command and will only match itself. - Example: "show ip bgp", every token is a WORD. -* `IPV4` -- 'A.B.C.D', matches an IPv4 address. -* `IPV6` -- 'X:X::X:X', matches an IPv6 address. -* `IPV4_PREFIX` -- 'A.B.C.D/M', matches an IPv4 prefix in CIDR notation. -* `IPV6_PREFIX` -- 'X:X::X:X/M', matches an IPv6 prefix in CIDR notation. -* `MAC` -- 'M:A:C', matches a 48-bit mac address -* `MAC_PREFIX` -- 'M:A:C/M', matches a 48-bit mac address with a mask -* `VARIABLE` -- Begins with a capital letter. Matches any input. -* `RANGE` -- Numeric range delimited by parentheses, e.g. (-100 - 100) or - (10-20). Will only match numbers in the range. - -Rules ------ -* `` -- Contain sequences of tokens separated by pipes and - provide mutual exclusion. Sequences may contain - `` but not as the first token. - Disallowed: `"example < c|d>"` - Allowed: `"example "` -* `[square brackets]` -- Contains sequences of tokens that are optional (can be - omitted). `[]` can be shortened to `[a|b]`. -* `{curly|braces}` -- similar to angle brackets, but instead of mutual - exclusion, curly braces indicate that one or more of the - pipe-separated sequences may be provided in any order. -* `VARIADICS...` -- Any token which accepts input (so anything except WORD) - and that occurs as the last token of a line may be - followed by an ellipsis, which indicates that input - matching the token may be repeated an unlimited number - of times. -* `$name` -- Specify a variable name for the preceding token. See - "Variable Names" below. - -Some general notes: - -* Options are allowed at the beginning of the command. The developer is - entreated to use these extremely sparingly. They are most useful for - implementing the 'no' form of configuration commands. Please think carefully - before using them for anything else. There is usually a better solution, even - if it is just separating out the command definition into separate ones. - -* The developer should judiciously apply separation of concerns when defining - CLI. CLI definitions for two unrelated or vaguely related commands or - configuration items should be defined in separate commands. Clarity is - preferred over LOC (within reason). - -* The maximum number of space-separated tokens that can be entered is presently - limited to 256. Please keep this limit in mind when implementing new CLI. - -Variable Names --------------- -The parser tries to fill the "varname" field on each token. This can happen -either manually or automatically. Manual specifications work by appending -`"$name"` after the input specifier: - -``` -foo bar$cmd WORD$name A.B.C.D$ip -``` - -Note that you can also assign variable names to fixed input tokens, this can -be useful if multiple commands share code. You can also use "$name" after a -multiple-choice option: - -``` -foo bar $addr [optionA|optionB]$mode -``` - -The variable name is in this case assigned to the last token in each of the -branches. - -Automatic assignment of variable names works by applying the following rules: - -- manual names always have priority -- a "[no]" at the beginning receives "no" as varname on the "no" token -- VARIABLE tokens whose text is not "WORD" or "NAME" receive a cleaned lowercase - version of the token text as varname, e.g. "ROUTE-MAP" becomes "route_map". -- other variable tokens (i.e. everything except "fixed") receive the text of - the preceding fixed token as varname, if one can be found. E.g.: - "ip route A.B.C.D/M INTERFACE" assigns "route" to the "A.B.C.D/M" token. - -These rules should make it possible to avoid manual varname assignment in 90% -of the cases. - -DEFPY ------ - -`DEFPY(...)` is an enhanced version of `DEFUN()` which is preprocessed by -` python/clidef.py`. The python script parses the command definition string, -extracts variable names and types, and generates a C wrapper function that -parses the variables and passes them on. This means that in the CLI function -body, you will receive additional parameters with appropriate types. - -This is best explained by an example: - -``` -DEFPY(func, func_cmd, "[no] foo bar A.B.C.D (0-99)$num", "...help...") - -=> - -func(self, vty, argc, argv, /* standard CLI arguments */ - - const char *no, /* unparsed "no" */ - struct in_addr bar, /* parsed IP address */ - const char *bar_str, /* unparsed IP address */ - long num, /* parsed num */ - const char *num_str) /* unparsed num */ -``` - -Note that as documented in the previous section, "bar" is automatically -applied as variable name for "A.B.C.D". The python code then detects this -is an IP address argument and generates code to parse it into a -`struct in_addr`, passing it in `bar`. The raw value is passed in `bar_str`. -The range/number argument works in the same way with the explicitly given -variable name. - -### Type rules - -| Token(s) | Type | Value if omitted by user | -|--------------------------|-------------|--------------------------| -| `A.B.C.D` | `struct in_addr` | 0.0.0.0 | -| `X:X::X:X` | `struct in6_addr` | :: | -| `A.B.C.D + X:X::X:X` | `const union sockunion *` | NULL | -| `A.B.C.D/M` | `const struct prefix_ipv4 *` | NULL | -| `X:X::X:X/M` | `const struct prefix_ipv6 *` | NULL | -| `A.B.C.D/M + X:X::X:X/M` | `const struct prefix *` | NULL | -| `(0-9)` | `long` | 0 | -| `VARIABLE` | `const char *` | NULL | -| `word` | `const char *` | NULL | -| _all other_ | `const char *` | NULL | - -Note the following details: - -* not all parameters are pointers, some are passed as values. -* when the type is not `const char *`, there will be an extra `_str` argument - with type `const char *`. -* you can give a variable name not only to `VARIABLE` tokens but also to - `word` tokens (e.g. constant words). This is useful if some parts of a - command are optional. The type will be `const char *`. -* `[no]` will be passed as `const char *no`. -* pointers will be NULL when the argument is optional and the user did not - use it. -* if a parameter is not a pointer, but is optional and the user didn't use it, - the default value will be passed. Check the `_str` argument if you need to - determine whether the parameter was omitted. -* if the definition contains multiple parameters with the same variable name, - they will be collapsed into a single function parameter. The python code - will detect if the types are compatible (i.e. IPv4 + IPv6 variantes) and - choose a corresponding C type. -* the standard DEFUN parameters (self, vty, argc, argv) are still present and - can be used. A DEFUN can simply be **edited into a DEFPY without further - changes and it will still work**; this allows easy forward migration. -* a file may contain both DEFUN and DEFPY statements. - -### Getting a parameter dump - -The clidef.py script can be called to get a list of DEFUNs/DEFPYs with -the parameter name/type list: - -``` -lib/clippy python/clidef.py --all-defun --show lib/plist.c > /dev/null -``` - -The generated code is printed to stdout, the info dump to stderr. The -`--all-defun` argument will make it process DEFUN blocks as well as DEFPYs, -which is useful prior to converting some DEFUNs. **The dump does not list -the `_str` arguments** to keep the output shorter. - -Note that the clidef.py script cannot be run with python directly, it needs -to be run with _clippy_ since the latter makes the CLI parser available. - -### Include & Makefile requirements - -A source file that uses DEFPY needs to include the `_clippy.c` file **before -all DEFPY statements**: - -``` -/* GPL header */ -#include ... - -... - -#include "daemon/filename_clippy.c" - -DEFPY(...) -DEFPY(...) - -install_element(...) -``` - -This dependency needs to be marked in Makefile.am: (there is no ordering -requirement) - -``` -include ../common.am - -# ... - -# if linked into a LTLIBRARY (.la/.so): -filename.lo: filename_clippy.c - -# if linked into an executable or static library (.a): -filename.o: filename_clippy.c -``` - -Doc Strings ------------ -Each token in a command definition should be documented with a brief doc -string that informs a user of the meaning and/or purpose of the subsequent -command tree. These strings are provided as the last parameter to DEFUN macros, -concatenated together and separated by an escaped newline ('\n'). These are -best explained by example. - -``` -DEFUN (config_terminal, - config_terminal_cmd, - "configure terminal", - "Configuration from vty interface\n" - "Configuration terminal\n") -``` - -The last parameter is split into two lines for readability. Two newline -delimited doc strings are present, one for each token in the command. The -second string documents the functionality of the 'terminal' command in the -'configure' tree. - -Note that the first string, for 'configure' does not contain documentation for -'terminal'. This is because the CLI is best envisioned as a tree, with tokens -defining branches. An imaginary 'start' token is the root of every command in a -CLI node. Each subsequent written token descends into a subtree, so the -documentation for that token ideally summarizes all the functionality contained -in the subtree. - -A consequence of this structure is that the developer must be careful to use -the same doc strings when defining multiple commands that are part of the same -tree. Commands which share prefixes must share the same doc strings for those -prefixes. On startup the parser will generate warnings if it notices -inconsistent doc strings. Behavior is undefined; the same token may show up -twice in completions, with different doc strings, or it may show up once with a -random doc string. Parser warnings should be heeded and fixed to avoid -confusing users. - -The number of doc strings provided must be equal to the amount of tokens -present in the command definition, read left to right, ignoring any special -constructs. - -In the examples below, each arrowed token needs a doc string. - -``` - "show ip bgp" - ^ ^ ^ - - "command [example]" - ^ ^ ^ ^ -``` - -Data Structures ---------------- -On startup, the CLI parser sequentially parses each command string definition -and constructs a directed graph with each token forming a node. This graph is -the basis of the entire CLI system. It is used to match user input in order to -generate command completions and match commands to functions. - -There is one graph per CLI node (not the same as a graph node in the CLI -graph). The CLI node struct keeps a reference to its graph (see lib/command.h). - -While most of the graph maintains the form of a tree, special constructs -outlined in the Rules section introduce some quirks. <>, [] and {} form -self-contained 'subgraphs'. Each subgraph is a tree except that all of the -'leaves' actually share a child node. This helps with minimizing graph size and -debugging. - -As an example, the subgraph generated by looks like this: - - . - . - | - +----+---+ - +--- -+ FORK +----+ - | +--------+ | - +--v---+ +--v---+ - | foo | | bar | - +--+---+ +--+---+ - | +------+ | - +------> JOIN <-----+ - +---+--+ - | - . - . - -FORK and JOIN nodes are plumbing nodes that don't correspond to user input. -They're necessary in order to deduplicate these constructs where applicable. - -Options follow the same form, except that there is an edge from the FORK node -to the JOIN node. - -Keywords follow the same form, except that there is an edge from JOIN to FORK. -Because of this the CLI graph cannot be called acyclic. There is special logic -in the input matching code that keeps a stack of paths already taken through -the node in order to disallow following the same path more than once. - -Variadics are a bit special; they have an edge back to themselves, which allows -repeating the same input indefinitely. - -The leaves of the graph are nodes that have no out edges. These nodes are -special; their data section does not contain a token, as most nodes do, or -NULL, as in FORK/JOIN nodes, but instead has a pointer to a cmd_element. All -paths through the graph that terminate on a leaf are guaranteed to be defined -by that command. When a user enters a complete command, the command matcher -tokenizes the input and executes a DFS on the CLI graph. If it is -simultaneously able to exhaust all input (one input token per graph node), and -then find exactly one leaf connected to the last node it reaches, then the -input has matched the corresponding command and the command is executed. If it -finds more than one node, then the command is ambiguous (more on this in -deduplication). If it cannot exhaust all input, the command is unknown. If it -exhausts all input but does not find an edge node, the command is incomplete. - -The parser uses an incremental strategy to build the CLI graph for a node. Each -command is parsed into its own graph, and then this graph is merged into the -overall graph. During this merge step, the parser makes a best-effort attempt -to remove duplicate nodes. If it finds a node in the overall graph that is -equal to a node in the corresponding position in the command graph, it will -intelligently merge the properties from the node in the command graph into the -already-existing node. Subgraphs are also checked for isomorphism and merged -where possible. The definition of whether two nodes are 'equal' is based on the -equality of some set of token properties; read the parser source for the most -up-to-date definition of equality. - -When the parser is unable to deduplicate some complicated constructs, this -can result in two identical paths through separate parts of the graph. If -this occurs and the user enters input that matches these paths, they will -receive an 'ambiguous command' error and will be unable to execute the command. -Most of the time the parser can detect and warn about duplicate commands, but -it will not always be able to do this. Hence care should be taken before -defining a new command to ensure it is not defined elsewhere. - - -Command handlers ----------------- -The block that follows a CLI definition is executed when a user enters input -that matches the definition. Its function signature looks like this: - -int (*func) (const struct cmd_element *, struct vty *, int, struct cmd_token *[]); - -The first argument is the command definition struct. The last argument is an -ordered array of tokens that correspond to the path taken through the graph, -and the argument just prior to that is the length of the array. - -The arrangement of the token array has changed from the prior incarnation of -the CLI system. In the old system, missing arguments were padded with NULLs so -that the same parts of a command would show up at the same indices regardless -of what was entered. The new system does not perform such padding and therefore -it is generally _incorrect_ to assume consistent indices in this array. As a -simple example: - -Command definition: -``` - command [foo] -``` - -User enters: -``` - command foo bar -``` - -Array: -``` - [0] -> command - [1] -> foo - [2] -> bar -``` - -User enters: -``` - command baz -``` - -Array: -``` - [0] -> command - [1] -> baz -``` - - - -Command abbreviation & matching priority ----------------------------------------- -As in the prior implementation, it is possible for users to elide parts of -tokens when the CLI matcher does not need them to make an unambiguous match. -This is best explained by example. - -Command definitions: -``` - command dog cow - command dog crow -``` - -User input: -``` - c d c -> ambiguous command - c d co -> match "command dog cow" -``` - -In the new implementation, this functionality has improved. Where previously -the parser would stop at the first ambiguous token, it will now look ahead and -attempt to disambiguate based on tokens later on in the input string. - -Command definitions: -``` - show ip bgp A.B.C.D - show ipv6 bgp X:X::X:X -``` - -User enters: -``` - s i b 4.3.2.1 -> match "show ip bgp A.B.C.D" - s i b ::e0 -> match "show ipv6 bgp X:X::X:X" -``` - -Previously both of these commands would be ambiguous since 'i' does not -explicitly select either 'ip' or 'ipv6'. However, since the user later provides -a token that matches only one of the commands (an IPv4 or IPv6 address) the -parser is able to look ahead and select the appropriate command. This has some -implications for parsing the argv*[] that is passed to the command handler. - -Now consider a command definition such as: -``` - command -``` - -'foo' only matches the string 'foo', but 'VAR' matches any input, including -'foo'. Who wins? In situations like this the matcher will always choose the -'better' match, so 'foo' will win. - -Consider also: -``` - show foo -``` - -User input: -``` - show ip foo -``` - -'ip' partially matches 'ipv6' but exactly matches 'ip', so 'ip' will win. - - -struct cmd_token ----------------- - -``` -/* Command token struct. */ -struct cmd_token -{ - enum cmd_token_type type; // token type - u_char attr; // token attributes - bool allowrepeat; // matcher allowed to match token repetitively? - - char *text; // token text - char *desc; // token description - long long min, max; // for ranges - char *arg; // user input that matches this token - char *varname; // variable name -}; -``` - -This struct is used in the CLI graph to match input against. It is also used to -pass user input to command handler functions, as it is frequently useful for -handlers to have access to that information. When a command is matched, the -sequence of cmd_tokens that form the matching path are duplicated and placed in -order into argv*[]. Before this happens the ->arg field is set to point at the -snippet of user input that matched it. - -For most nontrivial commands the handler function will need to determine which -of the possible matching inputs was entered. Previously this was done by -looking at the first few characters of input. This is now considered an -anti-pattern and should be avoided. Instead, the ->type or ->text fields for -this logic. The ->type field can be used when the possible inputs differ in -type. When the possible types are the same, use the ->text field. This field -has the full text of the corresponding token in the definition string and using -it makes for much more readable code. An example is helpful. - -Command definition: -``` - command <(1-10)|foo|BAR> -``` - -In this example, the user may enter any one of: - * an integer between 1 and 10 - * "foo" - * anything at all - -If the user enters "command f", then: - -``` -argv[1]->type == WORD_TKN -argv[1]->arg == "f" -argv[1]->text == "foo" -``` - -Range tokens have some special treatment; a token with ->type == RANGE_TKN will -have the ->min and ->max fields set to the bounding values of the range. - - -Permutations ------------- -Finally, it is sometimes useful to check all the possible combinations of input -that would match an arbitrary definition string. There is a tool in tools/ -called 'permutations' that reads CLI definition strings on stdin and prints out -all matching input permutations. It also dumps a text representation of the -graph, which is more useful for debugging than anything else. It looks like -this: - -``` -$ ./permutations "show [ip] bgp [ WORD]" - -show ip bgp view WORD -show ip bgp vrf WORD -show ip bgp -show bgp view WORD -show bgp vrf WORD -show bgp -``` - -This functionality is also built into VTY/VTYSH; the 'list permutations' -command will list all possible matching input permutations in the current CLI -node. diff --git a/doc/code/.gitignore b/doc/code/.gitignore deleted file mode 100644 index 0505537159..0000000000 --- a/doc/code/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -/_templates -/_build -!/Makefile diff --git a/doc/code/Makefile b/doc/code/Makefile deleted file mode 100644 index 056b78e68e..0000000000 --- a/doc/code/Makefile +++ /dev/null @@ -1,216 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = _build - -# User-friendly check for sphinx-build -ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) -$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) -endif - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . -# the i18n builder cannot share the environment and doctrees with the others -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . - -.PHONY: help -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " applehelp to make an Apple Help Book" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " texinfo to make Texinfo files" - @echo " info to make Texinfo files and run them through makeinfo" - @echo " gettext to make PO message catalogs" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " xml to make Docutils-native XML files" - @echo " pseudoxml to make pseudoxml-XML files for display purposes" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - @echo " coverage to run coverage check of the documentation (if enabled)" - -.PHONY: clean -clean: - rm -rf $(BUILDDIR)/* - -.PHONY: html -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -.PHONY: dirhtml -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -.PHONY: singlehtml -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -.PHONY: pickle -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -.PHONY: json -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -.PHONY: htmlhelp -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -.PHONY: qthelp -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/FRR.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/FRR.qhc" - -.PHONY: applehelp -applehelp: - $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp - @echo - @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." - @echo "N.B. You won't be able to view it unless you put it in" \ - "~/Library/Documentation/Help or install it in your application" \ - "bundle." - -.PHONY: devhelp -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/FRR" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/FRR" - @echo "# devhelp" - -.PHONY: epub -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -.PHONY: latex -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -.PHONY: latexpdf -latexpdf: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -.PHONY: latexpdfja -latexpdfja: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through platex and dvipdfmx..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -.PHONY: text -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -.PHONY: man -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -.PHONY: texinfo -texinfo: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo - @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." - @echo "Run \`make' in that directory to run these through makeinfo" \ - "(use \`make info' here to do that automatically)." - -.PHONY: info -info: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo "Running Texinfo files through makeinfo..." - make -C $(BUILDDIR)/texinfo info - @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." - -.PHONY: gettext -gettext: - $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale - @echo - @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." - -.PHONY: changes -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -.PHONY: linkcheck -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -.PHONY: doctest -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." - -.PHONY: coverage -coverage: - $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage - @echo "Testing of coverage in the sources finished, look at the " \ - "results in $(BUILDDIR)/coverage/python.txt." - -.PHONY: xml -xml: - $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml - @echo - @echo "Build finished. The XML files are in $(BUILDDIR)/xml." - -.PHONY: pseudoxml -pseudoxml: - $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml - @echo - @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." diff --git a/doc/code/conf.py b/doc/code/conf.py deleted file mode 100644 index 38be7f2fca..0000000000 --- a/doc/code/conf.py +++ /dev/null @@ -1,293 +0,0 @@ -# -*- 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 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 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 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 diff --git a/doc/code/hooks.rst b/doc/code/hooks.rst deleted file mode 100644 index 0afa297aa7..0000000000 --- a/doc/code/hooks.rst +++ /dev/null @@ -1,171 +0,0 @@ -.. highlight:: c - -Hooks -===== - -Libfrr provides type-safe subscribable hook points where other pieces of -code can add one or more callback functions. "type-safe" in this case -applies to the function pointers used for subscriptions. The -implementations checks (at compile-time) wheter a callback to be added has -the appropriate function signature (parameters) for the hook. - -Example: - -.. code-block:: c - :caption: mydaemon.h - - #include "hook.h" - DECLARE_HOOK(some_update_event, (struct eventinfo *info), (info)) - -.. code-block:: c - :caption: mydaemon.c - - #include "mydaemon.h" - DEFINE_HOOK(some_update_event, (struct eventinfo *info), (info)) - ... - hook_call(some_update_event, info); - -.. code-block:: c - :caption: mymodule.c - - #include "mydaemon.h" - static int event_handler(struct eventinfo *info); - ... - hook_register(some_update_event, event_handler); - -Do not use parameter names starting with "hook", these can collide with -names used by the hook code itself. - - -Return values -------------- - -Callbacks to be placed on hooks always return "int" for now; hook_call will -sum up the return values from each called function. (The default is 0 if no -callbacks are registered.) - -There are no pre-defined semantics for the value, in most cases it is -ignored. For success/failure indication, 0 should be success, and -handlers should make sure to only return 0 or 1 (not -1 or other values). - -There is no built-in way to abort executing a chain after a failure of one -of the callbacks. If this is needed, the hook can use an extra -``bool *aborted`` argument. - - -Priorities ----------- - -Hooks support a "priority" value for ordering registered calls -relative to each other. The priority is a signed integer where lower -values are called earlier. There are also "Koohs", which is hooks with -reverse priority ordering (for cleanup/deinit hooks, so you can use the -same priority value). - -Recommended priority value ranges are: - -======================== =================================================== -Range Usage ------------------------- --------------------------------------------------- - -999 ... 0 ... 999 main executable / daemon, or library - --1999 ... -1000 modules registering calls that should run before - the daemon's bits - -1000 ... 1999 modules' calls that should run after daemon's - (includes default value: 1000) -======================== =================================================== - -Note: the default value is 1000, based on the following 2 expectations: - -- most hook_register() usage will be in loadable modules -- usage of hook_register() in the daemon itself may need relative ordering - to itself, making an explicit value the expected case - -The priority value is passed as extra argument on hook_register_prio() / -hook_register_arg_prio(). Whether a hook runs in reverse is determined -solely by the code defining / calling the hook. (DECLARE_KOOH is actually -the same thing as DECLARE_HOOK, it's just there to make it obvious.) - - -Definition ----------- - -.. c:macro:: DECLARE_HOOK(name, arglist, passlist) -.. c:macro:: DECLARE_KOOH(name, arglist, passlist) - - :param name: Name of the hook to be defined - :param arglist: Function definition style parameter list in braces. - :param passlist: List of the same parameters without their types. - - Note: the second and third macro args must be the hook function's - parameter list, with the same names for each parameter. The second - macro arg is with types (used for defining things), the third arg is - just the names (used for passing along parameters). - - This macro must be placed in a header file; this header file must be - included to register a callback on the hook. - - Examples: - - .. code-block:: c - - DECLARE_HOOK(foo, (), ()) - DECLARE_HOOK(bar, (int arg), (arg)) - DECLARE_HOOK(baz, (const void *x, in_addr_t y), (x, y)) - -.. c:macro:: DEFINE_HOOK(name, arglist, passlist) - - Implements an hook. Each ``DECLARE_HOOK`` must have be accompanied by - exactly one ``DEFINE_HOOK``, which needs to be placed in a source file. - **The hook can only be called from this source file.** This is intentional - to avoid overloading and/or misusing hooks for distinct purposes. - - The compiled source file will include a global symbol with the name of the - hook prefixed by `_hook_`. Trying to register a callback for a hook that - doesn't exist will therefore result in a linker error, or a module - load-time error for dynamic modules. - -.. c:macro:: DEFINE_KOOH(name, arglist, passlist) - - Same as ``DEFINE_HOOK``, but the sense of priorities / order of callbacks - is reversed. This should be used for cleanup hooks. - -.. c:function:: int hook_call(name, ...) - - Calls the specified named hook. Parameters to the hook are passed right - after the hook name, e.g.: - - .. code-block:: c - - hook_call(foo); - hook_call(bar, 0); - hook_call(baz, NULL, INADDR_ANY); - - Returns the sum of return values from all callbacks. The ``DEFINE_HOOK`` - statement for the hook must be placed in the file before any ``hook_call`` - use of the hook. - - -Callback registration ---------------------- - -.. c:function:: void hook_register(name, int (*callback)(...)) -.. c:function:: void hook_register_prio(name, int priority, int (*callback)(...)) -.. c:function:: void hook_register_arg(name, int (*callback)(void *arg, ...), void *arg) -.. c:function:: void hook_register_arg_prio(name, int priority, int (*callback)(void *arg, ...), void *arg) - - Register a callback with an hook. If the caller needs to pass an extra - argument to the callback, the _arg variant can be used and the extra - parameter will be passed as first argument to the callback. There is no - typechecking for this argument. - - The priority value is used as described above. The variants without a - priority parameter use 1000 as priority value. - -.. c:function:: void hook_unregister(name, int (*callback)(...)) -.. c:function:: void hook_unregister_arg(name, int (*callback)(void *arg, ...), void *arg) - - Removes a previously registered callback from a hook. Note that there - is no _prio variant of these calls. The priority value is only used during - registration. diff --git a/doc/code/index.rst b/doc/code/index.rst deleted file mode 100644 index 79647d0b92..0000000000 --- a/doc/code/index.rst +++ /dev/null @@ -1,18 +0,0 @@ -Welcome to FRR's documentation! -=============================== - -Contents: - -.. toctree:: - :maxdepth: 2 - - library - - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - diff --git a/doc/code/library.rst b/doc/code/library.rst deleted file mode 100644 index dd46021db8..0000000000 --- a/doc/code/library.rst +++ /dev/null @@ -1,10 +0,0 @@ -libfrr library facilities -========================= - -.. toctree:: - :maxdepth: 2 - - memtypes - hooks - - diff --git a/doc/code/memtypes.rst b/doc/code/memtypes.rst deleted file mode 100644 index 62d211e864..0000000000 --- a/doc/code/memtypes.rst +++ /dev/null @@ -1,117 +0,0 @@ -.. highlight:: c - -Memtypes -======== - -FRR includes wrappers arround ``malloc()`` and ``free()`` that count the number -of objects currently allocated, for each of a defined ``MTYPE``. - -To this extent, there are `memory groups` and `memory types`. Each memory -type must belong to a memory group, this is used just to provide some basic -structure. - -Example: - -.. code-block:: c - :caption: mydaemon.h - - DECLARE_MGROUP(MYDAEMON) - DECLARE_MTYPE(MYNEIGHBOR) - -.. code-block:: c - :caption: mydaemon.c - - DEFINE_MGROUP( MYDAEMON, "My daemon's memory") - DEFINE_MTYPE( MYDAEMON, MYNEIGHBOR, "Neighbor entry") - DEFINE_MTYPE_STATIC(MYDAEMON, MYNEIGHBORNAME, "Neighbor name") - - struct neigh *neighbor_new(const char *name) - { - struct neigh *n = XMALLOC(MYNEIGHBOR, sizeof(*n)); - n->name = XSTRDUP(MYNEIGHBORNAME, name); - return n; - } - - void neighbor_free(struct neigh *n) - { - XFREE(MYNEIGHBORNAME, n->name); - XFREE(MYNEIGHBOR, n); - } - - -Definition ----------- - -.. c:macro:: DECLARE_MGROUP(name) - - This macro forward-declares a memory group and should be placed in a - ``.h`` file. It expands to an ``extern struct memgroup`` statement. - -.. c:macro:: DEFINE_MGROUP(mname, description) - - Defines/implements a memory group. Must be placed into exactly one ``.c`` - file (multiple inclusion will result in a link-time symbol conflict). - - Contains additional logic (constructor and destructor) to register the - memory group in a global list. - -.. c:macro:: DECLARE_MTYPE(name) - - Forward-declares a memory type and makes ``MTYPE_name`` available for use. - Note that the ``MTYPE_`` prefix must not be included in the name, it is - automatically prefixed. - - ``MTYPE_name`` is created as a `static const` symbol, i.e. a compile-time - constant. It refers to an ``extern struct memtype _mt_name``, where `name` - is replaced with the actual name. - -.. c:macro:: DEFINE_MTYPE(group, name, description) - - Define/implement a memory type, must be placed into exactly one ``.c`` - file (multiple inclusion will result in a link-time symbol conflict). - - Like ``DEFINE_MGROUP``, this contains actual code to register the MTYPE - under its group. - -.. c:macro:: DEFINE_MTYPE_STATIC(group, name, description) - - Same as ``DEFINE_MTYPE``, but the ``DEFINE_MTYPE_STATIC`` variant places - the C ``static`` keyword on the definition, restricting the MTYPE's - availability to the current source file. This should be appropriate in - >80% of cases. - - .. todo:: - - Daemons currently have ``daemon_memory.[ch]`` files listing all of - their MTYPEs. This is not how it should be, most of these types - should be moved into the appropriate files where they are used. - Only a few MTYPEs should remain non-static after that. - - -Usage ------ - -.. c:function:: void *XMALLOC(struct memtype *mtype, size_t size) - -.. c:function:: void *XCALLOC(struct memtype *mtype, size_t size) - -.. c:function:: void *XSTRDUP(struct memtype *mtype, size_t size) - - Allocation wrappers for malloc/calloc/realloc/strdup, taking an extra - mtype parameter. - -.. c:function:: void *XREALLOC(struct memtype *mtype, void *ptr, size_t size) - - Wrapper around realloc() with MTYPE tracking. Note that ``ptr`` may - be NULL, in which case the function does the same as XMALLOC (regardless - of whether the system realloc() supports this.) - -.. c:function:: void XFREE(struct memtype *mtype, void *ptr) - - Wrapper around free(), again taking an extra mtype parameter. This is - actually a macro, with the following additional properties: - - - the macro contains ``ptr = NULL`` - - if ptr is NULL, no operation is performed (as is guaranteed by system - implementations.) Do not surround XFREE with ``if (ptr != NULL)`` - checks. diff --git a/doc/developer/Building_FRR_on_CentOS6.rst b/doc/developer/Building_FRR_on_CentOS6.rst new file mode 100644 index 0000000000..e93ae603ef --- /dev/null +++ b/doc/developer/Building_FRR_on_CentOS6.rst @@ -0,0 +1,217 @@ +CentOS 6 +======================================== + +(As an alternative to this installation, you may prefer to create a FRR +rpm package yourself and install that package instead. See instructions +in redhat/README.rpm\_build.md on how to build a rpm package) + +Instructions are tested with ``CentOS 6.8`` on ``x86_64`` platform + +CentOS 6 restrictions: +---------------------- + +- PIMd is not supported on ``CentOS 6``. Upgrade to ``CentOS 7`` if + PIMd is needed +- MPLS is not supported on ``CentOS 6``. MPLS requires Linux Kernel 4.5 + or higher (LDP can be built, but may have limited use without MPLS) +- Zebra is unable to detect what bridge/vrf an interface is associcated + with (IFLA\_INFO\_SLAVE\_KIND does not exist in the kernel headers, + you can use a newer kernel + headers to get this functionality) +- frr\_reload.py will not work, as this requires Python 2.7, and CentOS + 6 only has 2.6. You can install Python 2.7 via IUS, but it won't work + properly unless you compile and install the ipaddr package for it. + +Install required packages +------------------------- + +Add packages: + +:: + + sudo yum install git autoconf automake libtool make gawk \ + readline-devel texinfo net-snmp-devel groff pkgconfig \ + json-c-devel pam-devel flex epel-release perl-XML-LibXML \ + c-ares-devel + +Install newer version of bison (CentOS 6 package source is too old) from +CentOS 7 + +:: + + sudo yum install rpm-build + curl -O http://vault.centos.org/7.0.1406/os/Source/SPackages/bison-2.7-4.el7.src.rpm + rpmbuild --rebuild ./bison-2.7-4.el7.src.rpm + sudo yum install ./rpmbuild/RPMS/x86_64/bison-2.7-4.el6.x86_64.rpm + rm -rf rpmbuild + +Install newer version of autoconf and automake (Package versions are too +old) + +:: + + curl -O http://ftp.gnu.org/gnu/autoconf/autoconf-2.69.tar.gz + tar xvf autoconf-2.69.tar.gz + cd autoconf-2.69 + ./configure --prefix=/usr + make + sudo make install + cd .. + + curl -O http://ftp.gnu.org/gnu/automake/automake-1.15.tar.gz + tar xvf automake-1.15.tar.gz + cd automake-1.15 + ./configure --prefix=/usr + make + sudo make install + cd .. + +Install ``Python 2.7`` in parallel to default 2.6. Make sure you've +install EPEL (``epel-release`` as above). Then install current +``python27``, ``python27-devel`` and ``pytest`` + +:: + + sudo rpm -ivh http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm + sudo rpm -ivh https://centos6.iuscommunity.org/ius-release.rpm + sudo yum install python27 python27-pip python27-devel + sudo pip2.7 install pytest + +Please note that ``CentOS 6`` needs to keep python pointing to version +2.6 for ``yum`` to keep working, so don't create a symlink for python2.7 +to python + +Get FRR, compile it and install it (from Git) +--------------------------------------------- + +**This assumes you want to build and install FRR from source and not +using any packages** + +Add frr groups and user +~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo groupadd -g 92 frr + sudo groupadd -r -g 85 frrvt + sudo useradd -u 92 -g 92 -M -r -G frrvt -s /sbin/nologin \ + -c "FRR FRRouting suite" -d /var/run/frr frr + +Download Source, configure and compile it +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +(You may prefer different options on configure statement. These are just +an example.) + +:: + + git clone https://github.com/frrouting/frr.git frr + cd frr + ./bootstrap.sh + ./configure \ + --bindir=/usr/bin \ + --sbindir=/usr/lib/frr \ + --sysconfdir=/etc/frr \ + --libdir=/usr/lib/frr \ + --libexecdir=/usr/lib/frr \ + --localstatedir=/var/run/frr \ + --with-moduledir=/usr/lib/frr/modules \ + --disable-pimd \ + --enable-snmp=agentx \ + --enable-multipath=64 \ + --enable-ospfclient=yes \ + --enable-ospfapi=yes \ + --enable-user=frr \ + --enable-group=frr \ + --enable-vty-group=frrvt \ + --enable-rtadv \ + --disable-exampledir \ + --enable-watchfrr \ + --disable-ldpd \ + --enable-fpm \ + --enable-nhrpd \ + --enable-eigrpd \ + --enable-babeld \ + --with-pkg-git-version \ + --with-pkg-extra-version=-MyOwnFRRVersion + make + make check PYTHON=/usr/bin/python2.7 + sudo make install + +Create empty FRR configuration files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo mkdir /var/log/frr + sudo mkdir /etc/frr + sudo touch /etc/frr/zebra.conf + sudo touch /etc/frr/bgpd.conf + sudo touch /etc/frr/ospfd.conf + sudo touch /etc/frr/ospf6d.conf + sudo touch /etc/frr/isisd.conf + sudo touch /etc/frr/ripd.conf + sudo touch /etc/frr/ripngd.conf + sudo touch /etc/frr/nhrpd.conf + sudo touch /etc/frr/eigrpd.conf + sudo touch /etc/frr/babeld.conf + sudo chown -R frr:frr /etc/frr/ + sudo touch /etc/frr/vtysh.conf + sudo chown frr:frrvt /etc/frr/vtysh.conf + sudo chmod 640 /etc/frr/*.conf + +Install daemon config file +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo install -p -m 644 redhat/daemons /etc/frr/ + sudo chown frr:frr /etc/frr/daemons + +Edit /etc/frr/daemons as needed to select the required daemons +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Look for the section with ``watchfrr_enable=...`` and ``zebra=...`` etc. +Enable the daemons as required by changing the value to ``yes`` + +Enable IP & IPv6 forwarding +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Edit ``/etc/sysctl.conf`` and set the following values (ignore the other +settings) + +:: + + # Controls IP packet forwarding + net.ipv4.ip_forward = 1 + net.ipv6.conf.all.forwarding=1 + + # Controls source route verification + net.ipv4.conf.default.rp_filter = 0 + +Load the modifed sysctl's on the system: + +:: + + sudo sysctl -p /etc/sysctl.d/90-routing-sysctl.conf + +Add init.d startup files +~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo install -p -m 755 redhat/frr.init /etc/init.d/frr + sudo chkconfig --add frr + +Enable frr daemon at startup +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo chkconfig frr on + +Start FRR manually (or reboot) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo /etc/init.d/frr start diff --git a/doc/developer/Building_FRR_on_CentOS7.rst b/doc/developer/Building_FRR_on_CentOS7.rst new file mode 100644 index 0000000000..60c4266894 --- /dev/null +++ b/doc/developer/Building_FRR_on_CentOS7.rst @@ -0,0 +1,168 @@ +CentOS 7 +======================================== + +(As an alternative to this installation, you may prefer to create a FRR +rpm package yourself and install that package instead. See instructions +in redhat/README.rpm\_build.md on how to build a rpm package) + +CentOS 7 restrictions: +---------------------- + +- MPLS is not supported on ``CentOS 7`` with default kernel. MPLS + requires Linux Kernel 4.5 or higher (LDP can be built, but may have + limited use without MPLS) + +Install required packages +------------------------- + +Add packages: + +:: + + sudo yum install git autoconf automake libtool make gawk \ + readline-devel texinfo net-snmp-devel groff pkgconfig \ + json-c-devel pam-devel bison flex pytest c-ares-devel \ + perl-XML-LibXML python-devel + +Get FRR, compile it and install it (from Git) +--------------------------------------------- + +**This assumes you want to build and install FRR from source and not +using any packages** + +Add frr groups and user +~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo groupadd -g 92 frr + sudo groupadd -r -g 85 frrvt + sudo useradd -u 92 -g 92 -M -r -G frrvt -s /sbin/nologin \ + -c "FRR FRRouting suite" -d /var/run/frr frr + +Download Source, configure and compile it +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +(You may prefer different options on configure statement. These are just +an example.) + +:: + + git clone https://github.com/frrouting/frr.git frr + cd frr + ./bootstrap.sh + ./configure \ + --bindir=/usr/bin \ + --sbindir=/usr/lib/frr \ + --sysconfdir=/etc/frr \ + --libdir=/usr/lib/frr \ + --libexecdir=/usr/lib/frr \ + --localstatedir=/var/run/frr \ + --with-moduledir=/usr/lib/frr/modules \ + --enable-pimd \ + --enable-snmp=agentx \ + --enable-multipath=64 \ + --enable-ospfclient=yes \ + --enable-ospfapi=yes \ + --enable-user=frr \ + --enable-group=frr \ + --enable-vty-group=frrvt \ + --enable-rtadv \ + --disable-exampledir \ + --enable-watchfrr \ + --disable-ldpd \ + --enable-fpm \ + --enable-nhrpd \ + --enable-eigrpd \ + --enable-babeld \ + --with-pkg-git-version \ + --with-pkg-extra-version=-MyOwnFRRVersion + make + make check + sudo make install + +Create empty FRR configuration files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo mkdir /var/log/frr + sudo mkdir /etc/frr + sudo touch /etc/frr/zebra.conf + sudo touch /etc/frr/bgpd.conf + sudo touch /etc/frr/ospfd.conf + sudo touch /etc/frr/ospf6d.conf + sudo touch /etc/frr/isisd.conf + sudo touch /etc/frr/ripd.conf + sudo touch /etc/frr/ripngd.conf + sudo touch /etc/frr/pimd.conf + sudo touch /etc/frr/nhrpd.conf + sudo touch /etc/frr/eigrpd.conf + sudo touch /etc/frr/babeld.conf + sudo chown -R frr:frr /etc/frr/ + sudo touch /etc/frr/vtysh.conf + sudo chown frr:frrvt /etc/frr/vtysh.conf + sudo chmod 640 /etc/frr/*.conf + +Install daemon config file +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo install -p -m 644 redhat/daemons /etc/frr/ + sudo chown frr:frr /etc/frr/daemons + +Edit /etc/frr/daemons as needed to select the required daemons +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Look for the section with ``watchfrr_enable=...`` and ``zebra=...`` etc. +Enable the daemons as required by changing the value to ``yes`` + +Enable IP & IPv6 forwarding +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Create a new file ``/etc/sysctl.d/90-routing-sysctl.conf`` with the +following content: + +:: + + # Sysctl for routing + # + # Routing: We need to forward packets + net.ipv4.conf.all.forwarding=1 + net.ipv6.conf.all.forwarding=1 + +Load the modifed sysctl's on the system: + +:: + + sudo sysctl -p /etc/sysctl.d/90-routing-sysctl.conf + +Install frr Service and redhat init files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo install -p -m 644 redhat/frr.service /usr/lib/systemd/system/frr.service + sudo install -p -m 755 redhat/frr.init /usr/lib/frr/frr + +Register the systemd files +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo systemctl preset frr.service + +Enable required frr at startup +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo systemctl enable frr + +Reboot or start FRR manually +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo systemctl start frr diff --git a/doc/developer/Building_FRR_on_Debian8.rst b/doc/developer/Building_FRR_on_Debian8.rst new file mode 100644 index 0000000000..af24539cb6 --- /dev/null +++ b/doc/developer/Building_FRR_on_Debian8.rst @@ -0,0 +1,156 @@ +Debian 8 +======================================== + +Debian 8 restrictions: +---------------------- + +- MPLS is not supported on ``Debian 8`` with default kernel. MPLS + requires Linux Kernel 4.5 or higher (LDP can be built, but may have + limited use without MPLS) + +Install required packages +------------------------- + +Add packages: + +:: + + sudo apt-get install git autoconf automake libtool make gawk \ + libreadline-dev texinfo libjson-c-dev pkg-config bison flex \ + python-pip libc-ares-dev python3-dev + +Install newer pytest (>3.0) from pip + +:: + + sudo pip install pytest + +Get FRR, compile it and install it (from Git) +--------------------------------------------- + +**This assumes you want to build and install FRR from source and not +using any packages** + +Add frr groups and user +~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo addgroup --system --gid 92 frr + sudo addgroup --system --gid 85 frrvty + sudo adduser --system --ingroup frr --home /var/run/frr/ \ + --gecos "FRR suite" --shell /bin/false frr + sudo usermod -a -G frrvty frr + +Download Source, configure and compile it +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +(You may prefer different options on configure statement. These are just +an example.) + +:: + + git clone https://github.com/frrouting/frr.git frr + cd frr + ./bootstrap.sh + ./configure \ + --enable-exampledir=/usr/share/doc/frr/examples/ \ + --localstatedir=/var/run/frr \ + --sbindir=/usr/lib/frr \ + --sysconfdir=/etc/frr \ + --enable-vtysh \ + --enable-isisd \ + --enable-pimd \ + --enable-watchfrr \ + --enable-ospfclient=yes \ + --enable-ospfapi=yes \ + --enable-multipath=64 \ + --enable-user=frr \ + --enable-group=frr \ + --enable-vty-group=frrvty \ + --enable-configfile-mask=0640 \ + --enable-logfile-mask=0640 \ + --enable-rtadv \ + --enable-fpm \ + --enable-ldpd \ + --with-pkg-git-version \ + --with-pkg-extra-version=-MyOwnFRRVersion + make + make check + sudo make install + +Create empty FRR configuration files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo install -m 755 -o frr -g frr -d /var/log/frr + sudo install -m 775 -o frr -g frrvty -d /etc/frr + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/zebra.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/bgpd.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospfd.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospf6d.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/isisd.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripd.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripngd.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/pimd.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ldpd.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/nhrpd.conf + sudo install -m 640 -o frr -g frrvty /dev/null /etc/frr/vtysh.conf + +Enable IP & IPv6 forwarding +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Edit ``/etc/sysctl.conf`` and uncomment the following values (ignore the +other settings) + +:: + + # Uncomment the next line to enable packet forwarding for IPv4 + net.ipv4.ip_forward=1 + + # Uncomment the next line to enable packet forwarding for IPv6 + # Enabling this option disables Stateless Address Autoconfiguration + # based on Router Advertisements for this host + net.ipv6.conf.all.forwarding=1 + +**Reboot** or use ``sysctl -p`` to apply the same config to the running +system + +Troubleshooting +~~~~~~~~~~~~~~~ + +**Local state directory** + +The local state directory must exist and have the correct permissions +applied for the frrouting daemons to start. In the above ./configure +example the local state directory is set to /var/run/frr +(--localstatedir=/var/run/frr) Debian considers /var/run/frr to be +temporary and this is removed after a reboot. + +When using a different local state directory you need to create the new +directory and change the ownership to the frr user, for example: + +:: + + mkdir /var/opt/frr + chown frr /var/opt/frr + +**Shared library error** + +If you try and start any of the frrouting daemons you may see the below +error due to the frrouting shared library directory not being found: + +:: + + ./zebra: error while loading shared libraries: libfrr.so.0: cannot open shared object file: No such file or directory + +The fix is to add the following line to /etc/ld.so.conf which will +continue to reference the library directory after the system reboots. To +load the library directory path immediately run the ldconfig command +after adding the line to the file eg: + +:: + + echo include /usr/local/lib >> /etc/ld.so.conf + ldconfig diff --git a/doc/developer/Building_FRR_on_Debian9.rst b/doc/developer/Building_FRR_on_Debian9.rst new file mode 100644 index 0000000000..a3e3d7ff97 --- /dev/null +++ b/doc/developer/Building_FRR_on_Debian9.rst @@ -0,0 +1,144 @@ +Debian 9 +======================================== + +Install required packages +------------------------- + +Add packages: + +:: + + sudo apt-get install git autoconf automake libtool make \ + libreadline-dev texinfo libjson-c-dev pkg-config bison flex \ + python-pip libc-ares-dev python3-dev python-pytest + +Get FRR, compile it and install it (from Git) +--------------------------------------------- + +**This assumes you want to build and install FRR from source and not +using any packages** + +Add frr groups and user +~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo addgroup --system --gid 92 frr + sudo addgroup --system --gid 85 frrvty + sudo adduser --system --ingroup frr --home /var/run/frr/ \ + --gecos "FRR suite" --shell /bin/false frr + sudo usermod -a -G frrvty frr + +Download Source, configure and compile it +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +(You may prefer different options on configure statement. These are just +an example.) + +:: + + git clone https://github.com/frrouting/frr.git frr + cd frr + git checkout stable/3.0 + ./bootstrap.sh + ./configure \ + --enable-exampledir=/usr/share/doc/frr/examples/ \ + --localstatedir=/var/run/frr \ + --sbindir=/usr/lib/frr \ + --sysconfdir=/etc/frr \ + --enable-vtysh \ + --enable-isisd \ + --enable-pimd \ + --enable-watchfrr \ + --enable-ospfclient=yes \ + --enable-ospfapi=yes \ + --enable-multipath=64 \ + --enable-user=frr \ + --enable-group=frr \ + --enable-vty-group=frrvty \ + --enable-configfile-mask=0640 \ + --enable-logfile-mask=0640 \ + --enable-rtadv \ + --enable-fpm \ + --enable-ldpd \ + --with-pkg-git-version \ + --with-pkg-extra-version=-MyOwnFRRVersion + make + make check + sudo make install + +Create empty FRR configuration files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo install -m 755 -o frr -g frr -d /var/log/frr + sudo install -m 775 -o frr -g frrvty -d /etc/frr + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/zebra.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/bgpd.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospfd.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospf6d.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/isisd.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripd.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripngd.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/pimd.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ldpd.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/nhrpd.conf + sudo install -m 640 -o frr -g frrvty /dev/null /etc/frr/vtysh.conf + +Enable IP & IPv6 forwarding +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Edit ``/etc/sysctl.conf`` and uncomment the following values (ignore the +other settings) + +:: + + # Uncomment the next line to enable packet forwarding for IPv4 + net.ipv4.ip_forward=1 + + # Uncomment the next line to enable packet forwarding for IPv6 + # Enabling this option disables Stateless Address Autoconfiguration + # based on Router Advertisements for this host + net.ipv6.conf.all.forwarding=1 + +**Reboot** or use ``sysctl -p`` to apply the same config to the running +system + +Troubleshooting +~~~~~~~~~~~~~~~ + +**Local state directory** + +The local state directory must exist and have the correct permissions +applied for the frrouting daemons to start. In the above ./configure +example the local state directory is set to /var/run/frr +(--localstatedir=/var/run/frr) Debian considers /var/run/frr to be +temporary and this is removed after a reboot. + +When using a different local state directory you need to create the new +directory and change the ownership to the frr user, for example: + +:: + + mkdir /var/opt/frr + chown frr /var/opt/frr + +**Shared library error** + +If you try and start any of the frrouting daemons you may see the below +error due to the frrouting shared library directory not being found: + +:: + + ./zebra: error while loading shared libraries: libfrr.so.0: cannot open shared object file: No such file or directory + +The fix is to add the following line to /etc/ld.so.conf which will +continue to reference the library directory after the system reboots. To +load the library directory path immediately run the ldconfig command +after adding the line to the file eg: + +:: + + echo include /usr/local/lib >> /etc/ld.so.conf + ldconfig diff --git a/doc/developer/Building_FRR_on_Fedora24.rst b/doc/developer/Building_FRR_on_Fedora24.rst new file mode 100644 index 0000000000..5ba4dd0e5f --- /dev/null +++ b/doc/developer/Building_FRR_on_Fedora24.rst @@ -0,0 +1,177 @@ +Fedora 24 +========================================= + +(As an alternative to this installation, you may prefer to create a FRR +rpm package yourself and install that package instead. See instructions +in redhat/README.rpm\_build.md on how to build a rpm package) + +Install required packages +------------------------- + +Add packages: + +:: + + sudo dnf install git autoconf automake libtool make gawk \ + readline-devel texinfo net-snmp-devel groff pkgconfig \ + json-c-devel pam-devel perl-XML-LibXML pytest bison flex \ + c-ares-devel python3-devel + +Get FRR, compile it and install it (from Git) +--------------------------------------------- + +**This assumes you want to build and install FRR from source and not +using any packages** + +Add frr groups and user +~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo groupadd -g 92 frr + sudo groupadd -r -g 85 frrvt + sudo useradd -u 92 -g 92 -M -r -G frrvt -s /sbin/nologin \ + -c "FRR FRRouting suite" -d /var/run/frr frr + +Download Source, configure and compile it +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +(You may prefer different options on configure statement. These are just +an example.) + +:: + + git clone https://github.com/frrouting/frr.git frr + cd frr + ./bootstrap.sh + ./configure \ + --bindir=/usr/bin \ + --sbindir=/usr/lib/frr \ + --sysconfdir=/etc/frr \ + --libdir=/usr/lib/frr \ + --libexecdir=/usr/lib/frr \ + --localstatedir=/var/run/frr \ + --with-moduledir=/usr/lib/frr/modules \ + --enable-pimd \ + --enable-snmp=agentx \ + --enable-multipath=64 \ + --enable-ospfclient=yes \ + --enable-ospfapi=yes \ + --enable-user=frr \ + --enable-group=frr \ + --enable-vty-group=frrvt \ + --enable-rtadv \ + --disable-exampledir \ + --enable-watchfrr \ + --enable-ldpd \ + --enable-fpm \ + --enable-nhrpd \ + --enable-eigrpd \ + --enable-babeld \ + --with-pkg-git-version \ + --with-pkg-extra-version=-MyOwnFRRVersion + make + make check + sudo make install + +Create empty FRR configuration files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo mkdir /var/log/frr + sudo mkdir /etc/frr + sudo touch /etc/frr/zebra.conf + sudo touch /etc/frr/bgpd.conf + sudo touch /etc/frr/ospfd.conf + sudo touch /etc/frr/ospf6d.conf + sudo touch /etc/frr/isisd.conf + sudo touch /etc/frr/ripd.conf + sudo touch /etc/frr/ripngd.conf + sudo touch /etc/frr/pimd.conf + sudo touch /etc/frr/ldpd.conf + sudo touch /etc/frr/nhrpd.conf + sudo touch /etc/frr/eigrpd.conf + sudo touch /etc/frr/babeld.conf + sudo chown -R frr:frr /etc/frr/ + sudo touch /etc/frr/vtysh.conf + sudo chown frr:frrvt /etc/frr/vtysh.conf + sudo chmod 640 /etc/frr/*.conf + +Install daemon config file +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo install -p -m 644 redhat/daemons /etc/frr/ + sudo chown frr:frr /etc/frr/daemons + +Edit /etc/frr/daemons as needed to select the required daemons +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Look for the section with ``watchfrr_enable=...`` and ``zebra=...`` etc. +Enable the daemons as required by changing the value to ``yes`` + +Enable IP & IPv6 forwarding (and MPLS) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Create a new file ``/etc/sysctl.d/90-routing-sysctl.conf`` with the +following content: (Please make sure to list all interfaces with +required MPLS similar to ``net.mpls.conf.eth0.input=1``) + +:: + + # Sysctl for routing + # + # Routing: We need to forward packets + net.ipv4.conf.all.forwarding=1 + net.ipv6.conf.all.forwarding=1 + # + # Enable MPLS Label processing on all interfaces + net.mpls.conf.eth0.input=1 + net.mpls.conf.eth1.input=1 + net.mpls.conf.eth2.input=1 + net.mpls.platform_labels=100000 + +Load the modifed sysctl's on the system: + +:: + + sudo sysctl -p /etc/sysctl.d/90-routing-sysctl.conf + +Create a new file ``/etc/modules-load.d/mpls.conf`` with the following +content: + +:: + + # Load MPLS Kernel Modules + mpls-router + mpls-iptunnel + +And load the kernel modules on the running system: + +:: + + sudo modprobe mpls-router mpls-iptunnel + +Install frr Service and redhat init files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo install -p -m 644 redhat/frr.service /usr/lib/systemd/system/frr.service + sudo install -p -m 755 redhat/frr.init /usr/lib/frr/frr + +Enable required frr at startup +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo systemctl enable frr + +Reboot or start FRR manually +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo systemctl start frr diff --git a/doc/developer/Building_FRR_on_FreeBSD10.rst b/doc/developer/Building_FRR_on_FreeBSD10.rst new file mode 100644 index 0000000000..94f2f27282 --- /dev/null +++ b/doc/developer/Building_FRR_on_FreeBSD10.rst @@ -0,0 +1,109 @@ +FreeBSD 10 +========================================== + +FreeBSD 10 restrictions: +------------------------ + +- MPLS is not supported on ``FreeBSD``. MPLS requires a Linux Kernel + (4.5 or higher). LDP can be built, but may have limited use without + MPLS + +Install required packages +------------------------- + +Add packages: (Allow the install of the package managment tool if this +is first package install and asked) + +:: + + pkg install git autoconf automake libtool gmake gawk json-c pkgconf \ + bison flex py27-pytest c-ares python3 + +Make sure there is no /usr/bin/flex preinstalled (and use the newly +installed in /usr/local/bin): (FreeBSD frequently provides a older flex +as part of the base OS which takes preference in path) + +:: + + rm -f /usr/bin/flex + +Get FRR, compile it and install it (from Git) +--------------------------------------------- + +**This assumes you want to build and install FRR from source and not +using any packages** + +Add frr group and user +~~~~~~~~~~~~~~~~~~~~~~ + +:: + + pw groupadd frr -g 101 + pw groupadd frrvty -g 102 + pw adduser frr -g 101 -u 101 -G 102 -c "FRR suite" \ + -d /usr/local/etc/frr -s /usr/sbin/nologin + +(You may prefer different options on configure statement. These are just +an example) + +:: + + git clone https://github.com/frrouting/frr.git frr + cd frr + ./bootstrap.sh + export MAKE=gmake + export LDFLAGS="-L/usr/local/lib" + export CPPFLAGS="-I/usr/local/include" + ./configure \ + --sysconfdir=/usr/local/etc/frr \ + --enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \ + --localstatedir=/var/run/frr \ + --prefix=/usr/local \ + --enable-ospfclient=yes \ + --enable-ospfapi=yes \ + --enable-multipath=64 \ + --enable-user=frr \ + --enable-group=frr \ + --enable-vty-group=frrvty \ + --enable-configfile-mask=0640 \ + --enable-logfile-mask=0640 \ + --enable-rtadv \ + --enable-fpm \ + --with-pkg-git-version \ + --with-pkg-extra-version=-MyOwnFRRVersion + gmake + gmake check + sudo gmake install + +Create empty FRR configuration files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo mkdir /usr/local/etc/frr + sudo touch /usr/local/etc/frr/zebra.conf + sudo touch /usr/local/etc/frr/bgpd.conf + sudo touch /usr/local/etc/frr/ospfd.conf + sudo touch /usr/local/etc/frr/ospf6d.conf + sudo touch /usr/local/etc/frr/isisd.conf + sudo touch /usr/local/etc/frr/ripd.conf + sudo touch /usr/local/etc/frr/ripngd.conf + sudo touch /usr/local/etc/frr/pimd.conf + sudo chown -R frr:frr /usr/local/etc/frr + sudo touch /usr/local/etc/frr/vtysh.conf + sudo chown frr:frrvty /usr/local/etc/frr/vtysh.conf + sudo chmod 640 /usr/local/etc/frr/*.conf + +Enable IP & IPv6 forwarding +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Add the following lines to the end of ``/etc/sysctl.conf``: + +:: + + # Routing: We need to forward packets + net.inet.ip.forwarding=1 + net.inet6.ip6.forwarding=1 + +**Reboot** or use ``sysctl`` to apply the same config to the running +system diff --git a/doc/developer/Building_FRR_on_FreeBSD11.rst b/doc/developer/Building_FRR_on_FreeBSD11.rst new file mode 100644 index 0000000000..de118093e6 --- /dev/null +++ b/doc/developer/Building_FRR_on_FreeBSD11.rst @@ -0,0 +1,109 @@ +FreeBSD 11 +========================================== + +FreeBSD 11 restrictions: +------------------------ + +- MPLS is not supported on ``FreeBSD``. MPLS requires a Linux Kernel + (4.5 or higher). LDP can be built, but may have limited use without + MPLS + +Install required packages +------------------------- + +Add packages: (Allow the install of the package managment tool if this +is first package install and asked) + +:: + + pkg install git autoconf automake libtool gmake gawk json-c pkgconf \ + bison flex py27-pytest c-ares python3 + +Make sure there is no /usr/bin/flex preinstalled (and use the newly +installed in /usr/local/bin): (FreeBSD frequently provides a older flex +as part of the base OS which takes preference in path) + +:: + + rm -f /usr/bin/flex + +Get FRR, compile it and install it (from Git) +--------------------------------------------- + +**This assumes you want to build and install FRR from source and not +using any packages** + +Add frr group and user +~~~~~~~~~~~~~~~~~~~~~~ + +:: + + pw groupadd frr -g 101 + pw groupadd frrvty -g 102 + pw adduser frr -g 101 -u 101 -G 102 -c "FRR suite" \ + -d /usr/local/etc/frr -s /usr/sbin/nologin + +(You may prefer different options on configure statement. These are just +an example) + +:: + + git clone https://github.com/frrouting/frr.git frr + cd frr + ./bootstrap.sh + export MAKE=gmake + export LDFLAGS="-L/usr/local/lib" + export CPPFLAGS="-I/usr/local/include" + ./configure \ + --sysconfdir=/usr/local/etc/frr \ + --enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \ + --localstatedir=/var/run/frr \ + --prefix=/usr/local \ + --enable-ospfclient=yes \ + --enable-ospfapi=yes \ + --enable-multipath=64 \ + --enable-user=frr \ + --enable-group=frr \ + --enable-vty-group=frrvty \ + --enable-configfile-mask=0640 \ + --enable-logfile-mask=0640 \ + --enable-rtadv \ + --enable-fpm \ + --with-pkg-git-version \ + --with-pkg-extra-version=-MyOwnFRRVersion + gmake + gmake check + sudo gmake install + +Create empty FRR configuration files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo mkdir /usr/local/etc/frr + sudo touch /usr/local/etc/frr/zebra.conf + sudo touch /usr/local/etc/frr/bgpd.conf + sudo touch /usr/local/etc/frr/ospfd.conf + sudo touch /usr/local/etc/frr/ospf6d.conf + sudo touch /usr/local/etc/frr/isisd.conf + sudo touch /usr/local/etc/frr/ripd.conf + sudo touch /usr/local/etc/frr/ripngd.conf + sudo touch /usr/local/etc/frr/pimd.conf + sudo chown -R frr:frr /usr/local/etc/frr + sudo touch /usr/local/etc/frr/vtysh.conf + sudo chown frr:frrvty /usr/local/etc/frr/vtysh.conf + sudo chmod 640 /usr/local/etc/frr/*.conf + +Enable IP & IPv6 forwarding +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Add the following lines to the end of ``/etc/sysctl.conf``: + +:: + + # Routing: We need to forward packets + net.inet.ip.forwarding=1 + net.inet6.ip6.forwarding=1 + +**Reboot** or use ``sysctl`` to apply the same config to the running +system diff --git a/doc/developer/Building_FRR_on_FreeBSD9.rst b/doc/developer/Building_FRR_on_FreeBSD9.rst new file mode 100644 index 0000000000..2ccf56be13 --- /dev/null +++ b/doc/developer/Building_FRR_on_FreeBSD9.rst @@ -0,0 +1,122 @@ +FreeBSD 9 +========================================= + +FreeBSD 9 restrictions: +----------------------- + +- MPLS is not supported on ``FreeBSD``. MPLS requires a Linux Kernel + (4.5 or higher). LDP can be built, but may have limited use without + MPLS + +Install required packages +------------------------- + +Add packages: (Allow the install of the package managment tool if this +is first package install and asked) + +:: + + pkg install -y git autoconf automake libtool gmake gawk \ + pkgconf texinfo json-c bison flex py27-pytest c-ares \ + python3 + +Make sure there is no /usr/bin/flex preinstalled (and use the newly +installed in /usr/local/bin): (FreeBSD frequently provides a older flex +as part of the base OS which takes preference in path) + +:: + + rm -f /usr/bin/flex + +For building with clang (instead of gcc), upgrade clang from 3.4 default +to 3.6 *This is needed to build FreeBSD packages as well - for packages +clang is default* (Clang 3.4 as shipped with FreeBSD 9 crashes during +compile) + +:: + + pkg install clang36 + pkg delete clang34 + mv /usr/bin/clang /usr/bin/clang34 + ln -s /usr/local/bin/clang36 /usr/bin/clang + +Get FRR, compile it and install it (from Git) +--------------------------------------------- + +**This assumes you want to build and install FRR from source and not +using any packages** + +Add frr group and user +~~~~~~~~~~~~~~~~~~~~~~ + +:: + + pw groupadd frr -g 101 + pw groupadd frrvty -g 102 + pw adduser frr -g 101 -u 101 -G 102 -c "FRR suite" \ + -d /usr/local/etc/frr -s /usr/sbin/nologin + +(You may prefer different options on configure statement. These are just +an example) + +:: + + git clone https://github.com/frrouting/frr.git frr + cd frr + ./bootstrap.sh + export MAKE=gmake + export LDFLAGS="-L/usr/local/lib" + export CPPFLAGS="-I/usr/local/include" + ./configure \ + --sysconfdir=/usr/local/etc/frr \ + --enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \ + --localstatedir=/var/run/frr \ + --prefix=/usr/local \ + --enable-ospfclient=yes \ + --enable-ospfapi=yes \ + --enable-multipath=64 \ + --enable-user=frr \ + --enable-group=frr \ + --enable-vty-group=frrvty \ + --enable-configfile-mask=0640 \ + --enable-logfile-mask=0640 \ + --enable-rtadv \ + --enable-fpm \ + --with-pkg-git-version \ + --with-pkg-extra-version=-MyOwnFRRVersion + gmake + gmake check + sudo gmake install + +Create empty FRR configuration files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo mkdir /usr/local/etc/frr + sudo touch /usr/local/etc/frr/zebra.conf + sudo touch /usr/local/etc/frr/bgpd.conf + sudo touch /usr/local/etc/frr/ospfd.conf + sudo touch /usr/local/etc/frr/ospf6d.conf + sudo touch /usr/local/etc/frr/isisd.conf + sudo touch /usr/local/etc/frr/ripd.conf + sudo touch /usr/local/etc/frr/ripngd.conf + sudo touch /usr/local/etc/frr/pimd.conf + sudo chown -R frr:frr /usr/local/etc/frr + sudo touch /usr/local/etc/frr/vtysh.conf + sudo chown frr:frrvty /usr/local/etc/frr/vtysh.conf + sudo chmod 640 /usr/local/etc/frr/*.conf + +Enable IP & IPv6 forwarding +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Add the following lines to the end of ``/etc/sysctl.conf``: + +:: + + # Routing: We need to forward packets + net.inet.ip.forwarding=1 + net.inet6.ip6.forwarding=1 + +**Reboot** or use ``sysctl`` to apply the same config to the running +system diff --git a/doc/developer/Building_FRR_on_LEDE-OpenWRT.rst b/doc/developer/Building_FRR_on_LEDE-OpenWRT.rst new file mode 100644 index 0000000000..2ddd8bcc44 --- /dev/null +++ b/doc/developer/Building_FRR_on_LEDE-OpenWRT.rst @@ -0,0 +1,107 @@ +OpenWRT/LEDE +============================================= + +- for the moment because of cross compile problems, master is not + supported, only up to 3.0 +- LDP can't be built because of missing Perl-XML-LibXML in OpenWRT/LEDE + tree + +Prepare build environment +------------------------- + +https://lede-project.org/docs/guide-developer/install-buildsystem + +for + +Ubuntu 12.04LTS: + +:: + + sudo apt-get install build-essential subversion git-core \ + libncurses5-dev zlib1g-dev gawk flex quilt libssl-dev xsltproc \ + libxml-parser-perl mercurial bzr ecj cvs unzip + +Ubuntu 64bit: + +:: + + sudo apt-get install build-essential subversion libncurses5-dev zlib1g-dev \ + gawk gcc-multilib flex git-core gettext libssl-dev + +Debian 8 Jessie: + +:: + + sudo apt-get install build-essential libncurses5-dev gawk git subversion \ + libssl-dev gettext unzip zlib1g-dev file python + +Debian 9 Stretch: + +:: + + sudo apt-get install build-essential libncurses5-dev gawk git subversion \ + libssl-dev gettext zlib1g-dev + +Centos x86-64 (some packages require EPEL): + +:: + + yum install subversion binutils bzip2 gcc gcc-c++ gawk gettext flex \ + ncurses-devel zlib-devel zlib-static make patch unzip glibc glibc-devel \ + perl-ExtUtils-MakeMaker glibc-static quilt ncurses-libs sed sdcc bison \ + intltool sharutils wget git-core openssl-devel xz + +Fedora 24 - 64Bit: + +:: + + dnf install -y subversion binutils bzip2 gcc gcc-c++ gawk gettext git-core \ + unzip ncurses-devel ncurses-compat-libs zlib-devel zlib-static make \ + flex patch perl-ExtUtils-MakeMaker perl-Thread-Queue glibc glibc-devel \ + glibc-static quilt sed sdcc intltool sharutils bison wget openssl-devel + +Get LEDE Sources (from Git) +--------------------------- + +LEDE and OpenWRT is planned to remerge and won't cover the similar +OpenWRT build As normal user: git clone +https://git.lede-project.org/source.git lede cd lede ./scripts/feeds +update -a ./scripts/feeds install -a cd feeds/routing git pull origin +pull/319/head ln -s ../../../feeds/routing/frr/ +../../package/feeds/routing/ cd ../.. make menuconfig + +Select the needed target then select needed packages in Network -> +Routing and Redirection -> frr, exit and save + +:: + + make or make package/frr/compile + +It may be possible that on first build ``make package/frr/compile`` not +to work and it may be needed to run a ``make`` for the entire build +envronment, add V=s for debugging + +Work with sources +----------------- + +To update the rc1 version or add other options, the Makefile is found in +feeds/routing/frr + +edit: PKG\_VERSION:= PKG\_SOURCE\_VERSION:= + +Usage +----- + +Edit ``/usr/sbin/frr.init`` and add/remove the daemons name in section +DAEMONS= or don't install unneded packages For example: zebra bgpd ldpd +isisd nhrpd ospfd ospf6d pimd ripd ripngd + +Enable the serivce +~~~~~~~~~~~~~~~~~~ + +- service frr enable + +Start the service +~~~~~~~~~~~~~~~~~ + +- service frr start diff --git a/doc/developer/Building_FRR_on_NetBSD6.rst b/doc/developer/Building_FRR_on_NetBSD6.rst new file mode 100644 index 0000000000..b4476127e3 --- /dev/null +++ b/doc/developer/Building_FRR_on_NetBSD6.rst @@ -0,0 +1,147 @@ +NetBSD 6 +======================================== + +NetBSD 6 restrictions: +---------------------- + +- MPLS is not supported on ``NetBSD``. MPLS requires a Linux Kernel + (4.5 or higher). LDP can be built, but may have limited use without + MPLS + +Install required packages +------------------------- + +Configure Package location: + +:: + + PKG_PATH="ftp://ftp.NetBSD.org/pub/pkgsrc/packages/NetBSD/`uname -m`/`uname -r`/All" + export PKG_PATH + +Add packages: + +:: + + sudo pkg_add git autoconf automake libtool gmake gawk openssl \ + pkg-config json-c python27 py27-test python35 + +Install SSL Root Certificates (for git https access): + +:: + + sudo pkg_add mozilla-rootcerts + sudo touch /etc/openssl/openssl.cnf + sudo mozilla-rootcerts install + +Select default Python and py.test + +:: + + sudo ln -s /usr/pkg/bin/python2.7 /usr/bin/python + sudo ln -s /usr/pkg/bin/py.test-2.7 /usr/bin/py.test + +Get FRR, compile it and install it (from Git) +--------------------------------------------- + +Add frr groups and user +~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo groupadd -g 92 frr + sudo groupadd -g 93 frrvty + sudo useradd -g 92 -u 92 -G frrvty -c "FRR suite" \ + -d /nonexistent -s /sbin/nologin frr + +Download Source, configure and compile it +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +(You may prefer different options on configure statement. These are just +an example) + +:: + + git clone https://github.com/frrouting/frr.git frr + cd frr + ./bootstrap.sh + MAKE=gmake + export LDFLAGS="-L/usr/pkg/lib -R/usr/pkg/lib" + export CPPFLAGS="-I/usr/pkg/include" + ./configure \ + --sysconfdir=/usr/pkg/etc/frr \ + --enable-exampledir=/usr/pkg/share/examples/frr \ + --enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \ + --localstatedir=/var/run/frr \ + --enable-ospfclient=yes \ + --enable-ospfapi=yes \ + --enable-multipath=64 \ + --enable-user=frr \ + --enable-group=frr \ + --enable-vty-group=frrvty \ + --enable-configfile-mask=0640 \ + --enable-logfile-mask=0640 \ + --enable-rtadv \ + --enable-fpm \ + --with-pkg-git-version \ + --with-pkg-extra-version=-MyOwnFRRVersion + gmake + gmake check + sudo gmake install + +Create empty FRR configuration files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo mkdir /var/log/frr + sudo mkdir /usr/pkg/etc/frr + sudo touch /usr/pkg/etc/frr/zebra.conf + sudo touch /usr/pkg/etc/frr/bgpd.conf + sudo touch /usr/pkg/etc/frr/ospfd.conf + sudo touch /usr/pkg/etc/frr/ospf6d.conf + sudo touch /usr/pkg/etc/frr/isisd.conf + sudo touch /usr/pkg/etc/frr/ripd.conf + sudo touch /usr/pkg/etc/frr/ripngd.conf + sudo touch /usr/pkg/etc/frr/pimd.conf + sudo chown -R frr:frr /usr/pkg/etc/frr + sudo touch /usr/local/etc/frr/vtysh.conf + sudo chown frr:frrvty /usr/pkg/etc/frr/*.conf + sudo chmod 640 /usr/pkg/etc/frr/*.conf + +Enable IP & IPv6 forwarding +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Add the following lines to the end of ``/etc/sysctl.conf``: + +:: + + # Routing: We need to forward packets + net.inet.ip.forwarding=1 + net.inet6.ip6.forwarding=1 + +**Reboot** or use ``sysctl`` to apply the same config to the running +system + +Install rc.d init files +~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + cp pkgsrc/*.sh /etc/rc.d/ + chmod 555 /etc/rc.d/*.sh + +Enable FRR processes +~~~~~~~~~~~~~~~~~~~~ + +(Enable the required processes only) + +:: + + echo "zebra=YES" >> /etc/rc.conf + echo "bgpd=YES" >> /etc/rc.conf + echo "ospfd=YES" >> /etc/rc.conf + echo "ospf6d=YES" >> /etc/rc.conf + echo "isisd=YES" >> /etc/rc.conf + echo "ripngd=YES" >> /etc/rc.conf + echo "ripd=YES" >> /etc/rc.conf + echo "pimd=YES" >> /etc/rc.conf diff --git a/doc/developer/Building_FRR_on_NetBSD7.rst b/doc/developer/Building_FRR_on_NetBSD7.rst new file mode 100644 index 0000000000..e4ff1df8a5 --- /dev/null +++ b/doc/developer/Building_FRR_on_NetBSD7.rst @@ -0,0 +1,137 @@ +NetBSD 7 +======================================== + +NetBSD 7 restrictions: +---------------------- + +- MPLS is not supported on ``NetBSD``. MPLS requires a Linux Kernel + (4.5 or higher). LDP can be built, but may have limited use without + MPLS + +Install required packages +------------------------- + +:: + + sudo pkgin install git autoconf automake libtool gmake gawk openssl \ + pkg-config json-c python27 py27-test python35 + +Install SSL Root Certificates (for git https access): + +:: + + sudo pkgin install mozilla-rootcerts + sudo touch /etc/openssl/openssl.cnf + sudo mozilla-rootcerts install + +Select default Python and py.test + +:: + + sudo ln -s /usr/pkg/bin/python2.7 /usr/bin/python + sudo ln -s /usr/pkg/bin/py.test-2.7 /usr/bin/py.test + +Get FRR, compile it and install it (from Git) +--------------------------------------------- + +Add frr groups and user +~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo groupadd -g 92 frr + sudo groupadd -g 93 frrvty + sudo useradd -g 92 -u 92 -G frrvty -c "FRR suite" \ + -d /nonexistent -s /sbin/nologin frr + +Download Source, configure and compile it +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +(You may prefer different options on configure statement. These are just +an example) + +:: + + git clone https://github.com/frrouting/frr.git frr + cd frr + ./bootstrap.sh + MAKE=gmake + export LDFLAGS="-L/usr/pkg/lib -R/usr/pkg/lib" + export CPPFLAGS="-I/usr/pkg/include" + ./configure \ + --sysconfdir=/usr/pkg/etc/frr \ + --enable-exampledir=/usr/pkg/share/examples/frr \ + --enable-pkgsrcrcdir=/usr/pkg/share/examples/rc.d \ + --localstatedir=/var/run/frr \ + --enable-ospfclient=yes \ + --enable-ospfapi=yes \ + --enable-multipath=64 \ + --enable-user=frr \ + --enable-group=frr \ + --enable-vty-group=frrvty \ + --enable-configfile-mask=0640 \ + --enable-logfile-mask=0640 \ + --enable-rtadv \ + --enable-fpm \ + --with-pkg-git-version \ + --with-pkg-extra-version=-MyOwnFRRVersion + gmake + gmake check + sudo gmake install + +Create empty FRR configuration files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo mkdir /usr/pkg/etc/frr + sudo touch /usr/pkg/etc/frr/zebra.conf + sudo touch /usr/pkg/etc/frr/bgpd.conf + sudo touch /usr/pkg/etc/frr/ospfd.conf + sudo touch /usr/pkg/etc/frr/ospf6d.conf + sudo touch /usr/pkg/etc/frr/isisd.conf + sudo touch /usr/pkg/etc/frr/ripd.conf + sudo touch /usr/pkg/etc/frr/ripngd.conf + sudo touch /usr/pkg/etc/frr/pimd.conf + sudo chown -R frr:frr /usr/pkg/etc/frr + sudo touch /usr/local/etc/frr/vtysh.conf + sudo chown frr:frrvty /usr/pkg/etc/frr/*.conf + sudo chmod 640 /usr/pkg/etc/frr/*.conf + +Enable IP & IPv6 forwarding +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Add the following lines to the end of ``/etc/sysctl.conf``: + +:: + + # Routing: We need to forward packets + net.inet.ip.forwarding=1 + net.inet6.ip6.forwarding=1 + +**Reboot** or use ``sysctl`` to apply the same config to the running +system + +Install rc.d init files +~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + cp pkgsrc/*.sh /etc/rc.d/ + chmod 555 /etc/rc.d/*.sh + +Enable FRR processes +~~~~~~~~~~~~~~~~~~~~ + +(Enable the required processes only) + +:: + + echo "zebra=YES" >> /etc/rc.conf + echo "bgpd=YES" >> /etc/rc.conf + echo "ospfd=YES" >> /etc/rc.conf + echo "ospf6d=YES" >> /etc/rc.conf + echo "isisd=YES" >> /etc/rc.conf + echo "ripngd=YES" >> /etc/rc.conf + echo "ripd=YES" >> /etc/rc.conf + echo "pimd=YES" >> /etc/rc.conf diff --git a/doc/developer/Building_FRR_on_OmniOS.rst b/doc/developer/Building_FRR_on_OmniOS.rst new file mode 100644 index 0000000000..bc4ff45715 --- /dev/null +++ b/doc/developer/Building_FRR_on_OmniOS.rst @@ -0,0 +1,142 @@ +OmniOS (OpenSolaris) +==================================================== + +OmniOS restrictions: +-------------------- + +- MPLS is not supported on ``OmniOS`` or ``Solaris``. MPLS requires a + Linux Kernel (4.5 or higher). LDP can be built, but may have limited + use without MPLS + +Enable IP & IPv6 forwarding +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + routeadm -e ipv4-forwarding + routeadm -e ipv6-forwarding + +Install required packages +------------------------- + +Add packages: + +:: + + pkg install \ + developer/build/autoconf \ + developer/build/automake \ + developer/lexer/flex \ + developer/parser/bison \ + developer/object-file \ + developer/linker \ + developer/library/lint \ + developer/build/gnu-make \ + developer/gcc51 \ + library/idnkit \ + library/idnkit/header-idnkit \ + system/header \ + system/library/math/header-math \ + git libtool gawk pkg-config + +Add additional Solaris packages: + +:: + + pkgadd -d http://get.opencsw.org/now + /opt/csw/bin/pkgutil -U + /opt/csw/bin/pkgutil -y -i texinfo + /opt/csw/bin/pkgutil -y -i perl + /opt/csw/bin/pkgutil -y -i libjson_c_dev + /opt/csw/bin/pkgutil -y -i python27 py_pip python27_dev + +Add libjson to Solaris equivalent of ld.so.conf + +:: + + crle -l /opt/csw/lib -u + +Add pytest: + +:: + + pip install pytest + +Select Python 2.7 as default (required for pytest) + +:: + + rm -f /usr/bin/python + ln -s /opt/csw/bin/python2.7 /usr/bin/python + +Fix PATH for all users and non-interactive sessions. Edit +``/etc/default/login`` and add the following default PATH: + +:: + + PATH=/usr/gnu/bin:/usr/bin:/usr/sbin:/sbin:/opt/csw/bin + +Edit ``~/.profile`` and add the following default PATH: + +:: + + PATH=/usr/gnu/bin:/usr/bin:/usr/sbin:/sbin:/opt/csw/bin + +Get FRR, compile it and install it (from Git) +--------------------------------------------- + +**This assumes you want to build and install FRR from source and not +using any packages** + +Add frr group and user +~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo groupadd -g 93 frr + sudo groupadd -g 94 frrvty + sudo useradd -g 93 -u 93 -G frrvty -c "FRR suite" \ + -d /nonexistent -s /bin/false frr + +(You may prefer different options on configure statement. These are just +an example) + +:: + + git clone https://github.com/frrouting/frr.git frr + cd frr + ./bootstrap.sh + export MAKE=gmake + export LDFLAGS="-L/opt/csw/lib" + export CPPFLAGS="-I/opt/csw/include" + export PKG_CONFIG_PATH=/opt/csw/lib/pkgconfig + ./configure \ + --sysconfdir=/etc/frr \ + --enable-exampledir=/usr/share/doc/frr/examples/ \ + --localstatedir=/var/run/frr \ + --sbindir=/usr/lib/frr \ + --enable-vtysh \ + --enable-watchfrr \ + --enable-ospfclient=yes \ + --enable-ospfapi=yes \ + --enable-multipath=64 \ + --enable-user=frr \ + --enable-group=frr \ + --enable-vty-group=frrvty \ + --enable-configfile-mask=0640 \ + --enable-logfile-mask=0640 \ + --enable-rtadv \ + --enable-fpm \ + --with-pkg-git-version \ + --with-pkg-extra-version=-MyOwnFRRVersion + gmake + gmake check + sudo gmake install + +Enable IP & IPv6 forwarding +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + routeadm -e ipv4-forwarding + routeadm -e ipv6-forwarding diff --git a/doc/developer/Building_FRR_on_OpenBSD6.rst b/doc/developer/Building_FRR_on_OpenBSD6.rst new file mode 100644 index 0000000000..0e51c8660c --- /dev/null +++ b/doc/developer/Building_FRR_on_OpenBSD6.rst @@ -0,0 +1,169 @@ +OpenBSD 6 +========================================= + +Install required packages +------------------------- + +Configure PKG\_PATH + +:: + + export PKG_PATH=http://ftp5.usa.openbsd.org/pub/OpenBSD/$(uname -r)/packages/$(machine -a)/ + +Add packages: + +:: + + pkg_add git autoconf-2.69p2 automake-1.15p0 libtool bison + pkg_add gmake gawk dejagnu openssl json-c py-test + +Select Python2.7 as default (required for pytest) + +:: + + ln -s /usr/local/bin/python2.7 /usr/local/bin/python + +Get FRR, compile it and install it (from Git) +--------------------------------------------- + +**This assumes you want to build and install FRR from source and not +using any packages** + +Add frr group and user +~~~~~~~~~~~~~~~~~~~~~~ + +:: + + groupadd -g 525 _frr + groupadd -g 526 _frrvty + useradd -g 525 -u 525 -c "FRR suite" -G _frrvty \ + -d /nonexistent -s /sbin/nologin _frr + +Download Source, configure and compile it +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +(You may prefer different options on configure statement. These are just +an example) + +:: + + git clone https://github.com/frrouting/frr.git frr + cd frr + export AUTOCONF_VERSION="2.69" + export AUTOMAKE_VERSION="1.15" + ./bootstrap.sh + export LDFLAGS="-L/usr/local/lib" + export CPPFLAGS="-I/usr/local/include" + ./configure \ + --sysconfdir=/etc/frr \ + --localstatedir=/var/frr \ + --enable-pimd \ + --enable-ospfclient=yes \ + --enable-ospfapi=yes \ + --enable-multipath=64 \ + --enable-user=_frr \ + --enable-group=_frr \ + --enable-vty-group=_frrvty \ + --enable-configfile-mask=0640 \ + --enable-logfile-mask=0640 \ + --enable-rtadv \ + --enable-fpm \ + --with-pkg-git-version \ + --with-pkg-extra-version=-MyOwnFRRVersion + gmake + gmake check + doas gmake install + +Create empty FRR configuration files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + doas mkdir /var/frr + doas chown _frr:_frr /var/frr + doas chmod 755 /var/frr + doas mkdir /etc/frr + doas touch /etc/frr/zebra.conf + doas touch /etc/frr/bgpd.conf + doas touch /etc/frr/ospfd.conf + doas touch /etc/frr/ospf6d.conf + doas touch /etc/frr/isisd.conf + doas touch /etc/frr/ripd.conf + doas touch /etc/frr/ripngd.conf + doas touch /etc/frr/pimd.conf + doas touch /etc/frr/ldpd.conf + doas touch /etc/frr/nhrpd.conf + doas chown -R _frr:_frr /etc/frr + doas touch /etc/frr/vtysh.conf + doas chown -R _frr:_frrvty /etc/frr/vtysh.conf + doas chmod 750 /etc/frr + doas chmod 640 /etc/frr/*.conf + +Enable IP & IPv6 forwarding +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Add the following lines to the end of ``/etc/rc.conf``: + +:: + + net.inet6.ip6.forwarding=1 # 1=Permit forwarding of IPv6 packets + net.inet6.ip6.mforwarding=1 # 1=Permit forwarding of IPv6 multicast packets + net.inet6.ip6.multipath=1 # 1=Enable IPv6 multipath routing + +**Reboot** to apply the config to the system + +Enable MPLS Forwarding +~~~~~~~~~~~~~~~~~~~~~~ + +To enable MPLS forwarding on a given interface, use the following +command: + +:: + + doas ifconfig em0 mpls + +Alternatively, to make MPLS forwarding persistent across reboots, add +the "mpls" keyword in the hostname.\* files of the desired interfaces. +Example: + +:: + + cat /etc/hostname.em0 + inet 10.0.1.1 255.255.255.0 mpls + +Install rc.d init files +~~~~~~~~~~~~~~~~~~~~~~~ + +(create them in /etc/rc.d - no example are included at this time with +FRR source) + +Example (for zebra - store as ``/etc/rc.d/frr_zebra.sh``) + +:: + + #!/bin/sh + # + # $OpenBSD: frr_zebra.rc,v 1.1 2013/04/18 20:29:08 sthen Exp $ + + daemon="/usr/local/sbin/zebra -d" + + . /etc/rc.d/rc.subr + + rc_cmd $1 + +Enable FRR processes +~~~~~~~~~~~~~~~~~~~~ + +(Enable the required processes only) + +:: + + echo "frr_zebra=YES" >> /etc/rc.conf + echo "frr_bgpd=YES" >> /etc/rc.conf + echo "frr_ospfd=YES" >> /etc/rc.conf + echo "frr_ospf6d=YES" >> /etc/rc.conf + echo "frr_isisd=YES" >> /etc/rc.conf + echo "frr_ripngd=YES" >> /etc/rc.conf + echo "frr_ripd=YES" >> /etc/rc.conf + echo "frr_pimd=YES" >> /etc/rc.conf + echo "frr_ldpd=YES" >> /etc/rc.conf diff --git a/doc/developer/Building_FRR_on_Ubuntu1204.rst b/doc/developer/Building_FRR_on_Ubuntu1204.rst new file mode 100644 index 0000000000..935d199842 --- /dev/null +++ b/doc/developer/Building_FRR_on_Ubuntu1204.rst @@ -0,0 +1,187 @@ +Ubuntu 12.04LTS +=============================================== + +- MPLS is not supported on ``Ubuntu 12.04`` with default kernel. MPLS + requires Linux Kernel 4.5 or higher (LDP can be built, but may have + limited use without MPLS) For an updated Ubuntu Kernel, see + http://kernel.ubuntu.com/~kernel-ppa/mainline/ + +Install required packages +------------------------- + +Add packages: + +:: + + apt-get install git autoconf automake libtool make gawk libreadline-dev \ + texinfo libpam0g-dev dejagnu libjson0-dev pkg-config libpam0g-dev \ + libjson0-dev flex python-pip libc-ares-dev python3-dev + +Install newer bison from 14.04 package source (Ubuntu 12.04 package +source is too old) + +:: + + mkdir builddir + cd builddir + wget http://archive.ubuntu.com/ubuntu/pool/main/b/bison/bison_3.0.2.dfsg-2.dsc + wget http://archive.ubuntu.com/ubuntu/pool/main/b/bison/bison_3.0.2.dfsg.orig.tar.bz2 + wget http://archive.ubuntu.com/ubuntu/pool/main/b/bison/bison_3.0.2.dfsg-2.debian.tar.gz + tar -jxvf bison_3.0.2.dfsg.orig.tar.bz2 + cd bison-3.0.2.dfsg/ + tar xzf ../bison_3.0.2.dfsg-2.debian.tar.gz + sudo apt-get build-dep bison + debuild -b -uc -us + cd .. + sudo dpkg -i ./libbison-dev_3.0.2.dfsg-2_amd64.deb ./bison_3.0.2.dfsg-2_amd64.deb + cd .. + rm -rf builddir + +Install newer version of autoconf and automake: + +:: + + wget http://ftp.gnu.org/gnu/autoconf/autoconf-2.69.tar.gz + tar xvf autoconf-2.69.tar.gz + cd autoconf-2.69 + ./configure --prefix=/usr + make + sudo make install + cd .. + + wget http://ftp.gnu.org/gnu/automake/automake-1.15.tar.gz + tar xvf automake-1.15.tar.gz + cd automake-1.15 + ./configure --prefix=/usr + make + sudo make install + cd .. + +Install pytest: + +:: + + pip install pytest + +Get FRR, compile it and install it (from Git) +--------------------------------------------- + +**This assumes you want to build and install FRR from source and not +using any packages** + +Add frr groups and user +~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo groupadd -g 92 frr + sudo groupadd -r -g 85 frrvty + sudo adduser --system --ingroup frr --home /var/run/frr/ \ + --gecos "FRR suite" --shell /sbin/nologin frr + sudo usermod -a -G frrvty frr + +Download Source, configure and compile it +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +(You may prefer different options on configure statement. These are just +an example.) + +:: + + git clone https://github.com/frrouting/frr.git frr + cd frr + ./bootstrap.sh + ./configure \ + --prefix=/usr \ + --enable-exampledir=/usr/share/doc/frr/examples/ \ + --localstatedir=/var/run/frr \ + --sbindir=/usr/lib/frr \ + --sysconfdir=/etc/frr \ + --enable-pimd \ + --enable-watchfrr \ + --enable-ospfclient=yes \ + --enable-ospfapi=yes \ + --enable-multipath=64 \ + --enable-user=frr \ + --enable-group=frr \ + --enable-vty-group=frrvty \ + --enable-configfile-mask=0640 \ + --enable-logfile-mask=0640 \ + --enable-rtadv \ + --enable-fpm \ + --with-pkg-git-version \ + --with-pkg-extra-version=-MyOwnFRRVersion + make + make check + sudo make install + +Create empty FRR configuration files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo install -m 755 -o frr -g frr -d /var/log/frr + sudo install -m 775 -o frr -g frrvty -d /etc/frr + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/zebra.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/bgpd.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospfd.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospf6d.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/isisd.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripd.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripngd.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/pimd.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ldpd.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/nhrpd.conf + sudo install -m 640 -o frr -g frrvty /dev/null /etc/frr/vtysh.conf + +Enable IP & IPv6 forwarding +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Edit ``/etc/sysctl.conf`` and uncomment the following values (ignore the +other settings) + +:: + + # Uncomment the next line to enable packet forwarding for IPv4 + net.ipv4.ip_forward=1 + + # Uncomment the next line to enable packet forwarding for IPv6 + # Enabling this option disables Stateless Address Autoconfiguration + # based on Router Advertisements for this host + net.ipv6.conf.all.forwarding=1 + +**Reboot** or use ``sysctl -p`` to apply the same config to the running +system + +Install the init.d service +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo install -m 755 tools/frr /etc/init.d/frr + sudo install -m 644 tools/etc/frr/daemons /etc/frr/daemons + sudo install -m 644 tools/etc/frr/daemons.conf /etc/frr/daemons.conf + sudo install -m 644 -o frr -g frr tools/etc/frr/vtysh.conf /etc/frr/vtysh.conf + +Enable daemons +~~~~~~~~~~~~~~ + +| Edit ``/etc/frr/daemons`` and change the value from "no" to "yes" for + those daemons you want to start by systemd. +| For example. + +:: + + zebra=yes + bgpd=yes + ospfd=yes + ospf6d=yes + ripd=yes + ripngd=yes + isisd=yes + +Start the init.d service +~~~~~~~~~~~~~~~~~~~~~~~~ + +- /etc/init.d/frr start +- use ``/etc/init.d/frr status`` to check its status. diff --git a/doc/developer/Building_FRR_on_Ubuntu1404.rst b/doc/developer/Building_FRR_on_Ubuntu1404.rst new file mode 100644 index 0000000000..4a4e38ea30 --- /dev/null +++ b/doc/developer/Building_FRR_on_Ubuntu1404.rst @@ -0,0 +1,139 @@ +Ubuntu 14.04LTS +=============================================== + +- MPLS is not supported on ``Ubuntu 14.04`` with default kernel. MPLS + requires Linux Kernel 4.5 or higher (LDP can be built, but may have + limited use without MPLS) For an updated Ubuntu Kernel, see + http://kernel.ubuntu.com/~kernel-ppa/mainline/ + +Install required packages +------------------------- + +Add packages: + +:: + + apt-get install git autoconf automake libtool make gawk libreadline-dev \ + texinfo dejagnu pkg-config libpam0g-dev libjson-c-dev bison flex \ + python-pytest libc-ares-dev python3-dev + +Get FRR, compile it and install it (from Git) +--------------------------------------------- + +**This assumes you want to build and install FRR from source and not +using any packages** + +Add frr groups and user +~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo groupadd -g 92 frr + sudo groupadd -r -g 85 frrvty + sudo adduser --system --ingroup frr --home /var/run/frr/ \ + --gecos "FRR suite" --shell /sbin/nologin frr + sudo usermod -a -G frrvty frr + +Download Source, configure and compile it +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +(You may prefer different options on configure statement. These are just +an example.) + +:: + + git clone https://github.com/frrouting/frr.git frr + cd frr + ./bootstrap.sh + ./configure \ + --prefix=/usr \ + --enable-exampledir=/usr/share/doc/frr/examples/ \ + --localstatedir=/var/run/frr \ + --sbindir=/usr/lib/frr \ + --sysconfdir=/etc/frr \ + --enable-pimd \ + --enable-watchfrr \ + --enable-ospfclient=yes \ + --enable-ospfapi=yes \ + --enable-multipath=64 \ + --enable-user=frr \ + --enable-group=frr \ + --enable-vty-group=frrvty \ + --enable-configfile-mask=0640 \ + --enable-logfile-mask=0640 \ + --enable-rtadv \ + --enable-fpm \ + --enable-ldpd \ + --with-pkg-git-version \ + --with-pkg-extra-version=-MyOwnFRRVersion + make + make check + sudo make install + +Create empty FRR configuration files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo install -m 755 -o frr -g frr -d /var/log/frr + sudo install -m 775 -o frr -g frrvty -d /etc/frr + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/zebra.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/bgpd.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospfd.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospf6d.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/isisd.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripd.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripngd.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/pimd.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ldpd.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/nhrpd.conf + sudo install -m 640 -o frr -g frrvty /dev/null /etc/frr/vtysh.conf + +Enable IP & IPv6 forwarding +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Edit ``/etc/sysctl.conf`` and uncomment the following values (ignore the +other settings) + +:: + + # Uncomment the next line to enable packet forwarding for IPv4 + net.ipv4.ip_forward=1 + + # Uncomment the next line to enable packet forwarding for IPv6 + # Enabling this option disables Stateless Address Autoconfiguration + # based on Router Advertisements for this host + net.ipv6.conf.all.forwarding=1 + +**Reboot** or use ``sysctl -p`` to apply the same config to the running +system ### Install the init.d service + +:: + + sudo install -m 755 tools/frr /etc/init.d/frr + sudo install -m 644 tools/etc/frr/daemons /etc/frr/daemons + sudo install -m 644 tools/etc/frr/daemons.conf /etc/frr/daemons.conf + sudo install -m 644 -o frr -g frr tools/etc/frr/vtysh.conf /etc/frr/vtysh.conf + +Enable daemons +~~~~~~~~~~~~~~ + +| Edit ``/etc/frr/daemons`` and change the value from "no" to "yes" for + those daemons you want to start by systemd. +| For example. + +:: + + zebra=yes + bgpd=yes + ospfd=yes + ospf6d=yes + ripd=yes + ripngd=yes + isisd=yes + +Start the init.d service +~~~~~~~~~~~~~~~~~~~~~~~~ + +- /etc/init.d/frr start +- use ``/etc/init.d/frr status`` to check its status. diff --git a/doc/developer/Building_FRR_on_Ubuntu1604.rst b/doc/developer/Building_FRR_on_Ubuntu1604.rst new file mode 100644 index 0000000000..dccc37adcc --- /dev/null +++ b/doc/developer/Building_FRR_on_Ubuntu1604.rst @@ -0,0 +1,175 @@ +Ubuntu 16.04LTS +=============================================== + +- MPLS is not supported on ``Ubuntu 16.04`` with default kernel. MPLS + requires Linux Kernel 4.5 or higher (LDP can be built, but may have + limited use without MPLS) For an updated Ubuntu Kernel, see + http://kernel.ubuntu.com/~kernel-ppa/mainline/ + +Install required packages +------------------------- + +Add packages: + +:: + + apt-get install git autoconf automake libtool make gawk libreadline-dev \ + texinfo dejagnu pkg-config libpam0g-dev libjson-c-dev bison flex \ + python-pytest libc-ares-dev python3-dev libsystemd-dev python-ipaddr + +Get FRR, compile it and install it (from Git) +--------------------------------------------- + +**This assumes you want to build and install FRR from source and not +using any packages** + +Add frr groups and user +~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo groupadd -g 92 frr + sudo groupadd -r -g 85 frrvty + sudo adduser --system --ingroup frr --home /var/run/frr/ \ + --gecos "FRR suite" --shell /sbin/nologin frr + sudo usermod -a -G frrvty frr + +Download Source, configure and compile it +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +(You may prefer different options on configure statement. These are just +an example.) + +:: + + git clone https://github.com/frrouting/frr.git frr + cd frr + ./bootstrap.sh + ./configure \ + --prefix=/usr \ + --enable-exampledir=/usr/share/doc/frr/examples/ \ + --localstatedir=/var/run/frr \ + --sbindir=/usr/lib/frr \ + --sysconfdir=/etc/frr \ + --enable-pimd \ + --enable-watchfrr \ + --enable-ospfclient=yes \ + --enable-ospfapi=yes \ + --enable-multipath=64 \ + --enable-user=frr \ + --enable-group=frr \ + --enable-vty-group=frrvty \ + --enable-configfile-mask=0640 \ + --enable-logfile-mask=0640 \ + --enable-rtadv \ + --enable-fpm \ + --enable-systemd=yes \ + --with-pkg-git-version \ + --with-pkg-extra-version=-MyOwnFRRVersion + make + make check + sudo make install + +Create empty FRR configuration files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo install -m 755 -o frr -g frr -d /var/log/frr + sudo install -m 775 -o frr -g frrvty -d /etc/frr + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/zebra.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/bgpd.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospfd.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ospf6d.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/isisd.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripd.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ripngd.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/pimd.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/ldpd.conf + sudo install -m 640 -o frr -g frr /dev/null /etc/frr/nhrpd.conf + sudo install -m 640 -o frr -g frrvty /dev/null /etc/frr/vtysh.conf + +Enable IPv4 & IPv6 forwarding +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Edit ``/etc/sysctl.conf`` and uncomment the following values (ignore the +other settings) + +:: + + # Uncomment the next line to enable packet forwarding for IPv4 + net.ipv4.ip_forward=1 + + # Uncomment the next line to enable packet forwarding for IPv6 + # Enabling this option disables Stateless Address Autoconfiguration + # based on Router Advertisements for this host + net.ipv6.conf.all.forwarding=1 + +Enable MPLS Forwarding (with Linux Kernel >= 4.5) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Edit ``/etc/sysctl.conf`` and the following lines. Make sure to add a +line equal to ``net.mpls.conf.eth0.input`` or each interface used with +MPLS + +:: + + # Enable MPLS Label processing on all interfaces + net.mpls.conf.eth0.input=1 + net.mpls.conf.eth1.input=1 + net.mpls.conf.eth2.input=1 + net.mpls.platform_labels=100000 + +Add MPLS kernel modules +~~~~~~~~~~~~~~~~~~~~~~~ + +Add the following lines to ``/etc/modules-load.d/modules.conf``: + +:: + + # Load MPLS Kernel Modules + mpls-router + mpls-iptunnel + +**Reboot** or use ``sysctl -p`` to apply the same config to the running +system + +Install the systemd service (if rebooted from last step, change directory back to frr directory) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:: + + sudo install -m 644 tools/frr.service /etc/systemd/system/frr.service + sudo install -m 644 tools/etc/default/frr /etc/default/frr + sudo install -m 644 tools/etc/frr/daemons /etc/frr/daemons + sudo install -m 644 tools/etc/frr/daemons.conf /etc/frr/daemons.conf + sudo install -m 644 tools/etc/frr/frr.conf /etc/frr/frr.conf + sudo install -m 644 -o frr -g frr tools/etc/frr/vtysh.conf /etc/frr/vtysh.conf + +Enable daemons +~~~~~~~~~~~~~~ + +| Edit ``/etc/frr/daemons`` and change the value from "no" to "yes" for + those daemons you want to start by systemd. +| For example. + +:: + + zebra=yes + bgpd=yes + ospfd=yes + ospf6d=yes + ripd=yes + ripngd=yes + isisd=yes + +Enable the systemd service +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +- systemctl enable frr + +Start the systemd service +~~~~~~~~~~~~~~~~~~~~~~~~~ + +- systemctl start frr +- use ``systemctl status frr`` to check its status. diff --git a/doc/developer/building.rst b/doc/developer/building.rst new file mode 100644 index 0000000000..4715bca532 --- /dev/null +++ b/doc/developer/building.rst @@ -0,0 +1,22 @@ +Building FRR +========================= + +.. toctree:: + :maxdepth: 2 + + Building_FRR_on_LEDE-OpenWRT + Building_FRR_on_CentOS6 + Building_FRR_on_CentOS7 + Building_FRR_on_Debian8 + Building_FRR_on_Debian9 + Building_FRR_on_Fedora24 + Building_FRR_on_FreeBSD10 + Building_FRR_on_FreeBSD11 + Building_FRR_on_FreeBSD9 + Building_FRR_on_NetBSD6 + Building_FRR_on_NetBSD7 + Building_FRR_on_OmniOS + Building_FRR_on_OpenBSD6 + Building_FRR_on_Ubuntu1204 + Building_FRR_on_Ubuntu1404 + Building_FRR_on_Ubuntu1604 diff --git a/doc/developer/cli.rst b/doc/developer/cli.rst new file mode 100644 index 0000000000..7462887410 --- /dev/null +++ b/doc/developer/cli.rst @@ -0,0 +1,615 @@ +FRR Command Line Interface +========================== + +Definition Grammar +------------------ + +This is a reference for the syntax used when defining new CLI commands. +An example definition is: + +:: + + DEFUN (command_name, + command_name_cmd, + --> "example DEFINITION...", + <..doc strings..>) + +The arrowed part is the definition string. + +Explicit syntax rules in Flex and Bison may be found in +lib/command\_lex.l and lib/command\_parse.y, respectively. If you can +read BNF and regex those will be more useful than this document. + +If the parser is throwing syntax or other errors and you can't figure +out why, it's unlikely to be a bug in the parser. If the error message +is not useful, please file a bug for a better error message. If all else +fails, read the token definitions in the lexer source and the Bison BNF +in the parser source. + +Characters allowed in each token type: + +Tokens +------ + +- ``WORD`` -- A token that begins with +, -, or a lowercase letter. It + is an unchanging part of the command and will only match itself. + Example: "show ip bgp", every token is a WORD. +- ``IPV4`` -- 'A.B.C.D', matches an IPv4 address. +- ``IPV6`` -- 'X:X::X:X', matches an IPv6 address. +- ``IPV4_PREFIX`` -- 'A.B.C.D/M', matches an IPv4 prefix in CIDR + notation. +- ``IPV6_PREFIX`` -- 'X:X::X:X/M', matches an IPv6 prefix in CIDR + notation. +- ``MAC`` -- 'M:A:C', matches a 48-bit mac address +- ``MAC_PREFIX`` -- 'M:A:C/M', matches a 48-bit mac address with a mask +- ``VARIABLE`` -- Begins with a capital letter. Matches any input. +- ``RANGE`` -- Numeric range delimited by parentheses, e.g. (-100 - + 100) or (10-20). Will only match numbers in the range. + +Rules +----- + +- ```` -- Contain sequences of tokens separated by + pipes and provide mutual exclusion. Sequences may contain + ```` but not as the first token. Disallowed: + ``"example < c|d>"`` Allowed: ``"example "`` +- ``[square brackets]`` -- Contains sequences of tokens that are + optional (can be omitted). ``[]`` can be shortened to ``[a|b]``. +- ``{curly|braces}`` -- similar to angle brackets, but instead of + mutual exclusion, curly braces indicate that one or more of the + pipe-separated sequences may be provided in any order. +- ``VARIADICS...`` -- Any token which accepts input (so anything except + WORD) and that occurs as the last token of a line may be followed by + an ellipsis, which indicates that input matching the token may be + repeated an unlimited number of times. +- ``$name`` -- Specify a variable name for the preceding token. See + "Variable Names" below. + +Some general notes: + +- Options are allowed at the beginning of the command. The developer is + entreated to use these extremely sparingly. They are most useful for + implementing the 'no' form of configuration commands. Please think + carefully before using them for anything else. There is usually a + better solution, even if it is just separating out the command + definition into separate ones. + +- The developer should judiciously apply separation of concerns when + defining + +CLI. CLI definitions for two unrelated or vaguely related commands or + configuration items should be defined in separate commands. Clarity + is preferred over LOC (within reason). + +- The maximum number of space-separated tokens that can be entered is + presently limited to 256. Please keep this limit in mind when + implementing new CLI. + +Variable Names +-------------- + +The parser tries to fill the "varname" field on each token. This can +happen either manually or automatically. Manual specifications work by +appending ``"$name"`` after the input specifier: + +:: + + foo bar$cmd WORD$name A.B.C.D$ip + +Note that you can also assign variable names to fixed input tokens, this +can be useful if multiple commands share code. You can also use "$name" +after a multiple-choice option: + +:: + + foo bar $addr [optionA|optionB]$mode + +The variable name is in this case assigned to the last token in each of +the branches. + +Automatic assignment of variable names works by applying the following +rules: + +- manual names always have priority +- a "[no]" at the beginning receives "no" as varname on the "no" token +- VARIABLE tokens whose text is not "WORD" or "NAME" receive a cleaned + lowercase version of the token text as varname, e.g. "ROUTE-MAP" + becomes "route\_map". +- other variable tokens (i.e. everything except "fixed") receive the + text of the preceding fixed token as varname, if one can be found. + E.g.: "ip route A.B.C.D/M INTERFACE" assigns "route" to the + "A.B.C.D/M" token. + +These rules should make it possible to avoid manual varname assignment +in 90% of the cases. + +DEFPY +----- + +``DEFPY(...)`` is an enhanced version of ``DEFUN()`` which is +preprocessed by ``python/clidef.py``. The python script parses the +command definition string, extracts variable names and types, and +generates a C wrapper function that parses the variables and passes them +on. This means that in the CLI function body, you will receive +additional parameters with appropriate types. + +This is best explained by an example: + +:: + + DEFPY(func, func_cmd, "[no] foo bar A.B.C.D (0-99)$num", "...help...") + + => + + func(self, vty, argc, argv, /* standard CLI arguments */ + + const char *no, /* unparsed "no" */ + struct in_addr bar, /* parsed IP address */ + const char *bar_str, /* unparsed IP address */ + long num, /* parsed num */ + const char *num_str) /* unparsed num */ + +Note that as documented in the previous section, "bar" is automatically +applied as variable name for "A.B.C.D". The python code then detects +this is an IP address argument and generates code to parse it into a +``struct in_addr``, passing it in ``bar``. The raw value is passed in +``bar_str``. The range/number argument works in the same way with the +explicitly given variable name. + +Type rules +~~~~~~~~~~ + ++------------------------------+----------------------------------+----------------------------+ +| Token(s) | Type | Value if omitted by user | ++==============================+==================================+============================+ +| ``A.B.C.D`` | ``struct in_addr`` | 0.0.0.0 | ++------------------------------+----------------------------------+----------------------------+ +| ``X:X::X:X`` | ``struct in6_addr`` | :: | ++------------------------------+----------------------------------+----------------------------+ +| ``A.B.C.D + X:X::X:X`` | ``const union sockunion *`` | NULL | ++------------------------------+----------------------------------+----------------------------+ +| ``A.B.C.D/M`` | ``const struct prefix_ipv4 *`` | NULL | ++------------------------------+----------------------------------+----------------------------+ +| ``X:X::X:X/M`` | ``const struct prefix_ipv6 *`` | NULL | ++------------------------------+----------------------------------+----------------------------+ +| ``A.B.C.D/M + X:X::X:X/M`` | ``const struct prefix *`` | NULL | ++------------------------------+----------------------------------+----------------------------+ +| ``(0-9)`` | ``long`` | 0 | ++------------------------------+----------------------------------+----------------------------+ +| ``VARIABLE`` | ``const char *`` | NULL | ++------------------------------+----------------------------------+----------------------------+ +| ``word`` | ``const char *`` | NULL | ++------------------------------+----------------------------------+----------------------------+ +| *all other* | ``const char *`` | NULL | ++------------------------------+----------------------------------+----------------------------+ + +Note the following details: + +- not all parameters are pointers, some are passed as values. +- when the type is not ``const char *``, there will be an extra + ``_str`` argument with type ``const char *``. +- you can give a variable name not only to ``VARIABLE`` tokens but also + to ``word`` tokens (e.g. constant words). This is useful if some + parts of a command are optional. The type will be ``const char *``. +- ``[no]`` will be passed as ``const char *no``. +- pointers will be NULL when the argument is optional and the user did + not use it. +- if a parameter is not a pointer, but is optional and the user didn't + use it, the default value will be passed. Check the ``_str`` argument + if you need to determine whether the parameter was omitted. +- if the definition contains multiple parameters with the same variable + name, they will be collapsed into a single function parameter. The + python code will detect if the types are compatible (i.e. IPv4 + IPv6 + variantes) and choose a corresponding C type. +- the standard DEFUN parameters (self, vty, argc, argv) are still + present and can be used. A DEFUN can simply be **edited into a DEFPY + without further changes and it will still work**; this allows easy + forward migration. +- a file may contain both DEFUN and DEFPY statements. + +Getting a parameter dump +~~~~~~~~~~~~~~~~~~~~~~~~ + +The clidef.py script can be called to get a list of DEFUNs/DEFPYs with +the parameter name/type list: + +:: + + lib/clippy python/clidef.py --all-defun --show lib/plist.c > /dev/null + +The generated code is printed to stdout, the info dump to stderr. The +``--all-defun`` argument will make it process DEFUN blocks as well as +DEFPYs, which is useful prior to converting some DEFUNs. **The dump does +not list the ``_str`` arguments** to keep the output shorter. + +Note that the clidef.py script cannot be run with python directly, it +needs to be run with *clippy* since the latter makes the CLI parser +available. + +Include & Makefile requirements +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A source file that uses DEFPY needs to include the ``_clippy.c`` file +**before all DEFPY statements**: + +:: + + /* GPL header */ + #include ... + + ... + + #include "daemon/filename_clippy.c" + + DEFPY(...) + DEFPY(...) + + install_element(...) + +This dependency needs to be marked in Makefile.am: (there is no ordering +requirement) + +:: + + include ../common.am + + # ... + + # if linked into a LTLIBRARY (.la/.so): + filename.lo: filename_clippy.c + + # if linked into an executable or static library (.a): + filename.o: filename_clippy.c + +Doc Strings +----------- + +Each token in a command definition should be documented with a brief doc +string that informs a user of the meaning and/or purpose of the +subsequent command tree. These strings are provided as the last +parameter to DEFUN macros, concatenated together and separated by an +escaped newline (':raw-latex:`\n`'). These are best explained by +example. + +:: + + DEFUN (config_terminal, + config_terminal_cmd, + "configure terminal", + "Configuration from vty interface\n" + "Configuration terminal\n") + +The last parameter is split into two lines for readability. Two newline +delimited doc strings are present, one for each token in the command. +The second string documents the functionality of the 'terminal' command +in the 'configure' tree. + +Note that the first string, for 'configure' does not contain +documentation for 'terminal'. This is because the CLI is best envisioned +as a tree, with tokens defining branches. An imaginary 'start' token is +the root of every command in a CLI node. Each subsequent written token +descends into a subtree, so the documentation for that token ideally +summarizes all the functionality contained in the subtree. + +A consequence of this structure is that the developer must be careful to +use the same doc strings when defining multiple commands that are part +of the same tree. Commands which share prefixes must share the same doc +strings for those prefixes. On startup the parser will generate warnings +if it notices inconsistent doc strings. Behavior is undefined; the same +token may show up twice in completions, with different doc strings, or +it may show up once with a random doc string. Parser warnings should be +heeded and fixed to avoid confusing users. + +The number of doc strings provided must be equal to the amount of tokens +present in the command definition, read left to right, ignoring any +special constructs. + +In the examples below, each arrowed token needs a doc string. + +:: + + "show ip bgp" + ^ ^ ^ + + "command [example]" + ^ ^ ^ ^ + +Data Structures +--------------- + +On startup, the CLI parser sequentially parses each command string +definition and constructs a directed graph with each token forming a +node. This graph is the basis of the entire CLI system. It is used to +match user input in order to generate command completions and match +commands to functions. + +There is one graph per CLI node (not the same as a graph node in the CLI +graph). The CLI node struct keeps a reference to its graph (see +lib/command.h). + +While most of the graph maintains the form of a tree, special constructs +outlined in the Rules section introduce some quirks. <>, [] and {} form +self-contained 'subgraphs'. Each subgraph is a tree except that all of +the 'leaves' actually share a child node. This helps with minimizing +graph size and debugging. + +As an example, the subgraph generated by looks like this: + +:: + + . + . + | + +----+---+ + +--- -+ FORK +----+ + | +--------+ | + +--v---+ +--v---+ + | foo | | bar | + +--+---+ +--+---+ + | +------+ | + +------> JOIN <-----+ + +---+--+ + | + . + . + +FORK and JOIN nodes are plumbing nodes that don't correspond to user +input. They're necessary in order to deduplicate these constructs where +applicable. + +Options follow the same form, except that there is an edge from the FORK +node to the JOIN node. + +Keywords follow the same form, except that there is an edge from JOIN to +FORK. Because of this the CLI graph cannot be called acyclic. There is +special logic in the input matching code that keeps a stack of paths +already taken through the node in order to disallow following the same +path more than once. + +Variadics are a bit special; they have an edge back to themselves, which +allows repeating the same input indefinitely. + +The leaves of the graph are nodes that have no out edges. These nodes +are special; their data section does not contain a token, as most nodes +do, or NULL, as in FORK/JOIN nodes, but instead has a pointer to a +cmd\_element. All paths through the graph that terminate on a leaf are +guaranteed to be defined by that command. When a user enters a complete +command, the command matcher tokenizes the input and executes a DFS on +the CLI graph. If it is simultaneously able to exhaust all input (one +input token per graph node), and then find exactly one leaf connected to +the last node it reaches, then the input has matched the corresponding +command and the command is executed. If it finds more than one node, +then the command is ambiguous (more on this in deduplication). If it +cannot exhaust all input, the command is unknown. If it exhausts all +input but does not find an edge node, the command is incomplete. + +The parser uses an incremental strategy to build the CLI graph for a +node. Each command is parsed into its own graph, and then this graph is +merged into the overall graph. During this merge step, the parser makes +a best-effort attempt to remove duplicate nodes. If it finds a node in +the overall graph that is equal to a node in the corresponding position +in the command graph, it will intelligently merge the properties from +the node in the command graph into the already-existing node. Subgraphs +are also checked for isomorphism and merged where possible. The +definition of whether two nodes are 'equal' is based on the equality of +some set of token properties; read the parser source for the most +up-to-date definition of equality. + +When the parser is unable to deduplicate some complicated constructs, +this can result in two identical paths through separate parts of the +graph. If this occurs and the user enters input that matches these +paths, they will receive an 'ambiguous command' error and will be unable +to execute the command. Most of the time the parser can detect and warn +about duplicate commands, but it will not always be able to do this. +Hence care should be taken before defining a new command to ensure it is +not defined elsewhere. + +Command handlers +---------------- + +The block that follows a CLI definition is executed when a user enters +input that matches the definition. Its function signature looks like +this: + +int (*func) (const struct cmd\_element *, struct vty *, int, struct +cmd\_token *\ []); + +The first argument is the command definition struct. The last argument +is an ordered array of tokens that correspond to the path taken through +the graph, and the argument just prior to that is the length of the +array. + +The arrangement of the token array has changed from the prior +incarnation of the CLI system. In the old system, missing arguments were +padded with NULLs so that the same parts of a command would show up at +the same indices regardless of what was entered. The new system does not +perform such padding and therefore it is generally *incorrect* to assume +consistent indices in this array. As a simple example: + +Command definition: + +:: + + command [foo] + +User enters: + +:: + + command foo bar + +Array: + +:: + + [0] -> command + [1] -> foo + [2] -> bar + +User enters: + +:: + + command baz + +Array: + +:: + + [0] -> command + [1] -> baz + +Command abbreviation & matching priority +---------------------------------------- + +As in the prior implementation, it is possible for users to elide parts +of tokens when the CLI matcher does not need them to make an unambiguous +match. This is best explained by example. + +Command definitions: + +:: + + command dog cow + command dog crow + +User input: + +:: + + c d c -> ambiguous command + c d co -> match "command dog cow" + +In the new implementation, this functionality has improved. Where +previously the parser would stop at the first ambiguous token, it will +now look ahead and attempt to disambiguate based on tokens later on in +the input string. + +Command definitions: + +:: + + show ip bgp A.B.C.D + show ipv6 bgp X:X::X:X + +User enters: + +:: + + s i b 4.3.2.1 -> match "show ip bgp A.B.C.D" + s i b ::e0 -> match "show ipv6 bgp X:X::X:X" + +Previously both of these commands would be ambiguous since 'i' does not +explicitly select either 'ip' or 'ipv6'. However, since the user later +provides a token that matches only one of the commands (an IPv4 or IPv6 +address) the parser is able to look ahead and select the appropriate +command. This has some implications for parsing the argv\*[] that is +passed to the command handler. + +Now consider a command definition such as: + +:: + + command + +'foo' only matches the string 'foo', but 'VAR' matches any input, +including 'foo'. Who wins? In situations like this the matcher will +always choose the 'better' match, so 'foo' will win. + +Consider also: + +:: + + show foo + +User input: + +:: + + show ip foo + +'ip' partially matches 'ipv6' but exactly matches 'ip', so 'ip' will +win. + +struct cmd\_token +----------------- + +:: + + /* Command token struct. */ + struct cmd_token + { + enum cmd_token_type type; // token type + u_char attr; // token attributes + bool allowrepeat; // matcher allowed to match token repetitively? + + char *text; // token text + char *desc; // token description + long long min, max; // for ranges + char *arg; // user input that matches this token + char *varname; // variable name + }; + +This struct is used in the CLI graph to match input against. It is also +used to pass user input to command handler functions, as it is +frequently useful for handlers to have access to that information. When +a command is matched, the sequence of cmd\_tokens that form the matching +path are duplicated and placed in order into argv\*[]. Before this +happens the ->arg field is set to point at the snippet of user input +that matched it. + +For most nontrivial commands the handler function will need to determine +which of the possible matching inputs was entered. Previously this was +done by looking at the first few characters of input. This is now +considered an anti-pattern and should be avoided. Instead, the ->type or +->text fields for this logic. The ->type field can be used when the +possible inputs differ in type. When the possible types are the same, +use the ->text field. This field has the full text of the corresponding +token in the definition string and using it makes for much more readable +code. An example is helpful. + +Command definition: + +:: + + command <(1-10)|foo|BAR> + +In this example, the user may enter any one of: \* an integer between 1 +and 10 \* "foo" \* anything at all + +If the user enters "command f", then: + +:: + + argv[1]->type == WORD_TKN + argv[1]->arg == "f" + argv[1]->text == "foo" + +Range tokens have some special treatment; a token with ->type == +RANGE\_TKN will have the ->min and ->max fields set to the bounding +values of the range. + +Permutations +------------ + +Finally, it is sometimes useful to check all the possible combinations +of input that would match an arbitrary definition string. There is a +tool in tools/ called 'permutations' that reads CLI definition strings +on stdin and prints out all matching input permutations. It also dumps a +text representation of the graph, which is more useful for debugging +than anything else. It looks like this: + +:: + + $ ./permutations "show [ip] bgp [ WORD]" + + show ip bgp view WORD + show ip bgp vrf WORD + show ip bgp + show bgp view WORD + show bgp vrf WORD + show bgp + +This functionality is also built into VTY/VTYSH; the 'list permutations' +command will list all possible matching input permutations in the +current CLI node. diff --git a/doc/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 diff --git a/doc/developer/dev-modules.rst b/doc/developer/dev-modules.rst new file mode 100644 index 0000000000..5cf1939ff3 --- /dev/null +++ b/doc/developer/dev-modules.rst @@ -0,0 +1,125 @@ +Module and Hook support (developer docs) +======================================== + +What it does +------------ + +It uses ``dlopen()`` to load DSOs at startup. + +Limitations +----------- + +- can't load, unload, or reload during runtime. This just needs some + work and can probably be done in the future. +- doesn't fix any of the "things need to be changed in the code in the + library" issues. Most prominently, you can't add a CLI node because + CLI nodes are listed in the library... +- if your module crashes, the daemon crashes. Should be obvious. +- **does not provide a stable API or ABI**. Your module must match a + version of FRR and you may have to update it frequently to match + changes. +- **does not create a license boundary**. Your module will need to link + libzebra and include header files from the daemons, meaning it will + be GPL-encumbered. + +Installation +------------ + +Look for ``moduledir`` in ``configure.ac``, default is normally +``/usr/lib64/frr/modules`` but depends on ``--libdir`` / ``--prefix``. + +The daemon's name is prepended when looking for a module, e.g. "snmp" +tries to find "zebra\_snmp" first when used in zebra. This is just to +make it nicer for the user, with the snmp module having the same name +everywhere. + +Modules can be packaged separately from FRR. The SNMP and FPM modules +are good candidates for this because they have dependencies (net-snmp / +protobuf) that are not FRR dependencies. However, any distro packages +should have an "exact-match" dependency onto the FRR package. Using a +module from a different FRR version will probably blow up nicely. + +For snapcraft (and during development), modules can be loaded with full +path (e.g. -M ``$SNAP/lib/frr/modules/zebra_snmp.so``). Note that +libtool puts output files in the .libs directory, so during development +you have to use ``./zebra -M .libs/zebra_snmp.so``. + +Creating a module +----------------- + +... best to look at the existing SNMP or FPM modules. + +Basic boilerplate: + +:: + + #include "hook.h" + #include "module.h" + + static int + module_init (void) + { + hook_register(frr_late_init, module_late_init); + return 0; + } + + FRR_MODULE_SETUP( + .name = "my module", + .version = "0.0", + .description = "my module", + .init = module_init, + ) + +The ``frr_late_init`` hook will be called after the daemon has finished +its other startup and is about to enter the main event loop; this is the +best place for most initialisation. + +Compiler & Linker magic +----------------------- + +There's a ``THIS_MODULE`` (like in the Linux kernel), which uses +``visibility`` attributes to restrict it to the current module. If you +get a linker error with ``_frrmod_this_module``, there is some linker +SNAFU. This shouldn't be possible, though one way to get it would be to +not include libzebra (which provides a fallback definition for the +symbol). + +libzebra and the daemons each have their own ``THIS_MODULE``, as do all +loadable modules. In any other libraries (e.g. ``libfrrsnmp``), +``THIS_MODULE`` will use the definition in libzebra; same applies if the +main executable doesn't use ``FRR_DAEMON_INFO`` (e.g. all testcases). + +The deciding factor here is "what dynamic linker unit are you using the +symbol from." If you're in a library function and want to know who +called you, you can't use ``THIS_MODULE`` (because that'll just tell you +you're in the library). Put a macro around your function that adds +``THIS_MODULE`` in the *caller's code calling your function*. + +The idea is to use this in the future for module unloading. Hooks +already remember which module they were installed by, as groundwork for +a function that removes all of a module's installed hooks. + +There's also the ``frr_module`` symbol in modules, pretty much a +standard entry point for loadable modules. + +Hooks +----- + +Hooks are just points in the code where you can register your callback +to be called. The parameter list is specific to the hook point. Since +there is no stable API, the hook code has some extra type safety checks +making sure you get a compiler warning when the hook parameter list +doesn't match your callback. Don't ignore these warnings. + +Relation to MTYPE macros +------------------------ + +The MTYPE macros, while primarily designed to decouple MTYPEs from the +library and beautify the code, also work very nicely with loadable +modules -- both constructors and destructors are executed when +loading/unloading modules. + +This means there is absolutely no change required to MTYPEs, you can +just use them in a module and they will even clean up themselves when we +implement module unloading and an unload happens. In fact, it's +impossible to create a bug where unloading fails to de-register a MTYPE. diff --git a/doc/developer/git_branches.svg b/doc/developer/git_branches.svg new file mode 100644 index 0000000000..0c2c96e39e --- /dev/null +++ b/doc/developer/git_branches.svg @@ -0,0 +1,720 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + 1.0ReleaseBranch + + + + + + + + + + Master(Stable) + + + + + + + + + 1.1ReleaseBranch + Version 1.0.a1 + Version 1.1.a1 + Version 1.1.a2 + + + + + Version 1.1.b1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Patch Email (Patchwork) + Github Pull Request + Github Pull Request + Patch Email (Patchwork) + Patch Email (Patchwork) + Github Pull Request + Github Pull Request + Github Pull Request + Patch Email (Patchwork) + Github Pull Request + Github Pull Request + Github Pull Request + Github Pull Request + Github Pull Request + Github Pull Request + + + + + + + + + Version 1.0.a2 + Version 1.0.b1 + Version 1.0.0 + Version 1.1.0 + Version 1.1.1 + Version 1.1.2 + + + + + + + + + + + + + + + + + + diff --git a/doc/developer/hooks.rst b/doc/developer/hooks.rst new file mode 100644 index 0000000000..0afa297aa7 --- /dev/null +++ b/doc/developer/hooks.rst @@ -0,0 +1,171 @@ +.. highlight:: c + +Hooks +===== + +Libfrr provides type-safe subscribable hook points where other pieces of +code can add one or more callback functions. "type-safe" in this case +applies to the function pointers used for subscriptions. The +implementations checks (at compile-time) wheter a callback to be added has +the appropriate function signature (parameters) for the hook. + +Example: + +.. code-block:: c + :caption: mydaemon.h + + #include "hook.h" + DECLARE_HOOK(some_update_event, (struct eventinfo *info), (info)) + +.. code-block:: c + :caption: mydaemon.c + + #include "mydaemon.h" + DEFINE_HOOK(some_update_event, (struct eventinfo *info), (info)) + ... + hook_call(some_update_event, info); + +.. code-block:: c + :caption: mymodule.c + + #include "mydaemon.h" + static int event_handler(struct eventinfo *info); + ... + hook_register(some_update_event, event_handler); + +Do not use parameter names starting with "hook", these can collide with +names used by the hook code itself. + + +Return values +------------- + +Callbacks to be placed on hooks always return "int" for now; hook_call will +sum up the return values from each called function. (The default is 0 if no +callbacks are registered.) + +There are no pre-defined semantics for the value, in most cases it is +ignored. For success/failure indication, 0 should be success, and +handlers should make sure to only return 0 or 1 (not -1 or other values). + +There is no built-in way to abort executing a chain after a failure of one +of the callbacks. If this is needed, the hook can use an extra +``bool *aborted`` argument. + + +Priorities +---------- + +Hooks support a "priority" value for ordering registered calls +relative to each other. The priority is a signed integer where lower +values are called earlier. There are also "Koohs", which is hooks with +reverse priority ordering (for cleanup/deinit hooks, so you can use the +same priority value). + +Recommended priority value ranges are: + +======================== =================================================== +Range Usage +------------------------ --------------------------------------------------- + -999 ... 0 ... 999 main executable / daemon, or library + +-1999 ... -1000 modules registering calls that should run before + the daemon's bits + +1000 ... 1999 modules' calls that should run after daemon's + (includes default value: 1000) +======================== =================================================== + +Note: the default value is 1000, based on the following 2 expectations: + +- most hook_register() usage will be in loadable modules +- usage of hook_register() in the daemon itself may need relative ordering + to itself, making an explicit value the expected case + +The priority value is passed as extra argument on hook_register_prio() / +hook_register_arg_prio(). Whether a hook runs in reverse is determined +solely by the code defining / calling the hook. (DECLARE_KOOH is actually +the same thing as DECLARE_HOOK, it's just there to make it obvious.) + + +Definition +---------- + +.. c:macro:: DECLARE_HOOK(name, arglist, passlist) +.. c:macro:: DECLARE_KOOH(name, arglist, passlist) + + :param name: Name of the hook to be defined + :param arglist: Function definition style parameter list in braces. + :param passlist: List of the same parameters without their types. + + Note: the second and third macro args must be the hook function's + parameter list, with the same names for each parameter. The second + macro arg is with types (used for defining things), the third arg is + just the names (used for passing along parameters). + + This macro must be placed in a header file; this header file must be + included to register a callback on the hook. + + Examples: + + .. code-block:: c + + DECLARE_HOOK(foo, (), ()) + DECLARE_HOOK(bar, (int arg), (arg)) + DECLARE_HOOK(baz, (const void *x, in_addr_t y), (x, y)) + +.. c:macro:: DEFINE_HOOK(name, arglist, passlist) + + Implements an hook. Each ``DECLARE_HOOK`` must have be accompanied by + exactly one ``DEFINE_HOOK``, which needs to be placed in a source file. + **The hook can only be called from this source file.** This is intentional + to avoid overloading and/or misusing hooks for distinct purposes. + + The compiled source file will include a global symbol with the name of the + hook prefixed by `_hook_`. Trying to register a callback for a hook that + doesn't exist will therefore result in a linker error, or a module + load-time error for dynamic modules. + +.. c:macro:: DEFINE_KOOH(name, arglist, passlist) + + Same as ``DEFINE_HOOK``, but the sense of priorities / order of callbacks + is reversed. This should be used for cleanup hooks. + +.. c:function:: int hook_call(name, ...) + + Calls the specified named hook. Parameters to the hook are passed right + after the hook name, e.g.: + + .. code-block:: c + + hook_call(foo); + hook_call(bar, 0); + hook_call(baz, NULL, INADDR_ANY); + + Returns the sum of return values from all callbacks. The ``DEFINE_HOOK`` + statement for the hook must be placed in the file before any ``hook_call`` + use of the hook. + + +Callback registration +--------------------- + +.. c:function:: void hook_register(name, int (*callback)(...)) +.. c:function:: void hook_register_prio(name, int priority, int (*callback)(...)) +.. c:function:: void hook_register_arg(name, int (*callback)(void *arg, ...), void *arg) +.. c:function:: void hook_register_arg_prio(name, int priority, int (*callback)(void *arg, ...), void *arg) + + Register a callback with an hook. If the caller needs to pass an extra + argument to the callback, the _arg variant can be used and the extra + parameter will be passed as first argument to the callback. There is no + typechecking for this argument. + + The priority value is used as described above. The variants without a + priority parameter use 1000 as priority value. + +.. c:function:: void hook_unregister(name, int (*callback)(...)) +.. c:function:: void hook_unregister_arg(name, int (*callback)(void *arg, ...), void *arg) + + Removes a previously registered callback from a hook. Note that there + is no _prio variant of these calls. The priority value is only used during + registration. diff --git a/doc/developer/index.rst b/doc/developer/index.rst new file mode 100644 index 0000000000..6f0dbebdfd --- /dev/null +++ b/doc/developer/index.rst @@ -0,0 +1,10 @@ +Welcome to FRR's documentation! +=============================== + +.. toctree:: + :maxdepth: 2 + + workflow + library + building + diff --git a/doc/developer/ldpd-basic-test-setup.md b/doc/developer/ldpd-basic-test-setup.md new file mode 100644 index 0000000000..b25a2b6d4b --- /dev/null +++ b/doc/developer/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 +``` diff --git a/doc/developer/library.rst b/doc/developer/library.rst new file mode 100644 index 0000000000..a8837b1253 --- /dev/null +++ b/doc/developer/library.rst @@ -0,0 +1,12 @@ +libfrr library facilities +========================= + +.. toctree:: + :maxdepth: 2 + + memtypes + hooks + cli + dev-modules + + diff --git a/doc/developer/memtypes.rst b/doc/developer/memtypes.rst new file mode 100644 index 0000000000..62d211e864 --- /dev/null +++ b/doc/developer/memtypes.rst @@ -0,0 +1,117 @@ +.. highlight:: c + +Memtypes +======== + +FRR includes wrappers arround ``malloc()`` and ``free()`` that count the number +of objects currently allocated, for each of a defined ``MTYPE``. + +To this extent, there are `memory groups` and `memory types`. Each memory +type must belong to a memory group, this is used just to provide some basic +structure. + +Example: + +.. code-block:: c + :caption: mydaemon.h + + DECLARE_MGROUP(MYDAEMON) + DECLARE_MTYPE(MYNEIGHBOR) + +.. code-block:: c + :caption: mydaemon.c + + DEFINE_MGROUP( MYDAEMON, "My daemon's memory") + DEFINE_MTYPE( MYDAEMON, MYNEIGHBOR, "Neighbor entry") + DEFINE_MTYPE_STATIC(MYDAEMON, MYNEIGHBORNAME, "Neighbor name") + + struct neigh *neighbor_new(const char *name) + { + struct neigh *n = XMALLOC(MYNEIGHBOR, sizeof(*n)); + n->name = XSTRDUP(MYNEIGHBORNAME, name); + return n; + } + + void neighbor_free(struct neigh *n) + { + XFREE(MYNEIGHBORNAME, n->name); + XFREE(MYNEIGHBOR, n); + } + + +Definition +---------- + +.. c:macro:: DECLARE_MGROUP(name) + + This macro forward-declares a memory group and should be placed in a + ``.h`` file. It expands to an ``extern struct memgroup`` statement. + +.. c:macro:: DEFINE_MGROUP(mname, description) + + Defines/implements a memory group. Must be placed into exactly one ``.c`` + file (multiple inclusion will result in a link-time symbol conflict). + + Contains additional logic (constructor and destructor) to register the + memory group in a global list. + +.. c:macro:: DECLARE_MTYPE(name) + + Forward-declares a memory type and makes ``MTYPE_name`` available for use. + Note that the ``MTYPE_`` prefix must not be included in the name, it is + automatically prefixed. + + ``MTYPE_name`` is created as a `static const` symbol, i.e. a compile-time + constant. It refers to an ``extern struct memtype _mt_name``, where `name` + is replaced with the actual name. + +.. c:macro:: DEFINE_MTYPE(group, name, description) + + Define/implement a memory type, must be placed into exactly one ``.c`` + file (multiple inclusion will result in a link-time symbol conflict). + + Like ``DEFINE_MGROUP``, this contains actual code to register the MTYPE + under its group. + +.. c:macro:: DEFINE_MTYPE_STATIC(group, name, description) + + Same as ``DEFINE_MTYPE``, but the ``DEFINE_MTYPE_STATIC`` variant places + the C ``static`` keyword on the definition, restricting the MTYPE's + availability to the current source file. This should be appropriate in + >80% of cases. + + .. todo:: + + Daemons currently have ``daemon_memory.[ch]`` files listing all of + their MTYPEs. This is not how it should be, most of these types + should be moved into the appropriate files where they are used. + Only a few MTYPEs should remain non-static after that. + + +Usage +----- + +.. c:function:: void *XMALLOC(struct memtype *mtype, size_t size) + +.. c:function:: void *XCALLOC(struct memtype *mtype, size_t size) + +.. c:function:: void *XSTRDUP(struct memtype *mtype, size_t size) + + Allocation wrappers for malloc/calloc/realloc/strdup, taking an extra + mtype parameter. + +.. c:function:: void *XREALLOC(struct memtype *mtype, void *ptr, size_t size) + + Wrapper around realloc() with MTYPE tracking. Note that ``ptr`` may + be NULL, in which case the function does the same as XMALLOC (regardless + of whether the system realloc() supports this.) + +.. c:function:: void XFREE(struct memtype *mtype, void *ptr) + + Wrapper around free(), again taking an extra mtype parameter. This is + actually a macro, with the following additional properties: + + - the macro contains ``ptr = NULL`` + - if ptr is NULL, no operation is performed (as is guaranteed by system + implementations.) Do not surround XFREE with ``if (ptr != NULL)`` + checks. diff --git a/doc/developer/next-hop-tracking.txt b/doc/developer/next-hop-tracking.txt new file mode 100644 index 0000000000..12ed63947b --- /dev/null +++ b/doc/developer/next-hop-tracking.txt @@ -0,0 +1,326 @@ +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 new file mode 100644 index 0000000000..38cf0b878d --- /dev/null +++ b/doc/developer/workflow.rst @@ -0,0 +1,544 @@ +Developing for FRRouting +======================== + +General note on this document +----------------------------- + +This document is "descriptive/post-factual" in that it documents +pratices that are in use; it is not "definitive/pre-factual" in +prescribing practices. + +This means that when a procedure changes, it is agreed upon, then put +into practice, and then documented here. If this document doesn't match +reality, it's the document that needs to be updated, not reality. + +Git Structure +------------- + +The master Git for FRRouting resides on Github at +`https://github.com/frrouting/frr `__ + +.. figure:: git_branches.svg + :alt: git branches continually merging to the left from 3 lanes; + float-right + + git branches continually merging to the left from 3 lanes; + float-right + +There is one main branch for development and a release branch for each +major release. + +New contributions are done against the head of the master branch. The CI +systems will pick up the Github Pull Requests or the new patch from +Patchwork, run some basic build and functional tests. + +For each major release (1.0, 1.1 etc) a new release branch is created +based on the master. + +There was an attempt to use a "develop" branch automatically maintained +by the CI system. This is not currently in active use, though the system +is operational. If the "develop" branch is in active use and this +paragraph is still here, this document obviously wasn't updated. + +Programming language, Tools and Libraries +----------------------------------------- + +The core of FRRouting is written in C (gcc or clang supported) and makes +use of GNU compiler extensions. A few non-essential scripts are +implemented in Perl and Python. FRRouting requires the following tools +to build distribution packages: automake, autoconf, texinfo, libtool and +gawk and various libraries (i.e. libpam and libjson-c). + +If your contribution requires a new library or other tool, then please +highlight this in your description of the change. Also make sure it’s +supported by all FRRouting platform OSes or provide a way to build +without the library (potentially without the new feature) on the other +platforms. + +Documentation should be written in Tex (.texi) or Markdown (.md) format +with a preference for Markdown. + +Mailing lists +------------- + +Italicized lists are private. + ++----------------------------------+--------------------------------+ +| Topic | List | ++==================================+================================+ +| Development | dev@lists.frrouting.org | ++----------------------------------+--------------------------------+ +| Users & Operators | frog@lists.frrouting.org | ++----------------------------------+--------------------------------+ +| Announcements | announce@lists.frrouting.org | ++----------------------------------+--------------------------------+ +| *Security* | security@lists.frrouting.org | ++----------------------------------+--------------------------------+ +| *Technical Steering Committee* | tsc@lists.frrouting.org | ++----------------------------------+--------------------------------+ + +Changelog +~~~~~~~~~ + +The changelog will be the base for the release notes. A changelog entry +for your changes is usually not required and will be added based on your +commit messages by the maintainers. However, you are free to include an +update to the changelog with some better description. The changelog will +be the base for the release notes. + +Submitting Patches and Enhancements +----------------------------------- + +Pre-submission Checklist +~~~~~~~~~~~~~~~~~~~~~~~~ + +- Format code (see `Developer's Guidelines <#developers-guidelines>`__) +- Verify and acknowledge license (see `License for + contributions <#license-for-contributions>`__) +- Ensure you have properly signed off (see `Signing + Off <#signing-off>`__) +- Test building with various configurations: + + - ``buildtest.sh`` + +- Verify building source distribution: + + - ``make dist`` (and try rebuilding from the resulting tar file) + +- Run unit tests: + + - ``make test`` + +- Document Regression Runs and plans for continued maintenance of the + feature + +License for contributions +~~~~~~~~~~~~~~~~~~~~~~~~~ + +FRRouting is under a “GPLv2 or later” license. Any code submitted must +be released under the same license (preferred) or any license which +allows redistribution under this GPLv2 license (eg MIT License). + +Signing Off +~~~~~~~~~~~ + +Code submitted to FRRouting must be signed off. We have the same +requirements for using the signed-off-by process as the Linux kernel. In +short, you must include a signed-off-by tag in every patch. + +``Signed-off-by:`` this is a developer's certification that he or she +has the right to submit the patch for inclusion into the project. It is +an agreement to the Developer's Certificate of Origin (below). Code +without a proper signoff can not and will not be merged. + +If you are unfamiliar with this process, you should read the `official +policy at +kernel.org `__ +and you might find this article about `participating in the Linux +community on the Linux Foundation +website `__ +to be a helpful resource. + +In short, when you sign off on a commit, you assert your agreement to +all of the following: + + Developer's Certificate of Origin 1.1 + + By making a contribution to this project, I certify that: + + (a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + + (b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part by + me, under the same open source license (unless I am permitted to + submit under a different license), as indicated in the file; or + + (c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified it. + + (d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. + +What do I submit my changes against? +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +We've documented where we would like to have the different fixes applied +at +https://github.com/FRRouting/frr/wiki/Where-Do-I-create-a-Pull-Request-against%3F +If you are unsure where your submission goes, look at that document or +ask a project maintainer. + +Github pull requests +~~~~~~~~~~~~~~~~~~~~ + +The preferred method of submitting changes is a Github pull request. +Code submitted by pull request will be automatically tested by one or +more CI systems. Once the automated tests succeed, other developers will +review your code for quality and correctness. After any concerns are +resolved, your code will be merged into the branch it was submitted +against. + +Patch submission via mailing list +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +As an alternative submission method, a patch can be mailed to the +development mailing list. Patches received on the mailing list will be +picked up by Patchwork and tested against the latest development branch. + +The recommended way to send the patch (or series of NN patches) to the +list is by using ``git send-email`` as follows (assuming they are the N +most recent commit(s) in your git history: + +:: + + git send-email -NN --annotate --to=dev@lists.frrouting.org + +If your commits do not already contain a ``Signed-off-by`` line, then +use the following command to add it (after making sure you agree to the +Developer Certificate of Origin as outlined above): + +:: + + git send-email -NN --annotate --signoff --to=dev@lists.frrouting.org + +Submitting multi-commit patches as a Github pull request is **strongly +encouraged** and increases the probability of your patch getting +reviewed and merged in a timely manner. + +After submitting your changes +----------------------------- + +- Watch for Continuous Integration (CI) Test results + + - You should automatically receive an email with the test results + within less than 2 hrs of the submission. If you don’t get the + email, then check status on the github pull request (if submitted + by pull request) or on Patchwork at + https://patchwork.frrouting.org (if submitted as patch to mailing + list). + - Please notify the development mailing list if you think something + doesn’t work. + +- If the tests failed: + + - In general, expect the community to ignore the submission until + the tests pass. + - It is up to you to fix and resubmit. + + - This includes fixing existing unit (“make test”) tests if your + changes broke or changed them. + - It also includes fixing distribution packages for the failing + platforms (ie if new libraries are required). + - Feel free to ask for help on the development list. + + - Go back to the submission process and repeat until the tests pass. + +- If the tests pass: + + - Wait for reviewers. Someone will review your code or be assigned + to review your code. + - Respond to any comments or concerns the reviewer has. + - After all comments and concerns are addressed, expect your patch + to be merged. + +- Watch out for questions on the mailing list. At this time there will + be a manual code review and further (longer) tests by various + community members. +- Your submission is done once it is merged to the master branch. + +Developer's Guidelines +---------------------- + +Commit messages +~~~~~~~~~~~~~~~ + +Commit messages should be formatted in the same way as Linux kernel +commit messages. The format is roughly + +:: + + dir: short summary + + extended summary + +``dir`` should be the top level source directory under which the change +was made. For example, a change in bgpd/rfapi would be formatted as: + +``bgpd: short summary`` + +The first line should be no longer than 50 characters. Subsequent lines +should be wrapped to 72 characters. + +Source file header +~~~~~~~~~~~~~~~~~~ + +New files need to have a Copyright header (see `License for +contributions <#license-for-contributions>`__ above) added to the file. +Preferred form of the header is as follows: + +:: + + /* + * Title/Function of file + * Copyright (C) YEAR Author’s Name + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + + #include + +Adding copyright claims to existing files +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When adding copyright claims for modifications to an existing file, +please preface the claim with "Portions: " on a line before it and +indent the "Copyright ..." string. If such a case already exists, add +your indented claim immediately after. E.g.: + +:: + + Portions: + Copyright (C) 2010 Entity A .... + Copyright (C) 2016 Your name [optional brief change description] + +Code formatting +~~~~~~~~~~~~~~~ + +FRR uses Linux kernel style except where noted below. Code which does +not comply with these style guidelines will not be accepted. + +To assist with compliance, in the project root there is a .clang-format +configuration file which can be used with the ``clang-format`` tool from +the LLVM project. In the ``tools/`` directory there is a Python script +named ``indent.py`` that wraps clang-format and handles some edge cases +specific to FRR. If you are submitting a new file, it is recommended to +run that script over the new file after ensuring that the latest stable +release of ``clang-format`` is in your PATH. + +**Whitespace changes in untouched parts of the code are not acceptable +in patches that change actual code.** To change/fix formatting issues, +please create a separate patch that only does formatting changes and +nothing else. + +Style documentation +^^^^^^^^^^^^^^^^^^^ + +Kernel and BSD styles are documented externally: + +- https://www.kernel.org/doc/html/latest/process/coding-style.html +- http://man.openbsd.org/style + +For GNU coding style, use ``indent`` with the following invocation: + +:: + + indent -nut -nfc1 file_for_submission.c + +Exceptions +^^^^^^^^^^ + +FRR project code comes from a variety of sources, so there are some +stylistic exceptions in place. They are organized here by branch. + +**For ``master``:** + +BSD coding style applies to: + +- ``ldpd/`` + +``babeld`` uses, approximately, the following style: + +- K&R style braces +- Indents are 4 spaces +- Function return types are on their own line + +**For ``stable/3.0`` and ``stable/2.0``:** + +GNU coding style apply to the following parts: + +- ``lib/`` +- ``zebra/`` +- ``bgpd/`` +- ``ospfd/`` +- ``ospf6d/`` +- ``isisd/`` +- ``ripd/`` +- ``ripngd/`` +- ``vtysh/`` + +BSD coding style applies to: + +- ``ldpd/`` + +Documentation +~~~~~~~~~~~~~ + +FRRouting is a large and complex software project developed by many +different people over a long period of time. Without adequate +documentation, it can be exceedingly difficult to understand code +segments, APIs and other interfaces. In the interest of keeping the +project healthy and maintainable, you should make every effort to +document your code so that other people can understand what it does +without needing to closely read the code itself. + +Some specific guidelines that contributors should follow are: + +- Functions exposed in header files should have descriptive comments + above their signatures in the header file. At a minimum, a function + comment should contain information about the return value, + parameters, and a general summary of the function's purpose. + Documentation on parameter values can be omitted if it is (very) + obvious what they are used for. + +Function comments must follow the style for multiline comments laid out +in the kernel style guide. + +Example: + +:: + + /* + * Determines whether or not a string is cool. + * + * @param text - the string to check for coolness + * @param is_clccfc - whether capslock is cruise control for cool + * @return 7 if the text is cool, 0 otherwise + */ + int check_coolness(const char *text, bool is_clccfc); + +The Javadoc-style annotations are not required, but you should still +strive to make it equally clear what parameters and return values are +used for. + +- Static functions should have descriptive comments in the same form as + above if what they do is not immediately obvious. Use good + engineering judgement when deciding whether a comment is necessary. + If you are unsure, document your code. + +- Global variables, static or not, should have a comment describing + their use. + +- **For new code in ``lib/``, these guidelines are hard requirements.** + +If you are contributing code that adds significant user-visible +functionality or introduces a new API, please document it in ``doc/``. +Markdown and LaTeX are acceptable formats, although Markdown is +currently preferred for new documentation. This may change in the near +future. + +Finally, if you come across some code that is undocumented and feel like +going above and beyond, document it! We absolutely appreciate and accept +patches that document previously undocumented code. + +Compile-time conditional code +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Many users access FRR via binary packages from 3rd party sources; +compile-time code puts inclusion/exclusion in the hands of the package +maintainer. Please think very carefully before making code conditional +at compile time, as it increases regression testing, maintenance +burdens, and user confusion. In particular, please avoid gratuitous +``--enable-…`` switches to the configure script - in general, code +should be of high quality and in working condition, or it shouldn’t be +in FRR at all. + +When code must be compile-time conditional, try have the compiler make +it conditional rather than the C pre-processor so that it will still be +checked by the compiler, even if disabled. For example, + +:: + + if (SOME_SYMBOL) + frobnicate(); + +is preferred to + +:: + + #ifdef SOME_SYMBOL + frobnicate (); + #endif /* SOME_SYMBOL */ + +Note that the former approach requires ensuring that ``SOME_SYMBOL`` +will be defined (watch your ``AC_DEFINE``\ s). + +Debug-guards in code +~~~~~~~~~~~~~~~~~~~~ + +Debugging statements are an important methodology to allow developers to +fix issues found in the code after it has been released. The caveat here +is that the developer must remember that people will be using the code +at scale and in ways that can be unexpected for the original +implementor. As such debugs **MUST** be guarded in such a way that they +can be turned off. FRR has the ability to turn on/off debugs from the +CLI and it is expected that the developer will use this convention to +allow control of their debugs. + +CLI changes +~~~~~~~~~~~ + +CLI's are a complicated ugly beast. Additions or changes to the CLI +should use a DEFUN to encapsulate one setting as much as is possible. +Additionally as new DEFUN's are added to the system, documentation +should be provided for the new commands. + +Backwards Compatibility +~~~~~~~~~~~~~~~~~~~~~~~ + +As a general principle, changes to CLI and code in the lib/ directory +should be made in a backwards compatible fashion. This means that +changes that are purely stylistic in nature should be avoided, e.g., +renaming an existing macro or library function name without any +functional change. When adding new parameters to common functions, it is +also good to consider if this too should be done in a backward +compatible fashion, e.g., by preserving the old form in addition to +adding the new form. + +This is not to say that minor or even major functional changes to CLI +and common code should be avoided, but rather that the benefit gained +from a change should be weighed against the added cost/complexity to +existing code. Also, that when making such changes, it is good to +preserve compatibility when possible to do so without introducing +maintenance overhead/cost. It is also important to keep in mind, +existing code includes code that may reside in private repositories (and +is yet to be submitted) or code that has yet to be migrated from Quagga +to FRR. + +That said, compatibility measures can (and should) be removed when +either: + +- they become a significant burden, e.g. when data structures change + and the compatibility measure would need a complex adaptation layer + or becomes flat-out impossible +- some measure of time (dependent on the specific case) has passed, so + that the compatibility grace period is considered expired. + +In all cases, compatibility pieces should be marked with +compiler/preprocessor annotations to print warnings at compile time, +pointing to the appropriate update path. A ``-Werror`` build should fail +if compatibility bits are used. + +Miscellaneous +~~~~~~~~~~~~~ + +When in doubt, follow the guidelines in the Linux kernel style guide, or +ask on the development mailing list / public Slack instance. diff --git a/doc/ldpd-basic-test-setup.md b/doc/ldpd-basic-test-setup.md deleted file mode 100644 index b25a2b6d4b..0000000000 --- a/doc/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/next-hop-tracking.txt b/doc/next-hop-tracking.txt deleted file mode 100644 index 12ed63947b..0000000000 --- a/doc/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