KNET Solutions (Online Training Centre),
http://knetsolutions.in
knetsolutions2@gmail.com
Phone/WhatsApp: +919445042007
Online Training, Consulting & Academic SDN Project assistance.
# 1. IntroductionThis Book is (RYU SDN CRASH COURSE Course book ), prepared by KNET Solutions. This Book is used as Course material for UDEMY SDN Crash Course.
This Book is (OPENDAYLIGHT SDN CRASH COURSE Course book ), prepared by KNET Solutions. This Book is used as Course material for UDEMY OPENDAYLIGHT SDN Crash Course.
The Course is available in . The Course link is UDEMY OPENDAYLIGHT COURSE
This Course covers SDN Basics, OPENDAYLIGHT Basics, RESTCONF, OpenFlow Theory, Mininet Basics, ODL OPENFLOW PLUGIN APIs, Demos, Openvswitch, OVSDB, OVS Commands, ODL OVSDB Plugin, BGP Test bed, ODL BGP Plugin and Demo, etc.
Some book contents (IMAGE/Text) are copied from Freely available resources from internet / RFCs/ Opensource materials. Thanks to the original authors.
This Book is free to use.
# 2. InstallationPreferred System requirements:
Configuration: 2 Core + 8GB RAM (preferably)
OS:
prefer Linux Ubuntu Version.
Ubuntu versions : Ubuntu 18.04
Java - 8+ version
JAVA Installation
sudo apt-get install default-jdk
ODL Installation
OpenDayLight Version : SODIUM - SR1
wget https://nexus.opendaylight.org/content/repositories/public/org/opendaylight/integration/opendaylight/0.11.1/opendaylight-0.11.1.tar.gz
tar xvzf opendaylight-0.11.1.tar.gz
cd opendaylight-0.11.1/
./bin/karaf
you will see the karaf shell
# 3. Console Commands# Feature commandManage the features/plugins
feature:list
Lists all existing features available from the defined repositories.
feature:list -i
List only installed features
feature:list -i | grep name
List the installed features and grep with specific name.
Example
Copy feature:list -i | grep restconf
feature:install name
Installs a feature with the specified name and version.
Example
Copy feature:install odl-restconf
feature:uninstall name
Uninstalls a feature with the specified name and version
Copy feature:uninstall odl-restconf
feature:info odl-restconf
# Log commandlog:display
Displays log entries.
log:get
Shows the currently set log level
log:set
Sets the log level.
The log level to set (TRACE, DEBUG, INFO, WARN, ERROR) or DEFAULT to unset
Log file is located in data/log/karaf.log
# Exit Commandshutdown, logout
# 4. RESTConfStandard mechanisms to allow Web applications to access the configuration data, state data, data-model-specific Remote Procedure Call (RPC) operations, and event notifications within a networking device, in a modular and extensible manner.
RESTCONF uses HTTP methods to provide CRUD operations on a conceptual datastore containing YANG-defined data, which is compatible with a server that implements NETCONF datastores.
# MethodsThe RESTCONF protocol uses HTTP methods to identify the CRUD operations requested for a particular resource.
Following are the widely used methods
# GET:The GET method is sent by the client to retrieve data and metadata for a resource. It is supported for all resource types, except operation resources.
If the user is not authorized to read the target resource, an error response containing a "401 Unauthorized" status-line SHOULD be returned.
# PUT:The PUT method is sent by the client to create or replace the target data resource. A request message-body MUST be present, representing the new data resource.
The "insert" and "point" query parameters MUST be supported by the PUT method for data resources.
if the PUT request creates a new resource, a "201 Created" status-line is returned. If an existing resource is modified, a "204 No Content" status-line is returned.
# DELETE:The DELETE method is used to delete the target resource. If the DELETE request succeeds, a "204 No Content" status-line is returned. If the user is not authorized to delete the target resource, then an error response containing a "403 Forbidden" status-line SHOULD be returned.
# POSTThe POST method is sent by the client to create a data resource or invoke an operation resource.
# REST ClientsPOSTMAN GUI Based.
To install, follow this link
curl
Quick to use. Command line interface. Little hard to understand the flags/options Copy sudo apt-get install curl
# Plugin InstallationInstall ODL as per previous session, and start the ODL KARAF shell
./bin/karaf
Install the restconf and Openflow plugins
Copy feature:install odl-restconf
feature:install odl-openflowplugin-flow-services-rest
Default ODL username/password : admin/admin
ODL IP&Port: http://192.168.122.219:8181
GET http://192.168.122.219:8181restconf/operational/network-topology:network-topology/
DataModel: XML
# Accessing with CURLGET Method:
Copy curl --user "admin":"admin" -H "Accept: application/xml" -H "Content-Type: application/xml" -X GET http://192.168.122.227:8181/restconf/operational/network-topology:network-topology/
# Accessing with POSTMANURL Copy http://192.168.122.227:8181/restconf/operational/network-topology:network-topology/
Base Headers: In the Authorization TAB, Select,
Copy Type: Basic Auth
Fill username and password as mentioned above
and click Preview Request,
In the Header TAB, you could see "Authorization" Header and value "Basic xxxxxxxxxxxx" could have been populated automatically.
Add "Content-Type" and "Accept" header with Value is "application/xml" for both.
Method: GET and Query # 5. OpenFlow Plugin# Mininet# InstallationOpen the terminal, and execute the below commands,
Copy sudo apt-get update
sudo apt-get install -y openvswitch-switch
sudo apt-get install -y mininet
sudo apt-get install libxml2-utils
verify the installation
Copy sudo mn --version
sudo ovs-vsctl show
# To clean up the existing ovs bridges and namespacesNote: sometime we mistakenly closed the mininet shell, or mininet crashed. But the topology components will continue to exists. To clean such stuff, cleanup command is used.
# Our First Topology (Single)Topology with Single Switch and 4 Nodes.
Copy sudo mn --controller=remote,ip=127.0.0.1 --mac -i 10.1.1.0/24 --switch=ovsk,protocols=OpenFlow13 --topo=single,4
options Description --controller type of controller local/remote and remote controller ip. --mac mac address starts with 00:00:00:00:00:01 -i IP Subnets for the Topology --switch Switch type (ovsk - openvswitch kernel module), and openflow version. --topo topology type(linear,minimal,reversed,single,torus,tree) and params.
# Basic Openvswitch commandsCopy sudo ovs-vsctl show
sudo ovs-ofctl -O OpenFlow13 dump-flows s1
sudo ovs-ofctl -O OpenFlow13 dump-ports s1
sudo ovs-ofctl -O OpenFlow13 show s1
# Add flow for normal(traditional switch behavior)Copy sudo ovs-ofctl -O OpenFlow13 add-flow s1 actions=NORMAL
Once you are done, make sure "exit" the mininet shell,
exit
Example:
Copy mininet> exit
*** Stopping 1 controllers
c0
*** Stopping 4 links
....
*** Stopping 1 switches
s1
*** Stopping 4 hosts
h1 h2 h3 h4
*** Done
completed in 2.604 seconds
suresh@suresh-vm:~$
# Mininet Basic Shell CommandsInformative commands
Action commands
Execute the commands in HOST/Node:
Option1:
we can login to each host using 'xterm' command
xterm h1
It will open a xterm terminal for the host. Now we can execute the command inside that terminal
Option2:
we can directly execute from the mininet shell.
Copy mininet><hostname> command
Example:
Copy mininet>h1 ifconfig
mininet>h1 ping h2
mininet>h1 ip route
we can use either method to run the Traffic tests or executing the commands.
# Linear Topologylinear topology (where each switch has one host, and all switches connect in a line)
Copy sudo mn --controller=remote,ip=127.0.0.1 --mac -i 10.1.1.0/24 --switch=ovsk,protocols=OpenFlow13 --topo=linear,4
install normal flows
Copy sudo ovs-ofctl -O OpenFlow13 add-flow s1 actions=NORMAL
sudo ovs-ofctl -O OpenFlow13 add-flow s2 actions=NORMAL
sudo ovs-ofctl -O OpenFlow13 add-flow s3 actions=NORMAL
sudo ovs-ofctl -O OpenFlow13 add-flow s4 actions=NORMAL
# Tree Topology
Copy sudo mn --controller=remote,ip=127.0.0.1 --mac -i 10.1.1.0/24 --topo=tree,depth=2,fanout=3
fanout : each switch is connected to these many childs
depth : depth of the tree
# Running TCP/UDP Traffic Testsa. Setup the Topology with xterms options (open terminal for each Node)
Copy sudo mn --controller=remote,ip=127.0.0.1 --mac -i 10.1.1.0/24 --switch=ovsk,protocols=OpenFlow13 --topo=linear,4 -x
install normal flows
Copy sudo ovs-ofctl -O OpenFlow13 add-flow s1 actions=NORMAL
sudo ovs-ofctl -O OpenFlow13 add-flow s2 actions=NORMAL
sudo ovs-ofctl -O OpenFlow13 add-flow s3 actions=NORMAL
sudo ovs-ofctl -O OpenFlow13 add-flow s4 actions=NORMAL
# TCP Traffic Test between h1 to h4Run IPERF TCP Server in h4
-s means server mode
RUN IPERF TCP Client in h1
Copy iperf -c 10.1.1.4 -i 10 -t 30
iperf -c 10.1.1.4 -i 10 -b 10m -t 30
iperf -c 10.1.1.4 -i 10 -P 10 -t 30
-c means client mode.
-i means reporting interval
-t means test duration in seconds
-b means bandwidth 10m means 10Mbps
-P means parallel connections
# UDP Traffic Test between h1 to h4Run IPERF UDP Server in h4
-u means udp
RUN IPERF UDP Client in h1
Copy iperf -u -c 10.1.1.4 -b 10m -i 10 -t 30
iperf -u -c 10.1.1.4 -b 10m -i 10 -P 10 -t 30
-b means bandwidth 10m means 10Mbps
# Openflow Plugin InstallationOpenDayLight Version : SODIUM - SR1
wget https://nexus.opendaylight.org/content/repositories/public/org/opendaylight/integration/opendaylight/0.11.1/opendaylight-0.11.1.tar.gz
tar xvzf opendaylight-0.11.1.tar.gz
cd opendaylight-0.11.1/
./bin/karaf
you will see the karaf shell
Install the Openflow Plugin:
feature:install odl-restconf
feature:install odl-openflowplugin-flow-services-rest
optional plugins:
feature:install odl-openflowplugin-app-lldp-speaker
feature:install odl-openflowplugin-app-table-miss-enforcer
# ComponentsThe OpenFlow Plugin provides the following RESTCONF APIs:
OpenFlow Topology OpenFlow Statistics OpenFlow Programming #### OpenFlow Topology
Retriving the topology details
http://localhost:8181/restconf/operational/network-topology:network-topology/
API : /restconf/operational/network-topology:network-topology/topology/flow:1
Copy curl --user "admin":"admin" -X GET http://127.0.0.1:8181/restconf/operational/network-topology:network-topology/topology/flow:1 | jq .
It returns switch,port details
Here openflow:1 is switch dpid.
The output can be compared to
Copy sudo ovs-ofctl -O OpenFlow13 show s1
# OpenFlow StatisticsInventory data:
http://localhost:8181/restconf/operational/opendaylight-inventory:nodes/
http://localhost:8181/restconf/operational/opendaylight-inventory:nodes/node/openflow:4
Copy curl --user "admin":"admin" -X GET http://172.17.0.2:8181/restconf/operational/opendaylight-inventory:nodes/ | jq .
Collect the Switch Hardware details such as make, version
Port description details - mac-address of the port, port speed, state, admin status,
Port statistics - tx, rx bytes trasfered
group statistcis
flow statistics,
etc.
Port stats
http://localhost:8181/restconf/operational/opendaylight-inventory:nodes/node/openflow:4/node-connector/openflow:4:1
Flow stats
http://localhost:8181/restconf/operational/opendaylight-inventory:nodes/node/openflow:4/table/0
Group stats
/restconf/operational/opendaylight-inventory:nodes/node/openflow:1/group/2
#### OpenFlow Programming
The controller provides interfaces that can be used to program the connected OpenFlow devices. These interfaces interact with the OpenFlow southbound plugin that uses OpenFlow modification messages to program flows, groups and meters in the switch.
The controller provides the following RESTCONF interfaces:
Configuration Datastore:
RPC Operations:
configuration datastore:
PUT
http://localhost:8181/restconf/operational/opendaylight-inventory:nodes/node/openflow:1/table/0/flow/1
# Demonstrationhttp://localhost:8181/restconf/operational/network-topology:network-topology/topology/flow:1
# HUB ExerciseCopy sudo mn --controller=remote,ip=127.0.0.1 --mac -i 10.1.1.0/24 --switch=ovsk,protocols=OpenFlow13 --topo=single,4
To add a flood flow
Copy curl --user "admin":"admin" -H "Accept: application/xml" -H "Content-Type: application/xml" -X PUT http://localhost:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/0/flow/1 -d @hub.xml
Copy sudo ovs-ofctl -O OpenFlow13 dump-flows s1
To remove this flow
Copy curl --user "admin":"admin" -H "Accept: application/xml" -H "Content-Type: application/xml" -X DELETE http://localhost:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/0/flow/1
# L2 Switch Exercise# 1. Create a Single topologyCopy sudo mn --controller=remote,ip=127.0.0.1 --mac -i 10.1.1.0/24 --switch=ovsk,protocols=OpenFlow13 --topo=single,4
# 2. Make sure ODL is running and openflow plugin is installedIn the karaf shell,
Copy feature:list -i |grep openflow
And in the terminal, verify the OPENFLOW port is listening mode,
Copy sudo netstat -i | grep 6653
# 3. Check the switches are connected to the ODL Controller# 4. Add a ARP flowCopy curl --user "admin":"admin" -H "Accept: application/xml" -H "Content-Type: application/xml" -X PUT http://localhost:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/0/flow/1 -d @arp.xml
# 5. Add a h1(00:00:00:00:00:01) to h2(00:00:00:00:00:02) flowCopy
curl --user "admin":"admin" -H "Accept: application/xml" -H "Content-Type: application/xml" -X PUT http://localhost:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/0/flow/2 -d @l2match1.xml
# 6. Add a h2(00:00:00:00:00:02) to h1(00:00:00:00:00:01) flowCopy curl --user "admin":"admin" -H "Accept: application/xml" -H "Content-Type: application/xml" -X PUT http://localhost:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/0/flow/3 -d @l2match2.xml
# 7. Verify the flows in OVSCopy sudo ovs-ofctl -O OpenFlow13 dump-flows s1
# 8. Verify the flows in ODL DatastoreSpecific flow:
Copy curl --user "admin":"admin" -H "Accept: application/xml" -H "Content-Type: application/xml" -X GET http://localhost:8181/restconf/operational/opendaylight-inventory:nodes/node/openflow:1/table/0/flow/1 | xmllint --format -
Copy curl --user "admin":"admin" -H "Accept: application/xml" -H "Content-Type: application/xml" -X GET http://localhost:8181/restconf/operational/opendaylight-inventory:nodes/node/openflow:1/table/0/flow/2 | xmllint --format -
Copy curl --user "admin":"admin" -H "Accept: application/xml" -H "Content-Type: application/xml" -X GET http://localhost:8181/restconf/operational/opendaylight-inventory:nodes/node/openflow:1/table/0/flow/3 | xmllint --format -
# 9. Try ping from mininet shell# 10. Delete the flows from ODLCopy curl -v --user "admin":"admin" -H "Accept: application/xml" -H "Content-Type: application/xml" -X DELETE http://localhost:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/0/flow/1
curl -v --user "admin":"admin" -H "Accept: application/xml" -H "Content-Type: application/xml" -X DELETE http://localhost:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/0/flow/2
curl -v --user "admin":"admin" -H "Accept: application/xml" -H "Content-Type: application/xml" -X DELETE http://localhost:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/0/flow/3
# 11. exit from mininet# L3 Switch Exercise# 1. Create a Single topologyCopy sudo mn --controller=remote,ip=127.0.0.1 --mac -i 10.1.1.0/24 --switch=ovsk,protocols=OpenFlow13 --topo=single,4
# 2. Make sure ODL is running and openflow plugin is installedIn the karaf shell,
Copy feature:list -i |grep openflow
And in the terminal, verify the OPENFLOW port is listening mode,
Copy sudo netstat -i | grep 6653
# 3. Check the switches are connected to the ODL Controller# 4. Add a ARP flowCopy curl --user "admin":"admin" -H "Accept: application/xml" -H "Content-Type: application/xml" -X PUT http://localhost:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/0/flow/1 -d @arp.xml
# 5. Add a h1(10.1.1.1) to h2(10.1.1.2) flowCopy
curl --user "admin":"admin" -H "Accept: application/xml" -H "Content-Type: application/xml" -X PUT http://localhost:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/0/flow/2 -d @l3match1.xml
# 6. Add a h2(10.1.1.2) to h1(10.1.1.1) flowCopy curl --user "admin":"admin" -H "Accept: application/xml" -H "Content-Type: application/xml" -X PUT http://localhost:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/0/flow/3 -d @l3match2.xml
# 7. Verify the flows in OVSCopy sudo ovs-ofctl -O OpenFlow13 dump-flows s1
# 8. Try ping from mininet shell# 9. Delete the flows from ODLCopy curl -v --user "admin":"admin" -H "Accept: application/xml" -H "Content-Type: application/xml" -X DELETE http://localhost:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/0/flow/1
curl -v --user "admin":"admin" -H "Accept: application/xml" -H "Content-Type: application/xml" -X DELETE http://localhost:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/0/flow/2
curl -v --user "admin":"admin" -H "Accept: application/xml" -H "Content-Type: application/xml" -X DELETE http://localhost:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/0/flow/3
# 10. exit from mininet# L4 Match switchAllow only TCP Traffic between h1 and h2
# Create a Single topologyCopy sudo mn --controller=remote,ip=127.0.0.1 --mac -i 10.1.1.0/24 --switch=ovsk,protocols=OpenFlow13 --topo=single,4
# Make sure ODL is running and openflow plugin is installedIn the karaf shell,
Copy feature:list -i |grep openflow
And in the terminal, verify the OPENFLOW port is listening mode,
Copy sudo netstat -i | grep 6653
# Check the switches are connected to the ODL Controller# Add a ARP flowCopy curl --user "admin":"admin" -H "Accept: application/xml" -H "Content-Type: application/xml" -X PUT http://localhost:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/0/flow/1 -d @arp.xml
# Add a h1(10.1.1.1) to h2(10.1.1.2) TCP flowCopy curl --user "admin":"admin" -H "Accept: application/xml" -H "Content-Type: application/xml" -X PUT http://localhost:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/0/flow/2 -d @l4match1.xml
# 7. Add a h2(10.1.1.2) to h1(10.1.1.1) TCP flowCopy curl --user "admin":"admin" -H "Accept: application/xml" -H "Content-Type: application/xml" -X PUT http://localhost:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/0/flow/3 -d @l4match2.xml
# 8. Verify the flows in OVSCopy sudo ovs-ofctl -O OpenFlow13 dump-flows s1
# 9. Try TCP traffic in mininet shellCopy h1 iperf -s &
h2 iperf -c h1
# 10. Delete the flows from ODLCopy curl -v --user "admin":"admin" -H "Accept: application/xml" -H "Content-Type: application/xml" -X DELETE http://localhost:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/0/flow/1
curl -v --user "admin":"admin" -H "Accept: application/xml" -H "Content-Type: application/xml" -X DELETE http://localhost:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/0/flow/2
curl -v --user "admin":"admin" -H "Accept: application/xml" -H "Content-Type: application/xml" -X DELETE http://localhost:8181/restconf/config/opendaylight-inventory:nodes/node/openflow:1/table/0/flow/3
# 11. exit from mininet# 6. OVSDB# Openvswitch# 1. Openvswitch installationsudo apt-get install openvswitch-switch
# 2. verify openvswitch is installedin the terminal,
# 3. verify openvswitch processin the terminal,
Copy sudo ps -ef | grep ovs
sudo lsmod | grep openvswitch
# 4. verify OVSDB Port is in listening modeCopy sudo netstat -a | grep 6640
# 5. Sample Management commandsCopy sudo ovs-vsctl add-br s1
sudo ovs-vsctl show
sudo ovs-vsctl add-port s1 veth0
sudo ovs-vsctl show
sudo ovs-vsctl add-port s1 veth1
sudo ovs-vsctl show
sudo ovs-vsctl del-port s1 veth0
sudo ovs-vsctl set-controller s1 tcp:192.168.56.101:6633
sudo ovs-vsctl set-controller s2 tcp:192.168.56.101:6633
sudo ovs-vsctl del-br s1
Note:
Copy sudo ip link add veth0 type veth peer name veth1
sudo ifconfig veth0 up
sudo ifconfig veth1 up
sudo ip link delete veth0
# 6. Example UsecaseTwo hosts(created using netns) are ready. we want to create a switch "s1" and connect these two hosts. Add "NORMAL" flow, and Verify ping traffic between the hosts.
Topology diagram without switch:
Now, we create two hosts using netns as below.
Copy #create host named red
sudo ip netns add red
sudo ip link add red-veth0 type veth peer name red-veth1
sudo ip link set red-veth1 netns red
sudo ip netns exec red ip addr add 10.10.20.1/24 dev red-veth1
sudo ip netns exec red ip link set red-veth1 up
#create host named blue
sudo ip netns add blue
sudo ip link add blue-veth0 type veth peer name blue-veth1
sudo ip link set blue-veth1 netns blue
sudo ip netns exec blue ip addr add 10.10.20.2/24 dev blue-veth1
sudo ip netns exec blue ip link set blue-veth1 up
sudo ifconfig red-veth0 up
sudo ifconfig blue-veth0 up
# Create switch and associate the portsNow, we create the switch and associate as below using ovs-vsctl (using OVSDB interface)
Copy sudo ovs-vsctl add-br s1
sudo ovs-vsctl add-port s1 red-veth0
sudo ovs-vsctl add-port s1 blue-veth0
Adding a Normal flow
Copy sudo ovs-ofctl -O OpenFlow13 add-flow s1 actions=NORMAL
Testing
Copy sudo ip netns exec blue ping 10.10.20.1
# Destory the setupCopy #delete
sudo ip netns delete red
sudo ip netns delete blue
sudo ovs-vsctl del-br s1
# OVSDB PluginOVSDB(OVS Management Interface) implementation in ODL. This plugin can communicate with Openvswitch and perform the configuration and management operations.
ODL exposing the Northbound REST APIs are for OVSDB.
Example:
http://localhost:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/
Using these APIs, user/app can perform the OVSDB operations to the manage the Openvswitch , such as,
Create a bridge, Create a Qos Delete a bridge Add a port to the bridge
etc. # InstallationOpenDayLight Version : SODIUM - SR1
JAVA Installation
sudo apt-get install default-jdk
sudo apt-get install openvswitch-switch jq
ODL Installation
wget https://nexus.opendaylight.org/content/repositories/public/org/opendaylight/integration/opendaylight/0.11.1/opendaylight-0.11.1.tar.gz
tar xvzf opendaylight-0.11.1.tar.gz
cd opendaylight-0.11.1/
./bin/karaf
you will see the karaf shell
Install the Openflow Plugin:
feature:install odl-mdsal-apidocs
feature:install odl-restconf
feature:install odl-ovsdb-southbound-impl-ui
Once installed, Check the OVSDB Topology will get created.
This can be verified in API DOCS or RESTAPI "network-topology" endpoint,
GET http://localhost:8181/restconf/operational/network-topology:network-topology/
Copy curl --user "admin":"admin" -H "Accept: application/json" -H "Content-Type: application/json" -X GET http://localhost:8181/restconf/operational/network-topology:network-topology/ | jq .
Response
Copy {
"network-topology": {
"topology": [
{
"topology-id": "ovsdb:1"
}
]
}
}
# Workflow in Detailcreate a OVSDB Host Perform operations(add switch, delete switch, etc) on that OVSDB HOST Delete OVSDB Host(if you want) Before connect to ODL, check ovs tables:
Copy sudo ovs-vsctl list open_vswitch
Configure the ODL to talk to the OVSDB host ACTIVE CONNECTION Mode:
API: http://localhost:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1
METHOD : PUT
DATA:
Copy {
"network-topology:node": [
{
"node-id": "ovsdb:HOST1",
"connection-info": {
"ovsdb:remote-port": "6640",
"ovsdb:remote-ip": "127.0.0.1"
}
}
]
}
Examples:
Copy curl --user "admin":"admin" -H "Accept: application/json" -H "Content-Type: application/json" -X PUT http://localhost:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1 -d @ovsdb_host.json
Verify the OVSDB Port Connections in HOST1 VM
Copy suresh@sdn:~$ sudo netstat -a | grep 6640
tcp 0 0 0.0.0.0:6640 0.0.0.0:* LISTEN
tcp 0 0 localhost:6640 localhost:59296 ESTABLISHED
tcp6 0 0 localhost:59296 localhost:6640 ESTABLISHED
suresh@sdn:~$
GET OVSDB host details (config and operational) GET
http://localhost:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1
GET
http://localhost:8181/restconf/operational/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1
Examples:
Copy
suresh@sdn:~$ curl --user "admin":"admin" -H "Accept: application/json" -H "Content-Type: application/json" -X GET http://localhost:8181/restconf/operational/network-topology:network-topology/ | jq .
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1417 100 1417 0 0 64409 0 --:--:-- --:--:-- --:--:-- 64409
{
"network-topology": {
"topology": [
{
"topology-id": "ovsdb:1",
"node": [
{
"node-id": "ovsdb:HOST1",
"ovsdb:datapath-type-entry": [
{
"datapath-type": "ovsdb:datapath-type-netdev"
},
{
"datapath-type": "ovsdb:datapath-type-system"
}
],
"ovsdb:ovs-version": "2.9.5",
"ovsdb:connection-info": {
"local-ip": "127.0.0.1",
"remote-port": 6640,
"remote-ip": "127.0.0.1",
"local-port": 59296
},
"ovsdb:openvswitch-external-ids": [
{
"external-id-key": "hostname",
"external-id-value": "sdn"
},
{
"external-id-key": "opendaylight-iid",
"external-id-value": "/network-topology:network-topology/network-topology:topology[network-topology:topology-id='ovsdb:1']/network-topology:node[network-topology:node-id='ovsdb:HOST1']"
},
{
"external-id-key": "system-id",
"external-id-value": "f1c3af1d-1bff-4d71-a00b-42cbb4134391"
},
{
"external-id-key": "rundir",
"external-id-value": "/var/run/openvswitch"
}
],
"ovsdb:db-version": "7.15.1",
"ovsdb:interface-type-entry": [
{
"interface-type": "ovsdb:interface-type-lisp"
},
{
"interface-type": "ovsdb:interface-type-geneve"
},
{
"interface-type": "ovsdb:interface-type-gre"
},
{
"interface-type": "ovsdb:interface-type-system"
},
{
"interface-type": "ovsdb:interface-type-vxlan"
},
{
"interface-type": "ovsdb:interface-type-internal"
},
{
"interface-type": "ovsdb:interface-type-stt"
},
{
"interface-type": "ovsdb:interface-type-tap"
},
{
"interface-type": "ovsdb:interface-type-patch"
}
],
"ovsdb:manager-entry": [
{
"target": "ptcp:6640",
"connected": true,
"number_of_connections": 1
}
]
}
]
}
]
}
}
suresh@sdn:~$
Copy suresh@sdn:~$ curl --user "admin":"admin" -H "Accept: application/json" -H "Content-Type: application/json" -X GET http://localhost:8181/restconf/config/network-topology:network-topology/ | jq .
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 165 100 165 0 0 8250 0 --:--:-- --:--:-- --:--:-- 8250
{
"network-topology": {
"topology": [
{
"topology-id": "ovsdb:1",
"node": [
{
"node-id": "ovsdb:HOST1",
"ovsdb:connection-info": {
"remote-ip": "127.0.0.1",
"remote-port": 6640
}
}
]
}
]
}
}
suresh@sdn:~$
Exercise add a another OVS HOST (HOST2)/and check
Copy curl --user "admin":"admin" -H "Accept: application/json" -H "Content-Type: application/json" -X PUT http://localhost:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST2 -d @ovsdb_host2.json
and check it.
# Operations - Add a new BridgeThis example shows how to add a bridge("s1") to the OVSDB node ovsdb:HOST1.
PUT
http://localhost:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1%2Fbridge%2Fs1
BODY
Copy {
"network-topology:node": [
{
"node-id": "ovsdb:HOST1/bridge/s1",
"ovsdb:bridge-name": "s1",
"ovsdb:protocol-entry": [
{
"protocol": "ovsdb:ovsdb-bridge-protocol-openflow-13"
}
],
"ovsdb:managed-by": "/network-topology:network-topology/network-topology:topology[network-topology:topology-id='ovsdb:1']/network-topology:node[network-topology:node-id='ovsdb:HOST1']"
}
]
}
Example:
Copy
curl --user "admin":"admin" -H "Accept: application/json" -H "Content-Type: application/json" -X PUT http://localhost:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1%2Fbridge%2Fs1 -d @s1.json
verify with cli
Notice that the ovsdb:managed-by attribute is specified in the command. This indicates the association of the new bridge node with its OVSDB node.
Verify it as below,
Copy suresh@sdn:~$ curl --user "admin":"admin" -H "Accept: application/json" -H "Content-Type: application/json" -X GET http://localhost:8181/restconf/operational/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1%2Fbridge%2Fs1 | jq .
{
"node": [
{
"node-id": "ovsdb:HOST1/bridge/s1",
"ovsdb:bridge-name": "s1",
"ovsdb:bridge-external-ids": [
{
"bridge-external-id-key": "opendaylight-iid",
"bridge-external-id-value": "/network-topology:network-topology/network-topology:topology[network-topology:topology-id='ovsdb:1']/network-topology:node[network-topology:node-id='ovsdb:HOST1/bridge/s1']"
}
],
"ovsdb:stp_enable": false,
"ovsdb:datapath-type": "ovsdb:datapath-type-system",
"ovsdb:datapath-id": "00:00:46:a8:3a:e5:95:45",
"ovsdb:bridge-uuid": "e53aa844-454c-4595-9787-6a5f102269f4",
"ovsdb:protocol-entry": [
{
"protocol": "ovsdb:ovsdb-bridge-protocol-openflow-13"
}
],
"ovsdb:managed-by": "/network-topology:network-topology/network-topology:topology[network-topology:topology-id='ovsdb:1']/network-topology:node[network-topology:node-id='ovsdb:HOST1']",
"termination-point": [
{
"tp-id": "s1",
"ovsdb:ingress-policing-rate": 0,
"ovsdb:interface-type": "ovsdb:interface-type-internal",
"ovsdb:interface-uuid": "215bbf31-2631-43ae-9feb-e482ade04075",
"ovsdb:ifindex": 4,
"ovsdb:name": "s1",
"ovsdb:mac-in-use": "46:a8:3a:e5:95:45",
"ovsdb:ingress-policing-burst": 0,
"ovsdb:port-uuid": "d72af941-dab8-4de0-b7dc-47cd5a420ca3",
"ovsdb:ofport": 65534
}
]
}
]
}
verify with cli
# Operations - Update the SDN Controller information in the BridgePUT
http://localhost:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1%2Fbridge%2Fs1
BODY
Copy {
"network-topology:node": [
{
"node-id": "ovsdb:HOST1/bridge/s1",
"ovsdb:bridge-name": "s1",
"ovsdb:controller-entry": [
{
"target": "tcp:127.0.0.1:6653"
}
],
"ovsdb:managed-by": "/network-topology:network-topology/network-topology:topology[network-topology:topology-id='ovsdb:1']/network-topology:node[network-topology:node-id='ovsdb:HOST1']"
}
]
}
Example:
Copy
curl --user "admin":"admin" -H "Accept: application/json" -H "Content-Type: application/json" -X PUT http://localhost:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1%2Fbridge%2Fs1 -d @s1_controller.json
verify with cli
# Operations - Add a port to the switchAPI
PUT
http://localhost:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1%2Fbridge%2Fs1/termination-point/port1
Copy {
"network-topology:termination-point": [
{
"ovsdb:name": "port1",
"tp-id": "port1"
}
]
}
Example:
Copy curl --user "admin":"admin" -H "Accept: application/json" -H "Content-Type: application/json" -X PUT http://localhost:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1%2Fbridge%2Fs1/termination-point/port1 -d @port1.json
Verify with cli :
ADD A PATCH PORT
Prerequisties:
Create veth pair
Copy sudo ip link add veth0 type veth peer name veth1
sudo ifconfig veth0 up
sudo ifconfig veth1 up
Copy {
"network-topology:termination-point": [
{
"ovsdb:name": "patch1",
"tp-id": "patch1",
"ovsdb:interface-type": "ovsdb:interface-type-patch",
"ovsdb:options": [
{
"ovsdb:option": "peer",
"ovsdb:value" : "veth0"
}
]
}
]
}
Example :
Copy curl --user "admin":"admin" -H "Accept: application/json" -H "Content-Type: application/json" -X PUT http://localhost:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1%2Fbridge%2Fs1/termination-point/patch1 -d @patch1.json
ADD A VXLAN PORT
Copy {
"network-topology:termination-point": [
{
"ovsdb:options": [
{
"ovsdb:option": "remote_ip",
"ovsdb:value" : "10.10.14.11"
}
],
"ovsdb:name": "vxlanport1",
"ovsdb:interface-type": "ovsdb:interface-type-vxlan",
"tp-id": "vxlanport1",
"vlan-tag": "1",
"trunks": [
{
"trunk": "5"
}
],
"vlan-mode":"access"
}
]
}
Example :
Copy curl --user "admin":"admin" -H "Accept: application/json" -H "Content-Type: application/json" -X PUT http://localhost:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1%2Fbridge%2Fs1/termination-point/vxlanport1 -d @vxlanport1.json
# 6. Operations - Delete a BridgeDELETE
http://localhost:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1%2Fbridge%2s1
Example
Copy suresh@sdn:~$ curl --user "admin":"admin" -H "Accept: application/json" -H "Content-Type: application/json" -X DELETE http://localhost:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1%2Fbridge%2Fs1
verify with cli
# 7. DELETE the OVSDB HOST entryDELETE http://localhost:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST1
Copy curl --user "admin":"admin" -H "Accept: application/json" -H "Content-Type: application/json" -X DELETE http://localhost:8181/restconf/config/network-topology:network-topology/topology/ovsdb:1/node/ovsdb:HOST2
After removed, check the status again.
# 7. ODL BGP# IntroductionBGP evolved long time before SDN was born, it plays a significant role in many SDN use-cases. Also, continuous evolution of the protocol brings extensions that are very well suited for SDN. Nowadays, BGP can carry various types of routing information - L3VPN, L2VPN, IP multicast, linkstate, etc. Here is a brief list of software-based/legacy-network technologies where BGP-based SDN solution get into an action:
SDN WAN - WAN orchestration and optimization SDN router - Turns switch into an Internet router Virtual Route Reflector - High-performance server-based BGP Route Reflector SDX - A Software Defined Internet Exchange controller Large-Scale Data Centers - BGP Data Center Routing, MPLS/SR in DCs, DC interconnection DDoS mitigation - Traffic Filtering distribution with BGP # BGP Testbed (ContainerNet)# 1. BGP Testbed(containernet) InstallationContainernet installation
Requires Ubuntu 18.04 LTS and Python3.
Copy sudo apt-get install ansible git aptitude
git clone https://github.com/containernet/containernet.git
cd containernet/ansible
sudo ansible-playbook -i "localhost," -c local install.yml
cd ..
Quick verification
Copy sudo mn --controller=remote,ip=127.0.0.1 --topo=single,2
you should see the "containernet>" prompt
To see the docker stuff
Copy sudo docker images
sudo docker ps -a
# 2. exercise1 - Traditional EBGPHow to run
i) Run the topology
ii) check the bgp protocol status of Router R1 and R2 in mininet shell
Copy r1 birdc show protocols
r1 birdc show route
r1 ip route
R2
Copy r2 birdc show protocols
r2 birdc show route
r2 ip route
BGP Peers are established between R1 and R2. Routes are synchronized.
Note: if you know docker commands, you can login/execute commands router docker .
Important Docker commands
Copy sudo docker ps -a
sudo docker exec -it mn.r1 sh
birdc important commands
Copy birdc show status
birdc show route
birdc show protocols
birdc show protocols all
Logs can be checked in
iii) verify the ping traffic from h1 to h2
try traceroute also
# ODL BGP Plugin# InstallationOpenDayLight Version : SODIUM - SR1
JAVA Installation
sudo apt-get install default-jdk
sudo apt-get install libxml2-utils
ODL Installation
wget https://nexus.opendaylight.org/content/repositories/public/org/opendaylight/integration/opendaylight/0.11.1/opendaylight-0.11.1.tar.gz
tar xvzf opendaylight-0.11.1.tar.gz
cd opendaylight-0.11.1/
./bin/karaf
you will see the karaf shell
Install the Openflow Plugin:
feature:install odl-mdsal-apidocs
feature:install odl-restconf
feature:install odl-bgpcep-bgp
Verification
In the apidocs, http://localhost:8181/apidoc/explorer/index.html
you would see bgp yang models/apis are displaying
# REST API VerificationsCreate a BGP Instace
Copy curl --user "admin":"admin" -H "Accept: application/xml" -H "Content-Type: application/xml" -X POST http://localhost:8181/restconf/config/openconfig-network-instance:network-instances/network-instance/global-bgp/openconfig-network-instance:protocols/ -d @bgp_router.xml
Copy curl -v --user "admin":"admin" -H "Accept: application/xml" -H "Content-Type: application/xml" -X GET http://localhost:8181/restconf/config/openconfig-network-instance:network-instances/network-instance/global-bgp/openconfig-network-instance:protocols/ | xmllint --format -
Verify the BGP Instace
Copy curl -v --user "admin":"admin" -H "Accept: application/xml" -H "Content-Type: application/xml" -X GET http://localhost:8181/restconf/operational/bgp-rib:bgp-rib/ | xmllint --format -
Delete the BGP Instance
Copy curl -v --user "admin":"admin" -H "Accept: application/xml" -H "Content-Type: application/xml" -X DELETE http://localhost:8181/restconf/config/openconfig-network-instance:network-instances/network-instance/global-bgp/openconfig-network-instance:protocols/ -d @bgp_router.xml
# Demo- ODL as EBGP routeri) Run the topology
ii) check the bgp protocol status on Router R1 and R2
R1
Copy containernet>r1 birdc show protocols
containernet>r1 ip route
R2
Copy containernet>r2 birdc show protocols
containernet>r2 ip route
BGP Peers are established between R1 and R2. Routes are synchronized.
iii) Create the ODL BGP Instance
Copy curl -v --user "admin":"admin" -H "Accept: application/xml" -H "Content-Type: application/xml" -X POST http://localhost:8181/restconf/config/openconfig-network-instance:network-instances/network-instance/global-bgp/openconfig-network-instance:protocols/ -d @bgp_router.xml
iv) verification
Copy curl -v --user "admin":"admin" -H "Accept: application/xml" -H "Content-Type: application/xml" -X GET http://localhost:8181/restconf/operational/bgp-rib:bgp-rib/ | xmllint --format -
v) create bgp neighbor
Copy curl -v --user "admin":"admin" -H "Accept: application/xml" -H "Content-Type: application/xml" -X POST http://localhost:8181/restconf/config/openconfig-network-instance:network-instances/network-instance/global-bgp/openconfig-network-instance:protocols/protocol/openconfig-policy-types:BGP/bgp-odl-router/bgp/neighbors/ -d @bgp_neighbor.xml
vi) verify bgp neighbor/route details
Copy curl -v --user "admin":"admin" -H "Accept: application/xml" -H "Content-Type: application/xml" -X GET http://localhost:8181/restconf/operational/bgp-rib:bgp-rib/rib/bgp-odl-router/ | xmllint --format -
vii) verify the bgp ports and neighbor establishment
Copy containernet>r1 birdc show protocols
containernet>r1 ip route
Copy $ netstat -a | grep bgp
tcp 0 0 172.17.0.1:50876 172.17.0.2:bgp ESTABLISHED
vii) Destroy the test
Delete the BGP instance in ODL
Copy curl -v --user "admin":"admin" -H "Accept: application/xml" -H "Content-Type: application/xml" -X DELETE http://localhost:8181/restconf/config/openconfig-network-instance:network-instances/network-instance/global-bgp/openconfig-network-instance:protocols/ -d @bgp_router.xml
exit from containernet.
# 8. References