Table of Contents

Support Neutron BGPVPN API on OpenDaylight L3VPN service

https://git.opendaylight.org/gerrit/#/q/topic:neutron-bgpvpn-api-support

Enhance current L3VPN service to realize VPNs consistently when VPNs are managed through the Openstack Neutron BGPVPN Plugin.

Problem description

As the current L3VPN service stands end-of-Oxygen release, it is able to realize a VPN orchestrated by Neutron BGPVPN API.

However, this orchestration is subjected heavily to timing and nature of how the orchestration was performed.

To explain, piecemeal creating a Neutron BGPVPN using Openstack BGPVPN REST API (or) CLI and making sure it is realized and then deleting the same Neutron BGPVPN (via RESTAPI or CLI) would succeed.

However, when the orchestration pattern on Openstack BGPVPN API is turned to be driven through an automation script (or) if the script uses Heat templates to automate and manage BGPVPNs, the runs will expose failure to properly realize such orchestrated VPNs in the OpenDaylight control plane (and thence data plane too).

The failures themselves will go unnoticed to the Openstack Orchestrator (or user) since the Openstack Neutron will provide a consistent view of available (or active) VPNs while the VPNs being realized in OpenDaylight would be either less than the active VPNs (or) might sometimes even be more (due to stale VPNs not cleaned up).

In scope

The following types of VPNs are scoped into this effort: a. Network-associated L3 BGPVPNs Networks can have either IPv4 (or) IPv6 (or) both IPv4 and IPv6 subnets in them. b. Router-associated L3 BGPVPNs Router can have either IPv4 (or) IPv6 (or) both IPv4 and IPv6 subnets attached to them. c. Plain Neutron Router (Internal VPN) Router can have either IPv4 (or) IPv6 (or) both IPv4 and IPv6 subnets attached to them. d. Plain External Network (Internal VPN) External network used as a VPN to provide external connectivity over FLAT / VLAN mechanisms. e. ExternalNetwork-associated L3 BGPVPNs L3BGPVPN representing connectivity to external networks via MPLSOverGRE tunnels.

Out of scope

  1. Network-associated EVPNs

  2. Router-associated EVPNs

Use Case Summary

This deals with making BGPVPN workflows inside ODL more robust when used with Neutron BGPVPN APIs. To add, when such Neutron BGPVPN APIs are applied through HOT templates, the VPNs have to be realized consistently in both the control-plane datastores and data-plane flows/routes.

RIB - Routing Information Base - Represents the routes held inside the ODL controller Quagga BGP. FIB - Forwarding Information Base - Represents the routes held inside ODL controller.

For all the router-driven BGPVPNs below, please assume that two subnets (one IPv4 and one IPv6) are associated to the router. For all the network-driven BGPVPNs below, please assume that only a single IPv4 subnet is present on the network.

For the template types and their contents, please see CSIT section.

UC 1: A net-driven BGPVPN creation with Network association

The steps for this use-case (single HOT template) template 1 - Create a VPN1 with RD1 Create Network1, Create Subnet1, Boot VMs on the Network1, Associate Network1 into VPN1

template 1 type - TYPE A

Create stack with template 1, make sure that VPN1 appears in the ODL controller. Also make sure all of the VM IPs (and their secondaries) must be realized into VPN1. Delete stack with template 1, make sure VPN1 disappears from the ODL controller.

UC 2: A net-driven BGPVPN cycled through multiple Networks association

The steps for this use-case (multiple HOT templates) template 1 - Create a VPN1 with RD1 template 2 - Create Network1, Create Subnet1, Boot VMs on the Network1, Associate Network1 into VPN1 template 3 - Create Network2, Create Subnet2, Boot VMs on the Network2, Associate Network2 into VPN1

template 1 type - TYPE B template 2 type - TYPE C template 3 type - TYPE C

Create stack with template 1, make sure VPN1 appears in the ODL controller.

Create stack with template 2 and template 3 concurrently. Make sure all of the VM IPs (and their secondaries) on Network1 and Network2 (and their secondaries) must be realized into VPN1.

Delete stack with template 2, template 3 concurrently. Make sure all of the VM IPs (and their secondaries) on Network1 and Network2 must be removed from VPN1.

Delete stack with template 1, VPN1 must disappear from the ODL controller.

association and disassociation (no overlapping cidrs on networks)

