summaryrefslogtreecommitdiffstats
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/developer/building-frr-for-omnios.rst2
-rw-r--r--doc/developer/building-libyang.rst2
-rw-r--r--doc/developer/topotests-jsontopo.rst475
-rw-r--r--doc/developer/topotests.rst2
-rw-r--r--doc/user/installation.rst16
5 files changed, 478 insertions, 19 deletions
diff --git a/doc/developer/building-frr-for-omnios.rst b/doc/developer/building-frr-for-omnios.rst
index ffc7a078e..3a69279b0 100644
--- a/doc/developer/building-frr-for-omnios.rst
+++ b/doc/developer/building-frr-for-omnios.rst
@@ -60,7 +60,7 @@ Add pytest:
::
- pip install pytest
+ pip install "pytest<5"
Install Sphinx:::
diff --git a/doc/developer/building-libyang.rst b/doc/developer/building-libyang.rst
index ed3e02990..f50b8cf72 100644
--- a/doc/developer/building-libyang.rst
+++ b/doc/developer/building-libyang.rst
@@ -10,7 +10,7 @@ The FRR project builds binary ``libyang`` packages, which we offer for download
.. warning::
- ``libyang`` version 0.16.74 or newer is required to build FRR.
+ ``libyang`` version 0.16.105 or newer is required to build FRR.
.. note::
diff --git a/doc/developer/topotests-jsontopo.rst b/doc/developer/topotests-jsontopo.rst
new file mode 100644
index 000000000..65bdcbe9c
--- /dev/null
+++ b/doc/developer/topotests-jsontopo.rst
@@ -0,0 +1,475 @@
+.. role:: raw-html-m2r(raw)
+ :format: html
+
+*************************************
+FRRouting Topology Tests with Mininet
+*************************************
+
+Overview
+########
+
+On top of current topotests framework following enhancements are done:
+
+
+#.
+ Creating the topology and assigning IPs to router' interfaces dynamically.\ :raw-html-m2r:`<br>`
+ It is achieved by using json file, in which user specify the number of routers,
+ links to each router, interfaces for the routers and protocol configurations for
+ all routers.
+
+#.
+ Creating the configurations dynamically. It is achieved by using
+ /usr/lib/frr/frr-reload.py utility, which takes running configuration and the
+ newly created configuration for any particular router and creates a delta
+ file(diff file) and loads it to router.
+
+
+Logging of test case executions
+###############################
+
+
+#. User can enable logging of testcases execution messages into log file by
+ adding "frrtest_log_dir = /tmp/topotests/" in pytest.ini file
+#. Router's current configuration can be displyed on console or sent to logs by
+ adding "show_router_config = True" in pytest.ini file
+
+Log file name will be displayed when we start execution:
+root@test:~/topotests/example-topojson-test/test_topo_json_single_link# python
+test_topo_json_single_link.py Logs will be sent to logfile:
+/tmp/topotests/test_topo_json_single_link_11:57:01.353797
+
+Note: directory "/tmp/topotests/" is created by topotests by default, making
+use of same directory to save execution logs.
+
+
+Guidelines
+##########
+
+Writing New Tests
+=================
+
+
+This section will guide you in all recommended steps to produce a standard topology test.
+
+This is the recommended test writing routine:
+
+
+* Create a json file , which will have routers and protocol configurations
+* Create topology from json
+* Create configuration from json
+* Write the tests
+* Create a Pull Request
+
+File Hierarchy
+==============
+
+Before starting to write any tests one must know the file hierarchy. The
+repository hierarchy looks like this:
+
+.. code-block::
+
+ $ cd path/to/topotests
+ $ find ./*
+ ...
+ ./example-topojson-test # the basic example test topology-1
+ ./example-topojson-test/test_example_topojson.json # input json file, having
+ topology, interfaces, bgp and other configuration
+ ./example-topojson-test/test_example_topojson.py # test script to write and
+ execute testcases
+ ...
+ ./lib # shared test/topology functions
+ ./lib/topojson.py # library to create topology and configurations dynamically
+ from json file
+ ./lib/common_config.py # library to create protocol's common configurations ex-
+ static_routes, prefix_lists, route_maps etc.
+ ./lib/bgp.py # library to create only bgp configurations
+
+Defining the Topology and initial configuration in JSON file
+""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
+
+The first step to write a new test is to define the topology and initial
+configuration. User has to define topology and initial configuration in JSON
+file. Here is an example of JSON file.
+
+.. code-block::
+
+ BGP neihghborship with single phy-link, sample JSON file:
+ {
+ "ipv4base": "192.168.0.0",
+ "ipv4mask": 30,
+ "ipv6base": "fd00::",
+ "ipv6mask": 64,
+ "link_ip_start": {"ipv4": "192.168.0.0", "v4mask": 30, "ipv6": "fd00::", "v6mask": 64},
+ "lo_prefix": {"ipv4": "1.0.", "v4mask": 32, "ipv6": "2001:DB8:F::", "v6mask": 128},
+ "routers": {
+ "r1": {
+ "links": {
+ "lo": {"ipv4": "auto", "ipv6": "auto", "type": "loopback"},
+ "r2": {"ipv4": "auto", "ipv6": "auto"},
+ "r3": {"ipv4": "auto", "ipv6": "auto"}
+ },
+ "bgp": {
+ "local_as": "64512",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1": {}
+ }
+ },
+ "r3": {
+ "dest_link": {
+ "r1": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "r2": {
+ "links": {
+ "lo": {"ipv4": "auto", "ipv6": "auto", "type": "loopback"},
+ "r1": {"ipv4": "auto", "ipv6": "auto"},
+ "r3": {"ipv4": "auto", "ipv6": "auto"}
+ },
+ "bgp": {
+ "local_as": "64512",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "redistribute": [
+ {
+ "redist_type": "static"
+ }
+ ],
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r2": {}
+ }
+ },
+ "r3": {
+ "dest_link": {
+ "r2": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ...
+
+
+ BGP neighboship with loopback interface, sample JSON file:
+ {
+ "ipv4base": "192.168.0.0",
+ "ipv4mask": 30,
+ "ipv6base": "fd00::",
+ "ipv6mask": 64,
+ "link_ip_start": {"ipv4": "192.168.0.0", "v4mask": 30, "ipv6": "fd00::", "v6mask": 64},
+ "lo_prefix": {"ipv4": "1.0.", "v4mask": 32, "ipv6": "2001:DB8:F::", "v6mask": 128},
+ "routers": {
+ "r1": {
+ "links": {
+ "lo": {"ipv4": "auto", "ipv6": "auto", "type": "loopback",
+ "add_static_route":"yes"},
+ "r2": {"ipv4": "auto", "ipv6": "auto"}
+ },
+ "bgp": {
+ "local_as": "64512",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "lo": {
+ "source_link": "lo"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "static_routes": [
+ {
+ "network": "1.0.2.17/32",
+ "next_hop": "192.168.0.1
+ }
+ ]
+ },
+ "r2": {
+ "links": {
+ "lo": {"ipv4": "auto", "ipv6": "auto", "type": "loopback",
+ "add_static_route":"yes"},
+ "r1": {"ipv4": "auto", "ipv6": "auto"},
+ "r3": {"ipv4": "auto", "ipv6": "auto"}
+ },
+ "bgp": {
+ "local_as": "64512",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "redistribute": [
+ {
+ "redist_type": "static"
+ }
+ ],
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "lo": {
+ "source_link": "lo"
+ }
+ }
+ },
+ "r3": {
+ "dest_link": {
+ "lo": {
+ "source_link": "lo"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "static_routes": [
+ {
+ "network": "192.0.20.1/32",
+ "no_of_ip": 9,
+ "admin_distance": 100,
+ "next_hop": "192.168.0.1",
+ "tag": 4001
+ }
+ ],
+ }
+ ...
+
+ BGP neighborship with Multiple phy-links, sample JSON file:
+ {
+ "ipv4base": "192.168.0.0",
+ "ipv4mask": 30,
+ "ipv6base": "fd00::",
+ "ipv6mask": 64,
+ "link_ip_start": {"ipv4": "192.168.0.0", "v4mask": 30, "ipv6": "fd00::", "v6mask": 64},
+ "lo_prefix": {"ipv4": "1.0.", "v4mask": 32, "ipv6": "2001:DB8:F::", "v6mask": 128},
+ "routers": {
+ "r1": {
+ "links": {
+ "lo": {"ipv4": "auto", "ipv6": "auto", "type": "loopback"},
+ "r2-link1": {"ipv4": "auto", "ipv6": "auto"},
+ "r2-link2": {"ipv4": "auto", "ipv6": "auto"}
+ },
+ "bgp": {
+ "local_as": "64512",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "neighbor": {
+ "r2": {
+ "dest_link": {
+ "r1-link1": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "r2": {
+ "links": {
+ "lo": {"ipv4": "auto", "ipv6": "auto", "type": "loopback"},
+ "r1-link1": {"ipv4": "auto", "ipv6": "auto"},
+ "r1-link2": {"ipv4": "auto", "ipv6": "auto"},
+ "r3-link1": {"ipv4": "auto", "ipv6": "auto"},
+ "r3-link2": {"ipv4": "auto", "ipv6": "auto"}
+ },
+ "bgp": {
+ "local_as": "64512",
+ "address_family": {
+ "ipv4": {
+ "unicast": {
+ "redistribute": [
+ {
+ "redist_type": "static"
+ }
+ ],
+ "neighbor": {
+ "r1": {
+ "dest_link": {
+ "r2-link1": {}
+ }
+ },
+ "r3": {
+ "dest_link": {
+ "r2-link1": {}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ...
+
+
+JSON file explained
+"""""""""""""""""""
+
+Mandatory keywords/options in JSON:
+
+
+* "ipv4base" : base ipv4 address to generate ips, ex - 192.168.0.0
+* "ipv4mask" : mask for ipv4 address, ex - 30
+* "ipv6base" : base ipv6 address to generate ips, ex - fd00:
+* "ipv6mask" : mask for ipv6 address, ex - 64
+* "link_ip_start" : physical interface base ipv4 and ipv6 address
+* "lo_prefix" : loopback interface base ipv4 and ipv6 address
+* "routers" : user can add number of routers as per topology, router's name
+ can be any logical name, ex- r1 or a0.
+* "r1" : name of the router
+* "lo" : loopback interface dict, ipv4 and/or ipv6 addresses generated automatically
+* "type" : type of interface, to identify loopback interface
+* "links" : physical interfaces dict, ipv4 and/or ipv6 addresses generated
+ automatically
+* "r2-link1" : it will be used when routers have multiple links. 'r2' is router
+ name, 'link' is any logical name, '1' is to identify link number,
+ router name and link must be seperated by hyphen ("-"), ex- a0-peer1
+
+Optional keywords/options in JSON:
+
+* "bgp" : bgp configuration
+* "local_as" : Local AS number
+* "unicast" : All SAFI configuration
+* "neighbor": All neighbor details
+* "dest_link" : Destination link to which router will connect
+* "router_id" : bgp router-id
+* "source_link" : if user wants to establish bgp neighborship with loopback
+ interface, add "source_link": "lo"
+* "keepalivetimer" : Keep alive timer for BGP neighbor
+* "holddowntimer" : Hold down timer for BGP neighbor
+* "static_routes" : create static routes for routers
+* "redistribute" : redistribute static and/or connected routes
+* "prefix_lists" : create Prefix-lists for routers
+
+Building topology and configurations
+""""""""""""""""""""""""""""""""""""
+
+Topology and initial configuration will be created in setup_module(). Following
+is the sample code:
+
+.. code-block::
+
+ class TemplateTopo(Topo):
+ def build(self, *_args, **_opts):
+ "Build function"
+ tgen = get_topogen(self)
+
+ # Building topology from json file
+ build_topo_from_json(tgen, topo)
+
+ def setup_module(mod):
+ tgen = Topogen(TemplateTopo, mod.__name__)
+
+ # Starting topology, create tmp files which are loaded to routers
+ # to start deamons and then start routers
+ start_topology(tgen)
+
+ # Creating configuration from JSON
+ build_config_from_json(tgen, topo)
+
+ def teardown_module(mod):
+ tgen = get_topogen()
+
+ # Stop toplogy and Remove tmp files
+ stop_topology(tgen)
+
+
+* Note: Topology will be created in setup module but routers will not be
+ started until we load zebra.conf and bgpd.conf to routers. For all routers
+ dirs will be created in /tmp/topotests/<test_folder_name>/<router_name>
+ zebra.conf and bgpd.conf empty files will be created and laoded to routers.
+ All folder and files are deleted in teardown module..
+
+Creating configuration files
+""""""""""""""""""""""""""""
+
+Router's configuration would be saved in config file frr_json.conf. Common
+configurations are like, static routes, prefixlists and route maps etc configs,
+these configs can be used by any other protocols as it is.
+BGP config will be specific to BGP protocol testing.
+
+* JSON file is passed to API build_config_from_json(), which looks for
+ configuration tags in JSON file.
+* If tag is found in JSON, configuration is created as per input and written
+ to file frr_json.conf
+* Once JSON parsing is over, frr_json.conf is loaded onto respective router.
+ Config loading is done using 'vtysh -f <file>'. Initial config at this point
+ is also saved frr_json_initial.conf. This file can be used to reset
+ configuration on router, during the course of execution.
+* Reset of configuration is done using frr "reload.py" utility, which
+ calculates the difference between router's running config and user's config
+ and loads delta file to router. API used - reset_config_on_router()
+
+Writing Tests
+"""""""""""""
+
+Test topologies should always be bootstrapped from the
+example-test/test_example.py, because it contains important boilerplate code
+that can't be avoided, like:
+
+imports: os, sys, pytest, topotest/topogen and mininet topology class
+
+The global variable CWD (Current Working directory): which is most likely going
+to be used to reference the routers configuration file location
+
+Example:
+
+
+* The topology class that inherits from Mininet Topo class
+
+.. code-block::
+
+ class TemplateTopo(Topo):
+ def build(self, *_args, **_opts):
+ tgen = get_topogen(self)
+ # topology build code
+
+
+* pytest setup_module() and teardown_module() to start the topology
+
+.. code-block::
+
+ def setup_module(_m):
+ tgen = Topogen(TemplateTopo)
+
+ # Starting topology, create tmp files which are loaded to routers
+ # to start deamons and then start routers
+ start_topology(tgen, CWD)
+
+ def teardown_module(_m):
+ tgen = get_topogen()
+
+ # Stop toplogy and Remove tmp files
+ stop_topology(tgen, CWD)
+
+
+* __main__ initialization code (to support running the script directly)
+
+.. code-block::
+
+ if **name** == '\ **main**\ ':
+ sys.exit(pytest.main(["-s"]))
+
diff --git a/doc/developer/topotests.rst b/doc/developer/topotests.rst
index e12bc3725..a0a574a79 100644
--- a/doc/developer/topotests.rst
+++ b/doc/developer/topotests.rst
@@ -22,7 +22,7 @@ Installing Mininet Infrastructure
apt-get install python-pip
apt-get install iproute
pip install ipaddr
- pip install pytest
+ pip install "pytest<5"
pip install exabgp==3.4.17 (Newer 4.0 version of exabgp is not yet
supported)
useradd -d /var/run/exabgp/ -s /bin/false exabgp
diff --git a/doc/user/installation.rst b/doc/user/installation.rst
index 64949fc8e..b45c83ca1 100644
--- a/doc/user/installation.rst
+++ b/doc/user/installation.rst
@@ -331,22 +331,6 @@ options to the configuration script.
Look for YANG modules in `dir` [`prefix`/share/yang]. Note that the FRR
YANG modules will be installed here.
-.. option:: --with-libyang-pluginsdir <dir>
-
- Look for libyang plugins in `dir` [`prefix`/lib/frr/libyang_plugins].
- Note that the FRR libyang plugins will be installed here.
-
- This option is meaningless with libyang 0.16.74 or newer and will be
- removed once support for older libyang versions is dropped.
-
-When it's desired to run FRR without installing it in the system, it's possible
-to configure it as follows to look for YANG modules and libyang plugins in the
-compile directory:
-.. code-block:: shell
-
- ./configure --with-libyang-pluginsdir="`pwd`/yang/libyang_plugins/.libs" \
- --with-yangmodelsdir="`pwd`/yang"
-
Python dependency, documentation and tests
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^