os_ken.app.rest_vtep

This sample application performs as VTEP for EVPN VXLAN and constructs a Single Subnet per EVI corresponding to the VLAN Based service in [RFC7432].

Note

This app will invoke OVSDB request to the switches. Please set the manager address before calling the API of this app.

$ sudo ovs-vsctl set-manager ptcp:6640
$ sudo ovs-vsctl show
    ...(snip)
    Manager "ptcp:6640"
    ...(snip)

Usage Example

Environment

This example supposes the following environment:

 Host A (172.17.0.1)                      Host B (172.17.0.2)
+--------------------+                   +--------------------+
|   OSKen1           | --- BGP(EVPN) --- |   OSKen2           |
+--------------------+                   +--------------------+
        |                                       |
+--------------------+                   +--------------------+
|   s1 (OVS)         | ===== vxlan ===== |   s2 (OVS)         |
+--------------------+                   +--------------------+
(s1-eth1)    (s1-eth2)                   (s2-eth1)    (s2-eth2)
   |            |                           |            |
+--------+  +--------+                   +--------+  +--------+
| s1h1   |  | s1h2   |                   | s2h1   |  | s2h2   |
+--------+  +--------+                   +--------+  +--------+

Configuration steps

  1. Creates a new BGPSpeaker instance on each host.

    On Host A:

    (Host A)$ curl -X POST -d '{
     "dpid": 1,
     "as_number": 65000,
     "router_id": "172.17.0.1"
     }' http://localhost:8080/vtep/speakers | python -m json.tool
    

    On Host B:

    (Host B)$ curl -X POST -d '{
     "dpid": 1,
     "as_number": 65000,
     "router_id": "172.17.0.2"
     }' http://localhost:8080/vtep/speakers | python -m json.tool
    
  2. Registers the neighbor for the speakers on each host.

    On Host A:

    (Host A)$ curl -X POST -d '{
     "address": "172.17.0.2",
     "remote_as": 65000
     }' http://localhost:8080/vtep/neighbors |
     python -m json.tool
    

    On Host B:

    (Host B)$ curl -X POST -d '{
     "address": "172.17.0.1",
     "remote_as": 65000
     }' http://localhost:8080/vtep/neighbors |
     python -m json.tool
    
  3. Defines a new VXLAN network(VNI=10) on the Host A/B.

    On Host A:

    (Host A)$ curl -X POST -d '{
     "vni": 10
     }' http://localhost:8080/vtep/networks | python -m json.tool
    

    On Host B:

    (Host B)$ curl -X POST -d '{
     "vni": 10
     }' http://localhost:8080/vtep/networks | python -m json.tool
    
  4. Registers the clients to the VXLAN network.

    For "s1h1"(ip="10.0.0.11", mac="aa:bb:cc:00:00:11") on Host A:

    (Host A)$ curl -X POST -d '{
     "port": "s1-eth1",
     "mac": "aa:bb:cc:00:00:11",
     "ip": "10.0.0.11"
     } ' http://localhost:8080/vtep/networks/10/clients |
     python -m json.tool
    

    For "s2h1"(ip="10.0.0.21", mac="aa:bb:cc:00:00:21") on Host B:

    (Host B)$ curl -X POST -d '{
     "port": "s2-eth1",
     "mac": "aa:bb:cc:00:00:21",
     "ip": "10.0.0.21"
     } ' http://localhost:8080/vtep/networks/10/clients |
     python -m json.tool
    

Testing

If BGP (EVPN) connection between OSKen1 and OSKen2 has been established, pings between the client s1h1 and s2h1 should work.

(s1h1)$ ping 10.0.0.21

Troubleshooting

If connectivity between s1h1 and s2h1 isn't working, please check the followings.

  1. Make sure that Host A and Host B have full network connectivity.

    (Host A)$ ping 172.17.0.2
    
  2. Make sure that BGP(EVPN) connection has been established.

    (Host A)$ curl -X GET http://localhost:8080/vtep/neighbors |
     python -m json.tool
    
    ...
    {
        "172.17.0.2": {
            "EvpnNeighbor": {
                "address": "172.17.0.2",
                "remote_as": 65000,
                "state": "up"  # "up" shows the connection established
            }
        }
    }
    
  3. Make sure that BGP(EVPN) routes have been advertised.

    (Host A)$ curl -X GET http://localhost:8080/vtep/networks |
     python -m json.tool
    
     ...
    {
        "10": {
            "EvpnNetwork": {
                "clients": {
                    "aa:bb:cc:00:00:11": {
                        "EvpnClient": {
                            "ip": "10.0.0.11",
                            "mac": "aa:bb:cc:00:00:11",
                            "next_hop": "172.17.0.1",
                            "port": 1
                        }
                    },
                    "aa:bb:cc:00:00:21": {  # route for "s2h1" on Host B
                        "EvpnClient": {
                            "ip": "10.0.0.21",
                            "mac": "aa:bb:cc:00:00:21",
                            "next_hop": "172.17.0.2",
                            "port": 3
                        }
                    }
                },
                "ethernet_tag_id": 0,
                "route_dist": "65000:10",
                "vni": 10
            }
        }
    }
    