The steps for this use-case (multiple HOT templates) template 1 - Create a VPN1 with RD1 template 2 - Create Network1, Create Subnet1, Boot VMs on the Network1, Associate Network1 into VPN1 template 3 - Create Network2, Create Subnet2, Boot VMs on the Network2, Associate Network2 into VPN1

template 1 type - TYPE B template 2 type - TYPE C template 3 type - TYPE C

Create stack with template 1, make sure VPN1 appears in the ODL controller. Create stack with template 2, all of the VM IPs (and their secondaries) on Network1 must be realized into VPN1.

Delete stack with template 2 and concurrently create stack with template 3. All of the VM IPs (and their secondaries) on Network1 must be removed from VPN1. All of the VM IPs (and their secondaries) on Network2 must be realized into VPN1.

Delete stack with template 3, make sure that Network2 must be removed from VPN1. Delete stack with template 1, VPN1 must disappear from the ODL controller.

association and disassociation (overlapping cidrs on networks)

The steps for this use-case (multiple HOT templates) template 1 - Create a VPN1 with RD1 template 2 - Create Network1, Create Subnet1, Boot VMs on the Network1, Associate Network1 into VPN1 template 3 - Create Network2, Create Subnet2 (same CIDR as Subnet1), Boot VMs on the Network2, Associate Network2 into VPN1

template 1 type - TYPE B template 2 type - TYPE C template 3 type - TYPE C

Create stack with template 1, make sure VPN1 appears in the ODL controller. Create stack with template 2, all of the VM IPs (and their secondaries) on Network1 must be realized into VPN1.

Delete stack with template 2 All of the VM IPs (and their secondaries) on Network1 must be removed from VPN1.

Create stack with template 3 All of the VM IPs (and their secondaries) on Network2 must be realized into VPN1.

Delete stack with template 3, make sure that Network2 must be removed from VPN1. Delete stack with template 1, VPN1 must disappear from the ODL controller.

UC 2.5: Two net-driven BGPVPNs cycled through with same RouteDistinguisher and same Network

template 1 - Create Network1, Create Subnet1, Boot VMs on the Network1 template 2 - Create a VPN1 with RD1 and associate Network1 to VPN1 template 3 - Create a VPN2 with RD1 and associate Network1 to VPN2

template 1 type - TYPE D template 2 type - TYPE E template 3 type - TYPE E

Create stack with template 1, make sure all the VMs appears in the ODL controller. Create stack with template 2, all of the VM IPs (and their secondaries) on Network1 must be realized into VPN1.

Delete stack with template 2 and concurrently create stack with template 3. All of the VM IPs (and their secondaries) on Network1 must be removed from VPN1. All of the VM IPs (and their secondaries) on Network1 must be realized into VPN2.

Delete stack with template 3, make sure that Network1 must be removed from VPN2. Delete stack with template 1, make sure all the VMs disappear from the ODL controller.

UC 2.6: A net-driven BGPVPN ordering VPN deletion before network deletion

template 1 - Create a VPN1 with RD1 template 2 - Create Network1, Create Subnet1, Boot VMs on the Network1, Associate Network1 into VPN1

template 1 type - TYPE B template 2 type - TYPE C

Create stack with template 1, make sure VPN1 appears in the ODL controller. Create stack with template 2, all of the VM IPs (and their secondaries) on Network1 must be realized into VPN1.

Delete stack with template 1 All of the VM IPs (and their secondaries) on Network1 must be removed from VPN1. Make sure ELAN traffic continues to work.

Delete stack with template 2 Make sure all the VMs, Networks disappear from the ODL controller.

UC 2.7: A net-driven BGPVPN ordering network deletion before VPN deletion without disassociating the network

The steps for this use-case (multiple HOT templates) template 1 - Create a VPN1 with RD1 template 2 - Create Network1, Create IPv4 Subnet1, Boot VMs on the Network1 template 3 - Associate Network1 into VPN1

template 1 type - TYPE B template 2 type - TYPE D template 3 type - TYPE F

Create stack with template 1, make sure VPN1 appears in the ODL controller. Create stack with template 2, ensure all of the VM IPs (and their secondaries) on Router1 must be realized into VPN1. Create stack with template 3, and ensure all of the VM IPs (and their secondaries) on Router1 must be realized into VPN1.

Delete stack with template 2, make sure that Network1 must be removed from VPN1. Also make sure all of the VMs (and their secondaries) along with Network1 are not hanging around at all.

Delete stack with template 1, VPN1 must disappear from the ODL controller. Delete stack with template 3, the stack deletion must fail and this is normal.

