ryu.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)
+--------------------+                   +--------------------+
|   Ryu1             | --- BGP(EVPN) --- |   Ryu2             |
+--------------------+                   +--------------------+
        |                                       |
+--------------------+                   +--------------------+
|   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 Ryu1 and Ryu2 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
            }
        }
    }
    

REST API

class ryu.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
        }
    }
}