4. Make sure that the IPv6 is enabled on your environment. Some OSKen BGP features require the IPv6 connectivity to bind sockets. Mininet seems to disable IPv6 on its installation.

For example:

$ sysctl net.ipv6.conf.all.disable_ipv6
net.ipv6.conf.all.disable_ipv6 = 0  # should NOT be enabled

$ grep GRUB_CMDLINE_LINUX_DEFAULT /etc/default/grub
# please remove "ipv6.disable=1" and reboot
GRUB_CMDLINE_LINUX_DEFAULT="ipv6.disable=1 quiet splash"

5. Make sure that your switch using the OpenFlow version 1.3. This application supports only the OpenFlow version 1.3.

For example:

$ ovs-vsctl get Bridge s1 protocols
["OpenFlow13"]

Note

At the time of this writing, we use the the following version of OSKen, Open vSwitch and Mininet.

$ os_ken --version
os_ken 4.19

$ ovs-vsctl --version
ovs-vsctl (Open vSwitch) 2.5.2  # APT packaged version of Ubuntu 16.04
Compiled Oct 17 2017 16:38:57
DB Schema 7.12.1

$ mn --version
2.2.1  # APT packaged version of Ubuntu 16.04

REST API

class os_ken.app.rest_vtep.RestVtepController(req, link, data, **config)
add_speaker(req, **kwargs)

Creates a new BGPSpeaker instance.

Usage:

Method

URI

POST

/vtep/speakers

Request parameters:

Attribute

Description

dpid

ID of Datapath binding to speaker. (e.g. 1)

as_number

AS number. (e.g. 65000)

router_id

Router ID. (e.g. "172.17.0.1")

Example:

$ curl -X POST -d '{
 "dpid": 1,
 "as_number": 65000,
 "router_id": "172.17.0.1"
 }' http://localhost:8080/vtep/speakers | python -m json.tool
{
    "172.17.0.1": {
        "EvpnSpeaker": {
            "as_number": 65000,
            "dpid": 1,
            "neighbors": {},
            "router_id": "172.17.0.1"
        }
    }
}
get_speakers(_, **kwargs)

Gets the info of BGPSpeaker instance.

Usage:

Method

URI

GET

/vtep/speakers

Example:

$ curl -X GET http://localhost:8080/vtep/speakers |
 python -m json.tool
{
    "172.17.0.1": {
        "EvpnSpeaker": {
            "as_number": 65000,
            "dpid": 1,
            "neighbors": {
                "172.17.0.2": {
                    "EvpnNeighbor": {
                        "address": "172.17.0.2",
                        "remote_as": 65000,
                        "state": "up"
                    }
                }
            },
            "router_id": "172.17.0.1"
        }
    }
}
del_speaker(_, **kwargs)

Shutdowns BGPSpeaker instance.

Usage:

Method

URI

DELETE

/vtep/speakers

Example:

$ curl -X DELETE http://localhost:8080/vtep/speakers |
 python -m json.tool
{
    "172.17.0.1": {
        "EvpnSpeaker": {
            "as_number": 65000,
            "dpid": 1,
            "neighbors": {},
            "router_id": "172.17.0.1"
        }
    }
}
add_neighbor(req, **kwargs)

Registers a new neighbor to the speaker.

Usage:

Method

URI

POST

/vtep/neighbors

Request parameters:

Attribute

Description

address

IP address of neighbor. (e.g. "172.17.0.2")

remote_as

AS number of neighbor. (e.g. 65000)

Example:

$ curl -X POST -d '{
 "address": "172.17.0.2",
 "remote_as": 65000
 }' http://localhost:8080/vtep/neighbors |
 python -m json.tool
{
    "172.17.0.2": {
        "EvpnNeighbor": {
            "address": "172.17.0.2",
            "remote_as": 65000,
            "state": "down"
        }
    }
}
get_neighbors(_, **kwargs)

Gets a list of all neighbors.

Usage:

Method

URI

GET

/vtep/neighbors

Example:

$ curl -X GET http://localhost:8080/vtep/neighbors |
 python -m json.tool
{
    "172.17.0.2": {
        "EvpnNeighbor": {
            "address": "172.17.0.2",
            "remote_as": 65000,
            "state": "up"
        }
    }
}
get_neighbor(_, **kwargs)

Gets the neighbor for the specified address.

Usage:

Method

URI

GET

/vtep/neighbors/{address}

Request parameters:

Attribute

Description

address

IP address of neighbor. (e.g. "172.17.0.2")

Example:

$ curl -X GET http://localhost:8080/vtep/neighbors/172.17.0.2 |
 python -m json.tool
{
    "172.17.0.2": {
        "EvpnNeighbor": {
            "address": "172.17.0.2",
            "remote_as": 65000,
            "state": "up"
        }
    }
}
del_neighbor(_, **kwargs)