UC 2.8: A router-driven BGPVPN creation with SingleStack Router association

The steps for this use-case (single HOT template) template 1 - Create a VPN1 with RD1. Create Network1, Create Subnet1, Boot VMs on the Network1, Create Router1, Add Subnet1 to Router1 and Associate Router1 into VPN1

template 1 type - TYPE M

Create stack with template 1, make sure that VPN1 appears in the ODL controller. Also make sure all of the VM IPs (and their secondaries) on the Router1 must be realized into VPN1. Delete stack with template 1, make sure VPN1 disappears from the ODL controller along with removal of VM IPs from the VPN1.

UC 2.9: A router-driven BGPVPN creation with DualStack Router association

The steps for this use-case (single HOT template) template 1 - Create a VPN1 with RD1. Create Network1, Create IPv4 Subnet11, Create IPv6 Subnet12 Create Network2, Create IPv4 Subnet21, Create IPv6 Subnet22, Boot VMs on the Network1 Boot VMs on the Network2, Create Router1, Add Subnet11 to Router1, Add Subnet12 to Router1, Add Subnet21 to Router1, Add Subnet22 to Router1 and Associate Router1 into VPN1

template 1 type - TYPE N

Create stack with template 1, make sure that VPN1 appears in the ODL controller. Also make sure all of the VM IPv4 and IPv6s (and their secondaries) on the Router1 must be realized into VPN1. Delete stack with template 1, make sure VPN1 disappears from the ODL controller.

UC 2.10: A router-driven BGPVPN cycled through with association and disassociation

The steps for this use-case (multiple HOT templates) template 1 - Create a VPN1 with RD1 template 2 - Create Network1, Create IPv4 Subnet1, Create IPv6 Subnet2, Boot VMs on the Network1 Create Router1, Add Subnet1 to Router1, Add Subnet2 to Router1 template 3 - Associate Router1 into VPN1

template 1 type - TYPE B template 2 type - TYPE O template 3 type - TYPE Q

Create stack with template 1, make sure VPN1 appears in the ODL controller. Create stack with template 2, all of the VM IPs (and their secondaries) on Network1 must be realized into Router1.

Create stack with template 3, and ensure all of the VM IPs (and their secondaries) on Router1 must be realized into VPN1.

Delete stack with template 3, make sure that Router1 must be removed from VPN1. Immediately create stack with template 3, make sure that Router1 is included back into VPN1. Also make sure all of the VM IPv4 and IPv6s (and their secondaries) on the Router1 must be realized into VPN1.

Delete stack with template 3, Router1 must disappear from VPN1. Delete stack with template 2, Router1 must disappear from the ODL controller. Delete stack with template 1, VPN1 must disappear from the ODL controller.

UC 2.10 variation 2 - A router-driven BGPVPN cycled through with association and disassociation

The steps for this use-case (multiple HOT templates) template 1 - Create a VPN1 with RD1. template 2 - Create Network1, Create IPv4 Subnet1, Create IPv6 Subnet2, Boot VMs on the Network1. Create Router1, Add Subnet1 to Router1, Add Subnet2 to Router1 template 3 - Associate Router1 into VPN1

template 1 type - TYPE B template 2 type - TYPE O template 3 type - TYPE Q

Create stack with template 1, make sure VPN1 appears in the ODL controller. Create stack with template 2, all of the VM IPs (and their secondaries) on Network1 must be realized into Router1.

Create stack with template 3, and ensure all of the VM IPs (and their secondaries) on Router1 must be realized into VPN1.

Delete stack with template 3, make sure that Router1 must be removed from VPN1. Immediately delete stack with template 2, make sure that Router1 disappears from ODL controller.

Delete stack with template 1, VPN1 must disappear from the ODL controller.

UC 2.11: A router-driven BGPVPN ordering router deletion before VPN deletion

The steps for this use-case (multiple HOT templates) template 1 - Create a VPN1 with RD1 template 2 - Create Network1, Create IPv4 Subnet1, Create IPv6 Subnet2, Boot VMs on the Network1 Create Router1, Add Subnet1 to Router1, Add Subnet2 to Router1, Associate Router1 into VPN1

template 1 type - TYPE B template 2 type - TYPE P

Create stack with template 1, make sure VPN1 appears in the ODL controller. Create stack with template 2, ensure all of the VM IPs (and their secondaries) on Router1 must be realized into VPN1.

