/Solenoid

App that injects routes directly into Cisco's IOS-XR RIB table.

Primary LanguagePythonOtherNOASSERTION

Solenoid

Route Injection Agent

Author: Lisa Roach & Karthik Kumaravel
Contact: Please use the Issues page to ask questions or open bugs and feature requests.

Description:

The end goal of this Route injector app is to be able to take any given logic and make changes to the prefixes on a RIB table.

The changes to the RIB are accomplished by using gRPC calls to send JSON modeled by YANG. The YANG model currently in use is [Cisco-IOS-XR-ip-static-cfg] (https://github.com/YangModels/yang/blob/master/vendor/cisco/xr/600/Cisco-IOS-XR-ip-static-cfg.yang), see Current Limitations for more information.

[exaBGP] (https://github.com/Exa-Networks/exabgp) is used for reading BGP updates. Exabgp is a tool for monitoring BGP network announcements, withdrawals, etc. and it triggers the gRPC changes based on these updates.

Current Limitations:

As of now, the IOS-XR does not support YANG models that can add true BGP or Application routes to the RIB table. As a workaround, static routes are added instead. Be aware of the limits of static routes before using this application.

RESTconf is not available on public images of the IOS-XR 6.X. If you are interested in testing RESTconf, please reach out to your Cisco account team or contact Lisa Roach directly.

Vagrant:

For an easy Solenoid-in-a-box demonstration, please refer to the vagrant directory. Here you will be able to download a fully functional vagrant environment that has Solenoid up and running already.

Usage:

Step 1: Clone this repo and cd into Solenoid.

Step 2: It is highly recommended you install and use a virtualenv.

pip install virtualenv

virtualenv venv

source venv/bin/activate

Step 3: Install gRPC (if you are using gRPC).

pip install grpcio

Step 4: Install Solenoid.

python setup.py install

Step 5 : Create a solenoid.config file in your top-level solenoid directory and fill in the values in the key:value pair. Please refer to the Config File section of the wiki for more information.

[default]
transport: transport  # Either gRPC or RESTconf
ip: ip_address        # IP address of the destination RIB table (the XR device you intend to control)
port: port number     # Depends on what is configured for your gRPC or RESTconf servers
username: username    # Username for the router
password: password    # Password for the router

Example:

[IOS-XRv]
transport: gRPC
ip: 192.168.1.2
port: 57777
username: vagrant
password: vagrant

Step 6 (optional): Create a filter.txt file to include the ranges of prefixes to be filtered with. This is a whitelist of prefixes, so all of these will be accepted and all others will be dropped. Single prefixes are also acceptable. Example:

1.1.1.0/32-1.1.2.0/32
10.1.1.0/32-10.1.5.0/32
10.1.1.6/32
192.168.1.0/28-192.168.2.0/28

Step 7: Set up [exaBGP] (https://github.com/Exa-Networks/exabgp). Form a neighborship with your BGP network.

Step 8: Change your exaBGP configuration file to run the edit_rib.py script. The important part is the process monitor-neighbors section, the rest is basic exaBGP configuration.

Example:

group test {
        router-id x.x.x.x;

        process monitor-neighbors {
            encoder json;
            receive {
                parsed;
                updates;
                neighbor-changes;
            }
            run /your/python/location /path/to/solenoid/solenoid/edit_rib.py;
        }

        neighbor y.y.y.y {
            local-address x.x.x.x;
            local as ####;
            peer-as ####;
        }

}

If you chose to add a filter file, you must add the path to the file in the run call with the file flag -f (be sure to include the quotes):

run /your/python/location /path/to//solenoid/solenoid/edit_rib.py -f '/path/to/filter/file';

Step 9: Launch your exaBGP instance. You should see the syslog HTTP status codes if it is successful.

###Testing

In order to run the full suite of unit tests, ensure that grpcio is installed. Run the tests with the following command from the Solenoid/ directory:

python -m unittest discover solenoid.tests.mock

If you only wish to use RESTconf and will not be testing the gRPC code, feel free to run the following individual tests:

python -m unittest solenoid.tests.mock.test_rib_rest

python -m unittest solenoid.tests.mock.test_rib_general

The following is expected output from the unit tests:

python -m unittest discover solenoid.tests.mock
............................
----------------------------------------------------------------------
Ran 28 tests in 0.042s

OK

If you recieve the final status of 'OK' you are good to go!

To run integration testing, run the following command from the Solenoid/ directory. CAUTION This will make changes to your router's RIB table! Do not run this code in a production environment!

For these tests to run, you must provide a properly formatted solenoid.config file, as described in step 3, and ensure that no other instance of Solenoid is currently running.

python -m unittest discover solenoid.tests.integration

Expected output:

python -m unittest discover solenoid.tests.integration
Thu, 01 Sep 2016 22:21:41 | INFO     | 19738  | solenoid      | ANNOUNCE | OK
.Thu, 01 Sep 2016 22:21:41 | INFO     | 19738  | solenoid      | WITHDRAW | OK
.Thu, 01 Sep 2016 22:21:42 | INFO     | 19738  | solenoid      | ANNOUNCE | OK
.Thu, 01 Sep 2016 22:21:42 | INFO     | 19738  | solenoid      | WITHDRAW | OK
.Thu, 01 Sep 2016 22:21:42 | INFO     | 19738  | solenoid      | EOR message
.
----------------------------------------------------------------------
Ran 5 tests in 0.890s

OK