Unregister the specified neighbor from the speaker.

Usage:

Method

URI

DELETE

/vtep/speaker/neighbors/{address}

Request parameters:

Attribute

Description

address

IP address of neighbor. (e.g. "172.17.0.2")

Example:

$ curl -X DELETE http://localhost:8080/vtep/speaker/neighbors/172.17.0.2 |
 python -m json.tool
{
    "172.17.0.2": {
        "EvpnNeighbor": {
            "address": "172.17.0.2",
            "remote_as": 65000,
            "state": "up"
        }
    }
}
add_network(req, **kwargs)

Defines a new network.

Usage:

Method

URI

POST

/vtep/networks

Request parameters:

Attribute

Description

vni

Virtual Network Identifier. (e.g. 10)

Example:

$ curl -X POST -d '{
 "vni": 10
 }' http://localhost:8080/vtep/networks | python -m json.tool
{
    "10": {
        "EvpnNetwork": {
            "clients": {},
            "ethernet_tag_id": 0,
            "route_dist": "65000:10",
            "vni": 10
        }
    }
}
get_networks(_, **kwargs)

Gets a list of all networks.

Usage:

Method

URI

GET

/vtep/networks

Example:

$ curl -X GET http://localhost:8080/vtep/networks |
 python -m json.tool
{
    "10": {
        "EvpnNetwork": {
            "clients": {
                "aa:bb:cc:dd:ee:ff": {
                    "EvpnClient": {
                        "ip": "10.0.0.1",
                        "mac": "aa:bb:cc:dd:ee:ff",
                        "next_hop": "172.17.0.1",
                        "port": 1
                    }
                }
            },
            "ethernet_tag_id": 0,
            "route_dist": "65000:10",
            "vni": 10
        }
    }
}
get_network(_, **kwargs)

Gets the network for the specified VNI.

Usage:

Method

URI

GET

/vtep/networks/{vni}

Request parameters:

Attribute

Description

vni

Virtual Network Identifier. (e.g. 10)

Example:

$ curl -X GET http://localhost:8080/vtep/networks/10 |
 python -m json.tool
{
    "10": {
        "EvpnNetwork": {
            "clients": {
                "aa:bb:cc:dd:ee:ff": {
                    "EvpnClient": {
                        "ip": "10.0.0.1",
                        "mac": "aa:bb:cc:dd:ee:ff",
                        "next_hop": "172.17.0.1",
                        "port": 1
                    }
                }
            },
            "ethernet_tag_id": 0,
            "route_dist": "65000:10",
            "vni": 10
        }
    }
}
del_network(_, **kwargs)

Deletes the network for the specified VNI.

Usage:

Method

URI

DELETE

/vtep/networks/{vni}

Request parameters:

Attribute

Description

vni

Virtual Network Identifier. (e.g. 10)

Example:

$ curl -X DELETE http://localhost:8080/vtep/networks/10 |
 python -m json.tool
{
    "10": {
        "EvpnNetwork": {
            "ethernet_tag_id": 10,
            "clients": [
                {
                    "EvpnClient": {
                        "ip": "10.0.0.11",
                        "mac": "e2:b1:0c:ba:42:ed",
                        "port": 1
                    }
                }
            ],
            "route_dist": "65000:100",
            "vni": 10
        }
    }
}
add_client(req, **kwargs)

Registers a new client to the specified network.

Usage:

Method

URI

POST

/vtep/networks/{vni}/clients

Request parameters:

Attribute

Description

vni

Virtual Network Identifier. (e.g. 10)

port

Port number to connect client. For convenience, port name can be specified and automatically translated to port number. (e.g. "s1-eth1" or 1)

mac

Client MAC address to register. (e.g. "aa:bb:cc:dd:ee:ff")

ip

Client IP address. (e.g. "10.0.0.1")

Example:

$ curl -X POST -d '{
 "port": "s1-eth1",
 "mac": "aa:bb:cc:dd:ee:ff",
 "ip": "10.0.0.1"
 }' http://localhost:8080/vtep/networks/10/clients |
 python -m json.tool
{
    "10": {
        "EvpnClient": {
            "ip": "10.0.0.1",
            "mac": "aa:bb:cc:dd:ee:ff",
            "next_hop": "172.17.0.1",
            "port": 1
        }
    }
}
del_client(_, **kwargs)

Registers a new client to the specified network.

Usage:

Method

URI

DELETE

/vtep/networks/{vni}/clients/{mac}

Request parameters:

Attribute

Description

vni

Virtual Network Identifier. (e.g. 10)

mac

Client MAC address to register.

Example:

$ curl -X DELETE http://localhost:8080/vtep/networks/10/clients/aa:bb:cc:dd:ee:ff |
 python -m json.tool
{
    "10": {
        "EvpnClient": {
            "ip": "10.0.0.1",
            "mac": "aa:bb:cc:dd:ee:ff",
            "next_hop": "172.17.0.1",
            "port": 1
        }
    }
}