Delete stack with template 2, make sure that Router2 must be removed from VPN1. Also make sure all of the VM IPv4 and IPv6s (and their secondaries) along with Router1 are not hanging around at all.

Delete stack with template 1, VPN1 must disappear from the ODL controller.

before VPN deletion without disassociating the router

The steps for this use-case (multiple HOT templates) template 1 - Create a VPN1 with RD1 template 2 - Create Network1, Create IPv4 Subnet1, Create IPv6 Subnet2, Boot VMs on the Network1 Create Router1, Add Subnet1 to Router1, Add Subnet2 to Router1 template 3 - Associate Router1 into VPN1

template 1 type - TYPE B template 2 type - TYPE O template 3 type - TYPE Q

Create stack with template 1, make sure VPN1 appears in the ODL controller. Create stack with template 2, ensure all of the VM IPs (and their secondaries) on Router1 must be realized into VPN1. Create stack with template 3, and ensure all of the VM IPs (and their secondaries) on Router1 must be realized into VPN1.

Delete stack with template 2, make sure that Router2 must be removed from VPN1. Also make sure all of the VM IPv4 and IPv6s (and their secondaries) along with Router1 are not hanging around at all.

Delete stack with template 1, VPN1 must disappear from the ODL controller. Delete stack with template 3, the stack deletion must fail and this is normal.

UC 2.12: A router-driven BGPVPN ordering VPN deletion before router deletion

template 1 - Create a VPN1 with RD1 template 2 - Create Network1, Create IPv4 Subnet1, Create IPv6 Subnet2, Boot VMs on the Network1 Create Router1, Add Subnet1 to Router1, Add Subnet2 to Router1, Associate Router1 to VPN1

template 1 type - TYPE B template 2 type - TYPE P

Create stack with template 1, make sure VPN1 appears in the ODL controller. Create stack with template 2, all of the VM IPs (and their secondaries) on Network1 must be realized into VPN1.

Delete stack with template 1 All of the VM IPs (and their secondaries) on Router1 must be removed from VPN1. Make sure ELAN traffic and Router1 traffic continues to work.

Delete stack with template 2 Make sure all the VMs, Routers disappear from the ODL controller.

UC 2.13: Two router-driven BGPVPNs cycled through with same RouteDistinguisher and same Router

template 1 - Create Network1, Create IPv4 Subnet1, Create IPv6 Subnet2, Boot VMs on the Network1 Create Router1, Add Subnet1 to Router1, Add Subnet2 to Router1 template 2 - Create a VPN1 with RD1 and Associate Router1 into VPN1 template 3 - Create a VPN2 with RD1 and Associate Router1 into VPN2

template 1 type - TYPE O template 2 type - TYPE R template 3 type - TYPE R

Create stack with template 1, make sure all the VMs appears in the ODL controller. Create stack with template 2, all of the VM IPs (and their secondaries) on Router1 must be realized into VPN1.

Delete stack with template 2. Immediately create a stack with template 3. All of the VM IPs (and their secondaries) on Router1 must be removed from VPN1. All of the VM IPs (and their secondaries) on Router1 must be realized into VPN2.

Delete stack with template 3, make sure that Router1 must be removed from VPN2. Delete stack with template 1, make sure all the VMs disappear from the ODL controller.

Proposed change

In order to tighten the L3VPN service to make it consistently realize the Openstack Neutron BGPVPN orchestrated VPNs (and the networks/routers in them) in OpenDaylight controller, we need to address gaps in various components of NetVirt.

The following components will be enhanced to ensure a consistent and scaled-out realization of BGPVPNs onto OpenDaylight NetVirt: a. NeutronVPN (NeutronVpnManager) b. VPN Engine (VpnInstanceListener and VpnInterfaceManager) c. BGP Engine (BGPManager) d. VRF Engine (FIBManager) e. NAT Engine (NATService) f. EVPN Engine (EVPN in ELANManager)

All of the above engines enhancement is to enable safe parallel processing of multiple vpn-instances regardless of whether such vpninstances use the same route-distinguisher, same ip-address, same interfaces etc.

Module Changes

VPN Engine:

Currently Oper/VpnInstanceOpData is keyed by vrf-id (aka Route Distinguisher) and this kind of keying was all OK as we serviced only one VPNInstance at a time that would carry this vrf-id.

