[lighty.io] OVSDB & OpenFlow Controller
OVSDB and OpenFlow controller based on lighty.io
PANTHEON.tech has recently published an example application of an SDN controller, using RESTCONF Northbound module and OVSDB + OpenFlow Southbound modules.
In this blog we are going to describe, how to use the SDN controller with an Open vSwitch instance running in OpenStack.
Open vSwitch, OVSDB & OpenFlow
Open vSwitch is open source virtual switch which uses OVSDB (Open vSwitch Database) and OVSDB management protocol for management of virtual OpenFlow switches referred to as bridges.
The bridges are configurable by OpenFlow protocol according to OpenFlow switch specification.
We have already written a blog about OpenFlow protocol and its support by lighty.io. There’s also example SDN controller application called lighty-community-restconf-ofp-app. It utilizes RESTCONF northbound module and OpenFlow southbound module only. You can find it at our GitHub repository.
Connecting to Open vSwitch of OpenStack
In this blog, we will show you some example setup and sequence of requests using both OVSDB and OpenFlow protocols implemented as SB modules in lighty.io.
We have published an example SDN controller called lighty-community-restconf-ovsdb-app, which utilizes RESTCONF northbound module and OVSDB southbound module only. You can check its README.md file and Postman collection for more details.
As we have already mentioned, Open vSwitch used in the testing setup is running in OpenStack. Here is a picture and description of the setup:
- Postman or curl requests are submitted from the same machine where SDN controller is running, so URLs use localhost address (127.0.0.1)
- Open vSwitch instance is running on a machine with IP address 10.14.0.103 (the same address used in ovs-vsctl command explained above) The tested instance has been set up by DevStack scripts but it can be any Open vSwitch instance running in OpenStack Network node, compute node or outside of OpenStack.
- TCP port used for OVSDB server(s) is 6640
- TCP port used by OpenFlow server(s) is 6633
Example workflow
Subsequent requests can be found in the repository at GitHub, in the form of Postman collection. In the README.md & in this blog, we are using a curl command to send the RESTCONF requests. We are also using the Python module json.tool for printing of JSON responses.
1. Configure OVSDB manager of Open vSwitch
The following piece of the ovs–vsctl show command output shows the initial configuration of the Open vSwitch and its state, where we can see that the Neutron service is connected as OVSDB manager (Manager “ptcp:6640:127.0.0.1”). The Neutron service is also configured as OpenFlow controller for the bridge br-tun (Controller “tcp:127.0.0.1:6633”) and br-tun is connected to the controller.
sudo ovs-vsctl show 729321e6-991d-4ae5-a4f9-96b1e2919596 Manager "ptcp:6640:127.0.0.1" is_connected: true Bridge br-tun Controller "tcp:127.0.0.1:6633" is_connected: true fail_mode: secure Port br-tun Interface br-tun type: internal Port patch-int Interface patch-int type: patch options: {peer=patch-tun}
Using this ovs-vsctl command we set up Open vSwitch to listen to second OVSDB manager connection at TCP port 6640 and an interface with IP address 10.14.0.103. The command keeps the configuration for Neutron service as OVSDB manager (ptcp:6640:127.0.0.1).
sudo ovs-vsctl set-manager ptcp:6640:127.0.0.1 ptcp:6640:10.14.0.103
The output of “ovs-vsctl show” command must be changed, as a result of the command above. There should be two managers configured, but only one of them is connected. The connected one is Neutron service and we have to start and configure the SDN controller, in order to initiate OVSDB connection from the controller’s side.
sudo ovs-vsctl show
729321e6-991d-4ae5-a4f9-96b1e2919596
Manager "ptcp:6640:127.0.0.1"
is_connected: true
Manager "ptcp:6640:10.14.0.103"
Bridge br-tun
Controller "tcp:127.0.0.1:6633"
is_connected: true
fail_mode: secure
Port br-tun
Interface br-tun
type: internal
Port patch-int
Interface patch-int
type: patch
options: {peer=patch-tun}
2. Setup OVSDB connection
This RESTCONF request results in OVSDB session initiation to the pre-configured OVSDB server in the Open vSwitch.
curl -v --request PUT \ --url http://127.0.0.1:8888/restconf/data/network-topology:network-topology/topology=ovsdb%3A1/node=ovsdb%3A%2F%2FHOST1 \ --header 'Authorization: Basic YWRtaW46YWRtaW4=' \ --header 'Content-Type: application/json' \ --data '{ "network-topology:node": [ { "node-id": "ovsdb://HOST1", "connection-info": { "ovsdb:remote-port": "6640", "ovsdb:remote-ip": "10.14.0.103" } } ] }'
You can check whether the session has been established using the “ovs-vsctl” show command. Both OVSDB managers should be connected now. You can also use the next RESTCONF request.
sudo ovs-vsctl show 729321e6-991d-4ae5-a4f9-96b1e2919596 Manager "ptcp:6640:127.0.0.1" is_connected: true Manager "ptcp:6640:10.14.0.103" is_connected: true Bridge br-tun Controller "tcp:127.0.0.1:6633" is_connected: true fail_mode: secure Port br-tun Interface br-tun type: internal Port patch-int Interface patch-int type: patch options: {peer=patch-tun}
3. Retrieve OVSDB network topology data (all nodes)
Now, we are going to ask lighty.io (meaning the SDN controller) about the state of OVS. In this step, we are going to access the SDN controller through a RESTCONF request. The controller will then create a request via the OVSDB protocol and OVS will create the same request, as shown in OVS-VSCTL show.
This RPC request returns the same data as an output of the ovs-vsctl show command. But the show command returns text output. In case of RPC request, the output is formatted as JSON or XML (depending on the Accept header) what is more appropriate for API between software layers of SDN solutions (i.e.: RPCs returning JSON or XML formatted output of commands are SDN ready).
NOTE: In this state, the OVSDB connection between SDN controller and Open vSwitch is established. There’s also another connection which is used by Neutron service. You can check this in the output of ovs-vsctl show:
Manager "ptcp:6640:127.0.0.1"
is_connected: true
Manager "ptcp:6640:10.14.0.103"
is_connected: true
… and also in the output of RESTCONF request:
"ovsdb:manager-entry": [
{
"target": "ptcp:6640:127.0.0.1",
"connected": true,
"number_of_connections": 5
},
{
"target": "ptcp:6640:10.14.0.103",
"connected": true,
"number_of_connections": 1
}
]
The only OpenFlow connection(s) in this state are used by Neutron service, you can see it in the output of ovs-vsctl show:
Bridge br-int
Controller "tcp:127.0.0.1:6633"
is_connected: true
Bridge br-ex
Controller "tcp:127.0.0.1:6633"
is_connected: true
... and the same for other bridges
… and also in the output of RESTCONF request:
... all bridges should have:
"ovsdb:controller-entry": [
{
"target": "tcp:127.0.0.1:6633",
"controller-uuid": "de378546-d727-4631-8d46-fa57d78737d9",
"is-connected": true
}
],
Here is an example of complete ovs-vsctl show command output:
The related RESTCONF request:
curl -v --request GET \
--url http://127.0.0.1:8888/restconf/data/network-topology:network-topology/topology=ovsdb%3A1 \
--header 'Authorization: Basic YWRtaW46YWRtaW4=' \
--header 'Accept: application/json' \
| python -m json.tool
The example output of the request can be found here.
4. Retrieve specific node from OVSDB topology data (node-id: “ovsdb://HOST1”)
curl -v --request GET \
--url http://127.0.0.1:8888/restconf/data/network-topology:network-topology/topology=ovsdb%3A1/node=ovsdb%3A%2F%2FHOST1 \
--header 'Authorization: Basic YWRtaW46YWRtaW4=' \
--header 'Accept: application/json' \
| python -m json.tool
Since there’s only one OVSDB topology node in the SDN controller, the output contains the same data as in case of the previous request.
5. Retrieve OVSDB data of specific bridge (br-int):
curl -v --request GET \
--url http://127.0.0.1:8888/restconf/data/network-topology:network-topology/topology=ovsdb%3A1/node=ovsdb%3A%2F%2FHOST1%2Fbridge%2Fbr-int \
--header 'Authorization: Basic YWRtaW46YWRtaW4=' \
--header 'Accept: application/json' \
| python -m json.tool
This request returns only a subset of data related to the bridge br-int.
6. Setup SDN controller as OpenFlow controller for bridge br-int:
curl -v --request PUT \
--url http://localhost:8888/restconf/data/network-topology:network-topology/topology=ovsdb%3A1/node=ovsdb%3A%2F%2FHOST1%2Fbridge%2Fbr-int \
--header 'Authorization: Basic YWRtaW46YWRtaW4=' \
--header 'Content-Type: application/json' \
--data '{
"network-topology:node": [
{
"node-id": "ovsdb://HOST1/bridge/br-int",
"ovsdb:bridge-name": "br-int",
"ovsdb:controller-entry": [
{
"target": "tcp:10.14.0.160:6633"
}
]
}
]
}'
7. Check the state of the connection – retrieve the controller-entry list of br-int:
curl -v --request GET \
--url http://localhost:8888/restconf/data/network-topology:network-topology/topology=ovsdb%3A1/node=ovsdb%3A%2F%2FHOST1%2Fbridge%2Fbr-int/controller-entry=tcp%3A10.14.0.160%3A6633 \
--header 'Authorization: Basic YWRtaW46YWRtaW4=' \
--header 'Accept: application/json' \
| python -m json.tool
The GET request above only retrieves OVSDB data of OpenFlow connection between Open vSwitch and SDN controller. The output only contains one entry (if the OpenFlow connection is established then the item “is-connected” is set to true):
{
"ovsdb:controller-entry": [
{
"controller-uuid": "5bfe55c9-70da-4e3b-b1ff-c6ecc8b6e62c",
"is-connected": true,
"target": "tcp:10.14.0.160:6633"
}
]
}
In the output of ovs-vsctl show command or previous get requests to OVSDB, you will also see a connection between Open vSwitch and Neutron service:
"ovsdb:controller-entry": [
{
"target": "tcp:127.0.0.1:6633",
"controller-uuid": "57b4a453-5ee5-40ea-953a-4132319ad1eb",
"is-connected": true
},
{
"target": "tcp:10.14.0.160:6633",
"controller-uuid": "bc0af587-fc76-44d9-ab24-fe926b1099e6",
"is-connected": true
}
],
8. Retrieve network topology:
curl -v --request GET \
--url http://127.0.0.1:8888/restconf/data/network-topology:network-topology/topology=flow%3A1 \
--header 'Authorization: Basic YWRtaW46YWRtaW4=' \
--header 'Accept: application/json' \
| python -m json.tool
Here’s an example of the output, where you can find a node-id of the Open vSwitch instance. This can be used in subsequent requests.
9. Retrieve data of all nodes (reply includes also OpenFlow flow tables):
curl -v --request GET \
--url http://127.0.0.1:8888/restconf/data/opendaylight-inventory:nodes \
--header 'Authorization: Basic YWRtaW46YWRtaW4=' \
--header 'Accept: application/json' \
| python -m json.tool
Here’s is the output from our example.
10. Retrieve data of a specific node (reply includes also OpenFlow flow tables):
This request uses node-id in the URL. The node-id can be found in reply to requests 8. and 9.
curl -v --request GET \
--url http://127.0.0.1:8888/restconf/data/opendaylight-inventory:nodes/node=openflow%3A143423481343818 \
--header 'Authorization: Basic YWRtaW46YWRtaW4=' \
--header 'Accept: application/json' \
| python -m json.tool
11. Retrieve specific OpenFlow table of specific node:
curl -v --request GET \ --url http://127.0.0.1:8888/restconf/data/opendaylight-inventory:nodes/node=openflow%3A143423481343818/table=0 \ --header 'Authorization: Basic YWRtaW46YWRtaW4=' \ --header 'Accept: application/json' \ | python -m json.tool
12. Delete OpenFlow controller connection from Open vSwitch configuration of bridge br-int:
curl -v --request DELETE \
--url http://localhost:8888/restconf/data/network-topology:network-topology/topology=ovsdb%3A1/node=ovsdb%3A%2F%2FHOST1%2Fbridge%2Fbr-int/controller-entry=tcp%3A10.14.0.160%3A6633 \
--header 'Authorization: Basic YWRtaW46YWRtaW4='
13. Close OVSDB connection to the Open vSwitch instance:
curl -v --request DELETE \ --url http://127.0.0.1:8888/restconf/data/network-topology:network-topology/topology=ovsdb%3A1/node=ovsdb%3A%2F%2FHOST1 \ --header 'Authorization: Basic YWRtaW46YWRtaW4='
OpenFlow manager (OFM)
For this setup, you can also use the OFM application, which provides GUI for management of OpenFlow switches. You can connect OFM to the controller and retrieve OpenFlow tables of a specific switch – plus the flows will be graphically displayed. You can also modify existing flows, or add new using OFM. See our blog about OpenFlow integration.
Conclusion
In this blog, we have described the use of an SDN controller with OVSDB and OpenFlow support. It can be used to manage Open vSwitch virtual switches. We have used Open vSwitch running in an OpenStack environment and we described the sequence of requests needed to connect SDN controller to OVSDB and OpenFlow interfaces of Open vSwitch.
This approach can be used to manage Open vSwitch instances, running in OpenStack Network nodes and Compute nodes without breaking the connection between Neutron service and the Open vSwitch instances. But the SDN controller example and described requests can be used with any virtual or physical network device supporting OpenFlow or OVSDB or both protocols.
The usage of RESTCONF SB plugin in the SDN controller means, that any application can implement RESTCONF (HTTP/REST/API) client and communicate with the controller, as we have demonstrated by Postman application and OpenFlow manager (OFM) in the previous blog.