As we move to public cloud, the customers will start to use the neutron bgpvpn api (in lieu of ODL provided RESTful APIs). With the Neutron BGPVPN API interface, it is very possible to have multiple VPNInstance could be managed by tenants where in such instances carry the same vrf-id (aka Route Distinguisher). This is because route-distinguisher is not how an VPN is identified in Neutron BGPVPN, instead the vpn-uuid allocated by Neutron uniquely identifies a VPN.

However, L3VPN Service in ODL is using the route-distinguisher as the key for realizing a vpn (i.e, VpnInstanceOpData) and so the key for this yang will be changed to use the vpn-instance-uuid instead of route-distinguisher.

This specific VpnInstanceOpData datastore is referred by many services within ODL and so such services must be updated on their consumption/production of information into this datastore.

One more new model that maps a given RD (route-distinguisher) to an Active VpnInstance will be required for use by the BGPEngine.

VRF Engine:

The VRFEngine does not use vpn-instance-uuid at all and uses only vrfTables as the primary datastore for representing the FIB. This vrfTables has vrf-id (route-distinguisher) as the key, to maintain the FIB.

This engine will be enhanced such that vrfTables become a child to a vpn-instance-uuid keyed container thereby enabling multiple vpninstances to be managed regardless of whether such vpn-instances use the same RD or otherwise.

So the VrfEntry will be keyed by (VPNInstance + RD + Prefix) instead of being keyed only with (RD + prefix) as it stands today.

All BGP Advertisements and Withdrawals (for all routes managed by ODL itself - i.e., non-BGP-imported routes), will be done within the VRFEngine (i.e, VrfEntryListener) rather than by the VPN Engine. All such advertisements will be serialized within the VrfEntryListener so that route consistency is maintained between ODL and its BGP neighbor.

BGP Engine:

The BGP Engine within ODL is primarily responsible for: a. Pushing a route from its external neighbor into ODL b. Removing a route from its external neighbor from ODL c. Advertising an ODL managed route to its external neighbor d. Withdrawing an ODL managed route to its external neighbor

Since there can be more than one VpnInstance that can use a given route-distinguisher at a time within Opendaylight (a situation where previous vpn-instance is being deleted while a new vpn-instance with same RD being created), BGP Engine needs to know which of the vpn-instances out of the these to choose to import a route when it comes from an external neighbor (case a).

This is because, BGP Engine (and Quagga which has real BGP logic) within ODL operates only with route-distinguishers and not with vpn-instances. This is the same case with the other BGP neighbors too that talk to ODL BGP Engine.

As a result the BGP Engine will continue to work only with route-distinguishers but it will make a call to the VpnEngine to figure out to which all vpn-instances an incoming route must be written to (case a). The same principle applies when an external bgp route is to be removed from within OpenDaylight (case b).

Advertising (or) Withdrawing an ODL managed route will be driven by the VRFEngine towards the BGPEngine i.e, case c and case d. The BGPEngine will have no role to play here.

NeutronVPN Engine:

There are race conditions within the NeutronVPN that gets triggered when HOT templates are executed primarily in the Neutron BGPVPN management path. These race conditions are around the Neutron Router, Neutron BGPVPN, Neutron Subnet and Neutron Network resources access and their management within NeutronVPN. So this engine will be enhanced to close out these race-conditions.

Pipeline changes

This initiative does not introduce (or) mandate any pipeline changes.

Yang changes

Changes will be needed in fib-rpc.yang , odl-fib.yang to address this feature.

Changes will be needed in odl-l3vpn.yang and odl-fib.yang to support the robustness for Neutron BGPVPN API.

FIB-RPC YANG CHANGES

fib-rpc.yang
 rpc populate-fib-on-dpn {
     description "Populates FIB table in specified DPN";
     input {
         leaf dpid {
             type uint64;
         }
         leaf vpn-id {
             type uint32;
         }
 +       leaf vpn-instance-name {
 +           type string;
 +       }
         leaf rd {
             type string;
         }
     }
 }

 rpc cleanup-dpn-for-vpn {
     description "Removes the VPN Fib entries in a given DPN";
     input {
         leaf dpid {
             type uint64;
         }
         leaf vpn-id {
             type uint32;
         }
 +       leaf vpn-instance-name {
 +           type string;
 +       }
         leaf rd {
             type string;
         }

     }
 }

ODL-FIB YANG CHANGES

odl-fib.yang
 --- a/fibmanager/api/src/main/yang/odl-fib.yang
 +++ b/fibmanager/api/src/main/yang/odl-fib.yang
 @@ -100,15 +100,19 @@ module odl-fib {

  container fibEntries {
      config true;
 -        list vrfTables{
 -            key "routeDistinguisher";
 -            leaf routeDistinguisher {type string;}
 -            uses vrfEntries;
 -            uses macVrfEntries;
 -        }
 +        list vpnInstanceNames {
 +            key vpnInstanceName;
 +            leaf vpnInstanceName { type string; }
 +            list vrfTables{
 +                key "routeDistinguisher";
 +                leaf routeDistinguisher {type string;}
 +                uses vrfEntries;
 +                uses macVrfEntries;
 +            }

 -        container ipv4Table{
 -            uses ipv4Entries;
 +            container ipv4Table{
 +                uses ipv4Entries;
 +            }
      }
  }

ODL-L3VPN YANG CHANGES

odl-l3vpn.yang
--- a/vpnmanager/api/src/main/yang/odl-l3vpn.yang
+++ b/vpnmanager/api/src/main/yang/odl-l3vpn.yang
@@ -184,10 +184,13 @@ module odl-l3vpn {
             }
      }

 -    container evpn-rd-to-networks {
 +    container evpn-to-networks {
          description "Holds the networks to which given evpn is attached";
 -        list evpn-rd-to-network {
 +        list evpn-to-network {
 -           key rd;
 +           key vpn-instance-name;
 +           leaf vpn-instance-name {
 +             type string;
 +           }
             leaf rd {
               type string;
             }
 @@ -261,7 +264,7 @@ module odl-l3vpn {
      container vpn-instance-op-data {
          config false;
          list vpn-instance-op-data-entry {
 -           key vrf-id;
 +           key vpn-instance-name;
             leaf vpn-id { type uint32;}
             leaf vrf-id {
               description

 @@ +706,7 +717,7 @@ module odl-l3vpn {
 + container rd-to-vpns {
 +    config false;
 +    list rd-to-vpn {
 +        key "rd";
 +        leaf rd { type string; }
 +        list vpn-instances {
 +            key "vpn-instance-name";
 +            leaf vpn-instance-name { type string; }
 +            leaf active { type boolean; }
 +        }
 +    }
 +}

Clustering considerations

The feature should operate in ODL Clustered (3-node cluster) environment reliably.

Scale and Performance Impact

Not covered by this Design Document.

Targeted Release

Fluorine.

Alternatives

There were no alternative proposals considered for this initiative.

Usage

The feature can be excited by Openstack Neutron BGPVPN REST APIs (or) by Openstack Neutron BGPVPN CLIs.

As part of this spec implementation, we will actually be exciting Neutron BGPVPN APIs via the Heat Templates. Please see more details of the templates and the types of templates we will use in the CSIT section.

Features to Install

This feature can be used by installing odl-netvirt-openstack. This feature doesn’t add any new karaf feature.

REST API

No REST APIs are introduced in this feature.

Implementation

Assignee(s)

Primary assignee:

Vivekanandan Narasimhan (n.vivekanandan@ericsson.com)

Work Items

The Trello cards have already been raised for this feature under the neutron-bgpvpn-api-support.

#Here is the link for the Trello Card: #https://trello.com/c/Tfpr3ezF/33-evpn-evpn-rt5

Testing

Unit Tests

Appropriate UTs will be added for the new code coming in once framework is in place.

Integration Tests

There won’t be any Integration tests provided for this feature.

CSIT

A New CSIT suite will be added for this feature, as this starts to use Neutron BGPVPN APIs in couple with HOT templates and makes it official for ODL platform.

CSIT will use the HOT Templates referred here.

TYPE A

TYPE A
description: BGPVPN networking example TYPE A (admin)
heat_template_version: '2013-05-23'

resources:

    BGPVPN1:
        type: OS::Neutron::BGPVPN
        properties:
            import_targets: [ "100:1001"]
            export_targets: [ "100:1002"]
            route_targets: [ "100:1000" ]
            name: "default VPN"

    Net1:
        type: OS::Neutron::Net
        properties:
            name: "default Net1"

    SubNet1:
        type: OS::Neutron::Subnet
        properties:
            network: { get_resource: Net1 }
            cidr: 20.1.1.0/24

    BGPVPN_NET_assoc1:
        type: OS::Neutron::BGPVPN-NET-ASSOCIATION
        properties:
            bgpvpn_id: { get_resource: BGPVPN1 }
            network_id: { get_resource: Net1 }

TYPE B

TYPE B
description: BGPVPN networking example TYPE B (admin)
heat_template_version: '2013-05-23'

resources:

    BGPVPN1:
        type: OS::Neutron::BGPVPN
        properties:
            import_targets: [ "100:1001"]
            export_targets: [ "100:1002"]
            route_targets: [ "100:1000" ]
            name: "default VPN"

TYPE C

TYPE C
description: BGPVPN networking example TYPE C (admin)
heat_template_version: '2013-05-23'

resources:

    Net1:
    type: OS::Neutron::Net
    properties:
        name: "default Net1"

    SubNet1:
        type: OS::Neutron::Subnet
        properties:
            network: { get_resource: Net1 }
            cidr: 20.1.1.0/24

    BGPVPN_NET_assoc1:
        type: OS::Neutron::BGPVPN-NET-ASSOCIATION
        properties:
            bgpvpn_id: "default VPN"
            network_id: { get_resource: Net1 }

TYPE D

TYPE D
description: BGPVPN networking example TYPE D (admin)
heat_template_version: '2013-05-23'

resources:

    Net1:
        type: OS::Neutron::Net
        properties:
            name: "default Net1"

    SubNet1:
    type: OS::Neutron::Subnet
    properties:
        network: { get_resource: Net1 }
        cidr: 20.1.1.0/24

TYPE E

TYPE E
description: BGPVPN networking example (admin)
heat_template_version: '2013-05-23'

resources:

BGPVPN1:
    type: OS::Neutron::BGPVPN
    properties:
        import_targets: [ "100:1001"]
        export_targets: [ "100:1002"]
        route_targets: [ "100:1000" ]
        name: "default VPN"

BGPVPN_NET_assoc1:
    type: OS::Neutron::BGPVPN-NET-ASSOCIATION
    properties:
        bgpvpn_id: "default VPN"
        network_id: "default Net1"

TYPE F

TYPE F
description: BGPVPN networking example (admin)
heat_template_version: '2013-05-23'

resources:

    BGPVPN_NET_assoc1:
        type: OS::Neutron::BGPVPN-NET-ASSOCIATION
        properties:
            bgpvpn_id: "default VPN"
            network_id: "default Net1"

TYPE M

TYPE M
description: BGPVPN networking example (admin)
heat_template_version: '2013-05-23'

resources:

    BGPVPN1:
        type: OS::Neutron::BGPVPN
        properties:
            import_targets: [ "100:1001"]
            export_targets: [ "100:1002"]
            route_targets: [ "100:1000" ]
            name: "default VPN"


    Net1:
        type: OS::Neutron::Net
        properties:
            name: "default Net1"

 SubNet1:
     type: OS::Neutron::Subnet
     properties:
        network: { get_resource: Net1 }
        cidr: 20.1.10.0/24

 Router:
     type: OS::Neutron::Router
     properties:
         name: "default Router"


 router_interface:
     type: OS::Neutron::RouterInterface
     properties:
        router_id: { get_resource: Router }
        subnet_id: { get_resource: SubNet1 }

 BGPVPN_router_assoc1:
     type: OS::Neutron::BGPVPN-ROUTER-ASSOCIATION
     properties:
         bgpvpn_id: { get_resource: BGPVPN1 }
         router_id: { get_resource: Router }

TYPE N

TYPE M
description: BGPVPN networking example (admin)
heat_template_version: '2013-05-23'

resources:

    BGPVPN1:
    type: OS::Neutron::BGPVPN
    properties:
        import_targets: [ "100:1001"]
        export_targets: [ "100:1002"]
        route_targets: [ "100:1000" ]
        name: "default VPN"

    Net1:
        type: OS::Neutron::Net
        properties:
            name: "default Net1"

    SubNet11:
        type: OS::Neutron::Subnet
        properties:
            network: { get_resource: Net1 }
            cidr: 20.1.1.0/24

    SubNet12:
        type: OS::Neutron::Subnet
        properties:
            network: { get_resource: Net1 }
            cidr: 2001:db8:cafe:1e::/64

    Net2:
        type: OS::Neutron::Net
        properties:
            name: "default Net2"

    SubNet21:
        type: OS::Neutron::Subnet
        properties:
            network: { get_resource: Net2 }
            cidr: 30.1.1.0/24

    SubNet22:
        type: OS::Neutron::Subnet
        properties:
            network: { get_resource: Net2 }
            cidr: 2002:db8:cafe:1e::/64

    Router:
        type: OS::Neutron::Router
        properties:
            name: "default Router"

    router_interface1:
        type: OS::Neutron::RouterInterface
        properties:
            router_id: { get_resource: Router }
            subnet_id: { get_resource: SubNet11 }

    router_interface2:
        type: OS::Neutron::RouterInterface
        properties:
            router_id: { get_resource: Router }
            subnet_id: { get_resource: SubNet12 }

    router_interface3:
        type: OS::Neutron::RouterInterface
        properties:
            router_id: { get_resource: Router }
            subnet_id: { get_resource: SubNet21 }

    router_interface4:
        type: OS::Neutron::RouterInterface
        properties:
            router_id: { get_resource: Router }
            subnet_id: { get_resource: SubNet22 }

    BGPVPN_router_assoc1:
        type: OS::Neutron::BGPVPN-ROUTER-ASSOCIATION
        properties:
             bgpvpn_id: { get_resource: BGPVPN1 }
             router_id: { get_resource: Router }

TYPE O

TYPE 0
description: BGPVPN networking example (admin)
heat_template_version: '2013-05-23'

resources:

    BGPVPN1:
        type: OS::Neutron::BGPVPN
        properties:
            import_targets: [ "100:1001"]
            export_targets: [ "100:1002"]
            route_targets: [ "100:1000" ]
            name: "default VPN"

    Net1:
        type: OS::Neutron::Net
        properties:
            name: "default Net1"

    SubNet11:
        type: OS::Neutron::Subnet
        properties:
            network: { get_resource: Net1 }
            cidr: 20.1.1.0/24

    SubNet12:
        type: OS::Neutron::Subnet
        properties:
           network: { get_resource: Net1 }
           cidr: 2001:db8:cafe:1e::/64

    Router:
        type: OS::Neutron::Router
        properties:
            name: "default Router"

    router_interface1:
        type: OS::Neutron::RouterInterface
        properties:
            router_id: { get_resource: Router }
            subnet_id: { get_resource: SubNet11 }

    router_interface2:
        type: OS::Neutron::RouterInterface
        properties:
            router_id: { get_resource: Router }
           subnet_id: { get_resource: SubNet12 }

TYPE P

TYPE P
description: BGPVPN networking example TYPE P (tenant)
heat_template_version: '2013-05-23'

resources:

    BGPVPN1:
    type: OS::Neutron::BGPVPN
    properties:
        import_targets: [ "100:1001"]
        export_targets: [ "100:1002"]
        route_targets: [ "100:1000" ]
        name: "default VPN"

    Net1:
        type: OS::Neutron::Net
        properties:
            name: "default Net1"

    SubNet11:
        type: OS::Neutron::Subnet
        properties:
            network: { get_resource: Net1 }
            cidr: 20.1.1.0/24

 SubNet12:
     type: OS::Neutron::Subnet
     properties:
        network: { get_resource: Net1 }
        cidr: 2001:db8:cafe:1e::/64

 Router:
     type: OS::Neutron::Router
     properties:
         name: "default Router"

 router_interface1:
     type: OS::Neutron::RouterInterface
     properties:
        router_id: { get_resource: Router }
        subnet_id: { get_resource: SubNet11 }

 router_interface2:
     type: OS::Neutron::RouterInterface
     properties:
        router_id: { get_resource: Router }
        subnet_id: { get_resource: SubNet12 }

 BGPVPN_router_assoc1:
     type: OS::Neutron::BGPVPN-ROUTER-ASSOCIATION
     properties:
         bgpvpn_id: { get_resource: BGPVPN1 }
         router_id: { get_resource: Router }

TYPE Q

TYPE Q
description: BGPVPN networking example TYPE P (tenant)
heat_template_version: '2013-05-23'

resources:

BGPVPN_router_assoc1:
    type: OS::Neutron::BGPVPN-ROUTER-ASSOCIATION
    properties:
        bgpvpn_id: "default VPN"
        router_id: "default Router"

TYPE R

TYPE R
description: BGPVPN networking example TYPE P (tenant)
heat_template_version: '2013-05-23'

resources:

    BGPVPN1:
        type: OS::Neutron::BGPVPN
        properties:
            import_targets: [ "100:1001"]
            export_targets: [ "100:1002"]
            route_targets: [ "100:1000" ]
            name: "default VPN"

    BGPVPN_router_assoc1:
        type: OS::Neutron::BGPVPN-ROUTER-ASSOCIATION
        properties:
            bgpvpn_id: "default VPN"
            router_id: "default Router"